mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Document watch history v2 pipeline
This commit is contained in:
1 parent
02bd23ccaf
commit
09fc89bda6
2 files changed
+83
-5
No files matched your search
@@ -49,8 +49,8 @@ read/write split.
|
||||
| NIP-94 mirror (`NOTE_TYPES.VIDEO_MIRROR`) | `1063` | Tags forwarded from `publishVideo` (URL, mime type, thumbnail, alt text, magnet) | Plain text alt description |
|
||||
| Relay list (`NOTE_TYPES.RELAY_LIST`) | `10002` | Repeating `['r', <relay url>]` tags, optionally with a marker of `'read'` or `'write'` to scope the relay; marker omitted for read/write relays | Empty content |
|
||||
| View counter (`NOTE_TYPES.VIEW_EVENT`) | `WATCH_HISTORY_KIND` (default `30079`, clients also read legacy `30078`) | Canonical tag set: `['t','view']`, a pointer tag (`['e', <eventId>]` or `['a', <address>]`), and a stable dedupe tag `['d', <view identifier>]`, with optional `['session','true']` when a session actor signs; schema overrides may append extra tags. `['video', ...]` is supported for legacy overrides only. | Optional plaintext message |
|
||||
| Watch history index (`NOTE_TYPES.WATCH_HISTORY_INDEX`, legacy) | `WATCH_HISTORY_KIND` (default `30079`, clients also read legacy `30078`) | `['d', WATCH_HISTORY_LIST_IDENTIFIER]`, `['snapshot', <id>]`, `['chunks', <total>]`, repeated `['a', <address>]` pointers to each chunk event plus schema append tags | JSON payload `{ snapshot, totalChunks }` |
|
||||
| Watch history chunk (`NOTE_TYPES.WATCH_HISTORY_CHUNK`, legacy) | `WATCH_HISTORY_KIND` (default `30079`, clients also read legacy `30078`) | `['d', <chunk identifier>]`, `['encrypted','nip04']`, `['snapshot', <id>]`, `['chunk', <index>, <total>]`, pointer tags for each entry, plus schema append tags | NIP-04 encrypted JSON chunk (`{ version, snapshot, chunkIndex, totalChunks, items[] }`) |
|
||||
| Watch history index (`NOTE_TYPES.WATCH_HISTORY_INDEX`) | `WATCH_HISTORY_KIND` (default `30079`, clients also read legacy `30078`) | `['d', WATCH_HISTORY_LIST_IDENTIFIER]`, `['snapshot', <id>]`, `['chunks', <total>]`, repeated `['a', <chunk address>]` pointers plus schema append tags | JSON payload `{ snapshot, totalChunks }` (may be empty when using tags only) |
|
||||
| Watch history chunk (`NOTE_TYPES.WATCH_HISTORY_CHUNK`) | `WATCH_HISTORY_KIND` (default `30079`, clients also read legacy `30078`) | `['d', <snapshotId:index>]`, `['encrypted','nip04']`, `['snapshot', <id>]`, `['chunk', <index>, <total>]`, optional leading `['head','1']` on the first chunk, pointer tags for each item, plus schema append tags | NIP-04 encrypted JSON chunk (`{ version, snapshot, chunkIndex, totalChunks, items[] }`) |
|
||||
| Subscription list (`NOTE_TYPES.SUBSCRIPTION_LIST`) | `30002` | `['d', 'subscriptions']` | NIP-04 encrypted JSON `{ subPubkeys: string[] }` |
|
||||
| User block list (`NOTE_TYPES.USER_BLOCK_LIST`) | `30002` | `['d', 'user-blocks']` | NIP-04 encrypted JSON `{ blockedPubkeys: string[] }` |
|
||||
| Admin moderation list (`NOTE_TYPES.ADMIN_MODERATION_LIST`) | `30000` | `['d', 'bitvid:admin:editors']`, repeated `['p', <pubkey>]` entries | Empty content |
|
||||
@@ -63,4 +63,21 @@ builders inherit the same debugging knobs.
|
||||
|
||||
### Watch history identifiers
|
||||
|
||||
The watch history publishing pipeline has been retired. These identifiers remain documented so existing relays can keep serving legacy payloads, but new clients no longer emit or refresh watch-history events.
|
||||
The encrypted watch history pipeline is gated by the `FEATURE_WATCH_HISTORY_V2`
|
||||
runtime flag. When the flag is disabled, clients continue emitting view events
|
||||
but skip publishing snapshots; the UI still resolves legacy `watch-history:v2:index`
|
||||
lists so operators can stage the rollout per deployment.【F:config/instance-config.js†L69-L94】【F:js/watchHistoryService.js†L82-L140】【F:js/watchHistoryService.js†L948-L985】
|
||||
|
||||
Active identifiers include the default `WATCH_HISTORY_LIST_IDENTIFIER`
|
||||
(`"watch-history"`) and the legacy aliases enumerated in
|
||||
`WATCH_HISTORY_LEGACY_LIST_IDENTIFIERS`. Chunk events derive their `d` tag from
|
||||
`<snapshotId>:<index>`, advertise `['snapshot', <id>]`, and carry `['chunk', <index>, <total>]`
|
||||
plus an optional leading `['head','1']` marker so relays can prioritize the first
|
||||
ciphertext. All chunk content is encrypted with NIP-04 and stores only pointer
|
||||
entries; richer metadata remains on-device via the
|
||||
[`WatchHistoryService`](../js/watchHistoryService.js) APIs, which default to
|
||||
pointer-only writes and local-only metadata caches.【F:config/instance-config.js†L60-L78】【F:js/nostrEventSchemas.js†L157-L189】【F:js/nostr.js†L2329-L2369】【F:js/watchHistoryService.js†L331-L376】
|
||||
|
||||
Refer to the [`WatchHistoryService`](../js/watchHistoryService.js) for queue
|
||||
management hooks, manual snapshot helpers, and metadata toggle controls that
|
||||
complement these schema definitions.【F:js/watchHistoryService.js†L695-L776】【F:js/watchHistoryService.js†L1040-L1093】
|
||||
@@ -1,3 +1,64 @@
|
||||
# Watch History Logging Cheatsheet
|
||||
# Watch history logging (v2 pipeline)
|
||||
|
||||
The legacy watch history publisher has been removed. Clients no longer emit watch-history snapshot events, and related console logs have been retired alongside the feature.
|
||||
BitVid's watch history sync is orchestrated by the
|
||||
[`WatchHistoryService`](../js/watchHistoryService.js). The service collects
|
||||
per-video pointer data during playback, batches it in session storage, and emits
|
||||
encrypted snapshots to relays only when a publish is triggered. Relay payloads
|
||||
stick to pointer identifiers so title, thumbnail, and profile context remain on
|
||||
the client unless an operator opts into local metadata caching.
|
||||
|
||||
## Snapshot composition
|
||||
|
||||
Snapshots publish two event types to the shared `WATCH_HISTORY_KIND` stream:
|
||||
|
||||
1. **Chunk events** — Each chunk carries a deterministic identifier in its
|
||||
`d` tag, advertises its `snapshot` and `chunk` position, and is tagged with
|
||||
`['encrypted','nip04']`. The first chunk is additionally marked as
|
||||
`['head','1']` and may append `"a"` tags that reference previous chunk
|
||||
addresses, allowing readers to reconstruct the full set even when relays
|
||||
deduplicate aggressively.【F:js/nostrEventSchemas.js†L175-L189】【F:js/nostr.js†L2329-L2369】
|
||||
2. **Pointer event** — After chunks are accepted, BitVid emits a compact index
|
||||
event containing the canonical list identifier (`['d', WATCH_HISTORY_LIST_IDENTIFIER]`),
|
||||
the `snapshot` label, the total chunk count, and an `a` tag for each chunk
|
||||
address.【F:js/nostrEventSchemas.js†L157-L170】【F:js/nostr.js†L2425-L2441】
|
||||
|
||||
Chunk content is a NIP-04 encrypted JSON envelope of `{ version: 2, snapshot,
|
||||
chunkIndex, totalChunks, items[] }`. Items are pointer descriptors (`e` or `a`
|
||||
references plus optional relay hints) so that relays never learn which titles
|
||||
were played—only which events or addresses the client can dereference later.【F:js/nostr.js†L2337-L2364】
|
||||
|
||||
## Snapshot cadence
|
||||
|
||||
`WatchHistoryService.publishView` queues pointer entries while the feature flag
|
||||
is enabled, merging repeats with a one-minute throttle and persisting the queue
|
||||
in `sessionStorage`. Snapshots run when `watchHistoryService.snapshot()` is
|
||||
invoked (e.g., on `beforeunload`, `visibilitychange`, or manual sync actions in
|
||||
the history UI) and clear the queue on success.【F:js/watchHistoryService.js†L872-L917】【F:js/app.js†L6041-L6081】【F:js/app.js†L7467-L7484】
|
||||
If no items are pending, the snapshot resolves with an empty result so UI calls
|
||||
remain idempotent.【F:js/watchHistoryService.js†L932-L944】
|
||||
|
||||
## Republish and backoff
|
||||
|
||||
When a snapshot publish fails but the response is retryable, the service stores
|
||||
the returned `snapshotId`, records the originating reason, and delegates to the
|
||||
Nostr client to retry with exponential backoff. Retries start after two seconds,
|
||||
double per attempt with 25% jitter, cap at five minutes, and stop after eight
|
||||
attempts unless a publish succeeds sooner.【F:js/watchHistoryService.js†L948-L985】【F:js/watchHistoryService.js†L723-L777】【F:js/nostr.js†L1988-L2087】
|
||||
|
||||
## Legacy payload handling
|
||||
|
||||
Readers hydrate history by combining the pointer event, any encrypted chunks,
|
||||
and fallback metadata embedded in legacy watch-history lists. The resolver still
|
||||
accepts the `watch-history:v2:index` identifier, merges pointer tags from the
|
||||
index event, and falls back to plaintext content when decryption fails so older
|
||||
relays remain compatible.【F:config/instance-config.js†L60-L78】【F:js/nostr.js†L2704-L2779】【F:js/nostr.js†L5216-L5264】
|
||||
|
||||
## Local metadata toggles
|
||||
|
||||
By default the service only persists pointer data to relays; richer metadata is
|
||||
stored locally (and opt-in). Users can toggle the "store watch history metadata"
|
||||
preference, which flips a localStorage flag, clears cached entries when
|
||||
disabled, and never pushes the sanitized video/profile cache over the network.【F:js/watchHistoryService.js†L82-L140】【F:js/watchHistoryService.js†L232-L313】【F:js/watchHistoryService.js†L331-L376】
|
||||
|
||||
See the [`WatchHistoryService` API](../js/watchHistoryService.js) for
|
||||
event hooks, queue inspection helpers, and manual snapshot controls.
|
||||
Reference in new issue
Block a user