Named arguments
This commit is contained in:
parent
1bd65cd283
commit
be81529c5d
|
@ -1,4 +1,4 @@
|
|||
import { DecodeError, IdentitySet, Value } from '@preserves/core';
|
||||
import { IdentitySet, Value } from '@preserves/core';
|
||||
import { Attenuation, runRewrites } from './rewrite.js';
|
||||
import { queueTask } from './task.js';
|
||||
|
||||
|
|
31
src/box.ts
31
src/box.ts
|
@ -15,19 +15,22 @@ export default function (t: Turn, arg: Assertion) {
|
|||
valueHandle = t.replace(ds, valueHandle, fromBoxState(BoxState(value)));
|
||||
}
|
||||
setValue(t, 0);
|
||||
t.assert(ds, fromObserve(Observe($SetBox, t.ref({
|
||||
message(t: Turn, [newValue]: [number]): void {
|
||||
// console.log(`Box ${t.actor.id}: got ${newValue}`);
|
||||
if (newValue % REPORT_EVERY === 0) {
|
||||
const endTime = Date.now();
|
||||
const delta = (endTime - startTime) / 1000.0;
|
||||
const count = newValue - prevValue;
|
||||
prevValue = newValue;
|
||||
startTime = endTime;
|
||||
console.log(`Box ${t.actor.id}: got ${newValue} (${count / delta} Hz)`);
|
||||
t.assert(ds, fromObserve(Observe({
|
||||
label: $SetBox,
|
||||
observer: t.ref({
|
||||
message(t: Turn, [newValue]: [number]): void {
|
||||
// console.log(`Box ${t.actor.id}: got ${newValue}`);
|
||||
if (newValue % REPORT_EVERY === 0) {
|
||||
const endTime = Date.now();
|
||||
const delta = (endTime - startTime) / 1000.0;
|
||||
const count = newValue - prevValue;
|
||||
prevValue = newValue;
|
||||
startTime = endTime;
|
||||
console.log(`Box ${t.actor.id}: got ${newValue} (${count / delta} Hz)`);
|
||||
}
|
||||
if (newValue === LIMIT) t.quit();
|
||||
setValue(t, newValue);
|
||||
}
|
||||
if (newValue === LIMIT) t.quit();
|
||||
setValue(t, newValue);
|
||||
}
|
||||
}))));
|
||||
})
|
||||
})));
|
||||
}
|
||||
|
|
|
@ -5,23 +5,29 @@ import { Assertion, Ref, Turn } from "./actor.js";
|
|||
export default function (t: Turn, ds: Ref) {
|
||||
console.log('Spawning Client');
|
||||
let count = 0;
|
||||
t.assert(ds, fromObserve(Observe($BoxState, t.ref({
|
||||
assert(t: Turn, [currentValue]: [number]): void {
|
||||
// console.log(`Client ${t.actor.id}: got ${currentValue}`);
|
||||
t.message(ds, fromSetBox(SetBox(currentValue + 1)));
|
||||
}
|
||||
}))));
|
||||
t.assert(ds, fromObserve(Observe($BoxState, t.ref({
|
||||
assert(_t: Turn, _assertion: Assertion): void {
|
||||
count++;
|
||||
// console.log('inc to', count, _assertion);
|
||||
},
|
||||
retract(t: Turn) {
|
||||
if (--count === 0) {
|
||||
console.log(`Client ${t.actor.id}: detected box termination`);
|
||||
t.quit();
|
||||
t.assert(ds, fromObserve(Observe({
|
||||
label: $BoxState,
|
||||
observer: t.ref({
|
||||
assert(t: Turn, [currentValue]: [number]): void {
|
||||
// console.log(`Client ${t.actor.id}: got ${currentValue}`);
|
||||
t.message(ds, fromSetBox(SetBox(currentValue + 1)));
|
||||
}
|
||||
// console.log('dec to', count);
|
||||
},
|
||||
}))));
|
||||
})
|
||||
})));
|
||||
t.assert(ds, fromObserve(Observe({
|
||||
label: $BoxState,
|
||||
observer: t.ref({
|
||||
assert(_t: Turn, _assertion: Assertion): void {
|
||||
count++;
|
||||
// console.log('inc to', count, _assertion);
|
||||
},
|
||||
retract(t: Turn) {
|
||||
if (--count === 0) {
|
||||
console.log(`Client ${t.actor.id}: detected box termination`);
|
||||
t.quit();
|
||||
}
|
||||
// console.log('dec to', count);
|
||||
},
|
||||
})
|
||||
})));
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ export type SetBox = {"value": number};
|
|||
|
||||
export const _toPtr = (v: _val) => {let result: undefined | _ptr; result = _i_Actor.toRef(v); return result;};
|
||||
|
||||
export function BoxState(value: number): BoxState {return {value};}
|
||||
export function BoxState(value: number): BoxState {return {"value": value};}
|
||||
|
||||
export function SetBox(value: number): SetBox {return {value};}
|
||||
export function SetBox(value: number): SetBox {return {"value": value};}
|
||||
|
||||
export function asBoxState(v: _val): BoxState {
|
||||
let result = toBoxState(v);
|
||||
|
|
|
@ -12,7 +12,7 @@ export type Observe = {"label": symbol, "observer": _ptr};
|
|||
|
||||
export const _toPtr = (v: _val) => {let result: undefined | _ptr; result = _i_Actor.toRef(v); return result;};
|
||||
|
||||
export function Observe(label: symbol, observer: _ptr): Observe {return {label, observer};}
|
||||
export function Observe({label, observer}: {label: symbol, observer: _ptr}): Observe {return {"label": label, "observer": observer};}
|
||||
|
||||
export function asObserve(v: _val): Observe {
|
||||
let result = toObserve(v);
|
||||
|
|
|
@ -47,25 +47,25 @@ export function Assertion(value: _val): Assertion {return value;}
|
|||
export function Handle(value: number): Handle {return value;}
|
||||
|
||||
export namespace Event {
|
||||
export function Assert(value: Assert): Event {return {"_variant": "Assert", value};};
|
||||
export function Retract(value: Retract): Event {return {"_variant": "Retract", value};};
|
||||
export function Message(value: Message): Event {return {"_variant": "Message", value};};
|
||||
export function Sync(value: Sync): Event {return {"_variant": "Sync", value};};
|
||||
export function Assert(value: Assert): Event {return {"_variant": "Assert", "value": value};};
|
||||
export function Retract(value: Retract): Event {return {"_variant": "Retract", "value": value};};
|
||||
export function Message(value: Message): Event {return {"_variant": "Message", "value": value};};
|
||||
export function Sync(value: Sync): Event {return {"_variant": "Sync", "value": value};};
|
||||
}
|
||||
|
||||
export function Oid(value: number): Oid {return value;}
|
||||
|
||||
export function Turn(value: Array<TurnEvent>): Turn {return value;}
|
||||
|
||||
export function TurnEvent(oid: Oid, event: Event): TurnEvent {return {oid, event};}
|
||||
export function TurnEvent({oid, event}: {oid: Oid, event: Event}): TurnEvent {return {"oid": oid, "event": event};}
|
||||
|
||||
export function Assert(assertion: Assertion, handle: Handle): Assert {return {assertion, handle};}
|
||||
export function Assert({assertion, handle}: {assertion: Assertion, handle: Handle}): Assert {return {"assertion": assertion, "handle": handle};}
|
||||
|
||||
export function Retract(handle: Handle): Retract {return {handle};}
|
||||
export function Retract(handle: Handle): Retract {return {"handle": handle};}
|
||||
|
||||
export function Message(body: Assertion): Message {return {body};}
|
||||
export function Message(body: Assertion): Message {return {"body": body};}
|
||||
|
||||
export function Sync(peer: _ptr): Sync {return {peer};}
|
||||
export function Sync(peer: _ptr): Sync {return {"peer": peer};}
|
||||
|
||||
export function asAssertion(v: _val): Assertion {
|
||||
let result = toAssertion(v);
|
||||
|
|
|
@ -84,65 +84,67 @@ export type TCompoundMembers = _.KeyedDictionary<_val, Template, _ptr>;
|
|||
|
||||
export const _toPtr = (v: _val) => {let result: undefined | _ptr; result = _i_Actor.toRef(v); return result;};
|
||||
|
||||
export function SturdyRef(oid: _val, caveatChain: Array<Attenuation>, sig: _.Bytes): SturdyRef {return {oid, caveatChain, sig};}
|
||||
export function SturdyRef(
|
||||
{oid, caveatChain, sig}: {oid: _val, caveatChain: Array<Attenuation>, sig: _.Bytes}
|
||||
): SturdyRef {return {"oid": oid, "caveatChain": caveatChain, "sig": sig};}
|
||||
|
||||
export function Attenuation(value: Array<Caveat>): Attenuation {return value;}
|
||||
|
||||
export namespace Caveat {
|
||||
export function Rewrite(value: Rewrite): Caveat {return {"_variant": "Rewrite", value};};
|
||||
export function Alts(value: Alts): Caveat {return {"_variant": "Alts", value};};
|
||||
export function Rewrite(value: Rewrite): Caveat {return {"_variant": "Rewrite", "value": value};};
|
||||
export function Alts(value: Alts): Caveat {return {"_variant": "Alts", "value": value};};
|
||||
}
|
||||
|
||||
export function Rewrite(pattern: Pattern, template: Template): Rewrite {return {pattern, template};}
|
||||
export function Rewrite({pattern, template}: {pattern: Pattern, template: Template}): Rewrite {return {"pattern": pattern, "template": template};}
|
||||
|
||||
export function Alts(alternatives: Array<Rewrite>): Alts {return {alternatives};}
|
||||
export function Alts(alternatives: Array<Rewrite>): Alts {return {"alternatives": alternatives};}
|
||||
|
||||
export function Resolve(sturdyref: SturdyRef, observer: _ptr): Resolve {return {sturdyref, observer};}
|
||||
export function Resolve({sturdyref, observer}: {sturdyref: SturdyRef, observer: _ptr}): Resolve {return {"sturdyref": sturdyref, "observer": observer};}
|
||||
|
||||
export namespace ConstructorSpec {
|
||||
export function CRec(value: CRec): ConstructorSpec {return {"_variant": "CRec", value};};
|
||||
export function CArr(value: CArr): ConstructorSpec {return {"_variant": "CArr", value};};
|
||||
export function CDict(value: CDict): ConstructorSpec {return {"_variant": "CDict", value};};
|
||||
export function CRec(value: CRec): ConstructorSpec {return {"_variant": "CRec", "value": value};};
|
||||
export function CArr(value: CArr): ConstructorSpec {return {"_variant": "CArr", "value": value};};
|
||||
export function CDict(value: CDict): ConstructorSpec {return {"_variant": "CDict", "value": value};};
|
||||
}
|
||||
|
||||
export function CRec(label: _val, arity: number): CRec {return {label, arity};}
|
||||
export function CRec({label, arity}: {label: _val, arity: number}): CRec {return {"label": label, "arity": arity};}
|
||||
|
||||
export function CArr(arity: number): CArr {return {arity};}
|
||||
export function CArr(arity: number): CArr {return {"arity": arity};}
|
||||
|
||||
export function CDict(): CDict {return null;}
|
||||
|
||||
export function Lit(value: _val): Lit {return {value};}
|
||||
export function Lit(value: _val): Lit {return {"value": value};}
|
||||
|
||||
export namespace Pattern {
|
||||
export function PDiscard(value: PDiscard): Pattern {return {"_variant": "PDiscard", value};};
|
||||
export function PBind(value: PBind): Pattern {return {"_variant": "PBind", value};};
|
||||
export function PAnd(value: PAnd): Pattern {return {"_variant": "PAnd", value};};
|
||||
export function PNot(value: PNot): Pattern {return {"_variant": "PNot", value};};
|
||||
export function Lit(value: Lit): Pattern {return {"_variant": "Lit", value};};
|
||||
export function PCompound(value: PCompound): Pattern {return {"_variant": "PCompound", value};};
|
||||
export function PDiscard(value: PDiscard): Pattern {return {"_variant": "PDiscard", "value": value};};
|
||||
export function PBind(value: PBind): Pattern {return {"_variant": "PBind", "value": value};};
|
||||
export function PAnd(value: PAnd): Pattern {return {"_variant": "PAnd", "value": value};};
|
||||
export function PNot(value: PNot): Pattern {return {"_variant": "PNot", "value": value};};
|
||||
export function Lit(value: Lit): Pattern {return {"_variant": "Lit", "value": value};};
|
||||
export function PCompound(value: PCompound): Pattern {return {"_variant": "PCompound", "value": value};};
|
||||
}
|
||||
|
||||
export function PDiscard(): PDiscard {return null;}
|
||||
|
||||
export function PBind(name: symbol, pattern: Pattern): PBind {return {name, pattern};}
|
||||
export function PBind({name, pattern}: {name: symbol, pattern: Pattern}): PBind {return {"name": name, "pattern": pattern};}
|
||||
|
||||
export function PAnd(patterns: Array<Pattern>): PAnd {return {patterns};}
|
||||
export function PAnd(patterns: Array<Pattern>): PAnd {return {"patterns": patterns};}
|
||||
|
||||
export function PNot(pattern: Pattern): PNot {return {pattern};}
|
||||
export function PNot(pattern: Pattern): PNot {return {"pattern": pattern};}
|
||||
|
||||
export function PCompound(ctor: ConstructorSpec, members: PCompoundMembers): PCompound {return {ctor, members};}
|
||||
export function PCompound({ctor, members}: {ctor: ConstructorSpec, members: PCompoundMembers}): PCompound {return {"ctor": ctor, "members": members};}
|
||||
|
||||
export function PCompoundMembers(value: _.KeyedDictionary<_val, Pattern, _ptr>): PCompoundMembers {return value;}
|
||||
|
||||
export namespace Template {
|
||||
export function TRef(value: TRef): Template {return {"_variant": "TRef", value};};
|
||||
export function Lit(value: Lit): Template {return {"_variant": "Lit", value};};
|
||||
export function TCompound(value: TCompound): Template {return {"_variant": "TCompound", value};};
|
||||
export function TRef(value: TRef): Template {return {"_variant": "TRef", "value": value};};
|
||||
export function Lit(value: Lit): Template {return {"_variant": "Lit", "value": value};};
|
||||
export function TCompound(value: TCompound): Template {return {"_variant": "TCompound", "value": value};};
|
||||
}
|
||||
|
||||
export function TRef(name: symbol): TRef {return {name};}
|
||||
export function TRef(name: symbol): TRef {return {"name": name};}
|
||||
|
||||
export function TCompound(ctor: ConstructorSpec, members: TCompoundMembers): TCompound {return {ctor, members};}
|
||||
export function TCompound({ctor, members}: {ctor: ConstructorSpec, members: TCompoundMembers}): TCompound {return {"ctor": ctor, "members": members};}
|
||||
|
||||
export function TCompoundMembers(value: _.KeyedDictionary<_val, Template, _ptr>): TCompoundMembers {return value;}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ export type Instance = {"name": string, "argument": _val};
|
|||
|
||||
export const _toPtr = () => { throw new _.DecodeError("Pointers forbidden"); };
|
||||
|
||||
export function Instance(name: string, argument: _val): Instance {return {name, argument};}
|
||||
export function Instance({name, argument}: {name: string, argument: _val}): Instance {return {"name": name, "argument": argument};}
|
||||
|
||||
export function asInstance(v: _val): Instance {
|
||||
let result = toInstance(v);
|
||||
|
|
30
src/main.ts
30
src/main.ts
|
@ -58,24 +58,34 @@ Turn.for(new Actor(), async (t: Turn) => {
|
|||
const ds_for_box = attenuate(
|
||||
ds,
|
||||
rfilter(
|
||||
Pattern.PCompound(PCompound(ConstructorSpec.CRec(CRec($BoxState, 1)), new Dictionary())),
|
||||
Pattern.PCompound(PCompound(ConstructorSpec.CRec(CRec($Observe, 2)),
|
||||
new Dictionary<Ref, Pattern>([
|
||||
[0, Pattern.Lit(Lit($SetBox))]])))));
|
||||
Pattern.PCompound(PCompound({
|
||||
ctor: ConstructorSpec.CRec(CRec({ label: $BoxState, arity: 1 })),
|
||||
members: new Dictionary()
|
||||
})),
|
||||
Pattern.PCompound(PCompound({
|
||||
ctor: ConstructorSpec.CRec(CRec({ label: $Observe, arity: 2 })),
|
||||
members: new Dictionary<Ref, Pattern>([
|
||||
[0, Pattern.Lit(Lit($SetBox))]])
|
||||
}))));
|
||||
|
||||
const ds_for_client = attenuate(
|
||||
ds_unproxied,
|
||||
rfilter(
|
||||
Pattern.PCompound(PCompound(ConstructorSpec.CRec(CRec($SetBox, 1)), new Dictionary())),
|
||||
Pattern.PCompound(PCompound(ConstructorSpec.CRec(CRec($Observe, 2)),
|
||||
new Dictionary<Ref, Pattern>([
|
||||
[0, Pattern.Lit(Lit($BoxState))]])))));
|
||||
Pattern.PCompound(PCompound({
|
||||
ctor: ConstructorSpec.CRec(CRec({ label: $SetBox, arity: 1 })),
|
||||
members: new Dictionary()
|
||||
})),
|
||||
Pattern.PCompound(PCompound({
|
||||
ctor: ConstructorSpec.CRec(CRec({ label: $Observe, arity: 2 })),
|
||||
members: new Dictionary<Ref, Pattern>([
|
||||
[0, Pattern.Lit(Lit($BoxState))]])
|
||||
}))));
|
||||
|
||||
const boxpath = path.join(__dirname, 'box.js');
|
||||
const clientpath = path.join(__dirname, 'client.js');
|
||||
|
||||
spawnModule(t, boxpath, [ds_for_box, 500000, 25000]);
|
||||
// spawnWorker(t, boxpath, [ds_for_box, 50000, 2500]);
|
||||
// spawnModule(t, boxpath, [ds_for_box, 500000, 25000]);
|
||||
spawnWorker(t, boxpath, [ds_for_box, 50000, 2500]);
|
||||
|
||||
spawnModule(t, clientpath, ds_for_client);
|
||||
// spawnWorker(t, clientpath, ds_for_client);
|
||||
|
|
|
@ -52,7 +52,10 @@ export class RelayEntity implements Entity {
|
|||
}
|
||||
|
||||
assert(_turn: Turn, assertion: Assertion, handle: Handle): void {
|
||||
this.send(IO.Event.Assert(IO.Assert(this.relay.register(assertion, handle), handle)))
|
||||
this.send(IO.Event.Assert(IO.Assert({
|
||||
assertion: this.relay.register(assertion, handle),
|
||||
handle
|
||||
})))
|
||||
}
|
||||
|
||||
retract(_turn: Turn, handle: Handle): void {
|
||||
|
@ -240,7 +243,7 @@ export class Relay {
|
|||
this.pendingTurn = [];
|
||||
});
|
||||
}
|
||||
this.pendingTurn.push(IO.TurnEvent(remoteOid, m));
|
||||
this.pendingTurn.push(IO.TurnEvent({ oid: remoteOid, event: m }));
|
||||
}
|
||||
|
||||
lookupLocal(localOid: IO.Oid): Ref {
|
||||
|
|
|
@ -150,7 +150,10 @@ export function runRewrites(a: Attenuation | undefined, v: Assertion): Assertion
|
|||
const _a = Symbol.for('a');
|
||||
|
||||
export function rfilter(... patterns: Pattern[]): Caveat {
|
||||
const ps = patterns.map(p => Rewrite(Pattern.PBind(PBind(_a, p)), Template.TRef(TRef(_a))));
|
||||
const ps = patterns.map(p => Rewrite({
|
||||
pattern: Pattern.PBind(PBind({ name: _a, pattern: p })),
|
||||
template: Template.TRef(TRef(_a))
|
||||
}));
|
||||
return ps.length === 1 ? Caveat.Rewrite(ps[0]) : Caveat.Alts(Alts(ps));
|
||||
}
|
||||
|
||||
|
|
|
@ -29,11 +29,14 @@ const socket = net.createConnection({ port: 5999, host: 'localhost' }, () => {
|
|||
// debug: true,
|
||||
}).then(gatekeeper => import(moduleName).then(m => t.freshen(t => {
|
||||
t.assert(shutdownRef, true);
|
||||
t.assert(gatekeeper, fromResolve(Resolve(asSturdyRef(cap), t.ref({
|
||||
assert(t, ds) {
|
||||
m.default(t, ds);
|
||||
}
|
||||
}))));
|
||||
t.assert(gatekeeper, fromResolve(Resolve({
|
||||
sturdyref: asSturdyRef(cap),
|
||||
observer: t.ref({
|
||||
assert(t, ds) {
|
||||
m.default(t, ds);
|
||||
}
|
||||
})
|
||||
})));
|
||||
})));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,14 +7,20 @@ import { Ref } from 'actor.js';
|
|||
async function main() {
|
||||
const m1 = await mint('hello world', new Bytes(KEY_LENGTH));
|
||||
console.log(m1);
|
||||
const m2 = await attenuate(m1, Caveat.Rewrite(Rewrite(
|
||||
RW.Pattern.PBind(RW.PBind(
|
||||
Symbol.for('a'),
|
||||
RW.Pattern.PCompound(RW.PCompound(
|
||||
RW.ConstructorSpec.CRec(RW.CRec(Symbol.for('says'), 2)),
|
||||
new Dictionary<Ref, RW.Pattern>([
|
||||
[0, RW.Pattern.Lit(RW.Lit('Tony'))]]))))),
|
||||
RW.Template.TRef(RW.TRef(Symbol.for('a'))))));
|
||||
const m2 = await attenuate(m1, Caveat.Rewrite(Rewrite({
|
||||
pattern: RW.Pattern.PBind(RW.PBind({
|
||||
name: Symbol.for('a'),
|
||||
pattern: RW.Pattern.PCompound(RW.PCompound({
|
||||
ctor: RW.ConstructorSpec.CRec(RW.CRec({
|
||||
label: Symbol.for('says'),
|
||||
arity: 2
|
||||
})),
|
||||
members: new Dictionary<Ref, RW.Pattern>([
|
||||
[0, RW.Pattern.Lit(RW.Lit('Tony'))]])
|
||||
}))
|
||||
})),
|
||||
template: RW.Template.TRef(RW.TRef(Symbol.for('a')))
|
||||
})));
|
||||
console.log(m2);
|
||||
console.log('should be true:', await validate(m1, new Bytes(KEY_LENGTH)));
|
||||
console.log('should be true:', await validate(m2, new Bytes(KEY_LENGTH)));
|
||||
|
|
|
@ -35,15 +35,19 @@ export function sturdyDecode(bs: Bytes): SturdyValue {
|
|||
}
|
||||
|
||||
export async function mint(oid: SturdyValue, secretKey: Bytes): Promise<S.SturdyRef> {
|
||||
return S.SturdyRef(oid, [], await mac(secretKey, sturdyEncode(oid)));
|
||||
return S.SturdyRef({
|
||||
oid,
|
||||
caveatChain: [],
|
||||
sig: await mac(secretKey, sturdyEncode(oid)),
|
||||
});
|
||||
}
|
||||
|
||||
export async function attenuate(r: S.SturdyRef, ... a: S.Attenuation): Promise<S.SturdyRef> {
|
||||
return S.SturdyRef(
|
||||
r.oid,
|
||||
[... r.caveatChain, a],
|
||||
await mac(r.sig, sturdyEncode(S.fromAttenuation(a)))
|
||||
);
|
||||
return S.SturdyRef({
|
||||
oid: r.oid,
|
||||
caveatChain: [... r.caveatChain, a],
|
||||
sig: await mac(r.sig, sturdyEncode(S.fromAttenuation(a)))
|
||||
});
|
||||
}
|
||||
|
||||
export async function validate(r: S.SturdyRef, secretKey: Bytes): Promise<boolean> {
|
||||
|
|
Loading…
Reference in New Issue