@weftui/dom 0.27.1 → 0.28.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.
- package/README.md +11 -8
- package/dist/client/index.d.ts +159 -146
- package/dist/client/index.js +1 -1
- package/dist/{data-Bk7mnjdd.d.ts → data-C88W1AwU.d.ts} +4 -5
- package/dist/index.d.ts +1 -1
- package/dist/rolldown-runtime-DK3Fl9T5.js +1 -0
- package/dist/server/index.d.ts +0 -1
- package/docs/explanation/reactive-primitives.md +1 -1
- package/docs/explanation/rendering-model.md +2 -2
- package/docs/explanation/services-and-context.md +13 -17
- package/docs/how-to/add-routing.md +6 -6
- package/docs/how-to/author-components.md +7 -5
- package/docs/how-to/load-data-with-rpc.md +4 -2
- package/docs/how-to/provide-services.md +52 -74
- package/docs/how-to/render-on-the-server.md +4 -3
- package/docs/index.md +2 -2
- package/docs/reference/dom.md +166 -45
- package/docs/reference/router.md +4 -4
- package/docs/tutorial/01-your-first-app.md +4 -3
- package/docs/tutorial/02-reactivity.md +3 -2
- package/docs/tutorial/03-services-and-async.md +12 -10
- package/docs/tutorial/04-errors-and-server.md +3 -2
- package/package.json +8 -7
package/README.md
CHANGED
|
@@ -20,12 +20,14 @@ Weft tracks Effect 4's beta line. This release is built and tested against `effe
|
|
|
20
20
|
|
|
21
21
|
### `@weftui/dom/client`
|
|
22
22
|
|
|
23
|
-
| Export
|
|
24
|
-
|
|
|
25
|
-
| `
|
|
26
|
-
| `
|
|
27
|
-
| `
|
|
28
|
-
| `
|
|
23
|
+
| Export | What it does |
|
|
24
|
+
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
25
|
+
| `WeftApp.make(layer?)` | Creates an app: one lazily-built `ManagedRuntime` (the layer), one root `Scope`, one error hub. Synchronous — the layer builds on first mount. |
|
|
26
|
+
| `WeftApp.mount(app, node, root)` | Renders a node into `root` as a new root of `app`, starting all streams. Returns `Effect<RootHandle, …>` with `R = never` — runs via bare `Effect.runPromise`. |
|
|
27
|
+
| `WeftApp.hydrate(app, node, root)` | Adopts server-rendered DOM **in place** as a new root of `app` and resumes reactivity — the flash-free path. |
|
|
28
|
+
| `WeftApp.errors(app)` | `Stream` of errors that escaped every user-level handler (stream failures, outermost-boundary escapes, event-handler failures/defects). Subscribing suppresses the default log fallback. |
|
|
29
|
+
| `WeftApp.dispose(app)` | Tears down every root, then releases the app layer, then shuts the error hub down. Idempotent. |
|
|
30
|
+
| `RootHandle` | Returned by `mount`/`hydrate`. `unmount()` closes that root's scope only — other roots and the app runtime are untouched. Idempotent. |
|
|
29
31
|
|
|
30
32
|
### `@weftui/dom/server`
|
|
31
33
|
|
|
@@ -42,7 +44,7 @@ The package root re-exports the renderer error types: `HydrationMismatchError`,
|
|
|
42
44
|
|
|
43
45
|
```typescript
|
|
44
46
|
import { h } from "@weftui/core";
|
|
45
|
-
import {
|
|
47
|
+
import { WeftApp } from "@weftui/dom/client";
|
|
46
48
|
import { Effect, SubscriptionRef } from "effect";
|
|
47
49
|
|
|
48
50
|
const Counter = () =>
|
|
@@ -53,7 +55,8 @@ const Counter = () =>
|
|
|
53
55
|
]);
|
|
54
56
|
});
|
|
55
57
|
|
|
56
|
-
|
|
58
|
+
const app = WeftApp.make();
|
|
59
|
+
void Effect.runPromise(WeftApp.mount(app, Counter(), document.getElementById("root")!));
|
|
57
60
|
```
|
|
58
61
|
|
|
59
62
|
## Documentation
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,179 +1,192 @@
|
|
|
1
|
-
import { i as UnsupportedNodeTypeError, n as RenderError, r as StreamSubscriptionError, t as HydrationMismatchError } from "../data-
|
|
2
|
-
import { Effect,
|
|
1
|
+
import { i as UnsupportedNodeTypeError, n as RenderError, r as StreamSubscriptionError, t as HydrationMismatchError } from "../data-C88W1AwU.js";
|
|
2
|
+
import { Cause, Effect, Layer, ManagedRuntime, Stream } from "effect";
|
|
3
3
|
import { AssertNoServerOnly, Node, Renderable, ServerOnlyLeak } from "@weftui/core";
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
declare namespace weft_app_d_exports {
|
|
5
|
+
export { HydrateError, MountError, RootHandle, TypeId, UnhandledError, WeftApp, dispose, errors, hydrate, make, mount };
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Unique brand for {@link WeftApp} values.
|
|
9
|
+
*/
|
|
10
|
+
declare const TypeId: unique symbol;
|
|
11
|
+
/**
|
|
12
|
+
* Errors that {@link mount} can fail with (beyond the app layer's own error
|
|
13
|
+
* channel `E`).
|
|
14
|
+
*/
|
|
15
|
+
type MountError = UnsupportedNodeTypeError | StreamSubscriptionError | RenderError;
|
|
16
|
+
/**
|
|
17
|
+
* Errors that {@link hydrate} can fail with (beyond the app layer's own error
|
|
18
|
+
* channel `E`): everything {@link mount} can fail with, plus
|
|
19
|
+
* {@link HydrationMismatchError} when the server DOM and the node tree diverge.
|
|
20
|
+
*/
|
|
21
|
+
type HydrateError = MountError | HydrationMismatchError;
|
|
22
|
+
/**
|
|
23
|
+
* An error that escaped every user-level handler and reached the app's
|
|
24
|
+
* unhandled-error hub — published on the {@link errors} stream.
|
|
25
|
+
*
|
|
26
|
+
* Sources (one entry per failing occurrence):
|
|
27
|
+
* - a rendered stream subscription failing or dying with no enclosing
|
|
28
|
+
* `Boundary` (region e.g. `"attribute:class"`, `"child:stream-3"`),
|
|
29
|
+
* - an error escaping the outermost `Boundary` recovery
|
|
30
|
+
* (region `"boundary:outermost"`),
|
|
31
|
+
* - an event-handler effect failing **or dying** (region `"event:onClick"`).
|
|
32
|
+
*
|
|
33
|
+
* Interrupt-only causes are never published. Errors handled by a nested
|
|
34
|
+
* `Boundary` never reach the hub.
|
|
35
|
+
*/
|
|
36
|
+
interface UnhandledError {
|
|
37
|
+
/** Full cause of the failure (failures and defects alike). */
|
|
38
|
+
readonly cause: Cause.Cause<unknown>;
|
|
39
|
+
/**
|
|
40
|
+
* Where in the render tree the error escaped, e.g. `"attribute:class"`,
|
|
41
|
+
* `"child:stream-3"`, `"event:onClick"`, `"boundary:outermost"`.
|
|
42
|
+
*/
|
|
43
|
+
readonly region: string;
|
|
44
|
+
/** Handle of the root the error originated from. */
|
|
45
|
+
readonly root: RootHandle;
|
|
46
|
+
}
|
|
6
47
|
/**
|
|
7
|
-
*
|
|
48
|
+
* Handle for one mounted (or hydrated) root, returned by {@link mount} /
|
|
49
|
+
* {@link hydrate}.
|
|
8
50
|
*
|
|
9
|
-
* The handle owns the
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* nodes from the root.
|
|
51
|
+
* The handle owns the root's lifetime: its forked subscriptions and event
|
|
52
|
+
* handlers stay live until `unmount`. Other roots and the app runtime are
|
|
53
|
+
* unaffected by it.
|
|
13
54
|
*/
|
|
14
|
-
interface
|
|
55
|
+
interface RootHandle {
|
|
56
|
+
/** The DOM element this root was mounted into. */
|
|
57
|
+
readonly element: HTMLElement;
|
|
15
58
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
59
|
+
* Closes this root's scope: interrupts its stream subscriptions and any
|
|
60
|
+
* scoped work forked from its event handlers. Does **not** dispose the app
|
|
61
|
+
* runtime, touch other roots, or remove the rendered DOM nodes from
|
|
62
|
+
* {@link element}. Idempotent — teardown side effects fire once.
|
|
19
63
|
*/
|
|
20
64
|
unmount(): Effect.Effect<void>;
|
|
21
65
|
}
|
|
22
66
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* -
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
67
|
+
* A Weft application: one lazy `ManagedRuntime` (the app layer), one root
|
|
68
|
+
* `Scope`, and one unhandled-error hub. Each {@link mount} / {@link hydrate}
|
|
69
|
+
* call creates a child root scope; layer-built services are shared by
|
|
70
|
+
* reference across all roots (layer memoization), which is what makes
|
|
71
|
+
* cross-island reactive state work.
|
|
72
|
+
*
|
|
73
|
+
* Create with {@link make}; tear down with {@link dispose}.
|
|
74
|
+
*
|
|
75
|
+
* @typeParam R - services provided by the app layer, available to every
|
|
76
|
+
* component, event handler, and stream subscription in every root
|
|
77
|
+
* @typeParam E - the app layer's construction error channel; surfaces on the
|
|
78
|
+
* first `mount`/`hydrate` (layer construction is lazy)
|
|
79
|
+
*/
|
|
80
|
+
interface WeftApp<in R = never, out E = never> {
|
|
81
|
+
readonly [TypeId]: typeof TypeId;
|
|
82
|
+
/**
|
|
83
|
+
* The app's `ManagedRuntime`, for running app-level effects against the
|
|
84
|
+
* shared layer outside any root — e.g.
|
|
85
|
+
* `app.runtime.runFork(trackPageviews)` or
|
|
86
|
+
* `app.runtime.runPromise(Router.push("/about"))`.
|
|
87
|
+
*/
|
|
88
|
+
readonly runtime: ManagedRuntime.ManagedRuntime<R, E>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Creates a {@link WeftApp} from an app layer.
|
|
31
92
|
*
|
|
32
|
-
*
|
|
93
|
+
* Synchronous and side-effect-free with respect to the layer: the layer builds
|
|
94
|
+
* **lazily** on the first {@link mount} / {@link hydrate} (or the first direct
|
|
95
|
+
* `app.runtime` run), per `ManagedRuntime.make` semantics. Layer construction
|
|
96
|
+
* errors therefore surface on first mount, not here.
|
|
33
97
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* after initial render. Because of this, providing a **scoped** layer the obvious
|
|
37
|
-
* way disposes it too early:
|
|
98
|
+
* There is deliberately no `makeScoped`. To bind an app's lifetime to a scope,
|
|
99
|
+
* compose it yourself:
|
|
38
100
|
*
|
|
39
101
|
* ```ts
|
|
40
|
-
*
|
|
41
|
-
*
|
|
102
|
+
* const acquireApp = Effect.acquireRelease(
|
|
103
|
+
* Effect.sync(() => WeftApp.make(AppLive)),
|
|
104
|
+
* (app) => WeftApp.dispose(app),
|
|
105
|
+
* );
|
|
42
106
|
* ```
|
|
43
107
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
108
|
+
* @param layer - the app layer; its services are the only services components
|
|
109
|
+
* see (ambient `Effect.provide` context around mount calls is not captured)
|
|
110
|
+
* @param options - optional `memoMap` to share layer memoization across apps
|
|
111
|
+
*/
|
|
112
|
+
type Make = {
|
|
113
|
+
(): WeftApp<never, never>;
|
|
114
|
+
<R, E>(layer: Layer.Layer<R, E, never>, options?: {
|
|
115
|
+
readonly memoMap?: Layer.MemoMap;
|
|
116
|
+
}): WeftApp<R, E>;
|
|
117
|
+
};
|
|
118
|
+
declare const make: Make;
|
|
119
|
+
/**
|
|
120
|
+
* Mounts a node tree into `root` as a new root of `app`.
|
|
121
|
+
*
|
|
122
|
+
* - Clears `root`'s existing children, renders the tree, appends the result.
|
|
123
|
+
* - Completes after initial render; streams keep running in the background,
|
|
124
|
+
* owned by the root's scope (a child of the app scope).
|
|
125
|
+
* - Self-contained: the returned effect's requirement channel is `never` —
|
|
126
|
+
* run it with a bare `Effect.runPromise`. Services come exclusively from the
|
|
127
|
+
* app layer; `Effect.provide` around this call does not feed components.
|
|
128
|
+
* - The app layer builds lazily here on first mount; its error channel `E`
|
|
129
|
+
* surfaces at that point.
|
|
130
|
+
* - On render failure the root scope is closed before the error propagates;
|
|
131
|
+
* the app runtime and other roots are untouched.
|
|
132
|
+
* - Mounting on a disposed app fails (it does not hang).
|
|
133
|
+
*
|
|
134
|
+
* @param app - the owning {@link WeftApp}
|
|
135
|
+
* @param node - node tree to render (built with `h.*`; components are plain
|
|
54
136
|
* functions that are called, e.g. `App()`)
|
|
55
|
-
* @param root - HTMLElement to mount
|
|
56
|
-
* @returns Effect
|
|
137
|
+
* @param root - HTMLElement to mount into
|
|
138
|
+
* @returns Effect yielding a {@link RootHandle} for this root
|
|
57
139
|
*
|
|
58
140
|
* @example
|
|
59
141
|
* ```ts
|
|
60
|
-
* const
|
|
61
|
-
* const handle = await Effect.runPromise(mount(App(),
|
|
62
|
-
* //
|
|
63
|
-
* await Effect.runPromise(handle.unmount());
|
|
142
|
+
* const app = WeftApp.make();
|
|
143
|
+
* const handle = await Effect.runPromise(WeftApp.mount(app, App(), rootEl));
|
|
144
|
+
* // later: await Effect.runPromise(handle.unmount());
|
|
64
145
|
* ```
|
|
65
146
|
*/
|
|
66
|
-
declare
|
|
147
|
+
declare const mount: <R, E>(app: WeftApp<R, E>, node: Renderable, root: HTMLElement) => Effect.Effect<RootHandle, E | MountError>;
|
|
67
148
|
/**
|
|
68
149
|
* Continues, on the client, the DOM produced on the server by
|
|
69
|
-
* `renderToStringHydratable`/`renderToStreamHydratable
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* Use {@link hydrateScoped} to bind the hydrated mount's lifetime to an ambient
|
|
87
|
-
* `Scope`, or a {@link ManagedRuntime} for scoped layers (see `mount`).
|
|
88
|
-
*
|
|
89
|
-
* Hydration is a **client-only** operation: the app's requirement channel `R`
|
|
90
|
-
* must be free of server-only dependencies. A {@link Boundary.server} discharges
|
|
91
|
-
* its `load`'s server requirements via `provide`, so they never reach here — but
|
|
92
|
-
* a server-only `ServerTag` accidentally referenced in client (`render`) code
|
|
93
|
-
* stays in `R`, and {@link AssertNoServerOnly} turns that into a compile error
|
|
94
|
-
* (the return type degrades to the {@link ServerOnlyLeak} sentinel).
|
|
95
|
-
*
|
|
96
|
-
* @param app - node tree to hydrate (must match the tree rendered on the server)
|
|
150
|
+
* `renderToStringHydratable`/`renderToStreamHydratable`, as a new root of
|
|
151
|
+
* `app`.
|
|
152
|
+
*
|
|
153
|
+
* Unlike {@link mount}, does **not** clear `root`: it walks the node tree in
|
|
154
|
+
* lockstep with the existing server DOM, adopting nodes in place. Hydration
|
|
155
|
+
* mechanics (readiness barrier, stream-id seeding, marker-based reactive
|
|
156
|
+
* regions) are unchanged from `hydrate.specs.md` / `hydrate-ready.specs.md`;
|
|
157
|
+
* only runtime/scope ownership and error routing follow the app model
|
|
158
|
+
* (see {@link mount}).
|
|
159
|
+
*
|
|
160
|
+
* Hydration is a **client-only** operation: the tree's requirement channel
|
|
161
|
+
* must be free of server-only dependencies. A server-only tag leaking into
|
|
162
|
+
* client code degrades the return type to the {@link ServerOnlyLeak} sentinel
|
|
163
|
+
* (compile error at the call site).
|
|
164
|
+
*
|
|
165
|
+
* @param app - the owning {@link WeftApp}
|
|
166
|
+
* @param node - node tree to hydrate (must match the tree rendered on the server)
|
|
97
167
|
* @param root - HTMLElement whose children were produced by the server renderer
|
|
98
|
-
* @returns Effect
|
|
99
|
-
*
|
|
100
|
-
* @example
|
|
101
|
-
* ```ts
|
|
102
|
-
* const root = document.getElementById("root")!;
|
|
103
|
-
* // root.innerHTML already contains server output
|
|
104
|
-
* const handle = await Effect.runPromise(hydrate(App(), root));
|
|
105
|
-
* ```
|
|
168
|
+
* @returns Effect yielding a {@link RootHandle} for this root
|
|
106
169
|
*/
|
|
107
|
-
declare function hydrate<A extends Renderable>(app: A, root: HTMLElement): [AssertNoServerOnly<Node.Context<A>>] extends [Node.Context<A>] ? Effect.Effect<
|
|
108
|
-
//#endregion
|
|
109
|
-
//#region src/client/mount-scoped.d.ts
|
|
170
|
+
declare function hydrate<A extends Renderable, R = never, E = never>(app: WeftApp<R, E>, node: A, root: HTMLElement): [AssertNoServerOnly<Node.Context<A>>] extends [Node.Context<A>] ? Effect.Effect<RootHandle, E | HydrateError> : ServerOnlyLeak;
|
|
110
171
|
/**
|
|
111
|
-
*
|
|
112
|
-
* channel.
|
|
113
|
-
*/
|
|
114
|
-
type MountErrors = UnsupportedNodeTypeError | StreamSubscriptionError | RenderError;
|
|
115
|
-
/**
|
|
116
|
-
* Error union raised by {@link hydrateScoped} — `mount`'s errors plus
|
|
117
|
-
* {@link HydrationMismatchError}, matching `hydrate`.
|
|
118
|
-
*/
|
|
119
|
-
type HydrateErrors = MountErrors | HydrationMismatchError;
|
|
120
|
-
/**
|
|
121
|
-
* Scope-aware {@link mount}. Behaves exactly like `mount`, but requires an
|
|
122
|
-
* ambient `Scope.Scope` in the effect's requirement channel and registers
|
|
123
|
-
* `unmount` as a finalizer on it: the mount lives until the ambient scope
|
|
124
|
-
* closes.
|
|
125
|
-
*
|
|
126
|
-
* This makes the mount lifetime composable with Effect's scoped resource
|
|
127
|
-
* management. Provide any scoped layer **outside** a long-lived scoped region so
|
|
128
|
-
* the layer outlives initial render — the mount Effect resolves right after the
|
|
129
|
-
* first render, so a layer released at mount-resolve would be disposed while the
|
|
130
|
-
* app is still running.
|
|
172
|
+
* The app's unhandled-error stream.
|
|
131
173
|
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
174
|
+
* While at least one subscriber exists, the default `Effect.logError` fallback
|
|
175
|
+
* is suppressed and every {@link UnhandledError} is delivered to all
|
|
176
|
+
* subscribers. With zero subscribers, each unhandled error runs the default
|
|
177
|
+
* log (annotated with `weft.region`) instead. No replay: a subscriber sees
|
|
178
|
+
* only errors published after it subscribed.
|
|
134
179
|
*
|
|
135
|
-
* @param app -
|
|
136
|
-
* @param root - HTMLElement to mount into
|
|
137
|
-
* @returns Effect requiring `Scope.Scope`, yielding a {@link MountHandle}
|
|
138
|
-
*
|
|
139
|
-
* @example
|
|
140
|
-
* ```ts
|
|
141
|
-
* const program = pipe(
|
|
142
|
-
* Effect.scoped(
|
|
143
|
-
* Effect.gen(function* () {
|
|
144
|
-
* yield* mountScoped(App(), root);
|
|
145
|
-
* yield* Effect.never; // keep the region (and layer) alive
|
|
146
|
-
* }),
|
|
147
|
-
* ),
|
|
148
|
-
* Effect.provide(AppLive), // OUTSIDE the region — lives until it ends
|
|
149
|
-
* );
|
|
150
|
-
* const fiber = Effect.runFork(program); // runFork, not runPromise
|
|
151
|
-
* // later: Effect.runPromise(Fiber.interrupt(fiber));
|
|
152
|
-
* // teardown order: unmount (inner scope close) → AppLive release
|
|
153
|
-
* ```
|
|
154
|
-
*
|
|
155
|
-
* @example Anti-pattern — do NOT do this; the layer is disposed at mount-resolve
|
|
156
|
-
* ```ts
|
|
157
|
-
* // ❌ finalizers run the moment runPromise settles
|
|
158
|
-
* Effect.runPromise(mountScoped(App(), root).pipe(Effect.provide(AppLive), Effect.scoped));
|
|
159
|
-
* ```
|
|
180
|
+
* @param app - the owning {@link WeftApp}
|
|
160
181
|
*/
|
|
161
|
-
declare
|
|
182
|
+
declare const errors: <R, E>(app: WeftApp<R, E>) => Stream.Stream<UnhandledError>;
|
|
162
183
|
/**
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* scope closes.
|
|
184
|
+
* Disposes the app: closes every root scope (in mount order), then releases
|
|
185
|
+
* the runtime's layers, then shuts the error hub down. Idempotent — teardown
|
|
186
|
+
* effects run once. Subsequent {@link mount} / {@link hydrate} calls fail.
|
|
167
187
|
*
|
|
168
|
-
*
|
|
169
|
-
* left in the app's requirement channel degrades the return type to the
|
|
170
|
-
* {@link ServerOnlyLeak} sentinel via {@link AssertNoServerOnly}.
|
|
171
|
-
*
|
|
172
|
-
* @param app - Renderable tree to hydrate (must match the server-rendered tree)
|
|
173
|
-
* @param root - HTMLElement whose children were produced by the server renderer
|
|
174
|
-
* @returns Effect requiring `Scope.Scope`, yielding a {@link MountHandle}, or the
|
|
175
|
-
* {@link ServerOnlyLeak} sentinel when a server-only requirement leaks
|
|
188
|
+
* @param app - the {@link WeftApp} to dispose
|
|
176
189
|
*/
|
|
177
|
-
declare
|
|
190
|
+
declare const dispose: <R, E>(app: WeftApp<R, E>) => Effect.Effect<void>;
|
|
178
191
|
//#endregion
|
|
179
|
-
export { type
|
|
192
|
+
export { type HydrateError, type MountError, type RootHandle, type UnhandledError, weft_app_d_exports as WeftApp, type WeftApp as WeftAppType };
|
package/dist/client/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as e,n as t,o as n,r,s as i,t as a}from"../data-uLmMpQMV.js";import{a as o,c as s,d as c,f as l,i as u,l as d,m as f,n as p,o as m,p as h,s as g,u as _}from"../boundary-replay-BR26_puM.js";import{Cause as v,Context as y,Deferred as b,Effect as x,Exit as S,Fiber as ee,HashMap as C,HashSet as w,Layer as te,ManagedRuntime as ne,Option as T,Ref as E,Schema as re,Scope as D,Stream as O,SubscriptionRef as k,pipe as A}from"effect";import{AppRpcClientTag as ie,FAILURE_BOUNDARY as ae,FRAGMENT as oe,LIST as se,SERVER_BOUNDARY as ce,SUSPENSE_BOUNDARY as le,Source as ue,Subscribable as j,getElementDescriptor as M,isStream as N,toStream as P}from"@weftui/core";function F(){return x.gen(function*(){let e=yield*r;return++e.streamIdCounter.current})}const de=F;let fe=0;const pe=()=>++fe;function me(e){if(e.length<=2||!e.startsWith(`on`))return!1;let t=e[2];return t!==void 0&&t>=`a`&&t<=`z`}function I(e,t){return x.gen(function*(){for(let[n,r]of Object.entries(t))if(n!==`children`){if(me(n)){yield*xe(e,n,r);continue}if(n===`ref`&&typeof r==`object`&&k.isSubscriptionRef(r)){yield*k.set(r,T.some(e));continue}if(n===`style`){yield*ye(e,r);continue}he(e,n)?yield*ge(e,n,r):yield*_e(e,n,r)}})}function he(e,t){if(t.startsWith(`data-`)||t.startsWith(`aria-`))return!1;let n=Object.getPrototypeOf(e);for(;n!==null;){if(Object.hasOwn(n,t))return!0;n=Object.getPrototypeOf(n)}return t in e}function ge(e,t,n){return x.gen(function*(){N(n)||x.isEffect(n)?yield*z(P(n),n=>{n==null?delete e[t]:e[t]=n},`property:${t}`):n!=null&&(e[t]=n)})}function _e(e,t,n){return x.gen(function*(){if(N(n)||x.isEffect(n))yield*z(P(n),n=>{if(n==null)e.removeAttribute(t);else{let r=ve(n);r!==void 0&&(typeof n==`boolean`?n?e.setAttribute(t,``):e.removeAttribute(t):e.setAttribute(t,r))}},`attribute:${t}`);else{let r=ve(n);r!==void 0&&(typeof n==`boolean`?n?e.setAttribute(t,``):e.removeAttribute(t):e.setAttribute(t,r))}})}function ve(e){if(e!=null)return String(e)}function ye(e,t){return x.gen(function*(){if(N(t)||x.isEffect(t)){yield*z(P(t),t=>{if(typeof t==`string`)e.setAttribute(`style`,t);else if(typeof t==`object`&&t){e.style.cssText=``;for(let[n,r]of Object.entries(t))r!=null&&e.style.setProperty(L(n),String(r))}},`style`);return}if(typeof t==`string`){e.setAttribute(`style`,t);return}typeof t==`object`&&t&&(yield*be(e,t))})}function be(e,t){return x.gen(function*(){for(let[n,r]of Object.entries(t))N(r)||x.isEffect(r)?yield*z(P(r),t=>{t!=null&&e.style.setProperty(L(n),String(t))},`style.${n}`):r!=null&&e.style.setProperty(L(n),String(r))})}function L(e){return e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}function R(e,t,n){return x.gen(function*(){let r=yield*x.serviceOption(a);if(T.isNone(r)){let r=yield*x.forkIn(e,t);return yield*A(ee.await(r),x.flatMap(e=>S.isFailure(e)&&!v.hasInterruptsOnly(e.cause)?A(x.logError(e.cause),x.annotateLogs(`weft.region`,n)):x.void),x.forkIn(t)),r}let i=yield*x.forkIn(e,t);return yield*A(ee.await(i),x.flatMap(e=>S.isFailure(e)?r.value.reportError(e.cause):x.void),x.forkIn(t)),i})}function z(e,t,n){return x.gen(function*(){let i=yield*r;yield*R(O.runForEach(e,e=>x.sync(()=>void t(e))),i.scope,n)})}function xe(e,t,n){return x.gen(function*(){let i=yield*r,a=t.slice(2).toLowerCase(),o=null,s=()=>{o&&=(e.removeEventListener(a,o),null)},c=n=>{s(),!(n==null||n===!1)&&typeof n==`function`&&(o=e=>{let r=n(e);x.isEffect(r)&&i.runtime.runFork(A(r,x.catch(e=>process.env.NODE_ENV===`development`?x.logError(`Event handler error: ${t}`,{error:e}):x.void)))},e.addEventListener(a,o))};yield*D.addFinalizer(i.scope,x.sync(s)),N(n)||x.isEffect(n)?yield*z(P(n),e=>c(e),`event:${t}`):c(n)})}function Se(e,t,n,r,i,a){return x.gen(function*(){let o=yield*b.await(t).pipe(x.flip,x.catch(()=>x.interrupt)),s=e.match(o);if(yield*D.close(n,S.void),s===null)return T.isSome(r)?yield*r.value.reportError(o):yield*x.logError(`Unhandled error escaped the outermost Boundary`,o);K(i,a);let c=yield*B(s),l=a.parentNode;if(l!==null&&c!==null)if(Array.isArray(c))for(let e of c)l.insertBefore(e,a);else l.insertBefore(c,a)})}function Ce(e){return x.gen(function*(){let t=yield*r,n=yield*x.serviceOption(a),i=pe(),s=document.createComment(o(i)),c=document.createComment(u(i)),l=yield*D.fork(t.scope,`sequential`),d={...t,scope:l},f=yield*b.make(),p=yield*A(V(e.children),x.provideService(a,{reportError:e=>b.fail(f,e).pipe(x.asVoid)}),x.provideService(r,d),x.provideService(D.Scope,l),x.catchCause(t=>{let n=e.match(t);return n===null?x.failCause(t):A(D.close(l,S.void),x.flatMap(()=>B(n)),x.map(e=>e===null?[]:Array.isArray(e)?e:[e]))}));return yield*x.forkIn(Se(e,f,l,n,s,c),t.scope),[s,...p,c]})}function we(e){return x.gen(function*(){let t=yield*r,i=yield*E.make(1),a=yield*b.make(),o=A(E.updateAndGet(i,e=>e-1),x.flatMap(e=>e<=0?x.asVoid(b.succeed(a,void 0)):x.void)),s={register:E.update(i,e=>e+1),settle:o},c=e.children,l=yield*B((c===void 0?[]:Array.isArray(c)?c:[c]).map(e=>M(e)===void 0&&(x.isEffect(e)||N(e))?{type:()=>e,props:{}}:e)).pipe(x.provideService(n,s)),u=l===null?[]:Array.isArray(l)?l:[l];yield*o;let d=yield*b.poll(a);if(T.isSome(d))return u;let p=yield*de(),m=document.createComment(f(p)),g=document.createComment(h(p)),_=yield*B(e.fallback??null),v=[];_!==null&&(Array.isArray(_)?v.push(..._):v.push(_));let y=document.createDocumentFragment();for(let e of u)y.appendChild(e);let S=x.gen(function*(){yield*b.await(a),K(m,g);let e=g.parentNode;e!==null&&(e.insertBefore(y,g),m.remove(),g.remove())});return yield*x.forkIn(S,t.scope),[m,...v,g]})}function Te(t){return x.gen(function*(){let n=yield*r,i=yield*x.serviceOption(ie);if(T.isNone(i))return yield*x.fail(new e({cause:void 0,message:`Boundary.rpc "${t.tag}" was mounted client-first without an AppRpcClient in context. Mount the app under @weftui/router (RouterLive), which provides the rpc client, so the boundary can resolve its data.`}));let a=i.value,s=pe(),c=document.createComment(o(s)),l=document.createComment(u(s)),d=yield*B(t.fallback??null),f=[];d!==null&&(Array.isArray(d)?f.push(...d):f.push(d));let p=x.gen(function*(){let e=yield*a.call(t.tag,t.payload()),n=yield*Ze(t.tag,t.payload,e,i),r=yield*B(t.render(n));K(c,l);let o=l.parentNode;if(o!==null&&r!==null)if(Array.isArray(r))for(let e of r)o.insertBefore(e,l);else o.insertBefore(r,l)}).pipe(x.catchCause(e=>x.logError(`[weft] Boundary.rpc "${t.tag}" mount failed to resolve; fallback left in place.`,e)));return yield*x.forkIn(p,n.scope),[c,...f,l]})}function B(e){return x.gen(function*(){if(typeof e==`string`||typeof e==`number`||typeof e==`bigint`)return document.createTextNode(String(e));if(typeof e==`boolean`||e==null)return null;if(N(e)||x.isEffect(e)){let t=M(e);if(t!==void 0)return yield*B(t);if(x.isEffect(e)){let t=yield*x.context(),n=x.runSyncExitWith(t)(e);if(S.isSuccess(n))return yield*B(n.value)}return yield*H(P(e))}if(typeof e==`object`&&Symbol.iterator in e&&!(`type`in e))return yield*V(Ee(e));if(typeof e==`object`&&`type`in e&&!(Symbol.iterator in e)){let{type:t,props:n}=e;return t===oe?yield*De(n):t===le?yield*we(n):t===ce?yield*Te(n):t===ae?yield*Ce(n):t===se?yield*Pe(n):typeof t==`string`?yield*Oe(t,n):typeof t==`function`?yield*ke(t,n):yield*x.fail(new i({type:t,message:`Invalid Renderable type: expected string, FRAGMENT, or function, got ${typeof t}`}))}return null})}function Ee(e){let t=[];function n(e){if(N(e)||x.isEffect(e)){t.push(e);return}if(typeof e==`object`&&e&&Symbol.iterator in e&&!(`type`in e))for(let t of e)n(t);else t.push(e)}return n(e),t}function V(e){return x.gen(function*(){let t=[];for(let n of e)if(M(n)===void 0&&(N(n)||x.isEffect(n))){let e=yield*H(P(n));t.push(...e)}else{let e=yield*B(n);e!==null&&(Array.isArray(e)?t.push(...e):t.push(e))}return t})}function De(e){return x.gen(function*(){let t=`children`in e?e.children:void 0;return t===void 0?[]:yield*V(Array.isArray(t)?t:[t])})}function Oe(e,t){return x.gen(function*(){let n=document.createElement(e);yield*I(n,t);let r=`children`in t?t.children:void 0;if(r!==void 0){let e=Array.isArray(r)?r:[r];for(let t of e)if(M(t)===void 0&&(N(t)||x.isEffect(t))){let e=yield*H(P(t));for(let t of e)n.appendChild(t)}else{let e=yield*B(t);if(e!==null)if(Array.isArray(e))for(let t of e)n.appendChild(t);else n.appendChild(e)}}return n})}function ke(e,t){return x.gen(function*(){let i=e(t);if(N(i)||x.isEffect(i)){let e=yield*r,t=yield*D.fork(e.scope,`sequential`),a={...e,scope:t},o=yield*x.serviceOption(n),s=P(i);return T.isSome(o)&&(yield*o.value.register,s=A(s,O.zipWithIndex,O.flatMap(([e,t])=>t===0?O.fromEffect(x.as(o.value.settle,e)):O.make(e)))),yield*H(s).pipe(x.provideService(r,a),x.provideService(D.Scope,t))}return yield*B(i)})}function H(e){return x.gen(function*(){let t=yield*r,n=yield*F(),[i,a]=Ae(n),o=null;return yield*R(O.runForEach(e,e=>x.gen(function*(){o!==null&&(yield*D.close(o,S.void)),o=yield*D.fork(t.scope,`sequential`);let n={...t,scope:o};yield*U(i,a,e).pipe(x.provideService(r,n),x.provideService(D.Scope,o))})),t.scope,`child:stream-${n}`),[i,a]})}function Ae(e){return[document.createComment(l(e)),document.createComment(c(e))]}function U(e,t,n){return x.gen(function*(){let r=e.nextSibling,i=r!==null&&r!==t&&r.nextSibling===t;if(i&&r.nodeType===it&&W(n)){let e=String(n);r.data!==e&&(r.data=e);return}if(i&&r.nodeType===X){let e=G(n);if(e!==void 0&&typeof e.type==`string`&&r.tagName.toLowerCase()===e.type.toLowerCase()){yield*je(r,e);return}}K(e,t);let a=yield*B(n),o=e.parentNode;if(o!==null&&a!==null)if(Array.isArray(a))for(let e of a)o.insertBefore(e,t);else o.insertBefore(a,t)})}function W(e){return typeof e==`string`||typeof e==`number`||typeof e==`bigint`}function G(e){let t=M(e);if(t!==void 0)return t;if(typeof e==`object`&&e&&`type`in e&&!(Symbol.iterator in e)&&!N(e)&&!x.isEffect(e))return e}function je(e,t){return x.gen(function*(){yield*I(e,t.props);let n=t.props.children,r=n===void 0?[]:Array.isArray(n)?n:[n];if(!(yield*Me(e,r))){for(;e.firstChild!==null;)e.firstChild.remove();yield*Ne(e,r)}})}function Me(e,t){return x.gen(function*(){let n=Array.from(e.childNodes);if(n.length!==t.length)return!1;for(let e=0;e<t.length;e++){let r=t[e],i=n[e];if(W(r)){if(i.nodeType!==it)return!1}else{let e=G(r);if(e===void 0||typeof e.type!=`string`||i.nodeType!==X||i.tagName.toLowerCase()!==e.type.toLowerCase())return!1}}for(let e=0;e<t.length;e++){let r=t[e],i=n[e];if(W(r)){let e=String(r);i.data!==e&&(i.data=e)}else yield*je(i,G(r))}return!0})}function Ne(e,t){return x.gen(function*(){for(let n of t)if(N(n)||x.isEffect(n)){let t=yield*H(P(n));for(let n of t)e.appendChild(n)}else{let t=yield*B(n);if(t!==null)if(Array.isArray(t))for(let n of t)e.appendChild(n);else e.appendChild(t)}})}function K(e,t){let n=e.nextSibling;for(;n!==null&&n!==t;){let e=n.nextSibling;n.remove(),n=e}}function Pe(e){return x.gen(function*(){let t=yield*r,{of:n,by:i,render:a}=e,o=yield*F(),[s,c]=Ae(o),l=yield*D.fork(t.scope,`sequential`),u=(yield*ue.toSubscribable(n).pipe(x.provideService(D.Scope,l))).changes,d={records:C.empty(),order:[]};return yield*R(O.runForEach(u,e=>x.gen(function*(){d=yield*q(Array.from(e),i,a,d,l,c,t)})),l,`list:stream-${o}`),[s,c]})}function Fe(t,n){return x.gen(function*(){let r=[],i=w.empty();for(let a=0;a<t.length;a++){let o=n===void 0?t[a]:n(t[a],a);if(w.has(i,o))return yield*x.fail(new e({cause:o,message:`List.each: duplicate key ${ze(o)} in a single emission; keys must be unique (set a stable \`by\`).`}));i=w.add(i,o),r.push(o)}return r})}function q(e,t,n,r,i,a,o){return x.gen(function*(){let s=yield*Fe(e,t),c=C.empty();r.order.forEach((e,t)=>{c=C.set(c,e,t)});let l=[],u=[];for(let t=0;t<e.length;t++){let a=s[t],d=C.get(r.records,a);if(T.isSome(d))l.push(d.value),u.push(T.getOrElse(C.get(c,a),()=>-1));else{let r=yield*Ie(a,e[t],t,n,i,o);l.push(r),u.push(-1)}}let d=w.empty();for(let e of s)d=w.add(d,e);for(let e of r.order)if(!w.has(d,e)){let t=C.get(r.records,e);T.isSome(t)&&(yield*D.close(t.value.scope,S.void),Re(t.value.startMarker,t.value.endMarker))}let f=Be(u),p=a.parentNode;if(p!==null)for(let e=l.length-1;e>=0;e--){let t=l[e];if(u[e]!==-1&&f.has(e))continue;let n=e+1<l.length?l[e+1].startMarker:a,r=u[e]===-1?[t.startMarker,...t.nodes,t.endMarker]:Le(t.startMarker,t.endMarker);for(let e of r)p.insertBefore(e,n)}let m=C.empty();for(let e of l)m=C.set(m,e.key,e);return{records:m,order:s}})}function Ie(e,t,n,i,a,o){return x.gen(function*(){let s=yield*D.fork(a,`sequential`),c={...o,scope:s},l=yield*F(),u=document.createComment(g(l)),d=document.createComment(m(l)),f=yield*B(i(t,n)).pipe(x.provideService(r,c),x.provideService(D.Scope,s));return{key:e,scope:s,startMarker:u,endMarker:d,nodes:f===null?[]:Array.isArray(f)?f:[f]}})}function Le(e,t){let n=[],r=e;for(;r!==null&&(n.push(r),r!==t);)r=r.nextSibling;return n}function Re(e,t){let n=e;for(;n!==null;){let e=n.nextSibling;if(n.remove(),n===t)break;n=e}}function ze(e){if(typeof e==`string`)return JSON.stringify(e);if(typeof e==`object`&&e)try{return JSON.stringify(e)}catch{return Object.prototype.toString.call(e)}return String(e)}function Be(e){let t=e.length,n=[],r=Array.from({length:t},()=>-1);for(let i=0;i<t;i++){let t=e[i];if(t===-1)continue;let a=0,o=n.length;for(;a<o;){let r=a+o>>1;e[n[r]]<t?a=r+1:o=r}a>0&&(r[i]=n[a-1]),n[a]=i}let i=new Set,a=n.length>0?n[n.length-1]:-1;for(;a!==-1;)i.add(a),a=r[a];return i}function Ve(e,t){return x.gen(function*(){let n=yield*x.context(),i=yield*x.serviceOption(D.Scope),a=yield*D.make(),o=ne.make(te.succeedContext(y.add(n,D.Scope,a))),s={runtime:o,scope:a,streamIdCounter:{current:0}},c=x.andThen(D.close(a,S.void),x.promise(()=>o.dispose()));t.innerHTML=``;let l=yield*B(e).pipe(x.provideService(r,s),x.provideService(D.Scope,a),x.tapError(()=>c));if(l!==null)if(Array.isArray(l))for(let e of l)t.appendChild(e);else t.appendChild(l);let u=!1,d={unmount:()=>x.gen(function*(){u||(u=!0,yield*D.close(a,S.void),yield*x.promise(()=>o.dispose()))})};return T.isSome(i)&&(yield*D.addFinalizer(i.value,d.unmount())),d})}function He(e,t){return x.gen(function*(){let n=yield*x.context(),i=yield*x.serviceOption(D.Scope),a=yield*D.make(),o=ne.make(te.succeedContext(y.add(n,D.Scope,a))),s=yield*We(),c={runtime:o,scope:a,streamIdCounter:{current:0},hydrationReady:s};at(t,c.streamIdCounter);let l=x.andThen(D.close(a,S.void),x.promise(()=>o.dispose()));yield*J(e,t.firstChild,`root`).pipe(x.provideService(r,c),x.provideService(D.Scope,a),x.tapError(()=>l)),yield*s.settle,yield*s.awaitReady;let u=!1,d={unmount:()=>x.gen(function*(){u||(u=!0,yield*D.close(a,S.void),yield*x.promise(()=>o.dispose()))})};return T.isSome(i)&&(yield*D.addFinalizer(i.value,d.unmount())),d})}function J(e,t,n){return x.gen(function*(){if(typeof e==`string`||typeof e==`number`||typeof e==`bigint`)return yield*Ue(String(e),t,n);if(typeof e==`boolean`||e==null)return t;if(N(e)||x.isEffect(e)){let r=M(e);if(r!==void 0)return yield*J(r,t,n);if(x.isEffect(e)){let r=x.runSyncExit(e);if(S.isSuccess(r))return yield*J(r.value,t,n)}return yield*Ke(P(e),t,n)}if(typeof e==`object`&&Symbol.iterator in e&&!(`type`in e)){let r=t,i=0;for(let t of e)r=yield*J(t,r,`${n}[${i}]`),i++;return r}if(typeof e==`object`&&`type`in e&&!(Symbol.iterator in e)){let{type:r,props:a}=e;if(r===oe)return yield*Y(a,t,n);if(r===le){if(t!==null&&t.nodeType===Z){let e=_(t);if(e!==null&&e.kind===`start`)return yield*Je(t,n)}return yield*Y(a,t,n)}return r===ae?yield*Xe(a,t,n):r===ce?yield*Qe(a,t,n):r===se?yield*et(a,t,n):typeof r==`string`?yield*$e(r,a,t,n):typeof r==`function`?yield*J(r(a),t,n):yield*x.fail(new i({type:r,message:`Invalid Renderable type during hydration at ${n}: expected string, FRAGMENT, or function, got ${typeof r}`}))}return t})}function Ue(e,t,n){return x.gen(function*(){if(e.length===0)return t;if(t===null||t.nodeType!==it)return yield*$(`text ${JSON.stringify(e)}`,Q(t),n);let r=t;return r.data.startsWith(e)?r.data.length>e.length?r.splitText(e.length):r.nextSibling:yield*$(`text ${JSON.stringify(e)}`,Q(t),n)})}function We(){return x.gen(function*(){let e=yield*E.make(1),t=yield*b.make(),n=A(E.updateAndGet(e,e=>e-1),x.flatMap(e=>e<=0?x.asVoid(b.succeed(t,void 0)):x.void));return{register:E.update(e,e=>e+1),settle:n,awaitReady:b.await(t)}})}function Ge(e){let t=!1;return x.suspend(()=>t||e===void 0?x.void:(t=!0,e.settle))}function Ke(e,t,n){return x.gen(function*(){let i=yield*r;if(t===null||t.nodeType!==Z)return yield*$(`reactive region start marker`,Q(t),n);let a=t,o=d(a);if(o===null||o.kind!==`start`)return yield*$(`reactive region start marker`,Q(t),n);let s=ot(a);if(s===null)return yield*$(`reactive region end marker`,`unterminated region starting at ${JSON.stringify(a.data)}`,n);let c=Ge(i.hydrationReady),l=!0,u=null,f=O.runForEach(e,e=>x.gen(function*(){u!==null&&(yield*D.close(u,S.void)),u=yield*D.fork(i.scope,`sequential`);let t={...i,scope:u};yield*x.gen(function*(){l?(l=!1,yield*qe(e,a,s,n),yield*c):yield*U(a,s,e)}).pipe(x.provideService(r,t),x.provideService(D.Scope,u))})).pipe(x.ensuring(c));return i.hydrationReady!==void 0&&(yield*i.hydrationReady.register),yield*R(f,i.scope,`hydrate:stream-${o.id} (${n})`),s.nextSibling})}function qe(e,t,n,r){return x.gen(function*(){let i=yield*J(e,t.nextSibling,`${r}<resume>`).pipe(x.map(e=>e===n?null:`adopted content did not align with the end marker`),x.catchTag(`HydrationMismatchError`,e=>x.succeed(`expected ${e.expected}, found ${e.actual} at ${e.path}`)));i!==null&&(console.error(`[weft] hydrate: reactive region at ${r} diverged from server output (${i}); patching.`),yield*U(t,n,e))})}function Je(e,t){return x.gen(function*(){let n=Ye(e);if(n===null)return yield*$(`substituted suspense end marker`,`unterminated region starting at ${JSON.stringify(e.data)}`,t);let r=null;for(let t=e.nextSibling;t!==null&&t!==n;t=t.nextSibling)if(t.nodeType===X&&t.tagName===`SCRIPT`&&t.getAttribute(`type`)===`application/json`&&t.hasAttribute(`data-weft-suspense-failure`)){r=t;break}let i=null;if(r!==null){let e=r.textContent??``;i=yield*x.try({try:()=>JSON.parse(e),catch:e=>e}).pipe(x.catch(()=>x.succeed(null)))}if(typeof i!=`object`||!i||!(`error`in i))return console.error(`[weft] hydrate: substituted suspense region at ${t} has no decodable failure sentinel; leaving its static content.`),n.nextSibling;let o=yield*x.serviceOption(a);return T.isNone(o)?(console.error(`[weft] hydrate: substituted suspense region at ${t} has no enclosing Boundary to replay its failure to; leaving its static content.`,i.error),n.nextSibling):(yield*o.value.reportError(v.fail(i.error)),n.nextSibling)})}function Ye(e){let t=0,n=e.nextSibling;for(;n!==null;){if(n.nodeType===Z){let e=_(n);if(e!==null)if(e.kind===`start`)t++;else if(t===0)return n;else t--}n=n.nextSibling}return null}function Xe(e,t,n){return x.gen(function*(){if(t===null||t.nodeType!==X||t.tagName!==`SCRIPT`||t.getAttribute(`type`)!==`application/json`||!t.hasAttribute(`data-weft-boundary-failure`)){let i=yield*r,s=yield*x.serviceOption(a),c=yield*D.fork(i.scope,`sequential`),l={...i,scope:c},d=yield*b.make(),f=yield*Y(e,t,n).pipe(x.provideService(a,{reportError:e=>b.fail(d,e).pipe(x.asVoid)}),x.provideService(r,l),x.provideService(D.Scope,c)),p=t?.parentNode??null;if(t===null||t===f||p===null)return console.error(`[weft] hydrate: boundary at ${n} adopted an empty extent; live failure recovery is not installed for it.`),f;let m=pe(),h=document.createComment(o(m)),g=document.createComment(u(m));return p.insertBefore(h,t),f===null?p.appendChild(g):p.insertBefore(g,f),yield*x.forkIn(Se(e,d,c,s,h,g),i.scope),f}let i=t,s=i.textContent??``,c=yield*x.gen(function*(){let t=yield*x.try({try:()=>JSON.parse(s),catch:e=>e}),n=p(e.children)[t.index];if(n===void 0)return null;let r=yield*re.decodeUnknownEffect(n.errorSchema)(t.error);return e.match(v.fail(r))}).pipe(x.catch(e=>(console.error(`[weft] hydrate: boundary failure payload at ${n} failed to decode; cannot replay.`,e),x.succeed(null))));if(c===null)return yield*$(`replayable boundary failure`,`undecodable failure payload`,n);let l=yield*J(c,i.nextSibling,n);return i.remove(),l})}function Ze(e,t,n,r){return x.gen(function*(){let i=yield*k.make(n),a=yield*k.make(!1),o=yield*k.make(T.none()),s=T.match(r,{onNone:()=>x.void,onSome:n=>x.gen(function*(){(yield*k.get(a))||(yield*k.set(a,!0),yield*x.gen(function*(){let r=yield*x.exit(n.call(e,t()));S.isSuccess(r)?(yield*k.set(i,r.value),yield*k.set(o,T.none())):yield*k.set(o,T.some(v.squash(r.cause)))}).pipe(x.ensuring(k.set(a,!1))))})});return{value:j.make({get:k.get(i),changes:k.changes(i)}),refetch:s,pending:j.make({get:k.get(a),changes:k.changes(a)}),error:j.make({get:k.get(o),changes:k.changes(o)})}})}function Qe(e,t,n){return x.gen(function*(){if(t===null||t.nodeType!==X||t.tagName!==`SCRIPT`||t.getAttribute(`type`)!==`application/json`)return yield*$(`server boundary payload <script type="application/json">`,Q(t),n);if(t.hasAttribute(`data-weft-boundary-failure`))return yield*$(`server boundary success payload <script type="application/json">`,`boundary failure payload`,n);let r=t,i=r.textContent??``,a=yield*x.try({try:()=>JSON.parse(i),catch:e=>e}).pipe(x.flatMap(t=>re.decodeUnknownEffect(e.successSchema)(t)),x.catch(e=>(console.error(`[weft] hydrate: server boundary payload at ${n} failed to decode; cannot replay.`,e),$(`decodable server boundary payload`,`undecodable payload`,n)))),o=yield*x.serviceOption(ie),s=yield*Ze(e.tag,e.payload,a,o),c=yield*J(e.render(s),r.nextSibling,n);return r.remove(),c})}function $e(e,t,n,r){return x.gen(function*(){if(n===null||n.nodeType!==X)return yield*$(`<${e}>`,Q(n),r);let i=n;return i.tagName.toLowerCase()===e.toLowerCase()?(yield*I(i,t),yield*Y(t,i.firstChild,`${r} > ${e}`),i.nextSibling):yield*$(`<${e}>`,Q(n),r)})}function Y(e,t,n){return x.gen(function*(){let r=`children`in e?e.children:void 0;if(r===void 0)return t;let i=Array.isArray(r)?r:[r],a=t,o=0;for(let e of i)a=yield*J(e,a,`${n}[${o}]`),o++;return a})}function et(e,t,n){return x.gen(function*(){let i=yield*r,{of:a,by:o,render:s}=e;if(t===null||t.nodeType!==Z)return yield*$(`list region start marker`,Q(t),n);let c=t,l=d(c);if(l===null||l.kind!==`start`)return yield*$(`list region start marker`,Q(t),n);let u=ot(c);if(u===null)return yield*$(`list region end marker`,`unterminated region starting at ${JSON.stringify(c.data)}`,n);let f=tt(c,u),p=yield*D.fork(i.scope,`sequential`),m=(yield*ue.toSubscribable(a).pipe(x.provideService(D.Scope,p))).changes,h={records:C.empty(),order:[]},g=!0,_=Ge(i.hydrationReady),v=O.runForEach(m,e=>x.gen(function*(){let t=Array.from(e);g?(g=!1,h=yield*nt(t,o,s,f,p,c,u,i,n),yield*_):h=yield*q(t,o,s,h,p,u,i)})).pipe(x.ensuring(_));return i.hydrationReady!==void 0&&(yield*i.hydrationReady.register),yield*R(v,p,`hydrate:list-${l.id} (${n})`),u.nextSibling})}function tt(e,t){let n=[],r=e.nextSibling;for(;r!==null&&r!==t;){let e=r.nodeType===Z?s(r):null;if(e===null||e.kind!==`start`){r=r.nextSibling;continue}let i=r,a=[],o=0,c=null,l=i.nextSibling;for(;l!==null&&l!==t;){if(l.nodeType===Z){let e=s(l);if(e!==null)if(e.kind===`start`)o++;else if(o===0){c=l;break}else o--}a.push(l),l=l.nextSibling}if(c===null)break;n.push({startMarker:i,endMarker:c,nodes:a}),r=c.nextSibling}return n}function nt(e,t,n,r,i,a,o,s,c){return x.gen(function*(){let l=yield*Fe(e,t);if(l.length!==r.length)return console.error(`[weft] hydrate: list region at ${c} had ${r.length} server item(s) but the first emission has ${l.length}; rebuilding.`),K(a,o),yield*q(e,t,n,{records:C.empty(),order:[]},i,o,s);let u=[];for(let t=0;t<e.length;t++){let a=yield*rt(l[t],e[t],t,n,r[t],i,s,c);u.push(a)}let d=C.empty();for(let e of u)d=C.set(d,e.key,e);return{records:d,order:l}})}function rt(e,t,n,i,a,o,s,c){return x.gen(function*(){let l=yield*D.fork(o,`sequential`),u={...s,scope:l},d=i(t,n),f=yield*J(d,a.startMarker.nextSibling,`${c}<item>`).pipe(x.provideService(r,u),x.provideService(D.Scope,l),x.map(e=>e===a.endMarker?null:`adopted item content did not align with its end marker`),x.catchTag(`HydrationMismatchError`,e=>x.succeed(`expected ${e.expected}, found ${e.actual} at ${e.path}`)));if(f===null)return{key:e,scope:l,startMarker:a.startMarker,endMarker:a.endMarker,nodes:a.nodes};console.error(`[weft] hydrate: list item at ${c} diverged from server output (${f}); patching.`),yield*D.close(l,S.void);let p=yield*D.fork(o,`sequential`),m={...s,scope:p};K(a.startMarker,a.endMarker);let h=yield*B(d).pipe(x.provideService(r,m),x.provideService(D.Scope,p)),g=h===null?[]:Array.isArray(h)?h:[h],_=a.endMarker.parentNode;if(_!==null)for(let e of g)_.insertBefore(e,a.endMarker);return{key:e,scope:p,startMarker:a.startMarker,endMarker:a.endMarker,nodes:g}})}const X=1,it=3,Z=8;function at(e,t){let n=document.createTreeWalker(e,128),r=t.current;for(let e=n.nextNode();e!==null;e=n.nextNode()){let t=e,n=d(t)??_(t)??s(t);n!==null&&n.id>r&&(r=n.id)}t.current=r}function ot(e){let t=0,n=e.nextSibling;for(;n!==null;){if(n.nodeType===8){let e=d(n);if(e!==null)if(e.kind===`start`)t++;else if(t===0)return n;else t--}n=n.nextSibling}return null}function Q(e){if(e===null)return`end of children`;switch(e.nodeType){case 1:return`<${e.tagName.toLowerCase()}>`;case 3:return`text ${JSON.stringify(e.data)}`;case 8:return`comment ${JSON.stringify(e.data)}`;default:return`node(type ${e.nodeType})`}}function $(e,n,r){return x.fail(new t({expected:e,actual:n,path:r}))}function st(e,t){return A(Ve(e,t),x.tap(e=>x.addFinalizer(()=>e.unmount())))}function ct(e,t){return A(He(e,t),x.tap(e=>x.addFinalizer(()=>e.unmount())))}export{He as hydrate,ct as hydrateScoped,Ve as mount,st as mountScoped};
|
|
1
|
+
import{t as e}from"../rolldown-runtime-DK3Fl9T5.js";import{i as t,n,o as r,r as i,s as a,t as o}from"../data-uLmMpQMV.js";import{a as s,c,d as l,f as u,i as d,l as f,m as p,n as m,o as h,p as g,s as _,u as v}from"../boundary-replay-BR26_puM.js";import{Cause as y,Context as b,Deferred as x,Effect as S,Exit as C,Fiber as ee,HashMap as w,HashSet as T,Layer as te,ManagedRuntime as ne,Option as E,PubSub as D,Ref as O,Schema as re,Scope as k,Stream as A,SubscriptionRef as j,pipe as M}from"effect";import{AppRpcClientTag as ie,FAILURE_BOUNDARY as ae,FRAGMENT as oe,LIST as se,SERVER_BOUNDARY as ce,SUSPENSE_BOUNDARY as le,Source as ue,Subscribable as de,getElementDescriptor as N,isStream as P,toStream as F}from"@weftui/core";function I(){return S.gen(function*(){let e=yield*i;return++e.streamIdCounter.current})}const fe=I;let pe=0;const L=()=>++pe;function me(e){if(e.length<=2||!e.startsWith(`on`))return!1;let t=e[2];return t!==void 0&&t>=`a`&&t<=`z`}function R(e,t){return S.gen(function*(){for(let[n,r]of Object.entries(t))if(n!==`children`){if(me(n)){yield*xe(e,n,r);continue}if(n===`ref`&&typeof r==`object`&&j.isSubscriptionRef(r)){yield*j.set(r,E.some(e));continue}if(n===`style`){yield*ye(e,r);continue}he(e,n)?yield*ge(e,n,r):yield*_e(e,n,r)}})}function he(e,t){if(t.startsWith(`data-`)||t.startsWith(`aria-`))return!1;let n=Object.getPrototypeOf(e);for(;n!==null;){if(Object.hasOwn(n,t))return!0;n=Object.getPrototypeOf(n)}return t in e}function ge(e,t,n){return S.gen(function*(){P(n)||S.isEffect(n)?yield*V(F(n),n=>{n==null?delete e[t]:e[t]=n},`property:${t}`):n!=null&&(e[t]=n)})}function _e(e,t,n){return S.gen(function*(){if(P(n)||S.isEffect(n))yield*V(F(n),n=>{if(n==null)e.removeAttribute(t);else{let r=ve(n);r!==void 0&&(typeof n==`boolean`?n?e.setAttribute(t,``):e.removeAttribute(t):e.setAttribute(t,r))}},`attribute:${t}`);else{let r=ve(n);r!==void 0&&(typeof n==`boolean`?n?e.setAttribute(t,``):e.removeAttribute(t):e.setAttribute(t,r))}})}function ve(e){if(e!=null)return String(e)}function ye(e,t){return S.gen(function*(){if(P(t)||S.isEffect(t)){yield*V(F(t),t=>{if(typeof t==`string`)e.setAttribute(`style`,t);else if(typeof t==`object`&&t){e.style.cssText=``;for(let[n,r]of Object.entries(t))r!=null&&e.style.setProperty(z(n),String(r))}},`style`);return}if(typeof t==`string`){e.setAttribute(`style`,t);return}typeof t==`object`&&t&&(yield*be(e,t))})}function be(e,t){return S.gen(function*(){for(let[n,r]of Object.entries(t))P(r)||S.isEffect(r)?yield*V(F(r),t=>{t!=null&&e.style.setProperty(z(n),String(t))},`style.${n}`):r!=null&&e.style.setProperty(z(n),String(r))})}function z(e){return e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}function B(e,t,n,r){return S.gen(function*(){let i=yield*S.serviceOption(o);if(E.isNone(i)){let i=yield*S.forkIn(e,t);return yield*M(ee.await(i),S.flatMap(e=>C.isFailure(e)&&!y.hasInterruptsOnly(e.cause)?r(e.cause,n):S.void),S.forkIn(t)),i}let a=yield*S.forkIn(e,t);return yield*M(ee.await(a),S.flatMap(e=>C.isFailure(e)?i.value.reportError(e.cause):S.void),S.forkIn(t)),a})}function V(e,t,n){return S.gen(function*(){let r=yield*i;yield*B(A.runForEach(e,e=>S.sync(()=>void t(e))),r.scope,n,r.reportUnhandled)})}function xe(e,t,n){return S.gen(function*(){let r=yield*i,a=t.slice(2).toLowerCase(),o=null,s=()=>{o&&=(e.removeEventListener(a,o),null)},c=n=>{s(),!(n==null||n===!1)&&typeof n==`function`&&(o=e=>{let i=n(e);S.isEffect(i)&&r.runtime.runFork(M(i,S.provideService(k.Scope,r.rootScope),S.exit,S.flatMap(e=>C.isFailure(e)&&!y.hasInterruptsOnly(e.cause)?r.reportUnhandled(e.cause,`event:${t}`):S.void)))},e.addEventListener(a,o))};yield*k.addFinalizer(r.scope,S.sync(s)),P(n)||S.isEffect(n)?yield*V(F(n),e=>c(e),`event:${t}`):c(n)})}function Se(e,t,n,r,a,o){return S.gen(function*(){let s=yield*i,c=yield*x.await(t).pipe(S.flip,S.catch(()=>S.interrupt)),l=e.match(c);if(yield*k.close(n,C.void),l===null)return E.isSome(r)?yield*r.value.reportError(c):yield*s.reportUnhandled(c,`boundary:outermost`);K(a,o);let u=yield*H(l),d=o.parentNode;if(d!==null&&u!==null)if(Array.isArray(u))for(let e of u)d.insertBefore(e,o);else d.insertBefore(u,o)})}function Ce(e){return S.gen(function*(){let t=yield*i,n=yield*S.serviceOption(o),r=L(),a=document.createComment(s(r)),c=document.createComment(d(r)),l=yield*k.fork(t.scope,`sequential`),u={...t,scope:l},f=yield*x.make(),p=yield*M(U(e.children),S.provideService(o,{reportError:e=>x.fail(f,e).pipe(S.asVoid)}),S.provideService(i,u),S.provideService(k.Scope,l),S.catchCause(t=>{let n=e.match(t);return n===null?S.failCause(t):M(k.close(l,C.void),S.flatMap(()=>H(n)),S.map(e=>e===null?[]:Array.isArray(e)?e:[e]))}));return yield*S.forkIn(Se(e,f,l,n,a,c),t.scope),[a,...p,c]})}function we(e){return S.gen(function*(){let t=yield*i,n=yield*O.make(1),a=yield*x.make(),o=M(O.updateAndGet(n,e=>e-1),S.flatMap(e=>e<=0?S.asVoid(x.succeed(a,void 0)):S.void)),s={register:O.update(n,e=>e+1),settle:o},c=e.children,l=yield*H((c===void 0?[]:Array.isArray(c)?c:[c]).map(e=>N(e)===void 0&&(S.isEffect(e)||P(e))?{type:()=>e,props:{}}:e)).pipe(S.provideService(r,s)),u=l===null?[]:Array.isArray(l)?l:[l];yield*o;let d=yield*x.poll(a);if(E.isSome(d))return u;let f=yield*fe(),m=document.createComment(p(f)),h=document.createComment(g(f)),_=yield*H(e.fallback??null),v=[];_!==null&&(Array.isArray(_)?v.push(..._):v.push(_));let y=document.createDocumentFragment();for(let e of u)y.appendChild(e);let b=S.gen(function*(){yield*x.await(a),K(m,h);let e=h.parentNode;e!==null&&(e.insertBefore(y,h),m.remove(),h.remove())});return yield*S.forkIn(b,t.scope),[m,...v,h]})}function Te(e){return S.gen(function*(){let n=yield*i,r=yield*S.serviceOption(ie);if(E.isNone(r))return yield*S.fail(new t({cause:void 0,message:`Boundary.rpc "${e.tag}" was mounted client-first without an AppRpcClient in context. Mount the app under @weftui/router (RouterLive), which provides the rpc client, so the boundary can resolve its data.`}));let a=r.value,o=L(),c=document.createComment(s(o)),l=document.createComment(d(o)),u=yield*H(e.fallback??null),f=[];u!==null&&(Array.isArray(u)?f.push(...u):f.push(u));let p=S.gen(function*(){let t=yield*a.call(e.tag,e.payload()),n=yield*Qe(e.tag,e.payload,t,r),i=yield*H(e.render(n));K(c,l);let o=l.parentNode;if(o!==null&&i!==null)if(Array.isArray(i))for(let e of i)o.insertBefore(e,l);else o.insertBefore(i,l)}).pipe(S.catchCause(t=>S.logError(`[weft] Boundary.rpc "${e.tag}" mount failed to resolve; fallback left in place.`,t)));return yield*S.forkIn(p,n.scope),[c,...f,l]})}function H(e){return S.gen(function*(){if(typeof e==`string`||typeof e==`number`||typeof e==`bigint`)return document.createTextNode(String(e));if(typeof e==`boolean`||e==null)return null;if(P(e)||S.isEffect(e)){let t=N(e);if(t!==void 0)return yield*H(t);if(S.isEffect(e)){let t=yield*S.context(),n=S.runSyncExitWith(t)(e);if(C.isSuccess(n))return yield*H(n.value)}return yield*W(F(e))}if(typeof e==`object`&&Symbol.iterator in e&&!(`type`in e))return yield*U(Ee(e));if(typeof e==`object`&&`type`in e&&!(Symbol.iterator in e)){let{type:t,props:n}=e;return t===oe?yield*De(n):t===le?yield*we(n):t===ce?yield*Te(n):t===ae?yield*Ce(n):t===se?yield*Ie(n):typeof t==`string`?yield*Oe(t,n):typeof t==`function`?yield*ke(t,n):yield*S.fail(new a({type:t,message:`Invalid Renderable type: expected string, FRAGMENT, or function, got ${typeof t}`}))}return null})}function Ee(e){let t=[];function n(e){if(P(e)||S.isEffect(e)){t.push(e);return}if(typeof e==`object`&&e&&Symbol.iterator in e&&!(`type`in e))for(let t of e)n(t);else t.push(e)}return n(e),t}function U(e){return S.gen(function*(){let t=[];for(let n of e)if(N(n)===void 0&&(P(n)||S.isEffect(n))){let e=yield*W(F(n));t.push(...e)}else{let e=yield*H(n);e!==null&&(Array.isArray(e)?t.push(...e):t.push(e))}return t})}function De(e){return S.gen(function*(){let t=`children`in e?e.children:void 0;return t===void 0?[]:yield*U(Array.isArray(t)?t:[t])})}function Oe(e,t){return S.gen(function*(){let n=document.createElement(e);yield*R(n,t);let r=`children`in t?t.children:void 0;if(r!==void 0){let e=Array.isArray(r)?r:[r];for(let t of e)if(N(t)===void 0&&(P(t)||S.isEffect(t))){let e=yield*W(F(t));for(let t of e)n.appendChild(t)}else{let e=yield*H(t);if(e!==null)if(Array.isArray(e))for(let t of e)n.appendChild(t);else n.appendChild(e)}}return n})}function ke(e,t){return S.gen(function*(){let n=e(t);if(P(n)||S.isEffect(n)){let e=yield*i,t=yield*k.fork(e.scope,`sequential`),a={...e,scope:t},o=yield*S.serviceOption(r),s=F(n);return E.isSome(o)&&(yield*o.value.register,s=M(s,A.zipWithIndex,A.flatMap(([e,t])=>t===0?A.fromEffect(S.as(o.value.settle,e)):A.make(e)))),yield*W(s).pipe(S.provideService(i,a),S.provideService(k.Scope,t))}return yield*H(n)})}function W(e){return S.gen(function*(){let t=yield*i,n=yield*I(),[r,a]=Ae(n),o=null;return yield*B(A.runForEach(e,e=>S.gen(function*(){o!==null&&(yield*k.close(o,C.void)),o=yield*k.fork(t.scope,`sequential`);let n={...t,scope:o};yield*G(r,a,e).pipe(S.provideService(i,n),S.provideService(k.Scope,o))})),t.scope,`child:stream-${n}`,t.reportUnhandled),[r,a]})}function Ae(e){return[document.createComment(u(e)),document.createComment(l(e))]}function G(e,t,n){return S.gen(function*(){let r=e.nextSibling,i=r!==null&&r!==t&&r.nextSibling===t;if(i&&r.nodeType===at&&je(n)){let e=String(n);r.data!==e&&(r.data=e);return}if(i&&r.nodeType===Y){let e=Me(n);if(e!==void 0&&typeof e.type==`string`&&r.tagName.toLowerCase()===e.type.toLowerCase()){yield*Ne(r,e);return}}K(e,t);let a=yield*H(n),o=e.parentNode;if(o!==null&&a!==null)if(Array.isArray(a))for(let e of a)o.insertBefore(e,t);else o.insertBefore(a,t)})}function je(e){return typeof e==`string`||typeof e==`number`||typeof e==`bigint`}function Me(e){let t=N(e);if(t!==void 0)return t;if(typeof e==`object`&&e&&`type`in e&&!(Symbol.iterator in e)&&!P(e)&&!S.isEffect(e))return e}function Ne(e,t){return S.gen(function*(){yield*R(e,t.props);let n=t.props.children,r=n===void 0?[]:Array.isArray(n)?n:[n];if(!(yield*Pe(e,r))){for(;e.firstChild!==null;)e.firstChild.remove();yield*Fe(e,r)}})}function Pe(e,t){return S.gen(function*(){let n=Array.from(e.childNodes);if(n.length!==t.length)return!1;for(let e=0;e<t.length;e++){let r=t[e],i=n[e];if(je(r)){if(i.nodeType!==at)return!1}else{let e=Me(r);if(e===void 0||typeof e.type!=`string`||i.nodeType!==Y||i.tagName.toLowerCase()!==e.type.toLowerCase())return!1}}for(let e=0;e<t.length;e++){let r=t[e],i=n[e];if(je(r)){let e=String(r);i.data!==e&&(i.data=e)}else yield*Ne(i,Me(r))}return!0})}function Fe(e,t){return S.gen(function*(){for(let n of t)if(P(n)||S.isEffect(n)){let t=yield*W(F(n));for(let n of t)e.appendChild(n)}else{let t=yield*H(n);if(t!==null)if(Array.isArray(t))for(let n of t)e.appendChild(n);else e.appendChild(t)}})}function K(e,t){let n=e.nextSibling;for(;n!==null&&n!==t;){let e=n.nextSibling;n.remove(),n=e}}function Ie(e){return S.gen(function*(){let t=yield*i,{of:n,by:r,render:a}=e,o=yield*I(),[s,c]=Ae(o),l=yield*k.fork(t.scope,`sequential`),u=(yield*ue.toSubscribable(n).pipe(S.provideService(k.Scope,l))).changes,d={records:w.empty(),order:[]};return yield*B(A.runForEach(u,e=>S.gen(function*(){d=yield*Re(Array.from(e),r,a,d,l,c,t)})),l,`list:stream-${o}`,t.reportUnhandled),[s,c]})}function Le(e,n){return S.gen(function*(){let r=[],i=T.empty();for(let a=0;a<e.length;a++){let o=n===void 0?e[a]:n(e[a],a);if(T.has(i,o))return yield*S.fail(new t({cause:o,message:`List.each: duplicate key ${He(o)} in a single emission; keys must be unique (set a stable \`by\`).`}));i=T.add(i,o),r.push(o)}return r})}function Re(e,t,n,r,i,a,o){return S.gen(function*(){let s=yield*Le(e,t),c=w.empty();r.order.forEach((e,t)=>{c=w.set(c,e,t)});let l=[],u=[];for(let t=0;t<e.length;t++){let a=s[t],d=w.get(r.records,a);if(E.isSome(d))l.push(d.value),u.push(E.getOrElse(w.get(c,a),()=>-1));else{let r=yield*ze(a,e[t],t,n,i,o);l.push(r),u.push(-1)}}let d=T.empty();for(let e of s)d=T.add(d,e);for(let e of r.order)if(!T.has(d,e)){let t=w.get(r.records,e);E.isSome(t)&&(yield*k.close(t.value.scope,C.void),Ve(t.value.startMarker,t.value.endMarker))}let f=Ue(u),p=a.parentNode;if(p!==null)for(let e=l.length-1;e>=0;e--){let t=l[e];if(u[e]!==-1&&f.has(e))continue;let n=e+1<l.length?l[e+1].startMarker:a,r=u[e]===-1?[t.startMarker,...t.nodes,t.endMarker]:Be(t.startMarker,t.endMarker);for(let e of r)p.insertBefore(e,n)}let m=w.empty();for(let e of l)m=w.set(m,e.key,e);return{records:m,order:s}})}function ze(e,t,n,r,a,o){return S.gen(function*(){let s=yield*k.fork(a,`sequential`),c={...o,scope:s},l=yield*I(),u=document.createComment(_(l)),d=document.createComment(h(l)),f=yield*H(r(t,n)).pipe(S.provideService(i,c),S.provideService(k.Scope,s));return{key:e,scope:s,startMarker:u,endMarker:d,nodes:f===null?[]:Array.isArray(f)?f:[f]}})}function Be(e,t){let n=[],r=e;for(;r!==null&&(n.push(r),r!==t);)r=r.nextSibling;return n}function Ve(e,t){let n=e;for(;n!==null;){let e=n.nextSibling;if(n.remove(),n===t)break;n=e}}function He(e){if(typeof e==`string`)return JSON.stringify(e);if(typeof e==`object`&&e)try{return JSON.stringify(e)}catch{return Object.prototype.toString.call(e)}return String(e)}function Ue(e){let t=e.length,n=[],r=Array.from({length:t},()=>-1);for(let i=0;i<t;i++){let t=e[i];if(t===-1)continue;let a=0,o=n.length;for(;a<o;){let r=a+o>>1;e[n[r]]<t?a=r+1:o=r}a>0&&(r[i]=n[a-1]),n[a]=i}let i=new Set,a=n.length>0?n[n.length-1]:-1;for(;a!==-1;)i.add(a),a=r[a];return i}function q(e,t,n){return S.gen(function*(){if(typeof e==`string`||typeof e==`number`||typeof e==`bigint`)return yield*We(String(e),t,n);if(typeof e==`boolean`||e==null)return t;if(P(e)||S.isEffect(e)){let r=N(e);if(r!==void 0)return yield*q(r,t,n);if(S.isEffect(e)){let r=S.runSyncExit(e);if(C.isSuccess(r))return yield*q(r.value,t,n)}return yield*qe(F(e),t,n)}if(typeof e==`object`&&Symbol.iterator in e&&!(`type`in e)){let r=t,i=0;for(let t of e)r=yield*q(t,r,`${n}[${i}]`),i++;return r}if(typeof e==`object`&&`type`in e&&!(Symbol.iterator in e)){let{type:r,props:i}=e;if(r===oe)return yield*J(i,t,n);if(r===le){if(t!==null&&t.nodeType===X){let e=v(t);if(e!==null&&e.kind===`start`)return yield*Ye(t,n)}return yield*J(i,t,n)}return r===ae?yield*Ze(i,t,n):r===ce?yield*$e(i,t,n):r===se?yield*tt(i,t,n):typeof r==`string`?yield*et(r,i,t,n):typeof r==`function`?yield*q(r(i),t,n):yield*S.fail(new a({type:r,message:`Invalid Renderable type during hydration at ${n}: expected string, FRAGMENT, or function, got ${typeof r}`}))}return t})}function We(e,t,n){return S.gen(function*(){if(e.length===0)return t;if(t===null||t.nodeType!==at)return yield*Q(`text ${JSON.stringify(e)}`,Z(t),n);let r=t;return r.data.startsWith(e)?r.data.length>e.length?r.splitText(e.length):r.nextSibling:yield*Q(`text ${JSON.stringify(e)}`,Z(t),n)})}function Ge(){return S.gen(function*(){let e=yield*O.make(1),t=yield*x.make(),n=M(O.updateAndGet(e,e=>e-1),S.flatMap(e=>e<=0?S.asVoid(x.succeed(t,void 0)):S.void));return{register:O.update(e,e=>e+1),settle:n,awaitReady:x.await(t)}})}function Ke(e){let t=!1;return S.suspend(()=>t||e===void 0?S.void:(t=!0,e.settle))}function qe(e,t,n){return S.gen(function*(){let r=yield*i;if(t===null||t.nodeType!==X)return yield*Q(`reactive region start marker`,Z(t),n);let a=t,o=f(a);if(o===null||o.kind!==`start`)return yield*Q(`reactive region start marker`,Z(t),n);let s=st(a);if(s===null)return yield*Q(`reactive region end marker`,`unterminated region starting at ${JSON.stringify(a.data)}`,n);let c=Ke(r.hydrationReady),l=!0,u=null,d=A.runForEach(e,e=>S.gen(function*(){u!==null&&(yield*k.close(u,C.void)),u=yield*k.fork(r.scope,`sequential`);let t={...r,scope:u};yield*S.gen(function*(){l?(l=!1,yield*Je(e,a,s,n),yield*c):yield*G(a,s,e)}).pipe(S.provideService(i,t),S.provideService(k.Scope,u))})).pipe(S.ensuring(c));return r.hydrationReady!==void 0&&(yield*r.hydrationReady.register),yield*B(d,r.scope,`hydrate:stream-${o.id} (${n})`,r.reportUnhandled),s.nextSibling})}function Je(e,t,n,r){return S.gen(function*(){let i=yield*q(e,t.nextSibling,`${r}<resume>`).pipe(S.map(e=>e===n?null:`adopted content did not align with the end marker`),S.catchTag(`HydrationMismatchError`,e=>S.succeed(`expected ${e.expected}, found ${e.actual} at ${e.path}`)));i!==null&&(console.error(`[weft] hydrate: reactive region at ${r} diverged from server output (${i}); patching.`),yield*G(t,n,e))})}function Ye(e,t){return S.gen(function*(){let n=Xe(e);if(n===null)return yield*Q(`substituted suspense end marker`,`unterminated region starting at ${JSON.stringify(e.data)}`,t);let r=null;for(let t=e.nextSibling;t!==null&&t!==n;t=t.nextSibling)if(t.nodeType===Y&&t.tagName===`SCRIPT`&&t.getAttribute(`type`)===`application/json`&&t.hasAttribute(`data-weft-suspense-failure`)){r=t;break}let i=null;if(r!==null){let e=r.textContent??``;i=yield*S.try({try:()=>JSON.parse(e),catch:e=>e}).pipe(S.catch(()=>S.succeed(null)))}if(typeof i!=`object`||!i||!(`error`in i))return console.error(`[weft] hydrate: substituted suspense region at ${t} has no decodable failure sentinel; leaving its static content.`),n.nextSibling;let a=yield*S.serviceOption(o);return E.isNone(a)?(console.error(`[weft] hydrate: substituted suspense region at ${t} has no enclosing Boundary to replay its failure to; leaving its static content.`,i.error),n.nextSibling):(yield*a.value.reportError(y.fail(i.error)),n.nextSibling)})}function Xe(e){let t=0,n=e.nextSibling;for(;n!==null;){if(n.nodeType===X){let e=v(n);if(e!==null)if(e.kind===`start`)t++;else if(t===0)return n;else t--}n=n.nextSibling}return null}function Ze(e,t,n){return S.gen(function*(){if(t===null||t.nodeType!==Y||t.tagName!==`SCRIPT`||t.getAttribute(`type`)!==`application/json`||!t.hasAttribute(`data-weft-boundary-failure`)){let r=yield*i,a=yield*S.serviceOption(o),c=yield*k.fork(r.scope,`sequential`),l={...r,scope:c},u=yield*x.make(),f=yield*J(e,t,n).pipe(S.provideService(o,{reportError:e=>x.fail(u,e).pipe(S.asVoid)}),S.provideService(i,l),S.provideService(k.Scope,c)),p=t?.parentNode??null;if(t===null||t===f||p===null)return console.error(`[weft] hydrate: boundary at ${n} adopted an empty extent; live failure recovery is not installed for it.`),f;let m=L(),h=document.createComment(s(m)),g=document.createComment(d(m));return p.insertBefore(h,t),f===null?p.appendChild(g):p.insertBefore(g,f),yield*S.forkIn(Se(e,u,c,a,h,g),r.scope),f}let r=t,a=r.textContent??``,c=yield*S.gen(function*(){let t=yield*S.try({try:()=>JSON.parse(a),catch:e=>e}),n=m(e.children)[t.index];if(n===void 0)return null;let r=yield*re.decodeUnknownEffect(n.errorSchema)(t.error);return e.match(y.fail(r))}).pipe(S.catch(e=>(console.error(`[weft] hydrate: boundary failure payload at ${n} failed to decode; cannot replay.`,e),S.succeed(null))));if(c===null)return yield*Q(`replayable boundary failure`,`undecodable failure payload`,n);let l=yield*q(c,r.nextSibling,n);return r.remove(),l})}function Qe(e,t,n,r){return S.gen(function*(){let i=yield*j.make(n),a=yield*j.make(!1),o=yield*j.make(E.none()),s=E.match(r,{onNone:()=>S.void,onSome:n=>S.gen(function*(){(yield*j.get(a))||(yield*j.set(a,!0),yield*S.gen(function*(){let r=yield*S.exit(n.call(e,t()));C.isSuccess(r)?(yield*j.set(i,r.value),yield*j.set(o,E.none())):yield*j.set(o,E.some(y.squash(r.cause)))}).pipe(S.ensuring(j.set(a,!1))))})});return{value:de.make({get:j.get(i),changes:j.changes(i)}),refetch:s,pending:de.make({get:j.get(a),changes:j.changes(a)}),error:de.make({get:j.get(o),changes:j.changes(o)})}})}function $e(e,t,n){return S.gen(function*(){if(t===null||t.nodeType!==Y||t.tagName!==`SCRIPT`||t.getAttribute(`type`)!==`application/json`)return yield*Q(`server boundary payload <script type="application/json">`,Z(t),n);if(t.hasAttribute(`data-weft-boundary-failure`))return yield*Q(`server boundary success payload <script type="application/json">`,`boundary failure payload`,n);let r=t,i=r.textContent??``,a=yield*S.try({try:()=>JSON.parse(i),catch:e=>e}).pipe(S.flatMap(t=>re.decodeUnknownEffect(e.successSchema)(t)),S.catch(e=>(console.error(`[weft] hydrate: server boundary payload at ${n} failed to decode; cannot replay.`,e),Q(`decodable server boundary payload`,`undecodable payload`,n)))),o=yield*S.serviceOption(ie),s=yield*Qe(e.tag,e.payload,a,o),c=yield*q(e.render(s),r.nextSibling,n);return r.remove(),c})}function et(e,t,n,r){return S.gen(function*(){if(n===null||n.nodeType!==Y)return yield*Q(`<${e}>`,Z(n),r);let i=n;return i.tagName.toLowerCase()===e.toLowerCase()?(yield*R(i,t),yield*J(t,i.firstChild,`${r} > ${e}`),i.nextSibling):yield*Q(`<${e}>`,Z(n),r)})}function J(e,t,n){return S.gen(function*(){let r=`children`in e?e.children:void 0;if(r===void 0)return t;let i=Array.isArray(r)?r:[r],a=t,o=0;for(let e of i)a=yield*q(e,a,`${n}[${o}]`),o++;return a})}function tt(e,t,n){return S.gen(function*(){let r=yield*i,{of:a,by:o,render:s}=e;if(t===null||t.nodeType!==X)return yield*Q(`list region start marker`,Z(t),n);let c=t,l=f(c);if(l===null||l.kind!==`start`)return yield*Q(`list region start marker`,Z(t),n);let u=st(c);if(u===null)return yield*Q(`list region end marker`,`unterminated region starting at ${JSON.stringify(c.data)}`,n);let d=nt(c,u),p=yield*k.fork(r.scope,`sequential`),m=(yield*ue.toSubscribable(a).pipe(S.provideService(k.Scope,p))).changes,h={records:w.empty(),order:[]},g=!0,_=Ke(r.hydrationReady),v=A.runForEach(m,e=>S.gen(function*(){let t=Array.from(e);g?(g=!1,h=yield*rt(t,o,s,d,p,c,u,r,n),yield*_):h=yield*Re(t,o,s,h,p,u,r)})).pipe(S.ensuring(_));return r.hydrationReady!==void 0&&(yield*r.hydrationReady.register),yield*B(v,p,`hydrate:list-${l.id} (${n})`,r.reportUnhandled),u.nextSibling})}function nt(e,t){let n=[],r=e.nextSibling;for(;r!==null&&r!==t;){let e=r.nodeType===X?c(r):null;if(e===null||e.kind!==`start`){r=r.nextSibling;continue}let i=r,a=[],o=0,s=null,l=i.nextSibling;for(;l!==null&&l!==t;){if(l.nodeType===X){let e=c(l);if(e!==null)if(e.kind===`start`)o++;else if(o===0){s=l;break}else o--}a.push(l),l=l.nextSibling}if(s===null)break;n.push({startMarker:i,endMarker:s,nodes:a}),r=s.nextSibling}return n}function rt(e,t,n,r,i,a,o,s,c){return S.gen(function*(){let l=yield*Le(e,t);if(l.length!==r.length)return console.error(`[weft] hydrate: list region at ${c} had ${r.length} server item(s) but the first emission has ${l.length}; rebuilding.`),K(a,o),yield*Re(e,t,n,{records:w.empty(),order:[]},i,o,s);let u=[];for(let t=0;t<e.length;t++){let a=yield*it(l[t],e[t],t,n,r[t],i,s,c);u.push(a)}let d=w.empty();for(let e of u)d=w.set(d,e.key,e);return{records:d,order:l}})}function it(e,t,n,r,a,o,s,c){return S.gen(function*(){let l=yield*k.fork(o,`sequential`),u={...s,scope:l},d=r(t,n),f=yield*q(d,a.startMarker.nextSibling,`${c}<item>`).pipe(S.provideService(i,u),S.provideService(k.Scope,l),S.map(e=>e===a.endMarker?null:`adopted item content did not align with its end marker`),S.catchTag(`HydrationMismatchError`,e=>S.succeed(`expected ${e.expected}, found ${e.actual} at ${e.path}`)));if(f===null)return{key:e,scope:l,startMarker:a.startMarker,endMarker:a.endMarker,nodes:a.nodes};console.error(`[weft] hydrate: list item at ${c} diverged from server output (${f}); patching.`),yield*k.close(l,C.void);let p=yield*k.fork(o,`sequential`),m={...s,scope:p};K(a.startMarker,a.endMarker);let h=yield*H(d).pipe(S.provideService(i,m),S.provideService(k.Scope,p)),g=h===null?[]:Array.isArray(h)?h:[h],_=a.endMarker.parentNode;if(_!==null)for(let e of g)_.insertBefore(e,a.endMarker);return{key:e,scope:p,startMarker:a.startMarker,endMarker:a.endMarker,nodes:g}})}const Y=1,at=3,X=8;function ot(e,t){let n=document.createTreeWalker(e,128),r=t.current;for(let e=n.nextNode();e!==null;e=n.nextNode()){let t=e,n=f(t)??v(t)??c(t);n!==null&&n.id>r&&(r=n.id)}t.current=r}function st(e){let t=0,n=e.nextSibling;for(;n!==null;){if(n.nodeType===8){let e=f(n);if(e!==null)if(e.kind===`start`)t++;else if(t===0)return n;else t--}n=n.nextSibling}return null}function Z(e){if(e===null)return`end of children`;switch(e.nodeType){case 1:return`<${e.tagName.toLowerCase()}>`;case 3:return`text ${JSON.stringify(e.data)}`;case 8:return`comment ${JSON.stringify(e.data)}`;default:return`node(type ${e.nodeType})`}}function Q(e,t,r){return S.fail(new n({expected:e,actual:t,path:r}))}var ct=e({TypeId:()=>lt,dispose:()=>yt,errors:()=>vt,hydrate:()=>_t,make:()=>ht,mount:()=>gt});const lt=Symbol.for(`@weftui/dom/WeftApp`),ut=new WeakMap;function $(e){let t=ut.get(e);if(t===void 0)throw Error(`Expected a WeftApp created by WeftApp.make`);return t}function dt(e,t){return S.gen(function*(){e.subscribers===0&&(yield*M(S.logError(t.cause),S.annotateLogs(`weft.region`,t.region))),yield*D.publish(e.hub,t)})}function ft(e){return S.suspend(()=>$(e).disposed?S.die(Error(`Cannot mount on a disposed WeftApp`)):e.runtime.contextEffect)}function pt(e,t){return S.gen(function*(){let n=$(e),r=yield*k.fork(n.appScope,`sequential`),i=!1,a={element:t,unmount:()=>S.suspend(()=>i?S.void:(i=!0,k.close(r,C.void)))};return{context:{runtime:e.runtime,scope:r,rootScope:r,streamIdCounter:{current:0},reportUnhandled:(e,t)=>dt(n,{cause:e,region:t,root:a})},handle:a,rootScope:r}})}function mt(e,t){let n=ne.make(e??te.empty,t),r=S.runSync(D.unbounded()),i={[lt]:lt,runtime:n};return ut.set(i,{appScope:k.makeUnsafe(`sequential`),hub:r,subscribers:0,disposed:!1}),i}const ht=mt,gt=(e,t,n)=>S.gen(function*(){let r=yield*ft(e),{context:a,handle:o,rootScope:s}=yield*pt(e,n);n.innerHTML=``;let c=yield*M(H(t),S.setContext(M(r,b.add(i,a),b.add(k.Scope,s))),S.tapError(()=>k.close(s,C.void)));if(c!==null)if(Array.isArray(c))for(let e of c)n.appendChild(e);else n.appendChild(c);return o});function _t(e,t,n){return S.gen(function*(){let r=yield*ft(e),{context:a,handle:o,rootScope:s}=yield*pt(e,n),c=yield*Ge(),l={...a,hydrationReady:c};return ot(n,l.streamIdCounter),yield*M(q(t,n.firstChild,`root`),S.setContext(M(r,b.add(i,l),b.add(k.Scope,s))),S.tapError(()=>k.close(s,C.void))),yield*c.settle,yield*c.awaitReady,o})}const vt=e=>{let t=$(e);return A.unwrap(S.sync(()=>(t.subscribers++,M(A.fromPubSub(t.hub),A.ensuring(S.sync(()=>{t.subscribers--}))))))},yt=e=>S.suspend(()=>{let t=$(e);return t.disposed?S.void:(t.disposed=!0,M(k.close(t.appScope,C.void),S.andThen(e.runtime.disposeEffect),S.andThen(D.shutdown(t.hub))))});export{ct as WeftApp};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Cause, Context, Effect, ManagedRuntime, Scope } from "effect";
|
|
2
|
-
|
|
3
2
|
//#region src/data.d.ts
|
|
4
|
-
declare const UnsupportedNodeTypeError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => Cause.YieldableError & {
|
|
3
|
+
declare const UnsupportedNodeTypeError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
5
4
|
readonly _tag: "UnsupportedNodeTypeError";
|
|
6
5
|
} & Readonly<A>;
|
|
7
6
|
/**
|
|
@@ -11,7 +10,7 @@ declare class UnsupportedNodeTypeError extends UnsupportedNodeTypeError_base<{
|
|
|
11
10
|
readonly type: unknown;
|
|
12
11
|
readonly message: string;
|
|
13
12
|
}> {}
|
|
14
|
-
declare const StreamSubscriptionError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => Cause.YieldableError & {
|
|
13
|
+
declare const StreamSubscriptionError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
15
14
|
readonly _tag: "StreamSubscriptionError";
|
|
16
15
|
} & Readonly<A>;
|
|
17
16
|
/**
|
|
@@ -21,7 +20,7 @@ declare class StreamSubscriptionError extends StreamSubscriptionError_base<{
|
|
|
21
20
|
readonly cause: unknown;
|
|
22
21
|
readonly context: string;
|
|
23
22
|
}> {}
|
|
24
|
-
declare const RenderError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => Cause.YieldableError & {
|
|
23
|
+
declare const RenderError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
25
24
|
readonly _tag: "RenderError";
|
|
26
25
|
} & Readonly<A>;
|
|
27
26
|
/**
|
|
@@ -31,7 +30,7 @@ declare class RenderError extends RenderError_base<{
|
|
|
31
30
|
readonly cause: unknown;
|
|
32
31
|
readonly message: string;
|
|
33
32
|
}> {}
|
|
34
|
-
declare const HydrationMismatchError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => Cause.YieldableError & {
|
|
33
|
+
declare const HydrationMismatchError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
35
34
|
readonly _tag: "HydrationMismatchError";
|
|
36
35
|
} & Readonly<A>;
|
|
37
36
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as UnsupportedNodeTypeError, n as RenderError, r as StreamSubscriptionError, t as HydrationMismatchError } from "./data-
|
|
1
|
+
import { i as UnsupportedNodeTypeError, n as RenderError, r as StreamSubscriptionError, t as HydrationMismatchError } from "./data-C88W1AwU.js";
|
|
2
2
|
export { HydrationMismatchError, RenderError, StreamSubscriptionError, UnsupportedNodeTypeError };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.defineProperty,t=(t,n)=>{let r={};for(var i in t)e(r,i,{get:t[i],enumerable:!0});return n||e(r,Symbol.toStringTag,{value:`Module`}),r};export{t};
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Cause, Context, Effect, Option, Scope, Stream } from "effect";
|
|
2
2
|
import { AppRpcClientTag, Renderable } from "@weftui/core";
|
|
3
3
|
import { Renderable as Renderable$1 } from "@weftui/core/types";
|
|
4
|
-
|
|
5
4
|
//#region src/server/render-to-stream.d.ts
|
|
6
5
|
/**
|
|
7
6
|
* Progressively serializes an Effect-infused JSX tree (`Renderable`) into a stream
|
|
@@ -147,7 +147,7 @@ When a `Stream` prop ends before emitting, the renderer raises a `NoPropValue` t
|
|
|
147
147
|
// Handle at the mount boundary if needed. `Effect.catchTag` matches the error
|
|
148
148
|
// by its string tag, so no `NoPropValue` import is required here.
|
|
149
149
|
pipe(
|
|
150
|
-
mount(App(), root),
|
|
150
|
+
WeftApp.mount(app, App(), root),
|
|
151
151
|
Effect.catchTag("NoPropValue", (e) =>
|
|
152
152
|
Effect.logWarning(`Prop stream ended before emitting: ${e.key}`),
|
|
153
153
|
),
|
|
@@ -46,9 +46,9 @@ This also fixes the update _shape_. Because the structure is fixed, an update is
|
|
|
46
46
|
The same component tree renders on the server and the client:
|
|
47
47
|
|
|
48
48
|
- On the **server**, the tree renders to an HTML string (or a streaming response) via `@weftui/dom/server`. The _hydratable_ renderers additionally emit the inline data each reactive region needs to resume.
|
|
49
|
-
- On the **client**, `hydrate
|
|
49
|
+
- On the **client**, `WeftApp.hydrate` walks that server-rendered DOM and **adopts it in place** — it wires up reactivity and event handlers on the existing nodes rather than re-rendering. The first client production matches the adopted DOM exactly, so nothing is mutated and there is no flash.
|
|
50
50
|
|
|
51
|
-
Because the same `Node<E, R>` describes both passes, there is nothing to keep in sync: the server output and the client's first render are the _same tree_ run in two environments. Services flow from the
|
|
51
|
+
Because the same `Node<E, R>` describes both passes, there is nothing to keep in sync: the server output and the client's first render are the _same tree_ run in two environments. Services flow from the app layer (or the router's render-time context) through the tree to wherever a component reads them, on both sides. The mechanics of the two-sided render live in [Render on the Server](https://weftui.dev/docs/how-to/render-on-the-server); the service flow is [Services and Context](https://weftui.dev/docs/explanation/services-and-context).
|
|
52
52
|
|
|
53
53
|
## Why this matters
|
|
54
54
|
|