@adviser/cement 0.2.28 → 0.2.30
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/{base-sys-abstraction-C9WW3w57.d.cts → base-sys-abstraction-BkEiLHl0.d.ts} +8 -4
- package/{base-sys-abstraction-C9WW3w57.d.ts → base-sys-abstraction-Qj7pkY1N.d.cts} +8 -4
- package/{chunk-OXD3YZZ7.js → chunk-7KFVMTOS.js} +3 -47
- package/chunk-7KFVMTOS.js.map +1 -0
- package/{chunk-P5RXA4C4.js → chunk-GES3MUGV.js} +24 -27
- package/{chunk-LCPYQVWT.js.map → chunk-GES3MUGV.js.map} +1 -1
- package/{chunk-YDIUMYIE.js → chunk-Q65HLCNL.js} +8 -7
- package/chunk-Q65HLCNL.js.map +1 -0
- package/{chunk-DPIL5UIL.js → chunk-WMMUXBDX.js} +6 -2
- package/chunk-WMMUXBDX.js.map +1 -0
- package/{index-Dhb2fQiw.d.cts → index-Q3phXzYr.d.cts} +2 -21
- package/{index-CcsGcehs.d.ts → index-tIGZMHTc.d.ts} +2 -21
- package/index.cjs +288 -7345
- package/index.cjs.map +1 -1
- package/index.d.cts +74 -12
- package/index.d.ts +74 -12
- package/index.js +239 -7266
- package/index.js.map +1 -1
- package/node/index.cjs +220 -39
- package/node/index.cjs.map +1 -1
- package/node/index.d.cts +22 -4
- package/node/index.d.ts +22 -4
- package/node/index.js +201 -25
- package/node/index.js.map +1 -1
- package/package.json +34 -23
- package/src/LICENSE +201 -0
- package/src/README.md +39 -0
- package/src/base-sys-abstraction.ts +242 -0
- package/src/bin2text.ts +47 -0
- package/src/crypto.ts +125 -0
- package/src/file-service.ts +24 -0
- package/src/future.ts +27 -0
- package/src/index.ts +23 -0
- package/src/jsr.json +22 -0
- package/src/log-level-impl.ts +87 -0
- package/src/log-writer-impl.ts +58 -0
- package/src/logger-impl.ts +498 -0
- package/src/logger.ts +208 -0
- package/src/node/deno-file-service.ts +92 -0
- package/src/node/deno-sys-abstraction.ts +133 -0
- package/src/node/index.ts +4 -0
- package/src/node/mock-file-service.ts +45 -0
- package/src/node/node-file-service.ts +91 -0
- package/src/node/node-sys-abstraction.ts +121 -0
- package/src/option.ts +60 -0
- package/src/refcounted.ts +23 -0
- package/src/resolve-once.ts +179 -0
- package/src/result.ts +165 -0
- package/src/runtime.ts +36 -0
- package/src/sys-abstraction.ts +53 -0
- package/src/sys-env.ts +216 -0
- package/src/test/log-write-stream.ts +95 -0
- package/src/test/mock-logger.ts +40 -0
- package/src/time.ts +20 -0
- package/src/tracer.ts +222 -0
- package/src/txt-en-decoder.ts +21 -0
- package/src/uri.ts +421 -0
- package/src/utils/console-write-stream.ts +72 -0
- package/src/utils/fanout-write-stream.ts +32 -0
- package/src/utils/index.ts +6 -0
- package/src/utils/rebuffer.ts +75 -0
- package/src/utils/stream-map.ts +67 -0
- package/src/utils/stream2string.ts +47 -0
- package/src/utils/string2stream.ts +14 -0
- package/src/version.ts +3 -0
- package/src/web/index.ts +1 -0
- package/src/web/web-sys-abstraction.ts +80 -0
- package/ts/base-sys-abstraction.d.ts +84 -0
- package/ts/base-sys-abstraction.d.ts.map +1 -0
- package/ts/base-sys-abstraction.js +178 -0
- package/ts/base-sys-abstraction.js.map +1 -0
- package/ts/base-sys-abstraction.test.d.ts +2 -0
- package/ts/base-sys-abstraction.test.d.ts.map +1 -0
- package/ts/base-sys-abstraction.test.js +82 -0
- package/ts/base-sys-abstraction.test.js.map +1 -0
- package/ts/bin2text.d.ts +3 -0
- package/ts/bin2text.d.ts.map +1 -0
- package/ts/bin2text.js +43 -0
- package/ts/bin2text.js.map +1 -0
- package/ts/bin2text.test.d.ts +2 -0
- package/ts/bin2text.test.d.ts.map +1 -0
- package/ts/bin2text.test.js +51 -0
- package/ts/bin2text.test.js.map +1 -0
- package/ts/crypto.d.ts +76 -0
- package/ts/crypto.d.ts.map +1 -0
- package/ts/crypto.js +22 -0
- package/ts/crypto.js.map +1 -0
- package/ts/crypto.test.d.ts +2 -0
- package/ts/crypto.test.d.ts.map +1 -0
- package/ts/crypto.test.js +14 -0
- package/ts/crypto.test.js.map +1 -0
- package/ts/file-service.d.ts +17 -0
- package/ts/file-service.d.ts.map +1 -0
- package/ts/file-service.js +2 -0
- package/ts/file-service.js.map +1 -0
- package/ts/future.d.ts +8 -0
- package/ts/future.d.ts.map +1 -0
- package/ts/future.js +38 -0
- package/ts/future.js.map +1 -0
- package/ts/future.test.d.ts +2 -0
- package/ts/future.test.d.ts.map +1 -0
- package/ts/future.test.js +28 -0
- package/ts/future.test.js.map +1 -0
- package/ts/index.d.ts +24 -0
- package/ts/index.d.ts.map +1 -0
- package/ts/index.js +24 -0
- package/ts/index.js.map +1 -0
- package/ts/log-level-impl.d.ts +14 -0
- package/ts/log-level-impl.d.ts.map +1 -0
- package/ts/log-level-impl.js +72 -0
- package/ts/log-level-impl.js.map +1 -0
- package/ts/log-writer-impl.d.ts +10 -0
- package/ts/log-writer-impl.d.ts.map +1 -0
- package/ts/log-writer-impl.js +45 -0
- package/ts/log-writer-impl.js.map +1 -0
- package/ts/logger-impl.d.ts +71 -0
- package/ts/logger-impl.d.ts.map +1 -0
- package/ts/logger-impl.js +412 -0
- package/ts/logger-impl.js.map +1 -0
- package/ts/logger.d.ts +84 -0
- package/ts/logger.d.ts.map +1 -0
- package/ts/logger.js +114 -0
- package/ts/logger.js.map +1 -0
- package/ts/logger.test.d.ts +2 -0
- package/ts/logger.test.d.ts.map +1 -0
- package/ts/logger.test.js +1023 -0
- package/ts/logger.test.js.map +1 -0
- package/ts/node/deno-file-service.d.ts +17 -0
- package/ts/node/deno-file-service.d.ts.map +1 -0
- package/ts/node/deno-file-service.js +65 -0
- package/ts/node/deno-file-service.js.map +1 -0
- package/ts/node/deno-sys-abstraction.d.ts +22 -0
- package/ts/node/deno-sys-abstraction.d.ts.map +1 -0
- package/ts/node/deno-sys-abstraction.js +101 -0
- package/ts/node/deno-sys-abstraction.js.map +1 -0
- package/ts/node/index.d.ts +5 -0
- package/ts/node/index.d.ts.map +1 -0
- package/ts/node/index.js +5 -0
- package/ts/node/index.js.map +1 -0
- package/ts/node/mock-file-service.d.ts +11 -0
- package/ts/node/mock-file-service.d.ts.map +1 -0
- package/ts/node/mock-file-service.js +34 -0
- package/ts/node/mock-file-service.js.map +1 -0
- package/ts/node/mock-file-service.test.d.ts +2 -0
- package/ts/node/mock-file-service.test.d.ts.map +1 -0
- package/ts/node/mock-file-service.test.js +31 -0
- package/ts/node/mock-file-service.test.js.map +1 -0
- package/ts/node/node-file-service.d.ts +16 -0
- package/ts/node/node-file-service.d.ts.map +1 -0
- package/ts/node/node-file-service.js +71 -0
- package/ts/node/node-file-service.js.map +1 -0
- package/ts/node/node-sys-abstraction.d.ts +22 -0
- package/ts/node/node-sys-abstraction.d.ts.map +1 -0
- package/ts/node/node-sys-abstraction.js +99 -0
- package/ts/node/node-sys-abstraction.js.map +1 -0
- package/ts/node/node-sys-abstraction.test.d.ts +2 -0
- package/ts/node/node-sys-abstraction.test.d.ts.map +1 -0
- package/ts/node/node-sys-abstraction.test.js +83 -0
- package/ts/node/node-sys-abstraction.test.js.map +1 -0
- package/ts/option.d.ts +25 -0
- package/ts/option.d.ts.map +1 -0
- package/ts/option.js +47 -0
- package/ts/option.js.map +1 -0
- package/ts/refcounted.d.ts +2 -0
- package/ts/refcounted.d.ts.map +1 -0
- package/ts/refcounted.js +19 -0
- package/ts/refcounted.js.map +1 -0
- package/ts/refcounted.test.d.ts +2 -0
- package/ts/refcounted.test.d.ts.map +1 -0
- package/ts/refcounted.test.js +39 -0
- package/ts/refcounted.test.js.map +1 -0
- package/ts/resolve-once.d.ts +46 -0
- package/ts/resolve-once.d.ts.map +1 -0
- package/ts/resolve-once.js +152 -0
- package/ts/resolve-once.js.map +1 -0
- package/ts/resolve-once.test.d.ts +2 -0
- package/ts/resolve-once.test.d.ts.map +1 -0
- package/ts/resolve-once.test.js +283 -0
- package/ts/resolve-once.test.js.map +1 -0
- package/ts/result.d.ts +34 -0
- package/ts/result.d.ts.map +1 -0
- package/ts/result.js +85 -0
- package/ts/result.js.map +1 -0
- package/ts/result.test.d.ts +2 -0
- package/ts/result.test.d.ts.map +1 -0
- package/ts/result.test.js +79 -0
- package/ts/result.test.js.map +1 -0
- package/ts/runtime.d.ts +8 -0
- package/ts/runtime.d.ts.map +1 -0
- package/ts/runtime.js +26 -0
- package/ts/runtime.js.map +1 -0
- package/ts/sys-abstraction.d.ts +36 -0
- package/ts/sys-abstraction.d.ts.map +1 -0
- package/ts/sys-abstraction.js +31 -0
- package/ts/sys-abstraction.js.map +1 -0
- package/ts/sys-env.d.ts +48 -0
- package/ts/sys-env.d.ts.map +1 -0
- package/ts/sys-env.js +176 -0
- package/ts/sys-env.js.map +1 -0
- package/ts/sys-env.test.d.ts +2 -0
- package/ts/sys-env.test.d.ts.map +1 -0
- package/ts/sys-env.test.js +51 -0
- package/ts/sys-env.test.js.map +1 -0
- package/ts/test/log-write-stream.d.ts +27 -0
- package/ts/test/log-write-stream.d.ts.map +1 -0
- package/ts/test/log-write-stream.js +74 -0
- package/ts/test/log-write-stream.js.map +1 -0
- package/ts/test/mock-logger.d.ts +14 -0
- package/ts/test/mock-logger.d.ts.map +1 -0
- package/ts/test/mock-logger.js +29 -0
- package/ts/test/mock-logger.js.map +1 -0
- package/ts/test/mock-logger.test.d.ts +2 -0
- package/ts/test/mock-logger.test.d.ts.map +1 -0
- package/ts/test/mock-logger.test.js +63 -0
- package/ts/test/mock-logger.test.js.map +1 -0
- package/ts/test/test-exit-handler.d.ts +2 -0
- package/ts/test/test-exit-handler.d.ts.map +1 -0
- package/ts/test/test-exit-handler.js +57 -0
- package/ts/test/test-exit-handler.js.map +1 -0
- package/ts/time.d.ts +13 -0
- package/ts/time.d.ts.map +1 -0
- package/ts/time.js +14 -0
- package/ts/time.js.map +1 -0
- package/ts/tracer.d.ts +59 -0
- package/ts/tracer.d.ts.map +1 -0
- package/ts/tracer.js +148 -0
- package/ts/tracer.js.map +1 -0
- package/ts/tracer.test.d.ts +2 -0
- package/ts/tracer.test.d.ts.map +1 -0
- package/ts/tracer.test.js +311 -0
- package/ts/tracer.test.js.map +1 -0
- package/ts/txt-en-decoder.d.ts +10 -0
- package/ts/txt-en-decoder.d.ts.map +1 -0
- package/ts/txt-en-decoder.js +15 -0
- package/ts/txt-en-decoder.js.map +1 -0
- package/ts/uri.d.ts +67 -0
- package/ts/uri.d.ts.map +1 -0
- package/ts/uri.js +283 -0
- package/ts/uri.js.map +1 -0
- package/ts/uri.test.d.ts +2 -0
- package/ts/uri.test.d.ts.map +1 -0
- package/ts/uri.test.js +119 -0
- package/ts/uri.test.js.map +1 -0
- package/ts/utils/console-write-stream.d.ts +21 -0
- package/ts/utils/console-write-stream.d.ts.map +1 -0
- package/ts/utils/console-write-stream.js +62 -0
- package/ts/utils/console-write-stream.js.map +1 -0
- package/ts/utils/fanout-write-stream.d.ts +12 -0
- package/ts/utils/fanout-write-stream.d.ts.map +1 -0
- package/ts/utils/fanout-write-stream.js +24 -0
- package/ts/utils/fanout-write-stream.js.map +1 -0
- package/ts/utils/index.d.ts +7 -0
- package/ts/utils/index.d.ts.map +1 -0
- package/ts/utils/index.js +7 -0
- package/ts/utils/index.js.map +1 -0
- package/ts/utils/rebuffer.d.ts +3 -0
- package/ts/utils/rebuffer.d.ts.map +1 -0
- package/ts/utils/rebuffer.js +60 -0
- package/ts/utils/rebuffer.js.map +1 -0
- package/ts/utils/rebuffer.test.d.ts +2 -0
- package/ts/utils/rebuffer.test.d.ts.map +1 -0
- package/ts/utils/rebuffer.test.js +77 -0
- package/ts/utils/rebuffer.test.js.map +1 -0
- package/ts/utils/stream-map.d.ts +9 -0
- package/ts/utils/stream-map.d.ts.map +1 -0
- package/ts/utils/stream-map.js +62 -0
- package/ts/utils/stream-map.js.map +1 -0
- package/ts/utils/stream-map.test.d.ts +2 -0
- package/ts/utils/stream-map.test.d.ts.map +1 -0
- package/ts/utils/stream-map.test.js +87 -0
- package/ts/utils/stream-map.test.js.map +1 -0
- package/ts/utils/stream-test-helper.d.ts +17 -0
- package/ts/utils/stream-test-helper.d.ts.map +1 -0
- package/ts/utils/stream-test-helper.js +37 -0
- package/ts/utils/stream-test-helper.js.map +1 -0
- package/ts/utils/stream2string.d.ts +3 -0
- package/ts/utils/stream2string.d.ts.map +1 -0
- package/ts/utils/stream2string.js +48 -0
- package/ts/utils/stream2string.js.map +1 -0
- package/ts/utils/stream2string.test.d.ts +2 -0
- package/ts/utils/stream2string.test.d.ts.map +1 -0
- package/ts/utils/stream2string.test.js +29 -0
- package/ts/utils/stream2string.test.js.map +1 -0
- package/ts/utils/string2stream.d.ts +4 -0
- package/ts/utils/string2stream.d.ts.map +1 -0
- package/ts/utils/string2stream.js +13 -0
- package/ts/utils/string2stream.js.map +1 -0
- package/ts/utils/string2stream.test.d.ts +2 -0
- package/ts/utils/string2stream.test.d.ts.map +1 -0
- package/ts/utils/string2stream.test.js +6 -0
- package/ts/utils/string2stream.test.js.map +1 -0
- package/ts/version.d.ts +2 -0
- package/ts/version.d.ts.map +1 -0
- package/ts/version.js +4 -0
- package/ts/version.js.map +1 -0
- package/ts/web/index.d.ts +2 -0
- package/ts/web/index.d.ts.map +1 -0
- package/ts/web/index.js +2 -0
- package/ts/web/index.js.map +1 -0
- package/ts/web/web-sys-abstraction.d.ts +4 -0
- package/ts/web/web-sys-abstraction.d.ts.map +1 -0
- package/ts/web/web-sys-abstraction.js +64 -0
- package/ts/web/web-sys-abstraction.js.map +1 -0
- package/utils/index.cjs +0 -42
- package/utils/index.cjs.map +1 -1
- package/utils/index.d.cts +1 -2
- package/utils/index.d.ts +1 -2
- package/utils/index.js +2 -7
- package/web/index.cjs +25 -7
- package/web/index.cjs.map +1 -1
- package/web/index.d.cts +2 -1
- package/web/index.d.ts +2 -1
- package/web/index.js +3 -3
- package/chunk-DPIL5UIL.js.map +0 -1
- package/chunk-LCPYQVWT.js +0 -21
- package/chunk-OXD3YZZ7.js.map +0 -1
- package/chunk-P5RXA4C4.js.map +0 -1
- package/chunk-YDIUMYIE.js.map +0 -1
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { Future } from "./future.js";
|
|
2
|
+
|
|
3
|
+
interface ResolveSeqItem<T, C> {
|
|
4
|
+
readonly future: Future<T>;
|
|
5
|
+
readonly fn: (c: C) => Promise<T>;
|
|
6
|
+
readonly id?: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export class ResolveSeq<T, C = void> {
|
|
10
|
+
readonly ctx: C;
|
|
11
|
+
constructor(ctx?: C) {
|
|
12
|
+
this.ctx = ctx as C;
|
|
13
|
+
}
|
|
14
|
+
reset(): void {
|
|
15
|
+
/* noop */
|
|
16
|
+
}
|
|
17
|
+
async _step(item?: ResolveSeqItem<T, C> | undefined): Promise<void> {
|
|
18
|
+
if (!item) {
|
|
19
|
+
// done
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
item
|
|
23
|
+
.fn(this.ctx)
|
|
24
|
+
.then((value) => item.future.resolve(value))
|
|
25
|
+
.catch((e) => item.future.reject(e as Error))
|
|
26
|
+
.finally(() => {
|
|
27
|
+
this._seqFutures.shift();
|
|
28
|
+
this._step(this._seqFutures[0]);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
readonly _seqFutures: ResolveSeqItem<T, C>[] = [];
|
|
32
|
+
async add(fn: (c: C) => Promise<T>, id?: number): Promise<T> {
|
|
33
|
+
const future = new Future<T>();
|
|
34
|
+
this._seqFutures.push({ future, fn, id });
|
|
35
|
+
if (this._seqFutures.length === 1) {
|
|
36
|
+
this._step(this._seqFutures[0]);
|
|
37
|
+
}
|
|
38
|
+
return future.asPromise();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class ResolveOnce<T, CTX = void> {
|
|
43
|
+
_onceDone = false;
|
|
44
|
+
readonly _onceFutures: Future<T>[] = [];
|
|
45
|
+
_onceOk = false;
|
|
46
|
+
_onceValue?: T;
|
|
47
|
+
_onceError?: Error;
|
|
48
|
+
_isPromise = false;
|
|
49
|
+
|
|
50
|
+
readonly ctx: CTX;
|
|
51
|
+
|
|
52
|
+
constructor(ctx?: CTX) {
|
|
53
|
+
this.ctx = ctx as CTX;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get ready(): boolean {
|
|
57
|
+
return this._onceDone;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
reset(): void {
|
|
61
|
+
this._onceDone = false;
|
|
62
|
+
this._onceOk = false;
|
|
63
|
+
this._onceValue = undefined;
|
|
64
|
+
this._onceError = undefined;
|
|
65
|
+
this._onceFutures.length = 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// T extends Option<infer U> ? U : T
|
|
69
|
+
once<R>(fn: (c: CTX) => R): R {
|
|
70
|
+
if (this._onceDone) {
|
|
71
|
+
if (this._onceError) {
|
|
72
|
+
if (this._isPromise) {
|
|
73
|
+
return Promise.reject(this._onceError) as unknown as R;
|
|
74
|
+
} else {
|
|
75
|
+
throw this._onceError;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (this._onceOk) {
|
|
79
|
+
if (this._isPromise) {
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
81
|
+
return Promise.resolve(this._onceValue!) as unknown as R;
|
|
82
|
+
} else {
|
|
83
|
+
return this._onceValue as unknown as R;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
throw new Error("ResolveOnce.once impossible");
|
|
87
|
+
}
|
|
88
|
+
const future = new Future<T>();
|
|
89
|
+
this._onceFutures.push(future);
|
|
90
|
+
if (this._onceFutures.length === 1) {
|
|
91
|
+
const okFn = (value: T): void => {
|
|
92
|
+
this._onceValue = value;
|
|
93
|
+
this._onceOk = true;
|
|
94
|
+
this._onceDone = true;
|
|
95
|
+
if (this._isPromise) {
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
97
|
+
this._onceFutures.forEach((f) => f.resolve(this._onceValue!));
|
|
98
|
+
}
|
|
99
|
+
this._onceFutures.length = 0;
|
|
100
|
+
};
|
|
101
|
+
const catchFn = (e: Error): void => {
|
|
102
|
+
this._onceError = e as Error;
|
|
103
|
+
this._onceOk = false;
|
|
104
|
+
this._onceValue = undefined;
|
|
105
|
+
this._onceDone = true;
|
|
106
|
+
if (this._isPromise) {
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
108
|
+
this._onceFutures.forEach((f) => f.reject(this._onceError!));
|
|
109
|
+
}
|
|
110
|
+
this._onceFutures.length = 0;
|
|
111
|
+
};
|
|
112
|
+
try {
|
|
113
|
+
const ret = fn(this.ctx);
|
|
114
|
+
if (typeof (ret as Promise<T>).then === "function") {
|
|
115
|
+
this._isPromise = true;
|
|
116
|
+
(ret as Promise<T>).then(okFn).catch(catchFn);
|
|
117
|
+
} else {
|
|
118
|
+
okFn(ret as unknown as T);
|
|
119
|
+
}
|
|
120
|
+
} catch (e) {
|
|
121
|
+
catchFn(e as Error);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (this._isPromise) {
|
|
125
|
+
return future.asPromise() as unknown as R;
|
|
126
|
+
} else {
|
|
127
|
+
// abit funky but i don't want to impl the return just once
|
|
128
|
+
return this.once(fn);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export class Keyed<T extends { reset: () => void }, K = string> {
|
|
134
|
+
private readonly _map = new Map<K, T>();
|
|
135
|
+
|
|
136
|
+
readonly factory: (key: K) => T;
|
|
137
|
+
constructor(factory: (key: K) => T) {
|
|
138
|
+
this.factory = factory;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async asyncGet(key: () => Promise<K>): Promise<T> {
|
|
142
|
+
return this.get(await key());
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
get(key: K | (() => K)): T {
|
|
146
|
+
if (typeof key === "function") {
|
|
147
|
+
key = (key as () => K)();
|
|
148
|
+
}
|
|
149
|
+
let keyed = this._map.get(key);
|
|
150
|
+
if (!keyed) {
|
|
151
|
+
keyed = this.factory(key);
|
|
152
|
+
this._map.set(key, keyed);
|
|
153
|
+
}
|
|
154
|
+
return keyed;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
unget(key: K): void {
|
|
158
|
+
const keyed = this._map.get(key);
|
|
159
|
+
keyed?.reset();
|
|
160
|
+
this._map.delete(key);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
reset(): void {
|
|
164
|
+
this._map.forEach((keyed) => keyed.reset());
|
|
165
|
+
this._map.clear();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export class KeyedResolvOnce<T, K = string> extends Keyed<ResolveOnce<T, K>, K> {
|
|
170
|
+
constructor() {
|
|
171
|
+
super((key) => new ResolveOnce<T, K>(key));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export class KeyedResolvSeq<T, K = string> extends Keyed<ResolveSeq<T, K>, K> {
|
|
176
|
+
constructor() {
|
|
177
|
+
super((key) => new ResolveSeq<T, K>(key));
|
|
178
|
+
}
|
|
179
|
+
}
|
package/src/result.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
export abstract class Result<T, E = Error> {
|
|
2
|
+
static Ok<T = void>(t: T): Result<T, Error> {
|
|
3
|
+
return new ResultOK(t);
|
|
4
|
+
}
|
|
5
|
+
static Err<T, E extends Error = Error>(t: E | string): Result<T, E> {
|
|
6
|
+
if (typeof t === "string") {
|
|
7
|
+
return new ResultError(new Error(t) as E);
|
|
8
|
+
}
|
|
9
|
+
return new ResultError(t);
|
|
10
|
+
}
|
|
11
|
+
static Is<T>(t: unknown): t is Result<T> {
|
|
12
|
+
if (!t) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
if (t instanceof Result) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
const rt = t as Result<T>;
|
|
19
|
+
if ([typeof rt.is_ok, typeof rt.is_err, typeof rt.unwrap, typeof rt.unwrap_err].every((x) => x === "function")) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
isOk(): boolean {
|
|
26
|
+
return this.is_ok();
|
|
27
|
+
}
|
|
28
|
+
isErr(): boolean {
|
|
29
|
+
return this.is_err();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
Ok(): T {
|
|
33
|
+
return this.unwrap();
|
|
34
|
+
}
|
|
35
|
+
Err(): E {
|
|
36
|
+
return this.unwrap_err();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
abstract is_ok(): boolean;
|
|
40
|
+
abstract is_err(): boolean;
|
|
41
|
+
abstract unwrap(): T;
|
|
42
|
+
abstract unwrap_err(): E;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export class ResultOK<T> extends Result<T, Error> {
|
|
46
|
+
private _t: T;
|
|
47
|
+
constructor(t: T) {
|
|
48
|
+
super();
|
|
49
|
+
this._t = t;
|
|
50
|
+
}
|
|
51
|
+
is_ok(): boolean {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
is_err(): boolean {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
unwrap_err(): Error {
|
|
58
|
+
throw new Error("Result is Ok");
|
|
59
|
+
}
|
|
60
|
+
unwrap(): T {
|
|
61
|
+
return this._t;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export class ResultError<T extends Error> extends Result<never, T> {
|
|
66
|
+
private _error: T;
|
|
67
|
+
constructor(t: T) {
|
|
68
|
+
super();
|
|
69
|
+
this._error = t;
|
|
70
|
+
}
|
|
71
|
+
is_ok(): boolean {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
is_err(): boolean {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
unwrap(): never {
|
|
78
|
+
throw new Error(`Result is Err: ${this._error}`);
|
|
79
|
+
}
|
|
80
|
+
unwrap_err(): T {
|
|
81
|
+
return this._error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export type WithoutResult<T> = T extends Result<infer U> ? U : T;
|
|
86
|
+
|
|
87
|
+
// type WithoutPromise<T> = T extends Promise<infer U> ? U : T;
|
|
88
|
+
type WithResult<T> = T extends Promise<infer U> ? Promise<Result<U>> : Result<T>;
|
|
89
|
+
|
|
90
|
+
export function exception2Result<FN extends () => Promise<T> | T, T>(fn: FN): WithResult<ReturnType<FN>> {
|
|
91
|
+
try {
|
|
92
|
+
const res = fn();
|
|
93
|
+
if (res instanceof Promise) {
|
|
94
|
+
return res.then((value) => Result.Ok(value)).catch((e) => Result.Err(e)) as WithResult<ReturnType<FN>>;
|
|
95
|
+
}
|
|
96
|
+
return Result.Ok(res) as WithResult<ReturnType<FN>>;
|
|
97
|
+
} catch (e) {
|
|
98
|
+
return Result.Err(e as Error) as WithResult<ReturnType<FN>>;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/*
|
|
103
|
+
|
|
104
|
+
type FinalizedResult<T> = {
|
|
105
|
+
result: T;
|
|
106
|
+
scopeResult?: Result<void>;
|
|
107
|
+
finally: () => Promise<void>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
type exection2ResultParam<T> = {
|
|
111
|
+
init: () => Promise<T>;
|
|
112
|
+
inScope?: (t: T) => Promise<void>;
|
|
113
|
+
cleanup: (t: T) => Promise<void>;
|
|
114
|
+
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function expection2Result<T>({fn, inScope, cleanup}: exection2ResultParam<T>): Promise<Result<FinalizedResult<T>>> {
|
|
118
|
+
try {
|
|
119
|
+
const res = await fn();
|
|
120
|
+
if (inScope) {
|
|
121
|
+
try {
|
|
122
|
+
await inScope?.(res)
|
|
123
|
+
} catch (err) {
|
|
124
|
+
return Result.Err(err as Error)
|
|
125
|
+
}
|
|
126
|
+
await cleanup(res)
|
|
127
|
+
return Result.Ok({
|
|
128
|
+
result: res,
|
|
129
|
+
finally: async () => { }
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
return Result.Ok({
|
|
133
|
+
result: res ,
|
|
134
|
+
finally: async () => {
|
|
135
|
+
return cleanup(res)
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
} catch (err) {
|
|
139
|
+
return Result.Err(err as Error)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
*/
|
|
143
|
+
|
|
144
|
+
// await expection2Result({
|
|
145
|
+
// init: openDB,
|
|
146
|
+
// inScope: (res) => {
|
|
147
|
+
// res.query()
|
|
148
|
+
// },
|
|
149
|
+
// cleanup: async (y) => {
|
|
150
|
+
// await y.close()
|
|
151
|
+
// }
|
|
152
|
+
// })
|
|
153
|
+
// async function openDB() {
|
|
154
|
+
// try {
|
|
155
|
+
// const opendb = await openDB()
|
|
156
|
+
// return Result.Ok({
|
|
157
|
+
// openDB,
|
|
158
|
+
// finally: async () => {
|
|
159
|
+
// await opendb.close()
|
|
160
|
+
// }})
|
|
161
|
+
// } catch (err) {
|
|
162
|
+
// return Result.Err(err)
|
|
163
|
+
// }
|
|
164
|
+
// }
|
|
165
|
+
// }
|
package/src/runtime.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface Runtime {
|
|
2
|
+
isNodeIsh: boolean;
|
|
3
|
+
isBrowser: boolean;
|
|
4
|
+
isDeno: boolean;
|
|
5
|
+
isReactNative: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
function isSet(value: string, ref: any = globalThis): boolean {
|
|
10
|
+
const [head, ...tail] = value.split(".");
|
|
11
|
+
if (["object", "function"].includes(typeof ref) && ref && ["object", "function"].includes(typeof ref[head]) && ref[head]) {
|
|
12
|
+
if (tail.length <= 1) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
return isSet(tail.join("."), ref[head]);
|
|
16
|
+
}
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function runtimeFn(): Runtime {
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
+
const gt: any = globalThis;
|
|
23
|
+
const isReactNative =
|
|
24
|
+
isSet("navigator.product") && typeof gt["navigator"] === "object" && gt["navigator"]["product"] === "ReactNative";
|
|
25
|
+
let isNodeIsh = false;
|
|
26
|
+
if (!isSet("Deno")) {
|
|
27
|
+
isNodeIsh = isSet("process.versions.node") && !isReactNative;
|
|
28
|
+
}
|
|
29
|
+
const isDeno = isSet("Deno");
|
|
30
|
+
return {
|
|
31
|
+
isNodeIsh,
|
|
32
|
+
isBrowser: !(isNodeIsh || isDeno) && !isReactNative,
|
|
33
|
+
isDeno,
|
|
34
|
+
isReactNative,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { FileService } from "./file-service.js";
|
|
2
|
+
import { Env } from "./sys-env.js";
|
|
3
|
+
import { Time } from "./time.js";
|
|
4
|
+
|
|
5
|
+
export enum TimeMode {
|
|
6
|
+
REAL = "real",
|
|
7
|
+
CONST = "const",
|
|
8
|
+
STEP = "step",
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export enum RandomMode {
|
|
12
|
+
CONST = "const",
|
|
13
|
+
STEP = "step",
|
|
14
|
+
RANDOM = "random",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export enum IDMode {
|
|
18
|
+
UUID = "uuid",
|
|
19
|
+
CONST = "const",
|
|
20
|
+
STEP = "step",
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function String2TimeMode(s?: string): TimeMode {
|
|
24
|
+
switch (s?.toLowerCase()) {
|
|
25
|
+
case "real":
|
|
26
|
+
return TimeMode.REAL;
|
|
27
|
+
case "const":
|
|
28
|
+
return TimeMode.CONST;
|
|
29
|
+
case "step":
|
|
30
|
+
return TimeMode.STEP;
|
|
31
|
+
default:
|
|
32
|
+
return TimeMode.REAL;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type VoidFunc = () => void | Promise<void>;
|
|
37
|
+
|
|
38
|
+
export interface SystemService {
|
|
39
|
+
Env(): Env;
|
|
40
|
+
Args(): string[];
|
|
41
|
+
OnExit(hdl: VoidFunc): VoidFunc;
|
|
42
|
+
Exit(code: number): void;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface SysAbstraction {
|
|
46
|
+
Time(): Time;
|
|
47
|
+
Stdout(): WritableStream<Uint8Array>;
|
|
48
|
+
Stderr(): WritableStream<Uint8Array>;
|
|
49
|
+
NextId(): string;
|
|
50
|
+
Random0ToValue(value: number): number;
|
|
51
|
+
System(): SystemService;
|
|
52
|
+
FileSystem(): FileService;
|
|
53
|
+
}
|
package/src/sys-env.ts
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { ResolveOnce } from "./resolve-once.js";
|
|
2
|
+
|
|
3
|
+
export interface EnvMap {
|
|
4
|
+
get(key: string): string | undefined;
|
|
5
|
+
set(key: string, value?: string): void;
|
|
6
|
+
delete(key: string): void;
|
|
7
|
+
keys(): string[];
|
|
8
|
+
}
|
|
9
|
+
export interface EnvActions extends EnvMap {
|
|
10
|
+
active(): boolean;
|
|
11
|
+
register(env: Env): Env;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
class NodeEnvActions implements EnvActions {
|
|
15
|
+
readonly #node = globalThis as unknown as { process: { env: Record<string, string> } };
|
|
16
|
+
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-useless-constructor, @typescript-eslint/no-unused-vars
|
|
18
|
+
constructor(opts: Partial<EnvFactoryOpts>) {
|
|
19
|
+
// do nothing
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
register(env: Env): Env {
|
|
23
|
+
return env;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
active(): boolean {
|
|
27
|
+
return typeof this.#node === "object" && typeof this.#node.process === "object" && typeof this.#node.process.env === "object";
|
|
28
|
+
}
|
|
29
|
+
readonly _env = this.active() ? this.#node.process.env : {};
|
|
30
|
+
keys(): string[] {
|
|
31
|
+
return Object.keys(this._env);
|
|
32
|
+
}
|
|
33
|
+
get(key: string): string | undefined {
|
|
34
|
+
return this._env[key];
|
|
35
|
+
}
|
|
36
|
+
set(key: string, value?: string): void {
|
|
37
|
+
if (value) {
|
|
38
|
+
this._env[key] = value;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
delete(key: string): void {
|
|
42
|
+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
43
|
+
delete this._env[key];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
class DenoEnvActions implements EnvActions {
|
|
48
|
+
readonly #deno = globalThis as unknown as { Deno: { env: Map<string, string> } };
|
|
49
|
+
|
|
50
|
+
get _env(): Map<string, string> {
|
|
51
|
+
return this.#deno.Deno.env;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-useless-constructor, @typescript-eslint/no-unused-vars
|
|
55
|
+
constructor(opts: Partial<EnvFactoryOpts>) {
|
|
56
|
+
// do nothing
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
register(env: Env): Env {
|
|
60
|
+
return env;
|
|
61
|
+
}
|
|
62
|
+
active(): boolean {
|
|
63
|
+
return typeof this.#deno === "object" && typeof this.#deno.Deno === "object" && typeof this.#deno.Deno.env === "object";
|
|
64
|
+
}
|
|
65
|
+
keys(): string[] {
|
|
66
|
+
return Array.from(this._env.keys());
|
|
67
|
+
}
|
|
68
|
+
get(key: string): string | undefined {
|
|
69
|
+
return this._env.get(key);
|
|
70
|
+
}
|
|
71
|
+
set(key: string, value?: string): void {
|
|
72
|
+
if (value) {
|
|
73
|
+
this._env.set(key, value);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
delete(key: string): void {
|
|
77
|
+
this._env.delete(key);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export class BrowserEnvActions implements EnvActions {
|
|
82
|
+
readonly env: Map<string, string> = new Map<string, string>();
|
|
83
|
+
readonly opts: Partial<EnvFactoryOpts>;
|
|
84
|
+
constructor(opts: Partial<EnvFactoryOpts>) {
|
|
85
|
+
this.opts = opts;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
get(key: string): string | undefined {
|
|
89
|
+
return this.env.get(key);
|
|
90
|
+
}
|
|
91
|
+
set(key: string, value?: string): void {
|
|
92
|
+
if (value) {
|
|
93
|
+
this.env.set(key, value);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
delete(key: string): void {
|
|
97
|
+
this.env.delete(key);
|
|
98
|
+
}
|
|
99
|
+
keys(): string[] {
|
|
100
|
+
return Array.from(this.env.keys());
|
|
101
|
+
}
|
|
102
|
+
active(): boolean {
|
|
103
|
+
return true; // that should work on every runtime
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
register(env: Env): Env {
|
|
107
|
+
const sym = Symbol.for(this.opts.symbol || "CP_ENV");
|
|
108
|
+
const browser = globalThis as unknown as Record<symbol, Env>;
|
|
109
|
+
browser[sym] = env;
|
|
110
|
+
return env;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface EnvFactoryOpts {
|
|
115
|
+
readonly symbol: string; // default "CP_ENV" used by BrowserEnvActions
|
|
116
|
+
readonly presetEnv: Map<string, string>;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
type OnSetFn = (key: string, value?: string) => void;
|
|
120
|
+
export interface OnSetItem {
|
|
121
|
+
readonly filter: Set<string>;
|
|
122
|
+
readonly fn: OnSetFn;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface Env extends EnvMap {
|
|
126
|
+
onSet(fn: OnSetFn, ...filter: string[]): void;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const _envFactory = new ResolveOnce<Env>();
|
|
130
|
+
export function envFactory(opts: Partial<EnvFactoryOpts> = {}): Env {
|
|
131
|
+
return _envFactory.once(() => {
|
|
132
|
+
const found = [new NodeEnvActions(opts), new DenoEnvActions(opts), new BrowserEnvActions(opts)].find((env) => env.active());
|
|
133
|
+
if (!found) {
|
|
134
|
+
throw new Error("SysContainer:envFactory: no env available");
|
|
135
|
+
}
|
|
136
|
+
const ret = new EnvImpl(found, opts);
|
|
137
|
+
found.register(ret);
|
|
138
|
+
return ret;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export class EnvImpl implements Env {
|
|
143
|
+
readonly _map: EnvMap;
|
|
144
|
+
constructor(map: EnvMap, opts: Partial<EnvFactoryOpts> = {}) {
|
|
145
|
+
this._map = map;
|
|
146
|
+
this._updatePresets(opts.presetEnv);
|
|
147
|
+
}
|
|
148
|
+
_updatePresets(presetEnv?: Map<string, string>): void {
|
|
149
|
+
if (!presetEnv) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
for (const [key, value] of presetEnv) {
|
|
153
|
+
this._map.set(key, value);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
_applyOnSet(onSet: OnSetItem[], key?: string, value?: string): void {
|
|
157
|
+
onSet.forEach((item) => {
|
|
158
|
+
let keys: string[] = [];
|
|
159
|
+
if (key) {
|
|
160
|
+
keys = [key];
|
|
161
|
+
} else {
|
|
162
|
+
keys = this._map.keys();
|
|
163
|
+
}
|
|
164
|
+
keys
|
|
165
|
+
.filter((k) => {
|
|
166
|
+
if (item.filter.size === 0) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
if (item.filter.has(k)) {
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
return false;
|
|
173
|
+
})
|
|
174
|
+
.forEach((k) => {
|
|
175
|
+
let v;
|
|
176
|
+
if (!key && !value) {
|
|
177
|
+
// init
|
|
178
|
+
v = this._map.get(k);
|
|
179
|
+
} else if (key && !value) {
|
|
180
|
+
// del
|
|
181
|
+
v = undefined;
|
|
182
|
+
} else {
|
|
183
|
+
// set
|
|
184
|
+
v = value;
|
|
185
|
+
}
|
|
186
|
+
item.fn(k, v);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
readonly _onSet: OnSetItem[] = [];
|
|
191
|
+
keys(): string[] {
|
|
192
|
+
return this._map.keys();
|
|
193
|
+
}
|
|
194
|
+
// filter is not set all sets passed
|
|
195
|
+
onSet(fn: OnSetFn, ...filter: string[]): void {
|
|
196
|
+
const item: OnSetItem = { filter: new Set(filter), fn };
|
|
197
|
+
this._onSet.push(item);
|
|
198
|
+
this._applyOnSet([item]);
|
|
199
|
+
}
|
|
200
|
+
get(key: string): string | undefined {
|
|
201
|
+
return this._map.get(key);
|
|
202
|
+
}
|
|
203
|
+
set(key: string, value?: string): void {
|
|
204
|
+
if (!value) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
this._map.set(key, value);
|
|
208
|
+
this._applyOnSet(this._onSet, key, value);
|
|
209
|
+
}
|
|
210
|
+
delete(key: string): void {
|
|
211
|
+
this._map.delete(key);
|
|
212
|
+
this._applyOnSet(this._onSet, key);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// export const envImpl = new EnvImpl();
|