@fireproof/core 0.20.0-dev-preview-40 → 0.20.0-dev-preview-50

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.
Files changed (45) hide show
  1. package/README.md +6 -4
  2. package/deno/index.js +2 -2
  3. package/deno/index.js.map +1 -1
  4. package/deno.json +3 -2
  5. package/index.cjs +955 -599
  6. package/index.cjs.map +1 -1
  7. package/index.d.cts +334 -127
  8. package/index.d.ts +334 -127
  9. package/index.js +939 -582
  10. package/index.js.map +1 -1
  11. package/indexeddb/index.cjs.map +1 -1
  12. package/indexeddb/index.js.map +1 -1
  13. package/indexeddb/metafile-cjs.json +1 -1
  14. package/indexeddb/metafile-esm.json +1 -1
  15. package/metafile-cjs.json +1 -1
  16. package/metafile-esm.json +1 -1
  17. package/package.json +7 -5
  18. package/react/index.cjs +17 -9
  19. package/react/index.cjs.map +1 -1
  20. package/react/index.d.cts +5 -4
  21. package/react/index.d.ts +5 -4
  22. package/react/index.js +17 -9
  23. package/react/index.js.map +1 -1
  24. package/react/metafile-cjs.json +1 -1
  25. package/react/metafile-esm.json +1 -1
  26. package/tests/blockstore/interceptor-gateway.test.ts +15 -1
  27. package/tests/blockstore/keyed-crypto-indexeddb-file.test.ts +8 -18
  28. package/tests/blockstore/keyed-crypto.test.ts +31 -53
  29. package/tests/blockstore/loader.test.ts +21 -19
  30. package/tests/blockstore/store.test.ts +52 -56
  31. package/tests/blockstore/transaction.test.ts +13 -11
  32. package/tests/fireproof/all-gateway.test.ts +53 -50
  33. package/tests/fireproof/attachable.test.ts +356 -0
  34. package/tests/fireproof/crdt.test.ts +100 -60
  35. package/tests/fireproof/database.test.ts +95 -54
  36. package/tests/fireproof/fireproof.test.ts +58 -55
  37. package/tests/fireproof/hello.test.ts +4 -4
  38. package/tests/fireproof/indexer.test.ts +44 -44
  39. package/tests/fireproof/stable-cid.test.ts +69 -0
  40. package/tests/fireproof/utils.test.ts +21 -10
  41. package/tests/gateway/file/loader-config.test.ts +25 -25
  42. package/tests/gateway/fp-envelope-serialize.test.ts +8 -8
  43. package/tests/gateway/indexeddb/loader-config.test.ts +6 -6
  44. package/tests/helpers.ts +81 -2
  45. package/tests/react/useFireproof.test.tsx +59 -17
package/react/index.js CHANGED
@@ -21,7 +21,7 @@ function useFireproof(name = "useFireproof", config = {}) {
21
21
  }
22
22
  const originalInitialDoc = useMemo(() => deepClone({ ...initialDoc }), []);
23
23
  const [doc, setDoc] = useState(initialDoc);
