waygraph 0.12.18 → 0.12.19

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/cli.js CHANGED
@@ -221,6 +221,8 @@ import {
221
221
  demoPaceIsBlitz,
222
222
  demoPaceIsFast,
223
223
  demoPaceIsSlow,
224
+ formatDemoPaceBadge,
225
+ formatDemoPaceLabel,
224
226
  } from "waygraph";
225
227
 
226
228
  function walkDir(dir, pattern) {
@@ -491,6 +493,18 @@ const RING_CSS =
491
493
  // block chain shows no episode heading at all.
492
494
  "#wg-panel .wg-episode{margin:0 0 6px;font:700 15px system-ui,sans-serif;color:#fff;" +
493
495
  "padding-bottom:6px;border-bottom:1px solid rgba(124,58,237,.35);}" +
496
+ // Pace chip - numbers speak in the overlay (2.5x / 4500ms / slow).
497
+ "#wg-panel .wg-pace{display:inline-flex;align-items:center;gap:8px;margin:0 0 10px;" +
498
+ "padding:6px 10px;border-radius:8px;background:rgba(124,58,237,.22);" +
499
+ "border:1px solid rgba(124,58,237,.45);font:600 12px/1.35 system-ui,sans-serif;color:#f0e8ff;}" +
500
+ "#wg-panel .wg-pace-badge{display:inline-block;padding:2px 8px;border-radius:999px;" +
501
+ "background:#7C3AED;color:#fff;font:800 11px/1.2 system-ui,sans-serif;letter-spacing:.04em;" +
502
+ "text-transform:uppercase;}" +
503
+ "#wg-panel .wg-pace[data-pace-kind=slow] .wg-pace-badge," +
504
+ "#wg-panel .wg-pace[data-pace-kind=num-slow] .wg-pace-badge{background:#EAB308;color:#1c1917;}" +
505
+ "#wg-panel .wg-pace[data-pace-kind=fast] .wg-pace-badge," +
506
+ "#wg-panel .wg-pace[data-pace-kind=blitz] .wg-pace-badge{background:#22C55E;color:#052e16;}" +
507
+ "#wg-panel .wg-pace[data-pace-kind=ms] .wg-pace-badge{background:#3B82F6;color:#fff;}" +
494
508
  "#wg-panel .wg-narration{margin:0 0 12px;font:italic 14px/1.4 system-ui,sans-serif;color:#f0e8ff;}" +
495
509
  "#wg-progress{height:4px;background:#2a1650;border-radius:2px;margin:0 0 12px;overflow:hidden;}" +
496
510
  "#wg-progress-bar{height:100%;background:#7C3AED;border-radius:2px;transition:width .3s ease;}" +
@@ -957,9 +971,20 @@ async function renderBeforeStep(page, info) {
957
971
  const narrationHtml = info.description
958
972
  ? "<div class=\\"wg-narration\\">" + esc(info.description) + "</div>"
959
973
  : "";
974
+ const paceHtml =
975
+ info.paceBadge || info.paceLabel
976
+ ? "<div class=\\"wg-pace\\" data-pace-kind=\\"" +
977
+ esc(info.paceKind || "normal") +
978
+ "\\"><span class=\\"wg-pace-badge\\">" +
979
+ esc(info.paceBadge || "1x") +
980
+ "</span><span>" +
981
+ esc(info.paceLabel || "") +
982
+ "</span></div>"
983
+ : "";
960
984
  let html =
961
985
  "<div id=\\"wg-progress\\"><div id=\\"wg-progress-bar\\" style=\\"width:" + pct + "%\\"></div></div>" +
962
986
  episodesHtml +
987
+ paceHtml +
963
988
  "<div id=\\"wg-modules\\" class=\\"" + modulesClass + "\\">" + modulesHtml + "</div>" +
964
989
  "<h3>Step " + (info.index + 1) + " / " + info.total + " - " + info.blockName + "</h3>" +
965
990
  narrationHtml;
@@ -995,7 +1020,12 @@ async function renderBeforeStep(page, info) {
995
1020
  }
996
1021
  if (window.__wgWirePanelChrome) {
997
1022
  window.__wgWirePanelChrome(panel, "wg-panel-hidden", "waygraph demo", {
998
- stepLabel: (info.index + 1) + " / " + info.total + (info.blockName ? " · " + info.blockName : ""),
1023
+ stepLabel:
1024
+ (info.index + 1) +
1025
+ " / " +
1026
+ info.total +
1027
+ (info.blockName ? " · " + info.blockName : "") +
1028
+ (info.paceBadge ? " · " + info.paceBadge : ""),
999
1029
  forceCollapsed: info.forceCollapsed === true ? true : info.forceCollapsed === false ? false : undefined,
1000
1030
  });
1001
1031
  }
@@ -1214,9 +1244,20 @@ async function renderAfterStep(page, info) {
1214
1244
  .join("") +
1215
1245
  "</div>"
1216
1246
  : "";
1247
+ const paceHtml =
1248
+ info.paceBadge || info.paceLabel
1249
+ ? "<div class=\\"wg-pace\\" data-pace-kind=\\"" +
1250
+ escA(info.paceKind || "normal") +
1251
+ "\\"><span class=\\"wg-pace-badge\\">" +
1252
+ escA(info.paceBadge || "1x") +
1253
+ "</span><span>" +
1254
+ escA(info.paceLabel || "") +
1255
+ "</span></div>"
1256
+ : "";
1217
1257
  panel.innerHTML =
1218
1258
  "<div id=\\"wg-progress\\"><div id=\\"wg-progress-bar\\" style=\\"width:" + pct + "%\\"></div></div>" +
1219
1259
  episodesHtml +
1260
+ paceHtml +
1220
1261
  "<div id=\\"wg-modules\\" class=\\"" + modulesClass + "\\">" + modulesHtml + "</div>" +
1221
1262
  "<h3>" + heading + "</h3>" +
1222
1263
  resultHtml +
@@ -1227,7 +1268,12 @@ async function renderAfterStep(page, info) {
1227
1268
  }
1228
1269
  if (window.__wgWirePanelChrome) {
1229
1270
  window.__wgWirePanelChrome(panel, "wg-panel-hidden", "waygraph demo", {
1230
- stepLabel: (info.index + 1) + " / " + info.total + (info.blockName ? " · " + info.blockName : ""),
1271
+ stepLabel:
1272
+ (info.index + 1) +
1273
+ " / " +
1274
+ info.total +
1275
+ (info.blockName ? " · " + info.blockName : "") +
1276
+ (info.paceBadge ? " · " + info.paceBadge : ""),
1231
1277
  forceCollapsed: info.forceCollapsed === true ? true : info.forceCollapsed === false ? false : undefined,
1232
1278
  });
1233
1279
  }
@@ -1329,7 +1375,12 @@ async function renderStepError(page, info) {
1329
1375
  }
1330
1376
  if (window.__wgWirePanelChrome) {
1331
1377
  window.__wgWirePanelChrome(panel, "wg-panel-hidden", "waygraph demo", {
1332
- stepLabel: (info.index + 1) + " / " + info.total + (info.blockName ? " · " + info.blockName : ""),
1378
+ stepLabel:
1379
+ (info.index + 1) +
1380
+ " / " +
1381
+ info.total +
1382
+ (info.blockName ? " · " + info.blockName : "") +
1383
+ (info.paceBadge ? " · " + info.paceBadge : ""),
1333
1384
  forceCollapsed: info.forceCollapsed === true ? true : info.forceCollapsed === false ? false : undefined,
1334
1385
  });
1335
1386
  }
@@ -1537,14 +1588,13 @@ async function presentSlides(page, slides, _gate, opts) {
1537
1588
  const episodeTitle = (opts && opts.episodeTitle) || "";
1538
1589
  const gatesFast = !!(opts && opts.fast);
1539
1590
  const demoPace = normalizeDemoPace((opts && opts.pace) || (gatesFast ? "fast" : "normal"));
1540
- const autoplayMs =
1591
+ const baseAutoplay =
1541
1592
  opts && opts.autoplayMs
1542
1593
  ? Number(opts.autoplayMs)
1543
1594
  : process.env.WAYGRAPH_AUTOPLAY_MS
1544
1595
  ? Number(process.env.WAYGRAPH_AUTOPLAY_MS)
1545
- : demoPace === "slow"
1546
- ? 3500
1547
- : 1800;
1596
+ : 1800;
1597
+ const autoplayMs = demoPaceGateMs(demoPace, baseAutoplay);
1548
1598
  for (let i = 0; i < slides.length; i++) {
1549
1599
  const s = slides[i];
1550
1600
  const caption = formatHighlightCaption(s);
@@ -1584,11 +1634,22 @@ async function presentSlides(page, slides, _gate, opts) {
1584
1634
  (info.episodeTitle ? ": " + esc(info.episodeTitle) : "") +
1585
1635
  " · yap slides</div>"
1586
1636
  : "";
1637
+ const paceHtml =
1638
+ info.paceBadge || info.paceLabel
1639
+ ? "<div class=\\"wg-pace\\" data-pace-kind=\\"" +
1640
+ esc(info.paceKind || "normal") +
1641
+ "\\"><span class=\\"wg-pace-badge\\">" +
1642
+ esc(info.paceBadge || "1x") +
1643
+ "</span><span>" +
1644
+ esc(info.paceLabel || "") +
1645
+ "</span></div>"
1646
+ : "";
1587
1647
  panel.innerHTML =
1588
1648
  "<div class=\\"wg-chrome\\"><span class=\\"wg-chrome-title\\">waygraph demo</span>" +
1589
1649
  "<button type=\\"button\\" class=\\"wg-hide-btn\\" data-wg-toggle=\\"1\\">Hide</button></div>" +
1590
1650
  "<div class=\\"wg-body\\">" +
1591
1651
  episodeLine +
1652
+ paceHtml +
1592
1653
  "<h3>Slide " +
1593
1654
  (info.index + 1) +
1594
1655
  " / " +
@@ -1706,6 +1767,9 @@ async function presentSlides(page, slides, _gate, opts) {
1706
1767
  dwellMs,
1707
1768
  episodeNumber: episodeNumber !== undefined ? episodeNumber : null,
1708
1769
  episodeTitle,
1770
+ paceBadge: formatDemoPaceBadge(demoPace, baseAutoplay),
1771
+ paceLabel: formatDemoPaceLabel(demoPace, baseAutoplay),
1772
+ paceKind: demoPaceKind(demoPace),
1709
1773
  },
1710
1774
  );
1711
1775
  const started = Date.now();
@@ -1738,6 +1802,25 @@ async function presentSlides(page, slides, _gate, opts) {
1738
1802
  await hideRing(page);
1739
1803
  }
1740
1804
 
1805
+ function demoPaceKind(pace) {
1806
+ const p = normalizeDemoPace(pace);
1807
+ if (typeof p === "number" && p > 20) return "ms";
1808
+ if (typeof p === "number") return demoPaceIsSlow(p) ? "num-slow" : demoPaceIsFast(p) ? "fast" : "normal";
1809
+ if (p === "blitz" || p === "fast" || p === "slow") return p;
1810
+ return "normal";
1811
+ }
1812
+
1813
+ function paceSpeakFields(pace, baseAutoplayMs) {
1814
+ const p = normalizeDemoPace(pace);
1815
+ const base = Number.isFinite(baseAutoplayMs) && baseAutoplayMs > 0 ? baseAutoplayMs : 1800;
1816
+ return {
1817
+ pace: p,
1818
+ paceBadge: formatDemoPaceBadge(p, base),
1819
+ paceLabel: formatDemoPaceLabel(p, base),
1820
+ paceKind: demoPaceKind(p),
1821
+ };
1822
+ }
1823
+
1741
1824
  async function hideRing(page) {
1742
1825
  await page
1743
1826
  .evaluate(() => {
@@ -2302,6 +2385,20 @@ async function runStepMode(engine, start, end, context, page, mem, resolved, slo
2302
2385
  }
2303
2386
  return { name: k.name, value };
2304
2387
  });
2388
+ const paceSpeak = paceSpeakFields(pacing.demoPace, autoplayMs);
2389
+ if (process.env.WAYGRAPH_JSON !== "1") {
2390
+ console.log(
2391
+ "waygraph demo: step " +
2392
+ (i + 1) +
2393
+ "/" +
2394
+ resolved.length +
2395
+ " " +
2396
+ r.block.name +
2397
+ " · " +
2398
+ paceSpeak.paceLabel +
2399
+ (r.episodeNumber ? " · episode " + r.episodeNumber : ""),
2400
+ );
2401
+ }
2305
2402
  await renderBeforeStep(page, {
2306
2403
  index: i,
2307
2404
  total: resolved.length,
@@ -2318,6 +2415,7 @@ async function runStepMode(engine, start, end, context, page, mem, resolved, slo
2318
2415
  episodeTitle: r.episodeTitle,
2319
2416
  stepperMode,
2320
2417
  forceCollapsed,
2418
+ ...paceSpeak,
2321
2419
  });
2322
2420
  const edits = await gate();
2323
2421
  for (const k of requires) {
@@ -2487,6 +2585,7 @@ async function runStepMode(engine, start, end, context, page, mem, resolved, slo
2487
2585
  highlights,
2488
2586
  gatesFast: pacing.gatesFast,
2489
2587
  pace: pacing.demoPace,
2588
+ ...paceSpeakFields(pacing.demoPace, autoplayMs),
2490
2589
  isLast: i === resolved.length - 1,
2491
2590
  allNames: moduleNames,
2492
2591
  allDescriptions: moduleDescriptions,
@@ -133,6 +133,16 @@ export declare function demoPaceIsFast(pace: DemoPace): boolean;
133
133
  export declare function demoPaceIsSlow(pace: DemoPace): boolean;
134
134
  /** Autoplay / Next-gate ms for this pace (base is WAYGRAPH_AUTOPLAY_MS or 1800). */
135
135
  export declare function demoPaceGateMs(pace: DemoPace, baseAutoplayMs: number): number;
136
+ /**
137
+ * Short chip for the demo panel (e.g. `2.5x`, `4500ms`, `slow`).
138
+ * Always printable - numbers speak in the UI, not only in code.
139
+ */
140
+ export declare function formatDemoPaceBadge(pace: DemoPace, baseAutoplayMs?: number): string;
141
+ /**
142
+ * Loud one-line pace description for panel + console
143
+ * (e.g. `pace 2.5x (~4500ms gates)` / `pace 4500ms gates (~2.25x)`).
144
+ */
145
+ export declare function formatDemoPaceLabel(pace: DemoPace, baseAutoplayMs?: number): string;
136
146
  /**
137
147
  * Resolve min dwell ms for any fixture (stub / flow fixture / yap slide),
138
148
  * or `null` when duration is unset (caller keeps legacy timing).
@@ -162,6 +162,51 @@ export function demoPaceGateMs(pace, baseAutoplayMs) {
162
162
  const scale = demoPaceScale(pace);
163
163
  return Math.min(30000, Math.max(80, Math.round(baseAutoplayMs * scale)));
164
164
  }
165
+ /**
166
+ * Short chip for the demo panel (e.g. `2.5x`, `4500ms`, `slow`).
167
+ * Always printable - numbers speak in the UI, not only in code.
168
+ */
169
+ export function formatDemoPaceBadge(pace, baseAutoplayMs = 1800) {
170
+ const p = normalizeDemoPace(pace);
171
+ if (typeof p === "number" && p > 20)
172
+ return `${Math.round(p)}ms`;
173
+ if (typeof p === "number") {
174
+ const s = Number.isInteger(p) ? String(p) : String(Math.round(p * 100) / 100);
175
+ return `${s}x`;
176
+ }
177
+ if (p === "blitz")
178
+ return "blitz";
179
+ if (p === "fast")
180
+ return "fast";
181
+ if (p === "slow")
182
+ return "slow";
183
+ void baseAutoplayMs;
184
+ return "1x";
185
+ }
186
+ /**
187
+ * Loud one-line pace description for panel + console
188
+ * (e.g. `pace 2.5x (~4500ms gates)` / `pace 4500ms gates (~2.25x)`).
189
+ */
190
+ export function formatDemoPaceLabel(pace, baseAutoplayMs = 1800) {
191
+ const p = normalizeDemoPace(pace);
192
+ const gate = demoPaceGateMs(p, baseAutoplayMs);
193
+ const scale = demoPaceScale(p);
194
+ const scaleTxt = Number.isInteger(scale) ? String(scale) : (Math.round(scale * 100) / 100).toString();
195
+ if (typeof p === "number" && p > 20) {
196
+ return `pace ${Math.round(p)}ms gates (~${scaleTxt}x)`;
197
+ }
198
+ if (typeof p === "number") {
199
+ const s = Number.isInteger(p) ? String(p) : String(Math.round(p * 100) / 100);
200
+ return `pace ${s}x (~${gate}ms gates)`;
201
+ }
202
+ if (p === "blitz")
203
+ return `pace blitz (~${gate}ms, skip theater)`;
204
+ if (p === "fast")
205
+ return `pace fast (~${scaleTxt}x, ~${gate}ms gates)`;
206
+ if (p === "slow")
207
+ return `pace slow (~${scaleTxt}x, ~${gate}ms gates)`;
208
+ return `pace normal (1x, ~${gate}ms gates)`;
209
+ }
165
210
  /**
166
211
  * Resolve min dwell ms for any fixture (stub / flow fixture / yap slide),
167
212
  * or `null` when duration is unset (caller keeps legacy timing).
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { connect, checkpoint } from "./types.js";
3
3
  export { MemKey, MemPage, key, keyGroup } from "./mem-page.js";
4
4
  export { Trait, urlMatches, textEquals, visible } from "./trait.js";
5
5
  export { runGraph, spawnTab, narrate, Engine, start, end, branch, withVerify, modVerify, modVerifyAll, defineBlock, defineNavBlock, defineNavClickBlock, defineMethodBlock, defineActionBlock, definePageBlock, defineEffectBlock, defineMemEffectBlock, defineMemNavBlock, locate, composeBlock, fastForwardComposeBlock, isFastForwardBlock, preflight, withSessionReset, withTitle, withDemoPace, withBlockPace, withHighlightStyle, withExpectedFailure, withHighlightFixtures, chainFlow, } from "./engine.js";
6
- export { resolveHighlightSlots, resolveSlides, resolveFixtureDwellMs, resolveSlideDwellMs, formatHighlightCaption, hasAuthoredStubAfter, hasAuthoredStubOnError, normalizeHighlightTone, normalizeDemoPace, normalizeHighlightSize, normalizeHighlightWeight, applyHighlightStyleDefaults, toneIconPrefix, resolveStepDemoPace, demoPaceScale, demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, demoPaceGateMs, FIXTURE_DURATION_MS_DEFAULT, FIXTURE_DURATION_FAST_MS_DEFAULT, FIXTURE_DURATION_SLOW_MS_DEFAULT, SLIDE_DURATION_MS_DEFAULT, SLIDE_DURATION_FAST_MS_DEFAULT, } from "./highlights.js";
6
+ export { resolveHighlightSlots, resolveSlides, resolveFixtureDwellMs, resolveSlideDwellMs, formatHighlightCaption, hasAuthoredStubAfter, hasAuthoredStubOnError, normalizeHighlightTone, normalizeDemoPace, normalizeHighlightSize, normalizeHighlightWeight, applyHighlightStyleDefaults, toneIconPrefix, resolveStepDemoPace, demoPaceScale, demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, demoPaceGateMs, formatDemoPaceBadge, formatDemoPaceLabel, FIXTURE_DURATION_MS_DEFAULT, FIXTURE_DURATION_FAST_MS_DEFAULT, FIXTURE_DURATION_SLOW_MS_DEFAULT, SLIDE_DURATION_MS_DEFAULT, SLIDE_DURATION_FAST_MS_DEFAULT, } from "./highlights.js";
7
7
  export type { WaygraphHighlightStub, WaygraphHighlightFixture, WaygraphSlide, FixtureDurationFields, HighlightStubPhase, HighlightStubPhaseName, HighlightFixtureMap, ResolvedHighlight, WaygraphHighlight, HighlightTone, HighlightSize, HighlightWeight, HighlightStyleDefaults, DemoPace, DemoPaceName, } from "./highlights.js";
8
8
  export type { Flow, EngineConfig, ComposedBlock, FastForwardComposedBlock, RunGraphOptions, BlockInfo, NavBlock, NavBlockOptions, NavClickBlock, NavClickBlockOptions, MethodBlock, ActionBlock, PageBlock, PageBlockOptions, PageMethodEntry, EffectBlock, MemEffectBlock, MemNavBlock, } from "./engine.js";
9
9
  export type { ActionPage } from "./types.js";
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ export { connect, checkpoint } from "./types.js";
2
2
  export { MemKey, MemPage, key, keyGroup } from "./mem-page.js";
3
3
  export { Trait, urlMatches, textEquals, visible } from "./trait.js";
4
4
  export { runGraph, spawnTab, narrate, Engine, start, end, branch, withVerify, modVerify, modVerifyAll, defineBlock, defineNavBlock, defineNavClickBlock, defineMethodBlock, defineActionBlock, definePageBlock, defineEffectBlock, defineMemEffectBlock, defineMemNavBlock, locate, composeBlock, fastForwardComposeBlock, isFastForwardBlock, preflight, withSessionReset, withTitle, withDemoPace, withBlockPace, withHighlightStyle, withExpectedFailure, withHighlightFixtures, chainFlow, } from "./engine.js";
5
- export { resolveHighlightSlots, resolveSlides, resolveFixtureDwellMs, resolveSlideDwellMs, formatHighlightCaption, hasAuthoredStubAfter, hasAuthoredStubOnError, normalizeHighlightTone, normalizeDemoPace, normalizeHighlightSize, normalizeHighlightWeight, applyHighlightStyleDefaults, toneIconPrefix, resolveStepDemoPace, demoPaceScale, demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, demoPaceGateMs, FIXTURE_DURATION_MS_DEFAULT, FIXTURE_DURATION_FAST_MS_DEFAULT, FIXTURE_DURATION_SLOW_MS_DEFAULT, SLIDE_DURATION_MS_DEFAULT, SLIDE_DURATION_FAST_MS_DEFAULT, } from "./highlights.js";
5
+ export { resolveHighlightSlots, resolveSlides, resolveFixtureDwellMs, resolveSlideDwellMs, formatHighlightCaption, hasAuthoredStubAfter, hasAuthoredStubOnError, normalizeHighlightTone, normalizeDemoPace, normalizeHighlightSize, normalizeHighlightWeight, applyHighlightStyleDefaults, toneIconPrefix, resolveStepDemoPace, demoPaceScale, demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, demoPaceGateMs, formatDemoPaceBadge, formatDemoPaceLabel, FIXTURE_DURATION_MS_DEFAULT, FIXTURE_DURATION_FAST_MS_DEFAULT, FIXTURE_DURATION_SLOW_MS_DEFAULT, SLIDE_DURATION_MS_DEFAULT, SLIDE_DURATION_FAST_MS_DEFAULT, } from "./highlights.js";
6
6
  export { discoverGraph, toMermaid, findOrphanBlocks, findBlockPath } from "./graph.js";
7
7
  export { isFileSelectToken, parseBlocksSelect, matchBlocksSelect, globToRegExp, } from "./blocks-select.js";
8
8
  export { EdgeLeaseCoordinator } from "./traverse-lease.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waygraph",
3
- "version": "0.12.18",
3
+ "version": "0.12.19",
4
4
  "type": "module",
5
5
  "description": "A typed graph of reusable Blocks for driving a browser through E2E flows.",
6
6
  "license": "MIT",