aberdeen 1.17.0 → 2.0.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.
Files changed (139) hide show
  1. package/dist/src/aberdeen.d.ts +928 -944
  2. package/dist/src/aberdeen.js +1693 -1704
  3. package/dist/src/aberdeen.js.map +3 -3
  4. package/dist/src/index.d.ts +12 -0
  5. package/dist/src/index.js +11 -0
  6. package/dist/src/index.js.map +10 -0
  7. package/dist/src/prediction.d.ts +7 -4
  8. package/dist/src/prediction.js +18 -23
  9. package/dist/src/prediction.js.map +3 -3
  10. package/dist/src/route.d.ts +112 -99
  11. package/dist/src/route.js +254 -254
  12. package/dist/src/route.js.map +3 -3
  13. package/dist/src/server-dom.d.ts +158 -0
  14. package/dist/src/server-dom.js +458 -0
  15. package/dist/src/server-dom.js.map +10 -0
  16. package/dist/src/server.d.ts +55 -0
  17. package/dist/src/server.js +25 -0
  18. package/dist/src/server.js.map +10 -0
  19. package/dist/src/transitions.js +7 -4
  20. package/dist/src/transitions.js.map +3 -3
  21. package/dist/tests/environment.d.ts +24 -0
  22. package/dist/tests/{fakedom.js → environment.js} +239 -288
  23. package/dist/tests/environment.js.map +11 -0
  24. package/dist/tests/helpers.d.ts +15 -3
  25. package/dist/tests/helpers.js +277 -306
  26. package/dist/tests/helpers.js.map +6 -5
  27. package/dist-docs/Tutorial/index.html +30 -30
  28. package/dist-docs/aberdeen/Aberdeen/index.html +350 -0
  29. package/dist-docs/aberdeen/InitOptions/index.html +4 -0
  30. package/dist-docs/aberdeen/KeyToString/index.html +2 -0
  31. package/dist-docs/aberdeen/PromiseProxy/index.html +6 -6
  32. package/dist-docs/aberdeen/SortKeyType/index.html +2 -0
  33. package/dist-docs/aberdeen/TargetType/index.html +2 -0
  34. package/dist-docs/aberdeen/ValueRef/index.html +2 -0
  35. package/dist-docs/aberdeen/WindowLike/index.html +5 -0
  36. package/dist-docs/aberdeen/{clone → createA}/index.html +10 -5
  37. package/dist-docs/aberdeen/index.html +13 -54
  38. package/dist-docs/assets/aberdeen/aberdeen.d.ts +928 -944
  39. package/dist-docs/assets/aberdeen/aberdeen.js +1693 -1704
  40. package/dist-docs/assets/aberdeen/aberdeen.js.map +3 -3
  41. package/dist-docs/assets/aberdeen/index.d.ts +12 -0
  42. package/dist-docs/assets/aberdeen/index.js +11 -0
  43. package/dist-docs/assets/aberdeen/index.js.map +10 -0
  44. package/dist-docs/assets/aberdeen/prediction.d.ts +7 -4
  45. package/dist-docs/assets/aberdeen/prediction.js +18 -23
  46. package/dist-docs/assets/aberdeen/prediction.js.map +3 -3
  47. package/dist-docs/assets/aberdeen/route.d.ts +112 -99
  48. package/dist-docs/assets/aberdeen/route.js +254 -254
  49. package/dist-docs/assets/aberdeen/route.js.map +3 -3
  50. package/dist-docs/assets/aberdeen/server-dom.d.ts +158 -0
  51. package/dist-docs/assets/aberdeen/server-dom.js +458 -0
  52. package/dist-docs/assets/aberdeen/server-dom.js.map +10 -0
  53. package/dist-docs/assets/aberdeen/server.d.ts +55 -0
  54. package/dist-docs/assets/aberdeen/server.js +25 -0
  55. package/dist-docs/assets/aberdeen/server.js.map +10 -0
  56. package/dist-docs/assets/aberdeen/transitions.js +7 -4
  57. package/dist-docs/assets/aberdeen/transitions.js.map +3 -3
  58. package/dist-docs/assets/navigation.js +1 -1
  59. package/dist-docs/assets/search.js +1 -1
  60. package/dist-docs/dispatcher/Dispatcher/index.html +5 -6
  61. package/dist-docs/dispatcher/MATCH_FAILED/index.html +2 -2
  62. package/dist-docs/dispatcher/MATCH_REST/index.html +2 -2
  63. package/dist-docs/dispatcher/index.html +2 -2
  64. package/dist-docs/hierarchy.html +1 -1
  65. package/dist-docs/index-1/index.html +2 -0
  66. package/dist-docs/index.html +2 -2
  67. package/dist-docs/media/CHANGELOG.md +14 -2
  68. package/dist-docs/modules.html +1 -1
  69. package/dist-docs/prediction/applyCanon/index.html +4 -3
  70. package/dist-docs/prediction/applyPrediction/index.html +4 -3
  71. package/dist-docs/prediction/index.html +2 -2
  72. package/dist-docs/route/Route/index.html +9 -9
  73. package/dist-docs/route/RouteApi/index.html +60 -0
  74. package/dist-docs/route/index.html +6 -15
  75. package/dist-docs/route/init/index.html +5 -0
  76. package/dist-docs/server/RenderToStringOptions/index.html +6 -0
  77. package/dist-docs/server/RenderToStringResult/index.html +6 -0
  78. package/dist-docs/server/index.html +4 -0
  79. package/dist-docs/server/renderToString/index.html +6 -0
  80. package/dist-docs/sitemap.xml +51 -155
  81. package/dist-docs/transitions/grow/index.html +2 -2
  82. package/dist-docs/transitions/index.html +2 -2
  83. package/dist-docs/transitions/shrink/index.html +2 -2
  84. package/package.json +17 -7
  85. package/skill/SKILL.md +28 -28
  86. package/skill/aberdeen.md +471 -3448
  87. package/skill/dispatcher.md +6 -16
  88. package/skill/prediction.md +17 -5
  89. package/skill/route.md +95 -77
  90. package/skill/transitions.md +3 -3
  91. package/src/aberdeen.ts +1226 -740
  92. package/src/index.ts +13 -0
  93. package/src/prediction.ts +25 -24
  94. package/src/route.ts +192 -142
  95. package/src/server-dom.ts +508 -0
  96. package/src/server.ts +74 -0
  97. package/src/transitions.ts +9 -3
  98. package/dist/tests/fakedom.d.ts +0 -9
  99. package/dist/tests/fakedom.js.map +0 -10
  100. package/dist-docs/aberdeen/A/index.html +0 -115
  101. package/dist-docs/aberdeen/CUSTOM_DUMP/index.html +0 -7
  102. package/dist-docs/aberdeen/NO_COPY/index.html +0 -2
  103. package/dist-docs/aberdeen/OPAQUE/index.html +0 -12
  104. package/dist-docs/aberdeen/clean/index.html +0 -11
  105. package/dist-docs/aberdeen/copy/index.html +0 -22
  106. package/dist-docs/aberdeen/count/index.html +0 -7
  107. package/dist-docs/aberdeen/cssVars/index.html +0 -11
  108. package/dist-docs/aberdeen/darkMode/index.html +0 -9
  109. package/dist-docs/aberdeen/default/index.html +0 -341
  110. package/dist-docs/aberdeen/derive/index.html +0 -18
  111. package/dist-docs/aberdeen/disableCreateDestroy/index.html +0 -6
  112. package/dist-docs/aberdeen/dump/index.html +0 -11
  113. package/dist-docs/aberdeen/insertCss/index.html +0 -30
  114. package/dist-docs/aberdeen/insertGlobalCss/index.html +0 -19
  115. package/dist-docs/aberdeen/invertString/index.html +0 -13
  116. package/dist-docs/aberdeen/isEmpty/index.html +0 -12
  117. package/dist-docs/aberdeen/map/index.html +0 -26
  118. package/dist-docs/aberdeen/merge/index.html +0 -11
  119. package/dist-docs/aberdeen/mount/index.html +0 -17
  120. package/dist-docs/aberdeen/multiMap/index.html +0 -28
  121. package/dist-docs/aberdeen/onEach/index.html +0 -19
  122. package/dist-docs/aberdeen/partition/index.html +0 -36
  123. package/dist-docs/aberdeen/peek/index.html +0 -40
  124. package/dist-docs/aberdeen/proxy/index.html +0 -35
  125. package/dist-docs/aberdeen/ref/index.html +0 -13
  126. package/dist-docs/aberdeen/runQueue/index.html +0 -13
  127. package/dist-docs/aberdeen/setErrorHandler/index.html +0 -16
  128. package/dist-docs/aberdeen/setSpacingCssVars/index.html +0 -8
  129. package/dist-docs/aberdeen/unmountAll/index.html +0 -5
  130. package/dist-docs/aberdeen/unproxy/index.html +0 -11
  131. package/dist-docs/route/back/index.html +0 -4
  132. package/dist-docs/route/current/index.html +0 -2
  133. package/dist-docs/route/go/index.html +0 -14
  134. package/dist-docs/route/interceptLinks/index.html +0 -8
  135. package/dist-docs/route/matchCurrent/index.html +0 -10
  136. package/dist-docs/route/persistScroll/index.html +0 -6
  137. package/dist-docs/route/push/index.html +0 -6
  138. package/dist-docs/route/setLog/index.html +0 -3
  139. package/dist-docs/route/up/index.html +0 -5
package/skill/aberdeen.md CHANGED
@@ -1,4 +1,4 @@
1
- [**Aberdeen v1.17.0**](README.md)
1
+ [**Aberdeen v2.0.0**](README.md)
2
2
 
3
3
  ***
4
4
 
@@ -8,57 +8,42 @@
8
8
 
9
9
  ## Interfaces
10
10
 
11
- ### PromiseProxy
12
-
13
- Defined in: [aberdeen.ts:1527](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1527)
14
-
15
- When `proxy` is called with a Promise, the returned object has this shape.
16
-
17
- #### Type Parameters
18
-
19
- ##### T
20
-
21
- `T`
22
-
23
- #### Properties
24
-
25
- ##### busy
26
-
27
- > **busy**: `boolean`
11
+ ### Aberdeen()
28
12
 
29
- Defined in: [aberdeen.ts:1531](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1531)
13
+ Defined in: [aberdeen.ts:51](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L51)
30
14
 
