@adcp/sdk 15.4.0 → 15.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/dist/lib/advanced.d.mts +2 -2
  2. package/dist/lib/advanced.d.ts +2 -2
  3. package/dist/lib/advanced.js +8 -2
  4. package/dist/lib/advanced.mjs +8 -2
  5. package/dist/lib/core/AgentClient.d.mts +4 -0
  6. package/dist/lib/core/AgentClient.d.ts +4 -0
  7. package/dist/lib/core/AgentClient.js +8 -0
  8. package/dist/lib/core/AgentClient.mjs +8 -0
  9. package/dist/lib/core/SingleAgentClient.d.mts +154 -0
  10. package/dist/lib/core/SingleAgentClient.d.ts +154 -0
  11. package/dist/lib/core/SingleAgentClient.js +661 -23
  12. package/dist/lib/core/SingleAgentClient.mjs +666 -23
  13. package/dist/lib/core/agent-discovery-cache.d.mts +103 -0
  14. package/dist/lib/core/agent-discovery-cache.d.ts +103 -0
  15. package/dist/lib/core/agent-discovery-cache.js +121 -0
  16. package/dist/lib/core/agent-discovery-cache.mjs +92 -0
  17. package/dist/lib/index.d.mts +5 -3
  18. package/dist/lib/index.d.ts +5 -3
  19. package/dist/lib/index.js +7 -0
  20. package/dist/lib/index.mjs +6 -0
  21. package/dist/lib/protocols/index.d.mts +2 -2
  22. package/dist/lib/protocols/index.d.ts +2 -2
  23. package/dist/lib/protocols/index.js +1 -1
  24. package/dist/lib/protocols/index.mjs +1 -1
  25. package/dist/lib/protocols/mcp-call-context.d.mts +109 -0
  26. package/dist/lib/protocols/mcp-call-context.d.ts +109 -0
  27. package/dist/lib/protocols/mcp-call-context.js +221 -0
  28. package/dist/lib/protocols/mcp-call-context.mjs +186 -0
  29. package/dist/lib/protocols/mcp-modern.d.mts +9 -1
  30. package/dist/lib/protocols/mcp-modern.d.ts +9 -1
  31. package/dist/lib/protocols/mcp-modern.js +180 -104
  32. package/dist/lib/protocols/mcp-modern.mjs +193 -104
  33. package/dist/lib/protocols/mcp-scope.d.mts +15 -0
  34. package/dist/lib/protocols/mcp-scope.d.ts +15 -0
  35. package/dist/lib/protocols/mcp.d.mts +4 -2
  36. package/dist/lib/protocols/mcp.d.ts +4 -2
  37. package/dist/lib/protocols/mcp.js +178 -154
  38. package/dist/lib/protocols/mcp.mjs +189 -153
  39. package/dist/lib/protocols/transportDiagnostics.d.mts +33 -1
  40. package/dist/lib/protocols/transportDiagnostics.d.ts +33 -1
  41. package/dist/lib/protocols/transportDiagnostics.js +128 -12
  42. package/dist/lib/protocols/transportDiagnostics.mjs +128 -12
  43. package/dist/lib/reporting/gcs/index.d.mts +2 -0
  44. package/dist/lib/reporting/gcs/index.d.ts +2 -0
  45. package/dist/lib/reporting/gcs/index.js +3 -0
  46. package/dist/lib/reporting/gcs/index.mjs +2 -0
  47. package/dist/lib/reporting/gcs/row-provider.d.mts +32 -0
  48. package/dist/lib/reporting/gcs/row-provider.d.ts +32 -0
  49. package/dist/lib/reporting/gcs/row-provider.js +205 -0
  50. package/dist/lib/reporting/gcs/row-provider.mjs +188 -0
  51. package/dist/lib/reporting/ledger/change-feed.d.mts +41 -0
  52. package/dist/lib/reporting/ledger/change-feed.d.ts +41 -0
  53. package/dist/lib/reporting/ledger/change-feed.js +101 -0
  54. package/dist/lib/reporting/ledger/change-feed.mjs +74 -0
  55. package/dist/lib/reporting/ledger/handler.js +22 -8
  56. package/dist/lib/reporting/ledger/handler.mjs +22 -8
  57. package/dist/lib/reporting/ledger/index.d.mts +4 -0
  58. package/dist/lib/reporting/ledger/index.d.ts +4 -0
  59. package/dist/lib/reporting/ledger/index.js +9 -1
  60. package/dist/lib/reporting/ledger/index.mjs +4 -0
  61. package/dist/lib/reporting/ledger/managed-postgres.d.mts +2 -0
  62. package/dist/lib/reporting/ledger/managed-postgres.d.ts +2 -0
  63. package/dist/lib/reporting/ledger/managed-postgres.js +21 -1
  64. package/dist/lib/reporting/ledger/managed-postgres.mjs +21 -1
  65. package/dist/lib/reporting/ledger/managed.d.mts +9 -0
  66. package/dist/lib/reporting/ledger/managed.d.ts +9 -0
  67. package/dist/lib/reporting/ledger/managed.js +18 -0
  68. package/dist/lib/reporting/ledger/managed.mjs +18 -0
  69. package/dist/lib/reporting/ledger/postgres.d.mts +175 -0
  70. package/dist/lib/reporting/ledger/postgres.d.ts +175 -0
  71. package/dist/lib/reporting/ledger/postgres.js +851 -26
  72. package/dist/lib/reporting/ledger/postgres.mjs +859 -26
  73. package/dist/lib/reporting/ledger/producer.js +10 -1
  74. package/dist/lib/reporting/ledger/producer.mjs +10 -1
  75. package/dist/lib/reporting/ledger/row-storage-errors.d.mts +7 -0
  76. package/dist/lib/reporting/ledger/row-storage-errors.d.ts +7 -0
  77. package/dist/lib/reporting/ledger/row-storage-errors.js +41 -0
  78. package/dist/lib/reporting/ledger/row-storage-errors.mjs +16 -0
  79. package/dist/lib/reporting/ledger/row-storage-migration.d.mts +41 -0
  80. package/dist/lib/reporting/ledger/row-storage-migration.d.ts +41 -0
  81. package/dist/lib/reporting/ledger/row-storage-migration.js +234 -0
  82. package/dist/lib/reporting/ledger/row-storage-migration.mjs +208 -0
  83. package/dist/lib/reporting/ledger/row-storage-object.d.mts +112 -0
  84. package/dist/lib/reporting/ledger/row-storage-object.d.ts +112 -0
  85. package/dist/lib/reporting/ledger/row-storage-object.js +281 -0
  86. package/dist/lib/reporting/ledger/row-storage-object.mjs +239 -0
  87. package/dist/lib/reporting/ledger/row-storage-provider-io.d.mts +51 -0
  88. package/dist/lib/reporting/ledger/row-storage-provider-io.d.ts +51 -0
  89. package/dist/lib/reporting/ledger/row-storage-provider-io.js +152 -0
  90. package/dist/lib/reporting/ledger/row-storage-provider-io.mjs +119 -0
  91. package/dist/lib/reporting/ledger/row-storage.d.mts +224 -0
  92. package/dist/lib/reporting/ledger/row-storage.d.ts +224 -0
  93. package/dist/lib/reporting/ledger/row-storage.js +692 -0
  94. package/dist/lib/reporting/ledger/row-storage.mjs +680 -0
  95. package/dist/lib/reporting/ledger/types.d.mts +8 -0
  96. package/dist/lib/reporting/ledger/types.d.ts +8 -0
  97. package/dist/lib/reporting/service/index.d.mts +41 -1
  98. package/dist/lib/reporting/service/index.d.ts +41 -1
  99. package/dist/lib/reporting/service/index.js +68 -1
  100. package/dist/lib/reporting/service/index.mjs +70 -1
  101. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  102. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  103. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  104. package/dist/lib/version.d.mts +3 -3
  105. package/dist/lib/version.d.ts +3 -3
  106. package/dist/lib/version.js +3 -3
  107. package/dist/lib/version.mjs +3 -3
  108. package/docs/README.md +1 -1
  109. package/docs/TYPE-SUMMARY.md +35 -2
  110. package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +142 -0
  111. package/docs/guides/EXISTING-PLATFORM.md +43 -12
  112. package/docs/guides/REPORTING-LEDGER.md +209 -0
  113. package/docs/llms.txt +4 -2
  114. package/docs/migration-14.x-rc-worksheet.md +4 -4
  115. package/package.json +1 -1
