import {
  FieldDiffSchema
} from "./chunk-SQDOBLBP.js";
import {
  __decorateClass
} from "./chunk-2E224ZSN.js";

// runtime/subsystems/integration/integration-run-recorder.memory-backend.ts
import { Injectable } from "@nestjs/common";
var MemoryRunRecorder = class {
  /**
   * All started runs keyed by id. Public so tests can inspect lifecycle
   * transitions without poking through recording methods.
   */
  runs = /* @__PURE__ */ new Map();
  /**
   * Items keyed by `integration_run_id`, array order matches insertion order —
   * mirrors the timeline the `(integration_run_id, created_at)` index produces
   * in Postgres.
   */
  items = /* @__PURE__ */ new Map();
  /**
   * Seedable subscription metadata — tests populate this to make
   * `listRecent` return meaningful `connectionId` values. The memory
   * backend doesn't track subscriptions on its own (only runs + items), so
   * this map is the intentional extension point: tests write entries for
   * the subscription ids they use, production code never touches it.
   */
  subscriptions = /* @__PURE__ */ new Map();
  async startRun(input) {
    const id = crypto.randomUUID();
    this.runs.set(id, {
      id,
      subscriptionId: input.subscriptionId,
      direction: input.direction,
      action: input.action,
      status: "running",
      cursorBefore: input.cursorBefore ?? null,
      cursorAfter: null,
      recordsFound: 0,
      recordsProcessed: 0,
      durationMs: null,
      error: null,
      tenantId: input.tenantId ?? null,
      startedAt: /* @__PURE__ */ new Date(),
      completedAt: null
    });
    this.items.set(id, []);
    return { id };
  }
  async recordItem(input) {
    FieldDiffSchema.parse(input.changedFields);
    const bucket = this.items.get(input.integrationRunId);
    if (!bucket) {
      throw new Error(
        `MemoryRunRecorder.recordItem: no run started for id '${input.integrationRunId}'. Call startRun(...) first.`
      );
    }
    bucket.push(input);
  }
  async completeRun(runId, input) {
    const run = this.runs.get(runId);
    if (!run) {
      throw new Error(
        `MemoryRunRecorder.completeRun: no run started for id '${runId}'.`
      );
    }
    run.status = input.status;
    run.recordsFound = input.recordsFound;
    run.recordsProcessed = input.recordsProcessed;
    run.cursorAfter = input.cursorAfter ?? null;
    run.durationMs = input.durationMs;
    run.error = input.error ?? null;
    run.completedAt = /* @__PURE__ */ new Date();
  }
  async listRecent(limit, subscriptionId, _tenantId) {
    const all = Array.from(this.runs.values());
    const filtered = subscriptionId === void 0 ? all : all.filter((r) => r.subscriptionId === subscriptionId);
    return filtered.sort((a, b) => b.startedAt.getTime() - a.startedAt.getTime()).slice(0, limit).map((r) => ({
      id: r.id,
      subscriptionId: r.subscriptionId,
      // connectionId is only knowable if the test seeded subscriptions
      // metadata; empty string otherwise. The Drizzle backend resolves
      // it via JOIN, which is the production path.
      connectionId: this.subscriptions.get(r.subscriptionId)?.connectionId ?? "",
      status: r.status,
      startedAt: r.startedAt,
      completedAt: r.completedAt,
      recordsProcessed: r.recordsProcessed,
      tenantId: r.tenantId
    }));
  }
  /** Reset state. Tests call this in `beforeEach`. */
  clear() {
    this.runs.clear();
    this.items.clear();
    this.subscriptions.clear();
  }
  // ─── test ergonomics ─────────────────────────────────────────────────
  /** All runs for a subscription, newest first. Timeline reads. */
  getRunsForSubscription(subscriptionId) {
    return Array.from(this.runs.values()).filter((r) => r.subscriptionId === subscriptionId).sort((a, b) => b.startedAt.getTime() - a.startedAt.getTime());
  }
  /** All item rows for a run, insertion-ordered. */
  getItemsForRun(runId) {
    return this.items.get(runId) ?? [];
  }
};
MemoryRunRecorder = __decorateClass([
  Injectable()
], MemoryRunRecorder);

export {
  MemoryRunRecorder
};
//# sourceMappingURL=chunk-EO2QPOKH.js.map