@graphrefly/ts 0.0.0

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 (210) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapters/index.cjs +9015 -0
  3. package/dist/adapters/index.cjs.map +1 -0
  4. package/dist/adapters/index.d.cts +678 -0
  5. package/dist/adapters/index.d.ts +678 -0
  6. package/dist/adapters/index.js +2894 -0
  7. package/dist/adapters/index.js.map +1 -0
  8. package/dist/adapters/observe-storage.cjs +260 -0
  9. package/dist/adapters/observe-storage.cjs.map +1 -0
  10. package/dist/adapters/observe-storage.d.cts +77 -0
  11. package/dist/adapters/observe-storage.d.ts +77 -0
  12. package/dist/adapters/observe-storage.js +161 -0
  13. package/dist/adapters/observe-storage.js.map +1 -0
  14. package/dist/append-log-DisvEReb.d.cts +189 -0
  15. package/dist/append-log-DzKMmjxx.d.ts +189 -0
  16. package/dist/chunk-2ILL7HQI.js +1189 -0
  17. package/dist/chunk-2ILL7HQI.js.map +1 -0
  18. package/dist/chunk-4VLAQHZI.js +330 -0
  19. package/dist/chunk-4VLAQHZI.js.map +1 -0
  20. package/dist/chunk-6PHB5CJS.js +229 -0
  21. package/dist/chunk-6PHB5CJS.js.map +1 -0
  22. package/dist/chunk-COHO25CZ.js +2449 -0
  23. package/dist/chunk-COHO25CZ.js.map +1 -0
  24. package/dist/chunk-D6BG7U6A.js +161 -0
  25. package/dist/chunk-D6BG7U6A.js.map +1 -0
  26. package/dist/chunk-DJC4CHLQ.js +818 -0
  27. package/dist/chunk-DJC4CHLQ.js.map +1 -0
  28. package/dist/chunk-DK554R7P.js +67 -0
  29. package/dist/chunk-DK554R7P.js.map +1 -0
  30. package/dist/chunk-DKP56CSW.js +322 -0
  31. package/dist/chunk-DKP56CSW.js.map +1 -0
  32. package/dist/chunk-G4M3NHRJ.js +688 -0
  33. package/dist/chunk-G4M3NHRJ.js.map +1 -0
  34. package/dist/chunk-GAJW5I5P.js +1 -0
  35. package/dist/chunk-GAJW5I5P.js.map +1 -0
  36. package/dist/chunk-GDL26N2T.js +282 -0
  37. package/dist/chunk-GDL26N2T.js.map +1 -0
  38. package/dist/chunk-GTPCOEOZ.js +741 -0
  39. package/dist/chunk-GTPCOEOZ.js.map +1 -0
  40. package/dist/chunk-H2HTHFVN.js +1 -0
  41. package/dist/chunk-H2HTHFVN.js.map +1 -0
  42. package/dist/chunk-HDRL4VQQ.js +218 -0
  43. package/dist/chunk-HDRL4VQQ.js.map +1 -0
  44. package/dist/chunk-I3IHOHCJ.js +2267 -0
  45. package/dist/chunk-I3IHOHCJ.js.map +1 -0
  46. package/dist/chunk-JIMUDQN3.js +965 -0
  47. package/dist/chunk-JIMUDQN3.js.map +1 -0
  48. package/dist/chunk-JR4IKCR2.js +462 -0
  49. package/dist/chunk-JR4IKCR2.js.map +1 -0
  50. package/dist/chunk-K3FXTC3I.js +165 -0
  51. package/dist/chunk-K3FXTC3I.js.map +1 -0
  52. package/dist/chunk-OOEN33FB.js +65 -0
  53. package/dist/chunk-OOEN33FB.js.map +1 -0
  54. package/dist/chunk-PKVBHGBM.js +554 -0
  55. package/dist/chunk-PKVBHGBM.js.map +1 -0
  56. package/dist/chunk-RIIOUTGM.js +1857 -0
  57. package/dist/chunk-RIIOUTGM.js.map +1 -0
  58. package/dist/chunk-SCRFRCGR.js +33 -0
  59. package/dist/chunk-SCRFRCGR.js.map +1 -0
  60. package/dist/chunk-SWTLEQL6.js +53 -0
  61. package/dist/chunk-SWTLEQL6.js.map +1 -0
  62. package/dist/chunk-SZAETNNA.js +1 -0
  63. package/dist/chunk-SZAETNNA.js.map +1 -0
  64. package/dist/chunk-TEW47IVR.js +49 -0
  65. package/dist/chunk-TEW47IVR.js.map +1 -0
  66. package/dist/chunk-Y3ZLRGHC.js +1482 -0
  67. package/dist/chunk-Y3ZLRGHC.js.map +1 -0
  68. package/dist/chunk-Z2ANQ6JW.js +149 -0
  69. package/dist/chunk-Z2ANQ6JW.js.map +1 -0
  70. package/dist/codec-BB7p8fJc.d.cts +38 -0
  71. package/dist/codec-BB7p8fJc.d.ts +38 -0
  72. package/dist/composition/index.cjs +2505 -0
  73. package/dist/composition/index.cjs.map +1 -0
  74. package/dist/composition/index.d.cts +95 -0
  75. package/dist/composition/index.d.ts +95 -0
  76. package/dist/composition/index.js +19 -0
  77. package/dist/composition/index.js.map +1 -0
  78. package/dist/core/index.cjs +2475 -0
  79. package/dist/core/index.cjs.map +1 -0
  80. package/dist/core/index.d.cts +25 -0
  81. package/dist/core/index.d.ts +25 -0
  82. package/dist/core/index.js +74 -0
  83. package/dist/core/index.js.map +1 -0
  84. package/dist/cqrs/index.cjs +595 -0
  85. package/dist/cqrs/index.cjs.map +1 -0
  86. package/dist/cqrs/index.d.cts +200 -0
  87. package/dist/cqrs/index.d.ts +200 -0
  88. package/dist/cqrs/index.js +557 -0
  89. package/dist/cqrs/index.js.map +1 -0
  90. package/dist/data-structures/index.cjs +4277 -0
  91. package/dist/data-structures/index.cjs.map +1 -0
  92. package/dist/data-structures/index.d.cts +22 -0
  93. package/dist/data-structures/index.d.ts +22 -0
  94. package/dist/data-structures/index.js +31 -0
  95. package/dist/data-structures/index.js.map +1 -0
  96. package/dist/describe-BZb7AS2y.d.ts +57 -0
  97. package/dist/describe-Ciu8SUnN.d.cts +57 -0
  98. package/dist/graph/index.cjs +7832 -0
  99. package/dist/graph/index.cjs.map +1 -0
  100. package/dist/graph/index.d.cts +251 -0
  101. package/dist/graph/index.d.ts +251 -0
  102. package/dist/graph/index.js +131 -0
  103. package/dist/graph/index.js.map +1 -0
  104. package/dist/graph-DfdF9zy4.d.ts +666 -0
  105. package/dist/graph-s23RbbFO.d.cts +666 -0
  106. package/dist/index-CAEmLCYF.d.cts +166 -0
  107. package/dist/index-SnzZu3x7.d.ts +166 -0
  108. package/dist/index.cjs +15409 -0
  109. package/dist/index.cjs.map +1 -0
  110. package/dist/index.d.cts +23 -0
  111. package/dist/index.d.ts +23 -0
  112. package/dist/index.js +582 -0
  113. package/dist/index.js.map +1 -0
  114. package/dist/messages-BZqrGGm1.d.cts +55 -0
  115. package/dist/messages-BZqrGGm1.d.ts +55 -0
  116. package/dist/messaging/index.cjs +818 -0
  117. package/dist/messaging/index.cjs.map +1 -0
  118. package/dist/messaging/index.d.cts +235 -0
  119. package/dist/messaging/index.d.ts +235 -0
  120. package/dist/messaging/index.js +767 -0
  121. package/dist/messaging/index.js.map +1 -0
  122. package/dist/observe-event-log-0SVsx7JG.d.cts +88 -0
  123. package/dist/observe-event-log-Dnm76owp.d.ts +88 -0
  124. package/dist/operators/index.cjs +3774 -0
  125. package/dist/operators/index.cjs.map +1 -0
  126. package/dist/operators/index.d.cts +308 -0
  127. package/dist/operators/index.d.ts +308 -0
  128. package/dist/operators/index.js +112 -0
  129. package/dist/operators/index.js.map +1 -0
  130. package/dist/orchestration/index.cjs +3541 -0
  131. package/dist/orchestration/index.cjs.map +1 -0
  132. package/dist/orchestration/index.d.cts +302 -0
  133. package/dist/orchestration/index.d.ts +302 -0
  134. package/dist/orchestration/index.js +1004 -0
  135. package/dist/orchestration/index.js.map +1 -0
  136. package/dist/patterns/index.cjs +1045 -0
  137. package/dist/patterns/index.cjs.map +1 -0
  138. package/dist/patterns/index.d.cts +39 -0
  139. package/dist/patterns/index.d.ts +39 -0
  140. package/dist/patterns/index.js +33 -0
  141. package/dist/patterns/index.js.map +1 -0
  142. package/dist/reactive-collection-BxBqtIOE.d.cts +344 -0
  143. package/dist/reactive-collection-Cb1II1Fi.d.ts +344 -0
  144. package/dist/reactive-collection-storage-BNiEc-Gd.d.ts +217 -0
  145. package/dist/reactive-collection-storage-D-KmjE0J.d.cts +217 -0
  146. package/dist/reactive-map-BcB4KsQR.d.ts +256 -0
  147. package/dist/reactive-map-D-g3dv8I.d.cts +256 -0
  148. package/dist/read-through-B1CYPfq_.d.cts +82 -0
  149. package/dist/read-through-DwyJhGs1.d.ts +82 -0
  150. package/dist/render/index.cjs +250 -0
  151. package/dist/render/index.cjs.map +1 -0
  152. package/dist/render/index.d.cts +58 -0
  153. package/dist/render/index.d.ts +58 -0
  154. package/dist/render/index.js +20 -0
  155. package/dist/render/index.js.map +1 -0
  156. package/dist/resilience-Dig3Q7n0.d.cts +45 -0
  157. package/dist/resilience-Dig3Q7n0.d.ts +45 -0
  158. package/dist/semantic-memory-graph-BYoIlP35.d.cts +356 -0
  159. package/dist/semantic-memory-graph-CxyXLms3.d.ts +356 -0
  160. package/dist/solutions/index.cjs +3249 -0
  161. package/dist/solutions/index.cjs.map +1 -0
  162. package/dist/solutions/index.d.cts +520 -0
  163. package/dist/solutions/index.d.ts +520 -0
  164. package/dist/solutions/index.js +31 -0
  165. package/dist/solutions/index.js.map +1 -0
  166. package/dist/sources/browser.cjs +3095 -0
  167. package/dist/sources/browser.cjs.map +1 -0
  168. package/dist/sources/browser.d.cts +39 -0
  169. package/dist/sources/browser.d.ts +39 -0
  170. package/dist/sources/browser.js +137 -0
  171. package/dist/sources/browser.js.map +1 -0
  172. package/dist/sources/index.cjs +3021 -0
  173. package/dist/sources/index.cjs.map +1 -0
  174. package/dist/sources/index.d.cts +7 -0
  175. package/dist/sources/index.d.ts +7 -0
  176. package/dist/sources/index.js +63 -0
  177. package/dist/sources/index.js.map +1 -0
  178. package/dist/sources/node.cjs +675 -0
  179. package/dist/sources/node.cjs.map +1 -0
  180. package/dist/sources/node.d.cts +109 -0
  181. package/dist/sources/node.d.ts +109 -0
  182. package/dist/sources/node.js +639 -0
  183. package/dist/sources/node.js.map +1 -0
  184. package/dist/storage/browser.cjs +777 -0
  185. package/dist/storage/browser.cjs.map +1 -0
  186. package/dist/storage/browser.d.cts +40 -0
  187. package/dist/storage/browser.d.ts +40 -0
  188. package/dist/storage/browser.js +275 -0
  189. package/dist/storage/browser.js.map +1 -0
  190. package/dist/storage/index.cjs +1989 -0
  191. package/dist/storage/index.cjs.map +1 -0
  192. package/dist/storage/index.d.cts +92 -0
  193. package/dist/storage/index.d.ts +92 -0
  194. package/dist/storage/index.js +161 -0
  195. package/dist/storage/index.js.map +1 -0
  196. package/dist/storage/node.cjs +898 -0
  197. package/dist/storage/node.cjs.map +1 -0
  198. package/dist/storage/node.d.cts +66 -0
  199. package/dist/storage/node.d.ts +66 -0
  200. package/dist/storage/node.js +402 -0
  201. package/dist/storage/node.js.map +1 -0
  202. package/dist/testing/index.cjs +95 -0
  203. package/dist/testing/index.cjs.map +1 -0
  204. package/dist/testing/index.d.cts +20 -0
  205. package/dist/testing/index.d.ts +20 -0
  206. package/dist/testing/index.js +8 -0
  207. package/dist/testing/index.js.map +1 -0
  208. package/dist/types-bNMSWKqF.d.cts +732 -0
  209. package/dist/types-h12mNYbq.d.ts +732 -0
  210. package/package.json +250 -0
