reactronic 0.94.25030 → 0.94.25032

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
@@ -231,7 +231,7 @@ class Component<P> extends React.Component<P> {
231
231
  }
232
232
 
233
233
  componentWillUnmount(): void {
234
- atomicAction(ReactiveSystem.dispose, this)
234
+ atomicAction(disposeObservableObject, this)
235
235
  }
236
236
  }
237
237
  ```
@@ -1,8 +1,7 @@
1
1
  export declare enum Mode {
2
2
  default = 0,
3
3
  autonomous = 1,
4
- manualMount = 2,
5
- rootNode = 4
4
+ external = 2
6
5
  }
7
6
  export declare enum Priority {
8
7
  realtime = 0,
@@ -2,8 +2,7 @@ export var Mode;
2
2
  (function (Mode) {
3
3
  Mode[Mode["default"] = 0] = "default";
4
4
  Mode[Mode["autonomous"] = 1] = "autonomous";
5
- Mode[Mode["manualMount"] = 2] = "manualMount";
6
- Mode[Mode["rootNode"] = 4] = "rootNode";
5
+ Mode[Mode["external"] = 2] = "external";
7
6
  })(Mode || (Mode = {}));
8
7
  export var Priority;
9
8
  (function (Priority) {
@@ -1,4 +1,5 @@
1
+ import { misuse } from "./util/Dbg.js";
1
2
  import { ObservableObject } from "./core/Mvcc.js";
2
3
  export class Pipe extends ObservableObject {
3
- static create(hint, capacity) { throw new Error("not implemented"); }
4
+ static create(hint, capacity) { throw misuse("not implemented"); }
4
5
  }
@@ -1,3 +1,4 @@
1
+ import { misuse } from "./util/Dbg.js";
1
2
  import { runAtomically, runNonReactively } from "./System.js";
2
3
  export function refs(owner) {
3
4
  return new Proxy(owner, RefGettingProxy);
@@ -34,7 +35,7 @@ export class Ref {
34
35
  return this.variable;
35
36
  }
36
37
  unobserve() {
37
- throw new Error("not implemented");
38
+ throw misuse("not implemented");
38
39
  }
39
40
  static sameRefs(v1, v2) {
40
41
  return v1.owner === v2.owner && v1.name === v2.name && v1.index === v2.index;
@@ -1,4 +1,4 @@
1
- import { Log } from "./util/Dbg.js";
1
+ import { Log, misuse } from "./util/Dbg.js";
2
2
  import { Kind, Isolation } from "./Enums.js";
3
3
  import { Meta, ObjectHandle } from "./core/Data.js";
4
4
  import { Changeset } from "./core/Changeset.js";
@@ -39,7 +39,7 @@ export function runSensitively(sensitivity, func, ...args) {
39
39
  return Mvcc.sensitive(sensitivity, func, ...args);
40
40
  }
41
41
  export function runContextually(p) {
42
- throw new Error("not implemented yet");
42
+ throw misuse("not implemented yet");
43
43
  }
44
44
  export function manageReactiveOperation(method) {
45
45
  return ReactiveOperationImpl.manageReactiveOperation(method);
@@ -1,4 +1,5 @@
1
1
  export { all, pause, proceedSyncOrAsync } from "./util/Utils.js";
2
+ export { Uri } from "./util/Uri.js";
2
3
  export { MergeList } from "./util/MergeList.js";
3
4
  export type { MergedItem, MergeListReader } from "./util/MergeList.js";
4
5
  export { SealedArray } from "./util/SealedArray.js";
@@ -20,5 +21,5 @@ export { Journal } from "./core/Journal.js";
20
21
  export { runAtomically, runNonReactively, runSensitively, runContextually, manageReactiveOperation, configureCurrentReactiveOperation, disposeObservableObject } from "./System.js";
21
22
  export { ReactiveSystem, observable, atomic, reactive, cached, options } from "./System.js";
22
23
  export { ReactiveOperationEx } from "./OperationEx.js";
23
- export { ReactiveTreeNode, BaseDriver, ReactiveTreeVariable } from "./core/TreeNode.js";
24
+ export { launch, ReactiveTreeNode, BaseDriver, ReactiveTreeVariable } from "./core/TreeNode.js";
24
25
  export type { Script, ScriptAsync, Handler, ReactiveTreeNodeDecl, ReactiveTreeNodeDriver, ReactiveTreeNodeContext } from "./core/TreeNode.js";
@@ -1,4 +1,5 @@
1
1
  export { all, pause, proceedSyncOrAsync } from "./util/Utils.js";
2
+ export { Uri } from "./util/Uri.js";
2
3
  export { MergeList } from "./util/MergeList.js";
3
4
  export { SealedArray } from "./util/SealedArray.js";
4
5
  export { SealedMap } from "./util/SealedMap.js";
@@ -16,4 +17,4 @@ export { Journal } from "./core/Journal.js";
16
17
  export { runAtomically, runNonReactively, runSensitively, runContextually, manageReactiveOperation, configureCurrentReactiveOperation, disposeObservableObject } from "./System.js";
17
18
  export { ReactiveSystem, observable, atomic, reactive, cached, options } from "./System.js";
18
19
  export { ReactiveOperationEx } from "./OperationEx.js";
19
- export { ReactiveTreeNode, BaseDriver, ReactiveTreeVariable } from "./core/TreeNode.js";
20
+ export { launch, ReactiveTreeNode, BaseDriver, ReactiveTreeVariable } from "./core/TreeNode.js";
@@ -1,3 +1,4 @@
1
+ import { misuse } from "../util/Dbg.js";
1
2
  import { Isolation } from "../Enums.js";
2
3
  import { ObservableObject } from "./Mvcc.js";
3
4
  import { Meta, ContentFootprint } from "./Data.js";
@@ -38,7 +39,7 @@ export class JournalImpl extends Journal {
38
39
  if (this._unsaved === patch)
39
40
  this._unsaved = new Map();
40
41
  else
41
- throw new Error("not implemented");
42
+ throw misuse("not implemented");
42
43
  }
43
44
  undo(count = 1) {
44
45
  Transaction.run({ hint: "Journal.undo", isolation: Isolation.disjoinFromOuterAndInnerTransactions }, () => {
@@ -6,6 +6,7 @@ import { ObservableObject } from "../core/Mvcc.js";
6
6
  export type Script<E> = (el: E, basis: () => void) => void;
7
7
  export type ScriptAsync<E> = (el: E, basis: () => Promise<void>) => Promise<void>;
8
8
  export type Handler<E = unknown, R = void> = (el: E) => R;
9
+ export declare function launch<T>(node: ReactiveTreeNode<T>, triggers?: unknown): ReactiveTreeNode<T>;
9
10
  export declare abstract class ReactiveTreeNode<E = unknown> {
10
11
  static readonly shortFrameDuration = 16;
11
12
  static readonly longFrameDuration = 300;
@@ -26,6 +27,7 @@ export declare abstract class ReactiveTreeNode<E = unknown> {
26
27
  abstract priority?: Priority;
27
28
  abstract childrenShuffling: boolean;
28
29
  abstract strictOrder: boolean;
30
+ abstract getUri(relativeTo?: ReactiveTreeNode<any>): string;
29
31
  abstract has(mode: Mode): boolean;
30
32
  abstract configureReactivity(options: Partial<ReactivityOptions>): ReactivityOptions;
31
33
  static get current(): ReactiveTreeNode;
@@ -34,10 +36,11 @@ export declare abstract class ReactiveTreeNode<E = unknown> {
34
36
  static declare<E = void>(driver: ReactiveTreeNodeDriver<E>, declaration?: ReactiveTreeNodeDecl<E>): ReactiveTreeNode<E>;
35
37
  static declare<E = void>(driver: ReactiveTreeNodeDriver<E>, scriptOrDeclaration?: Script<E> | ReactiveTreeNodeDecl<E>, scriptAsync?: ScriptAsync<E>, key?: string, mode?: Mode, preparation?: Script<E>, preparationAsync?: ScriptAsync<E>, finalization?: Script<E>, triggers?: unknown, basis?: ReactiveTreeNodeDecl<E>): ReactiveTreeNode<E>;
36
38
  static withBasis<E = void>(declaration?: ReactiveTreeNodeDecl<E>, basis?: ReactiveTreeNodeDecl<E>): ReactiveTreeNodeDecl<E>;
37
- static triggerScriptRun(node: ReactiveTreeNode<any>, triggers: unknown): void;
38
- static triggerFinalization(node: ReactiveTreeNode<any>): void;
39
+ static launchScript(node: ReactiveTreeNode<any>, triggers: unknown): void;
40
+ static launchFinalization(node: ReactiveTreeNode<any>): void;
39
41
  static runNestedNodeScriptsThenDo(action: (error: unknown) => void): void;
40
42
  static markAsMounted(node: ReactiveTreeNode<any>, yes: boolean): void;
43
+ lookupTreeNodeByUri<E = unknown>(uri: string): ReactiveTreeNode<E> | undefined;
41
44
  static findMatchingHost<E = unknown, R = unknown>(node: ReactiveTreeNode<E>, match: Handler<ReactiveTreeNode<E>, boolean>): ReactiveTreeNode<R> | undefined;
42
45
  static findMatchingPrevSibling<E = unknown, R = unknown>(node: ReactiveTreeNode<E>, match: Handler<ReactiveTreeNode<E>, boolean>): ReactiveTreeNode<R> | undefined;
43
46
  static forEachChildRecursively<E = unknown>(node: ReactiveTreeNode<E>, action: Handler<ReactiveTreeNode<E>>): void;
@@ -90,7 +93,7 @@ export declare class ReactiveTreeVariable<T extends Object = Object> {
90
93
  get value(): T;
91
94
  get valueOrUndefined(): T | undefined;
92
95
  }
93
- export declare function generateKey(owner: ReactiveTreeNodeImpl): string;
96
+ export declare function generateKey(owner?: ReactiveTreeNodeImpl): string;
94
97
  export declare function getModeUsingBasisChain(declaration?: ReactiveTreeNodeDecl<any>): Mode;
95
98
  declare class ReactiveTreeNodeContextImpl<T extends Object = Object> extends ObservableObject implements ReactiveTreeNodeContext<T> {
96
99
  next: ReactiveTreeNodeContextImpl<object> | undefined;
@@ -118,6 +121,7 @@ declare class ReactiveTreeNodeImpl<E = unknown> extends ReactiveTreeNode<E> {
118
121
  priority: Priority;
119
122
  childrenShuffling: boolean;
120
123
  constructor(key: string, driver: ReactiveTreeNodeDriver<E>, declaration: Readonly<ReactiveTreeNodeDecl<E>>, owner: ReactiveTreeNodeImpl | undefined);
124
+ getUri(relativeTo?: ReactiveTreeNode<any>): string;
121
125
  get strictOrder(): boolean;
122
126
  set strictOrder(value: boolean);
123
127
  get isMoved(): boolean;
@@ -17,12 +17,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
17
17
  });
18
18
  };
19
19
  import { misuse } from "../util/Dbg.js";
20
+ import { Uri } from "../util/Uri.js";
20
21
  import { MergeList } from "../util/MergeList.js";
21
- import { emitLetters, getCallerInfo, proceedSyncOrAsync } from "../util/Utils.js";
22
+ import { emitLetters, flags, getCallerInfo, proceedSyncOrAsync } from "../util/Utils.js";
22
23
  import { Priority, Mode, Isolation, Reentrance } from "../Enums.js";
23
24
  import { ObservableObject } from "../core/Mvcc.js";
24
25
  import { Transaction } from "../core/Transaction.js";
25
26
  import { ReactiveSystem, options, observable, reactive, runAtomically, runNonReactively, manageReactiveOperation, disposeObservableObject } from "../System.js";
27
+ export function launch(node, triggers) {
28
+ ReactiveTreeNode.launchScript(node, triggers);
29
+ return node;
30
+ }
26
31
  export class ReactiveTreeNode {
27
32
  static get current() {
28
33
  return ReactiveTreeNodeImpl.nodeSlot.instance;
@@ -42,7 +47,7 @@ export class ReactiveTreeNode {
42
47
  else
43
48
  declaration = scriptOrDeclaration !== null && scriptOrDeclaration !== void 0 ? scriptOrDeclaration : {};
44
49
  let effectiveKey = declaration.key;
45
- const owner = (getModeUsingBasisChain(declaration) & Mode.rootNode) !== Mode.rootNode ? gNodeSlot === null || gNodeSlot === void 0 ? void 0 : gNodeSlot.instance : undefined;
50
+ const owner = gNodeSlot === null || gNodeSlot === void 0 ? void 0 : gNodeSlot.instance;
46
51
  if (owner) {
47
52
  let existing = owner.driver.declareChild(owner, driver, declaration, declaration.basis);
48
53
  const children = owner.children;
@@ -50,7 +55,7 @@ export class ReactiveTreeNode {
50
55
  if (existing) {
51
56
  result = existing.instance;
52
57
  if (result.driver !== driver && driver !== undefined)
53
- throw new Error(`changing element driver is not yet supported: "${result.driver.name}" -> "${driver === null || driver === void 0 ? void 0 : driver.name}"`);
58
+ throw misuse(`changing element driver is not yet supported: "${result.driver.name}" -> "${driver === null || driver === void 0 ? void 0 : driver.name}"`);
54
59
  const exTriggers = result.declaration.triggers;
55
60
  if (observablesAreEqual(declaration.triggers, exTriggers))
56
61
  declaration.triggers = exTriggers;
@@ -62,9 +67,8 @@ export class ReactiveTreeNode {
62
67
  }
63
68
  }
64
69
  else {
65
- result = new ReactiveTreeNodeImpl(effectiveKey || "", driver, declaration, owner);
70
+ result = new ReactiveTreeNodeImpl(effectiveKey || generateKey(owner), driver, declaration, owner);
66
71
  result.slot = MergeList.createItem(result);
67
- triggerScriptRunViaSlot(result.slot);
68
72
  }
69
73
  return result;
70
74
  }
@@ -75,17 +79,17 @@ export class ReactiveTreeNode {
75
79
  declaration = basis !== null && basis !== void 0 ? basis : {};
76
80
  return declaration;
77
81
  }
78
- static triggerScriptRun(node, triggers) {
82
+ static launchScript(node, triggers) {
79
83
  const impl = node;
80
84
  const declaration = impl.declaration;
81
- if (!observablesAreEqual(triggers, declaration.triggers)) {
85
+ if (node.stamp >= Number.MAX_SAFE_INTEGER || !observablesAreEqual(triggers, declaration.triggers)) {
82
86
  declaration.triggers = triggers;
83
- triggerScriptRunViaSlot(impl.slot);
87
+ launchScriptViaSlot(impl.slot);
84
88
  }
85
89
  }
86
- static triggerFinalization(node) {
90
+ static launchFinalization(node) {
87
91
  const impl = node;
88
- triggerFinalization(impl.slot, true, true);
92
+ launchFinalization(impl.slot, true, true);
89
93
  }
90
94
  static runNestedNodeScriptsThenDo(action) {
91
95
  runNestedNodeScriptsThenDoImpl(ReactiveTreeNodeImpl.nodeSlot, undefined, action);
@@ -93,11 +97,22 @@ export class ReactiveTreeNode {
93
97
  static markAsMounted(node, yes) {
94
98
  const n = node;
95
99
  if (n.stamp < 0)
96
- throw new Error("deactivated node cannot be mounted or unmounted");
100
+ throw misuse("deactivated node cannot be mounted or unmounted");
97
101
  if (n.stamp >= Number.MAX_SAFE_INTEGER)
98
- throw new Error("node must be activated before mounting");
102
+ throw misuse("node must be activated before mounting");
99
103
  n.stamp = yes ? 0 : Number.MAX_SAFE_INTEGER - 1;
100
104
  }
105
+ lookupTreeNodeByUri(uri) {
106
+ var _a;
107
+ const t = Uri.parse(uri);
108
+ if (t.authority !== this.key)
109
+ throw misuse(`authority '${t.authority}' doesn't match root node key '${this.key}'`);
110
+ const segments = t.path.split("/");
111
+ let result = this;
112
+ for (let i = 1; i < segments.length && result !== undefined; i++)
113
+ result = (_a = result.children.lookup(segments[i])) === null || _a === void 0 ? void 0 : _a.instance;
114
+ return result;
115
+ }
101
116
  static findMatchingHost(node, match) {
102
117
  let p = node.host;
103
118
  while (p !== p.host && !match(p))
@@ -168,7 +183,7 @@ export class ReactiveTreeVariable {
168
183
  }
169
184
  }
