@effect-agent/platform-node 0.1.0-beta.53 → 0.1.0-beta.54

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.
@@ -1,4 +1,4 @@
1
- import { t as NodeWakeSchedulerConfig } from "./NodeWakeScheduler-DWdHIhWA.mjs";
1
+ import { t as NodeWakeSchedulerConfig } from "./NodeWakeScheduler-4ZeXYwPu.mjs";
2
2
  import { RunContextPreparation, RunCostEstimator, RunToolAuthorization, RunToolFailureObserver } from "@effect-agent/engine/RunOptions";
3
3
  import { SqliteStorageConfig } from "@effect-agent/storage-sqlite/SqliteStorageConfig";
4
4
  import { SqliteStorageFailpointHandler } from "@effect-agent/storage-sqlite/SqliteStorageFailpoint";
@@ -168,4 +168,4 @@ declare class NodeDurableAgentRuntime {
168
168
  }
169
169
  //#endregion
170
170
  export { NodeDurableAgentRuntimeOptions as a, NodePlatformConfigError as c, NodeDurableAgentRuntimeInitializationError as i, ownershipDrainLayer as l, NodeDurableAgentRuntimeConfig as n, NodeDurableAgentRuntimeServices as o, NodeDurableAgentRuntimeConfigValue as r, NodeDurableAgentRuntime_d_exports as s, NodeDurableAgentRuntime as t };
171
- //# sourceMappingURL=NodeDurableAgentRuntime-D3ka19Zy.d.mts.map
171
+ //# sourceMappingURL=NodeDurableAgentRuntime-CPmWN-L_.d.mts.map
@@ -1,2 +1,2 @@
1
- import { a as NodeDurableAgentRuntimeOptions, c as NodePlatformConfigError, i as NodeDurableAgentRuntimeInitializationError, l as ownershipDrainLayer, n as NodeDurableAgentRuntimeConfig, o as NodeDurableAgentRuntimeServices, r as NodeDurableAgentRuntimeConfigValue, t as NodeDurableAgentRuntime } from "./NodeDurableAgentRuntime-D3ka19Zy.mjs";
1
+ import { a as NodeDurableAgentRuntimeOptions, c as NodePlatformConfigError, i as NodeDurableAgentRuntimeInitializationError, l as ownershipDrainLayer, n as NodeDurableAgentRuntimeConfig, o as NodeDurableAgentRuntimeServices, r as NodeDurableAgentRuntimeConfigValue, t as NodeDurableAgentRuntime } from "./NodeDurableAgentRuntime-CPmWN-L_.mjs";
2
2
  export { NodeDurableAgentRuntime, NodeDurableAgentRuntimeConfig, NodeDurableAgentRuntimeConfigValue, NodeDurableAgentRuntimeInitializationError, NodeDurableAgentRuntimeOptions, NodeDurableAgentRuntimeServices, NodePlatformConfigError, ownershipDrainLayer };
@@ -1,5 +1,5 @@
1
- import { t as NodeWakeSchedulerConfig } from "./NodeWakeScheduler-DWdHIhWA.mjs";
2
- import { a as NodeDurableAgentRuntimeOptions, c as NodePlatformConfigError, n as NodeDurableAgentRuntimeConfig, o as NodeDurableAgentRuntimeServices } from "./NodeDurableAgentRuntime-D3ka19Zy.mjs";
1
+ import { t as NodeWakeSchedulerConfig } from "./NodeWakeScheduler-4ZeXYwPu.mjs";
2
+ import { a as NodeDurableAgentRuntimeOptions, c as NodePlatformConfigError, n as NodeDurableAgentRuntimeConfig, o as NodeDurableAgentRuntimeServices } from "./NodeDurableAgentRuntime-CPmWN-L_.mjs";
3
3
  import { SubmissionId, ThreadId } from "@effect-agent/core/Identifiers";
4
4
  import { AgentRegistration, DurableBindingFailure, ResolvedBinding } from "@effect-agent/thread/AgentRegistration";
5
5
  import { DurableAbortFailure, DurableAgentRuntime, DurableAwaitFailure, DurableExplainFailure, DurableObligationFailure, DurableObserveOptions, DurableRetryFailure, DurableSubmitAgent, DurableSubmitFailure, DurableSubmitOptions, DurableVerifyFailure, DurableWorkerFailure, Receipt, RecoveryReport } from "@effect-agent/thread/DurableAgentRuntime";
