reactronic 0.94.25030 → 0.94.25031
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 +1 -1
- package/build/dist/source/Pipe.js +2 -1
- package/build/dist/source/Ref.js +2 -1
- package/build/dist/source/System.js +2 -2
- package/build/dist/source/api.d.ts +1 -0
- package/build/dist/source/api.js +1 -0
- package/build/dist/source/core/Journal.js +2 -1
- package/build/dist/source/core/TreeNode.d.ts +4 -1
- package/build/dist/source/core/TreeNode.js +40 -8
- package/build/dist/source/util/MergeList.js +8 -7
- package/build/dist/source/util/Uri.d.ts +20 -0
- package/build/dist/source/util/Uri.js +67 -0
- package/build/dist/source/util/Utils.js +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -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
|
|
4
|
+
static create(hint, capacity) { throw misuse("not implemented"); }
|
|
4
5
|
}
|
package/build/dist/source/Ref.js
CHANGED
|
@@ -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
|
|
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
|
|
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";
|
package/build/dist/source/api.js
CHANGED
|
@@ -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
|
|
42
|
+
throw misuse("not implemented");
|
|
42
43
|
}
|
|
43
44
|
undo(count = 1) {
|
|
44
45
|
Transaction.run({ hint: "Journal.undo", isolation: Isolation.disjoinFromOuterAndInnerTransactions }, () => {
|
|
@@ -26,6 +26,7 @@ export declare abstract class ReactiveTreeNode<E = unknown> {
|
|
|
26
26
|
abstract priority?: Priority;
|
|
27
27
|
abstract childrenShuffling: boolean;
|
|
28
28
|
abstract strictOrder: boolean;
|
|
29
|
+
abstract getUri(relativeTo?: ReactiveTreeNode<any>): string;
|
|
29
30
|
abstract has(mode: Mode): boolean;
|
|
30
31
|
abstract configureReactivity(options: Partial<ReactivityOptions>): ReactivityOptions;
|
|
31
32
|
static get current(): ReactiveTreeNode;
|
|
@@ -38,6 +39,7 @@ export declare abstract class ReactiveTreeNode<E = unknown> {
|
|
|
38
39
|
static triggerFinalization(node: ReactiveTreeNode<any>): void;
|
|
39
40
|
static runNestedNodeScriptsThenDo(action: (error: unknown) => void): void;
|
|
40
41
|
static markAsMounted(node: ReactiveTreeNode<any>, yes: boolean): void;
|
|
42
|
+
lookupTreeNodeByUri<E = unknown>(uri: string): ReactiveTreeNode<E> | undefined;
|
|
41
43
|
static findMatchingHost<E = unknown, R = unknown>(node: ReactiveTreeNode<E>, match: Handler<ReactiveTreeNode<E>, boolean>): ReactiveTreeNode<R> | undefined;
|
|
42
44
|
static findMatchingPrevSibling<E = unknown, R = unknown>(node: ReactiveTreeNode<E>, match: Handler<ReactiveTreeNode<E>, boolean>): ReactiveTreeNode<R> | undefined;
|
|
43
45
|
static forEachChildRecursively<E = unknown>(node: ReactiveTreeNode<E>, action: Handler<ReactiveTreeNode<E>>): void;
|
|
@@ -90,7 +92,7 @@ export declare class ReactiveTreeVariable<T extends Object = Object> {
|
|
|
90
92
|
get value(): T;
|
|
91
93
|
get valueOrUndefined(): T | undefined;
|
|
92
94
|
}
|
|
93
|
-
export declare function generateKey(owner
|
|
95
|
+
export declare function generateKey(owner?: ReactiveTreeNodeImpl): string;
|
|
94
96
|
export declare function getModeUsingBasisChain(declaration?: ReactiveTreeNodeDecl<any>): Mode;
|
|
95
97
|
declare class ReactiveTreeNodeContextImpl<T extends Object = Object> extends ObservableObject implements ReactiveTreeNodeContext<T> {
|
|
96
98
|
next: ReactiveTreeNodeContextImpl<object> | undefined;
|
|
@@ -118,6 +120,7 @@ declare class ReactiveTreeNodeImpl<E = unknown> extends ReactiveTreeNode<E> {
|
|
|
118
120
|
priority: Priority;
|
|
119
121
|
childrenShuffling: boolean;
|
|
120
122
|
constructor(key: string, driver: ReactiveTreeNodeDriver<E>, declaration: Readonly<ReactiveTreeNodeDecl<E>>, owner: ReactiveTreeNodeImpl | undefined);
|
|
123
|
+
getUri(relativeTo?: ReactiveTreeNode<any>): string;
|
|
121
124
|
get strictOrder(): boolean;
|
|
122
125
|
set strictOrder(value: boolean);
|
|
123
126
|
get isMoved(): boolean;
|
|
@@ -17,6 +17,7 @@ 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
22
|
import { emitLetters, getCallerInfo, proceedSyncOrAsync } from "../util/Utils.js";
|
|
22
23
|
import { Priority, Mode, Isolation, Reentrance } from "../Enums.js";
|
|
@@ -50,7 +51,7 @@ export class ReactiveTreeNode {
|
|
|
50
51
|
if (existing) {
|
|
51
52
|
result = existing.instance;
|
|
52
53
|
if (result.driver !== driver && driver !== undefined)
|
|
53
|
-
throw
|
|
54
|
+
throw misuse(`changing element driver is not yet supported: "${result.driver.name}" -> "${driver === null || driver === void 0 ? void 0 : driver.name}"`);
|
|
54
55
|
const exTriggers = result.declaration.triggers;
|
|
55
56
|
if (observablesAreEqual(declaration.triggers, exTriggers))
|
|
56
57
|
declaration.triggers = exTriggers;
|
|
@@ -62,7 +63,7 @@ export class ReactiveTreeNode {
|
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
else {
|
|
65
|
-
result = new ReactiveTreeNodeImpl(effectiveKey ||
|
|
66
|
+
result = new ReactiveTreeNodeImpl(effectiveKey || generateKey(owner), driver, declaration, owner);
|
|
66
67
|
result.slot = MergeList.createItem(result);
|
|
67
68
|
triggerScriptRunViaSlot(result.slot);
|
|
68
69
|
}
|
|
@@ -93,11 +94,22 @@ export class ReactiveTreeNode {
|
|
|
93
94
|
static markAsMounted(node, yes) {
|
|
94
95
|
const n = node;
|
|
95
96
|
if (n.stamp < 0)
|
|
96
|
-
throw
|
|
97
|
+
throw misuse("deactivated node cannot be mounted or unmounted");
|
|
97
98
|
if (n.stamp >= Number.MAX_SAFE_INTEGER)
|
|
98
|
-
throw
|
|
99
|
+
throw misuse("node must be activated before mounting");
|
|
99
100
|
n.stamp = yes ? 0 : Number.MAX_SAFE_INTEGER - 1;
|
|
100
101
|
}
|
|
102
|
+
lookupTreeNodeByUri(uri) {
|
|
103
|
+
var _a;
|
|
104
|
+
const t = Uri.parse(uri);
|
|
105
|
+
if (t.authority !== this.key)
|
|
106
|
+
throw misuse(`authority '${t.authority}' doesn't match root node key '${this.key}'`);
|
|
107
|
+
const segments = t.path.split("/");
|
|
108
|
+
let result = this;
|
|
109
|
+
for (let i = 1; i < segments.length && result !== undefined; i++)
|
|
110
|
+
result = (_a = result.children.lookup(segments[i])) === null || _a === void 0 ? void 0 : _a.instance;
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
101
113
|
static findMatchingHost(node, match) {
|
|
102
114
|
let p = node.host;
|
|
103
115
|
while (p !== p.host && !match(p))
|
|
@@ -168,7 +180,7 @@ export class ReactiveTreeVariable {
|
|
|
168
180
|
}
|
|
169
181
|
}
|
|
170
182
|
export function generateKey(owner) {
|
|
171
|
-
const n = owner.numerator
|
|
183
|
+
const n = owner !== undefined ? owner.numerator++ : 0;
|
|
172
184
|
const lettered = emitLetters(n);
|
|
173
185
|
let result;
|
|
174
186
|
if (ReactiveSystem.isLogging)
|
|
@@ -266,6 +278,16 @@ class ReactiveTreeNodeImpl extends ReactiveTreeNode {
|
|
|
266
278
|
if (this.has(Mode.autonomous))
|
|
267
279
|
ReactiveTreeNodeImpl.disposableNodeCount++;
|
|
268
280
|
}
|
|
281
|
+
getUri(relativeTo) {
|
|
282
|
+
const path = [];
|
|
283
|
+
const authority = gatherAuthorityAndPath(this, path);
|
|
284
|
+
const result = Uri.from({
|
|
285
|
+
scheme: "node",
|
|
286
|
+
authority,
|
|
287
|
+
path: "/" + path.join("/"),
|
|
288
|
+
});
|
|
289
|
+
return result.toString();
|
|
290
|
+
}
|
|
269
291
|
get strictOrder() {
|
|
270
292
|
return this.children.isStrict;
|
|
271
293
|
}
|
|
@@ -283,12 +305,12 @@ class ReactiveTreeNodeImpl extends ReactiveTreeNode {
|
|
|
283
305
|
}
|
|
284
306
|
configureReactivity(options) {
|
|
285
307
|
if (this.stamp < Number.MAX_SAFE_INTEGER - 1 || !this.has(Mode.autonomous))
|
|
286
|
-
throw
|
|
308
|
+
throw misuse("reactronic can be configured only for elements with autonomous mode and only during preparation");
|
|
287
309
|
return manageReactiveOperation(this.script).configure(options);
|
|
288
310
|
}
|
|
289
311
|
static get nodeSlot() {
|
|
290
312
|
if (!gNodeSlot)
|
|
291
|
-
throw
|
|
313
|
+
throw misuse("current element is undefined");
|
|
292
314
|
return gNodeSlot;
|
|
293
315
|
}
|
|
294
316
|
static tryUseTreeVariableValue(variable) {
|
|
@@ -302,7 +324,7 @@ class ReactiveTreeNodeImpl extends ReactiveTreeNode {
|
|
|
302
324
|
var _a;
|
|
303
325
|
const result = (_a = ReactiveTreeNodeImpl.tryUseTreeVariableValue(variable)) !== null && _a !== void 0 ? _a : variable.defaultValue;
|
|
304
326
|
if (!result)
|
|
305
|
-
throw
|
|
327
|
+
throw misuse("unknown node variable");
|
|
306
328
|
return result;
|
|
307
329
|
}
|
|
308
330
|
static setTreeVariableValue(variable, value) {
|
|
@@ -345,6 +367,16 @@ __decorate([
|
|
|
345
367
|
__metadata("design:paramtypes", [Object]),
|
|
346
368
|
__metadata("design:returntype", void 0)
|
|
347
369
|
], ReactiveTreeNodeImpl.prototype, "script", null);
|
|
370
|
+
function gatherAuthorityAndPath(node, path, relativeTo) {
|
|
371
|
+
let authority;
|
|
372
|
+
if (node.owner !== node && node.owner !== relativeTo) {
|
|
373
|
+
authority = gatherAuthorityAndPath(node.owner, path);
|
|
374
|
+
path.push(node.key);
|
|
375
|
+
}
|
|
376
|
+
else
|
|
377
|
+
authority = node.key;
|
|
378
|
+
return authority;
|
|
379
|
+
}
|
|
348
380
|
function getNodeKey(node) {
|
|
349
381
|
return node.stamp >= 0 ? node.key : undefined;
|
|
350
382
|
}
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
102
|
+
throw misuse("not implemented");
|
|
102
103
|
}
|
|
103
104
|
beginMerge() {
|
|
104
105
|
if (this.isMergeInProgress)
|
|
105
|
-
throw
|
|
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
|
|
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
|
+
}
|
|
@@ -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) {
|
|
@@ -37,7 +38,7 @@ export class Utils {
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
export function UNDEF(...args) {
|
|
40
|
-
throw new Error("this method should never be called");
|
|
41
|
+
throw fatal(new Error("this method should never be called"));
|
|
41
42
|
}
|
|
42
43
|
export function all(promises) {
|
|
43
44
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -63,7 +64,7 @@ export function proceedSyncOrAsync(result, success, failure) {
|
|
|
63
64
|
}
|
|
64
65
|
export function emitLetters(n) {
|
|
65
66
|
if (n < 0)
|
|
66
|
-
throw
|
|
67
|
+
throw misuse(`emitLetters: argument (${n}) should not be negative or zero`);
|
|
67
68
|
let result = "";
|
|
68
69
|
while (n >= 0) {
|
|
69
70
|
const r = n % 26;
|