@orkestrel/workflow 0.0.13 → 0.0.15
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/src/browser/index.js.map +1 -0
- package/dist/src/core/index.cjs +9 -9
- package/dist/src/core/index.cjs.map +1 -0
- package/dist/src/core/index.d.cts +6 -4
- package/dist/src/core/index.d.ts +6 -4
- package/dist/src/core/index.js +9 -9
- package/dist/src/core/index.js.map +1 -0
- package/dist/src/server/index.cjs.map +1 -0
- package/dist/src/server/index.js.map +1 -0
- package/package.json +27 -21
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../../src/server/NodeScheduler.ts","../../../src/server/factories.ts"],"sourcesContent":["import type { SchedulerInterface, SchedulerOptions } from '@src/core'\nimport { scheduleHost } from '@src/core'\n\n/**\n * The Node {@link SchedulerInterface} — the server-native cooperative-yield backend.\n *\n * @remarks\n * - **`yield` is a `setImmediate` host-turn.** `yield()` waits on `setImmediate`, the\n * canonical Node \"give the host a turn\" — it runs AFTER the current operation and\n * any pending I/O callbacks, so the event loop genuinely regains control before\n * resuming (unlike a microtask, which drains within the current task). `delay(ms)`\n * waits on a real `setTimeout`.\n * - **Abort fidelity is verbatim.** A pending `yield` / `delay` rejects with\n * `signal.reason` exactly. The shared `scheduleHost` lifecycle links an owned composite\n * before arming either Node handle, so caller signal method mutation is harmless and the\n * first completion, abort, or setup failure owns settlement and cleanup. It deliberately\n * does NOT use `node:timers/promises`, whose `{ signal }` option replaces the caller reason\n * with a Node `AbortError` (`code: 'ABORT_ERR'`).\n * - **Priority is accepted but a no-op.** Node has no priority primitive (no equivalent\n * of the browser's `scheduler.postTask` priorities), so `options.priority` is accepted\n * for contract compliance and ignored — every yield/delay is uniform.\n * - **Event-free.** A pure functional primitive — no Emitter, no events.\n *\n * @example\n * ```ts\n * import { createAbort } from '@orkestrel/abort'\n * import { NodeScheduler } from '@orkestrel/workflow/server'\n *\n * const abort = createAbort()\n * const scheduler = new NodeScheduler()\n * while (!abort.signal.aborted) {\n * \tdoSomeWork()\n * \tawait scheduler.yield({ signal: abort.signal }) // a setImmediate host-turn\n * }\n * ```\n */\nexport class NodeScheduler implements SchedulerInterface {\n\t/**\n\t * Yield control back to the event loop via `setImmediate` so pending I/O and timers\n\t * can run, then resume; abort rejects with `signal.reason`.\n\t */\n\tyield(options?: SchedulerOptions): Promise<void> {\n\t\treturn this.#immediate(options?.signal)\n\t}\n\n\t/**\n\t * Resume after at least `ms` milliseconds via `setTimeout`; abort rejects with\n\t * `signal.reason`.\n\t *\n\t * @remarks\n\t * `ms` should be a non-negative finite number. The primitive does no validation: it\n\t * passes `ms` straight to the host `setTimeout`, which clamps a negative value or\n\t * `NaN` to ~0 — so an out-of-domain `ms` resolves on the next host turn rather than\n\t * throwing.\n\t */\n\tdelay(ms: number, options?: SchedulerOptions): Promise<void> {\n\t\treturn this.#sleep(ms, options?.signal)\n\t}\n\n\t// === Private\n\n\t// The Node-native immediate boundary; `scheduleHost` owns cancellation lifecycle.\n\t#immediate(signal?: AbortSignal): Promise<void> {\n\t\treturn scheduleHost((complete) => {\n\t\t\tconst handle = setImmediate(complete)\n\t\t\treturn () => clearImmediate(handle)\n\t\t}, signal)\n\t}\n\n\t// The Node timer boundary; `scheduleHost` owns cancellation lifecycle.\n\t#sleep(ms: number, signal?: AbortSignal): Promise<void> {\n\t\treturn scheduleHost((complete) => {\n\t\t\tconst handle = setTimeout(complete, ms)\n\t\t\treturn () => clearTimeout(handle)\n\t\t}, signal)\n\t}\n}\n","import type { SchedulerInterface } from '@src/core'\nimport { NodeScheduler } from './NodeScheduler.js'\n\n/**\n * Create the Node-native cooperative-yield {@link SchedulerInterface} — `yield()` is a\n * `setImmediate` host-turn (the canonical Node \"give the event loop a turn\"), `delay(ms)`\n * a real `setTimeout`.\n *\n * @remarks\n * Use it on a server instead of the cross-environment `createScheduler` when a yield\n * should hand the event loop a full turn (after pending I/O) via `setImmediate` rather\n * than a zero-delay timer. Both methods are abort-aware: pass `options.signal` and a\n * pending yield/delay rejects with the signal's exact `reason`; the shared owned-signal\n * lifecycle clears the native handle without invoking caller listener methods.\n * `options.priority` is accepted for contract compliance but a\n * no-op — Node has no priority primitive.\n *\n * @returns A {@link SchedulerInterface} backed by Node's `setImmediate` / `setTimeout`\n *\n * @example\n * ```ts\n * import { createAbort } from '@orkestrel/abort'\n * import { createNodeScheduler } from '@orkestrel/workflow/server'\n *\n * const abort = createAbort()\n * const scheduler = createNodeScheduler()\n * while (!abort.signal.aborted) {\n * \tdoSomeWork()\n * \tawait scheduler.yield({ signal: abort.signal })\n * }\n * ```\n */\nexport function createNodeScheduler(): SchedulerInterface {\n\treturn new NodeScheduler()\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,IAAa,gBAAb,MAAyD;;;;;CAKxD,MAAM,SAA2C;EAChD,OAAO,KAAK,WAAW,SAAS,MAAM;CACvC;;;;;;;;;;;CAYA,MAAM,IAAY,SAA2C;EAC5D,OAAO,KAAK,OAAO,IAAI,SAAS,MAAM;CACvC;CAKA,WAAW,QAAqC;EAC/C,QAAA,GAAO,UAAA,aAAA,EAAc,aAAa;GACjC,MAAM,SAAS,aAAa,QAAQ;GACpC,aAAa,eAAe,MAAM;EACnC,GAAG,MAAM;CACV;CAGA,OAAO,IAAY,QAAqC;EACvD,QAAA,GAAO,UAAA,aAAA,EAAc,aAAa;GACjC,MAAM,SAAS,WAAW,UAAU,EAAE;GACtC,aAAa,aAAa,MAAM;EACjC,GAAG,MAAM;CACV;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5CA,SAAgB,sBAA0C;CACzD,OAAO,IAAI,cAAc;AAC1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/server/NodeScheduler.ts","../../../src/server/factories.ts"],"sourcesContent":["import type { SchedulerInterface, SchedulerOptions } from '@src/core'\nimport { scheduleHost } from '@src/core'\n\n/**\n * The Node {@link SchedulerInterface} — the server-native cooperative-yield backend.\n *\n * @remarks\n * - **`yield` is a `setImmediate` host-turn.** `yield()` waits on `setImmediate`, the\n * canonical Node \"give the host a turn\" — it runs AFTER the current operation and\n * any pending I/O callbacks, so the event loop genuinely regains control before\n * resuming (unlike a microtask, which drains within the current task). `delay(ms)`\n * waits on a real `setTimeout`.\n * - **Abort fidelity is verbatim.** A pending `yield` / `delay` rejects with\n * `signal.reason` exactly. The shared `scheduleHost` lifecycle links an owned composite\n * before arming either Node handle, so caller signal method mutation is harmless and the\n * first completion, abort, or setup failure owns settlement and cleanup. It deliberately\n * does NOT use `node:timers/promises`, whose `{ signal }` option replaces the caller reason\n * with a Node `AbortError` (`code: 'ABORT_ERR'`).\n * - **Priority is accepted but a no-op.** Node has no priority primitive (no equivalent\n * of the browser's `scheduler.postTask` priorities), so `options.priority` is accepted\n * for contract compliance and ignored — every yield/delay is uniform.\n * - **Event-free.** A pure functional primitive — no Emitter, no events.\n *\n * @example\n * ```ts\n * import { createAbort } from '@orkestrel/abort'\n * import { NodeScheduler } from '@orkestrel/workflow/server'\n *\n * const abort = createAbort()\n * const scheduler = new NodeScheduler()\n * while (!abort.signal.aborted) {\n * \tdoSomeWork()\n * \tawait scheduler.yield({ signal: abort.signal }) // a setImmediate host-turn\n * }\n * ```\n */\nexport class NodeScheduler implements SchedulerInterface {\n\t/**\n\t * Yield control back to the event loop via `setImmediate` so pending I/O and timers\n\t * can run, then resume; abort rejects with `signal.reason`.\n\t */\n\tyield(options?: SchedulerOptions): Promise<void> {\n\t\treturn this.#immediate(options?.signal)\n\t}\n\n\t/**\n\t * Resume after at least `ms` milliseconds via `setTimeout`; abort rejects with\n\t * `signal.reason`.\n\t *\n\t * @remarks\n\t * `ms` should be a non-negative finite number. The primitive does no validation: it\n\t * passes `ms` straight to the host `setTimeout`, which clamps a negative value or\n\t * `NaN` to ~0 — so an out-of-domain `ms` resolves on the next host turn rather than\n\t * throwing.\n\t */\n\tdelay(ms: number, options?: SchedulerOptions): Promise<void> {\n\t\treturn this.#sleep(ms, options?.signal)\n\t}\n\n\t// === Private\n\n\t// The Node-native immediate boundary; `scheduleHost` owns cancellation lifecycle.\n\t#immediate(signal?: AbortSignal): Promise<void> {\n\t\treturn scheduleHost((complete) => {\n\t\t\tconst handle = setImmediate(complete)\n\t\t\treturn () => clearImmediate(handle)\n\t\t}, signal)\n\t}\n\n\t// The Node timer boundary; `scheduleHost` owns cancellation lifecycle.\n\t#sleep(ms: number, signal?: AbortSignal): Promise<void> {\n\t\treturn scheduleHost((complete) => {\n\t\t\tconst handle = setTimeout(complete, ms)\n\t\t\treturn () => clearTimeout(handle)\n\t\t}, signal)\n\t}\n}\n","import type { SchedulerInterface } from '@src/core'\nimport { NodeScheduler } from './NodeScheduler.js'\n\n/**\n * Create the Node-native cooperative-yield {@link SchedulerInterface} — `yield()` is a\n * `setImmediate` host-turn (the canonical Node \"give the event loop a turn\"), `delay(ms)`\n * a real `setTimeout`.\n *\n * @remarks\n * Use it on a server instead of the cross-environment `createScheduler` when a yield\n * should hand the event loop a full turn (after pending I/O) via `setImmediate` rather\n * than a zero-delay timer. Both methods are abort-aware: pass `options.signal` and a\n * pending yield/delay rejects with the signal's exact `reason`; the shared owned-signal\n * lifecycle clears the native handle without invoking caller listener methods.\n * `options.priority` is accepted for contract compliance but a\n * no-op — Node has no priority primitive.\n *\n * @returns A {@link SchedulerInterface} backed by Node's `setImmediate` / `setTimeout`\n *\n * @example\n * ```ts\n * import { createAbort } from '@orkestrel/abort'\n * import { createNodeScheduler } from '@orkestrel/workflow/server'\n *\n * const abort = createAbort()\n * const scheduler = createNodeScheduler()\n * while (!abort.signal.aborted) {\n * \tdoSomeWork()\n * \tawait scheduler.yield({ signal: abort.signal })\n * }\n * ```\n */\nexport function createNodeScheduler(): SchedulerInterface {\n\treturn new NodeScheduler()\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,IAAa,gBAAb,MAAyD;;;;;CAKxD,MAAM,SAA2C;EAChD,OAAO,KAAK,WAAW,SAAS,MAAM;CACvC;;;;;;;;;;;CAYA,MAAM,IAAY,SAA2C;EAC5D,OAAO,KAAK,OAAO,IAAI,SAAS,MAAM;CACvC;CAKA,WAAW,QAAqC;EAC/C,OAAO,cAAc,aAAa;GACjC,MAAM,SAAS,aAAa,QAAQ;GACpC,aAAa,eAAe,MAAM;EACnC,GAAG,MAAM;CACV;CAGA,OAAO,IAAY,QAAqC;EACvD,OAAO,cAAc,aAAa;GACjC,MAAM,SAAS,WAAW,UAAU,EAAE;GACtC,aAAa,aAAa,MAAM;EACjC,GAAG,MAAM;CACV;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5CA,SAAgB,sBAA0C;CACzD,OAAO,IAAI,cAAc;AAC1B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orkestrel/workflow",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"description": "A typed workflow engine for the @orkestrel line — a serializable Workflow → Phase → Task tree run by a composed runner on a cooperative scheduler. Part of the @orkestrel line.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"orchestration",
|
|
@@ -70,44 +70,50 @@
|
|
|
70
70
|
"format": "oxfmt --config .oxfmtrc.json --write .",
|
|
71
71
|
"format:check": "oxfmt --config .oxfmtrc.json --check .",
|
|
72
72
|
"lint:check": "oxlint --config .oxlintrc.json --deny-warnings .",
|
|
73
|
-
"test": "npm run test:src && npm run test:policy && npm run test:config && npm run test:guides",
|
|
73
|
+
"test": "npm run test:src && npm run test:policy && npm run test:config && npm run test:setup && npm run test:guides",
|
|
74
74
|
"test:src": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:core --project src:browser --project src:server",
|
|
75
75
|
"test:src:core": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:core",
|
|
76
76
|
"test:src:browser": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:browser",
|
|
77
77
|
"test:src:server": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:server",
|
|
78
78
|
"test:policy": "vitest run --config vite.config.ts --no-cache --reporter=dot --project policy",
|
|
79
79
|
"test:config": "vitest run --config vite.config.ts --no-cache --reporter=dot --project config",
|
|
80
|
-
"test:guides": "vitest run --config vite.config.ts --reporter=dot --project guides",
|
|
80
|
+
"test:guides": "vitest run --config vite.config.ts --no-cache --reporter=dot --project guides",
|
|
81
81
|
"build": "npm run clean && npm run build:src",
|
|
82
82
|
"build:src": "npm run build:src:core && npm run build:src:browser && npm run build:src:server",
|
|
83
83
|
"build:src:core": "vite build --config configs/src/vite.core.config.ts && npm run copy dist/src/core/index.d.ts dist/src/core/index.d.cts",
|
|
84
84
|
"build:src:browser": "vite build --config configs/src/vite.browser.config.ts",
|
|
85
85
|
"build:src:server": "vite build --config configs/src/vite.server.config.ts && npm run copy dist/src/server/index.d.ts dist/src/server/index.d.cts",
|
|
86
|
-
"
|
|
86
|
+
"prepack": "npm run build",
|
|
87
|
+
"prepublishOnly": "npm run format:check && npm run lint:check && npm run check && npm run build && npm test && npm run test:distribution -- --mode release",
|
|
88
|
+
"test:distribution": "vitest run --config vite.config.ts --no-cache --reporter=dot --project distribution",
|
|
89
|
+
"test:probe": "vitest run --config vite.config.ts --no-cache --reporter=verbose --project probe",
|
|
90
|
+
"test:bench": "vitest bench --config vite.config.ts --no-cache --project probe",
|
|
91
|
+
"test:setup": "vitest run --config vite.config.ts --no-cache --reporter=dot --project setup"
|
|
87
92
|
},
|
|
88
93
|
"dependencies": {
|
|
89
|
-
"@orkestrel/abort": "^0.0.
|
|
90
|
-
"@orkestrel/budget": "^0.0.
|
|
91
|
-
"@orkestrel/contract": "^0.0.
|
|
92
|
-
"@orkestrel/database": "^0.0.
|
|
93
|
-
"@orkestrel/emitter": "^0.0.
|
|
94
|
-
"@orkestrel/queue": "^0.0.
|
|
95
|
-
"@orkestrel/timeout": "^0.0.
|
|
94
|
+
"@orkestrel/abort": "^0.0.8",
|
|
95
|
+
"@orkestrel/budget": "^0.0.8",
|
|
96
|
+
"@orkestrel/contract": "^0.0.13",
|
|
97
|
+
"@orkestrel/database": "^0.0.12",
|
|
98
|
+
"@orkestrel/emitter": "^0.0.8",
|
|
99
|
+
"@orkestrel/queue": "^0.0.10",
|
|
100
|
+
"@orkestrel/timeout": "^0.0.8"
|
|
96
101
|
},
|
|
97
102
|
"devDependencies": {
|
|
98
|
-
"@microsoft/api-extractor": "^7.
|
|
99
|
-
"@orkestrel/guide": "^0.0.
|
|
100
|
-
"@orkestrel/
|
|
101
|
-
"@orkestrel/
|
|
102
|
-
"@
|
|
103
|
-
"@
|
|
104
|
-
"
|
|
105
|
-
"
|
|
103
|
+
"@microsoft/api-extractor": "^7.59.0",
|
|
104
|
+
"@orkestrel/guide": "^0.0.14",
|
|
105
|
+
"@orkestrel/probe": "^0.0.6",
|
|
106
|
+
"@orkestrel/scaffold": "^0.0.53",
|
|
107
|
+
"@orkestrel/test": "^0.0.11",
|
|
108
|
+
"@types/node": "^26.3.0",
|
|
109
|
+
"@vitest/browser-playwright": "^4.1.11",
|
|
110
|
+
"oxfmt": "^0.65.0",
|
|
111
|
+
"oxlint": "^1.80.0",
|
|
106
112
|
"playwright": "^1.62.1",
|
|
107
113
|
"typescript": "^6.0.3",
|
|
108
|
-
"vite": "^8.2.
|
|
114
|
+
"vite": "^8.2.2",
|
|
109
115
|
"vite-plugin-dts": "^5.0.3",
|
|
110
|
-
"vitest": "^4.1.
|
|
116
|
+
"vitest": "^4.1.11"
|
|
111
117
|
},
|
|
112
118
|
"engines": {
|
|
113
119
|
"node": ">=22.12.0"
|