aberdeen 1.11.1 → 1.12.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 +27 -26
- package/dist/src/aberdeen.d.ts +100 -86
- package/dist/src/aberdeen.js +5 -2
- package/dist/src/aberdeen.js.map +3 -3
- package/dist/src/aberdeen.min.js +4 -4
- package/dist/src/aberdeen.min.js.map +3 -3
- package/dist-docs/Tutorial/index.html +34 -29
- package/dist-docs/aberdeen/A/index.html +6 -6
- package/dist-docs/aberdeen/NO_COPY/index.html +2 -2
- package/dist-docs/aberdeen/PromiseProxy/index.html +5 -5
- package/dist-docs/aberdeen/clean/index.html +3 -3
- package/dist-docs/aberdeen/clone/index.html +2 -2
- package/dist-docs/aberdeen/copy/index.html +4 -4
- package/dist-docs/aberdeen/count/index.html +3 -3
- package/dist-docs/aberdeen/cssVars/index.html +2 -2
- package/dist-docs/aberdeen/darkMode/index.html +2 -2
- package/dist-docs/aberdeen/default/index.html +9 -8
- package/dist-docs/aberdeen/derive/index.html +4 -4
- package/dist-docs/aberdeen/disableCreateDestroy/index.html +2 -2
- package/dist-docs/aberdeen/dump/index.html +3 -3
- package/dist-docs/aberdeen/index.html +2 -2
- package/dist-docs/aberdeen/insertCss/index.html +2 -2
- package/dist-docs/aberdeen/insertGlobalCss/index.html +8 -2
- package/dist-docs/aberdeen/invertString/index.html +3 -3
- package/dist-docs/aberdeen/isEmpty/index.html +3 -3
- package/dist-docs/aberdeen/map/index.html +6 -6
- package/dist-docs/aberdeen/merge/index.html +5 -5
- package/dist-docs/aberdeen/mount/index.html +3 -3
- package/dist-docs/aberdeen/multiMap/index.html +5 -5
- package/dist-docs/aberdeen/onEach/index.html +6 -6
- package/dist-docs/aberdeen/partition/index.html +6 -6
- package/dist-docs/aberdeen/peek/index.html +9 -9
- package/dist-docs/aberdeen/proxy/index.html +9 -8
- package/dist-docs/aberdeen/ref/index.html +3 -3
- package/dist-docs/aberdeen/runQueue/index.html +3 -3
- package/dist-docs/aberdeen/setErrorHandler/index.html +2 -2
- package/dist-docs/aberdeen/setSpacingCssVars/index.html +2 -2
- package/dist-docs/aberdeen/unmountAll/index.html +2 -2
- package/dist-docs/aberdeen/unproxy/index.html +3 -3
- package/dist-docs/assets/aberdeen/aberdeen.d.ts +100 -86
- package/dist-docs/assets/aberdeen/aberdeen.js +5 -2
- package/dist-docs/assets/aberdeen/aberdeen.js.map +3 -3
- package/dist-docs/assets/aberdeen/aberdeen.min.js +4 -4
- package/dist-docs/assets/aberdeen/aberdeen.min.js.map +3 -3
- package/dist-docs/assets/search.js +1 -1
- package/dist-docs/dispatcher/Dispatcher/index.html +4 -4
- package/dist-docs/dispatcher/MATCH_FAILED/index.html +2 -2
- package/dist-docs/dispatcher/MATCH_REST/index.html +2 -2
- package/dist-docs/dispatcher/index.html +2 -2
- package/dist-docs/hierarchy.html +1 -1
- package/dist-docs/index.html +4 -4
- package/dist-docs/media/CHANGELOG.md +12 -0
- package/dist-docs/modules.html +1 -1
- package/dist-docs/prediction/applyCanon/index.html +2 -2
- package/dist-docs/prediction/applyPrediction/index.html +2 -2
- package/dist-docs/prediction/index.html +2 -2
- package/dist-docs/route/Route/index.html +9 -9
- package/dist-docs/route/back/index.html +2 -2
- package/dist-docs/route/current/index.html +2 -2
- package/dist-docs/route/go/index.html +2 -2
- package/dist-docs/route/index.html +2 -2
- package/dist-docs/route/interceptLinks/index.html +2 -2
- package/dist-docs/route/persistScroll/index.html +2 -2
- package/dist-docs/route/push/index.html +2 -2
- package/dist-docs/route/setLog/index.html +2 -2
- package/dist-docs/route/up/index.html +2 -2
- package/dist-docs/sitemap.xml +56 -56
- package/dist-docs/transitions/grow/index.html +2 -2
- package/dist-docs/transitions/index.html +2 -2
- package/dist-docs/transitions/shrink/index.html +2 -2
- package/package.json +1 -1
- package/skill/SKILL.md +162 -137
- package/skill/aberdeen.md +339 -311
- package/skill/dispatcher.md +6 -6
- package/skill/prediction.md +3 -3
- package/skill/route.md +17 -17
- package/skill/transitions.md +3 -3
- package/src/aberdeen.ts +163 -146
package/README.md
CHANGED
|
@@ -33,21 +33,22 @@ First, let's start with the obligatory reactive counter example. If you're readi
|
|
|
33
33
|
import A from 'aberdeen';
|
|
34
34
|
|
|
35
35
|
// Define some state as a proxied (observable) object
|
|
36
|
-
|
|
36
|
+
// The '$' prefix is just a convention to make reactive objects stand out
|
|
37
|
+
const $state = A.proxy({question: "How many roads must a man walk down?", answer: 42});
|
|
37
38
|
|
|
38
39
|
A('h3', () => {
|
|
39
40
|
// This function reruns whenever the question or the answer changes
|
|
40
|
-
A('text=', `${state.question} ↪ ${state.answer || 'Blowing in the wind'}`)
|
|
41
|
+
A('text=', `${$state.question} ↪ ${$state.answer || 'Blowing in the wind'}`)
|
|
41
42
|
});
|
|
42
43
|
|
|
43
|
-
// Two-way bind state.question to an <input>
|
|
44
|
-
A('input placeholder=Question bind=', A.ref(state, 'question'))
|
|
44
|
+
// Two-way bind $state.question to an <input>
|
|
45
|
+
A('input placeholder=Question bind=', A.ref($state, 'question'))
|
|
45
46
|
|
|
46
|
-
// Allow state.answer to be modified using both an <input> and buttons
|
|
47
|
+
// Allow $state.answer to be modified using both an <input> and buttons
|
|
47
48
|
A('div.row margin-top:1em', () => {
|
|
48
|
-
A('button text=- click=', () => state.answer--);
|
|
49
|
-
A('input type=number bind=', A.ref(state, 'answer'))
|
|
50
|
-
A('button text=+ click=', () => state.answer++);
|
|
49
|
+
A('button text=- click=', () => $state.answer--);
|
|
50
|
+
A('input type=number bind=', A.ref($state, 'answer'))
|
|
51
|
+
A('button text=+ click=', () => $state.answer++);
|
|
51
52
|
});
|
|
52
53
|
```
|
|
53
54
|
|
|
@@ -75,64 +76,64 @@ class TodoItem {
|
|
|
75
76
|
// The top-level user interface.
|
|
76
77
|
function drawMain() {
|
|
77
78
|
// Add some initial items. We'll wrap a A.proxy() around it!
|
|
78
|
-
let items: TodoItem[] = A.proxy([
|
|
79
|
+
let $items: TodoItem[] = A.proxy([
|
|
79
80
|
new TodoItem('Make todo-list demo', true),
|
|
80
81
|
new TodoItem('Learn Aberdeen', false),
|
|
81
82
|
]);
|
|
82
83
|
|
|
83
84
|
// Draw the list, ordered by label.
|
|
84
|
-
A.onEach(items, drawItem, item => item.label);
|
|
85
|
+
A.onEach($items, drawItem, $item => $item.label);
|
|
85
86
|
|
|
86
87
|
// Add item and delete checked buttons.
|
|
87
88
|
A('div.row', () => {
|
|
88
|
-
A('button text=+ click=', () => items.push(new TodoItem("")));
|
|
89
|
+
A('button text=+ click=', () => $items.push(new TodoItem("")));
|
|
89
90
|
A('button.outline text="Delete checked" click=', () => {
|
|
90
|
-
for(let idx in items) {
|
|
91
|
-
if (items[idx].done) delete items[idx];
|
|
91
|
+
for(let idx in $items) {
|
|
92
|
+
if ($items[idx].done) delete $items[idx];
|
|
92
93
|
}
|
|
93
94
|
});
|
|
94
95
|
});
|
|
95
96
|
};
|
|
96
97
|
|
|
97
98
|
// Called for each todo list item.
|
|
98
|
-
function drawItem(item) {
|
|
99
|
+
function drawItem($item) {
|
|
99
100
|
// Items without a label open in editing state.
|
|
100
101
|
// Note that we're creating this A.proxy outside the `div.row` scope
|
|
101
102
|
// create below, so that it will persist when that state reruns.
|
|
102
|
-
let editing: {value: boolean} = A.proxy(item.label == '');
|
|
103
|
+
let $editing: {value: boolean} = A.proxy($item.label == '');
|
|
103
104
|
|
|
104
105
|
A('div.row', todoItemStyle, 'create=', grow, 'destroy=', shrink, () => {
|
|
105
106
|
// Conditionally add a class to `div.row`, based on item.done
|
|
106
|
-
A({".done": A.ref(item,'done')});
|
|
107
|
+
A({".done": A.ref($item,'done')});
|
|
107
108
|
|
|
108
109
|
// The checkmark is hidden using CSS
|
|
109
110
|
A('div.checkmark text=✅');
|
|
110
111
|
|
|
111
|
-
if (editing.value) {
|
|
112
|
+
if ($editing.value) {
|
|
112
113
|
// Proxied string to hold label while being edited.
|
|
113
|
-
const labelCopy = A.proxy(item.label);
|
|
114
|
+
const $labelCopy = A.proxy($item.label);
|
|
114
115
|
function save() {
|
|
115
|
-
editing.value = false;
|
|
116
|
-
item.label = labelCopy.value;
|
|
116
|
+
$editing.value = false;
|
|
117
|
+
$item.label = $labelCopy.value;
|
|
117
118
|
}
|
|
118
119
|
// Label <input>. Save using enter or button.
|
|
119
|
-
A('input placeholder=Label bind=', labelCopy, 'keydown=', e => e.key==='Enter' && save());
|
|
120
|
-
A('button.outline text=Cancel click=', () => editing.value = false);
|
|
120
|
+
A('input placeholder=Label bind=', $labelCopy, 'keydown=', e => e.key==='Enter' && save());
|
|
121
|
+
A('button.outline text=Cancel click=', () => $editing.value = false);
|
|
121
122
|
A('button text=Save click=', save);
|
|
122
123
|
} else {
|
|
123
124
|
// Label as text.
|
|
124
|
-
A('p text=', item.label);
|
|
125
|
+
A('p text=', $item.label);
|
|
125
126
|
|
|
126
127
|
// Edit icon, if not done.
|
|
127
|
-
if (
|
|
128
|
+
if (!$item.done) {
|
|
128
129
|
A('a text=Edit click=', e => {
|
|
129
|
-
editing.value = true;
|
|
130
|
+
$editing.value = true;
|
|
130
131
|
e.stopPropagation(); // We don't want to toggle as well.
|
|
131
132
|
});
|
|
132
133
|
}
|
|
133
134
|
|
|
134
135
|
// Clicking a row toggles done.
|
|
135
|
-
A('cursor:pointer click=', () => item.done =
|
|
136
|
+
A('cursor:pointer click=', () => $item.done = !$item.done);
|
|
136
137
|
}
|
|
137
138
|
});
|
|
138
139
|
}
|
package/dist/src/aberdeen.d.ts
CHANGED
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
16
|
* ```typescript
|
|
17
|
-
* const data = A.proxy("before");
|
|
17
|
+
* const $data = A.proxy("before");
|
|
18
18
|
*
|
|
19
|
-
* A('#', data);
|
|
19
|
+
* A('#', $data);
|
|
20
20
|
* console.log(1, document.body.innerHTML); // before
|
|
21
21
|
*
|
|
22
22
|
* // Make an update that should cause the DOM to change.
|
|
23
|
-
* data.value = "after";
|
|
23
|
+
* $data.value = "after";
|
|
24
24
|
*
|
|
25
25
|
* // Normally, the DOM update would happen after a timeout.
|
|
26
26
|
* // But this causes an immediate update:
|
|
@@ -42,15 +42,15 @@ export declare function runQueue(): void;
|
|
|
42
42
|
*
|
|
43
43
|
* @example
|
|
44
44
|
* ```typescript
|
|
45
|
-
* const users = A.proxy([
|
|
45
|
+
* const $users = A.proxy([
|
|
46
46
|
* { id: 1, name: 'Charlie', score: 95 },
|
|
47
47
|
* { id: 2, name: 'Alice', score: 100 },
|
|
48
48
|
* { id: 3, name: 'Bob', score: 90 },
|
|
49
49
|
* ]);
|
|
50
50
|
*
|
|
51
|
-
* A.onEach(users, (user) => {
|
|
52
|
-
* A(`p#${user.name}: ${user.score}`);
|
|
53
|
-
* }, (user) => A.invertString(user.name)); // Reverse alphabetic order
|
|
51
|
+
* A.onEach($users, ($user) => {
|
|
52
|
+
* A(`p#${$user.name}: ${$user.score}`);
|
|
53
|
+
* }, ($user) => A.invertString($user.name)); // Reverse alphabetic order
|
|
54
54
|
* ```
|
|
55
55
|
*
|
|
56
56
|
* @param input The string whose sort order needs to be inverted.
|
|
@@ -78,21 +78,21 @@ export declare const EMPTY: unique symbol;
|
|
|
78
78
|
*
|
|
79
79
|
* @example
|
|
80
80
|
* ```typescript
|
|
81
|
-
* const items = A.proxy([]);
|
|
81
|
+
* const $items = A.proxy([]);
|
|
82
82
|
*
|
|
83
83
|
* // Reactively display a message if the items array is empty
|
|
84
84
|
* A('div', () => {
|
|
85
|
-
* if (A.isEmpty(items)) {
|
|
85
|
+
* if (A.isEmpty($items)) {
|
|
86
86
|
* A('p i#No items yet!');
|
|
87
87
|
* } else {
|
|
88
|
-
* A.onEach(items, item => A('p#'+item));
|
|
88
|
+
* A.onEach($items, item => A('p#'+item));
|
|
89
89
|
* }
|
|
90
90
|
* });
|
|
91
91
|
*
|
|
92
92
|
* // Adding an item will automatically remove the "No items yet!" message
|
|
93
93
|
* setInterval(() => {
|
|
94
|
-
* if (
|
|
95
|
-
* else items.length = 0;
|
|
94
|
+
* if (!$items.length || Math.random()>0.5) $items.push('Item');
|
|
95
|
+
* else $items.length = 0;
|
|
96
96
|
* }, 1000)
|
|
97
97
|
* ```
|
|
98
98
|
*/
|
|
@@ -109,19 +109,19 @@ export interface ValueRef<T> {
|
|
|
109
109
|
*
|
|
110
110
|
* @example
|
|
111
111
|
* ```typescript
|
|
112
|
-
* const items = A.proxy({x: 3, y: 7} as any);
|
|
113
|
-
* const
|
|
112
|
+
* const $items = A.proxy({x: 3, y: 7} as any);
|
|
113
|
+
* const $count = A.count($items);
|
|
114
114
|
*
|
|
115
115
|
* // Create a DOM text node for the count:
|
|
116
|
-
* A('div text=',
|
|
116
|
+
* A('div text=', $count);
|
|
117
117
|
* // <div>2</div>
|
|
118
118
|
|
|
119
119
|
* // Or we can use it in an {@link derive} function:
|
|
120
|
-
* A(() => console.log("The count is now",
|
|
120
|
+
* A(() => console.log("The count is now", $count.value));
|
|
121
121
|
* // The count is now 2
|
|
122
122
|
*
|
|
123
123
|
* // Adding/removing items will update the count
|
|
124
|
-
* items.z = 12;
|
|
124
|
+
* $items.z = 12;
|
|
125
125
|
* // Asynchronously, after 0ms:
|
|
126
126
|
* // <div>3</div>
|
|
127
127
|
* // The count is now 3
|
|
@@ -162,23 +162,23 @@ export declare function proxy<T extends any>(target: T): ValueRef<T extends numb
|
|
|
162
162
|
*
|
|
163
163
|
* @example
|
|
164
164
|
* ```typescript
|
|
165
|
-
* const
|
|
166
|
-
* const rawUser = A.unproxy(
|
|
165
|
+
* const $user = A.proxy({ name: 'Frank' });
|
|
166
|
+
* const rawUser = A.unproxy($user);
|
|
167
167
|
*
|
|
168
168
|
* // Log reactively
|
|
169
|
-
* A(() => console.log('proxied',
|
|
169
|
+
* A(() => console.log('proxied', $user.name));
|
|
170
170
|
* // The following will only ever log once, as we're not subscribing to any observable
|
|
171
171
|
* A(() => console.log('unproxied', rawUser.name));
|
|
172
172
|
*
|
|
173
173
|
* // This cause the first log to run again:
|
|
174
|
-
* setTimeout(() =>
|
|
174
|
+
* setTimeout(() => $user.name += '!', 1000);
|
|
175
175
|
*
|
|
176
176
|
* // This doesn't cause any new logs:
|
|
177
177
|
* setTimeout(() => rawUser.name += '?', 2000);
|
|
178
178
|
*
|
|
179
|
-
* // Both
|
|
179
|
+
* // Both $user and rawUser end up as `{name: 'Frank!?'}`
|
|
180
180
|
* setTimeout(() => {
|
|
181
|
-
* console.log('final proxied',
|
|
181
|
+
* console.log('final proxied', $user)
|
|
182
182
|
* console.log('final unproxied', rawUser)
|
|
183
183
|
* }, 3000);
|
|
184
184
|
* ```
|
|
@@ -203,12 +203,12 @@ export declare function unproxy<T>(target: T): T;
|
|
|
203
203
|
*
|
|
204
204
|
* @example Basic Copy
|
|
205
205
|
* ```typescript
|
|
206
|
-
* const source = A.proxy({ a: 1, b: { c: 2 } });
|
|
207
|
-
* const dest = A.proxy({ b: { d: 3 } });
|
|
208
|
-
* A.copy(dest, source);
|
|
209
|
-
* console.log(dest); // proxy({ a: 1, b: { c: 2 } })
|
|
210
|
-
* A.copy(dest, 'b', { e: 4 });
|
|
211
|
-
* console.log(dest); // proxy({ a: 1, b: { e: 4 } })
|
|
206
|
+
* const $source = A.proxy({ a: 1, b: { c: 2 } });
|
|
207
|
+
* const $dest = A.proxy({ b: { d: 3 } });
|
|
208
|
+
* A.copy($dest, $source);
|
|
209
|
+
* console.log($dest); // proxy({ a: 1, b: { c: 2 } })
|
|
210
|
+
* A.copy($dest, 'b', { e: 4 });
|
|
211
|
+
* console.log($dest); // proxy({ a: 1, b: { e: 4 } })
|
|
212
212
|
* ```
|
|
213
213
|
*/
|
|
214
214
|
export declare function copy<T extends object>(dst: T, src: T): boolean;
|
|
@@ -226,11 +226,11 @@ export declare function copy<T extends object>(dst: T, dstKey: keyof T, src: T[t
|
|
|
226
226
|
* @example Basic merge
|
|
227
227
|
* ```typescript
|
|
228
228
|
* const source = { b: { c: 99 }, d: undefined }; // d: undefined will delete
|
|
229
|
-
* const dest = A.proxy({ a: 1, b: { x: 5 }, d: 4 });
|
|
230
|
-
* A.merge(dest, source);
|
|
231
|
-
* A.merge(dest, 'b', { y: 6 }); // merge into dest.b
|
|
232
|
-
* A.merge(dest, 'c', { z: 7 }); //
|
|
233
|
-
* console.log(dest); // proxy({ a: 1, b: { c: 99, x: 5, y: 6 }, c: { z: 7 } })
|
|
229
|
+
* const $dest = A.proxy({ a: 1, b: { x: 5 }, d: 4 });
|
|
230
|
+
* A.merge($dest, source);
|
|
231
|
+
* A.merge($dest, 'b', { y: 6 }); // merge into $dest.b
|
|
232
|
+
* A.merge($dest, 'c', { z: 7 }); // $dest.c doesn't exist yet, so it will just be assigned
|
|
233
|
+
* console.log($dest); // proxy({ a: 1, b: { c: 99, x: 5, y: 6 }, c: { z: 7 } })
|
|
234
234
|
* ```
|
|
235
235
|
*
|
|
236
236
|
*/
|
|
@@ -349,16 +349,16 @@ export declare function clone<T extends object>(src: T): T;
|
|
|
349
349
|
*
|
|
350
350
|
* @example
|
|
351
351
|
* ```javascript
|
|
352
|
-
* const formData = A.proxy({ color: 'orange', velocity: 42 });
|
|
352
|
+
* const $formData = A.proxy({ color: 'orange', velocity: 42 });
|
|
353
353
|
*
|
|
354
354
|
* // Usage with `bind`
|
|
355
|
-
* A('input type=text bind=', A.ref(formData, 'color'));
|
|
355
|
+
* A('input type=text bind=', A.ref($formData, 'color'));
|
|
356
356
|
*
|
|
357
357
|
* // Usage as a dynamic property, causes a TextNode with just the name to be created and live-updated
|
|
358
|
-
* A('p text="Selected color: " text=', A.ref(formData, 'color'), 'color:', A.ref(formData, 'color'));
|
|
358
|
+
* A('p text="Selected color: " text=', A.ref($formData, 'color'), 'color:', A.ref($formData, 'color'));
|
|
359
359
|
*
|
|
360
|
-
* // Changes are actually stored in formData - this causes logs like `{color: "Blue", velocity 42}`
|
|
361
|
-
* A(() => console.log(formData))
|
|
360
|
+
* // Changes are actually stored in $formData - this causes logs like `{color: "Blue", velocity 42}`
|
|
361
|
+
* A(() => console.log($formData))
|
|
362
362
|
* ```
|
|
363
363
|
*/
|
|
364
364
|
export declare function ref<T extends TargetType, K extends keyof T>(target: T, index: K): ValueRef<T[K]>;
|
|
@@ -455,29 +455,29 @@ export declare function disableCreateDestroy(): void;
|
|
|
455
455
|
*
|
|
456
456
|
* @example Content Functions & Reactive Scope
|
|
457
457
|
* ```typescript
|
|
458
|
-
* const state = A.proxy({ count: 0 });
|
|
458
|
+
* const $state = A.proxy({ count: 0 });
|
|
459
459
|
* A('div', () => { // Outer element
|
|
460
|
-
* // This scope re-renders when state.count changes
|
|
461
|
-
* A(`p#Count is ${state.count}`);
|
|
462
|
-
* A('button text=Increment click=', () => state.count++);
|
|
460
|
+
* // This scope re-renders when $state.count changes
|
|
461
|
+
* A(`p#Count is ${$state.count}`);
|
|
462
|
+
* A('button text=Increment click=', () => $state.count++);
|
|
463
463
|
* });
|
|
464
464
|
* ```
|
|
465
465
|
*
|
|
466
466
|
* @example Two-way Binding
|
|
467
467
|
* ```typescript
|
|
468
|
-
* const user = A.proxy({ name: '' });
|
|
469
|
-
* A('input placeholder=Name bind=', A.ref(user, 'name'));
|
|
468
|
+
* const $user = A.proxy({ name: '' });
|
|
469
|
+
* A('input placeholder=Name bind=', A.ref($user, 'name'));
|
|
470
470
|
* A('h3', () => { // Reactive scope
|
|
471
|
-
* A(`#Hello ${user.name || 'stranger'}`);
|
|
471
|
+
* A(`#Hello ${$user.name || 'stranger'}`);
|
|
472
472
|
* });
|
|
473
473
|
* ```
|
|
474
474
|
*
|
|
475
475
|
* @example Conditional Rendering
|
|
476
476
|
* ```typescript
|
|
477
|
-
* const show = A.proxy(false);
|
|
478
|
-
* A('button click=', () => show.value =
|
|
477
|
+
* const $show = A.proxy(false);
|
|
478
|
+
* A('button click=', () => $show.value = !$show.value, () => A($show.value ? '#Hide' : '#Show'));
|
|
479
479
|
* A(() => { // Reactive scope
|
|
480
|
-
* if (show.value) {
|
|
480
|
+
* if ($show.value) {
|
|
481
481
|
* A('p#Details are visible!');
|
|
482
482
|
* }
|
|
483
483
|
* });
|
|
@@ -485,8 +485,8 @@ export declare function disableCreateDestroy(): void;
|
|
|
485
485
|
*
|
|
486
486
|
* @example Proxied objects as values
|
|
487
487
|
* ```typescript
|
|
488
|
-
* const myColor = A.proxy('red');
|
|
489
|
-
* A('p text="The color is " text=', myColor, 'click=', () => myColor.value = 'yellow')
|
|
488
|
+
* const $myColor = A.proxy('red');
|
|
489
|
+
* A('p text="The color is " text=', $myColor, 'click=', () => $myColor.value = 'yellow')
|
|
490
490
|
* // Clicking the text will cause it to change color without recreating the <p> itself
|
|
491
491
|
* ```
|
|
492
492
|
* This is often used together with {@link ref}, in order to use properties other than `.value`.
|
|
@@ -604,6 +604,20 @@ export declare function insertCss(style: string | object): string;
|
|
|
604
604
|
* }
|
|
605
605
|
* });
|
|
606
606
|
* ```
|
|
607
|
+
* At-rules such as `@media` and `@keyframes` should use nested objects. For keyframes,
|
|
608
|
+
* the step selectors (`0%`, `50%`, `100%`, etc.) become the nested keys and each value
|
|
609
|
+
* should be a concise CSS declaration string.
|
|
610
|
+
*
|
|
611
|
+
* @example Animation Keyframes
|
|
612
|
+
* ```typescript
|
|
613
|
+
* A.insertGlobalCss({
|
|
614
|
+
* "@keyframes connection-pulse": {
|
|
615
|
+
* "0%": "box-shadow: inset 0 0 0 0 rgba(255, 70, 70, 0.4);",
|
|
616
|
+
* "50%": "box-shadow: inset 0 0 0 6px rgba(255, 70, 70, 0.08);",
|
|
617
|
+
* "100%": "box-shadow: inset 0 0 0 0 rgba(255, 70, 70, 0.4);"
|
|
618
|
+
* }
|
|
619
|
+
* });
|
|
620
|
+
* ```
|
|
607
621
|
*/
|
|
608
622
|
export declare function insertGlobalCss(style: object): void;
|
|
609
623
|
/**
|
|
@@ -663,27 +677,27 @@ export declare function setErrorHandler(handler?: (error: Error) => boolean | un
|
|
|
663
677
|
*
|
|
664
678
|
* @example Maintaing a sum for a changing array
|
|
665
679
|
* ```typescript
|
|
666
|
-
* const
|
|
667
|
-
* let sum = A.proxy(0);
|
|
680
|
+
* const $numbers = A.proxy([3, 5, 10]);
|
|
681
|
+
* let $sum = A.proxy(0);
|
|
668
682
|
*
|
|
669
683
|
* // Show the array items and maintain the sum
|
|
670
|
-
* A.onEach(
|
|
684
|
+
* A.onEach($numbers, (item, index) => {
|
|
671
685
|
* A(`code#${index}→${item}`);
|
|
672
|
-
* // We'll update sum.value using peek, as += first does a read, but
|
|
686
|
+
* // We'll update $sum.value using peek, as += first does a read, but
|
|
673
687
|
* // we don't want to subscribe.
|
|
674
|
-
* A.peek(() => sum.value += item);
|
|
688
|
+
* A.peek(() => $sum.value += item);
|
|
675
689
|
* // Clean gets called before each rerun for a certain item index
|
|
676
690
|
* // No need for peek here, as the clean code doesn't run in an
|
|
677
691
|
* // observer scope.
|
|
678
|
-
* A.clean(() => sum.value -= item);
|
|
692
|
+
* A.clean(() => $sum.value -= item);
|
|
679
693
|
* })
|
|
680
694
|
*
|
|
681
695
|
* // Show the sum
|
|
682
|
-
* A('h1 text=', sum);
|
|
696
|
+
* A('h1 text=', $sum);
|
|
683
697
|
*
|
|
684
698
|
* // Make random changes to the array
|
|
685
699
|
* const rnd = () => 0|(Math.random()*20);
|
|
686
|
-
* setInterval(() =>
|
|
700
|
+
* setInterval(() => $numbers[rnd()] = rnd(), 1000);
|
|
687
701
|
* ```
|
|
688
702
|
*/
|
|
689
703
|
export declare function clean(cleaner: () => void): void;
|
|
@@ -701,20 +715,20 @@ export declare function clean(cleaner: () => void): void;
|
|
|
701
715
|
* observable returned by the `derive()` function.
|
|
702
716
|
* @returns An observable object, with its `value` property containing whatever the last run of `func` returned.
|
|
703
717
|
*
|
|
704
|
-
* @example Observation creating
|
|
718
|
+
* @example Observation creating UI components
|
|
705
719
|
* ```typescript
|
|
706
|
-
* const data = A.proxy({ user: 'Frank', notifications: 42 });
|
|
720
|
+
* const $data = A.proxy({ user: 'Frank', notifications: 42 });
|
|
707
721
|
*
|
|
708
722
|
* A('main', () => {
|
|
709
723
|
* console.log('Welcome');
|
|
710
|
-
* A('h3#Welcome, ' + data.user); // Reactive text
|
|
724
|
+
* A('h3#Welcome, ' + $data.user); // Reactive text
|
|
711
725
|
*
|
|
712
726
|
* A.derive(() => {
|
|
713
|
-
* // When data.notifications changes, only this inner scope reruns,
|
|
727
|
+
* // When $data.notifications changes, only this inner scope reruns,
|
|
714
728
|
* // leaving the `<p>Welcome, ..</p>` untouched.
|
|
715
729
|
* console.log('Notifications');
|
|
716
|
-
* A('code.notification-badge text=', data.notifications);
|
|
717
|
-
* A('a text=Notify! click=', () => data.notifications++);
|
|
730
|
+
* A('code.notification-badge text=', $data.notifications);
|
|
731
|
+
* A('a text=Notify! click=', () => $data.notifications++);
|
|
718
732
|
* });
|
|
719
733
|
* });
|
|
720
734
|
* ```
|
|
@@ -723,12 +737,12 @@ export declare function clean(cleaner: () => void): void;
|
|
|
723
737
|
*
|
|
724
738
|
* @example Observation with return value
|
|
725
739
|
* ```typescript
|
|
726
|
-
* const counter = A.proxy(0);
|
|
727
|
-
* setInterval(() => counter.value++, 1000);
|
|
728
|
-
* const double = A.derive(() => counter.value * 2);
|
|
740
|
+
* const $counter = A.proxy(0);
|
|
741
|
+
* setInterval(() => $counter.value++, 1000);
|
|
742
|
+
* const $double = A.derive(() => $counter.value * 2);
|
|
729
743
|
*
|
|
730
744
|
* A('h3', () => {
|
|
731
|
-
* A(`#counter=${counter.value} double=${double.value}`);
|
|
745
|
+
* A(`#counter=${$counter.value} double=${$double.value}`);
|
|
732
746
|
* })
|
|
733
747
|
* ```
|
|
734
748
|
*
|
|
@@ -761,16 +775,16 @@ export declare function derive<T>(func: () => T): ValueRef<T>;
|
|
|
761
775
|
*
|
|
762
776
|
* import A from 'aberdeen';
|
|
763
777
|
*
|
|
764
|
-
* const runTime = A.proxy(0);
|
|
765
|
-
* setInterval(() => runTime.value++, 1000);
|
|
778
|
+
* const $runTime = A.proxy(0);
|
|
779
|
+
* setInterval(() => $runTime.value++, 1000);
|
|
766
780
|
*
|
|
767
781
|
* A.mount(document.getElementById('app-root'), () => {
|
|
768
782
|
* A('h4#Aberdeen App');
|
|
769
|
-
* A(`p#Run time: ${runTime.value}s`);
|
|
783
|
+
* A(`p#Run time: ${$runTime.value}s`);
|
|
770
784
|
* // Conditionally render some content somewhere else in the static page
|
|
771
|
-
* if (runTime.value&1) {
|
|
785
|
+
* if ($runTime.value&1) {
|
|
772
786
|
* A.mount(document.getElementById('title-extra'), () =>
|
|
773
|
-
* A(`i#(${runTime.value}s)`)
|
|
787
|
+
* A(`i#(${$runTime.value}s)`)
|
|
774
788
|
* );
|
|
775
789
|
* }
|
|
776
790
|
* });
|
|
@@ -801,14 +815,14 @@ export declare function unmountAll(): void;
|
|
|
801
815
|
*
|
|
802
816
|
* @example Peeking within observer
|
|
803
817
|
* ```typescript
|
|
804
|
-
* const data = A.proxy({ a: 1, b: 2 });
|
|
818
|
+
* const $data = A.proxy({ a: 1, b: 2 });
|
|
805
819
|
* A(() => {
|
|
806
|
-
* // re-executes only when data.a changes, because data.b is peeked.
|
|
807
|
-
* const b = A.peek(() => data.b);
|
|
808
|
-
* console.log(`A is ${data.a}, B was ${b} when A changed.`);
|
|
820
|
+
* // re-executes only when $data.a changes, because $data.b is peeked.
|
|
821
|
+
* const b = A.peek(() => $data.b);
|
|
822
|
+
* console.log(`A is ${$data.a}, B was ${b} when A changed.`);
|
|
809
823
|
* });
|
|
810
|
-
* data.b = 3; // Does not trigger console.log
|
|
811
|
-
* data.a = 2; // Triggers console.log (logs "A is 2, B was 3 when A changed.")
|
|
824
|
+
* $data.b = 3; // Does not trigger console.log
|
|
825
|
+
* $data.a = 2; // Triggers console.log (logs "A is 2, B was 3 when A changed.")
|
|
812
826
|
* ```
|
|
813
827
|
*
|
|
814
828
|
*/
|
|
@@ -855,16 +869,16 @@ export declare function partition<IN_K extends string | number | symbol, OUT_K e
|
|
|
855
869
|
* ```typescript
|
|
856
870
|
* import A from 'aberdeen';
|
|
857
871
|
*
|
|
858
|
-
* const state = A.proxy({
|
|
872
|
+
* const $state = A.proxy({
|
|
859
873
|
* user: { name: 'Frank', kids: 1 },
|
|
860
874
|
* items: ['a', 'b']
|
|
861
875
|
* });
|
|
862
876
|
*
|
|
863
877
|
* A('h2#Live State Dump');
|
|
864
|
-
* A.dump(state);
|
|
878
|
+
* A.dump($state);
|
|
865
879
|
*
|
|
866
880
|
* // Change state later, the dump in the DOM will update
|
|
867
|
-
* setTimeout(() => { state.user.kids++; state.items.push('c'); }, 2000);
|
|
881
|
+
* setTimeout(() => { $state.user.kids++; $state.items.push('c'); }, 2000);
|
|
868
882
|
* ```
|
|
869
883
|
*/
|
|
870
884
|
export declare function dump<T>(data: T): T;
|
|
@@ -877,10 +891,10 @@ export declare function dump<T>(data: T): T;
|
|
|
877
891
|
* ```typescript
|
|
878
892
|
* import A from 'aberdeen';
|
|
879
893
|
*
|
|
880
|
-
* const state = A.proxy({ count: 0 });
|
|
894
|
+
* const $state = A.proxy({ count: 0 });
|
|
881
895
|
* A('div', () => {
|
|
882
|
-
* A(`p#Count: ${state.count}`);
|
|
883
|
-
* A('button text=+ click=', () => state.count++);
|
|
896
|
+
* A(`p#Count: ${$state.count}`);
|
|
897
|
+
* A('button text=+ click=', () => $state.count++);
|
|
884
898
|
* });
|
|
885
899
|
* ```
|
|
886
900
|
*/
|
package/dist/src/aberdeen.js
CHANGED
|
@@ -1533,6 +1533,7 @@ var KEBAB_SEGMENT = /-([a-z])/g;
|
|
|
1533
1533
|
function toCamel(p) {
|
|
1534
1534
|
return p.replace(KEBAB_SEGMENT, (_, l) => l.toUpperCase());
|
|
1535
1535
|
}
|
|
1536
|
+
var VALID_CSS_KEY = /^[a-zA-Z-]+$/;
|
|
1536
1537
|
function styleStringToCss(styleStr, selector) {
|
|
1537
1538
|
let props = "";
|
|
1538
1539
|
for (let pos = 0, len = styleStr.length;pos < len; ) {
|
|
@@ -1542,8 +1543,10 @@ function styleStringToCss(styleStr, selector) {
|
|
|
1542
1543
|
break;
|
|
1543
1544
|
const colon = styleStr.indexOf(":", pos);
|
|
1544
1545
|
if (colon === -1)
|
|
1545
|
-
|
|
1546
|
+
throw new Error(`Trailing data in style string: "${styleStr.substring(pos)}"`);
|
|
1546
1547
|
const key = styleStr.substring(pos, colon);
|
|
1548
|
+
if (!VALID_CSS_KEY.test(key))
|
|
1549
|
+
throw new Error(`Invalid CSS key: "${key}" in style string: "${styleStr}"`);
|
|
1547
1550
|
pos = colon + 1;
|
|
1548
1551
|
let val;
|
|
1549
1552
|
if (styleStr[pos] === " ") {
|
|
@@ -1868,5 +1871,5 @@ export {
|
|
|
1868
1871
|
A
|
|
1869
1872
|
};
|
|
1870
1873
|
|
|
1871
|
-
//# debugId=
|
|
1874
|
+
//# debugId=C25FF24CC098C9BC64756E2164756E21
|
|
1872
1875
|
//# sourceMappingURL=aberdeen.js.map
|