@pygmalionjs/pygmalion 0.5.29 → 0.5.31

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.
@@ -11985,34 +11985,36 @@ function iv(e, t) {
11985
11985
  const o = e.slice(r + n.length);
11986
11986
  return o.startsWith(" · ") ? o.slice(3) : t;
11987
11987
  }
11988
- function sv(e, t, n = () => !0) {
11989
- const r = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
11990
- for (const d of e) {
11991
- const u = d.canvas ?? "default";
11992
- i.set(u, (i.get(u) ?? 0) + 1), n(d) && o.set(u, (o.get(u) ?? 0) + 1), d.section && !r.has(u) && r.set(u, d.section);
11988
+ function sv(e, t, n = () => !0, r = () => !0) {
11989
+ const o = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Set();
11990
+ for (const p of e) {
11991
+ const m = p.canvas ?? "default";
11992
+ c.add(m), p.section && !o.has(m) && o.set(m, p.section), r(p) && (a.set(m, (a.get(m) ?? 0) + 1), n(p) && i.set(m, (i.get(m) ?? 0) + 1));
11993
11993
  }
11994
- const a = [], c = [], l = /* @__PURE__ */ new Map();
11995
- for (const d of t) {
11996
- const u = o.get(d) ?? 0, p = i.get(d) ?? 0, m = r.get(d);
11997
- if (!m || !d.includes(` · ${m}`)) {
11998
- a.push({ canvas: d, label: d, frames: u, declared: p });
11994
+ const l = [], d = [], u = /* @__PURE__ */ new Map();
11995
+ for (const p of t) {
11996
+ const m = i.get(p) ?? 0, b = a.get(p) ?? 0;
11997
+ if (b === 0 && c.has(p)) continue;
11998
+ const x = o.get(p);
11999
+ if (!x || !p.includes(` · ${x}`)) {
12000
+ l.push({ canvas: p, label: p, frames: m, declared: b });
11999
12001
  continue;
12000
12002
  }
12001
- const b = { canvas: d, label: iv(d, m), frames: u, declared: p }, x = l.get(m);
12002
- if (x === void 0) {
12003
- l.set(m, c.length), c.push({ section: m, canvases: [b], frames: u, declared: p, single: !0 });
12003
+ const w = { canvas: p, label: iv(p, x), frames: m, declared: b }, v = u.get(x);
12004
+ if (v === void 0) {
12005
+ u.set(x, d.length), d.push({ section: x, canvases: [w], frames: m, declared: b, single: !0 });
12004
12006
  continue;
12005
12007
  }
12006
- const w = c[x];
12007
- c[x] = {
12008
- section: m,
12009
- canvases: [...w.canvases, b],
12010
- frames: w.frames + u,
12011
- declared: w.declared + p,
12008
+ const E = d[v];
12009
+ d[v] = {
12010
+ section: x,
12011
+ canvases: [...E.canvases, w],
12012
+ frames: E.frames + m,
12013
+ declared: E.declared + b,
12012
12014
  single: !1
12013
12015
  };
12014
12016
  }
12015
- return { loose: a, groups: c };
12017
+ return { loose: l, groups: d };
12016
12018
  }
12017
12019
  let wa = null;
12018
12020
  const Sa = /* @__PURE__ */ new Set();
@@ -13078,9 +13080,10 @@ const ys = Be(function({
13078
13080
  ii
13079
13081
  );
13080
13082
  const [o, i] = Ev("frames", 176), [a, c] = Q({}), l = sv(
13081
- f.pages.filter((I) => f.isInSelectedRuntime(I)),
13083
+ f.pages,
13082
13084
  f.canvasNames,
13083
- (I) => f.isScreenStateShown(I)
13085
+ (I) => f.isScreenStateShown(I),
13086
+ (I) => f.isInSelectedRuntime(I)
13084
13087
  ), d = (I) => I.canvases.some((N) => N.canvas === f.activeCanvas), u = Xe(
13085
13088
  Mf,
13086
13089
  ho,
@@ -54,5 +54,5 @@ export type CanvasTreeVisibility = (page: never) => boolean;
54
54
  * canvas list already resolved — that order carries the host's declared
55
55
  * section ranking, which a regrouping here would quietly discard.
56
56
  */
57
- export declare function buildCanvasTree<TPage extends CanvasTreePage>(pages: readonly TPage[], canvasNames: readonly string[], isShown?: (page: TPage) => boolean): CanvasTree;
57
+ export declare function buildCanvasTree<TPage extends CanvasTreePage>(pages: readonly TPage[], canvasNames: readonly string[], isShown?: (page: TPage) => boolean, exists?: (page: TPage) => boolean): CanvasTree;
58
58
  export {};
@@ -1,5 +1,9 @@
1
1
  import path from 'node:path';
2
- import { validateRoutePreviewArtifactBundle } from './route-preview-artifact-v3.mjs';
2
+ import {
3
+ mergeRoutePreviewArtifactV3,
4
+ selectRoutePreviewArtifactFrames,
5
+ validateRoutePreviewArtifactBundle,
6
+ } from './route-preview-artifact-v3.mjs';
3
7
  import { createPreviewArtifactStore } from './preview-artifact-store.mjs';
4
8
 
5
9
  export const PYGMALION_PREVIEW_ARTIFACT_ENDPOINT =
@@ -247,6 +251,7 @@ export function pygmalionPreviewArtifactPlugin({
247
251
  acquireLease,
248
252
  requestRuntime,
249
253
  runtimePrepared = () => true,
254
+ artifactStoreMaxBytes,
250
255
  } = {}) {
251
256
  const resolvedRoot = path.resolve(root);
252
257
  const resolvedArtifact = path.resolve(resolvedRoot, artifactFile);
@@ -288,6 +293,9 @@ export function pygmalionPreviewArtifactPlugin({
288
293
  // With the source root, a published frame records the files it actually
289
294
  // rendered, so freshness stops depending on which revision captured it.
290
295
  sourceRoot: resolvedRoot,
296
+ ...(artifactStoreMaxBytes == null
297
+ ? {}
298
+ : { maxBytes: artifactStoreMaxBytes }),
291
299
  });
292
300
  const identityQueues = new Map();
293
301
  const inFlightRequests = new Map();
@@ -485,7 +493,7 @@ export function pygmalionPreviewArtifactPlugin({
485
493
  );
486
494
  const absent = new Set([...before.missing, ...before.stale]);
487
495
  const remaining = wanted.filter((frame) => absent.has(frame.id));
488
- if (remaining.length === 0) return before.bundle;
496
+ if (remaining.length === 0) return before;
489
497
 
490
498
  const generated = await withCaptureLease(sourceRevision, () =>
491
499
  generateArtifact({
@@ -508,13 +516,17 @@ export function pygmalionPreviewArtifactPlugin({
508
516
  sourceRevision,
509
517
  recordRevision: false,
510
518
  });
511
- return (
512
- await artifactStore.readFrameSelection(
513
- namespace,
514
- sourceRevision,
515
- wanted,
516
- )
517
- ).bundle;
519
+ // Retention is allowed to decline a newly generated object when older
520
+ // entries have earned higher read recency. That cache decision must not
521
+ // discard the result from the request that just paid to generate it.
522
+ const responseArtifact = mergeRoutePreviewArtifactV3(
523
+ before.bundle,
524
+ generated,
525
+ );
526
+ return selectRoutePreviewArtifactFrames(responseArtifact, wanted, {
527
+ includeStale: true,
528
+ sourceRevision,
529
+ });
518
530
  }, priority),
519
531
  );
520
532
  }
@@ -644,17 +656,17 @@ export function pygmalionPreviewArtifactPlugin({
644
656
  }
645
657
  const requested = new Set(absent);
646
658
  try {
647
- await generateFrames(
659
+ const captured = await generateFrames(
648
660
  namespace,
649
661
  sourceRevision,
650
662
  captureBaseUrl,
651
663
  wanted.filter((frame) => requested.has(frame.id)),
652
664
  priority,
653
665
  );
654
- picked = await artifactStore.readFrameSelection(
655
- namespace,
656
- sourceRevision,
666
+ picked = selectRoutePreviewArtifactFrames(
667
+ mergeRoutePreviewArtifactV3(picked.bundle, captured.bundle),
657
668
  wanted,
669
+ { includeStale: true, sourceRevision },
658
670
  );
659
671
  } catch (error) {
660
672
  sendGenerationFailure(response, error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pygmalionjs/pygmalion",
3
- "version": "0.5.29",
3
+ "version": "0.5.31",
4
4
  "description": "Code-backed DOM design sandbox and visual QA editor",
5
5
  "license": "UNLICENSED",
6
6
  "publishConfig": {