import React from "react"; import * as Y from "yjs"; import type { NoteId } from "~/lib/metadata"; import { useYDoc } from "./use-ydoc"; import type { WebsocketProvider } from "y-websocket"; import type { IndexeddbPersistence } from "y-indexeddb"; const NoteContext = React.createContext<{ doc: Y.Doc, providers: { indexeddb: IndexeddbPersistence, websocket: WebsocketProvider, } } | null>(null); export function NoteProvider(props: { children: React.ReactNode, id: NoteId }) { const { ydoc, indexeddbProvider, websocketProvider } = useYDoc(`note-${props.id}`); // If we don't have the provider yet, delay rendering until we do. if (!indexeddbProvider || !websocketProvider) { return null; } return ( {props.children} ); } export function useNoteDoc() { const ctx = React.useContext(NoteContext); if (!ctx) { throw new Error("useNoteDoc must be used within a NoteProvider") } return ctx.doc; } export function useNoteMap(name: string) { const ctx = React.useContext(NoteContext); if (!ctx) { throw new Error("useNoteMap must be used within a NoteProvider") } const map = ctx.doc.getMap(name); return map; } export function useNoteArray(name: string) { const ctx = React.useContext(NoteContext); if (!ctx) { throw new Error("useNoteArray must be used within a NoteProvider") } const array = ctx.doc.getArray(name); return array; } export function useNoteProviders() { const ctx = React.useContext(NoteContext); if (!ctx) { throw new Error("useNoteProviders must be used within a NoteProvider") } return ctx.providers; } export function useNoteAwareness() { const ctx = React.useContext(NoteContext); if (!ctx) { throw new Error("useNoteAwareness must be used within a NoteProvider") } const awareness = ctx.providers.websocket.awareness; return awareness; }