executable-stories-react 0.10.0 → 0.10.1

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/index.js CHANGED
@@ -286,23 +286,11 @@ function useReport() {
286
286
  return ctx.report;
287
287
  }
288
288
 
289
- // ../executable-stories-core/dist/utils/duration.js
290
- function formatDuration(ms) {
291
- if (ms < 1e3) {
292
- return `${Math.round(ms)} ms`;
293
- }
294
- if (ms < 6e4) {
295
- return `${(ms / 1e3).toFixed(2)} s`;
296
- }
297
- const minutes = Math.floor(ms / 6e4);
298
- const seconds = Math.floor(ms % 6e4 / 1e3);
299
- if (minutes < 60) {
300
- return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
301
- }
302
- const hours = Math.floor(minutes / 60);
303
- const remainingMinutes = minutes % 60;
304
- return `${hours}h ${remainingMinutes}m`;
305
- }
289
+ // src/components/ReportScenario.tsx
290
+ import { formatDuration as formatDuration3 } from "executable-stories-core/utils/duration";
291
+
292
+ // src/components/ReportSteps.tsx
293
+ import { formatDuration } from "executable-stories-core/utils/duration";
306
294
 
307
295
  // src/components/doc/DocNote.tsx
308
296
  import { jsx as jsx3 } from "react/jsx-runtime";
@@ -394,23 +382,8 @@ function DocLink({ entry }) {
394
382
  // src/components/doc/DocSection.tsx
395
383
  import { marked } from "marked";
396
384
 
397
- // ../executable-stories-core/dist/utils/url.js
398
- function safeUrl(value) {
399
- if (!value) return void 0;
400
- const trimmed = value.trim();
401
- const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(trimmed);
402
- if (scheme && !/^https?$/i.test(scheme[1] ?? "")) return void 0;
403
- return trimmed;
404
- }
405
- function safeImageUrl(value) {
406
- if (!value) return void 0;
407
- const trimmed = value.trim();
408
- if (/^data:image\//i.test(trimmed)) return trimmed;
409
- return safeUrl(trimmed);
410
- }
411
- function isLocalFsPath(value) {
412
- return /^(?:[/\\]|[A-Za-z]:[/\\])/.test(value);
413
- }
385
+ // src/lib/url.ts
386
+ import { safeUrl, safeImageUrl, isLocalFsPath } from "executable-stories-core/utils/url";
414
387
 
415
388
  // src/components/doc/DocSection.tsx
416
389
  import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
@@ -703,125 +676,10 @@ function ReportStepItem({ step }) {
703
676
  );
704
677
  }
705
678
 
706
- // ../executable-stories-core/dist/state-diff.js
707
- var isPlainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
708
- function deepEqual(a, b) {
709
- if (Object.is(a, b)) return true;
710
- if (Array.isArray(a) && Array.isArray(b)) {
711
- return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));
712
- }
713
- if (isPlainObject(a) && isPlainObject(b)) {
714
- const ak = Object.keys(a);
715
- const bk = Object.keys(b);
716
- return ak.length === bk.length && ak.every((k) => k in b && deepEqual(a[k], b[k]));
717
- }
718
- return false;
719
- }
720
- var joinKey = (path, key) => path === "" ? key : `${path}.${key}`;
721
- function walk(path, before, after, out) {
722
- if (Object.is(before, after)) return;
723
- if (Array.isArray(before) && Array.isArray(after)) {
724
- const shared = Math.min(before.length, after.length);
725
- for (let i = 0; i < shared; i++) walk(`${path}[${i}]`, before[i], after[i], out);
726
- for (let i = shared; i < after.length; i++) out.push({ path: `${path}[${i}]`, kind: "added", after: after[i] });
727
- for (let i = shared; i < before.length; i++) out.push({ path: `${path}[${i}]`, kind: "removed", before: before[i] });
728
- return;
729
- }
730
- if (isPlainObject(before) && isPlainObject(after)) {
731
- for (const key of Object.keys(after)) {
732
- const p = joinKey(path, key);
733
- if (key in before) walk(p, before[key], after[key], out);
734
- else out.push({ path: p, kind: "added", after: after[key] });
735
- }
736
- for (const key of Object.keys(before)) {
737
- if (!(key in after)) out.push({ path: joinKey(path, key), kind: "removed", before: before[key] });
738
- }
739
- return;
740
- }
741
- if (!deepEqual(before, after)) out.push({ path, kind: "changed", before, after });
742
- }
743
- function diffStateValues(before, after) {
744
- const out = [];
745
- walk("", before, after, out);
746
- return out;
747
- }
748
- function formatStateValue(value, maxLen = 60) {
749
- const s = value === void 0 ? "undefined" : JSON.stringify(value);
750
- return s.length > maxLen ? `${s.slice(0, maxLen - 1)}\u2026` : s;
751
- }
752
- function summarizeStateChanges(changes) {
753
- return changes.map((c) => {
754
- const at = c.path === "" ? "(root)" : c.path;
755
- switch (c.kind) {
756
- case "added":
757
- return `+ ${at}: ${formatStateValue(c.after)}`;
758
- case "removed":
759
- return `\u2212 ${at}`;
760
- case "changed":
761
- return `${at}: ${formatStateValue(c.before)} \u2192 ${formatStateValue(c.after)}`;
762
- }
763
- });
764
- }
765
-
766
- // ../executable-stories-core/dist/storyboard.js
767
- function findScreenshot(entries) {
768
- for (const entry of entries) {
769
- if (entry.kind === "screenshot") return entry;
770
- if (entry.children) {
771
- const nested = findScreenshot(entry.children);
772
- if (nested) return nested;
773
- }
774
- }
775
- return void 0;
776
- }
777
- function findStates(entries, out = []) {
778
- for (const entry of entries) {
779
- if (entry.kind === "state") out.push(entry);
780
- if (entry.children) findStates(entry.children, out);
781
- }
782
- return out;
783
- }
784
- var laneOf = (label) => label ?? "";
785
- function extractStoryboardFrames(scenario) {
786
- const frames = [];
787
- const laneOrder = [];
788
- const previous = /* @__PURE__ */ new Map();
789
- for (const step of scenario.steps) {
790
- const shot = findScreenshot(step.docEntries);
791
- const stateDocs = findStates(step.docEntries);
792
- if (!shot && stateDocs.length === 0) continue;
793
- const byLane = /* @__PURE__ */ new Map();
794
- for (const doc of stateDocs) {
795
- const lane = laneOf(doc.label);
796
- if (!byLane.has(lane) && !laneOrder.includes(lane)) laneOrder.push(lane);
797
- byLane.set(lane, doc);
798
- }
799
- const states = [];
800
- for (const lane of laneOrder) {
801
- const doc = byLane.get(lane);
802
- if (!doc) continue;
803
- const card = {
804
- ...doc.label !== void 0 && { label: doc.label },
805
- value: doc.value
806
- };
807
- if (previous.has(lane)) card.changes = diffStateValues(previous.get(lane), doc.value);
808
- previous.set(lane, doc.value);
809
- states.push(card);
810
- }
811
- frames.push({
812
- stepId: step.id,
813
- stepIndex: step.index,
814
- keyword: step.keyword,
815
- text: step.text,
816
- status: step.status,
817
- ...shot && { screenshot: { path: shot.path, ...shot.alt !== void 0 && { alt: shot.alt } } },
818
- states
819
- });
820
- }
821
- return frames;
822
- }
823
-
824
679
  // src/components/ReportStoryboard.tsx
