ilha 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -285
- package/dist/define.d.ts +5 -0
- package/dist/define.js +18 -0
- package/dist/index.d.ts +35 -2
- package/dist/index.js +51 -3209
- package/dist/jsx-dev-runtime.d.ts +4 -2
- package/dist/jsx-dev-runtime.js +3 -2
- package/dist/jsx-runtime.d.ts +8 -2
- package/dist/jsx-runtime.js +11 -2
- package/dist/mount-Dcy4teaf.js +992 -0
- package/dist/types-DU46exHq.d.ts +33 -0
- package/dist/vnode-BZLcG8lC.d.ts +20 -0
- package/dist/vnode-DHN2EFHi.js +37 -0
- package/package.json +19 -15
- package/dist/index-CVOjC94p.d.ts +0 -395
- package/dist/internal.d.ts +0 -77
- package/dist/internal.js +0 -62
- package/dist/jsx-runtime-CzU-60tX.d.ts +0 -631
- package/dist/jsx-runtime-DreKruAt.js +0 -124
package/README.md
CHANGED
|
@@ -1,355 +1,167 @@
|
|
|
1
1
|
# `ilha`
|
|
2
2
|
|
|
3
|
-
A tiny, isomorphic
|
|
3
|
+
A tiny, isomorphic UI library. You write a function component, declare `atom()` values, and render with JSX. Runs in the browser with signal reactivity and on the server as HTML. Powered by [Effect](https://effect.website) — no virtual DOM, no compiler.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm install ilha
|
|
10
|
+
npm install ilha effect
|
|
11
11
|
# or Bun
|
|
12
|
-
bun add ilha
|
|
12
|
+
bun add ilha effect
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
## Quick Start
|
|
18
|
-
|
|
19
|
-
```ts
|
|
20
|
-
import { ilha, state, action, html, mount } from "ilha";
|
|
21
|
-
|
|
22
|
-
const Counter = ilha(() => {
|
|
23
|
-
const count = state(0);
|
|
24
|
-
|
|
25
|
-
const increment = action(() => {
|
|
26
|
-
count.update((value) => value + 1);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
return html`
|
|
30
|
-
<div>
|
|
31
|
-
<p>Count: ${count()}</p>
|
|
32
|
-
<button onclick=${increment}>Increment</button>
|
|
33
|
-
</div>
|
|
34
|
-
`;
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
// SSR
|
|
38
|
-
Counter.toString(); // → '<div><p>Count: 0</p><button>Increment</button></div>'
|
|
39
|
-
|
|
40
|
-
// Client
|
|
41
|
-
Counter.mount(document.getElementById("app"));
|
|
42
|
-
```
|
|
15
|
+
`effect` is a peer dependency.
|
|
43
16
|
|
|
44
17
|
---
|
|
45
18
|
|
|
46
|
-
##
|
|
47
|
-
|
|
48
|
-
Islands are **function components** that know how to render themselves to an HTML string (SSR) and mount themselves into the DOM (client). Create one by passing the component to `ilha()`.
|
|
49
|
-
|
|
50
|
-
An island reruns when a reactive value it reads during rendering changes. Reactive primitives — `state()`, `derived()`, `action()`, `effect()`, `effect.once()`, and `onError()` — are registered by call order and persist across rerenders. Declare them at the component's top level in a stable order.
|
|
19
|
+
## Quick start
|
|
51
20
|
|
|
52
|
-
|
|
21
|
+
```tsx
|
|
22
|
+
import { atom, mount } from "ilha";
|
|
53
23
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
24
|
+
const Counter = () => {
|
|
25
|
+
const count = atom(0);
|
|
26
|
+
return (
|
|
27
|
+
<button type="button" onclick={() => count.update((n: number) => n + 1)}>
|
|
28
|
+
Count: {count}
|
|
29
|
+
</button>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
58
32
|
|
|
59
|
-
|
|
60
|
-
const Label = ilha<{ label: string }>(({ label }) => <span>{label}</span>);
|
|
33
|
+
mount(document.getElementById("app")!, Counter);
|
|
61
34
|
```
|
|
62
35
|
|
|
63
|
-
A
|
|
36
|
+
A **component** is a function, async function, or generator that returns a view. Nested functions share the parent fiber. `mount` / `renderToString` on a function makes it a root.
|
|
64
37
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
### `state(init?)`
|
|
38
|
+
---
|
|
68
39
|
|
|
69
|
-
|
|
40
|
+
## Atoms
|
|
70
41
|
|
|
71
42
|
```tsx
|
|
72
|
-
|
|
73
|
-
const count = state(0);
|
|
74
|
-
return <p>{count()}</p>;
|
|
75
|
-
});
|
|
43
|
+
import { atom } from "ilha";
|
|
76
44
|
|
|
45
|
+
const count = atom(0);
|
|
77
46
|
count(); // read
|
|
78
|
-
count.set(
|
|
79
|
-
count.update((
|
|
47
|
+
count.set(1); // replace
|
|
48
|
+
count.update((n) => n + 1); // patch
|
|
80
49
|
```
|
|
81
50
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
A state initializer applies only when the instance is created. Later prop changes rerender the component but do not reset state:
|
|
51
|
+
In JSX, `{count}` subscribes the render. A function initializer is a **computed** atom:
|
|
85
52
|
|
|
86
53
|
```tsx
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
return <p>{count()}</p>;
|
|
90
|
-
});
|
|
54
|
+
const items = atom([{ n: 1 }, { n: 2 }]);
|
|
55
|
+
const total = atom(() => items().reduce((sum, item) => sum + item.n, 0));
|
|
91
56
|
```
|
|
92
57
|
|
|
93
|
-
|
|
58
|
+
Atoms hold data. Do not store JSX in an atom.
|
|
94
59
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
```tsx
|
|
98
|
-
const UserCard = ilha<{ userId: string }>(({ userId }) => {
|
|
99
|
-
const user = derived(async ({ signal }) => {
|
|
100
|
-
const res = await fetch(`/api/users/${userId}`, { signal });
|
|
101
|
-
return res.json();
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
if (user.loading) return <p>Loading…</p>;
|
|
105
|
-
if (user.error) return <p>Error: {user.error.message}</p>;
|
|
106
|
-
return <p>{user()?.name}</p>;
|
|
107
|
-
});
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Async generators stream: each yielded value feeds the envelope. Stale runs abort via the passed `signal`.
|
|
111
|
-
|
|
112
|
-
### `action(fn)`
|
|
113
|
-
|
|
114
|
-
Define a reusable operation with reactive execution state. Use it when you render `pending`, `data`, or `error`, or when you need unmount cancellation:
|
|
115
|
-
|
|
116
|
-
```tsx
|
|
117
|
-
const save = action(async (form: FormData, { signal }) => {
|
|
118
|
-
const response = await fetch("/save", { method: "POST", body: form, signal });
|
|
119
|
-
return response.json();
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
save(payload);
|
|
123
|
-
save.pending;
|
|
124
|
-
save.data;
|
|
125
|
-
save.error;
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
Direct action references work as native event handlers (`onclick={save}`). Use plain functions for ordinary operations.
|
|
60
|
+
---
|
|
129
61
|
|
|
130
|
-
|
|
62
|
+
## Streams, when, watch, wait
|
|
131
63
|
|
|
132
|
-
|
|
64
|
+
Use a generator when you `yield*` instructions.
|
|
133
65
|
|
|
134
66
|
```tsx
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
67
|
+
import * as Stream from "effect/Stream";
|
|
68
|
+
import * as Atom from "effect/unstable/reactivity/Atom";
|
|
69
|
+
import { atom, when } from "ilha";
|
|
70
|
+
|
|
71
|
+
const Search = function* () {
|
|
72
|
+
const q = atom("");
|
|
73
|
+
yield (
|
|
74
|
+
<input value={q} oninput={(e: Event) => q.set((e.currentTarget as HTMLInputElement).value)} />
|
|
75
|
+
);
|
|
76
|
+
yield* when(Atom.toStream(q.atom).pipe(Stream.debounce("200 millis")), function* (query) {
|
|
77
|
+
if (!query) return;
|
|
78
|
+
yield <p>{query}</p>;
|
|
141
79
|
});
|
|
142
|
-
|
|
143
|
-
});
|
|
80
|
+
};
|
|
144
81
|
```
|
|
145
82
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
Register a per-island error handler. Context: `{ error, source, host }` with sources `"effect"`, `"once"`, `"event"`, and `"action"`. Fall back to the global [`onUncaughtError()`](#onuncaughterrorfn) for app-wide sinks.
|
|
151
|
-
|
|
152
|
-
## Typed props and validation
|
|
153
|
-
|
|
154
|
-
Pass a [Standard Schema](https://standardschema.dev)-compatible validator as the first `ilha()` argument to validate, coerce, and default props at runtime:
|
|
155
|
-
|
|
156
|
-
```tsx
|
|
157
|
-
import { z } from "zod";
|
|
158
|
-
|
|
159
|
-
const Greeting = ilha(z.object({ name: z.string().default("World") }), ({ name }) => (
|
|
160
|
-
<p>Hello, {name}!</p>
|
|
161
|
-
));
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
Validation runs during SSR, hydration, mount, and prop updates.
|
|
165
|
-
|
|
166
|
-
## Composing Islands
|
|
167
|
-
|
|
168
|
-
Nest islands as JSX components. Child islands render inline during SSR and mount independently on the client — a state change in a child does not re-render the parent:
|
|
169
|
-
|
|
170
|
-
```tsx
|
|
171
|
-
const Badge = ilha<{ label: string }>(({ label }) => <strong>{label}</strong>);
|
|
172
|
-
|
|
173
|
-
const Page = ilha(() => <Badge label="New" />);
|
|
174
|
-
```
|
|
83
|
+
- `when(stream, body)` — render `body` for each value (SSR takes the first).
|
|
84
|
+
- `watch(source, fn)` — side effect on an atom or Stream.
|
|
85
|
+
- `wait(body)` — paint until `done(value)`, then continue the generator.
|
|
175
86
|
|
|
176
|
-
|
|
87
|
+
Map a Stream of arrays to JSX for lists (`Stream.map`, `Atom.toStream`).
|
|
177
88
|
|
|
178
|
-
|
|
179
|
-
const Row = ilha(({ label }) => <li>{label}</li>, { as: "li" });
|
|
180
|
-
```
|
|
89
|
+
---
|
|
181
90
|
|
|
182
|
-
|
|
91
|
+
## SSR
|
|
183
92
|
|
|
184
93
|
```tsx
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const List = ilha(() => (
|
|
188
|
-
<ul>
|
|
189
|
-
{items.map((item) => {
|
|
190
|
-
const Keyed = Item.key(item.id);
|
|
191
|
-
return <Keyed label={item.label} />;
|
|
192
|
-
})}
|
|
193
|
-
</ul>
|
|
194
|
-
));
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
Keys must be unique within a parent render and cannot contain `:`.
|
|
198
|
-
|
|
199
|
-
## Island Interface
|
|
200
|
-
|
|
201
|
-
### `island.toString(props?)`
|
|
202
|
-
|
|
203
|
-
Synchronous SSR:
|
|
204
|
-
|
|
205
|
-
```ts
|
|
206
|
-
Counter.toString(); // → string
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
If the island declares async `derived()` values, `toString()` renders their loading state — use `await toStringAsync()` instead (a dev warning tells you when this happens).
|
|
210
|
-
|
|
211
|
-
### `await island.toStringAsync(props?)`
|
|
212
|
-
|
|
213
|
-
Async SSR — awaits async derived values and pulls the first value from async-generator derived values:
|
|
214
|
-
|
|
215
|
-
```ts
|
|
216
|
-
const html = await Counter.toStringAsync();
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### `island.mount(host, props?)`
|
|
220
|
-
|
|
221
|
-
Mount into a DOM element. Returns an unmount function that stops listeners, effects, and other active behavior:
|
|
222
|
-
|
|
223
|
-
```ts
|
|
224
|
-
const unmount = Counter.mount(document.getElementById("app"));
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### `await island.hydratable(props, options)`
|
|
228
|
-
|
|
229
|
-
Emit hydration markup with serialized props and an optional state snapshot. `name` must match the client registry key:
|
|
230
|
-
|
|
231
|
-
```ts
|
|
232
|
-
// Server
|
|
233
|
-
const html = await Counter.hydratable({}, { name: "Counter", snapshot: true });
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
```ts
|
|
237
|
-
// Client
|
|
238
|
-
mount({ Counter });
|
|
239
|
-
```
|
|
94
|
+
import { atom, renderToString, mount } from "ilha";
|
|
240
95
|
|
|
241
|
-
|
|
96
|
+
const Counter = () => {
|
|
97
|
+
const count = atom(0);
|
|
98
|
+
return <p>{count}</p>;
|
|
99
|
+
};
|
|
242
100
|
|
|
243
|
-
|
|
101
|
+
const html = await renderToString(Counter);
|
|
102
|
+
// <div data-ilha data-ilha-state="…"><p>0</p></div>
|
|
244
103
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
### `island.define(tagName, options?)`
|
|
248
|
-
|
|
249
|
-
Register the island as a custom element, usable from plain HTML or any framework:
|
|
250
|
-
|
|
251
|
-
```ts
|
|
252
|
-
Counter.define("x-counter", { observe: ["start"] });
|
|
104
|
+
const host = document.querySelector("[data-ilha]");
|
|
105
|
+
if (host) mount(host, Counter, { hydrate: true });
|
|
253
106
|
```
|
|
254
107
|
|
|
255
|
-
|
|
108
|
+
| Option | Default | Meaning |
|
|
109
|
+
| ---------------- | ------- | ------------------------------ |
|
|
110
|
+
| `snapshot` | `true` | Embed atom values |
|
|
111
|
+
| `markers` | `true` | Wrap in `<div data-ilha>` |
|
|
112
|
+
| `timeout` | none | Serialize after this many ms |
|
|
113
|
+
| `captureActions` | `false` | Probe handlers for server RPCs |
|
|
256
114
|
|
|
257
|
-
|
|
115
|
+
In Node, `renderToString` registers happy-dom when `document` is missing.
|
|
258
116
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
```ts
|
|
262
|
-
mount({ Counter, Badge });
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
Pass `{ root, lazy }` to scope discovery to a root element or defer mounting until hosts scroll into view.
|
|
266
|
-
|
|
267
|
-
### `effect(fn)`
|
|
117
|
+
---
|
|
268
118
|
|
|
269
|
-
|
|
119
|
+
## JSX
|
|
270
120
|
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"compilerOptions": {
|
|
124
|
+
"jsx": "react-jsx",
|
|
125
|
+
"jsxImportSource": "ilha"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
275
128
|
```
|
|
276
129
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
### `context(key, initial)`
|
|
280
|
-
|
|
281
|
-
Get or create a keyed, app-wide shared signal:
|
|
130
|
+
Event props are lowercase (`onclick`, `onchange`). Use `class`, not `className`. Use `h()` when you cannot use JSX.
|
|
282
131
|
|
|
283
|
-
|
|
284
|
-
const theme = context("app.theme", "light");
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
### `batch(fn)` / `untrack(fn)`
|
|
132
|
+
---
|
|
288
133
|
|
|
289
|
-
|
|
134
|
+
## Custom elements
|
|
290
135
|
|
|
291
136
|
```ts
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
137
|
+
import { atom } from "ilha";
|
|
138
|
+
import { define } from "ilha/define";
|
|
139
|
+
|
|
140
|
+
define("ilha-counter", () => {
|
|
141
|
+
const count = atom(0);
|
|
142
|
+
return (
|
|
143
|
+
<button type="button" onclick={() => count.update((n: number) => n + 1)}>
|
|
144
|
+
{count}
|
|
145
|
+
</button>
|
|
146
|
+
);
|
|
295
147
|
});
|
|
296
|
-
|
|
297
|
-
const value = untrack(() => secret());
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
### `persist(accessor, key)`
|
|
301
|
-
|
|
302
|
-
Keep a standalone signal in sync with `localStorage`:
|
|
303
|
-
|
|
304
|
-
```ts
|
|
305
|
-
persist(cart, "cart");
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
### `onUncaughtError(fn)`
|
|
309
|
-
|
|
310
|
-
Register an app-wide error sink for islands with no local `onError()`:
|
|
311
|
-
|
|
312
|
-
```ts
|
|
313
|
-
const stop = onUncaughtError((error, source) => telemetry.capture(error, { source }));
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
### `html` / `raw`
|
|
317
|
-
|
|
318
|
-
`html\`…\``is an XSS-safe tagged template that accepts signals, arrays, and nested templates.`raw(str)` opts into trusted markup:
|
|
319
|
-
|
|
320
|
-
```ts
|
|
321
|
-
import { html, raw } from "ilha";
|
|
322
|
-
|
|
323
|
-
html`<p>${count()}</p>`;
|
|
324
|
-
html`<button>${raw(icon)}</button>`;
|
|
325
148
|
```
|
|
326
149
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
Use `bind:*` inside JSX or `html`` for two-way form synchronization:
|
|
330
|
-
|
|
331
|
-
```tsx
|
|
332
|
-
<input bind:value={name} />
|
|
333
|
-
<input type="checkbox" bind:checked={done} />
|
|
150
|
+
```html
|
|
151
|
+
<ilha-counter data-ilha></ilha-counter>
|
|
334
152
|
```
|
|
335
153
|
|
|
336
|
-
|
|
154
|
+
---
|
|
337
155
|
|
|
338
|
-
##
|
|
156
|
+
## Routing and Astro
|
|
339
157
|
|
|
340
|
-
|
|
158
|
+
- [`@ilha/router`](https://github.com/ilhajs/ilha/tree/main/packages/router) — file-system SPA routes and Oxide server islands.
|
|
159
|
+
- [`@ilha/astro`](https://github.com/ilhajs/ilha/tree/main/packages/astro) — Astro renderer (`renderToString` + `mount`).
|
|
341
160
|
|
|
342
|
-
|
|
161
|
+
Docs: [ilha.build](https://ilha.build)
|
|
343
162
|
|
|
344
|
-
|
|
163
|
+
---
|
|
345
164
|
|
|
346
|
-
|
|
347
|
-
{
|
|
348
|
-
"compilerOptions": {
|
|
349
|
-
"jsx": "react-jsx",
|
|
350
|
-
"jsxImportSource": "ilha"
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
```
|
|
165
|
+
## License
|
|
354
166
|
|
|
355
|
-
|
|
167
|
+
MIT
|
package/dist/define.d.ts
ADDED
package/dist/define.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { t as mount } from "./mount-Dcy4teaf.js";
|
|
2
|
+
|
|
3
|
+
//#region src/define.ts
|
|
4
|
+
function define(name, component) {
|
|
5
|
+
customElements.define(name, class extends HTMLElement {
|
|
6
|
+
#unmount;
|
|
7
|
+
connectedCallback() {
|
|
8
|
+
this.#unmount = mount(this, component, { hydrate: this.hasAttribute("data-ilha") });
|
|
9
|
+
}
|
|
10
|
+
disconnectedCallback() {
|
|
11
|
+
this.#unmount?.();
|
|
12
|
+
this.#unmount = void 0;
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { define };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,35 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { a as Instruction, c as Yielded, i as Fragment, n as Component, r as Done, s as View, t as AtomHandle } from "./types-DU46exHq.js";
|
|
2
|
+
import { t as h } from "./vnode-BZLcG8lC.js";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Stream from "effect/Stream";
|
|
5
|
+
import * as Atom from "effect/unstable/reactivity/Atom";
|
|
6
|
+
import "effect/Scope";
|
|
7
|
+
import { AtomRegistry } from "effect/unstable/reactivity/AtomRegistry";
|
|
8
|
+
//#region src/atom.d.ts
|
|
9
|
+
declare function atom<A>(init: () => A): AtomHandle<A>;
|
|
10
|
+
declare function atom<A>(init: A | Atom.Atom<A> | Effect.Effect<A, any, any> | Stream.Stream<A, any, any>): AtomHandle<A>;
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/when.d.ts
|
|
13
|
+
declare function when<A, E = never, R = never>(stream: Stream.Stream<A, E, R>, body: (value: A) => Generator<Yielded, View | void, unknown>): Instruction<void, E>;
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/watch.d.ts
|
|
16
|
+
declare function watch<A>(source: AtomHandle<A> | Atom.Atom<A> | Stream.Stream<A, any, any>, fn: (value: A) => void): Instruction<void>;
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/wait.d.ts
|
|
19
|
+
declare function wait<A>(body: (done: Done<A>) => Generator<Yielded, View | void, unknown>): Instruction<A>;
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/mount.d.ts
|
|
22
|
+
type RenderToStringOptions = {
|
|
23
|
+
snapshot?: boolean;
|
|
24
|
+
markers?: boolean;
|
|
25
|
+
timeout?: number;
|
|
26
|
+
captureActions?: boolean;
|
|
27
|
+
};
|
|
28
|
+
type MountOptions = {
|
|
29
|
+
hydrate?: boolean;
|
|
30
|
+
onError?: (error: unknown) => void;
|
|
31
|
+
};
|
|
32
|
+
declare function mount(el: Element, fn: Component, opts?: MountOptions): () => void;
|
|
33
|
+
declare function renderToString(fn: Component, opts?: RenderToStringOptions): Promise<string>;
|
|
34
|
+
//#endregion
|
|
35
|
+
export { type AtomHandle, type Component, type Done, Fragment, type MountOptions, type RenderToStringOptions, type View, atom, h, mount, renderToString, wait, watch, when };
|