@blaze-chat/tanstack-db-idb-collection 0.0.3 → 0.0.5
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/README.md +3 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# TanStack DB IndexedDB Collection
|
|
2
2
|
|
|
3
|
-
IndexedDB adapter for [TanStack DB](https://tanstack.com/db/latest) (using [idb](https://www.npmjs.com/package/idb))
|
|
3
|
+
IndexedDB adapter for [TanStack DB](https://tanstack.com/db/latest) (using [idb](https://www.npmjs.com/package/idb)).
|
|
4
|
+
|
|
5
|
+
Full type safety.
|
|
4
6
|
|
|
5
7
|
## Usage Example
|
|
6
8
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IDBPDatabase } from "idb";
|
|
1
|
+
import { IDBPDatabase, IDBPObjectStore } from "idb";
|
|
2
2
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
3
3
|
import { DeleteMutationFn, InsertMutationFn, SyncConfig, UpdateMutationFn } from "@tanstack/db";
|
|
4
4
|
|
|
@@ -12,6 +12,7 @@ type ObjectStore<Entity extends object = any, IdPath extends ValidIdPath<Entity>
|
|
|
12
12
|
schema: StandardSchemaV1<Entity>;
|
|
13
13
|
idPath: IdPath;
|
|
14
14
|
indicies?: (keyof Entity & string)[];
|
|
15
|
+
upgrade?: (objectStore: IDBPObjectStore<unknown, ArrayLike<string>, string, "versionchange">) => Promise<void>;
|
|
15
16
|
};
|
|
16
17
|
type ObjectStores = Record<string, ObjectStore>;
|
|
17
18
|
/**
|
|
@@ -26,6 +27,10 @@ type ObjectStoreIdPath<Store extends ObjectStore> = Store extends ObjectStore<an
|
|
|
26
27
|
* Get IdType from ObjectStore
|
|
27
28
|
*/
|
|
28
29
|
type ObjectStoreIdType<Store extends ObjectStore> = Store extends ObjectStore<infer Entity, infer IdPath> ? Entity[IdPath] : never;
|
|
30
|
+
type IDBSchema<T extends ObjectStores> = { [K in keyof T]: {
|
|
31
|
+
value: ObjectStoreEntity<T[K]>;
|
|
32
|
+
key: ObjectStoreIdType<T[K]>;
|
|
33
|
+
} };
|
|
29
34
|
//#endregion
|
|
30
35
|
//#region src/database.d.ts
|
|
31
36
|
/**
|
|
@@ -69,5 +74,5 @@ declare function idbCollectionOptions<const T extends ObjectStores, const Name e
|
|
|
69
74
|
name: Name;
|
|
70
75
|
}): IDBCollectionConfig<NonNullable<T[Name]>, ObjectStoreEntity<NonNullable<T[Name]>>, ObjectStoreIdType<NonNullable<T[Name]>>>;
|
|
71
76
|
//#endregion
|
|
72
|
-
export { Database, IDBCollectionConfig, ObjectStore, ObjectStoreEntity, ObjectStoreIdPath, ObjectStoreIdType, ObjectStores, ValidId, ValidIdPath, createDatabase, defineObjectStore, idbCollectionOptions };
|
|
77
|
+
export { Database, IDBCollectionConfig, IDBSchema, ObjectStore, ObjectStoreEntity, ObjectStoreIdPath, ObjectStoreIdType, ObjectStores, ValidId, ValidIdPath, createDatabase, defineObjectStore, idbCollectionOptions };
|
|
73
78
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/database.ts","../src/options.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/database.ts","../src/options.ts"],"mappings":";;;;;KAGY,OAAA;AAAA;AAKZ;;AALY,KAKA,WAAA,wCACE,MAAA,GAAS,MAAA,CAAO,CAAA,UAAW,OAAA,GAAU,CAAA,iBAC3C,MAAA;AAAA,KAEI,WAAA,6CAAwD,WAAA,CAAY,MAAA;EAAA,MAAA,EACtE,gBAAA,CAAiB,MAAA;EAAA,MAAA,EACjB,MAAA;EAAA,QAAA,UACU,MAAA;EAAA,OAAA,IAAA,WAAA,EAEH,eAAA,UAAyB,SAAA,uCACnC,OAAA;AAAA;AAAA,KAGK,YAAA,GAAe,MAAA,SAAe,WAAA;AAAA;AAK1C;;AAL0C,KAK9B,iBAAA,eAAgC,WAAA,IAC1C,KAAA,SAAc,WAAA,iBAAA,MAAA;AAAA;;AAKhB;AALgB,KAKJ,iBAAA,eAAgC,WAAA,IAC1C,KAAA,SAAc,WAAA,sBAAA,MAAA;AAAA;;AAKhB;AALgB,KAKJ,iBAAA,eAAgC,WAAA,IAC1C,KAAA,SAAc,WAAA,+BAA0C,MAAA,CAAO,MAAA;AAAA,KAErD,SAAA,WAAoB,YAAA,kBAClB,CAAA;EAAA,KAAA,EACH,iBAAA,CAAkB,CAAA,CAAE,CAAA;EAAA,GAAA,EACtB,iBAAA,CAAkB,CAAA,CAAE,CAAA;AAAA;;;;ACtC7B;;iBAAgB,iBAAA,mDAEO,WAAA,CAAY,MAAA,EAAA,CAAA,WAAA,EACpB,WAAA,CAAY,MAAA,EAAQ,MAAA,IAAU,WAAA,CAAY,MAAA,EAAQ,MAAA;AAAA,KAIrD,QAAA,WAAmB,YAAA;EAAA;;;EAAA,GAAA,EAIxB,OAAA,CAAQ,YAAA;EAAA,YAAA,EACC,CAAA;AAAA;AAAA,iBAGA,cAAA,iBAA+B,YAAA,CAAA,CAAA,IAAA,UAAA,OAAA,UAAA,YAAA,EAG/B,CAAA,GACb,QAAA,CAAS,CAAA;;;cCbC,mBAAA,qBACS,WAAA,uBACC,iBAAA,CAAkB,KAAA,wBAClB,iBAAA,CAAkB,KAAA;EAAA,EAAA;EAAA,MAAA,EAG/B,gBAAA,CAAiB,MAAA;EAAA,MAAA,GAAA,MAAA,EACR,MAAA,KAAW,MAAA;EAAA,IAAA,EACtB,UAAA,CAAW,MAAA,EAAQ,MAAA;EAAA,QAAA,EAEf,gBAAA,CAAiB,MAAA,EAAQ,MAAA;EAAA,QAAA,EACzB,gBAAA,CAAiB,MAAA,EAAQ,MAAA;EAAA,QAAA,EACzB,gBAAA,CAAiB,MAAA,EAAQ,MAAA;EAAA,QAAA,KAAA;EAAA,QAAA,KAAA;EAAA,QAAA,MAAA;EAAA,YAAA,GAAA,EAMlB,OAAA,CAAQ,YAAA,GAAA,IAAA;IAAA,MAAA;IAAA;EAAA,GAAiD,KAAA;AAAA;AAAA,iBA6E5D,oBAAA,iBACE,YAAA,2BACS,CAAA,UAAA,CAAA;EAAA,QAAA;IAAA,GAAA;IAAA;EAAA;EAAA;AAAA;EAAA,QAAA,EAC8B,QAAA,CAAS,CAAA;EAAA,IAAA,EAAU,IAAA;AAAA,IAAM,mBAAA,CAAA,WAAA,CAAA,CAAA,CAAA,IAAA,IAAA,iBAAA,CAAA,WAAA,CAAA,CAAA,CAAA,IAAA,KAAA,iBAAA,CAAA,WAAA,CAAA,CAAA,CAAA,IAAA"}
|
package/dist/index.js
CHANGED
|
@@ -10,9 +10,10 @@ function defineObjectStore(objectStore) {
|
|
|
10
10
|
function createDatabase(name, version, objectStores) {
|
|
11
11
|
return {
|
|
12
12
|
idb: openDB(name, version, { async upgrade(database) {
|
|
13
|
-
for (const [
|
|
14
|
-
const objectStore = database.createObjectStore(
|
|
15
|
-
if (indicies) await Promise.all(indicies.map((index) => objectStore.createIndex(
|
|
13
|
+
for (const [objectStoreName, { idPath, indicies, upgrade }] of Object.entries(objectStores)) {
|
|
14
|
+
const objectStore = database.createObjectStore(objectStoreName, { keyPath: idPath });
|
|
15
|
+
if (indicies) await Promise.all(indicies.map((index) => objectStore.createIndex(index, index)));
|
|
16
|
+
await upgrade?.(objectStore);
|
|
16
17
|
}
|
|
17
18
|
} }),
|
|
18
19
|
objectStores
|
|
@@ -56,7 +57,7 @@ var IDBCollectionConfig = class {
|
|
|
56
57
|
this.onInsert = async ({ transaction }) => {
|
|
57
58
|
const entities = transaction.mutations.map((m) => m.modified);
|
|
58
59
|
const tx = (await idb).transaction(name, "readwrite");
|
|
59
|
-
await Promise.all(entities.map((entity) => tx.
|
|
60
|
+
await Promise.all(entities.map((entity) => tx.objectStore(name).add(entity)));
|
|
60
61
|
await tx.done;
|
|
61
62
|
this.begin();
|
|
62
63
|
for (const entity of entities) this.write({
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/database.ts","../src/options.ts"],"sourcesContent":["import { openDB, type IDBPDatabase } from \"idb\";\nimport type { ObjectStore, ObjectStores, ValidIdPath } from \"./types\";\n\n/**\n * Helper function for IDE auto completion\n */\nexport function defineObjectStore<\n const Entity extends object,\n const IdPath extends ValidIdPath<Entity>,\n>(objectStore: ObjectStore<Entity, IdPath>): ObjectStore<Entity, IdPath> {\n return objectStore;\n}\n\nexport type Database<T extends ObjectStores> = {\n /**\n * Note: Safari does not support Top-Level Await\n */\n idb: Promise<IDBPDatabase>;\n objectStores: T;\n};\n\nexport function createDatabase<const T extends ObjectStores>(\n name: string,\n version: number,\n objectStores: T,\n): Database<T> {\n const idb = openDB(name, version, {\n async upgrade(database) {\n for (const [
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/database.ts","../src/options.ts"],"sourcesContent":["import { openDB, type IDBPDatabase } from \"idb\";\nimport type { ObjectStore, ObjectStores, ValidIdPath } from \"./types\";\n\n/**\n * Helper function for IDE auto completion\n */\nexport function defineObjectStore<\n const Entity extends object,\n const IdPath extends ValidIdPath<Entity>,\n>(objectStore: ObjectStore<Entity, IdPath>): ObjectStore<Entity, IdPath> {\n return objectStore;\n}\n\nexport type Database<T extends ObjectStores> = {\n /**\n * Note: Safari does not support Top-Level Await\n */\n idb: Promise<IDBPDatabase>;\n objectStores: T;\n};\n\nexport function createDatabase<const T extends ObjectStores>(\n name: string,\n version: number,\n objectStores: T,\n): Database<T> {\n const idb = openDB(name, version, {\n async upgrade(database) {\n for (const [objectStoreName, { idPath, indicies, upgrade }] of Object.entries(objectStores)) {\n const objectStore = database.createObjectStore(objectStoreName, { keyPath: idPath });\n\n if (indicies) {\n // oxlint-disable-next-line no-await-in-loop\n await Promise.all(indicies.map((index) => objectStore.createIndex(index, index)));\n }\n\n // oxlint-disable-next-line no-await-in-loop\n await upgrade?.(objectStore);\n }\n },\n });\n\n return { idb, objectStores };\n}\n","import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport type {\n ChangeMessageOrDeleteKeyMessage,\n DeleteMutationFn,\n InsertMutationFn,\n SyncConfig,\n UpdateMutationFn,\n} from \"@tanstack/db\";\nimport type { IDBPDatabase } from \"idb\";\nimport type { Database } from \"./database\";\nimport type { ObjectStore, ObjectStoreEntity, ObjectStoreIdType, ObjectStores } from \"./types\";\n\nexport class IDBCollectionConfig<\n const Store extends ObjectStore,\n const Entity extends ObjectStoreEntity<Store>,\n const IdType extends ObjectStoreIdType<Store>,\n> {\n id: string;\n schema: StandardSchemaV1<Entity>;\n getKey: (entity: Entity) => IdType;\n sync: SyncConfig<Entity, IdType>;\n\n onInsert: InsertMutationFn<Entity, IdType>;\n onUpdate: UpdateMutationFn<Entity, IdType>;\n onDelete: DeleteMutationFn<Entity, IdType>;\n\n private begin!: () => void;\n private write!: (message: ChangeMessageOrDeleteKeyMessage<Entity, IdType>) => void;\n private commit!: () => void;\n\n constructor(idb: Promise<IDBPDatabase>, name: string, { idPath, schema }: Store) {\n this.id = name;\n this.schema = schema;\n this.getKey = (entity) => entity[idPath];\n this.sync = {\n sync: ({ begin, write, commit, markReady }) => {\n this.begin = begin;\n this.write = write;\n this.commit = commit;\n\n // oxlint-disable-next-line typescript/no-floating-promises\n (async () => {\n try {\n begin();\n\n for (const entity of await (await idb).getAll(name)) {\n write({ type: \"insert\", value: entity });\n }\n\n commit();\n } finally {\n markReady();\n }\n })();\n },\n };\n\n this.onInsert = async ({ transaction }) => {\n const entities = transaction.mutations.map((m) => m.modified);\n\n const tx = (await idb).transaction(name, \"readwrite\");\n\n await Promise.all(entities.map((entity) => tx.objectStore(name).add(entity)));\n\n await tx.done;\n\n this.begin();\n for (const entity of entities) {\n this.write({ type: \"insert\", value: entity });\n }\n this.commit();\n };\n\n this.onUpdate = async ({ transaction }) => {\n const entities = transaction.mutations.map((m) => m.modified);\n\n const tx = (await idb).transaction(name, \"readwrite\");\n\n await Promise.all(entities.map((entity) => tx.store.put(entity)));\n\n await tx.done;\n\n this.begin();\n for (const entity of entities) {\n this.write({ type: \"update\", value: entity });\n }\n this.commit();\n };\n\n this.onDelete = async ({ transaction }) => {\n const keys = transaction.mutations.map((m) => m.key);\n\n const tx = (await idb).transaction(name, \"readwrite\");\n\n await Promise.all(keys.map((key) => tx.store.delete(key)));\n\n await tx.done;\n\n this.begin();\n for (const key of keys) {\n this.write({ type: \"delete\", key });\n }\n this.commit();\n };\n }\n}\n\nexport function idbCollectionOptions<\n const T extends ObjectStores,\n const Name extends keyof T & string,\n>({ database: { idb, objectStores }, name }: { database: Database<T>; name: Name }) {\n return new IDBCollectionConfig(idb, name, objectStores[name]!);\n}\n"],"mappings":";;;;;;AAMA,SAAgB,kBAGd,aAAuE;AACvE,QAAO;;AAWT,SAAgB,eACd,MACA,SACA,cACa;AAiBb,QAAO;EAAE,KAhBG,OAAO,MAAM,SAAS,EAChC,MAAM,QAAQ,UAAU;AACtB,QAAK,MAAM,CAAC,iBAAiB,EAAE,QAAQ,UAAU,cAAc,OAAO,QAAQ,aAAa,EAAE;IAC3F,MAAM,cAAc,SAAS,kBAAkB,iBAAiB,EAAE,SAAS,QAAQ,CAAC;AAEpF,QAAI,SAEF,OAAM,QAAQ,IAAI,SAAS,KAAK,UAAU,YAAY,YAAY,OAAO,MAAM,CAAC,CAAC;AAInF,UAAM,UAAU,YAAY;;KAGjC,CAAC;EAEY;EAAc;;;;;AC9B9B,IAAa,sBAAb,MAIE;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CAEA,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,YAAY,KAA4B,MAAc,EAAE,QAAQ,UAAiB;AAC/E,OAAK,KAAK;AACV,OAAK,SAAS;AACd,OAAK,UAAU,WAAW,OAAO;AACjC,OAAK,OAAO,EACV,OAAO,EAAE,OAAO,OAAO,QAAQ,gBAAgB;AAC7C,QAAK,QAAQ;AACb,QAAK,QAAQ;AACb,QAAK,SAAS;AAGd,IAAC,YAAY;AACX,QAAI;AACF,YAAO;AAEP,UAAK,MAAM,UAAU,OAAO,MAAM,KAAK,OAAO,KAAK,CACjD,OAAM;MAAE,MAAM;MAAU,OAAO;MAAQ,CAAC;AAG1C,aAAQ;cACA;AACR,gBAAW;;OAEX;KAEP;AAED,OAAK,WAAW,OAAO,EAAE,kBAAkB;GACzC,MAAM,WAAW,YAAY,UAAU,KAAK,MAAM,EAAE,SAAS;GAE7D,MAAM,MAAM,MAAM,KAAK,YAAY,MAAM,YAAY;AAErD,SAAM,QAAQ,IAAI,SAAS,KAAK,WAAW,GAAG,YAAY,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC;AAE7E,SAAM,GAAG;AAET,QAAK,OAAO;AACZ,QAAK,MAAM,UAAU,SACnB,MAAK,MAAM;IAAE,MAAM;IAAU,OAAO;IAAQ,CAAC;AAE/C,QAAK,QAAQ;;AAGf,OAAK,WAAW,OAAO,EAAE,kBAAkB;GACzC,MAAM,WAAW,YAAY,UAAU,KAAK,MAAM,EAAE,SAAS;GAE7D,MAAM,MAAM,MAAM,KAAK,YAAY,MAAM,YAAY;AAErD,SAAM,QAAQ,IAAI,SAAS,KAAK,WAAW,GAAG,MAAM,IAAI,OAAO,CAAC,CAAC;AAEjE,SAAM,GAAG;AAET,QAAK,OAAO;AACZ,QAAK,MAAM,UAAU,SACnB,MAAK,MAAM;IAAE,MAAM;IAAU,OAAO;IAAQ,CAAC;AAE/C,QAAK,QAAQ;;AAGf,OAAK,WAAW,OAAO,EAAE,kBAAkB;GACzC,MAAM,OAAO,YAAY,UAAU,KAAK,MAAM,EAAE,IAAI;GAEpD,MAAM,MAAM,MAAM,KAAK,YAAY,MAAM,YAAY;AAErD,SAAM,QAAQ,IAAI,KAAK,KAAK,QAAQ,GAAG,MAAM,OAAO,IAAI,CAAC,CAAC;AAE1D,SAAM,GAAG;AAET,QAAK,OAAO;AACZ,QAAK,MAAM,OAAO,KAChB,MAAK,MAAM;IAAE,MAAM;IAAU;IAAK,CAAC;AAErC,QAAK,QAAQ;;;;AAKnB,SAAgB,qBAGd,EAAE,UAAU,EAAE,KAAK,gBAAgB,QAA+C;AAClF,QAAO,IAAI,oBAAoB,KAAK,MAAM,aAAa,MAAO"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blaze-chat/tanstack-db-idb-collection",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
3
|
+
"version": "0.0.5",
|
|
4
|
+
"description": "IndexedDB adapter for TanStack DB (using idb)",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"TanStack",
|
|
7
|
+
"TanStack DB",
|
|
8
|
+
"IndexedDB"
|
|
9
|
+
],
|
|
5
10
|
"author": "MioYi Sama",
|
|
11
|
+
"license": "Apache-2.0",
|
|
6
12
|
"repository": "https://github.com/MioYiSama/blaze-chat/tree/main/packages/tanstack-db-idb-collection",
|
|
7
13
|
"type": "module",
|
|
8
14
|
"files": [
|