@flight-framework/core 0.3.2 → 0.4.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 (141) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +541 -541
  3. package/dist/actions/index.js +1 -1
  4. package/dist/adapters/index.d.ts +138 -1
  5. package/dist/adapters/index.js +1 -1
  6. package/dist/cache/index.js +1 -1
  7. package/dist/{chunk-3UQJE3XZ.js → chunk-2F2QU6RC.js} +2 -2
  8. package/dist/chunk-2F2QU6RC.js.map +1 -0
  9. package/dist/{chunk-4U7CJVNQ.js → chunk-3KRBRSRJ.js} +2 -2
  10. package/dist/chunk-3KRBRSRJ.js.map +1 -0
  11. package/dist/{chunk-OZ3EXPLE.js → chunk-3QP3E7HS.js} +2 -2
  12. package/dist/chunk-3QP3E7HS.js.map +1 -0
  13. package/dist/{chunk-CKJHJPKQ.js → chunk-62C7LX2E.js} +2 -2
  14. package/dist/chunk-62C7LX2E.js.map +1 -0
  15. package/dist/{chunk-YNTMYL36.js → chunk-6BDCTUQY.js} +3 -3
  16. package/dist/chunk-6BDCTUQY.js.map +1 -0
  17. package/dist/{chunk-KDEA64UX.js → chunk-EGB7C73X.js} +5 -5
  18. package/dist/chunk-EGB7C73X.js.map +1 -0
  19. package/dist/{chunk-2JVEH76V.js → chunk-FSJNOPYE.js} +3 -3
  20. package/dist/chunk-FSJNOPYE.js.map +1 -0
  21. package/dist/{chunk-ARBKF6VI.js → chunk-GCQZ4FHI.js} +2 -2
  22. package/dist/{chunk-ARBKF6VI.js.map → chunk-GCQZ4FHI.js.map} +1 -1
  23. package/dist/{chunk-EHVUAFNH.js → chunk-IXMD5QH2.js} +2 -2
  24. package/dist/chunk-IXMD5QH2.js.map +1 -0
  25. package/dist/{chunk-6GI6HFSQ.js → chunk-K2CQZPCG.js} +2 -2
  26. package/dist/chunk-K2CQZPCG.js.map +1 -0
  27. package/dist/chunk-K5NYYNFS.js +311 -0
  28. package/dist/chunk-K5NYYNFS.js.map +1 -0
  29. package/dist/{chunk-6IG6XIXU.js → chunk-LNV47HGV.js} +2 -2
  30. package/dist/chunk-LNV47HGV.js.map +1 -0
  31. package/dist/{chunk-65JYF3DJ.js → chunk-MDQNNIHH.js} +2 -2
  32. package/dist/chunk-MDQNNIHH.js.map +1 -0
  33. package/dist/{chunk-GNS2FGPC.js → chunk-MQQLYWZZ.js} +2 -2
  34. package/dist/chunk-MQQLYWZZ.js.map +1 -0
  35. package/dist/{chunk-LAKHYTHL.js → chunk-NWMJYTMB.js} +3 -3
  36. package/dist/chunk-NWMJYTMB.js.map +1 -0
  37. package/dist/{chunk-R7MEVVA4.js → chunk-OYF2OAKS.js} +2 -2
  38. package/dist/chunk-OYF2OAKS.js.map +1 -0
  39. package/dist/{chunk-FRAH5QNY.js → chunk-P6WSBVDT.js} +4 -4
  40. package/dist/chunk-P6WSBVDT.js.map +1 -0
  41. package/dist/{chunk-5XHOLZBJ.js → chunk-PDW5WCMW.js} +2 -2
  42. package/dist/chunk-PDW5WCMW.js.map +1 -0
  43. package/dist/{chunk-A2QRUBVE.js → chunk-PVUMB632.js} +2 -2
  44. package/dist/chunk-PVUMB632.js.map +1 -0
  45. package/dist/{chunk-LKOPJ3GS.js → chunk-R7SQAREQ.js} +2 -2
  46. package/dist/chunk-R7SQAREQ.js.map +1 -0
  47. package/dist/{chunk-CNY3ZUVG.js → chunk-RSVA2EYO.js} +2 -2
  48. package/dist/chunk-RSVA2EYO.js.map +1 -0
  49. package/dist/{chunk-PAVI5W6M.js → chunk-T4Z4HM4W.js} +3 -3
  50. package/dist/chunk-T4Z4HM4W.js.map +1 -0
  51. package/dist/{chunk-HNPO6LFW.js → chunk-TASAT7KB.js} +2 -2
  52. package/dist/chunk-TASAT7KB.js.map +1 -0
  53. package/dist/{chunk-3N5ZBVZJ.js → chunk-VPFMHGEV.js} +2 -2
  54. package/dist/chunk-VPFMHGEV.js.map +1 -0
  55. package/dist/{chunk-A4TKWQBU.js → chunk-W6D62JCI.js} +2 -2
  56. package/dist/chunk-W6D62JCI.js.map +1 -0
  57. package/dist/{chunk-UFWGOJL7.js → chunk-WFAWAHJH.js} +2 -2
  58. package/dist/chunk-WFAWAHJH.js.map +1 -0
  59. package/dist/{chunk-NZS2YJ43.js → chunk-WOEIJWGJ.js} +2 -2
  60. package/dist/chunk-WOEIJWGJ.js.map +1 -0
  61. package/dist/{chunk-VNO2YUVD.js → chunk-XOIYNY4I.js} +2 -2
  62. package/dist/chunk-XOIYNY4I.js.map +1 -0
  63. package/dist/{chunk-PO7IHPFF.js → chunk-XSY5AAXT.js} +2 -2
  64. package/dist/chunk-XSY5AAXT.js.map +1 -0
  65. package/dist/{chunk-OZBPR27I.js → chunk-YHEVHRLH.js} +2 -2
  66. package/dist/chunk-YHEVHRLH.js.map +1 -0
  67. package/dist/{chunk-XU6MRYG2.js → chunk-ZIE56LCA.js} +3 -3
  68. package/dist/chunk-ZIE56LCA.js.map +1 -0
  69. package/dist/{chunk-B2LPSCES.js → chunk-ZVC3ZWLM.js} +2 -2
  70. package/dist/chunk-ZVC3ZWLM.js.map +1 -0
  71. package/dist/client.js +8 -8
  72. package/dist/client.js.map +1 -1
  73. package/dist/config/index.js +1 -1
  74. package/dist/errors/index.js +2 -2
  75. package/dist/file-router/index.js +1 -1
  76. package/dist/file-router/streaming-hints.js +1 -1
  77. package/dist/handlers/index.js +1 -1
  78. package/dist/index.js +30 -30
  79. package/dist/index.js.map +1 -1
  80. package/dist/islands/index.js +1 -1
  81. package/dist/middleware/index.js +1 -1
  82. package/dist/react/index.js +2 -2
  83. package/dist/react/index.js.map +1 -1
  84. package/dist/render/index.js +1 -1
  85. package/dist/router/index.js +1 -1
  86. package/dist/rsc/adapters/index.js +4 -4
  87. package/dist/rsc/adapters/preact.js +1 -1
  88. package/dist/rsc/adapters/react.js +1 -1
  89. package/dist/rsc/adapters/solid.js +1 -1
  90. package/dist/rsc/adapters/vue.js +1 -1
  91. package/dist/rsc/boundaries.js +1 -1
  92. package/dist/rsc/context.js +1 -1
  93. package/dist/rsc/index.js +11 -11
  94. package/dist/rsc/legacy.js +1 -1
  95. package/dist/rsc/payload.js +1 -1
  96. package/dist/rsc/plugins/esbuild.js +2 -2
  97. package/dist/rsc/plugins/index.js +4 -4
  98. package/dist/rsc/plugins/rollup.js +2 -2
  99. package/dist/rsc/renderer.js +3 -3
  100. package/dist/rsc/stream.js +1 -1
  101. package/dist/rsc/vite-plugin.js +2 -2
  102. package/dist/server/index.js +4 -4
  103. package/dist/streaming/adapters/index.js +1 -1
  104. package/dist/streaming/conditional.js +1 -1
  105. package/dist/streaming/index.js +1 -1
  106. package/dist/streaming/observability.js +2 -2
  107. package/dist/streaming/priority.js +1 -1
  108. package/dist/utils/index.js +1 -1
  109. package/package.json +1 -1
  110. package/dist/chunk-2JVEH76V.js.map +0 -1
  111. package/dist/chunk-3N5ZBVZJ.js.map +0 -1
  112. package/dist/chunk-3UQJE3XZ.js.map +0 -1
  113. package/dist/chunk-4U7CJVNQ.js.map +0 -1
  114. package/dist/chunk-5XHOLZBJ.js.map +0 -1
  115. package/dist/chunk-65JYF3DJ.js.map +0 -1
  116. package/dist/chunk-6GI6HFSQ.js.map +0 -1
  117. package/dist/chunk-6IG6XIXU.js.map +0 -1
  118. package/dist/chunk-A2QRUBVE.js.map +0 -1
  119. package/dist/chunk-A4TKWQBU.js.map +0 -1
  120. package/dist/chunk-B2LPSCES.js.map +0 -1
  121. package/dist/chunk-CKJHJPKQ.js.map +0 -1
  122. package/dist/chunk-CNY3ZUVG.js.map +0 -1
  123. package/dist/chunk-EHVUAFNH.js.map +0 -1
  124. package/dist/chunk-FRAH5QNY.js.map +0 -1
  125. package/dist/chunk-GNS2FGPC.js.map +0 -1
  126. package/dist/chunk-HNPO6LFW.js.map +0 -1
  127. package/dist/chunk-KDEA64UX.js.map +0 -1
  128. package/dist/chunk-LAKHYTHL.js.map +0 -1
  129. package/dist/chunk-LKOPJ3GS.js.map +0 -1
  130. package/dist/chunk-NZS2YJ43.js.map +0 -1
  131. package/dist/chunk-OZ3EXPLE.js.map +0 -1
  132. package/dist/chunk-OZBPR27I.js.map +0 -1
  133. package/dist/chunk-PAVI5W6M.js.map +0 -1
  134. package/dist/chunk-PO7IHPFF.js.map +0 -1
  135. package/dist/chunk-QK6UEQ75.js +0 -13
  136. package/dist/chunk-QK6UEQ75.js.map +0 -1
  137. package/dist/chunk-R7MEVVA4.js.map +0 -1
  138. package/dist/chunk-UFWGOJL7.js.map +0 -1
  139. package/dist/chunk-VNO2YUVD.js.map +0 -1
  140. package/dist/chunk-XU6MRYG2.js.map +0 -1
  141. package/dist/chunk-YNTMYL36.js.map +0 -1
@@ -1,3 +1,3 @@
1
- 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 } from '../chunk-OZ3EXPLE.js';
1
+ 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 } from '../chunk-3QP3E7HS.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -1,3 +1,139 @@
1
+ import { UIFrameworkAdapter, RenderContext, RenderResult } from '../render/index.js';
2
+
3
+ /**
4
+ * Flight Universal Handler - Platform-agnostic request handler
5
+ *
6
+ * This is the core abstraction that allows Flight applications to run anywhere.
7
+ * Adapters can use this handler, or implement their own - zero lock-in.
8
+ *
9
+ * @module @flight-framework/core/adapters/handler
10
+ */
11
+
12
+ /**
13
+ * Route rules for per-path configuration
14
+ * Similar to Nitro's routeRules - completely optional to use
15
+ */
16
+ interface RouteRules {
17
+ [pattern: string]: RouteRuleConfig;
18
+ }
19
+ interface RouteRuleConfig {
20
+ /** Cache configuration */
21
+ cache?: {
22
+ /** Max age in seconds */
23
+ maxAge?: number;
24
+ /** Stale-while-revalidate in seconds */
25
+ swr?: number;
26
+ /** Vary headers */
27
+ vary?: string[];
28
+ };
29
+ /** CORS configuration */
30
+ cors?: boolean | CorsOptions;
31
+ /** Headers to add to response */
32
+ headers?: Record<string, string>;
33
+ /** Redirect configuration */
34
+ redirect?: string | {
35
+ to: string;
36
+ statusCode?: 301 | 302 | 303 | 307 | 308;
37
+ };
38
+ /** Proxy to another URL */
39
+ proxy?: string;
40
+ /** Render mode override */
41
+ render?: 'ssr' | 'ssg' | 'csr' | 'isr';
42
+ /** ISR revalidation time in seconds */
43
+ isr?: number;
44
+ /** Prerender at build time */
45
+ prerender?: boolean;
46
+ }
47
+ interface CorsOptions {
48
+ origin?: string | string[] | boolean;
49
+ methods?: string[];
50
+ allowedHeaders?: string[];
51
+ exposedHeaders?: string[];
52
+ credentials?: boolean;
53
+ maxAge?: number;
54
+ }
55
+ /**
56
+ * Handler options - all optional, user configures what they need
57
+ */
58
+ interface UniversalHandlerOptions {
59
+ /** Route manifest from build */
60
+ manifest?: RouteManifest;
61
+ /** UI framework adapter (optional - for SSR) */
62
+ framework?: UIFrameworkAdapter;
63
+ /** Route rules (optional) */
64
+ routeRules?: RouteRules;
65
+ /** Static files directory (optional) */
66
+ staticDir?: string;
67
+ /** Base path (optional) */
68
+ basePath?: string;
69
+ /** Custom error handler (optional) */
70
+ onError?: (error: Error, request: Request) => Response | Promise<Response>;
71
+ /** Custom not found handler (optional) */
72
+ onNotFound?: (request: Request) => Response | Promise<Response>;
73
+ /** Hooks for extensibility (optional) */
74
+ hooks?: HandlerHooks;
75
+ }
76
+ /**
77
+ * Handler hooks for extensibility - all optional
78
+ */
79
+ interface HandlerHooks {
80
+ /** Before handling request */
81
+ beforeHandle?: (request: Request) => Request | Promise<Request> | void;
82
+ /** After getting response, before sending */
83
+ afterHandle?: (request: Request, response: Response) => Response | Promise<Response> | void;
84
+ /** Before SSR render */
85
+ beforeRender?: (context: RenderContext) => void | Promise<void>;
86
+ /** After SSR render */
87
+ afterRender?: (result: RenderResult) => RenderResult | Promise<RenderResult>;
88
+ }
89
+ /**
90
+ * Route manifest from build
91
+ */
92
+ interface RouteManifest {
93
+ routes: Array<{
94
+ path: string;
95
+ component: string;
96
+ mode: 'ssr' | 'ssg' | 'csr' | 'isr';
97
+ handler?: string;
98
+ }>;
99
+ staticFiles?: string[];
100
+ }
101
+ /**
102
+ * Universal handler interface
103
+ */
104
+ interface UniversalHandler {
105
+ /** Handle a fetch request */
106
+ fetch(request: Request, env?: unknown, ctx?: unknown): Promise<Response>;
107
+ /** Check if this handler can handle the request */
108
+ canHandle(request: Request): boolean;
109
+ }
110
+ /**
111
+ * Create a universal request handler
112
+ *
113
+ * This is the main abstraction for handling requests.
114
+ * Adapters can use this, extend it, or ignore it completely.
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * // Using the handler (optional)
119
+ * import { createUniversalHandler } from '@flight-framework/core/adapters';
120
+ *
121
+ * const handler = createUniversalHandler({
122
+ * manifest: await import('./manifest.json'),
123
+ * routeRules: {
124
+ * '/api/**': { cors: true },
125
+ * '/blog/**': { cache: { maxAge: 3600 } },
126
+ * },
127
+ * });
128
+ *
129
+ * // In your adapter
130
+ * export default {
131
+ * fetch: handler.fetch,
132
+ * };
133
+ * ```
134
+ */
135
+ declare function createUniversalHandler(options?: UniversalHandlerOptions): UniversalHandler;
136
+
1
137
  /**
2
138
  * Flight Adapters - Universal deployment adapters
3
139
  *
@@ -117,6 +253,7 @@ interface AdapterOptions {
117
253
  * ```
118
254
  */
