Make local graph execution optional across composed packages
This commit is contained in:
@@ -5,6 +5,7 @@ import type { StructuralRequest } from "./structural-plan.js";
|
||||
import { parseQx, walkSyntax } from "./source.js";
|
||||
import { addImplementation } from "./implementation-edit.js";
|
||||
import { formatQuixosLock } from "../resource-lock/index.js";
|
||||
import { javascriptTarget } from "../execution-world/native-backends.js";
|
||||
const json = (value: unknown) => JSON.stringify(value, null, 2) + "\n";
|
||||
const q = (value: string) => JSON.stringify(value);
|
||||
const nixString = (value: string) => q(value).replaceAll("${", "\\${");
|
||||
@@ -31,7 +32,10 @@ export async function executionScaffold(
|
||||
const create = (file: string, content: string) => files.push({ file: prefix + file, create: content });
|
||||
if (command === "package") {
|
||||
if (!spec.tools || !spec.revision) throw new Error("Execution package requires exact tool sources and a revision");
|
||||
create("package.qx", `package ${spec.name} id ${q(spec.id)} revision ${q(spec.revision)} {\n}\n`);
|
||||
create(
|
||||
"package.qx",
|
||||
`symbol JavaScript id ${q(javascriptTarget)};\npackage ${spec.name} id ${q(spec.id)} revision ${q(spec.revision)} {\n}\n`,
|
||||
);
|
||||
create(
|
||||
"quixos.lock",
|
||||
formatQuixosLock({ formatVersion: 1, quixos: { resolver: "git", ...spec.tools.quixos }, resources: [] }),
|
||||
@@ -90,7 +94,7 @@ in camino.assembleCaminoPackage {
|
||||
pkgs.lib.optional (portable != []) (camino.mkCaminoTypeScriptPackage {
|
||||
inherit pkgs context dependencies; src = ./.;
|
||||
entry = "src/server.ts"; entries.browser = "src/browser.ts";
|
||||
targets = pkgs.lib.unique (pkgs.lib.concatMap (entry: entry.execution.targets) portable);
|
||||
targets = pkgs.lib.unique (map (target: if target == "target:org.quixos.execution.javascript@1" then "browser" else if target == "server" then "server" else throw "Unsupported TypeScript backend target") (pkgs.lib.concatMap (entry: entry.execution.targets) portable));
|
||||
}) ++ pkgs.lib.optional (remote != []) (camino.mkCaminoTypeScriptService {
|
||||
inherit pkgs context dependencies; src = ./.; entry = "src/remote.ts";
|
||||
}) ++ pkgs.lib.optional (modules != {}) (camino.mkCaminoReactPackage {
|
||||
@@ -134,15 +138,16 @@ in camino.assembleCaminoPackage {
|
||||
.filter((token) => !token.trivia && token.start >= execution.start && token.end <= execution.end)
|
||||
.map((token) => token.text);
|
||||
const remote = tokens[1] === "remote";
|
||||
const targets = remote
|
||||
const declaredTargets = remote
|
||||
? ["remote"]
|
||||
: [...walkSyntax(execution)].filter((node) => node.kind === "identifier").map(text);
|
||||
const targets = declaredTargets.length ? declaredTargets : ["server"];
|
||||
if (
|
||||
!targets.length ||
|
||||
new Set(targets).size !== targets.length ||
|
||||
targets.some((target) => !(remote ? ["remote"] : ["browser", "server"]).includes(target))
|
||||
targets.some((target) => !(remote ? ["remote"] : ["JavaScript", "server"]).includes(target))
|
||||
)
|
||||
throw new Error("Execution scaffold supports browser/server portable targets and remote service handlers");
|
||||
throw new Error("This TypeScript scaffold supports the JavaScript target, server, and remote service handlers");
|
||||
const authored = await fs.readFile(path.join(root, prefix, "package.qx"), "utf8");
|
||||
const syntax = parseQx(authored);
|
||||
const packageNode = syntax.root.children.find((node) => node.kind === "packageResourceDecl");
|
||||
@@ -174,7 +179,7 @@ in camino.assembleCaminoPackage {
|
||||
`import type { ${remote ? "Remote" : "Portable"}Implementation } from "../gen/${remote ? "remote" : "qx"}.js";\nexport const handler: ${remote ? "Remote" : "Portable"}Implementation[${q(spec.name)}] = async (_context) => { throw new Error(${q("Implement " + spec.name)}); };\n`,
|
||||
);
|
||||
for (const target of targets) {
|
||||
const file = prefix + `src/${target}.ts`;
|
||||
const file = prefix + `src/${target === "JavaScript" ? "browser" : target}.ts`;
|
||||
const before = await fs.readFile(path.join(root, file), "utf8");
|
||||
files.push({
|
||||
file,
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -42,120 +42,121 @@ REF=41
|
||||
FRAGMENT=42
|
||||
IMPORT=43
|
||||
EXTERNAL=44
|
||||
ATOM=45
|
||||
INTERFACE=46
|
||||
INTERFACES=47
|
||||
PACKAGE=48
|
||||
VALUE=49
|
||||
FIELD=50
|
||||
RELATION=51
|
||||
OPERATION=52
|
||||
FUNCTION=53
|
||||
CONSTRUCTOR=54
|
||||
CONSTRUCTS=55
|
||||
INPUT=56
|
||||
CONFORM=57
|
||||
AS=58
|
||||
BIND=59
|
||||
STATIC=60
|
||||
TO=61
|
||||
PRIVATE=62
|
||||
SHARED=63
|
||||
STATE=64
|
||||
EDGE=65
|
||||
PROJECTION=66
|
||||
WITH=67
|
||||
USING=68
|
||||
ACCEPT=69
|
||||
VIA=70
|
||||
MATERIALIZE=71
|
||||
IF=72
|
||||
ABSENT=73
|
||||
ON=74
|
||||
POLICY=75
|
||||
DEFAULT=76
|
||||
SOURCE=77
|
||||
REPOSITORY=78
|
||||
COMMIT=79
|
||||
REVISION=80
|
||||
SEMANTIC_MAJOR=81
|
||||
ON_DELETE=82
|
||||
LIFECYCLE=83
|
||||
JOURNAL=84
|
||||
SUBSCRIPTION=85
|
||||
RETAIN_OTHER=86
|
||||
KEYED=87
|
||||
PUBLIC_TRAVERSAL=88
|
||||
ID=89
|
||||
DOC=90
|
||||
MODE=91
|
||||
EMITS=92
|
||||
RECEIVER=93
|
||||
REQUIRES=94
|
||||
ANY=95
|
||||
GET=96
|
||||
SET=97
|
||||
WATCH=98
|
||||
START=99
|
||||
STOP=100
|
||||
READ=101
|
||||
WRITE=102
|
||||
RESOLVE=103
|
||||
CONNECT=104
|
||||
DISCONNECT=105
|
||||
CALL=106
|
||||
WATCH_START=107
|
||||
WATCH_STOP=108
|
||||
SUBSCRIBE=109
|
||||
UNSUBSCRIBE=110
|
||||
REGISTER=111
|
||||
CRDT=112
|
||||
OPTIONAL_ONE=113
|
||||
EXACTLY_ONE=114
|
||||
MANY_UNIQUE=115
|
||||
MANY=116
|
||||
ORDERED=117
|
||||
UNIT=118
|
||||
WATCH_HANDLE=119
|
||||
MESSAGE=120
|
||||
ATOM_REF=121
|
||||
INTERFACE_REF=122
|
||||
OPTIONAL=123
|
||||
LIST=124
|
||||
RECORD=125
|
||||
BOOL=126
|
||||
BYTES=127
|
||||
DOUBLE=128
|
||||
INT32=129
|
||||
INT64=130
|
||||
STRING=131
|
||||
UINT32=132
|
||||
UINT64=133
|
||||
TRUE=134
|
||||
FALSE=135
|
||||
NULL=136
|
||||
ARROW=137
|
||||
COLON=138
|
||||
SEMI=139
|
||||
COMMA=140
|
||||
DOT=141
|
||||
LBRACE=142
|
||||
RBRACE=143
|
||||
LBRACK=144
|
||||
RBRACK=145
|
||||
LPAREN=146
|
||||
RPAREN=147
|
||||
LT=148
|
||||
GT=149
|
||||
AMP=150
|
||||
EQUAL=151
|
||||
INTEGER=152
|
||||
JSON_NUMBER=153
|
||||
IDENTIFIER=154
|
||||
STRING_LITERAL=155
|
||||
LINE_COMMENT=156
|
||||
BLOCK_COMMENT=157
|
||||
WS=158
|
||||
SYMBOL=45
|
||||
ATOM=46
|
||||
INTERFACE=47
|
||||
INTERFACES=48
|
||||
PACKAGE=49
|
||||
VALUE=50
|
||||
FIELD=51
|
||||
RELATION=52
|
||||
OPERATION=53
|
||||
FUNCTION=54
|
||||
CONSTRUCTOR=55
|
||||
CONSTRUCTS=56
|
||||
INPUT=57
|
||||
CONFORM=58
|
||||
AS=59
|
||||
BIND=60
|
||||
STATIC=61
|
||||
TO=62
|
||||
PRIVATE=63
|
||||
SHARED=64
|
||||
STATE=65
|
||||
EDGE=66
|
||||
PROJECTION=67
|
||||
WITH=68
|
||||
USING=69
|
||||
ACCEPT=70
|
||||
VIA=71
|
||||
MATERIALIZE=72
|
||||
IF=73
|
||||
ABSENT=74
|
||||
ON=75
|
||||
POLICY=76
|
||||
DEFAULT=77
|
||||
SOURCE=78
|
||||
REPOSITORY=79
|
||||
COMMIT=80
|
||||
REVISION=81
|
||||
SEMANTIC_MAJOR=82
|
||||
ON_DELETE=83
|
||||
LIFECYCLE=84
|
||||
JOURNAL=85
|
||||
SUBSCRIPTION=86
|
||||
RETAIN_OTHER=87
|
||||
KEYED=88
|
||||
PUBLIC_TRAVERSAL=89
|
||||
ID=90
|
||||
DOC=91
|
||||
MODE=92
|
||||
EMITS=93
|
||||
RECEIVER=94
|
||||
REQUIRES=95
|
||||
ANY=96
|
||||
GET=97
|
||||
SET=98
|
||||
WATCH=99
|
||||
START=100
|
||||
STOP=101
|
||||
READ=102
|
||||
WRITE=103
|
||||
RESOLVE=104
|
||||
CONNECT=105
|
||||
DISCONNECT=106
|
||||
CALL=107
|
||||
WATCH_START=108
|
||||
WATCH_STOP=109
|
||||
SUBSCRIBE=110
|
||||
UNSUBSCRIBE=111
|
||||
REGISTER=112
|
||||
CRDT=113
|
||||
OPTIONAL_ONE=114
|
||||
EXACTLY_ONE=115
|
||||
MANY_UNIQUE=116
|
||||
MANY=117
|
||||
ORDERED=118
|
||||
UNIT=119
|
||||
WATCH_HANDLE=120
|
||||
MESSAGE=121
|
||||
ATOM_REF=122
|
||||
INTERFACE_REF=123
|
||||
OPTIONAL=124
|
||||
LIST=125
|
||||
RECORD=126
|
||||
BOOL=127
|
||||
BYTES=128
|
||||
DOUBLE=129
|
||||
INT32=130
|
||||
INT64=131
|
||||
STRING=132
|
||||
UINT32=133
|
||||
UINT64=134
|
||||
TRUE=135
|
||||
FALSE=136
|
||||
NULL=137
|
||||
ARROW=138
|
||||
COLON=139
|
||||
SEMI=140
|
||||
COMMA=141
|
||||
DOT=142
|
||||
LBRACE=143
|
||||
RBRACE=144
|
||||
LBRACK=145
|
||||
RBRACK=146
|
||||
LPAREN=147
|
||||
RPAREN=148
|
||||
LT=149
|
||||
GT=150
|
||||
AMP=151
|
||||
EQUAL=152
|
||||
INTEGER=153
|
||||
JSON_NUMBER=154
|
||||
IDENTIFIER=155
|
||||
STRING_LITERAL=156
|
||||
LINE_COMMENT=157
|
||||
BLOCK_COMMENT=158
|
||||
WS=159
|
||||
'edit'=1
|
||||
'module'=2
|
||||
'contract'=3
|
||||
@@ -200,110 +201,111 @@ WS=158
|
||||
'fragment'=42
|
||||
'import'=43
|
||||
'external'=44
|
||||
'atom'=45
|
||||
'interface'=46
|
||||
'interfaces'=47
|
||||
'package'=48
|
||||
'value'=49
|
||||
'field'=50
|
||||
'relation'=51
|
||||
'operation'=52
|
||||
'function'=53
|
||||
'constructor'=54
|
||||
'constructs'=55
|
||||
'input'=56
|
||||
'conform'=57
|
||||
'as'=58
|
||||
'bind'=59
|
||||
'static'=60
|
||||
'to'=61
|
||||
'private'=62
|
||||
'shared'=63
|
||||
'state'=64
|
||||
'edge'=65
|
||||
'projection'=66
|
||||
'with'=67
|
||||
'using'=68
|
||||
'accept'=69
|
||||
'via'=70
|
||||
'materialize'=71
|
||||
'if'=72
|
||||
'absent'=73
|
||||
'on'=74
|
||||
'policy'=75
|
||||
'default'=76
|
||||
'source'=77
|
||||
'repository'=78
|
||||
'commit'=79
|
||||
'revision'=80
|
||||
'semantic-major'=81
|
||||
'on-delete'=82
|
||||
'lifecycle'=83
|
||||
'journal'=84
|
||||
'subscription'=85
|
||||
'retain-other'=86
|
||||
'keyed'=87
|
||||
'public-traversal'=88
|
||||
'id'=89
|
||||
'doc'=90
|
||||
'mode'=91
|
||||
'emits'=92
|
||||
'receiver'=93
|
||||
'requires'=94
|
||||
'any'=95
|
||||
'get'=96
|
||||
'set'=97
|
||||
'watch'=98
|
||||
'start'=99
|
||||
'stop'=100
|
||||
'read'=101
|
||||
'write'=102
|
||||
'resolve'=103
|
||||
'connect'=104
|
||||
'disconnect'=105
|
||||
'call'=106
|
||||
'watch-start'=107
|
||||
'watch-stop'=108
|
||||
'subscribe'=109
|
||||
'unsubscribe'=110
|
||||
'register'=111
|
||||
'crdt'=112
|
||||
'optional-one'=113
|
||||
'exactly-one'=114
|
||||
'many-unique'=115
|
||||
'many'=116
|
||||
'ordered'=117
|
||||
'unit'=118
|
||||
'watch-handle'=119
|
||||
'message'=120
|
||||
'atom-ref'=121
|
||||
'interface-ref'=122
|
||||
'optional'=123
|
||||
'list'=124
|
||||
'record'=125
|
||||
'bool'=126
|
||||
'bytes'=127
|
||||
'double'=128
|
||||
'int32'=129
|
||||
'int64'=130
|
||||
'string'=131
|
||||
'uint32'=132
|
||||
'uint64'=133
|
||||
'true'=134
|
||||
'false'=135
|
||||
'null'=136
|
||||
'->'=137
|
||||
':'=138
|
||||
';'=139
|
||||
','=140
|
||||
'.'=141
|
||||
'{'=142
|
||||
'}'=143
|
||||
'['=144
|
||||
']'=145
|
||||
'('=146
|
||||
')'=147
|
||||
'<'=148
|
||||
'>'=149
|
||||
'&'=150
|
||||
'='=151
|
||||
'symbol'=45
|
||||
'atom'=46
|
||||
'interface'=47
|
||||
'interfaces'=48
|
||||
'package'=49
|
||||
'value'=50
|
||||
'field'=51
|
||||
'relation'=52
|
||||
'operation'=53
|
||||
'function'=54
|
||||
'constructor'=55
|
||||
'constructs'=56
|
||||
'input'=57
|
||||
'conform'=58
|
||||
'as'=59
|
||||
'bind'=60
|
||||
'static'=61
|
||||
'to'=62
|
||||
'private'=63
|
||||
'shared'=64
|
||||
'state'=65
|
||||
'edge'=66
|
||||
'projection'=67
|
||||
'with'=68
|
||||
'using'=69
|
||||
'accept'=70
|
||||
'via'=71
|
||||
'materialize'=72
|
||||
'if'=73
|
||||
'absent'=74
|
||||
'on'=75
|
||||
'policy'=76
|
||||
'default'=77
|
||||
'source'=78
|
||||
'repository'=79
|
||||
'commit'=80
|
||||
'revision'=81
|
||||
'semantic-major'=82
|
||||
'on-delete'=83
|
||||
'lifecycle'=84
|
||||
'journal'=85
|
||||
'subscription'=86
|
||||
'retain-other'=87
|
||||
'keyed'=88
|
||||
'public-traversal'=89
|
||||
'id'=90
|
||||
'doc'=91
|
||||
'mode'=92
|
||||
'emits'=93
|
||||
'receiver'=94
|
||||
'requires'=95
|
||||
'any'=96
|
||||
'get'=97
|
||||
'set'=98
|
||||
'watch'=99
|
||||
'start'=100
|
||||
'stop'=101
|
||||
'read'=102
|
||||
'write'=103
|
||||
'resolve'=104
|
||||
'connect'=105
|
||||
'disconnect'=106
|
||||
'call'=107
|
||||
'watch-start'=108
|
||||
'watch-stop'=109
|
||||
'subscribe'=110
|
||||
'unsubscribe'=111
|
||||
'register'=112
|
||||
'crdt'=113
|
||||
'optional-one'=114
|
||||
'exactly-one'=115
|
||||
'many-unique'=116
|
||||
'many'=117
|
||||
'ordered'=118
|
||||
'unit'=119
|
||||
'watch-handle'=120
|
||||
'message'=121
|
||||
'atom-ref'=122
|
||||
'interface-ref'=123
|
||||
'optional'=124
|
||||
'list'=125
|
||||
'record'=126
|
||||
'bool'=127
|
||||
'bytes'=128
|
||||
'double'=129
|
||||
'int32'=130
|
||||
'int64'=131
|
||||
'string'=132
|
||||
'uint32'=133
|
||||
'uint64'=134
|
||||
'true'=135
|
||||
'false'=136
|
||||
'null'=137
|
||||
'->'=138
|
||||
':'=139
|
||||
';'=140
|
||||
','=141
|
||||
'.'=142
|
||||
'{'=143
|
||||
'}'=144
|
||||
'['=145
|
||||
']'=146
|
||||
'('=147
|
||||
')'=148
|
||||
'<'=149
|
||||
'>'=150
|
||||
'&'=151
|
||||
'='=152
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -42,120 +42,121 @@ REF=41
|
||||
FRAGMENT=42
|
||||
IMPORT=43
|
||||
EXTERNAL=44
|
||||
ATOM=45
|
||||
INTERFACE=46
|
||||
INTERFACES=47
|
||||
PACKAGE=48
|
||||
VALUE=49
|
||||
FIELD=50
|
||||
RELATION=51
|
||||
OPERATION=52
|
||||
FUNCTION=53
|
||||
CONSTRUCTOR=54
|
||||
CONSTRUCTS=55
|
||||
INPUT=56
|
||||
CONFORM=57
|
||||
AS=58
|
||||
BIND=59
|
||||
STATIC=60
|
||||
TO=61
|
||||
PRIVATE=62
|
||||
SHARED=63
|
||||
STATE=64
|
||||
EDGE=65
|
||||
PROJECTION=66
|
||||
WITH=67
|
||||
USING=68
|
||||
ACCEPT=69
|
||||
VIA=70
|
||||
MATERIALIZE=71
|
||||
IF=72
|
||||
ABSENT=73
|
||||
ON=74
|
||||
POLICY=75
|
||||
DEFAULT=76
|
||||
SOURCE=77
|
||||
REPOSITORY=78
|
||||
COMMIT=79
|
||||
REVISION=80
|
||||
SEMANTIC_MAJOR=81
|
||||
ON_DELETE=82
|
||||
LIFECYCLE=83
|
||||
JOURNAL=84
|
||||
SUBSCRIPTION=85
|
||||
RETAIN_OTHER=86
|
||||
KEYED=87
|
||||
PUBLIC_TRAVERSAL=88
|
||||
ID=89
|
||||
DOC=90
|
||||
MODE=91
|
||||
EMITS=92
|
||||
RECEIVER=93
|
||||
REQUIRES=94
|
||||
ANY=95
|
||||
GET=96
|
||||
SET=97
|
||||
WATCH=98
|
||||
START=99
|
||||
STOP=100
|
||||
READ=101
|
||||
WRITE=102
|
||||
RESOLVE=103
|
||||
CONNECT=104
|
||||
DISCONNECT=105
|
||||
CALL=106
|
||||
WATCH_START=107
|
||||
WATCH_STOP=108
|
||||
SUBSCRIBE=109
|
||||
UNSUBSCRIBE=110
|
||||
REGISTER=111
|
||||
CRDT=112
|
||||
OPTIONAL_ONE=113
|
||||
EXACTLY_ONE=114
|
||||
MANY_UNIQUE=115
|
||||
MANY=116
|
||||
ORDERED=117
|
||||
UNIT=118
|
||||
WATCH_HANDLE=119
|
||||
MESSAGE=120
|
||||
ATOM_REF=121
|
||||
INTERFACE_REF=122
|
||||
OPTIONAL=123
|
||||
LIST=124
|
||||
RECORD=125
|
||||
BOOL=126
|
||||
BYTES=127
|
||||
DOUBLE=128
|
||||
INT32=129
|
||||
INT64=130
|
||||
STRING=131
|
||||
UINT32=132
|
||||
UINT64=133
|
||||
TRUE=134
|
||||
FALSE=135
|
||||
NULL=136
|
||||
ARROW=137
|
||||
COLON=138
|
||||
SEMI=139
|
||||
COMMA=140
|
||||
DOT=141
|
||||
LBRACE=142
|
||||
RBRACE=143
|
||||
LBRACK=144
|
||||
RBRACK=145
|
||||
LPAREN=146
|
||||
RPAREN=147
|
||||
LT=148
|
||||
GT=149
|
||||
AMP=150
|
||||
EQUAL=151
|
||||
INTEGER=152
|
||||
JSON_NUMBER=153
|
||||
IDENTIFIER=154
|
||||
STRING_LITERAL=155
|
||||
LINE_COMMENT=156
|
||||
BLOCK_COMMENT=157
|
||||
WS=158
|
||||
SYMBOL=45
|
||||
ATOM=46
|
||||
INTERFACE=47
|
||||
INTERFACES=48
|
||||
PACKAGE=49
|
||||
VALUE=50
|
||||
FIELD=51
|
||||
RELATION=52
|
||||
OPERATION=53
|
||||
FUNCTION=54
|
||||
CONSTRUCTOR=55
|
||||
CONSTRUCTS=56
|
||||
INPUT=57
|
||||
CONFORM=58
|
||||
AS=59
|
||||
BIND=60
|
||||
STATIC=61
|
||||
TO=62
|
||||
PRIVATE=63
|
||||
SHARED=64
|
||||
STATE=65
|
||||
EDGE=66
|
||||
PROJECTION=67
|
||||
WITH=68
|
||||
USING=69
|
||||
ACCEPT=70
|
||||
VIA=71
|
||||
MATERIALIZE=72
|
||||
IF=73
|
||||
ABSENT=74
|
||||
ON=75
|
||||
POLICY=76
|
||||
DEFAULT=77
|
||||
SOURCE=78
|
||||
REPOSITORY=79
|
||||
COMMIT=80
|
||||
REVISION=81
|
||||
SEMANTIC_MAJOR=82
|
||||
ON_DELETE=83
|
||||
LIFECYCLE=84
|
||||
JOURNAL=85
|
||||
SUBSCRIPTION=86
|
||||
RETAIN_OTHER=87
|
||||
KEYED=88
|
||||
PUBLIC_TRAVERSAL=89
|
||||
ID=90
|
||||
DOC=91
|
||||
MODE=92
|
||||
EMITS=93
|
||||
RECEIVER=94
|
||||
REQUIRES=95
|
||||
ANY=96
|
||||
GET=97
|
||||
SET=98
|
||||
WATCH=99
|
||||
START=100
|
||||
STOP=101
|
||||
READ=102
|
||||
WRITE=103
|
||||
RESOLVE=104
|
||||
CONNECT=105
|
||||
DISCONNECT=106
|
||||
CALL=107
|
||||
WATCH_START=108
|
||||
WATCH_STOP=109
|
||||
SUBSCRIBE=110
|
||||
UNSUBSCRIBE=111
|
||||
REGISTER=112
|
||||
CRDT=113
|
||||
OPTIONAL_ONE=114
|
||||
EXACTLY_ONE=115
|
||||
MANY_UNIQUE=116
|
||||
MANY=117
|
||||
ORDERED=118
|
||||
UNIT=119
|
||||
WATCH_HANDLE=120
|
||||
MESSAGE=121
|
||||
ATOM_REF=122
|
||||
INTERFACE_REF=123
|
||||
OPTIONAL=124
|
||||
LIST=125
|
||||
RECORD=126
|
||||
BOOL=127
|
||||
BYTES=128
|
||||
DOUBLE=129
|
||||
INT32=130
|
||||
INT64=131
|
||||
STRING=132
|
||||
UINT32=133
|
||||
UINT64=134
|
||||
TRUE=135
|
||||
FALSE=136
|
||||
NULL=137
|
||||
ARROW=138
|
||||
COLON=139
|
||||
SEMI=140
|
||||
COMMA=141
|
||||
DOT=142
|
||||
LBRACE=143
|
||||
RBRACE=144
|
||||
LBRACK=145
|
||||
RBRACK=146
|
||||
LPAREN=147
|
||||
RPAREN=148
|
||||
LT=149
|
||||
GT=150
|
||||
AMP=151
|
||||
EQUAL=152
|
||||
INTEGER=153
|
||||
JSON_NUMBER=154
|
||||
IDENTIFIER=155
|
||||
STRING_LITERAL=156
|
||||
LINE_COMMENT=157
|
||||
BLOCK_COMMENT=158
|
||||
WS=159
|
||||
'edit'=1
|
||||
'module'=2
|
||||
'contract'=3
|
||||
@@ -200,110 +201,111 @@ WS=158
|
||||
'fragment'=42
|
||||
'import'=43
|
||||
'external'=44
|
||||
'atom'=45
|
||||
'interface'=46
|
||||
'interfaces'=47
|
||||
'package'=48
|
||||
'value'=49
|
||||
'field'=50
|
||||
'relation'=51
|
||||
'operation'=52
|
||||
'function'=53
|
||||
'constructor'=54
|
||||
'constructs'=55
|
||||
'input'=56
|
||||
'conform'=57
|
||||
'as'=58
|
||||
'bind'=59
|
||||
'static'=60
|
||||
'to'=61
|
||||
'private'=62
|
||||
'shared'=63
|
||||
'state'=64
|
||||
'edge'=65
|
||||
'projection'=66
|
||||
'with'=67
|
||||
'using'=68
|
||||
'accept'=69
|
||||
'via'=70
|
||||
'materialize'=71
|
||||
'if'=72
|
||||
'absent'=73
|
||||
'on'=74
|
||||
'policy'=75
|
||||
'default'=76
|
||||
'source'=77
|
||||
'repository'=78
|
||||
'commit'=79
|
||||
'revision'=80
|
||||
'semantic-major'=81
|
||||
'on-delete'=82
|
||||
'lifecycle'=83
|
||||
'journal'=84
|
||||
'subscription'=85
|
||||
'retain-other'=86
|
||||
'keyed'=87
|
||||
'public-traversal'=88
|
||||
'id'=89
|
||||
'doc'=90
|
||||
'mode'=91
|
||||
'emits'=92
|
||||
'receiver'=93
|
||||
'requires'=94
|
||||
'any'=95
|
||||
'get'=96
|
||||
'set'=97
|
||||
'watch'=98
|
||||
'start'=99
|
||||
'stop'=100
|
||||
'read'=101
|
||||
'write'=102
|
||||
'resolve'=103
|
||||
'connect'=104
|
||||
'disconnect'=105
|
||||
'call'=106
|
||||
'watch-start'=107
|
||||
'watch-stop'=108
|
||||
'subscribe'=109
|
||||
'unsubscribe'=110
|
||||
'register'=111
|
||||
'crdt'=112
|
||||
'optional-one'=113
|
||||
'exactly-one'=114
|
||||
'many-unique'=115
|
||||
'many'=116
|
||||
'ordered'=117
|
||||
'unit'=118
|
||||
'watch-handle'=119
|
||||
'message'=120
|
||||
'atom-ref'=121
|
||||
'interface-ref'=122
|
||||
'optional'=123
|
||||
'list'=124
|
||||
'record'=125
|
||||
'bool'=126
|
||||
'bytes'=127
|
||||
'double'=128
|
||||
'int32'=129
|
||||
'int64'=130
|
||||
'string'=131
|
||||
'uint32'=132
|
||||
'uint64'=133
|
||||
'true'=134
|
||||
'false'=135
|
||||
'null'=136
|
||||
'->'=137
|
||||
':'=138
|
||||
';'=139
|
||||
','=140
|
||||
'.'=141
|
||||
'{'=142
|
||||
'}'=143
|
||||
'['=144
|
||||
']'=145
|
||||
'('=146
|
||||
')'=147
|
||||
'<'=148
|
||||
'>'=149
|
||||
'&'=150
|
||||
'='=151
|
||||
'symbol'=45
|
||||
'atom'=46
|
||||
'interface'=47
|
||||
'interfaces'=48
|
||||
'package'=49
|
||||
'value'=50
|
||||
'field'=51
|
||||
'relation'=52
|
||||
'operation'=53
|
||||
'function'=54
|
||||
'constructor'=55
|
||||
'constructs'=56
|
||||
'input'=57
|
||||
'conform'=58
|
||||
'as'=59
|
||||
'bind'=60
|
||||
'static'=61
|
||||
'to'=62
|
||||
'private'=63
|
||||
'shared'=64
|
||||
'state'=65
|
||||
'edge'=66
|
||||
'projection'=67
|
||||
'with'=68
|
||||
'using'=69
|
||||
'accept'=70
|
||||
'via'=71
|
||||
'materialize'=72
|
||||
'if'=73
|
||||
'absent'=74
|
||||
'on'=75
|
||||
'policy'=76
|
||||
'default'=77
|
||||
'source'=78
|
||||
'repository'=79
|
||||
'commit'=80
|
||||
'revision'=81
|
||||
'semantic-major'=82
|
||||
'on-delete'=83
|
||||
'lifecycle'=84
|
||||
'journal'=85
|
||||
'subscription'=86
|
||||
'retain-other'=87
|
||||
'keyed'=88
|
||||
'public-traversal'=89
|
||||
'id'=90
|
||||
'doc'=91
|
||||
'mode'=92
|
||||
'emits'=93
|
||||
'receiver'=94
|
||||
'requires'=95
|
||||
'any'=96
|
||||
'get'=97
|
||||
'set'=98
|
||||
'watch'=99
|
||||
'start'=100
|
||||
'stop'=101
|
||||
'read'=102
|
||||
'write'=103
|
||||
'resolve'=104
|
||||
'connect'=105
|
||||
'disconnect'=106
|
||||
'call'=107
|
||||
'watch-start'=108
|
||||
'watch-stop'=109
|
||||
'subscribe'=110
|
||||
'unsubscribe'=111
|
||||
'register'=112
|
||||
'crdt'=113
|
||||
'optional-one'=114
|
||||
'exactly-one'=115
|
||||
'many-unique'=116
|
||||
'many'=117
|
||||
'ordered'=118
|
||||
'unit'=119
|
||||
'watch-handle'=120
|
||||
'message'=121
|
||||
'atom-ref'=122
|
||||
'interface-ref'=123
|
||||
'optional'=124
|
||||
'list'=125
|
||||
'record'=126
|
||||
'bool'=127
|
||||
'bytes'=128
|
||||
'double'=129
|
||||
'int32'=130
|
||||
'int64'=131
|
||||
'string'=132
|
||||
'uint32'=133
|
||||
'uint64'=134
|
||||
'true'=135
|
||||
'false'=136
|
||||
'null'=137
|
||||
'->'=138
|
||||
':'=139
|
||||
';'=140
|
||||
','=141
|
||||
'.'=142
|
||||
'{'=143
|
||||
'}'=144
|
||||
'['=145
|
||||
']'=146
|
||||
'('=147
|
||||
')'=148
|
||||
'<'=149
|
||||
'>'=150
|
||||
'&'=151
|
||||
'='=152
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,7 @@ import { WorkspaceItemContext } from "./QuixosCapabilityParser.js";
|
||||
import { ResourceImportDeclContext } from "./QuixosCapabilityParser.js";
|
||||
import { ExternalAtomDeclContext } from "./QuixosCapabilityParser.js";
|
||||
import { ExternalInterfaceDeclContext } from "./QuixosCapabilityParser.js";
|
||||
import { SymbolDeclContext } from "./QuixosCapabilityParser.js";
|
||||
import { ResourcePreambleContext } from "./QuixosCapabilityParser.js";
|
||||
import { AtomDeclContext } from "./QuixosCapabilityParser.js";
|
||||
import { InterfaceResourceDeclContext } from "./QuixosCapabilityParser.js";
|
||||
@@ -145,6 +146,12 @@ export class QuixosCapabilityVisitor<Result> extends AbstractParseTreeVisitor<Re
|
||||
* @return the visitor result
|
||||
*/
|
||||
visitExternalInterfaceDecl?: (ctx: ExternalInterfaceDeclContext) => Result;
|
||||
/**
|
||||
* Visit a parse tree produced by `QuixosCapabilityParser.symbolDecl`.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
visitSymbolDecl?: (ctx: SymbolDeclContext) => Result;
|
||||
/**
|
||||
* Visit a parse tree produced by `QuixosCapabilityParser.resourcePreamble`.
|
||||
* @param ctx the parse tree
|
||||
|
||||
@@ -205,6 +205,7 @@ interface LoweringState {
|
||||
fileName: string;
|
||||
diagnostics: CapabilitySourceDiagnostic[];
|
||||
atoms: Map<string, AtomId>;
|
||||
symbols: Map<string, string>;
|
||||
interfaces: Map<string, InterfaceSymbol>;
|
||||
packages: Map<string, PackageSymbol>;
|
||||
attachments: Map<string, AttachmentSymbol>;
|
||||
@@ -387,14 +388,33 @@ const lowerSelectedOperations = (
|
||||
return { operations };
|
||||
};
|
||||
|
||||
const lowerExecution = (context: ExecutionClauseContext | null): { execution?: ExecutionContract } => {
|
||||
const lowerExecution = (
|
||||
state: LoweringState,
|
||||
context: ExecutionClauseContext | null,
|
||||
implementation = false,
|
||||
): { execution?: ExecutionContract } => {
|
||||
if (!context) return {};
|
||||
if (!implementation && context.identifierList())
|
||||
loweringIssue(
|
||||
state,
|
||||
context,
|
||||
"interface-execution-targets",
|
||||
"Interfaces declare effects; execution targets belong to package implementations",
|
||||
);
|
||||
const targets = context
|
||||
.identifierList()
|
||||
?.identifier()
|
||||
.map((node) => {
|
||||
const name = identifier(node);
|
||||
if (name === "server") return name;
|
||||
return requireSymbol(state, state.symbols, name, node, "nominal execution target") ?? `unresolved:${name}`;
|
||||
}) ?? ["server"];
|
||||
return {
|
||||
execution: context.REMOTE()
|
||||
? { kind: "remote" }
|
||||
: {
|
||||
kind: context.SNAPSHOT() ? "snapshot" : "transaction",
|
||||
targets: context.identifierList()!.identifier().map(identifier),
|
||||
targets: implementation ? targets : ["server"],
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -508,17 +528,17 @@ const lowerValueMember = (state: LoweringState, context: ValueMemberContext): In
|
||||
if (operation.GET()) {
|
||||
operations.push({
|
||||
...valueOperation("get", capabilityId.operation(stringValue(operation.stringLiteral(0))), memberValueType),
|
||||
...lowerExecution(operation.executionClause()),
|
||||
...lowerExecution(state, operation.executionClause()),
|
||||
});
|
||||
} else if (operation.EDIT()) {
|
||||
operations.push({
|
||||
...valueOperation("edit", capabilityId.operation(stringValue(operation.stringLiteral(0))), memberValueType),
|
||||
...lowerExecution(operation.executionClause()),
|
||||
...lowerExecution(state, operation.executionClause()),
|
||||
});
|
||||
} else if (operation.SET()) {
|
||||
operations.push({
|
||||
...valueOperation("set", capabilityId.operation(stringValue(operation.stringLiteral(0))), memberValueType),
|
||||
...lowerExecution(operation.executionClause()),
|
||||
...lowerExecution(state, operation.executionClause()),
|
||||
});
|
||||
} else {
|
||||
operations.push(
|
||||
@@ -611,7 +631,7 @@ const lowerRelationshipMember = (
|
||||
);
|
||||
}
|
||||
if (operation.executionClause())
|
||||
Object.assign(operations[operations.length - 1]!, lowerExecution(operation.executionClause()));
|
||||
Object.assign(operations[operations.length - 1]!, lowerExecution(state, operation.executionClause()));
|
||||
}
|
||||
return {
|
||||
kind: "relationship",
|
||||
@@ -653,7 +673,7 @@ const lowerOperationMember = (state: LoweringState, context: OperationMemberCont
|
||||
outputType,
|
||||
mode: "call",
|
||||
...(context.STATIC() ? { scope: "class" as const } : {}),
|
||||
...lowerExecution(context.executionClause()),
|
||||
...lowerExecution(state, context.executionClause()),
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -814,18 +834,24 @@ const lowerInterfaceTemplate = (
|
||||
const id = capabilityId.operation(stringValue(operation.stringLiteral(0)));
|
||||
if (operation.GET())
|
||||
return [
|
||||
{ ...signature("get", id, valueType.unit, type), ...lowerExecution(operation.executionClause()) },
|
||||
{
|
||||
...signature("get", id, valueType.unit, type),
|
||||
...lowerExecution(state, operation.executionClause()),
|
||||
},
|
||||
];
|
||||
if (operation.EDIT())
|
||||
return [
|
||||
{
|
||||
...signature("edit", id, { kind: "change", value: type }, valueType.unit),
|
||||
...lowerExecution(operation.executionClause()),
|
||||
...lowerExecution(state, operation.executionClause()),
|
||||
},
|
||||
];
|
||||
if (operation.SET())
|
||||
return [
|
||||
{ ...signature("set", id, type, valueType.unit), ...lowerExecution(operation.executionClause()) },
|
||||
{
|
||||
...signature("set", id, type, valueType.unit),
|
||||
...lowerExecution(state, operation.executionClause()),
|
||||
},
|
||||
];
|
||||
return [
|
||||
signature("watch-start", id, valueType.unit, valueType.watchHandle, "watch-start", type),
|
||||
@@ -859,7 +885,7 @@ const lowerInterfaceTemplate = (
|
||||
outputType,
|
||||
),
|
||||
...(operation.STATIC() ? { scope: "class" as const } : {}),
|
||||
...lowerExecution(operation.executionClause()),
|
||||
...lowerExecution(state, operation.executionClause()),
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -907,7 +933,10 @@ const lowerInterfaceTemplate = (
|
||||
const id = capabilityId.operation(stringValue(operation.stringLiteral(0)));
|
||||
if (operation.RESOLVE())
|
||||
return [
|
||||
{ ...signature("resolve", id, valueType.unit, resolved), ...lowerExecution(operation.executionClause()) },
|
||||
{
|
||||
...signature("resolve", id, valueType.unit, resolved),
|
||||
...lowerExecution(state, operation.executionClause()),
|
||||
},
|
||||
];
|
||||
if (operation.CONNECT() || operation.DISCONNECT())
|
||||
return [
|
||||
@@ -918,7 +947,7 @@ const lowerInterfaceTemplate = (
|
||||
operation.CONNECT() ? keyedTarget : targetType,
|
||||
valueType.unit,
|
||||
),
|
||||
...lowerExecution(operation.executionClause()),
|
||||
...lowerExecution(state, operation.executionClause()),
|
||||
},
|
||||
];
|
||||
return [
|
||||
@@ -1196,7 +1225,7 @@ const lowerPackageOperation = (
|
||||
inputType: lowerValueType(state, context.valueType(0)),
|
||||
outputType: lowerValueType(state, context.valueType(1)),
|
||||
mode: text(context.operationMode()) as InterfaceOperationMode,
|
||||
...lowerExecution(context.executionClause()),
|
||||
...lowerExecution(state, context.executionClause(), true),
|
||||
eventType: event ? lowerValueType(state, event.valueType()) : undefined,
|
||||
receiverRequirement: lowerReceiver(state, context.receiverRequirement()),
|
||||
dependencyPorts: ports,
|
||||
@@ -1213,7 +1242,7 @@ const lowerPackageFunction = (
|
||||
const alias = identifier(context.identifier());
|
||||
const entry: PackageExport = {
|
||||
kind: "function",
|
||||
...lowerExecution(context.executionClause()),
|
||||
...lowerExecution(state, context.executionClause(), true),
|
||||
id: capabilityId.packageExport(stringValue(context.stringLiteral())),
|
||||
displayName: alias,
|
||||
inputType: lowerValueType(state, context.valueType(0)),
|
||||
@@ -1355,7 +1384,7 @@ const lowerGenericPackageExport = (
|
||||
displayName: identifier(context.identifier()),
|
||||
parameters,
|
||||
kind: operation ? "operation" : "function",
|
||||
...lowerExecution(context.executionClause()),
|
||||
...lowerExecution(state, context.executionClause(), true),
|
||||
inputType: state.types.expression(context.valueType(0)!),
|
||||
outputType: state.types.expression(context.valueType(1)!),
|
||||
dependencyPorts,
|
||||
@@ -3092,6 +3121,7 @@ const newLoweringState = (fileName: string, diagnostics: CapabilitySourceDiagnos
|
||||
atoms,
|
||||
types: new GenericSourceTypes(atoms),
|
||||
interfaces: new Map(),
|
||||
symbols: new Map(),
|
||||
packages: new Map(),
|
||||
attachments: new Map(),
|
||||
};
|
||||
@@ -3240,6 +3270,20 @@ const compileCapabilityResourceSourceInternal = (
|
||||
const externalAtoms = externalAtomsFrom(state, preamble.atoms);
|
||||
const imports = registerImports(state, preamble.imports, environment);
|
||||
const externalInterfaces = externalInterfacesFrom(state, preamble.interfaces);
|
||||
for (const declaration of (interfaceContext ?? packageContext)!
|
||||
.resourcePreamble()
|
||||
.flatMap((entry) => entry.symbolDecl() ?? [])) {
|
||||
const name = identifier(declaration.identifier());
|
||||
const identity = stringValue(declaration.stringLiteral());
|
||||
if (name === "server" || identity === "server" || !identity.trim())
|
||||
loweringIssue(
|
||||
state,
|
||||
declaration,
|
||||
"invalid-symbol",
|
||||
"Nominal symbols require a nonempty identity distinct from the server executor",
|
||||
);
|
||||
declareSymbol(state, state.symbols, name, identity, declaration, "symbol");
|
||||
}
|
||||
state.types.declareAliases(preamble.aliases);
|
||||
|
||||
let resource: CapabilityResource;
|
||||
|
||||
Reference in New Issue
Block a user