aberdeen 1.18.1 → 1.19.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 (156) hide show
  1. package/README.md +9 -0
  2. package/dist/src/aberdeen.d.ts +29 -0
  3. package/{dist-docs/assets/aberdeen/aberdeen.js → dist/src/aberdeen.dev.js} +796 -21
  4. package/dist/src/aberdeen.dev.js.map +12 -0
  5. package/dist/src/aberdeen.js +79 -19
  6. package/dist/src/aberdeen.js.map +3 -3
  7. package/dist/src/devtools.d.ts +26 -0
  8. package/dist/tests/fakedom.js +20 -3
  9. package/dist/tests/fakedom.js.map +3 -3
  10. package/dist/tests/helpers.js +20 -3
  11. package/dist/tests/helpers.js.map +3 -3
  12. package/html-to-aberdeen +9 -5
  13. package/package.json +17 -10
  14. package/skill/A.md +127 -0
  15. package/skill/Dispatcher.md +51 -0
  16. package/skill/OPAQUE.md +15 -0
  17. package/skill/PromiseProxy.md +25 -0
  18. package/skill/Route.md +50 -0
  19. package/skill/SKILL.md +272 -156
  20. package/skill/applyCanon.md +20 -0
  21. package/skill/applyPrediction.md +15 -0
  22. package/skill/back.md +11 -0
  23. package/skill/clean.md +43 -0
  24. package/skill/clone.md +15 -0
  25. package/skill/copy.md +40 -0
  26. package/skill/count.md +32 -0
  27. package/skill/cssVars.md +15 -0
  28. package/skill/darkMode.md +26 -0
  29. package/skill/derive.md +56 -0
  30. package/skill/developer-tools.md +23 -0
  31. package/skill/disableCreateDestroy.md +11 -0
  32. package/skill/dump.md +37 -0
  33. package/skill/freeze.md +20 -0
  34. package/skill/full-example-multi-page-app.md +146 -0
  35. package/skill/go.md +25 -0
  36. package/skill/grow.md +13 -0
  37. package/skill/html-to-aberdeen.md +9 -0
  38. package/skill/insertCss.md +79 -0
  39. package/skill/insertGlobalCss.md +68 -0
  40. package/skill/interceptLinks.md +19 -0
  41. package/skill/invertString.md +32 -0
  42. package/skill/isEmpty.md +38 -0
  43. package/skill/map.md +16 -0
  44. package/skill/matchCurrent.md +27 -0
  45. package/skill/merge.md +27 -0
  46. package/skill/mount.md +48 -0
  47. package/skill/multiMap.md +15 -0
  48. package/skill/onEach.md +14 -0
  49. package/skill/partition.md +15 -0
  50. package/skill/peek.md +36 -0
  51. package/skill/persistScroll.md +13 -0
  52. package/skill/proxy.md +11 -0
  53. package/skill/push.md +13 -0
  54. package/skill/ref.md +39 -0
  55. package/skill/runQueue.md +34 -0
  56. package/skill/setErrorHandler.md +48 -0
  57. package/skill/setLog.md +9 -0
  58. package/skill/setSpacingCssVars.md +31 -0
  59. package/skill/shrink.md +13 -0
  60. package/skill/unmountAll.md +9 -0
  61. package/skill/unproxy.md +43 -0
  62. package/skill/up.md +13 -0
  63. package/src/aberdeen.ts +220 -82
  64. package/src/devtools.ts +685 -0
  65. package/dist-docs/.nojekyll +0 -1
  66. package/dist-docs/Tutorial/index.html +0 -305
  67. package/dist-docs/aberdeen/A/index.html +0 -115
  68. package/dist-docs/aberdeen/CUSTOM_DUMP/index.html +0 -7
  69. package/dist-docs/aberdeen/NO_COPY/index.html +0 -2
  70. package/dist-docs/aberdeen/OPAQUE/index.html +0 -12
  71. package/dist-docs/aberdeen/PromiseProxy/index.html +0 -8
  72. package/dist-docs/aberdeen/clean/index.html +0 -11
  73. package/dist-docs/aberdeen/clone/index.html +0 -5
  74. package/dist-docs/aberdeen/copy/index.html +0 -22
  75. package/dist-docs/aberdeen/count/index.html +0 -7
  76. package/dist-docs/aberdeen/cssVars/index.html +0 -11
  77. package/dist-docs/aberdeen/darkMode/index.html +0 -9
  78. package/dist-docs/aberdeen/default/index.html +0 -341
  79. package/dist-docs/aberdeen/derive/index.html +0 -18
  80. package/dist-docs/aberdeen/disableCreateDestroy/index.html +0 -6
  81. package/dist-docs/aberdeen/dump/index.html +0 -11
  82. package/dist-docs/aberdeen/index.html +0 -54
  83. package/dist-docs/aberdeen/insertCss/index.html +0 -30
  84. package/dist-docs/aberdeen/insertGlobalCss/index.html +0 -19
  85. package/dist-docs/aberdeen/invertString/index.html +0 -13
  86. package/dist-docs/aberdeen/isEmpty/index.html +0 -12
  87. package/dist-docs/aberdeen/map/index.html +0 -26
  88. package/dist-docs/aberdeen/merge/index.html +0 -11
  89. package/dist-docs/aberdeen/mount/index.html +0 -17
  90. package/dist-docs/aberdeen/multiMap/index.html +0 -28
  91. package/dist-docs/aberdeen/onEach/index.html +0 -19
  92. package/dist-docs/aberdeen/partition/index.html +0 -36
  93. package/dist-docs/aberdeen/peek/index.html +0 -40
  94. package/dist-docs/aberdeen/proxy/index.html +0 -35
  95. package/dist-docs/aberdeen/ref/index.html +0 -13
  96. package/dist-docs/aberdeen/runQueue/index.html +0 -13
  97. package/dist-docs/aberdeen/setErrorHandler/index.html +0 -16
  98. package/dist-docs/aberdeen/setSpacingCssVars/index.html +0 -8
  99. package/dist-docs/aberdeen/unmountAll/index.html +0 -5
  100. package/dist-docs/aberdeen/unproxy/index.html +0 -11
  101. package/dist-docs/assets/aberdeen/aberdeen.d.ts +0 -961
  102. package/dist-docs/assets/aberdeen/aberdeen.js.map +0 -11
  103. package/dist-docs/assets/aberdeen/dispatcher.d.ts +0 -57
  104. package/dist-docs/assets/aberdeen/dispatcher.js +0 -66
  105. package/dist-docs/assets/aberdeen/dispatcher.js.map +0 -10
  106. package/dist-docs/assets/aberdeen/helpers/reverseSortedSet.d.ts +0 -96
  107. package/dist-docs/assets/aberdeen/prediction.d.ts +0 -33
  108. package/dist-docs/assets/aberdeen/prediction.js +0 -112
  109. package/dist-docs/assets/aberdeen/prediction.js.map +0 -10
  110. package/dist-docs/assets/aberdeen/route.d.ts +0 -137
  111. package/dist-docs/assets/aberdeen/route.js +0 -287
  112. package/dist-docs/assets/aberdeen/route.js.map +0 -10
  113. package/dist-docs/assets/aberdeen/transitions.d.ts +0 -18
  114. package/dist-docs/assets/aberdeen/transitions.js +0 -47
  115. package/dist-docs/assets/aberdeen/transitions.js.map +0 -10
  116. package/dist-docs/assets/custom.js +0 -573
  117. package/dist-docs/assets/favicon.png +0 -0
  118. package/dist-docs/assets/hierarchy.js +0 -1
  119. package/dist-docs/assets/highlight.css +0 -134
  120. package/dist-docs/assets/icons.js +0 -18
  121. package/dist-docs/assets/icons.svg +0 -1
  122. package/dist-docs/assets/main.js +0 -60
  123. package/dist-docs/assets/navigation.js +0 -1
  124. package/dist-docs/assets/search.js +0 -1
  125. package/dist-docs/assets/style.css +0 -1640
  126. package/dist-docs/dispatcher/Dispatcher/index.html +0 -21
  127. package/dist-docs/dispatcher/MATCH_FAILED/index.html +0 -2
  128. package/dist-docs/dispatcher/MATCH_REST/index.html +0 -2
  129. package/dist-docs/dispatcher/index.html +0 -4
  130. package/dist-docs/hierarchy.html +0 -1
  131. package/dist-docs/index.html +0 -61
  132. package/dist-docs/media/CHANGELOG.md +0 -260
  133. package/dist-docs/modules.html +0 -1
  134. package/dist-docs/prediction/applyCanon/index.html +0 -13
  135. package/dist-docs/prediction/applyPrediction/index.html +0 -8
  136. package/dist-docs/prediction/index.html +0 -9
  137. package/dist-docs/route/Route/index.html +0 -23
  138. package/dist-docs/route/back/index.html +0 -4
  139. package/dist-docs/route/current/index.html +0 -2
  140. package/dist-docs/route/go/index.html +0 -14
  141. package/dist-docs/route/index.html +0 -15
  142. package/dist-docs/route/interceptLinks/index.html +0 -8
  143. package/dist-docs/route/matchCurrent/index.html +0 -10
  144. package/dist-docs/route/persistScroll/index.html +0 -6
  145. package/dist-docs/route/push/index.html +0 -6
  146. package/dist-docs/route/setLog/index.html +0 -3
  147. package/dist-docs/route/up/index.html +0 -5
  148. package/dist-docs/sitemap.xml +0 -239
  149. package/dist-docs/transitions/grow/index.html +0 -6
  150. package/dist-docs/transitions/index.html +0 -5
  151. package/dist-docs/transitions/shrink/index.html +0 -6
  152. package/skill/aberdeen.md +0 -4584
  153. package/skill/dispatcher.md +0 -129
  154. package/skill/prediction.md +0 -73
  155. package/skill/route.md +0 -322
  156. package/skill/transitions.md +0 -59
