Every event, as it happens.
A live, public view of the atproto network—with replay from the archive.
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 systemPublic surfaces
- \\