@speckle/objectloader2 2.25.9 → 2.26.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.
- package/dist/commonjs/core/interfaces.d.ts +4 -6
- package/dist/commonjs/core/interfaces.d.ts.map +1 -1
- package/dist/commonjs/core/objectLoader2.js +2 -2
- package/dist/commonjs/core/objectLoader2.js.map +1 -1
- package/dist/commonjs/core/objectLoader2Factory.d.ts.map +1 -1
- package/dist/commonjs/core/objectLoader2Factory.js +4 -3
- package/dist/commonjs/core/objectLoader2Factory.js.map +1 -1
- package/dist/commonjs/core/stages/cacheWriter.js +1 -1
- package/dist/commonjs/core/stages/cacheWriter.js.map +1 -1
- package/dist/commonjs/core/stages/indexedDatabase.d.ts +20 -6
- package/dist/commonjs/core/stages/indexedDatabase.d.ts.map +1 -1
- package/dist/commonjs/core/stages/indexedDatabase.js +138 -19
- package/dist/commonjs/core/stages/indexedDatabase.js.map +1 -1
- package/dist/commonjs/core/stages/memory/memoryDatabase.d.ts +2 -4
- package/dist/commonjs/core/stages/memory/memoryDatabase.d.ts.map +1 -1
- package/dist/commonjs/core/stages/memory/memoryDatabase.js +3 -3
- package/dist/commonjs/core/stages/memory/memoryDatabase.js.map +1 -1
- package/dist/commonjs/core/stages/memory/memoryDownloader.d.ts +1 -1
- package/dist/commonjs/core/stages/memory/memoryDownloader.d.ts.map +1 -1
- package/dist/commonjs/core/stages/memory/memoryDownloader.js +1 -1
- package/dist/commonjs/core/stages/memory/memoryDownloader.js.map +1 -1
- package/dist/commonjs/core/stages/serverDownloader.d.ts +3 -2
- package/dist/commonjs/core/stages/serverDownloader.d.ts.map +1 -1
- package/dist/commonjs/core/stages/serverDownloader.js +12 -19
- package/dist/commonjs/core/stages/serverDownloader.js.map +1 -1
- package/dist/commonjs/queues/keyedQueue.test.d.ts +2 -0
- package/dist/commonjs/queues/keyedQueue.test.d.ts.map +1 -0
- package/dist/commonjs/queues/keyedQueue.test.js +118 -0
- package/dist/commonjs/queues/keyedQueue.test.js.map +1 -0
- package/dist/esm/core/interfaces.d.ts +4 -6
- package/dist/esm/core/interfaces.d.ts.map +1 -1
- package/dist/esm/core/objectLoader2.js +2 -2
- package/dist/esm/core/objectLoader2.js.map +1 -1
- package/dist/esm/core/objectLoader2Factory.d.ts.map +1 -1
- package/dist/esm/core/objectLoader2Factory.js +3 -2
- package/dist/esm/core/objectLoader2Factory.js.map +1 -1
- package/dist/esm/core/stages/cacheWriter.js +1 -1
- package/dist/esm/core/stages/cacheWriter.js.map +1 -1
- package/dist/esm/core/stages/indexedDatabase.d.ts +20 -6
- package/dist/esm/core/stages/indexedDatabase.d.ts.map +1 -1
- package/dist/esm/core/stages/indexedDatabase.js +140 -22
- package/dist/esm/core/stages/indexedDatabase.js.map +1 -1
- package/dist/esm/core/stages/memory/memoryDatabase.d.ts +2 -4
- package/dist/esm/core/stages/memory/memoryDatabase.d.ts.map +1 -1
- package/dist/esm/core/stages/memory/memoryDatabase.js +3 -3
- package/dist/esm/core/stages/memory/memoryDatabase.js.map +1 -1
- package/dist/esm/core/stages/memory/memoryDownloader.d.ts +1 -1
- package/dist/esm/core/stages/memory/memoryDownloader.d.ts.map +1 -1
- package/dist/esm/core/stages/memory/memoryDownloader.js +1 -1
- package/dist/esm/core/stages/memory/memoryDownloader.js.map +1 -1
- package/dist/esm/core/stages/serverDownloader.d.ts +3 -2
- package/dist/esm/core/stages/serverDownloader.d.ts.map +1 -1
- package/dist/esm/core/stages/serverDownloader.js +12 -19
- package/dist/esm/core/stages/serverDownloader.js.map +1 -1
- package/dist/esm/queues/keyedQueue.test.d.ts +2 -0
- package/dist/esm/queues/keyedQueue.test.d.ts.map +1 -0
- package/dist/esm/queues/keyedQueue.test.js +113 -0
- package/dist/esm/queues/keyedQueue.test.js.map +1 -0
- package/package.json +2 -2
- package/src/core/interfaces.ts +4 -4
- package/src/core/objectLoader2.spec.ts +1 -1
- package/src/core/objectLoader2.ts +2 -2
- package/src/core/objectLoader2Factory.ts +3 -2
- package/src/core/stages/cacheWriter.spec.ts +4 -4
- package/src/core/stages/cacheWriter.ts +1 -1
- package/src/core/stages/indexedDatabase.spec.ts +6 -6
- package/src/core/stages/indexedDatabase.ts +154 -25
- package/src/core/stages/memory/memoryDatabase.spec.ts +6 -6
- package/src/core/stages/memory/memoryDatabase.ts +3 -3
- package/src/core/stages/memory/memoryDownloader.spec.ts +2 -2
- package/src/core/stages/memory/memoryDownloader.ts +1 -1
- package/src/core/stages/serverDownloader.spec.ts +20 -12
- package/src/core/stages/serverDownloader.ts +18 -24
- package/src/queues/keyedQueue.test.ts +146 -0
- package/dist/commonjs/core/stages/ItemStore.d.ts +0 -37
- package/dist/commonjs/core/stages/ItemStore.d.ts.map +0 -1
- package/dist/commonjs/core/stages/ItemStore.js +0 -167
- package/dist/commonjs/core/stages/ItemStore.js.map +0 -1
- package/dist/commonjs/queues/batchedPool.d.ts +0 -13
- package/dist/commonjs/queues/batchedPool.d.ts.map +0 -1
- package/dist/commonjs/queues/batchedPool.js +0 -45
- package/dist/commonjs/queues/batchedPool.js.map +0 -1
- package/dist/esm/core/stages/ItemStore.d.ts +0 -37
- package/dist/esm/core/stages/ItemStore.d.ts.map +0 -1
- package/dist/esm/core/stages/ItemStore.js +0 -163
- package/dist/esm/core/stages/ItemStore.js.map +0 -1
- package/dist/esm/queues/batchedPool.d.ts +0 -13
- package/dist/esm/queues/batchedPool.d.ts.map +0 -1
- package/dist/esm/queues/batchedPool.js +0 -42
- package/dist/esm/queues/batchedPool.js.map +0 -1
- package/src/core/stages/ItemStore.ts +0 -196
- package/src/queues/batchedPool.ts +0 -58
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { Item } from '../../types/types.js';
|
|
2
|
-
/**
|
|
3
|
-
* A wrapper class for IndexedDB to simplify common database operations.
|
|
4
|
-
*/
|
|
5
|
-
export interface ItemStoreOptions {
|
|
6
|
-
indexedDB?: IDBFactory;
|
|
7
|
-
keyRange?: {
|
|
8
|
-
bound: Function;
|
|
9
|
-
lowerBound: Function;
|
|
10
|
-
upperBound: Function;
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
export declare class ItemStore {
|
|
14
|
-
#private;
|
|
15
|
-
constructor(options: ItemStoreOptions, dbName: string, storeName: string);
|
|
16
|
-
/**
|
|
17
|
-
* Initializes the database connection and creates the object store if needed.
|
|
18
|
-
* This must be called before any other database operations.
|
|
19
|
-
*/
|
|
20
|
-
init(): Promise<void>;
|
|
21
|
-
/**
|
|
22
|
-
* Inserts or updates an array of items in a single transaction.
|
|
23
|
-
* @param data The array of items to insert.
|
|
24
|
-
*/
|
|
25
|
-
bulkInsert(data: Item[]): Promise<void>;
|
|
26
|
-
/**
|
|
27
|
-
* Retrieves an array of items from the object store based on their IDs.
|
|
28
|
-
* @param ids The array of IDs to retrieve.
|
|
29
|
-
*/
|
|
30
|
-
bulkGet(ids: string[]): Promise<(Item | undefined)[]>;
|
|
31
|
-
/**
|
|
32
|
-
* Retrieves all items from the object store.
|
|
33
|
-
*/
|
|
34
|
-
getAll(): Promise<Item[]>;
|
|
35
|
-
close(): void;
|
|
36
|
-
}
|
|
37
|
-
//# sourceMappingURL=ItemStore.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ItemStore.d.ts","sourceRoot":"","sources":["../../../../src/core/stages/ItemStore.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAE3C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,UAAU,CAAA;IACtB,QAAQ,CAAC,EAAE;QACT,KAAK,EAAE,QAAQ,CAAA;QACf,UAAU,EAAE,QAAQ,CAAA;QACpB,UAAU,EAAE,QAAQ,CAAA;KACrB,CAAA;CACF;AACD,qBAAa,SAAS;;gBAOR,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAMxE;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAwE3B;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBvC;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC;IAmCrD;;OAEG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAezB,KAAK,IAAI,IAAI;CAKd"}
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-base-to-string */
|
|
2
|
-
/* eslint-disable @typescript-eslint/prefer-promise-reject-errors */
|
|
3
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
-
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
|
|
5
|
-
import { isSafari } from '@speckle/shared';
|
|
6
|
-
export class ItemStore {
|
|
7
|
-
#options;
|
|
8
|
-
#db = undefined;
|
|
9
|
-
#dbName;
|
|
10
|
-
#storeName;
|
|
11
|
-
constructor(options, dbName, storeName) {
|
|
12
|
-
this.#options = options;
|
|
13
|
-
this.#dbName = dbName;
|
|
14
|
-
this.#storeName = storeName;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Initializes the database connection and creates the object store if needed.
|
|
18
|
-
* This must be called before any other database operations.
|
|
19
|
-
*/
|
|
20
|
-
async init() {
|
|
21
|
-
if (this.#db)
|
|
22
|
-
return;
|
|
23
|
-
await this.#safariFix();
|
|
24
|
-
return this.#openDatabase();
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Opens the database, and if there's an error, deletes the database and tries again.
|
|
28
|
-
*/
|
|
29
|
-
async #openDatabase() {
|
|
30
|
-
const idb = this.#options.indexedDB ?? indexedDB;
|
|
31
|
-
return new Promise((resolve, reject) => {
|
|
32
|
-
const request = idb.open(this.#dbName, 1);
|
|
33
|
-
request.onerror = () => {
|
|
34
|
-
console.warn(`Failed to open database: ${this.#dbName}, deleting and trying again`);
|
|
35
|
-
// Delete the database and try again
|
|
36
|
-
const deleteRequest = idb.deleteDatabase(this.#dbName);
|
|
37
|
-
deleteRequest.onsuccess = () => {
|
|
38
|
-
// Try opening again after deletion
|
|
39
|
-
void this.#openDatabase().then(resolve).catch(reject);
|
|
40
|
-
};
|
|
41
|
-
deleteRequest.onerror = () => {
|
|
42
|
-
reject(`Failed to delete and reopen database: ${this.#dbName}`);
|
|
43
|
-
};
|
|
44
|
-
};
|
|
45
|
-
request.onupgradeneeded = (event) => {
|
|
46
|
-
const db = event.target.result;
|
|
47
|
-
if (db.objectStoreNames.contains(this.#storeName)) {
|
|
48
|
-
db.deleteObjectStore(this.#storeName);
|
|
49
|
-
}
|
|
50
|
-
db.createObjectStore(this.#storeName, { keyPath: 'baseId' });
|
|
51
|
-
};
|
|
52
|
-
request.onsuccess = (event) => {
|
|
53
|
-
this.#db = event.target.result;
|
|
54
|
-
resolve();
|
|
55
|
-
};
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
#getDB() {
|
|
59
|
-
if (!this.#db) {
|
|
60
|
-
throw new Error('Database not initialized. Call init() first.');
|
|
61
|
-
}
|
|
62
|
-
return this.#db;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Fixes a Safari bug where IndexedDB requests get lost and never resolve - invoke before you use IndexedDB
|
|
66
|
-
* @link Credits and more info: https://github.com/jakearchibald/safari-14-idb-fix
|
|
67
|
-
*/
|
|
68
|
-
async #safariFix() {
|
|
69
|
-
// No point putting other browsers or older versions of Safari through this mess.
|
|
70
|
-
if (!isSafari() || !this.#options.indexedDB?.databases)
|
|
71
|
-
return Promise.resolve();
|
|
72
|
-
let intervalId;
|
|
73
|
-
return new Promise((resolve) => {
|
|
74
|
-
const tryIdb = () => this.#options.indexedDB?.databases().finally(resolve);
|
|
75
|
-
intervalId = setInterval(() => {
|
|
76
|
-
void tryIdb();
|
|
77
|
-
}, 100);
|
|
78
|
-
void tryIdb();
|
|
79
|
-
}).finally(() => clearInterval(intervalId));
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Inserts or updates an array of items in a single transaction.
|
|
83
|
-
* @param data The array of items to insert.
|
|
84
|
-
*/
|
|
85
|
-
bulkInsert(data) {
|
|
86
|
-
return new Promise((resolve, reject) => {
|
|
87
|
-
try {
|
|
88
|
-
const transaction = this.#getDB().transaction(this.#storeName, 'readwrite', {
|
|
89
|
-
durability: 'relaxed'
|
|
90
|
-
});
|
|
91
|
-
const store = transaction.objectStore(this.#storeName);
|
|
92
|
-
transaction.onerror = () => {
|
|
93
|
-
reject(`Transaction error: ${transaction.error}`);
|
|
94
|
-
};
|
|
95
|
-
transaction.oncomplete = () => {
|
|
96
|
-
resolve();
|
|
97
|
-
};
|
|
98
|
-
data.forEach((item) => store.put(item));
|
|
99
|
-
}
|
|
100
|
-
catch (error) {
|
|
101
|
-
reject(error);
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Retrieves an array of items from the object store based on their IDs.
|
|
107
|
-
* @param ids The array of IDs to retrieve.
|
|
108
|
-
*/
|
|
109
|
-
bulkGet(ids) {
|
|
110
|
-
return new Promise((resolve, reject) => {
|
|
111
|
-
if (ids.length === 0) {
|
|
112
|
-
return resolve([]);
|
|
113
|
-
}
|
|
114
|
-
try {
|
|
115
|
-
const transaction = this.#getDB().transaction(this.#storeName, 'readonly', {
|
|
116
|
-
durability: 'relaxed'
|
|
117
|
-
});
|
|
118
|
-
const store = transaction.objectStore(this.#storeName);
|
|
119
|
-
const promises = [];
|
|
120
|
-
for (const id of ids) {
|
|
121
|
-
promises.push(new Promise((resolveGet, rejectGet) => {
|
|
122
|
-
const request = store.get(id);
|
|
123
|
-
request.onerror = () => rejectGet(`Request error for id ${id}: ${request.error}`);
|
|
124
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
125
|
-
request.onsuccess = () => resolveGet(request.result);
|
|
126
|
-
}));
|
|
127
|
-
}
|
|
128
|
-
Promise.all(promises)
|
|
129
|
-
.then((results) => {
|
|
130
|
-
resolve(results);
|
|
131
|
-
})
|
|
132
|
-
.catch(reject);
|
|
133
|
-
}
|
|
134
|
-
catch (error) {
|
|
135
|
-
reject(error);
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Retrieves all items from the object store.
|
|
141
|
-
*/
|
|
142
|
-
getAll() {
|
|
143
|
-
return new Promise((resolve, reject) => {
|
|
144
|
-
try {
|
|
145
|
-
const transaction = this.#getDB().transaction(this.#storeName, 'readonly');
|
|
146
|
-
const store = transaction.objectStore(this.#storeName);
|
|
147
|
-
const request = store.getAll();
|
|
148
|
-
request.onerror = () => reject(`Request error: ${request.error}`);
|
|
149
|
-
request.onsuccess = () => resolve(request.result);
|
|
150
|
-
}
|
|
151
|
-
catch (error) {
|
|
152
|
-
reject(error);
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
close() {
|
|
157
|
-
if (!this.#db)
|
|
158
|
-
return;
|
|
159
|
-
this.#db.close();
|
|
160
|
-
this.#db = undefined;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
//# sourceMappingURL=ItemStore.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ItemStore.js","sourceRoot":"","sources":["../../../../src/core/stages/ItemStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import Queue from './queue.js';
|
|
2
|
-
export default class BatchedPool<T> implements Queue<T> {
|
|
3
|
-
#private;
|
|
4
|
-
constructor(params: {
|
|
5
|
-
concurrencyAndSizes: number[];
|
|
6
|
-
maxWaitTime?: number;
|
|
7
|
-
processFunction: (batch: T[]) => Promise<void>;
|
|
8
|
-
});
|
|
9
|
-
add(item: T): void;
|
|
10
|
-
getBatch(batchSize: number): T[];
|
|
11
|
-
disposeAsync(): Promise<void>;
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=batchedPool.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"batchedPool.d.ts","sourceRoot":"","sources":["../../../src/queues/batchedPool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAA;AAE9B,MAAM,CAAC,OAAO,OAAO,WAAW,CAAC,CAAC,CAAE,YAAW,KAAK,CAAC,CAAC,CAAC;;gBAUzC,MAAM,EAAE;QAClB,mBAAmB,EAAE,MAAM,EAAE,CAAA;QAC7B,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,eAAe,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAC/C;IAOD,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IAIlB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,CAAC,EAAE;IAc1B,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;CAgBpC"}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
export default class BatchedPool {
|
|
2
|
-
#queue = [];
|
|
3
|
-
#concurrencyAndSizes;
|
|
4
|
-
#processFunction;
|
|
5
|
-
#baseInterval;
|
|
6
|
-
#processingLoop;
|
|
7
|
-
#disposed = false;
|
|
8
|
-
constructor(params) {
|
|
9
|
-
this.#concurrencyAndSizes = params.concurrencyAndSizes;
|
|
10
|
-
this.#baseInterval = Math.min(params.maxWaitTime ?? 200, 200); // Initial batch time (ms)
|
|
11
|
-
this.#processFunction = params.processFunction;
|
|
12
|
-
this.#processingLoop = this.#loop();
|
|
13
|
-
}
|
|
14
|
-
add(item) {
|
|
15
|
-
this.#queue.push(item);
|
|
16
|
-
}
|
|
17
|
-
getBatch(batchSize) {
|
|
18
|
-
return this.#queue.splice(0, Math.min(batchSize, this.#queue.length));
|
|
19
|
-
}
|
|
20
|
-
async #runWorker(batchSize) {
|
|
21
|
-
while (!this.#disposed || this.#queue.length > 0) {
|
|
22
|
-
if (this.#queue.length > 0) {
|
|
23
|
-
const batch = this.getBatch(batchSize);
|
|
24
|
-
await this.#processFunction(batch);
|
|
25
|
-
}
|
|
26
|
-
await this.#delay(this.#baseInterval);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
async disposeAsync() {
|
|
30
|
-
this.#disposed = true;
|
|
31
|
-
await this.#processingLoop;
|
|
32
|
-
}
|
|
33
|
-
async #loop() {
|
|
34
|
-
// Initialize workers
|
|
35
|
-
const workers = Array.from(this.#concurrencyAndSizes, (batchSize) => this.#runWorker(batchSize));
|
|
36
|
-
await Promise.all(workers);
|
|
37
|
-
}
|
|
38
|
-
#delay(ms) {
|
|
39
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
//# sourceMappingURL=batchedPool.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"batchedPool.js","sourceRoot":"","sources":["../../../src/queues/batchedPool.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,OAAO,WAAW;IAC9B,MAAM,GAAQ,EAAE,CAAA;IAChB,oBAAoB,CAAU;IAC9B,gBAAgB,CAA+B;IAE/C,aAAa,CAAQ;IAErB,eAAe,CAAe;IAC9B,SAAS,GAAG,KAAK,CAAA;IAEjB,YAAY,MAIX;QACC,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC,mBAAmB,CAAA;QACtD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,IAAI,GAAG,EAAE,GAAG,CAAC,CAAA,CAAC,0BAA0B;QACxF,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,eAAe,CAAA;QAC9C,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;IACrC,CAAC;IAED,GAAG,CAAC,IAAO;QACT,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC;IAED,QAAQ,CAAC,SAAiB;QACxB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IACvE,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,SAAiB;QAChC,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjD,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;gBACtC,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;YACpC,CAAC;YACD,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;QACvC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;QACrB,MAAM,IAAI,CAAC,eAAe,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,KAAK;QACT,qBAAqB;QACrB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,SAAiB,EAAE,EAAE,CAC1E,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAC3B,CAAA;QACD,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAC5B,CAAC;IAED,MAAM,CAAC,EAAU;QACf,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;IAC1D,CAAC;CACF"}
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-base-to-string */
|
|
2
|
-
/* eslint-disable @typescript-eslint/prefer-promise-reject-errors */
|
|
3
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
-
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
|
|
5
|
-
import { isSafari } from '@speckle/shared'
|
|
6
|
-
import { Item } from '../../types/types.js'
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* A wrapper class for IndexedDB to simplify common database operations.
|
|
10
|
-
*/
|
|
11
|
-
export interface ItemStoreOptions {
|
|
12
|
-
indexedDB?: IDBFactory
|
|
13
|
-
keyRange?: {
|
|
14
|
-
bound: Function
|
|
15
|
-
lowerBound: Function
|
|
16
|
-
upperBound: Function
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
export class ItemStore {
|
|
20
|
-
#options: ItemStoreOptions
|
|
21
|
-
|
|
22
|
-
#db: IDBDatabase | undefined = undefined
|
|
23
|
-
readonly #dbName: string
|
|
24
|
-
readonly #storeName: string
|
|
25
|
-
|
|
26
|
-
constructor(options: ItemStoreOptions, dbName: string, storeName: string) {
|
|
27
|
-
this.#options = options
|
|
28
|
-
this.#dbName = dbName
|
|
29
|
-
this.#storeName = storeName
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Initializes the database connection and creates the object store if needed.
|
|
34
|
-
* This must be called before any other database operations.
|
|
35
|
-
*/
|
|
36
|
-
async init(): Promise<void> {
|
|
37
|
-
if (this.#db) return
|
|
38
|
-
await this.#safariFix()
|
|
39
|
-
return this.#openDatabase()
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Opens the database, and if there's an error, deletes the database and tries again.
|
|
44
|
-
*/
|
|
45
|
-
async #openDatabase(): Promise<void> {
|
|
46
|
-
const idb = this.#options.indexedDB ?? indexedDB
|
|
47
|
-
|
|
48
|
-
return new Promise((resolve, reject) => {
|
|
49
|
-
const request = idb.open(this.#dbName, 1)
|
|
50
|
-
|
|
51
|
-
request.onerror = (): any => {
|
|
52
|
-
console.warn(
|
|
53
|
-
`Failed to open database: ${this.#dbName}, deleting and trying again`
|
|
54
|
-
)
|
|
55
|
-
// Delete the database and try again
|
|
56
|
-
const deleteRequest = idb.deleteDatabase(this.#dbName)
|
|
57
|
-
deleteRequest.onsuccess = (): any => {
|
|
58
|
-
// Try opening again after deletion
|
|
59
|
-
void this.#openDatabase().then(resolve).catch(reject)
|
|
60
|
-
}
|
|
61
|
-
deleteRequest.onerror = (): any => {
|
|
62
|
-
reject(`Failed to delete and reopen database: ${this.#dbName}`)
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
request.onupgradeneeded = (event): any => {
|
|
67
|
-
const db = (event.target as IDBOpenDBRequest).result
|
|
68
|
-
if (db.objectStoreNames.contains(this.#storeName)) {
|
|
69
|
-
db.deleteObjectStore(this.#storeName)
|
|
70
|
-
}
|
|
71
|
-
db.createObjectStore(this.#storeName, { keyPath: 'baseId' })
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
request.onsuccess = (event): any => {
|
|
75
|
-
this.#db = (event.target as IDBOpenDBRequest).result
|
|
76
|
-
resolve()
|
|
77
|
-
}
|
|
78
|
-
})
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
#getDB(): IDBDatabase {
|
|
82
|
-
if (!this.#db) {
|
|
83
|
-
throw new Error('Database not initialized. Call init() first.')
|
|
84
|
-
}
|
|
85
|
-
return this.#db
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Fixes a Safari bug where IndexedDB requests get lost and never resolve - invoke before you use IndexedDB
|
|
90
|
-
* @link Credits and more info: https://github.com/jakearchibald/safari-14-idb-fix
|
|
91
|
-
*/
|
|
92
|
-
async #safariFix(): Promise<void> {
|
|
93
|
-
// No point putting other browsers or older versions of Safari through this mess.
|
|
94
|
-
if (!isSafari() || !this.#options.indexedDB?.databases) return Promise.resolve()
|
|
95
|
-
|
|
96
|
-
let intervalId: ReturnType<typeof setInterval>
|
|
97
|
-
|
|
98
|
-
return new Promise<void>((resolve: () => void) => {
|
|
99
|
-
const tryIdb = (): Promise<IDBDatabaseInfo[]> | undefined =>
|
|
100
|
-
this.#options.indexedDB?.databases().finally(resolve)
|
|
101
|
-
intervalId = setInterval(() => {
|
|
102
|
-
void tryIdb()
|
|
103
|
-
}, 100)
|
|
104
|
-
void tryIdb()
|
|
105
|
-
}).finally(() => clearInterval(intervalId))
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Inserts or updates an array of items in a single transaction.
|
|
110
|
-
* @param data The array of items to insert.
|
|
111
|
-
*/
|
|
112
|
-
bulkInsert(data: Item[]): Promise<void> {
|
|
113
|
-
return new Promise((resolve, reject) => {
|
|
114
|
-
try {
|
|
115
|
-
const transaction = this.#getDB().transaction(this.#storeName, 'readwrite', {
|
|
116
|
-
durability: 'relaxed'
|
|
117
|
-
})
|
|
118
|
-
const store = transaction.objectStore(this.#storeName)
|
|
119
|
-
|
|
120
|
-
transaction.onerror = (): any => {
|
|
121
|
-
reject(`Transaction error: ${transaction.error}`)
|
|
122
|
-
}
|
|
123
|
-
transaction.oncomplete = (): any => {
|
|
124
|
-
resolve()
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
data.forEach((item) => store.put(item))
|
|
128
|
-
} catch (error) {
|
|
129
|
-
reject(error)
|
|
130
|
-
}
|
|
131
|
-
})
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Retrieves an array of items from the object store based on their IDs.
|
|
136
|
-
* @param ids The array of IDs to retrieve.
|
|
137
|
-
*/
|
|
138
|
-
bulkGet(ids: string[]): Promise<(Item | undefined)[]> {
|
|
139
|
-
return new Promise((resolve, reject) => {
|
|
140
|
-
if (ids.length === 0) {
|
|
141
|
-
return resolve([])
|
|
142
|
-
}
|
|
143
|
-
try {
|
|
144
|
-
const transaction = this.#getDB().transaction(this.#storeName, 'readonly', {
|
|
145
|
-
durability: 'relaxed'
|
|
146
|
-
})
|
|
147
|
-
const store = transaction.objectStore(this.#storeName)
|
|
148
|
-
const promises: Promise<Item | undefined>[] = []
|
|
149
|
-
|
|
150
|
-
for (const id of ids) {
|
|
151
|
-
promises.push(
|
|
152
|
-
new Promise((resolveGet, rejectGet) => {
|
|
153
|
-
const request = store.get(id)
|
|
154
|
-
request.onerror = (): void =>
|
|
155
|
-
rejectGet(`Request error for id ${id}: ${request.error}`)
|
|
156
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
157
|
-
request.onsuccess = (): void => resolveGet(request.result)
|
|
158
|
-
})
|
|
159
|
-
)
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
Promise.all(promises)
|
|
163
|
-
.then((results) => {
|
|
164
|
-
resolve(results)
|
|
165
|
-
})
|
|
166
|
-
.catch(reject)
|
|
167
|
-
} catch (error) {
|
|
168
|
-
reject(error)
|
|
169
|
-
}
|
|
170
|
-
})
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Retrieves all items from the object store.
|
|
175
|
-
*/
|
|
176
|
-
getAll(): Promise<Item[]> {
|
|
177
|
-
return new Promise((resolve, reject) => {
|
|
178
|
-
try {
|
|
179
|
-
const transaction = this.#getDB().transaction(this.#storeName, 'readonly')
|
|
180
|
-
const store = transaction.objectStore(this.#storeName)
|
|
181
|
-
const request = store.getAll()
|
|
182
|
-
|
|
183
|
-
request.onerror = (): any => reject(`Request error: ${request.error}`)
|
|
184
|
-
request.onsuccess = (): any => resolve(request.result)
|
|
185
|
-
} catch (error) {
|
|
186
|
-
reject(error)
|
|
187
|
-
}
|
|
188
|
-
})
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
close(): void {
|
|
192
|
-
if (!this.#db) return
|
|
193
|
-
this.#db.close()
|
|
194
|
-
this.#db = undefined
|
|
195
|
-
}
|
|
196
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import Queue from './queue.js'
|
|
2
|
-
|
|
3
|
-
export default class BatchedPool<T> implements Queue<T> {
|
|
4
|
-
#queue: T[] = []
|
|
5
|
-
#concurrencyAndSizes: number[]
|
|
6
|
-
#processFunction: (batch: T[]) => Promise<void>
|
|
7
|
-
|
|
8
|
-
#baseInterval: number
|
|
9
|
-
|
|
10
|
-
#processingLoop: Promise<void>
|
|
11
|
-
#disposed = false
|
|
12
|
-
|
|
13
|
-
constructor(params: {
|
|
14
|
-
concurrencyAndSizes: number[]
|
|
15
|
-
maxWaitTime?: number
|
|
16
|
-
processFunction: (batch: T[]) => Promise<void>
|
|
17
|
-
}) {
|
|
18
|
-
this.#concurrencyAndSizes = params.concurrencyAndSizes
|
|
19
|
-
this.#baseInterval = Math.min(params.maxWaitTime ?? 200, 200) // Initial batch time (ms)
|
|
20
|
-
this.#processFunction = params.processFunction
|
|
21
|
-
this.#processingLoop = this.#loop()
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
add(item: T): void {
|
|
25
|
-
this.#queue.push(item)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
getBatch(batchSize: number): T[] {
|
|
29
|
-
return this.#queue.splice(0, Math.min(batchSize, this.#queue.length))
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async #runWorker(batchSize: number): Promise<void> {
|
|
33
|
-
while (!this.#disposed || this.#queue.length > 0) {
|
|
34
|
-
if (this.#queue.length > 0) {
|
|
35
|
-
const batch = this.getBatch(batchSize)
|
|
36
|
-
await this.#processFunction(batch)
|
|
37
|
-
}
|
|
38
|
-
await this.#delay(this.#baseInterval)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async disposeAsync(): Promise<void> {
|
|
43
|
-
this.#disposed = true
|
|
44
|
-
await this.#processingLoop
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async #loop(): Promise<void> {
|
|
48
|
-
// Initialize workers
|
|
49
|
-
const workers = Array.from(this.#concurrencyAndSizes, (batchSize: number) =>
|
|
50
|
-
this.#runWorker(batchSize)
|
|
51
|
-
)
|
|
52
|
-
await Promise.all(workers)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
#delay(ms: number): Promise<void> {
|
|
56
|
-
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
57
|
-
}
|
|
58
|
-
}
|