reactronic 0.24.270 → 0.24.272
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 +11 -8
- package/build/dist/source/Logging.d.ts +1 -1
- package/build/dist/source/Logging.js +6 -6
- package/build/dist/source/Options.d.ts +2 -2
- package/build/dist/source/api.d.ts +1 -1
- package/build/dist/source/api.js +1 -1
- package/build/dist/source/core/Indicator.d.ts +40 -0
- package/build/dist/source/core/Indicator.js +145 -0
- package/build/dist/source/core/Mvcc.d.ts +2 -2
- package/build/dist/source/core/Mvcc.js +2 -2
- package/build/dist/source/core/Reaction.d.ts +2 -2
- package/build/dist/source/core/Reaction.js +13 -13
- package/build/dist/source/util/Dbg.js +2 -2
- package/package.json +7 -7
- package/build/dist/source/core/Monitor.d.ts +0 -32
- package/build/dist/source/core/Monitor.js +0 -96
package/README.md
CHANGED
|
@@ -259,8 +259,8 @@ and reactive functions:
|
|
|
259
259
|
- `cancelAndWaitPrevious` - cancel previous call in favor of recent one (but wait until canceling is completed)
|
|
260
260
|
- `runSideBySide` - multiple simultaneous calls are allowed.
|
|
261
261
|
|
|
262
|
-
**
|
|
263
|
-
which it is attached to. A single
|
|
262
|
+
**Indicator** is an object that maintains status of running functions,
|
|
263
|
+
which it is attached to. A single indicator object can be shared between
|
|
264
264
|
multiple transactional, reactive, and cached functions, thus maintaining
|
|
265
265
|
consolidated status for all of them (busy, workers, etc).
|
|
266
266
|
|
|
@@ -306,7 +306,7 @@ function options(value: Partial<MemberOptions>): F<any>
|
|
|
306
306
|
function unobs<T>(func: F<T>, ...args: any[]): T
|
|
307
307
|
function sensitive<T>(sensitivity: Sensitivity, func: F<T>, ...args: any[]): T
|
|
308
308
|
|
|
309
|
-
// SnapshotOptions, MemberOptions, Kind, Reentrance,
|
|
309
|
+
// SnapshotOptions, MemberOptions, Kind, Reentrance, Indicator, LoggingOptions, ProfilingOptions
|
|
310
310
|
|
|
311
311
|
export type SnapshotOptions = {
|
|
312
312
|
readonly hint?: string
|
|
@@ -325,7 +325,7 @@ type MemberOptions = {
|
|
|
325
325
|
readonly throttling: number // milliseconds, -1 is immediately, Number.MAX_SAFE_INTEGER is never
|
|
326
326
|
readonly reentrance: Reentrance
|
|
327
327
|
readonly journal: Journal | undefined
|
|
328
|
-
readonly
|
|
328
|
+
readonly indicator: Indicator | null
|
|
329
329
|
readonly logging?: Partial<LoggingOptions>
|
|
330
330
|
}
|
|
331
331
|
|
|
@@ -345,11 +345,14 @@ enum Reentrance {
|
|
|
345
345
|
runSideBySide = -3 // multiple simultaneous calls are allowed
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
-
class
|
|
349
|
-
readonly
|
|
348
|
+
class Indicator {
|
|
349
|
+
readonly isBusy: boolean
|
|
350
350
|
readonly counter: number
|
|
351
351
|
readonly workers: ReadonlySet<Worker>
|
|
352
|
-
|
|
352
|
+
readonly busyDuration: number
|
|
353
|
+
abstract whenBusy(): Promise<void>
|
|
354
|
+
abstract whenIdle(): Promise<void>
|
|
355
|
+
static create(hint: string, activationDelay: number, deactivationDelay: number): Indicator
|
|
353
356
|
}
|
|
354
357
|
|
|
355
358
|
type Worker = {
|
|
@@ -366,7 +369,7 @@ type LoggingOptions = {
|
|
|
366
369
|
readonly transaction: boolean
|
|
367
370
|
readonly operation: boolean
|
|
368
371
|
readonly step: boolean
|
|
369
|
-
readonly
|
|
372
|
+
readonly indicator: boolean
|
|
370
373
|
readonly read: boolean
|
|
371
374
|
readonly write: boolean
|
|
372
375
|
readonly change: boolean
|
|
@@ -4,7 +4,7 @@ export const LoggingLevel = {
|
|
|
4
4
|
transaction: false,
|
|
5
5
|
operation: false,
|
|
6
6
|
step: false,
|
|
7
|
-
|
|
7
|
+
indicator: false,
|
|
8
8
|
read: false,
|
|
9
9
|
write: false,
|
|
10
10
|
change: false,
|
|
@@ -22,7 +22,7 @@ export const LoggingLevel = {
|
|
|
22
22
|
transaction: false,
|
|
23
23
|
operation: false,
|
|
24
24
|
step: false,
|
|
25
|
-
|
|
25
|
+
indicator: false,
|
|
26
26
|
read: false,
|
|
27
27
|
write: false,
|
|
28
28
|
change: false,
|
|
@@ -40,7 +40,7 @@ export const LoggingLevel = {
|
|
|
40
40
|
transaction: false,
|
|
41
41
|
operation: false,
|
|
42
42
|
step: false,
|
|
43
|
-
|
|
43
|
+
indicator: false,
|
|
44
44
|
read: false,
|
|
45
45
|
write: false,
|
|
46
46
|
change: false,
|
|
@@ -58,7 +58,7 @@ export const LoggingLevel = {
|
|
|
58
58
|
transaction: true,
|
|
59
59
|
operation: false,
|
|
60
60
|
step: false,
|
|
61
|
-
|
|
61
|
+
indicator: false,
|
|
62
62
|
read: false,
|
|
63
63
|
write: false,
|
|
64
64
|
change: false,
|
|
@@ -76,7 +76,7 @@ export const LoggingLevel = {
|
|
|
76
76
|
transaction: true,
|
|
77
77
|
operation: true,
|
|
78
78
|
step: false,
|
|
79
|
-
|
|
79
|
+
indicator: true,
|
|
80
80
|
read: false,
|
|
81
81
|
write: false,
|
|
82
82
|
change: true,
|
|
@@ -94,7 +94,7 @@ export const LoggingLevel = {
|
|
|
94
94
|
transaction: true,
|
|
95
95
|
operation: true,
|
|
96
96
|
step: true,
|
|
97
|
-
|
|
97
|
+
indicator: true,
|
|
98
98
|
read: true,
|
|
99
99
|
write: true,
|
|
100
100
|
change: true,
|
|
@@ -3,7 +3,7 @@ import { SeparationMode } from "./core/Data.js";
|
|
|
3
3
|
export { LoggingLevel } from "./Logging.js";
|
|
4
4
|
export type { LoggingOptions, ProfilingOptions } from "./Logging.js";
|
|
5
5
|
import { Journal } from "./core/Journal.js";
|
|
6
|
-
import {
|
|
6
|
+
import { Indicator } from "./core/Indicator.js";
|
|
7
7
|
export type SnapshotOptions = {
|
|
8
8
|
readonly hint?: string;
|
|
9
9
|
readonly separation?: SeparationMode;
|
|
@@ -20,7 +20,7 @@ export type MemberOptions = {
|
|
|
20
20
|
readonly throttling: number;
|
|
21
21
|
readonly reentrance: Reentrance;
|
|
22
22
|
readonly journal: Journal | undefined;
|
|
23
|
-
readonly
|
|
23
|
+
readonly indicator: Indicator | null;
|
|
24
24
|
readonly logging?: Partial<LoggingOptions>;
|
|
25
25
|
};
|
|
26
26
|
export declare enum Kind {
|
|
@@ -14,7 +14,7 @@ export { TransactionalArray, ObservableArray } from "./core/MvccArray.js";
|
|
|
14
14
|
export { TransactionalMap, ObservableMap } from "./core/MvccMap.js";
|
|
15
15
|
export { Changeset } from "./core/Changeset.js";
|
|
16
16
|
export { Transaction } from "./core/Transaction.js";
|
|
17
|
-
export {
|
|
17
|
+
export { Indicator } from "./core/Indicator.js";
|
|
18
18
|
export { Journal } from "./core/Journal.js";
|
|
19
19
|
export { RxSystem, raw, obs, transactional, reactive, cached, transaction, unobs, sensitive, options } from "./RxSystem.js";
|
|
20
20
|
export { Reaction } from "./Reaction.js";
|
package/build/dist/source/api.js
CHANGED
|
@@ -10,7 +10,7 @@ export { TransactionalArray, ObservableArray } from "./core/MvccArray.js";
|
|
|
10
10
|
export { TransactionalMap, ObservableMap } from "./core/MvccMap.js";
|
|
11
11
|
export { Changeset } from "./core/Changeset.js";
|
|
12
12
|
export { Transaction } from "./core/Transaction.js";
|
|
13
|
-
export {
|
|
13
|
+
export { Indicator } from "./core/Indicator.js";
|
|
14
14
|
export { Journal } from "./core/Journal.js";
|
|
15
15
|
export { RxSystem, raw, obs, transactional, reactive, cached, transaction, unobs, sensitive, options } from "./RxSystem.js";
|
|
16
16
|
export { Reaction } from "./Reaction.js";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Worker } from "../Worker.js";
|
|
2
|
+
import { ObservableObject } from "./Mvcc.js";
|
|
3
|
+
export declare abstract class Indicator extends ObservableObject {
|
|
4
|
+
abstract readonly isBusy: boolean;
|
|
5
|
+
abstract readonly counter: number;
|
|
6
|
+
abstract readonly workers: ReadonlySet<Worker>;
|
|
7
|
+
abstract readonly busyDuration: number;
|
|
8
|
+
abstract whenBusy(): Promise<void>;
|
|
9
|
+
abstract whenIdle(): Promise<void>;
|
|
10
|
+
static create(hint: string, activationDelay: number, deactivationDelay: number, durationResolution: number): Indicator;
|
|
11
|
+
}
|
|
12
|
+
export declare class IndicatorImpl extends Indicator {
|
|
13
|
+
isBusy: boolean;
|
|
14
|
+
counter: number;
|
|
15
|
+
workers: Set<Worker>;
|
|
16
|
+
busyDuration: number;
|
|
17
|
+
readonly internals: {
|
|
18
|
+
whenBusy: Promise<void> | undefined;
|
|
19
|
+
resolveWhenBusy: ((value?: void | undefined) => void) | undefined;
|
|
20
|
+
whenIdle: Promise<void> | undefined;
|
|
21
|
+
resolveWhenIdle: ((value?: void | undefined) => void) | undefined;
|
|
22
|
+
started: number;
|
|
23
|
+
activationDelay: number;
|
|
24
|
+
activationTimeout: undefined;
|
|
25
|
+
deactivationDelay: number;
|
|
26
|
+
deactivationTimeout: undefined;
|
|
27
|
+
durationResolution: number;
|
|
28
|
+
};
|
|
29
|
+
whenBusy(): Promise<void>;
|
|
30
|
+
whenIdle(): Promise<void>;
|
|
31
|
+
enter(worker: Worker): void;
|
|
32
|
+
leave(worker: Worker): void;
|
|
33
|
+
static create(hint: string, activationDelay: number, deactivationDelay: number, durationResolution: number): IndicatorImpl;
|
|
34
|
+
static enter(mon: IndicatorImpl, worker: Worker): void;
|
|
35
|
+
static leave(mon: IndicatorImpl, worker: Worker): void;
|
|
36
|
+
private static doCreate;
|
|
37
|
+
private static activate;
|
|
38
|
+
private static deactivate;
|
|
39
|
+
private static tick;
|
|
40
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { ObservableObject, Mvcc } from "./Mvcc.js";
|
|
11
|
+
import { Transaction } from "./Transaction.js";
|
|
12
|
+
export class Indicator extends ObservableObject {
|
|
13
|
+
static create(hint, activationDelay, deactivationDelay, durationResolution) {
|
|
14
|
+
return IndicatorImpl.create(hint, activationDelay, deactivationDelay, durationResolution);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class IndicatorImpl extends Indicator {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments);
|
|
20
|
+
this.isBusy = false;
|
|
21
|
+
this.counter = 0;
|
|
22
|
+
this.workers = new Set();
|
|
23
|
+
this.busyDuration = 0;
|
|
24
|
+
this.internals = {
|
|
25
|
+
whenBusy: undefined,
|
|
26
|
+
resolveWhenBusy: undefined,
|
|
27
|
+
whenIdle: undefined,
|
|
28
|
+
resolveWhenIdle: undefined,
|
|
29
|
+
started: 0,
|
|
30
|
+
activationDelay: -1,
|
|
31
|
+
activationTimeout: undefined,
|
|
32
|
+
deactivationDelay: -1,
|
|
33
|
+
deactivationTimeout: undefined,
|
|
34
|
+
durationResolution: 1,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
whenBusy() {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
if (this.internals.started === 0) {
|
|
40
|
+
if (!this.internals.whenBusy) {
|
|
41
|
+
this.internals.whenBusy = new Promise((resolve, reject) => {
|
|
42
|
+
this.internals.resolveWhenBusy = resolve;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
yield this.internals.whenBusy;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
whenIdle() {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
if (this.internals.started !== 0) {
|
|
52
|
+
if (!this.internals.whenIdle) {
|
|
53
|
+
this.internals.whenIdle = new Promise((resolve, reject) => {
|
|
54
|
+
this.internals.resolveWhenIdle = resolve;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
yield this.internals.whenIdle;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
enter(worker) {
|
|
62
|
+
this.counter++;
|
|
63
|
+
const workers = this.workers = this.workers.toMutable();
|
|
64
|
+
workers.add(worker);
|
|
65
|
+
IndicatorImpl.activate(this, this.internals.activationDelay);
|
|
66
|
+
}
|
|
67
|
+
leave(worker) {
|
|
68
|
+
this.counter--;
|
|
69
|
+
const workers = this.workers = this.workers.toMutable();
|
|
70
|
+
workers.delete(worker);
|
|
71
|
+
IndicatorImpl.deactivate(this, this.internals.deactivationDelay);
|
|
72
|
+
}
|
|
73
|
+
static create(hint, activationDelay, deactivationDelay, durationResolution) {
|
|
74
|
+
return Transaction.run({ hint: "Indicator.create" }, IndicatorImpl.doCreate, hint, activationDelay, deactivationDelay, durationResolution);
|
|
75
|
+
}
|
|
76
|
+
static enter(mon, worker) {
|
|
77
|
+
mon.enter(worker);
|
|
78
|
+
}
|
|
79
|
+
static leave(mon, worker) {
|
|
80
|
+
mon.leave(worker);
|
|
81
|
+
}
|
|
82
|
+
static doCreate(hint, activationDelay, deactivationDelay, durationResolution) {
|
|
83
|
+
const m = new IndicatorImpl();
|
|
84
|
+
Mvcc.setHint(m, hint);
|
|
85
|
+
m.internals.activationDelay = activationDelay;
|
|
86
|
+
m.internals.deactivationDelay = deactivationDelay;
|
|
87
|
+
m.internals.durationResolution = durationResolution;
|
|
88
|
+
return m;
|
|
89
|
+
}
|
|
90
|
+
static activate(mon, delay) {
|
|
91
|
+
const active = mon.counter > 0;
|
|
92
|
+
if (mon.internals.started === 0 && active) {
|
|
93
|
+
mon.busyDuration = 0;
|
|
94
|
+
mon.internals.started = performance.now();
|
|
95
|
+
if (mon.internals.whenBusy) {
|
|
96
|
+
const resolve = mon.internals.resolveWhenBusy;
|
|
97
|
+
mon.internals.whenBusy = undefined;
|
|
98
|
+
mon.internals.resolveWhenBusy = undefined;
|
|
99
|
+
resolve();
|
|
100
|
+
}
|
|
101
|
+
IndicatorImpl.tick(mon);
|
|
102
|
+
}
|
|
103
|
+
if (delay >= 0) {
|
|
104
|
+
if (mon.internals.activationTimeout === undefined)
|
|
105
|
+
mon.internals.activationTimeout = setTimeout(() => Transaction.run({ hint: "Indicator.activate", separation: "isolated" }, IndicatorImpl.activate, mon, -1), delay);
|
|
106
|
+
}
|
|
107
|
+
else if (active)
|
|
108
|
+
mon.isBusy = true;
|
|
109
|
+
}
|
|
110
|
+
static deactivate(mon, delay) {
|
|
111
|
+
if (delay >= 0) {
|
|
112
|
+
clearTimeout(mon.internals.deactivationTimeout);
|
|
113
|
+
mon.internals.deactivationTimeout = setTimeout(() => Transaction.run({ hint: "Indicator.deactivate", separation: "isolated" }, IndicatorImpl.deactivate, mon, -1), delay);
|
|
114
|
+
}
|
|
115
|
+
else if (mon.counter <= 0) {
|
|
116
|
+
mon.isBusy = false;
|
|
117
|
+
mon.internals.activationTimeout = undefined;
|
|
118
|
+
}
|
|
119
|
+
if (mon.counter === 0 && mon.internals.started !== 0) {
|
|
120
|
+
const resolution = mon.internals.durationResolution;
|
|
121
|
+
mon.busyDuration = Math.round(resolution * (performance.now() - mon.internals.started)) / resolution;
|
|
122
|
+
mon.internals.started = 0;
|
|
123
|
+
if (mon.internals.whenIdle) {
|
|
124
|
+
const resolve = mon.internals.resolveWhenIdle;
|
|
125
|
+
mon.internals.whenIdle = undefined;
|
|
126
|
+
mon.internals.resolveWhenIdle = undefined;
|
|
127
|
+
resolve();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
static tick(mon) {
|
|
132
|
+
if (mon.internals.started !== 0) {
|
|
133
|
+
Transaction.run(INDICATOR_TICK_OPTIONS, () => {
|
|
134
|
+
const resolution = mon.internals.durationResolution;
|
|
135
|
+
mon.busyDuration = Math.round(resolution * (performance.now() - mon.internals.started)) / resolution;
|
|
136
|
+
});
|
|
137
|
+
const t = globalThis !== null && globalThis !== void 0 ? globalThis : global;
|
|
138
|
+
if (t.requestAnimationFrame)
|
|
139
|
+
requestAnimationFrame(() => IndicatorImpl.tick(mon));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const INDICATOR_TICK_OPTIONS = Object.freeze({
|
|
144
|
+
hint: "Indicator.tick",
|
|
145
|
+
});
|
|
@@ -3,7 +3,7 @@ import { MemberOptions, Kind, Reentrance } from "../Options.js";
|
|
|
3
3
|
import { LoggingOptions, ProfilingOptions } from "../Logging.js";
|
|
4
4
|
import { MemberName, ObjectHandle, SeparationMode } from "./Data.js";
|
|
5
5
|
import { Journal } from "./Journal.js";
|
|
6
|
-
import {
|
|
6
|
+
import { Indicator } from "./Indicator.js";
|
|
7
7
|
export declare abstract class MvccObject {
|
|
8
8
|
protected constructor(observable: boolean);
|
|
9
9
|
[Symbol.toStringTag](): string;
|
|
@@ -25,7 +25,7 @@ export declare class OptionsImpl implements MemberOptions {
|
|
|
25
25
|
readonly throttling: number;
|
|
26
26
|
readonly reentrance: Reentrance;
|
|
27
27
|
readonly journal: Journal | undefined;
|
|
28
|
-
readonly
|
|
28
|
+
readonly indicator: Indicator | null;
|
|
29
29
|
readonly logging?: Partial<LoggingOptions>;
|
|
30
30
|
static readonly INITIAL: Readonly<OptionsImpl>;
|
|
31
31
|
constructor(getter: Function | undefined, setter: Function | undefined, existing: OptionsImpl, patch: Partial<OptionsImpl>, implicit: boolean);
|
|
@@ -34,7 +34,7 @@ const DEFAULT_OPTIONS = Object.freeze({
|
|
|
34
34
|
throttling: Number.MAX_SAFE_INTEGER,
|
|
35
35
|
reentrance: Reentrance.preventWithError,
|
|
36
36
|
journal: undefined,
|
|
37
|
-
|
|
37
|
+
indicator: null,
|
|
38
38
|
logging: undefined,
|
|
39
39
|
});
|
|
40
40
|
export class OptionsImpl {
|
|
@@ -49,7 +49,7 @@ export class OptionsImpl {
|
|
|
49
49
|
this.throttling = merge(DEFAULT_OPTIONS.throttling, existing.throttling, patch.throttling, implicit);
|
|
50
50
|
this.reentrance = merge(DEFAULT_OPTIONS.reentrance, existing.reentrance, patch.reentrance, implicit);
|
|
51
51
|
this.journal = merge(DEFAULT_OPTIONS.journal, existing.journal, patch.journal, implicit);
|
|
52
|
-
this.
|
|
52
|
+
this.indicator = merge(DEFAULT_OPTIONS.indicator, existing.indicator, patch.indicator, implicit);
|
|
53
53
|
this.logging = merge(DEFAULT_OPTIONS.logging, existing.logging, patch.logging, implicit);
|
|
54
54
|
if (Log.isOn)
|
|
55
55
|
Object.freeze(this);
|
|
@@ -68,8 +68,8 @@ declare class Launch extends ValueSnapshot implements Observer {
|
|
|
68
68
|
private enter;
|
|
69
69
|
private leaveOrAsync;
|
|
70
70
|
private leave;
|
|
71
|
-
private
|
|
72
|
-
private
|
|
71
|
+
private indicatorEnter;
|
|
72
|
+
private indicatorLeave;
|
|
73
73
|
private addToDeferredReactiveFunctions;
|
|
74
74
|
private static processDeferredReactiveFunctions;
|
|
75
75
|
private static markUsed;
|
|
@@ -3,7 +3,7 @@ import { Kind, Reentrance } from "../Options.js";
|
|
|
3
3
|
import { ObjectHandle, ValueSnapshot, Meta } from "./Data.js";
|
|
4
4
|
import { Changeset, Dump, EMPTY_SNAPSHOT, MAX_REVISION } from "./Changeset.js";
|
|
5
5
|
import { Transaction } from "./Transaction.js";
|
|
6
|
-
import {
|
|
6
|
+
import { IndicatorImpl } from "./Indicator.js";
|
|
7
7
|
import { Mvcc, OptionsImpl } from "./Mvcc.js";
|
|
8
8
|
import { JournalImpl } from "./Journal.js";
|
|
9
9
|
const BOOT_ARGS = [];
|
|
@@ -374,8 +374,8 @@ class Launch extends ValueSnapshot {
|
|
|
374
374
|
}
|
|
375
375
|
}
|
|
376
376
|
enter() {
|
|
377
|
-
if (this.options.
|
|
378
|
-
this.
|
|
377
|
+
if (this.options.indicator)
|
|
378
|
+
this.indicatorEnter(this.options.indicator);
|
|
379
379
|
if (Log.isOn && Log.opt.operation)
|
|
380
380
|
Log.write("║", "‾\\", `${this.hint()} - enter`, undefined, ` [ ${Dump.obj(this.reaction.objectHandle, this.reaction.memberName)} ]`);
|
|
381
381
|
this.started = Date.now();
|
|
@@ -411,26 +411,26 @@ class Launch extends ValueSnapshot {
|
|
|
411
411
|
if (ms > (main ? Mvcc.mainThreadBlockingWarningThreshold : Mvcc.asyncActionDurationWarningThreshold))
|
|
412
412
|
Log.write("", "[!]", this.why(), ms, main ? " *** main thread is too busy ***" : " *** async is too long ***");
|
|
413
413
|
this.cause = undefined;
|
|
414
|
-
if (this.options.
|
|
415
|
-
this.
|
|
414
|
+
if (this.options.indicator)
|
|
415
|
+
this.indicatorLeave(this.options.indicator);
|
|
416
416
|
}
|
|
417
|
-
|
|
417
|
+
indicatorEnter(mon) {
|
|
418
418
|
const options = {
|
|
419
|
-
hint: "
|
|
419
|
+
hint: "Indicator.enter",
|
|
420
420
|
separation: "isolated",
|
|
421
|
-
logging: Log.isOn && Log.opt.
|
|
421
|
+
logging: Log.isOn && Log.opt.indicator ? undefined : Log.global
|
|
422
422
|
};
|
|
423
|
-
ReactionImpl.proceedWithinGivenLaunch(undefined, Transaction.run, options,
|
|
423
|
+
ReactionImpl.proceedWithinGivenLaunch(undefined, Transaction.run, options, IndicatorImpl.enter, mon, this.transaction);
|
|
424
424
|
}
|
|
425
|
-
|
|
425
|
+
indicatorLeave(mon) {
|
|
426
426
|
Transaction.outside(() => {
|
|
427
427
|
const leave = () => {
|
|
428
428
|
const options = {
|
|
429
|
-
hint: "
|
|
429
|
+
hint: "Indicator.leave",
|
|
430
430
|
separation: "isolated",
|
|
431
|
-
logging: Log.isOn && Log.opt.
|
|
431
|
+
logging: Log.isOn && Log.opt.indicator ? undefined : Log.DefaultLevel
|
|
432
432
|
};
|
|
433
|
-
ReactionImpl.proceedWithinGivenLaunch(undefined, Transaction.run, options,
|
|
433
|
+
ReactionImpl.proceedWithinGivenLaunch(undefined, Transaction.run, options, IndicatorImpl.leave, mon, this.transaction);
|
|
434
434
|
};
|
|
435
435
|
this.transaction.whenFinished().then(leave, leave);
|
|
436
436
|
});
|
|
@@ -46,7 +46,7 @@ export class Log {
|
|
|
46
46
|
transaction: t.transaction !== undefined ? t.transaction : existing.transaction,
|
|
47
47
|
operation: t.operation !== undefined ? t.operation : existing.operation,
|
|
48
48
|
step: t.step !== undefined ? t.step : existing.step,
|
|
49
|
-
|
|
49
|
+
indicator: t.indicator !== undefined ? t.indicator : existing.indicator,
|
|
50
50
|
read: t.read !== undefined ? t.read : existing.read,
|
|
51
51
|
write: t.write !== undefined ? t.write : existing.write,
|
|
52
52
|
change: t.change !== undefined ? t.change : existing.change,
|
|
@@ -73,7 +73,7 @@ Log.DefaultLevel = {
|
|
|
73
73
|
transaction: false,
|
|
74
74
|
operation: false,
|
|
75
75
|
step: false,
|
|
76
|
-
|
|
76
|
+
indicator: false,
|
|
77
77
|
read: false,
|
|
78
78
|
write: false,
|
|
79
79
|
change: false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reactronic",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.272",
|
|
4
4
|
"description": "Reactronic - Transactional Reactive State Management",
|
|
5
5
|
"publisher": "Nezaboodka Software",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
},
|
|
32
32
|
"homepage": "https://github.com/nezaboodka/reactronic/blob/master/README.md#readme",
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@types/node": "20.11.
|
|
35
|
-
"@types/react": "18.2.
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "
|
|
37
|
-
"@typescript-eslint/parser": "
|
|
38
|
-
"ava": "6.1.
|
|
34
|
+
"@types/node": "20.11.28",
|
|
35
|
+
"@types/react": "18.2.66",
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "7.2.0",
|
|
37
|
+
"@typescript-eslint/parser": "7.2.0",
|
|
38
|
+
"ava": "6.1.2",
|
|
39
39
|
"c8": "9.1.0",
|
|
40
|
-
"eslint": "8.
|
|
40
|
+
"eslint": "8.57.0",
|
|
41
41
|
"react": "18.2.0",
|
|
42
42
|
"ts-node": "10.9.2",
|
|
43
43
|
"typescript": "5.3.2"
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Worker } from "../Worker.js";
|
|
2
|
-
import { ObservableObject } from "./Mvcc.js";
|
|
3
|
-
export declare abstract class Monitor extends ObservableObject {
|
|
4
|
-
abstract readonly isActive: boolean;
|
|
5
|
-
abstract readonly counter: number;
|
|
6
|
-
abstract readonly workers: ReadonlySet<Worker>;
|
|
7
|
-
abstract readonly duration: number;
|
|
8
|
-
static create(hint: string, activationDelay: number, deactivationDelay: number, durationResolution: number): Monitor;
|
|
9
|
-
}
|
|
10
|
-
export declare class MonitorImpl extends Monitor {
|
|
11
|
-
isActive: boolean;
|
|
12
|
-
counter: number;
|
|
13
|
-
workers: Set<Worker>;
|
|
14
|
-
duration: number;
|
|
15
|
-
readonly internals: {
|
|
16
|
-
started: number;
|
|
17
|
-
activationDelay: number;
|
|
18
|
-
activationTimeout: undefined;
|
|
19
|
-
deactivationDelay: number;
|
|
20
|
-
deactivationTimeout: undefined;
|
|
21
|
-
durationResolution: number;
|
|
22
|
-
};
|
|
23
|
-
enter(worker: Worker): void;
|
|
24
|
-
leave(worker: Worker): void;
|
|
25
|
-
static create(hint: string, activationDelay: number, deactivationDelay: number, durationResolution: number): MonitorImpl;
|
|
26
|
-
static enter(mon: MonitorImpl, worker: Worker): void;
|
|
27
|
-
static leave(mon: MonitorImpl, worker: Worker): void;
|
|
28
|
-
private static doCreate;
|
|
29
|
-
private static activate;
|
|
30
|
-
private static deactivate;
|
|
31
|
-
private static tick;
|
|
32
|
-
}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { ObservableObject, Mvcc } from "./Mvcc.js";
|
|
2
|
-
import { Transaction } from "./Transaction.js";
|
|
3
|
-
export class Monitor extends ObservableObject {
|
|
4
|
-
static create(hint, activationDelay, deactivationDelay, durationResolution) {
|
|
5
|
-
return MonitorImpl.create(hint, activationDelay, deactivationDelay, durationResolution);
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
export class MonitorImpl extends Monitor {
|
|
9
|
-
constructor() {
|
|
10
|
-
super(...arguments);
|
|
11
|
-
this.isActive = false;
|
|
12
|
-
this.counter = 0;
|
|
13
|
-
this.workers = new Set();
|
|
14
|
-
this.duration = 0;
|
|
15
|
-
this.internals = {
|
|
16
|
-
started: 0,
|
|
17
|
-
activationDelay: -1,
|
|
18
|
-
activationTimeout: undefined,
|
|
19
|
-
deactivationDelay: -1,
|
|
20
|
-
deactivationTimeout: undefined,
|
|
21
|
-
durationResolution: 1,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
enter(worker) {
|
|
25
|
-
this.counter++;
|
|
26
|
-
const workers = this.workers = this.workers.toMutable();
|
|
27
|
-
workers.add(worker);
|
|
28
|
-
MonitorImpl.activate(this, this.internals.activationDelay);
|
|
29
|
-
}
|
|
30
|
-
leave(worker) {
|
|
31
|
-
this.counter--;
|
|
32
|
-
const workers = this.workers = this.workers.toMutable();
|
|
33
|
-
workers.delete(worker);
|
|
34
|
-
MonitorImpl.deactivate(this, this.internals.deactivationDelay);
|
|
35
|
-
}
|
|
36
|
-
static create(hint, activationDelay, deactivationDelay, durationResolution) {
|
|
37
|
-
return Transaction.run({ hint: "Monitor.create" }, MonitorImpl.doCreate, hint, activationDelay, deactivationDelay, durationResolution);
|
|
38
|
-
}
|
|
39
|
-
static enter(mon, worker) {
|
|
40
|
-
mon.enter(worker);
|
|
41
|
-
}
|
|
42
|
-
static leave(mon, worker) {
|
|
43
|
-
mon.leave(worker);
|
|
44
|
-
}
|
|
45
|
-
static doCreate(hint, activationDelay, deactivationDelay, durationResolution) {
|
|
46
|
-
const m = new MonitorImpl();
|
|
47
|
-
Mvcc.setHint(m, hint);
|
|
48
|
-
m.internals.activationDelay = activationDelay;
|
|
49
|
-
m.internals.deactivationDelay = deactivationDelay;
|
|
50
|
-
m.internals.durationResolution = durationResolution;
|
|
51
|
-
return m;
|
|
52
|
-
}
|
|
53
|
-
static activate(mon, delay) {
|
|
54
|
-
const active = mon.counter > 0;
|
|
55
|
-
if (mon.internals.started === 0 && active) {
|
|
56
|
-
mon.duration = 0;
|
|
57
|
-
mon.internals.started = performance.now();
|
|
58
|
-
MonitorImpl.tick(mon);
|
|
59
|
-
}
|
|
60
|
-
if (delay >= 0) {
|
|
61
|
-
if (mon.internals.activationTimeout === undefined)
|
|
62
|
-
mon.internals.activationTimeout = setTimeout(() => Transaction.run({ hint: "Monitor.activate", separation: "isolated" }, MonitorImpl.activate, mon, -1), delay);
|
|
63
|
-
}
|
|
64
|
-
else if (active)
|
|
65
|
-
mon.isActive = true;
|
|
66
|
-
}
|
|
67
|
-
static deactivate(mon, delay) {
|
|
68
|
-
if (delay >= 0) {
|
|
69
|
-
clearTimeout(mon.internals.deactivationTimeout);
|
|
70
|
-
mon.internals.deactivationTimeout = setTimeout(() => Transaction.run({ hint: "Monitor.deactivate", separation: "isolated" }, MonitorImpl.deactivate, mon, -1), delay);
|
|
71
|
-
}
|
|
72
|
-
else if (mon.counter <= 0) {
|
|
73
|
-
mon.isActive = false;
|
|
74
|
-
mon.internals.activationTimeout = undefined;
|
|
75
|
-
}
|
|
76
|
-
if (mon.counter === 0 && mon.internals.started !== 0) {
|
|
77
|
-
const resolution = mon.internals.durationResolution;
|
|
78
|
-
mon.duration = Math.round(resolution * (performance.now() - mon.internals.started)) / resolution;
|
|
79
|
-
mon.internals.started = 0;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
static tick(mon) {
|
|
83
|
-
if (mon.internals.started !== 0) {
|
|
84
|
-
Transaction.run(MONITOR_TICK_OPTIONS, () => {
|
|
85
|
-
const resolution = mon.internals.durationResolution;
|
|
86
|
-
mon.duration = Math.round(resolution * (performance.now() - mon.internals.started)) / resolution;
|
|
87
|
-
});
|
|
88
|
-
const t = globalThis !== null && globalThis !== void 0 ? globalThis : global;
|
|
89
|
-
if (t.requestAnimationFrame)
|
|
90
|
-
requestAnimationFrame(() => MonitorImpl.tick(mon));
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
const MONITOR_TICK_OPTIONS = Object.freeze({
|
|
95
|
-
hint: "Monitor.tick",
|
|
96
|
-
});
|