Member Junction
    Preparing search index...

    Generic, abstract base class for any scenario where we want to use a Singleton pattern. This base class abstracts away the complexity of ensuring a truly global singleton instance across multiple code paths in a deployed application. It uses a Global Object Store to ensure that only one instance of the class exists in the application even if the class has code imported into multiple execution paths (which is not optimal, of course, but can occur in some situations).

    Hierarchy (View Summary)

    Index

    Constructors

    Properties

    MaxBatchSize: number = DEFAULT_BATCH_SIZE

    Configurable maximum batch size. Connector batches exceeding this are truncated.

    MaxColumnsPerTable: number

    Effective per-table column limit — read from MJ_INTEGRATION_MAX_COLUMNS_PER_TABLE at startup and clamped to [1, MAX_COLUMNS_CEILING] (defaults to the ceiling when unset). Objects whose column count exceeds this are auto-disabled at apply time (reversible) instead of failing CREATE TABLE.

    MAX_COLUMNS_CEILING: 1000

    SQL Server's hard per-table column limit is 1024; the framework reserves headroom for its own sync/system columns (the _mj_integration* set + ID + timestamps), so the effective ceiling is 1000. MJ_INTEGRATION_MAX_COLUMNS_PER_TABLE can only LOWER this, never raise it past 1000.

    RECORD_MAP_PAGE_SIZE_CEILING: 50000 = 50_000

    Hard ceiling on the record-map keyset page size. Each page is one round trip that materializes this many rows in memory; past 50k the per-page cost stops amortizing and starts risking the response-size limits of the transport.

    RecordMapPageSize: number = ...

    Page size for the keyset walk over MJ: Company Integration Record Maps (see LoadAllRecordMaps). Read from MJ_INTEGRATION_RECORD_MAP_PAGE_SIZE at class-init and clamped to [1, RECORD_MAP_PAGE_SIZE_CEILING]; defaults to 10,000.

    Accessors

    • get GlobalKey(): string

      Returns string

    Methods

    • The Global Object Store is a place to store global objects that need to be shared across the application. Depending on the execution environment, this could be the window object in a browser, or the global object in a node environment, or something else in other contexts. The key here is that in some cases static variables are not truly shared because it is possible that a given class might have copies of its code in multiple paths in a deployed application. This approach ensures that no matter how many code copies might exist, there is only one instance of the object in question by using the Global Object Store.

      Returns GlobalObjectStore

    • Source field names the connector declared as SyncDirective 'Exclude' for one integration object, read from IntegrationObjectField.Configuration. Empty set on any lookup miss (unknown object, no fields, no integration id) - a failed lookup must never widen or narrow the sync beyond its declared behaviour.

      Parameters

      • integrationID: string
      • externalObjectName: string

      Returns Set<string>

    • Resumes any syncs that were orphaned by a process restart. Finds all CompanyIntegrationRun records with Status='In Progress', determines which entity maps already completed (have run details), and resumes from the remaining entity maps using existing watermarks.

      Call this once during MJAPI startup after metadata is loaded.

      Parameters

      Returns Promise<void>

    • Acquires the maintenance lock for a CompanyIntegration. Returns false (does NOT wait) when a data sync is currently running or another maintenance operation already holds the lock — the caller decides whether to wait for GetSyncProgress to clear or surface the conflict.

      Parameters

      • companyIntegrationID: string
      • reason: string

      Returns boolean

    • Parameters

      • _companyIntegrationID: string

      Returns boolean

      Superseded by IntegrationEngine.CancelSyncAsync, which records the cancel on the run row so the owning process observes it at its next batch boundary.

      Retained with its original signature for published consumers. Returns false — truthfully reporting that it cancelled nothing — rather than pretending to succeed, so a caller branching on the result is not silently misled.

    • Request cancellation of a running (or queued) sync by stamping CancelRequestedAt on the live run row (PR 1 item 4 — the DATABASE is the single source of cancellation truth, so a cancel issued in ANY process reaches the owner). The owner observes the stamp at its next batch boundary / lease renewal and stops after the current batch. Returns true when a live run row was stamped.

      Parameters

      Returns Promise<boolean>

    • Classifies a fetched batch against the ctx.BatchSize the engine asked for. Returns null when the batch is within contract, so the caller can treat "no verdict" as "nothing to warn about".

      Two severities, because they are different defects:

      • CONNECTOR_UNBOUNDED_BATCH — the FIRST batch came back over-size AND HasMore is not true, i.e. the connector ignored pagination entirely and pulled the whole object into memory in one request. That is what OOMs a large tenant, and it grows silently with the customer's data.
      • CONNECTOR_IGNORED_BATCH_SIZE — the connector IS paging but overshoots the requested size (e.g. a hardcoded page size). Bounded memory, still a contract violation worth fixing.

      Public + static because the decision is the interesting part and deserves a unit test that doesn't have to stand up a whole sync (same rationale as RatchetProgressSnapshot).

      Parameters

      • objectName: string
      • recordCount: number
      • requestedBatchSize: number
      • batchIndex: number
      • hasMore: boolean

      Returns {
          Code: "CONNECTOR_UNBOUNDED_BATCH" | "CONNECTOR_IGNORED_BATCH_SIZE";
          Message: string;
          Unbounded: boolean;
      }

    • Returns the singleton instance of the class. If the instance does not exist, it is created and stored in the Global Object Store. If className is provided it will be used as part of the key in the Global Object Store, otherwise the actual class name will be used. NOTE: the class name used by default is the lowest level of the object hierarchy, so if you have a class that extends another class, the lowest level class name will be used.

      Type Parameters

      Parameters

      • this: new () => T
      • OptionalclassName: string

      Returns T

    • Current maintenance lock for a CompanyIntegration, or undefined when none is held.

      Parameters

      • companyIntegrationID: string

      Returns { AcquiredAt: Date; Reason: string }

    • Parameters

      • _companyIntegrationID: string

      Returns SyncProgressSnapshot

      Superseded by IntegrationEngine.GetSyncProgressAsync, which reads the run row and therefore sees runs owned by ANY process.

      Retained with its original signature so a published consumer does not break on a minor upgrade. It cannot be made to work: the static map it used to read was removed when progress moved to the database, and a synchronous method cannot query it. It returns undefined — the same value it returned when no run was in progress — and logs once explaining the replacement.

    • Read current sync progress for a connector FROM THE DATABASE (PR 1 item 4 — progress lives on the run row, so it is visible from ANY process, not just the one executing the sync). Returns undefined when no live run exists. A run is "live" when Status is In Progress/Queued AND its lease has not expired — an expired lease means the owner died and the snapshot is stale history, not progress.

      Parameters

      Returns Promise<SyncProgressSnapshot>

    • Worker-mode poll (PR 1 item 8): the oldest claimable Queued runs. A row is claimable when it is unowned or its lease has lapsed — a Queued row with a LIVE lease is being started by another worker right now and must not be returned. This is only a candidate list; ExecuteQueuedRun's atomic claim is what actually grants exclusivity, so two workers polling simultaneously is safe by construction.

      Parameters

      Returns Promise<{ CompanyIntegrationID: string; ID: string }[]>