diff --git a/docs/product-copy-context.md b/docs/product-copy-context.md index 911e625..dbebe86 100644 --- a/docs/product-copy-context.md +++ b/docs/product-copy-context.md @@ -40,6 +40,10 @@ make ephemeral consumers cheap without making the network absorb the rebuild. - The moving waves are ambient animation, not evidence that the document refreshes itself. Do not tell readers to refresh unless the page actually auto-refreshes or offers a meaningful refresh action. +- If the browser page labels a value as live, that value must update in place. + Sequence, event count, uptime, listener count, and the sequence-derived river + should advance from one shared metrics sample so they cannot contradict one + another. - Dated compatibility and load-test results are audit receipts, not timeless statements about the currently running build. - Runtime facts belong on /status; the / page should remain legible, welcoming, @@ -56,4 +60,6 @@ make ephemeral consumers cheap without making the network absorb the rebuild. screens rather than centering an overflowing block off-screen. - Prefer ordinary language over implementation jokes. A clever detail earns its place only when a visitor can understand it without knowing Stream internals. - +- Do not promote the implementation language in the homepage footer. The build + identifier and source link are useful provenance; “written in Zig” is not a + visitor-facing capability. diff --git a/src/internal/homepage.zig b/src/internal/homepage.zig index 685a718..3855723 100644 --- a/src/internal/homepage.zig +++ b/src/internal/homepage.zig @@ -134,62 +134,73 @@ pub fn render(buf: []u8, args: Args) []const u8 { w.print(" \u{00b7} ", .{}) catch {}; writeCommas(&w, args.events_total); w.print(" live events this run \u{00b7} {d} listening\n", .{args.subscribers}) catch {}; - w.print(" {s} \u{00b7} zig \u{00b7} source: tangled.org/zat.dev/stream\n\n", .{build_options.git_sha}) catch {}; + w.print(" build {s} \u{00b7} source: tangled.org/zat.dev/stream\n\n", .{build_options.git_sha}) catch {}; return w.buffered(); } -/// html wrapper: same art in a dark
, waves drift on their own
+// Browser rendering lives below as a structured live instrument. The text
+// representation above remains intentionally useful to curl and terminals.
+
+/// The river is a live instrument: every displayed runtime value and the wave
+/// pattern refresh from /metrics without a page reload.
 pub fn renderHtml(buf: []u8, args: Args) []const u8 {
     var w: std.Io.Writer = .fixed(buf);
-    w.print(
-        \\
-        \\
-        \\
-        \\stream
-        \\
-    , .{}) catch {};
-
-    // re-render the text page, wrapping wave rows in drifting spans
-    var text_buf: [8192]u8 = undefined;
-    const text = render(&text_buf, args);
-    var lines = std.mem.splitScalar(u8, text, '\n');
-    var i: usize = 0;
-    while (lines.next()) |line| : (i += 1) {
-        const is_wave = std.mem.indexOfScalar(u8, line, '~') != null and i < 12 and i > 4;
-        if (is_wave) {
-            const cls: []const u8 = switch (i % 3) {
-                0 => "w",
-                1 => "w w2",
-                else => "w w3",
-            };
-            w.print("{s}\n", .{ cls, line }) catch {};
-        } else if (std.mem.indexOf(u8, line, "Heraclitus") != null or std.mem.indexOf(u8, line, "same river") != null or std.mem.indexOf(u8, line, "Following the network") != null) {
-            w.print("{s}\n", .{line}) catch {};
-        } else if (std.mem.indexOf(u8, line, "tangled.org") != null) {
-            w.print("  {s} \u{00b7} zig \u{00b7} source: tangled.org/zat.dev/stream\n", .{build_options.git_sha}) catch {};
-        } else {
-            w.print("{s}\n", .{line}) catch {};
-        }
+    w.writeAll(
+        \\
+        \\
+        \\stream · the atproto river
stream
+ ) catch {}; + w.writeAll(if (args.serving) "live" else "filling") catch {}; + w.writeAll( + \\

Every event, as it happens.

A live, public view of the atproto network—with replay from the archive.

+ \\
ϟ ° · ˚ · ϟ ° · ˚
\n", .{}) catch {}; + w.writeAll( + \\
Following the networklive reading
+ ) catch {}; + writeCommas(&w, if (args.seq > 0) @intCast(args.seq) else 0); + w.writeAll( + \\

“No one ever steps in the same river twice.”

— Heraclitus
+ \\

Open the stream

+ \\
GET/subscribeJetstream-compatible JSON firehose
+ \\
GET/subscribe-v2Sequence cursors, record CBOR, and sync events
+ \\
GET/xrpc/network.bsky.jetstream.listSegmentsBrowse sealed archive segments
+ \\
GET/xrpc/network.bsky.jetstream.getSegmentDownload a sealed segment
+ \\
GET/xrpc/network.bsky.jetstream.getBlockRead one compressed block
+ \\
POST/xrpc/network.bsky.jetstream.planBackfillPlan an archive range download
+ \\
up + ) catch {}; + writeUptime(&w, args.uptime_s); + w.writeAll("") catch {}; + writeCommas(&w, args.events_total); + w.print(" events this run{d} listening
", .{args.subscribers}) catch {}; + w.print("", .{build_options.git_sha}) catch {}; + w.writeAll( + \\ + ) catch {}; return w.buffered(); } @@ -334,7 +345,7 @@ pub fn renderStatusHtml(buf: []u8, args: StatusArgs) []const u8 { \\
touch the system

Public surfaces

- \\