@pygmalionjs/pygmalion 0.2.27 → 0.2.29

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.
@@ -1,6 +1,6 @@
1
1
  import { jsxs as C, jsx as w } from "react/jsx-runtime";
2
- import { b as Y, m as He, i as qe, g as Ke, e as q, c as Ge, a as Je, d as We, f as Ve, h as Qe, j as Le, k as Xe, l as Ye, n as be, o as ve, p as Ze, q as et, r as tt, t as nt, u as rt, v as ot, w as Ie, x as se, y as xe, S as st, A as it, z as Pe, B as at, C as ct, D as lt, E as dt, G as ut, H as ft, I as ht, J as pt, K as Ee } from "./App-rBeENUlS.js";
3
- import { L as mn, M as gn, O as yn, P as wn, Q as Sn, R as bn, T as vn, U as In, V as xn, W as Pn, X as En, Y as Cn, Z as Nn, _ as Rn, $ as An, a0 as $n, a1 as On, a2 as Mn, a3 as kn, a4 as Dn, a5 as Fn, a6 as Tn, a7 as zn, a8 as _n } from "./App-rBeENUlS.js";
2
+ import { b as Y, m as He, i as qe, g as Ke, e as q, c as Ge, a as Je, d as We, f as Ve, h as Qe, j as Le, k as Xe, l as Ye, n as be, o as ve, p as Ze, q as et, r as tt, t as nt, u as rt, v as ot, w as Ie, x as se, y as xe, S as st, A as it, z as Pe, B as at, C as ct, D as lt, E as dt, G as ut, H as ft, I as ht, J as pt, K as Ee } from "./App-CVHZqSEY.js";
3
+ import { L as mn, M as gn, O as yn, P as wn, Q as Sn, R as bn, T as vn, U as In, V as xn, W as Pn, X as En, Y as Cn, Z as Nn, _ as Rn, $ as An, a0 as $n, a1 as On, a2 as Mn, a3 as kn, a4 as Dn, a5 as Fn, a6 as Tn, a7 as zn, a8 as _n } from "./App-CVHZqSEY.js";
4
4
  import { createElement as Ce, useMemo as ae, useState as re, useRef as me, useCallback as X, useEffect as oe } from "react";
5
5
  function ge(e, t = /* @__PURE__ */ new Set()) {
6
6
  if (e == null || typeof e == "string" || typeof e == "boolean" || typeof e == "number" && Number.isFinite(e))
@@ -1,4 +1,4 @@
1
- import { F as s, N as a, e as r, s as i, a as t } from "./App-rBeENUlS.js";
1
+ import { F as s, N as a, e as r, s as i, a as t } from "./App-CVHZqSEY.js";
2
2
  export {
3
3
  s as FrozenRoutePreviewView,
4
4
  a as NodeModel,
@@ -0,0 +1,109 @@
1
+ import {
2
+ captureStoryboardCase,
3
+ storyboardCaptureSessionKey,
4
+ } from './storyboard-capture-runtime.mjs';
5
+
6
+ export const STORYBOARD_SESSION_POOL_LIMITS = Object.freeze({
7
+ maximumLanes: 16,
8
+ });
9
+
10
+ function assertPositiveLaneLimit(value) {
11
+ const lanes = value ?? STORYBOARD_SESSION_POOL_LIMITS.maximumLanes;
12
+ if (
13
+ !Number.isInteger(lanes) ||
14
+ lanes < 1 ||
15
+ lanes > STORYBOARD_SESSION_POOL_LIMITS.maximumLanes
16
+ ) {
17
+ throw new RangeError(
18
+ `Storyboard session lanes must be an integer from 1 to ${STORYBOARD_SESSION_POOL_LIMITS.maximumLanes}.`,
19
+ );
20
+ }
21
+ return lanes;
22
+ }
23
+
24
+ async function closeLane(lane) {
25
+ try {
26
+ await lane.context?.close();
27
+ } catch {
28
+ // The lane is being discarded — a close failure has nothing left to protect.
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Captures storyboard cases on warm pages when the case declares its state.
34
+ *
35
+ * One booted application can serve many screens: a declared state is reached by
36
+ * switching state, not by loading the app again. Cases that replay interactions
37
+ * keep the fresh-context path, because only the case itself knows how to undo
38
+ * what a click opened.
39
+ *
40
+ * A lane is a booted page plus the key it was booted for. Lanes are leased, so
41
+ * two workers never drive the same page, and a lane that saw a failure is
42
+ * discarded rather than handed to the next case.
43
+ */
44
+ export function createStoryboardCaptureSessions({
45
+ capture = captureStoryboardCase,
46
+ maximumLanes,
47
+ ...defaults
48
+ } = {}) {
49
+ const laneLimit = assertPositiveLaneLimit(maximumLanes);
50
+ const idle = new Map();
51
+ const open = new Set();
52
+ const stats = { warm: 0, cold: 0, boots: 0, discarded: 0 };
53
+
54
+ function leaseLane(key) {
55
+ const available = idle.get(key);
56
+ const lane = available?.pop();
57
+ if (available && available.length === 0) idle.delete(key);
58
+ if (lane) return lane;
59
+ if (open.size >= laneLimit) return null;
60
+ const created = { key, context: null, page: null, frozen: false };
61
+ open.add(created);
62
+ return created;
63
+ }
64
+
65
+ async function releaseLane(lane) {
66
+ if (lane.poisoned || !lane.page) {
67
+ open.delete(lane);
68
+ if (lane.context) stats.discarded += 1;
69
+ await closeLane(lane);
70
+ return;
71
+ }
72
+ const available = idle.get(lane.key);
73
+ if (available) available.push(lane);
74
+ else idle.set(lane.key, [lane]);
75
+ }
76
+
77
+ return {
78
+ async capture(screenCase, context = {}) {
79
+ const key = storyboardCaptureSessionKey(screenCase);
80
+ // Retry passes ask for isolation on purpose — a reused page is exactly
81
+ // what they are trying to rule out as the cause.
82
+ const lane = key && context.isolated !== true ? leaseLane(key) : null;
83
+ if (!lane) {
84
+ stats.cold += 1;
85
+ return capture({ ...defaults, screenCase });
86
+ }
87
+ const booted = Boolean(lane.page);
88
+ if (booted) stats.warm += 1;
89
+ else {
90
+ stats.cold += 1;
91
+ stats.boots += 1;
92
+ }
93
+ try {
94
+ return await capture({ ...defaults, screenCase, session: lane });
95
+ } finally {
96
+ await releaseLane(lane);
97
+ }
98
+ },
99
+ stats() {
100
+ return { ...stats, lanes: open.size };
101
+ },
102
+ async close() {
103
+ const lanes = [...open];
104
+ open.clear();
105
+ idle.clear();
106
+ await Promise.all(lanes.map((lane) => closeLane(lane)));
107
+ },
108
+ };
109
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pygmalionjs/pygmalion",
3
- "version": "0.2.27",
3
+ "version": "0.2.29",
4
4
  "description": "Code-backed DOM design sandbox and visual QA editor",
5
5
  "license": "UNLICENSED",
6
6
  "publishConfig": {
@@ -46,6 +46,7 @@
46
46
  "node/source-operations.mjs",
47
47
  "node/storyboard-canonical.mjs",
48
48
  "node/storyboard-capture-scheduler.mjs",
49
+ "node/storyboard-capture-sessions.mjs",
49
50
  "node/storyboard-capture-runtime.mjs",
50
51
  "node/storyboard-environment.mjs",
51
52
  "node/storyboard.mjs",