reactronic 0.22.308 → 0.22.309

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.
Files changed (45) hide show
  1. package/build/dist/source/Buffer.d.ts +8 -0
  2. package/build/dist/source/Buffer.js +8 -0
  3. package/build/dist/source/Controller.d.ts +12 -0
  4. package/build/dist/source/Controller.js +6 -0
  5. package/build/dist/source/Logging.d.ts +38 -0
  6. package/build/dist/source/Logging.js +113 -0
  7. package/build/dist/source/Options.d.ts +38 -0
  8. package/build/dist/source/Options.js +21 -0
  9. package/build/dist/source/Ref.d.ts +34 -0
  10. package/build/dist/source/Ref.js +90 -0
  11. package/build/dist/source/Rx.d.ts +27 -0
  12. package/build/dist/source/Rx.js +58 -0
  13. package/build/dist/source/Worker.d.ts +8 -0
  14. package/build/dist/source/Worker.js +2 -0
  15. package/build/dist/source/api.d.ts +14 -0
  16. package/build/dist/source/api.js +42 -0
  17. package/build/dist/source/impl/Changeset.d.ts +60 -0
  18. package/build/dist/source/impl/Changeset.js +361 -0
  19. package/build/dist/source/impl/Data.d.ts +60 -0
  20. package/build/dist/source/impl/Data.js +51 -0
  21. package/build/dist/source/impl/Hooks.d.ts +96 -0
  22. package/build/dist/source/impl/Hooks.js +310 -0
  23. package/build/dist/source/impl/Journal.d.ts +34 -0
  24. package/build/dist/source/impl/Journal.js +149 -0
  25. package/build/dist/source/impl/Meta.d.ts +13 -0
  26. package/build/dist/source/impl/Meta.js +33 -0
  27. package/build/dist/source/impl/Monitor.d.ts +32 -0
  28. package/build/dist/source/impl/Monitor.js +97 -0
  29. package/build/dist/source/impl/Operation.d.ts +93 -0
  30. package/build/dist/source/impl/Operation.js +722 -0
  31. package/build/dist/source/impl/Transaction.d.ts +30 -0
  32. package/build/dist/source/impl/Transaction.js +313 -0
  33. package/build/dist/source/util/Dbg.d.ts +15 -0
  34. package/build/dist/source/util/Dbg.js +96 -0
  35. package/build/dist/source/util/Sealant.d.ts +14 -0
  36. package/build/dist/source/util/Sealant.js +30 -0
  37. package/build/dist/source/util/SealedArray.d.ts +16 -0
  38. package/build/dist/source/util/SealedArray.js +28 -0
  39. package/build/dist/source/util/SealedMap.d.ts +13 -0
  40. package/build/dist/source/util/SealedMap.js +21 -0
  41. package/build/dist/source/util/SealedSet.d.ts +13 -0
  42. package/build/dist/source/util/SealedSet.js +21 -0
  43. package/build/dist/source/util/Utils.d.ts +9 -0
  44. package/build/dist/source/util/Utils.js +62 -0
  45. package/package.json +1 -1
