Avoid hand-written WireRef (un)marshalling, taking advantage of the new Pointer representation from preserves

This commit is contained in:
Tony Garnock-Jones 2021-04-25 00:15:15 +02:00
parent fa47fa3e5e
commit 4af4219cc7
28 changed files with 262 additions and 188 deletions

View File

@ -6,8 +6,8 @@
"typescript": "^4.2.3" "typescript": "^4.2.3"
}, },
"dependencies": { "dependencies": {
"@preserves/core": "^0.11.0", "@preserves/core": "^0.12.0",
"@preserves/schema": "^0.4.0" "@preserves/schema": "^0.5.1"
}, },
"scripts": { "scripts": {
"regenerate": "rm -rf ./src/gen && preserves-schema-ts --module Actor=./src/runtime/actor.ts --module Protocol=./src/transport/protocol.ts --output ./src/gen './schemas/**/*.prs'", "regenerate": "rm -rf ./src/gen && preserves-schema-ts --module Actor=./src/runtime/actor.ts --module Protocol=./src/transport/protocol.ts --output ./src/gen './schemas/**/*.prs'",

5
schemas/gatekeeper.prs Normal file
View File

@ -0,0 +1,5 @@
version 1 .
pointer Actor.Ref .
Resolve = <resolve @sturdyref sturdy.SturdyRef @observer ref>.
Bind = <bind @oid any @key bytes @target ref>.

View File

@ -1,5 +1,5 @@
version 1 . version 1 .
pointer Protocol.WireRef . pointer sturdy.WireRef .
Assertion = any . Assertion = any .
Handle = int . Handle = int .

View File

@ -1,5 +1,4 @@
version 1 . version 1 .
pointer Actor.Ref .
; Each Attenuation is a stage. The sequence of Attenuations is run RIGHT-TO-LEFT. ; Each Attenuation is a stage. The sequence of Attenuations is run RIGHT-TO-LEFT.
; That is, the newest Attenuations are at the right. ; That is, the newest Attenuations are at the right.
@ -15,8 +14,8 @@ Caveat = Rewrite / Alts .
Rewrite = <rewrite @pattern Pattern @template Template>. Rewrite = <rewrite @pattern Pattern @template Template>.
Alts = <or [@alternatives Rewrite ...]>. Alts = <or [@alternatives Rewrite ...]>.
Resolve = <resolve @sturdyref SturdyRef @observer ref>. Oid = int .
Bind = <bind @oid any @key bytes @target ref>. WireRef = @mine [0 @oid Oid] / @yours [1 @oid Oid @attenuation Caveat ...].
;--------------------------------------------------------------------------- ;---------------------------------------------------------------------------

View File

@ -1,7 +1,8 @@
import { Actor, Ref, Turn } from "../runtime/actor"; import { Actor, Ref, Turn } from "../runtime/actor";
import { Relay, spawnRelay } from "../transport/relay"; import { Relay, spawnRelay } from "../transport/relay";
import { sturdyDecode } from "../transport/sturdy"; import { sturdyDecode } from "../transport/sturdy";
import { Resolve, asSturdyRef, fromResolve } from "../gen/sturdy"; import { asSturdyRef } from "../gen/sturdy";
import { Resolve, fromResolve } from "../gen/gatekeeper";
import { during } from "../runtime/dataspace"; import { during } from "../runtime/dataspace";
import * as net from 'net'; import * as net from 'net';

View File

@ -6,8 +6,9 @@ import * as net from 'net';
import { mint, sturdyEncode, validate } from '../transport/sturdy.js'; import { mint, sturdyEncode, validate } from '../transport/sturdy.js';
import { KEY_LENGTH } from '../transport/cryptography.js'; import { KEY_LENGTH } from '../transport/cryptography.js';
import { attenuate } from '../runtime/rewrite.js'; import { attenuate } from '../runtime/rewrite.js';
import { Bytes, is } from '@preserves/core'; import { Bytes, embed, is } from '@preserves/core';
import { $bind, Attenuation, Bind, fromBind, fromSturdyRef, toBind, toResolve, _val } from '../gen/sturdy.js'; import { Attenuation, fromSturdyRef, _val } from '../gen/sturdy.js';
import { $bind, Bind, fromBind, toBind, toResolve } from '../gen/gatekeeper.js';
new Actor(t => { new Actor(t => {
t.activeFacet.preventInertCheck(); t.activeFacet.preventInertCheck();
@ -52,7 +53,7 @@ new Actor(t => {
r.caveatChain.forEach(cs => cavs.push(... cs)); r.caveatChain.forEach(cs => cavs.push(... cs));
const attenuated_ds = attenuate(b.target, ... cavs); const attenuated_ds = attenuate(b.target, ... cavs);
let replyHandle: Handle | undefined; let replyHandle: Handle | undefined;
t.freshen(t => replyHandle = t.assert(a.observer, attenuated_ds)); t.freshen(t => replyHandle = t.assert(a.observer, embed(attenuated_ds)));
return t => t.retract(replyHandle); return t => t.retract(replyHandle);
})); }));
}); });

View File

