@runappsai/sdk 0.5.1 → 0.6.2

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 (68) hide show
  1. package/README.md +29 -0
  2. package/dist/activity-tracker.d.ts +8 -0
  3. package/dist/activity-tracker.d.ts.map +1 -1
  4. package/dist/activity-tracker.js +3 -0
  5. package/dist/activity-tracker.js.map +1 -1
  6. package/dist/browser-auth.d.ts +7 -0
  7. package/dist/browser-auth.d.ts.map +1 -1
  8. package/dist/browser-auth.js +105 -15
  9. package/dist/browser-auth.js.map +1 -1
  10. package/dist/client.d.ts +25 -0
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +22 -0
  13. package/dist/client.js.map +1 -1
  14. package/dist/events.d.ts +20 -0
  15. package/dist/events.d.ts.map +1 -1
  16. package/dist/events.js.map +1 -1
  17. package/dist/files.d.ts +3 -0
  18. package/dist/files.d.ts.map +1 -1
  19. package/dist/files.js +4 -1
  20. package/dist/files.js.map +1 -1
  21. package/dist/index.d.ts +2 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +3 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/sdk.umd.js +2 -2
  26. package/dist/sdk.umd.js.map +1 -1
  27. package/dist/sync/codec.d.ts +39 -0
  28. package/dist/sync/codec.d.ts.map +1 -0
  29. package/dist/sync/codec.js +364 -0
  30. package/dist/sync/codec.js.map +1 -0
  31. package/dist/sync/engine.d.ts +143 -0
  32. package/dist/sync/engine.d.ts.map +1 -0
  33. package/dist/sync/engine.js +727 -0
  34. package/dist/sync/engine.js.map +1 -0
  35. package/dist/sync/hook.d.ts +42 -0
  36. package/dist/sync/hook.d.ts.map +1 -0
  37. package/dist/sync/hook.js +426 -0
  38. package/dist/sync/hook.js.map +1 -0
  39. package/dist/sync/index.d.ts +6 -0
  40. package/dist/sync/index.d.ts.map +1 -0
  41. package/dist/sync/index.js +6 -0
  42. package/dist/sync/index.js.map +1 -0
  43. package/dist/sync/log.d.ts +41 -0
  44. package/dist/sync/log.d.ts.map +1 -0
  45. package/dist/sync/log.js +143 -0
  46. package/dist/sync/log.js.map +1 -0
  47. package/dist/sync/remote.d.ts +38 -0
  48. package/dist/sync/remote.d.ts.map +1 -0
  49. package/dist/sync/remote.js +61 -0
  50. package/dist/sync/remote.js.map +1 -0
  51. package/dist/transport.d.ts +5 -0
  52. package/dist/transport.d.ts.map +1 -1
  53. package/dist/transport.js +19 -6
  54. package/dist/transport.js.map +1 -1
  55. package/package.json +2 -1
  56. package/src/activity-tracker.ts +5 -0
  57. package/src/browser-auth.ts +103 -16
  58. package/src/client.ts +37 -0
  59. package/src/events.ts +22 -0
  60. package/src/files.ts +7 -5
  61. package/src/index.ts +13 -0
  62. package/src/sync/codec.ts +354 -0
  63. package/src/sync/engine.ts +818 -0
  64. package/src/sync/hook.ts +495 -0
  65. package/src/sync/index.ts +5 -0
  66. package/src/sync/log.ts +170 -0
  67. package/src/sync/remote.ts +59 -0
  68. package/src/transport.ts +20 -8
