The Coline design system: accessible React components for Coline Apps, themed live by the host workspace, and for Coline Sites in light and dark. Tailwind v4 stylesheet included. MIT.
| type ColineRecordQuery, |
| 6 | type LiveCollectionOptions, |
| 7 | } from "@colineapp/sdk/v2"; |
| 8 | import { useColine, useColineContext } from "./provider"; |
| 9 |
| 10 | /** Inline query objects are safe: equivalent inputs retain the same live view. */ |
| 11 | export function useLiveCollection<T extends Record<string, unknown>>( |
| 12 | name: string, |
| 13 | query?: ColineRecordQuery<T>, |
| 14 | options?: LiveCollectionOptions, |
| 15 | ) { |
| 16 | const coline = useColine(); |
| 17 | const context = useColineContext(); |
| 18 | const key = JSON.stringify({ |
| 19 | query, |
| 20 | options: { actorUserId: context.actor?.userId, installId: context.app.installId, ...options }, |
| 21 | }); |
| 22 | const live = React.useMemo(() => { |
| 23 | const input = JSON.parse(key) as { |
| 24 | query?: ColineRecordQuery<T>; |
| 25 | options?: LiveCollectionOptions; |
| 26 | }; |
| 27 | return createLiveCollection<T>(coline, name, input.query, input.options); |
| 28 | }, [coline, name, key]); |
| 29 | React.useEffect(() => { |
| 30 | void live.start(); |
| 31 | return () => live.stop(); |
| 32 | }, [live]); |
| 33 | const snapshot = React.useSyncExternalStore(live.subscribe, live.getSnapshot, live.getSnapshot); |
| 34 | return { |
| 35 | ...snapshot, |
| 36 | insert: live.insert, |
| 37 | update: live.update, |
| 38 | delete: live.delete, |
| 39 | setAccess: live.setAccess, |
| 40 | refresh: live.refresh, |
| 41 | }; |
| 42 | } |
| 43 |