@flight-framework/core 0.1.0 → 0.2.1

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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/dist/{chunk-5KF3QQWZ.js → chunk-3ZSSRE6M.js} +5 -19
  3. package/dist/chunk-3ZSSRE6M.js.map +1 -0
  4. package/dist/chunk-4S5JWTGN.js +218 -0
  5. package/dist/chunk-4S5JWTGN.js.map +1 -0
  6. package/dist/chunk-62C7LX2E.js +205 -0
  7. package/dist/chunk-62C7LX2E.js.map +1 -0
  8. package/dist/chunk-63SCEXD7.js +3 -0
  9. package/dist/chunk-63SCEXD7.js.map +1 -0
  10. package/dist/{chunk-YIOQC3DC.js → chunk-6BDCTUQY.js} +3 -3
  11. package/dist/{chunk-YIOQC3DC.js.map → chunk-6BDCTUQY.js.map} +1 -1
  12. package/dist/chunk-6Z2RYHEU.js +212 -0
  13. package/dist/chunk-6Z2RYHEU.js.map +1 -0
  14. package/dist/chunk-HAX5OAB6.js +324 -0
  15. package/dist/chunk-HAX5OAB6.js.map +1 -0
  16. package/dist/chunk-K2CQZPCG.js +257 -0
  17. package/dist/chunk-K2CQZPCG.js.map +1 -0
  18. package/dist/chunk-N3TUOEV4.js +213 -0
  19. package/dist/chunk-N3TUOEV4.js.map +1 -0
  20. package/dist/chunk-NWMJYTMB.js +300 -0
  21. package/dist/chunk-NWMJYTMB.js.map +1 -0
  22. package/dist/chunk-OCVLNLTI.js +252 -0
  23. package/dist/chunk-OCVLNLTI.js.map +1 -0
  24. package/dist/chunk-PDW5WCMW.js +258 -0
  25. package/dist/chunk-PDW5WCMW.js.map +1 -0
  26. package/dist/chunk-PVUMB632.js +256 -0
  27. package/dist/chunk-PVUMB632.js.map +1 -0
  28. package/dist/{chunk-6WSPUG5L.js → chunk-RSVA2EYO.js} +2 -2
  29. package/dist/chunk-RSVA2EYO.js.map +1 -0
  30. package/dist/chunk-T4Z4HM4W.js +285 -0
  31. package/dist/chunk-T4Z4HM4W.js.map +1 -0
  32. package/dist/{chunk-OBNYNJB5.js → chunk-WOEIJWGJ.js} +6 -8
  33. package/dist/chunk-WOEIJWGJ.js.map +1 -0
  34. package/dist/{chunk-I2B4WSHC.js → chunk-XSY5AAXT.js} +3 -4
  35. package/dist/chunk-XSY5AAXT.js.map +1 -0
  36. package/dist/chunk-Y22AMGTM.js +3 -0
  37. package/dist/chunk-Y22AMGTM.js.map +1 -0
  38. package/dist/chunk-ZIE56LCA.js +341 -0
  39. package/dist/chunk-ZIE56LCA.js.map +1 -0
  40. package/dist/file-router/streaming-hints.d.ts +1 -1
  41. package/dist/file-router/streaming-hints.js +1 -1
  42. package/dist/index.d.ts +3 -1
  43. package/dist/index.js +19 -7
  44. package/dist/index.js.map +1 -1
  45. package/dist/rsc/adapters/index.d.ts +8 -0
  46. package/dist/rsc/adapters/index.js +7 -0
  47. package/dist/rsc/adapters/index.js.map +1 -0
  48. package/dist/rsc/adapters/preact.d.ts +97 -0
  49. package/dist/rsc/adapters/preact.js +3 -0
  50. package/dist/rsc/adapters/preact.js.map +1 -0
  51. package/dist/rsc/adapters/react.d.ts +82 -0
  52. package/dist/rsc/adapters/react.js +3 -0
  53. package/dist/rsc/adapters/react.js.map +1 -0
  54. package/dist/rsc/adapters/solid.d.ts +84 -0
  55. package/dist/rsc/adapters/solid.js +3 -0
  56. package/dist/rsc/adapters/solid.js.map +1 -0
  57. package/dist/rsc/adapters/vue.d.ts +80 -0
  58. package/dist/rsc/adapters/vue.js +3 -0
  59. package/dist/rsc/adapters/vue.js.map +1 -0
  60. package/dist/rsc/boundaries.d.ts +182 -0
  61. package/dist/rsc/boundaries.js +3 -0
  62. package/dist/rsc/boundaries.js.map +1 -0
  63. package/dist/rsc/context.d.ts +201 -0
  64. package/dist/rsc/context.js +3 -0
  65. package/dist/rsc/context.js.map +1 -0
  66. package/dist/rsc/index.d.ts +20 -124
  67. package/dist/rsc/index.js +13 -1
  68. package/dist/rsc/legacy.d.ts +131 -0
  69. package/dist/rsc/legacy.js +3 -0
  70. package/dist/rsc/legacy.js.map +1 -0
  71. package/dist/rsc/payload.d.ts +262 -0
  72. package/dist/rsc/payload.js +3 -0
  73. package/dist/rsc/payload.js.map +1 -0
  74. package/dist/rsc/plugins/esbuild.d.ts +124 -0
  75. package/dist/rsc/plugins/esbuild.js +4 -0
  76. package/dist/rsc/plugins/esbuild.js.map +1 -0
  77. package/dist/rsc/plugins/index.d.ts +4 -0
  78. package/dist/rsc/plugins/index.js +6 -0
  79. package/dist/rsc/plugins/index.js.map +1 -0
  80. package/dist/rsc/plugins/rollup.d.ts +103 -0
  81. package/dist/rsc/plugins/rollup.js +4 -0
  82. package/dist/rsc/plugins/rollup.js.map +1 -0
  83. package/dist/rsc/renderer.d.ts +160 -0
  84. package/dist/rsc/renderer.js +5 -0
  85. package/dist/rsc/renderer.js.map +1 -0
  86. package/dist/rsc/stream.d.ts +129 -0
  87. package/dist/rsc/stream.js +3 -0
  88. package/dist/rsc/stream.js.map +1 -0
  89. package/dist/rsc/vite-plugin.d.ts +78 -0
  90. package/dist/rsc/vite-plugin.js +4 -0
  91. package/dist/rsc/vite-plugin.js.map +1 -0
  92. package/dist/streaming/index.js +1 -1
  93. package/dist/streaming/observability.js +2 -2
  94. package/dist/streaming/priority.js +1 -1
  95. package/package.json +180 -124
  96. package/dist/chunk-5KF3QQWZ.js.map +0 -1
  97. package/dist/chunk-6WSPUG5L.js.map +0 -1
  98. package/dist/chunk-I2B4WSHC.js.map +0 -1
  99. package/dist/chunk-OBNYNJB5.js.map +0 -1
