@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.
Files changed (92) hide show
  1. package/dist/commonjs/core/interfaces.d.ts +4 -6
  2. package/dist/commonjs/core/interfaces.d.ts.map +1 -1
  3. package/dist/commonjs/core/objectLoader2.js +2 -2
  4. package/dist/commonjs/core/objectLoader2.js.map +1 -1
  5. package/dist/commonjs/core/objectLoader2Factory.d.ts.map +1 -1
  6. package/dist/commonjs/core/objectLoader2Factory.js +4 -3
  7. package/dist/commonjs/core/objectLoader2Factory.js.map +1 -1
  8. package/dist/commonjs/core/stages/cacheWriter.js +1 -1
  9. package/dist/commonjs/core/stages/cacheWriter.js.map +1 -1
  10. package/dist/commonjs/core/stages/indexedDatabase.d.ts +20 -6
  11. package/dist/commonjs/core/stages/indexedDatabase.d.ts.map +1 -1
  12. package/dist/commonjs/core/stages/indexedDatabase.js +138 -19
  13. package/dist/commonjs/core/stages/indexedDatabase.js.map +1 -1
  14. package/dist/commonjs/core/stages/memory/memoryDatabase.d.ts +2 -4
  15. package/dist/commonjs/core/stages/memory/memoryDatabase.d.ts.map +1 -1
  16. package/dist/commonjs/core/stages/memory/memoryDatabase.js +3 -3
  17. package/dist/commonjs/core/stages/memory/memoryDatabase.js.map +1 -1
  18. package/dist/commonjs/core/stages/memory/memoryDownloader.d.ts +1 -1
  19. package/dist/commonjs/core/stages/memory/memoryDownloader.d.ts.map +1 -1
  20. package/dist/commonjs/core/stages/memory/memoryDownloader.js +1 -1
  21. package/dist/commonjs/core/stages/memory/memoryDownloader.js.map +1 -1
  22. package/dist/commonjs/core/stages/serverDownloader.d.ts +3 -2
  23. package/dist/commonjs/core/stages/serverDownloader.d.ts.map +1 -1
  24. package/dist/commonjs/core/stages/serverDownloader.js +12 -19
  25. package/dist/commonjs/core/stages/serverDownloader.js.map +1 -1
  26. package/dist/commonjs/queues/keyedQueue.test.d.ts +2 -0
  27. package/dist/commonjs/queues/keyedQueue.test.d.ts.map +1 -0
  28. package/dist/commonjs/queues/keyedQueue.test.js +118 -0
  29. package/dist/commonjs/queues/keyedQueue.test.js.map +1 -0
  30. package/dist/esm/core/interfaces.d.ts +4 -6
  31. package/dist/esm/core/interfaces.d.ts.map +1 -1
  32. package/dist/esm/core/objectLoader2.js +2 -2
  33. package/dist/esm/core/objectLoader2.js.map +1 -1
  34. package/dist/esm/core/objectLoader2Factory.d.ts.map +1 -1
  35. package/dist/esm/core/objectLoader2Factory.js +3 -2
  36. package/dist/esm/core/objectLoader2Factory.js.map +1 -1
  37. package/dist/esm/core/stages/cacheWriter.js +1 -1
  38. package/dist/esm/core/stages/cacheWriter.js.map +1 -1
  39. package/dist/esm/core/stages/indexedDatabase.d.ts +20 -6
  40. package/dist/esm/core/stages/indexedDatabase.d.ts.map +1 -1
  41. package/dist/esm/core/stages/indexedDatabase.js +140 -22
  42. package/dist/esm/core/stages/indexedDatabase.js.map +1 -1
  43. package/dist/esm/core/stages/memory/memoryDatabase.d.ts +2 -4
  44. package/dist/esm/core/stages/memory/memoryDatabase.d.ts.map +1 -1
  45. package/dist/esm/core/stages/memory/memoryDatabase.js +3 -3
  46. package/dist/esm/core/stages/memory/memoryDatabase.js.map +1 -1
  47. package/dist/esm/core/stages/memory/memoryDownloader.d.ts +1 -1
  48. package/dist/esm/core/stages/memory/memoryDownloader.d.ts.map +1 -1
  49. package/dist/esm/core/stages/memory/memoryDownloader.js +1 -1
  50. package/dist/esm/core/stages/memory/memoryDownloader.js.map +1 -1
  51. package/dist/esm/core/stages/serverDownloader.d.ts +3 -2
  52. package/dist/esm/core/stages/serverDownloader.d.ts.map +1 -1
  53. package/dist/esm/core/stages/serverDownloader.js +12 -19
  54. package/dist/esm/core/stages/serverDownloader.js.map +1 -1
  55. package/dist/esm/queues/keyedQueue.test.d.ts +2 -0
  56. package/dist/esm/queues/keyedQueue.test.d.ts.map +1 -0
  57. package/dist/esm/queues/keyedQueue.test.js +113 -0
  58. package/dist/esm/queues/keyedQueue.test.js.map +1 -0
  59. package/package.json +2 -2
  60. package/src/core/interfaces.ts +4 -4
  61. package/src/core/objectLoader2.spec.ts +1 -1
  62. package/src/core/objectLoader2.ts +2 -2
  63. package/src/core/objectLoader2Factory.ts +3 -2
  64. package/src/core/stages/cacheWriter.spec.ts +4 -4
  65. package/src/core/stages/cacheWriter.ts +1 -1
  66. package/src/core/stages/indexedDatabase.spec.ts +6 -6
  67. package/src/core/stages/indexedDatabase.ts +154 -25
  68. package/src/core/stages/memory/memoryDatabase.spec.ts +6 -6
  69. package/src/core/stages/memory/memoryDatabase.ts +3 -3
  70. package/src/core/stages/memory/memoryDownloader.spec.ts +2 -2
  71. package/src/core/stages/memory/memoryDownloader.ts +1 -1
  72. package/src/core/stages/serverDownloader.spec.ts +20 -12
  73. package/src/core/stages/serverDownloader.ts +18 -24
  74. package/src/queues/keyedQueue.test.ts +146 -0
  75. package/dist/commonjs/core/stages/ItemStore.d.ts +0 -37
  76. package/dist/commonjs/core/stages/ItemStore.d.ts.map +0 -1
  77. package/dist/commonjs/core/stages/ItemStore.js +0 -167
  78. package/dist/commonjs/core/stages/ItemStore.js.map +0 -1
  79. package/dist/commonjs/queues/batchedPool.d.ts +0 -13
  80. package/dist/commonjs/queues/batchedPool.d.ts.map +0 -1
  81. package/dist/commonjs/queues/batchedPool.js +0 -45
  82. package/dist/commonjs/queues/batchedPool.js.map +0 -1
  83. package/dist/esm/core/stages/ItemStore.d.ts +0 -37
  84. package/dist/esm/core/stages/ItemStore.d.ts.map +0 -1
  85. package/dist/esm/core/stages/ItemStore.js +0 -163
  86. package/dist/esm/core/stages/ItemStore.js.map +0 -1
  87. package/dist/esm/queues/batchedPool.d.ts +0 -13
  88. package/dist/esm/queues/batchedPool.d.ts.map +0 -1
  89. package/dist/esm/queues/batchedPool.js +0 -42
  90. package/dist/esm/queues/batchedPool.js.map +0 -1
  91. package/src/core/stages/ItemStore.ts +0 -196
  92. package/src/queues/batchedPool.ts +0 -58