@@ -16,7 +16,7 @@ declare class NodeWakeSchedulerConfig extends NodeWakeSchedulerConfig_base {
16
16
  }
17
17
  /**
18
18
  * In-process Node `WakeScheduler`: `notify` publishes to a bounded sliding PubSub for prompt
19
- * same-process wakeups, and every `wakes` subscription additionally runs a periodic
19
+ * same-process wakeups, and active `wakes` subscriptions share one periodic
20
20
  * `SubmissionLedger.scanNonterminal` fallback so a dropped, coalesced, or never-sent notification
21
21
  * can never strand accepted work (persistence §14). Delivery may duplicate; consumers already
22
22
  * treat wakes as pure liveness hints.
@@ -24,4 +24,4 @@ declare class NodeWakeSchedulerConfig extends NodeWakeSchedulerConfig_base {
24
24
  declare const nodeWakeSchedulerLayer: Layer.Layer<WakeScheduler, never, SubmissionLedger | NodeWakeSchedulerConfig>;
25
25
  //#endregion
26
26
  export { NodeWakeScheduler_d_exports as n, nodeWakeSchedulerLayer as r, NodeWakeSchedulerConfig as t };
27
- //# sourceMappingURL=NodeWakeScheduler-DWdHIhWA.d.mts.map
27
+ //# sourceMappingURL=NodeWakeScheduler-4ZeXYwPu.d.mts.map
@@ -1,2 +1,2 @@
1
- import { r as nodeWakeSchedulerLayer, t as NodeWakeSchedulerConfig } from "./NodeWakeScheduler-DWdHIhWA.mjs";
1
+ import { r as nodeWakeSchedulerLayer, t as NodeWakeSchedulerConfig } from "./NodeWakeScheduler-4ZeXYwPu.mjs";
2
2
  export { NodeWakeSchedulerConfig, nodeWakeSchedulerLayer };
@@ -37,19 +37,23 @@ const makeWakeScheduler = Effect.gen(function* () {
37
37
  }), Effect.catch((error) => Effect.logWarning("NodeWakeScheduler fallback scan failed", error).pipe(Effect.as([]))));
38
38
  /**
39
39
  * Deployment §3: correctness must not depend on in-memory notifications, so every `wakes` run
40
- * merges its PubSub subscription with a Clock-driven ledger-scan loop. Both live entirely in
41
- * the consuming run's Scope; no fiber outlives its subscriber.
40
+ * merges its PubSub subscription with shared Clock-driven ledger scans. Share whole snapshots:
41
+ * sliding individual lanes would strand the beginning of scans larger than the hint buffer.
42
+ * The scan starts with the first subscriber and stops when the last subscriber leaves.
42
43
  */
43
- const fallbackScans = Stream.fromIterableEffectRepeat(Effect.sleep(config.scanInterval).pipe(Effect.andThen(scanOnce)));
44
+ const fallbackScans = yield* Stream.share(Stream.fromEffectRepeat(Effect.sleep(config.scanInterval).pipe(Effect.andThen(scanOnce))), {
45
+ capacity: 1,
46
+ strategy: "sliding"
47
+ });
44
48
  return WakeScheduler.of({
45
49
  notify: (threadId) => progress.notify(threadId).pipe(Effect.andThen(PubSub.publish(hints, threadId)), Effect.asVoid),
46
50
  subscribe: progress.subscribe,
47
- wakes: Stream.merge(Stream.fromPubSub(hints), fallbackScans)
51
+ wakes: Stream.merge(Stream.fromPubSub(hints), fallbackScans.pipe(Stream.flatMap(Stream.fromIterable)))
48
52
  });
49
53
  });
