elements-kit 0.0.18 → 0.0.20
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 +65 -118
- package/dist/{attributes-Dtn68R1u.d.mts → attributes-DILeh3-s.d.mts} +42 -9
- package/dist/attributes.d.mts +1 -1
- package/dist/attributes.mjs +32 -0
- package/dist/{define-CjbTZ3VG.d.mts → custom-elements-D5_NMNyD.d.mts} +20 -2
- package/dist/custom-elements.d.mts +2 -74
- package/dist/custom-elements.mjs +15 -86
- package/dist/{element-CGVy_8TW.mjs → element-w1GCIMVp.mjs} +33 -21
- package/dist/for.d.mts +31 -2
- package/dist/for.mjs +18 -2
- package/dist/infer-DuFY-y2b.d.mts +657 -0
- package/dist/integrations/react.d.mts +1 -1
- package/dist/integrations/react.mjs +6 -4
- package/dist/jsx-runtime/index.d.mts +2 -73
- package/dist/jsx-runtime/index.mjs +8 -14
- package/dist/{signals-J8dK_rA4.mjs → lib-D6duEs38.mjs} +1 -105
- package/dist/render.d.mts +21 -0
- package/dist/render.mjs +32 -0
- package/dist/scope-DM2gzOkb.mjs +45 -0
- package/dist/signals/index.d.mts +1 -1
- package/dist/signals/index.mjs +134 -1
- package/dist/{slot-Kb61AcgW.mjs → slot-CKtUoy2X.mjs} +0 -1
- package/dist/{slot-C7GQZe-r.d.mts → slot-D5iBUSAm.d.mts} +18 -1
- package/dist/slot.d.mts +1 -1
- package/dist/slot.mjs +1 -1
- package/dist/{test.BmQO5GaM-DfGStnii.mjs → test.BmQO5GaM-BeO5pvCo.mjs} +1 -1
- package/dist/utilities/_observe.mjs +2 -1
- package/dist/utilities/active-element.d.mts +1 -1
- package/dist/utilities/active-element.mjs +2 -1
- package/dist/utilities/active-element.test.mjs +1 -1
- package/dist/utilities/async.d.mts +39 -1
- package/dist/utilities/async.mjs +39 -1
- package/dist/utilities/async.test.mjs +3 -2
- package/dist/utilities/debounced.d.mts +12 -1
- package/dist/utilities/debounced.mjs +13 -1
- package/dist/utilities/debounced.test.mjs +3 -2
- package/dist/utilities/element-rect.d.mts +1 -1
- package/dist/utilities/element-rect.mjs +2 -1
- package/dist/utilities/element-rect.test.mjs +3 -2
- package/dist/utilities/element-scroll.d.mts +1 -1
- package/dist/utilities/element-scroll.test.mjs +3 -2
- package/dist/utilities/environment.d.mts +2 -0
- package/dist/utilities/environment.mjs +2 -0
- package/dist/utilities/event-driven.d.mts +1 -1
- package/dist/utilities/event-driven.mjs +2 -1
- package/dist/utilities/event-listener.d.mts +12 -1
- package/dist/utilities/event-listener.mjs +2 -1
- package/dist/utilities/event-listener.test.mjs +3 -2
- package/dist/utilities/focus-within.d.mts +1 -1
- package/dist/utilities/focus-within.mjs +2 -1
- package/dist/utilities/focus-within.test.mjs +3 -2
- package/dist/utilities/hover.d.mts +1 -1
- package/dist/utilities/hover.mjs +2 -1
- package/dist/utilities/hover.test.mjs +3 -2
- package/dist/utilities/intersection-observer.test.mjs +3 -2
- package/dist/utilities/interval.d.mts +14 -1
- package/dist/utilities/interval.mjs +2 -1
- package/dist/utilities/interval.test.mjs +3 -2
- package/dist/utilities/location.d.mts +1 -1
- package/dist/utilities/location.mjs +2 -1
- package/dist/utilities/location.test.mjs +1 -1
- package/dist/utilities/long-press.test.mjs +3 -2
- package/dist/utilities/media-devices.d.mts +1 -1
- package/dist/utilities/media-devices.mjs +2 -1
- package/dist/utilities/media-devices.test.mjs +3 -2
- package/dist/utilities/media-player.d.mts +1 -1
- package/dist/utilities/media-player.test.mjs +3 -2
- package/dist/utilities/media-query.d.mts +1 -1
- package/dist/utilities/media-query.mjs +2 -1
- package/dist/utilities/mutation-observer.test.mjs +3 -2
- package/dist/utilities/network.d.mts +1 -1
- package/dist/utilities/network.mjs +2 -1
- package/dist/utilities/network.test.mjs +1 -1
- package/dist/utilities/on-click-outside.test.mjs +3 -2
- package/dist/utilities/orientation.d.mts +1 -1
- package/dist/utilities/orientation.mjs +2 -1
- package/dist/utilities/previous.d.mts +13 -1
- package/dist/utilities/previous.mjs +14 -1
- package/dist/utilities/previous.test.mjs +3 -2
- package/dist/utilities/promise.d.mts +7 -1
- package/dist/utilities/promise.mjs +2 -1
- package/dist/utilities/promise.test.mjs +3 -2
- package/dist/utilities/retry.d.mts +15 -0
- package/dist/utilities/retry.mjs +17 -1
- package/dist/utilities/retry.test.mjs +3 -2
- package/dist/utilities/routing.d.mts +12 -1
- package/dist/utilities/routing.mjs +13 -1
- package/dist/utilities/routing.test.mjs +1 -1
- package/dist/utilities/search-params.d.mts +1 -1
- package/dist/utilities/search-params.test.mjs +3 -2
- package/dist/utilities/ssr.test.mjs +1 -1
- package/dist/utilities/storage.d.mts +18 -1
- package/dist/utilities/storage.mjs +17 -0
- package/dist/utilities/storage.test.mjs +3 -2
- package/dist/utilities/throttled.d.mts +12 -1
- package/dist/utilities/throttled.mjs +13 -1
- package/dist/utilities/throttled.test.mjs +3 -2
- package/dist/utilities/timeout.d.mts +1 -1
- package/dist/utilities/timeout.mjs +2 -1
- package/dist/utilities/timeout.test.mjs +3 -2
- package/dist/utilities/window-focus.d.mts +1 -1
- package/dist/utilities/window-focus.mjs +2 -1
- package/dist/utilities/window-size.d.mts +1 -1
- package/dist/utilities/window-size.mjs +2 -1
- package/dist/utilities/window-size.test.mjs +1 -1
- package/package.json +1 -1
- package/dist/index-DydGTqZU.d.mts +0 -315
- package/dist/infer-BfzRJoCn.d.mts +0 -203
- package/dist/polyfill-BVNd6ogU.d.mts +0 -9
- /package/dist/{magic-string.es-i62WTP6J.mjs → magic-string.es-cTgJnTCj.mjs} +0 -0
|
@@ -1,73 +1,2 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
|
|
3
|
-
import { n as MaybeReactive } from "../index-DydGTqZU.mjs";
|
|
4
|
-
import { JSX as JSX$1 } from "dom-expressions/src/jsx-h";
|
|
5
|
-
|
|
6
|
-
//#region src/jsx-runtime/element.d.ts
|
|
7
|
-
declare function createElement(type: string | Element | DocumentFragment | ComponentClass | ComponentFn, {
|
|
8
|
-
ref,
|
|
9
|
-
...props
|
|
10
|
-
}?: Record<string | symbol, unknown> & {
|
|
11
|
-
ref?: (el: Element) => void;
|
|
12
|
-
}): Element | DocumentFragment | null;
|
|
13
|
-
//#endregion
|
|
14
|
-
//#region src/jsx-runtime/fragment.d.ts
|
|
15
|
-
/**
|
|
16
|
-
* Used by the JSX transform for `<>...</>` fragments.
|
|
17
|
-
*
|
|
18
|
-
* createElement wraps this in effectScope + attachDisposables, so children's
|
|
19
|
-
* Symbol.dispose functions are collected via onCleanup and fired when the
|
|
20
|
-
* fragment's own dispose is called.
|
|
21
|
-
*/
|
|
22
|
-
declare function Fragment(props: {
|
|
23
|
-
children?: unknown;
|
|
24
|
-
}): DocumentFragment;
|
|
25
|
-
//#endregion
|
|
26
|
-
//#region src/jsx-runtime/index.d.ts
|
|
27
|
-
/** A value or a reactive zero-argument getter. */
|
|
28
|
-
type FunctionMaybe<T> = JSX$1.FunctionMaybe<T>;
|
|
29
|
-
/**
|
|
30
|
-
* Maps slot names to `Child` content.
|
|
31
|
-
* Use this to type `slot:name` JSX props on a custom component.
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```tsx
|
|
35
|
-
* function Card(props: { title: string } & SlotProps<"header" | "footer">) { … }
|
|
36
|
-
* // caller: <Card title="…" slot:header={<h1>…</h1>} slot:footer={<p>…</p>} />
|
|
37
|
-
* ```
|
|
38
|
-
*/
|
|
39
|
-
type SlotProps<K extends string> = { [P in K as `slot:${P}`]?: Child };
|
|
40
|
-
/**
|
|
41
|
-
* Get the full JSX prop types for a given tag name, including reactive
|
|
42
|
-
* attributes, events, and all our namespace extensions.
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* ```ts
|
|
46
|
-
* type InputProps = Attrs<"input">; // typed props for <input>
|
|
47
|
-
* type DivProps = Attrs<"div">; // typed props for <div>
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
type Attrs<K extends keyof JSX.IntrinsicElements> = JSX.IntrinsicElements[K];
|
|
51
|
-
/** Extra props injected into every intrinsic element beyond dom-expressions defaults. */
|
|
52
|
-
type OurProps = {
|
|
53
|
-
ref?: (el: Element) => void;
|
|
54
|
-
[slot: `slot:${string}`]: Child;
|
|
55
|
-
[cls: `class:${string}`]: FunctionMaybe<boolean>;
|
|
56
|
-
[sty: `style:${string}`]: FunctionMaybe<string | null>;
|
|
57
|
-
[prop: `prop:${string}`]: unknown;
|
|
58
|
-
};
|
|
59
|
-
type WithOurProps<T> = T & OurProps;
|
|
60
|
-
declare namespace JSX {
|
|
61
|
-
export type Element = globalThis.Element | globalThis.DocumentFragment | null;
|
|
62
|
-
export type ElementType = Child | ComponentClass;
|
|
63
|
-
export interface ElementChildrenAttribute {
|
|
64
|
-
children: {};
|
|
65
|
-
}
|
|
66
|
-
type RegisteredElements = { [K in keyof CustomElementRegistry]: CustomElementRegistry[K] extends AnyElementCtor ? ElementProps<CustomElementRegistry[K]> : never };
|
|
67
|
-
export type IntrinsicElements = { [K in keyof JSX$1.IntrinsicElements]: WithOurProps<JSX$1.IntrinsicElements[K]> } & RegisteredElements & {
|
|
68
|
-
/** Unregistered custom elements (`x-foo`, `my-component`, …) — loose fallback. */[customElement: `${string}-${string}`]: WithOurProps<JSX$1.DOMAttributes<HTMLElement>> & Record<string, unknown>;
|
|
69
|
-
};
|
|
70
|
-
export {};
|
|
71
|
-
}
|
|
72
|
-
//#endregion
|
|
73
|
-
export { Attrs, type ComponentProps, type ElementProps, Fragment, FunctionMaybe, JSX, type MaybeReactive, type MaybeReactiveProps, type Props, type Require, SlotProps, createElement as h, createElement as jsx, createElement as jsxDEV, createElement as jsxs };
|
|
1
|
+
import { U as createElement, _ as SlotProps, a as RawProps, b as MaybeReactive, c as ResolveProps, d as ComponentClass, f as ComponentFn, g as JSX, h as Attrs, i as Props, l as Child, m as PropsTarget, n as ElementProps, o as ReactiveProps, p as ComponentInstance, r as MaybeReactiveProps, s as Require, t as ComponentProps, u as Component, v as Fragment } from "../infer-DuFY-y2b.mjs";
|
|
2
|
+
export { Attrs, Child, Component, ComponentClass, ComponentFn, ComponentInstance, ComponentProps, ElementProps, Fragment, JSX, MaybeReactive, MaybeReactiveProps, Props, PropsTarget, RawProps, ReactiveProps, Require, ResolveProps, SlotProps, createElement as h, createElement as jsx, createElement as jsxDEV, createElement as jsxs };
|
|
@@ -1,26 +1,20 @@
|
|
|
1
|
-
import { t as createElement } from "../element-
|
|
2
|
-
import { _ as onCleanup } from "../signals-J8dK_rA4.mjs";
|
|
1
|
+
import { r as mountChild, t as createElement } from "../element-w1GCIMVp.mjs";
|
|
3
2
|
//#region src/jsx-runtime/fragment.ts
|
|
4
3
|
/**
|
|
5
4
|
* Used by the JSX transform for `<>...</>` fragments.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* Each child is routed through `mountChild`, which handles Nodes, strings,
|
|
7
|
+
* numbers, arrays, and reactive getters — matching the behavior of any other
|
|
8
|
+
* JSX container. `mountChild` also wires each child's cleanup via its own
|
|
9
|
+
* `effectScope`, which links to the enclosing `effectScope` created by
|
|
10
|
+
* `createElement(Fragment, ...)` for disposal propagation.
|
|
10
11
|
*/
|
|
11
12
|
function Fragment(props) {
|
|
12
13
|
const fragment = document.createDocumentFragment();
|
|
13
|
-
const raw = props.children;
|
|
14
|
+
const raw = props.children?.();
|
|
14
15
|
if (raw == null) return fragment;
|
|
15
16
|
const nodes = Array.isArray(raw) ? raw.flat(Infinity) : [raw];
|
|
16
|
-
const
|
|
17
|
-
for (const child of nodes) {
|
|
18
|
-
if (!(child instanceof Node)) continue;
|
|
19
|
-
const dispose = child[Symbol.dispose];
|
|
20
|
-
if (dispose) disposes.push(dispose);
|
|
21
|
-
fragment.appendChild(child);
|
|
22
|
-
}
|
|
23
|
-
if (disposes.length) onCleanup(() => disposes.forEach((fn) => fn()));
|
|
17
|
+
for (const child of nodes) mountChild(fragment, child);
|
|
24
18
|
return fragment;
|
|
25
19
|
}
|
|
26
20
|
//#endregion
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import "./polyfill-B1lNNcum.mjs";
|
|
2
1
|
//#region src/signals/system.ts
|
|
3
2
|
/**
|
|
4
3
|
* Creates and returns the five core graph-manipulation functions that together
|
|
@@ -908,107 +907,4 @@ function purgeDeps(sub) {
|
|
|
908
907
|
while (dep !== void 0) dep = unlink(dep, sub);
|
|
909
908
|
}
|
|
910
909
|
//#endregion
|
|
911
|
-
|
|
912
|
-
function isReactive(value) {
|
|
913
|
-
return isSignal(value) || isComputed(value);
|
|
914
|
-
}
|
|
915
|
-
/**
|
|
916
|
-
* A decorator that makes a class field reactive by automatically wrapping its value in a signal.
|
|
917
|
-
*
|
|
918
|
-
* The field behaves like a normal property (get/set) but reactivity is tracked under the hood.
|
|
919
|
-
* Any reads will subscribe to the signal and any writes will trigger updates.
|
|
920
|
-
*
|
|
921
|
-
* @example
|
|
922
|
-
* ```ts
|
|
923
|
-
* class Counter {
|
|
924
|
-
* @reactive()
|
|
925
|
-
* count: number = 0;
|
|
926
|
-
* }
|
|
927
|
-
*
|
|
928
|
-
* const counter = new Counter();
|
|
929
|
-
* counter.count++; // Triggers reactivity
|
|
930
|
-
* console.log(counter.count); // Subscribes to changes
|
|
931
|
-
* ```
|
|
932
|
-
*
|
|
933
|
-
* @remarks
|
|
934
|
-
* Equivalent to manually creating a private signal and getter/setter:
|
|
935
|
-
* ```ts
|
|
936
|
-
* class Counter {
|
|
937
|
-
* #count = signal(0);
|
|
938
|
-
* get count() { return this.#count(); }
|
|
939
|
-
* set count(value) { this.#count(value); }
|
|
940
|
-
* }
|
|
941
|
-
* ```
|
|
942
|
-
*/
|
|
943
|
-
function reactive(source) {
|
|
944
|
-
const signalStore = /* @__PURE__ */ new WeakMap();
|
|
945
|
-
return (_target, context) => {
|
|
946
|
-
context.addInitializer(function() {
|
|
947
|
-
const sig = signalStore.get(this);
|
|
948
|
-
const writable = !isComputed(sig);
|
|
949
|
-
Object.defineProperty(this, context.name, {
|
|
950
|
-
get() {
|
|
951
|
-
return sig();
|
|
952
|
-
},
|
|
953
|
-
...writable && { set(value) {
|
|
954
|
-
sig(value);
|
|
955
|
-
} },
|
|
956
|
-
enumerable: true,
|
|
957
|
-
configurable: true
|
|
958
|
-
});
|
|
959
|
-
});
|
|
960
|
-
return function(initialValue) {
|
|
961
|
-
signalStore.set(this, source ? source(this) : signal(initialValue));
|
|
962
|
-
return initialValue;
|
|
963
|
-
};
|
|
964
|
-
};
|
|
965
|
-
}
|
|
966
|
-
/**
|
|
967
|
-
* Resolve a {@link MaybeReactive} to its current value. Calls the getter
|
|
968
|
-
* when reactive; returns the value as-is when static.
|
|
969
|
-
*
|
|
970
|
-
* @example
|
|
971
|
-
* ```ts
|
|
972
|
-
* resolve(5); // 5
|
|
973
|
-
* resolve(() => count()); // current count value
|
|
974
|
-
* ```
|
|
975
|
-
*/
|
|
976
|
-
function resolve(value) {
|
|
977
|
-
return isReactive(value) ? value() : value;
|
|
978
|
-
}
|
|
979
|
-
/**
|
|
980
|
-
* Turn a reactive-props object into a bag of per-key getters. Callers may
|
|
981
|
-
* pass values or reactive sources (`signal`, `computed`); reading
|
|
982
|
-
* `props.name()` inside an effect or JSX getter subscribes to whatever
|
|
983
|
-
* drives it. Static values become stable thunks, signals and computed pass
|
|
984
|
-
* through unchanged — so identity is preserved (`props.name === props.name`).
|
|
985
|
-
*
|
|
986
|
-
* @example
|
|
987
|
-
* ```tsx
|
|
988
|
-
* import { resolveProps } from "elements-kit/signals";
|
|
989
|
-
*
|
|
990
|
-
* function Greeting(raw: MaybeReactiveProps<{ name: string; excited?: boolean }>) {
|
|
991
|
-
* const props = resolveProps(raw);
|
|
992
|
-
* return (
|
|
993
|
-
* <p>
|
|
994
|
-
* Hello, {props.name}
|
|
995
|
-
* {() => (props.excited() ? "!" : ".")}
|
|
996
|
-
* </p>
|
|
997
|
-
* );
|
|
998
|
-
* }
|
|
999
|
-
* ```
|
|
1000
|
-
*/
|
|
1001
|
-
function resolveProps(raw) {
|
|
1002
|
-
const cache = /* @__PURE__ */ new Map();
|
|
1003
|
-
return new Proxy(raw, { get(target, key) {
|
|
1004
|
-
let getter = cache.get(key);
|
|
1005
|
-
if (!getter) {
|
|
1006
|
-
const v = target[key];
|
|
1007
|
-
getter = isReactive(v) ? v : () => v;
|
|
1008
|
-
cache.set(key, getter);
|
|
1009
|
-
}
|
|
1010
|
-
return getter;
|
|
1011
|
-
} });
|
|
1012
|
-
}
|
|
1013
|
-
//#endregion
|
|
1014
|
-
export { onCleanup as _, COMPUTED as a, untracked as b, SIGNAL as c, effect as d, effectScope as f, isSignal as g, isEffectScope as h, resolveProps as i, batch as l, isEffect as m, reactive as n, EFFECT as o, isComputed as p, resolve as r, EFFECT_SCOPE as s, isReactive as t, computed as u, signal as v, trigger as y };
|
|
910
|
+
export { batch as a, effectScope as c, isEffectScope as d, isSignal as f, untracked as g, trigger as h, SIGNAL as i, isComputed as l, signal as m, EFFECT as n, computed as o, onCleanup as p, EFFECT_SCOPE as r, effect as s, COMPUTED as t, isEffect as u };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/render.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Mount a node into `target` with a scoped lifetime.
|
|
4
|
+
*
|
|
5
|
+
* `setup` runs inside a detached `effectScope`. The returned node is appended
|
|
6
|
+
* to `target`. Calling the returned `unmount` removes the node from the DOM,
|
|
7
|
+
* disposes its `Symbol.dispose` hook (JSX-created elements carry one), and
|
|
8
|
+
* tears down every `effect` / `onCleanup` registered inside `setup`.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* import { render } from "elements-kit/render";
|
|
13
|
+
*
|
|
14
|
+
* const unmount = render(document.getElementById("app")!, () => <App />);
|
|
15
|
+
* // later
|
|
16
|
+
* unmount();
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
declare function render(target: Element | DocumentFragment, setup: () => Node | null | undefined): () => void;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { render };
|
package/dist/render.mjs
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { t as scope } from "./scope-DM2gzOkb.mjs";
|
|
2
|
+
//#region src/render.ts
|
|
3
|
+
/**
|
|
4
|
+
* Mount a node into `target` with a scoped lifetime.
|
|
5
|
+
*
|
|
6
|
+
* `setup` runs inside a detached `effectScope`. The returned node is appended
|
|
7
|
+
* to `target`. Calling the returned `unmount` removes the node from the DOM,
|
|
8
|
+
* disposes its `Symbol.dispose` hook (JSX-created elements carry one), and
|
|
9
|
+
* tears down every `effect` / `onCleanup` registered inside `setup`.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* import { render } from "elements-kit/render";
|
|
14
|
+
*
|
|
15
|
+
* const unmount = render(document.getElementById("app")!, () => <App />);
|
|
16
|
+
* // later
|
|
17
|
+
* unmount();
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
function render(target, setup) {
|
|
21
|
+
const [result, stop] = scope(setup);
|
|
22
|
+
if (result) target.appendChild(result);
|
|
23
|
+
return () => {
|
|
24
|
+
if (result) {
|
|
25
|
+
result[Symbol.dispose]?.();
|
|
26
|
+
result.remove?.();
|
|
27
|
+
}
|
|
28
|
+
stop();
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { render };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { c as effectScope, g as untracked } from "./lib-D6duEs38.mjs";
|
|
2
|
+
//#region src/signals/scope.ts
|
|
3
|
+
/**
|
|
4
|
+
* Run `setup` inside a fresh `effectScope`. Returns `[result, stop]`.
|
|
5
|
+
*
|
|
6
|
+
* Use this wherever you need reactive code with an explicit lifetime outside
|
|
7
|
+
* the JSX element flow — most commonly a custom element's `connectedCallback`.
|
|
8
|
+
* `effect`, `onCleanup`, and any nested reactive registrations made in
|
|
9
|
+
* `setup` are owned by the returned `stop`.
|
|
10
|
+
*
|
|
11
|
+
* `untracked` detaches the new scope from any enclosing effect so it isn't
|
|
12
|
+
* torn down when that effect re-runs — its lifetime belongs solely to the
|
|
13
|
+
* caller.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* class Clock extends HTMLElement {
|
|
18
|
+
* #stop?: () => void;
|
|
19
|
+
*
|
|
20
|
+
* connectedCallback() {
|
|
21
|
+
* [, this.#stop] = scope(() => {
|
|
22
|
+
* const id = setInterval(() => (this.textContent = String(Date.now())), 1000);
|
|
23
|
+
* onCleanup(() => clearInterval(id));
|
|
24
|
+
* });
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* disconnectedCallback() {
|
|
28
|
+
* this.#stop?.();
|
|
29
|
+
* this.#stop = undefined;
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
function scope(setup) {
|
|
35
|
+
let result;
|
|
36
|
+
let stop;
|
|
37
|
+
untracked(() => {
|
|
38
|
+
stop = effectScope(() => {
|
|
39
|
+
result = setup();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
return [result, stop];
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { scope as t };
|
package/dist/signals/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as SIGNAL, B as signal, C as isReactive, D as COMPUTED, E as resolveProps, F as isComputed, H as untracked, I as isEffect, L as isEffectScope, M as computed, N as effect, O as EFFECT, P as effectScope, R as isSignal, S as Updater, T as resolve, V as trigger, b as MaybeReactive, j as batch, k as EFFECT_SCOPE, w as reactive, x as Signal, y as Computed, z as onCleanup } from "../infer-DuFY-y2b.mjs";
|
|
2
2
|
export { COMPUTED, Computed, EFFECT, EFFECT_SCOPE, MaybeReactive, SIGNAL, Signal, Updater, batch, computed, effect, effectScope, isComputed, isEffect, isEffectScope, isReactive, isSignal, onCleanup, reactive, resolve, resolveProps, signal, trigger, untracked };
|
package/dist/signals/index.mjs
CHANGED
|
@@ -1,2 +1,135 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as batch, c as effectScope, d as isEffectScope, f as isSignal, g as untracked, h as trigger, i as SIGNAL, l as isComputed, m as signal, n as EFFECT, o as computed, p as onCleanup, r as EFFECT_SCOPE, s as effect, t as COMPUTED, u as isEffect } from "../lib-D6duEs38.mjs";
|
|
2
|
+
import "../polyfill-B1lNNcum.mjs";
|
|
3
|
+
//#region src/signals/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* Type-guard: `true` when `value` is a reactive source (`signal` or `computed`),
|
|
6
|
+
* `false` when it is a plain value.
|
|
7
|
+
*
|
|
8
|
+
* Use this when you accept {@link MaybeReactive} and need to branch on whether
|
|
9
|
+
* the caller passed a live source or a static value.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { signal, isReactive } from "elements-kit/signals";
|
|
14
|
+
*
|
|
15
|
+
* const a: MaybeReactive<number> = 5;
|
|
16
|
+
* const b: MaybeReactive<number> = signal(0);
|
|
17
|
+
* const c: () => number = () => 5;
|
|
18
|
+
*
|
|
19
|
+
* isReactive(a); // false
|
|
20
|
+
* isReactive(b); // true
|
|
21
|
+
* isReactive(c); // false
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
function isReactive(value) {
|
|
25
|
+
return isSignal(value) || isComputed(value);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A decorator that makes a class field reactive by automatically wrapping its value in a signal.
|
|
29
|
+
*
|
|
30
|
+
* The field behaves like a normal property (get/set) but reactivity is tracked under the hood.
|
|
31
|
+
* Any reads will subscribe to the signal and any writes will trigger updates.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* class Counter {
|
|
36
|
+
* \@reactive() count: number = 0;
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* const counter = new Counter();
|
|
40
|
+
* counter.count++; // Triggers reactivity
|
|
41
|
+
* console.log(counter.count); // Subscribes to changes
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @remarks
|
|
45
|
+
* Equivalent to manually creating a private signal and getter/setter:
|
|
46
|
+
* ```ts
|
|
47
|
+
* class Counter {
|
|
48
|
+
* #count = signal(0);
|
|
49
|
+
* get count() { return this.#count(); }
|
|
50
|
+
* set count(value) { this.#count(value); }
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
function reactive(source) {
|
|
55
|
+
const signalStore = /* @__PURE__ */ new WeakMap();
|
|
56
|
+
return (_target, context) => {
|
|
57
|
+
context.addInitializer(function() {
|
|
58
|
+
const sig = signalStore.get(this);
|
|
59
|
+
const writable = !isComputed(sig);
|
|
60
|
+
Object.defineProperty(this, context.name, {
|
|
61
|
+
get() {
|
|
62
|
+
return sig();
|
|
63
|
+
},
|
|
64
|
+
...writable && { set(value) {
|
|
65
|
+
sig(value);
|
|
66
|
+
} },
|
|
67
|
+
enumerable: true,
|
|
68
|
+
configurable: true
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
return function(initialValue) {
|
|
72
|
+
signalStore.set(this, source ? source(this) : signal(initialValue));
|
|
73
|
+
return initialValue;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Resolve a {@link MaybeReactive} to its current value. Calls the getter
|
|
79
|
+
* when reactive; returns the value as-is when static.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* resolve(5); // 5
|
|
84
|
+
* resolve(() => count()); // current count value
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
function resolve(value) {
|
|
88
|
+
return isReactive(value) ? value() : value;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Turn a reactive-props object into a bag of per-key getters. Callers may
|
|
92
|
+
* pass values or reactive sources (`signal`, `computed`); reading
|
|
93
|
+
* `props.name()` inside an effect or JSX getter subscribes to whatever
|
|
94
|
+
* drives it. Static values become stable thunks, signals and computed pass
|
|
95
|
+
* through unchanged — so identity is preserved (`props.name === props.name`).
|
|
96
|
+
*
|
|
97
|
+
* The JSX runtime auto-applies this to function-component props — call
|
|
98
|
+
* directly only for non-JSX call sites or nested prop bags.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* import { resolveProps } from "elements-kit/signals";
|
|
103
|
+
* import { signal } from "elements-kit/signals";
|
|
104
|
+
*
|
|
105
|
+
* const count = signal(0);
|
|
106
|
+
* const props = resolveProps({ count, label: "n" });
|
|
107
|
+
* props.count(); // 0 — subscribes to count
|
|
108
|
+
* props.label(); // "n"
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
function resolveProps(raw) {
|
|
112
|
+
const cache = /* @__PURE__ */ new Map();
|
|
113
|
+
const get = (key) => {
|
|
114
|
+
let getter = cache.get(key);
|
|
115
|
+
if (!getter) {
|
|
116
|
+
const v = raw[key];
|
|
117
|
+
getter = isReactive(v) ? v : () => v;
|
|
118
|
+
cache.set(key, getter);
|
|
119
|
+
}
|
|
120
|
+
return getter;
|
|
121
|
+
};
|
|
122
|
+
return new Proxy(raw, {
|
|
123
|
+
get: (_target, key) => get(key),
|
|
124
|
+
has: (_target, key) => key in raw,
|
|
125
|
+
ownKeys: (_target) => Reflect.ownKeys(raw),
|
|
126
|
+
getOwnPropertyDescriptor: (_target, key) => key in raw ? {
|
|
127
|
+
enumerable: true,
|
|
128
|
+
configurable: true,
|
|
129
|
+
writable: false,
|
|
130
|
+
value: get(key)
|
|
131
|
+
} : void 0
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
//#endregion
|
|
2
135
|
export { COMPUTED, EFFECT, EFFECT_SCOPE, SIGNAL, batch, computed, effect, effectScope, isComputed, isEffect, isEffectScope, isReactive, isSignal, onCleanup, reactive, resolve, resolveProps, signal, trigger, untracked };
|
|
@@ -127,7 +127,6 @@ var Slot = class Slot {
|
|
|
127
127
|
});
|
|
128
128
|
}
|
|
129
129
|
};
|
|
130
|
-
/** A callable slot — invoke to render, or access `.set()` / `.isMounted()` / `.parent()` for management. */
|
|
131
130
|
/**
|
|
132
131
|
* Symbol key for attaching a `Slots` instance to a custom element instance.
|
|
133
132
|
* This prevent collisions with Element properties and are not meant to be treated as JSX children.
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
//#region src/lib.d.ts
|
|
2
2
|
type PrimitiveNodeType = Node | string | boolean | number | bigint | symbol | Date | RegExp | null | undefined;
|
|
3
3
|
//#endregion
|
|
4
|
+
//#region src/polyfill.d.ts
|
|
5
|
+
declare global {
|
|
6
|
+
interface SymbolConstructor {
|
|
7
|
+
readonly dispose: symbol;
|
|
8
|
+
}
|
|
9
|
+
interface Disposable {
|
|
10
|
+
[Symbol.dispose](): void;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
4
14
|
//#region src/slot.d.ts
|
|
5
15
|
/**
|
|
6
16
|
* A lightweight slot that reserves a region in the DOM using comment markers.
|
|
@@ -53,8 +63,15 @@ declare class Slot {
|
|
|
53
63
|
*/
|
|
54
64
|
static new(): Slot & ((defaultContent?: PrimitiveNodeType) => DocumentFragment);
|
|
55
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* A callable slot returned by {@link Slot.new}.
|
|
68
|
+
*
|
|
69
|
+
* - Invoke it (`slot()`) to render the slot region as a `DocumentFragment`,
|
|
70
|
+
* optionally with default content on first mount.
|
|
71
|
+
* - Call `.set()` to replace current content, `.clear()` to empty it, and
|
|
72
|
+
* `.isMounted()` / `.parent()` to inspect mount state.
|
|
73
|
+
*/
|
|
56
74
|
type SlotInstance = ReturnType<typeof Slot.new>;
|
|
57
|
-
/** A callable slot — invoke to render, or access `.set()` / `.isMounted()` / `.parent()` for management. */
|
|
58
75
|
/**
|
|
59
76
|
* Symbol key for attaching a `Slots` instance to a custom element instance.
|
|
60
77
|
* This prevent collisions with Element properties and are not meant to be treated as JSX children.
|
package/dist/slot.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as Slots, n as Slot, r as SlotInstance, t as SLOTS } from "./slot-
|
|
1
|
+
import { i as Slots, n as Slot, r as SlotInstance, t as SLOTS } from "./slot-D5iBUSAm.mjs";
|
|
2
2
|
export { SLOTS, Slot, SlotInstance, Slots };
|
package/dist/slot.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as Slot, r as Slots, t as SLOTS } from "./slot-
|
|
1
|
+
import { n as Slot, r as Slots, t as SLOTS } from "./slot-CKtUoy2X.mjs";
|
|
2
2
|
export { SLOTS, Slot, Slots };
|
|
@@ -10139,7 +10139,7 @@ function memo(fn) {
|
|
|
10139
10139
|
};
|
|
10140
10140
|
}
|
|
10141
10141
|
async function saveInlineSnapshots(environment, snapshots) {
|
|
10142
|
-
const MagicString = (await import("./magic-string.es-
|
|
10142
|
+
const MagicString = (await import("./magic-string.es-cTgJnTCj.mjs")).default;
|
|
10143
10143
|
const files = new Set(snapshots.map((i) => i.file));
|
|
10144
10144
|
await Promise.all(Array.from(files).map(async (file) => {
|
|
10145
10145
|
const snaps = snapshots.filter((i) => i.file === file);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { o as computed } from "../lib-D6duEs38.mjs";
|
|
2
|
+
import "../signals/index.mjs";
|
|
2
3
|
import { fromEvent, sync } from "./event-driven.mjs";
|
|
3
4
|
import { isBrowser } from "./environment.mjs";
|
|
4
5
|
//#region src/utilities/active-element.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as describe, s as it, t as globalExpect } from "../test.BmQO5GaM-
|
|
1
|
+
import { o as describe, s as it, t as globalExpect } from "../test.BmQO5GaM-BeO5pvCo.mjs";
|
|
2
2
|
import { activeElement } from "./active-element.mjs";
|
|
3
3
|
//#region src/utilities/active-element.test.ts
|
|
4
4
|
describe("activeElement (singleton)", () => {
|
|
@@ -1,8 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { b as MaybeReactive } from "../infer-DuFY-y2b.mjs";
|
|
2
2
|
import { ComputedPromise } from "./promise.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/utilities/async.d.ts
|
|
5
|
+
/** Shape of the async function driven by {@link Async} / {@link async}. */
|
|
5
6
|
type Fn<TInput, TOutput> = (input: TInput) => Promise<TOutput>;
|
|
7
|
+
/**
|
|
8
|
+
* Reactive wrapper around an async function. Exposes the current run as
|
|
9
|
+
* reactive signals (`state`, `value`, `reason`, `result`, `pending`) and
|
|
10
|
+
* lets you `run`/`start`/`stop` the underlying task imperatively.
|
|
11
|
+
*
|
|
12
|
+
* Prefer the {@link async} factory — it returns an `Async` that is also
|
|
13
|
+
* callable as a signal (`op()` === `op.result`), which is what most call
|
|
14
|
+
* sites want. Use this class directly only when you need the object form.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { Async } from "elements-kit/utilities/async";
|
|
19
|
+
*
|
|
20
|
+
* const loader = new Async<string, User>(fetchUser);
|
|
21
|
+
* loader.run("alice");
|
|
22
|
+
* effect(() => {
|
|
23
|
+
* if (loader.state === "fulfilled") console.log(loader.value);
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
6
27
|
declare class Async<TInput = undefined, TOutput = unknown> {
|
|
7
28
|
#private;
|
|
8
29
|
get fn(): Fn<TInput, TOutput>;
|
|
@@ -32,6 +53,23 @@ declare class Async<TInput = undefined, TOutput = unknown> {
|
|
|
32
53
|
*/
|
|
33
54
|
start(...args: TInput extends undefined ? [] : [input: TInput]): this;
|
|
34
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Create an {@link Async} that is also callable as a signal: invoking it
|
|
58
|
+
* (with no args) reads the current `result`, so it drops into any reactive
|
|
59
|
+
* context that expects a zero-arg getter.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { async } from "elements-kit/utilities/async";
|
|
64
|
+
*
|
|
65
|
+
* const load = async((id: string) => fetch(`/u/${id}`).then(r => r.json()));
|
|
66
|
+
* load.run("alice");
|
|
67
|
+
*
|
|
68
|
+
* // Read as a signal — subscribes to result changes
|
|
69
|
+
* effect(() => console.log(load()));
|
|
70
|
+
* await load; // Await the current run — works like a normal promise
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
35
73
|
declare function async<TInput = any, TOutput = undefined>(fn: MaybeReactive<(input: TInput) => Promise<TOutput>>): Async<TInput, TOutput> & ((...args: any[]) => TOutput | undefined);
|
|
36
74
|
//#endregion
|
|
37
75
|
export { Async, Fn, async };
|