@@ -1,4 +1,4 @@
1
- import BatchedPool from '../../queues/batchedPool.js';
1
+ import BatchingQueue from '../../queues/batchingQueue.js';
2
2
  import { ObjectLoaderRuntimeError } from '../../types/errors.js';
3
3
  import { indexOf, isBase, take } from '../../types/functions.js';
4
4
  const MAX_SAFARI_DECODE_BYTES = 2 * 1024 * 1024 * 1024 - 1024 * 1024; // 2GB minus a margin
@@ -10,6 +10,7 @@ export default class ServerDownloader {
10
10
  #fetch;
11
11
  #results;
12
12
  #total;
13
+ #logger;
13
14
  #downloadQueue;
14
15
  #decoder = new TextDecoder('utf-8', { fatal: true });
15
16
  #decodedBytesCount = 0;
@@ -17,6 +18,7 @@ export default class ServerDownloader {
17
18
  #rawEncoding;
18
19
  constructor(options) {
19
20
  this.#options = options;
21
+ this.#logger = options.logger;
20
22
  this.#fetch =
21
23
  options.fetch ?? ((...args) => globalThis.fetch(...args));
22
24
  this.#headers = {};
@@ -34,19 +36,13 @@ export default class ServerDownloader {
34
36
  const encoder = new TextEncoder();
35
37
  this.#rawEncoding = encoder.encode(this.#rawString);
36
38
  }
37
- #getDownloadCountAndSizes(total) {
38
- if (total <= 50) {
39
- return [total];
40
- }
41
- return [10000, 25000, 10000, 1000];
42
- }
43
- initializePool(params) {
44
- const { results, total } = params;
39
+ initialize(params) {
40
+ const { results, total, maxDownloadBatchWait } = params;
45
41
  this.#results = results;
46
42
  this.#total = total;
47
- this.#downloadQueue = new BatchedPool({
48
- concurrencyAndSizes: this.#getDownloadCountAndSizes(total),
49
- maxWaitTime: params.maxDownloadBatchWait,
43
+ this.#downloadQueue = new BatchingQueue({
44
+ batchSize: 15000, // 15k is a good number for most cases
45
+ maxWaitTime: maxDownloadBatchWait ?? 1000, // 1 second
50
46
  processFunction: (batch) => this.downloadBatch({
51
47
  batch,
52
48
  url: this.#requestUrlChildren,
@@ -54,14 +50,8 @@ export default class ServerDownloader {
54
50
  })
55
51
  });
56
52
  }
57
- #getPool() {
58
- if (this.#downloadQueue) {
59
- return this.#downloadQueue;
60
- }
61
- throw new Error('Download pool is not initialized');
62
- }
63
53
  add(id) {
64
- this.#getPool().add(id);
54
+ this.#downloadQueue?.add(id, id);
65
55
  }
66
56
  /*
67
57
  This is the most frequently reported and confirmed reason for this error in Safari. There's a known bug in WebKit (Safari's rendering engine) where TextDecoder can fail or throw a RangeError after decoding around 2GB of data. Chrome and other browsers handle much larger amounts of data without this specific limitation.
@@ -85,6 +75,8 @@ export default class ServerDownloader {
85
75
  }
86
76
  async downloadBatch(params) {
87
77
  const { batch, url, headers } = params;
78
+ const start = performance.now();
79
+ this.#logger(`Downloading batch of ${batch.length} items...`);
88
80
  const keys = new Set(batch);
89
81
  const response = await this.#fetch(url, {
90
82
  method: 'POST',
@@ -116,6 +108,7 @@ export default class ServerDownloader {
116
108
  if (count >= this.#total) {
117
109
  await this.#results?.disposeAsync(); // mark the queue as done
118
110
  }
111
+ this.#logger(`Downloaded batch of ${batch.length} items in ${performance.now() - start}ms`);
119
112
  }
120
113
  async #processArray(leftover, value, keys, callback) {
121
114
  //this concat will allocate a new array
@@ -1 +1 @@
1
- {"version":3,"file":"serverDownloader.js","sourceRoot":"","sources":["../../../../src/core/stages/serverDownloader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serverDownloader.js","sourceRoot":"","sources":["../../../../src/core/stages/serverDownloader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=keyedQueue.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyedQueue.test.d.ts","sourceRoot":"","sources":["../../../src/queues/keyedQueue.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,113 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import KeyedQueue from './keyedQueue.js';
3
+ describe('KeyedQueue', () => {
4
+ let queue;
5
+ beforeEach(() => {
6
+ queue = new KeyedQueue();
7
+ });
8
+ describe('enqueue', () => {
9
+ it('should add a key-value pair to the queue', () => {
10
+ const result = queue.enqueue('key1', 1);
11
+ expect(result).toBe(true);
12
+ expect(queue.size).toBe(1);
13
+ expect(queue.get('key1')).toBe(1);
14
+ });
15
+ it('should return false when trying to add a key that already exists', () => {
16
+ queue.enqueue('key1', 1);
17
+ const result = queue.enqueue('key1', 2);
18
+ expect(result).toBe(false);
19
+ expect(queue.size).toBe(1);
20
+ expect(queue.get('key1')).toBe(1); // Value should not be updated
21
+ });
22
+ });
23
+ describe('enqueueAll', () => {
24
+ it('should add multiple key-value pairs to the queue', () => {
25
+ const keys = ['key1', 'key2', 'key3'];
26
+ const values = [1, 2, 3];
27
+ const count = queue.enqueueAll(keys, values);
28
+ expect(count).toBe(3);
29
+ expect(queue.size).toBe(3);
30
+ expect(queue.get('key1')).toBe(1);
31
+ expect(queue.get('key2')).toBe(2);
32
+ expect(queue.get('key3')).toBe(3);
33
+ });
34
+ it('should skip keys that already exist and return the count of added items', () => {
35
+ queue.enqueue('key1', 1);
36
+ const keys = ['key1', 'key2', 'key3'];
37
+ const values = [10, 2, 3];
38
+ const count = queue.enqueueAll(keys, values);
39
+ expect(count).toBe(2);
40
+ expect(queue.size).toBe(3);
41
+ expect(queue.get('key1')).toBe(1); // Original value preserved
42
+ expect(queue.get('key2')).toBe(2);
43
+ expect(queue.get('key3')).toBe(3);
44
+ });
45
+ });
46
+ describe('get', () => {
47
+ it('should return the value for a given key', () => {
48
+ queue.enqueue('key1', 1);
49
+ expect(queue.get('key1')).toBe(1);
50
+ });
51
+ it('should return undefined for a non-existent key', () => {
52
+ expect(queue.get('nonexistent')).toBeUndefined();
53
+ });
54
+ });
55
+ describe('has', () => {
56
+ it('should return true if the key exists', () => {
57
+ queue.enqueue('key1', 1);
58
+ expect(queue.has('key1')).toBe(true);
59
+ });
60
+ it('should return false if the key does not exist', () => {
61
+ expect(queue.has('nonexistent')).toBe(false);
62
+ });
63
+ });
64
+ describe('size', () => {
65
+ it('should return the number of items in the queue', () => {
66
+ expect(queue.size).toBe(0);
67
+ queue.enqueue('key1', 1);
68
+ expect(queue.size).toBe(1);
69
+ queue.enqueue('key2', 2);
70
+ expect(queue.size).toBe(2);
71
+ });
72
+ });
73
+ describe('spliceValues', () => {
74
+ it('should remove and return values from the queue', () => {
75
+ queue.enqueue('key1', 1);
76
+ queue.enqueue('key2', 2);
77
+ queue.enqueue('key3', 3);
78
+ queue.enqueue('key4', 4);
79
+ const result = queue.spliceValues(1, 2);
80
+ expect(result).toEqual([2, 3]);
81
+ expect(queue.size).toBe(2);
82
+ expect(queue.has('key1')).toBe(true);
83
+ expect(queue.has('key2')).toBe(false);
84
+ expect(queue.has('key3')).toBe(false);
85
+ expect(queue.has('key4')).toBe(true);
86
+ });
87
+ it('should handle splicing at the beginning of the queue', () => {
88
+ queue.enqueue('key1', 1);
89
+ queue.enqueue('key2', 2);
90
+ const result = queue.spliceValues(0, 1);
91
+ expect(result).toEqual([1]);
92
+ expect(queue.size).toBe(1);
93
+ expect(queue.has('key1')).toBe(false);
94
+ expect(queue.has('key2')).toBe(true);
95
+ });
96
+ it('should handle splicing at the end of the queue', () => {
97
+ queue.enqueue('key1', 1);
98
+ queue.enqueue('key2', 2);
99
+ const result = queue.spliceValues(1, 1);
100
+ expect(result).toEqual([2]);
101
+ expect(queue.size).toBe(1);
102
+ expect(queue.has('key1')).toBe(true);
103
+ expect(queue.has('key2')).toBe(false);
104
+ });
105
+ it('should return an empty array when deleting zero elements', () => {
106
+ queue.enqueue('key1', 1);
107
+ const result = queue.spliceValues(0, 0);
108
+ expect(result).toEqual([]);
109
+ expect(queue.size).toBe(1);
110
+ });
111
+ });
112
+ });
113
+ //# sourceMappingURL=keyedQueue.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyedQueue.test.js","sourceRoot":"","sources":["../../../src/queues/keyedQueue.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@speckle/objectloader2",
3
- "version": "2.25.9",
3
+ "version": "2.26.0",
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.9"
36
+ "@speckle/shared": "^2.26.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/lodash": "^4.17.5",
@@ -2,7 +2,7 @@ import Queue from '../queues/queue.js'
2
2
  import { Item } from '../types/types.js'
3
3
 
4
4
  export interface Downloader extends Queue<string> {
5
- initializePool(params: {
5
+ initialize(params: {
6
6
  results: Queue<Item>
7
7
  total: number
8
8
  maxDownloadBatchWait?: number
@@ -12,7 +12,7 @@ export interface Downloader extends Queue<string> {
12
12
  }
13
13
 
14
14
  export interface Database {
15
- getAll(keys: string[]): Promise<(Item | undefined)[]>
16
- saveBatch(params: { batch: Item[] }): Promise<void>
17
- disposeAsync(): Promise<void>
15
+ getAll(ids: string[]): Promise<(Item | undefined)[]>
16
+ putAll(batch: Item[]): Promise<void>
17
+ dispose(): void
18
18
  }
@@ -1,7 +1,7 @@
1
1
  import { describe, test, expect } from 'vitest'
2
2
  import { Base, Item } from '../types/types.js'
3
3
  import { ObjectLoader2 } from './objectLoader2.js'
4
- import IndexedDatabase from './stages/indexedDatabase.js'
4
+ import { IndexedDatabase } from './stages/indexedDatabase.js'
5
5
  import { IDBFactory, IDBKeyRange } from 'fake-indexeddb'
6
6
  import { MemoryDatabase } from './stages/memory/memoryDatabase.js'
7
7
  import { MemoryDownloader } from './stages/memory/memoryDownloader.js'
@@ -131,7 +131,7 @@ export class ObjectLoader2 {
131
131
  )
132
132
  const children = sortedClosures.map((x) => x[0])
133
133
  const total = children.length + 1 // +1 for the root object
134
- this.#downloader.initializePool({
134
+ this.#downloader.initialize({
135
135
  results: new AggregateQueue(this.#gathered, this.#cacheWriter),
136
136
  total
137
137
  })
@@ -147,7 +147,7 @@ export class ObjectLoader2 {
147
147
  }
148
148
  }
149
149
  if (!this.#isRootStored) {
150
- await this.#database.saveBatch({ batch: [rootItem] })
150
+ await this.#database.putAll([rootItem])
151
151
  this.#isRootStored = true
152
152
  }
153
153
  }
@@ -1,7 +1,7 @@
1
1
  import { CustomLogger, getFeatureFlag, ObjectLoader2Flags } from '../types/functions.js'
2
2
  import { Base } from '../types/types.js'
3
3
  import { ObjectLoader2 } from './objectLoader2.js'
4
- import IndexedDatabase from './stages/indexedDatabase.js'
4
+ import { IndexedDatabase } from './stages/indexedDatabase.js'
5
5
  import { MemoryDatabase } from './stages/memory/memoryDatabase.js'
6
6
  import { MemoryDownloader } from './stages/memory/memoryDownloader.js'
7
7
  import ServerDownloader from './stages/serverDownloader.js'
@@ -66,7 +66,8 @@ export class ObjectLoader2Factory {
66
66
  streamId: params.streamId,
67
67
  objectId: params.objectId,
68
68
  token: params.token,
69
- headers: params.headers
69
+ headers: params.headers,
70
+ logger: log || ((): void => {})
70
71
  }),
71
72
  database,
72
73
  logger: log
@@ -15,13 +15,13 @@ class MockDatabase implements Database {
15
15
  return Promise.resolve([])
16
16
  }
17
17
 
18
- saveBatch({ batch }: { batch: Item[] }): Promise<void> {
18
+ putAll(batch: Item[]): Promise<void> {
19
19
  this.savedItems.push(...batch)
20
20
  return Promise.resolve()
21
21
  }
22
22
 
23
- disposeAsync(): Promise<void> {
24
- return Promise.resolve()
23
+ dispose(): void {
24
+ this.savedItems = []
25
25
  }
26
26
  }
27
27
 
@@ -150,7 +150,7 @@ describe('CacheWriter', () => {
150
150
  })
151
151
 
152
152
  it('should process items in batches according to maxCacheWriteSize', async () => {
153
- const spy = vi.spyOn(database, 'saveBatch')
153
+ const spy = vi.spyOn(database, 'putAll')
154
154
  const smallBatchOptions: CacheOptions = {
155
155
  ...options,
156
156
  maxCacheWriteSize: 2, // Set small batch size
@@ -45,7 +45,7 @@ export class CacheWriter implements Queue<Item> {
45
45
 
46
46
  async writeAll(items: Item[]): Promise<void> {
47
47
  const start = performance.now()
48
- await this.#database.saveBatch({ batch: items })
48
+ await this.#database.putAll(items)
49
49
  this.#logger(
50
50
  `writeBatch: wrote ${items.length}, time ${
51
51
  performance.now() - start
@@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest'
2
2
  import { IDBFactory, IDBKeyRange } from 'fake-indexeddb'
3
3
 
4
4
  import { Base, Item } from '../../types/types.js'
5
- import IndexedDatabase, { IndexedDatabaseOptions } from './indexedDatabase.js'
5
+ import { IndexedDatabase, IndexedDatabaseOptions } from './indexedDatabase.js'
6
6
 
7
7
  // Mock Item
8
8
  const defaultItem = (id: string): Item => ({
@@ -19,19 +19,19 @@ describe('IndexedDatabase', () => {
19
19
  db = new IndexedDatabase(options)
20
20
  })
21
21
 
22
- afterEach(async () => {
23
- await db.disposeAsync()
22
+ afterEach(() => {
23
+ db.dispose()
24
24
  })
25
25
 
26
26
  it('should add and get multiple items', async () => {
27
27
  const items = [defaultItem('id1'), defaultItem('id2')]
28
- await db.saveBatch({ batch: items })
28
+ await db.putAll(items)
29
29
  const result = await db.getAll(['id1', 'id2'])
30
30
  expect(result).toMatchSnapshot()
31
31
  expect(result).toEqual(items)
32
32
  })
33
33
 
34
- it('should dispose without error', async () => {
35
- await expect(db.disposeAsync()).resolves.not.toThrow()
34
+ it('should dispose without error', () => {
35
+ expect(() => db.dispose()).not.toThrow()
36
36
  })
37
37
  })
@@ -1,9 +1,14 @@
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 */
1
4
  /* eslint-disable @typescript-eslint/no-unsafe-function-type */
5
+ import { isSafari } from '@speckle/shared'
2
6
  import { Item } from '../../types/types.js'
3
7
  import { Database } from '../interfaces.js'
4
- import BatchingQueue from '../../queues/batchingQueue.js'
5
- import { ItemStore } from './ItemStore.js'
6
8
 
9
+ /**
10
+ * A wrapper class for IndexedDB to simplify common database operations.
11
+ */
7
12
  export interface IndexedDatabaseOptions {
8
13
  indexedDB?: IDBFactory
9
14
  keyRange?: {
@@ -12,38 +17,162 @@ export interface IndexedDatabaseOptions {
12
17
  upperBound: Function
13
18
  }
14
19
  }
15
-
16
- export default class IndexedDatabase implements Database {
20
+ export class IndexedDatabase implements Database {
17
21
  #options: IndexedDatabaseOptions
18
- #cacheDB: ItemStore
19
- #writeQueue: BatchingQueue<Item> | undefined
22
+
23
+ #db: IDBDatabase | undefined = undefined
24
+ readonly #dbName: string = 'speckle-cache'
25
+ readonly #storeName: string = 'cache'
20
26
 
21
27
  constructor(options: IndexedDatabaseOptions) {
22
28
  this.#options = options
23
- this.#cacheDB = new ItemStore(
24
- {
25
- indexedDB: this.#options.indexedDB,
26
- keyRange: this.#options.keyRange
27
- },
28
- 'speckle-cache',
29
- 'cache'
30
- )
31
29
  }
32
30
 
33
- async getAll(keys: string[]): Promise<(Item | undefined)[]> {
34
- await this.#cacheDB.init()
35
- return await this.#cacheDB.bulkGet(keys)
31
+ /**
32
+ * Initializes the database connection and creates the object store if needed.
33
+ * This must be called before any other database operations.
34
+ */
35
+ async init(): Promise<void> {
36
+ if (this.#db) return
37
+ await this.#safariFix()
38
+ return this.#openDatabase()
39
+ }
40
+
41
+ /**
42
+ * Opens the database, and if there's an error, deletes the database and tries again.
43
+ */
44
+ async #openDatabase(): Promise<void> {
45
+ const idb = this.#options.indexedDB ?? indexedDB
46
+
47
+ return new Promise((resolve, reject) => {
48
+ const request = idb.open(this.#dbName, 1)
49
+
50
+ request.onerror = (): any => {
51
+ console.warn(
52
+ `Failed to open database: ${this.#dbName}, deleting and trying again`
53
+ )
54
+ // Delete the database and try again
55
+ const deleteRequest = idb.deleteDatabase(this.#dbName)
56
+ deleteRequest.onsuccess = (): any => {
57
+ // Try opening again after deletion
58
+ void this.#openDatabase().then(resolve).catch(reject)
59
+ }
60
+ deleteRequest.onerror = (): any => {
61
+ reject(`Failed to delete and reopen database: ${this.#dbName}`)
62
+ }
63
+ }
64
+
65
+ request.onupgradeneeded = (event): any => {
66
+ const db = (event.target as IDBOpenDBRequest).result
67
+ if (db.objectStoreNames.contains(this.#storeName)) {
68
+ db.deleteObjectStore(this.#storeName)
69
+ }
70
+ db.createObjectStore(this.#storeName, { keyPath: 'baseId' })
71
+ }
72
+
73
+ request.onsuccess = (event): any => {
74
+ this.#db = (event.target as IDBOpenDBRequest).result
75
+ resolve()
76
+ }
77
+ })
36
78
  }
37
79
 
38
- async saveBatch(params: { batch: Item[] }): Promise<void> {
39
- await this.#cacheDB.init()
40
- const { batch } = params
41
- await this.#cacheDB.bulkInsert(batch)
80
+ #getDB(): IDBDatabase {
81
+ if (!this.#db) {
82
+ throw new Error('Database not initialized. Call init() first.')
83
+ }
84
+ return this.#db
42
85
  }
43
86
 
44
- async disposeAsync(): Promise<void> {
45
- await this.#writeQueue?.disposeAsync()
46
- this.#writeQueue = undefined
47
- this.#cacheDB.close()
87
+ /**
88
+ * Fixes a Safari bug where IndexedDB requests get lost and never resolve - invoke before you use IndexedDB
89
+ * @link Credits and more info: https://github.com/jakearchibald/safari-14-idb-fix
90
+ */
91
+ async #safariFix(): Promise<void> {
92
+ // No point putting other browsers or older versions of Safari through this mess.
93
+ if (!isSafari() || !this.#options.indexedDB?.databases) return Promise.resolve()
94
+
95
+ let intervalId: ReturnType<typeof setInterval>
96
+
97
+ return new Promise<void>((resolve: () => void) => {
98
+ const tryIdb = (): Promise<IDBDatabaseInfo[]> | undefined =>
99
+ this.#options.indexedDB?.databases().finally(resolve)
100
+ intervalId = setInterval(() => {
101
+ void tryIdb()
102
+ }, 100)
103
+ void tryIdb()
104
+ }).finally(() => clearInterval(intervalId))
105
+ }
106
+
107
+ /**
108
+ * Inserts or updates an array of items in a single transaction.
109
+ * @param data The array of items to insert.
110
+ */
111
+ async putAll(data: Item[]): Promise<void> {
112
+ await this.init() // Ensure the database is initialized
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
+ async getAll(ids: string[]): Promise<(Item | undefined)[]> {
139
+ await this.init() // Ensure the database is initialized
140
+ return new Promise((resolve, reject) => {
141
+ if (ids.length === 0) {
142
+ return resolve([])
143
+ }
144
+ try {
145
+ const transaction = this.#getDB().transaction(this.#storeName, 'readonly', {
146
+ durability: 'relaxed'
147
+ })
148
+ const store = transaction.objectStore(this.#storeName)
149
+ const promises: Promise<Item | undefined>[] = []
150
+
151
+ for (const id of ids) {
152
+ promises.push(
153
+ new Promise((resolveGet, rejectGet) => {
154
+ const request = store.get(id)
155
+ request.onerror = (): void =>
156
+ rejectGet(`Request error for id ${id}: ${request.error}`)
157
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
158
+ request.onsuccess = (): void => resolveGet(request.result)
159
+ })
160
+ )
161
+ }
162
+
163
+ Promise.all(promises)
164
+ .then((results) => {
165
+ resolve(results)
166
+ })
167
+ .catch(reject)
168
+ } catch (error) {
169
+ reject(error)
170
+ }
171
+ })
172
+ }
173
+ dispose(): void {
174
+ if (!this.#db) return
175
+ this.#db.close()
176
+ this.#db = undefined
48
177
  }
49
178
  }
@@ -21,14 +21,14 @@ describe('MemoryDatabase', () => {
21
21
 
22
22
  it('should add and retrieve a single item', async () => {
23
23
  const item = makeItem('id1')
24
- await db.saveBatch({ batch: [item] })
24
+ await db.putAll([item])
25
25
  const result = await db.getAll(['id1'])
26
26
  expect(result).toEqual([item])
27
27
  })
28
28
 
29
29
  it('should add and retrieve multiple items', async () => {
30
30
  const items = [makeItem('id1'), makeItem('id2', 'baz')]
31
- await db.saveBatch({ batch: items })
31
+ await db.putAll(items)
32
32
  const result = await db.getAll(['id1', 'id2'])
33
33
  expect(result).toEqual(items)
34
34
  })
@@ -36,13 +36,13 @@ describe('MemoryDatabase', () => {
36
36
  it('should overwrite items with the same key', async () => {
37
37
  const item1 = makeItem('id1', 'foo')
38
38
  const item2 = makeItem('id1', 'bar')
39
- await db.saveBatch({ batch: [item1] })
40
- await db.saveBatch({ batch: [item2] })
39
+ await db.putAll([item1])
40
+ await db.putAll([item2])
41
41
  const result = await db.getAll(['id1'])
42
42
  expect(result).toEqual([item2])
43
43
  })
44
44
 
45
- it('disposeAsync should resolve', async () => {
46
- await expect(db.disposeAsync()).resolves.not.toThrow()
45
+ it('dispose should not throw', () => {
46
+ db.dispose()
47
47
  })
48
48
  })