{"version":3,"file":"rx-angular-cdk-coalescing.mjs","sources":["../../../../libs/cdk/coalescing/src/lib/coalescingManager.ts","../../../../libs/cdk/coalescing/src/lib/coalesceWith.ts","../../../../libs/cdk/coalescing/src/rx-angular-cdk-coalescing.ts"],"sourcesContent":["interface CoalescingContextProps extends Record<string, unknown> {\n  numCoalescingSubscribers: number;\n}\n\nexport interface CoalescingManager {\n  remove: (scope: Record<string, unknown>) => void;\n  add: (scope: Record<string, unknown>) => void;\n  isCoalescing: (scope: Record<string, unknown>) => boolean;\n}\n\nexport const coalescingManager: CoalescingManager = createCoalesceManager();\ntype KeyOf<O> = keyof O;\ntype ValueOf<O> = O[keyof O];\nfunction hasKey<O>(ctx: O, property: KeyOf<O>): ctx is O {\n  return ctx[property] != null;\n}\n/*\n * createPropertiesWeakMap\n *\n * @param getDefaults: (o: O) => P\n * Example:\n *\n * export interface Properties {\n *   isCoalescing: boolean;\n * }\n *\n * const obj: object = {\n *   foo: 'bar',\n *   isCoalescing: 'weakMap version'\n * };\n *\n * const getDefaults = (ctx: object): Properties => ({isCoalescing: false});\n * const propsMap = createPropertiesWeakMap<object, Properties>(getDefaults);\n *\n * console.log('obj before:', obj);\n * // {foo: \"bar\", isCoalescing: \"weakMap version\"}\n * console.log('props before:', propsMap.getProps(obj));\n * // {isCoalescing: \"weakMap version\"}\n *\n * propsMap.setProps(obj, {isCoalescing: true});\n * console.log('obj after:', obj);\n * // {foo: \"bar\", isCoalescing: \"weakMap version\"}\n * console.log('props after:', propsMap.getProps(obj));\n * // {isCoalescing: \"true\"}\n * */\nfunction createPropertiesWeakMap<\n  O extends Record<string, unknown>,\n  P extends O\n>(getDefaults: (o: O) => P) {\n  type K = KeyOf<P>;\n  const propertyMap = new WeakMap<O, P>();\n\n  return {\n    getProps: getProperties,\n    setProps: setProperties,\n  };\n\n  function getProperties(ctx: O): P {\n    const defaults = getDefaults(ctx);\n    const propertiesPresent: P | undefined = propertyMap.get(ctx);\n    let properties: P;\n\n    if (propertiesPresent !== undefined) {\n      properties = propertiesPresent as P;\n    } else {\n      properties = {} as P;\n\n      (Object.entries(defaults) as unknown[]).forEach(\n        ([prop, value]: [KeyOf<P>, ValueOf<P>]): void => {\n          if (hasKey(ctx as P, prop)) {\n            properties[prop] = (ctx as P)[prop];\n          } else {\n            properties[prop] = value;\n          }\n        }\n      );\n\n      propertyMap.set(ctx, properties);\n    }\n    return properties;\n  }\n\n  function setProperties(ctx: O, props: Partial<P>): P {\n    const properties: P = getProperties(ctx);\n    (Object.entries(props) as [K, P[K]][]).forEach(([prop, value]) => {\n      properties[prop] = value;\n    });\n    propertyMap.set(ctx, properties);\n    return properties;\n  }\n}\n\nconst coalescingContextPropertiesMap = createPropertiesWeakMap<\n  Record<string, unknown>,\n  CoalescingContextProps\n>((ctx) => ({\n  numCoalescingSubscribers: 0,\n}));\n/**\n * @describe createCoalesceManager\n *\n * returns a\n * Maintains a weak map of component references ans flags\n * them if the coalescing process is already started for them.\n *\n * Used in render aware internally.\n */\nfunction createCoalesceManager(): CoalescingManager {\n  return {\n    remove: removeWork,\n    add: addWork,\n    isCoalescing,\n  };\n\n  // Increments the number of subscriptions in a scope e.g. a class instance\n  function removeWork(scope: Record<string, unknown>): void {\n    const numCoalescingSubscribers =\n      coalescingContextPropertiesMap.getProps(scope).numCoalescingSubscribers -\n      1;\n    coalescingContextPropertiesMap.setProps(scope, {\n      numCoalescingSubscribers:\n        numCoalescingSubscribers >= 0 ? numCoalescingSubscribers : 0,\n    });\n  }\n\n  // Decrements the number of subscriptions in a scope e.g. a class instance\n  function addWork(scope: Record<string, unknown>): void {\n    const numCoalescingSubscribers =\n      coalescingContextPropertiesMap.getProps(scope).numCoalescingSubscribers +\n      1;\n    coalescingContextPropertiesMap.setProps(scope, {\n      numCoalescingSubscribers,\n    });\n  }\n\n  // Checks if anybody else is already coalescing atm\n  function isCoalescing(scope: Record<string, unknown>): boolean {\n    return (\n      coalescingContextPropertiesMap.getProps(scope).numCoalescingSubscribers >\n      0\n    );\n  }\n}\n","import {\n  MonoTypeOperatorFunction,\n  Observable,\n  Observer,\n  Subscriber,\n  Subscription,\n  Unsubscribable,\n} from 'rxjs';\nimport { coalescingManager } from './coalescingManager';\n\n/**\n * @description\n * Limits the number of synchronous emitted a value from the source Observable to\n * one emitted value per\n *   durationSelector e.g. [`AnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame), then repeats\n * this process for every tick of the browsers event loop.\n *\n * The coalesce operator is based on the [throttle](https://rxjs-dev.firebaseapp.com/api/operators/throttle) operator.\n * In addition to that is provides emitted values for the trailing end only, as well as maintaining a context to scope\n *   coalescing.\n *\n * @param {function(value: T): Observable} durationSelector - A function\n * that receives a value from the source Observable, for computing the silencing\n * duration for each source value, returned as an Observable or a Promise.\n * It defaults to `requestAnimationFrame` as durationSelector.\n * @param scope\n * Defaults to `{ leading: false, trailing: true }`. The default scoping is per subscriber.\n * @return {Observable<T>} An Observable that performs the coalesce operation to\n * limit the rate of emissions from the source.\n *\n * @usageNotes\n * Emit clicks at a rate of at most one click per second\n * ```typescript\n * import { interval, fromEvent } from 'rxjs';\n * import { coalesceWith } from '@rx-angular/cdk/coalescing';\n *\n * const setTimeoutDurationSelector = interval(500);\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(coalesceWith(setTimeoutDurationSelector));\n * result.subscribe(x => console.log(x));\n * ```\n */\nexport function coalesceWith<T>(\n  durationSelector: Observable<unknown>,\n  scope?: Record<string, unknown>\n): MonoTypeOperatorFunction<T> {\n  const _scope = scope || {};\n\n  return (source) => {\n    return new Observable<T>((observer) => {\n      const rootSubscription = new Subscription();\n      rootSubscription.add(\n        source.subscribe(createInnerObserver(observer, rootSubscription))\n      );\n      return rootSubscription;\n    });\n\n    function createInnerObserver(\n      outerObserver: Subscriber<T>,\n      rootSubscription: Subscription\n    ): Observer<T> {\n      let actionSubscription: Unsubscribable;\n      let latestValue: T | undefined;\n\n      const tryEmitLatestValue = () => {\n        if (actionSubscription) {\n          // We only decrement the number if it is greater than 0 (isCoalescing)\n          coalescingManager.remove(_scope);\n          if (!coalescingManager.isCoalescing(_scope)) {\n            outerObserver.next(latestValue);\n          }\n        }\n      };\n      return {\n        complete: () => {\n          tryEmitLatestValue();\n          outerObserver.complete();\n        },\n        error: (error) => outerObserver.error(error),\n        next: (value) => {\n          latestValue = value;\n          if (!actionSubscription) {\n            coalescingManager.add(_scope);\n            actionSubscription = durationSelector.subscribe({\n              error: (error) => outerObserver.error(error),\n              next: () => {\n                tryEmitLatestValue();\n                actionSubscription?.unsubscribe();\n                actionSubscription = undefined;\n              },\n              complete: () => {\n                tryEmitLatestValue();\n                actionSubscription = undefined;\n              },\n            });\n            rootSubscription.add(\n              new Subscription(() => {\n                tryEmitLatestValue();\n                actionSubscription?.unsubscribe();\n                actionSubscription = undefined;\n              })\n            );\n          }\n        },\n      };\n    }\n  };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}