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.
Files changed (110) hide show
  1. package/README.md +65 -118
  2. package/dist/{attributes-Dtn68R1u.d.mts → attributes-DILeh3-s.d.mts} +42 -9
  3. package/dist/attributes.d.mts +1 -1
  4. package/dist/attributes.mjs +32 -0
  5. package/dist/{define-CjbTZ3VG.d.mts → custom-elements-D5_NMNyD.d.mts} +20 -2
  6. package/dist/custom-elements.d.mts +2 -74
  7. package/dist/custom-elements.mjs +15 -86
  8. package/dist/{element-CGVy_8TW.mjs → element-w1GCIMVp.mjs} +33 -21
  9. package/dist/for.d.mts +31 -2
  10. package/dist/for.mjs +18 -2
  11. package/dist/infer-DuFY-y2b.d.mts +657 -0
  12. package/dist/integrations/react.d.mts +1 -1
  13. package/dist/integrations/react.mjs +6 -4
  14. package/dist/jsx-runtime/index.d.mts +2 -73
  15. package/dist/jsx-runtime/index.mjs +8 -14
  16. package/dist/{signals-J8dK_rA4.mjs → lib-D6duEs38.mjs} +1 -105
  17. package/dist/render.d.mts +21 -0
  18. package/dist/render.mjs +32 -0
  19. package/dist/scope-DM2gzOkb.mjs +45 -0
  20. package/dist/signals/index.d.mts +1 -1
  21. package/dist/signals/index.mjs +134 -1
  22. package/dist/{slot-Kb61AcgW.mjs → slot-CKtUoy2X.mjs} +0 -1
  23. package/dist/{slot-C7GQZe-r.d.mts → slot-D5iBUSAm.d.mts} +18 -1
  24. package/dist/slot.d.mts +1 -1
  25. package/dist/slot.mjs +1 -1
  26. package/dist/{test.BmQO5GaM-DfGStnii.mjs → test.BmQO5GaM-BeO5pvCo.mjs} +1 -1
  27. package/dist/utilities/_observe.mjs +2 -1
  28. package/dist/utilities/active-element.d.mts +1 -1
  29. package/dist/utilities/active-element.mjs +2 -1
  30. package/dist/utilities/active-element.test.mjs +1 -1
  31. package/dist/utilities/async.d.mts +39 -1
  32. package/dist/utilities/async.mjs +39 -1
  33. package/dist/utilities/async.test.mjs +3 -2
  34. package/dist/utilities/debounced.d.mts +12 -1
  35. package/dist/utilities/debounced.mjs +13 -1
  36. package/dist/utilities/debounced.test.mjs +3 -2
  37. package/dist/utilities/element-rect.d.mts +1 -1
  38. package/dist/utilities/element-rect.mjs +2 -1
  39. package/dist/utilities/element-rect.test.mjs +3 -2
  40. package/dist/utilities/element-scroll.d.mts +1 -1
  41. package/dist/utilities/element-scroll.test.mjs +3 -2
  42. package/dist/utilities/environment.d.mts +2 -0
  43. package/dist/utilities/environment.mjs +2 -0
  44. package/dist/utilities/event-driven.d.mts +1 -1
  45. package/dist/utilities/event-driven.mjs +2 -1
  46. package/dist/utilities/event-listener.d.mts +12 -1
  47. package/dist/utilities/event-listener.mjs +2 -1
  48. package/dist/utilities/event-listener.test.mjs +3 -2
  49. package/dist/utilities/focus-within.d.mts +1 -1
  50. package/dist/utilities/focus-within.mjs +2 -1
  51. package/dist/utilities/focus-within.test.mjs +3 -2
  52. package/dist/utilities/hover.d.mts +1 -1
  53. package/dist/utilities/hover.mjs +2 -1
  54. package/dist/utilities/hover.test.mjs +3 -2
  55. package/dist/utilities/intersection-observer.test.mjs +3 -2
  56. package/dist/utilities/interval.d.mts +14 -1
  57. package/dist/utilities/interval.mjs +2 -1
  58. package/dist/utilities/interval.test.mjs +3 -2
  59. package/dist/utilities/location.d.mts +1 -1
  60. package/dist/utilities/location.mjs +2 -1
  61. package/dist/utilities/location.test.mjs +1 -1
  62. package/dist/utilities/long-press.test.mjs +3 -2
  63. package/dist/utilities/media-devices.d.mts +1 -1
  64. package/dist/utilities/media-devices.mjs +2 -1
  65. package/dist/utilities/media-devices.test.mjs +3 -2
  66. package/dist/utilities/media-player.d.mts +1 -1
  67. package/dist/utilities/media-player.test.mjs +3 -2
  68. package/dist/utilities/media-query.d.mts +1 -1
  69. package/dist/utilities/media-query.mjs +2 -1
  70. package/dist/utilities/mutation-observer.test.mjs +3 -2
  71. package/dist/utilities/network.d.mts +1 -1
  72. package/dist/utilities/network.mjs +2 -1
  73. package/dist/utilities/network.test.mjs +1 -1
  74. package/dist/utilities/on-click-outside.test.mjs +3 -2
  75. package/dist/utilities/orientation.d.mts +1 -1
  76. package/dist/utilities/orientation.mjs +2 -1
  77. package/dist/utilities/previous.d.mts +13 -1
  78. package/dist/utilities/previous.mjs +14 -1
  79. package/dist/utilities/previous.test.mjs +3 -2
  80. package/dist/utilities/promise.d.mts +7 -1
  81. package/dist/utilities/promise.mjs +2 -1
  82. package/dist/utilities/promise.test.mjs +3 -2
  83. package/dist/utilities/retry.d.mts +15 -0
  84. package/dist/utilities/retry.mjs +17 -1
  85. package/dist/utilities/retry.test.mjs +3 -2
  86. package/dist/utilities/routing.d.mts +12 -1
  87. package/dist/utilities/routing.mjs +13 -1
  88. package/dist/utilities/routing.test.mjs +1 -1
  89. package/dist/utilities/search-params.d.mts +1 -1
  90. package/dist/utilities/search-params.test.mjs +3 -2
  91. package/dist/utilities/ssr.test.mjs +1 -1
  92. package/dist/utilities/storage.d.mts +18 -1
  93. package/dist/utilities/storage.mjs +17 -0
  94. package/dist/utilities/storage.test.mjs +3 -2
  95. package/dist/utilities/throttled.d.mts +12 -1
  96. package/dist/utilities/throttled.mjs +13 -1
  97. package/dist/utilities/throttled.test.mjs +3 -2
  98. package/dist/utilities/timeout.d.mts +1 -1
  99. package/dist/utilities/timeout.mjs +2 -1
  100. package/dist/utilities/timeout.test.mjs +3 -2
  101. package/dist/utilities/window-focus.d.mts +1 -1
  102. package/dist/utilities/window-focus.mjs +2 -1
  103. package/dist/utilities/window-size.d.mts +1 -1
  104. package/dist/utilities/window-size.mjs +2 -1
  105. package/dist/utilities/window-size.test.mjs +1 -1
  106. package/package.json +1 -1
  107. package/dist/index-DydGTqZU.d.mts +0 -315
  108. package/dist/infer-BfzRJoCn.d.mts +0 -203
  109. package/dist/polyfill-BVNd6ogU.d.mts +0 -9
  110. /package/dist/{magic-string.es-i62WTP6J.mjs → magic-string.es-cTgJnTCj.mjs} +0 -0
