reactronic 0.93.25025 → 0.94.25027
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 +41 -40
- package/build/dist/source/Enums.d.ts +32 -0
- package/build/dist/source/Enums.js +37 -0
- package/build/dist/source/OperationEx.d.ts +7 -0
- package/build/dist/source/{ReactiveLoop.js → OperationEx.js} +8 -8
- package/build/dist/source/Options.d.ts +7 -27
- package/build/dist/source/Options.js +0 -24
- package/build/dist/source/Pipe.d.ts +2 -2
- package/build/dist/source/Pipe.js +2 -2
- package/build/dist/source/Ref.d.ts +1 -1
- package/build/dist/source/Ref.js +4 -4
- package/build/dist/source/System.d.ts +29 -0
- package/build/dist/source/{ReactiveSystem.js → System.js} +24 -19
- package/build/dist/source/api.d.ts +12 -10
- package/build/dist/source/api.js +10 -8
- package/build/dist/source/core/Changeset.d.ts +8 -7
- package/build/dist/source/core/Changeset.js +18 -18
- package/build/dist/source/core/Data.d.ts +6 -6
- package/build/dist/source/core/Data.js +2 -2
- package/build/dist/source/core/Indicator.d.ts +2 -2
- package/build/dist/source/core/Indicator.js +3 -3
- package/build/dist/source/core/Journal.d.ts +2 -2
- package/build/dist/source/core/Journal.js +7 -7
- package/build/dist/source/core/Meta.d.ts +1 -1
- package/build/dist/source/core/Meta.js +1 -1
- package/build/dist/source/core/Mvcc.d.ts +17 -16
- package/build/dist/source/core/Mvcc.js +30 -30
- package/build/dist/source/core/MvccArray.d.ts +3 -3
- package/build/dist/source/core/MvccArray.js +4 -4
- package/build/dist/source/core/MvccMap.d.ts +3 -3
- package/build/dist/source/core/MvccMap.js +4 -4
- package/build/dist/source/core/MvccMergeList.d.ts +2 -2
- package/build/dist/source/core/MvccMergeList.js +2 -2
- package/build/dist/source/core/Operation.d.ts +25 -25
- package/build/dist/source/core/Operation.js +200 -200
- package/build/dist/source/core/Transaction.d.ts +3 -3
- package/build/dist/source/core/Transaction.js +72 -72
- package/build/dist/source/core/Tree.d.ts +26 -0
- package/build/dist/source/core/Tree.js +120 -0
- package/build/dist/source/core/TreeNode.d.ts +117 -0
- package/build/dist/source/core/{ReactiveNode.js → TreeNode.js} +57 -185
- package/package.json +1 -1
- package/build/dist/source/ReactiveLoop.d.ts +0 -7
- package/build/dist/source/ReactiveSystem.d.ts +0 -30
- package/build/dist/source/core/ReactiveNode.d.ts +0 -107
package/build/dist/source/api.js
CHANGED
|
@@ -3,16 +3,18 @@ export { MergeList } from "./util/MergeList.js";
|
|
|
3
3
|
export { SealedArray } from "./util/SealedArray.js";
|
|
4
4
|
export { SealedMap } from "./util/SealedMap.js";
|
|
5
5
|
export { SealedSet } from "./util/SealedSet.js";
|
|
6
|
-
export {
|
|
6
|
+
export { LoggingLevel } from "./Options.js";
|
|
7
|
+
export { Mode, Priority, Kind, Reentrance, Isolation } from "./Enums.js";
|
|
7
8
|
export { Ref, ToggleRef, refs, toggleRefs, customToggleRefs } from "./Ref.js";
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
9
|
+
export { AtomicObject, ObservableObject } from "./core/Mvcc.js";
|
|
10
|
+
export { AtomicArray, ObservableArray } from "./core/MvccArray.js";
|
|
11
|
+
export { AtomicMap, ObservableMap } from "./core/MvccMap.js";
|
|
11
12
|
export { Changeset } from "./core/Changeset.js";
|
|
12
13
|
export { Transaction } from "./core/Transaction.js";
|
|
13
14
|
export { Indicator } from "./core/Indicator.js";
|
|
14
15
|
export { Journal } from "./core/Journal.js";
|
|
15
|
-
export {
|
|
16
|
-
export { ReactiveSystem,
|
|
17
|
-
export {
|
|
18
|
-
export {
|
|
16
|
+
export { runAtomically, runNonReactively, runSensitively, runContextually, manageReactiveOperation, configureCurrentReactiveOperation, disposeObservableObject } from "./System.js";
|
|
17
|
+
export { ReactiveSystem, observable, atomic, reactive, cached, options } from "./System.js";
|
|
18
|
+
export { ReactiveOperationEx } from "./OperationEx.js";
|
|
19
|
+
export { ReactiveTreeNode, BaseDriver, ReactiveTreeVariable } from "./core/TreeNode.js";
|
|
20
|
+
export { ReactiveTree } from "./core/Tree.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { Kind
|
|
2
|
-
import {
|
|
1
|
+
import { Kind } from "../Enums.js";
|
|
2
|
+
import { SnapshotOptions } from "../Options.js";
|
|
3
|
+
import { AbstractChangeset, ObjectVersion, FieldKey, ObjectHandle, ContentFootprint, OperationFootprint } from "./Data.js";
|
|
3
4
|
export declare const MAX_REVISION: number;
|
|
4
5
|
export declare const UNDEFINED_REVISION: number;
|
|
5
6
|
export declare class Changeset implements AbstractChangeset {
|
|
@@ -19,12 +20,12 @@ export declare class Changeset implements AbstractChangeset {
|
|
|
19
20
|
private revision;
|
|
20
21
|
private bumper;
|
|
21
22
|
items: Map<ObjectHandle, ObjectVersion>;
|
|
22
|
-
obsolete:
|
|
23
|
+
obsolete: OperationFootprint[];
|
|
23
24
|
sealed: boolean;
|
|
24
25
|
constructor(options: SnapshotOptions | null, parent?: Changeset);
|
|
25
26
|
static current: () => Changeset;
|
|
26
27
|
static edit: () => Changeset;
|
|
27
|
-
static markUsed: (
|
|
28
|
+
static markUsed: (cf: ContentFootprint, ov: ObjectVersion, fk: FieldKey, h: ObjectHandle, kind: Kind, weak: boolean) => void;
|
|
28
29
|
static markEdited: (oldValue: any, newValue: any, edited: boolean, ov: ObjectVersion, fk: FieldKey, h: ObjectHandle) => void;
|
|
29
30
|
static tryResolveConflict: (theirValue: any, ourFormerValue: any, ourValue: any) => {
|
|
30
31
|
isResolved: boolean;
|
|
@@ -32,7 +33,7 @@ export declare class Changeset implements AbstractChangeset {
|
|
|
32
33
|
};
|
|
33
34
|
static propagateAllChangesThroughSubscriptions: (changeset: Changeset) => void;
|
|
34
35
|
static revokeAllSubscriptions: (changeset: Changeset) => void;
|
|
35
|
-
static enqueueReactionsToRun: (reactions: Array<
|
|
36
|
+
static enqueueReactionsToRun: (reactions: Array<OperationFootprint>) => void;
|
|
36
37
|
lookupObjectVersion(h: ObjectHandle, fk: FieldKey, editing: boolean): ObjectVersion;
|
|
37
38
|
getObjectVersion(h: ObjectHandle, fk: FieldKey): ObjectVersion;
|
|
38
39
|
getEditableObjectVersion(h: ObjectHandle, fk: FieldKey, value: any, token?: any): ObjectVersion;
|
|
@@ -47,7 +48,7 @@ export declare class Changeset implements AbstractChangeset {
|
|
|
47
48
|
private merge;
|
|
48
49
|
seal(): void;
|
|
49
50
|
sealObjectVersion(h: ObjectHandle, ov: ObjectVersion): void;
|
|
50
|
-
static sealFieldVersion(
|
|
51
|
+
static sealFieldVersion(cf: ContentFootprint | symbol, fk: FieldKey, typeName: string): void;
|
|
51
52
|
static freezeObjectVersion(ov: ObjectVersion): ObjectVersion;
|
|
52
53
|
triggerGarbageCollection(): void;
|
|
53
54
|
private unlinkHistory;
|
|
@@ -56,7 +57,7 @@ export declare class Changeset implements AbstractChangeset {
|
|
|
56
57
|
export declare class Dump {
|
|
57
58
|
static valueHint: (value: any) => string;
|
|
58
59
|
static obj(h: ObjectHandle | undefined, fk?: FieldKey | undefined, stamp?: number, changesetId?: number, lastEditorChangesetId?: number, value?: any): string;
|
|
59
|
-
static snapshot2(h: ObjectHandle, s: AbstractChangeset, fk?: FieldKey,
|
|
60
|
+
static snapshot2(h: ObjectHandle, s: AbstractChangeset, fk?: FieldKey, cf?: ContentFootprint): string;
|
|
60
61
|
static snapshot(ov: ObjectVersion, fk?: FieldKey): string;
|
|
61
62
|
static conflicts(conflicts: ObjectVersion[]): string;
|
|
62
63
|
static conflictingMemberHint(fk: FieldKey, ours: ObjectVersion, theirs: ObjectVersion): string;
|
|
@@ -4,8 +4,8 @@ import { Sealant } from "../util/Sealant.js";
|
|
|
4
4
|
import { SealedArray } from "../util/SealedArray.js";
|
|
5
5
|
import { SealedMap } from "../util/SealedMap.js";
|
|
6
6
|
import { SealedSet } from "../util/SealedSet.js";
|
|
7
|
-
import { Isolation } from "../
|
|
8
|
-
import { ObjectVersion, ObjectHandle,
|
|
7
|
+
import { Isolation } from "../Enums.js";
|
|
8
|
+
import { ObjectVersion, ObjectHandle, ContentFootprint, Meta } from "./Data.js";
|
|
9
9
|
export const MAX_REVISION = Number.MAX_SAFE_INTEGER;
|
|
10
10
|
export const UNDEFINED_REVISION = MAX_REVISION - 1;
|
|
11
11
|
Object.defineProperty(ObjectHandle.prototype, "#this#", {
|
|
@@ -15,7 +15,7 @@ Object.defineProperty(ObjectHandle.prototype, "#this#", {
|
|
|
15
15
|
const data = Changeset.current().getObjectVersion(this, "#this#").data;
|
|
16
16
|
for (const fk in data) {
|
|
17
17
|
const v = data[fk];
|
|
18
|
-
if (v instanceof
|
|
18
|
+
if (v instanceof ContentFootprint)
|
|
19
19
|
result[fk] = v.content;
|
|
20
20
|
else if (v === Meta.Raw)
|
|
21
21
|
result[fk] = this.data[fk];
|
|
@@ -76,7 +76,7 @@ export class Changeset {
|
|
|
76
76
|
const revision = fk === Meta.Handle ? 1 : ov.revision + 1;
|
|
77
77
|
const data = Object.assign({}, fk === Meta.Handle ? value : ov.data);
|
|
78
78
|
Meta.set(data, Meta.Handle, h);
|
|
79
|
-
Meta.set(data, Meta.Revision, new
|
|
79
|
+
Meta.set(data, Meta.Revision, new ContentFootprint(revision, this.id));
|
|
80
80
|
ov = new ObjectVersion(this, ov, data);
|
|
81
81
|
this.items.set(h, ov);
|
|
82
82
|
h.editing = ov;
|
|
@@ -95,7 +95,7 @@ export class Changeset {
|
|
|
95
95
|
if (existing === undefined || existing.content !== content || sensitivity) {
|
|
96
96
|
const existingContent = existing === null || existing === void 0 ? void 0 : existing.content;
|
|
97
97
|
if (ov.former.objectVersion.data[fk] === existing) {
|
|
98
|
-
existing = ov.data[fk] = new
|
|
98
|
+
existing = ov.data[fk] = new ContentFootprint(content, this.id);
|
|
99
99
|
Changeset.markEdited(existingContent, content, true, ov, fk, h);
|
|
100
100
|
}
|
|
101
101
|
else {
|
|
@@ -125,7 +125,7 @@ export class Changeset {
|
|
|
125
125
|
}
|
|
126
126
|
isNewObjectVersionRequired(h, ov, fk, existing, value, token) {
|
|
127
127
|
if (this.sealed && ov.changeset !== EMPTY_OBJECT_VERSION.changeset)
|
|
128
|
-
throw misuse(`
|
|
128
|
+
throw misuse(`observable property ${Dump.obj(h, fk)} can only be modified inside transaction`);
|
|
129
129
|
if (fk !== Meta.Handle) {
|
|
130
130
|
if (value !== Meta.Handle) {
|
|
131
131
|
if (ov.changeset !== this || ov.former.objectVersion !== EMPTY_OBJECT_VERSION) {
|
|
@@ -190,8 +190,8 @@ export class Changeset {
|
|
|
190
190
|
const merged = Object.assign({}, theirs.data);
|
|
191
191
|
ours.changes.forEach((o, fk) => {
|
|
192
192
|
counter++;
|
|
193
|
-
const
|
|
194
|
-
merged[fk] =
|
|
193
|
+
const ourContentFootprint = ours.data[fk];
|
|
194
|
+
merged[fk] = ourContentFootprint;
|
|
195
195
|
if (theirsDisposed || oursDisposed) {
|
|
196
196
|
if (theirsDisposed !== oursDisposed) {
|
|
197
197
|
if (theirsDisposed || this.options.isolation !== Isolation.disjoinForInternalDisposal) {
|
|
@@ -204,10 +204,10 @@ export class Changeset {
|
|
|
204
204
|
else {
|
|
205
205
|
const theirValue = theirs.data[fk];
|
|
206
206
|
const ourFormerValue = ours.former.objectVersion.data[fk];
|
|
207
|
-
const { isResolved, resolvedValue } = Changeset.tryResolveConflict(theirValue, ourFormerValue,
|
|
207
|
+
const { isResolved, resolvedValue } = Changeset.tryResolveConflict(theirValue, ourFormerValue, ourContentFootprint);
|
|
208
208
|
if (!isResolved)
|
|
209
209
|
ours.conflicts.set(fk, theirs);
|
|
210
|
-
else if (resolvedValue.
|
|
210
|
+
else if (resolvedValue.isComputed)
|
|
211
211
|
merged[fk] = resolvedValue;
|
|
212
212
|
if (Log.isOn && Log.opt.change)
|
|
213
213
|
Log.write("║╠", "", `${Dump.snapshot2(h, ours.changeset, fk)} ${!isResolved ? "<>" : "=="} ${Dump.snapshot2(h, theirs.changeset, fk)}`, 0, !isResolved ? " *** CONFLICT ***" : undefined);
|
|
@@ -234,13 +234,13 @@ export class Changeset {
|
|
|
234
234
|
if (h.editors === 0)
|
|
235
235
|
h.editing = undefined;
|
|
236
236
|
}
|
|
237
|
-
static sealFieldVersion(
|
|
238
|
-
if (
|
|
239
|
-
const content =
|
|
237
|
+
static sealFieldVersion(cf, fk, typeName) {
|
|
238
|
+
if (cf instanceof ContentFootprint) {
|
|
239
|
+
const content = cf.content;
|
|
240
240
|
if (content !== undefined && content !== null) {
|
|
241
241
|
const sealedType = Object.getPrototypeOf(content)[Sealant.SealedType];
|
|
242
242
|
if (sealedType)
|
|
243
|
-
|
|
243
|
+
cf.content = Sealant.seal(content, sealedType, typeName, fk);
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
246
|
}
|
|
@@ -334,14 +334,14 @@ export class Dump {
|
|
|
334
334
|
result = `boot${member}`;
|
|
335
335
|
return result;
|
|
336
336
|
}
|
|
337
|
-
static snapshot2(h, s, fk,
|
|
337
|
+
static snapshot2(h, s, fk, cf) {
|
|
338
338
|
var _a;
|
|
339
|
-
return Dump.obj(h, fk, s.timestamp, s.id,
|
|
339
|
+
return Dump.obj(h, fk, s.timestamp, s.id, cf === null || cf === void 0 ? void 0 : cf.lastEditorChangesetId, (_a = cf === null || cf === void 0 ? void 0 : cf.content) !== null && _a !== void 0 ? _a : Meta.Undefined);
|
|
340
340
|
}
|
|
341
341
|
static snapshot(ov, fk) {
|
|
342
342
|
const h = Meta.get(ov.data, Meta.Handle);
|
|
343
|
-
const
|
|
344
|
-
return Dump.obj(h, fk, ov.changeset.timestamp, ov.changeset.id,
|
|
343
|
+
const cf = fk !== undefined ? ov.data[fk] : undefined;
|
|
344
|
+
return Dump.obj(h, fk, ov.changeset.timestamp, ov.changeset.id, cf === null || cf === void 0 ? void 0 : cf.lastEditorChangesetId);
|
|
345
345
|
}
|
|
346
346
|
static conflicts(conflicts) {
|
|
347
347
|
return conflicts.map(ours => {
|
|
@@ -5,19 +5,19 @@ export type AbstractChangeset = {
|
|
|
5
5
|
readonly timestamp: number;
|
|
6
6
|
readonly sealed: boolean;
|
|
7
7
|
};
|
|
8
|
-
export declare class
|
|
8
|
+
export declare class ContentFootprint<T = any> {
|
|
9
9
|
content: T;
|
|
10
|
-
|
|
10
|
+
subscribers?: Set<OperationFootprint>;
|
|
11
11
|
lastEditorChangesetId: number;
|
|
12
|
-
get
|
|
12
|
+
get isComputed(): boolean;
|
|
13
13
|
constructor(content: T, lastEditorChangesetId: number);
|
|
14
14
|
}
|
|
15
|
-
export type
|
|
15
|
+
export type OperationFootprint = {
|
|
16
16
|
readonly order: number;
|
|
17
|
-
readonly
|
|
17
|
+
readonly observables: Map<ContentFootprint, Subscription> | undefined;
|
|
18
18
|
readonly obsoleteSince: number;
|
|
19
19
|
hint(nop?: boolean): string;
|
|
20
|
-
markObsoleteDueTo(
|
|
20
|
+
markObsoleteDueTo(footprint: ContentFootprint, fk: FieldKey, changeset: AbstractChangeset, h: ObjectHandle, outer: string, since: number, collector: Array<OperationFootprint>): void;
|
|
21
21
|
relaunchIfNotUpToDate(now: boolean, nothrow: boolean): void;
|
|
22
22
|
};
|
|
23
23
|
export type FieldKey = PropertyKey;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Log } from "../util/Dbg.js";
|
|
2
2
|
import { Meta } from "./Meta.js";
|
|
3
3
|
export { Meta } from "./Meta.js";
|
|
4
|
-
export class
|
|
5
|
-
get
|
|
4
|
+
export class ContentFootprint {
|
|
5
|
+
get isComputed() { return false; }
|
|
6
6
|
constructor(content, lastEditorChangesetId) { this.content = content; this.lastEditorChangesetId = lastEditorChangesetId; }
|
|
7
7
|
}
|
|
8
8
|
export class ObjectVersion {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Worker } from "../Worker.js";
|
|
2
|
-
import {
|
|
3
|
-
export declare abstract class Indicator extends
|
|
2
|
+
import { ObservableObject } from "./Mvcc.js";
|
|
3
|
+
export declare abstract class Indicator extends ObservableObject {
|
|
4
4
|
abstract readonly isBusy: boolean;
|
|
5
5
|
abstract readonly counter: number;
|
|
6
6
|
abstract readonly workers: ReadonlySet<Worker>;
|
|
@@ -7,10 +7,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { Isolation } from "../
|
|
11
|
-
import {
|
|
10
|
+
import { Isolation } from "../Enums.js";
|
|
11
|
+
import { ObservableObject, Mvcc } from "./Mvcc.js";
|
|
12
12
|
import { Transaction } from "./Transaction.js";
|
|
13
|
-
export class Indicator extends
|
|
13
|
+
export class Indicator extends ObservableObject {
|
|
14
14
|
static create(hint, activationDelay, deactivationDelay, durationResolution) {
|
|
15
15
|
return IndicatorImpl.createImpl(hint, activationDelay, deactivationDelay, durationResolution);
|
|
16
16
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ObservableObject } from "./Mvcc.js";
|
|
2
2
|
import { ObjectHandle, ObjectVersion, PatchSet } from "./Data.js";
|
|
3
3
|
export type Saver = (patch: PatchSet) => Promise<void>;
|
|
4
|
-
export declare abstract class Journal extends
|
|
4
|
+
export declare abstract class Journal extends ObservableObject {
|
|
5
5
|
abstract capacity: number;
|
|
6
6
|
abstract readonly edits: ReadonlyArray<PatchSet>;
|
|
7
7
|
abstract readonly unsaved: PatchSet;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Isolation } from "../
|
|
2
|
-
import {
|
|
3
|
-
import { Meta,
|
|
1
|
+
import { Isolation } from "../Enums.js";
|
|
2
|
+
import { ObservableObject } from "./Mvcc.js";
|
|
3
|
+
import { Meta, ContentFootprint } from "./Data.js";
|
|
4
4
|
import { Changeset, EMPTY_OBJECT_VERSION } from "./Changeset.js";
|
|
5
5
|
import { Transaction } from "./Transaction.js";
|
|
6
6
|
import { Sealant } from "../util/Sealant.js";
|
|
7
|
-
export class Journal extends
|
|
7
|
+
export class Journal extends ObservableObject {
|
|
8
8
|
static create() { return new JournalImpl(); }
|
|
9
9
|
}
|
|
10
10
|
export class JournalImpl extends Journal {
|
|
@@ -100,7 +100,7 @@ export class JournalImpl extends Journal {
|
|
|
100
100
|
const content = undoing ? vp.formerContent : vp.freshContent;
|
|
101
101
|
const ov = ctx.getEditableObjectVersion(h, fk, content);
|
|
102
102
|
if (ov.changeset === ctx) {
|
|
103
|
-
ov.data[fk] = new
|
|
103
|
+
ov.data[fk] = new ContentFootprint(content, ctx.id);
|
|
104
104
|
const existing = ov.former.objectVersion.data[fk];
|
|
105
105
|
Changeset.markEdited(existing, content, existing !== content, ov, fk, h);
|
|
106
106
|
}
|
|
@@ -138,8 +138,8 @@ export class JournalImpl extends Journal {
|
|
|
138
138
|
});
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
-
function unseal(
|
|
142
|
-
const result =
|
|
141
|
+
function unseal(cf) {
|
|
142
|
+
const result = cf.content;
|
|
143
143
|
const createCopy = result === null || result === void 0 ? void 0 : result[Sealant.CreateCopy];
|
|
144
144
|
return createCopy !== undefined ? createCopy.call(result) : result;
|
|
145
145
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare abstract class Meta {
|
|
2
2
|
static readonly Handle: unique symbol;
|
|
3
3
|
static readonly Revision: unique symbol;
|
|
4
|
-
static readonly
|
|
4
|
+
static readonly Descriptor: unique symbol;
|
|
5
5
|
static readonly Initial: unique symbol;
|
|
6
6
|
static readonly Reactive: unique symbol;
|
|
7
7
|
static readonly Raw: unique symbol;
|
|
@@ -22,7 +22,7 @@ export class Meta {
|
|
|
22
22
|
}
|
|
23
23
|
Meta.Handle = Symbol("rx-handle");
|
|
24
24
|
Meta.Revision = Symbol("rx-revision");
|
|
25
|
-
Meta.
|
|
25
|
+
Meta.Descriptor = Symbol("rx-descriptor");
|
|
26
26
|
Meta.Initial = Symbol("rx-initial");
|
|
27
27
|
Meta.Reactive = Symbol("rx-reactive");
|
|
28
28
|
Meta.Raw = Symbol("rx-raw");
|
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
import { F } from "../util/Utils.js";
|
|
2
|
-
import {
|
|
2
|
+
import { Kind, Reentrance, Isolation } from "../Enums.js";
|
|
3
|
+
import { ReactivityOptions } from "../Options.js";
|
|
3
4
|
import { LoggingOptions, ProfilingOptions } from "../Logging.js";
|
|
4
5
|
import { FieldKey, ObjectHandle } from "./Data.js";
|
|
5
6
|
import { Journal } from "./Journal.js";
|
|
6
7
|
import { Indicator } from "./Indicator.js";
|
|
7
8
|
export declare abstract class MvccObject {
|
|
8
|
-
protected constructor(
|
|
9
|
+
protected constructor(isObservable: boolean);
|
|
9
10
|
[Symbol.toStringTag](): string;
|
|
10
11
|
}
|
|
11
|
-
export declare abstract class
|
|
12
|
+
export declare abstract class AtomicObject extends MvccObject {
|
|
12
13
|
constructor();
|
|
13
14
|
}
|
|
14
|
-
export declare abstract class
|
|
15
|
+
export declare abstract class ObservableObject extends MvccObject {
|
|
15
16
|
constructor();
|
|
16
17
|
}
|
|
17
|
-
export declare class OptionsImpl implements
|
|
18
|
+
export declare class OptionsImpl implements ReactivityOptions {
|
|
18
19
|
readonly getter: Function;
|
|
19
20
|
readonly setter: Function;
|
|
20
21
|
readonly kind: Kind;
|
|
21
22
|
readonly isolation: Isolation;
|
|
22
23
|
readonly order: number;
|
|
23
24
|
readonly noSideEffects: boolean;
|
|
24
|
-
readonly
|
|
25
|
+
readonly observableArgs: boolean;
|
|
25
26
|
readonly throttling: number;
|
|
26
27
|
readonly reentrance: Reentrance;
|
|
27
28
|
readonly allowObsoleteToFinish: boolean;
|
|
@@ -37,10 +38,10 @@ export declare class Mvcc implements ProxyHandler<ObjectHandle> {
|
|
|
37
38
|
static mainThreadBlockingWarningThreshold: number;
|
|
38
39
|
static asyncActionDurationWarningThreshold: number;
|
|
39
40
|
static sensitivity: boolean;
|
|
40
|
-
static readonly
|
|
41
|
-
static readonly
|
|
42
|
-
readonly
|
|
43
|
-
constructor(
|
|
41
|
+
static readonly atomic: Mvcc;
|
|
42
|
+
static readonly observable: Mvcc;
|
|
43
|
+
readonly isObservable: boolean;
|
|
44
|
+
constructor(isObservable: boolean);
|
|
44
45
|
getPrototypeOf(h: ObjectHandle): object | null;
|
|
45
46
|
get(h: ObjectHandle, fk: FieldKey, receiver: any): any;
|
|
46
47
|
set(h: ObjectHandle, fk: FieldKey, value: any, receiver: any): boolean;
|
|
@@ -48,15 +49,15 @@ export declare class Mvcc implements ProxyHandler<ObjectHandle> {
|
|
|
48
49
|
defineProperty?(h: ObjectHandle, name: string | symbol, attributes: PropertyDescriptor): boolean;
|
|
49
50
|
getOwnPropertyDescriptor(h: ObjectHandle, fk: FieldKey): PropertyDescriptor | undefined;
|
|
50
51
|
ownKeys(h: ObjectHandle): Array<string | symbol>;
|
|
51
|
-
static decorateData(
|
|
52
|
-
static decorateOperation(implicit: boolean, decorator: Function, options: Partial<
|
|
53
|
-
static decorateOperationParametrized(decorator: Function, options: Partial<
|
|
52
|
+
static decorateData(isObservable: boolean, proto: any, fk: FieldKey): any;
|
|
53
|
+
static decorateOperation(implicit: boolean, decorator: Function, options: Partial<ReactivityOptions>, proto: any, member: FieldKey, pd: PropertyDescriptor | undefined): any;
|
|
54
|
+
static decorateOperationParametrized(decorator: Function, options: Partial<ReactivityOptions>): F<any>;
|
|
54
55
|
static acquireHandle(obj: any): ObjectHandle;
|
|
55
|
-
static createHandleForMvccObject(proto: any, data: any, blank: any, hint: string,
|
|
56
|
+
static createHandleForMvccObject(proto: any, data: any, blank: any, hint: string, isObservable: boolean): ObjectHandle;
|
|
56
57
|
static setProfilingMode(isOn: boolean, options?: Partial<ProfilingOptions>): void;
|
|
57
58
|
static sensitive<T>(sensitivity: boolean, func: F<T>, ...args: any[]): T;
|
|
58
59
|
static setHint<T>(obj: T, hint: string | undefined): T;
|
|
59
60
|
static getHint<T>(obj: T): string;
|
|
60
|
-
static
|
|
61
|
-
static rememberOperationOptions: (proto: any, fk: FieldKey, getter: Function | undefined, setter: Function | undefined, enumerable: boolean, configurable: boolean, options: Partial<
|
|
61
|
+
static createOperationDescriptor: (h: ObjectHandle, fk: FieldKey, options: OptionsImpl) => F<any>;
|
|
62
|
+
static rememberOperationOptions: (proto: any, fk: FieldKey, getter: Function | undefined, setter: Function | undefined, enumerable: boolean, configurable: boolean, options: Partial<ReactivityOptions>, implicit: boolean) => OptionsImpl;
|
|
62
63
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { UNDEF } from "../util/Utils.js";
|
|
2
2
|
import { Log, misuse } from "../util/Dbg.js";
|
|
3
|
-
import { Kind, Reentrance, Isolation } from "../
|
|
4
|
-
import { ObjectVersion, ObjectHandle,
|
|
3
|
+
import { Kind, Reentrance, Isolation } from "../Enums.js";
|
|
4
|
+
import { ObjectVersion, ObjectHandle, ContentFootprint, Meta } from "./Data.js";
|
|
5
5
|
import { Changeset, Dump, EMPTY_OBJECT_VERSION } from "./Changeset.js";
|
|
6
6
|
export class MvccObject {
|
|
7
|
-
constructor(
|
|
7
|
+
constructor(isObservable) {
|
|
8
8
|
const proto = new.target.prototype;
|
|
9
9
|
const initial = Meta.getFrom(proto, Meta.Initial);
|
|
10
|
-
const h = Mvcc.createHandleForMvccObject(proto, this, initial, new.target.name,
|
|
10
|
+
const h = Mvcc.createHandleForMvccObject(proto, this, initial, new.target.name, isObservable);
|
|
11
11
|
return h.proxy;
|
|
12
12
|
}
|
|
13
13
|
[Symbol.toStringTag]() {
|
|
@@ -15,12 +15,12 @@ export class MvccObject {
|
|
|
15
15
|
return Dump.obj(h);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
export class
|
|
18
|
+
export class AtomicObject extends MvccObject {
|
|
19
19
|
constructor() {
|
|
20
20
|
super(false);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
export class
|
|
23
|
+
export class ObservableObject extends MvccObject {
|
|
24
24
|
constructor() {
|
|
25
25
|
super(true);
|
|
26
26
|
}
|
|
@@ -30,7 +30,7 @@ const DEFAULT_OPTIONS = Object.freeze({
|
|
|
30
30
|
isolation: Isolation.joinToCurrentTransaction,
|
|
31
31
|
order: 0,
|
|
32
32
|
noSideEffects: false,
|
|
33
|
-
|
|
33
|
+
observableArgs: false,
|
|
34
34
|
throttling: Number.MAX_SAFE_INTEGER,
|
|
35
35
|
reentrance: Reentrance.preventWithError,
|
|
36
36
|
allowObsoleteToFinish: false,
|
|
@@ -46,7 +46,7 @@ export class OptionsImpl {
|
|
|
46
46
|
this.isolation = merge(DEFAULT_OPTIONS.isolation, existing.isolation, patch.isolation, implicit);
|
|
47
47
|
this.order = merge(DEFAULT_OPTIONS.order, existing.order, patch.order, implicit);
|
|
48
48
|
this.noSideEffects = merge(DEFAULT_OPTIONS.noSideEffects, existing.noSideEffects, patch.noSideEffects, implicit);
|
|
49
|
-
this.
|
|
49
|
+
this.observableArgs = merge(DEFAULT_OPTIONS.observableArgs, existing.observableArgs, patch.observableArgs, implicit);
|
|
50
50
|
this.throttling = merge(DEFAULT_OPTIONS.throttling, existing.throttling, patch.throttling, implicit);
|
|
51
51
|
this.reentrance = merge(DEFAULT_OPTIONS.reentrance, existing.reentrance, patch.reentrance, implicit);
|
|
52
52
|
this.allowObsoleteToFinish = merge(DEFAULT_OPTIONS.allowObsoleteToFinish, existing.allowObsoleteToFinish, patch.allowObsoleteToFinish, implicit);
|
|
@@ -62,8 +62,8 @@ function merge(def, existing, patch, implicit) {
|
|
|
62
62
|
return patch !== undefined && (existing === def || !implicit) ? patch : existing;
|
|
63
63
|
}
|
|
64
64
|
export class Mvcc {
|
|
65
|
-
constructor(
|
|
66
|
-
this.
|
|
65
|
+
constructor(isObservable) {
|
|
66
|
+
this.isObservable = isObservable;
|
|
67
67
|
}
|
|
68
68
|
getPrototypeOf(h) {
|
|
69
69
|
return Reflect.getPrototypeOf(h.data);
|
|
@@ -74,8 +74,8 @@ export class Mvcc {
|
|
|
74
74
|
const cs = Changeset.current();
|
|
75
75
|
const ov = cs.getObjectVersion(h, fk);
|
|
76
76
|
result = ov.data[fk];
|
|
77
|
-
if (result instanceof
|
|
78
|
-
if (this.
|
|
77
|
+
if (result instanceof ContentFootprint && !result.isComputed) {
|
|
78
|
+
if (this.isObservable)
|
|
79
79
|
Changeset.markUsed(result, ov, fk, h, Kind.plain, false);
|
|
80
80
|
result = result.content;
|
|
81
81
|
}
|
|
@@ -117,21 +117,21 @@ export class Mvcc {
|
|
|
117
117
|
const result = [];
|
|
118
118
|
for (const fk of Object.getOwnPropertyNames(ov.data)) {
|
|
119
119
|
const field = ov.data[fk];
|
|
120
|
-
if (!(field instanceof
|
|
120
|
+
if (!(field instanceof ContentFootprint) || !field.isComputed)
|
|
121
121
|
result.push(fk);
|
|
122
122
|
}
|
|
123
123
|
return result;
|
|
124
124
|
}
|
|
125
|
-
static decorateData(
|
|
126
|
-
if (
|
|
127
|
-
Meta.acquire(proto, Meta.Initial)[fk] = new
|
|
125
|
+
static decorateData(isObservable, proto, fk) {
|
|
126
|
+
if (isObservable) {
|
|
127
|
+
Meta.acquire(proto, Meta.Initial)[fk] = new ContentFootprint(undefined, 0);
|
|
128
128
|
const get = function () {
|
|
129
129
|
const h = Mvcc.acquireHandle(this);
|
|
130
|
-
return Mvcc.
|
|
130
|
+
return Mvcc.observable.get(h, fk, this);
|
|
131
131
|
};
|
|
132
132
|
const set = function (value) {
|
|
133
133
|
const h = Mvcc.acquireHandle(this);
|
|
134
|
-
return Mvcc.
|
|
134
|
+
return Mvcc.observable.set(h, fk, value, this);
|
|
135
135
|
};
|
|
136
136
|
const enumerable = true;
|
|
137
137
|
const configurable = false;
|
|
@@ -150,7 +150,7 @@ export class Mvcc {
|
|
|
150
150
|
if (opts.getter === opts.setter) {
|
|
151
151
|
const bootstrap = function () {
|
|
152
152
|
const h = Mvcc.acquireHandle(this);
|
|
153
|
-
const operation = Mvcc.
|
|
153
|
+
const operation = Mvcc.createOperationDescriptor(h, member, opts);
|
|
154
154
|
Object.defineProperty(h.data, member, { value: operation, enumerable, configurable });
|
|
155
155
|
return operation;
|
|
156
156
|
};
|
|
@@ -159,7 +159,7 @@ export class Mvcc {
|
|
|
159
159
|
else if (opts.setter === UNDEF) {
|
|
160
160
|
const bootstrap = function () {
|
|
161
161
|
const h = Mvcc.acquireHandle(this);
|
|
162
|
-
const operation = Mvcc.
|
|
162
|
+
const operation = Mvcc.createOperationDescriptor(h, member, opts);
|
|
163
163
|
Object.defineProperty(h.data, member, { get: operation, enumerable, configurable });
|
|
164
164
|
return operation.call(this);
|
|
165
165
|
};
|
|
@@ -177,24 +177,24 @@ export class Mvcc {
|
|
|
177
177
|
let h = obj[Meta.Handle];
|
|
178
178
|
if (!h) {
|
|
179
179
|
if (obj !== Object(obj) || Array.isArray(obj))
|
|
180
|
-
throw misuse("only objects can be
|
|
180
|
+
throw misuse("only objects can be observable");
|
|
181
181
|
const initial = Meta.getFrom(Object.getPrototypeOf(obj), Meta.Initial);
|
|
182
182
|
const ov = new ObjectVersion(EMPTY_OBJECT_VERSION.changeset, EMPTY_OBJECT_VERSION, Object.assign({}, initial));
|
|
183
|
-
h = new ObjectHandle(obj, obj, Mvcc.
|
|
183
|
+
h = new ObjectHandle(obj, obj, Mvcc.observable, ov, obj.constructor.name);
|
|
184
184
|
Meta.set(ov.data, Meta.Handle, h);
|
|
185
185
|
Meta.set(obj, Meta.Handle, h);
|
|
186
|
-
Meta.set(ov.data, Meta.Revision, new
|
|
186
|
+
Meta.set(ov.data, Meta.Revision, new ContentFootprint(1, 0));
|
|
187
187
|
}
|
|
188
188
|
return h;
|
|
189
189
|
}
|
|
190
|
-
static createHandleForMvccObject(proto, data, blank, hint,
|
|
190
|
+
static createHandleForMvccObject(proto, data, blank, hint, isObservable) {
|
|
191
191
|
const ctx = Changeset.edit();
|
|
192
|
-
const mvcc =
|
|
192
|
+
const mvcc = isObservable ? Mvcc.observable : Mvcc.atomic;
|
|
193
193
|
const h = new ObjectHandle(data, undefined, mvcc, EMPTY_OBJECT_VERSION, hint);
|
|
194
194
|
ctx.getEditableObjectVersion(h, Meta.Handle, blank);
|
|
195
195
|
if (!Mvcc.reactivityAutoStartDisabled)
|
|
196
196
|
for (const fk in Meta.getFrom(proto, Meta.Reactive))
|
|
197
|
-
h.proxy[fk][Meta.
|
|
197
|
+
h.proxy[fk][Meta.Descriptor].markObsolete();
|
|
198
198
|
return h;
|
|
199
199
|
}
|
|
200
200
|
static setProfilingMode(isOn, options) {
|
|
@@ -238,10 +238,10 @@ Mvcc.repetitiveUsageWarningThreshold = Number.MAX_SAFE_INTEGER;
|
|
|
238
238
|
Mvcc.mainThreadBlockingWarningThreshold = Number.MAX_SAFE_INTEGER;
|
|
239
239
|
Mvcc.asyncActionDurationWarningThreshold = Number.MAX_SAFE_INTEGER;
|
|
240
240
|
Mvcc.sensitivity = false;
|
|
241
|
-
Mvcc.
|
|
242
|
-
Mvcc.
|
|
243
|
-
Mvcc.
|
|
244
|
-
throw misuse("this implementation of
|
|
241
|
+
Mvcc.atomic = new Mvcc(false);
|
|
242
|
+
Mvcc.observable = new Mvcc(true);
|
|
243
|
+
Mvcc.createOperationDescriptor = function (h, fk, options) {
|
|
244
|
+
throw misuse("this implementation of createOperationDescriptor should never be called");
|
|
245
245
|
};
|
|
246
246
|
Mvcc.rememberOperationOptions = function (proto, fk, getter, setter, enumerable, configurable, options, implicit) {
|
|
247
247
|
throw misuse("this implementation of rememberOperationOptions should never be called");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MvccObject } from "./Mvcc.js";
|
|
2
2
|
export declare class MvccArray<T> extends MvccObject {
|
|
3
3
|
private impl;
|
|
4
|
-
constructor(
|
|
4
|
+
constructor(isObservable: boolean, array: Array<T>);
|
|
5
5
|
get length(): number;
|
|
6
6
|
set length(n: number);
|
|
7
7
|
getItem(n: number): T;
|
|
@@ -47,13 +47,13 @@ export declare class MvccArray<T> extends MvccObject {
|
|
|
47
47
|
values(): IterableIterator<T>;
|
|
48
48
|
private get mutable();
|
|
49
49
|
}
|
|
50
|
-
export declare class
|
|
50
|
+
export declare class AtomicArray<T> extends MvccArray<T> {
|
|
51
51
|
constructor();
|
|
52
52
|
constructor(arrayLength: number);
|
|
53
53
|
constructor(arrayLength?: number);
|
|
54
54
|
constructor(...items: T[]);
|
|
55
55
|
}
|
|
56
|
-
export declare class
|
|
56
|
+
export declare class ObservableArray<T> extends MvccArray<T> {
|
|
57
57
|
constructor();
|
|
58
58
|
constructor(arrayLength: number);
|
|
59
59
|
constructor(arrayLength?: number);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Sealant } from "../util/Sealant.js";
|
|
2
2
|
import { MvccObject } from "./Mvcc.js";
|
|
3
3
|
export class MvccArray extends MvccObject {
|
|
4
|
-
constructor(
|
|
5
|
-
super(
|
|
4
|
+
constructor(isObservable, array) {
|
|
5
|
+
super(isObservable);
|
|
6
6
|
this.impl = array;
|
|
7
7
|
}
|
|
8
8
|
get length() { return this.impl.length; }
|
|
@@ -46,12 +46,12 @@ export class MvccArray extends MvccObject {
|
|
|
46
46
|
return this.impl;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
export class
|
|
49
|
+
export class AtomicArray extends MvccArray {
|
|
50
50
|
constructor(...args) {
|
|
51
51
|
super(false, new Array(...args));
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
-
export class
|
|
54
|
+
export class ObservableArray extends MvccArray {
|
|
55
55
|
constructor(...args) {
|
|
56
56
|
super(true, new Array(...args));
|
|
57
57
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MvccObject } from "./Mvcc.js";
|
|
2
2
|
export declare class MvccMap<K, V> extends MvccObject {
|
|
3
3
|
private impl;
|
|
4
|
-
constructor(
|
|
4
|
+
constructor(isObservable: boolean, map: Map<K, V>);
|
|
5
5
|
clear(): void;
|
|
6
6
|
delete(key: K): boolean;
|
|
7
7
|
forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
|
|
@@ -15,11 +15,11 @@ export declare class MvccMap<K, V> extends MvccObject {
|
|
|
15
15
|
[Symbol.toStringTag](): string;
|
|
16
16
|
private get mutable();
|
|
17
17
|
}
|
|
18
|
-
export declare class
|
|
18
|
+
export declare class AtomicMap<K, V> extends MvccMap<K, V> {
|
|
19
19
|
constructor();
|
|
20
20
|
constructor(iterable?: Iterable<readonly [K, V]> | null);
|
|
21
21
|
}
|
|
22
|
-
export declare class
|
|
22
|
+
export declare class ObservableMap<K, V> extends MvccMap<K, V> {
|
|
23
23
|
constructor();
|
|
24
24
|
constructor(iterable?: Iterable<readonly [K, V]> | null);
|
|
25
25
|
}
|