@ -1,3 +1,4 @@
import { Pointer } from "@preserves/core";
import { BoxState, $SetBox, fromBoxState } from "../gen/box-protocol.js"; import { BoxState, $SetBox, fromBoxState } from "../gen/box-protocol.js";
import { fromObserve, Observe } from "../gen/dataspace.js"; import { fromObserve, Observe } from "../gen/dataspace.js";
import { Assertion, Handle, Ref, Turn } from "../runtime/actor.js"; import { Assertion, Handle, Ref, Turn } from "../runtime/actor.js";
@ -6,9 +7,10 @@ let startTime = Date.now();
let prevValue = 0; let prevValue = 0;
export default function (t: Turn, arg: Assertion) { export default function (t: Turn, arg: Assertion) {
const [ds, LIMIT, REPORT_EVERY]: [Ref, number, number] = Array.isArray(arg) && arg.length === 3 const [ds_p, LIMIT, REPORT_EVERY]: [Pointer<Ref>, number, number] = Array.isArray(arg) && arg.length === 3
? arg as any ? arg as any
: [arg, 50000, 2500]; : [arg, 50000, 2500];
const ds = ds_p.embeddedValue;
console.log('Spawning Box', LIMIT, REPORT_EVERY); console.log('Spawning Box', LIMIT, REPORT_EVERY);
let valueHandle: Handle | undefined; let valueHandle: Handle | undefined;
function setValue(t: Turn, value: number) { function setValue(t: Turn, value: number) {

View File

@ -1,8 +1,10 @@
import { Pointer } from "@preserves/core";
import { $BoxState, fromSetBox, SetBox } from "../gen/box-protocol.js"; import { $BoxState, fromSetBox, SetBox } from "../gen/box-protocol.js";
import { fromObserve, Observe } from "../gen/dataspace.js"; import { fromObserve, Observe } from "../gen/dataspace.js";
import { Assertion, Ref, Turn } from "../runtime/actor.js"; import { Assertion, Ref, Turn } from "../runtime/actor.js";
export default function (t: Turn, ds: Ref) { export default function (t: Turn, ds_p: Pointer<Ref>) {
const ds = ds_p.embeddedValue;
console.log('Spawning Client'); console.log('Spawning Client');
let count = 0; let count = 0;
t.assert(ds, fromObserve(Observe({ t.assert(ds, fromObserve(Observe({

View File

@ -1,7 +1,7 @@
import { Actor, Assertion, Ref, Turn } from '../runtime/actor.js'; import { Actor, Assertion, Turn } from '../runtime/actor.js';
import { Dictionary } from '@preserves/core'; import { Dictionary, embed } from '@preserves/core';
import { Dataspace } from '../runtime/dataspace.js'; import { Dataspace } from '../runtime/dataspace.js';
import { attenuate, CRec, Lit, Pattern, PCompound, rfilter, ConstructorSpec } from '../runtime/rewrite.js'; import { _ptr, attenuate, CRec, Lit, Pattern, PCompound, rfilter, ConstructorSpec } from '../runtime/rewrite.js';
import { $BoxState, $SetBox } from '../gen/box-protocol.js'; import { $BoxState, $SetBox } from '../gen/box-protocol.js';
import { $Observe } from '../gen/dataspace.js'; import { $Observe } from '../gen/dataspace.js';
import { spawnWorker } from '../worker/index.js'; import { spawnWorker } from '../worker/index.js';
@ -38,7 +38,7 @@ new Actor(async (t: Turn) => {
})), })),
Pattern.PCompound(PCompound({ Pattern.PCompound(PCompound({
ctor: ConstructorSpec.CRec(CRec({ label: $Observe, arity: 2 })), ctor: ConstructorSpec.CRec(CRec({ label: $Observe, arity: 2 })),
members: new Dictionary<Ref, Pattern>([ members: new Dictionary<_ptr, Pattern>([
[0, Pattern.Lit(Lit($SetBox))]]) [0, Pattern.Lit(Lit($SetBox))]])
})))); }))));
@ -51,16 +51,16 @@ new Actor(async (t: Turn) => {
})), })),
Pattern.PCompound(PCompound({ Pattern.PCompound(PCompound({
ctor: ConstructorSpec.CRec(CRec({ label: $Observe, arity: 2 })), ctor: ConstructorSpec.CRec(CRec({ label: $Observe, arity: 2 })),
members: new Dictionary<Ref, Pattern>([ members: new Dictionary<_ptr, Pattern>([
[0, Pattern.Lit(Lit($BoxState))]]) [0, Pattern.Lit(Lit($BoxState))]])
})))); }))));
const boxpath = path.join(__dirname, 'box.js'); const boxpath = path.join(__dirname, 'box.js');
const clientpath = path.join(__dirname, 'client.js'); const clientpath = path.join(__dirname, 'client.js');
// spawnModule(t, boxpath, [ds_for_box, 500000, 25000]); // spawnModule(t, boxpath, [embed(ds_for_box), 500000, 25000]);
spawnWorker(t, boxpath, [ds_for_box, 50000, 2500]); spawnWorker(t, boxpath, [embed(ds_for_box), 50000, 2500]);
spawnModule(t, clientpath, ds_for_client); spawnModule(t, clientpath, embed(ds_for_client));
// spawnWorker(t, clientpath, ds_for_client); // spawnWorker(t, clientpath, embed(ds_for_client));
}); });

View File