package/skill/SKILL.md CHANGED
@@ -17,16 +17,6 @@ Aberdeen is a reactive UI library using fine-grained reactivity via JavaScript P
17
17
  8. **Prefix proxied objects** - As a convention, prefix variable names that contain proxied objects with '$' (e.g. `$user`, `$settings`)
18
18
  9. **Think about rerenders** - When you read from a proxied object (like `let n = $user.name;`), the containing A(() => {..}) or A('div', () => {}) function will rerun on change - plan on which level you want updates to trigger
19
19
 
20
- # Obtaining info
21
-
22
- The complete tutorial follows below. For detailed API reference open these files within the skill directory:
23
-
24
- - **[aberdeen](aberdeen.md)** - Core: `A`, `proxy`, `onEach`, `ref`, `derive`, `map`, `multiMap`, `partition`, `count`, `isEmpty`, `peek`, `dump`, `clean`, `insertCss`, `insertGlobalCss`, `mount`, `runQueue`, `darkMode`
25
- - **[route](route.md)** - Routing: `current`, `go`, `push`, `back`, `up`, `persistScroll`
26
- - **[dispatcher](dispatcher.md)** - Path matching: `Dispatcher`, `MATCH_REST`, `MATCH_FAILED`
27
- - **[transitions](transitions.md)** - Animations: `grow`, `shrink`
28
- - **[prediction](prediction.md)** - Optimistic UI: `applyPrediction`, `applyCanon`
29
-
30
20
 
