@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
|
@@ -22,7 +22,7 @@ export class MemoryDatabase implements Database {
|
|
|
22
22
|
return Promise.resolve(found)
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
putAll(batch: Item[]): Promise<void> {
|
|
26
26
|
for (const item of batch) {
|
|
27
27
|
if (!item.baseId || !item.base) {
|
|
28
28
|
throw new Error('Item must have a baseId and base')
|
|
@@ -32,7 +32,7 @@ export class MemoryDatabase implements Database {
|
|
|
32
32
|
return Promise.resolve()
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
dispose(): void {
|
|
36
|
+
this.items.clear()
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -33,13 +33,13 @@ describe('MemoryDownloader', () => {
|
|
|
33
33
|
})
|
|
34
34
|
|
|
35
35
|
it('should add found item to results queue', () => {
|
|
36
|
-
downloader.
|
|
36
|
+
downloader.initialize({ results, total: 2 })
|
|
37
37
|
downloader.add('id2')
|
|
38
38
|
expect(items).toMatchSnapshot()
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
it('should throw if added item is missing', () => {
|
|
42
|
-
downloader.
|
|
42
|
+
downloader.initialize({ results, total: 2 })
|
|
43
43
|
expect(() => downloader.add('missing')).toThrow()
|
|
44
44
|
})
|
|
45
45
|
|
|
@@ -16,9 +16,10 @@ describe('downloader', () => {
|
|
|
16
16
|
streamId: 'streamId',
|
|
17
17
|
objectId: 'objectId',
|
|
18
18
|
token: 'token',
|
|
19
|
-
fetch: fetchMocker
|
|
19
|
+
fetch: fetchMocker,
|
|
20
|
+
logger: (): void => {}
|
|
20
21
|
})
|
|
21
|
-
downloader.
|
|
22
|
+
downloader.initialize({
|
|
22
23
|
results: gathered,
|
|
23
24
|
total: 1,
|
|
24
25
|
maxDownloadBatchWait: 200
|
|
@@ -51,9 +52,10 @@ describe('downloader', () => {
|
|
|
51
52
|
objectId: 'objectId',
|
|
52
53
|
token: 'token',
|
|
53
54
|
|
|
54
|
-
fetch: fetchMocker
|
|
55
|
+
fetch: fetchMocker,
|
|
56
|
+
logger: (): void => {}
|
|
55
57
|
})
|
|
56
|
-
downloader.
|
|
58
|
+
downloader.initialize({
|
|
57
59
|
results: gathered,
|
|
58
60
|
total: 2,
|
|
59
61
|
maxDownloadBatchWait: 200
|
|
@@ -95,9 +97,10 @@ describe('downloader', () => {
|
|
|
95
97
|
objectId: 'objectId',
|
|
96
98
|
token: 'token',
|
|
97
99
|
|
|
98
|
-
fetch: fetchMocker
|
|
100
|
+
fetch: fetchMocker,
|
|
101
|
+
logger: (): void => {}
|
|
99
102
|
})
|
|
100
|
-
downloader.
|
|
103
|
+
downloader.initialize({
|
|
101
104
|
results: gathered,
|
|
102
105
|
total: 3,
|
|
103
106
|
maxDownloadBatchWait: 200
|
|
@@ -143,9 +146,10 @@ describe('downloader', () => {
|
|
|
143
146
|
objectId: 'objectId',
|
|
144
147
|
token: 'token',
|
|
145
148
|
|
|
146
|
-
fetch: fetchMocker
|
|
149
|
+
fetch: fetchMocker,
|
|
150
|
+
logger: (): void => {}
|
|
147
151
|
})
|
|
148
|
-
downloader.
|
|
152
|
+
downloader.initialize({
|
|
149
153
|
results: gathered,
|
|
150
154
|
total: 3,
|
|
151
155
|
maxDownloadBatchWait: 200
|
|
@@ -183,7 +187,8 @@ describe('downloader', () => {
|
|
|
183
187
|
objectId: i.baseId,
|
|
184
188
|
token: 'token',
|
|
185
189
|
|
|
186
|
-
fetch: fetchMocker
|
|
190
|
+
fetch: fetchMocker,
|
|
191
|
+
logger: (): void => {}
|
|
187
192
|
})
|
|
188
193
|
await expect(downloader.downloadSingle()).rejects.toThrow()
|
|
189
194
|
await downloader.disposeAsync()
|
|
@@ -202,7 +207,8 @@ describe('downloader', () => {
|
|
|
202
207
|
objectId: i.baseId,
|
|
203
208
|
token: 'token',
|
|
204
209
|
|
|
205
|
-
fetch: fetchMocker
|
|
210
|
+
fetch: fetchMocker,
|
|
211
|
+
logger: (): void => {}
|
|
206
212
|
})
|
|
207
213
|
const x = await downloader.downloadSingle()
|
|
208
214
|
expect(x).toMatchSnapshot()
|
|
@@ -228,7 +234,8 @@ describe('downloader', () => {
|
|
|
228
234
|
objectId: i.baseId,
|
|
229
235
|
token: 'token',
|
|
230
236
|
|
|
231
|
-
fetch: fetchMocker
|
|
237
|
+
fetch: fetchMocker,
|
|
238
|
+
logger: (): void => {}
|
|
232
239
|
})
|
|
233
240
|
const x = await downloader.downloadSingle()
|
|
234
241
|
expect(x).toMatchSnapshot()
|
|
@@ -245,7 +252,8 @@ describe('downloader', () => {
|
|
|
245
252
|
objectId: 'objectId',
|
|
246
253
|
token: 'token',
|
|
247
254
|
|
|
248
|
-
fetch: fetchMocker
|
|
255
|
+
fetch: fetchMocker,
|
|
256
|
+
logger: (): void => {}
|
|
249
257
|
})
|
|
250
258
|
await downloader.disposeAsync()
|
|
251
259
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import BatchingQueue from '../../queues/batchingQueue.js'
|
|
2
2
|
import Queue from '../../queues/queue.js'
|
|
3
3
|
import { ObjectLoaderRuntimeError } from '../../types/errors.js'
|
|
4
|
-
import { Fetcher, indexOf, isBase, take } from '../../types/functions.js'
|
|
4
|
+
import { CustomLogger, Fetcher, indexOf, isBase, take } from '../../types/functions.js'
|
|
5
5
|
import { Item } from '../../types/types.js'
|
|
6
6
|
import { Downloader } from '../interfaces.js'
|
|
7
7
|
|
|
@@ -11,6 +11,7 @@ export interface ServerDownloaderOptions {
|
|
|
11
11
|
objectId: string
|
|
12
12
|
token?: string
|
|
13
13
|
headers?: Headers
|
|
14
|
+
logger: CustomLogger
|
|
14
15
|
fetch?: Fetcher
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -24,8 +25,9 @@ export default class ServerDownloader implements Downloader {
|
|
|
24
25
|
#fetch: Fetcher
|
|
25
26
|
#results?: Queue<Item>
|
|
26
27
|
#total?: number
|
|
28
|
+
#logger: CustomLogger
|
|
27
29
|
|
|
28
|
-
#downloadQueue?:
|
|
30
|
+
#downloadQueue?: BatchingQueue<string>
|
|
29
31
|
#decoder = new TextDecoder('utf-8', { fatal: true })
|
|
30
32
|
#decodedBytesCount = 0
|
|
31
33
|
|
|
@@ -34,6 +36,7 @@ export default class ServerDownloader implements Downloader {
|
|
|
34
36
|
|
|
35
37
|
constructor(options: ServerDownloaderOptions) {
|
|
36
38
|
this.#options = options
|
|
39
|
+
this.#logger = options.logger
|
|
37
40
|
this.#fetch =
|
|
38
41
|
options.fetch ?? ((...args): Promise<Response> => globalThis.fetch(...args))
|
|
39
42
|
|
|
@@ -59,25 +62,17 @@ export default class ServerDownloader implements Downloader {
|
|
|
59
62
|
this.#rawEncoding = encoder.encode(this.#rawString)
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
if (total <= 50) {
|
|
64
|
-
return [total]
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return [10000, 25000, 10000, 1000]
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
initializePool(params: {
|
|
65
|
+
initialize(params: {
|
|
71
66
|
results: Queue<Item>
|
|
72
67
|
total: number
|
|
73
68
|
maxDownloadBatchWait?: number
|
|
74
69
|
}): void {
|
|
75
|
-
const { results, total } = params
|
|
70
|
+
const { results, total, maxDownloadBatchWait } = params
|
|
76
71
|
this.#results = results
|
|
77
72
|
this.#total = total
|
|
78
|
-
this.#downloadQueue = new
|
|
79
|
-
|
|
80
|
-
maxWaitTime:
|
|
73
|
+
this.#downloadQueue = new BatchingQueue<string>({
|
|
74
|
+
batchSize: 15000, // 15k is a good number for most cases
|
|
75
|
+
maxWaitTime: maxDownloadBatchWait ?? 1000, // 1 second
|
|
81
76
|
processFunction: (batch: string[]): Promise<void> =>
|
|
82
77
|
this.downloadBatch({
|
|
83
78
|
batch,
|
|
@@ -87,15 +82,8 @@ export default class ServerDownloader implements Downloader {
|
|
|
87
82
|
})
|
|
88
83
|
}
|
|
89
84
|
|
|
90
|
-
#getPool(): BatchedPool<string> {
|
|
91
|
-
if (this.#downloadQueue) {
|
|
92
|
-
return this.#downloadQueue
|
|
93
|
-
}
|
|
94
|
-
throw new Error('Download pool is not initialized')
|
|
95
|
-
}
|
|
96
|
-
|
|
97
85
|
add(id: string): void {
|
|
98
|
-
this.#
|
|
86
|
+
this.#downloadQueue?.add(id, id)
|
|
99
87
|
}
|
|
100
88
|
|
|
101
89
|
/*
|
|
@@ -126,6 +114,9 @@ Chrome's behavior: Chrome generally handles larger data sizes without this speci
|
|
|
126
114
|
headers: HeadersInit
|
|
127
115
|
}): Promise<void> {
|
|
128
116
|
const { batch, url, headers } = params
|
|
117
|
+
|
|
118
|
+
const start = performance.now()
|
|
119
|
+
this.#logger(`Downloading batch of ${batch.length} items...`)
|
|
129
120
|
const keys = new Set<string>(batch)
|
|
130
121
|
const response = await this.#fetch(url, {
|
|
131
122
|
method: 'POST',
|
|
@@ -162,6 +153,9 @@ Chrome's behavior: Chrome generally handles larger data sizes without this speci
|
|
|
162
153
|
if (count >= this.#total!) {
|
|
163
154
|
await this.#results?.disposeAsync() // mark the queue as done
|
|
164
155
|
}
|
|
156
|
+
this.#logger(
|
|
157
|
+
`Downloaded batch of ${batch.length} items in ${performance.now() - start}ms`
|
|
158
|
+
)
|
|
165
159
|
}
|
|
166
160
|
|
|
167
161
|
async #processArray(
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest'
|
|
2
|
+
import KeyedQueue from './keyedQueue.js'
|
|
3
|
+
|
|
4
|
+
describe('KeyedQueue', () => {
|
|
5
|
+
let queue: KeyedQueue<string, number>
|
|
6
|
+
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
queue = new KeyedQueue<string, number>()
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
describe('enqueue', () => {
|
|
12
|
+
it('should add a key-value pair to the queue', () => {
|
|
13
|
+
const result = queue.enqueue('key1', 1)
|
|
14
|
+
|
|
15
|
+
expect(result).toBe(true)
|
|
16
|
+
expect(queue.size).toBe(1)
|
|
17
|
+
expect(queue.get('key1')).toBe(1)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('should return false when trying to add a key that already exists', () => {
|
|
21
|
+
queue.enqueue('key1', 1)
|
|
22
|
+
const result = queue.enqueue('key1', 2)
|
|
23
|
+
|
|
24
|
+
expect(result).toBe(false)
|
|
25
|
+
expect(queue.size).toBe(1)
|
|
26
|
+
expect(queue.get('key1')).toBe(1) // Value should not be updated
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
describe('enqueueAll', () => {
|
|
31
|
+
it('should add multiple key-value pairs to the queue', () => {
|
|
32
|
+
const keys = ['key1', 'key2', 'key3']
|
|
33
|
+
const values = [1, 2, 3]
|
|
34
|
+
|
|
35
|
+
const count = queue.enqueueAll(keys, values)
|
|
36
|
+
|
|
37
|
+
expect(count).toBe(3)
|
|
38
|
+
expect(queue.size).toBe(3)
|
|
39
|
+
expect(queue.get('key1')).toBe(1)
|
|
40
|
+
expect(queue.get('key2')).toBe(2)
|
|
41
|
+
expect(queue.get('key3')).toBe(3)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('should skip keys that already exist and return the count of added items', () => {
|
|
45
|
+
queue.enqueue('key1', 1)
|
|
46
|
+
|
|
47
|
+
const keys = ['key1', 'key2', 'key3']
|
|
48
|
+
const values = [10, 2, 3]
|
|
49
|
+
|
|
50
|
+
const count = queue.enqueueAll(keys, values)
|
|
51
|
+
|
|
52
|
+
expect(count).toBe(2)
|
|
53
|
+
expect(queue.size).toBe(3)
|
|
54
|
+
expect(queue.get('key1')).toBe(1) // Original value preserved
|
|
55
|
+
expect(queue.get('key2')).toBe(2)
|
|
56
|
+
expect(queue.get('key3')).toBe(3)
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
describe('get', () => {
|
|
61
|
+
it('should return the value for a given key', () => {
|
|
62
|
+
queue.enqueue('key1', 1)
|
|
63
|
+
|
|
64
|
+
expect(queue.get('key1')).toBe(1)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('should return undefined for a non-existent key', () => {
|
|
68
|
+
expect(queue.get('nonexistent')).toBeUndefined()
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
describe('has', () => {
|
|
73
|
+
it('should return true if the key exists', () => {
|
|
74
|
+
queue.enqueue('key1', 1)
|
|
75
|
+
|
|
76
|
+
expect(queue.has('key1')).toBe(true)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('should return false if the key does not exist', () => {
|
|
80
|
+
expect(queue.has('nonexistent')).toBe(false)
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
describe('size', () => {
|
|
85
|
+
it('should return the number of items in the queue', () => {
|
|
86
|
+
expect(queue.size).toBe(0)
|
|
87
|
+
|
|
88
|
+
queue.enqueue('key1', 1)
|
|
89
|
+
expect(queue.size).toBe(1)
|
|
90
|
+
|
|
91
|
+
queue.enqueue('key2', 2)
|
|
92
|
+
expect(queue.size).toBe(2)
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
describe('spliceValues', () => {
|
|
97
|
+
it('should remove and return values from the queue', () => {
|
|
98
|
+
queue.enqueue('key1', 1)
|
|
99
|
+
queue.enqueue('key2', 2)
|
|
100
|
+
queue.enqueue('key3', 3)
|
|
101
|
+
queue.enqueue('key4', 4)
|
|
102
|
+
|
|
103
|
+
const result = queue.spliceValues(1, 2)
|
|
104
|
+
|
|
105
|
+
expect(result).toEqual([2, 3])
|
|
106
|
+
expect(queue.size).toBe(2)
|
|
107
|
+
expect(queue.has('key1')).toBe(true)
|
|
108
|
+
expect(queue.has('key2')).toBe(false)
|
|
109
|
+
expect(queue.has('key3')).toBe(false)
|
|
110
|
+
expect(queue.has('key4')).toBe(true)
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
it('should handle splicing at the beginning of the queue', () => {
|
|
114
|
+
queue.enqueue('key1', 1)
|
|
115
|
+
queue.enqueue('key2', 2)
|
|
116
|
+
|
|
117
|
+
const result = queue.spliceValues(0, 1)
|
|
118
|
+
|
|
119
|
+
expect(result).toEqual([1])
|
|
120
|
+
expect(queue.size).toBe(1)
|
|
121
|
+
expect(queue.has('key1')).toBe(false)
|
|
122
|
+
expect(queue.has('key2')).toBe(true)
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it('should handle splicing at the end of the queue', () => {
|
|
126
|
+
queue.enqueue('key1', 1)
|
|
127
|
+
queue.enqueue('key2', 2)
|
|
128
|
+
|
|
129
|
+
const result = queue.spliceValues(1, 1)
|
|
130
|
+
|
|
131
|
+
expect(result).toEqual([2])
|
|
132
|
+
expect(queue.size).toBe(1)
|
|
133
|
+
expect(queue.has('key1')).toBe(true)
|
|
134
|
+
expect(queue.has('key2')).toBe(false)
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
it('should return an empty array when deleting zero elements', () => {
|
|
138
|
+
queue.enqueue('key1', 1)
|
|
139
|
+
|
|
140
|
+
const result = queue.spliceValues(0, 0)
|
|
141
|
+
|
|
142
|
+
expect(result).toEqual([])
|
|
143
|
+
expect(queue.size).toBe(1)
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
})
|
|
@@ -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,167 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ItemStore = void 0;
|
|
4
|
-
/* eslint-disable @typescript-eslint/no-base-to-string */
|
|
5
|
-
/* eslint-disable @typescript-eslint/prefer-promise-reject-errors */
|
|
6
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
|
-
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
|
|
8
|
-
const shared_1 = require("@speckle/shared");
|
|
9
|
-
class ItemStore {
|
|
10
|
-
#options;
|
|
11
|
-
#db = undefined;
|
|
12
|
-
#dbName;
|
|
13
|
-
#storeName;
|
|
14
|
-
constructor(options, dbName, storeName) {
|
|
15
|
-
this.#options = options;
|
|
16
|
-
this.#dbName = dbName;
|
|
17
|
-
this.#storeName = storeName;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Initializes the database connection and creates the object store if needed.
|
|
21
|
-
* This must be called before any other database operations.
|
|
22
|
-
*/
|
|
23
|
-
async init() {
|
|
24
|
-
if (this.#db)
|
|
25
|
-
return;
|
|
26
|
-
await this.#safariFix();
|
|
27
|
-
return this.#openDatabase();
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Opens the database, and if there's an error, deletes the database and tries again.
|
|
31
|
-
*/
|
|
32
|
-
async #openDatabase() {
|
|
33
|
-
const idb = this.#options.indexedDB ?? indexedDB;
|
|
34
|
-
return new Promise((resolve, reject) => {
|
|
35
|
-
const request = idb.open(this.#dbName, 1);
|
|
36
|
-
request.onerror = () => {
|
|
37
|
-
console.warn(`Failed to open database: ${this.#dbName}, deleting and trying again`);
|
|
38
|
-
// Delete the database and try again
|
|
39
|
-
const deleteRequest = idb.deleteDatabase(this.#dbName);
|
|
40
|
-
deleteRequest.onsuccess = () => {
|
|
41
|
-
// Try opening again after deletion
|
|
42
|
-
void this.#openDatabase().then(resolve).catch(reject);
|
|
43
|
-
};
|
|
44
|
-
deleteRequest.onerror = () => {
|
|
45
|
-
reject(`Failed to delete and reopen database: ${this.#dbName}`);
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
request.onupgradeneeded = (event) => {
|
|
49
|
-
const db = event.target.result;
|
|
50
|
-
if (db.objectStoreNames.contains(this.#storeName)) {
|
|
51
|
-
db.deleteObjectStore(this.#storeName);
|
|
52
|
-
}
|
|
53
|
-
db.createObjectStore(this.#storeName, { keyPath: 'baseId' });
|
|
54
|
-
};
|
|
55
|
-
request.onsuccess = (event) => {
|
|
56
|
-
this.#db = event.target.result;
|
|
57
|
-
resolve();
|
|
58
|
-
};
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
#getDB() {
|
|
62
|
-
if (!this.#db) {
|
|
63
|
-
throw new Error('Database not initialized. Call init() first.');
|
|
64
|
-
}
|
|
65
|
-
return this.#db;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Fixes a Safari bug where IndexedDB requests get lost and never resolve - invoke before you use IndexedDB
|
|
69
|
-
* @link Credits and more info: https://github.com/jakearchibald/safari-14-idb-fix
|
|
70
|
-
*/
|
|
71
|
-
async #safariFix() {
|
|
72
|
-
// No point putting other browsers or older versions of Safari through this mess.
|
|
73
|
-
if (!(0, shared_1.isSafari)() || !this.#options.indexedDB?.databases)
|
|
74
|
-
return Promise.resolve();
|
|
75
|
-
let intervalId;
|
|
76
|
-
return new Promise((resolve) => {
|
|
77
|
-
const tryIdb = () => this.#options.indexedDB?.databases().finally(resolve);
|
|
78
|
-
intervalId = setInterval(() => {
|
|
79
|
-
void tryIdb();
|
|
80
|
-
}, 100);
|
|
81
|
-
void tryIdb();
|
|
82
|
-
}).finally(() => clearInterval(intervalId));
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Inserts or updates an array of items in a single transaction.
|
|
86
|
-
* @param data The array of items to insert.
|
|
87
|
-
*/
|
|
88
|
-
bulkInsert(data) {
|
|
89
|
-
return new Promise((resolve, reject) => {
|
|
90
|
-
try {
|
|
91
|
-
const transaction = this.#getDB().transaction(this.#storeName, 'readwrite', {
|
|
92
|
-
durability: 'relaxed'
|
|
93
|
-
});
|
|
94
|
-
const store = transaction.objectStore(this.#storeName);
|
|
95
|
-
transaction.onerror = () => {
|
|
96
|
-
reject(`Transaction error: ${transaction.error}`);
|
|
97
|
-
};
|
|
98
|
-
transaction.oncomplete = () => {
|
|
99
|
-
resolve();
|
|
100
|
-
};
|
|
101
|
-
data.forEach((item) => store.put(item));
|
|
102
|
-
}
|
|
103
|
-
catch (error) {
|
|
104
|
-
reject(error);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Retrieves an array of items from the object store based on their IDs.
|
|
110
|
-
* @param ids The array of IDs to retrieve.
|
|
111
|
-
*/
|
|
112
|
-
bulkGet(ids) {
|
|
113
|
-
return new Promise((resolve, reject) => {
|
|
114
|
-
if (ids.length === 0) {
|
|
115
|
-
return resolve([]);
|
|
116
|
-
}
|
|
117
|
-
try {
|
|
118
|
-
const transaction = this.#getDB().transaction(this.#storeName, 'readonly', {
|
|
119
|
-
durability: 'relaxed'
|
|
120
|
-
});
|
|
121
|
-
const store = transaction.objectStore(this.#storeName);
|
|
122
|
-
const promises = [];
|
|
123
|
-
for (const id of ids) {
|
|
124
|
-
promises.push(new Promise((resolveGet, rejectGet) => {
|
|
125
|
-
const request = store.get(id);
|
|
126
|
-
request.onerror = () => rejectGet(`Request error for id ${id}: ${request.error}`);
|
|
127
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
128
|
-
request.onsuccess = () => resolveGet(request.result);
|
|
129
|
-
}));
|
|
130
|
-
}
|
|
131
|
-
Promise.all(promises)
|
|
132
|
-
.then((results) => {
|
|
133
|
-
resolve(results);
|
|
134
|
-
})
|
|
135
|
-
.catch(reject);
|
|
136
|
-
}
|
|
137
|
-
catch (error) {
|
|
138
|
-
reject(error);
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Retrieves all items from the object store.
|
|
144
|
-
*/
|
|
145
|
-
getAll() {
|
|
146
|
-
return new Promise((resolve, reject) => {
|
|
147
|
-
try {
|
|
148
|
-
const transaction = this.#getDB().transaction(this.#storeName, 'readonly');
|
|
149
|
-
const store = transaction.objectStore(this.#storeName);
|
|
150
|
-
const request = store.getAll();
|
|
151
|
-
request.onerror = () => reject(`Request error: ${request.error}`);
|
|
152
|
-
request.onsuccess = () => resolve(request.result);
|
|
153
|
-
}
|
|
154
|
-
catch (error) {
|
|
155
|
-
reject(error);
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
close() {
|
|
160
|
-
if (!this.#db)
|
|
161
|
-
return;
|
|
162
|
-
this.#db.close();
|
|
163
|
-
this.#db = undefined;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
exports.ItemStore = ItemStore;
|
|
167
|
-
//# 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,45 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
class BatchedPool {
|
|
4
|
-
#queue = [];
|
|
5
|
-
#concurrencyAndSizes;
|
|
6
|
-
#processFunction;
|
|
7
|
-
#baseInterval;
|
|
8
|
-
#processingLoop;
|
|
9
|
-
#disposed = false;
|
|
10
|
-
constructor(params) {
|
|
11
|
-
this.#concurrencyAndSizes = params.concurrencyAndSizes;
|
|
12
|
-
this.#baseInterval = Math.min(params.maxWaitTime ?? 200, 200); // Initial batch time (ms)
|
|
13
|
-
this.#processFunction = params.processFunction;
|
|
14
|
-
this.#processingLoop = this.#loop();
|
|
15
|
-
}
|
|
16
|
-
add(item) {
|
|
17
|
-
this.#queue.push(item);
|
|
18
|
-
}
|
|
19
|
-
getBatch(batchSize) {
|
|
20
|
-
return this.#queue.splice(0, Math.min(batchSize, this.#queue.length));
|
|
21
|
-
}
|
|
22
|
-
async #runWorker(batchSize) {
|
|
23
|
-
while (!this.#disposed || this.#queue.length > 0) {
|
|
24
|
-
if (this.#queue.length > 0) {
|
|
25
|
-
const batch = this.getBatch(batchSize);
|
|
26
|
-
await this.#processFunction(batch);
|
|
27
|
-
}
|
|
28
|
-
await this.#delay(this.#baseInterval);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
async disposeAsync() {
|
|
32
|
-
this.#disposed = true;
|
|
33
|
-
await this.#processingLoop;
|
|
34
|
-
}
|
|
35
|
-
async #loop() {
|
|
36
|
-
// Initialize workers
|
|
37
|
-
const workers = Array.from(this.#concurrencyAndSizes, (batchSize) => this.#runWorker(batchSize));
|
|
38
|
-
await Promise.all(workers);
|
|
39
|
-
}
|
|
40
|
-
#delay(ms) {
|
|
41
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
exports.default = BatchedPool;
|
|
45
|
-
//# sourceMappingURL=batchedPool.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"batchedPool.js","sourceRoot":"","sources":["../../../src/queues/batchedPool.ts"],"names":[],"mappings":";;AAEA,MAAqB,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;AAvDD,8BAuDC"}
|