@speckle/objectloader2 2.25.1 → 2.25.7
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/helpers/aggregateQueue.d.ts +8 -0
- package/dist/commonjs/helpers/aggregateQueue.d.ts.map +1 -0
- package/dist/commonjs/helpers/aggregateQueue.js +19 -0
- package/dist/commonjs/helpers/aggregateQueue.js.map +1 -0
- package/dist/commonjs/helpers/asyncGeneratorQueue.d.ts +8 -0
- package/dist/commonjs/helpers/asyncGeneratorQueue.d.ts.map +1 -0
- package/dist/commonjs/helpers/asyncGeneratorQueue.js +35 -0
- package/dist/commonjs/helpers/asyncGeneratorQueue.js.map +1 -0
- package/dist/commonjs/helpers/batchedPool.d.ts +12 -0
- package/dist/commonjs/helpers/batchedPool.d.ts.map +1 -0
- package/dist/commonjs/helpers/batchedPool.js +45 -0
- package/dist/commonjs/helpers/batchedPool.js.map +1 -0
- package/dist/commonjs/helpers/batchingQueue.d.ts +14 -0
- package/dist/commonjs/helpers/batchingQueue.d.ts.map +1 -0
- package/dist/commonjs/helpers/batchingQueue.js +77 -0
- package/dist/commonjs/helpers/batchingQueue.js.map +1 -0
- package/dist/commonjs/helpers/bufferQueue.d.ts +7 -0
- package/dist/commonjs/helpers/bufferQueue.d.ts.map +1 -0
- package/dist/commonjs/helpers/bufferQueue.js +13 -0
- package/dist/commonjs/helpers/bufferQueue.js.map +1 -0
- package/dist/commonjs/helpers/cachePump.d.ts +22 -0
- package/dist/commonjs/helpers/cachePump.d.ts.map +1 -0
- package/dist/commonjs/helpers/cachePump.js +86 -0
- package/dist/commonjs/helpers/cachePump.js.map +1 -0
- package/dist/commonjs/helpers/cacheReader.d.ts +14 -0
- package/dist/commonjs/helpers/cacheReader.d.ts.map +1 -0
- package/dist/commonjs/helpers/cacheReader.js +58 -0
- package/dist/commonjs/helpers/cacheReader.js.map +1 -0
- package/dist/commonjs/helpers/defermentManager.d.ts +28 -0
- package/dist/commonjs/helpers/defermentManager.d.ts.map +1 -0
- package/dist/commonjs/helpers/defermentManager.js +150 -0
- package/dist/commonjs/helpers/defermentManager.js.map +1 -0
- package/dist/commonjs/helpers/deferredBase.d.ts +19 -0
- package/dist/commonjs/helpers/deferredBase.d.ts.map +1 -0
- package/dist/commonjs/helpers/deferredBase.js +51 -0
- package/dist/commonjs/helpers/deferredBase.js.map +1 -0
- package/dist/commonjs/helpers/keyedQueue.d.ts +11 -0
- package/dist/commonjs/helpers/keyedQueue.d.ts.map +1 -0
- package/dist/commonjs/helpers/keyedQueue.js +41 -0
- package/dist/commonjs/helpers/keyedQueue.js.map +1 -0
- package/dist/commonjs/helpers/memoryPump.d.ts +15 -0
- package/dist/commonjs/helpers/memoryPump.d.ts.map +1 -0
- package/dist/commonjs/helpers/memoryPump.js +34 -0
- package/dist/commonjs/helpers/memoryPump.js.map +1 -0
- package/dist/commonjs/helpers/pump.d.ts +8 -0
- package/dist/commonjs/helpers/pump.d.ts.map +1 -0
- package/dist/commonjs/helpers/pump.js +3 -0
- package/dist/commonjs/helpers/pump.js.map +1 -0
- package/dist/commonjs/helpers/queue.d.ts +4 -0
- package/dist/commonjs/helpers/queue.d.ts.map +1 -0
- package/dist/commonjs/helpers/queue.js +3 -0
- package/dist/commonjs/helpers/queue.js.map +1 -0
- package/dist/commonjs/index.d.ts +3 -0
- package/dist/commonjs/index.d.ts.map +1 -0
- package/dist/commonjs/index.js +1 -3
- package/dist/commonjs/index.js.map +1 -0
- package/dist/commonjs/operations/databases/indexedDatabase.d.ts +27 -0
- package/dist/commonjs/operations/databases/indexedDatabase.d.ts.map +1 -0
- package/dist/commonjs/operations/databases/indexedDatabase.js +98 -0
- package/dist/commonjs/operations/databases/indexedDatabase.js.map +1 -0
- package/dist/commonjs/operations/databases/memoryDatabase.d.ts +13 -0
- package/dist/commonjs/operations/databases/memoryDatabase.d.ts.map +1 -0
- package/dist/commonjs/operations/databases/memoryDatabase.js +33 -0
- package/dist/commonjs/operations/databases/memoryDatabase.js.map +1 -0
- package/dist/commonjs/operations/downloaders/memoryDownloader.d.ts +16 -0
- package/dist/commonjs/operations/downloaders/memoryDownloader.d.ts.map +1 -0
- package/dist/commonjs/operations/downloaders/memoryDownloader.js +35 -0
- package/dist/commonjs/operations/downloaders/memoryDownloader.js.map +1 -0
- package/dist/commonjs/operations/downloaders/serverDownloader.d.ts +32 -0
- package/dist/commonjs/operations/downloaders/serverDownloader.d.ts.map +1 -0
- package/dist/commonjs/operations/downloaders/serverDownloader.js +169 -0
- package/dist/commonjs/operations/downloaders/serverDownloader.js.map +1 -0
- package/dist/commonjs/operations/interfaces.d.ts +19 -0
- package/dist/commonjs/operations/interfaces.d.ts.map +1 -0
- package/dist/commonjs/operations/interfaces.js +3 -0
- package/dist/commonjs/operations/interfaces.js.map +1 -0
- package/dist/commonjs/operations/objectLoader2.d.ts +16 -0
- package/dist/commonjs/operations/objectLoader2.d.ts.map +1 -0
- package/dist/commonjs/operations/objectLoader2.js +101 -0
- package/dist/commonjs/operations/objectLoader2.js.map +1 -0
- package/dist/commonjs/operations/objectLoader2Factory.d.ts +25 -0
- package/dist/commonjs/operations/objectLoader2Factory.d.ts.map +1 -0
- package/dist/commonjs/operations/objectLoader2Factory.js +68 -0
- package/dist/commonjs/operations/objectLoader2Factory.js.map +1 -0
- package/dist/commonjs/operations/options.d.ts +26 -0
- package/dist/commonjs/operations/options.d.ts.map +1 -0
- package/dist/commonjs/operations/options.js +3 -0
- package/dist/commonjs/operations/options.js.map +1 -0
- package/dist/commonjs/operations/traverser.d.ts +19 -0
- package/dist/commonjs/operations/traverser.d.ts.map +1 -0
- package/dist/commonjs/operations/traverser.js +96 -0
- package/dist/commonjs/operations/traverser.js.map +1 -0
- package/dist/commonjs/package.json +3 -0
- package/dist/commonjs/types/errors.d.ts +21 -0
- package/dist/commonjs/types/errors.d.ts.map +1 -0
- package/dist/commonjs/types/errors.js +28 -0
- package/dist/commonjs/types/errors.js.map +1 -0
- package/dist/commonjs/types/types.d.ts +25 -0
- package/dist/commonjs/types/types.d.ts.map +1 -0
- package/dist/commonjs/types/types.js +39 -0
- package/dist/commonjs/types/types.js.map +1 -0
- package/dist/esm/helpers/aggregateQueue.d.ts +8 -0
- package/dist/esm/helpers/aggregateQueue.d.ts.map +1 -0
- package/dist/esm/helpers/aggregateQueue.js +16 -0
- package/dist/esm/helpers/aggregateQueue.js.map +1 -0
- package/dist/esm/helpers/asyncGeneratorQueue.d.ts +8 -0
- package/dist/esm/helpers/asyncGeneratorQueue.d.ts.map +1 -0
- package/dist/esm/helpers/asyncGeneratorQueue.js +32 -0
- package/dist/esm/helpers/asyncGeneratorQueue.js.map +1 -0
- package/dist/esm/helpers/batchedPool.d.ts +12 -0
- package/dist/esm/helpers/batchedPool.d.ts.map +1 -0
- package/dist/esm/helpers/batchedPool.js +42 -0
- package/dist/esm/helpers/batchedPool.js.map +1 -0
- package/dist/esm/helpers/batchingQueue.d.ts +14 -0
- package/dist/esm/helpers/batchingQueue.d.ts.map +1 -0
- package/dist/esm/helpers/batchingQueue.js +71 -0
- package/dist/esm/helpers/batchingQueue.js.map +1 -0
- package/dist/esm/helpers/bufferQueue.d.ts +7 -0
- package/dist/esm/helpers/bufferQueue.d.ts.map +1 -0
- package/dist/esm/helpers/bufferQueue.js +10 -0
- package/dist/esm/helpers/bufferQueue.js.map +1 -0
- package/dist/esm/helpers/cachePump.d.ts +22 -0
- package/dist/esm/helpers/cachePump.d.ts.map +1 -0
- package/dist/esm/helpers/cachePump.js +79 -0
- package/dist/esm/helpers/cachePump.js.map +1 -0
- package/dist/esm/helpers/cacheReader.d.ts +14 -0
- package/dist/esm/helpers/cacheReader.d.ts.map +1 -0
- package/dist/esm/helpers/cacheReader.js +51 -0
- package/dist/esm/helpers/cacheReader.js.map +1 -0
- package/dist/esm/helpers/defermentManager.d.ts +28 -0
- package/dist/esm/helpers/defermentManager.d.ts.map +1 -0
- package/dist/esm/helpers/defermentManager.js +146 -0
- package/dist/esm/helpers/defermentManager.js.map +1 -0
- package/dist/esm/helpers/deferredBase.d.ts +19 -0
- package/dist/esm/helpers/deferredBase.d.ts.map +1 -0
- package/dist/esm/helpers/deferredBase.js +47 -0
- package/dist/esm/helpers/deferredBase.js.map +1 -0
- package/dist/esm/helpers/keyedQueue.d.ts +11 -0
- package/dist/esm/helpers/keyedQueue.d.ts.map +1 -0
- package/dist/esm/helpers/keyedQueue.js +38 -0
- package/dist/esm/helpers/keyedQueue.js.map +1 -0
- package/dist/esm/helpers/memoryPump.d.ts +15 -0
- package/dist/esm/helpers/memoryPump.d.ts.map +1 -0
- package/dist/esm/helpers/memoryPump.js +30 -0
- package/dist/esm/helpers/memoryPump.js.map +1 -0
- package/dist/esm/helpers/pump.d.ts +8 -0
- package/dist/esm/helpers/pump.d.ts.map +1 -0
- package/dist/esm/helpers/pump.js +2 -0
- package/dist/esm/helpers/pump.js.map +1 -0
- package/dist/esm/helpers/queue.d.ts +4 -0
- package/dist/esm/helpers/queue.d.ts.map +1 -0
- package/dist/esm/helpers/queue.js +2 -0
- package/dist/esm/helpers/queue.js.map +1 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/operations/databases/indexedDatabase.d.ts +27 -0
- package/dist/esm/operations/databases/indexedDatabase.d.ts.map +1 -0
- package/dist/esm/operations/databases/indexedDatabase.js +93 -0
- package/dist/esm/operations/databases/indexedDatabase.js.map +1 -0
- package/dist/esm/operations/databases/memoryDatabase.d.ts +13 -0
- package/dist/esm/operations/databases/memoryDatabase.d.ts.map +1 -0
- package/dist/esm/operations/databases/memoryDatabase.js +29 -0
- package/dist/esm/operations/databases/memoryDatabase.js.map +1 -0
- package/dist/esm/operations/downloaders/memoryDownloader.d.ts +16 -0
- package/dist/esm/operations/downloaders/memoryDownloader.d.ts.map +1 -0
- package/dist/esm/operations/downloaders/memoryDownloader.js +31 -0
- package/dist/esm/operations/downloaders/memoryDownloader.js.map +1 -0
- package/dist/esm/operations/downloaders/serverDownloader.d.ts +32 -0
- package/dist/esm/operations/downloaders/serverDownloader.d.ts.map +1 -0
- package/dist/esm/operations/downloaders/serverDownloader.js +163 -0
- package/dist/esm/operations/downloaders/serverDownloader.js.map +1 -0
- package/dist/esm/operations/interfaces.d.ts +19 -0
- package/dist/esm/operations/interfaces.d.ts.map +1 -0
- package/dist/esm/operations/interfaces.js +2 -0
- package/dist/esm/operations/interfaces.js.map +1 -0
- package/dist/esm/operations/objectLoader2.d.ts +16 -0
- package/dist/esm/operations/objectLoader2.d.ts.map +1 -0
- package/dist/esm/operations/objectLoader2.js +94 -0
- package/dist/esm/operations/objectLoader2.js.map +1 -0
- package/dist/esm/operations/objectLoader2Factory.d.ts +25 -0
- package/dist/esm/operations/objectLoader2Factory.d.ts.map +1 -0
- package/dist/esm/operations/objectLoader2Factory.js +61 -0
- package/dist/esm/operations/objectLoader2Factory.js.map +1 -0
- package/dist/esm/operations/options.d.ts +26 -0
- package/dist/esm/operations/options.d.ts.map +1 -0
- package/dist/esm/operations/options.js +2 -0
- package/dist/esm/operations/options.js.map +1 -0
- package/dist/esm/operations/traverser.d.ts +19 -0
- package/dist/esm/operations/traverser.d.ts.map +1 -0
- package/dist/esm/operations/traverser.js +93 -0
- package/dist/esm/operations/traverser.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/types/errors.d.ts +21 -0
- package/dist/esm/types/errors.d.ts.map +1 -0
- package/dist/esm/types/errors.js +23 -0
- package/dist/esm/types/errors.js.map +1 -0
- package/dist/esm/types/types.d.ts +25 -0
- package/dist/esm/types/types.d.ts.map +1 -0
- package/dist/esm/types/types.js +33 -0
- package/dist/esm/types/types.js.map +1 -0
- package/package.json +2 -2
- package/src/helpers/cachePump.disposal.spec.ts +3 -1
- package/src/helpers/cachePump.spec.ts +2 -1
- package/src/helpers/cachePump.ts +9 -1
- package/src/helpers/defermentManager.defermentTotals.spec.ts +53 -0
- package/src/helpers/defermentManager.ts +20 -1
- package/src/index.ts +0 -1
- package/src/operations/databases/__snapshots__/indexedDatabase.spec.ts.snap +13 -26
- package/src/operations/databases/indexedDatabase.spec.ts +23 -27
- package/src/operations/databases/indexedDatabase.ts +1 -25
- package/src/operations/databases/memoryDatabase.spec.ts +48 -0
- package/src/operations/databases/memoryDatabase.ts +0 -8
- package/src/operations/downloaders/__snapshots__/memoryDownloader.spec.ts.snap +12 -0
- package/src/operations/downloaders/memoryDownloader.spec.ts +49 -0
- package/src/operations/downloaders/memoryDownloader.ts +1 -1
- package/src/operations/downloaders/serverDownloader.ts +1 -1
- package/src/operations/interfaces.ts +0 -1
- package/src/operations/objectLoader2.ts +12 -4
- package/src/operations/objectLoader2Factory.ts +40 -18
- package/src/test/e2e.spec.ts +4 -2
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Base } from '../types/types.js';
|
|
2
|
+
import { ObjectLoader2 } from './objectLoader2.js';
|
|
3
|
+
export type ProgressStage = 'download' | 'construction';
|
|
4
|
+
export type OnProgress = (e: {
|
|
5
|
+
stage: ProgressStage;
|
|
6
|
+
current: number;
|
|
7
|
+
total: number;
|
|
8
|
+
}) => void;
|
|
9
|
+
export interface TraverserOptions {
|
|
10
|
+
excludeProps?: string[];
|
|
11
|
+
}
|
|
12
|
+
export default class Traverser {
|
|
13
|
+
#private;
|
|
14
|
+
constructor(loader: ObjectLoader2, options?: TraverserOptions);
|
|
15
|
+
traverse(onProgress?: OnProgress): Promise<Base>;
|
|
16
|
+
traverseArray(array: Array<unknown>, onProgress?: OnProgress): Promise<void>;
|
|
17
|
+
traverseBase(base: Base, onProgress?: OnProgress): Promise<Base>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=traverser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traverser.d.ts","sourceRoot":"","sources":["../../../src/operations/traverser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAA4C,MAAM,mBAAmB,CAAA;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,cAAc,CAAA;AACvD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE;IAC3B,KAAK,EAAE,aAAa,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd,KAAK,IAAI,CAAA;AAEV,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACxB;AAED,MAAM,CAAC,OAAO,OAAO,SAAS;;gBAOhB,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAKvD,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAehD,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAe5E,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAuDvE"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { isBase, isReference, isScalar } from '../types/types.js';
|
|
2
|
+
export default class Traverser {
|
|
3
|
+
#loader;
|
|
4
|
+
#options;
|
|
5
|
+
#totalChildrenCount = 0;
|
|
6
|
+
#traversedReferencesCount = 0;
|
|
7
|
+
constructor(loader, options) {
|
|
8
|
+
this.#options = options || {};
|
|
9
|
+
this.#loader = loader;
|
|
10
|
+
}
|
|
11
|
+
async traverse(onProgress) {
|
|
12
|
+
let firstObjectPromise = undefined;
|
|
13
|
+
for await (const obj of this.#loader.getObjectIterator()) {
|
|
14
|
+
if (!firstObjectPromise) {
|
|
15
|
+
firstObjectPromise = this.traverseBase(obj, onProgress);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (firstObjectPromise) {
|
|
19
|
+
return await firstObjectPromise;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
throw new Error('No objects found');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async traverseArray(array, onProgress) {
|
|
26
|
+
for (let i = 0; i < 10; i++) {
|
|
27
|
+
const prop = array[i];
|
|
28
|
+
if (isScalar(prop))
|
|
29
|
+
continue;
|
|
30
|
+
if (isBase(prop)) {
|
|
31
|
+
array[i] = await this.traverseBase(prop, onProgress);
|
|
32
|
+
}
|
|
33
|
+
else if (isReference(prop)) {
|
|
34
|
+
array[i] = await this.traverseBase(await this.#loader.getObject({ id: prop.referencedId }), onProgress);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async traverseBase(base, onProgress) {
|
|
39
|
+
for (const ignoredProp of this.#options.excludeProps || []) {
|
|
40
|
+
delete base[ignoredProp];
|
|
41
|
+
}
|
|
42
|
+
if (base.__closure) {
|
|
43
|
+
const ids = Object.keys(base.__closure);
|
|
44
|
+
const promises = [];
|
|
45
|
+
for (const id of ids) {
|
|
46
|
+
promises.push(this.traverseBase(await this.#loader.getObject({ id }), onProgress));
|
|
47
|
+
}
|
|
48
|
+
await Promise.all(promises);
|
|
49
|
+
}
|
|
50
|
+
delete base['__closure'];
|
|
51
|
+
// De-chunk
|
|
52
|
+
if (base.speckle_type?.includes('DataChunk')) {
|
|
53
|
+
const chunk = base;
|
|
54
|
+
if (chunk.data) {
|
|
55
|
+
await this.traverseArray(chunk.data, onProgress);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//other props
|
|
59
|
+
for (const prop in base) {
|
|
60
|
+
if (prop === '__closure')
|
|
61
|
+
continue;
|
|
62
|
+
if (prop === 'referenceId')
|
|
63
|
+
continue;
|
|
64
|
+
if (prop === 'speckle_type')
|
|
65
|
+
continue;
|
|
66
|
+
if (prop === 'data')
|
|
67
|
+
continue;
|
|
68
|
+
const baseProp = base[prop];
|
|
69
|
+
if (isScalar(baseProp))
|
|
70
|
+
continue;
|
|
71
|
+
if (isBase(baseProp)) {
|
|
72
|
+
await this.traverseBase(baseProp, onProgress);
|
|
73
|
+
}
|
|
74
|
+
else if (isReference(baseProp)) {
|
|
75
|
+
await this.traverseBase(await this.#loader.getObject({ id: baseProp.referencedId }), onProgress);
|
|
76
|
+
}
|
|
77
|
+
else if (Array.isArray(baseProp)) {
|
|
78
|
+
await this.traverseArray(baseProp, onProgress);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (onProgress) {
|
|
82
|
+
onProgress({
|
|
83
|
+
stage: 'construction',
|
|
84
|
+
current: ++this.#traversedReferencesCount > this.#totalChildrenCount
|
|
85
|
+
? this.#totalChildrenCount
|
|
86
|
+
: this.#traversedReferencesCount,
|
|
87
|
+
total: this.#totalChildrenCount
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return base;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=traverser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traverser.js","sourceRoot":"","sources":["../../../src/operations/traverser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base ObjectLoader error
|
|
3
|
+
*/
|
|
4
|
+
declare class BaseError extends Error {
|
|
5
|
+
/**
|
|
6
|
+
* Default message if none is passed
|
|
7
|
+
*/
|
|
8
|
+
static defaultMessage: string;
|
|
9
|
+
/**
|
|
10
|
+
* @param {string} [message]
|
|
11
|
+
*/
|
|
12
|
+
constructor(message: string);
|
|
13
|
+
}
|
|
14
|
+
export declare class ObjectLoaderConfigurationError extends BaseError {
|
|
15
|
+
static defaultMessage: string;
|
|
16
|
+
}
|
|
17
|
+
export declare class ObjectLoaderRuntimeError extends BaseError {
|
|
18
|
+
static defaultMessage: string;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/types/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAM,SAAU,SAAQ,KAAK;IAC3B;;OAEG;IACH,MAAM,CAAC,cAAc,SAA8B;IAEnD;;OAEG;gBACS,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,8BAA+B,SAAQ,SAAS;IAC3D,MAAM,CAAC,cAAc,SAA0C;CAChE;AAED,qBAAa,wBAAyB,SAAQ,SAAS;IACrD,MAAM,CAAC,cAAc,SAAiD;CACvE"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base ObjectLoader error
|
|
3
|
+
*/
|
|
4
|
+
class BaseError extends Error {
|
|
5
|
+
/**
|
|
6
|
+
* Default message if none is passed
|
|
7
|
+
*/
|
|
8
|
+
static defaultMessage = 'Unexpected error occurred';
|
|
9
|
+
/**
|
|
10
|
+
* @param {string} [message]
|
|
11
|
+
*/
|
|
12
|
+
constructor(message) {
|
|
13
|
+
message ||= new.target.defaultMessage;
|
|
14
|
+
super(message);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class ObjectLoaderConfigurationError extends BaseError {
|
|
18
|
+
static defaultMessage = 'Object loader configured incorrectly!';
|
|
19
|
+
}
|
|
20
|
+
export class ObjectLoaderRuntimeError extends BaseError {
|
|
21
|
+
static defaultMessage = 'Object loader encountered a runtime problem!';
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/types/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,SAAU,SAAQ,KAAK;IAC3B;;OAEG;IACH,MAAM,CAAC,cAAc,GAAG,2BAA2B,CAAA;IAEnD;;OAEG;IACH,YAAY,OAAe;QACzB,OAAO,KAAK,GAAG,CAAC,MAAM,CAAC,cAAc,CAAA;QACrC,KAAK,CAAC,OAAO,CAAC,CAAA;IAChB,CAAC;;AAGH,MAAM,OAAO,8BAA+B,SAAQ,SAAS;IAC3D,MAAM,CAAC,cAAc,GAAG,uCAAuC,CAAA;;AAGjE,MAAM,OAAO,wBAAyB,SAAQ,SAAS;IACrD,MAAM,CAAC,cAAc,GAAG,8CAA8C,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type CustomLogger = (message?: string, ...optionalParams: unknown[]) => void;
|
|
2
|
+
export type Fetcher = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
3
|
+
export interface Item {
|
|
4
|
+
baseId: string;
|
|
5
|
+
base: Base;
|
|
6
|
+
size?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface Base {
|
|
9
|
+
id: string;
|
|
10
|
+
speckle_type: string;
|
|
11
|
+
__closure?: Record<string, number>;
|
|
12
|
+
}
|
|
13
|
+
export interface Reference {
|
|
14
|
+
speckle_type: string;
|
|
15
|
+
referencedId: string;
|
|
16
|
+
__closure?: Record<string, number>;
|
|
17
|
+
}
|
|
18
|
+
export interface DataChunk extends Base {
|
|
19
|
+
data?: Base[];
|
|
20
|
+
}
|
|
21
|
+
export declare function isBase(maybeBase?: unknown): maybeBase is Base;
|
|
22
|
+
export declare function isReference(maybeRef?: unknown): maybeRef is Reference;
|
|
23
|
+
export declare function isScalar(value: unknown): value is string | number | boolean | bigint | symbol | undefined;
|
|
24
|
+
export declare function take<T>(it: Iterator<T>, count: number): T[];
|
|
25
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;AAEnF,MAAM,MAAM,OAAO,GAAG,CACpB,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,EAC7B,IAAI,CAAC,EAAE,WAAW,KACf,OAAO,CAAC,QAAQ,CAAC,CAAA;AAEtB,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,IAAI,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACnC;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACnC;AAED,MAAM,WAAW,SAAU,SAAQ,IAAI;IACrC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAA;CACd;AAED,wBAAgB,MAAM,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,IAAI,IAAI,CAO7D;AAED,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,QAAQ,IAAI,SAAS,CAOrE;AAED,wBAAgB,QAAQ,CACtB,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAWlE;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,EAAE,CAQ3D"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export function isBase(maybeBase) {
|
|
2
|
+
return (maybeBase !== null &&
|
|
3
|
+
typeof maybeBase === 'object' &&
|
|
4
|
+
'id' in maybeBase &&
|
|
5
|
+
typeof maybeBase.id === 'string');
|
|
6
|
+
}
|
|
7
|
+
export function isReference(maybeRef) {
|
|
8
|
+
return (maybeRef !== null &&
|
|
9
|
+
typeof maybeRef === 'object' &&
|
|
10
|
+
'referencedId' in maybeRef &&
|
|
11
|
+
typeof maybeRef.referencedId === 'string');
|
|
12
|
+
}
|
|
13
|
+
export function isScalar(value) {
|
|
14
|
+
const type = typeof value;
|
|
15
|
+
return (value === null ||
|
|
16
|
+
type === 'string' ||
|
|
17
|
+
type === 'number' ||
|
|
18
|
+
type === 'boolean' ||
|
|
19
|
+
type === 'bigint' ||
|
|
20
|
+
type === 'symbol' ||
|
|
21
|
+
type === 'undefined');
|
|
22
|
+
}
|
|
23
|
+
export function take(it, count) {
|
|
24
|
+
const result = [];
|
|
25
|
+
for (let i = 0; i < count; i++) {
|
|
26
|
+
const itr = it.next();
|
|
27
|
+
if (itr.done)
|
|
28
|
+
break;
|
|
29
|
+
result.push(itr.value);
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/types/types.ts"],"names":[],"mappings":"AA6BA,MAAM,UAAU,MAAM,CAAC,SAAmB;IACxC,OAAO,CACL,SAAS,KAAK,IAAI;QAClB,OAAO,SAAS,KAAK,QAAQ;QAC7B,IAAI,IAAI,SAAS;QACjB,OAAO,SAAS,CAAC,EAAE,KAAK,QAAQ,CACjC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAkB;IAC5C,OAAO,CACL,QAAQ,KAAK,IAAI;QACjB,OAAO,QAAQ,KAAK,QAAQ;QAC5B,cAAc,IAAI,QAAQ;QAC1B,OAAO,QAAQ,CAAC,YAAY,KAAK,QAAQ,CAC1C,CAAA;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,KAAc;IAEd,MAAM,IAAI,GAAG,OAAO,KAAK,CAAA;IACzB,OAAO,CACL,KAAK,KAAK,IAAI;QACd,IAAI,KAAK,QAAQ;QACjB,IAAI,KAAK,QAAQ;QACjB,IAAI,KAAK,SAAS;QAClB,IAAI,KAAK,QAAQ;QACjB,IAAI,KAAK,QAAQ;QACjB,IAAI,KAAK,WAAW,CACrB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,IAAI,CAAI,EAAe,EAAE,KAAa;IACpD,MAAM,MAAM,GAAQ,EAAE,CAAA;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,EAAE,CAAA;QACrB,IAAI,GAAG,CAAC,IAAI;YAAE,MAAK;QACnB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IACxB,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@speckle/objectloader2",
|
|
3
|
-
"version": "2.25.
|
|
3
|
+
"version": "2.25.7",
|
|
4
4
|
"description": "This is an updated objectloader for the Speckle viewer written in typescript",
|
|
5
5
|
"main": "./dist/commonjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"author": "AEC Systems",
|
|
34
34
|
"license": "Apache-2.0",
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@speckle/shared": "^2.25.
|
|
36
|
+
"@speckle/shared": "^2.25.7",
|
|
37
37
|
"dexie": "^4.0.11"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
@@ -8,7 +8,9 @@ import { DefermentManager } from './defermentManager.js'
|
|
|
8
8
|
const makeDatabase = (): Database =>
|
|
9
9
|
({
|
|
10
10
|
cacheSaveBatch: async (): Promise<void> => {},
|
|
11
|
-
getAll: async (): Promise<(Item | undefined)[]> => Promise.resolve([])
|
|
11
|
+
getAll: async (): Promise<(Item | undefined)[]> => Promise.resolve([]),
|
|
12
|
+
getItem: async (): Promise<Item | undefined> => Promise.resolve(undefined),
|
|
13
|
+
disposeAsync: async (): Promise<void> => {}
|
|
12
14
|
} as unknown as Database)
|
|
13
15
|
const makeGathered = (): AsyncGeneratorQueue<Item> =>
|
|
14
16
|
({
|
|
@@ -78,7 +78,8 @@ describe('CachePump testing', () => {
|
|
|
78
78
|
const i2: Item = { baseId: 'id2', base: { id: 'id', speckle_type: 'type' } }
|
|
79
79
|
|
|
80
80
|
const db: Database = {
|
|
81
|
-
getAll: async () => Promise.resolve([])
|
|
81
|
+
getAll: async () => Promise.resolve([]),
|
|
82
|
+
disposeAsync: async (): Promise<void> => {}
|
|
82
83
|
} as unknown as Database
|
|
83
84
|
const gathered = new AsyncGeneratorQueue<Item>()
|
|
84
85
|
const deferments = new DefermentManager({ maxSizeInMb: 1, ttlms: 1 })
|
package/src/helpers/cachePump.ts
CHANGED
|
@@ -19,6 +19,8 @@ export class CachePump implements Pump {
|
|
|
19
19
|
|
|
20
20
|
#options: CacheOptions
|
|
21
21
|
|
|
22
|
+
#disposed = false
|
|
23
|
+
|
|
22
24
|
constructor(
|
|
23
25
|
database: Database,
|
|
24
26
|
gathered: AsyncGeneratorQueue<Item>,
|
|
@@ -46,6 +48,12 @@ export class CachePump implements Pump {
|
|
|
46
48
|
|
|
47
49
|
async disposeAsync(): Promise<void> {
|
|
48
50
|
await this.#writeQueue?.disposeAsync()
|
|
51
|
+
await this.#database.disposeAsync()
|
|
52
|
+
this.#disposed = true
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get isDisposed(): boolean {
|
|
56
|
+
return this.#disposed
|
|
49
57
|
}
|
|
50
58
|
|
|
51
59
|
async pumpItems(params: {
|
|
@@ -57,7 +65,7 @@ export class CachePump implements Pump {
|
|
|
57
65
|
const maxCacheReadSize = this.#options.maxCacheReadSize
|
|
58
66
|
|
|
59
67
|
for (let i = 0; i < ids.length; ) {
|
|
60
|
-
if (this
|
|
68
|
+
if (this.isDisposed) break
|
|
61
69
|
if ((this.#writeQueue?.count() ?? 0) > this.#options.maxWriteQueueSize) {
|
|
62
70
|
this.#logger(
|
|
63
71
|
'pausing reads (# in write queue: ' + this.#writeQueue?.count() + ')'
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, test, expect, beforeEach } from 'vitest'
|
|
2
|
+
import { DefermentManager } from './defermentManager.js'
|
|
3
|
+
import { DefermentManagerOptions } from '../operations/options.js'
|
|
4
|
+
import { Base, Item } from '../types/types.js'
|
|
5
|
+
|
|
6
|
+
const makeItem = (id: string, size = 1): Item => ({
|
|
7
|
+
baseId: id,
|
|
8
|
+
base: { foo: 'bar' } as unknown as Base,
|
|
9
|
+
size
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
describe('DefermentManager totalDefermentRequests', () => {
|
|
13
|
+
let manager: DefermentManager
|
|
14
|
+
let options: DefermentManagerOptions
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
options = { maxSizeInMb: 1, ttlms: 1000, logger: (): void => {} }
|
|
18
|
+
manager = new DefermentManager(options)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
test('tracks deferment requests for each id', () => {
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
23
|
+
manager.defer({ id: 'a' })
|
|
24
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
25
|
+
manager.defer({ id: 'a' })
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
27
|
+
manager.defer({ id: 'b' })
|
|
28
|
+
// @ts-expect-error: access private for test
|
|
29
|
+
expect(manager.totalDefermentRequests.get('a')).toBe(2)
|
|
30
|
+
// @ts-expect-error: access private for test
|
|
31
|
+
expect(manager.totalDefermentRequests.get('b')).toBe(1)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('increments and does not reset on undefer', () => {
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
36
|
+
manager.defer({ id: 'x' })
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
38
|
+
manager.defer({ id: 'x' })
|
|
39
|
+
manager.undefer(makeItem('x'))
|
|
40
|
+
// @ts-expect-error: access private for test
|
|
41
|
+
expect(manager.totalDefermentRequests.get('x')).toBe(2)
|
|
42
|
+
// @ts-expect-error: access private for test
|
|
43
|
+
const deferredBase = manager.deferments.get('x')
|
|
44
|
+
expect(deferredBase).toBeDefined()
|
|
45
|
+
expect(deferredBase?.getId()).toBe('x')
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
test('does not increment for undefer only', () => {
|
|
49
|
+
manager.undefer(makeItem('y'))
|
|
50
|
+
// @ts-expect-error: access private for test
|
|
51
|
+
expect(manager.totalDefermentRequests.get('y')).toBeUndefined()
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -8,6 +8,9 @@ export class DefermentManager {
|
|
|
8
8
|
private logger: CustomLogger
|
|
9
9
|
private currentSize = 0
|
|
10
10
|
private disposed = false
|
|
11
|
+
//tracks total deferment requests for each id
|
|
12
|
+
//this is used to prevent cleaning up deferments that are still being requested
|
|
13
|
+
private totalDefermentRequests: Map<string, number> = new Map()
|
|
11
14
|
|
|
12
15
|
constructor(private options: DefermentManagerOptions) {
|
|
13
16
|
this.resetGlobalTimer()
|
|
@@ -29,6 +32,7 @@ export class DefermentManager {
|
|
|
29
32
|
|
|
30
33
|
async defer(params: { id: string }): Promise<Base> {
|
|
31
34
|
if (this.disposed) throw new Error('DefermentManager is disposed')
|
|
35
|
+
this.trackDefermentRequest(params.id)
|
|
32
36
|
const now = this.now()
|
|
33
37
|
const deferredBase = this.deferments.get(params.id)
|
|
34
38
|
if (deferredBase) {
|
|
@@ -44,6 +48,15 @@ export class DefermentManager {
|
|
|
44
48
|
return notYetFound.getPromise()
|
|
45
49
|
}
|
|
46
50
|
|
|
51
|
+
private trackDefermentRequest(id: string): void {
|
|
52
|
+
const request = this.totalDefermentRequests.get(id)
|
|
53
|
+
if (request) {
|
|
54
|
+
this.totalDefermentRequests.set(id, request + 1)
|
|
55
|
+
} else {
|
|
56
|
+
this.totalDefermentRequests.set(id, 1)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
47
60
|
undefer(item: Item): void {
|
|
48
61
|
if (this.disposed) throw new Error('DefermentManager is disposed')
|
|
49
62
|
const now = this.now()
|
|
@@ -108,6 +121,12 @@ export class DefermentManager {
|
|
|
108
121
|
.filter((x) => x.isExpired(now))
|
|
109
122
|
.sort((a, b) => this.compareMaybeBasesBySize(a.getItem(), b.getItem()))) {
|
|
110
123
|
if (deferredBase.done(now)) {
|
|
124
|
+
//if the deferment is done but has been requested multiple times,
|
|
125
|
+
//we do not clean it up to allow the requests to resolve
|
|
126
|
+
const requestCount = this.totalDefermentRequests.get(deferredBase.getId())
|
|
127
|
+
if (requestCount && requestCount > 1) {
|
|
128
|
+
return
|
|
129
|
+
}
|
|
111
130
|
this.currentSize -= deferredBase.getItem()?.size || 0
|
|
112
131
|
this.deferments.delete(deferredBase.getId())
|
|
113
132
|
cleaned++
|
|
@@ -117,7 +136,7 @@ export class DefermentManager {
|
|
|
117
136
|
}
|
|
118
137
|
}
|
|
119
138
|
this.logger(
|
|
120
|
-
'cleaned deferments
|
|
139
|
+
'cleaned deferments: cleaned, left, time',
|
|
121
140
|
cleaned,
|
|
122
141
|
this.deferments.size,
|
|
123
142
|
performance.now() - start
|
package/src/index.ts
CHANGED
|
@@ -1,31 +1,18 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
-
exports[`
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"
|
|
7
|
-
"
|
|
3
|
+
exports[`IndexedDatabase > should add and get multiple items 1`] = `
|
|
4
|
+
[
|
|
5
|
+
{
|
|
6
|
+
"baseId": "id1",
|
|
7
|
+
"item": {
|
|
8
|
+
"foo": "bar",
|
|
9
|
+
},
|
|
8
10
|
},
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
{
|
|
15
|
-
"base": {
|
|
16
|
-
"id": "id",
|
|
17
|
-
"speckle_type": "type",
|
|
18
|
-
},
|
|
19
|
-
"baseId": "id1",
|
|
20
|
-
}
|
|
21
|
-
`;
|
|
22
|
-
|
|
23
|
-
exports[`database cache > write two items to queue use getItem 2`] = `
|
|
24
|
-
{
|
|
25
|
-
"base": {
|
|
26
|
-
"id": "id",
|
|
27
|
-
"speckle_type": "type",
|
|
11
|
+
{
|
|
12
|
+
"baseId": "id2",
|
|
13
|
+
"item": {
|
|
14
|
+
"foo": "bar",
|
|
15
|
+
},
|
|
28
16
|
},
|
|
29
|
-
|
|
30
|
-
}
|
|
17
|
+
]
|
|
31
18
|
`;
|
|
@@ -1,37 +1,33 @@
|
|
|
1
|
-
import { describe, expect,
|
|
2
|
-
import IndexedDatabase from './indexedDatabase.js'
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
|
3
2
|
import { IDBFactory, IDBKeyRange } from 'fake-indexeddb'
|
|
3
|
+
import IndexedDatabase, { IndexedDatabaseOptions } from './indexedDatabase.js'
|
|
4
4
|
import { Item } from '../../types/types.js'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const i: Item = { baseId: 'id', base: { id: 'id', speckle_type: 'type' } }
|
|
9
|
-
const database = new IndexedDatabase({
|
|
10
|
-
indexedDB: new IDBFactory(),
|
|
11
|
-
keyRange: IDBKeyRange
|
|
12
|
-
})
|
|
13
|
-
await database.add(i)
|
|
14
|
-
await database.disposeAsync()
|
|
6
|
+
// Mock Item
|
|
7
|
+
const defaultItem = (id: string): Item => ({ baseId: id, item: { foo: 'bar' } })
|
|
15
8
|
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
describe('IndexedDatabase', () => {
|
|
10
|
+
let db: IndexedDatabase
|
|
11
|
+
let options: IndexedDatabaseOptions
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
options = { indexedDB: new IDBFactory(), keyRange: IDBKeyRange }
|
|
15
|
+
db = new IndexedDatabase(options)
|
|
18
16
|
})
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const database = new IndexedDatabase({
|
|
24
|
-
indexedDB: new IDBFactory(),
|
|
25
|
-
keyRange: IDBKeyRange
|
|
26
|
-
})
|
|
27
|
-
await database.add(i1)
|
|
28
|
-
await database.add(i2)
|
|
29
|
-
await database.disposeAsync()
|
|
18
|
+
afterEach(async () => {
|
|
19
|
+
await db.disposeAsync()
|
|
20
|
+
})
|
|
30
21
|
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
it('should add and get multiple items', async () => {
|
|
23
|
+
const items = [defaultItem('id1'), defaultItem('id2')]
|
|
24
|
+
await db.cacheSaveBatch({ batch: items })
|
|
25
|
+
const result = await db.getAll(['id1', 'id2'])
|
|
26
|
+
expect(result).toMatchSnapshot()
|
|
27
|
+
expect(result).toEqual(items)
|
|
28
|
+
})
|
|
33
29
|
|
|
34
|
-
|
|
35
|
-
expect(
|
|
30
|
+
it('should dispose without error', async () => {
|
|
31
|
+
await expect(db.disposeAsync()).resolves.not.toThrow()
|
|
36
32
|
})
|
|
37
33
|
})
|
|
@@ -5,7 +5,7 @@ import { isSafari } from '@speckle/shared'
|
|
|
5
5
|
import { Dexie, DexieOptions, Table } from 'dexie'
|
|
6
6
|
import { Database } from '../interfaces.js'
|
|
7
7
|
|
|
8
|
-
class ObjectStore extends Dexie {
|
|
8
|
+
export class ObjectStore extends Dexie {
|
|
9
9
|
static #databaseName: string = 'speckle-cache'
|
|
10
10
|
objects!: Table<Item, string> // Table type: <entity, primaryKey>
|
|
11
11
|
|
|
@@ -83,30 +83,6 @@ export default class IndexedDatabase implements Database {
|
|
|
83
83
|
this.#cacheDB = await this.#openDatabase()
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
//this is for testing only - in the real world we will not use this
|
|
87
|
-
async add(item: Item): Promise<void> {
|
|
88
|
-
await this.#setupCacheDb()
|
|
89
|
-
await this.#cacheDB!.transaction('rw', this.#cacheDB!.objects, async () => {
|
|
90
|
-
return await this.#cacheDB?.objects.add(item)
|
|
91
|
-
})
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
async getItem(params: { id: string }): Promise<Item | undefined> {
|
|
95
|
-
const { id } = params
|
|
96
|
-
await this.#setupCacheDb()
|
|
97
|
-
//might not be in the real DB yet, so check the write queue first
|
|
98
|
-
if (this.#writeQueue) {
|
|
99
|
-
const item = this.#writeQueue.get(id)
|
|
100
|
-
if (item) {
|
|
101
|
-
return item
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return this.#cacheDB!.transaction('r', this.#cacheDB!.objects, async () => {
|
|
106
|
-
return await this.#cacheDB?.objects.get(id)
|
|
107
|
-
})
|
|
108
|
-
}
|
|
109
|
-
|
|
110
86
|
async cacheSaveBatch(params: { batch: Item[] }): Promise<void> {
|
|
111
87
|
await this.#setupCacheDb()
|
|
112
88
|
const { batch } = params
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest'
|
|
2
|
+
import { MemoryDatabase } from './memoryDatabase.js'
|
|
3
|
+
import { Base, Item } from '../../types/types.js'
|
|
4
|
+
|
|
5
|
+
const makeItem = (id: string, foo = 'bar'): Item => ({
|
|
6
|
+
baseId: id,
|
|
7
|
+
base: { foo } as unknown as Base
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
describe('MemoryDatabase', () => {
|
|
11
|
+
let db: MemoryDatabase
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
db = new MemoryDatabase()
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('should return undefined for missing keys', async () => {
|
|
18
|
+
const result = await db.getAll(['missing'])
|
|
19
|
+
expect(result).toEqual([undefined])
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('should add and retrieve a single item', async () => {
|
|
23
|
+
const item = makeItem('id1')
|
|
24
|
+
await db.cacheSaveBatch({ batch: [item] })
|
|
25
|
+
const result = await db.getAll(['id1'])
|
|
26
|
+
expect(result).toEqual([item])
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('should add and retrieve multiple items', async () => {
|
|
30
|
+
const items = [makeItem('id1'), makeItem('id2', 'baz')]
|
|
31
|
+
await db.cacheSaveBatch({ batch: items })
|
|
32
|
+
const result = await db.getAll(['id1', 'id2'])
|
|
33
|
+
expect(result).toEqual(items)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('should overwrite items with the same key', async () => {
|
|
37
|
+
const item1 = makeItem('id1', 'foo')
|
|
38
|
+
const item2 = makeItem('id1', 'bar')
|
|
39
|
+
await db.cacheSaveBatch({ batch: [item1] })
|
|
40
|
+
await db.cacheSaveBatch({ batch: [item2] })
|
|
41
|
+
const result = await db.getAll(['id1'])
|
|
42
|
+
expect(result).toEqual([item2])
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('disposeAsync should resolve', async () => {
|
|
46
|
+
await expect(db.disposeAsync()).resolves.not.toThrow()
|
|
47
|
+
})
|
|
48
|
+
})
|
|
@@ -29,14 +29,6 @@ export class MemoryDatabase implements Database {
|
|
|
29
29
|
return Promise.resolve()
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
getItem(params: { id: string }): Promise<Item | undefined> {
|
|
33
|
-
const item = this.items.get(params.id)
|
|
34
|
-
if (item) {
|
|
35
|
-
return Promise.resolve({ baseId: params.id, base: item })
|
|
36
|
-
}
|
|
37
|
-
return Promise.resolve(undefined)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
32
|
disposeAsync(): Promise<void> {
|
|
41
33
|
return Promise.resolve()
|
|
42
34
|
}
|