@pygmalionjs/pygmalion 0.6.32 → 0.6.34
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 +75 -2
- package/dist-lib/{FrozenRoutePreview-BwkyYvUV.js → FrozenRoutePreview-BbF5Ov5K.js} +2901 -2740
- package/dist-lib/pygmalion.js +11165 -9856
- package/dist-lib/testing.js +1 -1
- package/dist-lib/types/editor/captureSupply.d.ts +2 -0
- package/dist-lib/types/editor/documentSync.d.ts +15 -1
- package/dist-lib/types/editor/host.d.ts +9 -0
- package/dist-lib/types/editor/previewEnvironmentControls.d.ts +2 -0
- package/dist-lib/types/editor/projectBootGate.d.ts +15 -0
- package/dist-lib/types/editor/revisionCatalog.d.ts +135 -0
- package/dist-lib/types/editor/revisionCatalogInstall.d.ts +62 -0
- package/dist-lib/types/editor/routePreview.d.ts +1 -1
- package/dist-lib/types/editor/routePreviewStatus.d.ts +2 -1
- package/dist-lib/types/editor/store.d.ts +36 -37
- package/dist-lib/types/editor/tokens.d.ts +9 -0
- package/dist-lib/types/lib.d.ts +12 -3
- package/node/dev-mirror.mjs +567 -112
- package/node/preview-artifact-plugin.mjs +527 -68
- package/node/preview-artifact-store.mjs +370 -77
- package/node/vite.mjs +48 -2
- package/package.json +1 -1
- package/vite.d.ts +61 -4
package/node/vite.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
PYGMALION_DEV_PREFIX,
|
|
5
5
|
PYGMALION_WORKTREE_SOURCE_REF,
|
|
6
6
|
pygmalionDevMirrorPlugin,
|
|
7
|
+
resolveExactCheckoutSourceRoot,
|
|
7
8
|
} from './dev-mirror.mjs';
|
|
8
9
|
import {
|
|
9
10
|
PYGMALION_INSPECT_CONTROL,
|
|
@@ -68,6 +69,7 @@ import {
|
|
|
68
69
|
DEFAULT_PYGMALION_PREVIEW_ARTIFACT_FILE,
|
|
69
70
|
PYGMALION_PREVIEW_ARTIFACT_ENDPOINT,
|
|
70
71
|
PYGMALION_PREVIEW_CAPTURE_PROGRESS_SUFFIX,
|
|
72
|
+
PYGMALION_REVISION_CATALOG_SUFFIX,
|
|
71
73
|
pygmalionPreviewArtifactPlugin,
|
|
72
74
|
} from './preview-artifact-plugin.mjs';
|
|
73
75
|
import { createPreviewCaptureWorkerChannel } from './preview-capture-worker.mjs';
|
|
@@ -233,6 +235,17 @@ export function createPygmalionVitePlugins(config) {
|
|
|
233
235
|
// worker script; the function wins when both are present so existing
|
|
234
236
|
// configurations keep their exact behavior.
|
|
235
237
|
let generateArtifact = project.preview.generateArtifact;
|
|
238
|
+
const revisionCatalog =
|
|
239
|
+
project.preview.catalog === false
|
|
240
|
+
? false
|
|
241
|
+
: optionalObject(project.preview.catalog);
|
|
242
|
+
const revisionCatalogFile =
|
|
243
|
+
revisionCatalog === false
|
|
244
|
+
? undefined
|
|
245
|
+
: optionalNonEmptyString(
|
|
246
|
+
revisionCatalog.file,
|
|
247
|
+
'preview.catalog.file',
|
|
248
|
+
);
|
|
236
249
|
let captureWorkerChannel = null;
|
|
237
250
|
if (!generateArtifact && project.preview.captureWorker) {
|
|
238
251
|
const captureWorker = optionalObject(project.preview.captureWorker);
|
|
@@ -255,15 +268,47 @@ export function createPygmalionVitePlugins(config) {
|
|
|
255
268
|
generateArtifact = captureWorkerChannel.generateArtifact;
|
|
256
269
|
}
|
|
257
270
|
|
|
258
|
-
if (project.preview.artifactFile || generateArtifact) {
|
|
271
|
+
if (project.preview.artifactFile || generateArtifact || revisionCatalogFile) {
|
|
259
272
|
plugins.push(
|
|
260
273
|
pygmalionPreviewArtifactPlugin({
|
|
261
274
|
root: project.appRoot,
|
|
262
275
|
artifactFile: project.preview.artifactFile,
|
|
263
276
|
endpoint: project.preview.artifactEndpoint,
|
|
277
|
+
catalogFile: revisionCatalogFile,
|
|
278
|
+
catalogEndpoint:
|
|
279
|
+
revisionCatalog === false ? undefined : revisionCatalog.endpoint,
|
|
264
280
|
generateArtifact,
|
|
265
281
|
acquireLease: (label) => devMirror?.acquireLease(label) ?? null,
|
|
266
|
-
|
|
282
|
+
acquireSourceLease: async (sourceRevision, label) => {
|
|
283
|
+
if (devMirror?.acquireSourceLease) {
|
|
284
|
+
return devMirror.acquireSourceLease(sourceRevision, label);
|
|
285
|
+
}
|
|
286
|
+
const current = resolveGitSourceState(project.projectRoot);
|
|
287
|
+
if (current.dirty || current.revision !== sourceRevision) return null;
|
|
288
|
+
const exactSourceRoot = await resolveExactCheckoutSourceRoot({
|
|
289
|
+
checkoutRoot: project.projectRoot,
|
|
290
|
+
sourceRoot: project.appRoot,
|
|
291
|
+
expectedRevision: sourceRevision,
|
|
292
|
+
});
|
|
293
|
+
if (!exactSourceRoot) return null;
|
|
294
|
+
return {
|
|
295
|
+
sourceRoot: exactSourceRoot,
|
|
296
|
+
sourceRevision: current.revision,
|
|
297
|
+
async validate() {
|
|
298
|
+
const latest = resolveGitSourceState(project.projectRoot);
|
|
299
|
+
if (latest.dirty || latest.revision !== sourceRevision) {
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
const latestSourceRoot = await resolveExactCheckoutSourceRoot({
|
|
303
|
+
checkoutRoot: project.projectRoot,
|
|
304
|
+
sourceRoot: project.appRoot,
|
|
305
|
+
expectedRevision: sourceRevision,
|
|
306
|
+
});
|
|
307
|
+
return latestSourceRoot === exactSourceRoot;
|
|
308
|
+
},
|
|
309
|
+
async release() {},
|
|
310
|
+
};
|
|
311
|
+
},
|
|
267
312
|
requestRuntime: () => devMirror?.requestRuntime?.(),
|
|
268
313
|
// No mirror plugin means no checkout to prepare, so generation is
|
|
269
314
|
// always allowed to proceed as it did before.
|
|
@@ -442,6 +487,7 @@ export {
|
|
|
442
487
|
DEFAULT_PYGMALION_PREVIEW_ARTIFACT_FILE,
|
|
443
488
|
PYGMALION_PREVIEW_ARTIFACT_ENDPOINT,
|
|
444
489
|
PYGMALION_PREVIEW_CAPTURE_PROGRESS_SUFFIX,
|
|
490
|
+
PYGMALION_REVISION_CATALOG_SUFFIX,
|
|
445
491
|
pygmalionPreviewArtifactPlugin,
|
|
446
492
|
createPreviewCaptureWorkerChannel,
|
|
447
493
|
DEFAULT_QA_CAPTURE_MAX_FRAMES,
|
package/package.json
CHANGED
package/vite.d.ts
CHANGED
|
@@ -22,9 +22,18 @@ export interface PygmalionInventoryConfig {
|
|
|
22
22
|
outputRoot?: string;
|
|
23
23
|
/**
|
|
24
24
|
* Generator-owned paths relative to the host application root. The dedicated
|
|
25
|
-
* mirror restores
|
|
25
|
+
* mirror restores these paths before synchronization and rejects any change
|
|
26
|
+
* the generator leaves outside them.
|
|
26
27
|
*/
|
|
27
28
|
outputs?: string[];
|
|
29
|
+
/**
|
|
30
|
+
* Ignored runtime/configuration files the generator must not change. Paths
|
|
31
|
+
* are relative to appRoot; each entry must name a file, not a directory.
|
|
32
|
+
* Pygmalion compares bounded content signatures immediately around generation
|
|
33
|
+
* without walking .git, node_modules, or other unrelated trees. At most 64
|
|
34
|
+
* files totaling 16 MiB may be declared.
|
|
35
|
+
*/
|
|
36
|
+
runtimeInputs?: string[];
|
|
28
37
|
generate?: (context: PygmalionInventoryContext) => void | Promise<void>;
|
|
29
38
|
}
|
|
30
39
|
|
|
@@ -71,6 +80,16 @@ export interface PygmalionPreviewCaptureWorkerConfig {
|
|
|
71
80
|
jobTimeoutMs?: number;
|
|
72
81
|
}
|
|
73
82
|
|
|
83
|
+
export interface PygmalionRevisionCatalogConfig {
|
|
84
|
+
/**
|
|
85
|
+
* JSON catalog generated inside each source checkout, relative to appRoot.
|
|
86
|
+
* The mirror inventory step should own this file and stamp its exact commit.
|
|
87
|
+
*/
|
|
88
|
+
file: string;
|
|
89
|
+
/** Defaults to `${artifactEndpoint}/catalog`. */
|
|
90
|
+
endpoint?: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
74
93
|
export interface PygmalionPreviewCaptureProgressEvent {
|
|
75
94
|
phase: 'queued' | 'preparing' | 'capturing' | 'retrying' | 'finalizing';
|
|
76
95
|
completed: number;
|
|
@@ -83,6 +102,15 @@ export interface PygmalionPreviewCaptureGeneratorOptions {
|
|
|
83
102
|
onProgress?: (progress: PygmalionPreviewCaptureProgressEvent) => void;
|
|
84
103
|
}
|
|
85
104
|
|
|
105
|
+
export interface PygmalionPreviewFrameRequest {
|
|
106
|
+
id: string;
|
|
107
|
+
fingerprint?: string;
|
|
108
|
+
/** Identity of the complete capture recipe represented by `fingerprint`. */
|
|
109
|
+
recipeFingerprint?: string;
|
|
110
|
+
/** Opaque JSON recipe forwarded unchanged to the host capture generator. */
|
|
111
|
+
recipe?: Readonly<Record<string, unknown>>;
|
|
112
|
+
}
|
|
113
|
+
|
|
86
114
|
export interface PygmalionPreviewConfig {
|
|
87
115
|
configFile?: string;
|
|
88
116
|
viteConfig?: string;
|
|
@@ -104,7 +132,7 @@ export interface PygmalionPreviewConfig {
|
|
|
104
132
|
request: {
|
|
105
133
|
namespace: string;
|
|
106
134
|
sourceRevision: string;
|
|
107
|
-
frames?: readonly
|
|
135
|
+
frames?: readonly PygmalionPreviewFrameRequest[];
|
|
108
136
|
captureBaseUrl?: string;
|
|
109
137
|
},
|
|
110
138
|
options?: PygmalionPreviewCaptureGeneratorOptions,
|
|
@@ -114,6 +142,8 @@ export interface PygmalionPreviewConfig {
|
|
|
114
142
|
* `generateArtifact` is absent. When both are set, `generateArtifact` wins.
|
|
115
143
|
*/
|
|
116
144
|
captureWorker?: PygmalionPreviewCaptureWorkerConfig;
|
|
145
|
+
/** Exact-checkout screen catalog served before preview artifacts are probed. */
|
|
146
|
+
catalog?: false | PygmalionRevisionCatalogConfig;
|
|
117
147
|
}
|
|
118
148
|
|
|
119
149
|
export interface PygmalionQaConfig
|
|
@@ -186,17 +216,21 @@ export declare function createPygmalionVitePlugins(
|
|
|
186
216
|
|
|
187
217
|
export declare const PYGMALION_PREVIEW_ARTIFACT_ENDPOINT: string;
|
|
188
218
|
export declare const PYGMALION_PREVIEW_CAPTURE_PROGRESS_SUFFIX: string;
|
|
219
|
+
export declare const PYGMALION_REVISION_CATALOG_SUFFIX: string;
|
|
189
220
|
export declare const DEFAULT_PYGMALION_PREVIEW_ARTIFACT_FILE: string;
|
|
190
221
|
export declare function pygmalionPreviewArtifactPlugin(options?: {
|
|
191
222
|
root?: string;
|
|
192
223
|
artifactFile?: string;
|
|
193
224
|
endpoint?: string;
|
|
225
|
+
/** Requires `acquireSourceLease`; the catalog is never read without one. */
|
|
226
|
+
catalogFile?: string;
|
|
227
|
+
catalogEndpoint?: string;
|
|
194
228
|
disabled?: () => boolean;
|
|
195
229
|
generateArtifact?: (
|
|
196
230
|
request: {
|
|
197
231
|
namespace: string;
|
|
198
232
|
sourceRevision: string;
|
|
199
|
-
frames?: readonly
|
|
233
|
+
frames?: readonly PygmalionPreviewFrameRequest[];
|
|
200
234
|
captureBaseUrl?: string;
|
|
201
235
|
},
|
|
202
236
|
options?: PygmalionPreviewCaptureGeneratorOptions,
|
|
@@ -207,13 +241,36 @@ export declare function pygmalionPreviewArtifactPlugin(options?: {
|
|
|
207
241
|
| { release(): void | Promise<void> }
|
|
208
242
|
| null
|
|
209
243
|
| Promise<{ release(): void | Promise<void> } | null>;
|
|
244
|
+
/** Holds an exact checkout for catalog reads and the whole artifact capture. */
|
|
245
|
+
acquireSourceLease?: (
|
|
246
|
+
sourceRevision: string,
|
|
247
|
+
label: string,
|
|
248
|
+
) =>
|
|
249
|
+
| {
|
|
250
|
+
sourceRoot: string;
|
|
251
|
+
sourceRevision: string;
|
|
252
|
+
/** Revalidates direct worktrees that cannot be held by a mirror lease. */
|
|
253
|
+
validate?(): boolean | Promise<boolean>;
|
|
254
|
+
release(): void | Promise<void>;
|
|
255
|
+
}
|
|
256
|
+
| null
|
|
257
|
+
| Promise<{
|
|
258
|
+
sourceRoot: string;
|
|
259
|
+
sourceRevision: string;
|
|
260
|
+
/** Revalidates direct worktrees that cannot be held by a mirror lease. */
|
|
261
|
+
validate?(): boolean | Promise<boolean>;
|
|
262
|
+
release(): void | Promise<void>;
|
|
263
|
+
} | null>;
|
|
264
|
+
requestRuntime?: () => void;
|
|
265
|
+
runtimePrepared?: () => boolean;
|
|
266
|
+
artifactStoreMaxBytes?: number;
|
|
210
267
|
}): PluginOption;
|
|
211
268
|
export interface PygmalionPreviewCaptureWorkerChannel {
|
|
212
269
|
generateArtifact(
|
|
213
270
|
request: {
|
|
214
271
|
namespace: string;
|
|
215
272
|
sourceRevision: string;
|
|
216
|
-
frames?: readonly
|
|
273
|
+
frames?: readonly PygmalionPreviewFrameRequest[];
|
|
217
274
|
captureBaseUrl?: string;
|
|
218
275
|
},
|
|
219
276
|
options?: PygmalionPreviewCaptureGeneratorOptions,
|