680
+ import { extractStoryboardFrames } from "executable-stories-core/storyboard";
681
+ import { summarizeStateChanges } from "executable-stories-core/state-diff";
682
+ import { isLocalFsPath as isLocalFsPath2, safeImageUrl as safeImageUrl2 } from "executable-stories-core/utils/url";
825
683
  import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
826
684
  var FRAME_GLYPH = {
827
685
  passed: "\u2713",
@@ -870,7 +728,7 @@ function StoryboardFrameItem({ frame }) {
870
728
  }
871
729
  function FrameScreenshot({ frame, label }) {
872
730
  const path = frame.screenshot?.path ?? "";
873
- const src = isLocalFsPath(path) ? void 0 : safeImageUrl(path);
731
+ const src = isLocalFsPath2(path) ? void 0 : safeImageUrl2(path);
874
732
  return /* @__PURE__ */ jsx20(
875
733
  "a",
876
734
  {
@@ -976,6 +834,9 @@ function ReportAttachments({ attachments }) {
976
834
  );
977
835
  }
978
836
 
837
+ // src/components/ReportTrace.tsx
838
+ import { formatDuration as formatDuration2 } from "executable-stories-core/utils/duration";
839
+
979
840
  // src/lib/trace.ts
980
841
  var VALID = /* @__PURE__ */ new Set(["ok", "error", "unset"]);
981
842
  var safeStatus = (s) => VALID.has(s) ? s : "unset";
@@ -1028,15 +889,15 @@ function toTraceRows(spans) {
1028
889
  roots.sort((a, b) => a.span.startTimeMs - b.span.startTimeMs);
1029
890
  const rows = [];
1030
891
  const seen = /* @__PURE__ */ new Set();
1031
- const walk2 = (node, depth) => {
892
+ const walk = (node, depth) => {
1032
893
  if (seen.has(node.span.spanId)) return;
1033
894
  seen.add(node.span.spanId);
1034
895
  rows.push({ ...node.span, depth });
1035
- for (const child of node.children) walk2(child, depth + 1);
896
+ for (const child of node.children) walk(child, depth + 1);
1036
897
  };
1037
- for (const root of roots) walk2(root, 0);
898
+ for (const root of roots) walk(root, 0);
1038
899
  for (const node of byId.values()) {
1039
- if (!seen.has(node.span.spanId)) walk2(node, 0);
900
+ if (!seen.has(node.span.spanId)) walk(node, 0);
1040
901
  }
1041
902
  return rows;
1042
903
  }
@@ -1070,7 +931,7 @@ function ReportTrace({ spans }) {
1070
931
  " span",
1071
932
  rows.length === 1 ? "" : "s",
1072
933
  ", ",
1073
- formatDuration(totalMs),
934
+ formatDuration2(totalMs),
1074
935
  ")"
1075
936
  ] }),
1076
937
  /* @__PURE__ */ jsx22("ul", { className: "flex flex-col gap-0.5 px-3 pb-3 font-mono text-[0.6875rem]", children: rows.map((row, i) => {
@@ -1093,7 +954,7 @@ function ReportTrace({ spans }) {
1093
954
  style: { left: `${leftPct}%`, width: `${widthPct}%` }
1094
955
  }
1095
956
  ) }),
1096
- /* @__PURE__ */ jsx22("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: formatDuration(row.durationMs) })
957
+ /* @__PURE__ */ jsx22("span", { className: "w-16 shrink-0 text-right text-muted-foreground", children: formatDuration2(row.durationMs) })
1097
958
  ] }, `${row.spanId}-${i}`);
1098
959
  }) })