119
255
  declare function createAdapter(options: AdapterOptions): FlightAdapter;
256
+
120
257
  /**
121
258
  * Storage Adapter Interface
122
259
  *
@@ -240,4 +377,4 @@ interface DatabaseAdapter {
240
377
  transaction?<T>(fn: (tx: DatabaseAdapter) => Promise<T>): Promise<T>;
241
378
  }
242
379
 
243
- export { type AdapterBuilder, type AdapterOptions, type AuthAdapter, type AuthSession, type AuthUser, type BuildManifest, type DatabaseAdapter, type EmailAdapter, type FlightAdapter, type JobsAdapter, type RouteManifestEntry, type StorageAdapter, createAdapter };
380
+ export { type AdapterBuilder, type AdapterOptions, type AuthAdapter, type AuthSession, type AuthUser, type BuildManifest, type CorsOptions, type DatabaseAdapter, type EmailAdapter, type FlightAdapter, type HandlerHooks, type JobsAdapter, type RouteManifest, type RouteManifestEntry, type RouteRuleConfig, type RouteRules, type StorageAdapter, type UniversalHandler, type UniversalHandlerOptions, createAdapter, createUniversalHandler };
@@ -1,3 +1,3 @@
1
- export { createAdapter } from '../chunk-QK6UEQ75.js';
1
+ export { createAdapter, createUniversalHandler } from '../chunk-K5NYYNFS.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -1,3 +1,3 @@
1
- export { cacheKey, cached, createCache, dedupe, jsonSerializer, memory } from '../chunk-LKOPJ3GS.js';
1
+ export { cacheKey, cached, createCache, dedupe, jsonSerializer, memory } from '../chunk-R7SQAREQ.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -221,5 +221,5 @@ function markAsVueClientComponent(component, moduleId, exportName = "default") {
221
221
  }
222
222
 
223
223
  export { createVueAdapter, createVueConsumer, markAsVueClientComponent };
224
- //# sourceMappingURL=chunk-3UQJE3XZ.js.map
225
- //# sourceMappingURL=chunk-3UQJE3XZ.js.map
224
+ //# sourceMappingURL=chunk-2F2QU6RC.js.map
225
+ //# sourceMappingURL=chunk-2F2QU6RC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/rsc/adapters/vue.ts"],"names":["children"],"mappings":"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","file":"chunk-2F2QU6RC.js","sourcesContent":["/**\r\n * @flight-framework/core - Vue UI Adapter\r\n * \r\n * Adapter for using Vue 3 with Flight Server Components.\r\n * Enables Flight to render Vue components without tight coupling.\r\n * \r\n * Philosophy: Zero lock-in - Vue is optional, user decides.\r\n * \r\n * @module @flight-framework/core/rsc/adapters/vue\r\n */\r\n\r\nimport type { UIAdapter, ElementTypeInfo } from '../renderer.js';\r\n\r\n// ============================================================================\r\n// Vue Symbols (Vue 3 internal markers)\r\n// ============================================================================\r\n\r\nconst VUE_FRAGMENT = Symbol.for('v-fgt');\r\nconst VUE_TEXT = Symbol.for('v-txt');\r\nconst VUE_COMMENT = Symbol.for('v-cmt');\r\nconst VUE_SUSPENSE = Symbol.for('v-sus');\r\nconst VUE_TELEPORT = Symbol.for('v-tel');\r\n\r\n// Flight reference symbols\r\nconst CLIENT_REFERENCE = Symbol.for('flight.client.reference');\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Minimal Vue VNode interface\r\n */\r\ninterface VueVNode {\r\n __v_isVNode?: boolean;\r\n type: unknown;\r\n props: Record<string, unknown> | null;\r\n children: unknown;\r\n key: string | number | null;\r\n component?: unknown;\r\n shapeFlag?: number;\r\n}\r\n\r\n/**\r\n * Vue dependencies (user provides these)\r\n */\r\nexport interface VueDependencies {\r\n /** Vue module */\r\n Vue: {\r\n h: (type: unknown, props?: unknown, children?: unknown) => VueVNode;\r\n isVNode: (value: unknown) => boolean;\r\n createSSRApp?: (rootComponent: unknown) => unknown;\r\n Fragment?: symbol;\r\n Suspense?: unknown;\r\n Text?: symbol;\r\n };\r\n /** renderToString from vue/server-renderer (optional - for SSR) */\r\n renderToString?: (app: unknown) => Promise<string>;\r\n}\r\n\r\n// ============================================================================\r\n// Adapter Implementation\r\n// ============================================================================\r\n\r\n/**\r\n * Create Vue UI Adapter\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createVueAdapter } from '@flight-framework/core/rsc/adapters/vue';\r\n * import * as Vue from 'vue';\r\n * import { renderToString } from 'vue/server-renderer';\r\n * \r\n * const adapter = createVueAdapter({\r\n * Vue,\r\n * renderToString,\r\n * });\r\n * \r\n * const renderer = createRenderer(adapter);\r\n * ```\r\n */\r\nexport function createVueAdapter(deps?: VueDependencies): UIAdapter {\r\n const { Vue, renderToString } = deps || {};\r\n\r\n return {\r\n name: 'vue',\r\n\r\n isElement(value: unknown): boolean {\r\n if (Vue?.isVNode) {\r\n return Vue.isVNode(value);\r\n }\r\n // Fallback: check for __v_isVNode marker\r\n return (\r\n typeof value === 'object' &&\r\n value !== null &&\r\n (value as VueVNode).__v_isVNode === true\r\n );\r\n },\r\n\r\n getElementType(element: unknown): ElementTypeInfo {\r\n const vnode = element as VueVNode;\r\n const type = vnode.type;\r\n\r\n // String = host element (div, span, etc.)\r\n if (typeof type === 'string') {\r\n return { kind: 'host', tag: type };\r\n }\r\n\r\n // Symbol types\r\n if (typeof type === 'symbol') {\r\n // Fragment\r\n if (type === VUE_FRAGMENT || type === Vue?.Fragment) {\r\n return { kind: 'fragment' };\r\n }\r\n\r\n // Text\r\n if (type === VUE_TEXT || type === Vue?.Text) {\r\n const children = vnode.children;\r\n return {\r\n kind: 'text',\r\n value: String(children ?? '')\r\n };\r\n }\r\n\r\n // Comment\r\n if (type === VUE_COMMENT) {\r\n return { kind: 'null' };\r\n }\r\n\r\n // Suspense\r\n if (type === VUE_SUSPENSE) {\r\n return {\r\n kind: 'suspense',\r\n fallback: vnode.props?.fallback\r\n };\r\n }\r\n\r\n // Teleport (treat as fragment for RSC)\r\n if (type === VUE_TELEPORT) {\r\n return { kind: 'fragment' };\r\n }\r\n\r\n return { kind: 'null' };\r\n }\r\n\r\n // Object component (Options API or async component)\r\n if (typeof type === 'object' && type !== null) {\r\n const comp = type as {\r\n name?: string;\r\n setup?: unknown;\r\n render?: unknown;\r\n __asyncLoader?: unknown;\r\n };\r\n\r\n // Async component\r\n if (comp.__asyncLoader) {\r\n return {\r\n kind: 'component',\r\n fn: () => null,\r\n name: comp.name || 'AsyncComponent'\r\n };\r\n }\r\n\r\n // Options API component\r\n if (comp.setup || comp.render) {\r\n return {\r\n kind: 'component',\r\n fn: (_props) => {\r\n // Vue components need to be rendered differently\r\n // This is a placeholder - actual rendering uses renderToString\r\n return null;\r\n },\r\n name: comp.name || 'VueComponent',\r\n };\r\n }\r\n }\r\n\r\n // Function component (Composition API)\r\n if (typeof type === 'function') {\r\n const fn = type as ((props: Record<string, unknown>) => unknown) & {\r\n displayName?: string;\r\n name?: string;\r\n __name?: string;\r\n };\r\n return {\r\n kind: 'component',\r\n fn,\r\n name: fn.displayName || fn.__name || fn.name || 'Component'\r\n };\r\n }\r\n\r\n return { kind: 'null' };\r\n },\r\n\r\n getProps(element: unknown): Record<string, unknown> {\r\n const vnode = element as VueVNode;\r\n return vnode.props || {};\r\n },\r\n\r\n getChildren(element: unknown): unknown[] {\r\n const vnode = element as VueVNode;\r\n const children = vnode.children;\r\n\r\n if (children === undefined || children === null) {\r\n return [];\r\n }\r\n\r\n // String children\r\n if (typeof children === 'string' || typeof children === 'number') {\r\n return [children];\r\n }\r\n\r\n // Array children\r\n if (Array.isArray(children)) {\r\n return children.flat();\r\n }\r\n\r\n // Slots object\r\n if (typeof children === 'object' && children !== null) {\r\n const slots = children as Record<string, () => unknown[]>;\r\n if (typeof slots.default === 'function') {\r\n return slots.default();\r\n }\r\n }\r\n\r\n return [children];\r\n },\r\n\r\n getKey(element: unknown): string | number | undefined {\r\n const key = (element as VueVNode).key;\r\n return key !== null ? key : undefined;\r\n },\r\n\r\n isClientBoundary(component: unknown): boolean {\r\n if (typeof component !== 'function' && typeof component !== 'object') {\r\n return false;\r\n }\r\n\r\n const comp = component as {\r\n $$typeof?: symbol;\r\n __flight_client?: boolean;\r\n };\r\n\r\n // Check for Flight client marker\r\n if (comp.__flight_client === true) return true;\r\n\r\n // Check for client reference symbol\r\n if (comp.$$typeof === CLIENT_REFERENCE) return true;\r\n\r\n return false;\r\n },\r\n\r\n createElement(\r\n component: (props: Record<string, unknown>) => unknown,\r\n props: Record<string, unknown>\r\n ): unknown {\r\n // Create a Vue VNode using h() if available\r\n if (Vue?.h) {\r\n return Vue.h(component, props);\r\n }\r\n\r\n // Fallback: create VNode structure directly\r\n return {\r\n __v_isVNode: true,\r\n type: component,\r\n props,\r\n key: null,\r\n children: props.children ?? null,\r\n } as VueVNode;\r\n },\r\n\r\n async renderToString(element: unknown): Promise<string> {\r\n if (renderToString && Vue?.createSSRApp) {\r\n // Create SSR app wrapper\r\n const app = Vue.createSSRApp({\r\n render: () => element\r\n });\r\n return renderToString(app);\r\n }\r\n throw new Error(\r\n 'renderToString not provided. Pass Vue and renderToString when creating the adapter: ' +\r\n 'createVueAdapter({ Vue, renderToString })'\r\n );\r\n },\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Vue Client Consumer\r\n// ============================================================================\r\n\r\n/**\r\n * Options for Vue consumer\r\n */\r\nexport interface VueConsumerOptions {\r\n /** Registry of client components */\r\n registry?: Map<string, () => Promise<unknown>>;\r\n}\r\n\r\n/**\r\n * Create a Vue client-side consumer for Flight payloads\r\n */\r\nexport function createVueConsumer(deps: VueDependencies, options: VueConsumerOptions = {}) {\r\n const { Vue } = deps;\r\n const { registry = new Map() } = options;\r\n\r\n return {\r\n /**\r\n * Register a client component\r\n */\r\n register(id: string, loader: () => Promise<unknown>): void {\r\n registry.set(id, loader);\r\n },\r\n\r\n /**\r\n * Convert Flight elements to Vue VNodes\r\n */\r\n toVueElement(element: import('../payload.js').FlightElement): unknown {\r\n switch (element.$$type) {\r\n case 'null':\r\n return null;\r\n\r\n case 'text':\r\n return element.value;\r\n\r\n case 'host': {\r\n const children = element.children.map(c => this.toVueElement(c));\r\n return Vue.h(\r\n element.tag,\r\n { ...element.props, key: element.key },\r\n children\r\n );\r\n }\r\n\r\n case 'fragment': {\r\n const children = element.children.map(c => this.toVueElement(c));\r\n return Vue.h(Vue.Fragment!, null, children);\r\n }\r\n\r\n case 'suspense': {\r\n if (Vue.Suspense) {\r\n const fallback = this.toVueElement(element.fallback);\r\n const children = element.children.map(c => this.toVueElement(c));\r\n return Vue.h(Vue.Suspense, null, {\r\n default: () => children,\r\n fallback: () => fallback,\r\n });\r\n }\r\n // Fallback: render children directly\r\n const children = element.children.map(c => this.toVueElement(c));\r\n return Vue.h(Vue.Fragment!, null, children);\r\n }\r\n\r\n case 'client': {\r\n const loader = registry.get(element.ref);\r\n if (!loader) {\r\n console.warn(`[Flight] Client component not registered: ${element.ref}`);\r\n if (element.ssr) {\r\n return Vue.h('div', {\r\n innerHTML: element.ssr\r\n });\r\n }\r\n return null;\r\n }\r\n\r\n // Create async component\r\n const AsyncComponent = {\r\n async setup() {\r\n const mod = await loader() as { default?: unknown };\r\n return () => Vue.h(mod.default ?? mod as unknown);\r\n }\r\n };\r\n\r\n return Vue.h(AsyncComponent);\r\n }\r\n\r\n case 'lazy': {\r\n if (element.fallback) {\r\n return this.toVueElement(element.fallback);\r\n }\r\n return Vue.h('div', { 'data-flight-pending': element.id });\r\n }\r\n\r\n default:\r\n return null;\r\n }\r\n },\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Utility Types\r\n// ============================================================================\r\n\r\n/**\r\n * Type helper for Vue Server Component\r\n */\r\nexport type VueServerComponent<P = Record<string, unknown>> = (\r\n props: P,\r\n ctx: import('../context.js').ServerContext\r\n) => Promise<VueVNode> | VueVNode;\r\n\r\n/**\r\n * Mark a Vue component as a client component\r\n */\r\nexport function markAsVueClientComponent<T extends object>(\r\n component: T,\r\n moduleId: string,\r\n exportName = 'default'\r\n): T {\r\n const marked = component as T & {\r\n $$typeof: symbol;\r\n __flight_client: boolean;\r\n __flight_module: string;\r\n __flight_export: string;\r\n };\r\n\r\n marked.$$typeof = CLIENT_REFERENCE;\r\n marked.__flight_client = true;\r\n marked.__flight_module = moduleId;\r\n marked.__flight_export = exportName;\r\n\r\n return marked;\r\n}\r\n"]}
@@ -424,5 +424,5 @@ function pathMatches(routePath, actualPath) {
424
424
  }