@@ -0,0 +1,30 @@
1
+ import { F } from '../util/Utils';
2
+ import { Worker } from '../Worker';
3
+ import { SnapshotOptions } from '../Options';
4
+ import { Changeset } from './Changeset';
5
+ export declare abstract class Transaction implements Worker {
6
+ static get current(): Transaction;
7
+ abstract readonly id: number;
8
+ abstract readonly hint: string;
9
+ abstract readonly options: SnapshotOptions;
10
+ abstract readonly timestamp: number;
11
+ abstract readonly error: Error | undefined;
12
+ abstract readonly changeset: Changeset;
13
+ abstract readonly margin: number;
14
+ abstract run<T>(func: F<T>, ...args: any[]): T;
15
+ abstract inspect<T>(func: F<T>, ...args: any[]): T;
16
+ abstract apply(): void;
17
+ abstract seal(): this;
18
+ abstract wrap<T>(func: F<T>, secondary: boolean): F<T>;
19
+ abstract cancel(error: Error, retryAfterOrIgnore?: Worker | null): this;
20
+ abstract readonly isCanceled: boolean;
21
+ abstract readonly isFinished: boolean;
22
+ whenFinished(): Promise<void>;
23
+ static create(options: SnapshotOptions | null): Transaction;
24
+ static run<T>(options: SnapshotOptions | null, func: F<T>, ...args: any[]): T;
25
+ static standalone<T>(func: F<T>, ...args: any[]): T;
26
+ static off<T>(func: F<T>, ...args: any[]): T;
27
+ static isFrameOver(everyN?: number, timeLimit?: number): boolean;
28
+ static requestNextFrame(sleepTime?: number): Promise<void>;
29
+ static get isCanceled(): boolean;
30
+ }
@@ -0,0 +1,313 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.Transaction = void 0;
13
+ const Utils_1 = require("../util/Utils");
14
+ const Dbg_1 = require("../util/Dbg");
15
+ const Changeset_1 = require("./Changeset");
16
+ class Transaction {
17
+ static get current() { return TransactionImpl.current; }
18
+ whenFinished() {
19
+ return __awaiter(this, void 0, void 0, function* () { });
20
+ }
21
+ static create(options) { return new TransactionImpl(options); }
22
+ static run(options, func, ...args) { return TransactionImpl.run(options, func, ...args); }
23
+ static standalone(func, ...args) { return TransactionImpl.standalone(func, ...args); }
24
+ static off(func, ...args) { return TransactionImpl.off(func, ...args); }
25
+ static isFrameOver(everyN = 1, timeLimit = 10) { return TransactionImpl.isFrameOver(everyN, timeLimit); }
26
+ static requestNextFrame(sleepTime = 0) { return TransactionImpl.requestNextFrame(sleepTime); }
27
+ static get isCanceled() { return TransactionImpl.current.isCanceled; }
28
+ }
29
+ exports.Transaction = Transaction;
30
+ class TransactionImpl extends Transaction {
31
+ constructor(options) {
32
+ super();
33
+ this.margin = TransactionImpl.curr !== undefined ? TransactionImpl.curr.margin + 1 : -1;
34
+ this.changeset = new Changeset_1.Changeset(options);
35
+ this.pending = 0;
36
+ this.sealed = false;
37
+ this.canceled = undefined;
38
+ this.after = undefined;
39
+ this.promise = undefined;
40
+ this.resolve = Utils_1.UNDEF;
41
+ this.reject = Utils_1.UNDEF;
42
+ }
43
+ static get current() { return TransactionImpl.curr; }
44
+ get id() { return this.changeset.id; }
45
+ get hint() { return this.changeset.hint; }
46
+ get options() { return this.changeset.options; }
47
+ get timestamp() { return this.changeset.timestamp; }
48
+ get error() { return this.canceled; }
49
+ run(func, ...args) {
50
+ this.guard();
51
+ return this.runImpl(undefined, func, ...args);
52
+ }
53
+ inspect(func, ...args) {
54
+ const restore = TransactionImpl.inspection;
55
+ try {
56
+ TransactionImpl.inspection = true;
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
+ return this.runImpl(undefined, func, ...args);
60
+ }
61
+ finally {
62
+ TransactionImpl.inspection = restore;
63
+ }
64
+ }
65
+ apply() {
66
+ if (this.pending > 0)
67
+ throw (0, Dbg_1.misuse)('cannot apply transaction having active operations running');
68
+ if (this.canceled)
69
+ throw (0, Dbg_1.misuse)(`cannot apply transaction that is already canceled: ${this.canceled}`);
70
+ this.seal();
71
+ }
72
+ seal() {
73
+ if (!this.sealed)
74
+ this.run(TransactionImpl.seal, this, undefined, undefined);
75
+ return this;
76
+ }
77
+ wrap(func, error) {
78
+ this.guard();
79
+ const self = this;
80
+ const inspect = TransactionImpl.inspection;
81
+ if (!inspect)
82
+ self.run(TransactionImpl.wrapperEnter, self, error);
83
+ else
84
+ self.inspect(TransactionImpl.wrapperEnter, self, error);
85
+ const wrappedForTransaction = (...args) => {
86
+ if (!inspect)
87
+ return self.runImpl(undefined, TransactionImpl.wrapperLeave, self, error, func, ...args);
88
+ else
89
+ return self.inspect(TransactionImpl.wrapperLeave, self, error, func, ...args);
90
+ };
91
+ return wrappedForTransaction;
92
+ }
93
+ static wrapperEnter(t, error) {
94
+ if (!error)
95
+ t.pending++;
96
+ }
97
+ static wrapperLeave(t, error, func, ...args) {
98
+ t.pending--;
99
+ const result = func(...args);
100
+ return result;
101
+ }
102
+ cancel(error, restartAfter) {
103
+ this.runImpl(undefined, TransactionImpl.seal, this, error, restartAfter === null ? TransactionImpl.none : restartAfter);
104
+ return this;
105
+ }
106
+ get isCanceled() {
107
+ return this.canceled !== undefined;
108
+ }
109
+ get isFinished() {
110
+ return this.sealed && this.pending === 0;
111
+ }
112
+ whenFinished() {
113
+ return __awaiter(this, void 0, void 0, function* () {
114
+ if (!this.isFinished)
115
+ yield this.acquirePromise();
116
+ });
117
+ }
118
+ static run(options, func, ...args) {
119
+ const t = TransactionImpl.acquire(options);
120
+ const root = t !== TransactionImpl.curr;
121
+ t.guard();
122
+ let result = t.runImpl(options === null || options === void 0 ? void 0 : options.logging, func, ...args);
123
+ if (root) {
124
+ if (result instanceof Promise) {
125
+ result = TransactionImpl.off(() => {
126
+ return t.wrapToRetry(t.wrapToWaitUntilFinish(result), func, ...args);
127
+ });
128
+ }
129
+ t.seal();
130
+ }
131
+ return result;
132
+ }
133
+ static standalone(func, ...args) {
134
+ return TransactionImpl.run({ standalone: true }, func, ...args);
135
+ }
136
+ static off(func, ...args) {
137
+ const outer = TransactionImpl.curr;
138
+ try {
139
+ TransactionImpl.curr = TransactionImpl.none;
140
+ return func(...args);
141
+ }
142
+ finally {
143
+ TransactionImpl.curr = outer;
144
+ }
145
+ }
146
+ static isFrameOver(everyN = 1, timeLimit = 10) {
147
+ TransactionImpl.frameOverCounter++;
148
+ let result = TransactionImpl.frameOverCounter % everyN === 0;
149
+ if (result) {
150
+ const ms = performance.now() - TransactionImpl.frameStartTime;
151
+ result = ms > timeLimit;
152
+ }
153
+ return result;
154
+ }
155
+ static requestNextFrame(sleepTime = 0) {
156
+ return (0, Utils_1.pause)(sleepTime);
157
+ }
158
+ static acquire(options) {
159
+ const curr = TransactionImpl.curr;
160
+ if ((options === null || options === void 0 ? void 0 : options.standalone) || curr.isFinished || curr.options.standalone === 'isolated')
161
+ return new TransactionImpl(options);
162
+ else
163
+ return TransactionImpl.curr;
164
+ }
165
+ guard() {
166
+ if (this.sealed && TransactionImpl.curr !== this)
167
+ throw (0, Dbg_1.misuse)('cannot run transaction that is already sealed');
168
+ }
169
+ wrapToRetry(p, func, ...args) {
170
+ return __awaiter(this, void 0, void 0, function* () {
171
+ try {
172
+ const result = yield p;
173
+ if (this.canceled)
174
+ throw this.canceled;
175
+ return result;
176
+ }
177
+ catch (error) {
178
+ if (this.after !== TransactionImpl.none) {
179
+ if (this.after) {
180
+ yield this.after.whenFinished();
181
+ const options = {
182
+ hint: `${this.hint} - restart after T${this.after.id}`,
183
+ standalone: this.options.standalone === 'isolated' ? 'isolated' : true,
184
+ logging: this.changeset.options.logging,
185
+ token: this.changeset.options.token,
186
+ };
187
+ return TransactionImpl.run(options, func, ...args);
188
+ }
189
+ else
190
+ throw error;
191
+ }
192
+ else
193
+ return undefined;
194
+ }
195
+ });
196
+ }
197
+ wrapToWaitUntilFinish(p) {
198
+ return __awaiter(this, void 0, void 0, function* () {
199
+ const result = yield p;
200
+ yield this.whenFinished();
201
+ return result;
202
+ });
203
+ }
204
+ runImpl(logging, func, ...args) {
205
+ let result;
206
+ const outer = TransactionImpl.curr;
207
+ try {
208
+ if (outer === TransactionImpl.none) {
209
+ TransactionImpl.frameStartTime = performance.now();
210
+ TransactionImpl.frameOverCounter = 0;
211
+ }
212
+ TransactionImpl.curr = this;
213
+ this.pending++;
214
+ this.changeset.acquire(outer.changeset);
215
+ result = func(...args);
216
+ if (this.sealed && this.pending === 1) {
217
+ if (!this.canceled)
218
+ this.checkForConflicts();
219
+ else if (!this.after)
220
+ throw this.canceled;
221
+ }
222
+ }
223
+ catch (e) {
224
+ if (!TransactionImpl.inspection)
225
+ this.cancel(e);
226
+ throw e;
227
+ }
228
+ finally {
229
+ this.pending--;
230
+ if (this.sealed && this.pending === 0) {
231
+ const reactions = this.applyOrDiscard();
232
+ TransactionImpl.curr = outer;
233
+ TransactionImpl.off(Changeset_1.Changeset.enqueueReactionsToRun, reactions);
234
+ }
235
+ else
236
+ TransactionImpl.curr = outer;
237
+ }
238
+ return result;
239
+ }
240
+ static seal(t, error, after) {
241
+ if (!t.canceled && error) {
242
+ t.canceled = error;
243
+ t.after = after;
244
+ if (Dbg_1.Log.isOn && Dbg_1.Log.opt.transaction) {
245
+ Dbg_1.Log.write('║', ' [!]', `${error.message}`, undefined, ' *** CANCEL ***');
246
+ if (after && after !== TransactionImpl.none)
247
+ Dbg_1.Log.write('║', ' [!]', `T${t.id}[${t.hint}] will be restarted${t !== after ? ` after T${after.id}[${after.hint}]` : ''}`);
248
+ }
249
+ Changeset_1.Changeset.revokeAllSubscriptions(t.changeset);
250
+ }
251
+ t.sealed = true;
252
+ }
253
+ checkForConflicts() {
254
+ const conflicts = this.changeset.rebase();
255
+ if (conflicts)
256
+ this.tryResolveConflicts(conflicts);
257
+ }
258
+ tryResolveConflicts(conflicts) {
259
+ throw (0, Dbg_1.error)(`T${this.id}[${this.hint}] conflicts with: ${Changeset_1.Dump.conflicts(conflicts)}`, undefined);
260
+ }
261
+ applyOrDiscard() {
262
+ let reactions;
263
+ try {
264
+ if (Dbg_1.Log.isOn && Dbg_1.Log.opt.change)
265
+ Dbg_1.Log.write('╠═', '', '', undefined, 'changes');
266
+ reactions = this.changeset.applyOrDiscard(this.canceled);
267
+ this.changeset.triggerGarbageCollection();
268
+ if (this.promise) {
269
+ if (this.canceled && !this.after)
270
+ this.reject(this.canceled);
271
+ else
272
+ this.resolve();
273
+ }
274
+ if (Dbg_1.Log.isOn)
275
+ Object.freeze(this);
276
+ }
277
+ catch (e) {
278
+ (0, Dbg_1.fatal)(e);
279
+ throw e;
280
+ }
281
+ return reactions;
282
+ }
283
+ acquirePromise() {
284
+ if (!this.promise) {
285
+ this.promise = new Promise((resolve, reject) => {
286
+ this.resolve = resolve;
287
+ this.reject = reject;
288
+ });
289
+ }
290
+ return this.promise;
291
+ }
292
+ static getCurrentChangeset() {
293
+ return TransactionImpl.curr.changeset;
294
+ }
295
+ static getEditableChangeset() {
296
+ if (TransactionImpl.inspection)
297
+ throw (0, Dbg_1.misuse)('cannot make changes during transaction inspection');
298
+ return TransactionImpl.curr.changeset;
299
+ }
300
+ static _init() {
301
+ Changeset_1.Changeset.current = TransactionImpl.getCurrentChangeset;
302
+ Changeset_1.Changeset.edit = TransactionImpl.getEditableChangeset;
303
+ TransactionImpl.none.sealed = true;
304
+ TransactionImpl.none.changeset.applyOrDiscard();
305
+ Changeset_1.Changeset._init();
306
+ }
307
+ }
308
+ TransactionImpl.none = new TransactionImpl({ hint: 'Transaction.off' });
309
+ TransactionImpl.curr = TransactionImpl.none;
310
+ TransactionImpl.inspection = false;
311
+ TransactionImpl.frameStartTime = 0;
312
+ TransactionImpl.frameOverCounter = 0;
313
+ TransactionImpl._init();
@@ -0,0 +1,15 @@
1
+ import { LoggingOptions } from '../Logging';
2
+ export declare function error(message: string, dump: Error | undefined): Error;
3
+ export declare function misuse(message: string, dump?: any): Error;
4
+ export declare function fatal(error: Error): Error;
5
+ export declare class Log {
6
+ static DefaultLevel: LoggingOptions;
7
+ static isOn: boolean;
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
+ }
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Log = exports.fatal = exports.misuse = exports.error = void 0;
4
+ function error(message, dump) {
5
+ if (Log.isOn && Log.opt.error)
6
+ Log.write('█', ' ███', message, undefined, ' *** ERROR ***', dump);
7
+ return new Error(message);
8
+ }
9
+ exports.error = error;
10
+ function misuse(message, dump) {
11
+ const error = new Error(message);
12
+ Log.write(' ', ' ███', message, undefined, ' *** ERROR / MISUSE ***', dump !== null && dump !== void 0 ? dump : error);
13
+ return error;
14
+ }
15
+ exports.misuse = misuse;
16
+ function fatal(error) {
17
+ Log.write(' ', ' ███', error.message, undefined, ' *** FATAL ***', error);
18
+ return error;
19
+ }
20
+ exports.fatal = fatal;
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');
30
+ }
31
+ else if (Log.isOn)
32
+ Log.write('', '', 'Reactronic logging is turned off');
33
+ Log.isOn = isOn;
34
+ }
35
+ static write(bar, tran, message, ms = 0, highlight = undefined, dump) {
36
+ Log.writeAs(undefined, bar, tran, message, ms, highlight, dump);
37
+ }
38
+ static writeAs(options, bar, tran, message, ms = 0, highlight = undefined, dump) {
39
+ const t = Log.getMergedLoggingOptions(options);
40
+ const margin1 = ' '.repeat(t.margin1 >= 0 ? t.margin1 : 0);
41
+ const margin2 = ' '.repeat(t.margin2);
42
+ const enabled = (options && options.enabled !== undefined) ? options.enabled : t.enabled;
43
+ if (enabled) {
44
+ console.log('\x1b[37m%s\x1b[0m \x1b[' + t.color + 'm%s %s%s\x1b[0m \x1b[' + t.color + 'm%s%s\x1b[0m \x1b[' + t.color + 'm%s\x1b[0m%s', '', t.prefix, t.transaction ? margin1 : '', t.transaction ? bar : bar.replace(/./g, ' '), margin2, tran, message, (highlight !== undefined ? `${highlight}` : '') + (ms > 2 ? ` [ ${ms}ms ]` : ''));
45
+ if (dump)
46
+ console.log(dump);
47
+ }
48
+ }
49
+ static merge(t, color, prefix, existing) {
50
+ const result = !t ? Object.assign({}, existing) : {
51
+ enabled: t.enabled !== undefined ? t.enabled : existing.enabled,
52
+ transaction: t.transaction !== undefined ? t.transaction : existing.transaction,
53
+ operation: t.operation !== undefined ? t.operation : existing.operation,
54
+ step: t.step !== undefined ? t.step : existing.step,
55
+ monitor: t.monitor !== undefined ? t.monitor : existing.monitor,
56
+ read: t.read !== undefined ? t.read : existing.read,
57
+ write: t.write !== undefined ? t.write : existing.write,
58
+ change: t.change !== undefined ? t.change : existing.change,
59
+ obsolete: t.obsolete !== undefined ? t.obsolete : existing.obsolete,
60
+ error: t.error !== undefined ? t.error : existing.error,
61
+ warning: t.warning !== undefined ? t.warning : existing.warning,
62
+ gc: t.gc !== undefined ? t.gc : existing.gc,
63
+ color: t.color !== undefined ? t.color : existing.color,
64
+ prefix: t.prefix !== undefined ? t.prefix : existing.prefix,
65
+ margin1: t.margin1 !== undefined ? t.margin1 : existing.margin1,
66
+ margin2: t.margin2 !== undefined ? t.margin2 : existing.margin2,
67
+ };
68
+ if (color !== undefined)
69
+ result.color = color;
70
+ if (prefix !== undefined)
71
+ result.prefix = prefix;
72
+ return result;
73
+ }
74
+ }
75
+ exports.Log = Log;
76
+ Log.DefaultLevel = {
77
+ enabled: true,
78
+ error: false,
79
+ warning: false,
80
+ transaction: false,
81
+ operation: false,
82
+ step: false,
83
+ monitor: false,
84
+ read: false,
85
+ write: false,
86
+ change: false,
87
+ obsolete: false,
88
+ gc: false,
89
+ color: 37,
90
+ prefix: '',
91
+ margin1: 0,
92
+ margin2: 0,
93
+ };
94
+ Log.isOn = false;
95
+ Log.global = Log.DefaultLevel;
96
+ Log.getMergedLoggingOptions = (local) => Log.global;
@@ -0,0 +1,14 @@
1
+ export interface Sealable<T> {
2
+ toMutable(): T;
3
+ [Sealant.SealedType]: object;
4
+ }
5
+ export interface Sealed<T> {
6
+ [Sealant.CreateCopy]?: () => T;
7
+ }
8
+ export declare abstract class Sealant {
9
+ static readonly SealedType: unique symbol;
10
+ static readonly CreateCopy: unique symbol;
11
+ static seal<T extends Sealable<T>>(collection: T, sealedType: object, typeName: string, member: any): T;
12
+ static toMutable<T extends Sealable<T>>(collection: T): T;
13
+ static error(collection: Sealed<any>): Error;
14
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Sealant = void 0;
4
+ const Dbg_1 = require("./Dbg");
5
+ class Sealant {
6
+ static seal(collection, sealedType, typeName, member) {
7
+ let result = collection;
8
+ const createCopy = result[Sealant.CreateCopy];
9
+ if (createCopy)
10
+ result = createCopy.call(result);
11
+ if (Dbg_1.Log.isOn && Dbg_1.Log.opt.write)
12
+ Dbg_1.Log.write('║', ' ', `${typeName}.${member.toString()} - collection is sealed`);
13
+ Object.setPrototypeOf(result, sealedType);
14
+ Object.freeze(result);
15
+ return result;
16
+ }
17
+ static toMutable(collection) {
18
+ const a = collection;
19
+ const createCopy = a[Sealant.CreateCopy];
20
+ if (createCopy)
21
+ collection = createCopy.call(collection);
22
+ return collection;
23
+ }
24
+ static error(collection) {
25
+ return (0, Dbg_1.misuse)('use toMutable to create mutable copy of sealed collection');
26
+ }
27
+ }
28
+ exports.Sealant = Sealant;
29
+ Sealant.SealedType = Symbol('rxSealedType');
30
+ Sealant.CreateCopy = Symbol('rxCreateCopy');
@@ -0,0 +1,16 @@
1
+ import { Sealant, Sealed } from './Sealant';
2
+ declare global {
3
+ interface Array<T> {
4
+ toMutable(): Array<T>;
5
+ [Sealant.SealedType]: object;
6
+ }
7
+ }
8
+ export declare abstract class SealedArray<T> extends Array<T> implements Sealed<Array<T>> {
9
+ pop(): T | undefined;
10
+ push(...items: T[]): number;
11
+ sort(compareFn?: (a: T, b: T) => number): this;
12
+ splice(start: number, deleteCount?: number): T[];
13
+ unshift(...items: T[]): number;
14
+ [Sealant.CreateCopy](): Array<T>;
15
+ slice(start?: number, end?: number): T[];
16
+ }
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SealedArray = void 0;
4
+ const Sealant_1 = require("./Sealant");
5
+ class SealedArray extends Array {
6
+ pop() { throw Sealant_1.Sealant.error(this); }
7
+ push(...items) { throw Sealant_1.Sealant.error(this); }
8
+ sort(compareFn) { throw Sealant_1.Sealant.error(this); }
9
+ splice(start, deleteCount, ...items) { throw Sealant_1.Sealant.error(this); }
10
+ unshift(...items) { throw Sealant_1.Sealant.error(this); }
11
+ [Sealant_1.Sealant.CreateCopy]() { return this.slice(); }
12
+ slice(start, end) {
13
+ const result = super.slice(start, end);
14
+ Object.setPrototypeOf(result, Array.prototype);
15
+ return result;
16
+ }
17
+ }
18
+ exports.SealedArray = SealedArray;
19
+ Object.defineProperty(Array.prototype, 'toMutable', {
20
+ configurable: false, enumerable: false,
21
+ value() {
22
+ return Sealant_1.Sealant.toMutable(this);
23
+ },
24
+ });
25
+ Object.defineProperty(Array.prototype, Sealant_1.Sealant.SealedType, {
26
+ value: SealedArray.prototype,
27
+ configurable: false, enumerable: false, writable: false,
28
+ });
@@ -0,0 +1,13 @@
1
+ import { Sealant, Sealed } from './Sealant';
2
+ declare global {
3
+ interface Map<K, V> {
4
+ toMutable(): Map<K, V>;
5
+ [Sealant.SealedType]: object;
6
+ }
7
+ }
8
+ export declare abstract class SealedMap<K, V> extends Map<K, V> implements Sealed<Map<K, V>> {
9
+ clear(): void;
10
+ delete(key: K): boolean;
11
+ set(key: K, value: V): this;
12
+ [Sealant.CreateCopy](): Map<K, V>;
13
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SealedMap = void 0;
4
+ const Sealant_1 = require("./Sealant");
5
+ class SealedMap extends Map {
6
+ clear() { throw Sealant_1.Sealant.error(this); }
7
+ delete(key) { throw Sealant_1.Sealant.error(this); }
8
+ set(key, value) { throw Sealant_1.Sealant.error(this); }
9
+ [Sealant_1.Sealant.CreateCopy]() { return new Map(this.entries()); }
10
+ }
11
+ exports.SealedMap = SealedMap;
12
+ Object.defineProperty(Map.prototype, 'toMutable', {
13
+ configurable: false, enumerable: false,
14
+ value() {
15
+ return Sealant_1.Sealant.toMutable(this);
16
+ },
17
+ });
18
+ Object.defineProperty(Map.prototype, Sealant_1.Sealant.SealedType, {
19
+ value: SealedMap.prototype,
20
+ configurable: false, enumerable: false, writable: false,
21
+ });
@@ -0,0 +1,13 @@
1
+ import { Sealant, Sealed } from './Sealant';
2
+ declare global {
3
+ interface Set<T> {
4
+ toMutable(): Set<T>;
5
+ [Sealant.SealedType]: object;
6
+ }
7
+ }
8
+ export declare abstract class SealedSet<T> extends Set<T> implements Sealed<Set<T>> {
9
+ add(value: T): this;
10
+ clear(): void;
11
+ delete(value: T): boolean;
12
+ [Sealant.CreateCopy](): Set<T>;
13
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SealedSet = void 0;
4
+ const Sealant_1 = require("./Sealant");
5
+ class SealedSet extends Set {
6
+ add(value) { throw Sealant_1.Sealant.error(this); }
7
+ clear() { throw Sealant_1.Sealant.error(this); }
8
+ delete(value) { throw Sealant_1.Sealant.error(this); }
9
+ [Sealant_1.Sealant.CreateCopy]() { return new Set(this.values()); }
10
+ }
11
+ exports.SealedSet = SealedSet;
12
+ Object.defineProperty(Set.prototype, 'toMutable', {
13
+ configurable: false, enumerable: false,
14
+ value() {
15
+ return Sealant_1.Sealant.toMutable(this);
16
+ },
17
+ });
18
+ Object.defineProperty(Set.prototype, Sealant_1.Sealant.SealedType, {
19
+ value: SealedSet.prototype,
20
+ configurable: false, enumerable: false, writable: false,
21
+ });
@@ -0,0 +1,9 @@
1
+ export declare type F<T> = (...args: any[]) => T;
2
+ export declare class Utils {
3
+ static freezeSet<T>(obj?: Set<T>): Set<T> | undefined;
4
+ static freezeMap<K, V>(obj?: Map<K, V>): Map<K, V> | undefined;
5
+ static copyAllMembers(source: any, target: any): any;
6
+ }
7
+ export declare function UNDEF(...args: any[]): never;
8
+ export declare function all(promises: Array<Promise<any>>): Promise<any[]>;
9
+ export declare function pause<T>(timeout: number): Promise<T>;