@@ -0,0 +1,46 @@
|
||||
"use client"
|
||||
|
||||
// The project's notes, live (umbrella TS6.4 and TS6.6): the page's view renders the first page and hands it
|
||||
// over as the seed, so the page arrives complete; this keeps it current through the organization's live stream
|
||||
// -- a note another member adds, renames or deletes appears without a reload. The rows come from
|
||||
// `notes.note.getMany`, under the same permission as the list, so the stream itself never carries a note's
|
||||
// contents.
|
||||
|
||||
import type { ProjectSlugs } from "@conusai-kit/ui"
|
||||
import { liveCollection, useDataClient, useLive } from "@conusai-kit/ui/data"
|
||||
// Its live sync stops when no live query reads it any more (TanStack DB's collection GC).
|
||||
import { useState } from "react"
|
||||
import { NOTE_COLLECTION, type NoteView } from "../contract/index.js"
|
||||
|
||||
export function useLiveNotes(slugs: ProjectSlugs, seed: readonly NoteView[]): readonly NoteView[] {
|
||||
const client = useDataClient()
|
||||
// One collection for the life of the page: a page of another project mounts its own, and the seed is the
|
||||
// first render's.
|
||||
const [notes] = useState(() =>
|
||||
liveCollection<NoteView>({
|
||||
client,
|
||||
org: slugs.org,
|
||||
topic: { ws: slugs.workspace, project: slugs.project },
|
||||
entity: NOTE_COLLECTION.entity,
|
||||
key: NOTE_COLLECTION.key,
|
||||
version: "version",
|
||||
seed,
|
||||
list: {
|
||||
procedure: NOTE_COLLECTION.list,
|
||||
input: { ...slugs },
|
||||
rows: (out) => (out as { notes: NoteView[] }).notes,
|
||||
},
|
||||
getMany: {
|
||||
procedure: NOTE_COLLECTION.getMany,
|
||||
input: { ...slugs },
|
||||
rows: (out) => (out as { items: NoteView[] }).items,
|
||||
},
|
||||
}),
|
||||
)
|
||||
// Newest first, as the list procedure orders them, through the query operators (umbrella §7.2).
|
||||
const { data, isReady } = useLive(notes, (q, rows) =>
|
||||
q.from({ note: rows }).orderBy(({ note }: { note: NoteView }) => note.createdAt, "desc"),
|
||||
)
|
||||
// Until the collection is ready the server's rows are the answer, so the first paint matches it.
|
||||
return isReady ? data : seed
|
||||
}
|
||||
Reference in New Issue
Block a user