reactronic 0.92.25004 → 0.92.25005

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 CHANGED
@@ -24,11 +24,11 @@ Transactional reactivity is based on four fundamental concepts:
24
24
 
25
25
  - **Observable Objects** - a set of objects that store data of an
26
26
  application (state);
27
- - **Applying Function** - it makes changes in observable
27
+ - **Atomic Action** - a function that makes changes in observable
28
28
  objects in atomic way ("all or nothing");
29
- - **Reaction Function** - it is executed automatically in
29
+ - **Reaction** - a function that is executed automatically in
30
30
  response to changes made by a transaction;
31
- - **Cache Function** - its result is remembered and, if the becomes
31
+ - **Cache** - a function which result is remembered and, if the becomes
32
32
  obsolete, recomputed on-demand.
33
33
 
34
34
  Demo application built with Reactronic: https://nevod.io/#/playground.
@@ -45,7 +45,7 @@ class Demo extends ObservableObject {
45
45
  name: string = 'Nezaboodka Software'
46
46
  email: string = 'contact@nezaboodka.com'
47
47
 
48
- @apply
48
+ @atomicAction
49
49
  saveContact(name: string, email: string): void {
50
50
  this.name = name
51
51
  this.email = email
@@ -64,10 +64,10 @@ class Demo extends ObservableObject {
64
64
  In the example above, `Demo` is an observable object,
65
65
  meaning that access to its fields are seamlessly tracked
66
66
  to determine dependent reactions and caches. Reaction
67
- function `printContact` reads `name` and `email` fields,
68
- thus depends on them. It is executed automatically in
69
- response to changes of these fields made by the applying
70
- function `saveContact`.
67
+ `printContact` reads `name` and `email` fields, thus
68
+ depends on them. It is executed automatically in
69
+ response to changes of these fields made by the atomic
70
+ action `saveContact`.
71
71
 
72
72
  Here is an example of a cached value (re-)computed on-demand:
73
73
 
@@ -115,19 +115,19 @@ In the example above, the class `MyModel` is based on Reactronic's
115
115
  `ObservableObject` class and all its properties `url`, `content`,
116
116
  and `timestamp` are hooked.
117
117
 
118
- ## Apply
118
+ ## Atomic Action
119
119
 
120
- Applying function makes changes in observable objects
120
+ Atomic action makes changes in observable objects
121
121
  in transactional (atomic) way, thus provoking execution
122
122
  of dependent reactions and recalculation of dependent
123
- caches. Applying function is instrumented with hooks to
124
- provide transparent atomicity (by implicit context
125
- switching and isolation).
123
+ caches. Atomic action function is instrumented with
124
+ hooks to provide transparent atomicity (by implicit
125
+ context switching and isolation).
126
126
 
127
127
  ``` typescript
128
128
  class MyModel extends ObservableObject {
129
129
  // ...
130
- @apply
130
+ @atomicAction
131
131
  async load(url: string): Promise<void> {
132
132
  this.url = url
133
133
  this.content = await fetch(url)
@@ -136,11 +136,11 @@ class MyModel extends ObservableObject {
136
136
  }
137
137
  ```
138
138
 
139
- In the example above, the applying function `load` makes
139
+ In the example above, the atomic action `load` makes
140
140
  changes to `url`, `content` and `timestamp` properties. While
141
- applying transaction is running, the changes are visible only inside the
142
- transaction itself. The new values become atomically visible outside
143
- of the transaction only upon its completion.
141
+ atomic action is running, the changes are visible only inside the
142
+ action itself. The new values become atomically visible outside
143
+ of the action only upon its completion.
144
144
 
145
145
  Atomicity is achieved by making changes in an isolated data
146
146
  snapshot that is not visible outside of the running transaction
@@ -168,9 +168,9 @@ of asynchronous operations is fully completed.
168
168
  ## Reaction & Cache
169
169
 
170
170
  Reaction function is automatically and immediately called in
171
- response to changes in observable objects made by an applying function.
171
+ response to changes in observable objects made by an atomic action.
172
172
  Cache function is called on-demand to renew the value if it was
173
- marked as obsolete due to changes made by an applying function.
173
+ marked as obsolete due to changes made by an atomic action.
174
174
  Reaction and cache functions are instrumented with hooks
175
175
  to seamlessly subscribe to those observable objects and
176
176
  other cache functions (dependencies), which are used
@@ -212,7 +212,7 @@ class Component<P> extends React.Component<P> {
212
212
  }
213
213
 
214
214
  componentWillUnmount(): void {
215
- apply(RxSystem.dispose, this)
215
+ atomicAction(RxSystem.dispose, this)
216
216
  }
217
217
  }
218
218
  ```
@@ -256,8 +256,8 @@ of recurring changes:
256
256
  - `0` - execute immediately via event loop (asynchronously with zero timeout);
257
257
  - `>= Number.MAX_SAFE_INTEGER` - never execute (suspended reaction).
258
258
 
259
- **Reentrance** option defines how to handle reentrant calls of applying
260
- and reaction functions:
259
+ **Reentrance** option defines how to handle reentrant calls of atomic
260
+ actions and reactions:
261
261
 
262
262
  - `preventWithError` - fail with error if there is an existing call in progress;
263
263
  - `waitAndRestart` - wait for previous call to finish and then restart current one;
@@ -305,7 +305,7 @@ class ObservableObject { }
305
305
 
306
306
  function observable(proto, prop) // field only
307
307
  function unobservable(proto, prop) // field only
308
- function apply(proto, prop, pd) // method only
308
+ function atomicAction(proto, prop, pd) // method only
309
309
  function reaction(proto, prop, pd) // method only
310
310
  function cache(proto, prop, pd) // method only
311
311
  function options(value: Partial<MemberOptions>): F<any>
@@ -8,7 +8,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
10
  import { ObservableObject } from "./core/Mvcc.js";
11
- import { apply } from "./ReactiveSystem.js";
11
+ import { atomicAction } from "./ReactiveSystem.js";
12
12
  export class Clock extends ObservableObject {
13
13
  constructor(interval = 1000) {
14
14
  super();
@@ -40,13 +40,13 @@ export class Clock extends ObservableObject {
40
40
  }
41
41
  }
42
42
  __decorate([
43
- apply,
43
+ atomicAction,
44
44
  __metadata("design:type", Function),
45
45
  __metadata("design:paramtypes", [Boolean]),
46
46
  __metadata("design:returntype", void 0)
47
47
  ], Clock.prototype, "pause", null);
48
48
  __decorate([
49
- apply,
49
+ atomicAction,
50
50
  __metadata("design:type", Function),
51
51
  __metadata("design:paramtypes", []),
52
52
  __metadata("design:returntype", void 0)
@@ -18,11 +18,13 @@ export declare class ReactiveSystem {
18
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
+ export declare function nonreactive2<T>(options: SnapshotOptions, func: F<T>, ...args: any[]): T;
22
+ export declare function nonreactive2<T>(func: F<T>, ...args: any[]): T;
21
23
  export declare function sensitive<T>(sensitivity: boolean, func: F<T>, ...args: any[]): T;
22
24
  export declare function contextually<T>(p: Promise<T>): Promise<T>;
23
- export declare function apply<T>(func: F<T>, ...args: any[]): T;
24
- export declare function apply<T>(options: SnapshotOptions, func: F<T>, ...args: any[]): T;
25
- export declare function apply(proto: object, prop: PropertyKey, pd: PropertyDescriptor): any;
25
+ export declare function atomicAction<T>(func: F<T>, ...args: any[]): T;
26
+ export declare function atomicAction<T>(options: SnapshotOptions, func: F<T>, ...args: any[]): T;
27
+ export declare function atomicAction(proto: object, prop: PropertyKey, pd: PropertyDescriptor): any;
26
28
  export declare function unobservable(proto: object, prop: PropertyKey): any;
27
29
  export declare function observable(proto: object, prop: PropertyKey): any;
28
30
  export declare function reaction(proto: object, prop: PropertyKey, pd: PropertyDescriptor): any;
@@ -25,13 +25,31 @@ export class ReactiveSystem {
25
25
  export function nonreactive(func, ...args) {
26
26
  return OperationImpl.proceedWithinGivenLaunch(undefined, func, ...args);
27
27
  }
28
+ export function nonreactive2(p1, p2, p3) {
29
+ if (p1 instanceof Function) {
30
+ return OperationImpl.proceedWithinGivenLaunch(undefined, () => {
31
+ if (p2 !== undefined)
32
+ return Transaction.run(null, p1, ...p2);
33
+ else
34
+ return Transaction.run(null, p1);
35
+ });
36
+ }
37
+ else {
38
+ return OperationImpl.proceedWithinGivenLaunch(undefined, () => {
39
+ if (p3 !== undefined)
40
+ return Transaction.run(p1, p2, ...p3);
41
+ else
42
+ return Transaction.run(p1, p2);
43
+ });
44
+ }
45
+ }
28
46
  export function sensitive(sensitivity, func, ...args) {
29
47
  return Mvcc.sensitive(sensitivity, func, ...args);
30
48
  }
31
49
  export function contextually(p) {
32
50
  throw new Error("not implemented yet");
33
51
  }
34
- export function apply(p1, p2, p3) {
52
+ export function atomicAction(p1, p2, p3) {
35
53
  if (p1 instanceof Function) {
36
54
  if (p2 !== undefined)
37
55
  return Transaction.run(null, p1, ...p2);
@@ -49,7 +67,7 @@ export function apply(p1, p2, p3) {
49
67
  kind: Kind.apply,
50
68
  isolation: Isolation.joinToCurrentTransaction,
51
69
  };
52
- return Mvcc.decorateOperation(true, apply, opts, p1, p2, p3);
70
+ return Mvcc.decorateOperation(true, atomicAction, opts, p1, p2, p3);
53
71
  }
54
72
  }
55
73
  export function unobservable(proto, prop) {
@@ -1,4 +1,4 @@
1
- import { apply, nonreactive } from "./ReactiveSystem.js";
1
+ import { atomicAction, nonreactive } from "./ReactiveSystem.js";
2
2
  export function refs(owner) {
3
3
  return new Proxy(owner, RefGettingProxy);
4
4
  }
@@ -52,7 +52,7 @@ export class ToggleRef extends Ref {
52
52
  toggle() {
53
53
  const o = this.owner;
54
54
  const p = this.name;
55
- apply({ hint: `toggle ${o.constructor.name}.${p}` }, () => {
55
+ atomicAction({ hint: `toggle ${o.constructor.name}.${p}` }, () => {
56
56
  const v = o[p];
57
57
  const isOn = v === this.valueOn || (v instanceof Ref && this.valueOn instanceof Ref &&
58
58
  Ref.sameRefs(v, this.valueOn));
@@ -16,7 +16,7 @@ export { Changeset } from "./core/Changeset.js";
16
16
  export { Transaction } from "./core/Transaction.js";
17
17
  export { Indicator } from "./core/Indicator.js";
18
18
  export { Journal } from "./core/Journal.js";
19
- export { ReactiveSystem, observable, unobservable, apply, reaction, cache, nonreactive, sensitive, contextually, options } from "./ReactiveSystem.js";
19
+ export { ReactiveSystem, observable, unobservable, atomicAction, reaction, cache, nonreactive, sensitive, contextually, options } from "./ReactiveSystem.js";
20
20
  export { Reaction } from "./Reaction.js";
21
21
  export { ReactiveNode, Mode, Priority, BaseDriver, ReactiveNodeVariable } from "./core/ReactiveNode.js";
22
22
  export type { Script, ScriptAsync, Handler, ReactiveNodeDecl, ReactiveNodeDriver, ReactiveNodeContext } from "./core/ReactiveNode.js";
@@ -12,7 +12,7 @@ export { Changeset } from "./core/Changeset.js";
12
12
  export { Transaction } from "./core/Transaction.js";
13
13
  export { Indicator } from "./core/Indicator.js";
14
14
  export { Journal } from "./core/Journal.js";
15
- export { ReactiveSystem, observable, unobservable, apply, reaction, cache, nonreactive, sensitive, contextually, options } from "./ReactiveSystem.js";
15
+ export { ReactiveSystem, observable, unobservable, atomicAction, reaction, cache, nonreactive, sensitive, contextually, options } from "./ReactiveSystem.js";
16
16
  export { Reaction } from "./Reaction.js";
17
17
  export { ReactiveNode, Mode, Priority, BaseDriver, ReactiveNodeVariable } from "./core/ReactiveNode.js";
18
18
  export { Clock } from "./Clock.js";
@@ -744,8 +744,8 @@ function reactronicHookedThen(resolve, reject) {
744
744
  resolve = launch.wrap(resolve);
745
745
  reject = launch.wrap(reject);
746
746
  }
747
- resolve = tran.wrap(resolve, false);
748
- reject = tran.wrap(reject, true);
747
+ resolve = tran.wrapAsPending(resolve, false);
748
+ reject = tran.wrapAsPending(reject, true);
749
749
  }
750
750
  return ORIGINAL_PROMISE_THEN.call(this, resolve, reject);
751
751
  }
@@ -22,7 +22,7 @@ import { emitLetters, getCallerInfo, proceedSyncOrAsync } from "../util/Utils.js
22
22
  import { Isolation, Reentrance } from "../Options.js";
23
23
  import { ObservableObject } from "../core/Mvcc.js";
24
24
  import { Transaction } from "../core/Transaction.js";
25
- import { ReactiveSystem, options, unobservable, reaction, nonreactive, apply } from "../ReactiveSystem.js";
25
+ import { ReactiveSystem, options, unobservable, reaction, nonreactive, atomicAction } from "../ReactiveSystem.js";
26
26
  export var Mode;
27
27
  (function (Mode) {
28
28
  Mode[Mode["default"] = 0] = "default";
@@ -339,7 +339,7 @@ class ReactiveNodeImpl extends ReactiveNode {
339
339
  node.outer = owner;
340
340
  else
341
341
  node.outer = owner.outer;
342
- apply({ isolation: Isolation.joinAsNestedTransaction }, () => {
342
+ atomicAction({ isolation: Isolation.joinAsNestedTransaction }, () => {
343
343
  const ctx = node.context;
344
344
  if (ctx) {
345
345
  ctx.variable = variable;
@@ -546,7 +546,7 @@ function triggerFinalization(slot, isLeader, individual) {
546
546
  else
547
547
  gFirstToDispose = gLastToDispose = slot;
548
548
  if (gFirstToDispose === slot)
549
- apply({ isolation: Isolation.disjoinForInternalDisposal, hint: `runDisposalLoop(initiator=${slot.instance.key})` }, () => {
549
+ atomicAction({ isolation: Isolation.disjoinForInternalDisposal, hint: `runDisposalLoop(initiator=${slot.instance.key})` }, () => {
550
550
  void runDisposalLoop().then(NOP, error => console.log(error));
551
551
  });
552
552
  }
@@ -17,7 +17,7 @@ export declare abstract class Transaction implements Worker {
17
17
  abstract inspect<T>(func: F<T>, ...args: any[]): T;
18
18
  abstract apply(): void;
19
19
  abstract seal(): this;
20
- abstract wrap<T>(func: F<T>, secondary: boolean): F<T>;
20
+ abstract wrapAsPending<T>(func: F<T>, secondary: boolean): F<T>;
21
21
  abstract cancel(error: Error, retryAfterOrIgnore?: Worker | null): this;
22
22
  abstract readonly isCanceled: boolean;
23
23
  abstract readonly isFinished: boolean;
@@ -33,7 +33,7 @@ export declare abstract class Transaction implements Worker {
33
33
  export declare class TransactionImpl extends Transaction {
34
34
  private static readonly none;
35
35
  private static curr;
36
- private static inspection;
36
+ private static isInspectionMode;
37
37
  private static frameStartTime;
38
38
  private static frameOverCounter;
39
39
  readonly margin: number;
@@ -57,9 +57,9 @@ export declare class TransactionImpl extends Transaction {
57
57
  inspect<T>(func: F<T>, ...args: any[]): T;
58
58
  apply(): void;
59
59
  seal(): this;
60
- wrap<T>(func: F<T>, error: boolean): F<T>;
61
- private static wrapperEnter;
62
- private static wrapperLeave;
60
+ wrapAsPending<T>(func: F<T>, secondary: boolean): F<T>;
61
+ private static preparePendingFunction;
62
+ private static runPendingFunction;
63
63
  cancel(error: Error, restartAfter?: Worker | null): this;
64
64
  get isCanceled(): boolean;
65
65
  get isFinished(): boolean;
@@ -50,15 +50,15 @@ export class TransactionImpl extends Transaction {
50
50
  return this.runImpl(undefined, func, ...args);
51
51
  }
52
52
  inspect(func, ...args) {
53
- const restore = TransactionImpl.inspection;
53
+ const outer = TransactionImpl.isInspectionMode;
54
54
  try {
55
- TransactionImpl.inspection = true;
55
+ TransactionImpl.isInspectionMode = true;
56
56
  if (Log.isOn && Log.opt.transaction)
57
57
  Log.write(" ", " ", `T${this.id}[${this.hint}] is being inspected by T${TransactionImpl.curr.id}[${TransactionImpl.curr.hint}]`);
58
58
  return this.runImpl(undefined, func, ...args);
59
59
  }
60
60
  finally {
61
- TransactionImpl.inspection = restore;
61
+ TransactionImpl.isInspectionMode = outer;
62
62
  }
63
63
  }
64
64
  apply() {
@@ -73,27 +73,27 @@ export class TransactionImpl extends Transaction {
73
73
  this.run(TransactionImpl.seal, this, undefined, undefined);
74
74
  return this;
75
75
  }
76
- wrap(func, error) {
76
+ wrapAsPending(func, secondary) {
77
77
  this.guard();
78
78
  const self = this;
79
- const inspect = TransactionImpl.inspection;
80
- if (!inspect)
81
- self.run(TransactionImpl.wrapperEnter, self, error);
79
+ const inspection = TransactionImpl.isInspectionMode;
80
+ if (!inspection)
81
+ self.run(TransactionImpl.preparePendingFunction, self, secondary);
82
82
  else
83
- self.inspect(TransactionImpl.wrapperEnter, self, error);
84
- const wrappedForTransaction = (...args) => {
85
- if (!inspect)
86
- return self.runImpl(undefined, TransactionImpl.wrapperLeave, self, error, func, ...args);
83
+ self.inspect(TransactionImpl.preparePendingFunction, self, secondary);
84
+ const wrappedAsPendingForTransaction = (...args) => {
85
+ if (!inspection)
86
+ return self.runImpl(undefined, TransactionImpl.runPendingFunction, self, secondary, func, ...args);
87
87
  else
88
- return self.inspect(TransactionImpl.wrapperLeave, self, error, func, ...args);
88
+ return self.inspect(TransactionImpl.runPendingFunction, self, secondary, func, ...args);
89
89
  };
90
- return wrappedForTransaction;
90
+ return wrappedAsPendingForTransaction;
91
91
  }
92
- static wrapperEnter(t, error) {
93
- if (!error)
92
+ static preparePendingFunction(t, secondary) {
93
+ if (!secondary)
94
94
  t.pending++;
95
95
  }
96
- static wrapperLeave(t, error, func, ...args) {
96
+ static runPendingFunction(t, secondary, func, ...args) {
97
97
  t.pending--;
98
98
  const result = func(...args);
99
99
  return result;
@@ -118,10 +118,10 @@ export class TransactionImpl extends Transaction {
118
118
  }
119
119
  static run(options, func, ...args) {
120
120
  const t = TransactionImpl.acquire(options);
121
- const root = t !== TransactionImpl.curr;
121
+ const isRoot = t !== TransactionImpl.curr;
122
122
  t.guard();
123
123
  let result = t.runImpl(options === null || options === void 0 ? void 0 : options.logging, func, ...args);
124
- if (root) {
124
+ if (isRoot) {
125
125
  if (result instanceof Promise) {
126
126
  result = TransactionImpl.outside(() => {
127
127
  return t.wrapToRetry(t.wrapToWaitUntilFinish(result), func, ...args);
@@ -231,7 +231,7 @@ export class TransactionImpl extends Transaction {
231
231
  }
232
232
  }
233
233
  catch (e) {
234
- if (!TransactionImpl.inspection)
234
+ if (!TransactionImpl.isInspectionMode)
235
235
  this.cancel(e);
236
236
  throw e;
237
237
  }
@@ -460,7 +460,7 @@ export class TransactionImpl extends Transaction {
460
460
  return TransactionImpl.curr.changeset;
461
461
  }
462
462
  static getEditableChangeset() {
463
- if (TransactionImpl.inspection)
463
+ if (TransactionImpl.isInspectionMode)
464
464
  throw misuse("cannot make changes during transaction inspection");
465
465
  return TransactionImpl.curr.changeset;
466
466
  }
@@ -474,7 +474,7 @@ export class TransactionImpl extends Transaction {
474
474
  }
475
475
  TransactionImpl.none = new TransactionImpl({ hint: "<none>" });
476
476
  TransactionImpl.curr = TransactionImpl.none;
477
- TransactionImpl.inspection = false;
477
+ TransactionImpl.isInspectionMode = false;
478
478
  TransactionImpl.frameStartTime = 0;
479
479
  TransactionImpl.frameOverCounter = 0;
480
480
  TransactionImpl.migrateFieldVersion = function (fv, target) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reactronic",
3
- "version": "0.92.25004",
3
+ "version": "0.92.25005",
4
4
  "description": "Reactronic - Transactional Reactive State Management",
5
5
  "publisher": "Nezaboodka Software",
6
6
  "license": "Apache-2.0",