From 9521fc3dcc0feb189b61523cfebde5ef44833e5e Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Tue, 12 Mar 2024 21:38:49 +0100 Subject: [PATCH] Switch to directly-represented embedded values --- packages/core/src/runtime/actor.ts | 22 ++++++++-------- packages/core/src/runtime/bag.ts | 4 +-- packages/core/src/runtime/rewrite.ts | 5 ++-- packages/core/src/runtime/skeleton.ts | 6 ++--- packages/core/src/transport/relay.ts | 6 ++--- packages/html/src/index.ts | 12 ++++----- packages/ws-relay/src/index.ts | 36 +++++++++++---------------- 7 files changed, 43 insertions(+), 48 deletions(-) diff --git a/packages/core/src/runtime/actor.ts b/packages/core/src/runtime/actor.ts index f0e5065..79ebe29 100644 --- a/packages/core/src/runtime/actor.ts +++ b/packages/core/src/runtime/actor.ts @@ -1,7 +1,7 @@ /// SPDX-License-Identifier: GPL-3.0-or-later /// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones -import { IdentitySet, Value, embeddedId, is, fromJS, stringify, Dictionary, KeyedSet, Tuple } from '@preserves/core'; +import { IdentitySet, Value, embeddedId, is, fromJS, stringify, Dictionary, KeyedSet, Tuple, Embeddable } from '@preserves/core'; import { Cell, Field, Graph } from './dataflow.js'; import { Caveat, runRewrites } from './rewrite.js'; import { ActorSpace } from './space.js'; @@ -23,7 +23,11 @@ export type ExitReason = null | { ok: true } | { ok: false, err: unknown }; export type LocalAction = () => void; export type DetailedAction = LocalAction & { detail: T }; -export type Assertable = Assertion | { __as_preserve__: () => Value } | { __as_preserve__: () => Assertion }; +export type Assertable = + | Assertion + | { __as_preserve__: () => Value } + | { __as_preserve__: () => Assertion } +; export interface Entity { assert(assertion: Assertion, handle: Handle): void; @@ -35,13 +39,7 @@ export interface Entity { export type Cap = Ref; -export interface Ref { - readonly relay: Facet; - readonly target: Partial; - readonly attenuation?: Caveat[]; -} - -export class RefImpl implements Ref { +export class Ref { readonly relay: Facet; readonly target: Partial; readonly attenuation?: Caveat[]; @@ -64,6 +62,10 @@ export class RefImpl implements Ref { if ('sync' in this.target) sig = sig + 'S'; return `⌜${this.relay.idChain()}<${sig}>${entityRepr}⌝`; } + + static __from_preserve__(v: AnyValue): undefined | Ref { + return typeof v === 'object' && 'relay' in v ? v : void 0; + } } //--------------------------------------------------------------------------- @@ -351,7 +353,7 @@ export class Turn { } ref>(e: T): Ref { - return new RefImpl(this.activeFacet, e); + return new Ref(this.activeFacet, e); } facet(bootProc: LocalAction): Facet { diff --git a/packages/core/src/runtime/bag.ts b/packages/core/src/runtime/bag.ts index 423ca88..9611c11 100644 --- a/packages/core/src/runtime/bag.ts +++ b/packages/core/src/runtime/bag.ts @@ -3,7 +3,7 @@ // Bags and Deltas (which are Bags where item-counts can be negative). -import { Value, KeyedDictionary, KeyedSet } from '@preserves/core'; +import { Value, KeyedDictionary, KeyedSet, Embeddable } from '@preserves/core'; export enum ChangeDescription { PRESENT_TO_ABSENT = -1, @@ -12,7 +12,7 @@ export enum ChangeDescription { PRESENT_TO_PRESENT = 2, } -export class Bag = Value> { +export class Bag = Value> { _items: KeyedDictionary; constructor(s?: KeyedSet) { diff --git a/packages/core/src/runtime/rewrite.ts b/packages/core/src/runtime/rewrite.ts index 93e08e6..a1b0fe5 100644 --- a/packages/core/src/runtime/rewrite.ts +++ b/packages/core/src/runtime/rewrite.ts @@ -2,7 +2,7 @@ /// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones import { Turn } from "./actor.js"; -import { Bytes, Dictionary, DoubleFloat, embed, IdentityMap, is, isEmbedded, Record, Tuple, stringify } from "@preserves/core"; +import { Bytes, Dictionary, DoubleFloat, IdentityMap, is, isEmbedded, Record, Tuple, stringify } from "@preserves/core"; import type { Assertion, Handle, Ref } from "./actor.js"; import type { SturdyValue } from "../transport/sturdy.js"; @@ -113,8 +113,7 @@ export function instantiate(t: Template, b: Bindings): Assertion { if (!isEmbedded(v)) { throw new Error(`Attempt to attenuate non-capability: ${stringify(v)}`); } - const r = v.embeddedValue; - return embed(attenuate(r, ... t.value.attenuation)); + return attenuate(v, ... t.value.attenuation); } case 'TRef': { const n = t.value.binding; diff --git a/packages/core/src/runtime/skeleton.ts b/packages/core/src/runtime/skeleton.ts index dd385ca..1339445 100644 --- a/packages/core/src/runtime/skeleton.ts +++ b/packages/core/src/runtime/skeleton.ts @@ -1,7 +1,7 @@ /// SPDX-License-Identifier: GPL-3.0-or-later /// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones -import { Set, Dictionary, KeyedDictionary, IdentitySet, stringify, Value } from '@preserves/core'; +import { Set, Dictionary, KeyedDictionary, IdentitySet, stringify, Value, Embeddable } from '@preserves/core'; import { AnyValue, Assertion, Ref } from './actor.js'; import { Bag, ChangeDescription } from './bag.js'; import * as Stack from './stack.js'; @@ -142,13 +142,13 @@ export class Index { } } -function dumpBag>(b: Bag, indent: string) { +function dumpBag>(b: Bag, indent: string) { for (const [v, count] of b.entries()) { console.log(indent + stringify(v) + ' = ' + count); } } -function dumpSet(s: Set, indent: string) { +function dumpSet(s: Set, indent: string) { s.forEach(v => console.log(indent + stringify(v))); } diff --git a/packages/core/src/transport/relay.ts b/packages/core/src/transport/relay.ts index e896444..6c88310 100644 --- a/packages/core/src/transport/relay.ts +++ b/packages/core/src/transport/relay.ts @@ -2,7 +2,7 @@ /// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones import { Actor, Assertion, Entity, Facet, Handle, Ref, Turn } from '../runtime/actor.js'; -import { BytesLike, Decoder, Dictionary, embed, encode, IdentityMap, mapEmbeddeds, stringify, underlying, Value } from '@preserves/core'; +import { BytesLike, Decoder, Dictionary, encode, IdentityMap, mapEmbeddeds, stringify, underlying, Value } from '@preserves/core'; import * as IO from '../gen/protocol.js'; import { wireRefEmbeddedType } from './protocol.js'; import { attenuate } from '../runtime/rewrite.js'; @@ -193,7 +193,7 @@ export class Relay { register(targetRemoteOid: IO.Oid | null, assertion: Assertion, handle: Handle | null): Value { const transient = (handle === null); const pins: Array = []; - const rewritten = mapEmbeddeds(assertion, r => embed(this.rewriteRefOut(r, transient, pins))); + const rewritten = mapEmbeddeds(assertion, r => this.rewriteRefOut(r, transient, pins)); if (handle !== null) { if (targetRemoteOid !== null /* belt and suspenders */) { this.grabImportedOid(targetRemoteOid, pins); @@ -316,7 +316,7 @@ export class Relay { rewriteIn(a: Value): [Assertion, Array] { const pins: Array = []; - const rewritten = mapEmbeddeds(a, r => embed(this.rewriteRefIn(r, pins))); + const rewritten = mapEmbeddeds(a, r => this.rewriteRefIn(r, pins)); return [rewritten, pins]; } diff --git a/packages/html/src/index.ts b/packages/html/src/index.ts index b98e94a..07d3b03 100644 --- a/packages/html/src/index.ts +++ b/packages/html/src/index.ts @@ -1,7 +1,7 @@ /// SPDX-License-Identifier: GPL-3.0-or-later /// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones -import { randomId, Observe, FlexMap, embed, Embedded, Ref, Turn, AnyValue, Dataspace } from "@syndicate-lang/core"; +import { randomId, Observe, FlexMap, Ref, Turn, AnyValue, Dataspace } from "@syndicate-lang/core"; import { QuasiValue as Q } from "@syndicate-lang/core"; import * as P from "./protocol"; @@ -46,7 +46,7 @@ export function spawnGlobalEventFactory(ds: Ref) { function handler(event: Event) { facet.turn(() => { - send message P.GlobalEvent(selector, eventType, embed(create ({ data: event }))); + send message P.GlobalEvent(selector, eventType, create ({ data: event })); }); return dealWithPreventDefault(eventType, event); } @@ -78,7 +78,7 @@ export function spawnWindowEventFactory(ds: Ref) { let handler = (event: Event) => { facet.turn(() => { - send message P.WindowEvent(eventType, embed(create ({ data: event }))); + send message P.WindowEvent(eventType, create ({ data: event })); }); return dealWithPreventDefault(eventType, event); }; @@ -149,7 +149,7 @@ function spawnUIFragmentFactory(ds: Ref) { removeNodes(); selector = newSelector; - html = (newHtml as Embedded).embeddedValue.target.data as ChildNode[]; + html = (newHtml as Ref).target.data as ChildNode[]; orderBy = newOrderBy; anchorNodes = (selector !== null) ? selectorMatch(document.body, selector) : []; @@ -191,7 +191,7 @@ function spawnUIFragmentFactory(ds: Ref) { const facet = Turn.activeFacet; function handler(event: Event) { facet.turn(() => { - send message P.UIEvent(fragmentId, selector, eventType, embed(create ({ data: event }))); + send message P.UIEvent(fragmentId, selector, eventType, create ({ data: event })); }); return dealWithPreventDefault(eventType, event); } @@ -507,7 +507,7 @@ export class Anchor { if (!Array.isArray(html)) { html = html.nodes(); } - return P.UIFragment(this.fragmentId, selector, embed(create ({ data: html })), orderBy); + return P.UIFragment(this.fragmentId, selector, create ({ data: html }), orderBy); } } diff --git a/packages/ws-relay/src/index.ts b/packages/ws-relay/src/index.ts index 10bbf5a..4845601 100644 --- a/packages/ws-relay/src/index.ts +++ b/packages/ws-relay/src/index.ts @@ -6,7 +6,6 @@ import { Assertion, Bytes, Dataspace, - Embedded, IdentitySet, Observe, QuasiValue as Q, @@ -23,6 +22,7 @@ import { isEmbedded, stringify, underlying, + Embeddable, } from "@syndicate-lang/core"; import G = Schemas.gatekeeper; import S = Schemas.sturdy; @@ -140,14 +140,10 @@ export function boot(ds = Dataspace.global, debug: boolean = false, WebSocketCon console.log('tracking', addr.url); during G.TransportConnection({ "addr": addr, - "control": $control_e: Embedded, - "resolved": G.Resolved.accepted($peer_e: Embedded), + "control": $control: Ref, + "resolved": G.Resolved.accepted($peer: Ref), }) => { - const entry = { - addr, - control: control_e.embeddedValue, - peer: peer_e.embeddedValue, - }; + const entry = { addr, control, peer }; candidates.value.add(entry); candidates.changed(); on stop { @@ -237,11 +233,10 @@ export function boot(ds = Dataspace.global, debug: boolean = false, WebSocketCon }) }) => { const origin0 = Q.drop_lit(originPatValue); if (!origin0 || !isEmbedded(origin0)) return; - const origin = origin0.embeddedValue; + const origin = origin0; - const detail0 = Q.drop_lit(detailPatValue, N.toNoisePathStepDetail); - if (!detail0) return; - const spec: N.NoiseSpec = detail0; + const spec = Q.drop_lit(detailPatValue, N.toNoisePathStepDetail); + if (!spec) return; const algorithms = SaltyCrypto.Noise_25519_ChaChaPoly_BLAKE2s; const protocol = @@ -378,11 +373,10 @@ export function boot(ds = Dataspace.global, debug: boolean = false, WebSocketCon }) }) => { const origin0 = Q.drop_lit(originPatValue); if (!origin0 || !isEmbedded(origin0)) return; - const origin = origin0.embeddedValue; + const origin = origin0; - const detail0 = Q.drop_lit(detailPatValue, S.toSturdyPathStepDetail); - if (!detail0) return; - const parameters: S.Parameters = detail0; + const parameters = Q.drop_lit(detailPatValue, S.toSturdyPathStepDetail); + if (!parameters) return; at origin { assert G.Resolve({ @@ -411,7 +405,7 @@ export function boot(ds = Dataspace.global, debug: boolean = false, WebSocketCon } } -export function unpackStandardRoute(route: E.StandardRoute): G.Route { +export function unpackStandardRoute(route: E.StandardRoute): G.Route { if (route._variant === 'general') return route.value; const { transports, key, service, sig, oid } = route; @@ -465,15 +459,15 @@ export function contactRemote( ) => void, ds = Dataspace.global, ) { - const routeValue = Record.isRecord(route) ? route : G.fromRoute(G.Route(route)); + const routeValue = 'pathSteps' in route ? G.fromRoute(G.Route(route)) : route; at ds { during G.ResolvePath({ "route": routeValue, "addr": $addr, - "control": $control_e: Embedded, - "resolved": G.Resolved.accepted($resolved_e: Embedded), + "control": $control: Ref, + "resolved": G.Resolved.accepted($resolved: Ref), }) => { - connectedFacet(resolved_e.embeddedValue, control_e.embeddedValue, addr); + connectedFacet(resolved, control, addr); } } }