{"version":3,"sources":["../../src/emitter/emitter.ts"],"names":["Emitter","Serializable","listeners","groupId","namespace","creator","context","trace","cleanups","input","Object","prototype","assertValidNamespace","register","root","create","child","slice","cleanup","pipe","push","target","on","toBoundedFunction","args","invoke","value","name","isBlocking","once","persistent","matchNested","destroy","length","forEach","reset","filter","listener","options","registerCallbacks","callbacks","entries","key","event","callback","match","matcher","createMatcher","matchers","path","createFullPath","RegExp","test","isPath","EmitterError","matchSameRun","runId","unshift","every","raw","priority","insertIndex","findIndex","l","splice","removeFromArray","emit","assertValidName","createEvent","data","executions","i","run","Promise","all","id","createRandomHash","createdAt","Date","source","assign","shallowCopy","createSnapshot","map","pick","loadSnapshot","snapshot"],"mappings":"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","file":"emitter.cjs","sourcesContent":["/**\n * Copyright 2025 © BeeAI a Series of LF Projects, LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n  Callback,\n  CleanupFn,\n  EmitterOptions,\n  EventMeta,\n  EventTrace,\n  Matcher,\n  MatcherFn,\n  StringKey,\n} from \"@/emitter/types.js\";\nexport type { EventMeta, EventTrace, Callback };\nimport { Cache } from \"@/cache/decoratorCache.js\";\nimport { createFullPath, isPath, assertValidName, assertValidNamespace } from \"@/emitter/utils.js\";\nimport { EmitterError } from \"@/emitter/errors.js\";\nimport { createRandomHash } from \"@/internals/helpers/hash.js\";\nimport { shallowCopy, toBoundedFunction } from \"@/serializer/utils.js\";\nimport { RequiredAll } from \"@/internals/types.js\";\nimport { Serializable } from \"@/internals/serializable.js\";\nimport { pick } from \"remeda\";\nimport { removeFromArray } from \"@/internals/helpers/array.js\";\n\nexport interface EmitterInput<E extends object = object> {\n  groupId?: string;\n  namespace?: string[];\n  creator?: object;\n  context?: E & object;\n  trace?: EventTrace;\n}\nexport interface EmitterChildInput<E extends object = object> {\n  groupId?: string;\n  namespace?: string[];\n  creator?: object;\n  context?: E & object;\n  trace?: EventTrace;\n}\n\ninterface Listener<T = any> {\n  readonly match: MatcherFn;\n  readonly raw: Matcher;\n  readonly callback: Callback<T>;\n  readonly options?: EmitterOptions;\n}\n\nexport class Emitter<T = Record<keyof any, Callback<unknown>>> extends Serializable {\n  protected listeners: Listener[] = [];\n  protected readonly groupId?: string;\n  public readonly namespace: string[];\n  public readonly creator?: object;\n  public readonly context: object;\n  public readonly trace?: EventTrace;\n  protected readonly cleanups: CleanupFn[] = [];\n\n  constructor(input: EmitterInput = {}) {\n    super();\n    this.groupId = input?.groupId;\n    this.namespace = input?.namespace ?? [];\n    this.creator = input.creator ?? Object.prototype;\n    this.context = input?.context ?? {};\n    this.trace = input.trace;\n    assertValidNamespace(this.namespace);\n  }\n\n  static {\n    this.register();\n  }\n\n  @Cache()\n  static get root() {\n    return new Emitter<Record<string, Callback<any>>>({ creator: Object.create(null) });\n  }\n\n  child<R = T>(input: EmitterChildInput = {}): Emitter<R> {\n    const child = new Emitter<R>({\n      trace: input.trace ?? this.trace,\n      groupId: input?.groupId ?? this.groupId,\n      context: { ...this.context, ...input?.context },\n      creator: input?.creator ?? this.creator,\n      namespace: input?.namespace\n        ? [...this.namespace, ...input.namespace]\n        : this.namespace.slice(),\n    });\n\n    const cleanup = child.pipe(this);\n    this.cleanups.push(cleanup);\n\n    return child;\n  }\n\n  pipe(target: Emitter<any>): CleanupFn {\n    return this.on(\n      // @ts-expect-error\n      \"*.*\",\n      toBoundedFunction(\n        // @ts-expect-error\n        (...args) => target.invoke(...args),\n        [{ value: target, name: \"target\" }],\n      ),\n      {\n        isBlocking: true,\n        once: false,\n        persistent: true,\n        matchNested: false,\n      },\n    );\n  }\n\n  destroy() {\n    this.listeners.length = 0;\n    this.cleanups.forEach((child) => child());\n    this.cleanups.length = 0;\n  }\n\n  reset() {\n    this.listeners = this.listeners.filter((listener) => listener.options?.persistent);\n  }\n\n  registerCallbacks<K extends StringKey<RequiredAll<T>>>(\n    callbacks: Partial<\n      Record<K, NonNullable<T[K]> extends Callback<infer X> ? Callback<X> : never>\n    >,\n    options?: Partial<Record<K, EmitterOptions>>,\n  ): CleanupFn {\n    const listeners: CleanupFn[] = [];\n    Object.entries(callbacks).forEach(([key, value]) => {\n      if (value) {\n        // @ts-expect-error\n        listeners.push(this.on(key, value, options?.[key]));\n      }\n    });\n    return () => listeners.forEach((cleanup) => cleanup());\n  }\n\n  on<K extends StringKey<RequiredAll<T>>>(\n    event: K,\n    callback: NonNullable<T[K]> extends Callback<any> ? T[K] : never,\n    options?: EmitterOptions,\n  ): CleanupFn {\n    return this.match(event as Matcher, callback as Callback<any>, options);\n  }\n\n  match<L>(matcher: Matcher, callback: Callback<L>, options?: EmitterOptions): CleanupFn {\n    const createMatcher = (): MatcherFn => {\n      const matchers: MatcherFn[] = [];\n      let matchNested = options?.matchNested;\n\n      if (matcher === \"*\") {\n        matchNested ??= false;\n        matchers.push((event) => event.path === createFullPath(this.namespace, event.name));\n      } else if (matcher === \"*.*\") {\n        matchNested ??= true;\n        matchers.push(() => true);\n      } else if (matcher instanceof RegExp) {\n        matchNested ??= true;\n        matchers.push((event) => matcher.test(event.path));\n      } else if (typeof matcher === \"function\") {\n        matchNested ??= false;\n        matchers.push(matcher);\n      } else if (typeof matcher === \"string\") {\n        if (isPath(matcher)) {\n          matchNested ??= true;\n          matchers.push((event) => event.path === matcher);\n        } else {\n          matchNested ??= false;\n          matchers.push(\n            (event) =>\n              event.name === matcher && event.path === createFullPath(this.namespace, event.name),\n          );\n        }\n      } else {\n        throw new EmitterError(\"Invalid matcher provided!\");\n      }\n\n      if (!matchNested) {\n        const matchSameRun = (event: EventMeta) => {\n          // global observability x scoped observability\n          return !this.trace?.runId ? true : this.trace?.runId === event.trace?.runId;\n        };\n        matchers.unshift(matchSameRun);\n      }\n\n      return (event) => matchers.every((matcher) => matcher(event));\n    };\n\n    const listener: Listener = {\n      options,\n      callback,\n      raw: matcher,\n      match: createMatcher(),\n    };\n\n    const priority = options?.priority ?? 0;\n    const insertIndex = this.listeners.findIndex((l) => (l.options?.priority ?? 0) >= priority);\n    if (insertIndex === -1) {\n      this.listeners.push(listener);\n    } else {\n      this.listeners.splice(insertIndex, 0, listener);\n    }\n\n    return () => {\n      removeFromArray(this.listeners, listener);\n    };\n  }\n\n  async emit<K extends StringKey<RequiredAll<T>>>(\n    name: K,\n    value: NonNullable<T[K]> extends Callback<infer X> ? X : unknown,\n  ): Promise<void> {\n    assertValidName(name);\n\n    const event = this.createEvent(name);\n    return await this.invoke(value, event);\n  }\n\n  protected async invoke(data: unknown, event: EventMeta) {\n    const executions: unknown[] = [];\n    // Iterate in reverse to match Python's behavior (reversed list iteration)\n    for (let i = this.listeners.length - 1; i >= 0; i--) {\n      const listener = this.listeners[i];\n      if (!listener.match(event)) {\n        continue;\n      }\n\n      if (listener.options?.once) {\n        this.listeners.splice(i, 1);\n      }\n\n      const run = async () => listener.callback(data, event);\n      executions.push(listener.options?.isBlocking ? await run() : run());\n    }\n    await Promise.all(executions);\n  }\n\n  protected createEvent(name: string): EventMeta {\n    return {\n      id: createRandomHash(),\n      groupId: this.groupId,\n      name,\n      path: createFullPath(this.namespace, name),\n      createdAt: new Date(),\n      source: this,\n      creator: this.creator!,\n      context: Object.assign({}, this.context, {}),\n      trace: shallowCopy(this.trace), // TODO\n    };\n  }\n\n  createSnapshot() {\n    return {\n      groupId: this.groupId,\n      namespace: shallowCopy(this.namespace),\n      creator: this.creator,\n      context: this.context,\n      trace: this.trace,\n      listeners: this.listeners.map(pick([\"raw\", \"options\", \"callback\"])),\n      cleanups: this.cleanups,\n    };\n  }\n\n  loadSnapshot({ listeners, ...snapshot }: ReturnType<typeof this.createSnapshot>): void {\n    Object.assign(this, snapshot, { listeners: [] });\n    listeners.forEach(({ raw, callback, options }) => this.match(raw, callback, options));\n  }\n}\n"]}