@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.
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/notification/__tests__/filter-equivalence.test.d.ts +2 -0
- package/dist/notification/__tests__/filter-equivalence.test.d.ts.map +1 -0
- package/dist/notification/__tests__/filter-equivalence.test.js +123 -0
- package/dist/notification/__tests__/filter-equivalence.test.js.map +1 -0
- package/dist/notification/__tests__/snapshot-semantics.test.d.ts +2 -0
- package/dist/notification/__tests__/snapshot-semantics.test.d.ts.map +1 -0
- package/dist/notification/__tests__/snapshot-semantics.test.js +261 -0
- package/dist/notification/__tests__/snapshot-semantics.test.js.map +1 -0
- package/dist/notification/__tests__/snapshot-semantics.types-check.d.ts +3 -0
- package/dist/notification/__tests__/snapshot-semantics.types-check.d.ts.map +1 -0
- package/dist/notification/__tests__/snapshot-semantics.types-check.js +62 -0
- package/dist/notification/__tests__/snapshot-semantics.types-check.js.map +1 -0
- package/dist/notification/errors.d.ts +27 -0
- package/dist/notification/errors.d.ts.map +1 -0
- package/dist/notification/errors.js +24 -0
- package/dist/notification/errors.js.map +1 -0
- package/dist/notification/stream.d.ts +84 -0
- package/dist/notification/stream.d.ts.map +1 -0
- package/dist/notification/stream.js +106 -0
- package/dist/notification/stream.js.map +1 -0
- package/dist/runtime/index.d.ts +3 -4
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +3 -3
- package/dist/runtime/service-teardown.d.ts +5 -0
- package/dist/runtime/service-teardown.d.ts.map +1 -0
- package/dist/runtime/service-teardown.js +36 -0
- package/dist/runtime/service-teardown.js.map +1 -0
- package/dist/runtime/service-teardown.test.d.ts +2 -0
- package/dist/runtime/service-teardown.test.d.ts.map +1 -0
- package/dist/runtime/service-teardown.test.js +80 -0
- package/dist/runtime/service-teardown.test.js.map +1 -0
- package/dist/runtime/subscribers.d.ts +74 -136
- package/dist/runtime/subscribers.d.ts.map +1 -1
- package/dist/runtime/subscribers.js +187 -93
- package/dist/runtime/subscribers.js.map +1 -1
- package/dist/service.d.ts +10 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +45 -12
- package/dist/service.js.map +1 -1
- package/dist/test-utils/conformance-adapter.d.ts +6 -16
- package/dist/test-utils/conformance-adapter.d.ts.map +1 -1
- package/dist/test-utils/conformance-adapter.js +100 -59
- package/dist/test-utils/conformance-adapter.js.map +1 -1
- package/dist/ws-client-test-support.d.ts +1 -1
- package/dist/ws-client-test-support.d.ts.map +1 -1
- package/dist/ws-client-test-support.js +24 -3
- package/dist/ws-client-test-support.js.map +1 -1
- package/dist/ws-client.d.ts +52 -54
- package/dist/ws-client.d.ts.map +1 -1
- package/dist/ws-client.js +40 -168
- package/dist/ws-client.js.map +1 -1
- package/package.json +3 -3
- package/dist/runtime/subscribers.test.d.ts +0 -2
- package/dist/runtime/subscribers.test.d.ts.map +0 -1
- package/dist/runtime/subscribers.test.js +0 -193
- 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":"
|
|
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
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
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
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* `closeAll` are `Effect<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.
|
|
47
|
+
return Effect.suspend(() => sub.onFrame(frame)).pipe(Effect.catchAllDefect((err) => Effect.logWarning("subscriber onFrame callback threw", err)));
|
|
45
48
|
}
|
|
46
|
-
function
|
|
47
|
-
return
|
|
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
|
-
* -
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
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
|
-
|
|
68
|
-
return
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
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
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
117
|
-
? frame.params
|
|
118
|
-
: null;
|
|
119
|
-
return (matchesPayloadValue(params, "__emissionTag", filter.emissionTag) &&
|
|
120
|
-
matchesPayloadValue(params, "conversationId", filter.conversationId));
|
|
172
|
+
return true;
|
|
121
173
|
}
|
|
122
|
-
|
|
123
|
-
|
|
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
|
|
126
|
-
return
|
|
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":"AAAA
|
|
1
|
+
{"version":3,"file":"subscribers.js","sourceRoot":"","sources":["../../src/runtime/subscribers.ts"],"names":[],"mappings":"AAAA,2UAA2U;AAE3U;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EACL,iBAAiB,GAIlB,MAAM,mBAAmB,CAAC;AAI3B,MAAM,mBAAmB,GAAG,KAAK,CAAC,OAAO,EAAkB,CAAC;AA8H5D,SAAS,kBAAkB,CACzB,UAA2B;IAE3B,OAAO,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAC5D,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAC3D,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CACzB,OAAiD,EACjD,IAAsB;IAEtB,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,GAAG,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,kBAAkB,CACzB,OAAiD,EACjD,EAAkB;IAElB,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,aAAa,EAAE,EAAE,CAC3C,aAAa,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,CAAC,CAC/D,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAC3B,GAAqB,EACrB,KAAqD;IAErD,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAClD,MAAM,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE,EAAE,CAC5B,MAAM,CAAC,UAAU,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAC5D,CACF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,GAAqB,EACrB,KAAwB;IAExB,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAClD,MAAM,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE,EAAE,CAC5B,MAAM,CAAC,UAAU,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAC5D,CACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAS,uBAAuB,CAC9B,UAAyD,EACzD,IAA2B;IAE3B,OAAO,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,GAAG,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,uBAAuB,CAC9B,UAAyD,EACzD,EAAkB;IAElB,OAAO,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,aAAa,EAAE,EAAE,CAC9C,aAAa,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,CAAC,CAC/D,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAChC,GAA0B,EAC1B,KAAqD;IAErD,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAClD,MAAM,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE,EAAE,CAC5B,MAAM,CAAC,UAAU,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAC9D,CACF,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAC3B,GAA0B,EAC1B,KAAwB;IAExB,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAClD,MAAM,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE,EAAE,CAC5B,MAAM,CAAC,UAAU,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAC9D,CACF,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CACtB,UAAsE;IAEtE,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC/C,oEAAoE;IACpE,gEAAgE;IAChE,sEAAsE;IACtE,6BAA6B;IAC7B,iHAAiH;IACjH,OAAO,UAAqD,CAAC,CAAC,6JAA6J;AAC7N,CAAC;AAED,SAAS,aAAa,CACpB,OAAiD,EACjD,UAA2B;IAE3B,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,CAC3C,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACjD,MAAM,gBAAgB,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,IAAI,GAAqB;YAC7B,EAAE;YACF,UAAU;YACV,GAAG,CAAC,gBAAgB,KAAK,SAAS;gBAChC,CAAC,CAAC,EAAE,UAAU,EAAE,gBAAgB,EAAE;gBAClC,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,EAAE,SAAS,CAAC,OAAkC;YACrD,OAAO,EAAE,SAAS,CAAC,OAAO;SAC3B,CAAC;QACF,KAAK,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,UAAU,GAAG,kBAAkB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACnD,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,gBAAgB,CACvB,UAAyD,EACzD,UAA2B;IAE3B,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,CAC/B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;QACjD,MAAM,IAAI,GAA0B;YAClC,EAAE;YACF,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnD,OAAO,EAAE,SAAS,CAAC,OAAO;YAC1B,OAAO,EAAE,SAAS,CAAC,OAAO;SAC3B,CAAC;QACF,KAAK,CAAC,CAAC,uBAAuB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,uBAAuB,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3D,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAS,aAAa,CACpB,SAAiC,EACjC,MAAS,EACT,OAAe;IAEf,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,OAAO,CACZ,MAAM,CAAC,UAAU,CAAC,GAAG,OAAO,6BAA6B,EAAE,GAAG,CAAC,CAChE,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CACtB,GAAqB,EACrB,KAAqD;IAErD,IAAI,GAAG,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IACtD,IACE,GAAG,CAAC,UAAU,KAAK,SAAS;QAC5B,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC;QAEzD,OAAO,KAAK,CAAC;IACf,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oEAAoE;AACpE,SAAS,iBAAiB,CACxB,GAA0B,EAC1B,KAAqD;IAErD,OAAO,CACL,GAAG,CAAC,UAAU,KAAK,SAAS;QAC5B,aAAa,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,cAAc,CAAC,CACrD,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CACpB,OAAiD,EACjD,UAAyD;IAEzD,OAAO,CAAC,KAAK,EAAE,EAAE,CACf,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,kEAAkE;QAClE,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACvE,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,KAAK,CAAC,CAAC,oBAAoB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CACjD,iBAAiB,CAAC,GAAG,EAAE,KAAK,CAAC,CAC9B,CAAC;QACF,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;YAChC,KAAK,CAAC,CAAC,yBAAyB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,aAAa,CACpB,OAAiD,EACjD,UAAyD;IAEzD,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CACnC,OAAO,EACP,EAAqC,CACtC,CAAC;QACF,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CACxC,UAAU,EACV,EAA0C,CAC3C,CAAC;QACF,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC;YAClC,OAAO,EAAE,yBAAyB;SACnC,CAAC,CAAC;QACH,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,KAAK,CAAC,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;YAChC,KAAK,CAAC,CAAC,oBAAoB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,sBAAsB;IAIpC,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAkC,EAAE,CAAC,CAAC;QACrE,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAChC,EAAE,CACH,CAAC;QACF,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtC,OAAO;YACL,QAAQ,EAAE,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC;YAC5C,WAAW,EAAE,gBAAgB,CAAC,UAAU,EAAE,UAAU,CAAC;YACrD,QAAQ,EAAE,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC;YAC5C,QAAQ,EAAE,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC;SAC7C,CAAC;IACJ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,CAAC;AACrD,CAAC"}
|
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;
|
package/dist/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,OAAO,EAKZ,KAAK,yBAAyB,EAE9B,KAAK,mBAAmB,EACxB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,KAAK,UAAU,EACf,KAAK,OAAO,EAEZ,KAAK,gCAAgC,EACrC,KAAK,kCAAkC,EAWvC,KAAK,YAAY,EAEjB,eAAe,EACf,KAAK,oBAAoB,EACzB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAGL,MAAM,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,OAAO,EAKZ,KAAK,yBAAyB,EAE9B,KAAK,mBAAmB,EACxB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,KAAK,UAAU,EACf,KAAK,OAAO,EAEZ,KAAK,gCAAgC,EACrC,KAAK,kCAAkC,EAWvC,KAAK,YAAY,EAEjB,eAAe,EACf,KAAK,oBAAoB,EACzB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAGL,MAAM,EAMP,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AA8EzD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,eAAe,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,uEAAuE;AACvE,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;CACf;AAED,iGAAiG;AACjG,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,sBAAsB,EAAE,EACjC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GACvB,MAAM,GAAG,IAAI,CAef;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;AAKhD,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B;;;;;;;;OAQG;IACH,QAAQ,CAAC,eAAe,EAAE,mBAAmB,CAAC,yBAAyB,CAAC,CAAC;IACzE,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,oBAAoB,EAAE,gCAAgC,CAAC;IAChE,QAAQ,CAAC,sBAAsB,EAAE,kCAAkC,CAAC;IACpE,QAAQ,CAAC,eAAe,EAAE,oBAAoB,CAAC,OAAO,eAAe,CAAC,CAAC;IACvE,QAAQ,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,OAAO,kBAAkB,CAAC,CAAC;IAC7E,QAAQ,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,OAAO,iBAAiB,CAAC,CAAC;CAC5E;AAED,KAAK,kBAAkB,GAAG,MAAM,sBAAsB,CAAC;AAEvD,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAkCD;;;;;;;;;;GAUG;AACH,qBAAa,cAAc;IAsIb,OAAO,CAAC,IAAI;IArIxB,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,UAAU,CAAS;IAE3B;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY,CAAqC;IAEzD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAEuC;IACxE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAEkD;IAC9E,OAAO,CAAC,QAAQ,CAAC,aAAa,CAC8B;IAC5D,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAEoB;IAC9D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAI9B;IACF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAM1B;IACF,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAqB;IAE7D;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6C;IAC5E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAcvB;IACF,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAiErC;IAEH,OAAO,CAAC,WAAW,CAAqB;gBAEpB,IAAI,EAAE,cAAc;IAExC,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,UAAU,IAAI,MAAM,GAAG,SAAS,CAEnC;IAED,yFAAyF;IACzF,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC;IAqDlD;;;;;OAKG;IACH,KAAK,IAAI,IAAI;IAuCb,OAAO,CAAC,iBAAiB,CAAqC;IAC9D,OAAO,CAAC,gBAAgB,CAAuB;IAE/C,6EAA6E;IAC7E,MAAM,CAAC,QAAQ,CAAC,WAAW,SAAiC;IAE5D;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAIjC,2DAA2D;IAC3D,IAAI,UAAU,IAAI,MAAM,CAGvB;IAED,iBAAiB,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC;IAmBxD,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,yBAAyB;IAkDjC,OAAO,CAAC,oBAAoB;IAqC5B,OAAO,CAAC,sBAAsB;IAkB9B,OAAO,CAAC,wBAAwB;IAyBhC,OAAO,CAAC,4BAA4B;IASpC,OAAO,CAAC,sBAAsB;IAgC9B,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAM7D,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAI/C,gBAAgB,IAAI,gBAAgB,EAAE;IAMtC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE;IAWrD,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAMjD;;;;;OAKG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IA+B/D,IAAI,CACF,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GACpD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAAC;IAqBvC;;;;OAIG;IACH,eAAe,CACb,MAAM,EAAE,QAAQ,CAAC,OAAO,eAAe,CAAC,GACvC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,eAAe,CAAC,EAAE,eAAe,CAAC;IAInE;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE;QACpB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;KACjC,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,aAAa,CAAC,EAAE,eAAe,CAAC;IAIlE,WAAW,CACT,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,GAAG,kBAAkB,CAAC;IA4B5D;;;;OAIG;IACH,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI;IAavE;;;;;OAKG;IACH,kBAAkB,CAChB,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;KAAE,GAChE;QAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAAE;IAmB5D;;;;OAIG;IACH,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG;QACvC,QAAQ,EAAE,gBAAgB,EAAE,CAAC;QAC7B,MAAM,EAAE,MAAM,IAAI,CAAC;KACpB;IAsCD,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,wBAAwB;IAgBhC,OAAO,CAAE,qBAAqB;IAgB9B,OAAO,CAAC,mBAAmB;IAoB3B,EAAE,CAAC,CAAC,SAAS,kBAAkB,EAC7B,YAAY,EAAE,CAAC,EACf,OAAO,EAAE,mBAAmB,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,GACtD,IAAI;IAMP,OAAO,CAAC,CAAC,SAAS,aAAa,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,EAC/C,UAAU,EAAE,CAAC,EACb,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EACnB,IAAI,CAAC,EAAE,cAAc,GACpB,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC;IAW9C;;;;;OAKG;IACH,OAAO,CAAC,+BAA+B;IA8BvC,SAAS,CAAC,kBAAkB,CAC1B,YAAY,EAAE,mBAAmB,CAAC,yBAAyB,CAAC,GAC3D,IAAI;IAMP,OAAO,CAAC,uBAAuB;IAU/B,OAAO,CAAC,yBAAyB;IAUjC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,iCAAiC;IAmBzC,OAAO,CAAC,qCAAqC;IAS7C,OAAO,CAAC,qCAAqC;IAM7C,OAAO,CAAC,sCAAsC;IAO9C,OAAO,CAAC,wCAAwC;IAOhD,OAAO,CAAC,8BAA8B;IAsBtC,OAAO,CAAC,wBAAwB;IAiDhC,OAAO,CAAC,YAAY;CAiBrB"}
|
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
|
-
|
|
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
|
-
|
|
188
|
-
//
|
|
189
|
-
// `
|
|
190
|
-
//
|
|
191
|
-
// registry
|
|
192
|
-
|
|
193
|
-
|
|
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
|
-
|
|
209
|
-
|
|
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()),
|