@vanijs/vani 0.4.0 → 0.5.1
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 +300 -21
- package/README.md +1 -0
- package/dist/lib/index.d.mts +14 -2
- package/dist/lib/index.mjs +2 -1
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/jsx-dev-runtime.d.mts +1 -1
- package/dist/lib/jsx-dev-runtime.mjs +1 -1
- package/dist/lib/jsx-runtime-BK1MMitM.d.mts +287 -0
- package/dist/lib/jsx-runtime-Bbqe4zqZ.mjs +2 -0
- package/dist/lib/jsx-runtime-Bbqe4zqZ.mjs.map +1 -0
- package/dist/lib/jsx-runtime.d.mts +1 -26
- package/dist/lib/jsx-runtime.mjs +1 -1
- package/package.json +103 -38
- package/dist/lib/runtime-Cx9SKHrc.d.mts +0 -190
- package/dist/lib/runtime-X8xzmXJz.mjs +0 -1
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
//#region src/vani/common.d.ts
|
|
2
|
+
type ClassName = string | undefined | null | {
|
|
3
|
+
[key: string]: boolean | undefined | null;
|
|
4
|
+
} | ClassName[];
|
|
5
|
+
type RenderMode = 'dom' | 'ssr';
|
|
6
|
+
type AttrValue = ClassName | string | number | boolean | null | undefined;
|
|
7
|
+
type TextNode = Node | {
|
|
8
|
+
type: 'text';
|
|
9
|
+
text: string;
|
|
10
|
+
};
|
|
11
|
+
type SignalDomAdapter = {
|
|
12
|
+
getRenderMode: () => 'dom' | 'ssr';
|
|
13
|
+
createTextNode: (text: string) => TextNode;
|
|
14
|
+
addNodeCleanup: (node: Node, cleanup: () => void) => void;
|
|
15
|
+
classNames: (...classes: ClassName[]) => string;
|
|
16
|
+
normalizeAttrKey: (key: string, isSvg: boolean) => string;
|
|
17
|
+
};
|
|
18
|
+
declare function getRenderMode(): RenderMode;
|
|
19
|
+
declare function setRenderMode(mode: RenderMode): void;
|
|
20
|
+
declare function configureSignalDom(adapter: SignalDomAdapter): void;
|
|
21
|
+
declare function getSignalDomAdapter(): SignalDomAdapter | null;
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/vani/runtime.d.ts
|
|
24
|
+
type SSRNode = {
|
|
25
|
+
type: 'element';
|
|
26
|
+
tag: string;
|
|
27
|
+
props: Record<string, any>;
|
|
28
|
+
children: SSRNode[];
|
|
29
|
+
} | {
|
|
30
|
+
type: 'text';
|
|
31
|
+
text: string;
|
|
32
|
+
} | {
|
|
33
|
+
type: 'comment';
|
|
34
|
+
text: string;
|
|
35
|
+
} | {
|
|
36
|
+
type: 'fragment';
|
|
37
|
+
children: SSRNode[];
|
|
38
|
+
} | {
|
|
39
|
+
type: 'component';
|
|
40
|
+
instance: ComponentInstance<any>;
|
|
41
|
+
};
|
|
42
|
+
type VNode = Node | SSRNode;
|
|
43
|
+
declare class HydrationError extends Error {
|
|
44
|
+
constructor(message: string);
|
|
45
|
+
}
|
|
46
|
+
interface Handle {
|
|
47
|
+
/**
|
|
48
|
+
* Schedules a render for the component.
|
|
49
|
+
* This triggers a re-render on the next microtask.
|
|
50
|
+
*/
|
|
51
|
+
update(options?: UpdateOptions): void;
|
|
52
|
+
/**
|
|
53
|
+
* Flushes the component render.
|
|
54
|
+
* This triggers a re-render immediately.
|
|
55
|
+
*/
|
|
56
|
+
updateSync(options?: UpdateOptions): void;
|
|
57
|
+
/**
|
|
58
|
+
* Disposes the component: removes the component from the DOM and runs all cleanup functions.
|
|
59
|
+
*/
|
|
60
|
+
dispose(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Adds a cleanup function that is called when the component is disposed.
|
|
63
|
+
*/
|
|
64
|
+
onCleanup(fn: () => void): void;
|
|
65
|
+
/**
|
|
66
|
+
* This is purely syntatic sugar, as it is basically the same as running the function
|
|
67
|
+
* on the setup phase and calling onCleanup to add a cleanup function.
|
|
68
|
+
*
|
|
69
|
+
* Using onBeforeMount is necessary in SSR mode, for side effects to not run on the server
|
|
70
|
+
* (e.g. timers, subscriptions, DOM usage, etc.)
|
|
71
|
+
*
|
|
72
|
+
* Runs a side effect function during component setup, before the first render.
|
|
73
|
+
* The returning function may be a cleanup function that is called when the component is disposed.
|
|
74
|
+
*
|
|
75
|
+
*/
|
|
76
|
+
onBeforeMount(fn: () => void | (() => void)): void;
|
|
77
|
+
/**
|
|
78
|
+
* Runs after the first render, once the component's nodes are in the DOM.
|
|
79
|
+
* The first argument is a lazy getter for the mounted nodes, so it only traverses
|
|
80
|
+
* the DOM if called. The second argument is the parent mount point.
|
|
81
|
+
* The returning function may be a cleanup function that is called when the component is disposed.
|
|
82
|
+
*/
|
|
83
|
+
onMount(fn: (getNodes: () => Node[], parent: Node | null) => void | (() => void)): void;
|
|
84
|
+
}
|
|
85
|
+
type RenderFn = () => VChild;
|
|
86
|
+
type Component<Props = any> = (props: Props, handle: Handle) => RenderFn | Promise<RenderFn>;
|
|
87
|
+
type ComponentInstance<Props = any> = {
|
|
88
|
+
$$vani: 'component';
|
|
89
|
+
component: Component<Props>;
|
|
90
|
+
props: Props;
|
|
91
|
+
/**
|
|
92
|
+
* A key is used to identify the component when it is re-rendered.
|
|
93
|
+
* If a key is provided, the component will be re-rendered only if the key changes.
|
|
94
|
+
*/
|
|
95
|
+
key?: string | number;
|
|
96
|
+
/**
|
|
97
|
+
* A ref is used to get a reference to the component instance.
|
|
98
|
+
* The ref is set to the component instance when the component is mounted.
|
|
99
|
+
* The ref is set to null when the component is disposed.
|
|
100
|
+
*/
|
|
101
|
+
ref?: ComponentRef;
|
|
102
|
+
clientOnly?: boolean;
|
|
103
|
+
};
|
|
104
|
+
type ComponentInput<Props> = Props & {
|
|
105
|
+
key?: string | number;
|
|
106
|
+
ref?: ComponentRef;
|
|
107
|
+
};
|
|
108
|
+
type ComponentMetaProps$1 = {
|
|
109
|
+
key?: string | number;
|
|
110
|
+
ref?: ComponentRef;
|
|
111
|
+
fallback?: RenderFn;
|
|
112
|
+
clientOnly?: boolean;
|
|
113
|
+
};
|
|
114
|
+
type VChild = VNode | ComponentInstance<any> | string | number | null | undefined | false | VChild[];
|
|
115
|
+
type DataAttribute = `data-${string}` | `data${Capitalize<string>}`;
|
|
116
|
+
type HtmlTagName = keyof HTMLElementTagNameMap;
|
|
117
|
+
type SvgTagName = keyof SVGElementTagNameMap;
|
|
118
|
+
type ElementTagName$1 = HtmlTagName | SvgTagName;
|
|
119
|
+
type ElementByTag<T extends ElementTagName$1> = T extends HtmlTagName ? HTMLElementTagNameMap[T] : T extends SvgTagName ? SVGElementTagNameMap[T] : Element;
|
|
120
|
+
type SvgProps<T extends SvgTagName = SvgTagName> = BaseProps<T> & {
|
|
121
|
+
[key: string]: unknown;
|
|
122
|
+
};
|
|
123
|
+
type BaseProps<T extends ElementTagName$1> = ({
|
|
124
|
+
class?: ClassName;
|
|
125
|
+
className?: never;
|
|
126
|
+
style?: string;
|
|
127
|
+
ref?: DomRef<ElementByTag<T>>;
|
|
128
|
+
} | {
|
|
129
|
+
class?: never;
|
|
130
|
+
className?: ClassName;
|
|
131
|
+
style?: string;
|
|
132
|
+
ref?: DomRef<ElementByTag<T>>;
|
|
133
|
+
}) & {
|
|
134
|
+
[key: DataAttribute]: string | number | boolean | undefined | null;
|
|
135
|
+
};
|
|
136
|
+
type HtmlProps<T extends HtmlTagName = HtmlTagName> = BaseProps<T> & Partial<Omit<ElementByTag<T>, 'children' | 'className' | 'style'>>;
|
|
137
|
+
type ElementProps<T extends ElementTagName$1> = T extends SvgTagName ? SvgProps<T> : HtmlProps<Extract<T, HtmlTagName>>;
|
|
138
|
+
type ComponentRef = {
|
|
139
|
+
current: Handle | null;
|
|
140
|
+
};
|
|
141
|
+
type DomRef<T extends Element = Element> = {
|
|
142
|
+
current: T | null;
|
|
143
|
+
};
|
|
144
|
+
type UpdateOptions = {
|
|
145
|
+
onlyAttributes?: boolean;
|
|
146
|
+
};
|
|
147
|
+
declare function component(fn: Component<void>): (props?: ComponentMetaProps$1) => ComponentInstance<void>;
|
|
148
|
+
declare function component<Props>(fn: Component<Props>): (props: Props & ComponentMetaProps$1) => ComponentInstance<Props>;
|
|
149
|
+
/**
|
|
150
|
+
* Creates a reactive component that auto-tracks signal reads and re-renders when signals change.
|
|
151
|
+
*
|
|
152
|
+
* This is the only "magic" in Vani - signals read during render are automatically tracked,
|
|
153
|
+
* and when any tracked signal changes, the component re-renders.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```tsx
|
|
157
|
+
* const [count, setCount] = signal(0)
|
|
158
|
+
*
|
|
159
|
+
* const Counter = reactive((props, handle) => {
|
|
160
|
+
* return () => <div>Count: {count()}</div>
|
|
161
|
+
* })
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
declare function reactive(fn: Component<void>): (props?: ComponentMetaProps$1) => ComponentInstance<void>;
|
|
165
|
+
declare function reactive<Props>(fn: Component<Props>): (props: Props & ComponentMetaProps$1) => ComponentInstance<Props>;
|
|
166
|
+
declare function withRenderMode<T>(mode: RenderMode, fn: () => T): T;
|
|
167
|
+
type WrappedComponent$1<Props = any> = ((props?: Props & ComponentMetaProps$1) => ComponentInstance<Props>) & {
|
|
168
|
+
$$vaniWrapped?: true;
|
|
169
|
+
};
|
|
170
|
+
type Renderable = Component<any> | ComponentInstance<any> | WrappedComponent$1<any>;
|
|
171
|
+
declare function renderToDOM(components: Renderable | Renderable[], root: HTMLElement): Handle[];
|
|
172
|
+
type Root = {
|
|
173
|
+
/**
|
|
174
|
+
* Renders a component into the root container.
|
|
175
|
+
* Clears any existing content before rendering.
|
|
176
|
+
* Can be called multiple times to replace the rendered content.
|
|
177
|
+
*/
|
|
178
|
+
render(component: Renderable): void;
|
|
179
|
+
/**
|
|
180
|
+
* Unmounts the rendered content and cleans up all resources.
|
|
181
|
+
* After calling unmount(), the root cannot be used again.
|
|
182
|
+
*/
|
|
183
|
+
unmount(): void;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Creates a root for rendering Vani components.
|
|
187
|
+
*
|
|
188
|
+
* Similar to React's createRoot API, this provides a clean way to manage
|
|
189
|
+
* component lifecycle with automatic container clearing and proper cleanup.
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```ts
|
|
193
|
+
* const root = createRoot(document.getElementById('app')!)
|
|
194
|
+
* root.render(App())
|
|
195
|
+
*
|
|
196
|
+
* // Later, to unmount:
|
|
197
|
+
* root.unmount()
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
declare function createRoot(container: HTMLElement): Root;
|
|
201
|
+
declare function isComponentInstance(child: VChild): child is ComponentInstance<any>;
|
|
202
|
+
declare function renderKeyedChildren(parent: Node, children: Array<ComponentInstance<any>>): void;
|
|
203
|
+
declare function classNames(...classes: ClassName[]): string;
|
|
204
|
+
declare function el<E extends ElementTagName$1>(tag: E, props?: ElementProps<E> | VChild | null, ...children: VChild[]): VNode;
|
|
205
|
+
declare const fragment: (...children: VChild[]) => {
|
|
206
|
+
type: "fragment";
|
|
207
|
+
children: SSRNode[];
|
|
208
|
+
} | DocumentFragment;
|
|
209
|
+
declare function mount<Props>(component: Component<Props>, props: Props): VNode;
|
|
210
|
+
/**
|
|
211
|
+
* Marks all updates triggered inside the callback as a "transition".
|
|
212
|
+
*
|
|
213
|
+
* A transition represents non-urgent UI work that can be deferred
|
|
214
|
+
* to keep the application responsive.
|
|
215
|
+
*
|
|
216
|
+
* Updates scheduled inside `startTransition`:
|
|
217
|
+
* - do NOT block user interactions
|
|
218
|
+
* - are batched separately from urgent updates
|
|
219
|
+
* - may be flushed later (e.g. after the current event or during idle time)
|
|
220
|
+
*
|
|
221
|
+
* Transitions are NOT animations.
|
|
222
|
+
* They do not control how updates look, only *when* they are applied.
|
|
223
|
+
*
|
|
224
|
+
* Typical use cases:
|
|
225
|
+
* - Filtering or sorting large lists
|
|
226
|
+
* - Rendering expensive subtrees
|
|
227
|
+
* - Applying async results that are not immediately visible
|
|
228
|
+
*
|
|
229
|
+
* Example:
|
|
230
|
+
* ```ts
|
|
231
|
+
* button({
|
|
232
|
+
* onclick: () => {
|
|
233
|
+
* // urgent update
|
|
234
|
+
* setOpen(true)
|
|
235
|
+
* handle.update()
|
|
236
|
+
*
|
|
237
|
+
* // non-urgent update
|
|
238
|
+
* startTransition(() => {
|
|
239
|
+
* setItems(filter(items))
|
|
240
|
+
* handle.update()
|
|
241
|
+
* })
|
|
242
|
+
* },
|
|
243
|
+
* })
|
|
244
|
+
* ```
|
|
245
|
+
*
|
|
246
|
+
* If multiple transitions are triggered, they are automatically batched.
|
|
247
|
+
* Transition updates never interrupt urgent updates.
|
|
248
|
+
*/
|
|
249
|
+
declare function startTransition(fn: () => void): void;
|
|
250
|
+
declare function batch(fn: () => void): void;
|
|
251
|
+
declare function hydrateToDOM(components: Renderable | Renderable[], root: HTMLElement): Handle[];
|
|
252
|
+
declare function isDevMode(): boolean;
|
|
253
|
+
//#endregion
|
|
254
|
+
//#region src/vani/jsx-runtime.d.ts
|
|
255
|
+
type ElementTagName = Extract<keyof HTMLElementTagNameMap | keyof SVGElementTagNameMap, string>;
|
|
256
|
+
type IntrinsicElementProps<Tag extends ElementTagName> = ElementProps<Tag> & {
|
|
257
|
+
children?: VChild | VChild[];
|
|
258
|
+
key?: string | number;
|
|
259
|
+
class?: ClassName;
|
|
260
|
+
};
|
|
261
|
+
type Key = string | number | null | undefined;
|
|
262
|
+
type WrappedComponent<Props = any> = (props?: Props & ComponentMetaProps) => ComponentInstance<Props>;
|
|
263
|
+
type ComponentMetaProps = {
|
|
264
|
+
key?: string | number;
|
|
265
|
+
ref?: ComponentRef;
|
|
266
|
+
clientOnly?: boolean;
|
|
267
|
+
};
|
|
268
|
+
declare const Fragment: unique symbol;
|
|
269
|
+
type JsxElementType = string | Component<any> | WrappedComponent<any> | typeof Fragment;
|
|
270
|
+
declare function jsx(type: JsxElementType, props: Record<string, any> | null, key?: Key): VNode | ComponentInstance<any> | ComponentInstance<void>;
|
|
271
|
+
declare const jsxs: typeof jsx;
|
|
272
|
+
declare function jsxDEV(type: JsxElementType, props: Record<string, any> | null, key?: Key, _isStaticChildren?: boolean, _source?: unknown, _self?: unknown): VNode | ComponentInstance<any> | ComponentInstance<void>;
|
|
273
|
+
declare namespace JSX {
|
|
274
|
+
type Element = VNode | ComponentInstance<any>;
|
|
275
|
+
type ElementType = JsxElementType;
|
|
276
|
+
interface ElementChildrenAttribute {
|
|
277
|
+
children: {};
|
|
278
|
+
}
|
|
279
|
+
interface IntrinsicAttributes {
|
|
280
|
+
key?: string | number;
|
|
281
|
+
ref?: DomRef<globalThis.Element> | ComponentRef;
|
|
282
|
+
}
|
|
283
|
+
type IntrinsicElements = { [K in ElementTagName]: IntrinsicElementProps<K> };
|
|
284
|
+
}
|
|
285
|
+
//#endregion
|
|
286
|
+
export { isComponentInstance as A, RenderMode as B, batch as C, el as D, createRoot as E, renderToDOM as F, setRenderMode as G, configureSignalDom as H, startTransition as I, withRenderMode as L, mount as M, reactive as N, fragment as O, renderKeyedChildren as P, AttrValue as R, VNode as S, component as T, getRenderMode as U, TextNode as V, getSignalDomAdapter as W, Root as _, jsxs as a, UpdateOptions as b, ComponentInstance as c, DomRef as d, ElementProps as f, RenderFn as g, HydrationError as h, jsxDEV as i, isDevMode as j, hydrateToDOM as k, ComponentRef as l, HtmlProps as m, JSX as n, Component as o, Handle as p, jsx as r, ComponentInput as s, Fragment as t, DataAttribute as u, SSRNode as v, classNames as w, VChild as x, SvgProps as y, ClassName as z };
|
|
287
|
+
//# sourceMappingURL=jsx-runtime-BK1MMitM.d.mts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e={renderMode:`dom`,domAdapter:null};function t(){return e.renderMode}function n(t){e.renderMode=t}function r(t){e.domAdapter=t}function i(){return e.domAdapter}let a=null;const o=new Set;let s=!1;function c(e){!a||a.disposed||a.deps.has(e)||(a.deps.add(e),e.observers.add(a))}function l(e){for(let t of e.deps)t.observers.delete(e);e.deps.clear(),e.cleanup&&=(e.cleanup(),void 0)}function u(e){if(e.disposed)return;l(e);let t=a;a=e;let n=e.fn();a=t,typeof n==`function`&&(e.cleanup=n)}function d(e){e.disposed||(o.add(e),!s&&(s=!0,queueMicrotask(()=>{s=!1;let e=Array.from(o);o.clear();for(let t of e)u(t)})))}function f(e){let t={value:e,observers:new Set};return[()=>(c(t),t.value),e=>{let n=typeof e==`function`?e(t.value):e;if(!Object.is(n,t.value)){t.value=n;for(let e of t.observers)d(e)}}]}function p(e){return t()===`ssr`?(e(),()=>{}):m(e)}function m(e){let t={fn:e,deps:new Set,disposed:!1};return u(t),()=>{t.disposed||(t.disposed=!0,l(t))}}function ee(e){let[t,n]=f(e());return m(()=>{n(e())}),t}function te(e){let t=()=>typeof e==`function`?e():e,n=String(t()??``),r=i();if(!r)return typeof document<`u`?document.createTextNode(n):{type:`text`,text:n};let a=r.createTextNode(n);if(r.getRenderMode()===`ssr`)return a;if(typeof e==`function`){let e=a,n=m(()=>{e.textContent=String(t()??``)});i()?.addNodeCleanup(e,n)}return a}function ne(e,t,n){let r=i();if(!r||r.getRenderMode()===`ssr`||t.startsWith(`on`))return()=>{};let a=e instanceof SVGElement,o=t===`className`?`class`:r.normalizeAttrKey(t,a),s=t=>{if(o===`class`){let n=r.classNames(t);if(!n){e.removeAttribute(`class`);return}e.setAttribute(`class`,n);return}if(t===!0){e.setAttribute(o,``);return}if(t===!1||t==null){e.removeAttribute(o);return}e.setAttribute(o,String(t))};if(typeof n==`function`){let t=m(()=>{s(n())});return r.addNodeCleanup(e,t),t}return s(n),()=>{}}var h=class extends Error{constructor(e){super(e),this.name=`HydrationError`}};function g(e){let t=e;return t.__vaniKeyed||=new Map,t.__vaniKeyed}function _(e){let t=t=>{let n,r,i=!1,a=t;if(t&&typeof t==`object`){let e=t;if(n=e.key,r=e.ref,i=e.clientOnly,`key`in e||`ref`in e){let{key:t,ref:n,clientOnly:r,...i}=e;a=i}}return{$$vani:`component`,component:e,props:a,key:n,ref:r,clientOnly:i}};return t.$$vaniWrapped=!0,t}function re(e){return _((t,n)=>{let r=e(t,n);return r instanceof Promise?r.then(e=>ie(e,n)):ie(r,n)})}function ie(e,t){let n,r=!0;return t.onBeforeMount(()=>(n=m(()=>{if(e(),r){r=!1;return}t.update()}),n)),e}function ae(e,r){let i=t();n(e);let a=r();return a&&typeof a.finally==`function`?a.finally(()=>{n(i)}):(n(i),a)}function v(e){if(typeof e!=`object`||!e||!(`type`in e))return!1;let t=e;switch(t.type){case`element`:return typeof t.tag==`string`&&typeof t.props==`object`&&Array.isArray(t.children);case`text`:case`comment`:return typeof t.text==`string`;case`fragment`:return Array.isArray(t.children);case`component`:return typeof t.instance==`object`&&t.instance!=null;default:return!1}}function y(e){return v(e)&&e.type===`element`}function oe(e){return v(e)&&e.type===`fragment`}const se=new Set([`svg`,`g`,`path`,`circle`,`rect`,`line`,`polyline`,`polygon`,`ellipse`,`defs`,`clipPath`,`mask`,`pattern`,`linearGradient`,`radialGradient`,`stop`,`use`]);function ce(e){return t()===`dom`?se.has(e)?document.createElementNS(`http://www.w3.org/2000/svg`,e):document.createElement(e):{type:`element`,tag:e,props:{},children:[]}}function b(e){return t()===`dom`?document.createTextNode(e):{type:`text`,text:e}}function x(e,n){if(t()===`dom`){e.appendChild(n);return}(y(e)||oe(e))&&e.children.push(n)}function le(e,t){let n=e;if(!n.__vaniCleanup){n.__vaniCleanup=[t];return}n.__vaniCleanup.push(t)}function ue(e){let t=e,n=t.__vaniCleanup;if(Array.isArray(n)){t.__vaniCleanup=null;for(let e of n)e()}}function S(e,t){let n=e.nextSibling;for(;n&&n!==t;){let e=n.nextSibling;if(n.nodeType===Node.COMMENT_NODE&&n.nodeValue===`vani:start`){let t=n.__vaniHandle;if(t){let r=t.__vaniEnd?.nextSibling??e;t.dispose(),n=r;continue}}ue(n);let t=n;t.__vaniDomRef&&(t.__vaniDomRef.current=null),n.remove(),n=e}}function C(e,t){let n=[],r=e.nextSibling;for(;r&&r!==t;)n.push(r),r=r.nextSibling;return n}function de(e){if(e==null||e===!1)return document.createComment(`vani:empty`);if(T(e)){let t=document.createDocumentFragment(),n=w(e.component,E(e),t);return e.ref&&(e.ref.current=n),t}if(typeof e==`string`||typeof e==`number`)return document.createTextNode(String(e));if(e instanceof Node)return e;throw Error(`[vani] render returned an unsupported node type in DOM mode`)}function w(e,t,n,r){let i=[],a=[],o=!1,s=!1,c,l,u=null,d=t?.clientOnly===!0;if(q){let e=Y;Y+=1,c=ke(n,e),l=Ae(c,e)}else c=document.createComment(`vani:start`),l=document.createComment(`vani:end`),n.appendChild(c),n.appendChild(l);let f,p={update(e){if(o)return;let t=p.__vaniUpdateOptions,n=e?.onlyAttributes?{onlyAttributes:!0}:{onlyAttributes:!1};(!t||!t.onlyAttributes||!n.onlyAttributes)&&(p.__vaniUpdateOptions=n),z?W.has(p)||(G.add(p),V>0?U=!0:K()):(G.delete(p),W.add(p),V>0?H=!0:De())},updateSync(e){if(o||!c.parentNode)return;let t=e??p.__vaniUpdateOptions;if(p.__vaniUpdateOptions=void 0,t?.onlyAttributes&&u){let e=F;F=!0;let t;try{t=f()}finally{F=e}if(t instanceof Node){let e=O(t);if(e&&e.tagName===u.tagName){_e(u,e);return}}}S(c,l);let n=de(f()),r=O(n);if(l.before(n),u=r,!s&&(s=!0,a.length>0)){let e=c.parentNode,t=null,n=()=>t||(t=C(c,l),t),r=a.splice(0,a.length);for(let t of r){let r=t(n,e);typeof r==`function`&&i.push(r)}}},onCleanup(e){i.push(e)},dispose(){if(!o){o=!0,c.__vaniHandle=null,p.__vaniStart=null,p.__vaniEnd=null,W.delete(p),G.delete(p);for(let e of i)e();i.length=0,S(c,l),c.remove(),l.remove(),f=(()=>document.createComment(`disposed`))}},onBeforeMount(e){let t=e();typeof t==`function`&&i.push(t)},onMount(e){if(!o){if(s){queueMicrotask(()=>{if(o)return;let t=c.parentNode,n=null,r=e(()=>n||(n=C(c,l),n),t);typeof r==`function`&&i.push(r)});return}a.push(e)}}};if(p.__vaniStart=c,p.__vaniEnd=l,c.__vaniHandle=p,q&&!d){let n=!1;return f=()=>{if(!n){n=!0;let r=e(t,p);f=r instanceof Promise?()=>document.createComment(`async`):r}return f()},p}let m=e(t,p);return m instanceof Promise?(f=t?.fallback||(()=>document.createComment(`vani:async`)),(!q||d)&&(r?.initialRender===`sync`?p.updateSync():p.update()),m.then(e=>{o||(f=e,p.update())}).catch(e=>{o||(console.error(`[vani] async component failed:`,e),queueMicrotask(()=>{throw e}))}),p):(f=m,(!q||d)&&(r?.initialRender===`sync`?p.updateSync():p.update()),p)}function fe(e){return Array.isArray(e)?e:[e]}function pe(e,t){if(!t)throw Error(`[vani] root element not found`);globalThis.Vani$$=!0;let n=[],r=fe(e);for(let e of r){if(typeof e==`function`){if(e.$$vaniWrapped){let r=e(),i=w(r.component,E(r),t);n.push(i);continue}let r=w(e,{},t);n.push(r);continue}let r=w(e.component,E(e),t);n.push(r)}return n}function me(e){if(!e)throw Error(`[vani] container element not found`);globalThis.Vani$$=!0;let t=[],n=!1;return{render(r){if(n)throw Error(`[vani] Cannot render to an unmounted root. Create a new root instead.`);for(let e of t)e.dispose();t=[],e.innerHTML=``;let i=fe(r);for(let n of i){if(typeof n==`function`){if(n.$$vaniWrapped){let r=n(),i=w(r.component,E(r),e);t.push(i);continue}let r=w(n,{},e);t.push(r);continue}let r=w(n.component,E(n),e);t.push(r)}},unmount(){if(!n){n=!0;for(let e of t)e.dispose();t=[],e.innerHTML=``}}}}function T(e){let t=typeof Node<`u`&&e instanceof Node;if(typeof e!=`object`||t)return!1;let n=e;return n.$$vani===`component`&&typeof n.component==`function`}function he(e){let t=typeof Node<`u`&&e instanceof Node;return typeof e==`object`&&!!e&&!t&&!T(e)&&!v(e)}function E(e){return e.clientOnly?{...e.props??{},clientOnly:!0}:e.props}function ge(e){let t=e.__vaniStart,n=e.__vaniEnd;return!t||!n?null:{start:t,end:n}}function D(e,t,n,r=null){let i=document.createDocumentFragment(),a=t;for(;a;){let e=a.nextSibling;if(i.appendChild(a),a===n)break;a=e}e.insertBefore(i,r)}function O(e){if(e.nodeType===Node.ELEMENT_NODE)return e;if(e.nodeType===Node.DOCUMENT_FRAGMENT_NODE){let t=e.firstChild;if(t&&t.nodeType===Node.ELEMENT_NODE&&t.nextSibling===null)return t}return null}function _e(e,t){let n=new Set(t.getAttributeNames());for(let t of e.getAttributeNames())n.has(t)||e.removeAttribute(t);for(let r of n){let n=t.getAttribute(r);e.getAttribute(r)!==n&&(n===null?e.removeAttribute(r):e.setAttribute(r,n))}}function k(e,t){if(e.props===t)return!1;if(!e.props||typeof e.props!=`object`||!t||typeof t!=`object`)return e.props=t,!0;let n=!1,r=e.props,i=t;for(let e in r)e in i||(delete r[e],n=!0);for(let e in i)r[e]!==i[e]&&(r[e]=i[e],n=!0);return n}function A(e,t,n=null){let r=document.createDocumentFragment(),i=w(t.component,E(t),r,{initialRender:`sync`});t.ref&&(t.ref.current=i);let a=ge(i)??void 0,o={component:t.component,handle:i,fragment:r,ref:t.ref,props:t.props,start:a?.start,end:a?.end};return e.insertBefore(r,n),o}function j(e){let t=[];for(let n of e)Array.isArray(n)?t.push(...j(n)):t.push(n);return t}function M(e,n){let r=j(n);if(t()===`ssr`){for(let t of r)if(!(t==null||t===!1||t===void 0)){if(T(t)){x(e,{type:`component`,instance:t});continue}if(typeof t==`string`||typeof t==`number`){x(e,b(String(t)));continue}if(!Array.isArray(t)&&v(t)){x(e,t);continue}}return}let i=e;for(let e of r)if(!(e==null||e===!1||e===void 0)){if(T(e)){if(e.key!=null){let t=g(i),n=i.__vaniUsedKeys??=new Set,r=t.get(e.key);r&&r.component!==e.component&&(r.handle.dispose(),r.ref&&(r.ref.current=null),t.delete(e.key),r=void 0),r?(r.ref!==e.ref&&(r.ref&&(r.ref.current=null),r.ref=e.ref),r.ref&&(r.ref.current=r.handle),k(r,e.props)&&r.handle.update(),r.start&&r.end&&D(i,r.start,r.end)):(r=A(i,e,null),t.set(e.key,r)),n.add(e.key);continue}let t=document.createDocumentFragment(),n=w(e.component,E(e),t);e.ref&&(e.ref.current=n),i.appendChild(t);continue}if(typeof e==`string`||typeof e==`number`){i.appendChild(document.createTextNode(String(e)));continue}Array.isArray(e)||i.appendChild(e)}let a=i.__vaniKeyed,o=i.__vaniUsedKeys;if(a&&o){for(let[e,t]of a)o.has(e)||(t.handle.dispose(),t.ref&&(t.ref.current=null),a.delete(e));o.clear()}}function ve(e,n){if(t()===`ssr`)throw Error(`[vani] renderKeyedChildren is not supported in SSR mode`);let r=e,i=g(r),a=r.__vaniUsedKeys??=new Set,o=r.firstChild;for(let e of n){if(!T(e)||e.key==null)continue;let t=i.get(e.key);t&&t.component!==e.component&&(t.handle.dispose(),t.ref&&(t.ref.current=null),i.delete(e.key),t=void 0);let n=t==null;if(n)t=A(r,e,o),i.set(e.key,t);else{let n=t;n.ref!==e.ref&&(n.ref&&(n.ref.current=null),n.ref=e.ref),n.ref&&(n.ref.current=n.handle),k(n,e.props)&&n.handle.update(),t=n}let s=t;s.start&&s.end&&(!n&&o&&s.start!==o&&D(r,s.start,s.end,o),o=s.end.nextSibling),a.add(e.key)}for(let[e,t]of i)a.has(e)||(t.handle.dispose(),t.ref&&(t.ref.current=null),i.delete(e));a.clear()}function ye(e){return typeof SVGElement<`u`&&e instanceof SVGElement}function N(e,t){return e.startsWith(`aria`)?`aria-`+e.replace(`aria-`,``).replace(`aria`,``).toLowerCase():e.startsWith(`data`)?`data-`+e.replace(`data-`,``).replace(`data`,``):e.toLowerCase()===`htmlfor`?`for`:t?e:e.toLowerCase()}r({getRenderMode:t,createTextNode:e=>b(e),addNodeCleanup:le,classNames:P,normalizeAttrKey:N});function be(e,t){if(`class`in t&&`className`in t)throw Error(`[vani] Cannot use both "class" and "className" on the same element. Use one or the other.`);let n=y(e)?se.has(e.tag):ye(e);for(let r in t){let i=t[r];if(![`key`,`ref`].includes(r)){if(r===`className`||r===`class`){let t=P(i);y(e)?e.props.class=t:n?e.setAttribute(`class`,t):e.className=t;continue}if(r.startsWith(`on`)&&typeof i==`function`)y(e)||(e[r.toLowerCase()]=i);else if(r===`value`||r===`checked`||r===`selected`)y(e)?e.props[r]=String(i):e[r]=i;else if(i===!0)y(e)?e.props[r]=!0:e.setAttribute(r,``);else if(i===!1||i==null)continue;else{let t=N(r,n);y(e)?e.props[t]=String(i):e.setAttribute(t,String(i))}}}}function P(...e){return e.map(e=>{if(!(e==null||e===``))return typeof e==`string`?e.trim():Array.isArray(e)?P(...e):Object.entries(e).filter(([e,t])=>t).map(([e])=>e.trim()).join(` `).trim()}).filter(Boolean).join(` `)}let F=!1;const xe={select:[`value`]};function Se(e,t){let n=xe[e];if(!n)return{cleanProps:t,deferred:{}};let r={},i=!1;for(let e of n)e in t&&t[e]!==void 0&&(r[e]=t[e],i=!0);if(!i)return{cleanProps:t,deferred:{}};let a={...t};for(let e of n)delete a[e];return{cleanProps:a,deferred:r}}function Ce(e,t){if(!y(e))for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r)}function I(e,t,...n){let r=ce(e);if(he(t)){t.ref&&(!y(r)&&!F?(t.ref.current=r,r.__vaniDomRef=t.ref):t.ref.current=null);let{cleanProps:i,deferred:a}=Se(e,t);return be(r,i),F||M(r,n),Ce(r,a),r}return M(r,[t,...n]),r}const L=(...e)=>{if(t()===`ssr`){let t={type:`fragment`,children:[]};return M(t,e),t}let n=document.createDocumentFragment();return M(n,e),n};function we(e,n){if(t()===`ssr`)return{type:`component`,instance:{$$vani:`component`,component:e,props:n}};let r=document.createDocumentFragment();return w(e,n,r),r}let R=!1,z=!1,B=!1,V=0,H=!1,U=!1;const W=new Set,G=new Set;function Te(e){let t=z;z=!0;try{e()}finally{z=t,V>0?U=!0:K()}}function Ee(e){V+=1;try{e()}finally{--V,V===0&&(H&&(H=!1,De()),U&&(U=!1,K()))}}function K(){B||(B=!0,setTimeout(()=>{B=!1,Oe()},0))}function De(){R||(R=!0,queueMicrotask(()=>{R=!1;for(let e of W)e.updateSync(e.__vaniUpdateOptions);W.clear()}))}function Oe(){for(let e of G)e.updateSync(e.__vaniUpdateOptions);G.clear(),G.size>0&&K()}let q=!1,J=null,Y=0;function X(e){Z()&&console.warn(`[vani] hydration warning: ${e}`)}function ke(e,t){let n=J;(!n||!e.contains(n))&&(n=e.firstChild);let r=!1;for(;n;){if(n.nodeType===Node.COMMENT_NODE&&n.nodeValue===`vani:start`)return r&&X(`Found <!--vani:end--> before <!--vani:start--> for component #${t}. This usually means the server HTML anchor order is incorrect.`),n;n.nodeType===Node.COMMENT_NODE&&n.nodeValue===`vani:end`&&(r=!0),n=n.nextSibling}throw X(`Expected <!--vani:start--> for component #${t}, but none was found. This usually means the server HTML does not match the client component tree.`),new h(`[vani] hydration failed: start anchor not found`)}function Ae(e,t){let n=e.nextSibling,r=0;for(;n;){if(n.nodeType===Node.COMMENT_NODE){if(n.nodeValue===`vani:start`)r+=1;else if(n.nodeValue===`vani:end`){if(r===0)return J=n.nextSibling,n;--r}}n=n.nextSibling}throw X(`Expected <!--vani:end--> for component #${t}, but none was found. This usually means the server HTML does not match the client component tree.`),new h(`[vani] hydration failed: end anchor not found`)}function je(e,t){let n=[];q=!0,J=t.firstChild,Y=0;try{n=pe(e,t)}catch(e){if(e instanceof h)console.error(`[vani] hydration failed:`,e);else throw e}finally{if(Z()&&J){let e=J,t=!1;for(;e;){if(e.nodeType===Node.COMMENT_NODE){let n=e.nodeValue;if(n===`vani:start`||n===`vani:end`){t=!0;break}}e=e.nextSibling}t&&X(`Unused SSR anchors detected after hydration. Some server-rendered DOM was not claimed by the client runtime.`)}q=!1,J=null,Y=0}return n}function Z(){return`__vaniDevMode`in globalThis?globalThis.__vaniDevMode===!0:import.meta.env?import.meta.env.DEV:typeof process<`u`&&process.env!==void 0?process.env.NODE_ENV===`development`:!1}const Q=Symbol.for(`vani.fragment`);function Me(e){return e==null||e===!1?[]:Array.isArray(e)?e:[e]}function Ne(e,t){if(!e||typeof e!=`object`)return{props:null,children:[],key:t,ref:void 0,hasChildrenProp:!1};let n=Object.prototype.hasOwnProperty.call(e,`children`),r=n?Me(e.children):[],i=t??e.key,a=e.ref,{key:o,ref:s,children:c,...l}=e;return{props:Object.keys(l).length>0?l:null,children:r,key:i,ref:a,hasChildrenProp:n}}function $(e,t,n){let{props:r,children:i,key:a,ref:o,hasChildrenProp:s}=Ne(t,n);if(e===Q)return L(...i);if(typeof e==`string`){let t=o==null?r:{...r??{},ref:o};return t?I(e,t,...i):I(e,null,...i)}if(typeof e==`function`){let t={...r??{}};return(i.length>0||s)&&(t.children=i.length<=1?i[0]:i),a!=null&&(t.key=a),o&&(t.ref=o),e.$$vaniWrapped?e(t):_(e)(t)}throw Error(`[vani] jsx runtime received an unsupported element type.`)}const Pe=$;function Fe(e,t,n,r,i,a){return $(e,t,n)}export{n as A,ee as C,r as D,te as E,t as O,m as S,f as T,ve as _,h as a,ae as b,_ as c,L as d,je as f,re as g,we as h,Pe as i,i as k,me as l,Z as m,$ as n,Ee as o,T as p,Fe as r,P as s,Q as t,I as u,pe as v,p as w,ne as x,Te as y};
|
|
2
|
+
//# sourceMappingURL=jsx-runtime-Bbqe4zqZ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsx-runtime-Bbqe4zqZ.mjs","names":[],"sources":["../../src/vani/common.ts","../../src/vani/signals.ts","../../src/vani/runtime.ts","../../src/vani/jsx-runtime.ts"],"sourcesContent":["export type ClassName =\n | string\n | undefined\n | null\n | {\n [key: string]: boolean | undefined | null\n }\n | ClassName[]\n\nexport type RenderMode = 'dom' | 'ssr'\n\nexport type AttrValue = ClassName | string | number | boolean | null | undefined\nexport type TextNode = Node | { type: 'text'; text: string }\n\ntype StaticSettings = {\n renderMode: RenderMode\n domAdapter: SignalDomAdapter | null\n}\ntype SignalDomAdapter = {\n getRenderMode: () => 'dom' | 'ssr'\n createTextNode: (text: string) => TextNode\n addNodeCleanup: (node: Node, cleanup: () => void) => void\n classNames: (...classes: ClassName[]) => string\n normalizeAttrKey: (key: string, isSvg: boolean) => string\n}\n\nconst staticSettings: StaticSettings = {\n renderMode: 'dom',\n domAdapter: null,\n}\n\nexport function getRenderMode(): RenderMode {\n return staticSettings.renderMode\n}\n\nexport function setRenderMode(mode: RenderMode): void {\n staticSettings.renderMode = mode\n}\n\nexport function configureSignalDom(adapter: SignalDomAdapter): void {\n staticSettings.domAdapter = adapter\n}\n\nexport function getSignalDomAdapter(): SignalDomAdapter | null {\n return staticSettings.domAdapter\n}\n","import {\n getRenderMode,\n getSignalDomAdapter,\n type AttrValue,\n type ClassName,\n type TextNode,\n} from './common'\n\nexport type SignalGetter<T> = () => T\nexport type SignalSetter<T> = (value: T | ((prev: T) => T)) => void\nexport type Signal<T> = [SignalGetter<T>, SignalSetter<T>]\n\ntype SignalRecord<T> = {\n value: T\n observers: Set<SignalObserver>\n}\n\ntype SignalObserver = {\n fn: () => void | (() => void)\n deps: Set<SignalRecord<any>>\n cleanup?: () => void\n disposed: boolean\n}\n\nlet currentObserver: SignalObserver | null = null\nconst observerQueue = new Set<SignalObserver>()\nlet observerFlushScheduled = false\n\nfunction trackSignal(record: SignalRecord<any>) {\n if (!currentObserver || currentObserver.disposed) return\n if (!currentObserver.deps.has(record)) {\n currentObserver.deps.add(record)\n record.observers.add(currentObserver)\n }\n}\n\nfunction cleanupObserver(observer: SignalObserver) {\n for (const record of observer.deps) {\n record.observers.delete(observer)\n }\n observer.deps.clear()\n if (observer.cleanup) {\n observer.cleanup()\n observer.cleanup = undefined\n }\n}\n\nfunction runObserver(observer: SignalObserver) {\n if (observer.disposed) return\n cleanupObserver(observer)\n const prev = currentObserver\n currentObserver = observer\n const cleanup = observer.fn()\n currentObserver = prev\n if (typeof cleanup === 'function') {\n observer.cleanup = cleanup\n }\n}\n\nfunction scheduleObserver(observer: SignalObserver) {\n if (observer.disposed) return\n observerQueue.add(observer)\n if (observerFlushScheduled) return\n observerFlushScheduled = true\n queueMicrotask(() => {\n observerFlushScheduled = false\n const queued = Array.from(observerQueue)\n observerQueue.clear()\n for (const next of queued) {\n runObserver(next)\n }\n })\n}\n\nexport function signal<T>(value: T): Signal<T> {\n const record: SignalRecord<T> = {\n value,\n observers: new Set(),\n }\n\n const getter: SignalGetter<T> = () => {\n trackSignal(record)\n return record.value\n }\n\n const setter: SignalSetter<T> = (next) => {\n const resolved = typeof next === 'function' ? (next as (prev: T) => T)(record.value) : next\n if (Object.is(resolved, record.value)) return\n record.value = resolved\n for (const observer of record.observers) {\n scheduleObserver(observer)\n }\n }\n\n return [getter, setter]\n}\n\nexport function effect(fn: () => void | (() => void)): () => void {\n if (getRenderMode() === 'ssr') {\n fn()\n return () => {}\n }\n return createEffect(fn)\n}\n\nexport function createEffect(fn: () => void | (() => void)): () => void {\n const observer: SignalObserver = {\n fn,\n deps: new Set(),\n disposed: false,\n }\n\n runObserver(observer)\n\n return () => {\n if (observer.disposed) return\n observer.disposed = true\n cleanupObserver(observer)\n }\n}\n\nexport function derive<T>(fn: () => T): SignalGetter<T> {\n const [get, set] = signal(fn())\n createEffect(() => {\n set(fn())\n })\n return get\n}\n\nexport function text(value: SignalGetter<unknown> | (() => unknown) | unknown): TextNode {\n const resolve = () => (typeof value === 'function' ? (value as () => unknown)() : value)\n const textValue = String(resolve() ?? '')\n const adapter = getSignalDomAdapter()\n if (!adapter) {\n if (typeof document !== 'undefined') {\n return document.createTextNode(textValue)\n }\n return { type: 'text', text: textValue }\n }\n\n const node = adapter.createTextNode(textValue)\n if (adapter.getRenderMode() === 'ssr') {\n return node\n }\n\n if (typeof value === 'function') {\n const textNode = node as Text\n const dispose = createEffect(() => {\n textNode.textContent = String(resolve() ?? '')\n })\n getSignalDomAdapter()?.addNodeCleanup(textNode, dispose)\n }\n\n return node as TextNode\n}\n\nexport function attr(\n el: Element,\n name: string,\n value: SignalGetter<AttrValue> | (() => AttrValue) | AttrValue,\n) {\n const adapter = getSignalDomAdapter()\n if (!adapter) return () => {}\n if (adapter.getRenderMode() === 'ssr') return () => {}\n if (name.startsWith('on')) return () => {}\n\n const isSvg = el instanceof SVGElement\n const key = name === 'className' ? 'class' : adapter.normalizeAttrKey(name, isSvg)\n\n const apply = (nextValue: AttrValue) => {\n if (key === 'class') {\n const classValue = adapter.classNames(nextValue as ClassName)\n if (!classValue) {\n el.removeAttribute('class')\n return\n }\n el.setAttribute('class', classValue)\n return\n }\n\n if (nextValue === true) {\n el.setAttribute(key, '')\n return\n }\n\n if (nextValue === false || nextValue == null) {\n el.removeAttribute(key)\n return\n }\n\n el.setAttribute(key, String(nextValue))\n }\n\n if (typeof value === 'function') {\n const disposer = createEffect(() => {\n apply((value as () => AttrValue)())\n })\n adapter.addNodeCleanup(el, disposer)\n return disposer\n }\n\n apply(value as AttrValue)\n return () => {}\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable unicorn/prefer-dom-node-append */\n/* eslint-disable @typescript-eslint/ban-ts-comment */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable unicorn/no-negated-condition */\n\nimport {\n configureSignalDom,\n getRenderMode,\n setRenderMode,\n type ClassName,\n type RenderMode,\n type TextNode,\n} from './common'\nimport { createEffect } from './signals'\n\n// ─────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────\n\nexport type SSRNode =\n | {\n type: 'element'\n tag: string\n props: Record<string, any>\n children: SSRNode[]\n }\n | { type: 'text'; text: string }\n | { type: 'comment'; text: string }\n | { type: 'fragment'; children: SSRNode[] }\n | { type: 'component'; instance: ComponentInstance<any> }\n\nexport type VNode = Node | SSRNode\n\nexport class HydrationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'HydrationError'\n }\n}\n\nexport interface Handle {\n /**\n * Schedules a render for the component.\n * This triggers a re-render on the next microtask.\n */\n update(options?: UpdateOptions): void\n /**\n * Flushes the component render.\n * This triggers a re-render immediately.\n */\n updateSync(options?: UpdateOptions): void\n /**\n * Disposes the component: removes the component from the DOM and runs all cleanup functions.\n */\n dispose(): void\n /**\n * Adds a cleanup function that is called when the component is disposed.\n */\n onCleanup(fn: () => void): void\n /**\n * This is purely syntatic sugar, as it is basically the same as running the function\n * on the setup phase and calling onCleanup to add a cleanup function.\n *\n * Using onBeforeMount is necessary in SSR mode, for side effects to not run on the server\n * (e.g. timers, subscriptions, DOM usage, etc.)\n *\n * Runs a side effect function during component setup, before the first render.\n * The returning function may be a cleanup function that is called when the component is disposed.\n *\n */\n onBeforeMount(fn: () => void | (() => void)): void\n /**\n * Runs after the first render, once the component's nodes are in the DOM.\n * The first argument is a lazy getter for the mounted nodes, so it only traverses\n * the DOM if called. The second argument is the parent mount point.\n * The returning function may be a cleanup function that is called when the component is disposed.\n */\n onMount(fn: (getNodes: () => Node[], parent: Node | null) => void | (() => void)): void\n}\n\nexport type RenderFn = () => VChild\n\nexport type Component<Props = any> = (props: Props, handle: Handle) => RenderFn | Promise<RenderFn>\n\n// Component instance descriptor (returned by component())\nexport type ComponentInstance<Props = any> = {\n $$vani: 'component'\n component: Component<Props>\n props: Props\n /**\n * A key is used to identify the component when it is re-rendered.\n * If a key is provided, the component will be re-rendered only if the key changes.\n */\n key?: string | number\n /**\n * A ref is used to get a reference to the component instance.\n * The ref is set to the component instance when the component is mounted.\n * The ref is set to null when the component is disposed.\n */\n ref?: ComponentRef\n clientOnly?: boolean\n}\n\nexport type ComponentInput<Props> = Props & {\n key?: string | number\n ref?: ComponentRef\n}\n\ntype ComponentMetaProps = {\n key?: string | number\n ref?: ComponentRef\n fallback?: RenderFn\n clientOnly?: boolean\n}\n\nexport type VChild =\n | VNode\n | ComponentInstance<any>\n | string\n | number\n | null\n | undefined\n | false\n | VChild[]\n\nexport type DataAttribute = `data-${string}` | `data${Capitalize<string>}`\n\ntype HtmlTagName = keyof HTMLElementTagNameMap\ntype SvgTagName = keyof SVGElementTagNameMap\ntype ElementTagName = HtmlTagName | SvgTagName\n\ntype ElementByTag<T extends ElementTagName> = T extends HtmlTagName\n ? HTMLElementTagNameMap[T]\n : T extends SvgTagName\n ? SVGElementTagNameMap[T]\n : Element\n\nexport type SvgProps<T extends SvgTagName = SvgTagName> = BaseProps<T> & {\n [key: string]: unknown\n}\n\ntype BaseProps<T extends ElementTagName> = (\n | {\n class?: ClassName\n className?: never\n style?: string\n ref?: DomRef<ElementByTag<T>>\n }\n | {\n class?: never\n className?: ClassName\n style?: string\n ref?: DomRef<ElementByTag<T>>\n }\n) & {\n [key: DataAttribute]: string | number | boolean | undefined | null\n}\n\nexport type HtmlProps<T extends HtmlTagName = HtmlTagName> = BaseProps<T> &\n Partial<Omit<ElementByTag<T>, 'children' | 'className' | 'style'>>\n\nexport type ElementProps<T extends ElementTagName> = T extends SvgTagName\n ? SvgProps<T>\n : HtmlProps<Extract<T, HtmlTagName>>\n\ntype KeyedRecord = {\n handle: Handle\n fragment: DocumentFragment\n ref?: ComponentRef\n component: Component<any>\n props: unknown\n start?: Comment\n end?: Comment\n}\n\nexport type ComponentRef = {\n current: Handle | null\n}\n\nexport type DomRef<T extends Element = Element> = {\n current: T | null\n}\n\nexport type UpdateOptions = {\n onlyAttributes?: boolean\n}\n\n// ─────────────────────────────────────────────\n// component() helper\n// ─────────────────────────────────────────────\n\nfunction getKeyedMap(parent: Node): Map<string | number, KeyedRecord> {\n const anyParent = parent as any\n if (!anyParent.__vaniKeyed) {\n anyParent.__vaniKeyed = new Map()\n }\n return anyParent.__vaniKeyed\n}\n\nexport function component(\n fn: Component<void>,\n): (props?: ComponentMetaProps) => ComponentInstance<void>\nexport function component<Props>(\n fn: Component<Props>,\n): (props: Props & ComponentMetaProps) => ComponentInstance<Props>\nexport function component<Props>(fn: Component<Props>) {\n const wrapper = (input?: ComponentInput<Props>): ComponentInstance<Props> => {\n let key: string | number | undefined\n let ref: ComponentRef | undefined\n let clientOnly = false\n let props = input as Props\n\n if (input && typeof input === 'object') {\n const anyInput = input as any\n key = anyInput.key\n ref = anyInput.ref\n clientOnly = anyInput.clientOnly\n if ('key' in anyInput || 'ref' in anyInput) {\n const { key: _, ref: __, clientOnly: ___, ...rest } = anyInput\n props = rest\n }\n }\n\n return {\n $$vani: 'component',\n component: fn,\n props,\n key,\n ref,\n clientOnly,\n }\n }\n\n // Mark as wrapped component for JSX runtime detection\n ;(wrapper as any).$$vaniWrapped = true\n\n return wrapper\n}\n\n/**\n * Creates a reactive component that auto-tracks signal reads and re-renders when signals change.\n *\n * This is the only \"magic\" in Vani - signals read during render are automatically tracked,\n * and when any tracked signal changes, the component re-renders.\n *\n * @example\n * ```tsx\n * const [count, setCount] = signal(0)\n *\n * const Counter = reactive((props, handle) => {\n * return () => <div>Count: {count()}</div>\n * })\n * ```\n */\nexport function reactive(\n fn: Component<void>,\n): (props?: ComponentMetaProps) => ComponentInstance<void>\nexport function reactive<Props>(\n fn: Component<Props>,\n): (props: Props & ComponentMetaProps) => ComponentInstance<Props>\nexport function reactive<Props>(fn: Component<Props>) {\n const reactiveComponent: Component<Props> = (props, handle) => {\n const render = fn(props, handle)\n\n // Handle async components\n if (render instanceof Promise) {\n return render.then((renderFn) => {\n return wrapRenderWithEffect(renderFn, handle)\n })\n }\n\n return wrapRenderWithEffect(render, handle)\n }\n\n return component(reactiveComponent)\n}\n\nfunction wrapRenderWithEffect(render: RenderFn, handle: Handle): RenderFn {\n let disposeEffect: (() => void) | undefined\n let isFirstRun = true\n\n handle.onBeforeMount(() => {\n disposeEffect = createEffect(() => {\n // Run render to track signal dependencies\n render()\n\n if (isFirstRun) {\n isFirstRun = false\n return\n }\n\n // On subsequent runs, trigger component update\n handle.update()\n })\n\n return disposeEffect\n })\n\n return render\n}\n\n// ─────────────────────────────────────────────\n// Render mode (DOM vs SSR)\n// ─────────────────────────────────────────────\n\nexport function withRenderMode<T>(mode: RenderMode, fn: () => T): T {\n const prev = getRenderMode()\n setRenderMode(mode)\n const result = fn()\n if (result && typeof (result as unknown as Promise<unknown>).finally === 'function') {\n return (result as unknown as Promise<unknown>).finally(() => {\n setRenderMode(prev)\n }) as T\n }\n setRenderMode(prev)\n return result\n}\n\nfunction isSsrNode(node: VNode): node is SSRNode {\n if (typeof node !== 'object' || node === null || !('type' in node)) {\n return false\n }\n\n const anyNode = node as SSRNode\n switch (anyNode.type) {\n case 'element':\n return (\n typeof anyNode.tag === 'string' &&\n typeof anyNode.props === 'object' &&\n Array.isArray(anyNode.children)\n )\n case 'text':\n case 'comment':\n return typeof anyNode.text === 'string'\n case 'fragment':\n return Array.isArray(anyNode.children)\n case 'component':\n return typeof anyNode.instance === 'object' && anyNode.instance != null\n default:\n return false\n }\n}\n\nfunction isSsrElement(node: VNode): node is Extract<SSRNode, { type: 'element' }> {\n return isSsrNode(node) && node.type === 'element'\n}\n\nfunction isSsrFragment(node: VNode): node is Extract<SSRNode, { type: 'fragment' }> {\n return isSsrNode(node) && node.type === 'fragment'\n}\n\nconst svgTags = new Set<string>([\n 'svg',\n 'g',\n 'path',\n 'circle',\n 'rect',\n 'line',\n 'polyline',\n 'polygon',\n 'ellipse',\n 'defs',\n 'clipPath',\n 'mask',\n 'pattern',\n 'linearGradient',\n 'radialGradient',\n 'stop',\n 'use',\n])\n\nfunction createElementNode(tag: string): VNode {\n if (getRenderMode() === 'dom') {\n if (svgTags.has(tag)) {\n return document.createElementNS('http://www.w3.org/2000/svg', tag)\n }\n return document.createElement(tag)\n }\n return { type: 'element', tag, props: {}, children: [] }\n}\n\nfunction createTextNode(text: string): VNode {\n if (getRenderMode() === 'dom') {\n return document.createTextNode(text)\n }\n return { type: 'text', text }\n}\n\nfunction appendChildNode(parent: VNode, child: VNode) {\n if (getRenderMode() === 'dom') {\n ;(parent as Node).appendChild(child as Node)\n return\n }\n\n if (isSsrElement(parent) || isSsrFragment(parent)) {\n parent.children.push(child as SSRNode)\n }\n}\n\nfunction addNodeCleanup(node: Node, cleanup: () => void) {\n const anyNode = node as any\n if (!anyNode.__vaniCleanup) {\n anyNode.__vaniCleanup = [cleanup]\n return\n }\n anyNode.__vaniCleanup.push(cleanup)\n}\n\nfunction runNodeCleanup(node: Node) {\n const anyNode = node as any\n const cleanups = anyNode.__vaniCleanup\n if (!Array.isArray(cleanups)) return\n anyNode.__vaniCleanup = null\n for (const cleanup of cleanups) {\n cleanup()\n }\n}\n\n// ─────────────────────────────────────────────\n// Internal helpers\n// ─────────────────────────────────────────────\n\nfunction clearBetween(start: Comment, end: Comment) {\n let node = start.nextSibling\n while (node && node !== end) {\n const next = node.nextSibling\n if (node.nodeType === Node.COMMENT_NODE && node.nodeValue === 'vani:start') {\n const handle = (node as any).__vaniHandle as Handle | undefined\n if (handle) {\n const endAnchor = (handle as any).__vaniEnd as Comment | undefined\n const afterDisposed = endAnchor?.nextSibling ?? next\n handle.dispose()\n node = afterDisposed\n continue\n }\n }\n runNodeCleanup(node)\n const anyNode = node as any\n if (anyNode.__vaniDomRef) {\n anyNode.__vaniDomRef.current = null\n }\n node.remove()\n node = next\n }\n}\n\nfunction getNodesBetween(start: Comment, end: Comment): Node[] {\n const nodes: Node[] = []\n let node = start.nextSibling\n while (node && node !== end) {\n nodes.push(node)\n node = node.nextSibling\n }\n return nodes\n}\n\n// ─────────────────────────────────────────────\n// Core mounting logic\n// ─────────────────────────────────────────────\n\nfunction normalizeDomChild(child: VChild): Node {\n if (child == null || child === false) {\n return document.createComment('vani:empty')\n }\n\n if (isComponentInstance(child)) {\n const fragment = document.createDocumentFragment()\n const handle = mountComponent(child.component, getMountProps(child), fragment)\n if (child.ref) {\n child.ref.current = handle\n }\n return fragment\n }\n\n if (typeof child === 'string' || typeof child === 'number') {\n return document.createTextNode(String(child))\n }\n\n if (child instanceof Node) {\n return child\n }\n\n throw new Error('[vani] render returned an unsupported node type in DOM mode')\n}\n\ntype MountOptions = {\n initialRender?: 'scheduled' | 'sync'\n}\n\nfunction mountComponent<Props>(\n component: Component<Props>,\n props: Props,\n parent: Node,\n options?: MountOptions,\n): Handle {\n const cleanups: Array<() => void> = []\n const mountCallbacks: Array<\n (getNodes: () => Node[], parent: Node | null) => void | (() => void)\n > = []\n let disposed = false\n let hasMounted = false\n let start: Comment\n let end: Comment\n let currentRootElement: Element | null = null\n\n // ─────────────────────────────────────────────\n // Anchor handling (hydration-aware)\n // ─────────────────────────────────────────────\n\n const clientOnly = (props as any)?.clientOnly === true\n\n if (isHydrating) {\n const componentIndex = hydrationComponentIndex\n hydrationComponentIndex += 1\n start = findNextStartAnchor(parent, componentIndex)\n end = findMatchingEndAnchor(start, componentIndex)\n } else {\n start = document.createComment('vani:start')\n end = document.createComment('vani:end')\n parent.appendChild(start)\n parent.appendChild(end)\n }\n\n let render!: RenderFn\n\n // ─────────────────────────────────────────────\n // Handle\n // ─────────────────────────────────────────────\n\n const handle: Handle = {\n update(options) {\n if (disposed) return\n\n const existingOptions = (handle as any).__vaniUpdateOptions as UpdateOptions | undefined\n const nextOptions = options?.onlyAttributes\n ? { onlyAttributes: true }\n : { onlyAttributes: false }\n if (!existingOptions || !existingOptions.onlyAttributes || !nextOptions.onlyAttributes) {\n ;(handle as any).__vaniUpdateOptions = nextOptions\n }\n\n if (inTransition) {\n if (!urgentQueue.has(handle)) {\n transitionQueue.add(handle)\n if (batchDepth > 0) {\n pendingTransitionFlush = true\n } else {\n scheduleTransitionFlush()\n }\n }\n } else {\n transitionQueue.delete(handle)\n urgentQueue.add(handle)\n if (batchDepth > 0) {\n pendingUrgentFlush = true\n } else {\n scheduleUrgentFlush()\n }\n }\n },\n\n updateSync(options) {\n if (disposed) return\n if (!start.parentNode) return\n\n const resolvedOptions =\n options ?? ((handle as any).__vaniUpdateOptions as UpdateOptions | undefined)\n ;(handle as any).__vaniUpdateOptions = undefined\n\n if (resolvedOptions?.onlyAttributes && currentRootElement) {\n const prevAttrMode = attributesOnlyMode\n attributesOnlyMode = true\n let nextChild: VChild\n try {\n nextChild = render()\n } finally {\n attributesOnlyMode = prevAttrMode\n }\n\n if (nextChild instanceof Node) {\n const nextElement = getSingleElementFromNode(nextChild)\n if (nextElement && nextElement.tagName === currentRootElement.tagName) {\n patchElementAttributes(currentRootElement, nextElement)\n return\n }\n }\n }\n\n clearBetween(start, end)\n const node = normalizeDomChild(render())\n const nextElement = getSingleElementFromNode(node)\n end.before(node)\n currentRootElement = nextElement\n\n if (!hasMounted) {\n hasMounted = true\n if (mountCallbacks.length > 0) {\n const parentNode = start.parentNode\n let cachedNodes: Node[] | null = null\n const getNodes = () => {\n if (cachedNodes) return cachedNodes\n cachedNodes = getNodesBetween(start, end)\n return cachedNodes\n }\n const callbacks = mountCallbacks.splice(0, mountCallbacks.length)\n for (const callback of callbacks) {\n const cleanup = callback(getNodes, parentNode)\n if (typeof cleanup === 'function') {\n cleanups.push(cleanup)\n }\n }\n }\n }\n },\n\n onCleanup(fn) {\n cleanups.push(fn)\n },\n\n dispose() {\n if (disposed) return\n disposed = true\n ;(start as any).__vaniHandle = null\n ;(handle as any).__vaniStart = null\n ;(handle as any).__vaniEnd = null\n\n urgentQueue.delete(handle)\n transitionQueue.delete(handle)\n\n for (const fn of cleanups) fn()\n cleanups.length = 0\n\n clearBetween(start, end)\n start.remove()\n end.remove()\n\n // prevent accidental reuse\n render = (() => document.createComment('disposed')) as any\n },\n\n onBeforeMount(fn) {\n const cleanup = fn()\n if (typeof cleanup === 'function') {\n cleanups.push(cleanup)\n }\n },\n\n onMount(fn) {\n if (disposed) return\n if (hasMounted) {\n queueMicrotask(() => {\n if (disposed) return\n const parentNode = start.parentNode\n let cachedNodes: Node[] | null = null\n const getNodes = () => {\n if (cachedNodes) return cachedNodes\n cachedNodes = getNodesBetween(start, end)\n return cachedNodes\n }\n const cleanup = fn(getNodes, parentNode)\n if (typeof cleanup === 'function') {\n cleanups.push(cleanup)\n }\n })\n return\n }\n mountCallbacks.push(fn)\n },\n }\n\n ;(handle as any).__vaniStart = start\n ;(handle as any).__vaniEnd = end\n ;(start as any).__vaniHandle = handle\n\n // ─────────────────────────────────────────────\n // Setup phase\n // ─────────────────────────────────────────────\n\n if (isHydrating && !clientOnly) {\n let initialized = false\n\n render = () => {\n if (!initialized) {\n initialized = true\n const result = component(props, handle)\n render = result instanceof Promise ? () => document.createComment('async') : result\n }\n return render()\n }\n\n return handle\n }\n\n const result = component(props, handle)\n\n // ─────────────────────────────────────────────\n // Async component\n // ─────────────────────────────────────────────\n\n if (result instanceof Promise) {\n const fallback = (props as any)?.fallback\n render = fallback ? fallback : () => document.createComment('vani:async')\n\n // initial render only if not hydrating or clientOnly\n if (!isHydrating || clientOnly) {\n if (options?.initialRender === 'sync') {\n handle.updateSync()\n } else {\n handle.update()\n }\n }\n\n result\n .then((realRender) => {\n if (disposed) return\n render = realRender\n handle.update()\n })\n .catch((error) => {\n if (disposed) return\n console.error('[vani] async component failed:', error)\n queueMicrotask(() => {\n throw error\n })\n })\n\n return handle\n }\n\n // ─────────────────────────────────────────────\n // Sync component\n // ─────────────────────────────────────────────\n\n render = result\n\n // initial render only if not hydrating or clientOnly\n if (!isHydrating || clientOnly) {\n if (options?.initialRender === 'sync') {\n handle.updateSync()\n } else {\n handle.update()\n }\n }\n\n return handle\n}\n\n// ─────────────────────────────────────────────\n// Public render API\n// ─────────────────────────────────────────────\n\n// Wrapped component type (result of component())\ntype WrappedComponent<Props = any> = ((\n props?: Props & ComponentMetaProps,\n) => ComponentInstance<Props>) & { $$vaniWrapped?: true }\n\ntype Renderable = Component<any> | ComponentInstance<any> | WrappedComponent<any>\n\nfunction normalizeRenderables(input: Renderable | Renderable[]): Renderable[] {\n return Array.isArray(input) ? input : [input]\n}\n\nexport function renderToDOM(components: Renderable | Renderable[], root: HTMLElement): Handle[] {\n if (!root) {\n throw new Error('[vani] root element not found')\n }\n\n // flag to indicate that Vani is being used in the browser\n ;(globalThis as any).Vani$$ = true\n\n const handles: Handle[] = []\n const normalized = normalizeRenderables(components)\n for (const Comp of normalized) {\n if (typeof Comp === 'function') {\n // Check if it's a wrapped component (created with component())\n if ((Comp as any).$$vaniWrapped) {\n const instance = (Comp as WrappedComponent)()\n const handle = mountComponent(instance.component, getMountProps(instance), root)\n handles.push(handle)\n continue\n }\n // raw component (no props)\n const handle = mountComponent(Comp as Component<any>, {} as any, root)\n handles.push(handle)\n continue\n }\n\n // ComponentInstance descriptor\n const handle = mountComponent(Comp.component, getMountProps(Comp), root)\n handles.push(handle)\n }\n\n return handles\n}\n\n// ─────────────────────────────────────────────\n// createRoot helper\n// ─────────────────────────────────────────────\n\nexport type Root = {\n /**\n * Renders a component into the root container.\n * Clears any existing content before rendering.\n * Can be called multiple times to replace the rendered content.\n */\n render(component: Renderable): void\n /**\n * Unmounts the rendered content and cleans up all resources.\n * After calling unmount(), the root cannot be used again.\n */\n unmount(): void\n}\n\n/**\n * Creates a root for rendering Vani components.\n *\n * Similar to React's createRoot API, this provides a clean way to manage\n * component lifecycle with automatic container clearing and proper cleanup.\n *\n * @example\n * ```ts\n * const root = createRoot(document.getElementById('app')!)\n * root.render(App())\n *\n * // Later, to unmount:\n * root.unmount()\n * ```\n */\nexport function createRoot(container: HTMLElement): Root {\n if (!container) {\n throw new Error('[vani] container element not found')\n }\n\n // flag to indicate that Vani is being used in the browser\n ;(globalThis as any).Vani$$ = true\n\n let handles: Handle[] = []\n let unmounted = false\n\n const root: Root = {\n render(component: Renderable) {\n if (unmounted) {\n throw new Error('[vani] Cannot render to an unmounted root. Create a new root instead.')\n }\n\n // Dispose existing handles\n for (const handle of handles) {\n handle.dispose()\n }\n handles = []\n\n // Clear container content\n container.innerHTML = ''\n\n // Mount the new component\n const normalized = normalizeRenderables(component)\n for (const Comp of normalized) {\n if (typeof Comp === 'function') {\n if ((Comp as any).$$vaniWrapped) {\n const instance = (Comp as WrappedComponent)()\n const handle = mountComponent(instance.component, getMountProps(instance), container)\n handles.push(handle)\n continue\n }\n const handle = mountComponent(Comp as Component<any>, {} as any, container)\n handles.push(handle)\n continue\n }\n\n const handle = mountComponent(Comp.component, getMountProps(Comp), container)\n handles.push(handle)\n }\n },\n\n unmount() {\n if (unmounted) return\n\n unmounted = true\n for (const handle of handles) {\n handle.dispose()\n }\n handles = []\n container.innerHTML = ''\n },\n }\n\n return root\n}\n\n// ─────────────────────────────────────────────\n// DOM helpers\n// ─────────────────────────────────────────────\n\nexport function isComponentInstance(child: VChild): child is ComponentInstance<any> {\n const isDomNode = typeof Node !== 'undefined' && child instanceof Node\n if (typeof child !== 'object' || isDomNode) return false\n const instance = child as ComponentInstance<any>\n return instance.$$vani === 'component' && typeof instance.component === 'function'\n}\n\nfunction isHtmlProps(props: any): props is ElementProps<any> {\n const isDomNode = typeof Node !== 'undefined' && props instanceof Node\n return (\n props !== null &&\n typeof props === 'object' &&\n !isDomNode &&\n !isComponentInstance(props as VChild) &&\n !isSsrNode(props as VNode)\n )\n}\n\nfunction getMountProps<Props>(instance: ComponentInstance<Props>): Props {\n if (!instance.clientOnly) return instance.props\n const base = (instance.props ?? {}) as Record<string, any>\n return { ...base, clientOnly: true } as Props\n}\n\nfunction getHandleAnchors(handle: Handle): { start: Comment; end: Comment } | null {\n const start = (handle as any).__vaniStart as Comment | null | undefined\n const end = (handle as any).__vaniEnd as Comment | null | undefined\n if (!start || !end) return null\n return { start, end }\n}\n\nfunction moveAnchoredRange(\n parent: Node,\n start: Comment,\n end: Comment,\n before: ChildNode | null = null,\n) {\n const fragment = document.createDocumentFragment()\n let node: ChildNode | null = start\n while (node) {\n const nextNode: ChildNode | null = node.nextSibling\n fragment.appendChild(node)\n if (node === end) break\n node = nextNode\n }\n parent.insertBefore(fragment, before)\n}\n\nfunction getSingleElementFromNode(node: Node): Element | null {\n if (node.nodeType === Node.ELEMENT_NODE) {\n return node as Element\n }\n if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n const fragment = node as DocumentFragment\n const first = fragment.firstChild\n if (first && first.nodeType === Node.ELEMENT_NODE && first.nextSibling === null) {\n return first as Element\n }\n }\n return null\n}\n\nfunction patchElementAttributes(target: Element, source: Element) {\n const nextNames = new Set(source.getAttributeNames())\n for (const name of target.getAttributeNames()) {\n if (!nextNames.has(name)) {\n target.removeAttribute(name)\n }\n }\n for (const name of nextNames) {\n const value = source.getAttribute(name)\n if (target.getAttribute(name) !== value) {\n if (value === null) {\n target.removeAttribute(name)\n } else {\n target.setAttribute(name, value)\n }\n }\n }\n}\n\nfunction updateRecordProps(record: KeyedRecord, nextProps: unknown): boolean {\n if (record.props === nextProps) return false\n if (\n !record.props ||\n typeof record.props !== 'object' ||\n !nextProps ||\n typeof nextProps !== 'object'\n ) {\n record.props = nextProps\n return true\n }\n\n let changed = false\n const prev = record.props as Record<string, any>\n const next = nextProps as Record<string, any>\n\n for (const key in prev) {\n if (!(key in next)) {\n delete prev[key]\n changed = true\n }\n }\n\n for (const key in next) {\n if (prev[key] !== next[key]) {\n prev[key] = next[key]\n changed = true\n }\n }\n\n return changed\n}\n\nfunction mountKeyedRecord(\n domParent: Node,\n instance: ComponentInstance<any>,\n before: ChildNode | null = null,\n): KeyedRecord {\n const fragment = document.createDocumentFragment()\n const handle = mountComponent(instance.component, getMountProps(instance), fragment, {\n initialRender: 'sync',\n })\n if (instance.ref) {\n instance.ref.current = handle\n }\n const anchors = getHandleAnchors(handle) ?? undefined\n const record: KeyedRecord = {\n component: instance.component,\n handle,\n fragment,\n ref: instance.ref,\n props: instance.props,\n start: anchors?.start,\n end: anchors?.end,\n }\n domParent.insertBefore(fragment, before)\n return record\n}\n\n// Flatten nested arrays recursively\nfunction flattenChildren(children: VChild[]): VChild[] {\n const result: VChild[] = []\n for (const child of children) {\n if (Array.isArray(child)) {\n result.push(...flattenChildren(child as VChild[]))\n } else {\n result.push(child)\n }\n }\n return result\n}\n\nfunction appendChildren(parent: VNode, children: VChild[]) {\n // Auto-flatten arrays so users don't need fragment() for mapped children\n const flatChildren = flattenChildren(children)\n\n if (getRenderMode() === 'ssr') {\n for (const child of flatChildren) {\n if (child == null || child === false || child === undefined) continue\n\n if (isComponentInstance(child)) {\n appendChildNode(parent, { type: 'component', instance: child })\n continue\n }\n\n if (typeof child === 'string' || typeof child === 'number') {\n appendChildNode(parent, createTextNode(String(child)))\n continue\n }\n\n // Arrays are flattened above, this is just for type safety\n if (Array.isArray(child)) continue\n\n if (isSsrNode(child)) {\n appendChildNode(parent, child)\n continue\n }\n }\n\n return\n }\n\n const domParent = parent as Node\n for (const child of flatChildren) {\n if (child == null || child === false || child === undefined) continue\n\n if (isComponentInstance(child)) {\n // keyed component\n // Only components support keys, and that is the correct design:\n // - DOM elements don’t need identity, components do.\n // - React uses virtual DOM and diffing, but Vani uses the real DOM and is simpler and faster.\n // - forcing identity only where it matters keeps Vani simple, fast, and predictable\n if (child.key != null) {\n const keyedMap = getKeyedMap(domParent)\n const usedKeys = ((domParent as any).__vaniUsedKeys ??= new Set())\n\n let record = keyedMap.get(child.key)\n\n if (record && record.component !== child.component) {\n record.handle.dispose()\n if (record.ref) {\n record.ref.current = null\n }\n keyedMap.delete(child.key)\n record = undefined\n }\n\n if (!record) {\n record = mountKeyedRecord(domParent, child, null)\n keyedMap.set(child.key, record)\n } else {\n if (record.ref !== child.ref) {\n if (record.ref) record.ref.current = null\n record.ref = child.ref\n }\n if (record.ref) record.ref.current = record.handle\n if (updateRecordProps(record, child.props)) {\n record.handle.update()\n }\n if (record.start && record.end) {\n moveAnchoredRange(domParent, record.start, record.end)\n }\n }\n\n usedKeys.add(child.key)\n continue\n }\n\n // non-keyed component\n const fragment = document.createDocumentFragment()\n const handle = mountComponent(child.component, getMountProps(child), fragment)\n if (child.ref) {\n child.ref.current = handle\n }\n domParent.appendChild(fragment)\n continue\n }\n\n if (typeof child === 'string' || typeof child === 'number') {\n domParent.appendChild(document.createTextNode(String(child)))\n continue\n }\n\n // Arrays are flattened above, this is just for type safety\n if (Array.isArray(child)) continue\n\n domParent.appendChild(child as Node)\n }\n\n const keyedMap = (domParent as any).__vaniKeyed as Map<string | number, KeyedRecord> | undefined\n const usedKeys = (domParent as any).__vaniUsedKeys as Set<string | number> | undefined\n\n if (keyedMap && usedKeys) {\n for (const [key, record] of keyedMap) {\n if (!usedKeys.has(key)) {\n record.handle.dispose()\n if (record.ref) {\n record.ref.current = null\n }\n keyedMap.delete(key)\n }\n }\n usedKeys.clear()\n }\n}\n\nexport function renderKeyedChildren(parent: Node, children: Array<ComponentInstance<any>>): void {\n if (getRenderMode() === 'ssr') {\n throw new Error('[vani] renderKeyedChildren is not supported in SSR mode')\n }\n\n const domParent = parent as Node\n const keyedMap = getKeyedMap(domParent)\n const usedKeys = ((domParent as any).__vaniUsedKeys ??= new Set())\n let cursor: ChildNode | null = domParent.firstChild\n\n for (const child of children) {\n if (!isComponentInstance(child) || child.key == null) {\n continue\n }\n\n let record = keyedMap.get(child.key)\n\n if (record && record.component !== child.component) {\n record.handle.dispose()\n if (record.ref) {\n record.ref.current = null\n }\n keyedMap.delete(child.key)\n record = undefined\n }\n\n const isNewRecord = record == null\n if (isNewRecord) {\n record = mountKeyedRecord(domParent, child, cursor)\n keyedMap.set(child.key, record)\n } else {\n const existingRecord = record as KeyedRecord\n if (existingRecord.ref !== child.ref) {\n if (existingRecord.ref) existingRecord.ref.current = null\n existingRecord.ref = child.ref\n }\n if (existingRecord.ref) existingRecord.ref.current = existingRecord.handle\n if (updateRecordProps(existingRecord, child.props)) {\n existingRecord.handle.update()\n }\n record = existingRecord\n }\n\n const activeRecord = record as KeyedRecord\n if (activeRecord.start && activeRecord.end) {\n if (!isNewRecord && cursor && activeRecord.start !== cursor) {\n moveAnchoredRange(domParent, activeRecord.start, activeRecord.end, cursor)\n }\n cursor = activeRecord.end.nextSibling\n }\n\n usedKeys.add(child.key)\n }\n\n for (const [key, record] of keyedMap) {\n if (!usedKeys.has(key)) {\n record.handle.dispose()\n if (record.ref) {\n record.ref.current = null\n }\n keyedMap.delete(key)\n }\n }\n usedKeys.clear()\n}\n\nfunction isSvgElement(el: VNode): el is SVGElement {\n return typeof SVGElement !== 'undefined' && el instanceof SVGElement\n}\n\nfunction normalizeAttrKey(key: string, isSvg: boolean) {\n if (key.startsWith('aria')) {\n return 'aria-' + key.replace('aria-', '').replace('aria', '').toLowerCase()\n }\n if (key.startsWith('data')) {\n return 'data-' + key.replace('data-', '').replace('data', '')\n }\n if (key.toLowerCase() === 'htmlfor') {\n return 'for'\n }\n if (isSvg) return key\n return key.toLowerCase()\n}\n\nconfigureSignalDom({\n getRenderMode,\n createTextNode: (text: string) => createTextNode(text) as TextNode,\n addNodeCleanup,\n classNames,\n normalizeAttrKey,\n})\n\nfunction setProps(el: VNode, props: Record<string, any>) {\n // Check for class/className conflict\n if ('class' in props && 'className' in props) {\n throw new Error(\n '[vani] Cannot use both \"class\" and \"className\" on the same element. Use one or the other.',\n )\n }\n\n const isSvg = isSsrElement(el) ? svgTags.has(el.tag) : isSvgElement(el)\n for (const key in props) {\n const value = props[key]\n\n if (['key', 'ref'].includes(key)) {\n continue\n }\n\n // Handle both class and className (class is alias for className)\n if (key === 'className' || key === 'class') {\n const classValue = classNames(value)\n if (isSsrElement(el)) {\n el.props.class = classValue\n } else if (isSvg) {\n ;(el as SVGElement).setAttribute('class', classValue)\n } else {\n ;(el as HTMLElement).className = classValue\n }\n continue\n }\n\n if (key.startsWith('on') && typeof value === 'function') {\n if (!isSsrElement(el)) {\n ;(el as any)[key.toLowerCase()] = value\n }\n } else if (key === 'value' || key === 'checked' || key === 'selected') {\n // These properties must be set as DOM properties, not attributes\n if (!isSsrElement(el)) {\n ;(el as any)[key] = value\n } else {\n el.props[key] = String(value)\n }\n } else if (value === true) {\n if (isSsrElement(el)) {\n el.props[key] = true\n } else {\n ;(el as HTMLElement).setAttribute(key, '')\n }\n } else if (value === false || value == null) {\n continue\n } else {\n const normalizedKey = normalizeAttrKey(key, isSvg)\n if (isSsrElement(el)) {\n el.props[normalizedKey] = String(value)\n } else {\n ;(el as HTMLElement).setAttribute(normalizedKey, String(value))\n }\n }\n }\n}\n\nexport function classNames(...classes: ClassName[]): string {\n return classes\n .map((cls) => {\n if (cls === null || cls === undefined || cls === '') {\n return\n }\n if (typeof cls === 'string') {\n return cls.trim()\n }\n if (Array.isArray(cls)) {\n return classNames(...cls)\n }\n return Object.entries(cls)\n .filter(([_, value]) => value)\n .map(([key]) => key.trim())\n .join(' ')\n .trim()\n })\n .filter(Boolean)\n .join(' ')\n}\n\n// ─────────────────────────────────────────────\n// Element helpers\n// ─────────────────────────────────────────────\n\nlet attributesOnlyMode = false\n\n// Properties that must be set AFTER children are appended (e.g., select value needs options first)\nconst DEFERRED_PROPS: Record<string, string[]> = {\n select: ['value'],\n // Add other elements here if needed in the future\n}\n\ntype DeferredPropValues = Record<string, unknown>\n\nfunction extractDeferredProps(\n tag: string,\n props: Record<string, any>,\n): { cleanProps: Record<string, any>; deferred: DeferredPropValues } {\n const deferredKeys = DEFERRED_PROPS[tag]\n if (!deferredKeys) {\n return { cleanProps: props, deferred: {} }\n }\n\n const deferred: DeferredPropValues = {}\n let hasDeferred = false\n\n for (const key of deferredKeys) {\n if (key in props && props[key] !== undefined) {\n deferred[key] = props[key]\n hasDeferred = true\n }\n }\n\n if (!hasDeferred) {\n return { cleanProps: props, deferred: {} }\n }\n\n const cleanProps = { ...props }\n for (const key of deferredKeys) {\n delete cleanProps[key]\n }\n\n return { cleanProps, deferred }\n}\n\nfunction applyDeferredProps(node: VNode, deferred: DeferredPropValues): void {\n if (isSsrElement(node)) return\n\n for (const [key, value] of Object.entries(deferred)) {\n if (value !== undefined) {\n ;(node as any)[key] = value\n }\n }\n}\n\nexport function el<E extends ElementTagName>(\n tag: E,\n props?: ElementProps<E> | VChild | null,\n ...children: VChild[]\n): VNode {\n const node = createElementNode(tag)\n if (isHtmlProps(props)) {\n if (props.ref) {\n if (!isSsrElement(node) && !attributesOnlyMode) {\n props.ref.current = node as ElementByTag<E>\n ;(node as any).__vaniDomRef = props.ref\n } else {\n props.ref.current = null\n }\n }\n\n const { cleanProps, deferred } = extractDeferredProps(tag, props)\n setProps(node, cleanProps)\n\n if (!attributesOnlyMode) {\n appendChildren(node, children)\n }\n\n applyDeferredProps(node, deferred)\n return node\n }\n\n appendChildren(node, [props, ...children])\n return node\n}\n\nexport const fragment = (...children: VChild[]) => {\n if (getRenderMode() === 'ssr') {\n const node: SSRNode = { type: 'fragment', children: [] }\n appendChildren(node, children)\n return node\n }\n\n const node = document.createDocumentFragment()\n appendChildren(node, children)\n return node\n}\n\n// ─────────────────────────────────────────────\n// Low-level mount helper for unwrapped component functions\n// ─────────────────────────────────────────────\nexport function mount<Props>(component: Component<Props>, props: Props): VNode {\n if (getRenderMode() === 'ssr') {\n return {\n type: 'component',\n instance: {\n $$vani: 'component',\n component,\n props,\n },\n }\n }\n\n const fragment = document.createDocumentFragment()\n mountComponent(component, props, fragment)\n return fragment\n}\n\n// ─────────────────────────────────────────────\n// Transitions and Render batching\n// ─────────────────────────────────────────────\nlet flushScheduled = false\nlet inTransition = false\nlet transitionFlushScheduled = false\nlet batchDepth = 0\nlet pendingUrgentFlush = false\nlet pendingTransitionFlush = false\n\nconst urgentQueue = new Set<Handle>()\nconst transitionQueue = new Set<Handle>()\n\n/**\n * Marks all updates triggered inside the callback as a \"transition\".\n *\n * A transition represents non-urgent UI work that can be deferred\n * to keep the application responsive.\n *\n * Updates scheduled inside `startTransition`:\n * - do NOT block user interactions\n * - are batched separately from urgent updates\n * - may be flushed later (e.g. after the current event or during idle time)\n *\n * Transitions are NOT animations.\n * They do not control how updates look, only *when* they are applied.\n *\n * Typical use cases:\n * - Filtering or sorting large lists\n * - Rendering expensive subtrees\n * - Applying async results that are not immediately visible\n *\n * Example:\n * ```ts\n * button({\n * onclick: () => {\n * // urgent update\n * setOpen(true)\n * handle.update()\n *\n * // non-urgent update\n * startTransition(() => {\n * setItems(filter(items))\n * handle.update()\n * })\n * },\n * })\n * ```\n *\n * If multiple transitions are triggered, they are automatically batched.\n * Transition updates never interrupt urgent updates.\n */\nexport function startTransition(fn: () => void): void {\n const prev = inTransition\n inTransition = true\n\n try {\n fn()\n } finally {\n inTransition = prev\n if (batchDepth > 0) {\n pendingTransitionFlush = true\n } else {\n scheduleTransitionFlush()\n }\n }\n}\n\nexport function batch(fn: () => void): void {\n batchDepth += 1\n try {\n fn()\n } finally {\n batchDepth -= 1\n if (batchDepth === 0) {\n if (pendingUrgentFlush) {\n pendingUrgentFlush = false\n scheduleUrgentFlush()\n }\n if (pendingTransitionFlush) {\n pendingTransitionFlush = false\n scheduleTransitionFlush()\n }\n }\n }\n}\n\nfunction scheduleTransitionFlush() {\n if (transitionFlushScheduled) return\n transitionFlushScheduled = true\n\n // defer more than urgent work\n setTimeout(() => {\n transitionFlushScheduled = false\n flushTransitionQueue()\n }, 0)\n}\n\nfunction scheduleUrgentFlush() {\n if (flushScheduled) return\n flushScheduled = true\n\n queueMicrotask(() => {\n flushScheduled = false\n for (const handle of urgentQueue) {\n handle.updateSync((handle as any).__vaniUpdateOptions as UpdateOptions | undefined)\n }\n urgentQueue.clear()\n })\n}\n\nfunction flushTransitionQueue() {\n for (const handle of transitionQueue) {\n handle.updateSync((handle as any).__vaniUpdateOptions as UpdateOptions | undefined)\n }\n transitionQueue.clear()\n\n // if something queued during flush, schedule again\n if (transitionQueue.size > 0) {\n scheduleTransitionFlush()\n }\n}\n\n// ─────────────────────────────────────────────\n// Hydration and SSR\n// ─────────────────────────────────────────────\nlet isHydrating = false\nlet hydrationCursor: ChildNode | null = null\nlet hydrationComponentIndex = 0\n\nfunction warnHydration(message: string) {\n if (!isDevMode()) return\n console.warn(`[vani] hydration warning: ${message}`)\n}\n\nfunction findNextStartAnchor(parent: Node, componentIndex: number): Comment {\n let node = hydrationCursor\n if (!node || !parent.contains(node)) {\n node = parent.firstChild\n }\n let sawEndBeforeStart = false\n while (node) {\n if (node.nodeType === Node.COMMENT_NODE && node.nodeValue === 'vani:start') {\n if (sawEndBeforeStart) {\n warnHydration(\n `Found <!--vani:end--> before <!--vani:start--> for component #${componentIndex}. ` +\n `This usually means the server HTML anchor order is incorrect.`,\n )\n }\n return node as Comment\n }\n if (node.nodeType === Node.COMMENT_NODE && node.nodeValue === 'vani:end') {\n sawEndBeforeStart = true\n }\n node = node.nextSibling\n }\n warnHydration(\n `Expected <!--vani:start--> for component #${componentIndex}, but none was found. ` +\n `This usually means the server HTML does not match the client component tree.`,\n )\n throw new HydrationError('[vani] hydration failed: start anchor not found')\n}\n\nfunction findMatchingEndAnchor(start: Comment, componentIndex: number): Comment {\n let node = start.nextSibling\n let depth = 0\n while (node) {\n if (node.nodeType === Node.COMMENT_NODE) {\n if (node.nodeValue === 'vani:start') {\n depth += 1\n } else if (node.nodeValue === 'vani:end') {\n if (depth === 0) {\n hydrationCursor = node.nextSibling\n return node as Comment\n }\n depth -= 1\n }\n }\n node = node.nextSibling\n }\n warnHydration(\n `Expected <!--vani:end--> for component #${componentIndex}, but none was found. ` +\n `This usually means the server HTML does not match the client component tree.`,\n )\n throw new HydrationError('[vani] hydration failed: end anchor not found')\n}\n\nexport function hydrateToDOM(components: Renderable | Renderable[], root: HTMLElement): Handle[] {\n let handles: Handle[] = []\n isHydrating = true\n hydrationCursor = root.firstChild\n hydrationComponentIndex = 0\n try {\n handles = renderToDOM(components, root)\n } catch (error) {\n if (error instanceof HydrationError) {\n console.error('[vani] hydration failed:', error)\n } else {\n throw error\n }\n } finally {\n if (isDevMode() && hydrationCursor) {\n let node: ChildNode | null = hydrationCursor\n let foundExtraAnchors = false\n while (node) {\n if (node.nodeType === Node.COMMENT_NODE) {\n const value = node.nodeValue\n if (value === 'vani:start' || value === 'vani:end') {\n foundExtraAnchors = true\n break\n }\n }\n node = node.nextSibling\n }\n\n if (foundExtraAnchors) {\n warnHydration(\n 'Unused SSR anchors detected after hydration. ' +\n 'Some server-rendered DOM was not claimed by the client runtime.',\n )\n }\n }\n isHydrating = false\n hydrationCursor = null\n hydrationComponentIndex = 0\n }\n return handles\n}\n\nexport function isDevMode() {\n if ('__vaniDevMode' in globalThis) {\n return (globalThis as any).__vaniDevMode === true\n }\n\n // @ts-ignore\n if (import.meta.env) {\n // @ts-ignore\n return import.meta.env.DEV\n }\n\n // @ts-ignore\n if (typeof process !== 'undefined' && process.env !== undefined) {\n // @ts-ignore\n return process.env.NODE_ENV === 'development'\n }\n\n return false\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-namespace */\n/* eslint-disable @typescript-eslint/no-empty-object-type */\n/* eslint-disable unicorn/no-useless-fallback-in-spread */\n\nimport {\n component,\n el,\n fragment,\n type Component,\n type ComponentInstance,\n type ComponentRef,\n type DomRef,\n type ElementProps,\n type VChild,\n type VNode,\n} from './runtime'\nimport type { ClassName } from './common'\n\ntype ElementTagName = Extract<keyof HTMLElementTagNameMap | keyof SVGElementTagNameMap, string>\ntype IntrinsicElementProps<Tag extends ElementTagName> = ElementProps<Tag> & {\n children?: VChild | VChild[]\n key?: string | number\n class?: ClassName // Alias for className, for HTML compatibility\n}\ntype Key = string | number | null | undefined\n\n// Wrapped component type (result of component())\ntype WrappedComponent<Props = any> = (\n props?: Props & ComponentMetaProps,\n) => ComponentInstance<Props>\n\ntype ComponentMetaProps = {\n key?: string | number\n ref?: ComponentRef\n clientOnly?: boolean\n}\n\nexport const Fragment = Symbol.for('vani.fragment')\n\ntype SplitPropsResult = {\n props: Record<string, any> | null\n children: VChild[]\n key: Key\n ref: DomRef<Element> | ComponentRef | undefined\n hasChildrenProp: boolean\n}\n\nfunction toChildArray(children: VChild | VChild[] | undefined): VChild[] {\n if (children == null || children === false) return []\n return Array.isArray(children) ? children : [children]\n}\n\nfunction splitProps(input: Record<string, any> | null | undefined, key?: Key): SplitPropsResult {\n if (!input || typeof input !== 'object') {\n return {\n props: null,\n children: [],\n key,\n ref: undefined,\n hasChildrenProp: false,\n }\n }\n\n const hasChildrenProp = Object.prototype.hasOwnProperty.call(input, 'children')\n const children = hasChildrenProp ? toChildArray(input.children) : []\n const resolvedKey = key ?? input.key\n const ref = input.ref as DomRef<Element> | ComponentRef | undefined\n const { key: _key, ref: _ref, children: _children, ...rest } = input\n const props = Object.keys(rest).length > 0 ? rest : null\n\n return { props, children, key: resolvedKey, ref, hasChildrenProp }\n}\n\ntype JsxElementType = string | Component<any> | WrappedComponent<any> | typeof Fragment\n\nexport function jsx(type: JsxElementType, props: Record<string, any> | null, key?: Key) {\n const {\n props: cleanProps,\n children,\n key: resolvedKey,\n ref,\n hasChildrenProp,\n } = splitProps(props, key)\n\n if (type === Fragment) {\n return fragment(...children)\n }\n\n if (typeof type === 'string') {\n const elementProps =\n ref == null ? cleanProps : ({ ...(cleanProps ?? {}), ref } as Record<string, any>)\n if (elementProps) {\n return el(type as ElementTagName, elementProps, ...children)\n }\n return el(type as ElementTagName, null, ...children)\n }\n\n if (typeof type === 'function') {\n const componentProps = { ...(cleanProps ?? {}) } as Record<string, any>\n if (children.length > 0 || hasChildrenProp) {\n componentProps.children = children.length <= 1 ? children[0] : children\n }\n if (resolvedKey != null) {\n componentProps.key = resolvedKey\n }\n if (ref) {\n componentProps.ref = ref\n }\n // Check if it's already a wrapped component (has $$vaniWrapped marker)\n if ((type as any).$$vaniWrapped) {\n return (type as WrappedComponent)(componentProps)\n }\n // Otherwise wrap it as a raw Component\n return component(type as Component<any>)(componentProps)\n }\n\n throw new Error('[vani] jsx runtime received an unsupported element type.')\n}\n\nexport const jsxs = jsx\n\nexport function jsxDEV(\n type: JsxElementType,\n props: Record<string, any> | null,\n key?: Key,\n _isStaticChildren?: boolean,\n _source?: unknown,\n _self?: unknown,\n) {\n return jsx(type, props, key)\n}\n\nexport namespace JSX {\n export type Element = VNode | ComponentInstance<any>\n export type ElementType = JsxElementType\n export interface ElementChildrenAttribute {\n children: {}\n }\n export interface IntrinsicAttributes {\n key?: string | number\n ref?: DomRef<globalThis.Element> | ComponentRef\n }\n export type IntrinsicElements = { [K in ElementTagName]: IntrinsicElementProps<K> }\n}\n"],"mappings":"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"}
|
|
@@ -1,27 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
|
|
3
|
-
//#region src/vani/jsx-runtime.d.ts
|
|
4
|
-
type ElementTagName = Extract<keyof HTMLElementTagNameMap | keyof SVGElementTagNameMap, string>;
|
|
5
|
-
type IntrinsicElementProps<Tag extends ElementTagName> = ElementProps<Tag> & {
|
|
6
|
-
children?: VChild | VChild[];
|
|
7
|
-
};
|
|
8
|
-
type Key = string | number | null | undefined;
|
|
9
|
-
declare const Fragment: unique symbol;
|
|
10
|
-
type JsxElementType = string | Component<any> | typeof Fragment;
|
|
11
|
-
declare function jsx(type: JsxElementType, props: Record<string, any> | null, key?: Key): VNode | ComponentInstance<void>;
|
|
12
|
-
declare const jsxs: typeof jsx;
|
|
13
|
-
declare function jsxDEV(type: JsxElementType, props: Record<string, any> | null, key?: Key, _isStaticChildren?: boolean, _source?: unknown, _self?: unknown): VNode | ComponentInstance<void>;
|
|
14
|
-
declare namespace JSX {
|
|
15
|
-
type Element = VNode | ComponentInstance<any>;
|
|
16
|
-
type ElementType = JsxElementType;
|
|
17
|
-
interface ElementChildrenAttribute {
|
|
18
|
-
children: {};
|
|
19
|
-
}
|
|
20
|
-
interface IntrinsicAttributes {
|
|
21
|
-
key?: string | number;
|
|
22
|
-
ref?: DomRef<globalThis.Element> | ComponentRef;
|
|
23
|
-
}
|
|
24
|
-
type IntrinsicElements = { [K in ElementTagName]: IntrinsicElementProps<K> };
|
|
25
|
-
}
|
|
26
|
-
//#endregion
|
|
1
|
+
import { a as jsxs, i as jsxDEV, n as JSX, r as jsx, t as Fragment } from "./jsx-runtime-BK1MMitM.mjs";
|
|
27
2
|
export { Fragment, JSX, jsx, jsxDEV, jsxs };
|
package/dist/lib/jsx-runtime.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{i as e,n as t,r as n,t as r}from"./jsx-runtime-Bbqe4zqZ.mjs";export{r as Fragment,t as jsx,n as jsxDEV,e as jsxs};
|