@ -2,8 +2,10 @@ import { $joinedUser, $says, $user, asJoin, asSays, asUserInfo, fromNickClaim, f
import { during, observe } from "../runtime/dataspace.js"; import { during, observe } from "../runtime/dataspace.js";
import { Assertion, Ref, Turn } from "../runtime/actor.js"; import { Assertion, Ref, Turn } from "../runtime/actor.js";
import { attachReadline } from './readline.js'; import { attachReadline } from './readline.js';
import { Pointer } from "@preserves/core";
export default function (t: Turn, ds: Ref) { export default function (t: Turn, ds_ptr: Pointer<Ref>) {
const ds = ds_ptr.embeddedValue;
observe(t, ds, $joinedUser, during(async (t, j0) => { observe(t, ds, $joinedUser, during(async (t, j0) => {
const j = asJoin(j0); const j = asJoin(j0);
const facet = t.facet(t => runSession(t, j.uid, j.handle)); const facet = t.facet(t => runSession(t, j.uid, j.handle));

View File

@ -15,11 +15,12 @@ import {
import { Assertion, Handle, Ref, Turn } from "../runtime/actor.js"; import { Assertion, Handle, Ref, Turn } from "../runtime/actor.js";
import { observe, during, $Observe, asObserve, Dataspace } from "../runtime/dataspace.js"; import { observe, during, $Observe, asObserve, Dataspace } from "../runtime/dataspace.js";
import { attenuate, rfilter, pRec, pPointer, pString, pLit } from "../runtime/rewrite.js"; import { attenuate, rfilter, pRec, pPointer, pString, pLit } from "../runtime/rewrite.js";
import { attenuate as sturdyAttenuate, fromBind, Bind, KEY_LENGTH, sturdyEncode, fromSturdyRef, mint } from "../transport/sturdy.js"; import { attenuate as sturdyAttenuate, KEY_LENGTH, sturdyEncode, fromSturdyRef, mint } from "../transport/sturdy.js";
import { Bytes } from "@preserves/core"; import { Bind, fromBind } from "../gen/gatekeeper.js";
import { Bytes, Pointer } from "@preserves/core";
export default function (t: Turn, gatekeeperDs: Ref) { export default function (t: Turn, gatekeeperDs_ptr: Pointer<Ref>) {
let nextUserId: UserId = 0; const gatekeeperDs = gatekeeperDs_ptr.embeddedValue;
const ds = t.ref(new Dataspace()); const ds = t.ref(new Dataspace());
@ -34,6 +35,7 @@ export default function (t: Turn, gatekeeperDs: Ref) {
const nicks = new Map<string, UserId>(); const nicks = new Map<string, UserId>();
let nextUserId: UserId = 0;
observe(t, ds, $Observe, during(async (t, o0) => { observe(t, ds, $Observe, during(async (t, o0) => {
const o = asObserve(o0); const o = asObserve(o0);
if (o.label !== $joinedUser) return null; if (o.label !== $joinedUser) return null;

View File

@ -2,8 +2,11 @@ import { $Present, $Says, asPresent, asSays, fromPresent, fromSays, Present, Say
import { during, observe } from "../runtime/dataspace.js"; import { during, observe } from "../runtime/dataspace.js";
import { Assertion, Handle, Ref, Turn } from "../runtime/actor.js"; import { Assertion, Handle, Ref, Turn } from "../runtime/actor.js";
import { attachReadline } from './readline.js'; import { attachReadline } from './readline.js';
import { Pointer } from "@preserves/core";
export default function (t: Turn, ds_ptr: Pointer<Ref>) {
const ds = ds_ptr.embeddedValue;
export default function (t: Turn, ds: Ref) {
let username = ''; let username = '';
let usernameHandle: Handle | undefined; let usernameHandle: Handle | undefined;

View File

@ -2,7 +2,6 @@ import { newKey } from '../transport/cryptography.js';
import { attenuate, KEY_LENGTH, mint, Caveat, Rewrite, sturdyEncode, validate } from '../transport/sturdy.js'; import { attenuate, KEY_LENGTH, mint, Caveat, Rewrite, sturdyEncode, validate } from '../transport/sturdy.js';
import * as RW from '../runtime/rewrite.js'; import * as RW from '../runtime/rewrite.js';
import { Bytes, Dictionary } from '@preserves/core'; import { Bytes, Dictionary } from '@preserves/core';
import { Ref } from '../runtime/actor.js';
async function main() { async function main() {
const m1 = await mint('hello world', new Bytes(KEY_LENGTH)); const m1 = await mint('hello world', new Bytes(KEY_LENGTH));
@ -15,7 +14,7 @@ async function main() {
label: Symbol.for('says'), label: Symbol.for('says'),
arity: 2 arity: 2
})), })),
members: new Dictionary<Ref, RW.Pattern>([ members: new Dictionary<RW._ptr, RW.Pattern>([
[0, RW.Pattern.Lit(RW.Lit('Tony'))]]) [0, RW.Pattern.Lit(RW.Lit('Tony'))]])
})) }))
})), })),

View File

@ -13,8 +13,6 @@ export type BoxState = {"value": number};
export type SetBox = {"value": number}; 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": value};} export function BoxState(value: number): BoxState {return {"value": value};}
export function SetBox(value: number): SetBox {return {"value": value};} export function SetBox(value: number): SetBox {return {"value": value};}

View File

@ -10,8 +10,6 @@ export type _val = _.Value<_ptr>;
export type Observe = {"label": symbol, "observer": _ptr}; 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, observer}: {label: symbol, observer: _ptr}): Observe {return {"label": label, "observer": observer};} export function Observe({label, observer}: {label: symbol, observer: _ptr}): Observe {return {"label": label, "observer": observer};}
export function asObserve(v: _val): Observe { export function asObserve(v: _val): Observe {
@ -30,7 +28,7 @@ export function toObserve(v: _val): undefined | Observe {
_tmp1 = typeof v[0] === 'symbol' ? v[0] : void 0; _tmp1 = typeof v[0] === 'symbol' ? v[0] : void 0;
if (_tmp1 !== void 0) { if (_tmp1 !== void 0) {
let _tmp2: (_ptr) | undefined; let _tmp2: (_ptr) | undefined;
_tmp2 = _toPtr(v[1]); _tmp2 = _.isPointer<_ptr>(v[1]) ? v[1].embeddedValue : void 0;
if (_tmp2 !== void 0) {result = {"label": _tmp1, "observer": _tmp2};}; if (_tmp2 !== void 0) {result = {"label": _tmp1, "observer": _tmp2};};
}; };
}; };
@ -38,5 +36,5 @@ export function toObserve(v: _val): undefined | Observe {
return result; return result;
} }
export function fromObserve(_v: Observe): _val {return _.Record($Observe, [_v["label"], _v["observer"]]);} export function fromObserve(_v: Observe): _val {return _.Record($Observe, [_v["label"], _.embed(_v["observer"])]);}

78
src/gen/gatekeeper.ts Normal file
View File

@ -0,0 +1,78 @@
import * as _ from "@preserves/core";
import * as _i_Actor from "../runtime/actor";
import * as _i_sturdy from "./sturdy";
export const $bind = Symbol.for("bind");
export const $resolve = Symbol.for("resolve");
export type _ptr = _i_Actor.Ref;
export type _val = _.Value<_ptr>;
export type Resolve = {"sturdyref": _i_sturdy.SturdyRef, "observer": _ptr};
export type Bind = {"oid": _val, "key": _.Bytes, "target": _ptr};
export function Resolve({sturdyref, observer}: {sturdyref: _i_sturdy.SturdyRef, observer: _ptr}): Resolve {return {"sturdyref": sturdyref, "observer": observer};}
export function Bind({oid, key, target}: {oid: _val, key: _.Bytes, target: _ptr}): Bind {return {"oid": oid, "key": key, "target": target};}
export function asResolve(v: _val): Resolve {
let result = toResolve(v);
if (result === void 0) throw new TypeError(`Invalid Resolve: ${_.stringify(v)}`);
return result;
}
export function toResolve(v: _val): undefined | Resolve {
let result: undefined | Resolve;
if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) {
let _tmp0: (null) | undefined;
_tmp0 = _.is(v.label, $resolve) ? null : void 0;
if (_tmp0 !== void 0) {
let _tmp1: (_i_sturdy.SturdyRef) | undefined;
_tmp1 = _i_sturdy.toSturdyRef(v[0]);
if (_tmp1 !== void 0) {
let _tmp2: (_ptr) | undefined;
_tmp2 = _.isPointer<_ptr>(v[1]) ? v[1].embeddedValue : void 0;
if (_tmp2 !== void 0) {result = {"sturdyref": _tmp1, "observer": _tmp2};};
};
};
};
return result;
}
export function fromResolve(_v: Resolve): _val {
return _.Record($resolve, [_i_sturdy.fromSturdyRef(_v["sturdyref"]), _.embed(_v["observer"])]);
}
export function asBind(v: _val): Bind {
let result = toBind(v);
if (result === void 0) throw new TypeError(`Invalid Bind: ${_.stringify(v)}`);
return result;
}
export function toBind(v: _val): undefined | Bind {
let result: undefined | Bind;
if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) {
let _tmp0: (null) | undefined;
_tmp0 = _.is(v.label, $bind) ? null : void 0;
if (_tmp0 !== void 0) {
let _tmp1: (_val) | undefined;
_tmp1 = v[0];
if (_tmp1 !== void 0) {
let _tmp2: (_.Bytes) | undefined;
_tmp2 = _.Bytes.isBytes(v[1]) ? v[1] : void 0;
if (_tmp2 !== void 0) {
let _tmp3: (_ptr) | undefined;
_tmp3 = _.isPointer<_ptr>(v[2]) ? v[2].embeddedValue : void 0;
if (_tmp3 !== void 0) {result = {"oid": _tmp1, "key": _tmp2, "target": _tmp3};};
};
};
};
};
return result;
}
export function fromBind(_v: Bind): _val {return _.Record($bind, [_v["oid"], _v["key"], _.embed(_v["target"])]);}

View File

@ -1,12 +1,12 @@
import * as _ from "@preserves/core"; import * as _ from "@preserves/core";
import * as _i_Protocol from "../transport/protocol"; import * as _i_sturdy from "./sturdy";
export const $assert = Symbol.for("assert"); export const $assert = Symbol.for("assert");
export const $message = Symbol.for("message"); export const $message = Symbol.for("message");
export const $retract = Symbol.for("retract"); export const $retract = Symbol.for("retract");
export const $sync = Symbol.for("sync"); export const $sync = Symbol.for("sync");
export type _ptr = _i_Protocol.WireRef; export type _ptr = _i_sturdy.WireRef;
export type _val = _.Value<_ptr>; export type _val = _.Value<_ptr>;
@ -36,12 +36,6 @@ export type Message = {"body": Assertion};
export type Sync = {"peer": _ptr}; export type Sync = {"peer": _ptr};
export const _toPtr = (v: _val) => {
let result: undefined | _ptr;
result = _i_Protocol.toWireRef(v);
return result;
};
export function Assertion(value: _val): Assertion {return value;} export function Assertion(value: _val): Assertion {return value;}
export function Handle(value: number): Handle {return value;} export function Handle(value: number): Handle {return value;}
@ -285,12 +279,12 @@ export function toSync(v: _val): undefined | Sync {
_tmp0 = _.is(v.label, $sync) ? null : void 0; _tmp0 = _.is(v.label, $sync) ? null : void 0;
if (_tmp0 !== void 0) { if (_tmp0 !== void 0) {
let _tmp1: (_ptr) | undefined; let _tmp1: (_ptr) | undefined;
_tmp1 = _toPtr(v[0]); _tmp1 = _.isPointer<_ptr>(v[0]) ? v[0].embeddedValue : void 0;
if (_tmp1 !== void 0) {result = {"peer": _tmp1};}; if (_tmp1 !== void 0) {result = {"peer": _tmp1};};
}; };
}; };
return result; return result;
} }
export function fromSync(_v: Sync): _val {return _.Record($sync, [_v["peer"]]);} export function fromSync(_v: Sync): _val {return _.Record($sync, [_.embed(_v["peer"])]);}

