@flightdev/core 0.6.7

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 (187) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +541 -0
  3. package/dist/actions/index.d.ts +743 -0
  4. package/dist/actions/index.js +3 -0
  5. package/dist/actions/index.js.map +1 -0
  6. package/dist/adapters/index.d.ts +502 -0
  7. package/dist/adapters/index.js +3 -0
  8. package/dist/adapters/index.js.map +1 -0
  9. package/dist/cache/index.d.ts +191 -0
  10. package/dist/cache/index.js +3 -0
  11. package/dist/cache/index.js.map +1 -0
  12. package/dist/chunk-62HISNA3.js +354 -0
  13. package/dist/chunk-62HISNA3.js.map +1 -0
  14. package/dist/chunk-63LWTEDQ.js +341 -0
  15. package/dist/chunk-63LWTEDQ.js.map +1 -0
  16. package/dist/chunk-63SCEXD7.js +3 -0
  17. package/dist/chunk-63SCEXD7.js.map +1 -0
  18. package/dist/chunk-72MYOTUB.js +667 -0
  19. package/dist/chunk-72MYOTUB.js.map +1 -0
  20. package/dist/chunk-7CNW24MQ.js +257 -0
  21. package/dist/chunk-7CNW24MQ.js.map +1 -0
  22. package/dist/chunk-7WIEAUJT.js +300 -0
  23. package/dist/chunk-7WIEAUJT.js.map +1 -0
  24. package/dist/chunk-7ZZF4ULK.js +259 -0
  25. package/dist/chunk-7ZZF4ULK.js.map +1 -0
  26. package/dist/chunk-AE3JTS73.js +222 -0
  27. package/dist/chunk-AE3JTS73.js.map +1 -0
  28. package/dist/chunk-AP5NLUSB.js +258 -0
  29. package/dist/chunk-AP5NLUSB.js.map +1 -0
  30. package/dist/chunk-C37YQQI7.js +221 -0
  31. package/dist/chunk-C37YQQI7.js.map +1 -0
  32. package/dist/chunk-DCLVXFVH.js +225 -0
  33. package/dist/chunk-DCLVXFVH.js.map +1 -0
  34. package/dist/chunk-DZMWWDFD.js +223 -0
  35. package/dist/chunk-DZMWWDFD.js.map +1 -0
  36. package/dist/chunk-GCQZ4FHI.js +245 -0
  37. package/dist/chunk-GCQZ4FHI.js.map +1 -0
  38. package/dist/chunk-IPP44XY6.js +47 -0
  39. package/dist/chunk-IPP44XY6.js.map +1 -0
  40. package/dist/chunk-IW7FTQQX.js +267 -0
  41. package/dist/chunk-IW7FTQQX.js.map +1 -0
  42. package/dist/chunk-JX4YSCBH.js +428 -0
  43. package/dist/chunk-JX4YSCBH.js.map +1 -0
  44. package/dist/chunk-KX6UYWWR.js +229 -0
  45. package/dist/chunk-KX6UYWWR.js.map +1 -0
  46. package/dist/chunk-LWVETFJV.js +46 -0
  47. package/dist/chunk-LWVETFJV.js.map +1 -0
  48. package/dist/chunk-MCL2MCA2.js +285 -0
  49. package/dist/chunk-MCL2MCA2.js.map +1 -0
  50. package/dist/chunk-MZXCF35B.js +205 -0
  51. package/dist/chunk-MZXCF35B.js.map +1 -0
  52. package/dist/chunk-NCGPUFWV.js +96 -0
  53. package/dist/chunk-NCGPUFWV.js.map +1 -0
  54. package/dist/chunk-OEJMIE2Q.js +351 -0
  55. package/dist/chunk-OEJMIE2Q.js.map +1 -0
  56. package/dist/chunk-OYF2OAKS.js +394 -0
  57. package/dist/chunk-OYF2OAKS.js.map +1 -0
  58. package/dist/chunk-P6S43FYZ.js +316 -0
  59. package/dist/chunk-P6S43FYZ.js.map +1 -0
  60. package/dist/chunk-PL37KFRJ.js +3 -0
  61. package/dist/chunk-PL37KFRJ.js.map +1 -0
  62. package/dist/chunk-Q7BS5QC5.js +197 -0
  63. package/dist/chunk-Q7BS5QC5.js.map +1 -0
  64. package/dist/chunk-SDYPG3JD.js +288 -0
  65. package/dist/chunk-SDYPG3JD.js.map +1 -0
  66. package/dist/chunk-SUG56SZO.js +256 -0
  67. package/dist/chunk-SUG56SZO.js.map +1 -0
  68. package/dist/chunk-UVH5XJRP.js +164 -0
  69. package/dist/chunk-UVH5XJRP.js.map +1 -0
  70. package/dist/chunk-WZIJKCL3.js +282 -0
  71. package/dist/chunk-WZIJKCL3.js.map +1 -0
  72. package/dist/chunk-Y22AMGTM.js +3 -0
  73. package/dist/chunk-Y22AMGTM.js.map +1 -0
  74. package/dist/chunk-Z7G23XWU.js +200 -0
  75. package/dist/chunk-Z7G23XWU.js.map +1 -0
  76. package/dist/chunk-ZJU5M4IB.js +125 -0
  77. package/dist/chunk-ZJU5M4IB.js.map +1 -0
  78. package/dist/chunk-ZVC3ZWLM.js +52 -0
  79. package/dist/chunk-ZVC3ZWLM.js.map +1 -0
  80. package/dist/chunk-ZZZML7Y3.js +310 -0
  81. package/dist/chunk-ZZZML7Y3.js.map +1 -0
  82. package/dist/client.d.ts +25 -0
  83. package/dist/client.js +16 -0
  84. package/dist/client.js.map +1 -0
  85. package/dist/config/index.d.ts +170 -0
  86. package/dist/config/index.js +3 -0
  87. package/dist/config/index.js.map +1 -0
  88. package/dist/errors/index.d.ts +267 -0
  89. package/dist/errors/index.js +4 -0
  90. package/dist/errors/index.js.map +1 -0
  91. package/dist/file-router/index.d.ts +184 -0
  92. package/dist/file-router/index.js +3 -0
  93. package/dist/file-router/index.js.map +1 -0
  94. package/dist/file-router/streaming-hints.d.ts +129 -0
  95. package/dist/file-router/streaming-hints.js +3 -0
  96. package/dist/file-router/streaming-hints.js.map +1 -0
  97. package/dist/handlers/index.d.ts +59 -0
  98. package/dist/handlers/index.js +3 -0
  99. package/dist/handlers/index.js.map +1 -0
  100. package/dist/index.d.ts +588 -0
  101. package/dist/index.js +886 -0
  102. package/dist/index.js.map +1 -0
  103. package/dist/islands/index.d.ts +234 -0
  104. package/dist/islands/index.js +3 -0
  105. package/dist/islands/index.js.map +1 -0
  106. package/dist/middleware/index.d.ts +305 -0
  107. package/dist/middleware/index.js +3 -0
  108. package/dist/middleware/index.js.map +1 -0
  109. package/dist/react/index.d.ts +73 -0
  110. package/dist/react/index.js +52 -0
  111. package/dist/react/index.js.map +1 -0
  112. package/dist/render/index.d.ts +131 -0
  113. package/dist/render/index.js +3 -0
  114. package/dist/render/index.js.map +1 -0
  115. package/dist/router/index.d.ts +65 -0
  116. package/dist/router/index.js +3 -0
  117. package/dist/router/index.js.map +1 -0
  118. package/dist/rsc/adapters/index.d.ts +8 -0
  119. package/dist/rsc/adapters/index.js +7 -0
  120. package/dist/rsc/adapters/index.js.map +1 -0
  121. package/dist/rsc/adapters/preact.d.ts +97 -0
  122. package/dist/rsc/adapters/preact.js +3 -0
  123. package/dist/rsc/adapters/preact.js.map +1 -0
  124. package/dist/rsc/adapters/react.d.ts +82 -0
  125. package/dist/rsc/adapters/react.js +3 -0
  126. package/dist/rsc/adapters/react.js.map +1 -0
  127. package/dist/rsc/adapters/solid.d.ts +84 -0
  128. package/dist/rsc/adapters/solid.js +3 -0
  129. package/dist/rsc/adapters/solid.js.map +1 -0
  130. package/dist/rsc/adapters/vue.d.ts +80 -0
  131. package/dist/rsc/adapters/vue.js +3 -0
  132. package/dist/rsc/adapters/vue.js.map +1 -0
  133. package/dist/rsc/boundaries.d.ts +182 -0
  134. package/dist/rsc/boundaries.js +3 -0
  135. package/dist/rsc/boundaries.js.map +1 -0
  136. package/dist/rsc/context.d.ts +201 -0
  137. package/dist/rsc/context.js +3 -0
  138. package/dist/rsc/context.js.map +1 -0
  139. package/dist/rsc/index.d.ts +232 -0
  140. package/dist/rsc/index.js +15 -0
  141. package/dist/rsc/index.js.map +1 -0
  142. package/dist/rsc/legacy.d.ts +155 -0
  143. package/dist/rsc/legacy.js +3 -0
  144. package/dist/rsc/legacy.js.map +1 -0
  145. package/dist/rsc/payload.d.ts +262 -0
  146. package/dist/rsc/payload.js +3 -0
  147. package/dist/rsc/payload.js.map +1 -0
  148. package/dist/rsc/plugins/esbuild.d.ts +124 -0
  149. package/dist/rsc/plugins/esbuild.js +4 -0
  150. package/dist/rsc/plugins/esbuild.js.map +1 -0
  151. package/dist/rsc/plugins/index.d.ts +4 -0
  152. package/dist/rsc/plugins/index.js +6 -0
  153. package/dist/rsc/plugins/index.js.map +1 -0
  154. package/dist/rsc/plugins/rollup.d.ts +103 -0
  155. package/dist/rsc/plugins/rollup.js +4 -0
  156. package/dist/rsc/plugins/rollup.js.map +1 -0
  157. package/dist/rsc/renderer.d.ts +162 -0
  158. package/dist/rsc/renderer.js +5 -0
  159. package/dist/rsc/renderer.js.map +1 -0
  160. package/dist/rsc/stream.d.ts +129 -0
  161. package/dist/rsc/stream.js +3 -0
  162. package/dist/rsc/stream.js.map +1 -0
  163. package/dist/rsc/vite-plugin.d.ts +78 -0
  164. package/dist/rsc/vite-plugin.js +4 -0
  165. package/dist/rsc/vite-plugin.js.map +1 -0
  166. package/dist/server/index.d.ts +135 -0
  167. package/dist/server/index.js +6 -0
  168. package/dist/server/index.js.map +1 -0
  169. package/dist/streaming/adapters/index.d.ts +223 -0
  170. package/dist/streaming/adapters/index.js +3 -0
  171. package/dist/streaming/adapters/index.js.map +1 -0
  172. package/dist/streaming/conditional.d.ts +130 -0
  173. package/dist/streaming/conditional.js +3 -0
  174. package/dist/streaming/conditional.js.map +1 -0
  175. package/dist/streaming/index.d.ts +177 -0
  176. package/dist/streaming/index.js +3 -0
  177. package/dist/streaming/index.js.map +1 -0
  178. package/dist/streaming/observability.d.ts +201 -0
  179. package/dist/streaming/observability.js +4 -0
  180. package/dist/streaming/observability.js.map +1 -0
  181. package/dist/streaming/priority.d.ts +103 -0
  182. package/dist/streaming/priority.js +3 -0
  183. package/dist/streaming/priority.js.map +1 -0
  184. package/dist/utils/index.d.ts +42 -0
  185. package/dist/utils/index.js +4 -0
  186. package/dist/utils/index.js.map +1 -0
  187. package/package.json +228 -0
