ai-props 2.1.3 → 2.3.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.
Files changed (73) hide show
  1. package/.dev.vars +2 -0
  2. package/CHANGELOG.md +11 -0
  3. package/README.md +2 -0
  4. package/package.json +39 -13
  5. package/src/ai.ts +12 -31
  6. package/src/cascade.ts +795 -0
  7. package/src/client.ts +440 -0
  8. package/src/durable-cascade.ts +743 -0
  9. package/src/event-bridge.ts +478 -0
  10. package/src/generate.ts +14 -12
  11. package/src/hoc.ts +15 -19
  12. package/src/hono-jsx.ts +675 -0
  13. package/src/index.ts +30 -0
  14. package/src/mdx-types.ts +169 -0
  15. package/src/mdx-utils.ts +437 -0
  16. package/src/mdx.ts +1008 -0
  17. package/src/rpc.ts +614 -0
  18. package/src/streaming.ts +618 -0
  19. package/src/validate.ts +15 -29
  20. package/src/worker.ts +547 -0
  21. package/test/cascade.test.ts +338 -0
  22. package/test/durable-cascade.test.ts +319 -0
  23. package/test/event-bridge.test.ts +351 -0
  24. package/test/generate.test.ts +6 -16
  25. package/test/mdx.test.ts +817 -0
  26. package/test/worker/capnweb-rpc.test.ts +1084 -0
  27. package/test/worker/full-flow.integration.test.ts +1463 -0
  28. package/test/worker/hono-jsx.test.ts +1258 -0
  29. package/test/worker/mdx-parsing.test.ts +1148 -0
  30. package/test/worker/setup.ts +56 -0
  31. package/test/worker.test.ts +595 -0
  32. package/tsconfig.json +2 -1
  33. package/vitest.config.js +6 -0
  34. package/vitest.config.ts +15 -1
  35. package/vitest.workers.config.ts +58 -0
  36. package/wrangler.jsonc +27 -0
  37. package/.turbo/turbo-build.log +0 -4
  38. package/LICENSE +0 -21
  39. package/dist/ai.d.ts +0 -125
  40. package/dist/ai.d.ts.map +0 -1
  41. package/dist/ai.js +0 -199
  42. package/dist/ai.js.map +0 -1
  43. package/dist/cache.d.ts +0 -66
  44. package/dist/cache.d.ts.map +0 -1
  45. package/dist/cache.js +0 -183
  46. package/dist/cache.js.map +0 -1
  47. package/dist/generate.d.ts +0 -69
  48. package/dist/generate.d.ts.map +0 -1
  49. package/dist/generate.js +0 -221
  50. package/dist/generate.js.map +0 -1
  51. package/dist/hoc.d.ts +0 -164
  52. package/dist/hoc.d.ts.map +0 -1
  53. package/dist/hoc.js +0 -236
  54. package/dist/hoc.js.map +0 -1
  55. package/dist/index.d.ts +0 -15
  56. package/dist/index.d.ts.map +0 -1
  57. package/dist/index.js +0 -21
  58. package/dist/index.js.map +0 -1
  59. package/dist/types.d.ts +0 -152
  60. package/dist/types.d.ts.map +0 -1
  61. package/dist/types.js +0 -7
  62. package/dist/types.js.map +0 -1
  63. package/dist/validate.d.ts +0 -58
  64. package/dist/validate.d.ts.map +0 -1
  65. package/dist/validate.js +0 -253
  66. package/dist/validate.js.map +0 -1
  67. package/src/ai.js +0 -198
  68. package/src/cache.js +0 -182
  69. package/src/generate.js +0 -220
  70. package/src/hoc.js +0 -235
  71. package/src/index.js +0 -20
  72. package/src/types.js +0 -6
  73. package/src/validate.js +0 -252
