This commit is contained in:
Tony Garnock-Jones 2016-08-07 15:41:10 -04:00
parent 6a5f786b6b
commit d6306ae41c
22 changed files with 1032 additions and 797 deletions

412
dist/syndicate.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
examples/button/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.expanded.js

7
examples/button/Makefile Normal file
View File

@ -0,0 +1,7 @@
all: index.expanded.js
%.expanded.js: %.js
../../bin/syndicatec $< > $@ || (rm -f $@; false)
clean:
rm -f *.expanded.js

View File

@ -2,13 +2,14 @@
new Syndicate.Ground(function () {
Syndicate.UI.spawnUIDriver();
Syndicate.Actor.spawnActor(new Object(), function() {
var counter = 0;
Syndicate.Actor.spawnActor(function() {
Syndicate.Actor.declareField(this, "counter", 0);
var ui = new Syndicate.UI.Anchor();
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(ui.html('#button-label',''+counter), 0); }))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('#counter','click',_), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('#counter','click',_), metalevel: 0 }; }), (function() {
counter++;
})).completeBuild();
(function () {
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(ui.html('#button-label', '' + this.counter), 0); }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('#counter', 'click', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('#counter', 'click', _), metalevel: 0 }; }), (function() {
this.counter++;
})).completeBuild(); }).call(this);
});
}).startStepping();

View File

@ -2,12 +2,12 @@ ground dataspace {
Syndicate.UI.spawnUIDriver();
actor {
var counter = 0;
field this.counter = 0;
var ui = new Syndicate.UI.Anchor();
react {
assert ui.html('#button-label', '' + counter);
assert ui.html('#button-label', '' + this.counter);
on message Syndicate.UI.globalEvent('#counter', 'click', _) {
counter++;
this.counter++;
}
}
}

View File

@ -17,6 +17,8 @@ function spawnChatApp() {
actor {
var ui = new Syndicate.UI.Anchor();
field this.nym;
field this.status;
react {
on asserted inputValue('#nym', $v) { this.nym = v; }
on asserted inputValue('#status', $v) { this.status = v; }
@ -83,17 +85,11 @@ assertion type inputValue(selector, value);
function spawnInputChangeMonitor() {
actor {
react {
on asserted Syndicate.observe(inputValue($selector, _)) {
actor {
this.value = $(selector).val();
react {
assert inputValue(selector, this.value);
on message Syndicate.UI.globalEvent(selector, 'change', $e) {
this.value = e.target.value;
}
} until {
case retracted Syndicate.observe(inputValue(selector, _));
}
during Syndicate.observe(inputValue($selector, _)) actor {
field this.value = $(selector).val();
assert inputValue(selector, this.value);
on message Syndicate.UI.globalEvent(selector, 'change', $e) {
this.value = e.target.value;
}
}
}

View File

@ -60,7 +60,7 @@ function spawnRemoteListener() {
function spawnStoveSwitch() {
actor {
this.powerOn = false;
field this.powerOn = false;
this.ui = new Syndicate.UI.Anchor();
react {
assert componentPresent('stove switch');
@ -85,7 +85,7 @@ function spawnStoveSwitch() {
function spawnPowerDrawMonitor() {
actor {
this.watts = 0;
field this.watts = 0;
this.ui = new Syndicate.UI.Anchor();
react {
assert componentPresent('power draw monitor');

View File

@ -11,7 +11,7 @@ var G = new Syndicate.Ground(function () {
Syndicate.Timer.spawnTimerDriver();
Syndicate.Broker.spawnBrokerClientDriver();
Syndicate.Actor.spawnActor(new Object(), function() {
Syndicate.Actor.spawnActor(function() {
var id = Syndicate.RandomID.randomId(4, true);
var email_element = document.getElementById('my_email');
@ -41,7 +41,7 @@ var G = new Syndicate.Ground(function () {
var geocoder = new google.maps.Geocoder();
var wsurl_base = 'wss://demo-broker.syndicate-lang.org:8443/location/';
var wsurl = wsurl_base + group_element.value.trim();
Syndicate.Actor.declareField(this, "wsurl", wsurl_base + group_element.value.trim());
var watchId = ('geolocation' in navigator)
&& navigator.geolocation.watchPosition(Syndicate.Dataspace.wrap(function (pos) {
@ -62,29 +62,29 @@ var G = new Syndicate.Ground(function () {
timeout: 15000
}));
(function () { var currentLocation = null; var selectedMarker = null;
(function () { Syndicate.Actor.declareField(this, "currentLocation", null); var selectedMarker = null;
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(brokerConnection(wsurl), 0); }))
.addAssertion((function() { var _ = Syndicate.__; return (currentLocation) ? Syndicate.Patch.assert(toBroker(wsurl, currentLocation), 0) : Syndicate.Patch.emptyPatch; }))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('#my_email', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('#my_email', 'change', _), metalevel: 0 }; }), (function() {
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(brokerConnection(this.wsurl), 0); }))
.addAssertion((function() { var _ = Syndicate.__; return (this.currentLocation) ? Syndicate.Patch.assert(toBroker(this.wsurl, this.currentLocation), 0) : Syndicate.Patch.emptyPatch; }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('#my_email', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('#my_email', 'change', _), metalevel: 0 }; }), (function() {
var v = email_element.value.trim();
if (currentLocation) currentLocation[1] = v;
if (this.currentLocation) this.currentLocation = this.currentLocation.set(1, v);
localStorage.my_email = v;
}))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('#group', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('#group', 'change', _), metalevel: 0 }; }), (function() {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('#group', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('#group', 'change', _), metalevel: 0 }; }), (function() {
localStorage.group = group_element.value.trim();
wsurl = wsurl_base + group_element.value.trim();
this.wsurl = wsurl_base + group_element.value.trim();
}))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('#findMarker', 'click', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('#findMarker', 'click', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('#findMarker', 'click', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('#findMarker', 'click', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
Syndicate.Dataspace.send(findMarker(document.getElementById('markerList').value));
}))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('#markerList', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('#markerList', 'change', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('#markerList', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('#markerList', 'change', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
Syndicate.Dataspace.send(findMarker(document.getElementById('markerList').value));
}))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub((locationRecord(_, _, _, _, _)), 0); }), (function() { var _ = Syndicate.__; return { assertion: ((Syndicate._$("loc",locationRecord(_, _, _, _, _)))), metalevel: 0 }; }), (function(loc) {
currentLocation = loc;
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub((locationRecord(_, _, _, _, _)), 0); }), (function() { var _ = Syndicate.__; return { assertion: ((Syndicate._$("loc",locationRecord(_, _, _, _, _)))), metalevel: 0 }; }), (function(loc) {
this.currentLocation = loc;
}))
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(fromBroker(wsurl, locationRecord(_, _, _, _, _)), 0); }), (function() { var _ = Syndicate.__; return { assertion: fromBroker(wsurl, locationRecord((Syndicate._$("id")), (Syndicate._$("email")), _, _, _)), metalevel: 0 }; }), (function(id, email) { var ui = new Syndicate.UI.Anchor(); var marker = new google.maps.Marker({
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(fromBroker(this.wsurl, locationRecord(_, _, _, _, _)), 0); }), (function() { var _ = Syndicate.__; return { assertion: fromBroker(this.wsurl, locationRecord((Syndicate._$("id")), (Syndicate._$("email")), _, _, _)), metalevel: 0 }; }), (function(id, email) { var ui = new Syndicate.UI.Anchor(); var marker = new google.maps.Marker({
map: map,
clickable: true,
icon: 'https://www.gravatar.com/avatar/' + md5(email.trim().toLowerCase()) + '?s=32&d=retro'
@ -105,7 +105,7 @@ Syndicate.Actor.createFacet()
});
}
}
var _cachedAssertion1470084347961_0 = (function() { var _ = Syndicate.__; return fromBroker(wsurl, locationRecord(id, email, _, _, _)); })();
var _cachedAssertion1470598812190_0 = (function() { var _ = Syndicate.__; return fromBroker(this.wsurl, locationRecord(id, email, _, _, _)); }).call(this);
Syndicate.Actor.createFacet()
.addInitBlock((function() {
marker.addListener('click', Syndicate.Dataspace.wrap(function () {
@ -117,11 +117,11 @@ Syndicate.Actor.createFacet()
id: id,
email: email
})), 0); }))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(findMarker(id), 0); }), (function() { var _ = Syndicate.__; return { assertion: findMarker(id), metalevel: 0 }; }), (function() {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(findMarker(id), 0); }), (function() { var _ = Syndicate.__; return { assertion: findMarker(id), metalevel: 0 }; }), (function() {
selectMarker();
if (latestPosition) map.panTo(latestPosition);
}))
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(fromBroker(wsurl, locationRecord(id, email, _, _, _)), 0); }), (function() { var _ = Syndicate.__; return { assertion: fromBroker(wsurl, locationRecord(id, email, (Syndicate._$("timestamp")), (Syndicate._$("lat")), (Syndicate._$("lng")))), metalevel: 0 }; }), (function(timestamp, lat, lng) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(fromBroker(this.wsurl, locationRecord(id, email, _, _, _)), 0); }), (function() { var _ = Syndicate.__; return { assertion: fromBroker(this.wsurl, locationRecord(id, email, (Syndicate._$("timestamp")), (Syndicate._$("lat")), (Syndicate._$("lng")))), metalevel: 0 }; }), (function(timestamp, lat, lng) {
latestTimestamp = new Date(timestamp);
latestPosition = {lat: lat, lng: lng};
marker.setPosition(latestPosition);
@ -132,6 +132,6 @@ Syndicate.Actor.createFacet()
marker.setMap(null);
if (selectedMarker === marker) selectedMarker = null;
}))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084347961_0, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084347961_0, metalevel: 0 }; }), (function() {})).completeBuild(); })).completeBuild(); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598812190_0, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598812190_0, metalevel: 0 }; }), (function() {})).completeBuild(); })).completeBuild(); }).call(this);
});
}).startStepping();

