Updates for js-preserves2 Preserves implementation

This commit is contained in:
Tony Garnock-Jones 2024-03-28 12:41:16 +01:00
parent cbcd4b9ad9
commit fd491b5c71
8 changed files with 52 additions and 41 deletions

View File

@ -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> {

View File

@ -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();
}

View File

@ -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,

View File

@ -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)));
}

View File

@ -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();

View File

@ -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 {

View File

@ -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;

View File

@ -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));