{
  "version": 3,
  "sources": ["../../src/modules/diviner-abstract/AbstractDiviner.ts"],
  "sourcesContent": ["import type {\n  AsTypeFunction, EventUnsubscribeFunction, Logger,\n  Promisable, RetryConfig, RetryConfigWithComplete,\n} from '@ariestools/sdk'\nimport {\n  assertEx,\n  delay,\n  forget,\n  isDefined, isNull, isUndefined, retry,\n} from '@ariestools/sdk'\nimport type {\n  AccountInstance, Payload, QueryBoundWitness,\n  Schema, WithoutPrivateStorageMeta,\n} from '@xyo-network/sdk-protocol'\nimport { PayloadBuilder, QueryBoundWitnessWrapper } from '@xyo-network/sdk-protocol'\n\nimport { isArchivistInstance } from '#archivist-model'\nimport type {\n  AttachableDivinerInstance,\n  DivinerDivineQuery,\n  DivinerDivineResult,\n  DivinerInstance,\n  DivinerModuleEventData,\n  DivinerParams,\n  DivinerQueries,\n} from '#diviner-model'\nimport {\n  DivinerConfigSchema, DivinerDivineQuerySchema, isDivinerInstance,\n} from '#diviner-model'\nimport { AbstractModuleInstance } from '#module-abstract'\nimport {\n  asModuleInstance,\n  type ModuleConfig, type ModuleIdentifier, type ModuleInstance, type ModuleQueryHandlerResult, type ModuleQueryResult,\n} from '#module-model'\nimport { isWitnessInstance } from '#witness-model'\n\nconst delayedResolve = async <T extends ModuleInstance>(\n  parent: ModuleInstance,\n  id: ModuleIdentifier,\n  closure: (mod: T | null) => void,\n  as: AsTypeFunction<T> = asModuleInstance,\n  timeout = 30_000,\n  logger?: Logger,\n) => {\n  const start = Date.now()\n  let result: T | undefined\n  while (isUndefined(result)) {\n    result = as(await parent.resolve(id))\n    if (isDefined(result)) {\n      closure(result)\n      break\n    } else if (Date.now() - start > timeout) {\n      logger?.error(`Timed out waiting for ${id} to resolve`)\n      closure(null)\n    }\n    await delay(500)\n  }\n}\n\nexport abstract class AbstractDiviner<\n  TParams extends DivinerParams = DivinerParams,\n  TIn extends Payload = Payload,\n  TOut extends Payload = Payload,\n  TEventData extends DivinerModuleEventData<DivinerInstance<TParams, TIn, TOut>, TIn, TOut> = DivinerModuleEventData<\n    DivinerInstance<TParams, TIn, TOut>,\n    TIn,\n    TOut\n  >,\n>\n  extends AbstractModuleInstance<TParams, TEventData>\n  implements AttachableDivinerInstance<TParams, TIn, TOut, TEventData> {\n  static override readonly configSchemas: Schema[] = [...super.configSchemas, DivinerConfigSchema]\n  static override readonly defaultConfigSchema: Schema = DivinerConfigSchema\n  static readonly targetSchema: Schema\n\n  private _eventUnsubscribeFunctions: EventUnsubscribeFunction[] = []\n\n  override get queries(): Schema[] {\n    return [DivinerDivineQuerySchema, ...super.queries]\n  }\n\n  /** @function divine The main entry point for a diviner.  Do not override this function.  Implement/override divineHandler for custom functionality */\n  async divine(payloads: TIn[] = [], retryConfigIn?: RetryConfigWithComplete): Promise<DivinerDivineResult<TOut>[]> {\n    this._noOverride('divine')\n    this.isSupportedQuery(DivinerDivineQuerySchema, 'divine')\n    return await this.spanAsync('divine', async () => {\n      if (this.reentrancy?.scope === 'global' && this.reentrancy.action === 'skip' && this.globalReentrancyMutex?.isLocked()) {\n        return []\n      }\n      try {\n        await this.globalReentrancyMutex?.acquire()\n        return await this.busy(async () => {\n          const retryConfig = retryConfigIn ?? this.config.retry\n          await this.startedAsync('throw')\n          await this.emit('divineStart', { inPayloads: payloads, mod: this })\n          let outPayloads: TOut[] = []\n          const errors: Error[] = []\n          try {\n            outPayloads = (retryConfig ? await retry(() => this.divineHandler(payloads), retryConfig) : await this.divineHandler(payloads)) ?? []\n          } catch (ex) {\n            errors.push(ex as Error)\n            this.logger?.error(`Error in divineHandler: ${String(ex)}`)\n          }\n          await this.emit('divineEnd', {\n            errors, inPayloads: payloads, mod: this, outPayloads,\n          })\n          if (errors.length > 0) {\n            throw new Error(`Divine failed with ${errors.length} errors: ${errors.map(e => e.message).join(', ')}`)\n          }\n          return PayloadBuilder.omitPrivateStorageMeta<TOut>(outPayloads)\n        })\n      } finally {\n        this.globalReentrancyMutex?.release()\n      }\n    }, { timeBudgetLimit: 200 })\n  }\n\n  async divineQuery(payloads?: TIn[], account?: AccountInstance, _retry?: RetryConfig): Promise<ModuleQueryResult<TOut>> {\n    this._noOverride('divineQuery')\n    const queryPayload: DivinerDivineQuery = { schema: DivinerDivineQuerySchema }\n    return await this.sendQueryRaw(queryPayload, payloads, account)\n  }\n\n  /** @function queryHandler Calls divine for a divine query.  Override to support additional queries. */\n  protected override async queryHandler<T extends QueryBoundWitness = QueryBoundWitness, TConfig extends ModuleConfig = ModuleConfig>(\n    query: T,\n    payloads?: Payload[],\n    queryConfig?: TConfig,\n  ): Promise<ModuleQueryHandlerResult> {\n    const wrapper = QueryBoundWitnessWrapper.parseQuery<DivinerQueries>(query, payloads)\n    // remove the query payload\n    const cleanPayloads = await PayloadBuilder.filterExclude(payloads, query.query)\n    const queryPayload = await wrapper.getQuery()\n    assertEx(await this.queryable(query, payloads, queryConfig))\n    const resultPayloads: WithoutPrivateStorageMeta<Payload>[] = []\n    switch (queryPayload.schema) {\n      case DivinerDivineQuerySchema: {\n        resultPayloads.push(...(await this.divine(cleanPayloads as TIn[])))\n        break\n      }\n      default: {\n        return super.queryHandler(query, payloads)\n      }\n    }\n    return PayloadBuilder.omitPrivateStorageMeta(resultPayloads)\n  }\n\n  protected override async startHandler(): Promise<void> {\n    const { eventSubscriptions = [] } = this.config\n\n    for (const subscription of eventSubscriptions) {\n      const {\n        sourceEvent, sourceModule, targetModuleFunction,\n      } = subscription\n      if (targetModuleFunction === 'divine') {\n        forget(delayedResolve(this, sourceModule, (sourceModuleInstance: ModuleInstance | null) => {\n          if (isNull(sourceModuleInstance)) {\n            this.logger?.error(`Failed to resolve ${sourceModule} for ${this.modName}`)\n          } else {\n            if (isArchivistInstance(sourceModuleInstance)) {\n              if (sourceEvent === 'inserted') {\n                this._eventUnsubscribeFunctions.push(\n                  sourceModuleInstance.on(sourceEvent, async ({ outPayloads, payloads }) => {\n                    await this.divine((outPayloads ?? payloads) as Payload[] as TIn[])\n                  }),\n                )\n              } else {\n                this.logger?.warn(`Unsupported sourceEvent ${sourceEvent} for ${sourceModuleInstance.modName}`)\n              }\n            } else if (isDivinerInstance(sourceModuleInstance)) {\n              if (sourceEvent === 'divineEnd') {\n                this._eventUnsubscribeFunctions.push(\n                  sourceModuleInstance.on(sourceEvent, async ({ outPayloads }) => {\n                    await this.divine(outPayloads as TIn[])\n                  }),\n                )\n              } else {\n                this.logger?.warn(`Unsupported sourceEvent ${sourceEvent} for ${sourceModuleInstance.modName}`)\n              }\n            } else if (isWitnessInstance(sourceModuleInstance)) {\n              if (sourceEvent === 'observeEnd') {\n                this._eventUnsubscribeFunctions.push(\n                  sourceModuleInstance.on(sourceEvent, async ({ outPayloads }) => {\n                    await this.divine(outPayloads! as TIn[])\n                  }),\n                )\n              } else {\n                this.logger?.warn(`Unsupported sourceEvent ${sourceEvent} for ${sourceModuleInstance.modName}`)\n              }\n            }\n          }\n        }, asModuleInstance, undefined, this.logger))\n      }\n    }\n\n    return await super.startHandler()\n  }\n\n  protected override async stopHandler(): Promise<void> {\n    for (const unsubscribe of this._eventUnsubscribeFunctions) {\n      unsubscribe()\n    }\n    this._eventUnsubscribeFunctions = []\n    this._eventUnsubscribeFunctions = []\n    return await super.stopHandler()\n  }\n\n  /** @function divineHandler Implement or override to add custom functionality to a diviner */\n  protected abstract divineHandler(payloads?: TIn[]): Promisable<TOut[]>\n}\n"],
  "mappings": "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",
  "names": []
}
