elements-kit 0.0.19 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -104
- package/dist/{attributes-aiRoArZz.d.mts → attributes-DILeh3-s.d.mts} +42 -9
- package/dist/attributes.d.mts +1 -1
- package/dist/attributes.mjs +32 -0
- package/dist/{custom-elements-bVYOkHKt.d.mts → custom-elements-D5_NMNyD.d.mts} +18 -0
- package/dist/custom-elements.d.mts +1 -1
- package/dist/custom-elements.mjs +18 -0
- package/dist/{element-DxmInKJw.mjs → element-w1GCIMVp.mjs} +1 -1
- package/dist/for.d.mts +31 -2
- package/dist/for.mjs +16 -1
- package/dist/{infer-Dv5Wk-7E.d.mts → infer-DuFY-y2b.d.mts} +66 -27
- package/dist/integrations/react.d.mts +1 -1
- package/dist/jsx-runtime/index.d.mts +1 -1
- package/dist/jsx-runtime/index.mjs +1 -1
- package/dist/signals/index.d.mts +1 -1
- package/dist/signals/index.mjs +21 -2
- package/dist/{slot-Kb61AcgW.mjs → slot-CKtUoy2X.mjs} +0 -1
- package/dist/{slot-B5_VHB7E.d.mts → slot-D5iBUSAm.d.mts} +8 -1
- package/dist/slot.d.mts +1 -1
- package/dist/slot.mjs +1 -1
- package/dist/utilities/active-element.d.mts +1 -1
- package/dist/utilities/async.d.mts +39 -1
- package/dist/utilities/async.mjs +37 -0
- package/dist/utilities/debounced.d.mts +12 -1
- package/dist/utilities/debounced.mjs +11 -0
- package/dist/utilities/element-rect.d.mts +1 -1
- package/dist/utilities/element-scroll.d.mts +1 -1
- 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-listener.d.mts +12 -1
- package/dist/utilities/focus-within.d.mts +1 -1
- package/dist/utilities/hover.d.mts +1 -1
- package/dist/utilities/interval.d.mts +14 -1
- package/dist/utilities/location.d.mts +1 -1
- package/dist/utilities/media-devices.d.mts +1 -1
- package/dist/utilities/media-player.d.mts +1 -1
- package/dist/utilities/media-query.d.mts +1 -1
- package/dist/utilities/network.d.mts +1 -1
- package/dist/utilities/orientation.d.mts +1 -1
- package/dist/utilities/previous.d.mts +13 -1
- package/dist/utilities/previous.mjs +12 -0
- package/dist/utilities/promise.d.mts +7 -1
- package/dist/utilities/retry.d.mts +15 -0
- package/dist/utilities/retry.mjs +15 -0
- package/dist/utilities/routing.d.mts +12 -1
- package/dist/utilities/routing.mjs +11 -0
- package/dist/utilities/search-params.d.mts +1 -1
- package/dist/utilities/storage.d.mts +18 -1
- package/dist/utilities/storage.mjs +17 -0
- package/dist/utilities/throttled.d.mts +12 -1
- package/dist/utilities/throttled.mjs +11 -0
- package/dist/utilities/timeout.d.mts +1 -1
- package/dist/utilities/window-focus.d.mts +1 -1
- package/dist/utilities/window-size.d.mts +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as AttrChangeHandler, t as ATTRIBUTES } from "./attributes-
|
|
2
|
-
import { t as CustomElementRegistry } from "./custom-elements-
|
|
3
|
-
import { a as PrimitiveNodeType, i as Slots, n as Slot, t as SLOTS } from "./slot-
|
|
1
|
+
import { n as AttrChangeHandler, t as ATTRIBUTES } from "./attributes-DILeh3-s.mjs";
|
|
2
|
+
import { t as CustomElementRegistry } from "./custom-elements-D5_NMNyD.mjs";
|
|
3
|
+
import { a as PrimitiveNodeType, i as Slots, n as Slot, t as SLOTS } from "./slot-D5iBUSAm.mjs";
|
|
4
4
|
import { JSX } from "dom-expressions/src/jsx-h";
|
|
5
5
|
|
|
6
6
|
//#region src/jsx-runtime/element.d.ts
|
|
@@ -233,9 +233,44 @@ declare function untracked<T>(fn: Computed<T>): T;
|
|
|
233
233
|
declare function trigger<T = void>(fn: Computed<T>): void;
|
|
234
234
|
//#endregion
|
|
235
235
|
//#region src/signals/index.d.ts
|
|
236
|
+
/**
|
|
237
|
+
* Type-guard: `true` when `value` is a reactive source (`signal` or `computed`),
|
|
238
|
+
* `false` when it is a plain value.
|
|
239
|
+
*
|
|
240
|
+
* Use this when you accept {@link MaybeReactive} and need to branch on whether
|
|
241
|
+
* the caller passed a live source or a static value.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```ts
|
|
245
|
+
* import { signal, isReactive } from "elements-kit/signals";
|
|
246
|
+
*
|
|
247
|
+
* const a: MaybeReactive<number> = 5;
|
|
248
|
+
* const b: MaybeReactive<number> = signal(0);
|
|
249
|
+
* const c: () => number = () => 5;
|
|
250
|
+
*
|
|
251
|
+
* isReactive(a); // false
|
|
252
|
+
* isReactive(b); // true
|
|
253
|
+
* isReactive(c); // false
|
|
254
|
+
* ```
|
|
255
|
+
*/
|
|
236
256
|
declare function isReactive<T>(value: MaybeReactive<T>): value is () => T;
|
|
257
|
+
/** Writer half of a {@link Signal}: `sig(next)` assigns a new value. */
|
|
237
258
|
type Updater<T> = (value: T) => void;
|
|
259
|
+
/** Zero-arg getter that subscribes the current tracking scope on call. */
|
|
238
260
|
type Computed<T> = () => T;
|
|
261
|
+
/**
|
|
262
|
+
* A reactive read/write cell — callable as both a getter (no args) and a
|
|
263
|
+
* setter (one arg).
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* ```ts
|
|
267
|
+
* import { signal } from "elements-kit/signals";
|
|
268
|
+
*
|
|
269
|
+
* const count: Signal<number> = signal(0);
|
|
270
|
+
* count(); // read → 0 (subscribes the active scope)
|
|
271
|
+
* count(5); // write → notifies subscribers
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
239
274
|
type Signal<T> = Updater<T> & Computed<T>;
|
|
240
275
|
/**
|
|
241
276
|
* A decorator that makes a class field reactive by automatically wrapping its value in a signal.
|
|
@@ -246,8 +281,7 @@ type Signal<T> = Updater<T> & Computed<T>;
|
|
|
246
281
|
* @example
|
|
247
282
|
* ```ts
|
|
248
283
|
* class Counter {
|
|
249
|
-
*
|
|
250
|
-
* count: number = 0;
|
|
284
|
+
* \@reactive() count: number = 0;
|
|
251
285
|
* }
|
|
252
286
|
*
|
|
253
287
|
* const counter = new Counter();
|
|
@@ -359,15 +393,26 @@ type SlotProps<K extends string> = { [P in K as `slot:${P}`]?: Child };
|
|
|
359
393
|
* ```
|
|
360
394
|
*/
|
|
361
395
|
type Attrs<K extends keyof JSX$1.IntrinsicElements> = JSX$1.IntrinsicElements[K];
|
|
362
|
-
/**
|
|
363
|
-
|
|
396
|
+
/**
|
|
397
|
+
* Namespaced JSX props added by elements-kit on top of dom-expressions.
|
|
398
|
+
*
|
|
399
|
+
* - `ref` — callback invoked with the mounted element.
|
|
400
|
+
* - `slot:foo` — accepts any `Child`. Reactive children come for free because
|
|
401
|
+
* `Child` already includes `AnyFn` (so `() => content()` and `signal` both
|
|
402
|
+
* typecheck and are wired as reactive slots by `mountChild`).
|
|
403
|
+
* - `class:foo` / `style:foo` — `MaybeReactive<T>` (value or zero-arg getter),
|
|
404
|
+
* because their value types (`boolean` / `string | null`) are primitives
|
|
405
|
+
* that don't otherwise allow function form.
|
|
406
|
+
* - `prop:foo` — any value, direct property assignment, no reactive coupling.
|
|
407
|
+
*/
|
|
408
|
+
type JsxNamespaces = {
|
|
364
409
|
ref?: (el: Element) => void;
|
|
365
|
-
[slot: `slot:${string}`]:
|
|
366
|
-
[cls: `class:${string}`]:
|
|
367
|
-
[sty: `style:${string}`]:
|
|
368
|
-
[prop: `prop:${string}`]:
|
|
410
|
+
[slot: `slot:${string}`]: Child;
|
|
411
|
+
[cls: `class:${string}`]: MaybeReactive<boolean>;
|
|
412
|
+
[sty: `style:${string}`]: MaybeReactive<string | null>;
|
|
413
|
+
[prop: `prop:${string}`]: unknown;
|
|
369
414
|
};
|
|
370
|
-
type
|
|
415
|
+
type WithJsxNamespaces<T> = T & JsxNamespaces;
|
|
371
416
|
declare namespace JSX$1 {
|
|
372
417
|
export type Element = globalThis.Element | globalThis.DocumentFragment | null;
|
|
373
418
|
export type ElementType = Child | Component;
|
|
@@ -378,9 +423,9 @@ declare namespace JSX$1 {
|
|
|
378
423
|
ref?: (el: Element) => void;
|
|
379
424
|
}
|
|
380
425
|
export type LibraryManagedAttributes<C, P> = ResolveProps<C, P>;
|
|
381
|
-
type RegisteredElements = { [K in keyof CustomElementRegistry]: CustomElementRegistry[K] extends AnyElementCtor ? ElementProps<CustomElementRegistry[K]
|
|
382
|
-
export type IntrinsicElements = { [K in keyof JSX.IntrinsicElements]:
|
|
383
|
-
/** Unregistered custom elements (`x-foo`, `my-component`, …) — loose fallback. */[customElement: `${string}-${string}`]:
|
|
426
|
+
type RegisteredElements = { [K in keyof CustomElementRegistry]: CustomElementRegistry[K] extends AnyElementCtor ? MaybeReactiveProps<ElementProps<CustomElementRegistry[K]>> : never };
|
|
427
|
+
export type IntrinsicElements = { [K in keyof JSX.IntrinsicElements]: WithJsxNamespaces<JSX.IntrinsicElements[K]> } & RegisteredElements & {
|
|
428
|
+
/** Unregistered custom elements (`x-foo`, `my-component`, …) — loose fallback. */[customElement: `${string}-${string}`]: WithJsxNamespaces<JSX.DOMAttributes<HTMLElement>> & Record<string, unknown>;
|
|
384
429
|
};
|
|
385
430
|
export {};
|
|
386
431
|
}
|
|
@@ -487,14 +532,14 @@ type AttrMap<C> = C extends {
|
|
|
487
532
|
[ATTRIBUTES]: infer M;
|
|
488
533
|
} ? M : {};
|
|
489
534
|
type HandlerValue<H> = H extends AttrChangeHandler<any> ? string | null : H;
|
|
490
|
-
type AttrsOf<C> = AttrMap<C> extends infer M ? M extends Record<string, unknown> ? { [K in Exclude<keyof M & string, PropKeysOf<C>>]?:
|
|
491
|
-
type FlatPropsOf<C> =
|
|
535
|
+
type AttrsOf<C> = AttrMap<C> extends infer M ? M extends Record<string, unknown> ? string extends keyof M ? {} : { [K in Exclude<keyof M & string, PropKeysOf<C>>]?: HandlerValue<M[K]> } : {} : {};
|
|
536
|
+
type FlatPropsOf<C> = InstancePropsOf<C>;
|
|
492
537
|
type PropNamespacedOf<C> = { [K in PropKeysOf<C> as `prop:${K}`]?: NonNullable<InstancePropsOf<C>[K]> };
|
|
493
538
|
type EventMapOf<C> = C extends {
|
|
494
539
|
events: infer E;
|
|
495
540
|
} ? E : {};
|
|
496
541
|
type Capitalize1<S extends string> = S extends `${infer H}${infer R}` ? `${Uppercase<H>}${R}` : S;
|
|
497
|
-
type EventsOf<C> = EventMapOf<C> extends infer E ? E extends Record<string, Event> ? { [K in keyof E & string as `on:${K}`]?:
|
|
542
|
+
type EventsOf<C> = EventMapOf<C> extends infer E ? E extends Record<string, Event> ? { [K in keyof E & string as `on:${K}`]?: (ev: E[K]) => void } & { [K in keyof E & string as `on${Capitalize1<K>}`]?: (ev: E[K]) => void } : {} : {};
|
|
498
543
|
type SlotKeys<I> = I extends {
|
|
499
544
|
[SLOTS]: Slots<infer K>;
|
|
500
545
|
} ? K : never;
|
|
@@ -506,12 +551,6 @@ type ChildrenOf<C> = C extends {
|
|
|
506
551
|
children?: Child;
|
|
507
552
|
};
|
|
508
553
|
type BaseDOMAttrs = JSX.DOMAttributes<HTMLElement>;
|
|
509
|
-
type Namespaces = {
|
|
510
|
-
ref?: (el: Element) => void;
|
|
511
|
-
[cls: `class:${string}`]: MaybeReactive<boolean>;
|
|
512
|
-
[sty: `style:${string}`]: MaybeReactive<string | null>;
|
|
513
|
-
[prop: `prop:${string}`]: unknown;
|
|
514
|
-
};
|
|
515
554
|
/**
|
|
516
555
|
* Full JSX prop type for a custom-element class (extends `HTMLElement`).
|
|
517
556
|
*
|
|
@@ -530,12 +569,12 @@ type Namespaces = {
|
|
|
530
569
|
*
|
|
531
570
|
* @example
|
|
532
571
|
* ```ts
|
|
533
|
-
*
|
|
572
|
+
* \@attributes
|
|
534
573
|
* class XRange extends HTMLElement {
|
|
535
574
|
* static [ATTRIBUTES]: Attributes<XRange> = { min(v) { this.min = +v! } };
|
|
536
575
|
* declare static events: { commit: CustomEvent<number> };
|
|
537
576
|
* [SLOTS] = Slots.new(["label"] as const);
|
|
538
|
-
*
|
|
577
|
+
* \@reactive() min = 0;
|
|
539
578
|
* }
|
|
540
579
|
*
|
|
541
580
|
* type Props = ElementProps<typeof XRange>;
|
|
@@ -552,7 +591,7 @@ type Namespaces = {
|
|
|
552
591
|
*
|
|
553
592
|
* @see {@link Props} for class-components / function components (no attr/event/slot synthesis).
|
|
554
593
|
*/
|
|
555
|
-
type ElementProps<C extends AnyElementCtor> = BaseDOMAttrs & AttrsOf<C> & FlatPropsOf<C> & PropNamespacedOf<C> & EventsOf<C> & SlotsOf<C> & ChildrenOf<C
|
|
594
|
+
type ElementProps<C extends AnyElementCtor> = BaseDOMAttrs & AttrsOf<C> & FlatPropsOf<C> & PropNamespacedOf<C> & EventsOf<C> & SlotsOf<C> & ChildrenOf<C>;
|
|
556
595
|
/**
|
|
557
596
|
* Props of a class component that receives them via its constructor:
|
|
558
597
|
* `class Comp { constructor(props: P) }`. Reads `ConstructorParameters[0]`.
|
|
@@ -1,2 +1,2 @@
|
|
|
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-
|
|
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
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 };
|
package/dist/signals/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
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-
|
|
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,6 +1,26 @@
|
|
|
1
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
2
|
import "../polyfill-B1lNNcum.mjs";
|
|
3
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
|
+
*/
|
|
4
24
|
function isReactive(value) {
|
|
5
25
|
return isSignal(value) || isComputed(value);
|
|
6
26
|
}
|
|
@@ -13,8 +33,7 @@ function isReactive(value) {
|
|
|
13
33
|
* @example
|
|
14
34
|
* ```ts
|
|
15
35
|
* class Counter {
|
|
16
|
-
*
|
|
17
|
-
* count: number = 0;
|
|
36
|
+
* \@reactive() count: number = 0;
|
|
18
37
|
* }
|
|
19
38
|
*
|
|
20
39
|
* const counter = new Counter();
|
|
@@ -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.
|
|
@@ -63,8 +63,15 @@ declare class Slot {
|
|
|
63
63
|
*/
|
|
64
64
|
static new(): Slot & ((defaultContent?: PrimitiveNodeType) => DocumentFragment);
|
|
65
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
|
+
*/
|
|
66
74
|
type SlotInstance = ReturnType<typeof Slot.new>;
|
|
67
|
-
/** A callable slot — invoke to render, or access `.set()` / `.isMounted()` / `.parent()` for management. */
|
|
68
75
|
/**
|
|
69
76
|
* Symbol key for attaching a `Slots` instance to a custom element instance.
|
|
70
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 };
|
|
@@ -1,8 +1,29 @@
|
|
|
1
|
-
import { b as MaybeReactive } from "../infer-
|
|
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 };
|
package/dist/utilities/async.mjs
CHANGED
|
@@ -2,6 +2,26 @@ import { g as untracked, m as signal, s as effect } from "../lib-D6duEs38.mjs";
|
|
|
2
2
|
import { resolve } from "../signals/index.mjs";
|
|
3
3
|
import { promise } from "./promise.mjs";
|
|
4
4
|
//#region src/utilities/async.ts
|
|
5
|
+
/**
|
|
6
|
+
* Reactive wrapper around an async function. Exposes the current run as
|
|
7
|
+
* reactive signals (`state`, `value`, `reason`, `result`, `pending`) and
|
|
8
|
+
* lets you `run`/`start`/`stop` the underlying task imperatively.
|
|
9
|
+
*
|
|
10
|
+
* Prefer the {@link async} factory — it returns an `Async` that is also
|
|
11
|
+
* callable as a signal (`op()` === `op.result`), which is what most call
|
|
12
|
+
* sites want. Use this class directly only when you need the object form.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { Async } from "elements-kit/utilities/async";
|
|
17
|
+
*
|
|
18
|
+
* const loader = new Async<string, User>(fetchUser);
|
|
19
|
+
* loader.run("alice");
|
|
20
|
+
* effect(() => {
|
|
21
|
+
* if (loader.state === "fulfilled") console.log(loader.value);
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
5
25
|
var Async = class {
|
|
6
26
|
#fn = signal(async () => Promise.resolve(void 0));
|
|
7
27
|
#cleanup = () => {};
|
|
@@ -97,6 +117,23 @@ const ASYNC_KEYS = new Set([
|
|
|
97
117
|
"raw",
|
|
98
118
|
Symbol.dispose
|
|
99
119
|
]);
|
|
120
|
+
/**
|
|
121
|
+
* Create an {@link Async} that is also callable as a signal: invoking it
|
|
122
|
+
* (with no args) reads the current `result`, so it drops into any reactive
|
|
123
|
+
* context that expects a zero-arg getter.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* import { async } from "elements-kit/utilities/async";
|
|
128
|
+
*
|
|
129
|
+
* const load = async((id: string) => fetch(`/u/${id}`).then(r => r.json()));
|
|
130
|
+
* load.run("alice");
|
|
131
|
+
*
|
|
132
|
+
* // Read as a signal — subscribes to result changes
|
|
133
|
+
* effect(() => console.log(load()));
|
|
134
|
+
* await load; // Await the current run — works like a normal promise
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
100
137
|
function async(fn) {
|
|
101
138
|
const inst = new Async(fn);
|
|
102
139
|
const signal = () => inst.result;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { y as Computed } from "../infer-
|
|
1
|
+
import { y as Computed } from "../infer-DuFY-y2b.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/utilities/debounced.d.ts
|
|
4
4
|
/**
|
|
@@ -6,6 +6,17 @@ import { y as Computed } from "../infer-Dv5Wk-7E.mjs";
|
|
|
6
6
|
* milliseconds of silence (i.e. no new values from `getter`).
|
|
7
7
|
*
|
|
8
8
|
* The initial value is read synchronously, so the computed is never undefined.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { signal } from "elements-kit/signals";
|
|
13
|
+
* import { createDebounced } from "elements-kit/utilities/debounced";
|
|
14
|
+
*
|
|
15
|
+
* const query = signal("");
|
|
16
|
+
* const debounced = createDebounced(query, 300);
|
|
17
|
+
*
|
|
18
|
+
* effect(() => fetch(`/search?q=${debounced()}`));
|
|
19
|
+
* ```
|
|
9
20
|
*/
|
|
10
21
|
declare function createDebounced<T>(getter: () => T, delay: number | (() => number)): Computed<T>;
|
|
11
22
|
//#endregion
|
|
@@ -7,6 +7,17 @@ import { createTimeout } from "./timeout.mjs";
|
|
|
7
7
|
* milliseconds of silence (i.e. no new values from `getter`).
|
|
8
8
|
*
|
|
9
9
|
* The initial value is read synchronously, so the computed is never undefined.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { signal } from "elements-kit/signals";
|
|
14
|
+
* import { createDebounced } from "elements-kit/utilities/debounced";
|
|
15
|
+
*
|
|
16
|
+
* const query = signal("");
|
|
17
|
+
* const debounced = createDebounced(query, 300);
|
|
18
|
+
*
|
|
19
|
+
* effect(() => fetch(`/search?q=${debounced()}`));
|
|
20
|
+
* ```
|
|
10
21
|
*/
|
|
11
22
|
function createDebounced(getter, delay) {
|
|
12
23
|
const s = signal(getter());
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
//#region src/utilities/environment.d.ts
|
|
2
|
+
/** `true` when running in a browser (both `window` and `document` exist). */
|
|
2
3
|
declare const isBrowser: boolean;
|
|
4
|
+
/** A shared `Disposable` whose `Symbol.dispose` is a no-op — useful as a safe default. */
|
|
3
5
|
declare const noopDisposable: Disposable;
|
|
4
6
|
//#endregion
|
|
5
7
|
export { isBrowser, noopDisposable };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
//#region src/utilities/environment.ts
|
|
2
|
+
/** `true` when running in a browser (both `window` and `document` exist). */
|
|
2
3
|
const isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
|
|
4
|
+
/** A shared `Disposable` whose `Symbol.dispose` is a no-op — useful as a safe default. */
|
|
3
5
|
const noopDisposable = { [Symbol.dispose]() {} };
|
|
4
6
|
//#endregion
|
|
5
7
|
export { isBrowser, noopDisposable };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { y as Computed } from "../infer-
|
|
1
|
+
import { y as Computed } from "../infer-DuFY-y2b.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/utilities/event-listener.d.ts
|
|
4
4
|
/**
|
|
@@ -7,6 +7,17 @@ import { y as Computed } from "../infer-Dv5Wk-7E.mjs";
|
|
|
7
7
|
* When called inside an `effect` or `effectScope` the listener is removed
|
|
8
8
|
* when the scope is disposed. When the target is a reactive getter the
|
|
9
9
|
* listener is re-registered whenever the target changes.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { on } from "elements-kit/utilities/event-listener";
|
|
14
|
+
*
|
|
15
|
+
* // Static target — listener removed when the enclosing scope ends
|
|
16
|
+
* on(window, "resize", () => console.log(window.innerWidth));
|
|
17
|
+
*
|
|
18
|
+
* // Reactive target — listener follows the current element
|
|
19
|
+
* on(activeElement, "focus", () => console.log("focused"));
|
|
20
|
+
* ```
|
|
10
21
|
*/
|
|
11
22
|
declare function on<K extends keyof HTMLElementEventMap>(target: HTMLElement | Computed<HTMLElement | null>, type: K, handler: (e: HTMLElementEventMap[K]) => void, options?: AddEventListenerOptions): () => void;
|
|
12
23
|
declare function on<K extends keyof DocumentEventMap>(target: Document | Computed<Document | null>, type: K, handler: (e: DocumentEventMap[K]) => void, options?: AddEventListenerOptions): () => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { y as Computed } from "../infer-
|
|
1
|
+
import { y as Computed } from "../infer-DuFY-y2b.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/utilities/interval.d.ts
|
|
4
4
|
type IntervalResult = {
|
|
@@ -12,6 +12,19 @@ type Fn = () => void;
|
|
|
12
12
|
type Delay = number | (() => number);
|
|
13
13
|
/**
|
|
14
14
|
* Pausable `setInterval` wrapper. Starts running immediately on creation.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { createInterval } from "elements-kit/utilities/interval";
|
|
19
|
+
*
|
|
20
|
+
* // Reactive clock — updates a signal every second
|
|
21
|
+
* const { timestamp, stop } = createInterval(1000);
|
|
22
|
+
* effect(() => console.log(new Date(timestamp())));
|
|
23
|
+
*
|
|
24
|
+
* // With a callback
|
|
25
|
+
* const beat = createInterval(() => beatCount(beatCount() + 1), 500);
|
|
26
|
+
* beat.stop();
|
|
27
|
+
* ```
|
|
15
28
|
*/
|
|
16
29
|
declare function createInterval(delay: Delay): IntervalResult;
|
|
17
30
|
declare function createInterval(callback: Fn, delay: Delay): IntervalResult;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { y as Computed } from "../infer-
|
|
1
|
+
import { y as Computed } from "../infer-DuFY-y2b.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/utilities/previous.d.ts
|
|
4
4
|
/**
|
|
@@ -6,6 +6,18 @@ import { y as Computed } from "../infer-Dv5Wk-7E.mjs";
|
|
|
6
6
|
* Starts as `undefined` until the source changes for the first time.
|
|
7
7
|
*
|
|
8
8
|
* When `ignore` is provided, the previous value only updates when the ignore check fails.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { signal } from "elements-kit/signals";
|
|
13
|
+
* import { createPrevious } from "elements-kit/utilities/previous";
|
|
14
|
+
*
|
|
15
|
+
* const count = signal(0);
|
|
16
|
+
* const prev = createPrevious(count);
|
|
17
|
+
*
|
|
18
|
+
* count(1); prev(); // 0
|
|
19
|
+
* count(2); prev(); // 1
|
|
20
|
+
* ```
|
|
9
21
|
*/
|
|
10
22
|
declare function createPrevious<T>(source: Computed<T>, ignore?: (a: T, b: T) => boolean): Computed<T | undefined>;
|
|
11
23
|
//#endregion
|
|
@@ -6,6 +6,18 @@ import "../signals/index.mjs";
|
|
|
6
6
|
* Starts as `undefined` until the source changes for the first time.
|
|
7
7
|
*
|
|
8
8
|
* When `ignore` is provided, the previous value only updates when the ignore check fails.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { signal } from "elements-kit/signals";
|
|
13
|
+
* import { createPrevious } from "elements-kit/utilities/previous";
|
|
14
|
+
*
|
|
15
|
+
* const count = signal(0);
|
|
16
|
+
* const prev = createPrevious(count);
|
|
17
|
+
*
|
|
18
|
+
* count(1); prev(); // 0
|
|
19
|
+
* count(2); prev(); // 1
|
|
20
|
+
* ```
|
|
9
21
|
*/
|
|
10
22
|
function createPrevious(source, ignore) {
|
|
11
23
|
const prev = signal(void 0);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { y as Computed } from "../infer-
|
|
1
|
+
import { y as Computed } from "../infer-DuFY-y2b.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/utilities/promise.d.ts
|
|
4
4
|
/**
|
|
@@ -28,6 +28,12 @@ declare class ReactivePromise<T, E = unknown> extends Promise<T> {
|
|
|
28
28
|
constructor(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void);
|
|
29
29
|
static from<T, E = unknown>(p: Promise<T>): ReactivePromise<T, E>;
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* A {@link ReactivePromise} that is also callable as a `Computed<T | E | undefined>`.
|
|
33
|
+
*
|
|
34
|
+
* Invoking it (`p()`) reads the current `.result` — so it drops into any
|
|
35
|
+
* reactive context that expects a zero-arg getter.
|
|
36
|
+
*/
|
|
31
37
|
type ComputedPromise<T, E = unknown> = ReactivePromise<T, E> & Computed<T | E | undefined>;
|
|
32
38
|
type Executor<T, E = unknown> = (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: E) => void) => void;
|
|
33
39
|
/**
|