31
21
  # Tutorial
32
22
 
@@ -280,7 +270,6 @@ A('div.box color:', $textColor, '#Click me to change color', 'click=', () => {
280
270
 
281
271
  This way, when `$textColor.value` changes, only the style is updated without recreating the element.
282
272
 
283
-
284
273
  ## Observable arrays and sets
285
274
 
286
275
  You can create observable arrays too. They work just like regular arrays, apart from being observable.
@@ -343,7 +332,6 @@ A('button text=Grow click=', () => $graph.grow());
343
332
 
344
333
  The type returned by {@link aberdeen.proxy | A.proxy} matches the input type, meaning the type system does not distinguish proxied and unproxied objects. That makes sense, as they have the exact same methods and properties (though proxied objects may have additional side effects).
345
334
 
346
-
347
335
  ## Efficient list rendering with A.onEach
348
336
  For rendering lists efficiently, Aberdeen provides the {@link aberdeen.onEach | A.onEach} function. It takes three arguments:
349
337
  1. The array to iterate over.
@@ -687,18 +675,13 @@ A('button text="Update state" click=', () => {
687
675
 
688
676
  The A.dump renders recursively using `<ul>` and `<li>` elements, showing all properties and their values. It updates reactively when any proxied data changes. It is intended for debugging, though with some CSS styling you may find it useful in some simple real-world scenarios as well.
689
677
 
678
+ ## Developer tools
690
679
 
691
- ## html-to-aberdeen
692
-
693
- Sometimes, you want to just paste a largish block of HTML into your application (and then maybe modify it to bind some actual data). Having to translate HTML to `$` calls manually is little fun, so there's a tool for that:
680
+ Aberdeen has an in-browser inspector for its reactive scope tree. See [developer-tools.md](developer-tools.md).
694
681
 
695
- ```sh
696
- npx html-to-aberdeen
697
- ```
698
-
699
- It takes HTML on stdin (paste it and press `ctrl-d` for end-of-file), and outputs JavaScript on stdout.
682
+ ## html-to-aberdeen
700
683
 
701
- > Caveat: This tool has been vibe coded (thanks Claude!) with very little code review. As it doesn't use the filesystem nor the network, I'd say it's safe to use though! :-) Also, it happens to work pretty well.
684
+ This tool allows you to convert a block of HTML into Aberdeen syntax. See [html-to-aberdeen.md](html-to-aberdeen.md).
702
685
 
703
686
  ## Routing
704
687
 
@@ -775,154 +758,287 @@ When building interactive applications with client-server communication, Aberdee
775
758
 
776
759
  ## Full Example: Multi-page App
777
760
 
778
- Here's a complete example (a contact manager) demonstrating routing, state management, CSS, dark mode, and dynamic content:
761
+ Here's a complete example (a contact manager) demonstrating routing, state management, CSS, dark mode, and dynamic content. See [full-example-multi-page-app.md](full-example-multi-page-app.md).
779
762
 
780
- ```typescript
781
- import A from 'aberdeen';
782
- import * as route from 'aberdeen/route';
783
- import { Dispatcher } from 'aberdeen/dispatcher';
784
- import { grow, shrink } from 'aberdeen/transitions';
763
+ ## Further reading
785
764
 
786
- class Contact {
787
- constructor(
788
- public id: number,
789
- public firstName: string,
790
- public lastName: string,
791
- public email: string,
792
- public phone: string
793
- ) {}
794
- }
765
+ If you've understood all/most of the above, you should be ready to get going with Aberdeen! You may also find these links helpful:
795
766
 
796
- // Enable link interception for SPA navigation
797
- route.interceptLinks();
767
+ - [Reference documentation](https://aberdeenjs.org/modules.html)
768
+ - [Examples](https://aberdeenjs.org/#examples)
798
769
 
799
- // Initialize $1-$12 CSS variables for consistent spacing ($2=0.5rem, $3=1rem, $4=2rem, etc.)
800
- A.setSpacingCssVars();
770
+ # API Reference
801
771
 
802
- // Reactive theme based on system preference
803
- A(() => {
804
- A.cssVars.primary = '#2563eb';
805
- A.cssVars.bg = A.darkMode() ? '#0f172a' : '#ffffff';
806
- A.cssVars.fg = A.darkMode() ? '#e2e8f0' : '#1e293b';
807
- A.cssVars.cardBg = A.darkMode() ? '#1e293b' : '#f8fafc';
808
- A.cssVars.border = A.darkMode() ? '#334155' : '#e2e8f0';
809
- });
772
+ The sections below summarize each module's exports; the linked `.md` files within this skill directory contain detailed reference docs for individual symbols.
810
773
 
811
- // Global styles for semantic HTML elements that apply everywhere
812
- A.insertGlobalCss({
813
- "*": "m:0 p:0",
814
- "body": "bg:$bg fg:$fg font-family: system-ui, sans-serif;",
815
- "a": "color:$primary text-decoration:none",
816
- "a:hover": "text-decoration:underline",
817
- "a[role=button]": "bg:$primary fg:white r:8px p:$2",
818
- });
774
+ ## Core (aberdeen)
819
775
 
820
- // Application state
821
- const $contacts = A.proxy([
822
- new Contact(1, 'Emma', 'Wilson', 'emma.wilson@email.com', '555-0101'),
823
- new Contact(2, 'James', 'Anderson', 'j.anderson@email.com', '555-0102'),
824
- new Contact(3, 'Sofia', 'Martinez', 'sofia.m@email.com', '555-0103'),
825
- new Contact(4, 'Liam', 'Brown', 'liam.brown@email.com', '555-0104')
826
- ]);
827
-
828
- // Router setup
829
- const dispatcher = new Dispatcher();
830
- dispatcher.addRoute(drawHome);
831
- dispatcher.addRoute('contacts', drawContactList);
832
- dispatcher.addRoute('contacts', Number, drawContactDetail);
833
-
834
- // Main app
835
- A('div.app', () => {
836
- A('nav display:flex gap:$3 p:$3 border-bottom: 1px solid $border;', () => {
837
- A('a href=/ text=Home font-weight:', route.current.p.length === 0 ? 'bold' : 'normal');
838
- A('a href=/contacts text=Contacts font-weight:', route.current.p[0] === 'contacts' ? 'bold' : 'normal');
839
- });
840
- A('main p:$3', () => dispatcher.dispatch(route.current.p));
841
- });
776
+ Import as `import A from 'aberdeen'`. `A` is itself a callable function for building reactive DOM (creating elements, setting attributes, adding content); every other Aberdeen function is also available as a property on it (e.g. `A.proxy`, `A.onEach`).
842
777
 
843
- function drawHome() {
844
- A('h1#Contact Manager');
845
- A('p#A modern contact list with search, sort, and dark mode support.');
846
- }
778
+ ## [runQueue](runQueue.md) · function
847
779
 
848
- // Contact card styles
849
- const cardStyle = A.insertCss({
850
- "&": "bg:$cardBg border: 1px solid $border; r:8px p:$3 mv:$2 display:block transition: transform 0.2s;",
851
- "&:hover": "transform:translateX(4px)",
852
- "a&": "color:inherit;",
853
- });
780
+ Forces the immediate and synchronous execution of all pending reactive updates.
854
781
 
855
- const filterStyle = A.insertCss({
856
- "&": "display:flex gap:$3 mv:$3",
857
- "> *": "p:$2 r:4px bg:$bg fg:$fg border: 1px solid $border;",
858
- });
782
+ ## [freeze](freeze.md) · function
859
783
 
860
- function drawContactList() {
861
- A('h1#Contacts');
862
-
863
- // Search and sort controls
864
- A('div', filterStyle, () => {
865
- A('input flex:1 placeholder="Search contacts..." bind=', A.ref(route.current.search, 'q'));
866
- A('select bind=', A.ref(route.current.search, 'sort'), () => {
867
- A('option value=firstName #First Name');
868
- A('option value=lastName #Last Name');
869
- A('option value=email #Email');
870
- });
871
- });
872
-
873
- // Contact list
874
- A('div', () => {
875
- const sortBy = route.current.search.sort || 'firstName';
876
-
877
- const $filtered = A.map($contacts, $contact => {
878
- const query = route.current.search.q;
879
- if (query) {
880
- const info = `${$contact.firstName} ${$contact.lastName} ${$contact.email}`;
881
- if (!info.toLowerCase().includes(query.toLowerCase())) return; // Skip!
882
- }
883
- return $contact;
884
- });
885
-
886
- A.onEach($filtered, $contact => {
887
- A('a', cardStyle, 'create=', grow, 'destroy=', shrink, `href=/contacts/${$contact.id}`, () => {
888
- A('h2', () => {
889
- A('span font-weight:normal text=', $contact.firstName+" ");
890
- A('span text=', $contact.lastName);
891
- });
892
- A('div text=', $contact.email);
893
- });
894
- }, $contact => $contact[sortBy].toLowerCase());
895
-
896
- A(`a role=button mt:$3 text="Add new contact" href=/contacts/${$contacts.length}`);
897
- });
898
- }
784
+ Pause processing of reactive updates until the returned *thaw* function is called.
899
785
 
900
- // Detail form styles
901
- const detailStyle = A.insertCss({
902
- "&": "bg:$cardBg border: 1px solid $border; r:8px p:$4 max-width:600px",
903
- "label": "display:block font-weight:600 mt:$3 mb:$2",
904
- "input": "w:100% p:$2 r:4px border: 1px solid $border; bg:$bg fg:$fg"
905
- });
786
+ ## [invertString](invertString.md) · function
906
787
 
907
- function drawContactDetail(id: number) {
908
- $contacts[id] ||= new Contact(id, '', '', '', '');
909
- const $contact = $contacts[id];
910
-
911
- A('a role=button href=/contacts #← Back');
912
-
913
- A('div mt:$3', detailStyle, () => {
914
- A('h2 mb:$2 text=', A.ref($contact, 'firstName'), 'text=', ' ', 'text=', A.ref($contact, 'lastName'));
915
- A('label text="First Name" input bind=', A.ref($contact, 'firstName'));
916
- A('label text="Last Name" input bind=', A.ref($contact, 'lastName'));
917
- A('label text="Email" input type=email bind=', A.ref($contact, 'email'));
918
- A('label text="Phone" input type=tel bind=', A.ref($contact, 'phone'));
919
- });
920
- }
921
- ```
788
+ Creates a new string that has the opposite sort order compared to the input string.
922
789
 
923
- ## Further reading
790
+ ## [onEach](onEach.md) · function
924
791
 
925
- If you've understood all/most of the above, you should be ready to get going with Aberdeen! You may also find these links helpful:
792
+ ## [isEmpty](isEmpty.md) · function
793
+
794
+ Reactively checks if an observable array, object, Map, or Set is empty.
795
+
796
+ ## [count](count.md) · function
797
+
798
+ Reactively counts the number of properties in an object.
799
+
800
+ ## [proxy](proxy.md) · function
801
+
802
+ ## [unproxy](unproxy.md) · function
803
+
804
+ Returns the original, underlying data target from a reactive proxy created by `proxy`.
805
+ If the input `target` is not a proxy, it is returned directly.
806
+
807
+ ## [copy](copy.md) · function
808
+
809
+ Recursively copies properties or array items from `src` to `dst`.
810
+ It's designed to work efficiently with reactive proxies created by `proxy`.
811
+
812
+ ## [merge](merge.md) · function
813
+
814
+ Like `copy`, but uses merge semantics. Properties in `dst` not present in `src` are kept.
815
+ `null`/`undefined` in `src` delete properties in `dst`.
816
+
817
+ ## [setSpacingCssVars](setSpacingCssVars.md) · function
818
+
819
+ Initializes `cssVars[0]` through `cssVars[12]` with an exponential spacing scale.
820
+
821
+ ## [darkMode](darkMode.md) · function
822
+
823
+ Returns whether the user's browser prefers a dark color scheme.
824
+
825
+ ## [clone](clone.md) · function
826
+
827
+ Clone an (optionally proxied) object or array.
828
+
829
+ ## [ref](ref.md) · function
830
+
831
+ Creates a reactive reference (`{ value: T }`-like object) to a specific value
832
+ within a proxied object or array.
833
+
834
+ ## [disableCreateDestroy](disableCreateDestroy.md) · function
835
+
836
+ Make the `create` and `destroy` special properties no-ops.
837
+
838
+ ## [A](A.md) · function
839
+
840
+ The core function for building reactive user interfaces in Aberdeen. It creates and inserts new DOM elements
841
+ and sets attributes/properties/event listeners on DOM elements. It does so in a reactive way, meaning that
842
+ changes will be (mostly) undone when the current *scope* is destroyed or will be re-execute.
843
+
844
+ ## [insertCss](insertCss.md) · function
845
+
846
+ Inserts CSS rules into the document, scoping them with a unique class name.
847
+
848
+ ## [insertGlobalCss](insertGlobalCss.md) · function
849
+
850
+ Inserts CSS rules globally (unscoped).
851
+
852
+ ## [setErrorHandler](setErrorHandler.md) · function
853
+
854
+ Sets a custom error handler function for errors that occur asynchronously
855
+ within reactive scopes (e.g., during updates triggered by proxy changes in
856
+ `derive` or | A render functions).
857
+
858
+ ## [clean](clean.md) · function
859
+
860
+ Registers a cleanup function to be executed just before the current reactive scope
861
+ is destroyed or redraws.
862
+
863
+ ## [derive](derive.md) · function
864
+
865
+ Creates a reactive scope that automatically re-executes the provided function
866
+ whenever any proxied data (created by `proxy`) read during its last execution changes, storing
867
+ its return value in an observable.
868
+
869
+ ## [mount](mount.md) · function
870
+
871
+ Attaches a reactive Aberdeen UI fragment to an existing DOM element. Without the use of
872
+ this function, | A will assume `document.body` as its root.
873
+
874
+ ## [unmountAll](unmountAll.md) · function
875
+
876
+ Removes all Aberdeen-managed DOM nodes and stops all active reactive scopes
877
+ (created by `mount`, `derive`, | A with functions, etc.).
878
+
879
+ ## [peek](peek.md) · function
880
+
881
+ Executes a function or retrieves a value *without* creating subscriptions in the current reactive scope, and returns its result.
882
+
883
+ ## [map](map.md) · function
884
+
885
+ When using a Map as `source`.
886
+
887
+ ## [multiMap](multiMap.md) · function
888
+
889
+ When using an array as `source`.
890
+
891
+ ## [partition](partition.md) · function
892
+
893
+ When using an object as `array`.
894
+
895
+ ## [dump](dump.md) · function
896
+
897
+ Renders a live, recursive dump of a proxied data structure (or any value)
898
+ into the DOM at the current | A insertion point.
899
+
900
+ ## EMPTY · constant
901
+
902
+ **Value:** `unique symbol`
903
+
904
+ ## ValueRef · interface
905
+
906
+ **Type Parameters:**
907
+
908
+ - `T`
909
+
910
+ ### valueRef.value · member
911
+
912
+ **Type:** `T`
913
+
914
+ ## [PromiseProxy](PromiseProxy.md) · interface
915
+
916
+ When `proxy` is called with a Promise, the returned object has this shape.
917
+
918
+ ## [OPAQUE](OPAQUE.md) · constant
919
+
920
+ A symbol that controls how Aberdeen handles an object in copy operations and proxy wrapping.
921
+
922
+ ## NO_COPY · constant
923
+
924
+ Use `OPAQUE` instead. This is an alias kept for backward compatibility.
925
+
926
+ **Value:** `symbol`
927
+
928
+ ## [cssVars](cssVars.md) · constant
929
+
930
+ A reactive object containing CSS variable definitions.
931
+
932
+ ## CUSTOM_DUMP · constant
933
+
934
+ When set on an object or its prototype chain, `dump` calls this as a render function
935
+ (with the object as `this`) instead of its default recursive rendering. If the value is not
936
+ a function, it's treated as a string to display.
937
+
938
+ **Value:** `unique symbol`
939
+
940
+
941
+ ## Routing (aberdeen/route)
942
+
943
+ ## [setLog](setLog.md) · function
944
+
945
+ Configure logging on route changes.
946
+
947
+ ## [go](go.md) · function
948
+
949
+ Navigate to a new URL by pushing a new history entry.
950
+
951
+ ## [matchCurrent](matchCurrent.md) · function
952
+
953
+ Returns `true` if the current route matches `target`.
954
+
955
+ ## [push](push.md) · function
956
+
957
+ Modify the current route by merging `target` into it (using | A.merge), pushing a new history entry.
958
+
959
+ ## [back](back.md) · function
960
+
961
+ Try to go back in history to the first entry that matches the given target. If none is found, the given state will replace the current page. This is useful for "cancel" or "close" actions that should return to the previous page if possible, but create a new page if not (for instance when arriving at the current page through a direct link).
962
+
963
+ ## [up](up.md) · function
964
+
965
+ Navigate up in the path hierarchy, by going back to the first history entry
966
+ that has a shorter path than the current one. If there's none, we just shorten
967
+ the current path.
968
+
969
+ ## [persistScroll](persistScroll.md) · function
970
+
971
+ Restore and store the vertical and horizontal scroll position for
972
+ the parent element to the page state.
973
+
974
+ ## [interceptLinks](interceptLinks.md) · function
975
+
976
+ Intercept clicks and Enter key presses on links (`<a>` tags) and use Aberdeen routing
977
+ instead of browser navigation for local paths (paths without a protocol or host).
978
+
979
+ ## [Route](Route.md) · interface
980
+
981
+ The class for the global `route` object.
982
+
983
+ ## current · constant
984
+
985
+ The global `Route` object reflecting the current URL and browser history state. Changes you make to this affect the current browser history item (modifying the URL if needed).
986
+
987
+ **Value:** `Route`
988
+
989
+
990
+ ## Path matching (aberdeen/dispatcher)
991
+
992
+ ## MATCH_FAILED · constant
993
+
994
+ Symbol to return when a custom `Dispatcher.addRoute` matcher cannot match a segment.
995
+
996
+ **Value:** `unique symbol`
997
+
998
+ ## MATCH_REST · constant
999
+
1000
+ Special `Dispatcher.addRoute` matcher that matches the rest of the segments as an array of strings.
1001
+
1002
+ **Value:** `unique symbol`
1003
+
1004
+ ## [Dispatcher](Dispatcher.md) · class
1005
+
1006
+ Simple route matcher and dispatcher.
1007
+
1008
+
1009
+ ## Optimistic UI (aberdeen/prediction)
1010
+
1011
+ ## [applyPrediction](applyPrediction.md) · function
1012
+
1013
+ Run the provided function, while treating all changes to Observables as predictions,
1014
+ meaning they will be reverted when changes come back from the server (or some other
1015
+ async source).
1016
+
1017
+ ## [applyCanon](applyCanon.md) · function
1018
+
1019
+ Temporarily revert all outstanding predictions, optionally run the provided function
1020
+ (which will generally make authoritative changes to the data based on a server response),
1021
+ and then attempt to reapply the predictions on top of the new canonical state, dropping
1022
+ any predictions that can no longer be applied cleanly (the data has been modified) or
1023
+ that were specified in `dropPredictions`.
1024
+
1025
+ ## Patch · type
1026
+
1027
+ Represents a set of changes that can be applied to proxied objects.
1028
+ This is an opaque type - its internal structure is not part of the public API.
1029
+
1030
+ **Type:** `Map<TargetType, Map<any, [any, any]>>`
1031
+
1032
+
1033
+ ## Transitions (aberdeen/transitions)
1034
+
1035
+ ## [grow](grow.md) · function
1036
+
1037
+ Do a grow transition for the given element. This is meant to be used as a
1038
+ handler for the `create` property.
1039
+
1040
+ ## [shrink](shrink.md) · function
1041
+
1042
+ Do a shrink transition for the given element, and remove it from the DOM
1043
+ afterwards. This is meant to be used as a handler for the `destroy` property.
926
1044
 
927
- - [Reference documentation](https://aberdeenjs.org/modules.html)
928
- - [Examples](https://aberdeenjs.org/#examples)
@@ -0,0 +1,20 @@
1
+ ## applyCanon · function
2
+
3
+ Temporarily revert all outstanding predictions, optionally run the provided function
4
+ (which will generally make authoritative changes to the data based on a server response),
5
+ and then attempt to reapply the predictions on top of the new canonical state, dropping
6
+ any predictions that can no longer be applied cleanly (the data has been modified) or
7
+ that were specified in `dropPredictions`.
8
+
9
+ All of this is done such that redraws are only triggered if the overall effect is an
10
+ actual change to an `Observable`.
11
+
12
+ **Signature:** `(canonFunc?: () => void, dropPredictions?: Patch[]) => void`
13
+
14
+ **Parameters:**
15
+
16
+ - `canonFunc?: () => void` - The function to run without any predictions applied. This will typically
17
+ make authoritative changes to the data, based on a server response.
18
+ - `dropPredictions: Array<Patch>` (optional) - An optional list of predictions (as returned by `applyPrediction`)
19
+ to undo. Typically, when a server response for a certain request is being handled,
20
+ you'd want to drop the prediction that was done for that request.
@@ -0,0 +1,15 @@
1
+ ## applyPrediction · function
2
+
3
+ Run the provided function, while treating all changes to Observables as predictions,
4
+ meaning they will be reverted when changes come back from the server (or some other
5
+ async source).
6
+
7
+ **Signature:** `(predictFunc: () => void) => Patch`
8
+
9
+ **Parameters:**
10
+
11
+ - `predictFunc: () => void` - The function to run. It will generally modify some Observables
12
+ to immediately reflect state (as closely as possible) that we expect the server
13
+ to communicate back to us later on.
14
+
15
+ **Returns:** A `Patch` object. Don't modify it. This is only meant to be passed to `applyCanon`.
package/skill/back.md ADDED
@@ -0,0 +1,11 @@
1
+ ## back · function
2
+
3
+ Try to go back in history to the first entry that matches the given target. If none is found, the given state will replace the current page. This is useful for "cancel" or "close" actions that should return to the previous page if possible, but create a new page if not (for instance when arriving at the current page through a direct link).
4
+
5
+ Consider using `up` to go up in the path hierarchy.
6
+
7
+ **Signature:** `(target?: RouteTarget) => void`
8
+
9
+ **Parameters:**
10
+
11
+ - `target: RouteTarget` (optional) - The target route to go back to. May be a subset of `Route`, or a string (for `path`), or an array of strings (for `p`).
package/skill/clean.md ADDED
@@ -0,0 +1,43 @@
1
+ ## clean · function
2
+
3
+ Registers a cleanup function to be executed just before the current reactive scope
4
+ is destroyed or redraws.
5
+
6
+ This is useful for releasing resources, removing manual event listeners, or cleaning up
7
+ side effects associated with the scope. Cleaners are run in reverse order of registration.
8
+
9
+ Scopes are created by functions like `derive`, `mount`, | A (when given a render function),
10
+ and internally by constructs like `onEach`.
11
+
12
+ **Signature:** `(cleaner: () => void) => void`
13
+
14
+ **Parameters:**
15
+
16
+ - `cleaner: () => void` - - The function to execute during cleanup.
17
+
18
+ **Examples:**
19
+
20
+ Maintaing a sum for a changing array
21
+ ```typescript
22
+ const $numbers = A.proxy([3, 5, 10]);
23
+ let $sum = A.proxy(0);
24
+
25
+ // Show the array items and maintain the sum
26
+ A.onEach($numbers, (item, index) => {
27
+ A(`code#${index}→${item}`);
28
+ // We'll update $sum.value using peek, as += first does a read, but
29
+ // we don't want to subscribe.
30
+ A.peek(() => $sum.value += item);
31
+ // Clean gets called before each rerun for a certain item index
32
+ // No need for peek here, as the clean code doesn't run in an
33
+ // observer scope.
34
+ A.clean(() => $sum.value -= item);
35
+ })
36
+
37
+ // Show the sum
38
+ A('h1 text=', $sum);
39
+
40
+ // Make random changes to the array
41
+ const rnd = () => 0|(Math.random()*20);
42
+ setInterval(() => $numbers[rnd()] = rnd(), 1000);
43
+ ```
package/skill/clone.md ADDED
@@ -0,0 +1,15 @@
1
+ ## clone · function
2
+
3
+ Clone an (optionally proxied) object or array.
4
+
5
+ **Signature:** `<T extends object>(src: T) => T`
6
+
7
+ **Type Parameters:**
8
+
9
+ - `T extends object` - The type of the objects being copied.
10
+
11
+ **Parameters:**
12
+
13
+ - `src: T` - The object or array to clone. If it is proxied, `clone` will subscribe to any changes to the (nested) data structure.
14
+
15
+ **Returns:** A new unproxied array or object (of the same type as `src`), containing a deep copy of `src`.
package/skill/copy.md ADDED
@@ -0,0 +1,40 @@
1
+ ## copy · function
2
+
3
+ Recursively copies properties or array items from `src` to `dst`.
4
+ It's designed to work efficiently with reactive proxies created by `proxy`.
5
+
6
+ - **Minimizes Updates:** When copying between objects/arrays (proxied or not), if a nested object
7
+ exists in `dst` with the same constructor as the corresponding object in `src`, `copy`
8
+ will recursively copy properties into the existing `dst` object instead of replacing it.
9
+ This minimizes change notifications for reactive (proxied) destinations.
10
+ - **Fast with Proxies:** When copying to/from proxied objects, `copy` uses Aberdeen internals
11
+ to speed things up (compared to a non-Aberdeen-aware deep copy).
12
+
13
+ **Signature:** `{ <T extends object>(dst: T, src: T): boolean; <T extends object>(dst: T, dstKey: keyof T, src: T[keyof T]): boolean; }`
14
+
15
+ **Type Parameters:**
16
+
17
+ - `T extends object` - The type of the objects being copied.
18
+
19
+ **Parameters:**
20
+
21
+ - `dst: T` - - The destination object/array/Map (proxied or unproxied).
22
+ - `src: T` - - The source object/array/Map (proxied or unproxied). It won't be modified.
23
+
24
+ **Returns:** `true` if any changes were made to `dst`, or `false` if not.
25
+
26
+ **Throws:**
27
+
28
+ - Error if attempting to copy an array into a non-array or vice versa.
29
+
30
+ **Examples:**
31
+
32
+ Basic Copy
33
+ ```typescript
34
+ const $source = A.proxy({ a: 1, b: { c: 2 } });
35
+ const $dest = A.proxy({ b: { d: 3 } });
36
+ A.copy($dest, $source);
37
+ console.log($dest); // proxy({ a: 1, b: { c: 2 } })
38
+ A.copy($dest, 'b', { e: 4 });
39
+ console.log($dest); // proxy({ a: 1, b: { e: 4 } })
40
+ ```
package/skill/count.md ADDED
@@ -0,0 +1,32 @@
1
+ ## count · function
2
+
3
+ Reactively counts the number of properties in an object.
4
+
5
+ **Signature:** `(proxied: TargetType) => ValueRef<number>`
6
+
7
+ **Parameters:**
8
+
9
+ - `proxied: TargetType` - The observable object to count. In case an `array`, `Map`, or `Set` is passed in, a `ref` to its `.length` or `.size` will be returned.
10
+
11
+ **Returns:** 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.
12
+
13
+ **Examples:**
14
+
15
+ ```typescript
16
+ const $items = A.proxy({x: 3, y: 7} as any);
17
+ const $count = A.count($items);
18
+
19
+ // Create a DOM text node for the count:
20
+ A('div text=', $count);
21
+ // <div>2</div>
22
+
23
+ // Or we can use it in an `derive` function:
24
+ A(() => console.log("The count is now", $count.value));
25
+ // The count is now 2
26
+
27
+ // Adding/removing items will update the count
28
+ $items.z = 12;
29
+ // Asynchronously, after 0ms:
30
+ // <div>3</div>
31
+ // The count is now 3
32
+ ```
@@ -0,0 +1,15 @@
1
+ ## cssVars · constant
2
+
3
+ A reactive object containing CSS variable definitions.
4
+
5
+ Any property you assign to `cssVars` becomes available as a CSS custom property throughout your application.
6
+
7
+ Use `setSpacingCssVars` to optionally initialize `cssVars[1]` through `cssVars[12]` with an exponential spacing scale.
8
+
9
+ When you reference a CSS variable in Aberdeen using the `$` prefix (e.g., `$primary`), it automatically resolves to `var(--primary)`.
10
+ 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)`).
11
+
12
+ When you add the first property to cssVars, Aberdeen automatically creates a reactive `<style>` tag in `<head>`
13
+ containing the `:root` CSS custom property declarations. The style tag is automatically removed if cssVars becomes empty.
14
+
15
+ **Value:** `Record<string, string>`