@flight-framework/core 0.1.0 → 0.2.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 -0
- package/dist/{chunk-5KF3QQWZ.js → chunk-3AY23FZP.js} +5 -19
- package/dist/chunk-3AY23FZP.js.map +1 -0
- package/dist/chunk-4F77J5TY.js +324 -0
- package/dist/chunk-4F77J5TY.js.map +1 -0
- package/dist/chunk-5GUCB2CG.js +300 -0
- package/dist/chunk-5GUCB2CG.js.map +1 -0
- package/dist/chunk-62C7LX2E.js +205 -0
- package/dist/chunk-62C7LX2E.js.map +1 -0
- package/dist/chunk-63SCEXD7.js +3 -0
- package/dist/chunk-63SCEXD7.js.map +1 -0
- package/dist/{chunk-YIOQC3DC.js → chunk-6BDCTUQY.js} +3 -3
- package/dist/{chunk-YIOQC3DC.js.map → chunk-6BDCTUQY.js.map} +1 -1
- package/dist/chunk-6CD5FIYI.js +252 -0
- package/dist/chunk-6CD5FIYI.js.map +1 -0
- package/dist/chunk-6XZQPPYC.js +285 -0
- package/dist/chunk-6XZQPPYC.js.map +1 -0
- package/dist/chunk-BJIMTO2I.js +213 -0
- package/dist/chunk-BJIMTO2I.js.map +1 -0
- package/dist/chunk-CLZSB5QD.js +258 -0
- package/dist/chunk-CLZSB5QD.js.map +1 -0
- package/dist/chunk-K2CQZPCG.js +257 -0
- package/dist/chunk-K2CQZPCG.js.map +1 -0
- package/dist/chunk-MRLCNFSD.js +341 -0
- package/dist/chunk-MRLCNFSD.js.map +1 -0
- package/dist/chunk-PSJPMEQK.js +212 -0
- package/dist/chunk-PSJPMEQK.js.map +1 -0
- package/dist/chunk-Q62ZQ6FM.js +218 -0
- package/dist/chunk-Q62ZQ6FM.js.map +1 -0
- package/dist/{chunk-6WSPUG5L.js → chunk-RSVA2EYO.js} +2 -2
- package/dist/chunk-RSVA2EYO.js.map +1 -0
- package/dist/chunk-T3S5YC7L.js +256 -0
- package/dist/chunk-T3S5YC7L.js.map +1 -0
- package/dist/{chunk-OBNYNJB5.js → chunk-WOEIJWGJ.js} +6 -8
- package/dist/chunk-WOEIJWGJ.js.map +1 -0
- package/dist/{chunk-I2B4WSHC.js → chunk-XSY5AAXT.js} +3 -4
- package/dist/chunk-XSY5AAXT.js.map +1 -0
- package/dist/chunk-Y22AMGTM.js +3 -0
- package/dist/chunk-Y22AMGTM.js.map +1 -0
- package/dist/file-router/streaming-hints.d.ts +1 -1
- package/dist/file-router/streaming-hints.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/dist/rsc/adapters/index.d.ts +8 -0
- package/dist/rsc/adapters/index.js +7 -0
- package/dist/rsc/adapters/index.js.map +1 -0
- package/dist/rsc/adapters/preact.d.ts +97 -0
- package/dist/rsc/adapters/preact.js +3 -0
- package/dist/rsc/adapters/preact.js.map +1 -0
- package/dist/rsc/adapters/react.d.ts +82 -0
- package/dist/rsc/adapters/react.js +3 -0
- package/dist/rsc/adapters/react.js.map +1 -0
- package/dist/rsc/adapters/solid.d.ts +84 -0
- package/dist/rsc/adapters/solid.js +3 -0
- package/dist/rsc/adapters/solid.js.map +1 -0
- package/dist/rsc/adapters/vue.d.ts +80 -0
- package/dist/rsc/adapters/vue.js +3 -0
- package/dist/rsc/adapters/vue.js.map +1 -0
- package/dist/rsc/boundaries.d.ts +182 -0
- package/dist/rsc/boundaries.js +3 -0
- package/dist/rsc/boundaries.js.map +1 -0
- package/dist/rsc/context.d.ts +201 -0
- package/dist/rsc/context.js +3 -0
- package/dist/rsc/context.js.map +1 -0
- package/dist/rsc/index.d.ts +20 -124
- package/dist/rsc/index.js +13 -1
- package/dist/rsc/legacy.d.ts +131 -0
- package/dist/rsc/legacy.js +3 -0
- package/dist/rsc/legacy.js.map +1 -0
- package/dist/rsc/payload.d.ts +262 -0
- package/dist/rsc/payload.js +3 -0
- package/dist/rsc/payload.js.map +1 -0
- package/dist/rsc/plugins/esbuild.d.ts +124 -0
- package/dist/rsc/plugins/esbuild.js +4 -0
- package/dist/rsc/plugins/esbuild.js.map +1 -0
- package/dist/rsc/plugins/index.d.ts +4 -0
- package/dist/rsc/plugins/index.js +6 -0
- package/dist/rsc/plugins/index.js.map +1 -0
- package/dist/rsc/plugins/rollup.d.ts +103 -0
- package/dist/rsc/plugins/rollup.js +4 -0
- package/dist/rsc/plugins/rollup.js.map +1 -0
- package/dist/rsc/renderer.d.ts +160 -0
- package/dist/rsc/renderer.js +5 -0
- package/dist/rsc/renderer.js.map +1 -0
- package/dist/rsc/stream.d.ts +129 -0
- package/dist/rsc/stream.js +3 -0
- package/dist/rsc/stream.js.map +1 -0
- package/dist/rsc/vite-plugin.d.ts +78 -0
- package/dist/rsc/vite-plugin.js +4 -0
- package/dist/rsc/vite-plugin.js.map +1 -0
- package/dist/streaming/index.js +1 -1
- package/dist/streaming/observability.js +2 -2
- package/dist/streaming/priority.js +1 -1
- package/package.json +180 -124
- package/dist/chunk-5KF3QQWZ.js.map +0 -1
- package/dist/chunk-6WSPUG5L.js.map +0 -1
- package/dist/chunk-I2B4WSHC.js.map +0 -1
- package/dist/chunk-OBNYNJB5.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/streaming/observability.ts"],"names":[],"mappings":"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","file":"chunk-YIOQC3DC.js","sourcesContent":["/**\r\n * @flight-framework/core - Streaming Observability\r\n * \r\n * Zero-telemetry metrics and instrumentation for streaming SSR.\r\n * All data stays on YOUR infrastructure - never sent anywhere.\r\n * \r\n * Best Practices 2026:\r\n * - Comprehensive timing metrics for each boundary\r\n * - Hook-based observability for custom integrations\r\n * - Performance insights without vendor lock-in\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createInstrumentedStream } from '@flight-framework/core/streaming';\r\n * \r\n * const { stream, metrics } = await createInstrumentedStream({\r\n * shell: '<html>...',\r\n * boundaries: [...],\r\n * onMetrics: (m) => myAnalytics.track(m), // YOUR system\r\n * });\r\n * ```\r\n */\r\n\r\nimport type { StreamingRenderOptions, SuspenseBoundaryConfig } from './index.js';\r\nimport { createStreamingSSR } from './index.js';\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Timing information for a single boundary\r\n */\r\nexport interface BoundaryTiming {\r\n /** Boundary identifier */\r\n id: string;\r\n /** When the boundary started resolving (ms since stream start) */\r\n startTime: number;\r\n /** When the boundary finished resolving */\r\n endTime: number;\r\n /** Total duration in milliseconds */\r\n duration: number;\r\n /** Whether it resolved successfully */\r\n success: boolean;\r\n /** Size of content in bytes (if successful) */\r\n contentSize?: number;\r\n /** Error message if failed */\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Overall streaming metrics\r\n */\r\nexport interface StreamingMetrics {\r\n /** Unique ID for this stream session */\r\n streamId: string;\r\n /** When streaming started */\r\n startTime: number;\r\n /** Time to shell ready (TTFB improvement) */\r\n shellTime: number;\r\n /** Time until all boundaries resolved */\r\n totalStreamTime: number;\r\n /** Individual boundary timings */\r\n boundaries: BoundaryTiming[];\r\n /** Number of boundaries that resolved successfully */\r\n successCount: number;\r\n /** Number of boundaries that failed */\r\n errorCount: number;\r\n /** Total bytes streamed */\r\n totalBytes: number;\r\n /** Strategy used (if priority streaming) */\r\n strategy?: string;\r\n /** Custom metadata you can add */\r\n meta?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Observability hooks for streaming events\r\n */\r\nexport interface StreamingObserver {\r\n /** Called when streaming starts */\r\n onStreamStart?: (streamId: string) => void;\r\n /** Called when shell is sent */\r\n onShellReady?: (timing: { streamId: string; duration: number }) => void;\r\n /** Called when a boundary starts resolving */\r\n onBoundaryStart?: (info: { streamId: string; boundaryId: string; startTime: number }) => void;\r\n /** Called when a boundary finishes */\r\n onBoundaryEnd?: (timing: BoundaryTiming & { streamId: string }) => void;\r\n /** Called when streaming completes */\r\n onStreamEnd?: (metrics: StreamingMetrics) => void;\r\n /** Called on any error */\r\n onError?: (error: { streamId: string; boundaryId?: string; error: Error }) => void;\r\n}\r\n\r\n/**\r\n * Configuration for instrumented streaming\r\n */\r\nexport interface InstrumentedStreamConfig {\r\n /** Initial HTML shell */\r\n shell: string;\r\n /** Closing HTML */\r\n shellEnd: string;\r\n /** Suspense boundaries */\r\n suspenseBoundaries: SuspenseBoundaryConfig[];\r\n /** Streaming options */\r\n options?: StreamingRenderOptions;\r\n /** Observer hooks */\r\n observer?: StreamingObserver;\r\n /** Callback when all metrics are ready */\r\n onMetrics?: (metrics: StreamingMetrics) => void;\r\n /** Custom metadata to include in metrics */\r\n meta?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Result of instrumented streaming\r\n */\r\nexport interface InstrumentedStreamResult {\r\n /** The readable stream */\r\n stream: ReadableStream<Uint8Array>;\r\n /** Abort the stream */\r\n abort: () => void;\r\n /** Shell ready promise */\r\n shellReady: Promise<void>;\r\n /** All content ready promise */\r\n allReady: Promise<void>;\r\n /** Final metrics (resolves when stream completes) */\r\n metrics: Promise<StreamingMetrics>;\r\n /** Stream ID for correlation */\r\n streamId: string;\r\n}\r\n\r\n// ============================================================================\r\n// Implementation\r\n// ============================================================================\r\n\r\n/**\r\n * Generate a unique stream ID\r\n */\r\nfunction generateStreamId(): string {\r\n return `stream_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\r\n}\r\n\r\n/**\r\n * Create an instrumented streaming SSR response with full observability\r\n */\r\nexport async function createInstrumentedStream(\r\n config: InstrumentedStreamConfig\r\n): Promise<InstrumentedStreamResult> {\r\n const {\r\n shell,\r\n shellEnd,\r\n suspenseBoundaries,\r\n options = {},\r\n observer,\r\n onMetrics,\r\n meta,\r\n } = config;\r\n\r\n const streamId = generateStreamId();\r\n const startTime = Date.now();\r\n const boundaryTimings: BoundaryTiming[] = [];\r\n const boundaryStarts = new Map<string, number>();\r\n let shellTime = 0;\r\n let totalBytes = 0;\r\n\r\n // Metrics promise\r\n let resolveMetrics: (m: StreamingMetrics) => void;\r\n const metricsPromise = new Promise<StreamingMetrics>((r) => { resolveMetrics = r; });\r\n\r\n // Notify stream start\r\n observer?.onStreamStart?.(streamId);\r\n\r\n // Wrap boundaries with instrumentation\r\n const instrumentedBoundaries: SuspenseBoundaryConfig[] = suspenseBoundaries.map(boundary => {\r\n const boundaryStart = Date.now();\r\n boundaryStarts.set(boundary.id, boundaryStart);\r\n\r\n observer?.onBoundaryStart?.({\r\n streamId,\r\n boundaryId: boundary.id,\r\n startTime: boundaryStart - startTime,\r\n });\r\n\r\n return {\r\n ...boundary,\r\n contentPromise: boundary.contentPromise.then(\r\n (content) => {\r\n const endTime = Date.now();\r\n const timing: BoundaryTiming = {\r\n id: boundary.id,\r\n startTime: boundaryStarts.get(boundary.id)! - startTime,\r\n endTime: endTime - startTime,\r\n duration: endTime - boundaryStarts.get(boundary.id)!,\r\n success: true,\r\n contentSize: new TextEncoder().encode(content).length,\r\n };\r\n boundaryTimings.push(timing);\r\n observer?.onBoundaryEnd?.({ ...timing, streamId });\r\n return content;\r\n },\r\n (error) => {\r\n const endTime = Date.now();\r\n const timing: BoundaryTiming = {\r\n id: boundary.id,\r\n startTime: boundaryStarts.get(boundary.id)! - startTime,\r\n endTime: endTime - startTime,\r\n duration: endTime - boundaryStarts.get(boundary.id)!,\r\n success: false,\r\n error: error instanceof Error ? error.message : String(error),\r\n };\r\n boundaryTimings.push(timing);\r\n observer?.onBoundaryEnd?.({ ...timing, streamId });\r\n observer?.onError?.({ streamId, boundaryId: boundary.id, error: error as Error });\r\n throw error;\r\n }\r\n ),\r\n };\r\n });\r\n\r\n // Create the underlying stream with instrumented callbacks\r\n const result = await createStreamingSSR({\r\n shell,\r\n shellEnd,\r\n suspenseBoundaries: instrumentedBoundaries,\r\n options: {\r\n ...options,\r\n onShellReady: () => {\r\n shellTime = Date.now() - startTime;\r\n observer?.onShellReady?.({ streamId, duration: shellTime });\r\n options.onShellReady?.();\r\n },\r\n onAllReady: () => {\r\n const totalStreamTime = Date.now() - startTime;\r\n\r\n const metrics: StreamingMetrics = {\r\n streamId,\r\n startTime,\r\n shellTime,\r\n totalStreamTime,\r\n boundaries: boundaryTimings,\r\n successCount: boundaryTimings.filter(b => b.success).length,\r\n errorCount: boundaryTimings.filter(b => !b.success).length,\r\n totalBytes,\r\n meta,\r\n };\r\n\r\n observer?.onStreamEnd?.(metrics);\r\n onMetrics?.(metrics);\r\n resolveMetrics!(metrics);\r\n options.onAllReady?.();\r\n },\r\n onError: (error) => {\r\n observer?.onError?.({ streamId, error });\r\n options.onError?.(error);\r\n },\r\n },\r\n });\r\n\r\n // Wrap stream to count bytes\r\n const countingStream = result.stream.pipeThrough(\r\n new TransformStream<Uint8Array, Uint8Array>({\r\n transform(chunk, controller) {\r\n totalBytes += chunk.length;\r\n controller.enqueue(chunk);\r\n },\r\n })\r\n );\r\n\r\n return {\r\n stream: countingStream,\r\n abort: result.abort,\r\n shellReady: result.shellReady,\r\n allReady: result.allReady,\r\n metrics: metricsPromise,\r\n streamId,\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Utility: Metrics Aggregator\r\n// ============================================================================\r\n\r\n/**\r\n * Aggregate metrics from multiple streams for analysis\r\n */\r\nexport class MetricsAggregator {\r\n private metrics: StreamingMetrics[] = [];\r\n private maxSamples: number;\r\n\r\n constructor(maxSamples = 1000) {\r\n this.maxSamples = maxSamples;\r\n }\r\n\r\n /**\r\n * Add metrics from a stream\r\n */\r\n add(metrics: StreamingMetrics): void {\r\n this.metrics.push(metrics);\r\n if (this.metrics.length > this.maxSamples) {\r\n this.metrics.shift();\r\n }\r\n }\r\n\r\n /**\r\n * Get average shell time\r\n */\r\n getAverageShellTime(): number {\r\n if (this.metrics.length === 0) return 0;\r\n return this.metrics.reduce((sum, m) => sum + m.shellTime, 0) / this.metrics.length;\r\n }\r\n\r\n /**\r\n * Get average total stream time\r\n */\r\n getAverageTotalTime(): number {\r\n if (this.metrics.length === 0) return 0;\r\n return this.metrics.reduce((sum, m) => sum + m.totalStreamTime, 0) / this.metrics.length;\r\n }\r\n\r\n /**\r\n * Get slowest boundaries (by average duration)\r\n */\r\n getSlowestBoundaries(limit = 5): { id: string; avgDuration: number; errorRate: number }[] {\r\n const boundaryStats = new Map<string, { totalDuration: number; count: number; errors: number }>();\r\n\r\n for (const m of this.metrics) {\r\n for (const b of m.boundaries) {\r\n const stats = boundaryStats.get(b.id) || { totalDuration: 0, count: 0, errors: 0 };\r\n stats.totalDuration += b.duration;\r\n stats.count++;\r\n if (!b.success) stats.errors++;\r\n boundaryStats.set(b.id, stats);\r\n }\r\n }\r\n\r\n return [...boundaryStats.entries()]\r\n .map(([id, stats]) => ({\r\n id,\r\n avgDuration: stats.totalDuration / stats.count,\r\n errorRate: stats.errors / stats.count,\r\n }))\r\n .sort((a, b) => b.avgDuration - a.avgDuration)\r\n .slice(0, limit);\r\n }\r\n\r\n /**\r\n * Get overall error rate\r\n */\r\n getErrorRate(): number {\r\n const total = this.metrics.reduce((sum, m) => sum + m.boundaries.length, 0);\r\n const errors = this.metrics.reduce((sum, m) => sum + m.errorCount, 0);\r\n return total > 0 ? errors / total : 0;\r\n }\r\n\r\n /**\r\n * Get percentiles for shell time\r\n */\r\n getShellTimePercentiles(): { p50: number; p90: number; p99: number } {\r\n const sorted = [...this.metrics].map(m => m.shellTime).sort((a, b) => a - b);\r\n const len = sorted.length;\r\n if (len === 0) return { p50: 0, p90: 0, p99: 0 };\r\n\r\n return {\r\n p50: sorted[Math.floor(len * 0.5)] ?? 0,\r\n p90: sorted[Math.floor(len * 0.9)] ?? 0,\r\n p99: sorted[Math.floor(len * 0.99)] ?? 0,\r\n };\r\n }\r\n\r\n /**\r\n * Export all metrics for external analysis\r\n */\r\n export(): StreamingMetrics[] {\r\n return [...this.metrics];\r\n }\r\n\r\n /**\r\n * Clear all metrics\r\n */\r\n clear(): void {\r\n this.metrics = [];\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Utility: Create Observer from Logger\r\n// ============================================================================\r\n\r\n/**\r\n * Create a streaming observer from a simple logger function\r\n */\r\nexport function createLoggerObserver(\r\n log: (message: string, data?: Record<string, unknown>) => void\r\n): StreamingObserver {\r\n return {\r\n onStreamStart: (streamId) => {\r\n log('[Flight] Stream started', { streamId });\r\n },\r\n onShellReady: ({ streamId, duration }) => {\r\n log('[Flight] Shell ready', { streamId, duration: `${duration}ms` });\r\n },\r\n onBoundaryStart: ({ streamId, boundaryId, startTime }) => {\r\n log('[Flight] Boundary started', { streamId, boundaryId, startTime: `${startTime}ms` });\r\n },\r\n onBoundaryEnd: (timing) => {\r\n log('[Flight] Boundary completed', {\r\n streamId: (timing as any).streamId,\r\n boundaryId: timing.id,\r\n duration: `${timing.duration}ms`,\r\n success: timing.success,\r\n size: timing.contentSize ? `${timing.contentSize}b` : undefined,\r\n });\r\n },\r\n onStreamEnd: (metrics) => {\r\n log('[Flight] Stream completed', {\r\n streamId: metrics.streamId,\r\n totalTime: `${metrics.totalStreamTime}ms`,\r\n shellTime: `${metrics.shellTime}ms`,\r\n boundaries: metrics.boundaries.length,\r\n errors: metrics.errorCount,\r\n });\r\n },\r\n onError: ({ streamId, boundaryId, error }) => {\r\n log('[Flight] Stream error', { streamId, boundaryId, error: error.message });\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Create observer that sends metrics to a custom endpoint (YOUR infrastructure)\r\n */\r\nexport function createHttpObserver(endpoint: string, options?: {\r\n headers?: Record<string, string>;\r\n batchSize?: number;\r\n flushInterval?: number;\r\n}): StreamingObserver {\r\n const { headers = {}, batchSize = 10, flushInterval = 5000 } = options || {};\r\n const buffer: StreamingMetrics[] = [];\r\n let flushTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\n const flush = async () => {\r\n if (buffer.length === 0) return;\r\n const batch = buffer.splice(0, buffer.length);\r\n\r\n try {\r\n await fetch(endpoint, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...headers,\r\n },\r\n body: JSON.stringify({ metrics: batch, timestamp: Date.now() }),\r\n });\r\n } catch (error) {\r\n console.error('[Flight] Failed to send metrics:', error);\r\n // Re-add to buffer for retry\r\n buffer.unshift(...batch);\r\n }\r\n };\r\n\r\n const scheduleFlush = () => {\r\n if (flushTimer) return;\r\n flushTimer = setTimeout(() => {\r\n flushTimer = null;\r\n flush();\r\n }, flushInterval);\r\n };\r\n\r\n return {\r\n onStreamEnd: (metrics) => {\r\n buffer.push(metrics);\r\n if (buffer.length >= batchSize) {\r\n flush();\r\n } else {\r\n scheduleFlush();\r\n }\r\n },\r\n };\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/streaming/observability.ts"],"names":[],"mappings":"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","file":"chunk-6BDCTUQY.js","sourcesContent":["/**\r\n * @flight-framework/core - Streaming Observability\r\n * \r\n * Zero-telemetry metrics and instrumentation for streaming SSR.\r\n * All data stays on YOUR infrastructure - never sent anywhere.\r\n * \r\n * Best Practices 2026:\r\n * - Comprehensive timing metrics for each boundary\r\n * - Hook-based observability for custom integrations\r\n * - Performance insights without vendor lock-in\r\n * \r\n * @example\r\n * ```typescript\r\n * import { createInstrumentedStream } from '@flight-framework/core/streaming';\r\n * \r\n * const { stream, metrics } = await createInstrumentedStream({\r\n * shell: '<html>...',\r\n * boundaries: [...],\r\n * onMetrics: (m) => myAnalytics.track(m), // YOUR system\r\n * });\r\n * ```\r\n */\r\n\r\nimport type { StreamingRenderOptions, SuspenseBoundaryConfig } from './index.js';\r\nimport { createStreamingSSR } from './index.js';\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Timing information for a single boundary\r\n */\r\nexport interface BoundaryTiming {\r\n /** Boundary identifier */\r\n id: string;\r\n /** When the boundary started resolving (ms since stream start) */\r\n startTime: number;\r\n /** When the boundary finished resolving */\r\n endTime: number;\r\n /** Total duration in milliseconds */\r\n duration: number;\r\n /** Whether it resolved successfully */\r\n success: boolean;\r\n /** Size of content in bytes (if successful) */\r\n contentSize?: number;\r\n /** Error message if failed */\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Overall streaming metrics\r\n */\r\nexport interface StreamingMetrics {\r\n /** Unique ID for this stream session */\r\n streamId: string;\r\n /** When streaming started */\r\n startTime: number;\r\n /** Time to shell ready (TTFB improvement) */\r\n shellTime: number;\r\n /** Time until all boundaries resolved */\r\n totalStreamTime: number;\r\n /** Individual boundary timings */\r\n boundaries: BoundaryTiming[];\r\n /** Number of boundaries that resolved successfully */\r\n successCount: number;\r\n /** Number of boundaries that failed */\r\n errorCount: number;\r\n /** Total bytes streamed */\r\n totalBytes: number;\r\n /** Strategy used (if priority streaming) */\r\n strategy?: string;\r\n /** Custom metadata you can add */\r\n meta?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Observability hooks for streaming events\r\n */\r\nexport interface StreamingObserver {\r\n /** Called when streaming starts */\r\n onStreamStart?: (streamId: string) => void;\r\n /** Called when shell is sent */\r\n onShellReady?: (timing: { streamId: string; duration: number }) => void;\r\n /** Called when a boundary starts resolving */\r\n onBoundaryStart?: (info: { streamId: string; boundaryId: string; startTime: number }) => void;\r\n /** Called when a boundary finishes */\r\n onBoundaryEnd?: (timing: BoundaryTiming & { streamId: string }) => void;\r\n /** Called when streaming completes */\r\n onStreamEnd?: (metrics: StreamingMetrics) => void;\r\n /** Called on any error */\r\n onError?: (error: { streamId: string; boundaryId?: string; error: Error }) => void;\r\n}\r\n\r\n/**\r\n * Configuration for instrumented streaming\r\n */\r\nexport interface InstrumentedStreamConfig {\r\n /** Initial HTML shell */\r\n shell: string;\r\n /** Closing HTML */\r\n shellEnd: string;\r\n /** Suspense boundaries */\r\n suspenseBoundaries: SuspenseBoundaryConfig[];\r\n /** Streaming options */\r\n options?: StreamingRenderOptions;\r\n /** Observer hooks */\r\n observer?: StreamingObserver;\r\n /** Callback when all metrics are ready */\r\n onMetrics?: (metrics: StreamingMetrics) => void;\r\n /** Custom metadata to include in metrics */\r\n meta?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Result of instrumented streaming\r\n */\r\nexport interface InstrumentedStreamResult {\r\n /** The readable stream */\r\n stream: ReadableStream<Uint8Array>;\r\n /** Abort the stream */\r\n abort: () => void;\r\n /** Shell ready promise */\r\n shellReady: Promise<void>;\r\n /** All content ready promise */\r\n allReady: Promise<void>;\r\n /** Final metrics (resolves when stream completes) */\r\n metrics: Promise<StreamingMetrics>;\r\n /** Stream ID for correlation */\r\n streamId: string;\r\n}\r\n\r\n// ============================================================================\r\n// Implementation\r\n// ============================================================================\r\n\r\n/**\r\n * Generate a unique stream ID\r\n */\r\nfunction generateStreamId(): string {\r\n return `stream_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\r\n}\r\n\r\n/**\r\n * Create an instrumented streaming SSR response with full observability\r\n */\r\nexport async function createInstrumentedStream(\r\n config: InstrumentedStreamConfig\r\n): Promise<InstrumentedStreamResult> {\r\n const {\r\n shell,\r\n shellEnd,\r\n suspenseBoundaries,\r\n options = {},\r\n observer,\r\n onMetrics,\r\n meta,\r\n } = config;\r\n\r\n const streamId = generateStreamId();\r\n const startTime = Date.now();\r\n const boundaryTimings: BoundaryTiming[] = [];\r\n const boundaryStarts = new Map<string, number>();\r\n let shellTime = 0;\r\n let totalBytes = 0;\r\n\r\n // Metrics promise\r\n let resolveMetrics: (m: StreamingMetrics) => void;\r\n const metricsPromise = new Promise<StreamingMetrics>((r) => { resolveMetrics = r; });\r\n\r\n // Notify stream start\r\n observer?.onStreamStart?.(streamId);\r\n\r\n // Wrap boundaries with instrumentation\r\n const instrumentedBoundaries: SuspenseBoundaryConfig[] = suspenseBoundaries.map(boundary => {\r\n const boundaryStart = Date.now();\r\n boundaryStarts.set(boundary.id, boundaryStart);\r\n\r\n observer?.onBoundaryStart?.({\r\n streamId,\r\n boundaryId: boundary.id,\r\n startTime: boundaryStart - startTime,\r\n });\r\n\r\n return {\r\n ...boundary,\r\n contentPromise: boundary.contentPromise.then(\r\n (content) => {\r\n const endTime = Date.now();\r\n const timing: BoundaryTiming = {\r\n id: boundary.id,\r\n startTime: boundaryStarts.get(boundary.id)! - startTime,\r\n endTime: endTime - startTime,\r\n duration: endTime - boundaryStarts.get(boundary.id)!,\r\n success: true,\r\n contentSize: new TextEncoder().encode(content).length,\r\n };\r\n boundaryTimings.push(timing);\r\n observer?.onBoundaryEnd?.({ ...timing, streamId });\r\n return content;\r\n },\r\n (error) => {\r\n const endTime = Date.now();\r\n const timing: BoundaryTiming = {\r\n id: boundary.id,\r\n startTime: boundaryStarts.get(boundary.id)! - startTime,\r\n endTime: endTime - startTime,\r\n duration: endTime - boundaryStarts.get(boundary.id)!,\r\n success: false,\r\n error: error instanceof Error ? error.message : String(error),\r\n };\r\n boundaryTimings.push(timing);\r\n observer?.onBoundaryEnd?.({ ...timing, streamId });\r\n observer?.onError?.({ streamId, boundaryId: boundary.id, error: error as Error });\r\n throw error;\r\n }\r\n ),\r\n };\r\n });\r\n\r\n // Create the underlying stream with instrumented callbacks\r\n const result = await createStreamingSSR({\r\n shell,\r\n shellEnd,\r\n suspenseBoundaries: instrumentedBoundaries,\r\n options: {\r\n ...options,\r\n onShellReady: () => {\r\n shellTime = Date.now() - startTime;\r\n observer?.onShellReady?.({ streamId, duration: shellTime });\r\n options.onShellReady?.();\r\n },\r\n onAllReady: () => {\r\n const totalStreamTime = Date.now() - startTime;\r\n\r\n const metrics: StreamingMetrics = {\r\n streamId,\r\n startTime,\r\n shellTime,\r\n totalStreamTime,\r\n boundaries: boundaryTimings,\r\n successCount: boundaryTimings.filter(b => b.success).length,\r\n errorCount: boundaryTimings.filter(b => !b.success).length,\r\n totalBytes,\r\n meta,\r\n };\r\n\r\n observer?.onStreamEnd?.(metrics);\r\n onMetrics?.(metrics);\r\n resolveMetrics!(metrics);\r\n options.onAllReady?.();\r\n },\r\n onError: (error) => {\r\n observer?.onError?.({ streamId, error });\r\n options.onError?.(error);\r\n },\r\n },\r\n });\r\n\r\n // Wrap stream to count bytes\r\n const countingStream = result.stream.pipeThrough(\r\n new TransformStream<Uint8Array, Uint8Array>({\r\n transform(chunk, controller) {\r\n totalBytes += chunk.length;\r\n controller.enqueue(chunk);\r\n },\r\n })\r\n );\r\n\r\n return {\r\n stream: countingStream,\r\n abort: result.abort,\r\n shellReady: result.shellReady,\r\n allReady: result.allReady,\r\n metrics: metricsPromise,\r\n streamId,\r\n };\r\n}\r\n\r\n// ============================================================================\r\n// Utility: Metrics Aggregator\r\n// ============================================================================\r\n\r\n/**\r\n * Aggregate metrics from multiple streams for analysis\r\n */\r\nexport class MetricsAggregator {\r\n private metrics: StreamingMetrics[] = [];\r\n private maxSamples: number;\r\n\r\n constructor(maxSamples = 1000) {\r\n this.maxSamples = maxSamples;\r\n }\r\n\r\n /**\r\n * Add metrics from a stream\r\n */\r\n add(metrics: StreamingMetrics): void {\r\n this.metrics.push(metrics);\r\n if (this.metrics.length > this.maxSamples) {\r\n this.metrics.shift();\r\n }\r\n }\r\n\r\n /**\r\n * Get average shell time\r\n */\r\n getAverageShellTime(): number {\r\n if (this.metrics.length === 0) return 0;\r\n return this.metrics.reduce((sum, m) => sum + m.shellTime, 0) / this.metrics.length;\r\n }\r\n\r\n /**\r\n * Get average total stream time\r\n */\r\n getAverageTotalTime(): number {\r\n if (this.metrics.length === 0) return 0;\r\n return this.metrics.reduce((sum, m) => sum + m.totalStreamTime, 0) / this.metrics.length;\r\n }\r\n\r\n /**\r\n * Get slowest boundaries (by average duration)\r\n */\r\n getSlowestBoundaries(limit = 5): { id: string; avgDuration: number; errorRate: number }[] {\r\n const boundaryStats = new Map<string, { totalDuration: number; count: number; errors: number }>();\r\n\r\n for (const m of this.metrics) {\r\n for (const b of m.boundaries) {\r\n const stats = boundaryStats.get(b.id) || { totalDuration: 0, count: 0, errors: 0 };\r\n stats.totalDuration += b.duration;\r\n stats.count++;\r\n if (!b.success) stats.errors++;\r\n boundaryStats.set(b.id, stats);\r\n }\r\n }\r\n\r\n return [...boundaryStats.entries()]\r\n .map(([id, stats]) => ({\r\n id,\r\n avgDuration: stats.totalDuration / stats.count,\r\n errorRate: stats.errors / stats.count,\r\n }))\r\n .sort((a, b) => b.avgDuration - a.avgDuration)\r\n .slice(0, limit);\r\n }\r\n\r\n /**\r\n * Get overall error rate\r\n */\r\n getErrorRate(): number {\r\n const total = this.metrics.reduce((sum, m) => sum + m.boundaries.length, 0);\r\n const errors = this.metrics.reduce((sum, m) => sum + m.errorCount, 0);\r\n return total > 0 ? errors / total : 0;\r\n }\r\n\r\n /**\r\n * Get percentiles for shell time\r\n */\r\n getShellTimePercentiles(): { p50: number; p90: number; p99: number } {\r\n const sorted = [...this.metrics].map(m => m.shellTime).sort((a, b) => a - b);\r\n const len = sorted.length;\r\n if (len === 0) return { p50: 0, p90: 0, p99: 0 };\r\n\r\n return {\r\n p50: sorted[Math.floor(len * 0.5)] ?? 0,\r\n p90: sorted[Math.floor(len * 0.9)] ?? 0,\r\n p99: sorted[Math.floor(len * 0.99)] ?? 0,\r\n };\r\n }\r\n\r\n /**\r\n * Export all metrics for external analysis\r\n */\r\n export(): StreamingMetrics[] {\r\n return [...this.metrics];\r\n }\r\n\r\n /**\r\n * Clear all metrics\r\n */\r\n clear(): void {\r\n this.metrics = [];\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Utility: Create Observer from Logger\r\n// ============================================================================\r\n\r\n/**\r\n * Create a streaming observer from a simple logger function\r\n */\r\nexport function createLoggerObserver(\r\n log: (message: string, data?: Record<string, unknown>) => void\r\n): StreamingObserver {\r\n return {\r\n onStreamStart: (streamId) => {\r\n log('[Flight] Stream started', { streamId });\r\n },\r\n onShellReady: ({ streamId, duration }) => {\r\n log('[Flight] Shell ready', { streamId, duration: `${duration}ms` });\r\n },\r\n onBoundaryStart: ({ streamId, boundaryId, startTime }) => {\r\n log('[Flight] Boundary started', { streamId, boundaryId, startTime: `${startTime}ms` });\r\n },\r\n onBoundaryEnd: (timing) => {\r\n log('[Flight] Boundary completed', {\r\n streamId: (timing as any).streamId,\r\n boundaryId: timing.id,\r\n duration: `${timing.duration}ms`,\r\n success: timing.success,\r\n size: timing.contentSize ? `${timing.contentSize}b` : undefined,\r\n });\r\n },\r\n onStreamEnd: (metrics) => {\r\n log('[Flight] Stream completed', {\r\n streamId: metrics.streamId,\r\n totalTime: `${metrics.totalStreamTime}ms`,\r\n shellTime: `${metrics.shellTime}ms`,\r\n boundaries: metrics.boundaries.length,\r\n errors: metrics.errorCount,\r\n });\r\n },\r\n onError: ({ streamId, boundaryId, error }) => {\r\n log('[Flight] Stream error', { streamId, boundaryId, error: error.message });\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Create observer that sends metrics to a custom endpoint (YOUR infrastructure)\r\n */\r\nexport function createHttpObserver(endpoint: string, options?: {\r\n headers?: Record<string, string>;\r\n batchSize?: number;\r\n flushInterval?: number;\r\n}): StreamingObserver {\r\n const { headers = {}, batchSize = 10, flushInterval = 5000 } = options || {};\r\n const buffer: StreamingMetrics[] = [];\r\n let flushTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\n const flush = async () => {\r\n if (buffer.length === 0) return;\r\n const batch = buffer.splice(0, buffer.length);\r\n\r\n try {\r\n await fetch(endpoint, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...headers,\r\n },\r\n body: JSON.stringify({ metrics: batch, timestamp: Date.now() }),\r\n });\r\n } catch (error) {\r\n console.error('[Flight] Failed to send metrics:', error);\r\n // Re-add to buffer for retry\r\n buffer.unshift(...batch);\r\n }\r\n };\r\n\r\n const scheduleFlush = () => {\r\n if (flushTimer) return;\r\n flushTimer = setTimeout(() => {\r\n flushTimer = null;\r\n flush();\r\n }, flushInterval);\r\n };\r\n\r\n return {\r\n onStreamEnd: (metrics) => {\r\n buffer.push(metrics);\r\n if (buffer.length >= batchSize) {\r\n flush();\r\n } else {\r\n scheduleFlush();\r\n }\r\n },\r\n };\r\n}\r\n"]}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
// src/rsc/adapters/solid.ts
|
|
2
|
+
var CLIENT_REFERENCE = /* @__PURE__ */ Symbol.for("flight.client.reference");
|
|
3
|
+
function createSolidAdapter(deps) {
|
|
4
|
+
const { solid, web } = deps || {};
|
|
5
|
+
return {
|
|
6
|
+
name: "solid",
|
|
7
|
+
isElement(value) {
|
|
8
|
+
if (value === null || typeof value !== "object") {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const el = value;
|
|
12
|
+
if ("t" in el && ("p" in el || el.p === null)) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
if (typeof value === "function") {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
},
|
|
20
|
+
getElementType(element) {
|
|
21
|
+
if (typeof element === "function") {
|
|
22
|
+
const fn = element;
|
|
23
|
+
return {
|
|
24
|
+
kind: "component",
|
|
25
|
+
fn,
|
|
26
|
+
name: fn.displayName || fn.name || "SolidComponent"
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const el = element;
|
|
30
|
+
const type = el.t;
|
|
31
|
+
if (typeof type === "string") {
|
|
32
|
+
return { kind: "host", tag: type };
|
|
33
|
+
}
|
|
34
|
+
if (typeof type === "function") {
|
|
35
|
+
const fn = type;
|
|
36
|
+
if (solid) {
|
|
37
|
+
if (type === solid.For) {
|
|
38
|
+
return { kind: "fragment" };
|
|
39
|
+
}
|
|
40
|
+
if (type === solid.Show) {
|
|
41
|
+
return { kind: "fragment" };
|
|
42
|
+
}
|
|
43
|
+
if (type === solid.Suspense) {
|
|
44
|
+
return {
|
|
45
|
+
kind: "suspense",
|
|
46
|
+
fallback: el.p?.fallback
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
kind: "component",
|
|
52
|
+
fn,
|
|
53
|
+
name: fn.displayName || fn.name || "Component"
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (typeof type === "symbol") {
|
|
57
|
+
return { kind: "fragment" };
|
|
58
|
+
}
|
|
59
|
+
return { kind: "null" };
|
|
60
|
+
},
|
|
61
|
+
getProps(element) {
|
|
62
|
+
if (typeof element === "function") {
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
65
|
+
return element.p || {};
|
|
66
|
+
},
|
|
67
|
+
getChildren(element) {
|
|
68
|
+
if (typeof element === "function") {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
const props = element.p;
|
|
72
|
+
const children = props?.children;
|
|
73
|
+
if (children === void 0 || children === null) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
if (typeof children === "function") {
|
|
77
|
+
if (web?.isServer) {
|
|
78
|
+
try {
|
|
79
|
+
const result = children();
|
|
80
|
+
if (Array.isArray(result)) {
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
return [result];
|
|
84
|
+
} catch {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return [children];
|
|
89
|
+
}
|
|
90
|
+
if (Array.isArray(children)) {
|
|
91
|
+
return children.flat();
|
|
92
|
+
}
|
|
93
|
+
return [children];
|
|
94
|
+
},
|
|
95
|
+
getKey(element) {
|
|
96
|
+
if (typeof element === "function") {
|
|
97
|
+
return void 0;
|
|
98
|
+
}
|
|
99
|
+
const ref = element.r;
|
|
100
|
+
if (typeof ref === "string" || typeof ref === "number") {
|
|
101
|
+
return ref;
|
|
102
|
+
}
|
|
103
|
+
return void 0;
|
|
104
|
+
},
|
|
105
|
+
isClientBoundary(component) {
|
|
106
|
+
if (typeof component !== "function" && typeof component !== "object") {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
const comp = component;
|
|
110
|
+
if (comp.__flight_client === true) return true;
|
|
111
|
+
if (comp.$$typeof === CLIENT_REFERENCE) return true;
|
|
112
|
+
return false;
|
|
113
|
+
},
|
|
114
|
+
async renderToString(element) {
|
|
115
|
+
if (web?.renderToStringAsync) {
|
|
116
|
+
return web.renderToStringAsync(() => element);
|
|
117
|
+
}
|
|
118
|
+
if (web?.renderToString) {
|
|
119
|
+
return web.renderToString(() => element);
|
|
120
|
+
}
|
|
121
|
+
throw new Error(
|
|
122
|
+
"renderToString not provided. Pass solid-js/web when creating the adapter: createSolidAdapter({ solid, web })"
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function createSolidConsumer(deps, options = {}) {
|
|
128
|
+
const { solid, web } = deps;
|
|
129
|
+
const { registry = /* @__PURE__ */ new Map() } = options;
|
|
130
|
+
return {
|
|
131
|
+
/**
|
|
132
|
+
* Register a client component
|
|
133
|
+
*/
|
|
134
|
+
register(id, loader) {
|
|
135
|
+
registry.set(id, loader);
|
|
136
|
+
},
|
|
137
|
+
/**
|
|
138
|
+
* Convert Flight elements to Solid JSX
|
|
139
|
+
*/
|
|
140
|
+
toSolidElement(element) {
|
|
141
|
+
switch (element.$$type) {
|
|
142
|
+
case "null":
|
|
143
|
+
return null;
|
|
144
|
+
case "text":
|
|
145
|
+
return element.value;
|
|
146
|
+
case "host": {
|
|
147
|
+
const children = element.children.map((c) => this.toSolidElement(c));
|
|
148
|
+
return {
|
|
149
|
+
t: element.tag,
|
|
150
|
+
p: { ...element.props, children },
|
|
151
|
+
r: element.key
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
case "fragment": {
|
|
155
|
+
const children = element.children.map((c) => this.toSolidElement(c));
|
|
156
|
+
return children;
|
|
157
|
+
}
|
|
158
|
+
case "suspense": {
|
|
159
|
+
if (solid?.Suspense) {
|
|
160
|
+
const fallback = this.toSolidElement(element.fallback);
|
|
161
|
+
const children = element.children.map((c) => this.toSolidElement(c));
|
|
162
|
+
return {
|
|
163
|
+
t: solid.Suspense,
|
|
164
|
+
p: { fallback: () => fallback, children: () => children }
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
return element.children.map((c) => this.toSolidElement(c));
|
|
168
|
+
}
|
|
169
|
+
case "client": {
|
|
170
|
+
const loader = registry.get(element.ref);
|
|
171
|
+
if (!loader) {
|
|
172
|
+
console.warn(`[Flight] Client component not registered: ${element.ref}`);
|
|
173
|
+
if (element.ssr) {
|
|
174
|
+
return {
|
|
175
|
+
t: "div",
|
|
176
|
+
p: { innerHTML: element.ssr }
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
const LazyComponent = async () => {
|
|
182
|
+
const mod = await loader();
|
|
183
|
+
return mod.default ?? mod;
|
|
184
|
+
};
|
|
185
|
+
if (solid?.Suspense) {
|
|
186
|
+
return {
|
|
187
|
+
t: solid.Suspense,
|
|
188
|
+
p: {
|
|
189
|
+
fallback: () => element.ssr ? { t: "div", p: { innerHTML: element.ssr } } : null,
|
|
190
|
+
children: LazyComponent
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return { t: LazyComponent, p: {} };
|
|
195
|
+
}
|
|
196
|
+
case "lazy": {
|
|
197
|
+
if (element.fallback) {
|
|
198
|
+
return this.toSolidElement(element.fallback);
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
t: "div",
|
|
202
|
+
p: { "data-flight-pending": element.id }
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
default:
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
/**
|
|
210
|
+
* Hydrate Flight payload into DOM
|
|
211
|
+
*/
|
|
212
|
+
hydrate(chunks, container) {
|
|
213
|
+
const rootChunk = chunks.find((c) => c.type === "S" && c.id === "root");
|
|
214
|
+
if (!rootChunk || rootChunk.type !== "S") {
|
|
215
|
+
throw new Error("[Flight] No root chunk found");
|
|
216
|
+
}
|
|
217
|
+
for (const chunk of chunks) {
|
|
218
|
+
if (chunk.type === "C") {
|
|
219
|
+
if (!registry.has(chunk.id)) {
|
|
220
|
+
registry.set(chunk.id, () => import(
|
|
221
|
+
/* webpackIgnore: true */
|
|
222
|
+
chunk.module
|
|
223
|
+
));
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
const element = this.toSolidElement(rootChunk.tree);
|
|
228
|
+
if (web?.hydrate) {
|
|
229
|
+
return web.hydrate(() => element, container);
|
|
230
|
+
}
|
|
231
|
+
if (web?.render) {
|
|
232
|
+
return web.render(() => element, container);
|
|
233
|
+
}
|
|
234
|
+
throw new Error("[Flight] Solid web.hydrate or web.render not provided");
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
function markAsSolidClientComponent(component, moduleId, exportName = "default") {
|
|
239
|
+
const marked = component;
|
|
240
|
+
marked.$$typeof = CLIENT_REFERENCE;
|
|
241
|
+
marked.__flight_client = true;
|
|
242
|
+
marked.__flight_module = moduleId;
|
|
243
|
+
marked.__flight_export = exportName;
|
|
244
|
+
return marked;
|
|
245
|
+
}
|
|
246
|
+
function isServer(deps) {
|
|
247
|
+
return deps?.web?.isServer ?? typeof window === "undefined";
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export { createSolidAdapter, createSolidConsumer, isServer, markAsSolidClientComponent };
|
|
251
|
+
//# sourceMappingURL=chunk-6CD5FIYI.js.map
|
|
252
|
+
//# sourceMappingURL=chunk-6CD5FIYI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rsc/adapters/solid.ts"],"names":[],"mappings":";AAqBA,IAAM,gBAAA,mBAAmB,MAAA,CAAO,GAAA,CAAI,yBAAyB,CAAA;AAiEtD,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,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-6CD5FIYI.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\nconst SOLID_COMPONENT = Symbol.for('solid.component');\r\nconst SOLID_ELEMENT = Symbol.for('solid.element');\r\n\r\n// Flight reference symbols\r\nconst CLIENT_REFERENCE = Symbol.for('flight.client.reference');\r\nconst SERVER_REFERENCE = Symbol.for('flight.server.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 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"]}
|