@vanijs/vani 0.1.0 → 0.3.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 +782 -7
- package/README.md +51 -3
- package/dist/lib/index.d.mts +31 -158
- package/dist/lib/index.mjs +1 -1
- package/dist/lib/jsx-dev-runtime.d.mts +2 -0
- package/dist/lib/jsx-dev-runtime.mjs +1 -0
- package/dist/lib/jsx-runtime.d.mts +27 -0
- package/dist/lib/jsx-runtime.mjs +1 -0
- package/dist/lib/runtime-BIk4OH1t.mjs +1 -0
- package/dist/lib/runtime-Dp-nlil7.d.mts +166 -0
- package/llms.txt +1 -6
- package/package.json +61 -19
package/README.md
CHANGED
|
@@ -59,7 +59,7 @@ This guarantees:
|
|
|
59
59
|
|
|
60
60
|
Vani requires:
|
|
61
61
|
|
|
62
|
-
-
|
|
62
|
+
- JS-first by default (optional JSX adapter)
|
|
63
63
|
- no compiler
|
|
64
64
|
- no build-time transforms
|
|
65
65
|
- no generated code
|
|
@@ -154,6 +154,24 @@ This separates:
|
|
|
154
154
|
|
|
155
155
|
---
|
|
156
156
|
|
|
157
|
+
## JSX (optional)
|
|
158
|
+
|
|
159
|
+
Vani is JS-first and transpiler-free, but it also ships a JSX adapter that maps JSX syntax to the
|
|
160
|
+
same runtime behavior (CSR + SSR).
|
|
161
|
+
|
|
162
|
+
TypeScript config example:
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"compilerOptions": {
|
|
167
|
+
"jsx": "react-jsx",
|
|
168
|
+
"jsxImportSource": "@vanijs/vani"
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
157
175
|
## SSR (experimental)
|
|
158
176
|
|
|
159
177
|
Vani SSR is explicit and anchor-based. You call `renderToString`, and the output includes the same
|
|
@@ -185,11 +203,17 @@ Notes:
|
|
|
185
203
|
|
|
186
204
|
- ❌ Not a Virtual DOM
|
|
187
205
|
- ❌ Not reactive-by-default
|
|
188
|
-
- ❌ Not JSX-
|
|
206
|
+
- ❌ Not JSX-mandatory (optional adapter)
|
|
189
207
|
- ❌ Not compiler-driven
|
|
190
208
|
- ❌ Not a template language
|
|
191
209
|
- ❌ Not a framework that guesses intent
|
|
192
210
|
|
|
211
|
+
### Why not Web Components (yet)
|
|
212
|
+
|
|
213
|
+
Vani does not use Web Components today because the developer ergonomics are still rough and SSR
|
|
214
|
+
support is a key goal. We may revisit this if Web Components bring clear benefits without harming
|
|
215
|
+
productivity and cross-browser compatibility.
|
|
216
|
+
|
|
193
217
|
---
|
|
194
218
|
|
|
195
219
|
## Comparison with Popular Frameworks
|
|
@@ -206,7 +230,31 @@ Notes:
|
|
|
206
230
|
| SSR without heuristics | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
207
231
|
| Dependency-free core | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
208
232
|
|
|
209
|
-
⚠️ = partially / indirectly supported
|
|
233
|
+
⚠️ = partially / indirectly supported / average
|
|
234
|
+
|
|
235
|
+
The strength of Vani is its predictability and simplicity, while other frameworks focus on developer
|
|
236
|
+
productivity and ease of use, handling a lot of complexity behind the scenes automatically.
|
|
237
|
+
|
|
238
|
+
### Vani's Sweet Spot
|
|
239
|
+
|
|
240
|
+
✅ Perfect for:
|
|
241
|
+
|
|
242
|
+
- Dashboard widgets
|
|
243
|
+
- Micro-frontends
|
|
244
|
+
- Live-coding in the browser
|
|
245
|
+
- Embeddable components in other frameworks
|
|
246
|
+
- Performance-critical UIs where you need exact control
|
|
247
|
+
- Server-rendered sites
|
|
248
|
+
- Learning UI fundamentals (no magic, direct DOM)
|
|
249
|
+
- Lightweight SPAs or small Multi-Page Applications
|
|
250
|
+
|
|
251
|
+
❌ Not ideal for:
|
|
252
|
+
|
|
253
|
+
- Large, complex web applications with many interrelated states
|
|
254
|
+
- Teams that want framework conventions to handle complexity
|
|
255
|
+
- Projects needing a mature ecosystem
|
|
256
|
+
|
|
257
|
+
(at least not yet)
|
|
210
258
|
|
|
211
259
|
---
|
|
212
260
|
|
package/dist/lib/index.d.mts
CHANGED
|
@@ -1,157 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
type: 'element';
|
|
4
|
-
tag: string;
|
|
5
|
-
props: Record<string, any>;
|
|
6
|
-
children: SSRNode[];
|
|
7
|
-
} | {
|
|
8
|
-
type: 'text';
|
|
9
|
-
text: string;
|
|
10
|
-
} | {
|
|
11
|
-
type: 'comment';
|
|
12
|
-
text: string;
|
|
13
|
-
} | {
|
|
14
|
-
type: 'fragment';
|
|
15
|
-
children: SSRNode[];
|
|
16
|
-
} | {
|
|
17
|
-
type: 'component';
|
|
18
|
-
instance: ComponentInstance<any>;
|
|
19
|
-
};
|
|
20
|
-
type VNode = Node | SSRNode;
|
|
21
|
-
interface Handle {
|
|
22
|
-
/**
|
|
23
|
-
* Schedules a render for the component.
|
|
24
|
-
* This triggers a re-render on the next microtask.
|
|
25
|
-
*/
|
|
26
|
-
update(): void;
|
|
27
|
-
/**
|
|
28
|
-
* Flushes the component render.
|
|
29
|
-
* This triggers a re-render immediately.
|
|
30
|
-
*/
|
|
31
|
-
updateSync(): void;
|
|
32
|
-
/**
|
|
33
|
-
* Disposes the component: removes the component from the DOM and runs all cleanup functions.
|
|
34
|
-
*/
|
|
35
|
-
dispose(): void;
|
|
36
|
-
/**
|
|
37
|
-
* Adds a cleanup function that is called when the component is disposed.
|
|
38
|
-
*/
|
|
39
|
-
onCleanup(fn: () => void): void;
|
|
40
|
-
/**
|
|
41
|
-
* This is purely syntatic sugar, as it is basically the same as running the function
|
|
42
|
-
* on the setup phase and calling onCleanup to add a cleanup function.
|
|
43
|
-
*
|
|
44
|
-
* Using effects is necessary in SSR mode, for side effects to not run on the server
|
|
45
|
-
* (e.g. timers, subscriptions, DOM usage, etc.)
|
|
46
|
-
*
|
|
47
|
-
* Runs a side effect function when the component is mounted.
|
|
48
|
-
* The returning function may be a cleanup function that is called when the component is disposed.
|
|
49
|
-
*
|
|
50
|
-
*/
|
|
51
|
-
effect(fn: () => void | (() => void)): void;
|
|
52
|
-
}
|
|
53
|
-
type RenderFn = () => VChild;
|
|
54
|
-
type Component<Props = any> = (props: Props, handle: Handle) => RenderFn | Promise<RenderFn>;
|
|
55
|
-
type ComponentInstance<Props = any> = {
|
|
56
|
-
$$vani: 'component';
|
|
57
|
-
component: Component<Props>;
|
|
58
|
-
props: Props;
|
|
59
|
-
/**
|
|
60
|
-
* A key is used to identify the component when it is re-rendered.
|
|
61
|
-
* If a key is provided, the component will be re-rendered only if the key changes.
|
|
62
|
-
*/
|
|
63
|
-
key?: string | number;
|
|
64
|
-
/**
|
|
65
|
-
* A ref is used to get a reference to the component instance.
|
|
66
|
-
* The ref is set to the component instance when the component is mounted.
|
|
67
|
-
* The ref is set to null when the component is disposed.
|
|
68
|
-
*/
|
|
69
|
-
ref?: ComponentRef;
|
|
70
|
-
clientOnly?: boolean;
|
|
71
|
-
};
|
|
72
|
-
type ComponentInput<Props> = Props & {
|
|
73
|
-
key?: string | number;
|
|
74
|
-
ref?: ComponentRef;
|
|
75
|
-
};
|
|
76
|
-
type ComponentMetaProps = {
|
|
77
|
-
key?: string | number;
|
|
78
|
-
ref?: ComponentRef;
|
|
79
|
-
fallback?: RenderFn;
|
|
80
|
-
clientOnly?: boolean;
|
|
81
|
-
};
|
|
82
|
-
type VChild = VNode | ComponentInstance<any> | string | number | null | undefined | false;
|
|
83
|
-
type DataAttribute = `data-${string}`;
|
|
84
|
-
type HtmlProps<T extends keyof HTMLElementTagNameMap> = Partial<Omit<HTMLElementTagNameMap[T], 'children' | 'className' | 'style'>> & {
|
|
85
|
-
className?: ClassName;
|
|
86
|
-
style?: string;
|
|
87
|
-
ref?: DomRef<HTMLElementTagNameMap[T]>;
|
|
88
|
-
} & { [key in DataAttribute]?: string | number | boolean | undefined | null };
|
|
89
|
-
type ClassName = string | undefined | null | {
|
|
90
|
-
[key: string]: boolean | undefined | null;
|
|
91
|
-
} | ClassName[];
|
|
92
|
-
type ComponentRef = {
|
|
93
|
-
current: Handle | null;
|
|
94
|
-
};
|
|
95
|
-
type DomRef<T extends HTMLElement = HTMLElement> = {
|
|
96
|
-
current: T | null;
|
|
97
|
-
};
|
|
98
|
-
type RenderMode = 'dom' | 'ssr';
|
|
99
|
-
declare function component(fn: Component<void>): (props?: ComponentMetaProps) => ComponentInstance<void>;
|
|
100
|
-
declare function component<Props>(fn: Component<Props>): (props: Props & ComponentMetaProps) => ComponentInstance<Props>;
|
|
101
|
-
declare function withRenderMode<T>(mode: RenderMode, fn: () => T): T;
|
|
102
|
-
declare function getRenderMode(): RenderMode;
|
|
103
|
-
declare function renderToDOM(components: Array<Component<any> | ComponentInstance<any>>, root: HTMLElement): Handle[];
|
|
104
|
-
declare function isComponentInstance(child: VChild): child is ComponentInstance<any>;
|
|
105
|
-
declare function classNames(...classes: ClassName[]): string;
|
|
106
|
-
declare function el<E extends keyof HTMLElementTagNameMap>(tag: E, props?: HtmlProps<E> | VChild | null, ...children: VChild[]): VNode;
|
|
107
|
-
declare const fragment: (...children: VChild[]) => {
|
|
108
|
-
type: "fragment";
|
|
109
|
-
children: SSRNode[];
|
|
110
|
-
} | DocumentFragment;
|
|
111
|
-
declare function mount<Props>(component: Component<Props>, props: Props): VNode;
|
|
112
|
-
/**
|
|
113
|
-
* Marks all updates triggered inside the callback as a "transition".
|
|
114
|
-
*
|
|
115
|
-
* A transition represents non-urgent UI work that can be deferred
|
|
116
|
-
* to keep the application responsive.
|
|
117
|
-
*
|
|
118
|
-
* Updates scheduled inside `startTransition`:
|
|
119
|
-
* - do NOT block user interactions
|
|
120
|
-
* - are batched separately from urgent updates
|
|
121
|
-
* - may be flushed later (e.g. after the current event or during idle time)
|
|
122
|
-
*
|
|
123
|
-
* Transitions are NOT animations.
|
|
124
|
-
* They do not control how updates look, only *when* they are applied.
|
|
125
|
-
*
|
|
126
|
-
* Typical use cases:
|
|
127
|
-
* - Filtering or sorting large lists
|
|
128
|
-
* - Rendering expensive subtrees
|
|
129
|
-
* - Applying async results that are not immediately visible
|
|
130
|
-
*
|
|
131
|
-
* Example:
|
|
132
|
-
* ```ts
|
|
133
|
-
* button({
|
|
134
|
-
* onclick: () => {
|
|
135
|
-
* // urgent update
|
|
136
|
-
* setOpen(true)
|
|
137
|
-
* handle.update()
|
|
138
|
-
*
|
|
139
|
-
* // non-urgent update
|
|
140
|
-
* startTransition(() => {
|
|
141
|
-
* setItems(filter(items))
|
|
142
|
-
* handle.update()
|
|
143
|
-
* })
|
|
144
|
-
* },
|
|
145
|
-
* })
|
|
146
|
-
* ```
|
|
147
|
-
*
|
|
148
|
-
* If multiple transitions are triggered, they are automatically batched.
|
|
149
|
-
* Transition updates never interrupt urgent updates.
|
|
150
|
-
*/
|
|
151
|
-
declare function startTransition(fn: () => void): void;
|
|
152
|
-
declare function hydrateToDOM(components: Array<Component<any> | ComponentInstance<any>>, root: HTMLElement): Handle[];
|
|
153
|
-
declare function isDevMode(): boolean;
|
|
154
|
-
//#endregion
|
|
1
|
+
import { C as isDevMode, D as withRenderMode, E as startTransition, S as isComponentInstance, T as renderToDOM, _ as component, a as ComponentRef, b as getRenderMode, c as ElementProps, d as RenderFn, f as SSRNode, g as classNames, h as VNode, i as ComponentInstance, l as Handle, m as VChild, n as Component, o as DataAttribute, p as SvgProps, r as ComponentInput, s as DomRef, t as ClassName, u as HtmlProps, v as el, w as mount, x as hydrateToDOM, y as fragment } from "./runtime-Dp-nlil7.mjs";
|
|
2
|
+
|
|
155
3
|
//#region src/vani/html.d.ts
|
|
156
4
|
declare const div: (propsOrChild?: VChild | HtmlProps<"div">, ...children: VChild[]) => VNode;
|
|
157
5
|
declare const span: (propsOrChild?: VChild | HtmlProps<"span">, ...children: VChild[]) => VNode;
|
|
@@ -170,7 +18,7 @@ declare const aside: (propsOrChild?: VChild | HtmlProps<"aside">, ...children: V
|
|
|
170
18
|
declare const nav: (propsOrChild?: VChild | HtmlProps<"nav">, ...children: VChild[]) => VNode;
|
|
171
19
|
declare const details: (propsOrChild?: VChild | HtmlProps<"details">, ...children: VChild[]) => VNode;
|
|
172
20
|
declare const summary: (propsOrChild?: VChild | HtmlProps<"summary">, ...children: VChild[]) => VNode;
|
|
173
|
-
declare const a: (propsOrChild?: VChild |
|
|
21
|
+
declare const a: (propsOrChild?: VChild | SvgProps<"a">, ...children: VChild[]) => VNode;
|
|
174
22
|
declare const button: (propsOrChild?: VChild | HtmlProps<"button">, ...children: VChild[]) => VNode;
|
|
175
23
|
declare const input: (propsOrChild?: VChild | HtmlProps<"input">, ...children: VChild[]) => VNode;
|
|
176
24
|
declare const output: (propsOrChild?: VChild | HtmlProps<"output">, ...children: VChild[]) => VNode;
|
|
@@ -227,14 +75,39 @@ declare const tfoot: (propsOrChild?: VChild | HtmlProps<"tfoot">, ...children: V
|
|
|
227
75
|
declare const tr: (propsOrChild?: VChild | HtmlProps<"tr">, ...children: VChild[]) => VNode;
|
|
228
76
|
declare const td: (propsOrChild?: VChild | HtmlProps<"td">, ...children: VChild[]) => VNode;
|
|
229
77
|
declare const th: (propsOrChild?: VChild | HtmlProps<"th">, ...children: VChild[]) => VNode;
|
|
230
|
-
declare const style: (propsOrChild?: VChild |
|
|
231
|
-
declare const script: (propsOrChild?: VChild |
|
|
78
|
+
declare const style: (propsOrChild?: VChild | SvgProps<"style">, ...children: VChild[]) => VNode;
|
|
79
|
+
declare const script: (propsOrChild?: VChild | SvgProps<"script">, ...children: VChild[]) => VNode;
|
|
232
80
|
declare const noscript: (propsOrChild?: VChild | HtmlProps<"noscript">, ...children: VChild[]) => VNode;
|
|
233
81
|
declare const template: (propsOrChild?: VChild | HtmlProps<"template">, ...children: VChild[]) => VNode;
|
|
234
82
|
declare const slot: (propsOrChild?: VChild | HtmlProps<"slot">, ...children: VChild[]) => VNode;
|
|
83
|
+
declare const svg: (propsOrChild?: VChild | SvgProps<"svg">, ...children: VChild[]) => VNode;
|
|
84
|
+
declare const g: (propsOrChild?: VChild | SvgProps<"g">, ...children: VChild[]) => VNode;
|
|
85
|
+
declare const path: (propsOrChild?: VChild | SvgProps<"path">, ...children: VChild[]) => VNode;
|
|
86
|
+
declare const circle: (propsOrChild?: VChild | SvgProps<"circle">, ...children: VChild[]) => VNode;
|
|
87
|
+
declare const rect: (propsOrChild?: VChild | SvgProps<"rect">, ...children: VChild[]) => VNode;
|
|
88
|
+
declare const line: (propsOrChild?: VChild | SvgProps<"line">, ...children: VChild[]) => VNode;
|
|
89
|
+
declare const polyline: (propsOrChild?: VChild | SvgProps<"polyline">, ...children: VChild[]) => VNode;
|
|
90
|
+
declare const polygon: (propsOrChild?: VChild | SvgProps<"polygon">, ...children: VChild[]) => VNode;
|
|
91
|
+
declare const ellipse: (propsOrChild?: VChild | SvgProps<"ellipse">, ...children: VChild[]) => VNode;
|
|
92
|
+
declare const defs: (propsOrChild?: VChild | SvgProps<"defs">, ...children: VChild[]) => VNode;
|
|
93
|
+
declare const clipPath: (propsOrChild?: VChild | SvgProps<"clipPath">, ...children: VChild[]) => VNode;
|
|
94
|
+
declare const mask: (propsOrChild?: VChild | SvgProps<"mask">, ...children: VChild[]) => VNode;
|
|
95
|
+
declare const pattern: (propsOrChild?: VChild | SvgProps<"pattern">, ...children: VChild[]) => VNode;
|
|
96
|
+
declare const linearGradient: (propsOrChild?: VChild | SvgProps<"linearGradient">, ...children: VChild[]) => VNode;
|
|
97
|
+
declare const radialGradient: (propsOrChild?: VChild | SvgProps<"radialGradient">, ...children: VChild[]) => VNode;
|
|
98
|
+
declare const stop: (propsOrChild?: VChild | SvgProps<"stop">, ...children: VChild[]) => VNode;
|
|
99
|
+
declare const use: (propsOrChild?: VChild | SvgProps<"use">, ...children: VChild[]) => VNode;
|
|
235
100
|
//#endregion
|
|
236
101
|
//#region src/vani/ssr.d.ts
|
|
237
102
|
type Renderable = Component<any> | ComponentInstance<any>;
|
|
238
103
|
declare function renderToString(components: Renderable[]): Promise<string>;
|
|
239
104
|
//#endregion
|
|
240
|
-
|
|
105
|
+
//#region src/vani/svg.d.ts
|
|
106
|
+
type SvgRenderOptions = {
|
|
107
|
+
size?: number;
|
|
108
|
+
className?: string;
|
|
109
|
+
attributes?: SvgProps;
|
|
110
|
+
};
|
|
111
|
+
declare const renderSvgString: (svg: string, options?: SvgRenderOptions) => VNode;
|
|
112
|
+
//#endregion
|
|
113
|
+
export { ClassName, Component, ComponentInput, ComponentInstance, ComponentRef, DataAttribute, DomRef, ElementProps, Handle, HtmlProps, RenderFn, SSRNode, SvgProps, SvgRenderOptions, VChild, VNode, a, abbr, article, aside, audio, blockquote, br, button, caption, circle, cite, classNames, clipPath, code, col, colgroup, component, datalist, dd, defs, details, dfn, div, dl, dt, 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, renderSvgString, renderToDOM, renderToString, samp, script, section, select, 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 };
|
package/dist/lib/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e){let t=e;return t.__vaniKeyed||=new Map,t.__vaniKeyed}function t(e){return 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}}}let n=`dom`;function r(e,t){let r=n;n=e;let i=t();return i&&typeof i.finally==`function`?i.finally(()=>{n=r}):(n=r,i)}function i(){return n}function a(e){return typeof e==`object`&&!!e&&`type`in e}function o(e){return a(e)&&e.type===`element`}function s(e){return a(e)&&e.type===`fragment`}function c(e){return n===`dom`?document.createElement(e):{type:`element`,tag:e,props:{},children:[]}}function l(e){return n===`dom`?document.createTextNode(e):{type:`text`,text:e}}function u(e,t){if(n===`dom`){e.appendChild(t);return}(o(e)||s(e))&&e.children.push(t)}function d(e,t){let n=e.nextSibling;for(;n&&n!==t;){let e=n.nextSibling,t=n;t.__vaniDomRef&&(t.__vaniDomRef.current=null),n.remove(),n=e}}function ee(e){if(e==null||e===!1)return document.createComment(`vani:empty`);if(m(e)){let t=document.createDocumentFragment(),n=f(e.component,h(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 f(e,t,n){let r=[],i=!1,a,o,s=t?.clientOnly===!0;if(O){let e=A;A+=1,a=M(n,e),o=N(a,e)}else a=document.createComment(`vani:start`),o=document.createComment(`vani:end`),n.appendChild(a),n.appendChild(o);let c,l={update(){i||(S?w.has(l)||(T.add(l),D()):(T.delete(l),w.add(l),re()))},updateSync(){if(i)return;let e=a.parentNode;if(!e)return;d(a,o);let t=ee(c());e.insertBefore(t,o)},onCleanup(e){r.push(e)},dispose(){if(!i){i=!0,w.delete(l),T.delete(l);for(let e of r)e();r.length=0,d(a,o),a.remove(),o.remove(),c=(()=>document.createComment(`disposed`))}},effect(e){let t=e();typeof t==`function`&&r.push(t)}};if(O&&!s){let n=!1;return c=()=>{if(!n){n=!0;let r=e(t,l);c=r instanceof Promise?()=>document.createComment(`async`):r}return c()},l}let u=e(t,l);return u instanceof Promise?(c=t?.fallback||(()=>document.createComment(`vani:async`)),(!O||s)&&l.update(),u.then(e=>{i||(c=e,l.update())}),l):(c=u,(!O||s)&&l.update(),l)}function p(e,t){if(!t)throw Error(`[vani] root element not found`);let n=[];for(let r of e){if(typeof r==`function`){let e=f(r,{},t);n.push(e);continue}let e=f(r.component,h(r),t);n.push(e)}return n}function m(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 te(e){let t=typeof Node<`u`&&e instanceof Node;return typeof e==`object`&&!!e&&!t&&!m(e)}function h(e){return e.clientOnly?{...e.props??{},clientOnly:!0}:e.props}function g(t,r){if(n===`ssr`){for(let e of r)if(!(e==null||e===!1||e===void 0)){if(m(e)){u(t,{type:`component`,instance:e});continue}if(typeof e==`string`||typeof e==`number`){u(t,l(String(e)));continue}if(a(e)){u(t,e);continue}}return}let i=t;for(let t of r)if(!(t==null||t===!1||t===void 0)){if(m(t)){if(t.key!=null){let n=e(i),r=i.__vaniUsedKeys??=new Set,a=n.get(t.key);if(!a){let e=document.createDocumentFragment(),r=f(t.component,h(t),e);t.ref&&(t.ref.current=r),a={fragment:e,handle:r,ref:t.ref},n.set(t.key,a),t.ref&&(t.ref.current=r)}r.add(t.key),i.appendChild(a.fragment);continue}let n=document.createDocumentFragment(),r=f(t.component,h(t),n);t.ref&&(t.ref.current=r),i.appendChild(n);continue}if(typeof t==`string`||typeof t==`number`){i.appendChild(document.createTextNode(String(t)));continue}i.appendChild(t)}let o=i.__vaniKeyed,s=i.__vaniUsedKeys;if(o&&s){for(let[e,t]of o)s.has(e)||(t.handle.dispose(),t.ref&&(t.ref.current=null),o.delete(e));s.clear()}}function _(e,t){for(let n in t){let r=t[n];if(![`key`,`ref`].includes(n)){if(n===`className`){let t=v(r);o(e)?e.props.class=t:e.className=t;continue}if(n.startsWith(`on`)&&typeof r==`function`)o(e)||(e[n.toLowerCase()]=r);else if(r===!0)o(e)?e.props[n]=!0:e.setAttribute(n,``);else if(r===!1||r==null)continue;else o(e)?e.props[n]=String(r):e.setAttribute(n,String(r))}}}function v(...e){return e.map(e=>{if(!(e==null||e===``))return typeof e==`string`?e.trim():Array.isArray(e)?v(...e):Object.entries(e).filter(([e,t])=>t).map(([e])=>e.trim()).join(` `).trim()}).filter(Boolean).join(` `)}function y(e,t,...n){let r=c(e);return te(t)?(t.ref&&(o(r)?t.ref.current=null:(t.ref.current=r,r.__vaniDomRef=t.ref)),_(r,t),g(r,n),r):(g(r,[t,...n]),r)}const ne=(...e)=>{if(n===`ssr`){let t={type:`fragment`,children:[]};return g(t,e),t}let t=document.createDocumentFragment();return g(t,e),t};function b(e,t){if(n===`ssr`)return{type:`component`,instance:{$$vani:`component`,component:e,props:t}};let r=document.createDocumentFragment();return f(e,t,r),r}let x=!1,S=!1,C=!1;const w=new Set,T=new Set;function E(e){let t=S;S=!0;try{e()}finally{S=t,D()}}function D(){C||(C=!0,setTimeout(()=>{C=!1,ie()},0))}function re(){x||(x=!0,queueMicrotask(()=>{x=!1;for(let e of w)e.updateSync();w.clear()}))}function ie(){for(let e of T)e.updateSync();T.clear(),T.size>0&&D()}let O=!1,k=null,A=0;function j(e){F()&&console.warn(`[vani] hydration warning: ${e}`)}function M(e,t){let n=k;(!n||!e.contains(n))&&(n=e.firstChild);let r=!1;for(;n;){if(n.nodeType===Node.COMMENT_NODE&&n.nodeValue===`vani:start`)return r&&j(`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 j(`Expected <!--vani:start--> for component #${t}, but none was found. This usually means the server HTML does not match the client component tree.`),Error(`[vani] hydration failed: start anchor not found`)}function N(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 k=n.nextSibling,n;--r}}n=n.nextSibling}throw j(`Expected <!--vani:end--> for component #${t}, but none was found. This usually means the server HTML does not match the client component tree.`),Error(`[vani] hydration failed: end anchor not found`)}function P(e,t){let n=[];O=!0,k=t.firstChild,A=0;try{n=p(e,t)}catch(e){console.error(`[vani] hydration failed:`,e)}finally{if(F()&&k){let e=k,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&&j(`Unused SSR anchors detected after hydration. Some server-rendered DOM was not claimed by the client runtime.`)}O=!1,k=null,A=0}return n}function F(){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}function I(e){return(t,...n)=>y(e,t,...n)}const L=I(`div`),R=I(`span`),z=I(`ul`),B=I(`li`),V=I(`ol`),H=I(`dl`),U=I(`dt`),W=I(`dd`),G=I(`main`),K=I(`header`),q=I(`footer`),J=I(`section`),Y=I(`article`),ae=I(`aside`),oe=I(`nav`),se=I(`details`),ce=I(`summary`),le=I(`a`),ue=I(`button`),de=I(`input`),fe=I(`output`),pe=I(`textarea`),me=I(`select`),he=I(`option`),ge=I(`optgroup`),_e=I(`label`),ve=I(`form`),ye=I(`progress`),be=I(`meter`),xe=I(`fieldset`),Se=I(`legend`),Ce=I(`datalist`),we=I(`figure`),Te=I(`figcaption`),Ee=I(`img`),De=I(`picture`),Oe=I(`source`),ke=I(`video`),Ae=I(`audio`),je=I(`iframe`),Me=I(`embed`),Ne=I(`time`),Pe=I(`mark`),Fe=I(`p`),Ie=I(`h1`),Le=I(`h2`),Re=I(`h3`),ze=I(`h4`),Be=I(`h5`),Ve=I(`h6`),He=I(`code`),Ue=I(`pre`),We=I(`blockquote`),Ge=I(`var`),Ke=I(`kbd`),qe=I(`samp`),Je=I(`cite`),Ye=I(`dfn`),Xe=I(`abbr`),Ze=I(`small`),Qe=I(`strong`),$e=I(`em`),et=I(`br`),tt=I(`hr`),nt=I(`table`),rt=I(`caption`),it=I(`colgroup`),at=I(`col`),ot=I(`tbody`),st=I(`thead`),ct=I(`tfoot`),lt=I(`tr`),ut=I(`td`),dt=I(`th`),ft=I(`style`),pt=I(`script`),mt=I(`noscript`),ht=I(`template`),X=I(`slot`),gt=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]);function _t(){return{update(){},updateSync(){},dispose(){},onCleanup(){},effect(){}}}function vt(e){return typeof e==`function`?{$$vani:`component`,component:e,props:{}}:e}function Z(e){return e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`).replace(/'/g,`'`)}function yt(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}="${Z(String(r))}"`))}return t.length>0?` ${t.join(` `)}`:``}function Q(e){if(e==null||e===!1)return{type:`fragment`,children:[]};if(typeof e==`string`||typeof e==`number`)return{type:`text`,text:String(e)};if(m(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 bt(e){let t=`<!--vani:start-->`,n=`<!--vani:end-->`;if(e.clientOnly){let r=e.props?.fallback;return r?`${t}${await $(Q(r()))}${n}`:`${t}${n}`}let r=e.component(e.props,_t());return`${t}${await $(Q((r instanceof Promise?await r:r)()))}${n}`}async function $(e){switch(e.type){case`text`:return Z(e.text);case`comment`:return`<!--${e.text}-->`;case`fragment`:return(await Promise.all(e.children.map($))).join(``);case`component`:return bt(e.instance);case`element`:{let t=yt(e.props);if(gt.has(e.tag))return`<${e.tag}${t}>`;let n=(await Promise.all(e.children.map($))).join(``);return`<${e.tag}${t}>${n}</${e.tag}>`}}}async function xt(e){return r(`ssr`,async()=>{if(i()!==`ssr`)throw Error(`[vani] renderToString failed to set SSR render mode.`);let t=e.map(e=>({type:`component`,instance:vt(e)}));return(await Promise.all(t.map($))).join(``)})}export{le as a,Xe as abbr,Y as article,ae as aside,Ae as audio,We as blockquote,et as br,ue as button,rt as caption,Je as cite,v as classNames,He as code,at as col,it as colgroup,t as component,Ce as datalist,W as dd,se as details,Ye as dfn,L as div,H as dl,U as dt,y as el,$e as em,Me as embed,xe as fieldset,Te as figcaption,we as figure,q as footer,ve as form,ne as fragment,i as getRenderMode,Ie as h1,Le as h2,Re as h3,ze as h4,Be as h5,Ve as h6,K as header,tt as hr,P as hydrateToDOM,je as iframe,Ee as img,de as input,m as isComponentInstance,F as isDevMode,Ke as kbd,_e as label,Se as legend,B as li,G as main,Pe as mark,be as meter,b as mount,oe as nav,mt as noscript,V as ol,ge as optgroup,he as option,fe as output,Fe as p,De as picture,Ue as pre,ye as progress,p as renderToDOM,xt as renderToString,qe as samp,pt as script,J as section,me as select,X as slot,Ze as small,Oe as source,R as span,E as startTransition,Qe as strong,ft as style,ce as summary,nt as table,ot as tbody,ut as td,ht as template,pe as textarea,ct as tfoot,dt as th,st as thead,Ne as time,lt as tr,z as ul,Ge as var_,ke as video,r as withRenderMode};
|
|
1
|
+
import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,r as c,s as l,t as ee,u as te}from"./runtime-BIk4OH1t.mjs";function u(e){return(t,...n)=>c(e,t,...n)}const ne=u(`div`),re=u(`span`),ie=u(`ul`),ae=u(`li`),oe=u(`ol`),se=u(`dl`),d=u(`dt`),f=u(`dd`),p=u(`main`),m=u(`header`),h=u(`footer`),g=u(`section`),_=u(`article`),v=u(`aside`),y=u(`nav`),b=u(`details`),x=u(`summary`),S=u(`a`),C=u(`button`),w=u(`input`),T=u(`output`),E=u(`textarea`),D=u(`select`),O=u(`option`),k=u(`optgroup`),A=u(`label`),j=u(`form`),M=u(`progress`),N=u(`meter`),P=u(`fieldset`),F=u(`legend`),I=u(`datalist`),L=u(`figure`),R=u(`figcaption`),z=u(`img`),B=u(`picture`),V=u(`source`),H=u(`video`),U=u(`audio`),W=u(`iframe`),G=u(`embed`),K=u(`time`),ce=u(`mark`),le=u(`p`),ue=u(`h1`),de=u(`h2`),fe=u(`h3`),pe=u(`h4`),me=u(`h5`),he=u(`h6`),ge=u(`code`),_e=u(`pre`),ve=u(`blockquote`),ye=u(`var`),be=u(`kbd`),xe=u(`samp`),Se=u(`cite`),Ce=u(`dfn`),we=u(`abbr`),Te=u(`small`),Ee=u(`strong`),De=u(`em`),Oe=u(`br`),ke=u(`hr`),Ae=u(`table`),je=u(`caption`),Me=u(`colgroup`),Ne=u(`col`),Pe=u(`tbody`),Fe=u(`thead`),Ie=u(`tfoot`),Le=u(`tr`),Re=u(`td`),ze=u(`th`),Be=u(`style`),Ve=u(`script`),He=u(`noscript`),Ue=u(`template`),We=u(`slot`),Ge=u(`svg`),Ke=u(`g`),qe=u(`path`),Je=u(`circle`),Ye=u(`rect`),Xe=u(`line`),Ze=u(`polyline`),Qe=u(`polygon`),$e=u(`ellipse`),et=u(`defs`),tt=u(`clipPath`),nt=u(`mask`),rt=u(`pattern`),it=u(`linearGradient`),at=u(`radialGradient`),ot=u(`stop`),st=u(`use`),q=new Set([`area`,`base`,`br`,`col`,`embed`,`hr`,`img`,`input`,`link`,`meta`,`param`,`source`,`track`,`wbr`]);function ct(){return{update(){},updateSync(){},dispose(){},onCleanup(){},effect(){}}}function lt(e){return typeof e==`function`?{$$vani:`component`,component:e,props:{}}:e}function J(e){return e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`).replace(/"/g,`"`).replace(/'/g,`'`)}function ut(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(l(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 dt(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,ct());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 dt(e.instance);case`element`:{let t=ut(e.props);if(q.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 ft(t){return r(`ssr`,async()=>{if(e()!==`ssr`)throw Error(`[vani] renderToString failed to set SSR render mode.`);let n=t.map(e=>({type:`component`,instance:lt(e)}));return(await Promise.all(n.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},pt=(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))}}},mt=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},ht=e=>{let t=e.replace(/<!--[\s\S]*?-->/g,``).trim(),n=/<\/?[^>]+>/g,r=[],i=null,a=0,o,s=e=>{let t=r[r.length-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:mt(n===-1?``:t.slice(n+1)),children:[]};i?s(a):i=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($)},gt=(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)}}},_t=(t,n)=>{if(e()===`ssr`){let e=$(ht(t));return gt(e,n),e}let r=Z.get(t);r||(r=new DOMParser().parseFromString(t,`image/svg+xml`).documentElement,Z.set(t,r));let i=r.cloneNode(!0);return pt(i,n),i};export{S as a,we as abbr,_ as article,v as aside,U as audio,ve as blockquote,Oe as br,C as button,je as caption,Je as circle,Se as cite,ee as classNames,tt as clipPath,ge as code,Ne as col,Me as colgroup,o as component,I as datalist,f as dd,et as defs,b as details,Ce as dfn,ne as div,se as dl,d as dt,c as el,$e as ellipse,De as em,G as embed,P as fieldset,R as figcaption,L as figure,h as footer,j as form,i as fragment,Ke as g,e as getRenderMode,ue as h1,de as h2,fe as h3,pe as h4,me as h5,he as h6,m as header,ke as hr,s as hydrateToDOM,W as iframe,z as img,w as input,l as isComponentInstance,t as isDevMode,be as kbd,A as label,F as legend,ae as li,Xe as line,it as linearGradient,p as main,ce as mark,nt as mask,N as meter,a as mount,y as nav,He as noscript,oe as ol,k as optgroup,O as option,T as output,le as p,qe as path,rt as pattern,B as picture,Qe as polygon,Ze as polyline,_e as pre,M as progress,at as radialGradient,Ye as rect,_t as renderSvgString,te as renderToDOM,ft as renderToString,xe as samp,Ve as script,g as section,D as select,We as slot,Te as small,V as source,re as span,n as startTransition,ot as stop,Ee as strong,Be as style,x as summary,Ge as svg,Ae as table,Pe as tbody,Re as td,Ue as template,E as textarea,Ie as tfoot,ze as th,Fe as thead,K as time,Le as tr,ie as ul,st as use,ye as var_,H as video,r as withRenderMode};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
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};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { a as ComponentRef, c as ElementProps, h as VNode, i as ComponentInstance, m as VChild, n as Component, s as DomRef } from "./runtime-Dp-nlil7.mjs";
|
|
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
|
|
27
|
+
export { Fragment, JSX, jsx, jsxDEV, jsxs };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,n as t,r as n}from"./runtime-BIk4OH1t.mjs";const r=Symbol.for(`vani.fragment`);function i(e){return e==null||e===!1?[]:Array.isArray(e)?e:[e]}function a(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?i(e.children):[],a=t??e.key,o=e.ref,{key:s,ref:c,children:l,...u}=e;return{props:Object.keys(u).length>0?u:null,children:r,key:a,ref:o,hasChildrenProp:n}}function o(i,o,s){let{props:c,children:l,key:u,ref:d,hasChildrenProp:f}=a(o,s);if(i===r)return e(...l);if(typeof i==`string`)return c?n(i,c,...l):n(i,null,...l);if(typeof i==`function`){let e={...c??{}};return(l.length>0||f)&&(e.children=l.length<=1?l[0]:l),u!=null&&(e.key=u),d&&(e.ref=d),t(i)(e)}throw Error(`[vani] jsx runtime received an unsupported element type.`)}const s=o;function c(e,t,n,r,i,a){return o(e,t,n)}export{r as Fragment,o as jsx,c as jsxDEV,s as jsxs};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e){let t=e;return t.__vaniKeyed||=new Map,t.__vaniKeyed}function t(e){return 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}}}let n=`dom`;function r(e,t){let r=n;n=e;let i=t();return i&&typeof i.finally==`function`?i.finally(()=>{n=r}):(n=r,i)}function i(){return n}function a(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 o(e){return a(e)&&e.type===`element`}function s(e){return a(e)&&e.type===`fragment`}const c=new Set([`svg`,`g`,`path`,`circle`,`rect`,`line`,`polyline`,`polygon`,`ellipse`,`defs`,`clipPath`,`mask`,`pattern`,`linearGradient`,`radialGradient`,`stop`,`use`]);function l(e){return n===`dom`?c.has(e)?document.createElementNS(`http://www.w3.org/2000/svg`,e):document.createElement(e):{type:`element`,tag:e,props:{},children:[]}}function u(e){return n===`dom`?document.createTextNode(e):{type:`text`,text:e}}function d(e,t){if(n===`dom`){e.appendChild(t);return}(o(e)||s(e))&&e.children.push(t)}function f(e,t){let n=e.nextSibling;for(;n&&n!==t;){let e=n.nextSibling,t=n;t.__vaniDomRef&&(t.__vaniDomRef.current=null),n.remove(),n=e}}function p(e){if(e==null||e===!1)return document.createComment(`vani:empty`);if(g(e)){let t=document.createDocumentFragment(),n=m(e.component,v(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 m(e,t,n){let r=[],i=!1,a,o,s=t?.clientOnly===!0;if(I){let e=R;R+=1,a=B(n,e),o=V(a,e)}else a=document.createComment(`vani:start`),o=document.createComment(`vani:end`),n.appendChild(a),n.appendChild(o);let c,l={update(){i||(O?A.has(l)||(j.add(l),N()):(j.delete(l),A.add(l),P()))},updateSync(){if(i)return;let e=a.parentNode;if(!e)return;f(a,o);let t=p(c());e.insertBefore(t,o)},onCleanup(e){r.push(e)},dispose(){if(!i){i=!0,A.delete(l),j.delete(l);for(let e of r)e();r.length=0,f(a,o),a.remove(),o.remove(),c=(()=>document.createComment(`disposed`))}},effect(e){let t=e();typeof t==`function`&&r.push(t)}};if(I&&!s){let n=!1;return c=()=>{if(!n){n=!0;let r=e(t,l);c=r instanceof Promise?()=>document.createComment(`async`):r}return c()},l}let u=e(t,l);return u instanceof Promise?(c=t?.fallback||(()=>document.createComment(`vani:async`)),(!I||s)&&l.update(),u.then(e=>{i||(c=e,l.update())}),l):(c=u,(!I||s)&&l.update(),l)}function h(e,t){if(!t)throw Error(`[vani] root element not found`);let n=[];for(let r of e){if(typeof r==`function`){let e=m(r,{},t);n.push(e);continue}let e=m(r.component,v(r),t);n.push(e)}return n}function g(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 _(e){let t=typeof Node<`u`&&e instanceof Node;return typeof e==`object`&&!!e&&!t&&!g(e)&&!a(e)}function v(e){return e.clientOnly?{...e.props??{},clientOnly:!0}:e.props}function y(t,r){if(n===`ssr`){for(let e of r)if(!(e==null||e===!1||e===void 0)){if(g(e)){d(t,{type:`component`,instance:e});continue}if(typeof e==`string`||typeof e==`number`){d(t,u(String(e)));continue}if(a(e)){d(t,e);continue}}return}let i=t;for(let t of r)if(!(t==null||t===!1||t===void 0)){if(g(t)){if(t.key!=null){let n=e(i),r=i.__vaniUsedKeys??=new Set,a=n.get(t.key);if(!a){let e=document.createDocumentFragment(),r=m(t.component,v(t),e);t.ref&&(t.ref.current=r),a={fragment:e,handle:r,ref:t.ref},n.set(t.key,a),t.ref&&(t.ref.current=r)}r.add(t.key),i.appendChild(a.fragment);continue}let n=document.createDocumentFragment(),r=m(t.component,v(t),n);t.ref&&(t.ref.current=r),i.appendChild(n);continue}if(typeof t==`string`||typeof t==`number`){i.appendChild(document.createTextNode(String(t)));continue}i.appendChild(t)}let o=i.__vaniKeyed,s=i.__vaniUsedKeys;if(o&&s){for(let[e,t]of o)s.has(e)||(t.handle.dispose(),t.ref&&(t.ref.current=null),o.delete(e));s.clear()}}function b(e){return typeof SVGElement<`u`&&e instanceof SVGElement}function x(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()}function S(e,t){let n=o(e)?c.has(e.tag):b(e);for(let r in t){let i=t[r];if(![`key`,`ref`].includes(r)){if(r===`className`){let t=C(i);o(e)?e.props.class=t:n?e.setAttribute(`class`,t):e.className=t;continue}if(r.startsWith(`on`)&&typeof i==`function`)o(e)||(e[r.toLowerCase()]=i);else if(i===!0)o(e)?e.props[r]=!0:e.setAttribute(r,``);else if(i===!1||i==null)continue;else{let t=x(r,n);o(e)?e.props[t]=String(i):e.setAttribute(t,String(i))}}}}function C(...e){return e.map(e=>{if(!(e==null||e===``))return typeof e==`string`?e.trim():Array.isArray(e)?C(...e):Object.entries(e).filter(([e,t])=>t).map(([e])=>e.trim()).join(` `).trim()}).filter(Boolean).join(` `)}function w(e,t,...n){let r=l(e);return _(t)?(t.ref&&(o(r)?t.ref.current=null:(t.ref.current=r,r.__vaniDomRef=t.ref)),S(r,t),y(r,n),r):(y(r,[t,...n]),r)}const T=(...e)=>{if(n===`ssr`){let t={type:`fragment`,children:[]};return y(t,e),t}let t=document.createDocumentFragment();return y(t,e),t};function E(e,t){if(n===`ssr`)return{type:`component`,instance:{$$vani:`component`,component:e,props:t}};let r=document.createDocumentFragment();return m(e,t,r),r}let D=!1,O=!1,k=!1;const A=new Set,j=new Set;function M(e){let t=O;O=!0;try{e()}finally{O=t,N()}}function N(){k||(k=!0,setTimeout(()=>{k=!1,F()},0))}function P(){D||(D=!0,queueMicrotask(()=>{D=!1;for(let e of A)e.updateSync();A.clear()}))}function F(){for(let e of j)e.updateSync();j.clear(),j.size>0&&N()}let I=!1,L=null,R=0;function z(e){U()&&console.warn(`[vani] hydration warning: ${e}`)}function B(e,t){let n=L;(!n||!e.contains(n))&&(n=e.firstChild);let r=!1;for(;n;){if(n.nodeType===Node.COMMENT_NODE&&n.nodeValue===`vani:start`)return r&&z(`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 z(`Expected <!--vani:start--> for component #${t}, but none was found. This usually means the server HTML does not match the client component tree.`),Error(`[vani] hydration failed: start anchor not found`)}function V(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 L=n.nextSibling,n;--r}}n=n.nextSibling}throw z(`Expected <!--vani:end--> for component #${t}, but none was found. This usually means the server HTML does not match the client component tree.`),Error(`[vani] hydration failed: end anchor not found`)}function H(e,t){let n=[];I=!0,L=t.firstChild,R=0;try{n=h(e,t)}catch(e){console.error(`[vani] hydration failed:`,e)}finally{if(U()&&L){let e=L,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&&z(`Unused SSR anchors detected after hydration. Some server-rendered DOM was not claimed by the client runtime.`)}I=!1,L=null,R=0}return n}function U(){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}export{i as a,U as c,M as d,r as f,T as i,E as l,t as n,H as o,w as r,g as s,C as t,h as u};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
//#region src/vani/runtime.d.ts
|
|
2
|
+
type SSRNode = {
|
|
3
|
+
type: 'element';
|
|
4
|
+
tag: string;
|
|
5
|
+
props: Record<string, any>;
|
|
6
|
+
children: SSRNode[];
|
|
7
|
+
} | {
|
|
8
|
+
type: 'text';
|
|
9
|
+
text: string;
|
|
10
|
+
} | {
|
|
11
|
+
type: 'comment';
|
|
12
|
+
text: string;
|
|
13
|
+
} | {
|
|
14
|
+
type: 'fragment';
|
|
15
|
+
children: SSRNode[];
|
|
16
|
+
} | {
|
|
17
|
+
type: 'component';
|
|
18
|
+
instance: ComponentInstance<any>;
|
|
19
|
+
};
|
|
20
|
+
type VNode = Node | SSRNode;
|
|
21
|
+
interface Handle {
|
|
22
|
+
/**
|
|
23
|
+
* Schedules a render for the component.
|
|
24
|
+
* This triggers a re-render on the next microtask.
|
|
25
|
+
*/
|
|
26
|
+
update(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Flushes the component render.
|
|
29
|
+
* This triggers a re-render immediately.
|
|
30
|
+
*/
|
|
31
|
+
updateSync(): void;
|
|
32
|
+
/**
|
|
33
|
+
* Disposes the component: removes the component from the DOM and runs all cleanup functions.
|
|
34
|
+
*/
|
|
35
|
+
dispose(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Adds a cleanup function that is called when the component is disposed.
|
|
38
|
+
*/
|
|
39
|
+
onCleanup(fn: () => void): void;
|
|
40
|
+
/**
|
|
41
|
+
* This is purely syntatic sugar, as it is basically the same as running the function
|
|
42
|
+
* on the setup phase and calling onCleanup to add a cleanup function.
|
|
43
|
+
*
|
|
44
|
+
* Using effects is necessary in SSR mode, for side effects to not run on the server
|
|
45
|
+
* (e.g. timers, subscriptions, DOM usage, etc.)
|
|
46
|
+
*
|
|
47
|
+
* Runs a side effect function when the component is mounted.
|
|
48
|
+
* The returning function may be a cleanup function that is called when the component is disposed.
|
|
49
|
+
*
|
|
50
|
+
*/
|
|
51
|
+
effect(fn: () => void | (() => void)): void;
|
|
52
|
+
}
|
|
53
|
+
type RenderFn = () => VChild;
|
|
54
|
+
type Component<Props = any> = (props: Props, handle: Handle) => RenderFn | Promise<RenderFn>;
|
|
55
|
+
type ComponentInstance<Props = any> = {
|
|
56
|
+
$$vani: 'component';
|
|
57
|
+
component: Component<Props>;
|
|
58
|
+
props: Props;
|
|
59
|
+
/**
|
|
60
|
+
* A key is used to identify the component when it is re-rendered.
|
|
61
|
+
* If a key is provided, the component will be re-rendered only if the key changes.
|
|
62
|
+
*/
|
|
63
|
+
key?: string | number;
|
|
64
|
+
/**
|
|
65
|
+
* A ref is used to get a reference to the component instance.
|
|
66
|
+
* The ref is set to the component instance when the component is mounted.
|
|
67
|
+
* The ref is set to null when the component is disposed.
|
|
68
|
+
*/
|
|
69
|
+
ref?: ComponentRef;
|
|
70
|
+
clientOnly?: boolean;
|
|
71
|
+
};
|
|
72
|
+
type ComponentInput<Props> = Props & {
|
|
73
|
+
key?: string | number;
|
|
74
|
+
ref?: ComponentRef;
|
|
75
|
+
};
|
|
76
|
+
type ComponentMetaProps = {
|
|
77
|
+
key?: string | number;
|
|
78
|
+
ref?: ComponentRef;
|
|
79
|
+
fallback?: RenderFn;
|
|
80
|
+
clientOnly?: boolean;
|
|
81
|
+
};
|
|
82
|
+
type VChild = VNode | ComponentInstance<any> | string | number | null | undefined | false;
|
|
83
|
+
type DataAttribute = `data-${string}` | `data${Capitalize<string>}`;
|
|
84
|
+
type HtmlTagName = keyof HTMLElementTagNameMap;
|
|
85
|
+
type SvgTagName = keyof SVGElementTagNameMap;
|
|
86
|
+
type ElementTagName = HtmlTagName | SvgTagName;
|
|
87
|
+
type ElementByTag<T extends ElementTagName> = T extends HtmlTagName ? HTMLElementTagNameMap[T] : T extends SvgTagName ? SVGElementTagNameMap[T] : Element;
|
|
88
|
+
type SvgProps<T extends SvgTagName = SvgTagName> = BaseProps<T> & {
|
|
89
|
+
[key: string]: string | number | boolean | undefined | null | ((...args: any[]) => any);
|
|
90
|
+
};
|
|
91
|
+
type BaseProps<T extends ElementTagName> = {
|
|
92
|
+
className?: ClassName;
|
|
93
|
+
style?: string;
|
|
94
|
+
ref?: DomRef<ElementByTag<T>>;
|
|
95
|
+
} & {
|
|
96
|
+
[key: DataAttribute]: string | number | boolean | undefined | null;
|
|
97
|
+
};
|
|
98
|
+
type HtmlProps<T extends HtmlTagName = HtmlTagName> = BaseProps<T> & Partial<Omit<ElementByTag<T>, 'children' | 'className' | 'style'>>;
|
|
99
|
+
type ElementProps<T extends ElementTagName> = T extends SvgTagName ? SvgProps<T> : HtmlProps<Extract<T, HtmlTagName>>;
|
|
100
|
+
type ClassName = string | undefined | null | {
|
|
101
|
+
[key: string]: boolean | undefined | null;
|
|
102
|
+
} | ClassName[];
|
|
103
|
+
type ComponentRef = {
|
|
104
|
+
current: Handle | null;
|
|
105
|
+
};
|
|
106
|
+
type DomRef<T extends Element = Element> = {
|
|
107
|
+
current: T | null;
|
|
108
|
+
};
|
|
109
|
+
type RenderMode = 'dom' | 'ssr';
|
|
110
|
+
declare function component(fn: Component<void>): (props?: ComponentMetaProps) => ComponentInstance<void>;
|
|
111
|
+
declare function component<Props>(fn: Component<Props>): (props: Props & ComponentMetaProps) => ComponentInstance<Props>;
|
|
112
|
+
declare function withRenderMode<T>(mode: RenderMode, fn: () => T): T;
|
|
113
|
+
declare function getRenderMode(): RenderMode;
|
|
114
|
+
declare function renderToDOM(components: Array<Component<any> | ComponentInstance<any>>, root: HTMLElement): Handle[];
|
|
115
|
+
declare function isComponentInstance(child: VChild): child is ComponentInstance<any>;
|
|
116
|
+
declare function classNames(...classes: ClassName[]): string;
|
|
117
|
+
declare function el<E extends ElementTagName>(tag: E, props?: ElementProps<E> | VChild | null, ...children: VChild[]): VNode;
|
|
118
|
+
declare const fragment: (...children: VChild[]) => {
|
|
119
|
+
type: "fragment";
|
|
120
|
+
children: SSRNode[];
|
|
121
|
+
} | DocumentFragment;
|
|
122
|
+
declare function mount<Props>(component: Component<Props>, props: Props): VNode;
|
|
123
|
+
/**
|
|
124
|
+
* Marks all updates triggered inside the callback as a "transition".
|
|
125
|
+
*
|
|
126
|
+
* A transition represents non-urgent UI work that can be deferred
|
|
127
|
+
* to keep the application responsive.
|
|
128
|
+
*
|
|
129
|
+
* Updates scheduled inside `startTransition`:
|
|
130
|
+
* - do NOT block user interactions
|
|
131
|
+
* - are batched separately from urgent updates
|
|
132
|
+
* - may be flushed later (e.g. after the current event or during idle time)
|
|
133
|
+
*
|
|
134
|
+
* Transitions are NOT animations.
|
|
135
|
+
* They do not control how updates look, only *when* they are applied.
|
|
136
|
+
*
|
|
137
|
+
* Typical use cases:
|
|
138
|
+
* - Filtering or sorting large lists
|
|
139
|
+
* - Rendering expensive subtrees
|
|
140
|
+
* - Applying async results that are not immediately visible
|
|
141
|
+
*
|
|
142
|
+
* Example:
|
|
143
|
+
* ```ts
|
|
144
|
+
* button({
|
|
145
|
+
* onclick: () => {
|
|
146
|
+
* // urgent update
|
|
147
|
+
* setOpen(true)
|
|
148
|
+
* handle.update()
|
|
149
|
+
*
|
|
150
|
+
* // non-urgent update
|
|
151
|
+
* startTransition(() => {
|
|
152
|
+
* setItems(filter(items))
|
|
153
|
+
* handle.update()
|
|
154
|
+
* })
|
|
155
|
+
* },
|
|
156
|
+
* })
|
|
157
|
+
* ```
|
|
158
|
+
*
|
|
159
|
+
* If multiple transitions are triggered, they are automatically batched.
|
|
160
|
+
* Transition updates never interrupt urgent updates.
|
|
161
|
+
*/
|
|
162
|
+
declare function startTransition(fn: () => void): void;
|
|
163
|
+
declare function hydrateToDOM(components: Array<Component<any> | ComponentInstance<any>>, root: HTMLElement): Handle[];
|
|
164
|
+
declare function isDevMode(): boolean;
|
|
165
|
+
//#endregion
|
|
166
|
+
export { isDevMode as C, withRenderMode as D, startTransition as E, isComponentInstance as S, renderToDOM as T, component as _, ComponentRef as a, getRenderMode as b, ElementProps as c, RenderFn as d, SSRNode as f, classNames as g, VNode as h, ComponentInstance as i, Handle as l, VChild as m, Component as n, DataAttribute as o, SvgProps as p, ComponentInput as r, DomRef as s, ClassName as t, HtmlProps as u, el as v, mount as w, hydrateToDOM as x, fragment as y };
|
package/llms.txt
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
1
|
# Vani project agent guide
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
A fine-grained reactive open source framework for building lightning-fast apps — no virtual DOM, no
|
|
6
|
-
compiler, no JSX, no transpilation, zero dependencies, SSR support, imperative reactivity.
|
|
7
|
-
|
|
8
|
-
Check the DOCS.md and README.md files for more information.
|
|
3
|
+
Check the DOCS.md and README.md files for more information.
|