170
185
  export function generateKey(owner) {
171
- const n = owner.numerator++;
186
+ const n = owner !== undefined ? owner.numerator++ : 0;
172
187
  const lettered = emitLetters(n);
173
188
  let result;
174
189
  if (ReactiveSystem.isLogging)
@@ -266,6 +281,16 @@ class ReactiveTreeNodeImpl extends ReactiveTreeNode {
266
281
  if (this.has(Mode.autonomous))
267
282
  ReactiveTreeNodeImpl.disposableNodeCount++;
268
283
  }
284
+ getUri(relativeTo) {
285
+ const path = [];
286
+ const authority = gatherAuthorityAndPath(this, path);
287
+ const result = Uri.from({
288
+ scheme: "node",
289
+ authority,
290
+ path: "/" + path.join("/"),
291
+ });
292
+ return result.toString();
293
+ }
269
294
  get strictOrder() {
270
295
  return this.children.isStrict;
271
296
  }
@@ -276,19 +301,19 @@ class ReactiveTreeNodeImpl extends ReactiveTreeNode {
276
301
  return this.owner.children.isMoved(this.slot);
277
302
  }
278
303
  has(mode) {
279
- return (getModeUsingBasisChain(this.declaration) & mode) === mode;
304
+ return flags(getModeUsingBasisChain(this.declaration), mode);
280
305
  }
281
306
  script(_triggers) {
282
307
  runScriptNow(this.slot);
283
308
  }
284
309
  configureReactivity(options) {
285
310
  if (this.stamp < Number.MAX_SAFE_INTEGER - 1 || !this.has(Mode.autonomous))
286
- throw new Error("reactronic can be configured only for elements with autonomous mode and only during preparation");
311
+ throw misuse("reactronic can be configured only for elements with autonomous mode and only during preparation");
287
312
  return manageReactiveOperation(this.script).configure(options);
288
313
  }
289
314
  static get nodeSlot() {
290
315
  if (!gNodeSlot)
291
- throw new Error("current element is undefined");
316
+ throw misuse("current element is undefined");
292
317
  return gNodeSlot;
293
318
  }
294
319
  static tryUseTreeVariableValue(variable) {
@@ -302,7 +327,7 @@ class ReactiveTreeNodeImpl extends ReactiveTreeNode {
302
327
  var _a;
303
328
  const result = (_a = ReactiveTreeNodeImpl.tryUseTreeVariableValue(variable)) !== null && _a !== void 0 ? _a : variable.defaultValue;
304
329
  if (!result)
305
- throw new Error("unknown node variable");
330
+ throw misuse("unknown node variable");
306
331
  return result;
307
332
  }
308
333
  static setTreeVariableValue(variable, value) {
@@ -345,6 +370,16 @@ __decorate([
345
370
  __metadata("design:paramtypes", [Object]),
346
371
  __metadata("design:returntype", void 0)
347
372
  ], ReactiveTreeNodeImpl.prototype, "script", null);
373
+ function gatherAuthorityAndPath(node, path, relativeTo) {
374
+ let authority;
375
+ if (node.owner !== node && node.owner !== relativeTo) {
376
+ authority = gatherAuthorityAndPath(node.owner, path);
377
+ path.push(node.key);
378
+ }
379
+ else
380
+ authority = node.key;
381
+ return authority;
382
+ }
348
383
  function getNodeKey(node) {
349
384
  return node.stamp >= 0 ? node.key : undefined;
350
385
  }
@@ -358,7 +393,7 @@ function runNestedNodeScriptsThenDoImpl(nodeSlot, error, action) {
358
393
  try {
359
394
  children.endMerge(error);
360
395
  for (const child of children.removedItems(true))
361
- triggerFinalization(child, true, true);
396
+ launchFinalization(child, true, true);
362
397
  if (!error) {
363
398
  const sequential = children.isStrict;
364
399
  let p1 = undefined;
@@ -374,7 +409,7 @@ function runNestedNodeScriptsThenDoImpl(nodeSlot, error, action) {
374
409
  mounting = markToMountIfNecessary(mounting, host, child, children, sequential);
375
410
  const p = (_a = childNode.priority) !== null && _a !== void 0 ? _a : Priority.realtime;
376
411
  if (p === Priority.realtime)
377
- triggerScriptRunViaSlot(child);
412
+ launchScriptViaSlot(child);
378
413
  else if (p === Priority.normal)
379
414
  p1 = push(child, p1);
380
415
  else
@@ -395,7 +430,7 @@ function runNestedNodeScriptsThenDoImpl(nodeSlot, error, action) {
395
430
  }
396
431
  function markToMountIfNecessary(mounting, host, nodeSlot, children, sequential) {
397
432
  const node = nodeSlot.instance;
398
- if (node.element.native && !node.has(Mode.manualMount)) {
433
+ if (node.element.native && !node.has(Mode.external)) {
399
434
  if (mounting || node.host !== host) {
400
435
  children.markAsMoved(nodeSlot);
401
436
  mounting = false;
@@ -428,7 +463,7 @@ function runNestedScriptsIncrementally(owner, stamp, allChildren, items, priorit
428
463
  const frameDurationLimit = priority === Priority.background ? ReactiveTreeNode.shortFrameDuration : Infinity;
429
464
  let frameDuration = Math.min(frameDurationLimit, Math.max(ReactiveTreeNode.frameDuration / 4, ReactiveTreeNode.shortFrameDuration));
430
465
  for (const child of items) {
431
- triggerScriptRunViaSlot(child);
466
+ launchScriptViaSlot(child);
432
467
  if (Transaction.isFrameOver(1, frameDuration)) {
433
468
  ReactiveTreeNodeImpl.currentScriptPriority = outerPriority;
434
469
  yield Transaction.requestNextFrame(0);
@@ -446,7 +481,7 @@ function runNestedScriptsIncrementally(owner, stamp, allChildren, items, priorit
446
481
  }
447
482
  });
448
483
  }
449
- function triggerScriptRunViaSlot(nodeSlot) {
484
+ function launchScriptViaSlot(nodeSlot) {
450
485
  const node = nodeSlot.instance;
451
486
  if (node.stamp >= 0) {
452
487
  if (node.has(Mode.autonomous)) {
@@ -473,14 +508,14 @@ function mountOrRemountIfNecessary(node) {
473
508
  runNonReactively(() => {
474
509
  node.stamp = Number.MAX_SAFE_INTEGER - 1;
475
510
  driver.runPreparation(node);
476
- if (!node.has(Mode.manualMount)) {
511
+ if (!node.has(Mode.external)) {
477
512
  node.stamp = 0;
478
513
  if (node.host !== node)
479
514
  driver.runMount(node);
480
515
  }
481
516
  });
482
517
  }
483
- else if (node.isMoved && !node.has(Mode.manualMount) && node.host !== node)
518
+ else if (node.isMoved && !node.has(Mode.external) && node.host !== node)
484
519
  runNonReactively(() => driver.runMount(node));
485
520
  }
486
521
  function runScriptNow(nodeSlot) {
@@ -507,7 +542,7 @@ function runScriptNow(nodeSlot) {
507
542
  });
508
543
  }
509
544
  }
510
- function triggerFinalization(nodeSlot, isLeader, individual) {
545
+ function launchFinalization(nodeSlot, isLeader, individual) {
511
546
  const node = nodeSlot.instance;
512
547
  if (node.stamp >= 0) {
513
548
  const driver = node.driver;
@@ -528,7 +563,7 @@ function triggerFinalization(nodeSlot, isLeader, individual) {
528
563
  });
529
564
  }
530
565
  for (const child of node.children.items())
531
- triggerFinalization(child, childrenAreLeaders, false);
566
+ launchFinalization(child, childrenAreLeaders, false);
532
567
  ReactiveTreeNodeImpl.grandNodeCount--;
533
568
  }
534
569
  }
@@ -1,3 +1,4 @@
1
+ import { misuse } from "./Dbg.js";
1
2
  export class MergeList {
2
3
  constructor(getKey, strict = false) {
3
4
  this.getKey = getKey;
@@ -13,7 +14,7 @@ export class MergeList {
13
14
  get isStrict() { return this.strict; }
14
15
  set isStrict(value) {
15
16
  if (this.isMergeInProgress && this.current.count > 0)
16
- throw new Error("cannot change strict mode in the middle of merge");
17
+ throw misuse("cannot change strict mode in the middle of merge");
17
18
  this.strict = value;
18
19
  }
19
20
  get count() {
@@ -46,7 +47,7 @@ export class MergeList {
46
47
  tryMergeAsExisting(key, resolution, error) {
47
48
  const tag = this.tag;
48
49
  if (tag < 0)
49
- throw new Error(error !== null && error !== void 0 ? error : "merge is not in progress");
50
+ throw misuse(error !== null && error !== void 0 ? error : "merge is not in progress");
50
51
  let item = this.strictNextItem;
51
52
  if (key !== (item ? this.getKey(item.instance) : undefined))
52
53
  item = this.lookup(key);
@@ -65,7 +66,7 @@ export class MergeList {
65
66
  else if (resolution)
66
67
  resolution.isDuplicate = true;
67
68
  else
68
- throw new Error(`duplicate collection item: ${key}`);
69
+ throw misuse(`duplicate collection item: ${key}`);
69
70
  }
70
71
  else if (resolution)
71
72
  resolution.isDuplicate = false;
@@ -74,7 +75,7 @@ export class MergeList {
74
75
  mergeAsAdded(instance) {
75
76
  const key = this.getKey(instance);
76
77
  if (this.lookup(key) !== undefined)
77
- throw new Error(`key is already in use: ${key}`);
78
+ throw misuse(`key is already in use: ${key}`);
78
79
  let tag = this.tag;
79
80
  if (tag < 0) {
80
81
  tag = ~this.tag + 1;
@@ -98,11 +99,11 @@ export class MergeList {
98
99
  }
99
100
  }
100
101
  move(item, after) {
101
- throw new Error("not implemented");
102
+ throw misuse("not implemented");
102
103
  }
103
104
  beginMerge() {
104
105
  if (this.isMergeInProgress)
105
- throw new Error("merge is in progress already");
106
+ throw misuse("merge is in progress already");
106
107
  this.tag = ~this.tag + 1;
107
108
  this.strictNextItem = this.current.first;
108
109
  this.removed.grab(this.current, false);
@@ -110,7 +111,7 @@ export class MergeList {
110
111
  }
111
112
  endMerge(error) {
112
113
  if (!this.isMergeInProgress)
113
- throw new Error("merge is ended already");
114
+ throw misuse("merge is ended already");
114
115
  this.tag = ~this.tag;
115
116
  if (error === undefined) {
116
117
  const currentCount = this.current.count;
@@ -0,0 +1,20 @@
1
+ export interface UriComponents {
2
+ scheme: string;
3
+ authority?: string;
4
+ path?: string;
5
+ query?: string;
6
+ fragment?: string;
7
+ }
8
+ export declare class Uri implements UriComponents {
9
+ private static readonly regexp;
10
+ readonly scheme: string;
11
+ readonly authority: string;
12
+ readonly path: string;
13
+ readonly query: string;
14
+ readonly fragment: string;
15
+ protected constructor(scheme: string, authority?: string, path?: string, query?: string, fragment?: string);
16
+ equalsTo(uri: Uri): boolean;
17
+ toString(): string;
18
+ static parse(value: string): Uri;
19
+ static from(components: UriComponents): Uri;
20
+ }
@@ -0,0 +1,67 @@
1
+ import { misuse } from "./Dbg.js";
2
+ export class Uri {
3
+ constructor(scheme, authority, path, query, fragment) {
4
+ this.scheme = scheme;
5
+ this.authority = authority !== null && authority !== void 0 ? authority : "";
6
+ this.path = path !== null && path !== void 0 ? path : "";
7
+ this.query = query !== null && query !== void 0 ? query : "";
8
+ this.fragment = fragment !== null && fragment !== void 0 ? fragment : "";
9
+ validateUri(this);
10
+ }
11
+ equalsTo(uri) {
12
+ return this.scheme === uri.scheme &&
13
+ this.authority === uri.authority &&
14
+ this.path === uri.path &&
15
+ this.query === uri.query &&
16
+ this.fragment === uri.fragment;
17
+ }
18
+ toString() {
19
+ let result = `${this.scheme}://${this.authority}${this.path}`;
20
+ if (this.query) {
21
+ result += `?${this.query}`;
22
+ }
23
+ if (this.fragment) {
24
+ result += `#${this.fragment}`;
25
+ }
26
+ return result;
27
+ }
28
+ static parse(value) {
29
+ var _a, _b, _c, _d, _e;
30
+ let result;
31
+ const match = Uri.regexp.exec(value);
32
+ if (!match) {
33
+ result = new Uri("");
34
+ }
35
+ else {
36
+ result = new Uri((_a = match[2]) !== null && _a !== void 0 ? _a : "", (_b = match[4]) !== null && _b !== void 0 ? _b : "", (_c = match[5]) !== null && _c !== void 0 ? _c : "", (_d = match[7]) !== null && _d !== void 0 ? _d : "", (_e = match[9]) !== null && _e !== void 0 ? _e : "");
37
+ }
38
+ return result;
39
+ }
40
+ static from(components) {
41
+ return new Uri(components.scheme, components.authority, components.path, components.query, components.fragment);
42
+ }
43
+ }
44
+ Uri.regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
45
+ const SCHEME_PATTERN = /^\w[\w\d+.-]*$/;
46
+ const SINGLE_SLASH_START = /^\//;
47
+ const DOUBLE_SLASH_START = /^\/\//;
48
+ function validateUri(uri, strict) {
49
+ if (!uri.scheme && strict) {
50
+ throw misuse(`Scheme is missing: {scheme: "", authority: "${uri.authority}", path: "${uri.path}", query: "${uri.query}", fragment: "${uri.fragment}"}`);
51
+ }
52
+ if (uri.scheme && !SCHEME_PATTERN.test(uri.scheme)) {
53
+ throw misuse("Scheme contains illegal characters.");
54
+ }
55
+ if (uri.path) {
56
+ if (uri.authority) {
57
+ if (!SINGLE_SLASH_START.test(uri.path)) {
58
+ throw misuse("If a URI contains an authority component, then the path component must either be empty or begin with a slash character ('/').");
59
+ }
60
+ }
61
+ else {
62
+ if (DOUBLE_SLASH_START.test(uri.path)) {
63
+ throw misuse("If a URI does not contain an authority component, then the path cannot begin with two slash characters ('//').");
64
+ }
65
+ }
66
+ }
67
+ }
@@ -4,6 +4,7 @@ export declare class Utils {
4
4
  static freezeMap<K, V>(obj?: Map<K, V>): Map<K, V> | undefined;
5
5
  static copyAllMembers(source: any, target: any): any;
6
6
  }
7
+ export declare function flags(value: number, flags: number): boolean;
7
8
  export declare function UNDEF(...args: any[]): never;
8
9
  export declare function all(promises: Array<Promise<any>>): Promise<any[]>;
9
10
  export declare function pause<T>(timeout: number): Promise<T>;
@@ -7,6 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
+ import { fatal, misuse } from "./Dbg.js";
10
11
  export class Utils {
11
12
  static freezeSet(obj) {
12
13
  if (obj instanceof Set) {
@@ -36,8 +37,11 @@ export class Utils {
36
37
  return target;
37
38
  }
38
39
  }
40
+ export function flags(value, flags) {
41
+ return (value & flags) === flags;
42
+ }
39
43
  export function UNDEF(...args) {
40
- throw new Error("this method should never be called");
44
+ throw fatal(new Error("this method should never be called"));
41
45
  }
42
46
  export function all(promises) {
43
47
  return __awaiter(this, void 0, void 0, function* () {
@@ -63,7 +67,7 @@ export function proceedSyncOrAsync(result, success, failure) {
63
67
  }
64
68
  export function emitLetters(n) {
65
69
  if (n < 0)
66
- throw new Error(`emitLetters: argument (${n}) should not be negative or zero`);
70
+ throw misuse(`emitLetters: argument (${n}) should not be negative or zero`);
67
71
  let result = "";
68
72
  while (n >= 0) {
69
73
  const r = n % 26;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reactronic",
3
- "version": "0.94.25030",
3
+ "version": "0.94.25032",
4
4
  "description": "Reactronic - Transactional Reactive State Management",
5
5
  "publisher": "Nezaboodka Software",
6
6
  "license": "Apache-2.0",