@lunora/client 1.0.0-alpha.21 → 1.0.0-alpha.23

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 (32) hide show
  1. package/dist/auth/index.d.mts +1 -1
  2. package/dist/auth/index.d.ts +1 -1
  3. package/dist/index.d.mts +249 -4
  4. package/dist/index.d.ts +249 -4
  5. package/dist/index.mjs +10 -4
  6. package/dist/packem_shared/ClientServiceWorker-C3PAFwy0.mjs +100 -0
  7. package/dist/packem_shared/{LunoraClient-kXpHNyaE.mjs → LunoraClient-BBCQjjbl.mjs} +382 -243
  8. package/dist/packem_shared/{OfflineQueue-GGYJRmhF.mjs → OfflineQueue-B4HUF7rt.mjs} +1 -1
  9. package/dist/packem_shared/SubscriptionRegistry-CxS_Inha.mjs +31 -0
  10. package/dist/packem_shared/TabCoordinator-BwRR8H06.mjs +222 -0
  11. package/dist/packem_shared/createClientQuery-CQ51bWAE.mjs +71 -0
  12. package/dist/packem_shared/createLocalStore-BtqUmOQA.mjs +2 -0
  13. package/dist/packem_shared/createReply-lI4tVS2w.mjs +36 -0
  14. package/dist/packem_shared/{createServerClient-DF-3mLmb.mjs → createServerClient-CTTAmvMx.mjs} +1 -1
  15. package/dist/packem_shared/createSnapshotPrecondition-CxQ1T4ZP.mjs +18 -0
  16. package/dist/packem_shared/httpStream-BJU-aflc.mjs +159 -0
  17. package/dist/packem_shared/{local-store-BveBeFEo.mjs → local-store-DIq-UWfD.mjs} +1 -1
  18. package/dist/packem_shared/{lunora-client.d-BYkEjCEJ.d.mts → lunora-client.d-JvtVpf8A.d.mts} +302 -18
  19. package/dist/packem_shared/{lunora-client.d-BYkEjCEJ.d.ts → lunora-client.d-JvtVpf8A.d.ts} +302 -18
  20. package/dist/packem_shared/{offline-queue-B9vfdSqp.mjs → offline-queue-CF4_Co5k.mjs} +29 -0
  21. package/dist/packem_shared/{preload.d-B-vyHnml.d.ts → preload.d-C4_d_l5v.d.ts} +1 -1
  22. package/dist/packem_shared/{preload.d-DrfuisCE.d.mts → preload.d-DKbjGN5O.d.mts} +1 -1
  23. package/dist/packem_shared/wire-key-Djie6aaR.mjs +266 -0
  24. package/dist/query/index.d.mts +2 -2
  25. package/dist/query/index.d.ts +2 -2
  26. package/dist/ssr/index.d.mts +3 -3
  27. package/dist/ssr/index.d.ts +3 -3
  28. package/dist/ssr/index.mjs +1 -1
  29. package/package.json +2 -2
  30. package/dist/packem_shared/SubscriptionRegistry-DjGKZsqq.mjs +0 -1
  31. package/dist/packem_shared/createLocalStore-jRoqmazl.mjs +0 -2
  32. package/dist/packem_shared/subscription-BjynOXCU.mjs +0 -68
