@adcp/sdk 15.4.0 → 15.6.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.
- package/README.md +15 -0
- package/dist/lib/advanced.d.mts +2 -2
- package/dist/lib/advanced.d.ts +2 -2
- package/dist/lib/advanced.js +8 -2
- package/dist/lib/advanced.mjs +8 -2
- package/dist/lib/auth/oauth/index.d.mts +1 -0
- package/dist/lib/auth/oauth/index.d.ts +1 -0
- package/dist/lib/auth/oauth/index.js +5 -0
- package/dist/lib/auth/oauth/index.mjs +3 -0
- package/dist/lib/auth/oauth/pending-web-flow.d.mts +16 -0
- package/dist/lib/auth/oauth/pending-web-flow.d.ts +16 -0
- package/dist/lib/auth/oauth/pending-web-flow.js +66 -0
- package/dist/lib/auth/oauth/pending-web-flow.mjs +41 -0
- package/dist/lib/auth/oauth/web-flow.js +3 -3
- package/dist/lib/auth/oauth/web-flow.mjs +3 -3
- package/dist/lib/core/AgentClient.d.mts +4 -0
- package/dist/lib/core/AgentClient.d.ts +4 -0
- package/dist/lib/core/AgentClient.js +8 -0
- package/dist/lib/core/AgentClient.mjs +8 -0
- package/dist/lib/core/SingleAgentClient.d.mts +154 -0
- package/dist/lib/core/SingleAgentClient.d.ts +154 -0
- package/dist/lib/core/SingleAgentClient.js +661 -23
- package/dist/lib/core/SingleAgentClient.mjs +666 -23
- package/dist/lib/core/agent-discovery-cache.d.mts +103 -0
- package/dist/lib/core/agent-discovery-cache.d.ts +103 -0
- package/dist/lib/core/agent-discovery-cache.js +121 -0
- package/dist/lib/core/agent-discovery-cache.mjs +92 -0
- package/dist/lib/index.d.mts +5 -3
- package/dist/lib/index.d.ts +5 -3
- package/dist/lib/index.js +7 -0
- package/dist/lib/index.mjs +6 -0
- package/dist/lib/protocols/index.d.mts +2 -2
- package/dist/lib/protocols/index.d.ts +2 -2
- package/dist/lib/protocols/index.js +1 -1
- package/dist/lib/protocols/index.mjs +1 -1
- package/dist/lib/protocols/mcp-call-context.d.mts +109 -0
- package/dist/lib/protocols/mcp-call-context.d.ts +109 -0
- package/dist/lib/protocols/mcp-call-context.js +221 -0
- package/dist/lib/protocols/mcp-call-context.mjs +186 -0
- package/dist/lib/protocols/mcp-modern.d.mts +9 -1
- package/dist/lib/protocols/mcp-modern.d.ts +9 -1
- package/dist/lib/protocols/mcp-modern.js +180 -104
- package/dist/lib/protocols/mcp-modern.mjs +193 -104
- package/dist/lib/protocols/mcp-scope.d.mts +15 -0
- package/dist/lib/protocols/mcp-scope.d.ts +15 -0
- package/dist/lib/protocols/mcp.d.mts +4 -2
- package/dist/lib/protocols/mcp.d.ts +4 -2
- package/dist/lib/protocols/mcp.js +178 -154
- package/dist/lib/protocols/mcp.mjs +189 -153
- package/dist/lib/protocols/transportDiagnostics.d.mts +33 -1
- package/dist/lib/protocols/transportDiagnostics.d.ts +33 -1
- package/dist/lib/protocols/transportDiagnostics.js +128 -12
- package/dist/lib/protocols/transportDiagnostics.mjs +128 -12
- package/dist/lib/registry/types.generated.d.mts +63 -1
- package/dist/lib/registry/types.generated.d.ts +63 -1
- package/dist/lib/reporting/azure/index.d.mts +26 -0
- package/dist/lib/reporting/azure/index.d.ts +26 -0
- package/dist/lib/reporting/azure/index.js +247 -0
- package/dist/lib/reporting/azure/index.mjs +230 -0
- package/dist/lib/reporting/bigquery/index.d.mts +127 -0
- package/dist/lib/reporting/bigquery/index.d.ts +127 -0
- package/dist/lib/reporting/bigquery/index.js +379 -0
- package/dist/lib/reporting/bigquery/index.mjs +341 -0
- package/dist/lib/reporting/gcs/index.d.mts +2 -0
- package/dist/lib/reporting/gcs/index.d.ts +2 -0
- package/dist/lib/reporting/gcs/index.js +3 -0
- package/dist/lib/reporting/gcs/index.mjs +2 -0
- package/dist/lib/reporting/gcs/row-provider.d.mts +32 -0
- package/dist/lib/reporting/gcs/row-provider.d.ts +32 -0
- package/dist/lib/reporting/gcs/row-provider.js +205 -0
- package/dist/lib/reporting/gcs/row-provider.mjs +188 -0
- package/dist/lib/reporting/ledger/change-feed.d.mts +41 -0
- package/dist/lib/reporting/ledger/change-feed.d.ts +41 -0
- package/dist/lib/reporting/ledger/change-feed.js +101 -0
- package/dist/lib/reporting/ledger/change-feed.mjs +74 -0
- package/dist/lib/reporting/ledger/handler.js +22 -8
- package/dist/lib/reporting/ledger/handler.mjs +22 -8
- package/dist/lib/reporting/ledger/index.d.mts +4 -0
- package/dist/lib/reporting/ledger/index.d.ts +4 -0
- package/dist/lib/reporting/ledger/index.js +9 -1
- package/dist/lib/reporting/ledger/index.mjs +4 -0
- package/dist/lib/reporting/ledger/managed-postgres.d.mts +2 -0
- package/dist/lib/reporting/ledger/managed-postgres.d.ts +2 -0
- package/dist/lib/reporting/ledger/managed-postgres.js +21 -1
- package/dist/lib/reporting/ledger/managed-postgres.mjs +21 -1
- package/dist/lib/reporting/ledger/managed.d.mts +9 -0
- package/dist/lib/reporting/ledger/managed.d.ts +9 -0
- package/dist/lib/reporting/ledger/managed.js +18 -0
- package/dist/lib/reporting/ledger/managed.mjs +18 -0
- package/dist/lib/reporting/ledger/postgres.d.mts +185 -0
- package/dist/lib/reporting/ledger/postgres.d.ts +185 -0
- package/dist/lib/reporting/ledger/postgres.js +872 -26
- package/dist/lib/reporting/ledger/postgres.mjs +880 -26
- package/dist/lib/reporting/ledger/producer.js +10 -1
- package/dist/lib/reporting/ledger/producer.mjs +10 -1
- package/dist/lib/reporting/ledger/row-storage-errors.d.mts +7 -0
- package/dist/lib/reporting/ledger/row-storage-errors.d.ts +7 -0
- package/dist/lib/reporting/ledger/row-storage-errors.js +41 -0
- package/dist/lib/reporting/ledger/row-storage-errors.mjs +16 -0
- package/dist/lib/reporting/ledger/row-storage-migration.d.mts +41 -0
- package/dist/lib/reporting/ledger/row-storage-migration.d.ts +41 -0
- package/dist/lib/reporting/ledger/row-storage-migration.js +234 -0
- package/dist/lib/reporting/ledger/row-storage-migration.mjs +208 -0
- package/dist/lib/reporting/ledger/row-storage-object.d.mts +112 -0
- package/dist/lib/reporting/ledger/row-storage-object.d.ts +112 -0
- package/dist/lib/reporting/ledger/row-storage-object.js +304 -0
- package/dist/lib/reporting/ledger/row-storage-object.mjs +262 -0
- package/dist/lib/reporting/ledger/row-storage-provider-io.d.mts +44 -0
- package/dist/lib/reporting/ledger/row-storage-provider-io.d.ts +44 -0
- package/dist/lib/reporting/ledger/row-storage-provider-io.js +142 -0
- package/dist/lib/reporting/ledger/row-storage-provider-io.mjs +111 -0
- package/dist/lib/reporting/ledger/row-storage.d.mts +224 -0
- package/dist/lib/reporting/ledger/row-storage.d.ts +224 -0
- package/dist/lib/reporting/ledger/row-storage.js +692 -0
- package/dist/lib/reporting/ledger/row-storage.mjs +680 -0
- package/dist/lib/reporting/ledger/types.d.mts +8 -0
- package/dist/lib/reporting/ledger/types.d.ts +8 -0
- package/dist/lib/reporting/s3/index.d.mts +29 -0
- package/dist/lib/reporting/s3/index.d.ts +29 -0
- package/dist/lib/reporting/s3/index.js +324 -0
- package/dist/lib/reporting/s3/index.mjs +317 -0
- package/dist/lib/reporting/service/index.d.mts +43 -1
- package/dist/lib/reporting/service/index.d.ts +43 -1
- package/dist/lib/reporting/service/index.js +69 -1
- package/dist/lib/reporting/service/index.mjs +71 -1
- package/dist/lib/schemas/browser.d.mts +14 -0
- package/dist/lib/schemas/browser.d.ts +14 -0
- package/dist/lib/schemas/browser.js +48 -0
- package/dist/lib/schemas/browser.mjs +20 -0
- package/dist/lib/schemas/index.d.mts +2 -120
- package/dist/lib/schemas/index.d.ts +2 -120
- package/dist/lib/schemas/index.js +3 -11
- package/dist/lib/schemas/index.mjs +1 -9
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/testing/index.d.mts +1 -0
- package/dist/lib/testing/index.d.ts +1 -0
- package/dist/lib/testing/index.js +3 -0
- package/dist/lib/testing/index.mjs +2 -0
- package/dist/lib/testing/pending-web-flow-store.d.mts +20 -0
- package/dist/lib/testing/pending-web-flow-store.d.ts +20 -0
- package/dist/lib/testing/pending-web-flow-store.js +132 -0
- package/dist/lib/testing/pending-web-flow-store.mjs +98 -0
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/validation/get-products-request.d.mts +122 -0
- package/dist/lib/validation/get-products-request.d.ts +122 -0
- package/dist/lib/validation/get-products-request.js +39 -0
- package/dist/lib/validation/get-products-request.mjs +14 -0
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/docs/README.md +1 -1
- package/docs/TYPE-SUMMARY.md +35 -2
- package/docs/ZOD-SCHEMAS.md +13 -1
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +142 -0
- package/docs/guides/EXISTING-PLATFORM.md +43 -12
- package/docs/guides/OAUTH-ISSUER-BINDING.md +6 -0
- package/docs/guides/REPORTING-LEDGER.md +374 -0
- package/docs/guides/REPORTING-OPERATIONS.md +76 -1
- package/docs/guides/WEB-OAUTH.md +48 -1
- package/docs/llms.txt +4 -2
- package/docs/migration-14.x-rc-worksheet.md +6 -4
- package/package.json +64 -1
|
@@ -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
|
-
|
|
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
|
-
|
|
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,137 @@ 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
|
+
* When the change-feed tables exist, a period that is not yet retiring is
|
|
285
|
+
* also held while any live registered feed consumer (updated within
|
|
286
|
+
* `maxFeedHoldDays`, default 7) has not passed that period's change rows in
|
|
287
|
+
* the consumer's own feed order, the same rule `pruneChanges` applies. A
|
|
288
|
+
* held period is simply not a candidate this pass. A consumer that stays
|
|
289
|
+
* silent past `maxFeedHoldDays` stops holding, so retention is never
|
|
290
|
+
* blocked forever; it then falls behind retention and a sink sees the
|
|
291
|
+
* retired revisions as missing.
|
|
292
|
+
*/
|
|
293
|
+
retireExpiredPeriods(input: {
|
|
294
|
+
statusRetentionDays: number;
|
|
295
|
+
recordRetentionDays?: number;
|
|
296
|
+
maxFeedHoldDays?: number;
|
|
297
|
+
limit?: number;
|
|
298
|
+
account_id?: string;
|
|
299
|
+
signal?: AbortSignal;
|
|
300
|
+
}): Promise<{
|
|
301
|
+
retired: number;
|
|
302
|
+
failed: string[];
|
|
303
|
+
/** Secret-free cause per failed period: a row-store code or the error class name. */
|
|
304
|
+
failures: {
|
|
305
|
+
reporting_obligation_id: string;
|
|
306
|
+
cause: string;
|
|
307
|
+
}[];
|
|
308
|
+
}>;
|
|
309
|
+
private retirePeriod;
|
|
310
|
+
/**
|
|
311
|
+
* Resolve abandoned object uploads (spec §4.3). An expired `open` write
|
|
312
|
+
* intent whose ledger commit never happened is moved to `sweeping` under
|
|
313
|
+
* the account lock, so no writer can commit against it, then only the
|
|
314
|
+
* objects that upload created — never adopted ones, never any object a
|
|
315
|
+
* committed chunk references — are deleted at their recorded versions.
|
|
316
|
+
* Interrupted sweeps resume.
|
|
317
|
+
*/
|
|
318
|
+
sweepRowWriteIntents(input?: {
|
|
319
|
+
limit?: number;
|
|
320
|
+
account_id?: string;
|
|
321
|
+
signal?: AbortSignal;
|
|
322
|
+
}): Promise<{
|
|
323
|
+
swept: number;
|
|
324
|
+
objectsDeleted: number;
|
|
325
|
+
failed: number;
|
|
326
|
+
}>;
|
|
327
|
+
private optionalTables;
|
|
328
|
+
/**
|
|
329
|
+
* Upload an object-kind row set before its ledger commit (spec §3.5):
|
|
330
|
+
* skip when the document already exists (replay), refuse unless the lease
|
|
331
|
+
* still covers the upload deadline, open or take over an expired write
|
|
332
|
+
* intent under the account lock, then write every chunk create-only,
|
|
333
|
+
* recording each object this upload created in the intent first.
|
|
334
|
+
*/
|
|
335
|
+
private uploadRowSetUnlessCommitted;
|
|
336
|
+
/** Persist a prepared row set and close its upload intent in the ledger commit transaction. */
|
|
337
|
+
private writePreparedRowSet;
|
|
338
|
+
/** Attach verified rows to a revision document whose rows live in row storage. */
|
|
339
|
+
private hydrateRevision;
|
|
155
340
|
listAdjustmentMetadata(obligationId: string): Promise<ReportingLedgerAdjustmentMetadataV1[]>;
|
|
156
341
|
putConsumerStatus(status: ReportingLedgerConsumerStatusV1): Promise<{
|
|
157
342
|
inserted: boolean;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { REPORTING_LEDGER_AUTHORITY } from './types';
|
|
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';
|
|
3
3
|
import type { ReportingConsumerMismatchEscalationV1 } from './types';
|
|
4
|
+
import { type ReportingChangeKindV1, type ReportingChangesPageV1 } from './change-feed';
|
|
5
|
+
import { type ReportingRowStorageOptionsV1 } from './row-storage';
|
|
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,137 @@ 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
|
+
* When the change-feed tables exist, a period that is not yet retiring is
|
|
285
|
+
* also held while any live registered feed consumer (updated within
|
|
286
|
+
* `maxFeedHoldDays`, default 7) has not passed that period's change rows in
|
|
287
|
+
* the consumer's own feed order, the same rule `pruneChanges` applies. A
|
|
288
|
+
* held period is simply not a candidate this pass. A consumer that stays
|
|
289
|
+
* silent past `maxFeedHoldDays` stops holding, so retention is never
|
|
290
|
+
* blocked forever; it then falls behind retention and a sink sees the
|
|
291
|
+
* retired revisions as missing.
|
|
292
|
+
*/
|
|
293
|
+
retireExpiredPeriods(input: {
|
|
294
|
+
statusRetentionDays: number;
|
|
295
|
+
recordRetentionDays?: number;
|
|
296
|
+
maxFeedHoldDays?: number;
|
|
297
|
+
limit?: number;
|
|
298
|
+
account_id?: string;
|
|
299
|
+
signal?: AbortSignal;
|
|
300
|
+
}): Promise<{
|
|
301
|
+
retired: number;
|
|
302
|
+
failed: string[];
|
|
303
|
+
/** Secret-free cause per failed period: a row-store code or the error class name. */
|
|
304
|
+
failures: {
|
|
305
|
+
reporting_obligation_id: string;
|
|
306
|
+
cause: string;
|
|
307
|
+
}[];
|
|
308
|
+
}>;
|
|
309
|
+
private retirePeriod;
|
|
310
|
+
/**
|
|
311
|
+
* Resolve abandoned object uploads (spec §4.3). An expired `open` write
|
|
312
|
+
* intent whose ledger commit never happened is moved to `sweeping` under
|
|
313
|
+
* the account lock, so no writer can commit against it, then only the
|
|
314
|
+
* objects that upload created — never adopted ones, never any object a
|
|
315
|
+
* committed chunk references — are deleted at their recorded versions.
|
|
316
|
+
* Interrupted sweeps resume.
|
|
317
|
+
*/
|
|
318
|
+
sweepRowWriteIntents(input?: {
|
|
319
|
+
limit?: number;
|
|
320
|
+
account_id?: string;
|
|
321
|
+
signal?: AbortSignal;
|
|
322
|
+
}): Promise<{
|
|
323
|
+
swept: number;
|
|
324
|
+
objectsDeleted: number;
|
|
325
|
+
failed: number;
|
|
326
|
+
}>;
|
|
327
|
+
private optionalTables;
|
|
328
|
+
/**
|
|
329
|
+
* Upload an object-kind row set before its ledger commit (spec §3.5):
|
|
330
|
+
* skip when the document already exists (replay), refuse unless the lease
|
|
331
|
+
* still covers the upload deadline, open or take over an expired write
|
|
332
|
+
* intent under the account lock, then write every chunk create-only,
|
|
333
|
+
* recording each object this upload created in the intent first.
|
|
334
|
+
*/
|
|
335
|
+
private uploadRowSetUnlessCommitted;
|
|
336
|
+
/** Persist a prepared row set and close its upload intent in the ledger commit transaction. */
|
|
337
|
+
private writePreparedRowSet;
|
|
338
|
+
/** Attach verified rows to a revision document whose rows live in row storage. */
|
|
339
|
+
private hydrateRevision;
|
|
155
340
|
listAdjustmentMetadata(obligationId: string): Promise<ReportingLedgerAdjustmentMetadataV1[]>;
|
|
156
341
|
putConsumerStatus(status: ReportingLedgerConsumerStatusV1): Promise<{
|
|
157
342
|
inserted: boolean;
|