@moltzap/client 2026.519.0 → 2026.519.2

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 (66) hide show
  1. package/dist/index.d.ts +2 -2
  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/errors.d.ts +0 -13
  26. package/dist/runtime/errors.d.ts.map +1 -1
  27. package/dist/runtime/errors.js +0 -10
  28. package/dist/runtime/errors.js.map +1 -1
  29. package/dist/runtime/index.d.ts +3 -4
  30. package/dist/runtime/index.d.ts.map +1 -1
  31. package/dist/runtime/index.js +3 -3
  32. package/dist/runtime/service-teardown.d.ts +5 -0
  33. package/dist/runtime/service-teardown.d.ts.map +1 -0
  34. package/dist/runtime/service-teardown.js +36 -0
  35. package/dist/runtime/service-teardown.js.map +1 -0
  36. package/dist/runtime/service-teardown.test.d.ts +2 -0
  37. package/dist/runtime/service-teardown.test.d.ts.map +1 -0
  38. package/dist/runtime/service-teardown.test.js +80 -0
  39. package/dist/runtime/service-teardown.test.js.map +1 -0
  40. package/dist/runtime/subscribers.d.ts +74 -136
  41. package/dist/runtime/subscribers.d.ts.map +1 -1
  42. package/dist/runtime/subscribers.js +187 -93
  43. package/dist/runtime/subscribers.js.map +1 -1
  44. package/dist/service.d.ts +10 -0
  45. package/dist/service.d.ts.map +1 -1
  46. package/dist/service.js +45 -12
  47. package/dist/service.js.map +1 -1
  48. package/dist/test-utils/conformance-adapter.d.ts +6 -16
  49. package/dist/test-utils/conformance-adapter.d.ts.map +1 -1
  50. package/dist/test-utils/conformance-adapter.js +100 -59
  51. package/dist/test-utils/conformance-adapter.js.map +1 -1
  52. package/dist/ws-client-test-support.d.ts +13 -10
  53. package/dist/ws-client-test-support.d.ts.map +1 -1
  54. package/dist/ws-client-test-support.js +44 -11
  55. package/dist/ws-client-test-support.js.map +1 -1
  56. package/dist/ws-client.d.ts +91 -104
  57. package/dist/ws-client.d.ts.map +1 -1
  58. package/dist/ws-client.js +78 -244
  59. package/dist/ws-client.js.map +1 -1
  60. package/dist/ws-client.test.js +33 -36
  61. package/dist/ws-client.test.js.map +1 -1
  62. package/package.json +3 -3
  63. package/dist/runtime/subscribers.test.d.ts +0 -2
  64. package/dist/runtime/subscribers.test.d.ts.map +0 -1
  65. package/dist/runtime/subscribers.test.js +0 -193
  66. package/dist/runtime/subscribers.test.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -4,8 +4,8 @@
4
4
  export { MoltZapService, formatCrossConversationBlock, sanitizeForSystemReminder, type ConversationMeta, type ContextOptions, type CrossConvMessage, type CrossConversationEntry, type ServiceOptions, type ServiceRpcError, } from "./service.js";
5
5
  export { AgentNotFoundError, MalformedFrameError } from "./runtime/errors.js";
6
6
  export { MoltZapChannelCore, type ChannelCoreOptions, type ChannelService, type ContextBlocks, type DispatchAdmissionDecision, type DispatchAdmissionRequest, type DispatchReleaseFrame, type EnrichedConversationMeta, type EnrichedInboundMessage, type EnrichedSender, type InboundHandler, type PendingDispatchMessage, } from "./channel-core.js";
7
- export { MoltZapWsClient, type MoltZapWsClientOptions, type ServerRpcContext, type ServerRpcHandler, type RpcCallOptions, } from "./ws-client.js";
8
- export type { SubscriptionFilter, SubscriptionId, NotificationSubscription, SubscriberHandler, } from "./runtime/subscribers.js";
7
+ export { MoltZapWsClient, type MoltZapWsClientOptions, type AppCallbackHandlers, type TaskCallbackContext, type RpcCallOptions, } from "./ws-client.js";
9
8
  export type { CloseInfo } from "./runtime/close-info.js";
