reactronic 0.94.25034 → 0.94.25036
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/build/dist/source/api.d.ts +2 -2
- package/build/dist/source/api.js +1 -1
- package/build/dist/source/core/MvccMergeList.d.ts +20 -20
- package/build/dist/source/core/MvccMergeList.js +14 -14
- package/build/dist/source/core/TreeNode.d.ts +8 -8
- package/build/dist/source/core/TreeNode.js +13 -13
- package/build/dist/source/util/ScriptedList.d.ts +64 -0
- package/build/dist/source/util/{MergeList.js → ScriptedList.js} +58 -58
- package/package.json +1 -1
- package/build/dist/source/util/MergeList.d.ts +0 -64
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { all, pause, proceedSyncOrAsync } from "./util/Utils.js";
|
|
2
2
|
export { Uri } from "./util/Uri.js";
|
|
3
|
-
export {
|
|
4
|
-
export type {
|
|
3
|
+
export { ScriptedList } from "./util/ScriptedList.js";
|
|
4
|
+
export type { LinkedItem, ScriptedListReader } from "./util/ScriptedList.js";
|
|
5
5
|
export { SealedArray } from "./util/SealedArray.js";
|
|
6
6
|
export { SealedMap } from "./util/SealedMap.js";
|
|
7
7
|
export { SealedSet } from "./util/SealedSet.js";
|
package/build/dist/source/api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { all, pause, proceedSyncOrAsync } from "./util/Utils.js";
|
|
2
2
|
export { Uri } from "./util/Uri.js";
|
|
3
|
-
export {
|
|
3
|
+
export { ScriptedList } from "./util/ScriptedList.js";
|
|
4
4
|
export { SealedArray } from "./util/SealedArray.js";
|
|
5
5
|
export { SealedMap } from "./util/SealedMap.js";
|
|
6
6
|
export { SealedSet } from "./util/SealedSet.js";
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ScriptedList, LinkedItem, ScriptedListReader } from "../util/ScriptedList.js";
|
|
2
2
|
import { ObservableObject } from "./Mvcc.js";
|
|
3
|
-
export declare abstract class
|
|
4
|
-
protected abstract impl:
|
|
3
|
+
export declare abstract class ObservableScriptedList<T> extends ObservableObject implements ScriptedListReader<T> {
|
|
4
|
+
protected abstract impl: ScriptedList<T>;
|
|
5
5
|
get isStrict(): boolean;
|
|
6
6
|
get count(): number;
|
|
7
|
-
get
|
|
8
|
-
get
|
|
9
|
-
get
|
|
10
|
-
lookup(key: string):
|
|
11
|
-
tryMergeAsExisting(key: string):
|
|
12
|
-
mergeAsAdded(instance: T):
|
|
13
|
-
mergeAsRemoved(item:
|
|
14
|
-
move(item:
|
|
7
|
+
get countOfAdded(): number;
|
|
8
|
+
get countOfRemoved(): number;
|
|
9
|
+
get isScriptingInProgress(): boolean;
|
|
10
|
+
lookup(key: string): LinkedItem<T> | undefined;
|
|
11
|
+
tryMergeAsExisting(key: string): LinkedItem<T> | undefined;
|
|
12
|
+
mergeAsAdded(instance: T): LinkedItem<T>;
|
|
13
|
+
mergeAsRemoved(item: LinkedItem<T>): void;
|
|
14
|
+
move(item: LinkedItem<T>, after: LinkedItem<T>): void;
|
|
15
15
|
beginMerge(): void;
|
|
16
16
|
endMerge(error?: unknown): void;
|
|
17
17
|
resetAddedAndRemovedLists(): void;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
items(): Generator<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
isAdded(item:
|
|
24
|
-
isMoved(item:
|
|
25
|
-
isRemoved(item:
|
|
26
|
-
|
|
18
|
+
firstItem(): LinkedItem<T> | undefined;
|
|
19
|
+
lastItem(): LinkedItem<T> | undefined;
|
|
20
|
+
items(): Generator<LinkedItem<T>>;
|
|
21
|
+
itemsAdded(reset?: boolean): Generator<LinkedItem<T>>;
|
|
22
|
+
itemsRemoved(reset?: boolean): Generator<LinkedItem<T>>;
|
|
23
|
+
isAdded(item: LinkedItem<T>): boolean;
|
|
24
|
+
isMoved(item: LinkedItem<T>): boolean;
|
|
25
|
+
isRemoved(item: LinkedItem<T>): boolean;
|
|
26
|
+
isAlive(item: LinkedItem<T>): boolean;
|
|
27
27
|
}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { ObservableObject } from "./Mvcc.js";
|
|
2
|
-
export class
|
|
2
|
+
export class ObservableScriptedList extends ObservableObject {
|
|
3
3
|
get isStrict() { return this.impl.isStrict; }
|
|
4
4
|
get count() { return this.impl.count; }
|
|
5
|
-
get
|
|
6
|
-
get
|
|
7
|
-
get
|
|
5
|
+
get countOfAdded() { return this.impl.countOfAdded; }
|
|
6
|
+
get countOfRemoved() { return this.impl.countOfRemoved; }
|
|
7
|
+
get isScriptingInProgress() { return this.impl.isScriptingInProgress; }
|
|
8
8
|
lookup(key) { return this.impl.lookup(key); }
|
|
9
|
-
tryMergeAsExisting(key) { return this.impl.
|
|
10
|
-
mergeAsAdded(instance) { return this.impl.
|
|
11
|
-
mergeAsRemoved(item) { return this.impl.
|
|
9
|
+
tryMergeAsExisting(key) { return this.impl.tryReuse(key); }
|
|
10
|
+
mergeAsAdded(instance) { return this.impl.add(instance); }
|
|
11
|
+
mergeAsRemoved(item) { return this.impl.remove(item); }
|
|
12
12
|
move(item, after) { this.impl.move(item, after); }
|
|
13
|
-
beginMerge() { this.impl.
|
|
14
|
-
endMerge(error) { this.impl.
|
|
13
|
+
beginMerge() { this.impl.beginScriptExecution(); }
|
|
14
|
+
endMerge(error) { this.impl.endScriptExecution(error); }
|
|
15
15
|
resetAddedAndRemovedLists() { this.impl.resetAddedAndRemovedLists(); }
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
firstItem() { return this.impl.firstItem(); }
|
|
17
|
+
lastItem() { return this.impl.lastItem(); }
|
|
18
18
|
items() { return this.impl.items(); }
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
itemsAdded(reset) { return this.impl.itemsAdded(reset); }
|
|
20
|
+
itemsRemoved(reset) { return this.impl.itemsRemoved(reset); }
|
|
21
21
|
isAdded(item) { return this.impl.isAdded(item); }
|
|
22
22
|
isMoved(item) { return this.impl.isMoved(item); }
|
|
23
23
|
isRemoved(item) { return this.impl.isRemoved(item); }
|
|
24
|
-
|
|
24
|
+
isAlive(item) { return this.impl.isAlive(item); }
|
|
25
25
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LoggingOptions } from "../Logging.js";
|
|
2
|
-
import {
|
|
2
|
+
import { ScriptedList, ScriptedListReader, LinkedItem } from "../util/ScriptedList.js";
|
|
3
3
|
import { Priority, Mode } from "../Enums.js";
|
|
4
4
|
import { ReactivityOptions } from "../Options.js";
|
|
5
5
|
import { ObservableObject } from "../core/Mvcc.js";
|
|
@@ -23,8 +23,8 @@ export declare abstract class ReactiveTreeNode<E = unknown> {
|
|
|
23
23
|
abstract readonly owner: ReactiveTreeNode;
|
|
24
24
|
abstract element: E;
|
|
25
25
|
abstract readonly host: ReactiveTreeNode;
|
|
26
|
-
abstract readonly children:
|
|
27
|
-
abstract readonly slot:
|
|
26
|
+
abstract readonly children: ScriptedListReader<ReactiveTreeNode>;
|
|
27
|
+
abstract readonly slot: LinkedItem<ReactiveTreeNode<E>> | undefined;
|
|
28
28
|
abstract readonly stamp: number;
|
|
29
29
|
abstract readonly outer: ReactiveTreeNode;
|
|
30
30
|
abstract readonly context: ReactiveTreeNodeContext | undefined;
|
|
@@ -67,7 +67,7 @@ export type ReactiveTreeNodeDriver<E = unknown> = {
|
|
|
67
67
|
runFinalization(node: ReactiveTreeNode<E>, isLeader: boolean): boolean;
|
|
68
68
|
runMount(node: ReactiveTreeNode<E>): void;
|
|
69
69
|
runScript(node: ReactiveTreeNode<E>): void | Promise<void>;
|
|
70
|
-
declareChild(ownerNode: ReactiveTreeNode<E>, childDriver: ReactiveTreeNodeDriver<any>, childDeclaration?: ReactiveTreeNodeDecl<any>, childBasis?: ReactiveTreeNodeDecl<any>):
|
|
70
|
+
declareChild(ownerNode: ReactiveTreeNode<E>, childDriver: ReactiveTreeNodeDriver<any>, childDeclaration?: ReactiveTreeNodeDecl<any>, childBasis?: ReactiveTreeNodeDecl<any>): LinkedItem<ReactiveTreeNode> | undefined;
|
|
71
71
|
provideHost(node: ReactiveTreeNode<E>): ReactiveTreeNode<E>;
|
|
72
72
|
};
|
|
73
73
|
export type ReactiveTreeNodeContext<T extends Object = Object> = {
|
|
@@ -83,7 +83,7 @@ export declare abstract class BaseDriver<E = unknown> implements ReactiveTreeNod
|
|
|
83
83
|
runFinalization(node: ReactiveTreeNode<E>, isLeader: boolean): boolean;
|
|
84
84
|
runMount(node: ReactiveTreeNode<E>): void;
|
|
85
85
|
runScript(node: ReactiveTreeNode<E>): void | Promise<void>;
|
|
86
|
-
declareChild(ownerNode: ReactiveTreeNode<E>, childDriver: ReactiveTreeNodeDriver<any>, childDeclaration?: ReactiveTreeNodeDecl<any>, childBasis?: ReactiveTreeNodeDecl<any>):
|
|
86
|
+
declareChild(ownerNode: ReactiveTreeNode<E>, childDriver: ReactiveTreeNodeDriver<any>, childDeclaration?: ReactiveTreeNodeDecl<any>, childBasis?: ReactiveTreeNodeDecl<any>): LinkedItem<ReactiveTreeNode> | undefined;
|
|
87
87
|
provideHost(node: ReactiveTreeNode<E>): ReactiveTreeNode<E>;
|
|
88
88
|
}
|
|
89
89
|
export declare class ReactiveTreeVariable<T extends Object = Object> {
|
|
@@ -112,8 +112,8 @@ declare class ReactiveTreeNodeImpl<E = unknown> extends ReactiveTreeNode<E> {
|
|
|
112
112
|
readonly owner: ReactiveTreeNodeImpl;
|
|
113
113
|
readonly element: E;
|
|
114
114
|
host: ReactiveTreeNodeImpl;
|
|
115
|
-
readonly children:
|
|
116
|
-
slot:
|
|
115
|
+
readonly children: ScriptedList<ReactiveTreeNodeImpl>;
|
|
116
|
+
slot: LinkedItem<ReactiveTreeNodeImpl<E>> | undefined;
|
|
117
117
|
stamp: number;
|
|
118
118
|
outer: ReactiveTreeNodeImpl;
|
|
119
119
|
context: ReactiveTreeNodeContextImpl<any> | undefined;
|
|
@@ -128,7 +128,7 @@ declare class ReactiveTreeNodeImpl<E = unknown> extends ReactiveTreeNode<E> {
|
|
|
128
128
|
has(mode: Mode): boolean;
|
|
129
129
|
script(_triggers: unknown): void;
|
|
130
130
|
configureReactivity(options: Partial<ReactivityOptions>): ReactivityOptions;
|
|
131
|
-
static get nodeSlot():
|
|
131
|
+
static get nodeSlot(): LinkedItem<ReactiveTreeNodeImpl>;
|
|
132
132
|
static tryUseTreeVariableValue<T extends Object>(variable: ReactiveTreeVariable<T>): T | undefined;
|
|
133
133
|
static useTreeVariableValue<T extends Object>(variable: ReactiveTreeVariable<T>): T;
|
|
134
134
|
static setTreeVariableValue<T extends Object>(variable: ReactiveTreeVariable<T>, value: T | undefined): void;
|
|
@@ -18,7 +18,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
18
18
|
};
|
|
19
19
|
import { misuse } from "../util/Dbg.js";
|
|
20
20
|
import { Uri } from "../util/Uri.js";
|
|
21
|
-
import {
|
|
21
|
+
import { ScriptedList } from "../util/ScriptedList.js";
|
|
22
22
|
import { emitLetters, flags, getCallerInfo, proceedSyncOrAsync } from "../util/Utils.js";
|
|
23
23
|
import { Priority, Mode, Isolation, Reentrance } from "../Enums.js";
|
|
24
24
|
import { ObservableObject } from "../core/Mvcc.js";
|
|
@@ -40,7 +40,7 @@ export function declare(driver, scriptOrDeclaration, scriptAsync, key, mode, pre
|
|
|
40
40
|
if (owner) {
|
|
41
41
|
let existing = owner.driver.declareChild(owner, driver, declaration, declaration.basis);
|
|
42
42
|
const children = owner.children;
|
|
43
|
-
existing !== null && existing !== void 0 ? existing : (existing = children.
|
|
43
|
+
existing !== null && existing !== void 0 ? existing : (existing = children.tryReuse(effectiveKey = effectiveKey || generateKey(owner), undefined, "nested elements can be declared inside 'script' only"));
|
|
44
44
|
if (existing) {
|
|
45
45
|
result = existing.instance;
|
|
46
46
|
if (result.driver !== driver && driver !== undefined)
|
|
@@ -52,12 +52,12 @@ export function declare(driver, scriptOrDeclaration, scriptAsync, key, mode, pre
|
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
54
|
result = new ReactiveTreeNodeImpl(effectiveKey || generateKey(owner), driver, declaration, owner);
|
|
55
|
-
result.slot = children.
|
|
55
|
+
result.slot = children.add(result);
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
else {
|
|
59
59
|
result = new ReactiveTreeNodeImpl(effectiveKey || generateKey(owner), driver, declaration, owner);
|
|
60
|
-
result.slot =
|
|
60
|
+
result.slot = ScriptedList.createItem(result);
|
|
61
61
|
}
|
|
62
62
|
return result;
|
|
63
63
|
}
|
|
@@ -89,7 +89,7 @@ export class ReactiveTreeNode {
|
|
|
89
89
|
}
|
|
90
90
|
static launchFinalization(node) {
|
|
91
91
|
const impl = node;
|
|
92
|
-
|
|
92
|
+
launchFinalizationViaSlot(impl.slot, true, true);
|
|
93
93
|
}
|
|
94
94
|
static launchNestedNodesThenDo(action) {
|
|
95
95
|
launchNestedNodesThenDoImpl(ReactiveTreeNodeImpl.nodeSlot, undefined, action);
|
|
@@ -270,7 +270,7 @@ class ReactiveTreeNodeImpl extends ReactiveTreeNode {
|
|
|
270
270
|
}
|
|
271
271
|
this.element = driver.create(this);
|
|
272
272
|
this.host = thisAsUnknown;
|
|
273
|
-
this.children = new
|
|
273
|
+
this.children = new ScriptedList(getNodeKey, true);
|
|
274
274
|
this.slot = undefined;
|
|
275
275
|
this.stamp = Number.MAX_SAFE_INTEGER;
|
|
276
276
|
this.context = undefined;
|
|
@@ -388,12 +388,12 @@ function launchNestedNodesThenDoImpl(nodeSlot, error, action) {
|
|
|
388
388
|
var _a;
|
|
389
389
|
const owner = nodeSlot.instance;
|
|
390
390
|
const children = owner.children;
|
|
391
|
-
if (children.
|
|
391
|
+
if (children.isScriptingInProgress) {
|
|
392
392
|
let promised = undefined;
|
|
393
393
|
try {
|
|
394
|
-
children.
|
|
395
|
-
for (const child of children.
|
|
396
|
-
|
|
394
|
+
children.endScriptExecution(error);
|
|
395
|
+
for (const child of children.itemsRemoved(true))
|
|
396
|
+
launchFinalizationViaSlot(child, true, true);
|
|
397
397
|
if (!error) {
|
|
398
398
|
const sequential = children.isStrict;
|
|
399
399
|
let p1 = undefined;
|
|
@@ -528,7 +528,7 @@ function runScriptNow(nodeSlot) {
|
|
|
528
528
|
try {
|
|
529
529
|
node.stamp++;
|
|
530
530
|
node.numerator = 0;
|
|
531
|
-
node.children.
|
|
531
|
+
node.children.beginScriptExecution();
|
|
532
532
|
const driver = node.driver;
|
|
533
533
|
result = driver.runScript(node);
|
|
534
534
|
result = proceedSyncOrAsync(result, v => { launchNestedNodesThenDoImpl(nodeSlot, undefined, NOP); return v; }, e => { console.log(e); launchNestedNodesThenDoImpl(nodeSlot, e !== null && e !== void 0 ? e : new Error("unknown error"), NOP); });
|
|
@@ -542,7 +542,7 @@ function runScriptNow(nodeSlot) {
|
|
|
542
542
|
});
|
|
543
543
|
}
|
|
544
544
|
}
|
|
545
|
-
function
|
|
545
|
+
function launchFinalizationViaSlot(nodeSlot, isLeader, individual) {
|
|
546
546
|
const node = nodeSlot.instance;
|
|
547
547
|
if (node.stamp >= 0) {
|
|
548
548
|
const driver = node.driver;
|
|
@@ -563,7 +563,7 @@ function launchFinalization(nodeSlot, isLeader, individual) {
|
|
|
563
563
|
});
|
|
564
564
|
}
|
|
565
565
|
for (const child of node.children.items())
|
|
566
|
-
|
|
566
|
+
launchFinalizationViaSlot(child, childrenAreLeaders, false);
|
|
567
567
|
ReactiveTreeNodeImpl.grandNodeCount--;
|
|
568
568
|
}
|
|
569
569
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export type GetListItemKey<T = unknown> = (item: T) => string | undefined;
|
|
2
|
+
export type ScriptedListReader<T> = {
|
|
3
|
+
readonly isStrict: boolean;
|
|
4
|
+
readonly count: number;
|
|
5
|
+
readonly countOfAdded: number;
|
|
6
|
+
readonly countOfRemoved: number;
|
|
7
|
+
readonly isScriptingInProgress: boolean;
|
|
8
|
+
lookup(key: string): LinkedItem<T> | undefined;
|
|
9
|
+
firstItem(): LinkedItem<T> | undefined;
|
|
10
|
+
lastItem(): LinkedItem<T> | undefined;
|
|
11
|
+
items(onlyAfter?: LinkedItem<T>): Generator<LinkedItem<T>>;
|
|
12
|
+
itemsAdded(reset?: boolean): Generator<LinkedItem<T>>;
|
|
13
|
+
itemsRemoved(reset?: boolean): Generator<LinkedItem<T>>;
|
|
14
|
+
isAdded(item: LinkedItem<T>): boolean;
|
|
15
|
+
isMoved(item: LinkedItem<T>): boolean;
|
|
16
|
+
isRemoved(item: LinkedItem<T>): boolean;
|
|
17
|
+
isAlive(item: LinkedItem<T>): boolean;
|
|
18
|
+
};
|
|
19
|
+
export type LinkedItem<T> = {
|
|
20
|
+
readonly instance: T;
|
|
21
|
+
readonly index: number;
|
|
22
|
+
readonly next?: LinkedItem<T>;
|
|
23
|
+
readonly prev?: LinkedItem<T>;
|
|
24
|
+
aux?: LinkedItem<T>;
|
|
25
|
+
};
|
|
26
|
+
export declare class ScriptedList<T> implements ScriptedListReader<T> {
|
|
27
|
+
readonly getKey: GetListItemKey<T>;
|
|
28
|
+
private strict;
|
|
29
|
+
private map;
|
|
30
|
+
private cycle;
|
|
31
|
+
private current;
|
|
32
|
+
private added;
|
|
33
|
+
private removed;
|
|
34
|
+
private lastNotFoundKey;
|
|
35
|
+
private strictNextItem?;
|
|
36
|
+
constructor(getKey: GetListItemKey<T>, strict?: boolean);
|
|
37
|
+
get isStrict(): boolean;
|
|
38
|
+
set isStrict(value: boolean);
|
|
39
|
+
get count(): number;
|
|
40
|
+
get countOfAdded(): number;
|
|
41
|
+
get countOfRemoved(): number;
|
|
42
|
+
get isScriptingInProgress(): boolean;
|
|
43
|
+
lookup(key: string | undefined): LinkedItem<T> | undefined;
|
|
44
|
+
tryReuse(key: string, resolution?: {
|
|
45
|
+
isDuplicate: boolean;
|
|
46
|
+
}, error?: string): LinkedItem<T> | undefined;
|
|
47
|
+
add(instance: T): LinkedItem<T>;
|
|
48
|
+
remove(item: LinkedItem<T>): void;
|
|
49
|
+
move(item: LinkedItem<T>, after: LinkedItem<T>): void;
|
|
50
|
+
beginScriptExecution(): void;
|
|
51
|
+
endScriptExecution(error?: unknown): void;
|
|
52
|
+
resetAddedAndRemovedLists(): void;
|
|
53
|
+
firstItem(): LinkedItem<T> | undefined;
|
|
54
|
+
lastItem(): LinkedItem<T> | undefined;
|
|
55
|
+
items(onlyAfter?: LinkedItem<T>): Generator<LinkedItem<T>>;
|
|
56
|
+
itemsAdded(reset?: boolean): Generator<LinkedItem<T>>;
|
|
57
|
+
itemsRemoved(reset?: boolean): Generator<LinkedItem<T>>;
|
|
58
|
+
isAdded(item: LinkedItem<T>): boolean;
|
|
59
|
+
isMoved(item: LinkedItem<T>): boolean;
|
|
60
|
+
isRemoved(item: LinkedItem<T>): boolean;
|
|
61
|
+
isAlive(item: LinkedItem<T>): boolean;
|
|
62
|
+
markAsMoved(item: LinkedItem<T>): void;
|
|
63
|
+
static createItem<T>(instance: T): LinkedItem<T>;
|
|
64
|
+
}
|
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
import { misuse } from "./Dbg.js";
|
|
2
|
-
export class
|
|
2
|
+
export class ScriptedList {
|
|
3
3
|
constructor(getKey, strict = false) {
|
|
4
4
|
this.getKey = getKey;
|
|
5
5
|
this.strict = strict;
|
|
6
6
|
this.map = new Map();
|
|
7
|
-
this.
|
|
8
|
-
this.current = new
|
|
9
|
-
this.added = new
|
|
10
|
-
this.removed = new
|
|
7
|
+
this.cycle = ~0;
|
|
8
|
+
this.current = new LinkedItemChain();
|
|
9
|
+
this.added = new LinkedItemChain();
|
|
10
|
+
this.removed = new LinkedItemChain();
|
|
11
11
|
this.lastNotFoundKey = undefined;
|
|
12
12
|
this.strictNextItem = undefined;
|
|
13
13
|
}
|
|
14
14
|
get isStrict() { return this.strict; }
|
|
15
15
|
set isStrict(value) {
|
|
16
|
-
if (this.
|
|
17
|
-
throw misuse("cannot change strict mode in the middle of
|
|
16
|
+
if (this.isScriptingInProgress && this.current.count > 0)
|
|
17
|
+
throw misuse("cannot change strict mode in the middle of script execution");
|
|
18
18
|
this.strict = value;
|
|
19
19
|
}
|
|
20
20
|
get count() {
|
|
21
21
|
return this.current.count;
|
|
22
22
|
}
|
|
23
|
-
get
|
|
23
|
+
get countOfAdded() {
|
|
24
24
|
return this.added.count;
|
|
25
25
|
}
|
|
26
|
-
get
|
|
26
|
+
get countOfRemoved() {
|
|
27
27
|
return this.removed.count;
|
|
28
28
|
}
|
|
29
|
-
get
|
|
30
|
-
return this.
|
|
29
|
+
get isScriptingInProgress() {
|
|
30
|
+
return this.cycle > 0;
|
|
31
31
|
}
|
|
32
32
|
lookup(key) {
|
|
33
33
|
let result = undefined;
|
|
@@ -44,18 +44,18 @@ export class MergeList {
|
|
|
44
44
|
}
|
|
45
45
|
return result;
|
|
46
46
|
}
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
50
|
-
throw misuse(error !== null && error !== void 0 ? error : "
|
|
47
|
+
tryReuse(key, resolution, error) {
|
|
48
|
+
const cycle = this.cycle;
|
|
49
|
+
if (cycle < 0)
|
|
50
|
+
throw misuse(error !== null && error !== void 0 ? error : "script execution is not in progress");
|
|
51
51
|
let item = this.strictNextItem;
|
|
52
52
|
if (key !== (item ? this.getKey(item.instance) : undefined))
|
|
53
53
|
item = this.lookup(key);
|
|
54
54
|
if (item) {
|
|
55
|
-
if (item.
|
|
56
|
-
item.
|
|
55
|
+
if (item.cycle !== cycle) {
|
|
56
|
+
item.cycle = cycle;
|
|
57
57
|
if (this.strict && item !== this.strictNextItem)
|
|
58
|
-
item.status =
|
|
58
|
+
item.status = cycle;
|
|
59
59
|
this.strictNextItem = item.next;
|
|
60
60
|
this.removed.exclude(item);
|
|
61
61
|
item.index = this.current.count;
|
|
@@ -72,16 +72,16 @@ export class MergeList {
|
|
|
72
72
|
resolution.isDuplicate = false;
|
|
73
73
|
return item;
|
|
74
74
|
}
|
|
75
|
-
|
|
75
|
+
add(instance) {
|
|
76
76
|
const key = this.getKey(instance);
|
|
77
77
|
if (this.lookup(key) !== undefined)
|
|
78
78
|
throw misuse(`key is already in use: ${key}`);
|
|
79
|
-
let
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
this.
|
|
79
|
+
let cycle = this.cycle;
|
|
80
|
+
if (cycle < 0) {
|
|
81
|
+
cycle = ~this.cycle + 1;
|
|
82
|
+
this.cycle = ~cycle;
|
|
83
83
|
}
|
|
84
|
-
const item = new
|
|
84
|
+
const item = new LinkedItemImpl(instance, cycle);
|
|
85
85
|
this.map.set(key, item);
|
|
86
86
|
this.lastNotFoundKey = undefined;
|
|
87
87
|
this.strictNextItem = undefined;
|
|
@@ -90,29 +90,29 @@ export class MergeList {
|
|
|
90
90
|
this.added.aux(item);
|
|
91
91
|
return item;
|
|
92
92
|
}
|
|
93
|
-
|
|
93
|
+
remove(item) {
|
|
94
94
|
const t = item;
|
|
95
95
|
if (!this.isRemoved(t)) {
|
|
96
96
|
this.current.exclude(t);
|
|
97
97
|
this.removed.include(t);
|
|
98
|
-
t.
|
|
98
|
+
t.cycle--;
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
move(item, after) {
|
|
102
102
|
throw misuse("not implemented");
|
|
103
103
|
}
|
|
104
|
-
|
|
105
|
-
if (this.
|
|
106
|
-
throw misuse("
|
|
107
|
-
this.
|
|
104
|
+
beginScriptExecution() {
|
|
105
|
+
if (this.isScriptingInProgress)
|
|
106
|
+
throw misuse("script execution is in progress already");
|
|
107
|
+
this.cycle = ~this.cycle + 1;
|
|
108
108
|
this.strictNextItem = this.current.first;
|
|
109
109
|
this.removed.grab(this.current, false);
|
|
110
110
|
this.added.reset();
|
|
111
111
|
}
|
|
112
|
-
|
|
113
|
-
if (!this.
|
|
114
|
-
throw misuse("
|
|
115
|
-
this.
|
|
112
|
+
endScriptExecution(error) {
|
|
113
|
+
if (!this.isScriptingInProgress)
|
|
114
|
+
throw misuse("script execution is ended already");
|
|
115
|
+
this.cycle = ~this.cycle;
|
|
116
116
|
if (error === undefined) {
|
|
117
117
|
const currentCount = this.current.count;
|
|
118
118
|
if (currentCount > 0) {
|
|
@@ -145,10 +145,10 @@ export class MergeList {
|
|
|
145
145
|
this.removed.reset();
|
|
146
146
|
this.added.reset();
|
|
147
147
|
}
|
|
148
|
-
|
|
148
|
+
firstItem() {
|
|
149
149
|
return this.current.first;
|
|
150
150
|
}
|
|
151
|
-
|
|
151
|
+
lastItem() {
|
|
152
152
|
return this.current.last;
|
|
153
153
|
}
|
|
154
154
|
*items(onlyAfter) {
|
|
@@ -160,7 +160,7 @@ export class MergeList {
|
|
|
160
160
|
x = next;
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
|
-
*
|
|
163
|
+
*itemsAdded(reset) {
|
|
164
164
|
let x = this.added.first;
|
|
165
165
|
while (x !== undefined) {
|
|
166
166
|
const next = x.aux;
|
|
@@ -171,7 +171,7 @@ export class MergeList {
|
|
|
171
171
|
if (reset)
|
|
172
172
|
this.added.reset();
|
|
173
173
|
}
|
|
174
|
-
*
|
|
174
|
+
*itemsRemoved(reset) {
|
|
175
175
|
let x = this.removed.first;
|
|
176
176
|
while (x !== undefined) {
|
|
177
177
|
const next = x.next;
|
|
@@ -183,48 +183,48 @@ export class MergeList {
|
|
|
183
183
|
}
|
|
184
184
|
isAdded(item) {
|
|
185
185
|
const t = item;
|
|
186
|
-
let
|
|
187
|
-
if (
|
|
188
|
-
|
|
189
|
-
return t.status === ~
|
|
186
|
+
let cycle = this.cycle;
|
|
187
|
+
if (cycle < 0)
|
|
188
|
+
cycle = ~cycle;
|
|
189
|
+
return t.status === ~cycle && t.cycle > 0;
|
|
190
190
|
}
|
|
191
191
|
isMoved(item) {
|
|
192
192
|
const t = item;
|
|
193
|
-
let
|
|
194
|
-
if (
|
|
195
|
-
|
|
196
|
-
return t.status ===
|
|
193
|
+
let cycle = this.cycle;
|
|
194
|
+
if (cycle < 0)
|
|
195
|
+
cycle = ~cycle;
|
|
196
|
+
return t.status === cycle && t.cycle > 0;
|
|
197
197
|
}
|
|
198
198
|
isRemoved(item) {
|
|
199
199
|
const t = item;
|
|
200
|
-
const
|
|
201
|
-
return
|
|
200
|
+
const cycle = this.cycle;
|
|
201
|
+
return cycle > 0 ? t.cycle < cycle : t.cycle < cycle - 1;
|
|
202
202
|
}
|
|
203
|
-
|
|
203
|
+
isAlive(item) {
|
|
204
204
|
const t = item;
|
|
205
|
-
return t.
|
|
205
|
+
return t.cycle === this.cycle;
|
|
206
206
|
}
|
|
207
207
|
markAsMoved(item) {
|
|
208
208
|
const t = item;
|
|
209
|
-
if (t.
|
|
210
|
-
t.status = t.
|
|
209
|
+
if (t.cycle > 0)
|
|
210
|
+
t.status = t.cycle;
|
|
211
211
|
}
|
|
212
212
|
static createItem(instance) {
|
|
213
|
-
return new
|
|
213
|
+
return new LinkedItemImpl(instance, 0);
|
|
214
214
|
}
|
|
215
215
|
}
|
|
216
|
-
class
|
|
217
|
-
constructor(instance,
|
|
216
|
+
class LinkedItemImpl {
|
|
217
|
+
constructor(instance, cycle) {
|
|
218
218
|
this.instance = instance;
|
|
219
219
|
this.index = -1;
|
|
220
|
-
this.
|
|
221
|
-
this.status = ~
|
|
220
|
+
this.cycle = cycle;
|
|
221
|
+
this.status = ~cycle;
|
|
222
222
|
this.next = undefined;
|
|
223
223
|
this.prev = undefined;
|
|
224
224
|
this.aux = undefined;
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
|
-
class
|
|
227
|
+
class LinkedItemChain {
|
|
228
228
|
constructor() {
|
|
229
229
|
this.count = 0;
|
|
230
230
|
this.first = undefined;
|
package/package.json
CHANGED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
export type GetMergedItemKey<T = unknown> = (item: T) => string | undefined;
|
|
2
|
-
export type MergeListReader<T> = {
|
|
3
|
-
readonly isStrict: boolean;
|
|
4
|
-
readonly count: number;
|
|
5
|
-
readonly addedCount: number;
|
|
6
|
-
readonly removedCount: number;
|
|
7
|
-
readonly isMergeInProgress: boolean;
|
|
8
|
-
lookup(key: string): MergedItem<T> | undefined;
|
|
9
|
-
firstMergedItem(): MergedItem<T> | undefined;
|
|
10
|
-
lastMergedItem(): MergedItem<T> | undefined;
|
|
11
|
-
items(onlyAfter?: MergedItem<T>): Generator<MergedItem<T>>;
|
|
12
|
-
addedItems(reset?: boolean): Generator<MergedItem<T>>;
|
|
13
|
-
removedItems(reset?: boolean): Generator<MergedItem<T>>;
|
|
14
|
-
isAdded(item: MergedItem<T>): boolean;
|
|
15
|
-
isMoved(item: MergedItem<T>): boolean;
|
|
16
|
-
isRemoved(item: MergedItem<T>): boolean;
|
|
17
|
-
isActual(item: MergedItem<T>): boolean;
|
|
18
|
-
};
|
|
19
|
-
export type MergedItem<T> = {
|
|
20
|
-
readonly instance: T;
|
|
21
|
-
readonly index: number;
|
|
22
|
-
readonly next?: MergedItem<T>;
|
|
23
|
-
readonly prev?: MergedItem<T>;
|
|
24
|
-
aux?: MergedItem<T>;
|
|
25
|
-
};
|
|
26
|
-
export declare class MergeList<T> implements MergeListReader<T> {
|
|
27
|
-
readonly getKey: GetMergedItemKey<T>;
|
|
28
|
-
private strict;
|
|
29
|
-
private map;
|
|
30
|
-
private tag;
|
|
31
|
-
private current;
|
|
32
|
-
private added;
|
|
33
|
-
private removed;
|
|
34
|
-
private lastNotFoundKey;
|
|
35
|
-
private strictNextItem?;
|
|
36
|
-
constructor(getKey: GetMergedItemKey<T>, strict?: boolean);
|
|
37
|
-
get isStrict(): boolean;
|
|
38
|
-
set isStrict(value: boolean);
|
|
39
|
-
get count(): number;
|
|
40
|
-
get addedCount(): number;
|
|
41
|
-
get removedCount(): number;
|
|
42
|
-
get isMergeInProgress(): boolean;
|
|
43
|
-
lookup(key: string | undefined): MergedItem<T> | undefined;
|
|
44
|
-
tryMergeAsExisting(key: string, resolution?: {
|
|
45
|
-
isDuplicate: boolean;
|
|
46
|
-
}, error?: string): MergedItem<T> | undefined;
|
|
47
|
-
mergeAsAdded(instance: T): MergedItem<T>;
|
|
48
|
-
mergeAsRemoved(item: MergedItem<T>): void;
|
|
49
|
-
move(item: MergedItem<T>, after: MergedItem<T>): void;
|
|
50
|
-
beginMerge(): void;
|
|
51
|
-
endMerge(error?: unknown): void;
|
|
52
|
-
resetAddedAndRemovedLists(): void;
|
|
53
|
-
firstMergedItem(): MergedItem<T> | undefined;
|
|
54
|
-
lastMergedItem(): MergedItem<T> | undefined;
|
|
55
|
-
items(onlyAfter?: MergedItem<T>): Generator<MergedItem<T>>;
|
|
56
|
-
addedItems(reset?: boolean): Generator<MergedItem<T>>;
|
|
57
|
-
removedItems(reset?: boolean): Generator<MergedItem<T>>;
|
|
58
|
-
isAdded(item: MergedItem<T>): boolean;
|
|
59
|
-
isMoved(item: MergedItem<T>): boolean;
|
|
60
|
-
isRemoved(item: MergedItem<T>): boolean;
|
|
61
|
-
isActual(item: MergedItem<T>): boolean;
|
|
62
|
-
markAsMoved(item: MergedItem<T>): void;
|
|
63
|
-
static createItem<T>(instance: T): MergedItem<T>;
|
|
64
|
-
}
|