@weftui/dom 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/boundary-replay-C9r9jASU.js +1 -0
- package/dist/client/index.d.ts +78 -0
- package/dist/client/index.js +1 -0
- package/dist/data-Bk62ePeP.js +1 -0
- package/dist/data-Bk7mnjdd.d.ts +48 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/server/index.d.ts +50 -0
- package/dist/server/index.js +1 -0
- package/package.json +44 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stef van Wijchen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -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";function c(e){return` stream-start-${e} `}function l(e){return` stream-end-${e} `}function u(e){return` suspense-start-${e} `}function d(e){return` suspense-end-${e} `}const f=/^ suspense-(start|end)-(\d+) $/;function p(e){let t=f.exec(e.data);return t===null?null:{kind:t[1],id:Number.parseInt(t[2],10)}}function m(e){return` boundary-start-${e} `}function h(e){return` boundary-end-${e} `}const g=/^ stream-(start|end)-(\d+) $/;function _(e){let t=g.exec(e.data);return t===null?null:{kind:t[1],id:Number.parseInt(t[2],10)}}function v(e){return` list-item-start-${e} `}function y(e){return` list-item-end-${e} `}const b=/^ list-item-(start|end)-(\d+) $/;function x(e){let t=b.exec(e.data);return t===null?null:{kind:t[1],id:Number.parseInt(t[2],10)}}const S=`data-weft-boundary-failure`;function C(e){let t=[];return w(e,t),t}function w(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&&T(e,n);return}if(typeof t==`object`&&Symbol.iterator in t&&!(`type`in t)){for(let e of t)w(e,n);return}typeof t==`object`&&`type`in t&&!(Symbol.iterator in t)&&T(t,n)}}function T(e,o){let{type:s,props:c}=e;if(s===i){o.push(c);return}if(s===n||s===a||s===t){E(c,o);return}if(s!==r){if(typeof s==`string`){E(c,o);return}typeof s==`function`&&w(s(c),o)}}function E(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)w(e,t)}export{y as a,_ as c,c as d,d as f,m as i,p as l,C as n,v as o,u as p,h as r,x as s,S as t,l as u};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { i as UnsupportedNodeTypeError, n as RenderError, r as StreamSubscriptionError, t as HydrationMismatchError } from "../data-Bk7mnjdd.js";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { AssertNoServerOnly, Node, Renderable, ServerOnlyLeak } from "@weftui/core";
|
|
4
|
+
|
|
5
|
+
//#region src/client/render.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Cleanup handle returned from mount that allows unmounting
|
|
8
|
+
*/
|
|
9
|
+
interface MountHandle {
|
|
10
|
+
/**
|
|
11
|
+
* Unmounts the rendered tree and cleans up all resources.
|
|
12
|
+
* Returns an Effect that completes when cleanup is done.
|
|
13
|
+
* Safe to call multiple times (idempotent).
|
|
14
|
+
*/
|
|
15
|
+
unmount(): Effect.Effect<void>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Mounts a JSX tree to a DOM element with full reactive support.
|
|
19
|
+
*
|
|
20
|
+
* - Clears the root element's existing children
|
|
21
|
+
* - Renders the JSX tree to DOM nodes
|
|
22
|
+
* - Sets up reactive subscriptions for Stream/Effect values
|
|
23
|
+
* - Returns Effect that completes after initial render (streams run in background)
|
|
24
|
+
* - Creates a fresh ManagedRuntime per mount
|
|
25
|
+
* - Returns a cleanup handle to unmount and dispose resources
|
|
26
|
+
*
|
|
27
|
+
* @param app - JSX tree to render
|
|
28
|
+
* @param root - HTMLElement to mount to
|
|
29
|
+
* @returns Effect that yields MountHandle for cleanup
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* const app = <div>Hello World</div>;
|
|
34
|
+
* const root = document.getElementById("root")!;
|
|
35
|
+
* const handle = await Effect.runPromise(mount(app, root));
|
|
36
|
+
* // Later: cleanup
|
|
37
|
+
* await Effect.runPromise(handle.unmount());
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
declare function mount(app: Renderable, root: HTMLElement): Effect.Effect<MountHandle, UnsupportedNodeTypeError | StreamSubscriptionError | RenderError>;
|
|
41
|
+
/**
|
|
42
|
+
* Continues, on the client, the DOM produced on the server by
|
|
43
|
+
* `renderToStringHydratable`/`renderToStreamHydratable`.
|
|
44
|
+
*
|
|
45
|
+
* Unlike {@link mount}, `hydrate` does **not** clear the root: it walks the JSX
|
|
46
|
+
* tree in lockstep with the existing server DOM, adopting nodes in place,
|
|
47
|
+
* attaching event handlers and reactive subscriptions without re-creating the
|
|
48
|
+
* static structure. Reactive (`Stream`/`Effect`) regions are located via the
|
|
49
|
+
* `<!-- stream-start-N -->` / `<!-- stream-end-N -->` comment markers emitted by
|
|
50
|
+
* the hydratable server renderer. The stream's **first** emission is hydrated
|
|
51
|
+
* against that server-rendered content in place (no re-render, node identity
|
|
52
|
+
* preserved); only subsequent emissions patch the region — see
|
|
53
|
+
* `hydrate.specs.md`.
|
|
54
|
+
*
|
|
55
|
+
* Shares {@link mount}'s lifecycle: a fresh `ManagedRuntime` per call, a `Scope`
|
|
56
|
+
* owning all forked subscriptions, and a {@link MountHandle} for teardown.
|
|
57
|
+
*
|
|
58
|
+
* Hydration is a **client-only** operation: the app's requirement channel `R`
|
|
59
|
+
* must be free of server-only dependencies. A {@link Boundary.server} discharges
|
|
60
|
+
* its `load`'s server requirements via `provide`, so they never reach here — but
|
|
61
|
+
* a server-only `ServerTag` accidentally referenced in client (`render`) code
|
|
62
|
+
* stays in `R`, and {@link AssertNoServerOnly} turns that into a compile error
|
|
63
|
+
* (the return type degrades to the {@link ServerOnlyLeak} sentinel).
|
|
64
|
+
*
|
|
65
|
+
* @param app - JSX tree to hydrate (must match the tree rendered on the server)
|
|
66
|
+
* @param root - HTMLElement whose children were produced by the server renderer
|
|
67
|
+
* @returns Effect that yields a MountHandle for cleanup
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```tsx
|
|
71
|
+
* const root = document.getElementById("root")!;
|
|
72
|
+
* // root.innerHTML already contains server output
|
|
73
|
+
* const handle = await Effect.runPromise(hydrate(<App />, root));
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
declare function hydrate<A extends Renderable>(app: A, root: HTMLElement): [AssertNoServerOnly<Node.Context<A>>] extends [Node.Context<A>] ? Effect.Effect<MountHandle, UnsupportedNodeTypeError | StreamSubscriptionError | RenderError | HydrationMismatchError> : ServerOnlyLeak;
|
|
77
|
+
//#endregion
|
|
78
|
+
export { type MountHandle, hydrate, mount };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,n as t,o as n,r,s as i,t as a}from"../data-Bk62ePeP.js";import{a as o,c as s,d as c,f as l,i as u,l as d,n as f,o as p,p as m,r as h,s as g,u as _}from"../boundary-replay-C9r9jASU.js";import{Cause as v,Deferred as y,Effect as b,ExecutionStrategy as x,Exit as S,Fiber as C,HashMap as w,HashSet as T,Layer as E,ManagedRuntime as ee,Option as D,Ref as O,Schema as te,Scope as k,Stream as A,SubscriptionRef as j,pipe as M}from"effect";import{AppRpcClientTag as ne,FAILURE_BOUNDARY as re,FRAGMENT as ie,LIST as ae,SERVER_BOUNDARY as oe,SUSPENSE_BOUNDARY as se,Source as ce,getElementDescriptor as N,isStream as P,toStream as F}from"@weftui/core";function I(){return b.gen(function*(){let e=yield*r;return++e.streamIdCounter.current})}const le=I;let ue=0;const de=()=>++ue;function fe(e){if(e.length<=2||!e.startsWith(`on`))return!1;let t=e[2];return t!==void 0&&t>=`a`&&t<=`z`}function L(e,t){return b.gen(function*(){for(let[n,r]of Object.entries(t))if(n!==`children`){if(fe(n)){yield*ye(e,n,r);continue}if(n===`ref`&&typeof r==`object`&&O.RefTypeId in r){yield*O.set(r,D.some(e));continue}if(n===`style`){yield*_e(e,r);continue}pe(e,n)?yield*me(e,n,r):yield*he(e,n,r)}})}function pe(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 me(e,t,n){return b.gen(function*(){P(n)||b.isEffect(n)?yield*z(F(n),n=>{n==null?delete e[t]:e[t]=n},`property:${t}`):n!=null&&(e[t]=n)})}function he(e,t,n){return b.gen(function*(){if(P(n)||b.isEffect(n))yield*z(F(n),n=>{if(n==null)e.removeAttribute(t);else{let r=ge(n);r!==void 0&&(typeof n==`boolean`?n?e.setAttribute(t,``):e.removeAttribute(t):e.setAttribute(t,r))}},`attribute:${t}`);else{let r=ge(n);r!==void 0&&(typeof n==`boolean`?n?e.setAttribute(t,``):e.removeAttribute(t):e.setAttribute(t,r))}})}function ge(e){if(e!=null)return String(e)}function _e(e,t){return b.gen(function*(){if(P(t)||b.isEffect(t)){yield*z(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(R(n),String(r))}},`style`);return}if(typeof t==`string`){e.setAttribute(`style`,t);return}typeof t==`object`&&t&&(yield*ve(e,t))})}function ve(e,t){return b.gen(function*(){for(let[n,r]of Object.entries(t))P(r)||b.isEffect(r)?yield*z(F(r),t=>{t!=null&&e.style.setProperty(R(n),String(t))},`style.${n}`):r!=null&&e.style.setProperty(R(n),String(r))})}function R(e){return e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}function z(e,t,n){return b.gen(function*(){let n=yield*r,i=yield*b.serviceOption(a),o=A.runForEach(e,e=>b.sync(()=>void t(e))),s=yield*b.forkIn(o,n.scope);yield*M(C.await(s),b.flatMap(e=>S.isFailure(e)&&D.isSome(i)?i.value.reportError(e.cause):b.void),b.forkIn(n.scope))})}function ye(e,t,n){return b.gen(function*(){let i=yield*r,a=t.slice(2).toLowerCase(),o=null,s=()=>{o&&=(e.removeEventListener(a,o),null)},c=n=>{s(),!(n==null||n===!1)&&typeof n==`function`&&(o=e=>{let r=n(e);b.isEffect(r)&&i.runtime.runFork(M(r,b.catchAll(e=>process.env.NODE_ENV===`development`?b.logError(`Event handler error: ${t}`,{error:e}):b.void)))},e.addEventListener(a,o))};yield*k.addFinalizer(i.scope,b.sync(s)),P(n)||b.isEffect(n)?yield*z(F(n),e=>c(e),`event:${t}`):c(n)})}function be(e){return b.gen(function*(){let t=yield*r,n=yield*b.serviceOption(a),i=de(),o=document.createComment(u(i)),s=document.createComment(h(i)),c=yield*k.fork(t.scope,x.sequential),l={...t,scope:c},d=yield*y.make(),f=yield*M(V(e.children),b.provideService(a,{reportError:e=>y.fail(d,e).pipe(b.asVoid)}),b.provideService(r,l),b.provideService(k.Scope,c),b.catchAllCause(t=>{let n=e.match(t);return n===null?b.failCause(t):M(k.close(c,S.void),b.flatMap(()=>B(n)),b.map(e=>e===null?[]:Array.isArray(e)?e:[e]))})),p=b.gen(function*(){let t=yield*y.await(d).pipe(b.flip),r=e.match(t);if(yield*k.close(c,S.void),r===null)return D.isSome(n)?yield*n.value.reportError(t):yield*b.logError(`Unhandled error escaped the outermost Boundary`,t);K(o,s);let i=yield*B(r),a=s.parentNode;if(a!==null&&i!==null)if(Array.isArray(i))for(let e of i)a.insertBefore(e,s);else a.insertBefore(i,s)});return yield*b.forkIn(p,t.scope),[o,...f,s]})}function xe(e){return b.gen(function*(){let t=yield*r,i=yield*O.make(1),a=yield*y.make(),o=M(O.updateAndGet(i,e=>e-1),b.flatMap(e=>e<=0?b.asVoid(y.succeed(a,void 0)):b.void)),s={register:O.update(i,e=>e+1),settle:o},c=e.children,u=yield*B((c===void 0?[]:Array.isArray(c)?c:[c]).map(e=>b.isEffect(e)||P(e)?{type:()=>e,props:{}}:e)).pipe(b.provideService(n,s)),d=u===null?[]:Array.isArray(u)?u:[u];yield*o;let f=yield*y.poll(a);if(D.isSome(f))return d;let p=yield*le(),h=document.createComment(m(p)),g=document.createComment(l(p)),_=yield*B(e.fallback??null),v=[];_!==null&&(Array.isArray(_)?v.push(..._):v.push(_));let x=document.createDocumentFragment();for(let e of d)x.appendChild(e);let S=b.gen(function*(){yield*y.await(a),K(h,g);let e=g.parentNode;e!==null&&(e.insertBefore(x,g),h.remove(),g.remove())});return yield*b.forkIn(S,t.scope),[h,...v,g]})}function Se(t){return b.gen(function*(){let n=yield*r,i=yield*b.serviceOption(ne);if(D.isNone(i))return yield*b.fail(new e({cause:void 0,message:`Boundary.rpc "${t.tag}" was mounted client-first without an AppRpcClient in context. Mount the app under @weftui/router (RouterLive), which provides the rpc client, so the boundary can resolve its data.`}));let a=i.value,o=de(),s=document.createComment(u(o)),c=document.createComment(h(o)),l=yield*B(t.fallback??null),d=[];l!==null&&(Array.isArray(l)?d.push(...l):d.push(l));let f=b.gen(function*(){let e=yield*a.call(t.tag,t.payload()),n=yield*Ke(t.tag,t.payload,e,i),r=yield*B(t.render(n));K(s,c);let o=c.parentNode;if(o!==null&&r!==null)if(Array.isArray(r))for(let e of r)o.insertBefore(e,c);else o.insertBefore(r,c)}).pipe(b.catchAllCause(e=>b.logError(`[weft] Boundary.rpc "${t.tag}" mount failed to resolve; fallback left in place.`,e)));return yield*b.forkIn(f,n.scope),[s,...d,c]})}function B(e){return b.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)||b.isEffect(e)){let t=N(e);if(t!==void 0)return yield*B(t);if(b.isEffect(e)){let t=b.runSyncExit(e);if(S.isSuccess(t))return yield*B(t.value)}return yield*H(F(e))}if(typeof e==`object`&&Symbol.iterator in e&&!(`type`in e))return yield*V(Ce(e));if(typeof e==`object`&&`type`in e&&!(Symbol.iterator in e)){let{type:t,props:n}=e;return t===ie?yield*we(n):t===se?yield*xe(n):t===oe?yield*Se(n):t===re?yield*be(n):t===ae?yield*je(n):typeof t==`string`?yield*Te(t,n):typeof t==`function`?yield*Ee(t,n):yield*b.fail(new i({type:t,message:`Invalid Renderable type: expected string, FRAGMENT, or function, got ${typeof t}`}))}return null})}function Ce(e){let t=[];function n(e){if(P(e)||b.isEffect(e)){t.push(e);return}if(typeof e==`object`&&e&&Symbol.iterator in e&&!(`type`in e))for(let t of e)n(t);else t.push(e)}return n(e),t}function V(e){return b.gen(function*(){let t=[];for(let n of e)if(P(n)||b.isEffect(n)){let e=yield*H(F(n));t.push(...e)}else{let e=yield*B(n);e!==null&&(Array.isArray(e)?t.push(...e):t.push(e))}return t})}function we(e){return b.gen(function*(){let t=`children`in e?e.children:void 0;return t===void 0?[]:yield*V(Array.isArray(t)?t:[t])})}function Te(e,t){return b.gen(function*(){let n=document.createElement(e);yield*L(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(P(t)||b.isEffect(t)){let e=yield*H(F(t));for(let t of e)n.appendChild(t)}else{let e=yield*B(t);if(e!==null)if(Array.isArray(e))for(let t of e)n.appendChild(t);else n.appendChild(e)}}return n})}function Ee(e,t){return b.gen(function*(){let i=e(t);if(P(i)||b.isEffect(i)){let e=yield*r,t=yield*k.fork(e.scope,x.sequential),a={...e,scope:t},o=yield*b.serviceOption(n),s=F(i);return D.isSome(o)&&(yield*o.value.register,s=M(s,A.zipWithIndex,A.flatMap(([e,t])=>t===0?A.fromEffect(b.as(o.value.settle,e)):A.make(e)))),yield*H(s).pipe(b.provideService(r,a),b.provideService(k.Scope,t))}return yield*B(i)})}function H(e){return b.gen(function*(){let t=yield*r,[n,i]=De(yield*I()),o=null,s=A.runForEach(e,e=>b.gen(function*(){o!==null&&(yield*k.close(o,S.void)),o=yield*k.fork(t.scope,x.sequential);let a={...t,scope:o};yield*U(n,i,e).pipe(b.provideService(r,a),b.provideService(k.Scope,o))})),c=yield*b.forkIn(s,t.scope),l=yield*b.serviceOption(a);return yield*M(C.await(c),b.flatMap(e=>S.isFailure(e)&&D.isSome(l)?l.value.reportError(e.cause):b.void),b.forkIn(t.scope)),[n,i]})}function De(e){return[document.createComment(c(e)),document.createComment(_(e))]}function U(e,t,n){return b.gen(function*(){let r=e.nextSibling,i=r!==null&&r!==t&&r.nextSibling===t;if(i&&r.nodeType===$e&&W(n)){let e=String(n);r.data!==e&&(r.data=e);return}if(i&&r.nodeType===X){let e=G(n);if(e!==void 0&&typeof e.type==`string`&&r.tagName.toLowerCase()===e.type.toLowerCase()){yield*Oe(r,e);return}}K(e,t);let a=yield*B(n),o=e.parentNode;if(o!==null&&a!==null)if(Array.isArray(a))for(let e of a)o.insertBefore(e,t);else o.insertBefore(a,t)})}function W(e){return typeof e==`string`||typeof e==`number`||typeof e==`bigint`}function G(e){let t=N(e);if(t!==void 0)return t;if(typeof e==`object`&&e&&`type`in e&&!(Symbol.iterator in e)&&!P(e)&&!b.isEffect(e))return e}function Oe(e,t){return b.gen(function*(){yield*L(e,t.props);let n=t.props.children,r=n===void 0?[]:Array.isArray(n)?n:[n];if(!(yield*ke(e,r))){for(;e.firstChild!==null;)e.firstChild.remove();yield*Ae(e,r)}})}function ke(e,t){return b.gen(function*(){let n=Array.from(e.childNodes);if(n.length!==t.length)return!1;for(let e=0;e<t.length;e++){let r=t[e],i=n[e];if(W(r)){if(i.nodeType!==$e)return!1}else{let e=G(r);if(e===void 0||typeof e.type!=`string`||i.nodeType!==X||i.tagName.toLowerCase()!==e.type.toLowerCase())return!1}}for(let e=0;e<t.length;e++){let r=t[e],i=n[e];if(W(r)){let e=String(r);i.data!==e&&(i.data=e)}else yield*Oe(i,G(r))}return!0})}function Ae(e,t){return b.gen(function*(){for(let n of t)if(P(n)||b.isEffect(n)){let t=yield*H(F(n));for(let n of t)e.appendChild(n)}else{let t=yield*B(n);if(t!==null)if(Array.isArray(t))for(let n of t)e.appendChild(n);else e.appendChild(t)}})}function K(e,t){let n=e.nextSibling;for(;n!==null&&n!==t;){let e=n.nextSibling;n.remove(),n=e}}function je(e){return b.gen(function*(){let t=yield*r,{of:n,by:i,render:o}=e,[s,c]=De(yield*I()),l=yield*k.fork(t.scope,x.sequential),u=(yield*ce.toSubscribable(n).pipe(b.provideService(k.Scope,l))).changes,d={records:w.empty(),order:[]},f=A.runForEach(u,e=>b.gen(function*(){d=yield*q(Array.from(e),i,o,d,l,c,t)})),p=yield*b.forkIn(f,l),m=yield*b.serviceOption(a);return yield*M(C.await(p),b.flatMap(e=>S.isFailure(e)&&D.isSome(m)?m.value.reportError(e.cause):b.void),b.forkIn(t.scope)),[s,c]})}function Me(t,n){return b.gen(function*(){let r=[],i=T.empty();for(let a=0;a<t.length;a++){let o=n===void 0?t[a]:n(t[a],a);if(T.has(i,o))return yield*b.fail(new e({cause:o,message:`List.each: duplicate key ${Ie(o)} in a single emission; keys must be unique (set a stable \`by\`).`}));i=T.add(i,o),r.push(o)}return r})}function q(e,t,n,r,i,a,o){return b.gen(function*(){let s=yield*Me(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(D.isSome(d))l.push(d.value),u.push(D.getOrElse(w.get(c,a),()=>-1));else{let r=yield*Ne(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);D.isSome(t)&&(yield*k.close(t.value.scope,S.void),Fe(t.value.startMarker,t.value.endMarker))}let f=Le(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]:Pe(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 Ne(e,t,n,i,a,s){return b.gen(function*(){let c=yield*k.fork(a,x.sequential),l={...s,scope:c},u=yield*I(),d=document.createComment(p(u)),f=document.createComment(o(u)),m=yield*B(i(t,n)).pipe(b.provideService(r,l),b.provideService(k.Scope,c));return{key:e,scope:c,startMarker:d,endMarker:f,nodes:m===null?[]:Array.isArray(m)?m:[m]}})}function Pe(e,t){let n=[],r=e;for(;r!==null&&(n.push(r),r!==t);)r=r.nextSibling;return n}function Fe(e,t){let n=e;for(;n!==null;){let e=n.nextSibling;if(n.remove(),n===t)break;n=e}}function Ie(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 Le(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 Re(e,t){return b.gen(function*(){let n=yield*b.context(),i=ee.make(E.succeedContext(n)),a=yield*k.make(),o={runtime:i,scope:a,streamIdCounter:{current:0}},s=b.zipRight(k.close(a,S.void),b.promise(()=>i.dispose()));t.innerHTML=``;let c=yield*B(e).pipe(b.provideService(r,o),b.provideService(k.Scope,a),b.tapError(()=>s));if(c!==null)if(Array.isArray(c))for(let e of c)t.appendChild(e);else t.appendChild(c);let l=!1;return{unmount:()=>b.gen(function*(){l||(l=!0,yield*k.close(a,S.void),yield*b.promise(()=>i.dispose()))})}})}function ze(e,t){return b.gen(function*(){let n=yield*b.context(),i=ee.make(E.succeedContext(n)),a=yield*k.make(),o=yield*Ve(),s={runtime:i,scope:a,streamIdCounter:{current:0},hydrationReady:o};et(t,s.streamIdCounter);let c=b.zipRight(k.close(a,S.void),b.promise(()=>i.dispose()));yield*J(e,t.firstChild,`root`).pipe(b.provideService(r,s),b.provideService(k.Scope,a),b.tapError(()=>c)),yield*o.settle,yield*o.awaitReady;let l=!1;return{unmount:()=>b.gen(function*(){l||(l=!0,yield*k.close(a,S.void),yield*b.promise(()=>i.dispose()))})}})}function J(e,t,n){return b.gen(function*(){if(typeof e==`string`||typeof e==`number`||typeof e==`bigint`)return yield*Be(String(e),t,n);if(typeof e==`boolean`||e==null)return t;if(P(e)||b.isEffect(e)){let r=N(e);if(r!==void 0)return yield*J(r,t,n);if(b.isEffect(e)){let r=b.runSyncExit(e);if(S.isSuccess(r))return yield*J(r.value,t,n)}return yield*Ue(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*J(t,r,`${n}[${i}]`),i++;return r}if(typeof e==`object`&&`type`in e&&!(Symbol.iterator in e)){let{type:r,props:a}=e;return r===ie||r===se?yield*Y(a,t,n):r===re?yield*Ge(a,t,n):r===oe?yield*qe(a,t,n):r===ae?yield*Ye(a,t,n):typeof r==`string`?yield*Je(r,a,t,n):typeof r==`function`?yield*J(r(a),t,n):yield*b.fail(new i({type:r,message:`Invalid Renderable type during hydration at ${n}: expected string, FRAGMENT, or function, got ${typeof r}`}))}return t})}function Be(e,t,n){return b.gen(function*(){if(e.length===0)return t;if(t===null||t.nodeType!==$e)return yield*$(`text ${JSON.stringify(e)}`,Q(t),n);let r=t;return r.data.startsWith(e)?r.data.length>e.length?r.splitText(e.length):r.nextSibling:yield*$(`text ${JSON.stringify(e)}`,Q(t),n)})}function Ve(){return b.gen(function*(){let e=yield*O.make(1),t=yield*y.make(),n=M(O.updateAndGet(e,e=>e-1),b.flatMap(e=>e<=0?b.asVoid(y.succeed(t,void 0)):b.void));return{register:O.update(e,e=>e+1),settle:n,awaitReady:y.await(t)}})}function He(e){let t=!1;return b.suspend(()=>t||e===void 0?b.void:(t=!0,e.settle))}function Ue(e,t,n){return b.gen(function*(){let i=yield*r;if(t===null||t.nodeType!==Z)return yield*$(`reactive region start marker`,Q(t),n);let a=t,o=s(a);if(o===null||o.kind!==`start`)return yield*$(`reactive region start marker`,Q(t),n);let c=tt(a);if(c===null)return yield*$(`reactive region end marker`,`unterminated region starting at ${JSON.stringify(a.data)}`,n);let l=He(i.hydrationReady),u=!0,d=null,f=A.runForEach(e,e=>b.gen(function*(){d!==null&&(yield*k.close(d,S.void)),d=yield*k.fork(i.scope,x.sequential);let t={...i,scope:d};yield*b.gen(function*(){u?(u=!1,yield*We(e,a,c,n),yield*l):yield*U(a,c,e)}).pipe(b.provideService(r,t),b.provideService(k.Scope,d))})).pipe(b.ensuring(l));return i.hydrationReady!==void 0&&(yield*i.hydrationReady.register),yield*b.forkIn(f,i.scope),c.nextSibling})}function We(e,t,n,r){return b.gen(function*(){let i=yield*J(e,t.nextSibling,`${r}<resume>`).pipe(b.map(e=>e===n?null:`adopted content did not align with the end marker`),b.catchTag(`HydrationMismatchError`,e=>b.succeed(`expected ${e.expected}, found ${e.actual} at ${e.path}`)));i!==null&&(console.error(`[weft] hydrate: reactive region at ${r} diverged from server output (${i}); patching.`),yield*U(t,n,e))})}function Ge(e,t,n){return b.gen(function*(){if(t===null||t.nodeType!==X||t.tagName!==`SCRIPT`||t.getAttribute(`type`)!==`application/json`||!t.hasAttribute(`data-weft-boundary-failure`))return yield*Y(e,t,n);let r=t,i=r.textContent??``,a=yield*b.gen(function*(){let t=yield*b.try({try:()=>JSON.parse(i),catch:e=>e}),n=f(e.children)[t.index];if(n===void 0)return null;let r=yield*te.decodeUnknown(n.errorSchema)(t.error);return e.match(v.fail(r))}).pipe(b.catchAll(e=>(console.error(`[weft] hydrate: boundary failure payload at ${n} failed to decode; cannot replay.`,e),b.succeed(null))));if(a===null)return yield*$(`replayable boundary failure`,`undecodable failure payload`,n);let o=yield*J(a,r.nextSibling,n);return r.remove(),o})}function Ke(e,t,n,r){return b.gen(function*(){let i=yield*j.make(n),a=yield*j.make(!1),o=yield*j.make(D.none());return{value:i,refetch:D.match(r,{onNone:()=>b.void,onSome:n=>b.gen(function*(){(yield*j.get(a))||(yield*j.set(a,!0),yield*b.gen(function*(){let r=yield*b.exit(n.call(e,t()));S.isSuccess(r)?(yield*j.set(i,r.value),yield*j.set(o,D.none())):yield*j.set(o,D.some(v.squash(r.cause)))}).pipe(b.ensuring(j.set(a,!1))))})}),pending:a,error:o}})}function qe(e,t,n){return b.gen(function*(){if(t===null||t.nodeType!==X||t.tagName!==`SCRIPT`||t.getAttribute(`type`)!==`application/json`)return yield*$(`server boundary payload <script type="application/json">`,Q(t),n);if(t.hasAttribute(`data-weft-boundary-failure`))return yield*$(`server boundary success payload <script type="application/json">`,`boundary failure payload`,n);let r=t,i=r.textContent??``,a=yield*b.try({try:()=>JSON.parse(i),catch:e=>e}).pipe(b.flatMap(t=>te.decodeUnknown(e.successSchema)(t)),b.catchAll(e=>(console.error(`[weft] hydrate: server boundary payload at ${n} failed to decode; cannot replay.`,e),$(`decodable server boundary payload`,`undecodable payload`,n)))),o=yield*b.serviceOption(ne),s=yield*Ke(e.tag,e.payload,a,o),c=yield*J(e.render(s),r.nextSibling,n);return r.remove(),c})}function Je(e,t,n,r){return b.gen(function*(){if(n===null||n.nodeType!==X)return yield*$(`<${e}>`,Q(n),r);let i=n;return i.tagName.toLowerCase()===e.toLowerCase()?(yield*L(i,t),yield*Y(t,i.firstChild,`${r} > ${e}`),i.nextSibling):yield*$(`<${e}>`,Q(n),r)})}function Y(e,t,n){return b.gen(function*(){let r=`children`in e?e.children:void 0;if(r===void 0)return t;let i=Array.isArray(r)?r:[r],a=t,o=0;for(let e of i)a=yield*J(e,a,`${n}[${o}]`),o++;return a})}function Ye(e,t,n){return b.gen(function*(){let i=yield*r,{of:o,by:c,render:l}=e;if(t===null||t.nodeType!==Z)return yield*$(`list region start marker`,Q(t),n);let u=t,d=s(u);if(d===null||d.kind!==`start`)return yield*$(`list region start marker`,Q(t),n);let f=tt(u);if(f===null)return yield*$(`list region end marker`,`unterminated region starting at ${JSON.stringify(u.data)}`,n);let p=Xe(u,f),m=yield*k.fork(i.scope,x.sequential),h=(yield*ce.toSubscribable(o).pipe(b.provideService(k.Scope,m))).changes,g={records:w.empty(),order:[]},_=!0,v=He(i.hydrationReady),y=A.runForEach(h,e=>b.gen(function*(){let t=Array.from(e);_?(_=!1,g=yield*Ze(t,c,l,p,m,u,f,i,n),yield*v):g=yield*q(t,c,l,g,m,f,i)})).pipe(b.ensuring(v));i.hydrationReady!==void 0&&(yield*i.hydrationReady.register);let T=yield*b.forkIn(y,m),E=yield*b.serviceOption(a);return yield*M(C.await(T),b.flatMap(e=>S.isFailure(e)&&D.isSome(E)?E.value.reportError(e.cause):b.void),b.forkIn(i.scope)),f.nextSibling})}function Xe(e,t){let n=[],r=e.nextSibling;for(;r!==null&&r!==t;){let e=r.nodeType===Z?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===Z){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 Ze(e,t,n,r,i,a,o,s,c){return b.gen(function*(){let l=yield*Me(e,t);if(l.length!==r.length)return console.error(`[weft] hydrate: list region at ${c} had ${r.length} server item(s) but the first emission has ${l.length}; rebuilding.`),K(a,o),yield*q(e,t,n,{records:w.empty(),order:[]},i,o,s);let u=[];for(let t=0;t<e.length;t++){let a=yield*Qe(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 Qe(e,t,n,i,a,o,s,c){return b.gen(function*(){let l=yield*k.fork(o,x.sequential),u={...s,scope:l},d=i(t,n),f=yield*J(d,a.startMarker.nextSibling,`${c}<item>`).pipe(b.provideService(r,u),b.provideService(k.Scope,l),b.map(e=>e===a.endMarker?null:`adopted item content did not align with its end marker`),b.catchTag(`HydrationMismatchError`,e=>b.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,S.void);let p=yield*k.fork(o,x.sequential),m={...s,scope:p};K(a.startMarker,a.endMarker);let h=yield*B(d).pipe(b.provideService(r,m),b.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 X=1,$e=3,Z=8;function et(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=s(t)??d(t)??g(t);n!==null&&n.id>r&&(r=n.id)}t.current=r}function tt(e){let t=0,n=e.nextSibling;for(;n!==null;){if(n.nodeType===8){let e=s(n);if(e!==null)if(e.kind===`start`)t++;else if(t===0)return n;else t--}n=n.nextSibling}return null}function Q(e){if(e===null)return`end of children`;switch(e.nodeType){case 1:return`<${e.tagName.toLowerCase()}>`;case 3:return`text ${JSON.stringify(e.data)}`;case 8:return`comment ${JSON.stringify(e.data)}`;default:return`node(type ${e.nodeType})`}}function $(e,n,r){return b.fail(new t({expected:e,actual:n,path:r}))}export{ze as hydrate,Re as mount};
|
|
@@ -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.Tag(`BoundaryContext`)(){},s=class extends e.Tag(`SuspenseContext`)(){},c=class extends e.Tag(`RenderContext`)(){};export{r as a,i,a as n,s as o,c as r,n as s,o as t};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Cause, Context, Effect, ManagedRuntime, Scope } from "effect";
|
|
2
|
+
|
|
3
|
+
//#region src/data.d.ts
|
|
4
|
+
declare const UnsupportedNodeTypeError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => Cause.YieldableError & {
|
|
5
|
+
readonly _tag: "UnsupportedNodeTypeError";
|
|
6
|
+
} & Readonly<A>;
|
|
7
|
+
/**
|
|
8
|
+
* Error thrown when Renderable has invalid type (not string, FRAGMENT, or function)
|
|
9
|
+
*/
|
|
10
|
+
declare class UnsupportedNodeTypeError extends UnsupportedNodeTypeError_base<{
|
|
11
|
+
readonly type: unknown;
|
|
12
|
+
readonly message: string;
|
|
13
|
+
}> {}
|
|
14
|
+
declare const StreamSubscriptionError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => Cause.YieldableError & {
|
|
15
|
+
readonly _tag: "StreamSubscriptionError";
|
|
16
|
+
} & Readonly<A>;
|
|
17
|
+
/**
|
|
18
|
+
* Error thrown when stream subscription or execution fails
|
|
19
|
+
*/
|
|
20
|
+
declare class StreamSubscriptionError extends StreamSubscriptionError_base<{
|
|
21
|
+
readonly cause: unknown;
|
|
22
|
+
readonly context: string;
|
|
23
|
+
}> {}
|
|
24
|
+
declare const RenderError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => Cause.YieldableError & {
|
|
25
|
+
readonly _tag: "RenderError";
|
|
26
|
+
} & Readonly<A>;
|
|
27
|
+
/**
|
|
28
|
+
* Error thrown for general rendering failures
|
|
29
|
+
*/
|
|
30
|
+
declare class RenderError extends RenderError_base<{
|
|
31
|
+
readonly cause: unknown;
|
|
32
|
+
readonly message: string;
|
|
33
|
+
}> {}
|
|
34
|
+
declare const HydrationMismatchError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }>) => Cause.YieldableError & {
|
|
35
|
+
readonly _tag: "HydrationMismatchError";
|
|
36
|
+
} & Readonly<A>;
|
|
37
|
+
/**
|
|
38
|
+
* Error thrown when the existing DOM does not match the JSX tree during
|
|
39
|
+
* hydration (e.g. expected a text node but found an element, mismatched tag
|
|
40
|
+
* name, or a missing reactive-region marker).
|
|
41
|
+
*/
|
|
42
|
+
declare class HydrationMismatchError extends HydrationMismatchError_base<{
|
|
43
|
+
readonly expected: string;
|
|
44
|
+
readonly actual: string;
|
|
45
|
+
readonly path: string;
|
|
46
|
+
}> {}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { UnsupportedNodeTypeError as i, RenderError as n, StreamSubscriptionError as r, HydrationMismatchError as t };
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,i as t,n,s as r}from"./data-Bk62ePeP.js";export{n as HydrationMismatchError,t as RenderError,e as StreamSubscriptionError,r as UnsupportedNodeTypeError};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Effect, Stream } from "effect";
|
|
2
|
+
import { AppRpcClientTag, Renderable } from "@weftui/core";
|
|
3
|
+
import { Renderable as Renderable$1 } from "@weftui/core/types";
|
|
4
|
+
|
|
5
|
+
//#region src/server/render-to-stream.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Progressively serializes an Effect-infused JSX tree (`Renderable`) into a stream
|
|
8
|
+
* of HTML string chunks, in render-tree order.
|
|
9
|
+
*
|
|
10
|
+
* suspense boundaries are fully supported: the fallback is emitted inline
|
|
11
|
+
* between `<!-- suspense-start-N -->` / `<!-- suspense-end-N -->` comment
|
|
12
|
+
* markers; a `<template>+<script>` patch chunk is appended after the main
|
|
13
|
+
* document structure as each boundary resolves. The stream terminates only
|
|
14
|
+
* after all pending boundaries have emitted their patch.
|
|
15
|
+
*/
|
|
16
|
+
declare const renderToStream: (node: Renderable) => Stream.Stream<string, Error, AppRpcClientTag>;
|
|
17
|
+
/**
|
|
18
|
+
* Like {@link renderToStream}, but wraps each reactive (`Stream`/`Effect`)
|
|
19
|
+
* region in `<!-- stream-start-N -->` … `<!-- stream-end-N -->` comment markers
|
|
20
|
+
* so the client `hydrate` can locate reactive regions. Suspense streaming
|
|
21
|
+
* patches include these markers in the resolved children HTML (AC-SS3).
|
|
22
|
+
*/
|
|
23
|
+
declare const renderToStreamHydratable: (node: Renderable) => Stream.Stream<string, Error, AppRpcClientTag>;
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/server/render-to-string.d.ts
|
|
26
|
+
/**
|
|
27
|
+
* Serializes an Effect-infused JSX tree (`Renderable`) into a single HTML string.
|
|
28
|
+
* The server-side counterpart to the client DOM renderer, intended to produce
|
|
29
|
+
* output isomorphic with what the client renderer creates in the browser.
|
|
30
|
+
*
|
|
31
|
+
* Suspense boundaries render their fallback directly — no comment markers
|
|
32
|
+
* and no `<template>`/`<script>` patches. For streaming Suspense support use
|
|
33
|
+
* {@link renderToStreamHydratable} / {@link renderToStream} instead.
|
|
34
|
+
*
|
|
35
|
+
* Requires an {@link AppRpcClientTag} in context when the tree contains a
|
|
36
|
+
* `Boundary.rpc` (provided by `@weftui/router`'s `RouterServer`).
|
|
37
|
+
*/
|
|
38
|
+
declare const renderToString: (node: Renderable$1) => Effect.Effect<string, Error, AppRpcClientTag>;
|
|
39
|
+
/**
|
|
40
|
+
* Like {@link renderToString}, but emits the reactive-region comment markers
|
|
41
|
+
* (`<!-- stream-start-N -->` … `<!-- stream-end-N -->`) that the client
|
|
42
|
+
* `hydrate` needs to locate reactive regions. Use this when the page will be
|
|
43
|
+
* hydrated on the client; use {@link renderToString} for static, non-hydrated
|
|
44
|
+
* output.
|
|
45
|
+
*
|
|
46
|
+
* Re-derived from {@link renderToStreamHydratable} via `Stream.mkString`.
|
|
47
|
+
*/
|
|
48
|
+
declare const renderToStringHydratable: (node: Renderable$1) => Effect.Effect<string, Error, AppRpcClientTag>;
|
|
49
|
+
//#endregion
|
|
50
|
+
export { renderToStream, renderToStreamHydratable, renderToString, renderToStringHydratable };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{s as e}from"../data-Bk62ePeP.js";import{a as t,d as n,f as r,n as i,o as a,p as o,t as s,u as c}from"../boundary-replay-C9r9jASU.js";import{Cause as l,Effect as u,Exit as d,Option as f,Queue as p,Ref as m,Schema as h,Stream as g,Subscribable as _}from"effect";import{AppRpcClientTag as v,FAILURE_BOUNDARY as y,FRAGMENT as b,LIST as x,SERVER_BOUNDARY as S,SUSPENSE_BOUNDARY as C,Source as w,getElementDescriptor as T,isStream as E,toStream as D}from"@weftui/core";function O(e){if(e.length<=2||!e.startsWith(`on`))return!1;let t=e[2];return t!==void 0&&t>=`a`&&t<=`z`}const k=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]),A={'"':`"`,"&":`&`,"'":`'`,"<":`<`,">":`>`};function j(e){return e.replace(/["'&<>]/g,e=>A[e]??e)}const ee=new Set([38,60,62,8232,8233]);function M(e){let t=JSON.stringify(e),n=``;for(let e=0;e<t.length;e++){let r=t.charCodeAt(e);ee.has(r)?n+=`\\u${r.toString(16).padStart(4,`0`)}`:n+=t[e]}return n}function N(e){return e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}function P(e){return u.gen(function*(){let t=``;for(let[n,r]of Object.entries(e))if(!(n===`children`||n===`ref`||O(n))){if(n===`style`){t+=yield*L(r);continue}t+=yield*I(n,r)}return t})}function F(e){return E(e)||u.isEffect(e)?D(e).pipe(g.runHead,u.map(f.getOrElse(()=>void 0))):u.succeed(e)}function I(e,t){return u.gen(function*(){let n=yield*F(t);return n==null?``:typeof n==`boolean`?n?` ${e}=""`:``:` ${e}="${j(String(n))}"`})}function L(e){return u.gen(function*(){let t=yield*F(e);if(t==null)return``;if(typeof t==`string`)return t===``?``:` style="${j(t)}"`;if(typeof t==`object`){let e=[];for(let[n,r]of Object.entries(t)){let t=yield*F(r);t!=null&&e.push(`${N(n)}: ${String(t)}`)}return e.length===0?``:` style="${j(e.join(`; `))}"`}return``})}function R(e,t){return`<template id="ef-s-${e}">${t}</template><script>(function(){var w=document.createTreeWalker(document,128),s,e;while(w.nextNode()){var d=w.currentNode.data;if(d==="${o(e)}")s=w.currentNode;if(d==="${r(e)}"){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);p.removeChild(s);p.removeChild(e);t.remove();document.currentScript.remove();})();<\/script>`}function z(e,t,n){return g.unwrap(u.gen(function*(){let i=++t.idCounter.current;yield*m.update(t.pendingCount,e=>e+1);let a=e.children===void 0?null:(Array.isArray(e.children),e.children),s=u.gen(function*(){let e=yield*g.mkString(n(a));yield*p.offer(t.patchQueue,R(i,e))}).pipe(u.ensuring(m.updateAndGet(t.pendingCount,e=>e-1).pipe(u.flatMap(e=>e<=0?p.shutdown(t.patchQueue):u.void))),u.ignore);yield*u.forkIn(s,t.scope);let c=`<!--${o(i)}-->`,l=`<!--${r(i)}-->`,d=e.fallback??null;return g.make(c).pipe(g.concat(n(d)),g.concat(g.make(l)))}))}function B(e,t,n){let r=e.children.length===0?null:e.children.length===1?e.children[0]:e.children;return g.unwrapScoped(u.gen(function*(){let a=yield*g.mkString(n(r)).pipe(u.catchAllCause(r=>u.gen(function*(){let a=e.match(r);if(a===null)return yield*u.failCause(r);let o=yield*g.mkString(n(a));if(t===null)return o;let c=yield*m.getAndSet(t,f.none());return f.isNone(c)?o:`<script type="application/json" ${s}>${M({index:i(e.children).indexOf(c.value.owner),error:c.value.encoded})}<\/script>`+o})));return g.make(a)}))}function V(e,t,n){if(t===null)return u.failCause(n);let r=l.failureOption(n);return f.isNone(r)?u.failCause(n):h.encode(e.errorSchema)(r.value).pipe(u.flatMap(n=>m.set(t,f.some({owner:e,encoded:n}))),u.matchCauseEffect({onFailure:()=>u.failCause(n),onSuccess:()=>u.failCause(n)}))}function H(e){return{value:_.make({get:u.succeed(e),changes:g.make(e)}),refetch:u.void,pending:_.make({get:u.succeed(!1),changes:g.make(!1)}),error:_.make({get:u.succeed(f.none()),changes:g.make(f.none())})}}function U(e,t,n,r){return g.unwrap(u.gen(function*(){let i=yield*(yield*v).call(e.tag,e.payload()).pipe(u.catchAllCause(t=>V(e,n,t))),a=r(e.render(H(i)));if(!t)return a;let o=`<script type="application/json">${M(yield*h.encode(e.successSchema)(i))}<\/script>`;return g.make(o).pipe(g.concat(a))}))}function W(e){return u.scoped(w.toSubscribable(e).pipe(u.flatMap(e=>e.get),u.map(e=>Array.from(e)),u.catchTag(`NoPropValue`,()=>u.succeed([]))))}function G(t,n){if(t==null||typeof t==`boolean`)return g.empty;if(typeof t==`string`||typeof t==`number`||typeof t==`bigint`)return g.make(j(String(t)));if(E(t)||u.isEffect(t)){let e=T(t);if(e!==void 0)return G(e,n);if(u.isEffect(t)){let e=u.runSyncExit(t);if(d.isSuccess(e))return G(e.value,n)}return D(t).pipe(g.runHead,u.map(f.match({onNone:()=>g.empty,onSome:e=>G(e,n)})),g.unwrap)}if(typeof t==`object`&&Symbol.iterator in t&&!(`type`in t))return g.flatMap(g.fromIterable(t),e=>G(e,n));if(typeof t==`object`&&`type`in t&&!(Symbol.iterator in t)){let{type:e,props:r}=t;if(e===b)return q(r,n);if(e===C){let e=r;return n===null?G(e.fallback??null,null):z(e,n,e=>G(e,n))}if(e===y)return B(r,null,e=>G(e,n));if(e===S)return U(r,!1,null,e=>G(e,n));if(e===x)return K(r,n);if(typeof e==`string`){let t=g.fromEffect(P(r).pipe(u.map(t=>`<${e}${t}>`)));return k.has(e)?t:t.pipe(g.concat(q(r,n)),g.concat(g.make(`</${e}>`)))}if(typeof e==`function`)return G(e(r),n)}return g.fail(new e({type:t.type,message:`Invalid Renderable type: expected string, FRAGMENT, or function, got ${typeof t.type}`}))}function K(e,t){return g.unwrap(u.gen(function*(){let n=yield*W(e.of),r=g.empty;return n.forEach((n,i)=>{r=r.pipe(g.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 g.empty;let r=Array.isArray(n)?n:[n];return g.flatMap(g.fromIterable(r),e=>G(e,t))}function J(t,r,i){if(t==null||typeof t==`boolean`)return g.empty;if(typeof t==`string`||typeof t==`number`||typeof t==`bigint`)return g.make(j(String(t)));if(E(t)||u.isEffect(t)){let e=T(t);if(e!==void 0)return J(e,r,i);if(u.isEffect(t)){let e=u.runSyncExit(t);if(d.isSuccess(e))return J(e.value,r,i)}return D(t).pipe(g.runHead,u.map(e=>{let t=++r.current,a=f.match(e,{onNone:()=>g.empty,onSome:e=>J(e,r,i)});return g.make(`<!--${n(t)}-->`).pipe(g.concat(a),g.concat(g.make(`<!--${c(t)}-->`)))}),g.unwrap)}if(typeof t==`object`&&Symbol.iterator in t&&!(`type`in t))return g.flatMap(g.fromIterable(t),e=>J(e,r,i));if(typeof t==`object`&&`type`in t&&!(Symbol.iterator in t)){let{type:e,props:n}=t;if(e===b)return X(n,r,i);if(e===C){let e=n;return i===null?J(e.fallback??null,r,null):z(e,i,e=>J(e,r,i))}if(e===y)return B(n,i?.failureCollector??null,e=>J(e,r,i));if(e===S)return U(n,!0,i?.failureCollector??null,e=>J(e,r,i));if(e===x)return Y(n,r,i);if(typeof e==`string`){let t=g.fromEffect(P(n).pipe(u.map(t=>`<${e}${t}>`)));return k.has(e)?t:t.pipe(g.concat(X(n,r,i)),g.concat(g.make(`</${e}>`)))}if(typeof e==`function`)return J(e(n),r,i)}return g.fail(new e({type:t.type,message:`Invalid Renderable type: expected string, FRAGMENT, or function, got ${typeof t.type}`}))}function Y(e,r,i){return g.unwrap(u.gen(function*(){let o=++r.current,s=yield*W(e.of),l=g.empty;return s.forEach((n,o)=>{let s=++r.current;l=l.pipe(g.concat(g.make(`<!--${a(s)}-->`)),g.concat(J(e.render(n,o),r,i)),g.concat(g.make(`<!--${t(s)}-->`)))}),g.make(`<!--${n(o)}-->`).pipe(g.concat(l),g.concat(g.make(`<!--${c(o)}-->`)))}))}function X(e,t,n){let r=`children`in e?e.children:void 0;if(r==null)return g.empty;let i=Array.isArray(r)?r:[r];return g.flatMap(g.fromIterable(i),e=>J(e,t,n))}const Z=e=>G(e,null),Q=e=>g.unwrapScoped(u.gen(function*(){let t=yield*p.unbounded(),n=yield*m.make(0),r=G(e,{patchQueue:t,pendingCount:n,idCounter:{current:0},scope:yield*u.scope,failureCollector:null}).pipe(g.ensuring(m.get(n).pipe(u.flatMap(e=>e===0?p.shutdown(t):u.void))));return g.concat(r,g.fromQueue(t))})),$=e=>g.unwrapScoped(u.gen(function*(){let t=yield*p.unbounded(),n=yield*m.make(0),r=J(e,{current:0},{patchQueue:t,pendingCount:n,idCounter:{current:0},scope:yield*u.scope,failureCollector:yield*m.make(f.none())}).pipe(g.ensuring(m.get(n).pipe(u.flatMap(e=>e===0?p.shutdown(t):u.void))));return g.concat(r,g.fromQueue(t))})),te=e=>Z(e).pipe(g.mkString),ne=e=>$(e).pipe(g.mkString);export{Q as renderToStream,$ as renderToStreamHydratable,te as renderToString,ne as renderToStringHydratable};
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@weftui/dom",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Client-side DOM renderer for Weft",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Stef van Wijchen",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"type": "module",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./client": {
|
|
17
|
+
"types": "./dist/client/index.d.ts",
|
|
18
|
+
"import": "./dist/client/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./server": {
|
|
21
|
+
"types": "./dist/server/index.d.ts",
|
|
22
|
+
"import": "./dist/server/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@weftui/core": "0.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@effect/rpc": "^0.75.1",
|
|
33
|
+
"@types/jsdom": "^28.0.3",
|
|
34
|
+
"@types/node": "^25.9.1",
|
|
35
|
+
"effect": "^3.21.2",
|
|
36
|
+
"jsdom": "^29.1.1",
|
|
37
|
+
"tsx": "^4.22.3",
|
|
38
|
+
"typescript": "^6.0.3",
|
|
39
|
+
"vite-plus": "latest"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"effect": "^3.21"
|
|
43
|
+
}
|
|
44
|
+
}
|