@vizejs/composable 0.345.0 → 0.347.7

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 (42) hide show
  1. package/dist/abort-signal.d.mts +96 -0
  2. package/dist/abort-signal.mjs +203 -0
  3. package/dist/async-resource.d.mts +97 -0
  4. package/dist/async-resource.mjs +99 -0
  5. package/dist/capability-BNpkvSy5.d.mts +93 -0
  6. package/dist/capability.d.mts +2 -0
  7. package/dist/capability.mjs +37 -0
  8. package/dist/catalog-CuWhR-0q.d.mts +506 -0
  9. package/dist/catalog-DOXTbk4r.mjs +529 -0
  10. package/dist/catalog.d.mts +2 -0
  11. package/dist/catalog.mjs +2 -0
  12. package/dist/disposal-scope.d.mts +93 -0
  13. package/dist/disposal-scope.mjs +119 -0
  14. package/dist/event-listener.d.mts +85 -0
  15. package/dist/event-listener.mjs +55 -0
  16. package/dist/index.d.mts +19 -786
  17. package/dist/index.mjs +19 -751
  18. package/dist/locale.d.mts +65 -0
  19. package/dist/locale.mjs +72 -0
  20. package/dist/media-query.d.mts +56 -0
  21. package/dist/media-query.mjs +56 -0
  22. package/dist/retry-async.d.mts +91 -0
  23. package/dist/retry-async.mjs +136 -0
  24. package/dist/retry-delay.d.mts +73 -0
  25. package/dist/retry-delay.mjs +50 -0
  26. package/dist/scope.d.mts +18 -0
  27. package/dist/scope.mjs +23 -0
  28. package/dist/timeout-scheduler.d.mts +18 -0
  29. package/dist/timeout-scheduler.mjs +1 -0
  30. package/dist/use-counter.d.mts +91 -0
  31. package/dist/use-counter.mjs +67 -0
  32. package/dist/use-debounced.d.mts +87 -0
  33. package/dist/use-debounced.mjs +98 -0
  34. package/dist/use-history.d.mts +105 -0
  35. package/dist/use-history.mjs +137 -0
  36. package/dist/use-previous.d.mts +43 -0
  37. package/dist/use-previous.mjs +11 -0
  38. package/dist/use-throttled.d.mts +107 -0
  39. package/dist/use-throttled.mjs +124 -0
  40. package/dist/use-toggle.d.mts +45 -0
  41. package/dist/use-toggle.mjs +34 -0
  42. package/package.json +91 -1
