@takazudo/zfb 2.22.0 → 3.0.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 (85) hide show
  1. package/README.md +5 -9
  2. package/dist/config.d.ts +62 -19
  3. package/dist/config.js +27 -6
  4. package/dist/config.js.map +1 -1
  5. package/dist/content.d.ts +8 -22
  6. package/dist/content.js +6 -28
  7. package/dist/content.js.map +1 -1
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.js +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/island-boundary.d.ts +4 -0
  12. package/dist/island-boundary.js +42 -0
  13. package/dist/island-boundary.js.map +1 -0
  14. package/dist/island.d.ts +2 -118
  15. package/dist/island.js +4 -284
  16. package/dist/island.js.map +1 -1
  17. package/dist/jsx-types.d.ts +2 -38
  18. package/dist/jsx-types.js +3 -10
  19. package/dist/jsx-types.js.map +1 -1
  20. package/dist/plugins.d.ts +40 -0
  21. package/dist/plugins.js.map +1 -1
  22. package/dist/runtime.d.ts +23 -77
  23. package/dist/runtime.js +149 -320
  24. package/dist/runtime.js.map +1 -1
  25. package/dist/zudo-react/client.d.ts +3 -0
  26. package/dist/zudo-react/client.js +3 -0
  27. package/dist/zudo-react/client.js.map +1 -0
  28. package/dist/zudo-react/description.d.ts +16 -0
  29. package/dist/zudo-react/description.js +64 -0
  30. package/dist/zudo-react/description.js.map +1 -0
  31. package/dist/zudo-react/dom-bindings.d.ts +13 -0
  32. package/dist/zudo-react/dom-bindings.js +58 -0
  33. package/dist/zudo-react/dom-bindings.js.map +1 -0
  34. package/dist/zudo-react/escape.d.ts +2 -0
  35. package/dist/zudo-react/escape.js +7 -0
  36. package/dist/zudo-react/escape.js.map +1 -0
  37. package/dist/zudo-react/forms.d.ts +29 -0
  38. package/dist/zudo-react/forms.js +371 -0
  39. package/dist/zudo-react/forms.js.map +1 -0
  40. package/dist/zudo-react/hydrate.d.ts +4 -0
  41. package/dist/zudo-react/hydrate.js +909 -0
  42. package/dist/zudo-react/hydrate.js.map +1 -0
  43. package/dist/zudo-react/index.d.ts +47 -0
  44. package/dist/zudo-react/index.js +13 -0
  45. package/dist/zudo-react/index.js.map +1 -0
  46. package/dist/zudo-react/island-root-type.d.ts +1 -0
  47. package/dist/zudo-react/island-root-type.js +2 -0
  48. package/dist/zudo-react/island-root-type.js.map +1 -0
  49. package/dist/zudo-react/jsx-dev-runtime.d.ts +8 -0
  50. package/dist/zudo-react/jsx-dev-runtime.js +6 -0
  51. package/dist/zudo-react/jsx-dev-runtime.js.map +1 -0
  52. package/dist/zudo-react/jsx-runtime.d.ts +5 -0
  53. package/dist/zudo-react/jsx-runtime.js +7 -0
  54. package/dist/zudo-react/jsx-runtime.js.map +1 -0
  55. package/dist/zudo-react/jsx-types.d.ts +203 -0
  56. package/dist/zudo-react/jsx-types.js +2 -0
  57. package/dist/zudo-react/jsx-types.js.map +1 -0
  58. package/dist/zudo-react/props-transport.d.ts +2 -0
  59. package/dist/zudo-react/props-transport.js +95 -0
  60. package/dist/zudo-react/props-transport.js.map +1 -0
  61. package/dist/zudo-react/reactive-types.d.ts +8 -0
  62. package/dist/zudo-react/reactive-types.js +2 -0
  63. package/dist/zudo-react/reactive-types.js.map +1 -0
  64. package/dist/zudo-react/reactive.d.ts +20 -0
  65. package/dist/zudo-react/reactive.js +176 -0
  66. package/dist/zudo-react/reactive.js.map +1 -0
  67. package/dist/zudo-react/render-html.d.ts +3 -0
  68. package/dist/zudo-react/render-html.js +537 -0
  69. package/dist/zudo-react/render-html.js.map +1 -0
  70. package/dist/zudo-react/root.d.ts +20 -0
  71. package/dist/zudo-react/root.js +74 -0
  72. package/dist/zudo-react/root.js.map +1 -0
  73. package/dist/zudo-react/scheduler.d.ts +12 -0
  74. package/dist/zudo-react/scheduler.js +113 -0
  75. package/dist/zudo-react/scheduler.js.map +1 -0
  76. package/dist/zudo-react/scope.d.ts +42 -0
  77. package/dist/zudo-react/scope.js +220 -0
  78. package/dist/zudo-react/scope.js.map +1 -0
  79. package/dist/zudo-react/server.d.ts +15 -0
  80. package/dist/zudo-react/server.js +11 -0
  81. package/dist/zudo-react/server.js.map +1 -0
  82. package/dist/zudo-react/structure.d.ts +14 -0
  83. package/dist/zudo-react/structure.js +35 -0
  84. package/dist/zudo-react/structure.js.map +1 -0
  85. package/package.json +28 -24
