@pygmalionjs/pygmalion 0.2.37 → 0.2.39
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/dist-lib/{App-BE2sN74X.js → App-CJz8NrxS.js} +3815 -3736
- package/dist-lib/pygmalion.js +678 -684
- package/dist-lib/testing.js +1 -1
- package/node/design-session.mjs +6 -0
- package/node/dev-mirror.mjs +8 -2
- package/node/dev-view.vite.mjs +4 -0
- package/node/preview-artifact-plugin.mjs +0 -0
- package/node/preview-artifact-store.mjs +530 -0
- package/node/preview-vite-cache.mjs +26 -0
- package/node/route-dependency-digest.mjs +62 -0
- package/node/route-preview-artifact-v3.mjs +2 -1
- package/node/storyboard.mjs +2 -0
- package/node/vite.mjs +6 -0
- package/package.json +4 -1
- package/storyboard.d.ts +1 -0
- package/vite.d.ts +12 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
function normalizedRoutePath(value) {
|
|
2
|
+
if (typeof value !== 'string' || !value.trim()) return null;
|
|
3
|
+
try {
|
|
4
|
+
const pathname = new URL(value.trim(), 'http://pygmalion.invalid').pathname;
|
|
5
|
+
return `/${pathname.split('/').filter(Boolean).join('/')}`;
|
|
6
|
+
} catch {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function matches(pattern, route) {
|
|
12
|
+
for (let index = 0; index < pattern.length; index += 1) {
|
|
13
|
+
const segment = pattern[index];
|
|
14
|
+
if (segment === '*' || (segment.startsWith(':') && segment.endsWith('*'))) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
if (route[index] == null) return false;
|
|
18
|
+
if (!segment.startsWith(':') && segment !== route[index]) return false;
|
|
19
|
+
}
|
|
20
|
+
return route.length === pattern.length;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Resolves a concrete route against exact, `:param`, and `*` manifest paths. */
|
|
24
|
+
export function resolvePreviewRouteDependencyDigest(route, entries) {
|
|
25
|
+
const normalized = normalizedRoutePath(route);
|
|
26
|
+
if (!normalized || !Array.isArray(entries)) return undefined;
|
|
27
|
+
const routeSegments = normalized.split('/').filter(Boolean);
|
|
28
|
+
const candidates = [];
|
|
29
|
+
for (const [order, entry] of entries.entries()) {
|
|
30
|
+
if (
|
|
31
|
+
typeof entry?.path !== 'string' ||
|
|
32
|
+
typeof entry?.dependencyDigest !== 'string' ||
|
|
33
|
+
!entry.dependencyDigest
|
|
34
|
+
) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const pattern = normalizedRoutePath(entry.path);
|
|
38
|
+
if (!pattern) continue;
|
|
39
|
+
if (pattern === normalized) return entry.dependencyDigest;
|
|
40
|
+
const segments = pattern.split('/').filter(Boolean);
|
|
41
|
+
if (!matches(segments, routeSegments)) continue;
|
|
42
|
+
candidates.push({
|
|
43
|
+
digest: entry.dependencyDigest,
|
|
44
|
+
literalCount: segments.filter(
|
|
45
|
+
(segment) => !segment.startsWith(':') && segment !== '*',
|
|
46
|
+
).length,
|
|
47
|
+
wildcardCount: segments.filter(
|
|
48
|
+
(segment) => segment === '*' || segment.endsWith('*'),
|
|
49
|
+
).length,
|
|
50
|
+
length: segments.length,
|
|
51
|
+
order,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
candidates.sort(
|
|
55
|
+
(left, right) =>
|
|
56
|
+
right.literalCount - left.literalCount ||
|
|
57
|
+
left.wildcardCount - right.wildcardCount ||
|
|
58
|
+
right.length - left.length ||
|
|
59
|
+
right.order - left.order,
|
|
60
|
+
);
|
|
61
|
+
return candidates[0]?.digest;
|
|
62
|
+
}
|
|
@@ -626,7 +626,7 @@ function withFrames(bundle, frames) {
|
|
|
626
626
|
* requested one. Requests without a fingerprint accept whatever is stored, which
|
|
627
627
|
* keeps the whole-bundle callers of earlier versions working.
|
|
628
628
|
*/
|
|
629
|
-
export function selectRoutePreviewArtifactFrames(bundle, wanted) {
|
|
629
|
+
export function selectRoutePreviewArtifactFrames(bundle, wanted, options = {}) {
|
|
630
630
|
if (!isPlainRecord(bundle) || !isPlainRecord(bundle.frames)) {
|
|
631
631
|
throw new TypeError('Route preview artifact is invalid.');
|
|
632
632
|
}
|
|
@@ -649,6 +649,7 @@ export function selectRoutePreviewArtifactFrames(bundle, wanted) {
|
|
|
649
649
|
const fingerprint = isPlainRecord(request) ? request.fingerprint : undefined;
|
|
650
650
|
if (fingerprint != null && frame.fingerprint !== fingerprint) {
|
|
651
651
|
stale.push(id);
|
|
652
|
+
if (options.includeStale === true) frames[id] = frame;
|
|
652
653
|
continue;
|
|
653
654
|
}
|
|
654
655
|
frames[id] = frame;
|
package/node/storyboard.mjs
CHANGED
|
@@ -42,9 +42,11 @@ export {
|
|
|
42
42
|
export {
|
|
43
43
|
ROUTE_PREVIEW_ARTIFACT_V3_LIMITS,
|
|
44
44
|
createRoutePreviewArtifactV3,
|
|
45
|
+
mergeRoutePreviewArtifactV3,
|
|
45
46
|
reconstructRoutePreviewArtifactScreenshotV3,
|
|
46
47
|
reconstructRoutePreviewArtifactSnapshotV3,
|
|
47
48
|
reconstructRoutePreviewArtifactSnapshotsV3,
|
|
49
|
+
selectRoutePreviewArtifactFrames,
|
|
48
50
|
validateRoutePreviewArtifactBundle,
|
|
49
51
|
validateRoutePreviewArtifactV3,
|
|
50
52
|
} from './route-preview-artifact-v3.mjs';
|
package/node/vite.mjs
CHANGED
|
@@ -55,12 +55,15 @@ import {
|
|
|
55
55
|
import {
|
|
56
56
|
ROUTE_PREVIEW_ARTIFACT_V3_LIMITS,
|
|
57
57
|
createRoutePreviewArtifactV3,
|
|
58
|
+
mergeRoutePreviewArtifactV3,
|
|
58
59
|
reconstructRoutePreviewArtifactScreenshotV3,
|
|
59
60
|
reconstructRoutePreviewArtifactSnapshotV3,
|
|
60
61
|
reconstructRoutePreviewArtifactSnapshotsV3,
|
|
62
|
+
selectRoutePreviewArtifactFrames,
|
|
61
63
|
validateRoutePreviewArtifactBundle,
|
|
62
64
|
validateRoutePreviewArtifactV3,
|
|
63
65
|
} from './route-preview-artifact-v3.mjs';
|
|
66
|
+
import { resolvePreviewRouteDependencyDigest } from './route-dependency-digest.mjs';
|
|
64
67
|
import {
|
|
65
68
|
DEFAULT_PYGMALION_PREVIEW_ARTIFACT_FILE,
|
|
66
69
|
PYGMALION_PREVIEW_ARTIFACT_ENDPOINT,
|
|
@@ -366,9 +369,12 @@ export {
|
|
|
366
369
|
validateRoutePreviewArtifactV2,
|
|
367
370
|
ROUTE_PREVIEW_ARTIFACT_V3_LIMITS,
|
|
368
371
|
createRoutePreviewArtifactV3,
|
|
372
|
+
mergeRoutePreviewArtifactV3,
|
|
369
373
|
reconstructRoutePreviewArtifactScreenshotV3,
|
|
370
374
|
reconstructRoutePreviewArtifactSnapshotV3,
|
|
371
375
|
reconstructRoutePreviewArtifactSnapshotsV3,
|
|
376
|
+
selectRoutePreviewArtifactFrames,
|
|
377
|
+
resolvePreviewRouteDependencyDigest,
|
|
372
378
|
validateRoutePreviewArtifactBundle,
|
|
373
379
|
validateRoutePreviewArtifactV3,
|
|
374
380
|
DEFAULT_PYGMALION_PREVIEW_ARTIFACT_FILE,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pygmalionjs/pygmalion",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.39",
|
|
4
4
|
"description": "Code-backed DOM design sandbox and visual QA editor",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"publishConfig": {
|
|
@@ -37,9 +37,12 @@
|
|
|
37
37
|
"node/dev-view.vite.mjs",
|
|
38
38
|
"node/inspect-plugin.mjs",
|
|
39
39
|
"node/preview-artifact-plugin.mjs",
|
|
40
|
+
"node/preview-artifact-store.mjs",
|
|
41
|
+
"node/preview-vite-cache.mjs",
|
|
40
42
|
"node/qa-capture-plugin.mjs",
|
|
41
43
|
"node/route-preview-artifact-v2.mjs",
|
|
42
44
|
"node/route-preview-artifact-v3.mjs",
|
|
45
|
+
"node/route-dependency-digest.mjs",
|
|
43
46
|
"node/source-revision.mjs",
|
|
44
47
|
"node/source-diff.mjs",
|
|
45
48
|
"node/source-graph.mjs",
|
package/storyboard.d.ts
CHANGED
|
@@ -318,6 +318,7 @@ export interface RoutePreviewArtifactFrameRequest {
|
|
|
318
318
|
export declare function selectRoutePreviewArtifactFrames(
|
|
319
319
|
bundle: unknown,
|
|
320
320
|
wanted: readonly (RoutePreviewArtifactFrameRequest | string)[],
|
|
321
|
+
options?: { includeStale?: boolean },
|
|
321
322
|
): {
|
|
322
323
|
bundle: RoutePreviewArtifactBundleV3;
|
|
323
324
|
missing: string[];
|
package/vite.d.ts
CHANGED
|
@@ -76,6 +76,7 @@ export interface PygmalionPreviewConfig {
|
|
|
76
76
|
generateArtifact?: (request: {
|
|
77
77
|
namespace: string;
|
|
78
78
|
sourceRevision: string;
|
|
79
|
+
frames?: readonly { id: string; fingerprint?: string }[];
|
|
79
80
|
captureBaseUrl?: string;
|
|
80
81
|
}) => unknown | Promise<unknown>;
|
|
81
82
|
}
|
|
@@ -158,8 +159,15 @@ export declare function pygmalionPreviewArtifactPlugin(options?: {
|
|
|
158
159
|
generateArtifact?: (request: {
|
|
159
160
|
namespace: string;
|
|
160
161
|
sourceRevision: string;
|
|
162
|
+
frames?: readonly { id: string; fingerprint?: string }[];
|
|
161
163
|
captureBaseUrl?: string;
|
|
162
164
|
}) => unknown | Promise<unknown>;
|
|
165
|
+
acquireLease?: (
|
|
166
|
+
reason: string,
|
|
167
|
+
) =>
|
|
168
|
+
| { release(): void | Promise<void> }
|
|
169
|
+
| null
|
|
170
|
+
| Promise<{ release(): void | Promise<void> } | null>;
|
|
163
171
|
}): PluginOption;
|
|
164
172
|
export interface PygmalionGitSourceState {
|
|
165
173
|
commit: string;
|
|
@@ -511,6 +519,10 @@ export {
|
|
|
511
519
|
validateRoutePreviewArtifactBundle,
|
|
512
520
|
validateRoutePreviewArtifactV3,
|
|
513
521
|
} from './storyboard';
|
|
522
|
+
export declare function resolvePreviewRouteDependencyDigest(
|
|
523
|
+
route: string,
|
|
524
|
+
entries: readonly { path?: string; dependencyDigest?: string }[],
|
|
525
|
+
): string | undefined;
|
|
514
526
|
export type {
|
|
515
527
|
RoutePreviewArtifactBundleV3,
|
|
516
528
|
RoutePreviewArtifactFrameRequest,
|