@@ -36,6 +36,7 @@ var import_coverage = require('./coverage.js');
36
36
  var import_health = require('./health.js');
37
37
  var import_instant = require('./instant.js');
38
38
  var import_revision_metadata = require('./revision-metadata.js');
39
+ var import_row_storage = require('./row-storage.js');
39
40
  var import_schedule = require('./schedule.js');
40
41
  var import_types = require('./types.js');
41
42
  function createReportingStatusHandler(store, options) {
@@ -267,7 +268,9 @@ function createReportingStatusHandler(store, options) {
267
268
  else revisionRows = page2.rows;
268
269
  }
269
270
  } catch (error) {
270
- if (error instanceof ReportingReadCapacityError) return lookupUnavailable(view);
271
+ if (error instanceof ReportingReadCapacityError || (0, import_row_storage.isReportingRowStoreError)(error)) {
272
+ return lookupUnavailable(view);
273
+ }
271
274
  throw error;
272
275
  }
273
276
  }
@@ -450,13 +453,24 @@ function createReportingDeliveryHandler(store) {
450
453
  }
451
454
  let reportingRows = [];
452
455
  if (totalCount > 0) {
453
- const page = await (0, import_revision_metadata.readRevisionRowsFromStore)(store, {
454
- reporting_revision_id: revision.reporting_revision_id,
455
- account_id: accountId,
456
- offset,
457
- limit: maxResults,
458
- ...context.signal ? { signal: context.signal } : {}
459
- });
456
+ let page;
457
+ try {
458
+ page = await (0, import_revision_metadata.readRevisionRowsFromStore)(store, {
459
+ reporting_revision_id: revision.reporting_revision_id,
460
+ account_id: accountId,
461
+ offset,
462
+ limit: maxResults,
463
+ ...context.signal ? { signal: context.signal } : {}
464
+ });
465
+ } catch (error) {
466
+ if ((0, import_row_storage.isReportingRowStoreError)(error)) {
467
+ if (error.code === "ROWS_EXPIRED") throw new Error("Reporting revision is unavailable");
468
+ throw new import_async_outcome.AdcpError("SERVICE_UNAVAILABLE", {
469
+ message: "Reporting revision rows are temporarily unavailable"
470
+ });
471
+ }
472
+ throw error;
473
+ }
460
474
  if (!page || page.total !== totalCount) throw new Error("Reporting revision is unavailable");
461
475
  reportingRows = page.rows;
462
476
  }
