reactronic 0.24.275 → 0.24.302

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.
@@ -1,9 +1,9 @@
1
1
  import { LoggingOptions } from "../Logging.js";
2
2
  import { MergeListReader, MergedItem } from "../util/MergeList.js";
3
3
  import { MemberOptions } from "../Options.js";
4
- export type Script<T> = (el: T, basis: () => void) => void;
5
- export type ScriptAsync<T> = (el: T, basis: () => Promise<void>) => Promise<void>;
6
- export type Handler<T = unknown, R = void> = (el: T) => R;
4
+ export type Script<E> = (el: E, basis: () => void) => void;
5
+ export type ScriptAsync<E> = (el: E, basis: () => Promise<void>) => Promise<void>;
6
+ export type Handler<E = unknown, R = void> = (el: E) => R;
7
7
  export declare enum Mode {
8
8
  default = 0,
9
9
  independentUpdate = 1,
@@ -56,11 +56,13 @@ export declare abstract class RxNode<E = unknown> {
56
56
  static setDefaultLoggingOptions(logging?: LoggingOptions): void;
57
57
  }
58
58
  export type RxNodeDecl<E = unknown> = {
59
+ isAsync?: boolean;
59
60
  script?: Script<E>;
60
61
  scriptAsync?: ScriptAsync<E>;
61
62
  key?: string;
62
63
  mode?: Mode;
63
64
  creation?: Script<E>;
65
+ creationAsync?: ScriptAsync<E>;
64
66
  destruction?: Script<E>;
65
67
  triggers?: unknown;
66
68
  basis?: RxNodeDecl<E>;
@@ -83,10 +85,10 @@ export type RxNodeContext<T extends Object = Object> = {
83
85
  export declare abstract class BaseDriver<E = unknown> implements RxNodeDriver<E> {
84
86
  readonly name: string;
85
87
  readonly isPartition: boolean;
86
- readonly initialize?: Handler<E, void> | undefined;
87
- constructor(name: string, isPartition: boolean, initialize?: Handler<E, void> | undefined);
88
+ readonly initialize?: Handler<E> | undefined;
89
+ constructor(name: string, isPartition: boolean, initialize?: Handler<E> | undefined);
88
90
  abstract allocate(node: RxNode<E>): E;
89
- create(node: RxNode<E>): void;
91
+ create(node: RxNode<E>): void | Promise<void>;
90
92
  destroy(node: RxNode<E>, isLeader: boolean): boolean;
91
93
  mount(node: RxNode<E>): void;
92
94
  update(node: RxNode<E>): void | Promise<void>;
@@ -16,9 +16,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
16
16
  step((generator = generator.apply(thisArg, _arguments || [])).next());
17
17
  });
18
18
  };
19
+ import { misuse } from "../util/Dbg.js";
19
20
  import { MergeList } from "../util/MergeList.js";
20
- import { emitLetters, getCallerInfo } from "../util/Utils.js";
21
- import { Reentrance } from "../Options.js";
21
+ import { emitLetters, getCallerInfo, proceedSyncOrAsync } from "../util/Utils.js";
22
+ import { Isolation, Reentrance } from "../Options.js";
22
23
  import { ObservableObject } from "../core/Mvcc.js";
23
24
  import { Transaction } from "../core/Transaction.js";
24
25
  import { RxSystem, options, raw, reactive, unobs } from "../RxSystem.js";
@@ -152,7 +153,7 @@ export class BaseDriver {
152
153
  create(node) {
153
154
  var _a;
154
155
  (_a = this.initialize) === null || _a === void 0 ? void 0 : _a.call(this, node.element);
155
- invokeCreationUsingBasisChain(node.element, node.declaration);
156
+ return invokeCreationUsingBasisChain(node.element, node.declaration);
156
157
  }
157
158
  destroy(node, isLeader) {
158
159
  invokeDestructionUsingBasisChain(node.element, node.declaration);
@@ -161,7 +162,7 @@ export class BaseDriver {
161
162
  mount(node) {
162
163
  }
163
164
  update(node) {
164
- invokeScriptUsingBasisChain(node.element, node.declaration);
165
+ return invokeScriptUsingBasisChain(node.element, node.declaration);
165
166
  }
166
167
  child(ownerNode, childDriver, childDeclaration, childBasis) {
167
168
  return undefined;
@@ -199,20 +200,40 @@ function getModeUsingBasisChain(declaration) {
199
200
  return (_a = declaration === null || declaration === void 0 ? void 0 : declaration.mode) !== null && _a !== void 0 ? _a : ((declaration === null || declaration === void 0 ? void 0 : declaration.basis) ? getModeUsingBasisChain(declaration === null || declaration === void 0 ? void 0 : declaration.basis) : Mode.default);
200
201
  }
201
202
  function invokeScriptUsingBasisChain(element, declaration) {
203
+ let result = undefined;
202
204
  const basis = declaration.basis;
203
205
  const script = declaration.script;
204
- if (script)
205
- script(element, basis ? () => invokeScriptUsingBasisChain(element, basis) : NOP);
206
+ const scriptAsync = declaration.scriptAsync;
207
+ if (script && scriptAsync) {
208
+ throw misuse("'script' and 'scriptAsync' cannot be defined together");
209
+ }
210
+ if (script) {
211
+ result = script(element, basis ? () => invokeScriptUsingBasisChain(element, basis) : NOP);
212
+ }
213
+ else if (scriptAsync) {
214
+ result = scriptAsync(element, basis ? () => invokeScriptUsingBasisChain(element, basis) : NOP_ASYNC);
215
+ }
206
216
  else if (basis)
207
- invokeScriptUsingBasisChain(element, basis);
217
+ result = invokeScriptUsingBasisChain(element, basis);
218
+ return result;
208
219
  }
209
220
  function invokeCreationUsingBasisChain(element, declaration) {
221
+ let result = undefined;
210
222
  const basis = declaration.basis;
211
223
  const creation = declaration.creation;
212
- if (creation)
213
- creation(element, basis ? () => invokeCreationUsingBasisChain(element, basis) : NOP);
224
+ const creationAsync = declaration.creationAsync;
225
+ if (creation && creationAsync) {
226
+ throw misuse("'creation' and 'creationAsync' cannot be defined together");
227
+ }
228
+ if (creation) {
229
+ result = creation(element, basis ? () => invokeCreationUsingBasisChain(element, basis) : NOP);
230
+ }
231
+ else if (creationAsync) {
232
+ result = creationAsync(element, basis ? () => invokeCreationUsingBasisChain(element, basis) : NOP_ASYNC);
233
+ }
214
234
  else if (basis)
215
- invokeCreationUsingBasisChain(element, basis);
235
+ result = invokeCreationUsingBasisChain(element, basis);
236
+ return result;
216
237
  }
217
238
  function invokeDestructionUsingBasisChain(element, declaration) {
218
239
  const basis = declaration.basis;
@@ -281,7 +302,7 @@ class RxNodeImpl extends RxNode {
281
302
  configureReactronic(options) {
282
303
  if (this.stamp < Number.MAX_SAFE_INTEGER - 1 || !this.has(Mode.independentUpdate))
283
304
  throw new Error("reactronic can be configured only for elements with independent update mode and only during activation");
284
- return RxSystem.getReaction(this.update).configure(options);
305
+ return RxSystem.getOperation(this.update).configure(options);
285
306
  }
286
307
  static get ownSeat() {
287
308
  if (!gOwnSeat)
@@ -311,7 +332,7 @@ class RxNodeImpl extends RxNode {
311
332
  node.outer = owner;
312
333
  else
313
334
  node.outer = owner.outer;
314
- Transaction.run({ separation: true }, () => {
335
+ Transaction.run({ isolation: Isolation.joinAsNestedTransaction }, () => {
315
336
  const ctx = node.context;
316
337
  if (ctx) {
317
338
  ctx.variable = variable;
@@ -449,7 +470,7 @@ function triggerUpdateViaSeat(seat) {
449
470
  Transaction.outside(() => {
450
471
  if (RxSystem.isLogging)
451
472
  RxSystem.setLoggingHint(node.element, node.key);
452
- RxSystem.getReaction(node.update).configure({
473
+ RxSystem.getOperation(node.update).configure({
453
474
  order: node.level,
454
475
  });
455
476
  });
@@ -489,10 +510,7 @@ function updateNow(seat) {
489
510
  node.children.beginMerge();
490
511
  const driver = node.driver;
491
512
  result = driver.update(node);
492
- if (result instanceof Promise)
493
- result.then(v => { runUpdateNestedNodesThenDo(undefined, NOP); return v; }, e => { console.log(e); runUpdateNestedNodesThenDo(e !== null && e !== void 0 ? e : new Error("unknown error"), NOP); });
494
- else
495
- runUpdateNestedNodesThenDo(undefined, NOP);
513
+ result = proceedSyncOrAsync(result, v => { runUpdateNestedNodesThenDo(undefined, NOP); return v; }, e => { console.log(e); runUpdateNestedNodesThenDo(e !== null && e !== void 0 ? e : new Error("unknown error"), NOP); });
496
514
  }
497
515
  catch (e) {
498
516
  runUpdateNestedNodesThenDo(e, NOP);
@@ -519,7 +537,7 @@ function triggerDeactivation(seat, isLeader, individual) {
519
537
  else
520
538
  gFirstToDispose = gLastToDispose = seat;
521
539
  if (gFirstToDispose === seat)
522
- Transaction.run({ separation: "disposal", hint: `runDisposalLoop(initiator=${seat.instance.key})` }, () => {
540
+ Transaction.run({ isolation: Isolation.disjoinForInternalDisposal, hint: `runDisposalLoop(initiator=${seat.instance.key})` }, () => {
523
541
  void runDisposalLoop().then(NOP, error => console.log(error));
524
542
  });
525
543
  }
@@ -613,6 +631,7 @@ function defaultReject(error) {
613
631
  }
614
632
  Promise.prototype.then = reactronicDomHookedThen;
615
633
  const NOP = (...args) => { };
634
+ const NOP_ASYNC = (...args) => __awaiter(void 0, void 0, void 0, function* () { });
616
635
  let gOwnSeat = undefined;
617
636
  let gFirstToDispose = undefined;
618
637
  let gLastToDispose = undefined;
@@ -1,6 +1,7 @@
1
1
  import { F } from "../util/Utils.js";
2
2
  import { Worker } from "../Worker.js";
3
3
  import { SnapshotOptions } from "../Options.js";
4
+ import { ObjectHandle, ObjectVersion, Observer, FieldVersion, FieldKey } from "./Data.js";
4
5
  import { Changeset } from "./Changeset.js";
5
6
  export declare abstract class Transaction implements Worker {
6
7
  static get current(): Transaction;
@@ -20,11 +21,69 @@ export declare abstract class Transaction implements Worker {
20
21
  abstract readonly isCanceled: boolean;
21
22
  abstract readonly isFinished: boolean;
22
23
  whenFinished(): Promise<void>;
23
- static create(options: SnapshotOptions | null): Transaction;
24
+ static create(options: SnapshotOptions | null, parent?: Transaction): Transaction;
24
25
  static run<T>(options: SnapshotOptions | null, func: F<T>, ...args: any[]): T;
25
- static separate<T>(func: F<T>, ...args: any[]): T;
26
+ static isolate<T>(func: F<T>, ...args: any[]): T;
26
27
  static outside<T>(func: F<T>, ...args: any[]): T;
27
28
  static isFrameOver(everyN?: number, timeLimit?: number): boolean;
28
29
  static requestNextFrame(sleepTime?: number): Promise<void>;
29
30
  static get isCanceled(): boolean;
30
31
  }
32
+ export declare class TransactionImpl extends Transaction {
33
+ private static readonly none;
34
+ private static curr;
35
+ private static inspection;
36
+ private static frameStartTime;
37
+ private static frameOverCounter;
38
+ readonly margin: number;
39
+ readonly parent?: TransactionImpl;
40
+ readonly changeset: Changeset;
41
+ private pending;
42
+ private sealed;
43
+ private canceled?;
44
+ private after?;
45
+ private promise?;
46
+ private resolve;
47
+ private reject;
48
+ constructor(options: SnapshotOptions | null, parent?: TransactionImpl);
49
+ static get current(): TransactionImpl;
50
+ get id(): number;
51
+ get hint(): string;
52
+ get options(): SnapshotOptions;
53
+ get timestamp(): number;
54
+ get error(): Error | undefined;
55
+ run<T>(func: F<T>, ...args: any[]): T;
56
+ inspect<T>(func: F<T>, ...args: any[]): T;
57
+ apply(): void;
58
+ seal(): this;
59
+ wrap<T>(func: F<T>, error: boolean): F<T>;
60
+ private static wrapperEnter;
61
+ private static wrapperLeave;
62
+ cancel(error: Error, restartAfter?: Worker | null): this;
63
+ get isCanceled(): boolean;
64
+ get isFinished(): boolean;
65
+ whenFinished(): Promise<void>;
66
+ static run<T>(options: SnapshotOptions | null, func: F<T>, ...args: any[]): T;
67
+ static isolate<T>(func: F<T>, ...args: any[]): T;
68
+ static outside<T>(func: F<T>, ...args: any[]): T;
69
+ static isFrameOver(everyN?: number, timeLimit?: number): boolean;
70
+ static requestNextFrame(sleepTime?: number): Promise<void>;
71
+ private static acquire;
72
+ private guard;
73
+ private wrapToRetry;
74
+ private wrapToWaitUntilFinish;
75
+ private runImpl;
76
+ private static seal;
77
+ private checkForConflicts;
78
+ private tryResolveConflicts;
79
+ private applyOrDiscard;
80
+ applyOrDiscardChangeset(): Array<Observer>;
81
+ applyObjectChanges(h: ObjectHandle, ov: ObjectVersion): void;
82
+ static migrateObjectChangesToAnotherTransaction(h: ObjectHandle, ov: ObjectVersion, tParent: Transaction): void;
83
+ static migrateFieldVersionToAnotherTransaction(h: ObjectHandle, fk: FieldKey, ov: ObjectVersion, ovParent: ObjectVersion, tParent: Transaction): void;
84
+ private acquirePromise;
85
+ private static getCurrentChangeset;
86
+ private static getEditableChangeset;
87
+ static migrateFieldVersion: (fv: FieldVersion, target: Transaction) => FieldVersion;
88
+ static _init(): void;
89
+ }
@@ -9,25 +9,28 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { UNDEF, pause } from "../util/Utils.js";
11
11
  import { Log, misuse, error, fatal } from "../util/Dbg.js";
12
- import { Changeset, Dump } from "./Changeset.js";
12
+ import { Isolation } from "../Options.js";
13
+ import { Meta } from "./Data.js";
14
+ import { Changeset, Dump, EMPTY_OBJECT_VERSION, UNDEFINED_REVISION } from "./Changeset.js";
13
15
  export class Transaction {
14
16
  static get current() { return TransactionImpl.current; }
15
17
  whenFinished() {
16
18
  return __awaiter(this, void 0, void 0, function* () { });
17
19
  }
18
- static create(options) { return new TransactionImpl(options); }
20
+ static create(options, parent) { return new TransactionImpl(options, parent); }
19
21
  static run(options, func, ...args) { return TransactionImpl.run(options, func, ...args); }
20
- static separate(func, ...args) { return TransactionImpl.separate(func, ...args); }
22
+ static isolate(func, ...args) { return TransactionImpl.isolate(func, ...args); }
21
23
  static outside(func, ...args) { return TransactionImpl.outside(func, ...args); }
22
24
  static isFrameOver(everyN = 1, timeLimit = 10) { return TransactionImpl.isFrameOver(everyN, timeLimit); }
23
25
  static requestNextFrame(sleepTime = 0) { return TransactionImpl.requestNextFrame(sleepTime); }
24
26
  static get isCanceled() { return TransactionImpl.current.isCanceled; }
25
27
  }
26
- class TransactionImpl extends Transaction {
27
- constructor(options) {
28
+ export class TransactionImpl extends Transaction {
29
+ constructor(options, parent) {
28
30
  super();
29
31
  this.margin = TransactionImpl.curr !== undefined ? TransactionImpl.curr.margin + 1 : -1;
30
- this.changeset = new Changeset(options);
32
+ this.parent = parent;
33
+ this.changeset = new Changeset(options, parent === null || parent === void 0 ? void 0 : parent.changeset);
31
34
  this.pending = 0;
32
35
  this.sealed = false;
33
36
  this.canceled = undefined;
@@ -126,8 +129,8 @@ class TransactionImpl extends Transaction {
126
129
  }
127
130
  return result;
128
131
  }
129
- static separate(func, ...args) {
130
- return TransactionImpl.run({ separation: true }, func, ...args);
132
+ static isolate(func, ...args) {
133
+ return TransactionImpl.run({ isolation: Isolation.disjoinFromOuterTransaction }, func, ...args);
131
134
  }
132
135
  static outside(func, ...args) {
133
136
  const outer = TransactionImpl.curr;
@@ -152,11 +155,17 @@ class TransactionImpl extends Transaction {
152
155
  return pause(sleepTime);
153
156
  }
154
157
  static acquire(options) {
155
- const curr = TransactionImpl.curr;
156
- if ((options === null || options === void 0 ? void 0 : options.separation) || curr.isFinished || curr.options.separation === "isolated")
158
+ var _a;
159
+ const outer = TransactionImpl.curr;
160
+ const isolation = (_a = options === null || options === void 0 ? void 0 : options.isolation) !== null && _a !== void 0 ? _a : Isolation.joinToCurrentTransaction;
161
+ if (outer.isFinished || outer.options.isolation === Isolation.disjoinFromOuterAndInnerTransactions)
162
+ return new TransactionImpl(options);
163
+ else if (isolation === Isolation.joinAsNestedTransaction)
164
+ return new TransactionImpl(options, outer);
165
+ else if (isolation !== Isolation.joinToCurrentTransaction)
157
166
  return new TransactionImpl(options);
158
167
  else
159
- return TransactionImpl.curr;
168
+ return outer;
160
169
  }
161
170
  guard() {
162
171
  if (this.sealed && TransactionImpl.curr !== this)
@@ -176,7 +185,7 @@ class TransactionImpl extends Transaction {
176
185
  yield this.after.whenFinished();
177
186
  const options = {
178
187
  hint: `${this.hint} - restart after T${this.after.id}`,
179
- separation: this.options.separation === "isolated" ? "isolated" : true,
188
+ isolation: this.options.isolation === Isolation.joinToCurrentTransaction ? Isolation.disjoinFromOuterTransaction : this.options.isolation,
180
189
  logging: this.changeset.options.logging,
181
190
  token: this.changeset.options.token,
182
191
  };
@@ -255,11 +264,12 @@ class TransactionImpl extends Transaction {
255
264
  throw error(`T${this.id}[${this.hint}] conflicts with: ${Dump.conflicts(conflicts)}`, undefined);
256
265
  }
257
266
  applyOrDiscard() {
258
- let reactive;
267
+ let observers;
259
268
  try {
260
269
  if (Log.isOn && Log.opt.change)
261
270
  Log.write("╠═", "", "", undefined, "changes");
262
- reactive = this.changeset.applyOrDiscard(this.canceled);
271
+ this.changeset.seal();
272
+ observers = this.applyOrDiscardChangeset();
263
273
  this.changeset.triggerGarbageCollection();
264
274
  if (this.promise) {
265
275
  if (this.canceled && !this.after)
@@ -274,7 +284,159 @@ class TransactionImpl extends Transaction {
274
284
  fatal(e);
275
285
  throw e;
276
286
  }
277
- return reactive;
287
+ return observers;
288
+ }
289
+ applyOrDiscardChangeset() {
290
+ const error = this.canceled;
291
+ const changeset = this.changeset;
292
+ changeset.items.forEach((ov, h) => {
293
+ changeset.sealObjectVersion(h, ov);
294
+ if (!error) {
295
+ this.applyObjectChanges(h, ov);
296
+ if (Changeset.garbageCollectionSummaryInterval < Number.MAX_SAFE_INTEGER) {
297
+ Changeset.totalObjectSnapshotCount++;
298
+ if (ov.former.objectVersion === EMPTY_OBJECT_VERSION)
299
+ Changeset.totalObjectHandleCount++;
300
+ }
301
+ }
302
+ });
303
+ if (Log.isOn) {
304
+ if (Log.opt.change && !error && !changeset.parent) {
305
+ changeset.items.forEach((ov, h) => {
306
+ const fields = [];
307
+ ov.changes.forEach((o, fk) => fields.push(fk.toString()));
308
+ const s = fields.join(", ");
309
+ Log.write("║", "√", `${Dump.snapshot2(h, ov.changeset)} (${s}) is ${ov.former.objectVersion === EMPTY_OBJECT_VERSION ? "constructed" : `applied over #${h.id}t${ov.former.objectVersion.changeset.id}s${ov.former.objectVersion.changeset.timestamp}`}`);
310
+ });
311
+ }
312
+ if (Log.opt.transaction)
313
+ Log.write(changeset.timestamp < UNDEFINED_REVISION ? "╚══" : "═══", `s${this.timestamp}`, `${this.hint} - ${error ? "CANCEL" : "APPLY"}(${this.changeset.items.size})${error ? ` - ${error}` : ""}`);
314
+ }
315
+ if (!error && !this.parent)
316
+ Changeset.propagateAllChangesThroughSubscriptions(changeset);
317
+ return changeset.obsolete;
318
+ }
319
+ applyObjectChanges(h, ov) {
320
+ const parent = this.parent;
321
+ if (parent)
322
+ TransactionImpl.migrateObjectChangesToAnotherTransaction(h, ov, parent);
323
+ else
324
+ h.applied = ov;
325
+ }
326
+ static migrateObjectChangesToAnotherTransaction(h, ov, tParent) {
327
+ const csParent = tParent.changeset;
328
+ const ovParent = csParent.getEditableObjectVersion(h, Meta.Undefined, undefined);
329
+ if (ov.former.objectVersion.changeset === EMPTY_OBJECT_VERSION.changeset) {
330
+ for (const fk in ov.data) {
331
+ if (fk === Meta.Revision) {
332
+ console.log("(!)");
333
+ }
334
+ TransactionImpl.migrateFieldVersionToAnotherTransaction(h, fk, ov, ovParent, tParent);
335
+ }
336
+ }
337
+ else {
338
+ ov.changes.forEach((o, fk) => {
339
+ if (fk === Meta.Revision) {
340
+ console.log("(!)");
341
+ }
342
+ TransactionImpl.migrateFieldVersionToAnotherTransaction(h, fk, ov, ovParent, tParent);
343
+ });
344
+ }
345
+ }
346
+ static migrateFieldVersionToAnotherTransaction(h, fk, ov, ovParent, tParent) {
347
+ const csParent = tParent.changeset;
348
+ const fv = ov.data[fk];
349
+ const fvParent = ovParent.data[fk];
350
+ if (fv.isLaunch) {
351
+ const migrated = TransactionImpl.migrateFieldVersion(fv, tParent);
352
+ if (ovParent.former.objectVersion.data[fk] !== fvParent) {
353
+ let observers = fvParent.observers;
354
+ if (observers) {
355
+ const migratedObservers = migrated.observers = new Set();
356
+ observers.forEach(o => {
357
+ var _a, _b;
358
+ const sub = o.observables.get(fvParent);
359
+ (_a = o.observables) === null || _a === void 0 ? void 0 : _a.delete(fvParent);
360
+ (_b = o.observables) === null || _b === void 0 ? void 0 : _b.set(migrated, sub);
361
+ migratedObservers.add(o);
362
+ });
363
+ fvParent.observers = undefined;
364
+ }
365
+ observers = fv.observers;
366
+ if (observers) {
367
+ let migratedObservers = migrated.observers;
368
+ if (migratedObservers === undefined)
369
+ migratedObservers = migrated.observers = new Set();
370
+ observers.forEach(o => {
371
+ var _a, _b;
372
+ const sub = o.observables.get(fv);
373
+ (_a = o.observables) === null || _a === void 0 ? void 0 : _a.delete(fv);
374
+ (_b = o.observables) === null || _b === void 0 ? void 0 : _b.set(migrated, sub);
375
+ migratedObservers === null || migratedObservers === void 0 ? void 0 : migratedObservers.add(o);
376
+ });
377
+ fv.observers = undefined;
378
+ }
379
+ const observables = fv.observables;
380
+ const migratedObservables = migrated.observables;
381
+ if (observables) {
382
+ observables.forEach((s, o) => {
383
+ var _a, _b;
384
+ (_a = o.observers) === null || _a === void 0 ? void 0 : _a.delete(fv);
385
+ (_b = o.observers) === null || _b === void 0 ? void 0 : _b.add(migrated);
386
+ migratedObservables === null || migratedObservables === void 0 ? void 0 : migratedObservables.set(o, s);
387
+ });
388
+ observables.clear();
389
+ }
390
+ ovParent.data[fk] = migrated;
391
+ }
392
+ else {
393
+ const observers = fv.observers;
394
+ if (observers) {
395
+ const migratedObservers = migrated.observers = new Set();
396
+ observers.forEach(o => {
397
+ var _a, _b;
398
+ const sub = o.observables.get(fv);
399
+ (_a = o.observables) === null || _a === void 0 ? void 0 : _a.delete(fv);
400
+ (_b = o.observables) === null || _b === void 0 ? void 0 : _b.set(migrated, sub);
401
+ migratedObservers.add(o);
402
+ });
403
+ fv.observers = undefined;
404
+ }
405
+ const observables = fv.observables;
406
+ const migratedObservables = migrated.observables;
407
+ if (observables) {
408
+ observables.forEach((s, o) => {
409
+ var _a, _b;
410
+ (_a = o.observers) === null || _a === void 0 ? void 0 : _a.delete(fv);
411
+ (_b = o.observers) === null || _b === void 0 ? void 0 : _b.add(migrated);
412
+ migratedObservables === null || migratedObservables === void 0 ? void 0 : migratedObservables.set(o, s);
413
+ });
414
+ observables.clear();
415
+ }
416
+ ovParent.data[fk] = migrated;
417
+ }
418
+ csParent.bumpBy(ovParent.former.objectVersion.changeset.timestamp);
419
+ Changeset.markEdited(undefined, migrated, true, ovParent, fk, h);
420
+ }
421
+ else {
422
+ const parentContent = fvParent === null || fvParent === void 0 ? void 0 : fvParent.content;
423
+ if (ovParent.former.objectVersion.data[fk] !== fvParent) {
424
+ fvParent.content = fv.content;
425
+ const observers = fv.observers;
426
+ if (observers) {
427
+ observers.forEach(o => {
428
+ var _a, _b, _c;
429
+ const sub = o.observables.get(fv);
430
+ (_a = o.observables) === null || _a === void 0 ? void 0 : _a.delete(fv);
431
+ (_b = o.observables) === null || _b === void 0 ? void 0 : _b.set(fvParent, sub);
432
+ (_c = fvParent.observers) === null || _c === void 0 ? void 0 : _c.add(o);
433
+ });
434
+ }
435
+ }
436
+ else
437
+ ovParent.data[fk] = fv;
438
+ Changeset.markEdited(parentContent, fv.content, true, ovParent, fk, h);
439
+ }
278
440
  }
279
441
  acquirePromise() {
280
442
  if (!this.promise) {
@@ -297,7 +459,7 @@ class TransactionImpl extends Transaction {
297
459
  Changeset.current = TransactionImpl.getCurrentChangeset;
298
460
  Changeset.edit = TransactionImpl.getEditableChangeset;
299
461
  TransactionImpl.none.sealed = true;
300
- TransactionImpl.none.changeset.applyOrDiscard();
462
+ TransactionImpl.none.changeset.seal();
301
463
  Changeset._init();
302
464
  }
303
465
  }
@@ -306,4 +468,7 @@ TransactionImpl.curr = TransactionImpl.none;
306
468
  TransactionImpl.inspection = false;
307
469
  TransactionImpl.frameStartTime = 0;
308
470
  TransactionImpl.frameOverCounter = 0;
471
+ TransactionImpl.migrateFieldVersion = function (fv, target) {
472
+ throw misuse("this implementation of cloneLaunch should never be called");
473
+ };
309
474
  TransactionImpl._init();
@@ -7,6 +7,7 @@ export declare class Utils {
7
7
  export declare function UNDEF(...args: any[]): never;
8
8
  export declare function all(promises: Array<Promise<any>>): Promise<any[]>;
9
9
  export declare function pause<T>(timeout: number): Promise<T>;
10
+ export declare function proceedSyncOrAsync<T>(result: T | Promise<T>, success: (v: any) => T, failure: (e: any) => T): T | Promise<T>;
10
11
  export declare function emitLetters(n: number): string;
11
12
  export declare function objectHasMember<T>(obj: any, member: string): obj is T;
12
13
  export declare function getCallerInfo(prefix: string): string;
@@ -53,6 +53,14 @@ export function pause(timeout) {
53
53
  setTimeout(resolve.bind(null, () => resolve), timeout);
54
54
  });
55
55
  }
56
+ export function proceedSyncOrAsync(result, success, failure) {
57
+ let r;
58
+ if (result instanceof Promise)
59
+ r = result.then(v => success(v), e => failure(e));
60
+ else
61
+ r = success(result);
62
+ return r;
63
+ }
56
64
  export function emitLetters(n) {
57
65
  if (n < 0)
58
66
  throw new Error(`emitLetters: argument (${n}) should not be negative or zero`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reactronic",
3
- "version": "0.24.275",
3
+ "version": "0.24.302",
4
4
  "description": "Reactronic - Transactional Reactive State Management",
5
5
  "publisher": "Nezaboodka Software",
6
6
  "license": "Apache-2.0",
@@ -32,15 +32,15 @@
32
32
  "homepage": "https://github.com/nezaboodka/reactronic/blob/master/README.md#readme",
33
33
  "devDependencies": {
34
34
  "@types/node": "20.11.28",
35
- "@types/react": "18.2.66",
35
+ "@types/react": "18.3.4",
36
36
  "@typescript-eslint/eslint-plugin": "7.2.0",
37
37
  "@typescript-eslint/parser": "7.2.0",
38
38
  "ava": "6.1.2",
39
39
  "c8": "9.1.0",
40
40
  "eslint": "8.57.0",
41
- "react": "18.2.0",
41
+ "react": "18.3.1",
42
42
  "ts-node": "10.9.2",
43
- "typescript": "5.3.2"
43
+ "typescript": "5.5.4"
44
44
  },
45
45
  "scripts": {
46
46
  "build": "eslint source/**.ts test/**.test.ts react/**.tsx && tsc",