View File

@ -40,7 +40,7 @@ ground dataspace G {
var geocoder = new google.maps.Geocoder();
var wsurl_base = 'wss://demo-broker.syndicate-lang.org:8443/location/';
var wsurl = wsurl_base + group_element.value.trim();
field this.wsurl = wsurl_base + group_element.value.trim();
var watchId = ('geolocation' in navigator)
&& navigator.geolocation.watchPosition(Syndicate.Dataspace.wrap(function (pos) {
@ -62,21 +62,21 @@ ground dataspace G {
}));
react {
var currentLocation = null;
field this.currentLocation = null;
var selectedMarker = null;
assert brokerConnection(wsurl);
assert toBroker(wsurl, currentLocation) when (currentLocation);
assert brokerConnection(this.wsurl);
assert toBroker(this.wsurl, this.currentLocation) when (this.currentLocation);
on message Syndicate.UI.globalEvent('#my_email', 'change', _) {
var v = email_element.value.trim();
if (currentLocation) currentLocation[1] = v;
if (this.currentLocation) this.currentLocation = this.currentLocation.set(1, v);
localStorage.my_email = v;
}
on message Syndicate.UI.globalEvent('#group', 'change', _) {
localStorage.group = group_element.value.trim();
wsurl = wsurl_base + group_element.value.trim();
this.wsurl = wsurl_base + group_element.value.trim();
}
on message Syndicate.UI.globalEvent('#findMarker', 'click', $e) {
@ -87,10 +87,10 @@ ground dataspace G {
}
on message ($loc = locationRecord(_, _, _, _, _)) {
currentLocation = loc;
this.currentLocation = loc;
}
during fromBroker(wsurl, locationRecord($id, $email, _, _, _)) {
during fromBroker(this.wsurl, locationRecord($id, $email, _, _, _)) {
var ui = new Syndicate.UI.Anchor();
var marker = new google.maps.Marker({
map: map,
@ -131,7 +131,7 @@ ground dataspace G {
selectMarker();
if (latestPosition) map.panTo(latestPosition);
}
on asserted fromBroker(wsurl, locationRecord(id, email, $timestamp, $lat, $lng)) {
on asserted fromBroker(this.wsurl, locationRecord(id, email, $timestamp, $lat, $lng)) {
latestTimestamp = new Date(timestamp);
latestPosition = {lat: lat, lng: lng};
marker.setPosition(latestPosition);

View File

@ -14,8 +14,8 @@ ground dataspace G {
var color = tinycolor('hsl ' + (Math.random() * 360 | 0) + ' 100% 50%').toHexString();
var x = 0;
var y = 0;
var publishedX = x;
var publishedY = y;
field this.publishedX = x;
field this.publishedY = y;
function clamp(v) {
var limit = 9.8;
@ -28,10 +28,10 @@ ground dataspace G {
assert Syndicate.UI.uiAttribute('rect#my_color', 'fill', color);
assert toBroker(wsurl, point(color, publishedX, publishedY));
assert toBroker(wsurl, point(color, this.publishedX, this.publishedY));
on message Syndicate.Timer.periodicTick(100) {
publishedX = x;
publishedY = y;
this.publishedX = x;
this.publishedY = y;
}
on message Syndicate.UI.windowEvent('deviceorientation', $e) {

View File

@ -6,16 +6,16 @@ ground dataspace {
actor {
react until {
case asserted Syndicate.observe(beep(_)) {
var counter = 0;
field this.counter = 0;
react {
do {
:: beep(counter++);
:: beep(this.counter++);
}
on message beep(_) {
:: beep(counter++);
:: beep(this.counter++);
}
} until {
case (counter >= 10);
case (this.counter > 10);
}
}
}

View File

@ -4,6 +4,10 @@ ground dataspace G {
actor {
var ui = new Syndicate.UI.Anchor();
field this.angle;
field this.handX;
field this.handY;
react {
assert ui.html('#clock',
'<svg width="300px" viewBox="0 0 100 100">'+

View File

@ -20,7 +20,7 @@ function spawnModel() {
function spawnView() {
actor named 'view' {
var ui = new Syndicate.UI.Anchor();
var orderColumn = 2;
field this.orderColumn = 2;
function cell(text) {
// Should escape text in a real application.
@ -28,13 +28,13 @@ function spawnView() {
}
react {
on message setSortColumn($c) { orderColumn = c; }
on message setSortColumn($c) { this.orderColumn = c; }
during person($id, $firstName, $lastName, $address, $age) {
assert ui.context(id)
.html('table#the-table tbody',
'<tr>' + [id, firstName, lastName, address, age].map(cell).join('') + '</tr>',
[id, firstName, lastName, address, age][orderColumn]);
[id, firstName, lastName, address, age][this.orderColumn]);
}
}
}

View File

@ -26,24 +26,24 @@ function piece(text, pos, lo, hi, cls) {
function spawnGui() {
actor {
this.text = '';
this.pos = 0;
this.highlightState = false;
this.updateDisplay = function () {
var text = this.text;
var pos = this.pos;
var highlight = this.highlightState;
var hLeft = highlight ? highlight[0] : 0;
var hRight = highlight ? highlight[1] : 0;
document.getElementById("fieldContents").innerHTML = highlight
? piece(text, pos, 0, hLeft, "normal") +
piece(text, pos, hLeft, hRight, "highlight") +
piece(text, pos, hRight, text.length + 1, "normal")
: piece(text, pos, 0, text.length + 1, "normal");
};
react {
field this.text = '';
field this.pos = 0;
field this.highlightState = false;
dataflow {
var text = this.text;
var pos = this.pos;
var highlight = this.highlightState;
var hLeft = highlight ? highlight[0] : 0;
var hRight = highlight ? highlight[1] : 0;
document.getElementById("fieldContents").innerHTML = highlight
? piece(text, pos, 0, hLeft, "normal") +
piece(text, pos, hLeft, hRight, "highlight") +
piece(text, pos, hRight, text.length + 1, "normal")
: piece(text, pos, 0, text.length + 1, "normal");
}
on message globalEvent("#inputRow", "+keydown", $event) {
switch (event.keyCode) {
case 37 /* left */: :: fieldCommand("cursorLeft"); break;
@ -67,12 +67,10 @@ function spawnGui() {
on asserted fieldContents($text, $pos) {
this.text = text;
this.pos = pos;
this.updateDisplay();
}
on asserted highlight($state) {
this.highlightState = state;
this.updateDisplay();
}
}
}
@ -83,10 +81,10 @@ function spawnGui() {
function spawnModel() {
actor {
this.fieldValue = "initial";
this.cursorPos = this.fieldValue.length; /* positions address gaps between characters */
react {
field this.fieldValue = "initial";
field this.cursorPos = this.fieldValue.length; /* positions address gaps between characters */
assert fieldContents(this.fieldValue, this.cursorPos);
on message fieldCommand("cursorLeft") {
@ -126,29 +124,28 @@ function spawnModel() {
function spawnSearch() {
actor {
this.fieldValue = "";
this.highlight = false;
this.search = function () {
var searchtext = document.getElementById("searchBox").value;
if (searchtext) {
var pos = this.fieldValue.indexOf(searchtext);
this.highlight = (pos !== -1) && [pos, pos + searchtext.length];
} else {
this.highlight = false;
}
};
react {
field this.searchtext = document.getElementById("searchBox").value;
field this.fieldValue = "";
field this.highlight = false;
assert highlight(this.highlight);
dataflow {
if (this.searchtext) {
var pos = this.fieldValue.indexOf(this.searchtext);
this.highlight = (pos !== -1) && [pos, pos + this.searchtext.length];
} else {
this.highlight = false;
}
}
on message globalEvent("#searchBox", "input", $event) {
this.search();
this.searchtext = document.getElementById("searchBox").value;
}
on asserted fieldContents($text, _) {
this.fieldValue = text;
this.search();
}
}
}

View File

@ -20,21 +20,17 @@ var show = Syndicate.Struct.makeConstructor("show", ["completed"]);
//////////////////////////////////////////////////////////////////////////
function todoListItemModel(initialId, initialTitle, initialCompleted) {
Syndicate.Actor.spawnActor(new Object(), function() {
this.id = initialId;
this.title = initialTitle;
this.completed = initialCompleted;
(function () {
Syndicate.Actor.spawnActor(function() {
(function () { Syndicate.Actor.declareField(this, "id", initialId); Syndicate.Actor.declareField(this, "title", initialTitle); Syndicate.Actor.declareField(this, "completed", initialCompleted);
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(todo(this.id, this.title, this.completed), 0); }))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(setCompleted(this.id, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: setCompleted(this.id, (Syndicate._$("v"))), metalevel: 0 }; }), (function(v) { this.completed = v; }))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(setAllCompleted(_), 0); }), (function() { var _ = Syndicate.__; return { assertion: setAllCompleted((Syndicate._$("v"))), metalevel: 0 }; }), (function(v) { this.completed = v; }))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(setTitle(this.id, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: setTitle(this.id, (Syndicate._$("v"))), metalevel: 0 }; }), (function(v) { this.title = v; }))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(clearCompletedTodos(), 0); }), (function() { var _ = Syndicate.__; return { assertion: clearCompletedTodos(), metalevel: 0 }; }), (function() {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(setCompleted(this.id, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: setCompleted(this.id, (Syndicate._$("v"))), metalevel: 0 }; }), (function(v) { this.completed = v; }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(setAllCompleted(_), 0); }), (function() { var _ = Syndicate.__; return { assertion: setAllCompleted((Syndicate._$("v"))), metalevel: 0 }; }), (function(v) { this.completed = v; }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(setTitle(this.id, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: setTitle(this.id, (Syndicate._$("v"))), metalevel: 0 }; }), (function(v) { this.title = v; }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(clearCompletedTodos(), 0); }), (function() { var _ = Syndicate.__; return { assertion: clearCompletedTodos(), metalevel: 0 }; }), (function() {
if (this.completed) Syndicate.Dataspace.send(deleteTodo(this.id));
}))
.onEvent(true, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(deleteTodo(this.id), 0); }), (function() { var _ = Syndicate.__; return { assertion: deleteTodo(this.id), metalevel: 0 }; }), (function() {})).completeBuild(); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(deleteTodo(this.id), 0); }), (function() { var _ = Syndicate.__; return { assertion: deleteTodo(this.id), metalevel: 0 }; }), (function() {})).completeBuild(); }).call(this);
});
}
@ -48,16 +44,15 @@ function getTemplate(id) {
}
function todoListItemView(id) {
Syndicate.Actor.spawnActor(new Object(), function() {
Syndicate.Actor.spawnActor(function() {
this.ui = new Syndicate.UI.Anchor();
this.editing = false;
(function () {
(function () { Syndicate.Actor.declareField(this, "editing", false);
Syndicate.Actor.createFacet()
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(id, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo(id, (Syndicate._$("title")), (Syndicate._$("completed"))), metalevel: 0 }; }), (function(title, completed) {
var _cachedAssertion1470084349188_0 = (function() { var _ = Syndicate.__; return todo(id, title, completed); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(id, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo(id, (Syndicate._$("title")), (Syndicate._$("completed"))), metalevel: 0 }; }), (function(title, completed) {
var _cachedAssertion1470598813428_0 = (function() { var _ = Syndicate.__; return todo(id, title, completed); }).call(this);
Syndicate.Actor.createFacet()
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(show(completed), 0); }), (function() { var _ = Syndicate.__; return { assertion: show(completed), metalevel: 0 }; }), (function() {
var _cachedAssertion1470084349188_1 = (function() { var _ = Syndicate.__; return show(completed); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(show(completed), 0); }), (function() { var _ = Syndicate.__; return { assertion: show(completed), metalevel: 0 }; }), (function() {
var _cachedAssertion1470598813428_1 = (function() { var _ = Syndicate.__; return show(completed); }).call(this);
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(this.ui.html('.todo-list',
Mustache.render(getTemplate(this.editing
@ -70,31 +65,31 @@ Syndicate.Actor.createFacet()
checked: completed ? "checked" : "",
}),
id), 0); }))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084349188_1, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084349188_1, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084349188_0, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084349188_0, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(this.ui.event('.toggle', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: this.ui.event('.toggle', 'change', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598813428_1, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598813428_1, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598813428_0, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598813428_0, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(this.ui.event('.toggle', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: this.ui.event('.toggle', 'change', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
Syndicate.Dataspace.send(setCompleted(id, e.target.checked));
}))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(this.ui.event('.destroy', 'click', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: this.ui.event('.destroy', 'click', _), metalevel: 0 }; }), (function() {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(this.ui.event('.destroy', 'click', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: this.ui.event('.destroy', 'click', _), metalevel: 0 }; }), (function() {
Syndicate.Dataspace.send(deleteTodo(id));
}))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(this.ui.event('label', 'dblclick', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: this.ui.event('label', 'dblclick', _), metalevel: 0 }; }), (function() {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(this.ui.event('label', 'dblclick', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: this.ui.event('label', 'dblclick', _), metalevel: 0 }; }), (function() {
this.editing = true;
}))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(this.ui.event('input.edit', 'keyup', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: this.ui.event('input.edit', 'keyup', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(this.ui.event('input.edit', 'keyup', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: this.ui.event('input.edit', 'keyup', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
if (e.keyCode === ESCAPE_KEY_CODE || e.keyCode === ENTER_KEY_CODE) {
this.editing = false;
}
}))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(this.ui.event('input.edit', 'blur', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: this.ui.event('input.edit', 'blur', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(this.ui.event('input.edit', 'blur', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: this.ui.event('input.edit', 'blur', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
this.editing = false;
}))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(this.ui.event('input.edit', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: this.ui.event('input.edit', 'change', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(this.ui.event('input.edit', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: this.ui.event('input.edit', 'change', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
var newTitle = e.target.value.trim();
Syndicate.Dataspace.send((newTitle ? setTitle(id, newTitle) : deleteTodo(id)));
this.editing = false;
}))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(id, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo(id, _, _), metalevel: 0 }; }), (function() {})).completeBuild(); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(id, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo(id, _, _), metalevel: 0 }; }), (function() {})).completeBuild(); }).call(this);
});
}
@ -103,96 +98,94 @@ Syndicate.Actor.createFacet()
var G = new Syndicate.Ground(function () {
Syndicate.UI.spawnUIDriver();
Syndicate.Actor.spawnActor(new Object(), function() {
Syndicate.Actor.spawnActor(function() {
(function () {
Syndicate.Actor.createFacet()
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('.new-todo', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('.new-todo', 'change', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('.new-todo', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('.new-todo', 'change', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
var newTitle = e.target.value.trim();
if (newTitle) Syndicate.Dataspace.send(createTodo(newTitle));
e.target.value = "";
})).completeBuild(); })();
})).completeBuild(); }).call(this);
});
Syndicate.Actor.spawnActor(new Object(), function() {
Syndicate.Actor.spawnActor(function() {
this.ui = new Syndicate.UI.Anchor();
(function () {
Syndicate.Actor.createFacet()
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(activeTodoCount(_), 0); }), (function() { var _ = Syndicate.__; return { assertion: activeTodoCount((Syndicate._$("count"))), metalevel: 0 }; }), (function(count) {
var _cachedAssertion1470084349188_2 = (function() { var _ = Syndicate.__; return activeTodoCount(count); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(activeTodoCount(_), 0); }), (function() { var _ = Syndicate.__; return { assertion: activeTodoCount((Syndicate._$("count"))), metalevel: 0 }; }), (function(count) {
var _cachedAssertion1470598813428_2 = (function() { var _ = Syndicate.__; return activeTodoCount(count); }).call(this);
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(this.ui.context('count').html('.todo-count strong', '' + count), 0); }))
.addAssertion((function() { var _ = Syndicate.__; return (count !== 1) ? Syndicate.Patch.assert(this.ui.context('plural').html('.todo-count span.s', 's'), 0) : Syndicate.Patch.emptyPatch; }))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084349188_2, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084349188_2, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(totalTodoCount(0), 0); }), (function() { var _ = Syndicate.__; return { assertion: totalTodoCount(0), metalevel: 0 }; }), (function() {
var _cachedAssertion1470084349188_3 = (function() { var _ = Syndicate.__; return totalTodoCount(0); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598813428_2, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598813428_2, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(totalTodoCount(0), 0); }), (function() { var _ = Syndicate.__; return { assertion: totalTodoCount(0), metalevel: 0 }; }), (function() {
var _cachedAssertion1470598813428_3 = (function() { var _ = Syndicate.__; return totalTodoCount(0); }).call(this);
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(Syndicate.UI.uiAttribute('section.main', 'class', 'hidden'), 0); }))
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(Syndicate.UI.uiAttribute('footer.footer', 'class', 'hidden'), 0); }))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084349188_3, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084349188_3, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(completedTodoCount(0), 0); }), (function() { var _ = Syndicate.__; return { assertion: completedTodoCount(0), metalevel: 0 }; }), (function() {
var _cachedAssertion1470084349188_4 = (function() { var _ = Syndicate.__; return completedTodoCount(0); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598813428_3, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598813428_3, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(completedTodoCount(0), 0); }), (function() { var _ = Syndicate.__; return { assertion: completedTodoCount(0), metalevel: 0 }; }), (function() {
var _cachedAssertion1470598813428_4 = (function() { var _ = Syndicate.__; return completedTodoCount(0); }).call(this);
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(Syndicate.UI.uiAttribute('button.clear-completed', 'class', 'hidden'), 0); }))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084349188_4, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084349188_4, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('button.clear-completed', 'click', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('button.clear-completed', 'click', _), metalevel: 0 }; }), (function() {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598813428_4, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598813428_4, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('button.clear-completed', 'click', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('button.clear-completed', 'click', _), metalevel: 0 }; }), (function() {
Syndicate.Dataspace.send(clearCompletedTodos());
}))
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(allCompleted(), 0); }), (function() { var _ = Syndicate.__; return { assertion: allCompleted(), metalevel: 0 }; }), (function() {
var _cachedAssertion1470084349188_5 = (function() { var _ = Syndicate.__; return allCompleted(); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(allCompleted(), 0); }), (function() { var _ = Syndicate.__; return { assertion: allCompleted(), metalevel: 0 }; }), (function() {
var _cachedAssertion1470598813428_5 = (function() { var _ = Syndicate.__; return allCompleted(); }).call(this);
Syndicate.Actor.createFacet()
.addInitBlock((function() { Syndicate.Dataspace.send(Syndicate.UI.setProperty('.toggle-all', 'checked', true)); }))
.addDoneBlock((function() { Syndicate.Dataspace.send(Syndicate.UI.setProperty('.toggle-all', 'checked', false)); }))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084349188_5, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084349188_5, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('.toggle-all', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('.toggle-all', 'change', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598813428_5, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598813428_5, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.globalEvent('.toggle-all', 'change', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.globalEvent('.toggle-all', 'change', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) {
Syndicate.Dataspace.send(setAllCompleted(e.target.checked));
}))
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(_, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo((Syndicate._$("id")), _, _), metalevel: 0 }; }), (function(id) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(_, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo((Syndicate._$("id")), _, _), metalevel: 0 }; }), (function(id) {
todoListItemView(id);
})).completeBuild(); })();
})).completeBuild(); }).call(this);
});
Syndicate.Actor.spawnActor(new Object(), function() {
var completedCount = 0;
var activeCount = 0;
(function () {
Syndicate.Actor.spawnActor(function() {
(function () { Syndicate.Actor.declareField(this, "completedCount", 0); Syndicate.Actor.declareField(this, "activeCount", 0);
Syndicate.Actor.createFacet()
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(_, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo((Syndicate._$("id")), _, (Syndicate._$("completed"))), metalevel: 0 }; }), (function(id, completed) { if (completed) completedCount++; else activeCount++; }))
.onEvent(false, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(_, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo((Syndicate._$("id")), _, (Syndicate._$("completed"))), metalevel: 0 }; }), (function(id, completed) { if (completed) completedCount--; else activeCount--; }))
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(activeTodoCount(activeCount), 0); }))
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(completedTodoCount(completedCount), 0); }))
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(totalTodoCount(activeCount + completedCount), 0); }))
.addAssertion((function() { var _ = Syndicate.__; return (completedCount > 0 && activeCount === 0) ? Syndicate.Patch.assert(allCompleted(), 0) : Syndicate.Patch.emptyPatch; })).completeBuild(); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(_, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo((Syndicate._$("id")), _, (Syndicate._$("c"))), metalevel: 0 }; }), (function(id, c) { if (c) this.completedCount++; else this.activeCount++; }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(_, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo((Syndicate._$("id")), _, (Syndicate._$("c"))), metalevel: 0 }; }), (function(id, c) { if (c) this.completedCount--; else this.activeCount--; }))
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(activeTodoCount(this.activeCount), 0); }))
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(completedTodoCount(this.completedCount), 0); }))
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(totalTodoCount(this.activeCount + this.completedCount), 0); }))
.addAssertion((function() { var _ = Syndicate.__; return (this.completedCount > 0 && this.activeCount === 0) ? Syndicate.Patch.assert(allCompleted(), 0) : Syndicate.Patch.emptyPatch; })).completeBuild(); }).call(this);
});
Syndicate.Actor.spawnActor(new Object(), function() {
Syndicate.Actor.spawnActor(function() {
(function () {
Syndicate.Actor.createFacet()
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.locationHash(_), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.locationHash((Syndicate._$("hash"))), metalevel: 0 }; }), (function(hash) {
var _cachedAssertion1470084349188_6 = (function() { var _ = Syndicate.__; return Syndicate.UI.locationHash(hash); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.locationHash(_), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.locationHash((Syndicate._$("hash"))), metalevel: 0 }; }), (function(hash) {
var _cachedAssertion1470598813428_6 = (function() { var _ = Syndicate.__; return Syndicate.UI.locationHash(hash); }).call(this);
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(Syndicate.UI.uiAttribute('ul.filters > li > a[href="#'+hash+'"]',
'class', 'selected'), 0); }))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084349188_6, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084349188_6, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.locationHash('/'), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.locationHash('/'), metalevel: 0 }; }), (function() {
var _cachedAssertion1470084349188_7 = (function() { var _ = Syndicate.__; return Syndicate.UI.locationHash('/'); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598813428_6, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598813428_6, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.locationHash('/'), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.locationHash('/'), metalevel: 0 }; }), (function() {
var _cachedAssertion1470598813428_7 = (function() { var _ = Syndicate.__; return Syndicate.UI.locationHash('/'); }).call(this);
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(show(true), 0); }))
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(show(false), 0); }))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084349188_7, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084349188_7, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.locationHash('/active'), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.locationHash('/active'), metalevel: 0 }; }), (function() {
var _cachedAssertion1470084349188_8 = (function() { var _ = Syndicate.__; return Syndicate.UI.locationHash('/active'); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598813428_7, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598813428_7, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.locationHash('/active'), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.locationHash('/active'), metalevel: 0 }; }), (function() {
var _cachedAssertion1470598813428_8 = (function() { var _ = Syndicate.__; return Syndicate.UI.locationHash('/active'); }).call(this);
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(show(false), 0); }))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084349188_8, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084349188_8, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.locationHash('/completed'), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.locationHash('/completed'), metalevel: 0 }; }), (function() {
var _cachedAssertion1470084349188_9 = (function() { var _ = Syndicate.__; return Syndicate.UI.locationHash('/completed'); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598813428_8, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598813428_8, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.UI.locationHash('/completed'), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.UI.locationHash('/completed'), metalevel: 0 }; }), (function() {
var _cachedAssertion1470598813428_9 = (function() { var _ = Syndicate.__; return Syndicate.UI.locationHash('/completed'); }).call(this);
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(show(true), 0); }))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084349188_9, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084349188_9, metalevel: 0 }; }), (function() {})).completeBuild(); })).completeBuild(); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598813428_9, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598813428_9, metalevel: 0 }; }), (function() {})).completeBuild(); })).completeBuild(); }).call(this);
});
Syndicate.Actor.spawnActor(new Object(), function() {
Syndicate.Actor.spawnActor(function() {
var db;
if ('todos-syndicate' in localStorage) {
@ -205,33 +198,33 @@ Syndicate.Actor.createFacet()
db = {nextId: 0, todos: {}};
(function () {
Syndicate.Actor.createFacet()
.onEvent(true, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.observe(createTodo(_)), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.observe(createTodo(_)), metalevel: 0 }; }), (function() {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.observe(createTodo(_)), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.observe(createTodo(_)), metalevel: 0 }; }), (function() {
Syndicate.Dataspace.send(createTodo('Buy milk'));
Syndicate.Dataspace.send(createTodo('Buy bread'));
Syndicate.Dataspace.send(createTodo('Finish PhD'));
})).completeBuild(); })();
})).completeBuild(); }).call(this);
}
(function () {
Syndicate.Actor.createFacet()
.onEvent(false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(createTodo(_), 0); }), (function() { var _ = Syndicate.__; return { assertion: createTodo((Syndicate._$("title"))), metalevel: 0 }; }), (function(title) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(createTodo(_), 0); }), (function() { var _ = Syndicate.__; return { assertion: createTodo((Syndicate._$("title"))), metalevel: 0 }; }), (function(title) {
todoListItemModel(db.nextId++, title, false);
}))
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(_, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo((Syndicate._$("id")), _, _), metalevel: 0 }; }), (function(id) {
var _cachedAssertion1470084349188_10 = (function() { var _ = Syndicate.__; return todo(id, _, _); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(_, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo((Syndicate._$("id")), _, _), metalevel: 0 }; }), (function(id) {
var _cachedAssertion1470598813428_10 = (function() { var _ = Syndicate.__; return todo(id, _, _); }).call(this);
Syndicate.Actor.createFacet()
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(id, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo(id, (Syndicate._$("title")), (Syndicate._$("completed"))), metalevel: 0 }; }), (function(title, completed) {
var _cachedAssertion1470084349188_11 = (function() { var _ = Syndicate.__; return todo(id, title, completed); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(todo(id, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: todo(id, (Syndicate._$("title")), (Syndicate._$("completed"))), metalevel: 0 }; }), (function(title, completed) {
var _cachedAssertion1470598813428_11 = (function() { var _ = Syndicate.__; return todo(id, title, completed); }).call(this);
Syndicate.Actor.createFacet()
.addInitBlock((function() {
db.todos[id] = {id: id, title: title, completed: completed};
localStorage['todos-syndicate'] = JSON.stringify(db);
}))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084349188_11, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084349188_11, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598813428_11, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598813428_11, metalevel: 0 }; }), (function() {})).completeBuild(); }))
.addDoneBlock((function() {
delete db.todos[id];
localStorage['todos-syndicate'] = JSON.stringify(db);
}))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084349188_10, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084349188_10, metalevel: 0 }; }), (function() {})).completeBuild(); })).completeBuild(); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598813428_10, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598813428_10, metalevel: 0 }; }), (function() {})).completeBuild(); })).completeBuild(); }).call(this);
});
}).startStepping();

