aberdeen 0.2.4 → 0.5.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/LICENSE.txt +1 -1
- package/README.md +140 -99
- package/dist/aberdeen.d.ts +649 -512
- package/dist/aberdeen.js +1147 -1704
- package/dist/aberdeen.js.map +11 -1
- package/dist/helpers/reverseSortedSet.d.ts +91 -0
- package/dist/prediction.d.ts +7 -3
- package/dist/prediction.js +77 -93
- package/dist/prediction.js.map +10 -1
- package/dist/route.d.ts +44 -13
- package/dist/route.js +138 -112
- package/dist/route.js.map +10 -1
- package/dist/transitions.d.ts +2 -2
- package/dist/transitions.js +30 -63
- package/dist/transitions.js.map +10 -1
- package/dist-min/aberdeen.js +7 -2
- package/dist-min/aberdeen.js.map +11 -1
- package/dist-min/prediction.js +4 -2
- package/dist-min/prediction.js.map +10 -1
- package/dist-min/route.js +4 -2
- package/dist-min/route.js.map +10 -1
- package/dist-min/transitions.js +4 -2
- package/dist-min/transitions.js.map +10 -1
- package/package.json +20 -23
- package/src/aberdeen.ts +1956 -1696
- package/src/helpers/reverseSortedSet.ts +188 -0
- package/src/prediction.ts +14 -9
- package/src/route.ts +149 -69
- package/src/transitions.ts +26 -43
- package/dist-min/aberdeen.d.ts +0 -573
- package/dist-min/prediction.d.ts +0 -29
- package/dist-min/route.d.ts +0 -16
- package/dist-min/transitions.d.ts +0 -18
package/dist/aberdeen.d.ts
CHANGED
|
@@ -1,573 +1,710 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Forces the immediate and synchronous execution of all pending reactive updates.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Normally, changes to observed data sources (like proxied objects or arrays)
|
|
5
|
+
* are processed asynchronously in a batch after a brief timeout (0ms). This function
|
|
6
|
+
* allows you to bypass the timeout and process the update queue immediately.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* This helps reduce visual glitches and flashes by ensuring the browser doesn't render
|
|
11
|
-
* intermediate DOM states during updates.
|
|
8
|
+
* This can be useful in specific scenarios where you need the DOM to be updated
|
|
9
|
+
* synchronously.
|
|
12
10
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* This function is re-entrant, meaning it is safe to call `runQueue` from within
|
|
12
|
+
* a function that is itself being executed as part of an update cycle triggered
|
|
13
|
+
* by a previous (or the same) `runQueue` call.
|
|
15
14
|
*
|
|
16
|
-
* @
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const data = proxy("before");
|
|
18
|
+
*
|
|
19
|
+
* $({text: data});
|
|
20
|
+
* console.log(1, document.body.innerHTML); // before
|
|
21
|
+
*
|
|
22
|
+
* // Make an update that should cause the DOM to change.
|
|
23
|
+
* data.value = "after";
|
|
24
|
+
*
|
|
25
|
+
* // Normally, the DOM update would happen after a timeout.
|
|
26
|
+
* // But this causes an immediate update:
|
|
27
|
+
* runQueue();
|
|
28
|
+
*
|
|
29
|
+
* console.log(2, document.body.innerHTML); // after
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function runQueue(): void;
|
|
33
|
+
/**
|
|
34
|
+
* A sort key, as used by {@link onEach}, is a value that determines the order of items. It can
|
|
35
|
+
* be a number, string, or an array of numbers/strings. The sort key is used to sort items
|
|
36
|
+
* based on their values. The sort key can also be `undefined`, which indicates that the item
|
|
37
|
+
* should be ignored.
|
|
38
|
+
* @private
|
|
17
39
|
*/
|
|
18
|
-
export
|
|
40
|
+
export type SortKeyType = number | string | Array<number | string> | undefined;
|
|
19
41
|
/**
|
|
20
|
-
*
|
|
42
|
+
* Creates a new string that has the opposite sort order compared to the input string.
|
|
21
43
|
*
|
|
22
|
-
* This
|
|
23
|
-
*
|
|
24
|
-
*
|
|
44
|
+
* This is achieved by flipping the bits of each character code in the input string.
|
|
45
|
+
* The resulting string is intended for use as a sort key, particularly with the
|
|
46
|
+
* `makeKey` function in {@link onEach}, to achieve a descending sort order.
|
|
25
47
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* This helps reduce visual glitches and flashes by ensuring the browser doesn't render
|
|
29
|
-
* intermediate DOM states during updates.
|
|
48
|
+
* **Warning:** The output string will likely contain non-printable characters or
|
|
49
|
+
* appear as gibberish and should not be displayed to the user.
|
|
30
50
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const users = proxy([
|
|
54
|
+
* { id: 1, name: 'Charlie', score: 95 },
|
|
55
|
+
* { id: 2, name: 'Alice', score: 100 },
|
|
56
|
+
* { id: 3, name: 'Bob', score: 90 },
|
|
57
|
+
* ]);
|
|
33
58
|
*
|
|
34
|
-
*
|
|
59
|
+
* onEach(users, (user) => {
|
|
60
|
+
* $(`p:${user.name}: ${user.score}`);
|
|
61
|
+
* }, (user) => invertString(user.name)); // Reverse alphabetic order
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @param input The string whose sort order needs to be inverted.
|
|
65
|
+
* @returns A new string that will sort in the reverse order of the input string.
|
|
66
|
+
* @see {@link onEach} for usage with sorting.
|
|
35
67
|
*/
|
|
36
|
-
export declare function
|
|
68
|
+
export declare function invertString(input: string): string;
|
|
69
|
+
export declare function onEach<T>(target: Array<undefined | T>, render: (value: T, index: number) => void, makeKey?: (value: T, key: any) => SortKeyType): void;
|
|
70
|
+
export declare function onEach<K extends string | number | symbol, T>(target: Record<K, undefined | T>, render: (value: T, index: K) => void, makeKey?: (value: T, key: K) => SortKeyType): void;
|
|
37
71
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
72
|
+
* Reactively checks if an observable array or object is empty.
|
|
73
|
+
*
|
|
74
|
+
* This function not only returns the current emptiness state but also establishes
|
|
75
|
+
* a reactive dependency. If the emptiness state of the `proxied` object or array
|
|
76
|
+
* changes later (e.g., an item is added to an empty array, or the last property
|
|
77
|
+
* is deleted from an object), the scope that called `isEmpty` will be automatically
|
|
78
|
+
* scheduled for re-evaluation.
|
|
79
|
+
*
|
|
80
|
+
* @param proxied The observable array or object (obtained via `observe()`) to check.
|
|
81
|
+
* @returns `true` if the array has length 0 or the object has no own enumerable properties, `false` otherwise.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* const items = proxy([]);
|
|
40
86
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
87
|
+
* // Reactively display a message if the items array is empty
|
|
88
|
+
* $('div', () => {
|
|
89
|
+
* if (isEmpty(items)) {
|
|
90
|
+
* $('p', 'i:No items yet!');
|
|
91
|
+
* } else {
|
|
92
|
+
* onEach(items, item=>$('p:'+item));
|
|
93
|
+
* }
|
|
94
|
+
* });
|
|
95
|
+
*
|
|
96
|
+
* // Adding an item will automatically remove the "No items yet!" message
|
|
97
|
+
* setInterval(() => {
|
|
98
|
+
* if (!items.length || Math.random()>0.5) items.push('Item');
|
|
99
|
+
* else items.length = 0;
|
|
100
|
+
* }, 1000)
|
|
101
|
+
* ```
|
|
44
102
|
*/
|
|
45
|
-
export declare
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
* `Store`s. (Calling {@link Store.get} on the store will recreate the original data strucure, though.)
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* ```
|
|
53
|
-
* let emptyStore = new Store()
|
|
54
|
-
* let numStore = new Store(42)
|
|
55
|
-
* let objStore = new Store({x: {alice: 1, bob: 2}, y: [9,7,5,3,1]})
|
|
56
|
-
* ```
|
|
57
|
-
*/
|
|
58
|
-
constructor();
|
|
59
|
-
constructor(value: any);
|
|
60
|
-
/**
|
|
61
|
-
*
|
|
62
|
-
* @returns The index for this Store within its parent collection. This will be a `number`
|
|
63
|
-
* when the parent collection is an array, a `string` when it's an object, or any data type
|
|
64
|
-
* when it's a `Map`.
|
|
65
|
-
*
|
|
66
|
-
* @example
|
|
67
|
-
* ```
|
|
68
|
-
* let store = new Store({x: 123})
|
|
69
|
-
* let subStore = store.ref('x')
|
|
70
|
-
* assert(subStore.get() === 123)
|
|
71
|
-
* assert(subStore.index() === 'x') // <----
|
|
72
|
-
* ```
|
|
73
|
-
*/
|
|
74
|
-
index(): any;
|
|
75
|
-
/**
|
|
76
|
-
* @returns Resolves `path` and then retrieves the value that is there, subscribing
|
|
77
|
-
* to all read `Store` values. If `path` does not exist, `undefined` is returned.
|
|
78
|
-
* @param path - Any path terms to resolve before retrieving the value.
|
|
79
|
-
* @example
|
|
80
|
-
* ```
|
|
81
|
-
* let store = new Store({a: {b: {c: {d: 42}}}})
|
|
82
|
-
* assert('a' in store.get())
|
|
83
|
-
* assert(store.get('a', 'b') === {c: {d: 42}})
|
|
84
|
-
* ```
|
|
85
|
-
*/
|
|
86
|
-
get(...path: any[]): any;
|
|
87
|
-
/**
|
|
88
|
-
* Like {@link Store.get}, but doesn't subscribe to changes.
|
|
89
|
-
*/
|
|
90
|
-
peek(...path: any[]): any;
|
|
91
|
-
/**
|
|
92
|
-
* @returns Like {@link Store.get}, but throws a `TypeError` if the resulting value is not of type `number`.
|
|
93
|
-
* Using this instead of just {@link Store.get} is especially useful from within TypeScript.
|
|
94
|
-
*/
|
|
95
|
-
getNumber(...path: any[]): number;
|
|
96
|
-
/**
|
|
97
|
-
* @returns Like {@link Store.get}, but throws a `TypeError` if the resulting value is not of type `string`.
|
|
98
|
-
* Using this instead of just {@link Store.get} is especially useful from within TypeScript.
|
|
99
|
-
*/
|
|
100
|
-
getString(...path: any[]): string;
|
|
101
|
-
/**
|
|
102
|
-
* @returns Like {@link Store.get}, but throws a `TypeError` if the resulting value is not of type `boolean`.
|
|
103
|
-
* Using this instead of just {@link Store.get} is especially useful from within TypeScript.
|
|
104
|
-
*/
|
|
105
|
-
getBoolean(...path: any[]): boolean;
|
|
106
|
-
/**
|
|
107
|
-
* @returns Like {@link Store.get}, but throws a `TypeError` if the resulting value is not of type `function`.
|
|
108
|
-
* Using this instead of just {@link Store.get} is especially useful from within TypeScript.
|
|
109
|
-
*/
|
|
110
|
-
getFunction(...path: any[]): (Function);
|
|
111
|
-
/**
|
|
112
|
-
* @returns Like {@link Store.get}, but throws a `TypeError` if the resulting value is not of type `array`.
|
|
113
|
-
* Using this instead of just {@link Store.get} is especially useful from within TypeScript.
|
|
114
|
-
*/
|
|
115
|
-
getArray(...path: any[]): any[];
|
|
116
|
-
/**
|
|
117
|
-
* @returns Like {@link Store.get}, but throws a `TypeError` if the resulting value is not of type `object`.
|
|
118
|
-
* Using this instead of just {@link Store.get} is especially useful from within TypeScript.
|
|
119
|
-
*/
|
|
120
|
-
getObject(...path: any[]): object;
|
|
121
|
-
/**
|
|
122
|
-
* @returns Like {@link Store.get}, but throws a `TypeError` if the resulting value is not of type `map`.
|
|
123
|
-
* Using this instead of just {@link Store.get} is especially useful from within TypeScript.
|
|
124
|
-
*/
|
|
125
|
-
getMap(...path: any[]): Map<any, any>;
|
|
126
|
-
/**
|
|
127
|
-
* Like {@link Store.get}, but the first parameter is the default value (returned when the Store
|
|
128
|
-
* contains `undefined`). This default value is also used to determine the expected type,
|
|
129
|
-
* and to throw otherwise.
|
|
130
|
-
*
|
|
131
|
-
* @example
|
|
132
|
-
* ```
|
|
133
|
-
* let store = {x: 42}
|
|
134
|
-
* assert(getOr(99, 'x') == 42)
|
|
135
|
-
* assert(getOr(99, 'y') == 99)
|
|
136
|
-
* getOr('hello', x') # throws TypeError (because 42 is not a string)
|
|
137
|
-
* ```
|
|
138
|
-
*/
|
|
139
|
-
getOr<T>(defaultValue: T, ...path: any[]): T;
|
|
140
|
-
/** Retrieve a value, subscribing to all read `Store` values. This is a more flexible
|
|
141
|
-
* form of the {@link Store.get} and {@link Store.peek} methods.
|
|
142
|
-
*
|
|
143
|
-
* @returns The resulting value, or `undefined` if the `path` does not exist.
|
|
144
|
-
*/
|
|
145
|
-
query(opts: {
|
|
146
|
-
/** The value for this path should be retrieved. Defaults to `[]`, meaning the entire `Store`. */
|
|
147
|
-
path?: any[];
|
|
148
|
-
/** A string specifying what type the query is expected to return. Options are:
|
|
149
|
-
* "undefined", "null", "boolean", "number", "string", "function", "array", "map"
|
|
150
|
-
* and "object". If the store holds a different type of value, a `TypeError`
|
|
151
|
-
* exception is thrown. By default (when `type` is `undefined`) no type checking
|
|
152
|
-
* is done.
|
|
153
|
-
*/
|
|
154
|
-
type?: string;
|
|
155
|
-
/** Limit the depth of the retrieved data structure to this positive integer.
|
|
156
|
-
* When `depth` is `1`, only a single level of the value at `path` is unpacked. This
|
|
157
|
-
* makes no difference for primitive values (like strings), but for objects, maps and
|
|
158
|
-
* arrays, it means that each *value* in the resulting data structure will be a
|
|
159
|
-
* reference to the `Store` for that value.
|
|
160
|
-
*/
|
|
161
|
-
depth?: number;
|
|
162
|
-
/** Return this value when the `path` does not exist. Defaults to `undefined`. */
|
|
163
|
-
defaultValue?: any;
|
|
164
|
-
/** When peek is `undefined` or `false`, the current scope will automatically be
|
|
165
|
-
* subscribed to changes of any parts of the store being read. When `true`, no
|
|
166
|
-
* subscribers will be performed.
|
|
167
|
-
*/
|
|
168
|
-
peek?: boolean;
|
|
169
|
-
}): any;
|
|
170
|
-
/**
|
|
171
|
-
* Checks if the specified collection is empty, and subscribes the current scope to changes of the emptiness of this collection.
|
|
172
|
-
*
|
|
173
|
-
* @param path Any path terms to resolve before retrieving the value.
|
|
174
|
-
* @returns When the specified collection is not empty `true` is returned. If it is empty or if the value is undefined, `false` is returned.
|
|
175
|
-
* @throws When the value is not a collection and not undefined, an Error will be thrown.
|
|
176
|
-
*/
|
|
177
|
-
isEmpty(...path: any[]): boolean;
|
|
178
|
-
/**
|
|
179
|
-
* Returns the number of items in the specified collection, and subscribes the current scope to changes in this count.
|
|
180
|
-
*
|
|
181
|
-
* @param path Any path terms to resolve before retrieving the value.
|
|
182
|
-
* @returns The number of items contained in the collection, or 0 if the value is undefined.
|
|
183
|
-
* @throws When the value is not a collection and not undefined, an Error will be thrown.
|
|
184
|
-
*/
|
|
185
|
-
count(...path: any[]): number;
|
|
186
|
-
/**
|
|
187
|
-
* Returns a strings describing the type of the store value, subscribing to changes of this type.
|
|
188
|
-
* Note: this currently also subscribes to changes of primitive values, so changing a value from 3 to 4
|
|
189
|
-
* would cause the scope to be rerun. This is not great, and may change in the future. This caveat does
|
|
190
|
-
* not apply to changes made *inside* an object, `Array` or `Map`.
|
|
191
|
-
*
|
|
192
|
-
* @param path Any path terms to resolve before retrieving the value.
|
|
193
|
-
* @returns Possible options: "undefined", "null", "boolean", "number", "string", "function", "array", "map" or "object".
|
|
194
|
-
*/
|
|
195
|
-
getType(...path: any[]): string;
|
|
196
|
-
/**
|
|
197
|
-
* Sets the value to the last given argument. Any earlier argument are a Store-path that is first
|
|
198
|
-
* resolved/created using {@link Store.makeRef}.
|
|
199
|
-
*
|
|
200
|
-
* When a `Store` is passed in as the value, its value will be copied (subscribing to changes). In
|
|
201
|
-
* case the value is an object, an `Array` or a `Map`, a *reference* to that data structure will
|
|
202
|
-
* be created, so that changes made through one `Store` will be reflected through the other. Be
|
|
203
|
-
* carefull not to create loops in your `Store` tree that way, as that would cause any future
|
|
204
|
-
* call to {@link Store.get} to throw a `RangeError` (Maximum call stack size exceeded.)
|
|
205
|
-
*
|
|
206
|
-
* If you intent to make a copy instead of a reference, call {@link Store.get} on the origin `Store`.
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
* @example
|
|
210
|
-
* ```
|
|
211
|
-
* let store = new Store() // Value is `undefined`
|
|
212
|
-
*
|
|
213
|
-
* store.set('x', 6) // Causes the store to become an object
|
|
214
|
-
* assert(store.get() == {x: 6})
|
|
215
|
-
*
|
|
216
|
-
* store.set('a', 'b', 'c', 'd') // Create parent path as objects
|
|
217
|
-
* assert(store.get() == {x: 6, a: {b: {c: 'd'}}})
|
|
218
|
-
*
|
|
219
|
-
* store.set(42) // Overwrites all of the above
|
|
220
|
-
* assert(store.get() == 42)
|
|
221
|
-
*
|
|
222
|
-
* store.set('x', 6) // Throw Error (42 is not a collection)
|
|
223
|
-
* ```
|
|
224
|
-
*/
|
|
225
|
-
set(...pathAndValue: any[]): void;
|
|
226
|
-
/**
|
|
227
|
-
* Sets the `Store` to the given `mergeValue`, but without deleting any pre-existing
|
|
228
|
-
* items when a collection overwrites a similarly typed collection. This results in
|
|
229
|
-
* a deep merge.
|
|
230
|
-
*
|
|
231
|
-
* @example
|
|
232
|
-
* ```
|
|
233
|
-
* let store = new Store({a: {x: 1}})
|
|
234
|
-
* store.merge({a: {y: 2}, b: 3})
|
|
235
|
-
* assert(store.get() == {a: {x: 1, y: 2}, b: 3})
|
|
236
|
-
* ```
|
|
237
|
-
*/
|
|
238
|
-
merge(...pathAndValue: any): void;
|
|
239
|
-
/**
|
|
240
|
-
* Sets the value for the store to `undefined`, which causes it to be omitted from the map (or array, if it's at the end)
|
|
241
|
-
*
|
|
242
|
-
* @example
|
|
243
|
-
* ```
|
|
244
|
-
* let store = new Store({a: 1, b: 2})
|
|
245
|
-
* store.delete('a')
|
|
246
|
-
* assert(store.get() == {b: 2})
|
|
247
|
-
*
|
|
248
|
-
* store = new Store(['a','b','c'])
|
|
249
|
-
* store.delete(1)
|
|
250
|
-
* assert(store.get() == ['a', undefined, 'c'])
|
|
251
|
-
* store.delete(2)
|
|
252
|
-
* assert(store.get() == ['a'])
|
|
253
|
-
* ```
|
|
254
|
-
*/
|
|
255
|
-
delete(...path: any): void;
|
|
256
|
-
/**
|
|
257
|
-
* Pushes a value to the end of the Array that is at the specified path in the store.
|
|
258
|
-
* If that store path is `undefined`, an Array is created first.
|
|
259
|
-
* The last argument is the value to be added, any earlier arguments indicate the path.
|
|
260
|
-
*
|
|
261
|
-
* @example
|
|
262
|
-
* ```
|
|
263
|
-
* let store = new Store()
|
|
264
|
-
* store.push(3) // Creates the array
|
|
265
|
-
* store.push(6)
|
|
266
|
-
* assert(store.get() == [3,6])
|
|
267
|
-
*
|
|
268
|
-
* store = new Store({myArray: [1,2]})
|
|
269
|
-
* store.push('myArray', 3)
|
|
270
|
-
* assert(store.get() == {myArray: [1,2,3]})
|
|
271
|
-
* ```
|
|
272
|
-
*/
|
|
273
|
-
push(...pathAndValue: any[]): number;
|
|
274
|
-
/**
|
|
275
|
-
* {@link Store.peek} the current value, pass it through `func`, and {@link Store.set} the resulting
|
|
276
|
-
* value.
|
|
277
|
-
* @param func The function transforming the value.
|
|
278
|
-
*/
|
|
279
|
-
modify(func: (value: any) => any): void;
|
|
280
|
-
/**
|
|
281
|
-
* Return a `Store` deeper within the tree by resolving the given `path`,
|
|
282
|
-
* subscribing to every level.
|
|
283
|
-
* In case `undefined` is encountered while resolving the path, a newly
|
|
284
|
-
* created `Store` containing `undefined` is returned. In that case, the
|
|
285
|
-
* `Store`'s {@link Store.isDetached} method will return `true`.
|
|
286
|
-
* In case something other than a collection is encountered, an error is thrown.
|
|
287
|
-
*/
|
|
288
|
-
ref(...path: any[]): Store;
|
|
289
|
-
/**
|
|
290
|
-
* Similar to `ref()`, but instead of returning `undefined`, new objects are created when
|
|
291
|
-
* a path does not exist yet. An error is still thrown when the path tries to index an invalid
|
|
292
|
-
* type.
|
|
293
|
-
* Unlike `ref`, `makeRef` does *not* subscribe to the path levels, as it is intended to be
|
|
294
|
-
* a write-only operation.
|
|
295
|
-
*
|
|
296
|
-
* @example
|
|
297
|
-
* ```
|
|
298
|
-
* let store = new Store() // Value is `undefined`
|
|
299
|
-
*
|
|
300
|
-
* let ref = store.makeRef('a', 'b', 'c')
|
|
301
|
-
* assert(store.get() == {a: {b: {}}}
|
|
302
|
-
*
|
|
303
|
-
* ref.set(42)
|
|
304
|
-
* assert(store.get() == {a: {b: {c: 42}}}
|
|
305
|
-
*
|
|
306
|
-
* ref.makeRef('d') // Throw Error (42 is not a collection)
|
|
307
|
-
* ```
|
|
308
|
-
*/
|
|
309
|
-
makeRef(...path: any[]): Store;
|
|
310
|
-
/**
|
|
311
|
-
* Iterate the specified collection (Array, Map or object), running the given code block for each item.
|
|
312
|
-
* When items are added to the collection at some later point, the code block will be ran for them as well.
|
|
313
|
-
* When an item is removed, the {@link Store.clean} handlers left by its code block are executed.
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
* @param pathAndFuncs
|
|
318
|
-
*/
|
|
319
|
-
onEach(...pathAndFuncs: any): void;
|
|
320
|
-
/**
|
|
321
|
-
* Applies a filter/map function on each item within the `Store`'s collection,
|
|
322
|
-
* and reactively manages the returned `Map` `Store` to hold any results.
|
|
323
|
-
*
|
|
324
|
-
* @param func - Function that transform the given store into an output value or
|
|
325
|
-
* `undefined` in case this value should be skipped:
|
|
326
|
-
*
|
|
327
|
-
* @returns - A map `Store` with the values returned by `func` and the corresponding
|
|
328
|
-
* keys from the original map, array or object `Store`.
|
|
329
|
-
*
|
|
330
|
-
* When items disappear from the `Store` or are changed in a way that `func` depends
|
|
331
|
-
* upon, the resulting items are removed from the output `Store` as well. When multiple
|
|
332
|
-
* input items produce the same output keys, this may lead to unexpected results.
|
|
333
|
-
*/
|
|
334
|
-
map(func: (store: Store) => any): Store;
|
|
335
|
-
/**
|
|
336
|
-
* Applies a filter/map function on each item within the `Store`'s collection,
|
|
337
|
-
* each of which can deliver any number of key/value pairs, and reactively manages the
|
|
338
|
-
* returned map `Store` to hold any results.
|
|
339
|
-
*
|
|
340
|
-
* @param func - Function that transform the given store into output values
|
|
341
|
-
* that can take one of the following forms:
|
|
342
|
-
* - an `Object` or a `Map`: Each key/value pair will be added to the output `Store`.
|
|
343
|
-
* - anything else: No key/value pairs are added to the output `Store`.
|
|
344
|
-
*
|
|
345
|
-
* @returns - A map `Store` with the key/value pairs returned by all `func` invocations.
|
|
346
|
-
*
|
|
347
|
-
* When items disappear from the `Store` or are changed in a way that `func` depends
|
|
348
|
-
* upon, the resulting items are removed from the output `Store` as well. When multiple
|
|
349
|
-
* input items produce the same output keys, this may lead to unexpected results.
|
|
350
|
-
*/
|
|
351
|
-
multiMap(func: (store: Store) => any): Store;
|
|
352
|
-
/**
|
|
353
|
-
* @returns Returns `true` when the `Store` was created by {@link Store.ref}ing a path that
|
|
354
|
-
* does not exist.
|
|
355
|
-
*/
|
|
356
|
-
isDetached(): boolean;
|
|
357
|
-
/**
|
|
358
|
-
* Dump a live view of the `Store` tree as HTML text, `ul` and `li` nodes at
|
|
359
|
-
* the current mount position. Meant for debugging purposes.
|
|
360
|
-
*/
|
|
361
|
-
dump(): void;
|
|
103
|
+
export declare function isEmpty(proxied: TargetType): boolean;
|
|
104
|
+
/** @private */
|
|
105
|
+
export interface ValueRef<T> {
|
|
106
|
+
value: T;
|
|
362
107
|
}
|
|
363
108
|
/**
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
* @param
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
* - `function`: The render function used to draw the scope of the element. This function gets its own `Scope`, so that if any `Store` it reads changes, it will redraw by itself.
|
|
370
|
-
* - `Store`: Presuming `tag` is `"input"`, `"textarea"` or `"select"`, create a two-way binding between this `Store` value and the input element. The initial value of the input will be set to the initial value of the `Store`, or the other way around if the `Store` holds `undefined`. After that, the `Store` will be updated when the input changes and vice versa.
|
|
109
|
+
* Reactively counts the number of properties in an objects.
|
|
110
|
+
*
|
|
111
|
+
* @param proxied The observable object to count. In case an `array` is passed in, a {@link ref} to its `.length` will be returned.
|
|
112
|
+
* @returns an observable object for which the `value` property reflects the number of properties in `proxied` with a value other than `undefined`.
|
|
113
|
+
*
|
|
371
114
|
* @example
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
115
|
+
* ```typescript
|
|
116
|
+
* const items = proxy({x: 3, y: 7} as any);
|
|
117
|
+
* const cnt = count(items);
|
|
118
|
+
*
|
|
119
|
+
* // Create a DOM text node for the count:
|
|
120
|
+
* $('div', {text: cnt});
|
|
121
|
+
* // <div>2</div>
|
|
122
|
+
|
|
123
|
+
* // Or we can use it in an {@link observe} function:
|
|
124
|
+
* observe(() => console.log("The count is now", cnt.value));
|
|
125
|
+
* // The count is now 2
|
|
126
|
+
*
|
|
127
|
+
* // Adding/removing items will update the count
|
|
128
|
+
* items.z = 12;
|
|
129
|
+
* // Asynchronously, after 0ms:
|
|
130
|
+
* // <div>3</div>
|
|
131
|
+
* // The count is now 3
|
|
132
|
+
* ```
|
|
377
133
|
*/
|
|
378
|
-
export declare function
|
|
134
|
+
export declare function count(proxied: TargetType): ValueRef<number>;
|
|
135
|
+
export declare function proxy<T extends DatumType>(target: Array<T>): Array<T extends number ? number : T extends string ? string : T extends boolean ? boolean : T>;
|
|
136
|
+
export declare function proxy<T extends object>(target: T): T;
|
|
137
|
+
export declare function proxy<T extends DatumType>(target: T): ValueRef<T extends number ? number : T extends string ? string : T extends boolean ? boolean : T>;
|
|
379
138
|
/**
|
|
380
|
-
*
|
|
381
|
-
*
|
|
139
|
+
* Returns the original, underlying data target from a reactive proxy created by {@link proxy}.
|
|
140
|
+
* If the input `target` is not a proxy, it is returned directly.
|
|
141
|
+
*
|
|
142
|
+
* This is useful when you want to avoid triggering subscriptions during read operations or
|
|
143
|
+
* re-executes during write operations. Using {@link peek} is an alternative way to achieve this.
|
|
144
|
+
*
|
|
145
|
+
* @param target - A proxied object, array, or any other value.
|
|
146
|
+
* @returns The underlying (unproxied) data, or the input value if it wasn't a proxy.
|
|
147
|
+
* @template T - The type of the target.
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* const userProxy = proxy({ name: 'Frank' });
|
|
152
|
+
* const rawUser = unproxy(userProxy);
|
|
153
|
+
*
|
|
154
|
+
* // Log reactively
|
|
155
|
+
* $(() => console.log('proxied', userProxy.name));
|
|
156
|
+
* // The following will only ever log once, as we're not subscribing to any observable
|
|
157
|
+
* $(() => console.log('unproxied', rawUser.name));
|
|
158
|
+
*
|
|
159
|
+
* // This cause the first log to run again:
|
|
160
|
+
* setTimeout(() => userProxy.name += '!', 1000);
|
|
161
|
+
*
|
|
162
|
+
* // This doesn't cause any new logs:
|
|
163
|
+
* setTimeout(() => rawUser.name += '?', 2000);
|
|
164
|
+
*
|
|
165
|
+
* // Both userProxy and rawUser end up as `{name: 'Frank!?'}`
|
|
166
|
+
* setTimeout(() => console.log('final values', userProxy, rawUser), 3000);
|
|
167
|
+
* ```
|
|
382
168
|
*/
|
|
383
|
-
export declare function
|
|
169
|
+
export declare function unproxy<T>(target: T): T;
|
|
384
170
|
/**
|
|
385
|
-
*
|
|
171
|
+
* Recursively copies properties or array items from `src` to `dst`.
|
|
172
|
+
* It's designed to work efficiently with reactive proxies created by {@link proxy}.
|
|
173
|
+
*
|
|
174
|
+
* - **Minimizes Updates:** When copying between objects/arrays (proxied or not), if a nested object
|
|
175
|
+
* exists in `dst` with the same constructor as the corresponding object in `src`, `copy`
|
|
176
|
+
* will recursively copy properties into the existing `dst` object instead of replacing it.
|
|
177
|
+
* This minimizes change notifications for reactive updates.
|
|
178
|
+
* - **Handles Proxies:** Can accept proxied or unproxied objects/arrays for both `dst` and `src`.
|
|
179
|
+
*
|
|
180
|
+
* @param dst - The destination object/array (proxied or unproxied).
|
|
181
|
+
* @param src - The source object/array (proxied or unproxied). It won't be modified.
|
|
182
|
+
* @param flags - Bitmask controlling copy behavior:
|
|
183
|
+
* - {@link MERGE}: Performs a partial update. Properties in `dst` not present in `src` are kept.
|
|
184
|
+
* `null`/`undefined` in `src` delete properties in `dst`. Handles partial array updates via object keys.
|
|
185
|
+
* - {@link SHALLOW}: Performs a shallow copy; when an array/object of the right type doesn't exist in `dst` yet, a reference to the array/object in `src` will be made, instead of creating a copy. If the array/object already exists, it won't be replaced (by a reference), but all items will be individually checked and copied like normal, keeping changes (and therefore UI updates) to a minimum.
|
|
186
|
+
* @template T - The type of the objects being copied.
|
|
187
|
+
* @throws Error if attempting to copy an array into a non-array or vice versa (unless {@link MERGE} is set, allowing for sparse array updates).
|
|
188
|
+
*
|
|
189
|
+
* @example Basic Copy
|
|
190
|
+
* ```typescript
|
|
191
|
+
* const source = proxy({ a: 1, b: { c: 2 } });
|
|
192
|
+
* const dest = proxy({ b: { d: 3 } });
|
|
193
|
+
* copy(dest, source);
|
|
194
|
+
* console.log(dest); // proxy({ a: 1, b: { c: 2 } })
|
|
195
|
+
* ```
|
|
196
|
+
*
|
|
197
|
+
* @example MERGE
|
|
198
|
+
* ```typescript
|
|
199
|
+
* const source = { b: { c: 99 }, d: undefined }; // d: undefined will delete
|
|
200
|
+
* const dest = proxy({ a: 1, b: { x: 5 }, d: 4 });
|
|
201
|
+
* copy(dest, source, MERGE);
|
|
202
|
+
* console.log(dest); // proxy({ a: 1, b: { c: 99, x: 5 } })
|
|
203
|
+
* ```
|
|
204
|
+
*
|
|
205
|
+
* @example Partial Array Update with MERGE
|
|
206
|
+
* ```typescript
|
|
207
|
+
* const messages = proxy(['msg1', 'msg2', 'msg3']);
|
|
208
|
+
* const update = { 1: 'updated msg2' }; // Update using object key as index
|
|
209
|
+
* copy(messages, update, MERGE);
|
|
210
|
+
* console.log(messages); // proxy(['msg1', 'updated msg2', 'msg3'])
|
|
211
|
+
* ```
|
|
212
|
+
*
|
|
213
|
+
* @example SHALLOW
|
|
214
|
+
* ```typescript
|
|
215
|
+
* const source = { nested: [1, 2] };
|
|
216
|
+
* const dest = {};
|
|
217
|
+
* copy(dest, source, SHALLOW);
|
|
218
|
+
* dest.nested.push(3);
|
|
219
|
+
* console.log(source.nested); // [1, 2, 3] (source was modified)
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
export declare function copy<T extends object>(dst: T, src: T, flags?: number): void;
|
|
223
|
+
/** Flag to {@link copy} causing it to use merge semantics. See {@link copy} for details. */
|
|
224
|
+
export declare const MERGE = 1;
|
|
225
|
+
/** Flag to {@link copy} and {@link clone} causing them to create a shallow copy (instead of the deep copy done by default).*/
|
|
226
|
+
export declare const SHALLOW = 2;
|
|
227
|
+
/**
|
|
228
|
+
* Clone an (optionally proxied) object or array.
|
|
229
|
+
*
|
|
230
|
+
* @param src The object or array to clone. If it is proxied, `clone` will subscribe to any changes to the (nested) data structure.
|
|
231
|
+
* @param flags
|
|
232
|
+
* - {@link SHALLOW}: Performs a shallow clone, meaning that only the top-level array or object will be copied, while object/array values will just be references to the original data in `src`.
|
|
233
|
+
* @template T - The type of the objects being copied.
|
|
234
|
+
* @returns A new unproxied array or object (of the same type as `src`), containing a deep (by default) copy of `src`.
|
|
386
235
|
*/
|
|
387
|
-
export declare function
|
|
236
|
+
export declare function clone<T extends object>(src: T, flags?: number): T;
|
|
388
237
|
/**
|
|
389
|
-
*
|
|
390
|
-
*
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
396
|
-
*
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
401
|
-
* for elements that are created as part of a larger (re)draw, to prevent
|
|
402
|
-
* all elements from individually animating on page creation.
|
|
403
|
-
* - If `name` is `"destroy"`, `value` should be a function that gets called
|
|
404
|
-
* with the element as its only argument, *instead of* the element being
|
|
405
|
-
* removed from the DOM (which the function will presumably need to do
|
|
406
|
-
* eventually). This can be used for a conceal animation.
|
|
407
|
-
* As a convenience, it's also possible to provide a string instead of
|
|
408
|
-
* a function, which will be added to the element as a CSS class, allowing
|
|
409
|
-
* for simple transitions. In this case, the DOM element in removed 2 seconds
|
|
410
|
-
* later (currently not configurable).
|
|
411
|
-
* Similar to `"create"` (and in this case doing anything else would make little
|
|
412
|
-
* sense), this only happens when the element being is the top-level element
|
|
413
|
-
* being removed from the DOM.
|
|
414
|
-
* - If `value` is a function, it is registered as an event handler for the
|
|
415
|
-
* `name` event.
|
|
416
|
-
* - If `name` is `"class"` or `"className"` and the `value` is an
|
|
417
|
-
* object, all keys of the object are either added or removed from `classList`,
|
|
418
|
-
* depending on whether `value` is true-like or false-like.
|
|
419
|
-
* - If `value` is a boolean *or* `name` is `"value"`, `"className"` or
|
|
420
|
-
* `"selectedIndex"`, it is set as a DOM element *property*.
|
|
421
|
-
* - If `name` is `"text"`, the `value` is set as the element's `textContent`.
|
|
422
|
-
* - If `name` is `"style"` and `value` is an object, each of its
|
|
423
|
-
* key/value pairs are assigned to the element's `.style`.
|
|
424
|
-
* - In other cases, the `value` is set as the `name` HTML *attribute*.
|
|
238
|
+
* Creates a reactive reference (`{ value: T }`-like object) to a specific value
|
|
239
|
+
* within a proxied object or array.
|
|
240
|
+
*
|
|
241
|
+
* This is primarily used for the `bind` property in {@link $} to create two-way data bindings
|
|
242
|
+
* with form elements, and for passing a reactive property to any of the {@link $} key-value pairs.
|
|
243
|
+
*
|
|
244
|
+
* Reading `ref.value` accesses the property from the underlying proxy (and subscribes the current scope).
|
|
245
|
+
* Assigning to `ref.value` updates the property in the underlying proxy (triggering reactive updates).
|
|
246
|
+
*
|
|
247
|
+
* @param target - The reactive proxy (created by {@link proxy}) containing the target property.
|
|
248
|
+
* @param index - The key (for objects) or index (for arrays) of the property to reference.
|
|
249
|
+
* @returns A reference object with a `value` property linked to the specified proxy property.
|
|
425
250
|
*
|
|
426
251
|
* @example
|
|
427
|
-
* ```
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
*
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
444
|
-
*
|
|
445
|
-
* click: myClickHandler,
|
|
446
|
-
* })
|
|
447
|
-
* })
|
|
252
|
+
* ```javascript
|
|
253
|
+
* const formData = proxy({ color: 'orange', velocity: 42 });
|
|
254
|
+
*
|
|
255
|
+
* // Usage with `bind`
|
|
256
|
+
* $('input', {
|
|
257
|
+
* type: 'text',
|
|
258
|
+
* // Creates a two-way binding between the input's value and formData.username
|
|
259
|
+
* bind: ref(formData, 'color')
|
|
260
|
+
* });
|
|
261
|
+
*
|
|
262
|
+
* // Usage as a dynamic property, causes a TextNode with just the name to be created and live-updated
|
|
263
|
+
* $('p:Selected color: ', {
|
|
264
|
+
* text: ref(formData, 'color'),
|
|
265
|
+
* $color: ref(formData, 'color')
|
|
266
|
+
* });
|
|
267
|
+
*
|
|
268
|
+
* // Changes are actually stored in formData - this causes logs like `{color: "Blue", velocity 42}`
|
|
269
|
+
* $(() => console.log(formData))
|
|
448
270
|
* ```
|
|
449
271
|
*/
|
|
450
|
-
export declare function
|
|
451
|
-
export declare function prop(props: object): void;
|
|
272
|
+
export declare function ref<T extends TargetType, K extends keyof T>(target: T, index: K): ValueRef<T[K]>;
|
|
452
273
|
/**
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
274
|
+
* The core function for building reactive user interfaces in Aberdeen. It creates and inserts new DOM elements
|
|
275
|
+
* and sets attributes/properties/event listeners on DOM elements. It does so in a reactive way, meaning that
|
|
276
|
+
* changes will be (mostly) undone when the current *scope* is destroyed or will be re-execute.
|
|
277
|
+
*
|
|
278
|
+
* @param {...(string | function | object | false | undefined | null)} args - Any number of arguments can be given. How they're interpreted depends on their types:
|
|
279
|
+
*
|
|
280
|
+
* - `string`: Strings can be used to create and insert new elements, set classnames for the *current* element, and add text to the current element.
|
|
281
|
+
* The format of a string is: **tag**? (`.` **class**)* (':' **text**)?
|
|
282
|
+
* meaning it consists of...
|
|
283
|
+
* - An optional HTML **tag**, something like `h1`. If present, a DOM element of that tag is created, and that element will be the *current* element for the rest of this `$` function execution.
|
|
284
|
+
* - Any number of CSS classes prefixed by `.` characters. These classes will be added to the *current* element.
|
|
285
|
+
* - Optional content **text** prefixed by a `:` character, ranging til the end of the string. This will be added as a TextNode to the *current* element.
|
|
286
|
+
* - `function`: When a function (without argument nor a return value) is passed in, it will be reactively executed in its own observe scope, preserving the *current element*. So any `$()` invocations within this function will create DOM elements with our *current* element as parent. If the function reads observable data, and that data is changed later on, the function we re-execute (after side effects, such as DOM modifications through `$`, have been cleaned - see also {@link clean}).
|
|
287
|
+
* - `object`: When an object is passed in, its key-value pairs are used to modify the *current* element in the following ways...
|
|
288
|
+
* - `{<attrName>: any}`: The common case is setting the value as an HTML attribute named key. So `{placeholder: "Your name"}` would add `placeholder="Your name"` to the current HTML element.
|
|
289
|
+
* - `{<propName>: boolean}` or `{value: any}` or `{selectedIndex: number}`: If the value is a boolean, or if the key is `value` or `selectedIndex`, it is set on the `current` element as a DOM property instead of an HTML attribute. For example `{checked: true}` would do `el.checked = true` for the *current* element.
|
|
290
|
+
* - `{".class": boolean}`: If the key starts with a `.` character, its either added to or removed from the *current* element as a CSS class, based on the truthiness of the value. So `{".hidden": hide}` would toggle the `hidden` CSS class.
|
|
291
|
+
* - `{<eventName>: function}`: If the value is a `function` it is set as an event listener for the event with the name given by the key. For example: `{click: myClickHandler}`.
|
|
292
|
+
* - `{$<styleProp>: value}`: If the key starts with a `$` character, set a CSS style property with the name of the rest of the key to the given value. Example: `{$backgroundColor: 'red'}`.
|
|
293
|
+
* - `{create: string}`: Add the value string as a CSS class to the *current* element, *after* the browser has finished doing a layout pass. This behavior only triggers when the scope setting the `create` is the top-level scope being (re-)run. This allows for creation transitions, without triggering the transitions for deeply nested elements being drawn as part of a larger component. The string may also contain multiple dot-separated CSS classes, such as `.fade.grow`.
|
|
294
|
+
* - `{destroy: string}`: When the *current* element is a top-level element to be removed (due to reactivity cleanup), actual removal from the DOM is delayed by 2 seconds, and in the mean time the value string is added as a CSS class to the element, allowing for a deletion transition. The string may also contain multiple dot-separated CSS classes, such as `.fade.shrink`.
|
|
295
|
+
* - `{create: function}` and `{destroy: function}`: The function is invoked when the *current* element is the top-level element being created/destroyed. It can be used for more involved creation/deletion animations. In case of `destroy`, the function is responsible for actually removing the element from the DOM (eventually). See `transitions.ts` in the Aberdeen source code for some examples.
|
|
296
|
+
* - `{bind: <obsValue>}`: Create a two-way binding element between the `value` property of the given observable (proxy) variable, and the *current* input element (`<input>`, `<select>` or `<textarea>`). This is often used together with {@link ref}, in order to use properties other than `.value`.
|
|
297
|
+
* - `{<any>: <obsvalue>}`: Create a new observe scope and read the `value` property of the given observable (proxy) variable from within it, and apply the contained value using any of the other rules in this list. Example:
|
|
298
|
+
* ```typescript
|
|
299
|
+
* const myColor = proxy('red');
|
|
300
|
+
* $('p:Test', {$color: myColor, click: () => myColor.value = 'yellow'})
|
|
301
|
+
* // Clicking the text will cause it to change color without recreating the <p> itself
|
|
302
|
+
* ```
|
|
303
|
+
* This is often used together with {@link ref}, in order to use properties other than `.value`.
|
|
304
|
+
* - `{text: string|number}`: Add the value as a `TextNode` to the *current* element.
|
|
305
|
+
* - `{html: string}`: Add the value as HTML to the *current* element. This should only be used in exceptional situations. And of course, beware of XSS.
|
|
306
|
+
* - `{element: Node}`: Add a pre-existing HTML `Node` to the *current* element.
|
|
307
|
+
*
|
|
308
|
+
*
|
|
309
|
+
* @example Create Element
|
|
310
|
+
* ```typescript
|
|
311
|
+
* $('button.secondary.outline:Submit', {
|
|
312
|
+
* disabled: true,
|
|
313
|
+
* click: () => console.log('Clicked!'),
|
|
314
|
+
* $color: 'red'
|
|
315
|
+
* });
|
|
316
|
+
* ```
|
|
317
|
+
*
|
|
318
|
+
* @example Nested Elements & Reactive Scope
|
|
319
|
+
* ```typescript
|
|
320
|
+
* const state = proxy({ count: 0 });
|
|
321
|
+
* $('div', () => { // Outer element
|
|
322
|
+
* // This scope re-renders when state.count changes
|
|
323
|
+
* $('p:Count is ${state.count}`);
|
|
324
|
+
* $('button:Increment', { click: () => state.count++ });
|
|
325
|
+
* });
|
|
326
|
+
* ```
|
|
327
|
+
*
|
|
328
|
+
* @example Two-way Binding
|
|
329
|
+
* ```typescript
|
|
330
|
+
* const user = proxy({ name: '' });
|
|
331
|
+
* $('input', { placeholder: 'Name', bind: ref(user, 'name') });
|
|
332
|
+
* $('h3', () => { // Reactive scope
|
|
333
|
+
* $(`:Hello ${user.name || 'stranger'}`);
|
|
334
|
+
* });
|
|
335
|
+
* ```
|
|
336
|
+
*
|
|
337
|
+
* @example Conditional Rendering
|
|
338
|
+
* ```typescript
|
|
339
|
+
* const show = proxy(false);
|
|
340
|
+
* $('button', { click: () => show.value = !show.value }, () => $(show.value ? ':Hide' : ':Show'));
|
|
341
|
+
* $(() => { // Reactive scope
|
|
342
|
+
* if (show.value) {
|
|
343
|
+
* $('p:Details are visible!');
|
|
344
|
+
* }
|
|
345
|
+
* });
|
|
346
|
+
* ```
|
|
458
347
|
*/
|
|
459
|
-
export declare function
|
|
348
|
+
export declare function $(...args: (string | null | undefined | false | (() => void) | Record<string, any>)[]): void;
|
|
460
349
|
/**
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
*
|
|
350
|
+
* Inserts CSS rules into the document, optionally scoping them with a unique class name.
|
|
351
|
+
*
|
|
352
|
+
* Takes a JavaScript object representation of CSS rules. camelCased property keys are
|
|
353
|
+
* converted to kebab-case (e.g., `fontSize` becomes `font-size`).
|
|
354
|
+
*
|
|
355
|
+
* @param style - An object where keys are CSS selectors (or camelCased properties) and values are
|
|
356
|
+
* CSS properties or nested rule objects.
|
|
357
|
+
* - Selectors are usually combined as a descendant-relationship (meaning just a space character) with their parent selector.
|
|
358
|
+
* - In case a selector contains a `&`, that character will be replaced by the parent selector.
|
|
359
|
+
* - Selectors will be split on `,` characters, each combining with the parent selector with *or* semantics.
|
|
360
|
+
* - Selector starting with `'@'` define at-rules like media queries. They may be nested within regular selectors.
|
|
361
|
+
* @param global - If `true`, styles are inserted globally without prefixing.
|
|
362
|
+
* If `false` (default), all selectors are prefixed with a unique generated
|
|
363
|
+
* class name (e.g., `.AbdStl1`) to scope the styles.
|
|
364
|
+
* @returns The unique class name prefix used for scoping (e.g., `.AbdStl1`), or an empty string
|
|
365
|
+
* if `global` was `true`. Use this prefix with {@link $} to apply the styles.
|
|
366
|
+
*
|
|
367
|
+
* @example Scoped Styles
|
|
368
|
+
* ```typescript
|
|
369
|
+
* const scopeClass = insertCss({
|
|
370
|
+
* color: 'red',
|
|
371
|
+
* padding: '10px',
|
|
372
|
+
* '&:hover': { // Use '&' for the root scoped selector
|
|
373
|
+
* backgroundColor: '#535'
|
|
374
|
+
* },
|
|
375
|
+
* '.child-element': { // Nested selector
|
|
376
|
+
* fontWeight: 'bold'
|
|
377
|
+
* },
|
|
378
|
+
* '@media (max-width: 600px)': {
|
|
379
|
+
* padding: '5px'
|
|
380
|
+
* }
|
|
381
|
+
* });
|
|
382
|
+
* // scopeClass might be ".AbdStl1"
|
|
383
|
+
*
|
|
384
|
+
* // Apply the styles
|
|
385
|
+
* $(scopeClass, () => { // Add class to the div
|
|
386
|
+
* $(`:Scoped content`);
|
|
387
|
+
* $('div.child-element:Child'); // .AbdStl1 .child-element rule applies
|
|
388
|
+
* });
|
|
389
|
+
* ```
|
|
390
|
+
*
|
|
391
|
+
* @example Global Styles
|
|
392
|
+
* ```typescript
|
|
393
|
+
* insertCss({
|
|
394
|
+
* '*': {
|
|
395
|
+
* fontFamily: 'monospace',
|
|
396
|
+
* },
|
|
397
|
+
* 'a': {
|
|
398
|
+
* textDecoration: 'none',
|
|
399
|
+
* color: "#107ab0",
|
|
400
|
+
* }
|
|
401
|
+
* }, true); // Pass true for global
|
|
402
|
+
*
|
|
403
|
+
* $('a:Styled link');
|
|
404
|
+
* ```
|
|
464
405
|
*/
|
|
465
|
-
export declare function
|
|
406
|
+
export declare function insertCss(style: object, global?: boolean): string;
|
|
466
407
|
/**
|
|
467
|
-
*
|
|
468
|
-
* during
|
|
469
|
-
*
|
|
470
|
-
* no cause the outer function to rerun.
|
|
408
|
+
* Sets a custom error handler function for errors that occur asynchronously
|
|
409
|
+
* within reactive scopes (e.g., during updates triggered by proxy changes in
|
|
410
|
+
* {@link observe} or {@link $} render functions).
|
|
471
411
|
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
* @example
|
|
475
|
-
* ```
|
|
476
|
-
* let number = new Store(0)
|
|
477
|
-
* let doubled = new Store()
|
|
478
|
-
* setInterval(() => number.set(0|Math.random()*100)), 1000)
|
|
412
|
+
* The default handler logs the error to `console.error` and adds a simple
|
|
413
|
+
* 'Error' message div to the DOM at the location where the error occurred (if possible).
|
|
479
414
|
*
|
|
480
|
-
*
|
|
481
|
-
*
|
|
482
|
-
* })
|
|
415
|
+
* Your handler can provide custom logging, UI feedback, or suppress the default
|
|
416
|
+
* error message.
|
|
483
417
|
*
|
|
484
|
-
*
|
|
485
|
-
*
|
|
418
|
+
* @param handler - A function that accepts the `Error` object.
|
|
419
|
+
* - Return `false` to prevent adding an error message to the DOM.
|
|
420
|
+
* - Return `true` or `undefined` (or throw) to allow the error messages to be added to the DOM.
|
|
421
|
+
*
|
|
422
|
+
* @example Custom Logging and Suppressing Default Message
|
|
423
|
+
* ```typescript
|
|
424
|
+
* setErrorHandler(error => {
|
|
425
|
+
* console.warn('Aberdeen render error:', error.message);
|
|
426
|
+
* // Log to error reporting service
|
|
427
|
+
* // myErrorReporter.log(error);
|
|
428
|
+
*
|
|
429
|
+
* try {
|
|
430
|
+
* // Attempt to show a custom message in the UI
|
|
431
|
+
* $('div.error-display:Oops, something went wrong!');
|
|
432
|
+
* } catch (e) {
|
|
433
|
+
* // Ignore errors during error handling itself
|
|
434
|
+
* }
|
|
435
|
+
*
|
|
436
|
+
* return false; // Suppress default console log and DOM error message
|
|
437
|
+
* });
|
|
438
|
+
*
|
|
439
|
+
* // Cause an error within a render scope.
|
|
440
|
+
* $('div.box', () => {
|
|
441
|
+
* noSuchFunction();
|
|
486
442
|
* })
|
|
443
|
+
* ```
|
|
487
444
|
*/
|
|
488
|
-
export declare function
|
|
445
|
+
export declare function setErrorHandler(handler?: (error: Error) => boolean | undefined): void;
|
|
489
446
|
/**
|
|
490
|
-
*
|
|
491
|
-
*
|
|
492
|
-
*
|
|
493
|
-
*
|
|
494
|
-
*
|
|
495
|
-
*
|
|
496
|
-
*
|
|
447
|
+
* Gets the parent DOM `Element` where nodes created by {@link $} would currently be inserted.
|
|
448
|
+
*
|
|
449
|
+
* This is context-dependent based on the current reactive scope (e.g., inside a {@link mount}
|
|
450
|
+
* call or a {@link $} element's render function).
|
|
451
|
+
*
|
|
452
|
+
* **Note:** While this provides access to the DOM element, directly manipulating it outside
|
|
453
|
+
* of Aberdeen's control is generally discouraged. Prefer declarative updates using {@link $}.
|
|
454
|
+
*
|
|
455
|
+
* @returns The current parent `Element` for DOM insertion.
|
|
456
|
+
*
|
|
457
|
+
* @example Get parent for attaching a third-party library
|
|
458
|
+
* ```typescript
|
|
459
|
+
* function thirdPartyLibInit(parentElement) {
|
|
460
|
+
* parentElement.innerHTML = "This element is managed by a <em>third party</em> lib."
|
|
461
|
+
* }
|
|
462
|
+
*
|
|
463
|
+
* $('div.box', () => {
|
|
464
|
+
* // Get the div.box element just created
|
|
465
|
+
* const containerElement = getParentElement();
|
|
466
|
+
* thirdPartyLibInit(containerElement);
|
|
467
|
+
* });
|
|
468
|
+
* ```
|
|
497
469
|
*/
|
|
498
|
-
export declare function
|
|
470
|
+
export declare function getParentElement(): Element;
|
|
499
471
|
/**
|
|
500
|
-
*
|
|
501
|
-
|
|
502
|
-
* @param func - The function to be (repeatedly) executed, possibly adding DOM elements to `parentElement`.
|
|
503
|
-
* @param parentElement - A DOM element that will be used as the parent element for calls to `node`.
|
|
504
|
-
* @returns The mount id (usable for `unmount`) if this is a top-level mount.
|
|
472
|
+
* Registers a cleanup function to be executed just before the current reactive scope
|
|
473
|
+
* is destroyed or redraws.
|
|
505
474
|
*
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
475
|
+
* This is useful for releasing resources, removing manual event listeners, or cleaning up
|
|
476
|
+
* side effects associated with the scope. Cleaners are run in reverse order of registration.
|
|
477
|
+
*
|
|
478
|
+
* Scopes are created by functions like {@link observe}, {@link mount}, {@link $} (when given a render function),
|
|
479
|
+
* and internally by constructs like {@link onEach}.
|
|
480
|
+
*
|
|
481
|
+
* @param cleaner - The function to execute during cleanup.
|
|
510
482
|
*
|
|
511
|
-
*
|
|
512
|
-
*
|
|
483
|
+
* @example Maintaing a sum for a changing array
|
|
484
|
+
* ```typescript
|
|
485
|
+
* const myArray = proxy([3, 5, 10]);
|
|
486
|
+
* let sum = proxy(0);
|
|
487
|
+
*
|
|
488
|
+
* // Show the array items and maintain the sum
|
|
489
|
+
* onEach(myArray, (item, index) => {
|
|
490
|
+
* $(`code:${index}→${item}`);
|
|
491
|
+
* // We'll update sum.value using peek, as += first does a read, but
|
|
492
|
+
* // we don't want to subscribe.
|
|
493
|
+
* peek(() => sum.value += item);
|
|
494
|
+
* // Clean gets called before each rerun for a certain item index
|
|
495
|
+
* // No need for peek here, as the clean code doesn't run in an
|
|
496
|
+
* // observe scope.
|
|
497
|
+
* clean(() => sum.value -= item);
|
|
513
498
|
* })
|
|
499
|
+
*
|
|
500
|
+
* // Show the sum
|
|
501
|
+
* $('h1', {text: sum});
|
|
502
|
+
*
|
|
503
|
+
* // Make random changes to the array
|
|
504
|
+
* const rnd = () => 0|(Math.random()*20);
|
|
505
|
+
* setInterval(() => myArray[rnd()] = rnd(), 1000);
|
|
514
506
|
* ```
|
|
507
|
+
*/
|
|
508
|
+
export declare function clean(cleaner: () => void): void;
|
|
509
|
+
/**
|
|
510
|
+
* Creates a reactive scope that automatically re-executes the provided function
|
|
511
|
+
* whenever any proxied data (created by {@link proxy}) read during its last execution changes, storing
|
|
512
|
+
* its return value in an observable.
|
|
513
|
+
*
|
|
514
|
+
* Updates are batched and run asynchronously shortly after the changes occur.
|
|
515
|
+
* Use {@link clean} to register cleanup logic for the scope.
|
|
516
|
+
* Use {@link peek} or {@link unproxy} within the function to read proxied data without subscribing to it.
|
|
517
|
+
*
|
|
518
|
+
* @param func - The function to execute reactively. Any DOM manipulations should typically
|
|
519
|
+
* be done using {@link $} within this function. Its return value will be made available as an
|
|
520
|
+
* observable returned by the `observe()` function.
|
|
521
|
+
* @returns An observable object, with its `value` property containing whatever the last run of `func` returned.
|
|
522
|
+
*
|
|
523
|
+
* @example Observation creating a UI components
|
|
524
|
+
* ```typescript
|
|
525
|
+
* const data = proxy({ user: 'Frank', notifications: 42 });
|
|
526
|
+
*
|
|
527
|
+
* $('main', () => {
|
|
528
|
+
* console.log('Welcome');
|
|
529
|
+
* $('h3:Welcome, ' + data.user); // Reactive text
|
|
515
530
|
*
|
|
516
|
-
*
|
|
531
|
+
* observe(() => {
|
|
532
|
+
* // When data.notifications changes, only this inner scope reruns,
|
|
533
|
+
* // leaving the `<p>Welcome, ..</p>` untouched.
|
|
534
|
+
* console.log('Notifications');
|
|
535
|
+
* $('code.notification-badge:' + data.notifications);
|
|
536
|
+
* $('a:Notify!', {click: () => data.notifications++});
|
|
537
|
+
* });
|
|
538
|
+
* });
|
|
517
539
|
* ```
|
|
518
|
-
*
|
|
519
|
-
*
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
*
|
|
527
|
-
*
|
|
528
|
-
*
|
|
529
|
-
* node('input', {type: 'color', value: '#ffffff'}, colors.ref(selected.get()))
|
|
530
|
-
* })
|
|
531
|
-
*
|
|
532
|
-
* observe(() => {
|
|
533
|
-
* // This function will rerun when `selected` or the selected color changes.
|
|
534
|
-
* // It will change the <body> background-color.
|
|
535
|
-
* prop({style: {backgroundColor: colors.get(selected.get()) || 'white'}})
|
|
536
|
-
* })
|
|
540
|
+
*
|
|
541
|
+
* ***Note*** that the above could just as easily be done using `$(func)` instead of `observe(func)`.
|
|
542
|
+
*
|
|
543
|
+
* @example Observation with return value
|
|
544
|
+
* ```typescript
|
|
545
|
+
* const counter = proxy(0);
|
|
546
|
+
* setInterval(() => counter.value++, 1000);
|
|
547
|
+
* const double = observe(() => counter.value * 2);
|
|
548
|
+
*
|
|
549
|
+
* $('h3', () => {
|
|
550
|
+
* $(`:counter=${counter.value} double=${double.value}`);
|
|
537
551
|
* })
|
|
538
552
|
* ```
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
* Unmount one specific or all top-level mounts or observes, meaning those that were created outside of the scope
|
|
543
|
-
* of any other mount or observe.
|
|
544
|
-
* @param id Optional mount number (as returned by `mount`, `observe` or `immediateObserve`). If `undefined`, unmount all.
|
|
553
|
+
*
|
|
554
|
+
* @overload
|
|
555
|
+
* @param func Func without a return value.
|
|
545
556
|
*/
|
|
546
|
-
export declare function
|
|
547
|
-
/**
|
|
557
|
+
export declare function observe<T extends (DatumType | void)>(func: () => T): ValueRef<T>;
|
|
558
|
+
/**
|
|
559
|
+
* Similar to {@link observe}, creates a reactive scope that re-executes the function
|
|
560
|
+
* when its proxied dependencies change.
|
|
561
|
+
*
|
|
562
|
+
* **Difference:** Updates run **synchronously and immediately** after the proxy modification
|
|
563
|
+
* that triggered the update occurs.
|
|
564
|
+
*
|
|
565
|
+
* **Caution:** Use sparingly. Immediate execution bypasses Aberdeen's usual batching and
|
|
566
|
+
* ordering optimizations, which can lead to performance issues or observing inconsistent
|
|
567
|
+
* intermediate states if multiple related updates are applied sequentially.
|
|
568
|
+
* Prefer {@link observe} or {@link $} for most use cases.
|
|
569
|
+
*
|
|
570
|
+
* @param func - The function to execute reactively and synchronously.
|
|
548
571
|
*
|
|
549
|
-
* @param func Function to be executed immediately.
|
|
550
|
-
* @returns Whatever `func()` returns.
|
|
551
572
|
* @example
|
|
573
|
+
* ```javascript
|
|
574
|
+
* const state = proxy({ single: 'A' });
|
|
575
|
+
*
|
|
576
|
+
* immediateObserve(() => {
|
|
577
|
+
* state.double = state.single + state.single
|
|
578
|
+
* });
|
|
579
|
+
* console.log(state.double); // 'AA'
|
|
580
|
+
*
|
|
581
|
+
* state.single = 'B';
|
|
582
|
+
* // Synchronously:
|
|
583
|
+
* console.log(state.double); // 'BB'
|
|
552
584
|
* ```
|
|
553
|
-
|
|
585
|
+
*/
|
|
586
|
+
export declare function immediateObserve(func: () => void): void;
|
|
587
|
+
/**
|
|
588
|
+
* Attaches a reactive Aberdeen UI fragment to an existing DOM element. Without the use of
|
|
589
|
+
* this function, {@link $} will assume `document.body` as its root.
|
|
554
590
|
*
|
|
555
|
-
*
|
|
591
|
+
* It creates a top-level reactive scope associated with the `parentElement`. The provided
|
|
592
|
+
* function `func` is executed immediately within this scope. Any proxied data read by `func`
|
|
593
|
+
* will cause it to re-execute when the data changes, updating the DOM elements created within it.
|
|
556
594
|
*
|
|
557
|
-
*
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
595
|
+
* Calls to {@link $} inside `func` will append nodes to `parentElement`.
|
|
596
|
+
* You can nest {@link observe} or other {@link $} scopes within `func`.
|
|
597
|
+
* Use {@link unmountAll} to clean up all mounted scopes and their DOM nodes.
|
|
598
|
+
*
|
|
599
|
+
* Mounting scopes happens reactively, meaning that if this function is called from within another
|
|
600
|
+
* ({@link observe} or {@link $} or {@link mount}) scope that gets cleaned up, so will the mount.
|
|
601
|
+
*
|
|
602
|
+
* @param parentElement - The native DOM `Element` to which the UI fragment will be appended.
|
|
603
|
+
* @param func - The function that defines the UI fragment, typically containing calls to {@link $}.
|
|
604
|
+
*
|
|
605
|
+
* @example Basic Mount
|
|
606
|
+
* ```javascript
|
|
607
|
+
* // Create a pre-existing DOM structure (without Aberdeen)
|
|
608
|
+
* document.body.innerHTML = `<h3>Static content <span id="title-extra"></span></h3><div class="box" id="app-root"></div>`;
|
|
609
|
+
*
|
|
610
|
+
* import { mount, $, proxy } from 'aberdeen';
|
|
611
|
+
*
|
|
612
|
+
* const runTime = proxy(0);
|
|
613
|
+
* setInterval(() => runTime.value++, 1000);
|
|
614
|
+
*
|
|
615
|
+
* mount(document.getElementById('app-root'), () => {
|
|
616
|
+
* $('h4:Aberdeen App');
|
|
617
|
+
* $(`p:Run time: ${runTime.value}s`);
|
|
618
|
+
* // Conditionally render some content somewhere else in the static page
|
|
619
|
+
* if (runTime.value&1) {
|
|
620
|
+
* mount(document.getElementById('title-extra'), () =>
|
|
621
|
+
* $(`i:(${runTime.value}s)`)
|
|
622
|
+
* );
|
|
623
|
+
* }
|
|
624
|
+
* });
|
|
625
|
+
* ```
|
|
626
|
+
*
|
|
627
|
+
* Note how the inner mount behaves reactively as well, automatically unmounting when it's parent observer scope re-runs.
|
|
628
|
+
*/
|
|
629
|
+
export declare function mount(parentElement: Element, func: () => void): void;
|
|
630
|
+
/**
|
|
631
|
+
* Removes all Aberdeen-managed DOM nodes and stops all active reactive scopes
|
|
632
|
+
* (created by {@link mount}, {@link observe}, {@link $} with functions, etc.).
|
|
633
|
+
*
|
|
634
|
+
* This effectively cleans up the entire Aberdeen application state.
|
|
635
|
+
*/
|
|
636
|
+
export declare function unmountAll(): void;
|
|
637
|
+
/**
|
|
638
|
+
* Executes a function *without* creating subscriptions in the current reactive scope, and returns its result.
|
|
639
|
+
*
|
|
640
|
+
* This is useful when you need to access reactive data inside a reactive scope (like {@link observe})
|
|
641
|
+
* but do not want changes to that specific data to trigger a re-execute of the scope.
|
|
642
|
+
*
|
|
643
|
+
* @template T The type of the return value of your function.
|
|
644
|
+
*
|
|
645
|
+
* @param func - The function to execute without creating subscriptions.
|
|
646
|
+
* @returns Whatever `func` returns.
|
|
647
|
+
*
|
|
648
|
+
* @example Peeking within observe
|
|
649
|
+
* ```typescript
|
|
650
|
+
* const data = proxy({ a: 1, b: 2 });
|
|
651
|
+
* observe(() => {
|
|
652
|
+
* // re-executes only when data.a changes, because data.b is peeked.
|
|
653
|
+
* const b = peek(() => data.b);
|
|
654
|
+
* console.log(`A is ${data.a}, B was ${b} when A changed.`);
|
|
655
|
+
* });
|
|
656
|
+
* data.b = 3; // Does not trigger console.log
|
|
657
|
+
* data.a = 2; // Triggers console.log (logs "A is 2, B was 3 when A changed.")
|
|
562
658
|
* ```
|
|
563
659
|
*
|
|
564
|
-
* In the above example `store.get(0)` could be replaced with `store.peek(0)` to achieve the
|
|
565
|
-
* same result without `peek()` wrapping everything. There is no non-subscribing equivalent
|
|
566
|
-
* for `count()` however.
|
|
567
660
|
*/
|
|
568
661
|
export declare function peek<T>(func: () => T): T;
|
|
662
|
+
/** When using an object as `source`. */
|
|
663
|
+
export declare function map<IN, OUT>(source: Record<string | symbol, IN>, func: (value: IN, index: string | symbol) => undefined | OUT): Record<string | symbol, OUT>;
|
|
664
|
+
/** When using an array as `source`. */
|
|
665
|
+
export declare function map<IN, OUT>(source: Array<IN>, func: (value: IN, index: number) => undefined | OUT): Array<OUT>;
|
|
666
|
+
/** When using an array as `source`. */
|
|
667
|
+
export declare function multiMap<IN, OUT extends {
|
|
668
|
+
[key: string | symbol]: DatumType;
|
|
669
|
+
}>(source: Array<IN>, func: (value: IN, index: number) => OUT | undefined): OUT;
|
|
670
|
+
/** When using an object as `source`. */
|
|
671
|
+
export declare function multiMap<K extends string | number | symbol, IN, OUT extends {
|
|
672
|
+
[key: string | symbol]: DatumType;
|
|
673
|
+
}>(source: Record<K, IN>, func: (value: IN, index: K) => OUT | undefined): OUT;
|
|
674
|
+
/** When using an object as `array`. */
|
|
675
|
+
export declare function partition<OUT_K extends string | number | symbol, IN_V>(source: IN_V[], func: (value: IN_V, key: number) => undefined | OUT_K | OUT_K[]): Record<OUT_K, Record<number, IN_V>>;
|
|
676
|
+
/** When using an object as `source`. */
|
|
677
|
+
export declare function partition<IN_K extends string | number | symbol, OUT_K extends string | number | symbol, IN_V>(source: Record<IN_K, IN_V>, func: (value: IN_V, key: IN_K) => undefined | OUT_K | OUT_K[]): Record<OUT_K, Record<IN_K, IN_V>>;
|
|
569
678
|
/**
|
|
570
|
-
*
|
|
571
|
-
*
|
|
679
|
+
* Renders a live, recursive dump of a proxied data structure (or any value)
|
|
680
|
+
* into the DOM at the current {@link $} insertion point.
|
|
681
|
+
*
|
|
682
|
+
* Uses `<ul>` and `<li>` elements to display object properties and array items.
|
|
683
|
+
* Updates reactively if the dumped data changes. Primarily intended for debugging purposes.
|
|
684
|
+
*
|
|
685
|
+
* @param data - The proxied data structure (or any value) to display.
|
|
686
|
+
* @returns The original `data` argument, allowing for chaining.
|
|
687
|
+
* @template T - The type of the data being dumped.
|
|
688
|
+
*
|
|
689
|
+
* @example Dumping reactive state
|
|
690
|
+
* ```typescript
|
|
691
|
+
* import { $, proxy, dump } from 'aberdeen';
|
|
692
|
+
*
|
|
693
|
+
* const state = proxy({
|
|
694
|
+
* user: { name: 'Frank', kids: 1 },
|
|
695
|
+
* items: ['a', 'b']
|
|
696
|
+
* });
|
|
697
|
+
*
|
|
698
|
+
* $('h2:Live State Dump');
|
|
699
|
+
* dump(state);
|
|
700
|
+
*
|
|
701
|
+
* // Change state later, the dump in the DOM will update
|
|
702
|
+
* setTimeout(() => { state.user.kids++; state.items.push('c'); }, 2000);
|
|
703
|
+
* ```
|
|
572
704
|
*/
|
|
573
|
-
export declare function
|
|
705
|
+
export declare function dump<T>(data: T): T;
|
|
706
|
+
declare global {
|
|
707
|
+
interface String {
|
|
708
|
+
replaceAll(from: string, to: string): string;
|
|
709
|
+
}
|
|
710
|
+
}
|