@particle-academy/fancy-flow 0.44.0 → 0.46.0
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/dist/{ConfigFieldRenderer-LotNHeG8.d.cts → ConfigFieldRenderer-Cyir8-B8.d.cts} +2 -2
- package/dist/{ConfigFieldRenderer-BHQDZer6.d.ts → ConfigFieldRenderer-iMkZj0VK.d.ts} +2 -2
- package/dist/{FlowViewer-nLqo7s2E.d.cts → FlowViewer-CY3_vHSg.d.cts} +1 -1
- package/dist/{FlowViewer-C4QAVgWv.d.ts → FlowViewer-DGW6t-80.d.ts} +1 -1
- package/dist/{capabilities-CkhKj_U_.d.ts → capabilities-DMUhnyZD.d.ts} +2 -2
- package/dist/{capabilities-BtJQTbnw.d.cts → capabilities-Dmd26aAs.d.cts} +2 -2
- package/dist/chunk-BHM5HGXH.js +79 -0
- package/dist/chunk-BHM5HGXH.js.map +1 -0
- package/dist/{chunk-DHUFUDEX.js → chunk-HFUBVT7W.js} +3 -3
- package/dist/{chunk-DHUFUDEX.js.map → chunk-HFUBVT7W.js.map} +1 -1
- package/dist/{chunk-VLATLVGH.js → chunk-L43CWD63.js} +129 -5
- package/dist/chunk-L43CWD63.js.map +1 -0
- package/dist/{chunk-A6RFLGWV.js → chunk-MH4ZW4DJ.js} +3 -3
- package/dist/{chunk-A6RFLGWV.js.map → chunk-MH4ZW4DJ.js.map} +1 -1
- package/dist/{chunk-QZTGV3ZL.js → chunk-P5SYH6M6.js} +3 -3
- package/dist/{chunk-QZTGV3ZL.js.map → chunk-P5SYH6M6.js.map} +1 -1
- package/dist/{chunk-WBXGZVLB.js → chunk-RMU6YCIQ.js} +11 -5
- package/dist/chunk-RMU6YCIQ.js.map +1 -0
- package/dist/durable/index.d.cts +490 -0
- package/dist/durable/index.d.ts +490 -0
- package/dist/durable.cjs +927 -0
- package/dist/durable.cjs.map +1 -0
- package/dist/durable.js +552 -0
- package/dist/durable.js.map +1 -0
- package/dist/engine.cjs +198 -12
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.d.cts +44 -7
- package/dist/engine.d.ts +44 -7
- package/dist/engine.js +68 -12
- package/dist/engine.js.map +1 -1
- package/dist/fields/react-fancy.d.cts +4 -3
- package/dist/fields/react-fancy.d.ts +4 -3
- package/dist/index.cjs +133 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -10
- package/dist/index.d.ts +12 -10
- package/dist/index.js +13 -88
- package/dist/index.js.map +1 -1
- package/dist/layout/index.d.cts +1 -1
- package/dist/layout/index.d.ts +1 -1
- package/dist/llm/prism.d.cts +2 -2
- package/dist/llm/prism.d.ts +2 -2
- package/dist/llm/vercel-ai.d.cts +2 -2
- package/dist/llm/vercel-ai.d.ts +2 -2
- package/dist/pause-9iT4tCEV.d.cts +96 -0
- package/dist/pause-9iT4tCEV.d.ts +96 -0
- package/dist/registry/index.d.cts +7 -6
- package/dist/registry/index.d.ts +7 -6
- package/dist/{registry-C9KMVpn7.d.cts → registry-D_kyUZEf.d.cts} +1 -1
- package/dist/{registry-FGCBprcn.d.ts → registry-LHB3MlR9.d.ts} +1 -1
- package/dist/registry.cjs +133 -3
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +4 -4
- package/dist/{run-cohort-BnP6ErHi.d.ts → run-cohort-Cyeny2Uu.d.ts} +3 -34
- package/dist/{run-cohort-Bjv2ZU6g.d.cts → run-cohort-DdPPowJ3.d.cts} +3 -34
- package/dist/run-flow-1KiXhy59.d.cts +55 -0
- package/dist/run-flow-CQvTDBYk.d.ts +55 -0
- package/dist/runtime/index.d.cts +5 -3
- package/dist/runtime/index.d.ts +5 -3
- package/dist/runtime.cjs +128 -2
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +3 -3
- package/dist/schema/index.d.cts +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/screens.d.cts +2 -2
- package/dist/screens.d.ts +2 -2
- package/dist/screens.js +6 -6
- package/dist/{types-JViq8reb.d.ts → types--S2Kzx7w.d.cts} +3 -97
- package/dist/{types-B78Rm69S.d.cts → types-ChkCRonF.d.ts} +3 -97
- package/dist/types-Jx1TwehV.d.cts +247 -0
- package/dist/types-Jx1TwehV.d.ts +247 -0
- package/dist/ux.d.cts +3 -2
- package/dist/ux.d.ts +3 -2
- package/package.json +12 -2
- package/dist/chunk-VLATLVGH.js.map +0 -1
- package/dist/chunk-WBXGZVLB.js.map +0 -1
- package/dist/types-sOmpCitB.d.cts +0 -109
- package/dist/types-sOmpCitB.d.ts +0 -109
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { C as ConfigFieldRenderFn } from '../ConfigFieldRenderer-
|
|
1
|
+
import { C as ConfigFieldRenderFn } from '../ConfigFieldRenderer-Cyir8-B8.cjs';
|
|
2
2
|
import 'react';
|
|
3
|
-
import '../types-
|
|
3
|
+
import '../types-Jx1TwehV.cjs';
|
|
4
4
|
import '@xyflow/react';
|
|
5
|
-
import '../types
|
|
5
|
+
import '../types--S2Kzx7w.cjs';
|
|
6
|
+
import '../pause-9iT4tCEV.cjs';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Render a `json` config field as a react-fancy `JsonEditor`.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { C as ConfigFieldRenderFn } from '../ConfigFieldRenderer-
|
|
1
|
+
import { C as ConfigFieldRenderFn } from '../ConfigFieldRenderer-iMkZj0VK.js';
|
|
2
2
|
import 'react';
|
|
3
|
-
import '../types-
|
|
3
|
+
import '../types-Jx1TwehV.js';
|
|
4
4
|
import '@xyflow/react';
|
|
5
|
-
import '../types-
|
|
5
|
+
import '../types-ChkCRonF.js';
|
|
6
|
+
import '../pause-9iT4tCEV.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Render a `json` config field as a react-fancy `JsonEditor`.
|
package/dist/index.cjs
CHANGED
|
@@ -11172,10 +11172,121 @@ function resolveNodePorts(node, kind) {
|
|
|
11172
11172
|
};
|
|
11173
11173
|
}
|
|
11174
11174
|
|
|
11175
|
+
// src/runtime/run-identity.ts
|
|
11176
|
+
function escapeSegment(value) {
|
|
11177
|
+
return value.replace(/%/g, "%25").replace(/\//g, "%2F").replace(/#/g, "%23");
|
|
11178
|
+
}
|
|
11179
|
+
function renderSegment(value, occurrence) {
|
|
11180
|
+
const escaped = escapeSegment(value);
|
|
11181
|
+
return occurrence === void 0 || occurrence === null ? escaped : `${escaped}#${occurrence}`;
|
|
11182
|
+
}
|
|
11183
|
+
function instant(value) {
|
|
11184
|
+
const ms = Date.parse(value);
|
|
11185
|
+
if (Number.isNaN(ms)) {
|
|
11186
|
+
throw new Error(
|
|
11187
|
+
`RunIdentity: firstAttemptAt is not a parseable timestamp: ${JSON.stringify(value)}`
|
|
11188
|
+
);
|
|
11189
|
+
}
|
|
11190
|
+
return ms;
|
|
11191
|
+
}
|
|
11192
|
+
var RunIdentity = class _RunIdentity {
|
|
11193
|
+
constructor(runKey, path = [], attempt = 1, firstAttemptAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
11194
|
+
if (!runKey || runKey.trim() === "") {
|
|
11195
|
+
throw new Error("RunIdentity: runKey must be a non-empty string.");
|
|
11196
|
+
}
|
|
11197
|
+
this.runKey = runKey;
|
|
11198
|
+
this.path = Object.freeze([...path]);
|
|
11199
|
+
this.attempt = Math.max(1, Math.trunc(attempt));
|
|
11200
|
+
this.firstAttemptAt = firstAttemptAt;
|
|
11201
|
+
Object.freeze(this);
|
|
11202
|
+
}
|
|
11203
|
+
/**
|
|
11204
|
+
* The identity of one execution of one node — stable across retries of that
|
|
11205
|
+
* execution, distinct from every other execution of the same node.
|
|
11206
|
+
*
|
|
11207
|
+
* Pass `occurrence` when an executor runs the same node more than once at the
|
|
11208
|
+
* same level (a loop body, one item of a fan-out it drives itself).
|
|
11209
|
+
*/
|
|
11210
|
+
stepKey(nodeId, occurrence) {
|
|
11211
|
+
return `${this.runKey}:${[...this.path, renderSegment(nodeId, occurrence)].join("/")}`;
|
|
11212
|
+
}
|
|
11213
|
+
/**
|
|
11214
|
+
* A child identity for work nested inside this step.
|
|
11215
|
+
*
|
|
11216
|
+
* `subflow` pushes the invoking node's id, so a node inside the child graph
|
|
11217
|
+
* cannot collide with a same-named node in the parent. Attempt and
|
|
11218
|
+
* `firstAttemptAt` are carried down unchanged: the nested work happens inside
|
|
11219
|
+
* this step's attempt, and shares its clock.
|
|
11220
|
+
*/
|
|
11221
|
+
descend(segment, occurrence) {
|
|
11222
|
+
return new _RunIdentity(
|
|
11223
|
+
this.runKey,
|
|
11224
|
+
[...this.path, renderSegment(segment, occurrence)],
|
|
11225
|
+
this.attempt,
|
|
11226
|
+
this.firstAttemptAt
|
|
11227
|
+
);
|
|
11228
|
+
}
|
|
11229
|
+
/** A copy on a different attempt, first-attempt clock preserved. */
|
|
11230
|
+
withAttempt(attempt, firstAttemptAt) {
|
|
11231
|
+
return new _RunIdentity(
|
|
11232
|
+
this.runKey,
|
|
11233
|
+
this.path,
|
|
11234
|
+
attempt,
|
|
11235
|
+
firstAttemptAt ?? this.firstAttemptAt
|
|
11236
|
+
);
|
|
11237
|
+
}
|
|
11238
|
+
/**
|
|
11239
|
+
* May this attempt reuse the step key and still be deduplicated?
|
|
11240
|
+
*
|
|
11241
|
+
* Providers forget idempotency keys — Stripe after 24 hours. Past that
|
|
11242
|
+
* window, resending the key creates a second charge and sending a fresh one
|
|
11243
|
+
* creates a second charge, so **the caller must refuse rather than pick
|
|
11244
|
+
* between them**: a loud stuck run beats a silent double write.
|
|
11245
|
+
*
|
|
11246
|
+
* `true` on attempt 1 whatever the elapsed time — nothing was sent on an
|
|
11247
|
+
* earlier attempt, so there is nothing for the provider to have forgotten.
|
|
11248
|
+
* That is what lets a run park on a human gate for a week and then write.
|
|
11249
|
+
*
|
|
11250
|
+
* `windowSeconds: null` means the provider does not expire keys. `0` means
|
|
11251
|
+
* it does not dedupe at all, so no retry may reuse a key — it is a real
|
|
11252
|
+
* window, not an absent one, and the two must not be conflated: reading `0`
|
|
11253
|
+
* as `null` turns "this provider does not dedupe" into "this provider
|
|
11254
|
+
* dedupes forever", which is the more dangerous of the two by a distance.
|
|
11255
|
+
*/
|
|
11256
|
+
isReplaySafe(windowSeconds, now2 = /* @__PURE__ */ new Date()) {
|
|
11257
|
+
if (this.attempt <= 1) return true;
|
|
11258
|
+
if (windowSeconds === null || windowSeconds === void 0) return true;
|
|
11259
|
+
if (windowSeconds <= 0) return false;
|
|
11260
|
+
const nowMs = typeof now2 === "string" ? instant(now2) : now2.getTime();
|
|
11261
|
+
const elapsedSeconds = Math.max(0, (nowMs - instant(this.firstAttemptAt)) / 1e3);
|
|
11262
|
+
return elapsedSeconds <= windowSeconds;
|
|
11263
|
+
}
|
|
11264
|
+
toJSON() {
|
|
11265
|
+
return {
|
|
11266
|
+
runKey: this.runKey,
|
|
11267
|
+
path: [...this.path],
|
|
11268
|
+
attempt: this.attempt,
|
|
11269
|
+
firstAttemptAt: this.firstAttemptAt
|
|
11270
|
+
};
|
|
11271
|
+
}
|
|
11272
|
+
/** Rebuild from a queue payload. */
|
|
11273
|
+
static from(value) {
|
|
11274
|
+
if (value instanceof _RunIdentity) return value;
|
|
11275
|
+
if (typeof value === "string") return new _RunIdentity(value);
|
|
11276
|
+
return new _RunIdentity(
|
|
11277
|
+
value.runKey,
|
|
11278
|
+
value.path ?? [],
|
|
11279
|
+
value.attempt ?? 1,
|
|
11280
|
+
value.firstAttemptAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
11281
|
+
);
|
|
11282
|
+
}
|
|
11283
|
+
};
|
|
11284
|
+
|
|
11175
11285
|
// src/runtime/run-flow.ts
|
|
11176
11286
|
async function runFlow(graph, executors, onEvent = () => {
|
|
11177
11287
|
}, options = {}) {
|
|
11178
|
-
const { signal, initialInputs = {}, timeoutMs, depth = 0 } = options;
|
|
11288
|
+
const { signal, initialInputs = {}, timeoutMs, depth = 0, resumeOutputs = {} } = options;
|
|
11289
|
+
const run = options.run === void 0 ? void 0 : RunIdentity.from(options.run);
|
|
11179
11290
|
const outputs = {};
|
|
11180
11291
|
const portValues = /* @__PURE__ */ new Map();
|
|
11181
11292
|
const completed = /* @__PURE__ */ new Set();
|
|
@@ -11193,6 +11304,18 @@ async function runFlow(graph, executors, onEvent = () => {
|
|
|
11193
11304
|
for (const node of order) {
|
|
11194
11305
|
if (signal?.aborted) throw new Error("aborted");
|
|
11195
11306
|
if (errors.length) break;
|
|
11307
|
+
if (Object.prototype.hasOwnProperty.call(resumeOutputs, node.id)) {
|
|
11308
|
+
const stored = resumeOutputs[node.id];
|
|
11309
|
+
outputs[node.id] = stored;
|
|
11310
|
+
const activated = activatedPorts(node, stored);
|
|
11311
|
+
for (const portId of activated.ports) {
|
|
11312
|
+
portValues.set(`${node.id}:${portId}`, activated.value);
|
|
11313
|
+
onEvent({ type: "node-output", nodeId: node.id, portId, value: activated.value });
|
|
11314
|
+
}
|
|
11315
|
+
completed.add(node.id);
|
|
11316
|
+
onEvent({ type: "node-status", nodeId: node.id, status: "done", text: "resumed" });
|
|
11317
|
+
continue;
|
|
11318
|
+
}
|
|
11196
11319
|
const incoming = incomingByNode.get(node.id) ?? [];
|
|
11197
11320
|
if (incoming.length > 0) {
|
|
11198
11321
|
const anyActive = incoming.some((e) => portValues.has(`${e.source}:${e.sourceHandle ?? "out"}`));
|
|
@@ -11232,7 +11355,8 @@ async function runFlow(graph, executors, onEvent = () => {
|
|
|
11232
11355
|
throw new Error(reason ?? "aborted");
|
|
11233
11356
|
},
|
|
11234
11357
|
emit: onEvent,
|
|
11235
|
-
depth
|
|
11358
|
+
depth,
|
|
11359
|
+
run
|
|
11236
11360
|
})
|
|
11237
11361
|
);
|
|
11238
11362
|
outputs[node.id] = result;
|
|
@@ -11385,7 +11509,13 @@ var subflowExecutor = async (ctx) => {
|
|
|
11385
11509
|
// require no configuration at all.
|
|
11386
11510
|
__parent: ctx.inputs
|
|
11387
11511
|
},
|
|
11388
|
-
depth: depth + 1
|
|
11512
|
+
depth: depth + 1,
|
|
11513
|
+
// Push THIS node onto the identity path, so a node inside the child graph
|
|
11514
|
+
// cannot share an idempotency key with a same-named node in the parent —
|
|
11515
|
+
// or with the same child graph invoked from a different parent node.
|
|
11516
|
+
// Attempt and the first-attempt clock ride down unchanged: the child's
|
|
11517
|
+
// work happens inside this node's attempt.
|
|
11518
|
+
run: ctx.run?.descend(ctx.node.id)
|
|
11389
11519
|
}
|
|
11390
11520
|
);
|
|
11391
11521
|
if (!result.ok) {
|