@design.estate/wcctools 6.1.0 → 7.0.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 (112) hide show
  1. package/changelog.md +41 -0
  2. package/dist_shell/bundle.js +405 -368
  3. package/dist_shell/bundle.js.map +1 -1
  4. package/dist_shell/bundle.js.third-party-notices.json +52 -0
  5. package/dist_shell/bundle.js.third-party-notices.txt +107 -1
  6. package/dist_shell/index.html +1 -1
  7. package/dist_ts/00_commitinfo_data.js +1 -1
  8. package/dist_ts/capture/classes.capturebrowser.d.ts +65 -0
  9. package/dist_ts/capture/classes.capturebrowser.js +251 -0
  10. package/dist_ts/capture/classes.captureservice.d.ts +39 -0
  11. package/dist_ts/capture/classes.captureservice.js +119 -0
  12. package/dist_ts/capture/classes.screencast.d.ts +47 -0
  13. package/dist_ts/capture/classes.screencast.js +127 -0
  14. package/dist_ts/capture/errors.d.ts +14 -0
  15. package/dist_ts/capture/errors.js +23 -0
  16. package/dist_ts/capture/images.d.ts +3 -0
  17. package/dist_ts/capture/images.js +58 -0
  18. package/dist_ts/capture/index.d.ts +4 -0
  19. package/dist_ts/capture/index.js +5 -0
  20. package/dist_ts/capture/interaction.d.ts +11 -0
  21. package/dist_ts/capture/interaction.js +138 -0
  22. package/dist_ts/capture/navigationguard.d.ts +44 -0
  23. package/dist_ts/capture/navigationguard.js +129 -0
  24. package/dist_ts/capture/previewpage.d.ts +29 -0
  25. package/dist_ts/capture/previewpage.js +96 -0
  26. package/dist_ts/capture/request.d.ts +69 -0
  27. package/dist_ts/capture/request.js +239 -0
  28. package/dist_ts/classes.bundlestatus.d.ts +36 -0
  29. package/dist_ts/classes.bundlestatus.js +110 -0
  30. package/dist_ts/classes.devapi.d.ts +3 -0
  31. package/dist_ts/classes.devapi.js +8 -1
  32. package/dist_ts/classes.devserver.d.ts +65 -14
  33. package/dist_ts/classes.devserver.js +157 -52
  34. package/dist_ts/classes.hostpolicy.d.ts +63 -0
  35. package/dist_ts/classes.hostpolicy.js +171 -0
  36. package/dist_ts/cli.js +28 -3
  37. package/dist_ts/cli.screenshot.d.ts +6 -0
  38. package/dist_ts/cli.screenshot.js +89 -0
  39. package/dist_ts/index.d.ts +0 -2
  40. package/dist_ts/index.js +1 -3
  41. package/dist_ts/plugins.d.ts +6 -2
  42. package/dist_ts/plugins.js +8 -3
  43. package/dist_ts_interfaces/capture.d.ts +151 -0
  44. package/dist_ts_interfaces/capture.js +2 -0
  45. package/dist_ts_interfaces/index.d.ts +1 -0
  46. package/dist_ts_interfaces/index.js +2 -1
  47. package/dist_ts_interfaces/requests.d.ts +59 -0
  48. package/dist_ts_shell/bundlestatus.d.ts +15 -0
  49. package/dist_ts_shell/bundlestatus.js +64 -0
  50. package/dist_ts_shell/elements/wcc-contextmenu.d.ts +3 -0
  51. package/dist_ts_shell/elements/wcc-contextmenu.js +18 -3
  52. package/dist_ts_shell/elements/wcc-preview-frame.d.ts +6 -0
  53. package/dist_ts_shell/elements/wcc-preview-frame.js +50 -2
  54. package/dist_ts_shell/elements/wcc-recording-panel.d.ts +9 -0
  55. package/dist_ts_shell/elements/wcc-recording-panel.js +12 -1
  56. package/dist_ts_shell/elements/wcc-shell.d.ts +15 -0
  57. package/dist_ts_shell/elements/wcc-shell.js +45 -3
  58. package/dist_ts_shell/plugins.d.ts +2 -1
  59. package/dist_ts_shell/plugins.js +3 -2
  60. package/dist_ts_shell/services/framesampler.service.d.ts +23 -0
  61. package/dist_ts_shell/services/framesampler.service.js +101 -0
  62. package/dist_ts_web/00_commitinfo_data.js +1 -1
  63. package/package.json +6 -2
  64. package/readme.md +108 -6
  65. package/ts/00_commitinfo_data.ts +1 -1
  66. package/ts/capture/classes.capturebrowser.ts +290 -0
  67. package/ts/capture/classes.captureservice.ts +152 -0
  68. package/ts/capture/classes.screencast.ts +152 -0
  69. package/ts/capture/errors.ts +25 -0
  70. package/ts/capture/images.ts +61 -0
  71. package/ts/capture/index.ts +4 -0
  72. package/ts/capture/interaction.ts +146 -0
  73. package/ts/capture/navigationguard.ts +147 -0
  74. package/ts/capture/previewpage.ts +130 -0
  75. package/ts/capture/request.ts +304 -0
  76. package/ts/classes.bundlestatus.ts +123 -0
  77. package/ts/classes.devapi.ts +9 -0
  78. package/ts/classes.devserver.ts +172 -50
  79. package/ts/classes.hostpolicy.ts +201 -0
  80. package/ts/cli.screenshot.ts +95 -0
  81. package/ts/cli.ts +28 -2
  82. package/ts/index.ts +0 -2
  83. package/ts/plugins.ts +9 -2
  84. package/ts_interfaces/bridge.ts +95 -0
  85. package/ts_interfaces/capture.ts +144 -0
  86. package/ts_interfaces/catalog.ts +37 -0
  87. package/ts_interfaces/index.ts +5 -0
  88. package/ts_interfaces/plugins.ts +3 -0
  89. package/ts_interfaces/requests.ts +104 -0
  90. package/ts_interfaces/standard.ts +103 -0
  91. package/ts_shared/index.ts +1 -0
  92. package/ts_shared/plugins.ts +3 -0
  93. package/ts_shared/previewroute.ts +58 -0
  94. package/ts_shell/bundlestatus.ts +68 -0
  95. package/ts_shell/elements/wcc-contextmenu.ts +306 -0
  96. package/ts_shell/elements/wcc-preview-frame.ts +167 -0
  97. package/ts_shell/elements/wcc-properties.ts +998 -0
  98. package/ts_shell/elements/wcc-record-button.ts +108 -0
  99. package/ts_shell/elements/wcc-recording-panel.ts +1017 -0
  100. package/ts_shell/elements/wcc-shell.ts +485 -0
  101. package/ts_shell/elements/wcc-sidebar.ts +1419 -0
  102. package/ts_shell/index.html +21 -0
  103. package/ts_shell/index.ts +4 -0
  104. package/ts_shell/plugins.ts +12 -0
  105. package/ts_shell/previewconnection.ts +103 -0
  106. package/ts_shell/services/framesampler.service.ts +112 -0
  107. package/ts_shell/services/recorder.service.ts +451 -0
  108. package/ts_shell/types/dom-mediacapture-stub/index.d.ts +12 -0
  109. package/ts_shell/types/dom-mediacapture-stub/package.json +6 -0
  110. package/ts_shell/types/dom-webcodecs-stub/index.d.ts +2 -0
  111. package/ts_shell/types/dom-webcodecs-stub/package.json +6 -0
  112. package/ts_web/00_commitinfo_data.ts +1 -1