@@ -19,6 +19,7 @@ import {
19
19
  } from "./health.mjs";
20
20
  import { compareReportingInstants } from "./instant.mjs";
21
21
  import { getRevisionMetadataFromStore, readRevisionRowsFromStore } from "./revision-metadata.mjs";
22
+ import { isReportingRowStoreError } from "./row-storage.mjs";
22
23
  import { reportingPeriodSchedule } from "./schedule.mjs";
23
24
  import { ReportingLedgerSnapshotUnavailableError } from "./types.mjs";
24
25
  function createReportingStatusHandler(store, options) {
@@ -250,7 +251,9 @@ function createReportingStatusHandler(store, options) {
250
251
  else revisionRows = page2.rows;
251
252
  }
252
253
  } catch (error) {
253
- if (error instanceof ReportingReadCapacityError) return lookupUnavailable(view);
254
+ if (error instanceof ReportingReadCapacityError || isReportingRowStoreError(error)) {
255
+ return lookupUnavailable(view);
256
+ }
254
257
  throw error;
255
258
  }
256
259
  }
@@ -433,13 +436,24 @@ function createReportingDeliveryHandler(store) {
433
436
  }
434
437
  let reportingRows = [];
435
438
  if (totalCount > 0) {
436
- const page = await readRevisionRowsFromStore(store, {
437
- reporting_revision_id: revision.reporting_revision_id,
438
- account_id: accountId,
439
- offset,
440
- limit: maxResults,
441
- ...context.signal ? { signal: context.signal } : {}
442
- });
439
+ let page;
440
+ try {
441
+ page = await readRevisionRowsFromStore(store, {
442
+ reporting_revision_id: revision.reporting_revision_id,
443
+ account_id: accountId,
444
+ offset,
445
+ limit: maxResults,
446
+ ...context.signal ? { signal: context.signal } : {}
447
+ });
448
+ } catch (error) {
449
+ if (isReportingRowStoreError(error)) {
450
+ if (error.code === "ROWS_EXPIRED") throw new Error("Reporting revision is unavailable");
451
+ throw new AdcpError("SERVICE_UNAVAILABLE", {
452
+ message: "Reporting revision rows are temporarily unavailable"
453
+ });
454
+ }
455
+ throw error;
456
+ }
443
457
  if (!page || page.total !== totalCount) throw new Error("Reporting revision is unavailable");
444
458
  reportingRows = page.rows;
445
459
  }
@@ -12,3 +12,7 @@ export * from './managed-postgres.mjs';
12
12
  export * from './object-writes.mjs';
13
13
  export * from './notification-activity.mjs';
14
14
  export * from './row-encoding.mjs';
15
+ export * from './row-storage-migration.mjs';
16
+ export * from './row-storage.mjs';
17
+ export * from './row-storage-object.mjs';
18
+ export * from './change-feed.mjs';
@@ -12,3 +12,7 @@ export * from './managed-postgres';
12
12
  export * from './object-writes';
13
13
  export * from './notification-activity';
14
14
  export * from './row-encoding';
15
+ export * from './row-storage-migration';
16
+ export * from './row-storage';
17
+ export * from './row-storage-object';
18
+ export * from './change-feed';
@@ -29,6 +29,10 @@ __reExport(ledger_exports, require('./managed-postgres.js'), module.exports);
29
29
  __reExport(ledger_exports, require('./object-writes.js'), module.exports);
30
30
  __reExport(ledger_exports, require('./notification-activity.js'), module.exports);
31
31
  __reExport(ledger_exports, require('./row-encoding.js'), module.exports);
32
+ __reExport(ledger_exports, require('./row-storage-migration.js'), module.exports);
33
+ __reExport(ledger_exports, require('./row-storage.js'), module.exports);
34
+ __reExport(ledger_exports, require('./row-storage-object.js'), module.exports);
35
+ __reExport(ledger_exports, require('./change-feed.js'), module.exports);
32
36
  // Annotate the CommonJS export names for ESM import in node:
33
37
  0 && (module.exports = {
34
38
  ...require('./types.js'),
@@ -44,5 +48,9 @@ __reExport(ledger_exports, require('./row-encoding.js'), module.exports);
44
48
  ...require('./managed-postgres.js'),
45
49
  ...require('./object-writes.js'),
46
50
  ...require('./notification-activity.js'),
47
- ...require('./row-encoding.js')
51
+ ...require('./row-encoding.js'),
52
+ ...require('./row-storage-migration.js'),
53
+ ...require('./row-storage.js'),
54
+ ...require('./row-storage-object.js'),
55
+ ...require('./change-feed.js')
48
56
  });
@@ -12,3 +12,7 @@ export * from "./managed-postgres.mjs";
12
12
  export * from "./object-writes.mjs";
13
13
  export * from "./notification-activity.mjs";
14
14
  export * from "./row-encoding.mjs";
15
+ export * from "./row-storage-migration.mjs";
16
+ export * from "./row-storage.mjs";
17
+ export * from "./row-storage-object.mjs";
18
+ export * from "./change-feed.mjs";
@@ -94,6 +94,8 @@ export declare class PostgresReportingManagedDeliveryStore implements ReportingM
94
94
  private validateRecoveryWindow;
95
95
  private readPolicyRow;
96
96
  private readPolicy;
97
+ /** Read-only access to PostgreSQL row chunks for claim hydration. */
98
+ private readonly rowStorage;
97
99
  constructor(pool: ReportingPgPool, options?: PostgresReportingManagedDeliveryStoreOptions);
98
100
  /** SQL fragment scoping a count to the active retention window, if one is set. */
99
101
  private activeScope;
@@ -94,6 +94,8 @@ export declare class PostgresReportingManagedDeliveryStore implements ReportingM
94
94
  private validateRecoveryWindow;
95
95
  private readPolicyRow;
96
96
  private readPolicy;
97
+ /** Read-only access to PostgreSQL row chunks for claim hydration. */
98
+ private readonly rowStorage;
97
99
  constructor(pool: ReportingPgPool, options?: PostgresReportingManagedDeliveryStoreOptions);
98
100
  /** SQL fragment scoping a count to the active retention window, if one is set. */
99
101
  private activeScope;
@@ -26,6 +26,7 @@ var import_node_crypto = require("node:crypto");
26
26
  var import_jcs = require('../../utils/jcs.js');
27
27
  var import_evidence = require('../evidence.js');
28
28
  var import_types = require('./types.js');
29
+ var import_row_storage = require('./row-storage.js');
29
30
  var import_object_writes = require('./object-writes.js');
30
31
  var import_managed = require('./managed.js');
31
32
  const REPORTING_MANAGED_DELIVERY_MIGRATION = `
@@ -252,6 +253,7 @@ const MAX_RECEIPT_BATCH_RESULT_BYTES = 64 * 1024;
252
253
  class PostgresReportingManagedDeliveryStore {
253
254
  constructor(pool, options = {}) {
254
255
  this.pool = pool;
256
+ this.rowStorage = new import_row_storage.ReportingRowStorageV1(pool);
255
257
  if (options.statusRetentionDays !== void 0) positiveInteger(options.statusRetentionDays, "statusRetentionDays");
256
258
  if (options.evidenceRetentionDays !== void 0) {
257
259
  positiveInteger(options.evidenceRetentionDays, "evidenceRetentionDays");
@@ -466,6 +468,8 @@ class PostgresReportingManagedDeliveryStore {
466
468
  authorizationRevocationSeconds: policy.advertised_authorization_revocation_seconds
467
469
  };
468
470
  }
471
+ /** Read-only access to PostgreSQL row chunks for claim hydration. */
472
+ rowStorage;
469
473
  /** SQL fragment scoping a count to the active retention window, if one is set. */
470
474
  activeScope(column) {
471
475
  return this.evidenceRetentionDays === void 0 ? "" : ` AND ${column} >= clock_timestamp() - (${this.evidenceRetentionDays}::bigint * INTERVAL '1 day')`;
@@ -1171,7 +1175,7 @@ class PostgresReportingManagedDeliveryStore {
1171
1175
  }
1172
1176
  async claimMaterialization(input) {
1173
1177
  positiveInteger(input.lease_milliseconds, "lease_milliseconds");
1174
- return this.transaction(async (client) => {
1178
+ const lease = await this.transaction(async (client) => {
1175
1179
  const selected = await client.query(
1176
1180
  `WITH candidate AS (
1177
1181
  SELECT materialization.materialization_id
@@ -1227,6 +1231,22 @@ class PostgresReportingManagedDeliveryStore {
1227
1231
  expires_at: row.expires_at.toISOString()
1228
1232
  };
1229
1233
  });
1234
+ if (!lease || Array.isArray(lease.revision.rows)) return lease;
1235
+ try {
1236
+ const handle = await this.rowStorage.find(
1237
+ lease.revision.reporting_revision_id,
1238
+ lease.obligation.account.account_id
1239
+ );
1240
+ if (handle?.kind === "postgres") {
1241
+ lease.revision = {
1242
+ ...lease.revision,
1243
+ rows: await this.rowStorage.readAll(handle, lease.revision.wireRevision.control_totals)
1244
+ };
1245
+ }
1246
+ } catch (error) {
1247
+ if (!(0, import_row_storage.isReportingRowStoreError)(error)) throw error;
1248
+ }
1249
+ return lease;
1230
1250
  }
