reactronic 0.22.106 → 0.22.110
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/LICENSE +1 -1
- package/README.md +16 -25
- package/build/dist/source/Options.d.ts +4 -4
- package/build/dist/source/Options.js +2 -2
- package/build/dist/source/Rx.d.ts +7 -7
- package/build/dist/source/Rx.js +6 -6
- package/build/dist/source/Trace.d.ts +8 -8
- package/build/dist/source/Trace.js +2 -2
- package/build/dist/source/api.d.ts +1 -1
- package/build/dist/source/api.js +2 -2
- package/build/dist/source/impl/Data.js +1 -1
- package/build/dist/source/impl/Hooks.d.ts +3 -3
- package/build/dist/source/impl/Hooks.js +8 -8
- package/build/dist/source/impl/Operation.js +55 -55
- package/build/dist/source/impl/Snapshot.js +23 -23
- package/build/dist/source/impl/Transaction.js +13 -13
- package/build/dist/source/util/Dbg.d.ts +10 -10
- package/build/dist/source/util/Dbg.js +26 -26
- package/build/dist/source/util/Sealant.js +2 -2
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (C) 2016-
|
|
3
|
+
Copyright (C) 2016-2022 Yury Chetyrko <ychetyrko@gmail.com>
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -302,29 +302,20 @@ function reaction(proto, prop, pd) // method only
|
|
|
302
302
|
function cached(proto, prop, pd) // method only
|
|
303
303
|
function options(value: Partial<MemberOptions>): F<any>
|
|
304
304
|
|
|
305
|
-
function noSideEffects(value: boolean) // transaction & cached & reaction
|
|
306
|
-
function sensitiveArgs(value: boolean) // cached & reaction
|
|
307
|
-
function throttling(milliseconds: number) // reaction only
|
|
308
|
-
function reentrance(value: Reentrance) // transaction & reaction
|
|
309
|
-
function monitor(value: Monitor | null)
|
|
310
|
-
function trace(value: Partial<TraceOptions>)
|
|
311
|
-
|
|
312
305
|
function nonreactive<T>(func: F<T>, ...args: any[]): T
|
|
313
306
|
function sensitive<T>(sensitivity: Sensitivity, func: F<T>, ...args: any[]): T
|
|
314
307
|
|
|
315
|
-
//
|
|
308
|
+
// SnapshotOptions, MemberOptions, Kind, Reentrance, Monitor, LoggingOptions, ProfilingOptions
|
|
316
309
|
|
|
317
|
-
interface
|
|
318
|
-
readonly
|
|
319
|
-
readonly
|
|
320
|
-
readonly
|
|
321
|
-
readonly
|
|
322
|
-
readonly
|
|
323
|
-
readonly monitor: Monitor | null
|
|
324
|
-
readonly trace?: Partial<TraceOptions>
|
|
310
|
+
export interface SnapshotOptions {
|
|
311
|
+
readonly hint?: string
|
|
312
|
+
readonly standalone?: StandaloneMode
|
|
313
|
+
readonly journal?: TransactionJournal
|
|
314
|
+
readonly logging?: Partial<LoggingOptions>
|
|
315
|
+
readonly token?: any
|
|
325
316
|
}
|
|
326
317
|
|
|
327
|
-
|
|
318
|
+
interface MemberOptions {
|
|
328
319
|
readonly kind: Kind
|
|
329
320
|
readonly standalone: StandaloneMode
|
|
330
321
|
readonly order: number
|
|
@@ -334,7 +325,7 @@ export interface MemberOptions {
|
|
|
334
325
|
readonly reentrance: Reentrance
|
|
335
326
|
readonly journal: TransactionJournal | undefined
|
|
336
327
|
readonly monitor: Monitor | null
|
|
337
|
-
readonly
|
|
328
|
+
readonly logging?: Partial<LoggingOptions>
|
|
338
329
|
}
|
|
339
330
|
|
|
340
331
|
enum Kind {
|
|
@@ -375,7 +366,7 @@ interface Worker {
|
|
|
375
366
|
whenFinished(): Promise<void>
|
|
376
367
|
}
|
|
377
368
|
|
|
378
|
-
interface
|
|
369
|
+
interface LoggingOptions {
|
|
379
370
|
readonly silent: boolean
|
|
380
371
|
readonly transaction: boolean
|
|
381
372
|
readonly operation: boolean
|
|
@@ -451,12 +442,12 @@ class Reactronic {
|
|
|
451
442
|
static takeSnapshot<T>(obj: T): T
|
|
452
443
|
static dispose(obj: any): void
|
|
453
444
|
static reactionsAutoStartDisabled: boolean
|
|
454
|
-
static readonly
|
|
455
|
-
static readonly
|
|
456
|
-
static
|
|
457
|
-
static
|
|
458
|
-
static
|
|
459
|
-
static setProfilingMode(
|
|
445
|
+
static readonly isLogging: boolean
|
|
446
|
+
static readonly loggingOptions: LoggingOptions
|
|
447
|
+
static setLoggingMode(isOn: boolean, options?: LoggingOptions)
|
|
448
|
+
static setLoggingHint<T extends object>(obj: T, name: string | undefined): void
|
|
449
|
+
static getLoggingHint<T extends object>(obj: T): string | undefined
|
|
450
|
+
static setProfilingMode(isOn: boolean, options?: Partial<ProfilingOptions>): void
|
|
460
451
|
}
|
|
461
452
|
|
|
462
453
|
```
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LoggingOptions } from './Trace';
|
|
2
2
|
import { StandaloneMode } from './impl/Data';
|
|
3
|
-
export {
|
|
3
|
+
export { LoggingOptions, ProfilingOptions, LoggingLevel } from './Trace';
|
|
4
4
|
import { TransactionJournal } from './impl/TransactionJournal';
|
|
5
5
|
import { Monitor } from './impl/Monitor';
|
|
6
6
|
export interface SnapshotOptions {
|
|
7
7
|
readonly hint?: string;
|
|
8
8
|
readonly standalone?: StandaloneMode;
|
|
9
9
|
readonly journal?: TransactionJournal;
|
|
10
|
-
readonly
|
|
10
|
+
readonly logging?: Partial<LoggingOptions>;
|
|
11
11
|
readonly token?: any;
|
|
12
12
|
}
|
|
13
13
|
export interface MemberOptions {
|
|
@@ -20,7 +20,7 @@ export interface MemberOptions {
|
|
|
20
20
|
readonly reentrance: Reentrance;
|
|
21
21
|
readonly journal: TransactionJournal | undefined;
|
|
22
22
|
readonly monitor: Monitor | null;
|
|
23
|
-
readonly
|
|
23
|
+
readonly logging?: Partial<LoggingOptions>;
|
|
24
24
|
}
|
|
25
25
|
export declare enum Kind {
|
|
26
26
|
Plain = 0,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Reentrance = exports.Kind = exports.
|
|
3
|
+
exports.Reentrance = exports.Kind = exports.LoggingLevel = void 0;
|
|
4
4
|
var Trace_1 = require("./Trace");
|
|
5
|
-
Object.defineProperty(exports, "
|
|
5
|
+
Object.defineProperty(exports, "LoggingLevel", { enumerable: true, get: function () { return Trace_1.LoggingLevel; } });
|
|
6
6
|
var Kind;
|
|
7
7
|
(function (Kind) {
|
|
8
8
|
Kind[Kind["Plain"] = 0] = "Plain";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { F } from './util/Utils';
|
|
2
2
|
import { Controller } from './Controller';
|
|
3
|
-
import { MemberOptions,
|
|
3
|
+
import { MemberOptions, LoggingOptions, ProfilingOptions } from './Options';
|
|
4
4
|
export declare class Rx {
|
|
5
5
|
static why(brief?: boolean): string;
|
|
6
6
|
static getController<T>(method: F<T>): Controller<T>;
|
|
@@ -10,12 +10,12 @@ export declare class Rx {
|
|
|
10
10
|
static dispose(obj: any): void;
|
|
11
11
|
static get reactionsAutoStartDisabled(): boolean;
|
|
12
12
|
static set reactionsAutoStartDisabled(value: boolean);
|
|
13
|
-
static get
|
|
14
|
-
static get
|
|
15
|
-
static
|
|
16
|
-
static
|
|
17
|
-
static
|
|
18
|
-
static setProfilingMode(
|
|
13
|
+
static get isLogging(): boolean;
|
|
14
|
+
static get loggingOptions(): LoggingOptions;
|
|
15
|
+
static setLoggingMode(isOn: boolean, options?: LoggingOptions): void;
|
|
16
|
+
static setLoggingHint<T extends object>(obj: T, name: string | undefined): void;
|
|
17
|
+
static getLoggingHint<T extends object>(obj: T, full?: boolean): string | undefined;
|
|
18
|
+
static setProfilingMode(isOn: boolean, options?: Partial<ProfilingOptions>): void;
|
|
19
19
|
}
|
|
20
20
|
export declare function nonreactive<T>(func: F<T>, ...args: any[]): T;
|
|
21
21
|
export declare function sensitive<T>(sensitivity: boolean, func: F<T>, ...args: any[]): T;
|
package/build/dist/source/Rx.js
CHANGED
|
@@ -16,12 +16,12 @@ class Rx {
|
|
|
16
16
|
static dispose(obj) { Snapshot_1.Snapshot.dispose(obj); }
|
|
17
17
|
static get reactionsAutoStartDisabled() { return Hooks_1.Hooks.reactionsAutoStartDisabled; }
|
|
18
18
|
static set reactionsAutoStartDisabled(value) { Hooks_1.Hooks.reactionsAutoStartDisabled = value; }
|
|
19
|
-
static get
|
|
20
|
-
static get
|
|
21
|
-
static
|
|
22
|
-
static
|
|
23
|
-
static
|
|
24
|
-
static setProfilingMode(
|
|
19
|
+
static get isLogging() { return Dbg_1.Log.isOn; }
|
|
20
|
+
static get loggingOptions() { return Dbg_1.Log.opt; }
|
|
21
|
+
static setLoggingMode(isOn, options) { Dbg_1.Log.setMode(isOn, options); }
|
|
22
|
+
static setLoggingHint(obj, name) { Hooks_1.Hooks.setHint(obj, name); }
|
|
23
|
+
static getLoggingHint(obj, full = false) { return Data_1.ObjectHolder.getHint(obj, full); }
|
|
24
|
+
static setProfilingMode(isOn, options) { Hooks_1.Hooks.setProfilingMode(isOn, options); }
|
|
25
25
|
}
|
|
26
26
|
exports.Rx = Rx;
|
|
27
27
|
function nonreactive(func, ...args) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export interface
|
|
1
|
+
export interface LoggingOptions {
|
|
2
2
|
readonly silent: boolean;
|
|
3
3
|
readonly transaction: boolean;
|
|
4
4
|
readonly operation: boolean;
|
|
@@ -22,13 +22,13 @@ export interface ProfilingOptions {
|
|
|
22
22
|
asyncActionDurationWarningThreshold: number;
|
|
23
23
|
garbageCollectionSummaryInterval: number;
|
|
24
24
|
}
|
|
25
|
-
export declare const
|
|
26
|
-
ErrorsOnly:
|
|
27
|
-
Reactions:
|
|
28
|
-
Transactions:
|
|
29
|
-
Operations:
|
|
30
|
-
Debug:
|
|
31
|
-
Silent:
|
|
25
|
+
export declare const LoggingLevel: {
|
|
26
|
+
ErrorsOnly: LoggingOptions;
|
|
27
|
+
Reactions: LoggingOptions;
|
|
28
|
+
Transactions: LoggingOptions;
|
|
29
|
+
Operations: LoggingOptions;
|
|
30
|
+
Debug: LoggingOptions;
|
|
31
|
+
Silent: LoggingOptions;
|
|
32
32
|
};
|
|
33
33
|
declare global {
|
|
34
34
|
interface Window {
|
|
@@ -2,7 +2,7 @@ export { all, pause } from './util/Utils';
|
|
|
2
2
|
export { SealedArray } from './util/SealedArray';
|
|
3
3
|
export { SealedMap } from './util/SealedMap';
|
|
4
4
|
export { SealedSet } from './util/SealedSet';
|
|
5
|
-
export { MemberOptions, Kind, Reentrance,
|
|
5
|
+
export { MemberOptions, SnapshotOptions, Kind, Reentrance, LoggingOptions, ProfilingOptions, LoggingLevel } from './Options';
|
|
6
6
|
export { Worker } from './Worker';
|
|
7
7
|
export { Controller } from './Controller';
|
|
8
8
|
export { Ref, ToggleRef, BoolOnly, GivenTypeOnly } from './Ref';
|
package/build/dist/source/api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.options = exports.cached = exports.reaction = exports.transaction = exports.unobservable = exports.sensitive = exports.nonreactive = exports.Rx = exports.TransactionJournal = exports.Monitor = exports.Transaction = exports.Snapshot = exports.ObservableObject = exports.ToggleRef = exports.Ref = exports.Controller = exports.
|
|
3
|
+
exports.options = exports.cached = exports.reaction = exports.transaction = exports.unobservable = exports.sensitive = exports.nonreactive = exports.Rx = exports.TransactionJournal = exports.Monitor = exports.Transaction = exports.Snapshot = exports.ObservableObject = exports.ToggleRef = exports.Ref = exports.Controller = exports.LoggingLevel = exports.Reentrance = exports.Kind = exports.SealedSet = exports.SealedMap = exports.SealedArray = exports.pause = exports.all = void 0;
|
|
4
4
|
var Utils_1 = require("./util/Utils");
|
|
5
5
|
Object.defineProperty(exports, "all", { enumerable: true, get: function () { return Utils_1.all; } });
|
|
6
6
|
Object.defineProperty(exports, "pause", { enumerable: true, get: function () { return Utils_1.pause; } });
|
|
@@ -13,7 +13,7 @@ Object.defineProperty(exports, "SealedSet", { enumerable: true, get: function ()
|
|
|
13
13
|
var Options_1 = require("./Options");
|
|
14
14
|
Object.defineProperty(exports, "Kind", { enumerable: true, get: function () { return Options_1.Kind; } });
|
|
15
15
|
Object.defineProperty(exports, "Reentrance", { enumerable: true, get: function () { return Options_1.Reentrance; } });
|
|
16
|
-
Object.defineProperty(exports, "
|
|
16
|
+
Object.defineProperty(exports, "LoggingLevel", { enumerable: true, get: function () { return Options_1.LoggingLevel; } });
|
|
17
17
|
var Controller_1 = require("./Controller");
|
|
18
18
|
Object.defineProperty(exports, "Controller", { enumerable: true, get: function () { return Controller_1.Controller; } });
|
|
19
19
|
var Ref_1 = require("./Ref");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { F } from '../util/Utils';
|
|
2
2
|
import { MemberOptions, Kind, Reentrance } from '../Options';
|
|
3
|
-
import {
|
|
3
|
+
import { LoggingOptions, ProfilingOptions } from '../Trace';
|
|
4
4
|
import { MemberName, ObjectHolder, StandaloneMode } from './Data';
|
|
5
5
|
import { TransactionJournal } from './TransactionJournal';
|
|
6
6
|
import { Monitor } from './Monitor';
|
|
@@ -20,7 +20,7 @@ export declare class OptionsImpl implements MemberOptions {
|
|
|
20
20
|
readonly reentrance: Reentrance;
|
|
21
21
|
readonly journal: TransactionJournal | undefined;
|
|
22
22
|
readonly monitor: Monitor | null;
|
|
23
|
-
readonly
|
|
23
|
+
readonly logging?: Partial<LoggingOptions>;
|
|
24
24
|
static readonly INITIAL: Readonly<OptionsImpl>;
|
|
25
25
|
constructor(getter: Function | undefined, setter: Function | undefined, existing: OptionsImpl, patch: Partial<OptionsImpl>, implicit: boolean);
|
|
26
26
|
}
|
|
@@ -42,7 +42,7 @@ export declare class Hooks implements ProxyHandler<ObjectHolder> {
|
|
|
42
42
|
static decorateOperationParametrized(decorator: Function, options: Partial<MemberOptions>): F<any>;
|
|
43
43
|
static acquireObjectHolder(obj: any): ObjectHolder;
|
|
44
44
|
static createObjectHolder(proto: any, unobservable: any, blank: any, hint: string): ObjectHolder;
|
|
45
|
-
static setProfilingMode(
|
|
45
|
+
static setProfilingMode(isOn: boolean, options?: Partial<ProfilingOptions>): void;
|
|
46
46
|
static sensitive<T>(sensitivity: boolean, func: F<T>, ...args: any[]): T;
|
|
47
47
|
static setHint<T>(obj: T, hint: string | undefined): T;
|
|
48
48
|
static createControllerAndGetHook: (h: ObjectHolder, m: MemberName, options: OptionsImpl) => F<any>;
|
|
@@ -29,7 +29,7 @@ const DEFAULT_OPTIONS = Object.freeze({
|
|
|
29
29
|
reentrance: Options_1.Reentrance.PreventWithError,
|
|
30
30
|
journal: undefined,
|
|
31
31
|
monitor: null,
|
|
32
|
-
|
|
32
|
+
logging: undefined,
|
|
33
33
|
});
|
|
34
34
|
class OptionsImpl {
|
|
35
35
|
constructor(getter, setter, existing, patch, implicit) {
|
|
@@ -44,8 +44,8 @@ class OptionsImpl {
|
|
|
44
44
|
this.reentrance = merge(DEFAULT_OPTIONS.reentrance, existing.reentrance, patch.reentrance, implicit);
|
|
45
45
|
this.journal = merge(DEFAULT_OPTIONS.journal, existing.journal, patch.journal, implicit);
|
|
46
46
|
this.monitor = merge(DEFAULT_OPTIONS.monitor, existing.monitor, patch.monitor, implicit);
|
|
47
|
-
this.
|
|
48
|
-
if (Dbg_1.
|
|
47
|
+
this.logging = merge(DEFAULT_OPTIONS.logging, existing.logging, patch.logging, implicit);
|
|
48
|
+
if (Dbg_1.Log.isOn)
|
|
49
49
|
Object.freeze(this);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -175,7 +175,7 @@ class Hooks {
|
|
|
175
175
|
const initial = Data_1.Meta.getFrom(Object.getPrototypeOf(obj), Data_1.Meta.Initial);
|
|
176
176
|
const rev = new Data_1.ObjectRevision(Snapshot_1.ROOT_REV.snapshot, Snapshot_1.ROOT_REV, Object.assign({}, initial));
|
|
177
177
|
Data_1.Meta.set(rev.data, Data_1.Meta.Holder, h);
|
|
178
|
-
if (Dbg_1.
|
|
178
|
+
if (Dbg_1.Log.isOn)
|
|
179
179
|
Snapshot_1.Snapshot.freezeObjectRevision(rev);
|
|
180
180
|
h = new Data_1.ObjectHolder(obj, obj, Hooks.proxy, rev, obj.constructor.name);
|
|
181
181
|
Data_1.Meta.set(obj, Data_1.Meta.Holder, h);
|
|
@@ -191,11 +191,11 @@ class Hooks {
|
|
|
191
191
|
h.proxy[m][Data_1.Meta.Controller].markObsolete();
|
|
192
192
|
return h;
|
|
193
193
|
}
|
|
194
|
-
static setProfilingMode(
|
|
195
|
-
if (
|
|
194
|
+
static setProfilingMode(isOn, options) {
|
|
195
|
+
if (isOn) {
|
|
196
196
|
Hooks.repetitiveUsageWarningThreshold = options && options.repetitiveUsageWarningThreshold !== undefined ? options.repetitiveUsageWarningThreshold : 10;
|
|
197
|
-
Hooks.mainThreadBlockingWarningThreshold = options && options.mainThreadBlockingWarningThreshold !== undefined ? options.mainThreadBlockingWarningThreshold :
|
|
198
|
-
Hooks.asyncActionDurationWarningThreshold = options && options.asyncActionDurationWarningThreshold !== undefined ? options.asyncActionDurationWarningThreshold :
|
|
197
|
+
Hooks.mainThreadBlockingWarningThreshold = options && options.mainThreadBlockingWarningThreshold !== undefined ? options.mainThreadBlockingWarningThreshold : 14;
|
|
198
|
+
Hooks.asyncActionDurationWarningThreshold = options && options.asyncActionDurationWarningThreshold !== undefined ? options.asyncActionDurationWarningThreshold : 300;
|
|
199
199
|
Snapshot_1.Snapshot.garbageCollectionSummaryInterval = options && options.garbageCollectionSummaryInterval !== undefined ? options.garbageCollectionSummaryInterval : 100;
|
|
200
200
|
}
|
|
201
201
|
else {
|
|
@@ -27,7 +27,7 @@ class OperationController extends Controller_1.Controller {
|
|
|
27
27
|
get error() { return this.use().operation.error; }
|
|
28
28
|
get stamp() { return this.use().revision.snapshot.timestamp; }
|
|
29
29
|
get isUpToDate() { return this.use().isUpToDate; }
|
|
30
|
-
markObsolete() { Transaction_1.Transaction.run({ hint: Dbg_1.
|
|
30
|
+
markObsolete() { Transaction_1.Transaction.run({ hint: Dbg_1.Log.isOn ? `markObsolete(${Snapshot_1.Dump.obj(this.ownHolder, this.memberName)})` : 'markObsolete()' }, OperationController.markObsolete, this); }
|
|
31
31
|
pullLastResult(args) { return this.useOrRun(true, args).value; }
|
|
32
32
|
useOrRun(weak, args) {
|
|
33
33
|
var _a;
|
|
@@ -49,9 +49,9 @@ class OperationController extends Controller_1.Controller {
|
|
|
49
49
|
if (!weak || ctx === ctx2 || (ctx2.sealed && ctx.timestamp >= ctx2.timestamp))
|
|
50
50
|
oc = oc2;
|
|
51
51
|
}
|
|
52
|
-
else if (Dbg_1.
|
|
53
|
-
opts.
|
|
54
|
-
Dbg_1.
|
|
52
|
+
else if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation && (opts.logging === undefined ||
|
|
53
|
+
opts.logging.operation === undefined || opts.logging.operation === true))
|
|
54
|
+
Dbg_1.Log.write(Transaction_1.Transaction.current.isFinished ? '' : '║', ' (=)', `${Snapshot_1.Dump.rev2(oc.operation.controller.ownHolder, oc.snapshot, this.memberName)} result is reused from T${oc.operation.transaction.id}[${oc.operation.transaction.hint}]`);
|
|
55
55
|
const t = oc.operation;
|
|
56
56
|
Snapshot_1.Snapshot.markUsed(t, oc.revision, this.memberName, this.ownHolder, t.options.kind, weak);
|
|
57
57
|
return t;
|
|
@@ -71,8 +71,8 @@ class OperationController extends Controller_1.Controller {
|
|
|
71
71
|
if (!op || op.transaction.isFinished)
|
|
72
72
|
throw (0, Dbg_1.misuse)('a method is expected with reactronic decorator');
|
|
73
73
|
op.options = new Hooks_1.OptionsImpl(op.options.getter, op.options.setter, op.options, options, false);
|
|
74
|
-
if (Dbg_1.
|
|
75
|
-
Dbg_1.
|
|
74
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.write)
|
|
75
|
+
Dbg_1.Log.write('║', ' ✎', `${op.hint()}.options are changed`);
|
|
76
76
|
return op.options;
|
|
77
77
|
}
|
|
78
78
|
static runWithin(op, func, ...args) {
|
|
@@ -139,7 +139,7 @@ class OperationController extends Controller_1.Controller {
|
|
|
139
139
|
const m = this.memberName;
|
|
140
140
|
let op = r.data[m];
|
|
141
141
|
if (op.controller !== this) {
|
|
142
|
-
const hint = Dbg_1.
|
|
142
|
+
const hint = Dbg_1.Log.isOn ? `${Snapshot_1.Dump.obj(this.ownHolder, m)}/boot` : 'MethodController/init';
|
|
143
143
|
const standalone = r.snapshot.sealed || r.prev.revision !== Snapshot_1.ROOT_REV;
|
|
144
144
|
op = Transaction_1.Transaction.run({ hint, standalone, token: this }, () => {
|
|
145
145
|
const h = this.ownHolder;
|
|
@@ -161,22 +161,22 @@ class OperationController extends Controller_1.Controller {
|
|
|
161
161
|
return op;
|
|
162
162
|
}
|
|
163
163
|
run(existing, standalone, options, token, args) {
|
|
164
|
-
const hint = Dbg_1.
|
|
164
|
+
const hint = Dbg_1.Log.isOn ? `${Snapshot_1.Dump.obj(this.ownHolder, this.memberName)}${args && args.length > 0 && (typeof args[0] === 'number' || typeof args[0] === 'string') ? ` - ${args[0]}` : ''}` : `${Snapshot_1.Dump.obj(this.ownHolder, this.memberName)}`;
|
|
165
165
|
let oc = existing;
|
|
166
|
-
const opts = { hint, standalone, journal: options.journal,
|
|
166
|
+
const opts = { hint, standalone, journal: options.journal, logging: options.logging, token };
|
|
167
167
|
const result = Transaction_1.Transaction.run(opts, (argsx) => {
|
|
168
168
|
if (!oc.operation.transaction.isCanceled) {
|
|
169
169
|
oc = this.edit();
|
|
170
|
-
if (Dbg_1.
|
|
171
|
-
Dbg_1.
|
|
170
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation)
|
|
171
|
+
Dbg_1.Log.write('║', ' 𝑓', `${oc.operation.why()}`);
|
|
172
172
|
oc.operation.run(this.ownHolder.proxy, argsx);
|
|
173
173
|
}
|
|
174
174
|
else {
|
|
175
175
|
oc = this.peek(argsx);
|
|
176
176
|
if (oc.operation.options.kind === Options_1.Kind.Transaction || !oc.isUpToDate) {
|
|
177
177
|
oc = this.edit();
|
|
178
|
-
if (Dbg_1.
|
|
179
|
-
Dbg_1.
|
|
178
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation)
|
|
179
|
+
Dbg_1.Log.write('║', ' 𝑓', `${oc.operation.why()}`);
|
|
180
180
|
oc.operation.run(this.ownHolder.proxy, argsx);
|
|
181
181
|
}
|
|
182
182
|
}
|
|
@@ -240,15 +240,15 @@ class Operation extends Data_1.Observable {
|
|
|
240
240
|
}
|
|
241
241
|
wrap(func) {
|
|
242
242
|
const wrappedForOperation = (...args) => {
|
|
243
|
-
if (Dbg_1.
|
|
244
|
-
Dbg_1.
|
|
243
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.step && this.result)
|
|
244
|
+
Dbg_1.Log.writeAs({ margin2: this.margin }, '║', '‾\\', `${this.hint()} - step in `, 0, ' │');
|
|
245
245
|
const started = Date.now();
|
|
246
246
|
const result = OperationController.runWithin(this, func, ...args);
|
|
247
247
|
const ms = Date.now() - started;
|
|
248
|
-
if (Dbg_1.
|
|
249
|
-
Dbg_1.
|
|
248
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.step && this.result)
|
|
249
|
+
Dbg_1.Log.writeAs({ margin2: this.margin }, '║', '_/', `${this.hint()} - step out `, 0, this.started > 0 ? ' │' : '');
|
|
250
250
|
if (ms > Hooks_1.Hooks.mainThreadBlockingWarningThreshold)
|
|
251
|
-
Dbg_1.
|
|
251
|
+
Dbg_1.Log.write('', '[!]', this.why(), ms, ' *** main thread is too busy ***');
|
|
252
252
|
return result;
|
|
253
253
|
};
|
|
254
254
|
return wrappedForOperation;
|
|
@@ -273,8 +273,8 @@ class Operation extends Data_1.Observable {
|
|
|
273
273
|
this.obsoleteDueTo = why;
|
|
274
274
|
this.obsoleteSince = since;
|
|
275
275
|
const isReaction = this.options.kind === Options_1.Kind.Reaction;
|
|
276
|
-
if (Dbg_1.
|
|
277
|
-
Dbg_1.
|
|
276
|
+
if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.obsolete || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.obsolete)))
|
|
277
|
+
Dbg_1.Log.write(Dbg_1.Log.opt.transaction && !Snapshot_1.Snapshot.current().sealed ? '║' : ' ', isReaction ? '█' : '▒', isReaction && snapshot === Snapshot_1.ROOT_REV.snapshot
|
|
278
278
|
? `${this.hint()} is a reaction and will run automatically (order ${this.options.order})`
|
|
279
279
|
: `${this.hint()} is obsolete due to ${Snapshot_1.Dump.rev2(holder, snapshot, memberName)} since v${since}${isReaction ? ` and will run automatically (order ${this.options.order})` : ''}`);
|
|
280
280
|
if (isReaction)
|
|
@@ -287,8 +287,8 @@ class Operation extends Data_1.Observable {
|
|
|
287
287
|
else if (!tran.isFinished && this !== observable)
|
|
288
288
|
tran.cancel(new Error(`T${tran.id}[${tran.hint}] is canceled due to obsolete ${Snapshot_1.Dump.rev2(holder, snapshot, memberName)} changed by T${snapshot.id}[${snapshot.hint}]`), null);
|
|
289
289
|
}
|
|
290
|
-
else if (Dbg_1.
|
|
291
|
-
Dbg_1.
|
|
290
|
+
else if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.obsolete || ((_c = this.options.logging) === null || _c === void 0 ? void 0 : _c.obsolete)))
|
|
291
|
+
Dbg_1.Log.write(' ', 'x', `${this.hint()} is not obsolete due to its own change to ${Snapshot_1.Dump.rev2(holder, snapshot, memberName)}`);
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
294
|
runIfNotUpToDate(now, nothrow) {
|
|
@@ -328,8 +328,8 @@ class Operation extends Data_1.Observable {
|
|
|
328
328
|
let error = undefined;
|
|
329
329
|
const opponent = head.successor;
|
|
330
330
|
if (opponent && !opponent.transaction.isFinished) {
|
|
331
|
-
if (Dbg_1.
|
|
332
|
-
Dbg_1.
|
|
331
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.obsolete)
|
|
332
|
+
Dbg_1.Log.write('║', ' [!]', `${this.hint()} is trying to re-enter over ${opponent.hint()}`);
|
|
333
333
|
switch (head.options.reentrance) {
|
|
334
334
|
case Options_1.Reentrance.PreventWithError:
|
|
335
335
|
if (!opponent.transaction.isCanceled)
|
|
@@ -371,8 +371,8 @@ class Operation extends Data_1.Observable {
|
|
|
371
371
|
enter() {
|
|
372
372
|
if (this.options.monitor)
|
|
373
373
|
this.monitorEnter(this.options.monitor);
|
|
374
|
-
if (Dbg_1.
|
|
375
|
-
Dbg_1.
|
|
374
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation)
|
|
375
|
+
Dbg_1.Log.write('║', '‾\\', `${this.hint()} - enter`, undefined, ` [ ${Snapshot_1.Dump.obj(this.controller.ownHolder, this.controller.memberName)} ]`);
|
|
376
376
|
this.started = Date.now();
|
|
377
377
|
}
|
|
378
378
|
leaveOrAsync() {
|
|
@@ -386,11 +386,11 @@ class Operation extends Data_1.Observable {
|
|
|
386
386
|
this.leave(false, ' ⚐', '- finished ', 'ERR ──┘');
|
|
387
387
|
throw error;
|
|
388
388
|
});
|
|
389
|
-
if (Dbg_1.
|
|
390
|
-
if (Dbg_1.
|
|
391
|
-
Dbg_1.
|
|
392
|
-
else if (Dbg_1.
|
|
393
|
-
Dbg_1.
|
|
389
|
+
if (Dbg_1.Log.isOn) {
|
|
390
|
+
if (Dbg_1.Log.opt.operation)
|
|
391
|
+
Dbg_1.Log.write('║', '_/', `${this.hint()} - leave... `, 0, 'ASYNC ──┐');
|
|
392
|
+
else if (Dbg_1.Log.opt.transaction)
|
|
393
|
+
Dbg_1.Log.write('║', ' ', `${this.why()} ...`, 0, 'ASYNC');
|
|
394
394
|
}
|
|
395
395
|
}
|
|
396
396
|
else {
|
|
@@ -401,10 +401,10 @@ class Operation extends Data_1.Observable {
|
|
|
401
401
|
leave(main, op, message, highlight = undefined) {
|
|
402
402
|
const ms = Date.now() - this.started;
|
|
403
403
|
this.started = -this.started;
|
|
404
|
-
if (Dbg_1.
|
|
405
|
-
Dbg_1.
|
|
404
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation)
|
|
405
|
+
Dbg_1.Log.write('║', `${op}`, `${this.hint()} ${message}`, ms, highlight);
|
|
406
406
|
if (ms > (main ? Hooks_1.Hooks.mainThreadBlockingWarningThreshold : Hooks_1.Hooks.asyncActionDurationWarningThreshold))
|
|
407
|
-
Dbg_1.
|
|
407
|
+
Dbg_1.Log.write('', '[!]', this.why(), ms, main ? ' *** main thread is too busy ***' : ' *** async is too long ***');
|
|
408
408
|
this.cause = undefined;
|
|
409
409
|
if (this.options.monitor)
|
|
410
410
|
this.monitorLeave(this.options.monitor);
|
|
@@ -413,7 +413,7 @@ class Operation extends Data_1.Observable {
|
|
|
413
413
|
const options = {
|
|
414
414
|
hint: 'Monitor.enter',
|
|
415
415
|
standalone: 'isolated',
|
|
416
|
-
|
|
416
|
+
logging: Dbg_1.Log.isOn && Dbg_1.Log.opt.monitor ? undefined : Dbg_1.Log.global
|
|
417
417
|
};
|
|
418
418
|
OperationController.runWithin(undefined, Transaction_1.Transaction.run, options, Monitor_1.MonitorImpl.enter, mon, this.transaction);
|
|
419
419
|
}
|
|
@@ -423,7 +423,7 @@ class Operation extends Data_1.Observable {
|
|
|
423
423
|
const options = {
|
|
424
424
|
hint: 'Monitor.leave',
|
|
425
425
|
standalone: 'isolated',
|
|
426
|
-
|
|
426
|
+
logging: Dbg_1.Log.isOn && Dbg_1.Log.opt.monitor ? undefined : Dbg_1.Log.DefaultLevel
|
|
427
427
|
};
|
|
428
428
|
OperationController.runWithin(undefined, Transaction_1.Transaction.run, options, Monitor_1.MonitorImpl.leave, mon, this.transaction);
|
|
429
429
|
};
|
|
@@ -457,8 +457,8 @@ class Operation extends Data_1.Observable {
|
|
|
457
457
|
}
|
|
458
458
|
static markEdited(oldValue, newValue, edited, r, m, h) {
|
|
459
459
|
edited ? r.changes.add(m) : r.changes.delete(m);
|
|
460
|
-
if (Dbg_1.
|
|
461
|
-
edited ? Dbg_1.
|
|
460
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.write)
|
|
461
|
+
edited ? Dbg_1.Log.write('║', ' ✎', `${Snapshot_1.Dump.rev2(h, r.snapshot, m)} is changed from ${valueHint(oldValue, m)} to ${valueHint(newValue, m)}`) : Dbg_1.Log.write('║', ' ✎', `${Snapshot_1.Dump.rev2(h, r.snapshot, m)} is changed from ${valueHint(oldValue, m)} to ${valueHint(newValue, m)}`, undefined, ' (same as previous)');
|
|
462
462
|
}
|
|
463
463
|
static isConflicting(oldValue, newValue) {
|
|
464
464
|
let result = oldValue !== newValue;
|
|
@@ -512,7 +512,7 @@ class Operation extends Data_1.Observable {
|
|
|
512
512
|
if (Hooks_1.Hooks.repetitiveUsageWarningThreshold < Number.MAX_SAFE_INTEGER) {
|
|
513
513
|
curr.observables.forEach((info, v) => {
|
|
514
514
|
if (info.usageCount > Hooks_1.Hooks.repetitiveUsageWarningThreshold)
|
|
515
|
-
Dbg_1.
|
|
515
|
+
Dbg_1.Log.write('', '[!]', `${curr.hint()} uses ${info.memberHint} ${info.usageCount} times (consider remembering it in a local variable)`, 0, ' *** WARNING ***');
|
|
516
516
|
});
|
|
517
517
|
}
|
|
518
518
|
if (unsubscribe)
|
|
@@ -522,8 +522,8 @@ class Operation extends Data_1.Observable {
|
|
|
522
522
|
else if (curr instanceof Data_1.Observable && curr.observers) {
|
|
523
523
|
curr.observers.forEach(o => {
|
|
524
524
|
o.observables.delete(curr);
|
|
525
|
-
if (Dbg_1.
|
|
526
|
-
Dbg_1.
|
|
525
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.read)
|
|
526
|
+
Dbg_1.Log.write(Dbg_1.Log.opt.transaction && !Snapshot_1.Snapshot.current().sealed ? '║' : ' ', '-', `${o.hint()} is unsubscribed from own-changed ${Snapshot_1.Dump.rev(r, m)}`);
|
|
527
527
|
});
|
|
528
528
|
curr.observers = undefined;
|
|
529
529
|
}
|
|
@@ -551,8 +551,8 @@ class Operation extends Data_1.Observable {
|
|
|
551
551
|
(_a = this.observables) === null || _a === void 0 ? void 0 : _a.forEach((info, value) => {
|
|
552
552
|
var _a;
|
|
553
553
|
value.observers.delete(this);
|
|
554
|
-
if (Dbg_1.
|
|
555
|
-
Dbg_1.
|
|
554
|
+
if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.read || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.read)))
|
|
555
|
+
Dbg_1.Log.write(Dbg_1.Log.opt.transaction && !Snapshot_1.Snapshot.current().sealed ? '║' : ' ', '-', `${this.hint()} is unsubscribed from ${info.memberHint}`);
|
|
556
556
|
});
|
|
557
557
|
this.observables = undefined;
|
|
558
558
|
}
|
|
@@ -571,15 +571,15 @@ class Operation extends Data_1.Observable {
|
|
|
571
571
|
const info = { memberHint: Snapshot_1.Dump.rev2(h, r.snapshot, m), usageCount: times };
|
|
572
572
|
observable.observers.add(this);
|
|
573
573
|
this.observables.set(observable, info);
|
|
574
|
-
if (Dbg_1.
|
|
575
|
-
Dbg_1.
|
|
574
|
+
if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.read || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.read)))
|
|
575
|
+
Dbg_1.Log.write('║', ' ∞ ', `${this.hint()} is subscribed to ${Snapshot_1.Dump.rev2(h, r.snapshot, m)}${info.usageCount > 1 ? ` (${info.usageCount} times)` : ''}`);
|
|
576
576
|
}
|
|
577
|
-
else if (Dbg_1.
|
|
578
|
-
Dbg_1.
|
|
577
|
+
else if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.read || ((_b = this.options.logging) === null || _b === void 0 ? void 0 : _b.read)))
|
|
578
|
+
Dbg_1.Log.write('║', ' x ', `${this.hint()} is obsolete and is NOT subscribed to ${Snapshot_1.Dump.rev2(h, r.snapshot, m)}`);
|
|
579
579
|
}
|
|
580
580
|
else {
|
|
581
|
-
if (Dbg_1.
|
|
582
|
-
Dbg_1.
|
|
581
|
+
if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.read || ((_c = this.options.logging) === null || _c === void 0 ? void 0 : _c.read)))
|
|
582
|
+
Dbg_1.Log.write('║', ' x ', `${this.hint()} is NOT subscribed to already obsolete ${Snapshot_1.Dump.rev2(h, r.snapshot, m)}`);
|
|
583
583
|
}
|
|
584
584
|
return ok;
|
|
585
585
|
}
|
|
@@ -615,7 +615,7 @@ class Operation extends Data_1.Observable {
|
|
|
615
615
|
}
|
|
616
616
|
static init() {
|
|
617
617
|
Object.freeze(ROOT_ARGS);
|
|
618
|
-
Dbg_1.
|
|
618
|
+
Dbg_1.Log.getMergedLoggingOptions = getMergedLoggingOptions;
|
|
619
619
|
Snapshot_1.Snapshot.markUsed = Operation.markUsed;
|
|
620
620
|
Snapshot_1.Snapshot.markEdited = Operation.markEdited;
|
|
621
621
|
Snapshot_1.Snapshot.isConflicting = Operation.isConflicting;
|
|
@@ -668,14 +668,14 @@ function valueHint(value, m) {
|
|
|
668
668
|
result = '∅';
|
|
669
669
|
return result;
|
|
670
670
|
}
|
|
671
|
-
function
|
|
671
|
+
function getMergedLoggingOptions(local) {
|
|
672
672
|
const t = Transaction_1.Transaction.current;
|
|
673
|
-
let res = Dbg_1.
|
|
674
|
-
res = Dbg_1.
|
|
673
|
+
let res = Dbg_1.Log.merge(t.options.logging, t.id > 1 ? 31 + t.id % 6 : 37, t.id > 1 ? `T${t.id}` : `-${Snapshot_1.Snapshot.idGen.toString().replace(/[0-9]/g, '-')}`, Dbg_1.Log.global);
|
|
674
|
+
res = Dbg_1.Log.merge({ margin1: t.margin }, undefined, undefined, res);
|
|
675
675
|
if (Operation.current)
|
|
676
|
-
res = Dbg_1.
|
|
676
|
+
res = Dbg_1.Log.merge({ margin2: Operation.current.margin }, undefined, undefined, res);
|
|
677
677
|
if (local)
|
|
678
|
-
res = Dbg_1.
|
|
678
|
+
res = Dbg_1.Log.merge(local, undefined, undefined, res);
|
|
679
679
|
return res;
|
|
680
680
|
}
|
|
681
681
|
const ORIGINAL_PROMISE_THEN = Promise.prototype.then;
|
|
@@ -73,8 +73,8 @@ class Snapshot {
|
|
|
73
73
|
this.changeset.set(h, r);
|
|
74
74
|
h.editing = r;
|
|
75
75
|
h.editors++;
|
|
76
|
-
if (Dbg_1.
|
|
77
|
-
Dbg_1.
|
|
76
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.write)
|
|
77
|
+
Dbg_1.Log.write('║', ' ⎘', `${Dump.obj(h)} is cloned`);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
else
|
|
@@ -117,8 +117,8 @@ class Snapshot {
|
|
|
117
117
|
Snapshot.pending.push(this);
|
|
118
118
|
if (Snapshot.oldest === undefined)
|
|
119
119
|
Snapshot.oldest = this;
|
|
120
|
-
if (Dbg_1.
|
|
121
|
-
Dbg_1.
|
|
120
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.transaction)
|
|
121
|
+
Dbg_1.Log.write('╔══', `v${this.stamp}`, `${this.hint}`);
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
bumpBy(timestamp) {
|
|
@@ -136,8 +136,8 @@ class Snapshot {
|
|
|
136
136
|
conflicts = [];
|
|
137
137
|
conflicts.push(r);
|
|
138
138
|
}
|
|
139
|
-
if (Dbg_1.
|
|
140
|
-
Dbg_1.
|
|
139
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.transaction)
|
|
140
|
+
Dbg_1.Log.write('╠╝', '', `${Dump.rev2(h, r.snapshot)} is merged with ${Dump.rev2(h, h.head.snapshot)} among ${merged} properties with ${r.conflicts.size} conflicts.`);
|
|
141
141
|
}
|
|
142
142
|
});
|
|
143
143
|
if (this.options.token === undefined) {
|
|
@@ -165,8 +165,8 @@ class Snapshot {
|
|
|
165
165
|
if (headDisposed || m === Data_1.Meta.Disposed) {
|
|
166
166
|
if (headDisposed !== (m === Data_1.Meta.Disposed)) {
|
|
167
167
|
if (headDisposed || this.options.standalone !== 'disposal') {
|
|
168
|
-
if (Dbg_1.
|
|
169
|
-
Dbg_1.
|
|
168
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.change)
|
|
169
|
+
Dbg_1.Log.write('║╠', '', `${Dump.rev2(h, ours.snapshot, m)} <> ${Dump.rev2(h, head.snapshot, m)}`, 0, ' *** CONFLICT ***');
|
|
170
170
|
ours.conflicts.set(m, head);
|
|
171
171
|
}
|
|
172
172
|
}
|
|
@@ -175,8 +175,8 @@ class Snapshot {
|
|
|
175
175
|
const conflict = Snapshot.isConflicting(head.data[m], ours.prev.revision.data[m]);
|
|
176
176
|
if (conflict)
|
|
177
177
|
ours.conflicts.set(m, head);
|
|
178
|
-
if (Dbg_1.
|
|
179
|
-
Dbg_1.
|
|
178
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.change)
|
|
179
|
+
Dbg_1.Log.write('║╠', '', `${Dump.rev2(h, ours.snapshot, m)} ${conflict ? '<>' : '=='} ${Dump.rev2(h, head.snapshot, m)}`, 0, conflict ? ' *** CONFLICT ***' : undefined);
|
|
180
180
|
}
|
|
181
181
|
});
|
|
182
182
|
Utils_1.Utils.copyAllMembers(merged, ours.data);
|
|
@@ -199,17 +199,17 @@ class Snapshot {
|
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
201
|
});
|
|
202
|
-
if (Dbg_1.
|
|
203
|
-
if (Dbg_1.
|
|
202
|
+
if (Dbg_1.Log.isOn) {
|
|
203
|
+
if (Dbg_1.Log.opt.change && !error) {
|
|
204
204
|
this.changeset.forEach((r, h) => {
|
|
205
205
|
const members = [];
|
|
206
206
|
r.changes.forEach((o, m) => members.push(m.toString()));
|
|
207
207
|
const s = members.join(', ');
|
|
208
|
-
Dbg_1.
|
|
208
|
+
Dbg_1.Log.write('║', '√', `${Dump.rev2(h, r.snapshot)} (${s}) is ${r.prev.revision === exports.ROOT_REV ? 'constructed' : `applied on top of ${Dump.rev2(h, r.prev.revision.snapshot)}`}`);
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
|
-
if (Dbg_1.
|
|
212
|
-
Dbg_1.
|
|
211
|
+
if (Dbg_1.Log.opt.transaction)
|
|
212
|
+
Dbg_1.Log.write(this.stamp < exports.UNDEFINED_TIMESTAMP ? '╚══' : '═══', `v${this.stamp}`, `${this.hint} - ${error ? 'CANCEL' : 'APPLY'}(${this.changeset.size})${error ? ` - ${error}` : ''}`);
|
|
213
213
|
}
|
|
214
214
|
if (!error)
|
|
215
215
|
Snapshot.propagateAllChangesThroughSubscriptions(this);
|
|
@@ -221,7 +221,7 @@ class Snapshot {
|
|
|
221
221
|
else
|
|
222
222
|
for (const m in r.prev.revision.data)
|
|
223
223
|
r.data[m] = Data_1.Meta.Disposed;
|
|
224
|
-
if (Dbg_1.
|
|
224
|
+
if (Dbg_1.Log.isOn)
|
|
225
225
|
Snapshot.freezeObjectRevision(r);
|
|
226
226
|
}
|
|
227
227
|
static sealObservable(observable, m, typeName) {
|
|
@@ -254,18 +254,18 @@ class Snapshot {
|
|
|
254
254
|
Snapshot.oldest = Snapshot.pending[0];
|
|
255
255
|
const now = Date.now();
|
|
256
256
|
if (now - Snapshot.lastGarbageCollectionSummaryTimestamp > Snapshot.garbageCollectionSummaryInterval) {
|
|
257
|
-
Dbg_1.
|
|
257
|
+
Dbg_1.Log.write('', '[G]', `Total object/revision count: ${Snapshot.totalObjectHolderCount}/${Snapshot.totalObjectRevisionCount}`);
|
|
258
258
|
Snapshot.lastGarbageCollectionSummaryTimestamp = now;
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
263
|
unlinkHistory() {
|
|
264
|
-
if (Dbg_1.
|
|
265
|
-
Dbg_1.
|
|
264
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.gc)
|
|
265
|
+
Dbg_1.Log.write('', '[G]', `Dismiss history below v${this.stamp}t${this.id} (${this.hint})`);
|
|
266
266
|
this.changeset.forEach((r, h) => {
|
|
267
|
-
if (Dbg_1.
|
|
268
|
-
Dbg_1.
|
|
267
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.gc && r.prev.revision !== exports.ROOT_REV)
|
|
268
|
+
Dbg_1.Log.write(' ', ' ', `${Dump.rev2(h, r.prev.revision.snapshot)} is ready for GC because overwritten by ${Dump.rev2(h, r.snapshot)}`);
|
|
269
269
|
if (Snapshot.garbageCollectionSummaryInterval < Number.MAX_SAFE_INTEGER) {
|
|
270
270
|
if (r.prev.revision !== exports.ROOT_REV)
|
|
271
271
|
Snapshot.totalObjectRevisionCount--;
|
|
@@ -276,7 +276,7 @@ class Snapshot {
|
|
|
276
276
|
});
|
|
277
277
|
this.changeset = EMPTY_MAP;
|
|
278
278
|
this.reactions = EMPTY_ARRAY;
|
|
279
|
-
if (Dbg_1.
|
|
279
|
+
if (Dbg_1.Log.isOn)
|
|
280
280
|
Object.freeze(this);
|
|
281
281
|
}
|
|
282
282
|
static _init() {
|
|
@@ -344,6 +344,6 @@ exports.DefaultSnapshotOptions = Object.freeze({
|
|
|
344
344
|
hint: 'noname',
|
|
345
345
|
standalone: false,
|
|
346
346
|
journal: undefined,
|
|
347
|
-
|
|
347
|
+
logging: undefined,
|
|
348
348
|
token: undefined,
|
|
349
349
|
});
|
|
@@ -22,7 +22,7 @@ class Transaction {
|
|
|
22
22
|
static run(options, func, ...args) { return TransactionImpl.run(options, func, ...args); }
|
|
23
23
|
static standalone(func, ...args) { return TransactionImpl.standalone(func, ...args); }
|
|
24
24
|
static off(func, ...args) { return TransactionImpl.off(func, ...args); }
|
|
25
|
-
static isFrameOver(everyN = 1, timeLimit =
|
|
25
|
+
static isFrameOver(everyN = 1, timeLimit = 10) { return TransactionImpl.isFrameOver(everyN, timeLimit); }
|
|
26
26
|
static requestNextFrame(sleepTime = 0) { return TransactionImpl.requestNextFrame(sleepTime); }
|
|
27
27
|
static get isCanceled() { return TransactionImpl.current.isCanceled; }
|
|
28
28
|
}
|
|
@@ -54,8 +54,8 @@ class TransactionImpl extends Transaction {
|
|
|
54
54
|
const restore = TransactionImpl.inspection;
|
|
55
55
|
try {
|
|
56
56
|
TransactionImpl.inspection = true;
|
|
57
|
-
if (Dbg_1.
|
|
58
|
-
Dbg_1.
|
|
57
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.transaction)
|
|
58
|
+
Dbg_1.Log.write(' ', ' ', `T${this.id}[${this.hint}] is being inspected by T${TransactionImpl.curr.id}[${TransactionImpl.curr.hint}]`);
|
|
59
59
|
return this.runImpl(undefined, func, ...args);
|
|
60
60
|
}
|
|
61
61
|
finally {
|
|
@@ -119,7 +119,7 @@ class TransactionImpl extends Transaction {
|
|
|
119
119
|
const t = TransactionImpl.acquire(options);
|
|
120
120
|
const root = t !== TransactionImpl.curr;
|
|
121
121
|
t.guard();
|
|
122
|
-
let result = t.runImpl(options === null || options === void 0 ? void 0 : options.
|
|
122
|
+
let result = t.runImpl(options === null || options === void 0 ? void 0 : options.logging, func, ...args);
|
|
123
123
|
if (root) {
|
|
124
124
|
if (result instanceof Promise) {
|
|
125
125
|
result = TransactionImpl.off(() => {
|
|
@@ -143,7 +143,7 @@ class TransactionImpl extends Transaction {
|
|
|
143
143
|
TransactionImpl.curr = outer;
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
|
-
static isFrameOver(everyN = 1, timeLimit =
|
|
146
|
+
static isFrameOver(everyN = 1, timeLimit = 10) {
|
|
147
147
|
TransactionImpl.frameOverCounter++;
|
|
148
148
|
let result = TransactionImpl.frameOverCounter % everyN === 0;
|
|
149
149
|
if (result) {
|
|
@@ -181,7 +181,7 @@ class TransactionImpl extends Transaction {
|
|
|
181
181
|
const options = {
|
|
182
182
|
hint: `${this.hint} - restart after T${this.after.id}`,
|
|
183
183
|
standalone: this.options.standalone === 'isolated' ? 'isolated' : true,
|
|
184
|
-
|
|
184
|
+
logging: this.snapshot.options.logging,
|
|
185
185
|
token: this.snapshot.options.token,
|
|
186
186
|
};
|
|
187
187
|
return TransactionImpl.run(options, func, ...args);
|
|
@@ -201,7 +201,7 @@ class TransactionImpl extends Transaction {
|
|
|
201
201
|
return result;
|
|
202
202
|
});
|
|
203
203
|
}
|
|
204
|
-
runImpl(
|
|
204
|
+
runImpl(logging, func, ...args) {
|
|
205
205
|
let result;
|
|
206
206
|
const outer = TransactionImpl.curr;
|
|
207
207
|
try {
|
|
@@ -241,10 +241,10 @@ class TransactionImpl extends Transaction {
|
|
|
241
241
|
if (!t.canceled && error) {
|
|
242
242
|
t.canceled = error;
|
|
243
243
|
t.after = after;
|
|
244
|
-
if (Dbg_1.
|
|
245
|
-
Dbg_1.
|
|
244
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.transaction) {
|
|
245
|
+
Dbg_1.Log.write('║', ' [!]', `${error.message}`, undefined, ' *** CANCEL ***');
|
|
246
246
|
if (after && after !== TransactionImpl.none)
|
|
247
|
-
Dbg_1.
|
|
247
|
+
Dbg_1.Log.write('║', ' [!]', `T${t.id}[${t.hint}] will be restarted${t !== after ? ` after T${after.id}[${after.hint}]` : ''}`);
|
|
248
248
|
}
|
|
249
249
|
Snapshot_1.Snapshot.revokeAllSubscriptions(t.snapshot);
|
|
250
250
|
}
|
|
@@ -261,8 +261,8 @@ class TransactionImpl extends Transaction {
|
|
|
261
261
|
applyOrDiscard() {
|
|
262
262
|
let reactions;
|
|
263
263
|
try {
|
|
264
|
-
if (Dbg_1.
|
|
265
|
-
Dbg_1.
|
|
264
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.change)
|
|
265
|
+
Dbg_1.Log.write('╠═', '', '', undefined, 'changes');
|
|
266
266
|
reactions = this.snapshot.applyOrDiscard(this.canceled);
|
|
267
267
|
this.snapshot.triggerGarbageCollection();
|
|
268
268
|
if (this.promise) {
|
|
@@ -271,7 +271,7 @@ class TransactionImpl extends Transaction {
|
|
|
271
271
|
else
|
|
272
272
|
this.resolve();
|
|
273
273
|
}
|
|
274
|
-
if (Dbg_1.
|
|
274
|
+
if (Dbg_1.Log.isOn)
|
|
275
275
|
Object.freeze(this);
|
|
276
276
|
}
|
|
277
277
|
catch (e) {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LoggingOptions } from '../Trace';
|
|
2
2
|
export declare function error(message: string, dump: Error | undefined): Error;
|
|
3
3
|
export declare function misuse(message: string, dump?: any): Error;
|
|
4
4
|
export declare function fatal(error: Error): Error;
|
|
5
|
-
export declare class
|
|
6
|
-
static DefaultLevel:
|
|
5
|
+
export declare class Log {
|
|
6
|
+
static DefaultLevel: LoggingOptions;
|
|
7
7
|
static isOn: boolean;
|
|
8
|
-
static global:
|
|
9
|
-
static get
|
|
10
|
-
static
|
|
11
|
-
static
|
|
12
|
-
static
|
|
13
|
-
static
|
|
14
|
-
static merge(t: Partial<
|
|
8
|
+
static global: LoggingOptions;
|
|
9
|
+
static get opt(): LoggingOptions;
|
|
10
|
+
static getMergedLoggingOptions: (local: Partial<LoggingOptions> | undefined) => LoggingOptions;
|
|
11
|
+
static setMode(isOn: boolean, options?: LoggingOptions): void;
|
|
12
|
+
static write(bar: string, tran: string, message: string, ms?: number, highlight?: string | undefined, dump?: any): void;
|
|
13
|
+
static writeAs(options: Partial<LoggingOptions> | undefined, bar: string, tran: string, message: string, ms?: number, highlight?: string | undefined, dump?: any): void;
|
|
14
|
+
static merge(t: Partial<LoggingOptions> | undefined, color: number | undefined, prefix: string | undefined, existing: LoggingOptions): LoggingOptions;
|
|
15
15
|
}
|
|
@@ -1,42 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.Log = exports.fatal = exports.misuse = exports.error = void 0;
|
|
4
4
|
function error(message, dump) {
|
|
5
|
-
if (
|
|
6
|
-
|
|
5
|
+
if (Log.isOn && Log.opt.error)
|
|
6
|
+
Log.write('█', ' ███', message, undefined, ' *** ERROR ***', dump);
|
|
7
7
|
return new Error(message);
|
|
8
8
|
}
|
|
9
9
|
exports.error = error;
|
|
10
10
|
function misuse(message, dump) {
|
|
11
11
|
const error = new Error(message);
|
|
12
|
-
|
|
12
|
+
Log.write(' ', ' ███', message, undefined, ' *** ERROR / MISUSE ***', dump !== null && dump !== void 0 ? dump : error);
|
|
13
13
|
return error;
|
|
14
14
|
}
|
|
15
15
|
exports.misuse = misuse;
|
|
16
16
|
function fatal(error) {
|
|
17
|
-
|
|
17
|
+
Log.write(' ', ' ███', error.message, undefined, ' *** FATAL ***', error);
|
|
18
18
|
return error;
|
|
19
19
|
}
|
|
20
20
|
exports.fatal = fatal;
|
|
21
|
-
class
|
|
22
|
-
static get
|
|
23
|
-
static
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
Dbg.log('', '', 'Method-level trace can be configured with @options({ trace: ... }) decorator');
|
|
21
|
+
class Log {
|
|
22
|
+
static get opt() { return this.getMergedLoggingOptions(undefined); }
|
|
23
|
+
static setMode(isOn, options) {
|
|
24
|
+
Log.global = options || Log.DefaultLevel;
|
|
25
|
+
if (isOn) {
|
|
26
|
+
const t = Log.global;
|
|
27
|
+
const o = Object.keys(Log.global).filter(x => t[x] === true).join(', ');
|
|
28
|
+
Log.write('', '', `Reactronic logging is turned on: ${o}`);
|
|
29
|
+
Log.write('', '', 'Member-level logging can be configured with @options({ logging: ... }) decorator');
|
|
31
30
|
}
|
|
32
|
-
else
|
|
33
|
-
|
|
31
|
+
else if (Log.isOn)
|
|
32
|
+
Log.write('', '', 'Reactronic logging is turned off');
|
|
33
|
+
Log.isOn = isOn;
|
|
34
34
|
}
|
|
35
|
-
static
|
|
36
|
-
|
|
35
|
+
static write(bar, tran, message, ms = 0, highlight = undefined, dump) {
|
|
36
|
+
Log.writeAs(undefined, bar, tran, message, ms, highlight, dump);
|
|
37
37
|
}
|
|
38
|
-
static
|
|
39
|
-
const t =
|
|
38
|
+
static writeAs(options, bar, tran, message, ms = 0, highlight = undefined, dump) {
|
|
39
|
+
const t = Log.getMergedLoggingOptions(options);
|
|
40
40
|
const margin1 = ' '.repeat(t.margin1 >= 0 ? t.margin1 : 0);
|
|
41
41
|
const margin2 = ' '.repeat(t.margin2);
|
|
42
42
|
const silent = (options && options.silent !== undefined) ? options.silent : t.silent;
|
|
@@ -72,8 +72,8 @@ class Dbg {
|
|
|
72
72
|
return result;
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
|
-
exports.
|
|
76
|
-
|
|
75
|
+
exports.Log = Log;
|
|
76
|
+
Log.DefaultLevel = {
|
|
77
77
|
silent: false,
|
|
78
78
|
error: false,
|
|
79
79
|
warning: false,
|
|
@@ -91,6 +91,6 @@ Dbg.DefaultLevel = {
|
|
|
91
91
|
margin1: 0,
|
|
92
92
|
margin2: 0,
|
|
93
93
|
};
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
Log.isOn = false;
|
|
95
|
+
Log.global = Log.DefaultLevel;
|
|
96
|
+
Log.getMergedLoggingOptions = (local) => Log.global;
|
|
@@ -8,8 +8,8 @@ class Sealant {
|
|
|
8
8
|
const createCopy = result[Sealant.CreateCopy];
|
|
9
9
|
if (createCopy)
|
|
10
10
|
result = createCopy.call(result);
|
|
11
|
-
if (Dbg_1.
|
|
12
|
-
Dbg_1.
|
|
11
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.write)
|
|
12
|
+
Dbg_1.Log.write('║', ' ', `${typeName}.${member.toString()} - collection is sealed`);
|
|
13
13
|
Object.setPrototypeOf(result, sealedType);
|
|
14
14
|
Object.freeze(result);
|
|
15
15
|
return result;
|