cojson-storage-indexeddb 0.10.6 → 0.10.8
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +19 -0
- package/dist/CoJsonIDBTransaction.js +84 -0
- package/dist/CoJsonIDBTransaction.js.map +1 -0
- package/dist/idbClient.js +48 -58
- package/dist/idbClient.js.map +1 -1
- package/dist/idbNode.js +1 -3
- package/dist/idbNode.js.map +1 -1
- package/dist/tests/CoJsonIDBTransaction.test.js +125 -0
- package/dist/tests/CoJsonIDBTransaction.test.js.map +1 -0
- package/package.json +3 -3
- package/src/CoJsonIDBTransaction.ts +111 -0
- package/src/idbClient.ts +86 -124
- package/src/idbNode.ts +1 -12
- package/src/tests/CoJsonIDBTransaction.test.ts +170 -0
- package/dist/syncPromises.js +0 -163
- package/dist/syncPromises.js.map +0 -1
- package/src/syncPromises.ts +0 -224
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# cojson-storage-indexeddb
|
|
2
2
|
|
|
3
|
+
## 0.10.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [153dc99]
|
|
8
|
+
- cojson@0.10.8
|
|
9
|
+
- cojson-storage@0.10.8
|
|
10
|
+
|
|
11
|
+
## 0.10.7
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 1e625f3: Improve rollback on error when failing to add new content
|
|
16
|
+
- Updated dependencies [0f83320]
|
|
17
|
+
- Updated dependencies [012022d]
|
|
18
|
+
- Updated dependencies [1e625f3]
|
|
19
|
+
- cojson@0.10.7
|
|
20
|
+
- cojson-storage@0.10.7
|
|
21
|
+
|
|
3
22
|
## 0.10.6
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// A access unit for the IndexedDB Jazz database
|
|
2
|
+
// It's a wrapper around the IDBTransaction object that helps on batching multiple operations
|
|
3
|
+
// in a single transaction.
|
|
4
|
+
export class CoJsonIDBTransaction {
|
|
5
|
+
constructor(db) {
|
|
6
|
+
this.pendingRequests = [];
|
|
7
|
+
this.rejectHandlers = [];
|
|
8
|
+
this.id = Math.random();
|
|
9
|
+
this.running = false;
|
|
10
|
+
this.failed = false;
|
|
11
|
+
this.done = false;
|
|
12
|
+
this.startedAt = performance.now();
|
|
13
|
+
this.db = db;
|
|
14
|
+
this.tx = this.db.transaction(["coValues", "sessions", "transactions", "signatureAfter"], "readwrite");
|
|
15
|
+
this.tx.oncomplete = () => {
|
|
16
|
+
this.done = true;
|
|
17
|
+
};
|
|
18
|
+
this.tx.onabort = () => {
|
|
19
|
+
this.done = true;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
isReusable() {
|
|
23
|
+
const delta = performance.now() - this.startedAt;
|
|
24
|
+
return !this.done && delta <= 20;
|
|
25
|
+
}
|
|
26
|
+
getObjectStore(name) {
|
|
27
|
+
return this.tx.objectStore(name);
|
|
28
|
+
}
|
|
29
|
+
pushRequest(handler) {
|
|
30
|
+
const next = () => {
|
|
31
|
+
const next = this.pendingRequests.shift();
|
|
32
|
+
if (next) {
|
|
33
|
+
next(this);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
this.running = false;
|
|
37
|
+
this.done = true;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
if (this.running) {
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
this.rejectHandlers.push(reject);
|
|
43
|
+
this.pendingRequests.push(async () => {
|
|
44
|
+
try {
|
|
45
|
+
const result = await handler(this, next);
|
|
46
|
+
resolve(result);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
reject(error);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
this.running = true;
|
|
55
|
+
return handler(this, next);
|
|
56
|
+
}
|
|
57
|
+
handleRequest(handler) {
|
|
58
|
+
return this.pushRequest((txEntry, next) => {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
const request = handler(txEntry);
|
|
61
|
+
request.onerror = () => {
|
|
62
|
+
this.failed = true;
|
|
63
|
+
this.tx.abort();
|
|
64
|
+
console.error(request.error);
|
|
65
|
+
reject(request.error);
|
|
66
|
+
// Don't leave any pending promise
|
|
67
|
+
for (const handler of this.rejectHandlers) {
|
|
68
|
+
handler();
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
request.onsuccess = () => {
|
|
72
|
+
resolve(request.result);
|
|
73
|
+
next();
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
commit() {
|
|
79
|
+
if (!this.done) {
|
|
80
|
+
this.tx.commit();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=CoJsonIDBTransaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CoJsonIDBTransaction.js","sourceRoot":"","sources":["../src/CoJsonIDBTransaction.ts"],"names":[],"mappings":"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"}
|
package/dist/idbClient.js
CHANGED
|
@@ -1,102 +1,92 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CoJsonIDBTransaction } from "./CoJsonIDBTransaction.js";
|
|
2
2
|
export class IDBClient {
|
|
3
3
|
constructor(db) {
|
|
4
|
-
this.currentTxID = 0;
|
|
5
4
|
this.db = db;
|
|
6
5
|
}
|
|
7
6
|
makeRequest(handler) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
request.onsuccess = () => {
|
|
18
|
-
const value = request.result;
|
|
19
|
-
resolve(value);
|
|
20
|
-
const next = txEntry?.pendingRequests.shift();
|
|
21
|
-
if (next) {
|
|
22
|
-
next({ stores });
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
if (this.currentTx === txEntry) {
|
|
26
|
-
this.currentTx = undefined;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
};
|
|
31
|
-
// Transaction batching
|
|
32
|
-
if (!txEntry || performance.now() - txEntry.startedAt > 20) {
|
|
33
|
-
const tx = this.db.transaction(["coValues", "sessions", "transactions", "signatureAfter"], "readwrite");
|
|
34
|
-
txEntry = {
|
|
35
|
-
id: this.currentTxID++,
|
|
36
|
-
tx,
|
|
37
|
-
stores: {
|
|
38
|
-
coValues: tx.objectStore("coValues"),
|
|
39
|
-
sessions: tx.objectStore("sessions"),
|
|
40
|
-
transactions: tx.objectStore("transactions"),
|
|
41
|
-
signatureAfter: tx.objectStore("signatureAfter"),
|
|
42
|
-
},
|
|
43
|
-
startedAt: performance.now(),
|
|
44
|
-
pendingRequests: [],
|
|
45
|
-
};
|
|
46
|
-
this.currentTx = txEntry;
|
|
47
|
-
requestEntry(txEntry);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
txEntry.pendingRequests.push(requestEntry);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
7
|
+
if (this.activeTransaction) {
|
|
8
|
+
return this.activeTransaction.handleRequest(handler);
|
|
9
|
+
}
|
|
10
|
+
if (this.autoBatchingTransaction?.isReusable()) {
|
|
11
|
+
return this.autoBatchingTransaction.handleRequest(handler);
|
|
12
|
+
}
|
|
13
|
+
const tx = new CoJsonIDBTransaction(this.db);
|
|
14
|
+
this.autoBatchingTransaction = tx;
|
|
15
|
+
return tx.handleRequest(handler);
|
|
53
16
|
}
|
|
54
17
|
async getCoValue(coValueId) {
|
|
55
|
-
return this.makeRequest((
|
|
18
|
+
return this.makeRequest((tx) => tx.getObjectStore("coValues").index("coValuesById").get(coValueId));
|
|
56
19
|
}
|
|
57
20
|
async getCoValueSessions(coValueRowId) {
|
|
58
|
-
return this.makeRequest((
|
|
21
|
+
return this.makeRequest((tx) => tx
|
|
22
|
+
.getObjectStore("sessions")
|
|
23
|
+
.index("sessionsByCoValue")
|
|
24
|
+
.getAll(coValueRowId));
|
|
25
|
+
}
|
|
26
|
+
async getSingleCoValueSession(coValueRowId, sessionID) {
|
|
27
|
+
return this.makeRequest((tx) => tx
|
|
28
|
+
.getObjectStore("sessions")
|
|
29
|
+
.index("uniqueSessions")
|
|
30
|
+
.get([coValueRowId, sessionID]));
|
|
59
31
|
}
|
|
60
32
|
async getNewTransactionInSession(sessionRowId, firstNewTxIdx) {
|
|
61
|
-
return this.makeRequest((
|
|
33
|
+
return this.makeRequest((tx) => tx
|
|
34
|
+
.getObjectStore("transactions")
|
|
35
|
+
.getAll(IDBKeyRange.bound([sessionRowId, firstNewTxIdx], [sessionRowId, Number.POSITIVE_INFINITY])));
|
|
62
36
|
}
|
|
63
37
|
async getSignatures(sessionRowId, firstNewTxIdx) {
|
|
64
|
-
return this.makeRequest((
|
|
38
|
+
return this.makeRequest((tx) => tx
|
|
39
|
+
.getObjectStore("signatureAfter")
|
|
40
|
+
.getAll(IDBKeyRange.bound([sessionRowId, firstNewTxIdx], [sessionRowId, Number.POSITIVE_INFINITY])));
|
|
65
41
|
}
|
|
66
42
|
async addCoValue(msg) {
|
|
67
43
|
if (!msg.header) {
|
|
68
44
|
throw new Error(`Header is required, coId: ${msg.id}`);
|
|
69
45
|
}
|
|
70
|
-
return (await this.makeRequest((
|
|
46
|
+
return (await this.makeRequest((tx) => tx.getObjectStore("coValues").put({
|
|
71
47
|
id: msg.id,
|
|
72
48
|
// biome-ignore lint/style/noNonNullAssertion: TODO(JAZZ-561): Review
|
|
73
49
|
header: msg.header,
|
|
74
50
|
})));
|
|
75
51
|
}
|
|
76
52
|
async addSessionUpdate({ sessionUpdate, sessionRow, }) {
|
|
77
|
-
return this.makeRequest((
|
|
53
|
+
return this.makeRequest((tx) => tx.getObjectStore("sessions").put(sessionRow?.rowID
|
|
78
54
|
? {
|
|
79
55
|
rowID: sessionRow.rowID,
|
|
80
56
|
...sessionUpdate,
|
|
81
57
|
}
|
|
82
58
|
: sessionUpdate));
|
|
83
59
|
}
|
|
84
|
-
addTransaction(sessionRowID, idx, newTransaction) {
|
|
85
|
-
|
|
60
|
+
async addTransaction(sessionRowID, idx, newTransaction) {
|
|
61
|
+
await this.makeRequest((tx) => tx.getObjectStore("transactions").add({
|
|
86
62
|
ses: sessionRowID,
|
|
87
63
|
idx,
|
|
88
64
|
tx: newTransaction,
|
|
89
65
|
}));
|
|
90
66
|
}
|
|
91
67
|
async addSignatureAfter({ sessionRowID, idx, signature, }) {
|
|
92
|
-
return this.makeRequest((
|
|
68
|
+
return this.makeRequest((tx) => tx.getObjectStore("signatureAfter").put({
|
|
93
69
|
ses: sessionRowID,
|
|
94
70
|
idx,
|
|
95
71
|
signature,
|
|
96
72
|
}));
|
|
97
73
|
}
|
|
98
|
-
|
|
99
|
-
|
|
74
|
+
closeTransaction(tx) {
|
|
75
|
+
tx.commit();
|
|
76
|
+
if (tx === this.activeTransaction) {
|
|
77
|
+
this.activeTransaction = undefined;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async transaction(operationsCallback) {
|
|
81
|
+
const tx = new CoJsonIDBTransaction(this.db);
|
|
82
|
+
this.activeTransaction = tx;
|
|
83
|
+
try {
|
|
84
|
+
await operationsCallback();
|
|
85
|
+
tx.commit(); // Tells the browser to not wait for another possible request and commit the transaction immediately
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
this.activeTransaction = undefined;
|
|
89
|
+
}
|
|
100
90
|
}
|
|
101
91
|
}
|
|
102
92
|
//# sourceMappingURL=idbClient.js.map
|
package/dist/idbClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idbClient.js","sourceRoot":"","sources":["../src/idbClient.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"idbClient.js","sourceRoot":"","sources":["../src/idbClient.ts"],"names":[],"mappings":"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"}
|
package/dist/idbNode.js
CHANGED
|
@@ -18,9 +18,7 @@ export class IDBNode {
|
|
|
18
18
|
await this.syncManager.handleSyncMessage(msg);
|
|
19
19
|
}
|
|
20
20
|
catch (e) {
|
|
21
|
-
console.error(
|
|
22
|
-
? `${v.slice(0, 20)}...`
|
|
23
|
-
: v)}`, { cause: e }));
|
|
21
|
+
console.error(e);
|
|
24
22
|
}
|
|
25
23
|
}
|
|
26
24
|
};
|
package/dist/idbNode.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idbNode.js","sourceRoot":"","sources":["../src/idbNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,eAAe,GAChB,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,IAAI,aAAa,GAAG,cAAc,CAAC;AAEnC,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,aAAa,GAAG,IAAI,CAAC;AACvB,CAAC;AAED,MAAM,OAAO,OAAO;IAIlB,YACE,EAAe,EACf,aAAiC,EACjC,WAA8B;QAE9B,IAAI,CAAC,QAAQ,GAAG,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/D,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE;YACjC,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;gBACtC,IAAI,CAAC;oBACH,IAAI,GAAG,KAAK,cAAc,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;wBACpD,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;oBACrD,CAAC;oBACD,MAAM,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;gBAChD,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,OAAO,CAAC,KAAK,
|
|
1
|
+
{"version":3,"file":"idbNode.js","sourceRoot":"","sources":["../src/idbNode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test } from "vitest";
|
|
2
|
+
import { CoJsonIDBTransaction } from "../CoJsonIDBTransaction";
|
|
3
|
+
const TEST_DB_NAME = "test-cojson-idb-transaction";
|
|
4
|
+
describe("CoJsonIDBTransaction", () => {
|
|
5
|
+
let db;
|
|
6
|
+
beforeEach(async () => {
|
|
7
|
+
// Create test database
|
|
8
|
+
await new Promise((resolve, reject) => {
|
|
9
|
+
const request = indexedDB.open(TEST_DB_NAME, 1);
|
|
10
|
+
request.onerror = () => reject(request.error);
|
|
11
|
+
request.onupgradeneeded = (event) => {
|
|
12
|
+
const db = request.result;
|
|
13
|
+
// Create test stores
|
|
14
|
+
db.createObjectStore("coValues", { keyPath: "id" });
|
|
15
|
+
const sessions = db.createObjectStore("sessions", { keyPath: "id" });
|
|
16
|
+
sessions.createIndex("uniqueSessions", ["coValue", "sessionID"], {
|
|
17
|
+
unique: true,
|
|
18
|
+
});
|
|
19
|
+
db.createObjectStore("transactions", { keyPath: "id" });
|
|
20
|
+
db.createObjectStore("signatureAfter", { keyPath: "id" });
|
|
21
|
+
};
|
|
22
|
+
request.onsuccess = () => {
|
|
23
|
+
db = request.result;
|
|
24
|
+
resolve();
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
afterEach(async () => {
|
|
29
|
+
// Close and delete test database
|
|
30
|
+
db.close();
|
|
31
|
+
await new Promise((resolve, reject) => {
|
|
32
|
+
const request = indexedDB.deleteDatabase(TEST_DB_NAME);
|
|
33
|
+
request.onerror = () => reject(request.error);
|
|
34
|
+
request.onsuccess = () => resolve();
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
test("handles successful write and read operations", async () => {
|
|
38
|
+
const tx = new CoJsonIDBTransaction(db);
|
|
39
|
+
// Write test
|
|
40
|
+
await tx.handleRequest((tx) => tx.getObjectStore("coValues").put({
|
|
41
|
+
id: "test1",
|
|
42
|
+
value: "hello",
|
|
43
|
+
}));
|
|
44
|
+
// Read test
|
|
45
|
+
const readTx = new CoJsonIDBTransaction(db);
|
|
46
|
+
const result = await readTx.handleRequest((tx) => tx.getObjectStore("coValues").get("test1"));
|
|
47
|
+
expect(result).toEqual({
|
|
48
|
+
id: "test1",
|
|
49
|
+
value: "hello",
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
test("handles multiple operations in single transaction", async () => {
|
|
53
|
+
const tx = new CoJsonIDBTransaction(db);
|
|
54
|
+
// Multiple writes
|
|
55
|
+
await Promise.all([
|
|
56
|
+
tx.handleRequest((tx) => tx.getObjectStore("coValues").put({
|
|
57
|
+
id: "test1",
|
|
58
|
+
value: "hello",
|
|
59
|
+
})),
|
|
60
|
+
tx.handleRequest((tx) => tx.getObjectStore("coValues").put({
|
|
61
|
+
id: "test2",
|
|
62
|
+
value: "world",
|
|
63
|
+
})),
|
|
64
|
+
]);
|
|
65
|
+
// Read results
|
|
66
|
+
const readTx = new CoJsonIDBTransaction(db);
|
|
67
|
+
const [result1, result2] = await Promise.all([
|
|
68
|
+
readTx.handleRequest((tx) => tx.getObjectStore("coValues").get("test1")),
|
|
69
|
+
readTx.handleRequest((tx) => tx.getObjectStore("coValues").get("test2")),
|
|
70
|
+
]);
|
|
71
|
+
expect(result1).toEqual({
|
|
72
|
+
id: "test1",
|
|
73
|
+
value: "hello",
|
|
74
|
+
});
|
|
75
|
+
expect(result2).toEqual({
|
|
76
|
+
id: "test2",
|
|
77
|
+
value: "world",
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
test("handles transaction across multiple stores", async () => {
|
|
81
|
+
const tx = new CoJsonIDBTransaction(db);
|
|
82
|
+
await Promise.all([
|
|
83
|
+
tx.handleRequest((tx) => tx.getObjectStore("coValues").put({
|
|
84
|
+
id: "value1",
|
|
85
|
+
data: "value data",
|
|
86
|
+
})),
|
|
87
|
+
tx.handleRequest((tx) => tx.getObjectStore("sessions").put({
|
|
88
|
+
id: "session1",
|
|
89
|
+
data: "session data",
|
|
90
|
+
})),
|
|
91
|
+
]);
|
|
92
|
+
const readTx = new CoJsonIDBTransaction(db);
|
|
93
|
+
const [valueResult, sessionResult] = await Promise.all([
|
|
94
|
+
readTx.handleRequest((tx) => tx.getObjectStore("coValues").get("value1")),
|
|
95
|
+
readTx.handleRequest((tx) => tx.getObjectStore("sessions").get("session1")),
|
|
96
|
+
]);
|
|
97
|
+
expect(valueResult).toEqual({
|
|
98
|
+
id: "value1",
|
|
99
|
+
data: "value data",
|
|
100
|
+
});
|
|
101
|
+
expect(sessionResult).toEqual({
|
|
102
|
+
id: "session1",
|
|
103
|
+
data: "session data",
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
test("handles failed transactions", async () => {
|
|
107
|
+
const tx = new CoJsonIDBTransaction(db);
|
|
108
|
+
await expect(tx.handleRequest((tx) => tx.getObjectStore("sessions").put({
|
|
109
|
+
id: 1,
|
|
110
|
+
coValue: "value1",
|
|
111
|
+
sessionID: "session1",
|
|
112
|
+
data: "session data",
|
|
113
|
+
}))).resolves.toBe(1);
|
|
114
|
+
expect(tx.failed).toBe(false);
|
|
115
|
+
const badTx = new CoJsonIDBTransaction(db);
|
|
116
|
+
await expect(badTx.handleRequest((tx) => tx.getObjectStore("sessions").put({
|
|
117
|
+
id: 2,
|
|
118
|
+
coValue: "value1",
|
|
119
|
+
sessionID: "session1",
|
|
120
|
+
data: "session data",
|
|
121
|
+
}))).rejects.toThrow();
|
|
122
|
+
expect(badTx.failed).toBe(true);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
//# sourceMappingURL=CoJsonIDBTransaction.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CoJsonIDBTransaction.test.js","sourceRoot":"","sources":["../../src/tests/CoJsonIDBTransaction.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cojson-storage-indexeddb",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.8",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "src/index.ts",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"cojson": "0.10.
|
|
10
|
-
"cojson-storage": "0.10.
|
|
9
|
+
"cojson": "0.10.8",
|
|
10
|
+
"cojson-storage": "0.10.8"
|
|
11
11
|
},
|
|
12
12
|
"devDependencies": {
|
|
13
13
|
"@vitest/browser": "^3.0.5",
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export type StoreName =
|
|
2
|
+
| "coValues"
|
|
3
|
+
| "sessions"
|
|
4
|
+
| "transactions"
|
|
5
|
+
| "signatureAfter";
|
|
6
|
+
|
|
7
|
+
// A access unit for the IndexedDB Jazz database
|
|
8
|
+
// It's a wrapper around the IDBTransaction object that helps on batching multiple operations
|
|
9
|
+
// in a single transaction.
|
|
10
|
+
export class CoJsonIDBTransaction {
|
|
11
|
+
db: IDBDatabase;
|
|
12
|
+
tx: IDBTransaction;
|
|
13
|
+
|
|
14
|
+
pendingRequests: ((txEntry: this) => void)[] = [];
|
|
15
|
+
rejectHandlers: (() => void)[] = [];
|
|
16
|
+
|
|
17
|
+
id = Math.random();
|
|
18
|
+
|
|
19
|
+
running = false;
|
|
20
|
+
failed = false;
|
|
21
|
+
done = false;
|
|
22
|
+
|
|
23
|
+
constructor(db: IDBDatabase) {
|
|
24
|
+
this.db = db;
|
|
25
|
+
|
|
26
|
+
this.tx = this.db.transaction(
|
|
27
|
+
["coValues", "sessions", "transactions", "signatureAfter"],
|
|
28
|
+
"readwrite",
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
this.tx.oncomplete = () => {
|
|
32
|
+
this.done = true;
|
|
33
|
+
};
|
|
34
|
+
this.tx.onabort = () => {
|
|
35
|
+
this.done = true;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
startedAt = performance.now();
|
|
40
|
+
isReusable() {
|
|
41
|
+
const delta = performance.now() - this.startedAt;
|
|
42
|
+
return !this.done && delta <= 20;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
getObjectStore(name: StoreName) {
|
|
46
|
+
return this.tx.objectStore(name);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private pushRequest<T>(
|
|
50
|
+
handler: (txEntry: this, next: () => void) => Promise<T>,
|
|
51
|
+
) {
|
|
52
|
+
const next = () => {
|
|
53
|
+
const next = this.pendingRequests.shift();
|
|
54
|
+
|
|
55
|
+
if (next) {
|
|
56
|
+
next(this);
|
|
57
|
+
} else {
|
|
58
|
+
this.running = false;
|
|
59
|
+
this.done = true;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
if (this.running) {
|
|
64
|
+
return new Promise<T>((resolve, reject) => {
|
|
65
|
+
this.rejectHandlers.push(reject);
|
|
66
|
+
this.pendingRequests.push(async () => {
|
|
67
|
+
try {
|
|
68
|
+
const result = await handler(this, next);
|
|
69
|
+
resolve(result);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
reject(error);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
this.running = true;
|
|
78
|
+
return handler(this, next);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
handleRequest<T>(handler: (txEntry: this) => IDBRequest<T>) {
|
|
82
|
+
return this.pushRequest<T>((txEntry, next) => {
|
|
83
|
+
return new Promise<T>((resolve, reject) => {
|
|
84
|
+
const request = handler(txEntry);
|
|
85
|
+
|
|
86
|
+
request.onerror = () => {
|
|
87
|
+
this.failed = true;
|
|
88
|
+
this.tx.abort();
|
|
89
|
+
console.error(request.error);
|
|
90
|
+
reject(request.error);
|
|
91
|
+
|
|
92
|
+
// Don't leave any pending promise
|
|
93
|
+
for (const handler of this.rejectHandlers) {
|
|
94
|
+
handler();
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
request.onsuccess = () => {
|
|
99
|
+
resolve(request.result as T);
|
|
100
|
+
next();
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
commit() {
|
|
107
|
+
if (!this.done) {
|
|
108
|
+
this.tx.commit();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|