@speckle/objectloader2 2.26.2 → 2.26.3

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 (29) hide show
  1. package/dist/commonjs/deferment/defermentManager.test.js +10 -5
  2. package/dist/commonjs/deferment/defermentManager.test.js.map +1 -1
  3. package/dist/commonjs/queues/batchingQueue.d.ts +2 -0
  4. package/dist/commonjs/queues/batchingQueue.d.ts.map +1 -1
  5. package/dist/commonjs/queues/batchingQueue.dispose.test.js +1 -1
  6. package/dist/commonjs/queues/batchingQueue.dispose.test.js.map +1 -1
  7. package/dist/commonjs/queues/batchingQueue.js +19 -15
  8. package/dist/commonjs/queues/batchingQueue.js.map +1 -1
  9. package/dist/commonjs/queues/batchingQueue.test.js +98 -0
  10. package/dist/commonjs/queues/batchingQueue.test.js.map +1 -1
  11. package/dist/esm/deferment/defermentManager.test.js +10 -5
  12. package/dist/esm/deferment/defermentManager.test.js.map +1 -1
  13. package/dist/esm/queues/batchingQueue.d.ts +2 -0
  14. package/dist/esm/queues/batchingQueue.d.ts.map +1 -1
  15. package/dist/esm/queues/batchingQueue.dispose.test.js +1 -1
  16. package/dist/esm/queues/batchingQueue.dispose.test.js.map +1 -1
  17. package/dist/esm/queues/batchingQueue.js +19 -15
  18. package/dist/esm/queues/batchingQueue.js.map +1 -1
  19. package/dist/esm/queues/batchingQueue.test.js +98 -0
  20. package/dist/esm/queues/batchingQueue.test.js.map +1 -1
  21. package/package.json +2 -2
  22. package/src/core/objectLoader2.spec.ts +10 -3
  23. package/src/core/stages/cacheReader.spec.ts +1 -1
  24. package/src/core/stages/cacheWriter.spec.ts +1 -1
  25. package/src/core/stages/serverDownloader.spec.ts +122 -0
  26. package/src/deferment/defermentManager.test.ts +10 -5
  27. package/src/queues/batchingQueue.dispose.test.ts +1 -1
  28. package/src/queues/batchingQueue.test.ts +121 -0
  29. package/src/queues/batchingQueue.ts +20 -16