@@ -0,0 +1,667 @@
1
+ // src/actions/middleware.ts
2
+ function createActionContext(options) {
3
+ const store = /* @__PURE__ */ new Map();
4
+ return {
5
+ request: options.request,
6
+ headers: options.headers ?? options.request?.headers ?? new Headers(),
7
+ actionId: options.actionId,
8
+ args: options.args,
9
+ signal: options.signal,
10
+ get(key) {
11
+ return store.get(key);
12
+ },
13
+ set(key, value) {
14
+ store.set(key, value);
15
+ }
16
+ };
17
+ }
18
+ var middlewareCounter = 0;
19
+ function createActionMiddleware(handler, options = {}) {
20
+ const name = options.name ?? `middleware_${++middlewareCounter}`;
21
+ return {
22
+ name,
23
+ handler
24
+ };
25
+ }
26
+ function pipeline(...middlewares) {
27
+ return (action) => {
28
+ return async (...args) => {
29
+ const ctx = createActionContext({
30
+ actionId: action.name || "anonymous",
31
+ args
32
+ });
33
+ let index = -1;
34
+ const dispatch = async (i) => {
35
+ if (i <= index) {
36
+ throw new Error("next() called multiple times");
37
+ }
38
+ index = i;
39
+ if (i < middlewares.length) {
40
+ const middleware = middlewares[i];
41
+ return middleware.handler(ctx, () => dispatch(i + 1));
42
+ } else {
43
+ return action(...args);
44
+ }
45
+ };
46
+ return dispatch(0);
47
+ };
48
+ };
49
+ }
50
+ async function executeWithMiddleware(action, args, middlewares, options = {}) {
51
+ const ctx = createActionContext({
52
+ request: options.request,
53
+ headers: options.headers,
54
+ actionId: action.name || "anonymous",
55
+ args,
56
+ signal: options.signal
57
+ });
58
+ let index = -1;
59
+ const dispatch = async (i) => {
60
+ if (options.signal?.aborted) {
61
+ return { success: false, error: "Aborted", code: "ABORTED" };
62
+ }
63
+ if (i <= index) {
64
+ throw new Error("next() called multiple times");
65
+ }
66
+ index = i;
67
+ if (i < middlewares.length) {
68
+ const middleware = middlewares[i];
69
+ return middleware.handler(ctx, () => dispatch(i + 1));
70
+ } else {
71
+ return action(...args);
72
+ }
73
+ };
74
+ return dispatch(0);
75
+ }
76
+ function createTimingMiddleware(reporter) {
77
+ return createActionMiddleware(
78
+ async (ctx, next) => {
79
+ const start = performance.now();
80
+ const result = await next();
81
+ const duration = performance.now() - start;
82
+ reporter(ctx.actionId, duration, result);
83
+ return result;
84
+ },
85
+ { name: "timing" }
86
+ );
87
+ }
88
+ function createLoggingMiddleware(options) {
89
+ return createActionMiddleware(
90
+ async (ctx, next) => {
91
+ options.onStart?.(ctx);
92
+ const start = performance.now();
93
+ try {
94
+ const result = await next();
95
+ const duration = performance.now() - start;
96
+ options.onComplete?.(ctx, result, duration);
97
+ return result;
98
+ } catch (error) {
99
+ options.onError?.(ctx, error);
100
+ throw error;
101
+ }
102
+ },
103
+ { name: "logging" }
104
+ );
105
+ }
106
+ function createRetryMiddleware(options) {
107
+ const {
108
+ maxAttempts,
109
+ delay = () => 0,
110
+ shouldRetry = (result) => !result.success
111
+ } = options;
112
+ return createActionMiddleware(
113
+ async (ctx, next) => {
114
+ let lastResult = { success: false, error: "No attempts made" };
115
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
116
+ if (attempt > 0) {
117
+ const delayMs = delay(attempt);
118
+ if (delayMs > 0) {
119
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
120
+ }
121
+ }
122
+ lastResult = await next();
123
+ if (!shouldRetry(lastResult)) {
124
+ return lastResult;
125
+ }
126
+ }
127
+ return lastResult;
128
+ },
129
+ { name: "retry" }
130
+ );
131
+ }
132
+
133
+ // src/actions/streaming.ts
134
+ function createStreamableAction(generator, options = {}) {
135
+ options.name ?? generator.name ?? "streamable_action";
136
+ return (input) => {
137
+ const abortController = new AbortController();
138
+ let completed = false;
139
+ let finalResult = null;
140
+ let resolveDone;
141
+ const done = new Promise((resolve) => {
142
+ resolveDone = resolve;
143
+ });
144
+ let timeoutId;
145
+ if (options.timeout) {
146
+ timeoutId = setTimeout(() => {
147
+ abortController.abort();
148
+ }, options.timeout);
149
+ }
150
+ async function* iterate() {
151
+ try {
152
+ const gen = generator(input, abortController.signal);
153
+ while (true) {
154
+ if (abortController.signal.aborted) {
155
+ const abortResult = {
156
+ type: "result",
157
+ success: false,
158
+ error: "Stream aborted"
159
+ };
160
+ finalResult = abortResult;
161
+ resolveDone(abortResult);
162
+ yield abortResult;
163
+ return;
164
+ }
165
+ const next = await gen.next();
166
+ if (next.done) {
167
+ const successResult = {
168
+ type: "result",
169
+ success: true,
170
+ data: next.value
171
+ };
172
+ finalResult = successResult;
173
+ completed = true;
174
+ resolveDone(successResult);
175
+ yield successResult;
176
+ return;
177
+ } else {
178
+ yield {
179
+ type: "progress",
180
+ data: next.value
181
+ };
182
+ }
183
+ }
184
+ } catch (error) {
185
+ const errorResult = {
186
+ type: "result",
187
+ success: false,
188
+ error: error instanceof Error ? error.message : "Unknown error"
189
+ };
190
+ finalResult = errorResult;
191
+ resolveDone(errorResult);
192
+ yield errorResult;
193
+ } finally {
194
+ if (timeoutId) {
195
+ clearTimeout(timeoutId);
196
+ }
197
+ }
198
+ }
199
+ const iterator = iterate();
200
+ return {
201
+ [Symbol.asyncIterator]() {
202
+ return iterator;
203
+ },
204
+ abort() {
205
+ abortController.abort();
206
+ },
207
+ done
208
+ };
209
+ };
210
+ }
211
+ function streamToResponse(controller, options = {}) {
212
+ const encoder = new TextEncoder();
213
+ const stream = new ReadableStream({
214
+ async start(streamController) {
215
+ try {
216
+ for await (const item of controller) {
217
+ const chunk = JSON.stringify(item) + "\n";
218
+ streamController.enqueue(encoder.encode(chunk));
219
+ if (item.type === "result") {
220
+ break;
221
+ }
222
+ }
223
+ } catch (error) {
224
+ const errorChunk = JSON.stringify({
225
+ type: "result",
226
+ success: false,
227
+ error: error instanceof Error ? error.message : "Stream error"
228
+ }) + "\n";
229
+ streamController.enqueue(encoder.encode(errorChunk));
230
+ } finally {
231
+ streamController.close();
232
+ }
233
+ },
234
+ cancel() {
235
+ controller.abort();
236
+ }
237
+ });
238
+ return new Response(stream, {
239
+ status: 200,
240
+ headers: {
241
+ "Content-Type": "application/x-ndjson",
242
+ "Transfer-Encoding": "chunked",
243
+ "Cache-Control": "no-cache",
244
+ "Connection": "keep-alive",
245
+ ...options.headers
246
+ }
247
+ });
248
+ }
249
+ function responseToStream(response) {
250
+ const reader = response.body?.getReader();
251
+ const decoder = new TextDecoder();
252
+ if (!reader) {
253
+ throw new Error("Response body is not readable");
254
+ }
255
+ return (async function* () {
256
+ let buffer = "";
257
+ try {
258
+ while (true) {
259
+ const { done, value } = await reader.read();
260
+ if (done) {
261
+ break;
262
+ }
263
+ buffer += decoder.decode(value, { stream: true });
264
+ const lines = buffer.split("\n");
265
+ buffer = lines.pop() || "";
266
+ for (const line of lines) {
267
+ if (line.trim()) {
268
+ try {
269
+ const item = JSON.parse(line);
270
+ yield item;
271
+ } catch {
272
+ }
273
+ }
274
+ }
275
+ }
276
+ if (buffer.trim()) {
277
+ try {
278
+ const item = JSON.parse(buffer);
279
+ yield item;
280
+ } catch {
281
+ }
282
+ }
283
+ } finally {
284
+ reader.releaseLock();
285
+ }
286
+ })();
287
+ }
288
+ async function collectStream(controller) {
289
+ const items = [];
290
+ let result = null;
291
+ for await (const item of controller) {
292
+ items.push(item);
293
+ if (item.type === "result") {
294
+ result = item;
295
+ }
296
+ }
297
+ if (!result) {
298
+ result = { type: "result", success: false, error: "No result received" };
299
+ }
300
+ return { items, result };
301
+ }
302
+ function createProgressReporter(onProgress, onComplete) {
303
+ return (item) => {
304
+ if (item.type === "progress") {
305
+ onProgress(item.data);
306
+ } else {
307
+ onComplete?.(item);
308
+ }
309
+ };
310
+ }
311
+
312
+ // src/actions/queue.ts
313
+ var entryCounter = 0;
314
+ function generateEntryId() {
315
+ return `${Date.now()}_${++entryCounter}_${Math.random().toString(36).substring(2, 9)}`;
316
+ }
317
+ function createQueuedAction(action, options) {
318
+ const {
319
+ storage,
320
+ actionId = action.name || `action_${Date.now()}`,
321
+ retryStrategy = defaultRetryStrategy,
322
+ isOnline = defaultIsOnline,
323
+ onStatusChange,
324
+ onSuccess,
325
+ onFailure
326
+ } = options;
327
+ let isProcessing = false;
328
+ let processorRunning = false;
329
+ startProcessor();
330
+ async function startProcessor() {
331
+ if (processorRunning) return;
332
+ processorRunning = true;
333
+ while (processorRunning) {
334
+ await processQueue();
335
+ await sleep(1e3);
336
+ }
337
+ }
338
+ async function processQueue() {
339
+ const online = await isOnline();
340
+ if (!online) {
341
+ return;
342
+ }
343
+ const entry = await storage.dequeue();
344
+ if (!entry) {
345
+ if (isProcessing) {
346
+ isProcessing = false;
347
+ await notifyStatus();
348
+ }
349
+ return;
350
+ }
351
+ isProcessing = true;
352
+ await notifyStatus();
353
+ await storage.update(entry.id, { status: "processing" });
354
+ try {
355
+ const result = await action(entry.input);
356
+ await storage.remove(entry.id);
357
+ onSuccess?.(entry, result);
358
+ } catch (error) {
359
+ const err = error instanceof Error ? error : new Error(String(error));
360
+ const { shouldRetry, delayMs } = retryStrategy(entry, err);
361
+ if (shouldRetry) {
362
+ await storage.update(entry.id, {
363
+ status: "pending",
364
+ attempts: entry.attempts + 1,
365
+ lastError: err.message
366
+ });
367
+ if (delayMs > 0) {
368
+ await sleep(delayMs);
369
+ }
370
+ } else {
371
+ await storage.update(entry.id, {
372
+ status: "failed",
373
+ lastError: err.message
374
+ });
375
+ onFailure?.(entry, err);
376
+ }
377
+ }
378
+ }
379
+ async function notifyStatus() {
380
+ if (!onStatusChange) return;
381
+ const entries = await storage.peek();
382
+ const status = {
383
+ isProcessing,
384
+ pendingCount: entries.filter((e) => e.status === "pending").length,
385
+ failedCount: entries.filter((e) => e.status === "failed").length,
386
+ isOnline: await isOnline()
387
+ };
388
+ onStatusChange(status);
389
+ }
390
+ return async (input) => {
391
+ const online = await isOnline();
392
+ if (online) {
393
+ try {
394
+ const result = await action(input);
395
+ return { queued: false, result };
396
+ } catch {
397
+ }
398
+ }
399
+ const entry = {
400
+ id: generateEntryId(),
401
+ actionId,
402
+ input,
403
+ queuedAt: Date.now(),
404
+ attempts: 0,
405
+ status: "pending"
406
+ };
407
+ await storage.enqueue(entry);
408
+ await notifyStatus();
409
+ return { queued: true, entryId: entry.id };
410
+ };
411
+ }
412
+ var defaultRetryStrategy = (entry) => ({
413
+ shouldRetry: entry.attempts < 3,
414
+ delayMs: 1e3
415
+ });
416
+ function exponentialBackoff(options = {}) {
417
+ const {
418
+ maxAttempts = 5,
419
+ baseDelayMs = 1e3,
420
+ maxDelayMs = 3e4
421
+ } = options;
422
+ return (entry) => {
423
+ const shouldRetry = entry.attempts < maxAttempts;
424
+ const delayMs = Math.min(
425
+ baseDelayMs * Math.pow(2, entry.attempts),
426
+ maxDelayMs
427
+ );
428
+ return { shouldRetry, delayMs };
429
+ };
430
+ }
431
+ function fixedDelay(options = {}) {
432
+ const { maxAttempts = 3, delayMs = 1e3 } = options;
433
+ return (entry) => ({
434
+ shouldRetry: entry.attempts < maxAttempts,
435
+ delayMs
436
+ });
437
+ }
438
+ function createMemoryAdapter() {
439
+ const store = /* @__PURE__ */ new Map();
440
+ return {
441
+ async enqueue(entry) {
442
+ store.set(entry.id, entry);
443
+ },
444
+ async dequeue() {
445
+ for (const [id, entry] of store.entries()) {
446
+ if (entry.status === "pending") {
447
+ store.delete(id);
448
+ return entry;
449
+ }
450
+ }
451
+ return null;
452
+ },
453
+ async peek() {
454
+ return Array.from(store.values());
455
+ },
456
+ async update(id, updates) {
457
+ const entry = store.get(id);
458
+ if (entry) {
459
+ store.set(id, { ...entry, ...updates });
460
+ }
461
+ },
462
+ async remove(id) {
463
+ store.delete(id);
464
+ },
465
+ async clear() {
466
+ store.clear();
467
+ },
468
+ async length() {
469
+ return store.size;
470
+ }
471
+ };
472
+ }
473
+ function sleep(ms) {
474
+ return new Promise((resolve) => setTimeout(resolve, ms));
475
+ }
476
+ function defaultIsOnline() {
477
+ if (typeof navigator !== "undefined" && "onLine" in navigator) {
478
+ return navigator.onLine;
479
+ }
480
+ return true;
481
+ }
482
+ function createQueueManager(options) {
483
+ let paused = false;
484
+ return {
485
+ pause() {
486
+ paused = true;
487
+ },
488
+ resume() {
489
+ paused = false;
490
+ },
491
+ async getStatus() {
492
+ const entries = await options.storage.peek();
493
+ return {
494
+ isProcessing: !paused,
495
+ pendingCount: entries.filter((e) => e.status === "pending").length,
496
+ failedCount: entries.filter((e) => e.status === "failed").length,
497
+ isOnline: defaultIsOnline()
498
+ };
499
+ },
500
+ async clearFailed() {
501
+ const entries = await options.storage.peek();
502
+ for (const entry of entries) {
503
+ if (entry.status === "failed") {
504
+ await options.storage.remove(entry.id);
505
+ }
506
+ }
507
+ },
508
+ async retryFailed() {
509
+ const entries = await options.storage.peek();
510
+ for (const entry of entries) {
511
+ if (entry.status === "failed") {
512
+ await options.storage.update(entry.id, {
513
+ status: "pending",
514
+ attempts: 0,
515
+ lastError: void 0
516
+ });
517
+ }
518
+ }
519
+ }
520
+ };
521
+ }
522
+
523
+ // src/actions/index.ts
524
+ var actionRegistry = /* @__PURE__ */ new Map();
525
+ function registerAction(action) {
526
+ actionRegistry.set(action.id, action);
527
+ }
528
+ function getAction(id) {
529
+ return actionRegistry.get(id);
530
+ }
531
+ function getAllActions() {
532
+ return Array.from(actionRegistry.values());
533
+ }
534
+ function clearActions() {
535
+ actionRegistry.clear();
536
+ }
537
+ async function executeAction(actionId, args) {
538
+ const action = getAction(actionId);
539
+ if (!action) {
540
+ return {
541
+ success: false,
542
+ error: `Action not found: ${actionId}`
543
+ };
544
+ }
545
+ try {
546
+ const result = await action.fn(...args);
547
+ return {
548
+ success: true,
549
+ data: result
550
+ };
551
+ } catch (error) {
552
+ if (isRedirectError(error)) {
553
+ throw error;
554
+ }
555
+ console.error(`[Flight] Action error (${actionId}):`, error);
556
+ return {
557
+ success: false,
558
+ error: error instanceof Error ? error.message : "Unknown error"
559
+ };
560
+ }
561
+ }
562
+ async function executeFormAction(actionId, formData) {
563
+ return executeAction(actionId, [formData]);
564
+ }
565
+ var actionCounter = 0;
566
+ function generateActionId(name, filePath) {
567
+ const hash = simpleHash(`${filePath}:${name}`);
568
+ return `action_${hash}_${actionCounter++}`;
569
+ }
570
+ function simpleHash(str) {
571
+ let hash = 0;
572
+ for (let i = 0; i < str.length; i++) {
573
+ const char = str.charCodeAt(i);
574
+ hash = (hash << 5) - hash + char;
575
+ hash = hash & hash;
576
+ }
577
+ return Math.abs(hash).toString(36);
578
+ }
579
+ function cookies() {
580
+ const cookieStore = globalThis.__flightCookies;
581
+ if (!cookieStore) {
582
+ console.warn("[Flight] Cookies not available outside of action context");
583
+ return {
584
+ get: () => void 0,
585
+ set: () => {
586
+ },
587
+ delete: () => {
588
+ }
589
+ };
590
+ }
591
+ return cookieStore;
592
+ }
593
+ function redirect(url) {
594
+ throw new RedirectError(url);
595
+ }
596
+ var RedirectError = class extends Error {
597
+ url;
598
+ constructor(url) {
599
+ super(`Redirect to ${url}`);
600
+ this.name = "RedirectError";
601
+ this.url = url;
602
+ }
603
+ };
604
+ function isRedirectError(error) {
605
+ return error instanceof RedirectError;
606
+ }
607
+ function parseFormData(formData) {
608
+ const result = {};
609
+ formData.forEach((value, key) => {
610
+ result[key] = String(value);
611
+ });
612
+ return result;
613
+ }
614
+ function createActionReference(actionId) {
615
+ return `/__flight_action/${actionId}`;
616
+ }
617
+ async function handleActionRequest(request) {
618
+ const url = new URL(request.url);
619
+ const actionPath = url.pathname;
620
+ const match = actionPath.match(/^\/__flight_action\/(.+)$/);
621
+ if (!match) {
622
+ return new Response(JSON.stringify({ error: "Invalid action path" }), {
623
+ status: 400,
624
+ headers: { "Content-Type": "application/json" }
625
+ });
626
+ }
627
+ const actionId = match[1];
628
+ if (!actionId) {
629
+ return new Response(JSON.stringify({ error: "Missing action ID" }), {
630
+ status: 400,
631
+ headers: { "Content-Type": "application/json" }
632
+ });
633
+ }
634
+ try {
635
+ let result;
636
+ const contentType = request.headers.get("content-type") || "";
637
+ if (contentType.includes("application/x-www-form-urlencoded") || contentType.includes("multipart/form-data")) {
638
+ const formData = await request.formData();
639
+ result = await executeFormAction(actionId, formData);
640
+ } else {
641
+ const args = await request.json();
642
+ result = await executeAction(actionId, Array.isArray(args) ? args : [args]);
643
+ }
644
+ return new Response(JSON.stringify(result), {
645
+ status: result.success ? 200 : 400,
646
+ headers: { "Content-Type": "application/json" }
647
+ });
648
+ } catch (error) {
649
+ if (isRedirectError(error)) {
650
+ return new Response(null, {
651
+ status: 303,
652
+ headers: { Location: error.url }
653
+ });
654
+ }
655
+ return new Response(JSON.stringify({
656
+ success: false,
657
+ error: error instanceof Error ? error.message : "Unknown error"
658
+ }), {
659
+ status: 500,
660
+ headers: { "Content-Type": "application/json" }
661
+ });
662
+ }
663
+ }
664
+
665
+ export { RedirectError, clearActions, collectStream, cookies, createActionContext, createActionMiddleware, createActionReference, createLoggingMiddleware, createMemoryAdapter, createProgressReporter, createQueueManager, createQueuedAction, createRetryMiddleware, createStreamableAction, createTimingMiddleware, defaultRetryStrategy, executeAction, executeFormAction, executeWithMiddleware, exponentialBackoff, fixedDelay, generateActionId, getAction, getAllActions, handleActionRequest, isRedirectError, parseFormData, pipeline, redirect, registerAction, responseToStream, streamToResponse };
666
+ //# sourceMappingURL=chunk-72MYOTUB.js.map
667
+ //# sourceMappingURL=chunk-72MYOTUB.js.map