mundane-sdk 0.0.1 → 0.0.3
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/dist/src/errors.d.ts +9 -9
- package/dist/src/errors.js +20 -20
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +12 -12
- package/dist/src/lock.js +1 -1
- package/dist/src/names.d.ts +1 -1
- package/dist/src/names.js +1 -1
- package/dist/src/schema.js +2 -2
- package/dist/test/basic.test.js +7 -7
- package/package.json +1 -1
package/dist/src/errors.d.ts
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Custom error classes thrown by mundane.
|
|
3
3
|
*
|
|
4
|
-
* -
|
|
5
|
-
* -
|
|
4
|
+
* - LockedError: another live process holds the file lock.
|
|
5
|
+
* - SerializationError: a step's return value doesn't survive a
|
|
6
6
|
* JSON round-trip (Date, undefined, BigInt, Map, Set, function, circular).
|
|
7
|
-
* -
|
|
8
|
-
* -
|
|
7
|
+
* - SchemaError: file exists but meta.schema_version != "1".
|
|
8
|
+
* - StepFailedError: a step body threw; wraps the underlying error.
|
|
9
9
|
*/
|
|
10
|
-
export declare class
|
|
10
|
+
export declare class LockedError extends Error {
|
|
11
11
|
readonly code = "EMUNDANELOCKED";
|
|
12
12
|
constructor(message: string);
|
|
13
13
|
}
|
|
14
|
-
export declare class
|
|
14
|
+
export declare class SerializationError extends Error {
|
|
15
15
|
readonly code = "EMUNDANESERIALIZATION";
|
|
16
16
|
readonly path?: string;
|
|
17
17
|
constructor(message: string, path?: string);
|
|
18
18
|
}
|
|
19
|
-
export declare class
|
|
19
|
+
export declare class SchemaError extends Error {
|
|
20
20
|
readonly code = "EMUNDANESCHEMA";
|
|
21
21
|
constructor(message: string);
|
|
22
22
|
}
|
|
23
|
-
export declare class
|
|
23
|
+
export declare class DuplicateStepError extends Error {
|
|
24
24
|
readonly code = "EMUNDANEDUPLICATE";
|
|
25
25
|
readonly stepName: string;
|
|
26
26
|
constructor(stepName: string);
|
|
27
27
|
}
|
|
28
|
-
export declare class
|
|
28
|
+
export declare class StepFailedError extends Error {
|
|
29
29
|
readonly code = "EMUNDANESTEPFAILED";
|
|
30
30
|
readonly stepName: string;
|
|
31
31
|
readonly original: unknown;
|
package/dist/src/errors.js
CHANGED
|
@@ -2,51 +2,51 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Custom error classes thrown by mundane.
|
|
4
4
|
*
|
|
5
|
-
* -
|
|
6
|
-
* -
|
|
5
|
+
* - LockedError: another live process holds the file lock.
|
|
6
|
+
* - SerializationError: a step's return value doesn't survive a
|
|
7
7
|
* JSON round-trip (Date, undefined, BigInt, Map, Set, function, circular).
|
|
8
|
-
* -
|
|
9
|
-
* -
|
|
8
|
+
* - SchemaError: file exists but meta.schema_version != "1".
|
|
9
|
+
* - StepFailedError: a step body threw; wraps the underlying error.
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
13
|
-
class
|
|
12
|
+
exports.StepFailedError = exports.DuplicateStepError = exports.SchemaError = exports.SerializationError = exports.LockedError = void 0;
|
|
13
|
+
class LockedError extends Error {
|
|
14
14
|
code = "EMUNDANELOCKED";
|
|
15
15
|
constructor(message) {
|
|
16
16
|
super(message);
|
|
17
|
-
this.name = "
|
|
17
|
+
this.name = "LockedError";
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
exports.
|
|
21
|
-
class
|
|
20
|
+
exports.LockedError = LockedError;
|
|
21
|
+
class SerializationError extends Error {
|
|
22
22
|
code = "EMUNDANESERIALIZATION";
|
|
23
23
|
path;
|
|
24
24
|
constructor(message, path) {
|
|
25
25
|
super(message);
|
|
26
|
-
this.name = "
|
|
26
|
+
this.name = "SerializationError";
|
|
27
27
|
this.path = path;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
exports.
|
|
31
|
-
class
|
|
30
|
+
exports.SerializationError = SerializationError;
|
|
31
|
+
class SchemaError extends Error {
|
|
32
32
|
code = "EMUNDANESCHEMA";
|
|
33
33
|
constructor(message) {
|
|
34
34
|
super(message);
|
|
35
|
-
this.name = "
|
|
35
|
+
this.name = "SchemaError";
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
exports.
|
|
39
|
-
class
|
|
38
|
+
exports.SchemaError = SchemaError;
|
|
39
|
+
class DuplicateStepError extends Error {
|
|
40
40
|
code = "EMUNDANEDUPLICATE";
|
|
41
41
|
stepName;
|
|
42
42
|
constructor(stepName) {
|
|
43
43
|
super(`duplicate step name: ${stepName}`);
|
|
44
|
-
this.name = "
|
|
44
|
+
this.name = "DuplicateStepError";
|
|
45
45
|
this.stepName = stepName;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
-
exports.
|
|
49
|
-
class
|
|
48
|
+
exports.DuplicateStepError = DuplicateStepError;
|
|
49
|
+
class StepFailedError extends Error {
|
|
50
50
|
code = "EMUNDANESTEPFAILED";
|
|
51
51
|
stepName;
|
|
52
52
|
original;
|
|
@@ -55,7 +55,7 @@ class MundaneStepFailedError extends Error {
|
|
|
55
55
|
? `step ${JSON.stringify(stepName)} failed: ${original.message}`
|
|
56
56
|
: `step ${JSON.stringify(stepName)} failed: ${String(original)}`;
|
|
57
57
|
super(msg);
|
|
58
|
-
this.name = "
|
|
58
|
+
this.name = "StepFailedError";
|
|
59
59
|
this.stepName = stepName;
|
|
60
60
|
this.original = original;
|
|
61
61
|
if (original instanceof Error && original.stack) {
|
|
@@ -63,4 +63,4 @@ class MundaneStepFailedError extends Error {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
exports.
|
|
66
|
+
exports.StepFailedError = StepFailedError;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
*
|
|
9
9
|
* See ../../../SPEC.md (project root) for the full contract.
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
12
|
-
export {
|
|
11
|
+
import { DuplicateStepError, LockedError, SchemaError, SerializationError, StepFailedError } from "./errors";
|
|
12
|
+
export { DuplicateStepError, LockedError, SchemaError, SerializationError, StepFailedError };
|
|
13
13
|
export type Json = null | boolean | number | string | Json[] | {
|
|
14
14
|
[k: string]: Json;
|
|
15
15
|
};
|
package/dist/src/index.js
CHANGED
|
@@ -10,16 +10,16 @@
|
|
|
10
10
|
* See ../../../SPEC.md (project root) for the full contract.
|
|
11
11
|
*/
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.
|
|
13
|
+
exports.StepFailedError = exports.SerializationError = exports.SchemaError = exports.LockedError = exports.DuplicateStepError = void 0;
|
|
14
14
|
exports.run = run;
|
|
15
15
|
const db_1 = require("./db");
|
|
16
16
|
const duration_1 = require("./duration");
|
|
17
17
|
const errors_1 = require("./errors");
|
|
18
|
-
Object.defineProperty(exports, "
|
|
19
|
-
Object.defineProperty(exports, "
|
|
20
|
-
Object.defineProperty(exports, "
|
|
21
|
-
Object.defineProperty(exports, "
|
|
22
|
-
Object.defineProperty(exports, "
|
|
18
|
+
Object.defineProperty(exports, "DuplicateStepError", { enumerable: true, get: function () { return errors_1.DuplicateStepError; } });
|
|
19
|
+
Object.defineProperty(exports, "LockedError", { enumerable: true, get: function () { return errors_1.LockedError; } });
|
|
20
|
+
Object.defineProperty(exports, "SchemaError", { enumerable: true, get: function () { return errors_1.SchemaError; } });
|
|
21
|
+
Object.defineProperty(exports, "SerializationError", { enumerable: true, get: function () { return errors_1.SerializationError; } });
|
|
22
|
+
Object.defineProperty(exports, "StepFailedError", { enumerable: true, get: function () { return errors_1.StepFailedError; } });
|
|
23
23
|
const lock_1 = require("./lock");
|
|
24
24
|
const names_1 = require("./names");
|
|
25
25
|
const schema_1 = require("./schema");
|
|
@@ -29,16 +29,16 @@ function checkJsonRoundtrip(value) {
|
|
|
29
29
|
text = JSON.stringify(value);
|
|
30
30
|
}
|
|
31
31
|
catch (e) {
|
|
32
|
-
throw new errors_1.
|
|
32
|
+
throw new errors_1.SerializationError(`value is not JSON-serializable: ${e.message}`);
|
|
33
33
|
}
|
|
34
34
|
if (text === undefined) {
|
|
35
35
|
// JSON.stringify returns undefined for top-level undefined/function/symbol
|
|
36
|
-
throw new errors_1.
|
|
36
|
+
throw new errors_1.SerializationError("value is not JSON-serializable (undefined / function / symbol at top level)");
|
|
37
37
|
}
|
|
38
38
|
const decoded = JSON.parse(text);
|
|
39
39
|
const mismatch = deepDiff(value, decoded, "");
|
|
40
40
|
if (mismatch !== null) {
|
|
41
|
-
throw new errors_1.
|
|
41
|
+
throw new errors_1.SerializationError(`value does not round-trip through JSON at ${JSON.stringify(mismatch)}`, mismatch);
|
|
42
42
|
}
|
|
43
43
|
return text;
|
|
44
44
|
}
|
|
@@ -109,7 +109,7 @@ class TaskState {
|
|
|
109
109
|
}
|
|
110
110
|
checkSeen(name) {
|
|
111
111
|
if (this.seen.has(name)) {
|
|
112
|
-
throw new errors_1.
|
|
112
|
+
throw new errors_1.DuplicateStepError(name);
|
|
113
113
|
}
|
|
114
114
|
this.seen.add(name);
|
|
115
115
|
}
|
|
@@ -176,7 +176,7 @@ class ContextImpl {
|
|
|
176
176
|
catch (e) {
|
|
177
177
|
const msg = e instanceof Error ? e.message : String(e);
|
|
178
178
|
await this.task.commitFailed(name, msg);
|
|
179
|
-
throw new errors_1.
|
|
179
|
+
throw new errors_1.StepFailedError(name, e);
|
|
180
180
|
}
|
|
181
181
|
const text = checkJsonRoundtrip(value);
|
|
182
182
|
await this.task.commitDone(name, "json", text);
|
|
@@ -210,7 +210,7 @@ async function run(path, fn) {
|
|
|
210
210
|
lock = await (0, lock_1.acquireLock)(path);
|
|
211
211
|
}
|
|
212
212
|
catch (e) {
|
|
213
|
-
if (e instanceof errors_1.
|
|
213
|
+
if (e instanceof errors_1.LockedError)
|
|
214
214
|
throw e;
|
|
215
215
|
throw e;
|
|
216
216
|
}
|
package/dist/src/lock.js
CHANGED
|
@@ -53,7 +53,7 @@ async function acquireLock(path) {
|
|
|
53
53
|
await closeFd(fd);
|
|
54
54
|
const code = e.code;
|
|
55
55
|
if (code === "EWOULDBLOCK" || code === "EAGAIN") {
|
|
56
|
-
throw new errors_1.
|
|
56
|
+
throw new errors_1.LockedError(`${path}: locked by another process`);
|
|
57
57
|
}
|
|
58
58
|
throw e;
|
|
59
59
|
}
|
package/dist/src/names.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Step-name validation. Names must match /^[A-Za-z0-9][A-Za-z0-9._-]*$/.
|
|
3
|
-
* Duplicate names within one task body raise
|
|
3
|
+
* Duplicate names within one task body raise DuplicateStepError;
|
|
4
4
|
* see ../src/index.ts.
|
|
5
5
|
*/
|
|
6
6
|
export declare function validateName(name: string): void;
|
package/dist/src/names.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* Step-name validation. Names must match /^[A-Za-z0-9][A-Za-z0-9._-]*$/.
|
|
4
|
-
* Duplicate names within one task body raise
|
|
4
|
+
* Duplicate names within one task body raise DuplicateStepError;
|
|
5
5
|
* see ../src/index.ts.
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
package/dist/src/schema.js
CHANGED
|
@@ -42,7 +42,7 @@ async function bootstrap(db) {
|
|
|
42
42
|
if (existing) {
|
|
43
43
|
const row = await db.get("SELECT value FROM mundane_meta WHERE key='schema_version'");
|
|
44
44
|
if (row && row.value !== exports.SCHEMA_VERSION) {
|
|
45
|
-
throw new errors_1.
|
|
45
|
+
throw new errors_1.SchemaError(`schema_version is ${JSON.stringify(row.value)}, expected "${exports.SCHEMA_VERSION}"`);
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
await db.exec("BEGIN IMMEDIATE");
|
|
@@ -71,6 +71,6 @@ async function bootstrap(db) {
|
|
|
71
71
|
// Final check.
|
|
72
72
|
const row = await db.get("SELECT value FROM mundane_meta WHERE key='schema_version'");
|
|
73
73
|
if (!row || row.value !== exports.SCHEMA_VERSION) {
|
|
74
|
-
throw new errors_1.
|
|
74
|
+
throw new errors_1.SchemaError(`schema_version is ${JSON.stringify(row?.value)}, expected "${exports.SCHEMA_VERSION}"`);
|
|
75
75
|
}
|
|
76
76
|
}
|
package/dist/test/basic.test.js
CHANGED
|
@@ -110,13 +110,13 @@ function newDb() {
|
|
|
110
110
|
cleanup();
|
|
111
111
|
}
|
|
112
112
|
});
|
|
113
|
-
(0, node_test_1.test)("duplicate step name raises
|
|
113
|
+
(0, node_test_1.test)("duplicate step name raises DuplicateStepError", async () => {
|
|
114
114
|
const { path, cleanup } = newDb();
|
|
115
115
|
try {
|
|
116
116
|
await strict_1.default.rejects((0, index_1.run)(path, async (ctx) => {
|
|
117
117
|
await ctx.step("x", async () => 1);
|
|
118
118
|
await ctx.step("x", async () => 2);
|
|
119
|
-
}), (e) => e instanceof index_1.
|
|
119
|
+
}), (e) => e instanceof index_1.DuplicateStepError && e.stepName === "x");
|
|
120
120
|
// First step still committed before the dup raised.
|
|
121
121
|
const names = (await readSteps(path)).map((s) => s.name);
|
|
122
122
|
strict_1.default.deepEqual(names, ["x"]);
|
|
@@ -166,7 +166,7 @@ function newDb() {
|
|
|
166
166
|
const { path, cleanup } = newDb();
|
|
167
167
|
try {
|
|
168
168
|
// Back-to-back runs: if release() resolved before the helper actually
|
|
169
|
-
// dropped the flock, a later run would throw
|
|
169
|
+
// dropped the flock, a later run would throw LockedError.
|
|
170
170
|
for (let i = 0; i < 5; i++) {
|
|
171
171
|
await (0, index_1.run)(path, async (ctx) => ctx.step(`s${i}`, async () => i));
|
|
172
172
|
}
|
|
@@ -177,18 +177,18 @@ function newDb() {
|
|
|
177
177
|
cleanup();
|
|
178
178
|
}
|
|
179
179
|
});
|
|
180
|
-
(0, node_test_1.test)("non-JSON value raises
|
|
180
|
+
(0, node_test_1.test)("non-JSON value raises SerializationError", async () => {
|
|
181
181
|
const { path, cleanup } = newDb();
|
|
182
182
|
try {
|
|
183
183
|
await strict_1.default.rejects((0, index_1.run)(path, async (ctx) => {
|
|
184
184
|
await ctx.step("a", async () => new Date());
|
|
185
|
-
}), (e) => e instanceof index_1.
|
|
185
|
+
}), (e) => e instanceof index_1.SerializationError);
|
|
186
186
|
}
|
|
187
187
|
finally {
|
|
188
188
|
cleanup();
|
|
189
189
|
}
|
|
190
190
|
});
|
|
191
|
-
(0, node_test_1.test)("locked task throws
|
|
191
|
+
(0, node_test_1.test)("locked task throws LockedError", async () => {
|
|
192
192
|
const { path, cleanup } = newDb();
|
|
193
193
|
try {
|
|
194
194
|
let unblock;
|
|
@@ -202,7 +202,7 @@ function newDb() {
|
|
|
202
202
|
});
|
|
203
203
|
// Give the first run time to acquire the lock.
|
|
204
204
|
await new Promise((r) => setTimeout(r, 200));
|
|
205
|
-
await strict_1.default.rejects((0, index_1.run)(path, async () => { }), (e) => e instanceof index_1.
|
|
205
|
+
await strict_1.default.rejects((0, index_1.run)(path, async () => { }), (e) => e instanceof index_1.LockedError);
|
|
206
206
|
unblock();
|
|
207
207
|
await first;
|
|
208
208
|
}
|