@@ -0,0 +1,2894 @@
1
+ import {
2
+ AGENTIC_MEMORY_RECORD_CHANGE_FORMAT,
3
+ AGENTIC_MEMORY_RECORD_SNAPSHOT_FORMAT,
4
+ AGENTIC_MEMORY_RECORD_STORAGE_FRAME_VERSION,
5
+ agenticMemoryRecordChangeFrame,
6
+ agenticMemoryRecordSnapshotFrame,
7
+ agenticMemoryRecordsSnapshotKey,
8
+ assertAgenticMemoryRecordChangeFrame,
9
+ assertAgenticMemoryRecordSnapshotFrame,
10
+ loadAgenticMemoryRecordsState,
11
+ openPersistentAgenticMemoryRecords,
12
+ openPersistentReactiveIndex,
13
+ openPersistentReactiveList,
14
+ openPersistentReactiveLog,
15
+ openPersistentReactiveMap,
16
+ persistAgenticMemoryRecords,
17
+ persistReactiveCollection
18
+ } from "../chunk-DJC4CHLQ.js";
19
+ import "../chunk-GTPCOEOZ.js";
20
+ import "../chunk-COHO25CZ.js";
21
+ import "../chunk-JIMUDQN3.js";
22
+ import "../chunk-K3FXTC3I.js";
23
+ import "../chunk-6PHB5CJS.js";
24
+ import "../chunk-Z2ANQ6JW.js";
25
+ import "../chunk-2ILL7HQI.js";
26
+ import {
27
+ nextRetryDelayMs,
28
+ retryPolicy,
29
+ shouldRetry
30
+ } from "../chunk-OOEN33FB.js";
31
+ import "../chunk-DKP56CSW.js";
32
+ import "../chunk-RIIOUTGM.js";
33
+ import "../chunk-G4M3NHRJ.js";
34
+ import "../chunk-PKVBHGBM.js";
35
+ import "../chunk-I3IHOHCJ.js";
36
+ import "../chunk-4VLAQHZI.js";
37
+ import {
38
+ depBatch
39
+ } from "../chunk-SWTLEQL6.js";
40
+ import {
41
+ errorPayload
42
+ } from "../chunk-DK554R7P.js";
43
+
44
+ // src/adapters/bridge.ts
45
+ var envelopeTypes = /* @__PURE__ */ new Set([
46
+ "start",
47
+ "data",
48
+ "ack",
49
+ "nack",
50
+ "status",
51
+ "error",
52
+ "close"
53
+ ]);
54
+ var defaultAckTimeoutMs = 3e4;
55
+ var bridgeCommandSources = /* @__PURE__ */ new WeakMap();
56
+ var bridgeInboundTargets = /* @__PURE__ */ new WeakMap();
57
+ function wireBridgeIdempotencyKey(sessionId, seq) {
58
+ return `${sessionId}:${seq}`;
59
+ }
60
+ function wireBridgeEnvelope(input) {
61
+ if (typeof input.sessionId !== "string" || input.sessionId.length === 0) {
62
+ throw new RangeError("wireBridgeEnvelope: sessionId must be a non-empty string");
63
+ }
64
+ if (!envelopeTypes.has(input.type)) {
65
+ throw new RangeError("wireBridgeEnvelope: type is not recognized");
66
+ }
67
+ if (!isSafePositiveInteger(input.seq)) {
68
+ throw new RangeError("wireBridgeEnvelope: seq must be a positive integer");
69
+ }
70
+ const cursor = input.cursor ?? 0;
71
+ if (!isSafeNonNegativeInteger(cursor)) {
72
+ throw new RangeError("wireBridgeEnvelope: cursor must be a non-negative integer");
73
+ }
74
+ const attempt = input.attempt ?? 1;
75
+ if (!isSafePositiveInteger(attempt)) {
76
+ throw new RangeError("wireBridgeEnvelope: attempt must be a positive integer");
77
+ }
78
+ const maxAttempts = input.maxAttempts ?? attempt;
79
+ if (!isSafePositiveInteger(maxAttempts) || maxAttempts < attempt) {
80
+ throw new RangeError("wireBridgeEnvelope: maxAttempts must be >= attempt");
81
+ }
82
+ if (input.ackForSeq !== void 0 && !isSafePositiveInteger(input.ackForSeq)) {
83
+ throw new RangeError("wireBridgeEnvelope: ackForSeq must be a positive integer");
84
+ }
85
+ if ((input.type === "ack" || input.type === "nack") && input.ackForSeq === void 0) {
86
+ throw new RangeError(`wireBridgeEnvelope: ${input.type} envelope requires ackForSeq`);
87
+ }
88
+ if (input.idempotencyKey !== void 0 && input.idempotencyKey.length === 0) {
89
+ throw new RangeError("wireBridgeEnvelope: idempotencyKey must be a non-empty string");
90
+ }
91
+ const payloadError = validatePayloadForType(input.type, input.payload, "wireBridgeEnvelope");
92
+ if (payloadError !== void 0) {
93
+ throw new RangeError(payloadError);
94
+ }
95
+ return {
96
+ sessionId: input.sessionId,
97
+ type: input.type,
98
+ payload: input.payload,
99
+ metadata: {
100
+ seq: input.seq,
101
+ cursor,
102
+ idempotencyKey: input.idempotencyKey ?? wireBridgeIdempotencyKey(input.sessionId, input.seq),
103
+ attempt,
104
+ maxAttempts,
105
+ timestampMs: input.timestampMs,
106
+ ackForSeq: input.ackForSeq,
107
+ requestId: input.requestId
108
+ }
109
+ };
110
+ }
111
+ function wireBridge(graph, opts) {
112
+ const name = opts.name ?? "wireBridge";
113
+ const policy = opts.retry ?? retryPolicy();
114
+ const command = graph.node([], null, {
115
+ name: `${name}/command`,
116
+ factory: "wireBridgeCommand"
117
+ });
118
+ const inboundCore = graph.node(
119
+ [],
120
+ null,
121
+ {
122
+ name: `${name}/inbound`,
123
+ factory: "wireBridgeInbound"
124
+ }
125
+ );
126
+ const inbound = guardedInboundNode(inboundCore, opts.sessionId);
127
+ const events = wireBridgeEventsNode(
128
+ graph,
129
+ command,
130
+ inboundCore,
131
+ name,
132
+ opts,
133
+ policy
134
+ );
135
+ const outbound = projectOutbound(graph, events, name);
136
+ const acks = projectAcks(graph, events, name);
137
+ const nacks = projectNacks(graph, events, name);
138
+ const status = projectStatus(graph, events, name, opts.sessionId);
139
+ const errors = projectErrors(graph, events, name);
140
+ const cursor = projectCursor(graph, events, name);
141
+ const attempts = projectAttempts(graph, events, name);
142
+ const bundle = {
143
+ sessionId: opts.sessionId,
144
+ command,
145
+ outbound,
146
+ inbound,
147
+ events,
148
+ acks,
149
+ nacks,
150
+ status,
151
+ errors,
152
+ cursor,
153
+ attempts,
154
+ start: () => command.down([["DATA", { kind: "start" }]]),
155
+ send: (payload, sendOpts) => command.down([
156
+ [
157
+ "DATA",
158
+ {
159
+ kind: "send",
160
+ payload,
161
+ idempotencyKey: sendOpts?.idempotencyKey,
162
+ requestId: sendOpts?.requestId
163
+ }
164
+ ]
165
+ ]),
166
+ ack: (ackForSeq, ackOpts) => command.down([
167
+ [
168
+ "DATA",
169
+ {
170
+ kind: "ack",
171
+ ackForSeq,
172
+ idempotencyKey: ackOpts?.idempotencyKey,
173
+ requestId: ackOpts?.requestId
174
+ }
175
+ ]
176
+ ]),
177
+ nack: (ackForSeq, error, nackOpts) => command.down([
178
+ [
179
+ "DATA",
180
+ {
181
+ kind: "nack",
182
+ ackForSeq,
183
+ error,
184
+ idempotencyKey: nackOpts?.idempotencyKey,
185
+ requestId: nackOpts?.requestId
186
+ }
187
+ ]
188
+ ]),
189
+ close: (reason, closeOpts) => command.down([
190
+ ["DATA", { kind: "close", reason, idempotencyKey: closeOpts?.idempotencyKey }]
191
+ ])
192
+ };
193
+ bridgeCommandSources.set(bundle, { sources: [] });
194
+ bridgeInboundTargets.set(bundle, inboundCore);
195
+ return bundle;
196
+ }
197
+ function remoteCall(graph, bridge, opts = {}) {
198
+ const name = opts.name ?? "remoteCall";
199
+ const timeouts = graph.node([], null, {
200
+ name: `${name}/timeouts`,
201
+ factory: "remoteCallTimeouts",
202
+ completeWhenDepsComplete: false,
203
+ errorWhenDepsError: false
204
+ });
205
+ const responses = remoteCallResponsesNode(graph, bridge.events, timeouts, name);
206
+ const results = remoteCallResultsNode(graph, responses, name);
207
+ const status = remoteCallStatusNode(graph, bridge.events, responses, timeouts, name);
208
+ const errors = remoteCallErrorsNode(graph, responses, timeouts, bridge.events, name);
209
+ return {
210
+ responses,
211
+ results,
212
+ status,
213
+ errors,
214
+ timeouts,
215
+ call(operation, requestId, payload, callOpts) {
216
+ const request = remoteCallRequest(operation, requestId, payload);
217
+ bridge.command.down([
218
+ [
219
+ "DATA",
220
+ {
221
+ kind: "send",
222
+ payload: request,
223
+ idempotencyKey: callOpts?.idempotencyKey,
224
+ requestId
225
+ }
226
+ ]
227
+ ]);
228
+ return request;
229
+ },
230
+ timeout(requestId, operation, error) {
231
+ const timeout = remoteCallTimeout(requestId, operation, error);
232
+ timeouts.down([["DATA", timeout]]);
233
+ return timeout;
234
+ }
235
+ };
236
+ }
237
+ function remoteResponderHandler(operation, handle) {
238
+ if (operation.length === 0) {
239
+ throw new RangeError("remoteResponderHandler: operation must be non-empty");
240
+ }
241
+ if (typeof handle !== "function") {
242
+ throw new TypeError("remoteResponderHandler: handle must be a function");
243
+ }
244
+ return { operation, handle };
245
+ }
246
+ function remoteResponder(graph, bridge, opts = {}) {
247
+ const name = opts.name ?? "remoteResponder";
248
+ const handlers = normalizeRemoteHandlers(opts.handlers ?? []);
249
+ const topology = graph.topologyGroup({ name: `${name}.remoteResponder` });
250
+ const events = topology.add(
251
+ remoteResponderEventsNode(
252
+ graph,
253
+ wireBridgeInboundTarget(bridge),
254
+ name,
255
+ bridge.sessionId,
256
+ handlers,
257
+ opts.rejectUnknown === true
258
+ )
259
+ );
260
+ const responseCommands = topology.add(remoteResponderResponseCommandsNode(graph, events, name));
261
+ const requests = topology.add(remoteResponderRequestsNode(graph, events, name));
262
+ const status = topology.add(remoteResponderStatusNode(graph, events, name));
263
+ const errors = topology.add(remoteResponderErrorsNode(graph, events, name));
264
+ try {
265
+ attachWireBridgeCommandSource(bridge, responseCommands);
266
+ } catch (error) {
267
+ topology.release({ reason: `${name}.remoteResponder.failedAttach` });
268
+ throw error;
269
+ }
270
+ let released = false;
271
+ return {
272
+ events,
273
+ responseCommands,
274
+ requests,
275
+ status,
276
+ errors,
277
+ release() {
278
+ if (released) return;
279
+ detachWireBridgeCommandSource(bridge, responseCommands);
280
+ try {
281
+ topology.release({ reason: `${name}.remoteResponder.release` });
282
+ released = true;
283
+ } catch (error) {
284
+ attachWireBridgeCommandSource(bridge, responseCommands);
285
+ throw error;
286
+ }
287
+ }
288
+ };
289
+ }
290
+ function wireBridgeEventsNode(graph, command, inbound, name, opts, policy) {
291
+ const now = opts.now ?? Date.now;
292
+ return graph.node(
293
+ [command, inbound],
294
+ (ctx) => {
295
+ const state = initBridgeState(ctx);
296
+ const emitOutbound = (type, payload, commandOpts = {}, beforeEmit) => {
297
+ if (!isSafePositiveInteger(state.nextSeq)) {
298
+ ctx.down([
299
+ [
300
+ "DATA",
301
+ {
302
+ kind: "invalid",
303
+ error: `${opts.sessionId}: next outbound seq exceeded Number.MAX_SAFE_INTEGER`
304
+ }
305
+ ]
306
+ ]);
307
+ return;
308
+ }
309
+ const seq = state.nextSeq;
310
+ let envelope;
311
+ try {
312
+ envelope = wireBridgeEnvelope({
313
+ sessionId: opts.sessionId,
314
+ type,
315
+ seq,
316
+ cursor: state.cursor,
317
+ payload,
318
+ idempotencyKey: commandOpts.idempotencyKey,
319
+ attempt: 1,
320
+ maxAttempts: policy.maxAttempts,
321
+ timestampMs: now(),
322
+ ackForSeq: commandOpts.ackForSeq,
323
+ requestId: commandOpts.requestId
324
+ });
325
+ } catch (error) {
326
+ ctx.down([
327
+ [
328
+ "DATA",
329
+ {
330
+ kind: "invalid",
331
+ error: error instanceof Error ? error.message : String(error)
332
+ }
333
+ ]
334
+ ]);
335
+ return;
336
+ }
337
+ state.nextSeq++;
338
+ beforeEmit?.();
339
+ ctx.down([["DATA", { kind: "outbound", envelope }]]);
340
+ if (shouldTrackAck(type)) armAckTimeout(ctx, state, envelope, opts, policy, now);
341
+ };
342
+ for (const raw of depBatch(ctx, 1) ?? []) {
343
+ processInbound(ctx, state, raw, opts.sessionId);
344
+ }
345
+ const inboundTerminal = ctx.terminal[1];
346
+ if (inboundTerminal !== false && inboundTerminal !== void 0 && !state.terminalReported) {
347
+ state.terminalReported = true;
348
+ const error = inboundTerminal === true ? `${opts.sessionId}: inbound protocol COMPLETE is local misuse; remote completion must arrive as a DATA envelope fact` : `${opts.sessionId}: inbound protocol ERROR ${String(
349
+ errorPayload(inboundTerminal)
350
+ )} is local misuse; remote errors must arrive as DATA envelope facts`;
351
+ ctx.down([["DATA", { kind: "invalid", error }]]);
352
+ }
353
+ for (const raw of depBatch(ctx, 0) ?? []) {
354
+ const invalid = validateCommand(raw);
355
+ if (invalid !== void 0) {
356
+ ctx.down([["DATA", { kind: "invalid", error: invalid }]]);
357
+ continue;
358
+ }
359
+ const commandValue = raw;
360
+ switch (commandValue.kind) {
361
+ case "start":
362
+ emitOutbound("start", void 0, commandValue);
363
+ break;
364
+ case "send":
365
+ emitOutbound("data", { kind: "data", value: commandValue.payload }, commandValue);
366
+ break;
367
+ case "ack":
368
+ emitOutbound("ack", void 0, {
369
+ idempotencyKey: commandValue.idempotencyKey,
370
+ requestId: commandValue.requestId,
371
+ ackForSeq: commandValue.ackForSeq
372
+ });
373
+ break;
374
+ case "nack":
375
+ emitOutbound(
376
+ "nack",
377
+ { kind: "error", error: errorPayload(commandValue.error) },
378
+ {
379
+ idempotencyKey: commandValue.idempotencyKey,
380
+ requestId: commandValue.requestId,
381
+ ackForSeq: commandValue.ackForSeq
382
+ }
383
+ );
384
+ break;
385
+ case "close":
386
+ emitOutbound(
387
+ "close",
388
+ { kind: "close", reason: commandValue.reason },
389
+ commandValue,
390
+ () => {
391
+ for (const pending of state.pending.values()) {
392
+ if (pending.timer !== void 0) clearTimeout(pending.timer);
393
+ }
394
+ state.pending.clear();
395
+ }
396
+ );
397
+ break;
398
+ }
399
+ }
400
+ },
401
+ {
402
+ name: `${name}/events`,
403
+ factory: "wireBridgeEvents",
404
+ partial: true,
405
+ errorWhenDepsError: false,
406
+ completeWhenDepsComplete: false,
407
+ terminalAsRealInput: true
408
+ }
409
+ );
410
+ }
411
+ function initBridgeState(ctx) {
412
+ let state = ctx.state.get();
413
+ if (state === void 0) {
414
+ state = {
415
+ active: true,
416
+ cleanupInstalled: false,
417
+ nextSeq: 1,
418
+ cursor: 0,
419
+ remoteCursor: 0,
420
+ terminalReported: false,
421
+ pending: /* @__PURE__ */ new Map()
422
+ };
423
+ ctx.state.set(state);
424
+ }
425
+ state.active = true;
426
+ if (!state.cleanupInstalled) {
427
+ state.cleanupInstalled = true;
428
+ ctx.onDeactivation(() => {
429
+ state.active = false;
430
+ state.cleanupInstalled = false;
431
+ for (const pending of state.pending.values()) {
432
+ if (pending.timer !== void 0) clearTimeout(pending.timer);
433
+ }
434
+ state.pending.clear();
435
+ });
436
+ }
437
+ return state;
438
+ }
439
+ function attachWireBridgeCommandSource(bridge, source) {
440
+ const attached = bridgeCommandSources.get(bridge);
441
+ if (attached === void 0) {
442
+ throw new Error("remoteResponder: bridge command source registry missing");
443
+ }
444
+ const sources = attached.sources;
445
+ const previousSources = [...sources];
446
+ if (!sources.includes(source)) sources.push(source);
447
+ try {
448
+ bridge.command.replaceDeps([...sources], wireBridgeCommandSourceFn(sources.length));
449
+ } catch (error) {
450
+ sources.splice(0, sources.length, ...previousSources);
451
+ bridge.command.replaceDeps(
452
+ [...previousSources],
453
+ wireBridgeCommandSourceFn(previousSources.length)
454
+ );
455
+ throw error;
456
+ }
457
+ }
458
+ function detachWireBridgeCommandSource(bridge, source) {
459
+ const attached = bridgeCommandSources.get(bridge);
460
+ if (attached === void 0) {
461
+ throw new Error("remoteResponder: bridge command source registry missing");
462
+ }
463
+ const sources = attached.sources;
464
+ if (!sources.includes(source)) return;
465
+ const previousSources = [...sources];
466
+ const nextSources = sources.filter((candidate) => candidate !== source);
467
+ sources.splice(0, sources.length, ...nextSources);
468
+ try {
469
+ bridge.command.replaceDeps([...nextSources], wireBridgeCommandSourceFn(nextSources.length));
470
+ } catch (error) {
471
+ sources.splice(0, sources.length, ...previousSources);
472
+ bridge.command.replaceDeps(
473
+ [...previousSources],
474
+ wireBridgeCommandSourceFn(previousSources.length)
475
+ );
476
+ throw error;
477
+ }
478
+ }
479
+ function wireBridgeInboundTarget(bridge) {
480
+ const target = bridgeInboundTargets.get(bridge);
481
+ if (target === void 0) {
482
+ throw new Error("remoteResponder: bridge inbound target registry missing");
483
+ }
484
+ return target;
485
+ }
486
+ function wireBridgeCommandSourceFn(sourceCount) {
487
+ return (ctx) => {
488
+ for (let i = 0; i < sourceCount; i += 1) {
489
+ for (const command of depBatch(ctx, i) ?? []) {
490
+ ctx.down([["DATA", command]]);
491
+ }
492
+ }
493
+ };
494
+ }
495
+ function remoteCallRequest(operation, requestId, payload) {
496
+ if (operation.length === 0) throw new RangeError("remoteCall: operation must be non-empty");
497
+ if (requestId.length === 0) throw new RangeError("remoteCall: requestId must be non-empty");
498
+ return { operation, requestId, payload };
499
+ }
500
+ function remoteCallTimeout(requestId, operation, error) {
501
+ if (requestId.length === 0)
502
+ throw new RangeError("remoteCall: timeout requestId must be non-empty");
503
+ if (error.length === 0) throw new RangeError("remoteCall: timeout error must be non-empty");
504
+ return { ...operation === void 0 ? {} : { operation }, requestId, error };
505
+ }
506
+ function remotePendingState() {
507
+ return { requestIds: /* @__PURE__ */ new Set(), bySeq: /* @__PURE__ */ new Map() };
508
+ }
509
+ function remotePendingContains(state, requestId) {
510
+ return state.requestIds.has(requestId);
511
+ }
512
+ function remotePendingDuplicate(state, request) {
513
+ const current = remotePendingTakeBySeqPreview(state, request.seq);
514
+ return current?.requestId !== request.requestId && state.requestIds.has(request.requestId);
515
+ }
516
+ function remotePendingTakeBySeqPreview(state, seq) {
517
+ return state.bySeq.get(seq);
518
+ }
519
+ function remotePendingInsert(state, request) {
520
+ const existingBySeq = state.bySeq.get(request.seq);
521
+ if (existingBySeq !== void 0) {
522
+ state.requestIds.delete(existingBySeq.requestId);
523
+ }
524
+ for (const [seq, pending] of state.bySeq) {
525
+ if (pending.requestId === request.requestId && seq !== request.seq) {
526
+ state.bySeq.delete(seq);
527
+ break;
528
+ }
529
+ }
530
+ state.requestIds.add(request.requestId);
531
+ state.bySeq.set(request.seq, request);
532
+ }
533
+ function remotePendingTakeByRequestId(state, requestId) {
534
+ if (!state.requestIds.delete(requestId)) return void 0;
535
+ let seq;
536
+ let found;
537
+ for (const [candidateSeq, request] of state.bySeq) {
538
+ if (request.requestId === requestId) {
539
+ seq = candidateSeq;
540
+ found = request;
541
+ break;
542
+ }
543
+ }
544
+ if (seq !== void 0) state.bySeq.delete(seq);
545
+ return found;
546
+ }
547
+ function remotePendingTakeBySeq(state, seq) {
548
+ const request = state.bySeq.get(seq);
549
+ if (request === void 0) return void 0;
550
+ state.bySeq.delete(seq);
551
+ state.requestIds.delete(request.requestId);
552
+ return request;
553
+ }
554
+ function remotePendingFromReceipt(state, envelope) {
555
+ const bySeq = remotePendingTakeBySeq(state, envelope.metadata.seq);
556
+ if (bySeq !== void 0) return bySeq;
557
+ const fallback = pendingRequestFromEnvelope(envelope);
558
+ if (fallback === void 0 || remotePendingContains(state, fallback.requestId)) {
559
+ return void 0;
560
+ }
561
+ return fallback;
562
+ }
563
+ function pendingRequestFromEnvelope(envelope) {
564
+ if (envelope.payload?.kind !== "data") return void 0;
565
+ const request = validateRemoteCallRequest(envelope.payload.value);
566
+ if (request === void 0) return void 0;
567
+ return {
568
+ operation: request.operation,
569
+ requestId: request.requestId,
570
+ seq: envelope.metadata.seq
571
+ };
572
+ }
573
+ function validateRemoteCallRequest(value) {
574
+ if (!isRecord(value)) return void 0;
575
+ if (typeof value.operation !== "string" || value.operation.length === 0) return void 0;
576
+ if (typeof value.requestId !== "string" || value.requestId.length === 0) return void 0;
577
+ if (!("payload" in value)) return void 0;
578
+ return {
579
+ operation: value.operation,
580
+ requestId: value.requestId,
581
+ payload: value.payload
582
+ };
583
+ }
584
+ function validateRemoteCallResponse(value) {
585
+ if (!isRecord(value)) return void 0;
586
+ if (typeof value.operation !== "string" || value.operation.length === 0) return void 0;
587
+ if (typeof value.requestId !== "string" || value.requestId.length === 0) return void 0;
588
+ if (value.kind === "result" && "payload" in value) {
589
+ return {
590
+ kind: "result",
591
+ operation: value.operation,
592
+ requestId: value.requestId,
593
+ payload: value.payload
594
+ };
595
+ }
596
+ if (value.kind === "error" && typeof value.error === "string" && value.error.length > 0) {
597
+ return {
598
+ kind: "error",
599
+ operation: value.operation,
600
+ requestId: value.requestId,
601
+ error: value.error
602
+ };
603
+ }
604
+ if (value.kind === "status" && typeof value.status === "string" && value.status.length > 0) {
605
+ return {
606
+ kind: "status",
607
+ operation: value.operation,
608
+ requestId: value.requestId,
609
+ status: value.status
610
+ };
611
+ }
612
+ return void 0;
613
+ }
614
+ function remoteMalformedResponseRequestId(value) {
615
+ if (!isRecord(value)) return void 0;
616
+ return typeof value.requestId === "string" && value.requestId.length > 0 ? value.requestId : void 0;
617
+ }
618
+ function isRecord(value) {
619
+ return typeof value === "object" && value !== null;
620
+ }
621
+ function isThenable(value) {
622
+ return isRecord(value) && typeof value.then === "function";
623
+ }
624
+ function remoteCallResponseRequestId(response) {
625
+ return response.requestId;
626
+ }
627
+ function remoteCallResponseIsTerminal(response) {
628
+ return response.kind === "result" || response.kind === "error";
629
+ }
630
+ function remoteCallResponsesNode(graph, events, timeouts, name) {
631
+ return graph.node(
632
+ [events, timeouts],
633
+ (ctx) => {
634
+ const state = ctx.state.get() ?? {
635
+ pending: remotePendingState()
636
+ };
637
+ const ready = [];
638
+ for (const raw of depBatch(ctx, 0) ?? []) {
639
+ const event = raw;
640
+ if (event.kind === "outbound") {
641
+ const request = pendingRequestFromEnvelope(event.envelope);
642
+ if (request === void 0) continue;
643
+ if (remotePendingDuplicate(state.pending, request)) continue;
644
+ remotePendingInsert(state.pending, request);
645
+ } else if (event.kind === "inbound" && event.envelope.payload?.kind === "data") {
646
+ const response = validateRemoteCallResponse(event.envelope.payload.value);
647
+ if (response === void 0) {
648
+ const requestId2 = remoteMalformedResponseRequestId(event.envelope.payload.value);
649
+ if (requestId2 !== void 0 && remotePendingContains(state.pending, requestId2)) {
650
+ remotePendingTakeByRequestId(state.pending, requestId2);
651
+ }
652
+ continue;
653
+ }
654
+ const requestId = remoteCallResponseRequestId(response);
655
+ if (remotePendingContains(state.pending, requestId)) {
656
+ if (remoteCallResponseIsTerminal(response)) {
657
+ remotePendingTakeByRequestId(state.pending, requestId);
658
+ }
659
+ ready.push(response);
660
+ }
661
+ } else if (event.kind === "nack") {
662
+ remotePendingFromReceipt(state.pending, event.outbound);
663
+ } else if (event.kind === "exhausted") {
664
+ remotePendingTakeBySeq(state.pending, event.seq);
665
+ }
666
+ }
667
+ for (const raw of depBatch(ctx, 1) ?? []) {
668
+ const timeout = raw;
669
+ remotePendingTakeByRequestId(state.pending, timeout.requestId);
670
+ }
671
+ ctx.state.set(state);
672
+ for (const response of ready) ctx.down([["DATA", response]]);
673
+ },
674
+ {
675
+ name: `${name}/responses`,
676
+ factory: "remoteCallResponses",
677
+ partial: true,
678
+ completeWhenDepsComplete: false,
679
+ errorWhenDepsError: false
680
+ }
681
+ );
682
+ }
683
+ function remoteCallResultsNode(graph, responses, name) {
684
+ return graph.node(
685
+ [responses],
686
+ (ctx) => {
687
+ for (const raw of depBatch(ctx, 0) ?? []) {
688
+ const response = raw;
689
+ if (response.kind === "result") {
690
+ ctx.down([
691
+ [
692
+ "DATA",
693
+ {
694
+ operation: response.operation,
695
+ requestId: response.requestId,
696
+ payload: response.payload
697
+ }
698
+ ]
699
+ ]);
700
+ }
701
+ }
702
+ },
703
+ { name: `${name}/results`, factory: "remoteCallResults", completeWhenDepsComplete: false }
704
+ );
705
+ }
706
+ function remoteCallStatusNode(graph, events, responses, timeouts, name) {
707
+ return graph.node(
708
+ [events, responses, timeouts],
709
+ (ctx) => {
710
+ const state = ctx.state.get() ?? {
711
+ status: { state: "idle", pending: 0, completed: 0, errors: 0, timeouts: 0 },
712
+ pending: remotePendingState()
713
+ };
714
+ for (const raw of depBatch(ctx, 0) ?? []) {
715
+ const event = raw;
716
+ if (event.kind === "outbound") {
717
+ const request = pendingRequestFromEnvelope(event.envelope);
718
+ if (request !== void 0) {
719
+ if (remotePendingDuplicate(state.pending, request)) {
720
+ state.status = {
721
+ ...state.status,
722
+ state: "errored",
723
+ operation: request.operation,
724
+ requestId: request.requestId,
725
+ errors: state.status.errors + 1
726
+ };
727
+ continue;
728
+ }
729
+ remotePendingInsert(state.pending, request);
730
+ state.status = {
731
+ ...state.status,
732
+ state: "requested",
733
+ operation: request.operation,
734
+ requestId: request.requestId
735
+ };
736
+ }
737
+ } else if (event.kind === "invalid" || event.kind === "session-mismatch" || event.kind === "out-of-order" || event.kind === "late-receipt") {
738
+ state.status = {
739
+ ...state.status,
740
+ state: "bridge-errored",
741
+ errors: state.status.errors + 1
742
+ };
743
+ } else if (event.kind === "nack") {
744
+ const request = remotePendingFromReceipt(state.pending, event.outbound);
745
+ state.status = {
746
+ ...state.status,
747
+ state: "bridge-errored",
748
+ ...request === void 0 ? {} : { operation: request.operation, requestId: request.requestId },
749
+ errors: state.status.errors + 1
750
+ };
751
+ } else if (event.kind === "exhausted") {
752
+ const request = remotePendingTakeBySeq(state.pending, event.seq);
753
+ state.status = {
754
+ ...state.status,
755
+ state: "bridge-errored",
756
+ ...request === void 0 ? {} : { operation: request.operation, requestId: request.requestId },
757
+ errors: state.status.errors + 1
758
+ };
759
+ } else if (event.kind === "inbound" && event.envelope.payload?.kind === "data") {
760
+ const response = validateRemoteCallResponse(event.envelope.payload.value);
761
+ if (response === void 0) {
762
+ const requestId = remoteMalformedResponseRequestId(event.envelope.payload.value);
763
+ if (requestId !== void 0) {
764
+ const request = remotePendingTakeByRequestId(state.pending, requestId);
765
+ if (request !== void 0) {
766
+ state.status = {
767
+ ...state.status,
768
+ state: "errored",
769
+ operation: request.operation,
770
+ requestId,
771
+ errors: state.status.errors + 1
772
+ };
773
+ }
774
+ }
775
+ }
776
+ }
777
+ }
778
+ for (const raw of depBatch(ctx, 1) ?? []) {
779
+ const response = raw;
780
+ if (response.kind === "result") {
781
+ remotePendingTakeByRequestId(state.pending, response.requestId);
782
+ state.status = {
783
+ ...state.status,
784
+ state: "responded",
785
+ operation: response.operation,
786
+ requestId: response.requestId,
787
+ completed: state.status.completed + 1
788
+ };
789
+ } else if (response.kind === "error") {
790
+ remotePendingTakeByRequestId(state.pending, response.requestId);
791
+ state.status = {
792
+ ...state.status,
793
+ state: "errored",
794
+ operation: response.operation,
795
+ requestId: response.requestId,
796
+ errors: state.status.errors + 1
797
+ };
798
+ } else {
799
+ state.status = {
800
+ ...state.status,
801
+ operation: response.operation,
802
+ requestId: response.requestId
803
+ };
804
+ }
805
+ }
806
+ for (const raw of depBatch(ctx, 2) ?? []) {
807
+ const timeout = raw;
808
+ remotePendingTakeByRequestId(state.pending, timeout.requestId);
809
+ state.status = {
810
+ ...state.status,
811
+ state: "timed-out",
812
+ operation: timeout.operation,
813
+ requestId: timeout.requestId,
814
+ errors: state.status.errors + 1,
815
+ timeouts: state.status.timeouts + 1
816
+ };
817
+ }
818
+ state.status = { ...state.status, pending: state.pending.requestIds.size };
819
+ ctx.state.set(state);
820
+ ctx.down([["DATA", state.status]]);
821
+ },
822
+ {
823
+ name: `${name}/status`,
824
+ factory: "remoteCallStatus",
825
+ partial: true,
826
+ completeWhenDepsComplete: false,
827
+ errorWhenDepsError: false
828
+ }
829
+ );
830
+ }
831
+ function remoteCallErrorsNode(graph, responses, timeouts, events, name) {
832
+ return graph.node(
833
+ [responses, timeouts, events],
834
+ (ctx) => {
835
+ const pending = ctx.state.get() ?? remotePendingState();
836
+ for (const raw of depBatch(ctx, 2) ?? []) {
837
+ const event = raw;
838
+ if (event.kind === "outbound") {
839
+ const request = pendingRequestFromEnvelope(event.envelope);
840
+ if (request !== void 0) {
841
+ if (remotePendingDuplicate(pending, request)) {
842
+ ctx.down([
843
+ [
844
+ "DATA",
845
+ {
846
+ operation: request.operation,
847
+ requestId: request.requestId,
848
+ error: `remoteCall: duplicate in-flight requestId '${request.requestId}'`
849
+ }
850
+ ]
851
+ ]);
852
+ continue;
853
+ }
854
+ remotePendingInsert(pending, request);
855
+ }
856
+ }
857
+ }
858
+ for (const raw of depBatch(ctx, 0) ?? []) {
859
+ const response = raw;
860
+ if (response.kind === "error") {
861
+ remotePendingTakeByRequestId(pending, response.requestId);
862
+ ctx.down([
863
+ [
864
+ "DATA",
865
+ {
866
+ operation: response.operation,
867
+ requestId: response.requestId,
868
+ error: response.error
869
+ }
870
+ ]
871
+ ]);
872
+ } else if (response.kind === "result") {
873
+ remotePendingTakeByRequestId(pending, response.requestId);
874
+ }
875
+ }
876
+ for (const raw of depBatch(ctx, 1) ?? []) {
877
+ const timeout = raw;
878
+ remotePendingTakeByRequestId(pending, timeout.requestId);
879
+ ctx.down([
880
+ [
881
+ "DATA",
882
+ { operation: timeout.operation, requestId: timeout.requestId, error: timeout.error }
883
+ ]
884
+ ]);
885
+ }
886
+ for (const raw of depBatch(ctx, 2) ?? []) {
887
+ const event = raw;
888
+ if (event.kind === "inbound" && event.envelope.payload?.kind === "data") {
889
+ const response = validateRemoteCallResponse(event.envelope.payload.value);
890
+ if (response === void 0) {
891
+ const requestId = remoteMalformedResponseRequestId(event.envelope.payload.value);
892
+ const request = requestId === void 0 ? void 0 : remotePendingTakeByRequestId(pending, requestId);
893
+ if (request === void 0) continue;
894
+ ctx.down([
895
+ [
896
+ "DATA",
897
+ {
898
+ operation: request.operation,
899
+ requestId: request.requestId,
900
+ error: "remoteCall: response payload is malformed"
901
+ }
902
+ ]
903
+ ]);
904
+ }
905
+ continue;
906
+ }
907
+ if (event.kind === "nack") {
908
+ const request = remotePendingFromReceipt(pending, event.outbound);
909
+ ctx.down([
910
+ [
911
+ "DATA",
912
+ {
913
+ operation: request?.operation,
914
+ requestId: request?.requestId,
915
+ error: String(event.error)
916
+ }
917
+ ]
918
+ ]);
919
+ } else if (event.kind === "exhausted") {
920
+ const request = remotePendingTakeBySeq(pending, event.seq);
921
+ ctx.down([
922
+ [
923
+ "DATA",
924
+ {
925
+ operation: request?.operation,
926
+ requestId: request?.requestId,
927
+ error: String(event.error)
928
+ }
929
+ ]
930
+ ]);
931
+ } else if (event.kind === "invalid") {
932
+ ctx.down([["DATA", { error: event.error }]]);
933
+ } else if (event.kind === "session-mismatch" || event.kind === "out-of-order" || event.kind === "late-receipt") {
934
+ ctx.down([["DATA", { error: remoteCallBridgeErrorMessage(event) }]]);
935
+ }
936
+ }
937
+ ctx.state.set(pending);
938
+ },
939
+ {
940
+ name: `${name}/errors`,
941
+ factory: "remoteCallErrors",
942
+ partial: true,
943
+ completeWhenDepsComplete: false,
944
+ errorWhenDepsError: false
945
+ }
946
+ );
947
+ }
948
+ function remoteCallBridgeErrorMessage(event) {
949
+ if (event.kind === "session-mismatch") {
950
+ return `remoteCall: inbound session ${event.actual} did not match expected ${event.expected}`;
951
+ }
952
+ if (event.kind === "out-of-order") {
953
+ return `remoteCall: inbound seq ${event.seq} arrived before expected seq ${event.expected}`;
954
+ }
955
+ if (event.kind === "late-receipt") {
956
+ return `remoteCall: late ${event.receipt} for unknown or completed ackForSeq ${event.ackForSeq}`;
957
+ }
958
+ return "remoteCall: bridge error";
959
+ }
960
+ function normalizeRemoteHandlers(handlers) {
961
+ const out = /* @__PURE__ */ new Map();
962
+ for (const handler of handlers) {
963
+ if (handler.operation.length === 0) {
964
+ throw new RangeError("remoteResponder: operation must be non-empty");
965
+ }
966
+ if (out.has(handler.operation)) {
967
+ throw new RangeError(`remoteResponder: duplicate operation '${handler.operation}'`);
968
+ }
969
+ out.set(handler.operation, handler.handle);
970
+ }
971
+ return out;
972
+ }
973
+ function reduceRemoteResponderInbound(cursor, envelope, expectedSessionId) {
974
+ const envelopeError = validateInboundEnvelope(envelope);
975
+ if (envelopeError !== void 0) {
976
+ return { kind: "invalid", error: envelopeError };
977
+ }
978
+ if (envelope.sessionId !== expectedSessionId) {
979
+ return {
980
+ kind: "invalid",
981
+ error: `remoteResponder: inbound session ${envelope.sessionId} did not match expected ${expectedSessionId}`
982
+ };
983
+ }
984
+ const seq = envelope.metadata.seq;
985
+ const expected = cursor.cursor + 1;
986
+ if (seq <= cursor.cursor) {
987
+ return {
988
+ kind: "invalid",
989
+ error: `remoteResponder: duplicate request seq ${seq} at cursor ${cursor.cursor}`
990
+ };
991
+ }
992
+ if (seq > expected) {
993
+ return {
994
+ kind: "invalid",
995
+ error: `remoteResponder: out-of-order request seq ${seq}, expected ${expected}`
996
+ };
997
+ }
998
+ if (envelope.metadata.cursor < cursor.remoteCursor) {
999
+ return {
1000
+ kind: "invalid",
1001
+ error: `${envelope.sessionId}: remoteResponder inbound cursor ${envelope.metadata.cursor} regressed below ${cursor.remoteCursor}`
1002
+ };
1003
+ }
1004
+ cursor.cursor = seq;
1005
+ cursor.remoteCursor = envelope.metadata.cursor;
1006
+ if (envelope.type !== "data") return { kind: "consumed" };
1007
+ if (envelope.payload?.kind !== "data") {
1008
+ return { kind: "invalid", error: "remoteResponder: request envelope must carry request DATA" };
1009
+ }
1010
+ const request = validateRemoteCallRequest(envelope.payload.value);
1011
+ if (request === void 0) {
1012
+ return { kind: "invalid", error: "remoteResponder: request payload is malformed" };
1013
+ }
1014
+ return { kind: "request", request, seq };
1015
+ }
1016
+ function remoteResponderEventsNode(graph, inbound, name, expectedSessionId, handlers, rejectUnknown) {
1017
+ return graph.node(
1018
+ [inbound],
1019
+ (ctx) => {
1020
+ const cursor = ctx.state.get() ?? { cursor: 0, remoteCursor: 0 };
1021
+ for (const raw of depBatch(ctx, 0) ?? []) {
1022
+ const envelope = raw;
1023
+ const received = reduceRemoteResponderInbound(cursor, envelope, expectedSessionId);
1024
+ if (received.kind === "consumed") continue;
1025
+ if (received.kind === "invalid") {
1026
+ ctx.down([["DATA", { kind: "invalid", error: received.error }]]);
1027
+ continue;
1028
+ }
1029
+ const { request, seq } = received;
1030
+ ctx.down([["DATA", { kind: "request", request, seq }]]);
1031
+ const handler = handlers.get(request.operation);
1032
+ if (handler === void 0) {
1033
+ if (!rejectUnknown) continue;
1034
+ const error = `remoteResponder: unknown operation '${request.operation}'`;
1035
+ const response = remoteCallErrorResponse(request, error);
1036
+ ctx.down([
1037
+ [
1038
+ "DATA",
1039
+ {
1040
+ kind: "rejected",
1041
+ requestId: request.requestId,
1042
+ operation: request.operation,
1043
+ error,
1044
+ command: { kind: "send", payload: response, requestId: request.requestId }
1045
+ }
1046
+ ]
1047
+ ]);
1048
+ continue;
1049
+ }
1050
+ try {
1051
+ const payload = handler(request);
1052
+ if (isThenable(payload)) {
1053
+ throw new Error("remoteResponder: async handler results require a later adapter shape");
1054
+ }
1055
+ const response = {
1056
+ kind: "result",
1057
+ operation: request.operation,
1058
+ requestId: request.requestId,
1059
+ payload
1060
+ };
1061
+ ctx.down([
1062
+ [
1063
+ "DATA",
1064
+ {
1065
+ kind: "response",
1066
+ requestId: request.requestId,
1067
+ operation: request.operation,
1068
+ command: { kind: "send", payload: response, requestId: request.requestId }
1069
+ }
1070
+ ]
1071
+ ]);
1072
+ } catch (error) {
1073
+ rethrowGraphRuntimeInvariant(error);
1074
+ const message = errorMessage(error);
1075
+ const response = remoteCallErrorResponse(request, message);
1076
+ ctx.down([
1077
+ [
1078
+ "DATA",
1079
+ {
1080
+ kind: "rejected",
1081
+ requestId: request.requestId,
1082
+ operation: request.operation,
1083
+ error: message,
1084
+ command: { kind: "send", payload: response, requestId: request.requestId }
1085
+ }
1086
+ ]
1087
+ ]);
1088
+ }
1089
+ }
1090
+ ctx.state.set(cursor);
1091
+ },
1092
+ {
1093
+ name: `${name}/events`,
1094
+ factory: "remoteResponderEvents",
1095
+ partial: true,
1096
+ completeWhenDepsComplete: false,
1097
+ errorWhenDepsError: false
1098
+ }
1099
+ );
1100
+ }
1101
+ function remoteCallErrorResponse(request, error) {
1102
+ return {
1103
+ kind: "error",
1104
+ operation: request.operation,
1105
+ requestId: request.requestId,
1106
+ error
1107
+ };
1108
+ }
1109
+ function remoteResponderResponseCommandsNode(graph, events, name) {
1110
+ return graph.node(
1111
+ [events],
1112
+ (ctx) => {
1113
+ for (const raw of depBatch(ctx, 0) ?? []) {
1114
+ const event = raw;
1115
+ if ((event.kind === "response" || event.kind === "rejected") && event.command !== void 0) {
1116
+ ctx.down([["DATA", event.command]]);
1117
+ }
1118
+ }
1119
+ },
1120
+ {
1121
+ name: `${name}/responseCommands`,
1122
+ factory: "remoteResponderResponseCommands",
1123
+ completeWhenDepsComplete: false,
1124
+ errorWhenDepsError: false
1125
+ }
1126
+ );
1127
+ }
1128
+ function remoteResponderRequestsNode(graph, events, name) {
1129
+ return graph.node(
1130
+ [events],
1131
+ (ctx) => {
1132
+ for (const raw of depBatch(ctx, 0) ?? []) {
1133
+ const event = raw;
1134
+ if (event.kind === "request") ctx.down([["DATA", event.request]]);
1135
+ }
1136
+ },
1137
+ {
1138
+ name: `${name}/requests`,
1139
+ factory: "remoteResponderRequests",
1140
+ completeWhenDepsComplete: false
1141
+ }
1142
+ );
1143
+ }
1144
+ function remoteResponderStatusNode(graph, events, name) {
1145
+ return graph.node(
1146
+ [events],
1147
+ (ctx) => {
1148
+ let status = ctx.state.get() ?? { state: "idle", handled: 0, rejected: 0, errors: 0 };
1149
+ for (const raw of depBatch(ctx, 0) ?? []) {
1150
+ const event = raw;
1151
+ if (event.kind === "response") {
1152
+ status = {
1153
+ ...status,
1154
+ state: "responded",
1155
+ operation: event.operation,
1156
+ requestId: event.requestId,
1157
+ handled: status.handled + 1
1158
+ };
1159
+ } else if (event.kind === "rejected") {
1160
+ status = {
1161
+ ...status,
1162
+ state: "rejected",
1163
+ operation: event.operation,
1164
+ requestId: event.requestId,
1165
+ rejected: status.rejected + 1,
1166
+ errors: status.errors + 1
1167
+ };
1168
+ } else if (event.kind === "invalid") {
1169
+ status = { ...status, state: "errored", errors: status.errors + 1 };
1170
+ }
1171
+ }
1172
+ ctx.state.set(status);
1173
+ ctx.down([["DATA", status]]);
1174
+ },
1175
+ {
1176
+ name: `${name}/status`,
1177
+ factory: "remoteResponderStatus",
1178
+ partial: true,
1179
+ completeWhenDepsComplete: false,
1180
+ errorWhenDepsError: false
1181
+ }
1182
+ );
1183
+ }
1184
+ function remoteResponderErrorsNode(graph, events, name) {
1185
+ return graph.node(
1186
+ [events],
1187
+ (ctx) => {
1188
+ for (const raw of depBatch(ctx, 0) ?? []) {
1189
+ const event = raw;
1190
+ if (event.kind === "rejected") {
1191
+ ctx.down([
1192
+ [
1193
+ "DATA",
1194
+ { operation: event.operation, requestId: event.requestId, error: event.error }
1195
+ ]
1196
+ ]);
1197
+ } else if (event.kind === "invalid") {
1198
+ ctx.down([["DATA", { error: event.error }]]);
1199
+ }
1200
+ }
1201
+ },
1202
+ { name: `${name}/errors`, factory: "remoteResponderErrors", completeWhenDepsComplete: false }
1203
+ );
1204
+ }
1205
+ function armAckTimeout(ctx, state, envelope, opts, policy, now) {
1206
+ const timeoutMs = opts.ackTimeoutMs ?? defaultAckTimeoutMs;
1207
+ if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
1208
+ throw new RangeError("wireBridge: ackTimeoutMs must be a non-negative finite number");
1209
+ }
1210
+ const pending = { envelope };
1211
+ const schedule = (current) => {
1212
+ pending.timer = setTimeout(() => {
1213
+ pending.timer = void 0;
1214
+ if (!state.active || !state.pending.has(current.metadata.seq)) return;
1215
+ ctx.down([
1216
+ [
1217
+ "DATA",
1218
+ {
1219
+ kind: "timeout",
1220
+ seq: current.metadata.seq,
1221
+ attempt: current.metadata.attempt
1222
+ }
1223
+ ]
1224
+ ]);
1225
+ if (!shouldRetry(policy, current.metadata.attempt)) {
1226
+ const error = `${opts.sessionId}: ack timeout for seq ${current.metadata.seq}`;
1227
+ state.pending.delete(current.metadata.seq);
1228
+ ctx.down([
1229
+ [
1230
+ "DATA",
1231
+ {
1232
+ kind: "exhausted",
1233
+ seq: current.metadata.seq,
1234
+ attempt: current.metadata.attempt,
1235
+ error
1236
+ }
1237
+ ]
1238
+ ]);
1239
+ return;
1240
+ }
1241
+ const attempt = current.metadata.attempt + 1;
1242
+ const delayMs = nextRetryDelayMs(policy, attempt) ?? 0;
1243
+ ctx.down([
1244
+ [
1245
+ "DATA",
1246
+ {
1247
+ kind: "retry",
1248
+ seq: current.metadata.seq,
1249
+ attempt,
1250
+ delayMs,
1251
+ error: `${opts.sessionId}: ack timeout for seq ${current.metadata.seq}`
1252
+ }
1253
+ ]
1254
+ ]);
1255
+ const retry = wireBridgeEnvelope({
1256
+ sessionId: current.sessionId,
1257
+ type: current.type,
1258
+ seq: current.metadata.seq,
1259
+ cursor: state.cursor,
1260
+ payload: current.payload,
1261
+ idempotencyKey: current.metadata.idempotencyKey,
1262
+ attempt,
1263
+ maxAttempts: policy.maxAttempts,
1264
+ timestampMs: now(),
1265
+ requestId: current.metadata.requestId
1266
+ });
1267
+ pending.timer = setTimeout(() => {
1268
+ pending.timer = void 0;
1269
+ if (!state.active || !state.pending.has(current.metadata.seq)) return;
1270
+ pending.envelope = retry;
1271
+ ctx.down([["DATA", { kind: "outbound", envelope: retry }]]);
1272
+ schedule(retry);
1273
+ }, delayMs);
1274
+ }, timeoutMs);
1275
+ };
1276
+ state.pending.set(envelope.metadata.seq, pending);
1277
+ schedule(envelope);
1278
+ }
1279
+ function processInbound(ctx, state, input, sessionId) {
1280
+ if (isInvalidIngress(input)) {
1281
+ ctx.down([["DATA", { kind: "invalid", error: input.error }]]);
1282
+ return;
1283
+ }
1284
+ const invalid = validateInboundEnvelope(input);
1285
+ if (invalid !== void 0) {
1286
+ ctx.down([["DATA", { kind: "invalid", error: invalid }]]);
1287
+ return;
1288
+ }
1289
+ const envelope = input;
1290
+ if (envelope.sessionId !== sessionId) {
1291
+ ctx.down([
1292
+ [
1293
+ "DATA",
1294
+ {
1295
+ kind: "session-mismatch",
1296
+ expected: sessionId,
1297
+ actual: envelope.sessionId
1298
+ }
1299
+ ]
1300
+ ]);
1301
+ return;
1302
+ }
1303
+ const seq = envelope.metadata.seq;
1304
+ const expected = state.cursor + 1;
1305
+ if (seq <= state.cursor) {
1306
+ ctx.down([["DATA", { kind: "duplicate", seq, cursor: state.cursor }]]);
1307
+ return;
1308
+ }
1309
+ if (seq > expected) {
1310
+ ctx.down([["DATA", { kind: "out-of-order", seq, expected }]]);
1311
+ return;
1312
+ }
1313
+ if (envelope.metadata.cursor < state.remoteCursor) {
1314
+ ctx.down([
1315
+ [
1316
+ "DATA",
1317
+ {
1318
+ kind: "invalid",
1319
+ error: `${sessionId}: inbound cursor ${envelope.metadata.cursor} regressed below ${state.remoteCursor}`
1320
+ }
1321
+ ]
1322
+ ]);
1323
+ return;
1324
+ }
1325
+ state.remoteCursor = envelope.metadata.cursor;
1326
+ state.cursor = seq;
1327
+ ctx.down([["DATA", { kind: "cursor", cursor: state.cursor }]]);
1328
+ ctx.down([["DATA", { kind: "inbound", envelope }]]);
1329
+ if (envelope.type === "ack" && envelope.metadata.ackForSeq !== void 0) {
1330
+ const pending = state.pending.get(envelope.metadata.ackForSeq);
1331
+ if (pending === void 0) {
1332
+ ctx.down([
1333
+ ["DATA", { kind: "late-receipt", receipt: "ack", ackForSeq: envelope.metadata.ackForSeq }]
1334
+ ]);
1335
+ return;
1336
+ }
1337
+ if (pending?.timer !== void 0) clearTimeout(pending.timer);
1338
+ state.pending.delete(envelope.metadata.ackForSeq);
1339
+ ctx.down([
1340
+ [
1341
+ "DATA",
1342
+ {
1343
+ kind: "ack",
1344
+ ackForSeq: envelope.metadata.ackForSeq,
1345
+ envelope,
1346
+ outbound: pending.envelope
1347
+ }
1348
+ ]
1349
+ ]);
1350
+ } else if (envelope.type === "nack" && envelope.metadata.ackForSeq !== void 0) {
1351
+ const pending = state.pending.get(envelope.metadata.ackForSeq);
1352
+ if (pending === void 0) {
1353
+ ctx.down([
1354
+ ["DATA", { kind: "late-receipt", receipt: "nack", ackForSeq: envelope.metadata.ackForSeq }]
1355
+ ]);
1356
+ return;
1357
+ }
1358
+ if (pending?.timer !== void 0) clearTimeout(pending.timer);
1359
+ state.pending.delete(envelope.metadata.ackForSeq);
1360
+ ctx.down([
1361
+ [
1362
+ "DATA",
1363
+ {
1364
+ kind: "nack",
1365
+ ackForSeq: envelope.metadata.ackForSeq,
1366
+ envelope,
1367
+ outbound: pending.envelope,
1368
+ error: bridgePayloadError(envelope.payload, "remote nack")
1369
+ }
1370
+ ]
1371
+ ]);
1372
+ }
1373
+ }
1374
+ function validateInboundEnvelope(envelope) {
1375
+ if (typeof envelope !== "object" || envelope === null) {
1376
+ return "wireBridge: inbound envelope must be an object";
1377
+ }
1378
+ const candidate = envelope;
1379
+ if (typeof candidate.sessionId !== "string" || candidate.sessionId.length === 0) {
1380
+ return "wireBridge: inbound envelope sessionId must be a non-empty string";
1381
+ }
1382
+ if (typeof candidate.type !== "string" || !envelopeTypes.has(candidate.type)) {
1383
+ return "wireBridge: inbound envelope type is not recognized";
1384
+ }
1385
+ const metadata = candidate.metadata;
1386
+ if (typeof metadata !== "object" || metadata === null) {
1387
+ return "wireBridge: inbound envelope metadata must be an object";
1388
+ }
1389
+ if (!isSafePositiveInteger(metadata.seq)) {
1390
+ return "wireBridge: inbound envelope seq must be a positive integer";
1391
+ }
1392
+ if (!isSafeNonNegativeInteger(metadata.cursor)) {
1393
+ return "wireBridge: inbound envelope cursor must be a non-negative integer";
1394
+ }
1395
+ if (typeof metadata.idempotencyKey !== "string" || metadata.idempotencyKey.length === 0) {
1396
+ return "wireBridge: inbound envelope idempotencyKey must be a non-empty string";
1397
+ }
1398
+ if (!isSafePositiveInteger(metadata.attempt)) {
1399
+ return "wireBridge: inbound envelope attempt must be a positive integer";
1400
+ }
1401
+ if (!isSafePositiveInteger(metadata.maxAttempts) || metadata.maxAttempts < metadata.attempt) {
1402
+ return "wireBridge: inbound envelope maxAttempts must be >= attempt";
1403
+ }
1404
+ if (metadata.ackForSeq !== void 0 && !isSafePositiveInteger(metadata.ackForSeq)) {
1405
+ return "wireBridge: inbound envelope ackForSeq must be a positive integer";
1406
+ }
1407
+ if ((candidate.type === "ack" || candidate.type === "nack") && metadata.ackForSeq === void 0) {
1408
+ return `wireBridge: inbound ${candidate.type} envelope requires ackForSeq`;
1409
+ }
1410
+ const payloadError = validatePayloadForType(
1411
+ candidate.type,
1412
+ candidate.payload,
1413
+ "wireBridge: inbound envelope"
1414
+ );
1415
+ if (payloadError !== void 0) return payloadError;
1416
+ return void 0;
1417
+ }
1418
+ function validateCommand(value) {
1419
+ if (typeof value !== "object" || value === null) {
1420
+ return "wireBridge: command fact must be an object";
1421
+ }
1422
+ const kind = value.kind;
1423
+ if (kind !== "start" && kind !== "send" && kind !== "ack" && kind !== "nack" && kind !== "close") {
1424
+ return "wireBridge: command kind is not recognized";
1425
+ }
1426
+ if ((kind === "ack" || kind === "nack") && !isSafePositiveInteger(value.ackForSeq)) {
1427
+ return `wireBridge: ${kind} command ackForSeq must be a positive integer`;
1428
+ }
1429
+ return void 0;
1430
+ }
1431
+ function projectOutbound(graph, events, name) {
1432
+ return graph.node(
1433
+ [events],
1434
+ (ctx) => {
1435
+ for (const raw of depBatch(ctx, 0) ?? []) {
1436
+ const event = raw;
1437
+ if (event.kind === "outbound") ctx.down([["DATA", event.envelope]]);
1438
+ }
1439
+ },
1440
+ { name: `${name}/outbound`, factory: "wireBridgeOutbound" }
1441
+ );
1442
+ }
1443
+ function projectAcks(graph, events, name) {
1444
+ return graph.node(
1445
+ [events],
1446
+ (ctx) => {
1447
+ for (const raw of depBatch(ctx, 0) ?? []) {
1448
+ const event = raw;
1449
+ if (event.kind === "ack") {
1450
+ ctx.down([["DATA", { ackForSeq: event.ackForSeq, envelope: event.envelope }]]);
1451
+ }
1452
+ }
1453
+ },
1454
+ { name: `${name}/acks`, factory: "wireBridgeAcks" }
1455
+ );
1456
+ }
1457
+ function projectNacks(graph, events, name) {
1458
+ return graph.node(
1459
+ [events],
1460
+ (ctx) => {
1461
+ for (const raw of depBatch(ctx, 0) ?? []) {
1462
+ const event = raw;
1463
+ if (event.kind === "nack") {
1464
+ ctx.down([
1465
+ ["DATA", { ackForSeq: event.ackForSeq, envelope: event.envelope, error: event.error }]
1466
+ ]);
1467
+ }
1468
+ }
1469
+ },
1470
+ { name: `${name}/nacks`, factory: "wireBridgeNacks" }
1471
+ );
1472
+ }
1473
+ function projectStatus(graph, events, name, sessionId) {
1474
+ return graph.node(
1475
+ [events],
1476
+ (ctx) => {
1477
+ let next = ctx.state.get() ?? {
1478
+ sessionId,
1479
+ state: "idle",
1480
+ cursor: 0,
1481
+ nextSeq: 1,
1482
+ pending: 0,
1483
+ attempts: 0,
1484
+ acked: 0,
1485
+ nacked: 0,
1486
+ errors: 0
1487
+ };
1488
+ for (const raw of depBatch(ctx, 0) ?? []) {
1489
+ const event = raw;
1490
+ if (event.kind === "outbound") {
1491
+ const { seq, attempt } = event.envelope.metadata;
1492
+ const trackAck = shouldTrackAck(event.envelope.type);
1493
+ next = {
1494
+ ...next,
1495
+ state: event.envelope.type === "start" ? "started" : event.envelope.type === "close" ? "closed" : "open",
1496
+ nextSeq: Math.max(next.nextSeq, seq + 1),
1497
+ pending: event.envelope.type === "close" ? 1 : trackAck && attempt === 1 ? next.pending + 1 : next.pending,
1498
+ attempts: trackAck ? next.attempts + 1 : next.attempts,
1499
+ lastSeq: seq
1500
+ };
1501
+ } else if (event.kind === "ack") {
1502
+ next = {
1503
+ ...next,
1504
+ state: event.outbound.type === "close" ? "closed" : "open",
1505
+ pending: Math.max(0, next.pending - 1),
1506
+ acked: next.acked + 1,
1507
+ lastSeq: event.envelope.metadata.seq
1508
+ };
1509
+ } else if (event.kind === "nack") {
1510
+ next = {
1511
+ ...next,
1512
+ state: "errored",
1513
+ pending: Math.max(0, next.pending - 1),
1514
+ nacked: next.nacked + 1,
1515
+ errors: next.errors + 1,
1516
+ lastSeq: event.envelope.metadata.seq
1517
+ };
1518
+ } else if (event.kind === "retry") {
1519
+ next = {
1520
+ ...next,
1521
+ state: "waiting",
1522
+ lastSeq: event.seq,
1523
+ lastDelayMs: event.delayMs
1524
+ };
1525
+ } else if (event.kind === "exhausted") {
1526
+ next = {
1527
+ ...next,
1528
+ state: "exhausted",
1529
+ pending: Math.max(0, next.pending - 1),
1530
+ errors: next.errors + 1,
1531
+ lastSeq: event.seq
1532
+ };
1533
+ } else if (event.kind === "cursor") {
1534
+ next = { ...next, cursor: event.cursor };
1535
+ } else if (event.kind === "out-of-order") {
1536
+ next = { ...next, state: "errored", errors: next.errors + 1, lastSeq: event.seq };
1537
+ } else if (event.kind === "session-mismatch") {
1538
+ next = { ...next, state: "errored", errors: next.errors + 1 };
1539
+ } else if (event.kind === "late-receipt" || event.kind === "invalid") {
1540
+ next = { ...next, state: "errored", errors: next.errors + 1 };
1541
+ } else if (event.kind === "inbound" && event.envelope.type === "error") {
1542
+ next = {
1543
+ ...next,
1544
+ state: "errored",
1545
+ errors: next.errors + 1,
1546
+ lastSeq: event.envelope.metadata.seq
1547
+ };
1548
+ } else if (event.kind === "inbound" && event.envelope.type === "close") {
1549
+ next = { ...next, state: "closed", lastSeq: event.envelope.metadata.seq };
1550
+ }
1551
+ }
1552
+ ctx.state.set(next);
1553
+ ctx.down([["DATA", next]]);
1554
+ },
1555
+ { name: `${name}/status`, factory: "wireBridgeStatus" }
1556
+ );
1557
+ }
1558
+ function projectErrors(graph, events, name) {
1559
+ return graph.node(
1560
+ [events],
1561
+ (ctx) => {
1562
+ for (const raw of depBatch(ctx, 0) ?? []) {
1563
+ const event = raw;
1564
+ if (event.kind === "nack") ctx.down([["DATA", event.error]]);
1565
+ else if (event.kind === "exhausted") ctx.down([["DATA", event.error]]);
1566
+ else if (event.kind === "out-of-order") {
1567
+ ctx.down([
1568
+ [
1569
+ "DATA",
1570
+ `${name}: inbound seq ${event.seq} arrived before expected seq ${event.expected}`
1571
+ ]
1572
+ ]);
1573
+ } else if (event.kind === "inbound" && event.envelope.type === "error") {
1574
+ ctx.down([["DATA", bridgePayloadError(event.envelope.payload, "remote error envelope")]]);
1575
+ } else if (event.kind === "session-mismatch") {
1576
+ ctx.down([
1577
+ [
1578
+ "DATA",
1579
+ `${name}: inbound session ${event.actual} did not match expected ${event.expected}`
1580
+ ]
1581
+ ]);
1582
+ } else if (event.kind === "late-receipt") {
1583
+ ctx.down([
1584
+ [
1585
+ "DATA",
1586
+ `${name}: late ${event.receipt} for unknown or completed ackForSeq ${event.ackForSeq}`
1587
+ ]
1588
+ ]);
1589
+ } else if (event.kind === "invalid") {
1590
+ ctx.down([["DATA", event.error]]);
1591
+ }
1592
+ }
1593
+ },
1594
+ { name: `${name}/errors`, factory: "wireBridgeErrors" }
1595
+ );
1596
+ }
1597
+ function projectCursor(graph, events, name) {
1598
+ return graph.node(
1599
+ [events],
1600
+ (ctx) => {
1601
+ for (const raw of depBatch(ctx, 0) ?? []) {
1602
+ const event = raw;
1603
+ if (event.kind === "cursor") ctx.down([["DATA", event.cursor]]);
1604
+ }
1605
+ },
1606
+ { name: `${name}/cursor`, factory: "wireBridgeCursor" }
1607
+ );
1608
+ }
1609
+ function projectAttempts(graph, events, name) {
1610
+ return graph.node(
1611
+ [events],
1612
+ (ctx) => {
1613
+ for (const raw of depBatch(ctx, 0) ?? []) {
1614
+ const event = raw;
1615
+ if (event.kind === "outbound" && shouldTrackAck(event.envelope.type)) {
1616
+ ctx.down([
1617
+ [
1618
+ "DATA",
1619
+ {
1620
+ seq: event.envelope.metadata.seq,
1621
+ attempt: event.envelope.metadata.attempt,
1622
+ maxAttempts: event.envelope.metadata.maxAttempts
1623
+ }
1624
+ ]
1625
+ ]);
1626
+ }
1627
+ }
1628
+ },
1629
+ { name: `${name}/attempts`, factory: "wireBridgeAttempts" }
1630
+ );
1631
+ }
1632
+ function guardedInboundNode(node, sessionId) {
1633
+ return new Proxy(node, {
1634
+ get(target, property) {
1635
+ if (property === "down") {
1636
+ return (msgs) => target.down(guardInboundWave(msgs, sessionId));
1637
+ }
1638
+ const value = Reflect.get(target, property, target);
1639
+ return typeof value === "function" ? value.bind(target) : value;
1640
+ }
1641
+ });
1642
+ }
1643
+ function guardInboundWave(msgs, sessionId) {
1644
+ return msgs.map((msg) => {
1645
+ if (msg[0] === "DATA") return msg;
1646
+ if (msg[0] === "ERROR") {
1647
+ return [
1648
+ "DATA",
1649
+ invalidIngress(
1650
+ `${sessionId}: inbound protocol ERROR ${String(
1651
+ errorPayload(msg[1])
1652
+ )} is local misuse; remote errors must arrive as DATA envelope facts`
1653
+ )
1654
+ ];
1655
+ }
1656
+ if (msg[0] === "COMPLETE") {
1657
+ return [
1658
+ "DATA",
1659
+ invalidIngress(
1660
+ `${sessionId}: inbound protocol COMPLETE is local misuse; remote completion must arrive as a DATA envelope fact`
1661
+ )
1662
+ ];
1663
+ }
1664
+ return [
1665
+ "DATA",
1666
+ invalidIngress(
1667
+ `${sessionId}: inbound port accepts DATA envelope facts only; ${msg[0]} is local protocol traffic`
1668
+ )
1669
+ ];
1670
+ });
1671
+ }
1672
+ function invalidIngress(error) {
1673
+ return { __wireBridgeInvalidIngress: true, error };
1674
+ }
1675
+ function isInvalidIngress(value) {
1676
+ return typeof value === "object" && value !== null && value.__wireBridgeInvalidIngress === true && typeof value.error === "string";
1677
+ }
1678
+ function shouldTrackAck(type) {
1679
+ return type === "start" || type === "data" || type === "close";
1680
+ }
1681
+ function isSafePositiveInteger(value) {
1682
+ return Number.isSafeInteger(value) && value > 0;
1683
+ }
1684
+ function isSafeNonNegativeInteger(value) {
1685
+ return Number.isSafeInteger(value) && value >= 0;
1686
+ }
1687
+ function validatePayloadForType(type, payload, prefix) {
1688
+ const kind = typeof payload === "object" && payload !== null ? payload.kind : void 0;
1689
+ switch (type) {
1690
+ case "data":
1691
+ return kind === "data" && payload.value !== void 0 ? void 0 : `${prefix}: data envelope requires data payload`;
1692
+ case "nack":
1693
+ case "error":
1694
+ return kind === "error" && payload.error !== void 0 ? void 0 : `${prefix}: ${type} envelope requires error payload`;
1695
+ case "status":
1696
+ return kind === "status" && payload.status !== void 0 ? void 0 : `${prefix}: status envelope requires status payload`;
1697
+ case "close":
1698
+ return kind === "close" ? void 0 : `${prefix}: close envelope requires close payload`;
1699
+ case "start":
1700
+ case "ack":
1701
+ return payload === void 0 ? void 0 : `${prefix}: ${type} envelope must not carry a payload`;
1702
+ }
1703
+ }
1704
+ function bridgePayloadError(payload, fallback) {
1705
+ if (typeof payload === "object" && payload !== null && payload.kind === "error") {
1706
+ return payload.error;
1707
+ }
1708
+ return fallback;
1709
+ }
1710
+ function rethrowGraphRuntimeInvariant(error) {
1711
+ const message = errorMessage(error);
1712
+ if (message.includes("R-reentrancy") || message.includes("R-rewire") || message.includes("R-graph-domain") || message.includes("D37") || message.includes("D22") || message.includes("different graph") || message.includes("cross-graph") || message.includes("wire bridge") || message.includes("mid-fn topology mutation") || message.includes("reentrant dep mutation") || message.includes("feedback cycle")) {
1713
+ throw error;
1714
+ }
1715
+ }
1716
+ function errorMessage(error) {
1717
+ return error instanceof Error ? error.message : String(error);
1718
+ }
1719
+
1720
+ // src/adapters/environment.ts
1721
+ function assertSourceLocal(source) {
1722
+ return source;
1723
+ }
1724
+ function initSendState(ctx) {
1725
+ let state = ctx.state.get();
1726
+ if (state === void 0) {
1727
+ state = {
1728
+ seq: 0,
1729
+ cancels: /* @__PURE__ */ new Map(),
1730
+ timers: /* @__PURE__ */ new Map(),
1731
+ active: true,
1732
+ cleanupInstalled: false
1733
+ };
1734
+ ctx.state.set(state);
1735
+ }
1736
+ state.active = true;
1737
+ if (!state.cleanupInstalled) {
1738
+ state.cleanupInstalled = true;
1739
+ ctx.onDeactivation(() => {
1740
+ state.active = false;
1741
+ state.cleanupInstalled = false;
1742
+ for (const cancel of state.cancels.values()) runCancel(cancel);
1743
+ for (const timer of state.timers.values()) clearTimeout(timer);
1744
+ state.cancels.clear();
1745
+ state.timers.clear();
1746
+ });
1747
+ }
1748
+ return state;
1749
+ }
1750
+ function runCancel(cancel) {
1751
+ try {
1752
+ cancel();
1753
+ } catch {
1754
+ }
1755
+ }
1756
+ function outboundNodes(graph, events, name) {
1757
+ const status = graph.node(
1758
+ [events],
1759
+ (ctx) => {
1760
+ const current = ctx.state.get() ?? { state: "idle", inFlight: 0, attempt: 0, sent: 0, failed: 0 };
1761
+ let next = current;
1762
+ for (const event of depBatch(ctx, 0) ?? []) {
1763
+ next = reduceStatus(next, event);
1764
+ }
1765
+ ctx.state.set(next);
1766
+ ctx.down([["DATA", next]]);
1767
+ },
1768
+ { name: `${name}/status`, factory: "outboundStatus" }
1769
+ );
1770
+ const attempts = graph.node(
1771
+ [events],
1772
+ (ctx) => {
1773
+ for (const event of depBatch(ctx, 0) ?? []) {
1774
+ const typed = event;
1775
+ if ("attempt" in typed) ctx.down([["DATA", typed.attempt]]);
1776
+ }
1777
+ },
1778
+ { name: `${name}/attempts`, factory: "outboundAttempts" }
1779
+ );
1780
+ const errors = graph.node(
1781
+ [events],
1782
+ (ctx) => {
1783
+ for (const event of depBatch(ctx, 0) ?? []) {
1784
+ const typed = event;
1785
+ if ("error" in typed) ctx.down([["DATA", typed.error]]);
1786
+ }
1787
+ },
1788
+ { name: `${name}/errors`, factory: "outboundErrors" }
1789
+ );
1790
+ return { events, status, attempts, errors };
1791
+ }
1792
+ function reduceStatus(current, event) {
1793
+ switch (event.kind) {
1794
+ case "attempt":
1795
+ return {
1796
+ ...current,
1797
+ state: "running",
1798
+ inFlight: current.inFlight + 1,
1799
+ attempt: event.attempt
1800
+ };
1801
+ case "retry":
1802
+ return {
1803
+ ...current,
1804
+ state: "waiting",
1805
+ inFlight: Math.max(0, current.inFlight - 1),
1806
+ attempt: event.attempt,
1807
+ lastDelayMs: event.delayMs
1808
+ };
1809
+ case "sent":
1810
+ return {
1811
+ ...current,
1812
+ state: "succeeded",
1813
+ inFlight: Math.max(0, current.inFlight - 1),
1814
+ attempt: event.attempt,
1815
+ sent: current.sent + 1,
1816
+ lastDelayMs: void 0
1817
+ };
1818
+ case "failed":
1819
+ return {
1820
+ ...current,
1821
+ state: "failed",
1822
+ inFlight: Math.max(0, current.inFlight - 1),
1823
+ attempt: event.attempt,
1824
+ failed: current.failed + 1
1825
+ };
1826
+ case "exhausted":
1827
+ return {
1828
+ ...current,
1829
+ state: "exhausted",
1830
+ inFlight: Math.max(0, current.inFlight - 1),
1831
+ attempt: event.attempt,
1832
+ failed: current.failed + 1
1833
+ };
1834
+ case "upstream-complete":
1835
+ return { ...current, state: "completed" };
1836
+ case "upstream-error":
1837
+ return { ...current, state: "failed", failed: current.failed + 1 };
1838
+ }
1839
+ }
1840
+ function initWebSocketSessionState(ctx) {
1841
+ let state = ctx.state.get();
1842
+ if (state === void 0) {
1843
+ state = {
1844
+ active: true,
1845
+ connected: false,
1846
+ cleanupInstalled: false,
1847
+ currentAttempt: 0,
1848
+ currentSession: void 0,
1849
+ sendCancels: /* @__PURE__ */ new Map(),
1850
+ liveSends: /* @__PURE__ */ new Map(),
1851
+ pendingOutbound: [],
1852
+ timers: /* @__PURE__ */ new Map(),
1853
+ seq: 0,
1854
+ outboundSeq: 0
1855
+ };
1856
+ ctx.state.set(state);
1857
+ }
1858
+ state.active = true;
1859
+ if (!state.cleanupInstalled) {
1860
+ state.cleanupInstalled = true;
1861
+ ctx.onDeactivation(() => {
1862
+ const sendCancels = [...state.sendCancels.values()];
1863
+ const timers = [...state.timers.values()];
1864
+ const session = state.currentSession;
1865
+ state.active = false;
1866
+ state.cleanupInstalled = false;
1867
+ state.connected = false;
1868
+ state.currentAttempt = 0;
1869
+ state.currentSession = void 0;
1870
+ state.sendCancels.clear();
1871
+ state.liveSends.clear();
1872
+ state.pendingOutbound = [];
1873
+ state.timers.clear();
1874
+ for (const cancel of sendCancels) runCancel(cancel);
1875
+ for (const timer of timers) clearTimeout(timer);
1876
+ session?.cancel();
1877
+ });
1878
+ }
1879
+ return state;
1880
+ }
1881
+ function closeWebSocketSessionState(state, driverAction = "cancel") {
1882
+ const session = state.currentSession;
1883
+ const timers = [...state.timers.values()];
1884
+ const sendCancels = [...state.sendCancels.values()];
1885
+ const canceled = [...state.pendingOutbound, ...state.liveSends.values()];
1886
+ state.connected = false;
1887
+ state.currentAttempt = 0;
1888
+ state.currentSession = void 0;
1889
+ state.timers.clear();
1890
+ state.sendCancels.clear();
1891
+ state.pendingOutbound = [];
1892
+ state.liveSends.clear();
1893
+ for (const timer of timers) clearTimeout(timer);
1894
+ for (const cancelSend of sendCancels) runCancel(cancelSend);
1895
+ if (driverAction === "cancel") session?.cancel();
1896
+ return { canceled, session };
1897
+ }
1898
+ function cancelRetryTimers(state) {
1899
+ for (const timer of state.timers.values()) clearTimeout(timer);
1900
+ state.timers.clear();
1901
+ }
1902
+ function cleanupWebSocketConnection(state, driverAction = "cancel") {
1903
+ const session = state.currentSession;
1904
+ const sendCancels = [...state.sendCancels.values()];
1905
+ const canceled = [...state.liveSends.values()];
1906
+ state.connected = false;
1907
+ state.currentAttempt = 0;
1908
+ state.currentSession = void 0;
1909
+ state.sendCancels.clear();
1910
+ state.liveSends.clear();
1911
+ for (const cancelSend of sendCancels) runCancel(cancelSend);
1912
+ if (driverAction === "cancel") session?.cancel();
1913
+ return canceled;
1914
+ }
1915
+ function normalizeWebSocketSessionSendPolicy(policy) {
1916
+ if (policy?.kind !== "buffer") return { kind: "reject" };
1917
+ if (!Number.isFinite(policy.maxPending) || policy.maxPending < 1) {
1918
+ throw new Error("webSocketSession: buffer sendPolicy requires finite maxPending >= 1");
1919
+ }
1920
+ return { kind: "buffer", maxPending: Math.floor(policy.maxPending) };
1921
+ }
1922
+ function webSocketSessionEventNode(graph, command, request, name, policy, sendPolicy) {
1923
+ return graph.node(
1924
+ [command],
1925
+ (ctx) => {
1926
+ const state = initWebSocketSessionState(ctx);
1927
+ const emitOutbound = (fact) => {
1928
+ ctx.down([["DATA", { kind: "outbound", fact }]]);
1929
+ };
1930
+ const emitOutboundCanceled = (items, reason) => {
1931
+ for (const item of items) {
1932
+ emitOutbound({
1933
+ kind: "canceled",
1934
+ seq: item.seq,
1935
+ message: item.message,
1936
+ reason
1937
+ });
1938
+ }
1939
+ };
1940
+ const emitOutboundRejected = (items, error) => {
1941
+ const payload = errorPayload(error);
1942
+ for (const item of items) {
1943
+ emitOutbound({
1944
+ kind: "rejected",
1945
+ seq: item.seq,
1946
+ message: item.message,
1947
+ error: payload
1948
+ });
1949
+ }
1950
+ };
1951
+ const retryOrExhaust = (attempt, error) => {
1952
+ const payload = errorPayload(error);
1953
+ const canceled = cleanupWebSocketConnection(state);
1954
+ emitOutboundCanceled(canceled, `${name}: connection cleanup`);
1955
+ if (shouldRetry(policy, attempt)) {
1956
+ const nextAttempt = attempt + 1;
1957
+ const delayMs = nextRetryDelayMs(policy, nextAttempt) ?? 0;
1958
+ ctx.down([
1959
+ [
1960
+ "DATA",
1961
+ {
1962
+ kind: "retry",
1963
+ attempt,
1964
+ nextAttempt,
1965
+ delayMs,
1966
+ error: payload
1967
+ }
1968
+ ]
1969
+ ]);
1970
+ const timerId = state.seq++;
1971
+ const timer = setTimeout(() => {
1972
+ state.timers.delete(timerId);
1973
+ if (!state.active) return;
1974
+ start(nextAttempt);
1975
+ }, delayMs);
1976
+ state.timers.set(timerId, timer);
1977
+ } else {
1978
+ emitOutboundRejected(state.pendingOutbound, payload);
1979
+ state.pendingOutbound = [];
1980
+ ctx.down([
1981
+ [
1982
+ "DATA",
1983
+ { kind: "exhausted", attempt, error: payload }
1984
+ ]
1985
+ ]);
1986
+ }
1987
+ };
1988
+ const start = (attempt) => {
1989
+ if (!state.active || state.connected || state.currentAttempt !== 0 || state.timers.size > 0) {
1990
+ return;
1991
+ }
1992
+ const driver = ctx.environment().webSocketDriver();
1993
+ state.currentAttempt = attempt;
1994
+ ctx.down([
1995
+ [
1996
+ "DATA",
1997
+ {
1998
+ kind: "attempt",
1999
+ attempt,
2000
+ maxAttempts: policy.maxAttempts
2001
+ }
2002
+ ]
2003
+ ]);
2004
+ const connectSession = driver?.connectSession;
2005
+ if (connectSession === void 0) {
2006
+ retryOrExhaust(attempt, `${name}: missing WebSocket session capability`);
2007
+ return;
2008
+ }
2009
+ let session;
2010
+ try {
2011
+ session = connectSession.call(driver, request, (event) => {
2012
+ if (!state.active || state.currentAttempt !== attempt) return;
2013
+ if (event.kind === "event") {
2014
+ const ws = event.event;
2015
+ if (ws.kind === "open") {
2016
+ state.connected = true;
2017
+ ctx.down([["DATA", { kind: "open", attempt }]]);
2018
+ flushPending();
2019
+ } else if (ws.kind === "text" || ws.kind === "binary") {
2020
+ ctx.down([
2021
+ [
2022
+ "DATA",
2023
+ {
2024
+ kind: "message",
2025
+ message: ws
2026
+ }
2027
+ ]
2028
+ ]);
2029
+ } else if (ws.kind === "close") {
2030
+ const normalClose = ws.code === 1e3;
2031
+ const canceled = cleanupWebSocketConnection(state);
2032
+ emitOutboundCanceled(canceled, `${name}: session closed`);
2033
+ ctx.down([
2034
+ [
2035
+ "DATA",
2036
+ {
2037
+ kind: "closed",
2038
+ code: ws.code,
2039
+ reason: ws.reason
2040
+ }
2041
+ ]
2042
+ ]);
2043
+ if (!normalClose) {
2044
+ retryOrExhaust(attempt, {
2045
+ kind: "close",
2046
+ code: ws.code,
2047
+ reason: ws.reason
2048
+ });
2049
+ }
2050
+ }
2051
+ } else if (event.kind === "error") {
2052
+ retryOrExhaust(attempt, event.error);
2053
+ } else if (event.kind === "complete") {
2054
+ retryOrExhaust(attempt, `${name}: connection completed`);
2055
+ }
2056
+ });
2057
+ } catch (error) {
2058
+ retryOrExhaust(attempt, error);
2059
+ return;
2060
+ }
2061
+ if (session === void 0) {
2062
+ retryOrExhaust(attempt, `${name}: missing WebSocket session capability`);
2063
+ return;
2064
+ }
2065
+ if (state.active && state.currentAttempt === attempt) {
2066
+ state.currentSession = session;
2067
+ } else {
2068
+ session.cancel();
2069
+ }
2070
+ };
2071
+ function sendNow(item) {
2072
+ if (!state.connected) {
2073
+ emitOutbound({
2074
+ kind: "rejected",
2075
+ seq: item.seq,
2076
+ message: item.message,
2077
+ error: `${name}: session is not open`
2078
+ });
2079
+ ctx.down([
2080
+ [
2081
+ "DATA",
2082
+ {
2083
+ kind: "error",
2084
+ error: `${name}: session is not open`
2085
+ }
2086
+ ]
2087
+ ]);
2088
+ return;
2089
+ }
2090
+ const session = state.currentSession;
2091
+ if (session === void 0) {
2092
+ emitOutbound({
2093
+ kind: "rejected",
2094
+ seq: item.seq,
2095
+ message: item.message,
2096
+ error: `${name}: missing WebSocket session capability`
2097
+ });
2098
+ ctx.down([
2099
+ [
2100
+ "DATA",
2101
+ {
2102
+ kind: "error",
2103
+ error: `${name}: missing WebSocket session capability`
2104
+ }
2105
+ ]
2106
+ ]);
2107
+ return;
2108
+ }
2109
+ const sendId = state.seq++;
2110
+ state.liveSends.set(sendId, item);
2111
+ emitOutbound({ kind: "sending", seq: item.seq, message: item.message });
2112
+ let done = false;
2113
+ let cancel;
2114
+ try {
2115
+ cancel = session.send(item.message, (result) => {
2116
+ if (done || !state.active || !state.liveSends.has(sendId)) return;
2117
+ done = true;
2118
+ state.liveSends.delete(sendId);
2119
+ state.sendCancels.delete(sendId);
2120
+ if (result.ok) {
2121
+ emitOutbound({ kind: "sent", seq: item.seq, message: item.message });
2122
+ ctx.down([
2123
+ ["DATA", { kind: "sent", message: item.message }]
2124
+ ]);
2125
+ } else {
2126
+ const payload = errorPayload(result.error);
2127
+ emitOutbound({
2128
+ kind: "rejected",
2129
+ seq: item.seq,
2130
+ message: item.message,
2131
+ error: payload
2132
+ });
2133
+ ctx.down([
2134
+ [
2135
+ "DATA",
2136
+ {
2137
+ kind: "error",
2138
+ error: payload
2139
+ }
2140
+ ]
2141
+ ]);
2142
+ }
2143
+ });
2144
+ } catch (error) {
2145
+ state.liveSends.delete(sendId);
2146
+ const payload = errorPayload(error);
2147
+ emitOutbound({
2148
+ kind: "rejected",
2149
+ seq: item.seq,
2150
+ message: item.message,
2151
+ error: payload
2152
+ });
2153
+ ctx.down([["DATA", { kind: "error", error: payload }]]);
2154
+ return;
2155
+ }
2156
+ if (cancel !== void 0 && !done && state.active && state.liveSends.has(sendId)) {
2157
+ state.sendCancels.set(sendId, cancel);
2158
+ } else if (cancel !== void 0 && !state.active) runCancel(cancel);
2159
+ }
2160
+ function flushPending() {
2161
+ const pending = state.pendingOutbound;
2162
+ state.pendingOutbound = [];
2163
+ for (let index = 0; index < pending.length; index++) {
2164
+ const item = pending[index];
2165
+ if (!state.connected || state.currentSession === void 0) {
2166
+ emitOutboundCanceled(pending.slice(index), `${name}: session closed`);
2167
+ return;
2168
+ }
2169
+ sendNow(item);
2170
+ }
2171
+ }
2172
+ const send = (message) => {
2173
+ const item = { seq: state.outboundSeq++, message };
2174
+ if (state.connected) {
2175
+ sendNow(item);
2176
+ return;
2177
+ }
2178
+ if (sendPolicy.kind === "buffer") {
2179
+ if (state.pendingOutbound.length >= sendPolicy.maxPending) {
2180
+ emitOutbound({
2181
+ kind: "rejected",
2182
+ seq: item.seq,
2183
+ message,
2184
+ error: `${name}: outbound buffer full`
2185
+ });
2186
+ ctx.down([
2187
+ [
2188
+ "DATA",
2189
+ {
2190
+ kind: "error",
2191
+ error: `${name}: outbound buffer full`
2192
+ }
2193
+ ]
2194
+ ]);
2195
+ return;
2196
+ }
2197
+ state.pendingOutbound.push(item);
2198
+ emitOutbound({ kind: "queued", seq: item.seq, message });
2199
+ return;
2200
+ }
2201
+ emitOutbound({
2202
+ kind: "rejected",
2203
+ seq: item.seq,
2204
+ message,
2205
+ error: `${name}: session is not open`
2206
+ });
2207
+ ctx.down([
2208
+ [
2209
+ "DATA",
2210
+ {
2211
+ kind: "error",
2212
+ error: `${name}: session is not open`
2213
+ }
2214
+ ]
2215
+ ]);
2216
+ };
2217
+ for (const raw of depBatch(ctx, 0) ?? []) {
2218
+ const commandValue = raw;
2219
+ if (commandValue.kind === "start") start(1);
2220
+ else if (commandValue.kind === "send") send(commandValue.message);
2221
+ else {
2222
+ cancelRetryTimers(state);
2223
+ ctx.down([
2224
+ [
2225
+ "DATA",
2226
+ {
2227
+ kind: "closing",
2228
+ code: commandValue.code,
2229
+ reason: commandValue.reason
2230
+ }
2231
+ ]
2232
+ ]);
2233
+ const { canceled, session } = closeWebSocketSessionState(state, "none");
2234
+ emitOutboundCanceled(canceled, `${name}: session closed`);
2235
+ session?.close(commandValue.code, commandValue.reason);
2236
+ ctx.down([
2237
+ [
2238
+ "DATA",
2239
+ {
2240
+ kind: "closed",
2241
+ code: commandValue.code,
2242
+ reason: commandValue.reason
2243
+ }
2244
+ ]
2245
+ ]);
2246
+ }
2247
+ }
2248
+ },
2249
+ { name: `${name}/events`, factory: "webSocketSessionEvents" }
2250
+ );
2251
+ }
2252
+ function webSocketSessionNodes(graph, command, events, name, policy) {
2253
+ const inbound = graph.node(
2254
+ [events],
2255
+ (ctx) => {
2256
+ for (const raw of depBatch(ctx, 0) ?? []) {
2257
+ const event = raw;
2258
+ if (event.kind === "message") ctx.down([["DATA", event.message]]);
2259
+ }
2260
+ },
2261
+ { name: `${name}/inbound`, factory: "webSocketSessionInbound" }
2262
+ );
2263
+ const lifecycle = graph.node(
2264
+ [events],
2265
+ (ctx) => {
2266
+ for (const raw of depBatch(ctx, 0) ?? []) {
2267
+ const event = raw;
2268
+ if (event.kind === "attempt") {
2269
+ ctx.down([
2270
+ [
2271
+ "DATA",
2272
+ {
2273
+ kind: "starting",
2274
+ attempt: event.attempt,
2275
+ maxAttempts: event.maxAttempts
2276
+ }
2277
+ ]
2278
+ ]);
2279
+ } else if (event.kind === "open") {
2280
+ ctx.down([["DATA", { kind: "open", attempt: event.attempt }]]);
2281
+ } else if (event.kind === "sent") {
2282
+ ctx.down([["DATA", { kind: "sent", message: event.message }]]);
2283
+ } else if (event.kind === "closing" || event.kind === "closed") {
2284
+ ctx.down([["DATA", event]]);
2285
+ } else if (event.kind === "retry") {
2286
+ ctx.down([
2287
+ [
2288
+ "DATA",
2289
+ {
2290
+ kind: "retrying",
2291
+ attempt: event.attempt,
2292
+ nextAttempt: event.nextAttempt,
2293
+ delayMs: event.delayMs,
2294
+ error: event.error
2295
+ }
2296
+ ]
2297
+ ]);
2298
+ } else if (event.kind === "exhausted") {
2299
+ ctx.down([["DATA", event]]);
2300
+ }
2301
+ }
2302
+ },
2303
+ { name: `${name}/lifecycle`, factory: "webSocketSessionLifecycle" }
2304
+ );
2305
+ const outbound = graph.node(
2306
+ [events],
2307
+ (ctx) => {
2308
+ for (const raw of depBatch(ctx, 0) ?? []) {
2309
+ const event = raw;
2310
+ if (event.kind === "outbound") ctx.down([["DATA", event.fact]]);
2311
+ }
2312
+ },
2313
+ { name: `${name}/outbound`, factory: "webSocketSessionOutbound" }
2314
+ );
2315
+ const status = graph.node(
2316
+ [events],
2317
+ (ctx) => {
2318
+ let next = ctx.state.get() ?? {
2319
+ state: "idle",
2320
+ attempt: 0,
2321
+ maxAttempts: policy.maxAttempts,
2322
+ sent: 0,
2323
+ received: 0,
2324
+ errors: 0
2325
+ };
2326
+ for (const raw of depBatch(ctx, 0) ?? []) {
2327
+ const event = raw;
2328
+ if (event.kind === "attempt") {
2329
+ next = {
2330
+ ...next,
2331
+ state: "connecting",
2332
+ attempt: event.attempt,
2333
+ maxAttempts: event.maxAttempts,
2334
+ lastDelayMs: void 0
2335
+ };
2336
+ } else if (event.kind === "open") {
2337
+ next = { ...next, state: "open", attempt: event.attempt, lastDelayMs: void 0 };
2338
+ } else if (event.kind === "message") {
2339
+ next = { ...next, received: next.received + 1 };
2340
+ } else if (event.kind === "sent") {
2341
+ next = { ...next, sent: next.sent + 1 };
2342
+ } else if (event.kind === "closing") {
2343
+ next = { ...next, state: "closing" };
2344
+ } else if (event.kind === "closed") {
2345
+ next = { ...next, state: "closed" };
2346
+ } else if (event.kind === "retry") {
2347
+ next = {
2348
+ ...next,
2349
+ state: "waiting",
2350
+ attempt: event.attempt,
2351
+ errors: next.errors + 1,
2352
+ lastDelayMs: event.delayMs
2353
+ };
2354
+ } else if (event.kind === "error") {
2355
+ next = {
2356
+ ...next,
2357
+ state: "errored",
2358
+ attempt: event.attempt ?? next.attempt,
2359
+ errors: next.errors + 1
2360
+ };
2361
+ } else if (event.kind === "exhausted") {
2362
+ next = {
2363
+ ...next,
2364
+ state: "exhausted",
2365
+ attempt: event.attempt,
2366
+ errors: next.errors + 1
2367
+ };
2368
+ }
2369
+ }
2370
+ ctx.state.set(next);
2371
+ ctx.down([["DATA", next]]);
2372
+ },
2373
+ { name: `${name}/status`, factory: "webSocketSessionStatus" }
2374
+ );
2375
+ const errors = graph.node(
2376
+ [events],
2377
+ (ctx) => {
2378
+ for (const raw of depBatch(ctx, 0) ?? []) {
2379
+ const event = raw;
2380
+ if ("error" in event) ctx.down([["DATA", event.error]]);
2381
+ }
2382
+ },
2383
+ { name: `${name}/errors`, factory: "webSocketSessionErrors" }
2384
+ );
2385
+ const attempts = graph.node(
2386
+ [events],
2387
+ (ctx) => {
2388
+ for (const raw of depBatch(ctx, 0) ?? []) {
2389
+ const event = raw;
2390
+ if (event.kind === "attempt") ctx.down([["DATA", event.attempt]]);
2391
+ }
2392
+ },
2393
+ { name: `${name}/attempts`, factory: "webSocketSessionAttempts" }
2394
+ );
2395
+ return {
2396
+ command,
2397
+ inbound,
2398
+ lifecycle,
2399
+ outbound,
2400
+ status,
2401
+ errors,
2402
+ attempts,
2403
+ start: () => command.down([["DATA", { kind: "start" }]]),
2404
+ send: (message) => command.down([
2405
+ [
2406
+ "DATA",
2407
+ {
2408
+ kind: "send",
2409
+ message: typeof message === "string" || message instanceof Uint8Array ? { data: message } : message
2410
+ }
2411
+ ]
2412
+ ]),
2413
+ close: (code, reason) => command.down([["DATA", { kind: "close", code, reason }]])
2414
+ };
2415
+ }
2416
+ function webSocketSession(graph, request, opts = {}) {
2417
+ const name = opts.name ?? "webSocketSession";
2418
+ const policy = opts.retry ?? retryPolicy();
2419
+ const sendPolicy = normalizeWebSocketSessionSendPolicy(opts.sendPolicy);
2420
+ const command = graph.node([], null, {
2421
+ name: `${name}/command`,
2422
+ factory: "webSocketSessionCommand"
2423
+ });
2424
+ const events = webSocketSessionEventNode(graph, command, request, name, policy, sendPolicy);
2425
+ return webSocketSessionNodes(graph, command, events, name, policy);
2426
+ }
2427
+ function outboundNode(graph, source, name, send, opts) {
2428
+ const policy = opts.retry ?? retryPolicy();
2429
+ return graph.node(
2430
+ [assertSourceLocal(source)],
2431
+ (ctx) => {
2432
+ const state = initSendState(ctx);
2433
+ const start = (value, attempt) => {
2434
+ if (!state.active) return;
2435
+ const id = state.seq++;
2436
+ ctx.down([
2437
+ ["DATA", { kind: "attempt", value, attempt }]
2438
+ ]);
2439
+ const failTerminal = (error) => {
2440
+ const payload = errorPayload(error);
2441
+ ctx.down([
2442
+ [
2443
+ "DATA",
2444
+ { kind: "exhausted", value, attempt, error: payload }
2445
+ ]
2446
+ ]);
2447
+ ctx.down([["ERROR", payload]]);
2448
+ };
2449
+ let cancel;
2450
+ let done = false;
2451
+ try {
2452
+ cancel = send(ctx, value, (result) => {
2453
+ if (done || !state.active) return;
2454
+ done = true;
2455
+ state.cancels.delete(id);
2456
+ if (result.ok) {
2457
+ ctx.down([
2458
+ [
2459
+ "DATA",
2460
+ { kind: "sent", value, attempt, result: result.value }
2461
+ ]
2462
+ ]);
2463
+ return;
2464
+ }
2465
+ if (shouldRetry(policy, attempt)) {
2466
+ const nextAttempt = attempt + 1;
2467
+ const delayMs = nextRetryDelayMs(policy, nextAttempt) ?? 0;
2468
+ ctx.down([
2469
+ [
2470
+ "DATA",
2471
+ {
2472
+ kind: "retry",
2473
+ value,
2474
+ attempt,
2475
+ delayMs,
2476
+ error: errorPayload(result.error)
2477
+ }
2478
+ ]
2479
+ ]);
2480
+ const timer = setTimeout(() => {
2481
+ state.timers.delete(id);
2482
+ if (!state.active) return;
2483
+ start(value, nextAttempt);
2484
+ }, delayMs);
2485
+ state.timers.set(id, timer);
2486
+ } else {
2487
+ ctx.down([
2488
+ [
2489
+ "DATA",
2490
+ {
2491
+ kind: "exhausted",
2492
+ value,
2493
+ attempt,
2494
+ error: errorPayload(result.error)
2495
+ }
2496
+ ]
2497
+ ]);
2498
+ }
2499
+ });
2500
+ } catch (error) {
2501
+ if (!done) {
2502
+ done = true;
2503
+ state.cancels.delete(id);
2504
+ failTerminal(error);
2505
+ }
2506
+ return;
2507
+ }
2508
+ if (cancel === void 0) {
2509
+ if (!done) {
2510
+ done = true;
2511
+ failTerminal(`${name}: missing environment driver capability`);
2512
+ }
2513
+ return;
2514
+ }
2515
+ if (!done && state.active) {
2516
+ state.cancels.set(id, cancel);
2517
+ } else if (!state.active) {
2518
+ runCancel(cancel);
2519
+ }
2520
+ };
2521
+ for (const value of depBatch(ctx, 0) ?? []) start(value, 1);
2522
+ const terminal = ctx.terminal[0];
2523
+ if (terminal === true) {
2524
+ ctx.down([
2525
+ ["DATA", { kind: "upstream-complete" }]
2526
+ ]);
2527
+ } else if (terminal !== false && terminal !== void 0) {
2528
+ ctx.down([
2529
+ [
2530
+ "DATA",
2531
+ { kind: "upstream-error", error: terminal }
2532
+ ]
2533
+ ]);
2534
+ }
2535
+ },
2536
+ { name, factory: name }
2537
+ );
2538
+ }
2539
+ function toHttp(graph, source, requestOf, opts = {}) {
2540
+ const name = opts.name ?? "toHttp";
2541
+ const events = outboundNode(
2542
+ graph,
2543
+ source,
2544
+ name,
2545
+ (ctx, value, callback) => {
2546
+ const request = requestOf(value);
2547
+ return ctx.environment().httpDriver()?.request(request, callback);
2548
+ },
2549
+ opts
2550
+ );
2551
+ return outboundNodes(graph, events, name);
2552
+ }
2553
+ function toProcess(graph, source, commandOf, opts = {}) {
2554
+ const name = opts.name ?? "toProcess";
2555
+ const events = outboundNode(
2556
+ graph,
2557
+ source,
2558
+ name,
2559
+ (ctx, value, callback) => {
2560
+ const command = commandOf(value);
2561
+ return ctx.environment().processDriver()?.run(command, callback);
2562
+ },
2563
+ opts
2564
+ );
2565
+ return outboundNodes(graph, events, name);
2566
+ }
2567
+ function toWebSocket(graph, source, request, sendOf, opts = {}) {
2568
+ const name = opts.name ?? "toWebSocket";
2569
+ const events = outboundNode(
2570
+ graph,
2571
+ source,
2572
+ name,
2573
+ (ctx, value, callback) => {
2574
+ const driver = ctx.environment().webSocketDriver();
2575
+ return driver?.send?.(request, sendOf(value), callback);
2576
+ },
2577
+ opts
2578
+ );
2579
+ return outboundNodes(graph, events, name);
2580
+ }
2581
+
2582
+ // src/adapters/nestjs.ts
2583
+ var GRAPHREFLY_ROOT_GRAPH = /* @__PURE__ */ Symbol.for("graphrefly:root-graph");
2584
+ var GRAPHREFLY_MODULE_OPTIONS = /* @__PURE__ */ Symbol.for("graphrefly:module-options");
2585
+ var GRAPHREFLY_REQUEST_GRAPH = /* @__PURE__ */ Symbol.for("graphrefly:request-graph");
2586
+ var EVENT_HANDLERS = /* @__PURE__ */ new Map();
2587
+ var INTERVAL_HANDLERS = /* @__PURE__ */ new Map();
2588
+ var CRON_HANDLERS = /* @__PURE__ */ new Map();
2589
+ function getGraphToken(name) {
2590
+ return /* @__PURE__ */ Symbol.for(`graphrefly:graph:${name}`);
2591
+ }
2592
+ function getNodeToken(path) {
2593
+ return /* @__PURE__ */ Symbol.for(`graphrefly:node:${path}`);
2594
+ }
2595
+ function sameMeta(a, b) {
2596
+ const left = a;
2597
+ const right = b;
2598
+ const keys = Reflect.ownKeys(left);
2599
+ if (keys.length !== Reflect.ownKeys(right).length) return false;
2600
+ for (const key of keys) {
2601
+ if (!Object.is(left[key], right[key])) return false;
2602
+ }
2603
+ return true;
2604
+ }
2605
+ function pushUniqueMeta(registry, ctor, item) {
2606
+ const existing = registry.get(ctor) ?? [];
2607
+ if (existing.some((current) => sameMeta(current, item))) return;
2608
+ registry.set(ctor, [...existing, item]);
2609
+ }
2610
+ function registerMeta(registry, meta) {
2611
+ return ((targetOrValue, contextOrKey) => {
2612
+ if (typeof contextOrKey === "object" && contextOrKey !== null) {
2613
+ const methodKey = contextOrKey.name;
2614
+ contextOrKey.addInitializer(function() {
2615
+ const ctor2 = this.constructor;
2616
+ pushUniqueMeta(registry, ctor2, meta(methodKey));
2617
+ });
2618
+ return;
2619
+ }
2620
+ const ctor = targetOrValue.constructor;
2621
+ pushUniqueMeta(registry, ctor, meta(contextOrKey));
2622
+ });
2623
+ }
2624
+ function OnGraphEvent(nodeName) {
2625
+ return registerMeta(EVENT_HANDLERS, (methodKey) => ({ nodeName, methodKey }));
2626
+ }
2627
+ function GraphInterval(ms) {
2628
+ return registerMeta(INTERVAL_HANDLERS, (methodKey) => ({ ms, methodKey }));
2629
+ }
2630
+ function GraphCron(expr) {
2631
+ return registerMeta(CRON_HANDLERS, (methodKey) => ({ expr, methodKey }));
2632
+ }
2633
+
2634
+ // src/adapters/store.ts
2635
+ function nodeSnapshot(node) {
2636
+ return node.cache;
2637
+ }
2638
+ function subscribeNodeValues(node, run, opts = {}) {
2639
+ const read = opts.getSnapshot ?? (() => nodeSnapshot(node));
2640
+ if (opts.immediate) run(read());
2641
+ let subscribing = true;
2642
+ const skipSynchronousHandshakeData = opts.changesOnly || opts.immediate;
2643
+ const sink = (msg, delivery) => {
2644
+ switch (msg[0]) {
2645
+ case "DATA":
2646
+ if (skipSynchronousHandshakeData && subscribing && delivery === void 0) {
2647
+ return;
2648
+ }
2649
+ run(msg[1]);
2650
+ return;
2651
+ case "ERROR":
2652
+ opts.onError?.(msg[1]);
2653
+ return;
2654
+ case "COMPLETE":
2655
+ opts.onComplete?.();
2656
+ return;
2657
+ }
2658
+ };
2659
+ const unsubscribe = node.subscribe(sink);
2660
+ subscribing = false;
2661
+ return unsubscribe;
2662
+ }
2663
+ function readableStore(node, opts = {}) {
2664
+ return {
2665
+ get: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),
2666
+ subscribe: (run) => subscribeNodeValues(node, run, { immediate: true, ...opts })
2667
+ };
2668
+ }
2669
+ function hasWritableSet(node) {
2670
+ return typeof node.set === "function";
2671
+ }
2672
+ function defaultWrite(node, value) {
2673
+ node.set(value);
2674
+ }
2675
+ function writableStore(node, opts = {}) {
2676
+ const read = opts.getSnapshot ?? (() => nodeSnapshot(node));
2677
+ const write = opts.write ?? (hasWritableSet(node) ? defaultWrite : void 0);
2678
+ if (!write) {
2679
+ throw new TypeError("writableStore: node must expose set(value) or opts.write");
2680
+ }
2681
+ const writable = node;
2682
+ return {
2683
+ get: read,
2684
+ subscribe: (run) => subscribeNodeValues(node, run, { immediate: true, ...opts }),
2685
+ set: (value) => write(writable, value),
2686
+ update: (fn) => write(writable, fn(read()))
2687
+ };
2688
+ }
2689
+ function externalStore(node, opts = {}) {
2690
+ const read = opts.getSnapshot ?? (() => nodeSnapshot(node));
2691
+ return {
2692
+ getSnapshot: read,
2693
+ getServerSnapshot: read,
2694
+ subscribe: (onStoreChange) => subscribeNodeValues(node, () => onStoreChange(), {
2695
+ changesOnly: true,
2696
+ onError: opts.onError,
2697
+ onComplete: opts.onComplete
2698
+ })
2699
+ };
2700
+ }
2701
+ var reactExternalStore = externalStore;
2702
+ var svelteReadableStore = readableStore;
2703
+ var svelteWritableStore = writableStore;
2704
+ function recordReadableStore(keysNode, factory, opts = {}) {
2705
+ const read = () => {
2706
+ const keys = keysNode.cache ?? [];
2707
+ const out = {};
2708
+ for (const key of keys) {
2709
+ const nodes = factory(key);
2710
+ const values = {};
2711
+ for (const field of Object.keys(nodes)) {
2712
+ values[field] = nodes[field].cache;
2713
+ }
2714
+ out[key] = values;
2715
+ }
2716
+ return out;
2717
+ };
2718
+ return {
2719
+ get: read,
2720
+ subscribe(run) {
2721
+ const entryUnsubs = [];
2722
+ const cleanupEntries = () => {
2723
+ for (const unsub of entryUnsubs.splice(0)) unsub();
2724
+ };
2725
+ const sync = () => {
2726
+ cleanupEntries();
2727
+ for (const key of keysNode.cache ?? []) {
2728
+ const nodes = factory(key);
2729
+ for (const field of Object.keys(nodes)) {
2730
+ entryUnsubs.push(
2731
+ subscribeNodeValues(nodes[field], () => run(read()), {
2732
+ changesOnly: true,
2733
+ onError: opts.onError,
2734
+ onComplete: opts.onComplete
2735
+ })
2736
+ );
2737
+ }
2738
+ }
2739
+ run(read());
2740
+ };
2741
+ const keysUnsub = subscribeNodeValues(keysNode, sync, {
2742
+ changesOnly: true,
2743
+ onError: opts.onError,
2744
+ onComplete: opts.onComplete
2745
+ });
2746
+ sync();
2747
+ return () => {
2748
+ keysUnsub();
2749
+ cleanupEntries();
2750
+ };
2751
+ }
2752
+ };
2753
+ }
2754
+ function zustandStore(node, initialState = nodeSnapshot(node), opts = {}) {
2755
+ const listeners = /* @__PURE__ */ new Set();
2756
+ const read = opts.getSnapshot ?? (() => nodeSnapshot(node));
2757
+ const write = opts.write ?? (hasWritableSet(node) ? defaultWrite : void 0);
2758
+ if (!write) {
2759
+ throw new TypeError("zustandStore: node must expose set(value) or opts.write");
2760
+ }
2761
+ const writable = node;
2762
+ const api = {
2763
+ getState: () => read(),
2764
+ setState(partial, replace) {
2765
+ const prev = api.getState();
2766
+ const next = typeof partial === "function" ? partial(prev) : partial;
2767
+ write(writable, replace ? next : { ...prev, ...next });
2768
+ },
2769
+ getInitialState: () => initialState,
2770
+ subscribe(listener) {
2771
+ let prev = api.getState();
2772
+ const unsub = subscribeNodeValues(
2773
+ node,
2774
+ (value) => {
2775
+ const next = value;
2776
+ listener(next, prev);
2777
+ prev = next;
2778
+ },
2779
+ { changesOnly: true, onError: opts.onError, onComplete: opts.onComplete }
2780
+ );
2781
+ listeners.add(unsub);
2782
+ return () => {
2783
+ if (!listeners.delete(unsub)) return;
2784
+ unsub();
2785
+ };
2786
+ },
2787
+ destroy() {
2788
+ for (const unsub of [...listeners]) {
2789
+ listeners.delete(unsub);
2790
+ unsub();
2791
+ }
2792
+ }
2793
+ };
2794
+ return api;
2795
+ }
2796
+ function jotaiAtom(node, opts = {}) {
2797
+ const base = {
2798
+ get: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),
2799
+ subscribe: (callback) => subscribeNodeValues(node, callback, { changesOnly: true, ...opts }),
2800
+ _node: node
2801
+ };
2802
+ if (hasWritableSet(node) || typeof opts.write === "function") {
2803
+ const writable = writableStore(
2804
+ node,
2805
+ opts
2806
+ );
2807
+ return { ...base, set: writable.set, update: writable.update };
2808
+ }
2809
+ return base;
2810
+ }
2811
+ function nanoAtom(node, opts = {}) {
2812
+ const base = {
2813
+ get: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),
2814
+ subscribe: (callback) => subscribeNodeValues(node, callback, { immediate: true, ...opts }),
2815
+ listen: (callback) => subscribeNodeValues(node, callback, { changesOnly: true, ...opts }),
2816
+ _node: node
2817
+ };
2818
+ if (hasWritableSet(node) || typeof opts.write === "function") {
2819
+ const writable = writableStore(
2820
+ node,
2821
+ opts
2822
+ );
2823
+ return { ...base, set: writable.set, update: writable.update };
2824
+ }
2825
+ return base;
2826
+ }
2827
+ function signalFromNode(node, opts = {}) {
2828
+ const base = {
2829
+ get: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),
2830
+ subscribe: (callback) => subscribeNodeValues(node, callback, { changesOnly: true, ...opts }),
2831
+ _node: node
2832
+ };
2833
+ if (hasWritableSet(node) || typeof opts.write === "function") {
2834
+ const writable = writableStore(
2835
+ node,
2836
+ opts
2837
+ );
2838
+ return { ...base, set: writable.set, update: writable.update };
2839
+ }
2840
+ return base;
2841
+ }
2842
+ export {
2843
+ AGENTIC_MEMORY_RECORD_CHANGE_FORMAT,
2844
+ AGENTIC_MEMORY_RECORD_SNAPSHOT_FORMAT,
2845
+ AGENTIC_MEMORY_RECORD_STORAGE_FRAME_VERSION,
2846
+ CRON_HANDLERS,
2847
+ EVENT_HANDLERS,
2848
+ GRAPHREFLY_MODULE_OPTIONS,
2849
+ GRAPHREFLY_REQUEST_GRAPH,
2850
+ GRAPHREFLY_ROOT_GRAPH,
2851
+ GraphCron,
2852
+ GraphInterval,
2853
+ INTERVAL_HANDLERS,
2854
+ OnGraphEvent,
2855
+ agenticMemoryRecordChangeFrame,
2856
+ agenticMemoryRecordSnapshotFrame,
2857
+ agenticMemoryRecordsSnapshotKey,
2858
+ assertAgenticMemoryRecordChangeFrame,
2859
+ assertAgenticMemoryRecordSnapshotFrame,
2860
+ externalStore,
2861
+ getGraphToken,
2862
+ getNodeToken,
2863
+ jotaiAtom,
2864
+ loadAgenticMemoryRecordsState,
2865
+ nanoAtom,
2866
+ nodeSnapshot,
2867
+ openPersistentAgenticMemoryRecords,
2868
+ openPersistentReactiveIndex,
2869
+ openPersistentReactiveList,
2870
+ openPersistentReactiveLog,
2871
+ openPersistentReactiveMap,
2872
+ persistAgenticMemoryRecords,
2873
+ persistReactiveCollection,
2874
+ reactExternalStore,
2875
+ readableStore,
2876
+ recordReadableStore,
2877
+ remoteCall,
2878
+ remoteResponder,
2879
+ remoteResponderHandler,
2880
+ signalFromNode,
2881
+ subscribeNodeValues,
2882
+ svelteReadableStore,
2883
+ svelteWritableStore,
2884
+ toHttp,
2885
+ toProcess,
2886
+ toWebSocket,
2887
+ webSocketSession,
2888
+ wireBridge,
2889
+ wireBridgeEnvelope,
2890
+ wireBridgeIdempotencyKey,
2891
+ writableStore,
2892
+ zustandStore
2893
+ };
2894
+ //# sourceMappingURL=index.js.map