From be81529c5d5165f9ac6482325b7d751052fdca77 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Tue, 23 Mar 2021 19:18:26 +0100 Subject: [PATCH] Named arguments --- src/actor.ts | 2 +- src/box.ts | 31 ++++++++++++----------- src/client.ts | 42 ++++++++++++++++++------------- src/gen/box-protocol.ts | 4 +-- src/gen/dataspace.ts | 2 +- src/gen/protocol.ts | 18 ++++++------- src/gen/sturdy.ts | 56 +++++++++++++++++++++-------------------- src/gen/worker.ts | 2 +- src/main.ts | 30 ++++++++++++++-------- src/relay.ts | 7 ++++-- src/rewrite.ts | 5 +++- src/sandbox.ts | 13 ++++++---- src/sturdy-demo.ts | 22 ++++++++++------ src/sturdy.ts | 16 +++++++----- 14 files changed, 145 insertions(+), 105 deletions(-) diff --git a/src/actor.ts b/src/actor.ts index 741cfa0..e4e30ae 100644 --- a/src/actor.ts +++ b/src/actor.ts @@ -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'; diff --git a/src/box.ts b/src/box.ts index 21f6667..21f2ad4 100644 --- a/src/box.ts +++ b/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); - } - })))); + }) + }))); } diff --git a/src/client.ts b/src/client.ts index b70e8d9..51113fc 100644 --- a/src/client.ts +++ b/src/client.ts @@ -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); + }, + }) + }))); } diff --git a/src/gen/box-protocol.ts b/src/gen/box-protocol.ts index 25eba68..f1c7fd1 100644 --- a/src/gen/box-protocol.ts +++ b/src/gen/box-protocol.ts @@ -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); diff --git a/src/gen/dataspace.ts b/src/gen/dataspace.ts index f1243c5..c69f893 100644 --- a/src/gen/dataspace.ts +++ b/src/gen/dataspace.ts @@ -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); diff --git a/src/gen/protocol.ts b/src/gen/protocol.ts index 32bbda5..c140c72 100644 --- a/src/gen/protocol.ts +++ b/src/gen/protocol.ts @@ -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): 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); diff --git a/src/gen/sturdy.ts b/src/gen/sturdy.ts index afe1549..35a696f 100644 --- a/src/gen/sturdy.ts +++ b/src/gen/sturdy.ts @@ -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, sig: _.Bytes): SturdyRef {return {oid, caveatChain, sig};} +export function SturdyRef( + {oid, caveatChain, sig}: {oid: _val, caveatChain: Array, sig: _.Bytes} +): SturdyRef {return {"oid": oid, "caveatChain": caveatChain, "sig": sig};} export function Attenuation(value: Array): 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): Alts {return {alternatives};} +export function Alts(alternatives: Array): 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): PAnd {return {patterns};} +export function PAnd(patterns: Array): 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;} diff --git a/src/gen/worker.ts b/src/gen/worker.ts index c378db3..5517bc6 100644 --- a/src/gen/worker.ts +++ b/src/gen/worker.ts @@ -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); diff --git a/src/main.ts b/src/main.ts index 655dd56..c79524f 100644 --- a/src/main.ts +++ b/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([ - [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([ + [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([ - [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([ + [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); diff --git a/src/relay.ts b/src/relay.ts index 42f3232..009e3e0 100644 --- a/src/relay.ts +++ b/src/relay.ts @@ -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 { diff --git a/src/rewrite.ts b/src/rewrite.ts index 01f4b98..51be772 100644 --- a/src/rewrite.ts +++ b/src/rewrite.ts @@ -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)); } diff --git a/src/sandbox.ts b/src/sandbox.ts index 51035b4..3816e5c 100644 --- a/src/sandbox.ts +++ b/src/sandbox.ts @@ -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); + } + }) + }))); }))); }); }); diff --git a/src/sturdy-demo.ts b/src/sturdy-demo.ts index 6e3f9c8..9f26a90 100644 --- a/src/sturdy-demo.ts +++ b/src/sturdy-demo.ts @@ -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([ - [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([ + [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))); diff --git a/src/sturdy.ts b/src/sturdy.ts index 16eaca7..e0867b1 100644 --- a/src/sturdy.ts +++ b/src/sturdy.ts @@ -35,15 +35,19 @@ export function sturdyDecode(bs: Bytes): SturdyValue { } export async function mint(oid: SturdyValue, secretKey: Bytes): Promise { - 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 { - 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 {