package/package.json CHANGED
@@ -1,125 +1,181 @@
1
- {
2
- "name": "@flight-framework/core",
3
- "version": "0.1.0",
4
- "description": "Core primitives for Flight Framework - routing, rendering, caching",
5
- "keywords": [
6
- "flight",
7
- "framework",
8
- "core",
9
- "ssr",
10
- "routing"
11
- ],
12
- "license": "MIT",
13
- "author": "Flight Contributors",
14
- "type": "module",
15
- "exports": {
16
- ".": {
17
- "types": "./dist/index.d.ts",
18
- "import": "./dist/index.js"
19
- },
20
- "./router": {
21
- "types": "./dist/router/index.d.ts",
22
- "import": "./dist/router/index.js"
23
- },
24
- "./render": {
25
- "types": "./dist/render/index.d.ts",
26
- "import": "./dist/render/index.js"
27
- },
28
- "./cache": {
29
- "types": "./dist/cache/index.d.ts",
30
- "import": "./dist/cache/index.js"
31
- },
32
- "./middleware": {
33
- "types": "./dist/middleware/index.d.ts",
34
- "import": "./dist/middleware/index.js"
35
- },
36
- "./config": {
37
- "types": "./dist/config/index.d.ts",
38
- "import": "./dist/config/index.js"
39
- },
40
- "./adapters": {
41
- "types": "./dist/adapters/index.d.ts",
42
- "import": "./dist/adapters/index.js"
43
- },
44
- "./server": {
45
- "types": "./dist/server/index.d.ts",
46
- "import": "./dist/server/index.js"
47
- },
48
- "./file-router": {
49
- "types": "./dist/file-router/index.d.ts",
50
- "import": "./dist/file-router/index.js"
51
- },
52
- "./actions": {
53
- "types": "./dist/actions/index.d.ts",
54
- "import": "./dist/actions/index.js"
55
- },
56
- "./handlers": {
57
- "types": "./dist/handlers/index.d.ts",
58
- "import": "./dist/handlers/index.js"
59
- },
60
- "./streaming": {
61
- "types": "./dist/streaming/index.d.ts",
62
- "import": "./dist/streaming/index.js"
63
- },
64
- "./streaming/priority": {
65
- "types": "./dist/streaming/priority.d.ts",
66
- "import": "./dist/streaming/priority.js"
67
- },
68
- "./streaming/observability": {
69
- "types": "./dist/streaming/observability.d.ts",
70
- "import": "./dist/streaming/observability.js"
71
- },
72
- "./streaming/conditional": {
73
- "types": "./dist/streaming/conditional.d.ts",
74
- "import": "./dist/streaming/conditional.js"
75
- },
76
- "./streaming/adapters": {
77
- "types": "./dist/streaming/adapters/index.d.ts",
78
- "import": "./dist/streaming/adapters/index.js"
79
- },
80
- "./islands": {
81
- "types": "./dist/islands/index.d.ts",
82
- "import": "./dist/islands/index.js"
83
- },
84
- "./file-router/streaming-hints": {
85
- "types": "./dist/file-router/streaming-hints.d.ts",
86
- "import": "./dist/file-router/streaming-hints.js"
87
- },
88
- "./rsc": {
89
- "types": "./dist/rsc/index.d.ts",
90
- "import": "./dist/rsc/index.js"
91
- }
92
- },
93
- "main": "./dist/index.js",
94
- "types": "./dist/index.d.ts",
95
- "files": [
96
- "dist"
97
- ],
98
- "scripts": {
99
- "build": "tsup",
100
- "dev": "tsup --watch",
101
- "test": "vitest run",
102
- "test:watch": "vitest",
103
- "lint": "eslint src/",
104
- "clean": "rimraf dist",
105
- "typecheck": "tsc --noEmit"
106
- },
107
- "dependencies": {
108
- "radix3": "^1.1.0"
109
- },
110
- "devDependencies": {
111
- "@types/node": "^22.0.0",
112
- "rimraf": "^6.0.0",
113
- "tsup": "^8.0.0",
114
- "typescript": "^5.7.0",
115
- "vitest": "^2.0.0"
116
- },
117
- "peerDependencies": {
118
- "vite": "^6.0.0 || ^7.0.0"
119
- },
120
- "peerDependenciesMeta": {
121
- "vite": {
122
- "optional": true
123
- }
124
- }
1
+ {
2
+ "name": "@flight-framework/core",
3
+ "version": "0.2.1",
4
+ "description": "Core primitives for Flight Framework - routing, rendering, caching",
5
+ "keywords": [
6
+ "flight",
7
+ "framework",
8
+ "core",
9
+ "ssr",
10
+ "routing"
11
+ ],
12
+ "license": "MIT",
13
+ "author": "Flight Contributors",
14
+ "type": "module",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js"
19
+ },
20
+ "./router": {
21
+ "types": "./dist/router/index.d.ts",
22
+ "import": "./dist/router/index.js"
23
+ },
24
+ "./render": {
25
+ "types": "./dist/render/index.d.ts",
26
+ "import": "./dist/render/index.js"
27
+ },
28
+ "./cache": {
29
+ "types": "./dist/cache/index.d.ts",
30
+ "import": "./dist/cache/index.js"
31
+ },
32
+ "./middleware": {
33
+ "types": "./dist/middleware/index.d.ts",
34
+ "import": "./dist/middleware/index.js"
35
+ },
36
+ "./config": {
37
+ "types": "./dist/config/index.d.ts",
38
+ "import": "./dist/config/index.js"
39
+ },
40
+ "./adapters": {
41
+ "types": "./dist/adapters/index.d.ts",
42
+ "import": "./dist/adapters/index.js"
43
+ },
44
+ "./server": {
45
+ "types": "./dist/server/index.d.ts",
46
+ "import": "./dist/server/index.js"
47
+ },
48
+ "./file-router": {
49
+ "types": "./dist/file-router/index.d.ts",
50
+ "import": "./dist/file-router/index.js"
51
+ },
52
+ "./actions": {
53
+ "types": "./dist/actions/index.d.ts",
54
+ "import": "./dist/actions/index.js"
55
+ },
56
+ "./handlers": {
57
+ "types": "./dist/handlers/index.d.ts",
58
+ "import": "./dist/handlers/index.js"
59
+ },
60
+ "./streaming": {
61
+ "types": "./dist/streaming/index.d.ts",
62
+ "import": "./dist/streaming/index.js"
63
+ },
64
+ "./streaming/priority": {
65
+ "types": "./dist/streaming/priority.d.ts",
66
+ "import": "./dist/streaming/priority.js"
67
+ },
68
+ "./streaming/observability": {
69
+ "types": "./dist/streaming/observability.d.ts",
70
+ "import": "./dist/streaming/observability.js"
71
+ },
72
+ "./streaming/conditional": {
73
+ "types": "./dist/streaming/conditional.d.ts",
74
+ "import": "./dist/streaming/conditional.js"
75
+ },
76
+ "./streaming/adapters": {
77
+ "types": "./dist/streaming/adapters/index.d.ts",
78
+ "import": "./dist/streaming/adapters/index.js"
79
+ },
80
+ "./islands": {
81
+ "types": "./dist/islands/index.d.ts",
82
+ "import": "./dist/islands/index.js"
83
+ },
84
+ "./file-router/streaming-hints": {
85
+ "types": "./dist/file-router/streaming-hints.d.ts",
86
+ "import": "./dist/file-router/streaming-hints.js"
87
+ },
88
+ "./rsc": {
89
+ "types": "./dist/rsc/index.d.ts",
90
+ "import": "./dist/rsc/index.js"
91
+ },
92
+ "./rsc/payload": {
93
+ "types": "./dist/rsc/payload.d.ts",
94
+ "import": "./dist/rsc/payload.js"
95
+ },
96
+ "./rsc/boundaries": {
97
+ "types": "./dist/rsc/boundaries.d.ts",
98
+ "import": "./dist/rsc/boundaries.js"
99
+ },
100
+ "./rsc/context": {
101
+ "types": "./dist/rsc/context.d.ts",
102
+ "import": "./dist/rsc/context.js"
103
+ },
104
+ "./rsc/stream": {
105
+ "types": "./dist/rsc/stream.d.ts",
106
+ "import": "./dist/rsc/stream.js"
107
+ },
108
+ "./rsc/renderer": {
109
+ "types": "./dist/rsc/renderer.d.ts",
110
+ "import": "./dist/rsc/renderer.js"
111
+ },
112
+ "./rsc/vite-plugin": {
113
+ "types": "./dist/rsc/vite-plugin.d.ts",
114
+ "import": "./dist/rsc/vite-plugin.js"
115
+ },
116
+ "./rsc/adapters": {
117
+ "types": "./dist/rsc/adapters/index.d.ts",
118
+ "import": "./dist/rsc/adapters/index.js"
119
+ },
120
+ "./rsc/adapters/react": {
121
+ "types": "./dist/rsc/adapters/react.d.ts",
122
+ "import": "./dist/rsc/adapters/react.js"
123
+ },
124
+ "./rsc/adapters/vue": {
125
+ "types": "./dist/rsc/adapters/vue.d.ts",
126
+ "import": "./dist/rsc/adapters/vue.js"
127
+ },
128
+ "./rsc/adapters/solid": {
129
+ "types": "./dist/rsc/adapters/solid.d.ts",
130
+ "import": "./dist/rsc/adapters/solid.js"
131
+ },
132
+ "./rsc/adapters/preact": {
133
+ "types": "./dist/rsc/adapters/preact.d.ts",
134
+ "import": "./dist/rsc/adapters/preact.js"
135
+ },
136
+ "./rsc/plugins": {
137
+ "types": "./dist/rsc/plugins/index.d.ts",
138
+ "import": "./dist/rsc/plugins/index.js"
139
+ },
140
+ "./rsc/plugins/esbuild": {
141
+ "types": "./dist/rsc/plugins/esbuild.d.ts",
142
+ "import": "./dist/rsc/plugins/esbuild.js"
143
+ },
144
+ "./rsc/plugins/rollup": {
145
+ "types": "./dist/rsc/plugins/rollup.d.ts",
146
+ "import": "./dist/rsc/plugins/rollup.js"
147
+ }
148
+ },
149
+ "main": "./dist/index.js",
150
+ "types": "./dist/index.d.ts",
151
+ "files": [
152
+ "dist"
153
+ ],
154
+ "dependencies": {
155
+ "radix3": "^1.1.0"
156
+ },
157
+ "devDependencies": {
158
+ "@types/node": "^22.0.0",
159
+ "rimraf": "^6.0.0",
160
+ "tsup": "^8.0.0",
161
+ "typescript": "^5.7.0",
162
+ "vitest": "^2.0.0"
163
+ },
164
+ "peerDependencies": {
165
+ "vite": "^6.0.0 || ^7.0.0"
166
+ },
167
+ "peerDependenciesMeta": {
168
+ "vite": {
169
+ "optional": true
170
+ }
171
+ },
172
+ "scripts": {
173
+ "build": "tsup",
174
+ "dev": "tsup --watch",
175
+ "test": "vitest run",
176
+ "test:watch": "vitest",
177
+ "lint": "eslint src/",
178
+ "clean": "rimraf dist",
179
+ "typecheck": "tsc --noEmit"
180
+ }
125
181
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/rsc/index.ts"],"names":[],"mappings":"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","file":"chunk-5KF3QQWZ.js","sourcesContent":["/**\r\n * @flight-framework/core - React Server Components Support\r\n * \r\n * Framework-agnostic primitives for RSC-like patterns.\r\n * Enables async server components, client/server boundaries, and data fetching.\r\n * \r\n * Best Practices 2025/2026:\r\n * - Async components for server-side data fetching\r\n * - 'use client' / 'use server' directive detection\r\n * - Automatic component serialization\r\n * - Props passing between server and client\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Component rendering context\r\n */\r\nexport interface RenderContext {\r\n /** Current request */\r\n request: Request;\r\n /** Route params */\r\n params: Record<string, string>;\r\n /** Search params */\r\n searchParams: URLSearchParams;\r\n /** Request headers */\r\n headers: Headers;\r\n /** Cookies */\r\n cookies: Map<string, string>;\r\n}\r\n\r\n/**\r\n * Server component definition\r\n */\r\nexport interface ServerComponent<P = unknown> {\r\n (props: P, context: RenderContext): Promise<string> | string;\r\n /** Mark as server component */\r\n __flight_server?: true;\r\n /** Dependencies for hydration */\r\n __flight_deps?: string[];\r\n}\r\n\r\n/**\r\n * Client component definition\r\n */\r\nexport interface ClientComponent<P = unknown> {\r\n (props: P): unknown;\r\n /** Mark as client component */\r\n __flight_client?: true;\r\n /** Client bundle path */\r\n __flight_bundle?: string;\r\n}\r\n\r\n/**\r\n * Component type detection\r\n */\r\nexport type ComponentType = 'server' | 'client' | 'hybrid';\r\n\r\n// ============================================================================\r\n// Directive Detection (Build-time)\r\n// ============================================================================\r\n\r\n/**\r\n * Check if a file has 'use client' directive\r\n */\r\nexport function hasUseClientDirective(source: string): boolean {\r\n const firstLine = source.trim().split('\\n')[0] ?? '';\r\n return /^['\"]use client['\"];?/.test(firstLine);\r\n}\r\n\r\n/**\r\n * Check if a file has 'use server' directive\r\n */\r\nexport function hasUseServerDirective(source: string): boolean {\r\n const firstLine = source.trim().split('\\n')[0] ?? '';\r\n return /^['\"]use server['\"];?/.test(firstLine);\r\n}\r\n\r\n/**\r\n * Detect component type from source\r\n */\r\nexport function detectComponentType(source: string): ComponentType {\r\n if (hasUseClientDirective(source)) return 'client';\r\n if (hasUseServerDirective(source)) return 'server';\r\n return 'hybrid';\r\n}\r\n\r\n// ============================================================================\r\n// Server Component Execution\r\n// ============================================================================\r\n\r\n/**\r\n * Execute an async server component\r\n */\r\nexport async function executeServerComponent<P>(\r\n component: ServerComponent<P>,\r\n props: P,\r\n context: RenderContext\r\n): Promise<string> {\r\n try {\r\n const result = await component(props, context);\r\n return result;\r\n } catch (error) {\r\n console.error('[Flight] Server component error:', error);\r\n throw error;\r\n }\r\n}\r\n\r\n/**\r\n * Create a render context from a Request\r\n */\r\nexport function createRenderContext(request: Request, params: Record<string, string> = {}): RenderContext {\r\n const url = new URL(request.url);\r\n\r\n // Parse cookies\r\n const cookies = new Map<string, string>();\r\n const cookieHeader = request.headers.get('cookie') || '';\r\n cookieHeader.split(';').forEach(cookie => {\r\n const [key, value] = cookie.trim().split('=');\r\n if (key && value) cookies.set(key, value);\r\n });\r\n\r\n return {\r\n request,\r\n params,\r\n searchParams: url.searchParams,\r\n headers: request.headers,\r\n cookies,\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Data Fetching Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Cache for server-side fetch requests\r\n */\r\nconst fetchCache = new Map<string, { data: unknown; timestamp: number }>();\r\n\r\n/**\r\n * Server-side fetch with automatic caching (like Next.js fetch extensions)\r\n */\r\nexport async function serverFetch<T>(\r\n url: string,\r\n options: RequestInit & {\r\n revalidate?: number | false;\r\n tags?: string[];\r\n } = {}\r\n): Promise<T> {\r\n const { revalidate = 60, tags = [], ...fetchOptions } = options;\r\n const cacheKey = `${url}:${JSON.stringify(fetchOptions)}`;\r\n\r\n // Check cache\r\n const cached = fetchCache.get(cacheKey);\r\n if (cached) {\r\n const age = Date.now() - cached.timestamp;\r\n if (revalidate === false || age < (revalidate * 1000)) {\r\n return cached.data as T;\r\n }\r\n }\r\n\r\n // Fetch fresh data\r\n const response = await fetch(url, fetchOptions);\r\n\r\n if (!response.ok) {\r\n throw new Error(`Fetch failed: ${response.status} ${response.statusText}`);\r\n }\r\n\r\n const data = await response.json();\r\n\r\n // Cache the result\r\n if (revalidate !== false) {\r\n fetchCache.set(cacheKey, {\r\n data,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n return data as T;\r\n}\r\n\r\n/**\r\n * Invalidate cache by tag\r\n */\r\nexport function revalidateTag(tag: string): void {\r\n // In a real implementation, this would invalidate cache entries by tag\r\n console.log(`[Flight] Revalidating tag: ${tag}`);\r\n}\r\n\r\n/**\r\n * Invalidate cache by path\r\n */\r\nexport function revalidatePath(path: string): void {\r\n // In a real implementation, this would invalidate cache entries by path\r\n console.log(`[Flight] Revalidating path: ${path}`);\r\n}\r\n\r\n// ============================================================================\r\n// Component Serialization (for client boundary crossing)\r\n// ============================================================================\r\n\r\n/**\r\n * Serialize props for transmission to client\r\n */\r\nexport function serializeProps(props: unknown): string {\r\n // Pre-process to handle special types before JSON.stringify\r\n function preProcess(value: unknown): unknown {\r\n if (value instanceof Date) {\r\n return { __type: 'Date', value: value.toISOString() };\r\n }\r\n if (value instanceof Map) {\r\n return { __type: 'Map', value: Array.from(value.entries()).map(([k, v]) => [preProcess(k), preProcess(v)]) };\r\n }\r\n if (value instanceof Set) {\r\n return { __type: 'Set', value: Array.from(value).map(preProcess) };\r\n }\r\n if (typeof value === 'bigint') {\r\n return { __type: 'BigInt', value: value.toString() };\r\n }\r\n if (typeof value === 'function') {\r\n return undefined;\r\n }\r\n if (Array.isArray(value)) {\r\n return value.map(preProcess);\r\n }\r\n if (value && typeof value === 'object') {\r\n const result: Record<string, unknown> = {};\r\n for (const [k, v] of Object.entries(value)) {\r\n result[k] = preProcess(v);\r\n }\r\n return result;\r\n }\r\n return value;\r\n }\r\n\r\n return JSON.stringify(preProcess(props));\r\n}\r\n\r\n/**\r\n * Deserialize props on client\r\n */\r\nexport function deserializeProps<T>(serialized: string): T {\r\n return JSON.parse(serialized, (_key, value) => {\r\n if (value && typeof value === 'object' && '__type' in value) {\r\n switch (value.__type) {\r\n case 'Date':\r\n return new Date(value.value);\r\n case 'Map':\r\n return new Map(value.value);\r\n case 'Set':\r\n return new Set(value.value);\r\n case 'BigInt':\r\n return BigInt(value.value);\r\n }\r\n }\r\n return value;\r\n });\r\n}\r\n\r\n// ============================================================================\r\n// Client Component Boundary\r\n// ============================================================================\r\n\r\n/**\r\n * Create a client boundary placeholder\r\n */\r\nexport function createClientBoundary(\r\n componentId: string,\r\n props: unknown,\r\n fallback?: string\r\n): string {\r\n const serializedProps = serializeProps(props);\r\n\r\n return `\r\n<!--flight-client:${componentId}-->\r\n<div data-flight-component=\"${componentId}\" data-flight-props='${serializedProps.replace(/'/g, \"&#39;\")}'>\r\n ${fallback || '<div>Loading...</div>'}\r\n</div>\r\n<!--/flight-client-->\r\n<script type=\"module\">\r\n(async function() {\r\n const component = await import('/_flight/components/${componentId}.js');\r\n const props = JSON.parse('${serializedProps.replace(/'/g, \"\\\\'\")}');\r\n const container = document.querySelector('[data-flight-component=\"${componentId}\"]');\r\n if (container && component.default) {\r\n // Hydrate with the framework's hydration method\r\n if (typeof component.hydrate === 'function') {\r\n component.hydrate(container, props);\r\n }\r\n }\r\n})();\r\n</script>`;\r\n}\r\n\r\n// ============================================================================\r\n// Async Component Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Helper to create an async server component\r\n */\r\nexport function createAsyncComponent<P, T>(\r\n fetcher: (props: P, context: RenderContext) => Promise<T>,\r\n renderer: (data: T, props: P) => string\r\n): ServerComponent<P> {\r\n const component: ServerComponent<P> = async (props, context) => {\r\n const data = await fetcher(props, context);\r\n return renderer(data, props);\r\n };\r\n component.__flight_server = true;\r\n return component;\r\n}\r\n\r\n/**\r\n * Compose multiple server components\r\n */\r\nexport function composeComponents(\r\n ...components: Array<() => Promise<string> | string>\r\n): () => Promise<string> {\r\n return async () => {\r\n const results = await Promise.all(\r\n components.map(async (comp) => await comp())\r\n );\r\n return results.join('');\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Error Boundary for Server Components\r\n// ============================================================================\r\n\r\n/**\r\n * Wrap a server component with error handling\r\n */\r\nexport function withErrorBoundary<P>(\r\n component: ServerComponent<P>,\r\n errorFallback: (error: Error) => string\r\n): ServerComponent<P> {\r\n return async (props: P, context: RenderContext) => {\r\n try {\r\n return await component(props, context);\r\n } catch (error) {\r\n console.error('[Flight] Server component error:', error);\r\n return errorFallback(error as Error);\r\n }\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Not Found / Redirect Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Throw a not found error (like Next.js notFound())\r\n */\r\nexport function notFound(): never {\r\n const error = new Error('Not Found');\r\n (error as any).__flight_not_found = true;\r\n throw error;\r\n}\r\n\r\n/**\r\n * Check if error is not found\r\n */\r\nexport function isNotFoundError(error: unknown): boolean {\r\n return error instanceof Error && (error as any).__flight_not_found === true;\r\n}\r\n\r\n/**\r\n * Server-side redirect (like Next.js redirect())\r\n */\r\nexport function redirect(url: string, type: 'replace' | 'push' = 'replace'): never {\r\n const error = new Error(`Redirect: ${url}`);\r\n (error as any).__flight_redirect = { url, type };\r\n throw error;\r\n}\r\n\r\n/**\r\n * Check if error is redirect\r\n */\r\nexport function isRedirectError(error: unknown): { url: string; type: string } | null {\r\n if (error instanceof Error && (error as any).__flight_redirect) {\r\n return (error as any).__flight_redirect;\r\n }\r\n return null;\r\n}\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/streaming/index.ts"],"names":[],"mappings":"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","file":"chunk-6WSPUG5L.js","sourcesContent":["/**\r\n * @flight-framework/core - Streaming SSR\r\n * \r\n * Full streaming server-side rendering implementation following React 18+/19 patterns.\r\n * Supports both Node.js (renderToPipeableStream) and Edge (renderToReadableStream) environments.\r\n * \r\n * Best Practices 2025/2026:\r\n * - Progressive HTML streaming with Suspense boundaries\r\n * - Shell-first rendering for fast TTFB\r\n * - Nested Suspense for granular loading states\r\n * - Error boundaries for graceful degradation\r\n * - Web Streams API for Edge runtime compatibility\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Streaming render options following React's conventions\r\n */\r\nexport interface StreamingRenderOptions {\r\n /** Bootstrap scripts to load on client */\r\n bootstrapScripts?: string[];\r\n /** Bootstrap ES modules */\r\n bootstrapModules?: string[];\r\n /** Inline script content */\r\n bootstrapScriptContent?: string;\r\n /** Prefix for React IDs (useId) */\r\n identifierPrefix?: string;\r\n /** Nonce for CSP */\r\n nonce?: string;\r\n /** Callback when shell is ready (main content before Suspense) */\r\n onShellReady?: () => void;\r\n /** Callback when shell errors */\r\n onShellError?: (error: Error) => void;\r\n /** Callback when all content is ready */\r\n onAllReady?: () => void;\r\n /** Callback for any error */\r\n onError?: (error: Error) => void;\r\n /** Timeout before aborting stream */\r\n timeoutMs?: number;\r\n /** Progressive hydration enabled */\r\n progressiveHydration?: boolean;\r\n}\r\n\r\n/**\r\n * Streaming render result\r\n */\r\nexport interface StreamingRenderResult {\r\n /** The readable stream to pipe to response */\r\n stream: ReadableStream<Uint8Array>;\r\n /** Abort the stream */\r\n abort: () => void;\r\n /** Promise that resolves when shell is ready */\r\n shellReady: Promise<void>;\r\n /** Promise that resolves when all content is ready */\r\n allReady: Promise<void>;\r\n}\r\n\r\n/**\r\n * Suspense boundary configuration\r\n */\r\nexport interface SuspenseBoundaryConfig {\r\n /** Unique ID for this boundary */\r\n id: string;\r\n /** Fallback HTML to show while loading */\r\n fallback: string;\r\n /** Content resolver promise */\r\n contentPromise: Promise<string>;\r\n /** \r\n * IDs of boundaries that must resolve before this one.\r\n * Enables dependency-aware streaming for complex data relationships.\r\n * @example ['user'] - Wait for 'user' boundary before starting\r\n */\r\n dependsOn?: string[];\r\n /** Custom metadata for observability */\r\n meta?: Record<string, unknown>;\r\n}\r\n\r\n// ============================================================================\r\n// Streaming Renderer\r\n// ============================================================================\r\n\r\n/**\r\n * Create a streaming SSR response using Web Streams API.\r\n * Compatible with Edge Runtime (Cloudflare, Vercel Edge, Deno).\r\n * \r\n * @example\r\n * ```typescript\r\n * const result = await createStreamingSSR({\r\n * shell: '<html><body><div id=\"root\">',\r\n * shellEnd: '</div></body></html>',\r\n * suspenseBoundaries: [\r\n * {\r\n * id: 'posts',\r\n * fallback: '<div>Loading posts...</div>',\r\n * contentPromise: fetchAndRenderPosts(),\r\n * }\r\n * ],\r\n * bootstrapScripts: ['/client.js'],\r\n * });\r\n * \r\n * return new Response(result.stream, {\r\n * headers: { 'Content-Type': 'text/html' },\r\n * });\r\n * ```\r\n */\r\nexport async function createStreamingSSR(config: {\r\n /** Initial HTML shell (before suspense content) */\r\n shell: string;\r\n /** Closing HTML shell */\r\n shellEnd: string;\r\n /** Suspense boundaries with async content */\r\n suspenseBoundaries?: SuspenseBoundaryConfig[];\r\n /** Streaming options */\r\n options?: StreamingRenderOptions;\r\n}): Promise<StreamingRenderResult> {\r\n const { shell, shellEnd, suspenseBoundaries = [], options = {} } = config;\r\n\r\n let shellResolved = false;\r\n let allResolved = false;\r\n let _aborted = false;\r\n let abortController: AbortController | null = null;\r\n\r\n // Shell ready promise\r\n let resolveShell: () => void;\r\n const shellReady = new Promise<void>((resolve) => {\r\n resolveShell = resolve;\r\n });\r\n\r\n // All ready promise\r\n let resolveAll: () => void;\r\n const allReady = new Promise<void>((resolve) => {\r\n resolveAll = resolve;\r\n });\r\n\r\n const encoder = new TextEncoder();\r\n\r\n const stream = new ReadableStream<Uint8Array>({\r\n async start(controller) {\r\n try {\r\n // 1. Send the shell immediately (fast TTFB)\r\n const shellWithPlaceholders = buildShellWithPlaceholders(\r\n shell,\r\n suspenseBoundaries,\r\n shellEnd,\r\n options\r\n );\r\n\r\n controller.enqueue(encoder.encode(shellWithPlaceholders));\r\n\r\n shellResolved = true;\r\n options.onShellReady?.();\r\n resolveShell!();\r\n\r\n // 2. Stream Suspense boundary contents as they resolve\r\n if (suspenseBoundaries.length > 0) {\r\n await streamSuspenseContent(controller, encoder, suspenseBoundaries, options);\r\n }\r\n\r\n // 3. Send hydration script if needed\r\n if (options.bootstrapScripts?.length || options.bootstrapModules?.length) {\r\n const hydrationScript = buildHydrationScript(options);\r\n controller.enqueue(encoder.encode(hydrationScript));\r\n }\r\n\r\n allResolved = true;\r\n options.onAllReady?.();\r\n resolveAll!();\r\n\r\n controller.close();\r\n } catch (error) {\r\n if (!shellResolved) {\r\n options.onShellError?.(error as Error);\r\n }\r\n options.onError?.(error as Error);\r\n controller.error(error);\r\n }\r\n },\r\n\r\n cancel() {\r\n _aborted = true;\r\n abortController?.abort();\r\n },\r\n });\r\n\r\n // Abort function\r\n const abort = () => {\r\n _aborted = true;\r\n abortController?.abort();\r\n };\r\n\r\n // Timeout handling\r\n if (options.timeoutMs) {\r\n abortController = new AbortController();\r\n setTimeout(() => {\r\n if (!allResolved) {\r\n abort();\r\n }\r\n }, options.timeoutMs);\r\n }\r\n\r\n return {\r\n stream,\r\n abort,\r\n shellReady,\r\n allReady,\r\n };\r\n}\r\n\r\n/**\r\n * Build shell HTML with Suspense placeholders\r\n */\r\nfunction buildShellWithPlaceholders(\r\n shell: string,\r\n boundaries: SuspenseBoundaryConfig[],\r\n shellEnd: string,\r\n options: StreamingRenderOptions\r\n): string {\r\n let html = shell;\r\n\r\n // Add inline bootstrap script if provided\r\n if (options.bootstrapScriptContent) {\r\n html += `<script>${options.bootstrapScriptContent}</script>`;\r\n }\r\n\r\n // Add Suspense fallbacks with placeholder markers\r\n for (const boundary of boundaries) {\r\n html += `\r\n<!--$?--><template id=\"B:${boundary.id}\"></template>\r\n${boundary.fallback}\r\n<!--/$-->`;\r\n }\r\n\r\n html += shellEnd;\r\n\r\n return html;\r\n}\r\n\r\n/**\r\n * Stream Suspense content as promises resolve\r\n */\r\nasync function streamSuspenseContent(\r\n controller: ReadableStreamDefaultController<Uint8Array>,\r\n encoder: TextEncoder,\r\n boundaries: SuspenseBoundaryConfig[],\r\n options: StreamingRenderOptions\r\n): Promise<void> {\r\n // Race all boundaries - stream each as it completes\r\n const pending = boundaries.map(async (boundary) => {\r\n try {\r\n const content = await boundary.contentPromise;\r\n return { boundary, content, error: null };\r\n } catch (error) {\r\n return { boundary, content: null, error: error as Error };\r\n }\r\n });\r\n\r\n // Process as each resolves\r\n const results = await Promise.allSettled(pending);\r\n\r\n for (const result of results) {\r\n if (result.status === 'fulfilled') {\r\n const { boundary, content, error } = result.value;\r\n\r\n if (error) {\r\n // Send error replacement\r\n const errorScript = buildErrorReplacement(boundary.id, error.message);\r\n controller.enqueue(encoder.encode(errorScript));\r\n options.onError?.(error);\r\n } else if (content) {\r\n // Send content replacement script\r\n const replacementScript = buildContentReplacement(boundary.id, content);\r\n controller.enqueue(encoder.encode(replacementScript));\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Build script to replace Suspense placeholder with actual content\r\n * This follows React's streaming hydration pattern\r\n */\r\nfunction buildContentReplacement(id: string, content: string): string {\r\n // Escape script-breaking characters\r\n const escaped = content\r\n .replace(/\\\\/g, '\\\\\\\\')\r\n .replace(/</g, '\\\\u003c')\r\n .replace(/>/g, '\\\\u003e')\r\n .replace(/'/g, \"\\\\'\")\r\n .replace(/\"/g, '\\\\\"')\r\n .replace(/\\n/g, '\\\\n')\r\n .replace(/\\r/g, '\\\\r');\r\n\r\n return `\r\n<script>\r\n(function(){\r\n var b=document.getElementById(\"B:${id}\");\r\n if(b){\r\n var p=b.previousSibling;\r\n while(p&&p.nodeType===8&&p.data===\"$?\")p=p.previousSibling;\r\n var n=b.nextSibling;\r\n var f=document.createDocumentFragment();\r\n var t=document.createElement(\"template\");\r\n t.innerHTML=\"${escaped}\";\r\n while(t.content.firstChild)f.appendChild(t.content.firstChild);\r\n if(n&&n.nodeType===8&&n.data===\"/$\"){\r\n var s=n.nextSibling;\r\n while(s&&s!==b){var x=s.nextSibling;s.parentNode.removeChild(s);s=x;}\r\n }\r\n b.parentNode.replaceChild(f,b);\r\n }\r\n})();\r\n</script>`;\r\n}\r\n\r\n/**\r\n * Build script to show error in place of Suspense content\r\n */\r\nfunction buildErrorReplacement(id: string, message: string): string {\r\n const escaped = message.replace(/'/g, \"\\\\'\").replace(/\"/g, '\\\\\"');\r\n\r\n return `\r\n<script>\r\n(function(){\r\n var b=document.getElementById(\"B:${id}\");\r\n if(b){\r\n var t=document.createElement(\"div\");\r\n t.className=\"streaming-error\";\r\n t.textContent=\"Error: ${escaped}\";\r\n b.parentNode.replaceChild(t,b);\r\n }\r\n})();\r\n</script>`;\r\n}\r\n\r\n/**\r\n * Build hydration bootstrap script\r\n */\r\nfunction buildHydrationScript(options: StreamingRenderOptions): string {\r\n let scripts = '';\r\n\r\n if (options.bootstrapScripts?.length) {\r\n for (const src of options.bootstrapScripts) {\r\n const nonceAttr = options.nonce ? ` nonce=\"${options.nonce}\"` : '';\r\n scripts += `<script src=\"${src}\"${nonceAttr} async></script>`;\r\n }\r\n }\r\n\r\n if (options.bootstrapModules?.length) {\r\n for (const src of options.bootstrapModules) {\r\n const nonceAttr = options.nonce ? ` nonce=\"${options.nonce}\"` : '';\r\n scripts += `<script type=\"module\" src=\"${src}\"${nonceAttr}></script>`;\r\n }\r\n }\r\n\r\n return scripts;\r\n}\r\n\r\n// ============================================================================\r\n// Streaming Response Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Create a streaming HTML Response object\r\n */\r\nexport function createStreamingResponse(\r\n stream: ReadableStream<Uint8Array>,\r\n options: {\r\n status?: number;\r\n headers?: Record<string, string>;\r\n } = {}\r\n): Response {\r\n return new Response(stream, {\r\n status: options.status || 200,\r\n headers: {\r\n 'Content-Type': 'text/html; charset=utf-8',\r\n 'Transfer-Encoding': 'chunked',\r\n 'X-Content-Type-Options': 'nosniff',\r\n ...options.headers,\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * Higher-level API: Render page with Suspense boundaries\r\n * \r\n * @example\r\n * ```typescript\r\n * return renderWithStreaming({\r\n * layout: ({ children }) => `\r\n * <html>\r\n * <head><title>My App</title></head>\r\n * <body><div id=\"root\">${children}</div></body>\r\n * </html>\r\n * `,\r\n * page: async () => '<h1>Welcome</h1>',\r\n * suspense: {\r\n * posts: {\r\n * fallback: '<div class=\"skeleton\">Loading...</div>',\r\n * content: fetchPosts().then(renderPosts),\r\n * },\r\n * },\r\n * });\r\n * ```\r\n */\r\nexport async function renderWithStreaming(config: {\r\n /** Layout wrapper */\r\n layout: (props: { children: string }) => string;\r\n /** Main page content (sync part) */\r\n page: () => string | Promise<string>;\r\n /** Suspense boundaries keyed by ID */\r\n suspense?: Record<string, { fallback: string; content: Promise<string> }>;\r\n /** Bootstrap scripts */\r\n bootstrapScripts?: string[];\r\n /** Timeout in ms */\r\n timeoutMs?: number;\r\n}): Promise<Response> {\r\n const { layout, page, suspense = {}, bootstrapScripts, timeoutMs } = config;\r\n\r\n // Get synchronous page content\r\n const pageContent = await page();\r\n\r\n // Build suspense boundaries\r\n const boundaries: SuspenseBoundaryConfig[] = Object.entries(suspense).map(\r\n ([id, { fallback, content }]) => ({\r\n id,\r\n fallback,\r\n contentPromise: content,\r\n })\r\n );\r\n\r\n // Create streaming result\r\n const result = await createStreamingSSR({\r\n shell: layout({ children: pageContent }),\r\n shellEnd: '',\r\n suspenseBoundaries: boundaries,\r\n options: {\r\n bootstrapScripts,\r\n timeoutMs,\r\n },\r\n });\r\n\r\n return createStreamingResponse(result.stream);\r\n}\r\n\r\n// ============================================================================\r\n// Progressive Rendering Utilities\r\n// ============================================================================\r\n\r\n/**\r\n * Create a lazy component that streams its content\r\n */\r\nexport function createLazyContent<T>(\r\n fetcher: () => Promise<T>,\r\n renderer: (data: T) => string,\r\n fallback: string\r\n): { fallback: string; content: Promise<string> } {\r\n return {\r\n fallback,\r\n content: fetcher().then(renderer),\r\n };\r\n}\r\n\r\n/**\r\n * Parallel streaming: resolve multiple boundaries simultaneously\r\n */\r\nexport async function streamParallel(\r\n boundaries: Array<{\r\n id: string;\r\n fallback: string;\r\n content: () => Promise<string>;\r\n }>\r\n): Promise<SuspenseBoundaryConfig[]> {\r\n return boundaries.map((b) => ({\r\n id: b.id,\r\n fallback: b.fallback,\r\n contentPromise: b.content(),\r\n }));\r\n}\r\n\r\n/**\r\n * Sequential streaming: resolve boundaries in order\r\n */\r\nexport async function streamSequential(\r\n boundaries: Array<{\r\n id: string;\r\n fallback: string;\r\n content: () => Promise<string>;\r\n }>\r\n): Promise<SuspenseBoundaryConfig[]> {\r\n const result: SuspenseBoundaryConfig[] = [];\r\n\r\n for (const b of boundaries) {\r\n result.push({\r\n id: b.id,\r\n fallback: b.fallback,\r\n contentPromise: b.content(),\r\n });\r\n }\r\n\r\n return result;\r\n}\r\n\r\n// ============================================================================\r\n// Export for use with React\r\n// ============================================================================\r\n\r\n/**\r\n * NOTE: For React-specific streaming with renderToPipeableStream or \r\n * renderToReadableStream, use the dedicated React adapter:\r\n * \r\n * ```typescript\r\n * import { renderToReadableStream } from 'react-dom/server';\r\n * import { createStreamingResponse } from '@flight-framework/core/streaming';\r\n * \r\n * const stream = await renderToReadableStream(<App />, {\r\n * bootstrapScripts: ['/client.js'],\r\n * });\r\n * \r\n * return createStreamingResponse(stream);\r\n * ```\r\n * \r\n * This module provides framework-agnostic streaming primitives that work\r\n * with any UI library or custom HTML generation.\r\n */\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/file-router/streaming-hints.ts"],"names":[],"mappings":"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","file":"chunk-I2B4WSHC.js","sourcesContent":["/**\r\n * @flight-framework/core - File Router Streaming Hints\r\n * \r\n * Per-route streaming configuration through exports.\r\n * The user defines streaming behavior at the route level.\r\n * \r\n * @example\r\n * ```typescript\r\n * // src/routes/products/[id].page.tsx\r\n * \r\n * // Static export for streaming hints\r\n * export const streaming = {\r\n * enabled: true,\r\n * timeout: 5000,\r\n * priority: 'high',\r\n * };\r\n * \r\n * // Or dynamic function based on params\r\n * export function getStreamingConfig(params: { id: string }) {\r\n * return {\r\n * enabled: params.id !== 'preview',\r\n * timeout: 3000,\r\n * };\r\n * }\r\n * \r\n * export default function ProductPage({ params }) {\r\n * return <Product id={params.id} />;\r\n * }\r\n * ```\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Static streaming configuration export\r\n */\r\nexport interface StreamingHints {\r\n /** Whether streaming is enabled for this route (default: true) */\r\n enabled?: boolean;\r\n /** Timeout before aborting streaming (ms) */\r\n timeout?: number;\r\n /** Priority hint for streaming scheduler */\r\n priority?: 'high' | 'normal' | 'low';\r\n /** Expected suspense boundary IDs */\r\n boundaries?: string[];\r\n /** Force static rendering (no streaming) */\r\n forceStatic?: boolean;\r\n /** Cache the static version */\r\n cache?: {\r\n /** Time to cache in seconds */\r\n ttl?: number;\r\n /** Stale-while-revalidate time in seconds */\r\n swr?: number;\r\n /** Cache tags for invalidation */\r\n tags?: string[];\r\n };\r\n}\r\n\r\n/**\r\n * Dynamic streaming configuration function\r\n */\r\nexport type GetStreamingConfig<TParams = Record<string, string>> = (\r\n params: TParams,\r\n request?: Request\r\n) => StreamingHints | Promise<StreamingHints>;\r\n\r\n/**\r\n * Route module with streaming exports\r\n */\r\nexport interface StreamingRouteModule {\r\n /** Default component/handler */\r\n default: unknown;\r\n /** Static streaming configuration */\r\n streaming?: StreamingHints;\r\n /** Dynamic streaming configuration function */\r\n getStreamingConfig?: GetStreamingConfig;\r\n /** Other route exports (metadata, generateStaticParams, etc.) */\r\n [key: string]: unknown;\r\n}\r\n\r\n/**\r\n * Resolved streaming configuration for a request\r\n */\r\nexport interface ResolvedStreamingConfig extends StreamingHints {\r\n /** Source of the configuration */\r\n source: 'static' | 'dynamic' | 'default';\r\n /** Route path */\r\n routePath: string;\r\n}\r\n\r\n// ============================================================================\r\n// Default Configuration\r\n// ============================================================================\r\n\r\n/**\r\n * Default streaming hints when none are specified\r\n */\r\nexport const DEFAULT_STREAMING_HINTS: Required<StreamingHints> = {\r\n enabled: true,\r\n timeout: 10000, // 10 seconds\r\n priority: 'normal',\r\n boundaries: [],\r\n forceStatic: false,\r\n cache: {\r\n ttl: undefined as unknown as number,\r\n swr: undefined as unknown as number,\r\n tags: [],\r\n },\r\n};\r\n\r\n// ============================================================================\r\n// Configuration Resolution\r\n// ============================================================================\r\n\r\n/**\r\n * Resolve streaming configuration for a route request\r\n */\r\nexport async function resolveStreamingConfig(\r\n module: StreamingRouteModule,\r\n params: Record<string, string>,\r\n request?: Request,\r\n routePath: string = '/'\r\n): Promise<ResolvedStreamingConfig> {\r\n // Check for dynamic config first (takes precedence)\r\n if (typeof module.getStreamingConfig === 'function') {\r\n try {\r\n const dynamicConfig = await module.getStreamingConfig(params, request);\r\n return {\r\n ...DEFAULT_STREAMING_HINTS,\r\n ...dynamicConfig,\r\n source: 'dynamic',\r\n routePath,\r\n };\r\n } catch (error) {\r\n console.warn(`[Flight] Error in getStreamingConfig for ${routePath}:`, error);\r\n // Fall through to static config\r\n }\r\n }\r\n\r\n // Check for static config\r\n if (module.streaming) {\r\n return {\r\n ...DEFAULT_STREAMING_HINTS,\r\n ...module.streaming,\r\n source: 'static',\r\n routePath,\r\n };\r\n }\r\n\r\n // Return defaults\r\n return {\r\n ...DEFAULT_STREAMING_HINTS,\r\n source: 'default',\r\n routePath,\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Route Loader Enhancement\r\n// ============================================================================\r\n\r\n/**\r\n * Load route module and extract streaming configuration\r\n */\r\nexport async function loadRouteWithStreaming(\r\n filePath: string,\r\n moduleLoader?: (path: string) => Promise<StreamingRouteModule>\r\n): Promise<{\r\n module: StreamingRouteModule;\r\n hasStreamingConfig: boolean;\r\n hasGetStreamingConfig: boolean;\r\n}> {\r\n // Use custom loader or native import\r\n let module: StreamingRouteModule;\r\n if (moduleLoader) {\r\n module = await moduleLoader(filePath);\r\n } else {\r\n const { pathToFileURL } = await import('node:url');\r\n const fileUrl = pathToFileURL(filePath).href;\r\n module = await import(fileUrl);\r\n }\r\n\r\n return {\r\n module,\r\n hasStreamingConfig: 'streaming' in module,\r\n hasGetStreamingConfig: typeof module.getStreamingConfig === 'function',\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Streaming Decision Helper\r\n// ============================================================================\r\n\r\n/**\r\n * Determine if streaming should be used based on config and request\r\n */\r\nexport function shouldStream(\r\n config: ResolvedStreamingConfig,\r\n request?: Request\r\n): { stream: boolean; reason: string } {\r\n // Force static always wins\r\n if (config.forceStatic) {\r\n return { stream: false, reason: 'forceStatic enabled' };\r\n }\r\n\r\n // Check enabled flag\r\n if (config.enabled === false) {\r\n return { stream: false, reason: 'streaming disabled in config' };\r\n }\r\n\r\n // Check for bot user agents (optional, user can also use conditional.ts)\r\n if (request) {\r\n const userAgent = request.headers.get('user-agent') || '';\r\n\r\n // Check for explicit no-stream header\r\n if (request.headers.get('x-no-stream') === 'true') {\r\n return { stream: false, reason: 'x-no-stream header' };\r\n }\r\n\r\n // Check for low priority and slow connection\r\n if (config.priority === 'low') {\r\n const ect = request.headers.get('ect');\r\n if (ect && ['slow-2g', '2g'].includes(ect)) {\r\n return { stream: false, reason: 'low priority + slow connection' };\r\n }\r\n }\r\n }\r\n\r\n return { stream: true, reason: 'streaming enabled' };\r\n}\r\n\r\n// ============================================================================\r\n// Timeout Controller\r\n// ============================================================================\r\n\r\n/**\r\n * Create an abort controller with timeout\r\n */\r\nexport function createStreamingController(\r\n timeout: number\r\n): {\r\n controller: AbortController;\r\n signal: AbortSignal;\r\n cleanup: () => void;\r\n} {\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => {\r\n controller.abort(new Error(`Streaming timeout after ${timeout}ms`));\r\n }, timeout);\r\n\r\n return {\r\n controller,\r\n signal: controller.signal,\r\n cleanup: () => clearTimeout(timeoutId),\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Caching Integration\r\n// ============================================================================\r\n\r\n/**\r\n * Generate cache key for a streaming route\r\n */\r\nexport function generateCacheKey(\r\n routePath: string,\r\n params: Record<string, string>,\r\n config: StreamingHints\r\n): string {\r\n const paramString = Object.entries(params)\r\n .sort(([a], [b]) => a.localeCompare(b))\r\n .map(([k, v]) => `${k}=${v}`)\r\n .join('&');\r\n\r\n return `streaming:${routePath}:${paramString}`;\r\n}\r\n\r\n/**\r\n * Cache headers for static streaming fallback\r\n */\r\nexport function getStreamingCacheHeaders(config: StreamingHints): Record<string, string> {\r\n if (!config.cache) return {};\r\n\r\n const headers: Record<string, string> = {};\r\n\r\n if (config.cache.ttl) {\r\n if (config.cache.swr) {\r\n headers['Cache-Control'] = `s-maxage=${config.cache.ttl}, stale-while-revalidate=${config.cache.swr}`;\r\n } else {\r\n headers['Cache-Control'] = `s-maxage=${config.cache.ttl}`;\r\n }\r\n }\r\n\r\n if (config.cache.tags && config.cache.tags.length > 0) {\r\n headers['X-Cache-Tags'] = config.cache.tags.join(',');\r\n }\r\n\r\n return headers;\r\n}\r\n\r\n// ============================================================================\r\n// Type Guards\r\n// ============================================================================\r\n\r\n/**\r\n * Check if a module has streaming configuration\r\n */\r\nexport function hasStreamingConfig(module: unknown): module is StreamingRouteModule {\r\n if (!module || typeof module !== 'object') return false;\r\n return 'streaming' in module || 'getStreamingConfig' in module;\r\n}\r\n\r\n/**\r\n * Validate streaming hints object\r\n */\r\nexport function isValidStreamingHints(obj: unknown): obj is StreamingHints {\r\n if (!obj || typeof obj !== 'object') return false;\r\n const hints = obj as StreamingHints;\r\n\r\n if (hints.enabled !== undefined && typeof hints.enabled !== 'boolean') return false;\r\n if (hints.timeout !== undefined && typeof hints.timeout !== 'number') return false;\r\n if (hints.priority !== undefined && !['high', 'normal', 'low'].includes(hints.priority)) return false;\r\n if (hints.boundaries !== undefined && !Array.isArray(hints.boundaries)) return false;\r\n if (hints.forceStatic !== undefined && typeof hints.forceStatic !== 'boolean') return false;\r\n\r\n return true;\r\n}\r\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/streaming/priority.ts"],"names":["resolution"],"mappings":"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","file":"chunk-OBNYNJB5.js","sourcesContent":["/**\r\n * @flight-framework/core - Priority-Based Streaming SSR\r\n * \r\n * Out-of-order streaming with priority control, deadlines, and dependencies.\r\n * Gives developers full control over streaming order and timing.\r\n * \r\n * Best Practices 2026:\r\n * - Priority-based content delivery for optimal UX\r\n * - Deadline-aware streaming to prevent slow boundaries from blocking\r\n * - Dependency graphs for complex data relationships\r\n * - Strategy-based streaming modes for different use cases\r\n * \r\n * @example\r\n * ```typescript\r\n * import { streamWithPriority } from '@flight-framework/core/streaming';\r\n * \r\n * const result = await streamWithPriority({\r\n * shell: '<html>...',\r\n * shellEnd: '</html>',\r\n * boundaries: [\r\n * { id: 'hero', priority: 1, content: fetchHero() },\r\n * { id: 'nav', priority: 2, content: fetchNav() },\r\n * { id: 'comments', priority: 10, content: fetchComments() },\r\n * ],\r\n * strategy: 'priority-first',\r\n * });\r\n * ```\r\n */\r\n\r\nimport type { StreamingRenderOptions, StreamingRenderResult, SuspenseBoundaryConfig } from './index.js';\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Boundary with priority and advanced options\r\n */\r\nexport interface PriorityBoundary {\r\n /** Unique identifier for this boundary */\r\n id: string;\r\n /** Fallback HTML while loading */\r\n fallback: string;\r\n /** Content promise or factory function */\r\n content: Promise<string> | (() => Promise<string>);\r\n /** Priority level (lower number = higher priority, rendered first) */\r\n priority: number;\r\n /** Maximum time to wait before skipping (ms). Boundary shows fallback if exceeded. */\r\n deadline?: number;\r\n /** IDs of boundaries that must resolve before this one starts */\r\n dependsOn?: string[];\r\n /** Optional metadata for observability */\r\n meta?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Streaming strategy - how to order content delivery\r\n */\r\nexport type StreamingStrategy =\r\n | 'priority-first' // Strictly respect priority order\r\n | 'first-ready' // Send as soon as ready (fastest TTFB)\r\n | 'dependency-aware' // Respect dependencies, then priority\r\n | 'round-robin' // Alternate between priority levels\r\n | 'deadline-strict'; // Skip any boundary that misses deadline\r\n\r\n/**\r\n * Result of a priority boundary resolution\r\n */\r\nexport interface BoundaryResolution {\r\n id: string;\r\n content: string | null;\r\n duration: number;\r\n status: 'resolved' | 'timeout' | 'error' | 'skipped';\r\n error?: Error;\r\n}\r\n\r\n/**\r\n * Priority streaming configuration\r\n */\r\nexport interface PriorityStreamConfig {\r\n /** Initial HTML shell */\r\n shell: string;\r\n /** Closing HTML */\r\n shellEnd: string;\r\n /** Boundaries with priorities */\r\n boundaries: PriorityBoundary[];\r\n /** Streaming strategy */\r\n strategy: StreamingStrategy;\r\n /** Base streaming options */\r\n options?: StreamingRenderOptions;\r\n /** Callback when a boundary resolves */\r\n onBoundaryResolved?: (resolution: BoundaryResolution) => void;\r\n /** Global timeout for all boundaries */\r\n globalTimeout?: number;\r\n}\r\n\r\n/**\r\n * Priority streaming result with additional metrics\r\n */\r\nexport interface PriorityStreamResult extends StreamingRenderResult {\r\n /** Resolution details for each boundary */\r\n resolutions: Promise<BoundaryResolution[]>;\r\n}\r\n\r\n// ============================================================================\r\n// Priority Queue Implementation\r\n// ============================================================================\r\n\r\ninterface QueuedBoundary {\r\n boundary: PriorityBoundary;\r\n promise: Promise<string>;\r\n startTime: number;\r\n resolved: boolean;\r\n result?: string;\r\n error?: Error;\r\n}\r\n\r\n/**\r\n * Create a priority-ordered streaming SSR response\r\n */\r\nexport async function streamWithPriority(\r\n config: PriorityStreamConfig\r\n): Promise<PriorityStreamResult> {\r\n const {\r\n shell,\r\n shellEnd,\r\n boundaries,\r\n strategy,\r\n options = {},\r\n onBoundaryResolved,\r\n globalTimeout,\r\n } = config;\r\n\r\n let shellResolved = false;\r\n let allResolved = false;\r\n let aborted = false;\r\n const resolutionsPromise: BoundaryResolution[] = [];\r\n\r\n // Promises for lifecycle events\r\n let resolveShell: () => void;\r\n let resolveAll: () => void;\r\n const shellReady = new Promise<void>((r) => { resolveShell = r; });\r\n const allReady = new Promise<void>((r) => { resolveAll = r; });\r\n\r\n const encoder = new TextEncoder();\r\n\r\n // Sort boundaries by priority and prepare queue\r\n const sortedBoundaries = [...boundaries].sort((a, b) => a.priority - b.priority);\r\n\r\n // Build dependency graph\r\n const dependencyMap = new Map<string, Set<string>>();\r\n const resolvedIds = new Set<string>();\r\n\r\n for (const b of boundaries) {\r\n if (b.dependsOn && b.dependsOn.length > 0) {\r\n dependencyMap.set(b.id, new Set(b.dependsOn));\r\n }\r\n }\r\n\r\n // Check if a boundary's dependencies are satisfied\r\n const canProcess = (id: string): boolean => {\r\n const deps = dependencyMap.get(id);\r\n if (!deps) return true;\r\n for (const dep of deps) {\r\n if (!resolvedIds.has(dep)) return false;\r\n }\r\n return true;\r\n };\r\n\r\n // Create the readable stream\r\n const stream = new ReadableStream<Uint8Array>({\r\n async start(controller) {\r\n try {\r\n // 1. Send shell with fallback placeholders\r\n const shellHtml = buildShellWithPriorityPlaceholders(shell, sortedBoundaries, shellEnd, options);\r\n controller.enqueue(encoder.encode(shellHtml));\r\n\r\n shellResolved = true;\r\n options.onShellReady?.();\r\n resolveShell!();\r\n\r\n // 2. Process boundaries based on strategy\r\n if (boundaries.length > 0) {\r\n await processBoundariesByStrategy(\r\n controller,\r\n encoder,\r\n sortedBoundaries,\r\n strategy,\r\n dependencyMap,\r\n resolvedIds,\r\n canProcess,\r\n resolutionsPromise,\r\n onBoundaryResolved,\r\n globalTimeout,\r\n options\r\n );\r\n }\r\n\r\n // 3. Send hydration scripts\r\n if (options.bootstrapScripts?.length || options.bootstrapModules?.length) {\r\n const hydrationScript = buildHydrationScripts(options);\r\n controller.enqueue(encoder.encode(hydrationScript));\r\n }\r\n\r\n allResolved = true;\r\n options.onAllReady?.();\r\n resolveAll!();\r\n controller.close();\r\n\r\n } catch (error) {\r\n if (!shellResolved) {\r\n options.onShellError?.(error as Error);\r\n }\r\n options.onError?.(error as Error);\r\n controller.error(error);\r\n }\r\n },\r\n\r\n cancel() {\r\n aborted = true;\r\n },\r\n });\r\n\r\n return {\r\n stream,\r\n abort: () => { aborted = true; },\r\n shellReady,\r\n allReady,\r\n resolutions: Promise.resolve(resolutionsPromise),\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Strategy Processors\r\n// ============================================================================\r\n\r\nasync function processBoundariesByStrategy(\r\n controller: ReadableStreamDefaultController<Uint8Array>,\r\n encoder: TextEncoder,\r\n boundaries: PriorityBoundary[],\r\n strategy: StreamingStrategy,\r\n dependencyMap: Map<string, Set<string>>,\r\n resolvedIds: Set<string>,\r\n canProcess: (id: string) => boolean,\r\n resolutions: BoundaryResolution[],\r\n onResolved?: (r: BoundaryResolution) => void,\r\n globalTimeout?: number,\r\n options?: StreamingRenderOptions\r\n): Promise<void> {\r\n switch (strategy) {\r\n case 'priority-first':\r\n await processPriorityFirst(controller, encoder, boundaries, resolvedIds, resolutions, onResolved, globalTimeout, options);\r\n break;\r\n case 'first-ready':\r\n await processFirstReady(controller, encoder, boundaries, resolvedIds, resolutions, onResolved, globalTimeout, options);\r\n break;\r\n case 'dependency-aware':\r\n await processDependencyAware(controller, encoder, boundaries, dependencyMap, resolvedIds, canProcess, resolutions, onResolved, globalTimeout, options);\r\n break;\r\n case 'deadline-strict':\r\n await processDeadlineStrict(controller, encoder, boundaries, resolvedIds, resolutions, onResolved, options);\r\n break;\r\n case 'round-robin':\r\n await processRoundRobin(controller, encoder, boundaries, resolvedIds, resolutions, onResolved, globalTimeout, options);\r\n break;\r\n }\r\n}\r\n\r\n/**\r\n * Priority-first: Process boundaries strictly by priority order\r\n */\r\nasync function processPriorityFirst(\r\n controller: ReadableStreamDefaultController<Uint8Array>,\r\n encoder: TextEncoder,\r\n boundaries: PriorityBoundary[],\r\n resolvedIds: Set<string>,\r\n resolutions: BoundaryResolution[],\r\n onResolved?: (r: BoundaryResolution) => void,\r\n globalTimeout?: number,\r\n options?: StreamingRenderOptions\r\n): Promise<void> {\r\n for (const boundary of boundaries) {\r\n const resolution = await resolveBoundary(boundary, globalTimeout);\r\n resolutions.push(resolution);\r\n resolvedIds.add(boundary.id);\r\n onResolved?.(resolution);\r\n\r\n if (resolution.status === 'resolved' && resolution.content) {\r\n const script = buildContentReplacement(boundary.id, resolution.content);\r\n controller.enqueue(encoder.encode(script));\r\n } else if (resolution.status === 'error' || resolution.status === 'timeout') {\r\n const errorScript = buildErrorReplacement(boundary.id, resolution.error?.message || 'Timeout');\r\n controller.enqueue(encoder.encode(errorScript));\r\n options?.onError?.(resolution.error || new Error('Boundary timeout'));\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * First-ready: Process boundaries as they resolve (race all)\r\n */\r\nasync function processFirstReady(\r\n controller: ReadableStreamDefaultController<Uint8Array>,\r\n encoder: TextEncoder,\r\n boundaries: PriorityBoundary[],\r\n resolvedIds: Set<string>,\r\n resolutions: BoundaryResolution[],\r\n onResolved?: (r: BoundaryResolution) => void,\r\n globalTimeout?: number,\r\n options?: StreamingRenderOptions\r\n): Promise<void> {\r\n const pending = boundaries.map(b => resolveBoundary(b, globalTimeout));\r\n const results = await Promise.allSettled(pending);\r\n\r\n for (let i = 0; i < results.length; i++) {\r\n const result = results[i];\r\n const boundary = boundaries[i];\r\n\r\n if (result.status === 'fulfilled') {\r\n const resolution = result.value;\r\n resolutions.push(resolution);\r\n resolvedIds.add(boundary.id);\r\n onResolved?.(resolution);\r\n\r\n if (resolution.status === 'resolved' && resolution.content) {\r\n const script = buildContentReplacement(boundary.id, resolution.content);\r\n controller.enqueue(encoder.encode(script));\r\n } else {\r\n const errorScript = buildErrorReplacement(boundary.id, resolution.error?.message || 'Failed');\r\n controller.enqueue(encoder.encode(errorScript));\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Dependency-aware: Respect dependencies before processing\r\n */\r\nasync function processDependencyAware(\r\n controller: ReadableStreamDefaultController<Uint8Array>,\r\n encoder: TextEncoder,\r\n boundaries: PriorityBoundary[],\r\n dependencyMap: Map<string, Set<string>>,\r\n resolvedIds: Set<string>,\r\n canProcess: (id: string) => boolean,\r\n resolutions: BoundaryResolution[],\r\n onResolved?: (r: BoundaryResolution) => void,\r\n globalTimeout?: number,\r\n options?: StreamingRenderOptions\r\n): Promise<void> {\r\n const remaining = [...boundaries];\r\n\r\n while (remaining.length > 0) {\r\n // Find next boundary that can be processed\r\n const readyIndex = remaining.findIndex(b => canProcess(b.id));\r\n\r\n if (readyIndex === -1) {\r\n // Circular dependency detected - process remaining by priority\r\n console.warn('[Flight] Circular dependency detected, falling back to priority order');\r\n for (const b of remaining) {\r\n const resolution = await resolveBoundary(b, globalTimeout);\r\n resolutions.push(resolution);\r\n resolvedIds.add(b.id);\r\n onResolved?.(resolution);\r\n\r\n if (resolution.content) {\r\n controller.enqueue(encoder.encode(buildContentReplacement(b.id, resolution.content)));\r\n }\r\n }\r\n break;\r\n }\r\n\r\n const boundary = remaining.splice(readyIndex, 1)[0];\r\n const resolution = await resolveBoundary(boundary, globalTimeout);\r\n resolutions.push(resolution);\r\n resolvedIds.add(boundary.id);\r\n onResolved?.(resolution);\r\n\r\n if (resolution.status === 'resolved' && resolution.content) {\r\n controller.enqueue(encoder.encode(buildContentReplacement(boundary.id, resolution.content)));\r\n } else {\r\n controller.enqueue(encoder.encode(buildErrorReplacement(boundary.id, resolution.error?.message || 'Failed')));\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Deadline-strict: Skip boundaries that exceed their deadline\r\n */\r\nasync function processDeadlineStrict(\r\n controller: ReadableStreamDefaultController<Uint8Array>,\r\n encoder: TextEncoder,\r\n boundaries: PriorityBoundary[],\r\n resolvedIds: Set<string>,\r\n resolutions: BoundaryResolution[],\r\n onResolved?: (r: BoundaryResolution) => void,\r\n options?: StreamingRenderOptions\r\n): Promise<void> {\r\n const promises = boundaries.map(async (boundary) => {\r\n const deadline = boundary.deadline || 5000; // Default 5s\r\n const resolution = await resolveBoundary(boundary, deadline);\r\n return { boundary, resolution };\r\n });\r\n\r\n const results = await Promise.allSettled(promises);\r\n\r\n for (const result of results) {\r\n if (result.status === 'fulfilled') {\r\n const { boundary, resolution } = result.value;\r\n resolutions.push(resolution);\r\n resolvedIds.add(boundary.id);\r\n onResolved?.(resolution);\r\n\r\n if (resolution.status === 'timeout') {\r\n // Skip - leave fallback in place\r\n console.log(`[Flight] Boundary ${boundary.id} skipped due to deadline`);\r\n } else if (resolution.status === 'resolved' && resolution.content) {\r\n controller.enqueue(encoder.encode(buildContentReplacement(boundary.id, resolution.content)));\r\n } else {\r\n controller.enqueue(encoder.encode(buildErrorReplacement(boundary.id, resolution.error?.message || 'Error')));\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Round-robin: Alternate between priority groups\r\n */\r\nasync function processRoundRobin(\r\n controller: ReadableStreamDefaultController<Uint8Array>,\r\n encoder: TextEncoder,\r\n boundaries: PriorityBoundary[],\r\n resolvedIds: Set<string>,\r\n resolutions: BoundaryResolution[],\r\n onResolved?: (r: BoundaryResolution) => void,\r\n globalTimeout?: number,\r\n options?: StreamingRenderOptions\r\n): Promise<void> {\r\n // Group by priority\r\n const groups = new Map<number, PriorityBoundary[]>();\r\n for (const b of boundaries) {\r\n const group = groups.get(b.priority) || [];\r\n group.push(b);\r\n groups.set(b.priority, group);\r\n }\r\n\r\n const sortedPriorities = [...groups.keys()].sort((a, b) => a - b);\r\n const queues = sortedPriorities.map(p => [...groups.get(p)!]);\r\n\r\n // Process round-robin\r\n while (queues.some(q => q.length > 0)) {\r\n for (const queue of queues) {\r\n if (queue.length === 0) continue;\r\n\r\n const boundary = queue.shift()!;\r\n const resolution = await resolveBoundary(boundary, globalTimeout);\r\n resolutions.push(resolution);\r\n resolvedIds.add(boundary.id);\r\n onResolved?.(resolution);\r\n\r\n if (resolution.status === 'resolved' && resolution.content) {\r\n controller.enqueue(encoder.encode(buildContentReplacement(boundary.id, resolution.content)));\r\n }\r\n }\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Boundary Resolution\r\n// ============================================================================\r\n\r\nasync function resolveBoundary(\r\n boundary: PriorityBoundary,\r\n timeout?: number\r\n): Promise<BoundaryResolution> {\r\n const startTime = Date.now();\r\n const contentPromise = typeof boundary.content === 'function'\r\n ? boundary.content()\r\n : boundary.content;\r\n\r\n try {\r\n let content: string;\r\n\r\n if (timeout) {\r\n const timeoutPromise = new Promise<never>((_, reject) => {\r\n setTimeout(() => reject(new Error('Deadline exceeded')), timeout);\r\n });\r\n content = await Promise.race([contentPromise, timeoutPromise]);\r\n } else {\r\n content = await contentPromise;\r\n }\r\n\r\n return {\r\n id: boundary.id,\r\n content,\r\n duration: Date.now() - startTime,\r\n status: 'resolved',\r\n };\r\n } catch (error) {\r\n const isTimeout = (error as Error).message === 'Deadline exceeded';\r\n return {\r\n id: boundary.id,\r\n content: null,\r\n duration: Date.now() - startTime,\r\n status: isTimeout ? 'timeout' : 'error',\r\n error: error as Error,\r\n };\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// HTML Builders\r\n// ============================================================================\r\n\r\nfunction buildShellWithPriorityPlaceholders(\r\n shell: string,\r\n boundaries: PriorityBoundary[],\r\n shellEnd: string,\r\n options: StreamingRenderOptions\r\n): string {\r\n let html = shell;\r\n\r\n if (options.bootstrapScriptContent) {\r\n html += `<script>${options.bootstrapScriptContent}</script>`;\r\n }\r\n\r\n // Add placeholders with priority data attributes\r\n for (const boundary of boundaries) {\r\n html += `\r\n<!--$?--><template id=\"B:${boundary.id}\" data-priority=\"${boundary.priority}\"></template>\r\n${boundary.fallback}\r\n<!--/$-->`;\r\n }\r\n\r\n html += shellEnd;\r\n return html;\r\n}\r\n\r\nfunction buildContentReplacement(id: string, content: string): string {\r\n const escaped = content\r\n .replace(/\\\\/g, '\\\\\\\\')\r\n .replace(/</g, '\\\\u003c')\r\n .replace(/>/g, '\\\\u003e')\r\n .replace(/'/g, \"\\\\'\")\r\n .replace(/\"/g, '\\\\\"')\r\n .replace(/\\n/g, '\\\\n')\r\n .replace(/\\r/g, '\\\\r');\r\n\r\n return `\r\n<script>\r\n(function(){\r\n var b=document.getElementById(\"B:${id}\");\r\n if(b){\r\n var p=b.previousSibling;\r\n while(p&&p.nodeType===8&&p.data===\"$?\")p=p.previousSibling;\r\n var n=b.nextSibling;\r\n var f=document.createDocumentFragment();\r\n var t=document.createElement(\"template\");\r\n t.innerHTML=\"${escaped}\";\r\n while(t.content.firstChild)f.appendChild(t.content.firstChild);\r\n if(n&&n.nodeType===8&&n.data===\"/\\$\"){\r\n var s=n.nextSibling;\r\n while(s&&s!==b){var x=s.nextSibling;s.parentNode.removeChild(s);s=x;}\r\n }\r\n b.parentNode.replaceChild(f,b);\r\n }\r\n})();\r\n</script>`;\r\n}\r\n\r\nfunction buildErrorReplacement(id: string, message: string): string {\r\n const escaped = message.replace(/'/g, \"\\\\'\").replace(/\"/g, '\\\\\"');\r\n return `\r\n<script>\r\n(function(){\r\n var b=document.getElementById(\"B:${id}\");\r\n if(b){\r\n var t=document.createElement(\"div\");\r\n t.className=\"flight-streaming-error\";\r\n t.setAttribute(\"data-boundary-id\",\"${id}\");\r\n t.textContent=\"Error: ${escaped}\";\r\n b.parentNode.replaceChild(t,b);\r\n }\r\n})();\r\n</script>`;\r\n}\r\n\r\nfunction buildHydrationScripts(options: StreamingRenderOptions): string {\r\n let scripts = '';\r\n\r\n if (options.bootstrapScripts?.length) {\r\n for (const src of options.bootstrapScripts) {\r\n const nonceAttr = options.nonce ? ` nonce=\"${options.nonce}\"` : '';\r\n scripts += `<script src=\"${src}\"${nonceAttr} async></script>`;\r\n }\r\n }\r\n\r\n if (options.bootstrapModules?.length) {\r\n for (const src of options.bootstrapModules) {\r\n const nonceAttr = options.nonce ? ` nonce=\"${options.nonce}\"` : '';\r\n scripts += `<script type=\"module\" src=\"${src}\"${nonceAttr}></script>`;\r\n }\r\n }\r\n\r\n return scripts;\r\n}\r\n\r\n// ============================================================================\r\n// Utility: Validate Dependencies (check for cycles)\r\n// ============================================================================\r\n\r\n/**\r\n * Validate that boundaries don't have circular dependencies\r\n */\r\nexport function validateDependencies(boundaries: PriorityBoundary[]): { valid: boolean; cycles?: string[][] } {\r\n const graph = new Map<string, string[]>();\r\n const allIds = new Set(boundaries.map(b => b.id));\r\n\r\n for (const b of boundaries) {\r\n graph.set(b.id, b.dependsOn?.filter(d => allIds.has(d)) || []);\r\n }\r\n\r\n const cycles: string[][] = [];\r\n const visited = new Set<string>();\r\n const recursionStack = new Set<string>();\r\n\r\n function dfs(id: string, path: string[]): boolean {\r\n if (recursionStack.has(id)) {\r\n const cycleStart = path.indexOf(id);\r\n cycles.push(path.slice(cycleStart));\r\n return true;\r\n }\r\n if (visited.has(id)) return false;\r\n\r\n visited.add(id);\r\n recursionStack.add(id);\r\n\r\n for (const dep of graph.get(id) || []) {\r\n if (dfs(dep, [...path, id])) return true;\r\n }\r\n\r\n recursionStack.delete(id);\r\n return false;\r\n }\r\n\r\n for (const id of graph.keys()) {\r\n dfs(id, []);\r\n }\r\n\r\n return { valid: cycles.length === 0, cycles: cycles.length > 0 ? cycles : undefined };\r\n}\r\n"]}