1231
1251
  /**
1232
1252
  * Fails materializations that have used every delivery attempt.
@@ -2,6 +2,7 @@ import { createHash, randomUUID } from "node:crypto";
2
2
  import { canonicalize } from "../../utils/jcs.mjs";
3
3
  import { isReportingAdjustmentReceiptEvidence, isReportingReceiptEvidence } from "../evidence.mjs";
4
4
  import { REPORTING_LEDGER_AUTHORITY } from "./types.mjs";
5
+ import { ReportingRowStorageV1, isReportingRowStoreError } from "./row-storage.mjs";
5
6
  import {
6
7
  assertReportingObjectWriteScope,
7
8
  reportingObjectWritePlanFingerprint,
@@ -237,6 +238,7 @@ const MAX_RECEIPT_BATCH_RESULT_BYTES = 64 * 1024;
237
238
  class PostgresReportingManagedDeliveryStore {
238
239
  constructor(pool, options = {}) {
239
240
  this.pool = pool;
241
+ this.rowStorage = new ReportingRowStorageV1(pool);
240
242
  if (options.statusRetentionDays !== void 0) positiveInteger(options.statusRetentionDays, "statusRetentionDays");
241
243
  if (options.evidenceRetentionDays !== void 0) {
242
244
  positiveInteger(options.evidenceRetentionDays, "evidenceRetentionDays");
@@ -451,6 +453,8 @@ class PostgresReportingManagedDeliveryStore {
451
453
  authorizationRevocationSeconds: policy.advertised_authorization_revocation_seconds
452
454
  };
453
455
  }
456
+ /** Read-only access to PostgreSQL row chunks for claim hydration. */
457
+ rowStorage;
454
458
  /** SQL fragment scoping a count to the active retention window, if one is set. */
