@code-pushup/utils 0.115.0 → 0.116.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/package.json +2 -2
- package/src/lib/create-runner-files.js +2 -4
- package/src/lib/create-runner-files.js.map +1 -1
- package/src/lib/errors.d.ts +11 -0
- package/src/lib/errors.js +14 -0
- package/src/lib/errors.js.map +1 -1
- package/src/lib/profiler/constants.d.ts +5 -0
- package/src/lib/profiler/constants.js +5 -0
- package/src/lib/profiler/constants.js.map +1 -1
- package/src/lib/profiler/profiler-node.d.ts +2 -1
- package/src/lib/profiler/profiler-node.js +5 -2
- package/src/lib/profiler/profiler-node.js.map +1 -1
- package/src/lib/wal-sharded.d.ts +186 -0
- package/src/lib/wal-sharded.js +354 -0
- package/src/lib/wal-sharded.js.map +1 -0
- package/src/lib/wal.d.ts +8 -82
- package/src/lib/wal.js +4 -184
- package/src/lib/wal.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-pushup/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.116.0",
|
|
4
4
|
"description": "Low-level utilities (helper functions, etc.) used by Code PushUp CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/code-pushup/cli/tree/main/packages/utils#readme",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"node": ">=18.2.0"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@code-pushup/models": "0.
|
|
30
|
+
"@code-pushup/models": "0.116.0",
|
|
31
31
|
"ansis": "^3.3.0",
|
|
32
32
|
"build-md": "^0.4.2",
|
|
33
33
|
"bundle-require": "^5.1.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { writeFile } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { threadId } from 'node:worker_threads';
|
|
4
3
|
import { ensureDirectoryExists, pluginWorkDir } from './file-system.js';
|
|
4
|
+
import { getUniqueProcessThreadId } from './process-id.js';
|
|
5
5
|
/**
|
|
6
6
|
* Function to create timestamp nested plugin runner files for config and output.
|
|
7
7
|
*
|
|
@@ -9,9 +9,7 @@ import { ensureDirectoryExists, pluginWorkDir } from './file-system.js';
|
|
|
9
9
|
* @param configJSON - config of the plugin runner as JSON.
|
|
10
10
|
*/
|
|
11
11
|
export async function createRunnerFiles(pluginSlug, configJSON) {
|
|
12
|
-
|
|
13
|
-
// This prevents race conditions when running the same plugin for multiple projects in parallel
|
|
14
|
-
const uniqueId = `${(performance.timeOrigin + performance.now()) * 10}-${process.pid}-${threadId}`;
|
|
12
|
+
const uniqueId = getUniqueProcessThreadId();
|
|
15
13
|
const runnerWorkDir = path.join(pluginWorkDir(pluginSlug), uniqueId);
|
|
16
14
|
const runnerConfigPath = path.join(runnerWorkDir, 'plugin-config.json');
|
|
17
15
|
const runnerOutputPath = path.join(runnerWorkDir, 'runner-output.json');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-runner-files.js","sourceRoot":"","sources":["../../../src/lib/create-runner-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"create-runner-files.js","sourceRoot":"","sources":["../../../src/lib/create-runner-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,UAAkB,EAClB,UAAkB;IAElB,MAAM,QAAQ,GAAG,wBAAwB,EAAE,CAAC;IAC5C,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAC;IACrE,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAC;IACxE,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAC;IAExE,MAAM,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC5D,MAAM,SAAS,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;IAE9C,OAAO;QACL,gBAAgB;QAChB,gBAAgB;KACjB,CAAC;AACJ,CAAC"}
|
package/src/lib/errors.d.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
1
|
export declare function stringifyError(error: unknown, format?: {
|
|
2
2
|
oneline: boolean;
|
|
3
3
|
}): string;
|
|
4
|
+
/**
|
|
5
|
+
* Extends an error with a new message and keeps the original as the cause.
|
|
6
|
+
* This helps to keep the stacktrace intact and enables better debugging.
|
|
7
|
+
* @param error - The error to extend
|
|
8
|
+
* @param message - The new message to add to the error
|
|
9
|
+
* @param appendOriginalMessage - Whether to add the original error message after new message
|
|
10
|
+
* @returns A new error with the extended message and the original as cause
|
|
11
|
+
*/
|
|
12
|
+
export declare function extendError(error: unknown, message: string, { appendOriginalMessage }?: {
|
|
13
|
+
appendOriginalMessage?: boolean | undefined;
|
|
14
|
+
}): Error;
|
package/src/lib/errors.js
CHANGED
|
@@ -23,4 +23,18 @@ export function stringifyError(error, format) {
|
|
|
23
23
|
}
|
|
24
24
|
return JSON.stringify(error);
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Extends an error with a new message and keeps the original as the cause.
|
|
28
|
+
* This helps to keep the stacktrace intact and enables better debugging.
|
|
29
|
+
* @param error - The error to extend
|
|
30
|
+
* @param message - The new message to add to the error
|
|
31
|
+
* @param appendOriginalMessage - Whether to add the original error message after new message
|
|
32
|
+
* @returns A new error with the extended message and the original as cause
|
|
33
|
+
*/
|
|
34
|
+
export function extendError(error, message, { appendOriginalMessage = false } = {}) {
|
|
35
|
+
const errorMessage = appendOriginalMessage
|
|
36
|
+
? `${message}\n${stringifyError(error)}`
|
|
37
|
+
: message;
|
|
38
|
+
return new Error(errorMessage, { cause: error });
|
|
39
|
+
}
|
|
26
40
|
//# sourceMappingURL=errors.js.map
|
package/src/lib/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE1E,MAAM,UAAU,cAAc,CAC5B,KAAc,EACd,MAA6B;IAE7B,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,EAAE,CAChC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEvD,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,MAAM,cAAc,GAAG,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;gBACpB,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,gBAAgB,GAAG,CAAC;YAC/C,CAAC;YACD,OAAO,GAAG,KAAK,CAAC,IAAI,MAAM,cAAc,IAAI,CAAC;QAC/C,CAAC;QACD,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;IAC5C,CAAC;IAED,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACnE,OAAO,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,QAAQ,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC"}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE1E,MAAM,UAAU,cAAc,CAC5B,KAAc,EACd,MAA6B;IAE7B,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,EAAE,CAChC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEvD,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,MAAM,cAAc,GAAG,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;gBACpB,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,gBAAgB,GAAG,CAAC;YAC/C,CAAC;YACD,OAAO,GAAG,KAAK,CAAC,IAAI,MAAM,cAAc,IAAI,CAAC;QAC/C,CAAC;QACD,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;IAC5C,CAAC;IAED,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACnE,OAAO,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,QAAQ,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CACzB,KAAc,EACd,OAAe,EACf,EAAE,qBAAqB,GAAG,KAAK,EAAE,GAAG,EAAE;IAEtC,MAAM,YAAY,GAAG,qBAAqB;QACxC,CAAC,CAAC,GAAG,OAAO,KAAK,cAAc,CAAC,KAAK,CAAC,EAAE;QACxC,CAAC,CAAC,OAAO,CAAC;IACZ,OAAO,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -27,3 +27,8 @@ export declare const SHARDED_WAL_COORDINATOR_ID_ENV_VAR = "CP_SHARDED_WAL_COORDI
|
|
|
27
27
|
* Used as the base name for sharded WAL files (e.g., "trace" in "trace.json").
|
|
28
28
|
*/
|
|
29
29
|
export declare const PROFILER_PERSIST_BASENAME = "trace";
|
|
30
|
+
/**
|
|
31
|
+
* Name for current measure.
|
|
32
|
+
* Used as the name for the sharded folder.
|
|
33
|
+
*/
|
|
34
|
+
export declare const PROFILER_MEASURE_NAME_ENV_VAR = "CP_PROFILER_MEASURE_NAME";
|
|
@@ -27,4 +27,9 @@ export const SHARDED_WAL_COORDINATOR_ID_ENV_VAR = 'CP_SHARDED_WAL_COORDINATOR_ID
|
|
|
27
27
|
* Used as the base name for sharded WAL files (e.g., "trace" in "trace.json").
|
|
28
28
|
*/
|
|
29
29
|
export const PROFILER_PERSIST_BASENAME = 'trace';
|
|
30
|
+
/**
|
|
31
|
+
* Name for current measure.
|
|
32
|
+
* Used as the name for the sharded folder.
|
|
33
|
+
*/
|
|
34
|
+
export const PROFILER_MEASURE_NAME_ENV_VAR = 'CP_PROFILER_MEASURE_NAME';
|
|
30
35
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/lib/profiler/constants.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,cAAc,CAAC;AAEvD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAC7C,+BAA+B,CAAC;AAElC;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,OAAO,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/lib/profiler/constants.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,cAAc,CAAC;AAEvD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAC7C,+BAA+B,CAAC;AAElC;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,OAAO,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,0BAA0B,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type PerformanceObserverOptions } from '../performance-observer.js';
|
|
2
2
|
import type { ActionTrackEntryPayload } from '../user-timing-extensibility-api.type.js';
|
|
3
|
+
import { type WalRecord } from '../wal.js';
|
|
3
4
|
import { Profiler, type ProfilerOptions } from './profiler.js';
|
|
4
5
|
/**
|
|
5
6
|
* Options for configuring a NodejsProfiler instance.
|
|
@@ -40,7 +41,7 @@ export type NodejsProfilerOptions<DomainEvents extends string | object, Tracks e
|
|
|
40
41
|
* @template DomainEvents - The type of domain-specific events encoded by the performance observer sink
|
|
41
42
|
* @template Tracks - Record type defining available track names and their configurations
|
|
42
43
|
*/
|
|
43
|
-
export declare class NodejsProfiler<DomainEvents extends
|
|
44
|
+
export declare class NodejsProfiler<DomainEvents extends WalRecord, Tracks extends Record<string, ActionTrackEntryPayload> = Record<string, ActionTrackEntryPayload>> extends Profiler<Tracks> {
|
|
44
45
|
#private;
|
|
45
46
|
/**
|
|
46
47
|
* Creates a NodejsProfiler instance.
|
|
@@ -5,7 +5,8 @@ import { PerformanceObserverSink, } from '../performance-observer.js';
|
|
|
5
5
|
import { getUniqueInstanceId, getUniqueTimeId, } from '../process-id.js';
|
|
6
6
|
import { objectToEntries } from '../transform.js';
|
|
7
7
|
import { errorToMarkerPayload } from '../user-timing-extensibility-api-utils.js';
|
|
8
|
-
import {
|
|
8
|
+
import { getShardedPath } from '../wal-sharded.js';
|
|
9
|
+
import { WriteAheadLogFile, } from '../wal.js';
|
|
9
10
|
import { PROFILER_DEBUG_ENV_VAR, PROFILER_ENABLED_ENV_VAR, } from './constants.js';
|
|
10
11
|
import { Profiler } from './profiler.js';
|
|
11
12
|
import { traceEventWalFormat } from './wal-json-trace.js';
|
|
@@ -51,7 +52,9 @@ export class NodejsProfiler extends Profiler {
|
|
|
51
52
|
const walFormat = traceEventWalFormat();
|
|
52
53
|
this.#sink = new WriteAheadLogFile({
|
|
53
54
|
file: filename ??
|
|
54
|
-
path.join(process.cwd(),
|
|
55
|
+
path.join(process.cwd(),
|
|
56
|
+
// @TODO remove in PR https://github.com/code-pushup/cli/pull/1231 in favour of class method getShardedFileName
|
|
57
|
+
getShardedPath({
|
|
55
58
|
dir: 'tmp/profiles',
|
|
56
59
|
groupId: getUniqueTimeId(),
|
|
57
60
|
shardId: getUniqueInstanceId(this.#shardCounter),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profiler-node.js","sourceRoot":"","sources":["../../../../src/lib/profiler/profiler-node.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAEL,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,mBAAmB,EACnB,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAKjF,OAAO,
|
|
1
|
+
{"version":3,"file":"profiler-node.js","sourceRoot":"","sources":["../../../../src/lib/profiler/profiler-node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { type Counter } from './process-id.js';
|
|
2
|
+
import { type InvalidEntry, type RecoverResult, type WalFormat, type WalRecord, WriteAheadLogFile } from './wal.js';
|
|
3
|
+
/**
|
|
4
|
+
* Counter for generating sequential shard IDs.
|
|
5
|
+
* Encapsulates the shard count increment logic.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ShardedWalCounter: Counter;
|
|
8
|
+
/**
|
|
9
|
+
* Generates a unique readable instance ID.
|
|
10
|
+
* This ID uniquely identifies a shard/file per process/thread combination with a human-readable timestamp.
|
|
11
|
+
* Format: readable-timestamp.pid.threadId.counter
|
|
12
|
+
* Example: "20240101-120000-000.12345.1.1"
|
|
13
|
+
*
|
|
14
|
+
* @returns A unique ID string with readable timestamp, process ID, thread ID, and counter
|
|
15
|
+
*/
|
|
16
|
+
export declare function getShardId(): string;
|
|
17
|
+
/**
|
|
18
|
+
* @TODO remove in PR https://github.com/code-pushup/cli/pull/1231 in favour of class method getShardedFileName
|
|
19
|
+
* Generates a path to a shard file using human-readable IDs.
|
|
20
|
+
* Both groupId and shardId are already in readable date format.
|
|
21
|
+
*
|
|
22
|
+
* Example with groupId "20240101-120000-000" and shardId "20240101-120000-000.12345.1.1":
|
|
23
|
+
* Full path: /base/20240101-120000-000/trace.20240101-120000-000.12345.1.1.log
|
|
24
|
+
*
|
|
25
|
+
* @param opt.dir - The directory to store the shard file
|
|
26
|
+
* @param opt.format - The WalFormat to use for the shard file
|
|
27
|
+
* @param opt.groupId - The human-readable group ID (yyyymmdd-hhmmss-ms format)
|
|
28
|
+
* @param opt.shardId - The human-readable shard ID (readable-timestamp.pid.threadId.count format)
|
|
29
|
+
* @returns The path to the shard file
|
|
30
|
+
*/
|
|
31
|
+
export declare function getShardedPath<T extends object | string = object>(opt: {
|
|
32
|
+
dir?: string;
|
|
33
|
+
format: WalFormat<T>;
|
|
34
|
+
groupId: string;
|
|
35
|
+
shardId: string;
|
|
36
|
+
}): string;
|
|
37
|
+
/**
|
|
38
|
+
* Sharded Write-Ahead Log manager for coordinating multiple WAL shards.
|
|
39
|
+
* Handles distributed logging across multiple processes/files with atomic finalization.
|
|
40
|
+
*/
|
|
41
|
+
export declare class ShardedWal<T extends WalRecord = WalRecord> {
|
|
42
|
+
#private;
|
|
43
|
+
static instanceCount: number;
|
|
44
|
+
readonly groupId: string;
|
|
45
|
+
/**
|
|
46
|
+
* Initialize the given environment variable if not already set.
|
|
47
|
+
* This must be done as early as possible before any user code runs.
|
|
48
|
+
* Sets envVarName to the current instance ID if not already defined.
|
|
49
|
+
*
|
|
50
|
+
* @param envVarName - Environment variable name for storing coordinator ID
|
|
51
|
+
* @param instanceID - The instance ID to set as coordinator
|
|
52
|
+
*/
|
|
53
|
+
static setCoordinatorProcess(envVarName: string, instanceID: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Determines if this process is the leader WAL process.
|
|
56
|
+
*
|
|
57
|
+
* The leader is the process that first enabled profiling over the given env var.
|
|
58
|
+
* All descendant processes inherit the environment.
|
|
59
|
+
*
|
|
60
|
+
* @param envVarName - Environment variable name for storing coordinator ID
|
|
61
|
+
* @param instanceID - The instance ID to check
|
|
62
|
+
* @returns true if this is the leader WAL process, false otherwise
|
|
63
|
+
*/
|
|
64
|
+
static isCoordinatorProcess(envVarName: string, instanceID: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Create a sharded WAL manager.
|
|
67
|
+
*
|
|
68
|
+
* @param opt.dir - Base directory to store shard files (defaults to process.cwd())
|
|
69
|
+
* @param opt.format - WAL format configuration
|
|
70
|
+
* @param opt.groupId - Group ID for sharding (defaults to generated group ID)
|
|
71
|
+
* @param opt.coordinatorIdEnvVar - Environment variable name for storing coordinator ID (defaults to CP_SHARDED_WAL_COORDINATOR_ID)
|
|
72
|
+
* @param opt.autoCoordinator - Whether to auto-set the coordinator ID on construction (defaults to true)
|
|
73
|
+
*/
|
|
74
|
+
constructor(opt: {
|
|
75
|
+
debug?: boolean;
|
|
76
|
+
dir?: string;
|
|
77
|
+
format: WalFormat<T>;
|
|
78
|
+
groupId?: string;
|
|
79
|
+
coordinatorIdEnvVar: string;
|
|
80
|
+
autoCoordinator?: boolean;
|
|
81
|
+
});
|
|
82
|
+
/**
|
|
83
|
+
* Gets the unique instance ID for this ShardedWal.
|
|
84
|
+
*
|
|
85
|
+
* @returns The unique instance ID
|
|
86
|
+
*/
|
|
87
|
+
get id(): string;
|
|
88
|
+
/**
|
|
89
|
+
* Is this instance the coordinator?
|
|
90
|
+
*
|
|
91
|
+
* Coordinator status is determined from the coordinatorIdEnvVar environment variable.
|
|
92
|
+
* The coordinator handles finalization and cleanup of shard files.
|
|
93
|
+
* Checks dynamically to allow coordinator to be set after construction.
|
|
94
|
+
*
|
|
95
|
+
* @returns true if this instance is the coordinator, false otherwise
|
|
96
|
+
*/
|
|
97
|
+
isCoordinator(): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Asserts that the WAL is in 'active' state.
|
|
100
|
+
* Throws an error if the WAL has been finalized or cleaned.
|
|
101
|
+
*
|
|
102
|
+
* @throws Error if WAL is not in 'active' state
|
|
103
|
+
*/
|
|
104
|
+
private assertActive;
|
|
105
|
+
/**
|
|
106
|
+
* Gets the current lifecycle state of the WAL.
|
|
107
|
+
*
|
|
108
|
+
* @returns Current lifecycle state: 'active', 'finalized', or 'cleaned'
|
|
109
|
+
*/
|
|
110
|
+
getState(): 'active' | 'finalized' | 'cleaned';
|
|
111
|
+
/**
|
|
112
|
+
* Checks if the WAL has been finalized.
|
|
113
|
+
*
|
|
114
|
+
* @returns true if WAL is in 'finalized' state, false otherwise
|
|
115
|
+
*/
|
|
116
|
+
isFinalized(): boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Checks if the WAL has been cleaned.
|
|
119
|
+
*
|
|
120
|
+
* @returns true if WAL is in 'cleaned' state, false otherwise
|
|
121
|
+
*/
|
|
122
|
+
isCleaned(): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Generates a filename for a shard file using a shard ID.
|
|
125
|
+
* Both groupId and shardId are already in readable date format.
|
|
126
|
+
*
|
|
127
|
+
* Example with baseName "trace" and shardId "20240101-120000-000.12345.1.1":
|
|
128
|
+
* Filename: trace.20240101-120000-000.12345.1.1.log
|
|
129
|
+
*
|
|
130
|
+
* @param shardId - The human-readable shard ID (readable-timestamp.pid.threadId.count format)
|
|
131
|
+
* @returns The filename for the shard file
|
|
132
|
+
*/
|
|
133
|
+
getShardedFileName(shardId: string): string;
|
|
134
|
+
/**
|
|
135
|
+
* Generates a filename for the final merged output file.
|
|
136
|
+
* Uses the groupId as the identifier in the final filename.
|
|
137
|
+
*
|
|
138
|
+
* Example with baseName "trace" and groupId "20240101-120000-000":
|
|
139
|
+
* Filename: trace.20240101-120000-000.json
|
|
140
|
+
*
|
|
141
|
+
* Example with baseName "trace" and groupId "measureName":
|
|
142
|
+
* Filename: trace.measureName.json
|
|
143
|
+
*
|
|
144
|
+
* @returns The filename for the final merged output file
|
|
145
|
+
*/
|
|
146
|
+
getFinalFilePath(): string;
|
|
147
|
+
shard(): WriteAheadLogFile<T>;
|
|
148
|
+
/** Get all shard file paths matching this WAL's base name */
|
|
149
|
+
private shardFiles;
|
|
150
|
+
/** Get shard file paths created by this instance */
|
|
151
|
+
private getCreatedShardFiles;
|
|
152
|
+
/**
|
|
153
|
+
* Finalize all shards by merging them into a single output file.
|
|
154
|
+
* Recovers all records from all shards, validates no errors, and writes merged result.
|
|
155
|
+
* Idempotent: returns early if already finalized or cleaned.
|
|
156
|
+
* @throws Error if custom finalizer method throws
|
|
157
|
+
*/
|
|
158
|
+
finalize(opt?: Record<string, unknown>): void;
|
|
159
|
+
/**
|
|
160
|
+
* Cleanup shard files by removing them from disk.
|
|
161
|
+
* Coordinator-only: throws error if not coordinator to prevent race conditions.
|
|
162
|
+
* Idempotent: returns early if already cleaned.
|
|
163
|
+
*/
|
|
164
|
+
cleanup(): void;
|
|
165
|
+
get stats(): {
|
|
166
|
+
lastRecovery: {
|
|
167
|
+
file: string;
|
|
168
|
+
result: RecoverResult<T | InvalidEntry<string>>;
|
|
169
|
+
}[];
|
|
170
|
+
state: "active" | "finalized" | "cleaned";
|
|
171
|
+
groupId: string;
|
|
172
|
+
shardCount: number;
|
|
173
|
+
isCoordinator: boolean;
|
|
174
|
+
isFinalized: boolean;
|
|
175
|
+
isCleaned: boolean;
|
|
176
|
+
finalFilePath: string;
|
|
177
|
+
shardFileCount: number;
|
|
178
|
+
shardFiles: string[];
|
|
179
|
+
};
|
|
180
|
+
finalizeIfCoordinator(opt?: Record<string, unknown>): void;
|
|
181
|
+
/**
|
|
182
|
+
* Cleanup shard files if this instance is the coordinator.
|
|
183
|
+
* Safe to call from any process - only coordinator will execute cleanup.
|
|
184
|
+
*/
|
|
185
|
+
cleanupIfCoordinator(): void;
|
|
186
|
+
}
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
var _a;
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import process from 'node:process';
|
|
5
|
+
import { threadId } from 'node:worker_threads';
|
|
6
|
+
import { extendError } from './errors.js';
|
|
7
|
+
import { getUniqueInstanceId, getUniqueTimeId, } from './process-id.js';
|
|
8
|
+
import { WriteAheadLogFile, ensureDirectoryExistsSync, filterValidRecords, } from './wal.js';
|
|
9
|
+
/**
|
|
10
|
+
* Validates that a groupId is safe to use as a single path segment.
|
|
11
|
+
* Rejects path traversal attempts and path separators to prevent writing outside intended directory.
|
|
12
|
+
*
|
|
13
|
+
* @param groupId - The groupId to validate
|
|
14
|
+
* @throws Error if groupId contains unsafe characters or path traversal sequences
|
|
15
|
+
*/
|
|
16
|
+
function validateGroupId(groupId) {
|
|
17
|
+
// Reject empty or whitespace-only groupIds
|
|
18
|
+
if (!groupId || groupId.trim().length === 0) {
|
|
19
|
+
throw new Error('groupId cannot be empty or whitespace-only');
|
|
20
|
+
}
|
|
21
|
+
// Reject path separators (both forward and backward slashes)
|
|
22
|
+
if (groupId.includes('/') || groupId.includes('\\')) {
|
|
23
|
+
throw new Error('groupId cannot contain path separators');
|
|
24
|
+
}
|
|
25
|
+
// Reject relative path components
|
|
26
|
+
if (groupId === '..' || groupId === '.') {
|
|
27
|
+
throw new Error('groupId cannot be "." or ".."');
|
|
28
|
+
}
|
|
29
|
+
// Reject null bytes which can be used to bypass validation
|
|
30
|
+
if (groupId.includes('\0')) {
|
|
31
|
+
throw new Error('groupId cannot contain null bytes');
|
|
32
|
+
}
|
|
33
|
+
// Validate that the resolved path stays within the intended directory
|
|
34
|
+
// This catches cases where the path library normalizes to a parent directory
|
|
35
|
+
const normalized = path.normalize(groupId);
|
|
36
|
+
if (normalized !== groupId || normalized.startsWith('..')) {
|
|
37
|
+
throw new Error(`groupId normalization resulted in unsafe path: ${normalized}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// eslint-disable-next-line functional/no-let
|
|
41
|
+
let shardCount = 0;
|
|
42
|
+
/**
|
|
43
|
+
* Counter for generating sequential shard IDs.
|
|
44
|
+
* Encapsulates the shard count increment logic.
|
|
45
|
+
*/
|
|
46
|
+
export const ShardedWalCounter = {
|
|
47
|
+
next() {
|
|
48
|
+
return ++shardCount;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Generates a unique readable instance ID.
|
|
53
|
+
* This ID uniquely identifies a shard/file per process/thread combination with a human-readable timestamp.
|
|
54
|
+
* Format: readable-timestamp.pid.threadId.counter
|
|
55
|
+
* Example: "20240101-120000-000.12345.1.1"
|
|
56
|
+
*
|
|
57
|
+
* @returns A unique ID string with readable timestamp, process ID, thread ID, and counter
|
|
58
|
+
*/
|
|
59
|
+
export function getShardId() {
|
|
60
|
+
return `${getUniqueTimeId()}.${process.pid}.${threadId}.${ShardedWalCounter.next()}`;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* @TODO remove in PR https://github.com/code-pushup/cli/pull/1231 in favour of class method getShardedFileName
|
|
64
|
+
* Generates a path to a shard file using human-readable IDs.
|
|
65
|
+
* Both groupId and shardId are already in readable date format.
|
|
66
|
+
*
|
|
67
|
+
* Example with groupId "20240101-120000-000" and shardId "20240101-120000-000.12345.1.1":
|
|
68
|
+
* Full path: /base/20240101-120000-000/trace.20240101-120000-000.12345.1.1.log
|
|
69
|
+
*
|
|
70
|
+
* @param opt.dir - The directory to store the shard file
|
|
71
|
+
* @param opt.format - The WalFormat to use for the shard file
|
|
72
|
+
* @param opt.groupId - The human-readable group ID (yyyymmdd-hhmmss-ms format)
|
|
73
|
+
* @param opt.shardId - The human-readable shard ID (readable-timestamp.pid.threadId.count format)
|
|
74
|
+
* @returns The path to the shard file
|
|
75
|
+
*/
|
|
76
|
+
export function getShardedPath(opt) {
|
|
77
|
+
const { dir = '', format, groupId, shardId } = opt;
|
|
78
|
+
const { baseName, walExtension } = format;
|
|
79
|
+
return path.join(dir, groupId, `${baseName}.${shardId}${walExtension}`);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Sharded Write-Ahead Log manager for coordinating multiple WAL shards.
|
|
83
|
+
* Handles distributed logging across multiple processes/files with atomic finalization.
|
|
84
|
+
*/
|
|
85
|
+
export class ShardedWal {
|
|
86
|
+
static instanceCount = 0;
|
|
87
|
+
#id = getUniqueInstanceId({
|
|
88
|
+
next() {
|
|
89
|
+
return ++_a.instanceCount;
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
groupId;
|
|
93
|
+
#debug = false;
|
|
94
|
+
#format;
|
|
95
|
+
#dir = process.cwd();
|
|
96
|
+
#coordinatorIdEnvVar;
|
|
97
|
+
#state = 'active';
|
|
98
|
+
#lastRecovery = [];
|
|
99
|
+
#createdShardFiles = [];
|
|
100
|
+
/**
|
|
101
|
+
* Initialize the given environment variable if not already set.
|
|
102
|
+
* This must be done as early as possible before any user code runs.
|
|
103
|
+
* Sets envVarName to the current instance ID if not already defined.
|
|
104
|
+
*
|
|
105
|
+
* @param envVarName - Environment variable name for storing coordinator ID
|
|
106
|
+
* @param instanceID - The instance ID to set as coordinator
|
|
107
|
+
*/
|
|
108
|
+
static setCoordinatorProcess(envVarName, instanceID) {
|
|
109
|
+
if (!process.env[envVarName]) {
|
|
110
|
+
process.env[envVarName] = instanceID;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Determines if this process is the leader WAL process.
|
|
115
|
+
*
|
|
116
|
+
* The leader is the process that first enabled profiling over the given env var.
|
|
117
|
+
* All descendant processes inherit the environment.
|
|
118
|
+
*
|
|
119
|
+
* @param envVarName - Environment variable name for storing coordinator ID
|
|
120
|
+
* @param instanceID - The instance ID to check
|
|
121
|
+
* @returns true if this is the leader WAL process, false otherwise
|
|
122
|
+
*/
|
|
123
|
+
static isCoordinatorProcess(envVarName, instanceID) {
|
|
124
|
+
return process.env[envVarName] === instanceID;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Create a sharded WAL manager.
|
|
128
|
+
*
|
|
129
|
+
* @param opt.dir - Base directory to store shard files (defaults to process.cwd())
|
|
130
|
+
* @param opt.format - WAL format configuration
|
|
131
|
+
* @param opt.groupId - Group ID for sharding (defaults to generated group ID)
|
|
132
|
+
* @param opt.coordinatorIdEnvVar - Environment variable name for storing coordinator ID (defaults to CP_SHARDED_WAL_COORDINATOR_ID)
|
|
133
|
+
* @param opt.autoCoordinator - Whether to auto-set the coordinator ID on construction (defaults to true)
|
|
134
|
+
*/
|
|
135
|
+
constructor(opt) {
|
|
136
|
+
const { dir, format, debug, groupId, coordinatorIdEnvVar, autoCoordinator = true, } = opt;
|
|
137
|
+
if (debug != null) {
|
|
138
|
+
this.#debug = debug;
|
|
139
|
+
}
|
|
140
|
+
// Determine groupId: use provided, then env var, or generate
|
|
141
|
+
const resolvedGroupId = groupId == null ? getUniqueTimeId() : groupId;
|
|
142
|
+
// Validate groupId for path safety before using it
|
|
143
|
+
validateGroupId(resolvedGroupId);
|
|
144
|
+
this.groupId = resolvedGroupId;
|
|
145
|
+
if (dir) {
|
|
146
|
+
this.#dir = dir;
|
|
147
|
+
}
|
|
148
|
+
this.#format = format;
|
|
149
|
+
this.#coordinatorIdEnvVar = coordinatorIdEnvVar;
|
|
150
|
+
if (autoCoordinator) {
|
|
151
|
+
_a.setCoordinatorProcess(this.#coordinatorIdEnvVar, this.#id);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Gets the unique instance ID for this ShardedWal.
|
|
156
|
+
*
|
|
157
|
+
* @returns The unique instance ID
|
|
158
|
+
*/
|
|
159
|
+
get id() {
|
|
160
|
+
return this.#id;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Is this instance the coordinator?
|
|
164
|
+
*
|
|
165
|
+
* Coordinator status is determined from the coordinatorIdEnvVar environment variable.
|
|
166
|
+
* The coordinator handles finalization and cleanup of shard files.
|
|
167
|
+
* Checks dynamically to allow coordinator to be set after construction.
|
|
168
|
+
*
|
|
169
|
+
* @returns true if this instance is the coordinator, false otherwise
|
|
170
|
+
*/
|
|
171
|
+
isCoordinator() {
|
|
172
|
+
return _a.isCoordinatorProcess(this.#coordinatorIdEnvVar, this.#id);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Asserts that the WAL is in 'active' state.
|
|
176
|
+
* Throws an error if the WAL has been finalized or cleaned.
|
|
177
|
+
*
|
|
178
|
+
* @throws Error if WAL is not in 'active' state
|
|
179
|
+
*/
|
|
180
|
+
assertActive() {
|
|
181
|
+
if (this.#state !== 'active') {
|
|
182
|
+
throw new Error(`WAL is ${this.#state}, cannot modify`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Gets the current lifecycle state of the WAL.
|
|
187
|
+
*
|
|
188
|
+
* @returns Current lifecycle state: 'active', 'finalized', or 'cleaned'
|
|
189
|
+
*/
|
|
190
|
+
getState() {
|
|
191
|
+
return this.#state;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Checks if the WAL has been finalized.
|
|
195
|
+
*
|
|
196
|
+
* @returns true if WAL is in 'finalized' state, false otherwise
|
|
197
|
+
*/
|
|
198
|
+
isFinalized() {
|
|
199
|
+
return this.#state === 'finalized';
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Checks if the WAL has been cleaned.
|
|
203
|
+
*
|
|
204
|
+
* @returns true if WAL is in 'cleaned' state, false otherwise
|
|
205
|
+
*/
|
|
206
|
+
isCleaned() {
|
|
207
|
+
return this.#state === 'cleaned';
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Generates a filename for a shard file using a shard ID.
|
|
211
|
+
* Both groupId and shardId are already in readable date format.
|
|
212
|
+
*
|
|
213
|
+
* Example with baseName "trace" and shardId "20240101-120000-000.12345.1.1":
|
|
214
|
+
* Filename: trace.20240101-120000-000.12345.1.1.log
|
|
215
|
+
*
|
|
216
|
+
* @param shardId - The human-readable shard ID (readable-timestamp.pid.threadId.count format)
|
|
217
|
+
* @returns The filename for the shard file
|
|
218
|
+
*/
|
|
219
|
+
getShardedFileName(shardId) {
|
|
220
|
+
const { baseName, walExtension } = this.#format;
|
|
221
|
+
return `${baseName}.${shardId}${walExtension}`;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Generates a filename for the final merged output file.
|
|
225
|
+
* Uses the groupId as the identifier in the final filename.
|
|
226
|
+
*
|
|
227
|
+
* Example with baseName "trace" and groupId "20240101-120000-000":
|
|
228
|
+
* Filename: trace.20240101-120000-000.json
|
|
229
|
+
*
|
|
230
|
+
* Example with baseName "trace" and groupId "measureName":
|
|
231
|
+
* Filename: trace.measureName.json
|
|
232
|
+
*
|
|
233
|
+
* @returns The filename for the final merged output file
|
|
234
|
+
*/
|
|
235
|
+
getFinalFilePath() {
|
|
236
|
+
const groupIdDir = path.join(this.#dir, this.groupId);
|
|
237
|
+
const { baseName, finalExtension } = this.#format;
|
|
238
|
+
return path.join(groupIdDir, `${baseName}.${this.groupId}${finalExtension}`);
|
|
239
|
+
}
|
|
240
|
+
shard() {
|
|
241
|
+
this.assertActive();
|
|
242
|
+
const filePath = path.join(this.#dir, this.groupId, this.getShardedFileName(getShardId()));
|
|
243
|
+
this.#createdShardFiles.push(filePath);
|
|
244
|
+
return new WriteAheadLogFile({
|
|
245
|
+
file: filePath,
|
|
246
|
+
codec: this.#format.codec,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/** Get all shard file paths matching this WAL's base name */
|
|
250
|
+
shardFiles() {
|
|
251
|
+
if (!fs.existsSync(this.#dir)) {
|
|
252
|
+
return [];
|
|
253
|
+
}
|
|
254
|
+
const groupDir = path.join(this.#dir, this.groupId);
|
|
255
|
+
if (!fs.existsSync(groupDir)) {
|
|
256
|
+
return [];
|
|
257
|
+
}
|
|
258
|
+
return fs
|
|
259
|
+
.readdirSync(groupDir)
|
|
260
|
+
.filter(entry => entry.endsWith(this.#format.walExtension))
|
|
261
|
+
.filter(entry => entry.startsWith(`${this.#format.baseName}`))
|
|
262
|
+
.map(entry => path.join(groupDir, entry));
|
|
263
|
+
}
|
|
264
|
+
/** Get shard file paths created by this instance */
|
|
265
|
+
getCreatedShardFiles() {
|
|
266
|
+
return this.#createdShardFiles.filter(f => fs.existsSync(f));
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Finalize all shards by merging them into a single output file.
|
|
270
|
+
* Recovers all records from all shards, validates no errors, and writes merged result.
|
|
271
|
+
* Idempotent: returns early if already finalized or cleaned.
|
|
272
|
+
* @throws Error if custom finalizer method throws
|
|
273
|
+
*/
|
|
274
|
+
finalize(opt) {
|
|
275
|
+
if (this.#state !== 'active') {
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
// Ensure base directory exists before calling shardFiles()
|
|
279
|
+
ensureDirectoryExistsSync(this.#dir);
|
|
280
|
+
const lastRecovery = this.shardFiles().map(f => ({
|
|
281
|
+
file: f,
|
|
282
|
+
result: new WriteAheadLogFile({
|
|
283
|
+
file: f,
|
|
284
|
+
codec: this.#format.codec,
|
|
285
|
+
}).recover(),
|
|
286
|
+
}));
|
|
287
|
+
const records = lastRecovery.flatMap(({ result }) => result.records);
|
|
288
|
+
if (this.#debug) {
|
|
289
|
+
this.#lastRecovery = lastRecovery;
|
|
290
|
+
}
|
|
291
|
+
ensureDirectoryExistsSync(path.dirname(this.getFinalFilePath()));
|
|
292
|
+
try {
|
|
293
|
+
fs.writeFileSync(this.getFinalFilePath(), this.#format.finalizer(filterValidRecords(records), opt));
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
throw extendError(error, 'Could not finalize sharded wal. Finalizer method in format throws.', { appendOriginalMessage: true });
|
|
297
|
+
}
|
|
298
|
+
this.#state = 'finalized';
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Cleanup shard files by removing them from disk.
|
|
302
|
+
* Coordinator-only: throws error if not coordinator to prevent race conditions.
|
|
303
|
+
* Idempotent: returns early if already cleaned.
|
|
304
|
+
*/
|
|
305
|
+
cleanup() {
|
|
306
|
+
if (!this.isCoordinator()) {
|
|
307
|
+
throw new Error('cleanup() can only be called by coordinator');
|
|
308
|
+
}
|
|
309
|
+
if (this.#state === 'cleaned') {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
this.shardFiles()
|
|
313
|
+
.filter(f => fs.existsSync(f))
|
|
314
|
+
.forEach(f => {
|
|
315
|
+
fs.unlinkSync(f);
|
|
316
|
+
});
|
|
317
|
+
this.#state = 'cleaned';
|
|
318
|
+
}
|
|
319
|
+
get stats() {
|
|
320
|
+
// When finalized, count all shard files from filesystem (for multi-process scenarios)
|
|
321
|
+
// Otherwise, count only files created by this instance
|
|
322
|
+
const shardFilesList = this.#state === 'finalized' || this.#state === 'cleaned'
|
|
323
|
+
? this.shardFiles()
|
|
324
|
+
: this.getCreatedShardFiles();
|
|
325
|
+
return {
|
|
326
|
+
lastRecovery: this.#lastRecovery,
|
|
327
|
+
state: this.#state,
|
|
328
|
+
groupId: this.groupId,
|
|
329
|
+
shardCount: shardFilesList.length,
|
|
330
|
+
isCoordinator: this.isCoordinator(),
|
|
331
|
+
isFinalized: this.isFinalized(),
|
|
332
|
+
isCleaned: this.isCleaned(),
|
|
333
|
+
finalFilePath: this.getFinalFilePath(),
|
|
334
|
+
shardFileCount: shardFilesList.length,
|
|
335
|
+
shardFiles: shardFilesList,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
finalizeIfCoordinator(opt) {
|
|
339
|
+
if (this.isCoordinator()) {
|
|
340
|
+
this.finalize(opt);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Cleanup shard files if this instance is the coordinator.
|
|
345
|
+
* Safe to call from any process - only coordinator will execute cleanup.
|
|
346
|
+
*/
|
|
347
|
+
cleanupIfCoordinator() {
|
|
348
|
+
if (this.isCoordinator()) {
|
|
349
|
+
this.cleanup();
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
_a = ShardedWal;
|
|
354
|
+
//# sourceMappingURL=wal-sharded.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wal-sharded.js","sourceRoot":"","sources":["../../../src/lib/wal-sharded.ts"],"names":[],"mappings":"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"}
|
package/src/lib/wal.d.ts
CHANGED
|
@@ -78,7 +78,7 @@ export declare function recoverFromContent<T>(content: string, decode: Codec<T>[
|
|
|
78
78
|
* Write-Ahead Log implementation for crash-safe append-only logging.
|
|
79
79
|
* Provides atomic operations for writing, recovering, and repacking log entries.
|
|
80
80
|
*/
|
|
81
|
-
export declare class WriteAheadLogFile<T> implements AppendableSink<T> {
|
|
81
|
+
export declare class WriteAheadLogFile<T extends WalRecord = WalRecord> implements AppendableSink<T> {
|
|
82
82
|
#private;
|
|
83
83
|
/**
|
|
84
84
|
* Create a new WAL file instance.
|
|
@@ -122,11 +122,12 @@ export declare class WriteAheadLogFile<T> implements AppendableSink<T> {
|
|
|
122
122
|
*/
|
|
123
123
|
getStats(): WalStats<T>;
|
|
124
124
|
}
|
|
125
|
+
export type WalRecord = object | string;
|
|
125
126
|
/**
|
|
126
127
|
* Format descriptor that binds codec and file extension together.
|
|
127
128
|
* Prevents misconfiguration by keeping related concerns in one object.
|
|
128
129
|
*/
|
|
129
|
-
export type WalFormat<T extends
|
|
130
|
+
export type WalFormat<T extends WalRecord = WalRecord> = {
|
|
130
131
|
/** Base name for the WAL (e.g., "trace") */
|
|
131
132
|
baseName: string;
|
|
132
133
|
/** Shard file extension (e.g., ".jsonl") */
|
|
@@ -152,85 +153,10 @@ export declare const stringCodec: <T extends string | object = string>() => Code
|
|
|
152
153
|
* @param format - Partial WalFormat configuration
|
|
153
154
|
* @returns Parsed WalFormat with defaults filled in
|
|
154
155
|
*/
|
|
155
|
-
export declare function parseWalFormat<T extends
|
|
156
|
+
export declare function parseWalFormat<T extends WalRecord = WalRecord>(format: Partial<WalFormat<T>>): WalFormat<T>;
|
|
156
157
|
/**
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
* All descendant processes inherit the environment but have different PIDs.
|
|
161
|
-
*
|
|
162
|
-
* @returns true if this is the leader WAL process, false otherwise
|
|
158
|
+
* NOTE: this helper is only used within the scope of wal and sharded wal logic. The rest of the repo avoids sync methods so it is not reusable.
|
|
159
|
+
* Ensures a directory exists, creating it recursively if necessary using sync methods.
|
|
160
|
+
* @param dirPath - The directory path to ensure exists
|
|
163
161
|
*/
|
|
164
|
-
export declare function
|
|
165
|
-
/**
|
|
166
|
-
* Initialize the origin PID environment variable if not already set.
|
|
167
|
-
* This must be done as early as possible before any user code runs.
|
|
168
|
-
* Sets envVarName to the current process ID if not already defined.
|
|
169
|
-
*/
|
|
170
|
-
export declare function setCoordinatorProcess(envVarName: string, profilerID: string): void;
|
|
171
|
-
/**
|
|
172
|
-
* Generates a path to a shard file using human-readable IDs.
|
|
173
|
-
* Both groupId and shardId are already in readable date format.
|
|
174
|
-
*
|
|
175
|
-
* Example with groupId "20240101-120000-000" and shardId "20240101-120000-000.12345.1.1":
|
|
176
|
-
* Full path: /base/20240101-120000-000/trace.20240101-120000-000.12345.1.1.log
|
|
177
|
-
*
|
|
178
|
-
* @param opt.dir - The directory to store the shard file
|
|
179
|
-
* @param opt.format - The WalFormat to use for the shard file
|
|
180
|
-
* @param opt.groupId - The human-readable group ID (yyyymmdd-hhmmss-ms format)
|
|
181
|
-
* @param opt.shardId - The human-readable shard ID (readable-timestamp.pid.threadId.count format)
|
|
182
|
-
* @returns The path to the shard file
|
|
183
|
-
*/
|
|
184
|
-
export declare function getShardedPath<T extends object | string = object>(opt: {
|
|
185
|
-
dir?: string;
|
|
186
|
-
format: WalFormat<T>;
|
|
187
|
-
groupId: string;
|
|
188
|
-
shardId: string;
|
|
189
|
-
}): string;
|
|
190
|
-
export declare function getShardedFinalPath<T extends object | string = object>(opt: {
|
|
191
|
-
dir?: string;
|
|
192
|
-
format: WalFormat<T>;
|
|
193
|
-
groupId: string;
|
|
194
|
-
}): string;
|
|
195
|
-
/**
|
|
196
|
-
* Sharded Write-Ahead Log manager for coordinating multiple WAL shards.
|
|
197
|
-
* Handles distributed logging across multiple processes/files with atomic finalization.
|
|
198
|
-
*/
|
|
199
|
-
export declare class ShardedWal<T extends object | string = object> {
|
|
200
|
-
#private;
|
|
201
|
-
static instanceCount: number;
|
|
202
|
-
readonly groupId: string;
|
|
203
|
-
/**
|
|
204
|
-
* Create a sharded WAL manager.
|
|
205
|
-
*
|
|
206
|
-
* @param opt.dir - Base directory to store shard files (defaults to process.cwd())
|
|
207
|
-
* @param opt.format - WAL format configuration
|
|
208
|
-
* @param opt.groupId - Group ID for sharding (defaults to generated group ID)
|
|
209
|
-
* @param opt.coordinatorIdEnvVar - Environment variable name for storing coordinator ID (defaults to CP_SHARDED_WAL_COORDINATOR_ID)
|
|
210
|
-
*/
|
|
211
|
-
constructor(opt: {
|
|
212
|
-
dir?: string;
|
|
213
|
-
format: Partial<WalFormat<T>>;
|
|
214
|
-
groupId?: string;
|
|
215
|
-
coordinatorIdEnvVar: string;
|
|
216
|
-
});
|
|
217
|
-
/**
|
|
218
|
-
* Is this instance the coordinator?
|
|
219
|
-
*
|
|
220
|
-
* Coordinator status is determined from the coordinatorIdEnvVar environment variable.
|
|
221
|
-
* The coordinator handles finalization and cleanup of shard files.
|
|
222
|
-
*
|
|
223
|
-
* @returns true if this instance is the coordinator, false otherwise
|
|
224
|
-
*/
|
|
225
|
-
isCoordinator(): boolean;
|
|
226
|
-
shard(shardId?: string): WriteAheadLogFile<T>;
|
|
227
|
-
/** Get all shard file paths matching this WAL's base name */
|
|
228
|
-
private shardFiles;
|
|
229
|
-
/**
|
|
230
|
-
* Finalize all shards by merging them into a single output file.
|
|
231
|
-
* Recovers all records from all shards, validates no errors, and writes merged result.
|
|
232
|
-
* @throws Error if any shard contains decode errors
|
|
233
|
-
*/
|
|
234
|
-
finalize(opt?: Record<string, unknown>): void;
|
|
235
|
-
cleanup(): void;
|
|
236
|
-
}
|
|
162
|
+
export declare function ensureDirectoryExistsSync(dirPath: string): void;
|
package/src/lib/wal.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
/* eslint-disable max-lines */
|
|
2
1
|
import * as fs from 'node:fs';
|
|
3
2
|
import path from 'node:path';
|
|
4
|
-
import process from 'node:process';
|
|
5
|
-
import { threadId } from 'node:worker_threads';
|
|
6
|
-
import { getUniqueInstanceId, getUniqueTimeId, } from './process-id.js';
|
|
7
3
|
export const createTolerantCodec = (codec) => {
|
|
8
4
|
const { encode, decode } = codec;
|
|
9
5
|
return {
|
|
@@ -144,8 +140,8 @@ export class WriteAheadLogFile {
|
|
|
144
140
|
console.log('Found invalid entries during WAL repack');
|
|
145
141
|
}
|
|
146
142
|
const recordsToWrite = hasInvalidEntries
|
|
147
|
-
? r.records
|
|
148
|
-
:
|
|
143
|
+
? filterValidRecords(r.records)
|
|
144
|
+
: r.records;
|
|
149
145
|
ensureDirectoryExistsSync(path.dirname(out));
|
|
150
146
|
fs.writeFileSync(out, `${recordsToWrite.map(this.#encode).join('\n')}\n`);
|
|
151
147
|
}
|
|
@@ -210,189 +206,13 @@ export function parseWalFormat(format) {
|
|
|
210
206
|
};
|
|
211
207
|
}
|
|
212
208
|
/**
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
* The leader is the process that first enabled profiling (the one that set CP_PROFILER_ORIGIN_PID).
|
|
216
|
-
* All descendant processes inherit the environment but have different PIDs.
|
|
217
|
-
*
|
|
218
|
-
* @returns true if this is the leader WAL process, false otherwise
|
|
219
|
-
*/
|
|
220
|
-
export function isCoordinatorProcess(envVarName, profilerID) {
|
|
221
|
-
return process.env[envVarName] === profilerID;
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Initialize the origin PID environment variable if not already set.
|
|
225
|
-
* This must be done as early as possible before any user code runs.
|
|
226
|
-
* Sets envVarName to the current process ID if not already defined.
|
|
227
|
-
*/
|
|
228
|
-
export function setCoordinatorProcess(envVarName, profilerID) {
|
|
229
|
-
if (!process.env[envVarName]) {
|
|
230
|
-
// eslint-disable-next-line functional/immutable-data
|
|
231
|
-
process.env[envVarName] = profilerID;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Simple counter implementation for generating sequential IDs.
|
|
236
|
-
*/
|
|
237
|
-
const shardCounter = (() => {
|
|
238
|
-
// eslint-disable-next-line functional/no-let
|
|
239
|
-
let count = 0;
|
|
240
|
-
return { next: () => ++count };
|
|
241
|
-
})();
|
|
242
|
-
/**
|
|
243
|
-
* Generates a unique sharded WAL ID based on performance time origin, process ID, thread ID, and instance count.
|
|
244
|
-
*/
|
|
245
|
-
function getShardedWalId() {
|
|
246
|
-
// eslint-disable-next-line functional/immutable-data
|
|
247
|
-
return `${Math.round(performance.timeOrigin)}.${process.pid}.${threadId}.${++ShardedWal.instanceCount}`;
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
209
|
+
* NOTE: this helper is only used within the scope of wal and sharded wal logic. The rest of the repo avoids sync methods so it is not reusable.
|
|
250
210
|
* Ensures a directory exists, creating it recursively if necessary using sync methods.
|
|
251
211
|
* @param dirPath - The directory path to ensure exists
|
|
252
212
|
*/
|
|
253
|
-
function ensureDirectoryExistsSync(dirPath) {
|
|
213
|
+
export function ensureDirectoryExistsSync(dirPath) {
|
|
254
214
|
if (!fs.existsSync(dirPath)) {
|
|
255
215
|
fs.mkdirSync(dirPath, { recursive: true });
|
|
256
216
|
}
|
|
257
217
|
}
|
|
258
|
-
/**
|
|
259
|
-
* Generates a path to a shard file using human-readable IDs.
|
|
260
|
-
* Both groupId and shardId are already in readable date format.
|
|
261
|
-
*
|
|
262
|
-
* Example with groupId "20240101-120000-000" and shardId "20240101-120000-000.12345.1.1":
|
|
263
|
-
* Full path: /base/20240101-120000-000/trace.20240101-120000-000.12345.1.1.log
|
|
264
|
-
*
|
|
265
|
-
* @param opt.dir - The directory to store the shard file
|
|
266
|
-
* @param opt.format - The WalFormat to use for the shard file
|
|
267
|
-
* @param opt.groupId - The human-readable group ID (yyyymmdd-hhmmss-ms format)
|
|
268
|
-
* @param opt.shardId - The human-readable shard ID (readable-timestamp.pid.threadId.count format)
|
|
269
|
-
* @returns The path to the shard file
|
|
270
|
-
*/
|
|
271
|
-
export function getShardedPath(opt) {
|
|
272
|
-
const { dir = '', format, groupId, shardId } = opt;
|
|
273
|
-
const { baseName, walExtension } = format;
|
|
274
|
-
return path.join(dir, groupId, `${baseName}.${shardId}${walExtension}`);
|
|
275
|
-
}
|
|
276
|
-
export function getShardedFinalPath(opt) {
|
|
277
|
-
const { dir = '', format, groupId } = opt;
|
|
278
|
-
const { baseName, finalExtension } = format;
|
|
279
|
-
return path.join(dir, groupId, `${baseName}.${groupId}${finalExtension}`);
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* Sharded Write-Ahead Log manager for coordinating multiple WAL shards.
|
|
283
|
-
* Handles distributed logging across multiple processes/files with atomic finalization.
|
|
284
|
-
*/
|
|
285
|
-
export class ShardedWal {
|
|
286
|
-
static instanceCount = 0;
|
|
287
|
-
#id = getShardedWalId();
|
|
288
|
-
groupId = getUniqueTimeId();
|
|
289
|
-
#format;
|
|
290
|
-
#dir = process.cwd();
|
|
291
|
-
#isCoordinator;
|
|
292
|
-
/**
|
|
293
|
-
* Create a sharded WAL manager.
|
|
294
|
-
*
|
|
295
|
-
* @param opt.dir - Base directory to store shard files (defaults to process.cwd())
|
|
296
|
-
* @param opt.format - WAL format configuration
|
|
297
|
-
* @param opt.groupId - Group ID for sharding (defaults to generated group ID)
|
|
298
|
-
* @param opt.coordinatorIdEnvVar - Environment variable name for storing coordinator ID (defaults to CP_SHARDED_WAL_COORDINATOR_ID)
|
|
299
|
-
*/
|
|
300
|
-
constructor(opt) {
|
|
301
|
-
const { dir, format, groupId, coordinatorIdEnvVar } = opt;
|
|
302
|
-
this.groupId = groupId ?? getUniqueTimeId();
|
|
303
|
-
if (dir) {
|
|
304
|
-
this.#dir = dir;
|
|
305
|
-
}
|
|
306
|
-
this.#format = parseWalFormat(format);
|
|
307
|
-
this.#isCoordinator = isCoordinatorProcess(coordinatorIdEnvVar, this.#id);
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Is this instance the coordinator?
|
|
311
|
-
*
|
|
312
|
-
* Coordinator status is determined from the coordinatorIdEnvVar environment variable.
|
|
313
|
-
* The coordinator handles finalization and cleanup of shard files.
|
|
314
|
-
*
|
|
315
|
-
* @returns true if this instance is the coordinator, false otherwise
|
|
316
|
-
*/
|
|
317
|
-
isCoordinator() {
|
|
318
|
-
return this.#isCoordinator;
|
|
319
|
-
}
|
|
320
|
-
shard(shardId = getUniqueInstanceId(shardCounter)) {
|
|
321
|
-
return new WriteAheadLogFile({
|
|
322
|
-
file: getShardedPath({
|
|
323
|
-
dir: this.#dir,
|
|
324
|
-
format: this.#format,
|
|
325
|
-
groupId: this.groupId,
|
|
326
|
-
shardId,
|
|
327
|
-
}),
|
|
328
|
-
codec: this.#format.codec,
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
/** Get all shard file paths matching this WAL's base name */
|
|
332
|
-
shardFiles() {
|
|
333
|
-
if (!fs.existsSync(this.#dir)) {
|
|
334
|
-
return [];
|
|
335
|
-
}
|
|
336
|
-
const groupIdDir = path.dirname(getShardedFinalPath({
|
|
337
|
-
dir: this.#dir,
|
|
338
|
-
format: this.#format,
|
|
339
|
-
groupId: this.groupId,
|
|
340
|
-
}));
|
|
341
|
-
// create dir if not existing
|
|
342
|
-
ensureDirectoryExistsSync(groupIdDir);
|
|
343
|
-
return fs
|
|
344
|
-
.readdirSync(groupIdDir)
|
|
345
|
-
.filter(entry => entry.endsWith(this.#format.walExtension))
|
|
346
|
-
.filter(entry => entry.startsWith(`${this.#format.baseName}`))
|
|
347
|
-
.map(entry => path.join(groupIdDir, entry));
|
|
348
|
-
}
|
|
349
|
-
/**
|
|
350
|
-
* Finalize all shards by merging them into a single output file.
|
|
351
|
-
* Recovers all records from all shards, validates no errors, and writes merged result.
|
|
352
|
-
* @throws Error if any shard contains decode errors
|
|
353
|
-
*/
|
|
354
|
-
finalize(opt) {
|
|
355
|
-
const fileRecoveries = this.shardFiles().map(f => ({
|
|
356
|
-
file: f,
|
|
357
|
-
recovery: new WriteAheadLogFile({
|
|
358
|
-
file: f,
|
|
359
|
-
codec: this.#format.codec,
|
|
360
|
-
}).recover(),
|
|
361
|
-
}));
|
|
362
|
-
const records = fileRecoveries.flatMap(({ recovery }) => recovery.records);
|
|
363
|
-
// Check if any records are invalid entries (from tolerant codec)
|
|
364
|
-
const hasInvalidEntries = records.some(r => typeof r === 'object' && r != null && '__invalid' in r);
|
|
365
|
-
const recordsToFinalize = hasInvalidEntries
|
|
366
|
-
? records
|
|
367
|
-
: filterValidRecords(records);
|
|
368
|
-
const out = getShardedFinalPath({
|
|
369
|
-
dir: this.#dir,
|
|
370
|
-
format: this.#format,
|
|
371
|
-
groupId: this.groupId,
|
|
372
|
-
});
|
|
373
|
-
ensureDirectoryExistsSync(path.dirname(out));
|
|
374
|
-
fs.writeFileSync(out, this.#format.finalizer(recordsToFinalize, opt));
|
|
375
|
-
}
|
|
376
|
-
cleanup() {
|
|
377
|
-
this.shardFiles().forEach(f => {
|
|
378
|
-
// Remove the shard file
|
|
379
|
-
fs.unlinkSync(f);
|
|
380
|
-
// Remove the parent directory (shard group directory)
|
|
381
|
-
const shardDir = path.dirname(f);
|
|
382
|
-
try {
|
|
383
|
-
fs.rmdirSync(shardDir);
|
|
384
|
-
}
|
|
385
|
-
catch {
|
|
386
|
-
// Directory might not be empty or already removed, ignore
|
|
387
|
-
}
|
|
388
|
-
});
|
|
389
|
-
// Also try to remove the root directory if it becomes empty
|
|
390
|
-
try {
|
|
391
|
-
fs.rmdirSync(this.#dir);
|
|
392
|
-
}
|
|
393
|
-
catch {
|
|
394
|
-
// Directory might not be empty or already removed, ignore
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
218
|
//# sourceMappingURL=wal.js.map
|
package/src/lib/wal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wal.js","sourceRoot":"","sources":["../../../src/lib/wal.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wal.js","sourceRoot":"","sources":["../../../src/lib/wal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,WAAW,CAAC;AAiE7B,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAgB,KAGlD,EAAiC,EAAE;IAClC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAEjC,OAAO;QACL,MAAM,EAAE,CAAC,CAAC,EAAE,CACV,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,WAAW,IAAI,CAAC;YAC5C,CAAC,CAAE,CAAqB,CAAC,GAAG;YAC5B,CAAC,CAAC,MAAM,CAAC,CAAM,CAAC;QACpB,MAAM,EAAE,CAAC,CAAC,EAAE;YACV,IAAI,CAAC;gBACH,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;YACnB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;YACrC,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAChC,OAAsC;IAEtC,OAAO,OAAO;SACX,MAAM,CACL,CAAC,CAAC,EAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,IAAI,IAAI,IAAI,WAAW,IAAI,CAAC,CAAC,CACzE;SACA,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAM,CAAC,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAe,EACf,MAA0B;IAE1B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAErC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CACnC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;QACV,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,CAAC;YACH,OAAO;gBACL,GAAG,CAAC;gBACJ,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;aACnC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,GAAG,CAAC;gBACJ,MAAM,EAAE;oBACN,GAAG,CAAC,CAAC,MAAM;oBACX,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,KAAc,EAAE;iBAClD;aACF,CAAC;QACJ,CAAC;IACH,CAAC,EACD,EAAE,OAAO,EAAE,EAAS,EAAE,MAAM,EAAE,EAAgC,EAAE,CACjE,CAAC;IAEF,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1B,OAAO;QACL,GAAG,GAAG;QACN,WAAW,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;KAC1C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IAG5B,GAAG,GAAkB,IAAI,CAAC;IACjB,KAAK,CAAS;IACd,OAAO,CAAoC;IAC3C,OAAO,CAAqB;IACrC,kBAAkB,GAA2C,IAAI,CAAC;IAElE;;;OAGG;IACH,YAAY,OAA0C;QACpD,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;QAC1B,MAAM,CAAC,GAAG,mBAAmB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,CAAC;IAED,qCAAqC;IACrC,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;IAE3B,oEAAoE;IACpE,IAAI,GAAG,GAAG,EAAE;QACV,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QACD,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEF;;;;OAIG;IACH,MAAM,GAAG,CAAC,CAAI,EAAE,EAAE;QAChB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACpC,CAAC;QACD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC,CAAC;IAEF,yBAAyB;IACzB,KAAK,GAAG,GAAG,EAAE;QACX,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;IAClB,CAAC,CAAC;IAEF,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC;IAElC;;;;;OAKG;IACH,OAAO;QACL,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,kBAAkB,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;YACzE,OAAO,IAAI,CAAC,kBAAkB,CAAC;QACjC,CAAC;QACD,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAChD,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAC1C,GAAG,EACH,IAAI,CAAC,OAAO,CACb,CAAC;QAEF,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK;QACrB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,sCAAsC;YACtC,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACtD,CAAC;QAED,iEAAiE;QACjE,MAAM,iBAAiB,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CACtC,GAAG,CAAC,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,IAAI,IAAI,IAAI,WAAW,IAAI,GAAG,CACpE,CAAC;QACF,IAAI,iBAAiB,EAAE,CAAC;YACtB,sCAAsC;YACtC,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,cAAc,GAAG,iBAAiB;YACtC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/B,CAAC,CAAE,CAAC,CAAC,OAAe,CAAC;QACvB,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7C,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5E,CAAC;IAED;;;;OAIG;IACH,QAAQ;QACN,MAAM,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,KAAK;YACpB,QAAQ,EAAE,IAAI,CAAC,GAAG,IAAI,IAAI;YAC1B,UAAU;YACV,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACvD,YAAY,EAAE,IAAI,CAAC,kBAAkB;SACtC,CAAC;IACJ,CAAC;CACF;AAwBD,MAAM,CAAC,MAAM,WAAW,GAAG,GAEb,EAAE,CAAC,CAAC;IAChB,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC5D,MAAM,EAAE,CAAC,CAAC,EAAE;QACV,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAM,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAM,CAAC;QAChB,CAAC;IACH,CAAC;CACF,CAAC,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAC5B,MAA6B;IAE7B,MAAM,EACJ,QAAQ,GAAG,KAAK,EAChB,YAAY,GAAG,MAAM,EACrB,cAAc,GAAG,YAAY,EAC7B,KAAK,GAAG,WAAW,EAAK,GACzB,GAAG,MAAM,CAAC;IAEX,MAAM,SAAS,GACb,MAAM,CAAC,SAAS;QAChB,CAAC,CAAC,OAAqC,EAAE,EAAE;YACzC,qDAAqD;YACrD,sEAAsE;YACtE,4DAA4D;YAC5D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CACnC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,IAAI,IAAI,IAAI,WAAW,IAAI,MAAM;gBACnE,CAAC,CAAE,MAA+B,CAAC,GAAG;gBACtC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAW,CAAC,CAC9B,CAAC;YACF,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;QACnC,CAAC,CAAC,CAAC;IAEL,OAAO;QACL,QAAQ;QACR,YAAY;QACZ,cAAc;QACd,KAAK;QACL,SAAS;KACa,CAAC;AAC3B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAe;IACvD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
|