{"version":3,"sources":["../../../src/audit/events.ts","/home/runner/work/equipped/equipped/dist/cjs/audit/events.cjs"],"names":[],"mappings":"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","file":"/home/runner/work/equipped/equipped/dist/cjs/audit/events.cjs","sourcesContent":["import { type Pipe, type PipeInput, type PipeOutput, v } from 'valleyed'\n\nimport { Conditions, Db, type Table, wrapQueryParams } from '../dbs'\nimport { EquippedError } from '../errors'\nimport { Instance } from '../instance'\n\nexport type EventDefinition<P extends Pipe<any, any>, R> = {\n\tpipe: P\n\thandle: (payload: PipeOutput<P>, context: EventContext) => R | Promise<R>\n\tsync?: (result: R, payload: PipeOutput<P>, context: EventContext) => void\n\tasync?: (result: R, payload: PipeOutput<P>, context: EventContext) => void\n}\n\nexport type EventContext = {\n\tkey: string\n\tby: string | undefined\n\tat: Date\n\tfirstRun: boolean\n}\n\nexport type EventDoc = {\n\tkey: string\n\tname: string\n\tts: number\n\tbody: unknown\n\tsteps: { status: 'start' | 'sync' | 'async'; ts: number }[]\n\tby?: string\n}\ntype Context = Partial<Pick<EventContext, 'by' | 'at'>>\n\nfunction createStep(step: EventDoc['steps'][number]) {\n\treturn step\n}\n\nexport class EventAudit {\n\tprivate table: Table<any, EventDoc, EventDoc & { toJSON: () => Record<string, unknown> }, any>\n\tprivate definitions: Record<string, EventDefinition<any, any>> = {}\n\tprivate asyncQueue: (() => Promise<void>)[] = []\n\n\tconstructor(\n\t\tprivate db: Db<any>,\n\t\tdbName: string,\n\t) {\n\t\tthis.table = db.use({\n\t\t\tdb: dbName,\n\t\t\tcol: '__audits',\n\t\t\tmapper: (model) => ({ ...model, toJSON: () => model as Record<string, unknown> }),\n\t\t\toptions: { skipAudit: true },\n\t\t})\n\n\t\tInstance.on(\n\t\t\t'start',\n\t\t\t() => {\n\t\t\t\tsetInterval(async () => {\n\t\t\t\t\tconst queue = [...this.asyncQueue]\n\t\t\t\t\tthis.asyncQueue = []\n\t\t\t\t\tawait Promise.all(queue.map((job) => job()))\n\t\t\t\t}, 200)\n\t\t\t},\n\t\t\t4,\n\t\t)\n\t}\n\n\tasync #createEvent(name: string, payload: unknown, context: Context) {\n\t\tconst def = this.definitions[name]\n\t\tif (!def) throw new EquippedError('audit definition not found', { name, payload })\n\n\t\tconst validBody = v.assert(def.pipe, payload)\n\t\tconst ts = context.at ?? new Date()\n\t\tconst key = Instance.createId({ time: ts })\n\n\t\treturn await this.table.insertOne(\n\t\t\t{\n\t\t\t\tkey,\n\t\t\t\tname,\n\t\t\t\tts: ts.getTime(),\n\t\t\t\tbody: validBody,\n\t\t\t\tby: context.by,\n\t\t\t\tsteps: [],\n\t\t\t},\n\t\t\t{ getTime: () => ts, makeId: () => key },\n\t\t)\n\t}\n\n\tasync #processEvent<R>(event: EventDoc, firstRun: boolean) {\n\t\treturn this.db.session(async () => {\n\t\t\tconst def = this.definitions[event.name]\n\t\t\tif (!def) throw new EquippedError('audit definition not found', { event })\n\t\t\tawait this.table.updateOne({ key: event.key }, { $set: { steps: [createStep({ status: 'start', ts: Date.now() })] } })\n\t\t\tconst context: EventContext = {\n\t\t\t\tkey: event.key,\n\t\t\t\tby: event.by,\n\t\t\t\tat: new Date(event.ts),\n\t\t\t\tfirstRun,\n\t\t\t}\n\t\t\tconst result = await def.handle(event.body, context)\n\t\t\tawait def.sync?.(result, event.body, context)\n\t\t\tawait this.table.updateOne({ key: event.key }, { $push: { steps: createStep({ status: 'sync', ts: Date.now() }) } })\n\n\t\t\tconst asyncHandle = async () => {\n\t\t\t\tawait def.async?.(result, event.body, context)\n\t\t\t\tawait this.table.updateOne({ key: event.key }, { $push: { steps: createStep({ status: 'async', ts: Date.now() }) } })\n\t\t\t}\n\t\t\tif (!context.firstRun) await asyncHandle()\n\t\t\telse this.asyncQueue.push(asyncHandle)\n\t\t\treturn result as R\n\t\t})\n\t}\n\n\tasync replay(from?: Date) {\n\t\tconst { results: events } = await this.table.query(\n\t\t\twrapQueryParams({\n\t\t\t\twhere: [...(from ? [{ field: 'ts', value: from.getTime(), condition: Conditions.gte }] : [])],\n\t\t\t\tsort: [{ field: 'ts', desc: false }],\n\t\t\t\tall: true,\n\t\t\t}),\n\t\t)\n\t\tfor (const event of events) await this.#processEvent(event, false)\n\t}\n\n\tasync rerun(key: string) {\n\t\tconst event = await this.table.findOne({ key })\n\t\tif (!event) throw new EquippedError('audit event not found', { key })\n\t\tawait this.#processEvent(event, false)\n\t}\n\n\tregister<P extends Pipe<any, any>, R>(name: string, def: EventDefinition<P, R>) {\n\t\tif (this.definitions[name]) throw new EquippedError(`${name} already has a registered handler`, {})\n\t\tthis.definitions[name] = def\n\t\tv.compile(def.pipe)\n\t\treturn async (payload: PipeInput<P>, context: Context) =>\n\t\t\tthis.db.session(async () => {\n\t\t\t\tconst event = await this.#createEvent(name, payload, context)\n\t\t\t\treturn this.#processEvent<R>(event, true)\n\t\t\t})\n\t}\n}\n",null]}