@@ -35,6 +35,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
35
35
  import { DeesElement, property, state, html, customElement } from '@design.estate/dees-element';
36
36
  import * as plugins from '../plugins.js';
37
37
  import { WccPreviewConnection } from '../previewconnection.js';
38
+ import { WccBundleStatusClient } from '../bundlestatus.js';
38
39
  import './wcc-preview-frame.js';
39
40
  import './wcc-sidebar.js';
40
41
  import './wcc-properties.js';
@@ -56,6 +57,9 @@ let WccShell = (() => {
56
57
  let _previewPath_decorators;
57
58
  let _previewPath_initializers = [];
58
59
  let _previewPath_extraInitializers = [];
60
+ let _apiPath_decorators;
61
+ let _apiPath_initializers = [];
62
+ let _apiPath_extraInitializers = [];
59
63
  let _selection_decorators;
60
64
  let _selection_initializers = [];
61
65
  let _selection_extraInitializers = [];
@@ -95,11 +99,15 @@ let WccShell = (() => {
95
99
  let _captureTarget_decorators;
96
100
  let _captureTarget_initializers = [];
97
101
  let _captureTarget_extraInitializers = [];
102
+ let _bundleFailures_decorators;
103
+ let _bundleFailures_initializers = [];
104
+ let _bundleFailures_extraInitializers = [];
98
105
  var WccShell = class extends _classSuper {
99
106
  static { _classThis = this; }
100
107
  static {
101
108
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
102
109
  _previewPath_decorators = [property({ attribute: 'preview-path' })];
110
+ _apiPath_decorators = [property({ attribute: 'api-path' })];
103
111
  _selection_decorators = [property({ attribute: false })];
104
112
  _selectedViewport_decorators = [property()];
105
113
  _selectedTheme_decorators = [property()];
@@ -113,7 +121,9 @@ let WccShell = (() => {
113
121
  _advancedEditorOpen_decorators = [state()];
114
122
  _isResizing_decorators = [state()];
115
123
  _captureTarget_decorators = [state()];
124
+ _bundleFailures_decorators = [state()];
116
125
  __esDecorate(this, null, _previewPath_decorators, { kind: "accessor", name: "previewPath", static: false, private: false, access: { has: obj => "previewPath" in obj, get: obj => obj.previewPath, set: (obj, value) => { obj.previewPath = value; } }, metadata: _metadata }, _previewPath_initializers, _previewPath_extraInitializers);
126
+ __esDecorate(this, null, _apiPath_decorators, { kind: "accessor", name: "apiPath", static: false, private: false, access: { has: obj => "apiPath" in obj, get: obj => obj.apiPath, set: (obj, value) => { obj.apiPath = value; } }, metadata: _metadata }, _apiPath_initializers, _apiPath_extraInitializers);
117
127
  __esDecorate(this, null, _selection_decorators, { kind: "accessor", name: "selection", static: false, private: false, access: { has: obj => "selection" in obj, get: obj => obj.selection, set: (obj, value) => { obj.selection = value; } }, metadata: _metadata }, _selection_initializers, _selection_extraInitializers);
118
128
  __esDecorate(this, null, _selectedViewport_decorators, { kind: "accessor", name: "selectedViewport", static: false, private: false, access: { has: obj => "selectedViewport" in obj, get: obj => obj.selectedViewport, set: (obj, value) => { obj.selectedViewport = value; } }, metadata: _metadata }, _selectedViewport_initializers, _selectedViewport_extraInitializers);
119
129
  __esDecorate(this, null, _selectedTheme_decorators, { kind: "accessor", name: "selectedTheme", static: false, private: false, access: { has: obj => "selectedTheme" in obj, get: obj => obj.selectedTheme, set: (obj, value) => { obj.selectedTheme = value; } }, metadata: _metadata }, _selectedTheme_initializers, _selectedTheme_extraInitializers);
@@ -127,6 +137,7 @@ let WccShell = (() => {
127
137
  __esDecorate(this, null, _advancedEditorOpen_decorators, { kind: "accessor", name: "advancedEditorOpen", static: false, private: false, access: { has: obj => "advancedEditorOpen" in obj, get: obj => obj.advancedEditorOpen, set: (obj, value) => { obj.advancedEditorOpen = value; } }, metadata: _metadata }, _advancedEditorOpen_initializers, _advancedEditorOpen_extraInitializers);
128
138
  __esDecorate(this, null, _isResizing_decorators, { kind: "accessor", name: "isResizing", static: false, private: false, access: { has: obj => "isResizing" in obj, get: obj => obj.isResizing, set: (obj, value) => { obj.isResizing = value; } }, metadata: _metadata }, _isResizing_initializers, _isResizing_extraInitializers);
129
139
  __esDecorate(this, null, _captureTarget_decorators, { kind: "accessor", name: "captureTarget", static: false, private: false, access: { has: obj => "captureTarget" in obj, get: obj => obj.captureTarget, set: (obj, value) => { obj.captureTarget = value; } }, metadata: _metadata }, _captureTarget_initializers, _captureTarget_extraInitializers);
140
+ __esDecorate(this, null, _bundleFailures_decorators, { kind: "accessor", name: "bundleFailures", static: false, private: false, access: { has: obj => "bundleFailures" in obj, get: obj => obj.bundleFailures, set: (obj, value) => { obj.bundleFailures = value; } }, metadata: _metadata }, _bundleFailures_initializers, _bundleFailures_extraInitializers);
130
141
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
131
142
  WccShell = _classThis = _classDescriptor.value;
132
143
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -136,7 +147,15 @@ let WccShell = (() => {
136
147
  /** The path the server serves the preview document on. */
137
148
  get previewPath() { return this.#previewPath_accessor_storage; }
138
149
  set previewPath(value) { this.#previewPath_accessor_storage = value; }
139
- #selection_accessor_storage = (__runInitializers(this, _previewPath_extraInitializers), __runInitializers(this, _selection_initializers, null));
150
+ #apiPath_accessor_storage = (__runInitializers(this, _previewPath_extraInitializers), __runInitializers(this, _apiPath_initializers, ''));
151
+ /**
152
+ * The dev server's typed API. With it, the shell follows the bundle status and shows a failed
153
+ * catalog bundle over the preview; without it (the shell outside `wcctools dev`), it does not.
154
+ * Read when the shell connects.
155
+ */
156
+ get apiPath() { return this.#apiPath_accessor_storage; }
157
+ set apiPath(value) { this.#apiPath_accessor_storage = value; }
158
+ #selection_accessor_storage = (__runInitializers(this, _apiPath_extraInitializers), __runInitializers(this, _selection_initializers, null));
140
159
  get selection() { return this.#selection_accessor_storage; }
141
160
  set selection(value) { this.#selection_accessor_storage = value; }
142
161
  #selectedViewport_accessor_storage = (__runInitializers(this, _selection_extraInitializers), __runInitializers(this, _selectedViewport_initializers, 'desktop'));
@@ -179,10 +198,14 @@ let WccShell = (() => {
179
198
  #captureTarget_accessor_storage = (__runInitializers(this, _isResizing_extraInitializers), __runInitializers(this, _captureTarget_initializers, null));
180
199
  get captureTarget() { return this.#captureTarget_accessor_storage; }
181
200
  set captureTarget(value) { this.#captureTarget_accessor_storage = value; }
201
+ #bundleFailures_accessor_storage = (__runInitializers(this, _captureTarget_extraInitializers), __runInitializers(this, _bundleFailures_initializers, []));
202
+ /** The catalog bundles whose latest completed run failed, as the dev server reports them. */
203
+ get bundleFailures() { return this.#bundleFailures_accessor_storage; }
204
+ set bundleFailures(value) { this.#bundleFailures_accessor_storage = value; }
182
205
  get isNative() {
183
206
  return this.selectedViewport === 'native';
184
207
  }
185
- frameScrollY = (__runInitializers(this, _captureTarget_extraInitializers), 0);
208
+ frameScrollY = (__runInitializers(this, _bundleFailures_extraInitializers), 0);
186
209
  sidebarScrollY = 0;
187
210
  scrollPositionsRestored = false;
188
211
  /** The selection the preview shows, as far as the shell asked it to. */
@@ -202,6 +225,7 @@ let WccShell = (() => {
202
225
  this.debouncedScrollUpdate();
203
226
  },
204
227
  });
228
+ bundleStatusClient = null;
205
229
  routeDisposers = [];
206
230
  scrollDisposers = [];
207
231
  scrollUpdateTimeout;
@@ -281,6 +305,7 @@ let WccShell = (() => {
281
305
  .sidebarWidth=${this.sidebarWidth}
282
306
  .advancedEditorOpen=${this.advancedEditorOpen}
283
307
  .isResizing=${this.isResizing}
308
+ .bundleFailures=${this.bundleFailures}
284
309
  ></wcc-preview-frame>
285
310
  `;
286
311
  }
@@ -299,6 +324,7 @@ let WccShell = (() => {
299
324
  const connected = super.connectedCallback();
300
325
  document.addEventListener('keydown', this.handleDocumentKeydown);
301
326
  this.connection.start();
327
+ this.startBundleStatus();
302
328
  if (this.hasUpdated) {
303
329
  await this.setupSidebarScrollListener();
304
330
  }
@@ -309,6 +335,8 @@ let WccShell = (() => {
309
335
  const disconnected = super.disconnectedCallback();
310
336
  document.removeEventListener('keydown', this.handleDocumentKeydown);
311
337
  this.connection.dispose();
338
+ this.bundleStatusClient?.dispose();
339
+ this.bundleStatusClient = null;
312
340
  this.bridge = null;
313
341
  for (const dispose of this.routeDisposers) {
314
342
  dispose();
@@ -318,6 +346,20 @@ let WccShell = (() => {
318
346
  clearTimeout(this.scrollUpdateTimeout);
319
347
  return disconnected;
320
348
  }
349
+ startBundleStatus() {
350
+ if (!this.apiPath || this.bundleStatusClient) {
351
+ return;
352
+ }
353
+ this.bundleStatusClient = new WccBundleStatusClient(this.apiPath, (snapshotArg) => this.applyBundleStatus(snapshotArg));
354
+ this.bundleStatusClient.start();
355
+ }
356
+ /**
357
+ * Apply the dev server's bundle status: a bundle whose latest completed run failed is shown
358
+ * over the preview until a run of it finishes, which also reloads the preview.
359
+ */
360
+ applyBundleStatus(snapshotArg) {
361
+ this.bundleFailures = snapshotArg.bundles.filter((bundleArg) => bundleArg.errorMessage !== undefined);
362
+ }
321
363
  async firstUpdated() {
322
364
  await this.setupSidebarScrollListener();
323
365
  }
@@ -521,4 +563,4 @@ let WccShell = (() => {
521
563
  return WccShell = _classThis;
522
564
  })();
523
565
  export { WccShell };
524
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2NjLXNoZWxsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHNfc2hlbGwvZWxlbWVudHMvd2NjLXNoZWxsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBdUIsTUFBTSw2QkFBNkIsQ0FBQztBQUNySCxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUcvRCxPQUFPLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxxQkFBcUIsQ0FBQztBQVc3QixNQUFNLFNBQVMsR0FBbUIsQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDdEYsTUFBTSxtQkFBbUIsR0FBRyxHQUFHLENBQUM7QUFFaEMsTUFBTSxZQUFZLEdBQUcsQ0FBQyxZQUFxRCxFQUFpQixFQUFFLENBQzVGLFlBQVksQ0FBQyxDQUFDLENBQUMsR0FBRyxZQUFZLENBQUMsV0FBVyxLQUFLLFlBQVksQ0FBQyxRQUFRLEtBQUssWUFBWSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFRM0c7Ozs7O0dBS0c7SUFFVSxRQUFROzRCQURwQixhQUFhLENBQUMsV0FBVyxDQUFDOzs7O3NCQUNHLFdBQVc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7d0JBQW5CLFNBQVEsV0FBVzs7Ozt1Q0FFdEMsUUFBUSxDQUFDLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxDQUFDO3FDQUd2QyxRQUFRLENBQUMsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7NENBRzlCLFFB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
566
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2NjLXNoZWxsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHNfc2hlbGwvZWxlbWVudHMvd2NjLXNoZWxsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBdUIsTUFBTSw2QkFBNkIsQ0FBQztBQUNySCxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUMvRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUczRCxPQUFPLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxxQkFBcUIsQ0FBQztBQVc3QixNQUFNLFNBQVMsR0FBbUIsQ0FBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDdEYsTUFBTSxtQkFBbUIsR0FBRyxHQUFHLENBQUM7QUFFaEMsTUFBTSxZQUFZLEdBQUcsQ0FBQyxZQUFxRCxFQUFpQixFQUFFLENBQzVGLFlBQVksQ0FBQyxDQUFDLENBQUMsR0FBRyxZQUFZLENBQUMsV0FBVyxLQUFLLFlBQVksQ0FBQyxRQUFRLEtBQUssWUFBWSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFRM0c7Ozs7O0dBS0c7SUFFVSxRQUFROzRCQURwQixhQUFhLENBQUMsV0FBVyxDQUFDOzs7O3NCQUNHLFdBQVc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7d0JBQW5CLFNBQVEsV0FBVzs7Ozt1Q0FFdEMsUUFBUSxDQUFDLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxDQUFDO21DQVF2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
@@ -1,4 +1,5 @@
1
+ import * as typedrequest from '@api.global/typedrequest';
1
2
  import * as deesDomtools from '@design.estate/dees-domtools';
2
3
  import * as interfaces from '../dist_ts_interfaces/index.js';
3
4
  import * as shared from '../dist_ts_shared/index.js';
4
- export { deesDomtools, interfaces, shared, };
5
+ export { typedrequest, deesDomtools, interfaces, shared, };
@@ -1,5 +1,6 @@
1
+ import * as typedrequest from '@api.global/typedrequest';
1
2
  import * as deesDomtools from '@design.estate/dees-domtools';
2
3
  import * as interfaces from '../dist_ts_interfaces/index.js';
3
4
  import * as shared from '../dist_ts_shared/index.js';
4
- export { deesDomtools, interfaces, shared, };
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3NoZWxsL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLFlBQVksTUFBTSw4QkFBOEIsQ0FBQztBQUU3RCxPQUFPLEtBQUssVUFBVSxNQUFNLDJCQUEyQixDQUFDO0FBQ3hELE9BQU8sS0FBSyxNQUFNLE1BQU0sdUJBQXVCLENBQUM7QUFFaEQsT0FBTyxFQUNMLFlBQVksRUFDWixVQUFVLEVBQ1YsTUFBTSxHQUNQLENBQUMifQ==
5
+ export { typedrequest, deesDomtools, interfaces, shared, };
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3NoZWxsL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLFlBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEtBQUssWUFBWSxNQUFNLDhCQUE4QixDQUFDO0FBRTdELE9BQU8sS0FBSyxVQUFVLE1BQU0sMkJBQTJCLENBQUM7QUFDeEQsT0FBTyxLQUFLLE1BQU0sTUFBTSx1QkFBdUIsQ0FBQztBQUVoRCxPQUFPLEVBQ0wsWUFBWSxFQUNaLFlBQVksRUFDWixVQUFVLEVBQ1YsTUFBTSxHQUNQLENBQUMifQ==
@@ -0,0 +1,23 @@
1
+ import type * as plugins from '../plugins.js';
2
+ type IWccTimedFrame = plugins.interfaces.IWccTimedFrame;
3
+ type IWccFrameSamplingOptions = plugins.interfaces.IWccFrameSamplingOptions;
4
+ /** The limits of a frame sampling. */
5
+ export declare const frameSamplingLimits: {
6
+ readonly defaultCount: 8;
7
+ readonly maxCount: 32;
8
+ readonly defaultMaxWidth: 960;
9
+ readonly minMaxWidth: 64;
10
+ readonly maxMaxWidth: 3840;
11
+ readonly defaultQuality: 0.8;
12
+ };
13
+ /** Thrown when a recording cannot be sampled as asked. */
14
+ export declare class FrameSamplingError extends Error {
15
+ constructor(messageArg: string);
16
+ }
17
+ /**
18
+ * Samples timestamped JPEG frames from a recording (a WebM or MP4 blob, as the recorder produces):
19
+ * `count` frames at the middles of as many equal parts of the range, each the frame on screen at
20
+ * that time, scaled down to `maxWidth`. Frames that repeat one already sampled are left out.
21
+ */
22
+ export declare const sampleVideoFrames: (recordingArg: Blob, optionsArg?: IWccFrameSamplingOptions) => Promise<IWccTimedFrame[]>;
23
+ export {};
@@ -0,0 +1,101 @@
1
+ /** The limits of a frame sampling. */
2
+ export const frameSamplingLimits = {
3
+ defaultCount: 8,
4
+ maxCount: 32,
5
+ defaultMaxWidth: 960,
6
+ minMaxWidth: 64,
7
+ maxMaxWidth: 3840,
8
+ defaultQuality: 0.8,
9
+ };
10
+ /** Thrown when a recording cannot be sampled as asked. */
11
+ export class FrameSamplingError extends Error {
12
+ constructor(messageArg) {
13
+ super(messageArg);
14
+ this.name = 'FrameSamplingError';
15
+ }
16
+ }
17
+ const encodeBase64 = async (blobArg) => {
18
+ const bytes = new Uint8Array(await blobArg.arrayBuffer());
19
+ let binary = '';
20
+ // In chunks: String.fromCharCode takes a bounded number of arguments
21
+ for (let offset = 0; offset < bytes.length; offset += 0x8000) {
22
+ binary += String.fromCharCode(...bytes.subarray(offset, offset + 0x8000));
23
+ }
24
+ return btoa(binary);
25
+ };
26
+ const encodeJpeg = (canvasArg, qualityArg) => {
27
+ if (canvasArg instanceof OffscreenCanvas) {
28
+ return canvasArg.convertToBlob({ type: 'image/jpeg', quality: qualityArg });
29
+ }
30
+ return new Promise((resolve, reject) => {
31
+ canvasArg.toBlob((blobArg) => {
32
+ if (blobArg) {
33
+ resolve(blobArg);
34
+ }
35
+ else {
36
+ reject(new FrameSamplingError('wcctools: a recording frame could not be encoded as JPEG.'));
37
+ }
38
+ }, 'image/jpeg', qualityArg);
39
+ });
40
+ };
41
+ /**
42
+ * Samples timestamped JPEG frames from a recording (a WebM or MP4 blob, as the recorder produces):
43
+ * `count` frames at the middles of as many equal parts of the range, each the frame on screen at
44
+ * that time, scaled down to `maxWidth`. Frames that repeat one already sampled are left out.
45
+ */
46
+ export const sampleVideoFrames = async (recordingArg, optionsArg = {}) => {
47
+ const count = optionsArg.count ?? frameSamplingLimits.defaultCount;
48
+ if (!Number.isInteger(count) || count < 1 || count > frameSamplingLimits.maxCount) {
49
+ throw new FrameSamplingError(`wcctools: the frame count must be a whole number from 1 to ${frameSamplingLimits.maxCount}.`);
50
+ }
51
+ const maxWidth = optionsArg.maxWidth ?? frameSamplingLimits.defaultMaxWidth;
52
+ if (!Number.isInteger(maxWidth) || maxWidth < frameSamplingLimits.minMaxWidth || maxWidth > frameSamplingLimits.maxMaxWidth) {
53
+ throw new FrameSamplingError(`wcctools: maxWidth must be a whole number from ${frameSamplingLimits.minMaxWidth} to ${frameSamplingLimits.maxMaxWidth}.`);
54
+ }
55
+ const quality = optionsArg.quality ?? frameSamplingLimits.defaultQuality;
56
+ if (!(quality > 0 && quality <= 1)) {
57
+ throw new FrameSamplingError('wcctools: the quality must be above 0 and at most 1.');
58
+ }
59
+ const { Input, BlobSource, CanvasSink, ALL_FORMATS } = await import('mediabunny');
60
+ const input = new Input({ source: new BlobSource(recordingArg), formats: ALL_FORMATS });
61
+ try {
62
+ const track = await input.getPrimaryVideoTrack();
63
+ if (!track) {
64
+ throw new FrameSamplingError('wcctools: the recording has no video track.');
65
+ }
66
+ if (!(await track.canDecode())) {
67
+ throw new FrameSamplingError(`wcctools: this browser cannot decode the recording's ${track.codec ?? 'unknown'} video.`);
68
+ }
69
+ const firstTimestamp = await track.getFirstTimestamp();
70
+ const duration = await track.computeDuration();
71
+ const startS = Math.max(optionsArg.startS ?? firstTimestamp, firstTimestamp);
72
+ const endS = Math.min(optionsArg.endS ?? duration, duration);
73
+ if (!(endS > startS)) {
74
+ throw new FrameSamplingError(`wcctools: the range ${startS}–${endS} s holds no frames of the ${duration} s recording.`);
75
+ }
76
+ const sink = new CanvasSink(track, track.displayWidth > maxWidth ? { width: maxWidth } : {});
77
+ const step = (endS - startS) / count;
78
+ const timestamps = Array.from({ length: count }, (_, indexArg) => startS + step * (indexArg + 0.5));
79
+ const frames = [];
80
+ let previousTimestamp = null;
81
+ for await (const wrapped of sink.canvasesAtTimestamps(timestamps)) {
82
+ if (!wrapped || wrapped.timestamp === previousTimestamp) {
83
+ continue;
84
+ }
85
+ previousTimestamp = wrapped.timestamp;
86
+ const jpeg = await encodeJpeg(wrapped.canvas, quality);
87
+ frames.push({
88
+ mimeType: 'image/jpeg',
89
+ width: wrapped.canvas.width,
90
+ height: wrapped.canvas.height,
91
+ dataBase64: await encodeBase64(jpeg),
92
+ timestampMs: Math.round(wrapped.timestamp * 1000),
93
+ });
94
+ }
95
+ return frames;
96
+ }
97
+ finally {
98
+ input.dispose();
99
+ }
100
+ };
101
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJhbWVzYW1wbGVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90c19zaGVsbC9zZXJ2aWNlcy9mcmFtZXNhbXBsZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFLQSxzQ0FBc0M7QUFDdEMsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUc7SUFDakMsWUFBWSxFQUFFLENBQUM7SUFDZixRQUFRLEVBQUUsRUFBRTtJQUNaLGVBQWUsRUFBRSxHQUFHO0lBQ3BCLFdBQVcsRUFBRSxFQUFFO0lBQ2YsV0FBVyxFQUFFLElBQUk7SUFDakIsY0FBYyxFQUFFLEdBQUc7Q0FDWCxDQUFDO0FBRVgsMERBQTBEO0FBQzFELE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxLQUFLO0lBQzNDLFlBQVksVUFBa0I7UUFDNUIsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2xCLElBQUksQ0FBQyxJQUFJLEdBQUcsb0JBQW9CLENBQUM7SUFDbkMsQ0FBQztDQUNGO0FBRUQsTUFBTSxZQUFZLEdBQUcsS0FBSyxFQUFFLE9BQWEsRUFBbUIsRUFBRTtJQUM1RCxNQUFNLEtBQUssR0FBRyxJQUFJLFVBQVUsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQzFELElBQUksTUFBTSxHQUFHLEVBQUUsQ0FBQztJQUNoQixxRUFBcUU7SUFDckUsS0FBSyxJQUFJLE1BQU0sR0FBRyxDQUFDLEVBQUUsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsTUFBTSxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzdELE1BQU0sSUFBSSxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3RCLENBQUMsQ0FBQztBQUVGLE1BQU0s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
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/wcctools',
6
- version: '6.1.0',
6
+ version: '7.0.0',
7
7
  description: 'A set of web component tools for creating element catalogues, enabling the structured development and documentation of custom elements and pages.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUseUJBQXlCO0lBQy9CLE9BQU8sRUFBRSxPQUFPO0lBQ2hCLFdBQVcsRUFBRSxtSkFBbUo7Q0FDakssQ0FBQSJ9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@design.estate/wcctools",
3
- "version": "6.1.0",
3
+ "version": "7.0.0",
4
4
  "private": false,
5
5
  "description": "A set of web component tools for creating element catalogues, enabling the structured development and documentation of custom elements and pages.",
6
6
  "bin": {
@@ -19,7 +19,8 @@
19
19
  "@api.global/typedserver": "^14.2.1",
20
20
  "@design.estate/dees-domtools": "^5.0.0",
21
21
  "@design.estate/dees-element": "^4.0.0",
22
- "@git.zone/tswatch": "^6.0.1",
22
+ "@git.zone/tswatch": "^7.0.0",
23
+ "@push.rocks/smartbrowser": "^5.1.0",
23
24
  "@push.rocks/smartconfig": "^6.3.0",
24
25
  "@push.rocks/smartconsole": "^2.1.0",
25
26
  "@push.rocks/smartexit": "^2.2.0",
@@ -38,6 +39,9 @@
38
39
  },
39
40
  "files": [
40
41
  "ts/**/*",
42
+ "ts_interfaces/**/*",
43
+ "ts_shared/**/*",
44
+ "ts_shell/**/*",
41
45
  "ts_web/**/*",
42
46
  "dist/**/*",
43
47
  "dist_*/**/*",
package/readme.md CHANGED
@@ -6,7 +6,8 @@
6
6
 
7
7
  `@design.estate/wcctools` provides a comprehensive development environment for web components, featuring:
8
8
 
9
- - 🖥️ **`wcctools dev`** — One command bundles your catalogue with live reload and serves it in the wcctools shell
9
+ - 🖥️ **`wcctools dev`** — One command bundles your catalogue with live reload and serves it in the wcctools shell, on this machine only unless you expose it
10
+ - 📸 **Headless Captures** — `wcctools screenshot` and the dev server's typed API screenshot any demo at any viewport and theme, and observe scripted interactions frame by frame
10
11
  - 🎨 **Interactive Component Catalogue** — Live preview with customizable sidebar sections
11
12
  - 🔧 **Real-time Property Editing** — Modify component props on the fly with auto-detected editors
12
13
  - 🌓 **Theme Switching** — Test light/dark modes instantly
@@ -30,6 +31,14 @@ pnpm add -D @design.estate/wcctools
30
31
  npm install @design.estate/wcctools --save-dev
31
32
  ```
32
33
 
34
+ Captures run in a headless Chrome or Chromium found on the `PATH` (`google-chrome`, `chromium` or `chromium-browser`), driven by Puppeteer. pnpm asks whether Puppeteer's install script may run; without it, Puppeteer downloads no browser of its own and the one on the `PATH` is used:
35
+
36
+ ```yaml
37
+ # pnpm-workspace.yaml
38
+ allowBuilds:
39
+ puppeteer: false
40
+ ```
41
+
33
42
  ### Migrating from `@design.estate/dees-wcctools`
34
43
 
35
44
  `@design.estate/dees-wcctools` is now published as `@design.estate/wcctools`. Versions continue from 5.0.0 and the API is the same: swap the dependency and the import specifier.
@@ -56,6 +65,17 @@ A catalogue still on a 4.x or older release also follows the 5.0.0 changes: [`se
56
65
 
57
66
  Opened outside `wcctools dev` (for example from plain `tswatch`), the catalogue bundle shows a notice that names the command instead of the catalogue UI. `RecorderService`, `WccRecordButton` and `WccRecordingPanel` are no longer exported: recording lives in the shell.
58
67
 
68
+ ### Migrating to 7.0.0
69
+
70
+ 7.0.0 locks the dev server down, because its typed API now drives a headless browser:
71
+
72
+ 1. `wcctools dev` listens on `127.0.0.1` only. To open the catalogue from another machine, start it with `--host 0.0.0.0` (every interface; the machine's own addresses are then allowed) or `--host <address>`, and allow every further name you browse it under with `--allowed-host <name>`. Exposed this way, every machine that can reach the port can use the shell and the capture API: the `Host` and `Origin` checks below keep web pages in your browser from using the server, they do not authenticate other machines.
73
+ 2. Requests for a `Host` the server does not serve are refused with `403` and a message naming the `--allowed-host` to add.
74
+ 3. Typed requests and other state-changing requests, and WebSocket connections, are admitted only from the server's own origin; a request without an `Origin` header only from this machine.
75
+ 4. The preview no longer sends CORS headers: other origins cannot read the catalogue bundle.
76
+
77
+ Nothing changes for a catalogue opened on `http://localhost:<port>/wcctools/`.
78
+
59
79
  ## Quick Start
60
80
 
61
81
  ### 1. Create Your Component
@@ -163,9 +183,10 @@ setupWccTools({
163
183
  ```bash
164
184
  pnpm exec wcctools dev # port from the tswatch configuration, else 3002
165
185
  pnpm exec wcctools dev --port 0 # any free port
186
+ pnpm exec wcctools dev --host 0.0.0.0 --allowed-host devbox.lan # reachable from the network as devbox.lan
166
187
  ```
167
188
 
168
- It prints the shell's address, for example `wcctools dev: http://localhost:3002/wcctools/`. Saving a source file rebuilds the bundle and reloads only the preview frame; the shell keeps its state. `Ctrl+C` stops the server and the watchers.
189
+ It prints the shell's address, for example `wcctools dev: http://localhost:3002/wcctools/`. Saving a source file rebuilds the bundle and reloads only the preview frame; the shell keeps its state. When a bundle fails, the shell shows `bundle failed` with the bundler's message over the preview until the next run of that bundle finishes. `Ctrl+C` (or `SIGTERM`) stops the server and the watchers.
169
190
 
170
191
  ## 📂 Sections Configuration
171
192
 
@@ -490,7 +511,7 @@ The preview document alone renders one demo from its own route, for tools that c
490
511
 
491
512
  ## API Reference
492
513
 
493
- ### `wcctools dev [--port <port>]`
514
+ ### `wcctools dev [--port <port>] [--host <address>] [--allowed-host <name>…]`
494
515
 
495
516
  Bundles and watches the catalogue as the project's `@git.zone/tswatch` configuration describes (or tswatch's `element` preset) and serves on one port:
496
517
 
@@ -498,10 +519,82 @@ Bundles and watches the catalogue as the project's `@git.zone/tswatch` configura
498
519
  |------|--------|
499
520
  | `/` | Redirects to `/wcctools/` |
500
521
  | `/wcctools/`, `/wcctools-route/...` | The shell |
501
- | `/wcctools/typedrequest` | The shell's typed API |
522
+ | `/wcctools/typedrequest` | The typed API: the server info (`getDevServerInfo`), the bundle status (`getBundleStatus`) and [captures](#captures-on-the-typed-api) (`captureScreenshot`, `captureInteraction`) |
502
523
  | every other path | The catalogue's serve directory (default `dist_watch/`), with live reload for the preview document |
503
524
 
504
- `--port` overrides the configured port; `0` picks a free port.
525
+ `--port` overrides the configured port; `0` picks a free port. `--host` sets the interface address to listen on (default `127.0.0.1`); `--allowed-host` (repeatable) adds a hostname or address the server answers.
526
+
527
+ The shell follows the bundle status: per bundle the state of its latest run (`started`, `finished` or `failed`), the duration of the latest completed run and, while its latest completed run failed, the bundler's error message. A failed bundle is shown over the preview until a run of it finishes, which also reloads the preview.
528
+
529
+ #### Security model
530
+
531
+ The dev server serves your source and drives a headless browser, so by default it answers only this machine (with `--host`, every machine that can reach the port; the checks below guard against web pages, not against other machines):
532
+
533
+ - It listens on `127.0.0.1` unless `--host` says otherwise.
534
+ - It answers only the hosts it serves: `localhost`, `127.0.0.1`, `::1`, the `--host` address (with `--host 0.0.0.0` or `::`, every address of the machine's interfaces) and each `--allowed-host`. Any other `Host` is refused with `403`, which defeats DNS rebinding.
535
+ - Typed requests and every other request but `GET`, `HEAD` and `OPTIONS`, and WebSocket connections, must come from the server's own origin (`http://<allowed host>:<port>`). A request without an `Origin` header is admitted only from a loopback connection, as local tools send it. So other web pages you visit cannot drive the typed API, and since neither the shell nor the preview sends CORS headers, they cannot read the catalogue either. The same rule refuses the shell behind a TLS-terminating reverse proxy (see [Known Limitations](#known-limitations)).
536
+
537
+ `wcctools dev` owns the process signals: on `SIGINT` or `SIGTERM` it stops the server and tswatch's bundling and watching once, within tswatch's shutdown deadline (the longest `stopGracePeriod` of the configured watcher commands plus a margin), and exits.
538
+
539
+ ### `wcctools screenshot <item | section/item> --out <file>`
540
+
541
+ Bundles the catalogue of the working directory, serves it on a free loopback port, screenshots one demo in a headless browser, writes the image and stops.
542
+
543
+ ```bash
544
+ wcctools screenshot my-button --out button.png # desktop width, dark theme
545
+ wcctools screenshot Elements/MyButton --demo 1 --viewport phone --theme bright --out button-phone.png
546
+ wcctools screenshot Pages/Home --viewport tablet --out home.jpg # a page, in full
547
+ wcctools screenshot my-card --viewport 720 --framing viewport --height 600 --scale 2 --out card@2x.png
548
+ ```
549
+
550
+ | Option | Meaning |
551
+ |--------|---------|
552
+ | `<item>` | An entry's name or its element's tag; `section/item` when the name is in more than one section |
553
+ | `--out` | The file to write; `.png`, `.jpg` or `.jpeg` sets the format |
554
+ | `--demo` | The demo, counted from 0 as in the shell URL (default 0) |
555
+ | `--viewport` | `phone` (400), `phablet` (600), `tablet` (1024), `desktop` (1600, the default) or a width from 200 to 3840 pixels; the widths are the dees-domtools breakpoints |
556
+ | `--height` | Height of the preview window, which also sizes `100vh` (default 800) |
557
+ | `--theme` | `dark` (default) or `bright` |
558
+ | `--framing` | `element`: the rendered element, the default for element demos; `viewport`: the visible window; `fullpage`: the whole document, the default for pages (cut at 10000 pixels) |
559
+ | `--scale` | Device pixel ratio, 1 (default) or 2 |
560
+ | `--quality` | JPEG quality from 1 to 100 (default 80) |
561
+
562
+ The capture waits for the preview's own signals, never for a fixed time: the preview bridge, the render's completed element updates and the document's fonts. It fails (exit code 1) when the bundle failed or the demo renders nothing; an entry that does not exist, or invalid options, exit with 2 and list what exists.
563
+
564
+ ### Captures on the typed API
565
+
566
+ While `wcctools dev` runs, its typed API takes the same captures, in one shared headless browser that starts with the first capture, closes after a minute without one and always closes with the server. Two captures run at once and eight wait; more are refused as busy. Captures wait while a bundle builds and are refused while one failed. Every capture ends when its client goes away, and at its deadline, which counts from its request and includes waiting for a slot or a bundle: 30 seconds for a screenshot, 135 seconds for an interaction (20 steps of 5 seconds, 5 seconds of observation and 30 seconds of set-up). `TypedRequest.fire()` gives up after 60 seconds unless given a `timeoutMs`, so fire interactions with a `timeoutMs` above their deadline, as below.
567
+
568
+ ```typescript
569
+ import { TypedRequest } from '@api.global/typedrequest';
570
+ import type { IReq_CaptureScreenshot, IReq_CaptureInteraction } from '@design.estate/wcctools/interfaces';
571
+
572
+ const endpoint = 'http://localhost:3002/wcctools/typedrequest';
573
+
574
+ const shot = await new TypedRequest<IReq_CaptureScreenshot>(endpoint, 'captureScreenshot').fire({
575
+ subject: { itemName: 'my-button' },
576
+ viewport: 'phone',
577
+ theme: 'dark',
578
+ });
579
+ // shot.image: { mimeType: 'image/png', width, height, dataBase64 }
580
+
581
+ const observed = await new TypedRequest<IReq_CaptureInteraction>(endpoint, 'captureInteraction').fire({
582
+ subject: { sectionName: 'Elements', itemName: 'MyInput' },
583
+ viewport: 'phone',
584
+ steps: [
585
+ { action: 'click', selector: 'input' },
586
+ { action: 'fill', selector: 'input', text: 'hello' },
587
+ { action: 'press', key: 'Enter' },
588
+ { action: 'waitFor', selector: '.error-message', state: 'hidden' },
589
+ ],
590
+ observeMs: 500,
591
+ maxFrames: 12,
592
+ finalScreenshot: { framing: 'element' },
593
+ }, { timeoutMs: 140_000 }); // the interaction deadline is 135 s; fire() alone gives up after 60 s
594
+ // observed.frames: viewport JPEGs with timestampMs; observed.steps: per step ok/error and its time
595
+ ```
596
+
597
+ An interaction renders the demo, records the page's screencast while it runs the steps, keeps watching for `observeMs` after the last one (at most 5000) and returns at most `maxFrames` frames (at most 40) spread evenly over that time, the first and the last always among them. Steps are `click`, `hover`, `fill`, `press` (a key such as `Enter` or `Tab`, on a selector or the focused element), `waitFor` (`visible` or `hidden`) and `wait` (at most 3000 ms); there are at most 20. A selector is a CSS selector matched in the preview document and in every open shadow root below it, so `input` finds the input inside a component; the first match in document order is used once it is visible and enabled. Each step may take 5 seconds; a failing step ends the script and is reported with its error (`completed: false`), the frames up to then included. A capture stays on the preview route: a navigation that would replace the preview document (a link, a form submission, a script assigning `location`, a reload, also to the same URL, to `about:blank` or to a `blob:` URL) is cancelled as it starts, and the step that started it fails with `navigation to <url> blocked` and ends the script, so the final screenshot still shows the preview. A navigation started after the last step fails that step. The preview's history begins with the preview, so going back leaves nothing. A screenshot, or an interaction without steps, fails when its demo navigates away. Same-document navigations, such as fragment links and `history.pushState`, pass.
505
598
 
506
599
  Every `wcctools` command exits with code 2 on a usage error (an unknown command or option, a missing or invalid option value) and with 1 on any other failure.
507
600
 
@@ -573,7 +666,7 @@ The wrapper provides full DOM API access:
573
666
 
574
667
  ### `@design.estate/wcctools/interfaces`
575
668
 
576
- The contracts between the shell, the preview document and the dev server, for tools that drive a preview: the catalogue manifest (`IWccCatalogManifest`), the preview bridge the preview document installs as `window.wccPreview` (`IWccPreviewBridge`: render a demo, switch the theme, read and edit the rendered element's properties) and the dev server's typed requests, and the component standard's configuration and reports (`IStandardConfig`, `IStandardReport`, `IStandardFixResult`).
669
+ The contracts between the shell, the preview document and the dev server, for tools that drive a preview: the catalogue manifest (`IWccCatalogManifest`), the preview bridge the preview document installs as `window.wccPreview` (`IWccPreviewBridge`: render a demo, switch the theme, read and edit the rendered element's properties) and the dev server's typed requests including the capture requests and their results (`IReq_CaptureScreenshot`, `IReq_CaptureInteraction`, `IWccImage`, `TWccInteractionStep`, …), and the component standard's configuration and reports (`IStandardConfig`, `IStandardReport`, `IStandardFixResult`).
577
670
 
578
671
  ```typescript
579
672
  import type { IWccPreviewBridge } from '@design.estate/wcctools/interfaces';
@@ -583,6 +676,15 @@ await bridge.render({ sectionName: 'Elements', itemName: 'MyButton', demoIndex:
583
676
  const properties = await bridge.getProperties();
584
677
  ```
585
678
 
679
+ ## Known Limitations
680
+
681
+ - Captures need Chrome or Chromium on the `PATH`. In CI (`CI` set) or as root, the browser starts without its sandbox and prints a warning banner saying so.
682
+ - Each start of the capture browser prints its launch arguments and executable on standard output (from `@push.rocks/smartbrowser`, which has no quiet option yet). The lines appear in the `wcctools dev` log on the first capture and in the output of `wcctools screenshot`, which therefore has no machine-readable output mode and writes images only to files.
683
+ - A selector is matched within each document or shadow root on its own: `my-input input` does not reach into `my-input`'s shadow root, `input` does.
684
+ - Captures wait for element updates and fonts, not for images or other resources a demo loads.
685
+ - Captures cancel navigations through the Navigation API's `navigate` event before the demo's own listeners see it, so a demo that routes by calling `intercept()` on cross-document navigations does not route in a capture (its `intercept()` call throws). A `javascript:` URL navigates without that event; one that evaluates to a string replaces the preview document. A navigation Chrome does not let the page cancel (some history traversals; the preview's history holds only the preview, so there is none to traverse) is aborted at the network instead, may be reported on the step after the one that started it, and is not stopped when it loads nothing from the network.
686
+ - The shell does not work through a TLS-terminating reverse proxy, even for a name given with `--allowed-host`: its typed requests and WebSocket connections then carry an `https:` origin (or the proxy's port), and the dev server admits only `http://<allowed host>:<port>` with its own port, so it refuses them; plain page loads still pass. Reach the dev server over plain HTTP on its own port, for example through an SSH tunnel.
687
+
586
688
  ## Project Structure
587
689
 
588
690
  ```
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/wcctools',
6
- version: '6.1.0',
6
+ version: '7.0.0',
7
7
  description: 'A set of web component tools for creating element catalogues, enabling the structured development and documentation of custom elements and pages.'
8
8
  }