@oomol-lab/open-flow 0.1.0-beta.76 → 0.1.0-beta.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/browser/{ContentIcon-Cm1hbVzW.js → ContentIcon-CMn0c-kl.js} +99 -6
- package/dist/browser/{FlowCanvas-NzKtla_c.js → FlowCanvas-BQGBcfoL.js} +1709 -613
- package/dist/browser/{createResourceDialog-BgdedQqu.js → createResourceDialog-DCGxfKFM.js} +63 -57
- package/dist/browser/{dialog-aSElFFw2.js → dialog-WzR4CRFH.js} +76 -77
- package/dist/browser/{exportSvg-Dcz4HTo_.js → exportSvg-CYwyYiuH.js} +2 -2
- package/dist/browser/{flowChanges-NZyS7HSp.js → flowChanges-Bz4dbDN_.js} +6875 -11091
- package/dist/browser/{flowWorkspace-Bl0SDehy.js → flowWorkspace-BI6L6a4r.js} +1415 -3037
- package/dist/browser/licenses.md +1 -1
- package/dist/browser/preview.css +619 -462
- package/dist/browser/preview.js +9016 -14956
- package/dist/browser/theme.css +4 -2
- package/dist/browser/{tooltip-3XMK9jkr.js → tooltip-BDcVTNpu.js} +65 -2
- package/dist/browser/{typeScriptSession-C9sBGOKZ.js → typeScriptSession-CRoezJPN.js} +1 -1
- package/dist/browser/ui.css +112 -24
- package/dist/browser/ui.js +3 -2
- package/dist/browser/workbench.css +10020 -9842
- package/dist/browser/workbench.d.ts +5 -2
- package/dist/browser/workbench.js +2382 -2668
- package/dist/browser/{workbenchSelect-DBGP7Y4Z.js → workbenchSelect-DtAd0zc4.js} +2 -2
- package/dist/command/index.js +48 -48
- package/dist/common/authoring.d.ts +4 -4
- package/dist/common/authoringExamples.d.ts +3 -2
- package/dist/common/authoringSchema.d.ts +15 -4
- package/dist/common/control-api-conformance.js +155 -15
- package/dist/common/control-api-errors.d.ts +12 -0
- package/dist/common/control-api.d.ts +39 -2
- package/dist/common/control-api.js +180 -37
- package/dist/common/control-requests.d.ts +23 -3
- package/dist/common/control-requests.js +141 -14
- package/dist/common/engine-contract.d.ts +3 -2
- package/dist/common/flow-authoring.js +47 -7
- package/dist/common/flow-change-schema.d.ts +1 -1
- package/dist/common/flow-change.d.ts +2 -2
- package/dist/common/flow-change.js +48 -8
- package/dist/common/flow-encoding.js +47 -7
- package/dist/common/flow-semantics.js +86 -8
- package/dist/common/flow-state.d.ts +100 -0
- package/dist/common/flow-state.js +5794 -0
- package/dist/common/mcp.d.ts +96 -3
- package/dist/common/mcp.js +158 -13
- package/dist/common/run-events.js +19 -8
- package/dist/common/runtime-contract.d.ts +14 -0
- package/dist/common/runtime-contract.js +124 -17
- package/dist/common/runtime-nodejs-compat.js +11 -12
- package/dist/common/scheduler-node-execution.d.ts +1 -0
- package/dist/common/scheduler.d.ts +2 -1
- package/dist/common/scheduler.js +95 -40
- package/dist/common/state-conformance.d.ts +16 -0
- package/dist/common/tags.d.ts +4 -0
- package/dist/index.d.ts +11 -0
- package/package.json +5 -1
- package/src/control/common/api.ts +101 -11
- package/src/control/common/authoring.ts +7 -1
- package/src/control/common/authoringExamples.ts +9 -0
- package/src/control/common/authoringSchema.ts +18 -12
- package/src/control/common/errors.ts +6 -0
- package/src/control/common/flowDecoders.ts +1 -0
- package/src/control/common/mcp.ts +16 -0
- package/src/control/common/requests.ts +16 -2
- package/src/control/common/tags.ts +20 -0
- package/src/execution/common/events.ts +22 -7
- package/src/execution/common/node-execution.ts +3 -0
- package/src/execution/common/scheduler.ts +29 -13
- package/src/flow/common/change.ts +2 -1
- package/src/flow/common/changeSchema.ts +11 -1
- package/src/flow/common/errorHandling.ts +1 -1
- package/src/flow/common/semantics.ts +27 -1
- package/src/runtime/common/engineContract.ts +6 -3
- package/src/runtime/common/nodejsGuest.generated.json +11 -12
- package/src/runtime/common/runtime.ts +122 -7
- package/src/state/common/conformance.ts +81 -0
- package/src/state/common/state.ts +141 -0
- package/src/types/index.ts +11 -0
|
@@ -23,8 +23,8 @@ function dequal(foo, bar) {
|
|
|
23
23
|
}
|
|
24
24
|
//#endregion
|
|
25
25
|
//#region src/runtime/common/engineContract.ts
|
|
26
|
-
/**
|
|
27
|
-
var currentEngineContract = "open-flow-engine/
|
|
26
|
+
/** v10 adds persistent Flow State to the published v9 Node compatibility and fetch contract. */
|
|
27
|
+
var currentEngineContract = "open-flow-engine/v10";
|
|
28
28
|
/** The published v8 Node compatibility contract, retained for existing Publications and Runs. */
|
|
29
29
|
var nodejsEngineContract = "open-flow-engine/v8/nodejs-compat-v1";
|
|
30
30
|
var platformSource = (contract) => `export const engineContract = ${JSON.stringify(contract)}
|
|
@@ -69,13 +69,19 @@ var nodejsContract = {
|
|
|
69
69
|
].flatMap((name) => [name, `node:${name}`])),
|
|
70
70
|
platformSource: platformSource(nodejsEngineContract)
|
|
71
71
|
};
|
|
72
|
-
var
|
|
72
|
+
var v9Contract = {
|
|
73
73
|
...nodejsContract,
|
|
74
74
|
codeFetch: true,
|
|
75
|
+
platformSource: platformSource("open-flow-engine/v9")
|
|
76
|
+
};
|
|
77
|
+
var currentContract = {
|
|
78
|
+
...v9Contract,
|
|
79
|
+
flowState: true,
|
|
75
80
|
platformSource: platformSource(currentEngineContract)
|
|
76
81
|
};
|
|
77
82
|
function findEngineContract(contract) {
|
|
78
|
-
if (contract == "open-flow-engine/
|
|
83
|
+
if (contract == "open-flow-engine/v10") return currentContract;
|
|
84
|
+
if (contract == "open-flow-engine/v9") return v9Contract;
|
|
79
85
|
if (contract == "open-flow-engine/v8") return v8Contract;
|
|
80
86
|
if (contract == "open-flow-engine/v8/nodejs-compat-v1") return nodejsContract;
|
|
81
87
|
if (contract == "open-flow-engine/v7" || contract == "open-flow-engine/v7/nodejs-compat-v1") return {
|
|
@@ -95,6 +101,60 @@ function findEngineContract(contract) {
|
|
|
95
101
|
}
|
|
96
102
|
//#endregion
|
|
97
103
|
//#region src/runtime/common/runtime.ts
|
|
104
|
+
/** Serialized into the guest; keep validation and helpers self-contained. */
|
|
105
|
+
function createState(invoke) {
|
|
106
|
+
const invalid = (message) => Object.assign(new TypeError(message), { code: "capability.invalid" });
|
|
107
|
+
const keyOf = (key) => {
|
|
108
|
+
if (typeof key !== "string" || key.length === 0 || new TextEncoder().encode(key).length > 256) throw invalid("State keys require 1 to 256 UTF-8 bytes.");
|
|
109
|
+
return key;
|
|
110
|
+
};
|
|
111
|
+
const valueOf = (value) => {
|
|
112
|
+
if (value === void 0) throw invalid("State values must be JSON.");
|
|
113
|
+
try {
|
|
114
|
+
return snapshotRuntimeResult({ value }).value;
|
|
115
|
+
} catch {
|
|
116
|
+
throw invalid("State values must be JSON.");
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const idsOf = (ids) => {
|
|
120
|
+
if (!Array.isArray(ids) || !Array.from(ids).every((id) => typeof id === "string" || typeof id === "number" && Number.isFinite(id))) throw invalid("Identities must be strings or finite numbers.");
|
|
121
|
+
return ids;
|
|
122
|
+
};
|
|
123
|
+
return {
|
|
124
|
+
state: Object.freeze({
|
|
125
|
+
async get(key) {
|
|
126
|
+
return (await invoke("state.get", { key: keyOf(key) })).body.value;
|
|
127
|
+
},
|
|
128
|
+
async set(key, value) {
|
|
129
|
+
await invoke("state.set", {
|
|
130
|
+
key: keyOf(key),
|
|
131
|
+
value: valueOf(value)
|
|
132
|
+
});
|
|
133
|
+
},
|
|
134
|
+
async insert(key, value) {
|
|
135
|
+
if (value === null) throw invalid("State insert does not accept null.");
|
|
136
|
+
return (await invoke("state.insert", {
|
|
137
|
+
key: keyOf(key),
|
|
138
|
+
value: valueOf(value)
|
|
139
|
+
})).body.inserted;
|
|
140
|
+
},
|
|
141
|
+
async delete(key) {
|
|
142
|
+
await invoke("state.delete", { key: keyOf(key) });
|
|
143
|
+
},
|
|
144
|
+
async list() {
|
|
145
|
+
return (await invoke("state.list", {})).body.keys;
|
|
146
|
+
}
|
|
147
|
+
}),
|
|
148
|
+
dedupe: Object.freeze({
|
|
149
|
+
async insert(ids) {
|
|
150
|
+
return (await invoke("dedupe.insert", { ids: idsOf(ids) })).body.inserted;
|
|
151
|
+
},
|
|
152
|
+
async has(ids) {
|
|
153
|
+
return (await invoke("dedupe.has", { ids: idsOf(ids) })).body.present;
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
};
|
|
157
|
+
}
|
|
98
158
|
/** Snapshot a Task result before JSON transport can discard or coerce invalid values. */
|
|
99
159
|
function snapshotRuntimeResult(value) {
|
|
100
160
|
const parents = /* @__PURE__ */ new Set();
|
|
@@ -394,6 +454,59 @@ async function rejects(operation, pattern, message) {
|
|
|
394
454
|
throw new Error(`${message}: operation unexpectedly succeeded.`);
|
|
395
455
|
}
|
|
396
456
|
var runtimeConformanceCases = [
|
|
457
|
+
{
|
|
458
|
+
name: "cancels detached State work when its Task finishes",
|
|
459
|
+
async verify(harness) {
|
|
460
|
+
let aborted = false;
|
|
461
|
+
equal(await harness.invoke({
|
|
462
|
+
input: null,
|
|
463
|
+
invocationId: "state-detached",
|
|
464
|
+
capability: async ({ signal }) => await new Promise((resolve) => {
|
|
465
|
+
signal.addEventListener("abort", () => {
|
|
466
|
+
aborted = true;
|
|
467
|
+
resolve({
|
|
468
|
+
status: 200,
|
|
469
|
+
body: null
|
|
470
|
+
});
|
|
471
|
+
}, { once: true });
|
|
472
|
+
}),
|
|
473
|
+
program: program(harness, `export default async (_, context) => {
|
|
474
|
+
void context.state.set('detached', 1);
|
|
475
|
+
await new Promise(resolve => setTimeout(resolve, 20));
|
|
476
|
+
return null;
|
|
477
|
+
}`)
|
|
478
|
+
}), null, "Detached State Task result");
|
|
479
|
+
equal(aborted, true, "Detached State cancellation");
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
name: "rejects non-JSON State values and invalid identities before Host dispatch",
|
|
484
|
+
async verify(harness) {
|
|
485
|
+
let calls = 0;
|
|
486
|
+
equal(await harness.invoke({
|
|
487
|
+
input: null,
|
|
488
|
+
invocationId: "state-invalid",
|
|
489
|
+
capability: async () => {
|
|
490
|
+
calls += 1;
|
|
491
|
+
return {
|
|
492
|
+
status: 200,
|
|
493
|
+
body: null
|
|
494
|
+
};
|
|
495
|
+
},
|
|
496
|
+
program: program(harness, `export default async (_, context) => {
|
|
497
|
+
const cyclic = {}; cyclic.self = cyclic;
|
|
498
|
+
const invalid = [undefined, NaN, Infinity, new Date(), { x: undefined }, cyclic, [undefined], { x: () => 1 }];
|
|
499
|
+
const errors = [];
|
|
500
|
+
for (const value of invalid) { try { await context.state.set('key', value); errors.push('accepted'); } catch (e) { errors.push(e.code); } }
|
|
501
|
+
for (const call of [() => context.state.get(''), () => context.state.get('x'.repeat(257)), () => context.state.insert('x', null), () => context.dedupe.insert([NaN]), () => context.dedupe.has([null]), () => context.dedupe.insert(new Array(1))]) {
|
|
502
|
+
try { await call(); errors.push('accepted'); } catch (e) { errors.push(e.code); }
|
|
503
|
+
}
|
|
504
|
+
return errors;
|
|
505
|
+
}`)
|
|
506
|
+
}), Array.from({ length: 14 }, () => "capability.invalid"), "State boundary validation");
|
|
507
|
+
equal(calls, 0, "State invalid dispatch");
|
|
508
|
+
}
|
|
509
|
+
},
|
|
397
510
|
{
|
|
398
511
|
name: "rejects Task results that JSON transport would discard or coerce",
|
|
399
512
|
async verify(harness) {
|
|
@@ -923,19 +1036,13 @@ function createBase64() {
|
|
|
923
1036
|
const padding = text.endsWith("==") ? 2 : text.endsWith("=") ? 1 : 0;
|
|
924
1037
|
const bytes = new Uint8Array(text.length / 4 * 3 - padding);
|
|
925
1038
|
for (let index = 0, offset = 0; index < text.length; index += 4) {
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
1,
|
|
929
|
-
2,
|
|
930
|
-
3
|
|
931
|
-
].map((position) => {
|
|
1039
|
+
let value = 0;
|
|
1040
|
+
for (let position = 0; position < 4; position++) {
|
|
932
1041
|
const code = text.charCodeAt(index + position);
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
});
|
|
938
|
-
const value = digits[0] << 18 | digits[1] << 12 | digits[2] << 6 | digits[3];
|
|
1042
|
+
const digit = code == 61 && index + position >= text.length - padding ? 0 : code < 128 ? values[code] : 255;
|
|
1043
|
+
if (digit == 255) throw new TypeError("Base64 content is invalid.");
|
|
1044
|
+
value = value << 6 | digit;
|
|
1045
|
+
}
|
|
939
1046
|
if (offset < bytes.length) bytes[offset++] = value >> 16;
|
|
940
1047
|
if (offset < bytes.length) bytes[offset++] = value >> 8 & 255;
|
|
941
1048
|
if (offset < bytes.length) bytes[offset++] = value & 255;
|
|
@@ -1098,4 +1205,4 @@ function createWorkflows(invoke) {
|
|
|
1098
1205
|
} });
|
|
1099
1206
|
}
|
|
1100
1207
|
//#endregion
|
|
1101
|
-
export { createActions, createArtifacts, createBase64, createFetch, createWorkflows, currentEngineContract, findEngineContract, nodejsEngineContract, nodejsRuntimeConformanceCases, resolveAction, runtimeConformanceCases, snapshotRuntimeResult };
|
|
1208
|
+
export { createActions, createArtifacts, createBase64, createFetch, createState, createWorkflows, currentEngineContract, findEngineContract, nodejsEngineContract, nodejsRuntimeConformanceCases, resolveAction, runtimeConformanceCases, snapshotRuntimeResult };
|