@moltzap/client 2026.519.0 → 2026.519.1

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.
Files changed (60) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +4 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/notification/__tests__/filter-equivalence.test.d.ts +2 -0
  6. package/dist/notification/__tests__/filter-equivalence.test.d.ts.map +1 -0
  7. package/dist/notification/__tests__/filter-equivalence.test.js +123 -0
  8. package/dist/notification/__tests__/filter-equivalence.test.js.map +1 -0
  9. package/dist/notification/__tests__/snapshot-semantics.test.d.ts +2 -0
  10. package/dist/notification/__tests__/snapshot-semantics.test.d.ts.map +1 -0
  11. package/dist/notification/__tests__/snapshot-semantics.test.js +261 -0
  12. package/dist/notification/__tests__/snapshot-semantics.test.js.map +1 -0
  13. package/dist/notification/__tests__/snapshot-semantics.types-check.d.ts +3 -0
  14. package/dist/notification/__tests__/snapshot-semantics.types-check.d.ts.map +1 -0
  15. package/dist/notification/__tests__/snapshot-semantics.types-check.js +62 -0
  16. package/dist/notification/__tests__/snapshot-semantics.types-check.js.map +1 -0
  17. package/dist/notification/errors.d.ts +27 -0
  18. package/dist/notification/errors.d.ts.map +1 -0
  19. package/dist/notification/errors.js +24 -0
  20. package/dist/notification/errors.js.map +1 -0
  21. package/dist/notification/stream.d.ts +84 -0
  22. package/dist/notification/stream.d.ts.map +1 -0
  23. package/dist/notification/stream.js +106 -0
  24. package/dist/notification/stream.js.map +1 -0
  25. package/dist/runtime/index.d.ts +3 -4
  26. package/dist/runtime/index.d.ts.map +1 -1
  27. package/dist/runtime/index.js +3 -3
  28. package/dist/runtime/service-teardown.d.ts +5 -0
  29. package/dist/runtime/service-teardown.d.ts.map +1 -0
  30. package/dist/runtime/service-teardown.js +36 -0
  31. package/dist/runtime/service-teardown.js.map +1 -0
  32. package/dist/runtime/service-teardown.test.d.ts +2 -0
  33. package/dist/runtime/service-teardown.test.d.ts.map +1 -0
  34. package/dist/runtime/service-teardown.test.js +80 -0
  35. package/dist/runtime/service-teardown.test.js.map +1 -0
  36. package/dist/runtime/subscribers.d.ts +74 -136
  37. package/dist/runtime/subscribers.d.ts.map +1 -1
  38. package/dist/runtime/subscribers.js +187 -93
  39. package/dist/runtime/subscribers.js.map +1 -1
  40. package/dist/service.d.ts +10 -0
  41. package/dist/service.d.ts.map +1 -1
  42. package/dist/service.js +45 -12
  43. package/dist/service.js.map +1 -1
  44. package/dist/test-utils/conformance-adapter.d.ts +6 -16
  45. package/dist/test-utils/conformance-adapter.d.ts.map +1 -1
  46. package/dist/test-utils/conformance-adapter.js +100 -59
  47. package/dist/test-utils/conformance-adapter.js.map +1 -1
  48. package/dist/ws-client-test-support.d.ts +1 -1
  49. package/dist/ws-client-test-support.d.ts.map +1 -1
  50. package/dist/ws-client-test-support.js +24 -3
  51. package/dist/ws-client-test-support.js.map +1 -1
  52. package/dist/ws-client.d.ts +52 -54
  53. package/dist/ws-client.d.ts.map +1 -1
  54. package/dist/ws-client.js +40 -168
  55. package/dist/ws-client.js.map +1 -1
  56. package/package.json +3 -3
  57. package/dist/runtime/subscribers.test.d.ts +0 -2
  58. package/dist/runtime/subscribers.test.d.ts.map +0 -1
  59. package/dist/runtime/subscribers.test.js +0 -193
  60. package/dist/runtime/subscribers.test.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"subscribers.d.ts","sourceRoot":"","sources":["../../src/runtime/subscribers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAO,MAAM,QAAQ,CAAC;AAC5C,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACpB,MAAM,mBAAmB,CAAC;AAE3B,UAAU,2BAA2B;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,0EAA0E;AAC1E,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;AAGpE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAC1C;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,EAAE,EAAE,cAAc,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;CAClD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAC9B,KAAK,EAAE,mBAAmB,CAAC,yBAAyB,CAAC,KAClD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,CACjB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,iBAAiB,KACvB,MAAM,CAAC,MAAM,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;IAEpD;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,QAAQ,EAAE,CACjB,KAAK,EAAE,mBAAmB,CAAC,yBAAyB,CAAC,KAClD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAEhC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;CAC/C;AAiDD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAAC,MAAM,CACrD,kBAAkB,EAClB,KAAK,CACN,CAoCA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE,2BAA2B,GACjC,OAAO,CAiBT"}
