/** * rTube Automerge document schemas. * * Syncs shared playlists and watch party state across space members. * Actual video files remain on R2/S3; this doc manages collaborative * curation and viewing sessions. * * DocId format: {space}:tube:playlists */ import type { DocSchema } from '../../shared/local-first/document'; // ── Document types ── export interface PlaylistEntry { videoName: string; addedBy: string | null; addedAt: number; } export interface Playlist { id: string; name: string; entries: PlaylistEntry[]; createdBy: string | null; createdAt: number; } export interface WatchParty { videoName: string; startedBy: string | null; startedAt: number; /** Playback position in seconds */ position: number; playing: boolean; } export interface TubeDoc { meta: { module: string; collection: string; version: number; spaceSlug: string; createdAt: number; }; playlists: Record; watchParty: WatchParty | null; } // ── Schema registration ── export const tubeSchema: DocSchema = { module: 'tube', collection: 'playlists', version: 1, init: (): TubeDoc => ({ meta: { module: 'tube', collection: 'playlists', version: 1, spaceSlug: '', createdAt: Date.now(), }, playlists: {}, watchParty: null, }), migrate: (doc: any, _fromVersion: number) => { if (!doc.playlists) doc.playlists = {}; if (!('watchParty' in doc)) doc.watchParty = null; doc.meta.version = 1; return doc; }, }; // ── Helpers ── export function tubeDocId(space: string) { return `${space}:tube:playlists` as const; }