Member Junction
    Preparing search index...

    Writes structured progress artifacts to <rootDir>/<runID>/:

    • manifest.json (written once at start)
    • progress.jsonl (append-only event stream; checkpoint events carry resumableState)
    • result.json (written once at terminate)

    Sequence numbers monotonic per emitter instance. Disk I/O is async and serialized via an internal promise chain — callers don't await; the emitter guarantees ordered writes. A flush() method awaits the queue when needed (test teardown, run completion).

    Index

    Constructors

    Accessors

    Methods

    • Terminate the run as CANCELLED (a user/system abort stopped it mid-flight, not a failure and not a clean completion). Emits exitReason='aborted' so a cancelled run is distinguishable from one that finished — the persisted CompanyIntegrationRun has no 'Cancelled' status, so the artifact's ExitReason is the GQL-visible signal that the run was stopped early (partial state is still durable).

      Parameters

      • Optionalmessage: string

      Returns Promise<void>

    • Parameters

      • stage: string
      • message: string
      • Optionalcounts: {
            failed?: number;
            processed?: number;
            skipped?: number;
            succeeded?: number;
            totalKnown?: number;
        }

      Returns void

      Use Heartbeat.

    • Parameters

      • stage: string
      • message: string
      • Optionalcounts: {
            failed?: number;
            processed?: number;
            skipped?: number;
            succeeded?: number;
            totalKnown?: number;
        }

      Returns void

    • Announce that this process picked a killed run back up. Emits the already-declared 'run.resumed' event carrying the already-declared 'Restart' trigger type — deliberately NOT a new event type, and deliberately in the event's data rather than on the manifest, because the manifest must not be rewritten (see Resume).

      resumedFromSeq is the sequence the pre-restart process reached; a client can use it to tell "these events are the continuation" from "these are a fresh run".

      Parameters

      • Optionalmessage: string
      • Optionaldata: Record<string, unknown>

      Returns void

    • Parameters

      • stage: string
      • Optionalcounts: {
            failed?: number;
            processed?: number;
            skipped?: number;
            succeeded?: number;
            totalKnown?: number;
        }
      • Optionaldata: Record<string, unknown>

      Returns void

      Use StageComplete.

    • counts is the canonical quartet the reader aggregates. data carries anything a specific stage needs to survive that is not part of it — notably the CREATED vs UPDATED split, which the quartet folds into succeeded and which history has to show separately (plan.md: "Synced is different between created and updated").

      Parameters

      • stage: string
      • Optionalcounts: {
            failed?: number;
            processed?: number;
            skipped?: number;
            succeeded?: number;
            totalKnown?: number;
        }
      • Optionaldata: Record<string, unknown>

      Returns void

    • Emit a non-fatal warning. Carries a structured {stage, code, message, data} payload that the reader aggregates into the run result's warnings[] rollup. Unlike stageError, a warning never fails the run.

      Parameters

      • stage: string
      • code: string
      • message: string
      • Optionaldata: Record<string, unknown>

      Returns void

    • Re-attach to an existing, still-in-flight run and continue writing to its artifacts.

      Why this exists: the RSU pipeline restarts the API process as one of its own steps. The emitter dies mid-run, its run.end handler never fires, and the run stays flagged in-flight forever. The work that finishes the pipeline then happens in a NEW process, which — without this — could only open a brand-new run, invisible to every client already tailing the old one (the reader returns strictly seq > cursor, and a fresh emitter restarts at 1, so those events sort BELOW the client's cursor and are unrecoverable through that interface; worse, the resolver echoes the unchanged cursor back and the client polls forever receiving nothing).

      Three invariants make it safe:

      1. The manifest is preserved, never rewritten. The normal write is truncate-or-create, and the reader treats a missing/unparseable manifest as "run does not exist" — so a concurrent read during that write makes the run VANISH rather than degrade.
      2. The sequence continues from the journal's last line, so a tailing client's cursor keeps advancing and it sees the post-restart events.
      3. A run that already has a result.json is refused, so a terminal record can never be written twice or overwritten by a late re-attachment.

      The append-only journal is what makes all of this possible: it is never truncated, so its last line is an authoritative high-water mark for the sequence.

      Parameters

      Returns Promise<IntegrationProgressEmitter>

      when the run has no manifest, or is already terminal.

    • Register (or clear, with no arg) the global publish hook. The server registers this at startup so every emitted event also fans out to the live GraphQL subscription, in addition to the durable JSONL artifact + the pollable tail query.

      Parameters

      • Optionalhook: IntegrationProgressPublishHook

      Returns void