@vanijs/vani 0.4.0 → 0.5.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/DOCS.md CHANGED
@@ -226,6 +226,8 @@ export function MyReactComponent() {
226
226
  - Optional fine-grained state with `signal()`, `derive()`, `effect()`, plus `text()`/`attr()`
227
227
  helpers
228
228
  - Async components with fallbacks
229
+ - `onMount(getNodes, parent)` gives access to the rendered DOM subtree without ref plumbing,
230
+ aligning with explicit updates and simplifying vanilla JS integrations
229
231
  - `className` accepts string, array, and object forms for ergonomic composition
230
232
  - ESM-first and designed to run in any modern environment
231
233
 
@@ -386,6 +388,237 @@ Each component owns a DOM range delimited by anchors:
386
388
 
387
389
  Updates replace only the DOM between anchors.
388
390
 
391
+ ### 3.1) Nested component hierarchies (isolated subtrees)
392
+
393
+ To build a nested tree, have a parent return child component instances as part of its render output.
394
+ Each component instance creates its own anchor range, so parent and child updates stay isolated.
395
+
396
+ #### How DOM isolation works
397
+
398
+ When you nest components, each component gets its own pair of `<!--vani:start-->` and
399
+ `<!--vani:end-->` comment anchors. The DOM structure for a parent containing a child looks like:
400
+
401
+ ```html
402
+ <!--vani:start-->
403
+ <!-- Parent start -->
404
+ <div>
405
+ <div>Parent title</div>
406
+ <button>Rename parent</button>
407
+ <!--vani:start-->
408
+ <!-- Child start -->
409
+ <div>
410
+ Child clicks: 0
411
+ <button>Click child</button>
412
+ </div>
413
+ <!--vani:end-->
414
+ <!-- Child end -->
415
+ </div>
416
+ <!--vani:end-->
417
+ <!-- Parent end -->
418
+ ```
419
+
420
+ When the parent updates, Vani replaces the DOM between the parent's anchors **but preserves the
421
+ child's anchors and their contents**. When the child updates, only the DOM between the child's
422
+ anchors is replaced. This anchor-based isolation is automatic—no special API is needed.
423
+
424
+ #### Update isolation rules
425
+
426
+ - **Parent update**: replaces parent’s subtree but leaves nested child anchor ranges intact.
427
+ - **Child update**: replaces only the child’s subtree; parent is unaffected.
428
+ - **Re-render with new props**: if the parent re-renders and returns the same child component with
429
+ new props, the child’s component instance is preserved (not recreated) and the child can read the
430
+ new props on its next `update()`.
431
+
432
+ #### Basic parent-child example
433
+
434
+ ```ts
435
+ import { component, div, button, type Handle, type ComponentRef } from '@vanijs/vani'
436
+
437
+ const Child = component<{ label: string }>((props, handle: Handle) => {
438
+ let clicks = 0
439
+ return () =>
440
+ div(
441
+ `${props.label} clicks: ${clicks}`,
442
+ button(
443
+ {
444
+ onclick: () => {
445
+ clicks += 1
446
+ handle.update()
447
+ },
448
+ },
449
+ 'Click child',
450
+ ),
451
+ )
452
+ })
453
+
454
+ const Parent = component((_, handle: Handle) => {
455
+ let title = 'Parent'
456
+ const childRef: ComponentRef = { current: null }
457
+
458
+ const rename = () => {
459
+ title = title === 'Parent' ? 'Parent (renamed)' : 'Parent'
460
+ handle.update()
461
+ }
462
+
463
+ return () =>
464
+ div(
465
+ div(`Title: ${title}`),
466
+ button({ onclick: rename }, 'Rename parent'),
467
+ // Nested component subtree (isolated updates)
468
+ Child({ ref: childRef, label: 'Child' }),
469
+ )
470
+ })
471
+ ```
472
+
473
+ When you click "Rename parent", only the parent subtree updates. When you click "Click child", only
474
+ the child subtree updates.
475
+
476
+ #### Deeper nesting (grandparent → parent → child)
477
+
478
+ You can nest components to any depth. Each level maintains its own isolated subtree:
479
+
480
+ ```ts
481
+ import { component, div, button, type Handle } from '@vanijs/vani'
482
+
483
+ const GrandChild = component<{ name: string }>((props, handle: Handle) => {
484
+ let value = 0
485
+ return () =>
486
+ div(
487
+ `GrandChild (${props.name}): ${value}`,
488
+ button(
489
+ {
490
+ onclick: () => {
491
+ value += 1
492
+ handle.update()
493
+ },
494
+ },
495
+ '+',
496
+ ),
497
+ )
498
+ })
499
+
500
+ const Child = component<{ id: number }>((props, handle: Handle) => {
501
+ let label = `Child #${props.id}`
502
+ return () =>
503
+ div(
504
+ div(label),
505
+ button(
506
+ {
507
+ onclick: () => {
508
+ label += '!'
509
+ handle.update()
510
+ },
511
+ },
512
+ 'Edit label',
513
+ ),
514
+ GrandChild({ name: `gc-${props.id}` }),
515
+ )
516
+ })
517
+
518
+ const Parent = component((_, handle: Handle) => {
519
+ let count = 2
520
+ return () =>
521
+ div(
522
+ div(`Parent has ${count} children`),
523
+ button(
524
+ {
525
+ onclick: () => {
526
+ count += 1
527
+ handle.update()
528
+ },
529
+ },
530
+ 'Add child',
531
+ ),
532
+ ...Array.from({ length: count }, (_, i) => Child({ id: i })),
533
+ )
534
+ })
535
+ ```
536
+
537
+ Each `GrandChild` can update independently of its `Child`, and each `Child` can update independently
538
+ of the `Parent`. The anchor isolation means you can have deeply nested trees without cascading
539
+ re-renders.
540
+
541
+ #### Passing props and callbacks (prop drilling)
542
+
543
+ Props flow down explicitly. If a child needs data from an ancestor, pass it through props:
544
+
545
+ ```ts
546
+ import { component, div, button, type Handle } from '@vanijs/vani'
547
+
548
+ const Display = component<{ value: number }>((props) => {
549
+ return () => div(`Current value: ${props.value}`)
550
+ })
551
+
552
+ const Controls = component<{ onIncrement: () => void }>((props) => {
553
+ return () => button({ onclick: props.onIncrement }, 'Increment')
554
+ })
555
+
556
+ const App = component((_, handle: Handle) => {
557
+ let count = 0
558
+ const increment = () => {
559
+ count += 1
560
+ handle.update()
561
+ }
562
+ return () => div(Display({ value: count }), Controls({ onIncrement: increment }))
563
+ })
564
+ ```
565
+
566
+ When `increment` is called, the `App` re-renders. Because `Display` and `Controls` are nested
567
+ components with their own anchor ranges, their internal state (if any) is preserved. The new `value`
568
+ prop is available to `Display` on the next render.
569
+
570
+ #### Updating children from the parent via refs
571
+
572
+ If you need to trigger a child update without re-rendering the parent, store a `ComponentRef` and
573
+ call `update()` on it directly:
574
+
575
+ ```ts
576
+ import { component, div, button, type Handle, type ComponentRef } from '@vanijs/vani'
577
+
578
+ const Counter = component<{ start: number }>((props, handle: Handle) => {
579
+ let count = props.start
580
+ return () =>
581
+ div(
582
+ `Count: ${count}`,
583
+ button(
584
+ {
585
+ onclick: () => {
586
+ count += 1
587
+ handle.update()
588
+ },
589
+ },
590
+ '+',
591
+ ),
592
+ )
593
+ })
594
+
595
+ const Dashboard = component(() => {
596
+ const counterRef: ComponentRef = { current: null }
597
+
598
+ const resetCounter = () => {
599
+ // Update only the Counter subtree, not the Dashboard
600
+ counterRef.current?.update()
601
+ }
602
+
603
+ return () =>
604
+ div(
605
+ Counter({ ref: counterRef, start: 0 }),
606
+ button({ onclick: resetCounter }, 'Refresh counter'),
607
+ )
608
+ })
609
+ ```
610
+
611
+ Clicking "Refresh counter" calls `counterRef.current?.update()`, which re-renders only the `Counter`
612
+ subtree. The `Dashboard` itself does not re-render.
613
+
614
+ #### Summary
615
+
616
+ - Nesting is standard component composition—no special API.
617
+ - Each component instance owns an anchor-delimited DOM range.
618
+ - Updates are isolated: a component’s `handle.update()` only affects its own subtree.
619
+ - Props and callbacks flow down explicitly (prop drilling).
620
+ - Use `ComponentRef` to update children without re-rendering parents.
621
+
389
622
  ### 4) Lists and item-level updates
390
623
 
391
624
  Lists scale well in Vani when each item is its own component. Every item owns a tiny subtree and can
@@ -496,7 +729,7 @@ const List = component((_, handle: Handle) => {
496
729
  ),
497
730
  )
498
731
  }
499
- handle.effect(() => {
732
+ handle.onBeforeMount(() => {
500
733
  queueMicrotask(renderRows)
501
734
  })
502
735
 
@@ -855,7 +1088,7 @@ import { component, div, button, type Handle } from '@vanijs/vani'
855
1088
  import { getState, setState, subscribe } from './store'
856
1089
 
857
1090
  const Counter = component((_, handle: Handle) => {
858
- handle.effect(() => subscribe(() => handle.update()))
1091
+ handle.onBeforeMount(() => subscribe(() => handle.update()))
859
1092
 
860
1093
  return () => {
861
1094
  const { count } = getState()
@@ -939,7 +1172,7 @@ by never mutating another module's state directly; instead call exported command
939
1172
  scale, manual invalidation challenges include fan-out, over- or under-invalidating, update
940
1173
  ordering/races, stale reads during transitions, lifecycle leaks, and lack of observability. Mitigate
941
1174
  with explicit contracts, centralized command surfaces, predictable ordering, cleanup via
942
- `handle.effect()`, and lightweight logging around invalidation helpers.
1175
+ `handle.onBeforeMount()`, and lightweight logging around invalidation helpers.
943
1176
 
944
1177
  Architecture sketch:
945
1178
 
@@ -967,8 +1200,8 @@ Each module owns its state and exposes a small API:
967
1200
 
968
1201
  2. View adapters (bind handles)
969
1202
 
970
- Views subscribe once via `handle.effect()` and call `handle.update()` when their module notifies.
971
- This keeps invalidation scoped to the subtree that owns the handle.
1203
+ Views subscribe once via `handle.onBeforeMount()` and call `handle.update()` when their module
1204
+ notifies. This keeps invalidation scoped to the subtree that owns the handle.
972
1205
 
973
1206
  3. Coordinator or message hub
974
1207
 
@@ -1037,7 +1270,7 @@ export const createUsersFeature = (): { api: UsersFeatureApi; View: Component }
1037
1270
  }
1038
1271
 
1039
1272
  const View = component((_, handle: Handle) => {
1040
- handle.effect(() => api.subscribe(() => handle.update()))
1273
+ handle.onBeforeMount(() => api.subscribe(() => handle.update()))
1041
1274
  return () => div(api.getUsers().map((user) => div(user.name)))
1042
1275
  })
1043
1276
 
@@ -1109,7 +1342,7 @@ export const invalidateUserRow = (id: string) => {
1109
1342
  }
1110
1343
 
1111
1344
  export const UserRow = component<{ id: string; name: string }>((props, handle) => {
1112
- handle.effect(() => bindUserRow(props.id, handle))
1345
+ handle.onBeforeMount(() => bindUserRow(props.id, handle))
1113
1346
  return () => div(props.name)
1114
1347
  })
1115
1348
  ```
