Compare commits
30 Commits
@syndicate
...
main
Author | SHA1 | Date |
---|---|---|
Tony Garnock-Jones | d9fe78edf7 | |
Tony Garnock-Jones | 8fcea8362c | |
Tony Garnock-Jones | 4292c5f40f | |
Tony Garnock-Jones | a0ba43cfae | |
Tony Garnock-Jones | c59506fe0e | |
Tony Garnock-Jones | ffea85ece9 | |
Tony Garnock-Jones | 4c3eaeff1c | |
Tony Garnock-Jones | 830652d71c | |
Tony Garnock-Jones | d008cc3f94 | |
Tony Garnock-Jones | 333f743114 | |
Tony Garnock-Jones | 9c85ac5a85 | |
Tony Garnock-Jones | 248d22a3ef | |
Tony Garnock-Jones | 7a34dc9716 | |
Tony Garnock-Jones | 63ae985d83 | |
Tony Garnock-Jones | 4c5c93820b | |
Tony Garnock-Jones | ff1b013d66 | |
Tony Garnock-Jones | 25c701cd4e | |
Tony Garnock-Jones | 300c4046f8 | |
Tony Garnock-Jones | 81696a90b4 | |
Tony Garnock-Jones | d14ddc39f7 | |
Tony Garnock-Jones | 1e08230027 | |
Tony Garnock-Jones | 27c1c08bb6 | |
Tony Garnock-Jones | c7bb1035a6 | |
Tony Garnock-Jones | c8741c9c36 | |
Tony Garnock-Jones | df692507d9 | |
Tony Garnock-Jones | 3141582223 | |
Tony Garnock-Jones | 599b4ed469 | |
Tony Garnock-Jones | b4b5f5b111 | |
Tony Garnock-Jones | 6e555c9fd5 | |
Emery Hemingway | 8ebde104ca |
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@syndicate-lang/browser-stdenv",
|
||||
"version": "0.35.1",
|
||||
"version": "0.35.9",
|
||||
"description": "Aggregated Syndicate and Preserves scripts for in-browser use",
|
||||
"homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/browser-stdenv",
|
||||
"license": "GPL-3.0+",
|
||||
|
@ -22,9 +22,9 @@
|
|||
"dependencies": {
|
||||
"@preserves/core": "^0.995.200",
|
||||
"@preserves/schema": "^0.995.201",
|
||||
"@syndicate-lang/compiler": "^0.22.0",
|
||||
"@syndicate-lang/core": "^0.34.1",
|
||||
"@syndicate-lang/html2": "^0.35.1",
|
||||
"@syndicate-lang/ws-relay": "^0.36.1"
|
||||
"@syndicate-lang/compiler": "^0.22.3",
|
||||
"@syndicate-lang/core": "^0.34.8",
|
||||
"@syndicate-lang/html2": "^0.35.9",
|
||||
"@syndicate-lang/ws-relay": "^0.36.8"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@syndicate-lang/compiler",
|
||||
"version": "0.22.0",
|
||||
"version": "0.22.3",
|
||||
"description": "Syndicate/JS compiler library",
|
||||
"homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/compiler",
|
||||
"license": "GPL-3.0+",
|
||||
|
|
|
@ -29,7 +29,7 @@ export function stripShebang(items: Items): Items {
|
|||
return items;
|
||||
}
|
||||
|
||||
export type ModuleType ='es6' | 'require' | 'global' | 'none';
|
||||
export type ModuleType = 'es6' | 'require' | 'global' | 'none';
|
||||
|
||||
export type ErrorSink = (message: string, start: Pos | undefined, end: Pos | undefined) => void;
|
||||
|
||||
|
@ -194,10 +194,10 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(t)), '\n')}
|
|||
))
|
||||
})`;
|
||||
if (s.test === void 0) {
|
||||
return t`assertDataflow(() => ({ target: currentSyndicateTarget, assertion: ${assertion} }));`;
|
||||
return t`assertDataflow(() => ({ target: currentSyndicateTarget(), assertion: ${assertion} }));`;
|
||||
} else {
|
||||
return t`assertDataflow(() => (${walk(s.test)})
|
||||
? ({ target: currentSyndicateTarget, assertion: ${assertion} })
|
||||
? ({ target: currentSyndicateTarget(), assertion: ${assertion} })
|
||||
: ({ target: void 0, assertion: void 0 }));`;
|
||||
}
|
||||
});
|
||||
|
@ -222,7 +222,7 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(t)), '\n')}
|
|||
});
|
||||
|
||||
x(ctx.parser.atStatement, (s, t) => {
|
||||
return t`(((${ctx.argDecl(t, 'currentSyndicateTarget', '__SYNDICATE__.Ref')}) => {${walk(s.body)}})(${walk(s.target)}));`;
|
||||
return t`(((${ctx.argDecl(t, 'currentSyndicateTarget', '() => __SYNDICATE__.Ref')}) => {${walk(s.body)}})(() => (${walk(s.target)})));`;
|
||||
});
|
||||
|
||||
x(ctx.parser.createExpression, (s, t) => {
|
||||
|
@ -232,17 +232,17 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(t)), '\n')}
|
|||
xf(ctx.parser.assertionEndpointStatement, (s, t) => {
|
||||
if (s.isDynamic) {
|
||||
if (s.test === void 0) {
|
||||
return t`assertDataflow(() => ({ target: currentSyndicateTarget, assertion: ${walk(s.template)} }));`;
|
||||
return t`assertDataflow(() => ({ target: currentSyndicateTarget(), assertion: ${walk(s.template)} }));`;
|
||||
} else {
|
||||
return t`assertDataflow(() => (${walk(s.test)})
|
||||
? ({ target: currentSyndicateTarget, assertion: ${walk(s.template)} })
|
||||
? ({ target: currentSyndicateTarget(), assertion: ${walk(s.template)} })
|
||||
: ({ target: void 0, assertion: void 0 }));`;
|
||||
}
|
||||
} else {
|
||||
if (s.test === void 0) {
|
||||
return t`assert(currentSyndicateTarget, ${walk(s.template)});`;
|
||||
return t`assert(currentSyndicateTarget(), ${walk(s.template)});`;
|
||||
} else {
|
||||
return t`replace(currentSyndicateTarget, void 0, (${walk(s.test)}) ? (${walk(s.template)}) : void 0);`;
|
||||
return t`replace(currentSyndicateTarget(), void 0, (${walk(s.test)}) ? (${walk(s.template)}) : void 0);`;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -297,17 +297,17 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(t)), '\n')}
|
|||
|
||||
if (s.isDynamic) {
|
||||
if (s.test === void 0) {
|
||||
return wrap(t`__SYNDICATE__.Turn.active.assertDataflow(() => ({ target: currentSyndicateTarget, assertion: ${assertion} }));`);
|
||||
return wrap(t`__SYNDICATE__.Turn.active.assertDataflow(() => ({ target: currentSyndicateTarget(), assertion: ${assertion} }));`);
|
||||
} else {
|
||||
return wrap(t`__SYNDICATE__.Turn.active.assertDataflow(() => (${walk(s.test)})
|
||||
? ({ target: currentSyndicateTarget, assertion: ${assertion} })
|
||||
? ({ target: currentSyndicateTarget(), assertion: ${assertion} })
|
||||
: ({ target: void 0, assertion: void 0 }));`);
|
||||
}
|
||||
} else {
|
||||
if (s.test === void 0) {
|
||||
return wrap(t`__SYNDICATE__.Turn.active.replace(currentSyndicateTarget, void 0, ${assertion});`);
|
||||
return wrap(t`__SYNDICATE__.Turn.active.replace(currentSyndicateTarget(), void 0, ${assertion});`);
|
||||
} else {
|
||||
return wrap(t`__SYNDICATE__.Turn.active.replace(currentSyndicateTarget, void 0, (${walk(s.test)}) ? ${assertion} : void 0);`);
|
||||
return wrap(t`__SYNDICATE__.Turn.active.replace(currentSyndicateTarget(), void 0, (${walk(s.test)}) ? ${assertion} : void 0);`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -322,12 +322,14 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(t)), '\n')}
|
|||
return t`const ${[s.label]} = __SYNDICATE__.Record.makeConstructor${fs}()(${maybeWalk(s.wireName) ?? l}, ${fns});`;
|
||||
});
|
||||
|
||||
xf(ctx.parser.messageSendStatement, (s, t) => t`message(currentSyndicateTarget, ${walk(s.expr)});`);
|
||||
xf(ctx.parser.messageSendStatement, (s, t) => t`message(currentSyndicateTarget(), ${walk(s.expr)});`);
|
||||
|
||||
x(ctx.parser.reactStatement, (s, t) => facetWrap(t, s.label ?? 'default', s.body));
|
||||
|
||||
x(ctx.parser.stopStatement, (s, t) => t`${terminalWrap(t, s.facetToStop, s.body)};`);
|
||||
|
||||
xf(ctx.parser.syncStatement, (s, t) => t`_sync(${walk(s.peerToSyncWith)}, __SYNDICATE__.Turn.ref({ message() {${walk(s.body)}} }));`);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,10 @@ export interface StopStatement extends StatementTurnAction {
|
|||
facetToStop: FacetToStop;
|
||||
}
|
||||
|
||||
export interface SyncStatement extends StatementTurnAction {
|
||||
peerToSyncWith: Expr;
|
||||
}
|
||||
|
||||
export interface GenericEventEndpointStatement extends StatementTurnAction {
|
||||
facetToStop: FacetToStop | 'none' | 'once-wrapper';
|
||||
once: boolean;
|
||||
|
@ -385,6 +389,15 @@ export class SyndicateParser {
|
|||
alt(this.block(o.body), this.statementBoundary));
|
||||
});
|
||||
|
||||
// Principal: Turn
|
||||
readonly syncStatement: Pattern<SyncStatement> =
|
||||
this.turnAction(o => {
|
||||
o.body = [];
|
||||
return seq(atom('sync'),
|
||||
map(this.expr1(), e => o.peerToSyncWith = e),
|
||||
this.block(o.body));
|
||||
});
|
||||
|
||||
// Principal: none
|
||||
readonly atStatement: Pattern<AtStatement> =
|
||||
scope(o => {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/// SPDX-FileCopyrightText: Copyright © 2023-2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||
|
||||
const __SYNDICATE__ = Syndicate;
|
||||
const currentSyndicateTarget = Syndicate.Dataspace.global;
|
||||
const currentSyndicateTarget = () => Syndicate.Dataspace.local;
|
||||
|
||||
(() => {
|
||||
async function translateScripts() {
|
||||
|
|
|
@ -46,6 +46,35 @@ __SYNDICATE__.Turn.active.facet(() => {
|
|||
|
||||
});
|
||||
|
||||
describe('sync', () => {
|
||||
it('empty body', () => expectCodeEqual(`sync p {}`, `
|
||||
__SYNDICATE__.Turn.active._sync(p, __SYNDICATE__.Turn.ref({
|
||||
message() {}
|
||||
}));`));
|
||||
|
||||
it('nonempty body', () => expectCodeEqual(`sync p {q(); r();}`, `
|
||||
__SYNDICATE__.Turn.active._sync(p, __SYNDICATE__.Turn.ref({
|
||||
message() {
|
||||
q();
|
||||
r();
|
||||
}
|
||||
}));`));
|
||||
});
|
||||
|
||||
describe('at', () => {
|
||||
it('produces a closure for currentSyndicateTarget', () => {
|
||||
expectCodeEqual(`at someField.value { foo(); }`,
|
||||
`(((currentSyndicateTarget) => {
|
||||
foo();
|
||||
})(() => (someField.value)));`);
|
||||
expectCodeEqual(`at someField.value { foo(); }`,
|
||||
`(((currentSyndicateTarget: () => __SYNDICATE__.Ref) => {
|
||||
foo();
|
||||
})(() => (someField.value)));`,
|
||||
{ typescript: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe('spawn', () => {
|
||||
|
||||
it('without name', () => expectCodeEqual(`spawn { a; b; c; }`, `
|
||||
|
@ -132,7 +161,7 @@ describe('during', () => {
|
|||
|
||||
it('stop in body', () => expectCodeEqual(`during P => { a; stop; b; }`, `
|
||||
__SYNDICATE__.Turn.active.assertDataflow(() => ({
|
||||
target: currentSyndicateTarget,
|
||||
target: currentSyndicateTarget(),
|
||||
assertion: __SYNDICATE__.Observe({
|
||||
pattern: __SYNDICATE__.QuasiValue.finish((__SYNDICATE__.QuasiValue.lit(__SYNDICATE__.fromJS(P)))),
|
||||
observer: __SYNDICATE__.Turn.ref(__SYNDICATE__.assertionFacetObserver(
|
||||
|
@ -152,7 +181,7 @@ __SYNDICATE__.Turn.active.assertDataflow(() => ({
|
|||
|
||||
it('capture with type at top', () => expectCodeEqual(`during $v: T => { ok() }`, `
|
||||
__SYNDICATE__.Turn.active.assertDataflow(() => ({
|
||||
target: currentSyndicateTarget,
|
||||
target: currentSyndicateTarget(),
|
||||
assertion: __SYNDICATE__.Observe({
|
||||
pattern: __SYNDICATE__.QuasiValue.finish((__SYNDICATE__.QuasiValue.bind((__SYNDICATE__.QuasiValue._)))),
|
||||
observer: __SYNDICATE__.Turn.ref(__SYNDICATE__.assertionFacetObserver(
|
||||
|
@ -176,7 +205,7 @@ describe('once', () => {
|
|||
__SYNDICATE__.Turn.active.facet(() => {
|
||||
const __once_facet = __SYNDICATE__.Turn.activeFacet;
|
||||
__SYNDICATE__.Turn.active.assertDataflow(() => ({
|
||||
target: currentSyndicateTarget,
|
||||
target: currentSyndicateTarget(),
|
||||
assertion: __SYNDICATE__.Observe({
|
||||
pattern: __SYNDICATE__.QuasiValue.finish((__SYNDICATE__.QuasiValue.lit(__SYNDICATE__.fromJS(P)))),
|
||||
observer: __SYNDICATE__.Turn.ref({
|
||||
|
@ -195,7 +224,7 @@ __SYNDICATE__.Turn.active.facet(() => {
|
|||
__SYNDICATE__.Turn.active.facet(() => {
|
||||
const __once_facet = __SYNDICATE__.Turn.activeFacet;
|
||||
__SYNDICATE__.Turn.active.assertDataflow(() => ({
|
||||
target: currentSyndicateTarget,
|
||||
target: currentSyndicateTarget(),
|
||||
assertion: __SYNDICATE__.Observe({
|
||||
pattern: __SYNDICATE__.QuasiValue.finish((__SYNDICATE__.QuasiValue.lit(__SYNDICATE__.fromJS(P)))),
|
||||
observer: __SYNDICATE__.Turn.ref({
|
||||
|
@ -218,7 +247,7 @@ describe('on', () => {
|
|||
text.node.focus();
|
||||
}`, `__SYNDICATE__.Turn.active.assertDataflow(() => (isLast.value) ?
|
||||
({
|
||||
target: currentSyndicateTarget,
|
||||
target: currentSyndicateTarget(),
|
||||
assertion: __SYNDICATE__.Observe({
|
||||
pattern: __SYNDICATE__.QuasiValue.finish((__SYNDICATE__.QuasiValue.ctor(S.Focus, (__SYNDICATE__.QuasiValue.lit(__SYNDICATE__.fromJS(entity)))))),
|
||||
observer: __SYNDICATE__.Turn.ref({
|
||||
|
@ -241,7 +270,7 @@ describe('on', () => {
|
|||
it('asserted with guard', () => expectCodeEqual(`on asserted P when (someTest) => x;`, `
|
||||
__SYNDICATE__.Turn.active.assertDataflow(() => (someTest) ?
|
||||
({
|
||||
target: currentSyndicateTarget,
|
||||
target: currentSyndicateTarget(),
|
||||
assertion: __SYNDICATE__.Observe({
|
||||
pattern: __SYNDICATE__.QuasiValue.finish((__SYNDICATE__.QuasiValue.lit(__SYNDICATE__.fromJS(P)))),
|
||||
observer: __SYNDICATE__.Turn.ref({
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@syndicate-lang/core",
|
||||
"version": "0.34.1",
|
||||
"version": "0.34.8",
|
||||
"description": "Syndicate/JS for browser and node.js",
|
||||
"homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/core",
|
||||
"license": "GPL-3.0+",
|
||||
|
|
|
@ -3,8 +3,8 @@ tcp-remote
|
|||
ByteString„„„„³Headers´³dictof´³atom³Symbol„´³atom³String„„³MimeType´³atom³Symbol„³
|
||||
QueryValue´³orµµ±string´³atom³String„„µ±file´³rec´³lit³file„´³tupleµ´³named³filename´³atom³String„„´³named³headers´³refµ„³Headers„„´³named³body´³atom³
|
||||
ByteString„„„„„„„„³HostPattern´³orµµ±host´³atom³String„„µ±any´³lit€„„„„³HttpBinding´³rec´³lit³ http-bind„´³tupleµ´³named³host´³refµ„³HostPattern„„´³named³port´³atom³
SignedInteger„„´³named³method´³refµ„³
MethodPattern„„´³named³path´³refµ„³PathPattern„„´³named³handler´³embedded´³refµ„³HttpRequest„„„„„„³HttpContext´³rec´³lit³request„´³tupleµ´³named³req´³refµ„³HttpRequest„„´³named³res´³embedded´³refµ„³HttpResponse„„„„„„³HttpRequest´³rec´³lit³http-request„´³tupleµ´³named³sequenceNumber´³atom³
SignedInteger„„´³named³host´³refµ„³RequestHost„„´³named³port´³atom³
SignedInteger„„´³named³method´³atom³Symbol„„´³named³path´³seqof´³atom³String„„„´³named³headers´³refµ„³Headers„„´³named³query´³dictof´³atom³Symbol„´³seqof´³refµ„³
|
||||
QueryValue„„„„´³named³body´³refµ„³RequestBody„„„„„³HttpService´³rec´³lit³http-service„´³tupleµ´³named³host´³refµ„³HostPattern„„´³named³port´³atom³
SignedInteger„„´³named³method´³refµ„³
MethodPattern„„´³named³path´³refµ„³PathPattern„„„„„³PathPattern´³seqof´³refµ„³PathPatternElement„„³RequestBody´³orµµ±present´³atom³
|
||||
ByteString„„µ±absent´³lit€„„„„³RequestHost´³orµµ±present´³atom³String„„µ±absent´³lit€„„„„³HttpListener´³rec´³lit³
http-listener„´³tupleµ´³named³port´³atom³
SignedInteger„„„„„³HttpResponse´³orµµ±status´³rec´³lit³status„´³tupleµ´³named³code´³atom³
SignedInteger„„´³named³message´³atom³String„„„„„„µ±header´³rec´³lit³header„´³tupleµ´³named³name´³atom³Symbol„„´³named³value´³atom³String„„„„„„µ±chunk´³rec´³lit³chunk„´³tupleµ´³named³chunk´³refµ„³Chunk„„„„„„µ±done´³rec´³lit³done„´³tupleµ´³named³chunk´³refµ„³Chunk„„„„„„„„³
MethodPattern´³orµµ±any´³lit€„„µ±specific´³atom³Symbol„„„„³PathPatternElement´³orµµ±label´³atom³String„„µ±wildcard´³lit³_„„µ±rest´³lit³...„„„„„³embeddedType€„„µ³noise„´³schema·³version°³definitions·³Packet´³orµµ±complete´³atom³
|
||||
QueryValue„„„„´³named³body´³refµ„³RequestBody„„„„„³HttpService´³rec´³lit³http-service„´³tupleµ´³named³host´³refµ„³HostPattern„„´³named³port´³atom³
SignedInteger„„´³named³method´³refµ„³
MethodPattern„„´³named³path´³refµ„³PathPattern„„„„„³PathPattern´³seqof´³refµ„³PathPatternElement„„³RequestBody´³orµµ±absent´³lit€„„µ±present´³atom³
|
||||
ByteString„„„„³RequestHost´³orµµ±absent´³lit€„„µ±present´³atom³String„„„„³HttpListener´³rec´³lit³
http-listener„´³tupleµ´³named³port´³atom³
SignedInteger„„„„„³HttpResponse´³orµµ±status´³rec´³lit³status„´³tupleµ´³named³code´³atom³
SignedInteger„„´³named³message´³atom³String„„„„„„µ±header´³rec´³lit³header„´³tupleµ´³named³name´³atom³Symbol„„´³named³value´³atom³String„„„„„„µ±chunk´³rec´³lit³chunk„´³tupleµ´³named³chunk´³refµ„³Chunk„„„„„„µ±done´³rec´³lit³done„´³tupleµ´³named³chunk´³refµ„³Chunk„„„„„„„„³
MethodPattern´³orµµ±any´³lit€„„µ±specific´³atom³Symbol„„„„³PathPatternElement´³orµµ±label´³atom³String„„µ±wildcard´³lit³_„„µ±rest´³lit³...„„„„„³embeddedType€„„µ³noise„´³schema·³version°³definitions·³Packet´³orµµ±complete´³atom³
|
||||
ByteString„„µ±
|
||||
fragmented´³seqof´³atom³
|
||||
ByteString„„„„„³ Initiator´³rec´³lit³ initiator„´³tupleµ´³named³initiatorSession´³embedded´³refµ„³Packet„„„„„„³ NoiseSpec´³andµ´³dict·³key´³named³key´³atom³
|
||||
|
@ -38,7 +38,7 @@ Parameters
|
|||
Parameters„³SturdyDescriptionDetail´³dict·³key´³named³key´³atom³
|
||||
ByteString„„³oid´³named³oid³any„„„„³embeddedType´³refµ³ EntityRef„³Cap„„„µ³worker„´³schema·³version°³definitions·³Instance´³rec´³lit³Instance„´³tupleµ´³named³name´³atom³String„„´³named³argument³any„„„„„³embeddedType´³refµ³ EntityRef„³Cap„„„µ³service„´³schema·³version°³definitions·³State´³orµµ±started´³lit³started„„µ±ready´³lit³ready„„µ±failed´³lit³failed„„µ±complete´³lit³complete„„µ±userDefined³any„„„³
|
||||
RunService´³rec´³lit³run-service„´³tupleµ´³named³serviceName³any„„„„³ServiceState´³rec´³lit³
service-state„´³tupleµ´³named³serviceName³any„´³named³state´³refµ„³State„„„„„³
ServiceObject´³rec´³lit³service-object„´³tupleµ´³named³serviceName³any„´³named³object³any„„„„³RequireService´³rec´³lit³require-service„´³tupleµ´³named³serviceName³any„„„„³RestartService´³rec´³lit³restart-service„´³tupleµ´³named³serviceName³any„„„„³ServiceDependency´³rec´³lit³
|
||||
depends-on„´³tupleµ´³named³depender³any„´³named³dependee´³refµ„³ServiceState„„„„„„³embeddedType´³refµ³ EntityRef„³Cap„„„µ³protocol„´³schema·³version°³definitions·³Oid´³atom³
SignedInteger„³Sync´³rec´³lit³S„´³tupleµ´³named³peer´³embedded´³lit<69>„„„„„„³Turn´³seqof´³refµ„³ TurnEvent„„³Error´³rec´³lit³error„´³tupleµ´³named³message´³atom³String„„´³named³detail³any„„„„³Event´³orµµ±Assert´³refµ„³Assert„„µ±Retract´³refµ„³Retract„„µ±Message´³refµ„³Message„„µ±Sync´³refµ„³Sync„„„„³Assert´³rec´³lit³A„´³tupleµ´³named³ assertion´³refµ„³ Assertion„„´³named³handle´³refµ„³Handle„„„„„³Handle´³atom³
SignedInteger„³Packet´³orµµ±Turn´³refµ„³Turn„„µ±Error´³refµ„³Error„„µ± Extension´³refµ„³ Extension„„„„³Message´³rec´³lit³M„´³tupleµ´³named³body´³refµ„³ Assertion„„„„„³Retract´³rec´³lit³R„´³tupleµ´³named³handle´³refµ„³Handle„„„„„³ Assertion³any³ Extension´³rec´³named³label³any„´³named³fields´³seqof³any„„„³ TurnEvent´³tupleµ´³named³oid´³refµ„³Oid„„´³named³event´³refµ„³Event„„„„„³embeddedType€„„µ³ dataspace„´³schema·³version°³definitions·³Observe´³rec´³lit³Observe„´³tupleµ´³named³pattern´³refµ³dataspacePatterns„³Pattern„„´³named³observer´³embedded³any„„„„„„³embeddedType´³refµ³ EntityRef„³Cap„„„µ³
|
||||
depends-on„´³tupleµ´³named³depender³any„´³named³dependee´³refµ„³ServiceState„„„„„„³embeddedType´³refµ³ EntityRef„³Cap„„„µ³protocol„´³schema·³version°³definitions·³Nop´³lit€„³Oid´³atom³
SignedInteger„³Sync´³rec´³lit³S„´³tupleµ´³named³peer´³embedded´³lit<69>„„„„„„³Turn´³seqof´³refµ„³ TurnEvent„„³Error´³rec´³lit³error„´³tupleµ´³named³message´³atom³String„„´³named³detail³any„„„„³Event´³orµµ±Assert´³refµ„³Assert„„µ±Retract´³refµ„³Retract„„µ±Message´³refµ„³Message„„µ±Sync´³refµ„³Sync„„„„³Assert´³rec´³lit³A„´³tupleµ´³named³ assertion´³refµ„³ Assertion„„´³named³handle´³refµ„³Handle„„„„„³Handle´³atom³
SignedInteger„³Packet´³orµµ±Turn´³refµ„³Turn„„µ±Error´³refµ„³Error„„µ± Extension´³refµ„³ Extension„„µ±Nop´³refµ„³Nop„„„„³Message´³rec´³lit³M„´³tupleµ´³named³body´³refµ„³ Assertion„„„„„³Retract´³rec´³lit³R„´³tupleµ´³named³handle´³refµ„³Handle„„„„„³ Assertion³any³ Extension´³rec´³named³label³any„´³named³fields´³seqof³any„„„³ TurnEvent´³tupleµ´³named³oid´³refµ„³Oid„„´³named³event´³refµ„³Event„„„„„³embeddedType€„„µ³ dataspace„´³schema·³version°³definitions·³Observe´³rec´³lit³Observe„´³tupleµ´³named³pattern´³refµ³dataspacePatterns„³Pattern„„´³named³observer´³embedded³any„„„„„„³embeddedType´³refµ³ EntityRef„³Cap„„„µ³
|
||||
gatekeeper„´³schema·³version°³definitions·³Bind´³rec´³lit³bind„´³tupleµ´³named³description´³refµ„³Description„„´³named³target´³embedded³any„„´³named³observer´³refµ„³BindObserver„„„„„³Step´³rec´³named³stepType´³atom³Symbol„„´³tupleµ´³named³detail³any„„„„³Bound´³orµµ±bound´³rec´³lit³bound„´³tupleµ´³named³pathStep´³refµ„³PathStep„„„„„„µ±Rejected´³refµ„³Rejected„„„„³Route´³rec´³lit³route„´³tuplePrefixµ´³named³
|
||||
transports´³seqof³any„„„´³named³ pathSteps´³seqof´³refµ„³PathStep„„„„„³Resolve´³rec´³lit³resolve„´³tupleµ´³named³step´³refµ„³Step„„´³named³observer´³embedded´³refµ„³Resolved„„„„„„³PathStep´³rec´³named³stepType´³atom³Symbol„„´³tupleµ´³named³detail³any„„„„³Rejected´³rec´³lit³rejected„´³tupleµ´³named³detail³any„„„„³Resolved´³orµµ±accepted´³rec´³lit³accepted„´³tupleµ´³named³responderSession´³embedded³any„„„„„„µ±Rejected´³refµ„³Rejected„„„„³Description´³rec´³named³stepType´³atom³Symbol„„´³tupleµ´³named³detail³any„„„„³ResolvePath´³rec´³lit³resolve-path„´³tupleµ´³named³route´³refµ„³Route„„´³named³addr³any„´³named³control´³embedded´³refµ„³TransportControl„„„´³named³resolved´³refµ„³Resolved„„„„„³BindObserver´³orµµ±present´³embedded´³refµ„³Bound„„„µ±absent´³lit€„„„„³ForceDisconnect´³rec´³lit³force-disconnect„´³tupleµ„„„³ResolvedPathStep´³rec´³lit³ path-step„´³tupleµ´³named³origin´³embedded´³refµ„³Resolve„„„´³named³pathStep´³refµ„³PathStep„„´³named³resolved´³refµ„³Resolved„„„„„³TransportControl´³refµ„³ForceDisconnect„³TransportConnection´³rec´³lit³connect-transport„´³tupleµ´³named³addr³any„´³named³control´³embedded´³refµ„³TransportControl„„„´³named³resolved´³refµ„³Resolved„„„„„„³embeddedType´³refµ³ EntityRef„³Cap„„„µ³transportAddress„´³schema·³version°³definitions·³Tcp´³rec´³lit³tcp„´³tupleµ´³named³host´³atom³String„„´³named³port´³atom³
SignedInteger„„„„„³Unix´³rec´³lit³unix„´³tupleµ´³named³path´³atom³String„„„„„³Stdio´³rec´³lit³stdio„´³tupleµ„„„³ WebSocket´³rec´³lit³ws„´³tupleµ´³named³url´³atom³String„„„„„„³embeddedType€„„µ³dataspacePatterns„´³schema·³version°³definitions·³AnyAtom´³orµµ±bool´³atom³Boolean„„µ±double´³atom³Double„„µ±int´³atom³
SignedInteger„„µ±string´³atom³String„„µ±bytes´³atom³
|
||||
ByteString„„µ±symbol´³atom³Symbol„„µ±embedded´³embedded³any„„„„³Pattern´³orµµ±discard´³rec´³lit³_„´³tupleµ„„„„µ±bind´³rec´³lit³bind„´³tupleµ´³named³pattern´³refµ„³Pattern„„„„„„µ±lit´³rec´³lit³lit„´³tupleµ´³named³value´³refµ„³AnyAtom„„„„„„µ±group´³rec´³lit³group„´³tupleµ´³named³type´³refµ„³ GroupType„„´³named³entries´³dictof³any´³refµ„³Pattern„„„„„„„„„³ GroupType´³orµµ±rec´³rec´³lit³rec„´³tupleµ´³named³label³any„„„„„µ±arr´³rec´³lit³arr„´³tupleµ„„„„µ±dict´³rec´³lit³dict„´³tupleµ„„„„„„„³embeddedType´³refµ³ EntityRef„³Cap„„„„„
|
|
@ -31,8 +31,8 @@ HttpRequest = <http-request
|
|||
|
||||
Headers = {@"Lowercase" symbol: string ...:...} .
|
||||
QueryValue = @string string / <file @filename string @headers Headers @body bytes> .
|
||||
RequestBody = @present bytes / @absent #f .
|
||||
RequestHost = @present string / @absent #f .
|
||||
RequestBody = @absent #f / @present bytes .
|
||||
RequestHost = @absent #f / @present string .
|
||||
|
||||
# Assertion to handler entity
|
||||
HttpContext = <request @req HttpRequest @res #:HttpResponse> .
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
version 1 .
|
||||
|
||||
Packet = Turn / Error / Extension .
|
||||
Packet = Turn / Error / Extension / Nop .
|
||||
|
||||
Extension = <<rec> @label any @fields [any ...]> .
|
||||
Nop = #f .
|
||||
|
||||
Error = <error @message string @detail any>.
|
||||
|
||||
|
|
|
@ -20,8 +20,10 @@ export * as Skeleton from './runtime/skeleton.js';
|
|||
export * from './runtime/space.js';
|
||||
export * from './runtime/supervise.js';
|
||||
|
||||
export * as SaltyCrypto from 'salty-crypto';
|
||||
export * as Cryptography from './transport/cryptography.js';
|
||||
export * as WireProtocol from './transport/protocol.js';
|
||||
export * as Membrane from './transport/membrane.js';
|
||||
export * as Relay from './transport/relay.js';
|
||||
export * as Sturdy from './transport/sturdy.js';
|
||||
|
||||
|
|
|
@ -80,7 +80,10 @@ export function toRef(_v: any): Ref | undefined {
|
|||
return isRef(_v) ? _v : void 0;
|
||||
}
|
||||
|
||||
export function assertionFrom(a: Assertable): Assertion {
|
||||
export function assertionFrom(a: Assertable): Assertion;
|
||||
export function assertionFrom(a: Assertable | undefined): Assertion | undefined;
|
||||
export function assertionFrom(a: Assertable | undefined): Assertion | undefined {
|
||||
if (a === void 0) return void 0;
|
||||
if (typeof a === 'object' && '__as_preserve__' in a) {
|
||||
return fromJS(a);
|
||||
} else {
|
||||
|
@ -279,6 +282,32 @@ export class Facet {
|
|||
}
|
||||
}
|
||||
|
||||
export function suspend(asyncFn: (resume: <T>(v: T) => T) => void) {
|
||||
// TODO: consider how this should/could interact with preventInertCheck
|
||||
|
||||
const facet = Turn.activeFacet;
|
||||
|
||||
const resume = <T>(v: T) => {
|
||||
if (!facet.actor.space.isRunning()) {
|
||||
throw new Error('Cannot resume into inactive actor space'); // TODO
|
||||
}
|
||||
const t = Turn.___new(facet);
|
||||
queueMicrotask(() => {
|
||||
try {
|
||||
facet.actor.repairDataflowGraph();
|
||||
t.deliver();
|
||||
} catch (err) {
|
||||
Turn.for(facet.actor.root, () => facet.actor._terminateWith({ ok: false, err }));
|
||||
}
|
||||
if (Turn.active === t) Turn.active = void 0 as unknown as Turn;
|
||||
});
|
||||
Turn.active = t;
|
||||
return v;
|
||||
};
|
||||
|
||||
return asyncFn(resume);
|
||||
}
|
||||
|
||||
export const STOP_ON_RETRACT = Symbol('stop-on-retract'); // NB. NOT A GLOBAL SYMBOL
|
||||
|
||||
export class StopOnRetract implements Partial<Entity> {
|
||||
|
@ -338,6 +367,10 @@ export class Turn {
|
|||
}
|
||||
}
|
||||
|
||||
static ___new(facet: Facet): Turn {
|
||||
return new Turn(facet);
|
||||
}
|
||||
|
||||
private constructor(facet: Facet, queues = new Map<Actor, StructuredTask<TaskAction>[]>()) {
|
||||
this._activeFacet = facet;
|
||||
this.queues = queues;
|
||||
|
@ -464,6 +497,7 @@ export class Turn {
|
|||
let assertion: Assertable | undefined = void 0;
|
||||
this.dataflow(() => {
|
||||
let {target: nextTarget, assertion: nextAssertion} = assertionFunction();
|
||||
nextAssertion = assertionFrom(nextAssertion);
|
||||
if (target !== nextTarget || !is(assertion, nextAssertion)) {
|
||||
target = nextTarget;
|
||||
assertion = nextAssertion;
|
||||
|
@ -590,7 +624,7 @@ export class Turn {
|
|||
throw new Error("Attempt to reuse a committed Turn");
|
||||
}
|
||||
const a: StructuredTask<TaskAction> = {
|
||||
perform() { Turn.active._inFacet(relay, a0); },
|
||||
perform() { relay.isLive && Turn.active._inFacet(relay, a0); },
|
||||
describe() { return { targetFacet: relay, action: detail() }; },
|
||||
};
|
||||
this.queues.get(relay.actor)?.push(a) ?? this.queues.set(relay.actor, [a]);
|
||||
|
|
|
@ -214,7 +214,7 @@ export function lit(v: AnyValue): P.Pattern {
|
|||
return P.Pattern.lit(P.asAnyAtom(v));
|
||||
}
|
||||
|
||||
export function drop_lit(p: P.Pattern): AnyValue | null {
|
||||
export function drop_lit(p: P.Pattern, strip_binds = false): AnyValue | null {
|
||||
const e = new Error();
|
||||
|
||||
function walkEntries(target: AnyValue[], entries: EncodableDictionary<Ref, AnyValue, P.Pattern<Ref>>): void {
|
||||
|
@ -253,6 +253,11 @@ export function drop_lit(p: P.Pattern): AnyValue | null {
|
|||
}
|
||||
case 'lit':
|
||||
return P.fromAnyAtom(p.value);
|
||||
case 'bind':
|
||||
if (strip_binds) {
|
||||
return walk(p.pattern);
|
||||
}
|
||||
// fall through
|
||||
default:
|
||||
throw e;
|
||||
}
|
||||
|
|
|
@ -278,7 +278,10 @@ export function ctor(info: QuasiValueConstructorInfo, ... items: QuasiValue[]):
|
|||
} else if ('quasiValue' in info) {
|
||||
return info.quasiValue(... items);
|
||||
} else {
|
||||
((_i: never) => { throw new Error("INTERNAL ERROR"); })(info);
|
||||
((info: never) => {
|
||||
console.error('ctor() in quasivalue.ts cannot handle', info);
|
||||
throw new Error("INTERNAL ERROR");
|
||||
})(info);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,21 @@ import * as IO from '../gen/protocol.js';
|
|||
import { fromCaveat, WireRef } from '../gen/sturdy.js';
|
||||
import { attenuate } from '../runtime/rewrite.js';
|
||||
|
||||
export type MembraneTraceEvent = { type: 'grab' | 'drop', oid: IO.Oid, ref: Ref, delta: number, newCount: number };
|
||||
export type LayerMembraneTraceEvent = MembraneTraceEvent & { table: 'exported' | 'imported' };
|
||||
export type LayerTraceEvent =
|
||||
| LayerMembraneTraceEvent
|
||||
| { type: 'outbound' | 'inbound', target: any, event: 'assert', assertion: Value<any>, handle: Handle }
|
||||
| { type: 'outbound' | 'inbound', event: 'retract', handle: Handle }
|
||||
| { type: 'outbound' | 'inbound', event: 'message', assertion: Value<any> }
|
||||
| { type: 'outbound' | 'inbound', target: any, event: 'sync', peer: any }
|
||||
;
|
||||
export type LayerTracer = (e: LayerTraceEvent) => void;
|
||||
|
||||
let defaultLayerTracer: LayerTracer | undefined = void 0;
|
||||
export function getDefaultLayerTracer(): LayerTracer | undefined { return defaultLayerTracer; }
|
||||
export function setDefaultLayerTracer(t: LayerTracer | undefined) { defaultLayerTracer = t; }
|
||||
|
||||
export class WireSymbol {
|
||||
count = 0;
|
||||
|
||||
|
@ -18,6 +33,7 @@ export class WireSymbol {
|
|||
|
||||
drop(): void {
|
||||
this.count--;
|
||||
this.side.tracer?.({ type: 'drop', oid: this.oid, ref: this.ref, delta: -1, newCount: this.count });
|
||||
if (this.count === 0) {
|
||||
this.side.byOid.delete(this.oid);
|
||||
this.side.byRef.delete(this.ref);
|
||||
|
@ -31,6 +47,8 @@ export class Membrane {
|
|||
readonly byOid = new IdentityMap<IO.Oid, WireSymbol>();
|
||||
readonly byRef = new IdentityMap<Ref, WireSymbol>();
|
||||
|
||||
tracer?: (e: MembraneTraceEvent) => void;
|
||||
|
||||
grab<Table extends WhichTable>(table: Table,
|
||||
key: Parameters<Membrane[Table]['get']>[0],
|
||||
transient: boolean,
|
||||
|
@ -51,6 +69,7 @@ export class Membrane {
|
|||
this.byOid.set(e.oid, e);
|
||||
}
|
||||
if (!transient) e.count++;
|
||||
this.tracer?.({ type: 'grab', oid: e.oid, ref: e.ref, delta: transient ? 0 : +1, newCount: e.count });
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
@ -80,11 +99,19 @@ export abstract class LayerBoundary implements ProxyOutbound, ProxyInbound {
|
|||
readonly exported = new Membrane();
|
||||
readonly imported = new Membrane();
|
||||
|
||||
constructor(public trustPeer = true, public nextLocalOid: IO.Oid = 0) {}
|
||||
readonly tracer: LayerTracer | undefined = defaultLayerTracer;
|
||||
|
||||
constructor(public trustPeer = true, public nextLocalOid: IO.Oid = 0) {
|
||||
if (this.tracer) {
|
||||
this.exported.tracer = e => { const f = e as LayerMembraneTraceEvent; f.table = 'exported'; this.tracer?.(f); };
|
||||
this.imported.tracer = e => { const f = e as LayerMembraneTraceEvent; f.table = 'imported'; this.tracer?.(f); };
|
||||
}
|
||||
}
|
||||
|
||||
abstract send(remoteOid: IO.Oid, event: IO.Event<Embedded<WireRef>>): void;
|
||||
|
||||
proxyAssertion(targetRemoteOid: IO.Oid, assertion: Assertion, handle: Handle): Value<Embedded<WireRef>> {
|
||||
this.tracer?.({ type: 'outbound', target: targetRemoteOid, event: 'assert', assertion, handle });
|
||||
const pins: Array<WireSymbol> = [];
|
||||
const rewritten = mapEmbeddeds(assertion, r => this.rewriteRefOut(r, false, pins));
|
||||
this.grabImportedOid(targetRemoteOid, pins);
|
||||
|
@ -93,16 +120,19 @@ export abstract class LayerBoundary implements ProxyOutbound, ProxyInbound {
|
|||
}
|
||||
|
||||
proxyRetract(handle: Handle): void {
|
||||
this.tracer?.({ type: 'outbound', event: 'retract', handle });
|
||||
(this.outboundAssertions.get(handle) ?? []).forEach(e => e.drop());
|
||||
this.outboundAssertions.delete(handle);
|
||||
}
|
||||
|
||||
proxyMessage(assertion: Assertion): Value<Embedded<WireRef>> {
|
||||
this.tracer?.({ type: 'outbound', event: 'message', assertion });
|
||||
const pins: Array<WireSymbol> = [];
|
||||
return mapEmbeddeds(assertion, r => this.rewriteRefOut(r, true, pins));
|
||||
}
|
||||
|
||||
proxySync(targetRemoteOid: IO.Oid, peer: Ref): Embedded<WireRef> {
|
||||
this.tracer?.({ type: 'outbound', target: targetRemoteOid, event: 'sync', peer });
|
||||
const peerEntity = new SyncPeerEntity(peer);
|
||||
this.grabImportedOid(targetRemoteOid, peerEntity.pins);
|
||||
return this.rewriteRefOut(Turn.ref(peerEntity), false, peerEntity.pins);
|
||||
|
@ -111,9 +141,14 @@ export abstract class LayerBoundary implements ProxyOutbound, ProxyInbound {
|
|||
grabImportedOid(oid: IO.Oid, pins: Array<WireSymbol>): void {
|
||||
const e = this.imported.grab("byOid", oid, false, null);
|
||||
if (e === null) {
|
||||
throw new Error("Internal error: import table missing entry for oid " + oid);
|
||||
// This can happen if
|
||||
// 1. remote peer asserts a value causing oid to be allocated
|
||||
// 2. some local actor holds a reference to that entity
|
||||
// 3. remote peer retracts the value
|
||||
// 4. local actor uses the ref
|
||||
} else {
|
||||
pins.push(e);
|
||||
}
|
||||
pins.push(e);
|
||||
}
|
||||
|
||||
grabExportedOid(oid: IO.Oid, pins: Array<WireSymbol>): Ref {
|
||||
|
@ -192,6 +227,7 @@ export abstract class LayerBoundary implements ProxyOutbound, ProxyInbound {
|
|||
handle(localOid: IO.Oid, m: IO.Event<Embedded<WireRef>>): void {
|
||||
switch (m._variant) {
|
||||
case 'Assert': {
|
||||
this.tracer?.({ type: 'inbound', event: 'assert', target: localOid, assertion: m.value.assertion, handle: m.value.handle });
|
||||
const [a, pins] = this.rewriteIn(m.value.assertion);
|
||||
const r = this.grabExportedOid(localOid, pins);
|
||||
this.inboundAssertions.set(m.value.handle, {
|
||||
|
@ -201,6 +237,7 @@ export abstract class LayerBoundary implements ProxyOutbound, ProxyInbound {
|
|||
break;
|
||||
}
|
||||
case 'Retract': {
|
||||
this.tracer?.({ type: 'inbound', event: 'retract', handle: m.value.handle });
|
||||
const remoteHandle = m.value.handle;
|
||||
const h = this.inboundAssertions.get(remoteHandle);
|
||||
if (h === void 0) throw new Error(`Peer retracted invalid handle ${remoteHandle}`);
|
||||
|
@ -210,13 +247,18 @@ export abstract class LayerBoundary implements ProxyOutbound, ProxyInbound {
|
|||
break;
|
||||
}
|
||||
case 'Message': {
|
||||
this.tracer?.({ type: 'inbound', event: 'message', assertion: m.value.body });
|
||||
const [a, pins] = this.rewriteIn(m.value.body);
|
||||
if (pins.length > 0) throw new Error("Cannot receive transient reference");
|
||||
pins.forEach(e => {
|
||||
e.drop();
|
||||
if (e.count === 0) throw new Error("Cannot receive transient reference");
|
||||
});
|
||||
const r = this.exported.byOid.get(localOid)?.ref;
|
||||
if (r) Turn.active.message(r, a);
|
||||
break;
|
||||
}
|
||||
case 'Sync': {
|
||||
this.tracer?.({ type: 'inbound', event: 'sync', target: localOid, peer: m.value.peer });
|
||||
const pins: Array<WireSymbol> = [];
|
||||
const r = this.grabExportedOid(localOid, pins);
|
||||
const k = this.rewriteRefIn(m.value.peer, pins);
|
||||
|
@ -239,6 +281,9 @@ export abstract class LayerBoundary implements ProxyOutbound, ProxyInbound {
|
|||
case 'Extension':
|
||||
// Ignore unknown extensions.
|
||||
break;
|
||||
case 'Nop':
|
||||
// Ignore no-ops.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@syndicate-lang/fs",
|
||||
"version": "0.35.1",
|
||||
"version": "0.35.8",
|
||||
"description": "Reflect contents of a portion of the file system as assertions",
|
||||
"homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/fs",
|
||||
"license": "GPL-3.0+",
|
||||
|
@ -30,13 +30,13 @@
|
|||
"@preserves/core": "^0.995.200"
|
||||
},
|
||||
"dependencies": {
|
||||
"@syndicate-lang/core": "^0.34.1",
|
||||
"@syndicate-lang/service": "^0.35.1",
|
||||
"@syndicate-lang/core": "^0.34.8",
|
||||
"@syndicate-lang/service": "^0.35.8",
|
||||
"chokidar": "^3.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@preserves/schema-cli": ">=0.995.201",
|
||||
"@syndicate-lang/ts-plugin": "^0.36.1",
|
||||
"@syndicate-lang/tsc": "^0.36.1"
|
||||
"@syndicate-lang/ts-plugin": "^0.36.8",
|
||||
"@syndicate-lang/tsc": "^0.36.8"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@syndicate-lang/html",
|
||||
"version": "0.35.1",
|
||||
"version": "0.35.8",
|
||||
"description": "DOM/HTML UI for Syndicate/JS",
|
||||
"homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/html",
|
||||
"license": "GPL-3.0+",
|
||||
|
@ -25,10 +25,10 @@
|
|||
"veryclean": "yarn run clean && rm -rf node_modules"
|
||||
},
|
||||
"dependencies": {
|
||||
"@syndicate-lang/core": "^0.34.1"
|
||||
"@syndicate-lang/core": "^0.34.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@syndicate-lang/ts-plugin": "^0.36.1",
|
||||
"@syndicate-lang/tsc": "^0.36.1"
|
||||
"@syndicate-lang/ts-plugin": "^0.36.8",
|
||||
"@syndicate-lang/tsc": "^0.36.8"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@syndicate-lang/html2",
|
||||
"version": "0.35.1",
|
||||
"version": "0.35.9",
|
||||
"description": "DOM/HTML UI for Syndicate/JS",
|
||||
"homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/html2",
|
||||
"license": "GPL-3.0+",
|
||||
|
@ -25,10 +25,10 @@
|
|||
"veryclean": "yarn run clean && rm -rf node_modules"
|
||||
},
|
||||
"dependencies": {
|
||||
"@syndicate-lang/core": "^0.34.1"
|
||||
"@syndicate-lang/core": "^0.34.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@syndicate-lang/ts-plugin": "^0.36.1",
|
||||
"@syndicate-lang/tsc": "^0.36.1"
|
||||
"@syndicate-lang/ts-plugin": "^0.36.8",
|
||||
"@syndicate-lang/tsc": "^0.36.8"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,14 +34,17 @@ export class Widget implements EventTarget {
|
|||
constructor (arg0: ChildNode | NodeGenerator | string | HTMLTemplateElement, data?: object) {
|
||||
let nodeGenerator: NodeGenerator;
|
||||
|
||||
if (data === void 0) {
|
||||
if (typeof data === 'object') {
|
||||
nodeGenerator = templateGenerator(arg0 as (string | HTMLTemplateElement), data);
|
||||
} else {
|
||||
// `data` is either undefined or "garbage" e.g. a string given to us by
|
||||
// ValueWidget's constructor.
|
||||
|
||||
if (typeof arg0 === 'function') {
|
||||
nodeGenerator = arg0 as NodeGenerator;
|
||||
} else {
|
||||
nodeGenerator = () => [arg0 as ChildNode];
|
||||
}
|
||||
} else {
|
||||
nodeGenerator = templateGenerator(arg0 as (string | HTMLTemplateElement), data);
|
||||
}
|
||||
|
||||
this.facet = Turn.activeFacet;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@syndicate-lang/loader",
|
||||
"version": "0.35.1",
|
||||
"version": "0.35.8",
|
||||
"description": "Syndicate/JS node.js loader hook",
|
||||
"homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/loader",
|
||||
"license": "GPL-3.0+",
|
||||
|
@ -22,8 +22,8 @@
|
|||
"types": "lib/index.d.ts",
|
||||
"author": "Tony Garnock-Jones <tonyg@leastfixedpoint.com>",
|
||||
"dependencies": {
|
||||
"@syndicate-lang/compiler": "^0.22.0",
|
||||
"@syndicate-lang/core": "^0.34.1",
|
||||
"@syndicate-lang/service": "^0.35.1"
|
||||
"@syndicate-lang/compiler": "^0.22.3",
|
||||
"@syndicate-lang/core": "^0.34.8",
|
||||
"@syndicate-lang/service": "^0.35.8"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import Pos = Syntax.Pos;
|
|||
|
||||
import * as Syndicate from '@syndicate-lang/core';
|
||||
Object.defineProperty(globalThis, 'currentSyndicateTarget', {
|
||||
value: Syndicate.Dataspace.local,
|
||||
value: () => Syndicate.Dataspace.local,
|
||||
writable: false,
|
||||
});
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@syndicate-lang/service",
|
||||
"version": "0.35.1",
|
||||
"version": "0.35.8",
|
||||
"description": "Run a node.js program as a service within syndicate-server",
|
||||
"homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/service",
|
||||
"license": "GPL-3.0+",
|
||||
|
@ -22,10 +22,10 @@
|
|||
"veryclean": "yarn run clean && rm -rf node_modules"
|
||||
},
|
||||
"dependencies": {
|
||||
"@syndicate-lang/core": "^0.34.1"
|
||||
"@syndicate-lang/core": "^0.34.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@syndicate-lang/ts-plugin": "^0.36.1",
|
||||
"@syndicate-lang/tsc": "^0.36.1"
|
||||
"@syndicate-lang/ts-plugin": "^0.36.8",
|
||||
"@syndicate-lang/tsc": "^0.36.8"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@syndicate-lang/syndicatec",
|
||||
"version": "0.36.1",
|
||||
"version": "0.36.8",
|
||||
"description": "Syndicate/JS compiler command-line tool",
|
||||
"homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/syndicatec",
|
||||
"license": "GPL-3.0+",
|
||||
|
@ -20,8 +20,8 @@
|
|||
},
|
||||
"author": "Tony Garnock-Jones <tonyg@leastfixedpoint.com>",
|
||||
"dependencies": {
|
||||
"@syndicate-lang/compiler": "^0.22.0",
|
||||
"@syndicate-lang/core": "^0.34.1",
|
||||
"@syndicate-lang/compiler": "^0.22.3",
|
||||
"@syndicate-lang/core": "^0.34.8",
|
||||
"glob": "^7.1.6",
|
||||
"yargs": "^16.2.0"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@syndicate-lang/timer",
|
||||
"version": "0.35.1",
|
||||
"version": "0.35.8",
|
||||
"description": "Time and timer driver for Syndicate",
|
||||
"homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/timer",
|
||||
"license": "GPL-3.0+",
|
||||
|
@ -25,10 +25,10 @@
|
|||
"veryclean": "yarn run clean && rm -rf node_modules"
|
||||
},
|
||||
"dependencies": {
|
||||
"@syndicate-lang/core": "^0.34.1"
|
||||
"@syndicate-lang/core": "^0.34.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@syndicate-lang/ts-plugin": "^0.36.1",
|
||||
"@syndicate-lang/tsc": "^0.36.1"
|
||||
"@syndicate-lang/ts-plugin": "^0.36.8",
|
||||
"@syndicate-lang/tsc": "^0.36.8"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@syndicate-lang/ts-plugin",
|
||||
"version": "0.36.1",
|
||||
"version": "0.36.8",
|
||||
"description": "Syndicate/JS TypeScript tsserver plugin",
|
||||
"homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/ts-plugin",
|
||||
"license": "GPL-3.0+",
|
||||
|
@ -22,8 +22,8 @@
|
|||
"types": "lib/index.d.ts",
|
||||
"author": "Tony Garnock-Jones <tonyg@leastfixedpoint.com>",
|
||||
"dependencies": {
|
||||
"@syndicate-lang/compiler": "^0.22.0",
|
||||
"@syndicate-lang/core": "^0.34.1"
|
||||
"@syndicate-lang/compiler": "^0.22.3",
|
||||
"@syndicate-lang/core": "^0.34.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^4.9"
|
||||
|
|
|
@ -160,7 +160,7 @@ const boot: tslib.server.PluginModuleFactory = ({ typescript: ts }) => {
|
|||
const { text: expandedText, targetToSourceMap, sourceToTargetMap } = compile({
|
||||
source,
|
||||
name,
|
||||
typescript: true,
|
||||
typescript: !name.toLowerCase().endsWith('.js'),
|
||||
emitError: (message, start, end) => {
|
||||
console.error(`${Syntax.formatPos(start)}-${Syntax.formatPos(end)}: ${message}`);
|
||||
diagnostics.push({ message, start, end });
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@syndicate-lang/tsc",
|
||||
"version": "0.36.1",
|
||||
"version": "0.36.8",
|
||||
"description": "Syndicate for TypeScript compiler command-line tool",
|
||||
"homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/tsc",
|
||||
"license": "GPL-3.0+",
|
||||
|
@ -20,8 +20,8 @@
|
|||
},
|
||||
"author": "Tony Garnock-Jones <tonyg@leastfixedpoint.com>",
|
||||
"dependencies": {
|
||||
"@syndicate-lang/compiler": "^0.22.0",
|
||||
"@syndicate-lang/core": "^0.34.1",
|
||||
"@syndicate-lang/compiler": "^0.22.3",
|
||||
"@syndicate-lang/core": "^0.34.8",
|
||||
"glob": "^7.1.6",
|
||||
"yargs": "^16.2.0"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@syndicate-lang/ws-relay",
|
||||
"version": "0.36.1",
|
||||
"version": "0.36.8",
|
||||
"description": "Browser WebSocket relay to a Syndicate server",
|
||||
"homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/ws-relay",
|
||||
"license": "GPL-3.0+",
|
||||
|
@ -28,11 +28,10 @@
|
|||
"@preserves/core": "^0.995.200"
|
||||
},
|
||||
"dependencies": {
|
||||
"@syndicate-lang/core": "^0.34.1",
|
||||
"salty-crypto": "0.3"
|
||||
"@syndicate-lang/core": "^0.34.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@syndicate-lang/ts-plugin": "^0.36.1",
|
||||
"@syndicate-lang/tsc": "^0.36.1"
|
||||
"@syndicate-lang/ts-plugin": "^0.36.8",
|
||||
"@syndicate-lang/tsc": "^0.36.8"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,14 +24,15 @@ import {
|
|||
stringify,
|
||||
underlying,
|
||||
Embeddable,
|
||||
SaltyCrypto,
|
||||
} from "@syndicate-lang/core";
|
||||
import G = Schemas.gatekeeper;
|
||||
import S = Schemas.sturdy;
|
||||
import N = Schemas.noise;
|
||||
import T = Schemas.transportAddress;
|
||||
import E = Schemas.stdenv;
|
||||
import * as SaltyCrypto from 'salty-crypto';
|
||||
export * as SaltyCrypto from 'salty-crypto';
|
||||
|
||||
export * from './seal.js';
|
||||
|
||||
type TransportState = {
|
||||
addr: T.WebSocket,
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
/// SPDX-FileCopyrightText: Copyright © 2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||
|
||||
import { Bytes, Value, encode, decode, isEmbedded, isSequence } from "@preserves/core";
|
||||
import { SaltyCrypto, Ref } from "@syndicate-lang/core";
|
||||
|
||||
const aead = SaltyCrypto.ChaCha20Poly1305_RFC8439;
|
||||
|
||||
export type Sealed = [Bytes, number, number, number];
|
||||
|
||||
export function makeSeal() {
|
||||
const key = new DataView(SaltyCrypto.randomBytes(aead.KEYBYTES).buffer);
|
||||
const n = new SaltyCrypto.Nonce();
|
||||
return {
|
||||
seal(v: Value<Ref>): Promise<Sealed> {
|
||||
return new Promise(k => {
|
||||
at this.sealer {
|
||||
send message [v, create ({
|
||||
message(reply) { k(reply as Sealed); }
|
||||
})];
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
unseal(sealed: Sealed): Promise<{ ok: true, value: Value } | { ok: false }> {
|
||||
return new Promise(k => {
|
||||
at this.unsealer {
|
||||
send message [sealed, create ({
|
||||
message(reply) { k(reply as any); }
|
||||
})];
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
sealer: create ({
|
||||
message(req) {
|
||||
if (isSequence(req) && req.length === 2 && isEmbedded(req[1])) {
|
||||
try {
|
||||
const [term, k] = req;
|
||||
const m = encode(term);
|
||||
const c = aead.encrypt(m._view, key, n);
|
||||
at k { send message [Bytes.from(c), n.lo, n.hi, n.extra]; }
|
||||
n.increment();
|
||||
} catch (_e) { console.error('Failed sealing: ' + _e); }
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
unsealer: create ({
|
||||
message(req) {
|
||||
if (
|
||||
isSequence(req) && req.length === 2 && isEmbedded(req[1]) &&
|
||||
isSequence(req[0]) && req[0].length === 4 &&
|
||||
Bytes.isBytes(req[0][0]) &&
|
||||
typeof req[0][1] === 'number' &&
|
||||
typeof req[0][2] === 'number' &&
|
||||
typeof req[0][3] === 'number'
|
||||
) {
|
||||
const [[c, lo, hi, extra], k] = req;
|
||||
try {
|
||||
const n = new SaltyCrypto.Nonce(lo, hi, extra);
|
||||
const m = aead.decrypt(c._view, key, n);
|
||||
at k { send message { ok: true, value: decode(Bytes.from(m)) }; }
|
||||
} catch (e) {
|
||||
at k { send message { ok: false }; }
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue