@salesforce/lds-utils-adapters 1.110.1 → 1.111.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.
@@ -1,6 +1,7 @@
1
+ import { LdsAbortController } from './LdsAbortController';
1
2
  export interface Work<T> {
2
- workFn: () => Promise<T>;
3
- cancelFn?: () => Promise<void>;
3
+ workFn: (abortController: LdsAbortController) => Promise<T>;
4
+ cancelFn?: () => void;
4
5
  }
5
6
  export declare class AsyncWorkerPool {
6
7
  private concurrency;
@@ -8,6 +9,10 @@ export declare class AsyncWorkerPool {
8
9
  private activeWork;
9
10
  constructor(concurrency: number);
10
11
  push<T>(work: Work<T>): Promise<T>;
11
- cancel(): Promise<void>;
12
+ /**
13
+ * cancel all work in the queue and active work
14
+ * @returns true if all work was cancelled, false if any work could not be cancelled
15
+ */
16
+ cancel(): boolean;
12
17
  private doWork;
13
18
  }
@@ -0,0 +1,16 @@
1
+ type EventListener = (signal: AbortSignal, event: Event) => void;
2
+ export declare class LdsAbortController {
3
+ readonly signal: AbortSignal;
4
+ constructor();
5
+ abort(): void;
6
+ }
7
+ declare class AbortSignal {
8
+ private _aborted;
9
+ get aborted(): boolean;
10
+ private listeners;
11
+ addEventListener(type: 'abort', listener: EventListener): void;
12
+ removeEventListener(type: 'abort', listener: EventListener): void;
13
+ private dispatchEvent;
14
+ abort(): void;
15
+ }
16
+ export {};
@@ -303,6 +303,58 @@ function runAdapterWithReport(adapterName, adapter, adapterConfig, requestContex
303
303
  }
304
304
  }
305
305
 
306
+ /* Ideally we would use AbortController but it does not exist in V8, if it is ever polyfilled we can swap for it */
307
+ class LdsAbortController {
308
+ constructor() {
309
+ this.signal = new AbortSignal();
310
+ }
311
+ abort() {
312
+ this.signal.abort();
313
+ }
314
+ }
315
+ class AbortSignal {
316
+ constructor() {
317
+ this._aborted = false;
318
+ this.listeners = new Map();
319
+ }
320
+ get aborted() {
321
+ return this._aborted;
322
+ }
323
+ addEventListener(type, listener) {
324
+ let listeners = this.listeners.get(type);
325
+ if (!listeners) {
326
+ listeners = new Set();
327
+ this.listeners.set(type, listeners);
328
+ }
329
+ listeners.add(listener);
330
+ }
331
+ removeEventListener(type, listener) {
332
+ const listeners = this.listeners.get(type);
333
+ if (listeners) {
334
+ listeners.delete(listener);
335
+ if (listeners.size === 0) {
336
+ this.listeners.delete(type);
337
+ }
338
+ }
339
+ }
340
+ dispatchEvent(event) {
341
+ const listeners = this.listeners.get(event.type);
342
+ if (listeners) {
343
+ for (const listener of listeners) {
344
+ listener(this, event);
345
+ }
346
+ }
347
+ return !event.defaultPrevented;
348
+ }
349
+ abort() {
350
+ if (!this.aborted) {
351
+ this._aborted = true;
352
+ const abortEvent = new Event('abort');
353
+ this.dispatchEvent(abortEvent);
354
+ }
355
+ }
356
+ }
357
+
306
358
  class AsyncWorkerPool {
307
359
  constructor(concurrency) {
308
360
  this.queue = [];
@@ -313,51 +365,57 @@ class AsyncWorkerPool {
313
365
  return new Promise((resolve, reject) => {
314
366
  this.queue.push({
315
367
  ...work,
316
- workFn: () => work.workFn().then(resolve).catch(reject),
368
+ workFn: (abortController) => work.workFn(abortController).then(resolve).catch(reject),
317
369
  });
318
370
  this.doWork();
319
371
  });
320
372
  }
321
- async cancel() {
322
- const promises = [];
323
- const cancellingWork = [
324
- ...this.activeWork.splice(0, this.activeWork.length),
325
- ...this.queue.splice(0, this.queue.length),
326
- ];
327
- cancellingWork.forEach((work) => {
328
- const { cancelFn } = work;
373
+ /**
374
+ * cancel all work in the queue and active work
375
+ * @returns true if all work was cancelled, false if any work could not be cancelled
376
+ */
377
+ cancel() {
378
+ let success = true;
379
+ for (const { cancelFn } of this.queue) {
329
380
  if (cancelFn) {
330
- promises.push(cancelFn());
381
+ try {
382
+ cancelFn();
383
+ }
384
+ catch (_a) {
385
+ success = false;
386
+ }
331
387
  }
332
- });
333
- await promiseAllSettled(promises);
388
+ }
389
+ this.queue = [];
390
+ for (const { abortController, cancelFn } of this.activeWork) {
391
+ abortController.abort();
392
+ if (cancelFn) {
393
+ try {
394
+ cancelFn();
395
+ }
396
+ catch (_b) {
397
+ success = false;
398
+ }
399
+ }
400
+ }
401
+ this.activeWork = [];
402
+ return success;
334
403
  }
335
404
  doWork() {
336
405
  while (this.queue.length > 0 && this.activeWork.length < this.concurrency) {
337
406
  const work = this.queue.shift();
338
407
  if (work) {
339
- this.activeWork.push(work);
408
+ const abortController = new LdsAbortController();
409
+ const newWork = { ...work, abortController };
410
+ this.activeWork.push(newWork);
340
411
  const { workFn } = work;
341
- workFn()
342
- .then()
343
- .finally(() => {
344
- this.activeWork = this.activeWork.filter((w) => w !== work);
412
+ workFn(abortController).finally(() => {
413
+ this.activeWork = this.activeWork.filter((w) => w !== newWork);
345
414
  this.doWork();
346
415
  });
347
416
  }
348
417
  }
349
418
  }
350
- }
351
- function promiseAllSettled(promises) {
352
- return Promise.all(promises.map((promise) => promise
353
- .then((value) => ({
354
- status: 'fulfilled',
355
- value,
356
- }))
357
- .catch((reason) => ({
358
- status: 'rejected',
359
- reason,
360
- }))));
361
419
  }
362
420
 
363
- export { AsyncWorkerPool, runAdapterWithReport };
421
+ export { AsyncWorkerPool, LdsAbortController, runAdapterWithReport };
package/dist/main.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { runAdapterWithReport } from './runAdapterWithReport';
2
2
  export { AdapterReport } from './AdapterReport';
3
3
  export { AsyncWorkerPool } from './AsyncWorkerPool';
4
+ export { LdsAbortController } from './LdsAbortController';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-utils-adapters",
3
- "version": "1.110.1",
3
+ "version": "1.111.0",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "LDS Adapter Utilities",
6
6
  "main": "dist/ldsAdapterUtils.js",
@@ -26,6 +26,6 @@
26
26
  "test:unit": "jest"
27
27
  },
28
28
  "devDependencies": {
29
- "@luvio/engine": "0.135.4"
29
+ "@luvio/engine": "0.136.5"
30
30
  }
31
31
  }