You have no outstanding requests waiting for responses from others.
3 |
13 |
14 |
15 |
16 |
17 | {{#showRequestsFromOthers}}
18 |
19 |
All requests from others
20 |
21 |
22 | {{/showRequestsFromOthers}}
23 |
24 |
--------------------------------------------------------------------------------
/examples/webchat/htdocs/templates/permission-entry.html:
--------------------------------------------------------------------------------
1 |
2 | {{#postInfo.isDraft}}
{{/postInfo.isDraft}}
3 |
4 |
5 |
--------------------------------------------------------------------------------
/examples/webchat/server/.gitignore:
--------------------------------------------------------------------------------
1 | testing.rktd
2 | compiled/main_rkt.*
3 |
--------------------------------------------------------------------------------
/examples/webchat/server/account.rkt:
--------------------------------------------------------------------------------
1 | #lang syndicate
2 |
3 | (require racket/set)
4 |
5 | (require/activate syndicate/reload)
6 | (require/activate syndicate/supervise)
7 |
8 | (require "protocol.rkt")
9 | (require "duplicate.rkt")
10 |
11 | (spawn #:name 'account-manager
12 | (stop-when-reloaded)
13 | (define/query-set accounts (account $e) e)
14 | (on (asserted (session $email _))
15 | (when (not (set-member? (accounts) email))
16 | (send! (create-resource (account email))))))
17 |
18 | (spawn #:name 'account-factory
19 | (stop-when-reloaded)
20 | (on (message (create-resource ($ a (account $email))))
21 | (spawn #:name (list 'account email)
22 | (on-start (log-info "Account ~s created." email))
23 | (on-stop (log-info "Account ~s deleted." email))
24 | (assert a)
25 | (assert (grant email email email (p:follow email) #t))
26 | (stop-when-duplicate a)
27 | (stop-when (message (delete-resource a))))))
28 |
--------------------------------------------------------------------------------
/examples/webchat/server/duplicate.rkt:
--------------------------------------------------------------------------------
1 | #lang syndicate
2 |
3 | (provide stop-when-duplicate)
4 |
5 | (require syndicate/protocol/instance)
6 | (require "util.rkt")
7 |
8 | (define (stop-when-duplicate spec)
9 | (define id (random-hex-string 16))
10 | (assert (instance id spec))
11 | (on (asserted (instance $id2 spec))
12 | (when (string id id2)
13 | (log-info "Duplicate instance of ~v detected; terminating" spec)
14 | (stop-current-facet)))
15 | id)
16 |
--------------------------------------------------------------------------------
/examples/webchat/server/main.rkt:
--------------------------------------------------------------------------------
1 | #lang syndicate
2 |
3 | (require/activate syndicate/reload)
4 |
5 | (spawn-reloader "config.rkt")
6 | (spawn-reloader "trust.rkt")
7 | (spawn-reloader "api.rkt")
8 | (spawn-reloader "script-compiler.rkt")
9 | (spawn-reloader "static-content.rkt")
10 | (spawn-reloader "account.rkt")
11 | (spawn-reloader "pages.rkt")
12 | (spawn-reloader "qa.rkt")
13 | (spawn-reloader "contacts.rkt")
14 | (spawn-reloader "conversation.rkt")
15 |
--------------------------------------------------------------------------------
/examples/webchat/server/run:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | SYNDICATE_TRACE=${SYNDICATE_TRACE:-_}
3 | SYNDICATE_STDOUT_TO_STDERR=y
4 | export SYNDICATE_TRACE SYNDICATE_STDOUT_TO_STDERR
5 | exec racketmake main.rkt -f testing.rktd 2>&1 | tai64n | tai64nlocal
6 |
--------------------------------------------------------------------------------
/examples/webchat/server/script-compiler.rkt:
--------------------------------------------------------------------------------
1 | #lang syndicate
2 |
3 | (require racket/file)
4 | (require racket/port)
5 | (require racket/system)
6 |
7 | (require/activate syndicate/reload)
8 | (require/activate syndicate/drivers/filesystem)
9 | (require/activate syndicate/drivers/web)
10 |
11 | (spawn #:name 'script-compiler
12 | (stop-when-reloaded)
13 | (define source-filename "../htdocs/webchat.syndicate.js")
14 | (define target-filename "webchat.js")
15 | (during/spawn (file-content source-filename file->bytes $bs)
16 | #:name (list 'compiled source-filename)
17 | (define compiled (with-output-to-bytes
18 | (lambda () (system* "../../../js/bin/syndicatec" source-filename))))
19 | (log-info "Finished compiling ~s" target-filename)
20 | (on (web-request-get (id req) _ (,target-filename ()))
21 | (web-respond/bytes! id
22 | #:header (web-response-header
23 | #:headers (list (cons 'content-type
24 | "application/javascript")))
25 | compiled))))
26 |
--------------------------------------------------------------------------------
/examples/webchat/server/testdata.rkt:
--------------------------------------------------------------------------------
1 | #lang syndicate
2 |
3 | (require "protocol.rkt")
4 |
5 | (send! (create-resource (account "tonyg@ccs.neu.edu")))
6 | (send! (create-resource (account "me@here")))
7 | (send! (create-resource (account "also@here")))
8 |
9 | (define (follow! A B)
10 | (send! (create-resource (grant A A B (p:follow A) #f)))
11 | (send! (create-resource (grant B B A (p:follow B) #f))))
12 |
13 | (follow! "tonyg@ccs.neu.edu" "me@here")
14 | (follow! "also@here" "me@here")
15 | (follow! "tonyg@ccs.neu.edu" "also@here")
16 |
17 | (define (make-conversation! cid title creator . other-members)
18 | (send! (create-resource (conversation cid title creator "")))
19 | (for [(who (in-list (cons creator other-members)))]
20 | (send! (create-resource (in-conversation cid who)))))
21 |
22 | (make-conversation! "test" "Test Conversation" "tonyg@ccs.neu.edu" "me@here")
23 | (make-conversation! "grouptest" "Group Conversation" "also@here" "me@here" "tonyg@ccs.neu.edu")
24 |
--------------------------------------------------------------------------------
/examples/webchat/server/util.rkt:
--------------------------------------------------------------------------------
1 | #lang racket/base
2 |
3 | (provide random-hex-string)
4 |
5 | (require (only-in file/sha1 bytes->hex-string))
6 | (require (only-in racket/random crypto-random-bytes))
7 |
8 | (define (random-hex-string half-length)
9 | (bytes->hex-string (crypto-random-bytes half-length)))
10 |
--------------------------------------------------------------------------------
/historical/README.md:
--------------------------------------------------------------------------------
1 | # Historical implementations of Syndicate and its predecessors
2 |
3 | - `syndicate-monolithic` is an implementation of the "monolithic
4 | state change notification" dialect of Syndicate for Racket.
5 |
--------------------------------------------------------------------------------
/historical/syndicate-monolithic/README.md:
--------------------------------------------------------------------------------
1 | # syndicate-monolithic
2 |
3 | This is an implementation of the monolithic semantics, without any use
4 | of patches.
5 |
--------------------------------------------------------------------------------
/historical/syndicate-monolithic/examples/.gitignore:
--------------------------------------------------------------------------------
1 | private-key.pem
2 | server-cert.pem
3 |
--------------------------------------------------------------------------------
/historical/syndicate-monolithic/examples/Makefile:
--------------------------------------------------------------------------------
1 | keys: private-key.pem server-cert.pem
2 |
3 | private-key.pem:
4 | openssl genrsa -des3 -passout pass:a -out $@ 1024
5 | openssl rsa -passin pass:a -in $@ -out $@
6 |
7 | server-cert.pem: private-key.pem
8 | openssl req -new -x509 -nodes -sha1 -days 365 \
9 | -subj /CN=example.racket-rfc6455.leastfixedpoint.com \
10 | -passin pass:a \
11 | -key private-key.pem > $@
12 |
13 | clean-keys:
14 | rm -f private-key.pem server-cert.pem
15 |
--------------------------------------------------------------------------------
/historical/syndicate-monolithic/examples/bank-account.rkt:
--------------------------------------------------------------------------------
1 | #lang syndicate-monolithic
2 | ;; Hello-worldish "bank account" example.
3 |
4 | (struct account (balance) #:prefab)
5 | (struct deposit (amount) #:prefab)
6 |
7 | (define (manager e balance)
8 | (match e
9 | [(message (deposit amount))
10 | (transition (+ balance amount)
11 | (scn (assertion (account (+ balance amount)))))]
12 | [_ #f]))
13 |
14 | (define (observer e _)
15 | (when (scn? e)
16 | (for [(balance (project-assertions (scn-trie e) (account (?!))))]
17 | (printf "Balance changed to ~a\n" balance)))
18 | #f)
19 |
20 | (define (updater e _)
21 | (if (and (scn? e) (trie-non-empty? (scn-trie e)))
22 | (quit (list (message (deposit +100))
23 | (message (deposit -30))))
24 | #f))
25 |
26 | (spawn manager 0 (scn/union (assertion (observe (deposit ?))) (assertion (account 0))))
27 | (spawn observer (void) (scn (assertion (observe (account ?)))))
28 | (spawn updater (void) (scn (assertion (observe (observe (deposit ?))))))
29 |
--------------------------------------------------------------------------------
/historical/syndicate-monolithic/examples/box-and-client.rkt:
--------------------------------------------------------------------------------
1 | #lang syndicate-monolithic
2 | ;; Simple mutable box and count-to-infinity box client.
3 |
4 | (struct set-box (new-value) #:transparent)
5 | (struct box-state (value) #:transparent)
6 |
7 | (spawn (lambda (e current-value)
8 | (match e
9 | [(message (set-box new-value))
10 | (log-info "box: taking on new-value ~v" new-value)
11 | (transition new-value (scn/union (subscription (set-box ?))
12 | (assertion (box-state new-value))))]
13 | [_ #f]))
14 | 0
15 | (scn/union (subscription (set-box ?))
16 | (assertion (box-state 0))))
17 |
18 | (spawn (lambda (e s)
19 | (match e
20 | [(scn assertions)
21 | (transition s (for/list [(v (project-assertions assertions (box-state (?!))))]
22 | (log-info "client: learned that box's value is now ~v" v)
23 | (message (set-box (+ v 1)))))]
24 | [_ #f]))
25 | (void)
26 | (scn (subscription (box-state ?))))
27 |
--------------------------------------------------------------------------------
/historical/syndicate-monolithic/examples/example-layer.rkt:
--------------------------------------------------------------------------------
1 | #lang syndicate-monolithic
2 | ;; Check that nested-world assertions are properly retracted.
3 | ;; Should print two "Got SCN:" tries - one nonempty, and one empty.
4 |
5 | #;(spawn (lambda (e s)
6 | (match e
7 | [(message 'die) (quit)]
8 | [_ #f]))
9 | (void)
10 | (scn/union
11 | (subscription 'die)
12 | (subscription (observe 'die))))
13 |
14 | (spawn-dataspace
15 | (spawn (lambda (e s)
16 | (match e
17 | [(message (at-meta 'die)) (quit)]
18 | [_ #f]))
19 | (void)
20 | (scn/union
21 | (subscription 'die #:meta-level 1)
22 | (subscription (observe 'die) #:meta-level 1))))
23 |
24 | (spawn (lambda (e s)
25 | (match e
26 | [(scn g)
27 | (printf "Got SCN:\n")
28 | (pretty-print-trie g)
29 | (transition s (if (trie-non-empty? g)
30 | (message 'die)
31 | '()))]
32 | [_ #f]))
33 | (void)
34 | (scn (subscription (observe 'die))))
35 |
--------------------------------------------------------------------------------
/historical/syndicate-monolithic/examples/example-meta-echo2.rkt:
--------------------------------------------------------------------------------
1 | #lang syndicate-monolithic
2 | ;; The actor should receive a single event adding the (at-meta x) assertion.
3 |
4 | (require syndicate/pretty)
5 |
6 | (spawn-dataspace
7 | (spawn (lambda (e counter)
8 | (and e
9 | (let ((new-counter (+ counter 1)))
10 | (printf "Received event ~a:\n~a\n" new-counter (syndicate-pretty-print->string e))
11 | (transition (+ counter 1) '()))))
12 | 0
13 | (list (scn/union (assertion (at-meta 'x))
14 | (subscription 'x #:meta-level 1)))))
15 |
--------------------------------------------------------------------------------
/historical/syndicate-monolithic/examples/mini-echo.rkt:
--------------------------------------------------------------------------------
1 | #lang syndicate-monolithic
2 |
3 | (struct echo-req (body) #:prefab)
4 | (struct echo-resp (body) #:prefab)
5 |
6 | (spawn (lambda (e count)
7 | (match e
8 | [(message (echo-req body))
9 | (transition (+ count 1)
10 | (message (echo-resp body)))]
11 | [_ #f]))
12 | 0
13 | (scn (subscription (echo-req ?))))
14 |
15 | (spawn (lambda (e s)
16 | (match e
17 | [(message (echo-resp body))
18 | (printf "Received: ~v\n" body)
19 | #f]
20 | [_ #f]))
21 | (void)
22 | (list (scn (subscription (echo-resp ?)))
23 | (message (echo-req 0))
24 | (message (echo-req 1))
25 | (message (echo-req 2))))
26 |
--------------------------------------------------------------------------------
/historical/syndicate-monolithic/examples/udp-hello-plain.rkt:
--------------------------------------------------------------------------------
1 | #lang syndicate-monolithic
2 |
3 | (require "../drivers/udp.rkt")
4 |
5 | (spawn-udp-driver)
6 |
7 | (spawn (lambda (e s)
8 | (match e
9 | [(message (udp-packet src dst #"quit\n"))
10 | (log-info "Got quit request")
11 | (quit (message (udp-packet dst src #"Goodbye!\n")))]
12 | [(message (udp-packet src dst body))
13 | (log-info "Got packet from ~v: ~v" src body)
14 | (define reply (string->bytes/utf-8 (format "You said: ~a" body)))
15 | (transition s (message (udp-packet dst src reply)))]
16 | [_ #f]))
17 | (void)
18 | (scn (subscription (udp-packet ? (udp-listener 5999) ?))))
19 |
--------------------------------------------------------------------------------
/historical/syndicate-monolithic/lang/reader.rkt:
--------------------------------------------------------------------------------
1 | #lang s-exp syntax/module-reader
2 | syndicate-monolithic/lang
3 |
--------------------------------------------------------------------------------
/historical/syndicate-monolithic/main.rkt:
--------------------------------------------------------------------------------
1 | #lang racket/base
2 |
3 | (require "core.rkt")
4 | (require "ground.rkt")
5 |
6 | (provide (all-from-out "core.rkt")
7 | (all-from-out "ground.rkt"))
8 |
--------------------------------------------------------------------------------
/hs/.gitignore:
--------------------------------------------------------------------------------
1 | dist/
2 |
--------------------------------------------------------------------------------
/hs/Setup.hs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env runhaskell
2 | import Distribution.Simple
3 | main = defaultMain
4 |
--------------------------------------------------------------------------------
/hs/test/Main.hs:
--------------------------------------------------------------------------------
1 | {-# LANGUAGE FlexibleInstances #-}
2 | module Main where
3 |
4 | import Test.Framework
5 | import Test.Framework.Providers.HUnit
6 | import Test.Framework.Providers.QuickCheck2
7 |
8 | import Syndicate.Dataspace.Trie.Tests.ESOP2016 as ESOP2016
9 | import Syndicate.Dataspace.Trie.Tests.ESOP2016v2 as ESOP2016v2
10 | import Syndicate.Dataspace.Trie.Tests.ESOP2016v3 as ESOP2016v3
11 | import Syndicate.Dataspace.Trie.Tests.Prefix as Prefix
12 |
13 | testOpts = (mempty :: TestOptions)
14 | { topt_maximum_generated_tests = Just 1000
15 | , topt_maximum_unsuitable_generated_tests = Just 10000
16 | }
17 | runnerOpts = (mempty :: RunnerOptions) { ropt_test_options = Just testOpts }
18 | runTests tests = defaultMainWithOpts tests runnerOpts
19 |
20 | main = runTests
21 | [ testGroup "ESOP2016" $ hUnitTestToTests ESOP2016.hUnitSuite
22 | , testGroup "ESOP2016v2" $ hUnitTestToTests ESOP2016v2.hUnitSuite
23 | , testGroup "ESOP2016v3" $ hUnitTestToTests ESOP2016v3.hUnitSuite
24 | , testGroup "Prefix" [ testGroup "HUnit tests" $ hUnitTestToTests Prefix.hUnitSuite
25 | , testGroup "QuickCheck tests" Prefix.quickCheckSuite
26 | ]
27 | ]
28 |
--------------------------------------------------------------------------------
/js/.gitignore:
--------------------------------------------------------------------------------
1 | scratch/
2 | node_modules/
3 |
--------------------------------------------------------------------------------
/js/bin/syndicatec:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | // -*- javascript -*-
3 |
4 | var fs = require('fs');
5 | var compiler = require('../compiler/compiler.js');
6 |
7 | function compileAndPrint(inputSource) {
8 | var translatedSource = compiler.compileSyndicateSource(inputSource);
9 | if (translatedSource) {
10 | console.log(translatedSource);
11 | } else {
12 | process.exit(1);
13 | }
14 | }
15 |
16 | if (process.argv.length < 3 || process.argv[2] === '-') {
17 | var inputSource = '';
18 | process.stdin.resume();
19 | process.stdin.setEncoding('utf8');
20 | process.stdin.on('data', function(buf) { inputSource += buf; });
21 | process.stdin.on('end', function() { compileAndPrint(inputSource); });
22 | } else {
23 | var inputSource = fs.readFileSync(process.argv[2]).toString();
24 | compileAndPrint(inputSource);
25 | }
26 |
--------------------------------------------------------------------------------
/js/compiler/README.md:
--------------------------------------------------------------------------------
1 | # Syndicate/js compiler
2 |
3 | Translates ES5 + Syndicate extensions to plain ES5 using
4 | [Ohm](https://github.com/cdglabs/ohm#readme).
5 |
--------------------------------------------------------------------------------
/js/compiler/demo-bankaccount.js:
--------------------------------------------------------------------------------
1 | // bin/syndicatec compiler/demo-bankaccount.js | node
2 |
3 | var Syndicate = require('./src/main.js');
4 |
5 | assertion type account(balance);
6 | message type deposit(amount);
7 |
8 | ground dataspace {
9 | spawn {
10 | field this.balance = 0;
11 | assert account(this.balance);
12 | dataflow {
13 | console.log("Balance inside account is", this.balance);
14 | }
15 | on message deposit($amount) {
16 | this.balance += amount;
17 | }
18 | }
19 |
20 | spawn {
21 | on asserted account($balance) {
22 | console.log("Balance is now", balance);
23 | }
24 | }
25 |
26 | spawn {
27 | on start {
28 | console.log("Waiting for account.");
29 | }
30 | stop on asserted Syndicate.observe(deposit(_)) {
31 | console.log("Account became ready.");
32 | :: deposit(+100);
33 | :: deposit(-30);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/js/compiler/demo-during-criterion-snapshotting.js:
--------------------------------------------------------------------------------
1 | // Illustrates a (now fixed) bug where mutation altering a
2 | // subscription caused the `retracted` half of a during instance to be
3 | // lost.
4 | //
5 | // Symptomatic output:
6 | // x= 123 v= 999
7 | // x= 124 v= 999
8 | //
9 | // Correct output:
10 | // x= 123 v= 999
11 | // finally for x= 124 v= 999
12 | // x= 124 v= 999
13 | //
14 | // Should eventually be turned into some kind of test case.
15 |
16 | var Syndicate = require('./src/main.js');
17 | var Dataspace = Syndicate.Dataspace;
18 |
19 | assertion type foo(x, y);
20 |
21 | ground dataspace {
22 | spawn {
23 | field this.x = 123;
24 |
25 | assert foo(this.x, 999);
26 |
27 | during foo(this.x, $v) {
28 | on start {
29 | console.log('x=', this.x, 'v=', v);
30 | if (this.x === 123) {
31 | this.x = 124;
32 | }
33 | }
34 | on stop {
35 | console.log('finally for x=', this.x, 'v=', v);
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/js/dist/README.md:
--------------------------------------------------------------------------------
1 | Directory for build products, checked in to the repo for ease-of-use.
2 |
--------------------------------------------------------------------------------
/js/examples/button/.gitignore:
--------------------------------------------------------------------------------
1 | *.expanded.js
2 |
--------------------------------------------------------------------------------
/js/examples/button/Makefile:
--------------------------------------------------------------------------------
1 | all: index.expanded.js
2 |
3 | %.expanded.js: %.js
4 | ../../bin/syndicatec $< > $@ || (rm -f $@; false)
5 |
6 | clean:
7 | rm -f *.expanded.js
8 |
--------------------------------------------------------------------------------
/js/examples/button/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |