{"version":3,"file":"chunk-events.mjs","names":[],"sources":["../../src/errors.ts","../../src/timeout.ts","../../src/events.ts"],"sourcesContent":["//\n// Copyright 2020 DXOS.org\n//\n\nimport { type ObservableProvider } from './observable-value.ts';\n\n// TODO(burdon): Move to debug.\n//  Use: https://nodejs.org/api/errors.html\nexport const toError = (err: any) => (err === undefined || typeof err === 'string' ? new Error(err) : err);\n\nexport class TimeoutError extends Error {\n  constructor(timeout?: number, label?: string) {\n    super(timeout ? `Timeout [${timeout.toLocaleString()}ms]${label === undefined ? '' : `: ${label}`}` : 'Timeout');\n  }\n}\n\nexport interface AsyncEvents<T = any> {\n  onSuccess?(result: T): void;\n  onTimeout?(err: TimeoutError): void;\n  onError(err: any): void;\n}\n\nexport const observableError = (observable: ObservableProvider<AsyncEvents>, err: any) => {\n  if (err instanceof TimeoutError) {\n    observable.callback.onTimeout?.(err);\n  } else {\n    observable.callback.onError(toError(err));\n  }\n};\n","//\n// Copyright 2020 DXOS.org\n//\n\nimport { type Context, ContextDisposedError } from '@dxos/context';\n\nimport { TimeoutError } from './errors.ts';\n\n/**\n * Times out after delay.\n */\nexport const sleep = (ms: number) => {\n  return new Promise<void>((resolve) => {\n    const finish = Date.now() + ms;\n\n    // `setTimeout` does not guarantee execution at >= the scheduled time and may execute slightly early.\n    const sleeper = () => {\n      const delta = finish - Date.now();\n      if (delta > 0) {\n        setTimeout(sleeper, delta);\n      } else {\n        resolve();\n      }\n    };\n\n    sleeper();\n  });\n};\n\n// TODO(burdon): Reconcile with sleep.\nexport const sleepWithContext = (ctx: Context, ms: number) => {\n  const error = new ContextDisposedError();\n  return new Promise<void>((resolve, reject) => {\n    if (ctx.disposed) {\n      reject(error);\n      return;\n    }\n\n    const timeout = setTimeout(() => {\n      clearDispose();\n      resolve();\n    }, ms);\n\n    const clearDispose = ctx.onDispose(() => {\n      clearTimeout(timeout);\n      reject(error);\n    });\n  });\n};\n\n/**\n * Can be used in long-running tasks to let other callbacks be invoked.\n */\nexport const asyncReturn = () => sleep(0);\n\n/**\n * Wait for promise or throw error.\n */\nexport const asyncTimeout = async <T>(promise: Promise<T>, timeout: number, err?: Error | string): Promise<T> => {\n  if (typeof promise === 'function') {\n    throw new Error('First argument must be a promise.');\n  }\n\n  let timeoutId: NodeJS.Timeout;\n  const throwable = err === undefined || typeof err === 'string' ? new TimeoutError(timeout, err) : err;\n  const timeoutPromise = new Promise<T>((resolve, reject) => {\n    timeoutId = setTimeout(() => {\n      reject(throwable);\n    }, timeout);\n\n    unrefTimeout(timeoutId);\n  });\n\n  return await Promise.race([promise, timeoutPromise]).finally(() => {\n    clearTimeout(timeoutId);\n  });\n};\n\n/**\n * In Node.JS, `unref` prevents the timeout from blocking the process from exiting. Not available in browsers.\n * https://nodejs.org/api/timers.html#timeoutunref\n */\nexport const unrefTimeout = (timeoutId: NodeJS.Timeout) => {\n  if (typeof timeoutId === 'object' && 'unref' in timeoutId) {\n    timeoutId.unref();\n  }\n};\n","//\n// Copyright 2020 DXOS.org\n//\n\nimport { Context } from '@dxos/context';\nimport { type MaybePromise } from '@dxos/util';\n\nimport { type CleanupFn } from './cleanup.ts';\n\nexport type Effect = () => CleanupFn | undefined;\n\n/**\n * Effect that's been added to a specific Event.\n */\ninterface MaterializedEffect {\n  effect: Effect;\n  cleanup: CleanupFn | undefined;\n}\n\ninterface EventEmitterLike {\n  on(event: string, cb: (data?: any) => void): void;\n  off(event: string, cb: (data?: any) => void): void;\n}\n\nexport type ListenerOptions = {\n  weak?: boolean;\n  once?: boolean;\n};\n\ntype EventCallback<T> = (data: T) => MaybePromise<void>;\n\n// TODO(dmaretskyi): Remove this once the code is cleaned up.\nconst DO_NOT_ERROR_ON_ASYNC_CALLBACK = true;\n\n/**\n * An EventEmitter variant that does not do event multiplexing and represents a single event.\n *\n * ## Typical usage:\n * ```javascript\n * class Model {\n *   public readonly update = new Event<UpdateData>();\n *   private readonly privateEvent = new Event<void>();\n *\n *   onUpdate(data: UpdateData) {\n *     ...\n *     this.update.emit(data);\n *   }\n * }\n *\n * model.update.on(data => {\n *   ...\n * });\n * ```\n *\n * ## Advantages over traditional EventEmitter:\n * 1. User describes explicitly what events a class has as they are defined as class fields.\n * 2. User can explicitly define event visibility (public, protected, private).\n * 3. Having events as class fields allows the compiler to check for correct event usage.\n * 4. User can type the data that event will be emitting.\n * 5. Uses composition instead of inheritance.\n * 6. Removes the cases where event names intersect when used in cases with inheritance.\n * 7. Remove the need to namespace events when developing a class with events that will be used as a base-class.\n */\n// TODO(burdon): Rename EventSink? (Event is a built-in type).\nexport class Event<T = void> implements ReadOnlyEvent<T> {\n  /**\n   * Wrap objects that have on/off style event emitters.\n   */\n  static wrap<T>(emitter: EventEmitterLike, eventName: string): Event<T> {\n    const event = new Event<T>();\n\n    event.addEffect(() => {\n      const onEvent = (data: any) => event.emit(data);\n      emitter.on(eventName, onEvent);\n      return () => emitter.off(eventName, onEvent);\n    });\n\n    return event;\n  }\n\n  private readonly _listeners = new Set<EventListener<T>>();\n  private readonly _effects = new Set<MaterializedEffect>();\n\n  /**\n   * Emit an event.\n   * In most cases should only be called by the class or entity containing the event.\n   * All listeners are called in order of subscription with persistent ones first.\n   * Listeners are called synchronously in the same stack.\n   * A thrown exception in the listener will stop the event from being emitted to the rest of the listeners.\n   *\n   * @param data param that will be passed to all listeners.\n   */\n  emit(data: T): void {\n    for (const listener of this._listeners) {\n      listener.trigger(data);\n\n      if (listener.once) {\n        this._listeners.delete(listener);\n      }\n    }\n  }\n\n  /**\n   * Emit an event and wait for async listeners to complete.\n   * In most cases should only be called by the class or entity containing the event.\n   * All listeners are called in order of subscription with persistent ones first.\n   * Listeners are called sequentially.\n   *\n   * @param data param that will be passed to all listeners.\n   */\n  async emitAsync(data: T): Promise<void> {\n    for (const listener of this._listeners) {\n      await listener.triggerAsync(data);\n\n      if (listener.once) {\n        this._listeners.delete(listener);\n      }\n    }\n  }\n\n  /**\n   * Register an event listener.\n   * If provided callback was already registered as once-listener, it is made permanent.\n   *\n   * @param callback\n   * @param options.weak If true, the callback will be weakly referenced and will be garbage collected if no other references to it exist.\n   * @returns function that unsubscribes this event listener\n   */\n  on(callback: EventCallback<T>): CleanupFn;\n  on(ctx: Context, callback: EventCallback<T>, options?: ListenerOptions): CleanupFn;\n  on(_ctx: any, _callback?: EventCallback<T>, options?: ListenerOptions): CleanupFn {\n    const [ctx, callback] = _ctx instanceof Context ? [_ctx, _callback] : [new Context(), _ctx];\n    const weak = !!options?.weak;\n    const once = !!options?.once;\n\n    const listener = new EventListener(this, callback, ctx, once, weak);\n\n    this._addListener(listener);\n\n    return () => {\n      this._removeListener(listener);\n    };\n  }\n\n  /**\n   * Unsubscribe this callback from new events. Includes persistent and once-listeners.\n   * NOTE: It is recommended to use `Event.on`'s return value instead.\n   * If the callback is not subscribed this is no-op.\n   *\n   * @param callback\n   */\n  off(callback: (data: T) => void): void {\n    for (const listener of this._listeners) {\n      if (listener.derefCallback() === callback) {\n        this._removeListener(listener);\n      }\n    }\n  }\n\n  /**\n   * Register a callback to be called only once when the next event is emitted.\n   * If this callback is already registered as permanent listener, this is no-op.\n   *\n   * @param callback\n   */\n  once(callback: (data: T) => void): CleanupFn;\n  once(ctx: Context, callback: (data: T) => void): CleanupFn;\n  once(_ctx: any, _callback?: (data: T) => void): CleanupFn {\n    const [ctx, callback] = _ctx instanceof Context ? [_ctx, _callback] : [new Context(), _ctx];\n\n    const listener = new EventListener(this, callback, ctx, true, false);\n\n    this._addListener(listener);\n\n    return () => {\n      this._removeListener(listener);\n    };\n  }\n\n  /**\n   * An async iterator that iterates over events.\n   * This iterator runs indefinitely.\n   */\n  async *[Symbol.asyncIterator](): AsyncIterator<T> {\n    while (true) {\n      yield await new Promise((resolve) => {\n        this.once(resolve);\n      });\n    }\n  }\n\n  /**\n   * Returns a promise that resolves with the first event emitted that matches the provided predicate.\n   *\n   * @param predicate\n   */\n  waitFor(predicate: (data: T) => boolean): Promise<T> {\n    return new Promise((resolve) => {\n      const unsubscribe = this.on((data) => {\n        if (predicate(data)) {\n          unsubscribe();\n          resolve(data);\n        }\n      });\n    });\n  }\n\n  /**\n   * Returns a promise that resolves once a specific number of events was emitted since this method was called.\n   *\n   * @param expectedCount\n   */\n  waitForCount(expectedCount: number): Promise<T> {\n    let count = 0;\n    return this.waitFor(() => ++count === expectedCount);\n  }\n\n  /**\n   * Similar to waitFor, but the promise resolves immediately if the condition is already true.\n   */\n  // TODO(burdon): Should pass event property to predicate.\n  async waitForCondition(predicate: () => boolean): Promise<void> {\n    if (!predicate()) {\n      await this.waitFor(predicate);\n    }\n  }\n\n  /**\n   * Returns the number of persistent listeners.\n   */\n  listenerCount(): number {\n    return this._listeners.size;\n  }\n\n  /**\n   * Add a side effect that will be activated once the event has at least one subscriber.\n   * The provided callback can return a function that will be used to clean up after the last subscriber unsubscribes from the event.\n   * The API is similar to `useEffect` from React.\n   *\n   * ## Example:\n   * ```typescript\n   * event.addEffect(() => {\n   *   // do stuff\n   *   return () => {\n   *     // clean-up\n   *   };\n   * });\n   * ```\n   *\n   * @returns Callback that will remove this effect once called.\n   */\n  addEffect(effect: Effect): CleanupFn {\n    const handle: MaterializedEffect = { effect, cleanup: undefined };\n\n    if (this.listenerCount() > 0) {\n      handle.cleanup = handle.effect();\n    }\n\n    this._effects.add(handle);\n    return () => {\n      // eslint-disable-next-line no-unused-expressions\n      handle.cleanup?.();\n      this._effects.delete(handle);\n    };\n  }\n\n  /**\n   * Triggers an event with at least `timeout` milliseconds between each event.\n   * If the event is triggered more often, the event is delayed until the timeout is reached.\n   * If event is emitted for the first time or event wasn't fired for `timeout` milliseconds,\n   * the event is emitted after `timeout / 8` ms.\n   */\n  // TODO(burdon): Factor out generic function.\n  debounce(timeout = 0): Event<void> {\n    let firing: NodeJS.Timeout | undefined;\n    let lastFired: number | undefined;\n\n    const debouncedEvent = new Event<void>();\n    debouncedEvent.addEffect(() => {\n      const unsubscribe = this.on(() => {\n        if (!firing) {\n          const fireIn = !lastFired || Date.now() - lastFired > timeout ? timeout / 8 : timeout;\n          firing = setTimeout(() => {\n            lastFired = Date.now();\n            firing = undefined;\n            debouncedEvent.emit();\n          }, fireIn);\n        }\n      });\n\n      return () => {\n        unsubscribe();\n        clearTimeout(firing);\n      };\n    });\n\n    return debouncedEvent;\n  }\n\n  /**\n   * Turn any variant of `Event<T>` into an `Event<void>` discarding the callback parameter.\n   */\n  discardParameter(): Event<void> {\n    return this as any;\n  }\n\n  /**\n   * Pipe the events into another event.\n   * @param event\n   */\n  pipeInto(event: Event<T>): CleanupFn {\n    return this.on((data) => event.emit(data));\n  }\n\n  /**\n   * Overridden to not return implementation details.\n   */\n  toJSON(): { listenerCount: number } {\n    return {\n      listenerCount: this.listenerCount(),\n    };\n  }\n\n  private _addListener(listener: EventListener<T>): void {\n    this._listeners.add(listener);\n\n    if (this.listenerCount() === 1) {\n      this._runEffects();\n    }\n  }\n\n  /**\n   * @internal\n   */\n  _removeListener(listener: EventListener<T>): void {\n    this._listeners.delete(listener);\n    listener.remove();\n\n    if (this.listenerCount() === 0) {\n      this._cleanupEffects();\n    }\n  }\n\n  private _runEffects(): void {\n    for (const handle of this._effects) {\n      handle.cleanup = handle.effect();\n    }\n  }\n\n  private _cleanupEffects(): void {\n    for (const handle of this._effects) {\n      // eslint-disable-next-line no-unused-expressions\n      handle.cleanup?.();\n      handle.cleanup = undefined;\n    }\n  }\n}\n\n/**\n * A version of Event class which only has subscribe methods.\n * Useful in cases where you want to explicitly prohibit calling `emit` method.\n */\nexport interface ReadOnlyEvent<T = void> {\n  /**\n   * Register an event listener.\n   * If provided callback was already registered as once-listener, it is made permanent.\n   *\n   * @param callback\n   * @param options.weak If true, the callback will be weakly referenced and will be garbage collected if no other references to it exist.\n   * @returns function that unsubscribes this event listener\n   */\n  on(callback: (data: T) => void): CleanupFn;\n  on(ctx: Context, callback: (data: T) => void, options?: ListenerOptions): CleanupFn;\n\n  /**\n   * Unsubscribes this callback from new events. Includes persistent and once-listeners.\n   * NOTE: It is recommended to us `Event.on`'s return value.\n   * If the callback is not subscribed this is no-op.\n   *\n   * @param callback\n   */\n  off(callback: (data: T) => void): void;\n\n  /**\n   * Register a callback to be called only once when the next event is emitted.\n   * If this callback is already registered as permanent listener, this is no-op.\n   *\n   * @param callback\n   */\n  once(callback: (data: T) => void): CleanupFn;\n\n  /**\n   * An async iterator that iterates over events.\n   * This iterator runs indefinitely.\n   */\n  [Symbol.asyncIterator](): AsyncIterator<T>;\n\n  /**\n   * Returns a promise that resolves with the first event emitted that matches the provided predicate.\n   *\n   * @param predicate\n   */\n  waitFor(predicate: (data: T) => boolean): Promise<T>;\n\n  /**\n   * Returns a promise that resolves once a specific number of events was emitted since this method was called.\n   *\n   * @param expectedCount\n   */\n  waitForCount(expectedCount: number): Promise<T>;\n\n  /**\n   * Turn any variant of `Event<T>` into an `Event<void>` discarding the callback parameter.\n   */\n  discardParameter(): Event<void>;\n\n  /**\n   * Triggers an event with at least `timeout` milliseconds between each event.\n   * If the event is triggered more often, the event is delayed until the timeout is reached.\n   * If event is emitted for the first time or event wasn't fired for `timeout` milliseconds,\n   * the event is emitted after `timeout / 8` ms.\n   */\n  debounce(timeout?: number): Event<void>;\n}\n\nclass EventListener<T> {\n  public readonly callback: EventCallback<T> | WeakRef<EventCallback<T>>;\n\n  private readonly _clearDispose?: () => void = undefined;\n\n  constructor(\n    event: Event<T>,\n    listener: EventCallback<T>,\n    public readonly ctx: Context,\n    public readonly once: boolean,\n    public readonly weak: boolean,\n  ) {\n    this._clearDispose = ctx.onDispose(() => {\n      event._removeListener(this);\n    });\n\n    if (weak) {\n      this.callback = new WeakRef(listener);\n      weakListeners().registry?.register(\n        listener,\n        {\n          event: new WeakRef(event),\n          listener: this,\n        },\n        this,\n      );\n    } else {\n      this.callback = listener;\n    }\n  }\n\n  derefCallback(): EventCallback<T> | undefined {\n    return this.weak ? (this.callback as WeakRef<EventCallback<T>>).deref() : (this.callback as EventCallback<T>);\n  }\n\n  trigger(data: T): void {\n    let result!: MaybePromise<void>;\n    try {\n      const callback = this.derefCallback();\n      result = callback?.(data);\n    } catch (err: any) {\n      this.ctx.raise(err);\n    }\n\n    if (!DO_NOT_ERROR_ON_ASYNC_CALLBACK) {\n      if (result instanceof Promise) {\n        throw new TypeError('Event has async callbacks, use emitAsync instead');\n      }\n    }\n  }\n\n  async triggerAsync(data: T): Promise<void> {\n    try {\n      const callback = this.derefCallback();\n      await callback?.(data);\n    } catch (err: any) {\n      this.ctx.raise(err);\n    }\n  }\n\n  remove(): void {\n    this._clearDispose?.();\n    weakListeners().registry?.unregister(this);\n  }\n}\n\ntype HeldValue = {\n  event: WeakRef<Event<any>>;\n  listener: EventListener<any>;\n};\n\nlet weakListenersState: FinalizationRegistry<HeldValue> | null = null;\n\ntype WeakListeners = {\n  registry: FinalizationRegistry<HeldValue> | undefined;\n};\n\nconst FINALIZATION_REGISTRY_SUPPORTED = !!globalThis.FinalizationRegistry;\n\nconst weakListeners = (): WeakListeners => {\n  if (!FINALIZATION_REGISTRY_SUPPORTED) {\n    return { registry: undefined };\n  }\n  weakListenersState ??= new FinalizationRegistry(({ event, listener }) => {\n    event.deref()?._removeListener(listener);\n  });\n  return { registry: weakListenersState };\n};\n"],"mappings":"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"}