@but212/atom-effect-jquery 0.30.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -5,12 +5,28 @@ import { ReadonlyAtom } from '@but212/atom-effect';
5
5
  import { WritableAtom } from '@but212/atom-effect';
6
6
 
7
7
  /**
8
- * An extension of ReactiveValue that also supports Promises and async functions.
9
- * The binding system automatically handles the promise lifecycle, showing the
10
- * latest resolved value and ignoring stale ones (race condition protection).
8
+ * Extension of ReactiveValue that permits Promises.
9
+ * Used primarily for CSS and Attribute bindings that might rely on async fetching.
11
10
  */
12
11
  declare type AsyncReactiveValue<T> = T | ReadonlyAtom<T | Promise<T>> | Promise<T> | (() => T | Promise<T>);
13
12
 
13
+ export declare interface AtomNavOptions {
14
+ target: string | JQuery<HTMLElement> | HTMLElement;
15
+ selector?: string;
16
+ headers?: Record<string, string>;
17
+ onBeforeLoad?: (url: string) => boolean | undefined | Promise<boolean | undefined>;
18
+ onMount?: ($container: JQuery, url: string) => void;
19
+ onUnmount?: ($container: JQuery, oldUrl: string) => void;
20
+ onError?: (err: unknown, url: string) => boolean | undefined;
21
+ scrollToTop?: boolean;
22
+ syncTitle?: boolean;
23
+ window?: Window & typeof globalThis;
24
+ }
25
+
26
+ /**
27
+ * Central DSL for declarative jQuery bindings.
28
+ * Maps reactive sources to specific DOM manipulation strategies.
29
+ */
14
30
  export declare interface BindingOptions<T = unknown> {
15
31
  text?: AsyncReactiveValue<unknown> | [source: AsyncReactiveValue<unknown>, formatter: (v: unknown) => string];
16
32
  html?: AsyncReactiveValue<string>;
@@ -30,51 +46,49 @@ export declare interface BindingOptions<T = unknown> {
30
46
  }
31
47
 
32
48
  /**
33
- * Central registry mapping DOM elements to their reactive binding records.
49
+ * Manages the lifecycle of reactive bindings and component effects.
34
50
  *
35
- * Design goals:
36
- * - Zero memory leaks: all collections use WeakMap/WeakSet keyed by Element.
37
- * - Minimal allocations in the hot tracking path.
38
- * - O(bound-descendants) cleanup via a single querySelectorAll pass.
51
+ * Safety Rationale:
52
+ * - Uses WeakMap for records to avoid holding strong references that prevent GC.
53
+ * - Uses WeakSet for node flags (kept/ignored) to ensure the registry doesn't leak
54
+ * memory even for nodes that were "lost" without a cleanup call.
39
55
  */
40
56
  declare class BindingRegistry {
41
57
  private records;
42
58
  private preservedNodes;
43
59
  private ignoredNodes;
60
+ /** Mark a node to preserve its effects even if detached from the DOM (e.g., jQuery .detach()). */
44
61
  keep(node: Node): void;
45
62
  isKept(node: Node): boolean;
63
+ /** Temporary flag to block redundant cleanup cycles for the same node. */
46
64
  markIgnored(node: Node): void;
47
65
  isIgnored(node: Node): boolean;
48
66
  private getOrCreateRecord;
67
+ private addCleanup;
68
+ /** Registers a reactive effect instance to be disposed when the element is removed. */
69
+ trackEffect(element: Element, reactiveEffect: EffectObject): void;
70
+ /** Registers a generic cleanup closure to be executed when the element is removed. */
71
+ trackCleanup(element: Element, cleanupFunction: () => void): void;
72
+ /** Sets the optional teardown function returned by a mounted component. */
73
+ setComponentCleanup(element: Element, teardownFunction: (() => void) | undefined): void;
74
+ hasBind(element: Element): boolean;
49
75
  /**
50
- * Registers a reactive effect with an element's record.
51
- * Effects are automatically disposed when the element is removed from the DOM.
52
- *
53
- * @param el - The DOM element to bind the effect to.
54
- * @param fx - The reactive effect instance.
55
- */
56
- trackEffect(el: Element, fx: EffectObject): void;
57
- /**
58
- * Registers an arbitrary cleanup function with an element's record.
59
- * Cleanups are executed when the element is removed from the DOM.
60
- *
61
- * @param el - The DOM element to bind the cleanup to.
62
- * @param fn - The cleanup function (e.g., event unbinding, timer clear).
63
- */
64
- trackCleanup(el: Element, fn: () => void): void;
65
- /**
66
- * Assigns a component-level cleanup function (e.g., from atomMount).
67
- * Unlike generic cleanups, there can only be one component cleanup per element.
76
+ * Performs the actual destruction of all resources bound to the node.
77
+ * This clears the record, removes the tracking CSS class, and executes all callbacks.
68
78
  */
69
- setComponentCleanup(el: Element, fn: (() => void) | undefined): void;
70
- hasBind(el: Element): boolean;
71
- cleanup(el: Node): void;
72
- cleanupDescendants(el: Element | DocumentFragment | ShadowRoot): void;
73
- cleanupTree(el: Node): void;
79
+ cleanup(node: Node): void;
80
+ cleanupDescendants(root: Element | DocumentFragment | ShadowRoot): void;
81
+ /** Destroys the reactive state of the element and its entire sub-tree. */
82
+ cleanupTree(node: Node): void;
74
83
  }
75
84
 
85
+ /** Definition for a mountable component that manages its own lifecycle. */
76
86
  export declare type ComponentFn<P = Record<string, unknown>> = ($el: JQuery, props: P) => EffectResult;
77
87
 
88
+ declare interface ComponentLifecycle {
89
+ unmount: EffectCleanup;
90
+ }
91
+
78
92
  export { ComputedAtom }
79
93
 
80
94
  export declare type CssBindings = Record<string, CssValue>;
@@ -83,47 +97,46 @@ export declare type CssValue = AsyncReactiveValue<string | number> | [source: As
83
97
 
84
98
  export default default_2;
85
99
 
86
- /**
87
- * Stops all MutationObservers started by `enableAutoCleanup`.
88
- */
89
100
  export declare function disableAutoCleanup(): void;
90
101
 
91
- /**
92
- * Restores all jQuery methods patched by `enablejQueryOverrides()`.
93
- * Primarily useful in test environments to reset state between suites.
94
- */
102
+ /** Restores original jQuery prototype methods to their clean state. */
95
103
  export declare function disablejQueryOverrides(): void;
96
104
 
97
105
  export declare type EffectCleanup = () => void;
98
106
 
99
- export declare type EffectResult = undefined | EffectCleanup;
107
+ export declare type EffectResult = undefined | EffectCleanup | ComponentLifecycle;
100
108
 
101
109
  /**
102
- * Starts observing `root` for removed elements and automatically disposes
103
- * their reactive bindings when they leave the DOM.
104
- *
105
- * Supports Element, ShadowRoot, and DocumentFragment roots.
106
- * Multiple roots can be observed concurrently (e.g. for Micro-Frontends).
110
+ * Requirement: Native browser operations (like el.innerHTML = '') bypass jQuery hooks.
111
+ * This observer serves as a safety net, detecting removed nodes that missed the
112
+ * patched jQuery .remove() or .empty() calls.
107
113
  */
108
114
  export declare function enableAutoCleanup(root: Element | ShadowRoot | DocumentFragment): void;
109
115
 
116
+ /**
117
+ * Globally overrides specific jQuery prototype methods to automate library behavior.
118
+ *
119
+ * Responsibilities:
120
+ * 1. Auto-Batching: Wraps all event handlers in 'batch()' to prevent UI jitter.
121
+ * 2. Lifecycle Sync: Hooking .remove()/.empty() to stop reactive effects on deleted elements.
122
+ * 3. Persistence: Hooking .detach() to preserve effects when nodes are moved temporarily.
123
+ * 4. Identity Management: Uses a WeakMap so .off(originalFn) still works correctly.
124
+ */
110
125
  export declare function enablejQueryOverrides(): void;
111
126
 
112
127
  export declare type EqualFn<T> = (a: T, b: T) => boolean;
113
128
 
114
129
  export declare interface FetchOptions<T> {
115
130
  defaultValue: T;
131
+ name?: string;
116
132
  method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | (string & {});
117
133
  headers?: Record<string, string>;
118
- transform?: (raw: unknown) => T;
134
+ transform?: (raw: unknown, xhr: JQuery.jqXHR) => T;
119
135
  ajaxOptions?: JQuery.AjaxSettings | (() => JQuery.AjaxSettings);
120
136
  onError?: (err: unknown) => void;
121
137
  eager?: boolean;
122
138
  }
123
139
 
124
- /**
125
- * Options for `atomForm` binding.
126
- */
127
140
  declare interface FormOptions<T> extends ValOptions<T> {
128
141
  /** Custom function to transform field value based on path before atomic sync. */
129
142
  transform?: (path: string, value: unknown) => unknown;
@@ -131,19 +144,16 @@ declare interface FormOptions<T> extends ValOptions<T> {
131
144
  onChange?: (path: string, value: unknown) => void;
132
145
  }
133
146
 
134
- /** Checks if a given value is a reactive node (Atom or Computed). */
135
- export declare const isReactive: (v: unknown) => v is ReadonlyAtom<unknown>;
136
-
137
- declare type KeysOfType<T, V> = {
138
- [K in keyof T]: T[K] extends V ? K : never;
139
- }[keyof T];
140
-
141
147
  declare type ListKey = string | number;
142
148
 
143
149
  declare type ListKeyFn<T> = (item: T, index: number) => ListKey;
144
150
 
151
+ /**
152
+ * Configuration for high-performance list reconciliation.
153
+ * Uses 'key' for identity tracking to minimize DOM churn.
154
+ */
145
155
  export declare interface ListOptions<T> {
146
- key: KeysOfType<T, ListKey> | ListKeyFn<T>;
156
+ key: keyof T | ListKeyFn<T>;
147
157
  render: (item: T, index: number) => ListRenderResult;
148
158
  bind?: ($el: JQuery, item: T, index: number) => void;
149
159
  update?: ($el: JQuery, item: T, index: number) => void;
@@ -156,16 +166,17 @@ export declare interface ListOptions<T> {
156
166
 
157
167
  declare type ListRenderResult = string | Element | DocumentFragment | JQuery;
158
168
 
159
- /** Resolves after microtask effects flush. Fast Promise-based scheduling. */
169
+ /**
170
+ * Returns a promise that resolves after the next reactive tick.
171
+ * Useful for waiting until all pending effects have updated the DOM.
172
+ */
160
173
  export declare const nextTick: () => Promise<void>;
161
174
 
162
175
  export declare type PrimitiveValue = string | number | boolean | null | undefined;
163
176
 
164
177
  /**
165
- * Represents a value that can be tracked by the reactive system.
166
- * - T: Static value (one-time bind)
167
- * - ReadonlyAtom<T>: Reactive value (updates DOM when atom changes)
168
- * - () => T: Reactive function (updates DOM when any atom read inside changes)
178
+ * Flexible value container.
179
+ * Supports raw T, reactive Atoms, or functional getters for deferred execution.
169
180
  */
170
181
  export declare type ReactiveValue<T> = T | ReadonlyAtom<T> | (() => T);
171
182
 
@@ -173,15 +184,10 @@ export { ReadonlyAtom }
173
184
 
174
185
  export declare const registry: BindingRegistry;
175
186
 
176
- export declare interface RenderRoute extends RouteLifecycle {
177
- render: (container: HTMLElement, route: string, params: Record<string, string>, onUnmount: (cleanupFn: () => void) => void, router: Router) => void;
178
- template?: never;
179
- }
180
-
181
187
  export declare interface RouteConfig {
182
- target: string;
183
- default: string;
184
- routes: Record<string, RouteDefinition>;
188
+ target: string | JQuery<HTMLElement> | HTMLElement;
189
+ default?: string;
190
+ routes?: Record<string, RouteDefinition>;
185
191
  mode?: 'hash' | 'history';
186
192
  basePath?: string;
187
193
  notFound?: string;
@@ -191,39 +197,31 @@ export declare interface RouteConfig {
191
197
  afterTransition?: (from: string, to: string) => void;
192
198
  }
193
199
 
194
- export declare type RouteDefinition = TemplateRoute | RenderRoute;
200
+ export declare interface RouteDefinition extends RouteLifecycle {
201
+ template?: string;
202
+ render?: (container: HTMLElement, route: string, params: Record<string, string>, onUnmount: (cleanupFn: () => void) => void, router: Router) => void;
203
+ onMount?: ($content: JQuery, onUnmount: (cleanupFn: () => void) => void, router: Router) => void;
204
+ }
195
205
 
196
206
  export declare interface RouteLifecycle {
197
- onEnter?: (params: Record<string, string>, router: Router) => Record<string, string> | undefined;
207
+ onEnter?: (params: Record<string, string>, router: Router) => Record<string, string> | undefined | false;
198
208
  onLeave?: (router: Router) => boolean | undefined;
209
+ title?: string;
199
210
  }
200
211
 
201
212
  export declare interface Router {
202
213
  currentRoute: ReadonlyAtom<string>;
203
214
  queryParams: ReadonlyAtom<Record<string, string>>;
215
+ params: ReadonlyAtom<Record<string, string>>;
204
216
  navigate: (route: string) => void;
205
217
  destroy: () => void;
206
218
  }
207
219
 
208
- export declare interface TemplateRoute extends RouteLifecycle {
209
- template: string;
210
- render?: never;
211
- onMount?: ($content: JQuery, onUnmount: (cleanupFn: () => void) => void, router: Router) => void;
212
- }
213
-
214
- /**
215
- * Options for `atomVal`, `atomChecked`, and `atomForm` bindings.
216
- */
217
220
  export declare interface ValOptions<T> {
218
- /** Debounce duration in milliseconds for DOM -> Atom sync. Defaults to 0. */
219
221
  debounce?: number;
220
- /** jQuery event name(s) to listen to. Defaults to "input". */
221
222
  event?: string;
222
- /** Custom function to parse DOM string to atom type T. */
223
223
  parse?: (v: string) => T;
224
- /** Custom function to format atom type T to DOM string. */
225
224
  format?: (v: T) => string;
226
- /** Custom equality check to prevent redundant atom updates. */
227
225
  equal?: EqualFn<T>;
228
226
  }
229
227