@@ -1 +1 @@
1
- {"version":3,"file":"batchingQueue.js","sourceRoot":"","sources":["../../../src/queues/batchingQueue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"batchingQueue.js","sourceRoot":"","sources":["../../../src/queues/batchingQueue.ts"],"names":[],"mappings":"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"}
@@ -129,5 +129,103 @@ describe('BatchingQueue', () => {
129
129
  await queue.disposeAsync();
130
130
  }
131
131
  });
132
+ test('should handle processFunction throwing an exception during flush and is disposed', async () => {
133
+ const errorMessage = 'Process function failed';
134
+ const processFunction = vi.fn().mockRejectedValue(new Error(errorMessage));
135
+ const queue = new BatchingQueue({
136
+ batchSize: 5,
137
+ maxWaitTime: 1000,
138
+ processFunction
139
+ });
140
+ const items = Array.from({ length: 3 }, (_, i) => ({ id: `item-${i}` }));
141
+ items.forEach((item) => queue.add(item.id, item));
142
+ expect(queue.count()).toBe(3);
143
+ // flush should not throw even if processFunction rejects
144
+ await expect(queue.flush()).resolves.not.toThrow();
145
+ expect(processFunction).toHaveBeenCalled();
146
+ expect(queue.count()).toBe(0);
147
+ expect(queue.isDisposed()).toBe(false);
148
+ expect(queue.isErrored()).toBe(true);
149
+ // Add more items after the exception
150
+ queue.add('key3', { id: `item-3` });
151
+ queue.add('key4', { id: `item-4` });
152
+ // Wait to see if second batch gets processed (it shouldn't due to errored state)
153
+ await new Promise((resolve) => setTimeout(resolve, 200));
154
+ expect(queue.count()).toBe(0); // Items were not added due to errored state
155
+ await queue.disposeAsync();
156
+ });
157
+ test('should drain remaining items when disposed', async () => {
158
+ const processSpy = vi.fn();
159
+ const queue = new BatchingQueue({
160
+ batchSize: 5, // Large batch size to prevent automatic processing
161
+ maxWaitTime: 10000, // Long timeout to prevent timeout-based processing
162
+ processFunction: async (batch) => {
163
+ await new Promise((resolve) => setTimeout(resolve, 10));
164
+ processSpy(batch);
165
+ }
166
+ });
167
+ // Add items that won't trigger automatic processing (less than batch size)
168
+ queue.add('key1', 'item1');
169
+ queue.add('key2', 'item2');
170
+ queue.add('key3', 'item3');
171
+ // Verify items are in queue but haven't been processed yet
172
+ expect(queue.count()).toBe(3);
173
+ expect(processSpy).not.toHaveBeenCalled();
174
+ // Dispose should drain the remaining items
175
+ await queue.disposeAsync();
176
+ // Verify all items were processed during disposal
177
+ expect(processSpy).toHaveBeenCalledTimes(1);
178
+ expect(processSpy).toHaveBeenCalledWith(['item1', 'item2', 'item3']);
179
+ expect(queue.count()).toBe(0);
180
+ expect(queue.isDisposed()).toBe(true);
181
+ });
182
+ test('should drain items even with ongoing processing during dispose', async () => {
183
+ const processSpy = vi.fn();
184
+ let firstBatchStarted = false;
185
+ let allowFirstBatchToComplete = null;
186
+ const queue = new BatchingQueue({
187
+ batchSize: 2,
188
+ maxWaitTime: 100,
189
+ processFunction: async (batch) => {
190
+ processSpy(batch);
191
+ // Make the first batch wait for our signal
192
+ if (!firstBatchStarted) {
193
+ firstBatchStarted = true;
194
+ await new Promise((resolve) => {
195
+ allowFirstBatchToComplete = resolve;
196
+ });
197
+ }
198
+ else {
199
+ // Other batches process normally
200
+ await new Promise((resolve) => setTimeout(resolve, 10));
201
+ }
202
+ }
203
+ });
204
+ // Add first batch that will trigger processing but will be blocked
205
+ queue.add('key1', 'item1');
206
+ queue.add('key2', 'item2');
207
+ // Wait for first batch to start processing and allowFirstBatchToComplete to be assigned
208
+ await new Promise((resolve) => setTimeout(resolve, 50));
209
+ expect(firstBatchStarted).toBe(true);
210
+ expect(processSpy).toHaveBeenCalledTimes(1);
211
+ expect(allowFirstBatchToComplete).not.toBeNull();
212
+ // Add more items while first batch is still processing
213
+ queue.add('key3', 'item3');
214
+ queue.add('key4', 'item4');
215
+ // Verify the additional items are queued
216
+ expect(queue.count()).toBe(2);
217
+ // Start disposal (this should wait for ongoing processing and then drain)
218
+ const disposePromise = queue.disposeAsync();
219
+ // Allow the first batch to complete
220
+ allowFirstBatchToComplete();
221
+ // Wait for disposal to complete
222
+ await disposePromise;
223
+ // Verify all batches were processed
224
+ expect(processSpy).toHaveBeenCalledTimes(2);
225
+ expect(processSpy).toHaveBeenCalledWith(['item1', 'item2']);
226
+ expect(processSpy).toHaveBeenCalledWith(['item3', 'item4']);
227
+ expect(queue.count()).toBe(0);
228
+ expect(queue.isDisposed()).toBe(true);
229
+ });
132
230
  });
133
231
  //# sourceMappingURL=batchingQueue.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"batchingQueue.test.js","sourceRoot":"","sources":["../../../src/queues/batchingQueue.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"batchingQueue.test.js","sourceRoot":"","sources":["../../../src/queues/batchingQueue.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.26.2",
3
+ "version": "2.26.3",
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.26.2"
36
+ "@speckle/shared": "^2.26.3"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/lodash": "^4.17.5",
@@ -5,6 +5,7 @@ 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'
8
+ import { DefermentManager } from '../deferment/defermentManager.js'
8
9
 
