@flightdev/core 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +541 -0
  3. package/dist/actions/index.d.ts +743 -0
  4. package/dist/actions/index.js +3 -0
  5. package/dist/actions/index.js.map +1 -0
  6. package/dist/adapters/index.d.ts +502 -0
  7. package/dist/adapters/index.js +3 -0
  8. package/dist/adapters/index.js.map +1 -0
  9. package/dist/cache/index.d.ts +191 -0
  10. package/dist/cache/index.js +3 -0
  11. package/dist/cache/index.js.map +1 -0
  12. package/dist/chunk-62HISNA3.js +354 -0
  13. package/dist/chunk-62HISNA3.js.map +1 -0
  14. package/dist/chunk-63LWTEDQ.js +341 -0
  15. package/dist/chunk-63LWTEDQ.js.map +1 -0
  16. package/dist/chunk-63SCEXD7.js +3 -0
  17. package/dist/chunk-63SCEXD7.js.map +1 -0
  18. package/dist/chunk-72MYOTUB.js +667 -0
  19. package/dist/chunk-72MYOTUB.js.map +1 -0
  20. package/dist/chunk-7CNW24MQ.js +257 -0
  21. package/dist/chunk-7CNW24MQ.js.map +1 -0
  22. package/dist/chunk-7WIEAUJT.js +300 -0
  23. package/dist/chunk-7WIEAUJT.js.map +1 -0
  24. package/dist/chunk-7ZZF4ULK.js +259 -0
  25. package/dist/chunk-7ZZF4ULK.js.map +1 -0
  26. package/dist/chunk-AE3JTS73.js +222 -0
  27. package/dist/chunk-AE3JTS73.js.map +1 -0
  28. package/dist/chunk-AP5NLUSB.js +258 -0
  29. package/dist/chunk-AP5NLUSB.js.map +1 -0
  30. package/dist/chunk-C37YQQI7.js +221 -0
  31. package/dist/chunk-C37YQQI7.js.map +1 -0
  32. package/dist/chunk-DCLVXFVH.js +225 -0
  33. package/dist/chunk-DCLVXFVH.js.map +1 -0
  34. package/dist/chunk-DZMWWDFD.js +223 -0
  35. package/dist/chunk-DZMWWDFD.js.map +1 -0
  36. package/dist/chunk-GCQZ4FHI.js +245 -0
  37. package/dist/chunk-GCQZ4FHI.js.map +1 -0
  38. package/dist/chunk-IPP44XY6.js +47 -0
  39. package/dist/chunk-IPP44XY6.js.map +1 -0
  40. package/dist/chunk-IW7FTQQX.js +267 -0
  41. package/dist/chunk-IW7FTQQX.js.map +1 -0
  42. package/dist/chunk-JX4YSCBH.js +428 -0
  43. package/dist/chunk-JX4YSCBH.js.map +1 -0
  44. package/dist/chunk-KX6UYWWR.js +229 -0
  45. package/dist/chunk-KX6UYWWR.js.map +1 -0
  46. package/dist/chunk-LWVETFJV.js +46 -0
  47. package/dist/chunk-LWVETFJV.js.map +1 -0
  48. package/dist/chunk-MCL2MCA2.js +285 -0
  49. package/dist/chunk-MCL2MCA2.js.map +1 -0
  50. package/dist/chunk-MZXCF35B.js +205 -0
  51. package/dist/chunk-MZXCF35B.js.map +1 -0
  52. package/dist/chunk-NCGPUFWV.js +96 -0
  53. package/dist/chunk-NCGPUFWV.js.map +1 -0
  54. package/dist/chunk-OEJMIE2Q.js +351 -0
  55. package/dist/chunk-OEJMIE2Q.js.map +1 -0
  56. package/dist/chunk-OYF2OAKS.js +394 -0
  57. package/dist/chunk-OYF2OAKS.js.map +1 -0
  58. package/dist/chunk-P6S43FYZ.js +316 -0
  59. package/dist/chunk-P6S43FYZ.js.map +1 -0
  60. package/dist/chunk-PL37KFRJ.js +3 -0
  61. package/dist/chunk-PL37KFRJ.js.map +1 -0
  62. package/dist/chunk-Q7BS5QC5.js +197 -0
  63. package/dist/chunk-Q7BS5QC5.js.map +1 -0
  64. package/dist/chunk-SDYPG3JD.js +288 -0
  65. package/dist/chunk-SDYPG3JD.js.map +1 -0
  66. package/dist/chunk-SUG56SZO.js +256 -0
  67. package/dist/chunk-SUG56SZO.js.map +1 -0
  68. package/dist/chunk-UVH5XJRP.js +164 -0
  69. package/dist/chunk-UVH5XJRP.js.map +1 -0
  70. package/dist/chunk-WZIJKCL3.js +282 -0
  71. package/dist/chunk-WZIJKCL3.js.map +1 -0
  72. package/dist/chunk-Y22AMGTM.js +3 -0
  73. package/dist/chunk-Y22AMGTM.js.map +1 -0
  74. package/dist/chunk-Z7G23XWU.js +200 -0
  75. package/dist/chunk-Z7G23XWU.js.map +1 -0
  76. package/dist/chunk-ZJU5M4IB.js +125 -0
  77. package/dist/chunk-ZJU5M4IB.js.map +1 -0
  78. package/dist/chunk-ZVC3ZWLM.js +52 -0
  79. package/dist/chunk-ZVC3ZWLM.js.map +1 -0
  80. package/dist/chunk-ZZZML7Y3.js +310 -0
  81. package/dist/chunk-ZZZML7Y3.js.map +1 -0
  82. package/dist/client.d.ts +25 -0
  83. package/dist/client.js +16 -0
  84. package/dist/client.js.map +1 -0
  85. package/dist/config/index.d.ts +170 -0
  86. package/dist/config/index.js +3 -0
  87. package/dist/config/index.js.map +1 -0
  88. package/dist/errors/index.d.ts +267 -0
  89. package/dist/errors/index.js +4 -0
  90. package/dist/errors/index.js.map +1 -0
  91. package/dist/file-router/index.d.ts +184 -0
  92. package/dist/file-router/index.js +3 -0
  93. package/dist/file-router/index.js.map +1 -0
  94. package/dist/file-router/streaming-hints.d.ts +129 -0
  95. package/dist/file-router/streaming-hints.js +3 -0
  96. package/dist/file-router/streaming-hints.js.map +1 -0
  97. package/dist/handlers/index.d.ts +59 -0
  98. package/dist/handlers/index.js +3 -0
  99. package/dist/handlers/index.js.map +1 -0
  100. package/dist/index.d.ts +588 -0
  101. package/dist/index.js +886 -0
  102. package/dist/index.js.map +1 -0
  103. package/dist/islands/index.d.ts +234 -0
  104. package/dist/islands/index.js +3 -0
  105. package/dist/islands/index.js.map +1 -0
  106. package/dist/middleware/index.d.ts +305 -0
  107. package/dist/middleware/index.js +3 -0
  108. package/dist/middleware/index.js.map +1 -0
  109. package/dist/react/index.d.ts +73 -0
  110. package/dist/react/index.js +52 -0
  111. package/dist/react/index.js.map +1 -0
  112. package/dist/render/index.d.ts +131 -0
  113. package/dist/render/index.js +3 -0
  114. package/dist/render/index.js.map +1 -0
  115. package/dist/router/index.d.ts +65 -0
  116. package/dist/router/index.js +3 -0
  117. package/dist/router/index.js.map +1 -0
  118. package/dist/rsc/adapters/index.d.ts +8 -0
  119. package/dist/rsc/adapters/index.js +7 -0
  120. package/dist/rsc/adapters/index.js.map +1 -0
  121. package/dist/rsc/adapters/preact.d.ts +97 -0
  122. package/dist/rsc/adapters/preact.js +3 -0
  123. package/dist/rsc/adapters/preact.js.map +1 -0
  124. package/dist/rsc/adapters/react.d.ts +82 -0
  125. package/dist/rsc/adapters/react.js +3 -0
  126. package/dist/rsc/adapters/react.js.map +1 -0
  127. package/dist/rsc/adapters/solid.d.ts +84 -0
  128. package/dist/rsc/adapters/solid.js +3 -0
  129. package/dist/rsc/adapters/solid.js.map +1 -0
  130. package/dist/rsc/adapters/vue.d.ts +80 -0
  131. package/dist/rsc/adapters/vue.js +3 -0
  132. package/dist/rsc/adapters/vue.js.map +1 -0
  133. package/dist/rsc/boundaries.d.ts +182 -0
  134. package/dist/rsc/boundaries.js +3 -0
  135. package/dist/rsc/boundaries.js.map +1 -0
  136. package/dist/rsc/context.d.ts +201 -0
  137. package/dist/rsc/context.js +3 -0
  138. package/dist/rsc/context.js.map +1 -0
  139. package/dist/rsc/index.d.ts +232 -0
  140. package/dist/rsc/index.js +15 -0
  141. package/dist/rsc/index.js.map +1 -0
  142. package/dist/rsc/legacy.d.ts +155 -0
  143. package/dist/rsc/legacy.js +3 -0
  144. package/dist/rsc/legacy.js.map +1 -0
  145. package/dist/rsc/payload.d.ts +262 -0
  146. package/dist/rsc/payload.js +3 -0
  147. package/dist/rsc/payload.js.map +1 -0
  148. package/dist/rsc/plugins/esbuild.d.ts +124 -0
  149. package/dist/rsc/plugins/esbuild.js +4 -0
  150. package/dist/rsc/plugins/esbuild.js.map +1 -0
  151. package/dist/rsc/plugins/index.d.ts +4 -0
  152. package/dist/rsc/plugins/index.js +6 -0
  153. package/dist/rsc/plugins/index.js.map +1 -0
  154. package/dist/rsc/plugins/rollup.d.ts +103 -0
  155. package/dist/rsc/plugins/rollup.js +4 -0
  156. package/dist/rsc/plugins/rollup.js.map +1 -0
  157. package/dist/rsc/renderer.d.ts +162 -0
  158. package/dist/rsc/renderer.js +5 -0
  159. package/dist/rsc/renderer.js.map +1 -0
  160. package/dist/rsc/stream.d.ts +129 -0
  161. package/dist/rsc/stream.js +3 -0
  162. package/dist/rsc/stream.js.map +1 -0
  163. package/dist/rsc/vite-plugin.d.ts +78 -0
  164. package/dist/rsc/vite-plugin.js +4 -0
  165. package/dist/rsc/vite-plugin.js.map +1 -0
  166. package/dist/server/index.d.ts +135 -0
  167. package/dist/server/index.js +6 -0
  168. package/dist/server/index.js.map +1 -0
  169. package/dist/streaming/adapters/index.d.ts +223 -0
  170. package/dist/streaming/adapters/index.js +3 -0
  171. package/dist/streaming/adapters/index.js.map +1 -0
  172. package/dist/streaming/conditional.d.ts +130 -0
  173. package/dist/streaming/conditional.js +3 -0
  174. package/dist/streaming/conditional.js.map +1 -0
  175. package/dist/streaming/index.d.ts +177 -0
  176. package/dist/streaming/index.js +3 -0
  177. package/dist/streaming/index.js.map +1 -0
  178. package/dist/streaming/observability.d.ts +201 -0
  179. package/dist/streaming/observability.js +4 -0
  180. package/dist/streaming/observability.js.map +1 -0
  181. package/dist/streaming/priority.d.ts +103 -0
  182. package/dist/streaming/priority.js +3 -0
  183. package/dist/streaming/priority.js.map +1 -0
  184. package/dist/utils/index.d.ts +42 -0
  185. package/dist/utils/index.js +4 -0
  186. package/dist/utils/index.js.map +1 -0
  187. package/package.json +228 -0
