@flight-framework/core 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +541 -541
- package/dist/actions/index.js +1 -1
- package/dist/adapters/index.d.ts +138 -1
- package/dist/adapters/index.js +1 -1
- package/dist/cache/index.js +1 -1
- package/dist/{chunk-3UQJE3XZ.js → chunk-2F2QU6RC.js} +2 -2
- package/dist/chunk-2F2QU6RC.js.map +1 -0
- package/dist/{chunk-4U7CJVNQ.js → chunk-3KRBRSRJ.js} +2 -2
- package/dist/chunk-3KRBRSRJ.js.map +1 -0
- package/dist/{chunk-OZ3EXPLE.js → chunk-3QP3E7HS.js} +2 -2
- package/dist/chunk-3QP3E7HS.js.map +1 -0
- package/dist/{chunk-CKJHJPKQ.js → chunk-62C7LX2E.js} +2 -2
- package/dist/chunk-62C7LX2E.js.map +1 -0
- package/dist/{chunk-YNTMYL36.js → chunk-6BDCTUQY.js} +3 -3
- package/dist/chunk-6BDCTUQY.js.map +1 -0
- package/dist/{chunk-KDEA64UX.js → chunk-EGB7C73X.js} +5 -5
- package/dist/chunk-EGB7C73X.js.map +1 -0
- package/dist/{chunk-2JVEH76V.js → chunk-FSJNOPYE.js} +3 -3
- package/dist/chunk-FSJNOPYE.js.map +1 -0
- package/dist/{chunk-ARBKF6VI.js → chunk-GCQZ4FHI.js} +2 -2
- package/dist/{chunk-ARBKF6VI.js.map → chunk-GCQZ4FHI.js.map} +1 -1
- package/dist/{chunk-EHVUAFNH.js → chunk-IXMD5QH2.js} +2 -2
- package/dist/chunk-IXMD5QH2.js.map +1 -0
- package/dist/{chunk-6GI6HFSQ.js → chunk-K2CQZPCG.js} +2 -2
- package/dist/chunk-K2CQZPCG.js.map +1 -0
- package/dist/chunk-K5NYYNFS.js +311 -0
- package/dist/chunk-K5NYYNFS.js.map +1 -0
- package/dist/{chunk-6IG6XIXU.js → chunk-LNV47HGV.js} +2 -2
- package/dist/chunk-LNV47HGV.js.map +1 -0
- package/dist/{chunk-65JYF3DJ.js → chunk-MDQNNIHH.js} +2 -2
- package/dist/chunk-MDQNNIHH.js.map +1 -0
- package/dist/{chunk-GNS2FGPC.js → chunk-MQQLYWZZ.js} +2 -2
- package/dist/chunk-MQQLYWZZ.js.map +1 -0
- package/dist/{chunk-LAKHYTHL.js → chunk-NWMJYTMB.js} +3 -3
- package/dist/chunk-NWMJYTMB.js.map +1 -0
- package/dist/{chunk-R7MEVVA4.js → chunk-OYF2OAKS.js} +2 -2
- package/dist/chunk-OYF2OAKS.js.map +1 -0
- package/dist/{chunk-FRAH5QNY.js → chunk-P6WSBVDT.js} +4 -4
- package/dist/chunk-P6WSBVDT.js.map +1 -0
- package/dist/{chunk-5XHOLZBJ.js → chunk-PDW5WCMW.js} +2 -2
- package/dist/chunk-PDW5WCMW.js.map +1 -0
- package/dist/{chunk-A2QRUBVE.js → chunk-PVUMB632.js} +2 -2
- package/dist/chunk-PVUMB632.js.map +1 -0
- package/dist/{chunk-LKOPJ3GS.js → chunk-R7SQAREQ.js} +2 -2
- package/dist/chunk-R7SQAREQ.js.map +1 -0
- package/dist/{chunk-CNY3ZUVG.js → chunk-RSVA2EYO.js} +2 -2
- package/dist/chunk-RSVA2EYO.js.map +1 -0
- package/dist/{chunk-PAVI5W6M.js → chunk-T4Z4HM4W.js} +3 -3
- package/dist/chunk-T4Z4HM4W.js.map +1 -0
- package/dist/{chunk-HNPO6LFW.js → chunk-TASAT7KB.js} +2 -2
- package/dist/chunk-TASAT7KB.js.map +1 -0
- package/dist/{chunk-3N5ZBVZJ.js → chunk-VPFMHGEV.js} +2 -2
- package/dist/chunk-VPFMHGEV.js.map +1 -0
- package/dist/{chunk-A4TKWQBU.js → chunk-W6D62JCI.js} +2 -2
- package/dist/chunk-W6D62JCI.js.map +1 -0
- package/dist/{chunk-UFWGOJL7.js → chunk-WFAWAHJH.js} +2 -2
- package/dist/chunk-WFAWAHJH.js.map +1 -0
- package/dist/{chunk-NZS2YJ43.js → chunk-WOEIJWGJ.js} +2 -2
- package/dist/chunk-WOEIJWGJ.js.map +1 -0
- package/dist/{chunk-VNO2YUVD.js → chunk-XOIYNY4I.js} +2 -2
- package/dist/chunk-XOIYNY4I.js.map +1 -0
- package/dist/{chunk-PO7IHPFF.js → chunk-XSY5AAXT.js} +2 -2
- package/dist/chunk-XSY5AAXT.js.map +1 -0
- package/dist/{chunk-OZBPR27I.js → chunk-YHEVHRLH.js} +2 -2
- package/dist/chunk-YHEVHRLH.js.map +1 -0
- package/dist/{chunk-XU6MRYG2.js → chunk-ZIE56LCA.js} +3 -3
- package/dist/chunk-ZIE56LCA.js.map +1 -0
- package/dist/{chunk-B2LPSCES.js → chunk-ZVC3ZWLM.js} +2 -2
- package/dist/chunk-ZVC3ZWLM.js.map +1 -0
- package/dist/client.js +8 -8
- package/dist/client.js.map +1 -1
- 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.js +11 -11
- 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 +1 -1
- package/dist/chunk-2JVEH76V.js.map +0 -1
- package/dist/chunk-3N5ZBVZJ.js.map +0 -1
- package/dist/chunk-3UQJE3XZ.js.map +0 -1
- package/dist/chunk-4U7CJVNQ.js.map +0 -1
- package/dist/chunk-5XHOLZBJ.js.map +0 -1
- package/dist/chunk-65JYF3DJ.js.map +0 -1
- package/dist/chunk-6GI6HFSQ.js.map +0 -1
- package/dist/chunk-6IG6XIXU.js.map +0 -1
- package/dist/chunk-A2QRUBVE.js.map +0 -1
- package/dist/chunk-A4TKWQBU.js.map +0 -1
- package/dist/chunk-B2LPSCES.js.map +0 -1
- package/dist/chunk-CKJHJPKQ.js.map +0 -1
- package/dist/chunk-CNY3ZUVG.js.map +0 -1
- package/dist/chunk-EHVUAFNH.js.map +0 -1
- package/dist/chunk-FRAH5QNY.js.map +0 -1
- package/dist/chunk-GNS2FGPC.js.map +0 -1
- package/dist/chunk-HNPO6LFW.js.map +0 -1
- package/dist/chunk-KDEA64UX.js.map +0 -1
- package/dist/chunk-LAKHYTHL.js.map +0 -1
- package/dist/chunk-LKOPJ3GS.js.map +0 -1
- package/dist/chunk-NZS2YJ43.js.map +0 -1
- package/dist/chunk-OZ3EXPLE.js.map +0 -1
- package/dist/chunk-OZBPR27I.js.map +0 -1
- package/dist/chunk-PAVI5W6M.js.map +0 -1
- package/dist/chunk-PO7IHPFF.js.map +0 -1
- package/dist/chunk-QK6UEQ75.js +0 -13
- package/dist/chunk-QK6UEQ75.js.map +0 -1
- package/dist/chunk-R7MEVVA4.js.map +0 -1
- package/dist/chunk-UFWGOJL7.js.map +0 -1
- package/dist/chunk-VNO2YUVD.js.map +0 -1
- package/dist/chunk-XU6MRYG2.js.map +0 -1
- package/dist/chunk-YNTMYL36.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rsc/plugins/esbuild.ts"],"names":["exports"],"mappings":"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","file":"chunk-T4Z4HM4W.js","sourcesContent":["/**\r\n * @flight-framework/core - esbuild Plugin for RSC\r\n * \r\n * esbuild plugin for Flight Server Components.\r\n * Transforms 'use client' and 'use server' directives at build time.\r\n * \r\n * Philosophy: Zero lock-in - esbuild is optional, user decides bundler.\r\n * \r\n * @module @flight-framework/core/rsc/plugins/esbuild\r\n */\r\n\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 * esbuild Plugin interface (minimal)\r\n * We define our own to avoid requiring esbuild as dependency\r\n */\r\nexport interface EsbuildPlugin {\r\n name: string;\r\n setup: (build: EsbuildBuild) => void | Promise<void>;\r\n}\r\n\r\nexport interface EsbuildBuild {\r\n initialOptions: EsbuildBuildOptions;\r\n onStart: (callback: () => void | Promise<void>) => void;\r\n onEnd: (callback: (result: EsbuildResult) => void | Promise<void>) => void;\r\n onResolve: (\r\n options: { filter: RegExp; namespace?: string },\r\n callback: (args: EsbuildResolveArgs) => EsbuildResolveResult | null | undefined | Promise<EsbuildResolveResult | null | undefined>\r\n ) => void;\r\n onLoad: (\r\n options: { filter: RegExp; namespace?: string },\r\n callback: (args: EsbuildLoadArgs) => EsbuildLoadResult | null | undefined | Promise<EsbuildLoadResult | null | undefined>\r\n ) => void;\r\n}\r\n\r\nexport interface EsbuildBuildOptions {\r\n outdir?: string;\r\n write?: boolean;\r\n metafile?: boolean;\r\n}\r\n\r\nexport interface EsbuildResult {\r\n errors: unknown[];\r\n warnings: unknown[];\r\n metafile?: unknown;\r\n}\r\n\r\nexport interface EsbuildResolveArgs {\r\n path: string;\r\n importer: string;\r\n namespace: string;\r\n resolveDir: string;\r\n kind: string;\r\n}\r\n\r\nexport interface EsbuildResolveResult {\r\n path?: string;\r\n external?: boolean;\r\n namespace?: string;\r\n suffix?: string;\r\n pluginData?: unknown;\r\n errors?: unknown[];\r\n warnings?: unknown[];\r\n watchFiles?: string[];\r\n watchDirs?: string[];\r\n}\r\n\r\nexport interface EsbuildLoadArgs {\r\n path: string;\r\n namespace: string;\r\n suffix: string;\r\n pluginData: unknown;\r\n}\r\n\r\nexport interface EsbuildLoadResult {\r\n contents?: string;\r\n loader?: 'js' | 'jsx' | 'ts' | 'tsx' | 'json' | 'text' | 'css';\r\n resolveDir?: string;\r\n errors?: unknown[];\r\n warnings?: unknown[];\r\n watchFiles?: string[];\r\n watchDirs?: string[];\r\n}\r\n\r\n/**\r\n * Plugin configuration\r\n */\r\nexport interface FlightEsbuildPluginOptions {\r\n /** Include patterns (regex) */\r\n include?: RegExp;\r\n\r\n /** Exclude patterns (regex) */\r\n exclude?: RegExp;\r\n\r\n /** Server actions endpoint */\r\n actionsEndpoint?: string;\r\n\r\n /** Output directory for manifests */\r\n manifestDir?: string;\r\n\r\n /** Is this for SSR build? */\r\n ssr?: boolean;\r\n\r\n /** Dev mode (include extra debug info) */\r\n dev?: boolean;\r\n}\r\n\r\n/**\r\n * Manifest entry\r\n */\r\nexport interface ManifestEntry {\r\n id: string;\r\n file: string;\r\n exports: string[];\r\n}\r\n\r\n// ============================================================================\r\n// Plugin State\r\n// ============================================================================\r\n\r\ninterface PluginState {\r\n clientModules: Map<string, ManifestEntry>;\r\n serverActions: Map<string, ManifestEntry>;\r\n isSSR: boolean;\r\n}\r\n\r\n// ============================================================================\r\n// Plugin Implementation\r\n// ============================================================================\r\n\r\n/**\r\n * Flight RSC esbuild Plugin\r\n * \r\n * @example\r\n * ```typescript\r\n * // build.js\r\n * import * as esbuild from 'esbuild';\r\n * import { flightRSCEsbuild } from '@flight-framework/core/rsc/plugins/esbuild';\r\n * \r\n * await esbuild.build({\r\n * entryPoints: ['src/index.tsx'],\r\n * bundle: true,\r\n * outdir: 'dist',\r\n * plugins: [\r\n * flightRSCEsbuild({\r\n * actionsEndpoint: '/_flight/action',\r\n * ssr: true,\r\n * }),\r\n * ],\r\n * });\r\n * ```\r\n */\r\nexport function flightRSCEsbuild(options: FlightEsbuildPluginOptions = {}): EsbuildPlugin {\r\n const {\r\n include = /\\.(tsx?|jsx?)$/,\r\n exclude = /node_modules/,\r\n actionsEndpoint = '/_flight/action',\r\n manifestDir = '.flight',\r\n ssr = false,\r\n dev = false,\r\n } = options;\r\n\r\n const state: PluginState = {\r\n clientModules: new Map(),\r\n serverActions: new Map(),\r\n isSSR: ssr,\r\n };\r\n\r\n return {\r\n name: 'flight-rsc',\r\n\r\n setup(build) {\r\n const outdir = build.initialOptions.outdir || 'dist';\r\n\r\n // ============================================================\r\n // onStart: Reset state\r\n // ============================================================\r\n build.onStart(() => {\r\n state.clientModules.clear();\r\n state.serverActions.clear();\r\n });\r\n\r\n // ============================================================\r\n // onLoad: Transform client/server modules\r\n // ============================================================\r\n build.onLoad({ filter: include }, async (args) => {\r\n // Skip excluded\r\n if (exclude.test(args.path)) {\r\n return null;\r\n }\r\n\r\n // Read file\r\n const fs = await import('fs/promises');\r\n const code = await fs.readFile(args.path, 'utf-8');\r\n\r\n // Analyze module\r\n const analysis = analyzeModule(code, args.path);\r\n const moduleId = createModuleId(args.path);\r\n\r\n // Track client modules\r\n if (analysis.fileDirective === 'client') {\r\n state.clientModules.set(args.path, {\r\n id: moduleId,\r\n file: args.path,\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 state.serverActions.set(args.path, {\r\n id: moduleId,\r\n file: args.path,\r\n exports: analysis.serverActions,\r\n });\r\n }\r\n\r\n // Transform based on build type\r\n if (ssr) {\r\n // SSR build: Transform 'use client' to references\r\n if (hasUseClientDirective(code)) {\r\n return {\r\n contents: transformClientForSSR(code, moduleId),\r\n loader: getLoader(args.path),\r\n };\r\n }\r\n } else {\r\n // Client build: Transform 'use server' to RPC calls\r\n if (hasUseServerDirective(code)) {\r\n return {\r\n contents: transformServerForClient(code, moduleId, actionsEndpoint),\r\n loader: getLoader(args.path),\r\n };\r\n }\r\n\r\n // Transform inline server actions\r\n const inlineActions = detectInlineServerActions(code);\r\n if (inlineActions.length > 0) {\r\n return {\r\n contents: transformInlineActions(code, moduleId, inlineActions, actionsEndpoint),\r\n loader: getLoader(args.path),\r\n };\r\n }\r\n }\r\n\r\n return null;\r\n });\r\n\r\n // ============================================================\r\n // onEnd: Write manifests\r\n // ============================================================\r\n build.onEnd(async () => {\r\n const fs = await import('fs/promises');\r\n const path = await import('path');\r\n\r\n const manifestPath = path.join(outdir, manifestDir);\r\n\r\n // Ensure directory exists\r\n await fs.mkdir(manifestPath, { recursive: true });\r\n\r\n // Write client manifest\r\n if (state.clientModules.size > 0) {\r\n const clientManifest = Object.fromEntries(state.clientModules);\r\n await fs.writeFile(\r\n path.join(manifestPath, 'client-manifest.json'),\r\n JSON.stringify(clientManifest, null, 2)\r\n );\r\n }\r\n\r\n // Write server manifest\r\n if (state.serverActions.size > 0) {\r\n const serverManifest = Object.fromEntries(state.serverActions);\r\n await fs.writeFile(\r\n path.join(manifestPath, 'server-manifest.json'),\r\n JSON.stringify(serverManifest, null, 2)\r\n );\r\n }\r\n\r\n if (dev) {\r\n console.log(`[Flight RSC] Client modules: ${state.clientModules.size}`);\r\n console.log(`[Flight RSC] Server actions: ${state.serverActions.size}`);\r\n }\r\n });\r\n },\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Transform Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Transform 'use client' module for SSR build\r\n */\r\nfunction transformClientForSSR(code: string, moduleId: string): string {\r\n const exports = extractExportNames(code);\r\n\r\n let transformed = `\r\n// Flight RSC: Client Component Reference (esbuild)\r\n// Original module: ${moduleId}\r\n\r\nconst __flight_module_id = ${JSON.stringify(moduleId)};\r\n\r\n`;\r\n\r\n for (const exportName of exports) {\r\n if (exportName === 'default') {\r\n transformed += `\r\nconst __flight_default = Object.assign(\r\n function() {\r\n throw new Error('Client Component cannot be called on the server. Module: ' + __flight_module_id);\r\n },\r\n {\r\n $$typeof: Symbol.for('flight.client.reference'),\r\n $$id: __flight_module_id + '#default',\r\n $$async: false,\r\n __flight_client: true,\r\n __flight_module: __flight_module_id,\r\n __flight_export: 'default',\r\n }\r\n);\r\nexport default __flight_default;\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_module_id);\r\n },\r\n {\r\n $$typeof: Symbol.for('flight.client.reference'),\r\n $$id: __flight_module_id + '#${exportName}',\r\n $$async: false,\r\n __flight_client: true,\r\n __flight_module: __flight_module_id,\r\n __flight_export: '${exportName}',\r\n }\r\n);\r\n`;\r\n }\r\n }\r\n\r\n return transformed;\r\n}\r\n\r\n/**\r\n * Transform 'use server' module for client build\r\n */\r\nfunction transformServerForClient(code: string, moduleId: string, endpoint: string): string {\r\n const exports = extractExportNames(code);\r\n\r\n let transformed = `\r\n// Flight RSC: Server Actions RPC Proxies (esbuild)\r\n// Original module: ${moduleId}\r\n\r\nconst __flight_endpoint = ${JSON.stringify(endpoint)};\r\nconst __flight_module_id = ${JSON.stringify(moduleId)};\r\n\r\nasync function __flight_rpc(actionId, args) {\r\n const response = await fetch(__flight_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_rpc(${JSON.stringify(actionId)}, args);\r\n}\r\n`;\r\n } else {\r\n transformed += `\r\nexport async function ${exportName}(...args) {\r\n return __flight_rpc(${JSON.stringify(actionId)}, args);\r\n}\r\n`;\r\n }\r\n }\r\n\r\n return transformed;\r\n}\r\n\r\n/**\r\n * Transform inline server actions\r\n */\r\nfunction transformInlineActions(\r\n code: string,\r\n moduleId: string,\r\n actions: string[],\r\n endpoint: string\r\n): string {\r\n let transformed = code;\r\n\r\n // Add RPC helper at the top (after any imports)\r\n const rpcHelper = `\r\n// Flight RSC: Inline Server Action Helpers\r\nconst __flight_endpoint_inline = ${JSON.stringify(endpoint)};\r\nasync function __flight_rpc_inline(actionId, args) {\r\n const response = await fetch(__flight_endpoint_inline, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json', 'X-Flight-Action': actionId },\r\n body: 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 // Find last import statement\r\n const lastImportMatch = code.match(/^import\\s.+$/gm);\r\n if (lastImportMatch) {\r\n const lastImport = lastImportMatch[lastImportMatch.length - 1] || '';\r\n const insertPos = code.indexOf(lastImport) + lastImport.length;\r\n transformed = code.slice(0, insertPos) + '\\n' + rpcHelper + code.slice(insertPos);\r\n } else {\r\n transformed = rpcHelper + code;\r\n }\r\n\r\n // Transform each action function\r\n for (const actionName of actions) {\r\n const actionId = `${moduleId}#${actionName}`;\r\n\r\n // Replace async function with RPC call\r\n // This is simplified - production would use proper AST transformation\r\n const patterns = [\r\n // async function name() { 'use server'; ... }\r\n new RegExp(\r\n `async\\\\s+function\\\\s+${actionName}\\\\s*\\\\([^)]*\\\\)\\\\s*\\\\{[\\\\s\\\\S]*?['\"]use server['\"][\\\\s\\\\S]*?\\\\}`,\r\n 'g'\r\n ),\r\n // const name = async () => { 'use server'; ... }\r\n new RegExp(\r\n `const\\\\s+${actionName}\\\\s*=\\\\s*async\\\\s*\\\\([^)]*\\\\)\\\\s*=>\\\\s*\\\\{[\\\\s\\\\S]*?['\"]use server['\"][\\\\s\\\\S]*?\\\\}`,\r\n 'g'\r\n ),\r\n ];\r\n\r\n for (const pattern of patterns) {\r\n transformed = transformed.replace(\r\n pattern,\r\n `async function ${actionName}(...args) { return __flight_rpc_inline(${JSON.stringify(actionId)}, args); }`\r\n );\r\n }\r\n }\r\n\r\n return transformed;\r\n}\r\n\r\n// ============================================================================\r\n// Helper Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create module ID from file path\r\n */\r\nfunction createModuleId(filePath: string): string {\r\n // Normalize and create relative path\r\n let id = filePath.replace(/\\\\/g, '/');\r\n\r\n // Remove common prefixes\r\n const prefixes = ['/src/', 'src/'];\r\n for (const prefix of prefixes) {\r\n const idx = id.indexOf(prefix);\r\n if (idx !== -1) {\r\n id = id.slice(idx + prefix.length);\r\n break;\r\n }\r\n }\r\n\r\n if (!id.startsWith('/')) {\r\n id = '/' + id;\r\n }\r\n\r\n return id;\r\n}\r\n\r\n/**\r\n * Get esbuild loader from file extension\r\n */\r\nfunction getLoader(filePath: string): 'tsx' | 'ts' | 'jsx' | 'js' {\r\n if (filePath.endsWith('.tsx')) return 'tsx';\r\n if (filePath.endsWith('.ts')) return 'ts';\r\n if (filePath.endsWith('.jsx')) return 'jsx';\r\n return 'js';\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 flightRSCEsbuild;\r\n"]}
|
|
@@ -218,5 +218,5 @@ function markAsClientComponent(component, moduleId, exportName = "default") {
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
export { createReactAdapter, createReactConsumer, markAsClientComponent };
|
|
221
|
-
//# sourceMappingURL=chunk-
|
|
222
|
-
//# sourceMappingURL=chunk-
|
|
221
|
+
//# sourceMappingURL=chunk-TASAT7KB.js.map
|
|
222
|
+
//# sourceMappingURL=chunk-TASAT7KB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rsc/adapters/react.ts"],"names":[],"mappings":"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","file":"chunk-TASAT7KB.js","sourcesContent":["/**\r\n * @flight-framework/core - React UI Adapter\r\n * \r\n * Adapter for using React with Flight Server Components.\r\n * Enables Flight to render React elements without tight coupling.\r\n * \r\n * @module @flight-framework/core/rsc/adapters/react\r\n */\r\n\r\nimport type { UIAdapter, ElementTypeInfo } from '../renderer.js';\r\n\r\n// ============================================================================\r\n// React Symbols\r\n// ============================================================================\r\n\r\n// React internal symbols (stable across versions)\r\nconst REACT_ELEMENT_TYPE = Symbol.for('react.element');\r\nconst REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');\r\nconst REACT_PROVIDER_TYPE = Symbol.for('react.provider');\r\nconst REACT_CONTEXT_TYPE = Symbol.for('react.context');\r\nconst REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');\r\nconst REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');\r\nconst REACT_MEMO_TYPE = Symbol.for('react.memo');\r\nconst REACT_LAZY_TYPE = Symbol.for('react.lazy');\r\n\r\n// Flight reference symbols\r\nconst CLIENT_REFERENCE = Symbol.for('flight.client.reference');\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * React element shape (minimal interface)\r\n */\r\ninterface ReactElement {\r\n $$typeof: symbol;\r\n type: unknown;\r\n key: string | number | null;\r\n ref: unknown;\r\n props: Record<string, unknown>;\r\n _owner: unknown;\r\n}\r\n\r\n// ============================================================================\r\n// Adapter Implementation\r\n// ============================================================================\r\n\r\n/**\r\n * Create React UI Adapter\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createReactAdapter } from '@flight-framework/core/rsc/adapters/react';\r\n * import { renderToString } from 'react-dom/server';\r\n * import * as React from 'react';\r\n * \r\n * const adapter = createReactAdapter({\r\n * React,\r\n * renderToString,\r\n * });\r\n * \r\n * const renderer = createRenderer(adapter);\r\n * ```\r\n */\r\nexport function createReactAdapter(deps?: {\r\n /** React module (optional - for SSR) */\r\n React?: {\r\n isValidElement: (value: unknown) => boolean;\r\n Children: { toArray: (children: unknown) => unknown[] };\r\n Fragment: symbol;\r\n Suspense: unknown;\r\n };\r\n /** renderToString function (optional - for SSR fallbacks) */\r\n renderToString?: (element: unknown) => string;\r\n}): UIAdapter {\r\n const { React, renderToString } = deps || {};\r\n\r\n return {\r\n name: 'react',\r\n\r\n isElement(value: unknown): boolean {\r\n if (React) {\r\n return React.isValidElement(value);\r\n }\r\n // Fallback: check for $$typeof\r\n return (\r\n typeof value === 'object' &&\r\n value !== null &&\r\n '$$typeof' in value &&\r\n (value as ReactElement).$$typeof === REACT_ELEMENT_TYPE\r\n );\r\n },\r\n\r\n getElementType(element: unknown): ElementTypeInfo {\r\n const el = element as ReactElement;\r\n const type = el.type;\r\n\r\n // String = host element (div, span, etc.)\r\n if (typeof type === 'string') {\r\n return { kind: 'host', tag: type };\r\n }\r\n\r\n // Symbol types\r\n if (typeof type === 'symbol') {\r\n if (type === REACT_FRAGMENT_TYPE || type === (React?.Fragment as symbol)) {\r\n return { kind: 'fragment' };\r\n }\r\n if (type === REACT_SUSPENSE_TYPE || (React?.Suspense && type === (React.Suspense as unknown as symbol))) {\r\n return {\r\n kind: 'suspense',\r\n fallback: el.props.fallback\r\n };\r\n }\r\n if (type === REACT_PROVIDER_TYPE) {\r\n return { kind: 'provider', value: el.props.value };\r\n }\r\n if (type === REACT_CONTEXT_TYPE) {\r\n return { kind: 'context' };\r\n }\r\n return { kind: 'null' };\r\n }\r\n\r\n // Object types (memo, lazy, forwardRef)\r\n if (typeof type === 'object' && type !== null) {\r\n const typeObj = type as { $$typeof?: symbol; type?: unknown; render?: unknown };\r\n\r\n if (typeObj.$$typeof === REACT_MEMO_TYPE) {\r\n // Unwrap memo\r\n return this.getElementType({ ...el, type: typeObj.type });\r\n }\r\n\r\n if (typeObj.$$typeof === REACT_LAZY_TYPE) {\r\n return { kind: 'component', fn: () => null, name: 'Lazy' };\r\n }\r\n\r\n if (typeObj.$$typeof === REACT_FORWARD_REF_TYPE && typeObj.render) {\r\n return {\r\n kind: 'component',\r\n fn: typeObj.render as (props: Record<string, unknown>) => unknown,\r\n name: 'ForwardRef'\r\n };\r\n }\r\n\r\n // Check for Suspense object\r\n if ('$$typeof' in typeObj &&\r\n (typeObj.$$typeof === REACT_SUSPENSE_TYPE)) {\r\n return { kind: 'suspense', fallback: el.props.fallback };\r\n }\r\n }\r\n\r\n // Function component\r\n if (typeof type === 'function') {\r\n const fn = type as ((props: Record<string, unknown>) => unknown) & {\r\n displayName?: string;\r\n name?: string;\r\n };\r\n return {\r\n kind: 'component',\r\n fn,\r\n name: fn.displayName || fn.name || 'Component'\r\n };\r\n }\r\n\r\n return { kind: 'null' };\r\n },\r\n\r\n getProps(element: unknown): Record<string, unknown> {\r\n return (element as ReactElement).props || {};\r\n },\r\n\r\n getChildren(element: unknown): unknown[] {\r\n const props = (element as ReactElement).props;\r\n const children = props?.children;\r\n\r\n if (children === undefined || children === null) {\r\n return [];\r\n }\r\n\r\n if (React?.Children) {\r\n return React.Children.toArray(children);\r\n }\r\n\r\n // Fallback array handling\r\n if (Array.isArray(children)) {\r\n return children.flat();\r\n }\r\n\r\n return [children];\r\n },\r\n\r\n getKey(element: unknown): string | number | undefined {\r\n const key = (element as ReactElement).key;\r\n return key !== null ? key : undefined;\r\n },\r\n\r\n isClientBoundary(component: unknown): boolean {\r\n if (typeof component !== 'function') return false;\r\n\r\n const comp = component as {\r\n $$typeof?: symbol;\r\n __flight_client?: boolean;\r\n };\r\n\r\n // Check for Flight client marker\r\n if (comp.__flight_client === true) return true;\r\n\r\n // Check for client reference symbol\r\n if (comp.$$typeof === CLIENT_REFERENCE) return true;\r\n\r\n return false;\r\n },\r\n\r\n createElement(\r\n component: (props: Record<string, unknown>) => unknown,\r\n props: Record<string, unknown>\r\n ): unknown {\r\n // Create a React element using the internal structure\r\n // This is framework-agnostic from the caller's perspective\r\n return {\r\n $$typeof: REACT_ELEMENT_TYPE,\r\n type: component,\r\n key: null,\r\n ref: null,\r\n props,\r\n _owner: null,\r\n };\r\n },\r\n\r\n async renderToString(element: unknown): Promise<string> {\r\n if (renderToString) {\r\n return renderToString(element);\r\n }\r\n throw new Error(\r\n 'renderToString not provided. Pass it when creating the adapter: ' +\r\n 'createReactAdapter({ renderToString })'\r\n );\r\n },\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// React Client Consumer\r\n// ============================================================================\r\n\r\n/**\r\n * Opciones para el consumer de React\r\n */\r\nexport interface ReactConsumerOptions {\r\n /** Registry de client components */\r\n registry?: Map<string, () => Promise<unknown>>;\r\n /** Callback when hydration completes */\r\n onHydrate?: (id: string) => void;\r\n}\r\n\r\n/**\r\n * Create a React client-side consumer for Flight payloads\r\n * \r\n * This reconstructs React elements from Flight chunks on the client.\r\n */\r\nexport function createReactConsumer(deps: {\r\n React: {\r\n createElement: (type: unknown, props?: unknown, ...children: unknown[]) => unknown;\r\n Suspense: unknown;\r\n Fragment: unknown;\r\n lazy: (factory: () => Promise<{ default: unknown }>) => unknown;\r\n };\r\n}, options: ReactConsumerOptions = {}) {\r\n const { React } = deps;\r\n const { registry = new Map() } = options;\r\n\r\n return {\r\n /**\r\n * Register a client component\r\n */\r\n register(id: string, loader: () => Promise<unknown>): void {\r\n registry.set(id, loader);\r\n },\r\n\r\n /**\r\n * Convert Flight elements to React elements\r\n */\r\n toReactElement(element: import('../payload.js').FlightElement): unknown {\r\n switch (element.$$type) {\r\n case 'null':\r\n return null;\r\n\r\n case 'text':\r\n return element.value;\r\n\r\n case 'host': {\r\n const children = element.children.map(c => this.toReactElement(c));\r\n return React.createElement(\r\n element.tag,\r\n { ...element.props, key: element.key },\r\n ...children\r\n );\r\n }\r\n\r\n case 'fragment': {\r\n const children = element.children.map(c => this.toReactElement(c));\r\n return React.createElement(React.Fragment, null, ...children);\r\n }\r\n\r\n case 'suspense': {\r\n const fallback = this.toReactElement(element.fallback);\r\n const children = element.children.map(c => this.toReactElement(c));\r\n return React.createElement(\r\n React.Suspense,\r\n { fallback },\r\n ...children\r\n );\r\n }\r\n\r\n case 'client': {\r\n // Get loader from registry\r\n const loader = registry.get(element.ref);\r\n if (!loader) {\r\n console.warn(`[Flight] Client component not registered: ${element.ref}`);\r\n // Return SSR fallback if available\r\n if (element.ssr) {\r\n return React.createElement('div', {\r\n dangerouslySetInnerHTML: { __html: element.ssr }\r\n });\r\n }\r\n return null;\r\n }\r\n\r\n // Create lazy component\r\n const LazyComponent = React.lazy(async () => {\r\n const mod = await loader() as { default?: unknown };\r\n return { default: mod.default ?? mod };\r\n });\r\n\r\n return React.createElement(LazyComponent);\r\n }\r\n\r\n case 'lazy': {\r\n // This is a pending chunk - render fallback\r\n if (element.fallback) {\r\n return this.toReactElement(element.fallback);\r\n }\r\n return React.createElement('div', { 'data-flight-pending': element.id });\r\n }\r\n\r\n default:\r\n return null;\r\n }\r\n },\r\n\r\n /**\r\n * Process Flight chunks and build React tree\r\n */\r\n processChunks(chunks: import('../payload.js').FlightChunk[]): unknown {\r\n // Find root chunk\r\n const rootChunk = chunks.find(c => c.type === 'S' && c.id === 'root');\r\n if (!rootChunk || rootChunk.type !== 'S') {\r\n throw new Error('[Flight] No root chunk found in payload');\r\n }\r\n\r\n // Register all client references\r\n for (const chunk of chunks) {\r\n if (chunk.type === 'C') {\r\n // Default registry - lazy load via dynamic import\r\n if (!registry.has(chunk.id)) {\r\n registry.set(chunk.id, () => import(/* webpackIgnore: true */ chunk.module));\r\n }\r\n }\r\n }\r\n\r\n return this.toReactElement(rootChunk.tree);\r\n }\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Utility Types\r\n// ============================================================================\r\n\r\n/**\r\n * Type helper for React Server Component\r\n */\r\nexport type ReactServerComponent<P = Record<string, unknown>> = (\r\n props: P,\r\n ctx: import('../context.js').ServerContext\r\n) => Promise<ReturnType<typeof import('react').createElement>> | ReturnType<typeof import('react').createElement>;\r\n\r\n/**\r\n * Mark a component as a client component (for use without bundler transform)\r\n */\r\nexport function markAsClientComponent<T extends (...args: unknown[]) => unknown>(\r\n component: T,\r\n moduleId: string,\r\n exportName = 'default'\r\n): T {\r\n const marked = component as T & {\r\n $$typeof: symbol;\r\n __flight_client: boolean;\r\n __flight_module: string;\r\n __flight_export: string;\r\n };\r\n\r\n marked.$$typeof = CLIENT_REFERENCE;\r\n marked.__flight_client = true;\r\n marked.__flight_module = moduleId;\r\n marked.__flight_export = exportName;\r\n\r\n return marked;\r\n}\r\n"]}
|
|
@@ -255,5 +255,5 @@ function isServer(deps) {
|
|
|
255
255
|
}
|
|
256
256
|
|
|
257
257
|
export { createSolidAdapter, createSolidConsumer, isServer, markAsSolidClientComponent };
|
|
258
|
-
//# sourceMappingURL=chunk-
|
|
259
|
-
//# sourceMappingURL=chunk-
|
|
258
|
+
//# sourceMappingURL=chunk-VPFMHGEV.js.map
|
|
259
|
+
//# sourceMappingURL=chunk-VPFMHGEV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rsc/adapters/solid.ts"],"names":[],"mappings":";AAkBA,IAAM,gBAAA,mBAAmB,MAAA,CAAO,GAAA,CAAI,yBAAyB,CAAA;AAgEtD,SAAS,mBAAmB,IAAA,EAAqC;AACpE,EAAA,MAAM,EAAE,KAAA,EAAO,GAAA,EAAI,GAAI,QAAQ,EAAC;AAEhC,EAAA,OAAO;AAAA,IACH,IAAA,EAAM,OAAA;AAAA,IAEN,UAAU,KAAA,EAAyB;AAC/B,MAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,EAAU;AAC7C,QAAA,OAAO,KAAA;AAAA,MACX;AAGA,MAAA,MAAM,EAAA,GAAK,KAAA;AAGX,MAAA,IAAI,OAAO,EAAA,KAAO,GAAA,IAAO,EAAA,IAAM,EAAA,CAAG,MAAM,IAAA,CAAA,EAAO;AAC3C,QAAA,OAAO,IAAA;AAAA,MACX;AAGA,MAAA,IAAI,OAAO,UAAU,UAAA,EAAY;AAC7B,QAAA,OAAO,IAAA;AAAA,MACX;AAEA,MAAA,OAAO,KAAA;AAAA,IACX,CAAA;AAAA,IAEA,eAAe,OAAA,EAAmC;AAE9C,MAAA,IAAI,OAAO,YAAY,UAAA,EAAY;AAC/B,QAAA,MAAM,EAAA,GAAK,OAAA;AAIX,QAAA,OAAO;AAAA,UACH,IAAA,EAAM,WAAA;AAAA,UACN,EAAA;AAAA,UACA,IAAA,EAAM,EAAA,CAAG,WAAA,IAAe,EAAA,CAAG,IAAA,IAAQ;AAAA,SACvC;AAAA,MACJ;AAEA,MAAA,MAAM,EAAA,GAAK,OAAA;AACX,MAAA,MAAM,OAAO,EAAA,CAAG,CAAA;AAGhB,MAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC1B,QAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,GAAA,EAAK,IAAA,EAAK;AAAA,MACrC;AAGA,MAAA,IAAI,OAAO,SAAS,UAAA,EAAY;AAC5B,QAAA,MAAM,EAAA,GAAK,IAAA;AAMX,QAAA,IAAI,KAAA,EAAO;AACP,UAAA,IAAI,IAAA,KAAS,MAAM,GAAA,EAAK;AACpB,YAAA,OAAO,EAAE,MAAM,UAAA,EAAW;AAAA,UAC9B;AACA,UAAA,IAAI,IAAA,KAAS,MAAM,IAAA,EAAM;AACrB,YAAA,OAAO,EAAE,MAAM,UAAA,EAAW;AAAA,UAC9B;AACA,UAAA,IAAI,IAAA,KAAS,MAAM,QAAA,EAAU;AACzB,YAAA,OAAO;AAAA,cACH,IAAA,EAAM,UAAA;AAAA,cACN,QAAA,EAAU,GAAG,CAAA,EAAG;AAAA,aACpB;AAAA,UACJ;AAAA,QACJ;AAEA,QAAA,OAAO;AAAA,UACH,IAAA,EAAM,WAAA;AAAA,UACN,EAAA;AAAA,UACA,IAAA,EAAM,EAAA,CAAG,WAAA,IAAe,EAAA,CAAG,IAAA,IAAQ;AAAA,SACvC;AAAA,MACJ;AAGA,MAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC1B,QAAA,OAAO,EAAE,MAAM,UAAA,EAAW;AAAA,MAC9B;AAEA,MAAA,OAAO,EAAE,MAAM,MAAA,EAAO;AAAA,IAC1B,CAAA;AAAA,IAEA,SAAS,OAAA,EAA2C;AAChD,MAAA,IAAI,OAAO,YAAY,UAAA,EAAY;AAC/B,QAAA,OAAO,EAAC;AAAA,MACZ;AACA,MAAA,OAAQ,OAAA,CAAyB,KAAK,EAAC;AAAA,IAC3C,CAAA;AAAA,IAEA,YAAY,OAAA,EAA6B;AACrC,MAAA,IAAI,OAAO,YAAY,UAAA,EAAY;AAC/B,QAAA,OAAO,EAAC;AAAA,MACZ;AAEA,MAAA,MAAM,QAAS,OAAA,CAAyB,CAAA;AACxC,MAAA,MAAM,WAAW,KAAA,EAAO,QAAA;AAExB,MAAA,IAAI,QAAA,KAAa,MAAA,IAAa,QAAA,KAAa,IAAA,EAAM;AAC7C,QAAA,OAAO,EAAC;AAAA,MACZ;AAGA,MAAA,IAAI,OAAO,aAAa,UAAA,EAAY;AAEhC,QAAA,IAAI,KAAK,QAAA,EAAU;AACf,UAAA,IAAI;AACA,YAAA,MAAM,SAAU,QAAA,EAA2B;AAC3C,YAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AACvB,cAAA,OAAO,MAAA;AAAA,YACX;AACA,YAAA,OAAO,CAAC,MAAM,CAAA;AAAA,UAClB,CAAA,CAAA,MAAQ;AACJ,YAAA,OAAO,EAAC;AAAA,UACZ;AAAA,QACJ;AAEA,QAAA,OAAO,CAAC,QAAQ,CAAA;AAAA,MACpB;AAEA,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,EAAG;AACzB,QAAA,OAAO,SAAS,IAAA,EAAK;AAAA,MACzB;AAEA,MAAA,OAAO,CAAC,QAAQ,CAAA;AAAA,IACpB,CAAA;AAAA,IAEA,OAAO,OAAA,EAA+C;AAClD,MAAA,IAAI,OAAO,YAAY,UAAA,EAAY;AAC/B,QAAA,OAAO,MAAA;AAAA,MACX;AACA,MAAA,MAAM,MAAO,OAAA,CAAyB,CAAA;AACtC,MAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,OAAO,QAAQ,QAAA,EAAU;AACpD,QAAA,OAAO,GAAA;AAAA,MACX;AACA,MAAA,OAAO,MAAA;AAAA,IACX,CAAA;AAAA,IAEA,iBAAiB,SAAA,EAA6B;AAC1C,MAAA,IAAI,OAAO,SAAA,KAAc,UAAA,IAAc,OAAO,cAAc,QAAA,EAAU;AAClE,QAAA,OAAO,KAAA;AAAA,MACX;AAEA,MAAA,MAAM,IAAA,GAAO,SAAA;AAMb,MAAA,IAAI,IAAA,CAAK,eAAA,KAAoB,IAAA,EAAM,OAAO,IAAA;AAG1C,MAAA,IAAI,IAAA,CAAK,QAAA,KAAa,gBAAA,EAAkB,OAAO,IAAA;AAE/C,MAAA,OAAO,KAAA;AAAA,IACX,CAAA;AAAA,IAEA,aAAA,CACI,WACA,KAAA,EACO;AAEP,MAAA,OAAO;AAAA,QACH,CAAA,EAAG,SAAA;AAAA,QACH,CAAA,EAAG,KAAA;AAAA,QACH,CAAA,EAAG;AAAA,OACP;AAAA,IACJ,CAAA;AAAA,IAEA,MAAM,eAAe,OAAA,EAAmC;AACpD,MAAA,IAAI,KAAK,mBAAA,EAAqB;AAE1B,QAAA,OAAO,GAAA,CAAI,mBAAA,CAAoB,MAAM,OAAO,CAAA;AAAA,MAChD;AACA,MAAA,IAAI,KAAK,cAAA,EAAgB;AAErB,QAAA,OAAO,GAAA,CAAI,cAAA,CAAe,MAAM,OAAO,CAAA;AAAA,MAC3C;AACA,MAAA,MAAM,IAAI,KAAA;AAAA,QACN;AAAA,OAEJ;AAAA,IACJ;AAAA,GACJ;AACJ;AAiBO,SAAS,mBAAA,CACZ,IAAA,EACA,OAAA,GAAgC,EAAC,EACnC;AACE,EAAA,MAAM,EAAE,KAAA,EAAO,GAAA,EAAI,GAAI,IAAA;AACvB,EAAA,MAAM,EAAE,QAAA,mBAAW,IAAI,GAAA,IAAM,GAAI,OAAA;AAEjC,EAAA,OAAO;AAAA;AAAA;AAAA;AAAA,IAIH,QAAA,CAAS,IAAY,MAAA,EAAsC;AACvD,MAAA,QAAA,CAAS,GAAA,CAAI,IAAI,MAAM,CAAA;AAAA,IAC3B,CAAA;AAAA;AAAA;AAAA;AAAA,IAKA,eAAe,OAAA,EAAyD;AACpE,MAAA,QAAQ,QAAQ,MAAA;AAAQ,QACpB,KAAK,MAAA;AACD,UAAA,OAAO,IAAA;AAAA,QAEX,KAAK,MAAA;AACD,UAAA,OAAO,OAAA,CAAQ,KAAA;AAAA,QAEnB,KAAK,MAAA,EAAQ;AAET,UAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,CAAS,GAAA,CAAI,OAAK,IAAA,CAAK,cAAA,CAAe,CAAC,CAAC,CAAA;AACjE,UAAA,OAAO;AAAA,YACH,GAAG,OAAA,CAAQ,GAAA;AAAA,YACX,CAAA,EAAG,EAAE,GAAG,OAAA,CAAQ,OAAO,QAAA,EAAS;AAAA,YAChC,GAAG,OAAA,CAAQ;AAAA,WACf;AAAA,QACJ;AAAA,QAEA,KAAK,UAAA,EAAY;AACb,UAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,CAAS,GAAA,CAAI,OAAK,IAAA,CAAK,cAAA,CAAe,CAAC,CAAC,CAAA;AACjE,UAAA,OAAO,QAAA;AAAA,QACX;AAAA,QAEA,KAAK,UAAA,EAAY;AACb,UAAA,IAAI,OAAO,QAAA,EAAU;AACjB,YAAA,MAAM,QAAA,GAAW,IAAA,CAAK,cAAA,CAAe,OAAA,CAAQ,QAAQ,CAAA;AACrD,YAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,CAAS,GAAA,CAAI,OAAK,IAAA,CAAK,cAAA,CAAe,CAAC,CAAC,CAAA;AACjE,YAAA,OAAO;AAAA,cACH,GAAG,KAAA,CAAM,QAAA;AAAA,cACT,GAAG,EAAE,QAAA,EAAU,MAAM,QAAA,EAAU,QAAA,EAAU,MAAM,QAAA;AAAS,aAC5D;AAAA,UACJ;AACA,UAAA,OAAO,QAAQ,QAAA,CAAS,GAAA,CAAI,OAAK,IAAA,CAAK,cAAA,CAAe,CAAC,CAAC,CAAA;AAAA,QAC3D;AAAA,QAEA,KAAK,QAAA,EAAU;AACX,UAAA,MAAM,MAAA,GAAS,QAAA,CAAS,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA;AACvC,UAAA,IAAI,CAAC,MAAA,EAAQ;AACT,YAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,0CAAA,EAA6C,OAAA,CAAQ,GAAG,CAAA,CAAE,CAAA;AACvE,YAAA,IAAI,QAAQ,GAAA,EAAK;AACb,cAAA,OAAO;AAAA,gBACH,CAAA,EAAG,KAAA;AAAA,gBACH,CAAA,EAAG,EAAE,SAAA,EAAW,OAAA,CAAQ,GAAA;AAAI,eAChC;AAAA,YACJ;AACA,YAAA,OAAO,IAAA;AAAA,UACX;AAIA,UAAA,MAAM,gBAAgB,YAAY;AAC9B,YAAA,MAAM,GAAA,GAAM,MAAM,MAAA,EAAO;AACzB,YAAA,OAAO,IAAI,OAAA,IAAW,GAAA;AAAA,UAC1B,CAAA;AAEA,UAAA,IAAI,OAAO,QAAA,EAAU;AACjB,YAAA,OAAO;AAAA,cACH,GAAG,KAAA,CAAM,QAAA;AAAA,cACT,CAAA,EAAG;AAAA,gBACC,QAAA,EAAU,MAAM,OAAA,CAAQ,GAAA,GAAM,EAAE,CAAA,EAAG,KAAA,EAAO,CAAA,EAAG,EAAE,SAAA,EAAW,OAAA,CAAQ,GAAA,IAAM,GAAI,IAAA;AAAA,gBAC5E,QAAA,EAAU;AAAA;AACd,aACJ;AAAA,UACJ;AAEA,UAAA,OAAO,EAAE,CAAA,EAAG,aAAA,EAAe,CAAA,EAAG,EAAC,EAAE;AAAA,QACrC;AAAA,QAEA,KAAK,MAAA,EAAQ;AACT,UAAA,IAAI,QAAQ,QAAA,EAAU;AAClB,YAAA,OAAO,IAAA,CAAK,cAAA,CAAe,OAAA,CAAQ,QAAQ,CAAA;AAAA,UAC/C;AACA,UAAA,OAAO;AAAA,YACH,CAAA,EAAG,KAAA;AAAA,YACH,CAAA,EAAG,EAAE,qBAAA,EAAuB,OAAA,CAAQ,EAAA;AAAG,WAC3C;AAAA,QACJ;AAAA,QAEA;AACI,UAAA,OAAO,IAAA;AAAA;AACf,IACJ,CAAA;AAAA;AAAA;AAAA;AAAA,IAKA,OAAA,CACI,QACA,SAAA,EACwB;AACxB,MAAA,MAAM,SAAA,GAAY,OAAO,IAAA,CAAK,CAAA,CAAA,KAAK,EAAE,IAAA,KAAS,GAAA,IAAO,CAAA,CAAE,EAAA,KAAO,MAAM,CAAA;AACpE,MAAA,IAAI,CAAC,SAAA,IAAa,SAAA,CAAU,IAAA,KAAS,GAAA,EAAK;AACtC,QAAA,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAAA,MAClD;AAGA,MAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AACxB,QAAA,IAAI,KAAA,CAAM,SAAS,GAAA,EAAK;AACpB,UAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,EAAE,CAAA,EAAG;AACzB,YAAA,QAAA,CAAS,GAAA,CAAI,KAAA,CAAM,EAAA,EAAI,MAAM;AAAA;AAAA,cAAiC,KAAA,CAAM;AAAA,aAAO,CAAA;AAAA,UAC/E;AAAA,QACJ;AAAA,MACJ;AAEA,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,cAAA,CAAe,SAAA,CAAU,IAAI,CAAA;AAElD,MAAA,IAAI,KAAK,OAAA,EAAS;AACd,QAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,MAAM,OAAA,EAAS,SAAS,CAAA;AAAA,MAC/C;AACA,MAAA,IAAI,KAAK,MAAA,EAAQ;AACb,QAAA,OAAO,GAAA,CAAI,MAAA,CAAO,MAAM,OAAA,EAAS,SAAS,CAAA;AAAA,MAC9C;AAEA,MAAA,MAAM,IAAI,MAAM,uDAAuD,CAAA;AAAA,IAC3E;AAAA,GACJ;AACJ;AAiBO,SAAS,0BAAA,CACZ,SAAA,EACA,QAAA,EACA,UAAA,GAAa,SAAA,EACZ;AACD,EAAA,MAAM,MAAA,GAAS,SAAA;AAOf,EAAA,MAAA,CAAO,QAAA,GAAW,gBAAA;AAClB,EAAA,MAAA,CAAO,eAAA,GAAkB,IAAA;AACzB,EAAA,MAAA,CAAO,eAAA,GAAkB,QAAA;AACzB,EAAA,MAAA,CAAO,eAAA,GAAkB,UAAA;AAEzB,EAAA,OAAO,MAAA;AACX;AAKO,SAAS,SAAS,IAAA,EAAmC;AACxD,EAAA,OAAO,IAAA,EAAM,GAAA,EAAK,QAAA,IAAa,OAAO,MAAA,KAAW,WAAA;AACrD","file":"chunk-VPFMHGEV.js","sourcesContent":["/**\r\n * @flight-framework/core - Solid.js UI Adapter\r\n * \r\n * Adapter for using Solid.js with Flight Server Components.\r\n * Enables Flight to render Solid components without tight coupling.\r\n * \r\n * Philosophy: Zero lock-in - Solid is optional, user decides.\r\n * \r\n * @module @flight-framework/core/rsc/adapters/solid\r\n */\r\n\r\nimport type { UIAdapter, ElementTypeInfo } from '../renderer.js';\r\n\r\n// ============================================================================\r\n// Solid Symbols\r\n// ============================================================================\r\n\r\n// Flight reference symbols\r\nconst CLIENT_REFERENCE = Symbol.for('flight.client.reference');\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Minimal Solid JSX Element interface\r\n */\r\ninterface SolidElement {\r\n t: string | ((props: unknown) => unknown); // tag or component\r\n p: Record<string, unknown> | null; // props\r\n r?: unknown; // key/ref\r\n}\r\n\r\n/**\r\n * Solid dependencies (user provides these)\r\n */\r\nexport interface SolidDependencies {\r\n /** solid-js module */\r\n solid: {\r\n createSignal: <T>(value: T) => [() => T, (v: T) => void];\r\n createMemo: <T>(fn: () => T) => () => T;\r\n createEffect: (fn: () => void) => void;\r\n children: (fn: () => unknown) => () => unknown[];\r\n splitProps: <T extends object, K extends keyof T>(\r\n props: T,\r\n ...keys: K[][]\r\n ) => [Pick<T, K>, Omit<T, K>][];\r\n For?: unknown;\r\n Show?: unknown;\r\n Switch?: unknown;\r\n Match?: unknown;\r\n Suspense?: unknown;\r\n ErrorBoundary?: unknown;\r\n };\r\n /** solid-js/web module */\r\n web: {\r\n render?: (code: () => unknown, element: Element) => () => void;\r\n hydrate?: (code: () => unknown, element: Element) => () => void;\r\n renderToString?: (code: () => unknown) => string;\r\n renderToStringAsync?: (code: () => unknown) => Promise<string>;\r\n isServer?: boolean;\r\n Dynamic?: unknown;\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Adapter Implementation\r\n// ============================================================================\r\n\r\n/**\r\n * Create Solid.js UI Adapter\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createSolidAdapter } from '@flight-framework/core/rsc/adapters/solid';\r\n * import * as solid from 'solid-js';\r\n * import * as web from 'solid-js/web';\r\n * \r\n * const adapter = createSolidAdapter({ solid, web });\r\n * const renderer = createRenderer(adapter);\r\n * ```\r\n */\r\nexport function createSolidAdapter(deps?: SolidDependencies): UIAdapter {\r\n const { solid, web } = deps || {};\r\n\r\n return {\r\n name: 'solid',\r\n\r\n isElement(value: unknown): boolean {\r\n if (value === null || typeof value !== 'object') {\r\n return false;\r\n }\r\n\r\n // Solid JSX elements are plain objects with t (type) and p (props)\r\n const el = value as Record<string, unknown>;\r\n\r\n // Check for Solid's compiled JSX structure\r\n if ('t' in el && ('p' in el || el.p === null)) {\r\n return true;\r\n }\r\n\r\n // Check for function components (Solid lazy returns functions)\r\n if (typeof value === 'function') {\r\n return true;\r\n }\r\n\r\n return false;\r\n },\r\n\r\n getElementType(element: unknown): ElementTypeInfo {\r\n // Handle function directly (component or lazy)\r\n if (typeof element === 'function') {\r\n const fn = element as ((props: Record<string, unknown>) => unknown) & {\r\n displayName?: string;\r\n name?: string;\r\n };\r\n return {\r\n kind: 'component',\r\n fn,\r\n name: fn.displayName || fn.name || 'SolidComponent'\r\n };\r\n }\r\n\r\n const el = element as SolidElement;\r\n const type = el.t;\r\n\r\n // String = host element (div, span, etc.)\r\n if (typeof type === 'string') {\r\n return { kind: 'host', tag: type };\r\n }\r\n\r\n // Function = component\r\n if (typeof type === 'function') {\r\n const fn = type as ((props: Record<string, unknown>) => unknown) & {\r\n displayName?: string;\r\n name?: string;\r\n };\r\n\r\n // Check for Solid built-in components\r\n if (solid) {\r\n if (type === solid.For) {\r\n return { kind: 'fragment' };\r\n }\r\n if (type === solid.Show) {\r\n return { kind: 'fragment' };\r\n }\r\n if (type === solid.Suspense) {\r\n return {\r\n kind: 'suspense',\r\n fallback: el.p?.fallback\r\n };\r\n }\r\n }\r\n\r\n return {\r\n kind: 'component',\r\n fn,\r\n name: fn.displayName || fn.name || 'Component'\r\n };\r\n }\r\n\r\n // Symbol types (Fragment, etc.)\r\n if (typeof type === 'symbol') {\r\n return { kind: 'fragment' };\r\n }\r\n\r\n return { kind: 'null' };\r\n },\r\n\r\n getProps(element: unknown): Record<string, unknown> {\r\n if (typeof element === 'function') {\r\n return {};\r\n }\r\n return (element as SolidElement).p || {};\r\n },\r\n\r\n getChildren(element: unknown): unknown[] {\r\n if (typeof element === 'function') {\r\n return [];\r\n }\r\n\r\n const props = (element as SolidElement).p;\r\n const children = props?.children;\r\n\r\n if (children === undefined || children === null) {\r\n return [];\r\n }\r\n\r\n // Solid children can be functions (for reactivity)\r\n if (typeof children === 'function') {\r\n // In SSR context, we can call the function\r\n if (web?.isServer) {\r\n try {\r\n const result = (children as () => unknown)();\r\n if (Array.isArray(result)) {\r\n return result;\r\n }\r\n return [result];\r\n } catch {\r\n return [];\r\n }\r\n }\r\n // On client, return as-is for hydration\r\n return [children];\r\n }\r\n\r\n if (Array.isArray(children)) {\r\n return children.flat();\r\n }\r\n\r\n return [children];\r\n },\r\n\r\n getKey(element: unknown): string | number | undefined {\r\n if (typeof element === 'function') {\r\n return undefined;\r\n }\r\n const ref = (element as SolidElement).r;\r\n if (typeof ref === 'string' || typeof ref === 'number') {\r\n return ref;\r\n }\r\n return undefined;\r\n },\r\n\r\n isClientBoundary(component: unknown): boolean {\r\n if (typeof component !== 'function' && typeof component !== 'object') {\r\n return false;\r\n }\r\n\r\n const comp = component as {\r\n $$typeof?: symbol;\r\n __flight_client?: boolean;\r\n };\r\n\r\n // Check for Flight client marker\r\n if (comp.__flight_client === true) return true;\r\n\r\n // Check for client reference symbol\r\n if (comp.$$typeof === CLIENT_REFERENCE) return true;\r\n\r\n return false;\r\n },\r\n\r\n createElement(\r\n component: (props: Record<string, unknown>) => unknown,\r\n props: Record<string, unknown>\r\n ): unknown {\r\n // Solid JSX elements are plain objects with t (type) and p (props)\r\n return {\r\n t: component,\r\n p: props,\r\n r: null,\r\n } as SolidElement;\r\n },\r\n\r\n async renderToString(element: unknown): Promise<string> {\r\n if (web?.renderToStringAsync) {\r\n // Async SSR with Suspense support\r\n return web.renderToStringAsync(() => element);\r\n }\r\n if (web?.renderToString) {\r\n // Sync SSR\r\n return web.renderToString(() => element);\r\n }\r\n throw new Error(\r\n 'renderToString not provided. Pass solid-js/web when creating the adapter: ' +\r\n 'createSolidAdapter({ solid, web })'\r\n );\r\n },\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Solid Client Consumer\r\n// ============================================================================\r\n\r\n/**\r\n * Options for Solid consumer\r\n */\r\nexport interface SolidConsumerOptions {\r\n /** Registry of client components */\r\n registry?: Map<string, () => Promise<unknown>>;\r\n}\r\n\r\n/**\r\n * Create a Solid client-side consumer for Flight payloads\r\n */\r\nexport function createSolidConsumer(\r\n deps: SolidDependencies,\r\n options: SolidConsumerOptions = {}\r\n) {\r\n const { solid, web } = deps;\r\n const { registry = new Map() } = options;\r\n\r\n return {\r\n /**\r\n * Register a client component\r\n */\r\n register(id: string, loader: () => Promise<unknown>): void {\r\n registry.set(id, loader);\r\n },\r\n\r\n /**\r\n * Convert Flight elements to Solid JSX\r\n */\r\n toSolidElement(element: import('../payload.js').FlightElement): unknown {\r\n switch (element.$$type) {\r\n case 'null':\r\n return null;\r\n\r\n case 'text':\r\n return element.value;\r\n\r\n case 'host': {\r\n // Create Solid element structure\r\n const children = element.children.map(c => this.toSolidElement(c));\r\n return {\r\n t: element.tag,\r\n p: { ...element.props, children },\r\n r: element.key,\r\n };\r\n }\r\n\r\n case 'fragment': {\r\n const children = element.children.map(c => this.toSolidElement(c));\r\n return children;\r\n }\r\n\r\n case 'suspense': {\r\n if (solid?.Suspense) {\r\n const fallback = this.toSolidElement(element.fallback);\r\n const children = element.children.map(c => this.toSolidElement(c));\r\n return {\r\n t: solid.Suspense,\r\n p: { fallback: () => fallback, children: () => children },\r\n };\r\n }\r\n return element.children.map(c => this.toSolidElement(c));\r\n }\r\n\r\n case 'client': {\r\n const loader = registry.get(element.ref);\r\n if (!loader) {\r\n console.warn(`[Flight] Client component not registered: ${element.ref}`);\r\n if (element.ssr) {\r\n return {\r\n t: 'div',\r\n p: { innerHTML: element.ssr },\r\n };\r\n }\r\n return null;\r\n }\r\n\r\n // Create lazy component for Solid\r\n // Solid's lazy is different - it expects a dynamic import\r\n const LazyComponent = async () => {\r\n const mod = await loader() as { default?: unknown };\r\n return mod.default ?? mod;\r\n };\r\n\r\n if (solid?.Suspense) {\r\n return {\r\n t: solid.Suspense,\r\n p: {\r\n fallback: () => element.ssr ? { t: 'div', p: { innerHTML: element.ssr } } : null,\r\n children: LazyComponent,\r\n },\r\n };\r\n }\r\n\r\n return { t: LazyComponent, p: {} };\r\n }\r\n\r\n case 'lazy': {\r\n if (element.fallback) {\r\n return this.toSolidElement(element.fallback);\r\n }\r\n return {\r\n t: 'div',\r\n p: { 'data-flight-pending': element.id }\r\n };\r\n }\r\n\r\n default:\r\n return null;\r\n }\r\n },\r\n\r\n /**\r\n * Hydrate Flight payload into DOM\r\n */\r\n hydrate(\r\n chunks: import('../payload.js').FlightChunk[],\r\n container: Element\r\n ): (() => void) | undefined {\r\n const rootChunk = chunks.find(c => c.type === 'S' && c.id === 'root');\r\n if (!rootChunk || rootChunk.type !== 'S') {\r\n throw new Error('[Flight] No root chunk found');\r\n }\r\n\r\n // Register client components\r\n for (const chunk of chunks) {\r\n if (chunk.type === 'C') {\r\n if (!registry.has(chunk.id)) {\r\n registry.set(chunk.id, () => import(/* webpackIgnore: true */ chunk.module));\r\n }\r\n }\r\n }\r\n\r\n const element = this.toSolidElement(rootChunk.tree);\r\n\r\n if (web?.hydrate) {\r\n return web.hydrate(() => element, container);\r\n }\r\n if (web?.render) {\r\n return web.render(() => element, container);\r\n }\r\n\r\n throw new Error('[Flight] Solid web.hydrate or web.render not provided');\r\n },\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Utility Types\r\n// ============================================================================\r\n\r\n/**\r\n * Type helper for Solid Server Component\r\n */\r\nexport type SolidServerComponent<P = Record<string, unknown>> = (\r\n props: P,\r\n ctx: import('../context.js').ServerContext\r\n) => Promise<unknown> | unknown;\r\n\r\n/**\r\n * Mark a Solid component as a client component\r\n */\r\nexport function markAsSolidClientComponent<T extends object>(\r\n component: T,\r\n moduleId: string,\r\n exportName = 'default'\r\n): T {\r\n const marked = component as T & {\r\n $$typeof: symbol;\r\n __flight_client: boolean;\r\n __flight_module: string;\r\n __flight_export: string;\r\n };\r\n\r\n marked.$$typeof = CLIENT_REFERENCE;\r\n marked.__flight_client = true;\r\n marked.__flight_module = moduleId;\r\n marked.__flight_export = exportName;\r\n\r\n return marked;\r\n}\r\n\r\n/**\r\n * Check if running on server (Solid isServer helper)\r\n */\r\nexport function isServer(deps?: SolidDependencies): boolean {\r\n return deps?.web?.isServer ?? (typeof window === 'undefined');\r\n}\r\n"]}
|
|
@@ -43,5 +43,5 @@ async function parseBody(request) {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export { createRouteContext, error, json, parseBody, redirect };
|
|
46
|
-
//# sourceMappingURL=chunk-
|
|
47
|
-
//# sourceMappingURL=chunk-
|
|
46
|
+
//# sourceMappingURL=chunk-W6D62JCI.js.map
|
|
47
|
+
//# sourceMappingURL=chunk-W6D62JCI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/handlers/index.ts"],"names":[],"mappings":";AAuDO,SAAS,kBAAA,CACZ,OAAA,EACA,MAAA,GAAiC,EAAC,EACf;AACnB,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA;AAC/B,EAAA,OAAO;AAAA,IACH,MAAA;AAAA,IACA,cAAc,GAAA,CAAI;AAAA,GACtB;AACJ;AAKO,SAAS,IAAA,CAAQ,MAAS,IAAA,EAA+B;AAC5D,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAQ,IAAA,EAAM,OAAO,CAAA;AACzC,EAAA,OAAA,CAAQ,GAAA,CAAI,gBAAgB,iCAAiC,CAAA;AAE7D,EAAA,OAAO,IAAI,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,EAAG;AAAA,IACtC,GAAG,IAAA;AAAA,IACH;AAAA,GACH,CAAA;AACL;AAKO,SAAS,QAAA,CAAS,GAAA,EAAa,MAAA,GAAsC,GAAA,EAAe;AACvF,EAAA,OAAO,IAAI,SAAS,IAAA,EAAM;AAAA,IACtB,MAAA;AAAA,IACA,OAAA,EAAS,EAAE,QAAA,EAAU,GAAA;AAAI,GAC5B,CAAA;AACL;AAKO,SAAS,KAAA,CAAM,OAAA,EAAiB,MAAA,GAAS,GAAA,EAAe;AAC3D,EAAA,OAAO,IAAI,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,OAAA,EAAS,CAAA,EAAG;AAAA,IACpD,MAAA;AAAA,IACA,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA;AAAmB,GACjD,CAAA;AACL;AAKA,eAAsB,UAAa,OAAA,EAA8B;AAC7D,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,EAAA;AAE3D,EAAA,IAAI,WAAA,CAAY,QAAA,CAAS,kBAAkB,CAAA,EAAG;AAC1C,IAAA,OAAO,MAAM,QAAQ,IAAA,EAAK;AAAA,EAC9B;AAEA,EAAA,IAAI,WAAA,CAAY,QAAA,CAAS,mCAAmC,CAAA,EAAG;AAC3D,IAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,QAAA,EAAS;AACxC,IAAA,MAAM,MAA8B,EAAC;AACrC,IAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC7B,MAAA,GAAA,CAAI,GAAG,CAAA,GAAI,MAAA,CAAO,KAAK,CAAA;AAAA,IAC3B,CAAC,CAAA;AACD,IAAA,OAAO,GAAA;AAAA,EACX;AAEA,EAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,WAAW,CAAA,CAAE,CAAA;AAC9D","file":"chunk-W6D62JCI.js","sourcesContent":["/**\r\n * @flight-framework/core - Route Handlers\r\n * \r\n * Types and utilities for route handlers.\r\n * Similar to Next.js Route Handlers pattern.\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * HTTP methods supported by route handlers\r\n */\r\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';\r\n\r\n/**\r\n * Context passed to route handlers\r\n */\r\nexport interface RouteHandlerContext {\r\n /** Route parameters (e.g., { id: '123' }) */\r\n params: Record<string, string>;\r\n /** Query string parameters */\r\n searchParams: URLSearchParams;\r\n}\r\n\r\n/**\r\n * Route handler function signature\r\n * \r\n * @example\r\n * ```typescript\r\n * // src/routes/api/users/[id].ts\r\n * export const GET: RouteHandler = async (request, context) => {\r\n * const { id } = context.params;\r\n * return Response.json({ userId: id });\r\n * };\r\n * \r\n * export const PUT: RouteHandler = async (request, context) => {\r\n * const body = await request.json();\r\n * return Response.json({ updated: true, data: body });\r\n * };\r\n * ```\r\n */\r\nexport type RouteHandler = (\r\n request: Request,\r\n context: RouteHandlerContext\r\n) => Response | Promise<Response>;\r\n\r\n// ============================================================================\r\n// Helper Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Create a route handler context from request\r\n */\r\nexport function createRouteContext(\r\n request: Request,\r\n params: Record<string, string> = {}\r\n): RouteHandlerContext {\r\n const url = new URL(request.url);\r\n return {\r\n params,\r\n searchParams: url.searchParams,\r\n };\r\n}\r\n\r\n/**\r\n * Helper to create JSON response\r\n */\r\nexport function json<T>(data: T, init?: ResponseInit): Response {\r\n const headers = new Headers(init?.headers);\r\n headers.set('Content-Type', 'application/json; charset=utf-8');\r\n\r\n return new Response(JSON.stringify(data), {\r\n ...init,\r\n headers,\r\n });\r\n}\r\n\r\n/**\r\n * Helper to create redirect response\r\n */\r\nexport function redirect(url: string, status: 301 | 302 | 303 | 307 | 308 = 302): Response {\r\n return new Response(null, {\r\n status,\r\n headers: { Location: url },\r\n });\r\n}\r\n\r\n/**\r\n * Helper to create error response\r\n */\r\nexport function error(message: string, status = 500): Response {\r\n return new Response(JSON.stringify({ error: message }), {\r\n status,\r\n headers: { 'Content-Type': 'application/json' },\r\n });\r\n}\r\n\r\n/**\r\n * Helper to get request body as typed object\r\n */\r\nexport async function parseBody<T>(request: Request): Promise<T> {\r\n const contentType = request.headers.get('content-type') || '';\r\n\r\n if (contentType.includes('application/json')) {\r\n return await request.json() as T;\r\n }\r\n\r\n if (contentType.includes('application/x-www-form-urlencoded')) {\r\n const formData = await request.formData();\r\n const obj: Record<string, string> = {};\r\n formData.forEach((value, key) => {\r\n obj[key] = String(value);\r\n });\r\n return obj as T;\r\n }\r\n\r\n throw new Error(`Unsupported content type: ${contentType}`);\r\n}\r\n"]}
|
|
@@ -263,5 +263,5 @@ function registerFlightIslandElement() {
|
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
export { createIslandRegistry, createPreactIslandAdapter, createReactIslandAdapter, createSolidIslandAdapter, createVueIslandAdapter, defineIsland, hydrateIslands, registerFlightIslandElement, registerIsland, renderIsland, renderIslands, setIslandAdapter };
|
|
266
|
-
//# sourceMappingURL=chunk-
|
|
267
|
-
//# sourceMappingURL=chunk-
|
|
266
|
+
//# sourceMappingURL=chunk-WFAWAHJH.js.map
|
|
267
|
+
//# sourceMappingURL=chunk-WFAWAHJH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/islands/index.ts"],"names":[],"mappings":"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","file":"chunk-WFAWAHJH.js","sourcesContent":["/**\r\n * @flight-framework/core - Islands Architecture\r\n * \r\n * Selective hydration with fine-grained control over when and how\r\n * components become interactive. Framework-agnostic islands primitives.\r\n * \r\n * Best Practices 2026:\r\n * - Minimal JavaScript: Only hydrate what needs interactivity\r\n * - Lazy hydration: Load JS when actually needed\r\n * - Progressive enhancement: Works without JS\r\n * - Performance: Reduce main thread work\r\n * \r\n * @example\r\n * ```typescript\r\n * import { defineIsland, renderIsland, hydrateIslands } from '@flight-framework/core/islands';\r\n * \r\n * // Server: Define an interactive island\r\n * const Counter = defineIsland({\r\n * id: 'counter',\r\n * component: CounterComponent,\r\n * hydrate: 'visible', // Only hydrate when scrolled into view\r\n * });\r\n * \r\n * // Server: Render to HTML with island markers\r\n * const html = await renderIsland(Counter, { initial: 0 });\r\n * \r\n * // Client: Hydrate all islands on the page\r\n * hydrateIslands();\r\n * ```\r\n */\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * When to hydrate the island\r\n */\r\nexport type HydrationTrigger =\r\n | 'load' // Immediate: hydrate as soon as JS loads\r\n | 'idle' // When browser is idle (requestIdleCallback)\r\n | 'visible' // When island enters viewport (IntersectionObserver)\r\n | 'interaction' // On first user interaction (click, focus, hover)\r\n | 'media' // When media query matches\r\n | 'never' // Never hydrate (static HTML only)\r\n | CustomHydrationTrigger;\r\n\r\n/**\r\n * Custom hydration trigger function\r\n */\r\nexport interface CustomHydrationTrigger {\r\n type: 'custom';\r\n /** Name for debugging */\r\n name: string;\r\n /** Function that returns a promise resolving when hydration should occur */\r\n when: (element: HTMLElement) => Promise<void>;\r\n}\r\n\r\n/**\r\n * Island configuration\r\n */\r\nexport interface IslandConfig<P = Record<string, unknown>> {\r\n /** Unique identifier for this island type */\r\n id: string;\r\n /** The component to render (framework-specific) */\r\n component: unknown;\r\n /** When to hydrate on client */\r\n hydrate: HydrationTrigger;\r\n /** Default props */\r\n defaultProps?: P;\r\n /** Media query for 'media' trigger */\r\n mediaQuery?: string;\r\n /** Path to client-side component bundle */\r\n clientEntry?: string;\r\n /** Fallback HTML while not hydrated (optional override) */\r\n fallback?: string;\r\n /** Loading priority hint */\r\n priority?: 'high' | 'low';\r\n}\r\n\r\n/**\r\n * Island instance with props\r\n */\r\nexport interface Island<P = Record<string, unknown>> {\r\n /** Island configuration */\r\n config: IslandConfig<P>;\r\n /** Instance props */\r\n props: P;\r\n /** Unique instance ID (for multiple instances of same island type) */\r\n instanceId: string;\r\n}\r\n\r\n/**\r\n * Rendered island HTML with metadata\r\n */\r\nexport interface RenderedIsland {\r\n /** The HTML string */\r\n html: string;\r\n /** Island ID */\r\n id: string;\r\n /** Instance ID */\r\n instanceId: string;\r\n /** Serialized props for hydration */\r\n propsScript: string;\r\n /** CSS if any */\r\n css?: string;\r\n}\r\n\r\n/**\r\n * Island registry for client-side hydration\r\n */\r\nexport interface IslandRegistry {\r\n /** Register a component for an island ID */\r\n register(id: string, loader: () => Promise<unknown>): void;\r\n /** Get registered loader */\r\n get(id: string): (() => Promise<unknown>) | undefined;\r\n /** Check if island is registered */\r\n has(id: string): boolean;\r\n}\r\n\r\n/**\r\n * Client-side hydration options\r\n */\r\nexport interface HydrateOptions {\r\n /** Root element to scan for islands */\r\n root?: HTMLElement;\r\n /** Custom island registry */\r\n registry?: IslandRegistry;\r\n /** Callback when an island is hydrated */\r\n onHydrate?: (id: string, instanceId: string, duration: number) => void;\r\n /** Callback on hydration error */\r\n onError?: (id: string, error: Error) => void;\r\n}\r\n\r\n// ============================================================================\r\n// Server-Side: Island Definition\r\n// ============================================================================\r\n\r\nlet instanceCounter = 0;\r\n\r\n/**\r\n * Generate a unique instance ID\r\n */\r\nfunction generateInstanceId(islandId: string): string {\r\n return `${islandId}:${++instanceCounter}:${Math.random().toString(36).slice(2, 7)}`;\r\n}\r\n\r\n/**\r\n * Define an island component\r\n */\r\nexport function defineIsland<P = Record<string, unknown>>(\r\n config: IslandConfig<P>\r\n): (props?: P) => Island<P> {\r\n return (props?: P) => ({\r\n config,\r\n props: { ...config.defaultProps, ...props } as P,\r\n instanceId: generateInstanceId(config.id),\r\n });\r\n}\r\n\r\n/**\r\n * Serialize props for client-side hydration\r\n */\r\nfunction serializeProps(props: Record<string, unknown>): string {\r\n try {\r\n return JSON.stringify(props);\r\n } catch {\r\n console.warn('[Flight Islands] Props are not serializable, using empty object');\r\n return '{}';\r\n }\r\n}\r\n\r\n/**\r\n * Get hydration trigger attribute value\r\n */\r\nfunction getHydrateAttr(trigger: HydrationTrigger): string {\r\n if (typeof trigger === 'object' && trigger.type === 'custom') {\r\n return `custom:${trigger.name}`;\r\n }\r\n return trigger as string;\r\n}\r\n\r\n// ============================================================================\r\n// Server-Side: Island Rendering\r\n// ============================================================================\r\n\r\n/**\r\n * UI framework adapter for island rendering\r\n */\r\nexport interface IslandRenderAdapter {\r\n /** Framework name */\r\n name: string;\r\n /** Render component to HTML */\r\n renderToString(component: unknown, props: Record<string, unknown>): Promise<string>;\r\n /** Get CSS if any */\r\n getCSS?(component: unknown): string;\r\n}\r\n\r\nlet globalAdapter: IslandRenderAdapter | null = null;\r\n\r\n/**\r\n * Set the global island render adapter\r\n */\r\nexport function setIslandAdapter(adapter: IslandRenderAdapter): void {\r\n globalAdapter = adapter;\r\n}\r\n\r\n/**\r\n * Render an island to HTML with hydration markers\r\n */\r\nexport async function renderIsland<P extends Record<string, unknown>>(\r\n island: Island<P>,\r\n adapter?: IslandRenderAdapter\r\n): Promise<RenderedIsland> {\r\n const renderAdapter = adapter || globalAdapter;\r\n\r\n if (!renderAdapter) {\r\n throw new Error(\r\n '[Flight Islands] No render adapter set. Call setIslandAdapter() or pass adapter to renderIsland().'\r\n );\r\n }\r\n\r\n const { config, props, instanceId } = island;\r\n\r\n // Render component to HTML\r\n const componentHtml = await renderAdapter.renderToString(config.component, props);\r\n const css = renderAdapter.getCSS?.(config.component);\r\n\r\n // Build island wrapper with data attributes\r\n const hydrateAttr = getHydrateAttr(config.hydrate);\r\n const propsJson = serializeProps(props);\r\n\r\n const html = `\r\n<flight-island \r\n data-island=\"${config.id}\"\r\n data-instance=\"${instanceId}\"\r\n data-hydrate=\"${hydrateAttr}\"\r\n ${config.mediaQuery ? `data-media=\"${config.mediaQuery}\"` : ''}\r\n ${config.clientEntry ? `data-entry=\"${config.clientEntry}\"` : ''}\r\n ${config.priority ? `data-priority=\"${config.priority}\"` : ''}\r\n>\r\n ${componentHtml}\r\n</flight-island>`;\r\n\r\n // Props script (inline for hydration)\r\n const propsScript = `<script type=\"application/json\" data-island-props=\"${instanceId}\">${propsJson}</script>`;\r\n\r\n return {\r\n html,\r\n id: config.id,\r\n instanceId,\r\n propsScript,\r\n css,\r\n };\r\n}\r\n\r\n/**\r\n * Render multiple islands and collect their outputs\r\n */\r\nexport async function renderIslands<P extends Record<string, unknown>>(\r\n islands: Island<P>[],\r\n adapter?: IslandRenderAdapter\r\n): Promise<{\r\n html: string;\r\n propsScripts: string;\r\n css: string;\r\n}> {\r\n const rendered = await Promise.all(\r\n islands.map(island => renderIsland(island, adapter))\r\n );\r\n\r\n return {\r\n html: rendered.map(r => r.html).join('\\n'),\r\n propsScripts: rendered.map(r => r.propsScript).join('\\n'),\r\n css: rendered.filter(r => r.css).map(r => r.css).join('\\n'),\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Client-Side: Island Hydration\r\n// ============================================================================\r\n\r\n/**\r\n * Create an island registry for client-side hydration\r\n */\r\nexport function createIslandRegistry(): IslandRegistry {\r\n const loaders = new Map<string, () => Promise<unknown>>();\r\n\r\n return {\r\n register(id: string, loader: () => Promise<unknown>) {\r\n loaders.set(id, loader);\r\n },\r\n get(id: string) {\r\n return loaders.get(id);\r\n },\r\n has(id: string) {\r\n return loaders.has(id);\r\n },\r\n };\r\n}\r\n\r\n// Global registry for convenience\r\nconst globalRegistry = createIslandRegistry();\r\n\r\n/**\r\n * Register an island component for client-side hydration\r\n */\r\nexport function registerIsland(id: string, loader: () => Promise<unknown>): void {\r\n globalRegistry.register(id, loader);\r\n}\r\n\r\n/**\r\n * Client-side hydration bootstrapper\r\n * Call this in your client entry point\r\n */\r\nexport function hydrateIslands(options?: HydrateOptions): void {\r\n const {\r\n root = typeof document !== 'undefined' ? document.body : null,\r\n registry = globalRegistry,\r\n onHydrate,\r\n onError,\r\n } = options || {};\r\n\r\n if (!root || typeof document === 'undefined') {\r\n console.warn('[Flight Islands] hydrateIslands called in non-browser environment');\r\n return;\r\n }\r\n\r\n // Find all island elements\r\n const islands = root.querySelectorAll<HTMLElement>('flight-island[data-island]');\r\n\r\n islands.forEach((element) => {\r\n const islandId = element.dataset.island!;\r\n const instanceId = element.dataset.instance!;\r\n const hydrateTrigger = element.dataset.hydrate as string;\r\n const mediaQuery = element.dataset.media;\r\n\r\n // Check if component is registered\r\n if (!registry.has(islandId)) {\r\n console.warn(`[Flight Islands] No component registered for island: ${islandId}`);\r\n return;\r\n }\r\n\r\n // Setup hydration based on trigger\r\n setupHydration(\r\n element,\r\n islandId,\r\n instanceId,\r\n hydrateTrigger,\r\n mediaQuery,\r\n registry,\r\n onHydrate,\r\n onError\r\n );\r\n });\r\n}\r\n\r\n/**\r\n * Setup hydration trigger for an island element\r\n */\r\nfunction setupHydration(\r\n element: HTMLElement,\r\n islandId: string,\r\n instanceId: string,\r\n trigger: string,\r\n mediaQuery: string | undefined,\r\n registry: IslandRegistry,\r\n onHydrate?: (id: string, instanceId: string, duration: number) => void,\r\n onError?: (id: string, error: Error) => void\r\n): void {\r\n const hydrate = async () => {\r\n const startTime = performance.now();\r\n\r\n try {\r\n // Load component\r\n const loader = registry.get(islandId)!;\r\n const module = await loader() as { default?: unknown };\r\n const Component = module.default || module;\r\n\r\n // Get props\r\n const propsScript = document.querySelector(`[data-island-props=\"${instanceId}\"]`);\r\n const props = propsScript ? JSON.parse(propsScript.textContent || '{}') : {};\r\n\r\n // Hydrate (framework-specific, emit event for now)\r\n element.dispatchEvent(new CustomEvent('flight:hydrate', {\r\n detail: { Component, props, islandId, instanceId },\r\n bubbles: true,\r\n }));\r\n\r\n // Mark as hydrated\r\n element.setAttribute('data-hydrated', 'true');\r\n\r\n const duration = performance.now() - startTime;\r\n onHydrate?.(islandId, instanceId, duration);\r\n\r\n } catch (error) {\r\n console.error(`[Flight Islands] Failed to hydrate ${islandId}:`, error);\r\n element.setAttribute('data-hydrate-error', 'true');\r\n onError?.(islandId, error as Error);\r\n }\r\n };\r\n\r\n // Skip if already hydrated\r\n if (element.hasAttribute('data-hydrated')) return;\r\n\r\n switch (trigger) {\r\n case 'load':\r\n // Immediate hydration\r\n hydrate();\r\n break;\r\n\r\n case 'idle':\r\n // When browser is idle\r\n if ('requestIdleCallback' in window) {\r\n (window as unknown as { requestIdleCallback: (cb: () => void, opts?: { timeout: number }) => void })\r\n .requestIdleCallback(() => hydrate(), { timeout: 2000 });\r\n } else {\r\n setTimeout(hydrate, 200);\r\n }\r\n break;\r\n\r\n case 'visible': {\r\n // When element enters viewport\r\n const observer = new IntersectionObserver(\r\n (entries) => {\r\n entries.forEach((entry) => {\r\n if (entry.isIntersecting) {\r\n observer.disconnect();\r\n hydrate();\r\n }\r\n });\r\n },\r\n { rootMargin: '50px' }\r\n );\r\n observer.observe(element);\r\n break;\r\n }\r\n\r\n case 'interaction': {\r\n // On first user interaction\r\n const events = ['click', 'focus', 'touchstart', 'mouseenter'];\r\n const onInteraction = () => {\r\n events.forEach(e => element.removeEventListener(e, onInteraction));\r\n hydrate();\r\n };\r\n events.forEach(e => element.addEventListener(e, onInteraction, { once: true, passive: true }));\r\n break;\r\n }\r\n\r\n case 'media':\r\n // When media query matches\r\n if (mediaQuery) {\r\n const mql = window.matchMedia(mediaQuery);\r\n const check = () => {\r\n if (mql.matches) {\r\n mql.removeEventListener('change', check);\r\n hydrate();\r\n }\r\n };\r\n if (mql.matches) {\r\n hydrate();\r\n } else {\r\n mql.addEventListener('change', check);\r\n }\r\n }\r\n break;\r\n\r\n case 'never':\r\n // Never hydrate\r\n break;\r\n\r\n default:\r\n // Custom trigger\r\n if (trigger.startsWith('custom:')) {\r\n // Custom triggers need manual setup\r\n element.dispatchEvent(new CustomEvent('flight:custom-hydrate', {\r\n detail: { hydrate, trigger: trigger.replace('custom:', '') },\r\n bubbles: true,\r\n }));\r\n }\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Utility: Framework-Specific Adapter Factories\r\n// These return adapters that users configure with their own framework imports\r\n// ============================================================================\r\n\r\n/**\r\n * Create a React island render adapter\r\n * \r\n * @example\r\n * ```typescript\r\n * import { renderToString } from 'react-dom/server';\r\n * import { createElement } from 'react';\r\n * \r\n * const reactAdapter = createReactIslandAdapter({\r\n * renderToString,\r\n * createElement,\r\n * });\r\n * ```\r\n */\r\nexport function createReactIslandAdapter(deps: {\r\n renderToString: (element: unknown) => string;\r\n createElement: (type: unknown, props?: unknown) => unknown;\r\n}): IslandRenderAdapter {\r\n return {\r\n name: 'react',\r\n async renderToString(component, props) {\r\n const element = deps.createElement(component, props);\r\n return deps.renderToString(element);\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Create a Preact island render adapter\r\n * \r\n * @example\r\n * ```typescript\r\n * import { renderToString } from 'preact-render-to-string';\r\n * import { h } from 'preact';\r\n * \r\n * const preactAdapter = createPreactIslandAdapter({\r\n * renderToString,\r\n * h,\r\n * });\r\n * ```\r\n */\r\nexport function createPreactIslandAdapter(deps: {\r\n renderToString: (element: unknown) => string;\r\n h: (type: unknown, props?: unknown) => unknown;\r\n}): IslandRenderAdapter {\r\n return {\r\n name: 'preact',\r\n async renderToString(component, props) {\r\n const element = deps.h(component, props);\r\n return deps.renderToString(element);\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Create a Vue island render adapter\r\n * \r\n * @example\r\n * ```typescript\r\n * import { renderToString, createSSRApp } from 'vue/server-renderer';\r\n * \r\n * const vueAdapter = createVueIslandAdapter({\r\n * renderToString,\r\n * createSSRApp,\r\n * });\r\n * ```\r\n */\r\nexport function createVueIslandAdapter(deps: {\r\n renderToString: (app: unknown) => Promise<string>;\r\n createSSRApp: (component: unknown, props?: unknown) => unknown;\r\n}): IslandRenderAdapter {\r\n return {\r\n name: 'vue',\r\n async renderToString(component, props) {\r\n const app = deps.createSSRApp(component, props);\r\n return deps.renderToString(app);\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Create a Solid island render adapter\r\n * \r\n * @example\r\n * ```typescript\r\n * import { renderToString } from 'solid-js/web';\r\n * \r\n * const solidAdapter = createSolidIslandAdapter({\r\n * renderToString,\r\n * });\r\n * ```\r\n */\r\nexport function createSolidIslandAdapter(deps: {\r\n renderToString: (fn: () => unknown) => string;\r\n}): IslandRenderAdapter {\r\n return {\r\n name: 'solid',\r\n async renderToString(component, props) {\r\n // Solid uses a function component pattern\r\n return deps.renderToString(() => (component as (p: unknown) => unknown)(props));\r\n },\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Custom Element Registration (optional)\r\n// ============================================================================\r\n\r\n/**\r\n * Register the flight-island custom element\r\n * This provides additional functionality like slot support\r\n */\r\nexport function registerFlightIslandElement(): void {\r\n if (typeof customElements === 'undefined') return;\r\n if (customElements.get('flight-island')) return;\r\n\r\n class FlightIsland extends HTMLElement {\r\n static get observedAttributes() {\r\n return ['data-hydrated', 'data-hydrate-error'];\r\n }\r\n\r\n connectedCallback() {\r\n // Could add loading indicator logic here\r\n }\r\n\r\n attributeChangedCallback(name: string, _oldValue: string, newValue: string) {\r\n if (name === 'data-hydrated' && newValue === 'true') {\r\n this.classList.add('hydrated');\r\n }\r\n if (name === 'data-hydrate-error' && newValue === 'true') {\r\n this.classList.add('hydrate-error');\r\n }\r\n }\r\n }\r\n\r\n customElements.define('flight-island', FlightIsland);\r\n}\r\n"]}
|
|
@@ -347,5 +347,5 @@ function validateDependencies(boundaries) {
|
|
|
347
347
|
}
|
|
348
348
|
|
|
349
349
|
export { streamWithPriority, validateDependencies };
|
|
350
|
-
//# sourceMappingURL=chunk-
|
|
351
|
-
//# sourceMappingURL=chunk-
|
|
350
|
+
//# sourceMappingURL=chunk-WOEIJWGJ.js.map
|
|
351
|
+
//# sourceMappingURL=chunk-WOEIJWGJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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"]}
|
|
@@ -160,5 +160,5 @@ function createStaticResponse(html, options) {
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
export { DEFAULT_BOT_PATTERNS, addStreamingHeaders, createConditionalStreamer, createStaticResponse, createStreamingResponse, isBot, isSlowConnection, prefersNoStream, streamIf, supportsStreaming };
|
|
163
|
-
//# sourceMappingURL=chunk-
|
|
164
|
-
//# sourceMappingURL=chunk-
|
|
163
|
+
//# sourceMappingURL=chunk-XOIYNY4I.js.map
|
|
164
|
+
//# sourceMappingURL=chunk-XOIYNY4I.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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"]}
|
|
@@ -121,5 +121,5 @@ function isValidStreamingHints(obj) {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
export { DEFAULT_STREAMING_HINTS, createStreamingController, generateCacheKey, getStreamingCacheHeaders, hasStreamingConfig, isValidStreamingHints, loadRouteWithStreaming, resolveStreamingConfig, shouldStream };
|
|
124
|
-
//# sourceMappingURL=chunk-
|
|
125
|
-
//# sourceMappingURL=chunk-
|
|
124
|
+
//# sourceMappingURL=chunk-XSY5AAXT.js.map
|
|
125
|
+
//# sourceMappingURL=chunk-XSY5AAXT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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"]}
|
|
@@ -42,5 +42,5 @@ function getEnvironment() {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
export { getEnvironment, isBrowser, isDevelopment, isProduction, isServer, isTest };
|
|
45
|
-
//# sourceMappingURL=chunk-
|
|
46
|
-
//# sourceMappingURL=chunk-
|
|
45
|
+
//# sourceMappingURL=chunk-YHEVHRLH.js.map
|
|
46
|
+
//# sourceMappingURL=chunk-YHEVHRLH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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,4 +1,4 @@
|
|
|
1
|
-
import { analyzeModule, hasUseClientDirective, hasUseServerDirective, detectInlineServerActions } from './chunk-
|
|
1
|
+
import { analyzeModule, hasUseClientDirective, hasUseServerDirective, detectInlineServerActions } from './chunk-PDW5WCMW.js';
|
|
2
2
|
|
|
3
3
|
// src/rsc/vite-plugin.ts
|
|
4
4
|
function flightRSC(options = {}) {
|
|
@@ -337,5 +337,5 @@ function extractExportNames(code) {
|
|
|
337
337
|
var vite_plugin_default = flightRSC;
|
|
338
338
|
|
|
339
339
|
export { flightRSC, vite_plugin_default };
|
|
340
|
-
//# sourceMappingURL=chunk-
|
|
341
|
-
//# sourceMappingURL=chunk-
|
|
340
|
+
//# sourceMappingURL=chunk-ZIE56LCA.js.map
|
|
341
|
+
//# sourceMappingURL=chunk-ZIE56LCA.js.map
|