Switch to directly-represented embedded values
This commit is contained in:
parent
f5ed511c4e
commit
9521fc3dcc
|
@ -1,7 +1,7 @@
|
|||
/// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
/// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||
|
||||
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<T = AnyValue> = LocalAction & { detail: T };
|
||||
|
||||
export type Assertable = Assertion | { __as_preserve__: <T>() => Value<T> } | { __as_preserve__: () => Assertion };
|
||||
export type Assertable =
|
||||
| Assertion
|
||||
| { __as_preserve__: <T extends Embeddable>() => Value<T> }
|
||||
| { __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<Entity>;
|
||||
readonly attenuation?: Caveat[];
|
||||
}
|
||||
|
||||
export class RefImpl implements Ref {
|
||||
export class Ref {
|
||||
readonly relay: Facet;
|
||||
readonly target: Partial<Entity>;
|
||||
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<T extends Partial<Entity>>(e: T): Ref {
|
||||
return new RefImpl(this.activeFacet, e);
|
||||
return new Ref(this.activeFacet, e);
|
||||
}
|
||||
|
||||
facet(bootProc: LocalAction): Facet {
|
||||
|
|
|
@ -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<T, V extends Value<T> = Value<T>> {
|
||||
export class Bag<T extends Embeddable, V extends Value<T> = Value<T>> {
|
||||
_items: KeyedDictionary<V, number, T>;
|
||||
|
||||
constructor(s?: KeyedSet<V, T>) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||
|
||||
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;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
/// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||
|
||||
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<T> {
|
|||
}
|
||||
}
|
||||
|
||||
function dumpBag<T, V extends Value<T>>(b: Bag<T, V>, indent: string) {
|
||||
function dumpBag<T extends Embeddable, V extends Value<T>>(b: Bag<T, V>, indent: string) {
|
||||
for (const [v, count] of b.entries()) {
|
||||
console.log(indent + stringify(v) + ' = ' + count);
|
||||
}
|
||||
}
|
||||
|
||||
function dumpSet<V>(s: Set<V>, indent: string) {
|
||||
function dumpSet<V extends Embeddable>(s: Set<V>, indent: string) {
|
||||
s.forEach(v => console.log(indent + stringify(v)));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||
|
||||
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<WireRef> {
|
||||
const transient = (handle === null);
|
||||
const pins: Array<WireSymbol> = [];
|
||||
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<WireRef>): [Assertion, Array<WireSymbol>]
|
||||
{
|
||||
const pins: Array<WireSymbol> = [];
|
||||
const rewritten = mapEmbeddeds(a, r => embed(this.rewriteRefIn(r, pins)));
|
||||
const rewritten = mapEmbeddeds(a, r => this.rewriteRefIn(r, pins));
|
||||
return [rewritten, pins];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
/// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||
|
||||
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<Ref>).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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Ref> = 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<R>(route: E.StandardRoute<R>): G.Route<R> {
|
||||
export function unpackStandardRoute<R extends Embeddable>(route: E.StandardRoute<R>): G.Route<R> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue