@reporters/web 1.1.0 → 1.3.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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,55 @@
1
+ # Changelog
2
+
3
+ ## [1.3.0](https://github.com/MoLow/reporters/compare/web-v1.2.0...web-v1.3.0) (2026-07-02)
4
+
5
+
6
+ ### Features
7
+
8
+ * pluggable viewer report sources and custom s3 viewer links ([#222](https://github.com/MoLow/reporters/issues/222)) ([e553e89](https://github.com/MoLow/reporters/commit/e553e89a6e0c9ba9323483ca52a3142c8e70f8ce))
9
+
10
+ ## [1.2.0](https://github.com/MoLow/reporters/compare/web-v1.1.0...web-v1.2.0) (2026-07-02)
11
+
12
+
13
+ ### Features
14
+
15
+ * **web:** let sinks set the viewer poll cadence via a poll query param ([#219](https://github.com/MoLow/reporters/issues/219)) ([a78404d](https://github.com/MoLow/reporters/commit/a78404d61cf924d0c8e221ee41b8b0337f3d1023))
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **web:** stay a pure emitter under mux via symbol-declared default options ([#217](https://github.com/MoLow/reporters/issues/217)) ([96a7d14](https://github.com/MoLow/reporters/commit/96a7d14e82f69c6dc6d8d363645f94c09733fbda))
21
+
22
+ ## [1.1.0](https://github.com/MoLow/reporters/compare/web-v1.0.0...web-v1.1.0) (2026-07-02)
23
+
24
+
25
+ ### Features
26
+
27
+ * @reporters/mux environment-aware reporter routing + web NDJSON redesign ([#203](https://github.com/MoLow/reporters/issues/203)) ([82d1e20](https://github.com/MoLow/reporters/commit/82d1e205949e6daa90b13aec5838ddb0c7e931a5))
28
+ * live and web tree reporters ([#193](https://github.com/MoLow/reporters/issues/193)) ([0fae33e](https://github.com/MoLow/reporters/commit/0fae33e3c87f3a28d68b783a457ef9638cec2f17))
29
+ * **web:** implement the Panel design for the web report & live viewer ([#195](https://github.com/MoLow/reporters/issues/195)) ([f93b76b](https://github.com/MoLow/reporters/commit/f93b76bb8536adda53d57b7691b8912c86208cee))
30
+ * **web:** read destination from execArgv; auto-open the report locally ([#197](https://github.com/MoLow/reporters/issues/197)) ([d8eb056](https://github.com/MoLow/reporters/commit/d8eb056c117b1a35120dc9e898b600ff853d43bb))
31
+ * **web:** render ANSI colors in the report (fancy-ansi) ([#206](https://github.com/MoLow/reporters/issues/206)) ([a2c938e](https://github.com/MoLow/reporters/commit/a2c938e2d2ada1ecd0f2aea636c253e619dd084a))
32
+ * **web:** replace density toggle with a dark/light mode toggle ([#202](https://github.com/MoLow/reporters/issues/202)) ([47fbf7c](https://github.com/MoLow/reporters/commit/47fbf7c180dd7383d31eda75061631b41fc5c060))
33
+ * **web:** viewer design round 2 + live-viewer transition choreography ([#205](https://github.com/MoLow/reporters/issues/205)) ([b99d9c6](https://github.com/MoLow/reporters/commit/b99d9c62b4729a530922e18a2b4566ed219bd9a5))
34
+
35
+
36
+ ### Bug Fixes
37
+
38
+ * **tree-core:** group top-level stdout/stderr with their file's tests ([#200](https://github.com/MoLow/reporters/issues/200)) ([27a510d](https://github.com/MoLow/reporters/commit/27a510deb42a85de9a82782e85e84b68477599ea))
39
+ * **web:** auto-refresh the embedded report while streaming ([#196](https://github.com/MoLow/reporters/issues/196)) ([68090dc](https://github.com/MoLow/reporters/commit/68090dc3fbade1b2f01bba150310b9263aa0336c))
40
+ * **web:** honor REPORTERS_OPEN instead of REPORTERS_WEB_OPEN ([#208](https://github.com/MoLow/reporters/issues/208)) ([fe3716d](https://github.com/MoLow/reporters/commit/fe3716d499cf8ab592c66d7519fce8c9c50ae060))
41
+ * **web:** open the standalone live view even without a file destination ([#204](https://github.com/MoLow/reporters/issues/204)) ([cf6d465](https://github.com/MoLow/reporters/commit/cf6d4657efee5fdb6a5daa63e2be475be27bcab2))
42
+ * **web:** use the live viewer URL in the load-error hint ([#201](https://github.com/MoLow/reporters/issues/201)) ([acf6dec](https://github.com/MoLow/reporters/commit/acf6dec6701c8b42d98ab703fdd74965c7d94aff))
43
+
44
+
45
+ ### Documentation
46
+
47
+ * flag-order fixes and the gh collapsible actions log ([#216](https://github.com/MoLow/reporters/issues/216)) ([131f410](https://github.com/MoLow/reporters/commit/131f4107712d6d0b899d3b8ca7a39496b6e05276))
48
+ * rewrite package READMEs with demos and clearer positioning ([#209](https://github.com/MoLow/reporters/issues/209)) ([e1265e5](https://github.com/MoLow/reporters/commit/e1265e5f6b8a0f34b80ef7ee725cede4ed16b6da))
49
+
50
+
51
+ ### Miscellaneous Chores
52
+
53
+ * address review feedback on the tree reporters ([#194](https://github.com/MoLow/reporters/issues/194)) ([fada74a](https://github.com/MoLow/reporters/commit/fada74aa9be27f1a0a2f217de0115c5ae8de4851))
54
+ * route this repo's tests through @reporters/mux ([#207](https://github.com/MoLow/reporters/issues/207)) ([85a5973](https://github.com/MoLow/reporters/commit/85a59737bc3d631b0293edf343b77fd82e0c459d))
55
+ * use the gh reporter for tree-core/live/web tests ([#198](https://github.com/MoLow/reporters/issues/198)) ([cc1fefa](https://github.com/MoLow/reporters/commit/cc1fefa5e4f9d04eda6067c4134a83b4cf46aa4f))
package/README.md CHANGED
@@ -41,7 +41,7 @@ The NDJSON is rendered by the tree viewer, reached three ways:
41
41
  // mux.config.js
42
42
  import { httpServer } from '@reporters/web/sink';
43
43
  export default {
44
- // pass `options: { open: false }` on the route if it shouldn't open a browser
44
+ // pass `open: false` on the route if it shouldn't open a browser
45
45
  local: [{ reporter: '@reporters/web', sink: httpServer() }],
46
46
  };
47
47
  ```
@@ -60,3 +60,29 @@ The NDJSON is rendered by the tree viewer, reached three ways:
60
60
  Built on the shared [`@reporters/tree-core`](https://github.com/MoLow/reporters/tree/main/packages/tree-core)
61
61
  model (also used by [`@reporters/live`](https://github.com/MoLow/reporters/tree/main/packages/live)) —
62
62
  the same run state, rendered in the browser instead of the terminal.
63
+
64
+ ## Custom report sources (`@reporters/web/viewer`)
65
+
66
+ The hosted viewer reads `?src=<url>` with plain `fetch`. To serve reports that
67
+ need authentication (private buckets, SSO), build your own viewer page on the
68
+ same UI with a custom source resolver:
69
+
70
+ ```ts
71
+ import { startViewer } from '@reporters/web/viewer';
72
+
73
+ startViewer({
74
+ resolveSource: async (params) => {
75
+ if (params.get('src') || !params.get('key')) return null; // default handling
76
+ const credentials = await acquireCredentialsSomehow();
77
+ return { url: params.get('key')!, fetch: authenticatedFetch(credentials) };
78
+ },
79
+ });
80
+ ```
81
+
82
+ `resolveSource` runs before anything renders. Return `null`/`undefined` to fall
83
+ through to the default `?src=` handling; return `{ url, fetch?, pollMs? }` to
84
+ take over. The custom `fetch` receives the reader's `Range` header and must
85
+ return a standard `Response`; a thrown error shows the viewer's load-error
86
+ screen, and a promise that never resolves is fine while an auth redirect is in
87
+ flight. The export is a self-contained browser ESM module (React inlined) —
88
+ bundle it with your resolver into a static HTML page.
@@ -9,7 +9,7 @@ function viewerPage() {
9
9
  return '<!doctype html><meta charset="utf-8"><p>viewer bundle missing \u2014 run the package build</p>';
10
10
  }
11
11
  }
12
- function startViewerServer(host = "127.0.0.1") {
12
+ function startViewerServer(host = "127.0.0.1", pollMs = 250) {
13
13
  const page = viewerPage();
14
14
  let buffer = Buffer.alloc(0);
15
15
  return new Promise((resolve) => {
@@ -41,7 +41,9 @@ function startViewerServer(host = "127.0.0.1") {
41
41
  server.listen(0, host, () => {
42
42
  const { port } = server.address();
43
43
  resolve({
44
- url: `http://${host}:${port}/?src=/run.ndjson`,
44
+ // Serving from memory on localhost is cheap, so ask the viewer to poll
45
+ // fast; remote sinks (S3/gist) omit `poll` and get the slower default.
46
+ url: `http://${host}:${port}/?src=/run.ndjson&poll=${pollMs}`,
45
47
  push(chunk) {
46
48
  buffer = Buffer.concat([buffer, Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)]);
47
49
  },
package/dist/index.d.ts CHANGED
@@ -43,8 +43,8 @@ interface WebOptions {
43
43
  * Run standalone on a dev machine it also serves a live browser view and opens
44
44
  * it, the same way it behaves through `@reporters/mux`'s `httpServer()` sink.
45
45
  * Control this with the `open` option or `REPORTERS_OPEN=1|0`; it never opens
46
- * in CI by default. Through mux the reporter is a pure emitter and the sink owns
47
- * viewing.
46
+ * in CI by default. Through mux the reporter is a pure emitter and the sink
47
+ * owns viewing — it declares `{ open: false }` as its under-mux default options.
48
48
  */
49
49
  declare function web(source: AsyncIterable<TestEvent>, options?: WebOptions): AsyncGenerator<string>;
50
50
 
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  startViewerServer
3
- } from "./chunk-MZ7XNO2N.js";
3
+ } from "./chunk-X6OHEYIN.js";
4
4
 
5
5
  // ../tree-core/src/wire.ts
6
6
  function flattenError(raw) {
@@ -116,6 +116,7 @@ async function* web(source, options = {}) {
116
116
  if (process.stdin.isTTY) return;
117
117
  await server.close();
118
118
  }
119
+ Object.assign(web, { [/* @__PURE__ */ Symbol.for("reporters.mux.defaultOptions")]: { open: false } });
119
120
  export {
120
121
  web as default
121
122
  };
package/dist/sink.d.ts CHANGED
@@ -6,12 +6,19 @@ interface Sink {
6
6
  flush?(): Promise<void>;
7
7
  /** The run ended; release resources. */
8
8
  close(): Promise<void>;
9
- /** How a human views what was written, if anything. */
9
+ /**
10
+ * How a human views what was written, if anything. Valid once `start()` has
11
+ * resolved; under mux, every sink in the profile has started before any
12
+ * reporter receives events, so a getter wired into another route's
13
+ * `options` is live from the first event.
14
+ */
10
15
  viewerUrl?(): string | undefined;
11
16
  }
12
17
 
13
18
  interface HttpServerOptions {
14
19
  host?: string;
20
+ /** Viewer polling cadence in ms (default 250; the viewer clamps to 100–10000). */
21
+ pollMs?: number;
15
22
  }
16
23
  /**
17
24
  * A sink that serves the run locally: the viewer page at `/` and the growing
package/dist/sink.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  startViewerServer
3
- } from "./chunk-MZ7XNO2N.js";
3
+ } from "./chunk-X6OHEYIN.js";
4
4
 
5
5
  // src/sink.ts
6
6
  function httpServer(opts = {}) {
7
7
  let server;
8
8
  return {
9
9
  async start() {
10
- server = await startViewerServer(opts.host);
10
+ server = await startViewerServer(opts.host, opts.pollMs);
11
11
  },
12
12
  write(chunk) {
13
13
  server?.push(chunk);
@@ -0,0 +1,24 @@
1
+ type FetchLike = (url: string, init?: {
2
+ headers?: Record<string, string>;
3
+ }) => Promise<Response>;
4
+
5
+ interface ReportSource {
6
+ /** Passed to the NDJSON reader as the URL/identifier. */
7
+ url: string;
8
+ /** Transport for reads; defaults to the global fetch. Receives the reader's
9
+ * Range header and must return a standard Response. */
10
+ fetch?: FetchLike;
11
+ /** Poll cadence override; else resolved from ?poll= as today. */
12
+ pollMs?: number;
13
+ }
14
+ interface ViewerOptions {
15
+ /** Called first with the page's query params. Return a source to use it;
16
+ * return null/undefined to fall through to the default ?src= handling.
17
+ * A never-resolving promise is legitimate (e.g. an auth redirect is in
18
+ * flight). A thrown error shows the viewer's load-error screen. */
19
+ resolveSource?: (params: URLSearchParams) => Promise<ReportSource | null | undefined>;
20
+ }
21
+
22
+ declare function startViewer(options?: ViewerOptions): Promise<void>;
23
+
24
+ export { type FetchLike, type ReportSource, type ViewerOptions, startViewer };