@flight-framework/core 0.3.1 → 0.3.2
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.
- package/LICENSE +21 -0
- package/README.md +541 -541
- package/dist/actions/index.js +1 -1
- package/dist/adapters/index.js +1 -1
- package/dist/cache/index.js +1 -1
- package/dist/{chunk-FSJNOPYE.js → chunk-2JVEH76V.js} +3 -3
- package/dist/chunk-2JVEH76V.js.map +1 -0
- package/dist/{chunk-VPFMHGEV.js → chunk-3N5ZBVZJ.js} +2 -2
- package/dist/chunk-3N5ZBVZJ.js.map +1 -0
- package/dist/{chunk-2F2QU6RC.js → chunk-3UQJE3XZ.js} +2 -2
- package/dist/chunk-3UQJE3XZ.js.map +1 -0
- package/dist/{chunk-3KRBRSRJ.js → chunk-4U7CJVNQ.js} +2 -2
- package/dist/chunk-4U7CJVNQ.js.map +1 -0
- package/dist/{chunk-PDW5WCMW.js → chunk-5XHOLZBJ.js} +2 -2
- package/dist/chunk-5XHOLZBJ.js.map +1 -0
- package/dist/{chunk-MDQNNIHH.js → chunk-65JYF3DJ.js} +2 -2
- package/dist/chunk-65JYF3DJ.js.map +1 -0
- package/dist/{chunk-K2CQZPCG.js → chunk-6GI6HFSQ.js} +2 -2
- package/dist/chunk-6GI6HFSQ.js.map +1 -0
- package/dist/{chunk-3ZSSRE6M.js → chunk-6IG6XIXU.js} +29 -3
- package/dist/chunk-6IG6XIXU.js.map +1 -0
- package/dist/{chunk-PVUMB632.js → chunk-A2QRUBVE.js} +2 -2
- package/dist/chunk-A2QRUBVE.js.map +1 -0
- package/dist/{chunk-W6D62JCI.js → chunk-A4TKWQBU.js} +2 -2
- package/dist/chunk-A4TKWQBU.js.map +1 -0
- package/dist/{chunk-GCQZ4FHI.js → chunk-ARBKF6VI.js} +2 -2
- package/dist/{chunk-GCQZ4FHI.js.map → chunk-ARBKF6VI.js.map} +1 -1
- package/dist/{chunk-ZVC3ZWLM.js → chunk-B2LPSCES.js} +2 -2
- package/dist/chunk-B2LPSCES.js.map +1 -0
- package/dist/{chunk-62C7LX2E.js → chunk-CKJHJPKQ.js} +2 -2
- package/dist/chunk-CKJHJPKQ.js.map +1 -0
- package/dist/{chunk-RSVA2EYO.js → chunk-CNY3ZUVG.js} +2 -2
- package/dist/chunk-CNY3ZUVG.js.map +1 -0
- package/dist/{chunk-IXMD5QH2.js → chunk-EHVUAFNH.js} +2 -2
- package/dist/chunk-EHVUAFNH.js.map +1 -0
- package/dist/{chunk-P6WSBVDT.js → chunk-FRAH5QNY.js} +4 -4
- package/dist/chunk-FRAH5QNY.js.map +1 -0
- package/dist/{chunk-MQQLYWZZ.js → chunk-GNS2FGPC.js} +2 -2
- package/dist/chunk-GNS2FGPC.js.map +1 -0
- package/dist/{chunk-TASAT7KB.js → chunk-HNPO6LFW.js} +2 -2
- package/dist/chunk-HNPO6LFW.js.map +1 -0
- package/dist/{chunk-ROJFQCGV.js → chunk-KDEA64UX.js} +5 -5
- package/dist/chunk-KDEA64UX.js.map +1 -0
- package/dist/{chunk-NWMJYTMB.js → chunk-LAKHYTHL.js} +3 -3
- package/dist/chunk-LAKHYTHL.js.map +1 -0
- package/dist/{chunk-R7SQAREQ.js → chunk-LKOPJ3GS.js} +2 -2
- package/dist/chunk-LKOPJ3GS.js.map +1 -0
- package/dist/{chunk-WOEIJWGJ.js → chunk-NZS2YJ43.js} +2 -2
- package/dist/chunk-NZS2YJ43.js.map +1 -0
- package/dist/{chunk-3QP3E7HS.js → chunk-OZ3EXPLE.js} +2 -2
- package/dist/chunk-OZ3EXPLE.js.map +1 -0
- package/dist/{chunk-YHEVHRLH.js → chunk-OZBPR27I.js} +2 -2
- package/dist/chunk-OZBPR27I.js.map +1 -0
- package/dist/{chunk-T4Z4HM4W.js → chunk-PAVI5W6M.js} +3 -3
- package/dist/chunk-PAVI5W6M.js.map +1 -0
- package/dist/{chunk-XSY5AAXT.js → chunk-PO7IHPFF.js} +2 -2
- package/dist/chunk-PO7IHPFF.js.map +1 -0
- package/dist/{chunk-SUILH4ID.js → chunk-QK6UEQ75.js} +2 -2
- package/dist/chunk-QK6UEQ75.js.map +1 -0
- package/dist/{chunk-OYF2OAKS.js → chunk-R7MEVVA4.js} +2 -2
- package/dist/chunk-R7MEVVA4.js.map +1 -0
- package/dist/{chunk-WFAWAHJH.js → chunk-UFWGOJL7.js} +2 -2
- package/dist/chunk-UFWGOJL7.js.map +1 -0
- package/dist/{chunk-XOIYNY4I.js → chunk-VNO2YUVD.js} +2 -2
- package/dist/chunk-VNO2YUVD.js.map +1 -0
- package/dist/{chunk-ZIE56LCA.js → chunk-XU6MRYG2.js} +3 -3
- package/dist/chunk-XU6MRYG2.js.map +1 -0
- package/dist/{chunk-6BDCTUQY.js → chunk-YNTMYL36.js} +3 -3
- package/dist/chunk-YNTMYL36.js.map +1 -0
- package/dist/client.d.ts +25 -0
- package/dist/client.js +16 -0
- package/dist/client.js.map +1 -0
- package/dist/config/index.js +1 -1
- package/dist/errors/index.js +2 -2
- package/dist/file-router/index.js +1 -1
- package/dist/file-router/streaming-hints.js +1 -1
- package/dist/handlers/index.js +1 -1
- package/dist/index.js +30 -30
- package/dist/index.js.map +1 -1
- package/dist/islands/index.js +1 -1
- package/dist/middleware/index.js +1 -1
- package/dist/react/index.js +2 -2
- package/dist/react/index.js.map +1 -1
- package/dist/render/index.js +1 -1
- package/dist/router/index.js +1 -1
- package/dist/rsc/adapters/index.js +4 -4
- package/dist/rsc/adapters/preact.js +1 -1
- package/dist/rsc/adapters/react.js +1 -1
- package/dist/rsc/adapters/solid.js +1 -1
- package/dist/rsc/adapters/vue.js +1 -1
- package/dist/rsc/boundaries.js +1 -1
- package/dist/rsc/context.js +1 -1
- package/dist/rsc/index.d.ts +211 -6
- package/dist/rsc/index.js +11 -11
- package/dist/rsc/legacy.d.ts +26 -2
- package/dist/rsc/legacy.js +1 -1
- package/dist/rsc/payload.js +1 -1
- package/dist/rsc/plugins/esbuild.js +2 -2
- package/dist/rsc/plugins/index.js +4 -4
- package/dist/rsc/plugins/rollup.js +2 -2
- package/dist/rsc/renderer.js +3 -3
- package/dist/rsc/stream.js +1 -1
- package/dist/rsc/vite-plugin.js +2 -2
- package/dist/server/index.js +4 -4
- package/dist/streaming/adapters/index.js +1 -1
- package/dist/streaming/conditional.js +1 -1
- package/dist/streaming/index.js +1 -1
- package/dist/streaming/observability.js +2 -2
- package/dist/streaming/priority.js +1 -1
- package/dist/utils/index.js +1 -1
- package/package.json +228 -222
- package/dist/chunk-2F2QU6RC.js.map +0 -1
- package/dist/chunk-3KRBRSRJ.js.map +0 -1
- package/dist/chunk-3QP3E7HS.js.map +0 -1
- package/dist/chunk-3ZSSRE6M.js.map +0 -1
- package/dist/chunk-62C7LX2E.js.map +0 -1
- package/dist/chunk-6BDCTUQY.js.map +0 -1
- package/dist/chunk-FSJNOPYE.js.map +0 -1
- package/dist/chunk-IXMD5QH2.js.map +0 -1
- package/dist/chunk-K2CQZPCG.js.map +0 -1
- package/dist/chunk-MDQNNIHH.js.map +0 -1
- package/dist/chunk-MQQLYWZZ.js.map +0 -1
- package/dist/chunk-NWMJYTMB.js.map +0 -1
- package/dist/chunk-OYF2OAKS.js.map +0 -1
- package/dist/chunk-P6WSBVDT.js.map +0 -1
- package/dist/chunk-PDW5WCMW.js.map +0 -1
- package/dist/chunk-PVUMB632.js.map +0 -1
- package/dist/chunk-R7SQAREQ.js.map +0 -1
- package/dist/chunk-ROJFQCGV.js.map +0 -1
- package/dist/chunk-RSVA2EYO.js.map +0 -1
- package/dist/chunk-SUILH4ID.js.map +0 -1
- package/dist/chunk-T4Z4HM4W.js.map +0 -1
- package/dist/chunk-TASAT7KB.js.map +0 -1
- package/dist/chunk-VPFMHGEV.js.map +0 -1
- package/dist/chunk-W6D62JCI.js.map +0 -1
- package/dist/chunk-WFAWAHJH.js.map +0 -1
- package/dist/chunk-WOEIJWGJ.js.map +0 -1
- package/dist/chunk-XOIYNY4I.js.map +0 -1
- package/dist/chunk-XSY5AAXT.js.map +0 -1
- package/dist/chunk-YHEVHRLH.js.map +0 -1
- package/dist/chunk-ZIE56LCA.js.map +0 -1
- package/dist/chunk-ZVC3ZWLM.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/streaming/priority.ts"],"names":["resolution"],"mappings":"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","file":"chunk-WOEIJWGJ.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 } 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\n// Note: QueuedBoundary interface removed - not currently used\r\n// Can be added back when implementing more advanced queue features\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 // State tracking variables available for future use if needed\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 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 // Stream cancelled by consumer\r\n },\r\n });\r\n\r\n return {\r\n stream,\r\n abort: () => { /* abort requested */ },\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"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/streaming/conditional.ts"],"names":["result"],"mappings":"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","file":"chunk-XOIYNY4I.js","sourcesContent":["/**\r\n * @flight-framework/core - Conditional Streaming\r\n * \r\n * Smart streaming decisions based on request context.\r\n * Bots get full HTML, users get streaming - YOU control the logic.\r\n * \r\n * Best Practices 2026:\r\n * - SEO-friendly: Crawlers receive complete HTML\r\n * - Performance: Users get progressive streaming\r\n * - Flexibility: Custom conditions for any use case\r\n * \r\n * @example\r\n * ```typescript\r\n * import { streamIf } from '@flight-framework/core/streaming';\r\n * \r\n * const response = await streamIf({\r\n * request,\r\n * condition: (req) => !isBot(req), // YOUR logic\r\n * stream: () => createStreamingSSR({ ... }),\r\n * static: () => renderToString(<App />),\r\n * });\r\n * ```\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Condition function to determine if streaming should be used\r\n */\r\nexport type StreamingCondition = (request: Request) => boolean | Promise<boolean>;\r\n\r\n/**\r\n * Built-in condition types\r\n */\r\nexport type BuiltInCondition =\r\n | 'always-stream' // Always use streaming\r\n | 'never-stream' // Always use static\r\n | 'no-bots' // Stream for users, static for bots\r\n | 'fast-network' // Stream only on fast connections\r\n | 'modern-browser'; // Stream only on modern browsers\r\n\r\n/**\r\n * Configuration for conditional streaming\r\n */\r\nexport interface StreamIfConfig<T = Response> {\r\n /** The incoming request */\r\n request: Request;\r\n /** Condition to check (function or built-in) */\r\n condition: StreamingCondition | BuiltInCondition;\r\n /** Factory for streaming response */\r\n stream: () => Promise<T> | T;\r\n /** Factory for static response */\r\n static: () => Promise<T> | T;\r\n /** Optional: Custom bot patterns */\r\n botPatterns?: RegExp[];\r\n /** Optional: Force streaming via query param (for testing) */\r\n forceStreamParam?: string;\r\n /** Optional: Force static via query param (for testing) */\r\n forceStaticParam?: string;\r\n}\r\n\r\n/**\r\n * Result of condition evaluation\r\n */\r\nexport interface StreamingDecision {\r\n /** Whether streaming was used */\r\n streaming: boolean;\r\n /** Reason for the decision */\r\n reason: string;\r\n /** The response */\r\n response: Response;\r\n}\r\n\r\n// ============================================================================\r\n// Bot Detection\r\n// ============================================================================\r\n\r\n/**\r\n * Default bot patterns for detection\r\n */\r\nexport const DEFAULT_BOT_PATTERNS: RegExp[] = [\r\n /googlebot/i,\r\n /bingbot/i,\r\n /slurp/i, // Yahoo\r\n /duckduckbot/i,\r\n /baiduspider/i,\r\n /yandexbot/i,\r\n /sogou/i,\r\n /facebot/i, // Facebook\r\n /twitterbot/i,\r\n /linkedinbot/i,\r\n /whatsapp/i,\r\n /telegrambot/i,\r\n /discordbot/i,\r\n /slackbot/i,\r\n /applebot/i,\r\n /crawler/i,\r\n /spider/i,\r\n /bot\\//i,\r\n /bot;/i,\r\n /headless/i, // Headless browsers\r\n /lighthouse/i, // Google Lighthouse\r\n /pagespeed/i,\r\n /gtmetrix/i,\r\n /pingdom/i,\r\n /uptimerobot/i,\r\n];\r\n\r\n/**\r\n * Check if a request is from a bot/crawler\r\n */\r\nexport function isBot(request: Request, customPatterns?: RegExp[]): boolean {\r\n const userAgent = request.headers.get('user-agent') || '';\r\n const patterns = customPatterns || DEFAULT_BOT_PATTERNS;\r\n return patterns.some(pattern => pattern.test(userAgent));\r\n}\r\n\r\n/**\r\n * Check if request explicitly asks for no streaming\r\n */\r\nexport function prefersNoStream(request: Request): boolean {\r\n // Check for custom header\r\n if (request.headers.get('x-no-stream') === 'true') return true;\r\n if (request.headers.get('x-prefer-static') === 'true') return true;\r\n\r\n // Check Accept header for preference\r\n const accept = request.headers.get('accept') || '';\r\n if (accept.includes('text/html; streaming=false')) return true;\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if a connection is likely slow (based on headers)\r\n */\r\nexport function isSlowConnection(request: Request): boolean {\r\n // ECT (Effective Connection Type) header\r\n const ect = request.headers.get('ect');\r\n if (ect && ['slow-2g', '2g'].includes(ect)) return true;\r\n\r\n // Save-Data header\r\n if (request.headers.get('save-data') === 'on') return true;\r\n\r\n // Downlink header (Mbps)\r\n const downlink = request.headers.get('downlink');\r\n if (downlink && parseFloat(downlink) < 1) return true;\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if browser supports streaming well\r\n */\r\nexport function supportsStreaming(request: Request): boolean {\r\n const userAgent = request.headers.get('user-agent') || '';\r\n\r\n // IE doesn't support streaming well\r\n if (/MSIE|Trident/i.test(userAgent)) return false;\r\n\r\n // Very old browsers\r\n if (/Opera Mini/i.test(userAgent)) return false;\r\n\r\n // Check for modern browser features via client hints\r\n const secChUa = request.headers.get('sec-ch-ua');\r\n if (secChUa) {\r\n // Has client hints = modern browser\r\n return true;\r\n }\r\n\r\n return true; // Default to supporting streaming\r\n}\r\n\r\n// ============================================================================\r\n// Built-in Conditions\r\n// ============================================================================\r\n\r\nfunction getBuiltInCondition(\r\n condition: BuiltInCondition,\r\n botPatterns?: RegExp[]\r\n): StreamingCondition {\r\n switch (condition) {\r\n case 'always-stream':\r\n return () => true;\r\n case 'never-stream':\r\n return () => false;\r\n case 'no-bots':\r\n return (req) => !isBot(req, botPatterns) && !prefersNoStream(req);\r\n case 'fast-network':\r\n return (req) => !isSlowConnection(req) && !isBot(req, botPatterns);\r\n case 'modern-browser':\r\n return (req) => supportsStreaming(req) && !isBot(req, botPatterns);\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Main Function\r\n// ============================================================================\r\n\r\n/**\r\n * Conditionally use streaming or static rendering based on request context\r\n */\r\nexport async function streamIf<T = Response>(\r\n config: StreamIfConfig<T>\r\n): Promise<{ result: T; streaming: boolean; reason: string }> {\r\n const {\r\n request,\r\n condition,\r\n stream,\r\n static: staticFn,\r\n botPatterns,\r\n forceStreamParam = '__stream',\r\n forceStaticParam = '__static',\r\n } = config;\r\n\r\n // Check for forced mode via query params (useful for testing)\r\n const url = new URL(request.url);\r\n if (url.searchParams.has(forceStreamParam)) {\r\n const result = await stream();\r\n return { result, streaming: true, reason: 'forced via query param' };\r\n }\r\n if (url.searchParams.has(forceStaticParam)) {\r\n const result = await staticFn();\r\n return { result, streaming: false, reason: 'forced via query param' };\r\n }\r\n\r\n // Resolve condition\r\n const conditionFn = typeof condition === 'function'\r\n ? condition\r\n : getBuiltInCondition(condition, botPatterns);\r\n\r\n // Evaluate condition\r\n let shouldStream: boolean;\r\n let reason: string;\r\n\r\n try {\r\n shouldStream = await conditionFn(request);\r\n reason = shouldStream ? 'condition passed' : 'condition failed';\r\n } catch (error) {\r\n // On error, default to static (safer for SEO)\r\n shouldStream = false;\r\n reason = `condition error: ${error instanceof Error ? error.message : 'unknown'}`;\r\n }\r\n\r\n // Add specific reason for built-in conditions\r\n if (typeof condition === 'string') {\r\n if (!shouldStream && condition === 'no-bots') {\r\n reason = isBot(request, botPatterns)\r\n ? 'bot detected'\r\n : 'user prefers no streaming';\r\n } else if (!shouldStream && condition === 'fast-network') {\r\n reason = isSlowConnection(request)\r\n ? 'slow connection detected'\r\n : 'bot detected';\r\n }\r\n }\r\n\r\n // Execute appropriate renderer\r\n const result = shouldStream ? await stream() : await staticFn();\r\n return { result, streaming: shouldStream, reason };\r\n}\r\n\r\n/**\r\n * Create a middleware-style conditional streamer\r\n */\r\nexport function createConditionalStreamer<T = Response>(\r\n defaultCondition: StreamingCondition | BuiltInCondition,\r\n options?: {\r\n botPatterns?: RegExp[];\r\n forceStreamParam?: string;\r\n forceStaticParam?: string;\r\n }\r\n) {\r\n return async (config: {\r\n request: Request;\r\n stream: () => Promise<T> | T;\r\n static: () => Promise<T> | T;\r\n condition?: StreamingCondition | BuiltInCondition;\r\n }) => {\r\n return streamIf({\r\n request: config.request,\r\n condition: config.condition || defaultCondition,\r\n stream: config.stream,\r\n static: config.static,\r\n ...options,\r\n });\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Response Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Add streaming decision headers to response (for debugging)\r\n */\r\nexport function addStreamingHeaders(\r\n response: Response,\r\n decision: { streaming: boolean; reason: string }\r\n): Response {\r\n const headers = new Headers(response.headers);\r\n headers.set('X-Flight-Streaming', decision.streaming ? 'true' : 'false');\r\n headers.set('X-Flight-Streaming-Reason', decision.reason);\r\n\r\n return new Response(response.body, {\r\n status: response.status,\r\n statusText: response.statusText,\r\n headers,\r\n });\r\n}\r\n\r\n/**\r\n * Create a streaming-aware Response with appropriate headers\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 isStreaming?: boolean;\r\n }\r\n): Response {\r\n const { status = 200, headers = {}, isStreaming = true } = options || {};\r\n\r\n return new Response(stream, {\r\n status,\r\n headers: {\r\n 'Content-Type': 'text/html; charset=utf-8',\r\n 'Transfer-Encoding': isStreaming ? 'chunked' : undefined,\r\n 'X-Content-Type-Options': 'nosniff',\r\n 'X-Flight-Streaming': isStreaming ? 'true' : 'false',\r\n ...headers,\r\n } as HeadersInit,\r\n });\r\n}\r\n\r\n/**\r\n * Create a static HTML Response\r\n */\r\nexport function createStaticResponse(\r\n html: string,\r\n options?: {\r\n status?: number;\r\n headers?: Record<string, string>;\r\n }\r\n): Response {\r\n const { status = 200, headers = {} } = options || {};\r\n\r\n return new Response(html, {\r\n status,\r\n headers: {\r\n 'Content-Type': 'text/html; charset=utf-8',\r\n 'X-Flight-Streaming': 'false',\r\n ...headers,\r\n },\r\n });\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-XSY5AAXT.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 // userAgent could be used here for bot detection if needed\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/utils/env.ts"],"names":[],"mappings":";AAmBO,SAAS,YAAA,GAAwB;AAEpC,EAAA,IAAI,OAAO,UAAA,KAAe,WAAA,IAAe,SAAA,IAAa,UAAA,EAAY;AAC9D,IAAA,MAAM,OAAQ,UAAA,CAA6D,OAAA;AAC3E,IAAA,OAAO,IAAA,EAAM,KAAK,QAAA,KAAa,YAAA;AAAA,EACnC;AAEA,EAAA,IAAI,OAAO,MAAA,CAAA,IAAA,KAAgB,WAAA,IAAe,KAAA,IAAS,MAAA,CAAA,IAAA,EAAa;AAC5D,IAAA,MAAM,MAAO,MAAA,CAAA,IAAA,CAA4D,GAAA;AACzE,IAAA,OAAO,GAAA,EAAK,IAAA,KAAS,YAAA,IAAgB,GAAA,EAAK,IAAA,KAAS,IAAA;AAAA,EACvD;AACA,EAAA,OAAO,KAAA;AACX;AAUO,SAAS,aAAA,GAAyB;AAErC,EAAA,IAAI,OAAO,UAAA,KAAe,WAAA,IAAe,SAAA,IAAa,UAAA,EAAY;AAC9D,IAAA,MAAM,OAAQ,UAAA,CAA6D,OAAA;AAC3E,IAAA,OAAO,IAAA,EAAM,KAAK,QAAA,KAAa,aAAA;AAAA,EACnC;AAEA,EAAA,IAAI,OAAO,MAAA,CAAA,IAAA,KAAgB,WAAA,IAAe,KAAA,IAAS,MAAA,CAAA,IAAA,EAAa;AAC5D,IAAA,MAAM,MAAO,MAAA,CAAA,IAAA,CAA2D,GAAA;AACxE,IAAA,OAAO,GAAA,EAAK,IAAA,KAAS,aAAA,IAAiB,GAAA,EAAK,GAAA,KAAQ,IAAA;AAAA,EACvD;AAEA,EAAA,OAAO,IAAA;AACX;AAKO,SAAS,MAAA,GAAkB;AAC9B,EAAA,IAAI,OAAO,UAAA,KAAe,WAAA,IAAe,SAAA,IAAa,UAAA,EAAY;AAC9D,IAAA,MAAM,OAAQ,UAAA,CAA6D,OAAA;AAC3E,IAAA,OAAO,IAAA,EAAM,KAAK,QAAA,KAAa,MAAA;AAAA,EACnC;AACA,EAAA,OAAO,KAAA;AACX;AAKO,SAAS,QAAA,GAAoB;AAChC,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC7B;AAKO,SAAS,SAAA,GAAqB;AACjC,EAAA,OAAO,OAAO,MAAA,KAAW,WAAA;AAC7B;AAKO,SAAS,cAAA,GAAoE;AAChF,EAAA,IAAI,YAAA,IAAgB,OAAO,YAAA;AAC3B,EAAA,IAAI,aAAA,IAAiB,OAAO,aAAA;AAC5B,EAAA,IAAI,MAAA,IAAU,OAAO,MAAA;AACrB,EAAA,OAAO,SAAA;AACX","file":"chunk-YHEVHRLH.js","sourcesContent":["/**\r\n * @flight-framework/core - Environment Utilities\r\n * \r\n * Environment detection utilities that work across Node.js, browsers, and edge runtimes.\r\n * No hardcoded values - detects environment dynamically.\r\n */\r\n\r\n// ============================================================================\r\n// Environment Detection\r\n// ============================================================================\r\n\r\n/**\r\n * Check if running in production environment.\r\n * \r\n * Detection order:\r\n * 1. Node.js process.env.NODE_ENV\r\n * 2. Vite/modern bundlers import.meta.env.MODE or import.meta.env.PROD\r\n * 3. Default: false (not production)\r\n */\r\nexport function isProduction(): boolean {\r\n // Check for Node.js environment via globalThis (universal)\r\n if (typeof globalThis !== 'undefined' && 'process' in globalThis) {\r\n const proc = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\r\n return proc?.env?.NODE_ENV === 'production';\r\n }\r\n // Check for import.meta.env (Vite, modern bundlers)\r\n if (typeof import.meta !== 'undefined' && 'env' in import.meta) {\r\n const env = (import.meta as { env?: { MODE?: string; PROD?: boolean } }).env;\r\n return env?.MODE === 'production' || env?.PROD === true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if running in development environment.\r\n * \r\n * Detection order:\r\n * 1. Node.js process.env.NODE_ENV\r\n * 2. Vite/modern bundlers import.meta.env.MODE or import.meta.env.DEV\r\n * 3. Default: true (assume development if unknown)\r\n */\r\nexport function isDevelopment(): boolean {\r\n // Check for Node.js environment via globalThis (universal)\r\n if (typeof globalThis !== 'undefined' && 'process' in globalThis) {\r\n const proc = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\r\n return proc?.env?.NODE_ENV === 'development';\r\n }\r\n // Check for import.meta.env (Vite, modern bundlers)\r\n if (typeof import.meta !== 'undefined' && 'env' in import.meta) {\r\n const env = (import.meta as { env?: { MODE?: string; DEV?: boolean } }).env;\r\n return env?.MODE === 'development' || env?.DEV === true;\r\n }\r\n // Default to development if we can't detect\r\n return true;\r\n}\r\n\r\n/**\r\n * Check if running in test environment.\r\n */\r\nexport function isTest(): boolean {\r\n if (typeof globalThis !== 'undefined' && 'process' in globalThis) {\r\n const proc = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\r\n return proc?.env?.NODE_ENV === 'test';\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if running on the server (not browser).\r\n */\r\nexport function isServer(): boolean {\r\n return typeof window === 'undefined';\r\n}\r\n\r\n/**\r\n * Check if running in the browser.\r\n */\r\nexport function isBrowser(): boolean {\r\n return typeof window !== 'undefined';\r\n}\r\n\r\n/**\r\n * Get the current environment name.\r\n */\r\nexport function getEnvironment(): 'production' | 'development' | 'test' | 'unknown' {\r\n if (isProduction()) return 'production';\r\n if (isDevelopment()) return 'development';\r\n if (isTest()) return 'test';\r\n return 'unknown';\r\n}\r\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/rsc/vite-plugin.ts"],"names":["exports"],"mappings":"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","file":"chunk-ZIE56LCA.js","sourcesContent":["/**\r\n * @flight-framework/vite-plugin-rsc\r\n * \r\n * Vite plugin for Flight Server Components.\r\n * Transforms 'use client' and 'use server' directives at build time.\r\n * \r\n * Philosophy:\r\n * - Zero config for common cases\r\n * - Full control when needed\r\n * - Works with any Vite project\r\n * - No Next.js dependencies\r\n * \r\n * @module @flight-framework/vite-plugin-rsc\r\n */\r\n\r\nimport type { Plugin, ResolvedConfig } from 'vite';\r\nimport {\r\n analyzeModule,\r\n hasUseClientDirective,\r\n hasUseServerDirective,\r\n detectInlineServerActions,\r\n} from './boundaries.js';\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Plugin configuration\r\n */\r\nexport interface FlightRSCPluginOptions {\r\n /** Include patterns (glob) */\r\n include?: string[];\r\n\r\n /** Exclude patterns (glob) */\r\n exclude?: string[];\r\n\r\n /** Server actions endpoint */\r\n actionsEndpoint?: string;\r\n\r\n /** Client manifest output path */\r\n clientManifest?: string;\r\n\r\n /** Server manifest output path */\r\n serverManifest?: string;\r\n\r\n /** Enable dev mode features */\r\n dev?: boolean;\r\n\r\n /** Custom transforms */\r\n transforms?: {\r\n /** Transform client components */\r\n client?: (code: string, id: string) => string | null;\r\n /** Transform server actions */\r\n server?: (code: string, id: string) => string | null;\r\n };\r\n}\r\n\r\n/**\r\n * Client manifest entry\r\n */\r\nexport interface ClientManifestEntry {\r\n id: string;\r\n file: string;\r\n exports: string[];\r\n chunks?: string[];\r\n}\r\n\r\n/**\r\n * Server manifest entry\r\n */\r\nexport interface ServerManifestEntry {\r\n id: string;\r\n file: string;\r\n actions: string[];\r\n}\r\n\r\n// ============================================================================\r\n// Plugin Implementation\r\n// ============================================================================\r\n\r\n/**\r\n * Flight RSC Vite Plugin\r\n * \r\n * @example\r\n * ```typescript\r\n * // vite.config.ts\r\n * import { flightRSC } from '@flight-framework/core/rsc/vite-plugin';\r\n * \r\n * export default defineConfig({\r\n * plugins: [\r\n * flightRSC({\r\n * actionsEndpoint: '/_flight/action',\r\n * }),\r\n * ],\r\n * });\r\n * ```\r\n */\r\nexport function flightRSC(options: FlightRSCPluginOptions = {}): Plugin[] {\r\n const {\r\n include = ['**/*.tsx', '**/*.ts', '**/*.jsx', '**/*.js'],\r\n exclude = ['**/node_modules/**', '**/.git/**'],\r\n actionsEndpoint = '/_flight/action',\r\n clientManifest = '.flight/client-manifest.json',\r\n serverManifest = '.flight/server-manifest.json',\r\n // dev flag reserved for future use\r\n } = options;\r\n\r\n // State\r\n const clientModules = new Map<string, ClientManifestEntry>();\r\n const serverActions = new Map<string, ServerManifestEntry>();\r\n let config: ResolvedConfig;\r\n let isSSR = false;\r\n\r\n return [\r\n // ================================================================\r\n // 1. Analyze modules and track boundaries\r\n // ================================================================\r\n {\r\n name: 'flight-rsc:analyze',\r\n enforce: 'pre',\r\n\r\n configResolved(resolvedConfig) {\r\n config = resolvedConfig;\r\n },\r\n\r\n transform(code, id) {\r\n // Skip excluded files\r\n if (!shouldProcess(id, include, exclude)) {\r\n return null;\r\n }\r\n\r\n // Analyze module\r\n const analysis = analyzeModule(code, id);\r\n\r\n // Track client modules\r\n if (analysis.fileDirective === 'client') {\r\n clientModules.set(id, {\r\n id: createModuleId(id, config),\r\n file: id,\r\n exports: analysis.clientComponents,\r\n });\r\n }\r\n\r\n // Track server actions\r\n if (analysis.fileDirective === 'server' || analysis.serverActions.length > 0) {\r\n serverActions.set(id, {\r\n id: createModuleId(id, config),\r\n file: id,\r\n actions: analysis.serverActions,\r\n });\r\n }\r\n\r\n return null;\r\n },\r\n },\r\n\r\n // ================================================================\r\n // 2. Transform client components to references (server bundle)\r\n // ================================================================\r\n {\r\n name: 'flight-rsc:client-transform',\r\n\r\n transform(code, id, opts) {\r\n isSSR = opts?.ssr ?? false;\r\n\r\n if (!isSSR) return null;\r\n if (!hasUseClientDirective(code)) return null;\r\n if (!shouldProcess(id, include, exclude)) return null;\r\n\r\n // Custom transform\r\n if (options.transforms?.client) {\r\n const result = options.transforms.client(code, id);\r\n if (result) return result;\r\n }\r\n\r\n // Replace client component with reference proxy\r\n const moduleId = createModuleId(id, config);\r\n const exports = extractExportNames(code);\r\n\r\n let transformed = `\r\n// Flight RSC: Client Component Reference\r\n// Original: ${id}\r\n\r\nconst __flight_client_module_id = ${JSON.stringify(moduleId)};\r\n\r\n`;\r\n\r\n // Create proxy for each export\r\n for (const exportName of exports) {\r\n if (exportName === 'default') {\r\n transformed += `\r\nconst __flight_default_proxy = Object.assign(\r\n function() {\r\n throw new Error('Client Component cannot be called on the server. Module: ' + __flight_client_module_id);\r\n },\r\n {\r\n $$typeof: Symbol.for('flight.client.reference'),\r\n $$id: __flight_client_module_id + '#default',\r\n $$async: false,\r\n __flight_client: true,\r\n __flight_module: __flight_client_module_id,\r\n __flight_export: 'default',\r\n }\r\n);\r\n\r\nexport default __flight_default_proxy;\r\n`;\r\n } else {\r\n transformed += `\r\nexport const ${exportName} = Object.assign(\r\n function() {\r\n throw new Error('Client Component cannot be called on the server. Module: ' + __flight_client_module_id);\r\n },\r\n {\r\n $$typeof: Symbol.for('flight.client.reference'),\r\n $$id: __flight_client_module_id + '#${exportName}',\r\n $$async: false,\r\n __flight_client: true,\r\n __flight_module: __flight_client_module_id,\r\n __flight_export: '${exportName}',\r\n }\r\n);\r\n`;\r\n }\r\n }\r\n\r\n return {\r\n code: transformed,\r\n map: null,\r\n };\r\n },\r\n },\r\n\r\n // ================================================================\r\n // 3. Transform server actions to RPC calls (client bundle)\r\n // ================================================================\r\n {\r\n name: 'flight-rsc:server-transform',\r\n\r\n transform(code, id, opts) {\r\n isSSR = opts?.ssr ?? false;\r\n\r\n if (isSSR) return null; // Only transform for client\r\n if (!shouldProcess(id, include, exclude)) return null;\r\n\r\n // Check for file-level 'use server'\r\n if (hasUseServerDirective(code)) {\r\n // Custom transform\r\n if (options.transforms?.server) {\r\n const result = options.transforms.server(code, id);\r\n if (result) return result;\r\n }\r\n\r\n // Replace all exports with RPC calls\r\n const moduleId = createModuleId(id, config);\r\n const exports = extractExportNames(code);\r\n\r\n let transformed = `\r\n// Flight RSC: Server Actions (RPC Proxies)\r\n// Original: ${id}\r\n\r\nconst __flight_actions_endpoint = ${JSON.stringify(actionsEndpoint)};\r\nconst __flight_module_id = ${JSON.stringify(moduleId)};\r\n\r\nasync function __flight_call_action(actionId, args) {\r\n const response = await fetch(__flight_actions_endpoint, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Flight-Action': actionId,\r\n },\r\n body: JSON.stringify({ actionId, args }),\r\n });\r\n \r\n if (!response.ok) {\r\n const error = await response.json().catch(() => ({ message: 'Server action failed' }));\r\n throw new Error(error.message || 'Server action failed');\r\n }\r\n \r\n return response.json();\r\n}\r\n\r\n`;\r\n\r\n for (const exportName of exports) {\r\n const actionId = `${moduleId}#${exportName}`;\r\n if (exportName === 'default') {\r\n transformed += `\r\nexport default async function(...args) {\r\n return __flight_call_action(${JSON.stringify(actionId)}, args);\r\n}\r\n`;\r\n } else {\r\n transformed += `\r\nexport async function ${exportName}(...args) {\r\n return __flight_call_action(${JSON.stringify(actionId)}, args);\r\n}\r\n`;\r\n }\r\n }\r\n\r\n return {\r\n code: transformed,\r\n map: null,\r\n };\r\n }\r\n\r\n // Check for inline 'use server' in functions\r\n const inlineActions = detectInlineServerActions(code);\r\n if (inlineActions.length > 0) {\r\n // Transform specific functions to RPC calls\r\n let transformed = code;\r\n const moduleId = createModuleId(id, config);\r\n\r\n for (const actionName of inlineActions) {\r\n const actionId = `${moduleId}#${actionName}`;\r\n\r\n // Replace function with RPC call\r\n // This is a simplified transform - a real implementation would use AST\r\n const asyncFnPattern = new RegExp(\r\n `(async\\\\s+function\\\\s+${actionName}\\\\s*\\\\([^)]*\\\\)\\\\s*\\\\{[^}]*['\"]use server['\"][^}]*\\\\})`,\r\n 'g'\r\n );\r\n\r\n transformed = transformed.replace(asyncFnPattern, `\r\nasync function ${actionName}(...args) {\r\n const response = await fetch(${JSON.stringify(actionsEndpoint)}, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'X-Flight-Action': ${JSON.stringify(actionId)},\r\n },\r\n body: JSON.stringify({ actionId: ${JSON.stringify(actionId)}, args }),\r\n });\r\n if (!response.ok) throw new Error('Server action failed');\r\n return response.json();\r\n}`\r\n );\r\n }\r\n\r\n if (transformed !== code) {\r\n return {\r\n code: transformed,\r\n map: null,\r\n };\r\n }\r\n }\r\n\r\n return null;\r\n },\r\n },\r\n\r\n // ================================================================\r\n // 4. Generate manifests\r\n // ================================================================\r\n {\r\n name: 'flight-rsc:manifest',\r\n\r\n generateBundle() {\r\n // Client manifest\r\n if (clientModules.size > 0) {\r\n const manifest = Object.fromEntries(clientModules);\r\n this.emitFile({\r\n type: 'asset',\r\n fileName: clientManifest,\r\n source: JSON.stringify(manifest, null, 2),\r\n });\r\n }\r\n\r\n // Server manifest\r\n if (serverActions.size > 0) {\r\n const manifest = Object.fromEntries(serverActions);\r\n this.emitFile({\r\n type: 'asset',\r\n fileName: serverManifest,\r\n source: JSON.stringify(manifest, null, 2),\r\n });\r\n }\r\n },\r\n },\r\n\r\n // ================================================================\r\n // 5. Dev server middleware for server actions\r\n // ================================================================\r\n {\r\n name: 'flight-rsc:dev-server',\r\n apply: 'serve',\r\n\r\n configureServer(server) {\r\n server.middlewares.use(async (req, res, next) => {\r\n if (req.url?.startsWith(actionsEndpoint) && req.method === 'POST') {\r\n try {\r\n // Parse request body\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of req) {\r\n chunks.push(chunk as Buffer);\r\n }\r\n const body = JSON.parse(Buffer.concat(chunks).toString());\r\n\r\n const { actionId, args } = body;\r\n\r\n // Find and execute action\r\n const [moduleId, actionName] = actionId.split('#');\r\n const entry = [...serverActions.values()].find(e => e.id === moduleId);\r\n\r\n if (!entry) {\r\n res.statusCode = 404;\r\n res.end(JSON.stringify({ error: 'Action not found' }));\r\n return;\r\n }\r\n\r\n // Load module and execute action\r\n const mod = await server.ssrLoadModule(entry.file);\r\n const action = mod[actionName] || mod.default;\r\n\r\n if (typeof action !== 'function') {\r\n res.statusCode = 404;\r\n res.end(JSON.stringify({ error: 'Action not found' }));\r\n return;\r\n }\r\n\r\n const result = await action(...args);\r\n\r\n res.setHeader('Content-Type', 'application/json');\r\n res.end(JSON.stringify(result));\r\n\r\n } catch (error) {\r\n console.error('[Flight RSC] Action error:', error);\r\n res.statusCode = 500;\r\n res.end(JSON.stringify({\r\n error: (error as Error).message\r\n }));\r\n }\r\n return;\r\n }\r\n\r\n next();\r\n });\r\n },\r\n },\r\n ];\r\n}\r\n\r\n// ============================================================================\r\n// Helper Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Check if file should be processed\r\n */\r\nfunction shouldProcess(id: string, include: string[], exclude: string[]): boolean {\r\n // Simple glob matching (for production, use picomatch)\r\n const isIncluded = include.some(pattern => {\r\n const regex = globToRegex(pattern);\r\n return regex.test(id);\r\n });\r\n\r\n const isExcluded = exclude.some(pattern => {\r\n const regex = globToRegex(pattern);\r\n return regex.test(id);\r\n });\r\n\r\n return isIncluded && !isExcluded;\r\n}\r\n\r\n/**\r\n * Convert glob pattern to regex (simplified)\r\n */\r\nfunction globToRegex(pattern: string): RegExp {\r\n const escaped = pattern\r\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\r\n .replace(/\\*\\*/g, '{{GLOBSTAR}}')\r\n .replace(/\\*/g, '[^/]*')\r\n .replace(/{{GLOBSTAR}}/g, '.*');\r\n\r\n return new RegExp(escaped);\r\n}\r\n\r\n/**\r\n * Create a stable module ID from file path\r\n */\r\nfunction createModuleId(id: string, config: ResolvedConfig): string {\r\n // Remove root prefix\r\n let moduleId = id;\r\n if (config?.root && id.startsWith(config.root)) {\r\n moduleId = id.slice(config.root.length);\r\n }\r\n\r\n // Normalize path\r\n moduleId = moduleId.replace(/\\\\/g, '/');\r\n if (!moduleId.startsWith('/')) {\r\n moduleId = '/' + moduleId;\r\n }\r\n\r\n return moduleId;\r\n}\r\n\r\n/**\r\n * Extract export names from source code\r\n */\r\nfunction extractExportNames(code: string): string[] {\r\n const exports: string[] = [];\r\n\r\n // export default\r\n if (/export\\s+default\\s+/.test(code)) {\r\n exports.push('default');\r\n }\r\n\r\n // export function/const/let/class Name\r\n const namedPattern = /export\\s+(?:async\\s+)?(?:function|const|let|var|class)\\s+(\\w+)/g;\r\n let match;\r\n while ((match = namedPattern.exec(code)) !== null) {\r\n if (match[1] && match[1] !== 'default') {\r\n exports.push(match[1]);\r\n }\r\n }\r\n\r\n // export { a, b, c }\r\n const bracketPattern = /export\\s*\\{\\s*([^}]+)\\s*\\}/g;\r\n while ((match = bracketPattern.exec(code)) !== null) {\r\n if (match[1]) {\r\n const names = match[1].split(',').map(n => {\r\n const parts = n.trim().split(/\\s+as\\s+/);\r\n return parts[parts.length - 1]!.trim();\r\n });\r\n exports.push(...names.filter(n => n && n !== 'default'));\r\n }\r\n }\r\n\r\n return [...new Set(exports)];\r\n}\r\n\r\nexport default flightRSC;\r\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/render/index.ts"],"names":[],"mappings":";AA0EO,SAAS,eAAe,IAAA,EAA2B;AACtD,EAAA,OAAO,IAAA,KAAS,SAAS,IAAA,KAAS,KAAA;AACtC;AAKO,SAAS,YAAY,IAAA,EAA2B;AACnD,EAAA,OAAO,IAAA,KAAS,SAAS,IAAA,KAAS,KAAA;AACtC;AAKO,SAAS,aAAa,IAAA,EAA2B;AACpD,EAAA,OAAO,IAAA,KAAS,KAAA;AACpB;AAkDO,SAAS,gBAAgB,OAAA,EAOrB;AACP,EAAA,MAAM,EAAE,IAAA,GAAO,EAAA,EAAI,IAAA,EAAM,OAAA,GAAU,EAAC,EAAG,MAAA,GAAS,EAAC,EAAG,iBAAiB,EAAC,EAAG,cAAA,GAAiB,IAAG,GAAI,OAAA;AAEjG,EAAA,MAAM,SAAA,GAAY,OAAO,OAAA,CAAQ,cAAc,EAC1C,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,KAAK,MAAM,CAAA,EAAG,GAAG,KAAK,UAAA,CAAW,KAAK,CAAC,CAAA,CAAA,CAAG,CAAA,CACrD,KAAK,GAAG,CAAA;AAEb,EAAA,MAAM,SAAA,GAAY,OAAO,OAAA,CAAQ,cAAc,EAC1C,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,KAAK,MAAM,CAAA,EAAG,GAAG,KAAK,UAAA,CAAW,KAAK,CAAC,CAAA,CAAA,CAAG,CAAA,CACrD,KAAK,GAAG,CAAA;AAEb,EAAA,MAAM,UAAA,GAAa,MAAA,CACd,GAAA,CAAI,CAAA,IAAA,KAAQ,CAAA,6BAAA,EAAgC,UAAA,CAAW,IAAI,CAAC,CAAA,EAAA,CAAI,CAAA,CAChE,IAAA,CAAK,QAAQ,CAAA;AAElB,EAAA,MAAM,UAAA,GAAa,OAAA,CACd,GAAA,CAAI,CAAA,GAAA,KAAO,CAAA,2BAAA,EAA8B,UAAA,CAAW,GAAG,CAAC,CAAA,WAAA,CAAa,CAAA,CACrE,IAAA,CAAK,QAAQ,CAAA;AAElB,EAAA,OAAO,CAAA;AAAA,MAAA,EACH,SAAS,CAAA;AAAA;AAAA;AAAA;AAAA,IAAA,EAIX,UAAU;AAAA,IAAA,EACV,IAAI;AAAA;AAAA,QAAA,EAEA,SAAS,CAAA;AAAA,IAAA,EACb,IAAI;AAAA,IAAA,EACJ,UAAU;AAAA;AAAA,OAAA,CAAA;AAGhB;AAKO,SAAS,WAAW,GAAA,EAAqB;AAC5C,EAAA,OAAO,IACF,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAA,CACrB,OAAA,CAAQ,MAAM,MAAM,CAAA,CACpB,QAAQ,IAAA,EAAM,MAAM,EACpB,OAAA,CAAQ,IAAA,EAAM,QAAQ,CAAA,CACtB,OAAA,CAAQ,MAAM,OAAO,CAAA;AAC9B;AAKO,SAAS,eAAe,OAAA,EAId;AACb,EAAA,MAAM,EAAE,KAAA,GAAQ,YAAA,EAAc,WAAA,EAAa,MAAA,GAAS,OAAM,GAAI,OAAA;AAE9D,EAAA,MAAM,OAAO,eAAA,CAAgB;AAAA,IACzB,IAAA,EAAM,CAAA,OAAA,EAAU,UAAA,CAAW,KAAK,CAAC,CAAA,QAAA,CAAA;AAAA,IACjC,IAAA,EAAM,YAAY,MAAM,CAAA,QAAA,CAAA;AAAA,IACxB,OAAA,EAAS,CAAC,WAAW;AAAA,GACxB,CAAA;AAED,EAAA,OAAO;AAAA,IACH,IAAA;AAAA,IACA,MAAA,EAAQ,GAAA;AAAA,IACR,OAAA,EAAS;AAAA,MACL,cAAA,EAAgB;AAAA;AACpB,GACJ;AACJ","file":"chunk-ZVC3ZWLM.js","sourcesContent":["/**\r\n * Flight Render Engine - Universal rendering primitives\r\n * \r\n * Supports SSR, SSG, CSR, and ISR - the user chooses per route.\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/** Rendering modes supported by Flight */\r\nexport type RenderMode =\r\n | 'ssr' // Server-Side Rendering\r\n | 'ssg' // Static Site Generation\r\n | 'csr' // Client-Side Rendering\r\n | 'isr'; // Incremental Static Regeneration\r\n\r\n/** Context passed to render functions */\r\nexport interface RenderContext {\r\n /** The URL being rendered */\r\n url: URL;\r\n /** Route parameters */\r\n params: Record<string, string | string[]>;\r\n /** Request headers (available in SSR/ISR) */\r\n headers?: Headers;\r\n /** Cookies (available in SSR/ISR) */\r\n cookies?: Record<string, string>;\r\n /** Request method */\r\n method?: string;\r\n /** Request body (for POST/PUT/etc) */\r\n body?: unknown;\r\n /** Custom context data */\r\n locals?: Record<string, unknown>;\r\n}\r\n\r\n/** Result of a render operation */\r\nexport interface RenderResult {\r\n /** HTML content */\r\n html: string;\r\n /** HTTP status code */\r\n status: number;\r\n /** Response headers */\r\n headers: Record<string, string>;\r\n /** Head elements to inject */\r\n head?: {\r\n title?: string;\r\n meta?: Array<{ name?: string; property?: string; content: string }>;\r\n links?: Array<{ rel: string; href: string;[key: string]: string }>;\r\n scripts?: Array<{ src?: string; content?: string; type?: string }>;\r\n styles?: Array<{ href?: string; content?: string }>;\r\n };\r\n}\r\n\r\n/** Configuration for SSG/ISR */\r\nexport interface StaticRenderConfig {\r\n /** Paths to pre-render */\r\n paths: string[] | (() => Promise<string[]>);\r\n /** Fallback behavior for non-pre-rendered paths */\r\n fallback?: 'blocking' | 'prerender' | false;\r\n}\r\n\r\n/** Configuration for ISR */\r\nexport interface ISRConfig extends StaticRenderConfig {\r\n /** Revalidation time in seconds */\r\n revalidate: number;\r\n}\r\n\r\n// ============================================================================\r\n// Render Mode Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Check if a render mode requires server runtime\r\n */\r\nexport function requiresServer(mode: RenderMode): boolean {\r\n return mode === 'ssr' || mode === 'isr';\r\n}\r\n\r\n/**\r\n * Check if a render mode can be statically generated\r\n */\r\nexport function canBeStatic(mode: RenderMode): boolean {\r\n return mode === 'ssg' || mode === 'isr';\r\n}\r\n\r\n/**\r\n * Check if a render mode is purely client-side\r\n */\r\nexport function isClientOnly(mode: RenderMode): boolean {\r\n return mode === 'csr';\r\n}\r\n\r\n// ============================================================================\r\n// Abstract Renderer Interface\r\n// ============================================================================\r\n\r\n/**\r\n * UI Framework Integration Interface\r\n * \r\n * Each UI framework (React, Vue, Svelte, etc.) implements this interface\r\n * to integrate with Flight's render engine.\r\n */\r\nexport interface UIFrameworkAdapter<Component = unknown> {\r\n /** Framework name */\r\n name: string;\r\n\r\n /** \r\n * Render a component to HTML string (for SSR/SSG)\r\n */\r\n renderToString(\r\n component: Component,\r\n context: RenderContext\r\n ): Promise<RenderResult>;\r\n\r\n /**\r\n * Render a component to a stream (for streaming SSR)\r\n */\r\n renderToStream?(\r\n component: Component,\r\n context: RenderContext\r\n ): Promise<ReadableStream<Uint8Array>>;\r\n\r\n /**\r\n * Generate client hydration script\r\n */\r\n getHydrationScript?(component: Component): string;\r\n\r\n /**\r\n * File extensions this adapter handles\r\n */\r\n extensions: string[];\r\n}\r\n\r\n// ============================================================================\r\n// Default HTML Render Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Create a minimal HTML shell\r\n */\r\nexport function createHTMLShell(options: {\r\n head?: string;\r\n body: string;\r\n scripts?: string[];\r\n styles?: string[];\r\n htmlAttributes?: Record<string, string>;\r\n bodyAttributes?: Record<string, string>;\r\n}): string {\r\n const { head = '', body, scripts = [], styles = [], htmlAttributes = {}, bodyAttributes = {} } = options;\r\n\r\n const htmlAttrs = Object.entries(htmlAttributes)\r\n .map(([key, value]) => `${key}=\"${escapeHtml(value)}\"`)\r\n .join(' ');\r\n\r\n const bodyAttrs = Object.entries(bodyAttributes)\r\n .map(([key, value]) => `${key}=\"${escapeHtml(value)}\"`)\r\n .join(' ');\r\n\r\n const styleLinks = styles\r\n .map(href => `<link rel=\"stylesheet\" href=\"${escapeHtml(href)}\">`)\r\n .join('\\n ');\r\n\r\n const scriptTags = scripts\r\n .map(src => `<script type=\"module\" src=\"${escapeHtml(src)}\"></script>`)\r\n .join('\\n ');\r\n\r\n return `<!DOCTYPE html>\r\n<html ${htmlAttrs}>\r\n <head>\r\n <meta charset=\"UTF-8\">\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n ${styleLinks}\r\n ${head}\r\n </head>\r\n <body ${bodyAttrs}>\r\n ${body}\r\n ${scriptTags}\r\n </body>\r\n</html>`;\r\n}\r\n\r\n/**\r\n * Escape HTML special characters\r\n */\r\nexport function escapeHtml(str: string): string {\r\n return str\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n}\r\n\r\n/**\r\n * Create a CSR shell (minimal HTML that loads client bundle)\r\n */\r\nexport function createCSRShell(options: {\r\n title?: string;\r\n entryScript: string;\r\n rootId?: string;\r\n}): RenderResult {\r\n const { title = 'Flight App', entryScript, rootId = 'app' } = options;\r\n\r\n const html = createHTMLShell({\r\n head: `<title>${escapeHtml(title)}</title>`,\r\n body: `<div id=\"${rootId}\"></div>`,\r\n scripts: [entryScript],\r\n });\r\n\r\n return {\r\n html,\r\n status: 200,\r\n headers: {\r\n 'Content-Type': 'text/html; charset=utf-8',\r\n },\r\n };\r\n}\r\n"]}
|