50
54
  /**
51
55
  * In-process Node `WakeScheduler`: `notify` publishes to a bounded sliding PubSub for prompt
52
- * same-process wakeups, and every `wakes` subscription additionally runs a periodic
56
+ * same-process wakeups, and active `wakes` subscriptions share one periodic
53
57
  * `SubmissionLedger.scanNonterminal` fallback so a dropped, coalesced, or never-sent notification
54
58
  * can never strand accepted work (persistence §14). Delivery may duplicate; consumers already
55
59
  * treat wakes as pure liveness hints.
@@ -1 +1 @@
1
- {"version":3,"file":"NodeWakeScheduler.mjs","names":[],"sources":["../src/NodeWakeScheduler.ts"],"sourcesContent":["import { type ThreadId } from \"@effect-agent/core/Identifiers\";\nimport { SubmissionLedger } from \"@effect-agent/thread/SubmissionLedger\";\nimport { makeWakeSubscriptionHub, WakeScheduler } from \"@effect-agent/thread/WakeScheduler\";\nimport type { Duration } from \"effect\";\nimport { Context, Effect, Layer, PubSub, Stream } from \"effect\";\n\n/**\n * Bounded in-process wake buffer. Wake hints are droppable by contract (the ledger-scan fallback\n * keeps liveness), so a full buffer slides out the oldest hint instead of growing without bound.\n */\nconst WAKE_BUFFER_CAPACITY = 1_024;\n\n/** Cadence authority for the Node wake scheduler's ledger-scan fallback loop. */\nexport class NodeWakeSchedulerConfig extends Context.Service<\n NodeWakeSchedulerConfig,\n {\n /** Interval between ledger scans that re-emit every nonterminal Thread lane. */\n readonly scanInterval: Duration.Duration;\n }\n>()(\"@effect-agent/platform-node/NodeWakeSchedulerConfig\") {\n static layer(options: {\n readonly scanInterval: Duration.Duration;\n }): Layer.Layer<NodeWakeSchedulerConfig> {\n return Layer.succeed(NodeWakeSchedulerConfig)({ scanInterval: options.scanInterval });\n }\n}\n\nconst makeWakeScheduler = Effect.gen(function* () {\n const ledger = yield* SubmissionLedger;\n const config = yield* NodeWakeSchedulerConfig;\n const hints = yield* PubSub.sliding<ThreadId>(WAKE_BUFFER_CAPACITY);\n const progress = yield* makeWakeSubscriptionHub;\n\n yield* Effect.addFinalizer(() => PubSub.shutdown(hints));\n\n /**\n * One fallback scan: every Thread lane with nonterminal work, deduplicated. A scan\n * failure degrades to \"no hints this round\" — the wake channel has no error contract and the\n * next round retries — but is logged so a persistently failing ledger stays visible.\n */\n const scanOnce: Effect.Effect<ReadonlyArray<ThreadId>> = Stream.runCollect(\n ledger.scanNonterminal,\n ).pipe(\n Effect.map((snapshots) => {\n const lanes = new Set<ThreadId>();\n\n for (const snapshot of snapshots) {\n lanes.add(snapshot.threadId);\n }\n\n return [...lanes];\n }),\n Effect.catch((error) =>\n Effect.logWarning(\"NodeWakeScheduler fallback scan failed\", error).pipe(\n Effect.as([] as ReadonlyArray<ThreadId>),\n ),\n ),\n );\n\n /**\n * Deployment §3: correctness must not depend on in-memory notifications, so every `wakes` run\n * merges its PubSub subscription with a Clock-driven ledger-scan loop. Both live entirely in\n * the consuming run's Scope; no fiber outlives its subscriber.\n */\n const fallbackScans: Stream.Stream<ThreadId> = Stream.fromIterableEffectRepeat(\n Effect.sleep(config.scanInterval).pipe(Effect.andThen(scanOnce)),\n );\n\n return WakeScheduler.of({\n notify: (threadId) =>\n progress\n .notify(threadId)\n .pipe(Effect.andThen(PubSub.publish(hints, threadId)), Effect.asVoid),\n subscribe: progress.subscribe,\n wakes: Stream.merge(Stream.fromPubSub(hints), fallbackScans),\n });\n});\n\n/**\n * In-process Node `WakeScheduler`: `notify` publishes to a bounded sliding PubSub for prompt\n * same-process wakeups, and every `wakes` subscription additionally runs a periodic\n * `SubmissionLedger.scanNonterminal` fallback so a dropped, coalesced, or never-sent notification\n * can never strand accepted work (persistence §14). Delivery may duplicate; consumers already\n * treat wakes as pure liveness hints.\n */\nexport const nodeWakeSchedulerLayer: Layer.Layer<\n WakeScheduler,\n never,\n SubmissionLedger | NodeWakeSchedulerConfig\n> = Layer.effect(WakeScheduler)(makeWakeScheduler);\n"],"mappings":";;;;;;;;;;;;;;AAUA,MAAM,uBAAuB;;AAG7B,IAAa,0BAAb,MAAa,gCAAgC,QAAQ,QAMnD,CAAC,CAAC,qDAAqD,CAAC,CAAC;CACzD,OAAO,MAAM,SAE4B;EACvC,OAAO,MAAM,QAAQ,uBAAuB,CAAC,CAAC,EAAE,cAAc,QAAQ,aAAa,CAAC;CACtF;AACF;AAEA,MAAM,oBAAoB,OAAO,IAAI,aAAa;CAChD,MAAM,SAAS,OAAO;CACtB,MAAM,SAAS,OAAO;CACtB,MAAM,QAAQ,OAAO,OAAO,QAAkB,oBAAoB;CAClE,MAAM,WAAW,OAAO;CAExB,OAAO,OAAO,mBAAmB,OAAO,SAAS,KAAK,CAAC;;;;;;CAOvD,MAAM,WAAmD,OAAO,WAC9D,OAAO,eACT,CAAC,CAAC,KACA,OAAO,KAAK,cAAc;EACxB,MAAM,wBAAQ,IAAI,IAAc;EAEhC,KAAK,MAAM,YAAY,WACrB,MAAM,IAAI,SAAS,QAAQ;EAG7B,OAAO,CAAC,GAAG,KAAK;CAClB,CAAC,GACD,OAAO,OAAO,UACZ,OAAO,WAAW,0CAA0C,KAAK,CAAC,CAAC,KACjE,OAAO,GAAG,CAAC,CAA4B,CACzC,CACF,CACF;;;;;;CAOA,MAAM,gBAAyC,OAAO,yBACpD,OAAO,MAAM,OAAO,YAAY,CAAC,CAAC,KAAK,OAAO,QAAQ,QAAQ,CAAC,CACjE;CAEA,OAAO,cAAc,GAAG;EACtB,SAAS,aACP,SACG,OAAO,QAAQ,CAAC,CAChB,KAAK,OAAO,QAAQ,OAAO,QAAQ,OAAO,QAAQ,CAAC,GAAG,OAAO,MAAM;EACxE,WAAW,SAAS;EACpB,OAAO,OAAO,MAAM,OAAO,WAAW,KAAK,GAAG,aAAa;CAC7D,CAAC;AACH,CAAC;;;;;;;;AASD,MAAa,yBAIT,MAAM,OAAO,aAAa,CAAC,CAAC,iBAAiB"}
1
+ {"version":3,"file":"NodeWakeScheduler.mjs","names":[],"sources":["../src/NodeWakeScheduler.ts"],"sourcesContent":["import { type ThreadId } from \"@effect-agent/core/Identifiers\";\nimport { SubmissionLedger } from \"@effect-agent/thread/SubmissionLedger\";\nimport { makeWakeSubscriptionHub, WakeScheduler } from \"@effect-agent/thread/WakeScheduler\";\nimport type { Duration } from \"effect\";\nimport { Context, Effect, Layer, PubSub, Stream } from \"effect\";\n\n/**\n * Bounded in-process wake buffer. Wake hints are droppable by contract (the ledger-scan fallback\n * keeps liveness), so a full buffer slides out the oldest hint instead of growing without bound.\n */\nconst WAKE_BUFFER_CAPACITY = 1_024;\n\n/** Cadence authority for the Node wake scheduler's ledger-scan fallback loop. */\nexport class NodeWakeSchedulerConfig extends Context.Service<\n NodeWakeSchedulerConfig,\n {\n /** Interval between ledger scans that re-emit every nonterminal Thread lane. */\n readonly scanInterval: Duration.Duration;\n }\n>()(\"@effect-agent/platform-node/NodeWakeSchedulerConfig\") {\n static layer(options: {\n readonly scanInterval: Duration.Duration;\n }): Layer.Layer<NodeWakeSchedulerConfig> {\n return Layer.succeed(NodeWakeSchedulerConfig)({ scanInterval: options.scanInterval });\n }\n}\n\nconst makeWakeScheduler = Effect.gen(function* () {\n const ledger = yield* SubmissionLedger;\n const config = yield* NodeWakeSchedulerConfig;\n const hints = yield* PubSub.sliding<ThreadId>(WAKE_BUFFER_CAPACITY);\n const progress = yield* makeWakeSubscriptionHub;\n\n yield* Effect.addFinalizer(() => PubSub.shutdown(hints));\n\n /**\n * One fallback scan: every Thread lane with nonterminal work, deduplicated. A scan\n * failure degrades to \"no hints this round\" — the wake channel has no error contract and the\n * next round retries — but is logged so a persistently failing ledger stays visible.\n */\n const scanOnce: Effect.Effect<ReadonlyArray<ThreadId>> = Stream.runCollect(\n ledger.scanNonterminal,\n ).pipe(\n Effect.map((snapshots) => {\n const lanes = new Set<ThreadId>();\n\n for (const snapshot of snapshots) {\n lanes.add(snapshot.threadId);\n }\n\n return [...lanes];\n }),\n Effect.catch((error) =>\n Effect.logWarning(\"NodeWakeScheduler fallback scan failed\", error).pipe(\n Effect.as([] as ReadonlyArray<ThreadId>),\n ),\n ),\n );\n\n /**\n * Deployment §3: correctness must not depend on in-memory notifications, so every `wakes` run\n * merges its PubSub subscription with shared Clock-driven ledger scans. Share whole snapshots:\n * sliding individual lanes would strand the beginning of scans larger than the hint buffer.\n * The scan starts with the first subscriber and stops when the last subscriber leaves.\n */\n const fallbackScans = yield* Stream.share(\n Stream.fromEffectRepeat(Effect.sleep(config.scanInterval).pipe(Effect.andThen(scanOnce))),\n { capacity: 1, strategy: \"sliding\" },\n );\n\n return WakeScheduler.of({\n notify: (threadId) =>\n progress\n .notify(threadId)\n .pipe(Effect.andThen(PubSub.publish(hints, threadId)), Effect.asVoid),\n subscribe: progress.subscribe,\n wakes: Stream.merge(\n Stream.fromPubSub(hints),\n fallbackScans.pipe(Stream.flatMap(Stream.fromIterable)),\n ),\n });\n});\n\n/**\n * In-process Node `WakeScheduler`: `notify` publishes to a bounded sliding PubSub for prompt\n * same-process wakeups, and active `wakes` subscriptions share one periodic\n * `SubmissionLedger.scanNonterminal` fallback so a dropped, coalesced, or never-sent notification\n * can never strand accepted work (persistence §14). Delivery may duplicate; consumers already\n * treat wakes as pure liveness hints.\n */\nexport const nodeWakeSchedulerLayer: Layer.Layer<\n WakeScheduler,\n never,\n SubmissionLedger | NodeWakeSchedulerConfig\n> = Layer.effect(WakeScheduler)(makeWakeScheduler);\n"],"mappings":";;;;;;;;;;;;;;AAUA,MAAM,uBAAuB;;AAG7B,IAAa,0BAAb,MAAa,gCAAgC,QAAQ,QAMnD,CAAC,CAAC,qDAAqD,CAAC,CAAC;CACzD,OAAO,MAAM,SAE4B;EACvC,OAAO,MAAM,QAAQ,uBAAuB,CAAC,CAAC,EAAE,cAAc,QAAQ,aAAa,CAAC;CACtF;AACF;AAEA,MAAM,oBAAoB,OAAO,IAAI,aAAa;CAChD,MAAM,SAAS,OAAO;CACtB,MAAM,SAAS,OAAO;CACtB,MAAM,QAAQ,OAAO,OAAO,QAAkB,oBAAoB;CAClE,MAAM,WAAW,OAAO;CAExB,OAAO,OAAO,mBAAmB,OAAO,SAAS,KAAK,CAAC;;;;;;CAOvD,MAAM,WAAmD,OAAO,WAC9D,OAAO,eACT,CAAC,CAAC,KACA,OAAO,KAAK,cAAc;EACxB,MAAM,wBAAQ,IAAI,IAAc;EAEhC,KAAK,MAAM,YAAY,WACrB,MAAM,IAAI,SAAS,QAAQ;EAG7B,OAAO,CAAC,GAAG,KAAK;CAClB,CAAC,GACD,OAAO,OAAO,UACZ,OAAO,WAAW,0CAA0C,KAAK,CAAC,CAAC,KACjE,OAAO,GAAG,CAAC,CAA4B,CACzC,CACF,CACF;;;;;;;CAQA,MAAM,gBAAgB,OAAO,OAAO,MAClC,OAAO,iBAAiB,OAAO,MAAM,OAAO,YAAY,CAAC,CAAC,KAAK,OAAO,QAAQ,QAAQ,CAAC,CAAC,GACxF;EAAE,UAAU;EAAG,UAAU;CAAU,CACrC;CAEA,OAAO,cAAc,GAAG;EACtB,SAAS,aACP,SACG,OAAO,QAAQ,CAAC,CAChB,KAAK,OAAO,QAAQ,OAAO,QAAQ,OAAO,QAAQ,CAAC,GAAG,OAAO,MAAM;EACxE,WAAW,SAAS;EACpB,OAAO,OAAO,MACZ,OAAO,WAAW,KAAK,GACvB,cAAc,KAAK,OAAO,QAAQ,OAAO,YAAY,CAAC,CACxD;CACF,CAAC;AACH,CAAC;;;;;;;;AASD,MAAa,yBAIT,MAAM,OAAO,aAAa,CAAC,CAAC,iBAAiB"}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { n as NodeWakeScheduler_d_exports } from "./NodeWakeScheduler-DWdHIhWA.mjs";
2
- import { s as NodeDurableAgentRuntime_d_exports } from "./NodeDurableAgentRuntime-D3ka19Zy.mjs";
1
+ import { n as NodeWakeScheduler_d_exports } from "./NodeWakeScheduler-4ZeXYwPu.mjs";
2
+ import { s as NodeDurableAgentRuntime_d_exports } from "./NodeDurableAgentRuntime-CPmWN-L_.mjs";
3
3
  import { t as NodeDurableHost_d_exports } from "./NodeDurableHost.mjs";
