diff --git a/packages/core/package.json b/packages/core/package.json
index ad90956..d64b965 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -21,6 +21,7 @@
"nyc": "^13.1.0"
},
"dependencies": {
- "immutable": "^3.8.2"
+ "immutable": "^3.8.2",
+ "preserves": "^0.0.2"
}
}
diff --git a/packages/core/src/assertions.js b/packages/core/src/assertions.js
index 7861772..93fbfd2 100644
--- a/packages/core/src/assertions.js
+++ b/packages/core/src/assertions.js
@@ -17,13 +17,10 @@
// along with this program. If not, see .
//---------------------------------------------------------------------------
-var Struct = require('./struct.js');
+var { Record } = require('preserves');
function Seal(contents) {
- if (this === void 0) {
- return new Seal(contents);
- }
-
+ if (!(this instanceof Seal)) return new Seal(contents);
this.contents = contents;
}
@@ -35,10 +32,12 @@ Seal.prototype.toJSON = function () {
return { '@seal': 0 };
};
-module.exports.Discard = Struct.makeConstructor('discard', []);
-module.exports.Capture = Struct.makeConstructor('capture', ['specification']);
-module.exports.Observe = Struct.makeConstructor('observe', ['specification']);
+module.exports.Discard = Record.makeConstructor('discard', []);
+module.exports.Capture = Record.makeConstructor('capture', ['specification']);
+module.exports.Observe = Record.makeConstructor('observe', ['specification']);
+
+module.exports.Inbound = Record.makeConstructor('inbound', ['assertion']);
+module.exports.Outbound = Record.makeConstructor('outbound', ['assertion']);
+module.exports.Instance = Record.makeConstructor('instance', ['uniqueId']);
+
module.exports.Seal = Seal;
-module.exports.Inbound = Struct.makeConstructor('inbound', ['assertion']);
-module.exports.Outbound = Struct.makeConstructor('outbound', ['assertion']);
-module.exports.Instance = Struct.makeConstructor('instance', ['uniqueId']);
diff --git a/packages/core/src/bag.js b/packages/core/src/bag.js
index 917b605..0533371 100644
--- a/packages/core/src/bag.js
+++ b/packages/core/src/bag.js
@@ -20,6 +20,7 @@
// Bags and Deltas (which are Bags where item-counts can be negative).
const Immutable = require("immutable");
+const { fromJS } = require("preserves");
const PRESENT_TO_ABSENT = -1;
const ABSENT_TO_ABSENT = 0;
@@ -77,7 +78,7 @@ const Bag = Immutable.Map;
function fromSet(s) {
return Bag().withMutations(function (b) {
for (let v of Immutable.Set(s)) {
- b = b.set(Immutable.fromJS(v), 1);
+ b = b.set(fromJS(v), 1);
}
});
}
diff --git a/packages/core/src/dataspace.js b/packages/core/src/dataspace.js
index d4b96ae..0faa7b6 100644
--- a/packages/core/src/dataspace.js
+++ b/packages/core/src/dataspace.js
@@ -18,7 +18,8 @@
//---------------------------------------------------------------------------
const Immutable = require("immutable");
-const Struct = require('./struct.js');
+const { fromJS } = require("preserves");
+
const Skeleton = require('./skeleton.js');
const $Special = require('./special.js');
const Bag = require('./bag.js');
@@ -343,14 +344,14 @@ Actor.prototype.assert = function (a) { this.pendingPatch().adjust(a, +1); };
Actor.prototype.retract = function (a) { this.pendingPatch().adjust(a, -1); };
Actor.prototype.adhocRetract = function (a) {
- a = Immutable.fromJS(a);
+ a = fromJS(a);
if (this.adhocAssertions.change(a, -1, true) === Bag.PRESENT_TO_ABSENT) {
this.retract(a);
}
};
Actor.prototype.adhocAssert = function (a) {
- a = Immutable.fromJS(a);
+ a = fromJS(a);
if (this.adhocAssertions.change(a, +1) === Bag.ABSENT_TO_PRESENT) {
this.assert(a);
}
@@ -371,8 +372,10 @@ Patch.prototype.perform = function (ds, ac) {
};
Patch.prototype.adjust = function (a, count) {
- var _net;
- ({bag: this.changes, net: _net} = Bag.change(this.changes, Immutable.fromJS(a), count));
+ if (a !== void 0) {
+ var _net;
+ ({bag: this.changes, net: _net} = Bag.change(this.changes, fromJS(a), count));
+ }
};
function Message(body) {
@@ -381,7 +384,7 @@ function Message(body) {
Message.prototype.perform = function (ds, ac) {
if (this.body !== void 0) {
- ds.sendMessage(Immutable.fromJS(this.body));
+ ds.sendMessage(fromJS(this.body));
}
};
@@ -612,7 +615,7 @@ Endpoint.prototype._uninstall = function (ds, ac, emitPatches) {
Endpoint.prototype.refresh = function (ds, ac, facet) {
let [newAssertion, newHandler] = this.updateFun.call(facet.fields);
- newAssertion = Immutable.fromJS(newAssertion);
+ if (newAssertion !== void 0) newAssertion = fromJS(newAssertion);
if (!Immutable.is(newAssertion, this.assertion)) {
this._uninstall(ds, ac, true);
this._install(ds, ac, newAssertion, newHandler);
diff --git a/packages/core/src/ground.js b/packages/core/src/ground.js
index bd4afb9..93a8f07 100644
--- a/packages/core/src/ground.js
+++ b/packages/core/src/ground.js
@@ -19,6 +19,7 @@ Ground.prototype = new Dataspace(null);
Ground._resolved = Promise.resolve();
Ground.laterCall = function (thunk) {
Ground._resolved.then(() => {
+ Error.stackTraceLimit = 100;
try {
thunk();
} catch (e) {
diff --git a/packages/core/src/index.js b/packages/core/src/index.js
index 2dd4e83..41988f5 100644
--- a/packages/core/src/index.js
+++ b/packages/core/src/index.js
@@ -17,7 +17,6 @@
// along with this program. If not, see .
//---------------------------------------------------------------------------
-const Struct = require('./struct.js');
const Skeleton = require('./skeleton.js');
const RandomID = require('./randomid.js');
const Dataspace = require('./dataspace.js');
@@ -25,11 +24,12 @@ const Ground = require('./ground.js');
const Assertions = require('./assertions.js');
const Relay = require('./relay.js');
+Object.assign(module.exports, require("preserves"));
+
module.exports.Immutable = require('immutable');
// ^ for use by import machinery in syntactic extensions
module.exports.Bag = require("./bag.js");
-module.exports.Struct = Struct;
module.exports.Skeleton = Skeleton;
module.exports.RandomID = RandomID;
diff --git a/packages/core/src/relay.js b/packages/core/src/relay.js
index 23d6368..94a2e8a 100644
--- a/packages/core/src/relay.js
+++ b/packages/core/src/relay.js
@@ -47,18 +47,18 @@ NestedDataspace.prototype.sendMessage = function (m) {
NestedDataspace.prototype.endpointHook = function (facet, innerEp) {
const innerDs = this;
Dataspace.prototype.endpointHook.call(this, facet, innerEp);
- if (Observe.isClassOf(innerEp.assertion) && Inbound.isClassOf(innerEp.assertion[0])) {
+ if (Observe.isClassOf(innerEp.assertion) && Inbound.isClassOf(innerEp.assertion.get(0))) {
// We know that innerEp.assertion is an Observe(Inbound(...)).
// Also, if innerEp.handler exists, it will be consonant with innerEp.assertion.
// Beware of completely-constant patterns, which cause skeleton to be null!
this.hookEndpointLifecycle(innerEp, this.outerFacet.addEndpoint(() => {
const h = innerEp.handler;
- return [Observe(innerEp.assertion[0][0]),
+ return [Observe(innerEp.assertion.get(0).get(0)),
h && (h.skeleton === null
? {
skeleton: null,
constPaths: h.constPaths,
- constVals: h.constVals.map((v) => v[0]),
+ constVals: h.constVals.map((v) => v.get(0)),
capturePaths: h.capturePaths.map((p) => p.shift()),
callback: function (evt, captures) {
h.callback.call(this, evt, captures);
@@ -85,13 +85,13 @@ NestedDataspace.prototype.adjustIndex = function (a, count) {
switch (net) {
case Bag.ABSENT_TO_PRESENT:
this.outerFacet.actor.pushScript(() => {
- this.outerFacet.actor.adhocAssert(a[0]);
+ this.outerFacet.actor.adhocAssert(a.get(0));
});
this.outerFacet.actor.dataspace.start();
break;
case Bag.PRESENT_TO_ABSENT:
this.outerFacet.actor.pushScript(() => {
- this.outerFacet.actor.adhocRetract(a[0]);
+ this.outerFacet.actor.adhocRetract(a.get(0));
});
this.outerFacet.actor.dataspace.start();
break;
diff --git a/packages/core/src/skeleton.js b/packages/core/src/skeleton.js
index d91408e..b1a8199 100644
--- a/packages/core/src/skeleton.js
+++ b/packages/core/src/skeleton.js
@@ -18,7 +18,8 @@
//---------------------------------------------------------------------------
const Immutable = require("immutable");
-const Struct = require('./struct.js');
+const { Record } = require("preserves");
+
const $Special = require('./special.js');
const Bag = require('./bag.js');
const { Capture, Discard } = require('./assertions.js');
@@ -66,8 +67,8 @@ function Handler(cachedCaptures) {
}
function classOf(v) {
- if (v instanceof Struct.Structure) {
- return v.meta;
+ if (v instanceof Record) {
+ return v.getConstructorInfo();
} else if (v instanceof Immutable.List) {
return v.size;
} else {
@@ -104,7 +105,7 @@ Node.prototype.extend = function(skeleton) {
if (!nextNode) {
nextNode = new Node(new Continuation(
node.continuation.cachedAssertions.filter(
- (a) => classOf(projectPath(a, path)) === cls)));
+ (a) => Immutable.is(classOf(projectPath(a, path)), cls))));
table = table.set(cls, nextNode);
node.edges = node.edges.set(selector, table);
}
@@ -191,8 +192,7 @@ Node.prototype.modify = function(outerValue, m_cont, m_leaf, m_handler) {
while (i--) { mutable.pop(); }
});
let nextValue = step(nextStack.first(), selector.index);
- let cls = classOf(nextValue);
- let nextNode = table.get(cls, false);
+ let nextNode = table.get(classOf(nextValue), false);
if (nextNode) {
walkNode(nextNode, nextStack.push(nextValue));
}
@@ -279,6 +279,15 @@ function analyzeAssertion(a) {
let capturePaths = Immutable.List();
function walk(path, a) {
+ if (Capture.isClassOf(a)) {
+ capturePaths = capturePaths.push(path);
+ return walk(path, a.get(0));
+ }
+
+ if (Discard.isClassOf(a)) {
+ return null;
+ }
+
let cls = classOf(a);
if (cls !== null) {
let arity = (typeof cls === 'number') ? cls : cls.arity;
@@ -287,18 +296,11 @@ function analyzeAssertion(a) {
result.push(walk(path.push(i), step(a, i)));
}
return result;
- } else {
- if (Capture.isClassOf(a)) {
- capturePaths = capturePaths.push(path);
- return walk(path, a.get(0));
- } else if (Discard.isClassOf(a)) {
- return null;
- } else {
- constPaths = constPaths.push(path);
- constVals = constVals.push(a);
- return null;
- }
}
+
+ constPaths = constPaths.push(path);
+ constVals = constVals.push(a);
+ return null;
}
let skeleton = walk(Immutable.List(), a);
diff --git a/packages/core/src/struct.js b/packages/core/src/struct.js
deleted file mode 100644
index 213d5fe..0000000
--- a/packages/core/src/struct.js
+++ /dev/null
@@ -1,169 +0,0 @@
-"use strict";
-//---------------------------------------------------------------------------
-// @syndicate-lang/core, an implementation of Syndicate dataspaces for JS.
-// Copyright (C) 2016-2018 Tony Garnock-Jones
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-//---------------------------------------------------------------------------
-
-// "Structures": Simple named-tuple-like records.
-
-const Immutable = require("immutable");
-const $Special = require('./special.js');
-
-function StructureType(label, arity) {
- this.label = label;
- this.arity = arity;
-
- var self = this;
- this.ctor = function () {
- return self.instantiate(Array.prototype.slice.call(arguments));
- };
- this.ctor.meta = this;
- this.ctor.isClassOf = function (v) { return self.isClassOf(v); };
-}
-
-function makeConstructor(label, fieldNames) {
- return new StructureType(label, fieldNames.length).ctor;
-}
-
-StructureType.prototype.equals = function (other) {
- if (!(other instanceof StructureType)) return false;
- return this.arity === other.arity && this.label === other.label;
-};
-
-StructureType.prototype.hashCode = function () {
- return Immutable.List([this.label, this.arity]).hashCode();
-};
-
-StructureType.prototype.instantiate = function (fields) {
- return new Structure(this, fields);
-};
-
-StructureType.prototype.isClassOf = function (v) {
- return v && (v instanceof Structure) && (v.meta.equals(this));
-};
-
-function Structure(meta, fields) {
- if (!isStructureType(meta)) {
- throw new Error("Structure: requires structure type");
- }
- if (fields.length !== meta.arity) {
- throw new Error("Structure: cannot instantiate meta "+JSON.stringify(meta.label)+
- " expecting "+meta.arity+" fields with "+fields.length+" fields");
- }
- fields = fields.slice(0);
- this.meta = meta;
- this.length = meta.arity;
- this.fields = fields;
- for (var i = 0; i < fields.length; i++) {
- this[i] = fields[i] = Immutable.fromJS(fields[i]);
- if (this[i] === void 0) {
- throw new Error("Structure: cannot contain undefined value at field " + i);
- }
- }
-}
-
-Structure.prototype.clone = function () {
- return new Structure(this.meta, this.fields);
-};
-
-Structure.prototype.get = function (index) {
- return this[index];
-};
-
-Structure.prototype.set = function (index, value) {
- var s = this.clone();
- s[index] = s.fields[index] = value;
- return s;
-};
-
-Structure.prototype.equals = function (other) {
- if (!other) return false;
- if (!(other instanceof Structure)) return false;
- if (!other.meta.equals(this.meta)) return false;
- for (let i = 0; i < this.length; i++) {
- const a = this[i];
- const b = other[i];
- if (a === b) continue;
- if (!a || typeof a.equals !== 'function') return false;
- if (!a.equals(b)) return false;
- }
- return true;
-};
-
-Structure.prototype.hashCode = function () {
- return Immutable.List(this.fields).unshift(this.meta).hashCode();
-};
-
-Structure.prototype.toString = function () {
- let b = this.meta.label + "(";
- let needComma = false;
- for (let v of this.fields) {
- if (needComma) b = b + ", ";
- needComma = true;
- b = b + JSON.stringify(v);
- }
- return b + ")";
-};
-
-function reviveStructs(j) {
- if (Array.isArray(j)) {
- return j.map(reviveStructs);
- }
-
- if ((j !== null) && typeof j === 'object') {
- if ((typeof j['@type'] === 'string') && Array.isArray(j['fields'])) {
- return (new StructureType(j['@type'], j['fields'].length)).instantiate(j['fields']);
- } else {
- for (var k in j) {
- if (Object.prototype.hasOwnProperty.call(j, k)) {
- j[k] = reviveStructs(j[k]);
- }
- }
- return j;
- }
- }
-
- return j;
-}
-
-function reviver(k, v) {
- if (k === '') {
- return reviveStructs(v);
- }
- return v;
-};
-
-Structure.prototype.toJSON = function () {
- return { '@type': this.meta.label, 'fields': this.fields };
-};
-
-function isStructureType(v) {
- return v && (v instanceof StructureType);
-}
-
-function isStructure(v) {
- return v && (v instanceof Structure);
-}
-
-///////////////////////////////////////////////////////////////////////////
-
-module.exports.StructureType = StructureType;
-module.exports.makeConstructor = makeConstructor;
-module.exports.Structure = Structure;
-module.exports.reviveStructs = reviveStructs;
-module.exports.reviver = reviver;
-module.exports.isStructureType = isStructureType;
-module.exports.isStructure = isStructure;
diff --git a/packages/core/test/test-dataspace.js b/packages/core/test/test-dataspace.js
index 50f1711..2866ade 100644
--- a/packages/core/test/test-dataspace.js
+++ b/packages/core/test/test-dataspace.js
@@ -24,28 +24,27 @@ chai.use(require('chai-immutable'));
const Immutable = require('immutable');
const Syndicate = require('../src/index.js');
-const Skeleton = Syndicate.Skeleton;
-const Dataspace = Syndicate.Dataspace;
-const Struct = Syndicate.Struct;
-const __ = Syndicate.__;
-const _$ = Syndicate._$;
+const { Skeleton, Dataspace, Observe, Capture, Discard } = Syndicate;
describe('dataspace', () => {
it('should boot and run', () => {
// TODO: convert this into even a rudimentary somewhat-real test case
// (change console.log into gathering a trace)
- let ds = new Dataspace(null, () => {
+ let ds = new Dataspace(() => {
// console.log('boot');
Dataspace.currentFacet().addEndpoint(() => {
- let handler = Skeleton.analyzeAssertion(_$);
+ let handler = Skeleton.analyzeAssertion(Capture(Discard()));
handler.callback = (evt, vs) => {
- if (Syndicate.Observe.isClassOf(vs.get(0))) {
- // console.log('OBSERVATION EVENT', evt, vs, vs.get(0).get(0) === _$);
+ if (Observe.isClassOf(vs.get(0))) {
+ // console.log('OBSERVATION EVENT',
+ // evt,
+ // vs,
+ // Immutable.is(vs.get(0).get(0), Capture(Discard())));
} else {
// console.log('EVENT', evt, vs);
}
};
- return [Syndicate.Observe(_$), handler];
+ return [Observe(Capture(Discard())), handler];
});
Dataspace.deferTurn(() => {
// console.log('after defer');
diff --git a/packages/core/test/test-skeleton.js b/packages/core/test/test-skeleton.js
index 33d2e4a..07f2924 100644
--- a/packages/core/test/test-skeleton.js
+++ b/packages/core/test/test-skeleton.js
@@ -24,12 +24,12 @@ chai.use(require('chai-immutable'));
const Immutable = require('immutable');
const Syndicate = require('../src/index.js');
-const Skeleton = Syndicate.Skeleton;
-const Struct = Syndicate.Struct;
-const __ = Syndicate.__;
-const _$ = Syndicate._$;
+const { Seal, Skeleton, Capture, Discard, Record } = Syndicate;
-const Event = Struct.makeConstructor('Event', ['label', 'type', 'values']);
+const __ = Discard();
+const _$ = Capture(Discard());
+
+const Event = Record.makeConstructor('Event', ['label', 'type', 'values']);
function eventCallback(traceHolder, label) {
return (e, vs) => { traceHolder.push(Event(label, e, vs)) };
@@ -51,21 +51,21 @@ function _analyzeAssertion(a) {
describe('skeleton', () => {
- const A = Struct.makeConstructor('A', ['x', 'y']);
- const B = Struct.makeConstructor('B', ['v']);
- const C = Struct.makeConstructor('C', ['v']);
+ const A = Record.makeConstructor('A', ['x', 'y']);
+ const B = Record.makeConstructor('B', ['v']);
+ const C = Record.makeConstructor('C', ['v']);
describe('pattern analysis', () => {
it('should handle leaf captures', () => {
expect(Immutable.fromJS(_analyzeAssertion(A(B(_$), _$))))
- .to.equal(Immutable.fromJS({skeleton: [A.meta, [B.meta, null], null],
+ .to.equal(Immutable.fromJS({skeleton: [A.constructorInfo, [B.constructorInfo, null], null],
constPaths: Immutable.fromJS([]),
constVals: Immutable.fromJS([]),
capturePaths: Immutable.fromJS([[0, 0], [1]])}));
});
it('should handle atomic constants', () => {
expect(Immutable.fromJS(_analyzeAssertion(A(B("x"), _$))))
- .to.equal(Immutable.fromJS({skeleton: [A.meta, [B.meta, null], null],
+ .to.equal(Immutable.fromJS({skeleton: [A.constructorInfo, [B.constructorInfo, null], null],
constPaths: Immutable.fromJS([[0, 0]]),
constVals: Immutable.fromJS(["x"]),
capturePaths: Immutable.fromJS([[1]])}));
@@ -77,12 +77,15 @@ describe('skeleton', () => {
// will end up being complex at runtime. We can't properly test
// that situation without the static analysis half of the code.
// TODO later.
- let complexPlaceholder = new Object();
- expect(Immutable.fromJS(_analyzeAssertion(A(complexPlaceholder, C(_$)))))
- .to.equal(Immutable.fromJS({skeleton: [A.meta, null, [C.meta, null]],
- constPaths: Immutable.fromJS([[0]]),
- constVals: Immutable.fromJS([complexPlaceholder]),
- capturePaths: Immutable.fromJS([[1, 0]])}));
+ const complexPlaceholder = new Object();
+ const analysis = Immutable.fromJS(_analyzeAssertion(A(complexPlaceholder, C(_$))));
+ const expected = Immutable.fromJS({
+ skeleton: [A.constructorInfo, null, [C.constructorInfo, null]],
+ constPaths: Immutable.fromJS([[0]]),
+ constVals: Immutable.List([complexPlaceholder]),
+ capturePaths: Immutable.fromJS([[1, 0]]),
+ });
+ expect(analysis).to.equal(expected);
});
it('should handle complex constants (2)', () => {
// Marker: (***)
@@ -91,8 +94,10 @@ describe('skeleton', () => {
// will end up being complex at runtime. We can't properly test
// that situation without the static analysis half of the code.
// TODO later.
- expect(Immutable.fromJS(_analyzeAssertion(A(B(B("y")), _$("rhs", C(__))))))
- .to.equal(Immutable.fromJS({skeleton: [A.meta, [B.meta, [B.meta, null]], [C.meta, null]],
+ expect(Immutable.fromJS(_analyzeAssertion(A(B(B("y")), Capture(C(__))))))
+ .to.equal(Immutable.fromJS({skeleton: [A.constructorInfo,
+ [B.constructorInfo, [B.constructorInfo, null]],
+ [C.constructorInfo, null]],
constPaths: Immutable.fromJS([[0, 0, 0]]),
constVals: Immutable.fromJS(["y"]),
capturePaths: Immutable.fromJS([[1]])}));
@@ -117,13 +122,15 @@ describe('skeleton', () => {
let trace = skeletonTrace((i, traceHolder) => {
i.addHandler(_analyzeAssertion(A(B(_$), _$)), eventCallback(traceHolder, "AB"));
i.addHandler(_analyzeAssertion(A(B("x"), _$)), eventCallback(traceHolder, "ABx"));
- let complexConstantPattern1 = {skeleton: [A.meta, null, [C.meta, null]],
+ let complexConstantPattern1 = {skeleton: [A.constructorInfo, null, [C.constructorInfo, null]],
constPaths: Immutable.fromJS([[0]]),
constVals: Immutable.fromJS([B("y")]),
capturePaths: Immutable.fromJS([[1, 0]])};
// ^ See comment in 'should handle complex constants (1)' test above (marked (***)).
i.addHandler(complexConstantPattern1, eventCallback(traceHolder, "AByC"));
- let complexConstantPattern2 = {skeleton: [A.meta, [B.meta, null], [C.meta, null]],
+ let complexConstantPattern2 = {skeleton: [A.constructorInfo,
+ [B.constructorInfo, null],
+ [C.constructorInfo, null]],
constPaths: Immutable.fromJS([[0, 0]]),
constVals: Immutable.fromJS([B("y")]),
capturePaths: Immutable.fromJS([[1]])};
@@ -135,7 +142,7 @@ describe('skeleton', () => {
i.addAssertion(Immutable.fromJS(A(B("z"),C(3))));
});
- // trace.forEach((e) => { console.log(e.toString()) });
+ // trace.forEach((e) => { console.log(e) });
expect(trace)
.to.equal(Immutable.List([
@@ -236,7 +243,7 @@ describe('skeleton', () => {
expect(trace.size).to.equal(8);
});
it('should have a correct 3-EVENT subtrace', () => {
- expect(trace.filter((e) => { return e[0] === "3-EVENT"; }))
+ expect(trace.filter((e) => { return e.get(0) === "3-EVENT"; }))
.to.equal(Immutable.List([
Event("3-EVENT", Skeleton.EVENT_ADDED, [123, 234]),
Event("3-EVENT", Skeleton.EVENT_ADDED, [999, 999]),
@@ -245,7 +252,7 @@ describe('skeleton', () => {
Event("3-EVENT", Skeleton.EVENT_REMOVED, [123, 234])]));
});
it('should have a correct 2-EVENT subtrace', () => {
- expect(trace.filter((e) => { return e[0] === "2-EVENT"; }))
+ expect(trace.filter((e) => { return e.get(0) === "2-EVENT"; }))
.to.equal(Immutable.List([
Event("2-EVENT", Skeleton.EVENT_ADDED, []),
Event("2-EVENT", Skeleton.EVENT_MESSAGE, []),
diff --git a/packages/driver-browser-ui/src/html.js b/packages/driver-browser-ui/src/html.js
index ad0c25c..21ef0be 100644
--- a/packages/driver-browser-ui/src/html.js
+++ b/packages/driver-browser-ui/src/html.js
@@ -57,17 +57,18 @@ export function htmlToString(j) {
function walk(j) {
if (htmlTag.isClassOf(j)) {
- pieces.push('<', j[0]);
- j[1].forEach((p) => pieces.push(' ', escapeHtml(p[0]), '="', escapeHtml(p[1]), '"'));
+ pieces.push('<', j.get(0));
+ j.get(1).forEach(
+ (p) => pieces.push(' ', escapeHtml(p.get(0)), '="', escapeHtml(p.get(1)), '"'));
pieces.push('>');
- j[2].forEach(walk);
- if (!(j[0] in emptyHtmlElements)) {
- pieces.push('', j[0], '>');
+ j.get(2).forEach(walk);
+ if (!(j.get(0) in emptyHtmlElements)) {
+ pieces.push('', j.get(0), '>');
}
} else if (htmlFragment.isClassOf(j)) {
- j[0].forEach(walk);
+ j.get(0).forEach(walk);
} else if (htmlLiteral.isClassOf(j)) {
- pieces.push(j[0]);
+ pieces.push(j.get(0));
} else if (typeof j === 'object' && j && typeof j[Symbol.iterator] === 'function') {
for (let k of j) { walk(k); }
} else {
diff --git a/packages/driver-http-node/src/index.js b/packages/driver-http-node/src/index.js
index f29230e..90916a8 100644
--- a/packages/driver-http-node/src/index.js
+++ b/packages/driver-http-node/src/index.js
@@ -16,7 +16,7 @@
// along with this program. If not, see .
//---------------------------------------------------------------------------
-import { genUuid, Seal, Capture, Observe, Dataspace, currentFacet } from "@syndicate-lang/core";
+import { genUuid, Seal, Capture, Observe, Dataspace, currentFacet, Bytes } from "@syndicate-lang/core";
import { parse as parseUrl } from "url";
const http = require('http');
@@ -40,14 +40,14 @@ Object.assign(module.exports, {
Response, DataOut,
});
-spawn named 'HttpServerFactory' {
+spawn named 'driver/HttpServerFactory' {
during Observe(Request(_, HttpServer($h, $p), _, _, _, _)) assert HttpServer(h, p);
during Observe(Request(_, HttpsServer($h, $p, $o), _, _, _, _)) assert HttpsServer(h, p, o);
- during HttpServer($host, $port) spawn named ['HttpServer', host, port] {
+ during HttpServer($host, $port) spawn named ['driver/HttpServer', host, port] {
_server.call(this, host, port, null);
}
- during HttpsServer($host, $port, $options) spawn named ['HttpsServer', host, port] {
+ during HttpsServer($host, $port, $options) spawn named ['driver/HttpsServer', host, port] {
_server.call(this, host, port, options);
}
}
@@ -179,7 +179,7 @@ function _server(host, port, httpsOptions) {
facet.stop();
}
on message DataOut(id, $chunk) {
- res.write(chunk);
+ res.write(Bytes.toIO(chunk));
}
}
} else {
@@ -218,12 +218,12 @@ function _server(host, port, httpsOptions) {
on asserted Observe(DataIn(id, _)) {
ws.on('message', Dataspace.wrapExternal((message) => {
- ^ DataIn(id, message);
+ ^ DataIn(id, Bytes.fromIO(message));
}));
}
on message DataOut(id, $message) {
- ws.send(message);
+ ws.send(Bytes.toIO(message));
}
stop on retracted Observe(WebSocket(_, server, pathPattern, _));
diff --git a/packages/driver-tcp-node/src/index.js b/packages/driver-tcp-node/src/index.js
index 355f5f0..03e2227 100644
--- a/packages/driver-tcp-node/src/index.js
+++ b/packages/driver-tcp-node/src/index.js
@@ -16,7 +16,7 @@
// along with this program. If not, see .
//---------------------------------------------------------------------------
-import { currentFacet, Observe, Dataspace, genUuid } from "@syndicate-lang/core";
+import { currentFacet, Observe, Dataspace, genUuid, Bytes } from "@syndicate-lang/core";
const net = require('net');
const { sleep } = activate require("@syndicate-lang/driver-timer");
@@ -38,14 +38,14 @@ export {
TcpAddress, TcpListener,
};
-spawn named 'TcpDriver' {
- during Observe(TcpConnection(_, TcpListener($port))) spawn named ['TcpListener', port] {
+spawn named 'driver/TcpDriver' {
+ during Observe(TcpConnection(_, TcpListener($port))) spawn named ['driver/TcpListener', port] {
let finish = Dataspace.backgroundTask();
on stop finish();
let server = net.createServer(Dataspace.wrapExternal((socket) => {
let id = genUuid('tcp' + port);
- spawn named ['TcpInbound', id] {
+ spawn named ['driver/TcpInbound', id] {
assert TcpConnection(id, TcpListener(port));
on asserted TcpAccepted(id) _connectionCommon.call(this, currentFacet(), id, socket, true);
stop on retracted TcpAccepted(id);
@@ -57,7 +57,8 @@ spawn named 'TcpDriver' {
on stop try { server.close() } catch (e) { console.error(e); }
}
- during TcpConnection($id, TcpAddress($host, $port)) spawn named ['TcpOutbound', id, host, port] {
+ during TcpConnection($id, TcpAddress($host, $port))
+ spawn named ['driver/TcpOutbound', id, host, port] {
let finish = Dataspace.backgroundTask();
on stop finish();
@@ -69,9 +70,9 @@ spawn named 'TcpDriver' {
}
}
- during Observe(LineIn($id, _)) spawn named ['TcpLineReader', id] {
- field this.buffer = Buffer.alloc(0);
- on message DataIn(id, $data) this.buffer = Buffer.concat([this.buffer, data]);
+ during Observe(LineIn($id, _)) spawn named ['driver/TcpLineReader', id] {
+ field this.buffer = Bytes();
+ on message DataIn(id, $data) this.buffer = Bytes.concat([this.buffer, data]);
dataflow {
const pos = this.buffer.indexOf(10);
if (pos !== -1) {
@@ -107,12 +108,12 @@ function _connectionCommon(rootFacet, id, socket, established) {
on start react stop on asserted Observe(DataIn(id, _)) {
socket.on('data', Dataspace.wrapExternal((data) => {
- ^ DataIn(id, data);
+ ^ DataIn(id, Bytes.fromIO(data));
}));
}
on message DataOut(id, $data) {
- socket.write(data);
+ socket.write(Bytes.toIO(data));
}
}
}
diff --git a/packages/driver-udp-node/src/index.js b/packages/driver-udp-node/src/index.js
index 5055cf0..9f58cd6 100644
--- a/packages/driver-udp-node/src/index.js
+++ b/packages/driver-udp-node/src/index.js
@@ -16,7 +16,7 @@
// along with this program. If not, see .
//---------------------------------------------------------------------------
-import { currentFacet, Observe, Dataspace } from "@syndicate-lang/core";
+import { currentFacet, Observe, Dataspace, Bytes } from "@syndicate-lang/core";
import { createSocket } from "dgram";
const { sleep } = activate require("@syndicate-lang/driver-timer");
@@ -70,7 +70,7 @@ function _socket(addr, port) {
socket.on('listening', Dataspace.wrapExternal(() => { this.connected = true; }));
socket.on('message', Dataspace.wrapExternal((message, rinfo) => {
- ^ UdpPacket(UdpPeer(rinfo.address, rinfo.port), addr, message);
+ ^ UdpPacket(UdpPeer(rinfo.address, rinfo.port), addr, Bytes.fromIO(message));
}));
};
@@ -88,6 +88,7 @@ function _socket(addr, port) {
assert addr when (this.connected);
on message UdpPacket(addr, UdpPeer($host, $port), $payload) {
+ payload = Bytes.toIO(payload);
socket.send(payload, 0, payload.length, port, host, Dataspace.wrapExternal((err) => {
if (err) {
console.error(err);
diff --git a/packages/driver-websocket/src/index.js b/packages/driver-websocket/src/index.js
index 2bad7cb..4136226 100644
--- a/packages/driver-websocket/src/index.js
+++ b/packages/driver-websocket/src/index.js
@@ -16,7 +16,7 @@
// along with this program. If not, see .
//---------------------------------------------------------------------------
-import { currentFacet, Observe, Dataspace } from "@syndicate-lang/core";
+import { currentFacet, Bytes, Observe, Dataspace } from "@syndicate-lang/core";
const { sleep } = activate require("@syndicate-lang/driver-timer");
const _WebSocket = require('isomorphic-ws');
@@ -52,7 +52,7 @@ spawn named 'WebSocketFactory' {
ws.onopen = Dataspace.wrapExternal(() => { this.connected = true; });
ws.onclose = Dataspace.wrapExternal(() => { if (this.connected) { connect(); }});
- ws.onmessage = Dataspace.wrapExternal((data) => { ^ DataIn(id, data.data); });
+ ws.onmessage = Dataspace.wrapExternal((data) => { ^ DataIn(id, Bytes.fromIO(data.data)); });
};
const disconnect = () => {
@@ -70,7 +70,7 @@ spawn named 'WebSocketFactory' {
on message DataOut(id, $data) {
if (this.connected) {
- ws.send(data);
+ ws.send(Bytes.toIO(data));
}
}
}
diff --git a/packages/syntax-playground/src/client.js b/packages/syntax-playground/src/client.js
index 0ed3294..a15bd77 100644
--- a/packages/syntax-playground/src/client.js
+++ b/packages/syntax-playground/src/client.js
@@ -16,7 +16,7 @@
// along with this program. If not, see .
//---------------------------------------------------------------------------
-import { currentFacet, genUuid } from "@syndicate-lang/core";
+import { currentFacet, genUuid, Bytes } from "@syndicate-lang/core";
const WS = activate require("@syndicate-lang/driver-websocket");
const { PeriodicTick } = activate require("@syndicate-lang/driver-timer");
@@ -34,7 +34,7 @@ spawn named 'demo' {
}
on message PeriodicTick(1000) {
- ^ WS.DataOut(wsId, genUuid('timestamp'));
+ ^ WS.DataOut(wsId, Bytes.from(genUuid('timestamp')));
}
}
}
diff --git a/packages/syntax-playground/src/mc.js b/packages/syntax-playground/src/mc.js
index d9ce76c..96e13b5 100644
--- a/packages/syntax-playground/src/mc.js
+++ b/packages/syntax-playground/src/mc.js
@@ -35,7 +35,7 @@ spawn named 'multicast_demo' {
assert U.UdpMulticastLoopback(HANDLE, true);
on message U.UdpPacket(U.UdpPeer($host, $port), HANDLE, $body) {
- console.log('Got', body.toString(), 'from', host, port);
+ console.log('Got', body, 'from', host, port);
}
on message PeriodicTick(2000) {
diff --git a/packages/syntax-playground/src/server.js b/packages/syntax-playground/src/server.js
index 4c6de0c..51551d7 100644
--- a/packages/syntax-playground/src/server.js
+++ b/packages/syntax-playground/src/server.js
@@ -74,6 +74,15 @@ function counter() {
return id;
}
+spawn named 'serverLogger' {
+ on asserted Http.Request(_, server, $method, $path, $query, $req) {
+ console.log(method, path.toJS(), query.toJS());
+ }
+ on asserted Http.WebSocket(_, server, $path, $query) {
+ console.log(path.toJS(), query.toJS());
+ }
+}
+
spawn named 'rootServer' {
let counters = {};
on asserted Counter($id) counters[id] = true;
diff --git a/packages/syntax/src/plugin.js b/packages/syntax/src/plugin.js
index 053cfdf..472b10c 100644
--- a/packages/syntax/src/plugin.js
+++ b/packages/syntax/src/plugin.js
@@ -66,9 +66,9 @@ function discardAst(state) {
return _discardAst({ SYNDICATE: state.SyndicateID });
}
-const _listAst = template.expression(`IMMUTABLE.fromJS(VS)`);
+const _listAst = template.expression(`SYNDICATE.fromJS(VS)`);
function listAst(state, vs) {
- return _listAst({ IMMUTABLE: state.ImmutableID, VS: vs });
+ return _listAst({ SYNDICATE: state.SyndicateID, VS: vs });
}
function captureWrap(state, ast) {
@@ -123,7 +123,7 @@ function compilePattern(state, patternPath) {
// constPaths/constVals.
if (hasCapturesOrDiscards(patternPath)) {
let arity = pattern.arguments.length;
- let skel = [t.memberExpression(pattern.callee, t.identifier('meta'), false, false)];
+ let skel = [t.memberExpression(pattern.callee, t.identifier('constructorInfo'), false, false)];
let assn = [];
for (let i = 0; i < arity; i++) {
syndicatePath.push(i);
@@ -295,25 +295,22 @@ export default declare((api, options) => {
visitor: {
Program(path, state) {
let savedGlobalFacetUid = path.scope.generateUidIdentifier("savedGlobalFacet");
- state.ImmutableID = path.scope.generateUidIdentifier("Immutable");
state.SyndicateID = path.scope.generateUidIdentifier("Syndicate");
state.DataspaceID = path.scope.generateUidIdentifier("Dataspace");
state.SkeletonID = path.scope.generateUidIdentifier("Skeleton");
- state.StructID = path.scope.generateUidIdentifier("Struct");
+ state.RecordID = path.scope.generateUidIdentifier("Record");
path.unshiftContainer(
'body',
template(`const SYNDICATE = require("@syndicate-lang/core");
- const IMMUTABLE = SYNDICATE.Immutable;
const DATASPACE = SYNDICATE.Dataspace;
const SKELETON = SYNDICATE.Skeleton;
- const STRUCT = SYNDICATE.Struct;
+ const RECORD = SYNDICATE.Record;
let SAVEDGLOBALFACET = DATASPACE._currentFacet;
DATASPACE._currentFacet = new SYNDICATE._Dataspace.ActionCollector();`)({
- IMMUTABLE: state.ImmutableID,
SYNDICATE: state.SyndicateID,
DATASPACE: state.DataspaceID,
SKELETON: state.SkeletonID,
- STRUCT: state.StructID,
+ RECORD: state.RecordID,
SAVEDGLOBALFACET: savedGlobalFacetUid,
}));
path.pushContainer(
@@ -346,8 +343,8 @@ export default declare((api, options) => {
PROC: node.bootProc
}),
ASSERTIONS: node.initialAssertions.length === 0 ? null :
- template.expression(`IMMUTABLE.Set(SEQ)`)({
- IMMUTABLE: state.ImmutableID,
+ template.expression(`SYNDICATE.Set(SEQ)`)({
+ SYNDICATE: state.SyndicateID,
SEQ: t.arrayExpression(node.initialAssertions)
}),
}));
@@ -453,9 +450,9 @@ export default declare((api, options) => {
SyndicateTypeDefinition(path, state) {
const { node } = path;
- path.replaceWith(template(`const ID = STRUCT.makeConstructor(WIRE, FORMALS);`)({
+ path.replaceWith(template(`const ID = RECORD.makeConstructor(WIRE, FORMALS);`)({
ID: node.id,
- STRUCT: state.StructID,
+ RECORD: state.RecordID,
WIRE: node.wireName || t.stringLiteral(node.id.name),
FORMALS: t.arrayExpression(node.formals.map((f) => t.stringLiteral(f.name))),
}));