View File

@ -25,11 +25,11 @@ assertion type show(completed);
function todoListItemModel(initialId, initialTitle, initialCompleted) {
actor {
this.id = initialId;
this.title = initialTitle;
this.completed = initialCompleted;
react {
field this.id = initialId;
field this.title = initialTitle;
field this.completed = initialCompleted;
assert todo(this.id, this.title, this.completed);
on message setCompleted(this.id, $v) { this.completed = v; }
@ -58,8 +58,9 @@ function getTemplate(id) {
function todoListItemView(id) {
actor {
this.ui = new Syndicate.UI.Anchor();
this.editing = false;
react {
field this.editing = false;
during todo(id, $title, $completed) {
during show(completed) {
assert this.ui.html('.todo-list',
@ -158,15 +159,15 @@ ground dataspace G {
}
actor {
var completedCount = 0;
var activeCount = 0;
react {
on asserted todo($id, _, $completed) { if (completed) completedCount++; else activeCount++; }
on retracted todo($id, _, $completed) { if (completed) completedCount--; else activeCount--; }
assert activeTodoCount(activeCount);
assert completedTodoCount(completedCount);
assert totalTodoCount(activeCount + completedCount);
assert allCompleted() when (completedCount > 0 && activeCount === 0);
field this.completedCount = 0;
field this.activeCount = 0;
on asserted todo($id, _, $c) { if (c) this.completedCount++; else this.activeCount++; }
on retracted todo($id, _, $c) { if (c) this.completedCount--; else this.activeCount--; }
assert activeTodoCount(this.activeCount);
assert completedTodoCount(this.completedCount);
assert totalTodoCount(this.activeCount + this.completedCount);
assert allCompleted() when (this.completedCount > 0 && this.activeCount === 0);
}
}

View File

@ -75,30 +75,38 @@ function whileRelevantAssert(P) {
(function () {
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(P, 0); }))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.observe(P), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.observe(P), metalevel: 0 }; }), (function() {})).completeBuild(); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.observe(P), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.observe(P), metalevel: 0 }; }), (function() {})).completeBuild(); }).call(this);
}
/// ### Implementation: SELLER
function seller() {
Syndicate.Actor.spawnActor(new Object(), function() {
Syndicate.Actor.spawnActor(function() {
/// We give our actor two state variables: a dictionary recording our
/// inventory of books (mapping title to price), and a counter
/// tracking the next order ID to be allocated.
///
/// We mark each property (entry) in the `books` table as a *field* so
/// that dependency-tracking on a per-book basis is enabled. As a result,
/// when a book is sold, any client still interested in its price will
/// learn that the book is no longer available.
///
/// We do not enable dependency-tracking for either the `books` table
/// itself or the `nextOrderId` field: nothing depends on tracking
/// changes in their values.
this.books = {
"The Wind in the Willows": 3.95,
"Catch 22": 2.22,
"Candide": 34.95
};
this.books = {};
Syndicate.Actor.declareField(this.books, "The Wind in the Willows", 3.95);
Syndicate.Actor.declareField(this.books, "Catch 22", 2.22);
Syndicate.Actor.declareField(this.books, "Candide", 34.95);
this.nextOrderId = 10001483;
/// Looking up a price yields `false` if no such book is in our
/// inventory.
this.priceOf = function (title) {
return (title in this.books) && this.books[title];
return (title in this.books) && Syndicate.Actor.referenceField(this.books, title);
};
/// The seller responds to interest in bookQuotes by asserting a
@ -106,17 +114,17 @@ function seller() {
(function () {
Syndicate.Actor.createFacet()
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.observe(bookQuote(_, _)), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.observe(bookQuote((Syndicate._$("title")), _)), metalevel: 0 }; }), (function(title) {
var _cachedAssertion1470084350531_0 = (function() { var _ = Syndicate.__; return Syndicate.observe(bookQuote(title, _)); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.observe(bookQuote(_, _)), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.observe(bookQuote((Syndicate._$("title")), _)), metalevel: 0 }; }), (function(title) {
var _cachedAssertion1470598814704_0 = (function() { var _ = Syndicate.__; return Syndicate.observe(bookQuote(title, _)); }).call(this);
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(bookQuote(title, this.priceOf(title)), 0); }))
.onEvent(true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470084350531_0, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470084350531_0, metalevel: 0 }; }), (function() {})).completeBuild(); })).completeBuild(); })();
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "retracted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(_cachedAssertion1470598814704_0, 0); }), (function() { var _ = Syndicate.__; return { assertion: _cachedAssertion1470598814704_0, metalevel: 0 }; }), (function() {})).completeBuild(); })).completeBuild(); }).call(this);
/// It also responds to order requests.
(function () {
Syndicate.Actor.createFacet()
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.observe(order(_, _, _, _)), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.observe(order((Syndicate._$("title")), (Syndicate._$("offerPrice")), _, _)), metalevel: 0 }; }), (function(title, offerPrice) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.observe(order(_, _, _, _)), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.observe(order((Syndicate._$("title")), (Syndicate._$("offerPrice")), _, _)), metalevel: 0 }; }), (function(title, offerPrice) {
/// We cannot sell a book we do not have, and we will not sell for
/// less than our asking price.
@ -131,21 +139,21 @@ Syndicate.Actor.createFacet()
/// replying to the orderer.
var orderId = this.nextOrderId++;
delete this.books[title];
Syndicate.Actor.deleteField(this.books, title);
Syndicate.Actor.spawnActor(new Object(), function() {
Syndicate.Actor.spawnActor(function() {
whileRelevantAssert(
order(title, offerPrice, orderId, "March 9th"));
});
}
})).completeBuild(); })();
})).completeBuild(); }).call(this);
});
}
/// ### Implementation: SPLIT-PROPOSER and book-quote-requestor
function buyerA() {
Syndicate.Actor.spawnActor(new Object(), function() {
Syndicate.Actor.spawnActor(function() {
var self = this;
/// Our actor remembers which books remain on its shopping list, and
@ -174,7 +182,7 @@ function buyerA() {
(function () {
Syndicate.Actor.createFacet()
.onEvent(true, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(bookQuote(title, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: bookQuote(title, (Syndicate._$("price"))), metalevel: 0 }; }), (function(price) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(bookQuote(title, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: bookQuote(title, (Syndicate._$("price"))), metalevel: 0 }; }), (function(price) {
if (price === false) {
console.log("A learns that "+title+" is out-of-stock.");
buyBooks();
@ -189,7 +197,7 @@ Syndicate.Actor.createFacet()
trySplit(title, price, price / 2);
}
})).completeBuild(); })();
})).completeBuild(); }).call(this);
}
function trySplit(title, price, contribution) {
@ -210,18 +218,18 @@ Syndicate.Actor.createFacet()
(function () {
Syndicate.Actor.createFacet()
.onEvent(true, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(splitProposal(title, price, contribution, true), 0); }), (function() { var _ = Syndicate.__; return { assertion: splitProposal(title, price, contribution, true), metalevel: 0 }; }), (function() {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(splitProposal(title, price, contribution, true), 0); }), (function() { var _ = Syndicate.__; return { assertion: splitProposal(title, price, contribution, true), metalevel: 0 }; }), (function() {
console.log("A learns that the split-proposal for "+
title+" was accepted");
buyBooks();
}))
.onEvent(true, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(splitProposal(title, price, contribution, false), 0); }), (function() { var _ = Syndicate.__; return { assertion: splitProposal(title, price, contribution, false), metalevel: 0 }; }), (function() {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(splitProposal(title, price, contribution, false), 0); }), (function() { var _ = Syndicate.__; return { assertion: splitProposal(title, price, contribution, false), metalevel: 0 }; }), (function() {
console.log("A learns that the split-proposal for "+
title+" was rejected");
trySplit(title,
price,
contribution + ((price - contribution) / 2));
})).completeBuild(); })();
})).completeBuild(); }).call(this);
}
}
});
@ -230,7 +238,7 @@ Syndicate.Actor.createFacet()
/// ### Implementation: SPLIT-DISPOSER and BUYER
function buyerB() {
Syndicate.Actor.spawnActor(new Object(), function() {
Syndicate.Actor.spawnActor(function() {
/// This actor maintains a record of the amount of money it has left
/// to spend.
@ -242,7 +250,7 @@ function buyerB() {
(function () {
Syndicate.Actor.createFacet()
.onEvent(false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.observe(splitProposal(_,
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(Syndicate.observe(splitProposal(_,
_,
_,
_)), 0); }), (function() { var _ = Syndicate.__; return { assertion: Syndicate.observe(splitProposal((Syndicate._$("title")),
@ -271,20 +279,20 @@ Syndicate.Actor.createFacet()
remainingFunds+" remaining funds");
this.funds = remainingFunds;
Syndicate.Actor.spawnActor(new Object(), function() {
Syndicate.Actor.spawnActor(function() {
(function () {
Syndicate.Actor.createFacet()
.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(splitProposal(title,
price,
theirContribution,
true), 0); }))
.onEvent(true, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(order(title, price, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: order(title, price, (Syndicate._$("id")), (Syndicate._$("date"))), metalevel: 0 }; }), (function(id, date) {
.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "asserted", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(order(title, price, _, _), 0); }), (function() { var _ = Syndicate.__; return { assertion: order(title, price, (Syndicate._$("id")), (Syndicate._$("date"))), metalevel: 0 }; }), (function(id, date) {
console.log("The order for "+title+" has id "+id+
", and will be delivered on "+date);
})).completeBuild(); })();
})).completeBuild(); }).call(this);
});
}
})).completeBuild(); })();
})).completeBuild(); }).call(this);
});
}