1099
960
  ] });
@@ -1204,6 +1065,7 @@ function useCollapse() {
1204
1065
 
1205
1066
  // src/interactive/scenario-actions.tsx
1206
1067
  import { createContext as createContext4, useContext as useContext5 } from "react";
1068
+ import { scenarioToMarkdown as coreScenarioToMarkdown } from "executable-stories-core/utils/scenario-markdown";
1207
1069
  var ScenarioActionsContext = createContext4(null);
1208
1070
  var ScenarioActionsProvider = ScenarioActionsContext.Provider;
1209
1071
  function useScenarioActions() {
@@ -1349,7 +1211,7 @@ function ReportScenario({ scenario, hideTitle = false }) {
1349
1211
  ] }),
1350
1212
  /* @__PURE__ */ jsxs17("div", { className: "flex shrink-0 items-center gap-2", children: [
1351
1213
  /* @__PURE__ */ jsx26(ScenarioRunHistory, { scenarioId: scenario.id }),
1352
- scenario.durationMs > 0 ? /* @__PURE__ */ jsx26("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration(scenario.durationMs) }) : null,
1214
+ scenario.durationMs > 0 ? /* @__PURE__ */ jsx26("span", { className: "whitespace-nowrap font-mono text-[0.6875rem] text-muted-foreground", children: formatDuration3(scenario.durationMs) }) : null,
1353
1215
  meta.showPill ? /* @__PURE__ */ jsx26(Badge, { variant: meta.badgeVariant, "aria-label": `Status: ${label}`, children: label }) : /* @__PURE__ */ jsx26("span", { className: "sr-only", children: `Status: ${label}` }),
1354
1216
  actions ? /* @__PURE__ */ jsxs17(DropdownMenu, { children: [
1355
1217
  /* @__PURE__ */ jsx26(
@@ -1609,6 +1471,9 @@ function ReportSummaryView({ summary, className, ariaLabel }) {
1609
1471
  );
1610
1472
  }
1611
1473
 
1474
+ // src/components/ReportMeta.tsx
1475
+ import { formatDuration as formatDuration4 } from "executable-stories-core/utils/duration";
1476
+
1612
1477
  // src/lib/provenance.ts
1613
1478
  function reportLastRunMs(report) {
1614
1479
  if (report.finishedAtMs && report.finishedAtMs > 0) return report.finishedAtMs;
@@ -1668,7 +1533,7 @@ function ReportMeta() {
1668
1533
  items.push({ label: "Started", value: new Date(report.startedAtMs).toLocaleString() });
1669
1534
  }
1670
1535
  if (report.durationMs) {
1671
- items.push({ label: "Duration", value: formatDuration(report.durationMs) });
1536
+ items.push({ label: "Duration", value: formatDuration4(report.durationMs) });
1672
1537
  }
1673
1538
  if (report.packageVersion) {
1674
1539
  items.push({ label: "Version", value: report.packageVersion });