{"version":3,"sources":["../src/backend/capabilities/recorded-time-ownership.ts","../src/backend/capabilities/recorded-time.ts"],"names":["parseRecordedInstant","ConfigurationError"],"mappings":";;;;;;AA0BO,SAAS,6BACd,OAAA,EACuB;AACvB,EAAA,OAAO,OAAA,CAAQ,YAAA,KAAiB,MAAA,GAC5B,qBAAA,GACA,eAAA;AACN;AAuBO,SAAS,kCACd,OAAA,EACS;AACT,EAAA,OAAO,SAAS,IAAA,KAAS,eAAA;AAC3B;AAeO,SAAS,mCAAA,CACd,SAAA,EACA,OAAA,EACA,OAAA,EACM;AACN,EAAA,MAAM,KAAA,GAAQA,sCAAA,CAAqB,OAAA,EAAS,OAAO,CAAA;AACnD,EAAA,MAAM,YAAA,GAAe,SAAA,KAAc,eAAA,GAAkB,QAAA,GAAW,WAAA;AAChE,EAAA,IAAI,KAAA,CAAM,SAAS,YAAA,EAAc;AACjC,EAAA,MAAM,IAAIC,oCAAA;AAAA,IACR,GAAG,OAAO,CAAA,qFAAA,EAAwF,SAAS,CAAA,eAAA,EAAkB,MAAM,IAAI,CAAA,eAAA,CAAA;AAAA,IACvI;AAAA,MACE,IAAA,EAAM,qCAAA;AAAA,MACN,OAAA;AAAA,MACA,SAAA;AAAA,MACA,aAAa,KAAA,CAAM;AAAA,KACrB;AAAA,IACA;AAAA,MACE,UAAA,EACE,SAAA,KAAc,eAAA,GACZ,sIAAA,GACA;AAAA;AACN,GACF;AACF;;;ACwBO,SAAS,mBAAA,CACd,SACA,SAAA,EAC2B;AAC3B,EAAA,MAAM,eAAe,OAAA,CAAQ,YAAA;AAC7B,EAAA,IAAI,iBAAiB,MAAA,EAAW;AAC9B,IAAA,MAAM,IAAIA,oCAAA;AAAA,MACR,GAAG,SAAS,CAAA,6GAAA,CAAA;AAAA,MACZ,EAAE,IAAA,EAAM,2BAAA,EAA6B,SAAA,EAAU;AAAA,MAC/C;AAAA,QACE,UAAA,EACE;AAAA;AACJ,KACF;AAAA,EACF;AACA,EAAA,OAAO,YAAA;AACT","file":"chunk-2XQYRCPM.cjs","sourcesContent":["/**\n * Who allocates recorded-time revisions for a backend: TypeGraph's own\n * capture relations and clock, or the engine itself through\n * `GraphBackend.recordedTime` (`./recorded-time.ts`). Lives in its own\n * module, sibling to `write-fence.ts` and `recorded-time.ts`, because the\n * derivation is a one-line decision that several construction sites read\n * and must never re-spell.\n */\nimport {\n  parseRecordedInstant,\n  type RecordedInstant,\n} from \"../../core/temporal\";\nimport { ConfigurationError } from \"../../errors\";\nimport { type RecordedReadBinding } from \"../../query/compiler/schema\";\nimport { type GraphBackend } from \"../types\";\n\n/** Who allocates recorded-time revisions for a backend. See {@link resolveRecordedTimeOwnership}. */\nexport type RecordedTimeOwnership = \"typegraph-relations\" | \"engine-native\";\n\n/**\n * THE one reader of backend recorded-time ownership: `\"engine-native\"` when\n * the backend declares `recordedTime`, `\"typegraph-relations\"` otherwise —\n * today's behavior for every existing backend. There is no separate\n * declared flag to fall out of sync with the member: a backend that\n * supplies `recordedTime` IS engine-native, by construction.\n */\nexport function resolveRecordedTimeOwnership(\n  backend: Pick<GraphBackend, \"recordedTime\">,\n): RecordedTimeOwnership {\n  return backend.recordedTime === undefined ?\n      \"typegraph-relations\"\n    : \"engine-native\";\n}\n\n/**\n * THE one check for \"is this recorded read reached under engine-native\n * ownership,\" for the callers that hold a read binding rather than a\n * backend: the query compiler's historical identity traversal\n * (`query/compiler/identity-traversal.ts`) only ever sees\n * `ctx.recordedReadBinding`, never the store or its backend.\n *\n * A binding of kind `\"engine-native\"` implies that\n * {@link resolveRecordedTimeOwnership} answered `\"engine-native\"` for the\n * backend it was built from: `Store`'s constructor builds that binding kind\n * (`createEngineRecordedReadBinding`) only after the derivation already\n * held. The converse does not hold: an engine-native backend constructed\n * with neither `history` nor `recordedRead` binds nothing at all, so\n * ownership is engine-native while no binding exists — but `asOfRecorded()`\n * refuses such a store before any recorded read can reach this check. `Store.\n * identityAtCoordinate` — the other entry point a recorded identity read can\n * reach — therefore calls this same function over its own bound binding\n * rather than re-deriving the ownership from `#recordedTimeOwnership`, so\n * the two entry points cannot drift into disagreeing about which reads this\n * refuses.\n */\nexport function isEngineNativeRecordedReadBinding(\n  binding: RecordedReadBinding | undefined,\n): boolean {\n  return binding?.kind === \"engine-native\";\n}\n\n/**\n * THE one check that an `asOfRecorded` anchor was minted by the SAME\n * ownership form this store reads under: an engine-native store requires an\n * `e1:` instant (one its own `recordedTime.revisionNow` produced), and a\n * TypeGraph-owned store requires an `r1:` instant (one its own capture clock\n * produced). Reusing an anchor across ownership forms — or across two\n * differently-configured stores over the same graph — would otherwise\n * silently source rows through the wrong seam, since `RecordedReadSource`\n * only refuses the mismatch once a read is compiled ({@link\n * CompilerInvariantError} deep in `query/compiler/schema.ts`); this check\n * gives the same mismatch a typed, caller-facing refusal at the point the\n * anchor is supplied.\n */\nexport function assertRecordedInstantOwnershipMatch(\n  ownership: RecordedTimeOwnership,\n  instant: RecordedInstant,\n  surface: string,\n): void {\n  const parts = parseRecordedInstant(instant, surface);\n  const expectedKind = ownership === \"engine-native\" ? \"engine\" : \"typegraph\";\n  if (parts.kind === expectedKind) return;\n  throw new ConfigurationError(\n    `${surface} requires a recorded instant minted under this store's own recorded-time ownership (\"${ownership}\"), but got a \"${parts.kind}\"-form instant.`,\n    {\n      code: \"RECORDED_INSTANT_OWNERSHIP_MISMATCH\",\n      surface,\n      ownership,\n      instantKind: parts.kind,\n    },\n    {\n      suggestion:\n        ownership === \"engine-native\" ?\n          \"Pass an e1: instant read from this store's own recordedNow() — an r1: instant belongs to a TypeGraph-owned recorded-time store.\"\n        : \"Pass an r1: instant read from this store's own recordedNow() — an e1: instant belongs to an engine-native recorded-time store.\",\n    },\n  );\n}\n","/**\n * The backend's optional engine-native recorded-time capability: an engine\n * that supplies the recorded (system-time) axis itself, rather than through\n * TypeGraph's own capture relations and clock.\n *\n * Declaring this member is what `resolveRecordedTimeOwnership` (sibling\n * `recorded-time-ownership.ts`) reads to derive `\"engine-native\"` — there is\n * no separate boolean or capability flag to keep in sync with it.\n */\nimport { ConfigurationError } from \"../../errors\";\nimport type { RecordedSourceTable } from \"../../query/compiler/schema\";\nimport { type SqlFragment } from \"../../query/sql-fragment\";\nimport { type GraphBackend, type TransactionBackend } from \"../types\";\n\nexport type { RecordedSourceTable } from \"../../query/compiler/schema\";\n\n/**\n * The connection a `source()`/`revisionNow()` read runs on — the same\n * `Pick<TransactionBackend, \"execute\" | \"executeRaw\">` shape\n * {@link LineageSession} (`./lineage.ts`) reuses for the identical reason: a\n * root backend and a `transaction()` handle both satisfy it, and\n * `TransactionBackend`'s two members are themselves `Pick<GraphBackend, …>`\n * projections of the same signatures.\n */\nexport type RecordedTimeSession = Pick<\n  TransactionBackend,\n  \"execute\" | \"executeRaw\"\n>;\n\n/**\n * An engine-minted recorded-time revision: an opaque, engine-assigned\n * identifier paired with the ISO-8601 wall time the engine recorded\n * alongside it. Never parsed, ordered, or compared as a number — only ever\n * carried between `revisionNow` and `source`, and (through the engine\n * instant form built from it) compared by `recordedAt`.\n */\nexport type EngineRecordedRevision = Readonly<{\n  /** Opaque engine revision identifier — URL-safe, non-empty, never parsed. */\n  revision: string;\n  /** ISO-8601 wall time the engine recorded this revision at. */\n  recordedAt: string;\n}>;\n\n/**\n * The backend's engine-native recorded-time surface. Optional: a backend\n * that omits it is read under TypeGraph's own recorded-relations ownership\n * (see {@link resolveRecordedTimeOwnership} in `./recorded-time-ownership`).\n *\n * `source` names the table expression `table`'s rows are read from AS OF\n * `revision` — the engine's own temporal-table syntax, with the interval\n * already folded in, so it satisfies a recorded read binding's `source`\n * member (`RecordedReadSource`, `src/query/compiler/schema.ts`) with a\n * `predicate` that always returns `undefined`: the engine's `source` already\n * scopes every row to exactly one revision.\n *\n * `revisionNow` reads `session`'s own recorded-time revision — the\n * connection the CALLER's decision is bound to, not one this member opens\n * for itself, exactly as {@link LineageMembers}'s two members require\n * (`./lineage.ts`'s own doc comment states the full rationale: a commit-time\n * caller that already holds an open transaction passes that handle so the\n * read observes the transaction's own snapshot). What \"own revision\" means\n * depends on which session it is called with — the two call sites TypeGraph\n * makes never confuse them:\n *\n * - **On a root backend** (`store.recordedNow()`, `store.revisionNow()`):\n *   the engine's current COMMITTED revision.\n * - **On an open `transaction()` handle** (both `TransactionReceipt.recorded`\n *   sites, called before that transaction's own COMMIT): the revision at\n *   which THIS transaction's writes will become visible once it commits —\n *   the engine's pending/next revision for that session, not the last one\n *   committed before it opened. TypeGraph stamps this uncommitted value\n *   straight into the receipt it returns to the caller after the\n *   transaction succeeds, trusting it to describe exactly the state that\n *   commit produced.\n *\n * An engine that cannot name its own pending revision from inside an open\n * transaction — only its last-committed one — cannot supply `recordedTime`:\n * `TransactionReceipt.recorded` would then either lag one commit behind the\n * write it is supposed to describe, or require a second round trip after\n * COMMIT that reopens the race `recordedTime` exists to close.\n *\n * It is called at most once per transaction — the position TypeGraph's own\n * `flush()` occupies for a capture-owned store — never once per graph.\n */\nexport type EngineRecordedTimeMembers = Readonly<{\n  /**\n   * The table expression `table`'s recorded rows read from AS OF `revision`.\n   *\n   * `table` is never called with `\"identityAssertions\"` today: a recorded\n   * identity read (`Store.identityAtCoordinate` and the query compiler's\n   * historical identity traversal) is refused outright under engine-native\n   * ownership before any read compiles\n   * (`refuseEngineNativeRecordedIdentityRead`), and the recorded read schema\n   * this member feeds (`recordedReadSqlSchema`) only ever sources `\"nodes\"`\n   * and `\"edges\"`. An implementation still must handle the case — the union\n   * is shared with the TypeGraph-relation-backed source, which every\n   * revision does support — until a later engine-native identity-read seam\n   * routes those reads through here instead of refusing them.\n   */\n  source: (\n    this: void,\n    table: RecordedSourceTable,\n    revision: EngineRecordedRevision,\n  ) => SqlFragment;\n  /**\n   * `session`'s own recorded-time revision: the current committed one on a\n   * root backend, or the pending revision an open transaction's writes will\n   * land at once it commits. See this type's own doc comment for the full\n   * contract.\n   */\n  revisionNow: (\n    this: void,\n    session: RecordedTimeSession,\n  ) => Promise<EngineRecordedRevision>;\n}>;\n\n/**\n * THE refusal for a caller that needs the backend's engine-native\n * recorded-time capability and finds it absent, naming the missing member\n * so a caller can add it.\n */\nexport function requireRecordedTime(\n  backend: Pick<GraphBackend, \"recordedTime\">,\n  operation: string,\n): EngineRecordedTimeMembers {\n  const recordedTime = backend.recordedTime;\n  if (recordedTime === undefined) {\n    throw new ConfigurationError(\n      `${operation} requires the backend's engine-native recordedTime capability, but this backend declares no \\`recordedTime\\`.`,\n      { code: \"RECORDED_TIME_UNAVAILABLE\", operation },\n      {\n        suggestion:\n          \"Implement `recordedTime` on this backend (with a co-declared `lineage`), or use TypeGraph-owned recorded time (`history`/`revisionTracking`) instead.\",\n      },\n    );\n  }\n  return recordedTime;\n}\n"]}