@timber-js/app 0.2.0-alpha.23 → 0.2.0-alpha.24

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-render.d.ts","sourceRoot":"","sources":["../../src/server/ssr-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AA0DvC;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,SAAS,EAClB,OAAO,CAAC,EAAE;IAAE,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GAC7F,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAKrC;AAkHD;;;;;;;;;;;;GAYG;AACH,2CAA2C;AAC3C,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,MAAM,CAAC,EAAE,WAAW,GACnB,cAAc,CAAC,UAAU,CAAC,CA2B5B;AAWD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,cAAc,CAAC,UAAU,CAAC,EACtC,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,OAAO,GACvB,QAAQ,CASV"}
1
+ {"version":3,"file":"ssr-render.d.ts","sourceRoot":"","sources":["../../src/server/ssr-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAqEvC;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,SAAS,EAClB,OAAO,CAAC,EAAE;IAAE,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,GAC7F,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAKrC;AAkHD;;;;;;;;;;;;GAYG;AACH,2CAA2C;AAC3C,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,MAAM,CAAC,EAAE,WAAW,GACnB,cAAc,CAAC,UAAU,CAAC,CA2B5B;AAWD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,cAAc,CAAC,UAAU,CAAC,EACtC,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,OAAO,GACvB,QAAQ,CASV"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timber-js/app",
3
- "version": "0.2.0-alpha.23",
3
+ "version": "0.2.0-alpha.24",
4
4
  "description": "Vite-native React framework for Cloudflare Workers — correct HTTP semantics, real status codes, pages that work without JavaScript",
5
5
  "keywords": [
6
6
  "cloudflare-workers",
@@ -21,7 +21,7 @@
21
21
  */
22
22
 
23
23
  import type { ReactNode } from 'react';
24
- import { renderToReadableStream, renderToPipeableStream } from 'react-dom/server';
24
+ import { renderToReadableStream } from 'react-dom/server';
25
25
 
26
26
  import { formatSsrError } from './error-formatter.js';
27
27
 
@@ -54,9 +54,11 @@ const NOINDEX_SCRIPT =
54
54
  let _useNodeStreams = false;
55
55
  let _PassThrough: typeof import('node:stream').PassThrough | null = null;
56
56
  let _ReadableToWeb: ((readable: import('node:stream').Readable) => ReadableStream) | null = null;
57
+ let _renderToPipeableStream: typeof import('react-dom/server').renderToPipeableStream | null = null;
57
58
 
58
59
  try {
59
- // Dynamic import to avoid bundling node:stream for CF Workers builds.
60
+ // Dynamic imports to avoid bundling node:stream and the Node.js-specific
61
+ // react-dom/server entry for CF Workers builds.
60
62
  // On Node.js/Bun this resolves to native C++ streams.
61
63
  // On CF Workers this either fails or returns a JS polyfill.
62
64
  const nodeStream = await import('node:stream');
@@ -68,14 +70,23 @@ try {
68
70
  typeof process !== 'undefined' &&
69
71
  process.release?.name === 'node'
70
72
  ) {
71
- _useNodeStreams = true;
72
- _PassThrough = nodeStream.PassThrough;
73
- _ReadableToWeb = nodeStream.Readable.toWeb as (
74
- readable: import('node:stream').Readable
75
- ) => ReadableStream;
73
+ // Dynamically import renderToPipeableStream from the Node.js-specific
74
+ // entry point. The SSR bundle resolves react-dom/server to the edge/browser
75
+ // export (which lacks renderToPipeableStream), so we import the .node file
76
+ // directly. This is safe because we're inside a process.release.name === 'node'
77
+ // guard — this code only runs on real Node.js.
78
+ const reactDomServer = await import('react-dom/server.node');
79
+ if (typeof reactDomServer.renderToPipeableStream === 'function') {
80
+ _useNodeStreams = true;
81
+ _PassThrough = nodeStream.PassThrough;
82
+ _ReadableToWeb = nodeStream.Readable.toWeb as (
83
+ readable: import('node:stream').Readable
84
+ ) => ReadableStream;
85
+ _renderToPipeableStream = reactDomServer.renderToPipeableStream;
86
+ }
76
87
  }
77
88
  } catch {
78
- // node:stream not available — use Web Streams path
89
+ // node:stream or renderToPipeableStream not available — use Web Streams path
79
90
  }
80
91
 
81
92
  /**
@@ -127,7 +138,7 @@ async function renderViaPipeableStream(
127
138
  // Suppress unhandled rejection if nobody awaits allReady
128
139
  allReady.catch(() => {});
129
140
 
130
- const { pipe, abort } = renderToPipeableStream(element, {
141
+ const { pipe, abort } = _renderToPipeableStream!(element, {
131
142
  bootstrapScriptContent: options?.bootstrapScriptContent || undefined,
132
143
 
133
144
  onShellReady() {