@@ -0,0 +1,130 @@
1
+ /**
2
+ * @flightdev/core - Conditional Streaming
3
+ *
4
+ * Smart streaming decisions based on request context.
5
+ * Bots get full HTML, users get streaming - YOU control the logic.
6
+ *
7
+ * Best Practices 2026:
8
+ * - SEO-friendly: Crawlers receive complete HTML
9
+ * - Performance: Users get progressive streaming
10
+ * - Flexibility: Custom conditions for any use case
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { streamIf } from '@flightdev/core/streaming';
15
+ *
16
+ * const response = await streamIf({
17
+ * request,
18
+ * condition: (req) => !isBot(req), // YOUR logic
19
+ * stream: () => createStreamingSSR({ ... }),
20
+ * static: () => renderToString(<App />),
21
+ * });
22
+ * ```
23
+ */
24
+ /**
25
+ * Condition function to determine if streaming should be used
26
+ */
27
+ type StreamingCondition = (request: Request) => boolean | Promise<boolean>;
28
+ /**
29
+ * Built-in condition types
30
+ */
31
+ type BuiltInCondition = 'always-stream' | 'never-stream' | 'no-bots' | 'fast-network' | 'modern-browser';
32
+ /**
33
+ * Configuration for conditional streaming
34
+ */
35
+ interface StreamIfConfig<T = Response> {
36
+ /** The incoming request */
37
+ request: Request;
38
+ /** Condition to check (function or built-in) */
39
+ condition: StreamingCondition | BuiltInCondition;
40
+ /** Factory for streaming response */
41
+ stream: () => Promise<T> | T;
42
+ /** Factory for static response */
43
+ static: () => Promise<T> | T;
44
+ /** Optional: Custom bot patterns */
45
+ botPatterns?: RegExp[];
46
+ /** Optional: Force streaming via query param (for testing) */
47
+ forceStreamParam?: string;
48
+ /** Optional: Force static via query param (for testing) */
49
+ forceStaticParam?: string;
50
+ }
51
+ /**
52
+ * Result of condition evaluation
53
+ */
54
+ interface StreamingDecision {
55
+ /** Whether streaming was used */
56
+ streaming: boolean;
57
+ /** Reason for the decision */
58
+ reason: string;
59
+ /** The response */
60
+ response: Response;
61
+ }
62
+ /**
63
+ * Default bot patterns for detection
64
+ */
65
+ declare const DEFAULT_BOT_PATTERNS: RegExp[];
66
+ /**
67
+ * Check if a request is from a bot/crawler
68
+ */
69
+ declare function isBot(request: Request, customPatterns?: RegExp[]): boolean;
70
+ /**
71
+ * Check if request explicitly asks for no streaming
72
+ */
73
+ declare function prefersNoStream(request: Request): boolean;
74
+ /**
75
+ * Check if a connection is likely slow (based on headers)
76
+ */
77
+ declare function isSlowConnection(request: Request): boolean;
78
+ /**
79
+ * Check if browser supports streaming well
80
+ */
81
+ declare function supportsStreaming(request: Request): boolean;
82
+ /**
83
+ * Conditionally use streaming or static rendering based on request context
84
+ */
85
+ declare function streamIf<T = Response>(config: StreamIfConfig<T>): Promise<{
86
+ result: T;
87
+ streaming: boolean;
88
+ reason: string;
89
+ }>;
90
+ /**
91
+ * Create a middleware-style conditional streamer
92
+ */
93
+ declare function createConditionalStreamer<T = Response>(defaultCondition: StreamingCondition | BuiltInCondition, options?: {
94
+ botPatterns?: RegExp[];
95
+ forceStreamParam?: string;
96
+ forceStaticParam?: string;
97
+ }): (config: {
98
+ request: Request;
99
+ stream: () => Promise<T> | T;
100
+ static: () => Promise<T> | T;
101
+ condition?: StreamingCondition | BuiltInCondition;
102
+ }) => Promise<{
103
+ result: T;
104
+ streaming: boolean;
105
+ reason: string;
106
+ }>;
107
+ /**
108
+ * Add streaming decision headers to response (for debugging)
109
+ */
110
+ declare function addStreamingHeaders(response: Response, decision: {
111
+ streaming: boolean;
112
+ reason: string;
113
+ }): Response;
114
+ /**
115
+ * Create a streaming-aware Response with appropriate headers
116
+ */
117
+ declare function createStreamingResponse(stream: ReadableStream<Uint8Array>, options?: {
118
+ status?: number;
119
+ headers?: Record<string, string>;
120
+ isStreaming?: boolean;
121
+ }): Response;
122
+ /**
123
+ * Create a static HTML Response
124
+ */
125
+ declare function createStaticResponse(html: string, options?: {
126
+ status?: number;
127
+ headers?: Record<string, string>;
128
+ }): Response;
129
+
130
+ export { type BuiltInCondition, DEFAULT_BOT_PATTERNS, type StreamIfConfig, type StreamingCondition, type StreamingDecision, addStreamingHeaders, createConditionalStreamer, createStaticResponse, createStreamingResponse, isBot, isSlowConnection, prefersNoStream, streamIf, supportsStreaming };
@@ -0,0 +1,3 @@
1
+ export { DEFAULT_BOT_PATTERNS, addStreamingHeaders, createConditionalStreamer, createStaticResponse, createStreamingResponse, isBot, isSlowConnection, prefersNoStream, streamIf, supportsStreaming } from '../chunk-UVH5XJRP.js';
2
+ //# sourceMappingURL=conditional.js.map
3
+ //# sourceMappingURL=conditional.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"conditional.js"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * @flightdev/core - Streaming SSR
3
+ *
4
+ * Full streaming server-side rendering implementation following React 18+/19 patterns.
5
+ * Supports both Node.js (renderToPipeableStream) and Edge (renderToReadableStream) environments.
6
+ *
7
+ * Best Practices 2025/2026:
8
+ * - Progressive HTML streaming with Suspense boundaries
9
+ * - Shell-first rendering for fast TTFB
10
+ * - Nested Suspense for granular loading states
11
+ * - Error boundaries for graceful degradation
12
+ * - Web Streams API for Edge runtime compatibility
13
+ */
14
+ /**
15
+ * Streaming render options following React's conventions
16
+ */
17
+ interface StreamingRenderOptions {
18
+ /** Bootstrap scripts to load on client */
19
+ bootstrapScripts?: string[];
20
+ /** Bootstrap ES modules */
21
+ bootstrapModules?: string[];
22
+ /** Inline script content */
23
+ bootstrapScriptContent?: string;
24
+ /** Prefix for React IDs (useId) */
25
+ identifierPrefix?: string;
26
+ /** Nonce for CSP */
27
+ nonce?: string;
28
+ /** Callback when shell is ready (main content before Suspense) */
29
+ onShellReady?: () => void;
30
+ /** Callback when shell errors */
31
+ onShellError?: (error: Error) => void;
32
+ /** Callback when all content is ready */
33
+ onAllReady?: () => void;
34
+ /** Callback for any error */
35
+ onError?: (error: Error) => void;
36
+ /** Timeout before aborting stream */
37
+ timeoutMs?: number;
38
+ /** Progressive hydration enabled */
39
+ progressiveHydration?: boolean;
40
+ }
41
+ /**
42
+ * Streaming render result
43
+ */
44
+ interface StreamingRenderResult {
45
+ /** The readable stream to pipe to response */
46
+ stream: ReadableStream<Uint8Array>;
47
+ /** Abort the stream */
48
+ abort: () => void;
49
+ /** Promise that resolves when shell is ready */
50
+ shellReady: Promise<void>;
51
+ /** Promise that resolves when all content is ready */
52
+ allReady: Promise<void>;
53
+ }
54
+ /**
55
+ * Suspense boundary configuration
56
+ */
57
+ interface SuspenseBoundaryConfig {
58
+ /** Unique ID for this boundary */
59
+ id: string;
60
+ /** Fallback HTML to show while loading */
61
+ fallback: string;
62
+ /** Content resolver promise */
63
+ contentPromise: Promise<string>;
64
+ /**
65
+ * IDs of boundaries that must resolve before this one.
66
+ * Enables dependency-aware streaming for complex data relationships.
67
+ * @example ['user'] - Wait for 'user' boundary before starting
68
+ */
69
+ dependsOn?: string[];
70
+ /** Custom metadata for observability */
71
+ meta?: Record<string, unknown>;
72
+ }
73
+ /**
74
+ * Create a streaming SSR response using Web Streams API.
75
+ * Compatible with Edge Runtime (Cloudflare, Vercel Edge, Deno).
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * const result = await createStreamingSSR({
80
+ * shell: '<html><body><div id="root">',
81
+ * shellEnd: '</div></body></html>',
82
+ * suspenseBoundaries: [
83
+ * {
84
+ * id: 'posts',
85
+ * fallback: '<div>Loading posts...</div>',
86
+ * contentPromise: fetchAndRenderPosts(),
87
+ * }
88
+ * ],
89
+ * bootstrapScripts: ['/client.js'],
90
+ * });
91
+ *
92
+ * return new Response(result.stream, {
93
+ * headers: { 'Content-Type': 'text/html' },
94
+ * });
95
+ * ```
96
+ */
97
+ declare function createStreamingSSR(config: {
98
+ /** Initial HTML shell (before suspense content) */
99
+ shell: string;
100
+ /** Closing HTML shell */
101
+ shellEnd: string;
102
+ /** Suspense boundaries with async content */
103
+ suspenseBoundaries?: SuspenseBoundaryConfig[];
104
+ /** Streaming options */
105
+ options?: StreamingRenderOptions;
106
+ }): Promise<StreamingRenderResult>;
107
+ /**
108
+ * Create a streaming HTML Response object
109
+ */
110
+ declare function createStreamingResponse(stream: ReadableStream<Uint8Array>, options?: {
111
+ status?: number;
112
+ headers?: Record<string, string>;
113
+ }): Response;
114
+ /**
115
+ * Higher-level API: Render page with Suspense boundaries
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * return renderWithStreaming({
120
+ * layout: ({ children }) => `
121
+ * <html>
122
+ * <head><title>My App</title></head>
123
+ * <body><div id="root">${children}</div></body>
124
+ * </html>
125
+ * `,
126
+ * page: async () => '<h1>Welcome</h1>',
127
+ * suspense: {
128
+ * posts: {
129
+ * fallback: '<div class="skeleton">Loading...</div>',
130
+ * content: fetchPosts().then(renderPosts),
131
+ * },
132
+ * },
133
+ * });
134
+ * ```
135
+ */
136
+ declare function renderWithStreaming(config: {
137
+ /** Layout wrapper */
138
+ layout: (props: {
139
+ children: string;
140
+ }) => string;
141
+ /** Main page content (sync part) */
142
+ page: () => string | Promise<string>;
143
+ /** Suspense boundaries keyed by ID */
144
+ suspense?: Record<string, {
145
+ fallback: string;
146
+ content: Promise<string>;
147
+ }>;
148
+ /** Bootstrap scripts */
149
+ bootstrapScripts?: string[];
150
+ /** Timeout in ms */
151
+ timeoutMs?: number;
152
+ }): Promise<Response>;
153
+ /**
154
+ * Create a lazy component that streams its content
155
+ */
156
+ declare function createLazyContent<T>(fetcher: () => Promise<T>, renderer: (data: T) => string, fallback: string): {
157
+ fallback: string;
158
+ content: Promise<string>;
159
+ };
160
+ /**
161
+ * Parallel streaming: resolve multiple boundaries simultaneously
162
+ */
163
+ declare function streamParallel(boundaries: Array<{
164
+ id: string;
165
+ fallback: string;
166
+ content: () => Promise<string>;
167
+ }>): Promise<SuspenseBoundaryConfig[]>;
168
+ /**
169
+ * Sequential streaming: resolve boundaries in order
170
+ */
171
+ declare function streamSequential(boundaries: Array<{
172
+ id: string;
173
+ fallback: string;
174
+ content: () => Promise<string>;
175
+ }>): Promise<SuspenseBoundaryConfig[]>;
176
+
177
+ export { type StreamingRenderOptions, type StreamingRenderResult, type SuspenseBoundaryConfig, createLazyContent, createStreamingResponse, createStreamingSSR, renderWithStreaming, streamParallel, streamSequential };
@@ -0,0 +1,3 @@
1
+ export { createLazyContent, createStreamingResponse, createStreamingSSR, renderWithStreaming, streamParallel, streamSequential } from '../chunk-C37YQQI7.js';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,201 @@
1
+ import { SuspenseBoundaryConfig, StreamingRenderOptions } from './index.js';
2
+
3
+ /**
4
+ * @flightdev/core - Streaming Observability
5
+ *
6
+ * Zero-telemetry metrics and instrumentation for streaming SSR.
7
+ * All data stays on YOUR infrastructure - never sent anywhere.
8
+ *
9
+ * Best Practices 2026:
10
+ * - Comprehensive timing metrics for each boundary
11
+ * - Hook-based observability for custom integrations
12
+ * - Performance insights without vendor lock-in
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { createInstrumentedStream } from '@flightdev/core/streaming';
17
+ *
18
+ * const { stream, metrics } = await createInstrumentedStream({
19
+ * shell: '<html>...',
20
+ * boundaries: [...],
21
+ * onMetrics: (m) => myAnalytics.track(m), // YOUR system
22
+ * });
23
+ * ```
24
+ */
25
+
26
+ /**
27
+ * Timing information for a single boundary
28
+ */
29
+ interface BoundaryTiming {
30
+ /** Boundary identifier */
31
+ id: string;
32
+ /** When the boundary started resolving (ms since stream start) */
33
+ startTime: number;
34
+ /** When the boundary finished resolving */
35
+ endTime: number;
36
+ /** Total duration in milliseconds */
37
+ duration: number;
38
+ /** Whether it resolved successfully */
39
+ success: boolean;
40
+ /** Size of content in bytes (if successful) */
41
+ contentSize?: number;
42
+ /** Error message if failed */
43
+ error?: string;
44
+ }
45
+ /**
46
+ * Overall streaming metrics
47
+ */
48
+ interface StreamingMetrics {
49
+ /** Unique ID for this stream session */
50
+ streamId: string;
51
+ /** When streaming started */
52
+ startTime: number;
53
+ /** Time to shell ready (TTFB improvement) */
54
+ shellTime: number;
55
+ /** Time until all boundaries resolved */
56
+ totalStreamTime: number;
57
+ /** Individual boundary timings */
58
+ boundaries: BoundaryTiming[];
59
+ /** Number of boundaries that resolved successfully */
60
+ successCount: number;
61
+ /** Number of boundaries that failed */
62
+ errorCount: number;
63
+ /** Total bytes streamed */
64
+ totalBytes: number;
65
+ /** Strategy used (if priority streaming) */
66
+ strategy?: string;
67
+ /** Custom metadata you can add */
68
+ meta?: Record<string, unknown>;
69
+ }
70
+ /**
71
+ * Observability hooks for streaming events
72
+ */
73
+ interface StreamingObserver {
74
+ /** Called when streaming starts */
75
+ onStreamStart?: (streamId: string) => void;
76
+ /** Called when shell is sent */
77
+ onShellReady?: (timing: {
78
+ streamId: string;
79
+ duration: number;
80
+ }) => void;
81
+ /** Called when a boundary starts resolving */
82
+ onBoundaryStart?: (info: {
83
+ streamId: string;
84
+ boundaryId: string;
85
+ startTime: number;
86
+ }) => void;
87
+ /** Called when a boundary finishes */
88
+ onBoundaryEnd?: (timing: BoundaryTiming & {
89
+ streamId: string;
90
+ }) => void;
91
+ /** Called when streaming completes */
92
+ onStreamEnd?: (metrics: StreamingMetrics) => void;
93
+ /** Called on any error */
94
+ onError?: (error: {
95
+ streamId: string;
96
+ boundaryId?: string;
97
+ error: Error;
98
+ }) => void;
99
+ }
100
+ /**
101
+ * Configuration for instrumented streaming
102
+ */
103
+ interface InstrumentedStreamConfig {
104
+ /** Initial HTML shell */
105
+ shell: string;
106
+ /** Closing HTML */
107
+ shellEnd: string;
108
+ /** Suspense boundaries */
109
+ suspenseBoundaries: SuspenseBoundaryConfig[];
110
+ /** Streaming options */
111
+ options?: StreamingRenderOptions;
112
+ /** Observer hooks */
113
+ observer?: StreamingObserver;
114
+ /** Callback when all metrics are ready */
115
+ onMetrics?: (metrics: StreamingMetrics) => void;
116
+ /** Custom metadata to include in metrics */
117
+ meta?: Record<string, unknown>;
118
+ }
119
+ /**
120
+ * Result of instrumented streaming
121
+ */
122
+ interface InstrumentedStreamResult {
123
+ /** The readable stream */
124
+ stream: ReadableStream<Uint8Array>;
125
+ /** Abort the stream */
126
+ abort: () => void;
127
+ /** Shell ready promise */
128
+ shellReady: Promise<void>;
129
+ /** All content ready promise */
130
+ allReady: Promise<void>;
131
+ /** Final metrics (resolves when stream completes) */
132
+ metrics: Promise<StreamingMetrics>;
133
+ /** Stream ID for correlation */
134
+ streamId: string;
135
+ }
136
+ /**
137
+ * Create an instrumented streaming SSR response with full observability
138
+ */
139
+ declare function createInstrumentedStream(config: InstrumentedStreamConfig): Promise<InstrumentedStreamResult>;
140
+ /**
141
+ * Aggregate metrics from multiple streams for analysis
142
+ */
143
+ declare class MetricsAggregator {
144
+ private metrics;
145
+ private maxSamples;
146
+ constructor(maxSamples?: number);
147
+ /**
148
+ * Add metrics from a stream
149
+ */
150
+ add(metrics: StreamingMetrics): void;
151
+ /**
152
+ * Get average shell time
153
+ */
154
+ getAverageShellTime(): number;
155
+ /**
156
+ * Get average total stream time
157
+ */
158
+ getAverageTotalTime(): number;
159
+ /**
160
+ * Get slowest boundaries (by average duration)
161
+ */
162
+ getSlowestBoundaries(limit?: number): {
163
+ id: string;
164
+ avgDuration: number;
165
+ errorRate: number;
166
+ }[];
167
+ /**
168
+ * Get overall error rate
169
+ */
170
+ getErrorRate(): number;
171
+ /**
172
+ * Get percentiles for shell time
173
+ */
174
+ getShellTimePercentiles(): {
175
+ p50: number;
176
+ p90: number;
177
+ p99: number;
178
+ };
179
+ /**
180
+ * Export all metrics for external analysis
181
+ */
182
+ export(): StreamingMetrics[];
183
+ /**
184
+ * Clear all metrics
185
+ */
186
+ clear(): void;
187
+ }
188
+ /**
189
+ * Create a streaming observer from a simple logger function
190
+ */
191
+ declare function createLoggerObserver(log: (message: string, data?: Record<string, unknown>) => void): StreamingObserver;
192
+ /**
193
+ * Create observer that sends metrics to a custom endpoint (YOUR infrastructure)
194
+ */
195
+ declare function createHttpObserver(endpoint: string, options?: {
196
+ headers?: Record<string, string>;
197
+ batchSize?: number;
198
+ flushInterval?: number;
199
+ }): StreamingObserver;
200
+
201
+ export { type BoundaryTiming, type InstrumentedStreamConfig, type InstrumentedStreamResult, MetricsAggregator, type StreamingMetrics, type StreamingObserver, createHttpObserver, createInstrumentedStream, createLoggerObserver };
@@ -0,0 +1,4 @@
1
+ export { MetricsAggregator, createHttpObserver, createInstrumentedStream, createLoggerObserver } from '../chunk-WZIJKCL3.js';
2
+ import '../chunk-C37YQQI7.js';
3
+ //# sourceMappingURL=observability.js.map
4
+ //# sourceMappingURL=observability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"observability.js"}
@@ -0,0 +1,103 @@
1
+ import { StreamingRenderOptions, StreamingRenderResult } from './index.js';
2
+
3
+ /**
4
+ * @flightdev/core - Priority-Based Streaming SSR
5
+ *
6
+ * Out-of-order streaming with priority control, deadlines, and dependencies.
7
+ * Gives developers full control over streaming order and timing.
8
+ *
9
+ * Best Practices 2026:
10
+ * - Priority-based content delivery for optimal UX
11
+ * - Deadline-aware streaming to prevent slow boundaries from blocking
12
+ * - Dependency graphs for complex data relationships
13
+ * - Strategy-based streaming modes for different use cases
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * import { streamWithPriority } from '@flightdev/core/streaming';
18
+ *
19
+ * const result = await streamWithPriority({
20
+ * shell: '<html>...',
21
+ * shellEnd: '</html>',
22
+ * boundaries: [
23
+ * { id: 'hero', priority: 1, content: fetchHero() },
24
+ * { id: 'nav', priority: 2, content: fetchNav() },
25
+ * { id: 'comments', priority: 10, content: fetchComments() },
26
+ * ],
27
+ * strategy: 'priority-first',
28
+ * });
29
+ * ```
30
+ */
31
+
32
+ /**
33
+ * Boundary with priority and advanced options
34
+ */
35
+ interface PriorityBoundary {
36
+ /** Unique identifier for this boundary */
37
+ id: string;
38
+ /** Fallback HTML while loading */
39
+ fallback: string;
40
+ /** Content promise or factory function */
41
+ content: Promise<string> | (() => Promise<string>);
42
+ /** Priority level (lower number = higher priority, rendered first) */
43
+ priority: number;
44
+ /** Maximum time to wait before skipping (ms). Boundary shows fallback if exceeded. */
45
+ deadline?: number;
46
+ /** IDs of boundaries that must resolve before this one starts */
47
+ dependsOn?: string[];
48
+ /** Optional metadata for observability */
49
+ meta?: Record<string, unknown>;
50
+ }
51
+ /**
52
+ * Streaming strategy - how to order content delivery
53
+ */
54
+ type StreamingStrategy = 'priority-first' | 'first-ready' | 'dependency-aware' | 'round-robin' | 'deadline-strict';
55
+ /**
56
+ * Result of a priority boundary resolution
57
+ */
58
+ interface BoundaryResolution {
59
+ id: string;
60
+ content: string | null;
61
+ duration: number;
62
+ status: 'resolved' | 'timeout' | 'error' | 'skipped';
63
+ error?: Error;
64
+ }
65
+ /**
66
+ * Priority streaming configuration
67
+ */
68
+ interface PriorityStreamConfig {
69
+ /** Initial HTML shell */
70
+ shell: string;
71
+ /** Closing HTML */
72
+ shellEnd: string;
73
+ /** Boundaries with priorities */
74
+ boundaries: PriorityBoundary[];
75
+ /** Streaming strategy */
76
+ strategy: StreamingStrategy;
77
+ /** Base streaming options */
78
+ options?: StreamingRenderOptions;
79
+ /** Callback when a boundary resolves */
80
+ onBoundaryResolved?: (resolution: BoundaryResolution) => void;
81
+ /** Global timeout for all boundaries */
82
+ globalTimeout?: number;
83
+ }
84
+ /**
85
+ * Priority streaming result with additional metrics
86
+ */
87
+ interface PriorityStreamResult extends StreamingRenderResult {
88
+ /** Resolution details for each boundary */
89
+ resolutions: Promise<BoundaryResolution[]>;
90
+ }
91
+ /**
92
+ * Create a priority-ordered streaming SSR response
93
+ */
94
+ declare function streamWithPriority(config: PriorityStreamConfig): Promise<PriorityStreamResult>;
95
+ /**
96
+ * Validate that boundaries don't have circular dependencies
97
+ */
98
+ declare function validateDependencies(boundaries: PriorityBoundary[]): {
99
+ valid: boolean;
100
+ cycles?: string[][];
101
+ };
102
+
103
+ export { type BoundaryResolution, type PriorityBoundary, type PriorityStreamConfig, type PriorityStreamResult, type StreamingStrategy, streamWithPriority, validateDependencies };
@@ -0,0 +1,3 @@
1
+ export { streamWithPriority, validateDependencies } from '../chunk-OEJMIE2Q.js';
2
+ //# sourceMappingURL=priority.js.map
3
+ //# sourceMappingURL=priority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"priority.js"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @flightdev/core - Environment Utilities
3
+ *
4
+ * Environment detection utilities that work across Node.js, browsers, and edge runtimes.
5
+ * No hardcoded values - detects environment dynamically.
6
+ */
7
+ /**
8
+ * Check if running in production environment.
9
+ *
10
+ * Detection order:
11
+ * 1. Node.js process.env.NODE_ENV
12
+ * 2. Vite/modern bundlers import.meta.env.MODE or import.meta.env.PROD
13
+ * 3. Default: false (not production)
14
+ */
15
+ declare function isProduction(): boolean;
16
+ /**
17
+ * Check if running in development environment.
18
+ *
19
+ * Detection order:
20
+ * 1. Node.js process.env.NODE_ENV
21
+ * 2. Vite/modern bundlers import.meta.env.MODE or import.meta.env.DEV
22
+ * 3. Default: true (assume development if unknown)
23
+ */
24
+ declare function isDevelopment(): boolean;
25
+ /**
26
+ * Check if running in test environment.
27
+ */
28
+ declare function isTest(): boolean;
29
+ /**
30
+ * Check if running on the server (not browser).
31
+ */
32
+ declare function isServer(): boolean;
33
+ /**
34
+ * Check if running in the browser.
35
+ */
36
+ declare function isBrowser(): boolean;
37
+ /**
38
+ * Get the current environment name.
39
+ */
40
+ declare function getEnvironment(): 'production' | 'development' | 'test' | 'unknown';
41
+
42
+ export { getEnvironment, isBrowser, isDevelopment, isProduction, isServer, isTest };
@@ -0,0 +1,4 @@
1
+ import '../chunk-PL37KFRJ.js';
2
+ export { getEnvironment, isBrowser, isDevelopment, isProduction, isServer, isTest } from '../chunk-LWVETFJV.js';
3
+ //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map