Major update to @preserves/core from old preserves package.

This commit is contained in:
Tony Garnock-Jones 2021-05-17 16:26:01 +02:00
parent 35c965b85d
commit dc5c97b027
15 changed files with 51 additions and 53 deletions

View File

@ -207,14 +207,14 @@ export function expand(tree: Items, ctx: ExpansionContext): Items {
// TODO: untyped template
const sa = compilePattern(s.pattern);
return t`withSelfDo(function (thisFacet) {
const _Facets = new __SYNDICATE__.Dictionary<__SYNDICATE__.Facet<any>>();
const _Facets = new __SYNDICATE__.Dictionary<any, __SYNDICATE__.Facet<any>>();
on asserted ${patternText(s.pattern)} => react {
_Facets.set([${commaJoin(sa.captureBinders.map(t=>[t.id]))}], thisFacet);
dataflow { } // TODO: horrible hack to keep the facet alive if no other endpoints
${s.body}
}
on retracted ${patternText(s.pattern)} => {
const ${ctx.argDecl(t, '_Key', '__SYNDICATE__.Value[]')} =
const ${ctx.argDecl(t, '_Key', '__SYNDICATE__.Value<any>[]')} =
[${commaJoin(sa.captureBinders.map(t=>[t.id]))}];
_Facets.get(_Key)?._stop();
_Facets.delete(_Key);
@ -280,7 +280,7 @@ export function expand(tree: Items, ctx: ExpansionContext): Items {
constPaths: ${JSON.stringify(sa.constPaths)},
constVals: [${commaJoin(sa.constVals.map(walk))}],
capturePaths: ${JSON.stringify(sa.capturePaths)},
callback: thisFacet.wrap((thisFacet, __Evt, ${ctx.argDecl(t, '__vs', 'Array<__SYNDICATE__.Value>')}) => {
callback: thisFacet.wrap((thisFacet, __Evt, ${ctx.argDecl(t, '__vs', 'Array<__SYNDICATE__.Value<any>>')}) => {
if (__Evt === __SYNDICATE__.Skeleton.EventType.${expectedEvt}) {
${joinItems(sa.captureBinders.map(binderTypeGuard(t)), '\n')}
thisFacet.scheduleScript(() => {${terminalWrap(t, s.terminal, walk(s.body))}});
@ -296,7 +296,7 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(t)), '\n')}
const l = `Symbol.for(${JSON.stringify(s.label.text)})`;
const fns = JSON.stringify(s.fields.map(f => f.id.text));
const fs = ctx.typescript
? t`<${facetFieldObjectType(t, s.fields, t`__SYNDICATE__.Value`)}>`
? t`<${facetFieldObjectType(t, s.fields, t`__SYNDICATE__.Value<any>`)}, any>`
: '';
return t`const ${[s.label]} = __SYNDICATE__.Record.makeConstructor${fs}()(${maybeWalk(s.wireName) ?? l}, ${fns});`;
});

View File

@ -22,6 +22,6 @@
"types": "lib/index.d.ts",
"author": "Tony Garnock-Jones <tonyg@leastfixedpoint.com>",
"dependencies": {
"preserves": "0.6.2"
"@preserves/core": "0.15.0"
}
}

View File

@ -16,7 +16,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//---------------------------------------------------------------------------
export * from 'preserves';
export * from '@preserves/core';
export * from './runtime/randomid.js';
export * from './runtime/assertions.js';

View File

@ -16,7 +16,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//---------------------------------------------------------------------------
import { Record, RecordConstructor, AsPreserve, Value } from 'preserves';
import { Record, RecordConstructor, AsPreserve, Value } from '@preserves/core';
export class Seal {
readonly contents: any;

View File

@ -18,7 +18,8 @@
// Bags and Deltas (which are Bags where item-counts can be negative).
import { Value, Set, Dictionary } from 'preserves';
import { GenericEmbedded } from '@preserves/core';
import { Value, Set, Dictionary } from '@preserves/core';
export enum ChangeDescription {
PRESENT_TO_ABSENT = -1,
@ -28,7 +29,7 @@ export enum ChangeDescription {
}
export class Bag {
_items: Dictionary<number>;
_items: Dictionary<GenericEmbedded, number>;
constructor(s?: Set) {
this._items = new Dictionary();
@ -83,7 +84,7 @@ export class Bag {
this._items.forEach(f);
}
snapshot(): Dictionary<number> {
snapshot(): Dictionary<GenericEmbedded, number> {
return this._items.clone();
}

View File

@ -18,7 +18,7 @@
// Property-based "dataflow"
import { FlexSet, FlexMap, Canonicalizer } from 'preserves';
import { FlexSet, FlexMap, Canonicalizer } from '@preserves/core';
import * as MapSet from './mapset.js';
export interface PropertyOptions<ObjectId> {

View File

@ -16,7 +16,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//---------------------------------------------------------------------------
import { Value, fromJS, is, Set } from 'preserves';
import { Value, is, Set } from '@preserves/core';
import * as Skeleton from './skeleton.js';
import { Bag, ChangeDescription } from './bag.js';
@ -42,11 +42,11 @@ export type EndpointId = ActorId;
export type Task<T> = () => T;
export type Script<T, Fields> = (this: Fields & DataflowObservableObject, f: Facet<Fields>) => T;
export type MaybeValue = Value | undefined;
export type MaybeValue = Value<any> | undefined;
export type EndpointSpec = { assertion: MaybeValue, analysis: Skeleton.Analysis | null };
export type ObserverCallback<Fields> =
(this: Fields, facet: Facet<Fields>, bindings: Array<Value>) => void;
(this: Fields, facet: Facet<Fields>, bindings: Array<Value<any>>) => void;
export type ObserverCallbacks<Fields> = {
add?: ObserverCallback<Fields>;
@ -150,7 +150,7 @@ export abstract class Dataspace {
applyPatch(ac: Actor, delta: Bag) {
// if (!delta.isEmpty()) debug('applyPatch BEGIN', ac && ac.toString());
let removals: Array<[number, Value]> = [];
let removals: Array<[number, Value<any>]> = [];
delta.forEach((count, a) => {
if (count > 0) {
// debug('applyPatch +', a && a.toString());
@ -167,7 +167,7 @@ export abstract class Dataspace {
// if (!delta.isEmpty()) debug('applyPatch END');
}
deliverMessage(m: Value, _sendingActor: Actor | null) {
deliverMessage(m: Value<any>, _sendingActor: Actor | null) {
// debug('deliverMessage', sendingActor && sendingActor.toString(), m.toString());
this.index.deliverMessage(m);
// this.index.deliverMessage(m, (leaf, _m) => {
@ -175,7 +175,7 @@ export abstract class Dataspace {
// });
}
adjustIndex(a: Value, count: number) {
adjustIndex(a: Value<any>, count: number) {
return this.index.adjustAssertion(a, count);
}
@ -303,18 +303,16 @@ export class Actor {
return p;
}
assert(a: Value) { this.pendingPatch().adjust(a, +1); }
retract(a: Value) { this.pendingPatch().adjust(a, -1); }
assert(a: Value<any>) { this.pendingPatch().adjust(a, +1); }
retract(a: Value<any>) { this.pendingPatch().adjust(a, -1); }
adhocRetract(a: Value) {
a = fromJS(a);
adhocRetract(a: Value<any>) {
if (this.adhocAssertions.change(a, -1, true) === ChangeDescription.PRESENT_TO_ABSENT) {
this.retract(a);
}
}
adhocAssert(a: Value) {
a = fromJS(a);
adhocAssert(a: Value<any>) {
if (this.adhocAssertions.change(a, +1) === ChangeDescription.ABSENT_TO_PRESENT) {
this.assert(a);
}
@ -343,17 +341,17 @@ class Patch extends Action {
ds.applyPatch(ac!, this.changes);
}
adjust(a: Value, count: number) {
this.changes.change(fromJS(a), count);
adjust(a: Value<any>, count: number) {
this.changes.change(a, count);
}
}
class Message extends Action {
readonly body: Value;
readonly body: Value<any>;
constructor(body: any) {
constructor(body: Value<any>) {
super();
this.body = fromJS(body);
this.body = body;
}
perform(ds: Dataspace, ac: Actor | null): void {
@ -577,7 +575,7 @@ export class Facet<Fields> {
addObserverEndpoint(specThunk: (facet: Facet<Fields>) => MaybeValue, callbacks: ObserverCallbacks<Fields>): Endpoint<Fields> {
const scriptify = (f?: ObserverCallback<Fields>) =>
f && ((facet: Facet<Fields>, vs: Array<Value>) =>
f && ((facet: Facet<Fields>, vs: Array<Value<any>>) =>
facet.scheduleScript(() => f.call(facet.fields, facet, vs)));
return this._addRawObserverEndpoint(specThunk, {
add: scriptify(callbacks.add),
@ -667,11 +665,11 @@ export class Facet<Fields> {
}
// This alias exists because of the naive expansion done by the parser.
_send(body: any) {
_send(body: Value<any>) {
this.send(body);
}
send(body: any) {
send(body: Value<any>) {
this.ensureNonFacetSetup('`send`');
this.enqueueScriptAction(new Message(body));
}
@ -772,7 +770,6 @@ export class Endpoint<Fields> {
refresh() {
let newSpec = this.updateFun.call(this.facet.fields, this.facet);
if (newSpec.assertion !== void 0) newSpec.assertion = fromJS(newSpec.assertion);
if (!is(newSpec.assertion, this.spec.assertion)) {
this._uninstall(true);
this._install(newSpec);

View File

@ -18,7 +18,7 @@
// Utilities for Maps of Sets
import { FlexSet, FlexMap, Canonicalizer } from 'preserves';
import { FlexSet, FlexMap, Canonicalizer } from '@preserves/core';
export function add<K,V>(m: FlexMap<K, FlexSet<V>>, k: K, v: V, c: Canonicalizer<V>) {
let s = m.get(k);

View File

@ -16,7 +16,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//---------------------------------------------------------------------------
import { Bytes } from 'preserves';
import { Bytes } from '@preserves/core';
import * as node_crypto from 'crypto';
export function _btoa(s: string): string {

View File

@ -16,7 +16,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//---------------------------------------------------------------------------
import { Value, Record } from 'preserves';
import { embed, Value } from '@preserves/core';
import { $Special } from './special.js';
import { Dataspace, Facet, Actor, Endpoint, Script } from './dataspace.js';
@ -25,7 +25,7 @@ import { ChangeDescription } from './bag.js';
import { EventType, Analysis } from './skeleton.js';
import { Ground } from './ground.js';
export const $QuitDataspace = new $Special("quit-dataspace");
export const $QuitDataspace = embed(new $Special("quit-dataspace"));
export class NestedDataspace extends Dataspace {
readonly outerFacet: Facet<{}>;

View File

@ -17,7 +17,7 @@
//---------------------------------------------------------------------------
import { IdentitySet } from './idcoll.js';
import { is, Value, Record, Set, Dictionary, canonicalString, RecordConstructorInfo, Tuple } from 'preserves';
import { is, Value, Record, Set, Dictionary, canonicalString, RecordConstructorInfo, GenericEmbedded } from '@preserves/core';
import { Bag, ChangeDescription } from './bag.js';
import { Discard, Capture } from './assertions.js';
@ -255,7 +255,7 @@ function parseSelector(s: string): { popCount: number, index: number } {
class Continuation {
readonly cachedAssertions: Set;
readonly leafMap: Dictionary<Dictionary<Leaf>> = new Dictionary();
readonly leafMap: Dictionary<GenericEmbedded, Dictionary<GenericEmbedded, Leaf>> = new Dictionary();
constructor(cachedAssertions: Set) {
this.cachedAssertions = cachedAssertions;
@ -264,7 +264,7 @@ class Continuation {
class Leaf {
readonly cachedAssertions: Set = new Set();
readonly handlerMap: Dictionary<Handler> = new Dictionary();
readonly handlerMap: Dictionary<GenericEmbedded, Handler> = new Dictionary();
isEmpty(): boolean {
return this.cachedAssertions.size === 0 && this.handlerMap.size === 0;

View File

@ -20,7 +20,7 @@
// import { Observe, Outbound, Inbound, Capture, Discard } from './assertions.js';
// import * as Skeleton from './skeleton.js';
// import { preserves, Value, Bytes, Record, Dictionary, encode, decode } from 'preserves';
// import { preserves, Value, Bytes, Record, Dictionary, encode, decode } from '@preserves/core';
// type MessageHandler = (e: Bytes) => void;
// type ImplementationType = 'node.js' | 'browser' | 'none';

View File

@ -16,7 +16,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//---------------------------------------------------------------------------
import { Value } from '@syndicate-lang/core';
import { Embedded, Value } from '@syndicate-lang/core';
activate import { UIEvent, GlobalEvent, HtmlFragments, template, Anchor } from '@syndicate-lang/html';
assertion type Person(id, firstName, lastName, address, age);
@ -56,7 +56,7 @@ boot {
spawn named 'controller' {
on message GlobalEvent('table#the-table th', 'click', $e) => {
send message SetSortColumn(
JSON.parse(((e as unknown as Event).target as HTMLElement).dataset.column!));
JSON.parse(((e as Embedded<Event>).embeddedValue.target as HTMLElement).dataset.column!));
}
}

View File

@ -16,7 +16,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//---------------------------------------------------------------------------
import { randomId, Facet, Observe, FlexMap, Value, Record } from "@syndicate-lang/core";
import { randomId, Facet, Observe, FlexMap, Value, embed, Embedded } from "@syndicate-lang/core";
import * as P from "./protocol";
export * from "./protocol";
@ -52,7 +52,7 @@ export function spawnGlobalEventFactory<T>(thisFacet: Facet<T>) {
during Observe(P.GlobalEvent($selector: string, $eventType: string, _)) =>
spawn named ['GlobalEvent', selector, eventType] {
let sender = thisFacet.wrapExternal((thisFacet, e: Event) => {
send message P.GlobalEvent(selector, eventType, e);
send message P.GlobalEvent(selector, eventType, embed(e));
});
function handler(event: Event) {
@ -81,7 +81,7 @@ export function spawnWindowEventFactory<T>(thisFacet: Facet<T>) {
during Observe(P.WindowEvent($eventType: string, _)) =>
spawn named ['WindowEvent', eventType] {
let sender = thisFacet.wrapExternal((thisFacet, e: Event) => {
send message P.WindowEvent(eventType, e);
send message P.WindowEvent(eventType, embed(e));
});
let handler = function (event: Event) {
@ -148,7 +148,7 @@ function spawnUIFragmentFactory<T>(thisFacet: Facet<T>) {
removeNodes();
selector = newSelector;
html = newHtml as Array<ChildNode>;
html = (newHtml as Embedded<Array<ChildNode>>).embeddedValue;
orderBy = newOrderBy;
anchorNodes = (selector !== null) ? selectorMatch(document.body, selector) : [];
@ -188,7 +188,7 @@ function spawnUIFragmentFactory<T>(thisFacet: Facet<T>) {
let handlerClosure: HandlerClosure;
if (!eventRegistrations.has(key)) {
let sender = thisFacet.wrapExternal((thisFacet, e: Event) => {
send message P.UIEvent(fragmentId, selector, eventType, e);
send message P.UIEvent(fragmentId, selector, eventType, embed(e));
});
function handler(event: Event) {
sender(event);
@ -478,7 +478,7 @@ export class Anchor {
}
html(selector: string, html: HtmlFragments, orderBy: NodeOrderKey = ''): ReturnType<typeof P.UIFragment> {
return P.UIFragment(this.fragmentId, selector, html.nodes(), orderBy);
return P.UIFragment(this.fragmentId, selector, embed(html.nodes()), orderBy);
}
}

View File

@ -1366,6 +1366,11 @@
dependencies:
"@octokit/openapi-types" "^6.1.1"
"@preserves/core@0.15.0":
version "0.15.0"
resolved "https://registry.yarnpkg.com/@preserves/core/-/core-0.15.0.tgz#55a14288442d404d20a2906b92b7a7cc9e522a18"
integrity sha512-PoEvwlqNNXpYykwkiD7KyjT6kfo78XXEMwJ5yOhOiEF6nVD167NVv801/DR7xIINtPDaDjdqBtqY/tamyzi7vA==
"@rollup/plugin-node-resolve@^11.0.1":
version "11.2.1"
resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz#82aa59397a29cd4e13248b106e6a4a1880362a60"
@ -5781,11 +5786,6 @@ prelude-ls@~1.1.2:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
preserves@0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/preserves/-/preserves-0.6.2.tgz#9102dae1e619c4d88459cd6a0d49c745bb687d1d"
integrity sha512-Hinv4i8HM9iUti4TzdFBkJOzQxn9LhcDWqbH4NgUTN39CBwwEkTEDCPMilf49OU+JEQgwvCIsfO/566j1dELUQ==
pretty-format@^26.0.0, pretty-format@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93"