9
10
  describe('objectloader2', () => {
10
11
  test('can get a root object from cache', async () => {
@@ -17,6 +18,7 @@ describe('objectloader2', () => {
17
18
  const loader = new ObjectLoader2({
18
19
  rootId,
19
20
  downloader,
21
+ deferments: new DefermentManager(() => {}),
20
22
  database: new IndexedDatabase({
21
23
  indexedDB: new IDBFactory(),
22
24
  keyRange: IDBKeyRange
@@ -37,6 +39,7 @@ describe('objectloader2', () => {
37
39
  const loader = new ObjectLoader2({
38
40
  rootId,
39
41
  downloader,
42
+ deferments: new DefermentManager(() => {}),
40
43
  database: new IndexedDatabase({
41
44
  indexedDB: new IDBFactory(),
42
45
  keyRange: IDBKeyRange
@@ -58,6 +61,7 @@ describe('objectloader2', () => {
58
61
  const loader = new ObjectLoader2({
59
62
  rootId,
60
63
  downloader,
64
+ deferments: new DefermentManager(() => {}),
61
65
  database: new IndexedDatabase({
62
66
  indexedDB: new IDBFactory(),
63
67
  keyRange: IDBKeyRange
@@ -97,7 +101,8 @@ describe('objectloader2', () => {
97
101
  const loader = new ObjectLoader2({
98
102
  rootId: root.baseId,
99
103
  downloader: new MemoryDownloader(rootId, records),
100
- database: new MemoryDatabase({ items: records })
104
+ database: new MemoryDatabase({ items: records }),
105
+ deferments: new DefermentManager(() => {})
101
106
  })
102
107
 
103
108
  const r = []
@@ -139,7 +144,8 @@ describe('objectloader2', () => {
139
144
  const loader = new ObjectLoader2({
140
145
  rootId: root.baseId,
141
146
  downloader: new MemoryDownloader(rootId, records),
142
- database: new MemoryDatabase({ items: records })
147
+ database: new MemoryDatabase({ items: records }),
148
+ deferments: new DefermentManager(() => {})
143
149
  })
144
150
  const r = []
145
151
  const obj = loader.getObject({ id: child1.baseId })
@@ -180,7 +186,8 @@ describe('objectloader2', () => {
180
186
  database: new IndexedDatabase({
181
187
  indexedDB: new IDBFactory(),
182
188
  keyRange: IDBKeyRange
183
- })
189
+ }),
190
+ deferments: new DefermentManager(() => {})
184
191
  })
185
192
  const x = await loader.getRootObject()
186
193
  await loader.disposeAsync()
@@ -10,7 +10,7 @@ describe('CacheReader testing', () => {
10
10
  const i1: Item = { baseId: 'id1', base: { id: 'id', speckle_type: 'type' } }
11
11
 
12
12
  const cache = new MemoryCache({ maxSizeInMb: 1, ttlms: 1 }, () => {})
13
- const deferments = new DefermentManager(cache, () => {})
13
+ const deferments = new DefermentManager(() => {}, cache)
14
14
  const cacheReader = new CacheReader(
15
15
  new MemoryDatabase({
16
16
  items: new Map<string, Base>([[i1.baseId, i1.base!]])
@@ -42,7 +42,7 @@ describe('CacheWriter', () => {
42
42
  ttlms: 60000
43
43
  }
44
44
  memoryCache = new MemoryCache(memoryCacheOptions, logger)
45
- defermentManager = new DefermentManager(memoryCache, logger)
45
+ defermentManager = new DefermentManager(logger, memoryCache)
46
46
  requestItemMock = vi.fn()
47
47
 
48
48
  options = {
@@ -257,4 +257,126 @@ describe('downloader', () => {
257
257
  })
258
258
  await downloader.disposeAsync()
259
259
  })
260
+
261
+ test('nothing is frozen when validateResponse returns 403', async () => {
262
+ const fetchMocker = createFetchMock(vi)
263
+ const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
264
+
265
+ // Mock a 403 Forbidden response
266
+ fetchMocker.mockResponseOnce('', { status: 403, statusText: 'Forbidden' })
267
+
268
+ const gathered = new AsyncGeneratorQueue<Item>()
269
+ const downloader = new ServerDownloader({
270
+ serverUrl: 'http://speckle.test',
271
+ streamId: 'streamId',
272
+ objectId: 'objectId',
273
+ token: 'invalid-token',
274
+ fetch: fetchMocker,
275
+ logger: (): void => {}
276
+ })
277
+
278
+ try {
279
+ downloader.initialize({
280
+ results: gathered,
281
+ total: 2,
282
+ maxDownloadBatchWait: 100
283
+ })
284
+
285
+ // Add items to trigger batch processing
286
+ downloader.add('id1')
287
+ downloader.add('id2')
288
+
289
+ // Wait for the batch to be processed and fail with 403
290
+ await new Promise((resolve) => setTimeout(resolve, 200))
291
+
292
+ // Verify that the error was logged (indicating the batch processing failed)
293
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
294
+ 'Batch processing failed:',
295
+ expect.any(Error)
296
+ )
297
+
298
+ // The key test: verify we can still dispose the downloader properly
299
+ // This ensures the system isn't frozen and can clean up resources
300
+ const disposePromise = downloader.disposeAsync()
301
+
302
+ // Add a timeout to ensure disposal doesn't hang indefinitely
303
+ const timeoutPromise = new Promise((_, reject) => {
304
+ setTimeout(() => reject(new Error('Disposal timed out')), 5000)
305
+ })
306
+
307
+ // This should complete without timing out or throwing
308
+ await Promise.race([disposePromise, timeoutPromise])
309
+
310
+ // Additional verification: the batching queue should be marked as disposed
311
+ // We can't directly access the private field, but we can verify disposal completed
312
+ expect(true).toBe(true) // If we reach here, disposal succeeded
313
+ } finally {
314
+ consoleErrorSpy.mockRestore()
315
+ }
316
+ })
317
+
318
+ test('system remains functional after 403 error and can be properly cleaned up', async () => {
319
+ const fetchMocker = createFetchMock(vi)
320
+ const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
321
+
322
+ // First call returns 403, subsequent calls should not be made due to queue disposal
323
+ fetchMocker.mockResponseOnce('', { status: 403, statusText: 'Forbidden' })
324
+
325
+ const gathered = new AsyncGeneratorQueue<Item>()
326
+ const downloader = new ServerDownloader({
327
+ serverUrl: 'http://speckle.test',
328
+ streamId: 'streamId',
329
+ objectId: 'objectId',
330
+ token: 'invalid-token',
331
+ fetch: fetchMocker,
332
+ logger: (): void => {}
333
+ })
334
+
335
+ try {
336
+ downloader.initialize({
337
+ results: gathered,
338
+ total: 5,
339
+ maxDownloadBatchWait: 50
340
+ })
341
+
342
+ // Add first batch that will trigger the 403 error
343
+ downloader.add('id1')
344
+ downloader.add('id2')
345
+
346
+ // Wait for first batch to fail
347
+ await new Promise((resolve) => setTimeout(resolve, 100))
348
+
349
+ // Verify error was logged
350
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
351
+ 'Batch processing failed:',
352
+ expect.any(Error)
353
+ )
354
+
355
+ // Try to add more items after the failure
356
+ // These should be ignored since the queue is now disposed
357
+ downloader.add('id3')
358
+ downloader.add('id4')
359
+ downloader.add('id5')
360
+
361
+ // Wait a bit more to ensure no additional processing attempts
362
+ await new Promise((resolve) => setTimeout(resolve, 100))
363
+
364
+ // Note: The batching queue might make multiple attempts before disposal
365
+ // The key is that disposal should still work regardless of how many calls were made
366
+ expect(fetchMocker).toHaveBeenCalled()
367
+
368
+ // Critical test: disposal should complete without hanging
369
+ const start = Date.now()
370
+ await downloader.disposeAsync()
371
+ const elapsed = Date.now() - start
372
+
373
+ // Disposal should be quick (under 1 second) and not hang
374
+ expect(elapsed).toBeLessThan(1000)
375
+
376
+ // Verify that the results queue can also be disposed properly
377
+ await gathered.disposeAsync()
378
+ } finally {
379
+ consoleErrorSpy.mockRestore()
380
+ }
381
+ })
260
382
  })
@@ -9,7 +9,8 @@ describe('DefermentManager', () => {
9
9
  const mockLogger: CustomLogger = vi.fn()
10
10
  const mockCache = {
11
11
  get: vi.fn(),
12
- add: vi.fn()
12
+ add: vi.fn(),
13
+ dispose: vi.fn()
13
14
  } as unknown as MemoryCache
14
15
  const defermentManager = new DefermentManager(mockLogger, mockCache)
15
16
  expect(defermentManager).toBeDefined()
@@ -81,7 +82,8 @@ describe('DefermentManager', () => {
81
82
  const add = vi.fn()
82
83
  const mockCache = {
83
84
  get,
84
- add
85
+ add,
86
+ dispose: vi.fn()
85
87
  } as unknown as MemoryCache
86
88
  const defermentManager = new DefermentManager(mockLogger, mockCache)
87
89
 
@@ -165,7 +167,8 @@ describe('DefermentManager', () => {
165
167
  const add = vi.fn()
166
168
  const mockCache = {
167
169
  get,
168
- add
170
+ add,
171
+ dispose: vi.fn()
169
172
  } as unknown as MemoryCache
170
173
  const defermentManager = new DefermentManager(mockLogger, mockCache)
171
174
  const requestItem = vi.fn()
@@ -189,7 +192,8 @@ describe('DefermentManager', () => {
189
192
  const add = vi.fn()
190
193
  const mockCache = {
191
194
  get,
192
- add
195
+ add,
196
+ dispose: vi.fn()
193
197
  } as unknown as MemoryCache
194
198
  const defermentManager = new DefermentManager(mockLogger, mockCache)
195
199
 
@@ -205,7 +209,8 @@ describe('DefermentManager', () => {
205
209
  const add = vi.fn()
206
210
  const mockCache = {
207
211
  get,
208
- add
212
+ add,
213
+ dispose: vi.fn()
209
214
  } as unknown as MemoryCache
210
215
  const defermentManager = new DefermentManager(mockLogger, mockCache)
211
216
 
@@ -17,7 +17,7 @@ describe('BatchingQueue disposal', () => {
17
17
 
18
18
  await queue.disposeAsync()
19
19
 
20
- expect(processFunction).not.toHaveBeenCalled()
20
+ expect(processFunction).toHaveBeenCalled()
21
21
  expect(queue.count()).toBe(0)
22
22
  expect(queue.isDisposed()).toBe(true)
23
23
  })
@@ -146,4 +146,125 @@ describe('BatchingQueue', () => {
146
146
  await queue.disposeAsync()
147
147
  }
148
148
  })
149
+
150
+ test('should handle processFunction throwing an exception during flush and is disposed', async () => {
151
+ const errorMessage = 'Process function failed'
152
+ const processFunction = vi.fn().mockRejectedValue(new Error(errorMessage))
153
+
154
+ const queue = new BatchingQueue<{ id: string }>({
155
+ batchSize: 5,
156
+ maxWaitTime: 1000,
157
+ processFunction
158
+ })
159
+
160
+ const items = Array.from({ length: 3 }, (_, i) => ({ id: `item-${i}` }))
161
+ items.forEach((item) => queue.add(item.id, item))
162
+
163
+ expect(queue.count()).toBe(3)
164
+
165
+ // flush should not throw even if processFunction rejects
166
+ await expect(queue.flush()).resolves.not.toThrow()
167
+
168
+ expect(processFunction).toHaveBeenCalled()
169
+ expect(queue.count()).toBe(0)
170
+ expect(queue.isDisposed()).toBe(false)
171
+ expect(queue.isErrored()).toBe(true)
172
+ // Add more items after the exception
173
+ queue.add('key3', { id: `item-3` })
174
+ queue.add('key4', { id: `item-4` })
175
+
176
+ // Wait to see if second batch gets processed (it shouldn't due to errored state)
177
+ await new Promise((resolve) => setTimeout(resolve, 200))
178
+
179
+ expect(queue.count()).toBe(0) // Items were not added due to errored state
180
+ await queue.disposeAsync()
181
+ })
182
+
183
+ test('should drain remaining items when disposed', async () => {
184
+ const processSpy = vi.fn()
185
+ const queue = new BatchingQueue({
186
+ batchSize: 5, // Large batch size to prevent automatic processing
187
+ maxWaitTime: 10000, // Long timeout to prevent timeout-based processing
188
+ processFunction: async (batch: string[]): Promise<void> => {
189
+ await new Promise((resolve) => setTimeout(resolve, 10))
190
+ processSpy(batch)
191
+ }
192
+ })
193
+
194
+ // Add items that won't trigger automatic processing (less than batch size)
195
+ queue.add('key1', 'item1')
196
+ queue.add('key2', 'item2')
197
+ queue.add('key3', 'item3')
198
+
199
+ // Verify items are in queue but haven't been processed yet
200
+ expect(queue.count()).toBe(3)
201
+ expect(processSpy).not.toHaveBeenCalled()
202
+
203
+ // Dispose should drain the remaining items
204
+ await queue.disposeAsync()
205
+
206
+ // Verify all items were processed during disposal
207
+ expect(processSpy).toHaveBeenCalledTimes(1)
208
+ expect(processSpy).toHaveBeenCalledWith(['item1', 'item2', 'item3'])
209
+ expect(queue.count()).toBe(0)
210
+ expect(queue.isDisposed()).toBe(true)
211
+ })
212
+
213
+ test('should drain items even with ongoing processing during dispose', async () => {
214
+ const processSpy = vi.fn()
215
+ let firstBatchStarted = false
216
+ let allowFirstBatchToComplete: (() => void) | null = null
217
+
218
+ const queue = new BatchingQueue({
219
+ batchSize: 2,
220
+ maxWaitTime: 100,
221
+ processFunction: async (batch: string[]): Promise<void> => {
222
+ processSpy(batch)
223
+
224
+ // Make the first batch wait for our signal
225
+ if (!firstBatchStarted) {
226
+ firstBatchStarted = true
227
+ await new Promise<void>((resolve) => {
228
+ allowFirstBatchToComplete = resolve
229
+ })
230
+ } else {
231
+ // Other batches process normally
232
+ await new Promise((resolve) => setTimeout(resolve, 10))
233
+ }
234
+ }
235
+ })
236
+
237
+ // Add first batch that will trigger processing but will be blocked
238
+ queue.add('key1', 'item1')
239
+ queue.add('key2', 'item2')
240
+
241
+ // Wait for first batch to start processing and allowFirstBatchToComplete to be assigned
242
+ await new Promise((resolve) => setTimeout(resolve, 50))
243
+ expect(firstBatchStarted).toBe(true)
244
+ expect(processSpy).toHaveBeenCalledTimes(1)
245
+ expect(allowFirstBatchToComplete).not.toBeNull()
246
+
247
+ // Add more items while first batch is still processing
248
+ queue.add('key3', 'item3')
249
+ queue.add('key4', 'item4')
250
+
251
+ // Verify the additional items are queued
252
+ expect(queue.count()).toBe(2)
253
+
254
+ // Start disposal (this should wait for ongoing processing and then drain)
255
+ const disposePromise = queue.disposeAsync()
256
+
257
+ // Allow the first batch to complete
258
+ allowFirstBatchToComplete!()
259
+
260
+ // Wait for disposal to complete
261
+ await disposePromise
262
+
263
+ // Verify all batches were processed
264
+ expect(processSpy).toHaveBeenCalledTimes(2)
265
+ expect(processSpy).toHaveBeenCalledWith(['item1', 'item2'])
266
+ expect(processSpy).toHaveBeenCalledWith(['item3', 'item4'])
267
+ expect(queue.count()).toBe(0)
268
+ expect(queue.isDisposed()).toBe(true)
269
+ })
149
270
  })
@@ -11,9 +11,10 @@ export default class BatchingQueue<T> {
11
11
  #batchSize: number
12
12
  #processFunction: (batch: T[]) => Promise<void>
13
13
  #timeoutId: ReturnType<typeof setTimeout> | null = null
14
- #isProcessing = false
15
14
 
16
- #disposed = false
15
+ #isProcessing = false
16
+ #isDisposed = false
17
+ #isErrored = false
17
18
  #batchTimeout: number
18
19
 
19
20
  // Helper methods for cross-environment timeout handling
@@ -46,7 +47,8 @@ export default class BatchingQueue<T> {
46
47
  }
47
48
 
48
49
  async disposeAsync(): Promise<void> {
49
- this.#disposed = true
50
+ if (this.#isDisposed) return
51
+ this.#isDisposed = true
50
52
  if (this.#timeoutId) {
51
53
  this.#getClearTimeoutFn()(this.#timeoutId)
52
54
  this.#timeoutId = null
@@ -62,56 +64,54 @@ export default class BatchingQueue<T> {
62
64
  // After any ongoing flush is completed, there might be items in the queue.
63
65
  // We should flush them.
64
66
  if (this.#queue.size > 0) {
65
- await this.#flush()
67
+ await this.flush()
66
68
  }
67
69
  }
68
70
 
69
71
  add(key: string, item: T): void {
70
- if (this.#disposed) return
72
+ if (this.#isDisposed || this.#isErrored) return
71
73
  this.#queue.enqueue(key, item)
72
74
  this.#addCheck()
73
75
  }
74
76
 
75
77
  addAll(keys: string[], items: T[]): void {
76
- if (this.#disposed) return
78
+ if (this.#isDisposed || this.#isErrored) return
77
79
  this.#queue.enqueueAll(keys, items)
78
80
  this.#addCheck()
79
81
  }
80
82
 
81
83
  #addCheck(): void {
82
- if (this.#disposed) return
84
+ if (this.#isDisposed) return
83
85
  if (this.#queue.size >= this.#batchSize) {
84
86
  // Fire and forget, no need to await
85
87
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
86
- this.#flush()
88
+ this.flush()
87
89
  } else {
88
90
  if (this.#timeoutId) {
89
91
  this.#getClearTimeoutFn()(this.#timeoutId)
90
92
  }
91
93
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
92
- this.#timeoutId = this.#getSetTimeoutFn()(() => this.#flush(), this.#batchTimeout)
94
+ this.#timeoutId = this.#getSetTimeoutFn()(() => this.flush(), this.#batchTimeout)
93
95
  }
94
96
  }
95
97
 
96
- async #flush(): Promise<void> {
98
+ async flush(): Promise<void> {
97
99
  if (this.#timeoutId) {
98
100
  this.#getClearTimeoutFn()(this.#timeoutId)
99
101
  this.#timeoutId = null
100
102
  }
101
103
 
102
- if (this.#isProcessing || this.#queue.size === 0) {
104
+ if (this.#isErrored || this.#isProcessing || this.#queue.size === 0) {
103
105
  return
104
106
  }
105
107
  this.#isProcessing = true
106
108
 
107
- const batchToProcess = this.#getBatch(this.#batchSize)
108
- if (this.#disposed) return
109
-
110
109
  try {
110
+ const batchToProcess = this.#getBatch(this.#batchSize)
111
111
  await this.#processFunction(batchToProcess)
112
112
  } catch (error) {
113
113
  console.error('Batch processing failed:', error)
114
- this.#disposed = true
114
+ this.#isErrored = true
115
115
  } finally {
116
116
  this.#isProcessing = false
117
117
  }
@@ -127,7 +127,11 @@ export default class BatchingQueue<T> {
127
127
  }
128
128
 
129
129
  isDisposed(): boolean {
130
- return this.#disposed
130
+ return this.#isDisposed
131
+ }
132
+
133
+ isErrored(): boolean {
134
+ return this.#isErrored
131
135
  }
132
136
 
133
137
  #getBatch(batchSize: number): T[] {