@@ -1,73 +1,2 @@
1
- import { t as CustomElementRegistry } from "../define-CjbTZ3VG.mjs";
2
- import { a as Props, c as ComponentClass, i as MaybeReactiveProps, l as ComponentFn, n as ComponentProps, o as Require, r as ElementProps, s as Child, t as AnyElementCtor } from "../infer-BfzRJoCn.mjs";
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-CGVy_8TW.mjs";
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
- * createElement wraps this in effectScope + attachDisposables, so children's
8
- * Symbol.dispose functions are collected via onCleanup and fired when the
9
- * fragment's own dispose is called.
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 disposes = [];
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
- //#region src/signals/index.ts
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 };
@@ -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 };
@@ -1,2 +1,2 @@
1
- import { C as trigger, S as signal, _ as isComputed, a as isReactive, b as isSignal, c as resolveProps, d as EFFECT_SCOPE, f as SIGNAL, g as effectScope, h as effect, i as Updater, l as COMPUTED, m as computed, n as MaybeReactive, o as reactive, p as batch, r as Signal, s as resolve, t as Computed, u as EFFECT, v as isEffect, w as untracked, x as onCleanup, y as isEffectScope } from "../index-DydGTqZU.mjs";
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 };
@@ -1,2 +1,135 @@
1
- import { _ as onCleanup, a as COMPUTED, b as untracked, c as SIGNAL, d as effect, f as effectScope, g as isSignal, h as isEffectScope, i as resolveProps, l as batch, m as isEffect, n as reactive, o as EFFECT, p as isComputed, r as resolve, s as EFFECT_SCOPE, t as isReactive, u as computed, v as signal, y as trigger } from "../signals-J8dK_rA4.mjs";
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-C7GQZe-r.mjs";
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-Kb61AcgW.mjs";
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-i62WTP6J.mjs")).default;
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 { _ as onCleanup } from "../signals-J8dK_rA4.mjs";
1
+ import { p as onCleanup } from "../lib-D6duEs38.mjs";
2
+ import "../signals/index.mjs";
2
3
  //#region src/utilities/_observe.ts
3
4
  /**
4
5
  * Internal helper for observer wrappers (Intersection/Mutation/Resize).
@@ -1,4 +1,4 @@
1
- import { t as Computed } from "../index-DydGTqZU.mjs";
1
+ import { y as Computed } from "../infer-DuFY-y2b.mjs";
2
2
 
3
3
  //#region src/utilities/active-element.d.ts
4
4
  declare const activeElement: Computed<Element | null>;
@@ -1,4 +1,5 @@
1
- import { u as computed } from "../signals-J8dK_rA4.mjs";
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-DfGStnii.mjs";
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 { n as MaybeReactive } from "../index-DydGTqZU.mjs";
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 };