package/dist/runtime.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type When } from "./types.js";
2
+ import { type RootHandle } from "./zudo-react/root.js";
2
3
  /**
3
4
  * Schedule a hydration `fire` callback for `target` according to `when`.
4
5
  *
@@ -10,69 +11,37 @@ import { type When } from "./types.js";
10
11
  */
11
12
  export declare function scheduleHydrate(target: Element, when: When | string | undefined, fire: () => void): () => void;
12
13
  /**
13
- * The shape of the default export each per-island bundle ships.
14
+ * The mount function supplied by a shared-bundle island module.
14
15
  *
15
16
  * `mode === "hydrate"` is used for SSR'd islands, `"render"` for
16
17
  * SSR-skip islands.
17
18
  */
18
- type IslandMount = (props: Record<string, unknown>, element: Element, mode: "hydrate" | "render") => void;
19
- type IslandUnmount = (element: Element) => void;
19
+ type IslandMount = (props: Record<string, unknown>, element: Element, mode: "hydrate" | "render") => RootHandle | null;
20
20
  interface IslandModule {
21
- mount?: IslandMount;
22
- default?: IslandMount;
23
- unmount?: IslandUnmount;
21
+ identity: {
22
+ component: string;
23
+ build: string;
24
+ };
25
+ mount: IslandMount;
24
26
  }
25
27
  /**
26
28
  * Map of `componentName → island descriptor` baked into the runtime entry.
27
29
  *
28
- * Two descriptor shapes are accepted so the same `mountIslands` runtime
29
- * handles both bundling strategies the build emits:
30
- *
31
- * 1. `string` — a per-island bundle URL. The runtime fetches it via
32
- * dynamic `import()` and reads `mount` / `default` off the loaded
33
- * module. Used by the per-island bundling path
34
- * (`bundle_per_island` / `render_runtime_entry_source`).
35
- *
36
- * 2. `IslandModule` — an inline module-shaped object whose `mount` (or
37
- * `default`) is called directly. Used by the shared-bundle path
38
- * (`render_shared_bundle_entry_source`): every island's source code
39
- * is already in the same bundle, so the synthesised entry can hand
40
- * the runtime the constructed mount functions inline without a
41
- * second HTTP fetch. This preserves the one-request shared-bundle
42
- * contract while giving up nothing on hydration semantics
43
- * (zudolab/zudo-doc#1355 wave 6).
30
+ * Each manifest value is an inline module with `mount` or `default`.
31
+ * The shared bundle imports island sources at build time.
44
32
  */
45
- export type IslandManifestValue = string | IslandModule;
33
+ export type IslandManifestValue = IslandModule;
46
34
  export type IslandManifest = Readonly<Record<string, IslandManifestValue>>;
