keri-ts 0.1.0
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/LICENSE +202 -0
- package/README.md +70 -0
- package/esm/_dnt.polyfills.js +127 -0
- package/esm/_dnt.shims.js +61 -0
- package/esm/app/cli/agent.js +37 -0
- package/esm/app/cli/cli-node.js +9 -0
- package/esm/app/cli/cli.js +195 -0
- package/esm/app/cli/db-dump.js +68 -0
- package/esm/app/cli/init.js +75 -0
- package/esm/app/server.js +77 -0
- package/esm/core/bytes.js +39 -0
- package/esm/core/errors.js +26 -0
- package/esm/core/index.js +7 -0
- package/esm/db/basing.js +168 -0
- package/esm/db/core/db.js +19 -0
- package/esm/db/core/lmdber.js +474 -0
- package/esm/db/core/path-manager.js +450 -0
- package/esm/db/index.js +4 -0
- package/esm/npm/index.js +4 -0
- package/esm/package.json +3 -0
- package/package.json +57 -0
- package/types/_dnt.polyfills.d.ts +101 -0
- package/types/_dnt.polyfills.d.ts.map +1 -0
- package/types/_dnt.shims.d.ts +6 -0
- package/types/_dnt.shims.d.ts.map +1 -0
- package/types/app/cli/agent.d.ts +9 -0
- package/types/app/cli/agent.d.ts.map +1 -0
- package/types/app/cli/cli-node.d.ts +2 -0
- package/types/app/cli/cli-node.d.ts.map +1 -0
- package/types/app/cli/cli.d.ts +7 -0
- package/types/app/cli/cli.d.ts.map +1 -0
- package/types/app/cli/db-dump.d.ts +11 -0
- package/types/app/cli/db-dump.d.ts.map +1 -0
- package/types/app/cli/init.d.ts +3 -0
- package/types/app/cli/init.d.ts.map +1 -0
- package/types/app/server.d.ts +8 -0
- package/types/app/server.d.ts.map +1 -0
- package/types/core/bytes.d.ts +17 -0
- package/types/core/bytes.d.ts.map +1 -0
- package/types/core/errors.d.ts +19 -0
- package/types/core/errors.d.ts.map +1 -0
- package/types/core/index.d.ts +8 -0
- package/types/core/index.d.ts.map +1 -0
- package/types/db/basing.d.ts +80 -0
- package/types/db/basing.d.ts.map +1 -0
- package/types/db/core/db.d.ts +5 -0
- package/types/db/core/db.d.ts.map +1 -0
- package/types/db/core/lmdber.d.ts +135 -0
- package/types/db/core/lmdber.d.ts.map +1 -0
- package/types/db/core/path-manager.d.ts +92 -0
- package/types/db/core/path-manager.d.ts.map +1 -0
- package/types/db/index.d.ts +5 -0
- package/types/db/index.d.ts.map +1 -0
- package/types/npm/index.d.ts +5 -0
- package/types/npm/index.d.ts.map +1 -0
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PathManager - File and directory path management
|
|
3
|
+
*
|
|
4
|
+
* Manages file directories and files for KERI installation resources like databases.
|
|
5
|
+
* Uses composition pattern instead of inheritance.
|
|
6
|
+
*/
|
|
7
|
+
import * as dntShim from "../../_dnt.shims.js";
|
|
8
|
+
import { action } from "effection";
|
|
9
|
+
import { InvalidPathNameError, PathError } from "../../core/errors.js";
|
|
10
|
+
export const PATH_DEFAULTS = {
|
|
11
|
+
headDirPath: "/usr/local/var",
|
|
12
|
+
tailDirPath: "keri/db",
|
|
13
|
+
cleanTailDirPath: "keri/clean/db",
|
|
14
|
+
altHeadDirPath: "~",
|
|
15
|
+
altTailDirPath: ".keri/db",
|
|
16
|
+
altCleanTailDirPath: ".keri/clean/db",
|
|
17
|
+
tempHeadDir: "/tmp",
|
|
18
|
+
tempPrefix: "keri_lmdb_",
|
|
19
|
+
tempSuffix: "_test",
|
|
20
|
+
perm: 0o1700, // sticky + owner rwx
|
|
21
|
+
mode: "r+",
|
|
22
|
+
fext: "text",
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* PathManager manages file and directory paths
|
|
26
|
+
*/
|
|
27
|
+
export class PathManager {
|
|
28
|
+
constructor(options = {}, defaults) {
|
|
29
|
+
// name of the path, dir or file name
|
|
30
|
+
Object.defineProperty(this, "_name", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
configurable: true,
|
|
33
|
+
writable: true,
|
|
34
|
+
value: void 0
|
|
35
|
+
});
|
|
36
|
+
// base directory path
|
|
37
|
+
Object.defineProperty(this, "base", {
|
|
38
|
+
enumerable: true,
|
|
39
|
+
configurable: true,
|
|
40
|
+
writable: true,
|
|
41
|
+
value: void 0
|
|
42
|
+
});
|
|
43
|
+
// temporary directory flag
|
|
44
|
+
Object.defineProperty(this, "temp", {
|
|
45
|
+
enumerable: true,
|
|
46
|
+
configurable: true,
|
|
47
|
+
writable: true,
|
|
48
|
+
value: void 0
|
|
49
|
+
});
|
|
50
|
+
// head directory path
|
|
51
|
+
Object.defineProperty(this, "headDirPath", {
|
|
52
|
+
enumerable: true,
|
|
53
|
+
configurable: true,
|
|
54
|
+
writable: true,
|
|
55
|
+
value: void 0
|
|
56
|
+
});
|
|
57
|
+
// path to the directory or file
|
|
58
|
+
Object.defineProperty(this, "path", {
|
|
59
|
+
enumerable: true,
|
|
60
|
+
configurable: true,
|
|
61
|
+
writable: true,
|
|
62
|
+
value: void 0
|
|
63
|
+
});
|
|
64
|
+
Object.defineProperty(this, "perm", {
|
|
65
|
+
enumerable: true,
|
|
66
|
+
configurable: true,
|
|
67
|
+
writable: true,
|
|
68
|
+
value: void 0
|
|
69
|
+
});
|
|
70
|
+
Object.defineProperty(this, "filed", {
|
|
71
|
+
enumerable: true,
|
|
72
|
+
configurable: true,
|
|
73
|
+
writable: true,
|
|
74
|
+
value: void 0
|
|
75
|
+
});
|
|
76
|
+
Object.defineProperty(this, "extensioned", {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
configurable: true,
|
|
79
|
+
writable: true,
|
|
80
|
+
value: void 0
|
|
81
|
+
});
|
|
82
|
+
Object.defineProperty(this, "mode", {
|
|
83
|
+
enumerable: true,
|
|
84
|
+
configurable: true,
|
|
85
|
+
writable: true,
|
|
86
|
+
value: void 0
|
|
87
|
+
});
|
|
88
|
+
Object.defineProperty(this, "fext", {
|
|
89
|
+
enumerable: true,
|
|
90
|
+
configurable: true,
|
|
91
|
+
writable: true,
|
|
92
|
+
value: void 0
|
|
93
|
+
});
|
|
94
|
+
Object.defineProperty(this, "opened", {
|
|
95
|
+
enumerable: true,
|
|
96
|
+
configurable: true,
|
|
97
|
+
writable: true,
|
|
98
|
+
value: void 0
|
|
99
|
+
});
|
|
100
|
+
Object.defineProperty(this, "defaults", {
|
|
101
|
+
enumerable: true,
|
|
102
|
+
configurable: true,
|
|
103
|
+
writable: true,
|
|
104
|
+
value: void 0
|
|
105
|
+
});
|
|
106
|
+
this.defaults = { ...PATH_DEFAULTS, ...defaults };
|
|
107
|
+
this._name = options.name || "main";
|
|
108
|
+
this.base = options.base || "";
|
|
109
|
+
this.temp = options.temp || false;
|
|
110
|
+
this.headDirPath = options.headDirPath || this.defaults.headDirPath;
|
|
111
|
+
this.perm = options.perm ?? this.defaults.perm;
|
|
112
|
+
this.path = null;
|
|
113
|
+
this.filed = options.filed || false;
|
|
114
|
+
this.extensioned = options.extensioned || false;
|
|
115
|
+
this.mode = options.mode || this.defaults.mode;
|
|
116
|
+
this.fext = options.fext || this.defaults.fext;
|
|
117
|
+
this.opened = false;
|
|
118
|
+
// Note: Constructor cannot be async/generator, so reopen must be called explicitly
|
|
119
|
+
// if options.reopen is true. This is handled by callers (e.g., LMDBer).
|
|
120
|
+
}
|
|
121
|
+
get name() {
|
|
122
|
+
return this._name;
|
|
123
|
+
}
|
|
124
|
+
set name(value) {
|
|
125
|
+
// Check if path is absolute
|
|
126
|
+
if (value.startsWith("/") || value.includes(":")) {
|
|
127
|
+
throw new InvalidPathNameError(`Not relative name=${value} path.`, { name: value });
|
|
128
|
+
}
|
|
129
|
+
this._name = value;
|
|
130
|
+
}
|
|
131
|
+
_getTempPath() {
|
|
132
|
+
const tempDir = dntShim.Deno.env.get("TMPDIR") || dntShim.Deno.env.get("TMP") ||
|
|
133
|
+
dntShim.Deno.env.get("TEMP") || "/tmp";
|
|
134
|
+
const tempName = `${this.defaults.tempPrefix}${this.name}${this.defaults.tempSuffix}`;
|
|
135
|
+
return `${tempDir}/${tempName}`;
|
|
136
|
+
}
|
|
137
|
+
_pathExpandTilde(path) {
|
|
138
|
+
if (path === "~" || path.startsWith("~/")) {
|
|
139
|
+
const home = dntShim.Deno.env.get("HOME") || "~";
|
|
140
|
+
return path === "~" ? home : path.replace("~", home);
|
|
141
|
+
}
|
|
142
|
+
return path;
|
|
143
|
+
}
|
|
144
|
+
_getPrimaryPath(headDirPath, clean) {
|
|
145
|
+
// head / tail / base / name
|
|
146
|
+
// Expand ~ to HOME directory
|
|
147
|
+
let head = headDirPath;
|
|
148
|
+
head = this._pathExpandTilde(head);
|
|
149
|
+
let tail;
|
|
150
|
+
if (clean) {
|
|
151
|
+
tail = this.defaults.cleanTailDirPath;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
tail = this.defaults.tailDirPath;
|
|
155
|
+
}
|
|
156
|
+
const parts = [head, tail];
|
|
157
|
+
if (this.base)
|
|
158
|
+
parts.push(this.base);
|
|
159
|
+
parts.push(this.name);
|
|
160
|
+
const path = parts.join("/");
|
|
161
|
+
return path;
|
|
162
|
+
}
|
|
163
|
+
_getAltPath(clean) {
|
|
164
|
+
// HOME or ~ / tail / base / name
|
|
165
|
+
let head = dntShim.Deno.env.get("HOME") || "~";
|
|
166
|
+
head = this._pathExpandTilde(head);
|
|
167
|
+
let tail;
|
|
168
|
+
if (clean) {
|
|
169
|
+
tail = this.defaults.altCleanTailDirPath;
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
tail = this.defaults.altTailDirPath;
|
|
173
|
+
}
|
|
174
|
+
const altParts = [head, tail];
|
|
175
|
+
if (this.base)
|
|
176
|
+
altParts.push(this.base);
|
|
177
|
+
altParts.push(this.name);
|
|
178
|
+
const path = altParts.join("/");
|
|
179
|
+
return path;
|
|
180
|
+
}
|
|
181
|
+
/*
|
|
182
|
+
* Creates a file path based on head, tail, base, and name. Ensure path is created and optionally reuse it.
|
|
183
|
+
* @param options path creation options
|
|
184
|
+
* @returns File path to a persistent file or directory
|
|
185
|
+
*/
|
|
186
|
+
_getPersistentPaths(options = {}) {
|
|
187
|
+
const headDirPath = options.headDirPath ?? this.headDirPath;
|
|
188
|
+
const clean = options.clean || false;
|
|
189
|
+
const primary = this._getPrimaryPath(headDirPath, clean);
|
|
190
|
+
const alt = this._getAltPath(clean);
|
|
191
|
+
return [primary, alt];
|
|
192
|
+
}
|
|
193
|
+
_getPaths(options = {}) {
|
|
194
|
+
const [primary, alt] = this._getPersistentPaths(options);
|
|
195
|
+
const tempPath = this._getTempPath();
|
|
196
|
+
return [primary, alt, tempPath];
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Helper: Convert Promise-based file system operations to Effection operations
|
|
200
|
+
* This ensures proper structured concurrency and cancellation support
|
|
201
|
+
*/
|
|
202
|
+
*_statOp(path) {
|
|
203
|
+
return yield* action((resolve, reject) => {
|
|
204
|
+
dntShim.Deno.stat(path)
|
|
205
|
+
.then(() => resolve(true))
|
|
206
|
+
.catch((error) => {
|
|
207
|
+
if (error instanceof dntShim.Deno.errors.NotFound) {
|
|
208
|
+
resolve(false);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
reject(error);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
return () => { };
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
*_accessOp(path) {
|
|
218
|
+
return yield* action((resolve, reject) => {
|
|
219
|
+
// In Deno, we check access by stating or trying to read/write.
|
|
220
|
+
// Simplified to checking existence and relying on OS permissions for now
|
|
221
|
+
dntShim.Deno.stat(path)
|
|
222
|
+
.then(() => resolve(true))
|
|
223
|
+
.catch(() => resolve(false));
|
|
224
|
+
return () => { };
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
*_mkdirOp(path, perm) {
|
|
228
|
+
return yield* action((resolve, reject) => {
|
|
229
|
+
dntShim.Deno.mkdir(path, { recursive: true, mode: perm })
|
|
230
|
+
.then(() => resolve(true))
|
|
231
|
+
.catch((error) => {
|
|
232
|
+
if (error instanceof dntShim.Deno.errors.PermissionDenied) {
|
|
233
|
+
resolve(false);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
reject(error);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
return () => { };
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
*_rmOp(path) {
|
|
243
|
+
return yield* action((resolve, reject) => {
|
|
244
|
+
dntShim.Deno.remove(path, { recursive: true })
|
|
245
|
+
.then(() => resolve(undefined))
|
|
246
|
+
.catch((error) => {
|
|
247
|
+
if (error instanceof dntShim.Deno.errors.NotFound) {
|
|
248
|
+
resolve(undefined);
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
reject(error);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
return () => { };
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
*_statFileOp(path) {
|
|
258
|
+
return yield* action((resolve, reject) => {
|
|
259
|
+
dntShim.Deno.stat(path)
|
|
260
|
+
.then((stats) => {
|
|
261
|
+
resolve({
|
|
262
|
+
isDirectory: stats.isDirectory,
|
|
263
|
+
isFile: stats.isFile,
|
|
264
|
+
});
|
|
265
|
+
})
|
|
266
|
+
.catch((error) => {
|
|
267
|
+
if (error instanceof dntShim.Deno.errors.NotFound) {
|
|
268
|
+
resolve({
|
|
269
|
+
isDirectory: false,
|
|
270
|
+
isFile: false,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
reject(error);
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
return () => { };
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Reopen/create the directory or file path
|
|
282
|
+
* Replicates KERIpy/HIO Filer.remake logic:
|
|
283
|
+
* - Tries primary path (/usr/local/var/keri/*) first
|
|
284
|
+
* - Falls back to alt path (~/.keri/*) on OS errors or access issues
|
|
285
|
+
*
|
|
286
|
+
* Uses Effection for structured concurrency:
|
|
287
|
+
* - All file system operations are cancellable
|
|
288
|
+
* - No dangling promises - operations tracked in Effection task tree
|
|
289
|
+
* - Automatic cleanup if parent operation is halted
|
|
290
|
+
*/
|
|
291
|
+
*reopen(options = {}) {
|
|
292
|
+
const temp = options.temp ?? this.temp;
|
|
293
|
+
let headDirPath = options.headDirPath ?? this.headDirPath;
|
|
294
|
+
const perm = options.perm ?? this.perm;
|
|
295
|
+
const clear = options.clear || false;
|
|
296
|
+
const reuse = options.reuse || false;
|
|
297
|
+
const clean = options.clean || false;
|
|
298
|
+
const mode = options.mode ?? this.mode;
|
|
299
|
+
const fext = options.fext ?? this.fext;
|
|
300
|
+
this.temp = temp;
|
|
301
|
+
this.perm = perm;
|
|
302
|
+
this.mode = mode;
|
|
303
|
+
this.fext = fext;
|
|
304
|
+
let path;
|
|
305
|
+
const [primary, alt, tempPath] = this._getPaths({
|
|
306
|
+
...options,
|
|
307
|
+
headDirPath,
|
|
308
|
+
clean,
|
|
309
|
+
});
|
|
310
|
+
if (temp) {
|
|
311
|
+
// Use temporary directory
|
|
312
|
+
path = tempPath;
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
// Use persistent directory - try primary first, fall back to alt on error
|
|
316
|
+
path = primary;
|
|
317
|
+
let useAltPath = false;
|
|
318
|
+
// Only attempt fallback if using default headDirPath (not a custom one)
|
|
319
|
+
const usingDefaultHeadDir = headDirPath === this.defaults.headDirPath;
|
|
320
|
+
if (!reuse && usingDefaultHeadDir) {
|
|
321
|
+
// Check if path exists using Effection operation
|
|
322
|
+
const pathExists = yield* this._statOp(path);
|
|
323
|
+
if (!pathExists) {
|
|
324
|
+
// Path doesn't exist, try to create it
|
|
325
|
+
console.log(`Creating directory at ${path}`);
|
|
326
|
+
const created = yield* this._mkdirOp(path, perm);
|
|
327
|
+
if (!created) {
|
|
328
|
+
// Creation failed (e.g., EACCES) - fall back to alt path
|
|
329
|
+
console.log(`Failed to create primary path, falling back to alt path`);
|
|
330
|
+
useAltPath = true;
|
|
331
|
+
path = alt;
|
|
332
|
+
headDirPath = this.defaults.altHeadDirPath;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// If we're using alt path, ensure it exists
|
|
336
|
+
if (useAltPath) {
|
|
337
|
+
const altPathExists = yield* this._statOp(path);
|
|
338
|
+
if (!altPathExists) {
|
|
339
|
+
// Alt path doesn't exist, create it
|
|
340
|
+
console.log(`Creating alt directory at ${path}`);
|
|
341
|
+
const created = yield* this._mkdirOp(path, perm);
|
|
342
|
+
if (!created) {
|
|
343
|
+
// Even alt path creation failed - this is unexpected, but we'll continue
|
|
344
|
+
console.error(`Error: Failed to create alt directory at ${path}`);
|
|
345
|
+
throw new PathError(`Failed to create alt directory at ${path}`, { path });
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
// Path exists, verify access
|
|
350
|
+
const altHasAccess = yield* this._accessOp(path);
|
|
351
|
+
if (!altHasAccess) {
|
|
352
|
+
// Path exists but no access - this shouldn't happen for alt path, but log it
|
|
353
|
+
console.error(`Error: Alt path exists but is not accessible: ${path}`);
|
|
354
|
+
throw new PathError(`Alt path exists but is not accessible: ${path}`, { path });
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
else if (reuse) {
|
|
360
|
+
// Reuse mode - just verify the path exists and is accessible
|
|
361
|
+
const pathExists = yield* this._statOp(path);
|
|
362
|
+
const hasAccess = pathExists ? yield* this._accessOp(path) : false;
|
|
363
|
+
if (!pathExists || !hasAccess) {
|
|
364
|
+
// If reuse path doesn't work and we're using default, try alt
|
|
365
|
+
if (usingDefaultHeadDir) {
|
|
366
|
+
console.log(`Reuse path not accessible, trying alt path`);
|
|
367
|
+
path = alt;
|
|
368
|
+
headDirPath = this.defaults.altHeadDirPath;
|
|
369
|
+
const altPathExists = yield* this._statOp(path);
|
|
370
|
+
const altHasAccess = altPathExists
|
|
371
|
+
? yield* this._accessOp(path)
|
|
372
|
+
: false;
|
|
373
|
+
if (!altPathExists) {
|
|
374
|
+
// Alt path doesn't exist, create it
|
|
375
|
+
console.log(`Creating alt directory at ${path}`);
|
|
376
|
+
const created = yield* this._mkdirOp(path, perm);
|
|
377
|
+
if (!created) {
|
|
378
|
+
console.warn(`Warning: Failed to create alt directory at ${path}`);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
else if (!altHasAccess) {
|
|
382
|
+
// Alt path exists but not accessible - unexpected but continue
|
|
383
|
+
console.warn(`Warning: Alt path exists but is not accessible: ${path}`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
// Update headDirPath if we fell back to alt
|
|
390
|
+
this.headDirPath = headDirPath;
|
|
391
|
+
// Clear if requested
|
|
392
|
+
if (clear) {
|
|
393
|
+
const pathStat = yield* this._statFileOp(path);
|
|
394
|
+
if (pathStat && (pathStat.isDirectory || pathStat.isFile)) {
|
|
395
|
+
yield* this._rmOp(path);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
// Create directory if it doesn't exist (final check)
|
|
399
|
+
if (!this.filed) {
|
|
400
|
+
const pathExists = yield* this._statOp(path);
|
|
401
|
+
if (!pathExists) {
|
|
402
|
+
// Path doesn't exist, create it
|
|
403
|
+
console.log(`Creating directory at ${path}`);
|
|
404
|
+
const created = yield* this._mkdirOp(path, perm);
|
|
405
|
+
if (!created) {
|
|
406
|
+
// Creation failed - this is unexpected at this point, but log it
|
|
407
|
+
console.warn(`Warning: Failed to create directory at ${path}`);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
// Path exists, verify we can access it
|
|
412
|
+
const hasAccess = yield* this._accessOp(path);
|
|
413
|
+
if (!hasAccess) {
|
|
414
|
+
// Path exists but not accessible - unexpected but continue
|
|
415
|
+
console.warn(`Warning: Path exists but is not accessible: ${path}`);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
this.path = path;
|
|
420
|
+
this.opened = true;
|
|
421
|
+
return this.opened;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Close the path manager
|
|
425
|
+
* If clear is true, removes the directory/file
|
|
426
|
+
* Uses Effection for structured concurrency
|
|
427
|
+
*/
|
|
428
|
+
*close(clear = false) {
|
|
429
|
+
if (clear && this.path) {
|
|
430
|
+
yield* this._rmOp(this.path);
|
|
431
|
+
}
|
|
432
|
+
this.path = null;
|
|
433
|
+
this.opened = false;
|
|
434
|
+
return true;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Check if database files exist in the path directory
|
|
438
|
+
* LMDB creates data.mdb and lock.mdb files
|
|
439
|
+
* Returns true if data.mdb exists (lock.mdb might not exist if no active transactions)
|
|
440
|
+
* Uses Effection for structured concurrency
|
|
441
|
+
*/
|
|
442
|
+
*databaseFilesExist() {
|
|
443
|
+
if (!this.path) {
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
const dataMdbPath = `${this.path}/data.mdb`;
|
|
447
|
+
const pathStat = yield* this._statFileOp(dataMdbPath);
|
|
448
|
+
return pathStat.isFile ?? false;
|
|
449
|
+
}
|
|
450
|
+
}
|
package/esm/db/index.js
ADDED
package/esm/npm/index.js
ADDED
package/esm/package.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "keri-ts",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "KERI TypeScript package with database primitives and CLI runtime",
|
|
5
|
+
"homepage": "https://github.com/kentbull/keri-ts",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/kentbull/keri-ts.git"
|
|
9
|
+
},
|
|
10
|
+
"license": "Apache-2.0",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/kentbull/keri-ts/issues"
|
|
13
|
+
},
|
|
14
|
+
"main": "./esm/npm/index.js",
|
|
15
|
+
"module": "./esm/npm/index.js",
|
|
16
|
+
"types": "./types/npm/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"import": "./esm/npm/index.js",
|
|
20
|
+
"types": "./types/npm/index.d.ts"
|
|
21
|
+
},
|
|
22
|
+
"./src/app/cli/cli-node.js": {
|
|
23
|
+
"import": {
|
|
24
|
+
"types": "./types/app/cli/cli-node.d.ts",
|
|
25
|
+
"default": "./esm/app/cli/cli-node.js"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"prepublishOnly": "npm run test",
|
|
31
|
+
"test": "node --version"
|
|
32
|
+
},
|
|
33
|
+
"type": "module",
|
|
34
|
+
"sideEffects": false,
|
|
35
|
+
"bin": {
|
|
36
|
+
"kli": "./esm/app/cli/cli-node.js"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"esm",
|
|
40
|
+
"types",
|
|
41
|
+
"README.md",
|
|
42
|
+
"LICENSE"
|
|
43
|
+
],
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"commander": "^10.0.1",
|
|
49
|
+
"effection": "^3.6.0",
|
|
50
|
+
"lmdb": "^3.4.4",
|
|
51
|
+
"@deno/shim-deno": "~0.18.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/node": "^20.9.0"
|
|
55
|
+
},
|
|
56
|
+
"_generatedBy": "dnt@dev"
|
|
57
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Based on [import-meta-ponyfill](https://github.com/gaubee/import-meta-ponyfill),
|
|
3
|
+
* but instead of using npm to install additional dependencies,
|
|
4
|
+
* this approach manually consolidates cjs/mjs/d.ts into a single file.
|
|
5
|
+
*
|
|
6
|
+
* Note that this code might be imported multiple times
|
|
7
|
+
* (for example, both dnt.test.polyfills.ts and dnt.polyfills.ts contain this code;
|
|
8
|
+
* or Node.js might dynamically clear the cache and then force a require).
|
|
9
|
+
* Therefore, it's important to avoid redundant writes to global objects.
|
|
10
|
+
* Additionally, consider that commonjs is used alongside esm,
|
|
11
|
+
* so the two ponyfill functions are stored independently in two separate global objects.
|
|
12
|
+
*/
|
|
13
|
+
import { createRequire } from "node:module";
|
|
14
|
+
import { type URL } from "node:url";
|
|
15
|
+
declare global {
|
|
16
|
+
interface ImportMeta {
|
|
17
|
+
/** A string representation of the fully qualified module URL. When the
|
|
18
|
+
* module is loaded locally, the value will be a file URL (e.g.
|
|
19
|
+
* `file:///path/module.ts`).
|
|
20
|
+
*
|
|
21
|
+
* You can also parse the string as a URL to determine more information about
|
|
22
|
+
* how the current module was loaded. For example to determine if a module was
|
|
23
|
+
* local or not:
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* const url = new URL(import.meta.url);
|
|
27
|
+
* if (url.protocol === "file:") {
|
|
28
|
+
* console.log("this module was loaded locally");
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
url: string;
|
|
33
|
+
/**
|
|
34
|
+
* A function that returns resolved specifier as if it would be imported
|
|
35
|
+
* using `import(specifier)`.
|
|
36
|
+
*
|
|
37
|
+
* ```ts
|
|
38
|
+
* console.log(import.meta.resolve("./foo.js"));
|
|
39
|
+
* // file:///dev/foo.js
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @param specifier The module specifier to resolve relative to `parent`.
|
|
43
|
+
* @param parent The absolute parent module URL to resolve from.
|
|
44
|
+
* @returns The absolute (`file:`) URL string for the resolved module.
|
|
45
|
+
*/
|
|
46
|
+
resolve(specifier: string, parent?: string | URL | undefined): string;
|
|
47
|
+
/** A flag that indicates if the current module is the main module that was
|
|
48
|
+
* called when starting the program under Deno.
|
|
49
|
+
*
|
|
50
|
+
* ```ts
|
|
51
|
+
* if (import.meta.main) {
|
|
52
|
+
* // this was loaded as the main module, maybe do some bootstrapping
|
|
53
|
+
* }
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
main: boolean;
|
|
57
|
+
/** The absolute path of the current module.
|
|
58
|
+
*
|
|
59
|
+
* This property is only provided for local modules (ie. using `file://` URLs).
|
|
60
|
+
*
|
|
61
|
+
* Example:
|
|
62
|
+
* ```
|
|
63
|
+
* // Unix
|
|
64
|
+
* console.log(import.meta.filename); // /home/alice/my_module.ts
|
|
65
|
+
*
|
|
66
|
+
* // Windows
|
|
67
|
+
* console.log(import.meta.filename); // C:\alice\my_module.ts
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
filename: string;
|
|
71
|
+
/** The absolute path of the directory containing the current module.
|
|
72
|
+
*
|
|
73
|
+
* This property is only provided for local modules (ie. using `file://` URLs).
|
|
74
|
+
*
|
|
75
|
+
* * Example:
|
|
76
|
+
* ```
|
|
77
|
+
* // Unix
|
|
78
|
+
* console.log(import.meta.dirname); // /home/alice
|
|
79
|
+
*
|
|
80
|
+
* // Windows
|
|
81
|
+
* console.log(import.meta.dirname); // C:\alice
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
dirname: string;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
type NodeRequest = ReturnType<typeof createRequire>;
|
|
88
|
+
type NodeModule = NonNullable<NodeRequest["main"]>;
|
|
89
|
+
interface ImportMetaPonyfillCommonjs {
|
|
90
|
+
(require: NodeRequest, module: NodeModule): ImportMeta;
|
|
91
|
+
}
|
|
92
|
+
interface ImportMetaPonyfillEsmodule {
|
|
93
|
+
(importMeta: ImportMeta): ImportMeta;
|
|
94
|
+
}
|
|
95
|
+
interface ImportMetaPonyfill extends ImportMetaPonyfillCommonjs, ImportMetaPonyfillEsmodule {
|
|
96
|
+
}
|
|
97
|
+
export declare let import_meta_ponyfill_commonjs: ImportMetaPonyfillCommonjs;
|
|
98
|
+
export declare let import_meta_ponyfill_esmodule: ImportMetaPonyfillEsmodule;
|
|
99
|
+
export declare let import_meta_ponyfill: ImportMetaPonyfill;
|
|
100
|
+
export {};
|
|
101
|
+
//# sourceMappingURL=_dnt.polyfills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_dnt.polyfills.d.ts","sourceRoot":"","sources":["../src/_dnt.polyfills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAgC,KAAK,GAAG,EAAE,MAAM,UAAU,CAAC;AAGlE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,UAAU;QAClB;;;;;;;;;;;;;;WAcG;QACH,GAAG,EAAE,MAAM,CAAC;QACZ;;;;;;;;;;;;WAYG;QACH,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,GAAG,MAAM,CAAC;QACtE;;;;;;;;WAQG;QACH,IAAI,EAAE,OAAO,CAAC;QAEd;;;;;;;;;;;;WAYG;QACH,QAAQ,EAAE,MAAM,CAAC;QAEjB;;;;;;;;;;;;WAYG;QACH,OAAO,EAAE,MAAM,CAAC;KACjB;CACF;AAED,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACpD,KAAK,UAAU,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AACnD,UAAU,0BAA0B;IAClC,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;CACxD;AACD,UAAU,0BAA0B;IAClC,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,CAAC;CACtC;AACD,UAAU,kBACR,SAAQ,0BAA0B,EAAE,0BAA0B;CAC/D;AAiBD,eAAO,IAAI,6BAA6B,EA2BnC,0BAA0B,CAAC;AAMhC,eAAO,IAAI,6BAA6B,EA4DnC,0BAA0B,CAAC;AAMhC,eAAO,IAAI,oBAAoB,EAoB1B,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_dnt.shims.d.ts","sourceRoot":"","sources":["../src/_dnt.shims.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAKvC,eAAO,MAAM,aAAa;;CAA2C,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Operation } from "effection";
|
|
2
|
+
/**
|
|
3
|
+
* Agent command operation - starts the HTTP server
|
|
4
|
+
*
|
|
5
|
+
* @param args - Command arguments including optional port
|
|
6
|
+
* @returns Operation that runs the server until shutdown
|
|
7
|
+
*/
|
|
8
|
+
export declare function agentCommand(args: Record<string, unknown>): Operation<void>;
|
|
9
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/app/cli/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAuB3C;;;;;GAKG;AACH,wBAAiB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAoB5E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-node.d.ts","sourceRoot":"","sources":["../../../src/app/cli/cli-node.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Operation } from "effection";
|
|
2
|
+
/**
|
|
3
|
+
* Main CLI operation - runs within Effection's structured concurrency
|
|
4
|
+
* This is the outermost runtime, not JavaScript's event loop
|
|
5
|
+
*/
|
|
6
|
+
export declare function kli(args?: string[]): Operation<void>;
|
|
7
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/app/cli/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAuMnD;;;GAGG;AACH,wBAAiB,GAAG,CAAC,IAAI,GAAE,MAAM,EAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAkDzD"}
|