1
+ {"version":3,"file":"subscribers.d.ts","sourceRoot":"","sources":["../../src/runtime/subscribers.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAO,MAAM,QAAQ,CAAC;AAC5C,OAAO,EACL,iBAAiB,EACjB,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAC1B,MAAM,mBAAmB,CAAC;AAE3B,0EAA0E;AAC1E,KAAK,cAAc,GAAG,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;AAc7D;;;;;GAKG;AACH,KAAK,uBAAuB,GAAG,CAC7B,KAAK,EAAE,mBAAmB,CAAC,yBAAyB,CAAC,KAClD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAEhC;;;;GAIG;AACH,KAAK,uBAAuB,GAAG,CAC7B,KAAK,EAAE,iBAAiB,KACrB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAehC;;;;GAIG;AACH,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,EAAE,EAAE,cAAc,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;CACjD;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,SAAS,yBAAyB,EACrD,UAAU,EAAE,CAAC,EACb,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,GAAG,SAAS,EACtE,SAAS,EAAE;QACT,QAAQ,CAAC,OAAO,EAAE,CAChB,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;KAC3C,KACE,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;IAE9C;;;;;;;;;OASG;IACH,QAAQ,CAAC,WAAW,EAAE,CACpB,UAAU,EACN,CAAC,CACC,YAAY,EAAE,mBAAmB,CAAC,yBAAyB,CAAC,KACzD,OAAO,CAAC,GACb,SAAS,EACb,SAAS,EAAE;QACT,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;QAC1C,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;KAC3C,KACE,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;IAE9C;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,CACjB,KAAK,EAAE,mBAAmB,CAAC,yBAAyB,CAAC,KAClD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAEhC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;CAC/C;AA8RD,wBAAgB,sBAAsB,IAAI,MAAM,CAAC,MAAM,CACrD,kBAAkB,EAClB,KAAK,CACN,CAcA"}
@@ -1,35 +1,38 @@
1
+ /* eslint-disable jsdoc/text-escaping -- JSDoc references to generic types like `NotificationParamsOf<D>` use the natural angle-bracket form (TS source style) inside backtick-fenced code spans; the lint rule's pre-render check fires false positives on these multi-line spans. Matches the precedent in filter-equivalence.test.ts. */
1
2
  /**
2
3
  * Per-subscription notification registry for `MoltZapWsClient`.
3
4
  *
4
- * Responsibility: own the list of live `subscribe()` handles and fan each
5
- * inbound JSON-RPC notification out to every subscription whose filter matches.
6
- * Implements spec #222 §5.3 (C4 + the `RealClientEventSubscriber.subscribe`
7
- * filter stub). Lives as an internal collaborator of `MoltZapWsClient`;
8
- * the public types (`SubscriptionFilter`, `NotificationSubscription`,
9
- * `SubscriptionId`) re-export from the package barrel.
5
+ * Responsibility: own the list of live subscriptions and fan each inbound
6
+ * JSON-RPC notification out to every subscription whose definition (and
7
+ * optional typed refinement predicate) matches. Implements spec #596
8
+ * (notification consumption consolidation) via the AD1 path-(a) Stream.async
9
+ * design (architect plan §3, §5.5).
10
10
  *
11
- * Dispatch ordering (Invariant 6 — notifications delivered in arrival order):
12
- * 1. Inbound frames are handed to the registry in arrival order.
13
- * 2. Within a single frame, subscriptions are notified in registration
14
- * order.
15
- * 3. There is no separate legacy `onNotification` fanout — spec #222 OQ-4 is
16
- * resolved by DELETING `MoltZapWsClientOptions.onNotification`. Callers
17
- * that want every notification register `subscribe({}, handler)` after
18
- * construction and before `connect()`.
11
+ * Storage shape (post-Spec B):
12
+ * - Subscriptions are records of typed `{onFrame, onClose}` callbacks
13
+ * (NOT queues / Take items / Stream.fromQueue). `notification/stream.ts`
14
+ * owns Stream construction via `Stream.async`; this module owns the
15
+ * register/dispatch/closeAll lifecycle.
16
+ * - The dispatch path snapshots `subsRef` at iteration start (AD1
17
+ * snapshot-semantic contract from spec #222 §5.3 OQ-3 / spec #596
18
+ * "Stream lifecycle contract" row).
19
+ * - `closeAll` invokes each live sub's `onClose(new NotConnectedError(...))`
20
+ * before clearing `subsRef` — deterministic typed-failure delivery
21
+ * replaces the deleted `failAllNotificationWaiters` semantic.
19
22
  *
20
- * Unsubscribe semantics (OQ-3 A): `unsubscribe` takes effect on the next
21
- * frame. The registry snapshots its live-subscription list at the start
22
- * of each `dispatch` call; in-flight dispatch of frame N is not
23
- * interrupted by an unsubscribe during frame N. Frame N+1 observes the
24
- * unsubscribed state.
25
- *
26
- * Error channel: handlers are invoked inside a defect-catcher; a throw is
27
- * logged through Effect logging and swallowed (matching the prior
28
- * `onNotification` contract at `ws-client.ts:650-655` pre-deletion). The
29
- * registry itself has no typed error surface — `register`, `dispatch`, and
30
- * `closeAll` are `Effect&lt;T, never>`.
23
+ * Filter grammar (post-Spec B):
24
+ * - Subscription matches a frame iff `sub.definition === frame.definition`.
25
+ * - Optional `refinement` is a typed predicate over the frame's params
26
+ * (erased to the union type `ErasedNotificationRefinement` at the
27
+ * storage boundary; consumers receive the typed-narrowed shape via
28
+ * `Stream.async`'s typed `emit.single` callback inside
29
+ * `notification/stream.ts`).
30
+ * - The three-field `SubscriptionFilter` grammar is deleted (spec #596
31
+ * Goal #3 + §"Acceptance criteria" delete sweep). Multi-definition
32
+ * fan-out becomes `Stream.mergeAll([subscribe(d1), subscribe(d2)])`.
31
33
  */
32
34
  import { Brand, Effect, Ref } from "effect";
35
+ import { NotConnectedError, } from "@moltzap/protocol";
33
36
  const SubscriptionIdBrand = Brand.nominal();
34
37
  function nextSubscriptionId(counterRef) {
35
38
  return Ref.updateAndGet(counterRef, (count) => count + 1).pipe(Effect.map((count) => SubscriptionIdBrand(`sub-${count}`)));
@@ -41,88 +44,179 @@ function removeSubscription(subsRef, id) {
41
44
  return Ref.update(subsRef, (subscriptions) => subscriptions.filter((subscription) => subscription.id !== id));
42
45
  }
43
46
  function dispatchToSubscriber(sub, frame) {
44
- return Effect.suspend(() => sub.handler(frame)).pipe(Effect.catchAllDefect((err) => Effect.logWarning("subscriber handler threw", err)));
47
+ return Effect.suspend(() => sub.onFrame(frame)).pipe(Effect.catchAllDefect((err) => Effect.logWarning("subscriber onFrame callback threw", err)));
45
48
  }
46
- function isNotificationParamsRecord(value) {
47
- return typeof value === "object" && value !== null && !Array.isArray(value);
49
+ function closeSubscriber(sub, cause) {
50
+ return Effect.suspend(() => sub.onClose(cause)).pipe(Effect.catchAllDefect((err) => Effect.logWarning("subscriber onClose callback threw", err)));
48
51
  }
49
52
  /**
50
53
  * Construct an empty registry. Called once from the `MoltZapWsClient`
51
54
  * constructor.
52
55
  *
53
56
  * Implementation notes:
54
- * - Live subscriptions are stored in a `Ref&lt;ReadonlyArray&lt;…>>` keyed
55
- * by registration order. Append-on-register, filter-on-unsubscribe
56
- * keeps the dispatch path O(N) with N = live subscription count.
57
- * Bigger structures aren't justified at the expected sub count
58
- * (≤ ~10 per fixture).
59
- * - `dispatch` snapshots the array at start (OQ-3 A). An
60
- * `unsubscribe` mid-dispatch mutates the Ref but the in-flight
61
- * iteration walks the snapshot.
62
- * - Handler exceptions are caught with `Effect.catchAllDefect` after
63
- * the handler Effect. Sync `throw` from a `(frame) => …` body
64
- * surfaces as a defect; we log + swallow to match the pre-deletion
65
- * `onNotification` contract.
57
+ * - `subsRef: Ref<ReadonlyArray<LiveSubscription>>` keyed by registration
58
+ * order. Append-on-register, filter-on-unregister keeps the dispatch
59
+ * path O(N) with N = live subscription count.
60
+ * - `dispatch` snapshots `subsRef` at iteration start. An unregister
61
+ * mid-dispatch mutates the Ref but the in-flight iteration walks the
62
+ * snapshot (AD1 path-(a) snapshot semantic).
63
+ * - `closeAll` invokes each live sub's `onClose` in iteration order
64
+ * before clearing the ref. `Stream.async`'s `emit.fail` is the
65
+ * deterministic in-Effect mechanism that propagates the typed
66
+ * failure to each consumer.
66
67
  */
67
- export function makeSubscriberRegistry() {
68
- return Effect.gen(function* () {
69
- const subsRef = yield* Ref.make([]);
70
- const counterRef = yield* Ref.make(0);
71
- const register = (filter, handler) => Effect.gen(function* () {
72
- const id = yield* nextSubscriptionId(counterRef);
73
- const live = { id, filter, handler };
74
- yield* appendSubscription(subsRef, live);
75
- const unsubscribe = removeSubscription(subsRef, id);
76
- return { id, unsubscribe };
77
- });
78
- const dispatch = (frame) => Effect.gen(function* () {
79
- // Snapshot at dispatch-start: OQ-3 A. Unsubscribes during this
80
- // frame mutate `subsRef` but our iteration walks `snapshot`.
81
- const snapshot = yield* Ref.get(subsRef);
82
- // Short-circuit the common pre-subscribe path (every inbound
83
- // frame before any `subscribe()` call) so hot-path dispatch
84
- // avoids even the `for…of` allocation.
85
- if (snapshot.length === 0)
86
- return;
87
- for (const sub of snapshot) {
88
- if (!matchesFilter(sub.filter, frame))
89
- continue;
90
- // Handlers must not throw; we catch defects defensively so
91
- // one buggy subscriber can't kill the dispatch loop or break
92
- // the reader fiber.
93
- yield* dispatchToSubscriber(sub, frame);
94
- }
95
- });
96
- const closeAll = Ref.set(subsRef, []);
97
- return { register, dispatch, closeAll };
98
- }).pipe(Effect.withSpan("makeSubscriberRegistry"));
68
+ function appendBroadSubscription(subsAllRef, live) {
69
+ return Ref.update(subsAllRef, (subscriptions) => [...subscriptions, live]);
70
+ }
71
+ function removeBroadSubscription(subsAllRef, id) {
72
+ return Ref.update(subsAllRef, (subscriptions) => subscriptions.filter((subscription) => subscription.id !== id));
73
+ }
74
+ function dispatchToBroadSubscriber(sub, frame) {
75
+ return Effect.suspend(() => sub.onFrame(frame)).pipe(Effect.catchAllDefect((err) => Effect.logWarning("subscribeAll onFrame callback threw", err)));
76
+ }
77
+ function closeBroadSubscriber(sub, cause) {
78
+ return Effect.suspend(() => sub.onClose(cause)).pipe(Effect.catchAllDefect((err) => Effect.logWarning("subscribeAll onClose callback threw", err)));
79
+ }
80
+ /**
81
+ * Single named typed→erased adapter for the refinement predicate. The
82
+ * `Stream.async` callback inside `notification/stream.ts` keeps the typed
83
+ * shape for the consumer's typed payload; storage in `LiveSubscription`
84
+ * uses the broad-union erased form. This is the only place the typed →
85
+ * erased boundary crosses, so the cast is acknowledged with an explicit
86
+ * lint suppression.
87
+ */
88
+ function eraseRefinement(refinement) {
89
+ if (refinement === undefined)
90
+ return undefined;
91
+ // The typed→erased boundary is by construction safe: the registry's
92
+ // `dispatch` loop only invokes the refinement with frames whose
93
+ // `definition === sub.definition`, so `frame.params` always satisfies
94
+ // `NotificationParamsOf<D>`.
95
+ // eslint-disable-next-line agent-code-guard/as-unknown-as -- documented typed→erased boundary, see comment above
96
+ return refinement; // #ignore-sloppy-code[as-unknown-as]: typed→erased boundary for heterogeneous registry storage; dispatch loop enforces definition identity before invocation
97
+ }
98
+ function buildRegister(subsRef, counterRef) {
99
+ return (definition, refinement, callbacks) => Effect.gen(function* () {
100
+ const id = yield* nextSubscriptionId(counterRef);
101
+ const erasedRefinement = eraseRefinement(refinement);
102
+ const live = {
103
+ id,
104
+ definition,
105
+ ...(erasedRefinement !== undefined
106
+ ? { refinement: erasedRefinement }
107
+ : {}),
108
+ onFrame: callbacks.onFrame,
109
+ onClose: callbacks.onClose,
110
+ };
111
+ yield* appendSubscription(subsRef, live);
112
+ const unregister = removeSubscription(subsRef, id);
113
+ return { id, unregister };
114
+ });
115
+ }
116
+ function buildRegisterAll(subsAllRef, counterRef) {
117
+ return (refinement, callbacks) => Effect.gen(function* () {
118
+ const id = yield* nextSubscriptionId(counterRef);
119
+ const live = {
120
+ id,
121
+ ...(refinement !== undefined ? { refinement } : {}),
122
+ onFrame: callbacks.onFrame,
123
+ onClose: callbacks.onClose,
124
+ };
125
+ yield* appendBroadSubscription(subsAllRef, live);
126
+ const unregister = removeBroadSubscription(subsAllRef, id);
127
+ return { id, unregister };
128
+ });
99
129
  }
100
130
  /**
101
- * Pure filter-match predicate. Exposed for unit testing so executable
102
- * client-side divergence proofs can force known-bad subscription
103
- * behavior without bypassing the production dispatch path.
131
+ * Run a user-supplied refinement predicate with throw isolation. A throw
132
+ * inside the predicate must NOT defect the dispatch Effect (which would
133
+ * starve sibling subscribers of the in-flight frame, AD1 path-(a) snapshot
134
+ * contract). Treat any throw as "predicate said false" — the frame is
135
+ * filtered out for this subscriber, the throw is logged, dispatch
136
+ * continues with the next subscription in the snapshot.
104
137
  *
105
- * Returns `true` iff `frame` matches every set field on `filter`:
106
- * - `filter.emissionTag === frame.params.__emissionTag` (strict ===)
107
- * - `filter.conversationId === frame.params.conversationId` (strict ===)
108
- * - `frame.method.startsWith(filter.notificationNamePrefix)`
109
- * Unset filter fields are wildcards.
138
+ * The warning is emitted via `Effect.runFork(Effect.logWarning(…))`
139
+ * (detached from the dispatch fiber's span/annotations) so the
140
+ * synchronous filter returned by `subAcceptsFrame` / `broadAcceptsFrame`
141
+ * stays synchronous — pulling logging into the surrounding `Effect.gen`
142
+ * would either (a) require the predicate to become an Effect (forcing
143
+ * every caller to `yield*`) or (b) accumulate warnings in a Ref and
144
+ * re-emit post-dispatch (extra state for a non-load-bearing log). The
145
+ * detached log is acceptable for predicate misuse — a noisy warning
146
+ * that names the call site (`subscribe` vs `subscribeAll`) is sufficient
147
+ * signal for the application author to find the throw in their
148
+ * refinement. Codex r2 P3-1 documented this trade-off rather than
149
+ * restructuring.
150
+ */
151
+ function safePredicate(predicate, params, context) {
152
+ try {
153
+ return predicate(params);
154
+ }
155
+ catch (err) {
156
+ Effect.runFork(Effect.logWarning(`${context} refinement predicate threw`, err));
157
+ return false;
158
+ }
159
+ }
160
+ /**
161
+ * Cognitive-complexity helper: decides whether a per-definition sub
162
+ * accepts a given frame. Predicate throws are caught (P2-1, codex r1):
163
+ * a throwing refinement returns `false` rather than defecting the
164
+ * dispatch Effect.
110
165
  */
111
- export function matchesFilter(filter, frame) {
112
- const methodPrefix = filter.notificationNamePrefix;
113
- if (methodPrefix !== undefined &&
114
- !matchesMethodPrefix(methodPrefix, frame.method))
166
+ function subAcceptsFrame(sub, frame) {
167
+ if (sub.definition !== frame.definition)
168
+ return false;
169
+ if (sub.refinement !== undefined &&
170
+ !safePredicate(sub.refinement, frame.params, "subscribe"))
115
171
  return false;
116
- const params = isNotificationParamsRecord(frame.params)
117
- ? frame.params
118
- : null;
119
- return (matchesPayloadValue(params, "__emissionTag", filter.emissionTag) &&
120
- matchesPayloadValue(params, "conversationId", filter.conversationId));
172
+ return true;
121
173
  }
122
- function matchesMethodPrefix(prefix, method) {
123
- return method.startsWith(prefix);
174
+ /** Same as `subAcceptsFrame`, but for broad-union subscriptions. */
175
+ function broadAcceptsFrame(sub, frame) {
176
+ return (sub.refinement === undefined ||
177
+ safePredicate(sub.refinement, frame, "subscribeAll"));
124
178
  }
125
- function matchesPayloadValue(params, key, expected) {
126
- return expected === undefined || params?.[key] === expected;
179
+ function buildDispatch(subsRef, subsAllRef) {
180
+ return (frame) => Effect.gen(function* () {
181
+ // Snapshot both lists at iteration start (AD1 path-(a) semantic).
182
+ const snapshot = yield* Ref.get(subsRef);
183
+ const broadSnapshot = yield* Ref.get(subsAllRef);
184
+ const matching = snapshot.filter((sub) => subAcceptsFrame(sub, frame));
185
+ for (const sub of matching) {
186
+ yield* dispatchToSubscriber(sub, frame);
187
+ }
188
+ const matchingBroad = broadSnapshot.filter((sub) => broadAcceptsFrame(sub, frame));
189
+ for (const sub of matchingBroad) {
190
+ yield* dispatchToBroadSubscriber(sub, frame);
191
+ }
192
+ });
193
+ }
194
+ function buildCloseAll(subsRef, subsAllRef) {
195
+ return Effect.gen(function* () {
196
+ const snapshot = yield* Ref.getAndSet(subsRef, []);
197
+ const broadSnapshot = yield* Ref.getAndSet(subsAllRef, []);
198
+ const cause = new NotConnectedError({
199
+ message: "WebSocket not connected",
200
+ });
201
+ for (const sub of snapshot) {
202
+ yield* closeSubscriber(sub, cause);
203
+ }
204
+ for (const sub of broadSnapshot) {
205
+ yield* closeBroadSubscriber(sub, cause);
206
+ }
207
+ });
208
+ }
209
+ export function makeSubscriberRegistry() {
210
+ return Effect.gen(function* () {
211
+ const subsRef = yield* Ref.make([]);
212
+ const subsAllRef = yield* Ref.make([]);
213
+ const counterRef = yield* Ref.make(0);
214
+ return {
215
+ register: buildRegister(subsRef, counterRef),
216
+ registerAll: buildRegisterAll(subsAllRef, counterRef),
217
+ dispatch: buildDispatch(subsRef, subsAllRef),
218
+ closeAll: buildCloseAll(subsRef, subsAllRef),
219
+ };
220
+ }).pipe(Effect.withSpan("makeSubscriberRegistry"));
127
221
  }
128
222
  //# sourceMappingURL=subscribers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"subscribers.js","sourceRoot":"","sources":["../../src/runtime/subscribers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"subscribers.js","sourceRoot":"","sources":["../../src/runtime/subscribers.ts"],"names":[],"mappings":"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"}
package/dist/service.d.ts CHANGED
@@ -88,6 +88,16 @@ export declare class MoltZapService {
88
88
  private opts;
89
89
  private client;
90
90
  private _connected;
91
+ /**
92
+ * Service-owned scope (spec #596 / Spec B §"4.2 service.ts" lifecycle
93
+ * reshape). Opened in `connect()`, owns the `subscribeAll → Stream.runForEach`
94
+ * fan-out fiber. Closed in `close()` so the fiber terminates with the
95
+ * service.
96
+ *
97
+ * Held off the public `connect()` signature so callers do not need to
98
+ * thread a `Scope` requirement.
99
+ */
100
+ private serviceScope;
91
101
  private readonly conversationsRef;
92
102
  private readonly messagesRef;
93
103
  private readonly agentNamesRef;
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
package/dist/service.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { FileSystem, Path } from "@effect/platform";
2
2
  import { NodeContext } from "@effect/platform-node";
3
3
  import { AgentsLookup, AgentsLookupByName, ConversationsCreate, ConversationsGet, DispatchRequest, DispatchRelease, DispatchesConsumed, DispatchesExpired, DispatchesGet, MessageReceivedNotificationDefinition, ConversationCreatedNotificationDefinition, ConversationUpdatedNotificationDefinition, ConversationArchivedNotificationDefinition, ConversationUnarchivedNotificationDefinition, ConversationArchivedError, MessagesList, MessagesSend, NotConnectedError, rpcMethods, RpcServerError, RpcTimeoutError, } from "@moltzap/protocol";
4
- import { Config, ConfigProvider, Effect, HashMap, Option, Ref, Scope, } from "effect";
4
+ import { Config, ConfigProvider, Effect, HashMap, Option, Ref, Scope, Stream, } from "effect";
5
5
  import { MoltZapWsClient } from "./ws-client.js";
6
6
  import { AgentNotFoundError } from "./runtime/errors.js";
7
7
  import { getOr, snapshot } from "./runtime/refs.js";
@@ -10,6 +10,7 @@ import { getMoltZapAgentServiceSocketPath, getMoltZapServiceSocketPath, } from "
10
10
  import { startLocalSocketServer, stopLocalSocketServer, } from "./runtime/local-socket-server.js";
11
11
  import { buildContextEntries, makeContextCandidate, newMessagesForConversation, notificationTraceRecord, renderPart, ServiceInputError, } from "./runtime/service-helpers.js";
12
12
  import { decodeHistoryRequest, formatHistoryMessage, lastReadIdsForSession, } from "./runtime/local-history.js";
13
+ import { composeServiceTeardown } from "./runtime/service-teardown.js";
13
14
  const CROSS_CONTEXT_TEXT_LIMIT = 120;
14
15
  const DEFAULT_MAX_CONTEXT_CONVERSATIONS = 5;
15
16
  const DEFAULT_MAX_MESSAGES_PER_CONVERSATION = 3;
@@ -94,6 +95,16 @@ export class MoltZapService {
94
95
  opts;
95
96
  client = null;
96
97
  _connected = false;
98
+ /**
99
+ * Service-owned scope (spec #596 / Spec B §"4.2 service.ts" lifecycle
100
+ * reshape). Opened in `connect()`, owns the `subscribeAll → Stream.runForEach`
101
+ * fan-out fiber. Closed in `close()` so the fiber terminates with the
102
+ * service.
103
+ *
104
+ * Held off the public `connect()` signature so callers do not need to
105
+ * thread a `Scope` requirement.
106
+ */
107
+ serviceScope = null;
97
108
  conversationsRef = Effect.runSync(Ref.make(HashMap.empty()));
98
109
  messagesRef = Effect.runSync(Ref.make(HashMap.empty()));
99
110
  agentNamesRef = Effect.runSync(Ref.make(HashMap.empty()));
@@ -169,7 +180,7 @@ export class MoltZapService {
169
180
  /** Effect-native: compose via `yield*` or bridge at the edge via `Effect.runPromise`. */
170
181
  connect() {
171
182
  return Effect.gen(this, function* () {
172
- this.client = new MoltZapWsClient({
183
+ const client = new MoltZapWsClient({
173
184
  serverUrl: this.opts.serverUrl,
174
185
  agentKey: this.opts.agentKey,
175
186
  // Spec #222 OQ-6: arg required. The body doesn't branch on
@@ -184,13 +195,23 @@ export class MoltZapService {
184
195
  fanout(this.handlers.reconnect, helloOk);
185
196
  },
186
197
  });
187
- // Spec #222 OQ-4: per-notification callback is replaced by subscriptions.
188
- // Replacement: register a `{}` filter subscription before
189
- // `connect()` so every inbound notification still fans out to
190
- // `handleNotification`. Pre-connect registration is supported by the
191
- // registry.
192
- yield* this.client.subscribe({}, (notification) => Effect.sync(() => this.handleNotification(notification)));
193
- const helloOk = yield* this.client.connect();
198
+ this.client = client;
199
+ // Spec #596 / Spec B Goal #8: the legacy `subscribe({}, handler)` site
200
+ // is replaced by `subscribeAll().pipe(Stream.runForEach, …)` forked
201
+ // into a service-owned scope. The Stream is materialized BEFORE
202
+ // `connect()` so subscriptions are registered with the registry
203
+ // pre-handshake (pre-connect legality, preserved invariant).
204
+ //
205
+ // Stream errors of type `NotConnectedError` are surfaced on the
206
+ // fiber's failure channel only when the client transitions to
207
+ // terminal closed state (close() path); `Effect.catchAll` here
208
+ // would swallow them silently, so we route through `Effect.logError`
209
+ // before the fiber exits.
210
+ const serviceScope = yield* Scope.make();
211
+ this.serviceScope = serviceScope;
212
+ const fanoutEffect = client.subscribeAll().pipe(Stream.runForEach((notification) => Effect.sync(() => this.handleNotification(notification))), Effect.catchAll((cause) => Effect.logWarning("MoltZapService notification fan-out terminated", cause)), Effect.asVoid);
213
+ yield* Effect.forkIn(fanoutEffect, serviceScope);
214
+ const helloOk = yield* client.connect();
194
215
  this._connected = true;
195
216
  this._ownAgentId = helloOk.agentId;
196
217
  return helloOk;
@@ -205,10 +226,22 @@ export class MoltZapService {
205
226
  close() {
206
227
  this._connected = false;
207
228
  Effect.runFork(this.stopSocketServer());
208
- if (this.client) {
209
- Effect.runFork(this.client.close());
210
- }
229
+ // Spec #596 / Spec B §"4.2 service.ts": close the service-owned scope
230
+ // BEFORE the client. Closing the scope interrupts the
231
+ // `subscribeAll().pipe(Stream.runForEach, …)` fiber; the client's
232
+ // `close()` then closes the registry which fires `onClose` on every
233
+ // live subscription's Stream — but since our consumer fiber has
234
+ // already been interrupted, the typed-error delivery is to a
235
+ // terminated consumer (no-op, idempotent).
236
+ // Order: close the service-scope FIRST (interrupting the
237
+ // `subscribeAll → runForEach` fiber), THEN close the ws-client.
238
+ // zipRight chains the two Effects sequentially inside a single
239
+ // fork so the ordering is honoured deterministically.
240
+ const scopeToClose = this.serviceScope;
241
+ const clientToClose = this.client;
242
+ this.serviceScope = null;
211
243
  this.client = null;
244
+ Effect.runFork(composeServiceTeardown(scopeToClose, clientToClose));
212
245
  Effect.runSync(Effect.all([
213
246
  Ref.set(this.conversationsRef, HashMap.empty()),
214
247
  Ref.set(this.messagesRef, HashMap.empty()),