4
4
  import { t as NodeScheduling_d_exports } from "./NodeScheduling.mjs";
5
5
  import { t as NodeSubscriptions_d_exports } from "./NodeSubscriptions.mjs";
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@effect-agent/platform-node","version":"0.1.0-beta.53","dependencies":{"@effect-agent/core":"0.1.0-beta.53","@effect-agent/engine":"0.1.0-beta.53","@effect-agent/storage-sqlite":"0.1.0-beta.53","@effect-agent/thread":"0.1.0-beta.53","@effect-agent/workflow":"0.1.0-beta.53","@effect/platform-node":"4.0.0-rc.112","@effect/sql-sqlite-node":"4.0.0-rc.112"},"devDependencies":{"@effect-agent/capabilities":"0.1.0-beta.53","@effect/vitest":"4.0.0-rc.112","effect":"4.0.0-rc.112","typescript":"7.0.2","vite-plus":"0.3.0"},"peerDependencies":{"effect":"^4.0.0-rc.112"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./NodeDurableAgentRuntime":{"types":"./dist/NodeDurableAgentRuntime.d.mts","default":"./dist/NodeDurableAgentRuntime.mjs"},"./NodeDurableHost":{"types":"./dist/NodeDurableHost.d.mts","default":"./dist/NodeDurableHost.mjs"},"./NodeScheduling":{"types":"./dist/NodeScheduling.d.mts","default":"./dist/NodeScheduling.mjs"},"./NodeSubscriptions":{"types":"./dist/NodeSubscriptions.d.mts","default":"./dist/NodeSubscriptions.mjs"},"./NodeWakeScheduler":{"types":"./dist/NodeWakeScheduler.d.mts","default":"./dist/NodeWakeScheduler.mjs"},"./NodeWorkflow":{"types":"./dist/NodeWorkflow.d.mts","default":"./dist/NodeWorkflow.mjs"}},"description":"Class DN layer assembly for Effect Agent: the durable Node/SQLite runtime host, wake scheduler, and ownership drain.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-agent.git","directory":"packages/platform-node"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests"}}
1
+ {"name":"@effect-agent/platform-node","version":"0.1.0-beta.54","dependencies":{"@effect-agent/core":"0.1.0-beta.54","@effect-agent/engine":"0.1.0-beta.54","@effect-agent/storage-sqlite":"0.1.0-beta.54","@effect-agent/thread":"0.1.0-beta.54","@effect-agent/workflow":"0.1.0-beta.54","@effect/platform-node":"4.0.0-rc.112","@effect/sql-sqlite-node":"4.0.0-rc.112"},"devDependencies":{"@effect-agent/capabilities":"0.1.0-beta.54","@effect/vitest":"4.0.0-rc.112","effect":"4.0.0-rc.112","typescript":"7.0.2","vite-plus":"0.3.0"},"peerDependencies":{"effect":"^4.0.0-rc.112"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./NodeDurableAgentRuntime":{"types":"./dist/NodeDurableAgentRuntime.d.mts","default":"./dist/NodeDurableAgentRuntime.mjs"},"./NodeDurableHost":{"types":"./dist/NodeDurableHost.d.mts","default":"./dist/NodeDurableHost.mjs"},"./NodeScheduling":{"types":"./dist/NodeScheduling.d.mts","default":"./dist/NodeScheduling.mjs"},"./NodeSubscriptions":{"types":"./dist/NodeSubscriptions.d.mts","default":"./dist/NodeSubscriptions.mjs"},"./NodeWakeScheduler":{"types":"./dist/NodeWakeScheduler.d.mts","default":"./dist/NodeWakeScheduler.mjs"},"./NodeWorkflow":{"types":"./dist/NodeWorkflow.d.mts","default":"./dist/NodeWorkflow.mjs"}},"description":"Class DN layer assembly for Effect Agent: the durable Node/SQLite runtime host, wake scheduler, and ownership drain.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/danieljvdm/effect-agent.git","directory":"packages/platform-node"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test --passWithNoTests"}}
@@ -59,11 +59,13 @@ const makeWakeScheduler = Effect.gen(function* () {
59
59
 
60
60
  /**
61
61
  * Deployment §3: correctness must not depend on in-memory notifications, so every `wakes` run
62
- * merges its PubSub subscription with a Clock-driven ledger-scan loop. Both live entirely in
63
- * the consuming run's Scope; no fiber outlives its subscriber.
62
+ * merges its PubSub subscription with shared Clock-driven ledger scans. Share whole snapshots:
63
+ * sliding individual lanes would strand the beginning of scans larger than the hint buffer.
64
+ * The scan starts with the first subscriber and stops when the last subscriber leaves.
64
65
  */
65
- const fallbackScans: Stream.Stream<ThreadId> = Stream.fromIterableEffectRepeat(
66
- Effect.sleep(config.scanInterval).pipe(Effect.andThen(scanOnce)),
66
+ const fallbackScans = yield* Stream.share(
67
+ Stream.fromEffectRepeat(Effect.sleep(config.scanInterval).pipe(Effect.andThen(scanOnce))),
68
+ { capacity: 1, strategy: "sliding" },
67
69
  );
68
70
 
69
71
  return WakeScheduler.of({
@@ -72,13 +74,16 @@ const makeWakeScheduler = Effect.gen(function* () {
72
74
  .notify(threadId)
73
75
  .pipe(Effect.andThen(PubSub.publish(hints, threadId)), Effect.asVoid),
74
76
  subscribe: progress.subscribe,
75
- wakes: Stream.merge(Stream.fromPubSub(hints), fallbackScans),
77
+ wakes: Stream.merge(
78
+ Stream.fromPubSub(hints),
79
+ fallbackScans.pipe(Stream.flatMap(Stream.fromIterable)),
80
+ ),
76
81
  });
77
82
  });
78
83
 
79
84
  /**
80
85
  * In-process Node `WakeScheduler`: `notify` publishes to a bounded sliding PubSub for prompt
81
- * same-process wakeups, and every `wakes` subscription additionally runs a periodic
86
+ * same-process wakeups, and active `wakes` subscriptions share one periodic
82
87
  * `SubmissionLedger.scanNonterminal` fallback so a dropped, coalesced, or never-sent notification
83
88
  * can never strand accepted work (persistence §14). Delivery may duplicate; consumers already
84
89
  * treat wakes as pure liveness hints.