24
- const refreshDoc = useCallback(async () => {
24
+ const refresh = useCallback(async () => {
25
25
  const gotDoc = doc._id ? await database.get(doc._id).catch(() => initialDoc) : initialDoc;
26
26
  setDoc(gotDoc);
27
27
  }, [doc._id]);
@@ -64,11 +64,11 @@ function useFireproof(name = "useFireproof", config = {}) {
64
64
  const updateDoc = useCallback(
65
65
  (newDoc, opts = { replace: false, reset: false }) => {
66
66
  if (!newDoc) {
67
- return opts.reset ? reset() : refreshDoc();
67
+ return opts.reset ? reset() : refresh();
68
68
  }
69
69
  return opts.replace ? replace(newDoc) : merge(newDoc);
70
70
  },
71
- [refreshDoc, reset, replace, merge]
71
+ [refresh, reset, replace, merge]
72
72
  );
73
73
  useEffect(() => {
74
74
  if (!doc._id) return;
@@ -77,14 +77,21 @@ function useFireproof(name = "useFireproof", config = {}) {
77
77
  return;
78
78
  }
79
79
  if (changes.find((c) => c._id === doc._id)) {
80
- void refreshDoc();
80
+ void refresh();
81
81
  }
82
82
  }, true);
83
- }, [doc._id, refreshDoc]);
83
+ }, [doc._id, refresh]);
84
84
  useEffect(() => {
85
- void refreshDoc();
86
- }, [refreshDoc]);
87
- const refresh = useCallback(() => void refreshDoc(), [refreshDoc]);
85
+ void refresh();
86
+ }, [refresh]);
87
+ const submit = useCallback(
88
+ async (e) => {
89
+ if (e?.preventDefault) e.preventDefault();
90
+ await save();
91
+ reset();
92
+ },
93
+ [save, reset]
94
+ );
88
95
  const apiObject = {
89
96
  doc: { ...doc },
90
97
  merge,
@@ -92,7 +99,8 @@ function useFireproof(name = "useFireproof", config = {}) {
92
99
  reset,
93
100
  refresh,
94
101
  save,
95
- remove
102
+ remove,
103
+ submit
96
104
  };
97
105
  const tuple = [{ ...doc }, updateDoc, save, remove, reset, refresh];
98
106
  Object.assign(apiObject, tuple);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/react/useFireproof.ts","../../../src/react/useDocument.ts","../../../src/react/useLiveQuery.ts","../../../src/react/useAllDocs.ts","../../../src/react/useChanges.ts"],"sourcesContent":["import type {\n ConfigOpts,\n DocFragment,\n DocResponse,\n DocSet,\n DocTypes,\n DocWithId,\n IndexKeyType,\n IndexRow,\n MapFn,\n QueryOpts,\n Database,\n} from \"@fireproof/core\";\nimport { fireproof } from \"@fireproof/core\";\nimport { useCallback, useEffect, useMemo, useState, useRef } from \"react\";\nimport type { AllDocsQueryOpts, ChangesOptions, ClockHead } from \"@fireproof/core\";\n\nexport interface LiveQueryResult<T extends DocTypes, K extends IndexKeyType, R extends DocFragment = T> {\n readonly docs: DocWithId<T>[];\n readonly rows: IndexRow<K, T, R>[];\n /** @internal */\n readonly length: number;\n /** @internal */\n map<U>(callbackfn: (value: DocWithId<T>, index: number, array: DocWithId<T>[]) => U): U[];\n /** @internal */\n filter(predicate: (value: DocWithId<T>, index: number, array: DocWithId<T>[]) => boolean): DocWithId<T>[];\n /** @internal */\n forEach(callbackfn: (value: DocWithId<T>, index: number, array: DocWithId<T>[]) => void): void;\n /** @internal */\n [Symbol.iterator](): Iterator<DocWithId<T>>;\n}\n\nexport type UseLiveQuery = <T extends DocTypes, K extends IndexKeyType = string, R extends DocFragment = T>(\n mapFn: string | MapFn<T>,\n query?: QueryOpts<K>,\n initialRows?: IndexRow<K, T, R>[],\n) => LiveQueryResult<T, K, R>;\n\nexport interface AllDocsResult<T extends DocTypes> {\n readonly docs: DocWithId<T>[];\n}\n\nexport interface ChangesResult<T extends DocTypes> {\n readonly docs: DocWithId<T>[];\n}\n\nexport type UseAllDocs = <T extends DocTypes>(query?: AllDocsQueryOpts) => AllDocsResult<T>;\n\nexport type UseChanges = <T extends DocTypes>(since: ClockHead, opts: ChangesOptions) => ChangesResult<T>;\n\ninterface UpdateDocFnOptions {\n readonly replace?: boolean;\n readonly reset?: boolean;\n}\n\ntype UpdateDocFn<T extends DocTypes> = (newDoc?: DocSet<T>, options?: UpdateDocFnOptions) => void;\n\ntype StoreDocFn<T extends DocTypes> = (existingDoc?: DocWithId<T>) => Promise<DocResponse>;\n\ntype DeleteDocFn<T extends DocTypes> = (existingDoc?: DocWithId<T>) => Promise<DocResponse>;\n\ntype UseDocumentResultTuple<T extends DocTypes> = [DocWithId<T>, UpdateDocFn<T>, StoreDocFn<T>, DeleteDocFn<T>];\n\ninterface UseDocumentResultObject<T extends DocTypes> {\n doc: DocWithId<T>;\n merge: (newDoc: Partial<T>) => void;\n replace: (newDoc: T) => void;\n reset: () => void;\n refresh: () => void;\n save: StoreDocFn<T>;\n remove: DeleteDocFn<T>;\n}\n\nexport type UseDocumentResult<T extends DocTypes> = UseDocumentResultObject<T> & UseDocumentResultTuple<T>;\n\nexport type UseDocumentInitialDocOrFn<T extends DocTypes> = DocSet<T> | (() => DocSet<T>);\nexport type UseDocument = <T extends DocTypes>(initialDocOrFn: UseDocumentInitialDocOrFn<T>) => UseDocumentResult<T>;\n\nexport interface UseFireproof {\n readonly database: Database;\n /**\n * ## Summary\n *\n * React hook that provides the ability to create/update/save new Fireproof documents into your custom Fireproof database.\n * The creation occurs when you do not pass in an `_id` as part of your initial document -- the database will assign a new\n * one when you call the provided `save` handler. The hook also provides generics support so you can inline your custom type into\n * the invocation to receive type-safety and auto-complete support in your IDE.\n *\n * ## Usage\n *\n * ```tsx\n * const todo = useDocument<Todo>({\n * text: '',\n * date: Date.now(),\n * completed: false\n * })\n * // Access via object properties\n * todo.doc // The current document\n * todo.merge({ completed: true }) // Update specific fields\n * todo.replace({ text: 'new', date: Date.now(), completed: false }) // Replace entire doc\n * todo.save() // Save changes\n * todo.remove() // Delete document\n * todo.reset() // Reset to initial state\n * todo.refresh() // Refresh from database\n *\n * // Or use tuple destructuring for legacy compatibility\n * const [doc, updateDoc, saveDoc, removeDoc] = todo\n * ```\n *\n * ## Overview\n *\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useLiveQuery` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\n readonly useDocument: UseDocument;\n /**\n * ## Summary\n * React hook that provides access to live query results, enabling real-time updates in your app.\n *\n * ## Usage\n * ```tsx\n * const result = useLiveQuery(\"date\"); // using string key\n * const result = useLiveQuery('date', { limit: 10, descending: true }) // key + options\n * const result = useLiveQuery<CustomType>(\"date\"); // using generics\n * const result = useLiveQuery((doc) => doc.date)); // using map function\n * ```\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useLiveQuery` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\n readonly useLiveQuery: UseLiveQuery;\n /**\n * ## Summary\n * React hook that provides access to all documents in the database, sorted by `_id`.\n *\n * ## Usage\n * ```tsx\n * const result = useAllDocs({ limit: 10, descending: true }); // with options\n * const result = useAllDocs(); // without options\n * ```\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useAllDocs` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\n readonly useAllDocs: UseAllDocs;\n /**\n * ## Summary\n * React hook that provides access to all new documents in the database added since the last time the changes was called\n *\n * ## Usage\n * ```tsx\n * const result = useChanges(prevresult.clock,{limit:10}); // with options\n * const result = useChanges(); // without options\n * ```\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useAllDocs`, `useChanges` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\n readonly useChanges: UseChanges;\n}\n\n/**\n * @deprecated Use the `useFireproof` hook instead\n */\nexport const FireproofCtx = {} as UseFireproof;\n\nfunction deepClone<T>(value: T): T {\n if (typeof structuredClone !== \"undefined\") {\n return structuredClone(value);\n } else {\n // Fallback if structuredClone is not available (older browsers, older Node versions, etc.)\n return JSON.parse(JSON.stringify(value));\n }\n}\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 * ## Overview\n *\n * TL;DR: Only use this hook if you need to configure a database name other than the default `useFireproof`.\n *\n * For most applications, using the `useLiveQuery` or `useDocument` hooks exported from `use-fireproof` should\n * suffice for the majority of use-cases. Under the hood, they act against a database named `useFireproof` instantiated with\n * default configurations. However, if you need to do a custom database setup or configure a database name more to your liking\n * than the default `useFireproof`, then use `useFireproof` as it exists for that purpose. It will provide you with the\n * custom database accessor and *lexically scoped* versions of `useLiveQuery` and `useDocument` that act against said\n * custom database.\n *\n */\nexport function useFireproof(name: string | Database = \"useFireproof\", config: ConfigOpts = {}): UseFireproof {\n const database = typeof name === \"string\" ? fireproof(name, config) : name;\n\n // Tracks whether we've done a local update (merge, replace, or reset)\n const updateHappenedRef = useRef(false);\n\n function useDocument<T extends DocTypes>(initialDocOrFn?: UseDocumentInitialDocOrFn<T>): UseDocumentResult<T> {\n // Get fresh initialDoc value\n let initialDoc: DocSet<T>;\n if (typeof initialDocOrFn === \"function\") {\n initialDoc = initialDocOrFn();\n } else {\n initialDoc = initialDocOrFn ?? ({} as T);\n }\n\n // Store the original initial doc without _id for resets\n const originalInitialDoc = useMemo(() => deepClone({ ...initialDoc }), []);\n\n // We do not want to force consumers to memoize their initial document so we do it for them.\n // We use the stringified generator function to ensure that the memoization is stable across renders.\n // const initialDoc = useMemo(initialDocFn, [initialDocFn.toString()]);\n const [doc, setDoc] = useState(initialDoc);\n\n const refreshDoc = useCallback(async () => {\n // todo add option for mvcc checks\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 // This signals \"I'm applying local changes to DB, so let's go back to 'synced' mode\"\n updateHappenedRef.current = false;\n\n const toSave = existingDoc ?? doc;\n const res = await database.put(toSave);\n\n // If updateHappenedRef is *still* false after the save,\n // you can set _id or do any other \"subscription-friendly\" steps\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() : refreshDoc();\n }\n return opts.replace ? replace(newDoc as T) : merge(newDoc);\n },\n [refreshDoc, 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 refreshDoc();\n }\n }, true);\n }, [doc._id, refreshDoc]);\n\n useEffect(() => {\n void refreshDoc();\n }, [refreshDoc]);\n\n const refresh = useCallback(() => void refreshDoc(), [refreshDoc]);\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 };\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 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 const docs = initialRows.map((r) => r.doc).filter((r): r is DocWithId<T> => !!r);\n return {\n rows: initialRows,\n docs,\n length: docs.length,\n map: (fn) => docs.map(fn),\n filter: (fn) => docs.filter(fn),\n forEach: (fn) => docs.forEach(fn),\n [Symbol.iterator]: () => docs[Symbol.iterator](),\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 as DocWithId<T>).filter((r): r is DocWithId<T> => !!r);\n setResult({\n ...res,\n docs,\n length: docs.length,\n map: (fn) => docs.map(fn),\n filter: (fn) => docs.filter(fn),\n forEach: (fn) => docs.forEach(fn),\n [Symbol.iterator]: () => docs[Symbol.iterator](),\n });\n }, [mapFnString, queryString]);\n\n useEffect(() => {\n refreshRows(); // Initial data fetch\n return database.subscribe(refreshRows);\n }, [refreshRows]);\n\n return result;\n }\n\n 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 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 return { database, useLiveQuery, useDocument, useAllDocs, useChanges };\n}\n","import { Database, DocTypes, DocWithId } from \"@fireproof/core\";\n\nimport { UseDocument, UseDocumentResult, useFireproof } from \"./useFireproof.js\";\n\nexport interface TLUseDocument {\n <T extends DocTypes>(initialDoc: DocWithId<T>): UseDocumentResult<T>;\n database: Database;\n}\n\nfunction topLevelUseDocument(...args: Parameters<UseDocument>) {\n const { useDocument, database } = useFireproof();\n (topLevelUseDocument as TLUseDocument).database = database;\n return useDocument(...args);\n}\n\n/**\n * ## Summary\n *\n * React hook that provides the ability to create and manage Fireproof documents. The creation occurs when\n * you do not pass in an `_id` as part of your initial document -- the database will assign a new one when\n * you call the provided `save` handler.\n *\n * ## Usage\n *\n * ```tsx\n * const todo = useDocument({\n * text: '',\n * date: Date.now(),\n * completed: false\n * })\n * // Access via object properties\n * todo.doc // The current document\n * todo.merge({ completed: true }) // Update specific fields\n * todo.replace({ text: 'new', date: Date.now(), completed: false }) // Replace entire doc\n * todo.save() // Save changes\n * todo.remove() // Delete document\n * todo.reset() // Reset to initial state\n * todo.refresh() // Refresh from database\n * ```\n *\n * ### Create document with custom ID\n * Custom IDs let you create predictable document identifiers for data that has\n * a natural unique key, like userIds or email addresses. This makes it easy to\n * look up and update specific documents without having to query for them first.\n * For example, storing user profiles by customerId:\n *\n * ```tsx\n * const profile = useDocument({\n * _id: `${props.customerId}-profile`, // Predictable ID based on customerId\n * name: \"\",\n * company: \"\",\n * startedAt: Date.now()\n * })\n * ```\n *\n * ## API\n *\n * - `doc`: The current document state\n * - `merge(newDoc)`: Merge new properties into the document\n * - `replace(newDoc)`: Replace the entire document\n * - `reset()`: Reset to initial state\n * - `refresh()`: Refresh from database\n * - `save()`: Save changes to the document\n * - `remove()`: Delete the document\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useLiveQuery` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\nexport const useDocument = topLevelUseDocument as TLUseDocument;\n","import { Database, DocFragment, DocTypes, IndexKeyType } from \"@fireproof/core\";\n\nimport { LiveQueryResult, useFireproof, UseLiveQuery } from \"./useFireproof.js\";\n\nexport interface TLUseLiveQuery {\n <T extends DocTypes, K extends IndexKeyType, R extends DocFragment = T>(\n ...args: Parameters<UseLiveQuery>\n ): LiveQueryResult<T, K, R>;\n database: Database;\n}\n\nfunction topLevelUseLiveQuery(...args: Parameters<UseLiveQuery>) {\n const { useLiveQuery, database } = useFireproof();\n (topLevelUseLiveQuery as TLUseLiveQuery).database = database;\n return useLiveQuery(...args);\n}\n\n/**\n * ## Summary\n * React hook that provides access to live query results, enabling real-time updates in your app. This uses\n * the default database named \"useFireproof\" under the hood which you can also access via the `database` accessor.\n *\n * ## Usage\n * ```tsx\n * const results = useLiveQuery(\"date\"); // using string\n * const results = useLiveQuery((doc) => doc.date)); // using map function\n * const database = useLiveQuery.database; // underlying \"useFireproof\" database accessor\n * ```\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useLiveQuery` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\nexport const useLiveQuery = topLevelUseLiveQuery as TLUseLiveQuery;\n","import { Database, DocTypes } from \"@fireproof/core\";\n\nimport { AllDocsResult, useFireproof, UseAllDocs } from \"./useFireproof.js\";\n\nexport interface TLUseAllDocs {\n <T extends DocTypes>(...args: Parameters<UseAllDocs>): AllDocsResult<T>;\n database: Database;\n}\n\nfunction topLevelUseAllDocs(...args: Parameters<UseAllDocs>) {\n const { useAllDocs, database } = useFireproof();\n (topLevelUseAllDocs as TLUseAllDocs).database = database;\n return useAllDocs(...args);\n}\n\n/**\n * ## Summary\n * React hook that provides access to all documents in the database, sorted by `_id`.\n *\n * ## Usage\n * ```tsx\n * const result = useAllDocs({ limit: 10, descending: true }); // with options\n * const result = useAllDocs(); // without options\n * const database = useAllDocs.database; // underlying \"useFireproof\" database accessor\n * ```\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useAllDocs` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\nexport const useAllDocs = topLevelUseAllDocs as TLUseAllDocs;\n","import { DocTypes, Database } from \"@fireproof/core\";\n\nimport { ChangesResult, useFireproof, UseChanges } from \"./useFireproof.js\";\n\nexport interface TLUseChanges {\n <T extends DocTypes>(...args: Parameters<UseChanges>): ChangesResult<T>;\n database: Database;\n}\n\nfunction topLevelUseChanges(...args: Parameters<UseChanges>) {\n const { useChanges, database } = useFireproof();\n (topLevelUseChanges as TLUseChanges).database = database;\n return useChanges(...args);\n}\n\n/**\n * ## Summary\n * React hook that provides access to all new documents in the database added since the last time the changes was called\n *\n * ## Usage\n * ```tsx\n * const result = useChanges(prevresult.clock,{limit:10}); // with options\n * const result = useChanges(); // without options\n * const database = useChanges.database; // underlying \"useFireproof\" database accessor\n * ```\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useAllDocs`, `useChanges` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\nexport const useChanges = topLevelUseChanges as TLUseChanges;\n"],"mappings":"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","names":["useDocument","useLiveQuery","useAllDocs","useChanges","useDocument","useLiveQuery","useAllDocs","useChanges"]}