View File

@ -24,8 +24,6 @@ export type Says = {"who": UserId, "what": string};
export type NickConflict = null; export type NickConflict = null;
export const _toPtr = (v: _val) => {let result: undefined | _ptr; result = _i_Actor.toRef(v); return result;};
export function UserId(value: number): UserId {return value;} export function UserId(value: number): UserId {return value;}
export function Join({uid, handle}: {uid: UserId, handle: _ptr}): Join {return {"uid": uid, "handle": handle};} export function Join({uid, handle}: {uid: UserId, handle: _ptr}): Join {return {"uid": uid, "handle": handle};}
@ -70,7 +68,7 @@ export function toJoin(v: _val): undefined | Join {
_tmp1 = toUserId(v[0]); _tmp1 = toUserId(v[0]);
if (_tmp1 !== void 0) { if (_tmp1 !== void 0) {
let _tmp2: (_ptr) | undefined; let _tmp2: (_ptr) | undefined;
_tmp2 = _toPtr(v[1]); _tmp2 = _.isPointer<_ptr>(v[1]) ? v[1].embeddedValue : void 0;
if (_tmp2 !== void 0) {result = {"uid": _tmp1, "handle": _tmp2};}; if (_tmp2 !== void 0) {result = {"uid": _tmp1, "handle": _tmp2};};
}; };
}; };
@ -78,7 +76,7 @@ export function toJoin(v: _val): undefined | Join {
return result; return result;
} }
export function fromJoin(_v: Join): _val {return _.Record($joinedUser, [fromUserId(_v["uid"]), _v["handle"]]);} export function fromJoin(_v: Join): _val {return _.Record($joinedUser, [fromUserId(_v["uid"]), _.embed(_v["handle"])]);}
export function asNickClaim(v: _val): NickClaim { export function asNickClaim(v: _val): NickClaim {
let result = toNickClaim(v); let result = toNickClaim(v);
@ -99,7 +97,7 @@ export function toNickClaim(v: _val): undefined | NickClaim {
_tmp2 = typeof v[1] === 'string' ? v[1] : void 0; _tmp2 = typeof v[1] === 'string' ? v[1] : void 0;
if (_tmp2 !== void 0) { if (_tmp2 !== void 0) {
let _tmp3: (_ptr) | undefined; let _tmp3: (_ptr) | undefined;
_tmp3 = _toPtr(v[2]); _tmp3 = _.isPointer<_ptr>(v[2]) ? v[2].embeddedValue : void 0;
if (_tmp3 !== void 0) {result = {"uid": _tmp1, "name": _tmp2, "k": _tmp3};}; if (_tmp3 !== void 0) {result = {"uid": _tmp1, "name": _tmp2, "k": _tmp3};};
}; };
}; };
@ -108,7 +106,9 @@ export function toNickClaim(v: _val): undefined | NickClaim {
return result; return result;
} }
export function fromNickClaim(_v: NickClaim): _val {return _.Record($claimNick, [fromUserId(_v["uid"]), _v["name"], _v["k"]]);} export function fromNickClaim(_v: NickClaim): _val {
return _.Record($claimNick, [fromUserId(_v["uid"]), _v["name"], _.embed(_v["k"])]);
}
export function asUserInfo(v: _val): UserInfo { export function asUserInfo(v: _val): UserInfo {
let result = toUserInfo(v); let result = toUserInfo(v);

View File

@ -13,8 +13,6 @@ export type Present = {"username": string};
export type Says = {"who": string, "what": string}; export type Says = {"who": string, "what": string};
export const _toPtr = (v: _val) => {let result: undefined | _ptr; result = _i_Actor.toRef(v); return result;};
export function Present(username: string): Present {return {"username": username};} export function Present(username: string): Present {return {"username": username};}
export function Says({who, what}: {who: string, what: string}): Says {return {"who": who, "what": what};} export function Says({who, what}: {who: string, what: string}): Says {return {"who": who, "what": what};}

View File

@ -1,6 +1,7 @@
import * as _ from "@preserves/core"; import * as _ from "@preserves/core";
import * as _i_Actor from "../runtime/actor";
export const $0 = 0;
export const $1 = 1;
export const $Boolean = Symbol.for("Boolean"); export const $Boolean = Symbol.for("Boolean");
export const $ByteString = Symbol.for("ByteString"); export const $ByteString = Symbol.for("ByteString");
export const $Double = Symbol.for("Double"); export const $Double = Symbol.for("Double");
@ -20,10 +21,9 @@ export const $not = Symbol.for("not");
export const $or = Symbol.for("or"); export const $or = Symbol.for("or");
export const $rec = Symbol.for("rec"); export const $rec = Symbol.for("rec");
export const $ref = Symbol.for("ref"); export const $ref = Symbol.for("ref");
export const $resolve = Symbol.for("resolve");
export const $rewrite = Symbol.for("rewrite"); export const $rewrite = Symbol.for("rewrite");
export type _ptr = _i_Actor.Ref; export type _ptr = any;
export type _val = _.Value<_ptr>; export type _val = _.Value<_ptr>;
@ -40,9 +40,12 @@ export type Rewrite = {"pattern": Pattern, "template": Template};
export type Alts = {"alternatives": Array<Rewrite>}; export type Alts = {"alternatives": Array<Rewrite>};
export type Resolve = {"sturdyref": SturdyRef, "observer": _ptr}; export type Oid = number;
export type Bind = {"oid": _val, "key": _.Bytes, "target": _ptr}; export type WireRef = (
{"_variant": "mine", "oid": Oid} |
{"_variant": "yours", "oid": Oid, "attenuation": Array<Caveat>}
);
export type ConstructorSpec = ( export type ConstructorSpec = (
{"_variant": "CRec", "value": CRec} | {"_variant": "CRec", "value": CRec} |
@ -106,8 +109,6 @@ export type TCompound = {"ctor": ConstructorSpec, "members": TCompoundMembers};
export type TCompoundMembers = _.KeyedDictionary<_val, Template, _ptr>; 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( export function SturdyRef(
{oid, caveatChain, sig}: {oid: _val, caveatChain: Array<Attenuation>, sig: _.Bytes} {oid, caveatChain, sig}: {oid: _val, caveatChain: Array<Attenuation>, sig: _.Bytes}
): SturdyRef {return {"oid": oid, "caveatChain": caveatChain, "sig": sig};} ): SturdyRef {return {"oid": oid, "caveatChain": caveatChain, "sig": sig};}
@ -123,9 +124,12 @@ export function Rewrite({pattern, template}: {pattern: Pattern, template: Templa
export function Alts(alternatives: Array<Rewrite>): Alts {return {"alternatives": alternatives};} export function Alts(alternatives: Array<Rewrite>): Alts {return {"alternatives": alternatives};}
export function Resolve({sturdyref, observer}: {sturdyref: SturdyRef, observer: _ptr}): Resolve {return {"sturdyref": sturdyref, "observer": observer};} export function Oid(value: number): Oid {return value;}
export function Bind({oid, key, target}: {oid: _val, key: _.Bytes, target: _ptr}): Bind {return {"oid": oid, "key": key, "target": target};} export namespace WireRef {
export function mine(oid: Oid): WireRef {return {"_variant": "mine", "oid": oid};};
export function yours({oid, attenuation}: {oid: Oid, attenuation: Array<Caveat>}): WireRef {return {"_variant": "yours", "oid": oid, "attenuation": attenuation};};
}
export namespace ConstructorSpec { export namespace ConstructorSpec {
export function CRec(value: CRec): ConstructorSpec {return {"_variant": "CRec", "value": value};}; export function CRec(value: CRec): ConstructorSpec {return {"_variant": "CRec", "value": value};};
@ -347,53 +351,61 @@ export function toAlts(v: _val): undefined | Alts {
export function fromAlts(_v: Alts): _val {return _.Record($or, [_v["alternatives"].map(v => fromRewrite(v))]);} export function fromAlts(_v: Alts): _val {return _.Record($or, [_v["alternatives"].map(v => fromRewrite(v))]);}
export function asResolve(v: _val): Resolve { export function asOid(v: _val): Oid {
let result = toResolve(v); let result = toOid(v);
if (result === void 0) throw new TypeError(`Invalid Resolve: ${_.stringify(v)}`); if (result === void 0) throw new TypeError(`Invalid Oid: ${_.stringify(v)}`);
return result; return result;
} }
export function toResolve(v: _val): undefined | Resolve { export function toOid(v: _val): undefined | Oid {
let result: undefined | Resolve; let _tmp0: (number) | undefined;
if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { let result: undefined | Oid;
_tmp0 = typeof v === 'number' ? v : void 0;
if (_tmp0 !== void 0) {result = _tmp0;};
return result;
}
export function fromOid(_v: Oid): _val {return _v;}
export function asWireRef(v: _val): WireRef {
let result = toWireRef(v);
if (result === void 0) throw new TypeError(`Invalid WireRef: ${_.stringify(v)}`);
return result;
}
export function toWireRef(v: _val): undefined | WireRef {
let result: undefined | WireRef;
if (_.Array.isArray(v) && v.length === 2) {
let _tmp0: (null) | undefined; let _tmp0: (null) | undefined;
_tmp0 = _.is(v.label, $resolve) ? null : void 0; _tmp0 = _.is(v[0], $0) ? null : void 0;
if (_tmp0 !== void 0) { if (_tmp0 !== void 0) {
let _tmp1: (SturdyRef) | undefined; let _tmp1: (Oid) | undefined;
_tmp1 = toSturdyRef(v[0]); _tmp1 = toOid(v[1]);
if (_tmp1 !== void 0) { if (_tmp1 !== void 0) {result = {"_variant": "mine", "oid": _tmp1};};
let _tmp2: (_ptr) | undefined;
_tmp2 = _toPtr(v[1]);
if (_tmp2 !== void 0) {result = {"sturdyref": _tmp1, "observer": _tmp2};};
};
}; };
}; };
return result; if (result === void 0) {
} if (_.Array.isArray(v) && v.length >= 2) {
let _tmp2: (null) | undefined;
export function fromResolve(_v: Resolve): _val {return _.Record($resolve, [fromSturdyRef(_v["sturdyref"]), _v["observer"]]);} _tmp2 = _.is(v[0], $1) ? null : void 0;
if (_tmp2 !== void 0) {
export function asBind(v: _val): Bind { let _tmp3: (Oid) | undefined;
let result = toBind(v); _tmp3 = toOid(v[1]);
if (result === void 0) throw new TypeError(`Invalid Bind: ${_.stringify(v)}`); if (_tmp3 !== void 0) {
return result; let _tmp4: (Array<_val>) | undefined;
} let _tmp5: (Array<Caveat>) | undefined;
_tmp4 = v.slice(2);
export function toBind(v: _val): undefined | Bind { {
let result: undefined | Bind; _tmp5 = [];
if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { for (const _tmp6 of _tmp4) {
let _tmp0: (null) | undefined; let _tmp7: (Caveat) | undefined;
_tmp0 = _.is(v.label, $bind) ? null : void 0; _tmp7 = toCaveat(_tmp6);
if (_tmp0 !== void 0) { if (_tmp7 !== void 0) {_tmp5.push(_tmp7); continue;};
let _tmp1: (_val) | undefined; _tmp5 = void 0;
_tmp1 = v[0]; break;
if (_tmp1 !== void 0) { };
let _tmp2: (_.Bytes) | undefined; if (_tmp5 !== void 0) {result = {"_variant": "yours", "oid": _tmp3, "attenuation": _tmp5};};
_tmp2 = _.Bytes.isBytes(v[1]) ? v[1] : void 0; };
if (_tmp2 !== void 0) {
let _tmp3: (_ptr) | undefined;
_tmp3 = _toPtr(v[2]);
if (_tmp3 !== void 0) {result = {"oid": _tmp1, "key": _tmp2, "target": _tmp3};};
}; };
}; };
}; };
@ -401,7 +413,14 @@ export function toBind(v: _val): undefined | Bind {
return result; return result;
} }
export function fromBind(_v: Bind): _val {return _.Record($bind, [_v["oid"], _v["key"], _v["target"]]);} export function fromWireRef(_v: WireRef): _val {
switch (_v._variant) {
case "mine": {return [$0, fromOid(_v["oid"])];};
case "yours": {
return [$1, fromOid(_v["oid"]), ... _v["attenuation"].map(v => fromCaveat(v))];
};
};
}
export function asConstructorSpec(v: _val): ConstructorSpec { export function asConstructorSpec(v: _val): ConstructorSpec {
let result = toConstructorSpec(v); let result = toConstructorSpec(v);

View File

@ -10,8 +10,6 @@ export type _val = _.Value<_ptr>;
export type Instance = {"name": string, "argument": _val}; export type Instance = {"name": string, "argument": _val};
export const _toPtr = (v: _val) => {let result: undefined | _ptr; result = _i_Actor.toRef(v); return result;};
export function Instance({name, argument}: {name: string, argument: _val}): Instance {return {"name": name, "argument": argument};} export function Instance({name, argument}: {name: string, argument: _val}): Instance {return {"name": name, "argument": argument};}
export function asInstance(v: _val): Instance { export function asInstance(v: _val): Instance {

View File

@ -1,6 +1,6 @@
// Bags and Deltas (which are Bags where item-counts can be negative). // Bags and Deltas (which are Bags where item-counts can be negative).
import { Value, Set, Dictionary, DefaultPointer } from '@preserves/core'; import { Value, Set, Dictionary, GenericPointer } from '@preserves/core';
export enum ChangeDescription { export enum ChangeDescription {
PRESENT_TO_ABSENT = -1, PRESENT_TO_ABSENT = -1,
@ -9,7 +9,7 @@ export enum ChangeDescription {
PRESENT_TO_PRESENT = 2, PRESENT_TO_PRESENT = 2,
} }
export class Bag<T extends object = DefaultPointer> { export class Bag<T extends object = GenericPointer> {
_items: Dictionary<T, number>; _items: Dictionary<T, number>;
constructor(s?: Set<T>) { constructor(s?: Set<T>) {

View File

@ -23,6 +23,7 @@ import {
TRef, TRef,
Template, Template,
_val, _val,
_ptr,
} from '../gen/sturdy.js'; } from '../gen/sturdy.js';
export * from '../gen/sturdy.js'; export * from '../gen/sturdy.js';
@ -90,9 +91,9 @@ export function match(p: Pattern, v: Assertion): Bindings | null {
} }
return true; return true;
case 'CDict': case 'CDict':
if (!Dictionary.isDictionary<Assertion, Ref>(v)) return false; if (!Dictionary.isDictionary<Ref, Assertion>(v)) return false;
for (const [key, pp] of members) { for (const [key, pp] of members) {
const vv = v.get(key as Assertion); const vv = v.get(key);
if (vv === void 0) return false; if (vv === void 0) return false;
if (!walk(pp, vv)) return false; if (!walk(pp, vv)) return false;
} }
@ -118,7 +119,7 @@ export function instantiate(t: Template, b: Bindings): Assertion {
return v; return v;
} }
case 'Lit': case 'Lit':
return t.value.value as Assertion; return t.value.value;
case 'TCompound': { case 'TCompound': {
const ctor = t.value.ctor; const ctor = t.value.ctor;
const members = t.value.members; const members = t.value.members;
@ -143,7 +144,7 @@ export function instantiate(t: Template, b: Bindings): Assertion {
case 'CDict': { case 'CDict': {
const v = new Dictionary<Ref, Assertion>(); const v = new Dictionary<Ref, Assertion>();
for (const [key, tt] of members) { for (const [key, tt] of members) {
v.set(key as Assertion, walk(tt)); v.set(key, walk(tt));
} }
return v; return v;
} }
@ -233,21 +234,21 @@ export function forwarder(t: Turn, ref: Ref): { proxy: Ref, revoker: Ref } {
export function pRec(label: _val, ... members: Array<Pattern>): Pattern { export function pRec(label: _val, ... members: Array<Pattern>): Pattern {
return Pattern.PCompound(PCompound({ return Pattern.PCompound(PCompound({
ctor: ConstructorSpec.CRec(CRec({ label: label, arity: members.length })), ctor: ConstructorSpec.CRec(CRec({ label: label, arity: members.length })),
members: PCompoundMembers(new Dictionary<Ref, Pattern>( members: PCompoundMembers(new Dictionary<_ptr, Pattern>(
members.map((p, i) => [i, p] as const).filter(e => e[1]._variant !== 'PDiscard')))})); members.map((p, i) => [i, p] as const).filter(e => e[1]._variant !== 'PDiscard')))}));
} }
export function pArr(... members: Array<Pattern>): Pattern { export function pArr(... members: Array<Pattern>): Pattern {
return Pattern.PCompound(PCompound({ return Pattern.PCompound(PCompound({
ctor: ConstructorSpec.CArr(CArr(members.length)), ctor: ConstructorSpec.CArr(CArr(members.length)),
members: PCompoundMembers(new Dictionary<Ref, Pattern>( members: PCompoundMembers(new Dictionary<_ptr, Pattern>(
members.map((p, i) => [i, p] as const).filter(e => e[1]._variant !== 'PDiscard')))})); members.map((p, i) => [i, p] as const).filter(e => e[1]._variant !== 'PDiscard')))}));
} }
export function pDict(... entries: [_val, Pattern][]): Pattern { export function pDict(... entries: [_val, Pattern][]): Pattern {
return Pattern.PCompound(PCompound({ return Pattern.PCompound(PCompound({
ctor: ConstructorSpec.CDict(CDict()), ctor: ConstructorSpec.CDict(CDict()),
members: PCompoundMembers(new Dictionary<Ref, Pattern>(entries))})); members: PCompoundMembers(new Dictionary<_ptr, Pattern>(entries))}));
} }
export function pLit(value: _val): Pattern { export function pLit(value: _val): Pattern {

View File

@ -1,10 +1,10 @@
import { Bytes, Reader } from '@preserves/core'; import { Bytes, Reader } from '@preserves/core';
import { fromSturdyRef, toSturdyRef, toCaveat, attenuate, sturdyDecode, sturdyEncode } from '../transport/sturdy.js'; import { fromSturdyRef, toSturdyRef, toCaveat, attenuate, sturdyDecode, sturdyEncode, _ptr } from '../transport/sturdy.js';
const [ base, pat ] = process.argv.slice(2); const [ base, pat ] = process.argv.slice(2);
const baseCap = toSturdyRef(sturdyDecode(Bytes.fromHex(base ?? ''))); const baseCap = toSturdyRef(sturdyDecode(Bytes.fromHex(base ?? '')));
if (baseCap === void 0) throw new Error("Cannot decode sturdyref"); if (baseCap === void 0) throw new Error("Cannot decode sturdyref");
const cs0 = new Reader(pat).next(); const cs0 = new Reader<_ptr>(pat).next();
if (!Array.isArray(cs0)) throw new Error("Expected array of caveats"); if (!Array.isArray(cs0)) throw new Error("Expected array of caveats");
const cs = cs0.map(c => toCaveat(c) ?? (()=>{ throw new Error("Cannot decode caveat"); })()); const cs = cs0.map(c => toCaveat(c) ?? (()=>{ throw new Error("Cannot decode caveat"); })());
attenuate(baseCap, ... cs).then(derived => { attenuate(baseCap, ... cs).then(derived => {

View File

@ -1,42 +1,24 @@
import { Attenuation, toAttenuation } from '../gen/sturdy.js'; import * as S from '../gen/sturdy.js';
import * as IO from '../gen/protocol.js'; import * as IO from '../gen/protocol.js';
import { Assertion, Ref } from '../runtime/actor.js'; import { Ref } from '../runtime/actor.js';
import { mapPointers } from '@preserves/core'; import { Decoder, DecoderState, Encoder, EncoderState, GenericPointer, neverPointerType, PointerType, Value } from '@preserves/core';
import { pointerNotAllowed } from './sturdy.js';
export type WireSymbol = { oid: IO.Oid, ref: Ref, count: number }; export type WireSymbol = { oid: IO.Oid, ref: Ref, count: number };
export type WireRef = export const wireRefPointerType: PointerType<S.WireRef> = {
| { loc: "mine", oid: IO.Oid } decode(s: DecoderState): S.WireRef {
| { loc: "your", oid: IO.Oid, attenuation: Attenuation }; return S.asWireRef(new Decoder<any>(s).next());
},
export function myRef(oid: IO.Oid): WireRef & { loc: "mine" } { encode(s: EncoderState, v: S.WireRef): void {
return { loc: 'mine', oid }; new Encoder<any>(s, neverPointerType).push(S.fromWireRef(v));
} },
export function yourRef(oid: IO.Oid, attenuation: Attenuation): WireRef & { loc: "your" } { fromValue(v: Value<GenericPointer>): S.WireRef {
return { loc: 'your', oid, attenuation }; return S.asWireRef(v as S._val);
} },
export function toWireRef(v: IO._val): WireRef | undefined { toValue(v: S.WireRef): Value<GenericPointer> {
if (Array.isArray(v) && v.length >= 2) { return S.fromWireRef(v) as Value<GenericPointer>;
switch (v[0]) {
case 0: {
const oid = v[1];
if (typeof oid === 'number') return myRef(oid);
break;
}
case 1: {
const oid = v[1];
if (typeof oid === 'number') {
const attenuation = toAttenuation(mapPointers(v.slice(2), pointerNotAllowed) as Array<Assertion>);
if (attenuation !== void 0) return yourRef(oid, attenuation);
}
break;
}
default:
break;
}
} }
return void 0; };
}

View File

@ -1,11 +1,10 @@
import { Actor, Assertion, Entity, Facet, Handle, Ref, Turn } from '../runtime/actor.js'; import { Actor, Assertion, Entity, Facet, Handle, Ref, Turn } from '../runtime/actor.js';
import { BytesLike, canonicalString, Decoder, encode, FlexMap, IdentityMap, mapPointers, underlying, Value } from '@preserves/core'; import { BytesLike, Decoder, Dictionary, embed, encode, IdentityMap, mapPointers, underlying, Value } from '@preserves/core';
import * as IO from '../gen/protocol.js'; import * as IO from '../gen/protocol.js';
import { myRef, toWireRef, WireRef, WireSymbol, yourRef } from './protocol.js'; import { wireRefPointerType, WireSymbol } from './protocol.js';
import { queueTask } from '../runtime/task.js'; import { queueTask } from '../runtime/task.js';
import { attenuate } from '../runtime/rewrite.js'; import { attenuate } from '../runtime/rewrite.js';
import { Attenuation, fromAttenuation } from '../gen/sturdy.js'; import { fromAttenuation, WireRef } from '../gen/sturdy.js';
import { pointerNotAllowed } from './sturdy.js';
export class SyncPeerEntity implements Entity { export class SyncPeerEntity implements Entity {
readonly relay: Relay; readonly relay: Relay;
@ -136,8 +135,10 @@ export class Relay {
debug: boolean; debug: boolean;
trustPeer: boolean; trustPeer: boolean;
readonly decoder = new Decoder(void 0, { includeAnnotations: false }) readonly decoder = new Decoder(void 0, {
.replacePointerDecoder<WireRef>(d => toWireRef(d.next())); includeAnnotations: false,
pointerType: wireRefPointerType,
});
constructor(t: Turn, options: RelayOptions) { constructor(t: Turn, options: RelayOptions) {
this.facet = t.activeFacet; this.facet = t.activeFacet;
@ -152,14 +153,14 @@ export class Relay {
rewriteOut(assertion: Assertion, transient: boolean): [Value<WireRef>, Array<WireSymbol>] rewriteOut(assertion: Assertion, transient: boolean): [Value<WireRef>, Array<WireSymbol>]
{ {
const exported: Array<WireSymbol> = []; const exported: Array<WireSymbol> = [];
const rewritten = mapPointers(assertion, r => this.rewriteRefOut(r, transient, exported)); const rewritten = mapPointers(assertion, r => embed(this.rewriteRefOut(r, transient, exported)));
return [rewritten, exported]; return [rewritten, exported];
} }
rewriteIn(t: Turn, a: Value<WireRef>): [Assertion, Array<WireSymbol>] rewriteIn(t: Turn, a: Value<WireRef>): [Assertion, Array<WireSymbol>]
{ {
const imported: Array<WireSymbol> = []; const imported: Array<WireSymbol> = [];
const rewritten = mapPointers(a, r => this.rewriteRefIn(t, r, imported)); const rewritten = mapPointers(a, r => embed(this.rewriteRefIn(t, r, imported)));
return [rewritten, imported]; return [rewritten, imported];
} }
@ -177,12 +178,12 @@ export class Relay {
if (r.target instanceof RelayEntity && r.target.relay === this) { if (r.target instanceof RelayEntity && r.target.relay === this) {
if (r.attenuation === void 0 || r.attenuation.length === 0) { if (r.attenuation === void 0 || r.attenuation.length === 0) {
// No extra conditions on this reference since it was sent to us. // No extra conditions on this reference since it was sent to us.
return yourRef(r.target.oid, []); return WireRef.yours({ oid: r.target.oid, attenuation: [] });
} else { } else {
// This reference has been attenuated since it was sent to us. // This reference has been attenuated since it was sent to us.
// Do we trust the peer to enforce such attenuation on our behalf? // Do we trust the peer to enforce such attenuation on our behalf?
if (this.trustPeer) { if (this.trustPeer) {
return yourRef(r.target.oid, r.attenuation); return WireRef.yours({ oid: r.target.oid, attenuation: r.attenuation });
} else { } else {
// fall through: treat the attenuated ref as a local ref, and re-export it. // fall through: treat the attenuated ref as a local ref, and re-export it.
} }
@ -195,7 +196,7 @@ export class Relay {
return { oid: this.nextLocalOid++, ref: r, count: 0 }; return { oid: this.nextLocalOid++, ref: r, count: 0 };
}); });
exported.push(e); exported.push(e);
return myRef(e.oid); return WireRef.mine(e.oid);
} }
releaseRefOut(e: WireSymbol) { releaseRefOut(e: WireSymbol) {
@ -203,18 +204,18 @@ export class Relay {
} }
rewriteRefIn(t: Turn, n: WireRef, imported: Array<WireSymbol>): Ref { rewriteRefIn(t: Turn, n: WireRef, imported: Array<WireSymbol>): Ref {
switch (n.loc) { switch (n._variant) {
case 'your': { case 'yours': {
const r = this.lookupLocal(n.oid); const r = this.lookupLocal(n.oid);
if (n.attenuation.length === 0 || r === INERT_REF) { if (n.attenuation.length === 0 || r === INERT_REF) {
return r; return r;
} else { } else {
type AttenuatedRef = Ref & { __attenuations?: FlexMap<Attenuation, Ref> }; type AttenuatedRef = Ref & { __attenuations?: Dictionary<any, Ref> };
const ar = r as AttenuatedRef; const ar = r as AttenuatedRef;
if (ar.__attenuations === void 0) { if (ar.__attenuations === void 0) {
ar.__attenuations = new FlexMap(canonicalString); ar.__attenuations = new Dictionary();
} }
return ar.__attenuations.getOrSet(n.attenuation, () => return ar.__attenuations.getOrSet(fromAttenuation(n.attenuation), () =>
attenuate(r, ... n.attenuation)); attenuate(r, ... n.attenuation));
} }
} }
@ -231,15 +232,9 @@ export class Relay {
if (this.pendingTurn.length === 0) { if (this.pendingTurn.length === 0) {
queueTask(() => { queueTask(() => {
if (this.debug) console.log('OUT', IO.fromTurn(this.pendingTurn).asPreservesText()); if (this.debug) console.log('OUT', IO.fromTurn(this.pendingTurn).asPreservesText());
this.w(underlying(encode<WireRef>(IO.fromTurn(this.pendingTurn), { this.w(underlying(encode(IO.fromTurn(this.pendingTurn), {
canonical: true, canonical: true,
encodePointer: (e, n) => { pointerType: wireRefPointerType,
switch (n.loc) {
case 'mine': return e.push([0, n.oid]);
case 'your': return e.push([1, n.oid, ... mapPointers<Ref, IO._ptr>(
fromAttenuation(n.attenuation), pointerNotAllowed) as Array<IO._val>]);
}
},
}))); })));
this.pendingTurn = []; this.pendingTurn = [];
}); });
@ -323,7 +318,7 @@ export function spawnRelay(t: Turn, options: RelayActorOptions): Promise<Ref | n
relay.rewriteRefOut(options.initialRef, false, []); relay.rewriteRefOut(options.initialRef, false, []);
} }
if (options.initialOid !== void 0) { if (options.initialOid !== void 0) {
resolve(relay.rewriteRefIn(t, myRef(options.initialOid), [])); resolve(relay.rewriteRefIn(t, WireRef.mine(options.initialOid), []));
} else { } else {
resolve(null); resolve(null);
} }

View File

@ -7,7 +7,7 @@
// California: Internet Society, 2014. // California: Internet Society, 2014.
import { mac } from './cryptography.js'; import { mac } from './cryptography.js';
import { Bytes, decode, encode, is } from '@preserves/core'; import { Bytes, decode, encode, is, neverPointerType } from '@preserves/core';
import * as S from '../gen/sturdy.js'; import * as S from '../gen/sturdy.js';
export * from '../gen/sturdy.js'; export * from '../gen/sturdy.js';
@ -23,14 +23,14 @@ export function sturdyEncode(v: SturdyValue): Bytes {
return encode<S._ptr>(v, { return encode<S._ptr>(v, {
canonical: true, canonical: true,
includeAnnotations: false, includeAnnotations: false,
encodePointer: pointerNotAllowed, pointerType: neverPointerType,
}); });
} }
export function sturdyDecode(bs: Bytes): SturdyValue { export function sturdyDecode(bs: Bytes): SturdyValue {
return decode<S._ptr>(bs, { return decode<S._ptr>(bs, {
includeAnnotations: false, includeAnnotations: false,
decodePointer: pointerNotAllowed, pointerType: neverPointerType,
}); });
} }

View File

@ -1,13 +1,9 @@
// Web Worker loader // Web Worker loader
import { Actor, Turn, Assertion, Ref, __setNextActorId } from '../runtime/actor.js'; import { Actor, Turn, Ref, __setNextActorId } from '../runtime/actor.js';
import { Record } from '@preserves/core';
import { parentPort, threadId } from 'worker_threads'; import { parentPort, threadId } from 'worker_threads';
import { Relay, spawnRelay } from '../transport/relay.js'; import { Relay, spawnRelay } from '../transport/relay.js';
import { toInstance } from '../gen/worker.js';
const _Instance = Symbol.for('Instance');
const Instance = Record.makeConstructor<{moduleName: string, arg: Assertion}>()(
_Instance, ['moduleName', 'arg']);
const STARTING_ACTOR_ID = (threadId & (2 ** 20 - 1)) * 1000000000; const STARTING_ACTOR_ID = (threadId & (2 ** 20 - 1)) * 1000000000;
__setNextActorId(STARTING_ACTOR_ID); __setNextActorId(STARTING_ACTOR_ID);
@ -30,13 +26,14 @@ new Actor(t => {
p.on('close', () => Turn.for(t.activeFacet, t => t.stopActor())); p.on('close', () => Turn.for(t.activeFacet, t => t.stopActor()));
}, },
initialRef: t.ref({ initialRef: t.ref({
async assert(t, inst) { async assert(t, inst0) {
if (!Instance.isClassOf(inst)) return; const inst = toInstance(inst0);
if (inst === void 0) return;
if (taskState.state !== "start_pending") return; if (taskState.state !== "start_pending") return;
taskState = { state: "starting" }; taskState = { state: "starting" };
const m = await import(Instance._.moduleName(inst)); const m = await import(inst.name);
t.freshen(t => t.spawn(t => { t.freshen(t => t.spawn(t => {
t.activeFacet.actor.atExit(() => { t.activeFacet.actor.atExit(() => {
console.log('Worker terminating'); console.log('Worker terminating');
@ -49,7 +46,7 @@ new Actor(t => {
state: "running", state: "running",
shutdownRef: t.ref({ message(t) { t.stopActor(); } }), shutdownRef: t.ref({ message(t) { t.stopActor(); } }),
}; };
m.default(t, Instance._.arg(inst)); m.default(t, inst.argument);
} }
})); }));
}, },