reactronic 0.92.25005 → 0.92.25007

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
@@ -13,23 +13,28 @@ Reactronic is an experimental JavaScript library that provides
13
13
  [transactional reactive](https://blog.nezaboodka.com/post/2019/593-modern-database-should-natively-support-transactionally-reactive-programming)
14
14
  state management in a Web application.
15
15
 
16
- Transactional reactivity means that state changes are being made in an
17
- isolated data snapshot and then, once atomically applied, are
18
- **consistently propagated** to corresponding visual components for
19
- (re)rendering. All that is done in automatic, seamless, and fine-grained
16
+ Transactional reactivity means that state changes are
17
+ being made in an isolated data snapshot and then, once
18
+ atomically applied, are **consistently propagated** to
19
+ corresponding visual components for (re)rendering. All
20
+ that is done in automatic, seamless, and fine-grained
20
21
  way. Reactronic **takes full care of tracking dependencies**
21
- between visual components (observers) and state (observable objects).
22
-
23
- Transactional reactivity is based on four fundamental concepts:
24
-
25
- - **Observable Objects** - a set of objects that store data of an
26
- application (state);
27
- - **Atomic Action** - a function that makes changes in observable
28
- objects in atomic way ("all or nothing");
29
- - **Reaction** - a function that is executed automatically in
30
- response to changes made by a transaction;
31
- - **Cache** - a function which result is remembered and, if the becomes
32
- obsolete, recomputed on-demand.
22
+ between visual components (observers) and state
23
+ (observable objects).
24
+
25
+ Transactional reactivity is based on four fundamental
26
+ concepts:
27
+
28
+ - **Observable Objects** - a set of objects that store
29
+ data of an application (state);
30
+ - **Atomic Action** - a function that makes changes in
31
+ observable objects in atomic way ("all or nothing");
32
+ - **Reactive Process** - recurrent and automatic
33
+ (re-)execution of a function in response to changes
34
+ made by atomic actions;
35
+ - **Cached Result** - result value of a function that
36
+ is remembered and, if the becomes obsolete, causes
37
+ its function to re-execute on-demand.
33
38
 
34
39
  Demo application built with Reactronic: https://nevod.io/#/playground.
35
40
  Source code of the demo: https://gitlab.com/nezaboodka/nevod.web.public/-/blob/master/README.md.
@@ -51,7 +56,7 @@ class Demo extends ObservableObject {
51
56
  this.email = email
52
57
  }
53
58
 
54
- @reaction
59
+ @reactiveProcess
55
60
  printContact(): void {
56
61
  // depends on `name` and `email` and reacts to their changes
57
62
  if (this.email.indexOf('@') >= 0)
@@ -63,25 +68,26 @@ class Demo extends ObservableObject {
63
68
 
64
69
  In the example above, `Demo` is an observable object,
65
70
  meaning that access to its fields are seamlessly tracked
66
- to determine dependent reactions and caches. Reaction
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
+ to determine dependent reactive processes and cached
72
+ results. Reactive process `printContact` reads `name`
73
+ and `email` fields, thus depends on them. It is executed
74
+ automatically in response to changes of these fields
75
+ made by the atomic action `saveContact`.
71
76
 
72
- Here is an example of a cached value (re-)computed on-demand:
77
+ Here is an example of a cached result that is
78
+ (re-)computed on-demand:
73
79
 
74
80
  ``` typescript
75
81
  class Demo extends ObservableObject {
76
82
  name: string = 'Nezaboodka Software'
77
83
  email: string = 'contact@nezaboodka.com'
78
84
 
79
- @cache
85
+ @cachedResult
80
86
  get contact(): string {
81
87
  return this.name + ' <' + this.email + '>'
82
88
  }
83
89
 
84
- @reaction
90
+ @reactiveProcess
85
91
  printContact(): void {
86
92
  if (this.contact !== '')
87
93
  Console.log(this.contact)
@@ -89,19 +95,22 @@ class Demo extends ObservableObject {
89
95
  }
90
96
  ```
91
97
 
92
- In the example above, the value of `contact` is computed from
93
- source fields `name` and `email` upon first use. Once computed,
94
- the result is cached and is reused until source fields `name`
95
- and `email` are changed. Once source fields changed, `contact`
96
- value becomes obsolete, thus causing execution of depending
97
- reaction function `printContact`. When `printContact` function
98
- runs it reads `contact` and causes its re-computation.
98
+ In the example above, the result of `contact` getter is
99
+ computed from source fields `name` and `email`. Once
100
+ computed, the result is cached and is reused until
101
+ source fields `name` and `email` are changed. Once
102
+ source fields changed, `contact` result becomes obsolete,
103
+ thus causing execution of depending reactive process
104
+ `printContact`. When function of reactive process
105
+ `printContact` runs it reads `contact` and causes its
106
+ re-computation.
99
107
 
100
108
  ## Observable Objects
101
109
 
102
- Observable objects store data of an application. All such objects
103
- are transparently hooked to track access to their properties,
104
- both on reads and writes.
110
+ Observable objects are aimed to store data of an
111
+ application. All such objects are transparently hooked
112
+ to track access to their properties, both on reads and
113
+ writes.
105
114
 
106
115
  ``` typescript
107
116
  class MyModel extends ObservableObject {
@@ -111,18 +120,18 @@ class MyModel extends ObservableObject {
111
120
  }
112
121
  ```
113
122
 
114
- In the example above, the class `MyModel` is based on Reactronic's
115
- `ObservableObject` class and all its properties `url`, `content`,
116
- and `timestamp` are hooked.
123
+ In the example above, the class `MyModel` is based on
124
+ Reactronic's `ObservableObject` class and all its
125
+ properties `url`, `content`, and `timestamp` are hooked.
117
126
 
118
127
  ## Atomic Action
119
128
 
120
129
  Atomic action makes changes in observable objects
121
- in transactional (atomic) way, thus provoking execution
122
- of dependent reactions and recalculation of dependent
123
- caches. Atomic action function is instrumented with
124
- hooks to provide transparent atomicity (by implicit
125
- context switching and isolation).
130
+ in atomic (transactional) way, thus provoking execution
131
+ of dependent reactive processes and recalculation of
132
+ dependent cached results. Atomic action function is
133
+ instrumented with hooks to provide transparent atomicity
134
+ (by implicit context switching and isolation).
126
135
 
127
136
  ``` typescript
128
137
  class MyModel extends ObservableObject {
@@ -137,48 +146,53 @@ class MyModel extends ObservableObject {
137
146
  ```
138
147
 
139
148
  In the example above, the atomic action `load` makes
140
- changes to `url`, `content` and `timestamp` properties. While
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
-
145
- Atomicity is achieved by making changes in an isolated data
146
- snapshot that is not visible outside of the running transaction
147
- until it is fully finished and applied. Multiple objects
148
- and their properties can be changed with full respect
149
- to the all-or-nothing principle. To do so, separate data
150
- snapshot is automatically maintained for each transaction.
151
- That is a logical snapshot that does not create a full copy
152
- of all the data.
153
-
154
- Compensating rollback operations are not needed in case of the
155
- transaction failure, because all the changes made by the transaction
156
- in its logical snapshot are simply discarded. In case the transaction
157
- is successfully applied, affected caches are marked as obsolete
158
- and corresponding caching functions are re-executed in a proper
159
- order (but only when all the data changes are fully applied).
160
-
161
- Asynchronous operations (promises) are supported out of the box
162
- during transaction execution. The transaction may consist of a set of
163
- asynchronous calls prolonging the transaction until completion of
164
- all of them. An asynchronous call may spawn other asynchronous
165
- calls, which prolong transaction execution until the whole chain
166
- of asynchronous operations is fully completed.
167
-
168
- ## Reaction & Cache
169
-
170
- Reaction function is automatically and immediately called in
171
- response to changes in observable objects made by an atomic action.
172
- Cache function is called on-demand to renew the value if it was
173
- marked as obsolete due to changes made by an atomic action.
174
- Reaction and cache functions are instrumented with hooks
175
- to seamlessly subscribe to those observable objects and
176
- other cache functions (dependencies), which are used
177
- during their execution.
149
+ changes to `url`, `content` and `timestamp` properties.
150
+ While atomic action is running, the changes are visible
151
+ only inside the action itself. The new values become
152
+ atomically visible outside of the action only upon its
153
+ completion.
154
+
155
+ Atomicity is achieved by making changes in an isolated
156
+ data snapshot that is not visible outside of the running
157
+ action until it is fully finished and applied. Multiple
158
+ objects and their properties can be changed with full
159
+ respect to the all-or-nothing principle. To do so,
160
+ separate data snapshot is automatically maintained for
161
+ each atomic action. That is a logical snapshot that does
162
+ not create a full copy of all the data.
163
+
164
+ Compensating rollback operations are not needed in case
165
+ of the atomic action failure, because all the changes
166
+ made by the atomic action in its logical snapshot are
167
+ simply discarded. In case the atomic action is
168
+ successfully applied, affected cached results are marked
169
+ as obsolete and corresponding caching functions are
170
+ re-executed in a proper order (but only when all the
171
+ data changes are fully applied).
172
+
173
+ Asynchronous operations (promises) are supported out of
174
+ the box during atomic action execution. Atomic action
175
+ may consist of a set of asynchronous calls prolonging
176
+ the action until completion of all of them. An
177
+ asynchronous call may spawn other asynchronous calls,
178
+ which prolong atomic atomic execution until the whole
179
+ chain of asynchronous operations is fully completed.
180
+
181
+ ## Reactive Process & Cached Result
182
+
183
+ Reactive process function is automatically and
184
+ immediately called in response to changes in observable
185
+ objects made by atomic actions. Function of cached result
186
+ is called on-demand to renew the result if it was marked
187
+ as obsolete due to changes made by an atomic action.
188
+ Functions of reactive processes and cached results are
189
+ instrumented with hooks to seamlessly subscribe to those
190
+ observable objects and other cached results
191
+ (dependencies), which are used during their execution.
178
192
 
179
193
  ``` tsx
180
194
  class MyView extends Component<{model: MyModel}> {
181
- @cache
195
+ @cachedResult
182
196
  render(): React.JSX.Element {
183
197
  return (
184
198
  <div>
@@ -192,72 +206,84 @@ class MyView extends Component<{model: MyModel}> {
192
206
 
193
207
  ``` tsx
194
208
  class Component<P> extends React.Component<P> {
195
- @cache
209
+ @cachedResult
196
210
  render(): React.JSX.Element {
197
211
  throw new Error('render method is undefined')
198
212
  }
199
213
 
200
- @reaction // called immediately in response to changes
214
+ @reactiveProcess // called in response to changes
201
215
  ensureUpToDate(): void {
202
- if (this.shouldComponentUpdate())
203
- Transaction.outside(() => this.setState({})) // ask React to re-render
204
- } // ensureUpToDate is subscribed to render
216
+ if (this.shouldComponentUpdate()) {
217
+ // Ask React to re-render
218
+ Transaction.outside(() => this.setState({}))
219
+ }
220
+ } // EnsureUpToDate is subscribed to render
205
221
 
206
222
  shouldComponentUpdate(): boolean {
207
- return !RxSystem.getController(this.render).isUpToDate
223
+ const r = ReactiveSystem.getController(this.render)
224
+ return !r.isUpToDate
208
225
  }
209
226
 
210
227
  componentDidMount(): void {
211
- this.ensureUpToDate() // run to subscribe for the first time
228
+ // Run to subscribe for the first time
229
+ this.ensureUpToDate()
212
230
  }
213
231
 
214
232
  componentWillUnmount(): void {
215
- atomicAction(RxSystem.dispose, this)
233
+ atomicAction(ReactiveSystem.dispose, this)
216
234
  }
217
235
  }
218
236
  ```
219
237
 
220
- In the example above, reaction function `refresh` is transparently subscribed
221
- to the cache function `render`. In turn, cache function `render` is
222
- subscribed to the properties `url` and `content` of a corresponding
223
- `MyModel` object. Once `url` or `content` values are changed, the
224
- `render` cache becomes obsolete and causes the reaction function `refresh` to become
225
- obsolete as well and re-executed. While being executed, the reaction function `refresh`
226
- enqueues re-rendering request to React, which calls
227
- `render` function causing it to renew its cached value.
228
-
229
- In general case, all reactions and caches are automatically and
230
- immediately marked as obsolete when changes are made in those observable
231
- objects and other cached functions that were used during their execution.
232
- And once marked, the functions are automatically executed again,
233
- either immediately (for reaction functions) or on-demand
234
- (for cache functions).
235
-
236
- Reactronic takes full care of tracking dependencies between
237
- all the observable objects and reaction/caches.
238
- With Reactronic, you no longer need to create data change events
239
- in one set of objects, subscribe to these events in other objects,
240
- and manually maintain switching from the previous object version
241
- to a new one.
238
+ In the example above, reactive process `refresh` is
239
+ transparently subscribed to the cached result of
240
+ function `render`. In turn, cached result of function
241
+ `render` is subscribed to the properties `url` and
242
+ `content` of a corresponding `MyModel` object. Once
243
+ `url` or `content` values are changed, the `render`
244
+ cached result becomes obsolete and causes the reactive
245
+ process `refresh` to become obsolete and re-executed.
246
+ While being executed, the reactive process function
247
+ `refresh` enqueues re-rendering request to React, which
248
+ calls `render` function causing it to renew its cached
249
+ value.
250
+
251
+ In general case, all reactive processes and cached
252
+ results are automatically and immediately marked as
253
+ obsolete when changes are made in those observable
254
+ objects and other cached results that were used during
255
+ their execution. And once marked, the functions are
256
+ automatically executed again, either immediately (for
257
+ reactive processes) or on-demand (for cached results).
258
+
259
+ Reactronic takes full care of tracking dependencies
260
+ between all the observable objects and reactive processes
261
+ or cached results. With Reactronic, you no longer need
262
+ to create data change events in one set of objects,
263
+ subscribe to these events in other objects, and manually
264
+ maintain switching from the previous object version to a
265
+ new one.
242
266
 
243
267
  ## Behavior Options
244
268
 
245
- There are multiple options to configure behavior of transactional reactivity.
269
+ There are multiple options to configure behavior of
270
+ transactional reactivity.
246
271
 
247
- **Order** options defines order of execution for reactions:
272
+ **Order** options defines order of execution for
273
+ reactive processes:
248
274
 
249
275
  - (TBD)
250
276
 
251
- **Throttling** option defines how often reaction is executed in case
252
- of recurring changes:
277
+ **Throttling** option defines how often reactive process
278
+ is executed in case of recurring changes:
253
279
 
254
280
  - `(ms)` - minimal delay in milliseconds between executions;
255
- - `-1` - execute immediately once transaction is applied (synchronously);
281
+ - `-1` - execute immediately once atomic action is applied (synchronously);
256
282
  - `0` - execute immediately via event loop (asynchronously with zero timeout);
257
283
  - `>= Number.MAX_SAFE_INTEGER` - never execute (suspended reaction).
258
284
 
259
285
  **Reentrance** option defines how to handle reentrant calls of atomic
260
- actions and reactions:
286
+ actions and reactive processes:
261
287
 
262
288
  - `preventWithError` - fail with error if there is an existing call in progress;
263
289
  - `waitAndRestart` - wait for previous call to finish and then restart current one;
@@ -267,8 +293,8 @@ actions and reactions:
267
293
 
268
294
  **Indicator** is an object that maintains status of running functions,
269
295
  which it is attached to. A single indicator object can be shared between
270
- multiple transactional, reactive, and cached functions, thus maintaining
271
- consolidated status for all of them (busy, workers, etc).
296
+ multiple atomic actions, reactive processes, and cached results, thus
297
+ maintaining consolidated status for all of them (busy, workers, etc).
272
298
 
273
299
  ## Notes
274
300
 
@@ -306,8 +332,8 @@ class ObservableObject { }
306
332
  function observable(proto, prop) // field only
307
333
  function unobservable(proto, prop) // field only
308
334
  function atomicAction(proto, prop, pd) // method only
309
- function reaction(proto, prop, pd) // method only
310
- function cache(proto, prop, pd) // method only
335
+ function reactiveProcess(proto, prop, pd) // method only
336
+ function cachedResult(proto, prop, pd) // method only
311
337
  function options(value: Partial<MemberOptions>): F<any>
312
338
 
313
339
  function nonreactive<T>(func: F<T>, ...args: any[]): T
@@ -338,9 +364,9 @@ type MemberOptions = {
338
364
 
339
365
  enum Kind {
340
366
  plain = 0,
341
- transaction = 1,
342
- reaction = 2,
343
- cache = 3
367
+ atomicAction = 1,
368
+ reactiveProcess = 2,
369
+ cachedResult = 3
344
370
  }
345
371
 
346
372
  enum Reentrance {
@@ -25,9 +25,9 @@ export type MemberOptions = {
25
25
  };
26
26
  export declare enum Kind {
27
27
  plain = 0,
28
- apply = 1,
29
- reaction = 2,
30
- cache = 3
28
+ atomicAction = 1,
29
+ reactiveProcess = 2,
30
+ cachedResult = 3
31
31
  }
32
32
  export declare enum Reentrance {
33
33
  preventWithError = 1,
@@ -2,9 +2,9 @@ export { LoggingLevel } from "./Logging.js";
2
2
  export var Kind;
3
3
  (function (Kind) {
4
4
  Kind[Kind["plain"] = 0] = "plain";
5
- Kind[Kind["apply"] = 1] = "apply";
6
- Kind[Kind["reaction"] = 2] = "reaction";
7
- Kind[Kind["cache"] = 3] = "cache";
5
+ Kind[Kind["atomicAction"] = 1] = "atomicAction";
6
+ Kind[Kind["reactiveProcess"] = 2] = "reactiveProcess";
7
+ Kind[Kind["cachedResult"] = 3] = "cachedResult";
8
8
  })(Kind || (Kind = {}));
9
9
  export var Reentrance;
10
10
  (function (Reentrance) {
@@ -1,6 +1,6 @@
1
1
  import { F } from "./util/Utils.js";
2
2
  import { ObservableObject } from "./core/Mvcc.js";
3
- export declare class Reaction<T> extends ObservableObject {
3
+ export declare class ReactiveProcess<T> extends ObservableObject {
4
4
  protected action: F<T>;
5
5
  constructor(action: F<T>);
6
6
  protected launch(): T;
@@ -8,8 +8,8 @@ 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 { reaction } from "./ReactiveSystem.js";
12
- export class Reaction extends ObservableObject {
11
+ import { reactiveProcess } from "./ReactiveSystem.js";
12
+ export class ReactiveProcess extends ObservableObject {
13
13
  constructor(action) {
14
14
  super();
15
15
  this.action = action;
@@ -19,8 +19,8 @@ export class Reaction extends ObservableObject {
19
19
  }
20
20
  }
21
21
  __decorate([
22
- reaction,
22
+ reactiveProcess,
23
23
  __metadata("design:type", Function),
24
24
  __metadata("design:paramtypes", []),
25
25
  __metadata("design:returntype", Object)
26
- ], Reaction.prototype, "launch", null);
26
+ ], ReactiveProcess.prototype, "launch", null);
@@ -17,16 +17,14 @@ export declare class ReactiveSystem {
17
17
  static getLoggingHint<T extends object>(obj: T, full?: boolean): string | undefined;
18
18
  static setProfilingMode(isOn: boolean, options?: Partial<ProfilingOptions>): void;
19
19
  }
20
+ export declare function atomically<T>(func: F<T>, ...args: any[]): T;
21
+ export declare function atomically<T>(options: SnapshotOptions, func: F<T>, ...args: any[]): T;
20
22
  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;
23
23
  export declare function sensitive<T>(sensitivity: boolean, func: F<T>, ...args: any[]): T;
24
24
  export declare function contextually<T>(p: Promise<T>): Promise<T>;
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;
28
25
  export declare function unobservable(proto: object, prop: PropertyKey): any;
29
26
  export declare function observable(proto: object, prop: PropertyKey): any;
30
- export declare function reaction(proto: object, prop: PropertyKey, pd: PropertyDescriptor): any;
31
- export declare function cache(proto: object, prop: PropertyKey, pd: PropertyDescriptor): any;
27
+ export declare function atomicAction(proto: object, prop: PropertyKey, pd: PropertyDescriptor): any;
28
+ export declare function reactiveProcess(proto: object, prop: PropertyKey, pd: PropertyDescriptor): any;
29
+ export declare function cachedResult(proto: object, prop: PropertyKey, pd: PropertyDescriptor): any;
32
30
  export declare function options(value: Partial<MemberOptions>): F<any>;
@@ -22,53 +22,28 @@ export class ReactiveSystem {
22
22
  static getLoggingHint(obj, full = false) { return ObjectHandle.getHint(obj, full); }
23
23
  static setProfilingMode(isOn, options) { Mvcc.setProfilingMode(isOn, options); }
24
24
  }
25
- export function nonreactive(func, ...args) {
26
- return OperationImpl.proceedWithinGivenLaunch(undefined, func, ...args);
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
- }
46
- export function sensitive(sensitivity, func, ...args) {
47
- return Mvcc.sensitive(sensitivity, func, ...args);
48
- }
49
- export function contextually(p) {
50
- throw new Error("not implemented yet");
51
- }
52
- export function atomicAction(p1, p2, p3) {
25
+ export function atomically(p1, p2, p3) {
53
26
  if (p1 instanceof Function) {
54
27
  if (p2 !== undefined)
55
28
  return Transaction.run(null, p1, ...p2);
56
29
  else
57
30
  return Transaction.run(null, p1);
58
31
  }
59
- else if (p2 instanceof Function) {
32
+ else {
60
33
  if (p3 !== undefined)
61
34
  return Transaction.run(p1, p2, ...p3);
62
35
  else
63
36
  return Transaction.run(p1, p2);
64
37
  }
65
- else {
66
- const opts = {
67
- kind: Kind.apply,
68
- isolation: Isolation.joinToCurrentTransaction,
69
- };
70
- return Mvcc.decorateOperation(true, atomicAction, opts, p1, p2, p3);
71
- }
38
+ }
39
+ export function nonreactive(func, ...args) {
40
+ return OperationImpl.proceedWithinGivenLaunch(undefined, func, ...args);
41
+ }
42
+ export function sensitive(sensitivity, func, ...args) {
43
+ return Mvcc.sensitive(sensitivity, func, ...args);
44
+ }
45
+ export function contextually(p) {
46
+ throw new Error("not implemented yet");
72
47
  }
73
48
  export function unobservable(proto, prop) {
74
49
  return Mvcc.decorateData(false, proto, prop);
@@ -76,21 +51,28 @@ export function unobservable(proto, prop) {
76
51
  export function observable(proto, prop) {
77
52
  return Mvcc.decorateData(true, proto, prop);
78
53
  }
79
- export function reaction(proto, prop, pd) {
54
+ export function atomicAction(proto, prop, pd) {
55
+ const opts = {
56
+ kind: Kind.atomicAction,
57
+ isolation: Isolation.joinToCurrentTransaction,
58
+ };
59
+ return Mvcc.decorateOperation(true, atomicAction, opts, proto, prop, pd);
60
+ }
61
+ export function reactiveProcess(proto, prop, pd) {
80
62
  const opts = {
81
- kind: Kind.reaction,
63
+ kind: Kind.reactiveProcess,
82
64
  isolation: Isolation.joinAsNestedTransaction,
83
65
  throttling: -1,
84
66
  };
85
- return Mvcc.decorateOperation(true, reaction, opts, proto, prop, pd);
67
+ return Mvcc.decorateOperation(true, reactiveProcess, opts, proto, prop, pd);
86
68
  }
87
- export function cache(proto, prop, pd) {
69
+ export function cachedResult(proto, prop, pd) {
88
70
  const opts = {
89
- kind: Kind.cache,
71
+ kind: Kind.cachedResult,
90
72
  isolation: Isolation.joinToCurrentTransaction,
91
73
  noSideEffects: true,
92
74
  };
93
- return Mvcc.decorateOperation(true, cache, opts, proto, prop, pd);
75
+ return Mvcc.decorateOperation(true, cachedResult, opts, proto, prop, pd);
94
76
  }
95
77
  export function options(value) {
96
78
  return Mvcc.decorateOperationParametrized(options, value);
@@ -1,4 +1,4 @@
1
- import { atomicAction, nonreactive } from "./ReactiveSystem.js";
1
+ import { atomically, 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
- atomicAction({ hint: `toggle ${o.constructor.name}.${p}` }, () => {
55
+ atomically({ 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,8 +16,9 @@ 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, atomicAction, reaction, cache, nonreactive, sensitive, contextually, options } from "./ReactiveSystem.js";
20
- export { Reaction } from "./Reaction.js";
19
+ export { atomically, nonreactive, sensitive, contextually } from "./ReactiveSystem.js";
20
+ export { ReactiveSystem, observable, unobservable, atomicAction, reactiveProcess, cachedResult, options } from "./ReactiveSystem.js";
21
+ export { ReactiveProcess } from "./Reaction.js";
21
22
  export { ReactiveNode, Mode, Priority, BaseDriver, ReactiveNodeVariable } from "./core/ReactiveNode.js";
22
23
  export type { Script, ScriptAsync, Handler, ReactiveNodeDecl, ReactiveNodeDriver, ReactiveNodeContext } from "./core/ReactiveNode.js";
23
24
  export { Clock } from "./Clock.js";
@@ -12,7 +12,8 @@ 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, atomicAction, reaction, cache, nonreactive, sensitive, contextually, options } from "./ReactiveSystem.js";
16
- export { Reaction } from "./Reaction.js";
15
+ export { atomically, nonreactive, sensitive, contextually } from "./ReactiveSystem.js";
16
+ export { ReactiveSystem, observable, unobservable, atomicAction, reactiveProcess, cachedResult, options } from "./ReactiveSystem.js";
17
+ export { ReactiveProcess } from "./Reaction.js";
17
18
  export { ReactiveNode, Mode, Priority, BaseDriver, ReactiveNodeVariable } from "./core/ReactiveNode.js";
18
19
  export { Clock } from "./Clock.js";
@@ -99,7 +99,7 @@ export class OperationImpl {
99
99
  const ov = ctx.lookupObjectVersion(this.ownerHandle, this.fieldKey, false);
100
100
  const launch = this.acquireFromObjectVersion(ov, args);
101
101
  const applied = this.ownerHandle.applied.data[this.fieldKey];
102
- const isReusable = launch.options.kind !== Kind.apply && launch.cause !== BOOT_CAUSE &&
102
+ const isReusable = launch.options.kind !== Kind.atomicAction && launch.cause !== BOOT_CAUSE &&
103
103
  (ctx === launch.changeset || ctx.timestamp < launch.obsoleteSince || applied.obsoleteDueTo === undefined) &&
104
104
  (!launch.options.triggeringArgs || args === undefined ||
105
105
  launch.args.length === args.length && launch.args.every((t, i) => t === args[i])) || ov.disposed;
@@ -175,7 +175,7 @@ export class OperationImpl {
175
175
  }
176
176
  else {
177
177
  ror = this.peek(argsx);
178
- if (ror.launch.options.kind === Kind.apply || !ror.isReusable) {
178
+ if (ror.launch.options.kind === Kind.atomicAction || !ror.isReusable) {
179
179
  ror = this.edit();
180
180
  if (Log.isOn && Log.opt.operation)
181
181
  Log.write("║", " o", `${ror.launch.why()}`);
@@ -251,7 +251,7 @@ class Launch extends FieldVersion {
251
251
  let cause;
252
252
  if (this.cause)
253
253
  cause = ` ◀◀ ${this.cause}`;
254
- else if (this.operation.options.kind === Kind.apply)
254
+ else if (this.operation.options.kind === Kind.atomicAction)
255
255
  cause = " ◀◀ operation";
256
256
  else
257
257
  cause = ` ◀◀ T${this.changeset.id}[${this.changeset.hint}]`;
@@ -294,7 +294,7 @@ class Launch extends FieldVersion {
294
294
  changeset.id === this.lastEditorChangesetId;
295
295
  if (!skip) {
296
296
  const why = `${Dump.snapshot2(h, changeset, fk, observable)} ◀◀ ${outer}`;
297
- const isReactive = this.options.kind === Kind.reaction;
297
+ const isReactive = this.options.kind === Kind.reactiveProcess;
298
298
  this.obsoleteDueTo = why;
299
299
  this.obsoleteSince = since;
300
300
  if (Log.isOn && (Log.opt.obsolete || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.obsolete)))
@@ -326,14 +326,14 @@ class Launch extends FieldVersion {
326
326
  const launch = this.operation.reuseOrRelaunch(false, undefined);
327
327
  if (launch.result instanceof Promise)
328
328
  launch.result.catch(error => {
329
- if (launch.options.kind === Kind.reaction)
329
+ if (launch.options.kind === Kind.reactiveProcess)
330
330
  misuse(`reactive function ${launch.hint()} failed and will not run anymore: ${error}`, error);
331
331
  });
332
332
  }
333
333
  catch (e) {
334
334
  if (!nothrow)
335
335
  throw e;
336
- else if (this.options.kind === Kind.reaction)
336
+ else if (this.options.kind === Kind.reactiveProcess)
337
337
  misuse(`reactive ${this.hint()} failed and will not run anymore: ${e}`, e);
338
338
  }
339
339
  }
@@ -346,7 +346,7 @@ class Launch extends FieldVersion {
346
346
  }
347
347
  }
348
348
  isNotUpToDate() {
349
- return !this.error && (this.options.kind === Kind.apply ||
349
+ return !this.error && (this.options.kind === Kind.atomicAction ||
350
350
  !this.successor || this.successor.transaction.isCanceled);
351
351
  }
352
352
  reenterOver(head) {
@@ -469,9 +469,9 @@ class Launch extends FieldVersion {
469
469
  x.relaunchIfNotUpToDate(true, true);
470
470
  }
471
471
  static markUsed(observable, ov, fk, h, kind, weak) {
472
- if (kind !== Kind.apply) {
472
+ if (kind !== Kind.atomicAction) {
473
473
  const launch = Launch.current;
474
- if (launch && launch.options.kind !== Kind.apply &&
474
+ if (launch && launch.options.kind !== Kind.atomicAction &&
475
475
  launch.transaction === Transaction.current && fk !== Meta.Handle) {
476
476
  const ctx = Changeset.current();
477
477
  if (ctx !== ov.changeset)
@@ -652,11 +652,11 @@ class Launch extends FieldVersion {
652
652
  const rx = launch ? launch.operation : new OperationImpl(EMPTY_HANDLE, fk);
653
653
  const opts = launch ? launch.options : OptionsImpl.INITIAL;
654
654
  initial[fk] = launch = new Launch(Transaction.current, rx, EMPTY_OBJECT_VERSION.changeset, new OptionsImpl(getter, setter, opts, options, implicit), false);
655
- if (launch.options.kind === Kind.reaction && launch.options.throttling < Number.MAX_SAFE_INTEGER) {
655
+ if (launch.options.kind === Kind.reactiveProcess && launch.options.throttling < Number.MAX_SAFE_INTEGER) {
656
656
  const reactive = Meta.acquire(proto, Meta.Reactive);
657
657
  reactive[fk] = launch;
658
658
  }
659
- else if (launch.options.kind === Kind.reaction && launch.options.throttling >= Number.MAX_SAFE_INTEGER) {
659
+ else if (launch.options.kind === Kind.reactiveProcess && launch.options.throttling >= Number.MAX_SAFE_INTEGER) {
660
660
  const reactive = Meta.getFrom(proto, Meta.Reactive);
661
661
  delete reactive[fk];
662
662
  }
@@ -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, atomicAction } from "../ReactiveSystem.js";
25
+ import { ReactiveSystem, options, unobservable, reactiveProcess, atomically, nonreactive } 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
- atomicAction({ isolation: Isolation.joinAsNestedTransaction }, () => {
342
+ atomically({ isolation: Isolation.joinAsNestedTransaction }, () => {
343
343
  const ctx = node.context;
344
344
  if (ctx) {
345
345
  ctx.variable = variable;
@@ -359,7 +359,7 @@ ReactiveNodeImpl.logging = undefined;
359
359
  ReactiveNodeImpl.grandNodeCount = 0;
360
360
  ReactiveNodeImpl.disposableNodeCount = 0;
361
361
  __decorate([
362
- reaction,
362
+ reactiveProcess,
363
363
  options({
364
364
  reentrance: Reentrance.cancelAndWaitPrevious,
365
365
  allowObsoleteToFinish: true,
@@ -546,7 +546,7 @@ function triggerFinalization(slot, isLeader, individual) {
546
546
  else
547
547
  gFirstToDispose = gLastToDispose = slot;
548
548
  if (gFirstToDispose === slot)
549
- atomicAction({ isolation: Isolation.disjoinForInternalDisposal, hint: `runDisposalLoop(initiator=${slot.instance.key})` }, () => {
549
+ atomically({ isolation: Isolation.disjoinForInternalDisposal, hint: `runDisposalLoop(initiator=${slot.instance.key})` }, () => {
550
550
  void runDisposalLoop().then(NOP, error => console.log(error));
551
551
  });
552
552
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reactronic",
3
- "version": "0.92.25005",
3
+ "version": "0.92.25007",
4
4
  "description": "Reactronic - Transactional Reactive State Management",
5
5
  "publisher": "Nezaboodka Software",
6
6
  "license": "Apache-2.0",