@dbx-tools/appkit 0.9.120 → 0.9.122
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/README.md +0 -52
- package/index.ts +2 -5
- package/lib/index.d.ts +2 -5
- package/lib/index.js +2 -4
- package/lib/src/appkit.d.ts +0 -2
- package/lib/src/appkit.js +3 -10
- package/lib/src/identity.js +5 -4
- package/lib/src/provision.js +3 -4
- package/lib/src/tool-provider.d.ts +6 -1
- package/lib/src/tool-provider.js +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -17
- package/src/appkit.ts +2 -14
- package/src/identity.ts +6 -3
- package/src/provision.ts +2 -3
- package/src/tool-provider.ts +7 -1
- package/lib/src/child-process.d.ts +0 -65
- package/lib/src/child-process.js +0 -180
- package/src/child-process.ts +0 -238
package/lib/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/_auto-configure.ts","../src/appkit.ts","../src/brand-context.ts","../src/bundle.ts","../src/cache-storage.ts","../src/
|
|
1
|
+
{"root":["../src/_auto-configure.ts","../src/appkit.ts","../src/brand-context.ts","../src/bundle.ts","../src/cache-storage.ts","../src/databricks.ts","../src/files-cache.ts","../src/identity.ts","../src/interceptor.ts","../src/lakebase-resolver.ts","../src/migration.ts","../src/pgaddress.ts","../src/plugin-execution.ts","../src/plugin-registry.ts","../src/provision.ts","../src/request-tags.ts","../src/tool-operations.ts","../src/tool-provider.ts","../src/toolkit-entries.ts","../index.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@databricks/appkit": "0.81.0",
|
|
23
|
-
"@dbx-tools/projen": "^0.9.
|
|
23
|
+
"@dbx-tools/projen": "^0.9.122",
|
|
24
24
|
"@types/node": "^24.6.0",
|
|
25
25
|
"typescript": "^5.9.3",
|
|
26
26
|
"vitest": "3.2.4"
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@databricks/sdk-experimental": "^0.17.0",
|
|
33
|
-
"@dbx-tools/auth": "^0.9.
|
|
34
|
-
"@dbx-tools/cache": "^0.9.
|
|
35
|
-
"@dbx-tools/core": "^0.9.
|
|
36
|
-
"@dbx-tools/lakebase": "^0.9.
|
|
37
|
-
"@dbx-tools/postgres": "^0.9.
|
|
38
|
-
"@dbx-tools/shared-core": "^0.9.
|
|
39
|
-
"@dbx-tools/shared-fs": "^0.9.
|
|
33
|
+
"@dbx-tools/auth": "^0.9.122",
|
|
34
|
+
"@dbx-tools/cache": "^0.9.122",
|
|
35
|
+
"@dbx-tools/core": "^0.9.122",
|
|
36
|
+
"@dbx-tools/lakebase": "^0.9.122",
|
|
37
|
+
"@dbx-tools/postgres": "^0.9.122",
|
|
38
|
+
"@dbx-tools/shared-core": "^0.9.122",
|
|
39
|
+
"@dbx-tools/shared-fs": "^0.9.122",
|
|
40
40
|
"zod": "4.3.6"
|
|
41
41
|
},
|
|
42
42
|
"main": "./lib/index.js",
|
|
@@ -66,10 +66,6 @@
|
|
|
66
66
|
"types": "./lib/src/cache-storage.d.ts",
|
|
67
67
|
"default": "./lib/src/cache-storage.js"
|
|
68
68
|
},
|
|
69
|
-
"./child-process": {
|
|
70
|
-
"types": "./lib/src/child-process.d.ts",
|
|
71
|
-
"default": "./lib/src/child-process.js"
|
|
72
|
-
},
|
|
73
69
|
"./databricks": {
|
|
74
70
|
"types": "./lib/src/databricks.d.ts",
|
|
75
71
|
"default": "./lib/src/databricks.js"
|
|
@@ -133,7 +129,7 @@
|
|
|
133
129
|
"./package.json": "./package.json"
|
|
134
130
|
}
|
|
135
131
|
},
|
|
136
|
-
"version": "0.9.
|
|
132
|
+
"version": "0.9.122",
|
|
137
133
|
"types": "./lib/index.d.ts",
|
|
138
134
|
"dbxToolsConfig": {
|
|
139
135
|
"tags": [
|
|
@@ -162,10 +158,6 @@
|
|
|
162
158
|
"types": "./lib/src/cache-storage.d.ts",
|
|
163
159
|
"default": "./lib/src/cache-storage.js"
|
|
164
160
|
},
|
|
165
|
-
"./child-process": {
|
|
166
|
-
"types": "./lib/src/child-process.d.ts",
|
|
167
|
-
"default": "./lib/src/child-process.js"
|
|
168
|
-
},
|
|
169
161
|
"./databricks": {
|
|
170
162
|
"types": "./lib/src/databricks.d.ts",
|
|
171
163
|
"default": "./lib/src/databricks.js"
|
package/src/appkit.ts
CHANGED
|
@@ -36,11 +36,12 @@ import {
|
|
|
36
36
|
// publishes this subpath for exactly that type.
|
|
37
37
|
import type { PluginMap } from "@databricks/appkit/dist/shared/src/plugin";
|
|
38
38
|
import { profile as authProfile } from "@dbx-tools/auth";
|
|
39
|
-
import { asyncUtils,
|
|
39
|
+
import { asyncUtils, log } from "@dbx-tools/shared-core";
|
|
40
40
|
|
|
41
41
|
import { resolveAutoConfigurePolicy } from "./_auto-configure.ts";
|
|
42
42
|
import { loadBrandContext } from "./brand-context.ts";
|
|
43
43
|
import { createAppKitCacheStorage } from "./cache-storage.ts";
|
|
44
|
+
import { installAsUserDevelopmentPatch } from "./identity.ts";
|
|
44
45
|
import {
|
|
45
46
|
createInterceptorContext,
|
|
46
47
|
type Interceptor,
|
|
@@ -48,24 +49,11 @@ import {
|
|
|
48
49
|
lifecycleBridge,
|
|
49
50
|
type ResolvedAppEnv,
|
|
50
51
|
} from "./interceptor.ts";
|
|
51
|
-
import { installAsUserDevelopmentPatch } from "./identity.ts";
|
|
52
52
|
import { applyLakebaseEnv, type LakebaseConnection } from "./lakebase-resolver.ts";
|
|
53
53
|
import { provisionCacheSchema } from "./provision.ts";
|
|
54
54
|
|
|
55
55
|
const logger = log.logger("appkit");
|
|
56
56
|
|
|
57
|
-
/** Detect whether the current process is running as a deployed Databricks App. */
|
|
58
|
-
export function isDatabricksAppEnv(
|
|
59
|
-
source: Record<string, string | undefined> = process.env,
|
|
60
|
-
cwd: string = process.cwd(),
|
|
61
|
-
): boolean {
|
|
62
|
-
if (environmentUtils.isDatabricksAppEnv(source)) return true;
|
|
63
|
-
const normalized = cwd.replaceAll("\\", "/").replace(/\/+$/, "");
|
|
64
|
-
return (
|
|
65
|
-
normalized === "/app/python/source_code" || normalized.startsWith("/app/python/source_code/")
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
57
|
type AppKitCreateAppConfig = NonNullable<Parameters<typeof appkitCreateApp>[0]>;
|
|
70
58
|
type AppKitPlugins = NonNullable<AppKitCreateAppConfig["plugins"]>;
|
|
71
59
|
|
package/src/identity.ts
CHANGED
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
|
|
55
55
|
import { ConfigurationError, Plugin } from "@databricks/appkit";
|
|
56
56
|
import { configUtils } from "@dbx-tools/core";
|
|
57
|
-
import { log, stringUtils, token } from "@dbx-tools/shared-core";
|
|
57
|
+
import { errorUtils, log, stringUtils, token } from "@dbx-tools/shared-core";
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* Header the Databricks Apps front door forwards the caller's OBO token on.
|
|
@@ -194,7 +194,7 @@ export function installAsUserDevelopmentPatch(): void {
|
|
|
194
194
|
);
|
|
195
195
|
};
|
|
196
196
|
} catch (error) {
|
|
197
|
-
logger.debug("asUser development patch skipped", { error:
|
|
197
|
+
logger.debug("asUser development patch skipped", { error: errorUtils.toError(error) });
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
|
|
@@ -212,7 +212,10 @@ function withAsUserSkipWarnSuppressed<T>(req: HeaderBearing, fn: () => T): T {
|
|
|
212
212
|
}
|
|
213
213
|
const warn = console.warn;
|
|
214
214
|
console.warn = (...args: unknown[]) => {
|
|
215
|
-
if (
|
|
215
|
+
if (
|
|
216
|
+
!log.isLevelEnabled("debug") &&
|
|
217
|
+
args.some((value) => typeof value === "string" && value.includes(AS_USER_SKIP_WARN))
|
|
218
|
+
) {
|
|
216
219
|
return;
|
|
217
220
|
}
|
|
218
221
|
warn.apply(console, args as Parameters<typeof console.warn>);
|
package/src/provision.ts
CHANGED
|
@@ -22,9 +22,8 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
import { createLakebasePool, getWorkspaceClient, ValidationError } from "@databricks/appkit";
|
|
25
|
-
import { configUtils } from "@dbx-tools/core";
|
|
26
25
|
import { postgresConnectionOptions, quotePostgresIdentifier } from "@dbx-tools/postgres";
|
|
27
|
-
import { errorUtils, log } from "@dbx-tools/shared-core";
|
|
26
|
+
import { environmentUtils, errorUtils, log } from "@dbx-tools/shared-core";
|
|
28
27
|
|
|
29
28
|
const defaultLogger = log.logger("provision");
|
|
30
29
|
|
|
@@ -90,7 +89,7 @@ export async function provisionCacheSchema(
|
|
|
90
89
|
role: string | undefined,
|
|
91
90
|
logger: log.Logger = defaultLogger,
|
|
92
91
|
): Promise<void> {
|
|
93
|
-
if (
|
|
92
|
+
if (environmentUtils.isDatabricksAppEnv()) {
|
|
94
93
|
logger.debug("autopg: skip cache provisioning (inside a Databricks App)");
|
|
95
94
|
return;
|
|
96
95
|
}
|
package/src/tool-provider.ts
CHANGED
|
@@ -9,6 +9,12 @@ import {
|
|
|
9
9
|
type ToolRegistry,
|
|
10
10
|
} from "@databricks/appkit/beta";
|
|
11
11
|
|
|
12
|
+
/** Delivery options for one agent-tool progress event. */
|
|
13
|
+
export interface AgentToolProgressOptions {
|
|
14
|
+
/** Stream the event to active clients without persisting it in message history. */
|
|
15
|
+
readonly transient?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
/** Optional request state supplied by an agent host when dispatching a plugin tool. */
|
|
13
19
|
export interface AgentToolExecutionContext {
|
|
14
20
|
/** Resource identity associated with the current agent turn. */
|
|
@@ -16,7 +22,7 @@ export interface AgentToolExecutionContext {
|
|
|
16
22
|
/** Model endpoint selected for the current agent turn. */
|
|
17
23
|
readonly model?: string;
|
|
18
24
|
/** Best-effort progress sink validated by the hosting integration. */
|
|
19
|
-
readonly writeProgress?: (event: unknown) => Promise<void>;
|
|
25
|
+
readonly writeProgress?: (event: unknown, options?: AgentToolProgressOptions) => Promise<void>;
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
/**
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AppKit child-process lifecycle built on `@dbx-tools/core/exec`.
|
|
3
|
-
*
|
|
4
|
-
* @module
|
|
5
|
-
*/
|
|
6
|
-
import * as exec from "@dbx-tools/core/exec";
|
|
7
|
-
/** Spawn arguments accepted by {@link AppKitChildProcess}. */
|
|
8
|
-
export type AppKitSpawnArgs = exec.SpawnArgs<exec.ExecOptions>;
|
|
9
|
-
/** Context passed to one child-process readiness probe. */
|
|
10
|
-
export interface AppKitChildProcessHealthCheckContext {
|
|
11
|
-
/** Spawned process being checked. */
|
|
12
|
-
readonly process: exec.ChildProcessResult;
|
|
13
|
-
/** Aborts when shutdown begins or the readiness timeout expires. */
|
|
14
|
-
readonly signal: AbortSignal;
|
|
15
|
-
/** Zero-based readiness attempt. */
|
|
16
|
-
readonly attempt: number;
|
|
17
|
-
}
|
|
18
|
-
/** Return `true` when the spawned process is ready to serve callers. */
|
|
19
|
-
export type AppKitChildProcessHealthCheck = (context: AppKitChildProcessHealthCheckContext) => boolean | PromiseLike<boolean>;
|
|
20
|
-
/** Readiness and tree-shutdown policy for an AppKit child process. */
|
|
21
|
-
export interface AppKitChildProcessOptions extends exec.KillOptions {
|
|
22
|
-
/** Optional readiness probe polled after the process is spawned. */
|
|
23
|
-
healthCheck?: AppKitChildProcessHealthCheck;
|
|
24
|
-
/** Delay between readiness probes. Defaults to 200 milliseconds. */
|
|
25
|
-
healthCheckIntervalMs?: number;
|
|
26
|
-
/** Maximum time allowed for readiness. Defaults to 30 seconds. */
|
|
27
|
-
healthCheckTimeoutMs?: number;
|
|
28
|
-
}
|
|
29
|
-
/** Foreground signal policy for {@link AppKitChildProcess.run}. */
|
|
30
|
-
export interface AppKitChildProcessRunOptions {
|
|
31
|
-
/** Parent signals that trigger tree shutdown before being re-raised. */
|
|
32
|
-
signals?: readonly NodeJS.Signals[];
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Start and stop one AppKit-owned subprocess.
|
|
36
|
-
*
|
|
37
|
-
* The spawn arguments use {@link exec.ExecOptions}, including core exec's
|
|
38
|
-
* stdin, output capture, line handlers, exit checking, and trim policy.
|
|
39
|
-
* When configured, {@link AppKitChildProcessOptions.healthCheck} is polled
|
|
40
|
-
* until ready before {@link start} resolves. Shutdown aborts any active probe
|
|
41
|
-
* and delegates process-tree termination to {@link exec.kill}.
|
|
42
|
-
*/
|
|
43
|
-
export declare class AppKitChildProcess {
|
|
44
|
-
#private;
|
|
45
|
-
constructor(spawnArgs: AppKitSpawnArgs, options?: AppKitChildProcessOptions);
|
|
46
|
-
/** Current child handle, or `undefined` when no child is running. */
|
|
47
|
-
get process(): exec.ChildProcessResult | undefined;
|
|
48
|
-
/** Whether the current child has not reported an exit code or signal. */
|
|
49
|
-
get running(): boolean;
|
|
50
|
-
/** Spawn the child and resolve only after its optional readiness probe succeeds. */
|
|
51
|
-
start(): Promise<void>;
|
|
52
|
-
/**
|
|
53
|
-
* Start, await, and shut down one foreground child while preserving parent
|
|
54
|
-
* termination signals.
|
|
55
|
-
*/
|
|
56
|
-
run(options?: AppKitChildProcessRunOptions): Promise<exec.ExecResult>;
|
|
57
|
-
/**
|
|
58
|
-
* Abort readiness and stop the process tree once.
|
|
59
|
-
*
|
|
60
|
-
* An explicit non-`SIGKILL` signal runs only the graceful polling phase.
|
|
61
|
-
* Explicit `SIGKILL` skips directly to forced polling. Omitting the signal
|
|
62
|
-
* uses the configured graceful and forced policy.
|
|
63
|
-
*/
|
|
64
|
-
shutdown(signal?: NodeJS.Signals): Promise<void>;
|
|
65
|
-
}
|
package/lib/src/child-process.js
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AppKit child-process lifecycle built on `@dbx-tools/core/exec`.
|
|
3
|
-
*
|
|
4
|
-
* @module
|
|
5
|
-
*/
|
|
6
|
-
import * as exec from "@dbx-tools/core/exec";
|
|
7
|
-
import { asyncUtils } from "@dbx-tools/shared-core";
|
|
8
|
-
const DEFAULT_HEALTH_CHECK_INTERVAL_MS = 200;
|
|
9
|
-
const DEFAULT_HEALTH_CHECK_TIMEOUT_MS = 30_000;
|
|
10
|
-
const DEFAULT_RUN_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
11
|
-
/**
|
|
12
|
-
* Start and stop one AppKit-owned subprocess.
|
|
13
|
-
*
|
|
14
|
-
* The spawn arguments use {@link exec.ExecOptions}, including core exec's
|
|
15
|
-
* stdin, output capture, line handlers, exit checking, and trim policy.
|
|
16
|
-
* When configured, {@link AppKitChildProcessOptions.healthCheck} is polled
|
|
17
|
-
* until ready before {@link start} resolves. Shutdown aborts any active probe
|
|
18
|
-
* and delegates process-tree termination to {@link exec.kill}.
|
|
19
|
-
*/
|
|
20
|
-
export class AppKitChildProcess {
|
|
21
|
-
#spawnArgs;
|
|
22
|
-
#killOptions;
|
|
23
|
-
#healthCheck;
|
|
24
|
-
#healthCheckIntervalMs;
|
|
25
|
-
#healthCheckTimeoutMs;
|
|
26
|
-
#child;
|
|
27
|
-
#healthCheckController;
|
|
28
|
-
#shutdownPromise;
|
|
29
|
-
constructor(spawnArgs, options = {}) {
|
|
30
|
-
this.#spawnArgs = spawnArgs;
|
|
31
|
-
const { healthCheck, healthCheckIntervalMs = DEFAULT_HEALTH_CHECK_INTERVAL_MS, healthCheckTimeoutMs = DEFAULT_HEALTH_CHECK_TIMEOUT_MS, ...killOptions } = options;
|
|
32
|
-
this.#healthCheck = healthCheck;
|
|
33
|
-
this.#healthCheckIntervalMs = positiveMilliseconds(healthCheckIntervalMs, "healthCheckIntervalMs");
|
|
34
|
-
this.#healthCheckTimeoutMs = positiveMilliseconds(healthCheckTimeoutMs, "healthCheckTimeoutMs");
|
|
35
|
-
this.#killOptions = killOptions;
|
|
36
|
-
}
|
|
37
|
-
/** Current child handle, or `undefined` when no child is running. */
|
|
38
|
-
get process() {
|
|
39
|
-
return this.#child;
|
|
40
|
-
}
|
|
41
|
-
/** Whether the current child has not reported an exit code or signal. */
|
|
42
|
-
get running() {
|
|
43
|
-
return this.#child !== undefined && !hasExited(this.#child);
|
|
44
|
-
}
|
|
45
|
-
/** Spawn the child and resolve only after its optional readiness probe succeeds. */
|
|
46
|
-
start() {
|
|
47
|
-
if (this.running)
|
|
48
|
-
throw new Error("Child process is already running");
|
|
49
|
-
if (this.#shutdownPromise) {
|
|
50
|
-
throw new Error("Child process is shutting down or has been shut down");
|
|
51
|
-
}
|
|
52
|
-
const child = exec.spawn(...this.#spawnArgs);
|
|
53
|
-
const controller = new AbortController();
|
|
54
|
-
this.#child = child;
|
|
55
|
-
this.#healthCheckController = controller;
|
|
56
|
-
void child.once("close", () => {
|
|
57
|
-
if (this.#child === child)
|
|
58
|
-
this.#child = undefined;
|
|
59
|
-
});
|
|
60
|
-
return this.#completeStart(child, controller);
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Start, await, and shut down one foreground child while preserving parent
|
|
64
|
-
* termination signals.
|
|
65
|
-
*/
|
|
66
|
-
async run(options = {}) {
|
|
67
|
-
const signals = options.signals ?? DEFAULT_RUN_SIGNALS;
|
|
68
|
-
if (signals.includes("SIGKILL")) {
|
|
69
|
-
throw new Error("SIGKILL cannot be intercepted by a Node process");
|
|
70
|
-
}
|
|
71
|
-
const handlers = new Map();
|
|
72
|
-
let stopping = false;
|
|
73
|
-
const removeHandlers = () => {
|
|
74
|
-
for (const [signal, handler] of handlers)
|
|
75
|
-
process.off(signal, handler);
|
|
76
|
-
};
|
|
77
|
-
for (const signal of signals) {
|
|
78
|
-
const handler = () => {
|
|
79
|
-
if (stopping)
|
|
80
|
-
return;
|
|
81
|
-
stopping = true;
|
|
82
|
-
removeHandlers();
|
|
83
|
-
void this.shutdown()
|
|
84
|
-
.finally(() => process.kill(process.pid, signal))
|
|
85
|
-
.catch(() => undefined);
|
|
86
|
-
};
|
|
87
|
-
handlers.set(signal, handler);
|
|
88
|
-
process.once(signal, handler);
|
|
89
|
-
}
|
|
90
|
-
try {
|
|
91
|
-
await this.start();
|
|
92
|
-
const child = this.#child;
|
|
93
|
-
if (!child)
|
|
94
|
-
throw new Error("Child process exited after startup");
|
|
95
|
-
return await child;
|
|
96
|
-
}
|
|
97
|
-
finally {
|
|
98
|
-
removeHandlers();
|
|
99
|
-
await this.shutdown();
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Abort readiness and stop the process tree once.
|
|
104
|
-
*
|
|
105
|
-
* An explicit non-`SIGKILL` signal runs only the graceful polling phase.
|
|
106
|
-
* Explicit `SIGKILL` skips directly to forced polling. Omitting the signal
|
|
107
|
-
* uses the configured graceful and forced policy.
|
|
108
|
-
*/
|
|
109
|
-
shutdown(signal) {
|
|
110
|
-
this.#healthCheckController?.abort(new DOMException("Child process shutdown requested", "AbortError"));
|
|
111
|
-
const killOptions = signal === undefined
|
|
112
|
-
? this.#killOptions
|
|
113
|
-
: signal === "SIGKILL"
|
|
114
|
-
? { ...this.#killOptions, gracefulSignal: false, forceSignal: signal }
|
|
115
|
-
: { ...this.#killOptions, gracefulSignal: signal, forceSignal: false };
|
|
116
|
-
this.#shutdownPromise ??= this.#performShutdown(killOptions);
|
|
117
|
-
return this.#shutdownPromise;
|
|
118
|
-
}
|
|
119
|
-
async #completeStart(child, controller) {
|
|
120
|
-
try {
|
|
121
|
-
if (this.#healthCheck) {
|
|
122
|
-
await Promise.race([
|
|
123
|
-
this.#waitUntilHealthy(child, controller.signal),
|
|
124
|
-
child.then((result) => {
|
|
125
|
-
throw new Error(`Child process ${child.pid ?? "<unknown>"} exited before becoming ready ` +
|
|
126
|
-
`(exit ${result.exitCode})`);
|
|
127
|
-
}),
|
|
128
|
-
]);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
catch (error) {
|
|
132
|
-
try {
|
|
133
|
-
await this.shutdown();
|
|
134
|
-
}
|
|
135
|
-
catch (shutdownError) {
|
|
136
|
-
throw new AggregateError([error, shutdownError], `Child process ${child.pid ?? "<unknown>"} failed readiness and shutdown`);
|
|
137
|
-
}
|
|
138
|
-
throw error;
|
|
139
|
-
}
|
|
140
|
-
finally {
|
|
141
|
-
if (this.#healthCheckController === controller) {
|
|
142
|
-
this.#healthCheckController = undefined;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
async #waitUntilHealthy(child, signal) {
|
|
147
|
-
const healthCheck = this.#healthCheck;
|
|
148
|
-
if (!healthCheck)
|
|
149
|
-
return;
|
|
150
|
-
for await (const healthy of asyncUtils.poll(({ attempt, signal: pollSignal }) => healthCheck({ process: child, signal: pollSignal, attempt }), {
|
|
151
|
-
intervalMs: this.#healthCheckIntervalMs,
|
|
152
|
-
timeoutMs: this.#healthCheckTimeoutMs,
|
|
153
|
-
signal,
|
|
154
|
-
predicate: (healthy) => !healthy,
|
|
155
|
-
})) {
|
|
156
|
-
if (healthy)
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
async #performShutdown(options) {
|
|
161
|
-
const child = this.#child;
|
|
162
|
-
if (!child) {
|
|
163
|
-
this.#child = undefined;
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
await exec.kill(child, options);
|
|
167
|
-
if (this.#child === child)
|
|
168
|
-
this.#child = undefined;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
function hasExited(child) {
|
|
172
|
-
return child.exitCode !== null || child.signalCode !== null;
|
|
173
|
-
}
|
|
174
|
-
function positiveMilliseconds(value, name) {
|
|
175
|
-
if (!Number.isFinite(value) || value <= 0) {
|
|
176
|
-
throw new RangeError(`${name} must be a finite positive number`);
|
|
177
|
-
}
|
|
178
|
-
return value;
|
|
179
|
-
}
|
|
180
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hpbGQtcHJvY2Vzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jaGlsZC1wcm9jZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFDSCxPQUFPLEtBQUssSUFBSSxNQUFNLHNCQUFzQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUVwRCxNQUFNLGdDQUFnQyxHQUFHLEdBQUcsQ0FBQztBQUM3QyxNQUFNLCtCQUErQixHQUFHLE1BQU0sQ0FBQztBQUMvQyxNQUFNLG1CQUFtQixHQUFHLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQVUsQ0FBQztBQW9DckU7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLE9BQU8sa0JBQWtCO0lBQ3BCLFVBQVUsQ0FBa0I7SUFDNUIsWUFBWSxDQUFtQjtJQUMvQixZQUFZLENBQWlDO0lBQzdDLHNCQUFzQixDQUFTO0lBQy9CLHFCQUFxQixDQUFTO0lBRXZDLE1BQU0sQ0FBMkI7SUFDakMsc0JBQXNCLENBQW1CO0lBQ3pDLGdCQUFnQixDQUFpQjtJQUVqQyxZQUFZLFNBQTBCLEVBQUUsVUFBcUMsRUFBRTtRQUM3RSxJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQztRQUM1QixNQUFNLEVBQ0osV0FBVyxFQUNYLHFCQUFxQixHQUFHLGdDQUFnQyxFQUN4RCxvQkFBb0IsR0FBRywrQkFBK0IsRUFDdEQsR0FBRyxXQUFXLEVBQ2YsR0FBRyxPQUFPLENBQUM7UUFDWixJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztRQUNoQyxJQUFJLENBQUMsc0JBQXNCLEdBQUcsb0JBQW9CLENBQ2hELHFCQUFxQixFQUNyQix1QkFBdUIsQ0FDeEIsQ0FBQztRQUNGLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxvQkFBb0IsQ0FBQyxvQkFBb0IsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO1FBQ2hHLElBQUksQ0FBQyxZQUFZLEdBQUcs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TUFBTTtZQUNOLFNBQVMsRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPO1NBQ2pDLENBQ0YsRUFBRSxDQUFDO1lBQ0YsSUFBSSxPQUFPO2dCQUFFLE9BQU87UUFDdEIsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsZ0JBQWdCLENBQUMsT0FBeUI7UUFDOUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUMxQixJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQztZQUN4QixPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDaEMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLEtBQUs7WUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQztJQUNyRCxDQUFDO0NBQ0Y7QUFFRCxTQUFTLFNBQVMsQ0FBQyxLQUE4QjtJQUMvQyxPQUFPLEtBQUssQ0FBQyxRQUFRLEtBQUssSUFBSSxJQUFJLEtBQUssQ0FBQyxVQUFVLEtBQUssSUFBSSxDQUFDO0FBQzlELENBQUM7QUFFRCxTQUFTLG9CQUFvQixDQUFDLEtBQWEsRUFBRSxJQUFZO0lBQ3ZELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUMxQyxNQUFNLElBQUksVUFBVSxDQUFDLEdBQUcsSUFBSSxtQ0FBbUMsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEFwcEtpdCBjaGlsZC1wcm9jZXNzIGxpZmVjeWNsZSBidWlsdCBvbiBgQGRieC10b29scy9jb3JlL2V4ZWNgLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuaW1wb3J0ICogYXMgZXhlYyBmcm9tIFwiQGRieC10b29scy9jb3JlL2V4ZWNcIjtcbmltcG9ydCB7IGFzeW5jVXRpbHMgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuXG5jb25zdCBERUZBVUxUX0hFQUxUSF9DSEVDS19JTlRFUlZBTF9NUyA9IDIwMDtcbmNvbnN0IERFRkFVTFRfSEVBTFRIX0NIRUNLX1RJTUVPVVRfTVMgPSAzMF8wMDA7XG5jb25zdCBERUZBVUxUX1JVTl9TSUdOQUxTID0gW1wiU0lHSU5UXCIsIFwiU0lHVEVSTVwiLCBcIlNJR0hVUFwiXSBhcyBjb25zdDtcblxuLyoqIFNwYXduIGFyZ3VtZW50cyBhY2NlcHRlZCBieSB7QGxpbmsgQXBwS2l0Q2hpbGRQcm9jZXNzfS4gKi9cbmV4cG9ydCB0eXBlIEFwcEtpdFNwYXduQXJncyA9IGV4ZWMuU3Bhd25BcmdzPGV4ZWMuRXhlY09wdGlvbnM+O1xuXG4vKiogQ29udGV4dCBwYXNzZWQgdG8gb25lIGNoaWxkLXByb2Nlc3MgcmVhZGluZXNzIHByb2JlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcHBLaXRDaGlsZFByb2Nlc3NIZWFsdGhDaGVja0NvbnRleHQge1xuICAvKiogU3Bhd25lZCBwcm9jZXNzIGJlaW5nIGNoZWNrZWQuICovXG4gIHJlYWRvbmx5IHByb2Nlc3M6IGV4ZWMuQ2hpbGRQcm9jZXNzUmVzdWx0O1xuICAvKiogQWJvcnRzIHdoZW4gc2h1dGRvd24gYmVnaW5zIG9yIHRoZSByZWFkaW5lc3MgdGltZW91dCBleHBpcmVzLiAqL1xuICByZWFkb25seSBzaWduYWw6IEFib3J0U2lnbmFsO1xuICAvKiogWmVyby1iYXNlZCByZWFkaW5lc3MgYXR0ZW1wdC4gKi9cbiAgcmVhZG9ubHkgYXR0ZW1wdDogbnVtYmVyO1xufVxuXG4vKiogUmV0dXJuIGB0cnVlYCB3aGVuIHRoZSBzcGF3bmVkIHByb2Nlc3MgaXMgcmVhZHkgdG8gc2VydmUgY2FsbGVycy4gKi9cbmV4cG9ydCB0eXBlIEFwcEtpdENoaWxkUHJvY2Vzc0hlYWx0aENoZWNrID0gKFxuICBjb250ZXh0OiBBcHBLaXRDaGlsZFByb2Nlc3NIZWFsdGhDaGVja0NvbnRleHQsXG4pID0+IGJvb2xlYW4gfCBQcm9taXNlTGlrZTxib29sZWFuPjtcblxuLyoqIFJlYWRpbmVzcyBhbmQgdHJlZS1zaHV0ZG93biBwb2xpY3kgZm9yIGFuIEFwcEtpdCBjaGlsZCBwcm9jZXNzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcHBLaXRDaGlsZFByb2Nlc3NPcHRpb25zIGV4dGVuZHMgZXhlYy5LaWxsT3B0aW9ucyB7XG4gIC8qKiBPcHRpb25hbCByZWFkaW5lc3MgcHJvYmUgcG9sbGVkIGFmdGVyIHRoZSBwcm9jZXNzIGlzIHNwYXduZWQuICovXG4gIGhlYWx0aENoZWNrPzogQXBwS2l0Q2hpbGRQcm9jZXNzSGVhbHRoQ2hlY2s7XG4gIC8qKiBEZWxheSBiZXR3ZWVuIHJlYWRpbmVzcyBwcm9iZXMuIERlZmF1bHRzIHRvIDIwMCBtaWxsaXNlY29uZHMuICovXG4gIGhlYWx0aENoZWNrSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgLyoqIE1heGltdW0gdGltZSBhbGxvd2VkIGZvciByZWFkaW5lc3MuIERlZmF1bHRzIHRvIDMwIHNlY29uZHMuICovXG4gIGhlYWx0aENoZWNrVGltZW91dE1zPzogbnVtYmVyO1xufVxuXG4vKiogRm9yZWdyb3VuZCBzaWduYWwgcG9saWN5IGZvciB7QGxpbmsgQXBwS2l0Q2hpbGRQcm9jZXNzLnJ1bn0uICovXG5leHBvcnQgaW50ZXJmYWNlIEFwcEtpdENoaWxkUHJvY2Vzc1J1bk9wdGlvbnMge1xuICAvKiogUGFyZW50IHNpZ25hbHMgdGhhdCB0cmlnZ2VyIHRyZWUgc2h1dGRvd24gYmVmb3JlIGJlaW5nIHJlLXJhaXNlZC4gKi9cbiAgc2lnbmFscz86IHJlYWRvbmx5IE5vZGVKUy5TaWduYWxzW107XG59XG5cbi8qKlxuICogU3RhcnQgYW5kIHN0b3Agb25lIEFwcEtpdC1vd25lZCBzdWJwcm9jZXNzLlxuICpcbiAqIFRoZSBzcGF3biBhcmd1bWVudHMgdXNlIHtAbGluayBleGVjLkV4ZWNPcHRpb25zfSwgaW5jbHVkaW5nIGNvcmUgZXhlYydzXG4gKiBzdGRpbiwgb3V0cHV0IGNhcHR1cmUsIGxpbmUgaGFuZGxlcnMsIGV4aXQgY2hlY2tpbmcsIGFuZCB0cmltIHBvbGljeS5cbiAqIFdoZW4gY29uZmlndXJlZCwge0BsaW5rIEFwcEtpdENoaWxkUHJvY2Vzc09wdGlvbnMuaGVhbHRoQ2hlY2t9IGlzIHBvbGxlZFxuICogdW50aWwgcmVhZHkgYmVmb3JlIHtAbGluayBzdGFydH0gcmVzb2x2ZXMuIFNodXRkb3duIGFib3J0cyBhbnkgYWN0aXZlIHByb2JlXG4gKiBhbmQgZGVsZWdhdGVzIHByb2Nlc3MtdHJlZSB0ZXJtaW5hdGlvbiB0byB7QGxpbmsgZXhlYy5raWxsfS5cbiAqL1xuZXhwb3J0IGNsYXNzIEFwcEtpdENoaWxkUHJvY2VzcyB7XG4gIHJlYWRvbmx5ICNzcGF3bkFyZ3M6IEFwcEtpdFNwYXduQXJncztcbiAgcmVhZG9ubHkgI2tpbGxPcHRpb25zOiBleGVjLktpbGxPcHRpb25zO1xuICByZWFkb25seSAjaGVhbHRoQ2hlY2s/OiBBcHBLaXRDaGlsZFByb2Nlc3NIZWFsdGhDaGVjaztcbiAgcmVhZG9ubHkgI2hlYWx0aENoZWNrSW50ZXJ2YWxNczogbnVtYmVyO1xuICByZWFkb25seSAjaGVhbHRoQ2hlY2tUaW1lb3V0TXM6IG51bWJlcjtcblxuICAjY2hpbGQ/OiBleGVjLkNoaWxkUHJvY2Vzc1Jlc3VsdDtcbiAgI2hlYWx0aENoZWNrQ29udHJvbGxlcj86IEFib3J0Q29udHJvbGxlcjtcbiAgI3NodXRkb3duUHJvbWlzZT86IFByb21pc2U8dm9pZD47XG5cbiAgY29uc3RydWN0b3Ioc3Bhd25BcmdzOiBBcHBLaXRTcGF3bkFyZ3MsIG9wdGlvbnM6IEFwcEtpdENoaWxkUHJvY2Vzc09wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMuI3NwYXduQXJncyA9IHNwYXduQXJncztcbiAgICBjb25zdCB7XG4gICAgICBoZWFsdGhDaGVjayxcbiAgICAgIGhlYWx0aENoZWNrSW50ZXJ2YWxNcyA9IERFRkFVTFRfSEVBTFRIX0NIRUNLX0lOVEVSVkFMX01TLFxuICAgICAgaGVhbHRoQ2hlY2tUaW1lb3V0TXMgPSBERUZBVUxUX0hFQUxUSF9DSEVDS19USU1FT1VUX01TLFxuICAgICAgLi4ua2lsbE9wdGlvbnNcbiAgICB9ID0gb3B0aW9ucztcbiAgICB0aGlzLiNoZWFsdGhDaGVjayA9IGhlYWx0aENoZWNrO1xuICAgIHRoaXMuI2hlYWx0aENoZWNrSW50ZXJ2YWxNcyA9IHBvc2l0aXZlTWlsbGlzZWNvbmRzKFxuICAgICAgaGVhbHRoQ2hlY2tJbnRlcnZhbE1zLFxuICAgICAgXCJoZWFsdGhDaGVja0ludGVydmFsTXNcIixcbiAgICApO1xuICAgIHRoaXMuI2hlYWx0aENoZWNrVGltZW91dE1zID0gcG9zaXRpdmVNaWxsaXNlY29uZHMoaGVhbHRoQ2hlY2tUaW1lb3V0TXMsIFwiaGVhbHRoQ2hlY2tUaW1lb3V0TXNcIik7XG4gICAgdGhpcy4ja2lsbE9wdGlvbnMgPSBraWxsT3B0aW9ucztcbiAgfVxuXG4gIC8qKiBDdXJyZW50IGNoaWxkIGhhbmRsZSwgb3IgYHVuZGVmaW5lZGAgd2hlbiBubyBjaGlsZCBpcyBydW5uaW5nLiAqL1xuICBnZXQgcHJvY2VzcygpOiBleGVjLkNoaWxkUHJvY2Vzc1Jlc3VsdCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuI2NoaWxkO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgdGhlIGN1cnJlbnQgY2hpbGQgaGFzIG5vdCByZXBvcnRlZCBhbiBleGl0IGNvZGUgb3Igc2lnbmFsLiAqL1xuICBnZXQgcnVubmluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy4jY2hpbGQgIT09IHVuZGVmaW5lZCAmJiAhaGFzRXhpdGVkKHRoaXMuI2NoaWxkKTtcbiAgfVxuXG4gIC8qKiBTcGF3biB0aGUgY2hpbGQgYW5kIHJlc29sdmUgb25seSBhZnRlciBpdHMgb3B0aW9uYWwgcmVhZGluZXNzIHByb2JlIHN1Y2NlZWRzLiAqL1xuICBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5ydW5uaW5nKSB0aHJvdyBuZXcgRXJyb3IoXCJDaGlsZCBwcm9jZXNzIGlzIGFscmVhZHkgcnVubmluZ1wiKTtcbiAgICBpZiAodGhpcy4jc2h1dGRvd25Qcm9taXNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDaGlsZCBwcm9jZXNzIGlzIHNodXR0aW5nIGRvd24gb3IgaGFzIGJlZW4gc2h1dCBkb3duXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IGNoaWxkID0gZXhlYy5zcGF3biguLi50aGlzLiNzcGF3bkFyZ3MpO1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgdGhpcy4jY2hpbGQgPSBjaGlsZDtcbiAgICB0aGlzLiNoZWFsdGhDaGVja0NvbnRyb2xsZXIgPSBjb250cm9sbGVyO1xuICAgIHZvaWQgY2hpbGQub25jZShcImNsb3NlXCIsICgpID0+IHtcbiAgICAgIGlmICh0aGlzLiNjaGlsZCA9PT0gY2hpbGQpIHRoaXMuI2NoaWxkID0gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzLiNjb21wbGV0ZVN0YXJ0KGNoaWxkLCBjb250cm9sbGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCwgYXdhaXQsIGFuZCBzaHV0IGRvd24gb25lIGZvcmVncm91bmQgY2hpbGQgd2hpbGUgcHJlc2VydmluZyBwYXJlbnRcbiAgICogdGVybWluYXRpb24gc2lnbmFscy5cbiAgICovXG4gIGFzeW5jIHJ1bihvcHRpb25zOiBBcHBLaXRDaGlsZFByb2Nlc3NSdW5PcHRpb25zID0ge30pOiBQcm9taXNlPGV4ZWMuRXhlY1Jlc3VsdD4ge1xuICAgIGNvbnN0IHNpZ25hbHMgPSBvcHRpb25zLnNpZ25hbHMgPz8gREVGQVVMVF9SVU5fU0lHTkFMUztcbiAgICBpZiAoc2lnbmFscy5pbmNsdWRlcyhcIlNJR0tJTExcIikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNJR0tJTEwgY2Fubm90IGJlIGludGVyY2VwdGVkIGJ5IGEgTm9kZSBwcm9jZXNzXCIpO1xuICAgIH1cbiAgICBjb25zdCBoYW5kbGVycyA9IG5ldyBNYXA8Tm9kZUpTLlNpZ25hbHMsICgpID0+IHZvaWQ+KCk7XG4gICAgbGV0IHN0b3BwaW5nID0gZmFsc2U7XG4gICAgY29uc3QgcmVtb3ZlSGFuZGxlcnMgPSAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IFtzaWduYWwsIGhhbmRsZXJdIG9mIGhhbmRsZXJzKSBwcm9jZXNzLm9mZihzaWduYWwsIGhhbmRsZXIpO1xuICAgIH07XG4gICAgZm9yIChjb25zdCBzaWduYWwgb2Ygc2lnbmFscykge1xuICAgICAgY29uc3QgaGFuZGxlciA9ICgpID0+IHtcbiAgICAgICAgaWYgKHN0b3BwaW5nKSByZXR1cm47XG4gICAgICAgIHN0b3BwaW5nID0gdHJ1ZTtcbiAgICAgICAgcmVtb3ZlSGFuZGxlcnMoKTtcbiAgICAgICAgdm9pZCB0aGlzLnNodXRkb3duKClcbiAgICAgICAgICAuZmluYWxseSgoKSA9PiBwcm9jZXNzLmtpbGwocHJvY2Vzcy5waWQsIHNpZ25hbCkpXG4gICAgICAgICAgLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICB9O1xuICAgICAgaGFuZGxlcnMuc2V0KHNpZ25hbCwgaGFuZGxlcik7XG4gICAgICBwcm9jZXNzLm9uY2Uoc2lnbmFsLCBoYW5kbGVyKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5zdGFydCgpO1xuICAgICAgY29uc3QgY2hpbGQgPSB0aGlzLiNjaGlsZDtcbiAgICAgIGlmICghY2hpbGQpIHRocm93IG5ldyBFcnJvcihcIkNoaWxkIHByb2Nlc3MgZXhpdGVkIGFmdGVyIHN0YXJ0dXBcIik7XG4gICAgICByZXR1cm4gYXdhaXQgY2hpbGQ7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHJlbW92ZUhhbmRsZXJzKCk7XG4gICAgICBhd2FpdCB0aGlzLnNodXRkb3duKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFib3J0IHJlYWRpbmVzcyBhbmQgc3RvcCB0aGUgcHJvY2VzcyB0cmVlIG9uY2UuXG4gICAqXG4gICAqIEFuIGV4cGxpY2l0IG5vbi1gU0lHS0lMTGAgc2lnbmFsIHJ1bnMgb25seSB0aGUgZ3JhY2VmdWwgcG9sbGluZyBwaGFzZS5cbiAgICogRXhwbGljaXQgYFNJR0tJTExgIHNraXBzIGRpcmVjdGx5IHRvIGZvcmNlZCBwb2xsaW5nLiBPbWl0dGluZyB0aGUgc2lnbmFsXG4gICAqIHVzZXMgdGhlIGNvbmZpZ3VyZWQgZ3JhY2VmdWwgYW5kIGZvcmNlZCBwb2xpY3kuXG4gICAqL1xuICBzaHV0ZG93bihzaWduYWw/OiBOb2RlSlMuU2lnbmFscyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuI2hlYWx0aENoZWNrQ29udHJvbGxlcj8uYWJvcnQoXG4gICAgICBuZXcgRE9NRXhjZXB0aW9uKFwiQ2hpbGQgcHJvY2VzcyBzaHV0ZG93biByZXF1ZXN0ZWRcIiwgXCJBYm9ydEVycm9yXCIpLFxuICAgICk7XG4gICAgY29uc3Qga2lsbE9wdGlvbnM6IGV4ZWMuS2lsbE9wdGlvbnMgPVxuICAgICAgc2lnbmFsID09PSB1bmRlZmluZWRcbiAgICAgICAgPyB0aGlzLiNraWxsT3B0aW9uc1xuICAgICAgICA6IHNpZ25hbCA9PT0gXCJTSUdLSUxMXCJcbiAgICAgICAgICA/IHsgLi4udGhpcy4ja2lsbE9wdGlvbnMsIGdyYWNlZnVsU2lnbmFsOiBmYWxzZSwgZm9yY2VTaWduYWw6IHNpZ25hbCB9XG4gICAgICAgICAgOiB7IC4uLnRoaXMuI2tpbGxPcHRpb25zLCBncmFjZWZ1bFNpZ25hbDogc2lnbmFsLCBmb3JjZVNpZ25hbDogZmFsc2UgfTtcbiAgICB0aGlzLiNzaHV0ZG93blByb21pc2UgPz89IHRoaXMuI3BlcmZvcm1TaHV0ZG93bihraWxsT3B0aW9ucyk7XG4gICAgcmV0dXJuIHRoaXMuI3NodXRkb3duUHJvbWlzZTtcbiAgfVxuXG4gIGFzeW5jICNjb21wbGV0ZVN0YXJ0KGNoaWxkOiBleGVjLkNoaWxkUHJvY2Vzc1Jlc3VsdCwgY29udHJvbGxlcjogQWJvcnRDb250cm9sbGVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh0aGlzLiNoZWFsdGhDaGVjaykge1xuICAgICAgICBhd2FpdCBQcm9taXNlLnJhY2UoW1xuICAgICAgICAgIHRoaXMuI3dhaXRVbnRpbEhlYWx0aHkoY2hpbGQsIGNvbnRyb2xsZXIuc2lnbmFsKSxcbiAgICAgICAgICBjaGlsZC50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYENoaWxkIHByb2Nlc3MgJHtjaGlsZC5waWQgPz8gXCI8dW5rbm93bj5cIn0gZXhpdGVkIGJlZm9yZSBiZWNvbWluZyByZWFkeSBgICtcbiAgICAgICAgICAgICAgICBgKGV4aXQgJHtyZXN1bHQuZXhpdENvZGV9KWAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pLFxuICAgICAgICBdKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5zaHV0ZG93bigpO1xuICAgICAgfSBjYXRjaCAoc2h1dGRvd25FcnJvcikge1xuICAgICAgICB0aHJvdyBuZXcgQWdncmVnYXRlRXJyb3IoXG4gICAgICAgICAgW2Vycm9yLCBzaHV0ZG93bkVycm9yXSxcbiAgICAgICAgICBgQ2hpbGQgcHJvY2VzcyAke2NoaWxkLnBpZCA/PyBcIjx1bmtub3duPlwifSBmYWlsZWQgcmVhZGluZXNzIGFuZCBzaHV0ZG93bmAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKHRoaXMuI2hlYWx0aENoZWNrQ29udHJvbGxlciA9PT0gY29udHJvbGxlcikge1xuICAgICAgICB0aGlzLiNoZWFsdGhDaGVja0NvbnRyb2xsZXIgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgI3dhaXRVbnRpbEhlYWx0aHkoY2hpbGQ6IGV4ZWMuQ2hpbGRQcm9jZXNzUmVzdWx0LCBzaWduYWw6IEFib3J0U2lnbmFsKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgaGVhbHRoQ2hlY2sgPSB0aGlzLiNoZWFsdGhDaGVjaztcbiAgICBpZiAoIWhlYWx0aENoZWNrKSByZXR1cm47XG4gICAgZm9yIGF3YWl0IChjb25zdCBoZWFsdGh5IG9mIGFzeW5jVXRpbHMucG9sbChcbiAgICAgICh7IGF0dGVtcHQsIHNpZ25hbDogcG9sbFNpZ25hbCB9KSA9PlxuICAgICAgICBoZWFsdGhDaGVjayh7IHByb2Nlc3M6IGNoaWxkLCBzaWduYWw6IHBvbGxTaWduYWwsIGF0dGVtcHQgfSksXG4gICAgICB7XG4gICAgICAgIGludGVydmFsTXM6IHRoaXMuI2hlYWx0aENoZWNrSW50ZXJ2YWxNcyxcbiAgICAgICAgdGltZW91dE1zOiB0aGlzLiNoZWFsdGhDaGVja1RpbWVvdXRNcyxcbiAgICAgICAgc2lnbmFsLFxuICAgICAgICBwcmVkaWNhdGU6IChoZWFsdGh5KSA9PiAhaGVhbHRoeSxcbiAgICAgIH0sXG4gICAgKSkge1xuICAgICAgaWYgKGhlYWx0aHkpIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBhc3luYyAjcGVyZm9ybVNodXRkb3duKG9wdGlvbnM6IGV4ZWMuS2lsbE9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjaGlsZCA9IHRoaXMuI2NoaWxkO1xuICAgIGlmICghY2hpbGQpIHtcbiAgICAgIHRoaXMuI2NoaWxkID0gdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGF3YWl0IGV4ZWMua2lsbChjaGlsZCwgb3B0aW9ucyk7XG4gICAgaWYgKHRoaXMuI2NoaWxkID09PSBjaGlsZCkgdGhpcy4jY2hpbGQgPSB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFzRXhpdGVkKGNoaWxkOiBleGVjLkNoaWxkUHJvY2Vzc1Jlc3VsdCk6IGJvb2xlYW4ge1xuICByZXR1cm4gY2hpbGQuZXhpdENvZGUgIT09IG51bGwgfHwgY2hpbGQuc2lnbmFsQ29kZSAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gcG9zaXRpdmVNaWxsaXNlY29uZHModmFsdWU6IG51bWJlciwgbmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgaWYgKCFOdW1iZXIuaXNGaW5pdGUodmFsdWUpIHx8IHZhbHVlIDw9IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgJHtuYW1lfSBtdXN0IGJlIGEgZmluaXRlIHBvc2l0aXZlIG51bWJlcmApO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cbiJdfQ==
|