9
+ export { TimeoutError as NotificationTimeoutError, StreamClosedError as NotificationStreamClosedError, type NotificationConsumerError, } from "./notification/errors.js";
10
10
  export { registerAgent, type RegisterAgentOptions, type RegisterResponse, } from "./auth.js";
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,yBAAyB,EACzB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EACL,kBAAkB,EAClB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,sBAAsB,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,eAAe,EACf,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,cAAc,GACpB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,GACtB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,yBAAyB,EACzB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EACL,kBAAkB,EAClB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,sBAAsB,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,eAAe,EACf,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAIzD,OAAO,EACL,YAAY,IAAI,wBAAwB,EACxC,iBAAiB,IAAI,6BAA6B,EAClD,KAAK,yBAAyB,GAC/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,GACtB,MAAM,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -5,5 +5,9 @@ export { MoltZapService, formatCrossConversationBlock, sanitizeForSystemReminder
5
5
  export { AgentNotFoundError, MalformedFrameError } from "./runtime/errors.js";
6
6
  export { MoltZapChannelCore, } from "./channel-core.js";
7
7
  export { MoltZapWsClient, } from "./ws-client.js";
8
+ // Spec B (#596) — tagged errors for the typed-Stream subscribe surface.
9
+ // `NotificationConsumerError` is a type union (see notification/errors.ts
10
+ // header for rationale, codex review r1 finding #8).
11
+ export { TimeoutError as NotificationTimeoutError, StreamClosedError as NotificationStreamClosedError, } from "./notification/errors.js";
8
12
  export { registerAgent, } from "./auth.js";
9
13
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,yBAAyB,GAO1B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EACL,kBAAkB,GAYnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,eAAe,GAKhB,MAAM,gBAAgB,CAAC;AAQxB,OAAO,EACL,aAAa,GAGd,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,yBAAyB,GAO1B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EACL,kBAAkB,GAYnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,eAAe,GAKhB,MAAM,gBAAgB,CAAC;AAExB,wEAAwE;AACxE,0EAA0E;AAC1E,qDAAqD;AACrD,OAAO,EACL,YAAY,IAAI,wBAAwB,EACxC,iBAAiB,IAAI,6BAA6B,GAEnD,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,aAAa,GAGd,MAAM,WAAW,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=filter-equivalence.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-equivalence.test.d.ts","sourceRoot":"","sources":["../../../src/notification/__tests__/filter-equivalence.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,123 @@
1
+ /* eslint-disable max-nested-callbacks, max-lines-per-function, sonarjs/max-lines-per-function, agent-code-guard/as-unknown-as, agent-code-guard/async-keyword, jsdoc/text-escaping -- fast-check + Effect.gen + Stream.runForEach nest by construction; the cross-shape brand erasure in `oracle`/`fakeOtherFrame` is the typed→erased boundary the property test deliberately probes; fc.asyncProperty requires an async function */
2
+ /**
3
+ * Filter-equivalence oracle (spec #596 §Acceptance criteria).
4
+ *
5
+ * For any property-generated sequence of inbound notifications (length up
6
+ * to 32, value pool size up to 8) and any property-generated typed
7
+ * predicate `p`, the Stream-based subscribe API output equals the pure-JS
8
+ * reference `frames.filter(frame => def===frame.definition && p(frame.params))`.
9
+ *
10
+ * The oracle is a pure-JS reference implementation embedded in this file
11
+ * (NOT a reference to the deleted three-storage shape).
12
+ *
13
+ * Bounded generators per spec: max array length 32, value pool size 8.
14
+ *
15
+ * The type-guard overload narrows the Stream's payload to
16
+ * `DecodedNotification<D, R>`; the second property-test below pins the
17
+ * runtime narrowing matches the compile-time canary in
18
+ * `snapshot-semantics.types-check.ts → Canary #1`.
19
+ */
20
+ import { describe, expect, it } from "vitest";
21
+ import * as fc from "fast-check";
22
+ import { Effect, Fiber, Ref, Stream } from "effect";
23
+ import { PresenceChangedNotificationDefinition, } from "@moltzap/protocol";
24
+ import { makeSubscriberRegistry } from "../../runtime/subscribers.js";
25
+ import { subscribe } from "../stream.js";
26
+ const MAX_SEQUENCE_LENGTH = 32;
27
+ const VALUE_POOL_SIZE = 8;
28
+ const PROPERTY_RUN_COUNT = 25;
29
+ const arbAgentId = fc
30
+ .integer({ min: 0, max: VALUE_POOL_SIZE - 1 })
31
+ .map((n) => `agent-${n}`);
32
+ const arbStatus = fc.constantFrom("online", "offline");
33
+ const arbGeneratedFrame = fc.record({
34
+ definitionTag: fc.constantFrom("presence", "other"),
35
+ agentId: arbAgentId,
36
+ status: arbStatus,
37
+ });
38
+ const arbSequence = fc.array(arbGeneratedFrame, {
39
+ minLength: 0,
40
+ maxLength: MAX_SEQUENCE_LENGTH,
41
+ });
42
+ /** Pure-JS reference oracle. Filters by definition identity + predicate. */
43
+ function oracle(frames, predicate) {
44
+ const presenceOnly = frames.filter((f) => f.definitionTag === "presence");
45
+ const presenceParams = presenceOnly.map((f) => ({ agentId: f.agentId, status: f.status }));
46
+ return presenceParams.filter(predicate);
47
+ }
48
+ function decodedPresence(generated) {
49
+ return {
50
+ _tag: "Notification",
51
+ jsonrpc: "2.0",
52
+ definition: PresenceChangedNotificationDefinition,
53
+ method: PresenceChangedNotificationDefinition.name,
54
+ params: {
55
+ agentId: generated.agentId,
56
+ status: generated.status,
57
+ },
58
+ };
59
+ }
60
+ function fakeOtherFrame(generated) {
61
+ // A frame whose `.definition` reference does NOT match
62
+ // `PresenceChangedNotificationDefinition` — used to verify the registry's
63
+ // definition-identity filter drops it before the predicate runs.
64
+ const raw = {
65
+ _tag: "Notification",
66
+ jsonrpc: "2.0",
67
+ definition: { name: "other/method" },
68
+ method: "other/method",
69
+ params: { agentId: generated.agentId, status: generated.status },
70
+ };
71
+ return raw; // #ignore-sloppy-code[as-unknown-as]: fake-frame for the non-matching arm; the test is precisely about the boundary's behaviour on misshapen frames
72
+ }
73
+ describe("Spec B filter-equivalence oracle", () => {
74
+ it("Stream output equals pure-JS filter oracle for arbitrary inputs", () => fc.assert(fc.asyncProperty(arbSequence, async (frames) => {
75
+ // Property-generated predicate: deterministic, total, varies by
76
+ // status. Closing over an outer counter would invalidate the
77
+ // oracle equivalence.
78
+ const predicate = (params) => params.status === "online";
79
+ const collected = await Effect.runPromise(Effect.gen(function* () {
80
+ const registry = yield* makeSubscriberRegistry();
81
+ const seen = yield* Ref.make([]);
82
+ const fiber = yield* Effect.fork(subscribe(registry, PresenceChangedNotificationDefinition, predicate).pipe(Stream.runForEach((frame) => Ref.update(seen, (xs) => [...xs, frame.params])), Effect.catchAll(() => Effect.void)));
83
+ // Yield once to materialise the Stream's subscription via
84
+ // Stream.async's register callback.
85
+ yield* Effect.yieldNow();
86
+ for (const f of frames) {
87
+ const decoded = f.definitionTag === "presence"
88
+ ? decodedPresence(f)
89
+ : fakeOtherFrame(f);
90
+ yield* registry.dispatch(decoded);
91
+ }
92
+ yield* Effect.yieldNow();
93
+ yield* registry.closeAll;
94
+ yield* Fiber.join(fiber);
95
+ return yield* Ref.get(seen);
96
+ }));
97
+ const expected = oracle(frames, predicate);
98
+ expect(collected).toEqual(expected);
99
+ }), { numRuns: PROPERTY_RUN_COUNT }));
100
+ it("user-defined type guard narrows the Stream payload", () => Effect.runPromise(Effect.gen(function* () {
101
+ const registry = yield* makeSubscriberRegistry();
102
+ const seen = yield* Ref.make([]);
103
+ const isOnline = (params) => params.status === "online";
104
+ const fiber = yield* Effect.fork(subscribe(registry, PresenceChangedNotificationDefinition, isOnline).pipe(Stream.runForEach((frame) => Ref.update(seen, (xs) => [...xs, frame.params])), Effect.catchAll(() => Effect.void)));
105
+ yield* Effect.yieldNow();
106
+ yield* registry.dispatch(decodedPresence({
107
+ definitionTag: "presence",
108
+ agentId: "agent-0",
109
+ status: "online",
110
+ }));
111
+ yield* registry.dispatch(decodedPresence({
112
+ definitionTag: "presence",
113
+ agentId: "agent-1",
114
+ status: "offline",
115
+ }));
116
+ yield* Effect.yieldNow();
117
+ yield* registry.closeAll;
118
+ yield* Fiber.join(fiber);
119
+ const observed = yield* Ref.get(seen);
120
+ expect(observed).toEqual([{ agentId: "agent-0", status: "online" }]);
121
+ })));
122
+ });
123
+ //# sourceMappingURL=filter-equivalence.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-equivalence.test.js","sourceRoot":"","sources":["../../../src/notification/__tests__/filter-equivalence.test.ts"],"names":[],"mappings":"AAAA,saAAsa;AAEta;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACpD,OAAO,EACL,qCAAqC,GAGtC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAC/B,MAAM,eAAe,GAAG,CAAC,CAAC;AAC1B,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAY9B,MAAM,UAAU,GAAG,EAAE;KAClB,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,eAAe,GAAG,CAAC,EAAE,CAAC;KAC7C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AAE5B,MAAM,SAAS,GAAG,EAAE,CAAC,YAAY,CAAuB,QAAQ,EAAE,SAAS,CAAC,CAAC;AAE7E,MAAM,iBAAiB,GAAiC,EAAE,CAAC,MAAM,CAAC;IAChE,aAAa,EAAE,EAAE,CAAC,YAAY,CAAuB,UAAU,EAAE,OAAO,CAAC;IACzE,OAAO,EAAE,UAAU;IACnB,MAAM,EAAE,SAAS;CAClB,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG,EAAE,CAAC,KAAK,CAAC,iBAAiB,EAAE;IAC9C,SAAS,EAAE,CAAC;IACZ,SAAS,EAAE,mBAAmB;CAC/B,CAAC,CAAC;AAEH,4EAA4E;AAC5E,SAAS,MAAM,CACb,MAAqC,EACrC,SAA8C;IAE9C,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,UAAU,CAAC,CAAC;IAC1E,MAAM,cAAc,GAAG,YAAY,CAAC,GAAG,CACrC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAA8B,CAC1E,CAAC;IACF,OAAO,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,eAAe,CACtB,SAAyB;IAEzB,OAAO;QACL,IAAI,EAAE,cAAuB;QAC7B,OAAO,EAAE,KAAK;QACd,UAAU,EAAE,qCAAqC;QACjD,MAAM,EAAE,qCAAqC,CAAC,IAAI;QAClD,MAAM,EAAE;YACN,OAAO,EAAE,SAAS,CAAC,OAAoC;YACvD,MAAM,EAAE,SAAS,CAAC,MAAM;SACzB;KACmE,CAAC;AACzE,CAAC;AAMD,SAAS,cAAc,CAAC,SAAyB;IAC/C,uDAAuD;IACvD,0EAA0E;IAC1E,iEAAiE;IACjE,MAAM,GAAG,GAAG;QACV,IAAI,EAAE,cAAuB;QAC7B,OAAO,EAAE,KAAK;QACd,UAAU,EAAE,EAAE,IAAI,EAAE,cAAc,EAAa;QAC/C,MAAM,EAAE,cAAc;QACtB,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE;KACjE,CAAC;IACF,OAAO,GAA+B,CAAC,CAAC,oJAAoJ;AAC9L,CAAC;AAED,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAChD,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE,CACzE,EAAE,CAAC,MAAM,CACP,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAC7C,gEAAgE;QAChE,6DAA6D;QAC7D,sBAAsB;QACtB,MAAM,SAAS,GAAG,CAAC,MAAsB,EAAE,EAAE,CAC3C,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC;QAE7B,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,UAAU,CACvC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,sBAAsB,EAAE,CAAC;YACjD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAgC,EAAE,CAAC,CAAC;YAEhE,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAC9B,SAAS,CACP,QAAQ,EACR,qCAAqC,EACrC,SAAS,CACV,CAAC,IAAI,CACJ,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,EAAE,CAC1B,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAChD,EACD,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CACnC,CACF,CAAC;YAEF,0DAA0D;YAC1D,oCAAoC;YACpC,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAEzB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,MAAM,OAAO,GACX,CAAC,CAAC,aAAa,KAAK,UAAU;oBAC5B,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;oBACpB,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;gBACxB,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACpC,CAAC;YAED,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACzB,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACzB,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAEzB,OAAO,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC,CAAC,CACH,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC3C,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC,CAAC,EACF,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAChC,CAAC,CAAC;IAEL,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE,CAC5D,MAAM,CAAC,UAAU,CACf,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,sBAAsB,EAAE,CAAC;QACjD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAgC,EAAE,CAAC,CAAC;QAOhE,MAAM,QAAQ,GAAG,CAAC,MAAsB,EAA4B,EAAE,CACpE,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC;QAE7B,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAC9B,SAAS,CACP,QAAQ,EACR,qCAAqC,EACrC,QAAQ,CACT,CAAC,IAAI,CACJ,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,EAAE,CAC1B,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAChD,EACD,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CACnC,CACF,CAAC;QACF,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAEzB,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CACtB,eAAe,CAAC;YACd,aAAa,EAAE,UAAU;YACzB,OAAO,EAAE,SAAS;YAClB,MAAM,EAAE,QAAQ;SACjB,CAAC,CACH,CAAC;QACF,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CACtB,eAAe,CAAC;YACd,aAAa,EAAE,UAAU;YACzB,OAAO,EAAE,SAAS;YAClB,MAAM,EAAE,SAAS;SAClB,CAAC,CACH,CAAC;QAEF,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACzB,KAAK,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACzB,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEzB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CACH,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=snapshot-semantics.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-semantics.test.d.ts","sourceRoot":"","sources":["../../../src/notification/__tests__/snapshot-semantics.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,261 @@
1
+ /* eslint-disable max-nested-callbacks, max-lines-per-function, sonarjs/max-lines-per-function, agent-code-guard/no-example-only-tests -- vitest + Effect.gen + Stream.runForEach nest by construction; AD1 properties are scenario-shaped (snapshot semantics + lifecycle); generative coverage lives in filter-equivalence.test.ts */
2
+ /**
3
+ * Snapshot-semantics property test (validates AD1 via spec #222 §5.3 OQ-3
4
+ * acceptance criterion). Spec B (#596).
5
+ *
6
+ * Four architect-named properties (see `snapshot-semantics.types-check.ts`
7
+ * for the compile-time AD1 canaries):
8
+ *
9
+ * 1. "No notification with arrival time > T_cancel is delivered through s."
10
+ * — verified via two subscriptions (`s_observer` + `s_target`) racing
11
+ * against a series of dispatched frames. After `s_target` cancels at
12
+ * frame index K, only `s_observer` keeps receiving frames K+1…N.
13
+ * 2. "Unregister between frames doesn't affect prior dispatches." —
14
+ * verified by registering three subscribers, running `dispatch(frameN)`
15
+ * once; *after* the dispatch returns, interrupt `s2`, then
16
+ * `dispatch(frameN+1)` — assert s2 received frameN but not frameN+1.
17
+ * (Renamed in r1 cleanup per P2-3: this test does NOT exercise true
18
+ * mid-dispatch interleaving; the standalone "mid-dispatch" test below
19
+ * does.)
20
+ * 3. "In-flight dispatch of frame N is NOT interrupted by an unregister
21
+ * that commits during frame N." — verified by forking a dispatch whose
22
+ * first invoked subscriber suspends on a `Deferred`. While the
23
+ * dispatch fiber is parked mid-handler, interrupt a SIBLING
24
+ * subscriber's consumer fiber (which calls `handle.unregister`
25
+ * via the Stream finalizer); release the dispatch fiber and assert
26
+ * the interrupted sibling STILL received the frame — proving the
27
+ * dispatch is iterating a snapshot, not the live list.
28
+ * 4. "Closed client terminates all in-flight Streams with `NotConnectedError`."
29
+ * — verified by forking a `Stream.runForEach` consumer, calling
30
+ * `closeAll`, then asserting the fiber's exit is a typed
31
+ * `NotConnectedError` failure.
32
+ *
33
+ * The tests intentionally exercise `SubscriberRegistry` + the
34
+ * `notification/stream.ts` Stream factories together (the public API
35
+ * surface), not the registry alone — Canary #3's "internal Scope, no
36
+ * leakage" contract is what we are validating end-to-end.
37
+ *
38
+ * Per P3 #612 fix (architect revision): each `expect` here asserts a
39
+ * value computed by the system under test rather than the test's own
40
+ * input — no tautological "X === X" patterns.
41
+ *
42
+ * Determinism (r1 cleanup, P2-2): readiness between forked consumers and
43
+ * the dispatch path uses `Effect.yieldNow()` (deterministic single-tick
44
+ * scheduling) rather than `Effect.sleep(...)` (wall-clock dependent).
45
+ * Mid-dispatch suspension uses `Deferred` so the dispatch fiber is parked
46
+ * at a known point inside the handler, independent of any timer.
47
+ */
48
+ import { describe, expect, it } from "vitest";
49
+ import { Cause, Deferred, Effect, Exit, Fiber, Option, Ref, Stream, } from "effect";
50
+ import { NotConnectedError, } from "@moltzap/protocol";
51
+ import { PresenceChangedNotificationDefinition, MessageReceivedNotificationDefinition, } from "@moltzap/protocol";
52
+ import { makeSubscriberRegistry } from "../../runtime/subscribers.js";
53
+ import { subscribe, subscribeAll } from "../stream.js";
54
+ const PROP_TEST_FRAME_COUNT = 6;
55
+ const PROP_TEST_CANCEL_AT = 3;
56
+ function decodedPresence(seq) {
57
+ return {
58
+ _tag: "Notification",
59
+ jsonrpc: "2.0",
60
+ definition: PresenceChangedNotificationDefinition,
61
+ method: PresenceChangedNotificationDefinition.name,
62
+ params: {
63
+ agentId: `agent-${seq}`,
64
+ status: seq % 2 === 0 ? "online" : "offline",
65
+ },
66
+ };
67
+ }
68
+ function decodedMessageReceived() {
69
+ return {
70
+ _tag: "Notification",
71
+ jsonrpc: "2.0",
72
+ definition: MessageReceivedNotificationDefinition,
73
+ method: MessageReceivedNotificationDefinition.name,
74
+ params: {
75
+ message: {
76
+ id: "m1",
77
+ conversationId: "c1",
78
+ senderId: "agent-0",
79
+ parts: [{ type: "text", text: "hi" }],
80
+ },
81
+ },
82
+ };
83
+ }
84
+ describe("AD1 snapshot semantics — Stream cancellation", () => {
85
+ it("no notification with index > T_cancel is delivered through s_target", () => Effect.runPromise(Effect.gen(function* () {
86
+ const registry = yield* makeSubscriberRegistry();
87
+ const observerSeen = yield* Ref.make([]);
88
+ const targetSeen = yield* Ref.make([]);
89
+ const observerFiber = yield* Effect.fork(subscribe(registry, PresenceChangedNotificationDefinition).pipe(Stream.runForEach((frame) => Ref.update(observerSeen, (xs) => [
90
+ ...xs,
91
+ Number(frame.params.agentId.slice("agent-".length)),
92
+ ])), Effect.catchAll(() => Effect.void)));
93
+ const targetStream = subscribe(registry, PresenceChangedNotificationDefinition);
94
+ const targetFiber = yield* Effect.fork(targetStream.pipe(Stream.take(PROP_TEST_CANCEL_AT), Stream.runForEach((frame) => Ref.update(targetSeen, (xs) => [
95
+ ...xs,
96
+ Number(frame.params.agentId.slice("agent-".length)),
97
+ ])), Effect.catchAll(() => Effect.void)));
98
+ // Yield once so each forked consumer's Stream.async register
99
+ // callback commits its subscription into `subsRef` before the
100
+ // dispatch loop reads the snapshot. `Effect.yieldNow()` is
101
+ // deterministic (single-tick scheduling) — replaces the prior
102
+ // `Effect.sleep("10 millis")` which was wall-clock dependent
103
+ // (P2-2 r1 cleanup).
104
+ yield* Effect.yieldNow();
105
+ for (let i = 0; i < PROP_TEST_FRAME_COUNT; i++) {
106
+ yield* registry.dispatch(decodedPresence(i));
107
+ }
108
+ yield* Effect.yieldNow();
109
+ yield* Fiber.join(targetFiber);
110
+ // Drain the registry by running closeAll so the observer fiber
111
+ // terminates with NotConnectedError and we can assert what it saw.
112
+ yield* registry.closeAll;
113
+ yield* Fiber.join(observerFiber);
114
+ const target = yield* Ref.get(targetSeen);
115
+ const observer = yield* Ref.get(observerSeen);
116
+ // Target only saw the first PROP_TEST_CANCEL_AT frames before
117
+ // Stream.take cancelled its subscription.
118
+ expect(target.length).toBe(PROP_TEST_CANCEL_AT);
119
+ for (const idx of target) {
120
+ expect(idx).toBeLessThan(PROP_TEST_CANCEL_AT);
121
+ }
122
+ // Observer (never cancelled) saw every frame.
123
+ expect(observer.length).toBe(PROP_TEST_FRAME_COUNT);
124
+ })));
125
+ it("unregister between frames doesn't affect prior dispatches", () => Effect.runPromise(Effect.gen(function* () {
126
+ // This test confirms a sequential property — dispatch frameN, then
127
+ // interrupt s2 BETWEEN dispatches, then dispatch frameN+1 — and
128
+ // observes that s2 received frameN (because it was registered) and
129
+ // did NOT receive frameN+1 (because the snapshot at the start of
130
+ // frameN+1's dispatch excludes the now-unregistered s2). Note that
131
+ // there is NO concurrent interleaving here: every step completes
132
+ // before the next begins. True mid-dispatch interleaving is
133
+ // exercised by the "in-flight dispatch is NOT interrupted by an
134
+ // unregister that commits during frame N" test below.
135
+ const registry = yield* makeSubscriberRegistry();
136
+ const receivedByS2 = yield* Ref.make([]);
137
+ const s1Fiber = yield* Effect.fork(subscribe(registry, PresenceChangedNotificationDefinition).pipe(Stream.runDrain, Effect.catchAll(() => Effect.void)));
138
+ const s3Fiber = yield* Effect.fork(subscribe(registry, PresenceChangedNotificationDefinition).pipe(Stream.runDrain, Effect.catchAll(() => Effect.void)));
139
+ const s2Stream = subscribe(registry, PresenceChangedNotificationDefinition);
140
+ const s2Fiber = yield* Effect.fork(s2Stream.pipe(Stream.runForEach((frame) => Ref.update(receivedByS2, (xs) => [
141
+ ...xs,
142
+ Number(frame.params.agentId.slice("agent-".length)),
143
+ ])), Effect.catchAll(() => Effect.void)));
144
+ // Single-tick yield so every forked consumer's Stream.async
145
+ // register callback commits before the first dispatch reads
146
+ // the snapshot. Deterministic — see file header (P2-2 r1).
147
+ yield* Effect.yieldNow();
148
+ yield* registry.dispatch(decodedPresence(0));
149
+ // Drain s2's onFrame Effect into receivedByS2 deterministically.
150
+ yield* Effect.yieldNow();
151
+ // Interrupt s2's consumer; Stream finalizer runs `unregister`
152
+ // synchronously. Subsequent dispatch's snapshot must exclude s2.
153
+ yield* Fiber.interrupt(s2Fiber);
154
+ yield* registry.dispatch(decodedPresence(1));
155
+ yield* Effect.yieldNow();
156
+ const seen = yield* Ref.get(receivedByS2);
157
+ expect(seen).toEqual([0]);
158
+ // Tidy up sibling fibers.
159
+ yield* registry.closeAll;
160
+ yield* Fiber.join(s1Fiber);
161
+ yield* Fiber.join(s3Fiber);
162
+ })));
163
+ it("in-flight dispatch is NOT interrupted by an unregister that commits during frame N", () => Effect.runPromise(Effect.gen(function* () {
164
+ // True mid-dispatch interleaving — distinguishes the snapshot
165
+ // semantic from a live-list-iteration semantic (which would skip
166
+ // the unregistered subscriber).
167
+ //
168
+ // Method: register two subscribers directly via the registry API
169
+ // so we control the dispatch fiber's progress mid-handler. s1's
170
+ // handler parks the dispatcher on a `Deferred` inside onFrame.
171
+ // While parked, we call `s2.unregister` synchronously — mutating
172
+ // `subsRef`. We then release s1; the dispatcher continues to s2
173
+ // (per its captured snapshot) and invokes `s2.onFrame`. If the
174
+ // dispatcher iterated the LIVE list, s2 would have been skipped
175
+ // and `s2Received` would still be empty.
176
+ //
177
+ // (Stream-API end-to-end coverage is exercised by tests #1 and
178
+ // the closeAll lifecycle test #4; here we need the registry's
179
+ // direct API to control dispatch ordering deterministically.)
180
+ const registry = yield* makeSubscriberRegistry();
181
+ const enteredS1 = yield* Deferred.make();
182
+ const releaseS1 = yield* Deferred.make();
183
+ const s2Received = yield* Ref.make([]);
184
+ yield* registry.register(PresenceChangedNotificationDefinition, undefined, {
185
+ onFrame: () => Effect.gen(function* () {
186
+ yield* Deferred.succeed(enteredS1, void 0);
187
+ yield* Deferred.await(releaseS1);
188
+ }),
189
+ onClose: () => Effect.void,
190
+ });
191
+ const s2Handle = yield* registry.register(PresenceChangedNotificationDefinition, undefined, {
192
+ onFrame: (frame) => Ref.update(s2Received, (xs) => [
193
+ ...xs,
194
+ Number(frame.params.agentId.slice("agent-".length)),
195
+ ]),
196
+ onClose: () => Effect.void,
197
+ });
198
+ // Fork dispatch. Snapshot at fork time has both s1 and s2.
199
+ const dispatchFiber = yield* Effect.fork(registry.dispatch(decodedPresence(0)));
200
+ // Wait until s1's handler enters (dispatch is parked mid-flight).
201
+ yield* Deferred.await(enteredS1);
202
+ // Unregister s2 NOW — concurrently with the parked dispatch.
203
+ // Mutates subsRef; in-flight snapshot is unaffected.
204
+ yield* s2Handle.unregister;
205
+ // Release s1; dispatch proceeds to s2 per its snapshot.
206
+ yield* Deferred.succeed(releaseS1, void 0);
207
+ yield* Fiber.join(dispatchFiber);
208
+ const observed = yield* Ref.get(s2Received);
209
+ // Snapshot semantic: s2 was in the snapshot, so its onFrame fires
210
+ // even though it was unregistered while dispatch was mid-flight.
211
+ expect(observed).toEqual([0]);
212
+ // Sanity: confirm s2's unregister DID commit to subsRef — a
213
+ // subsequent dispatch must NOT deliver to s2.
214
+ yield* registry.dispatch(decodedPresence(1));
215
+ expect(yield* Ref.get(s2Received)).toEqual([0]);
216
+ yield* registry.closeAll;
217
+ })));
218
+ it("closeAll terminates in-flight Streams with NotConnectedError", () => Effect.runPromise(Effect.gen(function* () {
219
+ const registry = yield* makeSubscriberRegistry();
220
+ const fiber = yield* Effect.fork(subscribe(registry, MessageReceivedNotificationDefinition).pipe(Stream.runDrain));
221
+ // Deterministic single-tick yield so the Stream materialises its
222
+ // subscription (Stream.async register callback runs synchronously
223
+ // inside Stream.runDrain's setup on the forked fiber's first turn)
224
+ // before we call closeAll. P2-2 r1 cleanup.
225
+ yield* Effect.yieldNow();
226
+ yield* registry.closeAll;
227
+ const exit = yield* Fiber.await(fiber);
228
+ const failure = Exit.causeOption(exit).pipe(Option.flatMap(Cause.failureOption));
229
+ // Verify the typed failure was NotConnectedError, not a defect.
230
+ const ok = Option.match(failure, {
231
+ onNone: () => false,
232
+ onSome: (e) => e instanceof NotConnectedError,
233
+ });
234
+ expect(ok).toBe(true);
235
+ })));
236
+ it("subscribeAll receives every notification regardless of definition", () => Effect.runPromise(Effect.gen(function* () {
237
+ const registry = yield* makeSubscriberRegistry();
238
+ const observed = yield* Ref.make([]);
239
+ const fiber = yield* Effect.fork(subscribeAll(registry).pipe(Stream.runForEach((frame) => Ref.update(observed, (xs) => [
240
+ ...xs,
241
+ frame.definition.name,
242
+ ])), Effect.catchAll(() => Effect.void)));
243
+ // Single-tick yield ensures the forked subscribeAll consumer's
244
+ // register callback commits before dispatch reads the snapshot
245
+ // (P2-2 r1).
246
+ yield* Effect.yieldNow();
247
+ yield* registry.dispatch(decodedPresence(0));
248
+ yield* registry.dispatch(decodedMessageReceived());
249
+ // Drain the consumer's onFrame Effect into `observed` before
250
+ // closing — deterministic single-tick.
251
+ yield* Effect.yieldNow();
252
+ yield* registry.closeAll;
253
+ yield* Fiber.join(fiber);
254
+ const names = yield* Ref.get(observed);
255
+ expect(names).toEqual([
256
+ PresenceChangedNotificationDefinition.name,
257
+ MessageReceivedNotificationDefinition.name,
258
+ ]);
259
+ })));
260
+ });
261
+ //# sourceMappingURL=snapshot-semantics.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-semantics.test.js","sourceRoot":"","sources":["../../../src/notification/__tests__/snapshot-semantics.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ declare const _adhoc_phantom_canary_ref: unknown;
2
+ export { _adhoc_phantom_canary_ref };
3
+ //# sourceMappingURL=snapshot-semantics.types-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-semantics.types-check.d.ts","sourceRoot":"","sources":["../../../src/notification/__tests__/snapshot-semantics.types-check.ts"],"names":[],"mappings":"AAkLA,QAAA,MAAM,yBAAyB,EAAE,OAAsB,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Type-canary for AD1 (architect-decision: trust `Stream.runForEach`
3
+ * cancellation to preserve spec #222 §5.3 OQ-3 snapshot semantics).
4
+ *
5
+ * Compile-time assertions only — this file is referenced by `tsc --build`
6
+ * (via the package's vitest config glob) but has no runtime test bodies.
7
+ * Any drift in `subscribe` / `subscribeAll` public signatures, or in the
8
+ * Stream lifecycle contract, surfaces as a TypeScript error here.
9
+ *
10
+ * **DO NOT delete this file** without first updating spec #596 AD1 and
11
+ * the architect plan at issue #604.
12
+ *
13
+ * **Architect stub** (Spec B): canaries probe the architect-stubbed
14
+ * `subscribe` / `subscribeAll` signatures in `../stream.ts`. Impl-staff
15
+ * preserves the canary shapes and re-targets them at
16
+ * `MoltZapWsClient.prototype.subscribe` / `.subscribeAll` once the
17
+ * methods are wired.
18
+ */
19
+ import { Stream } from "effect";
20
+ import { subscribe, subscribeAll } from "../stream.js";
21
+ // Phantom value-level pin: passing a Canary alias forces tsc to resolve
22
+ // the alias; a `false` resolution fires TS2344 because `false` is not
23
+ // assignable to the `true` constraint.
24
+ function assertCanary() {
25
+ // intentionally empty: type-level pin
26
+ }
27
+ import { PresenceChangedNotificationDefinition } from "@moltzap/protocol";
28
+ const _canary1bStream = subscribe(_canary1bRegistry, PresenceChangedNotificationDefinition, _canary1bIsOnline);
29
+ // P3 #612 fix: ground Canary #3 in the ACTUAL return type of a real
30
+ // `Stream.runForEach(_subStreamForCanary, _handlerForCanary)` call,
31
+ // not a manually-reconstructed `Effect<…, E, R>` inferred from the
32
+ // Stream's own type parameters (which would be a tautology). Calling
33
+ // `runForEach` and capturing the return type forces TypeScript to
34
+ // resolve the overloads using the real Stream value's signature.
35
+ const _ad1Canary3Helper = () => Stream.runForEach(_subStreamForCanary, _handlerForCanary);
36
+ // Phantom value-level call sites: pin each Canary alias as used and let
37
+ // knip/oxlint see the file as fully reachable. tsc never invokes
38
+ // `_ad1Canaries`; the canary alias resolutions happen at type-check
39
+ // time inside the function body.
40
+ function _ad1Canaries() {
41
+ assertCanary();
42
+ assertCanary();
43
+ assertCanary();
44
+ assertCanary();
45
+ assertCanary();
46
+ // Force the runtime-shape value declarations to be used (otherwise
47
+ // tsc warns even on `declare const`). Also exercises a real call
48
+ // into Stream.runForEach to keep Canary #3's premise grounded.
49
+ Stream.runForEach(_subStreamForCanary, _handlerForCanary);
50
+ _ad1Canary3Helper();
51
+ // Touch `_canary1bStream` so tsc keeps the canary-call expression
52
+ // alive (the `Equal<>` assertion + the assignment below force the
53
+ // overload to resolve at compile time).
54
+ const _touch1b = _canary1bStream;
55
+ if (false)
56
+ _touch1b;
57
+ }
58
+ // Discard return so module-level `_ad1Canaries` is read; an assignment
59
+ // to `_` satisfies the linter without invoking the function.
60
+ const _adhoc_phantom_canary_ref = _ad1Canaries;
61
+ export { _adhoc_phantom_canary_ref };
62
+ //# sourceMappingURL=snapshot-semantics.types-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-semantics.types-check.js","sourceRoot":"","sources":["../../../src/notification/__tests__/snapshot-semantics.types-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAQhC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAQvD,wEAAwE;AACxE,sEAAsE;AACtE,uCAAuC;AACvC,SAAS,YAAY;IACnB,sCAAsC;AACxC,CAAC;AA2CD,OAAO,EAAE,qCAAqC,EAAE,MAAM,mBAAmB,CAAC;AAS1E,MAAM,eAAe,GAAG,SAAS,CAC/B,iBAAiB,EACjB,qCAAqC,EACrC,iBAAiB,CAClB,CAAC;AAsCF,oEAAoE;AACpE,oEAAoE;AACpE,mEAAmE;AACnE,qEAAqE;AACrE,kEAAkE;AAClE,iEAAiE;AACjE,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAC7B,MAAM,CAAC,UAAU,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,CAAC;AAe5D,wEAAwE;AACxE,iEAAiE;AACjE,oEAAoE;AACpE,iCAAiC;AACjC,SAAS,YAAY;IACnB,YAAY,EAAmC,CAAC;IAChD,YAAY,EAAsC,CAAC;IACnD,YAAY,EAAmC,CAAC;IAChD,YAAY,EAA6C,CAAC;IAC1D,YAAY,EAA6B,CAAC;IAC1C,mEAAmE;IACnE,iEAAiE;IACjE,+DAA+D;IAC/D,MAAM,CAAC,UAAU,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,CAAC;IAC1D,iBAAiB,EAAE,CAAC;IACpB,kEAAkE;IAClE,kEAAkE;IAClE,wCAAwC;IACxC,MAAM,QAAQ,GAA2B,eAAe,CAAC;IACzD,IAAI,KAAgB;QAAE,QAAQ,CAAC;AACjC,CAAC;AACD,uEAAuE;AACvE,6DAA6D;AAC7D,MAAM,yBAAyB,GAAY,YAAY,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,CAAC"}
@@ -0,0 +1,27 @@
1
+ declare const TimeoutError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
2
+ readonly _tag: "TimeoutError";
3
+ } & Readonly<A>;
4
+ export declare class TimeoutError extends TimeoutError_base<{
5
+ readonly definition: string;
6
+ readonly durationMs: number;
7
+ }> {
8
+ }
9
+ declare const StreamClosedError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
10
+ readonly _tag: "StreamClosedError";
11
+ } & Readonly<A>;
12
+ export declare class StreamClosedError extends StreamClosedError_base<{
13
+ readonly definition: string;
14
+ }> {
15
+ }
16
+ /**
17
+ * Union of all notification consumer error tags. Catch sites use
18
+ * `Effect.catchTags({ TimeoutError: ..., StreamClosedError: ... })` for
19
+ * exhaustive handling, or accept this union in their typed error channel.
20
+ *
21
+ * NOT a class — Effect's `Data.TaggedError` classes do not inherit from
22
+ * a shared `Data.TaggedError` base in a way that preserves `_tag`
23
+ * discrimination. The union is the canonical shape.
24
+ */
25
+ export type NotificationConsumerError = TimeoutError | StreamClosedError;
26
+ export {};
27
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/notification/errors.ts"],"names":[],"mappings":";;;AAoBA,qBAAa,YAAa,SAAQ,kBAAiC;IACjE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B,CAAC;CAAG;;;;AAEL,qBAAa,iBAAkB,SAAQ,uBAAsC;IAC3E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B,CAAC;CAAG;AAEL;;;;;;;;GAQG;AACH,MAAM,MAAM,yBAAyB,GAAG,YAAY,GAAG,iBAAiB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Tagged errors for the notification consumption surface (Spec B, #596).
3
+ *
4
+ * Per architect-revision r1 (codex review finding #8): `Data.TaggedError`
5
+ * classes do NOT compose via class inheritance — extending one tagged
6
+ * class from another produces broken `_tag` discrimination at runtime.
7
+ * The shared abstraction is therefore a TYPE UNION (`NotificationConsumerError`)
8
+ * not a base class. Catch sites that want to handle "any notification
9
+ * consumer error" pattern-match on the union.
10
+ *
11
+ * `TimeoutError` carries the timeout duration so callers can log + retry
12
+ * with sane backoff. `StreamClosedError` fires when the consumer's Stream
13
+ * completes empty (e.g. the client transitioned to terminal closed state
14
+ * before a notification arrived).
15
+ *
16
+ * **Architect stub** (Spec B). Impl-staff fills any helper combinators
17
+ * (`isTimeoutError`, mapping helpers) per downstream consumer needs.
18
+ */
19
+ import { Data } from "effect";
20
+ export class TimeoutError extends Data.TaggedError("TimeoutError") {
21
+ }
22
+ export class StreamClosedError extends Data.TaggedError("StreamClosedError") {
23
+ }
24
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/notification/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,MAAM,OAAO,YAAa,SAAQ,IAAI,CAAC,WAAW,CAAC,cAAc,CAG/D;CAAG;AAEL,MAAM,OAAO,iBAAkB,SAAQ,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAEzE;CAAG"}