@vscode/component-explorer-cli 0.1.1-6 → 0.1.1-8
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 +4 -5
- package/dist/commands/compareCommand.d.ts +0 -3
- package/dist/commands/compareCommand.d.ts.map +1 -1
- package/dist/commands/compareCommand.js +18 -210
- package/dist/commands/compareCommand.js.map +1 -1
- package/dist/commands/mcpCommand.d.ts +2 -0
- package/dist/commands/mcpCommand.d.ts.map +1 -1
- package/dist/commands/mcpCommand.js +35 -6
- package/dist/commands/mcpCommand.js.map +1 -1
- package/dist/commands/screenshotCommand.d.ts.map +1 -1
- package/dist/commands/screenshotCommand.js +21 -75
- package/dist/commands/screenshotCommand.js.map +1 -1
- package/dist/commands/serveCommand.d.ts +3 -0
- package/dist/commands/serveCommand.d.ts.map +1 -1
- package/dist/commands/serveCommand.js +52 -3
- package/dist/commands/serveCommand.js.map +1 -1
- package/dist/comparison.d.ts +60 -0
- package/dist/comparison.d.ts.map +1 -0
- package/dist/comparison.js +250 -0
- package/dist/comparison.js.map +1 -0
- package/dist/component-explorer-config.schema.json +183 -0
- package/dist/componentExplorer.d.ts +13 -0
- package/dist/componentExplorer.d.ts.map +1 -1
- package/dist/componentExplorer.js +65 -2
- package/dist/componentExplorer.js.map +1 -1
- package/dist/daemon/DaemonService.d.ts +55 -4
- package/dist/daemon/DaemonService.d.ts.map +1 -1
- package/dist/daemon/DaemonService.js +139 -8
- package/dist/daemon/DaemonService.js.map +1 -1
- package/dist/daemon/lifecycle.js +3 -3
- package/dist/daemon/lifecycle.js.map +1 -1
- package/dist/daemon/pipeClient.js +3 -3
- package/dist/daemon/pipeClient.js.map +1 -1
- package/dist/daemon/pipeServer.js +2 -2
- package/dist/daemon/pipeServer.js.map +1 -1
- package/dist/dependencyInstaller.js +1 -1
- package/dist/dependencyInstaller.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/disposables.js +24 -1
- package/dist/external/vscode-observables/observables/dist/disposables.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/commonFacade/deps.js +1 -4
- package/dist/external/vscode-observables/observables/dist/observableInternal/commonFacade/deps.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/index.js +2 -5
- package/dist/external/vscode-observables/observables/dist/observableInternal/index.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/consoleObservableLogger.js +30 -6
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/consoleObservableLogger.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/observables/baseObservable.js +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/observables/baseObservable.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/observables/derived.js +12 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/observables/derived.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/utils/utilsCancellation.js +55 -0
- package/dist/external/vscode-observables/observables/dist/observableInternal/utils/utilsCancellation.js.map +1 -0
- package/dist/git/gitUtils.js +1 -1
- package/dist/git/gitUtils.js.map +1 -1
- package/dist/mcp/McpServer.d.ts +30 -4
- package/dist/mcp/McpServer.d.ts.map +1 -1
- package/dist/mcp/McpServer.js +435 -80
- package/dist/mcp/McpServer.js.map +1 -1
- package/dist/packages/simple-api/dist/{chunk-A5PE72HI.js → chunk-Q24JOMNK.js} +7 -1
- package/dist/packages/simple-api/dist/chunk-Q24JOMNK.js.map +1 -0
- package/dist/utils.d.ts +24 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +50 -0
- package/dist/utils.js.map +1 -0
- package/dist/watchConfig.d.ts +36 -0
- package/dist/watchConfig.d.ts.map +1 -1
- package/dist/watchConfig.js +32 -22
- package/dist/watchConfig.js.map +1 -1
- package/package.json +6 -4
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/debuggerRpc.js +0 -72
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/debuggerRpc.js.map +0 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/devToolsLogger.js +0 -447
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/devToolsLogger.js.map +0 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/rpc.js +0 -64
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/rpc.js.map +0 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/utils.js +0 -52
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/utils.js.map +0 -1
- package/dist/packages/simple-api/dist/chunk-A5PE72HI.js.map +0 -1
|
@@ -5,6 +5,7 @@ export interface FixtureInfo {
|
|
|
5
5
|
readonly fixtureId: string;
|
|
6
6
|
readonly fixtureName: string;
|
|
7
7
|
readonly groupPath: string[];
|
|
8
|
+
readonly background: 'light' | 'dark';
|
|
8
9
|
}
|
|
9
10
|
export type FixtureId = {
|
|
10
11
|
readonly fixtureId: string;
|
|
@@ -48,9 +49,19 @@ export interface ScreenshotResult {
|
|
|
48
49
|
readonly image: Uint8Array;
|
|
49
50
|
readonly errors: ErrorInfo[];
|
|
50
51
|
}
|
|
52
|
+
export interface StabilityScreenshot {
|
|
53
|
+
readonly image: Uint8Array;
|
|
54
|
+
readonly delayMs: number;
|
|
55
|
+
}
|
|
56
|
+
export interface StabilityCheckResult {
|
|
57
|
+
readonly screenshots: readonly StabilityScreenshot[];
|
|
58
|
+
readonly errors: ErrorInfo[];
|
|
59
|
+
}
|
|
51
60
|
export interface ComponentExplorer {
|
|
52
61
|
listFixtures(): Promise<FixtureInfo[]>;
|
|
53
62
|
screenshotFixture(fixtureId: string): Promise<ScreenshotResult>;
|
|
63
|
+
screenshotFixtureStabilityCheck(fixtureId: string): Promise<StabilityCheckResult>;
|
|
64
|
+
evaluateJs(expression: string, fixtureId?: string): Promise<unknown>;
|
|
54
65
|
codeCoverage(id: FixtureId | FixtureGroupId): Promise<CoverageData>;
|
|
55
66
|
waitForUpdate(timeoutMs?: number): Promise<void>;
|
|
56
67
|
dispose(): Promise<void>;
|
|
@@ -68,6 +79,8 @@ export declare class BrowserComponentExplorer implements ComponentExplorer {
|
|
|
68
79
|
private _getState;
|
|
69
80
|
listFixtures(): Promise<FixtureInfo[]>;
|
|
70
81
|
screenshotFixture(fixtureId: string): Promise<ScreenshotResult>;
|
|
82
|
+
screenshotFixtureStabilityCheck(fixtureId: string): Promise<StabilityCheckResult>;
|
|
83
|
+
evaluateJs(expression: string, fixtureId?: string): Promise<unknown>;
|
|
71
84
|
codeCoverage(_id: FixtureId | FixtureGroupId): Promise<CoverageData>;
|
|
72
85
|
waitForUpdate(timeoutMs?: number): Promise<void>;
|
|
73
86
|
dispose(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"componentExplorer.d.ts","sourceRoot":"","sources":["../src/componentExplorer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,KAAK,OAAO,EAAc,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"componentExplorer.d.ts","sourceRoot":"","sources":["../src/componentExplorer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { nullLogger } from './logger.js';
|
|
2
|
+
import { buildExplorerUrl } from './utils.js';
|
|
2
3
|
|
|
3
4
|
class BrowserComponentExplorer {
|
|
4
5
|
_browserPageFactory;
|
|
@@ -14,7 +15,7 @@ class BrowserComponentExplorer {
|
|
|
14
15
|
}
|
|
15
16
|
async _ensureReady() {
|
|
16
17
|
if (!this._page) {
|
|
17
|
-
const cliUrl = this._server.url
|
|
18
|
+
const cliUrl = buildExplorerUrl({ baseUrl: this._server.url, rawRender: true });
|
|
18
19
|
this._logger.log(`Opening browser page: ${cliUrl}`);
|
|
19
20
|
this._page = await this._browserPageFactory.openPage(cliUrl);
|
|
20
21
|
await this._waitForCliApi(this._page);
|
|
@@ -54,7 +55,7 @@ class BrowserComponentExplorer {
|
|
|
54
55
|
try {
|
|
55
56
|
const page = await this._ensureReady();
|
|
56
57
|
const escapedId = JSON.stringify(fixtureId);
|
|
57
|
-
const debugUrl =
|
|
58
|
+
const debugUrl = buildExplorerUrl({ baseUrl: this._server.url, rawRender: true, fixtureId });
|
|
58
59
|
this._logger.log(`Rendering fixture: ${debugUrl}`);
|
|
59
60
|
// renderFixture now returns { errors: ErrorInfo[] }
|
|
60
61
|
const renderResult = await page.evaluateJs(`window.__componentExplorerCli__.renderFixture(${escapedId})`);
|
|
@@ -65,6 +66,68 @@ class BrowserComponentExplorer {
|
|
|
65
66
|
resolve();
|
|
66
67
|
}
|
|
67
68
|
}
|
|
69
|
+
async screenshotFixtureStabilityCheck(fixtureId) {
|
|
70
|
+
const prev = this._screenshotMutex;
|
|
71
|
+
let resolve;
|
|
72
|
+
this._screenshotMutex = new Promise(r => { resolve = r; });
|
|
73
|
+
await prev;
|
|
74
|
+
try {
|
|
75
|
+
const page = await this._ensureReady();
|
|
76
|
+
const escapedId = JSON.stringify(fixtureId);
|
|
77
|
+
const debugUrl = buildExplorerUrl({ baseUrl: this._server.url, rawRender: true, fixtureId });
|
|
78
|
+
this._logger.log(`Stability check: ${debugUrl}`);
|
|
79
|
+
// Dispose current fixture first to test initial mounting stability
|
|
80
|
+
await page.evaluateJs(`window.__componentExplorerCli__.disposeCurrentFixture?.()`);
|
|
81
|
+
const startTime = Date.now();
|
|
82
|
+
const renderResult = await page.evaluateJs(`window.__componentExplorerCli__.renderFixture(${escapedId})`);
|
|
83
|
+
// Screenshot at t≈0 (immediately after render)
|
|
84
|
+
const domExpr = `document.getElementById('root').lastElementChild`;
|
|
85
|
+
const image0 = await page.screenshot(domExpr);
|
|
86
|
+
const delay0 = Date.now() - startTime;
|
|
87
|
+
// Wait until 500ms from start
|
|
88
|
+
const elapsed1 = Date.now() - startTime;
|
|
89
|
+
if (elapsed1 < 500) {
|
|
90
|
+
await new Promise(r => setTimeout(r, 500 - elapsed1));
|
|
91
|
+
}
|
|
92
|
+
const image1 = await page.screenshot(domExpr);
|
|
93
|
+
const delay1 = Date.now() - startTime;
|
|
94
|
+
// Wait until 3000ms from start
|
|
95
|
+
const elapsed2 = Date.now() - startTime;
|
|
96
|
+
if (elapsed2 < 3000) {
|
|
97
|
+
await new Promise(r => setTimeout(r, 3000 - elapsed2));
|
|
98
|
+
}
|
|
99
|
+
const image2 = await page.screenshot(domExpr);
|
|
100
|
+
const delay2 = Date.now() - startTime;
|
|
101
|
+
return {
|
|
102
|
+
screenshots: [
|
|
103
|
+
{ image: image0, delayMs: delay0 },
|
|
104
|
+
{ image: image1, delayMs: delay1 },
|
|
105
|
+
{ image: image2, delayMs: delay2 },
|
|
106
|
+
],
|
|
107
|
+
errors: renderResult.errors,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
resolve();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async evaluateJs(expression, fixtureId) {
|
|
115
|
+
const prev = this._screenshotMutex;
|
|
116
|
+
let resolve;
|
|
117
|
+
this._screenshotMutex = new Promise(r => { resolve = r; });
|
|
118
|
+
await prev;
|
|
119
|
+
try {
|
|
120
|
+
const page = await this._ensureReady();
|
|
121
|
+
if (fixtureId !== undefined) {
|
|
122
|
+
const escapedId = JSON.stringify(fixtureId);
|
|
123
|
+
await page.evaluateJs(`window.__componentExplorerCli__.renderFixture(${escapedId})`);
|
|
124
|
+
}
|
|
125
|
+
return await page.evaluateJs(expression);
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
resolve();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
68
131
|
async codeCoverage(_id) {
|
|
69
132
|
throw new Error('Code coverage not yet implemented');
|
|
70
133
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"componentExplorer.js","sources":["../src/componentExplorer.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"componentExplorer.js","sources":["../src/componentExplorer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,25 @@
|
|
|
1
|
+
import { type IDisposable, type IReader } from '@vscode/observables';
|
|
1
2
|
import { AsyncStream } from '@hediet/simple-api';
|
|
2
3
|
import { ExplorerSession } from '../explorerSession.js';
|
|
3
4
|
import type { ResolvedWatchConfig } from '../watchConfig.js';
|
|
4
5
|
import { type ILogger } from '../logger.js';
|
|
5
6
|
import { type ApprovalStore } from './approvalStore.js';
|
|
7
|
+
export declare class ActivityTracker implements IDisposable {
|
|
8
|
+
private readonly _idleTimeoutMs;
|
|
9
|
+
private readonly _onIdle;
|
|
10
|
+
private readonly _logger;
|
|
11
|
+
private _lastActivityTime;
|
|
12
|
+
private _idleCheckInterval;
|
|
13
|
+
private _autorunDisposable;
|
|
14
|
+
private _disposed;
|
|
15
|
+
private _started;
|
|
16
|
+
private _activeCount;
|
|
17
|
+
constructor(_idleTimeoutMs: number, _onIdle: () => void, _logger: ILogger);
|
|
18
|
+
setActive(value: boolean): void;
|
|
19
|
+
reportActivity(): void;
|
|
20
|
+
start(): void;
|
|
21
|
+
dispose(): void;
|
|
22
|
+
}
|
|
6
23
|
export type DaemonEvent = {
|
|
7
24
|
readonly type: 'source-change';
|
|
8
25
|
readonly sessionName: string;
|
|
@@ -16,12 +33,17 @@ export type DaemonEvent = {
|
|
|
16
33
|
readonly level: 'info' | 'debug' | 'trace';
|
|
17
34
|
readonly message: string;
|
|
18
35
|
};
|
|
19
|
-
export
|
|
36
|
+
export type SessionInfo = {
|
|
20
37
|
readonly name: string;
|
|
21
38
|
readonly sourceKind: 'current' | 'worktree';
|
|
39
|
+
readonly isLoading: true;
|
|
40
|
+
} | {
|
|
41
|
+
readonly name: string;
|
|
42
|
+
readonly sourceKind: 'current' | 'worktree';
|
|
43
|
+
readonly isLoading?: false;
|
|
22
44
|
readonly serverUrl: string;
|
|
23
45
|
readonly sourceTreeId: string;
|
|
24
|
-
}
|
|
46
|
+
};
|
|
25
47
|
export declare class SourceTreeChangedError extends Error {
|
|
26
48
|
constructor(sessionName: string);
|
|
27
49
|
}
|
|
@@ -35,9 +57,11 @@ export declare class DaemonService {
|
|
|
35
57
|
private readonly _sessions;
|
|
36
58
|
private readonly _sessionConfigs;
|
|
37
59
|
private readonly _resolvers;
|
|
60
|
+
private readonly _eventListenerCount;
|
|
38
61
|
private readonly _eventListeners;
|
|
39
62
|
private _shutdownRequested;
|
|
40
63
|
private _shutdownResolvers;
|
|
64
|
+
private readonly _activityTracker;
|
|
41
65
|
readonly approvals: ApprovalStore;
|
|
42
66
|
readonly api: import("@hediet/simple-api").ApiImplementation<import("@hediet/simple-api").MapMethods<{
|
|
43
67
|
fixtures: import("@hediet/simple-api").ApiImplementation<import("@hediet/simple-api").MapMethods<{
|
|
@@ -52,11 +76,25 @@ export declare class DaemonService {
|
|
|
52
76
|
sourceTreeId: string;
|
|
53
77
|
sessionName: string;
|
|
54
78
|
includeImage?: boolean | undefined;
|
|
79
|
+
stabilityCheck?: boolean | undefined;
|
|
55
80
|
}, {
|
|
56
81
|
hash: string;
|
|
57
82
|
sourceTreeId: string;
|
|
58
83
|
image: string | undefined;
|
|
59
84
|
errors: import("../componentExplorer.js").ErrorInfo[] | undefined;
|
|
85
|
+
isStable: boolean;
|
|
86
|
+
stabilityScreenshots: {
|
|
87
|
+
hash: string;
|
|
88
|
+
delayMs: number;
|
|
89
|
+
image: string | undefined;
|
|
90
|
+
}[];
|
|
91
|
+
} | {
|
|
92
|
+
hash: string;
|
|
93
|
+
sourceTreeId: string;
|
|
94
|
+
image: string | undefined;
|
|
95
|
+
errors: import("../componentExplorer.js").ErrorInfo[] | undefined;
|
|
96
|
+
isStable?: undefined;
|
|
97
|
+
stabilityScreenshots?: undefined;
|
|
60
98
|
}, undefined>;
|
|
61
99
|
takeBatch: import("@hediet/simple-api").IMethod<{
|
|
62
100
|
fixtureIds: string[];
|
|
@@ -111,15 +149,28 @@ export declare class DaemonService {
|
|
|
111
149
|
modifiedHash: string;
|
|
112
150
|
}, import("./approvalStore.js").ApprovalInfo | null, undefined>;
|
|
113
151
|
}>, undefined>;
|
|
152
|
+
evaluate: import("@hediet/simple-api").IMethod<{
|
|
153
|
+
sessionName: string;
|
|
154
|
+
sourceTreeId: string;
|
|
155
|
+
expression: string;
|
|
156
|
+
fixtureId?: string | undefined;
|
|
157
|
+
}, {
|
|
158
|
+
result: unknown;
|
|
159
|
+
}, undefined>;
|
|
114
160
|
events: import("@hediet/simple-api").IMethod<Record<string, never>, AsyncStream<DaemonEvent>, undefined>;
|
|
115
161
|
sessions: import("@hediet/simple-api").IMethod<Record<string, never>, SessionInfo[], undefined>;
|
|
116
162
|
shutdown: import("@hediet/simple-api").IMethod<Record<string, never>, void, undefined>;
|
|
117
163
|
}>, undefined>;
|
|
118
164
|
private constructor();
|
|
119
|
-
static create(config: ResolvedWatchConfig, logger: ILogger, pipeName?: string
|
|
165
|
+
static create(config: ResolvedWatchConfig, logger: ILogger, pipeName?: string, options?: {
|
|
166
|
+
idleTimeoutMs?: number;
|
|
167
|
+
}): Promise<DaemonService>;
|
|
120
168
|
private _buildApi;
|
|
121
169
|
getSession(name: string): ExplorerSession;
|
|
122
|
-
getSessionInfos(): SessionInfo[];
|
|
170
|
+
getSessionInfos(reader?: IReader): SessionInfo[];
|
|
171
|
+
waitForSession(sessionName: string | undefined): Promise<SessionInfo & {
|
|
172
|
+
isLoading?: false;
|
|
173
|
+
}>;
|
|
123
174
|
getSourceTreeId(sessionName: string): string;
|
|
124
175
|
assertSourceTreeId(sessionName: string, expected: string): void;
|
|
125
176
|
eventStream(): AsyncIterable<DaemonEvent>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DaemonService.d.ts","sourceRoot":"","sources":["../../src/daemon/DaemonService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DaemonService.d.ts","sourceRoot":"","sources":["../../src/daemon/DaemonService.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import '../external/vscode-observables/observables/dist/observableInternal/index.js';
|
|
3
|
+
import { observableValue } from '../external/vscode-observables/observables/dist/observableInternal/observables/observableValue.js';
|
|
3
4
|
import '../external/vscode-observables/observables/dist/observableInternal/debugLocation.js';
|
|
4
5
|
import { autorun } from '../external/vscode-observables/observables/dist/observableInternal/reactions/autorun.js';
|
|
5
|
-
import '../external/vscode-observables/observables/dist/observableInternal/observables/derived.js';
|
|
6
|
+
import { derived } from '../external/vscode-observables/observables/dist/observableInternal/observables/derived.js';
|
|
7
|
+
import { waitForState } from '../external/vscode-observables/observables/dist/observableInternal/utils/utilsCancellation.js';
|
|
6
8
|
import '../external/vscode-observables/observables/dist/observableInternal/utils/utils.js';
|
|
7
9
|
import '../external/vscode-observables/observables/dist/observableInternal/observables/observableFromEvent.js';
|
|
8
10
|
import { createApiFactory } from '../packages/simple-api/dist/chunk-3R7GHWBM.js';
|
|
@@ -14,6 +16,63 @@ import { installDependencies } from '../dependencyInstaller.js';
|
|
|
14
16
|
import { FileApprovalStore } from './approvalStore.js';
|
|
15
17
|
import { contentHash } from '../screenshotCache.js';
|
|
16
18
|
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// ActivityTracker — monitors idle time and triggers shutdown
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
class ActivityTracker {
|
|
23
|
+
_idleTimeoutMs;
|
|
24
|
+
_onIdle;
|
|
25
|
+
_logger;
|
|
26
|
+
_lastActivityTime = Date.now();
|
|
27
|
+
_idleCheckInterval;
|
|
28
|
+
_autorunDisposable;
|
|
29
|
+
_disposed = false;
|
|
30
|
+
_started = false;
|
|
31
|
+
_activeCount = 0;
|
|
32
|
+
constructor(_idleTimeoutMs, _onIdle, _logger) {
|
|
33
|
+
this._idleTimeoutMs = _idleTimeoutMs;
|
|
34
|
+
this._onIdle = _onIdle;
|
|
35
|
+
this._logger = _logger;
|
|
36
|
+
}
|
|
37
|
+
setActive(value) {
|
|
38
|
+
if (value) {
|
|
39
|
+
this._activeCount++;
|
|
40
|
+
this._lastActivityTime = Date.now();
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
this._activeCount = Math.max(0, this._activeCount - 1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
reportActivity() {
|
|
47
|
+
this._lastActivityTime = Date.now();
|
|
48
|
+
}
|
|
49
|
+
start() {
|
|
50
|
+
if (this._started || this._disposed || this._idleTimeoutMs <= 0) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
this._started = true;
|
|
54
|
+
const checkIntervalMs = Math.min(30_000, this._idleTimeoutMs / 2);
|
|
55
|
+
this._idleCheckInterval = setInterval(() => {
|
|
56
|
+
if (this._activeCount > 0) {
|
|
57
|
+
this._lastActivityTime = Date.now();
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const idleMs = Date.now() - this._lastActivityTime;
|
|
61
|
+
if (idleMs >= this._idleTimeoutMs) {
|
|
62
|
+
this._logger.log(`Idle for ${Math.round(idleMs / 1000)}s, shutting down`);
|
|
63
|
+
this._onIdle();
|
|
64
|
+
}
|
|
65
|
+
}, checkIntervalMs);
|
|
66
|
+
}
|
|
67
|
+
dispose() {
|
|
68
|
+
this._disposed = true;
|
|
69
|
+
this._autorunDisposable?.dispose();
|
|
70
|
+
if (this._idleCheckInterval) {
|
|
71
|
+
clearInterval(this._idleCheckInterval);
|
|
72
|
+
this._idleCheckInterval = undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
17
76
|
class SourceTreeChangedError extends Error {
|
|
18
77
|
constructor(sessionName) {
|
|
19
78
|
super(`Source tree changed for session "${sessionName}" — retry with latest sourceTreeId`);
|
|
@@ -32,27 +91,31 @@ class DaemonService {
|
|
|
32
91
|
_sessions = new Map();
|
|
33
92
|
_sessionConfigs = new Map();
|
|
34
93
|
_resolvers = new Map();
|
|
94
|
+
_eventListenerCount = observableValue(this, 0);
|
|
35
95
|
_eventListeners = new Set();
|
|
36
96
|
_shutdownRequested = false;
|
|
37
97
|
_shutdownResolvers = [];
|
|
98
|
+
_activityTracker;
|
|
38
99
|
approvals;
|
|
39
100
|
api;
|
|
40
|
-
constructor(_config, _pipeName, _logger, _browserFactory, _serverFactory, approvalStorePath) {
|
|
101
|
+
constructor(_config, _pipeName, _logger, _browserFactory, _serverFactory, approvalStorePath, idleTimeoutMs) {
|
|
41
102
|
this._config = _config;
|
|
42
103
|
this._pipeName = _pipeName;
|
|
43
104
|
this._logger = _logger;
|
|
44
105
|
this._browserFactory = _browserFactory;
|
|
45
106
|
this._serverFactory = _serverFactory;
|
|
46
107
|
this.approvals = new FileApprovalStore(approvalStorePath);
|
|
108
|
+
this._activityTracker = new ActivityTracker(idleTimeoutMs, () => this.requestShutdown(), this._logger);
|
|
47
109
|
this.api = this._buildApi();
|
|
48
110
|
}
|
|
49
|
-
static async create(config, logger, pipeName) {
|
|
111
|
+
static async create(config, logger, pipeName, options) {
|
|
50
112
|
const browserFactory = new PlaywrightBrowserPageFactory();
|
|
51
113
|
const serverFactory = new DefaultComponentExplorerHttpServerFactory();
|
|
52
114
|
const approvalStorePath = `${config.screenshotDir}/approvals.json`;
|
|
115
|
+
const idleTimeoutMs = options?.idleTimeoutMs ?? 5 * 60 * 1000; // 5 minutes default
|
|
53
116
|
// Wrap the logger so messages also appear on the event stream
|
|
54
117
|
const eventStreamLogger = new EventStreamLogger(logger);
|
|
55
|
-
const svc = new DaemonService(config, pipeName ?? '', eventStreamLogger, browserFactory, serverFactory, approvalStorePath);
|
|
118
|
+
const svc = new DaemonService(config, pipeName ?? '', eventStreamLogger, browserFactory, serverFactory, approvalStorePath, idleTimeoutMs);
|
|
56
119
|
eventStreamLogger._emitter = (event) => svc._emit(event);
|
|
57
120
|
const currentSession = config.sessions.find(s => s.source.kind === 'current');
|
|
58
121
|
const resolveViteFrom = currentSession?.viteProject.cwd;
|
|
@@ -73,6 +136,7 @@ class DaemonService {
|
|
|
73
136
|
sourceTreeId: z.string(),
|
|
74
137
|
},
|
|
75
138
|
}, async (args) => {
|
|
139
|
+
this._activityTracker.reportActivity();
|
|
76
140
|
this.assertSourceTreeId(args.sessionName, args.sourceTreeId);
|
|
77
141
|
const session = this.getSession(args.sessionName);
|
|
78
142
|
const result = await session.explorer.listFixtures();
|
|
@@ -87,10 +151,35 @@ class DaemonService {
|
|
|
87
151
|
sourceTreeId: z.string(),
|
|
88
152
|
sessionName: z.string(),
|
|
89
153
|
includeImage: z.boolean().optional(),
|
|
154
|
+
stabilityCheck: z.boolean().optional(),
|
|
90
155
|
},
|
|
91
156
|
}, async (args) => {
|
|
157
|
+
this._activityTracker.reportActivity();
|
|
92
158
|
const session = this.getSession(args.sessionName);
|
|
93
159
|
this.assertSourceTreeId(args.sessionName, args.sourceTreeId);
|
|
160
|
+
if (args.stabilityCheck) {
|
|
161
|
+
const result = await session.explorer.screenshotFixtureStabilityCheck(args.fixtureId);
|
|
162
|
+
this.assertSourceTreeId(args.sessionName, args.sourceTreeId);
|
|
163
|
+
const hashes = result.screenshots.map(s => contentHash(s.image));
|
|
164
|
+
const isStable = hashes[0] === hashes[1] && hashes[1] === hashes[2];
|
|
165
|
+
const stabilityScreenshots = result.screenshots.map((s, i) => ({
|
|
166
|
+
hash: hashes[i],
|
|
167
|
+
delayMs: s.delayMs,
|
|
168
|
+
image: (args.includeImage ?? true)
|
|
169
|
+
? Buffer.from(s.image).toString('base64')
|
|
170
|
+
: undefined,
|
|
171
|
+
}));
|
|
172
|
+
return {
|
|
173
|
+
hash: hashes[hashes.length - 1],
|
|
174
|
+
sourceTreeId: args.sourceTreeId,
|
|
175
|
+
image: (args.includeImage ?? true)
|
|
176
|
+
? Buffer.from(result.screenshots[result.screenshots.length - 1].image).toString('base64')
|
|
177
|
+
: undefined,
|
|
178
|
+
errors: result.errors.length > 0 ? result.errors : undefined,
|
|
179
|
+
isStable,
|
|
180
|
+
stabilityScreenshots,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
94
183
|
const result = await session.explorer.screenshotFixture(args.fixtureId);
|
|
95
184
|
this.assertSourceTreeId(args.sessionName, args.sourceTreeId);
|
|
96
185
|
return {
|
|
@@ -110,6 +199,7 @@ class DaemonService {
|
|
|
110
199
|
includeImages: z.boolean().optional(),
|
|
111
200
|
},
|
|
112
201
|
}, async (args) => {
|
|
202
|
+
this._activityTracker.reportActivity();
|
|
113
203
|
const session = this.getSession(args.sessionName);
|
|
114
204
|
this.assertSourceTreeId(args.sessionName, args.sourceTreeId);
|
|
115
205
|
const includeImages = args.includeImages ?? false;
|
|
@@ -138,6 +228,7 @@ class DaemonService {
|
|
|
138
228
|
includeImages: z.boolean().optional(),
|
|
139
229
|
},
|
|
140
230
|
}, async (args) => {
|
|
231
|
+
this._activityTracker.reportActivity();
|
|
141
232
|
const baselineSession = this.getSession(args.baselineSessionName);
|
|
142
233
|
const currentSession = this.getSession(args.currentSessionName);
|
|
143
234
|
this.assertSourceTreeId(args.baselineSessionName, args.baselineSourceTreeId);
|
|
@@ -178,6 +269,7 @@ class DaemonService {
|
|
|
178
269
|
comment: z.string(),
|
|
179
270
|
},
|
|
180
271
|
}, async (args) => {
|
|
272
|
+
this._activityTracker.reportActivity();
|
|
181
273
|
this.approvals.approve(args);
|
|
182
274
|
}),
|
|
183
275
|
revoke: createMethod({
|
|
@@ -187,11 +279,13 @@ class DaemonService {
|
|
|
187
279
|
modifiedHash: z.string(),
|
|
188
280
|
},
|
|
189
281
|
}, async (args) => {
|
|
282
|
+
this._activityTracker.reportActivity();
|
|
190
283
|
this.approvals.revoke(args);
|
|
191
284
|
}),
|
|
192
285
|
list: createMethod({
|
|
193
286
|
args: { fixtureId: z.string().optional() },
|
|
194
287
|
}, async (args) => {
|
|
288
|
+
this._activityTracker.reportActivity();
|
|
195
289
|
return this.approvals.list(args.fixtureId);
|
|
196
290
|
}),
|
|
197
291
|
lookup: createMethod({
|
|
@@ -201,13 +295,30 @@ class DaemonService {
|
|
|
201
295
|
modifiedHash: z.string(),
|
|
202
296
|
},
|
|
203
297
|
}, async (args) => {
|
|
298
|
+
this._activityTracker.reportActivity();
|
|
204
299
|
return this.approvals.lookup(args) ?? null;
|
|
205
300
|
}),
|
|
206
301
|
}),
|
|
302
|
+
evaluate: createMethod({
|
|
303
|
+
args: {
|
|
304
|
+
sessionName: z.string(),
|
|
305
|
+
sourceTreeId: z.string(),
|
|
306
|
+
expression: z.string(),
|
|
307
|
+
fixtureId: z.string().optional(),
|
|
308
|
+
},
|
|
309
|
+
}, async (args) => {
|
|
310
|
+
this._activityTracker.reportActivity();
|
|
311
|
+
const session = this.getSession(args.sessionName);
|
|
312
|
+
this.assertSourceTreeId(args.sessionName, args.sourceTreeId);
|
|
313
|
+
const result = await session.explorer.evaluateJs(args.expression, args.fixtureId);
|
|
314
|
+
this.assertSourceTreeId(args.sessionName, args.sourceTreeId);
|
|
315
|
+
return { result };
|
|
316
|
+
}),
|
|
207
317
|
events: createMethod({ args: {} }, async () => {
|
|
208
318
|
return AsyncStream.fromIterable(this.eventStream());
|
|
209
319
|
}),
|
|
210
320
|
sessions: createMethod({ args: {} }, async () => {
|
|
321
|
+
this._activityTracker.reportActivity();
|
|
211
322
|
return this.getSessionInfos();
|
|
212
323
|
}),
|
|
213
324
|
shutdown: createMethod({ args: {} }, async () => {
|
|
@@ -223,17 +334,28 @@ class DaemonService {
|
|
|
223
334
|
}
|
|
224
335
|
return session;
|
|
225
336
|
}
|
|
226
|
-
getSessionInfos() {
|
|
337
|
+
getSessionInfos(reader) {
|
|
227
338
|
return this._config.sessions.map(sc => {
|
|
228
339
|
const session = this._sessions.get(sc.name);
|
|
340
|
+
if (!session) {
|
|
341
|
+
return { name: sc.name, sourceKind: sc.source.kind, isLoading: true };
|
|
342
|
+
}
|
|
229
343
|
return {
|
|
230
344
|
name: sc.name,
|
|
231
345
|
sourceKind: sc.source.kind,
|
|
232
346
|
serverUrl: session.serverUrl,
|
|
233
|
-
sourceTreeId: session.sourceTreeId.get().value,
|
|
347
|
+
sourceTreeId: reader ? session.sourceTreeId.read(reader).value : session.sourceTreeId.get().value,
|
|
234
348
|
};
|
|
235
349
|
});
|
|
236
350
|
}
|
|
351
|
+
waitForSession(sessionName) {
|
|
352
|
+
const sessionObs = derived(this, reader => {
|
|
353
|
+
const infos = this.getSessionInfos(reader);
|
|
354
|
+
const session = sessionName ? infos.find(s => s.name === sessionName) : infos[0];
|
|
355
|
+
return session && !session.isLoading ? session : undefined;
|
|
356
|
+
});
|
|
357
|
+
return waitForState(sessionObs);
|
|
358
|
+
}
|
|
237
359
|
getSourceTreeId(sessionName) {
|
|
238
360
|
return this.getSession(sessionName).sourceTreeId.get().value;
|
|
239
361
|
}
|
|
@@ -262,6 +384,8 @@ class DaemonService {
|
|
|
262
384
|
}
|
|
263
385
|
};
|
|
264
386
|
self._eventListeners.add(listener);
|
|
387
|
+
self._eventListenerCount.set(self._eventListeners.size, undefined);
|
|
388
|
+
self._activityTracker.setActive(true);
|
|
265
389
|
const onShutdown = () => {
|
|
266
390
|
done = true;
|
|
267
391
|
if (resolve) {
|
|
@@ -271,6 +395,11 @@ class DaemonService {
|
|
|
271
395
|
}
|
|
272
396
|
};
|
|
273
397
|
self._shutdownResolvers.push(onShutdown);
|
|
398
|
+
const cleanup = () => {
|
|
399
|
+
self._eventListeners.delete(listener);
|
|
400
|
+
self._eventListenerCount.set(self._eventListeners.size, undefined);
|
|
401
|
+
self._activityTracker.setActive(false);
|
|
402
|
+
};
|
|
274
403
|
return {
|
|
275
404
|
next() {
|
|
276
405
|
if (done) {
|
|
@@ -283,7 +412,7 @@ class DaemonService {
|
|
|
283
412
|
},
|
|
284
413
|
return() {
|
|
285
414
|
done = true;
|
|
286
|
-
|
|
415
|
+
cleanup();
|
|
287
416
|
return Promise.resolve({ value: undefined, done: true });
|
|
288
417
|
},
|
|
289
418
|
};
|
|
@@ -293,6 +422,7 @@ class DaemonService {
|
|
|
293
422
|
// -- Event loop ----------------------------------------------------------
|
|
294
423
|
async runEventLoop() {
|
|
295
424
|
this._startSourceChangeWatchers();
|
|
425
|
+
this._activityTracker.start();
|
|
296
426
|
await new Promise(resolve => {
|
|
297
427
|
if (this._shutdownRequested) {
|
|
298
428
|
resolve();
|
|
@@ -372,6 +502,7 @@ class DaemonService {
|
|
|
372
502
|
}
|
|
373
503
|
async dispose() {
|
|
374
504
|
this.requestShutdown();
|
|
505
|
+
this._activityTracker.dispose();
|
|
375
506
|
for (const d of this._sourceChangeDisposables) {
|
|
376
507
|
d.dispose();
|
|
377
508
|
}
|
|
@@ -457,5 +588,5 @@ class EventStreamLogger {
|
|
|
457
588
|
}
|
|
458
589
|
}
|
|
459
590
|
|
|
460
|
-
export { DaemonService, SourceTreeChangedError };
|
|
591
|
+
export { ActivityTracker, DaemonService, SourceTreeChangedError };
|
|
461
592
|
//# sourceMappingURL=DaemonService.js.map
|