425
425
 
426
426
  export { createFileRouter, extractRouteParams, findInterceptingRoute, getSlotDefault, getSlotNames, loadRoutes, resolveParallelSlots, scanRoutes, shouldDismissIntercept };
427
- //# sourceMappingURL=chunk-4U7CJVNQ.js.map
428
- //# sourceMappingURL=chunk-4U7CJVNQ.js.map
427
+ //# sourceMappingURL=chunk-3KRBRSRJ.js.map
428
+ //# sourceMappingURL=chunk-3KRBRSRJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/file-router/index.ts"],"names":[],"mappings":"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","file":"chunk-3KRBRSRJ.js","sourcesContent":["/**\r\n * @flight-framework/core - File Router\r\n * \r\n * Auto-discovery of routes from file system.\r\n * Similar to Next.js App Router and Nuxt server/api patterns.\r\n */\r\n\r\nimport { readdir } from 'node:fs/promises';\r\nimport { join, basename, extname } from 'node:path';\r\nimport { pathToFileURL } from 'node:url';\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';\r\n\r\nexport type Handler = (context: unknown) => Response | Promise<Response>;\r\nexport type Middleware = (context: unknown, next: () => Promise<Response>) => Response | Promise<Response>;\r\n\r\nexport interface FileRoute {\r\n /** HTTP method (GET, POST, etc) or 'ALL' */\r\n method: HttpMethod | 'ALL';\r\n /** Route path with params (e.g., /users/:id) */\r\n path: string;\r\n /** Original file path */\r\n filePath: string;\r\n /** Handler function (for APIs) */\r\n handler?: Handler;\r\n /** Route-specific middleware */\r\n middleware?: Middleware[];\r\n /** Route type: 'page' for SSR pages, 'api' for API endpoints */\r\n type: 'page' | 'api';\r\n /** Component function (for pages) */\r\n component?: () => unknown;\r\n /** Page metadata (title, description, etc) */\r\n meta?: Record<string, unknown>;\r\n /** Parallel route slot name (for @folder convention) */\r\n slot?: string;\r\n /** Intercepting route info (for (.) (..) (...) convention) */\r\n interceptInfo?: {\r\n /** Number of levels to intercept: 1 = same, 2 = parent, 3+ = root */\r\n level: number;\r\n /** Target route segment to intercept */\r\n target: string;\r\n /** Original path that triggers interception */\r\n interceptPath: string;\r\n };\r\n}\r\n\r\nexport interface FileRouterOptions {\r\n /** Root directory to scan (default: src/routes) */\r\n directory: string;\r\n /** File extensions to consider (default: ['.ts', '.js']) */\r\n extensions?: string[];\r\n /** Whether to watch for changes (default: false in prod) */\r\n watch?: boolean;\r\n /** \r\n * Custom module loader for development with Vite.\r\n * Pass vite.ssrLoadModule to load TSX files correctly.\r\n * Falls back to native import() if not provided.\r\n */\r\n moduleLoader?: (filePath: string) => Promise<any>;\r\n}\r\n\r\nexport interface ScanResult {\r\n routes: FileRoute[];\r\n errors: string[];\r\n}\r\n\r\n// ============================================================================\r\n// File Scanner\r\n// ============================================================================\r\n\r\n/**\r\n * Scan a directory for route files\r\n */\r\nexport async function scanRoutes(options: FileRouterOptions): Promise<ScanResult> {\r\n const {\r\n directory,\r\n extensions = ['.ts', '.js'],\r\n } = options;\r\n\r\n const routes: FileRoute[] = [];\r\n const errors: string[] = [];\r\n\r\n async function scanDir(dir: string, basePath: string = ''): Promise<void> {\r\n try {\r\n const entries = await readdir(dir, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n const fullPath = join(dir, entry.name);\r\n\r\n if (entry.isDirectory()) {\r\n // Skip hidden directories and node_modules\r\n if (entry.name.startsWith('.') || entry.name === 'node_modules') {\r\n continue;\r\n }\r\n\r\n // Detect parallel route slots (@folder convention)\r\n if (entry.name.startsWith('@')) {\r\n const slotName = entry.name.slice(1);\r\n // Scan slot directory and mark routes with slot name\r\n const slotRoutes = await scanSlotDir(fullPath, basePath, slotName, extensions);\r\n routes.push(...slotRoutes);\r\n continue;\r\n }\r\n\r\n // Detect intercepting routes ((.) (..) (...) convention)\r\n const interceptMatch = entry.name.match(/^\\((\\.+)\\)(.+)$/);\r\n if (interceptMatch) {\r\n const level = interceptMatch[1].length;\r\n const targetSegment = interceptMatch[2];\r\n // Scan intercept directory and mark routes with interceptInfo\r\n const interceptRoutes = await scanInterceptDir(\r\n fullPath,\r\n basePath,\r\n level,\r\n targetSegment,\r\n extensions\r\n );\r\n routes.push(...interceptRoutes);\r\n continue;\r\n }\r\n\r\n // Detect route groups ((groupName) without dots - organizational only)\r\n // Route groups allow organizing routes without affecting URL structure\r\n // Example: (marketing)/about.page.tsx -> /about (not /marketing/about)\r\n const groupMatch = entry.name.match(/^\\(([^.]+)\\)$/);\r\n if (groupMatch) {\r\n // This is a route group - scan contents but don't add group to path\r\n await scanDir(fullPath, basePath);\r\n continue;\r\n }\r\n\r\n // Recurse into subdirectory\r\n await scanDir(fullPath, `${basePath}/${entry.name}`);\r\n } else if (entry.isFile()) {\r\n const ext = extname(entry.name);\r\n\r\n if (!extensions.includes(ext)) {\r\n continue;\r\n }\r\n\r\n // Parse route from filename\r\n const routeInfo = parseRouteFile(entry.name, basePath);\r\n\r\n if (routeInfo && routeInfo.method && routeInfo.path) {\r\n routes.push({\r\n method: routeInfo.method,\r\n path: routeInfo.path,\r\n filePath: fullPath,\r\n type: routeInfo.type,\r\n });\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n errors.push(`Failed to scan ${dir}: ${error}`);\r\n }\r\n }\r\n\r\n await scanDir(directory);\r\n\r\n return { routes, errors };\r\n}\r\n\r\n/**\r\n * Scan a parallel route slot directory\r\n */\r\nasync function scanSlotDir(\r\n dir: string,\r\n basePath: string,\r\n slotName: string,\r\n extensions: string[] = ['.ts', '.js', '.tsx', '.jsx']\r\n): Promise<FileRoute[]> {\r\n const routes: FileRoute[] = [];\r\n\r\n try {\r\n const entries = await readdir(dir, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n const fullPath = join(dir, entry.name);\r\n\r\n if (entry.isFile()) {\r\n const ext = extname(entry.name);\r\n\r\n if (!extensions.includes(ext)) {\r\n continue;\r\n }\r\n\r\n const routeInfo = parseRouteFile(entry.name, basePath);\r\n\r\n if (routeInfo && routeInfo.method && routeInfo.path) {\r\n routes.push({\r\n method: routeInfo.method,\r\n path: routeInfo.path,\r\n filePath: fullPath,\r\n type: routeInfo.type,\r\n slot: slotName,\r\n });\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n console.error(`[Flight] Failed to scan slot @${slotName}:`, error);\r\n }\r\n\r\n return routes;\r\n}\r\n\r\n/**\r\n * Scan an intercepting route directory\r\n * Uses (.) (..) (...) convention similar to Next.js\r\n * - (.)segment - intercepts from same level\r\n * - (..)segment - intercepts from parent level\r\n * - (...)segment - intercepts from root\r\n */\r\nasync function scanInterceptDir(\r\n dir: string,\r\n basePath: string,\r\n level: number,\r\n targetSegment: string,\r\n extensions: string[] = ['.ts', '.js', '.tsx', '.jsx']\r\n): Promise<FileRoute[]> {\r\n const routes: FileRoute[] = [];\r\n\r\n // Calculate the intercept path based on level\r\n const pathParts = basePath.split('/').filter(Boolean);\r\n let interceptPath: string;\r\n\r\n if (level === 1) {\r\n // (.) - Same level, intercepts sibling route\r\n interceptPath = `${basePath}/${targetSegment}`;\r\n } else if (level === 2) {\r\n // (..) - Parent level\r\n pathParts.pop();\r\n interceptPath = `/${pathParts.join('/')}/${targetSegment}`;\r\n } else {\r\n // (...) - Root level (3 or more dots)\r\n interceptPath = `/${targetSegment}`;\r\n }\r\n\r\n try {\r\n const entries = await readdir(dir, { withFileTypes: true });\r\n\r\n for (const entry of entries) {\r\n const fullPath = join(dir, entry.name);\r\n\r\n if (entry.isFile()) {\r\n const ext = extname(entry.name);\r\n\r\n if (!extensions.includes(ext)) {\r\n continue;\r\n }\r\n\r\n const routeInfo = parseRouteFile(entry.name, basePath);\r\n\r\n if (routeInfo && routeInfo.method && routeInfo.path) {\r\n routes.push({\r\n method: routeInfo.method,\r\n path: routeInfo.path,\r\n filePath: fullPath,\r\n type: routeInfo.type,\r\n interceptInfo: {\r\n level,\r\n target: targetSegment,\r\n interceptPath: interceptPath.replace(/\\/+/g, '/') || '/',\r\n },\r\n });\r\n }\r\n } else if (entry.isDirectory()) {\r\n // Recurse into subdirectories within intercept folder\r\n const subRoutes = await scanInterceptDir(\r\n fullPath,\r\n `${basePath}/${entry.name}`,\r\n level,\r\n targetSegment,\r\n extensions\r\n );\r\n routes.push(...subRoutes);\r\n }\r\n }\r\n } catch (error) {\r\n console.error(`[Flight] Failed to scan intercept (${'.'.repeat(level)})${targetSegment}:`, error);\r\n }\r\n\r\n return routes;\r\n}\r\n\r\n// ============================================================================\r\n// Route Parser\r\n// ============================================================================\r\n\r\ninterface ParsedRoute {\r\n method: HttpMethod | 'ALL';\r\n path: string;\r\n type: 'page' | 'api';\r\n}\r\n\r\n/**\r\n * Parse route information from filename and path\r\n * \r\n * Patterns:\r\n * - index.ts → /\r\n * - users.ts → /users\r\n * - users.get.ts → GET /users (API)\r\n * - users.post.ts → POST /users (API)\r\n * - about.page.tsx → GET /about (Page)\r\n * - blog/[slug].page.tsx → GET /blog/:slug (Page)\r\n * - [id].ts → /:id\r\n * - [...slug].ts → /* (catch-all)\r\n * - [[...slug]].ts → /* (optional catch-all)\r\n */\r\nfunction parseRouteFile(filename: string, basePath: string): ParsedRoute | null {\r\n const ext = extname(filename);\r\n const nameWithoutExt = basename(filename, ext);\r\n\r\n // Skip files starting with underscore (private)\r\n if (nameWithoutExt.startsWith('_')) {\r\n return null;\r\n }\r\n\r\n // Detect route type\r\n let type: 'page' | 'api' = 'api';\r\n let routeName = nameWithoutExt;\r\n let method: HttpMethod | 'ALL' = 'ALL';\r\n\r\n // Check for page suffix (e.g., about.page.tsx, index.page.tsx)\r\n const pageMatch = nameWithoutExt.match(/^(.+)?\\.page$/i);\r\n if (pageMatch) {\r\n type = 'page';\r\n method = 'GET'; // Pages are always GET\r\n routeName = pageMatch[1] || 'index';\r\n } else {\r\n // Check for method suffix (e.g., users.get.ts)\r\n const methodMatch = nameWithoutExt.match(/^(.+)\\.(get|post|put|delete|patch|head|options)$/i);\r\n if (methodMatch) {\r\n routeName = methodMatch[1] || nameWithoutExt;\r\n method = (methodMatch[2] || 'ALL').toUpperCase() as HttpMethod;\r\n }\r\n }\r\n\r\n // Also check if file is in /api/ directory\r\n if (basePath.startsWith('/api') || basePath.includes('/api/')) {\r\n type = 'api';\r\n }\r\n\r\n // Build route path\r\n let path = basePath;\r\n\r\n if (routeName !== 'index') {\r\n path = `${basePath}/${convertToRoutePath(routeName)}`;\r\n }\r\n\r\n // Ensure path starts with /\r\n if (!path.startsWith('/')) {\r\n path = '/' + path;\r\n }\r\n\r\n // Remove trailing slash (except for root)\r\n if (path !== '/' && path.endsWith('/')) {\r\n path = path.slice(0, -1);\r\n }\r\n\r\n return { method, path, type };\r\n}\r\n\r\n/**\r\n * Convert filename segment to route path segment\r\n * \r\n * - [id] → :id\r\n * - [...slug] → *\r\n * - [[...slug]] → *?\r\n */\r\nfunction convertToRoutePath(name: string): string {\r\n // Optional catch-all: [[...slug]]\r\n if (name.startsWith('[[...') && name.endsWith(']]')) {\r\n const paramName = name.slice(5, -2);\r\n return `:${paramName}*`;\r\n }\r\n\r\n // Catch-all: [...slug]\r\n if (name.startsWith('[...') && name.endsWith(']')) {\r\n const paramName = name.slice(4, -1);\r\n return `:${paramName}+`;\r\n }\r\n\r\n // Dynamic param: [id]\r\n if (name.startsWith('[') && name.endsWith(']')) {\r\n const paramName = name.slice(1, -1);\r\n return `:${paramName}`;\r\n }\r\n\r\n return name;\r\n}\r\n\r\n// ============================================================================\r\n// Route Loader\r\n// ============================================================================\r\n\r\n/**\r\n * Load routes with their handlers or components\r\n * @param scanResult - Result from scanRoutes\r\n * @param moduleLoader - Optional custom loader (use vite.ssrLoadModule for dev)\r\n */\r\nexport async function loadRoutes(\r\n scanResult: ScanResult,\r\n moduleLoader?: (filePath: string) => Promise<any>\r\n): Promise<FileRoute[]> {\r\n const loadedRoutes: FileRoute[] = [];\r\n\r\n for (const route of scanResult.routes) {\r\n try {\r\n // Use custom loader if provided (Vite ssrLoadModule for TSX)\r\n // Otherwise fall back to native import() for production\r\n let module: any;\r\n if (moduleLoader) {\r\n module = await moduleLoader(route.filePath);\r\n } else {\r\n // Convert to file:// URL for Windows ESM compatibility\r\n const fileUrl = pathToFileURL(route.filePath).href;\r\n module = await import(fileUrl);\r\n }\r\n\r\n // Handle PAGE routes\r\n if (route.type === 'page') {\r\n // Pages export default component\r\n const component = module.default;\r\n const meta = module.meta || module.metadata || {};\r\n\r\n if (component) {\r\n loadedRoutes.push({\r\n ...route,\r\n component,\r\n meta,\r\n });\r\n }\r\n continue;\r\n }\r\n\r\n // Handle API routes\r\n if (route.method === 'ALL') {\r\n // Look for named exports: GET, POST, PUT, DELETE, etc\r\n const methods: HttpMethod[] = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'];\r\n\r\n for (const method of methods) {\r\n if (typeof module[method] === 'function') {\r\n loadedRoutes.push({\r\n ...route,\r\n method,\r\n handler: module[method],\r\n });\r\n }\r\n }\r\n\r\n // Also check for default export as handler\r\n if (typeof module.default === 'function') {\r\n loadedRoutes.push({\r\n ...route,\r\n method: 'ALL',\r\n handler: module.default,\r\n });\r\n }\r\n } else {\r\n // Specific method from filename suffix\r\n const handler = module[route.method] || module.default;\r\n\r\n if (typeof handler === 'function') {\r\n loadedRoutes.push({\r\n ...route,\r\n handler,\r\n });\r\n }\r\n }\r\n } catch (error) {\r\n console.error(`[Flight] Failed to load route ${route.filePath}:`, error);\r\n }\r\n }\r\n\r\n return loadedRoutes;\r\n}\r\n\r\n// ============================================================================\r\n// File Router Factory\r\n// ============================================================================\r\n\r\nexport interface FileRouter {\r\n routes: FileRoute[];\r\n refresh: () => Promise<void>;\r\n}\r\n\r\n/**\r\n * Create a file-based router\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createFileRouter } from '@flight-framework/core/file-router';\r\n * import { createServer } from '@flight-framework/http';\r\n * \r\n * const router = await createFileRouter({ directory: './src/routes' });\r\n * const app = createServer();\r\n * \r\n * // Register all discovered routes\r\n * for (const route of router.routes) {\r\n * app[route.method.toLowerCase()](route.path, route.handler);\r\n * }\r\n * ```\r\n */\r\nexport async function createFileRouter(options: FileRouterOptions): Promise<FileRouter> {\r\n let routes: FileRoute[] = [];\r\n const { moduleLoader } = options;\r\n\r\n async function refresh(): Promise<void> {\r\n const scanResult = await scanRoutes(options);\r\n\r\n if (scanResult.errors.length > 0) {\r\n console.warn('[Flight] Route scan errors:', scanResult.errors);\r\n }\r\n\r\n routes = await loadRoutes(scanResult, moduleLoader);\r\n\r\n console.log(`[Flight] Loaded ${routes.length} routes from ${options.directory}`);\r\n }\r\n\r\n // Initial load\r\n await refresh();\r\n\r\n return {\r\n get routes() {\r\n return routes;\r\n },\r\n refresh,\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Parallel Routes Resolution\r\n// ============================================================================\r\n\r\n/**\r\n * Resolved parallel route slots for a layout.\r\n * Each slot name maps to its resolved component or null if not matched.\r\n */\r\nexport interface ResolvedSlots {\r\n [slotName: string]: {\r\n /** The component to render */\r\n component: () => unknown;\r\n /** The full route information */\r\n route: FileRoute;\r\n } | null;\r\n}\r\n\r\n/**\r\n * Resolve parallel route slots for a given path.\r\n * \r\n * Parallel routes use the @folder convention to define named slots\r\n * that can render alongside the main content in a layout.\r\n * \r\n * @param routes - All loaded routes from the file router\r\n * @param currentPath - The current URL path to resolve slots for\r\n * @returns Object mapping slot names to their resolved components\r\n * \r\n * @example\r\n * ```typescript\r\n * // Given routes from @modal/ and @sidebar/ directories\r\n * const slots = resolveParallelSlots(router.routes, '/dashboard');\r\n * \r\n * // In layout:\r\n * if (slots.modal) {\r\n * renderModal(slots.modal.component);\r\n * }\r\n * ```\r\n */\r\nexport function resolveParallelSlots(\r\n routes: FileRoute[],\r\n currentPath: string\r\n): ResolvedSlots {\r\n const slots: ResolvedSlots = {};\r\n const normalizedPath = normalizePath(currentPath);\r\n\r\n // Get all unique slot names from routes\r\n const slotNames = new Set<string>();\r\n for (const route of routes) {\r\n if (route.slot) {\r\n slotNames.add(route.slot);\r\n }\r\n }\r\n\r\n // For each slot, find matching route or default\r\n for (const slotName of slotNames) {\r\n const slotRoutes = routes.filter(r => r.slot === slotName);\r\n\r\n // Find exact match for current path\r\n let matchingRoute = slotRoutes.find(r => {\r\n const routePath = normalizePath(r.path);\r\n return pathMatches(routePath, normalizedPath);\r\n });\r\n\r\n // If no match, look for default.page in the slot\r\n if (!matchingRoute) {\r\n matchingRoute = slotRoutes.find(r =>\r\n r.path.endsWith('/default') || r.filePath.includes('default.page')\r\n );\r\n }\r\n\r\n if (matchingRoute && matchingRoute.component) {\r\n slots[slotName] = {\r\n component: matchingRoute.component,\r\n route: matchingRoute,\r\n };\r\n } else {\r\n // Slot has no matching content for this path\r\n slots[slotName] = null;\r\n }\r\n }\r\n\r\n return slots;\r\n}\r\n\r\n/**\r\n * Get the default page for an unmatched slot.\r\n * \r\n * When a parallel route slot doesn't have a matching route for the current path,\r\n * it should render its default.page if one exists, or null.\r\n * \r\n * @param routes - All loaded routes\r\n * @param slotName - Name of the slot (without @)\r\n * @param basePath - Base path to search from\r\n * @returns The default route for the slot, or null\r\n */\r\nexport function getSlotDefault(\r\n routes: FileRoute[],\r\n slotName: string,\r\n basePath: string = ''\r\n): FileRoute | null {\r\n const normalizedBase = normalizePath(basePath);\r\n\r\n return routes.find(r =>\r\n r.slot === slotName &&\r\n (r.filePath.includes('default.page') || r.path === `${normalizedBase}/default`)\r\n ) || null;\r\n}\r\n\r\n/**\r\n * Get all slot names used in the routes.\r\n * \r\n * @param routes - All loaded routes\r\n * @returns Array of unique slot names\r\n */\r\nexport function getSlotNames(routes: FileRoute[]): string[] {\r\n const names = new Set<string>();\r\n for (const route of routes) {\r\n if (route.slot) {\r\n names.add(route.slot);\r\n }\r\n }\r\n return Array.from(names);\r\n}\r\n\r\n// ============================================================================\r\n// Intercepting Routes Resolution\r\n// ============================================================================\r\n\r\n/**\r\n * Check if a navigation should be intercepted by an intercepting route.\r\n * \r\n * Intercepting routes use the (.) (..) (...) convention:\r\n * - (.)segment - intercepts from same level\r\n * - (..)segment - intercepts from parent level \r\n * - (...)segment - intercepts from root\r\n * \r\n * @param routes - All loaded routes\r\n * @param fromPath - Current path where navigation originates\r\n * @param toPath - Target path the user wants to navigate to\r\n * @returns The intercepting route if found, null otherwise\r\n * \r\n * @example\r\n * ```typescript\r\n * // User is on /feed and clicks link to /photo/123\r\n * const intercepted = findInterceptingRoute(routes, '/feed', '/photo/123');\r\n * \r\n * if (intercepted) {\r\n * // Render intercepted.component as modal instead of navigating\r\n * showModal(intercepted);\r\n * }\r\n * ```\r\n */\r\nexport function findInterceptingRoute(\r\n routes: FileRoute[],\r\n fromPath: string,\r\n toPath: string\r\n): FileRoute | null {\r\n const normalizedFrom = normalizePath(fromPath);\r\n const normalizedTo = normalizePath(toPath);\r\n\r\n // Filter to only intercepting routes\r\n const interceptingRoutes = routes.filter(r => r.interceptInfo);\r\n\r\n for (const route of interceptingRoutes) {\r\n const { interceptInfo } = route;\r\n if (!interceptInfo) continue;\r\n\r\n // Check if the interceptPath matches the target path\r\n const interceptPath = normalizePath(interceptInfo.interceptPath);\r\n\r\n if (!pathMatches(interceptPath, normalizedTo)) {\r\n continue;\r\n }\r\n\r\n // Check if we're navigating from a valid origin based on level\r\n // For level 1 (.), the intercept route is at same level as navigation origin\r\n // For level 2 (..), the intercept route is one level up from navigation origin\r\n // For level 3+ (...), intercepts from anywhere\r\n\r\n let validOrigin = false;\r\n\r\n // Find the intercept marker position in route path\r\n // Route path example: /feed/(.)photo/:id -> base is /feed\r\n const routePathStr = normalizePath(route.path);\r\n const interceptMarkerMatch = routePathStr.match(/\\/\\(\\.+\\)/);\r\n\r\n if (interceptInfo.level >= 3) {\r\n // (...) - Root level: intercepts from anywhere\r\n validOrigin = true;\r\n } else if (interceptMarkerMatch && interceptMarkerMatch.index !== undefined) {\r\n // Extract the base path before the intercept marker\r\n const routeBase = routePathStr.substring(0, interceptMarkerMatch.index);\r\n\r\n if (interceptInfo.level === 1) {\r\n // (.) - Same level: origin should be at or under the route base\r\n // Route at /feed/(.)photo, origin should be /feed or /feed/*\r\n validOrigin = normalizedFrom === routeBase ||\r\n normalizedFrom.startsWith(routeBase + '/') ||\r\n (routeBase === '' && normalizedFrom.startsWith('/'));\r\n } else if (interceptInfo.level === 2) {\r\n // (..) - Parent level: origin is one level deeper\r\n // Route at /gallery/albums/(..)photo, origin should be /gallery/albums/*\r\n validOrigin = normalizedFrom === routeBase ||\r\n normalizedFrom.startsWith(routeBase + '/');\r\n }\r\n }\r\n\r\n if (validOrigin) {\r\n return route;\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Check if an intercepting route should be dismissed on this navigation.\r\n * \r\n * @param currentRoute - The currently active intercepting route\r\n * @param toPath - The path being navigated to\r\n * @returns true if the interception should be dismissed\r\n */\r\nexport function shouldDismissIntercept(\r\n currentRoute: FileRoute | null,\r\n toPath: string\r\n): boolean {\r\n if (!currentRoute || !currentRoute.interceptInfo) {\r\n return false;\r\n }\r\n\r\n const normalizedTo = normalizePath(toPath);\r\n const interceptPath = normalizePath(currentRoute.interceptInfo.interceptPath);\r\n\r\n // Dismiss if navigating away from the intercepted path\r\n return !pathMatches(interceptPath, normalizedTo);\r\n}\r\n\r\n/**\r\n * Get route params from a path match.\r\n * \r\n * @param routePath - The route pattern with params (e.g., /photo/:id)\r\n * @param actualPath - The actual URL path (e.g., /photo/123)\r\n * @returns Object with matched params, or null if no match\r\n */\r\nexport function extractRouteParams(\r\n routePath: string,\r\n actualPath: string\r\n): Record<string, string> | null {\r\n const routeParts = routePath.split('/').filter(Boolean);\r\n const actualParts = actualPath.split('/').filter(Boolean);\r\n\r\n if (routeParts.length !== actualParts.length) {\r\n // Check for catch-all\r\n const hasCatchAll = routeParts.some(p => p.endsWith('+') || p.endsWith('*'));\r\n if (!hasCatchAll) {\r\n return null;\r\n }\r\n }\r\n\r\n const params: Record<string, string> = {};\r\n\r\n for (let i = 0; i < routeParts.length; i++) {\r\n const routePart = routeParts[i];\r\n const actualPart = actualParts[i];\r\n\r\n if (!routePart) continue;\r\n\r\n if (routePart.startsWith(':')) {\r\n // Dynamic param\r\n const paramName = routePart.slice(1).replace(/[+*]$/, '');\r\n\r\n if (routePart.endsWith('+') || routePart.endsWith('*')) {\r\n // Catch-all: collect remaining parts\r\n params[paramName] = actualParts.slice(i).join('/');\r\n break;\r\n }\r\n\r\n if (!actualPart) {\r\n if (routePart.endsWith('*')) {\r\n // Optional catch-all, can be empty\r\n params[paramName] = '';\r\n break;\r\n }\r\n return null;\r\n }\r\n\r\n params[paramName] = actualPart;\r\n } else if (routePart !== actualPart) {\r\n return null;\r\n }\r\n }\r\n\r\n return params;\r\n}\r\n\r\n// ============================================================================\r\n// Path Utilities\r\n// ============================================================================\r\n\r\n/**\r\n * Normalize a path for consistent comparison.\r\n */\r\nfunction normalizePath(path: string): string {\r\n let normalized = path.trim();\r\n\r\n // Ensure starts with /\r\n if (!normalized.startsWith('/')) {\r\n normalized = '/' + normalized;\r\n }\r\n\r\n // Remove trailing slash (except for root)\r\n if (normalized !== '/' && normalized.endsWith('/')) {\r\n normalized = normalized.slice(0, -1);\r\n }\r\n\r\n // Remove duplicate slashes\r\n normalized = normalized.replace(/\\/+/g, '/');\r\n\r\n return normalized;\r\n}\r\n\r\n/**\r\n * Check if a route path matches an actual path.\r\n * Handles dynamic segments (:param) and catch-alls.\r\n */\r\nfunction pathMatches(routePath: string, actualPath: string): boolean {\r\n const routeParts = routePath.split('/').filter(Boolean);\r\n const actualParts = actualPath.split('/').filter(Boolean);\r\n\r\n for (let i = 0; i < routeParts.length; i++) {\r\n const routePart = routeParts[i];\r\n const actualPart = actualParts[i];\r\n\r\n if (!routePart) continue;\r\n\r\n // Catch-all segment\r\n if (routePart.startsWith(':') && (routePart.endsWith('+') || routePart.endsWith('*'))) {\r\n return true; // Matches rest of path\r\n }\r\n\r\n // Dynamic segment\r\n if (routePart.startsWith(':')) {\r\n if (!actualPart) return false;\r\n continue; // Any value matches\r\n }\r\n\r\n // Static segment - must match exactly\r\n if (routePart !== actualPart) {\r\n return false;\r\n }\r\n }\r\n\r\n // Check lengths match (unless catch-all was present)\r\n return routeParts.length === actualParts.length;\r\n}\r\n\r\n"]}
@@ -663,5 +663,5 @@ async function handleActionRequest(request) {
663
663
  }