@@ -0,0 +1,618 @@
1
+ /**
2
+ * Optimized streaming utilities for AI-powered props rendering
3
+ *
4
+ * This module provides high-performance streaming capabilities with:
5
+ * - Adaptive chunk sizing for network efficiency
6
+ * - Backpressure handling to prevent memory overflow
7
+ * - Progress callbacks for streaming status
8
+ * - Memory-efficient streaming for large components
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+
13
+ import {
14
+ renderToReadableStream as baseRenderToReadableStream,
15
+ streamJSXResponse as baseStreamJSXResponse,
16
+ createStreamingRenderer as baseCreateStreamingRenderer,
17
+ createHydrationContext,
18
+ serializeHydrationData,
19
+ type StreamingOptions,
20
+ type StreamingRendererOptions,
21
+ type HydrationContext,
22
+ type HydrationData,
23
+ type HydrationNode,
24
+ } from './hono-jsx.js'
25
+
26
+ import { streamMDXWithProps as baseStreamMDXWithProps, type StreamMDXOptions } from './mdx.js'
27
+
28
+ // ============================================================================
29
+ // Constants
30
+ // ============================================================================
31
+
32
+ /** Default chunk size for optimal network performance (16KB) */
33
+ export const DEFAULT_CHUNK_SIZE = 16 * 1024
34
+
35
+ /** Minimum chunk size to avoid excessive overhead (1KB) */
36
+ export const MIN_CHUNK_SIZE = 1024
37
+
38
+ /** Maximum chunk size for memory efficiency (64KB) */
39
+ export const MAX_CHUNK_SIZE = 64 * 1024
40
+
41
+ /** High water mark for backpressure (64KB) */
42
+ export const DEFAULT_HIGH_WATER_MARK = 64 * 1024
43
+
44
+ // ============================================================================
45
+ // Types
46
+ // ============================================================================
47
+
48
+ /**
49
+ * Progress information during streaming
50
+ */
51
+ export interface StreamingProgress {
52
+ /** Total bytes processed so far */
53
+ bytesProcessed: number
54
+ /** Total bytes expected (if known) */
55
+ totalBytes?: number
56
+ /** Number of chunks sent */
57
+ chunksProcessed: number
58
+ /** Percentage complete (0-100, if total is known) */
59
+ percentComplete?: number
60
+ /** Current streaming phase */
61
+ phase: 'starting' | 'streaming' | 'hydration' | 'complete' | 'error'
62
+ /** Time elapsed in milliseconds */
63
+ elapsedMs: number
64
+ }
65
+
66
+ /**
67
+ * Progress callback function type
68
+ */
69
+ export type StreamingProgressCallback = (progress: StreamingProgress) => void
70
+
71
+ /**
72
+ * Enhanced streaming options with optimization controls
73
+ */
74
+ export interface OptimizedStreamingOptions extends StreamingOptions {
75
+ /** Chunk size in bytes (default: 16KB) */
76
+ chunkSize?: number
77
+ /** High water mark for backpressure (default: 64KB) */
78
+ highWaterMark?: number
79
+ /** Progress callback for streaming updates */
80
+ onProgress?: StreamingProgressCallback
81
+ /** Timeout in milliseconds (default: 30000) */
82
+ timeout?: number
83
+ /** Enable compression hints for response */
84
+ compressionHint?: boolean
85
+ /** Flush chunks immediately without buffering */
86
+ flushImmediate?: boolean
87
+ }
88
+
89
+ /**
90
+ * Enhanced streaming renderer options
91
+ */
92
+ export interface OptimizedStreamingRendererOptions extends StreamingRendererOptions {
93
+ /** Chunk size in bytes */
94
+ chunkSize?: number
95
+ /** High water mark for backpressure */
96
+ highWaterMark?: number
97
+ /** Progress callback */
98
+ onProgress?: StreamingProgressCallback
99
+ }
100
+
101
+ /**
102
+ * Streaming statistics for monitoring
103
+ */
104
+ export interface StreamingStats {
105
+ /** Total bytes streamed */
106
+ totalBytes: number
107
+ /** Number of chunks sent */
108
+ totalChunks: number
109
+ /** Average chunk size */
110
+ averageChunkSize: number
111
+ /** Time to first byte in ms */
112
+ timeToFirstByte: number
113
+ /** Total streaming duration in ms */
114
+ totalDuration: number
115
+ /** Whether backpressure was encountered */
116
+ encounteredBackpressure: boolean
117
+ }
118
+
119
+ // ============================================================================
120
+ // Utility Functions
121
+ // ============================================================================
122
+
123
+ /**
124
+ * Calculate optimal chunk size based on content size
125
+ *
126
+ * @param contentLength - Total content length in bytes
127
+ * @returns Optimal chunk size
128
+ */
129
+ export function calculateOptimalChunkSize(contentLength: number): number {
130
+ // For very small content, use minimum chunk size
131
+ if (contentLength < MIN_CHUNK_SIZE * 2) {
132
+ return MIN_CHUNK_SIZE
133
+ }
134
+
135
+ // For medium content, use default
136
+ if (contentLength < MAX_CHUNK_SIZE * 4) {
137
+ return DEFAULT_CHUNK_SIZE
138
+ }
139
+
140
+ // For large content, use larger chunks
141
+ return MAX_CHUNK_SIZE
142
+ }
143
+
144
+ /**
145
+ * Create a progress tracker for streaming operations
146
+ */
147
+ function createProgressTracker(
148
+ totalBytes: number | undefined,
149
+ onProgress?: StreamingProgressCallback
150
+ ): {
151
+ update: (
152
+ bytesProcessed: number,
153
+ chunksProcessed: number,
154
+ phase: StreamingProgress['phase']
155
+ ) => void
156
+ startTime: number
157
+ } {
158
+ const startTime = Date.now()
159
+
160
+ return {
161
+ startTime,
162
+ update(bytesProcessed: number, chunksProcessed: number, phase: StreamingProgress['phase']) {
163
+ if (!onProgress) return
164
+
165
+ const elapsedMs = Date.now() - startTime
166
+ const progress: StreamingProgress = {
167
+ bytesProcessed,
168
+ chunksProcessed,
169
+ phase,
170
+ elapsedMs,
171
+ }
172
+
173
+ if (totalBytes !== undefined) {
174
+ progress.totalBytes = totalBytes
175
+ progress.percentComplete = Math.min(100, (bytesProcessed / totalBytes) * 100)
176
+ }
177
+
178
+ onProgress(progress)
179
+ },
180
+ }
181
+ }
182
+
183
+ // ============================================================================
184
+ // Core Streaming Functions
185
+ // ============================================================================
186
+
187
+ /**
188
+ * Render a component to a ReadableStream with optimizations
189
+ *
190
+ * Features:
191
+ * - Adaptive chunk sizing based on content
192
+ * - Backpressure handling to prevent memory overflow
193
+ * - Progress callbacks for monitoring
194
+ * - Memory-efficient streaming for large content
195
+ *
196
+ * @param component - Component function to render
197
+ * @param props - Props to pass to component
198
+ * @param options - Optimized streaming options
199
+ * @returns ReadableStream of rendered HTML
200
+ *
201
+ * @example
202
+ * ```ts
203
+ * const stream = await renderToReadableStream(
204
+ * MyComponent,
205
+ * { title: 'Hello' },
206
+ * {
207
+ * chunkSize: 8192,
208
+ * onProgress: (progress) => console.log(`${progress.percentComplete}% complete`),
209
+ * }
210
+ * )
211
+ * ```
212
+ */
213
+ export async function renderToReadableStream<P>(
214
+ component: (props: P) => string | Promise<string>,
215
+ props: P,
216
+ options?: OptimizedStreamingOptions
217
+ ): Promise<ReadableStream<Uint8Array>> {
218
+ const encoder = new TextEncoder()
219
+ const chunkSize = options?.chunkSize ?? DEFAULT_CHUNK_SIZE
220
+ const highWaterMark = options?.highWaterMark ?? DEFAULT_HIGH_WATER_MARK
221
+
222
+ // Create hydration context if needed
223
+ let hydrationContext: HydrationContext | null = null
224
+ if (options?.includeHydration) {
225
+ hydrationContext = createHydrationContext()
226
+ }
227
+
228
+ // Render the component
229
+ let content: string
230
+ try {
231
+ content = await component(props)
232
+ } catch (error) {
233
+ if (options?.onError && error instanceof Error) {
234
+ content = options.onError(error)
235
+ } else {
236
+ throw error
237
+ }
238
+ }
239
+
240
+ // Register for hydration
241
+ if (hydrationContext) {
242
+ const componentName = component.name || 'Anonymous'
243
+ hydrationContext.register(componentName, props as Record<string, unknown>)
244
+ }
245
+
246
+ // Prepare hydration script
247
+ let hydrationScript = ''
248
+ if (options?.includeHydration && hydrationContext) {
249
+ const hydrationData = hydrationContext.getData()
250
+ hydrationScript = `<script>window.__HYDRATION_DATA__=${serializeHydrationData(
251
+ hydrationData
252
+ )}</script>`
253
+ }
254
+
255
+ const fullContent = content + hydrationScript
256
+ const contentBytes = encoder.encode(fullContent)
257
+ const totalLength = contentBytes.length
258
+
259
+ // Calculate optimal chunk size if not specified
260
+ const effectiveChunkSize = options?.chunkSize ?? calculateOptimalChunkSize(totalLength)
261
+
262
+ // Create progress tracker
263
+ const tracker = createProgressTracker(totalLength, options?.onProgress)
264
+
265
+ let bytesProcessed = 0
266
+ let chunksProcessed = 0
267
+ let offset = 0
268
+
269
+ tracker.update(0, 0, 'starting')
270
+
271
+ return new ReadableStream<Uint8Array>(
272
+ {
273
+ pull(controller) {
274
+ // Check if we're done
275
+ if (offset >= totalLength) {
276
+ tracker.update(bytesProcessed, chunksProcessed, 'complete')
277
+ controller.close()
278
+ return
279
+ }
280
+
281
+ // Calculate chunk end
282
+ const end = Math.min(offset + effectiveChunkSize, totalLength)
283
+ const chunk = contentBytes.slice(offset, end)
284
+
285
+ controller.enqueue(chunk)
286
+
287
+ bytesProcessed += chunk.length
288
+ chunksProcessed++
289
+ offset = end
290
+
291
+ tracker.update(bytesProcessed, chunksProcessed, 'streaming')
292
+ },
293
+
294
+ cancel() {
295
+ tracker.update(bytesProcessed, chunksProcessed, 'error')
296
+ },
297
+ },
298
+ // Queuing strategy for backpressure
299
+ new ByteLengthQueuingStrategy({ highWaterMark })
300
+ )
301
+ }
302
+
303
+ /**
304
+ * Create a streaming Response with optimizations
305
+ *
306
+ * @param component - Component function to render
307
+ * @param props - Props to pass to component
308
+ * @param options - Optimized streaming options
309
+ * @returns Response with streaming body
310
+ *
311
+ * @example
312
+ * ```ts
313
+ * // In a Hono/Worker handler
314
+ * export default {
315
+ * fetch(request, env) {
316
+ * return streamJSXResponse(
317
+ * PageComponent,
318
+ * { data: pageData },
319
+ * {
320
+ * streaming: true,
321
+ * compressionHint: true,
322
+ * }
323
+ * )
324
+ * }
325
+ * }
326
+ * ```
327
+ */
328
+ export async function streamJSXResponse<P>(
329
+ component: (props: P) => string | Promise<string>,
330
+ props: P,
331
+ options?: OptimizedStreamingOptions
332
+ ): Promise<Response> {
333
+ const stream = await renderToReadableStream(component, props, options)
334
+
335
+ const headers = new Headers({
336
+ 'Content-Type': 'text/html; charset=utf-8',
337
+ 'X-Content-Type-Options': 'nosniff',
338
+ ...options?.headers,
339
+ })
340
+
341
+ // Add streaming hints
342
+ if (options?.streaming) {
343
+ headers.set('Transfer-Encoding', 'chunked')
344
+ }
345
+
346
+ // Add compression hint
347
+ if (options?.compressionHint) {
348
+ headers.set('Vary', 'Accept-Encoding')
349
+ }
350
+
351
+ return new Response(stream, {
352
+ status: 200,
353
+ headers,
354
+ })
355
+ }
356
+
357
+ /**
358
+ * Create a reusable streaming renderer with configuration
359
+ *
360
+ * @param options - Renderer options with optimization controls
361
+ * @returns Streaming renderer instance with stats
362
+ *
363
+ * @example
364
+ * ```ts
365
+ * const renderer = createStreamingRenderer({
366
+ * doctype: '<!DOCTYPE html>',
367
+ * includeHydration: true,
368
+ * chunkSize: 8192,
369
+ * onProgress: (p) => console.log(p.phase),
370
+ * })
371
+ *
372
+ * const stream = await renderer.render(MyComponent, props)
373
+ * const stats = renderer.getStats()
374
+ * ```
375
+ */
376
+ export function createStreamingRenderer(options: OptimizedStreamingRendererOptions): {
377
+ render: <P>(
378
+ component: (props: P) => string | Promise<string>,
379
+ props: P
380
+ ) => Promise<ReadableStream<Uint8Array>>
381
+ getStats: () => StreamingStats | null
382
+ resetStats: () => void
383
+ } {
384
+ const encoder = new TextEncoder()
385
+ const chunkSize = options.chunkSize ?? DEFAULT_CHUNK_SIZE
386
+ const highWaterMark = options.highWaterMark ?? DEFAULT_HIGH_WATER_MARK
387
+
388
+ // Stats tracking
389
+ let currentStats: StreamingStats | null = null
390
+
391
+ return {
392
+ async render<P>(
393
+ component: (props: P) => string | Promise<string>,
394
+ props: P
395
+ ): Promise<ReadableStream<Uint8Array>> {
396
+ const startTime = Date.now()
397
+ let timeToFirstByte = 0
398
+ let totalBytes = 0
399
+ let totalChunks = 0
400
+ let encounteredBackpressure = false
401
+
402
+ // Create hydration context
403
+ const ctx = options.includeHydration ? createHydrationContext() : null
404
+
405
+ // Render the component
406
+ const content = await component(props)
407
+
408
+ // Register for hydration data
409
+ if (ctx) {
410
+ const componentName = component.name || 'Anonymous'
411
+ ctx.register(componentName, props as Record<string, unknown>)
412
+ }
413
+
414
+ // Get hydration data
415
+ let hydrationJson = ''
416
+ if (options.includeHydration && ctx) {
417
+ hydrationJson = serializeHydrationData(ctx.getData())
418
+ }
419
+
420
+ // Apply shell wrapper if provided
421
+ let output: string
422
+ if (options.shell) {
423
+ const hydrationScript = hydrationJson ? `window.__HYDRATION_DATA__=${hydrationJson}` : ''
424
+ output = options.shell(content, hydrationScript)
425
+ } else {
426
+ output = content
427
+ if (options.includeHydration && hydrationJson) {
428
+ output += `<script>window.__HYDRATION_DATA__=${hydrationJson}</script>`
429
+ }
430
+ }
431
+
432
+ // Prepend doctype if provided
433
+ if (options.doctype) {
434
+ output = options.doctype + '\n' + output
435
+ }
436
+
437
+ const contentBytes = encoder.encode(output)
438
+ const contentLength = contentBytes.length
439
+
440
+ // Create progress tracker
441
+ const tracker = createProgressTracker(contentLength, options.onProgress)
442
+ tracker.update(0, 0, 'starting')
443
+
444
+ let offset = 0
445
+
446
+ return new ReadableStream<Uint8Array>(
447
+ {
448
+ pull(controller) {
449
+ // Track time to first byte
450
+ if (totalChunks === 0) {
451
+ timeToFirstByte = Date.now() - startTime
452
+ }
453
+
454
+ if (offset >= contentLength) {
455
+ // Finalize stats
456
+ currentStats = {
457
+ totalBytes,
458
+ totalChunks,
459
+ averageChunkSize: totalChunks > 0 ? totalBytes / totalChunks : 0,
460
+ timeToFirstByte,
461
+ totalDuration: Date.now() - startTime,
462
+ encounteredBackpressure,
463
+ }
464
+
465
+ tracker.update(totalBytes, totalChunks, 'complete')
466
+ controller.close()
467
+ return
468
+ }
469
+
470
+ const end = Math.min(offset + chunkSize, contentLength)
471
+ const chunk = contentBytes.slice(offset, end)
472
+
473
+ controller.enqueue(chunk)
474
+
475
+ totalBytes += chunk.length
476
+ totalChunks++
477
+ offset = end
478
+
479
+ tracker.update(totalBytes, totalChunks, 'streaming')
480
+ },
481
+
482
+ cancel() {
483
+ tracker.update(totalBytes, totalChunks, 'error')
484
+ },
485
+ },
486
+ new ByteLengthQueuingStrategy({ highWaterMark })
487
+ )
488
+ },
489
+
490
+ getStats(): StreamingStats | null {
491
+ return currentStats
492
+ },
493
+
494
+ resetStats(): void {
495
+ currentStats = null
496
+ },
497
+ }
498
+ }
499
+
500
+ /**
501
+ * Stream MDX content with AI-generated props and optimizations
502
+ *
503
+ * @param mdx - MDX content string
504
+ * @param props - Props for each component
505
+ * @param options - Stream options with optimizations
506
+ * @returns ReadableStream of rendered content
507
+ *
508
+ * @example
509
+ * ```ts
510
+ * const stream = await streamMDXWithProps(
511
+ * '<Hero title="Welcome" />',
512
+ * { Hero: { title: 'Welcome', subtitle: 'To the site' } },
513
+ * {
514
+ * chunkSize: 8192,
515
+ * onProgress: (p) => console.log(`${p.chunksProcessed} chunks sent`),
516
+ * }
517
+ * )
518
+ * ```
519
+ */
520
+ export async function streamMDXWithProps(
521
+ mdx: string,
522
+ props: Record<string, Record<string, unknown>>,
523
+ options?: StreamMDXOptions & {
524
+ chunkSize?: number
525
+ highWaterMark?: number
526
+ onProgress?: StreamingProgressCallback
527
+ }
528
+ ): Promise<ReadableStream<Uint8Array>> {
529
+ // Get base stream from mdx module
530
+ const baseStream = await baseStreamMDXWithProps(mdx, props, options)
531
+
532
+ // If no optimization options, return base stream
533
+ if (!options?.chunkSize && !options?.highWaterMark && !options?.onProgress) {
534
+ return baseStream
535
+ }
536
+
537
+ // Apply optimizations by re-chunking the stream
538
+ const reader = baseStream.getReader()
539
+ const encoder = new TextEncoder()
540
+ const chunkSize = options?.chunkSize ?? DEFAULT_CHUNK_SIZE
541
+ const highWaterMark = options?.highWaterMark ?? DEFAULT_HIGH_WATER_MARK
542
+
543
+ // Buffer for accumulating content
544
+ let buffer = new Uint8Array(0)
545
+ let bytesProcessed = 0
546
+ let chunksProcessed = 0
547
+
548
+ const tracker = createProgressTracker(undefined, options?.onProgress)
549
+ tracker.update(0, 0, 'starting')
550
+
551
+ return new ReadableStream<Uint8Array>(
552
+ {
553
+ async pull(controller) {
554
+ // Read from source stream
555
+ const { done, value } = await reader.read()
556
+
557
+ if (done) {
558
+ // Flush remaining buffer
559
+ if (buffer.length > 0) {
560
+ controller.enqueue(buffer)
561
+ bytesProcessed += buffer.length
562
+ chunksProcessed++
563
+ }
564
+ tracker.update(bytesProcessed, chunksProcessed, 'complete')
565
+ controller.close()
566
+ return
567
+ }
568
+
569
+ // Append to buffer
570
+ const newBuffer = new Uint8Array(buffer.length + value.length)
571
+ newBuffer.set(buffer)
572
+ newBuffer.set(value, buffer.length)
573
+ buffer = newBuffer
574
+
575
+ // Emit full chunks
576
+ while (buffer.length >= chunkSize) {
577
+ const chunk = buffer.slice(0, chunkSize)
578
+ controller.enqueue(chunk)
579
+ buffer = buffer.slice(chunkSize)
580
+
581
+ bytesProcessed += chunk.length
582
+ chunksProcessed++
583
+ tracker.update(bytesProcessed, chunksProcessed, 'streaming')
584
+ }
585
+ },
586
+
587
+ cancel() {
588
+ reader.cancel()
589
+ tracker.update(bytesProcessed, chunksProcessed, 'error')
590
+ },
591
+ },
592
+ new ByteLengthQueuingStrategy({ highWaterMark })
593
+ )
594
+ }
595
+
596
+ // ============================================================================
597
+ // Re-exports from hono-jsx for convenience
598
+ // ============================================================================
599
+
600
+ export {
601
+ createHydrationContext,
602
+ serializeHydrationData,
603
+ collectHydrationData,
604
+ HydrationProvider,
605
+ useHydration,
606
+ type HydrationContext,
607
+ type HydrationData,
608
+ type HydrationNode,
609
+ type StreamingOptions,
610
+ type StreamingRendererOptions,
611
+ } from './hono-jsx.js'
612
+
613
+ // Re-export base functions with different names for direct access
614
+ export {
615
+ baseRenderToReadableStream as renderToReadableStreamBasic,
616
+ baseStreamJSXResponse as streamJSXResponseBasic,
617
+ baseCreateStreamingRenderer as createStreamingRendererBasic,
618
+ }