47
35
  /**
48
- * Public DOM signal written after an island's mount function returns.
49
- *
50
- * State table (the marker is observational only and is never a mount guard):
51
- *
52
- * - initial: absent; `mountIslands` / `mountNewIslands` strip a marker that is
53
- * stale relative to this module instance's `mounted` map before scheduling.
54
- * - deferred idle / visible / media: absent while the scheduler is waiting.
55
- * - importing: absent while the URL module is in `pending`.
56
- * - mounted via URL: `scheduleMount`'s URL success handler writes it only after
57
- * `fn(propsForMount, element, mode)` returns, alongside the `mounted` entry.
58
- * - mounted via inline module: `fireInlineMount` writes it only after
59
- * `fn(props, element, mode)` returns, alongside the `mounted` entry.
60
- * - missing manifest entry: absent; `scheduleMount` returns without writing.
61
- * - no `mount` export: absent; both manifest paths return without writing.
62
- * - synchronous mount throw: absent; the `mounted` entry is not written, so a
63
- * later walk can retry the element.
64
- * - rejected import: absent; the URL rejection handler clears `pending` and
65
- * any defensive `mounted` entry.
66
- * - detached during import: absent; the URL success handler clears `pending`
67
- * and returns before calling mount.
68
- * - unmounted (discarded): `unmountIslands` clears the marker and `mounted`
69
- * entry in `finally`, even when the unmount thunk throws.
70
- * - unmounted (persisted-lifted): retained together with the `mounted` entry;
71
- * `unmountIslands` skips elements whose persist id exists in the incoming body.
72
- * - props-changed remount: `clearMountedForRemount` clears the marker and map
73
- * entry in `finally`, then the forced mount writes it again after mount returns.
74
- * - dev hot-swap over a marked DOM: a fresh module's `mountIslands` strips the
75
- * stale marker before scheduling, then writes it after its own mount returns.
36
+ * Public observation marker; the symbol handle is the live-root guard.
37
+ *
38
+ * State table:
39
+ * - initial/deferred/missing entry/failed mount: marker and handle absent;
40
+ * - successful mount: both present;
41
+ * - discarded root: disposal leaves DOM for the body swap, then clears both;
42
+ * - unchanged persisted root: both survive with the same DOM node;
43
+ * - changed persisted root: dispose, clear, then mount in render mode;
44
+ * - bundle re-import: dispose the old symbol handle before render mode replaces it.
76
45
  */
77
46
  export declare const ISLAND_MOUNTED_ATTR = "data-zfb-island-mounted";
78
47
  /**
@@ -81,7 +50,7 @@ export declare const ISLAND_MOUNTED_ATTR = "data-zfb-island-mounted";
81
50
  *
82
51
  * No-op when `document` is undefined (SSR, edge runtime). Safe to call
83
52
  * multiple times: each element is mounted at most once thanks to the
84
- * `mounted` WeakSet guard.
53
+ * symbol-handle guard.
85
54
  *
86
55
  * The manifest is captured at module level so `mountNewIslands()` can re-use
87
56
  * it after an SPA body swap without needing the caller to re-supply it.
@@ -110,33 +79,10 @@ export declare function mountNewIslands(): void;
110
79
  */
111
80
  export declare function cancelPendingIslands(): void;
112
81
  /**
113
- * Unmount the mounted islands within `root` (default: `document.body`) that will
114
- * NOT survive the body swap.
115
- *
116
- * Walks `root` for `[data-zfb-island]` and `[data-zfb-island-skip-ssr]` elements,
117
- * looks up each element's unmount thunk in the `mounted` WeakMap, calls it (which
118
- * triggers `render(null, element)` for Preact or `root.unmount()` for React), and
119
- * removes the entry from the map so `mountNewIslands()` can re-mount later.
120
- *
121
- * Call this before `swapBodyElement(...)` so the OLD body's islands receive proper
122
- * framework lifecycle cleanup (useEffect teardowns, etc.) before being discarded.
123
- *
124
- * When `incomingBody` is supplied (the client-router passes the parsed incoming
125
- * document body), any island whose `data-zfb-transition-persist` id matches a
126
- * marker in that body is DELIBERATELY SKIPPED: swapBodyElement will physically
127
- * lift the node into the new body, so its component instance and internal state
128
- * must survive — unmounting it here would empty the container before the lift and
129
- * defeat the persist contract (issue #1389). Omit `incomingBody` (or pass null)
130
- * to unmount everything, the pre-#1389 behavior.
131
- *
132
- * No-op for elements not in the `mounted` map (e.g. never-mounted or already cleaned up).
82
+ * Dispose roots that the incoming body will discard. Persisted roots keep their
83
+ * handles and DOM until the post-swap scan determines whether to recreate them.
133
84
  */
134
85
  export declare function unmountIslands(root?: ParentNode, incomingBody?: ParentNode | null): void;
135
- /**
136
- * Test-only seam. Replace the module dynamic-import with a fake.
137
- * Returns the previous implementation so tests can restore it.
138
- */
139
- export declare function __setIslandImporterForTests(impl: (url: string) => Promise<IslandModule>): (url: string) => Promise<IslandModule>;
140
86
  /**
141
87
  * Test-only seam. Returns whether the given element has an entry in the
142
88
  * module-private `pendingCancels` Map. Used to assert that a synchronous