664
664
 
665
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-OZ3EXPLE.js.map
667
- //# sourceMappingURL=chunk-OZ3EXPLE.js.map
666
+ //# sourceMappingURL=chunk-3QP3E7HS.js.map
667
+ //# sourceMappingURL=chunk-3QP3E7HS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/actions/middleware.ts","../src/actions/streaming.ts","../src/actions/queue.ts","../src/actions/index.ts"],"names":[],"mappings":"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","file":"chunk-3QP3E7HS.js","sourcesContent":["/**\r\n * @flight-framework/core - Action Middleware\r\n * \r\n * Agnostic middleware system for Server Actions.\r\n * Flight provides the PRIMITIVES, you build YOUR solution.\r\n * \r\n * @example\r\n * ```typescript\r\n * // Create your own auth middleware (Flight doesn't impose any auth provider)\r\n * const withAuth = createActionMiddleware(async (ctx, next) => {\r\n * const session = await yourAuthProvider.getSession(ctx.headers);\r\n * if (!session) {\r\n * return { success: false, error: 'UNAUTHORIZED' };\r\n * }\r\n * ctx.set('session', session);\r\n * return next();\r\n * });\r\n * \r\n * // Create your own rate limiter (Flight doesn't impose any rate limit provider)\r\n * const withRateLimit = createActionMiddleware(async (ctx, next) => {\r\n * const allowed = await yourRateLimiter.check(ctx.get('session').userId);\r\n * if (!allowed) {\r\n * return { success: false, error: 'RATE_LIMITED' };\r\n * }\r\n * return next();\r\n * });\r\n * \r\n * // Compose them\r\n * const protectedAction = pipeline(withAuth, withRateLimit)(myAction);\r\n * ```\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Action context - holds request data and middleware-set values\r\n */\r\nexport interface ActionContext {\r\n /** Original request (if available) */\r\n readonly request?: Request;\r\n /** Request headers */\r\n readonly headers: Headers;\r\n /** Action ID being executed */\r\n readonly actionId: string;\r\n /** Action arguments */\r\n readonly args: unknown[];\r\n /** Abort signal for cancellation */\r\n readonly signal?: AbortSignal;\r\n\r\n /** Get a value set by previous middleware */\r\n get<T = unknown>(key: string): T | undefined;\r\n /** Set a value for subsequent middleware/action */\r\n set<T = unknown>(key: string, value: T): void;\r\n}\r\n\r\n/**\r\n * Action result following Flight conventions\r\n */\r\nexport interface ActionResult<T = unknown> {\r\n success: boolean;\r\n data?: T;\r\n error?: string;\r\n code?: string;\r\n}\r\n\r\n/**\r\n * Next function to call the next middleware or action\r\n */\r\nexport type ActionNext<T = unknown> = () => Promise<ActionResult<T>>;\r\n\r\n/**\r\n * Middleware handler function\r\n */\r\nexport type ActionMiddlewareHandler<TContext extends ActionContext = ActionContext> = (\r\n ctx: TContext,\r\n next: ActionNext\r\n) => Promise<ActionResult> | ActionResult;\r\n\r\n/**\r\n * A middleware instance\r\n */\r\nexport interface ActionMiddleware {\r\n /** Unique name for debugging */\r\n readonly name: string;\r\n /** The handler function */\r\n readonly handler: ActionMiddlewareHandler;\r\n}\r\n\r\n/**\r\n * An action function\r\n */\r\nexport type Action<TInput = unknown, TOutput = unknown> = (\r\n ...args: TInput extends unknown[] ? TInput : [TInput]\r\n) => Promise<ActionResult<TOutput>>;\r\n\r\n/**\r\n * Options for creating middleware\r\n */\r\nexport interface CreateMiddlewareOptions {\r\n /** Name for debugging/logging */\r\n name?: string;\r\n}\r\n\r\n// ============================================================================\r\n// Action Context Implementation\r\n// ============================================================================\r\n\r\n/**\r\n * Create an action context from request or minimal data\r\n */\r\nexport function createActionContext(options: {\r\n request?: Request;\r\n headers?: Headers;\r\n actionId: string;\r\n args: unknown[];\r\n signal?: AbortSignal;\r\n}): ActionContext {\r\n const store = new Map<string, unknown>();\r\n\r\n return {\r\n request: options.request,\r\n headers: options.headers ?? options.request?.headers ?? new Headers(),\r\n actionId: options.actionId,\r\n args: options.args,\r\n signal: options.signal,\r\n\r\n get<T = unknown>(key: string): T | undefined {\r\n return store.get(key) as T | undefined;\r\n },\r\n\r\n set<T = unknown>(key: string, value: T): void {\r\n store.set(key, value);\r\n },\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Middleware Creation\r\n// ============================================================================\r\n\r\nlet middlewareCounter = 0;\r\n\r\n/**\r\n * Create a reusable action middleware.\r\n * \r\n * Flight provides this PRIMITIVE - you define WHAT the middleware does.\r\n * \r\n * @example\r\n * ```typescript\r\n * // Authentication middleware (you choose the auth provider)\r\n * const withAuth = createActionMiddleware(async (ctx, next) => {\r\n * const token = ctx.headers.get('Authorization');\r\n * const user = await myAuthLib.verify(token); // YOUR auth library\r\n * \r\n * if (!user) {\r\n * return { success: false, error: 'Unauthorized', code: 'AUTH_ERROR' };\r\n * }\r\n * \r\n * ctx.set('user', user);\r\n * return next();\r\n * });\r\n * \r\n * // Validation middleware (you choose the validator)\r\n * const withValidation = (schema: ZodSchema) => createActionMiddleware(\r\n * async (ctx, next) => {\r\n * const result = schema.safeParse(ctx.args[0]);\r\n * if (!result.success) {\r\n * return { success: false, error: 'Validation failed', code: 'VALIDATION_ERROR' };\r\n * }\r\n * return next();\r\n * },\r\n * { name: 'validation' }\r\n * );\r\n * ```\r\n */\r\nexport function createActionMiddleware(\r\n handler: ActionMiddlewareHandler,\r\n options: CreateMiddlewareOptions = {}\r\n): ActionMiddleware {\r\n const name = options.name ?? `middleware_${++middlewareCounter}`;\r\n\r\n return {\r\n name,\r\n handler,\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Pipeline Composition\r\n// ============================================================================\r\n\r\n/**\r\n * Compose multiple middleware into a pipeline that wraps an action.\r\n * \r\n * Middleware executes in order: first middleware runs first.\r\n * Each middleware can:\r\n * - Short-circuit by returning a result without calling next()\r\n * - Transform context for subsequent middleware\r\n * - Wrap the next() call for timing/logging\r\n * \r\n * @example\r\n * ```typescript\r\n * const protectedAction = pipeline(\r\n * withAuth,\r\n * withRateLimit,\r\n * withValidation(UserSchema),\r\n * )(createUserAction);\r\n * \r\n * // Now protectedAction has auth, rate-limit, and validation\r\n * const result = await protectedAction(userData);\r\n * ```\r\n */\r\nexport function pipeline<TInput, TOutput>(\r\n ...middlewares: ActionMiddleware[]\r\n): (action: Action<TInput, TOutput>) => Action<TInput, TOutput> {\r\n return (action: Action<TInput, TOutput>): Action<TInput, TOutput> => {\r\n return async (...args: TInput extends unknown[] ? TInput : [TInput]): Promise<ActionResult<TOutput>> => {\r\n // Create context for this execution\r\n const ctx = createActionContext({\r\n actionId: action.name || 'anonymous',\r\n args: args as unknown[],\r\n });\r\n\r\n // Build the middleware chain\r\n let index = -1;\r\n\r\n const dispatch = async (i: number): Promise<ActionResult<TOutput>> => {\r\n if (i <= index) {\r\n throw new Error('next() called multiple times');\r\n }\r\n index = i;\r\n\r\n if (i < middlewares.length) {\r\n // Execute middleware\r\n const middleware = middlewares[i]!;\r\n return middleware.handler(ctx, () => dispatch(i + 1)) as Promise<ActionResult<TOutput>>;\r\n } else {\r\n // Execute the actual action\r\n return action(...args);\r\n }\r\n };\r\n\r\n return dispatch(0);\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Execute an action with middleware, providing custom context.\r\n * \r\n * Use this when you need to provide request context (headers, etc.)\r\n * \r\n * @example\r\n * ```typescript\r\n * const result = await executeWithMiddleware(\r\n * myAction,\r\n * [arg1, arg2],\r\n * [withAuth, withRateLimit],\r\n * { request: incomingRequest }\r\n * );\r\n * ```\r\n */\r\nexport async function executeWithMiddleware<TInput extends unknown[], TOutput>(\r\n action: (...args: TInput) => Promise<ActionResult<TOutput>>,\r\n args: TInput,\r\n middlewares: ActionMiddleware[],\r\n options: {\r\n request?: Request;\r\n headers?: Headers;\r\n signal?: AbortSignal;\r\n } = {}\r\n): Promise<ActionResult<TOutput>> {\r\n // Create context with request info\r\n const ctx = createActionContext({\r\n request: options.request,\r\n headers: options.headers,\r\n actionId: action.name || 'anonymous',\r\n args: args as unknown[],\r\n signal: options.signal,\r\n });\r\n\r\n // Build the middleware chain\r\n let index = -1;\r\n\r\n const dispatch = async (i: number): Promise<ActionResult<TOutput>> => {\r\n // Check for abort\r\n if (options.signal?.aborted) {\r\n return { success: false, error: 'Aborted', code: 'ABORTED' };\r\n }\r\n\r\n if (i <= index) {\r\n throw new Error('next() called multiple times');\r\n }\r\n index = i;\r\n\r\n if (i < middlewares.length) {\r\n const middleware = middlewares[i]!;\r\n return middleware.handler(ctx, () => dispatch(i + 1)) as Promise<ActionResult<TOutput>>;\r\n } else {\r\n return action(...args);\r\n }\r\n };\r\n\r\n return dispatch(0);\r\n}\r\n\r\n// ============================================================================\r\n// Utility Middleware Factories\r\n// ============================================================================\r\n\r\n/**\r\n * Create a timing middleware for observability.\r\n * \r\n * You provide the reporter - Flight doesn't impose any observability provider.\r\n * \r\n * @example\r\n * ```typescript\r\n * const withTiming = createTimingMiddleware((actionId, durationMs) => {\r\n * myMetricsService.histogram('action.duration', durationMs, { actionId });\r\n * });\r\n * ```\r\n */\r\nexport function createTimingMiddleware(\r\n reporter: (actionId: string, durationMs: number, result: ActionResult) => void\r\n): ActionMiddleware {\r\n return createActionMiddleware(\r\n async (ctx, next) => {\r\n const start = performance.now();\r\n const result = await next();\r\n const duration = performance.now() - start;\r\n reporter(ctx.actionId, duration, result);\r\n return result;\r\n },\r\n { name: 'timing' }\r\n );\r\n}\r\n\r\n/**\r\n * Create a logging middleware.\r\n * \r\n * You provide the logger - Flight doesn't impose any logging library.\r\n * \r\n * @example\r\n * ```typescript\r\n * const withLogging = createLoggingMiddleware({\r\n * onStart: (ctx) => console.log(`[${ctx.actionId}] Starting...`),\r\n * onComplete: (ctx, result, ms) => console.log(`[${ctx.actionId}] ${result.success ? 'OK' : 'FAIL'} in ${ms}ms`),\r\n * });\r\n * ```\r\n */\r\nexport function createLoggingMiddleware(options: {\r\n onStart?: (ctx: ActionContext) => void;\r\n onComplete?: (ctx: ActionContext, result: ActionResult, durationMs: number) => void;\r\n onError?: (ctx: ActionContext, error: Error) => void;\r\n}): ActionMiddleware {\r\n return createActionMiddleware(\r\n async (ctx, next) => {\r\n options.onStart?.(ctx);\r\n const start = performance.now();\r\n\r\n try {\r\n const result = await next();\r\n const duration = performance.now() - start;\r\n options.onComplete?.(ctx, result, duration);\r\n return result;\r\n } catch (error) {\r\n options.onError?.(ctx, error as Error);\r\n throw error;\r\n }\r\n },\r\n { name: 'logging' }\r\n );\r\n}\r\n\r\n/**\r\n * Create a retry middleware.\r\n * \r\n * @example\r\n * ```typescript\r\n * const withRetry = createRetryMiddleware({\r\n * maxAttempts: 3,\r\n * delay: (attempt) => Math.pow(2, attempt) * 100, // Exponential backoff\r\n * shouldRetry: (result) => result.code === 'TEMPORARY_ERROR',\r\n * });\r\n * ```\r\n */\r\nexport function createRetryMiddleware(options: {\r\n maxAttempts: number;\r\n delay?: (attempt: number) => number;\r\n shouldRetry?: (result: ActionResult) => boolean;\r\n}): ActionMiddleware {\r\n const {\r\n maxAttempts,\r\n delay = () => 0,\r\n shouldRetry = (result) => !result.success,\r\n } = options;\r\n\r\n return createActionMiddleware(\r\n async (ctx, next) => {\r\n let lastResult: ActionResult = { success: false, error: 'No attempts made' };\r\n\r\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\r\n if (attempt > 0) {\r\n const delayMs = delay(attempt);\r\n if (delayMs > 0) {\r\n await new Promise(resolve => setTimeout(resolve, delayMs));\r\n }\r\n }\r\n\r\n lastResult = await next();\r\n\r\n if (!shouldRetry(lastResult)) {\r\n return lastResult;\r\n }\r\n }\r\n\r\n return lastResult;\r\n },\r\n { name: 'retry' }\r\n );\r\n}\r\n","/**\r\n * @flight-framework/core - Action Streaming\r\n * \r\n * Streamable actions using async generators.\r\n * Flight provides the PRIMITIVES, you choose the transport.\r\n * \r\n * @example\r\n * ```typescript\r\n * // Create a streamable action for long-running operations\r\n * const generateReport = createStreamableAction(async function* (params: ReportParams) {\r\n * yield { type: 'progress', message: 'Fetching data...', progress: 0 };\r\n * const data = await fetchData(params);\r\n * \r\n * yield { type: 'progress', message: 'Processing...', progress: 33 };\r\n * const processed = await processData(data);\r\n * \r\n * yield { type: 'progress', message: 'Generating PDF...', progress: 66 };\r\n * const pdf = await generatePDF(processed);\r\n * \r\n * yield { type: 'progress', message: 'Complete!', progress: 100 };\r\n * return { success: true, data: pdf };\r\n * });\r\n * \r\n * // Client consumption\r\n * for await (const update of generateReport(params)) {\r\n * if (update.type === 'progress') {\r\n * setProgress(update.progress);\r\n * } else if (update.type === 'result') {\r\n * handleResult(update.data);\r\n * }\r\n * }\r\n * ```\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Progress update yielded during streaming\r\n */\r\nexport interface StreamProgress<TYield = unknown> {\r\n type: 'progress';\r\n data: TYield;\r\n}\r\n\r\n/**\r\n * Final result of a streaming action\r\n */\r\nexport interface StreamResult<TReturn = unknown> {\r\n type: 'result';\r\n success: boolean;\r\n data?: TReturn;\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Union type for stream items\r\n */\r\nexport type StreamItem<TYield, TReturn> = StreamProgress<TYield> | StreamResult<TReturn>;\r\n\r\n/**\r\n * Streamable action generator function\r\n */\r\nexport type StreamableGenerator<TInput, TYield, TReturn> = (\r\n input: TInput,\r\n signal?: AbortSignal\r\n) => AsyncGenerator<TYield, TReturn>;\r\n\r\n/**\r\n * Options for creating a streamable action\r\n */\r\nexport interface StreamableActionOptions {\r\n /** Name for debugging */\r\n name?: string;\r\n /** Timeout in milliseconds */\r\n timeout?: number;\r\n}\r\n\r\n/**\r\n * Controller for a running stream\r\n */\r\nexport interface StreamController<TYield, TReturn> {\r\n /** Async iterator for consuming the stream */\r\n [Symbol.asyncIterator](): AsyncIterator<StreamItem<TYield, TReturn>>;\r\n /** Abort the stream */\r\n abort(): void;\r\n /** Promise that resolves when stream completes */\r\n done: Promise<StreamResult<TReturn>>;\r\n}\r\n\r\n/**\r\n * A streamable action function\r\n */\r\nexport type StreamableAction<TInput, TYield, TReturn> = (\r\n input: TInput\r\n) => StreamController<TYield, TReturn>;\r\n\r\n// ============================================================================\r\n// Streamable Action Creation\r\n// ============================================================================\r\n\r\n/**\r\n * Create a streamable action from an async generator.\r\n * \r\n * Flight provides this PRIMITIVE - you define the generator logic\r\n * and choose how to transport the stream (HTTP, WebSocket, etc.)\r\n * \r\n * @example\r\n * ```typescript\r\n * // AI streaming response\r\n * const streamChat = createStreamableAction(async function* (message: string) {\r\n * const stream = await openai.chat.completions.create({\r\n * model: 'gpt-4',\r\n * messages: [{ role: 'user', content: message }],\r\n * stream: true,\r\n * });\r\n * \r\n * let fullResponse = '';\r\n * for await (const chunk of stream) {\r\n * const text = chunk.choices[0]?.delta?.content || '';\r\n * fullResponse += text;\r\n * yield { text, partial: true };\r\n * }\r\n * \r\n * return { text: fullResponse, partial: false };\r\n * });\r\n * ```\r\n */\r\nexport function createStreamableAction<TInput, TYield, TReturn>(\r\n generator: StreamableGenerator<TInput, TYield, TReturn>,\r\n options: StreamableActionOptions = {}\r\n): StreamableAction<TInput, TYield, TReturn> {\r\n const actionName = options.name ?? generator.name ?? 'streamable_action';\r\n\r\n return (input: TInput): StreamController<TYield, TReturn> => {\r\n const abortController = new AbortController();\r\n let completed = false;\r\n let finalResult: StreamResult<TReturn> | null = null;\r\n\r\n // Create done promise\r\n let resolveDone: (result: StreamResult<TReturn>) => void;\r\n const done = new Promise<StreamResult<TReturn>>((resolve) => {\r\n resolveDone = resolve;\r\n });\r\n\r\n // Setup timeout if specified\r\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\r\n if (options.timeout) {\r\n timeoutId = setTimeout(() => {\r\n abortController.abort();\r\n }, options.timeout);\r\n }\r\n\r\n // Create the async iterator\r\n async function* iterate(): AsyncGenerator<StreamItem<TYield, TReturn>> {\r\n try {\r\n const gen = generator(input, abortController.signal);\r\n\r\n while (true) {\r\n if (abortController.signal.aborted) {\r\n const abortResult: StreamResult<TReturn> = {\r\n type: 'result',\r\n success: false,\r\n error: 'Stream aborted',\r\n };\r\n finalResult = abortResult;\r\n resolveDone!(abortResult);\r\n yield abortResult;\r\n return;\r\n }\r\n\r\n const next = await gen.next();\r\n\r\n if (next.done) {\r\n // Generator returned - this is the final value\r\n const successResult: StreamResult<TReturn> = {\r\n type: 'result',\r\n success: true,\r\n data: next.value,\r\n };\r\n finalResult = successResult;\r\n completed = true;\r\n resolveDone!(successResult);\r\n yield successResult;\r\n return;\r\n } else {\r\n // Generator yielded - this is a progress update\r\n yield {\r\n type: 'progress',\r\n data: next.value,\r\n };\r\n }\r\n }\r\n } catch (error) {\r\n const errorResult: StreamResult<TReturn> = {\r\n type: 'result',\r\n success: false,\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n };\r\n finalResult = errorResult;\r\n resolveDone!(errorResult);\r\n yield errorResult;\r\n } finally {\r\n if (timeoutId) {\r\n clearTimeout(timeoutId);\r\n }\r\n }\r\n }\r\n\r\n const iterator = iterate();\r\n\r\n return {\r\n [Symbol.asyncIterator]() {\r\n return iterator;\r\n },\r\n abort() {\r\n abortController.abort();\r\n },\r\n done,\r\n };\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// HTTP Transport Adapter\r\n// ============================================================================\r\n\r\n/**\r\n * Convert a streamable action result to an HTTP streaming response.\r\n * \r\n * This is ONE transport option - you can create others (WebSocket, SSE, etc.)\r\n * \r\n * @example\r\n * ```typescript\r\n * // In your API route\r\n * export async function POST(request: Request) {\r\n * const body = await request.json();\r\n * const stream = generateReport(body);\r\n * return streamToResponse(stream);\r\n * }\r\n * ```\r\n */\r\nexport function streamToResponse<TYield, TReturn>(\r\n controller: StreamController<TYield, TReturn>,\r\n options: {\r\n headers?: Record<string, string>;\r\n } = {}\r\n): Response {\r\n const encoder = new TextEncoder();\r\n\r\n const stream = new ReadableStream({\r\n async start(streamController) {\r\n try {\r\n for await (const item of controller) {\r\n const chunk = JSON.stringify(item) + '\\n';\r\n streamController.enqueue(encoder.encode(chunk));\r\n\r\n if (item.type === 'result') {\r\n break;\r\n }\r\n }\r\n } catch (error) {\r\n const errorChunk = JSON.stringify({\r\n type: 'result',\r\n success: false,\r\n error: error instanceof Error ? error.message : 'Stream error',\r\n }) + '\\n';\r\n streamController.enqueue(encoder.encode(errorChunk));\r\n } finally {\r\n streamController.close();\r\n }\r\n },\r\n cancel() {\r\n controller.abort();\r\n },\r\n });\r\n\r\n return new Response(stream, {\r\n status: 200,\r\n headers: {\r\n 'Content-Type': 'application/x-ndjson',\r\n 'Transfer-Encoding': 'chunked',\r\n 'Cache-Control': 'no-cache',\r\n 'Connection': 'keep-alive',\r\n ...options.headers,\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * Parse an HTTP streaming response back to a stream controller (client-side).\r\n * \r\n * @example\r\n * ```typescript\r\n * // Client-side consumption\r\n * const response = await fetch('/api/generate-report', {\r\n * method: 'POST',\r\n * body: JSON.stringify(params),\r\n * });\r\n * \r\n * const stream = responseToStream<Progress, Report>(response);\r\n * \r\n * for await (const item of stream) {\r\n * if (item.type === 'progress') {\r\n * setProgress(item.data);\r\n * } else {\r\n * setReport(item.data);\r\n * }\r\n * }\r\n * ```\r\n */\r\nexport function responseToStream<TYield, TReturn>(\r\n response: Response\r\n): AsyncGenerator<StreamItem<TYield, TReturn>> {\r\n const reader = response.body?.getReader();\r\n const decoder = new TextDecoder();\r\n\r\n if (!reader) {\r\n throw new Error('Response body is not readable');\r\n }\r\n\r\n return (async function* () {\r\n let buffer = '';\r\n\r\n try {\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n\r\n if (done) {\r\n break;\r\n }\r\n\r\n buffer += decoder.decode(value, { stream: true });\r\n\r\n // Process complete lines\r\n const lines = buffer.split('\\n');\r\n buffer = lines.pop() || ''; // Keep incomplete line in buffer\r\n\r\n for (const line of lines) {\r\n if (line.trim()) {\r\n try {\r\n const item = JSON.parse(line) as StreamItem<TYield, TReturn>;\r\n yield item;\r\n } catch {\r\n // Skip malformed JSON\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Process remaining buffer\r\n if (buffer.trim()) {\r\n try {\r\n const item = JSON.parse(buffer) as StreamItem<TYield, TReturn>;\r\n yield item;\r\n } catch {\r\n // Skip malformed JSON\r\n }\r\n }\r\n } finally {\r\n reader.releaseLock();\r\n }\r\n })();\r\n}\r\n\r\n// ============================================================================\r\n// Utility Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Collect all items from a stream into an array.\r\n * \r\n * Useful for testing or when you want to wait for completion.\r\n */\r\nexport async function collectStream<TYield, TReturn>(\r\n controller: StreamController<TYield, TReturn>\r\n): Promise<{ items: StreamItem<TYield, TReturn>[]; result: StreamResult<TReturn> }> {\r\n const items: StreamItem<TYield, TReturn>[] = [];\r\n let result: StreamResult<TReturn> | null = null;\r\n\r\n for await (const item of controller) {\r\n items.push(item);\r\n if (item.type === 'result') {\r\n result = item;\r\n }\r\n }\r\n\r\n if (!result) {\r\n result = { type: 'result', success: false, error: 'No result received' };\r\n }\r\n\r\n return { items, result };\r\n}\r\n\r\n/**\r\n * Create a simple progress reporter for streams.\r\n * \r\n * @example\r\n * ```typescript\r\n * const onProgress = createProgressReporter<MyProgress>((data) => {\r\n * console.log(`Progress: ${data.percent}%`);\r\n * });\r\n * \r\n * for await (const item of myStream) {\r\n * onProgress(item);\r\n * }\r\n * ```\r\n */\r\nexport function createProgressReporter<TYield, TReturn = unknown>(\r\n onProgress: (data: TYield) => void,\r\n onComplete?: (result: StreamResult<TReturn>) => void\r\n): (item: StreamItem<TYield, TReturn>) => void {\r\n return (item: StreamItem<TYield, TReturn>) => {\r\n if (item.type === 'progress') {\r\n onProgress(item.data);\r\n } else {\r\n onComplete?.(item);\r\n }\r\n };\r\n}\r\n","/**\r\n * @flight-framework/core - Action Queue\r\n * \r\n * Offline-first action queuing with pluggable storage.\r\n * Flight provides the PRIMITIVES and INTERFACE, you choose the storage.\r\n * \r\n * @example\r\n * ```typescript\r\n * // 1. Use a storage adapter (install separately or create your own)\r\n * import { indexedDBAdapter } from '@flight-framework/queue-indexeddb';\r\n * // OR create your own:\r\n * const myAdapter: QueueStorageAdapter = { ... };\r\n * \r\n * // 2. Create a queued action\r\n * const saveNote = createQueuedAction(\r\n * async (note: Note) => {\r\n * await api.saveNote(note);\r\n * return { success: true };\r\n * },\r\n * {\r\n * storage: indexedDBAdapter({ dbName: 'myapp' }),\r\n * retryStrategy: exponentialBackoff({ maxAttempts: 5 }),\r\n * onStatusChange: (status) => console.log('Queue status:', status),\r\n * }\r\n * );\r\n * \r\n * // 3. Use it - works offline!\r\n * await saveNote({ title: 'My Note', content: '...' });\r\n * // If offline: queued and synced later\r\n * // If online: executed immediately\r\n * ```\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * A queued action entry\r\n */\r\nexport interface QueuedActionEntry<TInput = unknown> {\r\n /** Unique ID for this entry */\r\n id: string;\r\n /** Action identifier */\r\n actionId: string;\r\n /** Action arguments */\r\n input: TInput;\r\n /** When the action was queued */\r\n queuedAt: number;\r\n /** Number of execution attempts */\r\n attempts: number;\r\n /** Last error message if failed */\r\n lastError?: string;\r\n /** Status */\r\n status: 'pending' | 'processing' | 'failed';\r\n /** Optional metadata */\r\n meta?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Queue storage adapter interface.\r\n * \r\n * Flight does NOT provide storage implementations - you choose:\r\n * - @flight-framework/queue-indexeddb (browser)\r\n * - @flight-framework/queue-sqlite (mobile/desktop)\r\n * - @flight-framework/queue-memory (testing)\r\n * - Your own implementation\r\n */\r\nexport interface QueueStorageAdapter {\r\n /** Add an action to the queue */\r\n enqueue<TInput>(entry: QueuedActionEntry<TInput>): Promise<void>;\r\n\r\n /** Get and remove the next pending action */\r\n dequeue(): Promise<QueuedActionEntry | null>;\r\n\r\n /** Get all pending actions without removing */\r\n peek(): Promise<QueuedActionEntry[]>;\r\n\r\n /** Update an existing entry */\r\n update(id: string, updates: Partial<QueuedActionEntry>): Promise<void>;\r\n\r\n /** Remove an entry by ID */\r\n remove(id: string): Promise<void>;\r\n\r\n /** Clear all entries */\r\n clear(): Promise<void>;\r\n\r\n /** Get queue length */\r\n length(): Promise<number>;\r\n}\r\n\r\n/**\r\n * Retry strategy function\r\n */\r\nexport type RetryStrategy = (\r\n entry: QueuedActionEntry,\r\n error: Error\r\n) => { shouldRetry: boolean; delayMs: number };\r\n\r\n/**\r\n * Queue status for observability\r\n */\r\nexport interface QueueStatus {\r\n /** Whether the queue processor is running */\r\n isProcessing: boolean;\r\n /** Number of pending actions */\r\n pendingCount: number;\r\n /** Number of failed actions */\r\n failedCount: number;\r\n /** Whether online */\r\n isOnline: boolean;\r\n}\r\n\r\n/**\r\n * Options for creating a queued action\r\n */\r\nexport interface QueuedActionOptions {\r\n /** Storage adapter (required - Flight doesn't provide default) */\r\n storage: QueueStorageAdapter;\r\n /** Custom action ID */\r\n actionId?: string;\r\n /** Retry strategy */\r\n retryStrategy?: RetryStrategy;\r\n /** Check if online (default: navigator.onLine on browser) */\r\n isOnline?: () => boolean | Promise<boolean>;\r\n /** Called when queue status changes */\r\n onStatusChange?: (status: QueueStatus) => void;\r\n /** Called when an action is successfully processed */\r\n onSuccess?: (entry: QueuedActionEntry, result: unknown) => void;\r\n /** Called when an action fails permanently */\r\n onFailure?: (entry: QueuedActionEntry, error: Error) => void;\r\n}\r\n\r\n/**\r\n * Action result for queued actions\r\n */\r\nexport interface QueuedActionResult<TOutput = unknown> {\r\n /** Whether immediately executed or queued */\r\n queued: boolean;\r\n /** Queue entry ID if queued */\r\n entryId?: string;\r\n /** Result if immediately executed */\r\n result?: { success: boolean; data?: TOutput; error?: string };\r\n}\r\n\r\n/**\r\n * A queued action function\r\n */\r\nexport type QueuedAction<TInput, TOutput> = (\r\n input: TInput\r\n) => Promise<QueuedActionResult<TOutput>>;\r\n\r\n// ============================================================================\r\n// Queue Creation\r\n// ============================================================================\r\n\r\nlet entryCounter = 0;\r\n\r\nfunction generateEntryId(): string {\r\n return `${Date.now()}_${++entryCounter}_${Math.random().toString(36).substring(2, 9)}`;\r\n}\r\n\r\n/**\r\n * Create an offline-capable queued action.\r\n * \r\n * Flight provides this PRIMITIVE - you provide the storage adapter.\r\n * \r\n * @example\r\n * ```typescript\r\n * // Create with your storage adapter\r\n * const syncData = createQueuedAction(\r\n * async (data: MyData) => {\r\n * await api.sync(data);\r\n * return { success: true };\r\n * },\r\n * {\r\n * storage: myStorageAdapter,\r\n * retryStrategy: exponentialBackoff(),\r\n * }\r\n * );\r\n * \r\n * // Use it - works offline automatically\r\n * const result = await syncData({ items: [...] });\r\n * \r\n * if (result.queued) {\r\n * console.log('Queued for later sync:', result.entryId);\r\n * } else {\r\n * console.log('Synced immediately:', result.result);\r\n * }\r\n * ```\r\n */\r\nexport function createQueuedAction<TInput, TOutput>(\r\n action: (input: TInput) => Promise<{ success: boolean; data?: TOutput; error?: string }>,\r\n options: QueuedActionOptions\r\n): QueuedAction<TInput, TOutput> {\r\n const {\r\n storage,\r\n actionId = action.name || `action_${Date.now()}`,\r\n retryStrategy = defaultRetryStrategy,\r\n isOnline = defaultIsOnline,\r\n onStatusChange,\r\n onSuccess,\r\n onFailure,\r\n } = options;\r\n\r\n // Queue processor state\r\n let isProcessing = false;\r\n let processorRunning = false;\r\n\r\n // Start background processor\r\n startProcessor();\r\n\r\n async function startProcessor() {\r\n if (processorRunning) return;\r\n processorRunning = true;\r\n\r\n // Process queue periodically\r\n while (processorRunning) {\r\n await processQueue();\r\n await sleep(1000); // Check every second\r\n }\r\n }\r\n\r\n async function processQueue() {\r\n // Check if online\r\n const online = await isOnline();\r\n if (!online) {\r\n return;\r\n }\r\n\r\n // Get next entry\r\n const entry = await storage.dequeue();\r\n if (!entry) {\r\n if (isProcessing) {\r\n isProcessing = false;\r\n await notifyStatus();\r\n }\r\n return;\r\n }\r\n\r\n isProcessing = true;\r\n await notifyStatus();\r\n\r\n // Update status to processing\r\n await storage.update(entry.id, { status: 'processing' });\r\n\r\n try {\r\n // Execute the action\r\n const result = await action(entry.input as TInput);\r\n\r\n // Success - remove from queue\r\n await storage.remove(entry.id);\r\n onSuccess?.(entry, result);\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n\r\n // Check retry strategy\r\n const { shouldRetry, delayMs } = retryStrategy(entry, err);\r\n\r\n if (shouldRetry) {\r\n // Re-queue with updated attempts\r\n await storage.update(entry.id, {\r\n status: 'pending',\r\n attempts: entry.attempts + 1,\r\n lastError: err.message,\r\n });\r\n\r\n // Wait before next attempt\r\n if (delayMs > 0) {\r\n await sleep(delayMs);\r\n }\r\n } else {\r\n // Mark as failed\r\n await storage.update(entry.id, {\r\n status: 'failed',\r\n lastError: err.message,\r\n });\r\n onFailure?.(entry, err);\r\n }\r\n }\r\n }\r\n\r\n async function notifyStatus() {\r\n if (!onStatusChange) return;\r\n\r\n const entries = await storage.peek();\r\n const status: QueueStatus = {\r\n isProcessing,\r\n pendingCount: entries.filter(e => e.status === 'pending').length,\r\n failedCount: entries.filter(e => e.status === 'failed').length,\r\n isOnline: await isOnline(),\r\n };\r\n onStatusChange(status);\r\n }\r\n\r\n // Return the queued action function\r\n return async (input: TInput): Promise<QueuedActionResult<TOutput>> => {\r\n const online = await isOnline();\r\n\r\n if (online) {\r\n // Try to execute immediately\r\n try {\r\n const result = await action(input);\r\n return { queued: false, result };\r\n } catch {\r\n // Fall through to queue\r\n }\r\n }\r\n\r\n // Queue for later\r\n const entry: QueuedActionEntry<TInput> = {\r\n id: generateEntryId(),\r\n actionId,\r\n input,\r\n queuedAt: Date.now(),\r\n attempts: 0,\r\n status: 'pending',\r\n };\r\n\r\n await storage.enqueue(entry);\r\n await notifyStatus();\r\n\r\n return { queued: true, entryId: entry.id };\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Built-in Retry Strategies\r\n// ============================================================================\r\n\r\n/**\r\n * Default retry strategy: 3 attempts with 1 second delay\r\n */\r\nexport const defaultRetryStrategy: RetryStrategy = (entry) => ({\r\n shouldRetry: entry.attempts < 3,\r\n delayMs: 1000,\r\n});\r\n\r\n/**\r\n * Create an exponential backoff retry strategy.\r\n * \r\n * @example\r\n * ```typescript\r\n * const retry = exponentialBackoff({\r\n * maxAttempts: 5,\r\n * baseDelayMs: 1000,\r\n * maxDelayMs: 30000,\r\n * });\r\n * ```\r\n */\r\nexport function exponentialBackoff(options: {\r\n maxAttempts?: number;\r\n baseDelayMs?: number;\r\n maxDelayMs?: number;\r\n} = {}): RetryStrategy {\r\n const {\r\n maxAttempts = 5,\r\n baseDelayMs = 1000,\r\n maxDelayMs = 30000,\r\n } = options;\r\n\r\n return (entry) => {\r\n const shouldRetry = entry.attempts < maxAttempts;\r\n const delayMs = Math.min(\r\n baseDelayMs * Math.pow(2, entry.attempts),\r\n maxDelayMs\r\n );\r\n\r\n return { shouldRetry, delayMs };\r\n };\r\n}\r\n\r\n/**\r\n * Create a fixed delay retry strategy.\r\n */\r\nexport function fixedDelay(options: {\r\n maxAttempts?: number;\r\n delayMs?: number;\r\n} = {}): RetryStrategy {\r\n const { maxAttempts = 3, delayMs = 1000 } = options;\r\n\r\n return (entry) => ({\r\n shouldRetry: entry.attempts < maxAttempts,\r\n delayMs,\r\n });\r\n}\r\n\r\n// ============================================================================\r\n// In-Memory Storage Adapter (for testing only)\r\n// ============================================================================\r\n\r\n/**\r\n * In-memory queue storage adapter.\r\n * \r\n * ⚠️ FOR TESTING ONLY - data is lost on page refresh.\r\n * \r\n * For production, use:\r\n * - @flight-framework/queue-indexeddb (browser)\r\n * - @flight-framework/queue-sqlite (native apps)\r\n * - Your own implementation\r\n */\r\nexport function createMemoryAdapter(): QueueStorageAdapter {\r\n const store = new Map<string, QueuedActionEntry>();\r\n\r\n return {\r\n async enqueue(entry) {\r\n store.set(entry.id, entry);\r\n },\r\n\r\n async dequeue() {\r\n for (const [id, entry] of store.entries()) {\r\n if (entry.status === 'pending') {\r\n store.delete(id);\r\n return entry;\r\n }\r\n }\r\n return null;\r\n },\r\n\r\n async peek() {\r\n return Array.from(store.values());\r\n },\r\n\r\n async update(id, updates) {\r\n const entry = store.get(id);\r\n if (entry) {\r\n store.set(id, { ...entry, ...updates });\r\n }\r\n },\r\n\r\n async remove(id) {\r\n store.delete(id);\r\n },\r\n\r\n async clear() {\r\n store.clear();\r\n },\r\n\r\n async length() {\r\n return store.size;\r\n },\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Utility Functions\r\n// ============================================================================\r\n\r\nfunction sleep(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n}\r\n\r\nfunction defaultIsOnline(): boolean {\r\n if (typeof navigator !== 'undefined' && 'onLine' in navigator) {\r\n return navigator.onLine;\r\n }\r\n // Assume online in non-browser environments\r\n return true;\r\n}\r\n\r\n/**\r\n * Create a queue manager to control multiple queued actions.\r\n * \r\n * @example\r\n * ```typescript\r\n * const queueManager = createQueueManager({\r\n * storage: myStorageAdapter,\r\n * });\r\n * \r\n * // Pause all processing\r\n * queueManager.pause();\r\n * \r\n * // Resume\r\n * queueManager.resume();\r\n * \r\n * // Get status\r\n * const status = await queueManager.getStatus();\r\n * ```\r\n */\r\nexport function createQueueManager(options: {\r\n storage: QueueStorageAdapter;\r\n}): {\r\n pause: () => void;\r\n resume: () => void;\r\n getStatus: () => Promise<QueueStatus>;\r\n clearFailed: () => Promise<void>;\r\n retryFailed: () => Promise<void>;\r\n} {\r\n let paused = false;\r\n\r\n return {\r\n pause() {\r\n paused = true;\r\n },\r\n\r\n resume() {\r\n paused = false;\r\n },\r\n\r\n async getStatus() {\r\n const entries = await options.storage.peek();\r\n return {\r\n isProcessing: !paused,\r\n pendingCount: entries.filter(e => e.status === 'pending').length,\r\n failedCount: entries.filter(e => e.status === 'failed').length,\r\n isOnline: defaultIsOnline(),\r\n };\r\n },\r\n\r\n async clearFailed() {\r\n const entries = await options.storage.peek();\r\n for (const entry of entries) {\r\n if (entry.status === 'failed') {\r\n await options.storage.remove(entry.id);\r\n }\r\n }\r\n },\r\n\r\n async retryFailed() {\r\n const entries = await options.storage.peek();\r\n for (const entry of entries) {\r\n if (entry.status === 'failed') {\r\n await options.storage.update(entry.id, {\r\n status: 'pending',\r\n attempts: 0,\r\n lastError: undefined,\r\n });\r\n }\r\n }\r\n },\r\n };\r\n}\r\n","/**\r\n * @flight-framework/core - Server Actions\r\n * \r\n * Implementation of React 19 style Server Actions.\r\n * Functions marked with 'use server' run on the server.\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Server action metadata\r\n */\r\nexport interface ServerAction {\r\n /** Unique action ID */\r\n id: string;\r\n /** Original function name */\r\n name: string;\r\n /** File path where action is defined */\r\n filePath: string;\r\n /** The actual action function */\r\n fn: (...args: unknown[]) => Promise<unknown>;\r\n}\r\n\r\n/**\r\n * Server action result\r\n */\r\nexport interface ActionResult<T = unknown> {\r\n success: boolean;\r\n data?: T;\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Form action data\r\n */\r\nexport interface FormActionData {\r\n actionId: string;\r\n formData: FormData;\r\n}\r\n\r\n// ============================================================================\r\n// Action Registry\r\n// ============================================================================\r\n\r\nconst actionRegistry = new Map<string, ServerAction>();\r\n\r\n/**\r\n * Register a server action\r\n */\r\nexport function registerAction(action: ServerAction): void {\r\n actionRegistry.set(action.id, action);\r\n}\r\n\r\n/**\r\n * Get a registered action by ID\r\n */\r\nexport function getAction(id: string): ServerAction | undefined {\r\n return actionRegistry.get(id);\r\n}\r\n\r\n/**\r\n * Get all registered actions\r\n */\r\nexport function getAllActions(): ServerAction[] {\r\n return Array.from(actionRegistry.values());\r\n}\r\n\r\n/**\r\n * Clear all registered actions (useful for testing)\r\n */\r\nexport function clearActions(): void {\r\n actionRegistry.clear();\r\n}\r\n\r\n// ============================================================================\r\n// Action Execution\r\n// ============================================================================\r\n\r\n/**\r\n * Execute a server action\r\n */\r\nexport async function executeAction<T = unknown>(\r\n actionId: string,\r\n args: unknown[]\r\n): Promise<ActionResult<T>> {\r\n const action = getAction(actionId);\r\n\r\n if (!action) {\r\n return {\r\n success: false,\r\n error: `Action not found: ${actionId}`,\r\n };\r\n }\r\n\r\n try {\r\n const result = await action.fn(...args);\r\n return {\r\n success: true,\r\n data: result as T,\r\n };\r\n } catch (error) {\r\n // Re-throw RedirectError so handleActionRequest can return 303\r\n if (isRedirectError(error)) {\r\n throw error;\r\n }\r\n console.error(`[Flight] Action error (${actionId}):`, error);\r\n return {\r\n success: false,\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Execute a form action\r\n */\r\nexport async function executeFormAction<T = unknown>(\r\n actionId: string,\r\n formData: FormData\r\n): Promise<ActionResult<T>> {\r\n return executeAction<T>(actionId, [formData]);\r\n}\r\n\r\n// ============================================================================\r\n// Action ID Generation\r\n// ============================================================================\r\n\r\nlet actionCounter = 0;\r\n\r\n/**\r\n * Generate a unique action ID\r\n */\r\nexport function generateActionId(name: string, filePath: string): string {\r\n const hash = simpleHash(`${filePath}:${name}`);\r\n return `action_${hash}_${actionCounter++}`;\r\n}\r\n\r\n/**\r\n * Simple hash function for action IDs\r\n */\r\nfunction simpleHash(str: string): string {\r\n let hash = 0;\r\n for (let i = 0; i < str.length; i++) {\r\n const char = str.charCodeAt(i);\r\n hash = ((hash << 5) - hash) + char;\r\n hash = hash & hash; // Convert to 32bit integer\r\n }\r\n return Math.abs(hash).toString(36);\r\n}\r\n\r\n// ============================================================================\r\n// Action Helpers (for use inside actions)\r\n// ============================================================================\r\n\r\n/**\r\n * Get cookies in server action context\r\n */\r\nexport function cookies(): {\r\n get: (name: string) => string | undefined;\r\n set: (name: string, value: string, options?: CookieOptions) => void;\r\n delete: (name: string) => void;\r\n} {\r\n // This will be populated by the runtime\r\n const cookieStore = (globalThis as any).__flightCookies;\r\n\r\n if (!cookieStore) {\r\n console.warn('[Flight] Cookies not available outside of action context');\r\n return {\r\n get: () => undefined,\r\n set: () => { },\r\n delete: () => { },\r\n };\r\n }\r\n\r\n return cookieStore;\r\n}\r\n\r\nexport interface CookieOptions {\r\n maxAge?: number;\r\n expires?: Date;\r\n path?: string;\r\n domain?: string;\r\n secure?: boolean;\r\n httpOnly?: boolean;\r\n sameSite?: 'strict' | 'lax' | 'none';\r\n}\r\n\r\n/**\r\n * Redirect in server action context\r\n */\r\nexport function redirect(url: string): never {\r\n throw new RedirectError(url);\r\n}\r\n\r\n/**\r\n * Special error for redirects\r\n */\r\nexport class RedirectError extends Error {\r\n public readonly url: string;\r\n\r\n constructor(url: string) {\r\n super(`Redirect to ${url}`);\r\n this.name = 'RedirectError';\r\n this.url = url;\r\n }\r\n}\r\n\r\n/**\r\n * Check if error is a redirect\r\n */\r\nexport function isRedirectError(error: unknown): error is RedirectError {\r\n return error instanceof RedirectError;\r\n}\r\n\r\n// ============================================================================\r\n// Form Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Parse form data to typed object\r\n */\r\nexport function parseFormData<T extends Record<string, string>>(\r\n formData: FormData\r\n): T {\r\n const result: Record<string, string> = {};\r\n\r\n formData.forEach((value, key) => {\r\n result[key] = String(value);\r\n });\r\n\r\n return result as T;\r\n}\r\n\r\n/**\r\n * Create action reference for form action attribute\r\n */\r\nexport function createActionReference(actionId: string): string {\r\n return `/__flight_action/${actionId}`;\r\n}\r\n\r\n// ============================================================================\r\n// Action Handler (for HTTP endpoint)\r\n// ============================================================================\r\n\r\n/**\r\n * Handle action request from client\r\n */\r\nexport async function handleActionRequest(\r\n request: Request\r\n): Promise<Response> {\r\n const url = new URL(request.url);\r\n const actionPath = url.pathname;\r\n\r\n // Extract action ID from path: /__flight_action/{actionId}\r\n const match = actionPath.match(/^\\/__flight_action\\/(.+)$/);\r\n\r\n if (!match) {\r\n return new Response(JSON.stringify({ error: 'Invalid action path' }), {\r\n status: 400,\r\n headers: { 'Content-Type': 'application/json' },\r\n });\r\n }\r\n\r\n const actionId = match[1];\r\n\r\n if (!actionId) {\r\n return new Response(JSON.stringify({ error: 'Missing action ID' }), {\r\n status: 400,\r\n headers: { 'Content-Type': 'application/json' },\r\n });\r\n }\r\n\r\n try {\r\n let result: ActionResult;\r\n\r\n // Check content type for form vs JSON\r\n const contentType = request.headers.get('content-type') || '';\r\n\r\n if (contentType.includes('application/x-www-form-urlencoded') ||\r\n contentType.includes('multipart/form-data')) {\r\n const formData = await request.formData();\r\n result = await executeFormAction(actionId, formData);\r\n } else {\r\n const args = await request.json();\r\n result = await executeAction(actionId, Array.isArray(args) ? args : [args]);\r\n }\r\n\r\n return new Response(JSON.stringify(result), {\r\n status: result.success ? 200 : 400,\r\n headers: { 'Content-Type': 'application/json' },\r\n });\r\n } catch (error) {\r\n if (isRedirectError(error)) {\r\n return new Response(null, {\r\n status: 303,\r\n headers: { Location: error.url },\r\n });\r\n }\r\n\r\n return new Response(JSON.stringify({\r\n success: false,\r\n error: error instanceof Error ? error.message : 'Unknown error',\r\n }), {\r\n status: 500,\r\n headers: { 'Content-Type': 'application/json' },\r\n });\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Re-export New Modules\r\n// ============================================================================\r\n\r\n// Action Middleware - composable middleware for actions\r\nexport * from './middleware.js';\r\n\r\n// Action Streaming - async generator-based streaming actions\r\nexport * from './streaming.js';\r\n\r\n// Action Queue - offline-first action queuing\r\nexport * from './queue.js';\r\n\r\n"]}
@@ -201,5 +201,5 @@ function getRedirectInfo(error) {
201
201
  }
202
202
 
203
203
  export { acceptsJson, createServerContext, deleteCookie, getHeader, getHeaders, getPreferredLanguage, getRedirectInfo, isAjaxRequest, isBotRequest, isMutationRequest, isNotFoundError, isRedirectError, notFound, redirect, setCacheControl, setCookie, supportsStreaming };
204
- //# sourceMappingURL=chunk-CKJHJPKQ.js.map
205
- //# sourceMappingURL=chunk-CKJHJPKQ.js.map
204
+ //# sourceMappingURL=chunk-62C7LX2E.js.map
205
+ //# sourceMappingURL=chunk-62C7LX2E.js.map