aberdeen 1.0.11 → 1.0.13
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 +1 -1
- package/dist/aberdeen.d.ts +38 -17
- package/dist/aberdeen.js +244 -34
- package/dist/aberdeen.js.map +3 -3
- package/dist/prediction.d.ts +2 -2
- package/dist/prediction.js.map +1 -1
- package/dist/route.js +2 -2
- package/dist/route.js.map +3 -3
- package/dist-min/aberdeen.js +5 -5
- package/dist-min/aberdeen.js.map +3 -3
- package/dist-min/prediction.js.map +1 -1
- package/dist-min/route.js +2 -2
- package/dist-min/route.js.map +3 -3
- package/package.json +2 -2
- package/src/aberdeen.ts +363 -99
- package/src/prediction.ts +4 -4
- package/src/route.ts +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Aberdeen's approach is refreshingly simple:
|
|
|
11
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
12
|
- ⏩ **Fast:** No virtual DOM. Aberdeen intelligently updates only the minimal, necessary parts of your UI when proxied data changes.
|
|
13
13
|
- 👥 **Awesome lists**: It's very easy and performant to reactively display data sorted by whatever you like.
|
|
14
|
-
- 🔬 **Tiny:** Around
|
|
14
|
+
- 🔬 **Tiny:** Around 6KB (minimized and gzipped) and with zero runtime dependencies.
|
|
15
15
|
- 🔋 **Batteries included**: Comes with client-side 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
16
|
|
|
17
17
|
## Why *not* use Aberdeen?
|
package/dist/aberdeen.d.ts
CHANGED
|
@@ -30,14 +30,6 @@
|
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
32
|
export declare function runQueue(): void;
|
|
33
|
-
/**
|
|
34
|
-
* A sort key, as used by {@link onEach}, is a value that determines the order of items. It can
|
|
35
|
-
* be a number, string, or an array of numbers/strings. The sort key is used to sort items
|
|
36
|
-
* based on their values. The sort key can also be `undefined`, which indicates that the item
|
|
37
|
-
* should be ignored.
|
|
38
|
-
* @private
|
|
39
|
-
*/
|
|
40
|
-
export type SortKeyType = number | string | Array<number | string> | undefined;
|
|
41
33
|
/**
|
|
42
34
|
* Creates a new string that has the opposite sort order compared to the input string.
|
|
43
35
|
*
|
|
@@ -66,7 +58,7 @@ export type SortKeyType = number | string | Array<number | string> | undefined;
|
|
|
66
58
|
* @see {@link onEach} for usage with sorting.
|
|
67
59
|
*/
|
|
68
60
|
export declare function invertString(input: string): string;
|
|
69
|
-
|
|
61
|
+
export declare function onEach<K, T>(target: Map<K, undefined | T>, render: (value: T, key: K) => void, makeKey?: (value: T, key: K) => SortKeyType): void;
|
|
70
62
|
export declare function onEach<T>(target: ReadonlyArray<undefined | T>, render: (value: T, index: number) => void, makeKey?: (value: T, index: number) => SortKeyType): void;
|
|
71
63
|
export declare function onEach<K extends string | number | symbol, T>(target: Record<K, undefined | T>, render: (value: T, index: KeyToString<K>) => void, makeKey?: (value: T, index: KeyToString<K>) => SortKeyType): void;
|
|
72
64
|
/**
|
|
@@ -133,9 +125,9 @@ export interface ValueRef<T> {
|
|
|
133
125
|
* ```
|
|
134
126
|
*/
|
|
135
127
|
export declare function count(proxied: TargetType): ValueRef<number>;
|
|
136
|
-
export declare function proxy<T extends
|
|
128
|
+
export declare function proxy<T extends any>(target: Array<T>): Array<T extends number ? number : T extends string ? string : T extends boolean ? boolean : T>;
|
|
137
129
|
export declare function proxy<T extends object>(target: T): T;
|
|
138
|
-
export declare function proxy<T extends
|
|
130
|
+
export declare function proxy<T extends any>(target: T): ValueRef<T extends number ? number : T extends string ? string : T extends boolean ? boolean : T>;
|
|
139
131
|
/**
|
|
140
132
|
* Returns the original, underlying data target from a reactive proxy created by {@link proxy}.
|
|
141
133
|
* If the input `target` is not a proxy, it is returned directly.
|
|
@@ -180,14 +172,17 @@ export declare function unproxy<T>(target: T): T;
|
|
|
180
172
|
* will recursively copy properties into the existing `dst` object instead of replacing it.
|
|
181
173
|
* This minimizes change notifications for reactive updates.
|
|
182
174
|
* - **Handles Proxies:** Can accept proxied or unproxied objects/arrays for both `dst` and `src`.
|
|
175
|
+
* - **Cross-Type Copying:** Supports copying between Maps and objects. When copying from an object
|
|
176
|
+
* to a Map, object properties become Map entries. When copying from a Map to an object, Map entries
|
|
177
|
+
* become object properties (only for Maps with string/number/symbol keys).
|
|
183
178
|
*
|
|
184
|
-
* @param dst - The destination object/array (proxied or unproxied).
|
|
185
|
-
* @param src - The source object/array (proxied or unproxied). It won't be modified.
|
|
179
|
+
* @param dst - The destination object/array/Map (proxied or unproxied).
|
|
180
|
+
* @param src - The source object/array/Map (proxied or unproxied). It won't be modified.
|
|
186
181
|
* @param flags - Bitmask controlling copy behavior:
|
|
187
182
|
* - {@link MERGE}: Performs a partial update. Properties in `dst` not present in `src` are kept.
|
|
188
183
|
* `null`/`undefined` in `src` delete properties in `dst`. Handles partial array updates via object keys.
|
|
189
184
|
* - {@link SHALLOW}: Performs a shallow copy; when an array/object of the right type doesn't exist in `dst` yet, a reference to the array/object in `src` will be made, instead of creating a copy. If the array/object already exists, it won't be replaced (by a reference), but all items will be individually checked and copied like normal, keeping changes (and therefore UI updates) to a minimum.
|
|
190
|
-
* @template T - The type of the
|
|
185
|
+
* @template T - The type of the destination object.
|
|
191
186
|
* @throws Error if attempting to copy an array into a non-array or vice versa (unless {@link MERGE} is set, allowing for sparse array updates).
|
|
192
187
|
*
|
|
193
188
|
* @example Basic Copy
|
|
@@ -198,6 +193,22 @@ export declare function unproxy<T>(target: T): T;
|
|
|
198
193
|
* console.log(dest); // proxy({ a: 1, b: { c: 2 } })
|
|
199
194
|
* ```
|
|
200
195
|
*
|
|
196
|
+
* @example Map to Object
|
|
197
|
+
* ```typescript
|
|
198
|
+
* const source = new Map([['x', 3], ['y', 4]]);
|
|
199
|
+
* const dest = proxy({});
|
|
200
|
+
* copy(dest, source);
|
|
201
|
+
* console.log(dest); // proxy({ x: 3, y: 4 })
|
|
202
|
+
* ```
|
|
203
|
+
*
|
|
204
|
+
* @example Object to Map
|
|
205
|
+
* ```typescript
|
|
206
|
+
* const source = { x: 3, y: 4 };
|
|
207
|
+
* const dest = proxy(new Map());
|
|
208
|
+
* copy(dest, source);
|
|
209
|
+
* console.log(dest); // proxy(Map([['x', 3], ['y', 4]]))
|
|
210
|
+
* ```
|
|
211
|
+
*
|
|
201
212
|
* @example MERGE
|
|
202
213
|
* ```typescript
|
|
203
214
|
* const source = { b: { c: 99 }, d: undefined }; // d: undefined will delete
|
|
@@ -223,6 +234,9 @@ export declare function unproxy<T>(target: T): T;
|
|
|
223
234
|
* console.log(source.nested); // [1, 2, 3] (source was modified)
|
|
224
235
|
* ```
|
|
225
236
|
*/
|
|
237
|
+
export declare function copy<K, V>(dst: Map<K, V>, src: Record<K extends string | number | symbol ? K : never, V> | Partial<Record<K extends string | number | symbol ? K : never, V>>, flags?: number): void;
|
|
238
|
+
export declare function copy<K, V>(dst: Map<K, V>, src: Map<K, V> | Partial<Map<K, V>>, flags?: number): void;
|
|
239
|
+
export declare function copy<T extends Record<string | number | symbol, any>>(dst: T, src: Map<keyof T, T[keyof T]>, flags?: number): void;
|
|
226
240
|
export declare function copy<T extends object>(dst: T, src: Partial<T>, flags?: number): void;
|
|
227
241
|
/** Flag to {@link copy} causing it to use merge semantics. See {@link copy} for details. */
|
|
228
242
|
export declare const MERGE = 1;
|
|
@@ -685,22 +699,30 @@ export declare function unmountAll(): void;
|
|
|
685
699
|
*
|
|
686
700
|
*/
|
|
687
701
|
export declare function peek<T>(func: () => T): T;
|
|
702
|
+
/** When using a Map as `source`. */
|
|
703
|
+
export declare function map<K, IN, OUT>(source: Map<K, IN>, func: (value: IN, key: K) => undefined | OUT): Map<K, OUT>;
|
|
688
704
|
/** When using an object as `source`. */
|
|
689
705
|
export declare function map<IN, const IN_KEY extends string | number | symbol, OUT>(source: Record<IN_KEY, IN>, func: (value: IN, index: KeyToString<IN_KEY>) => undefined | OUT): Record<string | symbol, OUT>;
|
|
690
706
|
/** When using an array as `source`. */
|
|
691
707
|
export declare function map<IN, OUT>(source: Array<IN>, func: (value: IN, index: number) => undefined | OUT): Array<OUT>;
|
|
692
708
|
/** When using an array as `source`. */
|
|
693
709
|
export declare function multiMap<IN, OUT extends {
|
|
694
|
-
[key: string | symbol]:
|
|
710
|
+
[key: string | symbol]: any;
|
|
695
711
|
}>(source: Array<IN>, func: (value: IN, index: number) => OUT | undefined): OUT;
|
|
696
712
|
/** When using an object as `source`. */
|
|
697
713
|
export declare function multiMap<K extends string | number | symbol, IN, OUT extends {
|
|
698
|
-
[key: string | symbol]:
|
|
714
|
+
[key: string | symbol]: any;
|
|
699
715
|
}>(source: Record<K, IN>, func: (value: IN, index: KeyToString<K>) => OUT | undefined): OUT;
|
|
716
|
+
/** When using a Map as `source`. */
|
|
717
|
+
export declare function multiMap<K, IN, OUT extends {
|
|
718
|
+
[key: string | symbol]: any;
|
|
719
|
+
}>(source: Map<K, IN>, func: (value: IN, key: K) => OUT | undefined): OUT;
|
|
700
720
|
/** When using an object as `array`. */
|
|
701
721
|
export declare function partition<OUT_K extends string | number | symbol, IN_V>(source: IN_V[], func: (value: IN_V, key: number) => undefined | OUT_K | OUT_K[]): Record<OUT_K, Record<number, IN_V>>;
|
|
702
722
|
/** When using an object as `source`. */
|
|
703
723
|
export declare function partition<IN_K extends string | number | symbol, OUT_K extends string | number | symbol, IN_V>(source: Record<IN_K, IN_V>, func: (value: IN_V, key: IN_K) => undefined | OUT_K | OUT_K[]): Record<OUT_K, Record<IN_K, IN_V>>;
|
|
724
|
+
/** When using a Map as `source`. */
|
|
725
|
+
export declare function partition<IN_K extends string | number | symbol, OUT_K extends string | number | symbol, IN_V>(source: Map<IN_K, IN_V>, func: (value: IN_V, key: IN_K) => undefined | OUT_K | OUT_K[]): Record<OUT_K, Record<IN_K, IN_V>>;
|
|
704
726
|
/**
|
|
705
727
|
* Renders a live, recursive dump of a proxied data structure (or any value)
|
|
706
728
|
* into the DOM at the current {@link $} insertion point.
|
|
@@ -729,4 +751,3 @@ export declare function partition<IN_K extends string | number | symbol, OUT_K e
|
|
|
729
751
|
* ```
|
|
730
752
|
*/
|
|
731
753
|
export declare function dump<T>(data: T): T;
|
|
732
|
-
export {};
|
package/dist/aberdeen.js
CHANGED
|
@@ -388,8 +388,8 @@ class OnEachScope extends Scope {
|
|
|
388
388
|
}
|
|
389
389
|
}
|
|
390
390
|
} else {
|
|
391
|
-
for (const key
|
|
392
|
-
if (
|
|
391
|
+
for (const [key, value] of getEntries(target)) {
|
|
392
|
+
if (value !== undefined) {
|
|
393
393
|
new OnEachItemScope(this, key, false);
|
|
394
394
|
}
|
|
395
395
|
}
|
|
@@ -410,7 +410,13 @@ class OnEachScope extends Scope {
|
|
|
410
410
|
const oldScope = this.byIndex.get(index);
|
|
411
411
|
if (oldScope)
|
|
412
412
|
oldScope.remove();
|
|
413
|
-
|
|
413
|
+
let hasValue;
|
|
414
|
+
if (this.target instanceof Map) {
|
|
415
|
+
hasValue = this.target.has(index);
|
|
416
|
+
} else {
|
|
417
|
+
hasValue = this.target[index] !== undefined;
|
|
418
|
+
}
|
|
419
|
+
if (!hasValue) {
|
|
414
420
|
this.byIndex.delete(index);
|
|
415
421
|
} else {
|
|
416
422
|
new OnEachItemScope(this, index, true);
|
|
@@ -490,17 +496,25 @@ class OnEachItemScope extends ContentScope {
|
|
|
490
496
|
topRedrawScope = undefined;
|
|
491
497
|
}
|
|
492
498
|
redraw() {
|
|
493
|
-
|
|
499
|
+
let value;
|
|
500
|
+
const target = this.parent.target;
|
|
501
|
+
let itemIndex = this.itemIndex;
|
|
502
|
+
if (target instanceof Map) {
|
|
503
|
+
value = optProxy(target.get(itemIndex));
|
|
504
|
+
itemIndex = optProxy(itemIndex);
|
|
505
|
+
} else {
|
|
506
|
+
value = optProxy(target[itemIndex]);
|
|
507
|
+
}
|
|
494
508
|
const savedScope = currentScope;
|
|
495
509
|
currentScope = this;
|
|
496
510
|
let sortKey;
|
|
497
511
|
try {
|
|
498
512
|
if (this.parent.makeSortKey) {
|
|
499
|
-
const rawSortKey = this.parent.makeSortKey(value,
|
|
513
|
+
const rawSortKey = this.parent.makeSortKey(value, itemIndex);
|
|
500
514
|
if (rawSortKey != null)
|
|
501
515
|
sortKey = rawSortKey instanceof Array ? rawSortKey.map(partToStr).join("") : rawSortKey;
|
|
502
516
|
} else {
|
|
503
|
-
sortKey =
|
|
517
|
+
sortKey = itemIndex;
|
|
504
518
|
}
|
|
505
519
|
if (typeof sortKey === "number")
|
|
506
520
|
sortKey = partToStr(sortKey);
|
|
@@ -509,7 +523,7 @@ class OnEachItemScope extends ContentScope {
|
|
|
509
523
|
this.sortKey = sortKey;
|
|
510
524
|
}
|
|
511
525
|
if (sortKey != null)
|
|
512
|
-
this.parent.renderer(value,
|
|
526
|
+
this.parent.renderer(value, itemIndex);
|
|
513
527
|
} catch (e) {
|
|
514
528
|
handleError(e, sortKey != null);
|
|
515
529
|
}
|
|
@@ -541,6 +555,7 @@ var ROOT_SCOPE = new RootScope;
|
|
|
541
555
|
var currentScope = ROOT_SCOPE;
|
|
542
556
|
var ANY_SYMBOL = Symbol("any");
|
|
543
557
|
var TARGET_SYMBOL = Symbol("target");
|
|
558
|
+
var MAP_SIZE_SYMBOL = Symbol("mapSize");
|
|
544
559
|
var subscribers = new WeakMap;
|
|
545
560
|
var peeking = 0;
|
|
546
561
|
function subscribe(target, index, observer = currentScope) {
|
|
@@ -586,6 +601,13 @@ function isEmpty(proxied) {
|
|
|
586
601
|
});
|
|
587
602
|
return !target.length;
|
|
588
603
|
}
|
|
604
|
+
if (target instanceof Map) {
|
|
605
|
+
subscribe(target, MAP_SIZE_SYMBOL, (index, newData, oldData) => {
|
|
606
|
+
if (!newData !== !oldData)
|
|
607
|
+
queue(scope);
|
|
608
|
+
});
|
|
609
|
+
return !target.size;
|
|
610
|
+
}
|
|
589
611
|
const result = isObjEmpty(target);
|
|
590
612
|
subscribe(target, ANY_SYMBOL, (index, newData, oldData) => {
|
|
591
613
|
if (result ? oldData === undefined : newData === undefined)
|
|
@@ -596,6 +618,8 @@ function isEmpty(proxied) {
|
|
|
596
618
|
function count(proxied) {
|
|
597
619
|
if (proxied instanceof Array)
|
|
598
620
|
return ref(proxied, "length");
|
|
621
|
+
if (proxied instanceof Map)
|
|
622
|
+
return ref(proxied, "size");
|
|
599
623
|
const target = proxied[TARGET_SYMBOL] || proxied;
|
|
600
624
|
let cnt = 0;
|
|
601
625
|
for (const k in target)
|
|
@@ -707,6 +731,129 @@ var arrayHandler = {
|
|
|
707
731
|
return arraySet(target, prop, undefined);
|
|
708
732
|
}
|
|
709
733
|
};
|
|
734
|
+
function wrapIteratorSingle(iterator) {
|
|
735
|
+
return {
|
|
736
|
+
[Symbol.iterator]() {
|
|
737
|
+
return this;
|
|
738
|
+
},
|
|
739
|
+
next() {
|
|
740
|
+
const result = iterator.next();
|
|
741
|
+
if (result.done)
|
|
742
|
+
return result;
|
|
743
|
+
return {
|
|
744
|
+
done: false,
|
|
745
|
+
value: optProxy(result.value)
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
function wrapIteratorPair(iterator) {
|
|
751
|
+
return {
|
|
752
|
+
[Symbol.iterator]() {
|
|
753
|
+
return this;
|
|
754
|
+
},
|
|
755
|
+
next() {
|
|
756
|
+
const result = iterator.next();
|
|
757
|
+
if (result.done)
|
|
758
|
+
return result;
|
|
759
|
+
return {
|
|
760
|
+
done: false,
|
|
761
|
+
value: [optProxy(result.value[0]), optProxy(result.value[1])]
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
var mapMethodHandlers = {
|
|
767
|
+
get(key) {
|
|
768
|
+
const target = this[TARGET_SYMBOL];
|
|
769
|
+
if (typeof key === "object" && key)
|
|
770
|
+
key = key[TARGET_SYMBOL] || key;
|
|
771
|
+
subscribe(target, key);
|
|
772
|
+
return optProxy(target.get(key));
|
|
773
|
+
},
|
|
774
|
+
set(key, newData) {
|
|
775
|
+
const target = this[TARGET_SYMBOL];
|
|
776
|
+
if (typeof key === "object" && key)
|
|
777
|
+
key = key[TARGET_SYMBOL] || key;
|
|
778
|
+
if (typeof newData === "object" && newData)
|
|
779
|
+
newData = newData[TARGET_SYMBOL] || newData;
|
|
780
|
+
const oldData = target.get(key);
|
|
781
|
+
if (newData !== oldData) {
|
|
782
|
+
const oldSize = target.size;
|
|
783
|
+
target.set(key, newData);
|
|
784
|
+
emit(target, key, newData, oldData);
|
|
785
|
+
emit(target, MAP_SIZE_SYMBOL, target.size, oldSize);
|
|
786
|
+
runImmediateQueue();
|
|
787
|
+
}
|
|
788
|
+
return this;
|
|
789
|
+
},
|
|
790
|
+
delete(key) {
|
|
791
|
+
const target = this[TARGET_SYMBOL];
|
|
792
|
+
if (typeof key === "object" && key)
|
|
793
|
+
key = key[TARGET_SYMBOL] || key;
|
|
794
|
+
const oldData = target.get(key);
|
|
795
|
+
const result = target.delete(key);
|
|
796
|
+
if (result) {
|
|
797
|
+
emit(target, key, undefined, oldData);
|
|
798
|
+
emit(target, MAP_SIZE_SYMBOL, target.size, target.size + 1);
|
|
799
|
+
runImmediateQueue();
|
|
800
|
+
}
|
|
801
|
+
return result;
|
|
802
|
+
},
|
|
803
|
+
clear() {
|
|
804
|
+
const target = this[TARGET_SYMBOL];
|
|
805
|
+
const oldSize = target.size;
|
|
806
|
+
for (const key of target.keys()) {
|
|
807
|
+
const oldData = target.get(key);
|
|
808
|
+
emit(target, key, undefined, oldData);
|
|
809
|
+
}
|
|
810
|
+
target.clear();
|
|
811
|
+
emit(target, MAP_SIZE_SYMBOL, 0, oldSize);
|
|
812
|
+
runImmediateQueue();
|
|
813
|
+
},
|
|
814
|
+
has(key) {
|
|
815
|
+
const target = this[TARGET_SYMBOL];
|
|
816
|
+
if (typeof key === "object" && key)
|
|
817
|
+
key = key[TARGET_SYMBOL] || key;
|
|
818
|
+
subscribe(target, key);
|
|
819
|
+
return target.has(key);
|
|
820
|
+
},
|
|
821
|
+
keys() {
|
|
822
|
+
const target = this[TARGET_SYMBOL];
|
|
823
|
+
subscribe(target, ANY_SYMBOL);
|
|
824
|
+
return wrapIteratorSingle(target.keys());
|
|
825
|
+
},
|
|
826
|
+
values() {
|
|
827
|
+
const target = this[TARGET_SYMBOL];
|
|
828
|
+
subscribe(target, ANY_SYMBOL);
|
|
829
|
+
return wrapIteratorSingle(target.values());
|
|
830
|
+
},
|
|
831
|
+
entries() {
|
|
832
|
+
const target = this[TARGET_SYMBOL];
|
|
833
|
+
subscribe(target, ANY_SYMBOL);
|
|
834
|
+
return wrapIteratorPair(target.entries());
|
|
835
|
+
},
|
|
836
|
+
[Symbol.iterator]() {
|
|
837
|
+
const target = this[TARGET_SYMBOL];
|
|
838
|
+
subscribe(target, ANY_SYMBOL);
|
|
839
|
+
return wrapIteratorPair(target[Symbol.iterator]());
|
|
840
|
+
}
|
|
841
|
+
};
|
|
842
|
+
var mapHandler = {
|
|
843
|
+
get(target, prop) {
|
|
844
|
+
if (prop === TARGET_SYMBOL)
|
|
845
|
+
return target;
|
|
846
|
+
if (prop in mapMethodHandlers) {
|
|
847
|
+
return mapMethodHandlers[prop];
|
|
848
|
+
}
|
|
849
|
+
if (prop === "size") {
|
|
850
|
+
subscribe(target, MAP_SIZE_SYMBOL);
|
|
851
|
+
return target.size;
|
|
852
|
+
}
|
|
853
|
+
subscribe(target, prop);
|
|
854
|
+
return optProxy(target[prop]);
|
|
855
|
+
}
|
|
856
|
+
};
|
|
710
857
|
var proxyMap = new WeakMap;
|
|
711
858
|
function optProxy(value) {
|
|
712
859
|
if (typeof value !== "object" || !value || value[TARGET_SYMBOL] !== undefined) {
|
|
@@ -715,7 +862,15 @@ function optProxy(value) {
|
|
|
715
862
|
let proxied = proxyMap.get(value);
|
|
716
863
|
if (proxied)
|
|
717
864
|
return proxied;
|
|
718
|
-
|
|
865
|
+
let handler;
|
|
866
|
+
if (value instanceof Array) {
|
|
867
|
+
handler = arrayHandler;
|
|
868
|
+
} else if (value instanceof Map) {
|
|
869
|
+
handler = mapHandler;
|
|
870
|
+
} else {
|
|
871
|
+
handler = objectHandler;
|
|
872
|
+
}
|
|
873
|
+
proxied = new Proxy(value, handler);
|
|
719
874
|
proxyMap.set(value, proxied);
|
|
720
875
|
return proxied;
|
|
721
876
|
}
|
|
@@ -740,10 +895,21 @@ var SHALLOW = 2;
|
|
|
740
895
|
var COPY_SUBSCRIBE = 32;
|
|
741
896
|
var COPY_EMIT = 64;
|
|
742
897
|
function clone(src, flags = 0) {
|
|
743
|
-
|
|
898
|
+
let dst;
|
|
899
|
+
if (src instanceof Map) {
|
|
900
|
+
dst = new Map;
|
|
901
|
+
} else {
|
|
902
|
+
dst = Object.create(Object.getPrototypeOf(src));
|
|
903
|
+
}
|
|
744
904
|
copyRecurse(dst, src, flags);
|
|
745
905
|
return dst;
|
|
746
906
|
}
|
|
907
|
+
function getEntries(subject) {
|
|
908
|
+
return subject instanceof Map ? subject.entries() : Object.entries(subject);
|
|
909
|
+
}
|
|
910
|
+
function getKeys(subject) {
|
|
911
|
+
return subject instanceof Map ? subject.keys() : Object.keys(subject);
|
|
912
|
+
}
|
|
747
913
|
function copyRecurse(dst, src, flags) {
|
|
748
914
|
let unproxied = dst[TARGET_SYMBOL];
|
|
749
915
|
if (unproxied) {
|
|
@@ -764,7 +930,7 @@ function copyRecurse(dst, src, flags) {
|
|
|
764
930
|
const dstLen = dst.length;
|
|
765
931
|
const srcLen = src.length;
|
|
766
932
|
for (let i = 0;i < srcLen; i++) {
|
|
767
|
-
copyValue(dst,
|
|
933
|
+
copyValue(dst, i, src[i], flags);
|
|
768
934
|
}
|
|
769
935
|
if (srcLen !== dstLen) {
|
|
770
936
|
if (flags & COPY_EMIT) {
|
|
@@ -780,25 +946,41 @@ function copyRecurse(dst, src, flags) {
|
|
|
780
946
|
}
|
|
781
947
|
}
|
|
782
948
|
} else {
|
|
783
|
-
for (const
|
|
784
|
-
copyValue(dst,
|
|
949
|
+
for (const [key, value] of getEntries(src)) {
|
|
950
|
+
copyValue(dst, key, value, flags);
|
|
785
951
|
}
|
|
786
952
|
if (!(flags & MERGE)) {
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
953
|
+
if (src instanceof Map) {
|
|
954
|
+
for (const key of getKeys(dst)) {
|
|
955
|
+
if (!src.has(key)) {
|
|
956
|
+
deleteKey(dst, key, flags);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
} else {
|
|
960
|
+
for (const key of getKeys(dst)) {
|
|
961
|
+
if (!(key in src)) {
|
|
962
|
+
deleteKey(dst, key, flags);
|
|
793
963
|
}
|
|
794
964
|
}
|
|
795
965
|
}
|
|
796
966
|
}
|
|
797
967
|
}
|
|
798
968
|
}
|
|
799
|
-
function
|
|
800
|
-
|
|
801
|
-
|
|
969
|
+
function deleteKey(dst, key, flags) {
|
|
970
|
+
let old;
|
|
971
|
+
if (dst instanceof Map) {
|
|
972
|
+
old = dst.get(key);
|
|
973
|
+
dst.delete(key);
|
|
974
|
+
} else {
|
|
975
|
+
old = dst[key];
|
|
976
|
+
delete dst[key];
|
|
977
|
+
}
|
|
978
|
+
if (flags & COPY_EMIT && old !== undefined) {
|
|
979
|
+
emit(dst, key, undefined, old);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
function copyValue(dst, index, srcValue, flags) {
|
|
983
|
+
const dstValue = dst instanceof Map ? dst.get(index) : dst[index];
|
|
802
984
|
if (srcValue !== dstValue) {
|
|
803
985
|
if (srcValue && dstValue && typeof srcValue === "object" && typeof dstValue === "object" && (srcValue.constructor === dstValue.constructor || flags & MERGE && dstValue instanceof Array)) {
|
|
804
986
|
copyRecurse(dstValue, srcValue, flags);
|
|
@@ -809,13 +991,19 @@ function copyValue(dst, src, index, flags) {
|
|
|
809
991
|
copyRecurse(copy2, srcValue, 0);
|
|
810
992
|
srcValue = copy2;
|
|
811
993
|
}
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
994
|
+
if (dst instanceof Map) {
|
|
995
|
+
if (flags & MERGE && srcValue == null)
|
|
996
|
+
dst.delete(index);
|
|
997
|
+
else
|
|
998
|
+
dst.set(index, srcValue);
|
|
999
|
+
} else {
|
|
1000
|
+
if (flags & MERGE && srcValue == null)
|
|
1001
|
+
delete dst[index];
|
|
1002
|
+
else
|
|
1003
|
+
dst[index] = srcValue;
|
|
1004
|
+
}
|
|
817
1005
|
if (flags & COPY_EMIT)
|
|
818
|
-
emit(dst, index, srcValue,
|
|
1006
|
+
emit(dst, index, srcValue, dstValue);
|
|
819
1007
|
}
|
|
820
1008
|
}
|
|
821
1009
|
var refHandler = {
|
|
@@ -1105,14 +1293,28 @@ function peek(func) {
|
|
|
1105
1293
|
}
|
|
1106
1294
|
}
|
|
1107
1295
|
function map(source, func) {
|
|
1108
|
-
|
|
1296
|
+
let out;
|
|
1297
|
+
if (source instanceof Array) {
|
|
1298
|
+
out = optProxy([]);
|
|
1299
|
+
} else if (source instanceof Map) {
|
|
1300
|
+
out = optProxy(new Map);
|
|
1301
|
+
} else {
|
|
1302
|
+
out = optProxy({});
|
|
1303
|
+
}
|
|
1109
1304
|
onEach(source, (item, key) => {
|
|
1110
1305
|
const value = func(item, key);
|
|
1111
1306
|
if (value !== undefined) {
|
|
1112
|
-
out
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1307
|
+
if (out instanceof Map) {
|
|
1308
|
+
out.set(key, value);
|
|
1309
|
+
clean(() => {
|
|
1310
|
+
out.delete(key);
|
|
1311
|
+
});
|
|
1312
|
+
} else {
|
|
1313
|
+
out[key] = value;
|
|
1314
|
+
clean(() => {
|
|
1315
|
+
delete out[key];
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1116
1318
|
}
|
|
1117
1319
|
});
|
|
1118
1320
|
return out;
|
|
@@ -1160,7 +1362,15 @@ function partition(source, func) {
|
|
|
1160
1362
|
}
|
|
1161
1363
|
function dump(data) {
|
|
1162
1364
|
if (data && typeof data === "object") {
|
|
1163
|
-
|
|
1365
|
+
let label;
|
|
1366
|
+
if (data instanceof Array) {
|
|
1367
|
+
label = "<array>";
|
|
1368
|
+
} else if (data instanceof Map) {
|
|
1369
|
+
label = "<Map>";
|
|
1370
|
+
} else {
|
|
1371
|
+
label = "<object>";
|
|
1372
|
+
}
|
|
1373
|
+
$({ text: label });
|
|
1164
1374
|
$("ul", () => {
|
|
1165
1375
|
onEach(data, (value, key) => {
|
|
1166
1376
|
$(`li:${JSON.stringify(key)}: `, () => {
|
|
@@ -1228,5 +1438,5 @@ export {
|
|
|
1228
1438
|
$
|
|
1229
1439
|
};
|
|
1230
1440
|
|
|
1231
|
-
//# debugId=
|
|
1441
|
+
//# debugId=8143A247906C19B564756E2164756E21
|
|
1232
1442
|
//# sourceMappingURL=aberdeen.js.map
|