Updates for js-preserves2 Preserves implementation
This commit is contained in:
parent
cbcd4b9ad9
commit
fd491b5c71
|
@ -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, Embeddable } from '@preserves/core';
|
||||
import { IdentitySet, Value, embeddedId, is, fromJS, stringify, KeyedSet, Tuple, Embeddable, IsEmbedded } from '@preserves/core';
|
||||
import { Cell, Field, Graph } from './dataflow.js';
|
||||
import { Caveat, runRewrites } from './rewrite.js';
|
||||
import { ActorSpace } from './space.js';
|
||||
|
@ -40,6 +40,8 @@ export interface Entity {
|
|||
export type Cap = Ref;
|
||||
|
||||
export class Ref {
|
||||
get [IsEmbedded](): true { return true; }
|
||||
|
||||
readonly relay: Facet;
|
||||
readonly target: Partial<Entity>;
|
||||
readonly attenuation?: Caveat[];
|
||||
|
@ -64,7 +66,7 @@ export class Ref {
|
|||
}
|
||||
|
||||
static __from_preserve__(v: AnyValue): undefined | Ref {
|
||||
return typeof v === 'object' && 'relay' in v ? v : void 0;
|
||||
return typeof v === 'object' && IsEmbedded in v && 'relay' in v ? v : void 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,7 +403,7 @@ export class Turn {
|
|||
});
|
||||
},
|
||||
() => {
|
||||
const a = new KeyedSet<number, Ref>();
|
||||
const a = new KeyedSet<Ref, number>();
|
||||
initialAssertions.forEach(h => a.add(h));
|
||||
return Q.ActionDescription.spawnActor({ detail, initialAssertions: a });
|
||||
});
|
||||
|
@ -430,10 +432,10 @@ export class Turn {
|
|||
crash(err: Error): void {
|
||||
this.enqueue(this.activeFacet.actor.root,
|
||||
() => this.activeFacet.actor._terminateWith({ ok: false, err }),
|
||||
() => Q.ActionDescription.stopActor(Q.OptionalAny.some(Dictionary.fromJS({
|
||||
() => Q.ActionDescription.stopActor(Q.OptionalAny.some<Ref>({
|
||||
message: err.message,
|
||||
stack: err.stack ? err.stack : false,
|
||||
}))));
|
||||
})));
|
||||
}
|
||||
|
||||
field<V>(initial: V, name?: string): Field<V> {
|
||||
|
|
|
@ -13,9 +13,9 @@ export enum ChangeDescription {
|
|||
}
|
||||
|
||||
export class Bag<T extends Embeddable, V extends Value<T> = Value<T>> {
|
||||
_items: KeyedDictionary<V, number, T>;
|
||||
_items: KeyedDictionary<T, V, number>;
|
||||
|
||||
constructor(s?: KeyedSet<V, T>) {
|
||||
constructor(s?: KeyedSet<T, V>) {
|
||||
this._items = new KeyedDictionary();
|
||||
if (s) s.forEach((v) => this._items.set(v, 1));
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ export class Bag<T extends Embeddable, V extends Value<T> = Value<T>> {
|
|||
this._items.forEach((c, v) => f(c, v));
|
||||
}
|
||||
|
||||
snapshot(): KeyedDictionary<V, number, T> {
|
||||
snapshot(): KeyedDictionary<T, V, number> {
|
||||
return this._items.clone();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ export type DataspaceOptions = {
|
|||
};
|
||||
|
||||
export class DataspaceObserver implements IndexObserver<Turn> {
|
||||
readonly captureMap = new KeyedDictionary<Array<AnyValue>, Handle, Ref>();
|
||||
readonly captureMap = new KeyedDictionary<Ref, Array<AnyValue>, Handle>();
|
||||
|
||||
constructor(
|
||||
public readonly target: Ref,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
/// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||
|
||||
import { canonicalString, KeyedDictionary, Dictionary, is, Record, RecordConstructorInfo, Value, CompoundKey, _iterMap } from '@preserves/core';
|
||||
import { canonicalString, KeyedDictionary, is, Record, RecordConstructorInfo, Value, _iterMap, DictionaryMap, Dictionary } from '@preserves/core';
|
||||
import { AnyValue, Ref } from './actor.js';
|
||||
import * as P from '../gen/dataspacePatterns.js';
|
||||
|
||||
|
@ -14,7 +14,7 @@ export function classOfValue(v: any): Shape | null {
|
|||
return constructorInfoSignature(Record.constructorInfo(v));
|
||||
} else if (Array.isArray(v)) {
|
||||
return '' + v.length;
|
||||
} else if (Map.isMap(v)) {
|
||||
} else if (Dictionary.isDictionary(v)) {
|
||||
return '{}';
|
||||
} else {
|
||||
return null;
|
||||
|
@ -38,8 +38,9 @@ export function constructorInfoSignature(ci: RecordConstructorInfo<Value>): stri
|
|||
}
|
||||
|
||||
export function step(v: AnyValue, index: AnyValue): AnyValue | undefined {
|
||||
if (Map.isMap(v)) {
|
||||
return v.get(index);
|
||||
const vMap = Dictionary.asMap<Ref>(v);
|
||||
if (vMap) {
|
||||
return vMap.get(index);
|
||||
} else {
|
||||
return (v as Array<AnyValue> /* includes Record! */)[index as number];
|
||||
}
|
||||
|
@ -169,7 +170,7 @@ export function withoutCaptures(p: P.Pattern): P.Pattern {
|
|||
case 'arr':
|
||||
return P.Pattern.DCompound(P.DCompound.arr(p.value.items.map(walk)));
|
||||
case 'dict': {
|
||||
const newDict = new KeyedDictionary<Value<Ref>, P.Pattern<Ref>, Ref>();
|
||||
const newDict = new KeyedDictionary<Ref, Value<Ref>, P.Pattern<Ref>>();
|
||||
for (const [k, v] of p.value.entries) {
|
||||
newDict.set(k, walk(v));
|
||||
}
|
||||
|
@ -204,14 +205,20 @@ export function lit(v: AnyValue): P.Pattern {
|
|||
} else {
|
||||
return P.Pattern.DCompound(P.DCompound.arr(v.map(lit)));
|
||||
}
|
||||
} else if (Map.isMap(v)) {
|
||||
return P.Pattern.DCompound(P.DCompound.dict(v.mapEntries(
|
||||
e => [e[0], lit(e[1])])));
|
||||
} else if (Set.isSet(v)) {
|
||||
throw new Error("Cannot express literal set in pattern");
|
||||
} else {
|
||||
return P.Pattern.DLit(P.DLit(P.asAnyAtom(v)));
|
||||
}
|
||||
|
||||
const vMap = Dictionary.asMap<Ref>(v);
|
||||
if (vMap) {
|
||||
const r = new KeyedDictionary<Ref, AnyValue, P.Pattern>();
|
||||
vMap.forEach((val, key) => r.set(key, lit(val)));
|
||||
return P.Pattern.DCompound(P.DCompound.dict(r));
|
||||
}
|
||||
|
||||
if (Set.isSet(v)) {
|
||||
throw new Error("Cannot express literal set in pattern");
|
||||
}
|
||||
|
||||
return P.Pattern.DLit(P.DLit(P.asAnyAtom(v)));
|
||||
}
|
||||
|
||||
export function drop_lit(p: P.Pattern): AnyValue | null {
|
||||
|
@ -229,9 +236,9 @@ export function drop_lit(p: P.Pattern): AnyValue | null {
|
|||
case 'arr':
|
||||
return p.value.items.map(walk);
|
||||
case 'dict': {
|
||||
const v = new Dictionary<Ref, AnyValue>();
|
||||
const v = new DictionaryMap<Ref, AnyValue>();
|
||||
p.value.entries.forEach((pp, key) => v.set(key, walk(pp)));
|
||||
return v;
|
||||
return v.simplifiedValue();
|
||||
}
|
||||
}
|
||||
case 'DLit':
|
||||
|
@ -257,5 +264,6 @@ export function arr(... patterns: P.Pattern[]): P.Pattern {
|
|||
}
|
||||
|
||||
export function dict(... entries: [AnyValue, P.Pattern][]): P.Pattern {
|
||||
return P.Pattern.DCompound(P.DCompound.dict(new Dictionary<Ref, P.Pattern>(entries)));
|
||||
return P.Pattern.DCompound(P.DCompound.dict(
|
||||
new KeyedDictionary<Ref, AnyValue, P.Pattern>(entries)));
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
import { AnyValue, Ref } from './actor.js';
|
||||
import { Pattern, toPattern } from '../gen/dataspacePatterns.js';
|
||||
import * as P from './pattern.js';
|
||||
import { RecordConstructorInfo, is, Record } from '@preserves/core';
|
||||
import { RecordConstructorInfo, is, Record, JsDictionary } from '@preserves/core';
|
||||
import { Meta, Type, GenType, SchemaDefinition } from '@preserves/schema';
|
||||
|
||||
export type QuasiValueConstructorInfo =
|
||||
|
@ -100,7 +100,7 @@ export function ctor(info: QuasiValueConstructorInfo, ... items: QuasiValue[]):
|
|||
} else if ('schema' in info) {
|
||||
const definfo = info.schema();
|
||||
const schema = Meta.asSchema(definfo.schema);
|
||||
const def = schema.definitions.get(definfo.definitionName)!;
|
||||
const def = JsDictionary.get(schema.definitions, definfo.definitionName)!;
|
||||
const defNameStr = definfo.definitionName.description!;
|
||||
const ctorArgs = items.slice();
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||
|
||||
import { Turn, Ref } from "./actor.js";
|
||||
import { Bytes, Dictionary, DoubleFloat, IdentityMap, is, isEmbedded, Record, Tuple, stringify } from "@preserves/core";
|
||||
import { Bytes, Dictionary, DictionaryMap, DoubleFloat, IdentityMap, KeyedDictionary, is, isEmbedded, Record, Tuple, stringify } from "@preserves/core";
|
||||
import type { Assertion, Handle } from "./actor.js";
|
||||
import type { SturdyValue } from "../transport/sturdy.js";
|
||||
|
||||
|
@ -89,9 +89,10 @@ export function match(p: Pattern, v: Assertion): Bindings | null {
|
|||
return true;
|
||||
}
|
||||
case 'dict':{
|
||||
if (!Dictionary.isDictionary<Ref, Assertion>(v)) return false;
|
||||
const vMap = Dictionary.asMap<Ref, Assertion>(v);
|
||||
if (!vMap) return false;
|
||||
for (const [key, pp] of p.value.entries.entries()) {
|
||||
const vv = v.get(key);
|
||||
const vv = vMap.get(key);
|
||||
if (vv === void 0) return false;
|
||||
if (!walk(pp, vv)) return false;
|
||||
}
|
||||
|
@ -136,9 +137,9 @@ export function instantiate(t: Template, b: Bindings): Assertion {
|
|||
case 'arr':
|
||||
return t.value.items.map(walk);
|
||||
case 'dict': {
|
||||
const v = new Dictionary<Ref, Assertion>();
|
||||
const v = new DictionaryMap<Ref, Assertion>();
|
||||
t.value.entries.forEach((tt, key) => v.set(key, walk(tt)));
|
||||
return v;
|
||||
return v.simplifiedValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +244,7 @@ export function pArr(... items: Array<Pattern>): Pattern {
|
|||
}
|
||||
|
||||
export function pDict(... entries: [SturdyValue, Pattern][]): Pattern {
|
||||
return Pattern.PCompound(PCompound.dict(new Dictionary<_embedded, Pattern>(entries)));
|
||||
return Pattern.PCompound(PCompound.dict(new KeyedDictionary<_embedded, SturdyValue, Pattern>(entries)));
|
||||
}
|
||||
|
||||
export function pLit(value: SturdyValue): Pattern {
|
||||
|
@ -303,7 +304,7 @@ export function tArr(... items: Array<Template>): Template {
|
|||
}
|
||||
|
||||
export function tDict(... entries: [SturdyValue, Template][]): Template {
|
||||
return Template.TCompound(TCompound.dict(new Dictionary<_embedded, Template>(entries)));
|
||||
return Template.TCompound(TCompound.dict(new KeyedDictionary<_embedded, SturdyValue, Template>(entries)));
|
||||
}
|
||||
|
||||
export function tLit(value: SturdyValue): Template {
|
||||
|
|
|
@ -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, Embeddable } from '@preserves/core';
|
||||
import { Set, 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';
|
||||
|
@ -35,7 +35,7 @@ export class Index<T> {
|
|||
const continuation = this.root.extend(pattern);
|
||||
let constValMap = continuation.leafMap.get(constPaths);
|
||||
if (!constValMap) {
|
||||
constValMap = new Dictionary();
|
||||
constValMap = new KeyedDictionary();
|
||||
continuation.cachedAssertions.forEach((a) => {
|
||||
const key = projectPaths(a, constPaths);
|
||||
let leaf = constValMap!.get(key);
|
||||
|
@ -156,7 +156,7 @@ type Selector = [number, AnyValue];
|
|||
|
||||
class Node<T> {
|
||||
readonly continuation: Continuation<T>;
|
||||
readonly edges: KeyedDictionary<Selector, { [shape: string]: Node<T> }, Ref> = new KeyedDictionary();
|
||||
readonly edges: KeyedDictionary<Ref, Selector, { [shape: string]: Node<T> }> = new KeyedDictionary();
|
||||
|
||||
constructor(continuation: Continuation<T>) {
|
||||
this.continuation = continuation;
|
||||
|
@ -267,7 +267,7 @@ class Node<T> {
|
|||
|
||||
class Continuation<T> {
|
||||
readonly cachedAssertions: Set<Ref>;
|
||||
readonly leafMap: KeyedDictionary<Array<Path>, Dictionary<Ref, Leaf<T>>, Ref> = new KeyedDictionary();
|
||||
readonly leafMap: KeyedDictionary<Ref, Array<Path>, KeyedDictionary<Ref, Assertion, Leaf<T>>> = new KeyedDictionary();
|
||||
|
||||
constructor(cachedAssertions: Set<Ref>) {
|
||||
this.cachedAssertions = cachedAssertions;
|
||||
|
@ -286,7 +286,7 @@ class Continuation<T> {
|
|||
|
||||
class Leaf<T> {
|
||||
readonly cachedAssertions: Set<Ref> = new Set();
|
||||
readonly observerGroups: KeyedDictionary<Array<Path>, ObserverGroup<T>, Ref> = new KeyedDictionary();
|
||||
readonly observerGroups: KeyedDictionary<Ref, Array<Path>, ObserverGroup<T>> = new KeyedDictionary();
|
||||
|
||||
isEmpty(): boolean {
|
||||
return this.cachedAssertions.size === 0 && this.observerGroups.size === 0;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/// SPDX-FileCopyrightText: Copyright © 2016-2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||
|
||||
import { Actor, Ref, Handle, Assertion, Entity, Turn } from '../runtime/actor.js';
|
||||
import { Value, Embedded, mapEmbeddeds, IdentityMap, Dictionary, stringify } from '@preserves/core';
|
||||
import { Value, Embedded, mapEmbeddeds, IdentityMap, KeyedDictionary, stringify } from '@preserves/core';
|
||||
import * as IO from '../gen/protocol.js';
|
||||
import { fromCaveat, WireRef } from '../gen/sturdy.js';
|
||||
import { attenuate } from '../runtime/rewrite.js';
|
||||
|
@ -163,10 +163,10 @@ export abstract class LayerBoundary implements ProxyOutbound, ProxyInbound {
|
|||
if (n.attenuation.length === 0) {
|
||||
return r;
|
||||
} else {
|
||||
type AttenuatedRef = Ref & { __attenuations?: Dictionary<any, Ref> };
|
||||
type AttenuatedRef = Ref & { __attenuations?: KeyedDictionary<Ref, Assertion, any> };
|
||||
const ar = r as AttenuatedRef;
|
||||
if (ar.__attenuations === void 0) {
|
||||
ar.__attenuations = new Dictionary();
|
||||
ar.__attenuations = new KeyedDictionary();
|
||||
}
|
||||
return ar.__attenuations.getOrSet(n.attenuation.map(fromCaveat), () =>
|
||||
attenuate(r, ... n.attenuation));
|
||||
|
|
Loading…
Reference in New Issue