mobx-mantle 0.3.7 → 0.6.1
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 +898 -120
- package/dist/behaviors/index.cjs +419 -0
- package/dist/behaviors/index.cjs.map +1 -0
- package/dist/behaviors/index.d.cts +275 -0
- package/dist/behaviors/index.d.ts +275 -0
- package/dist/behaviors/index.js +419 -0
- package/dist/behaviors/index.js.map +1 -0
- package/dist/chunk-LP5TAGSI.js +9 -0
- package/dist/chunk-LP5TAGSI.js.map +1 -0
- package/dist/chunk-WNF647U6.cjs +9 -0
- package/dist/chunk-WNF647U6.cjs.map +1 -0
- package/dist/index.cjs +1172 -258
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +431 -83
- package/dist/index.d.ts +431 -83
- package/dist/index.js +1159 -200
- package/dist/index.js.map +1 -1
- package/dist/reactive-args-BBucrU54.d.cts +32 -0
- package/dist/reactive-args-BBucrU54.d.ts +32 -0
- package/dist/testing/index.cjs +33 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.cts +18 -0
- package/dist/testing/index.d.ts +18 -0
- package/dist/testing/index.js +33 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +42 -8
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { Behavior, MaybeGetter } from 'mobx-mantle';
|
|
2
|
+
export { M as MaybeGetter, t as toValue } from '../reactive-args-BBucrU54.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Standard library of built-in behaviors. Every argument documented as
|
|
6
|
+
* MaybeGetter accepts either a plain value (frozen at construction) or a
|
|
7
|
+
* getter (a live connection — re-resolved whenever its observable sources
|
|
8
|
+
* change):
|
|
9
|
+
*
|
|
10
|
+
* ```tsx
|
|
11
|
+
* media = withMediaQuery('(max-width: 768px)'); // static
|
|
12
|
+
* media = withMediaQuery(() => this.props.breakpoint); // live
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* Author-side conventions on display throughout this file:
|
|
16
|
+
* - `this.sync(arg)` — normalize a MaybeGetter into an ordinary field that
|
|
17
|
+
* stays current (see withFetch, withAutosave)
|
|
18
|
+
* - `this.watch(arg, cb)` — a MaybeGetter is a valid watch source directly
|
|
19
|
+
* (see withDebounce, withThrottle)
|
|
20
|
+
* - `toValue(arg)` — one-off reads inside effect bodies, where the getter
|
|
21
|
+
* call doubles as dependency tracking (see withEventListener, withInterval)
|
|
22
|
+
*
|
|
23
|
+
* Several of these behaviors are themselves compositions of the others
|
|
24
|
+
* (withFetch = withAsync + watch, withWindowSize = withEventListener + state,
|
|
25
|
+
* withAutosave = withInterval + withAsync) — the same nesting available to
|
|
26
|
+
* user-defined behaviors.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
declare class EventListenerBehavior extends Behavior {
|
|
30
|
+
onCreate(target: MaybeGetter<EventTarget | null | undefined>, type: MaybeGetter<string>, handler: (event: Event) => void, options?: AddEventListenerOptions): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Attach an event listener for the mounted lifetime of the host. Re-attaches
|
|
34
|
+
* when a getter target or type changes.
|
|
35
|
+
*
|
|
36
|
+
* @example keys = withEventListener(window, 'keydown', (e) => this.handleKey(e));
|
|
37
|
+
*/
|
|
38
|
+
declare const withEventListener: {
|
|
39
|
+
(target: MaybeGetter<EventTarget | null | undefined>, type: MaybeGetter<string>, handler: (event: Event) => void, options?: AddEventListenerOptions | undefined): EventListenerBehavior;
|
|
40
|
+
new (target: MaybeGetter<EventTarget | null | undefined>, type: MaybeGetter<string>, handler: (event: Event) => void, options?: AddEventListenerOptions | undefined): EventListenerBehavior;
|
|
41
|
+
};
|
|
42
|
+
declare class IntervalBehavior extends Behavior {
|
|
43
|
+
onCreate(callback: () => void, delay?: MaybeGetter<number | null>): void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Run a callback on an interval for the mounted lifetime of the host.
|
|
47
|
+
* A getter delay reschedules on change; resolving to null pauses.
|
|
48
|
+
*
|
|
49
|
+
* @example poll = withInterval(() => this.refresh(), 10_000);
|
|
50
|
+
*/
|
|
51
|
+
declare const withInterval: {
|
|
52
|
+
(callback: () => void, delay?: MaybeGetter<number | null> | undefined): IntervalBehavior;
|
|
53
|
+
new (callback: () => void, delay?: MaybeGetter<number | null> | undefined): IntervalBehavior;
|
|
54
|
+
};
|
|
55
|
+
declare class TimeoutBehavior extends Behavior {
|
|
56
|
+
/** True while the timeout is scheduled and hasn't fired */
|
|
57
|
+
pending: boolean;
|
|
58
|
+
onCreate(callback: () => void, delay: MaybeGetter<number | null>): void;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Run a callback once after a delay (measured from mount). A getter delay
|
|
62
|
+
* reschedules on change; resolving to null cancels.
|
|
63
|
+
*
|
|
64
|
+
* @example toast = withTimeout(() => (this.visible = false), 3000);
|
|
65
|
+
*/
|
|
66
|
+
declare const withTimeout: {
|
|
67
|
+
(callback: () => void, delay: MaybeGetter<number | null>): TimeoutBehavior;
|
|
68
|
+
new (callback: () => void, delay: MaybeGetter<number | null>): TimeoutBehavior;
|
|
69
|
+
};
|
|
70
|
+
declare class AsyncBehavior<T = unknown> extends Behavior {
|
|
71
|
+
value: T | undefined;
|
|
72
|
+
error: unknown;
|
|
73
|
+
loading: boolean;
|
|
74
|
+
private _fn;
|
|
75
|
+
private _runId;
|
|
76
|
+
onCreate(fn: (...args: any[]) => Promise<T>): void;
|
|
77
|
+
/**
|
|
78
|
+
* Run the async function. Out-of-order completions are discarded: only the
|
|
79
|
+
* most recent run may write value/error/loading.
|
|
80
|
+
*/
|
|
81
|
+
run(...args: any[]): Promise<T | undefined>;
|
|
82
|
+
/** Discard any in-flight run's result */
|
|
83
|
+
cancel(): void;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Track an async function's latest run as observable value/error/loading state.
|
|
87
|
+
*
|
|
88
|
+
* @example search = withAsync((q: string) => api.search(q)); // later: this.search.run(this.query)
|
|
89
|
+
*/
|
|
90
|
+
declare const withAsync: {
|
|
91
|
+
<T>(fn: (...args: any[]) => Promise<T>): AsyncBehavior<T>;
|
|
92
|
+
new <T>(fn: (...args: any[]) => Promise<T>): AsyncBehavior<T>;
|
|
93
|
+
};
|
|
94
|
+
declare class FetchBehavior<T = unknown> extends Behavior {
|
|
95
|
+
/** Current URL — a one-way mirror of the url argument (this.sync) */
|
|
96
|
+
url: string | null | undefined;
|
|
97
|
+
/** The request state machine is a nested withAsync behavior */
|
|
98
|
+
request: AsyncBehavior<T>;
|
|
99
|
+
private _init?;
|
|
100
|
+
onCreate(url: MaybeGetter<string | null | undefined>, init?: RequestInit): void;
|
|
101
|
+
get data(): T | undefined;
|
|
102
|
+
get loading(): boolean;
|
|
103
|
+
get error(): unknown;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Fetch JSON from a URL. A getter URL refetches on change (the first fetch
|
|
107
|
+
* fires at mount); a URL resolving to null/undefined skips fetching.
|
|
108
|
+
* Out-of-order responses are discarded by the underlying withAsync.
|
|
109
|
+
*
|
|
110
|
+
* @example user = withFetch<User>(() => `/api/users/${this.props.userId}`);
|
|
111
|
+
*/
|
|
112
|
+
declare const withFetch: {
|
|
113
|
+
<T = unknown>(url: MaybeGetter<string | null | undefined>, init?: RequestInit): FetchBehavior<T>;
|
|
114
|
+
new <T = unknown>(url: MaybeGetter<string | null | undefined>, init?: RequestInit): FetchBehavior<T>;
|
|
115
|
+
};
|
|
116
|
+
declare class LocalStorageBehavior<T = unknown> extends Behavior {
|
|
117
|
+
value: T;
|
|
118
|
+
/** Cross-tab sync rides on a nested withEventListener */
|
|
119
|
+
storageSync: EventListenerBehavior;
|
|
120
|
+
onCreate(key: string, initialValue: T): void;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* An observable value persisted to localStorage under `key`, hydrated from
|
|
124
|
+
* storage at construction and kept in sync across tabs. Values must be
|
|
125
|
+
* JSON-serializable.
|
|
126
|
+
*
|
|
127
|
+
* @example theme = withLocalStorage('theme', 'dark'); // read/write this.theme.value
|
|
128
|
+
*/
|
|
129
|
+
declare const withLocalStorage: {
|
|
130
|
+
<T>(key: string, initialValue: T): LocalStorageBehavior<T>;
|
|
131
|
+
new <T>(key: string, initialValue: T): LocalStorageBehavior<T>;
|
|
132
|
+
};
|
|
133
|
+
interface ElementSizeRef {
|
|
134
|
+
readonly current: Element | null;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Observe one ref's border-box dimensions for the mounted lifetime of its
|
|
138
|
+
* host. Setup and teardown both live in onLayoutMount so React StrictMode's
|
|
139
|
+
* effect replay always reacquires the observer against the retained DOM node.
|
|
140
|
+
*/
|
|
141
|
+
declare class ElementSizeBehavior extends Behavior {
|
|
142
|
+
width: number | null;
|
|
143
|
+
height: number | null;
|
|
144
|
+
private target;
|
|
145
|
+
onCreate(target: ElementSizeRef): void;
|
|
146
|
+
measure(entry?: ResizeObserverEntry): void;
|
|
147
|
+
onLayoutMount(): (() => void) | undefined;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Reactive layout-space border-box width and height for an element ref.
|
|
151
|
+
* CSS transforms on the element or its ancestors do not affect the reported
|
|
152
|
+
* size, so responsive components behave consistently inside scaled containers.
|
|
153
|
+
* Values are null before layout mount, while no element is attached, and
|
|
154
|
+
* after cleanup.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* root = this.ref<HTMLDivElement>();
|
|
158
|
+
* size = withElementSize(this.root);
|
|
159
|
+
*/
|
|
160
|
+
declare const withElementSize: {
|
|
161
|
+
(target: ElementSizeRef): ElementSizeBehavior;
|
|
162
|
+
new (target: ElementSizeRef): ElementSizeBehavior;
|
|
163
|
+
};
|
|
164
|
+
declare class WindowSizeBehavior extends Behavior {
|
|
165
|
+
width: number;
|
|
166
|
+
height: number;
|
|
167
|
+
resize: EventListenerBehavior;
|
|
168
|
+
measure(): void;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Observable window inner width/height (0×0 during SSR).
|
|
172
|
+
*
|
|
173
|
+
* @example size = withWindowSize(); // this.size.width × this.size.height
|
|
174
|
+
*/
|
|
175
|
+
declare const withWindowSize: {
|
|
176
|
+
(): WindowSizeBehavior;
|
|
177
|
+
new (): WindowSizeBehavior;
|
|
178
|
+
};
|
|
179
|
+
declare class MediaQueryBehavior extends Behavior {
|
|
180
|
+
matches: boolean;
|
|
181
|
+
onCreate(query: MaybeGetter<string>): void;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Observable match state for a media query (false during SSR).
|
|
185
|
+
*
|
|
186
|
+
* @example isMobile = withMediaQuery('(max-width: 768px)'); // this.isMobile.matches
|
|
187
|
+
*/
|
|
188
|
+
declare const withMediaQuery: {
|
|
189
|
+
(query: MaybeGetter<string>): MediaQueryBehavior;
|
|
190
|
+
new (query: MaybeGetter<string>): MediaQueryBehavior;
|
|
191
|
+
};
|
|
192
|
+
declare class DebounceBehavior<T = unknown> extends Behavior {
|
|
193
|
+
value: T;
|
|
194
|
+
private _timer;
|
|
195
|
+
onCreate(source: MaybeGetter<T>, delay?: number): void;
|
|
196
|
+
onUnmount(): void;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* A debounced mirror of a reactive source: updates settle after `delay` ms of quiet.
|
|
200
|
+
*
|
|
201
|
+
* @example debouncedQuery = withDebounce(() => this.query, 300);
|
|
202
|
+
*/
|
|
203
|
+
declare const withDebounce: {
|
|
204
|
+
<T>(source: MaybeGetter<T>, delay?: number): DebounceBehavior<T>;
|
|
205
|
+
new <T>(source: MaybeGetter<T>, delay?: number): DebounceBehavior<T>;
|
|
206
|
+
};
|
|
207
|
+
declare class ThrottleBehavior<T = unknown> extends Behavior {
|
|
208
|
+
value: T;
|
|
209
|
+
private _timer;
|
|
210
|
+
private _lastEmit;
|
|
211
|
+
onCreate(source: MaybeGetter<T>, delay?: number): void;
|
|
212
|
+
onUnmount(): void;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* A throttled mirror of a reactive source: at most one update per `delay` ms, trailing edge included.
|
|
216
|
+
*
|
|
217
|
+
* @example scrollY = withThrottle(() => this.rawScrollY, 100);
|
|
218
|
+
*/
|
|
219
|
+
declare const withThrottle: {
|
|
220
|
+
<T>(source: MaybeGetter<T>, delay?: number): ThrottleBehavior<T>;
|
|
221
|
+
new <T>(source: MaybeGetter<T>, delay?: number): ThrottleBehavior<T>;
|
|
222
|
+
};
|
|
223
|
+
declare class DocumentTitleBehavior extends Behavior {
|
|
224
|
+
onCreate(title: MaybeGetter<string>): void;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Set document.title for the mounted lifetime; restores the previous title on unmount.
|
|
228
|
+
*
|
|
229
|
+
* @example title = withDocumentTitle(() => `Inbox (${this.unread})`);
|
|
230
|
+
*/
|
|
231
|
+
declare const withDocumentTitle: {
|
|
232
|
+
(title: MaybeGetter<string>): DocumentTitleBehavior;
|
|
233
|
+
new (title: MaybeGetter<string>): DocumentTitleBehavior;
|
|
234
|
+
};
|
|
235
|
+
declare class PageVisibilityBehavior extends Behavior {
|
|
236
|
+
visible: boolean;
|
|
237
|
+
visibilityListener: EventListenerBehavior;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Observable page visibility (true during SSR).
|
|
241
|
+
*
|
|
242
|
+
* @example page = withPageVisibility(); // pause work when !this.page.visible
|
|
243
|
+
*/
|
|
244
|
+
declare const withPageVisibility: {
|
|
245
|
+
(): PageVisibilityBehavior;
|
|
246
|
+
new (): PageVisibilityBehavior;
|
|
247
|
+
};
|
|
248
|
+
declare class AutosaveBehavior extends Behavior {
|
|
249
|
+
/** Posting rides on withAsync (out-of-order completions discarded) */
|
|
250
|
+
saver: AsyncBehavior<Response>;
|
|
251
|
+
/** Scheduling rides on withInterval (assigned in onCreate, still collected) */
|
|
252
|
+
timer: IntervalBehavior;
|
|
253
|
+
/** Current save endpoint — a one-way mirror of the url argument (this.sync) */
|
|
254
|
+
url: string;
|
|
255
|
+
private _data;
|
|
256
|
+
private _lastSaved;
|
|
257
|
+
onCreate(url: MaybeGetter<string>, data: () => unknown, interval?: MaybeGetter<number | null>): void;
|
|
258
|
+
/** Save now. Skipped when the payload hasn't changed since the last save. */
|
|
259
|
+
save(): void;
|
|
260
|
+
get saving(): boolean;
|
|
261
|
+
get error(): unknown;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Periodically POST a data snapshot as JSON while mounted, skipping saves
|
|
265
|
+
* when nothing changed. A getter interval reschedules on change; resolving
|
|
266
|
+
* to null pauses autosaving. Call save() for an immediate flush.
|
|
267
|
+
*
|
|
268
|
+
* @example autosave = withAutosave('/api/draft', () => this.doc, 5000);
|
|
269
|
+
*/
|
|
270
|
+
declare const withAutosave: {
|
|
271
|
+
(url: MaybeGetter<string>, data: () => unknown, interval?: MaybeGetter<number | null> | undefined): AutosaveBehavior;
|
|
272
|
+
new (url: MaybeGetter<string>, data: () => unknown, interval?: MaybeGetter<number | null> | undefined): AutosaveBehavior;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
export { AsyncBehavior, AutosaveBehavior, DebounceBehavior, DocumentTitleBehavior, ElementSizeBehavior, type ElementSizeRef, EventListenerBehavior, FetchBehavior, IntervalBehavior, LocalStorageBehavior, MediaQueryBehavior, PageVisibilityBehavior, ThrottleBehavior, TimeoutBehavior, WindowSizeBehavior, withAsync, withAutosave, withDebounce, withDocumentTitle, withElementSize, withEventListener, withFetch, withInterval, withLocalStorage, withMediaQuery, withPageVisibility, withThrottle, withTimeout, withWindowSize };
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { Behavior, MaybeGetter } from 'mobx-mantle';
|
|
2
|
+
export { M as MaybeGetter, t as toValue } from '../reactive-args-BBucrU54.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Standard library of built-in behaviors. Every argument documented as
|
|
6
|
+
* MaybeGetter accepts either a plain value (frozen at construction) or a
|
|
7
|
+
* getter (a live connection — re-resolved whenever its observable sources
|
|
8
|
+
* change):
|
|
9
|
+
*
|
|
10
|
+
* ```tsx
|
|
11
|
+
* media = withMediaQuery('(max-width: 768px)'); // static
|
|
12
|
+
* media = withMediaQuery(() => this.props.breakpoint); // live
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* Author-side conventions on display throughout this file:
|
|
16
|
+
* - `this.sync(arg)` — normalize a MaybeGetter into an ordinary field that
|
|
17
|
+
* stays current (see withFetch, withAutosave)
|
|
18
|
+
* - `this.watch(arg, cb)` — a MaybeGetter is a valid watch source directly
|
|
19
|
+
* (see withDebounce, withThrottle)
|
|
20
|
+
* - `toValue(arg)` — one-off reads inside effect bodies, where the getter
|
|
21
|
+
* call doubles as dependency tracking (see withEventListener, withInterval)
|
|
22
|
+
*
|
|
23
|
+
* Several of these behaviors are themselves compositions of the others
|
|
24
|
+
* (withFetch = withAsync + watch, withWindowSize = withEventListener + state,
|
|
25
|
+
* withAutosave = withInterval + withAsync) — the same nesting available to
|
|
26
|
+
* user-defined behaviors.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
declare class EventListenerBehavior extends Behavior {
|
|
30
|
+
onCreate(target: MaybeGetter<EventTarget | null | undefined>, type: MaybeGetter<string>, handler: (event: Event) => void, options?: AddEventListenerOptions): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Attach an event listener for the mounted lifetime of the host. Re-attaches
|
|
34
|
+
* when a getter target or type changes.
|
|
35
|
+
*
|
|
36
|
+
* @example keys = withEventListener(window, 'keydown', (e) => this.handleKey(e));
|
|
37
|
+
*/
|
|
38
|
+
declare const withEventListener: {
|
|
39
|
+
(target: MaybeGetter<EventTarget | null | undefined>, type: MaybeGetter<string>, handler: (event: Event) => void, options?: AddEventListenerOptions | undefined): EventListenerBehavior;
|
|
40
|
+
new (target: MaybeGetter<EventTarget | null | undefined>, type: MaybeGetter<string>, handler: (event: Event) => void, options?: AddEventListenerOptions | undefined): EventListenerBehavior;
|
|
41
|
+
};
|
|
42
|
+
declare class IntervalBehavior extends Behavior {
|
|
43
|
+
onCreate(callback: () => void, delay?: MaybeGetter<number | null>): void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Run a callback on an interval for the mounted lifetime of the host.
|
|
47
|
+
* A getter delay reschedules on change; resolving to null pauses.
|
|
48
|
+
*
|
|
49
|
+
* @example poll = withInterval(() => this.refresh(), 10_000);
|
|
50
|
+
*/
|
|
51
|
+
declare const withInterval: {
|
|
52
|
+
(callback: () => void, delay?: MaybeGetter<number | null> | undefined): IntervalBehavior;
|
|
53
|
+
new (callback: () => void, delay?: MaybeGetter<number | null> | undefined): IntervalBehavior;
|
|
54
|
+
};
|
|
55
|
+
declare class TimeoutBehavior extends Behavior {
|
|
56
|
+
/** True while the timeout is scheduled and hasn't fired */
|
|
57
|
+
pending: boolean;
|
|
58
|
+
onCreate(callback: () => void, delay: MaybeGetter<number | null>): void;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Run a callback once after a delay (measured from mount). A getter delay
|
|
62
|
+
* reschedules on change; resolving to null cancels.
|
|
63
|
+
*
|
|
64
|
+
* @example toast = withTimeout(() => (this.visible = false), 3000);
|
|
65
|
+
*/
|
|
66
|
+
declare const withTimeout: {
|
|
67
|
+
(callback: () => void, delay: MaybeGetter<number | null>): TimeoutBehavior;
|
|
68
|
+
new (callback: () => void, delay: MaybeGetter<number | null>): TimeoutBehavior;
|
|
69
|
+
};
|
|
70
|
+
declare class AsyncBehavior<T = unknown> extends Behavior {
|
|
71
|
+
value: T | undefined;
|
|
72
|
+
error: unknown;
|
|
73
|
+
loading: boolean;
|
|
74
|
+
private _fn;
|
|
75
|
+
private _runId;
|
|
76
|
+
onCreate(fn: (...args: any[]) => Promise<T>): void;
|
|
77
|
+
/**
|
|
78
|
+
* Run the async function. Out-of-order completions are discarded: only the
|
|
79
|
+
* most recent run may write value/error/loading.
|
|
80
|
+
*/
|
|
81
|
+
run(...args: any[]): Promise<T | undefined>;
|
|
82
|
+
/** Discard any in-flight run's result */
|
|
83
|
+
cancel(): void;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Track an async function's latest run as observable value/error/loading state.
|
|
87
|
+
*
|
|
88
|
+
* @example search = withAsync((q: string) => api.search(q)); // later: this.search.run(this.query)
|
|
89
|
+
*/
|
|
90
|
+
declare const withAsync: {
|
|
91
|
+
<T>(fn: (...args: any[]) => Promise<T>): AsyncBehavior<T>;
|
|
92
|
+
new <T>(fn: (...args: any[]) => Promise<T>): AsyncBehavior<T>;
|
|
93
|
+
};
|
|
94
|
+
declare class FetchBehavior<T = unknown> extends Behavior {
|
|
95
|
+
/** Current URL — a one-way mirror of the url argument (this.sync) */
|
|
96
|
+
url: string | null | undefined;
|
|
97
|
+
/** The request state machine is a nested withAsync behavior */
|
|
98
|
+
request: AsyncBehavior<T>;
|
|
99
|
+
private _init?;
|
|
100
|
+
onCreate(url: MaybeGetter<string | null | undefined>, init?: RequestInit): void;
|
|
101
|
+
get data(): T | undefined;
|
|
102
|
+
get loading(): boolean;
|
|
103
|
+
get error(): unknown;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Fetch JSON from a URL. A getter URL refetches on change (the first fetch
|
|
107
|
+
* fires at mount); a URL resolving to null/undefined skips fetching.
|
|
108
|
+
* Out-of-order responses are discarded by the underlying withAsync.
|
|
109
|
+
*
|
|
110
|
+
* @example user = withFetch<User>(() => `/api/users/${this.props.userId}`);
|
|
111
|
+
*/
|
|
112
|
+
declare const withFetch: {
|
|
113
|
+
<T = unknown>(url: MaybeGetter<string | null | undefined>, init?: RequestInit): FetchBehavior<T>;
|
|
114
|
+
new <T = unknown>(url: MaybeGetter<string | null | undefined>, init?: RequestInit): FetchBehavior<T>;
|
|
115
|
+
};
|
|
116
|
+
declare class LocalStorageBehavior<T = unknown> extends Behavior {
|
|
117
|
+
value: T;
|
|
118
|
+
/** Cross-tab sync rides on a nested withEventListener */
|
|
119
|
+
storageSync: EventListenerBehavior;
|
|
120
|
+
onCreate(key: string, initialValue: T): void;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* An observable value persisted to localStorage under `key`, hydrated from
|
|
124
|
+
* storage at construction and kept in sync across tabs. Values must be
|
|
125
|
+
* JSON-serializable.
|
|
126
|
+
*
|
|
127
|
+
* @example theme = withLocalStorage('theme', 'dark'); // read/write this.theme.value
|
|
128
|
+
*/
|
|
129
|
+
declare const withLocalStorage: {
|
|
130
|
+
<T>(key: string, initialValue: T): LocalStorageBehavior<T>;
|
|
131
|
+
new <T>(key: string, initialValue: T): LocalStorageBehavior<T>;
|
|
132
|
+
};
|
|
133
|
+
interface ElementSizeRef {
|
|
134
|
+
readonly current: Element | null;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Observe one ref's border-box dimensions for the mounted lifetime of its
|
|
138
|
+
* host. Setup and teardown both live in onLayoutMount so React StrictMode's
|
|
139
|
+
* effect replay always reacquires the observer against the retained DOM node.
|
|
140
|
+
*/
|
|
141
|
+
declare class ElementSizeBehavior extends Behavior {
|
|
142
|
+
width: number | null;
|
|
143
|
+
height: number | null;
|
|
144
|
+
private target;
|
|
145
|
+
onCreate(target: ElementSizeRef): void;
|
|
146
|
+
measure(entry?: ResizeObserverEntry): void;
|
|
147
|
+
onLayoutMount(): (() => void) | undefined;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Reactive layout-space border-box width and height for an element ref.
|
|
151
|
+
* CSS transforms on the element or its ancestors do not affect the reported
|
|
152
|
+
* size, so responsive components behave consistently inside scaled containers.
|
|
153
|
+
* Values are null before layout mount, while no element is attached, and
|
|
154
|
+
* after cleanup.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* root = this.ref<HTMLDivElement>();
|
|
158
|
+
* size = withElementSize(this.root);
|
|
159
|
+
*/
|
|
160
|
+
declare const withElementSize: {
|
|
161
|
+
(target: ElementSizeRef): ElementSizeBehavior;
|
|
162
|
+
new (target: ElementSizeRef): ElementSizeBehavior;
|
|
163
|
+
};
|
|
164
|
+
declare class WindowSizeBehavior extends Behavior {
|
|
165
|
+
width: number;
|
|
166
|
+
height: number;
|
|
167
|
+
resize: EventListenerBehavior;
|
|
168
|
+
measure(): void;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Observable window inner width/height (0×0 during SSR).
|
|
172
|
+
*
|
|
173
|
+
* @example size = withWindowSize(); // this.size.width × this.size.height
|
|
174
|
+
*/
|
|
175
|
+
declare const withWindowSize: {
|
|
176
|
+
(): WindowSizeBehavior;
|
|
177
|
+
new (): WindowSizeBehavior;
|
|
178
|
+
};
|
|
179
|
+
declare class MediaQueryBehavior extends Behavior {
|
|
180
|
+
matches: boolean;
|
|
181
|
+
onCreate(query: MaybeGetter<string>): void;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Observable match state for a media query (false during SSR).
|
|
185
|
+
*
|
|
186
|
+
* @example isMobile = withMediaQuery('(max-width: 768px)'); // this.isMobile.matches
|
|
187
|
+
*/
|
|
188
|
+
declare const withMediaQuery: {
|
|
189
|
+
(query: MaybeGetter<string>): MediaQueryBehavior;
|
|
190
|
+
new (query: MaybeGetter<string>): MediaQueryBehavior;
|
|
191
|
+
};
|
|
192
|
+
declare class DebounceBehavior<T = unknown> extends Behavior {
|
|
193
|
+
value: T;
|
|
194
|
+
private _timer;
|
|
195
|
+
onCreate(source: MaybeGetter<T>, delay?: number): void;
|
|
196
|
+
onUnmount(): void;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* A debounced mirror of a reactive source: updates settle after `delay` ms of quiet.
|
|
200
|
+
*
|
|
201
|
+
* @example debouncedQuery = withDebounce(() => this.query, 300);
|
|
202
|
+
*/
|
|
203
|
+
declare const withDebounce: {
|
|
204
|
+
<T>(source: MaybeGetter<T>, delay?: number): DebounceBehavior<T>;
|
|
205
|
+
new <T>(source: MaybeGetter<T>, delay?: number): DebounceBehavior<T>;
|
|
206
|
+
};
|
|
207
|
+
declare class ThrottleBehavior<T = unknown> extends Behavior {
|
|
208
|
+
value: T;
|
|
209
|
+
private _timer;
|
|
210
|
+
private _lastEmit;
|
|
211
|
+
onCreate(source: MaybeGetter<T>, delay?: number): void;
|
|
212
|
+
onUnmount(): void;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* A throttled mirror of a reactive source: at most one update per `delay` ms, trailing edge included.
|
|
216
|
+
*
|
|
217
|
+
* @example scrollY = withThrottle(() => this.rawScrollY, 100);
|
|
218
|
+
*/
|
|
219
|
+
declare const withThrottle: {
|
|
220
|
+
<T>(source: MaybeGetter<T>, delay?: number): ThrottleBehavior<T>;
|
|
221
|
+
new <T>(source: MaybeGetter<T>, delay?: number): ThrottleBehavior<T>;
|
|
222
|
+
};
|
|
223
|
+
declare class DocumentTitleBehavior extends Behavior {
|
|
224
|
+
onCreate(title: MaybeGetter<string>): void;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Set document.title for the mounted lifetime; restores the previous title on unmount.
|
|
228
|
+
*
|
|
229
|
+
* @example title = withDocumentTitle(() => `Inbox (${this.unread})`);
|
|
230
|
+
*/
|
|
231
|
+
declare const withDocumentTitle: {
|
|
232
|
+
(title: MaybeGetter<string>): DocumentTitleBehavior;
|
|
233
|
+
new (title: MaybeGetter<string>): DocumentTitleBehavior;
|
|
234
|
+
};
|
|
235
|
+
declare class PageVisibilityBehavior extends Behavior {
|
|
236
|
+
visible: boolean;
|
|
237
|
+
visibilityListener: EventListenerBehavior;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Observable page visibility (true during SSR).
|
|
241
|
+
*
|
|
242
|
+
* @example page = withPageVisibility(); // pause work when !this.page.visible
|
|
243
|
+
*/
|
|
244
|
+
declare const withPageVisibility: {
|
|
245
|
+
(): PageVisibilityBehavior;
|
|
246
|
+
new (): PageVisibilityBehavior;
|
|
247
|
+
};
|
|
248
|
+
declare class AutosaveBehavior extends Behavior {
|
|
249
|
+
/** Posting rides on withAsync (out-of-order completions discarded) */
|
|
250
|
+
saver: AsyncBehavior<Response>;
|
|
251
|
+
/** Scheduling rides on withInterval (assigned in onCreate, still collected) */
|
|
252
|
+
timer: IntervalBehavior;
|
|
253
|
+
/** Current save endpoint — a one-way mirror of the url argument (this.sync) */
|
|
254
|
+
url: string;
|
|
255
|
+
private _data;
|
|
256
|
+
private _lastSaved;
|
|
257
|
+
onCreate(url: MaybeGetter<string>, data: () => unknown, interval?: MaybeGetter<number | null>): void;
|
|
258
|
+
/** Save now. Skipped when the payload hasn't changed since the last save. */
|
|
259
|
+
save(): void;
|
|
260
|
+
get saving(): boolean;
|
|
261
|
+
get error(): unknown;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Periodically POST a data snapshot as JSON while mounted, skipping saves
|
|
265
|
+
* when nothing changed. A getter interval reschedules on change; resolving
|
|
266
|
+
* to null pauses autosaving. Call save() for an immediate flush.
|
|
267
|
+
*
|
|
268
|
+
* @example autosave = withAutosave('/api/draft', () => this.doc, 5000);
|
|
269
|
+
*/
|
|
270
|
+
declare const withAutosave: {
|
|
271
|
+
(url: MaybeGetter<string>, data: () => unknown, interval?: MaybeGetter<number | null> | undefined): AutosaveBehavior;
|
|
272
|
+
new (url: MaybeGetter<string>, data: () => unknown, interval?: MaybeGetter<number | null> | undefined): AutosaveBehavior;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
export { AsyncBehavior, AutosaveBehavior, DebounceBehavior, DocumentTitleBehavior, ElementSizeBehavior, type ElementSizeRef, EventListenerBehavior, FetchBehavior, IntervalBehavior, LocalStorageBehavior, MediaQueryBehavior, PageVisibilityBehavior, ThrottleBehavior, TimeoutBehavior, WindowSizeBehavior, withAsync, withAutosave, withDebounce, withDocumentTitle, withElementSize, withEventListener, withFetch, withInterval, withLocalStorage, withMediaQuery, withPageVisibility, withThrottle, withTimeout, withWindowSize };
|