@@ -1 +1 @@
1
- export { O as OfflineQueue, n as nextId, r as reportPersistenceError } from './offline-queue-B9vfdSqp.mjs';
1
+ export { O as OfflineQueue, n as nextId, r as reportPersistenceError } from './offline-queue-CF4_Co5k.mjs';
@@ -0,0 +1,31 @@
1
+ import { s as stableWireKey } from './wire-key-Djie6aaR.mjs';
2
+
3
+ class SubscriptionRegistry {
4
+ static key(functionPath, args, shardKey) {
5
+ return `${functionPath}::${stableWireKey(args)}::${shardKey ?? ""}`;
6
+ }
7
+ byKey = /* @__PURE__ */ new Map();
8
+ byId = /* @__PURE__ */ new Map();
9
+ get(key) {
10
+ return this.byKey.get(key);
11
+ }
12
+ getById(id) {
13
+ return this.byId.get(id);
14
+ }
15
+ add(state) {
16
+ this.byKey.set(SubscriptionRegistry.key(state.fn.__lunoraRef, state.args, state.shardKey), state);
17
+ this.byId.set(state.id, state);
18
+ }
19
+ remove(state) {
20
+ const key = SubscriptionRegistry.key(state.fn.__lunoraRef, state.args, state.shardKey);
21
+ if (this.byKey.get(key) === state) {
22
+ this.byKey.delete(key);
23
+ }
24
+ this.byId.delete(state.id);
25
+ }
26
+ all() {
27
+ return [...this.byKey.values()];
28
+ }
29
+ }
30
+
31
+ export { SubscriptionRegistry };
@@ -0,0 +1,222 @@
1
+ let nextTabId = 0;
2
+ const DEFAULT_CHANNEL = "lunora-bridge";
3
+ const DEFAULT_HEARTBEAT_MS = 1e3;
4
+ const DEFAULT_LEADER_TIMEOUT_MS = 3e3;
5
+ class TabCoordinator {
6
+ bc;
7
+ tabId;
8
+ heartbeatInterval;
9
+ leaderTimeout;
10
+ /** The tab id of the current known leader, or `undefined` if no leader. */
11
+ knownLeader = void 0;
12
+ /** `true` when this tab believes it is the leader. */
13
+ leader = false;
14
+ /** `true` once `start()` has been called. */
15
+ running = false;
16
+ /** Timestamp of the most recent leader heartbeat. */
17
+ lastHeartbeat = 0;
18
+ heartbeatTimer = void 0;
19
+ leaderCheckTimer = void 0;
20
+ /** Callbacks set via constructor options. */
21
+ onBecomeLeader;
22
+ onStopBeingLeader;
23
+ onSubscriptionData;
24
+ onSubscriptionError;
25
+ constructor(options = {}) {
26
+ nextTabId += 1;
27
+ this.tabId = `tab_${String(nextTabId)}_${crypto.randomUUID()}`;
28
+ this.heartbeatInterval = options.heartbeatInterval ?? DEFAULT_HEARTBEAT_MS;
29
+ this.leaderTimeout = options.leaderTimeout ?? DEFAULT_LEADER_TIMEOUT_MS;
30
+ this.onBecomeLeader = options.onBecomeLeader;
31
+ this.onStopBeingLeader = options.onStopBeingLeader;
32
+ this.onSubscriptionData = options.onSubscriptionData;
33
+ this.onSubscriptionError = options.onSubscriptionError;
34
+ if (typeof BroadcastChannel === "undefined") {
35
+ this.bc = void 0;
36
+ return;
37
+ }
38
+ this.bc = new BroadcastChannel(options.channelName ?? DEFAULT_CHANNEL);
39
+ this.bc.addEventListener("message", (event) => {
40
+ this.handleMessage(event.data);
41
+ });
42
+ }
43
+ // -----------------------------------------------------------------------
44
+ // Public API
45
+ // -----------------------------------------------------------------------
46
+ /**
47
+ * Start the coordinator: attempt to claim leadership and begin the
48
+ * heartbeat/leader-check cycle. Safe to call multiple times.
49
+ */
50
+ start() {
51
+ if (this.running) {
52
+ return;
53
+ }
54
+ this.running = true;
55
+ if (this.bc === void 0) {
56
+ this.becomeLeader();
57
+ return;
58
+ }
59
+ this.broadcast({ type: "claim-leadership", tabId: this.tabId, ts: Date.now() });
60
+ setTimeout(() => {
61
+ if (!this.running) {
62
+ return;
63
+ }
64
+ if (this.knownLeader === void 0) {
65
+ this.becomeLeader();
66
+ }
67
+ }, this.leaderTimeout);
68
+ this.leaderCheckTimer = setInterval(() => {
69
+ this.checkLeaderHealth();
70
+ }, this.leaderTimeout);
71
+ this.heartbeatTimer = setInterval(() => {
72
+ this.sendHeartbeat();
73
+ }, this.heartbeatInterval);
74
+ }
75
+ /**
76
+ * Stop the coordinator: yield leadership (if held), close the channel, and
77
+ * clear all timers. Safe to call multiple times.
78
+ */
79
+ stop() {
80
+ this.running = false;
81
+ if (this.leader) {
82
+ this.broadcast({ type: "yield-leadership", tabId: this.tabId });
83
+ this.leader = false;
84
+ this.knownLeader = void 0;
85
+ this.onStopBeingLeader?.();
86
+ }
87
+ if (this.heartbeatTimer !== void 0) {
88
+ clearInterval(this.heartbeatTimer);
89
+ this.heartbeatTimer = void 0;
90
+ }
91
+ if (this.leaderCheckTimer !== void 0) {
92
+ clearInterval(this.leaderCheckTimer);
93
+ this.leaderCheckTimer = void 0;
94
+ }
95
+ this.bc?.close();
96
+ }
97
+ /** `true` when this tab is the current WebSocket leader. */
98
+ isLeader() {
99
+ return this.leader;
100
+ }
101
+ /** The tab id of the current leader, or `undefined` if unknown / no leader. */
102
+ get leaderTabId() {
103
+ return this.knownLeader;
104
+ }
105
+ /** The id of this tab. */
106
+ get id() {
107
+ return this.tabId;
108
+ }
109
+ /** `true` when the coordinator has been started and is not yet stopped. */
110
+ get isRunning() {
111
+ return this.running;
112
+ }
113
+ // -----------------------------------------------------------------------
114
+ // Broadcasting
115
+ // -----------------------------------------------------------------------
116
+ /**
117
+ * Broadcast subscription data to all follower tabs. Only the leader should
118
+ * call this.
119
+ */
120
+ broadcastSubscriptionData(key, data) {
121
+ if (!this.leader) {
122
+ return;
123
+ }
124
+ this.broadcast({ type: "subscription-data", tabId: this.tabId, key, data });
125
+ }
126
+ /**
127
+ * Broadcast a subscription error to all follower tabs. Only the leader
128
+ * should call this.
129
+ */
130
+ broadcastSubscriptionError(key, error) {
131
+ if (!this.leader) {
132
+ return;
133
+ }
134
+ this.broadcast({ type: "subscription-error", tabId: this.tabId, key, error });
135
+ }
136
+ // -----------------------------------------------------------------------
137
+ // Internal
138
+ // -----------------------------------------------------------------------
139
+ broadcast(message) {
140
+ this.bc?.postMessage(message);
141
+ }
142
+ handleMessage(message) {
143
+ switch (message.type) {
144
+ case "claim-leadership": {
145
+ if (message.tabId === this.tabId) {
146
+ break;
147
+ }
148
+ if (this.leader) {
149
+ this.broadcast({ type: "heartbeat", tabId: this.tabId, ts: Date.now() });
150
+ break;
151
+ }
152
+ if (this.knownLeader === void 0 && message.tabId < this.tabId) {
153
+ this.knownLeader = message.tabId;
154
+ }
155
+ break;
156
+ }
157
+ case "heartbeat": {
158
+ this.lastHeartbeat = message.ts;
159
+ this.knownLeader = message.tabId;
160
+ break;
161
+ }
162
+ case "subscription-data": {
163
+ if (this.leader || message.tabId === this.tabId) {
164
+ break;
165
+ }
166
+ this.onSubscriptionData?.(message.key, message.data);
167
+ break;
168
+ }
169
+ case "subscription-error": {
170
+ if (this.leader || message.tabId === this.tabId) {
171
+ break;
172
+ }
173
+ this.onSubscriptionError?.(message.key, message.error);
174
+ break;
175
+ }
176
+ case "yield-leadership": {
177
+ if (this.knownLeader === message.tabId) {
178
+ this.knownLeader = void 0;
179
+ }
180
+ break;
181
+ }
182
+ }
183
+ }
184
+ becomeLeader() {
185
+ if (this.leader) {
186
+ return;
187
+ }
188
+ this.leader = true;
189
+ this.knownLeader = this.tabId;
190
+ this.lastHeartbeat = Date.now();
191
+ this.onBecomeLeader?.();
192
+ this.broadcast({ type: "heartbeat", tabId: this.tabId, ts: Date.now() });
193
+ }
194
+ sendHeartbeat() {
195
+ if (!this.leader) {
196
+ return;
197
+ }
198
+ this.broadcast({ type: "heartbeat", tabId: this.tabId, ts: Date.now() });
199
+ }
200
+ checkLeaderHealth() {
201
+ if (!this.running) {
202
+ return;
203
+ }
204
+ if (this.leader) {
205
+ return;
206
+ }
207
+ if (this.knownLeader !== void 0) {
208
+ const elapsed = Date.now() - this.lastHeartbeat;
209
+ if (elapsed > this.leaderTimeout) {
210
+ this.knownLeader = void 0;
211
+ this.broadcast({ type: "claim-leadership", tabId: this.tabId, ts: Date.now() });
212
+ setTimeout(() => {
213
+ if (this.running && this.knownLeader === void 0) {
214
+ this.becomeLeader();
215
+ }
216
+ }, this.leaderTimeout);
217
+ }
218
+ }
219
+ }
220
+ }
221
+
222
+ export { TabCoordinator };
@@ -0,0 +1,71 @@
1
+ class ClientQueryStore {
2
+ /** Current values, keyed by the ref's stable key. Absent = never set. */
3
+ values = /* @__PURE__ */ new Map();
4
+ /** Subscribers keyed by ref key — notified on every set. */
5
+ subscribers = /* @__PURE__ */ new Map();
6
+ /**
7
+ * Return the current value for `ref`, or `ref.defaultValue` if none has
8
+ * been set explicitly. Returns `ref.defaultValue` when the slot has been
9
+ * set to `undefined` (which is distinct from "never set").
10
+ */
11
+ get(ref) {
12
+ if (this.values.has(ref.key)) {
13
+ return this.values.get(ref.key);
14
+ }
15
+ return ref.defaultValue;
16
+ }
17
+ /**
18
+ * Set a new value for `ref` and notify every subscriber. Pass `undefined`
19
+ * to reset the slot to `ref.defaultValue`.
20
+ */
21
+ set(ref, value) {
22
+ this.values.set(ref.key, value);
23
+ this.notify(ref.key);
24
+ }
25
+ /**
26
+ * Delete the stored value for `ref`, resetting to `ref.defaultValue` and
27
+ * notifying subscribers.
28
+ */
29
+ reset(ref) {
30
+ this.values.delete(ref.key);
31
+ this.notify(ref.key);
32
+ }
33
+ /**
34
+ * Subscribe to changes for `ref`. The callback is NOT invoked on
35
+ * registration — callers should read the current value via
36
+ * {@link get} first. Returns an unsubscribe function.
37
+ */
38
+ subscribe(ref, callback) {
39
+ let subs = this.subscribers.get(ref.key);
40
+ if (!subs) {
41
+ subs = /* @__PURE__ */ new Set();
42
+ this.subscribers.set(ref.key, subs);
43
+ }
44
+ subs.add(callback);
45
+ return () => {
46
+ subs.delete(callback);
47
+ if (subs.size === 0) {
48
+ this.subscribers.delete(ref.key);
49
+ }
50
+ };
51
+ }
52
+ /** Notify every subscriber of a value change for the given key. */
53
+ notify(key) {
54
+ const subs = this.subscribers.get(key);
55
+ if (!subs) {
56
+ return;
57
+ }
58
+ const value = this.values.get(key);
59
+ for (const callback of subs) {
60
+ try {
61
+ callback(value);
62
+ } catch {
63
+ }
64
+ }
65
+ }
66
+ }
67
+ const createClientQuery = (key, defaultValue) => {
68
+ return { defaultValue, key };
69
+ };
70
+
71
+ export { ClientQueryStore, createClientQuery };
@@ -0,0 +1,2 @@
1
+ export { c as createLocalStore } from './local-store-DIq-UWfD.mjs';
2
+ import './SubscriptionRegistry-CxS_Inha.mjs';
@@ -0,0 +1,36 @@
1
+ const sendToSw = (sw, message, expectResponse = false) => new Promise((resolve, reject) => {
2
+ if (!sw) {
3
+ reject(new Error("No active service worker"));
4
+ return;
5
+ }
6
+ const id = message.correlationId ?? crypto.randomUUID();
7
+ const outgoingMessage = { ...message, correlationId: id };
8
+ if (expectResponse) {
9
+ let timer;
10
+ const handler = (event) => {
11
+ if (event.data.correlationId === id) {
12
+ clearTimeout(timer);
13
+ navigator.serviceWorker.removeEventListener("message", handler);
14
+ resolve(event.data.payload);
15
+ }
16
+ };
17
+ timer = setTimeout(() => {
18
+ navigator.serviceWorker.removeEventListener("message", handler);
19
+ reject(new Error(`SW message ${id} timed out`));
20
+ }, 3e4);
21
+ navigator.serviceWorker.addEventListener("message", handler);
22
+ sw.postMessage(outgoingMessage);
23
+ } else {
24
+ sw.postMessage(outgoingMessage);
25
+ resolve(void 0);
26
+ }
27
+ });
28
+ const createReply = (original, payload) => {
29
+ return {
30
+ type: `${original.type}:reply`,
31
+ payload,
32
+ correlationId: original.correlationId
33
+ };
34
+ };
35
+
36
+ export { createReply, sendToSw };
@@ -1,4 +1,4 @@
1
- import { LunoraClient } from './LunoraClient-kXpHNyaE.mjs';
1
+ import { LunoraClient } from './LunoraClient-BBCQjjbl.mjs';
2
2
 
