web-idb-client 1.0.0

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 (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +230 -0
  3. package/dist/client/index.d.ts +7 -0
  4. package/dist/client/index.js +12 -0
  5. package/dist/client/index.js.map +1 -0
  6. package/dist/client/indexed-db-client.d.ts +40 -0
  7. package/dist/client/indexed-db-client.js +211 -0
  8. package/dist/client/indexed-db-client.js.map +1 -0
  9. package/dist/client/mutations.d.ts +12 -0
  10. package/dist/client/mutations.js +3 -0
  11. package/dist/client/mutations.js.map +1 -0
  12. package/dist/client/store.d.ts +42 -0
  13. package/dist/client/store.js +356 -0
  14. package/dist/client/store.js.map +1 -0
  15. package/dist/client/transaction.d.ts +14 -0
  16. package/dist/client/transaction.js +37 -0
  17. package/dist/client/transaction.js.map +1 -0
  18. package/dist/errors/index.d.ts +15 -0
  19. package/dist/errors/index.js +35 -0
  20. package/dist/errors/index.js.map +1 -0
  21. package/dist/index.d.ts +10 -0
  22. package/dist/index.js +33 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/liveQuery/index.d.ts +31 -0
  25. package/dist/liveQuery/index.js +216 -0
  26. package/dist/liveQuery/index.js.map +1 -0
  27. package/dist/migrate/diff.d.ts +28 -0
  28. package/dist/migrate/diff.js +89 -0
  29. package/dist/migrate/diff.js.map +1 -0
  30. package/dist/migrate/helpers.d.ts +29 -0
  31. package/dist/migrate/helpers.js +89 -0
  32. package/dist/migrate/helpers.js.map +1 -0
  33. package/dist/migrate/index.d.ts +6 -0
  34. package/dist/migrate/index.js +14 -0
  35. package/dist/migrate/index.js.map +1 -0
  36. package/dist/migrate/upgrade.d.ts +19 -0
  37. package/dist/migrate/upgrade.js +123 -0
  38. package/dist/migrate/upgrade.js.map +1 -0
  39. package/dist/query/order.d.ts +8 -0
  40. package/dist/query/order.js +30 -0
  41. package/dist/query/order.js.map +1 -0
  42. package/dist/query/where.d.ts +17 -0
  43. package/dist/query/where.js +106 -0
  44. package/dist/query/where.js.map +1 -0
  45. package/dist/relation/define-relation.d.ts +49 -0
  46. package/dist/relation/define-relation.js +101 -0
  47. package/dist/relation/define-relation.js.map +1 -0
  48. package/dist/relation/index.d.ts +3 -0
  49. package/dist/relation/index.js +14 -0
  50. package/dist/relation/index.js.map +1 -0
  51. package/dist/relation/load-related.d.ts +21 -0
  52. package/dist/relation/load-related.js +54 -0
  53. package/dist/relation/load-related.js.map +1 -0
  54. package/dist/schema/define-db.d.ts +5 -0
  55. package/dist/schema/define-db.js +41 -0
  56. package/dist/schema/define-db.js.map +1 -0
  57. package/dist/schema/define-store.d.ts +17 -0
  58. package/dist/schema/define-store.js +95 -0
  59. package/dist/schema/define-store.js.map +1 -0
  60. package/dist/schema/fields.d.ts +75 -0
  61. package/dist/schema/fields.js +90 -0
  62. package/dist/schema/fields.js.map +1 -0
  63. package/dist/schema/index.d.ts +5 -0
  64. package/dist/schema/index.js +22 -0
  65. package/dist/schema/index.js.map +1 -0
  66. package/dist/schema/infer.d.ts +131 -0
  67. package/dist/schema/infer.js +3 -0
  68. package/dist/schema/infer.js.map +1 -0
  69. package/dist/schema/infer.test-types.d.ts +11 -0
  70. package/dist/schema/infer.test-types.js +80 -0
  71. package/dist/schema/infer.test-types.js.map +1 -0
  72. package/dist/schema/types.d.ts +55 -0
  73. package/dist/schema/types.js +3 -0
  74. package/dist/schema/types.js.map +1 -0
  75. package/dist/utils/assert-keys.d.ts +3 -0
  76. package/dist/utils/assert-keys.js +15 -0
  77. package/dist/utils/assert-keys.js.map +1 -0
  78. package/dist/utils/boolean-codec.d.ts +23 -0
  79. package/dist/utils/boolean-codec.js +149 -0
  80. package/dist/utils/boolean-codec.js.map +1 -0
  81. package/dist/utils/index.d.ts +5 -0
  82. package/dist/utils/index.js +16 -0
  83. package/dist/utils/index.js.map +1 -0
  84. package/dist/utils/key-range.d.ts +14 -0
  85. package/dist/utils/key-range.js +157 -0
  86. package/dist/utils/key-range.js.map +1 -0
  87. package/dist/utils/promisify.d.ts +2 -0
  88. package/dist/utils/promisify.js +29 -0
  89. package/dist/utils/promisify.js.map +1 -0
  90. package/dist/utils/type-utils.d.ts +2 -0
  91. package/dist/utils/type-utils.js +3 -0
  92. package/dist/utils/type-utils.js.map +1 -0
  93. package/package.json +71 -0
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.liveQuery = void 0;
4
+ const bridges = new WeakMap();
5
+ function channelName(dbName) {
6
+ return `web-idb-client:${dbName}`;
7
+ }
8
+ function storageKey(dbName) {
9
+ return `web-idb-client:mutate:${dbName}`;
10
+ }
11
+ function ensureBridge(client) {
12
+ let bridge = bridges.get(client);
13
+ if (bridge) {
14
+ return bridge;
15
+ }
16
+ const listeners = new Set();
17
+ const name = client.name;
18
+ let channel = null;
19
+ try {
20
+ if (typeof BroadcastChannel !== 'undefined') {
21
+ channel = new BroadcastChannel(channelName(name));
22
+ channel.onmessage = (event) => {
23
+ var _a;
24
+ const stores = (_a = event.data) === null || _a === void 0 ? void 0 : _a.stores;
25
+ if (!Array.isArray(stores) || stores.length === 0) {
26
+ return;
27
+ }
28
+ const batch = { stores, remote: true };
29
+ for (const listener of listeners) {
30
+ listener(batch);
31
+ }
32
+ };
33
+ }
34
+ }
35
+ catch (_a) {
36
+ channel = null;
37
+ }
38
+ const key = storageKey(name);
39
+ let onStorage = null;
40
+ if (typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
41
+ onStorage = (event) => {
42
+ if (event.key !== key || event.newValue == null) {
43
+ return;
44
+ }
45
+ let stores = ['*'];
46
+ try {
47
+ const parsed = JSON.parse(event.newValue);
48
+ if (Array.isArray(parsed.stores) && parsed.stores.length > 0) {
49
+ stores = parsed.stores;
50
+ }
51
+ }
52
+ catch (_a) {
53
+ // ignore malformed payloads
54
+ }
55
+ const batch = { stores, remote: true };
56
+ for (const listener of listeners) {
57
+ listener(batch);
58
+ }
59
+ };
60
+ window.addEventListener('storage', onStorage);
61
+ }
62
+ const unsubLocal = client.subscribeMutations((batch) => {
63
+ for (const listener of listeners) {
64
+ listener(batch);
65
+ }
66
+ if (batch.remote) {
67
+ return;
68
+ }
69
+ try {
70
+ channel === null || channel === void 0 ? void 0 : channel.postMessage({ stores: batch.stores });
71
+ }
72
+ catch (_a) {
73
+ // ignore
74
+ }
75
+ if (typeof localStorage !== 'undefined') {
76
+ try {
77
+ localStorage.setItem(key, JSON.stringify({ stores: batch.stores, t: Date.now() }));
78
+ }
79
+ catch (_b) {
80
+ // private mode / quota
81
+ }
82
+ }
83
+ });
84
+ bridge = {
85
+ channel,
86
+ storageKey: key,
87
+ unsubLocal,
88
+ onStorage,
89
+ listeners,
90
+ refCount: 0,
91
+ };
92
+ bridges.set(client, bridge);
93
+ return bridge;
94
+ }
95
+ function retainBridge(client) {
96
+ const bridge = ensureBridge(client);
97
+ bridge.refCount += 1;
98
+ return bridge;
99
+ }
100
+ function releaseBridge(client) {
101
+ var _a;
102
+ const bridge = bridges.get(client);
103
+ if (!bridge) {
104
+ return;
105
+ }
106
+ bridge.refCount -= 1;
107
+ if (bridge.refCount > 0) {
108
+ return;
109
+ }
110
+ bridge.unsubLocal();
111
+ try {
112
+ (_a = bridge.channel) === null || _a === void 0 ? void 0 : _a.close();
113
+ }
114
+ catch (_b) {
115
+ // ignore
116
+ }
117
+ if (bridge.onStorage && typeof window !== 'undefined') {
118
+ window.removeEventListener('storage', bridge.onStorage);
119
+ }
120
+ bridges.delete(client);
121
+ }
122
+ /**
123
+ * Opt-in reactive query (browser tabs only — not sync / mobile).
124
+ *
125
+ * Re-runs `querier` after local mutations and when other tabs signal via
126
+ * BroadcastChannel (with `storage` event fallback).
127
+ *
128
+ * ```ts
129
+ * import { liveQuery } from 'web-idb-client/liveQuery';
130
+ *
131
+ * const sub = liveQuery(db, () => db.todos.findMany()).subscribe({
132
+ * next: (rows) => render(rows),
133
+ * error: console.error,
134
+ * });
135
+ * // later: sub.unsubscribe();
136
+ * ```
137
+ */
138
+ function liveQuery(client, querier) {
139
+ return {
140
+ subscribe(subscriber) {
141
+ const bridge = retainBridge(client);
142
+ let cancelled = false;
143
+ let running = false;
144
+ let rerun = false;
145
+ let timer = null;
146
+ const emitError = (error) => {
147
+ var _a;
148
+ if (!cancelled) {
149
+ (_a = subscriber.error) === null || _a === void 0 ? void 0 : _a.call(subscriber, error);
150
+ }
151
+ };
152
+ const run = () => {
153
+ if (cancelled) {
154
+ return;
155
+ }
156
+ if (running) {
157
+ rerun = true;
158
+ return;
159
+ }
160
+ running = true;
161
+ Promise.resolve()
162
+ .then(() => querier())
163
+ .then((value) => {
164
+ var _a;
165
+ if (!cancelled) {
166
+ (_a = subscriber.next) === null || _a === void 0 ? void 0 : _a.call(subscriber, value);
167
+ }
168
+ })
169
+ .catch(emitError)
170
+ .finally(() => {
171
+ running = false;
172
+ if (rerun && !cancelled) {
173
+ rerun = false;
174
+ run();
175
+ }
176
+ });
177
+ };
178
+ const schedule = () => {
179
+ if (cancelled) {
180
+ return;
181
+ }
182
+ if (timer != null) {
183
+ return;
184
+ }
185
+ timer = setTimeout(() => {
186
+ timer = null;
187
+ run();
188
+ }, 0);
189
+ };
190
+ const onBatch = (_batch) => {
191
+ schedule();
192
+ };
193
+ bridge.listeners.add(onBatch);
194
+ run();
195
+ return {
196
+ refresh: schedule,
197
+ unsubscribe() {
198
+ var _a;
199
+ if (cancelled) {
200
+ return;
201
+ }
202
+ cancelled = true;
203
+ if (timer != null) {
204
+ clearTimeout(timer);
205
+ timer = null;
206
+ }
207
+ bridge.listeners.delete(onBatch);
208
+ releaseBridge(client);
209
+ (_a = subscriber.complete) === null || _a === void 0 ? void 0 : _a.call(subscriber);
210
+ },
211
+ };
212
+ },
213
+ };
214
+ }
215
+ exports.liveQuery = liveQuery;
216
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/liveQuery/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { DeclaredDbInterface, DeclaredStoreInterface, IndexInterface } from '../schema/types';
2
+ export interface InstalledStoreInterface {
3
+ name: string;
4
+ primaryKey: {
5
+ keyPath: string | string[] | null;
6
+ autoIncrement: boolean;
7
+ };
8
+ indexes: IndexInterface[];
9
+ }
10
+ export declare function readStoreSchemaFromTx(tx: IDBTransaction, storeName: string): InstalledStoreInterface;
11
+ export interface SchemaDiffInterface {
12
+ storesToCreate: DeclaredStoreInterface[];
13
+ storesToDelete: string[];
14
+ indexesToCreate: {
15
+ storeName: string;
16
+ index: IndexInterface;
17
+ }[];
18
+ indexesToDelete: {
19
+ storeName: string;
20
+ indexName: string;
21
+ }[];
22
+ keyPathConflicts: {
23
+ storeName: string;
24
+ installed: string | string[] | null;
25
+ declared: string;
26
+ }[];
27
+ }
28
+ export declare function diffSchema(tx: IDBTransaction, declared: DeclaredDbInterface): SchemaDiffInterface;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.diffSchema = exports.readStoreSchemaFromTx = void 0;
4
+ function keyPathEquals(a, b) {
5
+ if (Array.isArray(a) && Array.isArray(b)) {
6
+ return a.length === b.length && a.every((v, i) => v === b[i]);
7
+ }
8
+ return a === b;
9
+ }
10
+ function readStoreSchemaFromTx(tx, storeName) {
11
+ const store = tx.objectStore(storeName);
12
+ const indexes = [];
13
+ for (const indexName of Array.from(store.indexNames)) {
14
+ const index = store.index(indexName);
15
+ indexes.push({
16
+ name: index.name,
17
+ keyPath: index.keyPath,
18
+ unique: index.unique,
19
+ multiEntry: index.multiEntry,
20
+ });
21
+ }
22
+ return {
23
+ name: store.name,
24
+ primaryKey: {
25
+ keyPath: store.keyPath,
26
+ autoIncrement: store.autoIncrement,
27
+ },
28
+ indexes,
29
+ };
30
+ }
31
+ exports.readStoreSchemaFromTx = readStoreSchemaFromTx;
32
+ function diffSchema(tx, declared) {
33
+ const installedNames = new Set(Array.from(tx.objectStoreNames));
34
+ const declaredByName = new Map(declared.stores.map((s) => [s.name, s]));
35
+ const storesToCreate = [];
36
+ const storesToDelete = [];
37
+ const indexesToCreate = [];
38
+ const indexesToDelete = [];
39
+ const keyPathConflicts = [];
40
+ for (const store of declared.stores) {
41
+ if (!installedNames.has(store.name)) {
42
+ storesToCreate.push(store);
43
+ continue;
44
+ }
45
+ const installed = readStoreSchemaFromTx(tx, store.name);
46
+ if (!keyPathEquals(installed.primaryKey.keyPath, store.primaryKey.keyPath) ||
47
+ installed.primaryKey.autoIncrement !== store.primaryKey.autoIncrement) {
48
+ keyPathConflicts.push({
49
+ storeName: store.name,
50
+ installed: installed.primaryKey.keyPath,
51
+ declared: store.primaryKey.keyPath,
52
+ });
53
+ }
54
+ const installedIndexNames = new Set(installed.indexes.map((i) => i.name));
55
+ const declaredIndexNames = new Set(store.indexes.map((i) => i.name));
56
+ for (const index of store.indexes) {
57
+ const existing = installed.indexes.find((i) => i.name === index.name);
58
+ if (!existing) {
59
+ indexesToCreate.push({ storeName: store.name, index });
60
+ continue;
61
+ }
62
+ if (!keyPathEquals(existing.keyPath, index.keyPath) ||
63
+ Boolean(existing.unique) !== Boolean(index.unique) ||
64
+ Boolean(existing.multiEntry) !== Boolean(index.multiEntry)) {
65
+ indexesToDelete.push({ storeName: store.name, indexName: index.name });
66
+ indexesToCreate.push({ storeName: store.name, index });
67
+ }
68
+ }
69
+ for (const indexName of Array.from(installedIndexNames)) {
70
+ if (!declaredIndexNames.has(indexName)) {
71
+ indexesToDelete.push({ storeName: store.name, indexName });
72
+ }
73
+ }
74
+ }
75
+ for (const name of Array.from(installedNames)) {
76
+ if (!declaredByName.has(name)) {
77
+ storesToDelete.push(name);
78
+ }
79
+ }
80
+ return {
81
+ storesToCreate,
82
+ storesToDelete,
83
+ indexesToCreate,
84
+ indexesToDelete,
85
+ keyPathConflicts,
86
+ };
87
+ }
88
+ exports.diffSchema = diffSchema;
89
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/migrate/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { IndexInterface, PrimaryKeyInterface } from '../schema/types';
2
+ /** Create an index inside a `versionchange` / upgrade transaction. */
3
+ export declare function addIndex(tx: IDBTransaction, storeName: string, index: IndexInterface): void;
4
+ /** Delete an index inside a `versionchange` / upgrade transaction. */
5
+ export declare function dropIndex(tx: IDBTransaction, storeName: string, indexName: string): void;
6
+ export interface CopyStoreAndDropOptions {
7
+ /** Existing store to read from. */
8
+ from: string;
9
+ /**
10
+ * Destination store name.
11
+ * If equal to `from`, copies via a temporary store then swaps in place
12
+ * (required when changing `keyPath` while keeping the same store name).
13
+ */
14
+ to: string;
15
+ primaryKey: PrimaryKeyInterface;
16
+ indexes?: IndexInterface[];
17
+ /**
18
+ * Transform each record. Return `null` to skip.
19
+ * Default: shallow copy of the row.
20
+ */
21
+ map?: (row: Record<string, unknown>) => Record<string, unknown> | null;
22
+ }
23
+ /**
24
+ * Copy records into a (new) store, then drop the source (or swap in place).
25
+ *
26
+ * Use inside `upgrade` hooks when changing `keyPath` — IndexedDB cannot
27
+ * alter keyPath in place. Same-name recreate uses a temporary store.
28
+ */
29
+ export declare function copyStoreAndDrop(db: IDBDatabase, tx: IDBTransaction, options: CopyStoreAndDropOptions): void;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.copyStoreAndDrop = exports.dropIndex = exports.addIndex = void 0;
4
+ const errors_1 = require("../errors");
5
+ function createIndexOnStore(store, index) {
6
+ store.createIndex(index.name, index.keyPath, {
7
+ unique: Boolean(index.unique),
8
+ multiEntry: Boolean(index.multiEntry),
9
+ });
10
+ }
11
+ /** Create an index inside a `versionchange` / upgrade transaction. */
12
+ function addIndex(tx, storeName, index) {
13
+ const store = tx.objectStore(storeName);
14
+ if (store.indexNames.contains(index.name)) {
15
+ return;
16
+ }
17
+ createIndexOnStore(store, index);
18
+ }
19
+ exports.addIndex = addIndex;
20
+ /** Delete an index inside a `versionchange` / upgrade transaction. */
21
+ function dropIndex(tx, storeName, indexName) {
22
+ const store = tx.objectStore(storeName);
23
+ if (!store.indexNames.contains(indexName)) {
24
+ return;
25
+ }
26
+ store.deleteIndex(indexName);
27
+ }
28
+ exports.dropIndex = dropIndex;
29
+ function createStoreWithIndexes(db, name, primaryKey, indexes) {
30
+ const store = db.createObjectStore(name, {
31
+ keyPath: primaryKey.keyPath,
32
+ autoIncrement: Boolean(primaryKey.autoIncrement),
33
+ });
34
+ for (const index of indexes) {
35
+ createIndexOnStore(store, index);
36
+ }
37
+ }
38
+ function copyRows(rows, dest, map) {
39
+ for (const raw of rows) {
40
+ const row = raw;
41
+ const next = map ? map(row) : Object.assign({}, row);
42
+ if (next !== null) {
43
+ dest.put(next);
44
+ }
45
+ }
46
+ }
47
+ /**
48
+ * Copy records into a (new) store, then drop the source (or swap in place).
49
+ *
50
+ * Use inside `upgrade` hooks when changing `keyPath` — IndexedDB cannot
51
+ * alter keyPath in place. Same-name recreate uses a temporary store.
52
+ */
53
+ function copyStoreAndDrop(db, tx, options) {
54
+ const { from, to, primaryKey, indexes = [], map } = options;
55
+ if (!db.objectStoreNames.contains(from)) {
56
+ throw new errors_1.IndexedDbError('SCHEMA_INVALID', `copyStoreAndDrop: source store "${from}" does not exist`, { store: from });
57
+ }
58
+ const inPlace = from === to;
59
+ const destName = inPlace ? `${from}__idc_migrate` : to;
60
+ if (db.objectStoreNames.contains(destName)) {
61
+ throw new errors_1.IndexedDbError('SCHEMA_INVALID', `copyStoreAndDrop: destination store "${destName}" already exists`, { store: destName });
62
+ }
63
+ createStoreWithIndexes(db, destName, primaryKey, indexes);
64
+ const getAll = tx.objectStore(from).getAll();
65
+ getAll.onerror = () => {
66
+ console.error('copyStoreAndDrop getAll failed', getAll.error);
67
+ };
68
+ getAll.onsuccess = () => {
69
+ const rows = getAll.result;
70
+ // Re-resolve store from the live transaction (stale refs go inactive).
71
+ copyRows(rows, tx.objectStore(destName), map);
72
+ if (!inPlace) {
73
+ db.deleteObjectStore(from);
74
+ return;
75
+ }
76
+ db.deleteObjectStore(from);
77
+ createStoreWithIndexes(db, from, primaryKey, indexes);
78
+ const getTemp = tx.objectStore(destName).getAll();
79
+ getTemp.onerror = () => {
80
+ console.error('copyStoreAndDrop temp getAll failed', getTemp.error);
81
+ };
82
+ getTemp.onsuccess = () => {
83
+ copyRows(getTemp.result, tx.objectStore(from), undefined);
84
+ db.deleteObjectStore(destName);
85
+ };
86
+ };
87
+ }
88
+ exports.copyStoreAndDrop = copyStoreAndDrop;
89
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/migrate/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { diffSchema, readStoreSchemaFromTx } from './diff';
2
+ export type { InstalledStoreInterface, SchemaDiffInterface, } from './diff';
3
+ export { applySchemaUpgrade, assertKeyPathsMatchSchema } from './upgrade';
4
+ export type { ApplyUpgradeArgsInterface } from './upgrade';
5
+ export { addIndex, dropIndex, copyStoreAndDrop } from './helpers';
6
+ export type { CopyStoreAndDropOptions } from './helpers';
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.copyStoreAndDrop = exports.dropIndex = exports.addIndex = exports.assertKeyPathsMatchSchema = exports.applySchemaUpgrade = exports.readStoreSchemaFromTx = exports.diffSchema = void 0;
4
+ var diff_1 = require("./diff");
5
+ Object.defineProperty(exports, "diffSchema", { enumerable: true, get: function () { return diff_1.diffSchema; } });
6
+ Object.defineProperty(exports, "readStoreSchemaFromTx", { enumerable: true, get: function () { return diff_1.readStoreSchemaFromTx; } });
7
+ var upgrade_1 = require("./upgrade");
8
+ Object.defineProperty(exports, "applySchemaUpgrade", { enumerable: true, get: function () { return upgrade_1.applySchemaUpgrade; } });
9
+ Object.defineProperty(exports, "assertKeyPathsMatchSchema", { enumerable: true, get: function () { return upgrade_1.assertKeyPathsMatchSchema; } });
10
+ var helpers_1 = require("./helpers");
11
+ Object.defineProperty(exports, "addIndex", { enumerable: true, get: function () { return helpers_1.addIndex; } });
12
+ Object.defineProperty(exports, "dropIndex", { enumerable: true, get: function () { return helpers_1.dropIndex; } });
13
+ Object.defineProperty(exports, "copyStoreAndDrop", { enumerable: true, get: function () { return helpers_1.copyStoreAndDrop; } });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrate/index.ts"],"names":[],"mappings":";;;AAAA,+BAA2D;AAAlD,kGAAA,UAAU,OAAA;AAAE,6GAAA,qBAAqB,OAAA;AAK1C,qCAA0E;AAAjE,6GAAA,kBAAkB,OAAA;AAAE,oHAAA,yBAAyB,OAAA;AAEtD,qCAAkE;AAAzD,mGAAA,QAAQ,OAAA;AAAE,oGAAA,SAAS,OAAA;AAAE,2GAAA,gBAAgB,OAAA"}
@@ -0,0 +1,19 @@
1
+ import type { DeclaredDbInterface, UpgradeFn } from '../schema/types';
2
+ /** Sync check after upgrade tx completed (e.g. on open success). */
3
+ export declare function assertKeyPathsMatchSchema(db: IDBDatabase, schema: DeclaredDbInterface): void;
4
+ export interface ApplyUpgradeArgsInterface {
5
+ db: IDBDatabase;
6
+ tx: IDBTransaction;
7
+ schema: DeclaredDbInterface;
8
+ oldVersion: number;
9
+ newVersion: number;
10
+ upgradeHooks?: Record<number, UpgradeFn>;
11
+ }
12
+ /**
13
+ * Apply structural schema changes and versioned upgrade hooks.
14
+ *
15
+ * When declared `keyPath` differs from installed, hooks run **first** so they
16
+ * can `copyStoreAndDrop`. Structural ops for those stores are skipped in this
17
+ * turn (the helper recreates them). A final keyPath check runs on open success.
18
+ */
19
+ export declare function applySchemaUpgrade(args: ApplyUpgradeArgsInterface): void;
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applySchemaUpgrade = exports.assertKeyPathsMatchSchema = void 0;
4
+ const errors_1 = require("../errors");
5
+ const diff_1 = require("./diff");
6
+ function createIndex(store, index) {
7
+ store.createIndex(index.name, index.keyPath, {
8
+ unique: Boolean(index.unique),
9
+ multiEntry: Boolean(index.multiEntry),
10
+ });
11
+ }
12
+ function keyPathEquals(a, b) {
13
+ if (Array.isArray(a) && Array.isArray(b)) {
14
+ return a.length === b.length && a.every((v, i) => v === b[i]);
15
+ }
16
+ return a === b;
17
+ }
18
+ function runUpgradeHooks(tx, oldVersion, newVersion, upgradeHooks) {
19
+ if (!upgradeHooks) {
20
+ return;
21
+ }
22
+ const versions = Object.keys(upgradeHooks)
23
+ .map(Number)
24
+ .filter((v) => v > oldVersion && v <= newVersion)
25
+ .sort((a, b) => a - b);
26
+ for (const version of versions) {
27
+ const hook = upgradeHooks[version];
28
+ void hook(tx, { oldVersion, newVersion });
29
+ }
30
+ }
31
+ /** Sync check after upgrade tx completed (e.g. on open success). */
32
+ function assertKeyPathsMatchSchema(db, schema) {
33
+ const existing = schema.stores
34
+ .map((s) => s.name)
35
+ .filter((n) => db.objectStoreNames.contains(n));
36
+ if (existing.length === 0) {
37
+ return;
38
+ }
39
+ const tx = db.transaction(existing, 'readonly');
40
+ const conflicts = [];
41
+ for (const store of schema.stores) {
42
+ if (!db.objectStoreNames.contains(store.name)) {
43
+ continue;
44
+ }
45
+ const installed = (0, diff_1.readStoreSchemaFromTx)(tx, store.name);
46
+ if (!keyPathEquals(installed.primaryKey.keyPath, store.primaryKey.keyPath) ||
47
+ installed.primaryKey.autoIncrement !== store.primaryKey.autoIncrement) {
48
+ conflicts.push(`"${store.name}": installed keyPath ${JSON.stringify(installed.primaryKey.keyPath)} vs declared "${store.primaryKey.keyPath}"`);
49
+ }
50
+ }
51
+ if (conflicts.length === 0) {
52
+ return;
53
+ }
54
+ throw new errors_1.IndexedDbError('SCHEMA_MISMATCH', `Cannot change object store keyPath in place. Use copyStoreAndDrop() in an upgrade hook (see docs/upgrades.md). Conflicts: ${conflicts.join('; ')}`);
55
+ }
56
+ exports.assertKeyPathsMatchSchema = assertKeyPathsMatchSchema;
57
+ /**
58
+ * Apply structural schema changes and versioned upgrade hooks.
59
+ *
60
+ * When declared `keyPath` differs from installed, hooks run **first** so they
61
+ * can `copyStoreAndDrop`. Structural ops for those stores are skipped in this
62
+ * turn (the helper recreates them). A final keyPath check runs on open success.
63
+ */
64
+ function applySchemaUpgrade(args) {
65
+ const { db, tx, schema, oldVersion, newVersion, upgradeHooks } = args;
66
+ const diff = (0, diff_1.diffSchema)(tx, schema);
67
+ const conflicted = new Set(diff.keyPathConflicts.map((c) => c.storeName));
68
+ const hasKeyPathConflict = conflicted.size > 0;
69
+ if (hasKeyPathConflict) {
70
+ runUpgradeHooks(tx, oldVersion, newVersion, upgradeHooks);
71
+ }
72
+ const next = hasKeyPathConflict ? (0, diff_1.diffSchema)(tx, schema) : diff;
73
+ // After async copyStoreAndDrop the sync re-diff may still see old keyPaths;
74
+ // never delete/recreate conflicted stores here — hooks own that.
75
+ const skip = (storeName) => conflicted.has(storeName);
76
+ for (const storeName of next.storesToDelete) {
77
+ if (skip(storeName)) {
78
+ continue;
79
+ }
80
+ // Temporary stores used by copyStoreAndDrop during this upgrade.
81
+ if (storeName.endsWith('__idc_migrate')) {
82
+ continue;
83
+ }
84
+ db.deleteObjectStore(storeName);
85
+ }
86
+ for (const store of next.storesToCreate) {
87
+ if (skip(store.name)) {
88
+ continue;
89
+ }
90
+ const objectStore = db.createObjectStore(store.name, {
91
+ keyPath: store.primaryKey.keyPath,
92
+ autoIncrement: store.primaryKey.autoIncrement,
93
+ });
94
+ for (const index of store.indexes) {
95
+ createIndex(objectStore, index);
96
+ }
97
+ }
98
+ for (const { storeName, indexName } of next.indexesToDelete) {
99
+ if (skip(storeName)) {
100
+ continue;
101
+ }
102
+ if (db.objectStoreNames.contains(storeName)) {
103
+ const store = tx.objectStore(storeName);
104
+ if (store.indexNames.contains(indexName)) {
105
+ store.deleteIndex(indexName);
106
+ }
107
+ }
108
+ }
109
+ for (const { storeName, index } of next.indexesToCreate) {
110
+ if (skip(storeName)) {
111
+ continue;
112
+ }
113
+ const store = tx.objectStore(storeName);
114
+ if (!store.indexNames.contains(index.name)) {
115
+ createIndex(store, index);
116
+ }
117
+ }
118
+ if (!hasKeyPathConflict) {
119
+ runUpgradeHooks(tx, oldVersion, newVersion, upgradeHooks);
120
+ }
121
+ }
122
+ exports.applySchemaUpgrade = applySchemaUpgrade;
123
+ //# sourceMappingURL=upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/migrate/upgrade.ts"],"names":[],"mappings":"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"}