@adviser/cement 0.2.28 → 0.2.30
Sign up to get free protection for your applications and to get access to all the features.
- 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,95 @@
|
|
1
|
+
import { FanoutWriteStream } from "../utils/fanout-write-stream.js";
|
2
|
+
import { Future } from "../future.js";
|
3
|
+
import { TxtEnDecoder, Utf8EnDecoderSingleton } from "../txt-en-decoder.js";
|
4
|
+
|
5
|
+
export class LogWriteStream implements WritableStreamDefaultWriter<Uint8Array> {
|
6
|
+
private readonly _bufferArr: Uint8Array[];
|
7
|
+
|
8
|
+
constructor(bufferArr: Uint8Array[]) {
|
9
|
+
this._bufferArr = bufferArr;
|
10
|
+
}
|
11
|
+
|
12
|
+
readonly _resolveClosed: Future<undefined> = new Future<undefined>();
|
13
|
+
readonly closed: Promise<undefined> = this._resolveClosed.asPromise();
|
14
|
+
readonly desiredSize: number | null = null;
|
15
|
+
readonly ready: Promise<undefined> = Promise.resolve(undefined);
|
16
|
+
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
|
18
|
+
abort(reason?: any): Promise<void> {
|
19
|
+
throw new Error("Method not implemented.");
|
20
|
+
}
|
21
|
+
async close(): Promise<void> {
|
22
|
+
await this.closed;
|
23
|
+
return Promise.resolve(undefined);
|
24
|
+
}
|
25
|
+
releaseLock(): void {
|
26
|
+
// do nothing
|
27
|
+
}
|
28
|
+
async write(chunk?: Uint8Array): Promise<void> {
|
29
|
+
if (chunk) {
|
30
|
+
this._bufferArr.push(chunk);
|
31
|
+
}
|
32
|
+
return Promise.resolve(undefined);
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
export class LogCollector implements WritableStream<Uint8Array> {
|
37
|
+
readonly locked: boolean = false;
|
38
|
+
private _writer?: FanoutWriteStream;
|
39
|
+
private readonly _pass?: WritableStreamDefaultWriter<Uint8Array>;
|
40
|
+
private readonly _bufferArr: Uint8Array[] = [];
|
41
|
+
private readonly _txtEnDe: TxtEnDecoder;
|
42
|
+
|
43
|
+
constructor(pass?: WritableStreamDefaultWriter<Uint8Array>, txtEnDe?: TxtEnDecoder) {
|
44
|
+
this._pass = pass;
|
45
|
+
this._txtEnDe = txtEnDe || Utf8EnDecoderSingleton();
|
46
|
+
}
|
47
|
+
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
49
|
+
abort(reason?: Uint8Array): Promise<void> {
|
50
|
+
throw new Error("Method not implemented.");
|
51
|
+
}
|
52
|
+
|
53
|
+
async close(): Promise<void> {
|
54
|
+
if (this._writer) {
|
55
|
+
const ret = await this._writer.close();
|
56
|
+
this._writer = undefined;
|
57
|
+
return ret;
|
58
|
+
}
|
59
|
+
return Promise.resolve(undefined);
|
60
|
+
}
|
61
|
+
|
62
|
+
getWriter(): WritableStreamDefaultWriter<Uint8Array> {
|
63
|
+
if (!this._writer) {
|
64
|
+
const dests: WritableStreamDefaultWriter[] = [new LogWriteStream(this._bufferArr)];
|
65
|
+
if (this._pass) {
|
66
|
+
dests.push(this._pass);
|
67
|
+
}
|
68
|
+
this._writer = new FanoutWriteStream(dests);
|
69
|
+
}
|
70
|
+
return this._writer;
|
71
|
+
}
|
72
|
+
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
74
|
+
Logs(notJsonLine = false): any[] {
|
75
|
+
if (!this._writer) {
|
76
|
+
return [];
|
77
|
+
}
|
78
|
+
const jsonNlStr = this._txtEnDe.decode(
|
79
|
+
new Uint8Array(
|
80
|
+
(function* (res: Uint8Array[]): Generator<number, void, undefined> {
|
81
|
+
for (const x of res) {
|
82
|
+
yield* x;
|
83
|
+
}
|
84
|
+
})(this._bufferArr),
|
85
|
+
),
|
86
|
+
);
|
87
|
+
if (!notJsonLine) {
|
88
|
+
const splitStr = jsonNlStr.split("\n");
|
89
|
+
const filterStr = splitStr.filter((a) => a.length);
|
90
|
+
const mapStr = filterStr.map((a) => JSON.parse(a));
|
91
|
+
return mapStr;
|
92
|
+
}
|
93
|
+
return jsonNlStr.split("\n").filter((a) => a.length);
|
94
|
+
}
|
95
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import { LevelHandlerImpl } from "../log-level-impl.js";
|
2
|
+
import { Logger } from "../logger.js";
|
3
|
+
import { LoggerImpl } from "../logger-impl.js";
|
4
|
+
import { SysAbstraction } from "../sys-abstraction.js";
|
5
|
+
import { LogCollector } from "./log-write-stream.js";
|
6
|
+
|
7
|
+
export interface MockLoggerReturn {
|
8
|
+
readonly logger: Logger;
|
9
|
+
readonly logCollector: LogCollector;
|
10
|
+
}
|
11
|
+
|
12
|
+
export function MockLogger(params?: {
|
13
|
+
readonly sys?: SysAbstraction;
|
14
|
+
readonly pass?: WritableStreamDefaultWriter<Uint8Array>;
|
15
|
+
moduleName?: string | string[];
|
16
|
+
readonly disableDebug?: boolean;
|
17
|
+
}): MockLoggerReturn {
|
18
|
+
const lc = new LogCollector(params?.pass);
|
19
|
+
let modNames = ["MockLogger"];
|
20
|
+
if (typeof params?.moduleName === "string") {
|
21
|
+
modNames = [params?.moduleName];
|
22
|
+
} else if (Array.isArray(params?.moduleName)) {
|
23
|
+
modNames = [...params.moduleName, ...modNames];
|
24
|
+
}
|
25
|
+
const logger = new LoggerImpl({
|
26
|
+
out: lc,
|
27
|
+
sys: params?.sys,
|
28
|
+
levelHandler: new LevelHandlerImpl(),
|
29
|
+
})
|
30
|
+
.With()
|
31
|
+
.Module(modNames[0])
|
32
|
+
.Logger();
|
33
|
+
if (!params?.disableDebug) {
|
34
|
+
logger.SetDebug(...modNames);
|
35
|
+
}
|
36
|
+
return {
|
37
|
+
logCollector: lc,
|
38
|
+
logger,
|
39
|
+
};
|
40
|
+
}
|
package/src/time.ts
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
export abstract class Time {
|
2
|
+
abstract Now(add?: number): Date;
|
3
|
+
abstract Sleep(duration: Duration): Promise<void>;
|
4
|
+
TimeSince(start: Date): Duration {
|
5
|
+
const now = this.Now();
|
6
|
+
return now.getTime() - start.getTime();
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
export type Duration = number;
|
11
|
+
|
12
|
+
export enum TimeUnits {
|
13
|
+
Microsecond = 1,
|
14
|
+
// eslint-disable-next-line @typescript-eslint/prefer-literal-enum-member
|
15
|
+
Second = 1000 * Microsecond,
|
16
|
+
// eslint-disable-next-line @typescript-eslint/prefer-literal-enum-member
|
17
|
+
Minute = 60 * Second,
|
18
|
+
// eslint-disable-next-line @typescript-eslint/prefer-literal-enum-member
|
19
|
+
Hour = 60 * Minute,
|
20
|
+
}
|
package/src/tracer.ts
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
import type { MarkWritable } from "ts-essentials";
|
2
|
+
import { Time } from "./time.js";
|
3
|
+
import { Logger } from "./logger.js";
|
4
|
+
|
5
|
+
export type TraceCtx = {
|
6
|
+
readonly spanId: string;
|
7
|
+
readonly time: Time;
|
8
|
+
readonly parent: TraceNode;
|
9
|
+
readonly metrics: Map<string, Metric<unknown>>;
|
10
|
+
readonly logger?: Logger;
|
11
|
+
} & Record<string, unknown>;
|
12
|
+
|
13
|
+
export type CleanCtx = {
|
14
|
+
readonly spanId: string;
|
15
|
+
} & Record<string, unknown>;
|
16
|
+
|
17
|
+
export type TraceCtxParam = {
|
18
|
+
readonly spanId: string;
|
19
|
+
} & Partial<{
|
20
|
+
readonly time: Time;
|
21
|
+
readonly parent: TraceNode;
|
22
|
+
readonly logger: Logger;
|
23
|
+
}> &
|
24
|
+
Record<string, unknown>;
|
25
|
+
|
26
|
+
export class Metric<T> {
|
27
|
+
value?: T;
|
28
|
+
readonly path: string;
|
29
|
+
|
30
|
+
constructor(path: string) {
|
31
|
+
this.path = path;
|
32
|
+
}
|
33
|
+
|
34
|
+
set(value: T): void {
|
35
|
+
this.value = value;
|
36
|
+
}
|
37
|
+
|
38
|
+
add<R extends number | ArrayLike<T>>(value: R): void {
|
39
|
+
if (typeof value === "number") {
|
40
|
+
if (this.value === undefined) {
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
42
|
+
this.value = 0 as any;
|
43
|
+
}
|
44
|
+
(this.value as number) = ((this.value as number) + value) as number;
|
45
|
+
} else if (Array.isArray(value)) {
|
46
|
+
if (!Array.isArray(this.value)) {
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
48
|
+
this.value = [] as any;
|
49
|
+
}
|
50
|
+
(this.value as T[]).push(...value);
|
51
|
+
} else {
|
52
|
+
throw new Error("add only support number or array");
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
export type MetricMap = Map<string, Metric<unknown>>;
|
58
|
+
|
59
|
+
export class Metrics {
|
60
|
+
readonly tracenode: TraceNode;
|
61
|
+
private readonly map: MetricMap;
|
62
|
+
|
63
|
+
readonly spanRefs: MetricMap = new Map<string, Metric<unknown>>();
|
64
|
+
constructor(tracenode: TraceNode) {
|
65
|
+
this.tracenode = tracenode;
|
66
|
+
this.map = tracenode.ctx.metrics;
|
67
|
+
}
|
68
|
+
|
69
|
+
toJSON(): Record<string, unknown> {
|
70
|
+
const obj: Record<string, unknown> = {};
|
71
|
+
for (const [key, value] of this.map) {
|
72
|
+
obj[key] = value.value;
|
73
|
+
}
|
74
|
+
return obj;
|
75
|
+
}
|
76
|
+
|
77
|
+
get<T>(ipath: string): Metric<T> {
|
78
|
+
const path = ipath.replace(/[/]+/g, "/").trim();
|
79
|
+
if (path.startsWith("/")) {
|
80
|
+
if (path.slice(1).length === 0) {
|
81
|
+
throw new Error(`Metrics path must contain value /:${path}`);
|
82
|
+
}
|
83
|
+
let metric = this.map.get(path);
|
84
|
+
if (!metric) {
|
85
|
+
metric = new Metric<T>(path);
|
86
|
+
this.map.set(path, metric);
|
87
|
+
}
|
88
|
+
this.spanRefs.set(path, metric);
|
89
|
+
return metric as Metric<T>;
|
90
|
+
} else if (path.includes("/")) {
|
91
|
+
throw new Error(`Metrics path must start with /:${path}`);
|
92
|
+
}
|
93
|
+
const rootPath = this.tracenode.getRootPath();
|
94
|
+
return this.get(`${rootPath}/${path}`);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
export interface Invokaction {
|
99
|
+
readonly result: "success" | "error";
|
100
|
+
readonly start: number;
|
101
|
+
readonly end: number;
|
102
|
+
readonly metrics?: Metrics;
|
103
|
+
}
|
104
|
+
|
105
|
+
export type TraceNodeMap = Map<string, TraceNode>;
|
106
|
+
|
107
|
+
export class TraceNode {
|
108
|
+
readonly childs: TraceNodeMap = new Map<string, TraceNode>();
|
109
|
+
|
110
|
+
readonly invokations: Invokaction[] = [];
|
111
|
+
|
112
|
+
readonly spanId: string;
|
113
|
+
readonly ctx: TraceCtx;
|
114
|
+
readonly metrics: Metrics;
|
115
|
+
|
116
|
+
static root(time: Time, logger?: Logger): TraceNode {
|
117
|
+
return new TraceNode({
|
118
|
+
spanId: "root",
|
119
|
+
time,
|
120
|
+
logger,
|
121
|
+
metrics: new Map(),
|
122
|
+
parent: undefined as unknown as TraceNode,
|
123
|
+
});
|
124
|
+
}
|
125
|
+
|
126
|
+
constructor(ctx: TraceCtx) {
|
127
|
+
this.spanId = ctx.spanId;
|
128
|
+
this.ctx = ctx;
|
129
|
+
this.metrics = new Metrics(this);
|
130
|
+
}
|
131
|
+
|
132
|
+
getRootPath(rpath: string[] = []): string {
|
133
|
+
if (!this.ctx.parent) {
|
134
|
+
return "/" + rpath.reverse().join("/");
|
135
|
+
}
|
136
|
+
return this.ctx.parent.getRootPath(rpath.concat(this.ctx.spanId));
|
137
|
+
}
|
138
|
+
|
139
|
+
invokes(): { ctx: CleanCtx; invokations: Invokaction[] } {
|
140
|
+
const cleanCtx = { ...this.ctx } as CleanCtx;
|
141
|
+
delete cleanCtx.parent;
|
142
|
+
delete cleanCtx.time;
|
143
|
+
delete cleanCtx.logger;
|
144
|
+
delete cleanCtx.metrics;
|
145
|
+
const spanRefs = this.metrics.toJSON.call({ map: this.metrics.spanRefs });
|
146
|
+
const metricsRefs = Object.keys(spanRefs).length > 0 ? { metricRefs: spanRefs } : {};
|
147
|
+
return {
|
148
|
+
ctx: cleanCtx as CleanCtx,
|
149
|
+
invokations: this.invokations,
|
150
|
+
...metricsRefs,
|
151
|
+
};
|
152
|
+
}
|
153
|
+
|
154
|
+
ctxWith(spanId: string, logger?: Logger): TraceCtxParam {
|
155
|
+
const ctx = {
|
156
|
+
...this.ctx,
|
157
|
+
spanId,
|
158
|
+
};
|
159
|
+
if (logger) {
|
160
|
+
ctx.logger = logger;
|
161
|
+
}
|
162
|
+
return ctx;
|
163
|
+
}
|
164
|
+
|
165
|
+
// <V extends () => Promise<T> | T, T>(id: string, fn: V): ReturnType<V>
|
166
|
+
span<V extends (trace: TraceNode) => Promise<T> | T, T>(inSpanId: string | TraceCtxParam, fn: V): ReturnType<V> {
|
167
|
+
let ctx: TraceCtx;
|
168
|
+
if (typeof inSpanId === "string") {
|
169
|
+
ctx = {
|
170
|
+
...this.ctx,
|
171
|
+
spanId: inSpanId,
|
172
|
+
parent: this,
|
173
|
+
};
|
174
|
+
} else {
|
175
|
+
ctx = {
|
176
|
+
...this.ctx,
|
177
|
+
...inSpanId,
|
178
|
+
parent: this,
|
179
|
+
};
|
180
|
+
}
|
181
|
+
if (ctx.logger) {
|
182
|
+
ctx = {
|
183
|
+
...ctx,
|
184
|
+
...ctx.logger.Attributes(),
|
185
|
+
};
|
186
|
+
}
|
187
|
+
const spanId = ctx.spanId;
|
188
|
+
let spanTrace = this.childs.get(spanId);
|
189
|
+
if (!spanTrace) {
|
190
|
+
spanTrace = new TraceNode(ctx);
|
191
|
+
this.childs.set(spanId.toString(), spanTrace);
|
192
|
+
}
|
193
|
+
const invokation: MarkWritable<MarkWritable<Invokaction, "end">, "result"> = {
|
194
|
+
start: this.ctx.time.Now().getTime(),
|
195
|
+
end: 0,
|
196
|
+
result: "success",
|
197
|
+
};
|
198
|
+
spanTrace.invokations.push(invokation);
|
199
|
+
try {
|
200
|
+
const possiblePromise = fn(spanTrace);
|
201
|
+
if (possiblePromise instanceof Promise) {
|
202
|
+
return possiblePromise
|
203
|
+
.then((v) => {
|
204
|
+
return v;
|
205
|
+
})
|
206
|
+
.catch((e) => {
|
207
|
+
invokation.result = "error";
|
208
|
+
throw e;
|
209
|
+
})
|
210
|
+
.finally(() => {
|
211
|
+
invokation.end = this.ctx.time.Now().getTime();
|
212
|
+
}) as ReturnType<V>;
|
213
|
+
}
|
214
|
+
invokation.end = this.ctx.time.Now().getTime();
|
215
|
+
return possiblePromise as ReturnType<V>;
|
216
|
+
} catch (e) {
|
217
|
+
invokation.result = "error";
|
218
|
+
invokation.end = this.ctx.time.Now().getTime();
|
219
|
+
throw e;
|
220
|
+
}
|
221
|
+
}
|
222
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
export interface TxtEnDecoder {
|
2
|
+
encode(str: string): Uint8Array;
|
3
|
+
decode(data: Uint8Array): string;
|
4
|
+
}
|
5
|
+
|
6
|
+
const encoder = new TextEncoder();
|
7
|
+
const decoder = new TextDecoder();
|
8
|
+
|
9
|
+
export class Utf8EnDecoder implements TxtEnDecoder {
|
10
|
+
encode(str: string): Uint8Array {
|
11
|
+
return encoder.encode(str);
|
12
|
+
}
|
13
|
+
decode(data: Uint8Array): string {
|
14
|
+
return decoder.decode(data);
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
const utf8EnDecoder = new Utf8EnDecoder();
|
19
|
+
export function Utf8EnDecoderSingleton(): TxtEnDecoder {
|
20
|
+
return utf8EnDecoder;
|
21
|
+
}
|