diff --git a/examples/chat-raw/index.html b/examples/chat-raw/index.html
new file mode 100644
index 0000000..b0a816f
--- /dev/null
+++ b/examples/chat-raw/index.html
@@ -0,0 +1,67 @@
+
+
+
+ JS Marketplace: Chat Example
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/chat-raw/index.js b/examples/chat-raw/index.js
new file mode 100644
index 0000000..997ff1c
--- /dev/null
+++ b/examples/chat-raw/index.js
@@ -0,0 +1,162 @@
+var Route = Minimart.Route;
+var World = Minimart.World;
+var sub = Minimart.sub;
+var pub = Minimart.pub;
+var __ = Minimart.__;
+var _$ = Minimart._$;
+
+function chatEvent(nym, status, utterance, stamp) {
+ return ["chatEvent", nym, status, utterance, stamp || +(new Date())];
+}
+function chatEventNym(c) { return c[1]; }
+function chatEventStatus(c) { return c[2]; }
+function chatEventUtterance(c) { return c[3]; }
+function chatEventStamp(c) { return c[4]; }
+
+function outputItem(item) {
+ var stamp = $("").text((new Date()).toGMTString()).addClass("timestamp");
+ var item = $("").append([stamp].concat(item));
+ var o = $("#chat_output");
+ o.append(item);
+ o[0].scrollTop = o[0].scrollHeight;
+ return item;
+}
+
+function updateNymList(g) {
+ var statuses = {};
+ var nymProj = ["broker", 0, ["chatEvent", _$, _$, __, __]];
+ var matchedNyms = Route.matcherKeys(g.project(Route.compileProjection(nymProj), true, 0, 0));
+ for (var i = 0; i < matchedNyms.length; i++) {
+ statuses[matchedNyms[i][0]] = matchedNyms[i][1];
+ }
+ var nyms = [];
+ for (var nym in statuses) { nyms.push(nym); }
+ nyms.sort();
+
+ var container = $("#nymlist");
+ container[0].innerHTML = ""; // remove all children
+ for (var i = 0; i < nyms.length; i++) {
+ var n = $("").text(nyms[i]).addClass("nym");
+ var s = statuses[nyms[i]];
+ if (s) {
+ container.append($("").append([n, $("").text(s).addClass("nym_status")]));
+ } else {
+ container.append($("").append(n));
+ }
+ }
+}
+
+function outputState(state) {
+ outputItem([$("").text(state).addClass(state).addClass("state")])
+ .addClass("state_" + state);
+}
+
+function outputUtterance(who, what) {
+ outputItem([$("").text(who).addClass("nym"),
+ $("").text(what).addClass("utterance")]).addClass("utterance");
+}
+
+var G;
+$(document).ready(function () {
+ $("#chat_form").submit(function (e) { e.preventDefault(); return false; });
+ $("#nym_form").submit(function (e) { e.preventDefault(); return false; });
+ if (!($("#nym").val())) { $("#nym").val("nym" + Math.floor(Math.random() * 65536)); }
+
+ G = new Minimart.Ground(function () {
+ console.log('starting ground boot');
+ // World.spawn(new Spy());
+ Minimart.JQuery.spawnJQueryDriver();
+ Minimart.DOM.spawnDOMDriver();
+ Minimart.RoutingTableWidget.spawnRoutingTableWidget("#spy-holder", "spy");
+
+ World.spawn(new Minimart.WakeDetector());
+ var wsconn = new Minimart.WebSocket.WebSocketConnection("broker", $("#wsurl").val(), true);
+ World.spawn(wsconn);
+ World.spawn({
+ // Monitor connection, notifying connectivity changes
+ state: "crashed", // start with this to avoid spurious initial message print
+ boot: function () {
+ World.updateRoutes([sub(["broker_state", __], 0, 1)]);
+ },
+ handleEvent: function (e) {
+ if (e.type === "routes") {
+ var states =
+ Route.matcherKeys(e.gestalt.project(Route.compileProjection([__, _$]),
+ true, 0, 0));
+ var newState = states.length > 0 ? states[0][0] : "crashed";
+ if (this.state != newState) {
+ outputState(newState);
+ this.state = newState;
+ }
+ }
+ }
+ });
+ World.spawn({
+ // Actual chat functionality
+ boot: function () {
+ World.updateRoutes(this.subscriptions());
+ },
+ nym: function () { return $("#nym").val(); },
+ currentStatus: function () { return $("#status").val(); },
+ subscriptions: function () {
+ return [sub("wake"),
+ sub(["jQuery", "#send_chat", "click", __]),
+ sub(["jQuery", "#nym", "change", __]),
+ sub(["jQuery", "#status", "change", __]),
+ sub(["jQuery", "#wsurl", "change", __]),
+ pub(["broker", 0, chatEvent(this.nym(), this.currentStatus(), __, __)]),
+ sub(["broker", 0, chatEvent(__, __, __, __)], 0, 1)];
+ },
+ handleEvent: function (e) {
+ var self = this;
+ switch (e.type) {
+ case "routes":
+ updateNymList(e.gestalt);
+ break;
+ case "message":
+ if (e.message === "wake") {
+ wsconn.forceclose();
+ return;
+ }
+ switch (e.message[0]) {
+ case "jQuery":
+ switch (e.message[1]) {
+ case "#send_chat":
+ var inp = $("#chat_input");
+ var utterance = inp.val();
+ inp.val("");
+ if (utterance) {
+ World.send(["broker", 0, chatEvent(this.nym(),
+ this.currentStatus(),
+ utterance)]);
+ }
+ break;
+ case "#nym":
+ case "#status":
+ World.updateRoutes(this.subscriptions());
+ break;
+ case "#wsurl":
+ wsconn.forceclose();
+ wsconn.wsurl = $("#wsurl").val();
+ break;
+ default:
+ console.log("Got jquery event from as-yet-unhandled subscription",
+ e.message[2], e.message[3]);
+ }
+ break;
+ case "broker":
+ if (e.message[2][0] === "chatEvent") {
+ outputUtterance(chatEventNym(e.message[2]),
+ chatEventUtterance(e.message[2]));
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ }
+ });
+ });
+ G.startStepping();
+});
diff --git a/examples/chat-raw/style.css b/examples/chat-raw/style.css
new file mode 100644
index 0000000..a19cf9d
--- /dev/null
+++ b/examples/chat-raw/style.css
@@ -0,0 +1,73 @@
+span.timestamp {
+ color: #d0d0d0;
+}
+
+span.timestamp:after {
+ content: " ";
+}
+
+.utterance span.nym:after {
+ content: ": ";
+}
+
+span.arrived:after {
+ content: " arrived";
+}
+
+span.departed:after {
+ content: " departed";
+}
+
+div.notification {
+ background-color: #eeeeff;
+}
+
+span.state.connected, span.arrived {
+ color: #00c000;
+}
+
+span.state.disconnected, span.departed {
+ color: #c00000;
+}
+
+span.state.crashed {
+ color: white;
+ background: red;
+}
+
+span.state.crashed:after {
+ content: "; please reload the page";
+}
+
+div.state_disconnected {
+ background-color: #ffeeee;
+}
+
+div.state_connected {
+ background-color: #eeffee;
+}
+
+#chat_output {
+ height: 15em;
+ overflow-y: scroll;
+}
+
+#chat_input {
+ width: 80%;
+}
+
+.nym {
+ color: #00c000;
+}
+
+.nym_status:before {
+ content: " (";
+}
+
+.nym_status:after {
+ content: ")";
+}
+
+.nym_status {
+ font-size: smaller;
+}
\ No newline at end of file
diff --git a/examples/chat/app-resources/Info.plist b/examples/chat/app-resources/Info.plist
deleted file mode 100644
index 3e42d52..0000000
--- a/examples/chat/app-resources/Info.plist
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- English
- CFBundleExecutable
- boot.sh
- CFBundleIconFile
- app.icns
- CFBundleIdentifier
- com.leastfixedpoint.js-marketplace.chat-demo
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- chat-demo
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- chat-demo 0.0.0
- CFBundleSignature
- ????
- CFBundleVersion
- 0.0.0
- LSMinimumSystemVersion
- 10.6
-
-
diff --git a/examples/chat/app-resources/app.icns b/examples/chat/app-resources/app.icns
deleted file mode 100644
index 4d50fa4..0000000
Binary files a/examples/chat/app-resources/app.icns and /dev/null differ
diff --git a/examples/chat/app-resources/boot.sh b/examples/chat/app-resources/boot.sh
deleted file mode 100644
index 1f69d48..0000000
--- a/examples/chat/app-resources/boot.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-cd "$(dirname "$0")"/../Resources
-open examples/chat/index.html
diff --git a/examples/chat/index.js b/examples/chat/index.js
index 997ff1c..bfa0e2f 100644
--- a/examples/chat/index.js
+++ b/examples/chat/index.js
@@ -1,5 +1,6 @@
var Route = Minimart.Route;
var World = Minimart.World;
+var Actor = Minimart.Actor;
var sub = Minimart.sub;
var pub = Minimart.pub;
var __ = Minimart.__;
@@ -8,10 +9,6 @@ var _$ = Minimart._$;
function chatEvent(nym, status, utterance, stamp) {
return ["chatEvent", nym, status, utterance, stamp || +(new Date())];
}
-function chatEventNym(c) { return c[1]; }
-function chatEventStatus(c) { return c[2]; }
-function chatEventUtterance(c) { return c[3]; }
-function chatEventStamp(c) { return c[4]; }
function outputItem(item) {
var stamp = $("").text((new Date()).toGMTString()).addClass("timestamp");
@@ -22,12 +19,10 @@ function outputItem(item) {
return item;
}
-function updateNymList(g) {
+function updateNymList(allStatuses) {
var statuses = {};
- var nymProj = ["broker", 0, ["chatEvent", _$, _$, __, __]];
- var matchedNyms = Route.matcherKeys(g.project(Route.compileProjection(nymProj), true, 0, 0));
- for (var i = 0; i < matchedNyms.length; i++) {
- statuses[matchedNyms[i][0]] = matchedNyms[i][1];
+ for (var i = 0; i < allStatuses.length; i++) {
+ statuses[allStatuses[i].nym] = allStatuses[i].status;
}
var nyms = [];
for (var nym in statuses) { nyms.push(nym); }
@@ -72,91 +67,71 @@ $(document).ready(function () {
World.spawn(new Minimart.WakeDetector());
var wsconn = new Minimart.WebSocket.WebSocketConnection("broker", $("#wsurl").val(), true);
World.spawn(wsconn);
- World.spawn({
+ World.spawn(new Actor(function () {
// Monitor connection, notifying connectivity changes
- state: "crashed", // start with this to avoid spurious initial message print
- boot: function () {
- World.updateRoutes([sub(["broker_state", __], 0, 1)]);
- },
- handleEvent: function (e) {
- if (e.type === "routes") {
- var states =
- Route.matcherKeys(e.gestalt.project(Route.compileProjection([__, _$]),
- true, 0, 0));
- var newState = states.length > 0 ? states[0][0] : "crashed";
+ this.state = "crashed"; // start with this to avoid spurious initial message print
+
+ Actor.observeAdvertisers(
+ function () { return ["broker_state", _$("newState")]; },
+ { name: "states" },
+ function () {
+ var newState = this.states.length > 0 ? this.states[0].newState : "crashed";
if (this.state != newState) {
outputState(newState);
this.state = newState;
}
- }
- }
- });
- World.spawn({
+ });
+ }));
+ World.spawn(new Actor(function () {
// Actual chat functionality
- boot: function () {
- World.updateRoutes(this.subscriptions());
- },
- nym: function () { return $("#nym").val(); },
- currentStatus: function () { return $("#status").val(); },
- subscriptions: function () {
- return [sub("wake"),
- sub(["jQuery", "#send_chat", "click", __]),
- sub(["jQuery", "#nym", "change", __]),
- sub(["jQuery", "#status", "change", __]),
- sub(["jQuery", "#wsurl", "change", __]),
- pub(["broker", 0, chatEvent(this.nym(), this.currentStatus(), __, __)]),
- sub(["broker", 0, chatEvent(__, __, __, __)], 0, 1)];
- },
- handleEvent: function (e) {
- var self = this;
- switch (e.type) {
- case "routes":
- updateNymList(e.gestalt);
- break;
- case "message":
- if (e.message === "wake") {
- wsconn.forceclose();
- return;
+ this.nym = function () { return $("#nym").val(); };
+ this.currentStatus = function () { return $("#status").val(); };
+
+ Actor.subscribe(
+ function () { return "wake"; },
+ function () { wsconn.forceclose(); });
+
+ Actor.advertise(
+ function () { return ["broker", 0,
+ chatEvent(this.nym(), this.currentStatus(), __, __)]; });
+ Actor.observeAdvertisers(
+ function () { return ["broker", 0,
+ chatEvent(_$("nym"), _$("status"), __, __)]; },
+ { name: "allStatuses" },
+ function () { updateNymList(this.allStatuses); });
+
+ Actor.subscribe(
+ function () { return ["jQuery", "#send_chat", "click", __]; },
+ function () {
+ var inp = $("#chat_input");
+ var utterance = inp.val();
+ inp.val("");
+ if (utterance) {
+ World.send(["broker", 0, chatEvent(this.nym(),
+ this.currentStatus(),
+ utterance)]);
}
- switch (e.message[0]) {
- case "jQuery":
- switch (e.message[1]) {
- case "#send_chat":
- var inp = $("#chat_input");
- var utterance = inp.val();
- inp.val("");
- if (utterance) {
- World.send(["broker", 0, chatEvent(this.nym(),
- this.currentStatus(),
- utterance)]);
- }
- break;
- case "#nym":
- case "#status":
- World.updateRoutes(this.subscriptions());
- break;
- case "#wsurl":
- wsconn.forceclose();
- wsconn.wsurl = $("#wsurl").val();
- break;
- default:
- console.log("Got jquery event from as-yet-unhandled subscription",
- e.message[2], e.message[3]);
- }
- break;
- case "broker":
- if (e.message[2][0] === "chatEvent") {
- outputUtterance(chatEventNym(e.message[2]),
- chatEventUtterance(e.message[2]));
- }
- break;
- default:
- break;
- }
- break;
- }
- }
- });
+ });
+
+ Actor.subscribe(
+ function () { return ["jQuery", "#nym", "change", __]; },
+ function () { this.updateRoutes(); });
+
+ Actor.subscribe(
+ function () { return ["jQuery", "#status", "change", __]; },
+ function () { this.updateRoutes(); });
+
+ Actor.subscribe(
+ function () { return ["jQuery", "#wsurl", "change", __]; },
+ function () {
+ wsconn.forceclose();
+ wsconn.wsurl = $("#wsurl").val();
+ });
+
+ Actor.subscribe(
+ function () { return ["broker", 0, chatEvent(_$("who"), __, _$("what"), __)]; },
+ function (who, what) { outputUtterance(who, what); });
+ }));
});
G.startStepping();
});