@scenar/cli 0.9.0 → 0.10.0

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.
Files changed (66) hide show
  1. package/example-bundle/assets/index-DpJUOVBT.js +388 -0
  2. package/example-bundle/assets/style-ix_q0zsc.css +1 -0
  3. package/example-bundle/embed.js +1 -1
  4. package/example-bundle/index.html +2 -2
  5. package/example-bundle/pack-manifest.json +11 -11
  6. package/example-bundle/scenario.json +6 -2
  7. package/package.json +4 -4
  8. package/src/__tests__/collect-pack-shots.test.ts +115 -0
  9. package/src/__tests__/find-authored-viewport.test.ts +58 -0
  10. package/src/__tests__/pack-generate-embed-entry.test.ts +5 -1
  11. package/src/__tests__/pack-manifest.test.ts +17 -0
  12. package/src/__tests__/read-shots.test.ts +57 -0
  13. package/src/__tests__/resolve-pack-viewport.test.ts +46 -0
  14. package/src/__tests__/run-shoot.test.ts +51 -2
  15. package/src/bundle/read-shots.d.ts +28 -0
  16. package/src/bundle/read-shots.d.ts.map +1 -0
  17. package/src/bundle/read-shots.js +28 -0
  18. package/src/bundle/read-shots.js.map +1 -0
  19. package/src/bundle/read-shots.ts +38 -0
  20. package/src/commands/pack.d.ts.map +1 -1
  21. package/src/commands/pack.js +23 -4
  22. package/src/commands/pack.js.map +1 -1
  23. package/src/commands/pack.ts +26 -5
  24. package/src/pack/build.d.ts +33 -1
  25. package/src/pack/build.d.ts.map +1 -1
  26. package/src/pack/build.js +35 -10
  27. package/src/pack/build.js.map +1 -1
  28. package/src/pack/build.ts +63 -17
  29. package/src/pack/collect-pack-shots.d.ts +47 -0
  30. package/src/pack/collect-pack-shots.d.ts.map +1 -0
  31. package/src/pack/collect-pack-shots.js +66 -0
  32. package/src/pack/collect-pack-shots.js.map +1 -0
  33. package/src/pack/collect-pack-shots.ts +89 -0
  34. package/src/pack/generate-embed-entry.d.ts +7 -0
  35. package/src/pack/generate-embed-entry.d.ts.map +1 -1
  36. package/src/pack/generate-embed-entry.js +14 -3
  37. package/src/pack/generate-embed-entry.js.map +1 -1
  38. package/src/pack/generate-embed-entry.ts +15 -3
  39. package/src/pack/pack-manifest.d.ts +12 -3
  40. package/src/pack/pack-manifest.d.ts.map +1 -1
  41. package/src/pack/pack-manifest.js +13 -3
  42. package/src/pack/pack-manifest.js.map +1 -1
  43. package/src/pack/pack-manifest.ts +13 -2
  44. package/src/pack/run-pack.d.ts +13 -2
  45. package/src/pack/run-pack.d.ts.map +1 -1
  46. package/src/pack/run-pack.js +56 -17
  47. package/src/pack/run-pack.js.map +1 -1
  48. package/src/pack/run-pack.ts +81 -19
  49. package/src/pack/viewport.d.ts +17 -0
  50. package/src/pack/viewport.d.ts.map +1 -1
  51. package/src/pack/viewport.js +19 -0
  52. package/src/pack/viewport.js.map +1 -1
  53. package/src/pack/viewport.ts +29 -0
  54. package/src/shoot/run-shoot.d.ts +6 -0
  55. package/src/shoot/run-shoot.d.ts.map +1 -1
  56. package/src/shoot/run-shoot.js +18 -0
  57. package/src/shoot/run-shoot.js.map +1 -1
  58. package/src/shoot/run-shoot.ts +19 -0
  59. package/src/util/load-ts.d.ts +35 -2
  60. package/src/util/load-ts.d.ts.map +1 -1
  61. package/src/util/load-ts.js +76 -10
  62. package/src/util/load-ts.js.map +1 -1
  63. package/src/util/load-ts.ts +87 -11
  64. package/tsconfig.tsbuildinfo +1 -1
  65. package/example-bundle/assets/index-BoIR0_nN.js +0 -147
  66. package/example-bundle/assets/style-YRMeJPPX.css +0 -1
@@ -11,18 +11,16 @@ export interface ImportedStep {
11
11
  }
12
12
 
