partial-react 0.0.3 → 0.0.5
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/README.md +6 -0
- package/package.json +3 -3
- package/src/compiler.ts +3 -3
- package/src/importProbe.ts +4 -1
- package/src/runtime.ts +6 -2
package/README.md
CHANGED
|
@@ -36,6 +36,12 @@ import { mergeFallbackImports, prepareRendererImportMap } from "partial-react/im
|
|
|
36
36
|
import { useGenUIRenderContext } from "partial-react/render-context";
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
+
## Bundlers
|
|
40
|
+
|
|
41
|
+
The loader's `import()` specifiers are computed at runtime — a blob URL for the generated module, import-map targets for its dependencies — so no bundler may resolve them at build time. They carry `@vite-ignore`, `webpackIgnore: true`, and `turbopackIgnore: true` together, which covers Vite, webpack/Rspack, and Turbopack (Next.js); if you re-emit this source through a tool that strips comments, preserve those three.
|
|
42
|
+
|
|
43
|
+
Turbopack builds also need [#1690](https://github.com/MindLab-Research/macaron-genui-demo/issues/1690): `compiler.ts` loads the tsx wasm through Vite's `?url` query, which Turbopack rejects. Until that lands, Next.js consumers still need to patch that import.
|
|
44
|
+
|
|
39
45
|
## State and Streaming
|
|
40
46
|
|
|
41
47
|
- Keep `preserveStateOnUpdate: true` for normal previews. It preserves useful React state and DOM continuity across regenerated code.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "partial-react",
|
|
3
3
|
"description": "A state-preserving renderer for prefix-growing streaming React/TSX.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.5",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"partial-tsx": "0.0.3"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"react": "^19.0.0",
|
|
28
|
-
"react-dom": "^19.0.0"
|
|
27
|
+
"react": "^18.3.0 || ^19.0.0",
|
|
28
|
+
"react-dom": "^18.3.0 || ^19.0.0"
|
|
29
29
|
},
|
|
30
30
|
"sideEffects": false
|
|
31
31
|
}
|
package/src/compiler.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import initTsx, { transform as transformTsx } from "@esm.sh/tsx";
|
|
2
|
-
import tsxWasmUrl from "@esm.sh/tsx/pkg/tsx_bg.wasm?url";
|
|
3
2
|
import { normalizeGeneratedTsx } from "partial-tsx";
|
|
4
3
|
import { rewriteImportMetaResolveSpecifiers, type RendererImportMap } from "./importMap";
|
|
5
4
|
|
|
@@ -19,9 +18,10 @@ const initCompiler = () =>
|
|
|
19
18
|
try {
|
|
20
19
|
if (typeof window === "undefined") return initTsx(await loadNodeWasm());
|
|
21
20
|
} catch {
|
|
22
|
-
// Environments without a filesystem (e.g. web workers) fall back to
|
|
21
|
+
// Environments without a filesystem (e.g. web workers) fall back to the bundled asset below.
|
|
23
22
|
}
|
|
24
|
-
|
|
23
|
+
// No argument: wasm-bindgen resolves `new URL("tsx_bg.wasm", import.meta.url)`, which every bundler understands — a Vite-only `?url` import here broke the rest. #1690
|
|
24
|
+
return initTsx();
|
|
25
25
|
})().catch((error) => {
|
|
26
26
|
initPromise = null;
|
|
27
27
|
throw error;
|
package/src/importProbe.ts
CHANGED
|
@@ -41,7 +41,10 @@ export async function probeModuleImports(code: string, imports?: Record<string,
|
|
|
41
41
|
const specifier = reverseResolveSpecifier(importEntries, target);
|
|
42
42
|
let module: Record<string, unknown>;
|
|
43
43
|
try {
|
|
44
|
-
|
|
44
|
+
// `target` is import-map-resolved at runtime, so it needs the same three-bundler ignore stack as the blob import
|
|
45
|
+
// in runtime.ts — otherwise every probe throws `Cannot find module 'unknown'` and reports each dependency as
|
|
46
|
+
// broken, burying the one that actually is. #1688
|
|
47
|
+
module = (await import(/* @vite-ignore */ /* webpackIgnore: true */ /* turbopackIgnore: true */ target)) as Record<string, unknown>;
|
|
45
48
|
} catch (error) {
|
|
46
49
|
return { specifier, target, detail: `failed to load: ${error instanceof Error ? error.message : String(error)}` };
|
|
47
50
|
}
|
package/src/runtime.ts
CHANGED
|
@@ -346,7 +346,10 @@ export class GenUIRenderer {
|
|
|
346
346
|
try {
|
|
347
347
|
let module: { default?: GeneratedComponent };
|
|
348
348
|
try {
|
|
349
|
-
|
|
349
|
+
// The specifier is a runtime-built blob URL, so every bundler must leave it alone: @vite-ignore for Vite,
|
|
350
|
+
// webpackIgnore for webpack/Rspack, turbopackIgnore for Turbopack. Dropping any of them makes the host bundler
|
|
351
|
+
// resolve it at build time and the renderer dies with `Cannot find module 'unknown'`. #1688
|
|
352
|
+
module = (await import(/* @vite-ignore */ /* webpackIgnore: true */ /* turbopackIgnore: true */ moduleUrl)) as { default?: GeneratedComponent };
|
|
350
353
|
} catch (error) {
|
|
351
354
|
// The browser reports a failed blob module as one opaque "Failed to fetch dynamically imported module" without
|
|
352
355
|
// naming the entry that broke; re-probe each dependency to raise an actionable, heal-ready error instead. #1371
|
|
@@ -419,7 +422,8 @@ export class GenUIRenderer {
|
|
|
419
422
|
createElement(
|
|
420
423
|
RuntimeErrorBoundary,
|
|
421
424
|
{ key: preserve ? getPreserveBoundaryKey(this.preserveBoundaryEpoch) : `boundary:${this.renderRound}`, resetKey: this.errorEpoch, onError: onRenderError },
|
|
422
|
-
|
|
425
|
+
// The cast wraps the whole ternary: @types/react 18 rejects the slot's `Promise<ReactNode>` return, and we ship raw .ts to 18.3 peers.
|
|
426
|
+
createElement(GenUIRenderContext.Provider, { value: renderContext }, createElement((preserve ? this.slot.Component : renderedComponent) as ComponentType<Record<string, unknown>>, { key: "generated-component" })),
|
|
423
427
|
createElement(RenderNotify, {
|
|
424
428
|
key: `render-notify:${this.renderRound}`,
|
|
425
429
|
onCommit: () => {
|