@@ -0,0 +1,143 @@
1
+ // sync/log.ts — the SDK's own IndexedDB database.
2
+ //
3
+ // Holds what the sync engine needs to survive a reload:
4
+ // ops — local changes not yet pushed, in commit order. Values are kept
5
+ // as the app wrote them (structured clone, Blobs included);
6
+ // they are encoded only when pushed, so logging works offline.
7
+ // meta — small key/value state: the owner (user id the local data
8
+ // belongs to), shard ETags seen last, store clear marks.
9
+ //
10
+ // Opened through the untouched `indexedDB.open`, never the hooked one,
11
+ // and its name starts with `__runapps` so the hook leaves it alone.
12
+ export const SYNC_DB_NAME = "__runapps_sync__";
13
+ const SYNC_DB_VERSION = 1;
14
+ function req(r) {
15
+ return new Promise((resolve, reject) => {
16
+ r.onsuccess = () => resolve(r.result);
17
+ r.onerror = () => reject(r.error ?? new Error("IndexedDB request failed"));
18
+ });
19
+ }
20
+ function done(tx) {
21
+ return new Promise((resolve, reject) => {
22
+ tx.oncomplete = () => resolve();
23
+ tx.onabort = () => reject(tx.error ?? new Error("IndexedDB transaction aborted"));
24
+ tx.onerror = () => reject(tx.error ?? new Error("IndexedDB transaction failed"));
25
+ });
26
+ }
27
+ export class SyncLog {
28
+ open;
29
+ dbPromise = null;
30
+ constructor(open) {
31
+ this.open = open;
32
+ }
33
+ db() {
34
+ if (!this.dbPromise) {
35
+ this.dbPromise = new Promise((resolve, reject) => {
36
+ const r = this.open(SYNC_DB_NAME, SYNC_DB_VERSION);
37
+ r.onupgradeneeded = () => {
38
+ const db = r.result;
39
+ if (!db.objectStoreNames.contains("ops")) {
40
+ const ops = db.createObjectStore("ops", { keyPath: "id", autoIncrement: true });
41
+ ops.createIndex("store", ["db", "store"], { unique: false });
42
+ }
43
+ if (!db.objectStoreNames.contains("meta"))
44
+ db.createObjectStore("meta");
45
+ };
46
+ r.onsuccess = () => {
47
+ const db = r.result;
48
+ // Another tab upgrading (a future SDK) must not be blocked by us.
49
+ db.onversionchange = () => {
50
+ db.close();
51
+ this.dbPromise = null;
52
+ };
53
+ resolve(db);
54
+ };
55
+ r.onerror = () => reject(r.error ?? new Error("cannot open sync log"));
56
+ r.onblocked = () => reject(new Error("sync log open blocked"));
57
+ });
58
+ this.dbPromise.catch(() => {
59
+ this.dbPromise = null;
60
+ });
61
+ }
62
+ return this.dbPromise;
63
+ }
64
+ async append(ops) {
65
+ if (ops.length === 0)
66
+ return;
67
+ const db = await this.db();
68
+ const tx = db.transaction("ops", "readwrite");
69
+ const st = tx.objectStore("ops");
70
+ for (const op of ops)
71
+ st.add(op);
72
+ await done(tx);
73
+ }
74
+ async pending() {
75
+ const db = await this.db();
76
+ const tx = db.transaction("ops", "readonly");
77
+ const all = (await req(tx.objectStore("ops").getAll()));
78
+ return all;
79
+ }
80
+ async pendingCount() {
81
+ const db = await this.db();
82
+ const tx = db.transaction("ops", "readonly");
83
+ return req(tx.objectStore("ops").count());
84
+ }
85
+ async remove(ids) {
86
+ if (ids.length === 0)
87
+ return;
88
+ const db = await this.db();
89
+ const tx = db.transaction("ops", "readwrite");
90
+ const st = tx.objectStore("ops");
91
+ for (const id of ids)
92
+ st.delete(id);
93
+ await done(tx);
94
+ }
95
+ async clearOps() {
96
+ const db = await this.db();
97
+ const tx = db.transaction("ops", "readwrite");
98
+ tx.objectStore("ops").clear();
99
+ await done(tx);
100
+ }
101
+ async getMeta(key) {
102
+ const db = await this.db();
103
+ const tx = db.transaction("meta", "readonly");
104
+ return (await req(tx.objectStore("meta").get(key)));
105
+ }
106
+ async setMeta(entries) {
107
+ const db = await this.db();
108
+ const tx = db.transaction("meta", "readwrite");
109
+ const st = tx.objectStore("meta");
110
+ for (const k of Object.keys(entries)) {
111
+ if (entries[k] === undefined)
112
+ st.delete(k);
113
+ else
114
+ st.put(entries[k], k);
115
+ }
116
+ await done(tx);
117
+ }
118
+ /** Every meta entry whose key starts with `prefix`, as a map. */
119
+ async metaWithPrefix(prefix) {
120
+ const db = await this.db();
121
+ const tx = db.transaction("meta", "readonly");
122
+ const st = tx.objectStore("meta");
123
+ const range = IDBKeyRange.bound(prefix, prefix + "￿");
124
+ const keys = (await req(st.getAllKeys(range)));
125
+ const vals = await req(st.getAll(range));
126
+ const out = new Map();
127
+ keys.forEach((k, i) => out.set(k, vals[i]));
128
+ return out;
129
+ }
130
+ async clearAll() {
131
+ const db = await this.db();
132
+ const tx = db.transaction(["ops", "meta"], "readwrite");
133
+ tx.objectStore("ops").clear();
134
+ tx.objectStore("meta").clear();
135
+ await done(tx);
136
+ }
137
+ close() {
138
+ this.dbPromise?.then((db) => db.close()).catch(() => { });
139
+ this.dbPromise = null;
140
+ }
141
+ }
142
+ export { req as idbRequest, done as idbDone };
143
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/sync/log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { FilesService } from "../files.js";
2
+ import type { SyncRemote } from "./engine.js";
3
+ export declare class FilesRemote implements SyncRemote {
4
+ private readonly files;
5
+ constructor(files: FilesService);
6
+ list(prefix: string): Promise<{
7
+ path: string;
8
+ etag: string;
9
+ }[]>;
10
+ getJSON(path: string, ifNoneMatch?: string): Promise<{
11
+ status: "unchanged";
12
+ value?: undefined;
13
+ etag?: undefined;
14
+ } | {
15
+ status: "missing";
16
+ value?: undefined;
17
+ etag?: undefined;
18
+ } | {
19
+ status: "ok";
20
+ value: {} | null;
21
+ etag: string;
22
+ }>;
23
+ putJSON(path: string, value: unknown, cond: {
24
+ ifMatch?: string;
25
+ ifNoneMatch?: boolean;
26
+ }): Promise<{
27
+ status: "ok";
28
+ etag: string;
29
+ serverTime: number | undefined;
30
+ } | {
31
+ status: "conflict";
32
+ etag?: undefined;
33
+ serverTime?: undefined;
34
+ }>;
35
+ putBlob(path: string, blob: Blob): Promise<void>;
36
+ getBlob(path: string): Promise<Blob>;
37
+ }
38
+ //# sourceMappingURL=remote.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../src/sync/remote.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,qBAAa,WAAY,YAAW,UAAU;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,YAAY;IAE1C,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAW/D,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM;;;;;;;;;;;;;IAO1C,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE;;;;;;;;;IAevF,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGrC"}
@@ -0,0 +1,61 @@
1
+ // sync/remote.ts — the sync engine's storage, over the files API.
2
+ //
3
+ // Shards are plain JSON files in the user's file space for the app, so
4
+ // they share its quota, billing and deletion with everything else the
5
+ // app stores for that user. Conditional reads (304) and writes (412 /
6
+ // 409) come from the files API, which checks them against the store.
7
+ export class FilesRemote {
8
+ files;
9
+ constructor(files) {
10
+ this.files = files;
11
+ }
12
+ async list(prefix) {
13
+ const out = [];
14
+ let cursor;
15
+ do {
16
+ const page = await this.files.list({ prefix, limit: 1000, ...(cursor ? { cursor } : {}) });
17
+ for (const f of page.files)
18
+ if (f.etag)
19
+ out.push({ path: f.path, etag: f.etag });
20
+ cursor = page.next_cursor;
21
+ } while (cursor);
22
+ return out;
23
+ }
24
+ async getJSON(path, ifNoneMatch) {
25
+ const r = await this.files.readJSON(path, ifNoneMatch ? { ifNoneMatch } : undefined);
26
+ if (r.notModified)
27
+ return { status: "unchanged" };
28
+ if (r.value === undefined)
29
+ return { status: "missing" };
30
+ return { status: "ok", value: r.value, etag: r.etag ?? "" };
31
+ }
32
+ async putJSON(path, value, cond) {
33
+ try {
34
+ const obj = await this.files.put(path, JSON.stringify(value), {
35
+ contentType: "application/json",
36
+ ...(cond.ifMatch ? { ifMatch: cond.ifMatch } : {}),
37
+ ...(cond.ifNoneMatch ? { ifNoneMatch: true } : {}),
38
+ });
39
+ return { status: "ok", etag: obj.etag ?? "", serverTime: obj.last_modified ? Date.parse(obj.last_modified) : undefined };
40
+ }
41
+ catch (e) {
42
+ const code = e.statusCode;
43
+ if (code === 412 || code === 409)
44
+ return { status: "conflict" };
45
+ throw e;
46
+ }
47
+ }
48
+ async putBlob(path, blob) {
49
+ try {
50
+ await this.files.put(path, blob, { contentType: blob.type || "application/octet-stream", ifNoneMatch: true });
51
+ }
52
+ catch (e) {
53
+ if (e.statusCode !== 409)
54
+ throw e; // already stored: same bytes, same name
55
+ }
56
+ }
57
+ getBlob(path) {
58
+ return this.files.get(path);
59
+ }
60
+ }
61
+ //# sourceMappingURL=remote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/sync/remote.ts"],"names":[],"mappings":"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"}
@@ -83,10 +83,13 @@ export declare class Transport {
83
83
  * and the ETag of those bytes, when the server sends one. */
84
84
  getRaw(path: string, init?: {
85
85
  signal?: AbortSignal;
86
+ ifNoneMatch?: string;
86
87
  }): Promise<{
87
88
  data: Uint8Array;
88
89
  contentType: string;
89
90
  etag?: string;
91
+ notModified?: boolean;
92
+ serverTime?: number;
90
93
  }>;
91
94
  /** POST a multipart/form-data body. Used by audio.transcribe and image.edit. */
92
95
  postMultipart<T>(path: string, form: FormData, init?: {
@@ -123,4 +126,6 @@ export declare class Transport {
123
126
  private authHeaders;
124
127
  private parseError;
125
128
  }
129
+ /** The server's clock from a Date header, as ms since epoch. */
130
+ export declare function parseServerDate(h: string | null): number | undefined;
126
131
  //# sourceMappingURL=transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
package/dist/transport.js CHANGED
@@ -109,18 +109,24 @@ export class Transport {
109
109
  /** GET path; return raw bytes + content-type (for video/audio downloads)
110
110
  * and the ETag of those bytes, when the server sends one. */
111
111
  async getRaw(path, init) {
112
- const resp = await this.fetchWithAuthRetry(path, async () => ({
113
- method: "GET",
114
- headers: await this.authHeaders(),
115
- signal: init?.signal,
116
- }));
112
+ const resp = await this.fetchWithAuthRetry(path, async () => {
113
+ const headers = await this.authHeaders();
114
+ if (init?.ifNoneMatch)
115
+ headers["If-None-Match"] = `"${init.ifNoneMatch.replace(/"/g, "")}"`;
116
+ return { method: "GET", headers, signal: init?.signal };
117
+ });
118
+ const serverTime = parseServerDate(resp.headers.get("date"));
119
+ if (resp.status === 304) {
120
+ const etag = (resp.headers.get("etag") ?? "").replace(/"/g, "") || init?.ifNoneMatch;
121
+ return { data: new Uint8Array(0), contentType: "", etag, notModified: true, serverTime };
122
+ }
117
123
  if (!resp.ok) {
118
124
  throw await this.parseError(resp);
119
125
  }
120
126
  const buf = new Uint8Array(await resp.arrayBuffer());
121
127
  const contentType = resp.headers.get("content-type") ?? "";
122
128
  const etag = (resp.headers.get("etag") ?? "").replace(/"/g, "") || undefined;
123
- return { data: buf, contentType, etag };
129
+ return { data: buf, contentType, etag, serverTime };
124
130
  }
125
131
  /** POST a multipart/form-data body. Used by audio.transcribe and image.edit. */
126
132
  async postMultipart(path, form, init) {
@@ -225,4 +231,11 @@ export class Transport {
225
231
  return new APIError(resp.status, type, message);
226
232
  }
227
233
  }
234
+ /** The server's clock from a Date header, as ms since epoch. */
235
+ export function parseServerDate(h) {
236
+ if (!h)
237
+ return undefined;
238
+ const t = Date.parse(h);
239
+ return Number.isNaN(t) ? undefined : t;
240
+ }
228
241
  //# sourceMappingURL=transport.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runappsai/sdk",
3
- "version": "0.5.1",
3
+ "version": "0.6.2",
4
4
  "description": "JavaScript / TypeScript client for the RunApps AI Gateway",
5
5
  "license": "MIT",
6
6
  "author": "RunApps",
@@ -50,6 +50,7 @@
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/node": "^20.0.0",
53
+ "fake-indexeddb": "^6.2.5",
53
54
  "tsup": "^8.5.1",
54
55
  "typescript": "^5.5.0"
55
56
  }
@@ -85,6 +85,8 @@ export interface ActivitySnapshot {
85
85
  active: ActiveCall[];
86
86
  recent: CompletedCall[];
87
87
  session: SessionStats;
88
+ /** Sync state, when RunApps Sync is on (see `client.sync`). */
89
+ sync?: { state: "off" | "idle" | "syncing" | "offline" | "error"; pending: number; lastSyncedAt?: number; error?: string };
88
90
  /** Highest-priority status colour for the LED dot:
89
91
  * "error" → recent failure within ERROR_HIGHLIGHT_MS
90
92
  * "active" → at least one in-flight call
@@ -116,6 +118,7 @@ export class ActivityTracker {
116
118
  * ring/LED stayed idle until the user opened the popover —
117
119
  * events landed in the tracker but nobody told the DOM. */
118
120
  private changeListeners = new Set<() => void>();
121
+ private sync: ActivitySnapshot["sync"] | undefined = undefined;
119
122
 
120
123
  /**
121
124
  * Subscribe the tracker to a bus. Returns a single disposer that
@@ -128,6 +131,7 @@ export class ActivityTracker {
128
131
  events.on("request:streamDelta", (e) => { this.onDelta(e); this.notify(); }),
129
132
  events.on("request:end", (e) => { this.onEnd(e); this.notify(); }),
130
133
  events.on("request:error", (e) => { this.onError(e); this.notify(); }),
134
+ events.on("sync:state", (e) => { this.sync = { ...e }; this.notify(); }),
131
135
  ];
132
136
  return () => {
133
137
  for (const o of offs) o();
@@ -165,6 +169,7 @@ export class ActivityTracker {
165
169
  active: Array.from(this.active.values()),
166
170
  recent: this.recent.slice(),
167
171
  session: { ...this.session },
172
+ ...(this.sync ? { sync: { ...this.sync } } : {}),
168
173
  status:
169
174
  now - this.lastErrorAt < ERROR_HIGHLIGHT_MS
170
175
  ? "error"
@@ -23,6 +23,7 @@
23
23
 
24
24
  import { ActivityTracker, type ActivitySnapshot, type SessionStats } from "./activity-tracker.js";
25
25
  import type { SDKEvents } from "./events.js";
26
+ import { hash32 } from "./sync/codec.js";
26
27
 
27
28
  export interface BrowserAuthOptions {
28
29
  /**
@@ -310,6 +311,18 @@ export class BrowserAuth {
310
311
  return this.tokenIsFresh();
311
312
  }
312
313
 
314
+ /**
315
+ * A stable id for whose data is on this browser, or null when nobody
316
+ * is signed in. The user's id when the grant carried one; otherwise
317
+ * derived from the token, which is bound to one user and one app and
318
+ * never rotates. Used by Sync to tell an account switch.
319
+ */
320
+ ownerId(): string | null {
321
+ if (!this.tokenIsFresh()) return null;
322
+ if (this.userInfo?.id) return this.userInfo.id;
323
+ return "t" + hash32(this.token as string).toString(36);
324
+ }
325
+
313
326
  /**
314
327
  * Clear the cached token / user / badge and the persisted copy in
315
328
  * localStorage. Next gateway call will trigger a redirect to the
@@ -544,7 +557,7 @@ export class BrowserAuth {
544
557
  .split("&")
545
558
  .forEach((kv) => {
546
559
  const i = kv.indexOf("=");
547
- if (i >= 0) params[decodeURIComponent(kv.slice(0, i))] = decodeURIComponent(kv.slice(i + 1));
560
+ if (i >= 0) params[decodeURIComponent(kv.slice(0, i))] = decodeURIComponent(kv.slice(i + 1).replace(/\+/g, " "));
548
561
  });
549
562
  const token = params.runapps_token || params.runjobs_token;
550
563
  if (!token) return false;
@@ -870,7 +883,7 @@ function mountActivityBadge(opts: MountOpts): HTMLButtonElement {
870
883
  const el = document.createElement("button");
871
884
  el.id = id;
872
885
  el.type = "button";
873
- el.title = "RunApps activity";
886
+ el.title = user.name || "RunApps";
874
887
  el.setAttribute("aria-label", "RunApps activity status");
875
888
  el.style.cssText = [
876
889
  "position:fixed",
@@ -878,9 +891,9 @@ function mountActivityBadge(opts: MountOpts): HTMLButtonElement {
878
891
  "z-index:2147483647",
879
892
  "display:flex",
880
893
  "align-items:center",
881
- "gap:8px",
882
- "padding:6px 12px 6px 6px",
883
- "border-radius:999px",
894
+ "justify-content:center",
895
+ "padding:5px",
896
+ "border-radius:50%",
884
897
  "font:500 12px/1 -apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif",
885
898
  "color:#fff",
886
899
  "background:rgba(15,15,20,0.55)",
@@ -889,7 +902,6 @@ function mountActivityBadge(opts: MountOpts): HTMLButtonElement {
889
902
  "border:1px solid rgba(255,255,255,0.12)",
890
903
  "box-shadow:0 4px 16px rgba(0,0,0,0.15)",
891
904
  "user-select:none",
892
- "max-width:220px",
893
905
  "overflow:visible", // popover spills out the top
894
906
  "cursor:pointer",
895
907
  "appearance:none",
@@ -982,12 +994,7 @@ function mountActivityBadge(opts: MountOpts): HTMLButtonElement {
982
994
  avatarWrap.appendChild(avatar);
983
995
  avatarWrap.appendChild(led);
984
996
 
985
- const name = document.createElement("span");
986
- name.textContent = user.name || "Signed in";
987
- name.style.cssText = "white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none";
988
-
989
997
  el.appendChild(avatarWrap);
990
- el.appendChild(name);
991
998
 
992
999
  // ─── Popover (lazy, append on first open) ──────────────────
993
1000
  //
@@ -1035,7 +1042,7 @@ function mountActivityBadge(opts: MountOpts): HTMLButtonElement {
1035
1042
  return;
1036
1043
  }
1037
1044
  if (!popover) {
1038
- popover = createPopover(dashboardUrl, currentPopoverCss, () => {
1045
+ popover = createPopover(user, dashboardUrl, currentPopoverCss, () => {
1039
1046
  // Tear down our DOM before the auth flip runs so the popover
1040
1047
  // doesn't briefly show "signed out" state to a user who's
1041
1048
  // about to navigate away. closePopover() also removes the
@@ -1344,10 +1351,26 @@ function updateRing(
1344
1351
 
1345
1352
  function updateLED(led: HTMLSpanElement, snap: ActivitySnapshot): void {
1346
1353
  switch (snap.status) {
1347
- case "idle":
1348
- led.style.background = "rgba(255,255,255,0.2)";
1349
- led.style.boxShadow = "0 0 0 0 transparent";
1354
+ case "idle": {
1355
+ // Nothing in flight: the LED shows the sync instead — blue pulse
1356
+ // while syncing, amber while changes wait offline or after a
1357
+ // failed attempt, grey when everything is on the server.
1358
+ const sync = snap.sync;
1359
+ if (sync && sync.state === "syncing") {
1360
+ led.style.background = "#3b82f6";
1361
+ led.style.boxShadow = "0 0 0 0 rgba(59,130,246,0.7)";
1362
+ led.style.animation = "__runapps_led_pulse__ 1.2s ease-out infinite";
1363
+ } else if (sync && (sync.state === "offline" || sync.state === "error")) {
1364
+ led.style.background = "#f59e0b";
1365
+ led.style.boxShadow = "0 0 0 2px rgba(245,158,11,0.3)";
1366
+ led.style.animation = "";
1367
+ } else {
1368
+ led.style.background = "rgba(255,255,255,0.2)";
1369
+ led.style.boxShadow = "0 0 0 0 transparent";
1370
+ led.style.animation = "";
1371
+ }
1350
1372
  break;
1373
+ }
1351
1374
  case "active":
1352
1375
  led.style.background = "#3b82f6";
1353
1376
  // CSS-driven pulse via box-shadow ring expanding outward —
@@ -1363,7 +1386,7 @@ function updateLED(led: HTMLSpanElement, snap: ActivitySnapshot): void {
1363
1386
  }
1364
1387
  }
1365
1388
 
1366
- function createPopover(dashboardUrl: string, anchorCss: string, onSignOut: () => void): HTMLDivElement {
1389
+ function createPopover(user: BrowserUser, dashboardUrl: string, anchorCss: string, onSignOut: () => void): HTMLDivElement {
1367
1390
  const pop = document.createElement("div");
1368
1391
  pop.style.cssText = [
1369
1392
  "position:absolute",
@@ -1387,6 +1410,37 @@ function createPopover(dashboardUrl: string, anchorCss: string, onSignOut: () =>
1387
1410
  pop.setAttribute("data-runapps-popover", "1");
1388
1411
  pop.addEventListener("click", (e) => e.stopPropagation());
1389
1412
 
1413
+ // Who is signed in. The badge itself is only the avatar circle, so
1414
+ // the full name lives here, above the activity sections.
1415
+ const header = document.createElement("div");
1416
+ header.style.cssText = [
1417
+ "display:flex;align-items:center;gap:8px",
1418
+ "margin-bottom:10px;padding-bottom:8px",
1419
+ "border-bottom:1px solid rgba(255,255,255,0.08)",
1420
+ ].join(";");
1421
+ const headAvatar = document.createElement("div");
1422
+ headAvatar.textContent = (user.name || "?").charAt(0).toUpperCase();
1423
+ headAvatar.style.cssText = [
1424
+ "width:24px;height:24px;border-radius:50%;flex-shrink:0",
1425
+ "display:flex;align-items:center;justify-content:center",
1426
+ "background:linear-gradient(135deg,#3b82f6,#8b5cf6)",
1427
+ "font-size:11px;font-weight:600;color:#fff",
1428
+ ].join(";");
1429
+ const headName = document.createElement("div");
1430
+ headName.textContent = user.name || "Signed in";
1431
+ headName.title = user.name || "";
1432
+ headName.style.cssText = "font-size:12px;font-weight:500;color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap";
1433
+ const headSub = document.createElement("div");
1434
+ headSub.textContent = "Signed in with RunApps";
1435
+ headSub.style.cssText = "font-size:10px;color:rgba(255,255,255,0.5)";
1436
+ const headText = document.createElement("div");
1437
+ headText.style.cssText = "min-width:0";
1438
+ headText.appendChild(headName);
1439
+ headText.appendChild(headSub);
1440
+ header.appendChild(headAvatar);
1441
+ header.appendChild(headText);
1442
+ pop.appendChild(header);
1443
+
1390
1444
  // The popover's content is rebuilt on every redraw to keep DOM
1391
1445
  // diffing simple. ~3 sections × ~6 children = ~20 nodes, no
1392
1446
  // measurable cost at the 6 Hz redraw rate.
@@ -1448,9 +1502,42 @@ function updatePopover(pop: HTMLDivElement, snap: ActivitySnapshot): void {
1448
1502
  const now = Date.now();
1449
1503
  inner.appendChild(renderActiveSection(snap, now));
1450
1504
  inner.appendChild(renderRecentSection(snap, now));
1505
+ if (snap.sync) inner.appendChild(renderSyncSection(snap.sync, now));
1451
1506
  inner.appendChild(renderSessionSection(snap.session, now));
1452
1507
  }
1453
1508
 
1509
+ function renderSyncSection(sync: NonNullable<ActivitySnapshot["sync"]>, now: number): HTMLDivElement {
1510
+ const sec = document.createElement("div");
1511
+ sec.style.marginBottom = "10px";
1512
+ const hint = sync.lastSyncedAt ? `synced ${relativeTime(now - sync.lastSyncedAt)}` : "—";
1513
+ sec.appendChild(sectionLabel("Sync", hint));
1514
+ const row = document.createElement("div");
1515
+ row.style.cssText = "display:flex;justify-content:space-between;gap:8px;padding:3px 0;font-size:10px";
1516
+ const left = document.createElement("span");
1517
+ const dot = document.createElement("span");
1518
+ dot.textContent = "● ";
1519
+ const label: Record<string, [string, string]> = {
1520
+ off: ["Not signed in", "rgba(255,255,255,0.4)"],
1521
+ idle: ["Up to date", "#10b981"],
1522
+ syncing: ["Syncing…", "#3b82f6"],
1523
+ offline: ["Offline", "#f59e0b"],
1524
+ error: ["Retrying", "#f59e0b"],
1525
+ };
1526
+ const [text, color] = label[sync.state] ?? ["", "#fff"];
1527
+ dot.style.color = color;
1528
+ left.style.color = "#fff";
1529
+ left.appendChild(dot);
1530
+ left.appendChild(document.createTextNode(text));
1531
+ const right = document.createElement("span");
1532
+ right.style.cssText = "color:rgba(255,255,255,0.7);font-variant-numeric:tabular-nums";
1533
+ right.textContent = sync.pending > 0 ? `${sync.pending} pending` : "";
1534
+ right.title = sync.error ?? "";
1535
+ row.appendChild(left);
1536
+ row.appendChild(right);
1537
+ sec.appendChild(row);
1538
+ return sec;
1539
+ }
1540
+
1454
1541
  function renderActiveSection(snap: ActivitySnapshot, now: number): HTMLDivElement {
1455
1542
  const sec = document.createElement("div");
1456
1543
  sec.style.marginBottom = "10px";