@fireproof/core 0.20.1 → 0.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fireproof/core",
3
- "version": "0.20.1",
3
+ "version": "0.20.2",
4
4
  "description": "Live ledger for the web.",
5
5
  "type": "module",
6
6
  "module": "./index.js",
package/react/index.cjs CHANGED
@@ -157,24 +157,18 @@ function createUseDocument(database) {
157
157
  var import_react2 = require("react");
158
158
  function createUseLiveQuery(database) {
159
159
  return function useLiveQuery(mapFn, query = {}, initialRows = []) {
160
- const [result, setResult] = (0, import_react2.useState)(() => {
161
- const docs = initialRows.map((r) => r.doc).filter((r) => !!r);
162
- return Object.assign(docs, {
163
- docs,
164
- rows: initialRows
165
- });
160
+ const [result, setResult] = (0, import_react2.useState)({
161
+ docs: initialRows.map((r) => r.doc).filter((r) => !!r),
162
+ rows: initialRows
166
163
  });
167
164
  const queryString = (0, import_react2.useMemo)(() => JSON.stringify(query), [query]);
168
165
  const mapFnString = (0, import_react2.useMemo)(() => mapFn.toString(), [mapFn]);
169
166
  const refreshRows = (0, import_react2.useCallback)(async () => {
170
167
  const res = await database.query(mapFn, query);
171
- const docs = res.rows.map((r) => r.doc).filter((r) => !!r);
172
- setResult(
173
- Object.assign(docs, {
174
- docs,
175
- rows: res.rows
176
- })
177
- );
168
+ setResult({
169
+ docs: res.rows.map((r) => r.doc).filter((r) => !!r),
170
+ rows: res.rows
171
+ });
178
172
  }, [database, mapFnString, queryString]);
179
173
  (0, import_react2.useEffect)(() => {
180
174
  refreshRows();
@@ -197,12 +191,18 @@ function createUseAllDocs(database) {
197
191
  const queryString = (0, import_react3.useMemo)(() => JSON.stringify(query), [query]);
198
192
  const refreshRows = (0, import_react3.useCallback)(async () => {
199
193
  const res = await database.allDocs(query);
200
- setResult({ ...res, docs: res.rows.map((r) => r.value) });
201
- }, [queryString]);
194
+ setResult({
195
+ ...res,
196
+ docs: res.rows.map((r) => r.value)
197
+ });
198
+ }, [database, queryString]);
202
199
  (0, import_react3.useEffect)(() => {
203
200
  refreshRows();
204
- return database.subscribe(refreshRows);
205
- }, [refreshRows]);
201
+ const unsubscribe = database.subscribe(refreshRows);
202
+ return () => {
203
+ unsubscribe();
204
+ };
205
+ }, [database, refreshRows]);
206
206
  return result;
207
207
  };
208
208
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/react/index.ts","../../../src/react/use-fireproof.ts","../../../src/react/use-document.ts","../../../src/react/utils.ts","../../../src/react/use-live-query.ts","../../../src/react/use-all-docs.ts","../../../src/react/use-changes.ts","../../../src/react/img-file.ts"],"sourcesContent":["export { FireproofCtx, useFireproof } from \"./use-fireproof.js\";\nexport * from \"./types.js\";\nexport * from \"./img-file.js\";\n","import type { ConfigOpts, Database } from \"@fireproof/core\";\nimport { fireproof } from \"@fireproof/core\";\nimport { useMemo } from \"react\";\nimport type { UseFireproof } from \"./types.js\";\nimport { createUseDocument } from \"./use-document.js\";\nimport { createUseLiveQuery } from \"./use-live-query.js\";\nimport { createUseAllDocs } from \"./use-all-docs.js\";\nimport { createUseChanges } from \"./use-changes.js\";\n\n/**\n * @deprecated Use the `useFireproof` hook instead\n */\nexport const FireproofCtx = {} as UseFireproof;\n\n/**\n *\n * ## Summary\n *\n * React hook to create a custom-named Fireproof database and provides the utility hooks to query against it.\n *\n * ## Usage\n * ```tsx\n * const { database, useLiveQuery, useDocument } = useFireproof(\"dbname\");\n * const { database, useLiveQuery, useDocument } = useFireproof(\"dbname\", { ...options });\n * ```\n *\n *\n */\nexport function useFireproof(name: string | Database = \"useFireproof\", config: ConfigOpts = {}): UseFireproof {\n // Use useMemo to ensure stable references across renders\n return useMemo(() => {\n const database = typeof name === \"string\" ? fireproof(name, config) : name;\n\n const useDocument = createUseDocument(database);\n const useLiveQuery = createUseLiveQuery(database);\n const useAllDocs = createUseAllDocs(database);\n const useChanges = createUseChanges(database);\n\n return { database, useLiveQuery, useDocument, useAllDocs, useChanges };\n }, [name, JSON.stringify(config)]); // Only recreate if name or stringified config changes\n}\n\n// Export types\nexport type {\n LiveQueryResult,\n UseDocumentResult,\n AllDocsResult,\n ChangesResult,\n UseDocument,\n UseLiveQuery,\n UseAllDocs,\n UseChanges,\n UseFireproof,\n} from \"./types.js\";\n","import { useCallback, useEffect, useMemo, useState, useRef } from \"react\";\nimport type { DocSet, DocTypes, DocWithId, Database } from \"@fireproof/core\";\nimport { deepClone } from \"./utils.js\";\nimport type { DeleteDocFn, StoreDocFn, UseDocumentInitialDocOrFn, UseDocumentResult } from \"./types.js\";\n\n/**\n * Implementation of the useDocument hook\n */\nexport function createUseDocument(database: Database) {\n return function useDocument<T extends DocTypes>(initialDocOrFn?: UseDocumentInitialDocOrFn<T>): UseDocumentResult<T> {\n const updateHappenedRef = useRef(false);\n let initialDoc: DocSet<T>;\n if (typeof initialDocOrFn === \"function\") {\n initialDoc = initialDocOrFn();\n } else {\n initialDoc = initialDocOrFn ?? ({} as T);\n }\n\n const originalInitialDoc = useMemo(() => deepClone({ ...initialDoc }), []);\n\n const [doc, setDoc] = useState(initialDoc);\n\n const refresh = useCallback(async () => {\n const gotDoc = doc._id ? await database.get<T>(doc._id).catch(() => initialDoc) : initialDoc;\n setDoc(gotDoc);\n }, [doc._id]);\n\n const save: StoreDocFn<T> = useCallback(\n async (existingDoc) => {\n updateHappenedRef.current = false;\n const toSave = existingDoc ?? doc;\n const res = await database.put(toSave);\n\n if (!updateHappenedRef.current && !doc._id && !existingDoc) {\n setDoc((d) => ({ ...d, _id: res.id }));\n }\n\n return res;\n },\n [doc],\n );\n\n const remove: DeleteDocFn<T> = useCallback(\n async (existingDoc) => {\n const id = existingDoc?._id ?? doc._id;\n if (!id) throw database.logger.Error().Msg(`Document must have an _id to be removed`).AsError();\n const gotDoc = await database.get<T>(id).catch(() => undefined);\n if (!gotDoc) throw database.logger.Error().Str(\"id\", id).Msg(`Document not found`).AsError();\n const res = await database.del(id);\n setDoc(initialDoc);\n return res;\n },\n [doc, initialDoc],\n );\n\n // New granular update methods\n const merge = useCallback((newDoc: Partial<T>) => {\n updateHappenedRef.current = true;\n setDoc((prev) => ({ ...prev, ...newDoc }));\n }, []);\n\n const replace = useCallback((newDoc: T) => {\n updateHappenedRef.current = true;\n setDoc(newDoc);\n }, []);\n\n const reset = useCallback(() => {\n updateHappenedRef.current = true;\n setDoc({ ...originalInitialDoc });\n }, [originalInitialDoc]);\n\n // Legacy-compatible updateDoc\n const updateDoc = useCallback(\n (newDoc?: DocSet<T>, opts = { replace: false, reset: false }) => {\n if (!newDoc) {\n return opts.reset ? reset() : refresh();\n }\n return opts.replace ? replace(newDoc as T) : merge(newDoc);\n },\n [refresh, reset, replace, merge],\n );\n\n useEffect(() => {\n if (!doc._id) return;\n return database.subscribe((changes) => {\n if (updateHappenedRef.current) {\n return;\n }\n if (changes.find((c) => c._id === doc._id)) {\n void refresh();\n }\n }, true);\n }, [doc._id, refresh]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const submit = useCallback(\n async (e?: Event) => {\n if (e?.preventDefault) e.preventDefault();\n await save();\n reset();\n },\n [save, reset],\n );\n\n // Primary Object API with both new and legacy methods\n const apiObject = {\n doc: { ...doc } as DocWithId<T>,\n merge,\n replace,\n reset,\n refresh,\n save,\n remove,\n submit,\n };\n\n // Make the object properly iterable\n const tuple = [{ ...doc }, updateDoc, save, remove, reset, refresh];\n Object.assign(apiObject, tuple);\n Object.defineProperty(apiObject, Symbol.iterator, {\n enumerable: false,\n value: function* () {\n yield* tuple;\n },\n });\n\n return apiObject as UseDocumentResult<T>;\n };\n}\n","/**\n * Deep clone a value\n */\nexport function deepClone<T>(value: T): T {\n return (structuredClone ?? ((v: T) => JSON.parse(JSON.stringify(v))))(value);\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { DocFragment, DocTypes, DocWithId, IndexKeyType, IndexRow, MapFn, Database } from \"@fireproof/core\";\nimport type { LiveQueryResult } from \"./types.js\";\n\n// Internal shadow type for array-like behavior (implementation detail)\ntype EnhancedQueryResult<T extends DocTypes, K extends IndexKeyType, R extends DocFragment = T> = LiveQueryResult<T, K, R> &\n DocWithId<T>[];\n\n/**\n * Implementation of the useLiveQuery hook\n */\nexport function createUseLiveQuery(database: Database) {\n return function useLiveQuery<T extends DocTypes, K extends IndexKeyType = string, R extends DocFragment = T>(\n mapFn: MapFn<T> | string,\n query = {},\n initialRows: IndexRow<K, T, R>[] = [],\n ): LiveQueryResult<T, K, R> {\n const [result, setResult] = useState<EnhancedQueryResult<T, K, R>>(() => {\n const docs = initialRows.map((r) => r.doc).filter((r): r is DocWithId<T> => !!r);\n return Object.assign(docs, {\n docs,\n rows: initialRows,\n });\n });\n\n const queryString = useMemo(() => JSON.stringify(query), [query]);\n const mapFnString = useMemo(() => mapFn.toString(), [mapFn]);\n\n const refreshRows = useCallback(async () => {\n const res = await database.query<K, T, R>(mapFn, query);\n const docs = res.rows.map((r) => r.doc).filter((r): r is DocWithId<T> => !!r);\n setResult(\n Object.assign(docs, {\n docs,\n rows: res.rows,\n }),\n );\n }, [database, mapFnString, queryString]);\n\n useEffect(() => {\n refreshRows();\n const unsubscribe = database.subscribe(refreshRows);\n return () => {\n unsubscribe();\n };\n }, [database, refreshRows]);\n\n return result;\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { AllDocsQueryOpts, DocTypes, DocWithId, Database } from \"@fireproof/core\";\nimport type { AllDocsResult } from \"./types.js\";\n\n/**\n * Implementation of the useAllDocs hook\n */\nexport function createUseAllDocs(database: Database) {\n return function useAllDocs<T extends DocTypes>(query: AllDocsQueryOpts = {}): AllDocsResult<T> {\n const [result, setResult] = useState<AllDocsResult<T>>({\n docs: [],\n });\n\n const queryString = useMemo(() => JSON.stringify(query), [query]);\n\n const refreshRows = useCallback(async () => {\n const res = await database.allDocs<T>(query);\n setResult({ ...res, docs: res.rows.map((r) => r.value as DocWithId<T>) });\n }, [queryString]);\n\n useEffect(() => {\n refreshRows(); // Initial data fetch\n return database.subscribe(refreshRows);\n }, [refreshRows]);\n\n return result;\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { ChangesOptions, ClockHead, DocTypes, DocWithId, Database } from \"@fireproof/core\";\nimport type { ChangesResult } from \"./types.js\";\n\n/**\n * Implementation of the useChanges hook\n */\nexport function createUseChanges(database: Database) {\n return function useChanges<T extends DocTypes>(since: ClockHead = [], opts: ChangesOptions = {}): ChangesResult<T> {\n const [result, setResult] = useState<ChangesResult<T>>({\n docs: [],\n });\n\n const queryString = useMemo(() => JSON.stringify(opts), [opts]);\n\n const refreshRows = useCallback(async () => {\n const res = await database.changes<T>(since, opts);\n setResult({ ...res, docs: res.rows.map((r) => r.value as DocWithId<T>) });\n }, [since, queryString]);\n\n useEffect(() => {\n refreshRows(); // Initial data fetch\n return database.subscribe(refreshRows);\n }, [refreshRows]);\n\n return result;\n };\n}\n","import { DocFileMeta } from \"@fireproof/core\";\nimport React, { useState, useEffect, ImgHTMLAttributes } from \"react\";\n\nconst { URL } = globalThis;\n\n// Union type to support both direct File objects and metadata objects\ntype FileType = File | DocFileMeta;\n\ninterface ImgFileProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, \"src\"> {\n file?: FileType;\n /**\n * @deprecated Use 'file' instead. This is for internal use only to support legacy code.\n * @internal\n */\n meta?: FileType;\n}\n\n// Helper function to determine if the object is a File-like object\nfunction isFile(obj: FileType): obj is File {\n return \"type\" in obj && \"size\" in obj && \"stream\" in obj && typeof obj.stream === \"function\";\n}\n\n// Helper function to determine if the object is a DocFileMeta\nfunction isFileMeta(obj: FileType): obj is DocFileMeta {\n return \"type\" in obj && \"size\" in obj && \"file\" in obj && typeof obj.file === \"function\";\n}\n\nexport function ImgFile({ file, meta, ...imgProps }: ImgFileProps) {\n const [imgDataUrl, setImgDataUrl] = useState(\"\");\n\n // Use meta as fallback if file is not provided (for backward compatibility)\n const fileData = file || meta;\n\n useEffect(() => {\n if (!fileData) return;\n\n const loadFile = async () => {\n let fileObj: File | null = null;\n let fileType = \"\";\n\n switch (true) {\n case isFile(fileData):\n fileObj = fileData;\n fileType = fileData.type;\n break;\n case isFileMeta(fileData):\n fileType = fileData.type;\n fileObj = (await fileData.file?.()) || null;\n break;\n }\n\n if (fileObj && /image/.test(fileType)) {\n const src = URL.createObjectURL(fileObj);\n setImgDataUrl(src);\n return () => URL.revokeObjectURL(src);\n }\n };\n\n let isMounted = true;\n let cleanup: (() => void) | undefined;\n\n loadFile().then((result) => {\n if (isMounted) {\n cleanup = result;\n } else if (result) {\n result();\n }\n });\n\n return () => {\n isMounted = false;\n if (cleanup) cleanup();\n };\n }, [fileData]);\n\n return imgDataUrl\n ? React.createElement(\"img\", {\n src: imgDataUrl,\n ...imgProps,\n })\n : null;\n}\n\nexport default ImgFile;\n"],"mappings":"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","names":["import_react","import_react","import_react","import_react","import_react","React"]}
1
+ {"version":3,"sources":["../../../src/react/index.ts","../../../src/react/use-fireproof.ts","../../../src/react/use-document.ts","../../../src/react/utils.ts","../../../src/react/use-live-query.ts","../../../src/react/use-all-docs.ts","../../../src/react/use-changes.ts","../../../src/react/img-file.ts"],"sourcesContent":["export { FireproofCtx, useFireproof } from \"./use-fireproof.js\";\nexport * from \"./types.js\";\nexport * from \"./img-file.js\";\n","import type { ConfigOpts, Database } from \"@fireproof/core\";\nimport { fireproof } from \"@fireproof/core\";\nimport { useMemo } from \"react\";\nimport type { UseFireproof } from \"./types.js\";\nimport { createUseDocument } from \"./use-document.js\";\nimport { createUseLiveQuery } from \"./use-live-query.js\";\nimport { createUseAllDocs } from \"./use-all-docs.js\";\nimport { createUseChanges } from \"./use-changes.js\";\n\n/**\n * @deprecated Use the `useFireproof` hook instead\n */\nexport const FireproofCtx = {} as UseFireproof;\n\n/**\n *\n * ## Summary\n *\n * React hook to create a custom-named Fireproof database and provides the utility hooks to query against it.\n *\n * ## Usage\n * ```tsx\n * const { database, useLiveQuery, useDocument } = useFireproof(\"dbname\");\n * const { database, useLiveQuery, useDocument } = useFireproof(\"dbname\", { ...options });\n * ```\n *\n *\n */\nexport function useFireproof(name: string | Database = \"useFireproof\", config: ConfigOpts = {}): UseFireproof {\n // Use useMemo to ensure stable references across renders\n return useMemo(() => {\n const database = typeof name === \"string\" ? fireproof(name, config) : name;\n\n const useDocument = createUseDocument(database);\n const useLiveQuery = createUseLiveQuery(database);\n const useAllDocs = createUseAllDocs(database);\n const useChanges = createUseChanges(database);\n\n return { database, useLiveQuery, useDocument, useAllDocs, useChanges };\n }, [name, JSON.stringify(config)]); // Only recreate if name or stringified config changes\n}\n\n// Export types\nexport type {\n LiveQueryResult,\n UseDocumentResult,\n AllDocsResult,\n ChangesResult,\n UseDocument,\n UseLiveQuery,\n UseAllDocs,\n UseChanges,\n UseFireproof,\n} from \"./types.js\";\n","import { useCallback, useEffect, useMemo, useState, useRef } from \"react\";\nimport type { DocSet, DocTypes, DocWithId, Database } from \"@fireproof/core\";\nimport { deepClone } from \"./utils.js\";\nimport type { DeleteDocFn, StoreDocFn, UseDocumentInitialDocOrFn, UseDocumentResult } from \"./types.js\";\n\n/**\n * Implementation of the useDocument hook\n */\nexport function createUseDocument(database: Database) {\n return function useDocument<T extends DocTypes>(initialDocOrFn?: UseDocumentInitialDocOrFn<T>): UseDocumentResult<T> {\n const updateHappenedRef = useRef(false);\n let initialDoc: DocSet<T>;\n if (typeof initialDocOrFn === \"function\") {\n initialDoc = initialDocOrFn();\n } else {\n initialDoc = initialDocOrFn ?? ({} as T);\n }\n\n const originalInitialDoc = useMemo(() => deepClone({ ...initialDoc }), []);\n\n const [doc, setDoc] = useState(initialDoc);\n\n const refresh = useCallback(async () => {\n const gotDoc = doc._id ? await database.get<T>(doc._id).catch(() => initialDoc) : initialDoc;\n setDoc(gotDoc);\n }, [doc._id]);\n\n const save: StoreDocFn<T> = useCallback(\n async (existingDoc) => {\n updateHappenedRef.current = false;\n const toSave = existingDoc ?? doc;\n const res = await database.put(toSave);\n\n if (!updateHappenedRef.current && !doc._id && !existingDoc) {\n setDoc((d) => ({ ...d, _id: res.id }));\n }\n\n return res;\n },\n [doc],\n );\n\n const remove: DeleteDocFn<T> = useCallback(\n async (existingDoc) => {\n const id = existingDoc?._id ?? doc._id;\n if (!id) throw database.logger.Error().Msg(`Document must have an _id to be removed`).AsError();\n const gotDoc = await database.get<T>(id).catch(() => undefined);\n if (!gotDoc) throw database.logger.Error().Str(\"id\", id).Msg(`Document not found`).AsError();\n const res = await database.del(id);\n setDoc(initialDoc);\n return res;\n },\n [doc, initialDoc],\n );\n\n // New granular update methods\n const merge = useCallback((newDoc: Partial<T>) => {\n updateHappenedRef.current = true;\n setDoc((prev) => ({ ...prev, ...newDoc }));\n }, []);\n\n const replace = useCallback((newDoc: T) => {\n updateHappenedRef.current = true;\n setDoc(newDoc);\n }, []);\n\n const reset = useCallback(() => {\n updateHappenedRef.current = true;\n setDoc({ ...originalInitialDoc });\n }, [originalInitialDoc]);\n\n // Legacy-compatible updateDoc\n const updateDoc = useCallback(\n (newDoc?: DocSet<T>, opts = { replace: false, reset: false }) => {\n if (!newDoc) {\n return opts.reset ? reset() : refresh();\n }\n return opts.replace ? replace(newDoc as T) : merge(newDoc);\n },\n [refresh, reset, replace, merge],\n );\n\n useEffect(() => {\n if (!doc._id) return;\n return database.subscribe((changes) => {\n if (updateHappenedRef.current) {\n return;\n }\n if (changes.find((c) => c._id === doc._id)) {\n void refresh();\n }\n }, true);\n }, [doc._id, refresh]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const submit = useCallback(\n async (e?: Event) => {\n if (e?.preventDefault) e.preventDefault();\n await save();\n reset();\n },\n [save, reset],\n );\n\n // Primary Object API with both new and legacy methods\n const apiObject = {\n doc: { ...doc } as DocWithId<T>,\n merge,\n replace,\n reset,\n refresh,\n save,\n remove,\n submit,\n };\n\n // Make the object properly iterable\n const tuple = [{ ...doc }, updateDoc, save, remove, reset, refresh];\n Object.assign(apiObject, tuple);\n Object.defineProperty(apiObject, Symbol.iterator, {\n enumerable: false,\n value: function* () {\n yield* tuple;\n },\n });\n\n return apiObject as UseDocumentResult<T>;\n };\n}\n","/**\n * Deep clone a value\n */\nexport function deepClone<T>(value: T): T {\n return (structuredClone ?? ((v: T) => JSON.parse(JSON.stringify(v))))(value);\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { DocFragment, DocTypes, DocWithId, IndexKeyType, IndexRow, MapFn, Database } from \"@fireproof/core\";\nimport type { LiveQueryResult } from \"./types.js\";\n\n/**\n * Implementation of the useLiveQuery hook\n */\nexport function createUseLiveQuery(database: Database) {\n return function useLiveQuery<T extends DocTypes, K extends IndexKeyType = string, R extends DocFragment = T>(\n mapFn: MapFn<T> | string,\n query = {},\n initialRows: IndexRow<K, T, R>[] = [],\n ): LiveQueryResult<T, K, R> {\n const [result, setResult] = useState<LiveQueryResult<T, K, R>>({\n docs: initialRows.map((r) => r.doc).filter((r): r is DocWithId<T> => !!r),\n rows: initialRows,\n });\n\n const queryString = useMemo(() => JSON.stringify(query), [query]);\n const mapFnString = useMemo(() => mapFn.toString(), [mapFn]);\n\n const refreshRows = useCallback(async () => {\n const res = await database.query<K, T, R>(mapFn, query);\n setResult({\n docs: res.rows.map((r) => r.doc).filter((r): r is DocWithId<T> => !!r),\n rows: res.rows,\n });\n }, [database, mapFnString, queryString]);\n\n useEffect(() => {\n refreshRows();\n const unsubscribe = database.subscribe(refreshRows);\n return () => {\n unsubscribe();\n };\n }, [database, refreshRows]);\n\n return result;\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { AllDocsQueryOpts, DocTypes, DocWithId, Database } from \"@fireproof/core\";\nimport type { AllDocsResult } from \"./types.js\";\n\n/**\n * Implementation of the useAllDocs hook\n */\nexport function createUseAllDocs(database: Database) {\n return function useAllDocs<T extends DocTypes>(query: AllDocsQueryOpts = {}): AllDocsResult<T> {\n const [result, setResult] = useState<AllDocsResult<T>>({\n docs: [],\n });\n\n const queryString = useMemo(() => JSON.stringify(query), [query]);\n\n const refreshRows = useCallback(async () => {\n const res = await database.allDocs<T>(query);\n setResult({\n ...res,\n docs: res.rows.map((r) => r.value as DocWithId<T>),\n });\n }, [database, queryString]);\n\n useEffect(() => {\n refreshRows();\n const unsubscribe = database.subscribe(refreshRows);\n return () => {\n unsubscribe();\n };\n }, [database, refreshRows]);\n\n return result;\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { ChangesOptions, ClockHead, DocTypes, DocWithId, Database } from \"@fireproof/core\";\nimport type { ChangesResult } from \"./types.js\";\n\n/**\n * Implementation of the useChanges hook\n */\nexport function createUseChanges(database: Database) {\n return function useChanges<T extends DocTypes>(since: ClockHead = [], opts: ChangesOptions = {}): ChangesResult<T> {\n const [result, setResult] = useState<ChangesResult<T>>({\n docs: [],\n });\n\n const queryString = useMemo(() => JSON.stringify(opts), [opts]);\n\n const refreshRows = useCallback(async () => {\n const res = await database.changes<T>(since, opts);\n setResult({ ...res, docs: res.rows.map((r) => r.value as DocWithId<T>) });\n }, [since, queryString]);\n\n useEffect(() => {\n refreshRows(); // Initial data fetch\n return database.subscribe(refreshRows);\n }, [refreshRows]);\n\n return result;\n };\n}\n","import { DocFileMeta } from \"@fireproof/core\";\nimport React, { useState, useEffect, ImgHTMLAttributes } from \"react\";\n\nconst { URL } = globalThis;\n\n// Union type to support both direct File objects and metadata objects\ntype FileType = File | DocFileMeta;\n\ninterface ImgFileProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, \"src\"> {\n file?: FileType;\n /**\n * @deprecated Use 'file' instead. This is for internal use only to support legacy code.\n * @internal\n */\n meta?: FileType;\n}\n\n// Helper function to determine if the object is a File-like object\nfunction isFile(obj: FileType): obj is File {\n return \"type\" in obj && \"size\" in obj && \"stream\" in obj && typeof obj.stream === \"function\";\n}\n\n// Helper function to determine if the object is a DocFileMeta\nfunction isFileMeta(obj: FileType): obj is DocFileMeta {\n return \"type\" in obj && \"size\" in obj && \"file\" in obj && typeof obj.file === \"function\";\n}\n\nexport function ImgFile({ file, meta, ...imgProps }: ImgFileProps) {\n const [imgDataUrl, setImgDataUrl] = useState(\"\");\n\n // Use meta as fallback if file is not provided (for backward compatibility)\n const fileData = file || meta;\n\n useEffect(() => {\n if (!fileData) return;\n\n const loadFile = async () => {\n let fileObj: File | null = null;\n let fileType = \"\";\n\n switch (true) {\n case isFile(fileData):\n fileObj = fileData;\n fileType = fileData.type;\n break;\n case isFileMeta(fileData):\n fileType = fileData.type;\n fileObj = (await fileData.file?.()) || null;\n break;\n }\n\n if (fileObj && /image/.test(fileType)) {\n const src = URL.createObjectURL(fileObj);\n setImgDataUrl(src);\n return () => URL.revokeObjectURL(src);\n }\n };\n\n let isMounted = true;\n let cleanup: (() => void) | undefined;\n\n loadFile().then((result) => {\n if (isMounted) {\n cleanup = result;\n } else if (result) {\n result();\n }\n });\n\n return () => {\n isMounted = false;\n if (cleanup) cleanup();\n };\n }, [fileData]);\n\n return imgDataUrl\n ? React.createElement(\"img\", {\n src: imgDataUrl,\n ...imgProps,\n })\n : null;\n}\n\nexport default ImgFile;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,kBAA0B;AAC1B,IAAAA,gBAAwB;;;ACFxB,mBAAkE;;;ACG3D,SAAS,UAAa,OAAa;AACxC,UAAQ,oBAAoB,CAAC,MAAS,KAAK,MAAM,KAAK,UAAU,CAAC,CAAC,IAAI,KAAK;AAC7E;;;ADGO,SAAS,kBAAkB,UAAoB;AACpD,SAAO,SAAS,YAAgC,gBAAqE;AACnH,UAAM,wBAAoB,qBAAO,KAAK;AACtC,QAAI;AACJ,QAAI,OAAO,mBAAmB,YAAY;AACxC,mBAAa,eAAe;AAAA,IAC9B,OAAO;AACL,mBAAa,kBAAmB,CAAC;AAAA,IACnC;AAEA,UAAM,yBAAqB,sBAAQ,MAAM,UAAU,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;AAEzE,UAAM,CAAC,KAAK,MAAM,QAAI,uBAAS,UAAU;AAEzC,UAAM,cAAU,0BAAY,YAAY;AACtC,YAAM,SAAS,IAAI,MAAM,MAAM,SAAS,IAAO,IAAI,GAAG,EAAE,MAAM,MAAM,UAAU,IAAI;AAClF,aAAO,MAAM;AAAA,IACf,GAAG,CAAC,IAAI,GAAG,CAAC;AAEZ,UAAM,WAAsB;AAAA,MAC1B,OAAO,gBAAgB;AACrB,0BAAkB,UAAU;AAC5B,cAAM,SAAS,eAAe;AAC9B,cAAM,MAAM,MAAM,SAAS,IAAI,MAAM;AAErC,YAAI,CAAC,kBAAkB,WAAW,CAAC,IAAI,OAAO,CAAC,aAAa;AAC1D,iBAAO,CAAC,OAAO,EAAE,GAAG,GAAG,KAAK,IAAI,GAAG,EAAE;AAAA,QACvC;AAEA,eAAO;AAAA,MACT;AAAA,MACA,CAAC,GAAG;AAAA,IACN;AAEA,UAAM,aAAyB;AAAA,MAC7B,OAAO,gBAAgB;AACrB,cAAM,KAAK,aAAa,OAAO,IAAI;AACnC,YAAI,CAAC,GAAI,OAAM,SAAS,OAAO,MAAM,EAAE,IAAI,yCAAyC,EAAE,QAAQ;AAC9F,cAAM,SAAS,MAAM,SAAS,IAAO,EAAE,EAAE,MAAM,MAAM,MAAS;AAC9D,YAAI,CAAC,OAAQ,OAAM,SAAS,OAAO,MAAM,EAAE,IAAI,MAAM,EAAE,EAAE,IAAI,oBAAoB,EAAE,QAAQ;AAC3F,cAAM,MAAM,MAAM,SAAS,IAAI,EAAE;AACjC,eAAO,UAAU;AACjB,eAAO;AAAA,MACT;AAAA,MACA,CAAC,KAAK,UAAU;AAAA,IAClB;AAGA,UAAM,YAAQ,0BAAY,CAAC,WAAuB;AAChD,wBAAkB,UAAU;AAC5B,aAAO,CAAC,UAAU,EAAE,GAAG,MAAM,GAAG,OAAO,EAAE;AAAA,IAC3C,GAAG,CAAC,CAAC;AAEL,UAAM,cAAU,0BAAY,CAAC,WAAc;AACzC,wBAAkB,UAAU;AAC5B,aAAO,MAAM;AAAA,IACf,GAAG,CAAC,CAAC;AAEL,UAAM,YAAQ,0BAAY,MAAM;AAC9B,wBAAkB,UAAU;AAC5B,aAAO,EAAE,GAAG,mBAAmB,CAAC;AAAA,IAClC,GAAG,CAAC,kBAAkB,CAAC;AAGvB,UAAM,gBAAY;AAAA,MAChB,CAAC,QAAoB,OAAO,EAAE,SAAS,OAAO,OAAO,MAAM,MAAM;AAC/D,YAAI,CAAC,QAAQ;AACX,iBAAO,KAAK,QAAQ,MAAM,IAAI,QAAQ;AAAA,QACxC;AACA,eAAO,KAAK,UAAU,QAAQ,MAAW,IAAI,MAAM,MAAM;AAAA,MAC3D;AAAA,MACA,CAAC,SAAS,OAAO,SAAS,KAAK;AAAA,IACjC;AAEA,gCAAU,MAAM;AACd,UAAI,CAAC,IAAI,IAAK;AACd,aAAO,SAAS,UAAU,CAAC,YAAY;AACrC,YAAI,kBAAkB,SAAS;AAC7B;AAAA,QACF;AACA,YAAI,QAAQ,KAAK,CAAC,MAAM,EAAE,QAAQ,IAAI,GAAG,GAAG;AAC1C,eAAK,QAAQ;AAAA,QACf;AAAA,MACF,GAAG,IAAI;AAAA,IACT,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC;AAErB,gCAAU,MAAM;AACd,WAAK,QAAQ;AAAA,IACf,GAAG,CAAC,OAAO,CAAC;AAEZ,UAAM,aAAS;AAAA,MACb,OAAO,MAAc;AACnB,YAAI,GAAG,eAAgB,GAAE,eAAe;AACxC,cAAM,KAAK;AACX,cAAM;AAAA,MACR;AAAA,MACA,CAAC,MAAM,KAAK;AAAA,IACd;AAGA,UAAM,YAAY;AAAA,MAChB,KAAK,EAAE,GAAG,IAAI;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,UAAM,QAAQ,CAAC,EAAE,GAAG,IAAI,GAAG,WAAW,MAAM,QAAQ,OAAO,OAAO;AAClE,WAAO,OAAO,WAAW,KAAK;AAC9B,WAAO,eAAe,WAAW,OAAO,UAAU;AAAA,MAChD,YAAY;AAAA,MACZ,OAAO,aAAa;AAClB,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AACF;;;AEnIA,IAAAC,gBAA0D;AAOnD,SAAS,mBAAmB,UAAoB;AACrD,SAAO,SAAS,aACd,OACA,QAAQ,CAAC,GACT,cAAmC,CAAC,GACV;AAC1B,UAAM,CAAC,QAAQ,SAAS,QAAI,wBAAmC;AAAA,MAC7D,MAAM,YAAY,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,MAAyB,CAAC,CAAC,CAAC;AAAA,MACxE,MAAM;AAAA,IACR,CAAC;AAED,UAAM,kBAAc,uBAAQ,MAAM,KAAK,UAAU,KAAK,GAAG,CAAC,KAAK,CAAC;AAChE,UAAM,kBAAc,uBAAQ,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC;AAE3D,UAAM,kBAAc,2BAAY,YAAY;AAC1C,YAAM,MAAM,MAAM,SAAS,MAAe,OAAO,KAAK;AACtD,gBAAU;AAAA,QACR,MAAM,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,MAAyB,CAAC,CAAC,CAAC;AAAA,QACrE,MAAM,IAAI;AAAA,MACZ,CAAC;AAAA,IACH,GAAG,CAAC,UAAU,aAAa,WAAW,CAAC;AAEvC,iCAAU,MAAM;AACd,kBAAY;AACZ,YAAM,cAAc,SAAS,UAAU,WAAW;AAClD,aAAO,MAAM;AACX,oBAAY;AAAA,MACd;AAAA,IACF,GAAG,CAAC,UAAU,WAAW,CAAC;AAE1B,WAAO;AAAA,EACT;AACF;;;ACvCA,IAAAC,gBAA0D;AAOnD,SAAS,iBAAiB,UAAoB;AACnD,SAAO,SAAS,WAA+B,QAA0B,CAAC,GAAqB;AAC7F,UAAM,CAAC,QAAQ,SAAS,QAAI,wBAA2B;AAAA,MACrD,MAAM,CAAC;AAAA,IACT,CAAC;AAED,UAAM,kBAAc,uBAAQ,MAAM,KAAK,UAAU,KAAK,GAAG,CAAC,KAAK,CAAC;AAEhE,UAAM,kBAAc,2BAAY,YAAY;AAC1C,YAAM,MAAM,MAAM,SAAS,QAAW,KAAK;AAC3C,gBAAU;AAAA,QACR,GAAG;AAAA,QACH,MAAM,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,KAAqB;AAAA,MACnD,CAAC;AAAA,IACH,GAAG,CAAC,UAAU,WAAW,CAAC;AAE1B,iCAAU,MAAM;AACd,kBAAY;AACZ,YAAM,cAAc,SAAS,UAAU,WAAW;AAClD,aAAO,MAAM;AACX,oBAAY;AAAA,MACd;AAAA,IACF,GAAG,CAAC,UAAU,WAAW,CAAC;AAE1B,WAAO;AAAA,EACT;AACF;;;ACjCA,IAAAC,gBAA0D;AAOnD,SAAS,iBAAiB,UAAoB;AACnD,SAAO,SAAS,WAA+B,QAAmB,CAAC,GAAG,OAAuB,CAAC,GAAqB;AACjH,UAAM,CAAC,QAAQ,SAAS,QAAI,wBAA2B;AAAA,MACrD,MAAM,CAAC;AAAA,IACT,CAAC;AAED,UAAM,kBAAc,uBAAQ,MAAM,KAAK,UAAU,IAAI,GAAG,CAAC,IAAI,CAAC;AAE9D,UAAM,kBAAc,2BAAY,YAAY;AAC1C,YAAM,MAAM,MAAM,SAAS,QAAW,OAAO,IAAI;AACjD,gBAAU,EAAE,GAAG,KAAK,MAAM,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,KAAqB,EAAE,CAAC;AAAA,IAC1E,GAAG,CAAC,OAAO,WAAW,CAAC;AAEvB,iCAAU,MAAM;AACd,kBAAY;AACZ,aAAO,SAAS,UAAU,WAAW;AAAA,IACvC,GAAG,CAAC,WAAW,CAAC;AAEhB,WAAO;AAAA,EACT;AACF;;;ALfO,IAAM,eAAe,CAAC;AAgBtB,SAAS,aAAa,OAA0B,gBAAgB,SAAqB,CAAC,GAAiB;AAE5G,aAAO,uBAAQ,MAAM;AACnB,UAAM,WAAW,OAAO,SAAS,eAAW,uBAAU,MAAM,MAAM,IAAI;AAEtE,UAAM,cAAc,kBAAkB,QAAQ;AAC9C,UAAM,eAAe,mBAAmB,QAAQ;AAChD,UAAM,aAAa,iBAAiB,QAAQ;AAC5C,UAAM,aAAa,iBAAiB,QAAQ;AAE5C,WAAO,EAAE,UAAU,cAAc,aAAa,YAAY,WAAW;AAAA,EACvE,GAAG,CAAC,MAAM,KAAK,UAAU,MAAM,CAAC,CAAC;AACnC;;;AMvCA,IAAAC,gBAA8D;AAE9D,IAAM,EAAE,IAAI,IAAI;AAehB,SAAS,OAAO,KAA4B;AAC1C,SAAO,UAAU,OAAO,UAAU,OAAO,YAAY,OAAO,OAAO,IAAI,WAAW;AACpF;AAGA,SAAS,WAAW,KAAmC;AACrD,SAAO,UAAU,OAAO,UAAU,OAAO,UAAU,OAAO,OAAO,IAAI,SAAS;AAChF;AAEO,SAAS,QAAQ,EAAE,MAAM,MAAM,GAAG,SAAS,GAAiB;AACjE,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAS,EAAE;AAG/C,QAAM,WAAW,QAAQ;AAEzB,+BAAU,MAAM;AACd,QAAI,CAAC,SAAU;AAEf,UAAM,WAAW,YAAY;AAC3B,UAAI,UAAuB;AAC3B,UAAI,WAAW;AAEf,cAAQ,MAAM;AAAA,QACZ,KAAK,OAAO,QAAQ;AAClB,oBAAU;AACV,qBAAW,SAAS;AACpB;AAAA,QACF,KAAK,WAAW,QAAQ;AACtB,qBAAW,SAAS;AACpB,oBAAW,MAAM,SAAS,OAAO,KAAM;AACvC;AAAA,MACJ;AAEA,UAAI,WAAW,QAAQ,KAAK,QAAQ,GAAG;AACrC,cAAM,MAAM,IAAI,gBAAgB,OAAO;AACvC,sBAAc,GAAG;AACjB,eAAO,MAAM,IAAI,gBAAgB,GAAG;AAAA,MACtC;AAAA,IACF;AAEA,QAAI,YAAY;AAChB,QAAI;AAEJ,aAAS,EAAE,KAAK,CAAC,WAAW;AAC1B,UAAI,WAAW;AACb,kBAAU;AAAA,MACZ,WAAW,QAAQ;AACjB,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAED,WAAO,MAAM;AACX,kBAAY;AACZ,UAAI,QAAS,SAAQ;AAAA,IACvB;AAAA,EACF,GAAG,CAAC,QAAQ,CAAC;AAEb,SAAO,aACH,cAAAC,QAAM,cAAc,OAAO;AAAA,IACzB,KAAK;AAAA,IACL,GAAG;AAAA,EACL,CAAC,IACD;AACN;","names":["import_react","import_react","import_react","import_react","import_react","React"]}
package/react/index.js CHANGED
@@ -119,24 +119,18 @@ function createUseDocument(database) {
119
119
  import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
120
120
  function createUseLiveQuery(database) {
121
121
  return function useLiveQuery(mapFn, query = {}, initialRows = []) {
122
- const [result, setResult] = useState2(() => {
123
- const docs = initialRows.map((r) => r.doc).filter((r) => !!r);
124
- return Object.assign(docs, {
125
- docs,
126
- rows: initialRows
127
- });
122
+ const [result, setResult] = useState2({
123
+ docs: initialRows.map((r) => r.doc).filter((r) => !!r),
124
+ rows: initialRows
128
125
  });
129
126
  const queryString = useMemo2(() => JSON.stringify(query), [query]);
130
127
  const mapFnString = useMemo2(() => mapFn.toString(), [mapFn]);
131
128
  const refreshRows = useCallback2(async () => {
132
129
  const res = await database.query(mapFn, query);
133
- const docs = res.rows.map((r) => r.doc).filter((r) => !!r);
134
- setResult(
135
- Object.assign(docs, {
136
- docs,
137
- rows: res.rows
138
- })
139
- );
130
+ setResult({
131
+ docs: res.rows.map((r) => r.doc).filter((r) => !!r),
132
+ rows: res.rows
133
+ });
140
134
  }, [database, mapFnString, queryString]);
141
135
  useEffect2(() => {
142
136
  refreshRows();
@@ -159,12 +153,18 @@ function createUseAllDocs(database) {
159
153
  const queryString = useMemo3(() => JSON.stringify(query), [query]);
160
154
  const refreshRows = useCallback3(async () => {
161
155
  const res = await database.allDocs(query);
162
- setResult({ ...res, docs: res.rows.map((r) => r.value) });
163
- }, [queryString]);
156
+ setResult({
157
+ ...res,
158
+ docs: res.rows.map((r) => r.value)
159
+ });
160
+ }, [database, queryString]);
164
161
  useEffect3(() => {
165
162
  refreshRows();
166
- return database.subscribe(refreshRows);
167
- }, [refreshRows]);
163
+ const unsubscribe = database.subscribe(refreshRows);
164
+ return () => {
165
+ unsubscribe();
166
+ };
167
+ }, [database, refreshRows]);
168
168
  return result;
169
169
  };
170
170
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/react/use-fireproof.ts","../../../src/react/use-document.ts","../../../src/react/utils.ts","../../../src/react/use-live-query.ts","../../../src/react/use-all-docs.ts","../../../src/react/use-changes.ts","../../../src/react/img-file.ts"],"sourcesContent":["import type { ConfigOpts, Database } from \"@fireproof/core\";\nimport { fireproof } from \"@fireproof/core\";\nimport { useMemo } from \"react\";\nimport type { UseFireproof } from \"./types.js\";\nimport { createUseDocument } from \"./use-document.js\";\nimport { createUseLiveQuery } from \"./use-live-query.js\";\nimport { createUseAllDocs } from \"./use-all-docs.js\";\nimport { createUseChanges } from \"./use-changes.js\";\n\n/**\n * @deprecated Use the `useFireproof` hook instead\n */\nexport const FireproofCtx = {} as UseFireproof;\n\n/**\n *\n * ## Summary\n *\n * React hook to create a custom-named Fireproof database and provides the utility hooks to query against it.\n *\n * ## Usage\n * ```tsx\n * const { database, useLiveQuery, useDocument } = useFireproof(\"dbname\");\n * const { database, useLiveQuery, useDocument } = useFireproof(\"dbname\", { ...options });\n * ```\n *\n *\n */\nexport function useFireproof(name: string | Database = \"useFireproof\", config: ConfigOpts = {}): UseFireproof {\n // Use useMemo to ensure stable references across renders\n return useMemo(() => {\n const database = typeof name === \"string\" ? fireproof(name, config) : name;\n\n const useDocument = createUseDocument(database);\n const useLiveQuery = createUseLiveQuery(database);\n const useAllDocs = createUseAllDocs(database);\n const useChanges = createUseChanges(database);\n\n return { database, useLiveQuery, useDocument, useAllDocs, useChanges };\n }, [name, JSON.stringify(config)]); // Only recreate if name or stringified config changes\n}\n\n// Export types\nexport type {\n LiveQueryResult,\n UseDocumentResult,\n AllDocsResult,\n ChangesResult,\n UseDocument,\n UseLiveQuery,\n UseAllDocs,\n UseChanges,\n UseFireproof,\n} from \"./types.js\";\n","import { useCallback, useEffect, useMemo, useState, useRef } from \"react\";\nimport type { DocSet, DocTypes, DocWithId, Database } from \"@fireproof/core\";\nimport { deepClone } from \"./utils.js\";\nimport type { DeleteDocFn, StoreDocFn, UseDocumentInitialDocOrFn, UseDocumentResult } from \"./types.js\";\n\n/**\n * Implementation of the useDocument hook\n */\nexport function createUseDocument(database: Database) {\n return function useDocument<T extends DocTypes>(initialDocOrFn?: UseDocumentInitialDocOrFn<T>): UseDocumentResult<T> {\n const updateHappenedRef = useRef(false);\n let initialDoc: DocSet<T>;\n if (typeof initialDocOrFn === \"function\") {\n initialDoc = initialDocOrFn();\n } else {\n initialDoc = initialDocOrFn ?? ({} as T);\n }\n\n const originalInitialDoc = useMemo(() => deepClone({ ...initialDoc }), []);\n\n const [doc, setDoc] = useState(initialDoc);\n\n const refresh = useCallback(async () => {\n const gotDoc = doc._id ? await database.get<T>(doc._id).catch(() => initialDoc) : initialDoc;\n setDoc(gotDoc);\n }, [doc._id]);\n\n const save: StoreDocFn<T> = useCallback(\n async (existingDoc) => {\n updateHappenedRef.current = false;\n const toSave = existingDoc ?? doc;\n const res = await database.put(toSave);\n\n if (!updateHappenedRef.current && !doc._id && !existingDoc) {\n setDoc((d) => ({ ...d, _id: res.id }));\n }\n\n return res;\n },\n [doc],\n );\n\n const remove: DeleteDocFn<T> = useCallback(\n async (existingDoc) => {\n const id = existingDoc?._id ?? doc._id;\n if (!id) throw database.logger.Error().Msg(`Document must have an _id to be removed`).AsError();\n const gotDoc = await database.get<T>(id).catch(() => undefined);\n if (!gotDoc) throw database.logger.Error().Str(\"id\", id).Msg(`Document not found`).AsError();\n const res = await database.del(id);\n setDoc(initialDoc);\n return res;\n },\n [doc, initialDoc],\n );\n\n // New granular update methods\n const merge = useCallback((newDoc: Partial<T>) => {\n updateHappenedRef.current = true;\n setDoc((prev) => ({ ...prev, ...newDoc }));\n }, []);\n\n const replace = useCallback((newDoc: T) => {\n updateHappenedRef.current = true;\n setDoc(newDoc);\n }, []);\n\n const reset = useCallback(() => {\n updateHappenedRef.current = true;\n setDoc({ ...originalInitialDoc });\n }, [originalInitialDoc]);\n\n // Legacy-compatible updateDoc\n const updateDoc = useCallback(\n (newDoc?: DocSet<T>, opts = { replace: false, reset: false }) => {\n if (!newDoc) {\n return opts.reset ? reset() : refresh();\n }\n return opts.replace ? replace(newDoc as T) : merge(newDoc);\n },\n [refresh, reset, replace, merge],\n );\n\n useEffect(() => {\n if (!doc._id) return;\n return database.subscribe((changes) => {\n if (updateHappenedRef.current) {\n return;\n }\n if (changes.find((c) => c._id === doc._id)) {\n void refresh();\n }\n }, true);\n }, [doc._id, refresh]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const submit = useCallback(\n async (e?: Event) => {\n if (e?.preventDefault) e.preventDefault();\n await save();\n reset();\n },\n [save, reset],\n );\n\n // Primary Object API with both new and legacy methods\n const apiObject = {\n doc: { ...doc } as DocWithId<T>,\n merge,\n replace,\n reset,\n refresh,\n save,\n remove,\n submit,\n };\n\n // Make the object properly iterable\n const tuple = [{ ...doc }, updateDoc, save, remove, reset, refresh];\n Object.assign(apiObject, tuple);\n Object.defineProperty(apiObject, Symbol.iterator, {\n enumerable: false,\n value: function* () {\n yield* tuple;\n },\n });\n\n return apiObject as UseDocumentResult<T>;\n };\n}\n","/**\n * Deep clone a value\n */\nexport function deepClone<T>(value: T): T {\n return (structuredClone ?? ((v: T) => JSON.parse(JSON.stringify(v))))(value);\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { DocFragment, DocTypes, DocWithId, IndexKeyType, IndexRow, MapFn, Database } from \"@fireproof/core\";\nimport type { LiveQueryResult } from \"./types.js\";\n\n// Internal shadow type for array-like behavior (implementation detail)\ntype EnhancedQueryResult<T extends DocTypes, K extends IndexKeyType, R extends DocFragment = T> = LiveQueryResult<T, K, R> &\n DocWithId<T>[];\n\n/**\n * Implementation of the useLiveQuery hook\n */\nexport function createUseLiveQuery(database: Database) {\n return function useLiveQuery<T extends DocTypes, K extends IndexKeyType = string, R extends DocFragment = T>(\n mapFn: MapFn<T> | string,\n query = {},\n initialRows: IndexRow<K, T, R>[] = [],\n ): LiveQueryResult<T, K, R> {\n const [result, setResult] = useState<EnhancedQueryResult<T, K, R>>(() => {\n const docs = initialRows.map((r) => r.doc).filter((r): r is DocWithId<T> => !!r);\n return Object.assign(docs, {\n docs,\n rows: initialRows,\n });\n });\n\n const queryString = useMemo(() => JSON.stringify(query), [query]);\n const mapFnString = useMemo(() => mapFn.toString(), [mapFn]);\n\n const refreshRows = useCallback(async () => {\n const res = await database.query<K, T, R>(mapFn, query);\n const docs = res.rows.map((r) => r.doc).filter((r): r is DocWithId<T> => !!r);\n setResult(\n Object.assign(docs, {\n docs,\n rows: res.rows,\n }),\n );\n }, [database, mapFnString, queryString]);\n\n useEffect(() => {\n refreshRows();\n const unsubscribe = database.subscribe(refreshRows);\n return () => {\n unsubscribe();\n };\n }, [database, refreshRows]);\n\n return result;\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { AllDocsQueryOpts, DocTypes, DocWithId, Database } from \"@fireproof/core\";\nimport type { AllDocsResult } from \"./types.js\";\n\n/**\n * Implementation of the useAllDocs hook\n */\nexport function createUseAllDocs(database: Database) {\n return function useAllDocs<T extends DocTypes>(query: AllDocsQueryOpts = {}): AllDocsResult<T> {\n const [result, setResult] = useState<AllDocsResult<T>>({\n docs: [],\n });\n\n const queryString = useMemo(() => JSON.stringify(query), [query]);\n\n const refreshRows = useCallback(async () => {\n const res = await database.allDocs<T>(query);\n setResult({ ...res, docs: res.rows.map((r) => r.value as DocWithId<T>) });\n }, [queryString]);\n\n useEffect(() => {\n refreshRows(); // Initial data fetch\n return database.subscribe(refreshRows);\n }, [refreshRows]);\n\n return result;\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { ChangesOptions, ClockHead, DocTypes, DocWithId, Database } from \"@fireproof/core\";\nimport type { ChangesResult } from \"./types.js\";\n\n/**\n * Implementation of the useChanges hook\n */\nexport function createUseChanges(database: Database) {\n return function useChanges<T extends DocTypes>(since: ClockHead = [], opts: ChangesOptions = {}): ChangesResult<T> {\n const [result, setResult] = useState<ChangesResult<T>>({\n docs: [],\n });\n\n const queryString = useMemo(() => JSON.stringify(opts), [opts]);\n\n const refreshRows = useCallback(async () => {\n const res = await database.changes<T>(since, opts);\n setResult({ ...res, docs: res.rows.map((r) => r.value as DocWithId<T>) });\n }, [since, queryString]);\n\n useEffect(() => {\n refreshRows(); // Initial data fetch\n return database.subscribe(refreshRows);\n }, [refreshRows]);\n\n return result;\n };\n}\n","import { DocFileMeta } from \"@fireproof/core\";\nimport React, { useState, useEffect, ImgHTMLAttributes } from \"react\";\n\nconst { URL } = globalThis;\n\n// Union type to support both direct File objects and metadata objects\ntype FileType = File | DocFileMeta;\n\ninterface ImgFileProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, \"src\"> {\n file?: FileType;\n /**\n * @deprecated Use 'file' instead. This is for internal use only to support legacy code.\n * @internal\n */\n meta?: FileType;\n}\n\n// Helper function to determine if the object is a File-like object\nfunction isFile(obj: FileType): obj is File {\n return \"type\" in obj && \"size\" in obj && \"stream\" in obj && typeof obj.stream === \"function\";\n}\n\n// Helper function to determine if the object is a DocFileMeta\nfunction isFileMeta(obj: FileType): obj is DocFileMeta {\n return \"type\" in obj && \"size\" in obj && \"file\" in obj && typeof obj.file === \"function\";\n}\n\nexport function ImgFile({ file, meta, ...imgProps }: ImgFileProps) {\n const [imgDataUrl, setImgDataUrl] = useState(\"\");\n\n // Use meta as fallback if file is not provided (for backward compatibility)\n const fileData = file || meta;\n\n useEffect(() => {\n if (!fileData) return;\n\n const loadFile = async () => {\n let fileObj: File | null = null;\n let fileType = \"\";\n\n switch (true) {\n case isFile(fileData):\n fileObj = fileData;\n fileType = fileData.type;\n break;\n case isFileMeta(fileData):\n fileType = fileData.type;\n fileObj = (await fileData.file?.()) || null;\n break;\n }\n\n if (fileObj && /image/.test(fileType)) {\n const src = URL.createObjectURL(fileObj);\n setImgDataUrl(src);\n return () => URL.revokeObjectURL(src);\n }\n };\n\n let isMounted = true;\n let cleanup: (() => void) | undefined;\n\n loadFile().then((result) => {\n if (isMounted) {\n cleanup = result;\n } else if (result) {\n result();\n }\n });\n\n return () => {\n isMounted = false;\n if (cleanup) cleanup();\n };\n }, [fileData]);\n\n return imgDataUrl\n ? React.createElement(\"img\", {\n src: imgDataUrl,\n ...imgProps,\n })\n : null;\n}\n\nexport default ImgFile;\n"],"mappings":"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","names":["useMemo","useCallback","useEffect","useMemo","useState","useCallback","useEffect","useMemo","useState","useCallback","useEffect","useMemo","useState","useMemo","useState","useEffect"]}
1
+ {"version":3,"sources":["../../../src/react/use-fireproof.ts","../../../src/react/use-document.ts","../../../src/react/utils.ts","../../../src/react/use-live-query.ts","../../../src/react/use-all-docs.ts","../../../src/react/use-changes.ts","../../../src/react/img-file.ts"],"sourcesContent":["import type { ConfigOpts, Database } from \"@fireproof/core\";\nimport { fireproof } from \"@fireproof/core\";\nimport { useMemo } from \"react\";\nimport type { UseFireproof } from \"./types.js\";\nimport { createUseDocument } from \"./use-document.js\";\nimport { createUseLiveQuery } from \"./use-live-query.js\";\nimport { createUseAllDocs } from \"./use-all-docs.js\";\nimport { createUseChanges } from \"./use-changes.js\";\n\n/**\n * @deprecated Use the `useFireproof` hook instead\n */\nexport const FireproofCtx = {} as UseFireproof;\n\n/**\n *\n * ## Summary\n *\n * React hook to create a custom-named Fireproof database and provides the utility hooks to query against it.\n *\n * ## Usage\n * ```tsx\n * const { database, useLiveQuery, useDocument } = useFireproof(\"dbname\");\n * const { database, useLiveQuery, useDocument } = useFireproof(\"dbname\", { ...options });\n * ```\n *\n *\n */\nexport function useFireproof(name: string | Database = \"useFireproof\", config: ConfigOpts = {}): UseFireproof {\n // Use useMemo to ensure stable references across renders\n return useMemo(() => {\n const database = typeof name === \"string\" ? fireproof(name, config) : name;\n\n const useDocument = createUseDocument(database);\n const useLiveQuery = createUseLiveQuery(database);\n const useAllDocs = createUseAllDocs(database);\n const useChanges = createUseChanges(database);\n\n return { database, useLiveQuery, useDocument, useAllDocs, useChanges };\n }, [name, JSON.stringify(config)]); // Only recreate if name or stringified config changes\n}\n\n// Export types\nexport type {\n LiveQueryResult,\n UseDocumentResult,\n AllDocsResult,\n ChangesResult,\n UseDocument,\n UseLiveQuery,\n UseAllDocs,\n UseChanges,\n UseFireproof,\n} from \"./types.js\";\n","import { useCallback, useEffect, useMemo, useState, useRef } from \"react\";\nimport type { DocSet, DocTypes, DocWithId, Database } from \"@fireproof/core\";\nimport { deepClone } from \"./utils.js\";\nimport type { DeleteDocFn, StoreDocFn, UseDocumentInitialDocOrFn, UseDocumentResult } from \"./types.js\";\n\n/**\n * Implementation of the useDocument hook\n */\nexport function createUseDocument(database: Database) {\n return function useDocument<T extends DocTypes>(initialDocOrFn?: UseDocumentInitialDocOrFn<T>): UseDocumentResult<T> {\n const updateHappenedRef = useRef(false);\n let initialDoc: DocSet<T>;\n if (typeof initialDocOrFn === \"function\") {\n initialDoc = initialDocOrFn();\n } else {\n initialDoc = initialDocOrFn ?? ({} as T);\n }\n\n const originalInitialDoc = useMemo(() => deepClone({ ...initialDoc }), []);\n\n const [doc, setDoc] = useState(initialDoc);\n\n const refresh = useCallback(async () => {\n const gotDoc = doc._id ? await database.get<T>(doc._id).catch(() => initialDoc) : initialDoc;\n setDoc(gotDoc);\n }, [doc._id]);\n\n const save: StoreDocFn<T> = useCallback(\n async (existingDoc) => {\n updateHappenedRef.current = false;\n const toSave = existingDoc ?? doc;\n const res = await database.put(toSave);\n\n if (!updateHappenedRef.current && !doc._id && !existingDoc) {\n setDoc((d) => ({ ...d, _id: res.id }));\n }\n\n return res;\n },\n [doc],\n );\n\n const remove: DeleteDocFn<T> = useCallback(\n async (existingDoc) => {\n const id = existingDoc?._id ?? doc._id;\n if (!id) throw database.logger.Error().Msg(`Document must have an _id to be removed`).AsError();\n const gotDoc = await database.get<T>(id).catch(() => undefined);\n if (!gotDoc) throw database.logger.Error().Str(\"id\", id).Msg(`Document not found`).AsError();\n const res = await database.del(id);\n setDoc(initialDoc);\n return res;\n },\n [doc, initialDoc],\n );\n\n // New granular update methods\n const merge = useCallback((newDoc: Partial<T>) => {\n updateHappenedRef.current = true;\n setDoc((prev) => ({ ...prev, ...newDoc }));\n }, []);\n\n const replace = useCallback((newDoc: T) => {\n updateHappenedRef.current = true;\n setDoc(newDoc);\n }, []);\n\n const reset = useCallback(() => {\n updateHappenedRef.current = true;\n setDoc({ ...originalInitialDoc });\n }, [originalInitialDoc]);\n\n // Legacy-compatible updateDoc\n const updateDoc = useCallback(\n (newDoc?: DocSet<T>, opts = { replace: false, reset: false }) => {\n if (!newDoc) {\n return opts.reset ? reset() : refresh();\n }\n return opts.replace ? replace(newDoc as T) : merge(newDoc);\n },\n [refresh, reset, replace, merge],\n );\n\n useEffect(() => {\n if (!doc._id) return;\n return database.subscribe((changes) => {\n if (updateHappenedRef.current) {\n return;\n }\n if (changes.find((c) => c._id === doc._id)) {\n void refresh();\n }\n }, true);\n }, [doc._id, refresh]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const submit = useCallback(\n async (e?: Event) => {\n if (e?.preventDefault) e.preventDefault();\n await save();\n reset();\n },\n [save, reset],\n );\n\n // Primary Object API with both new and legacy methods\n const apiObject = {\n doc: { ...doc } as DocWithId<T>,\n merge,\n replace,\n reset,\n refresh,\n save,\n remove,\n submit,\n };\n\n // Make the object properly iterable\n const tuple = [{ ...doc }, updateDoc, save, remove, reset, refresh];\n Object.assign(apiObject, tuple);\n Object.defineProperty(apiObject, Symbol.iterator, {\n enumerable: false,\n value: function* () {\n yield* tuple;\n },\n });\n\n return apiObject as UseDocumentResult<T>;\n };\n}\n","/**\n * Deep clone a value\n */\nexport function deepClone<T>(value: T): T {\n return (structuredClone ?? ((v: T) => JSON.parse(JSON.stringify(v))))(value);\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { DocFragment, DocTypes, DocWithId, IndexKeyType, IndexRow, MapFn, Database } from \"@fireproof/core\";\nimport type { LiveQueryResult } from \"./types.js\";\n\n/**\n * Implementation of the useLiveQuery hook\n */\nexport function createUseLiveQuery(database: Database) {\n return function useLiveQuery<T extends DocTypes, K extends IndexKeyType = string, R extends DocFragment = T>(\n mapFn: MapFn<T> | string,\n query = {},\n initialRows: IndexRow<K, T, R>[] = [],\n ): LiveQueryResult<T, K, R> {\n const [result, setResult] = useState<LiveQueryResult<T, K, R>>({\n docs: initialRows.map((r) => r.doc).filter((r): r is DocWithId<T> => !!r),\n rows: initialRows,\n });\n\n const queryString = useMemo(() => JSON.stringify(query), [query]);\n const mapFnString = useMemo(() => mapFn.toString(), [mapFn]);\n\n const refreshRows = useCallback(async () => {\n const res = await database.query<K, T, R>(mapFn, query);\n setResult({\n docs: res.rows.map((r) => r.doc).filter((r): r is DocWithId<T> => !!r),\n rows: res.rows,\n });\n }, [database, mapFnString, queryString]);\n\n useEffect(() => {\n refreshRows();\n const unsubscribe = database.subscribe(refreshRows);\n return () => {\n unsubscribe();\n };\n }, [database, refreshRows]);\n\n return result;\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { AllDocsQueryOpts, DocTypes, DocWithId, Database } from \"@fireproof/core\";\nimport type { AllDocsResult } from \"./types.js\";\n\n/**\n * Implementation of the useAllDocs hook\n */\nexport function createUseAllDocs(database: Database) {\n return function useAllDocs<T extends DocTypes>(query: AllDocsQueryOpts = {}): AllDocsResult<T> {\n const [result, setResult] = useState<AllDocsResult<T>>({\n docs: [],\n });\n\n const queryString = useMemo(() => JSON.stringify(query), [query]);\n\n const refreshRows = useCallback(async () => {\n const res = await database.allDocs<T>(query);\n setResult({\n ...res,\n docs: res.rows.map((r) => r.value as DocWithId<T>),\n });\n }, [database, queryString]);\n\n useEffect(() => {\n refreshRows();\n const unsubscribe = database.subscribe(refreshRows);\n return () => {\n unsubscribe();\n };\n }, [database, refreshRows]);\n\n return result;\n };\n}\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { ChangesOptions, ClockHead, DocTypes, DocWithId, Database } from \"@fireproof/core\";\nimport type { ChangesResult } from \"./types.js\";\n\n/**\n * Implementation of the useChanges hook\n */\nexport function createUseChanges(database: Database) {\n return function useChanges<T extends DocTypes>(since: ClockHead = [], opts: ChangesOptions = {}): ChangesResult<T> {\n const [result, setResult] = useState<ChangesResult<T>>({\n docs: [],\n });\n\n const queryString = useMemo(() => JSON.stringify(opts), [opts]);\n\n const refreshRows = useCallback(async () => {\n const res = await database.changes<T>(since, opts);\n setResult({ ...res, docs: res.rows.map((r) => r.value as DocWithId<T>) });\n }, [since, queryString]);\n\n useEffect(() => {\n refreshRows(); // Initial data fetch\n return database.subscribe(refreshRows);\n }, [refreshRows]);\n\n return result;\n };\n}\n","import { DocFileMeta } from \"@fireproof/core\";\nimport React, { useState, useEffect, ImgHTMLAttributes } from \"react\";\n\nconst { URL } = globalThis;\n\n// Union type to support both direct File objects and metadata objects\ntype FileType = File | DocFileMeta;\n\ninterface ImgFileProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, \"src\"> {\n file?: FileType;\n /**\n * @deprecated Use 'file' instead. This is for internal use only to support legacy code.\n * @internal\n */\n meta?: FileType;\n}\n\n// Helper function to determine if the object is a File-like object\nfunction isFile(obj: FileType): obj is File {\n return \"type\" in obj && \"size\" in obj && \"stream\" in obj && typeof obj.stream === \"function\";\n}\n\n// Helper function to determine if the object is a DocFileMeta\nfunction isFileMeta(obj: FileType): obj is DocFileMeta {\n return \"type\" in obj && \"size\" in obj && \"file\" in obj && typeof obj.file === \"function\";\n}\n\nexport function ImgFile({ file, meta, ...imgProps }: ImgFileProps) {\n const [imgDataUrl, setImgDataUrl] = useState(\"\");\n\n // Use meta as fallback if file is not provided (for backward compatibility)\n const fileData = file || meta;\n\n useEffect(() => {\n if (!fileData) return;\n\n const loadFile = async () => {\n let fileObj: File | null = null;\n let fileType = \"\";\n\n switch (true) {\n case isFile(fileData):\n fileObj = fileData;\n fileType = fileData.type;\n break;\n case isFileMeta(fileData):\n fileType = fileData.type;\n fileObj = (await fileData.file?.()) || null;\n break;\n }\n\n if (fileObj && /image/.test(fileType)) {\n const src = URL.createObjectURL(fileObj);\n setImgDataUrl(src);\n return () => URL.revokeObjectURL(src);\n }\n };\n\n let isMounted = true;\n let cleanup: (() => void) | undefined;\n\n loadFile().then((result) => {\n if (isMounted) {\n cleanup = result;\n } else if (result) {\n result();\n }\n });\n\n return () => {\n isMounted = false;\n if (cleanup) cleanup();\n };\n }, [fileData]);\n\n return imgDataUrl\n ? React.createElement(\"img\", {\n src: imgDataUrl,\n ...imgProps,\n })\n : null;\n}\n\nexport default ImgFile;\n"],"mappings":"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","names":["useMemo","useCallback","useEffect","useMemo","useState","useCallback","useEffect","useMemo","useState","useCallback","useEffect","useMemo","useState","useMemo","useState","useEffect"]}
@@ -1 +1 @@
1
- {"inputs":{"src/react/utils.ts":{"bytes":156,"imports":[],"format":"esm"},"src/react/use-document.ts":{"bytes":3959,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/react/utils.ts","kind":"import-statement","original":"./utils.js"}],"format":"esm"},"src/react/use-live-query.ts":{"bytes":1760,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/use-all-docs.ts":{"bytes":934,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/use-changes.ts":{"bytes":974,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/use-fireproof.ts":{"bytes":1719,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/react/use-document.ts","kind":"import-statement","original":"./use-document.js"},{"path":"src/react/use-live-query.ts","kind":"import-statement","original":"./use-live-query.js"},{"path":"src/react/use-all-docs.ts","kind":"import-statement","original":"./use-all-docs.js"},{"path":"src/react/use-changes.ts","kind":"import-statement","original":"./use-changes.js"}],"format":"esm"},"src/react/types.ts":{"bytes":2407,"imports":[],"format":"esm"},"src/react/img-file.ts":{"bytes":2248,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/index.ts":{"bytes":124,"imports":[{"path":"src/react/use-fireproof.ts","kind":"import-statement","original":"./use-fireproof.js"},{"path":"src/react/types.ts","kind":"import-statement","original":"./types.js"},{"path":"src/react/img-file.ts","kind":"import-statement","original":"./img-file.js"}],"format":"esm"}},"outputs":{"dist/fireproof-core/react/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":18837},"dist/fireproof-core/react/index.cjs":{"imports":[{"path":"@fireproof/core","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true}],"exports":[],"entryPoint":"src/react/index.ts","inputs":{"src/react/index.ts":{"bytesInOutput":197},"src/react/use-fireproof.ts":{"bytesInOutput":634},"src/react/use-document.ts":{"bytesInOutput":3460},"src/react/utils.ts":{"bytesInOutput":107},"src/react/use-live-query.ts":{"bytesInOutput":1129},"src/react/use-all-docs.ts":{"bytesInOutput":657},"src/react/use-changes.ts":{"bytesInOutput":679},"src/react/img-file.ts":{"bytesInOutput":1499}},"bytes":10043}}}
1
+ {"inputs":{"src/react/utils.ts":{"bytes":156,"imports":[],"format":"esm"},"src/react/use-document.ts":{"bytes":3959,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/react/utils.ts","kind":"import-statement","original":"./utils.js"}],"format":"esm"},"src/react/use-live-query.ts":{"bytes":1403,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/use-all-docs.ts":{"bytes":1021,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/use-changes.ts":{"bytes":974,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/use-fireproof.ts":{"bytes":1719,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/react/use-document.ts","kind":"import-statement","original":"./use-document.js"},{"path":"src/react/use-live-query.ts","kind":"import-statement","original":"./use-live-query.js"},{"path":"src/react/use-all-docs.ts","kind":"import-statement","original":"./use-all-docs.js"},{"path":"src/react/use-changes.ts","kind":"import-statement","original":"./use-changes.js"}],"format":"esm"},"src/react/types.ts":{"bytes":2407,"imports":[],"format":"esm"},"src/react/img-file.ts":{"bytes":2248,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/index.ts":{"bytes":124,"imports":[{"path":"src/react/use-fireproof.ts","kind":"import-statement","original":"./use-fireproof.js"},{"path":"src/react/types.ts","kind":"import-statement","original":"./types.js"},{"path":"src/react/img-file.ts","kind":"import-statement","original":"./img-file.js"}],"format":"esm"}},"outputs":{"dist/fireproof-core/react/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":18533},"dist/fireproof-core/react/index.cjs":{"imports":[{"path":"@fireproof/core","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true}],"exports":[],"entryPoint":"src/react/index.ts","inputs":{"src/react/index.ts":{"bytesInOutput":197},"src/react/use-fireproof.ts":{"bytesInOutput":634},"src/react/use-document.ts":{"bytesInOutput":3460},"src/react/utils.ts":{"bytesInOutput":107},"src/react/use-live-query.ts":{"bytesInOutput":993},"src/react/use-all-docs.ts":{"bytesInOutput":765},"src/react/use-changes.ts":{"bytesInOutput":679},"src/react/img-file.ts":{"bytesInOutput":1499}},"bytes":10015}}}
@@ -1 +1 @@
1
- {"inputs":{"src/react/utils.ts":{"bytes":156,"imports":[],"format":"esm"},"src/react/use-document.ts":{"bytes":3959,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/react/utils.ts","kind":"import-statement","original":"./utils.js"}],"format":"esm"},"src/react/use-live-query.ts":{"bytes":1760,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/use-all-docs.ts":{"bytes":934,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/use-changes.ts":{"bytes":974,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/use-fireproof.ts":{"bytes":1719,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/react/use-document.ts","kind":"import-statement","original":"./use-document.js"},{"path":"src/react/use-live-query.ts","kind":"import-statement","original":"./use-live-query.js"},{"path":"src/react/use-all-docs.ts","kind":"import-statement","original":"./use-all-docs.js"},{"path":"src/react/use-changes.ts","kind":"import-statement","original":"./use-changes.js"}],"format":"esm"},"src/react/types.ts":{"bytes":2407,"imports":[],"format":"esm"},"src/react/img-file.ts":{"bytes":2248,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/index.ts":{"bytes":124,"imports":[{"path":"src/react/use-fireproof.ts","kind":"import-statement","original":"./use-fireproof.js"},{"path":"src/react/types.ts","kind":"import-statement","original":"./types.js"},{"path":"src/react/img-file.ts","kind":"import-statement","original":"./img-file.js"}],"format":"esm"}},"outputs":{"dist/fireproof-core/react/index.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":18877},"dist/fireproof-core/react/index.js":{"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"exports":["FireproofCtx","ImgFile","useFireproof"],"entryPoint":"src/react/index.ts","inputs":{"src/react/use-fireproof.ts":{"bytesInOutput":605},"src/react/use-document.ts":{"bytesInOutput":3264},"src/react/utils.ts":{"bytesInOutput":107},"src/react/use-live-query.ts":{"bytesInOutput":1123},"src/react/use-all-docs.ts":{"bytesInOutput":669},"src/react/use-changes.ts":{"bytesInOutput":691},"src/react/index.ts":{"bytesInOutput":0},"src/react/img-file.ts":{"bytesInOutput":1476}},"bytes":8250}}}
1
+ {"inputs":{"src/react/utils.ts":{"bytes":156,"imports":[],"format":"esm"},"src/react/use-document.ts":{"bytes":3959,"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"src/react/utils.ts","kind":"import-statement","original":"./utils.js"}],"format":"esm"},"src/react/use-live-query.ts":{"bytes":1403,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/use-all-docs.ts":{"bytes":1021,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/use-changes.ts":{"bytes":974,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/use-fireproof.ts":{"bytes":1719,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"src/react/use-document.ts","kind":"import-statement","original":"./use-document.js"},{"path":"src/react/use-live-query.ts","kind":"import-statement","original":"./use-live-query.js"},{"path":"src/react/use-all-docs.ts","kind":"import-statement","original":"./use-all-docs.js"},{"path":"src/react/use-changes.ts","kind":"import-statement","original":"./use-changes.js"}],"format":"esm"},"src/react/types.ts":{"bytes":2407,"imports":[],"format":"esm"},"src/react/img-file.ts":{"bytes":2248,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/index.ts":{"bytes":124,"imports":[{"path":"src/react/use-fireproof.ts","kind":"import-statement","original":"./use-fireproof.js"},{"path":"src/react/types.ts","kind":"import-statement","original":"./types.js"},{"path":"src/react/img-file.ts","kind":"import-statement","original":"./img-file.js"}],"format":"esm"}},"outputs":{"dist/fireproof-core/react/index.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":18573},"dist/fireproof-core/react/index.js":{"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"exports":["FireproofCtx","ImgFile","useFireproof"],"entryPoint":"src/react/index.ts","inputs":{"src/react/use-fireproof.ts":{"bytesInOutput":605},"src/react/use-document.ts":{"bytesInOutput":3264},"src/react/utils.ts":{"bytesInOutput":107},"src/react/use-live-query.ts":{"bytesInOutput":987},"src/react/use-all-docs.ts":{"bytesInOutput":777},"src/react/use-changes.ts":{"bytesInOutput":691},"src/react/index.ts":{"bytesInOutput":0},"src/react/img-file.ts":{"bytesInOutput":1476}},"bytes":8222}}}
@@ -0,0 +1,173 @@
1
+ import { renderHook, waitFor } from "@testing-library/react";
2
+ import { describe, expect, it, beforeEach, afterEach } from "vitest";
3
+ import { fireproof, useFireproof } from "use-fireproof";
4
+ import type { Database } from "use-fireproof";
5
+ import type { AllDocsResult } from "../../src/react/types.js";
6
+
7
+ // Test timeout value for CI
8
+ const TEST_TIMEOUT = 45000;
9
+
10
+ describe("HOOK: useFireproof useAllDocs", () => {
11
+ const dbName = "useAllDocsTest";
12
+ let db: Database,
13
+ database: ReturnType<typeof useFireproof>["database"],
14
+ useAllDocs: ReturnType<typeof useFireproof>["useAllDocs"];
15
+
16
+ beforeEach(async () => {
17
+ const expectedValues = ["apple", "banana", "cherry"];
18
+ db = fireproof(dbName);
19
+ for (const value of expectedValues) {
20
+ await db.put({ fruit: value });
21
+ }
22
+
23
+ const allDocs = await db.allDocs<{ fruit: string }>();
24
+ expect(allDocs.rows.map((row) => row.value.fruit)).toEqual(expectedValues);
25
+ });
26
+
27
+ it(
28
+ "fetches documents correctly",
29
+ async () => {
30
+ let result: AllDocsResult<{ fruit: string }>;
31
+
32
+ renderHook(() => {
33
+ const hookResult = useFireproof(dbName);
34
+ database = hookResult.database;
35
+ useAllDocs = hookResult.useAllDocs;
36
+ result = useAllDocs<{ fruit: string }>();
37
+ });
38
+
39
+ await waitFor(() => {
40
+ expect(result.docs.length).toBe(3);
41
+ expect(result.docs.map((doc) => doc.fruit)).toEqual(["apple", "banana", "cherry"]);
42
+ });
43
+ },
44
+ TEST_TIMEOUT,
45
+ );
46
+
47
+ it(
48
+ "updates when database changes",
49
+ async () => {
50
+ let allDocsResult: AllDocsResult<{ fruit: string }>;
51
+
52
+ renderHook(() => {
53
+ const hookResult = useFireproof(dbName);
54
+ database = hookResult.database;
55
+ useAllDocs = hookResult.useAllDocs;
56
+ allDocsResult = useAllDocs<{ fruit: string }>();
57
+ });
58
+
59
+ // Wait for initial data to load
60
+ await waitFor(() => {
61
+ expect(allDocsResult.docs.length).toBe(3);
62
+ });
63
+
64
+ // Add a new document
65
+ await database.put({ fruit: "dragonfruit" });
66
+
67
+ // Verify the hook updates with the new document
68
+ await waitFor(() => {
69
+ expect(allDocsResult.docs.length).toBe(4);
70
+ expect(allDocsResult.docs.map((doc) => doc.fruit)).toContain("dragonfruit");
71
+ });
72
+ },
73
+ TEST_TIMEOUT,
74
+ );
75
+
76
+ it(
77
+ "properly handles subscription lifecycle",
78
+ async () => {
79
+ // This test verifies that the subscription works properly
80
+ // We'll just check that the component renders and updates
81
+
82
+ // Render the hook in a way we can unmount it
83
+ const { unmount, result } = renderHook(() => {
84
+ const hookResult = useFireproof(dbName);
85
+ database = hookResult.database;
86
+ useAllDocs = hookResult.useAllDocs;
87
+ return useAllDocs<{ fruit: string }>();
88
+ });
89
+
90
+ // Wait for the hook to initialize with data
91
+ await waitFor(() => {
92
+ expect(result.current.docs.length).toBe(3);
93
+ });
94
+
95
+ // Add a document to test subscription works
96
+ await database?.put({ fruit: "date" });
97
+
98
+ // Verify the hook updates with the new document
99
+ await waitFor(() => {
100
+ expect(result.current.docs.length).toBe(4);
101
+ });
102
+
103
+ // Unmount the component to trigger cleanup
104
+ unmount();
105
+
106
+ // Test passes if no errors occur during unmount
107
+ },
108
+ TEST_TIMEOUT,
109
+ );
110
+
111
+ it(
112
+ "accepts query parameters",
113
+ async () => {
114
+ // This test verifies that the hook accepts query parameters
115
+ let allDocsResult: AllDocsResult<{ fruit: string }>;
116
+
117
+ renderHook(() => {
118
+ const hookResult = useFireproof(dbName);
119
+ database = hookResult.database;
120
+ useAllDocs = hookResult.useAllDocs;
121
+ // Pass query parameters to the hook
122
+ allDocsResult = useAllDocs<{ fruit: string }>({ descending: true });
123
+ });
124
+
125
+ // Wait for the hook to initialize
126
+ await waitFor(() => {
127
+ // Verify that the hook returns data regardless of parameters
128
+ expect(allDocsResult.docs.length).toBe(3);
129
+ // The current implementation doesn't filter client-side
130
+ });
131
+ },
132
+ TEST_TIMEOUT,
133
+ );
134
+
135
+ it(
136
+ "refreshes when query parameters change",
137
+ async () => {
138
+ // This test verifies that the useAllDocs hook refreshes when query parameters change
139
+ let allDocsResult: AllDocsResult<{ fruit: string }>;
140
+ let queryParams = {};
141
+
142
+ const { rerender } = renderHook(() => {
143
+ const hookResult = useFireproof(dbName);
144
+ database = hookResult.database;
145
+ useAllDocs = hookResult.useAllDocs;
146
+ allDocsResult = useAllDocs<{ fruit: string }>(queryParams);
147
+ });
148
+
149
+ // Verify initial state with no query parameters
150
+ await waitFor(() => {
151
+ expect(allDocsResult.docs.length).toBe(3);
152
+ });
153
+
154
+ // Change the query parameters
155
+ queryParams = { descending: true };
156
+ rerender();
157
+
158
+ // Verify the hook still works after query parameters change
159
+ // The implementation should handle the parameter change correctly
160
+ await waitFor(() => {
161
+ expect(allDocsResult.docs.length).toBe(3);
162
+ });
163
+ },
164
+ TEST_TIMEOUT,
165
+ );
166
+
167
+ afterEach(async () => {
168
+ await db.close();
169
+ await db.destroy();
170
+ await database?.close();
171
+ await database?.destroy();
172
+ });
173
+ });
@@ -2,9 +2,7 @@ import { renderHook, waitFor } from "@testing-library/react";
2
2
  import { describe, expect, it } from "vitest";
3
3
  import { fireproof, useFireproof } from "use-fireproof";
4
4
  import type { Database, DocResponse, LiveQueryResult, UseDocumentResult } from "use-fireproof";
5
- import { DocWithId } from "@fireproof/core";
6
5
 
7
- // Test timeout value for CI
8
6
  const TEST_TIMEOUT = 45000;
9
7
 
10
8
  describe("HOOK: useFireproof", () => {
@@ -73,93 +71,6 @@ describe("HOOK: useFireproof useLiveQuery has results", () => {
73
71
  });
74
72
  });
75
73
 
76
- // Separate describe block for array-like behavior test
77
- describe("HOOK: useFireproof useLiveQuery supports array-like behavior", () => {
78
- const dbName = "useLiveQueryArrayLike";
79
- let db: Database,
80
- database: ReturnType<typeof useFireproof>["database"],
81
- useLiveQuery: ReturnType<typeof useFireproof>["useLiveQuery"];
82
-
83
- beforeEach(async () => {
84
- const expectedValues = ["aha", "bar", "caz"];
85
- db = fireproof(dbName);
86
- for (const value of expectedValues) {
87
- await db.put({ foo: value });
88
- }
89
-
90
- const allDocs = await db.allDocs<{ foo: string }>();
91
- expect(allDocs.rows.map((row) => row.value.foo)).toEqual(expectedValues);
92
- });
93
-
94
- it(
95
- "supports array-like behavior",
96
- async () => {
97
- let arrayLikeQuery: LiveQueryResult<{ foo: string }, string>;
98
- let destructuredDocs: DocWithId<{ foo: string }>[];
99
-
100
- renderHook(() => {
101
- const result = useFireproof(dbName);
102
- database = result.database;
103
- useLiveQuery = result.useLiveQuery;
104
- arrayLikeQuery = useLiveQuery<{ foo: string }>("foo");
105
-
106
- // Test destructuring the docs property
107
- const { docs } = arrayLikeQuery;
108
- destructuredDocs = docs;
109
- });
110
-
111
- await waitFor(() => {
112
- // Verify destructured docs
113
- expect(destructuredDocs.length).toBe(3);
114
- expect(destructuredDocs.map((doc) => doc.foo)).toEqual(["aha", "bar", "caz"]);
115
-
116
- // Verify array-like behavior - need to use type assertions since our interface doesn't include these methods
117
- const arrayLike = arrayLikeQuery as unknown as {
118
- length: number;
119
- [Symbol.iterator](): Iterator<DocWithId<{ foo: string }>>;
120
- map<U>(fn: (doc: DocWithId<{ foo: string }>) => U): U[];
121
- filter(fn: (doc: DocWithId<{ foo: string }>) => boolean): DocWithId<{ foo: string }>[];
122
- forEach(fn: (doc: DocWithId<{ foo: string }>) => void): void;
123
- };
124
-
125
- // Test length property
126
- expect(arrayLike.length).toBe(3);
127
-
128
- // Test iteration
129
- const values: string[] = [];
130
- for (const doc of arrayLike) {
131
- values.push(doc.foo);
132
- }
133
- expect(values).toEqual(["aha", "bar", "caz"]);
134
-
135
- // Test map
136
- const mappedValues = arrayLike.map((doc) => doc.foo.toUpperCase());
137
- expect(mappedValues).toEqual(["AHA", "BAR", "CAZ"]);
138
-
139
- // Test filter
140
- const filtered = arrayLike.filter((doc) => doc.foo.includes("a"));
141
- expect(filtered.length).toBe(3);
142
- expect(filtered.map((doc) => doc.foo)).toEqual(["aha", "bar", "caz"]);
143
-
144
- // Test forEach
145
- const forEachValues: string[] = [];
146
- arrayLike.forEach((doc) => {
147
- forEachValues.push(doc.foo);
148
- });
149
- expect(forEachValues).toEqual(["aha", "bar", "caz"]);
150
- });
151
- },
152
- TEST_TIMEOUT,
153
- );
154
-
155
- afterEach(async () => {
156
- await db.close();
157
- await db.destroy();
158
- await database?.close();
159
- await database?.destroy();
160
- });
161
- });
162
-
163
74
  describe("HOOK: useFireproof useDocument has results", () => {
164
75
  const dbName = "useDocumentHasResults";
165
76
  let db: Database,