supabase-edge-function-continuous-stream 1.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.
@@ -0,0 +1,75 @@
1
+ type EdgeFunctionRawMessage = Record<string, unknown> & {
2
+ type: string;
3
+ };
4
+ interface EdgeFunctionMessageContext<TResponse extends Record<string, unknown>> {
5
+ resolve: (value: TResponse) => void;
6
+ reject: (reason: Error) => void;
7
+ closeSocket: () => void;
8
+ clearOverallTimeout: () => void;
9
+ isResolved: () => boolean;
10
+ }
11
+ type EdgeStreamConfig = {
12
+ functionPath: string;
13
+ };
14
+ /** Callbacks a caller can wire up for side-effects during streaming. */
15
+ interface StandardAiCallbacks {
16
+ onServerAction?: (type: string, data: unknown) => void;
17
+ toUserMessage?: (error: unknown) => string | null;
18
+ }
19
+ type WarmupOptions = {
20
+ onServerAction?: (type: string, data: unknown) => void;
21
+ };
22
+ type StartStreamOptions<TResponse extends Record<string, unknown>> = {
23
+ /** Optional: Use a custom message handler. If omitted, it uses the Standard AI Protocol handler. */
24
+ onMessage?: (message: EdgeFunctionRawMessage, ctx: EdgeFunctionMessageContext<TResponse>) => void;
25
+ /** Optional: Defaults to seed the response object if not sent by the server. */
26
+ defaults?: Partial<TResponse>;
27
+ /** Optional: Listener for server actions (status, complete, etc.) */
28
+ onServerAction?: (type: string, data: unknown) => void;
29
+ /** Optional: Tags to invalidate on completion. */
30
+ invalidateTags?: {
31
+ tags: Array<string | {
32
+ type: string;
33
+ id?: string | number;
34
+ }>;
35
+ condition?: (response?: TResponse) => boolean;
36
+ };
37
+ /** Optional: Edge worker expiry from server checkpoint metadata */
38
+ getWorkerExpiresAt?: () => number | null;
39
+ };
40
+ /** Mutable ref bag used by connectEdgeSocket without React */
41
+ type Ref<T> = {
42
+ current: T;
43
+ };
44
+
45
+ /** Client-side edge worker timing configuration */
46
+ type EdgeWorkerLimits = {
47
+ edgeWorkerTtlMs: number;
48
+ edgeRotateThresholdMs: number;
49
+ overallTimeoutMs: number;
50
+ };
51
+ /** Default limits aligned with short-lived edge workers (~2.5 min TTL) */
52
+ declare const DEFAULT_EDGE_WORKER_LIMITS: EdgeWorkerLimits;
53
+
54
+ type EdgeStreamCoreDeps = {
55
+ getAccessToken: () => Promise<string>;
56
+ getSupabaseUrl: () => string;
57
+ workerLimits: EdgeWorkerLimits;
58
+ toUserMessage?: (error: unknown) => string | null;
59
+ invalidateTags?: (tags: Array<string | {
60
+ type: string;
61
+ id?: string | number;
62
+ }>) => void;
63
+ };
64
+ /** Factory for a WebSocket streaming hook wired to a host app */
65
+ declare function createUseEdgeStream(deps: EdgeStreamCoreDeps): <TPayload, TResponse extends Record<string, unknown>>(config: EdgeStreamConfig) => {
66
+ warmup: (payload: TPayload, options?: WarmupOptions) => Promise<void>;
67
+ send: (payload: TPayload, options: StartStreamOptions<TResponse>) => Promise<TResponse>;
68
+ abort: () => void;
69
+ isLoading: boolean;
70
+ error: Error | null;
71
+ data: TResponse | undefined;
72
+ isConnected: boolean;
73
+ };
74
+
75
+ export { DEFAULT_EDGE_WORKER_LIMITS as D, type EdgeFunctionRawMessage as E, type Ref as R, type StandardAiCallbacks as S, type WarmupOptions as W, type EdgeFunctionMessageContext as a, type EdgeStreamConfig as b, type EdgeStreamCoreDeps as c, type EdgeWorkerLimits as d, type StartStreamOptions as e, createUseEdgeStream as f };
package/dist/react.cjs ADDED
@@ -0,0 +1,485 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/react.ts
21
+ var react_exports = {};
22
+ __export(react_exports, {
23
+ createUseEdgeStream: () => createUseEdgeStream
24
+ });
25
+ module.exports = __toCommonJS(react_exports);
26
+
27
+ // src/createUseEdgeStream.ts
28
+ var import_react = require("react");
29
+
30
+ // src/constants.ts
31
+ var MAX_RETRIES = 200;
32
+ var INITIAL_RETRY_DELAY_MS = 1e3;
33
+ var CONNECTION_TIMEOUT_MS = 1e4;
34
+
35
+ // src/connection.ts
36
+ async function connectEdgeSocket(deps) {
37
+ const {
38
+ functionPath,
39
+ getAccessToken,
40
+ getSupabaseUrl,
41
+ wsRef,
42
+ isExplicitDisconnectRef,
43
+ isConnectingRef,
44
+ retryCountRef,
45
+ socketOpenedAtRef,
46
+ isWarmupReadyRef,
47
+ warmupWaitersRef,
48
+ passiveOnServerActionRef,
49
+ activeRequestRef,
50
+ lastWarmupPayloadRef,
51
+ setIsConnected,
52
+ closeSocket,
53
+ sendWarmupPayload,
54
+ settleWarmupWaiters
55
+ } = deps;
56
+ if (wsRef.current?.readyState === WebSocket.OPEN) return Promise.resolve();
57
+ if (isConnectingRef.current) {
58
+ return new Promise((resolve, reject) => {
59
+ const checkInterval = setInterval(() => {
60
+ if (wsRef.current?.readyState === WebSocket.OPEN) {
61
+ clearInterval(checkInterval);
62
+ resolve();
63
+ } else if (wsRef.current?.readyState === WebSocket.CLOSED) {
64
+ clearInterval(checkInterval);
65
+ reject(new Error("Connection closed during check"));
66
+ }
67
+ }, 100);
68
+ });
69
+ }
70
+ isConnectingRef.current = true;
71
+ isExplicitDisconnectRef.current = false;
72
+ try {
73
+ const accessToken = await getAccessToken();
74
+ const supabaseUrl = getSupabaseUrl();
75
+ if (!supabaseUrl) throw new Error("Missing Supabase URL");
76
+ const wsUrl = supabaseUrl.replace(
77
+ /^https?:\/\//,
78
+ (m) => m === "https://" ? "wss://" : "ws://"
79
+ );
80
+ const functionUrl = `${wsUrl}/functions/v1/${functionPath}`;
81
+ return await new Promise((resolveConnection, rejectConnection) => {
82
+ let connectionTimeout = null;
83
+ if (wsRef.current) {
84
+ try {
85
+ wsRef.current.onopen = null;
86
+ wsRef.current.onmessage = null;
87
+ wsRef.current.onerror = null;
88
+ wsRef.current.onclose = null;
89
+ if (wsRef.current.readyState === WebSocket.OPEN || wsRef.current.readyState === WebSocket.CONNECTING) {
90
+ wsRef.current.close();
91
+ }
92
+ } catch {
93
+ }
94
+ }
95
+ const urlWithToken = new URL(functionUrl);
96
+ urlWithToken.searchParams.set("jwt", accessToken);
97
+ wsRef.current = new WebSocket(urlWithToken.toString());
98
+ if (retryCountRef.current === 0) {
99
+ connectionTimeout = setTimeout(() => {
100
+ if (wsRef.current && wsRef.current.readyState !== WebSocket.OPEN) {
101
+ isExplicitDisconnectRef.current = false;
102
+ closeSocket();
103
+ }
104
+ }, CONNECTION_TIMEOUT_MS);
105
+ }
106
+ wsRef.current.onopen = () => {
107
+ if (connectionTimeout) clearTimeout(connectionTimeout);
108
+ retryCountRef.current = 0;
109
+ isConnectingRef.current = false;
110
+ setIsConnected(true);
111
+ socketOpenedAtRef.current = Date.now();
112
+ if (lastWarmupPayloadRef.current) {
113
+ sendWarmupPayload();
114
+ }
115
+ resolveConnection();
116
+ };
117
+ wsRef.current.onerror = () => {
118
+ };
119
+ const retryConnect = () => {
120
+ connectEdgeSocket(deps).then(resolveConnection).catch(rejectConnection);
121
+ };
122
+ wsRef.current.onclose = () => {
123
+ if (connectionTimeout) clearTimeout(connectionTimeout);
124
+ isConnectingRef.current = false;
125
+ setIsConnected(false);
126
+ isWarmupReadyRef.current = false;
127
+ const willRetry = !isExplicitDisconnectRef.current && retryCountRef.current < MAX_RETRIES;
128
+ if (!willRetry) {
129
+ settleWarmupWaiters(new Error("WebSocket closed"));
130
+ }
131
+ if (isExplicitDisconnectRef.current) {
132
+ rejectConnection(
133
+ new Error("WebSocket closed by server or aborted")
134
+ );
135
+ } else if (retryCountRef.current < MAX_RETRIES) {
136
+ retryCountRef.current++;
137
+ const delay = INITIAL_RETRY_DELAY_MS * Math.pow(2, retryCountRef.current - 1);
138
+ setTimeout(retryConnect, delay);
139
+ } else {
140
+ rejectConnection(
141
+ new Error(
142
+ `WebSocket connection failed after ${retryCountRef.current} retries`
143
+ )
144
+ );
145
+ }
146
+ };
147
+ wsRef.current.onmessage = (event) => {
148
+ try {
149
+ const message = JSON.parse(event.data);
150
+ if (message.type === "status" && message.data === "ready") {
151
+ isWarmupReadyRef.current = true;
152
+ settleWarmupWaiters();
153
+ }
154
+ if (message.type === "error" && warmupWaitersRef.current.length > 0 && !isWarmupReadyRef.current) {
155
+ isWarmupReadyRef.current = false;
156
+ settleWarmupWaiters(
157
+ new Error(String(message.data ?? "Warmup failed"))
158
+ );
159
+ }
160
+ const passive = passiveOnServerActionRef.current;
161
+ if (passive && !activeRequestRef.current) {
162
+ const isWarmupControl = message.type === "status" && (message.data === "ready" || message.data === "context");
163
+ if (!isWarmupControl) {
164
+ passive(message.type, message.data);
165
+ }
166
+ }
167
+ if (!activeRequestRef.current) return;
168
+ const { ctx, handler } = activeRequestRef.current;
169
+ handler(message, ctx);
170
+ } catch (error) {
171
+ if (!activeRequestRef.current) return;
172
+ const ctx = activeRequestRef.current.ctx;
173
+ ctx.reject(
174
+ new Error(
175
+ `Failed to parse WebSocket message: ${error instanceof Error ? error.message : String(error)}`
176
+ )
177
+ );
178
+ }
179
+ };
180
+ });
181
+ } catch (err) {
182
+ isConnectingRef.current = false;
183
+ throw err;
184
+ }
185
+ }
186
+
187
+ // src/handler.ts
188
+ function createStandardAiMessageHandler(defaults = {}, callbacks) {
189
+ const state = {};
190
+ const buildResponse = (overrides) => ({
191
+ ...defaults,
192
+ ...state,
193
+ ...overrides
194
+ });
195
+ return (message, ctx) => {
196
+ if (message.type === "response_text" && typeof message.data === "string") {
197
+ state.reply = message.data;
198
+ }
199
+ if (typeof message.data === "object" && message.data !== null && message.type !== "error") {
200
+ Object.assign(state, message.data);
201
+ }
202
+ if (message.type === "error") {
203
+ const raw = message.data ?? "Server error";
204
+ const userMsg = callbacks?.toUserMessage?.(raw);
205
+ if (userMsg) callbacks?.onServerAction?.("error", userMsg);
206
+ ctx.reject(new Error(raw));
207
+ return;
208
+ }
209
+ if (message.type === "complete") {
210
+ ctx.clearOverallTimeout();
211
+ callbacks?.onServerAction?.("complete", message.data);
212
+ if (!ctx.isResolved()) {
213
+ ctx.resolve(buildResponse(message.data));
214
+ }
215
+ return;
216
+ }
217
+ callbacks?.onServerAction?.(message.type, message.data);
218
+ };
219
+ }
220
+
221
+ // src/createUseEdgeStream.ts
222
+ function createUseEdgeStream(deps) {
223
+ const {
224
+ getAccessToken,
225
+ getSupabaseUrl,
226
+ workerLimits,
227
+ toUserMessage,
228
+ invalidateTags
229
+ } = deps;
230
+ const { edgeWorkerTtlMs, edgeRotateThresholdMs, overallTimeoutMs } = workerLimits;
231
+ return function useEdgeStream(config) {
232
+ const [isLoading, setIsLoading] = (0, import_react.useState)(false);
233
+ const [error, setError] = (0, import_react.useState)(null);
234
+ const [data, setData] = (0, import_react.useState)(void 0);
235
+ const wsRef = (0, import_react.useRef)(null);
236
+ const isExplicitDisconnectRef = (0, import_react.useRef)(false);
237
+ const [isConnected, setIsConnected] = (0, import_react.useState)(false);
238
+ const isConnectingRef = (0, import_react.useRef)(false);
239
+ const lastWarmupPayloadRef = (0, import_react.useRef)(null);
240
+ const isWarmupReadyRef = (0, import_react.useRef)(false);
241
+ const warmupWaitersRef = (0, import_react.useRef)([]);
242
+ const retryCountRef = (0, import_react.useRef)(0);
243
+ const passiveOnServerActionRef = (0, import_react.useRef)(null);
244
+ const socketOpenedAtRef = (0, import_react.useRef)(null);
245
+ const settleWarmupWaiters = (0, import_react.useCallback)((warmupError) => {
246
+ const waiters = warmupWaitersRef.current;
247
+ warmupWaitersRef.current = [];
248
+ if (warmupError) {
249
+ waiters.forEach((w) => w.reject(warmupError));
250
+ return;
251
+ }
252
+ waiters.forEach((w) => w.resolve());
253
+ }, []);
254
+ const waitForWarmupReady = (0, import_react.useCallback)(() => {
255
+ if (isWarmupReadyRef.current) return Promise.resolve();
256
+ return new Promise((resolve, reject) => {
257
+ warmupWaitersRef.current.push({ resolve, reject });
258
+ });
259
+ }, []);
260
+ const sendWarmupPayload = (0, import_react.useCallback)(() => {
261
+ if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {
262
+ return;
263
+ }
264
+ if (!lastWarmupPayloadRef.current) return;
265
+ isWarmupReadyRef.current = false;
266
+ wsRef.current.send(
267
+ JSON.stringify({
268
+ type: "client_warmup",
269
+ data: lastWarmupPayloadRef.current
270
+ })
271
+ );
272
+ }, []);
273
+ const activeRequestRef = (0, import_react.useRef)(null);
274
+ (0, import_react.useEffect)(() => {
275
+ return () => {
276
+ isExplicitDisconnectRef.current = true;
277
+ if (wsRef.current) {
278
+ try {
279
+ wsRef.current.close();
280
+ } catch {
281
+ }
282
+ }
283
+ };
284
+ }, []);
285
+ const closeSocket = (0, import_react.useCallback)(() => {
286
+ if (!wsRef.current) return;
287
+ try {
288
+ wsRef.current.close();
289
+ } catch {
290
+ }
291
+ socketOpenedAtRef.current = null;
292
+ }, []);
293
+ const abort = (0, import_react.useCallback)(() => {
294
+ isExplicitDisconnectRef.current = true;
295
+ closeSocket();
296
+ setIsLoading(false);
297
+ if (activeRequestRef.current) {
298
+ activeRequestRef.current.reject(new Error("Request aborted"));
299
+ if (activeRequestRef.current.overallTimeout) {
300
+ clearTimeout(activeRequestRef.current.overallTimeout);
301
+ }
302
+ activeRequestRef.current = null;
303
+ }
304
+ }, [closeSocket]);
305
+ const connectWebSocket = (0, import_react.useCallback)(
306
+ () => connectEdgeSocket({
307
+ functionPath: config.functionPath,
308
+ getAccessToken,
309
+ getSupabaseUrl,
310
+ wsRef,
311
+ isExplicitDisconnectRef,
312
+ isConnectingRef,
313
+ retryCountRef,
314
+ socketOpenedAtRef,
315
+ isWarmupReadyRef,
316
+ warmupWaitersRef,
317
+ passiveOnServerActionRef,
318
+ activeRequestRef,
319
+ lastWarmupPayloadRef,
320
+ setIsConnected,
321
+ closeSocket,
322
+ sendWarmupPayload,
323
+ settleWarmupWaiters
324
+ }),
325
+ [
326
+ config.functionPath,
327
+ closeSocket,
328
+ sendWarmupPayload,
329
+ settleWarmupWaiters
330
+ ]
331
+ );
332
+ const rotateConnectionIfNeeded = (0, import_react.useCallback)(
333
+ async (getExpiresAt) => {
334
+ const fallbackExpires = socketOpenedAtRef.current ? socketOpenedAtRef.current + edgeWorkerTtlMs : null;
335
+ const expiresAt = getExpiresAt?.() ?? fallbackExpires;
336
+ if (!expiresAt) return;
337
+ if (expiresAt - Date.now() >= edgeRotateThresholdMs) return;
338
+ isExplicitDisconnectRef.current = false;
339
+ closeSocket();
340
+ isWarmupReadyRef.current = false;
341
+ await connectWebSocket();
342
+ },
343
+ [closeSocket, connectWebSocket, edgeRotateThresholdMs, edgeWorkerTtlMs]
344
+ );
345
+ const warmup = (0, import_react.useCallback)(
346
+ async (payload, options) => {
347
+ if (options?.onServerAction) {
348
+ passiveOnServerActionRef.current = options.onServerAction;
349
+ }
350
+ lastWarmupPayloadRef.current = payload;
351
+ isWarmupReadyRef.current = false;
352
+ const wasOpen = wsRef.current?.readyState === WebSocket.OPEN;
353
+ await connectWebSocket();
354
+ if (!isWarmupReadyRef.current) {
355
+ if (wasOpen) sendWarmupPayload();
356
+ await waitForWarmupReady();
357
+ }
358
+ },
359
+ [connectWebSocket, sendWarmupPayload, waitForWarmupReady]
360
+ );
361
+ const send = (0, import_react.useCallback)(
362
+ async (payload, options) => {
363
+ if (!isLoading) {
364
+ await rotateConnectionIfNeeded(options.getWorkerExpiresAt);
365
+ }
366
+ setIsLoading(true);
367
+ setError(null);
368
+ setData(void 0);
369
+ isExplicitDisconnectRef.current = false;
370
+ let resolved = false;
371
+ const ctx = {
372
+ resolve: (value) => {
373
+ resolved = true;
374
+ setData(value);
375
+ setIsLoading(false);
376
+ if (options.invalidateTags && invalidateTags) {
377
+ const shouldInvalidate = options.invalidateTags.condition ? options.invalidateTags.condition(value) : true;
378
+ if (shouldInvalidate) {
379
+ invalidateTags(options.invalidateTags.tags);
380
+ }
381
+ }
382
+ if (activeRequestRef.current?.overallTimeout) {
383
+ clearTimeout(activeRequestRef.current.overallTimeout);
384
+ }
385
+ if (activeRequestRef.current?.resolve) {
386
+ activeRequestRef.current.resolve(value);
387
+ }
388
+ activeRequestRef.current = null;
389
+ },
390
+ reject: (err) => {
391
+ resolved = true;
392
+ setError(err);
393
+ setIsLoading(false);
394
+ if (activeRequestRef.current?.overallTimeout) {
395
+ clearTimeout(activeRequestRef.current.overallTimeout);
396
+ }
397
+ if (activeRequestRef.current?.reject) {
398
+ activeRequestRef.current.reject(err);
399
+ }
400
+ activeRequestRef.current = null;
401
+ },
402
+ closeSocket,
403
+ clearOverallTimeout: () => {
404
+ if (activeRequestRef.current?.overallTimeout) {
405
+ clearTimeout(activeRequestRef.current.overallTimeout);
406
+ }
407
+ },
408
+ isResolved: () => resolved
409
+ };
410
+ return new Promise((resolvePromise, rejectPromise) => {
411
+ const overallTimeout = setTimeout(() => {
412
+ if (!resolved) {
413
+ const err = new Error("WebSocket request timeout");
414
+ setError(err);
415
+ setIsLoading(false);
416
+ rejectPromise(err);
417
+ activeRequestRef.current = null;
418
+ }
419
+ }, overallTimeoutMs);
420
+ const handler = options.onMessage || createStandardAiMessageHandler(options.defaults || {}, {
421
+ onServerAction: options.onServerAction,
422
+ toUserMessage
423
+ });
424
+ activeRequestRef.current = {
425
+ payload,
426
+ options,
427
+ ctx,
428
+ resolve: resolvePromise,
429
+ reject: rejectPromise,
430
+ overallTimeout,
431
+ handler
432
+ };
433
+ connectWebSocket().then(async () => {
434
+ if (!activeRequestRef.current || activeRequestRef.current.sent) {
435
+ return;
436
+ }
437
+ if (!lastWarmupPayloadRef.current) {
438
+ throw new Error("Warmup required");
439
+ }
440
+ if (!isWarmupReadyRef.current) {
441
+ sendWarmupPayload();
442
+ await waitForWarmupReady();
443
+ }
444
+ if (wsRef.current?.readyState === WebSocket.OPEN && activeRequestRef.current && !activeRequestRef.current.sent) {
445
+ activeRequestRef.current.sent = true;
446
+ wsRef.current.send(
447
+ JSON.stringify({ type: "client_message", data: payload })
448
+ );
449
+ }
450
+ }).catch((err) => {
451
+ clearTimeout(overallTimeout);
452
+ setError(err);
453
+ setIsLoading(false);
454
+ rejectPromise(err);
455
+ activeRequestRef.current = null;
456
+ });
457
+ });
458
+ },
459
+ [
460
+ connectWebSocket,
461
+ closeSocket,
462
+ sendWarmupPayload,
463
+ waitForWarmupReady,
464
+ rotateConnectionIfNeeded,
465
+ isLoading,
466
+ overallTimeoutMs,
467
+ toUserMessage,
468
+ invalidateTags
469
+ ]
470
+ );
471
+ return {
472
+ warmup,
473
+ send,
474
+ abort,
475
+ isLoading,
476
+ error,
477
+ data,
478
+ isConnected
479
+ };
480
+ };
481
+ }
482
+ // Annotate the CommonJS export names for ESM import in node:
483
+ 0 && (module.exports = {
484
+ createUseEdgeStream
485
+ });
@@ -0,0 +1 @@
1
+ export { a as EdgeFunctionMessageContext, E as EdgeFunctionRawMessage, b as EdgeStreamConfig, c as EdgeStreamCoreDeps, S as StandardAiCallbacks, e as StartStreamOptions, W as WarmupOptions, f as createUseEdgeStream } from './react-BgnmZ7M3.cjs';
@@ -0,0 +1 @@
1
+ export { a as EdgeFunctionMessageContext, E as EdgeFunctionRawMessage, b as EdgeStreamConfig, c as EdgeStreamCoreDeps, S as StandardAiCallbacks, e as StartStreamOptions, W as WarmupOptions, f as createUseEdgeStream } from './react-BgnmZ7M3.js';
package/dist/react.js ADDED
@@ -0,0 +1,6 @@
1
+ import {
2
+ createUseEdgeStream
3
+ } from "./chunk-GP2SEFBH.js";
4
+ export {
5
+ createUseEdgeStream
6
+ };
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "supabase-edge-function-continuous-stream",
3
+ "version": "1.0.0",
4
+ "description": "Continuous WebSocket streaming for Supabase edge functions",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.cjs"
12
+ },
13
+ "./react": {
14
+ "types": "./dist/react.d.ts",
15
+ "import": "./react.js",
16
+ "require": "./dist/react.cjs",
17
+ "default": "./react.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "react.js",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsup",
28
+ "prepublishOnly": "npm run build",
29
+ "test": "vitest run"
30
+ },
31
+ "peerDependencies": {
32
+ "react": ">=18"
33
+ },
34
+ "peerDependenciesMeta": {
35
+ "react": {
36
+ "optional": true
37
+ }
38
+ },
39
+ "devDependencies": {
40
+ "@types/react": "^19",
41
+ "react": "^19",
42
+ "tsup": "^8.5.0",
43
+ "typescript": "^5.9.0",
44
+ "vitest": "^3.2.4"
45
+ },
46
+ "keywords": [
47
+ "supabase",
48
+ "edge-functions",
49
+ "websocket",
50
+ "streaming",
51
+ "react"
52
+ ]
53
+ }
package/react.js ADDED
@@ -0,0 +1 @@
1
+ export * from "./dist/react.js";