diff --git a/package.json b/package.json index 8857434..bb4e764 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "@preserves/schema": "^0.4.0" }, "scripts": { - "regenerate": "rm -rf ./src/gen && preserves-schema-ts --module Actor=./src/actor.ts --module Protocol=./src/protocol.ts --output ./src/gen './schemas/**/*.prs'", + "regenerate": "rm -rf ./src/gen && preserves-schema-ts --module Actor=./src/runtime/actor.ts --module Protocol=./src/transport/protocol.ts --output ./src/gen './schemas/**/*.prs'", "regenerate:watch": "yarn regenerate --watch", "regenerate:bundle": "preserves-schemac './schemas/**/*.prs' > novy-syndicate.schema.bundle.bin", "compile": "tsc", diff --git a/rollup.config.js b/rollup.config.js index dc3a31d..fef517b 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,5 +1,5 @@ export default { - input: 'lib/sturdy-demo.js', + input: 'lib/examples/sturdy-demo.js', output: { file: 'index.js', format: 'umd', diff --git a/schemas/worker.prs b/schemas/worker.prs index a1598f6..2371e5a 100644 --- a/schemas/worker.prs +++ b/schemas/worker.prs @@ -1,3 +1,4 @@ version 1 . +pointer Actor.Ref . Instance = . diff --git a/src/sandbox.ts b/src/distributed/sandbox.ts similarity index 86% rename from src/sandbox.ts rename to src/distributed/sandbox.ts index d28c183..61d866c 100644 --- a/src/sandbox.ts +++ b/src/distributed/sandbox.ts @@ -1,8 +1,8 @@ -import { Actor, Ref, Turn } from "./actor"; -import { Relay, spawnRelay } from "./relay"; -import { sturdyDecode } from "./sturdy"; -import { Resolve, asSturdyRef, fromResolve } from "./gen/sturdy"; -import { during } from "./dataspace"; +import { Actor, Ref, Turn } from "../runtime/actor"; +import { Relay, spawnRelay } from "../transport/relay"; +import { sturdyDecode } from "../transport/sturdy"; +import { Resolve, asSturdyRef, fromResolve } from "../gen/sturdy"; +import { during } from "../runtime/dataspace"; import * as net from 'net'; import { Bytes } from "@preserves/core"; diff --git a/src/server.ts b/src/distributed/server.ts similarity index 87% rename from src/server.ts rename to src/distributed/server.ts index 4bd3eb4..1d9f19b 100644 --- a/src/server.ts +++ b/src/distributed/server.ts @@ -1,13 +1,13 @@ -import { Actor, Handle, Turn } from './actor.js'; -import { Dataspace, during, observe } from './dataspace.js'; -import { Relay, spawnRelay } from './relay.js'; +import { Actor, Handle, Turn } from '../runtime/actor.js'; +import { Dataspace, during, observe } from '../runtime/dataspace.js'; +import { Relay, spawnRelay } from '../transport/relay.js'; import * as net from 'net'; -import { mint, sturdyEncode, validate } from './sturdy.js'; -import { KEY_LENGTH } from './cryptography.js'; -import { attenuate } from './rewrite.js'; +import { mint, sturdyEncode, validate } from '../transport/sturdy.js'; +import { KEY_LENGTH } from '../transport/cryptography.js'; +import { attenuate } from '../runtime/rewrite.js'; import { Bytes, is } from '@preserves/core'; -import { $bind, Attenuation, Bind, fromBind, fromSturdyRef, toBind, toResolve, _val } from './gen/sturdy.js'; +import { $bind, Attenuation, Bind, fromBind, fromSturdyRef, toBind, toResolve, _val } from '../gen/sturdy.js'; new Actor(t => { t.activeFacet.preventInertCheck(); diff --git a/src/box.ts b/src/examples/box.ts similarity index 86% rename from src/box.ts rename to src/examples/box.ts index 8c761a5..b663335 100644 --- a/src/box.ts +++ b/src/examples/box.ts @@ -1,6 +1,6 @@ -import { BoxState, $SetBox, fromBoxState } from "./gen/box-protocol.js"; -import { fromObserve, Observe } from "./gen/dataspace.js"; -import { Assertion, Handle, Ref, Turn } from "./actor.js"; +import { BoxState, $SetBox, fromBoxState } from "../gen/box-protocol.js"; +import { fromObserve, Observe } from "../gen/dataspace.js"; +import { Assertion, Handle, Ref, Turn } from "../runtime/actor.js"; let startTime = Date.now(); let prevValue = 0; diff --git a/src/client.ts b/src/examples/client.ts similarity index 83% rename from src/client.ts rename to src/examples/client.ts index 6559879..c82c418 100644 --- a/src/client.ts +++ b/src/examples/client.ts @@ -1,6 +1,6 @@ -import { $BoxState, fromSetBox, SetBox } from "./gen/box-protocol.js"; -import { fromObserve, Observe } from "./gen/dataspace.js"; -import { Assertion, Ref, Turn } from "./actor.js"; +import { $BoxState, fromSetBox, SetBox } from "../gen/box-protocol.js"; +import { fromObserve, Observe } from "../gen/dataspace.js"; +import { Assertion, Ref, Turn } from "../runtime/actor.js"; export default function (t: Turn, ds: Ref) { console.log('Spawning Client'); diff --git a/src/main.ts b/src/examples/main.ts similarity index 61% rename from src/main.ts rename to src/examples/main.ts index 71b3e56..9d202e5 100644 --- a/src/main.ts +++ b/src/examples/main.ts @@ -1,40 +1,12 @@ -import { Actor, Assertion, Ref, Turn } from './actor.js'; -import { Dictionary, Record } from '@preserves/core'; -import { Dataspace } from './dataspace.js'; -import { Worker } from 'worker_threads'; -import { Relay, spawnRelay } from './relay.js'; +import { Actor, Assertion, Ref, Turn } from '../runtime/actor.js'; +import { Dictionary } from '@preserves/core'; +import { Dataspace } from '../runtime/dataspace.js'; +import { attenuate, CRec, Lit, Pattern, PCompound, rfilter, ConstructorSpec } from '../runtime/rewrite.js'; +import { $BoxState, $SetBox } from '../gen/box-protocol.js'; +import { $Observe } from '../gen/dataspace.js'; +import { spawnWorker } from '../worker/index.js'; import path from 'path'; -import { attenuate, CRec, Lit, Pattern, PCompound, rfilter, ConstructorSpec } from './rewrite.js'; -import { $BoxState, $SetBox } from './gen/box-protocol.js'; -import { $Observe } from './gen/dataspace.js'; - -const Instance = Record.makeConstructor<{moduleName: string, arg: Assertion}>()( - Symbol.for('Instance'), ['moduleName', 'arg']); - -function spawnWorker(t: Turn, moduleName: string, arg: Assertion) { - const w = new Worker(path.join(__dirname, 'wload.js')); - const reenable = t.activeFacet.preventInertCheck(); - spawnRelay(t, { - packetWriter: bs => w.postMessage(bs), - setup(t: Turn, r: Relay) { - w.on('message', bs => r.accept(bs)); - w.on('error', err => Turn.for(t.activeFacet, t => t.crash(err))); - w.on('exit', code => Turn.for(t.activeFacet, t => { - if (code === 0) { - t.stopActor(); - } else { - t.crash(new Error(`Worker crashed with code ${code}`)); - } - })); - }, - initialOid: 0, - }).then(factory => { - reenable(); - new Actor(t => t.assert(factory, Instance(moduleName, arg))); - }); -} - function spawnModule(t: Turn, moduleName: string, arg: Assertion) { import(moduleName).then(m => t.freshen(t => t.spawn(t => m.default(t, arg)))); } diff --git a/src/readline.ts b/src/examples/readline.ts similarity index 91% rename from src/readline.ts rename to src/examples/readline.ts index 2a9c91f..5132d44 100644 --- a/src/readline.ts +++ b/src/examples/readline.ts @@ -1,4 +1,4 @@ -import { Turn, Entity, Facet } from './actor.js'; +import { Turn, Entity, Facet } from '../runtime/actor.js'; import readline from 'readline'; export function attachReadline(t: Turn, entity: Partial): Facet { diff --git a/src/secure-chat-client.ts b/src/examples/secure-chat-client.ts similarity index 91% rename from src/secure-chat-client.ts rename to src/examples/secure-chat-client.ts index 2b0ae5b..34a6f9e 100644 --- a/src/secure-chat-client.ts +++ b/src/examples/secure-chat-client.ts @@ -1,6 +1,6 @@ -import { $joinedUser, $says, $user, asJoin, asSays, asUserInfo, fromNickClaim, fromSays, NickClaim, Says, UserId } from "./gen/secure-chat-protocol.js"; -import { during, observe } from "./dataspace.js"; -import { Assertion, Ref, Turn } from "./actor.js"; +import { $joinedUser, $says, $user, asJoin, asSays, asUserInfo, fromNickClaim, fromSays, NickClaim, Says, UserId } from "../gen/secure-chat-protocol.js"; +import { during, observe } from "../runtime/dataspace.js"; +import { Assertion, Ref, Turn } from "../runtime/actor.js"; import { attachReadline } from './readline.js'; export default function (t: Turn, ds: Ref) { diff --git a/src/secure-chat-moderator.ts b/src/examples/secure-chat-moderator.ts similarity index 91% rename from src/secure-chat-moderator.ts rename to src/examples/secure-chat-moderator.ts index dbf4cf6..bd698b4 100644 --- a/src/secure-chat-moderator.ts +++ b/src/examples/secure-chat-moderator.ts @@ -11,11 +11,11 @@ import { fromJoin, fromNickConflict, fromUserInfo, -} from "./gen/secure-chat-protocol.js"; -import { Assertion, Handle, Ref, Turn } from "./actor.js"; -import { observe, during, $Observe, asObserve, Dataspace } from "./dataspace.js"; -import { attenuate, rfilter, pRec, pPointer, pString, pLit } from "./rewrite.js"; -import { attenuate as sturdyAttenuate, fromBind, Bind, KEY_LENGTH, sturdyEncode, fromSturdyRef, mint } from "./sturdy.js"; +} from "../gen/secure-chat-protocol.js"; +import { Assertion, Handle, Ref, Turn } from "../runtime/actor.js"; +import { observe, during, $Observe, asObserve, Dataspace } from "../runtime/dataspace.js"; +import { attenuate, rfilter, pRec, pPointer, pString, pLit } from "../runtime/rewrite.js"; +import { attenuate as sturdyAttenuate, fromBind, Bind, KEY_LENGTH, sturdyEncode, fromSturdyRef, mint } from "../transport/sturdy.js"; import { Bytes } from "@preserves/core"; export default function (t: Turn, gatekeeperDs: Ref) { diff --git a/src/simple-chat.ts b/src/examples/simple-chat.ts similarity index 83% rename from src/simple-chat.ts rename to src/examples/simple-chat.ts index fae1d1f..96cb193 100644 --- a/src/simple-chat.ts +++ b/src/examples/simple-chat.ts @@ -1,6 +1,6 @@ -import { $Present, $Says, asPresent, asSays, fromPresent, fromSays, Present, Says } from "./gen/simple-chat-protocol.js"; -import { during, observe } from "./dataspace.js"; -import { Assertion, Handle, Ref, Turn } from "./actor.js"; +import { $Present, $Says, asPresent, asSays, fromPresent, fromSays, Present, Says } from "../gen/simple-chat-protocol.js"; +import { during, observe } from "../runtime/dataspace.js"; +import { Assertion, Handle, Ref, Turn } from "../runtime/actor.js"; import { attachReadline } from './readline.js'; export default function (t: Turn, ds: Ref) { @@ -27,7 +27,7 @@ export default function (t: Turn, ds: Ref) { }); attachReadline(t, { - retract(t) { t.stop(); }, + retract(t) { t.stopActor(); }, message(t, line: string) { if (line.toLowerCase().startsWith('/nick ')) { updateUsername(t, line.slice(5).trimLeft()); diff --git a/src/sturdy-demo.ts b/src/examples/sturdy-demo.ts similarity index 89% rename from src/sturdy-demo.ts rename to src/examples/sturdy-demo.ts index 9f26a90..f2fde90 100644 --- a/src/sturdy-demo.ts +++ b/src/examples/sturdy-demo.ts @@ -1,8 +1,8 @@ -import { newKey } from './cryptography.js'; -import { attenuate, KEY_LENGTH, mint, Caveat, Rewrite, sturdyEncode, validate } from './sturdy.js'; -import * as RW from './rewrite.js'; +import { newKey } from '../transport/cryptography.js'; +import { attenuate, KEY_LENGTH, mint, Caveat, Rewrite, sturdyEncode, validate } from '../transport/sturdy.js'; +import * as RW from '../runtime/rewrite.js'; import { Bytes, Dictionary } from '@preserves/core'; -import { Ref } from 'actor.js'; +import { Ref } from '../runtime/actor.js'; async function main() { const m1 = await mint('hello world', new Bytes(KEY_LENGTH)); diff --git a/src/gen/box-protocol.ts b/src/gen/box-protocol.ts index f1c7fd1..21058e2 100644 --- a/src/gen/box-protocol.ts +++ b/src/gen/box-protocol.ts @@ -1,5 +1,5 @@ import * as _ from "@preserves/core"; -import * as _i_Actor from "../actor"; +import * as _i_Actor from "../runtime/actor"; export const $BoxState = Symbol.for("BoxState"); export const $SetBox = Symbol.for("SetBox"); diff --git a/src/gen/dataspace.ts b/src/gen/dataspace.ts index c69f893..f968ad9 100644 --- a/src/gen/dataspace.ts +++ b/src/gen/dataspace.ts @@ -1,5 +1,5 @@ import * as _ from "@preserves/core"; -import * as _i_Actor from "../actor"; +import * as _i_Actor from "../runtime/actor"; export const $Observe = Symbol.for("Observe"); diff --git a/src/gen/protocol.ts b/src/gen/protocol.ts index c140c72..411661a 100644 --- a/src/gen/protocol.ts +++ b/src/gen/protocol.ts @@ -1,5 +1,5 @@ import * as _ from "@preserves/core"; -import * as _i_Protocol from "../protocol"; +import * as _i_Protocol from "../transport/protocol"; export const $assert = Symbol.for("assert"); export const $message = Symbol.for("message"); diff --git a/src/gen/secure-chat-protocol.ts b/src/gen/secure-chat-protocol.ts index cb59a8e..90987b7 100644 --- a/src/gen/secure-chat-protocol.ts +++ b/src/gen/secure-chat-protocol.ts @@ -1,5 +1,5 @@ import * as _ from "@preserves/core"; -import * as _i_Actor from "../actor"; +import * as _i_Actor from "../runtime/actor"; export const $claimNick = Symbol.for("claimNick"); export const $joinedUser = Symbol.for("joinedUser"); diff --git a/src/gen/simple-chat-protocol.ts b/src/gen/simple-chat-protocol.ts index fce0b36..c2ae0eb 100644 --- a/src/gen/simple-chat-protocol.ts +++ b/src/gen/simple-chat-protocol.ts @@ -1,5 +1,5 @@ import * as _ from "@preserves/core"; -import * as _i_Actor from "../actor"; +import * as _i_Actor from "../runtime/actor"; export const $Present = Symbol.for("Present"); export const $Says = Symbol.for("Says"); diff --git a/src/gen/sturdy.ts b/src/gen/sturdy.ts index 946d224..d52c31a 100644 --- a/src/gen/sturdy.ts +++ b/src/gen/sturdy.ts @@ -1,5 +1,5 @@ import * as _ from "@preserves/core"; -import * as _i_Actor from "../actor"; +import * as _i_Actor from "../runtime/actor"; export const $Boolean = Symbol.for("Boolean"); export const $ByteString = Symbol.for("ByteString"); diff --git a/src/gen/worker.ts b/src/gen/worker.ts index 5517bc6..2c41c2c 100644 --- a/src/gen/worker.ts +++ b/src/gen/worker.ts @@ -1,15 +1,16 @@ import * as _ from "@preserves/core"; +import * as _i_Actor from "../runtime/actor"; export const $Instance = Symbol.for("Instance"); -export type _ptr = never; +export type _ptr = _i_Actor.Ref; export type _val = _.Value<_ptr>; export type Instance = {"name": string, "argument": _val}; -export const _toPtr = () => { throw new _.DecodeError("Pointers forbidden"); }; +export const _toPtr = (v: _val) => {let result: undefined | _ptr; result = _i_Actor.toRef(v); return result;}; export function Instance({name, argument}: {name: string, argument: _val}): Instance {return {"name": name, "argument": argument};} diff --git a/src/actor.ts b/src/runtime/actor.ts similarity index 100% rename from src/actor.ts rename to src/runtime/actor.ts diff --git a/src/bag.ts b/src/runtime/bag.ts similarity index 100% rename from src/bag.ts rename to src/runtime/bag.ts diff --git a/src/dataspace.ts b/src/runtime/dataspace.ts similarity index 97% rename from src/dataspace.ts rename to src/runtime/dataspace.ts index e02a620..c3fe240 100644 --- a/src/dataspace.ts +++ b/src/runtime/dataspace.ts @@ -1,9 +1,9 @@ -import { Assertion, Entity, Handle, LocalAction, Ref, Turn } from 'actor'; +import { Assertion, Entity, Handle, LocalAction, Ref, Turn } from 'runtime/actor'; import { Dictionary, IdentityMap, is, Record, Tuple } from '@preserves/core'; import { Bag, ChangeDescription } from './bag'; -import { fromObserve, toObserve, Observe } from './gen/dataspace'; -export * from './gen/dataspace'; +import { fromObserve, toObserve, Observe } from '../gen/dataspace'; +export * from '../gen/dataspace'; // Q. Why keep "Observe"? Why not do the clever trick of asserting the // observer, and having the dataspace read the implicit pattern it's diff --git a/src/rewrite.ts b/src/runtime/rewrite.ts similarity index 99% rename from src/rewrite.ts rename to src/runtime/rewrite.ts index 6f802b0..5a7ed03 100644 --- a/src/rewrite.ts +++ b/src/runtime/rewrite.ts @@ -23,8 +23,8 @@ import { TRef, Template, _val, -} from './gen/sturdy.js'; -export * from './gen/sturdy.js'; +} from '../gen/sturdy.js'; +export * from '../gen/sturdy.js'; export type Bindings = { [name: string]: Assertion }; diff --git a/src/task.ts b/src/runtime/task.ts similarity index 100% rename from src/task.ts rename to src/runtime/task.ts diff --git a/src/tools/attenuate.ts b/src/tools/attenuate.ts index f98f75b..9e4da42 100644 --- a/src/tools/attenuate.ts +++ b/src/tools/attenuate.ts @@ -1,5 +1,5 @@ import { Bytes, Reader } from '@preserves/core'; -import { fromSturdyRef, toSturdyRef, toCaveat, attenuate, sturdyDecode, sturdyEncode } from '../sturdy.js'; +import { fromSturdyRef, toSturdyRef, toCaveat, attenuate, sturdyDecode, sturdyEncode } from '../transport/sturdy.js'; const [ base, pat ] = process.argv.slice(2); const baseCap = toSturdyRef(sturdyDecode(Bytes.fromHex(base ?? ''))); diff --git a/src/cryptography.ts b/src/transport/cryptography.ts similarity index 100% rename from src/cryptography.ts rename to src/transport/cryptography.ts diff --git a/src/protocol.ts b/src/transport/protocol.ts similarity index 88% rename from src/protocol.ts rename to src/transport/protocol.ts index 2d81a30..15f0558 100644 --- a/src/protocol.ts +++ b/src/transport/protocol.ts @@ -1,6 +1,6 @@ -import { Attenuation, toAttenuation } from './gen/sturdy.js'; -import * as IO from './gen/protocol.js'; -import { Assertion, Ref } from './actor.js'; +import { Attenuation, toAttenuation } from '../gen/sturdy.js'; +import * as IO from '../gen/protocol.js'; +import { Assertion, Ref } from '../runtime/actor.js'; import { mapPointers } from '@preserves/core'; import { pointerNotAllowed } from './sturdy.js'; diff --git a/src/relay.ts b/src/transport/relay.ts similarity index 98% rename from src/relay.ts rename to src/transport/relay.ts index c0088c8..44551cd 100644 --- a/src/relay.ts +++ b/src/transport/relay.ts @@ -1,10 +1,10 @@ -import { Actor, Assertion, Entity, Facet, Handle, Ref, Turn } from './actor.js'; +import { Actor, Assertion, Entity, Facet, Handle, Ref, Turn } from '../runtime/actor.js'; import { BytesLike, canonicalString, Decoder, encode, FlexMap, IdentityMap, mapPointers, underlying, Value } from '@preserves/core'; -import * as IO from './gen/protocol.js'; +import * as IO from '../gen/protocol.js'; import { myRef, toWireRef, WireRef, WireSymbol, yourRef } from './protocol.js'; -import { queueTask } from './task.js'; -import { attenuate } from './rewrite.js'; -import { Attenuation, fromAttenuation } from './gen/sturdy.js'; +import { queueTask } from '../runtime/task.js'; +import { attenuate } from '../runtime/rewrite.js'; +import { Attenuation, fromAttenuation } from '../gen/sturdy.js'; import { pointerNotAllowed } from './sturdy.js'; export class SyncPeerEntity implements Entity { diff --git a/src/sturdy.ts b/src/transport/sturdy.ts similarity index 96% rename from src/sturdy.ts rename to src/transport/sturdy.ts index e0867b1..5a3eb4c 100644 --- a/src/sturdy.ts +++ b/src/transport/sturdy.ts @@ -8,8 +8,8 @@ import { mac } from './cryptography.js'; import { Bytes, decode, encode, is } from '@preserves/core'; -import * as S from './gen/sturdy.js'; -export * from './gen/sturdy.js'; +import * as S from '../gen/sturdy.js'; +export * from '../gen/sturdy.js'; export type SturdyValue = S._val; diff --git a/src/worker/index.ts b/src/worker/index.ts new file mode 100644 index 0000000..a88a655 --- /dev/null +++ b/src/worker/index.ts @@ -0,0 +1,31 @@ +import { Actor, Assertion, Turn } from '../runtime/actor.js'; +import { Relay, spawnRelay } from '../transport/relay.js'; +import { Worker } from 'worker_threads'; +import { fromInstance, Instance } from '../gen/worker.js'; +import path from 'path'; + +export function spawnWorker(t: Turn, moduleName: string, arg: Assertion) { + const w = new Worker(path.join(__dirname, 'wload.js')); + const reenable = t.activeFacet.preventInertCheck(); + spawnRelay(t, { + packetWriter: bs => w.postMessage(bs), + setup(t: Turn, r: Relay) { + w.on('message', bs => r.accept(bs)); + w.on('error', err => Turn.for(t.activeFacet, t => t.crash(err))); + w.on('exit', code => Turn.for(t.activeFacet, t => { + if (code === 0) { + t.stopActor(); + } else { + t.crash(new Error(`Worker crashed with code ${code}`)); + } + })); + }, + initialOid: 0, + }).then(factory => { + reenable(); + new Actor(t => t.assert(factory, fromInstance(Instance({ + name: moduleName, + argument: arg, + })))); + }); +} diff --git a/src/wload.ts b/src/worker/wload.ts similarity index 96% rename from src/wload.ts rename to src/worker/wload.ts index 49be4d5..80e2d73 100644 --- a/src/wload.ts +++ b/src/worker/wload.ts @@ -1,9 +1,9 @@ // Web Worker loader -import { Actor, Turn, Assertion, Ref, __setNextActorId } from './actor.js'; +import { Actor, Turn, Assertion, Ref, __setNextActorId } from '../runtime/actor.js'; import { Record } from '@preserves/core'; import { parentPort, threadId } from 'worker_threads'; -import { Relay, spawnRelay } from './relay.js'; +import { Relay, spawnRelay } from '../transport/relay.js'; const _Instance = Symbol.for('Instance'); const Instance = Record.makeConstructor<{moduleName: string, arg: Assertion}>()(