@getcirrus/pds 0.10.5 → 0.11.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/dist/index.d.ts CHANGED
@@ -30,14 +30,6 @@ declare class SqliteRepoStorage extends ReadableBlockstore implements RepoStorag
30
30
  * Get the current revision string.
31
31
  */
32
32
  getRev(): Promise<string | null>;
33
- /**
34
- * Get the current sequence number for firehose events.
35
- */
36
- getSeq(): Promise<number>;
37
- /**
38
- * Increment and return the next sequence number.
39
- */
40
- nextSeq(): Promise<number>;
41
33
  /**
42
34
  * Get the raw bytes for a block by CID.
43
35
  */
@@ -226,6 +218,7 @@ declare class SqliteOAuthStorage implements OAuthStorage {
226
218
  * Initialize the OAuth database schema. Should be called once on DO startup.
227
219
  */
228
220
  initSchema(): void;
221
+ private migrateClientTable;
229
222
  /**
230
223
  * Clean up expired entries. Should be called periodically.
231
224
  */
@@ -648,7 +641,11 @@ declare class AccountDurableObject extends DurableObject<PDSEnv> {
648
641
  * RPC method: Firehose status - returns subscriber count and latest sequence
649
642
  */
650
643
  rpcGetFirehoseStatus(): Promise<{
651
- subscribers: number;
644
+ subscribers: Array<{
645
+ connectedAt: number;
646
+ cursor: number;
647
+ ip: string | null;
648
+ }>;
652
649
  latestSeq: number | null;
653
650
  }>;
654
651
  /** Save an authorization code */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/storage.ts","../src/oauth-storage.ts","../src/blobs.ts","../src/types.ts","../src/account-do.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/storage.ts","../src/oauth-storage.ts","../src/blobs.ts","../src/types.ts","../src/account-do.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -215,20 +215,6 @@ var SqliteRepoStorage = class extends ReadableBlockstore {
215
215
  return rows.length > 0 ? rows[0].rev ?? null : null;
216
216
  }
217
217
  /**
218
- * Get the current sequence number for firehose events.
219
- */
220
- async getSeq() {
221
- const rows = this.sql.exec("SELECT seq FROM repo_state WHERE id = 1").toArray();
222
- return rows.length > 0 ? rows[0].seq ?? 0 : 0;
223
- }
224
- /**
225
- * Increment and return the next sequence number.
226
- */
227
- async nextSeq() {
228
- this.sql.exec("UPDATE repo_state SET seq = seq + 1 WHERE id = 1");
229
- return this.getSeq();
230
- }
231
- /**
232
218
  * Get the raw bytes for a block by CID.
233
219
  */
234
220
  async getBytes(cid) {
@@ -551,7 +537,6 @@ var SqliteOAuthStorage = class {
551
537
  */
552
538
  initSchema() {
553
539
  this.sql.exec(`
554
- -- Authorization codes (5 min TTL)
555
540
  CREATE TABLE IF NOT EXISTS oauth_auth_codes (
556
541
  code TEXT PRIMARY KEY,
557
542
  client_id TEXT NOT NULL,
@@ -565,7 +550,6 @@ var SqliteOAuthStorage = class {
565
550
 
566
551
  CREATE INDEX IF NOT EXISTS idx_auth_codes_expires ON oauth_auth_codes(expires_at);
567
552
 
568
- -- OAuth tokens
569
553
  CREATE TABLE IF NOT EXISTS oauth_tokens (
570
554
  access_token TEXT PRIMARY KEY,
571
555
  refresh_token TEXT NOT NULL UNIQUE,
@@ -589,10 +573,12 @@ var SqliteOAuthStorage = class {
589
573
  redirect_uris TEXT NOT NULL,
590
574
  logo_uri TEXT,
591
575
  client_uri TEXT,
576
+ token_endpoint_auth_method TEXT NOT NULL DEFAULT 'none',
577
+ jwks TEXT,
578
+ jwks_uri TEXT,
592
579
  cached_at INTEGER NOT NULL
593
580
  );
594
581
 
595
- -- PAR requests (90 sec TTL)
596
582
  CREATE TABLE IF NOT EXISTS oauth_par_requests (
597
583
  request_uri TEXT PRIMARY KEY,
598
584
  client_id TEXT NOT NULL,
@@ -602,7 +588,6 @@ var SqliteOAuthStorage = class {
602
588
 
603
589
  CREATE INDEX IF NOT EXISTS idx_par_expires ON oauth_par_requests(expires_at);
604
590
 
605
- -- DPoP nonces for replay prevention (5 min TTL)
606
591
  CREATE TABLE IF NOT EXISTS oauth_nonces (
607
592
  nonce TEXT PRIMARY KEY,
608
593
  created_at INTEGER NOT NULL
@@ -610,7 +595,6 @@ var SqliteOAuthStorage = class {
610
595
 
611
596
  CREATE INDEX IF NOT EXISTS idx_nonces_created ON oauth_nonces(created_at);
612
597
 
613
- -- WebAuthn challenges for passkey authentication (2 min TTL)
614
598
  CREATE TABLE IF NOT EXISTS oauth_webauthn_challenges (
615
599
  challenge TEXT PRIMARY KEY,
616
600
  created_at INTEGER NOT NULL
@@ -618,6 +602,15 @@ var SqliteOAuthStorage = class {
618
602
 
619
603
  CREATE INDEX IF NOT EXISTS idx_challenges_created ON oauth_webauthn_challenges(created_at);
620
604
  `);
605
+ this.migrateClientTable();
606
+ }
607
+ migrateClientTable() {
608
+ if (!this.sql.exec("PRAGMA table_info(oauth_clients)").toArray().map((r) => r.name).includes("token_endpoint_auth_method")) {
609
+ this.sql.exec("ALTER TABLE oauth_clients ADD COLUMN token_endpoint_auth_method TEXT NOT NULL DEFAULT 'none'");
610
+ this.sql.exec("ALTER TABLE oauth_clients ADD COLUMN jwks TEXT");
611
+ this.sql.exec("ALTER TABLE oauth_clients ADD COLUMN jwks_uri TEXT");
612
+ this.sql.exec("DELETE FROM oauth_clients");
613
+ }
621
614
  }
622
615
  /**
623
616
  * Clean up expired entries. Should be called periodically.
@@ -712,11 +705,11 @@ var SqliteOAuthStorage = class {
712
705
  }
713
706
  async saveClient(clientId, metadata) {
714
707
  this.sql.exec(`INSERT OR REPLACE INTO oauth_clients
715
- (client_id, client_name, redirect_uris, logo_uri, client_uri, cached_at)
716
- VALUES (?, ?, ?, ?, ?, ?)`, clientId, metadata.clientName, JSON.stringify(metadata.redirectUris), metadata.logoUri ?? null, metadata.clientUri ?? null, metadata.cachedAt ?? Date.now());
708
+ (client_id, client_name, redirect_uris, logo_uri, client_uri, token_endpoint_auth_method, jwks, jwks_uri, cached_at)
709
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, clientId, metadata.clientName, JSON.stringify(metadata.redirectUris), metadata.logoUri ?? null, metadata.clientUri ?? null, metadata.tokenEndpointAuthMethod ?? "none", metadata.jwks ? JSON.stringify(metadata.jwks) : null, metadata.jwksUri ?? null, metadata.cachedAt ?? Date.now());
717
710
  }
718
711
  async getClient(clientId) {
719
- const rows = this.sql.exec(`SELECT client_id, client_name, redirect_uris, logo_uri, client_uri, cached_at
712
+ const rows = this.sql.exec(`SELECT client_id, client_name, redirect_uris, logo_uri, client_uri, token_endpoint_auth_method, jwks, jwks_uri, cached_at
720
713
  FROM oauth_clients WHERE client_id = ?`, clientId).toArray();
721
714
  if (rows.length === 0) return null;
722
715
  const row = rows[0];
@@ -726,6 +719,9 @@ var SqliteOAuthStorage = class {
726
719
  redirectUris: JSON.parse(row.redirect_uris),
727
720
  logoUri: row.logo_uri ?? void 0,
728
721
  clientUri: row.client_uri ?? void 0,
722
+ tokenEndpointAuthMethod: row.token_endpoint_auth_method ?? "none",
723
+ jwks: row.jwks ? JSON.parse(row.jwks) : void 0,
724
+ jwksUri: row.jwks_uri ?? void 0,
729
725
  cachedAt: row.cached_at
730
726
  };
731
727
  }
@@ -1606,7 +1602,8 @@ var AccountDurableObject = class extends DurableObject {
1606
1602
  this.ctx.acceptWebSocket(server);
1607
1603
  server.serializeAttachment({
1608
1604
  cursor: cursor ?? 0,
1609
- connectedAt: Date.now()
1605
+ connectedAt: Date.now(),
1606
+ ip: request.headers.get("CF-Connecting-IP") ?? null
1610
1607
  });
1611
1608
  if (cursor !== null) await this.backfillFirehose(server, cursor);
1612
1609
  return new Response(null, {
@@ -1766,9 +1763,16 @@ var AccountDurableObject = class extends DurableObject {
1766
1763
  async rpcGetFirehoseStatus() {
1767
1764
  const sockets = this.ctx.getWebSockets();
1768
1765
  await this.ensureStorageInitialized();
1769
- const seq = await (await this.getStorage()).getSeq();
1766
+ const seq = this.sequencer.getLatestSeq();
1770
1767
  return {
1771
- subscribers: sockets.length,
1768
+ subscribers: sockets.map((ws) => {
1769
+ const attachment = ws.deserializeAttachment();
1770
+ return {
1771
+ connectedAt: attachment.connectedAt,
1772
+ cursor: attachment.cursor,
1773
+ ip: attachment.ip ?? null
1774
+ };
1775
+ }),
1772
1776
  latestSeq: seq || null
1773
1777
  };
1774
1778
  }
@@ -4213,9 +4217,20 @@ function renderPasskeyErrorPage(error, description) {
4213
4217
  </html>`;
4214
4218
  }
4215
4219
 
4220
+ //#endregion
4221
+ //#region src/dashboard.html
4222
+ var dashboard_default = "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>CIRRUS</title>\n <style>\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n :root {\n --bg: #08090d;\n --panel: #0f1117;\n --border: #1a1d2e;\n --text: #b4bcd0;\n --text-bright: #e8ecf4;\n --accent: #7dd3fc;\n --green: #4ade80;\n --amber: #fbbf24;\n --red: #f87171;\n --dim: #3f4558;\n }\n html,\n body {\n height: 100%;\n background: var(--bg);\n color: var(--text);\n font-family:\n ui-monospace, \"Cascadia Code\", \"Source Code Pro\", Menlo, Consolas,\n \"DejaVu Sans Mono\", monospace;\n overflow: hidden;\n }\n body {\n display: flex;\n flex-direction: column;\n padding: clamp(1rem, 2vw, 2rem);\n gap: clamp(0.75rem, 1.5vw, 1.5rem);\n }\n\n /* Header */\n header {\n display: flex;\n align-items: baseline;\n gap: 1.5rem;\n flex-wrap: wrap;\n }\n .brand {\n font-size: clamp(1.5rem, 3vw, 2.5rem);\n font-weight: 700;\n color: var(--text-bright);\n letter-spacing: 0.15em;\n }\n .server-info {\n display: flex;\n gap: 1.5rem;\n align-items: baseline;\n font-size: clamp(0.9rem, 1.5vw, 1.2rem);\n }\n .hostname {\n color: var(--accent);\n }\n .ver {\n color: var(--dim);\n }\n .identity {\n font-size: clamp(0.8rem, 1.2vw, 1rem);\n color: var(--dim);\n width: 100%;\n }\n .identity .handle {\n color: var(--text);\n }\n\n /* Panels */\n .panels {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: clamp(0.75rem, 1.5vw, 1.5rem);\n }\n .panel {\n background: var(--panel);\n border: 1px solid var(--border);\n border-radius: 8px;\n padding: clamp(1rem, 2vw, 1.5rem);\n }\n .panel h2 {\n font-size: clamp(0.7rem, 1vw, 0.85rem);\n letter-spacing: 0.2em;\n color: var(--dim);\n margin-bottom: clamp(0.75rem, 1.5vw, 1.25rem);\n font-weight: 500;\n }\n\n /* Repository panel */\n .record-row {\n display: flex;\n justify-content: space-between;\n padding: 0.3em 0;\n font-size: clamp(0.9rem, 1.5vw, 1.2rem);\n }\n .record-name {\n color: var(--text);\n }\n .record-count {\n color: var(--text-bright);\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n }\n .empty-state {\n color: var(--dim);\n font-style: italic;\n font-size: clamp(0.85rem, 1.3vw, 1.1rem);\n }\n\n /* Federation panel */\n .relay-name {\n font-size: clamp(0.85rem, 1.3vw, 1.1rem);\n color: var(--text);\n margin-bottom: clamp(0.5rem, 1vw, 1rem);\n }\n .sync-status {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n transition: all 0.5s ease;\n }\n .sync-status .status-text {\n font-size: clamp(1.5rem, 3vw, 2.5rem);\n font-weight: 700;\n letter-spacing: 0.1em;\n transition:\n color 0.5s ease,\n text-shadow 0.8s ease;\n }\n .dot {\n width: clamp(10px, 1.2vw, 16px);\n height: clamp(10px, 1.2vw, 16px);\n border-radius: 50%;\n display: inline-block;\n flex-shrink: 0;\n transition:\n background 0.5s ease,\n box-shadow 0.8s ease;\n }\n .sync-status.checking .dot {\n background: var(--dim);\n }\n .sync-status.checking .status-text {\n color: var(--dim);\n }\n .sync-status.unknown .dot {\n background: var(--dim);\n animation: pulse-dim 3s ease-in-out infinite;\n }\n .sync-status.unknown .status-text {\n color: var(--dim);\n }\n .sync-status.behind .dot {\n background: var(--amber);\n animation: pulse 1.5s ease-in-out infinite;\n }\n .sync-status.behind .status-text {\n color: var(--amber);\n }\n .sync-status.synced .dot {\n background: var(--green);\n box-shadow: 0 0 12px var(--green);\n }\n .sync-status.synced .status-text {\n color: var(--green);\n }\n .sync-status.error .dot {\n background: var(--red);\n }\n .sync-status.error .status-text {\n color: var(--red);\n }\n .sync-status.flash .status-text {\n text-shadow:\n 0 0 30px currentColor,\n 0 0 60px currentColor;\n }\n .sync-status.flash .dot {\n box-shadow:\n 0 0 20px currentColor,\n 0 0 40px currentColor;\n }\n .relay-rev {\n font-size: clamp(0.7rem, 1vw, 0.85rem);\n color: var(--dim);\n margin-top: 0.5rem;\n font-variant-numeric: tabular-nums;\n }\n\n /* Events */\n .events-container {\n flex: 1;\n display: flex;\n flex-direction: column;\n background: var(--panel);\n border: 1px solid var(--border);\n border-radius: 8px;\n overflow: hidden;\n min-height: 0;\n }\n .events-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: clamp(0.75rem, 1.5vw, 1rem) clamp(1rem, 2vw, 1.5rem);\n border-bottom: 1px solid var(--border);\n flex-shrink: 0;\n }\n .events-header h2 {\n font-size: clamp(0.7rem, 1vw, 0.85rem);\n letter-spacing: 0.2em;\n color: var(--dim);\n font-weight: 500;\n }\n .ws-status {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: clamp(0.7rem, 1vw, 0.85rem);\n color: var(--dim);\n }\n .ws-status.connected .dot {\n background: var(--green);\n animation: pulse 2s ease-in-out infinite;\n }\n .ws-status.connected .ws-label {\n color: var(--green);\n }\n .ws-status.disconnected .dot {\n background: var(--dim);\n }\n .ws-status.error .dot {\n background: var(--red);\n }\n .events-list {\n flex: 1;\n overflow-y: auto;\n padding: 0 clamp(1rem, 2vw, 1.5rem);\n }\n .events-list .empty-state {\n padding: 1rem 0;\n }\n .event {\n display: flex;\n gap: clamp(0.75rem, 1.5vw, 1.5rem);\n padding: 0.4em 0;\n font-size: clamp(0.85rem, 1.3vw, 1.1rem);\n border-bottom: 1px solid rgba(26, 29, 46, 0.5);\n animation: slide-in 0.3s ease-out;\n }\n .event.new {\n background: rgba(125, 211, 252, 0.06);\n transition: background 1.5s ease-out;\n }\n .event-time {\n color: var(--dim);\n font-variant-numeric: tabular-nums;\n flex-shrink: 0;\n }\n .event-seq {\n color: var(--dim);\n font-variant-numeric: tabular-nums;\n flex-shrink: 0;\n min-width: 3em;\n text-align: right;\n }\n .event-action {\n flex-shrink: 0;\n font-weight: 600;\n min-width: 5em;\n }\n .event-action.create {\n color: var(--green);\n }\n .event-action.update {\n color: var(--amber);\n }\n .event-action.delete {\n color: var(--red);\n }\n .event-path {\n color: var(--text);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n }\n /* Animations */\n @keyframes pulse {\n 0%,\n 100% {\n opacity: 0.5;\n }\n 50% {\n opacity: 1;\n }\n }\n @keyframes pulse-dim {\n 0%,\n 100% {\n opacity: 0.3;\n }\n 50% {\n opacity: 0.6;\n }\n }\n @keyframes slide-in {\n from {\n opacity: 0;\n transform: translateX(20px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n }\n\n /* Scrollbar */\n .events-list::-webkit-scrollbar {\n width: 4px;\n }\n .events-list::-webkit-scrollbar-track {\n background: transparent;\n }\n .events-list::-webkit-scrollbar-thumb {\n background: var(--border);\n border-radius: 2px;\n }\n </style>\n </head>\n <body>\n <header>\n <div class=\"brand\">&#9729;&#65039; CIRRUS</div>\n <div class=\"server-info\">\n <span class=\"hostname\" id=\"cfg-hostname\"></span>\n <span class=\"ver\" id=\"cfg-version\"></span>\n </div>\n <div class=\"identity\">\n <span class=\"handle\" id=\"cfg-handle\"></span>\n <span>&middot;</span>\n <span id=\"cfg-did\"></span>\n </div>\n </header>\n\n <section class=\"panels\">\n <div class=\"panel\">\n <h2>REPOSITORY</h2>\n <div id=\"records\"><span class=\"empty-state\">Loading&hellip;</span></div>\n </div>\n <div class=\"panel\">\n <h2>FEDERATION</h2>\n <div class=\"relay-name\">bsky.network</div>\n <div class=\"sync-status checking\" id=\"sync-status\">\n <span class=\"dot\"></span>\n <span class=\"status-text\">CHECKING</span>\n </div>\n <div class=\"relay-rev\" id=\"relay-rev\"></div>\n </div>\n </section>\n\n <section class=\"events-container\">\n <div class=\"events-header\">\n <h2>EVENTS</h2>\n <div class=\"ws-status disconnected\" id=\"ws-status\">\n <span class=\"dot\"></span>\n <span class=\"ws-label\">disconnected</span>\n </div>\n </div>\n <div class=\"events-list\" id=\"events\">\n <div class=\"empty-state\">Waiting for events&hellip;</div>\n </div>\n </section>\n\n <script>\n {\n const CONFIG = window.__CIRRUS_CONFIG || {};\n const BASE = window.location.origin;\n const RELAY = \"https://bsky.network\";\n const DID = CONFIG.did || \"\";\n const MAX_EVENTS = 100;\n let pdsRev = null;\n let currentSyncStatus = null;\n let reconnectTimer = null;\n\n const $ = (id) => document.getElementById(id);\n\n // -- Populate config into DOM --\n const applyConfig = () => {\n document.title = `CIRRUS \\u00b7 ${CONFIG.hostname || \"\"}`;\n $(\"cfg-hostname\").textContent = CONFIG.hostname || \"\";\n $(\"cfg-version\").textContent = CONFIG.version\n ? `v${CONFIG.version}`\n : \"\";\n $(\"cfg-handle\").textContent = CONFIG.handle\n ? `@${CONFIG.handle}`\n : \"\";\n $(\"cfg-did\").textContent = CONFIG.did || \"\";\n };\n\n // -- Minimal CBOR decoder for firehose frames --\n const decodeCBOR = (d, o) => {\n const view = new DataView(d.buffer, d.byteOffset, d.byteLength);\n const major = d[o] >> 5;\n const additional = d[o] & 0x1f;\n\n const readLen = (off, add) => {\n if (add < 24) return [add, off + 1];\n if (add === 24) return [d[off + 1], off + 2];\n if (add === 25) return [view.getUint16(off + 1), off + 3];\n if (add === 26) return [view.getUint32(off + 1), off + 5];\n if (add === 27)\n return [\n view.getUint32(off + 1) * 0x100000000 + view.getUint32(off + 5),\n off + 9,\n ];\n return [0, off + 1];\n };\n\n switch (major) {\n case 0:\n return readLen(o, additional);\n case 1: {\n const [n, p] = readLen(o, additional);\n return [-1 - n, p];\n }\n case 2: {\n const [n, p] = readLen(o, additional);\n return [d.slice(p, p + n), p + n];\n }\n case 3: {\n const [n, p] = readLen(o, additional);\n return [new TextDecoder().decode(d.subarray(p, p + n)), p + n];\n }\n case 4: {\n let [count, pos] = readLen(o, additional);\n const arr = [];\n for (let i = 0; i < count; i++) {\n const [val, next] = decodeCBOR(d, pos);\n arr.push(val);\n pos = next;\n }\n return [arr, pos];\n }\n case 5: {\n let [count, pos] = readLen(o, additional);\n const obj = {};\n for (let i = 0; i < count; i++) {\n const [key, kNext] = decodeCBOR(d, pos);\n const [val, vNext] = decodeCBOR(d, kNext);\n obj[key] = val;\n pos = vNext;\n }\n return [obj, pos];\n }\n case 6: {\n const [, p] = readLen(o, additional);\n return decodeCBOR(d, p);\n }\n case 7: {\n if (additional === 20) return [false, o + 1];\n if (additional === 21) return [true, o + 1];\n if (additional === 22) return [null, o + 1];\n if (additional === 23) return [undefined, o + 1];\n if (additional === 25) return [null, o + 3];\n if (additional === 26) return [view.getFloat32(o + 1), o + 5];\n if (additional === 27) return [view.getFloat64(o + 1), o + 9];\n return [null, o + 1];\n }\n }\n return [null, o + 1];\n };\n\n const parseFirehoseMessage = (buffer) => {\n try {\n const d = new Uint8Array(buffer);\n const [header, bodyOff] = decodeCBOR(d, 0);\n if (!header || header.op !== 1 || header.t !== \"#commit\")\n return null;\n const [body] = decodeCBOR(d, bodyOff);\n if (!body) return null;\n return {\n seq: body.seq,\n repo: body.repo,\n rev: body.rev,\n ops: (body.ops || []).map((op) => ({\n action: op.action,\n path: op.path,\n })),\n };\n } catch {\n return null;\n }\n };\n\n // -- Friendly collection names --\n const COLLECTION_NAMES = {\n \"app.bsky.feed.post\": \"posts\",\n \"app.bsky.feed.like\": \"likes\",\n \"app.bsky.graph.follow\": \"follows\",\n \"app.bsky.feed.repost\": \"reposts\",\n \"app.bsky.actor.profile\": \"profile\",\n \"app.bsky.graph.block\": \"blocks\",\n \"app.bsky.graph.list\": \"lists\",\n \"app.bsky.graph.listitem\": \"list items\",\n \"app.bsky.feed.generator\": \"feeds\",\n \"app.bsky.feed.threadgate\": \"threadgates\",\n \"app.bsky.graph.starterpack\": \"starter packs\",\n };\n\n const friendlyName = (collection) =>\n COLLECTION_NAMES[collection] || collection.split(\".\").pop();\n\n const animateNumber = (el, target) => {\n let current = parseInt(el.textContent) || 0;\n if (current === target) return;\n const diff = target - current;\n const steps = Math.min(Math.abs(diff), 20);\n const stepSize = diff / steps;\n let step = 0;\n const tick = () => {\n step++;\n if (step >= steps) {\n el.textContent = target;\n return;\n }\n el.textContent = Math.round(current + stepSize * step);\n requestAnimationFrame(tick);\n };\n requestAnimationFrame(tick);\n };\n\n // -- Data fetching --\n const fetchRepoData = async () => {\n try {\n const reposRes = await fetch(\n `${BASE}/xrpc/com.atproto.sync.listRepos`,\n );\n const reposData = await reposRes.json();\n const repo = reposData.repos?.[0];\n if (repo) pdsRev = repo.rev;\n\n const descRes = await fetch(\n `${BASE}/xrpc/com.atproto.repo.describeRepo?repo=${encodeURIComponent(DID)}`,\n );\n const desc = await descRes.json();\n const collections = desc.collections || [];\n\n if (collections.length === 0) {\n $(\"records\").innerHTML =\n '<span class=\"empty-state\">No records yet</span>';\n return;\n }\n\n const results = await Promise.all(\n collections.map(async (col) => {\n const res = await fetch(\n `${BASE}/xrpc/com.atproto.repo.listRecords?repo=${encodeURIComponent(DID)}&collection=${encodeURIComponent(col)}&limit=100`,\n );\n const data = await res.json();\n return {\n collection: col,\n count: data.records?.length || 0,\n hasMore: !!data.cursor,\n };\n }),\n );\n\n const container = $(\"records\");\n for (const r of results) {\n const id = `rec-${r.collection.replaceAll(\".\", \"-\")}`;\n const existing = $(id);\n if (existing) {\n const countEl = existing.querySelector(\".record-count\");\n animateNumber(countEl, r.count);\n if (r.hasMore) countEl.textContent = `${r.count}+`;\n } else {\n if (container.querySelector(\".empty-state\"))\n container.innerHTML = \"\";\n const row = document.createElement(\"div\");\n row.className = \"record-row\";\n row.id = id;\n row.innerHTML = `<span class=\"record-name\">${friendlyName(r.collection)}</span><span class=\"record-count\">${r.count}${r.hasMore ? \"+\" : \"\"}</span>`;\n container.appendChild(row);\n }\n }\n } catch (e) {\n console.error(\"Failed to fetch repo data:\", e);\n }\n };\n\n const fetchRelaySync = async () => {\n if (!pdsRev) return;\n try {\n const res = await fetch(\n `${RELAY}/xrpc/com.atproto.sync.getLatestCommit?did=${encodeURIComponent(DID)}`,\n );\n if (res.status === 404) {\n setSyncStatus(\"unknown\");\n return;\n }\n const data = await res.json();\n setSyncStatus(data.rev === pdsRev ? \"synced\" : \"behind\", data.rev);\n } catch {\n setSyncStatus(\"error\");\n }\n };\n\n // -- Sync status display --\n const setSyncStatus = (status, rev) => {\n if (status === currentSyncStatus) return;\n const el = $(\"sync-status\");\n const prevStatus = currentSyncStatus;\n\n el.className = `sync-status ${status}`;\n el.querySelector(\".status-text\").textContent = status.toUpperCase();\n $(\"relay-rev\").textContent = rev ? `rev: ${rev.slice(0, 12)}` : \"\";\n\n if (prevStatus && prevStatus !== status) {\n el.classList.add(\"flash\");\n setTimeout(() => el.classList.remove(\"flash\"), 1200);\n }\n currentSyncStatus = status;\n };\n\n // -- Event stream --\n const addEvent = (seq, action, path) => {\n const container = $(\"events\");\n container.querySelector(\".empty-state\")?.remove();\n\n const el = document.createElement(\"div\");\n el.className = \"event new\";\n const time = new Date().toLocaleTimeString(\"en-GB\", {\n hour12: false,\n });\n el.innerHTML =\n `<span class=\"event-time\">${time}</span>` +\n `<span class=\"event-seq\">#${seq}</span>` +\n `<span class=\"event-action ${action}\">${action.toUpperCase()}</span>` +\n `<span class=\"event-path\">${path}</span>`;\n container.prepend(el);\n setTimeout(() => el.classList.remove(\"new\"), 1500);\n while (container.children.length > MAX_EVENTS) {\n container.lastChild.remove();\n }\n };\n\n // -- WebSocket --\n const setWsStatus = (status) => {\n const el = $(\"ws-status\");\n el.className = `ws-status ${status}`;\n el.querySelector(\".ws-label\").textContent = status;\n };\n\n const connectFirehose = () => {\n if (reconnectTimer) {\n clearTimeout(reconnectTimer);\n reconnectTimer = null;\n }\n const proto = location.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n const ws = new WebSocket(\n `${proto}//${location.host}/xrpc/com.atproto.sync.subscribeRepos`,\n );\n ws.binaryType = \"arraybuffer\";\n\n ws.onopen = () => setWsStatus(\"connected\");\n ws.onmessage = (e) => {\n const commit = parseFirehoseMessage(e.data);\n if (!commit) return;\n for (const op of commit.ops) {\n addEvent(commit.seq, op.action, op.path);\n }\n };\n ws.onclose = () => {\n setWsStatus(\"disconnected\");\n reconnectTimer = setTimeout(connectFirehose, 3000);\n };\n ws.onerror = () => setWsStatus(\"error\");\n };\n\n // -- Init --\n const init = () => {\n applyConfig();\n fetchRepoData();\n fetchRelaySync();\n connectFirehose();\n\n setInterval(fetchRelaySync, 5000);\n setInterval(fetchRepoData, 30000);\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init);\n } else {\n init();\n }\n }\n <\/script>\n </body>\n</html>\n";
4223
+
4224
+ //#endregion
4225
+ //#region src/dashboard.ts
4226
+ function renderDashboard(config) {
4227
+ const configScript = `<script>window.__CIRRUS_CONFIG=${JSON.stringify(config)};<\/script>`;
4228
+ return dashboard_default.replace("</head>", configScript + "\n</head>");
4229
+ }
4230
+
4216
4231
  //#endregion
4217
4232
  //#region package.json
4218
- var version = "0.10.5";
4233
+ var version = "0.11.0";
4219
4234
 
4220
4235
  //#endregion
4221
4236
  //#region src/index.ts
@@ -4346,6 +4361,14 @@ body {
4346
4361
  </html>`;
4347
4362
  return c.html(html);
4348
4363
  });
4364
+ app.get("/status", (c) => {
4365
+ return c.html(renderDashboard({
4366
+ hostname: c.env.PDS_HOSTNAME,
4367
+ handle: c.env.HANDLE,
4368
+ did: c.env.DID,
4369
+ version
4370
+ }));
4371
+ });
4349
4372
  app.get("/xrpc/com.atproto.sync.getRepo", (c) => getRepo(c, getAccountDO(c.env)));
4350
4373
  app.get("/xrpc/com.atproto.sync.getRepoStatus", (c) => getRepoStatus(c, getAccountDO(c.env)));
4351
4374
  app.get("/xrpc/com.atproto.sync.getBlocks", (c) => getBlocks(c, getAccountDO(c.env)));