13
13
  /**
14
- * Dynamically import a TypeScript steps file and extract the
15
- * steps array by duck-typing (looks for the first exported array
16
- * whose elements have a `delayMs` property).
14
+ * Find the steps array in a loaded module's exports by duck-typing: the
15
+ * first exported array whose first element has a `delayMs` property.
16
+ * Returns null when the module exports no such array.
17
17
  *
18
- * Requires the caller's Node process to have a TypeScript loader
19
- * active (e.g. running via `tsx`). The CLI itself does not depend
20
- * on any TS compilation tool.
18
+ * This is THE steps-discovery rule, shared by every Node-side loader and
19
+ * mirrored verbatim by the browser-side `_findSteps` in the generated
20
+ * pack entry (see generate-embed-entry.ts) — the mirrors must agree, or
21
+ * pack-time tooling would see different steps than the packed bundle.
21
22
  */
22
- export async function loadStepsFromTs(filePath: string): Promise<ImportedStep[]> {
23
- const mod = await import(pathToFileURL(filePath).href);
24
- const exports = mod.default ?? mod;
25
-
23
+ export function findStepsArray(exports: Record<string, unknown>): ImportedStep[] | null {
26
24
  for (const value of Object.values(exports)) {
27
25
  if (
28
26
  Array.isArray(value) &&
@@ -34,6 +32,84 @@ export async function loadStepsFromTs(filePath: string): Promise<ImportedStep[]>
34
32
  return value as ImportedStep[];
35
33
  }
36
34
  }
35
+ return null;
36
+ }
37
+
38
+ /** A scenario-authored canonical viewport, in CSS pixels. */
39
+ export interface AuthoredViewport {
40
+ width: number;
41
+ height: number;
42
+ }
43
+
44
+ function isViewportShape(value: unknown): value is AuthoredViewport {
45
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
46
+ const record = value as Record<string, unknown>;
47
+ return (
48
+ typeof record["width"] === "number" &&
49
+ Number.isFinite(record["width"]) &&
50
+ record["width"] > 0 &&
51
+ typeof record["height"] === "number" &&
52
+ Number.isFinite(record["height"]) &&
53
+ record["height"] > 0
54
+ );
55
+ }
56
+
57
+ function isStepsShape(value: unknown): boolean {
58
+ return (
59
+ Array.isArray(value) &&
60
+ value.length > 0 &&
61
+ typeof value[0] === "object" &&
62
+ value[0] !== null &&
63
+ "delayMs" in value[0]
64
+ );
65
+ }
37
66
 
38
- throw new Error(`No steps array found in ${filePath}`);
67
+ /**
68
+ * Find the scenario's authored canonical viewport in a loaded module's
69
+ * exports, or null when the module authors none (the common case — the
70
+ * packer then falls back to CLI flags or its default).
71
+ *
72
+ * Two authored forms are honored, mirroring the two authoring surfaces:
73
+ *
74
+ * 1. A scenario-shaped export — an object carrying both a `viewport` and a
75
+ * delayMs-bearing `steps` array, i.e. what `createScenario()` returns.
76
+ * The viewport rides the scenario, so only a real scenario export
77
+ * qualifies; a stray `viewport` field on an unrelated object does not.
78
+ * 2. An export *named* `viewport` with `{ width, height }` — the
79
+ * directory-form counterpart, for authors of a raw steps array.
80
+ *
81
+ * Precedence between the two follows specificity: a scenario-shaped export
82
+ * wins, because its viewport is inseparable from the steps it sizes.
83
+ */
84
+ export function findAuthoredViewport(exports: Record<string, unknown>): AuthoredViewport | null {
85
+ for (const value of Object.values(exports)) {
86
+ if (typeof value !== "object" || value === null || Array.isArray(value)) continue;
87
+ const record = value as Record<string, unknown>;
88
+ if (isViewportShape(record["viewport"]) && isStepsShape(record["steps"])) {
89
+ const viewport = record["viewport"] as AuthoredViewport;
90
+ return { width: viewport.width, height: viewport.height };
91
+ }
92
+ }
93
+ const named = exports["viewport"];
94
+ if (isViewportShape(named)) {
95
+ return { width: named.width, height: named.height };
96
+ }
97
+ return null;
98
+ }
99
+
100
+ /**
101
+ * Dynamically import a TypeScript steps file and extract the
102
+ * steps array by duck-typing ({@link findStepsArray}).
103
+ *
104
+ * Requires the caller's Node process to have a TypeScript loader
105
+ * active (e.g. running via `tsx`). The CLI itself does not depend
106
+ * on any TS compilation tool.
107
+ */
108
+ export async function loadStepsFromTs(filePath: string): Promise<ImportedStep[]> {
109
+ const mod = await import(pathToFileURL(filePath).href);
110
+ const steps = findStepsArray(mod.default ?? mod);
111
+ if (steps === null) {
112
+ throw new Error(`No steps array found in ${filePath}`);
113
+ }
114
+ return steps;
39
115
  }