@@ -1158,7 +1391,7 @@ export const queueUpdate = (handle: Handle) => {
1158
1391
  - Stale reads during transitions: if you defer with `startTransition()`, ensure that the render
1159
1392
  reads the latest snapshot or that the transition captures the intended version.
1160
1393
  - Lifecycle leaks: if a handle isn't unsubscribed, updates keep firing. Always return cleanup from
1161
- `subscribe()` and bind it through `handle.effect()`.
1394
+ `subscribe()` and bind it through `handle.onBeforeMount()`.
1162
1395
  - Observability gaps: without implicit reactivity, you need traceability. Wrap invalidation helpers
1163
1396
  to log or count updates per module and catch runaway loops early.
1164
1397
 
@@ -1178,7 +1411,7 @@ Creates a component factory. The `fn` receives `props` and a `handle`.
1178
1411
  import { component, div, type Handle } from '@vanijs/vani'
1179
1412
 
1180
1413
  const Card = component<{ title: string }>((props, handle: Handle) => {
1181
- handle.effect(() => {
1414
+ handle.onBeforeMount(() => {
1182
1415
  console.log('Mounted:', props.title)
1183
1416
  })
1184
1417
 
@@ -1189,11 +1422,10 @@ const Card = component<{ title: string }>((props, handle: Handle) => {
1189
1422
  Components can return other component instances directly:
1190
1423
 
1191
1424
  ```ts
1192
- import { component } from '@vanijs/vani'
1193
- import * as h from '@vanijs/vani'
1425
+ import { component, h1 } from '@vanijs/vani'
1194
1426
 
1195
1427
  const Hero = component(() => {
1196
- return () => h.h1('Hello')
1428
+ return () => h1('Hello')
1197
1429
  })
1198
1430
 
1199
1431
  const Page = component(() => {
@@ -1227,6 +1459,9 @@ const handles = hydrateToDOM(App(), root)
1227
1459
  handles.forEach((handle) => handle.update())
1228
1460
  ```
1229
1461
 
1462
+ If hydration fails due to missing anchors or mismatched structure, Vani raises a `HydrationError`
1463
+ and `hydrateToDOM()` logs it. Other errors are rethrown so they surface immediately.
1464
+
1230
1465
  ### `renderToString(components)`
1231
1466
 
1232
1467
  Server‑side render to HTML with anchors. Accepts a single component or an array of components.
@@ -1275,7 +1510,8 @@ div(span('Label'), input({ type: 'text' }), button({ onclick: () => {} }, 'Submi
1275
1510
  ### SVG icons (Lucide)
1276
1511
 
1277
1512
  Use the Vite SVG plugin at `src/ecosystem/vite-plugin-vani-svg.ts` and import SVGs with `?vani`.
1278
- This keeps the bundle small by only including the icons you actually import.
1513
+ This keeps the bundle small by only including the icons you actually import. Invalid SVG strings
1514
+ throw an error so failures stay obvious.
1279
1515
 
1280
1516
  In your `vite.config.ts`:
1281
1517
 
@@ -1336,21 +1572,22 @@ const Parent = component(() => {
1336
1572
  })
1337
1573
  ```
1338
1574
 
1339
- ### Cleanup and effects
1575
+ ### Cleanup and lifecycle
1340
1576
 
1341
- Effects are explicit and can return a cleanup function.
1577
+ The `onBeforeMount` hook runs once during component setup (before the first render) and can return a
1578
+ cleanup function.
1342
1579
 
1343
- If you plan to use vani for a SSR/SSG application, you should use effects to run client-only code
1344
- such as accessing the window object, accessing the DOM, etc.
1580
+ If you plan to use vani for a SSR/SSG application, you should use `onBeforeMount` to run client-only
1581
+ code such as accessing the window object, accessing the DOM, etc.
1345
1582
 
1346
- Effects are very simple and run once during component setup (the component function run). They do
1347
- not re-run on every `handle.update()`; updates only call the render function.
1583
+ The `onBeforeMount` hook is very simple and runs once during component setup (the component function
1584
+ run). It does not re-run on every `handle.update()`; updates only call the render function.
1348
1585
 
1349
1586
  ```ts
1350
1587
  import { component, div } from '@vanijs/vani'
1351
1588
 
1352
1589
  const Timer = component((_, handle) => {
1353
- handle.effect(() => {
1590
+ handle.onBeforeMount(() => {
1354
1591
  const id = setInterval(() => console.log('tick'), 1000)
1355
1592
  return () => clearInterval(id)
1356
1593
  })
@@ -1358,6 +1595,48 @@ const Timer = component((_, handle) => {
1358
1595
  })
1359
1596
  ```
1360
1597
 
1598
+ The `onMount` hook runs after the first render, once the component's nodes are in the DOM. It
1599
+ receives a lazy `getNodes()` function and the parent mount point.
1600
+
1601
+ Benefits:
1602
+
1603
+ - No need to set up refs ahead of time just to access nodes after render.
1604
+ - Easy to initialize external, vanilla JS libraries with all rendered nodes in one place.
1605
+ - `getNodes()` is lazy, so you only pay for DOM traversal if you actually need it.
1606
+
1607
+ ```ts
1608
+ import { component, div } from '@vanijs/vani'
1609
+
1610
+ const Measure = component((_, handle) => {
1611
+ handle.onMount((getNodes, parent) => {
1612
+ const nodes = getNodes()
1613
+ const firstElement = nodes.find((node) => node instanceof HTMLElement)
1614
+ if (!firstElement) return
1615
+
1616
+ const rect = (firstElement as HTMLElement).getBoundingClientRect()
1617
+ console.log('Mounted in', parent, 'size', rect.width, rect.height)
1618
+ })
1619
+
1620
+ return () => div('Measured')
1621
+ })
1622
+ ```
1623
+
1624
+ You can also register cleanup functions directly with `handle.onCleanup()`:
1625
+
1626
+ ```ts
1627
+ import { component, div } from '@vanijs/vani'
1628
+
1629
+ const Subscription = component((_, handle) => {
1630
+ const unsubscribe = someStore.subscribe(() => handle.update())
1631
+ handle.onCleanup(unsubscribe)
1632
+
1633
+ return () => div('Subscribed')
1634
+ })
1635
+ ```
1636
+
1637
+ Both patterns are equivalent. Use `handle.onBeforeMount()` when the setup and cleanup are logically
1638
+ grouped, and `handle.onCleanup()` when you need to register cleanup separately from initialization.
1639
+
1361
1640
  ### Signals and DOM bindings (optional)
1362
1641
 
1363
1642
  Signals are opt-in fine-grained state. They update only the DOM nodes bound to them.
@@ -1379,7 +1658,7 @@ const Counter = component(() => {
1379
1658
  - `derive(fn)` returns a computed getter.
1380
1659
  - `effect(fn)` re-runs when signals used inside `fn` change.
1381
1660
  - `text(getter)` binds a text node to a signal.
1382
- - `attr(el, name, getter)` binds an attribute/class to a signal.
1661
+ - `attr(el, name, value)` binds an attribute/class to a signal getter or static value.
1383
1662
 
1384
1663
  ### Partial attribute updates
1385
1664
 
package/README.md CHANGED
@@ -11,6 +11,7 @@ updates and opt-in fine-grained state.
11
11
  - Subtree ownership via anchors
12
12
  - Runtime-first, no compiler
13
13
  - Opt-in signals for fine-grained updates
14
+ - Ref-based and Ref-free DOM subtree access on mount.
14
15
 
15
16
  ## Installation
16
17
 
@@ -1,4 +1,4 @@
1
- import { A as renderToDOM, C as fragment, D as isDevMode, E as isComponentInstance, F as SignalGetter, I as SignalSetter, L as attr, M as startTransition, N as withRenderMode, O as mount, P as Signal, R as text, S as el, T as hydrateToDOM, _ as batch, a as ComponentRef, b as derive, c as ElementProps, d as RenderFn, f as SSRNode, g as VNode, h as VChild, i as ComponentInstance, j as signal, k as renderKeyedChildren, l as Handle, m as UpdateOptions, n as Component, o as DataAttribute, p as SvgProps, r as ComponentInput, s as DomRef, t as ClassName, u as HtmlProps, v as classNames, w as getRenderMode, x as effect, y as component } from "./runtime-Cx9SKHrc.mjs";
1
+ import { A as isComponentInstance, B as RenderMode, C as batch, D as el, E as createRoot, F as renderToDOM, G as setRenderMode, H as configureSignalDom, I as startTransition, L as withRenderMode, M as mount, N as reactive, O as fragment, P as renderKeyedChildren, R as AttrValue, S as VNode, T as component, U as getRenderMode, V as TextNode, W as getSignalDomAdapter, _ as Root, b as UpdateOptions, c as ComponentInstance, d as DomRef, f as ElementProps, g as RenderFn, h as HydrationError, j as isDevMode, k as hydrateToDOM, l as ComponentRef, m as HtmlProps, o as Component, p as Handle, s as ComponentInput, t as Fragment, u as DataAttribute, v as SSRNode, w as classNames, x as VChild, y as SvgProps, z as ClassName } from "./jsx-runtime-BK1MMitM.mjs";
2
2
 
3
3
  //#region src/vani/html.d.ts
4
4
  declare const div: (propsOrChild?: VChild | HtmlProps<"div">, ...children: VChild[]) => VNode;
@@ -110,4 +110,5 @@ type SvgRenderOptions = {
110
110
  };
111
111
  declare const renderSvgString: (svg: string, options?: SvgRenderOptions) => VNode;
112
112
  //#endregion
113
- export { ClassName, Component, ComponentInput, ComponentInstance, ComponentRef, DataAttribute, DomRef, ElementProps, Handle, HtmlProps, RenderFn, SSRNode, Signal, SignalGetter, SignalSetter, SvgProps, SvgRenderOptions, UpdateOptions, VChild, VNode, a, abbr, article, aside, attr, audio, batch, blockquote, br, button, caption, circle, cite, classNames, clipPath, code, col, colgroup, component, datalist, dd, defs, derive, details, dfn, div, dl, dt, effect, el, ellipse, em, embed, fieldset, figcaption, figure, footer, form, fragment, g, getRenderMode, h1, h2, h3, h4, h5, h6, header, hr, hydrateToDOM, iframe, img, input, isComponentInstance, isDevMode, kbd, label, legend, li, line, linearGradient, main, mark, mask, meter, mount, nav, noscript, ol, optgroup, option, output, p, path, pattern, picture, polygon, polyline, pre, progress, radialGradient, rect, renderKeyedChildren, renderSvgString, renderToDOM, renderToString, samp, script, section, select, signal, slot, small, source, span, startTransition, stop, strong, style, summary, svg, table, tbody, td, template, text, textarea, tfoot, th, thead, time, tr, ul, use, var_, video, withRenderMode };
113
+ export { AttrValue, ClassName, Component, ComponentInput, ComponentInstance, ComponentRef, DataAttribute, DomRef, ElementProps, Fragment, Handle, HtmlProps, HydrationError, RenderFn, RenderMode, Root, SSRNode, SvgProps, SvgRenderOptions, TextNode, UpdateOptions, VChild, VNode, a, abbr, article, aside, audio, batch, blockquote, br, button, caption, circle, cite, classNames, clipPath, code, col, colgroup, component, configureSignalDom, createRoot, datalist, dd, defs, details, dfn, div, dl, dt, el, ellipse, em, embed, fieldset, figcaption, figure, footer, form, fragment, g, getRenderMode, getSignalDomAdapter, h1, h2, h3, h4, h5, h6, header, hr, hydrateToDOM, iframe, img, input, isComponentInstance, isDevMode, kbd, label, legend, li, line, linearGradient, main, mark, mask, meter, mount, nav, noscript, ol, optgroup, option, output, p, path, pattern, picture, polygon, polyline, pre, progress, radialGradient, reactive, rect, renderKeyedChildren, renderSvgString, renderToDOM, renderToString, samp, script, section, select, setRenderMode, slot, small, source, span, startTransition, stop, strong, style, summary, svg, table, tbody, td, template, textarea, tfoot, th, thead, time, tr, ul, use, var_, video, withRenderMode };
114
+ //# sourceMappingURL=index.d.mts.map
@@ -1 +1,2 @@
1
- import{_ as e,a as t,c as n,d as r,f as i,g as a,h as o,i as s,l as c,m as ee,n as te,o as l,p as ne,r as re,s as ie,t as ae,u,v as oe,y as se}from"./runtime-X8xzmXJz.mjs";function d(e){return(t,...n)=>l(e,t,...n)}const f=d(`div`),p=d(`span`),m=d(`ul`),h=d(`li`),g=d(`ol`),_=d(`dl`),v=d(`dt`),y=d(`dd`),b=d(`main`),x=d(`header`),S=d(`footer`),C=d(`section`),w=d(`article`),T=d(`aside`),E=d(`nav`),D=d(`details`),O=d(`summary`),k=d(`a`),A=d(`button`),j=d(`input`),M=d(`output`),N=d(`textarea`),P=d(`select`),F=d(`option`),I=d(`optgroup`),L=d(`label`),R=d(`form`),z=d(`progress`),B=d(`meter`),V=d(`fieldset`),H=d(`legend`),U=d(`datalist`),W=d(`figure`),G=d(`figcaption`),K=d(`img`),ce=d(`picture`),le=d(`source`),ue=d(`video`),de=d(`audio`),fe=d(`iframe`),pe=d(`embed`),me=d(`time`),he=d(`mark`),ge=d(`p`),_e=d(`h1`),ve=d(`h2`),ye=d(`h3`),be=d(`h4`),xe=d(`h5`),Se=d(`h6`),Ce=d(`code`),we=d(`pre`),Te=d(`blockquote`),Ee=d(`var`),De=d(`kbd`),Oe=d(`samp`),ke=d(`cite`),q=d(`dfn`),Ae=d(`abbr`),je=d(`small`),Me=d(`strong`),Ne=d(`em`),Pe=d(`br`),Fe=d(`hr`),Ie=d(`table`),Le=d(`caption`),Re=d(`colgroup`),ze=d(`col`),Be=d(`tbody`),Ve=d(`thead`),He=d(`tfoot`),Ue=d(`tr`),We=d(`td`),Ge=d(`th`),Ke=d(`style`),qe=d(`script`),Je=d(`noscript`),Ye=d(`template`),Xe=d(`slot`),Ze=d(`svg`),Qe=d(`g`),$e=d(`path`),et=d(`circle`),tt=d(`rect`),nt=d(`line`),rt=d(`polyline`),it=d(`polygon`),at=d(`ellipse`),ot=d(`defs`),st=d(`clipPath`),ct=d(`mask`),lt=d(`pattern`),ut=d(`linearGradient`),dt=d(`radialGradient`),ft=d(`stop`),pt=d(`use`);function mt(e){return Array.isArray(e)?e:[e]}const ht=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]);function gt(){return{update(){},updateSync(){},dispose(){},onCleanup(){},effect(){}}}function _t(e){return typeof e==`function`?{$$vani:`component`,component:e,props:{}}:e}function J(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`).replaceAll(`'`,`&#39;`)}function vt(e){let t=[];for(let n of Object.keys(e)){let r=e[n];r==null||r===!1||n.startsWith(`on`)&&typeof r==`function`||(r===!0?t.push(n):t.push(`${n}="${J(String(r))}"`))}return t.length>0?` ${t.join(` `)}`:``}function Y(e){if(e==null||e===!1)return{type:`fragment`,children:[]};if(typeof e==`string`||typeof e==`number`)return{type:`text`,text:String(e)};if(u(e))return{type:`component`,instance:e};if(typeof e==`object`&&`type`in e)return e;throw Error(`[vani] SSR received a DOM node. This is not supported.`)}async function yt(e){let t=`<!--vani:start-->`,n=`<!--vani:end-->`;if(e.clientOnly){let r=e.props?.fallback;return r?`${t}${await X(Y(r()))}${n}`:`${t}${n}`}let r=e.component(e.props,gt());return`${t}${await X(Y((r instanceof Promise?await r:r)()))}${n}`}async function X(e){switch(e.type){case`text`:return J(e.text);case`comment`:return`<!--${e.text}-->`;case`fragment`:return(await Promise.all(e.children.map(X))).join(``);case`component`:return yt(e.instance);case`element`:{let t=vt(e.props);if(ht.has(e.tag))return`<${e.tag}${t}>`;let n=(await Promise.all(e.children.map(X))).join(``);return`<${e.tag}${t}>${n}</${e.tag}>`}}}async function bt(t){return e(`ssr`,async()=>{if(n()!==`ssr`)throw Error(`[vani] renderToString failed to set SSR render mode.`);let e=mt(t).map(e=>({type:`component`,instance:_t(e)}));return(await Promise.all(e.map(X))).join(``)})}const Z=new Map,Q=(e,t)=>{if(!t)return e;let n=`${e??``} ${t}`.trim();return n.length>0?n:void 0},xt=(e,t)=>{if(!t)return;let n=t.size;if(n!=null&&(e.setAttribute(`width`,String(n)),e.setAttribute(`height`,String(n))),t.className){let n=Q(e.getAttribute(`class`)??void 0,t.className);n&&e.setAttribute(`class`,n)}if(t.attributes){for(let[n,r]of Object.entries(t.attributes))if(!(r==null||r===!1)){if(r===!0){e.setAttribute(n,``);continue}e.setAttribute(n,String(r))}}},St=e=>{let t={},n=/([^\s=]+)(?:=(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g,r;for(;r=n.exec(e);){let e=r[1],n=r[2]??r[3]??r[4];t[e]=n===void 0?!0:n}return t},Ct=e=>{let t=e.replaceAll(/<!--[\s\S]*?-->/g,``).trim(),n=/<\/?[^>]+>/g,r=[],i=null,a=0,o,s=e=>{let t=r.at(-1);t&&(t.type===`element`||t.type===`fragment`)&&t.children.push(e)};for(;o=n.exec(t);){let e=t.slice(a,o.index);e.trim().length>0&&s({type:`text`,text:e});let c=o[0];if(c.startsWith(`</`))r.pop();else{let e=c.endsWith(`/>`),t=c.slice(1,e?-2:-1).trim(),n=t.search(/\s/),a={type:`element`,tag:n===-1?t:t.slice(0,n),props:St(n===-1?``:t.slice(n+1)),children:[]};i==null?i=a:s(a),e||r.push(a)}a=n.lastIndex}return i??{type:`fragment`,children:[]}},$=e=>e.type===`text`?{type:`text`,text:e.text}:e.type===`comment`?{type:`comment`,text:e.text}:e.type===`fragment`?{type:`fragment`,children:e.children.map($)}:e.type===`component`?{type:`component`,instance:e.instance}:{type:`element`,tag:e.tag,props:{...e.props},children:e.children.map($)},wt=(e,t)=>{if(!t||e.type!==`element`||e.tag!==`svg`)return;let n=e.props;if(t.size!=null&&(n.width=String(t.size),n.height=String(t.size)),t.className){let e=Q(n.class,t.className);e&&(n.class=e)}if(t.attributes){for(let[e,r]of Object.entries(t.attributes))if(!(r==null||r===!1)){if(r===!0){n[e]=!0;continue}n[e]=String(r)}}},Tt=(e,t)=>{if(n()===`ssr`){let n=$(Ct(e));return wt(n,t),n}let r=Z.get(e);r||(r=new DOMParser().parseFromString(e,`image/svg+xml`).documentElement,Z.set(e,r));let i=r.cloneNode(!0);return xt(i,t),i};export{k as a,Ae as abbr,w as article,T as aside,oe as attr,de as audio,ae as batch,Te as blockquote,Pe as br,A as button,Le as caption,et as circle,ke as cite,te as classNames,st as clipPath,Ce as code,ze as col,Re as colgroup,re as component,U as datalist,y as dd,ot as defs,s as derive,D as details,q as dfn,f as div,_ as dl,v as dt,t as effect,l as el,at as ellipse,Ne as em,pe as embed,V as fieldset,G as figcaption,W as figure,S as footer,R as form,ie as fragment,Qe as g,n as getRenderMode,_e as h1,ve as h2,ye as h3,be as h4,xe as h5,Se as h6,x as header,Fe as hr,c as hydrateToDOM,fe as iframe,K as img,j as input,u as isComponentInstance,r as isDevMode,De as kbd,L as label,H as legend,h as li,nt as line,ut as linearGradient,b as main,he as mark,ct as mask,B as meter,i as mount,E as nav,Je as noscript,g as ol,I as optgroup,F as option,M as output,ge as p,$e as path,lt as pattern,ce as picture,it as polygon,rt as polyline,we as pre,z as progress,dt as radialGradient,tt as rect,ne as renderKeyedChildren,Tt as renderSvgString,ee as renderToDOM,bt as renderToString,Oe as samp,qe as script,C as section,P as select,o as signal,Xe as slot,je as small,le as source,p as span,a as startTransition,ft as stop,Me as strong,Ke as style,O as summary,Ze as svg,Ie as table,Be as tbody,We as td,Ye as template,se as text,N as textarea,He as tfoot,Ge as th,Ve as thead,me as time,Ue as tr,m as ul,pt as use,Ee as var_,ue as video,e as withRenderMode};
1
+ import{C as e,S as t,_ as n,a as r,b as i,c as a,d as o,f as s,g as c,h as ee,l as te,m as l,o as ne,p as u,s as re,t as ie,u as d,v as ae,w as oe,x as se,y as f}from"./jsx-runtime-BUSOLzm1.mjs";function p(e){return(t,...n)=>d(e,t,...n)}const m=p(`div`),h=p(`span`),g=p(`ul`),_=p(`li`),v=p(`ol`),y=p(`dl`),b=p(`dt`),x=p(`dd`),S=p(`main`),C=p(`header`),w=p(`footer`),T=p(`section`),E=p(`article`),D=p(`aside`),O=p(`nav`),k=p(`details`),A=p(`summary`),j=p(`a`),M=p(`button`),N=p(`input`),P=p(`output`),F=p(`textarea`),I=p(`select`),L=p(`option`),R=p(`optgroup`),z=p(`label`),B=p(`form`),V=p(`progress`),H=p(`meter`),U=p(`fieldset`),W=p(`legend`),G=p(`datalist`),K=p(`figure`),ce=p(`figcaption`),le=p(`img`),ue=p(`picture`),de=p(`source`),fe=p(`video`),pe=p(`audio`),me=p(`iframe`),he=p(`embed`),ge=p(`time`),_e=p(`mark`),ve=p(`p`),ye=p(`h1`),be=p(`h2`),xe=p(`h3`),Se=p(`h4`),Ce=p(`h5`),we=p(`h6`),Te=p(`code`),Ee=p(`pre`),De=p(`blockquote`),Oe=p(`var`),ke=p(`kbd`),Ae=p(`samp`),je=p(`cite`),Me=p(`dfn`),Ne=p(`abbr`),Pe=p(`small`),Fe=p(`strong`),Ie=p(`em`),Le=p(`br`),Re=p(`hr`),ze=p(`table`),Be=p(`caption`),Ve=p(`colgroup`),He=p(`col`),Ue=p(`tbody`),We=p(`thead`),Ge=p(`tfoot`),Ke=p(`tr`),qe=p(`td`),Je=p(`th`),Ye=p(`style`),Xe=p(`script`),Ze=p(`noscript`),Qe=p(`template`),$e=p(`slot`),et=p(`svg`),tt=p(`g`),nt=p(`path`),rt=p(`circle`),it=p(`rect`),at=p(`line`),ot=p(`polyline`),st=p(`polygon`),ct=p(`ellipse`),lt=p(`defs`),ut=p(`clipPath`),dt=p(`mask`),ft=p(`pattern`),pt=p(`linearGradient`),mt=p(`radialGradient`),ht=p(`stop`),gt=p(`use`);function _t(e){return Array.isArray(e)?e:[e]}const vt=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]);function yt(){return{update(){},updateSync(){},dispose(){},onCleanup(){},onBeforeMount(){},onMount(){}}}function bt(e){return typeof e==`function`?{$$vani:`component`,component:e,props:{}}:e}function q(e){return e.replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replaceAll(`"`,`&quot;`).replaceAll(`'`,`&#39;`)}function xt(e){let t=[];for(let n of Object.keys(e)){let r=e[n];r==null||r===!1||n.startsWith(`on`)&&typeof r==`function`||(r===!0?t.push(n):t.push(`${n}="${q(String(r))}"`))}return t.length>0?` ${t.join(` `)}`:``}function J(e){if(e==null||e===!1)return{type:`fragment`,children:[]};if(typeof e==`string`||typeof e==`number`)return{type:`text`,text:String(e)};if(u(e))return{type:`component`,instance:e};if(typeof e==`object`&&`type`in e)return e;throw Error(`[vani] SSR received a DOM node. This is not supported.`)}async function St(e){let t=`<!--vani:start-->`,n=`<!--vani:end-->`;if(e.clientOnly){let r=e.props?.fallback;return r?`${t}${await Y(J(r()))}${n}`:`${t}${n}`}let r=e.component(e.props,yt());return`${t}${await Y(J((r instanceof Promise?await r:r)()))}${n}`}async function Y(e){switch(e.type){case`text`:return q(e.text);case`comment`:return`<!--${e.text}-->`;case`fragment`:return(await Promise.all(e.children.map(Y))).join(``);case`component`:return St(e.instance);case`element`:{let t=xt(e.props);if(vt.has(e.tag))return`<${e.tag}${t}>`;let n=(await Promise.all(e.children.map(Y))).join(``);return`<${e.tag}${t}>${n}</${e.tag}>`}}}async function X(e){return i(`ssr`,async()=>{if(t()!==`ssr`)throw Error(`[vani] renderToString failed to set SSR render mode.`);let n=_t(e).map(e=>({type:`component`,instance:bt(e)}));return(await Promise.all(n.map(Y))).join(``)})}const Z=new Map,Q=(e,t)=>{if(!t)return e;let n=`${e??``} ${t}`.trim();return n.length>0?n:void 0},Ct=(e,t)=>{if(!t)return;let n=t.size;if(n!=null&&(e.setAttribute(`width`,String(n)),e.setAttribute(`height`,String(n))),t.className){let n=Q(e.getAttribute(`class`)??void 0,t.className);n&&e.setAttribute(`class`,n)}if(t.attributes){for(let[n,r]of Object.entries(t.attributes))if(!(r==null||r===!1)){if(r===!0){e.setAttribute(n,``);continue}e.setAttribute(n,String(r))}}},wt=e=>{let t={},n=/([^\s=]+)(?:=(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g,r;for(;r=n.exec(e);){let e=r[1],n=r[2]??r[3]??r[4];t[e]=n===void 0?!0:n}return t},Tt=e=>{let t=e.replaceAll(/<!--[\s\S]*?-->/g,``).trim(),n=/<\/?[^>]+>/g,r=[],i=null,a=0,o,s=e=>{let t=r.at(-1);t&&(t.type===`element`||t.type===`fragment`)&&t.children.push(e)};for(;o=n.exec(t);){let e=t.slice(a,o.index);e.trim().length>0&&s({type:`text`,text:e});let c=o[0];if(c.startsWith(`</`))r.pop();else{let e=c.endsWith(`/>`),t=c.slice(1,e?-2:-1).trim(),n=t.search(/\s/),a={type:`element`,tag:n===-1?t:t.slice(0,n),props:wt(n===-1?``:t.slice(n+1)),children:[]};i==null?i=a:s(a),e||r.push(a)}a=n.lastIndex}return i??{type:`fragment`,children:[]}},$=e=>e.type===`text`?{type:`text`,text:e.text}:e.type===`comment`?{type:`comment`,text:e.text}:e.type===`fragment`?{type:`fragment`,children:e.children.map($)}:e.type===`component`?{type:`component`,instance:e.instance}:{type:`element`,tag:e.tag,props:{...e.props},children:e.children.map($)},Et=(e,t)=>{if(!t||e.type!==`element`||e.tag!==`svg`)return;let n=e.props;if(t.size!=null&&(n.width=String(t.size),n.height=String(t.size)),t.className){let e=Q(n.class,t.className);e&&(n.class=e)}if(t.attributes){for(let[e,r]of Object.entries(t.attributes))if(!(r==null||r===!1)){if(r===!0){n[e]=!0;continue}n[e]=String(r)}}},Dt=(e,n)=>{if(t()===`ssr`){let t=$(Tt(e));return Et(t,n),t}let r=Z.get(e);if(!r){let t=new DOMParser().parseFromString(e,`image/svg+xml`);if(t.documentElement.nodeName===`parsererror`?t.documentElement:t.querySelector(`parsererror`))throw Error(`[vani] invalid SVG string`);r=t.documentElement,Z.set(e,r)}let i=r.cloneNode(!0);return Ct(i,n),i};export{ie as Fragment,r as HydrationError,j as a,Ne as abbr,E as article,D as aside,pe as audio,ne as batch,De as blockquote,Le as br,M as button,Be as caption,rt as circle,je as cite,re as classNames,ut as clipPath,Te as code,He as col,Ve as colgroup,a as component,se as configureSignalDom,te as createRoot,G as datalist,x as dd,lt as defs,k as details,Me as dfn,m as div,y as dl,b as dt,d as el,ct as ellipse,Ie as em,he as embed,U as fieldset,ce as figcaption,K as figure,w as footer,B as form,o as fragment,tt as g,t as getRenderMode,e as getSignalDomAdapter,ye as h1,be as h2,xe as h3,Se as h4,Ce as h5,we as h6,C as header,Re as hr,s as hydrateToDOM,me as iframe,le as img,N as input,u as isComponentInstance,l as isDevMode,ke as kbd,z as label,W as legend,_ as li,at as line,pt as linearGradient,S as main,_e as mark,dt as mask,H as meter,ee as mount,O as nav,Ze as noscript,v as ol,R as optgroup,L as option,P as output,ve as p,nt as path,ft as pattern,ue as picture,st as polygon,ot as polyline,Ee as pre,V as progress,mt as radialGradient,c as reactive,it as rect,n as renderKeyedChildren,Dt as renderSvgString,ae as renderToDOM,X as renderToString,Ae as samp,Xe as script,T as section,I as select,oe as setRenderMode,$e as slot,Pe as small,de as source,h as span,f as startTransition,ht as stop,Fe as strong,Ye as style,A as summary,et as svg,ze as table,Ue as tbody,qe as td,Qe as template,F as textarea,Ge as tfoot,Je as th,We as thead,ge as time,Ke as tr,g as ul,gt as use,Oe as var_,fe as video,i as withRenderMode};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/vani/html.ts","../../src/vani/ssr.ts","../../src/vani/svg.ts"],"sourcesContent":["// ─────────────────────────────────────────────\n// HTML element helpers\n// ─────────────────────────────────────────────\n\nimport { el, type ElementProps, type VChild } from './runtime'\n\ntype ElementTagName = keyof HTMLElementTagNameMap | keyof SVGElementTagNameMap\n\nfunction createElementFn<E extends ElementTagName>(tag: E) {\n return (propsOrChild?: ElementProps<E> | VChild | null, ...children: VChild[]) =>\n el(tag, propsOrChild, ...children)\n}\n\n// Basic and semantic elements\nexport const div = createElementFn('div')\nexport const span = createElementFn('span')\nexport const ul = createElementFn('ul')\nexport const li = createElementFn('li')\nexport const ol = createElementFn('ol')\nexport const dl = createElementFn('dl')\nexport const dt = createElementFn('dt')\nexport const dd = createElementFn('dd')\nexport const main = createElementFn('main')\nexport const header = createElementFn('header')\nexport const footer = createElementFn('footer')\nexport const section = createElementFn('section')\nexport const article = createElementFn('article')\nexport const aside = createElementFn('aside')\nexport const nav = createElementFn('nav')\n\n// Interactive elements\nexport const details = createElementFn('details')\nexport const summary = createElementFn('summary')\nexport const a = createElementFn('a')\nexport const button = createElementFn('button')\nexport const input = createElementFn('input')\nexport const output = createElementFn('output')\nexport const textarea = createElementFn('textarea')\nexport const select = createElementFn('select')\nexport const option = createElementFn('option')\nexport const optgroup = createElementFn('optgroup')\nexport const label = createElementFn('label')\nexport const form = createElementFn('form')\nexport const progress = createElementFn('progress')\nexport const meter = createElementFn('meter')\nexport const fieldset = createElementFn('fieldset')\nexport const legend = createElementFn('legend')\nexport const datalist = createElementFn('datalist')\n\n// Media elements\nexport const figure = createElementFn('figure')\nexport const figcaption = createElementFn('figcaption')\nexport const img = createElementFn('img')\nexport const picture = createElementFn('picture')\nexport const source = createElementFn('source')\nexport const video = createElementFn('video')\nexport const audio = createElementFn('audio')\nexport const iframe = createElementFn('iframe')\nexport const embed = createElementFn('embed')\n\n// Prose elements\nexport const time = createElementFn('time')\nexport const mark = createElementFn('mark')\nexport const p = createElementFn('p')\nexport const h1 = createElementFn('h1')\nexport const h2 = createElementFn('h2')\nexport const h3 = createElementFn('h3')\nexport const h4 = createElementFn('h4')\nexport const h5 = createElementFn('h5')\nexport const h6 = createElementFn('h6')\nexport const code = createElementFn('code')\nexport const pre = createElementFn('pre')\nexport const blockquote = createElementFn('blockquote')\nexport const var_ = createElementFn('var')\nexport const kbd = createElementFn('kbd')\nexport const samp = createElementFn('samp')\nexport const cite = createElementFn('cite')\nexport const dfn = createElementFn('dfn')\nexport const abbr = createElementFn('abbr')\nexport const small = createElementFn('small')\nexport const strong = createElementFn('strong')\nexport const em = createElementFn('em')\nexport const br = createElementFn('br')\nexport const hr = createElementFn('hr')\n\n// Tables\nexport const table = createElementFn('table')\nexport const caption = createElementFn('caption')\nexport const colgroup = createElementFn('colgroup')\nexport const col = createElementFn('col')\nexport const tbody = createElementFn('tbody')\nexport const thead = createElementFn('thead')\nexport const tfoot = createElementFn('tfoot')\nexport const tr = createElementFn('tr')\nexport const td = createElementFn('td')\nexport const th = createElementFn('th')\n\n// Scripting elements\nexport const style = createElementFn('style')\nexport const script = createElementFn('script')\nexport const noscript = createElementFn('noscript')\nexport const template = createElementFn('template')\nexport const slot = createElementFn('slot')\n\n// SVG elements\nexport const svg = createElementFn('svg')\nexport const g = createElementFn('g')\nexport const path = createElementFn('path')\nexport const circle = createElementFn('circle')\nexport const rect = createElementFn('rect')\nexport const line = createElementFn('line')\nexport const polyline = createElementFn('polyline')\nexport const polygon = createElementFn('polygon')\nexport const ellipse = createElementFn('ellipse')\nexport const defs = createElementFn('defs')\nexport const clipPath = createElementFn('clipPath')\nexport const mask = createElementFn('mask')\nexport const pattern = createElementFn('pattern')\nexport const linearGradient = createElementFn('linearGradient')\nexport const radialGradient = createElementFn('radialGradient')\nexport const stop = createElementFn('stop')\nexport const use = createElementFn('use')\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable unicorn/no-array-callback-reference */\n\nimport { getRenderMode } from './common'\nimport {\n isComponentInstance,\n withRenderMode,\n type Component,\n type ComponentInstance,\n type Handle,\n type RenderFn,\n type SSRNode,\n type VChild,\n} from './runtime'\n\ntype Renderable = Component<any> | ComponentInstance<any>\n\nfunction normalizeRenderables(input: Renderable | Renderable[]): Renderable[] {\n return Array.isArray(input) ? input : [input]\n}\n\nconst voidElements = new Set([\n 'area',\n 'base',\n 'br',\n 'col',\n 'embed',\n 'hr',\n 'img',\n 'input',\n 'link',\n 'meta',\n 'param',\n 'source',\n 'track',\n 'wbr',\n])\n\nfunction createSsrHandle(): Handle {\n return {\n update() {},\n updateSync() {},\n dispose() {},\n onCleanup() {},\n onBeforeMount() {},\n onMount() {},\n }\n}\n\nfunction normalizeComponent(comp: Renderable): ComponentInstance<any> {\n if (typeof comp === 'function') {\n return {\n $$vani: 'component',\n component: comp,\n props: {},\n }\n }\n return comp\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replaceAll('&', '&amp;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n .replaceAll('\"', '&quot;')\n .replaceAll(\"'\", '&#39;')\n}\n\nfunction serializeProps(props: Record<string, any>): string {\n const parts: string[] = []\n for (const key of Object.keys(props)) {\n const value = props[key]\n if (value == null || value === false) continue\n if (key.startsWith('on') && typeof value === 'function') continue\n\n if (value === true) {\n parts.push(key)\n } else {\n parts.push(`${key}=\"${escapeHtml(String(value))}\"`)\n }\n }\n\n return parts.length > 0 ? ` ${parts.join(' ')}` : ''\n}\n\nfunction toSsrNode(node: VChild): SSRNode {\n if (node == null || node === false) {\n return { type: 'fragment', children: [] }\n }\n\n if (typeof node === 'string' || typeof node === 'number') {\n return { type: 'text', text: String(node) }\n }\n\n if (isComponentInstance(node)) {\n return { type: 'component', instance: node }\n }\n\n if (typeof node === 'object' && 'type' in node) {\n return node as SSRNode\n }\n\n throw new Error('[vani] SSR received a DOM node. This is not supported.')\n}\n\nasync function renderComponent(instance: ComponentInstance<any>): Promise<string> {\n const start = '<!--vani:start-->'\n const end = '<!--vani:end-->'\n\n if (instance.clientOnly) {\n const fallback = (instance.props as any)?.fallback as RenderFn | undefined\n if (!fallback) {\n return `${start}${end}`\n }\n const fallbackNode = toSsrNode(fallback())\n return `${start}${await serializeNode(fallbackNode)}${end}`\n }\n\n const result = instance.component(instance.props, createSsrHandle())\n const renderFn = result instanceof Promise ? await result : result\n const node = toSsrNode(renderFn())\n return `${start}${await serializeNode(node)}${end}`\n}\n\nasync function serializeNode(node: SSRNode): Promise<string> {\n switch (node.type) {\n case 'text':\n return escapeHtml(node.text)\n case 'comment':\n return `<!--${node.text}-->`\n case 'fragment':\n return (await Promise.all(node.children.map(serializeNode))).join('')\n case 'component':\n return renderComponent(node.instance)\n case 'element': {\n const attrs = serializeProps(node.props)\n if (voidElements.has(node.tag)) {\n return `<${node.tag}${attrs}>`\n }\n const children = (await Promise.all(node.children.map(serializeNode))).join('')\n return `<${node.tag}${attrs}>${children}</${node.tag}>`\n }\n }\n}\n\nexport async function renderToString(components: Renderable | Renderable[]): Promise<string> {\n return withRenderMode('ssr', async () => {\n if (getRenderMode() !== 'ssr') {\n throw new Error('[vani] renderToString failed to set SSR render mode.')\n }\n\n const normalized = normalizeRenderables(components)\n const nodes: SSRNode[] = normalized.map((component) => ({\n type: 'component',\n instance: normalizeComponent(component),\n }))\n\n const rendered = await Promise.all(nodes.map(serializeNode))\n return rendered.join('')\n })\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable unicorn/no-array-callback-reference */\n\nimport { getRenderMode } from './common'\nimport { type SSRNode, type SvgProps, type VNode } from './runtime'\n\nexport type SvgRenderOptions = {\n size?: number\n className?: string\n attributes?: SvgProps\n}\n\nconst svgStringCache = new Map<string, SVGSVGElement>()\n\nconst mergeClassValue = (base: string | undefined, extra: string | undefined) => {\n if (!extra) return base\n const merged = `${base ?? ''} ${extra}`.trim()\n return merged.length > 0 ? merged : undefined\n}\n\nconst applySvgOverridesToNode = (node: SVGSVGElement, options?: SvgRenderOptions) => {\n if (!options) return\n const size = options.size\n if (size != null) {\n node.setAttribute('width', String(size))\n node.setAttribute('height', String(size))\n }\n if (options.className) {\n const merged = mergeClassValue(node.getAttribute('class') ?? undefined, options.className)\n if (merged) {\n node.setAttribute('class', merged)\n }\n }\n if (options.attributes) {\n for (const [key, value] of Object.entries(options.attributes)) {\n if (value == null || value === false) continue\n if (value === true) {\n node.setAttribute(key, '')\n continue\n }\n node.setAttribute(key, String(value))\n }\n }\n}\n\nconst parseSvgAttributes = (input: string) => {\n const attrs: Record<string, string | boolean> = {}\n const attrRegex = /([^\\s=]+)(?:=(?:\"([^\"]*)\"|'([^']*)'|([^\\s\"'>]+)))?/g\n let match: RegExpExecArray | null\n while ((match = attrRegex.exec(input))) {\n const key = match[1]\n const value = match[2] ?? match[3] ?? match[4]\n attrs[key] = value === undefined ? true : value\n }\n return attrs\n}\n\nconst parseSvgToSsrNode = (svg: string): SSRNode => {\n const cleaned = svg.replaceAll(/<!--[\\s\\S]*?-->/g, '').trim()\n const tagRegex = /<\\/?[^>]+>/g\n const stack: Array<SSRNode> = []\n let root: SSRNode | null = null\n let lastIndex = 0\n let match: RegExpExecArray | null\n\n const appendChild = (child: SSRNode) => {\n const parent = stack.at(-1)\n if (parent && (parent.type === 'element' || parent.type === 'fragment')) {\n parent.children.push(child)\n }\n }\n\n while ((match = tagRegex.exec(cleaned))) {\n const text = cleaned.slice(lastIndex, match.index)\n if (text.trim().length > 0) {\n appendChild({ type: 'text', text })\n }\n\n const token = match[0]\n if (token.startsWith('</')) {\n stack.pop()\n } else {\n const selfClosing = token.endsWith('/>')\n const inside = token.slice(1, selfClosing ? -2 : -1).trim()\n const spaceIndex = inside.search(/\\s/)\n const tag = spaceIndex === -1 ? inside : inside.slice(0, spaceIndex)\n const attrString = spaceIndex === -1 ? '' : inside.slice(spaceIndex + 1)\n const props = parseSvgAttributes(attrString)\n const node: SSRNode = { type: 'element', tag, props, children: [] }\n\n if (root == null) {\n root = node\n } else {\n appendChild(node)\n }\n\n if (!selfClosing) {\n stack.push(node)\n }\n }\n\n lastIndex = tagRegex.lastIndex\n }\n\n return root ?? { type: 'fragment', children: [] }\n}\n\nconst cloneSsrNode = (node: SSRNode): SSRNode => {\n if (node.type === 'text') {\n return { type: 'text', text: node.text }\n }\n if (node.type === 'comment') {\n return { type: 'comment', text: node.text }\n }\n if (node.type === 'fragment') {\n return { type: 'fragment', children: node.children.map(cloneSsrNode) }\n }\n if (node.type === 'component') {\n return { type: 'component', instance: node.instance }\n }\n return {\n type: 'element',\n tag: node.tag,\n props: { ...node.props },\n children: node.children.map(cloneSsrNode),\n }\n}\n\nconst applySvgOverridesToSsr = (node: SSRNode, options?: SvgRenderOptions) => {\n if (!options || node.type !== 'element' || node.tag !== 'svg') return\n const props = node.props as Record<string, any>\n if (options.size != null) {\n props.width = String(options.size)\n props.height = String(options.size)\n }\n if (options.className) {\n const merged = mergeClassValue(props.class as string | undefined, options.className)\n if (merged) {\n props.class = merged\n }\n }\n if (options.attributes) {\n for (const [key, value] of Object.entries(options.attributes)) {\n if (value == null || value === false) continue\n if (value === true) {\n props[key] = true\n continue\n }\n props[key] = String(value)\n }\n }\n}\n\nexport const renderSvgString = (svg: string, options?: SvgRenderOptions): VNode => {\n if (getRenderMode() === 'ssr') {\n const parsed = cloneSsrNode(parseSvgToSsrNode(svg))\n applySvgOverridesToSsr(parsed, options)\n return parsed\n }\n\n let base = svgStringCache.get(svg)\n if (!base) {\n const doc = new DOMParser().parseFromString(svg, 'image/svg+xml')\n const parserError =\n doc.documentElement.nodeName === 'parsererror'\n ? doc.documentElement\n : doc.querySelector('parsererror')\n if (parserError) {\n throw new Error('[vani] invalid SVG string')\n }\n base = doc.documentElement as unknown as SVGSVGElement\n svgStringCache.set(svg, base)\n }\n const node = base.cloneNode(true) as SVGSVGElement\n applySvgOverridesToNode(node, options)\n return node\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { Fragment, jsx, jsxDEV, jsxs } from "./jsx-runtime.mjs";
1
+ import { a as jsxs, i as jsxDEV, r as jsx, t as Fragment } from "./jsx-runtime-BK1MMitM.mjs";
2
2
  export { Fragment, jsx, jsxDEV, jsxs };
@@ -1 +1 @@
1
- import"./runtime-X8xzmXJz.mjs";import{Fragment as e,jsx as t,jsxDEV as n,jsxs as r}from"./jsx-runtime.mjs";export{e as Fragment,t as jsx,n as jsxDEV,r as jsxs};
1
+ import{i as e,n as t,r as n,t as r}from"./jsx-runtime-BUSOLzm1.mjs";export{r as Fragment,t as jsx,n as jsxDEV,e as jsxs};