@weftui/dom 0.28.0 → 0.29.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 +25 -14
- package/dist/boundary-replay-BY4GyLot.js +1 -0
- package/dist/client/index.d.ts +5 -5
- package/dist/client/index.js +1 -1
- package/dist/index.d.ts +195 -1
- package/dist/index.js +1 -1
- package/dist/server/index.d.ts +6 -6
- package/dist/server/index.js +1 -1
- package/dist/shared-Dz0KM9ku.js +1 -0
- package/docs/explanation/boundaries-and-suspense.md +37 -18
- package/docs/explanation/combinator-api.md +14 -12
- package/docs/explanation/reactive-primitives.md +14 -14
- package/docs/explanation/rendering-model.md +20 -18
- package/docs/explanation/services-and-context.md +35 -21
- package/docs/how-to/add-routing.md +72 -48
- package/docs/how-to/author-components.md +40 -28
- package/docs/how-to/compose-behavior-and-markup.md +144 -0
- package/docs/how-to/handle-forms.md +6 -6
- package/docs/how-to/load-async-data.md +15 -13
- package/docs/how-to/load-data-with-rpc.md +30 -28
- package/docs/how-to/provide-services.md +20 -18
- package/docs/how-to/render-keyed-lists.md +10 -8
- package/docs/how-to/render-on-the-server.md +16 -12
- package/docs/how-to/show-navigation-progress.md +10 -8
- package/docs/how-to/split-routes-lazily.md +16 -14
- package/docs/how-to/style-reactively.md +13 -13
- package/docs/how-to/use-element-refs.md +10 -8
- package/docs/index.md +20 -18
- package/docs/reference/core.md +44 -40
- package/docs/reference/dom.md +274 -58
- package/docs/reference/router.md +69 -47
- package/docs/tutorial/01-your-first-app.md +7 -9
- package/docs/tutorial/02-reactivity.md +8 -6
- package/docs/tutorial/03-services-and-async.md +10 -6
- package/docs/tutorial/04-errors-and-server.md +14 -5
- package/package.json +3 -3
- package/dist/boundary-replay-BR26_puM.js +0 -1
- package/dist/data-uLmMpQMV.js +0 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @weftui/dom
|
|
2
2
|
|
|
3
|
-
> The DOM renderer for [Weft](https://weftui.dev)
|
|
3
|
+
> The DOM renderer for [Weft](https://weftui.dev): mount and hydrate in the browser, render to string or stream on the server.
|
|
4
4
|
|
|
5
|
-
Takes a [`@weftui/core`](https://weftui.dev/docs/reference/core) node tree and renders it to real DOM on the client or to HTML on the server. There is no virtual DOM and no diffing
|
|
5
|
+
Takes a [`@weftui/core`](https://weftui.dev/docs/reference/core) node tree and renders it to real DOM on the client or to HTML on the server. There is no virtual DOM and no diffing: streams patch the tree in place. The same tree renders to HTML with `renderToStringHydratable` and `hydrate()`s flash-free on the client.
|
|
6
6
|
|
|
7
7
|
Two entry points: `@weftui/dom/client` for the browser, `@weftui/dom/server` for Node.
|
|
8
8
|
|
|
@@ -22,23 +22,34 @@ Weft tracks Effect 4's beta line. This release is built and tested against `effe
|
|
|
22
22
|
|
|
23
23
|
| Export | What it does |
|
|
24
24
|
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
25
|
-
| `WeftApp.make(layer?)` | Creates an app: one lazily-built `ManagedRuntime` (the layer), one root `Scope`, one error hub. Synchronous
|
|
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
|
|
27
|
-
| `WeftApp.hydrate(app, node, root)` | Adopts server-rendered DOM **in place** as a new root of `app` and resumes reactivity
|
|
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`, so it 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
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
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
|
|
30
|
+
| `RootHandle` | Returned by `mount`/`hydrate`. `unmount()` closes that root's scope only; other roots and the app runtime are untouched. Idempotent. |
|
|
31
31
|
|
|
32
32
|
### `@weftui/dom/server`
|
|
33
33
|
|
|
34
|
-
| Export | What it does
|
|
35
|
-
| -------------------------------- |
|
|
36
|
-
| `renderToString` | Renders a node to a complete HTML string (static, non-hydrated).
|
|
37
|
-
| `renderToStringHydratable` | Same, plus the hydration markers `hydrate` needs. Pair with `hydrate`.
|
|
38
|
-
| `renderToStream` / `…Hydratable` | Streaming variants
|
|
39
|
-
| `renderToHydratableShell` | Produces the document scaffold for servers that assemble the shell separately.
|
|
34
|
+
| Export | What it does |
|
|
35
|
+
| -------------------------------- | ------------------------------------------------------------------------------- |
|
|
36
|
+
| `renderToString` | Renders a node to a complete HTML string (static, non-hydrated). |
|
|
37
|
+
| `renderToStringHydratable` | Same, plus the hydration markers `hydrate` needs. Pair with `hydrate`. |
|
|
38
|
+
| `renderToStream` / `…Hydratable` | Streaming variants: emit HTML chunks as the tree resolves, for progressive SSR. |
|
|
39
|
+
| `renderToHydratableShell` | Produces the document scaffold for servers that assemble the shell separately. |
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
### `@weftui/dom` (package root)
|
|
42
|
+
|
|
43
|
+
| Export | What it does |
|
|
44
|
+
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
45
|
+
| `Props.merge(...)` | Merges prop bags left to right: handlers chain, `class` concatenates, `style` merges per property, `ref` fans out, everything else is last-wins. Pure, and `h.*` takes the result. |
|
|
46
|
+
| `Props.cx(...)` | Builds a class string from strings, falsy values, nested arrays, and `{ className: condition }` records. Conditions may be reactive. |
|
|
47
|
+
|
|
48
|
+
`Props.merge` lets a shared behavior and the element's owner both contribute
|
|
49
|
+
props without either silently dropping the other. See
|
|
50
|
+
[Compose Behavior and Markup](../../docs/how-to/compose-behavior-and-markup.md).
|
|
51
|
+
|
|
52
|
+
The package root also re-exports the renderer error types: `HydrationMismatchError`, `UnsupportedNodeTypeError`, `RenderError`, `StreamSubscriptionError`.
|
|
42
53
|
|
|
43
54
|
## Example
|
|
44
55
|
|
|
@@ -64,7 +75,7 @@ void Effect.runPromise(WeftApp.mount(app, Counter(), document.getElementById("ro
|
|
|
64
75
|
- Full docs: **https://weftui.dev**
|
|
65
76
|
- `@weftui/dom` API reference: **https://weftui.dev/docs/reference/dom**
|
|
66
77
|
- Server-side rendering guide: **https://weftui.dev/docs/how-to/render-on-the-server**
|
|
67
|
-
- Bundled with this package: see the [`./docs`](./docs) directory in `node_modules/@weftui/dom/docs
|
|
78
|
+
- Bundled with this package: see the [`./docs`](./docs) directory in `node_modules/@weftui/dom/docs`. The complete tutorial, how-to, explanation, and reference tree ships on disk for offline and agent use.
|
|
68
79
|
|
|
69
80
|
## License
|
|
70
81
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Effect as e}from"effect";import{FAILURE_BOUNDARY as t,FRAGMENT as n,LIST as r,SERVER_BOUNDARY as i,SUSPENSE_BOUNDARY as a,getElementDescriptor as o,isStream as s}from"@weftui/core";const c=`data-weft-boundary-failure`;function l(e){let t=[];return u(e,t),t}function u(t,n){if(!(t==null||typeof t==`boolean`)&&!(typeof t==`string`||typeof t==`number`||typeof t==`bigint`)){if(s(t)||e.isEffect(t)){let e=o(t);e!==void 0&&d(e,n);return}if(typeof t==`object`&&Symbol.iterator in t&&!(`type`in t)){for(let e of t)u(e,n);return}typeof t==`object`&&`type`in t&&!(Symbol.iterator in t)&&d(t,n)}}function d(e,o){let{type:s,props:c}=e;if(s===i){o.push(c);return}if(s===n||s===a||s===t){f(c,o);return}if(s!==r){if(typeof s==`string`){f(c,o);return}typeof s==`function`&&u(s(c),o)}}function f(e,t){let n=`children`in e?e.children:void 0;if(n==null)return;let r=Array.isArray(n)?n:[n];for(let e of r)u(e,t)}export{l as n,c as t};
|
package/dist/client/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ type MountError = UnsupportedNodeTypeError | StreamSubscriptionError | RenderErr
|
|
|
21
21
|
type HydrateError = MountError | HydrationMismatchError;
|
|
22
22
|
/**
|
|
23
23
|
* An error that escaped every user-level handler and reached the app's
|
|
24
|
-
* unhandled-error hub
|
|
24
|
+
* unhandled-error hub, published on the {@link errors} stream.
|
|
25
25
|
*
|
|
26
26
|
* Sources (one entry per failing occurrence):
|
|
27
27
|
* - a rendered stream subscription failing or dying with no enclosing
|
|
@@ -59,7 +59,7 @@ interface RootHandle {
|
|
|
59
59
|
* Closes this root's scope: interrupts its stream subscriptions and any
|
|
60
60
|
* scoped work forked from its event handlers. Does **not** dispose the app
|
|
61
61
|
* runtime, touch other roots, or remove the rendered DOM nodes from
|
|
62
|
-
* {@link element}. Idempotent
|
|
62
|
+
* {@link element}. Idempotent. Teardown side effects fire once.
|
|
63
63
|
*/
|
|
64
64
|
unmount(): Effect.Effect<void>;
|
|
65
65
|
}
|
|
@@ -81,7 +81,7 @@ interface WeftApp<in R = never, out E = never> {
|
|
|
81
81
|
readonly [TypeId]: typeof TypeId;
|
|
82
82
|
/**
|
|
83
83
|
* The app's `ManagedRuntime`, for running app-level effects against the
|
|
84
|
-
* shared layer outside any root
|
|
84
|
+
* shared layer outside any root, e.g.
|
|
85
85
|
* `app.runtime.runFork(trackPageviews)` or
|
|
86
86
|
* `app.runtime.runPromise(Router.push("/about"))`.
|
|
87
87
|
*/
|
|
@@ -122,7 +122,7 @@ declare const make: Make;
|
|
|
122
122
|
* - Clears `root`'s existing children, renders the tree, appends the result.
|
|
123
123
|
* - Completes after initial render; streams keep running in the background,
|
|
124
124
|
* owned by the root's scope (a child of the app scope).
|
|
125
|
-
* - Self-contained: the returned effect's requirement channel is `never
|
|
125
|
+
* - Self-contained: the returned effect's requirement channel is `never`, so
|
|
126
126
|
* run it with a bare `Effect.runPromise`. Services come exclusively from the
|
|
127
127
|
* app layer; `Effect.provide` around this call does not feed components.
|
|
128
128
|
* - The app layer builds lazily here on first mount; its error channel `E`
|
|
@@ -182,7 +182,7 @@ declare function hydrate<A extends Renderable, R = never, E = never>(app: WeftAp
|
|
|
182
182
|
declare const errors: <R, E>(app: WeftApp<R, E>) => Stream.Stream<UnhandledError>;
|
|
183
183
|
/**
|
|
184
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
|
|
185
|
+
* the runtime's layers, then shuts the error hub down. Idempotent: teardown
|
|
186
186
|
* effects run once. Subsequent {@link mount} / {@link hydrate} calls fail.
|
|
187
187
|
*
|
|
188
188
|
* @param app - the {@link WeftApp} to dispose
|
package/dist/client/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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
|
+
import{t as e}from"../rolldown-runtime-DK3Fl9T5.js";import{_ as t,a as n,b as r,c as i,d as a,f as o,g as s,h as c,i as l,l as u,m as d,n as f,o as p,p as m,r as h,s as g,u as _,y as v}from"../shared-Dz0KM9ku.js";import{n as ee}from"../boundary-replay-BY4GyLot.js";import{Cause as y,Context as b,Deferred as x,Effect as S,Exit as C,Fiber as te,HashMap as w,HashSet as T,Layer as ne,ManagedRuntime as re,Option as E,PubSub as D,Ref as O,Schema as ie,Scope as k,Stream as A,SubscriptionRef as j,pipe as M}from"effect";import{AppRpcClientTag as ae,FAILURE_BOUNDARY as oe,FRAGMENT as se,LIST as ce,SERVER_BOUNDARY as le,SUSPENSE_BOUNDARY as ue,Source as de,Subscribable as fe,getElementDescriptor as N,isStream as P,toStream as F}from"@weftui/core";function I(){return S.gen(function*(){let e=yield*s;return++e.streamIdCounter.current})}const pe=I;let me=0;const L=()=>++me;function R(e,t){return S.gen(function*(){for(let[n,r]of Object.entries(t))if(n!==`children`){if(l(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===`ref`&&Array.isArray(r)){yield*S.forEach(r.filter(e=>j.isSubscriptionRef(e)),t=>j.set(t,E.some(e)),{discard:!0});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(d);if(E.isNone(i)){let i=yield*S.forkIn(e,t);return yield*M(te.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(te.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*s;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*s,i=t.slice(2).toLowerCase(),a=null,o=()=>{a&&=(e.removeEventListener(i,a),null)},c=n=>{o(),!(n==null||n===!1)&&typeof n==`function`&&(a=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(i,a))};yield*k.addFinalizer(r.scope,S.sync(o)),P(n)||S.isEffect(n)?yield*V(F(n),e=>c(e),`event:${t}`):c(n)})}function Se(e,t,n,r,i,a){return S.gen(function*(){let o=yield*s,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*o.reportUnhandled(c,`boundary:outermost`);K(i,a);let u=yield*H(l),d=a.parentNode;if(d!==null&&u!==null)if(Array.isArray(u))for(let e of u)d.insertBefore(e,a);else d.insertBefore(u,a)})}function Ce(e){return S.gen(function*(){let t=yield*s,n=yield*S.serviceOption(d),r=L(),i=document.createComment(h(r)),a=document.createComment(f(r)),o=yield*k.fork(t.scope,`sequential`),c={...t,scope:o},l=yield*x.make(),u=yield*M(U(e.children),S.provideService(d,{reportError:e=>x.fail(l,e).pipe(S.asVoid)}),S.provideService(s,c),S.provideService(k.Scope,o),S.catchCause(t=>{let n=e.match(t);return n===null?S.failCause(t):M(k.close(o,C.void),S.flatMap(()=>H(n)),S.map(e=>e===null?[]:Array.isArray(e)?e:[e]))}));return yield*S.forkIn(Se(e,l,o,n,i,a),t.scope),[i,...u,a]})}function we(e){return S.gen(function*(){let t=yield*s,n=yield*O.make(1),r=yield*x.make(),i=M(O.updateAndGet(n,e=>e-1),S.flatMap(e=>e<=0?S.asVoid(x.succeed(r,void 0)):S.void)),a={register:O.update(n,e=>e+1),settle:i},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(v,a)),u=l===null?[]:Array.isArray(l)?l:[l];yield*i;let d=yield*x.poll(r);if(E.isSome(d))return u;let f=yield*pe(),p=document.createComment(m(f)),h=document.createComment(o(f)),g=yield*H(e.fallback??null),_=[];g!==null&&(Array.isArray(g)?_.push(...g):_.push(g));let ee=document.createDocumentFragment();for(let e of u)ee.appendChild(e);let y=S.gen(function*(){yield*x.await(r),K(p,h);let e=h.parentNode;e!==null&&(e.insertBefore(ee,h),p.remove(),h.remove())});return yield*S.forkIn(y,t.scope),[p,..._,h]})}function Te(e){return S.gen(function*(){let n=yield*s,r=yield*S.serviceOption(ae);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 i=r.value,a=L(),o=document.createComment(h(a)),c=document.createComment(f(a)),l=yield*H(e.fallback??null),u=[];l!==null&&(Array.isArray(l)?u.push(...l):u.push(l));let d=S.gen(function*(){let t=yield*i.call(e.tag,e.payload()),n=yield*Qe(e.tag,e.payload,t,r),a=yield*H(e.render(n));K(o,c);let s=c.parentNode;if(s!==null&&a!==null)if(Array.isArray(a))for(let e of a)s.insertBefore(e,c);else s.insertBefore(a,c)}).pipe(S.catchCause(t=>S.logError(`[weft] Boundary.rpc "${e.tag}" mount failed to resolve; fallback left in place.`,t)));return yield*S.forkIn(d,n.scope),[o,...u,c]})}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===se?yield*De(n):t===ue?yield*we(n):t===le?yield*Te(n):t===oe?yield*Ce(n):t===ce?yield*Ie(n):typeof t==`string`?yield*Oe(t,n):typeof t==`function`?yield*ke(t,n):yield*S.fail(new r({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*s,t=yield*k.fork(e.scope,`sequential`),r={...e,scope:t},i=yield*S.serviceOption(v),a=F(n);return E.isSome(i)&&(yield*i.value.register,a=M(a,A.zipWithIndex,A.flatMap(([e,t])=>t===0?A.fromEffect(S.as(i.value.settle,e)):A.make(e)))),yield*W(a).pipe(S.provideService(s,r),S.provideService(k.Scope,t))}return yield*H(n)})}function W(e){return S.gen(function*(){let t=yield*s,n=yield*I(),[r,i]=Ae(n),a=null;return yield*B(A.runForEach(e,e=>S.gen(function*(){a!==null&&(yield*k.close(a,C.void)),a=yield*k.fork(t.scope,`sequential`);let n={...t,scope:a};yield*G(r,i,e).pipe(S.provideService(s,n),S.provideService(k.Scope,a))})),t.scope,`child:stream-${n}`,t.reportUnhandled),[r,i]})}function Ae(e){return[document.createComment(a(e)),document.createComment(_(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*s,{of:n,by:r,render:i}=e,a=yield*I(),[o,c]=Ae(a),l=yield*k.fork(t.scope,`sequential`),u=(yield*de.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,i,d,l,c,t)})),l,`list:stream-${a}`,t.reportUnhandled),[o,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,r,i,a,o){return S.gen(function*(){let c=yield*k.fork(a,`sequential`),l={...o,scope:c},u=yield*I(),d=document.createComment(p(u)),f=document.createComment(n(u)),m=yield*H(i(t,r)).pipe(S.provideService(s,l),S.provideService(k.Scope,c));return{key:e,scope:c,startMarker:d,endMarker:f,nodes:m===null?[]:Array.isArray(m)?m:[m]}})}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:i,props:a}=e;if(i===se)return yield*J(a,t,n);if(i===ue){if(t!==null&&t.nodeType===X){let e=u(t);if(e!==null&&e.kind===`start`)return yield*Ye(t,n)}return yield*J(a,t,n)}return i===oe?yield*Ze(a,t,n):i===le?yield*$e(a,t,n):i===ce?yield*tt(a,t,n):typeof i==`string`?yield*et(i,a,t,n):typeof i==`function`?yield*q(i(a),t,n):yield*S.fail(new r({type:i,message:`Invalid Renderable type during hydration at ${n}: expected string, FRAGMENT, or function, got ${typeof i}`}))}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*s;if(t===null||t.nodeType!==X)return yield*Q(`reactive region start marker`,Z(t),n);let a=t,o=i(a);if(o===null||o.kind!==`start`)return yield*Q(`reactive region start marker`,Z(t),n);let c=st(a);if(c===null)return yield*Q(`reactive region end marker`,`unterminated region starting at ${JSON.stringify(a.data)}`,n);let l=Ke(r.hydrationReady),u=!0,d=null,f=A.runForEach(e,e=>S.gen(function*(){d!==null&&(yield*k.close(d,C.void)),d=yield*k.fork(r.scope,`sequential`);let t={...r,scope:d};yield*S.gen(function*(){u?(u=!1,yield*Je(e,a,c,n),yield*l):yield*G(a,c,e)}).pipe(S.provideService(s,t),S.provideService(k.Scope,d))})).pipe(S.ensuring(l));return r.hydrationReady!==void 0&&(yield*r.hydrationReady.register),yield*B(f,r.scope,`hydrate:stream-${o.id} (${n})`,r.reportUnhandled),c.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(d);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=u(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*s,i=yield*S.serviceOption(d),a=yield*k.fork(r.scope,`sequential`),o={...r,scope:a},c=yield*x.make(),l=yield*J(e,t,n).pipe(S.provideService(d,{reportError:e=>x.fail(c,e).pipe(S.asVoid)}),S.provideService(s,o),S.provideService(k.Scope,a)),u=t?.parentNode??null;if(t===null||t===l||u===null)return console.error(`[weft] hydrate: boundary at ${n} adopted an empty extent; live failure recovery is not installed for it.`),l;let p=L(),m=document.createComment(h(p)),g=document.createComment(f(p));return u.insertBefore(m,t),l===null?u.appendChild(g):u.insertBefore(g,l),yield*S.forkIn(Se(e,c,a,i,m,g),r.scope),l}let r=t,i=r.textContent??``,a=yield*S.gen(function*(){let t=yield*S.try({try:()=>JSON.parse(i),catch:e=>e}),n=ee(e.children)[t.index];if(n===void 0)return null;let r=yield*ie.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(a===null)return yield*Q(`replayable boundary failure`,`undecodable failure payload`,n);let o=yield*q(a,r.nextSibling,n);return r.remove(),o})}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:fe.make({get:j.get(i),changes:j.changes(i)}),refetch:s,pending:fe.make({get:j.get(a),changes:j.changes(a)}),error:fe.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=>ie.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(ae),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*s,{of:a,by:o,render:c}=e;if(t===null||t.nodeType!==X)return yield*Q(`list region start marker`,Z(t),n);let l=t,u=i(l);if(u===null||u.kind!==`start`)return yield*Q(`list region start marker`,Z(t),n);let d=st(l);if(d===null)return yield*Q(`list region end marker`,`unterminated region starting at ${JSON.stringify(l.data)}`,n);let f=nt(l,d),p=yield*k.fork(r.scope,`sequential`),m=(yield*de.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,c,f,p,l,d,r,n),yield*_):h=yield*Re(t,o,c,h,p,d,r)})).pipe(S.ensuring(_));return r.hydrationReady!==void 0&&(yield*r.hydrationReady.register),yield*B(v,p,`hydrate:list-${u.id} (${n})`,r.reportUnhandled),d.nextSibling})}function nt(e,t){let n=[],r=e.nextSibling;for(;r!==null&&r!==t;){let e=r.nodeType===X?g(r):null;if(e===null||e.kind!==`start`){r=r.nextSibling;continue}let i=r,a=[],o=0,s=null,c=i.nextSibling;for(;c!==null&&c!==t;){if(c.nodeType===X){let e=g(c);if(e!==null)if(e.kind===`start`)o++;else if(o===0){s=c;break}else o--}a.push(c),c=c.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,i,a,o,c){return S.gen(function*(){let l=yield*k.fork(a,`sequential`),u={...o,scope:l},d=r(t,n),f=yield*q(d,i.startMarker.nextSibling,`${c}<item>`).pipe(S.provideService(s,u),S.provideService(k.Scope,l),S.map(e=>e===i.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:i.startMarker,endMarker:i.endMarker,nodes:i.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(a,`sequential`),m={...o,scope:p};K(i.startMarker,i.endMarker);let h=yield*H(d).pipe(S.provideService(s,m),S.provideService(k.Scope,p)),g=h===null?[]:Array.isArray(h)?h:[h],_=i.endMarker.parentNode;if(_!==null)for(let e of g)_.insertBefore(e,i.endMarker);return{key:e,scope:p,startMarker:i.startMarker,endMarker:i.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=i(t)??u(t)??g(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=i(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,n){return S.fail(new c({expected:e,actual:t,path:n}))}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=re.make(e??ne.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:i,handle:a,rootScope:o}=yield*pt(e,n);n.innerHTML=``;let c=yield*M(H(t),S.setContext(M(r,b.add(s,i),b.add(k.Scope,o))),S.tapError(()=>k.close(o,C.void)));if(c!==null)if(Array.isArray(c))for(let e of c)n.appendChild(e);else n.appendChild(c);return a});function _t(e,t,n){return S.gen(function*(){let r=yield*ft(e),{context:i,handle:a,rootScope:o}=yield*pt(e,n),c=yield*Ge(),l={...i,hydrationReady:c};return ot(n,l.streamIdCounter),yield*M(q(t,n.firstChild,`root`),S.setContext(M(r,b.add(s,l),b.add(k.Scope,o))),S.tapError(()=>k.close(o,C.void))),yield*c.settle,yield*c.awaitReady,a})}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};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,196 @@
|
|
|
1
1
|
import { i as UnsupportedNodeTypeError, n as RenderError, r as StreamSubscriptionError, t as HydrationMismatchError } from "./data-C88W1AwU.js";
|
|
2
|
-
|
|
2
|
+
import { Effect, Option, Stream, SubscriptionRef } from "effect";
|
|
3
|
+
import { NoPropValue, Source, Subscribable } from "@weftui/core";
|
|
4
|
+
declare namespace props_d_exports {
|
|
5
|
+
export { CxInput, CxRecord, CxResult, DomProps, Merged, cx, merge };
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The prop-bag argument shape accepted by `h.*` element builders.
|
|
9
|
+
* Loosely constrained because {@link merge} dispatches on the key
|
|
10
|
+
* (`class`, `style`, `ref`, `on*`), not on the bag's declared type.
|
|
11
|
+
*/
|
|
12
|
+
type DomProps = object;
|
|
13
|
+
/** Any reactive prop value: the non-static arms of `Source.Source`. */
|
|
14
|
+
type ReactiveValue = Stream.Stream<any, any, any> | Effect.Effect<any, any, any> | Subscribable.Subscribable<any, any, any>;
|
|
15
|
+
/** Any function value, used to detect plain event-handler functions. */
|
|
16
|
+
type AnyFunction = (...args: ReadonlyArray<any>) => any;
|
|
17
|
+
/** The lowercase third character the renderer's `isEventHandler` check requires. */
|
|
18
|
+
type LowercaseLetter = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z";
|
|
19
|
+
/**
|
|
20
|
+
* Type-level form of the renderer's `isEventHandler` check. Mirrors it exactly,
|
|
21
|
+
* including the lowercase third character: Weft's DOM handler props are all
|
|
22
|
+
* lowercase (`onclick`), so a camelCase `onClick` is not a handler key and must
|
|
23
|
+
* type as last-wins, matching what the runtime does with it.
|
|
24
|
+
*/
|
|
25
|
+
type EventHandlerKey = `on${LowercaseLetter}${string}`;
|
|
26
|
+
/**
|
|
27
|
+
* Error channel a handler side contributes. Covers a plain handler returning an
|
|
28
|
+
* Effect and the reactive `Stream`/`Effect`-of-handler forms core's
|
|
29
|
+
* `EventHandler` allows, so a reactive side keeps its channel even though the
|
|
30
|
+
* runtime treats it as last-wins.
|
|
31
|
+
*/
|
|
32
|
+
type HandlerError<H> = H extends ((...args: ReadonlyArray<any>) => infer Ret) ? Ret extends Effect.Effect<any, infer E, any> ? E : never : H extends Stream.Stream<any, infer E, any> ? E : H extends Effect.Effect<any, infer E, any> ? E : never;
|
|
33
|
+
/** Context channel a handler side contributes; mirrors {@link HandlerError}. */
|
|
34
|
+
type HandlerContext<H> = H extends ((...args: ReadonlyArray<any>) => infer Ret) ? Ret extends Effect.Effect<any, any, infer R> ? R : never : H extends Stream.Stream<any, any, infer R> ? R : H extends Effect.Effect<any, any, infer R> ? R : never;
|
|
35
|
+
/**
|
|
36
|
+
* A handler side with its "no handler" arms removed. Core declares handler
|
|
37
|
+
* props as `null | false | EventHandler<...>`, and leaving those in place makes
|
|
38
|
+
* the event-parameter match below fail, degrading the merged handler's event to
|
|
39
|
+
* the base `Event` (so `ev.clientX` stops compiling). Kept separate from
|
|
40
|
+
* {@link Present}, which must not strip `false` from ordinary boolean props.
|
|
41
|
+
*/
|
|
42
|
+
type HandlerSide<T> = Exclude<T, null | false | undefined>;
|
|
43
|
+
/** Event parameter of a chained handler: intersection of both sides' events. */
|
|
44
|
+
type MergedHandlerEvent<L, R> = [HandlerSide<L>] extends [(event: infer EL) => any] ? [HandlerSide<R>] extends [(event: infer ER) => any] ? EL & ER : EL : [HandlerSide<R>] extends [(event: infer ER2) => any] ? ER2 : Event;
|
|
45
|
+
/**
|
|
46
|
+
* Handler cell rule. If either side can carry a handler the merged value is a
|
|
47
|
+
* handler function whose channels union both sides'; if neither can, the cell
|
|
48
|
+
* is the nullish "no handler" type.
|
|
49
|
+
*
|
|
50
|
+
* The callable shape is deliberately coarse: core declares handler props as
|
|
51
|
+
* `null | false | EventHandler<...>`, so a rule that only matched two bare
|
|
52
|
+
* functions would miss every realistically-typed bag and drop the left side's
|
|
53
|
+
* `E`/`R` from `PropsE`/`PropsR`. Channel accuracy is the part that must not
|
|
54
|
+
* degrade, so it is computed from whatever shape each side has.
|
|
55
|
+
*/
|
|
56
|
+
type MergedHandlerValue<L, R> = [HandlerSide<L>, HandlerSide<R>] extends [never, never] // Neither side can carry a handler, so neither can the result.
|
|
57
|
+
? null | false | undefined : (event: MergedHandlerEvent<L, R>) => Effect.Effect<void, HandlerError<HandlerSide<L>> | HandlerError<HandlerSide<R>>, HandlerContext<HandlerSide<L>> | HandlerContext<HandlerSide<R>>>;
|
|
58
|
+
/**
|
|
59
|
+
* Class cell rule. A side that cannot carry a reactive value joins statically,
|
|
60
|
+
* so two such sides stay a plain `string` and the descriptor remains
|
|
61
|
+
* analyzable (AC8). If either side might be reactive the cell is exactly a
|
|
62
|
+
* `Stream`, never a union: `PropsE`/`PropsR` extract channels by matching
|
|
63
|
+
* `P[K] extends Stream<...>`, and a union would fail that match and silently
|
|
64
|
+
* drop the class's `E`/`R`. Erring toward `Stream` is therefore the safe
|
|
65
|
+
* direction, at the cost of over-reporting for a wide `Source<string>` side.
|
|
66
|
+
*/
|
|
67
|
+
type MergedClassValue<L, R> = true extends IsReactiveCxInput<L> | IsReactiveCxInput<R> ? Stream.Stream<string, CxInputError<L> | CxInputError<R> | NoPropValue, CxInputContext<L> | CxInputContext<R>> : string;
|
|
68
|
+
/**
|
|
69
|
+
* True for a per-property style object. Mirrors the runtime
|
|
70
|
+
* `isPlainStyleObject`, including its array exclusion, so the two cannot
|
|
71
|
+
* disagree about which shape takes the object-merge branch.
|
|
72
|
+
*/
|
|
73
|
+
type IsStyleObject<V> = V extends object ? V extends ReactiveValue | AnyFunction | ReadonlyArray<any> ? false : true : false;
|
|
74
|
+
/**
|
|
75
|
+
* Style cell rule: object plus object takes the key union with the right side
|
|
76
|
+
* winning per key, each surviving value passed through by reference.
|
|
77
|
+
* Any other shape on either side is last-wins.
|
|
78
|
+
*/
|
|
79
|
+
type MergedStyleValue<L, R> = [IsStyleObject<L>, IsStyleObject<R>] extends [true, true] ? { readonly [K in keyof L | keyof R]: K extends keyof R ? R[K] : K extends keyof L ? L[K] : never; } : R;
|
|
80
|
+
/**
|
|
81
|
+
* Ref cell rule: both sides concatenate into one readonly fan-out array.
|
|
82
|
+
* Typed against the same permissive element as the core `ref` array arm so the
|
|
83
|
+
* result stays assignable to any element builder. `SubscriptionRef` is
|
|
84
|
+
* invariant, so a union of the two sides' exact ref types would reject the
|
|
85
|
+
* heterogeneous fan-out this rule exists to enable (AC14a).
|
|
86
|
+
*/
|
|
87
|
+
type MergedRefValue = ReadonlyArray<SubscriptionRef.SubscriptionRef<Option.Option<any>>>;
|
|
88
|
+
/**
|
|
89
|
+
* The value a side actually carries when its key is present. An optional prop
|
|
90
|
+
* indexes to `T | undefined`; the cell rules must dispatch on `T`, or every
|
|
91
|
+
* pattern match below silently falls through to last-wins.
|
|
92
|
+
*/
|
|
93
|
+
type Present<T> = Exclude<T, undefined>;
|
|
94
|
+
/** Per-key dispatch for a key present on both sides. */
|
|
95
|
+
type MergedValue<K extends PropertyKey, L, R> = K extends "class" ? MergedClassValue<Present<L>, Present<R>> : K extends "style" ? MergedStyleValue<Present<L>, Present<R>> : K extends "ref" ? MergedRefValue : K extends EventHandlerKey ? MergedHandlerValue<Present<L>, Present<R>> : Present<R>;
|
|
96
|
+
/**
|
|
97
|
+
* The cell for a key both bags declare.
|
|
98
|
+
*
|
|
99
|
+
* When one side's key is optional it may be absent at runtime, in which case
|
|
100
|
+
* the other side's value survives unmerged. That outcome is deliberately not
|
|
101
|
+
* unioned in: each cell rule above is already coarse enough to accept it at a
|
|
102
|
+
* prop slot, and unioning the bare side back in would reintroduce the invariant
|
|
103
|
+
* `SubscriptionRef` that makes the AC14a fan-out fail to compile.
|
|
104
|
+
*/
|
|
105
|
+
type MergedSharedValue<K extends keyof L & keyof R, L, R> = MergedValue<K, L[K], R[K]>;
|
|
106
|
+
/** Flattens an intersection into one object type, preserving optional modifiers. */
|
|
107
|
+
type Simplify<T> = { [K in keyof T]: T[K]; };
|
|
108
|
+
/** Keys only the left bag has. Homomorphic over `L`, so `?` modifiers survive. */
|
|
109
|
+
type MergedLeftOnly<L, R> = { readonly [K in keyof L as K extends keyof R ? never : K]: L[K]; };
|
|
110
|
+
/** Keys only the right bag has. Homomorphic over `R`, so `?` modifiers survive. */
|
|
111
|
+
type MergedRightOnly<L, R> = { readonly [K in keyof R as K extends keyof L ? never : K]: R[K]; };
|
|
112
|
+
/**
|
|
113
|
+
* Keys both bags declare. Emitted as required (`-?`) with an undefined-free
|
|
114
|
+
* value, because `PropsE`/`PropsR` extract channels by matching `P[K]` against
|
|
115
|
+
* a function or `Stream` shape, and a `T | undefined` union fails that match
|
|
116
|
+
* and silently drops the key's `E`/`R`. Channel accuracy outranks presence
|
|
117
|
+
* precision here, so a shared key that is optional on both sides and absent at
|
|
118
|
+
* runtime is still typed as present.
|
|
119
|
+
*/
|
|
120
|
+
type MergedShared<L, R> = { readonly [K in keyof L & keyof R]-?: MergedSharedValue<K, L, R>; };
|
|
121
|
+
/**
|
|
122
|
+
* Binary merge of two bags: shared keys via {@link MergedValue}, rest pass
|
|
123
|
+
* through. Built from two homomorphic mapped types so optional keys stay
|
|
124
|
+
* optional. A single `[K in keyof L | keyof R]` map would mark every key
|
|
125
|
+
* required, claiming keys are present that the runtime never copied.
|
|
126
|
+
*/
|
|
127
|
+
type MergedPair<L, R> = Simplify<MergedLeftOnly<L, R> & MergedRightOnly<L, R> & MergedShared<L, R>>;
|
|
128
|
+
/** The empty bag: identity of the merge monoid and result of `merge()`. */
|
|
129
|
+
type EmptyBag = Readonly<Record<never, never>>;
|
|
130
|
+
/**
|
|
131
|
+
* Result of {@link merge}: a left-to-right fold of {@link MergedPair} over the
|
|
132
|
+
* bag tuple. Value types stay coarse but `E`/`R` channels stay precise, so
|
|
133
|
+
* `PropsE`/`PropsR` accumulate the full union through `h.*`.
|
|
134
|
+
*/
|
|
135
|
+
type Merged<Bags extends ReadonlyArray<DomProps>> = Bags extends readonly [] ? EmptyBag : Bags extends readonly [infer Only extends DomProps] ? Only : Bags extends readonly [infer L extends DomProps, infer R extends DomProps, ...infer Rest extends ReadonlyArray<DomProps>] ? Merged<[MergedPair<L, R>, ...Rest]> : MergedPair<Bags[number], Bags[number]>;
|
|
136
|
+
/**
|
|
137
|
+
* Merge DOM prop bags left to right. Pure: the result is a plain prop bag of
|
|
138
|
+
* ordinary Weft prop values, so `h.*` accepts it and `PropsE`/`PropsR` carry
|
|
139
|
+
* the error and context channels through. `{}` is the identity, and the fold is
|
|
140
|
+
* associative except for `style` when a non-object form takes part (see below).
|
|
141
|
+
*
|
|
142
|
+
* Rules for a key present on both sides:
|
|
143
|
+
*
|
|
144
|
+
* - `on*`: chained left to right, both always run, failures isolated and causes aggregated.
|
|
145
|
+
* - `class`: space-concatenated. Static stays a `string`, reactive derives a `Stream<string>`.
|
|
146
|
+
* - `style`: two per-property objects merge per key (right wins). Other forms are
|
|
147
|
+
* last-wins, which discards a side and so is not associative (v1 limitation).
|
|
148
|
+
* - `ref`: fan-out. Refs concatenate into an array and every ref is set.
|
|
149
|
+
* - anything else: last-wins.
|
|
150
|
+
*
|
|
151
|
+
* Keys on only one side pass through untouched.
|
|
152
|
+
*
|
|
153
|
+
* @param bags - Lowest precedence first.
|
|
154
|
+
*/
|
|
155
|
+
declare function merge<const Bags extends ReadonlyArray<DomProps>>(...bags: Bags): Merged<Bags>;
|
|
156
|
+
/** A reactive string value accepted by {@link cx} in value position. */
|
|
157
|
+
type CxReactiveValue = Stream.Stream<string, any, any> | Effect.Effect<string, any, any> | Subscribable.Subscribable<string, any, any>;
|
|
158
|
+
/** A condition in a {@link cx} record: a static or reactive boolean. */
|
|
159
|
+
type CxCondition = boolean | Stream.Stream<boolean, any, any> | Effect.Effect<boolean, any, any> | Subscribable.Subscribable<boolean, any, any>;
|
|
160
|
+
/**
|
|
161
|
+
* Record form of a {@link cx} input: each key is a class name included while
|
|
162
|
+
* its condition is truthy. Reactive conditions are the difference from clsx.
|
|
163
|
+
*/
|
|
164
|
+
interface CxRecord {
|
|
165
|
+
readonly [className: string]: CxCondition;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* One input to {@link cx}: a string, a falsy value (skipped), a reactive
|
|
169
|
+
* string, a condition record, or a nested array of inputs.
|
|
170
|
+
*/
|
|
171
|
+
type CxInput = string | false | null | undefined | CxReactiveValue | CxRecord | ReadonlyArray<CxInput>;
|
|
172
|
+
/** True when a {@link cx} input contains a reactive value at any depth. */
|
|
173
|
+
type IsReactiveCxInput<I> = I extends ReactiveValue ? true : I extends ReadonlyArray<infer Item> ? IsReactiveCxInput<Item> : I extends CxRecord ? I[keyof I] extends boolean ? false : true : false;
|
|
174
|
+
/** Union of the error channels contributed by a {@link cx} input. */
|
|
175
|
+
type CxInputError<I> = I extends ReactiveValue ? Source.Error<I> : I extends ReadonlyArray<infer Item> ? CxInputError<Item> : I extends CxRecord ? Source.Error<I[keyof I]> : never;
|
|
176
|
+
/** Union of the context channels contributed by a {@link cx} input. */
|
|
177
|
+
type CxInputContext<I> = I extends ReactiveValue ? Source.Context<I> : I extends ReadonlyArray<infer Item> ? CxInputContext<Item> : I extends CxRecord ? Source.Context<I[keyof I]> : never;
|
|
178
|
+
/**
|
|
179
|
+
* Result of {@link cx}: a plain `string` when every input is static, otherwise
|
|
180
|
+
* a `Stream<string>` unioning all reactive inputs' channels plus `NoPropValue`.
|
|
181
|
+
*/
|
|
182
|
+
type CxResult<Inputs extends ReadonlyArray<CxInput>> = true extends IsReactiveCxInput<Inputs[number]> ? Stream.Stream<string, CxInputError<Inputs[number]> | NoPropValue, CxInputContext<Inputs[number]>> : string;
|
|
183
|
+
/**
|
|
184
|
+
* Reactive clsx. Builds a class string from strings, falsy values (skipped),
|
|
185
|
+
* nested arrays, and `{ className: condition }` records, where any value or
|
|
186
|
+
* condition may be a `Stream`, `Effect`, or `Subscribable`.
|
|
187
|
+
*
|
|
188
|
+
* All-static inputs join into a plain string, so the descriptor stays
|
|
189
|
+
* analyzable. Any reactive input derives a pure `Stream<string>` description,
|
|
190
|
+
* the same engine {@link merge} uses for its `class` rule.
|
|
191
|
+
*
|
|
192
|
+
* @param inputs - Joined left to right, no dedupe.
|
|
193
|
+
*/
|
|
194
|
+
declare function cx<const Inputs extends ReadonlyArray<CxInput>>(...inputs: Inputs): CxResult<Inputs>;
|
|
195
|
+
//#endregion
|
|
196
|
+
export { HydrationMismatchError, props_d_exports as Props, RenderError, StreamSubscriptionError, UnsupportedNodeTypeError };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{t as e}from"./rolldown-runtime-DK3Fl9T5.js";import{_ as t,b as n,h as r,i,v as a}from"./shared-Dz0KM9ku.js";import{Cause as o,Effect as s,Exit as c,Stream as l,pipe as u}from"effect";import{NoPropValue as d,Subscribable as f,isStream as p}from"@weftui/core";var m=e({cx:()=>C,merge:()=>h});function h(...e){return e.reduce((e,t)=>g(e,t),{})}function g(e,t){let n={...e};for(let[r,i]of Object.entries(t))n[r]=Object.hasOwn(e,r)?y(r,e[r],i):i;return n}function _(e){return p(e)||s.isEffect(e)||f.isSubscribable(e)}function v(e){return typeof e==`object`&&!!e&&!Array.isArray(e)&&!_(e)&&w(e)}function y(e,t,n){return e===`ref`?[...b(t),...b(n)]:e===`class`?k([t,n],`class`):e===`style`?v(t)&&v(n)?{...t,...n}:n:i(e)?typeof t==`function`&&typeof n==`function`?S(t,n):n??t:n}function b(e){return(Array.isArray(e)?e:[e]).filter(e=>e!=null)}function x(e,t){try{let n=e(t);return s.isEffect(n)?n:s.void}catch(e){return s.die(e)}}function S(e,t){return n=>{let r=x(e,n),i=x(t,n);return s.gen(function*(){let e=yield*s.exit(r),t=yield*s.exit(i);if(c.isFailure(e)&&c.isFailure(t))return yield*s.failCause(o.fromReasons([...e.cause.reasons,...t.cause.reasons]));if(c.isFailure(e))return yield*s.failCause(e.cause);if(c.isFailure(t))return yield*s.failCause(t.cause)})}}function C(...e){return k(e)}function w(e){let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function T(e,t){for(let n of e)if(!(n===!1||n==null)){if(typeof n==`string`){n!==``&&t.push({kind:`static`,text:n});continue}if(Array.isArray(n)){T(n,t);continue}if(_(n)){t.push({kind:`value`,source:n});continue}if(w(n))for(let[e,r]of Object.entries(n))_(r)?t.push({kind:`toggle`,name:e,source:r}):r&&t.push({kind:`static`,text:e})}}function E(e,t){let n=[],r=0;for(let i of e){if(i.kind===`static`){n.push(i.text);continue}let e=t[r];r+=1,i.kind===`value`?typeof e==`string`&&e!==``&&n.push(e):e&&n.push(i.name)}return n.join(` `)}function D(e,t){return l.suspend(()=>{let n=!1;return u(e,l.tap(()=>s.sync(()=>{n=!0})),l.concat(l.suspend(()=>n?l.empty:l.fail(new d({key:t})))))})}function O(e,t){if(p(e))return D(e,t);if(s.isEffect(e))return l.fromEffect(e);let n=e;return l.concat(l.fromEffect(n.get),n.changes)}function k(e,t){let n=[];T(e,n);let r=n.filter(e=>e.kind!==`static`);if(r.length===0)return E(n,[]);let i=r.map(e=>O(e.source,t));return u(l.zipLatestAll(...i),l.map(e=>E(n,e)))}export{r as HydrationMismatchError,m as Props,t as RenderError,a as StreamSubscriptionError,n as UnsupportedNodeTypeError};
|
package/dist/server/index.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ declare const renderToStreamHydratable: (node: Renderable) => Stream.Stream<stri
|
|
|
27
27
|
* The server-side counterpart to the client DOM renderer, intended to produce
|
|
28
28
|
* output isomorphic with what the client renderer creates in the browser.
|
|
29
29
|
*
|
|
30
|
-
* Suspense boundaries render their fallback directly
|
|
30
|
+
* Suspense boundaries render their fallback directly: no comment markers
|
|
31
31
|
* and no `<template>`/`<script>` patches. For streaming Suspense support use
|
|
32
32
|
* {@link renderToStreamHydratable} / {@link renderToStream} instead.
|
|
33
33
|
*
|
|
@@ -53,7 +53,7 @@ declare const renderToStringHydratable: (node: Renderable$1) => Effect.Effect<st
|
|
|
53
53
|
*/
|
|
54
54
|
interface HydratableShell {
|
|
55
55
|
/**
|
|
56
|
-
* The fully buffered main walk
|
|
56
|
+
* The fully buffered main walk, byte-identical to the `mainStream` portion
|
|
57
57
|
* of `renderToStreamHydratable` for the same tree: reactive-region markers,
|
|
58
58
|
* Suspense fallbacks inline with their markers, resolved (blocking)
|
|
59
59
|
* `Boundary.rpc` regions, and failure-boundary fallbacks with payloads.
|
|
@@ -61,7 +61,7 @@ interface HydratableShell {
|
|
|
61
61
|
readonly shell: string;
|
|
62
62
|
/**
|
|
63
63
|
* The Suspense patch queue as a stream. Never fails (resolution fibers
|
|
64
|
-
* handle their own errors
|
|
64
|
+
* handle their own errors, see {@link SuspenseFailureHandlerTag}); completes
|
|
65
65
|
* once all pending boundaries have resolved, or immediately if the tree has
|
|
66
66
|
* no `Boundary.suspend`.
|
|
67
67
|
*/
|
|
@@ -73,7 +73,7 @@ interface HydratableShell {
|
|
|
73
73
|
* an HTTP consumer can decide status/headers before flushing any bytes, then
|
|
74
74
|
* streams Suspense patches separately.
|
|
75
75
|
*
|
|
76
|
-
* Errors raised during the main walk fail this Effect
|
|
76
|
+
* Errors raised during the main walk fail this Effect. Nothing has been
|
|
77
77
|
* handed to the consumer yet, so the caller may respond with a different
|
|
78
78
|
* document and a real status (AC-SH2).
|
|
79
79
|
*
|
|
@@ -95,7 +95,7 @@ interface SuspenseFailureSubstitute {
|
|
|
95
95
|
* When `true`, the patch script also injects
|
|
96
96
|
* `<meta name="robots" content="noindex">` into `document.head` before
|
|
97
97
|
* performing the swap (the head has long been flushed; DOM injection is the
|
|
98
|
-
* only route
|
|
98
|
+
* only route: Googlebot's soft-404 pattern).
|
|
99
99
|
*/
|
|
100
100
|
readonly markNoindex: boolean;
|
|
101
101
|
/**
|
|
@@ -114,7 +114,7 @@ interface SuspenseFailureSubstitute {
|
|
|
114
114
|
* cause escapes the suspended children unhandled (no failure `Boundary`
|
|
115
115
|
* inside the children matched it). Returning `Option.some` substitutes the
|
|
116
116
|
* patch content for that boundary; `Option.none` (or an absent service)
|
|
117
|
-
* keeps the default behaviour
|
|
117
|
+
* keeps the default behaviour: the failure is swallowed, no patch is
|
|
118
118
|
* emitted, and the fallback persists. Spec: `streaming-shell.specs.md`
|
|
119
119
|
* (AC-FH1 … AC-FH6).
|
|
120
120
|
*/
|
package/dist/server/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{a as e,b as t,d as n,f as r,i,o as a,p as o,t as s,u as c}from"../shared-Dz0KM9ku.js";import{n as l,t as u}from"../boundary-replay-BY4GyLot.js";import{Cause as d,Context as f,Effect as p,Exit as m,Option as h,Queue as g,Ref as _,Schema as v,Scope as y,Stream as b}from"effect";import{AppRpcClientTag as ee,FAILURE_BOUNDARY as x,FRAGMENT as S,LIST as C,SERVER_BOUNDARY as w,SUSPENSE_BOUNDARY as T,Source as te,Subscribable as E,getElementDescriptor as D,isStream as O,toStream as k}from"@weftui/core";const A=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]),j={'"':`"`,"&":`&`,"'":`'`,"<":`<`,">":`>`};function M(e){return e.replace(/["'&<>]/g,e=>j[e]??e)}const N=new Set([38,60,62,8232,8233]);function P(e){let t=JSON.stringify(e),n=``;for(let e=0;e<t.length;e++){let r=t.charCodeAt(e);N.has(r)?n+=`\\u${r.toString(16).padStart(4,`0`)}`:n+=t[e]}return n}function F(e){return e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}function I(e){return p.gen(function*(){let t=``;for(let[n,r]of Object.entries(e))if(!(n===`children`||n===`ref`||i(n))){if(n===`style`){t+=yield*R(r);continue}t+=yield*ne(n,r)}return t})}function L(e){return O(e)||p.isEffect(e)?k(e).pipe(b.runHead,p.map(h.getOrElse(()=>void 0))):p.succeed(e)}function ne(e,t){return p.gen(function*(){let n=yield*L(t);return n==null?``:typeof n==`boolean`?n?` ${e}=""`:``:` ${e}="${M(String(n))}"`})}function R(e){return p.gen(function*(){let t=yield*L(e);if(t==null)return``;if(typeof t==`string`)return t===``?``:` style="${M(t)}"`;if(typeof t==`object`){let e=[];for(let[n,r]of Object.entries(t)){let t=yield*L(r);t!=null&&e.push(`${F(n)}: ${String(t)}`)}return e.length===0?``:` style="${M(e.join(`; `))}"`}return``})}var z=class extends f.Service()(`@weftui/dom/SuspenseFailureHandler`){};function B(e,t,n=!1,i){let a=o(e),c=r(e),l=n?`var m=document.createElement("meta");m.setAttribute("name","robots");m.setAttribute("content","noindex");document.head.appendChild(m);`:``,u=i!==void 0,d=u?`<script type="application/json" ${s}>`+P({error:i})+`<\/script>`+t:t,f=u?``:`p.removeChild(s);p.removeChild(e);`;return`<template id="ef-s-${e}">${d}</template><script>(function(){`+l+`var w=document.createTreeWalker(document,128),s,e;while(w.nextNode()){var d=w.currentNode.data;if(d==="${a}")s=w.currentNode;if(d==="${c}"){e=w.currentNode;break;}}if(!s||!e)return;var p=s.parentNode,c=s.nextSibling,n;while(c&&c!==e){n=c.nextSibling;p.removeChild(c);c=n;}var t=document.getElementById("ef-s-${e}");p.insertBefore(t.content,e);`+f+`t.remove();document.currentScript.remove();})();<\/script>`}function V(e,t,n){return b.unwrap(p.gen(function*(){let i=++t.idCounter.current;yield*_.update(t.pendingCount,e=>e+1);let a=e.children===void 0?null:(Array.isArray(e.children),e.children),s=p.gen(function*(){let e=yield*b.mkString(n(a));yield*g.offer(t.patchQueue,h.some(B(i,e)))}).pipe(p.catchCause(e=>d.hasInterruptsOnly(e)?p.failCause(e):p.gen(function*(){let r=yield*p.serviceOption(z);if(h.isNone(r))return;let a=r.value.handle(e);if(h.isNone(a))return;let o=yield*b.mkString(n(a.value.content));yield*g.offer(t.patchQueue,h.some(B(i,o,a.value.markNoindex,a.value.failureReplay)))})),p.ensuring(_.updateAndGet(t.pendingCount,e=>e-1).pipe(p.flatMap(e=>e<=0?g.offer(t.patchQueue,h.none()).pipe(p.asVoid):p.void))),p.ignore);yield*p.forkIn(s,t.scope);let c=`<!--${o(i)}-->`,l=`<!--${r(i)}-->`,u=e.fallback??null;return b.make(c).pipe(b.concat(n(u)),b.concat(b.make(l)))}))}function H(e,t,n){let r=e.children.length===0?null:e.children.length===1?e.children[0]:e.children;return b.unwrap(p.gen(function*(){let i=yield*b.mkString(n(r)).pipe(p.catchCause(r=>p.gen(function*(){let i=e.match(r);if(i===null)return yield*p.failCause(r);let a=yield*b.mkString(n(i));if(t===null)return a;let o=yield*_.getAndSet(t,h.none());return h.isNone(o)?a:`<script type="application/json" ${u}>${P({index:l(e.children).indexOf(o.value.owner),error:o.value.encoded})}<\/script>`+a})));return b.make(i)}))}function re(e,t,n){if(t===null)return p.failCause(n);let r=d.findErrorOption(n);return h.isNone(r)?p.failCause(n):v.encodeEffect(e.errorSchema)(r.value).pipe(p.flatMap(n=>_.set(t,h.some({owner:e,encoded:n}))),p.matchCauseEffect({onFailure:()=>p.failCause(n),onSuccess:()=>p.failCause(n)}))}function ie(e){return{value:E.make({get:p.succeed(e),changes:b.make(e)}),refetch:p.void,pending:E.make({get:p.succeed(!1),changes:b.make(!1)}),error:E.make({get:p.succeed(h.none()),changes:b.make(h.none())})}}function U(e,t,n,r){return b.unwrap(p.gen(function*(){let i=yield*(yield*ee).call(e.tag,e.payload()).pipe(p.catchCause(t=>re(e,n,t))),a=r(e.render(ie(i)));if(!t)return a;let o=`<script type="application/json">${P(yield*v.encodeEffect(e.successSchema)(i))}<\/script>`;return b.make(o).pipe(b.concat(a))}))}function W(e){return p.scoped(te.toSubscribable(e).pipe(p.flatMap(e=>e.get),p.map(e=>Array.from(e)),p.catchTag(`NoPropValue`,()=>p.succeed([]))))}function G(e,n){if(e==null||typeof e==`boolean`)return b.empty;if(typeof e==`string`||typeof e==`number`||typeof e==`bigint`)return b.make(M(String(e)));if(O(e)||p.isEffect(e)){let t=D(e);if(t!==void 0)return G(t,n);if(p.isEffect(e)){let t=p.runSyncExit(e);if(m.isSuccess(t))return G(t.value,n)}return k(e).pipe(b.runHead,p.map(h.match({onNone:()=>b.empty,onSome:e=>G(e,n)})),b.unwrap)}if(typeof e==`object`&&Symbol.iterator in e&&!(`type`in e))return b.flatMap(b.fromIterable(e),e=>G(e,n));if(typeof e==`object`&&`type`in e&&!(Symbol.iterator in e)){let{type:t,props:r}=e;if(t===S)return q(r,n);if(t===T){let e=r;return n===null?G(e.fallback??null,null):V(e,n,e=>G(e,n))}if(t===x)return H(r,null,e=>G(e,n));if(t===w)return U(r,!1,null,e=>G(e,n));if(t===C)return K(r,n);if(typeof t==`string`){let e=b.fromEffect(I(r).pipe(p.map(e=>`<${t}${e}>`)));return A.has(t)?e:e.pipe(b.concat(q(r,n)),b.concat(b.make(`</${t}>`)))}if(typeof t==`function`)return G(t(r),n)}return b.fail(new t({type:e.type,message:`Invalid Renderable type: expected string, FRAGMENT, or function, got ${typeof e.type}`}))}function K(e,t){return b.unwrap(p.gen(function*(){let n=yield*W(e.of),r=b.empty;return n.forEach((n,i)=>{r=r.pipe(b.concat(G(e.render(n,i),t)))}),r}))}function q(e,t){let n=`children`in e?e.children:void 0;if(n==null)return b.empty;let r=Array.isArray(n)?n:[n];return b.flatMap(b.fromIterable(r),e=>G(e,t))}function J(e,r,i){if(e==null||typeof e==`boolean`)return b.empty;if(typeof e==`string`||typeof e==`number`||typeof e==`bigint`)return b.make(M(String(e)));if(O(e)||p.isEffect(e)){let t=D(e);if(t!==void 0)return J(t,r,i);if(p.isEffect(e)){let t=p.runSyncExit(e);if(m.isSuccess(t))return J(t.value,r,i)}return k(e).pipe(b.runHead,p.map(e=>{let t=++r.current,a=h.match(e,{onNone:()=>b.empty,onSome:e=>J(e,r,i)});return b.make(`<!--${n(t)}-->`).pipe(b.concat(a),b.concat(b.make(`<!--${c(t)}-->`)))}),b.unwrap)}if(typeof e==`object`&&Symbol.iterator in e&&!(`type`in e))return b.flatMap(b.fromIterable(e),e=>J(e,r,i));if(typeof e==`object`&&`type`in e&&!(Symbol.iterator in e)){let{type:t,props:n}=e;if(t===S)return Y(n,r,i);if(t===T){let e=n;return i===null?J(e.fallback??null,r,null):V(e,i,e=>J(e,r,i))}if(t===x)return H(n,i?.failureCollector??null,e=>J(e,r,i));if(t===w)return U(n,!0,i?.failureCollector??null,e=>J(e,r,i));if(t===C)return ae(n,r,i);if(typeof t==`string`){let e=b.fromEffect(I(n).pipe(p.map(e=>`<${t}${e}>`)));return A.has(t)?e:e.pipe(b.concat(Y(n,r,i)),b.concat(b.make(`</${t}>`)))}if(typeof t==`function`)return J(t(n),r,i)}return b.fail(new t({type:e.type,message:`Invalid Renderable type: expected string, FRAGMENT, or function, got ${typeof e.type}`}))}function ae(t,r,i){return b.unwrap(p.gen(function*(){let o=++r.current,s=yield*W(t.of),l=b.empty;return s.forEach((n,o)=>{let s=++r.current;l=l.pipe(b.concat(b.make(`<!--${a(s)}-->`)),b.concat(J(t.render(n,o),r,i)),b.concat(b.make(`<!--${e(s)}-->`)))}),b.make(`<!--${n(o)}-->`).pipe(b.concat(l),b.concat(b.make(`<!--${c(o)}-->`)))}))}function Y(e,t,n){let r=`children`in e?e.children:void 0;if(r==null)return b.empty;let i=Array.isArray(r)?r:[r];return b.flatMap(b.fromIterable(i),e=>J(e,t,n))}const X=e=>G(e,null),oe=e=>b.unwrap(p.gen(function*(){let t=yield*g.unbounded(),n=yield*_.make(0),r=G(e,{patchQueue:t,pendingCount:n,idCounter:{current:0},scope:yield*p.scope,failureCollector:null}).pipe(b.ensuring(_.get(n).pipe(p.flatMap(e=>e===0?g.offer(t,h.none()).pipe(p.asVoid):p.void))));return b.concat(r,Z(t))})),Z=e=>b.fromQueue(e).pipe(b.takeWhile(h.isSome),b.map(e=>e.value)),Q=(e,t)=>p.gen(function*(){let n=yield*g.unbounded();yield*y.addFinalizer(t,p.asVoid(g.offer(n,h.none())));let r=yield*_.make(0);return{mainStream:J(e,{current:0},{patchQueue:n,pendingCount:r,idCounter:{current:0},scope:t,failureCollector:yield*_.make(h.none())}).pipe(b.ensuring(_.get(r).pipe(p.flatMap(e=>e===0?g.offer(n,h.none()).pipe(p.asVoid):p.void)))),patches:Z(n)}}),$=e=>b.unwrap(p.gen(function*(){let t=yield*p.scope,{mainStream:n,patches:r}=yield*Q(e,t);return b.concat(n,r)})),se=e=>X(e).pipe(b.mkString),ce=e=>$(e).pipe(b.mkString),le=e=>p.gen(function*(){let t=yield*p.scope,n=yield*y.fork(t,`sequential`),{mainStream:r,patches:i}=yield*Q(e,n);return{shell:yield*b.mkString(r).pipe(p.onError(e=>y.close(n,m.failCause(e)))),patches:i}});export{z as SuspenseFailureHandlerTag,le as renderToHydratableShell,oe as renderToStream,$ as renderToStreamHydratable,se as renderToString,ce as renderToStringHydratable};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Context as e,Data as t}from"effect";var n=class extends t.TaggedError(`UnsupportedNodeTypeError`){},r=class extends t.TaggedError(`StreamSubscriptionError`){},i=class extends t.TaggedError(`RenderError`){},a=class extends t.TaggedError(`HydrationMismatchError`){},o=class extends e.Service()(`BoundaryContext`){},s=class extends e.Service()(`SuspenseContext`){},c=class extends e.Service()(`RenderContext`){};function l(e){return` stream-start-${e} `}function u(e){return` stream-end-${e} `}function d(e){return` suspense-start-${e} `}function f(e){return` suspense-end-${e} `}const p=`data-weft-suspense-failure`,m=/^ suspense-(start|end)-(\d+) $/;function h(e){let t=m.exec(e.data);return t===null?null:{kind:t[1],id:Number.parseInt(t[2],10)}}function g(e){return` boundary-start-${e} `}function _(e){return` boundary-end-${e} `}const v=/^ stream-(start|end)-(\d+) $/;function y(e){let t=v.exec(e.data);return t===null?null:{kind:t[1],id:Number.parseInt(t[2],10)}}function b(e){return` list-item-start-${e} `}function x(e){return` list-item-end-${e} `}const S=/^ list-item-(start|end)-(\d+) $/;function C(e){let t=S.exec(e.data);return t===null?null:{kind:t[1],id:Number.parseInt(t[2],10)}}function w(e){if(e.length<=2||!e.startsWith(`on`))return!1;let t=e[2];return t!==void 0&&t>=`a`&&t<=`z`}export{i as _,x as a,n as b,y as c,l as d,f,c as g,a as h,w as i,h as l,o as m,_ as n,b as o,d as p,g as r,C as s,p as t,u,r as v,s as y};
|