@@ -0,0 +1,119 @@
1
+ import { tryOnScopeDispose } from "./scope.mjs";
2
+ //#region src/disposal-scope.ts
3
+ /** Stable error code reported when one or more owned cleanups fail. */
4
+ const DISPOSAL_ERROR_CODE = "VIZE_COMPOSE_DISPOSAL_FAILED";
5
+ /** Aggregate failure produced after every owned cleanup has been attempted. */
6
+ var DisposalError = class extends AggregateError {
7
+ /** Stable machine-readable error code. */
8
+ code = DISPOSAL_ERROR_CODE;
9
+ /**
10
+ * Create an aggregate disposal failure.
11
+ *
12
+ * Nested {@link DisposalError} instances are flattened by the scope before
13
+ * construction, so `errors` contains the original cleanup failures in
14
+ * execution order.
15
+ *
16
+ * @param errors Cleanup failures in deterministic execution order.
17
+ */
18
+ constructor(errors) {
19
+ super(errors, `[${DISPOSAL_ERROR_CODE}] ${String(errors.length)} cleanup operation(s) failed.`);
20
+ this.name = "DisposalError";
21
+ }
22
+ };
23
+ /**
24
+ * Create an explicit, deterministic cleanup owner.
25
+ *
26
+ * The owner is runtime-neutral and performs no browser-global access. By
27
+ * default it joins an active Vue reactive scope; when no scope exists, or
28
+ * `scope` is disabled, the caller must invoke `dispose()`. Cleanups are
29
+ * synchronous by contract so disposal completes before the owner releases
30
+ * its records.
31
+ *
32
+ * @param options Reactive-scope ownership behavior.
33
+ * @default options {}
34
+ * @returns A disposal owner with child-lifetime support.
35
+ */
36
+ function createDisposalScope(options = {}) {
37
+ const owner = createOwner();
38
+ if (options.scope ?? true) tryOnScopeDispose(owner.dispose);
39
+ return owner;
40
+ }
41
+ function createOwner(onDispose) {
42
+ const records = [];
43
+ let disposed = false;
44
+ let size = 0;
45
+ const add = (cleanup) => {
46
+ if (disposed) {
47
+ try {
48
+ cleanup();
49
+ } catch (error) {
50
+ throw new DisposalError(flattenDisposalError(error));
51
+ }
52
+ return inactiveRegistration();
53
+ }
54
+ const record = {
55
+ active: true,
56
+ cleanup
57
+ };
58
+ records.push(record);
59
+ size += 1;
60
+ return {
61
+ get active() {
62
+ return record.active;
63
+ },
64
+ unregister() {
65
+ if (!record.active) return false;
66
+ record.active = false;
67
+ size -= 1;
68
+ return true;
69
+ }
70
+ };
71
+ };
72
+ const dispose = () => {
73
+ if (disposed) return;
74
+ disposed = true;
75
+ onDispose?.();
76
+ const errors = [];
77
+ for (let index = records.length - 1; index >= 0; index -= 1) {
78
+ const record = records[index];
79
+ if (!record?.active) continue;
80
+ record.active = false;
81
+ size -= 1;
82
+ try {
83
+ record.cleanup();
84
+ } catch (error) {
85
+ errors.push(...flattenDisposalError(error));
86
+ }
87
+ }
88
+ records.length = 0;
89
+ if (errors.length > 0) throw new DisposalError(errors);
90
+ };
91
+ const child = () => {
92
+ let parentRegistration;
93
+ const childOwner = createOwner(() => parentRegistration?.unregister());
94
+ parentRegistration = add(childOwner.dispose);
95
+ return childOwner;
96
+ };
97
+ return {
98
+ get disposed() {
99
+ return disposed;
100
+ },
101
+ get size() {
102
+ return size;
103
+ },
104
+ add,
105
+ child,
106
+ dispose
107
+ };
108
+ }
109
+ function inactiveRegistration() {
110
+ return {
111
+ active: false,
112
+ unregister: () => false
113
+ };
114
+ }
115
+ function flattenDisposalError(error) {
116
+ return error instanceof DisposalError ? error.errors : [error];
117
+ }
118
+ //#endregion
119
+ export { DISPOSAL_ERROR_CODE, DisposalError, createDisposalScope };
@@ -0,0 +1,85 @@
1
+ import { MaybeRefOrGetter, Ref } from "vue";
2
+
3
+ //#region src/event-listener.d.ts
4
+ /** Options for {@link useEventListener}. */
5
+ interface UseEventListenerOptions {
6
+ /**
7
+ * Invoke the listener during the capture phase.
8
+ *
9
+ * @default false
10
+ */
11
+ readonly capture?: boolean;
12
+ /**
13
+ * Stop listening after the first event.
14
+ *
15
+ * @default false
16
+ */
17
+ readonly once?: boolean;
18
+ /**
19
+ * Declare that the listener does not cancel the event's default action.
20
+ *
21
+ * @default false
22
+ */
23
+ readonly passive?: boolean;
24
+ /**
25
+ * Stop listening when this signal is aborted. An already-aborted signal
26
+ * prevents listening from ever starting.
27
+ *
28
+ * @default undefined
29
+ */
30
+ readonly signal?: AbortSignal;
31
+ /**
32
+ * Start listening during composable creation.
33
+ *
34
+ * @default true
35
+ */
36
+ readonly immediate?: boolean;
37
+ /**
38
+ * Reactive target update timing.
39
+ *
40
+ * @default "pre"
41
+ */
42
+ readonly flush?: "pre" | "post" | "sync";
43
+ }
44
+ /** Reactive controls returned by {@link useEventListener}. */
45
+ interface EventListenerControls {
46
+ /** Whether a concrete target currently owns the listener. */
47
+ readonly isListening: Readonly<Ref<boolean>>;
48
+ /**
49
+ * Begin listening.
50
+ *
51
+ * @returns Whether a new reactive watcher was started. `false` while the
52
+ * watcher is already active (including a null-target watcher with no
53
+ * listener attached), after the abort signal has fired, and after the
54
+ * owning reactive scope has been disposed.
55
+ */
56
+ readonly start: () => boolean;
57
+ /** Stop listening. Repeated calls are safe. */
58
+ readonly stop: () => void;
59
+ }
60
+ /**
61
+ * Attach an event listener to a reactive target and clean it up with the
62
+ * current reactive scope. Missing targets are valid during server rendering:
63
+ * a `null`/`undefined` target keeps the listener detached until a concrete
64
+ * target appears, so no browser globals are required.
65
+ *
66
+ * The listener is re-attached whenever the reactive target changes and is
67
+ * removed when the owning reactive scope stops, when
68
+ * {@link EventListenerControls.stop} is called, or when the abort signal
69
+ * fires. Outside an active scope, teardown ownership stays with the caller,
70
+ * who must call `stop` explicitly. Errors thrown by a custom target's
71
+ * add/remove methods propagate to the active watcher run.
72
+ *
73
+ * @param target Reactive event target.
74
+ * @param event Event name.
75
+ * @param listener Typed event listener.
76
+ * @param options Listener lifecycle and scheduling options.
77
+ * @default options {}
78
+ * @returns Controls to observe and change the listening state.
79
+ */
80
+ declare function useEventListener<Key extends keyof WindowEventMap>(target: MaybeRefOrGetter<Window | null | undefined>, event: Key, listener: (event: WindowEventMap[Key]) => void, options?: UseEventListenerOptions): EventListenerControls;
81
+ declare function useEventListener<Key extends keyof DocumentEventMap>(target: MaybeRefOrGetter<Document | null | undefined>, event: Key, listener: (event: DocumentEventMap[Key]) => void, options?: UseEventListenerOptions): EventListenerControls;
82
+ declare function useEventListener<Key extends keyof HTMLElementEventMap>(target: MaybeRefOrGetter<HTMLElement | null | undefined>, event: Key, listener: (event: HTMLElementEventMap[Key]) => void, options?: UseEventListenerOptions): EventListenerControls;
83
+ declare function useEventListener(target: MaybeRefOrGetter<EventTarget | null | undefined>, event: string, listener: EventListener, options?: UseEventListenerOptions): EventListenerControls;
84
+ //#endregion
85
+ export { EventListenerControls, UseEventListenerOptions, useEventListener };
@@ -0,0 +1,55 @@
1
+ import { tryOnScopeDispose } from "./scope.mjs";
2
+ import { readonly, ref, toValue, watch } from "vue";
3
+ //#region src/event-listener.ts
4
+ function useEventListener(target, event, listener, options = {}) {
5
+ const { capture = false, once = false, passive = false, signal, immediate = true, flush = "pre" } = options;
6
+ const isListening = ref(false);
7
+ const eventOptions = {
8
+ capture,
9
+ passive,
10
+ ...signal ? { signal } : {}
11
+ };
12
+ let disposed = false;
13
+ let stopWatch;
14
+ const stop = () => {
15
+ stopWatch?.stop();
16
+ stopWatch = void 0;
17
+ isListening.value = false;
18
+ };
19
+ const start = () => {
20
+ if (disposed || stopWatch || signal?.aborted) return false;
21
+ stopWatch = watch(() => toValue(target), (next, _previous, onCleanup) => {
22
+ isListening.value = false;
23
+ if (!next || signal?.aborted) return;
24
+ const invoke = (nativeEvent) => {
25
+ if (once) stop();
26
+ listener(nativeEvent);
27
+ };
28
+ const onAbort = () => stop();
29
+ next.addEventListener(event, invoke, eventOptions);
30
+ signal?.addEventListener("abort", onAbort, { once: true });
31
+ isListening.value = true;
32
+ onCleanup(() => {
33
+ next.removeEventListener(event, invoke, capture);
34
+ signal?.removeEventListener("abort", onAbort);
35
+ isListening.value = false;
36
+ });
37
+ }, {
38
+ flush,
39
+ immediate: true
40
+ });
41
+ return true;
42
+ };
43
+ tryOnScopeDispose(() => {
44
+ disposed = true;
45
+ stop();
46
+ });
47
+ if (immediate) start();
48
+ return {
49
+ isListening: readonly(isListening),
50
+ start,
51
+ stop
52
+ };
53
+ }
54
+ //#endregion
55
+ export { useEventListener };