31
- True if the promise is still pending, false if it has resolved or rejected.
15
+ The Aberdeen instance returned by [createA](#createa): a callable element-builder with every
16
+ Aberdeen function attached as a method. `import A from 'aberdeen'` gives you one of these.
32
17
 
33
- ##### error?
18
+ > **Aberdeen**(...`args`): `undefined` \| `Element`
34
19
 
35
- > `optional` **error**: `any`
20
+ Defined in: [aberdeen.ts:53](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L53)
36
21
 
37
- Defined in: [aberdeen.ts:1539](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1539)
22
+ Build reactive DOM: create elements, set attributes/properties/event listeners, add content. See the tutorial for the full mini-language.
38
23
 
39
- If the promise has rejected, this contains the rejection error.
24
+ #### Parameters
40
25
 
41
- ##### value?
26
+ ##### args
42
27
 
43
- > `optional` **value**: `T`
28
+ ...`any`[]
44
29
 
45
- Defined in: [aberdeen.ts:1535](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1535)
30
+ #### Returns
46
31
 
47
- If the promise has resolved, this contains the resolved value.
32
+ `undefined` \| `Element`
48
33
 
49
- ## Variables
34
+ #### Properties
50
35
 
51
- ### cssVars
36
+ ##### cssVars
52
37
 
53
- > `const` **cssVars**: `Record`\<`string`, `string`\>
38
+ > **cssVars**: `Record`\<`string`, `string`\>
54
39
 
55
- Defined in: [aberdeen.ts:1959](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1959)
40
+ Defined in: [aberdeen.ts:192](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L192)
56
41
 
57
42
  A reactive object containing CSS variable definitions.
58
43
 
59
44
  Any property you assign to `cssVars` becomes available as a CSS custom property throughout your application.
60
45
 
61
- Use [setSpacingCssVars](#setspacingcssvars) to optionally initialize `cssVars[1]` through `cssVars[12]` with an exponential spacing scale.
46
+ Use [Aberdeen.setSpacingCssVars](#setspacingcssvars) to optionally initialize `cssVars[1]` through `cssVars[12]` with an exponential spacing scale.
62
47
 
63
48
  When you reference a CSS variable in Aberdeen using the `$` prefix (e.g., `$primary`), it automatically resolves to `var(--primary)`.
64
49
  For numeric keys (which can't be used directly as CSS custom property names), Aberdeen prefixes them with `m` (e.g., `$3` becomes `var(--m3)`).
@@ -66,7 +51,7 @@ For numeric keys (which can't be used directly as CSS custom property names), Ab
66
51
  When you add the first property to cssVars, Aberdeen automatically creates a reactive `<style>` tag in `<head>`
67
52
  containing the `:root` CSS custom property declarations. The style tag is automatically removed if cssVars becomes empty.
68
53
 
69
- #### Example
54
+ ###### Example
70
55
 
71
56
  ```javascript
72
57
  import A from 'aberdeen';
@@ -85,19 +70,17 @@ A('button bg:$primary fg:white #I'm a primary button');
85
70
  A('hr mt:$3'); // Sets margin-top to var(--m3)
86
71
  ```
87
72
 
88
- ***
89
-
90
- ### CUSTOM\_DUMP
73
+ ##### CUSTOM\_DUMP
91
74
 
92
- > `const` **CUSTOM\_DUMP**: *typeof* [`CUSTOM_DUMP`](#custom_dump)
75
+ > **CUSTOM\_DUMP**: `any`
93
76
 
94
- Defined in: [aberdeen.ts:3465](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3465)
77
+ Defined in: [aberdeen.ts:207](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L207)
95
78
 
96
- When set on an object or its prototype chain, [dump](#dump) calls this as a render function
79
+ When set on an object or its prototype chain, [Aberdeen.dump](#dump) calls this as a render function
97
80
  (with the object as `this`) instead of its default recursive rendering. If the value is not
98
81
  a function, it's treated as a string to display.
99
82
 
100
- #### Example
83
+ ###### Example
101
84
 
102
85
  ```typescript
103
86
  class Color {
@@ -106,32 +89,41 @@ class Color {
106
89
  }
107
90
  ```
108
91
 
109
- ***
92
+ ##### ~~NO\_COPY~~
110
93
 
111
- ### default
94
+ > **NO\_COPY**: `any`
112
95
 
113
- > **default**: (...`args`) => `undefined` \| `Element` & `object`
96
+ Defined in: [aberdeen.ts:618](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L618)
114
97
 
115
- Defined in: [aberdeen.ts:3559](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3559)
98
+ Use [Aberdeen.OPAQUE](#opaque) instead. This is an alias kept for backward compatibility.
116
99
 
117
- The main Aberdeen API. `A` is itself a callable function for building reactive DOM trees
118
- (creating elements, setting attributes, adding content). All other Aberdeen functions and
119
- values are available as properties on `A`.
100
+ ###### Deprecated
120
101
 
121
- #### Type declaration
102
+ ##### OPAQUE
122
103
 
123
- ##### clean()
104
+ > **OPAQUE**: `any`
124
105
 
125
- > **clean**: (`cleaner`) => `void`
106
+ Defined in: [aberdeen.ts:611](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L611)
126
107
 
127
- Registers a cleanup function to be executed just before the current reactive scope
128
- is destroyed or redraws.
108
+ A symbol that controls how Aberdeen handles an object in copy operations and proxy wrapping.
129
109
 
130
- This is useful for releasing resources, removing manual event listeners, or cleaning up
131
- side effects associated with the scope. Cleaners are run in reverse order of registration.
110
+ The **presence** of this symbol (regardless of its value) prevents deep-copying: the object is
111
+ stored and passed by reference in [Aberdeen.clone](#clone) and [Aberdeen.copy](#copy).
112
+
113
+ The **value** of the symbol controls proxy wrapping when the object is read from reactive state:
114
+ - **Truthy** (e.g. `true`): the object is fully opaque — it is not wrapped in a proxy, so its
115
+ properties are not observable. Use this for objects that break when proxied (e.g. class instances
116
+ with internal slots, Promises) or that must be invisible to Aberdeen's reactive system.
117
+ - **Falsy** (e.g. `false`): the object is still wrapped in a proxy, so reads on its properties
118
+ create reactive dependencies as normal — only deep-copying is suppressed.
119
+
120
+ #### Methods
121
+
122
+ ##### clean()
132
123
 
133
- Scopes are created by functions like [derive](#derive), [mount](#mount), [A](#a) (when given a render function),
134
- and internally by constructs like [onEach](#oneach).
124
+ > **clean**(`cleaner`): `void`
125
+
126
+ Defined in: [aberdeen.ts:92](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L92)
135
127
 
136
128
  Registers a cleanup function to be executed just before the current reactive scope
137
129
  is destroyed or redraws.
@@ -139,8 +131,8 @@ is destroyed or redraws.
139
131
  This is useful for releasing resources, removing manual event listeners, or cleaning up
140
132
  side effects associated with the scope. Cleaners are run in reverse order of registration.
141
133
 
142
- Scopes are created by functions like [derive](#derive), [mount](#mount), [A](#a) (when given a render function),
143
- and internally by constructs like [onEach](#oneach).
134
+ Scopes are created by functions like [Aberdeen.derive](#derive), [Aberdeen.mount](#mount), [A](#aberdeen) (when given a render function),
135
+ and internally by constructs like [Aberdeen.onEach](#oneach).
144
136
 
145
137
  ###### Parameters
146
138
 
@@ -182,9 +174,9 @@ setInterval(() => $numbers[rnd()] = rnd(), 1000);
182
174
 
183
175
  ##### clone()
184
176
 
185
- > **clone**: \<`T`\>(`src`) => `T`
177
+ > **clone**\<`T`\>(`src`): `T`
186
178
 
187
- Clone an (optionally proxied) object or array.
179
+ Defined in: [aberdeen.ts:101](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L101)
188
180
 
189
181
  Clone an (optionally proxied) object or array.
190
182
 
@@ -210,30 +202,14 @@ The object or array to clone. If it is proxied, `clone` will subscribe to any ch
210
202
 
211
203
  A new unproxied array or object (of the same type as `src`), containing a deep copy of `src`.
212
204
 
213
- ###### Returns
214
-
215
- A new unproxied array or object (of the same type as `src`), containing a deep copy of `src`.
216
-
217
205
  ##### copy()
218
206
 
219
- > **copy**: \{\<`T`\>(`dst`, `src`): `boolean`; \<`T`\>(`dst`, `dstKey`, `src`): `boolean`; \}
220
-
221
- Recursively copies properties or array items from `src` to `dst`.
222
- It's designed to work efficiently with reactive proxies created by [proxy](#proxy).
223
-
224
- - **Minimizes Updates:** When copying between objects/arrays (proxied or not), if a nested object
225
- exists in `dst` with the same constructor as the corresponding object in `src`, `copy`
226
- will recursively copy properties into the existing `dst` object instead of replacing it.
227
- This minimizes change notifications for reactive (proxied) destinations.
228
- - **Fast with Proxies:** When copying to/from proxied objects, `copy` uses Aberdeen internals
229
- to speed things up (compared to a non-Aberdeen-aware deep copy).
230
-
231
- ###### Call Signature
207
+ > **copy**\<`T`\>(`dst`, `src`): `boolean`
232
208
 
233
- > \<`T`\>(`dst`, `src`): `boolean`
209
+ Defined in: [aberdeen.ts:130](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L130)
234
210
 
235
211
  Recursively copies properties or array items from `src` to `dst`.
236
- It's designed to work efficiently with reactive proxies created by [proxy](#proxy).
212
+ It's designed to work efficiently with reactive proxies created by [Aberdeen.proxy](#proxy).
237
213
 
238
214
  - **Minimizes Updates:** When copying between objects/arrays (proxied or not), if a nested object
239
215
  exists in `dst` with the same constructor as the corresponding object in `src`, `copy`
@@ -285,48 +261,11 @@ A.copy($dest, 'b', { e: 4 });
285
261
  console.log($dest); // proxy({ a: 1, b: { e: 4 } })
286
262
  ```
287
263
 
288
- ###### Call Signature
289
-
290
- > \<`T`\>(`dst`, `dstKey`, `src`): `boolean`
291
-
292
- Like above, but copies `src` into `dst[dstKey]`. This is useful if you're unsure if dst[dstKey]
293
- already exists (as the right type of object) or if you don't want to subscribe to dst[dstKey].
294
-
295
- ###### Type Parameters
296
-
297
- ###### T
298
-
299
- `T` *extends* `object`
300
-
301
- ###### Parameters
302
-
303
- ###### dst
304
-
305
- `T`
306
-
307
- ###### dstKey
308
-
309
- keyof `T`
310
-
311
- Optional key in `dst` to copy into.
312
-
313
- ###### src
314
-
315
- `T`\[keyof `T`\]
316
-
317
- ###### Returns
318
-
319
- `boolean`
320
-
321
- ###### Returns
322
-
323
- `true` if any changes were made to `dst`, or `false` if not.
324
-
325
264
  ##### count()
326
265
 
327
- > **count**: (`proxied`) => `ValueRef`\<`number`\>
266
+ > **count**(`proxied`): [`ValueRef`](#valueref)\<`number`\>
328
267
 
329
- Reactively counts the number of properties in an object.
268
+ Defined in: [aberdeen.ts:159](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L159)
330
269
 
331
270
  Reactively counts the number of properties in an object.
332
271
 
@@ -334,13 +273,13 @@ Reactively counts the number of properties in an object.
334
273
 
335
274
  ###### proxied
336
275
 
337
- `TargetType`
276
+ [`TargetType`](#targettype)
338
277
 
339
- The observable object to count. In case an `array`, `Map`, or `Set` is passed in, a [ref](#ref) to its `.length` or `.size` will be returned.
278
+ The observable object to count. In case an `array`, `Map`, or `Set` is passed in, a [Aberdeen.ref](#ref) to its `.length` or `.size` will be returned.
340
279
 
341
280
  ###### Returns
342
281
 
343
- `ValueRef`\<`number`\>
282
+ [`ValueRef`](#valueref)\<`number`\>
344
283
 
345
284
  an observable object for which the `value` property reflects the number of properties in `proxied` with a value other than `undefined`, or the collection size for arrays, Maps, and Sets.
346
285
 
@@ -354,7 +293,7 @@ const $count = A.count($items);
354
293
  A('div text=', $count);
355
294
  // <div>2</div>
356
295
 
357
- // Or we can use it in an {@link derive} function:
296
+ // Or we can use it in an {@link Aberdeen.derive} function:
358
297
  A(() => console.log("The count is now", $count.value));
359
298
  // The count is now 2
360
299
 
@@ -365,51 +304,18 @@ $items.z = 12;
365
304
  // The count is now 3
366
305
  ```
367
306
 
368
- ###### Returns
369
-
370
- an observable object for which the `value` property reflects the number of properties in `proxied` with a value other than `undefined`, or the collection size for arrays, Maps, and Sets.
371
-
372
- ##### cssVars
373
-
374
- > **cssVars**: `Record`\<`string`, `string`\>
375
-
376
- A reactive object containing CSS variable definitions.
377
-
378
- Any property you assign to `cssVars` becomes available as a CSS custom property throughout your application.
379
-
380
- Use [setSpacingCssVars](#setspacingcssvars) to optionally initialize `cssVars[1]` through `cssVars[12]` with an exponential spacing scale.
381
-
382
- When you reference a CSS variable in Aberdeen using the `$` prefix (e.g., `$primary`), it automatically resolves to `var(--primary)`.
383
- For numeric keys (which can't be used directly as CSS custom property names), Aberdeen prefixes them with `m` (e.g., `$3` becomes `var(--m3)`).
384
-
385
- When you add the first property to cssVars, Aberdeen automatically creates a reactive `<style>` tag in `<head>`
386
- containing the `:root` CSS custom property declarations. The style tag is automatically removed if cssVars becomes empty.
387
-
388
- ##### CUSTOM\_DUMP
389
-
390
- > **CUSTOM\_DUMP**: `symbol`
391
-
392
- When set on an object or its prototype chain, [dump](#dump) calls this as a render function
393
- (with the object as `this`) instead of its default recursive rendering. If the value is not
394
- a function, it's treated as a string to display.
395
-
396
307
  ##### darkMode()
397
308
 
398
- > **darkMode**: () => `boolean`
399
-
400
- Returns whether the user's browser prefers a dark color scheme.
401
-
402
- This function is reactive - scopes that call it will re-execute when the
403
- browser's color scheme preference changes (via the `prefers-color-scheme` media query).
309
+ > **darkMode**(): `boolean`
404
310
 
405
- Use this in combination with [A](#a) and [cssVars](#cssvars) to implement theme switching:
311
+ Defined in: [aberdeen.ts:232](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L232)
406
312
 
407
313
  Returns whether the user's browser prefers a dark color scheme.
408
314
 
409
315
  This function is reactive - scopes that call it will re-execute when the
410
316
  browser's color scheme preference changes (via the `prefers-color-scheme` media query).
411
317
 
412
- Use this in combination with [A](#a) and [cssVars](#cssvars) to implement theme switching:
318
+ Use this in combination with [A](#aberdeen) and [Aberdeen.cssVars](#cssvars) to implement theme switching:
413
319
 
414
320
  ###### Returns
415
321
 
@@ -431,29 +337,19 @@ A(() => {
431
337
  A('div bg:$bg fg:$fg p:1rem #Colors change based on system dark mode preference');
432
338
  ```
433
339
 
434
- ###### Returns
435
-
436
- `true` if the browser prefers dark mode, `false` if it prefers light mode.
437
-
438
340
  ##### derive()
439
341
 
440
- > **derive**: \<`T`\>(`func`) => `ValueRef`\<`T`\>
342
+ > **derive**\<`T`\>(`func`): [`ValueRef`](#valueref)\<`T`\>
441
343
 
442
- Creates a reactive scope that automatically re-executes the provided function
443
- whenever any proxied data (created by [proxy](#proxy)) read during its last execution changes, storing
444
- its return value in an observable.
445
-
446
- Updates are batched and run asynchronously shortly after the changes occur.
447
- Use [clean](#clean) to register cleanup logic for the scope.
448
- Use [peek](#peek) or [unproxy](#unproxy) within the function to read proxied data without subscribing to it.
344
+ Defined in: [aberdeen.ts:282](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L282)
449
345
 
450
346
  Creates a reactive scope that automatically re-executes the provided function
451
- whenever any proxied data (created by [proxy](#proxy)) read during its last execution changes, storing
347
+ whenever any proxied data (created by [Aberdeen.proxy](#proxy)) read during its last execution changes, storing
452
348
  its return value in an observable.
453
349
 
454
350
  Updates are batched and run asynchronously shortly after the changes occur.
455
- Use [clean](#clean) to register cleanup logic for the scope.
456
- Use [peek](#peek) or [unproxy](#unproxy) within the function to read proxied data without subscribing to it.
351
+ Use [Aberdeen.clean](#clean) to register cleanup logic for the scope.
352
+ Use [Aberdeen.peek](#peek) or [Aberdeen.unproxy](#unproxy) within the function to read proxied data without subscribing to it.
457
353
 
458
354
  ###### Type Parameters
459
355
 
@@ -468,12 +364,12 @@ Use [peek](#peek) or [unproxy](#unproxy) within the function to read proxied dat
468
364
  () => `T`
469
365
 
470
366
  The function to execute reactively. Any DOM manipulations should typically
471
- be done using [A](#a) within this function. Its return value will be made available as an
367
+ be done using [A](#aberdeen) within this function. Its return value will be made available as an
472
368
  observable returned by the `derive()` function.
473
369
 
474
370
  ###### Returns
475
371
 
476
- `ValueRef`\<`T`\>
372
+ [`ValueRef`](#valueref)\<`T`\>
477
373
 
478
374
  An observable object, with its `value` property containing whatever the last run of `func` returned.
479
375
 
@@ -508,46 +404,14 @@ A('h3', () => {
508
404
  })
509
405
  ```
510
406
 
511
- ###### Returns
512
-
513
- An observable object, with its `value` property containing whatever the last run of `func` returned.
514
-
515
- ##### disableCreateDestroy()
516
-
517
- > **disableCreateDestroy**: () => `void`
518
-
519
- Make the `create` and `destroy` special properties no-ops.
520
-
521
- This is useful from within automated testing environments, where the transitioning
522
- new and lingering old elements may make writing reliable selectors difficult.
523
-
524
- As this is only intended for testing, there's no way to re-enable the special properties
525
- once disabled.
526
-
527
- Make the `create` and `destroy` special properties no-ops.
528
-
529
- This is useful from within automated testing environments, where the transitioning
530
- new and lingering old elements may make writing reliable selectors difficult.
531
-
532
- As this is only intended for testing, there's no way to re-enable the special properties
533
- once disabled.
534
-
535
- ###### Returns
536
-
537
- `void`
538
-
539
407
  ##### dump()
540
408
 
541
- > **dump**: \<`T`\>(`data`) => `T`
542
-
543
- Renders a live, recursive dump of a proxied data structure (or any value)
544
- into the DOM at the current [A](#a) insertion point.
409
+ > **dump**\<`T`\>(`data`): `T`
545
410
 
546
- Uses `<ul>` and `<li>` elements to display object properties and array items.
547
- Updates reactively if the dumped data changes. Primarily intended for debugging purposes.
411
+ Defined in: [aberdeen.ts:311](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L311)
548
412
 
549
413
  Renders a live, recursive dump of a proxied data structure (or any value)
550
- into the DOM at the current [A](#a) insertion point.
414
+ into the DOM at the current [A](#aberdeen) insertion point.
551
415
 
552
416
  Uses `<ul>` and `<li>` elements to display object properties and array items.
553
417
  Updates reactively if the dumped data changes. Primarily intended for debugging purposes.
@@ -591,33 +455,11 @@ A.dump($state);
591
455
  setTimeout(() => { $state.user.kids++; $state.items.push('c'); }, 2000);
592
456
  ```
593
457
 
594
- ###### Returns
595
-
596
- The original `data` argument, allowing for chaining.
597
-
598
458
  ##### insertCss()
599
459
 
600
- > **insertCss**: (`style`) => `string`
601
-
602
- Inserts CSS rules into the document, scoping them with a unique class name.
603
-
604
- The `style` parameter can be either:
605
- - A **concise style string** (for rules applying to the root class).
606
- - An **object** where keys are selectors (with `&` representing the root class)
607
- and values are concise style strings or nested objects. When the key does not contain `&`,
608
- it is treated as a descendant selector. So `{p: "color:red"}` becomes `".AbdStlX p { color: red; }"` with `AbdStlX` being the generated class name.
609
-
610
- ### Concise Style Strings
611
-
612
- Concise style strings use two syntaxes (same as inline CSS in [A](#a)):
613
- - **Short form** `key:value` (no space after colon): The value ends at the next whitespace.
614
- Example: `'m:$3 bg:red r:8px'`
615
- - **Long form** `key: value;` (space after colon): The value continues until a semicolon.
616
- Example: `'box-shadow: 2px 0 6px black; transition: all 0.3s ease;'`
617
-
618
- Both forms can be mixed: `'m:$3 box-shadow: 0 2px 4px rgba(0,0,0,0.2); bg:$cardBg'`
460
+ > **insertCss**(`style`): `string`
619
461
 
620
- Supports the same CSS shortcuts as [A](#a) and CSS variable references with `$` (e.g., `$primary`, `$3`).
462
+ Defined in: [aberdeen.ts:381](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L381)
621
463
 
622
464
  Inserts CSS rules into the document, scoping them with a unique class name.
623
465
 
@@ -629,7 +471,7 @@ The `style` parameter can be either:
629
471
 
630
472
  ### Concise Style Strings
631
473
 
632
- Concise style strings use two syntaxes (same as inline CSS in [A](#a)):
474
+ Concise style strings use two syntaxes (same as inline CSS in [A](#aberdeen)):
633
475
  - **Short form** `key:value` (no space after colon): The value ends at the next whitespace.
634
476
  Example: `'m:$3 bg:red r:8px'`
635
477
  - **Long form** `key: value;` (space after colon): The value continues until a semicolon.
@@ -637,7 +479,7 @@ Concise style strings use two syntaxes (same as inline CSS in [A](#a)):
637
479
 
638
480
  Both forms can be mixed: `'m:$3 box-shadow: 0 2px 4px rgba(0,0,0,0.2); bg:$cardBg'`
639
481
 
640
- Supports the same CSS shortcuts as [A](#a) and CSS variable references with `$` (e.g., `$primary`, `$3`).
482
+ Supports the same CSS shortcuts as [A](#aberdeen) and CSS variable references with `$` (e.g., `$primary`, `$3`).
641
483
 
642
484
  ###### Parameters
643
485
 
@@ -652,7 +494,7 @@ A concise style string or a style object.
652
494
  `string`
653
495
 
654
496
  The unique class name prefix used for scoping (e.g., `.AbdStl1`).
655
- Use this prefix with [A](#a) to apply the styles.
497
+ Use this prefix with [A](#aberdeen) to apply the styles.
656
498
 
657
499
  ###### Examples
658
500
 
@@ -696,30 +538,19 @@ const badge = A.insertCss({
696
538
  A(badge + ' span#Product Name');
697
539
  ```
698
540
 
699
- ###### Returns
700
-
701
- The unique class name prefix used for scoping (e.g., `.AbdStl1`).
702
- Use this prefix with [A](#a) to apply the styles.
703
-
704
541
  ##### insertGlobalCss()
705
542
 
706
- > **insertGlobalCss**: (`style`) => `void`
707
-
708
- Inserts CSS rules globally (unscoped).
709
-
710
- Works exactly like [insertCss](#insertcss), but without prefixing selectors with a unique class name.
711
- This is useful for global resets, base styles, or styles that need to apply to the entire document.
543
+ > **insertGlobalCss**(`style`): `void`
712
544
 
713
- Accepts the same concise style string syntax and CSS shortcuts as [insertCss](#insertcss).
714
- See [insertCss](#insertcss) for detailed documentation on syntax and shortcuts.
545
+ Defined in: [aberdeen.ts:441](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L441)
715
546
 
716
547
  Inserts CSS rules globally (unscoped).
717
548
 
718
- Works exactly like [insertCss](#insertcss), but without prefixing selectors with a unique class name.
549
+ Works exactly like [Aberdeen.insertCss](#insertcss), but without prefixing selectors with a unique class name.
719
550
  This is useful for global resets, base styles, or styles that need to apply to the entire document.
720
551
 
721
- Accepts the same concise style string syntax and CSS shortcuts as [insertCss](#insertcss).
722
- See [insertCss](#insertcss) for detailed documentation on syntax and shortcuts.
552
+ Accepts the same concise style string syntax and CSS shortcuts as [Aberdeen.insertCss](#insertcss).
553
+ See [Aberdeen.insertCss](#insertcss) for detailed documentation on syntax and shortcuts.
723
554
 
724
555
  ###### Parameters
725
556
 
@@ -781,22 +612,15 @@ A.insertGlobalCss({
781
612
 
782
613
  ##### invertString()
783
614
 
784
- > **invertString**: (`input`) => `string`
785
-
786
- Creates a new string that has the opposite sort order compared to the input string.
787
-
788
- This is achieved by flipping the bits of each character code in the input string.
789
- The resulting string is intended for use as a sort key, particularly with the
790
- `makeKey` function in [onEach](#oneach), to achieve a descending sort order.
615
+ > **invertString**(`input`): `string`
791
616
 
792
- **Warning:** The output string will likely contain non-printable characters or
793
- appear as gibberish and should not be displayed to the user.
617
+ Defined in: [aberdeen.ts:470](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L470)
794
618
 
795
619
  Creates a new string that has the opposite sort order compared to the input string.
796
620
 
797
621
  This is achieved by flipping the bits of each character code in the input string.
798
622
  The resulting string is intended for use as a sort key, particularly with the
799
- `makeKey` function in [onEach](#oneach), to achieve a descending sort order.
623
+ `makeKey` function in [Aberdeen.onEach](#oneach), to achieve a descending sort order.
800
624
 
801
625
  **Warning:** The output string will likely contain non-printable characters or
802
626
  appear as gibberish and should not be displayed to the user.
@@ -831,23 +655,13 @@ A.onEach($users, ($user) => {
831
655
 
832
656
  ###### See
833
657
 
834
- [onEach](#oneach) for usage with sorting.
835
-
836
- ###### Returns
837
-
838
- A new string that will sort in the reverse order of the input string.
658
+ [Aberdeen.onEach](#oneach) for usage with sorting.
839
659
 
840
660
  ##### isEmpty()
841
661
 
842
- > **isEmpty**: (`proxied`) => `boolean`
843
-
844
- Reactively checks if an observable array, object, Map, or Set is empty.
662
+ > **isEmpty**(`proxied`): `boolean`
845
663
 
846
- This function not only returns the current emptiness state but also establishes
847
- a reactive dependency. If the emptiness state of the `proxied` object or array
848
- changes later (e.g., an item is added to an empty array, or the last property
849
- is deleted from an object), the scope that called `isEmpty` will be automatically
850
- scheduled for re-evaluation.
664
+ Defined in: [aberdeen.ts:504](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L504)
851
665
 
852
666
  Reactively checks if an observable array, object, Map, or Set is empty.
853
667
 
@@ -861,7 +675,7 @@ scheduled for re-evaluation.
861
675
 
862
676
  ###### proxied
863
677
 
864
- `TargetType`
678
+ [`TargetType`](#targettype)
865
679
 
866
680
  The observable array, object, Map, or Set to check.
867
681
 
@@ -892,27 +706,11 @@ setInterval(() => {
892
706
  }, 1000)
893
707
  ```
894
708
 
895
- ###### Returns
896
-
897
- `true` if the array has length 0, the Map/Set has size 0, or the object has no own enumerable properties, `false` otherwise.
898
-
899
709
  ##### map()
900
710
 
901
- > **map**: \{\<`K`, `IN`, `OUT`\>(`source`, `func`): `Map`\<`K`, `OUT`\>; \<`IN`, `OUT`\>(`source`, `func`): `OUT`[]; \<`IN`, `IN_KEY`, `OUT`\>(`source`, `func`): `Record`\<`string` \| `symbol`, `OUT`\>; \}
902
-
903
- Reactively maps/filters items from a proxied source array or object to a new proxied array or object.
904
-
905
- It iterates over the `target` proxy. For each item, it calls `func`.
906
- - If `func` returns a value, it's added to the result proxy under the same key/index.
907
- - If `func` returns `undefined`, the item is skipped (filtered out).
908
-
909
- The returned proxy automatically updates when:
910
- - Items are added/removed/updated in the `target` proxy.
911
- - Any proxied data read *within* the `func` call changes (for a specific item).
912
-
913
- ###### Call Signature
711
+ > **map**\<`K`, `IN`, `OUT`\>(`source`, `func`): `Map`\<`K`, `OUT`\>
914
712
 
915
- > \<`K`, `IN`, `OUT`\>(`source`, `func`): `Map`\<`K`, `OUT`\>
713
+ Defined in: [aberdeen.ts:507](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L507)
916
714
 
917
715
  When using a Map as `source`.
918
716
 
@@ -944,192 +742,65 @@ When using a Map as `source`.
944
742
 
945
743
  `Map`\<`K`, `OUT`\>
946
744
 
947
- ###### Call Signature
948
-
949
- > \<`IN`, `OUT`\>(`source`, `func`): `OUT`[]
745
+ ##### merge()
950
746
 
951
- When using an array as `source`.
747
+ > **merge**\<`T`\>(`dst`, `value`): `boolean`
952
748
 
953
- ###### Type Parameters
749
+ Defined in: [aberdeen.ts:535](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L535)
954
750
 
955
- ###### IN
751
+ Like [Aberdeen.copy](#copy), but uses merge semantics. Properties in `dst` not present in `src` are kept.
752
+ `null`/`undefined` in `src` delete properties in `dst`.
956
753
 
957
- `IN`
754
+ ###### Type Parameters
958
755
 
959
- ###### OUT
756
+ ###### T
960
757
 
961
- `OUT`
758
+ `T` *extends* `object`
962
759
 
963
760
  ###### Parameters
964
761
 
965
- ###### source
762
+ ###### dst
966
763
 
967
- `IN`[]
764
+ `T`
968
765
 
969
- ###### func
766
+ ###### value
970
767
 
971
- (`value`, `index`) => `undefined` \| `OUT`
768
+ `Partial`\<`T`\>
972
769
 
973
770
  ###### Returns
974
771
 
975
- `OUT`[]
772
+ `boolean`
976
773
 
977
- ###### Call Signature
774
+ ###### Example
978
775
 
979
- > \<`IN`, `IN_KEY`, `OUT`\>(`source`, `func`): `Record`\<`string` \| `symbol`, `OUT`\>
776
+ ```typescript
777
+ const source = { b: { c: 99 }, d: undefined }; // d: undefined will delete
778
+ const $dest = A.proxy({ a: 1, b: { x: 5 }, d: 4 });
779
+ A.merge($dest, source);
780
+ A.merge($dest, 'b', { y: 6 }); // merge into $dest.b
781
+ A.merge($dest, 'c', { z: 7 }); // $dest.c doesn't exist yet, so it will just be assigned
782
+ console.log($dest); // proxy({ a: 1, b: { c: 99, x: 5, y: 6 }, c: { z: 7 } })
783
+ ```
980
784
 
981
- When using an object as `source`.
785
+ ##### mount()
982
786
 
983
- ###### Type Parameters
787
+ > **mount**(`parentElement`, `func`): `void`
984
788
 
985
- ###### IN
986
-
987
- `IN`
988
-
989
- ###### IN_KEY
990
-
991
- `IN_KEY` *extends* `string` \| `number` \| `symbol`
992
-
993
- ###### OUT
994
-
995
- `OUT`
996
-
997
- ###### Parameters
998
-
999
- ###### source
1000
-
1001
- `Record`\<`IN_KEY`, `IN`\>
1002
-
1003
- ###### func
1004
-
1005
- (`value`, `index`) => `undefined` \| `OUT`
1006
-
1007
- ###### Returns
1008
-
1009
- `Record`\<`string` \| `symbol`, `OUT`\>
1010
-
1011
- ###### Returns
1012
-
1013
- A new proxied array or object containing the mapped values.
1014
-
1015
- ##### merge()
1016
-
1017
- > **merge**: \{\<`T`\>(`dst`, `value`): `boolean`; \<`T`\>(`dst`, `dstKey`, `value`): `boolean`; \}
1018
-
1019
- Like [copy](#copy), but uses merge semantics. Properties in `dst` not present in `src` are kept.
1020
- `null`/`undefined` in `src` delete properties in `dst`.
1021
-
1022
- ###### Call Signature
1023
-
1024
- > \<`T`\>(`dst`, `value`): `boolean`
1025
-
1026
- Like [copy](#copy), but uses merge semantics. Properties in `dst` not present in `src` are kept.
1027
- `null`/`undefined` in `src` delete properties in `dst`.
1028
-
1029
- ###### Type Parameters
1030
-
1031
- ###### T
1032
-
1033
- `T` *extends* `object`
1034
-
1035
- ###### Parameters
1036
-
1037
- ###### dst
1038
-
1039
- `T`
1040
-
1041
- ###### value
1042
-
1043
- `Partial`\<`T`\>
1044
-
1045
- ###### Returns
1046
-
1047
- `boolean`
1048
-
1049
- ###### Example
1050
-
1051
- ```typescript
1052
- const source = { b: { c: 99 }, d: undefined }; // d: undefined will delete
1053
- const $dest = A.proxy({ a: 1, b: { x: 5 }, d: 4 });
1054
- A.merge($dest, source);
1055
- A.merge($dest, 'b', { y: 6 }); // merge into $dest.b
1056
- A.merge($dest, 'c', { z: 7 }); // $dest.c doesn't exist yet, so it will just be assigned
1057
- console.log($dest); // proxy({ a: 1, b: { c: 99, x: 5, y: 6 }, c: { z: 7 } })
1058
- ```
1059
-
1060
- ###### Call Signature
1061
-
1062
- > \<`T`\>(`dst`, `dstKey`, `value`): `boolean`
1063
-
1064
- Like [copy](#copy), but uses merge semantics. Properties in `dst` not present in `src` are kept.
1065
- `null`/`undefined` in `src` delete properties in `dst`.
1066
-
1067
- ###### Type Parameters
1068
-
1069
- ###### T
1070
-
1071
- `T` *extends* `object`
1072
-
1073
- ###### Parameters
1074
-
1075
- ###### dst
1076
-
1077
- `T`
1078
-
1079
- ###### dstKey
1080
-
1081
- keyof `T`
1082
-
1083
- ###### value
1084
-
1085
- `Partial`\<`T`\[keyof `T`\]\>
1086
-
1087
- ###### Returns
1088
-
1089
- `boolean`
1090
-
1091
- ###### Example
1092
-
1093
- ```typescript
1094
- const source = { b: { c: 99 }, d: undefined }; // d: undefined will delete
1095
- const $dest = A.proxy({ a: 1, b: { x: 5 }, d: 4 });
1096
- A.merge($dest, source);
1097
- A.merge($dest, 'b', { y: 6 }); // merge into $dest.b
1098
- A.merge($dest, 'c', { z: 7 }); // $dest.c doesn't exist yet, so it will just be assigned
1099
- console.log($dest); // proxy({ a: 1, b: { c: 99, x: 5, y: 6 }, c: { z: 7 } })
1100
- ```
1101
-
1102
- ##### mount()
1103
-
1104
- > **mount**: (`parentElement`, `func`) => `void`
1105
-
1106
- Attaches a reactive Aberdeen UI fragment to an existing DOM element. Without the use of
1107
- this function, [A](#a) will assume `document.body` as its root.
1108
-
1109
- It creates a top-level reactive scope associated with the `parentElement`. The provided
1110
- function `func` is executed immediately within this scope. Any proxied data read by `func`
1111
- will cause it to re-execute when the data changes, updating the DOM elements created within it.
1112
-
1113
- Calls to [A](#a) inside `func` will append nodes to `parentElement`.
1114
- You can nest [derive](#derive) or other [A](#a) scopes within `func`.
1115
- Use [unmountAll](#unmountall) to clean up all mounted scopes and their DOM nodes.
1116
-
1117
- Mounting scopes happens reactively, meaning that if this function is called from within another
1118
- ([derive](#derive) or [A](#a) or [mount](#mount)) scope that gets cleaned up, so will the mount.
789
+ Defined in: [aberdeen.ts:580](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L580)
1119
790
 
1120
791
  Attaches a reactive Aberdeen UI fragment to an existing DOM element. Without the use of
1121
- this function, [A](#a) will assume `document.body` as its root.
792
+ this function, [A](#aberdeen) will assume `document.body` as its root.
1122
793
 
1123
794
  It creates a top-level reactive scope associated with the `parentElement`. The provided
1124
795
  function `func` is executed immediately within this scope. Any proxied data read by `func`
1125
796
  will cause it to re-execute when the data changes, updating the DOM elements created within it.
1126
797
 
1127
- Calls to [A](#a) inside `func` will append nodes to `parentElement`.
1128
- You can nest [derive](#derive) or other [A](#a) scopes within `func`.
1129
- Use [unmountAll](#unmountall) to clean up all mounted scopes and their DOM nodes.
798
+ Calls to [A](#aberdeen) inside `func` will append nodes to `parentElement`.
799
+ You can nest [Aberdeen.derive](#derive) or other [A](#aberdeen) scopes within `func`.
800
+ Use [Aberdeen.unmountAll](#unmountall) to clean up all mounted scopes and their DOM nodes.
1130
801
 
1131
802
  Mounting scopes happens reactively, meaning that if this function is called from within another
1132
- ([derive](#derive) or [A](#a) or [mount](#mount)) scope that gets cleaned up, so will the mount.
803
+ ([Aberdeen.derive](#derive) or [A](#aberdeen) or [Aberdeen.mount](#mount)) scope that gets cleaned up, so will the mount.
1133
804
 
1134
805
  ###### Parameters
1135
806
 
@@ -1143,7 +814,7 @@ The native DOM `Element` to which the UI fragment will be appended.
1143
814
 
1144
815
  () => `void`
1145
816
 
1146
- The function that defines the UI fragment, typically containing calls to [A](#a).
817
+ The function that defines the UI fragment, typically containing calls to [A](#aberdeen).
1147
818
 
1148
819
  ###### Returns
1149
820
 
@@ -1176,26 +847,9 @@ Note how the inner mount behaves reactively as well, automatically unmounting wh
1176
847
 
1177
848
  ##### multiMap()
1178
849
 
1179
- > **multiMap**: \{\<`IN`, `OUT`\>(`source`, `func`): `OUT`; \<`K`, `IN`, `OUT`\>(`source`, `func`): `OUT`; \<`K`, `IN`, `OUT`\>(`source`, `func`): `OUT`; \}
1180
-
1181
- Reactively maps items from a source proxy (array or object) to a target proxied object,
1182
- where each source item can contribute multiple key-value pairs to the target.
1183
-
1184
- It iterates over the `target` proxy. For each item, it calls `func`.
1185
- - If `func` returns an object, all key-value pairs from that object are added to the result proxy.
1186
- - If `func` returns `undefined`, the item contributes nothing.
1187
-
1188
- The returned proxy automatically updates when:
1189
- - Items are added/removed/updated in the `target` proxy.
1190
- - Any proxied data read *within* the `func` call changes (for a specific item).
1191
- - If multiple input items produce the same output key, the last one processed usually "wins",
1192
- but the exact behavior on collision depends on update timing.
1193
-
1194
- This is useful for "flattening" or "indexing" data, or converting an observable array to an observable object.
1195
-
1196
- ###### Call Signature
850
+ > **multiMap**\<`IN`, `OUT`\>(`source`, `func`): `OUT`
1197
851
 
1198
- > \<`IN`, `OUT`\>(`source`, `func`): `OUT`
852
+ Defined in: [aberdeen.ts:583](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L583)
1199
853
 
1200
854
  When using an array as `source`.
1201
855
 
@@ -1223,395 +877,174 @@ When using an array as `source`.
1223
877
 
1224
878
  `OUT`
1225
879
 
1226
- ###### Call Signature
880
+ ##### onEach()
1227
881
 
1228
- > \<`K`, `IN`, `OUT`\>(`source`, `func`): `OUT`
882
+ > **onEach**\<`K`, `T`\>(`target`, `render`, `makeKey?`): `void`
1229
883
 
1230
- When using an object as `source`.
884
+ Defined in: [aberdeen.ts:688](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L688)
1231
885
 
1232
- ###### Type Parameters
886
+ Reactively iterates over the items of an observable array, object, Map, or Set, optionally rendering content for each item.
1233
887
 
1234
- ###### K
888
+ Automatically updates when items are added, removed, or modified.
1235
889
 
1236
- `K` *extends* `string` \| `number` \| `symbol`
890
+ ###### Type Parameters
1237
891
 
1238
- ###### IN
892
+ ###### K
1239
893
 
1240
- `IN`
894
+ `K`
1241
895
 
1242
- ###### OUT
896
+ ###### T
1243
897
 
1244
- `OUT` *extends* `object`
898
+ `T`
1245
899
 
1246
900
  ###### Parameters
1247
901
 
1248
- ###### source
1249
-
1250
- `Record`\<`K`, `IN`\>
1251
-
1252
- ###### func
1253
-
1254
- (`value`, `index`) => `undefined` \| `OUT`
1255
-
1256
- ###### Returns
1257
-
1258
- `OUT`
902
+ ###### target
1259
903
 
1260
- ###### Call Signature
904
+ `Map`\<`K`, `undefined` \| `T`\>
1261
905
 
1262
- > \<`K`, `IN`, `OUT`\>(`source`, `func`): `OUT`
906
+ The observable array, object, Map, or Set to iterate over. Values that are `undefined` are skipped.
1263
907
 
1264
- When using a Map as `source`.
908
+ ###### render
1265
909
 
1266
- ###### Type Parameters
910
+ (`value`, `key`) => `void`
1267
911
 
1268
- ###### K
912
+ A function called for each item. It receives the item's (observable) value and its index/key. For Sets, only the value is provided. Any DOM elements created within this function will be associated with the item, placed at the right spot in the DOM, and cleaned up when redrawing/removing the item.
1269
913
 
1270
- `K`
914
+ ###### makeKey?
1271
915
 
1272
- ###### IN
916
+ (`value`, `key`) => [`SortKeyType`](#sortkeytype)
1273
917
 
1274
- `IN`
918
+ An optional function to generate a sort key for each item. This controls the order in which items are rendered in the DOM. If omitted, arrays use index order, Sets use the item value itself, and objects/Maps use their natural key order. The returned key can be a number, string, or an array of numbers/strings for composite sorting. Use [Aberdeen.invertString](#invertstring) on string keys for descending order. Returning `null` or `undefined` from `makeKey` will prevent the item from being rendered.
1275
919
 
1276
- ###### OUT
920
+ ###### Returns
1277
921
 
1278
- `OUT` *extends* `object`
922
+ `void`
1279
923
 
1280
- ###### Parameters
924
+ ###### Examples
1281
925
 
1282
- ###### source
926
+ ```typescript
927
+ const $items = A.proxy(['apple', 'banana', 'cherry']);
1283
928
 
1284
- `Map`\<`K`, `IN`\>
929
+ // Basic iteration
930
+ A.onEach($items, (item, index) => A(`li#${item} (#${index})`));
1285
931
 
1286
- ###### func
932
+ // Add a new item - the list updates automatically
933
+ setTimeout(() => $items.push('durian'), 2000);
934
+ // Same for updates and deletes
935
+ setTimeout(() => $items[1] = 'berry', 4000);
936
+ setTimeout(() => delete $items[2], 6000);
937
+ ```
1287
938
 
1288
- (`value`, `key`) => `undefined` \| `OUT`
939
+ ```typescript
940
+ const $users = A.proxy([
941
+ { id: 3, group: 1, name: 'Charlie' },
942
+ { id: 1, group: 1, name: 'Alice' },
943
+ { id: 2, group: 2, name: 'Bob' },
944
+ ]);
1289
945
 
1290
- ###### Returns
946
+ // Sort by name alphabetically
947
+ A.onEach($users, ($user) => {
948
+ A(`p#${$user.name} (id=${$user.id})`);
949
+ }, ($user) => [$user.group, $user.name]); // Sort by group, and within each group sort by name
950
+ ```
1291
951
 
1292
- `OUT`
952
+ ```javascript
953
+ const $config = A.proxy({ theme: 'dark', fontSize: 14, showTips: true });
1293
954
 
1294
- ###### Returns
955
+ // Display configuration options
956
+ A('dl', () => {
957
+ A.onEach($config, (value, key) => {
958
+ if (key === 'showTips') return; // Don't render this one
959
+ A('dt#'+key);
960
+ A('dd#'+value);
961
+ });
962
+ });
1295
963
 
1296
- A new proxied object containing the aggregated key-value pairs.
964
+ // Change a value - the display updates automatically
965
+ setTimeout(() => $config.fontSize = 16, 2000);
966
+ ```
1297
967
 
1298
- ##### NO\_COPY
968
+ ```javascript
969
+ const $tags = A.proxy(new Set(['ui', 'fast', 'tiny']));
1299
970
 
1300
- > **NO\_COPY**: `symbol`
971
+ A('ul', () => {
972
+ A.onEach($tags, (tag) => { // Defaults to alphabetically ordering by tag
973
+ A(`li#${tag}`);
974
+ });
975
+ });
1301
976
 
1302
- Use [OPAQUE](#opaque) instead. This is an alias kept for backward compatibility.
977
+ setTimeout(() => $tags.add('reactive'), 2000);
978
+ ```
1303
979
 
1304
- ##### onEach()
980
+ ###### See
1305
981
 
1306
- > **onEach**: \{\<`K`, `T`\>(`target`, `render`, `makeKey?`): `void`; \<`T`\>(`target`, `render`, `makeKey?`): `void`; \<`T`\>(`target`, `render`, `makeKey?`): `void`; \<`K`, `T`\>(`target`, `render`, `makeKey?`): `void`; \}
982
+ [Aberdeen.invertString](#invertstring) To easily create keys for reverse sorting.
1307
983
 
1308
- Reactively iterates over the items of an observable array, object, Map, or Set, optionally rendering content for each item.
984
+ ##### partition()
1309
985
 
1310
- Automatically updates when items are added, removed, or modified.
986
+ > **partition**\<`OUT_K`, `IN_V`\>(`source`, `func`): `Record`\<`OUT_K`, `Record`\<`number`, `IN_V`\>\>
1311
987
 
1312
- ###### Call Signature
988
+ Defined in: [aberdeen.ts:710](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L710)
1313
989
 
1314
- > \<`K`, `T`\>(`target`, `render`, `makeKey?`): `void`
990
+ When using an object as `array`.
1315
991
 
1316
992
  ###### Type Parameters
1317
993
 
1318
- ###### K
994
+ ###### OUT_K
1319
995
 
1320
- `K`
996
+ `OUT_K` *extends* `string` \| `number` \| `symbol`
1321
997
 
1322
- ###### T
998
+ ###### IN_V
1323
999
 
1324
- `T`
1000
+ `IN_V`
1325
1001
 
1326
1002
  ###### Parameters
1327
1003
 
1328
- ###### target
1004
+ ###### source
1329
1005
 
1330
- `Map`\<`K`, `undefined` \| `T`\>
1006
+ `IN_V`[]
1331
1007
 
1332
- ###### render
1008
+ ###### func
1333
1009
 
1334
- (`value`, `key`) => `void`
1010
+ (`value`, `key`) => `undefined` \| `OUT_K` \| `OUT_K`[]
1335
1011
 
1336
- ###### makeKey?
1012
+ ###### Returns
1337
1013
 
1338
- (`value`, `key`) => `SortKeyType`
1014
+ `Record`\<`OUT_K`, `Record`\<`number`, `IN_V`\>\>
1339
1015
 
1340
- ###### Returns
1016
+ ##### peek()
1341
1017
 
1342
- `void`
1018
+ > **peek**\<`T`, `K`\>(`target`, `key`): `T`\[`K`\]
1019
+
1020
+ Defined in: [aberdeen.ts:756](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L756)
1021
+
1022
+ Executes a function or retrieves a value *without* creating subscriptions in the current reactive scope, and returns its result.
1343
1023
 
1344
- ###### Call Signature
1024
+ This is useful when you need to access reactive data inside a reactive scope (like [A](#aberdeen))
1025
+ but do not want changes to that specific data to trigger a re-execute of the scope.
1345
1026
 
1346
- > \<`T`\>(`target`, `render`, `makeKey?`): `void`
1027
+ Note: You may also use [Aberdeen.unproxy](#unproxy) to get to the raw underlying data structure, which can be used to similar effect.
1347
1028
 
1348
1029
  ###### Type Parameters
1349
1030
 
1350
1031
  ###### T
1351
1032
 
1352
- `T`
1033
+ `T` *extends* `object`
1034
+
1035
+ ###### K
1036
+
1037
+ `K` *extends* `string` \| `number` \| `symbol`
1353
1038
 
1354
1039
  ###### Parameters
1355
1040
 
1356
1041
  ###### target
1357
1042
 
1358
- `Set`\<`T`\>
1043
+ `T`
1359
1044
 
1360
- ###### render
1045
+ Either a function to execute, or an object (which may also be an Array or a Map) to index.
1361
1046
 
1362
- (`value`) => `void`
1363
-
1364
- ###### makeKey?
1365
-
1366
- (`value`) => `SortKeyType`
1367
-
1368
- ###### Returns
1369
-
1370
- `void`
1371
-
1372
- ###### Call Signature
1373
-
1374
- > \<`T`\>(`target`, `render`, `makeKey?`): `void`
1375
-
1376
- ###### Type Parameters
1377
-
1378
- ###### T
1379
-
1380
- `T`
1381
-
1382
- ###### Parameters
1383
-
1384
- ###### target
1385
-
1386
- readonly (`undefined` \| `T`)[]
1387
-
1388
- ###### render
1389
-
1390
- (`value`, `index`) => `void`
1391
-
1392
- ###### makeKey?
1393
-
1394
- (`value`, `index`) => `SortKeyType`
1395
-
1396
- ###### Returns
1397
-
1398
- `void`
1399
-
1400
- ###### Call Signature
1401
-
1402
- > \<`K`, `T`\>(`target`, `render`, `makeKey?`): `void`
1403
-
1404
- ###### Type Parameters
1405
-
1406
- ###### K
1407
-
1408
- `K` *extends* `string` \| `number` \| `symbol`
1409
-
1410
- ###### T
1411
-
1412
- `T`
1413
-
1414
- ###### Parameters
1415
-
1416
- ###### target
1417
-
1418
- `Record`\<`K`, `undefined` \| `T`\>
1419
-
1420
- ###### render
1421
-
1422
- (`value`, `index`) => `void`
1423
-
1424
- ###### makeKey?
1425
-
1426
- (`value`, `index`) => `SortKeyType`
1427
-
1428
- ###### Returns
1429
-
1430
- `void`
1431
-
1432
- ##### OPAQUE
1433
-
1434
- > **OPAQUE**: `symbol`
1435
-
1436
- A symbol that controls how Aberdeen handles an object in copy operations and proxy wrapping.
1437
-
1438
- The **presence** of this symbol (regardless of its value) prevents deep-copying: the object is
1439
- stored and passed by reference in [clone](#clone) and [copy](#copy).
1440
-
1441
- The **value** of the symbol controls proxy wrapping when the object is read from reactive state:
1442
- - **Truthy** (e.g. `true`): the object is fully opaque — it is not wrapped in a proxy, so its
1443
- properties are not observable. Use this for objects that break when proxied (e.g. class instances
1444
- with internal slots, Promises) or that must be invisible to Aberdeen's reactive system.
1445
- - **Falsy** (e.g. `false`): the object is still wrapped in a proxy, so reads on its properties
1446
- create reactive dependencies as normal — only deep-copying is suppressed.
1447
-
1448
- ##### partition()
1449
-
1450
- > **partition**: \{\<`OUT_K`, `IN_V`\>(`source`, `func`): `Record`\<`OUT_K`, `Record`\<`number`, `IN_V`\>\>; \<`IN_K`, `OUT_K`, `IN_V`\>(`source`, `func`): `Record`\<`OUT_K`, `Record`\<`IN_K`, `IN_V`\>\>; \<`IN_K`, `OUT_K`, `IN_V`\>(`source`, `func`): `Record`\<`OUT_K`, `Record`\<`IN_K`, `IN_V`\>\>; \}
1451
-
1452
- Reactively partitions items from a source proxy (array or object) into multiple "bucket" proxies
1453
- based on keys determined by a classifier function.
1454
-
1455
- This function iterates through the `source` proxy using [onEach](#oneach). For each item,
1456
- it calls the classifier `func`, which should return:
1457
- - A single key (`OUT_K`): The item belongs to the bucket with this key.
1458
- - An array of keys (`OUT_K[]`): The item belongs to all buckets specified in the array.
1459
- - `undefined`: The item is not placed in any bucket.
1460
-
1461
- The function returns a main proxied object. The keys of this object are the bucket keys (`OUT_K`)
1462
- returned by `func`. Each value associated with a bucket key is another proxied object (the "bucket").
1463
- This inner bucket object maps the *original* keys/indices from the `source` to the items
1464
- themselves that were classified into that bucket.
1465
-
1466
- The entire structure is reactive. Changes in the `source` proxy (adding/removing/updating items)
1467
- or changes in dependencies read by the `func` will cause the output partitioning to update automatically.
1468
- Buckets are created dynamically as needed and removed when they become empty.
1469
-
1470
- ###### Call Signature
1471
-
1472
- > \<`OUT_K`, `IN_V`\>(`source`, `func`): `Record`\<`OUT_K`, `Record`\<`number`, `IN_V`\>\>
1473
-
1474
- When using an object as `array`.
1475
-
1476
- ###### Type Parameters
1477
-
1478
- ###### OUT_K
1479
-
1480
- `OUT_K` *extends* `string` \| `number` \| `symbol`
1481
-
1482
- ###### IN_V
1483
-
1484
- `IN_V`
1485
-
1486
- ###### Parameters
1487
-
1488
- ###### source
1489
-
1490
- `IN_V`[]
1491
-
1492
- ###### func
1493
-
1494
- (`value`, `key`) => `undefined` \| `OUT_K` \| `OUT_K`[]
1495
-
1496
- ###### Returns
1497
-
1498
- `Record`\<`OUT_K`, `Record`\<`number`, `IN_V`\>\>
1499
-
1500
- ###### Call Signature
1501
-
1502
- > \<`IN_K`, `OUT_K`, `IN_V`\>(`source`, `func`): `Record`\<`OUT_K`, `Record`\<`IN_K`, `IN_V`\>\>
1503
-
1504
- When using an object as `source`.
1505
-
1506
- ###### Type Parameters
1507
-
1508
- ###### IN_K
1509
-
1510
- `IN_K` *extends* `string` \| `number` \| `symbol`
1511
-
1512
- ###### OUT_K
1513
-
1514
- `OUT_K` *extends* `string` \| `number` \| `symbol`
1515
-
1516
- ###### IN_V
1517
-
1518
- `IN_V`
1519
-
1520
- ###### Parameters
1521
-
1522
- ###### source
1523
-
1524
- `Record`\<`IN_K`, `IN_V`\>
1525
-
1526
- ###### func
1527
-
1528
- (`value`, `key`) => `undefined` \| `OUT_K` \| `OUT_K`[]
1529
-
1530
- ###### Returns
1531
-
1532
- `Record`\<`OUT_K`, `Record`\<`IN_K`, `IN_V`\>\>
1533
-
1534
- ###### Call Signature
1535
-
1536
- > \<`IN_K`, `OUT_K`, `IN_V`\>(`source`, `func`): `Record`\<`OUT_K`, `Record`\<`IN_K`, `IN_V`\>\>
1537
-
1538
- When using a Map as `source`.
1539
-
1540
- ###### Type Parameters
1541
-
1542
- ###### IN_K
1543
-
1544
- `IN_K` *extends* `string` \| `number` \| `symbol`
1545
-
1546
- ###### OUT_K
1547
-
1548
- `OUT_K` *extends* `string` \| `number` \| `symbol`
1549
-
1550
- ###### IN_V
1551
-
1552
- `IN_V`
1553
-
1554
- ###### Parameters
1555
-
1556
- ###### source
1557
-
1558
- `Map`\<`IN_K`, `IN_V`\>
1559
-
1560
- ###### func
1561
-
1562
- (`value`, `key`) => `undefined` \| `OUT_K` \| `OUT_K`[]
1563
-
1564
- ###### Returns
1565
-
1566
- `Record`\<`OUT_K`, `Record`\<`IN_K`, `IN_V`\>\>
1567
-
1568
- ###### Returns
1569
-
1570
- A proxied object where keys are the bucket identifiers (`OUT_K`) and values are proxied Records
1571
- (`Record<IN_K | number, IN_V>`) representing the buckets. Each bucket maps original source keys/indices
1572
- to the items belonging to that bucket.
1573
-
1574
- ##### peek()
1575
-
1576
- > **peek**: \{\<`T`, `K`\>(`target`, `key`): `T`\[`K`\]; \<`K`, `V`\>(`target`, `key`): `undefined` \| `V`; \<`T`\>(`target`, `key`): `undefined` \| `T`; \<`T`\>(`target`): `T`; \}
1577
-
1578
- Executes a function or retrieves a value *without* creating subscriptions in the current reactive scope, and returns its result.
1579
-
1580
- This is useful when you need to access reactive data inside a reactive scope (like [A](#a))
1581
- but do not want changes to that specific data to trigger a re-execute of the scope.
1582
-
1583
- Note: You may also use [unproxy](#unproxy) to get to the raw underlying data structure, which can be used to similar effect.
1584
-
1585
- ###### Call Signature
1586
-
1587
- > \<`T`, `K`\>(`target`, `key`): `T`\[`K`\]
1588
-
1589
- Executes a function or retrieves a value *without* creating subscriptions in the current reactive scope, and returns its result.
1590
-
1591
- This is useful when you need to access reactive data inside a reactive scope (like [A](#a))
1592
- but do not want changes to that specific data to trigger a re-execute of the scope.
1593
-
1594
- Note: You may also use [unproxy](#unproxy) to get to the raw underlying data structure, which can be used to similar effect.
1595
-
1596
- ###### Type Parameters
1597
-
1598
- ###### T
1599
-
1600
- `T` *extends* `object`
1601
-
1602
- ###### K
1603
-
1604
- `K` *extends* `string` \| `number` \| `symbol`
1605
-
1606
- ###### Parameters
1607
-
1608
- ###### target
1609
-
1610
- `T`
1611
-
1612
- Either a function to execute, or an object (which may also be an Array or a Map) to index.
1613
-
1614
- ###### key
1047
+ ###### key
1615
1048
 
1616
1049
  `K`
1617
1050
 
@@ -1636,2512 +1069,16 @@ $data.b = 3; // Does not trigger console.log
1636
1069
  $data.a = 2; // Triggers console.log (logs "A is 2, B was 3 when A changed.")
1637
1070
  ```
1638
1071
 
1639
- ###### Call Signature
1640
-
1641
- > \<`K`, `V`\>(`target`, `key`): `undefined` \| `V`
1642
-
1643
- Executes a function or retrieves a value *without* creating subscriptions in the current reactive scope, and returns its result.
1644
-
1645
- This is useful when you need to access reactive data inside a reactive scope (like [A](#a))
1646
- but do not want changes to that specific data to trigger a re-execute of the scope.
1647
-
1648
- Note: You may also use [unproxy](#unproxy) to get to the raw underlying data structure, which can be used to similar effect.
1649
-
1650
- ###### Type Parameters
1651
-
1652
- ###### K
1653
-
1654
- `K`
1655
-
1656
- ###### V
1657
-
1658
- `V`
1659
-
1660
- ###### Parameters
1661
-
1662
- ###### target
1663
-
1664
- `Map`\<`K`, `V`\>
1665
-
1666
- Either a function to execute, or an object (which may also be an Array or a Map) to index.
1667
-
1668
- ###### key
1669
-
1670
- `K`
1671
-
1672
- Optional key/index to use when `target` is an object.
1673
-
1674
- ###### Returns
1675
-
1676
- `undefined` \| `V`
1677
-
1678
- The result of the function call, or the value at `target[key]` when `target` is an object or `target.get(key)` when it's a Map.
1679
-
1680
- ###### Example
1681
-
1682
- ```typescript
1683
- const $data = A.proxy({ a: 1, b: 2 });
1684
- A(() => {
1685
- // re-executes only when $data.a changes, because $data.b is peeked.
1686
- const b = A.peek(() => $data.b);
1687
- console.log(`A is ${$data.a}, B was ${b} when A changed.`);
1688
- });
1689
- $data.b = 3; // Does not trigger console.log
1690
- $data.a = 2; // Triggers console.log (logs "A is 2, B was 3 when A changed.")
1691
- ```
1692
-
1693
- ###### Call Signature
1694
-
1695
- > \<`T`\>(`target`, `key`): `undefined` \| `T`
1696
-
1697
- Executes a function or retrieves a value *without* creating subscriptions in the current reactive scope, and returns its result.
1698
-
1699
- This is useful when you need to access reactive data inside a reactive scope (like [A](#a))
1700
- but do not want changes to that specific data to trigger a re-execute of the scope.
1701
-
1702
- Note: You may also use [unproxy](#unproxy) to get to the raw underlying data structure, which can be used to similar effect.
1703
-
1704
- ###### Type Parameters
1705
-
1706
- ###### T
1072
+ ##### proxy()
1707
1073
 
1708
- `T`
1709
-
1710
- ###### Parameters
1711
-
1712
- ###### target
1713
-
1714
- `T`[]
1715
-
1716
- Either a function to execute, or an object (which may also be an Array or a Map) to index.
1717
-
1718
- ###### key
1719
-
1720
- `number`
1721
-
1722
- Optional key/index to use when `target` is an object.
1723
-
1724
- ###### Returns
1725
-
1726
- `undefined` \| `T`
1727
-
1728
- The result of the function call, or the value at `target[key]` when `target` is an object or `target.get(key)` when it's a Map.
1729
-
1730
- ###### Example
1731
-
1732
- ```typescript
1733
- const $data = A.proxy({ a: 1, b: 2 });
1734
- A(() => {
1735
- // re-executes only when $data.a changes, because $data.b is peeked.
1736
- const b = A.peek(() => $data.b);
1737
- console.log(`A is ${$data.a}, B was ${b} when A changed.`);
1738
- });
1739
- $data.b = 3; // Does not trigger console.log
1740
- $data.a = 2; // Triggers console.log (logs "A is 2, B was 3 when A changed.")
1741
- ```
1742
-
1743
- ###### Call Signature
1744
-
1745
- > \<`T`\>(`target`): `T`
1746
-
1747
- Executes a function or retrieves a value *without* creating subscriptions in the current reactive scope, and returns its result.
1748
-
1749
- This is useful when you need to access reactive data inside a reactive scope (like [A](#a))
1750
- but do not want changes to that specific data to trigger a re-execute of the scope.
1751
-
1752
- Note: You may also use [unproxy](#unproxy) to get to the raw underlying data structure, which can be used to similar effect.
1753
-
1754
- ###### Type Parameters
1755
-
1756
- ###### T
1757
-
1758
- `T`
1759
-
1760
- ###### Parameters
1761
-
1762
- ###### target
1763
-
1764
- () => `T`
1765
-
1766
- Either a function to execute, or an object (which may also be an Array or a Map) to index.
1767
-
1768
- ###### Returns
1769
-
1770
- `T`
1771
-
1772
- The result of the function call, or the value at `target[key]` when `target` is an object or `target.get(key)` when it's a Map.
1773
-
1774
- ###### Example
1775
-
1776
- ```typescript
1777
- const $data = A.proxy({ a: 1, b: 2 });
1778
- A(() => {
1779
- // re-executes only when $data.a changes, because $data.b is peeked.
1780
- const b = A.peek(() => $data.b);
1781
- console.log(`A is ${$data.a}, B was ${b} when A changed.`);
1782
- });
1783
- $data.b = 3; // Does not trigger console.log
1784
- $data.a = 2; // Triggers console.log (logs "A is 2, B was 3 when A changed.")
1785
- ```
1786
-
1787
- ###### Returns
1788
-
1789
- The result of the function call, or the value at `target[key]` when `target` is an object or `target.get(key)` when it's a Map.
1790
-
1791
- ##### proxy()
1792
-
1793
- > **proxy**: \{\<`T`\>(`target`): [`PromiseProxy`](#promiseproxy)\<`T`\>; \<`T`\>(`target`): `T` *extends* `number` ? `number` : `T` *extends* `string` ? `string` : `T` *extends* `boolean` ? `boolean` : `T`[]; \<`T`\>(`target`): `T`; \<`T`\>(`target`): `ValueRef`\<`T` *extends* `number` ? `number` : `T` *extends* `string` ? `string` : `T` *extends* `boolean` ? `boolean` : `T`\>; \}
1794
-
1795
- Creates a reactive proxy around the given data.
1796
-
1797
- Reading properties from the returned proxy within a reactive scope (like one created by
1798
- [A](#a) or [derive](#derive)) establishes a subscription. Modifying properties *through*
1799
- the proxy will notify subscribed scopes, causing them to re-execute.
1800
-
1801
- - Plain objects, arrays, Maps, and Sets are wrapped in a standard JavaScript `Proxy` that intercepts
1802
- property access and mutations, but otherwise works like the underlying data.
1803
- - Primitives (string, number, boolean, null, undefined) are wrapped in an object
1804
- `{ value: T }` which is then proxied. Access the primitive via the `.value` property.
1805
- - Promises are represented by proxied objects `{ busy: boolean, value?: T, error?: any }`.
1806
- Initially, `busy` is `true`. When the promise resolves, `value` is set and `busy`
1807
- is set to `false`. If the promise is rejected, `error` is set and `busy` is also
1808
- set to `false`.
1809
-
1810
- Use [unproxy](#unproxy) to get the original underlying data back.
1811
- By convention in the examples below, local variables that hold proxied values are prefixed with `$`.
1812
-
1813
- ###### Call Signature
1814
-
1815
- > \<`T`\>(`target`): [`PromiseProxy`](#promiseproxy)\<`T`\>
1816
-
1817
- ###### Type Parameters
1818
-
1819
- ###### T
1820
-
1821
- `T` *extends* `unknown`
1822
-
1823
- ###### Parameters
1824
-
1825
- ###### target
1826
-
1827
- `Promise`\<`T`\>
1828
-
1829
- ###### Returns
1830
-
1831
- [`PromiseProxy`](#promiseproxy)\<`T`\>
1832
-
1833
- ###### Call Signature
1834
-
1835
- > \<`T`\>(`target`): `T` *extends* `number` ? `number` : `T` *extends* `string` ? `string` : `T` *extends* `boolean` ? `boolean` : `T`[]
1836
-
1837
- ###### Type Parameters
1838
-
1839
- ###### T
1840
-
1841
- `T` *extends* `unknown`
1842
-
1843
- ###### Parameters
1844
-
1845
- ###### target
1846
-
1847
- `T`[]
1848
-
1849
- ###### Returns
1850
-
1851
- `T` *extends* `number` ? `number` : `T` *extends* `string` ? `string` : `T` *extends* `boolean` ? `boolean` : `T`[]
1852
-
1853
- ###### Call Signature
1854
-
1855
- > \<`T`\>(`target`): `T`
1856
-
1857
- ###### Type Parameters
1858
-
1859
- ###### T
1860
-
1861
- `T` *extends* `object`
1862
-
1863
- ###### Parameters
1864
-
1865
- ###### target
1866
-
1867
- `T`
1868
-
1869
- ###### Returns
1870
-
1871
- `T`
1872
-
1873
- ###### Call Signature
1874
-
1875
- > \<`T`\>(`target`): `ValueRef`\<`T` *extends* `number` ? `number` : `T` *extends* `string` ? `string` : `T` *extends* `boolean` ? `boolean` : `T`\>
1876
-
1877
- ###### Type Parameters
1878
-
1879
- ###### T
1880
-
1881
- `T` *extends* `unknown`
1882
-
1883
- ###### Parameters
1884
-
1885
- ###### target
1886
-
1887
- `T`
1888
-
1889
- ###### Returns
1890
-
1891
- `ValueRef`\<`T` *extends* `number` ? `number` : `T` *extends* `string` ? `string` : `T` *extends* `boolean` ? `boolean` : `T`\>
1892
-
1893
- ###### Returns
1894
-
1895
- A reactive proxy wrapping the target data.
1896
-
1897
- ##### ref()
1898
-
1899
- > **ref**: \<`T`, `K`\>(`target`, `index`) => `ValueRef`\<`T`\[`K`\]\>
1900
-
1901
- Creates a reactive reference (`{ value: T }`-like object) to a specific value
1902
- within a proxied object or array.
1903
-
1904
- This is primarily used for the `bind` property in [A](#a) to create two-way data bindings
1905
- with form elements, and for passing a reactive property to any of the [A](#a) key-value pairs.
1906
-
1907
- Reading `ref.value` accesses the property from the underlying proxy (and subscribes the current scope).
1908
- Assigning to `ref.value` updates the property in the underlying proxy (triggering reactive updates).
1909
-
1910
- Creates a reactive reference (`{ value: T }`-like object) to a specific value
1911
- within a proxied object or array.
1912
-
1913
- This is primarily used for the `bind` property in [A](#a) to create two-way data bindings
1914
- with form elements, and for passing a reactive property to any of the [A](#a) key-value pairs.
1915
-
1916
- Reading `ref.value` accesses the property from the underlying proxy (and subscribes the current scope).
1917
- Assigning to `ref.value` updates the property in the underlying proxy (triggering reactive updates).
1918
-
1919
- ###### Type Parameters
1920
-
1921
- ###### T
1922
-
1923
- `T` *extends* `TargetType`
1924
-
1925
- ###### K
1926
-
1927
- `K` *extends* `string` \| `number` \| `symbol`
1928
-
1929
- ###### Parameters
1930
-
1931
- ###### target
1932
-
1933
- `T`
1934
-
1935
- The reactive proxy (created by [proxy](#proxy)) containing the target property.
1936
-
1937
- ###### index
1938
-
1939
- `K`
1940
-
1941
- The key (for objects) or index (for arrays) of the property to reference.
1942
-
1943
- ###### Returns
1944
-
1945
- `ValueRef`\<`T`\[`K`\]\>
1946
-
1947
- A reference object with a `value` property linked to the specified proxy property.
1948
-
1949
- ###### Example
1950
-
1951
- ```javascript
1952
- const $formData = A.proxy({ color: 'orange', velocity: 42 });
1953
-
1954
- // Usage with `bind`
1955
- A('input type=text bind=', A.ref($formData, 'color'));
1956
-
1957
- // Usage as a dynamic property, causes a TextNode with just the name to be created and live-updated
1958
- A('p text="Selected color: " text=', A.ref($formData, 'color'), 'color:', A.ref($formData, 'color'));
1959
-
1960
- // Changes are actually stored in $formData - this causes logs like `{color: "Blue", velocity 42}`
1961
- A(() => console.log($formData))
1962
- ```
1963
-
1964
- ###### Returns
1965
-
1966
- A reference object with a `value` property linked to the specified proxy property.
1967
-
1968
- ##### runQueue()
1969
-
1970
- > **runQueue**: () => `void`
1971
-
1972
- Forces the immediate and synchronous execution of all pending reactive updates.
1973
-
1974
- Normally, changes to observed data sources (like proxied objects or arrays)
1975
- are processed asynchronously in a batch after a brief timeout (0ms). This function
1976
- allows you to bypass the timeout and process the update queue immediately.
1977
-
1978
- This can be useful in specific scenarios where you need the DOM to be updated
1979
- synchronously.
1980
-
1981
- This function is re-entrant, meaning it is safe to call `runQueue` from within
1982
- a function that is itself being executed as part of an update cycle triggered
1983
- by a previous (or the same) `runQueue` call.
1984
-
1985
- Forces the immediate and synchronous execution of all pending reactive updates.
1986
-
1987
- Normally, changes to observed data sources (like proxied objects or arrays)
1988
- are processed asynchronously in a batch after a brief timeout (0ms). This function
1989
- allows you to bypass the timeout and process the update queue immediately.
1990
-
1991
- This can be useful in specific scenarios where you need the DOM to be updated
1992
- synchronously.
1993
-
1994
- This function is re-entrant, meaning it is safe to call `runQueue` from within
1995
- a function that is itself being executed as part of an update cycle triggered
1996
- by a previous (or the same) `runQueue` call.
1997
-
1998
- ###### Returns
1999
-
2000
- `void`
2001
-
2002
- ###### Example
2003
-
2004
- ```typescript
2005
- const $data = A.proxy("before");
2006
-
2007
- A('#', $data);
2008
- console.log(1, document.body.innerHTML); // before
2009
-
2010
- // Make an update that should cause the DOM to change.
2011
- $data.value = "after";
2012
-
2013
- // Normally, the DOM update would happen after a timeout.
2014
- // But this causes an immediate update:
2015
- A.runQueue();
2016
-
2017
- console.log(2, document.body.innerHTML); // after
2018
- ```
2019
-
2020
- ##### setErrorHandler()
2021
-
2022
- > **setErrorHandler**: (`handler?`) => `void`
2023
-
2024
- Sets a custom error handler function for errors that occur asynchronously
2025
- within reactive scopes (e.g., during updates triggered by proxy changes in
2026
- [derive](#derive) or [A](#a) render functions).
2027
-
2028
- The default handler logs the error to `console.error` and adds a simple
2029
- 'Error' message div to the DOM at the location where the error occurred (if possible).
2030
-
2031
- Your handler can provide custom logging, UI feedback, or suppress the default
2032
- error message.
2033
-
2034
- Sets a custom error handler function for errors that occur asynchronously
2035
- within reactive scopes (e.g., during updates triggered by proxy changes in
2036
- [derive](#derive) or [A](#a) render functions).
2037
-
2038
- The default handler logs the error to `console.error` and adds a simple
2039
- 'Error' message div to the DOM at the location where the error occurred (if possible).
2040
-
2041
- Your handler can provide custom logging, UI feedback, or suppress the default
2042
- error message.
2043
-
2044
- ###### Parameters
2045
-
2046
- ###### handler?
2047
-
2048
- (`error`) => `undefined` \| `boolean`
2049
-
2050
- A function that accepts the `Error` object.
2051
- - Return `false` to prevent adding an error message to the DOM.
2052
- - Return `true` or `undefined` (or throw) to allow the error messages to be added to the DOM.
2053
-
2054
- ###### Returns
2055
-
2056
- `void`
2057
-
2058
- ###### Example
2059
-
2060
- ```typescript
2061
- A.setErrorHandler(error => {
2062
- console.warn('Aberdeen render error:', error.message);
2063
- // Log to error reporting service
2064
- // myErrorReporter.log(error);
2065
-
2066
- try {
2067
- // Attempt to show a custom message in the UI
2068
- A('div#Oops, something went wrong!', errorClass);
2069
- } catch (e) {
2070
- // Ignore errors during error handling itself
2071
- }
2072
-
2073
- return false; // Suppress default console log and DOM error message
2074
- });
2075
-
2076
- // Styling for our custom error message
2077
- const errorClass = A.insertCss('background-color:#e31f00 display:inline-block color:white r:3px padding: 2px 4px;');
2078
-
2079
- // Cause an error within a render scope.
2080
- A('div.box', () => {
2081
- // Will cause our error handler to insert an error message within the box
2082
- noSuchFunction();
2083
- })
2084
- ```
2085
-
2086
- ##### setSpacingCssVars()
2087
-
2088
- > **setSpacingCssVars**: (`base`, `unit`) => `void`
2089
-
2090
- Initializes `cssVars[0]` through `cssVars[12]` with an exponential spacing scale.
2091
-
2092
- The scale is calculated as `2^(n-3) * base`, providing values from `0.25 * base` to `512 * base`.
2093
-
2094
- Initializes `cssVars[0]` through `cssVars[12]` with an exponential spacing scale.
2095
-
2096
- The scale is calculated as `2^(n-3) * base`, providing values from `0.25 * base` to `512 * base`.
2097
-
2098
- ###### Parameters
2099
-
2100
- ###### base
2101
-
2102
- `number` = `1`
2103
-
2104
- The base size for the spacing scale that will apply to `cssVars[3]`. Every step up the scale will double this, while every step down will halve it. Defaults to 1.
2105
-
2106
- ###### unit
2107
-
2108
- `string` = `'rem'`
2109
-
2110
- The CSS unit to use, like 'rem', 'em', or 'px'. Defaults to 'rem'.
2111
-
2112
- ###### Returns
2113
-
2114
- `void`
2115
-
2116
- ###### Example
2117
-
2118
- ```javascript
2119
- import A from 'aberdeen';
2120
- // Use default scale (0.25rem to 512rem)
2121
- A.setSpacingCssVars();
2122
-
2123
- // Use custom base size
2124
- A.setSpacingCssVars(16, 'px'); // 4px to 8192px
2125
-
2126
- // Use em units
2127
- A.setSpacingCssVars(1, 'em'); // 0.25em to 512em
2128
-
2129
- // Show the last generated spacing values
2130
- A.onEach(A.cssVars, (value, key) => {
2131
- A(`div #${key} → ${value}`)
2132
- }, (value, key) => parseInt(key)); // Numeric sort
2133
- ```
2134
-
2135
- ##### unmountAll()
2136
-
2137
- > **unmountAll**: () => `void`
2138
-
2139
- Removes all Aberdeen-managed DOM nodes and stops all active reactive scopes
2140
- (created by [mount](#mount), [derive](#derive), [A](#a) with functions, etc.).
2141
-
2142
- This effectively cleans up the entire Aberdeen application state. Aside from in
2143
- automated tests, there should probably be little reason to call this function.
2144
-
2145
- Removes all Aberdeen-managed DOM nodes and stops all active reactive scopes
2146
- (created by [mount](#mount), [derive](#derive), [A](#a) with functions, etc.).
2147
-
2148
- This effectively cleans up the entire Aberdeen application state. Aside from in
2149
- automated tests, there should probably be little reason to call this function.
2150
-
2151
- ###### Returns
2152
-
2153
- `void`
2154
-
2155
- ##### unproxy()
2156
-
2157
- > **unproxy**: \<`T`\>(`target`) => `T`
2158
-
2159
- Returns the original, underlying data target from a reactive proxy created by [proxy](#proxy).
2160
- If the input `target` is not a proxy, it is returned directly.
2161
-
2162
- This is useful when you want to avoid triggering subscriptions during read operations or
2163
- re-executes during write operations. Using [peek](#peek) is an alternative way to achieve this.
2164
-
2165
- Returns the original, underlying data target from a reactive proxy created by [proxy](#proxy).
2166
- If the input `target` is not a proxy, it is returned directly.
2167
-
2168
- This is useful when you want to avoid triggering subscriptions during read operations or
2169
- re-executes during write operations. Using [peek](#peek) is an alternative way to achieve this.
2170
-
2171
- ###### Type Parameters
2172
-
2173
- ###### T
2174
-
2175
- `T`
2176
-
2177
- The type of the target.
2178
-
2179
- ###### Parameters
2180
-
2181
- ###### target
2182
-
2183
- `T`
2184
-
2185
- A proxied object, array, or any other value.
2186
-
2187
- ###### Returns
2188
-
2189
- `T`
2190
-
2191
- The underlying (unproxied) data, or the input value if it wasn't a proxy.
2192
-
2193
- ###### Example
2194
-
2195
- ```typescript
2196
- const $user = A.proxy({ name: 'Frank' });
2197
- const rawUser = A.unproxy($user);
2198
-
2199
- // Log reactively
2200
- A(() => console.log('proxied', $user.name));
2201
- // The following will only ever log once, as we're not subscribing to any observable
2202
- A(() => console.log('unproxied', rawUser.name));
2203
-
2204
- // This cause the first log to run again:
2205
- setTimeout(() => $user.name += '!', 1000);
2206
-
2207
- // This doesn't cause any new logs:
2208
- setTimeout(() => rawUser.name += '?', 2000);
2209
-
2210
- // Both $user and rawUser end up as `{name: 'Frank!?'}`
2211
- setTimeout(() => {
2212
- console.log('final proxied', $user)
2213
- console.log('final unproxied', rawUser)
2214
- }, 3000);
2215
- ```
2216
-
2217
- ###### Returns
2218
-
2219
- The underlying (unproxied) data, or the input value if it wasn't a proxy.
2220
-
2221
- #### Example
2222
-
2223
- ```typescript
2224
- import A from 'aberdeen';
2225
-
2226
- const $state = A.proxy({ count: 0 });
2227
- A('div', () => {
2228
- A(`p#Count: ${$state.count}`);
2229
- A('button text=+ click=', () => $state.count++);
2230
- });
2231
- ```
2232
-
2233
- ***
2234
-
2235
- ### ~~NO\_COPY~~
2236
-
2237
- > `const` **NO\_COPY**: `symbol` = `OPAQUE`
2238
-
2239
- Defined in: [aberdeen.ts:1923](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1923)
2240
-
2241
- Use [OPAQUE](#opaque) instead. This is an alias kept for backward compatibility.
2242
-
2243
- #### Deprecated
2244
-
2245
- ***
2246
-
2247
- ### OPAQUE
2248
-
2249
- > `const` **OPAQUE**: *typeof* [`OPAQUE`](#opaque)
2250
-
2251
- Defined in: [aberdeen.ts:1916](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1916)
2252
-
2253
- A symbol that controls how Aberdeen handles an object in copy operations and proxy wrapping.
2254
-
2255
- The **presence** of this symbol (regardless of its value) prevents deep-copying: the object is
2256
- stored and passed by reference in [clone](#clone) and [copy](#copy).
2257
-
2258
- The **value** of the symbol controls proxy wrapping when the object is read from reactive state:
2259
- - **Truthy** (e.g. `true`): the object is fully opaque — it is not wrapped in a proxy, so its
2260
- properties are not observable. Use this for objects that break when proxied (e.g. class instances
2261
- with internal slots, Promises) or that must be invisible to Aberdeen's reactive system.
2262
- - **Falsy** (e.g. `false`): the object is still wrapped in a proxy, so reads on its properties
2263
- create reactive dependencies as normal — only deep-copying is suppressed.
2264
-
2265
- ## Functions
2266
-
2267
- ### A()
2268
-
2269
- > **A**(...`args`): `undefined` \| `Element`
2270
-
2271
- Defined in: [aberdeen.ts:2399](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L2399)
2272
-
2273
- The core function for building reactive user interfaces in Aberdeen. It creates and inserts new DOM elements
2274
- and sets attributes/properties/event listeners on DOM elements. It does so in a reactive way, meaning that
2275
- changes will be (mostly) undone when the current *scope* is destroyed or will be re-execute.
2276
-
2277
- #### Parameters
2278
-
2279
- ##### args
2280
-
2281
- ...`any`[]
2282
-
2283
- Any number of arguments can be given. How they're interpreted depends on their types:
2284
-
2285
- ### String arguments
2286
- Strings can be used to create and insert new elements, set classnames for the *current* element, and add text to the current element.
2287
- The format of a string is: (**tag** | `.` **class** | **key**[=:]**val** | **key**[=:]"**val containing spaces**")* ('#' **text** | **key**[=:])?
2288
-
2289
- So a string may consist of any number of...
2290
- - **tag** elements, like `h1` or `div`. These elements are created, added to the *current* element, and become the new *current* element for the rest of this `A` function execution.
2291
- - CSS classes prefixed by `.` characters. These classes will be added to the *current* element. Optionally, CSS classes can be appended to a **tag** without a space. So both `div.myclass` and `div .myclass` are valid and do the same thing.
2292
- - Property key/value pairs, like `type=password`, `placeholder="Your name"` or `data-id=123`. When the value contains spaces, it needs to be quoted with either "double quotes", 'single quotes' or `backticks`. Quotes within quoted values cannot be escaped (see the next rule for a solution). Key/value pairs will be handled according to *Property rules* below, but with the caveat that values can only be strings.
2293
- - CSS key/value pairs using two syntaxes:
2294
- - **Short form** `key:value` (no space after colon): The value ends at the next whitespace. Example: `m:$3 bg:red r:8px`
2295
- - **Long form** `key: value;` (space after colon): The value continues until a semicolon. Example: `box-shadow: 2px 0 6px black; transition: all 0.3s ease;`
2296
-
2297
- Both forms support CSS shortcuts (see below). You can mix them: `m:$3 box-shadow: 0 2px 4px rgba(0,0,0,0.2); bg:$cardBg`
2298
- The elements must be separated by spaces, except before a `.cssClass` if it is preceded by either **tag** or another CSS class.
2299
-
2300
- And a string may end in...
2301
- - A '#' followed by text, which will be added as a `TextNode` to the *current* element. The text ranges til the end of the string, and may contain any characters, including spaces and quotes.
2302
- - A key followed by an '=' character, in which case the value is expected as a separate argument. The key/value pair is set according to the *Property rules* below. This is useful when the value is not a string or contains spaces or user data. Example: `A('button text="Click me" click=', () => alert('Clicked!'))` or `A('input.value=', someUserData, "placeholder=", "Type your stuff")`. In case the value is a proxied object, its `.value` property will be applied reactively without needing to rerender the parent scope.
2303
- - A key followed by a ':' character (with no value), in which case the value is expected as a separate argument. The value is treated as a CSS value to be set inline on the *current* element. Example: `A('div margin-top:', someValueInPx)`. In case the value is a proxied object, its `.value` property will be applied reactively without needing to rerender the parent scope.
2304
-
2305
- ### Function arguments
2306
- When a function (without arguments nor a return value) is passed in, it will be reactively executed in its own observer scope, preserving the *current* element. So any `A()` invocations within this function will add child elements to or set properties on that element. 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 `A`, have been cleaned - see also [clean](#clean)).
2307
-
2308
- ### Object arguments
2309
- When an object is passed in, its key-value pairs are used to modify the *current* element according to the *Property rules* below, *unless* the key starts with a `$` character, in which case that character is stripped of and the key/value pair is treated as a CSS property, subject to the *CSS shortcuts* below. In case a value is a proxied object, its `.value` property will be applied reactively without needing to rerender the parent scope. In most cases, the string notation (`key=` and `key:`) is preferred over this object notation, for readability.
2310
-
2311
- ### DOM node arguments
2312
- When a DOM Node (Element or TextNode) is passed in, it is added as a child to the *current* element. If the Node is an Element, it becomes the new *current* element for the rest of this `A` function execution.
2313
-
2314
- ### Property rules
2315
- - **Attribute:** The common case is setting the value as an HTML attribute named key. For example `A('input placeholder=Name')` results in `<input placeholder="Name">`.
2316
- - **Event listener:** 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: A('button text=Press! click=', () => alert('Clicked!'))`. The event listener will be removed when the current scope is destroyed.
2317
- - **DOM property:** When the value is a boolean, or the key is `"value"` or `"selectedIndex"`, it is set on the `current` element as a DOM property instead of an HTML attribute. For example `A('checked=', true)` would do `el.checked = true` for the *current* element.
2318
- - **Conditional CSS class:** 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 `A('.hidden=', isHidden)` would toggle the `hidden` CSS class. This only works if the `=` is the last character of the string, and the next argument is the value. Its common for the value to be a proxied object, in which case its `.value` is reactively applied without needing to rerender the parent scope.
2319
- - **Create transition:** When the key is `"create"`, the value will be added as a CSS class to the *current* element immediately, and then removed right 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`. The initial dot is optional. Alternatively, to allow for more complex transitions, the value may be a function that receives the `HTMLElement` being created as its only argument. It is *only* called if this is the top-level element being created in this scope run. See `transitions.ts` in the Aberdeen source code for some examples.
2320
- - **Destroy transition:** When the key is `"destroy"` the value will be used to apply a CSS transition if the *current* element is later on removed from the DOM and is the top-level element to be removed. This happens as follows: 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`. The initial dot is optional. Alternatively, to allow for more complex transitions, the value may be a function that receives the `HTMLElement` to be removed from the DOM as its only argument. This function may perform any transitions and is then itself responsible for eventually removing the element from the DOM. See `transitions.ts` in the Aberdeen source code for some examples.
2321
- - **Two-way data binding:** When the key is `"bind"` a two-way binding between the `.value` property of the given proxied object, and the *current* input element (`<input>`, `<select>` or `<textarea>`) is created. This is often used together with {@link ref}, in order to use properties other than `.value`.
2322
- - **Text:**: If the key is `"text"`, the value will be appended as a `TextNode` to the *current* element. The same can also be done with the `#` syntax in string arguments, though `text=` allows additional properties to come after in the same string: `A('button text=Hello click=', alert)`.
2323
- - **Unsafe HTML:** When the key is `"html"`, the value will be added as HTML to the *current* element. This should only be used in exceptional situations. Beware of XSS! Never use this with untrusted user data.
2324
- - **Rich text:** When the key is `"rich"`, the value is parsed as simple markdown-like syntax and rendered as inline elements. Supports `*italic*`, `**bold**`, `` `code` ``, and `[link text](/path)`. All text content is safely escaped, making it suitable for user data (though links should be validated if untrusted). Example: `A('p rich="Click *here* for **more** info")`.
2325
-
2326
- ### CSS shortcuts
2327
- For conciseness, Aberdeen supports some CSS shortcuts when setting CSS properties.
2328
- | Shortcut | Expands to |
2329
- |----------|------------|
2330
- | `m`, `mt`, `mb`, `ml`, `mr` | `margin`, `margin-top`, `margin-bottom`, `margin-left`, `margin-right` |
2331
- | `mv`, `mh` | Vertical (top+bottom) or horizontal (left+right) margins |
2332
- | `p`, `pt`, `pb`, `pl`, `pr` | `padding`, `padding-top`, `padding-bottom`, `padding-left`, `padding-right` |
2333
- | `pv`, `ph` | Vertical or horizontal padding |
2334
- | `w`, `h` | `width`, `height` |
2335
- | `bg` | `background` |
2336
- | `fg` | `color` |
2337
- | `r` | `border-radius` |
2338
-
2339
- Also, when the value is a string starting with `$`, it is treated as a reference to a CSS variable, expanding to `var(--variableName)`. For numeric variable names (which can't be used directly as CSS custom property names), Aberdeen prefixes them with `m`, so `$3` expands to `var(--m3)`. This is primarily intended for use with [setSpacingCssVars](#setspacingcssvars), which initializes spacing variables named `0` through `12` with an exponential spacing scale.
2340
-
2341
- #### Returns
2342
-
2343
- `undefined` \| `Element`
2344
-
2345
- The most inner DOM element that was created (not counting text nodes nor elements created by content functions), or the current element if no new element was created. You should normally not need to use the return value - use this function's DOM manipulation abilities instead. One valid use case is when integrating with non-Aberdeen code that requires a reference to a DOM element.
2346
-
2347
- #### Examples
2348
-
2349
- ```typescript
2350
- A('button.secondary.outline text=Submit color:red disabled=', false, 'click=', () => console.log('Clicked!'));
2351
- ```
2352
-
2353
- We want to set `disabled` as a property instead of an attribute, so we must use the `key=` syntax in order to provide
2354
- `false` as a boolean instead of a string.
2355
-
2356
- ```typescript
2357
- let inputElement: Element = A('label text="Click me" input type=checkbox');
2358
- // You should usually not touch raw DOM elements, unless when integrating
2359
- // with non-Aberdeen code.
2360
- console.log('DOM element:', inputElement);
2361
- ```
2362
-
2363
- ```typescript
2364
- const $state = A.proxy({ count: 0 });
2365
- A('div', () => { // Outer element
2366
- // This scope re-renders when $state.count changes
2367
- A(`p#Count is ${$state.count}`);
2368
- A('button text=Increment click=', () => $state.count++);
2369
- });
2370
- ```
2371
-
2372
- ```typescript
2373
- const $user = A.proxy({ name: '' });
2374
- A('input placeholder=Name bind=', A.ref($user, 'name'));
2375
- A('h3', () => { // Reactive scope
2376
- A(`#Hello ${$user.name || 'stranger'}`);
2377
- });
2378
- ```
2379
-
2380
- ```typescript
2381
- const $show = A.proxy(false);
2382
- A('button click=', () => $show.value = !$show.value, () => A($show.value ? '#Hide' : '#Show'));
2383
- A(() => { // Reactive scope
2384
- if ($show.value) {
2385
- A('p#Details are visible!');
2386
- }
2387
- });
2388
- ```
2389
-
2390
- ```typescript
2391
- const $myColor = A.proxy('red');
2392
- A('p text="The color is " text=', $myColor, 'click=', () => $myColor.value = 'yellow')
2393
- // Clicking the text will cause it to change color without recreating the <p> itself
2394
- ```
2395
- This is often used together with [ref](#ref), in order to use properties other than `.value`.
2396
-
2397
- ***
2398
-
2399
- ### clean()
2400
-
2401
- > **clean**(`cleaner`): `void`
2402
-
2403
- Defined in: [aberdeen.ts:2935](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L2935)
2404
-
2405
- Registers a cleanup function to be executed just before the current reactive scope
2406
- is destroyed or redraws.
2407
-
2408
- This is useful for releasing resources, removing manual event listeners, or cleaning up
2409
- side effects associated with the scope. Cleaners are run in reverse order of registration.
2410
-
2411
- Scopes are created by functions like [derive](#derive), [mount](#mount), [A](#a) (when given a render function),
2412
- and internally by constructs like [onEach](#oneach).
2413
-
2414
- #### Parameters
2415
-
2416
- ##### cleaner
2417
-
2418
- () => `void`
2419
-
2420
- The function to execute during cleanup.
2421
-
2422
- #### Returns
2423
-
2424
- `void`
2425
-
2426
- #### Example
2427
-
2428
- ```typescript
2429
- const $numbers = A.proxy([3, 5, 10]);
2430
- let $sum = A.proxy(0);
2431
-
2432
- // Show the array items and maintain the sum
2433
- A.onEach($numbers, (item, index) => {
2434
- A(`code#${index}→${item}`);
2435
- // We'll update $sum.value using peek, as += first does a read, but
2436
- // we don't want to subscribe.
2437
- A.peek(() => $sum.value += item);
2438
- // Clean gets called before each rerun for a certain item index
2439
- // No need for peek here, as the clean code doesn't run in an
2440
- // observer scope.
2441
- A.clean(() => $sum.value -= item);
2442
- })
2443
-
2444
- // Show the sum
2445
- A('h1 text=', $sum);
2446
-
2447
- // Make random changes to the array
2448
- const rnd = () => 0|(Math.random()*20);
2449
- setInterval(() => $numbers[rnd()] = rnd(), 1000);
2450
- ```
2451
-
2452
- ***
2453
-
2454
- ### clone()
2455
-
2456
- > **clone**\<`T`\>(`src`): `T`
2457
-
2458
- Defined in: [aberdeen.ts:2081](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L2081)
2459
-
2460
- Clone an (optionally proxied) object or array.
2461
-
2462
- #### Type Parameters
2463
-
2464
- ##### T
2465
-
2466
- `T` *extends* `object`
2467
-
2468
- The type of the objects being copied.
2469
-
2470
- #### Parameters
2471
-
2472
- ##### src
2473
-
2474
- `T`
2475
-
2476
- The object or array to clone. If it is proxied, `clone` will subscribe to any changes to the (nested) data structure.
2477
-
2478
- #### Returns
2479
-
2480
- `T`
2481
-
2482
- A new unproxied array or object (of the same type as `src`), containing a deep copy of `src`.
2483
-
2484
- ***
2485
-
2486
- ### copy()
2487
-
2488
- #### Call Signature
2489
-
2490
- > **copy**\<`T`\>(`dst`, `src`): `boolean`
2491
-
2492
- Defined in: [aberdeen.ts:1708](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1708)
2493
-
2494
- Recursively copies properties or array items from `src` to `dst`.
2495
- It's designed to work efficiently with reactive proxies created by [proxy](#proxy).
2496
-
2497
- - **Minimizes Updates:** When copying between objects/arrays (proxied or not), if a nested object
2498
- exists in `dst` with the same constructor as the corresponding object in `src`, `copy`
2499
- will recursively copy properties into the existing `dst` object instead of replacing it.
2500
- This minimizes change notifications for reactive (proxied) destinations.
2501
- - **Fast with Proxies:** When copying to/from proxied objects, `copy` uses Aberdeen internals
2502
- to speed things up (compared to a non-Aberdeen-aware deep copy).
2503
-
2504
- ##### Type Parameters
2505
-
2506
- ###### T
2507
-
2508
- `T` *extends* `object`
2509
-
2510
- The type of the objects being copied.
2511
-
2512
- ##### Parameters
2513
-
2514
- ###### dst
2515
-
2516
- `T`
2517
-
2518
- The destination object/array/Map (proxied or unproxied).
2519
-
2520
- ###### src
2521
-
2522
- `T`
2523
-
2524
- The source object/array/Map (proxied or unproxied). It won't be modified.
2525
-
2526
- ##### Returns
2527
-
2528
- `boolean`
2529
-
2530
- `true` if any changes were made to `dst`, or `false` if not.
2531
-
2532
- ##### Throws
2533
-
2534
- Error if attempting to copy an array into a non-array or vice versa.
2535
-
2536
- ##### Example
2537
-
2538
- ```typescript
2539
- const $source = A.proxy({ a: 1, b: { c: 2 } });
2540
- const $dest = A.proxy({ b: { d: 3 } });
2541
- A.copy($dest, $source);
2542
- console.log($dest); // proxy({ a: 1, b: { c: 2 } })
2543
- A.copy($dest, 'b', { e: 4 });
2544
- console.log($dest); // proxy({ a: 1, b: { e: 4 } })
2545
- ```
2546
-
2547
- #### Call Signature
2548
-
2549
- > **copy**\<`T`\>(`dst`, `dstKey`, `src`): `boolean`
2550
-
2551
- Defined in: [aberdeen.ts:1715](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1715)
2552
-
2553
- Like above, but copies `src` into `dst[dstKey]`. This is useful if you're unsure if dst[dstKey]
2554
- already exists (as the right type of object) or if you don't want to subscribe to dst[dstKey].
2555
-
2556
- ##### Type Parameters
2557
-
2558
- ###### T
2559
-
2560
- `T` *extends* `object`
2561
-
2562
- ##### Parameters
2563
-
2564
- ###### dst
2565
-
2566
- `T`
2567
-
2568
- ###### dstKey
2569
-
2570
- keyof `T`
2571
-
2572
- Optional key in `dst` to copy into.
2573
-
2574
- ###### src
2575
-
2576
- `T`\[keyof `T`\]
2577
-
2578
- ##### Returns
2579
-
2580
- `boolean`
2581
-
2582
- ***
2583
-
2584
- ### count()
2585
-
2586
- > **count**(`proxied`): `ValueRef`\<`number`\>
2587
-
2588
- Defined in: [aberdeen.ts:1155](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1155)
2589
-
2590
- Reactively counts the number of properties in an object.
2591
-
2592
- #### Parameters
2593
-
2594
- ##### proxied
2595
-
2596
- `TargetType`
2597
-
2598
- The observable object to count. In case an `array`, `Map`, or `Set` is passed in, a [ref](#ref) to its `.length` or `.size` will be returned.
2599
-
2600
- #### Returns
2601
-
2602
- `ValueRef`\<`number`\>
2603
-
2604
- an observable object for which the `value` property reflects the number of properties in `proxied` with a value other than `undefined`, or the collection size for arrays, Maps, and Sets.
2605
-
2606
- #### Example
2607
-
2608
- ```typescript
2609
- const $items = A.proxy({x: 3, y: 7} as any);
2610
- const $count = A.count($items);
2611
-
2612
- // Create a DOM text node for the count:
2613
- A('div text=', $count);
2614
- // <div>2</div>
2615
-
2616
- // Or we can use it in an {@link derive} function:
2617
- A(() => console.log("The count is now", $count.value));
2618
- // The count is now 2
2619
-
2620
- // Adding/removing items will update the count
2621
- $items.z = 12;
2622
- // Asynchronously, after 0ms:
2623
- // <div>3</div>
2624
- // The count is now 3
2625
- ```
2626
-
2627
- ***
2628
-
2629
- ### darkMode()
2630
-
2631
- > **darkMode**(): `boolean`
2632
-
2633
- Defined in: [aberdeen.ts:2038](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L2038)
2634
-
2635
- Returns whether the user's browser prefers a dark color scheme.
2636
-
2637
- This function is reactive - scopes that call it will re-execute when the
2638
- browser's color scheme preference changes (via the `prefers-color-scheme` media query).
2639
-
2640
- Use this in combination with [A](#a) and [cssVars](#cssvars) to implement theme switching:
2641
-
2642
- #### Returns
2643
-
2644
- `boolean`
2645
-
2646
- `true` if the browser prefers dark mode, `false` if it prefers light mode.
2647
-
2648
- #### Example
2649
-
2650
- ```javascript
2651
- import A from 'aberdeen';
2652
-
2653
- // Reactively set colors based on browser preference
2654
- A(() => {
2655
- A.cssVars.bg = A.darkMode() ? '#1a1a1a' : '#ffffff';
2656
- A.cssVars.fg = A.darkMode() ? '#e5e5e5' : '#000000';
2657
- });
2658
-
2659
- A('div bg:$bg fg:$fg p:1rem #Colors change based on system dark mode preference');
2660
- ```
2661
-
2662
- ***
2663
-
2664
- ### derive()
2665
-
2666
- > **derive**\<`T`\>(`func`): `ValueRef`\<`T`\>
2667
-
2668
- Defined in: [aberdeen.ts:2987](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L2987)
2669
-
2670
- Creates a reactive scope that automatically re-executes the provided function
2671
- whenever any proxied data (created by [proxy](#proxy)) read during its last execution changes, storing
2672
- its return value in an observable.
2673
-
2674
- Updates are batched and run asynchronously shortly after the changes occur.
2675
- Use [clean](#clean) to register cleanup logic for the scope.
2676
- Use [peek](#peek) or [unproxy](#unproxy) within the function to read proxied data without subscribing to it.
2677
-
2678
- #### Type Parameters
2679
-
2680
- ##### T
2681
-
2682
- `T`
2683
-
2684
- #### Parameters
2685
-
2686
- ##### func
2687
-
2688
- () => `T`
2689
-
2690
- The function to execute reactively. Any DOM manipulations should typically
2691
- be done using [A](#a) within this function. Its return value will be made available as an
2692
- observable returned by the `derive()` function.
2693
-
2694
- #### Returns
2695
-
2696
- `ValueRef`\<`T`\>
2697
-
2698
- An observable object, with its `value` property containing whatever the last run of `func` returned.
2699
-
2700
- #### Examples
2701
-
2702
- ```typescript
2703
- const $data = A.proxy({ user: 'Frank', notifications: 42 });
2704
-
2705
- A('main', () => {
2706
- console.log('Welcome');
2707
- A('h3#Welcome, ' + $data.user); // Reactive text
2708
-
2709
- A.derive(() => {
2710
- // When $data.notifications changes, only this inner scope reruns,
2711
- // leaving the `<p>Welcome, ..</p>` untouched.
2712
- console.log('Notifications');
2713
- A('code.notification-badge text=', $data.notifications);
2714
- A('a text=Notify! click=', () => $data.notifications++);
2715
- });
2716
- });
2717
- ```
2718
-
2719
- ***Note*** that the above could just as easily be done using `A(func)` instead of `derive(func)`.
2720
-
2721
- ```typescript
2722
- const $counter = A.proxy(0);
2723
- setInterval(() => $counter.value++, 1000);
2724
- const $double = A.derive(() => $counter.value * 2);
2725
-
2726
- A('h3', () => {
2727
- A(`#counter=${$counter.value} double=${$double.value}`);
2728
- })
2729
- ```
2730
-
2731
- ***
2732
-
2733
- ### disableCreateDestroy()
2734
-
2735
- > **disableCreateDestroy**(): `void`
2736
-
2737
- Defined in: [aberdeen.ts:2275](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L2275)
2738
-
2739
- Make the `create` and `destroy` special properties no-ops.
2740
-
2741
- This is useful from within automated testing environments, where the transitioning
2742
- new and lingering old elements may make writing reliable selectors difficult.
2743
-
2744
- As this is only intended for testing, there's no way to re-enable the special properties
2745
- once disabled.
2746
-
2747
- #### Returns
2748
-
2749
- `void`
2750
-
2751
- ***
2752
-
2753
- ### dump()
2754
-
2755
- > **dump**\<`T`\>(`data`): `T`
2756
-
2757
- Defined in: [aberdeen.ts:3408](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3408)
2758
-
2759
- Renders a live, recursive dump of a proxied data structure (or any value)
2760
- into the DOM at the current [A](#a) insertion point.
2761
-
2762
- Uses `<ul>` and `<li>` elements to display object properties and array items.
2763
- Updates reactively if the dumped data changes. Primarily intended for debugging purposes.
2764
-
2765
- #### Type Parameters
2766
-
2767
- ##### T
2768
-
2769
- `T`
2770
-
2771
- The type of the data being dumped.
2772
-
2773
- #### Parameters
2774
-
2775
- ##### data
2776
-
2777
- `T`
2778
-
2779
- The proxied data structure (or any value) to display.
2780
-
2781
- #### Returns
2782
-
2783
- `T`
2784
-
2785
- The original `data` argument, allowing for chaining.
2786
-
2787
- #### Example
2788
-
2789
- ```typescript
2790
- import A from 'aberdeen';
2791
-
2792
- const $state = A.proxy({
2793
- user: { name: 'Frank', kids: 1 },
2794
- items: ['a', 'b']
2795
- });
2796
-
2797
- A('h2#Live State Dump');
2798
- A.dump($state);
2799
-
2800
- // Change state later, the dump in the DOM will update
2801
- setTimeout(() => { $state.user.kids++; $state.items.push('c'); }, 2000);
2802
- ```
2803
-
2804
- ***
2805
-
2806
- ### insertCss()
2807
-
2808
- > **insertCss**(`style`): `string`
2809
-
2810
- Defined in: [aberdeen.ts:2597](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L2597)
2811
-
2812
- Inserts CSS rules into the document, scoping them with a unique class name.
2813
-
2814
- The `style` parameter can be either:
2815
- - A **concise style string** (for rules applying to the root class).
2816
- - An **object** where keys are selectors (with `&` representing the root class)
2817
- and values are concise style strings or nested objects. When the key does not contain `&`,
2818
- it is treated as a descendant selector. So `{p: "color:red"}` becomes `".AbdStlX p { color: red; }"` with `AbdStlX` being the generated class name.
2819
-
2820
- ### Concise Style Strings
2821
-
2822
- Concise style strings use two syntaxes (same as inline CSS in [A](#a)):
2823
- - **Short form** `key:value` (no space after colon): The value ends at the next whitespace.
2824
- Example: `'m:$3 bg:red r:8px'`
2825
- - **Long form** `key: value;` (space after colon): The value continues until a semicolon.
2826
- Example: `'box-shadow: 2px 0 6px black; transition: all 0.3s ease;'`
2827
-
2828
- Both forms can be mixed: `'m:$3 box-shadow: 0 2px 4px rgba(0,0,0,0.2); bg:$cardBg'`
2829
-
2830
- Supports the same CSS shortcuts as [A](#a) and CSS variable references with `$` (e.g., `$primary`, `$3`).
2831
-
2832
- #### Parameters
2833
-
2834
- ##### style
2835
-
2836
- A concise style string or a style object.
2837
-
2838
- `string` | `object`
2839
-
2840
- #### Returns
2841
-
2842
- `string`
2843
-
2844
- The unique class name prefix used for scoping (e.g., `.AbdStl1`).
2845
- Use this prefix with [A](#a) to apply the styles.
2846
-
2847
- #### Examples
2848
-
2849
- ```typescript
2850
- const cardClass = A.insertCss({
2851
- '&': 'bg:white p:$4 r:8px transition: background-color 0.3s;',
2852
- '&:hover': 'bg:#f5f5f5',
2853
- });
2854
-
2855
- A('section', cardClass, () => {
2856
- A('p#Card content');
2857
- });
2858
- ```
2859
-
2860
- ```typescript
2861
- const formClass = A.insertCss({
2862
- '&': 'bg:#0004 p:$3 r:$2',
2863
- button: {
2864
- '&': 'bg:$primary fg:white p:$2 r:4px cursor:pointer',
2865
- '&:hover': 'bg:$primaryHover',
2866
- '&:disabled': 'bg:#ccc cursor:not-allowed',
2867
- '.icon': 'display:inline-block mr:$1',
2868
- '@media (max-width: 600px)': 'p:$1 font-size:14px'
2869
- }
2870
- });
2871
-
2872
- A('form', formClass, () => {
2873
- A('button', () => {
2874
- A('span.icon text=🔥');
2875
- A('#Click Me');
2876
- });
2877
- });
2878
- ```
2879
-
2880
- ```typescript
2881
- const badge = A.insertCss({
2882
- '&::before': 'content: "★"; color:gold mr:$1',
2883
- '&': 'position:relative box-shadow: 0 2px 8px rgba(0,0,0,0.15);'
2884
- });
2885
-
2886
- A(badge + ' span#Product Name');
2887
- ```
2888
-
2889
- ***
2890
-
2891
- ### insertGlobalCss()
2892
-
2893
- > **insertGlobalCss**(`style`): `void`
2894
-
2895
- Defined in: [aberdeen.ts:2749](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L2749)
2896
-
2897
- Inserts CSS rules globally (unscoped).
2898
-
2899
- Works exactly like [insertCss](#insertcss), but without prefixing selectors with a unique class name.
2900
- This is useful for global resets, base styles, or styles that need to apply to the entire document.
2901
-
2902
- Accepts the same concise style string syntax and CSS shortcuts as [insertCss](#insertcss).
2903
- See [insertCss](#insertcss) for detailed documentation on syntax and shortcuts.
2904
-
2905
- #### Parameters
2906
-
2907
- ##### style
2908
-
2909
- `object`
2910
-
2911
- Object with selectors as keys and concise CSS strings as values.
2912
-
2913
- #### Returns
2914
-
2915
- `void`
2916
-
2917
- #### Examples
2918
-
2919
- ```typescript
2920
- // Set up global styles using CSS shortcuts
2921
- A.insertGlobalCss({
2922
- "*": "m:0 p:0 box-sizing:border-box",
2923
- "body": "font-family: system-ui, sans-serif; m:0 p:$3 bg:#434 fg:#d0dafa",
2924
- "a": "text-decoration:none fg:#57f",
2925
- "a:hover": "text-decoration:underline",
2926
- "code": "font-family:monospace bg:#222 fg:#afc p:4px r:3px"
2927
- });
2928
-
2929
- A('h2#Title without margins');
2930
- A('a#This is a link');
2931
- A('code#const x = 42;');
2932
- ```
2933
-
2934
- ```typescript
2935
- A.insertGlobalCss({
2936
- "html": "font-size:16px",
2937
- "body": "line-height:1.6",
2938
- "h1, h2, h3": "font-weight:600 mt:$4 mb:$2",
2939
- "@media (max-width: 768px)": {
2940
- "html": "font-size:14px",
2941
- "body": "p:$2"
2942
- },
2943
- "@media (prefers-color-scheme: dark)": {
2944
- "body": "bg:#1a1a1a fg:#e5e5e5",
2945
- "code": "bg:#2a2a2a"
2946
- }
2947
- });
2948
- ```
2949
- At-rules such as `@media` and `@keyframes` should use nested objects. For keyframes,
2950
- the step selectors (`0%`, `50%`, `100%`, etc.) become the nested keys and each value
2951
- should be a concise CSS declaration string.
2952
-
2953
- ```typescript
2954
- A.insertGlobalCss({
2955
- "@keyframes connection-pulse": {
2956
- "0%": "box-shadow: inset 0 0 0 0 rgba(255, 70, 70, 0.4);",
2957
- "50%": "box-shadow: inset 0 0 0 6px rgba(255, 70, 70, 0.08);",
2958
- "100%": "box-shadow: inset 0 0 0 0 rgba(255, 70, 70, 0.4);"
2959
- }
2960
- });
2961
- ```
2962
-
2963
- ***
2964
-
2965
- ### invertString()
2966
-
2967
- > **invertString**(`input`): `string`
2968
-
2969
- Defined in: [aberdeen.ts:192](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L192)
2970
-
2971
- Creates a new string that has the opposite sort order compared to the input string.
2972
-
2973
- This is achieved by flipping the bits of each character code in the input string.
2974
- The resulting string is intended for use as a sort key, particularly with the
2975
- `makeKey` function in [onEach](#oneach), to achieve a descending sort order.
2976
-
2977
- **Warning:** The output string will likely contain non-printable characters or
2978
- appear as gibberish and should not be displayed to the user.
2979
-
2980
- #### Parameters
2981
-
2982
- ##### input
2983
-
2984
- `string`
2985
-
2986
- The string whose sort order needs to be inverted.
2987
-
2988
- #### Returns
2989
-
2990
- `string`
2991
-
2992
- A new string that will sort in the reverse order of the input string.
2993
-
2994
- #### Example
2995
-
2996
- ```typescript
2997
- const $users = A.proxy([
2998
- { id: 1, name: 'Charlie', score: 95 },
2999
- { id: 2, name: 'Alice', score: 100 },
3000
- { id: 3, name: 'Bob', score: 90 },
3001
- ]);
3002
-
3003
- A.onEach($users, ($user) => {
3004
- A(`p#${$user.name}: ${$user.score}`);
3005
- }, ($user) => A.invertString($user.name)); // Reverse alphabetic order
3006
- ```
3007
-
3008
- #### See
3009
-
3010
- [onEach](#oneach) for usage with sorting.
3011
-
3012
- ***
3013
-
3014
- ### isEmpty()
3015
-
3016
- > **isEmpty**(`proxied`): `boolean`
3017
-
3018
- Defined in: [aberdeen.ts:1095](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1095)
3019
-
3020
- Reactively checks if an observable array, object, Map, or Set is empty.
3021
-
3022
- This function not only returns the current emptiness state but also establishes
3023
- a reactive dependency. If the emptiness state of the `proxied` object or array
3024
- changes later (e.g., an item is added to an empty array, or the last property
3025
- is deleted from an object), the scope that called `isEmpty` will be automatically
3026
- scheduled for re-evaluation.
3027
-
3028
- #### Parameters
3029
-
3030
- ##### proxied
3031
-
3032
- `TargetType`
3033
-
3034
- The observable array, object, Map, or Set to check.
3035
-
3036
- #### Returns
3037
-
3038
- `boolean`
3039
-
3040
- `true` if the array has length 0, the Map/Set has size 0, or the object has no own enumerable properties, `false` otherwise.
3041
-
3042
- #### Example
3043
-
3044
- ```typescript
3045
- const $items = A.proxy([]);
3046
-
3047
- // Reactively display a message if the items array is empty
3048
- A('div', () => {
3049
- if (A.isEmpty($items)) {
3050
- A('p i#No items yet!');
3051
- } else {
3052
- A.onEach($items, item => A('p#'+item));
3053
- }
3054
- });
3055
-
3056
- // Adding an item will automatically remove the "No items yet!" message
3057
- setInterval(() => {
3058
- if (!$items.length || Math.random()>0.5) $items.push('Item');
3059
- else $items.length = 0;
3060
- }, 1000)
3061
- ```
3062
-
3063
- ***
3064
-
3065
- ### map()
3066
-
3067
- Reactively maps/filters items from a proxied source array or object to a new proxied array or object.
3068
-
3069
- It iterates over the `target` proxy. For each item, it calls `func`.
3070
- - If `func` returns a value, it's added to the result proxy under the same key/index.
3071
- - If `func` returns `undefined`, the item is skipped (filtered out).
3072
-
3073
- The returned proxy automatically updates when:
3074
- - Items are added/removed/updated in the `target` proxy.
3075
- - Any proxied data read *within* the `func` call changes (for a specific item).
3076
-
3077
- #### Param
3078
-
3079
- A function `(value, key) => mappedValue | undefined` that transforms each item.
3080
- It receives the item's value and its key/index. Return `undefined` to filter the item out.
3081
-
3082
- #### Template
3083
-
3084
- The type of items in the source proxy.
3085
-
3086
- #### Template
3087
-
3088
- The type of items in the resulting proxy.
3089
-
3090
- #### Examples
3091
-
3092
- ```typescript
3093
- const $numbers = A.proxy([1, 2, 3]);
3094
- const $doubled = A.map($numbers, (n) => n * 2);
3095
- // $doubled is proxy([2, 4, 6])
3096
-
3097
- A(() => console.log($doubled)); // Logs updates
3098
- $numbers.push(4); // $doubled becomes proxy([2, 4, 6, 8])
3099
- ```
3100
-
3101
- ```typescript
3102
- const $users = A.proxy({
3103
- 'u1': { name: 'Alice', active: true },
3104
- 'u2': { name: 'Bob', active: false },
3105
- 'u3': { name: 'Charlie', active: true }
3106
- });
3107
-
3108
- const $activeUserNames = A.map($users, ($user) => $user.active ? $user.name : undefined);
3109
- // $activeUserNames is proxy({ u1: 'Alice', u3: 'Charlie' })
3110
- A(() => console.log(Object.values($activeUserNames)));
3111
-
3112
- $users.u2.active = true;
3113
- // $activeUserNames becomes proxy({ u1: 'Alice', u2: 'Bob', u3: 'Charlie' })
3114
- ```
3115
-
3116
- #### Call Signature
3117
-
3118
- > **map**\<`K`, `IN`, `OUT`\>(`source`, `func`): `Map`\<`K`, `OUT`\>
3119
-
3120
- Defined in: [aberdeen.ts:3095](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3095)
3121
-
3122
- When using a Map as `source`.
3123
-
3124
- ##### Type Parameters
3125
-
3126
- ###### K
3127
-
3128
- `K`
3129
-
3130
- ###### IN
3131
-
3132
- `IN`
3133
-
3134
- ###### OUT
3135
-
3136
- `OUT`
3137
-
3138
- ##### Parameters
3139
-
3140
- ###### source
3141
-
3142
- `Map`\<`K`, `IN`\>
3143
-
3144
- ###### func
3145
-
3146
- (`value`, `key`) => `undefined` \| `OUT`
3147
-
3148
- ##### Returns
3149
-
3150
- `Map`\<`K`, `OUT`\>
3151
-
3152
- #### Call Signature
3153
-
3154
- > **map**\<`IN`, `OUT`\>(`source`, `func`): `OUT`[]
3155
-
3156
- Defined in: [aberdeen.ts:3100](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3100)
3157
-
3158
- When using an array as `source`.
3159
-
3160
- ##### Type Parameters
3161
-
3162
- ###### IN
3163
-
3164
- `IN`
3165
-
3166
- ###### OUT
3167
-
3168
- `OUT`
3169
-
3170
- ##### Parameters
3171
-
3172
- ###### source
3173
-
3174
- `IN`[]
3175
-
3176
- ###### func
3177
-
3178
- (`value`, `index`) => `undefined` \| `OUT`
3179
-
3180
- ##### Returns
3181
-
3182
- `OUT`[]
3183
-
3184
- #### Call Signature
3185
-
3186
- > **map**\<`IN`, `IN_KEY`, `OUT`\>(`source`, `func`): `Record`\<`string` \| `symbol`, `OUT`\>
3187
-
3188
- Defined in: [aberdeen.ts:3105](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3105)
3189
-
3190
- When using an object as `source`.
3191
-
3192
- ##### Type Parameters
3193
-
3194
- ###### IN
3195
-
3196
- `IN`
3197
-
3198
- ###### IN_KEY
3199
-
3200
- `IN_KEY` *extends* `string` \| `number` \| `symbol`
3201
-
3202
- ###### OUT
3203
-
3204
- `OUT`
3205
-
3206
- ##### Parameters
3207
-
3208
- ###### source
3209
-
3210
- `Record`\<`IN_KEY`, `IN`\>
3211
-
3212
- ###### func
3213
-
3214
- (`value`, `index`) => `undefined` \| `OUT`
3215
-
3216
- ##### Returns
3217
-
3218
- `Record`\<`string` \| `symbol`, `OUT`\>
3219
-
3220
- ***
3221
-
3222
- ### merge()
3223
-
3224
- #### Call Signature
3225
-
3226
- > **merge**\<`T`\>(`dst`, `value`): `boolean`
3227
-
3228
- Defined in: [aberdeen.ts:1748](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1748)
3229
-
3230
- Like [copy](#copy), but uses merge semantics. Properties in `dst` not present in `src` are kept.
3231
- `null`/`undefined` in `src` delete properties in `dst`.
3232
-
3233
- ##### Type Parameters
3234
-
3235
- ###### T
3236
-
3237
- `T` *extends* `object`
3238
-
3239
- ##### Parameters
3240
-
3241
- ###### dst
3242
-
3243
- `T`
3244
-
3245
- ###### value
3246
-
3247
- `Partial`\<`T`\>
3248
-
3249
- ##### Returns
3250
-
3251
- `boolean`
3252
-
3253
- ##### Example
3254
-
3255
- ```typescript
3256
- const source = { b: { c: 99 }, d: undefined }; // d: undefined will delete
3257
- const $dest = A.proxy({ a: 1, b: { x: 5 }, d: 4 });
3258
- A.merge($dest, source);
3259
- A.merge($dest, 'b', { y: 6 }); // merge into $dest.b
3260
- A.merge($dest, 'c', { z: 7 }); // $dest.c doesn't exist yet, so it will just be assigned
3261
- console.log($dest); // proxy({ a: 1, b: { c: 99, x: 5, y: 6 }, c: { z: 7 } })
3262
- ```
3263
-
3264
- #### Call Signature
3265
-
3266
- > **merge**\<`T`\>(`dst`, `dstKey`, `value`): `boolean`
3267
-
3268
- Defined in: [aberdeen.ts:1749](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1749)
3269
-
3270
- Like [copy](#copy), but uses merge semantics. Properties in `dst` not present in `src` are kept.
3271
- `null`/`undefined` in `src` delete properties in `dst`.
3272
-
3273
- ##### Type Parameters
3274
-
3275
- ###### T
3276
-
3277
- `T` *extends* `object`
3278
-
3279
- ##### Parameters
3280
-
3281
- ###### dst
3282
-
3283
- `T`
3284
-
3285
- ###### dstKey
3286
-
3287
- keyof `T`
3288
-
3289
- ###### value
3290
-
3291
- `Partial`\<`T`\[keyof `T`\]\>
3292
-
3293
- ##### Returns
3294
-
3295
- `boolean`
3296
-
3297
- ##### Example
3298
-
3299
- ```typescript
3300
- const source = { b: { c: 99 }, d: undefined }; // d: undefined will delete
3301
- const $dest = A.proxy({ a: 1, b: { x: 5 }, d: 4 });
3302
- A.merge($dest, source);
3303
- A.merge($dest, 'b', { y: 6 }); // merge into $dest.b
3304
- A.merge($dest, 'c', { z: 7 }); // $dest.c doesn't exist yet, so it will just be assigned
3305
- console.log($dest); // proxy({ a: 1, b: { c: 99, x: 5, y: 6 }, c: { z: 7 } })
3306
- ```
3307
-
3308
- ***
3309
-
3310
- ### mount()
3311
-
3312
- > **mount**(`parentElement`, `func`): `void`
3313
-
3314
- Defined in: [aberdeen.ts:3034](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3034)
3315
-
3316
- Attaches a reactive Aberdeen UI fragment to an existing DOM element. Without the use of
3317
- this function, [A](#a) will assume `document.body` as its root.
3318
-
3319
- It creates a top-level reactive scope associated with the `parentElement`. The provided
3320
- function `func` is executed immediately within this scope. Any proxied data read by `func`
3321
- will cause it to re-execute when the data changes, updating the DOM elements created within it.
3322
-
3323
- Calls to [A](#a) inside `func` will append nodes to `parentElement`.
3324
- You can nest [derive](#derive) or other [A](#a) scopes within `func`.
3325
- Use [unmountAll](#unmountall) to clean up all mounted scopes and their DOM nodes.
3326
-
3327
- Mounting scopes happens reactively, meaning that if this function is called from within another
3328
- ([derive](#derive) or [A](#a) or [mount](#mount)) scope that gets cleaned up, so will the mount.
3329
-
3330
- #### Parameters
3331
-
3332
- ##### parentElement
3333
-
3334
- `Element`
3335
-
3336
- The native DOM `Element` to which the UI fragment will be appended.
3337
-
3338
- ##### func
3339
-
3340
- () => `void`
3341
-
3342
- The function that defines the UI fragment, typically containing calls to [A](#a).
3343
-
3344
- #### Returns
3345
-
3346
- `void`
3347
-
3348
- #### Example
3349
-
3350
- ```javascript
3351
- // Create a pre-existing DOM structure (without Aberdeen)
3352
- document.body.innerHTML = `<h3>Static content <span id="title-extra"></span></h3><div class="box" id="app-root"></div>`;
3353
-
3354
- import A from 'aberdeen';
3355
-
3356
- const $runTime = A.proxy(0);
3357
- setInterval(() => $runTime.value++, 1000);
3358
-
3359
- A.mount(document.getElementById('app-root'), () => {
3360
- A('h4#Aberdeen App');
3361
- A(`p#Run time: ${$runTime.value}s`);
3362
- // Conditionally render some content somewhere else in the static page
3363
- if ($runTime.value&1) {
3364
- A.mount(document.getElementById('title-extra'), () =>
3365
- A(`i#(${$runTime.value}s)`)
3366
- );
3367
- }
3368
- });
3369
- ```
3370
-
3371
- Note how the inner mount behaves reactively as well, automatically unmounting when it's parent observer scope re-runs.
3372
-
3373
- ***
3374
-
3375
- ### multiMap()
3376
-
3377
- Reactively maps items from a source proxy (array or object) to a target proxied object,
3378
- where each source item can contribute multiple key-value pairs to the target.
3379
-
3380
- It iterates over the `target` proxy. For each item, it calls `func`.
3381
- - If `func` returns an object, all key-value pairs from that object are added to the result proxy.
3382
- - If `func` returns `undefined`, the item contributes nothing.
3383
-
3384
- The returned proxy automatically updates when:
3385
- - Items are added/removed/updated in the `target` proxy.
3386
- - Any proxied data read *within* the `func` call changes (for a specific item).
3387
- - If multiple input items produce the same output key, the last one processed usually "wins",
3388
- but the exact behavior on collision depends on update timing.
3389
-
3390
- This is useful for "flattening" or "indexing" data, or converting an observable array to an observable object.
3391
-
3392
- #### Param
3393
-
3394
- The source proxied array or object.
3395
-
3396
- #### Param
3397
-
3398
- A function `(value, key) => ({...pairs} | undefined)` that transforms an item
3399
- into an object of key-value pairs to add, or `undefined` to add nothing.
3400
-
3401
- #### Template
3402
-
3403
- The type of items in the source proxy.
3404
-
3405
- #### Template
3406
-
3407
- The type of the aggregated output object (should encompass all possible key-value pairs).
3408
-
3409
- #### Example
3410
-
3411
- ```typescript
3412
- const $items = A.proxy([
3413
- { id: 'a', value: 10 },
3414
- { id: 'b', value: 20 },
3415
- ]);
3416
- const $itemsById = A.multiMap($items, ($item) => ({
3417
- [$item.id]: $item.value,
3418
- [$item.id+$item.id]: $item.value*10,
3419
- }));
3420
- // $itemsById is proxy({ a: 10, aa: 100, b: 20, bb: 200 })
3421
-
3422
- A(() => console.log($itemsById));
3423
-
3424
- $items.push({ id: 'c', value: 30 });
3425
- // $itemsById becomes proxy({ a: 10, aa: 100, b: 20, bb: 200, c: 30, cc: 300 })
3426
- ```
3427
-
3428
- #### Call Signature
3429
-
3430
- > **multiMap**\<`IN`, `OUT`\>(`source`, `func`): `OUT`
3431
-
3432
- Defined in: [aberdeen.ts:3185](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3185)
3433
-
3434
- When using an array as `source`.
3435
-
3436
- ##### Type Parameters
3437
-
3438
- ###### IN
3439
-
3440
- `IN`
3441
-
3442
- ###### OUT
3443
-
3444
- `OUT` *extends* `object`
3445
-
3446
- ##### Parameters
3447
-
3448
- ###### source
3449
-
3450
- `IN`[]
3451
-
3452
- ###### func
3453
-
3454
- (`value`, `index`) => `undefined` \| `OUT`
3455
-
3456
- ##### Returns
3457
-
3458
- `OUT`
3459
-
3460
- #### Call Signature
3461
-
3462
- > **multiMap**\<`K`, `IN`, `OUT`\>(`source`, `func`): `OUT`
3463
-
3464
- Defined in: [aberdeen.ts:3190](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3190)
3465
-
3466
- When using an object as `source`.
3467
-
3468
- ##### Type Parameters
3469
-
3470
- ###### K
3471
-
3472
- `K` *extends* `string` \| `number` \| `symbol`
3473
-
3474
- ###### IN
3475
-
3476
- `IN`
3477
-
3478
- ###### OUT
3479
-
3480
- `OUT` *extends* `object`
3481
-
3482
- ##### Parameters
3483
-
3484
- ###### source
3485
-
3486
- `Record`\<`K`, `IN`\>
3487
-
3488
- ###### func
3489
-
3490
- (`value`, `index`) => `undefined` \| `OUT`
3491
-
3492
- ##### Returns
3493
-
3494
- `OUT`
3495
-
3496
- #### Call Signature
3497
-
3498
- > **multiMap**\<`K`, `IN`, `OUT`\>(`source`, `func`): `OUT`
3499
-
3500
- Defined in: [aberdeen.ts:3196](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3196)
3501
-
3502
- When using a Map as `source`.
3503
-
3504
- ##### Type Parameters
3505
-
3506
- ###### K
3507
-
3508
- `K`
3509
-
3510
- ###### IN
3511
-
3512
- `IN`
3513
-
3514
- ###### OUT
3515
-
3516
- `OUT` *extends* `object`
3517
-
3518
- ##### Parameters
3519
-
3520
- ###### source
3521
-
3522
- `Map`\<`K`, `IN`\>
3523
-
3524
- ###### func
3525
-
3526
- (`value`, `key`) => `undefined` \| `OUT`
3527
-
3528
- ##### Returns
3529
-
3530
- `OUT`
3531
-
3532
- ***
3533
-
3534
- ### onEach()
3535
-
3536
- Reactively iterates over the items of an observable array, object, Map, or Set, optionally rendering content for each item.
3537
-
3538
- Automatically updates when items are added, removed, or modified.
3539
-
3540
- #### Param
3541
-
3542
- The observable array, object, Map, or Set to iterate over. Values that are `undefined` are skipped.
3543
-
3544
- #### Param
3545
-
3546
- A function called for each item. It receives the item's (observable) value and its index/key. For Sets, only the value is provided. Any DOM elements created within this function will be associated with the item, placed at the right spot in the DOM, and cleaned up when redrawing/removing the item.
3547
-
3548
- #### Param
3549
-
3550
- An optional function to generate a sort key for each item. This controls the order in which items are rendered in the DOM. If omitted, arrays use index order, Sets use the item value itself, and objects/Maps use their natural key order. The returned key can be a number, string, or an array of numbers/strings for composite sorting. Use [invertString](#invertstring) on string keys for descending order. Returning `null` or `undefined` from `makeKey` will prevent the item from being rendered.
3551
-
3552
- #### Examples
3553
-
3554
- ```typescript
3555
- const $items = A.proxy(['apple', 'banana', 'cherry']);
3556
-
3557
- // Basic iteration
3558
- A.onEach($items, (item, index) => A(`li#${item} (#${index})`));
3559
-
3560
- // Add a new item - the list updates automatically
3561
- setTimeout(() => $items.push('durian'), 2000);
3562
- // Same for updates and deletes
3563
- setTimeout(() => $items[1] = 'berry', 4000);
3564
- setTimeout(() => delete $items[2], 6000);
3565
- ```
3566
-
3567
- ```typescript
3568
- const $users = A.proxy([
3569
- { id: 3, group: 1, name: 'Charlie' },
3570
- { id: 1, group: 1, name: 'Alice' },
3571
- { id: 2, group: 2, name: 'Bob' },
3572
- ]);
3573
-
3574
- // Sort by name alphabetically
3575
- A.onEach($users, ($user) => {
3576
- A(`p#${$user.name} (id=${$user.id})`);
3577
- }, ($user) => [$user.group, $user.name]); // Sort by group, and within each group sort by name
3578
- ```
3579
-
3580
- ```javascript
3581
- const $config = A.proxy({ theme: 'dark', fontSize: 14, showTips: true });
3582
-
3583
- // Display configuration options
3584
- A('dl', () => {
3585
- A.onEach($config, (value, key) => {
3586
- if (key === 'showTips') return; // Don't render this one
3587
- A('dt#'+key);
3588
- A('dd#'+value);
3589
- });
3590
- });
3591
-
3592
- // Change a value - the display updates automatically
3593
- setTimeout(() => $config.fontSize = 16, 2000);
3594
- ```
3595
-
3596
- ```javascript
3597
- const $tags = A.proxy(new Set(['ui', 'fast', 'tiny']));
3598
-
3599
- A('ul', () => {
3600
- A.onEach($tags, (tag) => { // Defaults to alphabetically ordering by tag
3601
- A(`li#${tag}`);
3602
- });
3603
- });
3604
-
3605
- setTimeout(() => $tags.add('reactive'), 2000);
3606
- ```
3607
-
3608
- #### See
3609
-
3610
- [invertString](#invertstring) To easily create keys for reverse sorting.
3611
-
3612
- #### Call Signature
3613
-
3614
- > **onEach**\<`K`, `T`\>(`target`, `render`, `makeKey?`): `void`
3615
-
3616
- Defined in: [aberdeen.ts:954](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L954)
3617
-
3618
- ##### Type Parameters
3619
-
3620
- ###### K
3621
-
3622
- `K`
3623
-
3624
- ###### T
3625
-
3626
- `T`
3627
-
3628
- ##### Parameters
3629
-
3630
- ###### target
3631
-
3632
- `Map`\<`K`, `undefined` \| `T`\>
3633
-
3634
- ###### render
3635
-
3636
- (`value`, `key`) => `void`
3637
-
3638
- ###### makeKey?
3639
-
3640
- (`value`, `key`) => `SortKeyType`
3641
-
3642
- ##### Returns
3643
-
3644
- `void`
3645
-
3646
- #### Call Signature
3647
-
3648
- > **onEach**\<`T`\>(`target`, `render`, `makeKey?`): `void`
3649
-
3650
- Defined in: [aberdeen.ts:959](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L959)
3651
-
3652
- ##### Type Parameters
3653
-
3654
- ###### T
3655
-
3656
- `T`
3657
-
3658
- ##### Parameters
3659
-
3660
- ###### target
3661
-
3662
- `Set`\<`T`\>
3663
-
3664
- ###### render
3665
-
3666
- (`value`) => `void`
3667
-
3668
- ###### makeKey?
3669
-
3670
- (`value`) => `SortKeyType`
3671
-
3672
- ##### Returns
3673
-
3674
- `void`
3675
-
3676
- #### Call Signature
3677
-
3678
- > **onEach**\<`T`\>(`target`, `render`, `makeKey?`): `void`
3679
-
3680
- Defined in: [aberdeen.ts:964](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L964)
3681
-
3682
- ##### Type Parameters
3683
-
3684
- ###### T
3685
-
3686
- `T`
3687
-
3688
- ##### Parameters
3689
-
3690
- ###### target
3691
-
3692
- readonly (`undefined` \| `T`)[]
3693
-
3694
- ###### render
3695
-
3696
- (`value`, `index`) => `void`
3697
-
3698
- ###### makeKey?
3699
-
3700
- (`value`, `index`) => `SortKeyType`
3701
-
3702
- ##### Returns
3703
-
3704
- `void`
3705
-
3706
- #### Call Signature
3707
-
3708
- > **onEach**\<`K`, `T`\>(`target`, `render`, `makeKey?`): `void`
3709
-
3710
- Defined in: [aberdeen.ts:969](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L969)
3711
-
3712
- ##### Type Parameters
3713
-
3714
- ###### K
3715
-
3716
- `K` *extends* `string` \| `number` \| `symbol`
3717
-
3718
- ###### T
3719
-
3720
- `T`
3721
-
3722
- ##### Parameters
3723
-
3724
- ###### target
3725
-
3726
- `Record`\<`K`, `undefined` \| `T`\>
3727
-
3728
- ###### render
3729
-
3730
- (`value`, `index`) => `void`
3731
-
3732
- ###### makeKey?
3733
-
3734
- (`value`, `index`) => `SortKeyType`
3735
-
3736
- ##### Returns
3737
-
3738
- `void`
3739
-
3740
- ***
3741
-
3742
- ### partition()
3743
-
3744
- Reactively partitions items from a source proxy (array or object) into multiple "bucket" proxies
3745
- based on keys determined by a classifier function.
3746
-
3747
- This function iterates through the `source` proxy using [onEach](#oneach). For each item,
3748
- it calls the classifier `func`, which should return:
3749
- - A single key (`OUT_K`): The item belongs to the bucket with this key.
3750
- - An array of keys (`OUT_K[]`): The item belongs to all buckets specified in the array.
3751
- - `undefined`: The item is not placed in any bucket.
3752
-
3753
- The function returns a main proxied object. The keys of this object are the bucket keys (`OUT_K`)
3754
- returned by `func`. Each value associated with a bucket key is another proxied object (the "bucket").
3755
- This inner bucket object maps the *original* keys/indices from the `source` to the items
3756
- themselves that were classified into that bucket.
3757
-
3758
- The entire structure is reactive. Changes in the `source` proxy (adding/removing/updating items)
3759
- or changes in dependencies read by the `func` will cause the output partitioning to update automatically.
3760
- Buckets are created dynamically as needed and removed when they become empty.
3761
-
3762
- #### Param
3763
-
3764
- The input proxied Array or Record (e.g., created by [proxy](#proxy)) containing the items to partition.
3765
-
3766
- #### Param
3767
-
3768
- A classifier function `(value: IN_V, key: IN_K | number) => undefined | OUT_K | OUT_K[]`.
3769
- It receives the item's value and its original key/index from the `source`. It returns the bucket key(s)
3770
- the item belongs to, or `undefined` to ignore the item.
3771
-
3772
- #### Template
3773
-
3774
- The type of the keys used for the output buckets (string, number, or symbol).
3775
-
3776
- #### Template
3777
-
3778
- The type of the values in the source proxy.
3779
-
3780
- #### Template
3781
-
3782
- The type of the keys in the source proxy (if it's a Record).
3783
-
3784
- #### Examples
3785
-
3786
- ```typescript
3787
- interface Product { id: string; category: string; name: string; }
3788
- const $products = A.proxy<Product[]>([
3789
- { id: 'p1', category: 'Fruit', name: 'Apple' },
3790
- { id: 'p2', category: 'Veg', name: 'Carrot' },
3791
- { id: 'p3', category: 'Fruit', name: 'Banana' },
3792
- ]);
3793
-
3794
- // Partition products by category. Output keys are categories (string).
3795
- // Inner keys are original array indices (number).
3796
- const $productsByCategory = A.partition($products, ($product) => $product.category);
3797
-
3798
- // Reactively show the data structure
3799
- A.dump($productsByCategory);
3800
-
3801
- // Make random changes to the categories, to show reactiveness
3802
- setInterval(() => $products[0|(Math.random()*3)].category = ['Snack','Fruit','Veg'][0|(Math.random()*3)], 2000);
3803
- ```
3804
-
3805
- ```typescript
3806
- interface User { id: number; tags: string[]; name: string; }
3807
- const $users = A.proxy({
3808
- 'u1': { name: 'Alice', tags: ['active', 'new'] },
3809
- 'u2': { name: 'Bob', tags: ['active'] }
3810
- });
3811
-
3812
- // Partition users by tag. Output keys are tags (string).
3813
- // Inner keys are original object keys (string: 'u1', 'u2').
3814
- const $usersByTag = A.partition($users, ($user) => $user.tags);
3815
-
3816
- console.log($usersByTag);
3817
- ```
3818
-
3819
- #### Call Signature
3820
-
3821
- > **partition**\<`OUT_K`, `IN_V`\>(`source`, `func`): `Record`\<`OUT_K`, `Record`\<`number`, `IN_V`\>\>
3822
-
3823
- Defined in: [aberdeen.ts:3260](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3260)
3824
-
3825
- When using an object as `array`.
3826
-
3827
- ##### Type Parameters
3828
-
3829
- ###### OUT_K
3830
-
3831
- `OUT_K` *extends* `string` \| `number` \| `symbol`
3832
-
3833
- ###### IN_V
3834
-
3835
- `IN_V`
3836
-
3837
- ##### Parameters
3838
-
3839
- ###### source
3840
-
3841
- `IN_V`[]
3842
-
3843
- ###### func
3844
-
3845
- (`value`, `key`) => `undefined` \| `OUT_K` \| `OUT_K`[]
3846
-
3847
- ##### Returns
3848
-
3849
- `Record`\<`OUT_K`, `Record`\<`number`, `IN_V`\>\>
3850
-
3851
- #### Call Signature
3852
-
3853
- > **partition**\<`IN_K`, `OUT_K`, `IN_V`\>(`source`, `func`): `Record`\<`OUT_K`, `Record`\<`IN_K`, `IN_V`\>\>
3854
-
3855
- Defined in: [aberdeen.ts:3265](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3265)
3856
-
3857
- When using an object as `source`.
3858
-
3859
- ##### Type Parameters
3860
-
3861
- ###### IN_K
3862
-
3863
- `IN_K` *extends* `string` \| `number` \| `symbol`
3864
-
3865
- ###### OUT_K
3866
-
3867
- `OUT_K` *extends* `string` \| `number` \| `symbol`
3868
-
3869
- ###### IN_V
3870
-
3871
- `IN_V`
3872
-
3873
- ##### Parameters
3874
-
3875
- ###### source
3876
-
3877
- `Record`\<`IN_K`, `IN_V`\>
3878
-
3879
- ###### func
3880
-
3881
- (`value`, `key`) => `undefined` \| `OUT_K` \| `OUT_K`[]
3882
-
3883
- ##### Returns
3884
-
3885
- `Record`\<`OUT_K`, `Record`\<`IN_K`, `IN_V`\>\>
3886
-
3887
- #### Call Signature
3888
-
3889
- > **partition**\<`IN_K`, `OUT_K`, `IN_V`\>(`source`, `func`): `Record`\<`OUT_K`, `Record`\<`IN_K`, `IN_V`\>\>
3890
-
3891
- Defined in: [aberdeen.ts:3274](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3274)
3892
-
3893
- When using a Map as `source`.
3894
-
3895
- ##### Type Parameters
3896
-
3897
- ###### IN_K
3898
-
3899
- `IN_K` *extends* `string` \| `number` \| `symbol`
3900
-
3901
- ###### OUT_K
3902
-
3903
- `OUT_K` *extends* `string` \| `number` \| `symbol`
3904
-
3905
- ###### IN_V
3906
-
3907
- `IN_V`
3908
-
3909
- ##### Parameters
3910
-
3911
- ###### source
3912
-
3913
- `Map`\<`IN_K`, `IN_V`\>
3914
-
3915
- ###### func
3916
-
3917
- (`value`, `key`) => `undefined` \| `OUT_K` \| `OUT_K`[]
3918
-
3919
- ##### Returns
3920
-
3921
- `Record`\<`OUT_K`, `Record`\<`IN_K`, `IN_V`\>\>
3922
-
3923
- ***
3924
-
3925
- ### peek()
3926
-
3927
- #### Call Signature
3928
-
3929
- > **peek**\<`T`, `K`\>(`target`, `key`): `T`\[`K`\]
3930
-
3931
- Defined in: [aberdeen.ts:3076](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3076)
3932
-
3933
- Executes a function or retrieves a value *without* creating subscriptions in the current reactive scope, and returns its result.
3934
-
3935
- This is useful when you need to access reactive data inside a reactive scope (like [A](#a))
3936
- but do not want changes to that specific data to trigger a re-execute of the scope.
3937
-
3938
- Note: You may also use [unproxy](#unproxy) to get to the raw underlying data structure, which can be used to similar effect.
3939
-
3940
- ##### Type Parameters
3941
-
3942
- ###### T
3943
-
3944
- `T` *extends* `object`
3945
-
3946
- ###### K
3947
-
3948
- `K` *extends* `string` \| `number` \| `symbol`
3949
-
3950
- ##### Parameters
3951
-
3952
- ###### target
3953
-
3954
- `T`
3955
-
3956
- Either a function to execute, or an object (which may also be an Array or a Map) to index.
3957
-
3958
- ###### key
3959
-
3960
- `K`
3961
-
3962
- Optional key/index to use when `target` is an object.
3963
-
3964
- ##### Returns
3965
-
3966
- `T`\[`K`\]
3967
-
3968
- The result of the function call, or the value at `target[key]` when `target` is an object or `target.get(key)` when it's a Map.
3969
-
3970
- ##### Example
3971
-
3972
- ```typescript
3973
- const $data = A.proxy({ a: 1, b: 2 });
3974
- A(() => {
3975
- // re-executes only when $data.a changes, because $data.b is peeked.
3976
- const b = A.peek(() => $data.b);
3977
- console.log(`A is ${$data.a}, B was ${b} when A changed.`);
3978
- });
3979
- $data.b = 3; // Does not trigger console.log
3980
- $data.a = 2; // Triggers console.log (logs "A is 2, B was 3 when A changed.")
3981
- ```
3982
-
3983
- #### Call Signature
3984
-
3985
- > **peek**\<`K`, `V`\>(`target`, `key`): `undefined` \| `V`
3986
-
3987
- Defined in: [aberdeen.ts:3077](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3077)
3988
-
3989
- Executes a function or retrieves a value *without* creating subscriptions in the current reactive scope, and returns its result.
3990
-
3991
- This is useful when you need to access reactive data inside a reactive scope (like [A](#a))
3992
- but do not want changes to that specific data to trigger a re-execute of the scope.
3993
-
3994
- Note: You may also use [unproxy](#unproxy) to get to the raw underlying data structure, which can be used to similar effect.
3995
-
3996
- ##### Type Parameters
3997
-
3998
- ###### K
3999
-
4000
- `K`
4001
-
4002
- ###### V
4003
-
4004
- `V`
4005
-
4006
- ##### Parameters
4007
-
4008
- ###### target
4009
-
4010
- `Map`\<`K`, `V`\>
4011
-
4012
- Either a function to execute, or an object (which may also be an Array or a Map) to index.
4013
-
4014
- ###### key
4015
-
4016
- `K`
4017
-
4018
- Optional key/index to use when `target` is an object.
4019
-
4020
- ##### Returns
4021
-
4022
- `undefined` \| `V`
4023
-
4024
- The result of the function call, or the value at `target[key]` when `target` is an object or `target.get(key)` when it's a Map.
4025
-
4026
- ##### Example
4027
-
4028
- ```typescript
4029
- const $data = A.proxy({ a: 1, b: 2 });
4030
- A(() => {
4031
- // re-executes only when $data.a changes, because $data.b is peeked.
4032
- const b = A.peek(() => $data.b);
4033
- console.log(`A is ${$data.a}, B was ${b} when A changed.`);
4034
- });
4035
- $data.b = 3; // Does not trigger console.log
4036
- $data.a = 2; // Triggers console.log (logs "A is 2, B was 3 when A changed.")
4037
- ```
4038
-
4039
- #### Call Signature
4040
-
4041
- > **peek**\<`T`\>(`target`, `key`): `undefined` \| `T`
4042
-
4043
- Defined in: [aberdeen.ts:3078](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3078)
4044
-
4045
- Executes a function or retrieves a value *without* creating subscriptions in the current reactive scope, and returns its result.
4046
-
4047
- This is useful when you need to access reactive data inside a reactive scope (like [A](#a))
4048
- but do not want changes to that specific data to trigger a re-execute of the scope.
4049
-
4050
- Note: You may also use [unproxy](#unproxy) to get to the raw underlying data structure, which can be used to similar effect.
4051
-
4052
- ##### Type Parameters
4053
-
4054
- ###### T
4055
-
4056
- `T`
4057
-
4058
- ##### Parameters
4059
-
4060
- ###### target
4061
-
4062
- `T`[]
4063
-
4064
- Either a function to execute, or an object (which may also be an Array or a Map) to index.
4065
-
4066
- ###### key
4067
-
4068
- `number`
4069
-
4070
- Optional key/index to use when `target` is an object.
4071
-
4072
- ##### Returns
4073
-
4074
- `undefined` \| `T`
4075
-
4076
- The result of the function call, or the value at `target[key]` when `target` is an object or `target.get(key)` when it's a Map.
4077
-
4078
- ##### Example
4079
-
4080
- ```typescript
4081
- const $data = A.proxy({ a: 1, b: 2 });
4082
- A(() => {
4083
- // re-executes only when $data.a changes, because $data.b is peeked.
4084
- const b = A.peek(() => $data.b);
4085
- console.log(`A is ${$data.a}, B was ${b} when A changed.`);
4086
- });
4087
- $data.b = 3; // Does not trigger console.log
4088
- $data.a = 2; // Triggers console.log (logs "A is 2, B was 3 when A changed.")
4089
- ```
4090
-
4091
- #### Call Signature
4092
-
4093
- > **peek**\<`T`\>(`target`): `T`
4094
-
4095
- Defined in: [aberdeen.ts:3079](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3079)
4096
-
4097
- Executes a function or retrieves a value *without* creating subscriptions in the current reactive scope, and returns its result.
4098
-
4099
- This is useful when you need to access reactive data inside a reactive scope (like [A](#a))
4100
- but do not want changes to that specific data to trigger a re-execute of the scope.
4101
-
4102
- Note: You may also use [unproxy](#unproxy) to get to the raw underlying data structure, which can be used to similar effect.
4103
-
4104
- ##### Type Parameters
4105
-
4106
- ###### T
4107
-
4108
- `T`
4109
-
4110
- ##### Parameters
4111
-
4112
- ###### target
4113
-
4114
- () => `T`
4115
-
4116
- Either a function to execute, or an object (which may also be an Array or a Map) to index.
4117
-
4118
- ##### Returns
4119
-
4120
- `T`
4121
-
4122
- The result of the function call, or the value at `target[key]` when `target` is an object or `target.get(key)` when it's a Map.
4123
-
4124
- ##### Example
4125
-
4126
- ```typescript
4127
- const $data = A.proxy({ a: 1, b: 2 });
4128
- A(() => {
4129
- // re-executes only when $data.a changes, because $data.b is peeked.
4130
- const b = A.peek(() => $data.b);
4131
- console.log(`A is ${$data.a}, B was ${b} when A changed.`);
4132
- });
4133
- $data.b = 3; // Does not trigger console.log
4134
- $data.a = 2; // Triggers console.log (logs "A is 2, B was 3 when A changed.")
4135
- ```
4136
-
4137
- ***
1074
+ > **proxy**\<`T`\>(`target`): [`PromiseProxy`](#promiseproxy)\<`T`\>
4138
1075
 
4139
- ### proxy()
1076
+ Defined in: [aberdeen.ts:826](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L826)
4140
1077
 
4141
1078
  Creates a reactive proxy around the given data.
4142
1079
 
4143
1080
  Reading properties from the returned proxy within a reactive scope (like one created by
4144
- [A](#a) or [derive](#derive)) establishes a subscription. Modifying properties *through*
1081
+ [A](#aberdeen) or [Aberdeen.derive](#derive)) establishes a subscription. Modifying properties *through*
4145
1082
  the proxy will notify subscribed scopes, causing them to re-execute.
4146
1083
 
4147
1084
  - Plain objects, arrays, Maps, and Sets are wrapped in a standard JavaScript `Proxy` that intercepts
@@ -4153,18 +1090,32 @@ the proxy will notify subscribed scopes, causing them to re-execute.
4153
1090
  is set to `false`. If the promise is rejected, `error` is set and `busy` is also
4154
1091
  set to `false`.
4155
1092
 
4156
- Use [unproxy](#unproxy) to get the original underlying data back.
1093
+ Use [Aberdeen.unproxy](#unproxy) to get the original underlying data back.
4157
1094
  By convention in the examples below, local variables that hold proxied values are prefixed with `$`.
4158
1095
 
4159
- #### Param
1096
+ ###### Type Parameters
4160
1097
 
4161
- The object, array, Map, Set, or primitive value to make reactive.
1098
+ ###### T
4162
1099
 
4163
- #### Template
1100
+ `T` *extends* `unknown`
4164
1101
 
4165
1102
  The type of the data being proxied.
4166
1103
 
4167
- #### Examples
1104
+ ###### Parameters
1105
+
1106
+ ###### target
1107
+
1108
+ `Promise`\<`T`\>
1109
+
1110
+ The object, array, Map, Set, or primitive value to make reactive.
1111
+
1112
+ ###### Returns
1113
+
1114
+ [`PromiseProxy`](#promiseproxy)\<`T`\>
1115
+
1116
+ A reactive proxy wrapping the target data.
1117
+
1118
+ ###### Examples
4168
1119
 
4169
1120
  ```javascript
4170
1121
  const $state = A.proxy({ count: 0, message: 'Hello' });
@@ -4203,142 +1154,52 @@ setTimeout(() => $graph.grow(), 2000);
4203
1154
  setTimeout(() => $graph.grow(), 4000);
4204
1155
  ```
4205
1156
 
4206
- #### Call Signature
4207
-
4208
- > **proxy**\<`T`\>(`target`): [`PromiseProxy`](#promiseproxy)\<`T`\>
4209
-
4210
- Defined in: [aberdeen.ts:1542](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1542)
4211
-
4212
- ##### Type Parameters
4213
-
4214
- ###### T
4215
-
4216
- `T` *extends* `unknown`
4217
-
4218
- ##### Parameters
4219
-
4220
- ###### target
4221
-
4222
- `Promise`\<`T`\>
4223
-
4224
- ##### Returns
4225
-
4226
- [`PromiseProxy`](#promiseproxy)\<`T`\>
4227
-
4228
- #### Call Signature
4229
-
4230
- > **proxy**\<`T`\>(`target`): `T` *extends* `number` ? `number` : `T` *extends* `string` ? `string` : `T` *extends* `boolean` ? `boolean` : `T`[]
4231
-
4232
- Defined in: [aberdeen.ts:1543](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1543)
4233
-
4234
- ##### Type Parameters
4235
-
4236
- ###### T
4237
-
4238
- `T` *extends* `unknown`
4239
-
4240
- ##### Parameters
4241
-
4242
- ###### target
4243
-
4244
- `T`[]
4245
-
4246
- ##### Returns
4247
-
4248
- `T` *extends* `number` ? `number` : `T` *extends* `string` ? `string` : `T` *extends* `boolean` ? `boolean` : `T`[]
4249
-
4250
- #### Call Signature
4251
-
4252
- > **proxy**\<`T`\>(`target`): `T`
4253
-
4254
- Defined in: [aberdeen.ts:1544](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1544)
4255
-
4256
- ##### Type Parameters
4257
-
4258
- ###### T
4259
-
4260
- `T` *extends* `object`
4261
-
4262
- ##### Parameters
4263
-
4264
- ###### target
4265
-
4266
- `T`
4267
-
4268
- ##### Returns
4269
-
4270
- `T`
4271
-
4272
- #### Call Signature
4273
-
4274
- > **proxy**\<`T`\>(`target`): `ValueRef`\<`T` *extends* `number` ? `number` : `T` *extends* `string` ? `string` : `T` *extends* `boolean` ? `boolean` : `T`\>
4275
-
4276
- Defined in: [aberdeen.ts:1545](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1545)
4277
-
4278
- ##### Type Parameters
4279
-
4280
- ###### T
4281
-
4282
- `T` *extends* `unknown`
4283
-
4284
- ##### Parameters
4285
-
4286
- ###### target
4287
-
4288
- `T`
4289
-
4290
- ##### Returns
4291
-
4292
- `ValueRef`\<`T` *extends* `number` ? `number` : `T` *extends* `string` ? `string` : `T` *extends* `boolean` ? `boolean` : `T`\>
4293
-
4294
- ***
4295
-
4296
- ### ref()
1157
+ ##### ref()
4297
1158
 
4298
- > **ref**\<`T`, `K`\>(`target`, `index`): `ValueRef`\<`T`\[`K`\]\>
1159
+ > **ref**\<`T`, `K`\>(`target`, `index`): [`ValueRef`](#valueref)\<`T`\[`K`\]\>
4299
1160
 
4300
- Defined in: [aberdeen.ts:2143](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L2143)
1161
+ Defined in: [aberdeen.ts:859](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L859)
4301
1162
 
4302
1163
  Creates a reactive reference (`{ value: T }`-like object) to a specific value
4303
1164
  within a proxied object or array.
4304
1165
 
4305
- This is primarily used for the `bind` property in [A](#a) to create two-way data bindings
4306
- with form elements, and for passing a reactive property to any of the [A](#a) key-value pairs.
1166
+ This is primarily used for the `bind` property in [A](#aberdeen) to create two-way data bindings
1167
+ with form elements, and for passing a reactive property to any of the [A](#aberdeen) key-value pairs.
4307
1168
 
4308
1169
  Reading `ref.value` accesses the property from the underlying proxy (and subscribes the current scope).
4309
1170
  Assigning to `ref.value` updates the property in the underlying proxy (triggering reactive updates).
4310
1171
 
4311
- #### Type Parameters
1172
+ ###### Type Parameters
4312
1173
 
4313
- ##### T
1174
+ ###### T
4314
1175
 
4315
- `T` *extends* `TargetType`
1176
+ `T` *extends* [`TargetType`](#targettype)
4316
1177
 
4317
- ##### K
1178
+ ###### K
4318
1179
 
4319
1180
  `K` *extends* `string` \| `number` \| `symbol`
4320
1181
 
4321
- #### Parameters
1182
+ ###### Parameters
4322
1183
 
4323
- ##### target
1184
+ ###### target
4324
1185
 
4325
1186
  `T`
4326
1187
 
4327
- The reactive proxy (created by [proxy](#proxy)) containing the target property.
1188
+ The reactive proxy (created by [Aberdeen.proxy](#proxy)) containing the target property.
4328
1189
 
4329
- ##### index
1190
+ ###### index
4330
1191
 
4331
1192
  `K`
4332
1193
 
4333
1194
  The key (for objects) or index (for arrays) of the property to reference.
4334
1195
 
4335
- #### Returns
1196
+ ###### Returns
4336
1197
 
4337
- `ValueRef`\<`T`\[`K`\]\>
1198
+ [`ValueRef`](#valueref)\<`T`\[`K`\]\>
4338
1199
 
4339
1200
  A reference object with a `value` property linked to the specified proxy property.
4340
1201
 
4341
- #### Example
1202
+ ###### Example
4342
1203
 
4343
1204
  ```javascript
4344
1205
  const $formData = A.proxy({ color: 'orange', velocity: 42 });
@@ -4353,13 +1214,11 @@ A('p text="Selected color: " text=', A.ref($formData, 'color'), 'color:', A.ref(
4353
1214
  A(() => console.log($formData))
4354
1215
  ```
4355
1216
 
4356
- ***
4357
-
4358
- ### runQueue()
1217
+ ##### runQueue()
4359
1218
 
4360
1219
  > **runQueue**(): `void`
4361
1220
 
4362
- Defined in: [aberdeen.ts:107](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L107)
1221
+ Defined in: [aberdeen.ts:895](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L895)
4363
1222
 
4364
1223
  Forces the immediate and synchronous execution of all pending reactive updates.
4365
1224
 
@@ -4374,11 +1233,11 @@ This function is re-entrant, meaning it is safe to call `runQueue` from within
4374
1233
  a function that is itself being executed as part of an update cycle triggered
4375
1234
  by a previous (or the same) `runQueue` call.
4376
1235
 
4377
- #### Returns
1236
+ ###### Returns
4378
1237
 
4379
1238
  `void`
4380
1239
 
4381
- #### Example
1240
+ ###### Example
4382
1241
 
4383
1242
  ```typescript
4384
1243
  const $data = A.proxy("before");
@@ -4396,17 +1255,15 @@ A.runQueue();
4396
1255
  console.log(2, document.body.innerHTML); // after
4397
1256
  ```
4398
1257
 
4399
- ***
4400
-
4401
- ### setErrorHandler()
1258
+ ##### setErrorHandler()
4402
1259
 
4403
1260
  > **setErrorHandler**(`handler?`): `void`
4404
1261
 
4405
- Defined in: [aberdeen.ts:2891](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L2891)
1262
+ Defined in: [aberdeen.ts:939](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L939)
4406
1263
 
4407
1264
  Sets a custom error handler function for errors that occur asynchronously
4408
1265
  within reactive scopes (e.g., during updates triggered by proxy changes in
4409
- [derive](#derive) or [A](#a) render functions).
1266
+ [Aberdeen.derive](#derive) or [A](#aberdeen) render functions).
4410
1267
 
4411
1268
  The default handler logs the error to `console.error` and adds a simple
4412
1269
  'Error' message div to the DOM at the location where the error occurred (if possible).
@@ -4414,9 +1271,9 @@ The default handler logs the error to `console.error` and adds a simple
4414
1271
  Your handler can provide custom logging, UI feedback, or suppress the default
4415
1272
  error message.
4416
1273
 
4417
- #### Parameters
1274
+ ###### Parameters
4418
1275
 
4419
- ##### handler?
1276
+ ###### handler?
4420
1277
 
4421
1278
  (`error`) => `undefined` \| `boolean`
4422
1279
 
@@ -4424,11 +1281,11 @@ A function that accepts the `Error` object.
4424
1281
  - Return `false` to prevent adding an error message to the DOM.
4425
1282
  - Return `true` or `undefined` (or throw) to allow the error messages to be added to the DOM.
4426
1283
 
4427
- #### Returns
1284
+ ###### Returns
4428
1285
 
4429
1286
  `void`
4430
1287
 
4431
- #### Example
1288
+ ###### Example
4432
1289
 
4433
1290
  ```typescript
4434
1291
  A.setErrorHandler(error => {
@@ -4456,37 +1313,35 @@ A('div.box', () => {
4456
1313
  })
4457
1314
  ```
4458
1315
 
4459
- ***
4460
-
4461
- ### setSpacingCssVars()
1316
+ ##### setSpacingCssVars()
4462
1317
 
4463
- > **setSpacingCssVars**(`base`, `unit`): `void`
1318
+ > **setSpacingCssVars**(`base?`, `unit?`): `void`
4464
1319
 
4465
- Defined in: [aberdeen.ts:1987](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1987)
1320
+ Defined in: [aberdeen.ts:969](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L969)
4466
1321
 
4467
1322
  Initializes `cssVars[0]` through `cssVars[12]` with an exponential spacing scale.
4468
1323
 
4469
1324
  The scale is calculated as `2^(n-3) * base`, providing values from `0.25 * base` to `512 * base`.
4470
1325
 
4471
- #### Parameters
1326
+ ###### Parameters
4472
1327
 
4473
- ##### base
1328
+ ###### base?
4474
1329
 
4475
- `number` = `1`
1330
+ `number`
4476
1331
 
4477
1332
  The base size for the spacing scale that will apply to `cssVars[3]`. Every step up the scale will double this, while every step down will halve it. Defaults to 1.
4478
1333
 
4479
- ##### unit
1334
+ ###### unit?
4480
1335
 
4481
- `string` = `'rem'`
1336
+ `string`
4482
1337
 
4483
1338
  The CSS unit to use, like 'rem', 'em', or 'px'. Defaults to 'rem'.
4484
1339
 
4485
- #### Returns
1340
+ ###### Returns
4486
1341
 
4487
1342
  `void`
4488
1343
 
4489
- #### Example
1344
+ ###### Example
4490
1345
 
4491
1346
  ```javascript
4492
1347
  import A from 'aberdeen';
@@ -4505,61 +1360,57 @@ A.onEach(A.cssVars, (value, key) => {
4505
1360
  }, (value, key) => parseInt(key)); // Numeric sort
4506
1361
  ```
4507
1362
 
4508
- ***
4509
-
4510
- ### unmountAll()
1363
+ ##### unmountAll()
4511
1364
 
4512
1365
  > **unmountAll**(): `void`
4513
1366
 
4514
- Defined in: [aberdeen.ts:3045](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L3045)
1367
+ Defined in: [aberdeen.ts:978](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L978)
4515
1368
 
4516
1369
  Removes all Aberdeen-managed DOM nodes and stops all active reactive scopes
4517
- (created by [mount](#mount), [derive](#derive), [A](#a) with functions, etc.).
1370
+ (created by [Aberdeen.mount](#mount), [Aberdeen.derive](#derive), [A](#aberdeen) with functions, etc.).
4518
1371
 
4519
1372
  This effectively cleans up the entire Aberdeen application state. Aside from in
4520
1373
  automated tests, there should probably be little reason to call this function.
4521
1374
 
4522
- #### Returns
1375
+ ###### Returns
4523
1376
 
4524
1377
  `void`
4525
1378
 
4526
- ***
4527
-
4528
- ### unproxy()
1379
+ ##### unproxy()
4529
1380
 
4530
1381
  > **unproxy**\<`T`\>(`target`): `T`
4531
1382
 
4532
- Defined in: [aberdeen.ts:1667](https://github.com/vanviegen/aberdeen/blob/7f828964cffa6e7ff5c5fd7eeb6e63503dcab127/src/aberdeen.ts#L1667)
1383
+ Defined in: [aberdeen.ts:1014](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L1014)
4533
1384
 
4534
- Returns the original, underlying data target from a reactive proxy created by [proxy](#proxy).
1385
+ Returns the original, underlying data target from a reactive proxy created by [Aberdeen.proxy](#proxy).
4535
1386
  If the input `target` is not a proxy, it is returned directly.
4536
1387
 
4537
1388
  This is useful when you want to avoid triggering subscriptions during read operations or
4538
- re-executes during write operations. Using [peek](#peek) is an alternative way to achieve this.
1389
+ re-executes during write operations. Using [Aberdeen.peek](#peek) is an alternative way to achieve this.
4539
1390
 
4540
- #### Type Parameters
1391
+ ###### Type Parameters
4541
1392
 
4542
- ##### T
1393
+ ###### T
4543
1394
 
4544
1395
  `T`
4545
1396
 
4546
1397
  The type of the target.
4547
1398
 
4548
- #### Parameters
1399
+ ###### Parameters
4549
1400
 
4550
- ##### target
1401
+ ###### target
4551
1402
 
4552
1403
  `T`
4553
1404
 
4554
1405
  A proxied object, array, or any other value.
4555
1406
 
4556
- #### Returns
1407
+ ###### Returns
4557
1408
 
4558
1409
  `T`
4559
1410
 
4560
1411
  The underlying (unproxied) data, or the input value if it wasn't a proxy.
4561
1412
 
4562
- #### Example
1413
+ ###### Example
4563
1414
 
4564
1415
  ```typescript
4565
1416
  const $user = A.proxy({ name: 'Frank' });
@@ -4582,3 +1433,175 @@ setTimeout(() => {
4582
1433
  console.log('final unproxied', rawUser)
4583
1434
  }, 3000);
4584
1435
  ```
1436
+
1437
+ ***
1438
+
1439
+ ### InitOptions
1440
+
1441
+ Defined in: [aberdeen.ts:22](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L22)
1442
+
1443
+ Options for [createA](#createa).
1444
+
1445
+ #### Properties
1446
+
1447
+ ##### transitions?
1448
+
1449
+ > `optional` **transitions**: `boolean`
1450
+
1451
+ Defined in: [aberdeen.ts:24](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L24)
1452
+
1453
+ Set to `false` to disable `create`/`destroy` transitions for this instance (e.g. for SSR).
1454
+
1455
+ ***
1456
+
1457
+ ### PromiseProxy
1458
+
1459
+ Defined in: [aberdeen.ts:1054](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L1054)
1460
+
1461
+ When `proxy` is called with a Promise, the returned object has this shape.
1462
+
1463
+ #### Type Parameters
1464
+
1465
+ ##### T
1466
+
1467
+ `T`
1468
+
1469
+ #### Properties
1470
+
1471
+ ##### busy
1472
+
1473
+ > **busy**: `boolean`
1474
+
1475
+ Defined in: [aberdeen.ts:1056](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L1056)
1476
+
1477
+ True while the promise is pending, false once it has resolved or rejected.
1478
+
1479
+ ##### error?
1480
+
1481
+ > `optional` **error**: `any`
1482
+
1483
+ Defined in: [aberdeen.ts:1060](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L1060)
1484
+
1485
+ If the promise has rejected, the rejection error.
1486
+
1487
+ ##### value?
1488
+
1489
+ > `optional` **value**: `T`
1490
+
1491
+ Defined in: [aberdeen.ts:1058](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L1058)
1492
+
1493
+ If the promise has resolved, the resolved value.
1494
+
1495
+ ***
1496
+
1497
+ ### ValueRef
1498
+
1499
+ Defined in: [aberdeen.ts:1049](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L1049)
1500
+
1501
+ The shape returned by [Aberdeen.ref](#ref): an object whose single `value` property is reactive.
1502
+
1503
+ #### Type Parameters
1504
+
1505
+ ##### T
1506
+
1507
+ `T`
1508
+
1509
+ ***
1510
+
1511
+ ### WindowLike
1512
+
1513
+ Defined in: [aberdeen.ts:7](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L7)
1514
+
1515
+ The minimal `window`-like object an Aberdeen instance renders against. A real browser
1516
+ `window`, a jsdom window, and the server window from `aberdeen/server` all satisfy this.
1517
+
1518
+ #### Properties
1519
+
1520
+ ##### setTimeout()?
1521
+
1522
+ > `optional` **setTimeout**: (...`args`) => `any`
1523
+
1524
+ Defined in: [aberdeen.ts:17](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L17)
1525
+
1526
+ Optional; falls back to the host's timers when absent (e.g. the lean server window).
1527
+
1528
+ ###### Parameters
1529
+
1530
+ ###### args
1531
+
1532
+ ...`any`[]
1533
+
1534
+ ###### Returns
1535
+
1536
+ `any`
1537
+
1538
+ ## Type Aliases
1539
+
1540
+ ### KeyToString
1541
+
1542
+ > **KeyToString**\<`K`\> = `K` *extends* `number` ? `string` : `K` *extends* `string` \| `symbol` ? `K` : `K` *extends* `number` \| infer U ? `string` \| `U` : `K`
1543
+
1544
+ Defined in: [aberdeen.ts:45](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L45)
1545
+
1546
+ Maps object key types to the string form Aberdeen passes to callbacks.
1547
+
1548
+ #### Type Parameters
1549
+
1550
+ ##### K
1551
+
1552
+ `K`
1553
+
1554
+ ***
1555
+
1556
+ ### SortKeyType
1557
+
1558
+ > **SortKeyType** = `number` \| `string` \| (`number` \| `string`)[] \| `undefined` \| `void`
1559
+
1560
+ Defined in: [aberdeen.ts:43](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L43)
1561
+
1562
+ A sort key returned by `onEach`/`map` ordering callbacks.
1563
+
1564
+ ***
1565
+
1566
+ ### TargetType
1567
+
1568
+ > **TargetType** = `any`[] \| \{\[`key`: `string` \| `symbol`\]: `any`; \} \| `Map`\<`any`, `any`\> \| `Set`\<`any`\>
1569
+
1570
+ Defined in: [aberdeen.ts:41](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L41)
1571
+
1572
+ Any value Aberdeen can proxy: array, plain object, Map or Set.
1573
+
1574
+ ## Functions
1575
+
1576
+ ### createA()
1577
+
1578
+ > **createA**(`window?`, `options?`): [`Aberdeen`](#aberdeen)
1579
+
1580
+ Defined in: [aberdeen.ts:1076](https://github.com/vanviegen/aberdeen/blob/bb39ef2418f1368ed94a83b45dc3201369d991ca/src/aberdeen.ts#L1076)
1581
+
1582
+ Create an isolated Aberdeen instance bound to the given window. Returns the callable `A`
1583
+ object (with all Aberdeen functions attached as properties).
1584
+
1585
+ In the browser you normally import the pre-initialised default instance
1586
+ (`import A from 'aberdeen'`). Call `init` yourself to render against a non-browser DOM
1587
+ (see `aberdeen/server`) or to create multiple isolated instances. All reactive state lives
1588
+ in the returned instance, so separate instances never interfere.
1589
+
1590
+ #### Parameters
1591
+
1592
+ ##### window?
1593
+
1594
+ [`WindowLike`](#windowlike)
1595
+
1596
+ The window to render against. May be omitted for the browser default when
1597
+ no `window` global exists yet; rendering then throws until a real window is available.
1598
+
1599
+ ##### options?
1600
+
1601
+ [`InitOptions`](#initoptions) = `{}`
1602
+
1603
+ See [InitOptions](#initoptions).
1604
+
1605
+ #### Returns
1606
+
1607
+ [`Aberdeen`](#aberdeen)