@alixex/ranview 0.1.0-alpha.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/dist/core.d.ts ADDED
@@ -0,0 +1,254 @@
1
+ import type { EventManager } from './events';
2
+ import { type Getter } from './signal';
3
+ export interface Ref<T extends HTMLElement = HTMLElement> {
4
+ current: T | null;
5
+ }
6
+ export declare const createRef: <T extends HTMLElement = HTMLElement>() => Ref<T>;
7
+ /** A single directly-appendable child: element, text, nested builder, or nothing.
8
+ * Internal helper — the public, general type is {@link Child}. */
9
+ type StaticChild = HTMLElement | string | ElementBuilder<any> | undefined | null;
10
+ /**
11
+ * The one type every `children()` / `replaceChildren()` argument accepts —
12
+ * fully composable (recursive): a node, text, nested builder, `null`/`undefined`,
13
+ * a (nested) array, a {@link For}/{@link Index} handle for a keyed list, or a
14
+ * getter `() => Child` marking a reactive region. A getter (or `Show`/`Switch`
15
+ * branch) may itself return any `Child`, including a `For`/`Index` or another
16
+ * getter — control-flow nests freely. On SSR getters / `For` / `Index` render once.
17
+ */
18
+ export type Child = StaticChild | ForHandle | IndexHandle | Child[] | (() => Child);
19
+ declare const FOR_BRAND = "__ranFor";
20
+ /** Options for {@link For}. */
21
+ export interface ForOptions<T> {
22
+ /** Reactive source array. Read inside an effect, so the list updates on change. */
23
+ each: () => readonly T[] | null | undefined;
24
+ /** Stable identity per item — **must be unique** within the list. Reused across
25
+ * updates to match old nodes to new items (that is what preserves DOM state). */
26
+ key: (item: T, index: number) => string | number;
27
+ /** Render one item to a single node. `index` is a **getter** (reactive): it
28
+ * reflects the item's current position even after the list reorders. Runs once
29
+ * per item (not on every list change) — drive per-item updates with signals. */
30
+ render: (item: T, index: Getter<number>) => StaticChild;
31
+ }
32
+ /** Opaque handle returned by {@link For}; pass it straight to `children()`. */
33
+ export type ForHandle = {
34
+ readonly [FOR_BRAND]: true;
35
+ };
36
+ /**
37
+ * Keyed list for `children()`. Unlike a plain getter child (which rebuilds the
38
+ * whole region on every change), `For` matches items by `key` and **reuses their
39
+ * DOM nodes** — only added/removed/moved items touch the DOM, so focus, scroll,
40
+ * input values and in-flight transitions inside surviving rows are preserved.
41
+ *
42
+ * Ul().children(
43
+ * For({
44
+ * each: () => rows(),
45
+ * key: (r) => r.id,
46
+ * render: (r, i) => Li().text(() => `${i()}. ${r.title}`),
47
+ * }),
48
+ * );
49
+ *
50
+ * On SSR the list is rendered once as a static snapshot. Must be built inside a
51
+ * `createRoot` so per-item scopes are disposed with the page.
52
+ */
53
+ export declare function For<T>(options: ForOptions<T>): ForHandle;
54
+ /** Options for {@link Show}. */
55
+ export interface ShowOptions<T> {
56
+ /** Condition source. Truthy → `children`, falsy → `fallback`. */
57
+ when: () => T;
58
+ /** Built when `when` is truthy. May return any {@link Child} — a `For`/`Index`
59
+ * list, a nested `Show`, etc. Receives an accessor to the narrowed value —
60
+ * read it inside a binding (`.text(() => v())`) to update without rebuilding. */
61
+ children: (value: () => NonNullable<T>) => Child;
62
+ /** Built when `when` is falsy. Omitted → nothing is rendered. */
63
+ fallback?: () => Child;
64
+ }
65
+ /**
66
+ * Fine-grained conditional child. Unlike a raw getter child (which re-runs on
67
+ * **every** change it reads), `Show` rebuilds the branch **only when the
68
+ * truthiness of `when` flips** — the condition is memoized. Content inside a
69
+ * branch updates through its own bindings, not by re-running `Show`. This is the
70
+ * SwiftUI/Solid model: build once, toggle only when the branch actually changes.
71
+ *
72
+ * Show({
73
+ * when: () => user(), // reads a signal
74
+ * children: (u) => Div().text(() => u().name),
75
+ * fallback: () => Div().text('Signed out'),
76
+ * })
77
+ *
78
+ * `Show` returns a getter, so it is accepted anywhere `children()` takes a child.
79
+ * Must be created inside a `createRoot` (it owns a memo + the branch effect).
80
+ */
81
+ export declare function Show<T>(options: ShowOptions<T>): () => Child;
82
+ /** One branch of a {@link Switch}; build with {@link Match}. */
83
+ export interface MatchClause<T> {
84
+ when: () => T;
85
+ children: (value: () => NonNullable<T>) => Child;
86
+ }
87
+ /** Declare one `Switch` branch (identity helper — gives per-clause type inference). */
88
+ export declare function Match<T>(clause: MatchClause<T>): MatchClause<T>;
89
+ /** Options for {@link Switch}. */
90
+ export interface SwitchOptions {
91
+ /** Branches, tried in order; the first with a truthy `when` renders. Clauses are
92
+ * heterogeneous (each `Match<T>` carries its own `T`), hence `any` here. */
93
+ children: MatchClause<any>[];
94
+ /** Rendered when no branch matches. Omitted → nothing. */
95
+ fallback?: () => Child;
96
+ }
97
+ /**
98
+ * Fine-grained multi-branch conditional (the n-way `Show`). Renders the first
99
+ * `Match` whose `when` is truthy, else `fallback`. Only the **index of the
100
+ * winning branch** is memoized, so it rebuilds only when the active branch
101
+ * changes — not on every change a `when` reads. Evaluation short-circuits at the
102
+ * first match (later branches aren't subscribed while an earlier one wins).
103
+ *
104
+ * Switch({
105
+ * fallback: () => Span().text('idle'),
106
+ * children: [
107
+ * Match({ when: () => status() === 'loading', children: () => Spinner() }),
108
+ * Match({ when: () => error(), children: (e) => ErrorView(e) }),
109
+ * ],
110
+ * })
111
+ */
112
+ export declare function Switch(options: SwitchOptions): () => Child;
113
+ declare const INDEX_BRAND = "__ranIndex";
114
+ /** Options for {@link Index}. */
115
+ export interface IndexOptions<T> {
116
+ /** Reactive source array. */
117
+ each: () => readonly T[] | null | undefined;
118
+ /** Render the slot at a position. `item` is a **getter** (a signal): when the
119
+ * value at this index changes, it updates in place — the node is not rebuilt.
120
+ * `index` is a fixed number (the position never moves). */
121
+ render: (item: () => T, index: number) => StaticChild;
122
+ }
123
+ /** Opaque handle returned by {@link Index}; pass it straight to `children()`. */
124
+ export type IndexHandle = {
125
+ readonly [INDEX_BRAND]: true;
126
+ };
127
+ /**
128
+ * Position-keyed list. The node at index `i` is **reused** across updates and its
129
+ * `item` signal is updated in place — nodes never move. Use it when position is
130
+ * the identity (primitive arrays, fixed-length rows). Use {@link For} instead
131
+ * when items have a stable id and can reorder. SSR renders once.
132
+ *
133
+ * Ul().children(
134
+ * Index({ each: () => nums(), render: (n, i) => Li().text(() => `${i}: ${n()}`) }),
135
+ * );
136
+ */
137
+ export declare function Index<T>(options: IndexOptions<T>): IndexHandle;
138
+ export declare const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
139
+ export declare class ElementBuilder<T extends HTMLElement = HTMLElement> {
140
+ private el;
141
+ /**
142
+ * @param tag element name
143
+ * @param namespace element namespace; inferred for SVG-only tags, and forced
144
+ * by `Svg()` for the tags SVG shares with HTML.
145
+ *
146
+ * The namespace matters more than it looks. `document.createElement('svg')`
147
+ * yields an `HTMLUnknownElement`: the browser does not render it as SVG, and
148
+ * -- because HTML lowercases attribute names -- `viewBox` lands as `viewbox`,
149
+ * which SVG reads case-sensitively and therefore ignores. An icon built that
150
+ * way is invisible, with markup that looks right in a serialized page.
151
+ */
152
+ constructor(tag: string, namespace?: string);
153
+ id(value: string): this;
154
+ /**
155
+ * Apply a value now, or bind it reactively when a getter is passed.
156
+ * A getter creates an effect owned by the current reactive scope (createRoot),
157
+ * so the binding is disposed automatically when that scope is torn down.
158
+ */
159
+ private bind;
160
+ /**
161
+ * Sets the element's class.
162
+ *
163
+ * Written through `setAttribute` rather than `className`. On an SVG element `className`
164
+ * is a read-only `SVGAnimatedString`, so assigning to it throws
165
+ * `Cannot set property className of [object SVGElement] which has only a getter` — which,
166
+ * happening inside a custom element's constructor, leaves the element un-upgraded with
167
+ * no shadow root rather than reporting a styling problem. `setAttribute` is equivalent
168
+ * for HTML elements and correct for both.
169
+ */
170
+ class(name: string | Getter<string>): this;
171
+ addClass(...names: string[]): this;
172
+ removeClass(...names: string[]): this;
173
+ attr(name: string, value: string | Getter<string>): this;
174
+ attrs(values: Record<string, string | number | boolean | null | undefined>): this;
175
+ boolAttr(name: string, value: boolean | Getter<boolean>, enabledValue?: string): this;
176
+ part(value: string | Getter<string>): this;
177
+ data(key: string, value: string | Getter<string>): this;
178
+ style(keyOrMap: string | Record<string, string>, value?: string | Getter<string>): this;
179
+ cssVar(name: string, value: string | Getter<string>): this;
180
+ aria(key: string, value: string | Getter<string>): this;
181
+ role(value: string | Getter<string>): this;
182
+ tabIndex(value: number): this;
183
+ label(value: string | Getter<string>): this;
184
+ labelledBy(id: string | Getter<string>): this;
185
+ describedBy(id: string | Getter<string>): this;
186
+ ariaHidden(hidden?: boolean): this;
187
+ /**
188
+ * Permanent build-time listener — tied to the element's lifetime.
189
+ * Use for internal shadow DOM elements created in the constructor.
190
+ */
191
+ on<K extends keyof HTMLElementEventMap>(type: K, listener: (this: T, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): this;
192
+ /**
193
+ * Lifecycle-managed listener — registered into an EventManager.
194
+ * Use in connectedCallback when building elements that need cleanup on disconnect.
195
+ * Call manager.abort() in disconnectedCallback to remove all listeners at once.
196
+ */
197
+ listen<K extends keyof HTMLElementEventMap>(manager: EventManager, type: K, handler: (this: T, ev: HTMLElementEventMap[K]) => any, options?: Omit<AddEventListenerOptions, 'signal'>): this;
198
+ /**
199
+ * Delegated listener — the built element acts as the parent container.
200
+ * Fires handler only when the event originates from a descendant matching selector.
201
+ * Registered into an EventManager so it is cleaned up with manager.abort().
202
+ *
203
+ * Div().class('list')
204
+ * .children(...)
205
+ * .delegate(scope, '.item', 'click', (ev, item) => handleItem(item))
206
+ * .build();
207
+ */
208
+ delegate<K extends keyof HTMLElementEventMap>(manager: EventManager, selector: string, type: K, handler: (ev: HTMLElementEventMap[K], target: Element) => void, options?: Omit<AddEventListenerOptions, 'signal'>): this;
209
+ children(...items: Child[]): this;
210
+ replaceChildren(...items: Child[]): this;
211
+ text(value: string | Getter<string>): this;
212
+ /**
213
+ * Set the element's content from a string of markup, without escaping it.
214
+ *
215
+ * The counterpart to `text()`, and named for the difference: `text()` escapes,
216
+ * this does not. Everything handed here is parsed as HTML, so anything that
217
+ * came from outside the program must be sanitized before it arrives.
218
+ *
219
+ * It exists because some content simply *is* HTML, and a builder without this
220
+ * cannot express it at all: markdown rendered for a page, a fragment assembled
221
+ * somewhere else, a translated string that carries its own emphasis
222
+ * (`Local-first · <b>open source</b>`). That gap is why a static-site
223
+ * generator with markdown in it could not be written against this API and had
224
+ * to concatenate strings instead.
225
+ *
226
+ * Like `textContent`, this replaces whatever content the element had --
227
+ * including anything set by `text()` or `children()` before it.
228
+ */
229
+ unsafeHtml(value: string | Getter<string>): this;
230
+ ref(holder: Ref<T>): this;
231
+ shadow(options?: ShadowRootInit): ShadowBuilder<T>;
232
+ build(): T;
233
+ serialize(): string;
234
+ }
235
+ export declare class ShadowBuilder<T extends HTMLElement = HTMLElement> {
236
+ private root;
237
+ private hostEl;
238
+ /**
239
+ * `options` is taken and discarded: `attachShadow` has already consumed it by the time
240
+ * a builder exists, and nothing ever read the copy this class used to keep. The
241
+ * parameter stays so the call signature is unchanged.
242
+ */
243
+ constructor(host: T, root: ShadowRoot, _options: ShadowRootInit);
244
+ children(...items: Child[]): this;
245
+ adoptSheet(...sheets: CSSStyleSheet[]): this;
246
+ css(cssText: string): this;
247
+ done(): {
248
+ host: T;
249
+ shadow: ShadowRoot;
250
+ };
251
+ serialize(): string;
252
+ }
253
+ export {};
254
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
package/dist/env.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare const isSSR: boolean;
2
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,SAAkC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { escapeHtml } from 'ranuts/utils';
2
+ export { escapeHtml };
3
+ /**
4
+ * 属性值转义。当前与 `escapeHtml` 完全一致:单双引号都会被转义,所以带引号、
5
+ * 不带引号的属性值都安全。保留独立的名字是为了在调用点标出意图。
6
+ */
7
+ export declare function escapeHtmlAttribute(unsafe: string): string;
8
+ //# sourceMappingURL=escape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../src/escape.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE1D"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * EventManager — lifecycle-scoped event registry backed by AbortController.
3
+ *
4
+ * Web Component usage:
5
+ *
6
+ * private _events = new EventManager();
7
+ *
8
+ * connectedCallback() {
9
+ * this._events
10
+ * .on(this._input, 'input', this.handleInput)
11
+ * .on(this, 'click', this.handleClick, { capture: true });
12
+ * }
13
+ *
14
+ * disconnectedCallback() {
15
+ * this._events.abort(); // removes all listeners, resets for next connect
16
+ * }
17
+ *
18
+ * Page development usage:
19
+ *
20
+ * function initSection(container: HTMLElement) {
21
+ * const scope = new EventManager();
22
+ *
23
+ * scope
24
+ * .on(input, 'input', handleSearch)
25
+ * .delegate(container, '[data-action]', 'click', (ev, target) => {
26
+ * handleAction(target.getAttribute('data-action'));
27
+ * });
28
+ *
29
+ * return () => scope.abort(); // call on section teardown
30
+ * }
31
+ */
32
+ export declare class EventManager {
33
+ /**
34
+ * Created on first use, and dropped again by {@link abort}.
35
+ *
36
+ * No component registers a listener in its constructor — they all wait for
37
+ * `connectedCallback` — and some managers, like the drag-scoped one in `r-progress`,
38
+ * only ever register during an interaction that may not happen. Allocating eagerly
39
+ * charged every construction, and every `abort()`, for a controller that might go unused:
40
+ * about 30% of a mount/unmount cycle for `r-progress`.
41
+ */
42
+ private ac;
43
+ /** The underlying AbortSignal — pass to addEventListener options directly if needed. */
44
+ get signal(): AbortSignal;
45
+ on<K extends keyof HTMLElementEventMap>(target: HTMLElement, type: K, handler: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: Omit<AddEventListenerOptions, 'signal'>): this;
46
+ on(target: EventTarget, type: string, handler: EventListener, options?: Omit<AddEventListenerOptions, 'signal'>): this;
47
+ /**
48
+ * Event delegation — attach one listener to `parent`, fire `handler` only when
49
+ * the event originates from a descendant matching `selector`.
50
+ *
51
+ * The handler receives the original event and the matched element as arguments.
52
+ *
53
+ * scope.delegate(list, '.item', 'click', (ev, item) => {
54
+ * console.log(item.dataset.id);
55
+ * });
56
+ */
57
+ delegate<K extends keyof HTMLElementEventMap>(parent: HTMLElement, selector: string, type: K, handler: (ev: HTMLElementEventMap[K], target: Element) => void, options?: Omit<AddEventListenerOptions, 'signal'>): this;
58
+ /**
59
+ * Remove all registered listeners and drop the controller.
60
+ * Safe to call multiple times; the next on() / delegate() starts a fresh one.
61
+ */
62
+ abort(): void;
63
+ }
64
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,YAAY;IACvB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,CAAgC;IAE1C,wFAAwF;IACxF,IAAI,MAAM,IAAI,WAAW,CAGxB;IAED,EAAE,CAAC,CAAC,SAAS,MAAM,mBAAmB,EACpC,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,GAAG,EAC/D,OAAO,CAAC,EAAE,IAAI,CAAC,uBAAuB,EAAE,QAAQ,CAAC,GAChD,IAAI,CAAC;IACR,EAAE,CACA,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,IAAI,CAAC,uBAAuB,EAAE,QAAQ,CAAC,GAChD,IAAI,CAAC;IAMR;;;;;;;;;OASG;IACH,QAAQ,CAAC,CAAC,SAAS,MAAM,mBAAmB,EAC1C,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,CAAC,EAAE,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,EAC9D,OAAO,CAAC,EAAE,IAAI,CAAC,uBAAuB,EAAE,QAAQ,CAAC,GAChD,IAAI,CAUN;IAED;;;OAGG;IACH,KAAK,IAAI,IAAI,CAGZ;CACF"}
@@ -0,0 +1,33 @@
1
+ import { ElementBuilder } from './core';
2
+ export declare const View: <T extends HTMLElement = HTMLElement>(tag: string) => ElementBuilder<T>;
3
+ export declare const Div: () => ElementBuilder<HTMLDivElement>;
4
+ /**
5
+ * An element in the SVG namespace.
6
+ *
7
+ * `View()` already infers it for tags that only exist in SVG (`path`, `circle`,
8
+ * `g`, …), so this is for the ones SVG shares with HTML -- `a`, `script`,
9
+ * `style`, `title` -- where guessing would break the commoner HTML case.
10
+ *
11
+ * ```ts
12
+ * View('svg').attrs({ viewBox: '0 0 16 16' }).children(
13
+ * Svg('a').attr('href', '#').children(View('path').attr('d', 'M1 1').build()).build(),
14
+ * );
15
+ * ```
16
+ */
17
+ export declare const Svg: <T extends HTMLElement = HTMLElement>(tag: string) => ElementBuilder<T>;
18
+ export declare const Span: () => ElementBuilder<HTMLSpanElement>;
19
+ export declare const Slot: () => ElementBuilder<HTMLSlotElement>;
20
+ export declare const ButtonBuilder: () => ElementBuilder<HTMLButtonElement>;
21
+ export declare const InputBuilder: () => ElementBuilder<HTMLInputElement>;
22
+ export declare const Style: () => ElementBuilder<HTMLStyleElement>;
23
+ export declare const Label: () => ElementBuilder<HTMLLabelElement>;
24
+ export declare const Ul: () => ElementBuilder<HTMLUListElement>;
25
+ export declare const Li: () => ElementBuilder<HTMLLIElement>;
26
+ export declare const Section: () => ElementBuilder<HTMLElement>;
27
+ export declare const Article: () => ElementBuilder<HTMLElement>;
28
+ export declare const Nav: () => ElementBuilder<HTMLElement>;
29
+ export declare const Header: () => ElementBuilder<HTMLElement>;
30
+ export declare const Footer: () => ElementBuilder<HTMLElement>;
31
+ export declare const Main: () => ElementBuilder<HTMLElement>;
32
+ export declare const DeclarativeShadow: (mode?: 'open' | 'closed', delegatesFocus?: boolean) => ElementBuilder<HTMLTemplateElement>;
33
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,MAAM,QAAQ,CAAC;AAEvD,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,WAAW,GAAG,WAAW,OAAO,MAAM,KAAG,cAAc,CAAC,CAAC,CAA+B,CAAC;AACxH,eAAO,MAAM,GAAG,QAAO,cAAc,CAAC,cAAc,CAAgC,CAAC;AAErF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,GAAG,GAAI,CAAC,SAAS,WAAW,GAAG,WAAW,OAAO,MAAM,KAAG,cAAc,CAAC,CAAC,CAC5C,CAAC;AAC5C,eAAO,MAAM,IAAI,QAAO,cAAc,CAAC,eAAe,CAAkC,CAAC;AACzF,eAAO,MAAM,IAAI,QAAO,cAAc,CAAC,eAAe,CAAkC,CAAC;AACzF,eAAO,MAAM,aAAa,QAAO,cAAc,CAAC,iBAAiB,CAAsC,CAAC;AACxG,eAAO,MAAM,YAAY,QAAO,cAAc,CAAC,gBAAgB,CAAoC,CAAC;AACpG,eAAO,MAAM,KAAK,QAAO,cAAc,CAAC,gBAAgB,CAAoC,CAAC;AAC7F,eAAO,MAAM,KAAK,QAAO,cAAc,CAAC,gBAAgB,CAAoC,CAAC;AAC7F,eAAO,MAAM,EAAE,QAAO,cAAc,CAAC,gBAAgB,CAAiC,CAAC;AACvF,eAAO,MAAM,EAAE,QAAO,cAAc,CAAC,aAAa,CAA8B,CAAC;AACjF,eAAO,MAAM,OAAO,QAAO,cAAc,CAAC,WAAW,CAAiC,CAAC;AACvF,eAAO,MAAM,OAAO,QAAO,cAAc,CAAC,WAAW,CAAiC,CAAC;AACvF,eAAO,MAAM,GAAG,QAAO,cAAc,CAAC,WAAW,CAA6B,CAAC;AAC/E,eAAO,MAAM,MAAM,QAAO,cAAc,CAAC,WAAW,CAAgC,CAAC;AACrF,eAAO,MAAM,MAAM,QAAO,cAAc,CAAC,WAAW,CAAgC,CAAC;AACrF,eAAO,MAAM,IAAI,QAAO,cAAc,CAAC,WAAW,CAA8B,CAAC;AAEjF,eAAO,MAAM,iBAAiB,UACtB,MAAM,GAAG,QAAQ,+BAEtB,cAAc,CAAC,mBAAmB,CAKpC,CAAC"}
package/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./signal.cjs"),t=require("./mocks-DvJQ7jGP.cjs");let n=require("ranuts/utils");var r=typeof document>`u`,i=class{ac=null;get signal(){return this.ac??=new AbortController,this.ac.signal}on(e,t,n,r){return e.addEventListener(t,n,{...r,signal:this.signal}),this}delegate(e,t,n,r,i){return e.addEventListener(n,n=>{let i=n.target?.closest(t);i&&e.contains(i)&&r(n,i)},{...i,signal:this.signal}),this}abort(){this.ac?.abort(),this.ac=null}},a=()=>({current:null}),o=e=>e.reduce((e,t)=>Array.isArray(t)?e.concat(o(t)):e.concat(t),[]),s=e=>e==null?null:e instanceof D?e.build():typeof e==`string`?r?e:document.createTextNode(e):e,c=(t,n)=>{if(r){C(t,[n()]);return}let i=document.createComment(``),a=document.createComment(``);t.appendChild(i),t.appendChild(a);let o=null,s=()=>{o?.(),o=null;let e=i.nextSibling;for(;e&&e!==a;){let t=e.nextSibling;e.parentNode?.removeChild(e),e=t}};e.createEffect(()=>{let t=n();s();let r=document.createDocumentFragment();o=e.createRoot(e=>(C(r,[t]),e)),a.parentNode?.insertBefore(r,a)}),e.onCleanup(()=>o?.())},l=`__ranFor`;function u(e){return{...e,[l]:!0}}var d=e=>typeof e==`object`&&!!e&&e[l]===!0;function f(t){let n=e.computed(()=>!!t.when()),r=()=>t.when();return()=>n()?t.children(r):t.fallback?.()??null}function p(e){return e}function m(t){let n=t.children,r=e.computed(()=>n.findIndex(e=>!!e.when()));return()=>{let e=r();if(e<0)return t.fallback?.()??null;let i=n[e];return i.children(()=>i.when())}}var h=(t,n,r)=>{let[i,a]=e.signal(n),o=null,c=e.createRoot(e=>{let n=s(r(t,i));return o=typeof n==`string`?document.createTextNode(n):n,e});return{node:o,index:a,dispose:c}},g=(e,t)=>{let n=e.parentNode;if(!n)return;let r=e;for(let e of t)r.nextSibling!==e&&n.insertBefore(e,r.nextSibling),r=e},_=(t,n)=>{if(r){(n.each()??[]).forEach((e,r)=>{let i=s(n.render(e,()=>r));i!=null&&t.appendChild(i)});return}let i=document.createComment(``);t.appendChild(i);let a=new Map;e.onCleanup(()=>{for(let e of a.values())e.dispose();a.clear()}),e.createEffect(()=>{let e=n.each()??[],t=new Map,r=[];e.forEach((e,i)=>{let o=n.key(e,i);if(t.has(o)){E()&&console.error(`[ranview For] duplicate key "${String(o)}" — keys must be unique; ignoring the duplicate item.`);return}let s=a.get(o);s?(a.delete(o),s.index(i)):s=h(e,i,n.render),t.set(o,s),s.node&&r.push(s.node)});for(let e of a.values())e.node?.parentNode?.removeChild(e.node),e.dispose();g(i,r),a=t})},v=`__ranIndex`;function y(e){return{...e,[v]:!0}}var b=e=>typeof e==`object`&&!!e&&e[v]===!0,x=(t,n,r)=>{let[i,a]=e.signal(t),o=null,c=e.createRoot(e=>{let t=s(r(i,n));return o=typeof t==`string`?document.createTextNode(t):t,e});return{node:o,setItem:a,dispose:c}},S=(t,n)=>{if(r){(n.each()??[]).forEach((e,r)=>{let i=s(n.render(()=>e,r));i!=null&&t.appendChild(i)});return}let i=document.createComment(``);t.appendChild(i);let a=[];e.onCleanup(()=>{for(let e of a)e.dispose();a=[]}),e.createEffect(()=>{let e=n.each()??[];for(let t=0;t<e.length;t++)t<a.length?a[t].setItem(e[t]):a.push(x(e[t],t,n.render));for(let t=a.length-1;t>=e.length;t--){let{node:e}=a[t];e?.parentNode?.removeChild(e),a[t].dispose(),a.pop()}g(i,a.map(e=>e.node).filter(e=>e!=null))})},C=(e,t)=>{o(t).forEach(t=>{if(d(t)){_(e,t);return}if(b(t)){S(e,t);return}if(typeof t==`function`){c(e,t);return}let n=s(t);n!=null&&e.appendChild(n)})},w=`http://www.w3.org/2000/svg`,T=new Set(`svg.circle.clipPath.defs.desc.ellipse.feBlend.feColorMatrix.feComposite.feDropShadow.feFlood.feGaussianBlur.feMerge.feMergeNode.feOffset.filter.foreignObject.g.image.line.linearGradient.marker.mask.path.pattern.polygon.polyline.radialGradient.rect.stop.switch.symbol.text.textPath.tspan.use`.split(`.`)),E=()=>!1,D=class{el;constructor(e,n){let i=n??(T.has(e)?`http://www.w3.org/2000/svg`:void 0);this.el=r?new t.n(e):i?document.createElementNS(i,e):document.createElement(e)}id(e){return this.el.setAttribute(`id`,e),this}bind(t,n){typeof t==`function`?e.createEffect(()=>n(t())):n(t)}class(e){return this.bind(e,e=>{r?this.el.attributes.set(`class`,e):this.el.setAttribute(`class`,e)}),this}addClass(...e){return e.forEach(e=>this.el.classList.add(e)),this}removeClass(...e){return e.forEach(e=>this.el.classList.remove(e)),this}attr(e,t){return this.bind(t,t=>this.el.setAttribute(e,t)),this}attrs(e){return Object.entries(e).forEach(([e,t])=>{t!=null&&this.el.setAttribute(e,String(t))}),this}boolAttr(e,t,n=``){return this.bind(t,t=>{t?this.el.setAttribute(e,n):this.el.removeAttribute(e)}),this}part(e){return this.attr(`part`,e)}data(e,t){return this.attr(`data-${e}`,t)}style(e,t){return typeof e==`string`?this.bind(t??``,t=>this.el.style.setProperty(e,t)):Object.entries(e).forEach(([e,t])=>this.el.style.setProperty(e,t)),this}cssVar(e,t){let n=e.startsWith(`--`)?e:`--${e}`;return this.style(n,t)}aria(e,t){return this.attr(`aria-${e}`,t)}role(e){return this.attr(`role`,e)}tabIndex(e){return this.attr(`tabindex`,String(e))}label(e){return this.aria(`label`,e)}labelledBy(e){return this.aria(`labelledby`,e)}describedBy(e){return this.aria(`describedby`,e)}ariaHidden(e=!0){return this.aria(`hidden`,String(e))}on(e,t,n){return this.el.addEventListener(e,t,n),this}listen(e,t,n,r){return e.on(this.el,t,n,r),this}delegate(e,t,n,r,i){return e.delegate(this.el,t,n,r,i),this}children(...e){return C(this.el,e),this}replaceChildren(...e){if(r){let e=this.el;e.childrenList=[]}else this.el.replaceChildren();return this.children(...e)}text(e){return this.bind(e,e=>{this.el.textContent=e}),this}unsafeHtml(e){return this.bind(e,e=>{this.el.innerHTML=e}),this}ref(e){return e.current=this.el,this}shadow(e={mode:`closed`}){let t=this.el.attachShadow(e);return new O(this.el,t,e)}build(){return this.el}serialize(){if(r)return this.el.serialize();let e=document.createElement(`div`);return e.appendChild(this.el.cloneNode(!0)),e.innerHTML}},O=class{root;hostEl;constructor(e,t,n){this.hostEl=e,this.root=t}children(...e){return C(this.root,e),this}adoptSheet(...e){return this.root.adoptedStyleSheets=[...this.root.adoptedStyleSheets,...e],this}css(e){if(r)return this.root.adoptedStyleSheets.push(e),this;if(typeof CSSStyleSheet<`u`)try{let t=new CSSStyleSheet;return t.replaceSync(e),this.root.adoptedStyleSheets=[...this.root.adoptedStyleSheets,t],this}catch{}let t=document.createElement(`style`);return t.textContent=e,this.root.appendChild(t),this}done(){return{host:this.hostEl,shadow:this.root}}serialize(){return r?this.root.serialize():this.root.innerHTML}},k=e=>new D(e),A=()=>k(`div`),j=e=>new D(e,w),M=()=>k(`span`),N=()=>k(`slot`),P=()=>k(`button`),F=()=>k(`input`),I=()=>k(`style`),L=()=>k(`label`),R=()=>k(`ul`),z=()=>k(`li`),B=()=>k(`section`),V=()=>k(`article`),H=()=>k(`nav`),U=()=>k(`header`),W=()=>k(`footer`),G=()=>k(`main`),K=(e=`open`,t=!1)=>{let n=k(`template`);return n.attr(`shadowrootmode`,e),t&&n.attr(`shadowrootdelegatesfocus`,``),n};exports.Article=V,exports.ButtonBuilder=P,exports.DeclarativeShadow=K,exports.Div=A,exports.DocumentFragmentMock=t.t,exports.ElementBuilder=D,exports.EventManager=i,exports.Footer=W,exports.For=u,exports.HTMLElementMock=t.n,exports.Header=U,exports.Index=y,exports.InputBuilder=F,exports.Label=L,exports.Li=z,exports.Main=G,exports.Match=p,exports.Nav=H,exports.SVG_NAMESPACE=w,exports.Section=B,exports.ShadowBuilder=O,exports.ShadowRootMock=t.r,exports.Show=f,exports.Slot=N,exports.Span=M,exports.Style=I,exports.Svg=j,exports.Switch=m,exports.Ul=R,exports.View=k,exports.batch=e.batch,exports.collectMatches=t.i,exports.computed=e.computed,exports.createEffect=e.createEffect,exports.createRef=a,exports.createRoot=e.createRoot,exports.escapeHtml=n.escapeHtml,exports.escapeHtmlAttribute=t.o,exports.getOwner=e.getOwner,exports.isSSR=r,exports.matchSelector=t.a,exports.onCleanup=e.onCleanup,exports.runWithOwner=e.runWithOwner,exports.signal=e.signal,exports.untrack=e.untrack;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/env.ts","../src/events.ts","../src/core.ts","../src/factory.ts"],"sourcesContent":["export const isSSR = typeof document === 'undefined';\n","/**\n * EventManager — lifecycle-scoped event registry backed by AbortController.\n *\n * Web Component usage:\n *\n * private _events = new EventManager();\n *\n * connectedCallback() {\n * this._events\n * .on(this._input, 'input', this.handleInput)\n * .on(this, 'click', this.handleClick, { capture: true });\n * }\n *\n * disconnectedCallback() {\n * this._events.abort(); // removes all listeners, resets for next connect\n * }\n *\n * Page development usage:\n *\n * function initSection(container: HTMLElement) {\n * const scope = new EventManager();\n *\n * scope\n * .on(input, 'input', handleSearch)\n * .delegate(container, '[data-action]', 'click', (ev, target) => {\n * handleAction(target.getAttribute('data-action'));\n * });\n *\n * return () => scope.abort(); // call on section teardown\n * }\n */\nexport class EventManager {\n /**\n * Created on first use, and dropped again by {@link abort}.\n *\n * No component registers a listener in its constructor — they all wait for\n * `connectedCallback` — and some managers, like the drag-scoped one in `r-progress`,\n * only ever register during an interaction that may not happen. Allocating eagerly\n * charged every construction, and every `abort()`, for a controller that might go unused:\n * about 30% of a mount/unmount cycle for `r-progress`.\n */\n private ac: AbortController | null = null;\n\n /** The underlying AbortSignal — pass to addEventListener options directly if needed. */\n get signal(): AbortSignal {\n this.ac ??= new AbortController();\n return this.ac.signal;\n }\n\n on<K extends keyof HTMLElementEventMap>(\n target: HTMLElement,\n type: K,\n handler: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any,\n options?: Omit<AddEventListenerOptions, 'signal'>,\n ): this;\n on(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: Omit<AddEventListenerOptions, 'signal'>,\n ): this;\n on(target: EventTarget, type: string, handler: any, options?: Omit<AddEventListenerOptions, 'signal'>): this {\n target.addEventListener(type, handler, { ...options, signal: this.signal });\n return this;\n }\n\n /**\n * Event delegation — attach one listener to `parent`, fire `handler` only when\n * the event originates from a descendant matching `selector`.\n *\n * The handler receives the original event and the matched element as arguments.\n *\n * scope.delegate(list, '.item', 'click', (ev, item) => {\n * console.log(item.dataset.id);\n * });\n */\n delegate<K extends keyof HTMLElementEventMap>(\n parent: HTMLElement,\n selector: string,\n type: K,\n handler: (ev: HTMLElementEventMap[K], target: Element) => void,\n options?: Omit<AddEventListenerOptions, 'signal'>,\n ): this {\n parent.addEventListener(\n type,\n (ev) => {\n const target = (ev.target as Element | null)?.closest(selector);\n if (target && parent.contains(target)) handler(ev as HTMLElementEventMap[K], target);\n },\n { ...options, signal: this.signal },\n );\n return this;\n }\n\n /**\n * Remove all registered listeners and drop the controller.\n * Safe to call multiple times; the next on() / delegate() starts a fresh one.\n */\n abort(): void {\n this.ac?.abort();\n this.ac = null;\n }\n}\n","import { isSSR } from './env';\nimport { DocumentFragmentMock, HTMLElementMock, ShadowRootMock } from './mocks';\nimport type { EventManager } from './events';\nimport { computed, createEffect, createRoot, onCleanup, signal, type Getter } from './signal';\n\nexport interface Ref<T extends HTMLElement = HTMLElement> {\n current: T | null;\n}\n\nexport const createRef = <T extends HTMLElement = HTMLElement>(): Ref<T> => ({ current: null });\n\n/** A single directly-appendable child: element, text, nested builder, or nothing.\n * Internal helper — the public, general type is {@link Child}. */\ntype StaticChild = HTMLElement | string | ElementBuilder<any> | undefined | null;\n\n/**\n * The one type every `children()` / `replaceChildren()` argument accepts —\n * fully composable (recursive): a node, text, nested builder, `null`/`undefined`,\n * a (nested) array, a {@link For}/{@link Index} handle for a keyed list, or a\n * getter `() => Child` marking a reactive region. A getter (or `Show`/`Switch`\n * branch) may itself return any `Child`, including a `For`/`Index` or another\n * getter — control-flow nests freely. On SSR getters / `For` / `Index` render once.\n */\nexport type Child = StaticChild | ForHandle | IndexHandle | Child[] | (() => Child);\n\nconst flattenChildren = (arr: unknown[]): unknown[] =>\n arr.reduce<unknown[]>((acc, val) => (Array.isArray(val) ? acc.concat(flattenChildren(val)) : acc.concat(val)), []);\n\n/** Resolve one static child to a node (client) / string (SSR); `null` when skippable. */\nconst toChildNode = (item: StaticChild): Node | string | null => {\n if (item == null) return null;\n if (item instanceof ElementBuilder) return item.build() as unknown as Node;\n if (typeof item === 'string') return isSSR ? item : document.createTextNode(item);\n return item as Node;\n};\n\n/**\n * Mount a reactive child region into `parent`. The getter may return **any**\n * `Child` — static nodes, arrays, a `For`/`Index` handle, or another getter —\n * so `Show`/`Switch` branches nest control flow freely.\n *\n * Client: a `start`/`end` comment pair brackets the region. Each run disposes the\n * previous run's scope (tearing down any nested `For`/`Index`/getter effects),\n * clears the bracketed nodes, then mounts the new output under a fresh\n * `createRoot` via `appendChildren` (uniform dispatch). SSR: evaluate once.\n */\nconst mountReactiveChildren = (parent: Node, getter: () => Child): void => {\n if (isSSR) {\n appendChildren(parent, [getter()]);\n return;\n }\n const start = document.createComment('');\n const end = document.createComment('');\n parent.appendChild(start);\n parent.appendChild(end);\n let disposeInner: (() => void) | null = null;\n const clear = (): void => {\n disposeInner?.();\n disposeInner = null;\n let n = start.nextSibling;\n while (n && n !== end) {\n const nextN = n.nextSibling;\n n.parentNode?.removeChild(n);\n n = nextN;\n }\n };\n createEffect(() => {\n const out = getter();\n clear();\n const frag = document.createDocumentFragment();\n disposeInner = createRoot((dispose) => {\n appendChildren(frag, [out]);\n return dispose;\n });\n end.parentNode?.insertBefore(frag, end);\n });\n onCleanup(() => disposeInner?.());\n};\n\n// ── For — keyed list reconciliation ──────────────────────────────────────────\n\nconst FOR_BRAND = '__ranFor';\n\n/** Options for {@link For}. */\nexport interface ForOptions<T> {\n /** Reactive source array. Read inside an effect, so the list updates on change. */\n each: () => readonly T[] | null | undefined;\n /** Stable identity per item — **must be unique** within the list. Reused across\n * updates to match old nodes to new items (that is what preserves DOM state). */\n key: (item: T, index: number) => string | number;\n /** Render one item to a single node. `index` is a **getter** (reactive): it\n * reflects the item's current position even after the list reorders. Runs once\n * per item (not on every list change) — drive per-item updates with signals. */\n render: (item: T, index: Getter<number>) => StaticChild;\n}\n\ninterface ForSpec<T> extends ForOptions<T> {\n [FOR_BRAND]: true;\n}\n\n/** Opaque handle returned by {@link For}; pass it straight to `children()`. */\nexport type ForHandle = { readonly [FOR_BRAND]: true };\n\n/**\n * Keyed list for `children()`. Unlike a plain getter child (which rebuilds the\n * whole region on every change), `For` matches items by `key` and **reuses their\n * DOM nodes** — only added/removed/moved items touch the DOM, so focus, scroll,\n * input values and in-flight transitions inside surviving rows are preserved.\n *\n * Ul().children(\n * For({\n * each: () => rows(),\n * key: (r) => r.id,\n * render: (r, i) => Li().text(() => `${i()}. ${r.title}`),\n * }),\n * );\n *\n * On SSR the list is rendered once as a static snapshot. Must be built inside a\n * `createRoot` so per-item scopes are disposed with the page.\n */\nexport function For<T>(options: ForOptions<T>): ForHandle {\n return { ...options, [FOR_BRAND]: true } as ForSpec<T>;\n}\n\nconst isForSpec = (v: unknown): v is ForSpec<unknown> =>\n typeof v === 'object' && v !== null && (v as Record<string, unknown>)[FOR_BRAND] === true;\n\n// ── Show — fine-grained conditional ──────────────────────────────────────────\n\n/** Options for {@link Show}. */\nexport interface ShowOptions<T> {\n /** Condition source. Truthy → `children`, falsy → `fallback`. */\n when: () => T;\n /** Built when `when` is truthy. May return any {@link Child} — a `For`/`Index`\n * list, a nested `Show`, etc. Receives an accessor to the narrowed value —\n * read it inside a binding (`.text(() => v())`) to update without rebuilding. */\n children: (value: () => NonNullable<T>) => Child;\n /** Built when `when` is falsy. Omitted → nothing is rendered. */\n fallback?: () => Child;\n}\n\n/**\n * Fine-grained conditional child. Unlike a raw getter child (which re-runs on\n * **every** change it reads), `Show` rebuilds the branch **only when the\n * truthiness of `when` flips** — the condition is memoized. Content inside a\n * branch updates through its own bindings, not by re-running `Show`. This is the\n * SwiftUI/Solid model: build once, toggle only when the branch actually changes.\n *\n * Show({\n * when: () => user(), // reads a signal\n * children: (u) => Div().text(() => u().name),\n * fallback: () => Div().text('Signed out'),\n * })\n *\n * `Show` returns a getter, so it is accepted anywhere `children()` takes a child.\n * Must be created inside a `createRoot` (it owns a memo + the branch effect).\n */\nexport function Show<T>(options: ShowOptions<T>): () => Child {\n const on = computed(() => Boolean(options.when()));\n const value = (): NonNullable<T> => options.when() as NonNullable<T>;\n return () => (on() ? options.children(value) : (options.fallback?.() ?? null));\n}\n\n// ── Switch / Match — fine-grained multi-branch ───────────────────────────────\n\n/** One branch of a {@link Switch}; build with {@link Match}. */\nexport interface MatchClause<T> {\n when: () => T;\n children: (value: () => NonNullable<T>) => Child;\n}\n\n/** Declare one `Switch` branch (identity helper — gives per-clause type inference). */\nexport function Match<T>(clause: MatchClause<T>): MatchClause<T> {\n return clause;\n}\n\n/** Options for {@link Switch}. */\nexport interface SwitchOptions {\n /** Branches, tried in order; the first with a truthy `when` renders. Clauses are\n * heterogeneous (each `Match<T>` carries its own `T`), hence `any` here. */\n children: MatchClause<any>[];\n /** Rendered when no branch matches. Omitted → nothing. */\n fallback?: () => Child;\n}\n\n/**\n * Fine-grained multi-branch conditional (the n-way `Show`). Renders the first\n * `Match` whose `when` is truthy, else `fallback`. Only the **index of the\n * winning branch** is memoized, so it rebuilds only when the active branch\n * changes — not on every change a `when` reads. Evaluation short-circuits at the\n * first match (later branches aren't subscribed while an earlier one wins).\n *\n * Switch({\n * fallback: () => Span().text('idle'),\n * children: [\n * Match({ when: () => status() === 'loading', children: () => Spinner() }),\n * Match({ when: () => error(), children: (e) => ErrorView(e) }),\n * ],\n * })\n */\nexport function Switch(options: SwitchOptions): () => Child {\n const clauses = options.children;\n const winner = computed(() => clauses.findIndex((c) => Boolean(c.when())));\n return () => {\n const i = winner();\n if (i < 0) return options.fallback?.() ?? null;\n const clause = clauses[i];\n return clause.children(() => clause.when() as NonNullable<unknown>);\n };\n}\n\ninterface ItemScope {\n node: Node | null;\n index: (value: number) => void;\n dispose: () => void;\n}\n\n/** Create one item's node inside its own reactive scope (independently disposable). */\nconst createItemScope = <T>(item: T, i: number, render: ForSpec<T>['render']): ItemScope => {\n const [index, setIndex] = signal(i);\n let node: Node | null = null;\n const dispose = createRoot((d) => {\n const built = toChildNode(render(item, index) as StaticChild);\n node = typeof built === 'string' ? document.createTextNode(built) : built;\n return d;\n });\n return { node, index: setIndex, dispose };\n};\n\n/** Reorder `nodes` to sit, in order, immediately after `anchor` — moving only\n * those out of place (reused nodes keep their identity, hence their state). */\nconst placeAfterAnchor = (anchor: ChildNode, nodes: Node[]): void => {\n const parent = anchor.parentNode;\n if (!parent) return;\n let ref: ChildNode = anchor;\n for (const node of nodes) {\n if (ref.nextSibling !== node) parent.insertBefore(node, ref.nextSibling);\n ref = node as ChildNode;\n }\n};\n\n/** Mount a keyed list: SSR renders once; client reconciles by key on each change. */\nconst mountKeyedList = <T>(parent: Node, spec: ForSpec<T>): void => {\n if (isSSR) {\n (spec.each() ?? []).forEach((item, i) => {\n const node = toChildNode(spec.render(item, () => i) as StaticChild);\n if (node != null) (parent as unknown as { appendChild(n: unknown): unknown }).appendChild(node);\n });\n return;\n }\n\n const anchor = document.createComment('');\n parent.appendChild(anchor);\n let scopes = new Map<string | number, ItemScope>();\n onCleanup(() => {\n for (const scope of scopes.values()) scope.dispose();\n scopes.clear();\n });\n\n createEffect(() => {\n const items = spec.each() ?? [];\n const next = new Map<string | number, ItemScope>();\n const ordered: Node[] = [];\n\n items.forEach((item, i) => {\n const k = spec.key(item, i);\n // Duplicate key: a Map can hold one node per key, so honouring the second\n // would orphan the first (untracked → never removed/disposed). Ignore the\n // duplicate — deterministic and leak-free — and warn in dev.\n if (next.has(k)) {\n if (isDev()) {\n console.error(\n `[ranview For] duplicate key \"${String(k)}\" — keys must be unique; ignoring the duplicate item.`,\n );\n }\n return;\n }\n let scope = scopes.get(k);\n if (scope) {\n scopes.delete(k); // claimed → leftovers below are removals\n scope.index(i); // keep the reactive index in sync after moves\n } else {\n scope = createItemScope(item, i, spec.render);\n }\n next.set(k, scope);\n if (scope.node) ordered.push(scope.node);\n });\n\n // Remove + dispose items no longer present.\n for (const scope of scopes.values()) {\n scope.node?.parentNode?.removeChild(scope.node);\n scope.dispose();\n }\n placeAfterAnchor(anchor, ordered);\n scopes = next;\n });\n};\n\n// ── Index — position-keyed list ──────────────────────────────────────────────\n\nconst INDEX_BRAND = '__ranIndex';\n\n/** Options for {@link Index}. */\nexport interface IndexOptions<T> {\n /** Reactive source array. */\n each: () => readonly T[] | null | undefined;\n /** Render the slot at a position. `item` is a **getter** (a signal): when the\n * value at this index changes, it updates in place — the node is not rebuilt.\n * `index` is a fixed number (the position never moves). */\n render: (item: () => T, index: number) => StaticChild;\n}\n\ninterface IndexSpec<T> extends IndexOptions<T> {\n [INDEX_BRAND]: true;\n}\n\n/** Opaque handle returned by {@link Index}; pass it straight to `children()`. */\nexport type IndexHandle = { readonly [INDEX_BRAND]: true };\n\n/**\n * Position-keyed list. The node at index `i` is **reused** across updates and its\n * `item` signal is updated in place — nodes never move. Use it when position is\n * the identity (primitive arrays, fixed-length rows). Use {@link For} instead\n * when items have a stable id and can reorder. SSR renders once.\n *\n * Ul().children(\n * Index({ each: () => nums(), render: (n, i) => Li().text(() => `${i}: ${n()}`) }),\n * );\n */\nexport function Index<T>(options: IndexOptions<T>): IndexHandle {\n return { ...options, [INDEX_BRAND]: true } as IndexSpec<T>;\n}\n\nconst isIndexSpec = (v: unknown): v is IndexSpec<unknown> =>\n typeof v === 'object' && v !== null && (v as Record<string, unknown>)[INDEX_BRAND] === true;\n\ninterface IndexSlot<T> {\n node: Node | null;\n setItem: (value: T) => void;\n dispose: () => void;\n}\n\nconst createIndexSlot = <T>(item: T, i: number, render: IndexSpec<T>['render']): IndexSlot<T> => {\n const [get, setItem] = signal(item);\n let node: Node | null = null;\n const dispose = createRoot((d) => {\n const built = toChildNode(render(get, i) as StaticChild);\n node = typeof built === 'string' ? document.createTextNode(built) : built;\n return d;\n });\n return { node, setItem, dispose };\n};\n\n/** Mount a position-keyed list: SSR renders once; client reuses nodes per index. */\nconst mountIndexList = <T>(parent: Node, spec: IndexSpec<T>): void => {\n if (isSSR) {\n (spec.each() ?? []).forEach((item, i) => {\n const node = toChildNode(spec.render(() => item, i) as StaticChild);\n if (node != null) (parent as unknown as { appendChild(n: unknown): unknown }).appendChild(node);\n });\n return;\n }\n\n const anchor = document.createComment('');\n parent.appendChild(anchor);\n let slots: IndexSlot<T>[] = [];\n onCleanup(() => {\n for (const s of slots) s.dispose();\n slots = [];\n });\n\n createEffect(() => {\n const items = spec.each() ?? [];\n // Reuse slot 0..n: update its signal (no-op if unchanged) — node stays put.\n for (let i = 0; i < items.length; i++) {\n if (i < slots.length) slots[i].setItem(items[i]);\n else slots.push(createIndexSlot(items[i], i, spec.render));\n }\n // Trailing slots (list shrank) → remove + dispose.\n for (let i = slots.length - 1; i >= items.length; i--) {\n const { node } = slots[i];\n node?.parentNode?.removeChild(node);\n slots[i].dispose();\n slots.pop();\n }\n placeAfterAnchor(\n anchor,\n slots.map((s) => s.node).filter((n): n is Node => n != null),\n );\n });\n};\n\n/** Append mixed static / array / reactive-getter / keyed-list children to a parent node. */\nconst appendChildren = (parent: Node, items: Child[]): void => {\n flattenChildren(items).forEach((item) => {\n if (isForSpec(item)) {\n mountKeyedList(parent, item);\n return;\n }\n if (isIndexSpec(item)) {\n mountIndexList(parent, item);\n return;\n }\n if (typeof item === 'function') {\n mountReactiveChildren(parent, item as () => Child);\n return;\n }\n const node = toChildNode(item as StaticChild);\n if (node != null) (parent as unknown as { appendChild(n: unknown): unknown }).appendChild(node);\n });\n};\n\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n\n/**\n * Tags that exist only in SVG, so a builder can create them correctly without\n * being told which namespace they belong to.\n *\n * Deliberately excludes the tags SVG shares with HTML -- `a`, `script`,\n * `style`, `title` -- since guessing wrong there would silently produce the\n * wrong kind of element for the far more common HTML case. Reach for `Svg()`\n * when one of those is meant as SVG.\n */\nconst SVG_ONLY_TAGS = new Set([\n 'svg',\n 'circle',\n 'clipPath',\n 'defs',\n 'desc',\n 'ellipse',\n 'feBlend',\n 'feColorMatrix',\n 'feComposite',\n 'feDropShadow',\n 'feFlood',\n 'feGaussianBlur',\n 'feMerge',\n 'feMergeNode',\n 'feOffset',\n 'filter',\n 'foreignObject',\n 'g',\n 'image',\n 'line',\n 'linearGradient',\n 'marker',\n 'mask',\n 'path',\n 'pattern',\n 'polygon',\n 'polyline',\n 'radialGradient',\n 'rect',\n 'stop',\n 'switch',\n 'symbol',\n 'text',\n 'textPath',\n 'tspan',\n 'use',\n]);\n\n/**\n * True in a dev build, without needing `vite/client` in the consumer's tsconfig.\n *\n * This package exports TypeScript source to workspace consumers, so its types are checked\n * in *their* project. A bare `import.meta.env.DEV` therefore fails to compile anywhere\n * that has not declared Vite's ambient types — which is every consumer that does not\n * happen to use Vite.\n */\nconst isDev = (): boolean => (import.meta as { env?: { DEV?: boolean } }).env?.DEV === true;\n\nexport class ElementBuilder<T extends HTMLElement = HTMLElement> {\n private el: T;\n\n /**\n * @param tag element name\n * @param namespace element namespace; inferred for SVG-only tags, and forced\n * by `Svg()` for the tags SVG shares with HTML.\n *\n * The namespace matters more than it looks. `document.createElement('svg')`\n * yields an `HTMLUnknownElement`: the browser does not render it as SVG, and\n * -- because HTML lowercases attribute names -- `viewBox` lands as `viewbox`,\n * which SVG reads case-sensitively and therefore ignores. An icon built that\n * way is invisible, with markup that looks right in a serialized page.\n */\n constructor(tag: string, namespace?: string) {\n const ns = namespace ?? (SVG_ONLY_TAGS.has(tag) ? SVG_NAMESPACE : undefined);\n this.el = (isSSR\n ? new HTMLElementMock(tag)\n : ns\n ? document.createElementNS(ns, tag)\n : document.createElement(tag)) as unknown as T;\n }\n\n id(value: string): this {\n this.el.setAttribute('id', value);\n return this;\n }\n\n /**\n * Apply a value now, or bind it reactively when a getter is passed.\n * A getter creates an effect owned by the current reactive scope (createRoot),\n * so the binding is disposed automatically when that scope is torn down.\n */\n private bind<V>(value: V | Getter<V>, apply: (v: V) => void): void {\n if (typeof value === 'function') createEffect(() => apply((value as Getter<V>)()));\n else apply(value);\n }\n\n /**\n * Sets the element's class.\n *\n * Written through `setAttribute` rather than `className`. On an SVG element `className`\n * is a read-only `SVGAnimatedString`, so assigning to it throws\n * `Cannot set property className of [object SVGElement] which has only a getter` — which,\n * happening inside a custom element's constructor, leaves the element un-upgraded with\n * no shadow root rather than reporting a styling problem. `setAttribute` is equivalent\n * for HTML elements and correct for both.\n */\n class(name: string | Getter<string>): this {\n this.bind(name, (n) => {\n if (isSSR) (this.el as unknown as HTMLElementMock).attributes.set('class', n);\n else this.el.setAttribute('class', n);\n });\n return this;\n }\n\n addClass(...names: string[]): this {\n names.forEach((n) => this.el.classList.add(n));\n return this;\n }\n\n removeClass(...names: string[]): this {\n names.forEach((n) => this.el.classList.remove(n));\n return this;\n }\n\n attr(name: string, value: string | Getter<string>): this {\n this.bind(value, (v) => this.el.setAttribute(name, v));\n return this;\n }\n\n attrs(values: Record<string, string | number | boolean | null | undefined>): this {\n Object.entries(values).forEach(([name, value]) => {\n if (value == null) return;\n this.el.setAttribute(name, String(value));\n });\n return this;\n }\n\n boolAttr(name: string, value: boolean | Getter<boolean>, enabledValue = ''): this {\n this.bind(value, (v) => {\n if (v) this.el.setAttribute(name, enabledValue);\n else this.el.removeAttribute(name);\n });\n return this;\n }\n\n part(value: string | Getter<string>): this {\n return this.attr('part', value);\n }\n\n data(key: string, value: string | Getter<string>): this {\n return this.attr(`data-${key}`, value);\n }\n\n style(keyOrMap: string | Record<string, string>, value?: string | Getter<string>): this {\n if (typeof keyOrMap === 'string') {\n this.bind(value ?? '', (v) => this.el.style.setProperty(keyOrMap, v));\n } else {\n Object.entries(keyOrMap).forEach(([k, v]) => this.el.style.setProperty(k, v));\n }\n return this;\n }\n\n cssVar(name: string, value: string | Getter<string>): this {\n const property = name.startsWith('--') ? name : `--${name}`;\n return this.style(property, value);\n }\n\n aria(key: string, value: string | Getter<string>): this {\n return this.attr(`aria-${key}`, value);\n }\n\n role(value: string | Getter<string>): this {\n return this.attr('role', value);\n }\n\n tabIndex(value: number): this {\n return this.attr('tabindex', String(value));\n }\n\n label(value: string | Getter<string>): this {\n return this.aria('label', value);\n }\n\n labelledBy(id: string | Getter<string>): this {\n return this.aria('labelledby', id);\n }\n\n describedBy(id: string | Getter<string>): this {\n return this.aria('describedby', id);\n }\n\n ariaHidden(hidden = true): this {\n return this.aria('hidden', String(hidden));\n }\n\n /**\n * Permanent build-time listener — tied to the element's lifetime.\n * Use for internal shadow DOM elements created in the constructor.\n */\n on<K extends keyof HTMLElementEventMap>(\n type: K,\n listener: (this: T, ev: HTMLElementEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions,\n ): this {\n this.el.addEventListener(type, listener as EventListener, options);\n return this;\n }\n\n /**\n * Lifecycle-managed listener — registered into an EventManager.\n * Use in connectedCallback when building elements that need cleanup on disconnect.\n * Call manager.abort() in disconnectedCallback to remove all listeners at once.\n */\n listen<K extends keyof HTMLElementEventMap>(\n manager: EventManager,\n type: K,\n handler: (this: T, ev: HTMLElementEventMap[K]) => any,\n options?: Omit<AddEventListenerOptions, 'signal'>,\n ): this {\n manager.on(this.el, type, handler as EventListener, options);\n return this;\n }\n\n /**\n * Delegated listener — the built element acts as the parent container.\n * Fires handler only when the event originates from a descendant matching selector.\n * Registered into an EventManager so it is cleaned up with manager.abort().\n *\n * Div().class('list')\n * .children(...)\n * .delegate(scope, '.item', 'click', (ev, item) => handleItem(item))\n * .build();\n */\n delegate<K extends keyof HTMLElementEventMap>(\n manager: EventManager,\n selector: string,\n type: K,\n handler: (ev: HTMLElementEventMap[K], target: Element) => void,\n options?: Omit<AddEventListenerOptions, 'signal'>,\n ): this {\n manager.delegate(this.el, selector, type, handler, options);\n return this;\n }\n\n children(...items: Child[]): this {\n appendChildren(this.el, items);\n return this;\n }\n\n replaceChildren(...items: Child[]): this {\n if (isSSR) {\n const mock = this.el as unknown as HTMLElementMock | DocumentFragmentMock;\n mock.childrenList = [];\n } else {\n this.el.replaceChildren();\n }\n return this.children(...items);\n }\n\n text(value: string | Getter<string>): this {\n this.bind(value, (v) => {\n this.el.textContent = v;\n });\n return this;\n }\n\n /**\n * Set the element's content from a string of markup, without escaping it.\n *\n * The counterpart to `text()`, and named for the difference: `text()` escapes,\n * this does not. Everything handed here is parsed as HTML, so anything that\n * came from outside the program must be sanitized before it arrives.\n *\n * It exists because some content simply *is* HTML, and a builder without this\n * cannot express it at all: markdown rendered for a page, a fragment assembled\n * somewhere else, a translated string that carries its own emphasis\n * (`Local-first · <b>open source</b>`). That gap is why a static-site\n * generator with markdown in it could not be written against this API and had\n * to concatenate strings instead.\n *\n * Like `textContent`, this replaces whatever content the element had --\n * including anything set by `text()` or `children()` before it.\n */\n unsafeHtml(value: string | Getter<string>): this {\n this.bind(value, (v) => {\n this.el.innerHTML = v;\n });\n return this;\n }\n\n ref(holder: Ref<T>): this {\n holder.current = this.el;\n return this;\n }\n\n shadow(options: ShadowRootInit = { mode: 'closed' }): ShadowBuilder<T> {\n const root = this.el.attachShadow(options);\n return new ShadowBuilder<T>(this.el, root, options);\n }\n\n build(): T {\n return this.el;\n }\n\n serialize(): string {\n if (isSSR) return (this.el as unknown as HTMLElementMock).serialize();\n const outer = document.createElement('div');\n outer.appendChild(this.el.cloneNode(true));\n return outer.innerHTML;\n }\n}\n\nexport class ShadowBuilder<T extends HTMLElement = HTMLElement> {\n private root: ShadowRoot;\n private hostEl: T;\n\n /**\n * `options` is taken and discarded: `attachShadow` has already consumed it by the time\n * a builder exists, and nothing ever read the copy this class used to keep. The\n * parameter stays so the call signature is unchanged.\n */\n constructor(host: T, root: ShadowRoot, _options: ShadowRootInit) {\n this.hostEl = host;\n this.root = root;\n }\n\n children(...items: Child[]): this {\n appendChildren(this.root, items);\n return this;\n }\n\n adoptSheet(...sheets: CSSStyleSheet[]): this {\n this.root.adoptedStyleSheets = [...this.root.adoptedStyleSheets, ...sheets];\n return this;\n }\n\n css(cssText: string): this {\n if (isSSR) {\n (this.root as unknown as ShadowRootMock).adoptedStyleSheets.push(cssText);\n return this;\n }\n if (typeof CSSStyleSheet !== 'undefined') {\n try {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(cssText);\n this.root.adoptedStyleSheets = [...this.root.adoptedStyleSheets, sheet];\n return this;\n } catch {\n // Fallback to style injection when adoptedStyleSheets is unavailable.\n }\n }\n const style = document.createElement('style');\n style.textContent = cssText;\n this.root.appendChild(style);\n return this;\n }\n\n done(): { host: T; shadow: ShadowRoot } {\n return { host: this.hostEl, shadow: this.root };\n }\n\n serialize(): string {\n if (isSSR) return (this.root as unknown as ShadowRootMock).serialize();\n return (this.root as ShadowRoot).innerHTML;\n }\n}\n","import { ElementBuilder, SVG_NAMESPACE } from './core';\n\nexport const View = <T extends HTMLElement = HTMLElement>(tag: string): ElementBuilder<T> => new ElementBuilder<T>(tag);\nexport const Div = (): ElementBuilder<HTMLDivElement> => View<HTMLDivElement>('div');\n\n/**\n * An element in the SVG namespace.\n *\n * `View()` already infers it for tags that only exist in SVG (`path`, `circle`,\n * `g`, …), so this is for the ones SVG shares with HTML -- `a`, `script`,\n * `style`, `title` -- where guessing would break the commoner HTML case.\n *\n * ```ts\n * View('svg').attrs({ viewBox: '0 0 16 16' }).children(\n * Svg('a').attr('href', '#').children(View('path').attr('d', 'M1 1').build()).build(),\n * );\n * ```\n */\nexport const Svg = <T extends HTMLElement = HTMLElement>(tag: string): ElementBuilder<T> =>\n new ElementBuilder<T>(tag, SVG_NAMESPACE);\nexport const Span = (): ElementBuilder<HTMLSpanElement> => View<HTMLSpanElement>('span');\nexport const Slot = (): ElementBuilder<HTMLSlotElement> => View<HTMLSlotElement>('slot');\nexport const ButtonBuilder = (): ElementBuilder<HTMLButtonElement> => View<HTMLButtonElement>('button');\nexport const InputBuilder = (): ElementBuilder<HTMLInputElement> => View<HTMLInputElement>('input');\nexport const Style = (): ElementBuilder<HTMLStyleElement> => View<HTMLStyleElement>('style');\nexport const Label = (): ElementBuilder<HTMLLabelElement> => View<HTMLLabelElement>('label');\nexport const Ul = (): ElementBuilder<HTMLUListElement> => View<HTMLUListElement>('ul');\nexport const Li = (): ElementBuilder<HTMLLIElement> => View<HTMLLIElement>('li');\nexport const Section = (): ElementBuilder<HTMLElement> => View<HTMLElement>('section');\nexport const Article = (): ElementBuilder<HTMLElement> => View<HTMLElement>('article');\nexport const Nav = (): ElementBuilder<HTMLElement> => View<HTMLElement>('nav');\nexport const Header = (): ElementBuilder<HTMLElement> => View<HTMLElement>('header');\nexport const Footer = (): ElementBuilder<HTMLElement> => View<HTMLElement>('footer');\nexport const Main = (): ElementBuilder<HTMLElement> => View<HTMLElement>('main');\n\nexport const DeclarativeShadow = (\n mode: 'open' | 'closed' = 'open',\n delegatesFocus = false,\n): ElementBuilder<HTMLTemplateElement> => {\n const tpl = View<HTMLTemplateElement>('template');\n tpl.attr('shadowrootmode', mode);\n if (delegatesFocus) tpl.attr('shadowrootdelegatesfocus', '');\n return tpl;\n};\n"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export { isSSR } from './env';
2
+ export { EventManager } from './events';
3
+ export { signal, createEffect, computed, batch, untrack, createRoot, onCleanup, getOwner, runWithOwner, } from './signal';
4
+ export type { Getter, Setter, SignalOptions, Owner } from './signal';
5
+ export { escapeHtml, escapeHtmlAttribute } from './escape';
6
+ export { type MockNode, matchSelector, collectMatches } from './selectors';
7
+ export { DocumentFragmentMock, HTMLElementMock, ShadowRootMock } from './mocks';
8
+ export { type Ref, type Child, type ForOptions, type ForHandle, type IndexOptions, type IndexHandle, type ShowOptions, type SwitchOptions, type MatchClause, createRef, For, Index, Show, Switch, Match, ElementBuilder, ShadowBuilder, SVG_NAMESPACE, } from './core';
9
+ export { View, Div, Svg, Span, Slot, ButtonBuilder, InputBuilder, Style, Label, Ul, Li, Section, Article, Nav, Header, Footer, Main, DeclarativeShadow, } from './factory';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EACL,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,KAAK,EACL,OAAO,EACP,UAAU,EACV,SAAS,EACT,QAAQ,EACR,YAAY,GACb,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,KAAK,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,EACL,KAAK,GAAG,EACR,KAAK,KAAK,EACV,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,SAAS,EACT,GAAG,EACH,KAAK,EACL,IAAI,EACJ,MAAM,EACN,KAAK,EACL,cAAc,EACd,aAAa,EACb,aAAa,GACd,MAAM,QAAQ,CAAC;AAChB,OAAO,EACL,IAAI,EACJ,GAAG,EACH,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,aAAa,EACb,YAAY,EACZ,KAAK,EACL,KAAK,EACL,EAAE,EACF,EAAE,EACF,OAAO,EACP,OAAO,EACP,GAAG,EACH,MAAM,EACN,MAAM,EACN,IAAI,EACJ,iBAAiB,GAClB,MAAM,WAAW,CAAC"}