View File

@ -91,19 +91,27 @@ function seller() {
/// We give our actor two state variables: a dictionary recording our
/// inventory of books (mapping title to price), and a counter
/// tracking the next order ID to be allocated.
///
/// We mark each property (entry) in the `books` table as a *field* so
/// that dependency-tracking on a per-book basis is enabled. As a result,
/// when a book is sold, any client still interested in its price will
/// learn that the book is no longer available.
///
/// We do not enable dependency-tracking for either the `books` table
/// itself or the `nextOrderId` field: nothing depends on tracking
/// changes in their values.
this.books = {
"The Wind in the Willows": 3.95,
"Catch 22": 2.22,
"Candide": 34.95
};
this.books = {};
field this.books["The Wind in the Willows"] = 3.95;
field this.books["Catch 22"] = 2.22;
field this.books["Candide"] = 34.95;
this.nextOrderId = 10001483;
/// Looking up a price yields `false` if no such book is in our
/// inventory.
this.priceOf = function (title) {
return (title in this.books) && this.books[title];
return (title in this.books) && field this.books[title];
};
/// The seller responds to interest in bookQuotes by asserting a
@ -134,7 +142,7 @@ function seller() {
/// replying to the orderer.
var orderId = this.nextOrderId++;
delete this.books[title];
delete field this.books[title];
actor {
whileRelevantAssert(

View File

@ -92,18 +92,26 @@ We give our actor two state variables: a dictionary recording our
inventory of books (mapping title to price), and a counter
tracking the next order ID to be allocated.
this.books = {
"The Wind in the Willows": 3.95,
"Catch 22": 2.22,
"Candide": 34.95
};
We mark each property (entry) in the `books` table as a *field* so
that dependency-tracking on a per-book basis is enabled. As a result,
when a book is sold, any client still interested in its price will
learn that the book is no longer available.
We do not enable dependency-tracking for either the `books` table
itself or the `nextOrderId` field: nothing depends on tracking
changes in their values.
this.books = {};
field this.books["The Wind in the Willows"] = 3.95;
field this.books["Catch 22"] = 2.22;
field this.books["Candide"] = 34.95;
this.nextOrderId = 10001483;
Looking up a price yields `false` if no such book is in our
inventory.
this.priceOf = function (title) {
return (title in this.books) && this.books[title];
return (title in this.books) && field this.books[title];
};
The seller responds to interest in bookQuotes by asserting a
@ -134,7 +142,7 @@ But if we can sell it, we do so by allocating an order ID and
replying to the orderer.
var orderId = this.nextOrderId++;
delete this.books[title];
delete field this.books[title];
actor {
whileRelevantAssert(