455
459
  activeScope(column) {
456
460
  return this.evidenceRetentionDays === void 0 ? "" : ` AND ${column} >= clock_timestamp() - (${this.evidenceRetentionDays}::bigint * INTERVAL '1 day')`;
@@ -1156,7 +1160,7 @@ class PostgresReportingManagedDeliveryStore {
1156
1160
  }
1157
1161
  async claimMaterialization(input) {
1158
1162
  positiveInteger(input.lease_milliseconds, "lease_milliseconds");
1159
- return this.transaction(async (client) => {
1163
+ const lease = await this.transaction(async (client) => {
1160
1164
  const selected = await client.query(
1161
1165
  `WITH candidate AS (
1162
1166
  SELECT materialization.materialization_id
@@ -1212,6 +1216,22 @@ class PostgresReportingManagedDeliveryStore {
1212
1216
  expires_at: row.expires_at.toISOString()
1213
1217
  };
1214
1218
  });
1219
+ if (!lease || Array.isArray(lease.revision.rows)) return lease;
1220
+ try {
1221
+ const handle = await this.rowStorage.find(
1222
+ lease.revision.reporting_revision_id,
1223
+ lease.obligation.account.account_id
1224
+ );
1225
+ if (handle?.kind === "postgres") {
1226
+ lease.revision = {
1227
+ ...lease.revision,
1228
+ rows: await this.rowStorage.readAll(handle, lease.revision.wireRevision.control_totals)
1229
+ };
1230
+ }
1231
+ } catch (error) {
1232
+ if (!isReportingRowStoreError(error)) throw error;
1233
+ }
1234
+ return lease;
1215
1235
  }
1216
1236
  /**
1217
1237
  * Fails materializations that have used every delivery attempt.
@@ -258,6 +258,15 @@ export interface ReportingManagedDeliveryWorkerOptionsV1 {
258
258
  */
259
259
  authorizationRevocationSeconds?: number;
260
260
  account_id?: string;
261
+ /**
262
+ * Loads verified rows for a claimed revision whose rows live in row storage
263
+ * rather than in the ledger document. `createReportingManagedDeliveryRuntime`
264
+ * supplies one backed by its Core store. PostgreSQL-kind chunks are
265
+ * hydrated by the managed store's claim itself; a direct caller whose rows
266
+ * live in an external binding must supply this, or the adapter receives a
267
+ * revision without rows.
268
+ */
269
+ hydrateRevision?: (revision: ReportingManagedDeliveryLeaseV1['revision'], account_id: string, signal: AbortSignal | undefined) => Promise<ReportingManagedDeliveryLeaseV1['revision']>;
261
270
  }
262
271
  export interface CreateReportingManagedDeliveryRuntimeOptionsV1<TContext extends {
263
272
  account?: unknown;
@@ -258,6 +258,15 @@ export interface ReportingManagedDeliveryWorkerOptionsV1 {
258
258
  */
259
259
  authorizationRevocationSeconds?: number;
260
260
  account_id?: string;
261
+ /**
262
+ * Loads verified rows for a claimed revision whose rows live in row storage
263
+ * rather than in the ledger document. `createReportingManagedDeliveryRuntime`
264
+ * supplies one backed by its Core store. PostgreSQL-kind chunks are
265
+ * hydrated by the managed store's claim itself; a direct caller whose rows
266
+ * live in an external binding must supply this, or the adapter receives a
267
+ * revision without rows.
268
+ */
269
+ hydrateRevision?: (revision: ReportingManagedDeliveryLeaseV1['revision'], account_id: string, signal: AbortSignal | undefined) => Promise<ReportingManagedDeliveryLeaseV1['revision']>;
261
270
  }
262
271
  export interface CreateReportingManagedDeliveryRuntimeOptionsV1<TContext extends {
263
272
  account?: unknown;
@@ -130,6 +130,13 @@ async function createReportingManagedDeliveryRuntime(options) {
130
130
  getMediaBuyDelivery,
131
131
  ...syncReportingReceipts ? { syncReportingReceipts } : {},
132
132
  runWorker: (workerOptions) => runManagedDeliveryWorker(options.store, options.adapter, {
133
+ ...typeof options.coreStore.getRevision === "function" ? {
134
+ hydrateRevision: async (revision, accountId) => {
135
+ const hydrated = await options.coreStore.getRevision(revision.reporting_revision_id, accountId);
136
+ if (!hydrated) throw new Error("Reporting revision is unavailable for delivery");
137
+ return hydrated;
138
+ }
139
+ } : {},
133
140
  ...workerOptions,
134
141
  minimumResourceRetentionDays: Math.max(
135
142
  options.resourceRetentionDays,
@@ -356,6 +363,17 @@ async function runManagedDeliveryWorker(store, adapter, options = {}) {
356
363
  if (!lease) break;
357
364
  counts.claimed += 1;
358
365
  try {
366
+ if (!Array.isArray(lease.revision.rows) && options.hydrateRevision) {
367
+ const hydrated = await options.hydrateRevision(
368
+ lease.revision,
369
+ lease.obligation.account.account_id,
370
+ options.signal
371
+ );
372
+ if (hydrated.reporting_revision_id !== lease.revision.reporting_revision_id || hydrated.binding.sha256 !== lease.revision.binding.sha256 || !Array.isArray(hydrated.rows)) {
373
+ throw new Error("Hydrated reporting revision does not match the claimed revision");
374
+ }
375
+ lease.revision = hydrated;
376
+ }
359
377
  const outcome = await withinDeadline(
360
378
  (signal) => adapter.deliver(
361
379
  {
@@ -103,6 +103,13 @@ async function createReportingManagedDeliveryRuntime(options) {
103
103
  getMediaBuyDelivery,
104
104
  ...syncReportingReceipts ? { syncReportingReceipts } : {},
105
105
  runWorker: (workerOptions) => runManagedDeliveryWorker(options.store, options.adapter, {
106
+ ...typeof options.coreStore.getRevision === "function" ? {
107
+ hydrateRevision: async (revision, accountId) => {
108
+ const hydrated = await options.coreStore.getRevision(revision.reporting_revision_id, accountId);
109
+ if (!hydrated) throw new Error("Reporting revision is unavailable for delivery");
110
+ return hydrated;
111
+ }
112
+ } : {},
106
113
  ...workerOptions,
107
114
  minimumResourceRetentionDays: Math.max(
108
115
  options.resourceRetentionDays,
@@ -329,6 +336,17 @@ async function runManagedDeliveryWorker(store, adapter, options = {}) {
329
336
  if (!lease) break;
330
337
  counts.claimed += 1;
331
338
  try {
339
+ if (!Array.isArray(lease.revision.rows) && options.hydrateRevision) {
340
+ const hydrated = await options.hydrateRevision(
341
+ lease.revision,
342
+ lease.obligation.account.account_id,
343
+ options.signal
344
+ );
345
+ if (hydrated.reporting_revision_id !== lease.revision.reporting_revision_id || hydrated.binding.sha256 !== lease.revision.binding.sha256 || !Array.isArray(hydrated.rows)) {
346
+ throw new Error("Hydrated reporting revision does not match the claimed revision");
347
+ }
348
+ lease.revision = hydrated;
349
+ }
332
350
  const outcome = await withinDeadline(
333
351
  (signal) => adapter.deliver(
334
352
  {
@@ -1,6 +1,8 @@
1
1
  import { REPORTING_LEDGER_AUTHORITY } from './types.mjs';
2
2
  import type { ReportingLedgerConfigurationV1, ReportingLedgerAdjustmentMetadataV1, ReportingLedgerAdjustmentV1, ReportingLedgerConsumerStatusV1, ReportingLedgerIssueV1, ReportingLedgerLeaseV1, ReportingLedgerObligationV1, ReportingLedgerPageV1, ReportingLedgerRevisionV1, ReportingLedgerSnapshotQueryV1, ReportingLedgerSnapshotV1, ReportingLedgerStatusTransitionV1, ReportingLedgerNotificationActivityPortV1, ReportingLedgerTransactionV1, ReportingObservedFinalityV1, ReportingLedgerStore, ReportingConsumerStatusBatchInputV1, ReportingConsumerStatusBatchResultV1, ReportingConsumerStatusReplayInputV1, ReportingLedgerRevisionMetadataV1, ReportingRevisionRowsPageV1, ReportingRevisionRowsReadV1, ReportingManagedLifecycleProjectionV1, ReportingLedgerAuthorityV1 } from './types.mjs';
3
3
  import type { ReportingConsumerMismatchEscalationV1 } from './types.mjs';
4
+ import { type ReportingChangeKindV1, type ReportingChangesPageV1 } from './change-feed.mjs';
5
+ import { type ReportingRowStorageOptionsV1 } from './row-storage.mjs';
4
6
  type QueryResultRow = Record<string, unknown>;
5
7
  interface ReportingPgResult<Row extends QueryResultRow> {
6
8
  rows: Row[];
@@ -86,10 +88,28 @@ export interface PostgresReportingLedgerStoreOptions {
86
88
  * lifecycle transaction. Its tables must be migrated before transitions run.
87
89
  */
88
90
  notificationActivityPort?: ReportingLedgerNotificationActivityPortV1<ReportingLedgerTransactionV1>;
91
+ /**
92
+ * Store new revision and adjustment rows as verified canonical JSONL chunks
93
+ * (see `REPORTING_ROW_STORAGE_MIGRATION`) instead of inline in the ledger
94
+ * document. `true` uses a single `postgres` binding. Revisions written
95
+ * before enabling this keep their inline rows; reads handle both forms
96
+ * whether or not this option is set.
97
+ */
98
+ rowStorage?: boolean | ReportingRowStorageOptionsV1;
99
+ /**
100
+ * Append obligation, revision, adjustment and retirement changes to the
101
+ * host change feed (`REPORTING_LEDGER_CHANGES_MIGRATION`, PostgreSQL 13+) in
102
+ * the same transaction as each record. Required for `changesAfter`.
103
+ */
104
+ changeFeed?: boolean;
89
105
  }
90
106
  export declare class ReportingLedgerLeaseLostError extends Error {
91
107
  constructor(message?: string);
92
108
  }
109
+ /** A planner or writer named a period whose ledger records were retired by retention. */
110
+ export declare class ReportingLedgerPeriodRetiredError extends Error {
111
+ constructor(message?: string);
112
+ }
93
113
  export declare class ReportingLedgerContinuityError extends Error {
94
114
  constructor(message?: string);
95
115
  }
@@ -113,7 +133,36 @@ export declare class PostgresReportingLedgerStore implements ReportingLedgerStor
113
133
  private readonly obligatedConsumers;
114
134
  readonly transactionalNotificationActivity: boolean;
115
135
  private readonly notificationActivityPort?;
136
+ private readonly rowStorage;
137
+ private readonly rowStorageWrites;
138
+ private readonly changeFeed;
116
139
  constructor(pool: ReportingPgPool, options?: PostgresReportingLedgerStoreOptions);
140
+ /** Append one host change-feed row inside the caller's account-locked transaction. */
141
+ private appendChange;
142
+ /** Probe and register row storage when enabled. Safe to call repeatedly. */
143
+ readyRowStorage(): Promise<void>;
144
+ /**
145
+ * Move legacy inline revision and adjustment rows into row storage, a
146
+ * bounded batch at a time. Each row set is re-encoded, proven to reproduce
147
+ * its committed binding, written, and only then removed from the ledger
148
+ * document, in one transaction under the account lock. A document whose
149
+ * rows do not reproduce its binding is never rewritten: it is reported in
150
+ * `quarantined` and left inline. Pass the returned `cursor` back to resume
151
+ * after the last examined document; it is absent once every candidate has
152
+ * been examined. Reclaiming the freed space needs `VACUUM FULL` or an online
153
+ * repack.
154
+ */
155
+ migrateInlineRows(input?: {
156
+ limit?: number;
157
+ account_id?: string;
158
+ cursor?: string;
159
+ bindingId?: string;
160
+ signal?: AbortSignal;
161
+ }): Promise<{
162
+ migrated: number;
163
+ quarantined: string[];
164
+ cursor?: string;
165
+ }>;
117
166
  putConfiguration(configuration: ReportingLedgerConfigurationV1): Promise<{
118
167
  inserted: boolean;
119
168
  value: ReportingLedgerConfigurationV1;
@@ -124,6 +173,11 @@ export declare class PostgresReportingLedgerStore implements ReportingLedgerStor
124
173
  value: ReportingLedgerObligationV1;
125
174
  }>;
126
175
  getObligation(id: string, account_id?: string): Promise<ReportingLedgerObligationV1 | null>;
176
+ /** Periods retired by retention; planners treat them as already covered. */
177
+ listRetiredObligationOrdinals(account_id?: string): Promise<{
178
+ configurationId: string;
179
+ periodOrdinal: number;
180
+ }[]>;
127
181
  listObligations(account_id?: string): Promise<ReportingLedgerObligationV1[]>;
128
182
  listLifecycleDueObligations(input: {
129
183
  ledgerAsOf: string;
@@ -152,6 +206,127 @@ export declare class PostgresReportingLedgerStore implements ReportingLedgerStor
152
206
  value: ReportingLedgerAdjustmentV1;
153
207
  }>;
154
208
  listAdjustments(obligationId: string): Promise<ReportingLedgerAdjustmentV1[]>;
209
+ /**
210
+ * The obligation's current revision header: its official revision if one
211
+ * exists, otherwise its highest-numbered snapshot. An official revision is
212
+ * terminal, so this is always the highest revision number — one index
213
+ * lookup. Rows are read separately through `readRevisionRows`.
214
+ */
215
+ getCurrentRevision(input: {
216
+ account_id: string;
217
+ reporting_obligation_id: string;
218
+ }): Promise<ReportingLedgerRevisionMetadataV1 | null>;
219
+ /**
220
+ * Current revision headers for an account's obligations whose period starts
221
+ * in `[period_start_from, period_start_to)`, ordered by period start.
222
+ * Obligations without a revision yet are omitted. Page with `cursor`.
223
+ */
224
+ listCurrentRevisions(input: {
225
+ account_id: string;
226
+ period_start_from: string;
227
+ period_start_to: string;
228
+ delivery_config_id?: string;
229
+ limit?: number;
230
+ cursor?: string;
231
+ }): Promise<{
232
+ revisions: ReportingLedgerRevisionMetadataV1[];
233
+ cursor?: string;
234
+ }>;
235
+ /**
236
+ * Host change feed. Omit `cursor` to start from the oldest retained change.
237
+ * Account-scoped feeds order by sequence; the deployment-wide feed orders by
238
+ * `(xid, seq)` and returns only changes whose transaction precedes every
239
+ * transaction still in flight, so no commit is ever skipped. A cursor older
240
+ * than the retained history throws `ReportingChangeCursorExpiredError`;
241
+ * resynchronize from `listCurrentRevisions`.
242
+ */
243
+ changesAfter(input?: {
244
+ cursor?: string;
245
+ account_id?: string;
246
+ kinds?: readonly ReportingChangeKindV1[];
247
+ limit?: number;
248
+ }): Promise<ReportingChangesPageV1>;
249
+ /**
250
+ * Record a named durable consumer's position. Registered consumers hold
251
+ * back change-table pruning until `maxFeedHoldDays` after their last update.
252
+ */
253
+ saveFeedConsumerCursor(name: string, cursor: string): Promise<void>;
254
+ /**
255
+ * Delete change rows older than `changeRetentionDays` that every consumer
256
+ * updated within `maxFeedHoldDays` has passed, and advance the expiry
257
+ * horizon so older cursors fail closed.
258
+ */
259
+ pruneChanges(input?: {
260
+ changeRetentionDays?: number;
261
+ maxFeedHoldDays?: number;
262
+ limit?: number;
263
+ }): Promise<{
264
+ deleted: number;
265
+ }>;
266
+ /**
267
+ * Retire whole reporting periods whose retention has elapsed (shared SDK
268
+ * persistence spec §4). A period is eligible once both its end and its
269
+ * latest publication are older than `max(statusRetentionDays,
270
+ * recordRetentionDays)`, no worker holds its lease, and no Managed Delivery
271
+ * materialization still references it. Retirement is period-aligned and
272
+ * resumable:
273
+ *
274
+ * 1. under the account lock, record a `retiring` tombstone and mark the
275
+ * period's row sets `pruning`, so exact reads answer as expired;
276
+ * 2. delete the period's external row objects at their recorded versions;
277
+ * 3. under the account lock, delete the period's ledger records (rows,
278
+ * revisions, adjustments, consumer statuses, issues, transitions,
279
+ * lifecycle state, obligation) and mark the tombstone `retired`.
280
+ *
281
+ * Planners skip retired periods, and `ledger_retained_from` advances past
282
+ * them because their obligations no longer exist.
283
+ */
284
+ retireExpiredPeriods(input: {
285
+ statusRetentionDays: number;
286
+ recordRetentionDays?: number;
287
+ limit?: number;
288
+ account_id?: string;
289
+ signal?: AbortSignal;
290
+ }): Promise<{
291
+ retired: number;
292
+ failed: string[];
293
+ /** Secret-free cause per failed period: a row-store code or the error class name. */
294
+ failures: {
295
+ reporting_obligation_id: string;
296
+ cause: string;
297
+ }[];
298
+ }>;
299
+ private retirePeriod;
300
+ /**
301
+ * Resolve abandoned object uploads (spec §4.3). An expired `open` write
302
+ * intent whose ledger commit never happened is moved to `sweeping` under
303
+ * the account lock, so no writer can commit against it, then only the
304
+ * objects that upload created — never adopted ones, never any object a
305
+ * committed chunk references — are deleted at their recorded versions.
306
+ * Interrupted sweeps resume.
307
+ */
308
+ sweepRowWriteIntents(input?: {
309
+ limit?: number;
310
+ account_id?: string;
311
+ signal?: AbortSignal;
312
+ }): Promise<{
313
+ swept: number;
314
+ objectsDeleted: number;
315
+ failed: number;
316
+ }>;
317
+ private optionalTables;
318
+ /**
319
+ * Upload an object-kind row set before its ledger commit (spec §3.5):
320
+ * skip when the document already exists (replay), refuse unless the lease
321
+ * still covers the upload deadline, open or take over an expired write
322
+ * intent under the account lock, then write every chunk create-only,
323
+ * recording each object this upload created in the intent first.
324
+ */
325
+ private uploadRowSetUnlessCommitted;
326
+ /** Persist a prepared row set and close its upload intent in the ledger commit transaction. */
327
+ private writePreparedRowSet;
328
+ /** Attach verified rows to a revision document whose rows live in row storage. */
329
+ private hydrateRevision;
155
330
  listAdjustmentMetadata(obligationId: string): Promise<ReportingLedgerAdjustmentMetadataV1[]>;
156
331
  putConsumerStatus(status: ReportingLedgerConsumerStatusV1): Promise<{
157
332
  inserted: boolean;