@roc-db/indexed-db 0.2.0-pre.10 → 0.2.0-pre.100
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/dist/index.js +321 -199
- package/dist/types/createIndexedDBAdapter.d.ts +11 -18
- package/dist/types/functions/batchReadEntities.d.ts +3 -0
- package/dist/types/functions/begin.d.ts +3 -1
- package/dist/types/functions/commit.d.ts +3 -0
- package/dist/types/functions/commitCreate.d.ts +3 -0
- package/dist/types/functions/commitDelete.d.ts +3 -0
- package/dist/types/functions/commitUpdate.d.ts +3 -0
- package/dist/types/functions/end.d.ts +1 -2
- package/dist/types/functions/findDebounceMutation.d.ts +2 -3
- package/dist/types/functions/getChangeSetMutations.d.ts +2 -3
- package/dist/types/functions/index.d.ts +5 -4
- package/dist/types/functions/pageEntities.d.ts +2 -0
- package/dist/types/functions/pageEntitiesByIndex.d.ts +2 -0
- package/dist/types/functions/pageMutations.d.ts +2 -2
- package/dist/types/functions/readEntity.d.ts +3 -1
- package/dist/types/functions/readMutation.d.ts +2 -1
- package/dist/types/functions/refByUniqueField.d.ts +2 -0
- package/dist/types/functions/saveMutation.d.ts +2 -1
- package/dist/types/lib/documentFromDBRow.d.ts +1 -0
- package/dist/types/lib/documentToDBRow.d.ts +1 -0
- package/dist/types/types/IndexedDBEngine.d.ts +5 -0
- package/dist/types/types/IndexedDBReadTransaction.d.ts +1 -2
- package/dist/types/types/IndexedDBWriteTransaction.d.ts +3 -0
- package/package.json +8 -4
- package/dist/types/functions/createEntity.d.ts +0 -3
- package/dist/types/functions/deleteEntity.d.ts +0 -1
- package/dist/types/functions/patchEntity.d.ts +0 -7
- package/dist/types/functions/updateEntity.d.ts +0 -6
package/dist/index.js
CHANGED
|
@@ -10,33 +10,83 @@ var __export = (target, all) => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
// src/createIndexedDBAdapter.ts
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
createAdapter,
|
|
15
|
+
Snowflake
|
|
16
|
+
} from "roc-db";
|
|
14
17
|
|
|
15
18
|
// src/functions/index.ts
|
|
16
19
|
var exports_functions = {};
|
|
17
20
|
__export(exports_functions, {
|
|
18
|
-
updateEntity: () => updateEntity,
|
|
19
21
|
saveMutation: () => saveMutation,
|
|
22
|
+
refByUniqueField: () => refByUniqueField,
|
|
20
23
|
readMutation: () => readMutation,
|
|
21
24
|
readEntity: () => readEntity,
|
|
22
|
-
patchEntity: () => patchEntity,
|
|
23
25
|
pageMutations: () => pageMutations,
|
|
26
|
+
pageEntitiesByIndex: () => pageEntitiesByIndex,
|
|
27
|
+
pageEntities: () => pageEntities,
|
|
24
28
|
getChangeSetMutations: () => getChangeSetMutations,
|
|
25
29
|
findDebounceMutation: () => findDebounceMutation,
|
|
26
30
|
end: () => end,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
commit: () => commit,
|
|
32
|
+
begin: () => begin,
|
|
33
|
+
batchReadEntities: () => batchReadEntities
|
|
30
34
|
});
|
|
31
35
|
|
|
32
|
-
// src/
|
|
33
|
-
var
|
|
36
|
+
// src/lib/documentFromDBRow.ts
|
|
37
|
+
var documentFromDBRow = ({
|
|
38
|
+
unique_constraint_0,
|
|
39
|
+
unique_constraint_1,
|
|
40
|
+
index_entries,
|
|
41
|
+
...document
|
|
42
|
+
}) => {
|
|
43
|
+
return {
|
|
44
|
+
...document,
|
|
45
|
+
__: {
|
|
46
|
+
uniqueExisting: [],
|
|
47
|
+
indexExisting: []
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// src/functions/readEntity.ts
|
|
53
|
+
var readEntity = async (txn, ref) => {
|
|
54
|
+
const objectStore = txn.engineOpts.txn.objectStore("entities");
|
|
55
|
+
const request = objectStore.get(ref);
|
|
34
56
|
return new Promise((resolve, reject) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
57
|
+
request.onsuccess = (event) => {
|
|
58
|
+
const result = event.target.result;
|
|
59
|
+
if (!result) {
|
|
60
|
+
return resolve(undefined);
|
|
61
|
+
}
|
|
62
|
+
resolve(documentFromDBRow(result));
|
|
63
|
+
};
|
|
64
|
+
request.onerror = (event) => {
|
|
65
|
+
reject(event.target.error);
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// src/functions/batchReadEntities.ts
|
|
71
|
+
var batchReadEntities = (txn, refs) => {
|
|
72
|
+
return Promise.all(refs.map((ref) => readEntity(txn, ref)));
|
|
73
|
+
};
|
|
74
|
+
// src/functions/begin.ts
|
|
75
|
+
var DB_CACHE = new WeakMap;
|
|
76
|
+
var openDatabase = (engineOpts) => {
|
|
77
|
+
let cached = DB_CACHE.get(engineOpts);
|
|
78
|
+
if (cached)
|
|
79
|
+
return cached;
|
|
80
|
+
const promise = new Promise((resolve, reject) => {
|
|
81
|
+
const idbRequest = indexedDB.open(engineOpts.dbName, engineOpts.version);
|
|
82
|
+
idbRequest.onupgradeneeded = () => {
|
|
38
83
|
const entitiesObjectStore = idbRequest.result.createObjectStore("entities", { keyPath: "ref" });
|
|
39
84
|
const mutationsObjectStore = idbRequest.result.createObjectStore("mutations", { keyPath: "ref" });
|
|
85
|
+
entitiesObjectStore.createIndex("unique_constraint_0", ["entity", "unique_constraint_0"], { unique: true });
|
|
86
|
+
entitiesObjectStore.createIndex("unique_constraint_1", ["entity", "unique_constraint_1"], { unique: true });
|
|
87
|
+
entitiesObjectStore.createIndex("byIndexEntry", "index_entries", {
|
|
88
|
+
multiEntry: true
|
|
89
|
+
});
|
|
40
90
|
mutationsObjectStore.createIndex("timestamp", "timestamp", {
|
|
41
91
|
unique: false
|
|
42
92
|
});
|
|
@@ -44,104 +94,209 @@ var begin = async (request, engineOpts, callback) => {
|
|
|
44
94
|
unique: false
|
|
45
95
|
});
|
|
46
96
|
};
|
|
47
|
-
idbRequest.onsuccess = (
|
|
48
|
-
db = idbRequest.result;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
97
|
+
idbRequest.onsuccess = () => {
|
|
98
|
+
const db = idbRequest.result;
|
|
99
|
+
db.onversionchange = () => {
|
|
100
|
+
db.close();
|
|
101
|
+
DB_CACHE.delete(engineOpts);
|
|
102
|
+
};
|
|
103
|
+
resolve(db);
|
|
104
|
+
};
|
|
105
|
+
idbRequest.onerror = () => {
|
|
106
|
+
DB_CACHE.delete(engineOpts);
|
|
107
|
+
reject(idbRequest.error);
|
|
58
108
|
};
|
|
59
109
|
});
|
|
110
|
+
DB_CACHE.set(engineOpts, promise);
|
|
111
|
+
return promise;
|
|
60
112
|
};
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
113
|
+
var begin = async (engineOpts, callback) => {
|
|
114
|
+
const db = await openDatabase(engineOpts);
|
|
115
|
+
return new Promise((resolve, reject) => {
|
|
116
|
+
const txn = db.transaction(["entities", "mutations"], "readwrite");
|
|
117
|
+
let callbackResult;
|
|
118
|
+
let callbackDone = false;
|
|
119
|
+
let txnComplete = false;
|
|
120
|
+
let settled = false;
|
|
121
|
+
const maybeResolve = () => {
|
|
122
|
+
if (settled)
|
|
123
|
+
return;
|
|
124
|
+
if (callbackDone && txnComplete) {
|
|
125
|
+
settled = true;
|
|
126
|
+
resolve(callbackResult);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
txn.oncomplete = () => {
|
|
130
|
+
txnComplete = true;
|
|
131
|
+
maybeResolve();
|
|
132
|
+
};
|
|
133
|
+
txn.onerror = (event) => {
|
|
134
|
+
if (settled)
|
|
135
|
+
return;
|
|
136
|
+
settled = true;
|
|
137
|
+
reject(txn.error ?? event.target?.error);
|
|
138
|
+
};
|
|
139
|
+
txn.onabort = () => {
|
|
140
|
+
if (settled)
|
|
141
|
+
return;
|
|
142
|
+
settled = true;
|
|
143
|
+
reject(txn.error ?? new Error("Transaction aborted"));
|
|
144
|
+
};
|
|
145
|
+
Promise.resolve(callback({
|
|
146
|
+
...engineOpts,
|
|
147
|
+
db,
|
|
148
|
+
txn
|
|
149
|
+
})).then((result) => {
|
|
150
|
+
callbackResult = result;
|
|
151
|
+
callbackDone = true;
|
|
152
|
+
maybeResolve();
|
|
153
|
+
}).catch((error) => {
|
|
154
|
+
if (settled)
|
|
155
|
+
return;
|
|
156
|
+
settled = true;
|
|
157
|
+
try {
|
|
158
|
+
txn.abort();
|
|
159
|
+
} catch {}
|
|
160
|
+
reject(error);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
// src/functions/commitCreate.ts
|
|
165
|
+
import { createUniqueConstraintConflictError } from "roc-db";
|
|
166
|
+
var commitCreate = (txn, document) => {
|
|
64
167
|
const objectStore = txn.engineOpts.txn.objectStore("entities");
|
|
168
|
+
const request = objectStore.add(document);
|
|
169
|
+
return new Promise((resolve, reject) => {
|
|
170
|
+
request.onsuccess = (event) => {
|
|
171
|
+
resolve(document);
|
|
172
|
+
};
|
|
173
|
+
request.onerror = (event) => {
|
|
174
|
+
const error = event?.target?.error;
|
|
175
|
+
if (error?.name === "ConstraintError") {
|
|
176
|
+
event.stopPropagation();
|
|
177
|
+
event.preventDefault();
|
|
178
|
+
reject(createUniqueConstraintConflictError(document.entity));
|
|
179
|
+
} else {
|
|
180
|
+
console.error("Error creating entity:", document, error);
|
|
181
|
+
reject(error);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// src/functions/commitDelete.ts
|
|
188
|
+
import { entityFromRef } from "roc-db";
|
|
189
|
+
var commitDelete = async (txn, ref) => {
|
|
65
190
|
const entity = entityFromRef(ref);
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
timestamp: txn.mutation.timestamp
|
|
71
|
-
},
|
|
72
|
-
updated: {
|
|
73
|
-
mutationRef: txn.mutation.ref,
|
|
74
|
-
timestamp: txn.mutation.timestamp
|
|
75
|
-
},
|
|
76
|
-
entity,
|
|
77
|
-
data,
|
|
78
|
-
children,
|
|
79
|
-
ancestors,
|
|
80
|
-
parents
|
|
81
|
-
};
|
|
82
|
-
if (txn.request.changeSetRef) {
|
|
83
|
-
if (txn.engineOpts.changeSet.entities.has(ref)) {
|
|
84
|
-
throw new Error("Entity already exists in changeSet");
|
|
85
|
-
} else {
|
|
86
|
-
txn.engineOpts.changeSet.entities.set(ref, document);
|
|
87
|
-
return document;
|
|
88
|
-
}
|
|
191
|
+
const engineTxn = txn.engineOpts.txn;
|
|
192
|
+
let objectStore;
|
|
193
|
+
if (entity === "Mutation") {
|
|
194
|
+
objectStore = engineTxn.objectStore("mutations");
|
|
89
195
|
} else {
|
|
90
|
-
|
|
91
|
-
return new Promise((resolve, reject) => {
|
|
92
|
-
request.onsuccess = (event) => {
|
|
93
|
-
resolve(document);
|
|
94
|
-
};
|
|
95
|
-
request.onerror = (event) => {
|
|
96
|
-
console.error("Error creating entity:", document, event?.target?.error);
|
|
97
|
-
reject(event?.target?.error);
|
|
98
|
-
};
|
|
99
|
-
});
|
|
196
|
+
objectStore = engineTxn.objectStore("entities");
|
|
100
197
|
}
|
|
101
|
-
|
|
102
|
-
// src/functions/deleteEntity.ts
|
|
103
|
-
import { DELETED_IN_CHANGE_SET_SYMBOL } from "roc-db";
|
|
104
|
-
var deleteIndexed = (store, ref) => {
|
|
105
|
-
const request = store.delete(ref);
|
|
198
|
+
const request = objectStore.delete(ref);
|
|
106
199
|
return new Promise((resolve, reject) => {
|
|
107
200
|
request.onsuccess = () => {
|
|
108
201
|
resolve(true);
|
|
109
202
|
};
|
|
110
203
|
request.onerror = (event) => {
|
|
111
|
-
console.error("Error
|
|
204
|
+
console.error("Error deleting document", event?.target?.error);
|
|
112
205
|
reject(event?.target?.error);
|
|
113
206
|
};
|
|
114
207
|
});
|
|
115
208
|
};
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
209
|
+
|
|
210
|
+
// src/functions/commitUpdate.ts
|
|
211
|
+
var commitUpdate = async (txn, document) => {
|
|
212
|
+
const objectStore = txn.engineOpts.txn.objectStore("entities");
|
|
213
|
+
const request = objectStore.put(document);
|
|
214
|
+
return new Promise((resolve, reject) => {
|
|
215
|
+
request.onsuccess = (event) => {
|
|
216
|
+
resolve(document);
|
|
217
|
+
};
|
|
218
|
+
request.onerror = (event) => {
|
|
219
|
+
console.error("Error updating document", event?.target?.error);
|
|
220
|
+
reject(event?.target?.error);
|
|
221
|
+
};
|
|
222
|
+
});
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
// src/functions/saveMutation.ts
|
|
226
|
+
var saveMutation = (txn, finalizedMutation) => {
|
|
227
|
+
const objectStore = txn.engineOpts.txn.objectStore("mutations");
|
|
228
|
+
let request;
|
|
229
|
+
if (finalizedMutation.debounceCount > 0 || finalizedMutation.appliedAt) {
|
|
230
|
+
request = objectStore.put(finalizedMutation);
|
|
123
231
|
} else {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
232
|
+
request = objectStore.add(finalizedMutation);
|
|
233
|
+
}
|
|
234
|
+
return new Promise((resolve, reject) => {
|
|
235
|
+
request.onsuccess = (event) => {
|
|
236
|
+
resolve(finalizedMutation);
|
|
237
|
+
};
|
|
238
|
+
request.onerror = (event) => {
|
|
239
|
+
console.error("Error saving mutation", event?.target?.error);
|
|
240
|
+
reject(event?.target?.error);
|
|
241
|
+
};
|
|
242
|
+
});
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
// src/lib/documentToDBRow.ts
|
|
246
|
+
var stringifyIndexEntry = (entity, [k, v]) => `${entity}:${k}:${JSON.stringify(v)}`;
|
|
247
|
+
var stringifyUniqueEntry = ([k, v]) => `${k}:${JSON.stringify(v)}`;
|
|
248
|
+
var stringifyIndexEntries = (entity, arr) => {
|
|
249
|
+
return arr.map((pair) => stringifyIndexEntry(entity, pair));
|
|
250
|
+
};
|
|
251
|
+
var documentToDBRow = (document) => {
|
|
252
|
+
return {
|
|
253
|
+
...document,
|
|
254
|
+
index_entries: document.__.index ? stringifyIndexEntries(document.entity, document.__.index) : [],
|
|
255
|
+
unique_constraint_0: document.__?.unique?.[0] ? stringifyUniqueEntry(document.__?.unique?.[0]) : null,
|
|
256
|
+
unique_constraint_1: document.__?.unique?.[1] ? stringifyUniqueEntry(document.__?.unique?.[1]) : null
|
|
257
|
+
};
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
// src/functions/commit.ts
|
|
261
|
+
var commit = async (txn, mutation, { created, updated, deleted }) => {
|
|
262
|
+
const currentMutation = await txn.readMutation(txn.mutation.ref, false);
|
|
263
|
+
if (currentMutation) {
|
|
264
|
+
if (currentMutation && mutation.appliedAt === txn.timestamp) {
|
|
265
|
+
await saveMutation(txn, mutation);
|
|
266
|
+
} else if (currentMutation && mutation.debounceCount > currentMutation.debounceCount) {
|
|
267
|
+
await saveMutation(txn, mutation);
|
|
268
|
+
} else {
|
|
269
|
+
throw new Error("Mutation already exists");
|
|
128
270
|
}
|
|
129
|
-
|
|
271
|
+
} else {
|
|
272
|
+
await saveMutation(txn, mutation);
|
|
273
|
+
}
|
|
274
|
+
if (txn.request.changeSetRef)
|
|
275
|
+
return mutation;
|
|
276
|
+
for (const doc of created) {
|
|
277
|
+
await commitCreate(txn, documentToDBRow(doc));
|
|
130
278
|
}
|
|
279
|
+
for (const doc of updated) {
|
|
280
|
+
await commitUpdate(txn, documentToDBRow(doc));
|
|
281
|
+
}
|
|
282
|
+
for (const ref of deleted) {
|
|
283
|
+
await commitDelete(txn, ref);
|
|
284
|
+
}
|
|
285
|
+
return mutation;
|
|
131
286
|
};
|
|
132
287
|
// src/functions/end.ts
|
|
133
|
-
var end = (
|
|
288
|
+
var end = (engineOpts) => {
|
|
134
289
|
return new Promise((resolve, reject) => {
|
|
135
|
-
|
|
290
|
+
engineOpts.txn.oncomplete = () => {
|
|
136
291
|
resolve(undefined);
|
|
137
292
|
};
|
|
138
|
-
|
|
293
|
+
engineOpts.txn.onerror = (event) => {
|
|
139
294
|
reject(event.target.error);
|
|
140
295
|
};
|
|
141
296
|
});
|
|
142
297
|
};
|
|
143
298
|
// src/functions/getChangeSetMutations.ts
|
|
144
|
-
var getChangeSetMutations =
|
|
299
|
+
var getChangeSetMutations = (txn, changeSetRef) => {
|
|
145
300
|
const objectStore = txn.engineOpts.txn.objectStore("mutations");
|
|
146
301
|
const index = objectStore.index("byChangeSetRef");
|
|
147
302
|
const range = IDBKeyRange.only(changeSetRef);
|
|
@@ -160,11 +315,10 @@ var getChangeSetMutations = async (txn, changeSetRef) => {
|
|
|
160
315
|
});
|
|
161
316
|
};
|
|
162
317
|
// src/functions/findDebounceMutation.ts
|
|
163
|
-
var findDebounceMutation =
|
|
164
|
-
const mutationName = request.schema.shape.name.value;
|
|
318
|
+
var findDebounceMutation = (request, engine, now, mutationName, identityRef) => {
|
|
165
319
|
const objectStore = engine.txn.objectStore("mutations");
|
|
166
320
|
const index = objectStore.index("timestamp");
|
|
167
|
-
const timestamp = new Date(now - request.
|
|
321
|
+
const timestamp = new Date(now.getTime() - request.operation.debounce * 1000).toISOString();
|
|
168
322
|
const range = IDBKeyRange.lowerBound(timestamp, true);
|
|
169
323
|
const idbRequest = index.openCursor(range);
|
|
170
324
|
return new Promise((resolve, reject) => {
|
|
@@ -173,31 +327,59 @@ var findDebounceMutation = async (request, engine, now) => {
|
|
|
173
327
|
const cursor = idbRequest.result;
|
|
174
328
|
if (cursor) {
|
|
175
329
|
const doc = cursor.value;
|
|
176
|
-
if (doc.name === mutationName && doc.payload.ref === request.payload.ref && doc.changeSetRef === request.changeSetRef) {
|
|
330
|
+
if (doc.operation.name === mutationName && doc.payload.ref === request.payload.ref && doc.changeSetRef === request.changeSetRef && doc.identityRef === identityRef) {
|
|
177
331
|
results.push(doc);
|
|
178
332
|
}
|
|
179
333
|
cursor.continue();
|
|
180
334
|
} else {
|
|
181
|
-
if (results.length) {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
335
|
+
if (results.length > 1) {
|
|
336
|
+
reject(new Error("Unhandled multiple debounced mutations"));
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
resolve(results[0]);
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
idbRequest.onerror = () => {
|
|
343
|
+
reject(idbRequest.error);
|
|
344
|
+
};
|
|
345
|
+
});
|
|
346
|
+
};
|
|
347
|
+
// src/functions/pageEntities.ts
|
|
348
|
+
var pageEntities = async (txn, args) => {
|
|
349
|
+
const { size, entities, childrenOf } = args;
|
|
350
|
+
const objectStore = txn.engineOpts.txn.objectStore("entities");
|
|
351
|
+
const idbRequest = objectStore.openCursor();
|
|
352
|
+
return new Promise((resolve, reject) => {
|
|
353
|
+
const results = [];
|
|
354
|
+
idbRequest.onsuccess = () => {
|
|
355
|
+
if (results.length >= size) {
|
|
356
|
+
resolve(results);
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
const cursor = idbRequest.result;
|
|
360
|
+
if (cursor) {
|
|
361
|
+
if (entities && entities !== "*" && !entities.includes(cursor.value.entity)) {
|
|
362
|
+
cursor.continue();
|
|
186
363
|
} else {
|
|
187
|
-
|
|
364
|
+
if (childrenOf && childrenOf.length > 0 && !childrenOf.some((childRef) => cursor.value.__.parentRefs.includes(childRef))) {
|
|
365
|
+
cursor.continue();
|
|
366
|
+
} else {
|
|
367
|
+
results.push(cursor.value);
|
|
368
|
+
cursor.continue();
|
|
369
|
+
}
|
|
188
370
|
}
|
|
371
|
+
} else {
|
|
372
|
+
resolve(results);
|
|
189
373
|
}
|
|
190
374
|
};
|
|
191
375
|
});
|
|
192
376
|
};
|
|
193
|
-
// src/functions/
|
|
194
|
-
var
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
const
|
|
199
|
-
const index = objectStore.index("byChangeSetRef");
|
|
200
|
-
const range = IDBKeyRange.only(changeSetRef);
|
|
377
|
+
// src/functions/pageEntitiesByIndex.ts
|
|
378
|
+
var pageEntitiesByIndex = async (txn, entity, field, value) => {
|
|
379
|
+
const objectStore = txn.engineOpts.txn.objectStore("entities");
|
|
380
|
+
const index = objectStore.index("byIndexEntry");
|
|
381
|
+
const entry = `${entity}:${field}:${JSON.stringify(value)}`;
|
|
382
|
+
const range = IDBKeyRange.only(entry);
|
|
201
383
|
const idbRequest = index.openCursor(range);
|
|
202
384
|
return new Promise((resolve, reject) => {
|
|
203
385
|
const results = [];
|
|
@@ -212,65 +394,31 @@ var pageMutations = async (txn, args) => {
|
|
|
212
394
|
};
|
|
213
395
|
});
|
|
214
396
|
};
|
|
215
|
-
// src/functions/
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
return doc;
|
|
397
|
+
// src/functions/pageMutations.ts
|
|
398
|
+
var pageMutations = async (txn, args) => {
|
|
399
|
+
const { size, changeSetRef, skip } = args;
|
|
400
|
+
const objectStore = txn.engineOpts.txn.objectStore("mutations");
|
|
401
|
+
let idbRequest;
|
|
402
|
+
if (changeSetRef) {
|
|
403
|
+
const index = objectStore.index("byChangeSetRef");
|
|
404
|
+
const range = IDBKeyRange.only(changeSetRef);
|
|
405
|
+
idbRequest = index.openCursor(range);
|
|
406
|
+
} else {
|
|
407
|
+
idbRequest = objectStore.openCursor();
|
|
227
408
|
}
|
|
228
|
-
const objectStore = txn.engineOpts.txn.objectStore("entities");
|
|
229
|
-
const request = objectStore.get(ref);
|
|
230
409
|
return new Promise((resolve, reject) => {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
410
|
+
const results = [];
|
|
411
|
+
idbRequest.onsuccess = () => {
|
|
412
|
+
const cursor = idbRequest.result;
|
|
413
|
+
if (cursor) {
|
|
414
|
+
results.push(cursor.value);
|
|
415
|
+
cursor.continue();
|
|
416
|
+
} else {
|
|
417
|
+
resolve(results);
|
|
418
|
+
}
|
|
237
419
|
};
|
|
238
420
|
});
|
|
239
421
|
};
|
|
240
|
-
|
|
241
|
-
// src/functions/patchEntity.ts
|
|
242
|
-
var patchEntity = async (txn, ref, { data = {}, children = {}, parents = {}, ancestors = {} }) => {
|
|
243
|
-
const existingDocument = await readEntity(txn, ref);
|
|
244
|
-
if (!existingDocument)
|
|
245
|
-
throw new NotFoundError(ref);
|
|
246
|
-
const updatedDocument = {
|
|
247
|
-
...existingDocument,
|
|
248
|
-
updated: {
|
|
249
|
-
timestamp: txn.mutation.timestamp,
|
|
250
|
-
mutationRef: txn.mutation.ref
|
|
251
|
-
},
|
|
252
|
-
data: deepPatch(existingDocument.data, data),
|
|
253
|
-
children: deepPatch(existingDocument.children, children),
|
|
254
|
-
parents: deepPatch(existingDocument.parents, parents),
|
|
255
|
-
ancestors: deepPatch(existingDocument.ancestors, ancestors)
|
|
256
|
-
};
|
|
257
|
-
if (txn.request.changeSetRef) {
|
|
258
|
-
txn.engineOpts.changeSet.entities.set(ref, updatedDocument);
|
|
259
|
-
return updatedDocument;
|
|
260
|
-
} else {
|
|
261
|
-
const objectStore = txn.engineOpts.txn.objectStore("entities");
|
|
262
|
-
const request = objectStore.put(updatedDocument);
|
|
263
|
-
return new Promise((resolve, reject) => {
|
|
264
|
-
request.onsuccess = (event) => {
|
|
265
|
-
resolve(updatedDocument);
|
|
266
|
-
};
|
|
267
|
-
request.onerror = (event) => {
|
|
268
|
-
console.error("Error patching document", event?.target?.error);
|
|
269
|
-
reject(event?.target?.error);
|
|
270
|
-
};
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
422
|
// src/functions/readMutation.ts
|
|
275
423
|
var readMutation = (engineOpts, ref) => {
|
|
276
424
|
const objectStore = engineOpts.txn.objectStore("mutations");
|
|
@@ -285,67 +433,41 @@ var readMutation = (engineOpts, ref) => {
|
|
|
285
433
|
};
|
|
286
434
|
});
|
|
287
435
|
};
|
|
288
|
-
// src/functions/
|
|
289
|
-
var
|
|
290
|
-
const objectStore = txn.engineOpts.txn.objectStore("
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
436
|
+
// src/functions/refByUniqueField.ts
|
|
437
|
+
var refByUniqueField = (txn, entity, field, fieldIndex, value) => {
|
|
438
|
+
const objectStore = txn.engineOpts.txn.objectStore("entities");
|
|
439
|
+
if (fieldIndex > 1)
|
|
440
|
+
throw new Error("Field index must be 0 or 1");
|
|
441
|
+
const index = objectStore.index(`unique_constraint_${fieldIndex}`);
|
|
442
|
+
const range = IDBKeyRange.only([
|
|
443
|
+
entity,
|
|
444
|
+
`${field}:${JSON.stringify(value)}`
|
|
445
|
+
]);
|
|
446
|
+
const idbRequest = index.openCursor(range);
|
|
297
447
|
return new Promise((resolve, reject) => {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
request.onerror = (event) => {
|
|
302
|
-
console.error("Error saving mutation", event?.target?.error);
|
|
303
|
-
reject(event?.target?.error);
|
|
448
|
+
idbRequest.onsuccess = () => {
|
|
449
|
+
const cursor = idbRequest.result;
|
|
450
|
+
resolve(cursor?.value?.ref);
|
|
304
451
|
};
|
|
305
452
|
});
|
|
306
453
|
};
|
|
307
|
-
// src/functions/updateEntity.ts
|
|
308
|
-
var updateEntity = async (txn, ref, { data = {}, children = {}, parents = {}, ancestors = {} }) => {
|
|
309
|
-
const currentEntity = await readEntity(txn, ref);
|
|
310
|
-
const objectStore = txn.engineOpts.txn.objectStore("entities");
|
|
311
|
-
const document = {
|
|
312
|
-
...currentEntity,
|
|
313
|
-
updated: {
|
|
314
|
-
mutationRef: txn.mutation.ref,
|
|
315
|
-
timestamp: txn.mutation.timestamp
|
|
316
|
-
},
|
|
317
|
-
data,
|
|
318
|
-
children,
|
|
319
|
-
parents,
|
|
320
|
-
ancestors
|
|
321
|
-
};
|
|
322
|
-
if (txn.request.changeSetRef) {
|
|
323
|
-
throw new Error("TODO support changeSetRef");
|
|
324
|
-
} else {
|
|
325
|
-
const request = objectStore.put(document);
|
|
326
|
-
return new Promise((resolve, reject) => {
|
|
327
|
-
request.onsuccess = (event) => {
|
|
328
|
-
resolve(document);
|
|
329
|
-
};
|
|
330
|
-
request.onerror = (event) => {
|
|
331
|
-
console.error("Error updating document", event?.target?.error);
|
|
332
|
-
reject(event?.target?.error);
|
|
333
|
-
};
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
};
|
|
337
454
|
// src/createIndexedDBAdapter.ts
|
|
338
455
|
var createIndexedDBAdapter = ({
|
|
339
456
|
operations,
|
|
340
457
|
entities,
|
|
341
|
-
|
|
458
|
+
session,
|
|
459
|
+
dbName = "roc-db",
|
|
460
|
+
optimistic = false,
|
|
461
|
+
snowflake = new Snowflake(1, 1)
|
|
342
462
|
}) => {
|
|
343
463
|
return createAdapter({
|
|
344
464
|
name: "indexed-db",
|
|
345
465
|
operations,
|
|
346
466
|
entities,
|
|
347
467
|
functions: exports_functions,
|
|
348
|
-
|
|
468
|
+
optimistic,
|
|
469
|
+
session,
|
|
470
|
+
snowflake,
|
|
349
471
|
async: true
|
|
350
472
|
}, {
|
|
351
473
|
dbName,
|
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
_entityKinds: Entities[number]["shape"]["entity"]["value"];
|
|
9
|
-
_operationNames: Operations[number]["operationName"];
|
|
10
|
-
_operations: Operations;
|
|
11
|
-
_entites: Entities;
|
|
12
|
-
createRef: (entity: any) => string;
|
|
13
|
-
changeSet: (changeSetRef: any) => /*elided*/ any & {
|
|
14
|
-
[x: string]: any;
|
|
1
|
+
import { Snowflake, type Adapter, type Entity, type Operation } from "roc-db";
|
|
2
|
+
export declare const createIndexedDBAdapter: ({ operations, entities, session, dbName, optimistic, snowflake, }: {
|
|
3
|
+
operations: readonly Operation[];
|
|
4
|
+
entities: readonly Entity<any>[];
|
|
5
|
+
session: {
|
|
6
|
+
identityRef: string;
|
|
7
|
+
sessionRef?: string;
|
|
15
8
|
};
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
};
|
|
9
|
+
dbName?: string;
|
|
10
|
+
optimistic?: boolean;
|
|
11
|
+
snowflake?: Snowflake;
|
|
12
|
+
}) => Adapter;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import type { EndFunction } from "roc-db";
|
|
2
2
|
import type { IndexedDBEngine } from "../types/IndexedDBEngine";
|
|
3
|
-
|
|
4
|
-
export declare const end: EndFunction<WriteRequest, IndexedDBEngine, [], any>;
|
|
3
|
+
export declare const end: EndFunction<IndexedDBEngine>;
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export declare const findDebounceMutation: (request: WriteRequest, engine: IndexedDBEngine, now: number) => Promise<unknown>;
|
|
1
|
+
import type { FindDebounceMutationFunction } from "roc-db";
|
|
2
|
+
export declare const findDebounceMutation: FindDebounceMutationFunction;
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export declare const getChangeSetMutations: (txn: IndexedDBReadTransaction, changeSetRef: Ref) => Promise<unknown>;
|
|
1
|
+
import type { GetChangeSetMutationsFunction } from "roc-db";
|
|
2
|
+
export declare const getChangeSetMutations: GetChangeSetMutationsFunction;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
export { batchReadEntities } from "./batchReadEntities";
|
|
1
2
|
export { begin } from "./begin";
|
|
2
|
-
export {
|
|
3
|
-
export { deleteEntity } from "./deleteEntity";
|
|
3
|
+
export { commit } from "./commit";
|
|
4
4
|
export { end } from "./end";
|
|
5
5
|
export { getChangeSetMutations } from "./getChangeSetMutations";
|
|
6
6
|
export { findDebounceMutation } from "./findDebounceMutation";
|
|
7
|
+
export { pageEntities } from "./pageEntities";
|
|
8
|
+
export { pageEntitiesByIndex } from "./pageEntitiesByIndex";
|
|
7
9
|
export { pageMutations } from "./pageMutations";
|
|
8
|
-
export { patchEntity } from "./patchEntity";
|
|
9
10
|
export { readEntity } from "./readEntity";
|
|
10
11
|
export { readMutation } from "./readMutation";
|
|
12
|
+
export { refByUniqueField } from "./refByUniqueField";
|
|
11
13
|
export { saveMutation } from "./saveMutation";
|
|
12
|
-
export { updateEntity } from "./updateEntity";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const pageMutations:
|
|
1
|
+
import type { PageMutationsFunction } from "roc-db";
|
|
2
|
+
export declare const pageMutations: PageMutationsFunction;
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import type { ReadMutationFunction } from "roc-db";
|
|
2
|
+
export declare const readMutation: ReadMutationFunction;
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import type { SaveMutationFunction } from "roc-db";
|
|
2
|
+
export declare const saveMutation: SaveMutationFunction;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const documentFromDBRow: ({ unique_constraint_0, unique_constraint_1, index_entries, ...document }: any) => any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const documentToDBRow: (document: any) => any;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import type { ReadTransaction } from "roc-db";
|
|
2
2
|
import type { IndexedDBEngine } from "./IndexedDBEngine";
|
|
3
|
-
export type IndexedDBReadTransaction = ReadTransaction<
|
|
4
|
-
], any>;
|
|
3
|
+
export type IndexedDBReadTransaction = ReadTransaction<IndexedDBEngine>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@roc-db/indexed-db",
|
|
3
|
-
"version": "0.2.0-pre.
|
|
3
|
+
"version": "0.2.0-pre.100",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"sideEffects": false,
|
|
15
15
|
"dependencies": {},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"roc-db": "0.2.0-pre.
|
|
18
|
-
"zod": "
|
|
17
|
+
"roc-db": ">=0.2.0-pre.98 <1.0.0",
|
|
18
|
+
"zod": ">=4.0.0"
|
|
19
19
|
},
|
|
20
20
|
"keywords": [],
|
|
21
21
|
"author": "Eigil Sagafos",
|
|
@@ -23,5 +23,9 @@
|
|
|
23
23
|
"type": "git",
|
|
24
24
|
"url": "git+https://github.com/eigilsagafos/roc-db.git"
|
|
25
25
|
},
|
|
26
|
-
"license": "MIT"
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public",
|
|
29
|
+
"registry": "https://registry.npmjs.org/"
|
|
30
|
+
}
|
|
27
31
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const deleteEntity: (txn: any, ref: any, cascade?: boolean) => Promise<boolean>;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { IndexedDBReadTransaction } from "../types/IndexedDBReadTransaction";
|
|
2
|
-
export declare const patchEntity: (txn: IndexedDBReadTransaction, ref: any, { data, children, parents, ancestors }: {
|
|
3
|
-
data?: {} | undefined;
|
|
4
|
-
children?: {} | undefined;
|
|
5
|
-
parents?: {} | undefined;
|
|
6
|
-
ancestors?: {} | undefined;
|
|
7
|
-
}) => Promise<any>;
|