3
3
  const createServerClient = (options) => {
4
4
  const client = new LunoraClient({ fetch: options.fetch, url: options.url });
@@ -0,0 +1,18 @@
1
+ import { s as stableWireKey } from './wire-key-Djie6aaR.mjs';
2
+
3
+ const createSnapshotPrecondition = (client, functionRef, args, shardKey) => {
4
+ const snapshot = client.peekActiveQueryValue(functionRef.__lunoraRef, args, shardKey);
5
+ const snapshotKey = snapshot === void 0 ? void 0 : stableWireKey(snapshot);
6
+ return () => {
7
+ const current = client.peekActiveQueryValue(functionRef.__lunoraRef, args, shardKey);
8
+ if (snapshotKey === void 0 && current === void 0) {
9
+ return true;
10
+ }
11
+ if (snapshotKey === void 0 || current === void 0) {
12
+ return false;
13
+ }
14
+ return stableWireKey(current) === snapshotKey;
15
+ };
16
+ };
17
+
18
+ export { createSnapshotPrecondition as default };
@@ -0,0 +1,159 @@
1
+ import { LunoraError } from '@lunora/errors';
2
+ import { createStream } from './DEFAULT_MAX_BUFFER-7hFnzNk9.mjs';
3
+
4
+ const SSE_FIELD_SPACE_RE = /^ /u;
5
+ const parameterToString = (value) => typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
6
+ const parseSseFrame = (raw) => {
7
+ let event = "";
8
+ const dataLines = [];
9
+ for (const line of raw.split("\n")) {
10
+ if (line.startsWith("event:")) {
11
+ event = line.slice("event:".length).replace(SSE_FIELD_SPACE_RE, "");
12
+ } else if (line.startsWith("data:")) {
13
+ dataLines.push(line.slice("data:".length).replace(SSE_FIELD_SPACE_RE, ""));
14
+ }
15
+ }
16
+ return { data: dataLines.join("\n"), event };
17
+ };
18
+ const buildHttpStreamUrl = (route, args, baseUrl) => {
19
+ const parameters = args.params ?? {};
20
+ const path = route.path.split("/").map((segment) => {
21
+ if (!segment.startsWith(":")) {
22
+ return segment;
23
+ }
24
+ const name = segment.slice(1);
25
+ const value = parameters[name];
26
+ if (value === void 0) {
27
+ throw new LunoraError("HTTP_STREAM_MISSING_PARAM", `httpStream: missing path param ":${name}" for route ${route.path}`);
28
+ }
29
+ return encodeURIComponent(parameterToString(value));
30
+ }).join("/");
31
+ const search = new URLSearchParams();
32
+ for (const [key, value] of Object.entries(args.searchParams ?? {})) {
33
+ if (value !== void 0) {
34
+ search.set(key, parameterToString(value));
35
+ }
36
+ }
37
+ const query = search.toString();
38
+ const trimmedBase = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
39
+ return `${trimmedBase}${path}${query === "" ? "" : `?${query}`}`;
40
+ };
41
+ const handleSseFrame = (frame, handle) => {
42
+ if (frame.event === "complete") {
43
+ handle.complete();
44
+ return true;
45
+ }
46
+ if (frame.event === "error") {
47
+ let payload = {};
48
+ try {
49
+ payload = JSON.parse(frame.data);
50
+ } catch {
51
+ }
52
+ const message = typeof payload.message === "string" ? payload.message : "stream error";
53
+ const code = typeof payload.code === "string" ? payload.code : "HTTP_STREAM_ERROR";
54
+ handle.fail(new LunoraError(code, message));
55
+ return true;
56
+ }
57
+ if ((frame.event === "" || frame.event === "message") && frame.data !== "") {
58
+ try {
59
+ handle.push(JSON.parse(frame.data));
60
+ } catch {
61
+ handle.fail(new LunoraError("HTTP_STREAM_BAD_CHUNK", "httpStream: malformed SSE chunk (invalid JSON)"));
62
+ return true;
63
+ }
64
+ }
65
+ return false;
66
+ };
67
+ const pumpSseBody = async (body, handle) => {
68
+ const reader = body.getReader();
69
+ const decoder = new TextDecoder();
70
+ let buffer = "";
71
+ const drainFrames = () => {
72
+ let separatorIndex = buffer.indexOf("\n\n");
73
+ while (separatorIndex !== -1) {
74
+ const frame = parseSseFrame(buffer.slice(0, separatorIndex));
75
+ buffer = buffer.slice(separatorIndex + 2);
76
+ if (handleSseFrame(frame, handle)) {
77
+ return true;
78
+ }
79
+ separatorIndex = buffer.indexOf("\n\n");
80
+ }
81
+ return false;
82
+ };
83
+ for (; ; ) {
84
+ const { done, value } = await reader.read();
85
+ if (done) {
86
+ break;
87
+ }
88
+ buffer += decoder.decode(value, { stream: true }).replaceAll("\r\n", "\n");
89
+ if (drainFrames()) {
90
+ await reader.cancel().catch(() => {
91
+ });
92
+ return;
93
+ }
94
+ }
95
+ buffer += decoder.decode().replaceAll("\r\n", "\n");
96
+ if (!drainFrames()) {
97
+ handle.fail(new LunoraError("HTTP_STREAM_INTERRUPTED", "httpStream: stream ended without a complete frame"));
98
+ }
99
+ };
100
+ const httpStream = (route, args, options = {}) => {
101
+ const fetchImpl = options.fetch ?? (typeof fetch === "function" ? fetch.bind(globalThis) : void 0);
102
+ if (!fetchImpl) {
103
+ throw new LunoraError("INTERNAL", "httpStream: no `fetch` implementation available");
104
+ }
105
+ const url = buildHttpStreamUrl(route, args ?? {}, options.baseUrl ?? "");
106
+ const ac = new AbortController();
107
+ if (options.signal) {
108
+ if (options.signal.aborted) {
109
+ ac.abort();
110
+ } else {
111
+ options.signal.addEventListener(
112
+ "abort",
113
+ () => {
114
+ ac.abort();
115
+ },
116
+ { once: true }
117
+ );
118
+ }
119
+ }
120
+ const { handle, iterable } = createStream({
121
+ maxBuffer: options.maxBuffer,
122
+ onCancel: () => {
123
+ ac.abort();
124
+ }
125
+ });
126
+ (async () => {
127
+ const response = await fetchImpl(url, {
128
+ headers: { accept: "text/event-stream", ...options.headers },
129
+ method: route.method,
130
+ signal: ac.signal
131
+ });
132
+ if (!response.ok) {
133
+ handle.fail(
134
+ new LunoraError("HTTP_STREAM_STATUS", `httpStream: request failed (status ${response.status.toString()})`, {
135
+ status: response.status
136
+ })
137
+ );
138
+ return;
139
+ }
140
+ if (!response.body) {
141
+ handle.fail(new LunoraError("HTTP_STREAM_NO_BODY", "httpStream: response has no body"));
142
+ return;
143
+ }
144
+ await pumpSseBody(response.body, handle);
145
+ })().catch((error) => {
146
+ if (ac.signal.aborted) {
147
+ handle.complete();
148
+ return;
149
+ }
150
+ if (error instanceof Error && "code" in error) {
151
+ handle.fail(error);
152
+ return;
153
+ }
154
+ handle.fail(new LunoraError("HTTP_STREAM_TRANSPORT", error instanceof Error ? error.message : String(error), { cause: error }));
155
+ });
156
+ return iterable;
157
+ };
158
+
159
+ export { httpStream };
@@ -1,4 +1,4 @@
1
- import { S as SubscriptionRegistry } from './subscription-BjynOXCU.mjs';
1
+ import { SubscriptionRegistry } from './SubscriptionRegistry-CxS_Inha.mjs';
2
2
 
3
3
  const foldOptimistic = (base, layers) => {
4
4
  let value = base;