1
+ {"version":3,"sources":["../../../src/react/useFireproof.ts","../../../src/react/useDocument.ts","../../../src/react/useLiveQuery.ts","../../../src/react/useAllDocs.ts","../../../src/react/useChanges.ts"],"sourcesContent":["import type {\n ConfigOpts,\n DocFragment,\n DocResponse,\n DocSet,\n DocTypes,\n DocWithId,\n IndexKeyType,\n IndexRow,\n MapFn,\n QueryOpts,\n Database,\n} from \"@fireproof/core\";\nimport { fireproof } from \"@fireproof/core\";\nimport { useCallback, useEffect, useMemo, useState, useRef } from \"react\";\nimport type { AllDocsQueryOpts, ChangesOptions, ClockHead } from \"@fireproof/core\";\n\nexport interface LiveQueryResult<T extends DocTypes, K extends IndexKeyType, R extends DocFragment = T> {\n readonly docs: DocWithId<T>[];\n readonly rows: IndexRow<K, T, R>[];\n /** @internal */\n readonly length: number;\n /** @internal */\n map<U>(callbackfn: (value: DocWithId<T>, index: number, array: DocWithId<T>[]) => U): U[];\n /** @internal */\n filter(predicate: (value: DocWithId<T>, index: number, array: DocWithId<T>[]) => boolean): DocWithId<T>[];\n /** @internal */\n forEach(callbackfn: (value: DocWithId<T>, index: number, array: DocWithId<T>[]) => void): void;\n /** @internal */\n [Symbol.iterator](): Iterator<DocWithId<T>>;\n}\n\nexport type UseLiveQuery = <T extends DocTypes, K extends IndexKeyType = string, R extends DocFragment = T>(\n mapFn: string | MapFn<T>,\n query?: QueryOpts<K>,\n initialRows?: IndexRow<K, T, R>[],\n) => LiveQueryResult<T, K, R>;\n\nexport interface AllDocsResult<T extends DocTypes> {\n readonly docs: DocWithId<T>[];\n}\n\nexport interface ChangesResult<T extends DocTypes> {\n readonly docs: DocWithId<T>[];\n}\n\nexport type UseAllDocs = <T extends DocTypes>(query?: AllDocsQueryOpts) => AllDocsResult<T>;\n\nexport type UseChanges = <T extends DocTypes>(since: ClockHead, opts: ChangesOptions) => ChangesResult<T>;\n\ninterface UpdateDocFnOptions {\n readonly replace?: boolean;\n readonly reset?: boolean;\n}\n\ntype UpdateDocFn<T extends DocTypes> = (newDoc?: DocSet<T>, options?: UpdateDocFnOptions) => void;\n\ntype StoreDocFn<T extends DocTypes> = (existingDoc?: DocWithId<T>) => Promise<DocResponse>;\n\ntype DeleteDocFn<T extends DocTypes> = (existingDoc?: DocWithId<T>) => Promise<DocResponse>;\n\ntype UseDocumentResultTuple<T extends DocTypes> = [DocWithId<T>, UpdateDocFn<T>, StoreDocFn<T>, DeleteDocFn<T>];\n\ninterface UseDocumentResultObject<T extends DocTypes> {\n doc: DocWithId<T>;\n merge: (newDoc: Partial<T>) => void;\n replace: (newDoc: T) => void;\n reset: () => void;\n refresh: () => Promise<void>;\n save: StoreDocFn<T>;\n remove: DeleteDocFn<T>;\n submit: (e?: Event) => Promise<void>;\n}\n\nexport type UseDocumentResult<T extends DocTypes> = UseDocumentResultObject<T> & UseDocumentResultTuple<T>;\n\nexport type UseDocumentInitialDocOrFn<T extends DocTypes> = DocSet<T> | (() => DocSet<T>);\nexport type UseDocument = <T extends DocTypes>(initialDocOrFn: UseDocumentInitialDocOrFn<T>) => UseDocumentResult<T>;\n\nexport interface UseFireproof {\n readonly database: Database;\n /**\n * ## Summary\n *\n * React hook that provides the ability to create/update/save new Fireproof documents into your custom Fireproof database.\n * The creation occurs when you do not pass in an `_id` as part of your initial document -- the database will assign a new\n * one when you call the provided `save` handler. The hook also provides generics support so you can inline your custom type into\n * the invocation to receive type-safety and auto-complete support in your IDE.\n *\n * ## Usage\n *\n * ```tsx\n * const todo = useDocument<Todo>({\n * text: '',\n * date: Date.now(),\n * completed: false\n * })\n * // Access via object properties\n * todo.doc // The current document\n * todo.merge({ completed: true }) // Update specific fields\n * todo.replace({ text: 'new', date: Date.now(), completed: false }) // Replace entire doc\n * todo.save() // Save changes\n * todo.remove() // Delete document\n * todo.reset() // Reset to initial state\n * todo.refresh() // Refresh from database\n *\n * // Or use tuple destructuring for legacy compatibility\n * const [doc, updateDoc, saveDoc, removeDoc] = todo\n * ```\n *\n * ## Overview\n *\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useLiveQuery` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\n readonly useDocument: UseDocument;\n /**\n * ## Summary\n * React hook that provides access to live query results, enabling real-time updates in your app.\n *\n * ## Usage\n * ```tsx\n * const result = useLiveQuery(\"date\"); // using string key\n * const result = useLiveQuery('date', { limit: 10, descending: true }) // key + options\n * const result = useLiveQuery<CustomType>(\"date\"); // using generics\n * const result = useLiveQuery((doc) => doc.date)); // using map function\n * ```\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useLiveQuery` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\n readonly useLiveQuery: UseLiveQuery;\n /**\n * ## Summary\n * React hook that provides access to all documents in the database, sorted by `_id`.\n *\n * ## Usage\n * ```tsx\n * const result = useAllDocs({ limit: 10, descending: true }); // with options\n * const result = useAllDocs(); // without options\n * ```\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useAllDocs` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\n readonly useAllDocs: UseAllDocs;\n /**\n * ## Summary\n * React hook that provides access to all new documents in the database added since the last time the changes was called\n *\n * ## Usage\n * ```tsx\n * const result = useChanges(prevresult.clock,{limit:10}); // with options\n * const result = useChanges(); // without options\n * ```\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useAllDocs`, `useChanges` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\n readonly useChanges: UseChanges;\n}\n\n/**\n * @deprecated Use the `useFireproof` hook instead\n */\nexport const FireproofCtx = {} as UseFireproof;\n\nfunction deepClone<T>(value: T): T {\n if (typeof structuredClone !== \"undefined\") {\n return structuredClone(value);\n } else {\n // Fallback if structuredClone is not available (older browsers, older Node versions, etc.)\n return JSON.parse(JSON.stringify(value));\n }\n}\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 * ## Overview\n *\n * TL;DR: Only use this hook if you need to configure a database name other than the default `useFireproof`.\n *\n * For most applications, using the `useLiveQuery` or `useDocument` hooks exported from `use-fireproof` should\n * suffice for the majority of use-cases. Under the hood, they act against a database named `useFireproof` instantiated with\n * default configurations. However, if you need to do a custom database setup or configure a database name more to your liking\n * than the default `useFireproof`, then use `useFireproof` as it exists for that purpose. It will provide you with the\n * custom database accessor and *lexically scoped* versions of `useLiveQuery` and `useDocument` that act against said\n * custom database.\n *\n */\nexport function useFireproof(name: string | Database = \"useFireproof\", config: ConfigOpts = {}): UseFireproof {\n const database = typeof name === \"string\" ? fireproof(name, config) : name;\n\n const updateHappenedRef = useRef(false);\n\n function useDocument<T extends DocTypes>(initialDocOrFn?: UseDocumentInitialDocOrFn<T>): UseDocumentResult<T> {\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 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 const docs = initialRows.map((r) => r.doc).filter((r): r is DocWithId<T> => !!r);\n return {\n rows: initialRows,\n docs,\n length: docs.length,\n map: (fn) => docs.map(fn),\n filter: (fn) => docs.filter(fn),\n forEach: (fn) => docs.forEach(fn),\n [Symbol.iterator]: () => docs[Symbol.iterator](),\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 as DocWithId<T>).filter((r): r is DocWithId<T> => !!r);\n setResult({\n ...res,\n docs,\n length: docs.length,\n map: (fn) => docs.map(fn),\n filter: (fn) => docs.filter(fn),\n forEach: (fn) => docs.forEach(fn),\n [Symbol.iterator]: () => docs[Symbol.iterator](),\n });\n }, [mapFnString, queryString]);\n\n useEffect(() => {\n refreshRows(); // Initial data fetch\n return database.subscribe(refreshRows);\n }, [refreshRows]);\n\n return result;\n }\n\n 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 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 return { database, useLiveQuery, useDocument, useAllDocs, useChanges };\n}\n","import { Database, DocTypes, DocWithId } from \"@fireproof/core\";\n\nimport { UseDocument, UseDocumentResult, useFireproof } from \"./useFireproof.js\";\n\nexport interface TLUseDocument {\n <T extends DocTypes>(initialDoc: DocWithId<T>): UseDocumentResult<T>;\n database: Database;\n}\n\nfunction topLevelUseDocument(...args: Parameters<UseDocument>) {\n const { useDocument, database } = useFireproof();\n (topLevelUseDocument as TLUseDocument).database = database;\n return useDocument(...args);\n}\n\n/**\n * ## Summary\n *\n * React hook that provides the ability to create and manage Fireproof documents. The creation occurs when\n * you do not pass in an `_id` as part of your initial document -- the database will assign a new one when\n * you call the provided `save` handler.\n *\n * ## Usage\n *\n * ```tsx\n * const todo = useDocument({\n * text: '',\n * date: Date.now(),\n * completed: false\n * })\n * // Access via object properties\n * todo.doc // The current document\n * todo.merge({ completed: true }) // Update specific fields\n * todo.replace({ text: 'new', date: Date.now(), completed: false }) // Replace entire doc\n * todo.save() // Save changes\n * todo.remove() // Delete document\n * todo.reset() // Reset to initial state\n * todo.refresh() // Refresh from database\n * ```\n *\n * ### Create document with custom ID\n * Custom IDs let you create predictable document identifiers for data that has\n * a natural unique key, like userIds or email addresses. This makes it easy to\n * look up and update specific documents without having to query for them first.\n * For example, storing user profiles by customerId:\n *\n * ```tsx\n * const profile = useDocument({\n * _id: `${props.customerId}-profile`, // Predictable ID based on customerId\n * name: \"\",\n * company: \"\",\n * startedAt: Date.now()\n * })\n * ```\n *\n * ## API\n *\n * - `doc`: The current document state\n * - `merge(newDoc)`: Merge new properties into the document\n * - `replace(newDoc)`: Replace the entire document\n * - `reset()`: Reset to initial state\n * - `refresh()`: Refresh from database\n * - `save()`: Save changes to the document\n * - `remove()`: Delete the document\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useLiveQuery` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\nexport const useDocument = topLevelUseDocument as TLUseDocument;\n","import { Database, DocFragment, DocTypes, IndexKeyType } from \"@fireproof/core\";\n\nimport { LiveQueryResult, useFireproof, UseLiveQuery } from \"./useFireproof.js\";\n\nexport interface TLUseLiveQuery {\n <T extends DocTypes, K extends IndexKeyType, R extends DocFragment = T>(\n ...args: Parameters<UseLiveQuery>\n ): LiveQueryResult<T, K, R>;\n database: Database;\n}\n\nfunction topLevelUseLiveQuery(...args: Parameters<UseLiveQuery>) {\n const { useLiveQuery, database } = useFireproof();\n (topLevelUseLiveQuery as TLUseLiveQuery).database = database;\n return useLiveQuery(...args);\n}\n\n/**\n * ## Summary\n * React hook that provides access to live query results, enabling real-time updates in your app. This uses\n * the default database named \"useFireproof\" under the hood which you can also access via the `database` accessor.\n *\n * ## Usage\n * ```tsx\n * const results = useLiveQuery(\"date\"); // using string\n * const results = useLiveQuery((doc) => doc.date)); // using map function\n * const database = useLiveQuery.database; // underlying \"useFireproof\" database accessor\n * ```\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useLiveQuery` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\nexport const useLiveQuery = topLevelUseLiveQuery as TLUseLiveQuery;\n","import { Database, DocTypes } from \"@fireproof/core\";\n\nimport { AllDocsResult, useFireproof, UseAllDocs } from \"./useFireproof.js\";\n\nexport interface TLUseAllDocs {\n <T extends DocTypes>(...args: Parameters<UseAllDocs>): AllDocsResult<T>;\n database: Database;\n}\n\nfunction topLevelUseAllDocs(...args: Parameters<UseAllDocs>) {\n const { useAllDocs, database } = useFireproof();\n (topLevelUseAllDocs as TLUseAllDocs).database = database;\n return useAllDocs(...args);\n}\n\n/**\n * ## Summary\n * React hook that provides access to all documents in the database, sorted by `_id`.\n *\n * ## Usage\n * ```tsx\n * const result = useAllDocs({ limit: 10, descending: true }); // with options\n * const result = useAllDocs(); // without options\n * const database = useAllDocs.database; // underlying \"useFireproof\" database accessor\n * ```\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useAllDocs` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\nexport const useAllDocs = topLevelUseAllDocs as TLUseAllDocs;\n","import { DocTypes, Database } from \"@fireproof/core\";\n\nimport { ChangesResult, useFireproof, UseChanges } from \"./useFireproof.js\";\n\nexport interface TLUseChanges {\n <T extends DocTypes>(...args: Parameters<UseChanges>): ChangesResult<T>;\n database: Database;\n}\n\nfunction topLevelUseChanges(...args: Parameters<UseChanges>) {\n const { useChanges, database } = useFireproof();\n (topLevelUseChanges as TLUseChanges).database = database;\n return useChanges(...args);\n}\n\n/**\n * ## Summary\n * React hook that provides access to all new documents in the database added since the last time the changes was called\n *\n * ## Usage\n * ```tsx\n * const result = useChanges(prevresult.clock,{limit:10}); // with options\n * const result = useChanges(); // without options\n * const database = useChanges.database; // underlying \"useFireproof\" database accessor\n * ```\n *\n * ## Overview\n * Changes made via remote sync peers, or other members of your cloud replica group will appear automatically\n * when you use the `useAllDocs`, `useChanges` and `useDocument` APIs. By default, Fireproof stores data in the browser's\n * local storage.\n */\nexport const useChanges = topLevelUseChanges as TLUseChanges;\n"],"mappings":"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","names":["useDocument","useLiveQuery","useAllDocs","useChanges","useDocument","useLiveQuery","useAllDocs","useChanges"]}
@@ -1 +1 @@
1
- {"inputs":{"src/react/useFireproof.ts":{"bytes":14885,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/useDocument.ts":{"bytes":2460,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/useLiveQuery.ts":{"bytes":1409,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/useAllDocs.ts":{"bytes":1146,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/useChanges.ts":{"bytes":1191,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/index.ts":{"bytes":971,"imports":[{"path":"src/react/useDocument.ts","kind":"import-statement","original":"./useDocument.js"},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"},{"path":"src/react/useLiveQuery.ts","kind":"import-statement","original":"./useLiveQuery.js"},{"path":"src/react/useAllDocs.ts","kind":"import-statement","original":"./useAllDocs.js"},{"path":"src/react/useChanges.ts","kind":"import-statement","original":"./useChanges.js"}],"format":"esm"}},"outputs":{"dist/fireproof-core/react/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":28587},"dist/fireproof-core/react/index.cjs":{"imports":[{"path":"@fireproof/core","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true}],"exports":[],"entryPoint":"src/react/index.ts","inputs":{"src/react/index.ts":{"bytesInOutput":305},"src/react/useFireproof.ts":{"bytesInOutput":6288},"src/react/useDocument.ts":{"bytesInOutput":222},"src/react/useLiveQuery.ts":{"bytesInOutput":229},"src/react/useAllDocs.ts":{"bytesInOutput":215},"src/react/useChanges.ts":{"bytesInOutput":215}},"bytes":8441}}}
1
+ {"inputs":{"src/react/useFireproof.ts":{"bytes":14322,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/useDocument.ts":{"bytes":2460,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/useLiveQuery.ts":{"bytes":1409,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/useAllDocs.ts":{"bytes":1146,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/useChanges.ts":{"bytes":1191,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/index.ts":{"bytes":1017,"imports":[{"path":"src/react/useDocument.ts","kind":"import-statement","original":"./useDocument.js"},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"},{"path":"src/react/useLiveQuery.ts","kind":"import-statement","original":"./useLiveQuery.js"},{"path":"src/react/useAllDocs.ts","kind":"import-statement","original":"./useAllDocs.js"},{"path":"src/react/useChanges.ts","kind":"import-statement","original":"./useChanges.js"}],"format":"esm"}},"outputs":{"dist/fireproof-core/react/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":28152},"dist/fireproof-core/react/index.cjs":{"imports":[{"path":"@fireproof/core","kind":"require-call","external":true},{"path":"react","kind":"require-call","external":true}],"exports":[],"entryPoint":"src/react/index.ts","inputs":{"src/react/index.ts":{"bytesInOutput":305},"src/react/useFireproof.ts":{"bytesInOutput":6388},"src/react/useDocument.ts":{"bytesInOutput":222},"src/react/useLiveQuery.ts":{"bytesInOutput":229},"src/react/useAllDocs.ts":{"bytesInOutput":215},"src/react/useChanges.ts":{"bytesInOutput":215}},"bytes":8541}}}
@@ -1 +1 @@
1
- {"inputs":{"src/react/useFireproof.ts":{"bytes":14885,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/useDocument.ts":{"bytes":2460,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/useLiveQuery.ts":{"bytes":1409,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/useAllDocs.ts":{"bytes":1146,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/useChanges.ts":{"bytes":1191,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/index.ts":{"bytes":971,"imports":[{"path":"src/react/useDocument.ts","kind":"import-statement","original":"./useDocument.js"},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"},{"path":"src/react/useLiveQuery.ts","kind":"import-statement","original":"./useLiveQuery.js"},{"path":"src/react/useAllDocs.ts","kind":"import-statement","original":"./useAllDocs.js"},{"path":"src/react/useChanges.ts","kind":"import-statement","original":"./useChanges.js"}],"format":"esm"}},"outputs":{"dist/fireproof-core/react/index.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":27470},"dist/fireproof-core/react/index.js":{"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"exports":["FireproofCtx","useAllDocs","useChanges","useDocument","useFireproof","useLiveQuery"],"entryPoint":"src/react/index.ts","inputs":{"src/react/useFireproof.ts":{"bytesInOutput":5840},"src/react/useDocument.ts":{"bytesInOutput":222},"src/react/index.ts":{"bytesInOutput":0},"src/react/useLiveQuery.ts":{"bytesInOutput":229},"src/react/useAllDocs.ts":{"bytesInOutput":215},"src/react/useChanges.ts":{"bytesInOutput":215}},"bytes":6967}}}
1
+ {"inputs":{"src/react/useFireproof.ts":{"bytes":14322,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"src/react/useDocument.ts":{"bytes":2460,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/useLiveQuery.ts":{"bytes":1409,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/useAllDocs.ts":{"bytes":1146,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/useChanges.ts":{"bytes":1191,"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"}],"format":"esm"},"src/react/index.ts":{"bytes":1017,"imports":[{"path":"src/react/useDocument.ts","kind":"import-statement","original":"./useDocument.js"},{"path":"src/react/useFireproof.ts","kind":"import-statement","original":"./useFireproof.js"},{"path":"src/react/useLiveQuery.ts","kind":"import-statement","original":"./useLiveQuery.js"},{"path":"src/react/useAllDocs.ts","kind":"import-statement","original":"./useAllDocs.js"},{"path":"src/react/useChanges.ts","kind":"import-statement","original":"./useChanges.js"}],"format":"esm"}},"outputs":{"dist/fireproof-core/react/index.js.map":{"imports":[],"exports":[],"inputs":{},"bytes":26991},"dist/fireproof-core/react/index.js":{"imports":[{"path":"@fireproof/core","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"exports":["FireproofCtx","useAllDocs","useChanges","useDocument","useFireproof","useLiveQuery"],"entryPoint":"src/react/index.ts","inputs":{"src/react/useFireproof.ts":{"bytesInOutput":5940},"src/react/useDocument.ts":{"bytesInOutput":222},"src/react/index.ts":{"bytesInOutput":0},"src/react/useLiveQuery.ts":{"bytesInOutput":229},"src/react/useAllDocs.ts":{"bytesInOutput":215},"src/react/useChanges.ts":{"bytesInOutput":215}},"bytes":7067}}}
@@ -70,7 +70,7 @@ describe("InterceptorGateway", () => {
70
70
  await db.close();
71
71
  await db.destroy();
72
72
  // await sleep(1000);
73
- expect(gwi.fn.mock.calls.length).toBe(42);
73
+ expect(gwi.fn.mock.calls.length).toBe(56);
74
74
  // might be a stupid test
75
75
  expect(gwi.fn.mock.calls.map((i) => i[0]).sort() /* not ok there are some operation */).toEqual(
76
76
  [
@@ -79,17 +79,31 @@ describe("InterceptorGateway", () => {
79
79
  "buildUrl",
80
80
  "get",
81
81
  "buildUrl",
82
+ "buildUrl",
83
+ "buildUrl",
84
+ "buildUrl",
85
+ "buildUrl",
86
+ "buildUrl",
87
+ "buildUrl",
88
+ "buildUrl",
89
+ "get",
82
90
  "get",
83
91
  "start",
84
92
  "start",
85
93
  "buildUrl",
86
94
  "get",
95
+ "get",
87
96
  "buildUrl",
88
97
  "put",
98
+ "put",
89
99
  "buildUrl",
90
100
  "put",
91
101
  "buildUrl",
92
102
  "put",
103
+ "put",
104
+ "put",
105
+ "put",
106
+ "put",
93
107
  "start",
94
108
  "start",
95
109
  "start",
@@ -1,9 +1,8 @@
1
1
  import { bs, ensureSuperThis, PARAM, rt } from "@fireproof/core";
2
2
  import { runtimeFn, toCryptoRuntime, URI } from "@adviser/cement";
3
3
  import { base58btc } from "multiformats/bases/base58";
4
- import { mockSuperThis } from "../helpers.js";
4
+ import { mockLoader, mockSuperThis } from "../helpers.js";
5
5
  import { KeyBagProviderIndexedDB } from "@fireproof/core/indexeddb";
6
- import { toKeyWithFingerPrint } from "../../src/runtime/key-bag.js";
7
6
 
8
7
  describe("KeyBag indexeddb and file", () => {
9
8
  let url: URI;
@@ -73,10 +72,10 @@ describe("KeyBag indexeddb and file", () => {
73
72
  return JSON.parse(sthis.txt.decode(data)) as rt.kb.KeysItem;
74
73
  });
75
74
  }
76
- expect((await toKeyWithFingerPrint(kb, Object.values(diskBag.keys)[0].key)).Ok().fingerPrint).toEqual(
75
+ expect((await rt.kb.toKeyWithFingerPrint(kb, Object.values(diskBag.keys)[0].key)).Ok().fingerPrint).toEqual(
77
76
  (await res.Ok().get())?.fingerPrint,
78
77
  );
79
- expect((await toKeyWithFingerPrint(kb, Object.values(diskBag2.keys)[0].key)).Ok().fingerPrint).toEqual(
78
+ expect((await rt.kb.toKeyWithFingerPrint(kb, Object.values(diskBag2.keys)[0].key)).Ok().fingerPrint).toEqual(
80
79
  (await created.Ok().get())?.fingerPrint,
81
80
  );
82
81
  const algo = {
@@ -105,29 +104,20 @@ describe("KeyedCryptoStore", () => {
105
104
  beforeEach(async () => {
106
105
  await sthis.start();
107
106
  // logger = MockLogger().logger;
108
- let kbUrl: URI;
107
+ // let kbUrl: URI;
109
108
  if (runtimeFn().isBrowser) {
110
- kbUrl = URI.from("indexeddb://fp-keybag");
109
+ // kbUrl = URI.from("indexeddb://fp-keybag");
111
110
  baseUrl = URI.from("indexeddb://fp-keyed-crypto-store");
112
111
  } else {
113
- kbUrl = URI.merge(`file://./dist/tests/key.bag`, sthis.env.get("FP_KEYBAG_URL"));
112
+ // kbUrl = URI.merge(`file://./dist/tests/key.bag`, sthis.env.get("FP_KEYBAG_URL"));
114
113
  baseUrl = URI.merge("file://./dist/tests/keyed-crypto-store", sthis.env.get("FP_STORAGE_URL"));
115
114
  }
116
115
  baseUrl = baseUrl.build().defParam(PARAM.NAME, "test").URI();
117
- loader = {
118
- sthis,
119
- keyBag: () => rt.kb.getKeyBag(sthis, { url: kbUrl }),
120
- } as bs.Loadable;
116
+ loader = mockLoader(sthis);
121
117
  });
122
118
  it("no crypto", async () => {
123
- const strt = bs.toStoreRuntime(sthis);
124
119
  const url = baseUrl.build().setParam(PARAM.STORE_KEY, "insecure").URI();
125
-
126
- for (const pstore of [
127
- strt.makeDataStore({ url, loader }),
128
- strt.makeMetaStore({ url, loader }),
129
- strt.makeWALStore({ url, loader }),
130
- ]) {
120
+ for (const pstore of (await bs.createAttachedStores(url, loader, "insecure")).stores.baseStores) {
131
121
  const store = await pstore;
132
122
  // await store.start();
133
123
  const kc = await store.keyedCrypto();
@@ -1,12 +1,11 @@
1
- import { bs, ensureSuperThis, PARAM, rt } from "@fireproof/core";
1
+ import { bs, ensureSuperThis, PARAM, rt, StoreType, storeType2DataMetaWal } from "@fireproof/core";
2
2
  import { BuildURI, runtimeFn, toCryptoRuntime, URI } from "@adviser/cement";
3
3
  import { base58btc } from "multiformats/bases/base58";
4
- import { sha256 as hasher } from "multiformats/hashes/sha2";
5
- import * as dagCodec from "@ipld/dag-cbor";
4
+ // import { sha256 as hasher } from "multiformats/hashes/sha2";
5
+ // import * as dagCodec from "@ipld/dag-cbor";
6
+ import * as cborg from "cborg";
6
7
  import type { KeyBagProviderIndexedDB } from "@fireproof/core/indexeddb";
7
- import { MockSuperThis, mockSuperThis } from "../helpers.js";
8
- import { KeyWithFingerPrint } from "../../src/blockstore/types.js";
9
- import { toKeyWithFingerPrint } from "../../src/runtime/key-bag.js";
8
+ import { mockLoader, MockSuperThis, mockSuperThis } from "../helpers.js";
10
9
 
11
10
  describe("KeyBag", () => {
12
11
  let url: URI;
@@ -113,10 +112,10 @@ describe("KeyBag", () => {
113
112
  return JSON.parse(sthis.txt.decode(data)) as rt.kb.KeysItem;
114
113
  });
115
114
  }
116
- expect((await toKeyWithFingerPrint(kb, Object.values(diskBag.keys)[0].key)).Ok().fingerPrint).toEqual(
115
+ expect((await rt.toKeyWithFingerPrint(kb, Object.values(diskBag.keys)[0].key)).Ok().fingerPrint).toEqual(
117
116
  (await res.Ok().get())?.fingerPrint,
118
117
  );
119
- expect((await toKeyWithFingerPrint(kb, Object.values(diskBag2.keys)[0].key)).Ok().fingerPrint).toEqual(
118
+ expect((await rt.toKeyWithFingerPrint(kb, Object.values(diskBag2.keys)[0].key)).Ok().fingerPrint).toEqual(
120
119
  (await created.Ok().get())?.fingerPrint,
121
120
  );
122
121
  const algo = {
@@ -129,7 +128,7 @@ describe("KeyBag", () => {
129
128
  expect(await kb.rt.crypto.encrypt(algo, (await res.Ok().get())!.key, data))
130
129
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
131
130
  .toEqual(await kb.rt.crypto.encrypt(algo, (await created.Ok().get())!.key, data));
132
- const kf = (await created.Ok().get()) as KeyWithFingerPrint;
131
+ const kf = (await created.Ok().get()) as bs.KeyWithFingerPrint;
133
132
  expect(await kb.rt.crypto.encrypt(algo, await kb.subtleKey(Object.values(diskBag.keys)[0].key), data)).toEqual(
134
133
  await kb.rt.crypto.encrypt(algo, kf.key, data),
135
134
  );
@@ -150,11 +149,11 @@ describe("KeyBag", () => {
150
149
  }
151
150
  expect(Object.keys((await kb.getNamedKey(name).then((i) => i.Ok().asKeysItem())).keys).length).toBe(1);
152
151
 
153
- const myKey = (await rMyKey.Ok().get()) as KeyWithFingerPrint;
152
+ const myKey = (await rMyKey.Ok().get()) as bs.KeyWithFingerPrint;
154
153
  expect(myKey.fingerPrint).toMatch(/^z/);
155
154
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
156
155
  await rMyKey.Ok().upsert((await myKey.extract())!.key);
157
- const myKey1 = (await rMyKey.Ok().get()) as KeyWithFingerPrint;
156
+ const myKey1 = (await rMyKey.Ok().get()) as bs.KeyWithFingerPrint;
158
157
  expect(myKey.fingerPrint).toEqual(myKey1.fingerPrint);
159
158
 
160
159
  expect(Object.keys((await kb.getNamedKey(name).then((i) => i.Ok().asKeysItem())).keys).length).toBe(1);
@@ -164,13 +163,13 @@ describe("KeyBag", () => {
164
163
  const res1 = await rMyKey1.Ok().upsert(kb.rt.crypto.randomBytes(kb.rt.keyLength));
165
164
  expect(res1.isOk()).toBeTruthy();
166
165
 
167
- const myKey2 = (await rMyKey1.Ok().get()) as KeyWithFingerPrint;
166
+ const myKey2 = (await rMyKey1.Ok().get()) as bs.KeyWithFingerPrint;
168
167
  expect(myKey.fingerPrint).toEqual(myKey2.fingerPrint);
169
168
  expect(Object.keys((await kb.getNamedKey(name).then((i) => i.Ok().asKeysItem())).keys).length).toBe(2);
170
169
 
171
170
  const res = await rMyKey1.Ok().upsert(kb.rt.crypto.randomBytes(kb.rt.keyLength), true);
172
171
  expect(res.isOk()).toBeTruthy();
173
- const myKey3 = (await rMyKey.Ok().get()) as KeyWithFingerPrint;
172
+ const myKey3 = (await rMyKey.Ok().get()) as bs.KeyWithFingerPrint;
174
173
  expect(Object.keys((await kb.getNamedKey(name).then((i) => i.Ok().asKeysItem())).keys).length).toBe(3);
175
174
 
176
175
  expect(myKey.fingerPrint).not.toEqual(myKey3.fingerPrint);
@@ -185,7 +184,7 @@ describe("KeyBag", () => {
185
184
  });
186
185
  const key = base58btc.encode(kb.rt.crypto.randomBytes(kb.rt.keyLength));
187
186
  const name = "default-key" + Math.random();
188
- const fpr = (await toKeyWithFingerPrint(kb, key)).Ok().fingerPrint;
187
+ const fpr = (await rt.toKeyWithFingerPrint(kb, key)).Ok().fingerPrint;
189
188
  const rMyKey = await kb.getNamedKey(name, false, key);
190
189
  expect(rMyKey.isOk()).toBeTruthy();
191
190
  const myKey = rMyKey.Ok();
@@ -199,7 +198,7 @@ describe("KeyBag", () => {
199
198
  const keys = [{ key, fpr }];
200
199
  for (let i = 0; i < 10; ++i) {
201
200
  const key = base58btc.encode(kb.rt.crypto.randomBytes(kb.rt.keyLength));
202
- const fpr = (await toKeyWithFingerPrint(kb, key)).Ok().fingerPrint;
201
+ const fpr = (await rt.toKeyWithFingerPrint(kb, key)).Ok().fingerPrint;
203
202
  keys.push({ key, fpr });
204
203
  const rUpsert = await myKey.upsert(key, true);
205
204
  expect(rUpsert.Ok().modified).toBeTruthy();
@@ -230,11 +229,11 @@ describe("KeyBag", () => {
230
229
  });
231
230
 
232
231
  describe("KeyedCryptoStore", () => {
233
- let loader: bs.Loadable;
234
232
  let kb: rt.kb.KeyBag;
235
233
  // let logger: Logger;
236
234
  let baseUrl: URI;
237
235
  const sthis = ensureSuperThis();
236
+ let loader: bs.Loadable;
238
237
  beforeEach(async () => {
239
238
  await sthis.start();
240
239
  // logger = MockLogger().logger;
@@ -256,20 +255,12 @@ describe("KeyedCryptoStore", () => {
256
255
  }
257
256
  baseUrl = baseUrl.build().setParam(PARAM.NAME, "test").URI();
258
257
  kb = await rt.kb.getKeyBag(sthis, {});
259
- loader = {
260
- sthis,
261
- keyBag: async () => kb,
262
- } as bs.Loadable;
258
+ loader = mockLoader(sthis);
263
259
  });
264
260
  it("no crypto", async () => {
265
- const strt = bs.toStoreRuntime(sthis);
266
261
  const url = baseUrl.build().setParam(PARAM.STORE_KEY, "insecure").URI();
267
262
 
268
- for (const pstore of [
269
- strt.makeDataStore({ url, loader }),
270
- strt.makeMetaStore({ url, loader }),
271
- strt.makeWALStore({ url, loader }),
272
- ]) {
263
+ for (const pstore of (await bs.createAttachedStores(url, loader, "insecure")).stores.baseStores) {
273
264
  const store = await pstore;
274
265
  // await store.start();
275
266
  const kc = await store.keyedCrypto();
@@ -281,17 +272,14 @@ describe("KeyedCryptoStore", () => {
281
272
  });
282
273
 
283
274
  it("create key", async () => {
284
- const strt = bs.toStoreRuntime(sthis);
285
- for (const pstore of [
286
- strt.makeDataStore({ url: baseUrl, loader }),
287
- strt.makeMetaStore({ url: baseUrl, loader }),
288
- strt.makeWALStore({ url: baseUrl, loader }),
289
- ]) {
275
+ for (const pstore of (await bs.createAttachedStores(baseUrl, loader, "insecure")).stores.baseStores) {
290
276
  const store = await pstore; // await bs.ensureStart(await pstore, logger);
291
277
  const kc = await store.keyedCrypto();
292
278
  expect(kc.constructor.name).toBe("cryptoAction");
293
279
  // expect(kc.isEncrypting).toBe(true);
294
- expect(store.url().getParam(PARAM.STORE_KEY)).toBe(`@test:${store.url().getParam(PARAM.STORE)}@`);
280
+ expect(store.url().getParam(PARAM.STORE_KEY)).toBe(
281
+ `@test-${storeType2DataMetaWal(store.url().getParam(PARAM.STORE) as StoreType)}@`,
282
+ );
295
283
  }
296
284
  });
297
285
 
@@ -299,12 +287,7 @@ describe("KeyedCryptoStore", () => {
299
287
  const key = base58btc.encode(kb.rt.crypto.randomBytes(kb.rt.keyLength));
300
288
  const genKey = await kb.getNamedKey("@heute@", false, key);
301
289
  const url = baseUrl.build().setParam(PARAM.STORE_KEY, "@heute@").URI();
302
- const strt = bs.toStoreRuntime(sthis);
303
- for (const pstore of [
304
- strt.makeDataStore({ url, loader }),
305
- strt.makeMetaStore({ url, loader }),
306
- strt.makeWALStore({ url, loader }),
307
- ]) {
290
+ for (const pstore of (await bs.createAttachedStores(url, loader, "insecure")).stores.baseStores) {
308
291
  const store = await pstore;
309
292
  // await store.start();
310
293
  expect(store.url().getParam(PARAM.STORE_KEY)).toBe(`@heute@`);
@@ -315,7 +298,7 @@ describe("KeyedCryptoStore", () => {
315
298
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
316
299
  const blk = await kc._encrypt({ bytes: testData, key: (await kc.key.get())!.key, iv });
317
300
  expect(blk).not.toEqual(testData);
318
- const fpkey = (await genKey.Ok().get()) as KeyWithFingerPrint;
301
+ const fpkey = (await genKey.Ok().get()) as bs.KeyWithFingerPrint;
319
302
  expect(fpkey.fingerPrint).toEqual(fpkey.fingerPrint);
320
303
  const dec = new Uint8Array(await kc.crypto.decrypt(kc.algo(iv), fpkey.key, blk));
321
304
  expect(dec).toEqual(testData);
@@ -324,13 +307,8 @@ describe("KeyedCryptoStore", () => {
324
307
 
325
308
  it("key", async () => {
326
309
  const key = base58btc.encode(kb.rt.crypto.randomBytes(kb.rt.keyLength));
327
- const strt = bs.toStoreRuntime(sthis);
328
310
  const url = baseUrl.build().setParam(PARAM.STORE_KEY, key).URI();
329
- for (const pstore of [
330
- strt.makeDataStore({ url, loader }),
331
- strt.makeMetaStore({ url, loader }),
332
- strt.makeWALStore({ url, loader }),
333
- ]) {
311
+ for (const pstore of (await bs.createAttachedStores(url, loader, "insecure")).stores.baseStores) {
334
312
  // for (const pstore of [strt.makeDataStore(loader), strt.makeMetaStore(loader), strt.makeWALStore(loader)]) {
335
313
  const store = await pstore;
336
314
  // await store.start();
@@ -339,7 +317,7 @@ describe("KeyedCryptoStore", () => {
339
317
  expect(kc.constructor.name).toBe("cryptoAction");
340
318
  const testData = kb.rt.crypto.randomBytes(1024);
341
319
  const iv = kb.rt.crypto.randomBytes(12);
342
- const ks = (await kc.key.get()) as KeyWithFingerPrint;
320
+ const ks = (await kc.key.get()) as bs.KeyWithFingerPrint;
343
321
  const blk = await kc._encrypt({ bytes: testData, key: ks.key, iv });
344
322
  expect(blk).not.toEqual(testData);
345
323
  const dec = await kc._decrypt({ bytes: blk, key: ks.key, iv });
@@ -371,12 +349,12 @@ describe("KeyedCrypto", () => {
371
349
  const iv = kb.rt.crypto.randomBytes(12);
372
350
  const codec = kycr.codec(iv, { noIVVerify: true });
373
351
  const blk = (await codec.encode(testData)) as Uint8Array;
374
- const myDec = await rt.mf.block.decode<bs.IvKeyIdData, number, number>({ bytes: blk, hasher, codec: dagCodec });
375
- expect(myDec.value.iv).toEqual(iv);
376
- const kc = (await kycr.key.get()) as KeyWithFingerPrint;
377
- expect(base58btc.encode(myDec.value.keyId)).toEqual(kc.fingerPrint);
352
+ const myDec = cborg.decode(blk) as bs.IvKeyIdData;
353
+ expect(myDec.iv).toEqual(iv);
354
+ const kc = (await kycr.key.get()) as bs.KeyWithFingerPrint;
355
+ expect(base58btc.encode(myDec.keyId)).toEqual(kc.fingerPrint);
378
356
  const dec = await codec.decode(blk);
379
- expect(dec).toEqual(testData);
357
+ expect(dec.data).toEqual(testData);
380
358
  });
381
359
 
382
360
  it("codec implict iv", async () => {
@@ -385,7 +363,7 @@ describe("KeyedCrypto", () => {
385
363
  const blk = await codec.encode(testData);
386
364
  expect(blk.length).toBeGreaterThanOrEqual(12 + testData.length);
387
365
  const dec = await codec.decode(blk);
388
- expect(dec).toEqual(testData);
366
+ expect(dec.data).toEqual(testData);
389
367
  });
390
368
 
391
369
  it("codec implict iv same for multiple clients", async () => {