aberdeen 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,10 +38,10 @@ $('h3', () => {
38
38
  $('input placeholder=Question bind=', ref(state, 'question'))
39
39
 
40
40
  // Allow state.answer to be modified using both an <input> and buttons
41
- $('div.row $marginTop=1em', () => {
42
- $('button:-', {click: () => state.answer--});
43
- $('input', {type: 'number', bind: ref(state, 'answer')})
44
- $('button:+', {click: () => state.answer++});
41
+ $('div.row marginTop:1em', () => {
42
+ $('button text=- click=', () => state.answer--);
43
+ $('input type=number bind=', ref(state, 'answer'))
44
+ $('button text=+ click=', () => state.answer++);
45
45
  });
46
46
  ```
47
47
 
@@ -79,10 +79,10 @@ function drawMain() {
79
79
 
80
80
  // Add item and delete checked buttons.
81
81
  $('div.row', () => {
82
- $('button:+', {
82
+ $('button#+', {
83
83
  click: () => items.push(new TodoItem("")),
84
84
  });
85
- $('button.outline:Delete checked', {
85
+ $('button.outline#Delete checked', {
86
86
  click: () => {
87
87
  for(let idx in items) {
88
88
  if (items[idx].done) delete items[idx];
@@ -104,7 +104,7 @@ function drawItem(item) {
104
104
  $({".done": ref(item,'done')});
105
105
 
106
106
  // The checkmark is hidden using CSS
107
- $('div.checkmark:✅');
107
+ $('div.checkmark#✅');
108
108
 
109
109
  if (editing.value) {
110
110
  // Label <input>. Save using enter or button.
@@ -117,15 +117,15 @@ function drawItem(item) {
117
117
  value: item.label,
118
118
  keydown: e => e.key==='Enter' && save(),
119
119
  });
120
- $('button.outline:Cancel', {click: () => editing.value = false});
121
- $('button:Save', {click: save});
120
+ $('button.outline#Cancel', {click: () => editing.value = false});
121
+ $('button#Save', {click: save});
122
122
  } else {
123
123
  // Label as text.
124
- $('p:' + item.label);
124
+ $('p#' + item.label);
125
125
 
126
126
  // Edit icon, if not done.
127
127
  if (!item.done) {
128
- $('a:Edit', {
128
+ $('a#Edit', {
129
129
  click: e => {
130
130
  editing.value = true;
131
131
  e.stopPropagation(); // We don't want to toggle as well.
@@ -134,7 +134,7 @@ function drawItem(item) {
134
134
  }
135
135
 
136
136
  // Clicking a row toggles done.
137
- $({click: () => item.done = !item.done, $cursor: 'pointer'});
137
+ $('cursor:pointer click=', () => item.done = !item.done);
138
138
  }
139
139
  });
140
140
  }
@@ -174,6 +174,14 @@ And you may want to study the examples above, of course!
174
174
 
175
175
  ## Changelog
176
176
 
177
+ ### 1.3.0 (2025-12-03)
178
+ **Breaking changes:**
179
+ - The shortcut for setting inline CSS styles in now `$('div color:red')` instead of `$('div $color=red')`.
180
+ - The shortcut for adding text content is now `$('p#Hello')` instead of `$('p:Hello')`. It now also works with dynamic content: `$('p#', myObservable)`.
181
+
182
+ **Enhancements:**
183
+ - New A() string parser, reducing complexity and line count.
184
+
177
185
  ### 1.2.0 (2025-09-27)
178
186
 
179
187
  **Enhancements:**
package/README.md.bak ADDED
@@ -0,0 +1,212 @@
1
+ # [Aberdeen](https://aberdeenjs.org/) [![](https://img.shields.io/badge/license-ISC-blue.svg)](https://github.com/vanviegen/aberdeen/blob/master/LICENSE.txt) [![](https://badge.fury.io/js/aberdeen.svg)](https://badge.fury.io/js/aberdeen) ![](https://img.shields.io/bundlejs/size/aberdeen) [![](https://img.shields.io/github/last-commit/vanviegen/aberdeen)](https://github.com/vanviegen/aberdeen)
2
+
3
+ Build fast reactive UIs in pure TypeScript/JavaScript without a virtual DOM.
4
+
5
+ Aberdeen's approach is refreshingly simple:
6
+
7
+ > Use many small anonymous functions for emitting DOM elements, and automatically rerun them when their underlying data changes. JavaScript `Proxy` is used to track reads and updates to this data, which can consist of anything, from simple values to complex, typed, and deeply nested data structures.
8
+
9
+ ## Why use Aberdeen?
10
+
11
+ - 🎩 **Simple:** Express UIs naturally in JavaScript/TypeScript, without build steps or JSX, and with a minimal amount of concepts you need to learn.
12
+ - ⏩ **Fast:** No virtual DOM. Aberdeen intelligently updates only the minimal, necessary parts of your UI when proxied data changes.
13
+ - 👥 **Awesome lists**: It's very easy and performant to reactively display data sorted by whatever you like.
14
+ - 🔬 **Tiny:** Around 6KB (minimized and gzipped) for the core system. Zero runtime dependencies.
15
+ - 🔋 **Batteries included**: Comes with browser history management, routing, revertible patches for optimistic user-interface updates, component-local CSS, SVG support, helper functions for transforming reactive data (mapping, partitioning, filtering, etc) and hide/unhide transition effects. No bikeshedding required!
16
+
17
+ ## Why *not* use Aberdeen?
18
+
19
+ - 🤷 **Lack of community:** There are not many of us -Aberdeen developers- yet, so don't expect terribly helpful Stack Overflow/AI answers.
20
+ - 📚 **Lack of ecosystem:** You'd have to code things yourself, instead of duct-taping together a gazillion React ecosystem libraries.
21
+
22
+ ## Examples
23
+
24
+ First, let's start with the obligatory reactive counter example. If you're reading this on [the official website](https://aberdeenjs.org) you should see a working demo below the code, and an 'edit' button in the top-right corner of the code, to play around.
25
+
26
+ ```javascript
27
+ import A from 'aberdeen';
28
+
29
+ // Define some state as a proxied (observable) object
30
+ const state = A.proxy({question: "How many roads must a man walk down?", answer: 42});
31
+
32
+ A`h3`(() => {
33
+ // This function reruns whenever the question or the answer changes
34
+ A`"${state.question} ↪ ${state.answer || 'Blowing in the wind'}"`;
35
+ });
36
+
37
+ // Two-way bind state.question to an <input>
38
+ A`input placeholder=Question bind!${A.at(state, 'question')}`;
39
+
40
+ // Allow state.answer to be modified using both an <input> and buttons
41
+ A`div.row`(() => {
42
+ A`button click=${() => state.answer--} "-"`;
43
+ A`input type=number bind!${A.at(state, 'answer')}`;
44
+ A`button click=${() => state.answer++} "+"`;
45
+ });
46
+ ```
47
+
48
+ Okay, next up is a somewhat more complex app - a todo-list with the following behavior:
49
+
50
+ - New items open in an 'editing state'.
51
+ - Items that are in 'editing state' show a text input, a save button and a cancel button. Done status cannot be toggled while editing.
52
+ - Pressing one of the buttons, or pressing enter will transition from 'editing state' to 'viewing state', saving the new label text unless cancel was pressed.
53
+ - In 'viewing state', the label is shown as non-editable. There's an 'Edit' link, that will transition the item to 'editing state'. Clicking anywhere else will toggle the done status.
54
+ - The list of items is sorted alphabetically by label. Items move when 'save' changes their label.
55
+ - Items that are created, moved or deleted grow and shrink as appropriate.
56
+
57
+ Pfew.. now let's look at the code:
58
+
59
+ ```typescript
60
+ import A from "aberdeen";
61
+ import {grow, shrink} from "aberdeen/transitions";
62
+
63
+ // We'll use a simple class to store our data.
64
+ class TodoItem {
65
+ constructor(public label: string = '', public done: boolean = false) {}
66
+ toggle() { this.done = !this.done; }
67
+ }
68
+
69
+ // The top-level user interface.
70
+ function drawMain() {
71
+ // Add some initial items. We'll wrap a proxy() around it!
72
+ let items: TodoItem[] = A.proxy([
73
+ new TodoItem('Make todo-list demo', true),
74
+ new TodoItem('Learn Aberdeen', false),
75
+ ]);
76
+
77
+ // Draw the list, ordered by label.
78
+ A.onEach(items, drawItem, item => item.label);
79
+
80
+ // Add item and delete checked buttons.
81
+ A`div.row`(() => {
82
+ A`button click=${() => items.push(new TodoItem(""))} "+"`;
83
+ A`button.outline click=${() => {
84
+ for(let idx in items) {
85
+ if (items[idx].done) delete items[idx];
86
+ }
87
+ }} "Delete checked"`;
88
+ });
89
+ };
90
+
91
+ // Called for each todo list item.
92
+ function drawItem(item) {
93
+ // Items without a label open in editing state.
94
+ // Note that we're creating this proxy outside the `div.row` scope
95
+ // create below, so that it will persist when that state reruns.
96
+ let editing: {value: boolean} = A.proxy(item.label == '');
97
+
98
+ A`div.row.${todoItemStyle} create!${grow} destroy!${shrink}`(() => {
99
+ // Conditionally add a class to `div.row`, based on item.done
100
+ A`if!${A.at(item,'done')} .done`;
101
+
102
+ // The checkmark is hidden using CSS
103
+ A`div.checkmark "✅"`;
104
+
105
+ if (editing.value) {
106
+ // Label <input>. Save using enter or button.
107
+ function save() {
108
+ editing.value = false;
109
+ item.label = inputElement.value;
110
+ }
111
+ let inputElement = A`input placeholder=Label value~${item.label} keydown=${e => e.key==='Enter' && save()}`;
112
+ A`button.outline click=${() => editing.value = false} "Cancel"`;
113
+ A`button click=${save} "Save"`;
114
+ } else {
115
+ // Label as text.
116
+ A`p "${item.label}"`;
117
+
118
+ // Edit icon, if not done.
119
+ if (!item.done) {
120
+ A`a click=${e => {
121
+ editing.value = true;
122
+ e.stopPropagation(); // We don't want to toggle as well.
123
+ }} "Edit"`;
124
+ }
125
+
126
+ // Clicking a row toggles done.
127
+ A`click=${() => item.done = !item.done} cursor:pointer`;
128
+ }
129
+ });
130
+ }
131
+
132
+ // Insert some component-local CSS, specific for this demo.
133
+ const todoItemStyle = A.insertCss({
134
+ marginBottom: "0.5rem",
135
+ ".checkmark": {
136
+ opacity: 0.2,
137
+ },
138
+ "&.done": {
139
+ textDecoration: "line-through",
140
+ ".checkmark": {
141
+ opacity: 1,
142
+ },
143
+ },
144
+ });
145
+
146
+ // Go!
147
+ drawMain();
148
+ ```
149
+
150
+ Some further examples:
151
+
152
+ - [Input demo](https://aberdeenjs.org/examples/input/) - [Source](https://github.com/vanviegen/aberdeen/tree/master/examples/input)
153
+ - [Tic Tac Toe demo](https://aberdeenjs.org/examples/tictactoe/) - [Source](https://github.com/vanviegen/aberdeen/tree/master/examples/tictactoe)
154
+ - [List demo](https://aberdeenjs.org/examples/list/) - [Source](https://github.com/vanviegen/aberdeen/tree/master/examples/list)
155
+ - [Routing demo](https://aberdeenjs.org/examples/router/) - [Source](https://github.com/vanviegen/aberdeen/tree/master/examples/router)
156
+ - [JS Framework Benchmark demo](https://aberdeenjs.org/examples/js-framework-benchmark/) - [Source](https://github.com/vanviegen/aberdeen/tree/master/examples/js-framework-benchmark)
157
+
158
+ ## Learning Aberdeen
159
+
160
+ - [Tutorial](https://aberdeenjs.org/Tutorial/)
161
+ - [Reference documentation](https://aberdeenjs.org/modules.html)
162
+
163
+ And you may want to study the examples above, of course!
164
+
165
+ ## Changelog
166
+
167
+ ### 1.2.0 (2025-09-27)
168
+
169
+ **Enhancements:**
170
+ - The `A` function now supports a concise template literal syntax for creating elements, setting attributes and properties, adding classes, etc. See the documentation for details.
171
+ - The `A.proxy()` function can now accept `Promise`s, which will return an observable object with properties for `busy` status, `error` (if any), and the resolved `value`. This makes it easier to call async functions from within UI code.
172
+
173
+ **Breaking changes:**
174
+ - When a UI render function returns a `Promise`, that will now be reported as an error. Async render functions are fundamentally incompatible with Aberdeen's reactive model, so it's helpful to point that out. Use the new `A.proxy()` async support instead.
175
+ - Setting attributes versus properties is no longer automatically inferred. Use `name=value` for attributes and `name~value` for properties.
176
+ - Special attributes (like `bind`, `create`, `destroy`, `if`, `else`, `end`, and `html`) now use a different syntax: `name!value` or just `name!`.
177
+ - Conditional rendering has been completely redesigned, now using `if!`, `else!`, and `end!` special attributes with different semantics.
178
+
179
+ ### 1.1.0 (2025-09-12)
180
+
181
+ This major release aims to reduce surprises in our API, aligning more closely with regular JavaScript semantics (for better or worse).
182
+
183
+ **Breaking changes:**
184
+
185
+ - Functions that iterate objects (like `A.onEach` and `A.map`) will now only work on *own* properties of the object, ignoring those in the prototype chain. The new behavior should be more consistent and faster.
186
+ - These iteration function now properly distinguish between `undefined` and *empty*. Previously, object/array/map items with `undefined` values were considered non-existent. The new behavior (though arguably confusing) is more consistent with regular JavaScript semantics.
187
+ - The `A.copy` function no longer ..
188
+ - Supports `SHALLOW` and `MERGE` flags. The latter has been replaced by a dedicated `A.merge` function. The former turned out not to be particularly useful.
189
+ - Has weird special cases that would allow copying objects into maps and merging objects into arrays.
190
+ - Copies properties from the prototype chain of objects. Only *own* properties are copied now. As the prototype link itself *is* copied over, this should actually result in copies being *more* similar to the original.
191
+ - The `observe` function has been renamed to `A.derive` to better reflect its purpose and match terminology used in other reactive programming libraries.
192
+ - The `A.route` API brings some significant changes. Modifying the `A.route` observable (which should now be accessed as `A.route.current`) will now always result in changing the current browser history item (URL and state, using `replaceState`), instead of using a heuristic to figure out what you probably want. Dedicated functions have been added for navigating to a new URL (`A.go`), back to a previous URL (`A.back`), and for going up in the route hierarchy (`A.up`).
193
+ - The concept of immediate observers (through the `immediateObserve` function) no longer exists. It caused unexpected behavior (for instance due to the fact that an array `pop()` in JavaScript is implemented as a delete followed by a length change, so happens in two steps that would each call immediate observers). The reason it existed was mostly to enable a pre-1.0 version of the `A.route` API. It turned out to be a mistake.
194
+
195
+ **Enhancements:**
196
+
197
+ - The `A.peek` function can now also accept an object and a key as argument (e.g. `A.peek(obj, 'myKey')`). It does the same as `A.peek(() => obj.myKey)`, but more concise and faster.
198
+ - The `A.copy` and `A.merge` functions now ..
199
+ - Accept an optional `dstKey` argument, allowing you to assign to a specific key with `A.copy` semantics, and without subscribing to the key.
200
+ - Return a boolean indicating whether any changes were made.
201
+ - Are faster.
202
+ - A new `A.dispatcher` module has been added. It provides a simple and type-safe way to match URL paths to handler functions, and extract parameters from the path. You can still use your own routing solution if you prefer, of course.
203
+ - The `A.route` module now also has tests, making the whole project now fully covered by tests.
204
+
205
+ **Fixes:**
206
+
207
+ - Browser-back behavior in the `A.route` module had some reliability issues after page reloads.
208
+ - The `A.copy` and `A.clone` function created Maps and Arrays with the wrong internal type. So `instanceof Array` would say yes, while `Array.isArray` would say no. JavaScript is weird.
209
+
210
+ ### 1.0.0 (2025-05-07)
211
+
212
+ After five years of working on this library on and off, I'm finally happy with its API and the developer experience it offers. I'm calling it 1.0! To celebrate, I've created some pretty fancy (if I may say so myself) interactive documentation and a tutorial.
@@ -49,7 +49,7 @@ export declare function runQueue(): void;
49
49
  * ]);
50
50
  *
51
51
  * onEach(users, (user) => {
52
- * $(`p:${user.name}: ${user.score}`);
52
+ * $(`p#${user.name}: ${user.score}`);
53
53
  * }, (user) => invertString(user.name)); // Reverse alphabetic order
54
54
  * ```
55
55
  *
@@ -80,9 +80,9 @@ export declare function onEach<K extends string | number | symbol, T>(target: Re
80
80
  * // Reactively display a message if the items array is empty
81
81
  * $('div', () => {
82
82
  * if (isEmpty(items)) {
83
- * $('p', 'i:No items yet!');
83
+ * $('p', 'i#No items yet!');
84
84
  * } else {
85
- * onEach(items, item=>$('p:'+item));
85
+ * onEach(items, item=>$('p#'+item));
86
86
  * }
87
87
  * });
88
88
  *
@@ -125,10 +125,22 @@ export interface ValueRef<T> {
125
125
  * ```
126
126
  */
127
127
  export declare function count(proxied: TargetType): ValueRef<number>;
128
- interface PromiseProxy<T> {
128
+ /**
129
+ * When `proxy` is called with a Promise, the returned object has this shape.
130
+ */
131
+ export interface PromiseProxy<T> {
132
+ /**
133
+ * True if the promise is still pending, false if it has resolved or rejected.
134
+ */
129
135
  busy: boolean;
130
- error?: any;
136
+ /**
137
+ * If the promise has resolved, this contains the resolved value.
138
+ */
131
139
  value?: T;
140
+ /**
141
+ * If the promise has rejected, this contains the rejection error.
142
+ */
143
+ error?: any;
132
144
  }
133
145
  export declare function proxy<T extends any>(target: Promise<T>): PromiseProxy<T>;
134
146
  export declare function proxy<T extends any>(target: Array<T>): Array<T extends number ? number : T extends string ? string : T extends boolean ? boolean : T>;
@@ -233,6 +245,12 @@ export declare function copy<T extends object>(dst: T, dstKey: keyof T, src: T[t
233
245
  */
234
246
  export declare function merge<T extends object>(dst: T, value: Partial<T>): boolean;
235
247
  export declare function merge<T extends object>(dst: T, dstKey: keyof T, value: Partial<T[typeof dstKey]>): boolean;
248
+ /**
249
+ * A symbol that can be added to an object to prevent it from being cloned by {@link clone} or {@link copy}.
250
+ * This is useful for objects that should be shared by reference. That also mean that their contents won't
251
+ * be observed for changes.
252
+ */
253
+ export declare const NO_COPY: unique symbol;
236
254
  /**
237
255
  * Clone an (optionally proxied) object or array.
238
256
  *
@@ -267,7 +285,7 @@ export declare function clone<T extends object>(src: T): T;
267
285
  * });
268
286
  *
269
287
  * // Usage as a dynamic property, causes a TextNode with just the name to be created and live-updated
270
- * $('p:Selected color: ', {
288
+ * $('p#Selected color: ', {
271
289
  * text: ref(formData, 'color'),
272
290
  * $color: ref(formData, 'color')
273
291
  * });
@@ -285,12 +303,12 @@ export declare function ref<T extends TargetType, K extends keyof T>(target: T,
285
303
  * @param {...(string | function | object | false | undefined | null)} args - Any number of arguments can be given. How they're interpreted depends on their types:
286
304
  *
287
305
  * - `string`: Strings can be used to create and insert new elements, set classnames for the *current* element, and add text to the current element.
288
- * The format of a string is: (**tag** | `.` **class** | **key**=**val** | **key**="**long val**")* (':' **text** | **key**=)?
306
+ * The format of a string is: (**tag** | `.` **class** | **key**=**val** | **key**="**long val**")* ('#' **text** | **key**=)?
289
307
  * So there can be:
290
308
  * - Any number of **tag** element, like `h1` or `div`. These elements are created, added to the *current* element, and become the new *current* element for the rest of this `$` function execution.
291
309
  * - Any number of 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.
292
310
  * - Any number of key/value pairs with string values, like `placeholder="Your name"` or `data-id=123`. These will be handled according to the rules specified for `object`, below, but with the caveat that values can only be strings. The quotes around string values are optional, unless the value contains spaces. It's not possible to escape quotes within the value. If you want to do that, or if you have user-provided values, use the `object` syntax (see below) or end your string with `key=` followed by the data as a separate argument (see below).
293
- * - The string may end in 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.
311
+ * - The string may end in 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.
294
312
  * - Alternatively, the string may end in 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 rules specified for `object` below. This is useful when the value is not a string or contains spaces or user data. Example: `$('button text="Click me" click=', () => alert('Clicked!'))` or `$('input.value=', someUserData, "placeholder=", "Type your stuff")`.
295
313
  * - `function`: When a function (without argument nor a return value) is passed in, it will be reactively executed in its own observer scope, preserving the *current element*. So any `$()` invocations within this function will create DOM elements with our *current* element as parent. If the function reads observable data, and that data is changed later on, the function we re-execute (after side effects, such as DOM modifications through `$`, have been cleaned - see also {@link clean}).
296
314
  * - `object`: When an object is passed in, its key-value pairs are used to modify the *current* element in the following ways...
@@ -306,7 +324,7 @@ export declare function ref<T extends TargetType, K extends keyof T>(target: T,
306
324
  * - `{<any>: <obsvalue>}`: Create a new observer scope and read the `value` property of the given observable (proxy) variable from within it, and apply the contained value using any of the other rules in this list. Example:
307
325
  * ```typescript
308
326
  * const myColor = proxy('red');
309
- * $('p:Test', {$color: myColor, click: () => myColor.value = 'yellow'})
327
+ * $('p#Test', {$color: myColor, click: () => myColor.value = 'yellow'})
310
328
  * // Clicking the text will cause it to change color without recreating the <p> itself
311
329
  * ```
312
330
  * This is often used together with {@link ref}, in order to use properties other than `.value`.
@@ -319,7 +337,7 @@ export declare function ref<T extends TargetType, K extends keyof T>(target: T,
319
337
  *
320
338
  * @example Create Element
321
339
  * ```typescript
322
- * $('button.secondary.outline:Submit', {
340
+ * $('button.secondary.outline#Submit', {
323
341
  * disabled: false,
324
342
  * click: () => console.log('Clicked!'),
325
343
  * $color: 'red'
@@ -336,7 +354,7 @@ export declare function ref<T extends TargetType, K extends keyof T>(target: T,
336
354
  *
337
355
  * @example Create Nested Elements
338
356
  * ```typescript
339
- * let inputElement: Element = $('label:Click me', 'input', {type: 'checkbox'});
357
+ * let inputElement: Element = $('label#Click me', 'input', {type: 'checkbox'});
340
358
  * // You should usually not touch raw DOM elements, unless when integrating
341
359
  * // with non-Aberdeen code.
342
360
  * console.log('DOM element:', inputElement);
@@ -347,8 +365,8 @@ export declare function ref<T extends TargetType, K extends keyof T>(target: T,
347
365
  * const state = proxy({ count: 0 });
348
366
  * $('div', () => { // Outer element
349
367
  * // This scope re-renders when state.count changes
350
- * $(`p:Count is ${state.count}`);
351
- * $('button:Increment', { click: () => state.count++ });
368
+ * $(`p#Count is ${state.count}`);
369
+ * $('button#Increment', { click: () => state.count++ });
352
370
  * });
353
371
  * ```
354
372
  *
@@ -357,17 +375,17 @@ export declare function ref<T extends TargetType, K extends keyof T>(target: T,
357
375
  * const user = proxy({ name: '' });
358
376
  * $('input', { placeholder: 'Name', bind: ref(user, 'name') });
359
377
  * $('h3', () => { // Reactive scope
360
- * $(`:Hello ${user.name || 'stranger'}`);
378
+ * $(`#Hello ${user.name || 'stranger'}`);
361
379
  * });
362
380
  * ```
363
381
  *
364
382
  * @example Conditional Rendering
365
383
  * ```typescript
366
384
  * const show = proxy(false);
367
- * $('button', { click: () => show.value = !show.value }, () => $(show.value ? ':Hide' : ':Show'));
385
+ * $('button', { click: () => show.value = !show.value }, () => $(show.value ? '#Hide' : '#Show'));
368
386
  * $(() => { // Reactive scope
369
387
  * if (show.value) {
370
- * $('p:Details are visible!');
388
+ * $('p#Details are visible!');
371
389
  * }
372
390
  * });
373
391
  * ```
@@ -410,8 +428,8 @@ export declare function $(...args: (string | null | undefined | false | (() => v
410
428
  *
411
429
  * // Apply the styles
412
430
  * $(scopeClass, () => { // Add class to the div
413
- * $(`:Scoped content`);
414
- * $('div.child-element:Child'); // .AbdStl1 .child-element rule applies
431
+ * $(`#Scoped content`);
432
+ * $('div.child-element#Child'); // .AbdStl1 .child-element rule applies
415
433
  * });
416
434
  * ```
417
435
  *
@@ -427,7 +445,7 @@ export declare function $(...args: (string | null | undefined | false | (() => v
427
445
  * }
428
446
  * }, true); // Pass true for global
429
447
  *
430
- * $('a:Styled link');
448
+ * $('a#Styled link');
431
449
  * ```
432
450
  */
433
451
  export declare function insertCss(style: object, global?: boolean): string;
@@ -455,7 +473,7 @@ export declare function insertCss(style: object, global?: boolean): string;
455
473
  *
456
474
  * try {
457
475
  * // Attempt to show a custom message in the UI
458
- * $('div.error-message:Oops, something went wrong!');
476
+ * $('div.error-message#Oops, something went wrong!');
459
477
  * } catch (e) {
460
478
  * // Ignore errors during error handling itself
461
479
  * }
@@ -526,7 +544,7 @@ export declare function getParentElement(): Element;
526
544
  *
527
545
  * // Show the array items and maintain the sum
528
546
  * onEach(myArray, (item, index) => {
529
- * $(`code:${index}→${item}`);
547
+ * $(`code#${index}→${item}`);
530
548
  * // We'll update sum.value using peek, as += first does a read, but
531
549
  * // we don't want to subscribe.
532
550
  * peek(() => sum.value += item);
@@ -565,14 +583,14 @@ export declare function clean(cleaner: () => void): void;
565
583
  *
566
584
  * $('main', () => {
567
585
  * console.log('Welcome');
568
- * $('h3:Welcome, ' + data.user); // Reactive text
586
+ * $('h3#Welcome, ' + data.user); // Reactive text
569
587
  *
570
588
  * derive(() => {
571
589
  * // When data.notifications changes, only this inner scope reruns,
572
590
  * // leaving the `<p>Welcome, ..</p>` untouched.
573
591
  * console.log('Notifications');
574
- * $('code.notification-badge:' + data.notifications);
575
- * $('a:Notify!', {click: () => data.notifications++});
592
+ * $('code.notification-badge#' + data.notifications);
593
+ * $('a#Notify!', {click: () => data.notifications++});
576
594
  * });
577
595
  * });
578
596
  * ```
@@ -586,7 +604,7 @@ export declare function clean(cleaner: () => void): void;
586
604
  * const double = derive(() => counter.value * 2);
587
605
  *
588
606
  * $('h3', () => {
589
- * $(`:counter=${counter.value} double=${double.value}`);
607
+ * $(`#counter=${counter.value} double=${double.value}`);
590
608
  * })
591
609
  * ```
592
610
  *
@@ -623,12 +641,12 @@ export declare function derive<T>(func: () => T): ValueRef<T>;
623
641
  * setInterval(() => runTime.value++, 1000);
624
642
  *
625
643
  * mount(document.getElementById('app-root'), () => {
626
- * $('h4:Aberdeen App');
627
- * $(`p:Run time: ${runTime.value}s`);
644
+ * $('h4#Aberdeen App');
645
+ * $(`p#Run time: ${runTime.value}s`);
628
646
  * // Conditionally render some content somewhere else in the static page
629
647
  * if (runTime.value&1) {
630
648
  * mount(document.getElementById('title-extra'), () =>
631
- * $(`i:(${runTime.value}s)`)
649
+ * $(`i#(${runTime.value}s)`)
632
650
  * );
633
651
  * }
634
652
  * });
@@ -717,7 +735,7 @@ export declare function partition<IN_K extends string | number | symbol, OUT_K e
717
735
  * items: ['a', 'b']
718
736
  * });
719
737
  *
720
- * $('h2:Live State Dump');
738
+ * $('h2#Live State Dump');
721
739
  * dump(state);
722
740
  *
723
741
  * // Change state later, the dump in the DOM will update
@@ -725,4 +743,3 @@ export declare function partition<IN_K extends string | number | symbol, OUT_K e
725
743
  * ```
726
744
  */
727
745
  export declare function dump<T>(data: T): T;
728
- export {};