@adcp/sdk 15.9.0 → 16.0.0-beta.1
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/bin/adcp-identity.js +74 -0
- package/bin/adcp.js +2 -0
- package/dist/lib/adapters/keyed-account-backend.d.mts +37 -0
- package/dist/lib/adapters/keyed-account-backend.d.ts +37 -0
- package/dist/lib/adapters/keyed-account-backend.js +121 -0
- package/dist/lib/adapters/keyed-account-backend.mjs +94 -0
- package/dist/lib/adapters/keyed-account-store.d.mts +28 -0
- package/dist/lib/adapters/keyed-account-store.d.ts +28 -0
- package/dist/lib/adapters/keyed-account-store.js +227 -0
- package/dist/lib/adapters/keyed-account-store.mjs +203 -0
- package/dist/lib/core/SingleAgentClient.d.mts +16 -2
- package/dist/lib/core/SingleAgentClient.d.ts +16 -2
- package/dist/lib/core/SingleAgentClient.js +259 -62
- package/dist/lib/core/SingleAgentClient.mjs +261 -57
- package/dist/lib/core/TaskExecutor.d.mts +6 -0
- package/dist/lib/core/TaskExecutor.d.ts +6 -0
- package/dist/lib/core/TaskExecutor.js +66 -5
- package/dist/lib/core/TaskExecutor.mjs +71 -5
- package/dist/lib/core/postgres-webhook-registration-store.js +32 -5
- package/dist/lib/core/postgres-webhook-registration-store.mjs +32 -5
- package/dist/lib/core/redis-webhook-registration-store.js +23 -1
- package/dist/lib/core/redis-webhook-registration-store.mjs +23 -1
- package/dist/lib/core/webhook-registration.d.mts +7 -1
- package/dist/lib/core/webhook-registration.d.ts +7 -1
- package/dist/lib/core/webhook-registration.js +24 -2
- package/dist/lib/core/webhook-registration.mjs +23 -2
- package/dist/lib/identity-3.3/index.d.mts +10 -0
- package/dist/lib/identity-3.3/index.d.ts +10 -0
- package/dist/lib/identity-3.3/index.js +75 -0
- package/dist/lib/identity-3.3/index.mjs +46 -0
- package/dist/lib/identity-3.3/lifecycle.d.mts +113 -0
- package/dist/lib/identity-3.3/lifecycle.d.ts +113 -0
- package/dist/lib/identity-3.3/lifecycle.js +267 -0
- package/dist/lib/identity-3.3/lifecycle.mjs +240 -0
- package/dist/lib/identity-3.3/revocation.d.mts +50 -0
- package/dist/lib/identity-3.3/revocation.d.ts +50 -0
- package/dist/lib/identity-3.3/revocation.js +238 -0
- package/dist/lib/identity-3.3/revocation.mjs +216 -0
- package/dist/lib/identity-3.3/schemas.draft.d.mts +2472 -0
- package/dist/lib/identity-3.3/schemas.draft.d.ts +2472 -0
- package/dist/lib/identity-3.3/schemas.draft.js +1448 -0
- package/dist/lib/identity-3.3/schemas.draft.mjs +1428 -0
- package/dist/lib/identity-3.3/server.d.mts +34 -0
- package/dist/lib/identity-3.3/server.d.ts +34 -0
- package/dist/lib/identity-3.3/server.js +219 -0
- package/dist/lib/identity-3.3/server.mjs +194 -0
- package/dist/lib/identity-3.3/store.d.mts +24 -0
- package/dist/lib/identity-3.3/store.d.ts +24 -0
- package/dist/lib/identity-3.3/store.js +191 -0
- package/dist/lib/identity-3.3/store.mjs +169 -0
- package/dist/lib/identity-3.3/trust.d.mts +94 -0
- package/dist/lib/identity-3.3/trust.d.ts +94 -0
- package/dist/lib/identity-3.3/trust.js +278 -0
- package/dist/lib/identity-3.3/trust.mjs +239 -0
- package/dist/lib/identity-3.3/types.d.mts +127 -0
- package/dist/lib/identity-3.3/types.d.ts +127 -0
- package/dist/lib/identity-3.3/types.js +16 -0
- package/dist/lib/identity-3.3/types.mjs +0 -0
- package/dist/lib/identity-3.3/validation.d.mts +2 -0
- package/dist/lib/identity-3.3/validation.d.ts +2 -0
- package/dist/lib/identity-3.3/validation.js +125 -0
- package/dist/lib/identity-3.3/validation.mjs +91 -0
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/reporting/azure/index.d.mts +5 -0
- package/dist/lib/reporting/azure/index.d.ts +5 -0
- package/dist/lib/reporting/azure/index.js +26 -7
- package/dist/lib/reporting/azure/index.mjs +26 -7
- package/dist/lib/reporting/bigquery/index.d.mts +80 -25
- package/dist/lib/reporting/bigquery/index.d.ts +80 -25
- package/dist/lib/reporting/bigquery/index.js +184 -81
- package/dist/lib/reporting/bigquery/index.mjs +182 -80
- package/dist/lib/reporting/gcs/adapter.d.mts +8 -1
- package/dist/lib/reporting/gcs/adapter.d.ts +8 -1
- package/dist/lib/reporting/gcs/errors.d.mts +6 -0
- package/dist/lib/reporting/gcs/errors.d.ts +6 -0
- package/dist/lib/reporting/gcs/fence.d.mts +5 -0
- package/dist/lib/reporting/gcs/fence.d.ts +5 -0
- package/dist/lib/reporting/gcs/index.d.mts +9 -0
- package/dist/lib/reporting/gcs/index.d.ts +9 -0
- package/dist/lib/reporting/gcs/reader.d.mts +27 -3
- package/dist/lib/reporting/gcs/reader.d.ts +27 -3
- package/dist/lib/reporting/gcs/row-provider.d.mts +7 -0
- package/dist/lib/reporting/gcs/row-provider.d.ts +7 -0
- package/dist/lib/reporting/gcs/row-provider.js +34 -14
- package/dist/lib/reporting/gcs/row-provider.mjs +34 -14
- package/dist/lib/reporting/ledger/change-feed.d.mts +22 -1
- package/dist/lib/reporting/ledger/change-feed.d.ts +22 -1
- package/dist/lib/reporting/ledger/index.d.mts +11 -0
- package/dist/lib/reporting/ledger/index.d.ts +11 -0
- package/dist/lib/reporting/ledger/managed-postgres.d.mts +8 -0
- package/dist/lib/reporting/ledger/managed-postgres.d.ts +8 -0
- package/dist/lib/reporting/ledger/managed-router.d.mts +27 -2
- package/dist/lib/reporting/ledger/managed-router.d.ts +27 -2
- package/dist/lib/reporting/ledger/managed.d.mts +86 -6
- package/dist/lib/reporting/ledger/managed.d.ts +86 -6
- package/dist/lib/reporting/ledger/notification-activity.d.mts +65 -3
- package/dist/lib/reporting/ledger/notification-activity.d.ts +65 -3
- package/dist/lib/reporting/ledger/object-writes.d.mts +64 -5
- package/dist/lib/reporting/ledger/object-writes.d.ts +64 -5
- package/dist/lib/reporting/ledger/postgres.d.mts +43 -9
- package/dist/lib/reporting/ledger/postgres.d.ts +43 -9
- package/dist/lib/reporting/ledger/postgres.js +43 -27
- package/dist/lib/reporting/ledger/postgres.mjs +43 -27
- package/dist/lib/reporting/ledger/row-encoding.d.mts +92 -6
- package/dist/lib/reporting/ledger/row-encoding.d.ts +92 -6
- package/dist/lib/reporting/ledger/row-encoding.js +8 -4
- package/dist/lib/reporting/ledger/row-encoding.mjs +6 -3
- package/dist/lib/reporting/ledger/row-storage-errors.d.mts +11 -1
- package/dist/lib/reporting/ledger/row-storage-errors.d.ts +11 -1
- package/dist/lib/reporting/ledger/row-storage-migration.d.mts +19 -1
- package/dist/lib/reporting/ledger/row-storage-migration.d.ts +19 -1
- package/dist/lib/reporting/ledger/row-storage-migration.js +133 -18
- package/dist/lib/reporting/ledger/row-storage-migration.mjs +133 -18
- package/dist/lib/reporting/ledger/row-storage-object.d.mts +103 -12
- package/dist/lib/reporting/ledger/row-storage-object.d.ts +103 -12
- package/dist/lib/reporting/ledger/row-storage-object.js +106 -31
- package/dist/lib/reporting/ledger/row-storage-object.mjs +104 -31
- package/dist/lib/reporting/ledger/row-storage.d.mts +87 -20
- package/dist/lib/reporting/ledger/row-storage.d.ts +87 -20
- package/dist/lib/reporting/ledger/row-storage.js +126 -66
- package/dist/lib/reporting/ledger/row-storage.mjs +129 -67
- package/dist/lib/reporting/ledger/schedule.d.mts +13 -0
- package/dist/lib/reporting/ledger/schedule.d.ts +13 -0
- package/dist/lib/reporting/ledger/schedule.js +24 -0
- package/dist/lib/reporting/ledger/schedule.mjs +23 -0
- package/dist/lib/reporting/ledger/types.d.mts +23 -1
- package/dist/lib/reporting/ledger/types.d.ts +23 -1
- package/dist/lib/reporting/s3/index.d.mts +5 -0
- package/dist/lib/reporting/s3/index.d.ts +5 -0
- package/dist/lib/reporting/s3/index.js +37 -14
- package/dist/lib/reporting/s3/index.mjs +37 -14
- package/dist/lib/reporting/service/index.d.mts +10 -0
- package/dist/lib/reporting/service/index.d.ts +10 -0
- package/dist/lib/reporting/service/maintenance.d.mts +28 -2
- package/dist/lib/reporting/service/maintenance.d.ts +28 -2
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/account-sync-contract.d.mts +14 -0
- package/dist/lib/server/account-sync-contract.d.ts +14 -0
- package/dist/lib/server/account-sync-contract.js +225 -0
- package/dist/lib/server/account-sync-contract.mjs +197 -0
- package/dist/lib/server/adcp-server.js +5 -0
- package/dist/lib/server/adcp-server.mjs +10 -0
- package/dist/lib/server/auth-signature.d.mts +10 -0
- package/dist/lib/server/auth-signature.d.ts +10 -0
- package/dist/lib/server/auth-signature.js +61 -2
- package/dist/lib/server/auth-signature.mjs +65 -2
- package/dist/lib/server/auth.d.mts +6 -0
- package/dist/lib/server/auth.d.ts +6 -0
- package/dist/lib/server/auth.js +6 -0
- package/dist/lib/server/auth.mjs +6 -0
- package/dist/lib/server/create-adcp-server.d.mts +19 -5
- package/dist/lib/server/create-adcp-server.d.ts +19 -5
- package/dist/lib/server/create-adcp-server.js +238 -19
- package/dist/lib/server/create-adcp-server.mjs +240 -10
- package/dist/lib/server/decisioning/account.d.mts +24 -1
- package/dist/lib/server/decisioning/account.d.ts +24 -1
- package/dist/lib/server/decisioning/index.d.mts +1 -1
- package/dist/lib/server/decisioning/index.d.ts +1 -1
- package/dist/lib/server/decisioning/runtime/from-platform.d.mts +0 -50
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts +0 -50
- package/dist/lib/server/decisioning/runtime/from-platform.js +61 -11
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +65 -12
- package/dist/lib/server/index.d.mts +2 -0
- package/dist/lib/server/index.d.ts +2 -0
- package/dist/lib/server/index.js +12 -0
- package/dist/lib/server/index.mjs +12 -0
- package/dist/lib/server/notification-subscriptions/runtime.js +9 -1
- package/dist/lib/server/notification-subscriptions/runtime.mjs +9 -1
- package/dist/lib/server/notification-subscriptions/types.d.mts +5 -0
- package/dist/lib/server/notification-subscriptions/types.d.ts +5 -0
- package/dist/lib/server/principal/types.d.mts +1 -1
- package/dist/lib/server/principal/types.d.ts +1 -1
- package/dist/lib/server/serve.js +5 -0
- package/dist/lib/server/serve.mjs +5 -0
- package/dist/lib/server/webhook-delivery/recovery.d.mts +1 -0
- package/dist/lib/server/webhook-delivery/recovery.d.ts +1 -0
- package/dist/lib/server/webhook-delivery/recovery.js +4 -0
- package/dist/lib/server/webhook-delivery/recovery.mjs +4 -0
- package/dist/lib/server/webhook-emitter.d.mts +10 -0
- package/dist/lib/server/webhook-emitter.d.ts +10 -0
- package/dist/lib/server/webhook-emitter.js +22 -0
- package/dist/lib/server/webhook-emitter.mjs +22 -0
- package/dist/lib/signing/agent-context.d.mts +0 -5
- package/dist/lib/signing/agent-context.d.ts +0 -5
- package/dist/lib/signing/agent-context.js +9 -1
- package/dist/lib/signing/agent-context.mjs +9 -1
- package/dist/lib/signing/agent-fetch.js +27 -2
- package/dist/lib/signing/agent-fetch.mjs +32 -2
- package/dist/lib/signing/agent-resolver/canonicalize.d.mts +10 -15
- package/dist/lib/signing/agent-resolver/canonicalize.d.ts +10 -15
- package/dist/lib/signing/agent-resolver/canonicalize.js +17 -5
- package/dist/lib/signing/agent-resolver/canonicalize.mjs +16 -5
- package/dist/lib/signing/agent-resolver/index.d.mts +1 -0
- package/dist/lib/signing/agent-resolver/index.d.ts +1 -0
- package/dist/lib/signing/agent-resolver/index.js +5 -0
- package/dist/lib/signing/agent-resolver/index.mjs +3 -0
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +3 -2
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +3 -2
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +30 -3
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +30 -3
- package/dist/lib/signing/agent-resolver/strict-json.d.mts +2 -2
- package/dist/lib/signing/agent-resolver/strict-json.d.ts +2 -2
- package/dist/lib/signing/agent-resolver/strict-json.js +5 -3
- package/dist/lib/signing/agent-resolver/strict-json.mjs +5 -3
- package/dist/lib/signing/brand-jwks.d.mts +2 -2
- package/dist/lib/signing/brand-jwks.d.ts +2 -2
- package/dist/lib/signing/brand-jwks.js +4 -4
- package/dist/lib/signing/brand-jwks.mjs +4 -4
- package/dist/lib/signing/client.d.mts +1 -0
- package/dist/lib/signing/client.d.ts +1 -0
- package/dist/lib/signing/client.js +5 -0
- package/dist/lib/signing/client.mjs +3 -0
- package/dist/lib/signing/jwks-https.d.mts +1 -1
- package/dist/lib/signing/jwks-https.d.ts +1 -1
- package/dist/lib/signing/jwks-https.js +1 -1
- package/dist/lib/signing/jwks-https.mjs +1 -1
- package/dist/lib/signing/jwks.d.mts +11 -3
- package/dist/lib/signing/jwks.d.ts +11 -3
- package/dist/lib/signing/jwks.js +1 -1
- package/dist/lib/signing/jwks.mjs +1 -1
- package/dist/lib/signing/parser.d.mts +1 -1
- package/dist/lib/signing/parser.d.ts +1 -1
- package/dist/lib/signing/parser.js +5 -3
- package/dist/lib/signing/parser.mjs +6 -4
- package/dist/lib/signing/revocation.d.mts +4 -1
- package/dist/lib/signing/revocation.d.ts +4 -1
- package/dist/lib/signing/revocation.js +33 -3
- package/dist/lib/signing/revocation.mjs +31 -2
- package/dist/lib/signing/server.d.mts +1 -1
- package/dist/lib/signing/server.d.ts +1 -1
- package/dist/lib/signing/server.js +4 -0
- package/dist/lib/signing/server.mjs +4 -0
- package/dist/lib/signing/types.d.mts +3 -0
- package/dist/lib/signing/types.d.ts +3 -0
- package/dist/lib/signing/web-bot-auth.d.mts +117 -0
- package/dist/lib/signing/web-bot-auth.d.ts +117 -0
- package/dist/lib/signing/web-bot-auth.js +660 -0
- package/dist/lib/signing/web-bot-auth.mjs +624 -0
- package/dist/lib/testing/client.d.mts +1 -4
- package/dist/lib/testing/client.d.ts +1 -4
- package/dist/lib/testing/client.js +141 -20
- package/dist/lib/testing/client.mjs +137 -19
- package/dist/lib/testing/compliance/comply.js +29 -10
- package/dist/lib/testing/compliance/comply.mjs +37 -11
- package/dist/lib/testing/storyboard/account-sync-contract.d.mts +3 -0
- package/dist/lib/testing/storyboard/account-sync-contract.d.ts +3 -0
- package/dist/lib/testing/storyboard/account-sync-contract.js +79 -0
- package/dist/lib/testing/storyboard/account-sync-contract.mjs +55 -0
- package/dist/lib/testing/storyboard/default-invariants.js +2 -0
- package/dist/lib/testing/storyboard/default-invariants.mjs +2 -0
- package/dist/lib/testing/storyboard/runner.js +23 -8
- package/dist/lib/testing/storyboard/runner.mjs +24 -8
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/types/adcp.d.mts +4 -0
- package/dist/lib/types/adcp.d.ts +4 -0
- package/dist/lib/types/schemas.generated.d.ts +6 -6
- package/dist/lib/utils/capabilities.d.mts +1 -0
- package/dist/lib/utils/capabilities.d.ts +1 -0
- package/dist/lib/utils/capabilities.js +5 -0
- package/dist/lib/utils/capabilities.mjs +5 -0
- package/dist/lib/v2/projection/creative-delivery.d.mts +3 -1
- package/dist/lib/v2/projection/creative-delivery.d.ts +3 -1
- package/dist/lib/v2/projection/creative-delivery.js +26 -10
- package/dist/lib/v2/projection/creative-delivery.mjs +26 -10
- package/dist/lib/v2/projection/index.d.mts +1 -1
- package/dist/lib/v2/projection/index.d.ts +1 -1
- package/dist/lib/v2/projection/legacy-routes.d.mts +24 -2
- package/dist/lib/v2/projection/legacy-routes.d.ts +24 -2
- package/dist/lib/v2/projection/legacy-routes.js +28 -2
- package/dist/lib/v2/projection/legacy-routes.mjs +26 -2
- package/dist/lib/validation/schema-loader.d.mts +2 -0
- package/dist/lib/validation/schema-loader.d.ts +2 -0
- package/dist/lib/validation/schema-loader.js +43 -4
- package/dist/lib/validation/schema-loader.mjs +39 -3
- 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/TYPE-SUMMARY.md +2 -2
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +4 -0
- package/docs/guides/REPORTING-LEDGER-CUTOVER.md +1 -1
- package/docs/guides/REPORTING-LEDGER.md +132 -46
- package/docs/guides/REPORTING-OPERATIONS.md +25 -4
- package/docs/guides/REPORTING-STABILITY.md +76 -0
- package/docs/guides/account-resolution.md +101 -0
- package/docs/llms.txt +3 -2
- package/docs/migration-12-to-13.md +7 -0
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-agent-identity-3.3.md +355 -0
- package/docs/migration-agent-resolution-3.3.md +5 -0
- package/docs/migration-reporting-row-storage-alignment.md +137 -0
- package/examples/storyboards/account-sync-contract.yaml +57 -0
- package/package.json +15 -1
|
@@ -3,6 +3,9 @@ import { promises as fs } from "fs";
|
|
|
3
3
|
import * as path from "path";
|
|
4
4
|
import { canonicalize } from "../../utils/jcs.mjs";
|
|
5
5
|
import { ReportingRowStoreError } from "./row-storage-errors.mjs";
|
|
6
|
+
import { reportingPeriodDate } from "./schedule.mjs";
|
|
7
|
+
const REPORTING_ROW_OBJECT_REF_MAX_LENGTH = 1024;
|
|
8
|
+
const REPORTING_ROW_NATIVE_VERSION_REF_MAX_LENGTH = 1024;
|
|
6
9
|
const REPORTING_ROW_KEY_PLACEHOLDERS = Object.freeze([
|
|
7
10
|
"prefix",
|
|
8
11
|
"namespace_key",
|
|
@@ -17,13 +20,18 @@ const REPORTING_ROW_DEFAULT_KEY_TEMPLATE = "{prefix}/{namespace_key}/{account_ke
|
|
|
17
20
|
const PREFIX = /^[A-Za-z0-9_.=-]+(?:\/[A-Za-z0-9_.=-]+)*$/;
|
|
18
21
|
const KEY = /^[A-Za-z0-9_.=-]+(?:\/[A-Za-z0-9_.=-]+)*$/;
|
|
19
22
|
const PLACEHOLDER = /\{([a-z0-9_]+)\}/g;
|
|
20
|
-
function assertReportingRowKeyTemplateV1(template) {
|
|
23
|
+
function assertReportingRowKeyTemplateV1(template, options = {}) {
|
|
21
24
|
if (!template.startsWith("{prefix}/{namespace_key}/")) {
|
|
22
25
|
throw new ReportingRowStoreError("INVALID_INPUT", "key templates must begin with {prefix}/{namespace_key}/");
|
|
23
26
|
}
|
|
24
|
-
|
|
27
|
+
const requiredPlaceholders = ["{content_sha256}", "{chunk_index}"];
|
|
28
|
+
if (options.requireRevisionKey ?? true) requiredPlaceholders.push("{revision_key}");
|
|
29
|
+
for (const required of requiredPlaceholders) {
|
|
25
30
|
if (!template.includes(required)) {
|
|
26
|
-
throw new ReportingRowStoreError(
|
|
31
|
+
throw new ReportingRowStoreError(
|
|
32
|
+
"INVALID_INPUT",
|
|
33
|
+
required === "{revision_key}" ? "key templates must include {revision_key} so every row set has unique object keys. A binding identity includes its template, so add it under a NEW binding ID and keep the old definition configured with `readOnly: true` while rows reference it (rows already written stay readable at their recorded object_ref)" : `key templates must include ${required}`
|
|
34
|
+
);
|
|
27
35
|
}
|
|
28
36
|
}
|
|
29
37
|
const unknown = [...template.matchAll(PLACEHOLDER)].map((match) => match[1]).filter((name) => !REPORTING_ROW_KEY_PLACEHOLDERS.includes(name));
|
|
@@ -51,7 +59,8 @@ function renderReportingRowObjectKeyV1(input) {
|
|
|
51
59
|
prefix: input.prefix,
|
|
52
60
|
namespace_key: input.namespaceKey,
|
|
53
61
|
account_key: reportingRowAccountKeyV1(input.namespaceKey, input.accountId),
|
|
54
|
-
period_date
|
|
62
|
+
// Rendered only when the template uses it, so a template without {period_date} needs no timezone.
|
|
63
|
+
period_date: input.template.includes("{period_date}") ? renderedPeriodDate(input.periodStart, input.sourceTimezone) : "",
|
|
55
64
|
finality: input.finality ?? "adjustment",
|
|
56
65
|
revision_key: reportingRowRevisionKeyV1(input.rowSetId),
|
|
57
66
|
content_sha256: input.contentSha256,
|
|
@@ -61,13 +70,30 @@ function renderReportingRowObjectKeyV1(input) {
|
|
|
61
70
|
if (!KEY.test(key) || key.split("/").some((segment) => segment === "." || segment === "..") || !key.startsWith(`${input.prefix}/${input.namespaceKey}/`)) {
|
|
62
71
|
throw new ReportingRowStoreError("INVALID_INPUT", "rendered object key escapes the binding prefix");
|
|
63
72
|
}
|
|
73
|
+
if (key.length > REPORTING_ROW_OBJECT_REF_MAX_LENGTH) {
|
|
74
|
+
throw new ReportingRowStoreError(
|
|
75
|
+
"INVALID_INPUT",
|
|
76
|
+
`rendered object key exceeds ${REPORTING_ROW_OBJECT_REF_MAX_LENGTH} characters (AdCP object_ref bound)`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
64
79
|
return key;
|
|
65
80
|
}
|
|
66
|
-
function
|
|
81
|
+
function renderedPeriodDate(periodStart, sourceTimezone) {
|
|
67
82
|
if (!periodStart) return "undated";
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
83
|
+
if (!sourceTimezone) {
|
|
84
|
+
throw new ReportingRowStoreError(
|
|
85
|
+
"INVALID_INPUT",
|
|
86
|
+
"a period start needs its source_timezone to render {period_date}"
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
return reportingPeriodDate(periodStart, sourceTimezone);
|
|
91
|
+
} catch {
|
|
92
|
+
throw new ReportingRowStoreError(
|
|
93
|
+
"INVALID_INPUT",
|
|
94
|
+
"period start or source_timezone is invalid; cannot render {period_date}"
|
|
95
|
+
);
|
|
96
|
+
}
|
|
71
97
|
}
|
|
72
98
|
function createFilesystemReportingRowObjectProviderV1(options) {
|
|
73
99
|
const roots = /* @__PURE__ */ new Map();
|
|
@@ -104,7 +130,7 @@ function createFilesystemReportingRowObjectProviderV1(options) {
|
|
|
104
130
|
},
|
|
105
131
|
async putIfAbsent(input, context) {
|
|
106
132
|
context.signal.throwIfAborted();
|
|
107
|
-
const target = resolve(input.location, input.
|
|
133
|
+
const target = resolve(input.location, input.objectRef);
|
|
108
134
|
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
109
135
|
const temporary = `${target}.${randomUUID()}.tmp`;
|
|
110
136
|
const handle = await fs.open(temporary, "wx");
|
|
@@ -118,10 +144,10 @@ function createFilesystemReportingRowObjectProviderV1(options) {
|
|
|
118
144
|
}
|
|
119
145
|
try {
|
|
120
146
|
await fs.link(temporary, target);
|
|
121
|
-
return { created: true,
|
|
147
|
+
return { created: true, nativeVersionRef: await version(target) };
|
|
122
148
|
} catch (error) {
|
|
123
149
|
if (error.code === "EEXIST") {
|
|
124
|
-
return { created: false,
|
|
150
|
+
return { created: false, nativeVersionRef: await version(target) };
|
|
125
151
|
}
|
|
126
152
|
throw new ReportingRowStoreError("PROVIDER_UNAVAILABLE", "filesystem write failed");
|
|
127
153
|
} finally {
|
|
@@ -130,7 +156,7 @@ function createFilesystemReportingRowObjectProviderV1(options) {
|
|
|
130
156
|
},
|
|
131
157
|
async get(input, context) {
|
|
132
158
|
context.signal.throwIfAborted();
|
|
133
|
-
const target = resolve(input.location, input.
|
|
159
|
+
const target = resolve(input.location, input.objectRef);
|
|
134
160
|
let handle;
|
|
135
161
|
try {
|
|
136
162
|
handle = await fs.open(target, "r");
|
|
@@ -140,7 +166,7 @@ function createFilesystemReportingRowObjectProviderV1(options) {
|
|
|
140
166
|
}
|
|
141
167
|
try {
|
|
142
168
|
const stat = await handle.stat({ bigint: true });
|
|
143
|
-
if (versionOf(stat) !== input.
|
|
169
|
+
if (versionOf(stat) !== input.nativeVersionRef) return null;
|
|
144
170
|
const size = Number(stat.size);
|
|
145
171
|
const offset = input.range?.offset ?? 0;
|
|
146
172
|
const length = input.range?.length ?? size - offset;
|
|
@@ -157,11 +183,22 @@ function createFilesystemReportingRowObjectProviderV1(options) {
|
|
|
157
183
|
await handle.close();
|
|
158
184
|
}
|
|
159
185
|
},
|
|
186
|
+
async stat(input, context) {
|
|
187
|
+
context.signal.throwIfAborted();
|
|
188
|
+
const target = resolve(input.location, input.objectRef);
|
|
189
|
+
try {
|
|
190
|
+
const stat = await fs.stat(target, { bigint: true });
|
|
191
|
+
return versionOf(stat) === input.nativeVersionRef ? { nativeVersionRef: input.nativeVersionRef, sizeBytes: Number(stat.size) } : null;
|
|
192
|
+
} catch (error) {
|
|
193
|
+
if (error.code === "ENOENT") return null;
|
|
194
|
+
throw new ReportingRowStoreError("PROVIDER_UNAVAILABLE", "filesystem stat failed");
|
|
195
|
+
}
|
|
196
|
+
},
|
|
160
197
|
async delete(input, context) {
|
|
161
198
|
context.signal.throwIfAborted();
|
|
162
|
-
const target = resolve(input.location, input.
|
|
199
|
+
const target = resolve(input.location, input.objectRef);
|
|
163
200
|
try {
|
|
164
|
-
if (await version(target) !== input.
|
|
201
|
+
if (await version(target) !== input.nativeVersionRef) return "absent";
|
|
165
202
|
await fs.unlink(target);
|
|
166
203
|
return "deleted";
|
|
167
204
|
} catch (error) {
|
|
@@ -183,64 +220,98 @@ async function runReportingRowObjectProviderConformanceV1(provider, input) {
|
|
|
183
220
|
await provider.probe(input, context);
|
|
184
221
|
passed.push("probe");
|
|
185
222
|
const created = await provider.putIfAbsent(
|
|
186
|
-
{ ...base, key, bytes: first, contentType: "application/x-ndjson", metadata },
|
|
223
|
+
{ ...base, objectRef: key, bytes: first, contentType: "application/x-ndjson", metadata },
|
|
187
224
|
context
|
|
188
225
|
);
|
|
189
|
-
if (!created.created || !created.
|
|
226
|
+
if (!created.created || !created.nativeVersionRef) throw new Error("putIfAbsent did not create a new object");
|
|
190
227
|
passed.push("create");
|
|
191
228
|
const conflict = await provider.putIfAbsent(
|
|
192
|
-
{ ...base, key, bytes: Buffer.from('{"c":3}\n'), contentType: "application/x-ndjson", metadata },
|
|
229
|
+
{ ...base, objectRef: key, bytes: Buffer.from('{"c":3}\n'), contentType: "application/x-ndjson", metadata },
|
|
193
230
|
context
|
|
194
231
|
);
|
|
195
|
-
if (conflict.created || conflict.
|
|
232
|
+
if (conflict.created || conflict.nativeVersionRef !== created.nativeVersionRef) {
|
|
196
233
|
throw new Error("putIfAbsent replaced or re-versioned an existing object");
|
|
197
234
|
}
|
|
198
|
-
const stored = await provider.get(
|
|
235
|
+
const stored = await provider.get(
|
|
236
|
+
{ ...base, objectRef: key, nativeVersionRef: created.nativeVersionRef, maxBytes: 1024 },
|
|
237
|
+
context
|
|
238
|
+
);
|
|
199
239
|
if (!stored || !Buffer.from(stored).equals(first))
|
|
200
240
|
throw new Error("create-only write did not preserve the first bytes");
|
|
201
241
|
passed.push("create-only");
|
|
202
242
|
if (provider.rangedReads) {
|
|
203
243
|
const ranged = await provider.get(
|
|
204
|
-
{
|
|
244
|
+
{
|
|
245
|
+
...base,
|
|
246
|
+
objectRef: key,
|
|
247
|
+
nativeVersionRef: created.nativeVersionRef,
|
|
248
|
+
range: { offset: 8, length: 8 },
|
|
249
|
+
maxBytes: 1024
|
|
250
|
+
},
|
|
205
251
|
context
|
|
206
252
|
);
|
|
207
253
|
if (!ranged || Buffer.from(ranged).toString("utf8") !== '{"b":2}\n')
|
|
208
254
|
throw new Error("ranged read returned wrong bytes");
|
|
209
255
|
passed.push("ranged-read");
|
|
210
256
|
}
|
|
211
|
-
if (await provider.get({ ...base, key,
|
|
257
|
+
if (await provider.get({ ...base, objectRef: key, nativeVersionRef: "not-a-version", maxBytes: 1024 }, context) !== null) {
|
|
212
258
|
throw new Error("get returned bytes for a version that does not exist");
|
|
213
259
|
}
|
|
214
260
|
passed.push("version-pinned-read");
|
|
215
|
-
if (
|
|
261
|
+
if (provider.stat) {
|
|
262
|
+
const stat = await provider.stat({ ...base, objectRef: key, nativeVersionRef: created.nativeVersionRef }, context);
|
|
263
|
+
if (!stat || stat.sizeBytes !== first.byteLength) throw new Error("stat did not report the stored object size");
|
|
264
|
+
if (stat.nativeVersionRef !== created.nativeVersionRef) throw new Error("stat did not echo the version it checked");
|
|
265
|
+
if (await provider.stat({ ...base, objectRef: key, nativeVersionRef: "not-a-version" }, context) !== null) {
|
|
266
|
+
throw new Error("stat returned metadata for a version that does not exist");
|
|
267
|
+
}
|
|
268
|
+
passed.push("version-pinned-stat");
|
|
269
|
+
}
|
|
270
|
+
if (await provider.delete({ ...base, objectRef: key, nativeVersionRef: "not-a-version" }, context) !== "absent") {
|
|
216
271
|
throw new Error("delete removed an object at a different version");
|
|
217
272
|
}
|
|
218
|
-
if (await provider.delete({ ...base, key,
|
|
273
|
+
if (await provider.delete({ ...base, objectRef: key, nativeVersionRef: created.nativeVersionRef }, context) !== "deleted") {
|
|
219
274
|
throw new Error("delete did not remove the exact version");
|
|
220
275
|
}
|
|
221
|
-
if (await provider.delete({ ...base, key,
|
|
276
|
+
if (await provider.delete({ ...base, objectRef: key, nativeVersionRef: created.nativeVersionRef }, context) !== "absent") {
|
|
222
277
|
throw new Error("repeated delete was not idempotent");
|
|
223
278
|
}
|
|
224
279
|
passed.push("exact-version-delete");
|
|
280
|
+
if (provider.stat && await provider.stat({ ...base, objectRef: key, nativeVersionRef: created.nativeVersionRef }, context) !== null) {
|
|
281
|
+
throw new Error("stat returned metadata for a deleted version");
|
|
282
|
+
}
|
|
225
283
|
const recreated = await provider.putIfAbsent(
|
|
226
|
-
{ ...base, key, bytes: first, contentType: "application/x-ndjson", metadata },
|
|
284
|
+
{ ...base, objectRef: key, bytes: first, contentType: "application/x-ndjson", metadata },
|
|
227
285
|
context
|
|
228
286
|
);
|
|
229
|
-
if (!recreated.created || !recreated.
|
|
230
|
-
|
|
287
|
+
if (!recreated.created || !recreated.nativeVersionRef)
|
|
288
|
+
throw new Error("putIfAbsent did not re-create a deleted object");
|
|
289
|
+
if (recreated.nativeVersionRef === created.nativeVersionRef) {
|
|
231
290
|
throw new Error("re-creating identical bytes produced the same native version; versions must be write-unique");
|
|
232
291
|
}
|
|
233
|
-
if (await provider.delete({ ...base, key,
|
|
292
|
+
if (await provider.delete({ ...base, objectRef: key, nativeVersionRef: created.nativeVersionRef }, context) !== "absent") {
|
|
234
293
|
throw new Error("delete of a stale version removed or reported a later write");
|
|
235
294
|
}
|
|
295
|
+
if (provider.stat) {
|
|
296
|
+
if (await provider.stat({ ...base, objectRef: key, nativeVersionRef: created.nativeVersionRef }, context) !== null) {
|
|
297
|
+
throw new Error("stat of a stale version reported a later write at the same key");
|
|
298
|
+
}
|
|
299
|
+
const current = await provider.stat(
|
|
300
|
+
{ ...base, objectRef: key, nativeVersionRef: recreated.nativeVersionRef },
|
|
301
|
+
context
|
|
302
|
+
);
|
|
303
|
+
if (!current || current.sizeBytes !== first.byteLength || current.nativeVersionRef !== recreated.nativeVersionRef) {
|
|
304
|
+
throw new Error("stat did not report the re-created object");
|
|
305
|
+
}
|
|
306
|
+
}
|
|
236
307
|
const survivor = await provider.get(
|
|
237
|
-
{ ...base, key,
|
|
308
|
+
{ ...base, objectRef: key, nativeVersionRef: recreated.nativeVersionRef, maxBytes: 1024 },
|
|
238
309
|
context
|
|
239
310
|
);
|
|
240
311
|
if (!survivor || !Buffer.from(survivor).equals(first)) {
|
|
241
312
|
throw new Error("delete of a stale version removed a later write with identical bytes");
|
|
242
313
|
}
|
|
243
|
-
if (await provider.delete({ ...base, key,
|
|
314
|
+
if (await provider.delete({ ...base, objectRef: key, nativeVersionRef: recreated.nativeVersionRef }, context) !== "deleted") {
|
|
244
315
|
throw new Error("delete did not remove the re-created version");
|
|
245
316
|
}
|
|
246
317
|
passed.push("write-unique-version");
|
|
@@ -252,6 +323,8 @@ function sha256Hex(value) {
|
|
|
252
323
|
export {
|
|
253
324
|
REPORTING_ROW_DEFAULT_KEY_TEMPLATE,
|
|
254
325
|
REPORTING_ROW_KEY_PLACEHOLDERS,
|
|
326
|
+
REPORTING_ROW_NATIVE_VERSION_REF_MAX_LENGTH,
|
|
327
|
+
REPORTING_ROW_OBJECT_REF_MAX_LENGTH,
|
|
255
328
|
assertReportingRowKeyTemplateV1,
|
|
256
329
|
assertReportingRowPrefixV1,
|
|
257
330
|
createFilesystemReportingRowObjectProviderV1,
|
|
@@ -9,7 +9,11 @@ import { type ReportingRowObjectProviderV1 } from './row-storage-object.mjs';
|
|
|
9
9
|
*/
|
|
10
10
|
export { ReportingRowStoreError, isReportingRowStoreError } from './row-storage-errors.mjs';
|
|
11
11
|
export type { ReportingRowStoreErrorCode } from './row-storage-errors.mjs';
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* Rows stored as chunk bodies in the ledger's own PostgreSQL schema.
|
|
14
|
+
*
|
|
15
|
+
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
16
|
+
*/
|
|
13
17
|
export interface ReportingPostgresRowBindingV1 {
|
|
14
18
|
kind: 'postgres';
|
|
15
19
|
}
|
|
@@ -18,6 +22,8 @@ export interface ReportingPostgresRowBindingV1 {
|
|
|
18
22
|
* definition lives in host code, which makes it the allowlist: a row set
|
|
19
23
|
* whose recorded binding identity differs from the configured definition is
|
|
20
24
|
* never read from or written to.
|
|
25
|
+
*
|
|
26
|
+
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
21
27
|
*/
|
|
22
28
|
export interface ReportingObjectRowBindingV1 {
|
|
23
29
|
kind: 'object';
|
|
@@ -27,22 +33,41 @@ export interface ReportingObjectRowBindingV1 {
|
|
|
27
33
|
location: Readonly<Record<string, string>>;
|
|
28
34
|
/** Owned key prefix. Sweeps and deletes never touch keys outside it. */
|
|
29
35
|
prefix: string;
|
|
30
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Object key template; see `REPORTING_ROW_DEFAULT_KEY_TEMPLATE`. It must include `{revision_key}`, so every
|
|
38
|
+
* row set writes its own object keys (a read-only binding is exempt).
|
|
39
|
+
*/
|
|
31
40
|
keyTemplate?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Keep this binding configured only to read (and retire) row sets already written through it, for
|
|
43
|
+
* example under an older template without `{revision_key}`. A read-only binding is never selected for
|
|
44
|
+
* new writes and is exempt from the `{revision_key}` requirement; reads use each chunk's recorded
|
|
45
|
+
* `object_ref`, never a re-rendered key. Not part of the binding's identity.
|
|
46
|
+
*/
|
|
47
|
+
readOnly?: boolean;
|
|
32
48
|
/** Stored encoding; digests always cover uncompressed bytes. Default `gzip`. */
|
|
33
49
|
compression?: 'none' | 'gzip';
|
|
34
50
|
/** Host-mapped client reference passed to the provider; never a secret. */
|
|
35
51
|
credentialRef?: string;
|
|
36
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
55
|
+
*/
|
|
37
56
|
export type ReportingRowBindingDefinitionV1 = ReportingPostgresRowBindingV1 | ReportingObjectRowBindingV1;
|
|
57
|
+
/**
|
|
58
|
+
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
59
|
+
*/
|
|
38
60
|
export interface ReportingRowBindingSelectionInputV1 {
|
|
39
61
|
account_id: string;
|
|
40
62
|
reporting_obligation_id: string;
|
|
41
63
|
row_set_kind: 'revision' | 'adjustment';
|
|
42
64
|
finality?: 'snapshot' | 'official';
|
|
43
65
|
row_count: number;
|
|
44
|
-
|
|
66
|
+
content_size_bytes: number;
|
|
45
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
70
|
+
*/
|
|
46
71
|
export interface ReportingRowStorageOptionsV1 {
|
|
47
72
|
/**
|
|
48
73
|
* Logical binding ID → immutable definition. Defaults to a single
|
|
@@ -64,6 +89,9 @@ export interface ReportingRowStorageOptionsV1 {
|
|
|
64
89
|
/** Deadline for one object read. Default 30 seconds. */
|
|
65
90
|
readDeadlineMilliseconds?: number;
|
|
66
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
94
|
+
*/
|
|
67
95
|
export interface ReportingRowSetPrepareInputV1 {
|
|
68
96
|
rowSetId: string;
|
|
69
97
|
rowSetKind: 'revision' | 'adjustment';
|
|
@@ -71,8 +99,10 @@ export interface ReportingRowSetPrepareInputV1 {
|
|
|
71
99
|
obligationId: string;
|
|
72
100
|
rows: readonly Record<string, unknown>[];
|
|
73
101
|
finality?: 'snapshot' | 'official';
|
|
74
|
-
/** Reporting period start, used for `{period_date}` in object keys. */
|
|
102
|
+
/** Reporting period start, used with `sourceTimezone` for `{period_date}` in object keys. */
|
|
75
103
|
periodStart?: string;
|
|
104
|
+
/** The period's `source_timezone` (required with `periodStart`): `{period_date}` is the local calendar date. */
|
|
105
|
+
sourceTimezone?: string;
|
|
76
106
|
/** Committed protocol binding the chunks must reproduce. */
|
|
77
107
|
binding: {
|
|
78
108
|
sha256: string;
|
|
@@ -85,11 +115,14 @@ export interface ReportingRowSetPrepareInputV1 {
|
|
|
85
115
|
bindingId?: string;
|
|
86
116
|
}
|
|
87
117
|
interface PreparedObjectV1 {
|
|
88
|
-
readonly
|
|
118
|
+
readonly objectRef: string;
|
|
89
119
|
readonly physicalBytes: Buffer;
|
|
90
120
|
readonly physicalSha256: string;
|
|
91
121
|
readonly compression: 'none' | 'gzip';
|
|
92
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
125
|
+
*/
|
|
93
126
|
export interface ReportingPreparedRowSetV1 {
|
|
94
127
|
readonly input: ReportingRowSetPrepareInputV1;
|
|
95
128
|
readonly encoded: ReportingEncodedRowsV1;
|
|
@@ -99,13 +132,21 @@ export interface ReportingPreparedRowSetV1 {
|
|
|
99
132
|
/** Object kind only: one planned object per chunk. */
|
|
100
133
|
readonly objects?: readonly PreparedObjectV1[];
|
|
101
134
|
}
|
|
102
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Where one chunk was stored; recorded in the chunk manifest.
|
|
137
|
+
*
|
|
138
|
+
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
139
|
+
*/
|
|
103
140
|
export interface ReportingRowChunkLocatorV1 {
|
|
104
|
-
|
|
105
|
-
|
|
141
|
+
/** AdCP `object_ref`: decoded, destination-relative, 1 to 1024 characters. */
|
|
142
|
+
objectRef: string;
|
|
143
|
+
/** AdCP `native_version_ref`: decoded provider-native immutable version, 1 to 1024 characters. */
|
|
144
|
+
nativeVersionRef: string;
|
|
106
145
|
compression: 'none' | 'gzip';
|
|
146
|
+
/** SHA-256 of the stored (possibly compressed) object bytes. */
|
|
107
147
|
physicalSha256: string;
|
|
108
|
-
|
|
148
|
+
/** AdCP `size_bytes`: the stored object's size, after any compression. */
|
|
149
|
+
sizeBytes: number;
|
|
109
150
|
/** Whether this upload created the object (as opposed to adopting identical bytes). */
|
|
110
151
|
created: boolean;
|
|
111
152
|
}
|
|
@@ -115,7 +156,11 @@ interface QueryableV1 {
|
|
|
115
156
|
rowCount?: number | null;
|
|
116
157
|
}>;
|
|
117
158
|
}
|
|
118
|
-
/**
|
|
159
|
+
/**
|
|
160
|
+
* A row set whose chunk manifest has been verified against its committed digest.
|
|
161
|
+
*
|
|
162
|
+
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
163
|
+
*/
|
|
119
164
|
export interface ReportingRowSetHandleV1 {
|
|
120
165
|
readonly rowSetId: string;
|
|
121
166
|
readonly rowSetKind: 'revision' | 'adjustment';
|
|
@@ -123,7 +168,11 @@ export interface ReportingRowSetHandleV1 {
|
|
|
123
168
|
readonly obligationId: string;
|
|
124
169
|
readonly digestProfile: 'revision_envelope_v1' | 'rows_v1';
|
|
125
170
|
readonly contentSha256: string;
|
|
126
|
-
|
|
171
|
+
/**
|
|
172
|
+
* Byte count of the content `contentSha256` covers (the committed binding's `byteCount`): for a revision it includes
|
|
173
|
+
* the envelope, so it is not the sum of the chunks' `canonical_size_bytes`.
|
|
174
|
+
*/
|
|
175
|
+
readonly contentSizeBytes: number;
|
|
127
176
|
readonly rowCount: number;
|
|
128
177
|
readonly rowManifestSha256: string;
|
|
129
178
|
readonly bindingId: string;
|
|
@@ -138,6 +187,8 @@ export interface ReportingRowSetHandleV1 {
|
|
|
138
187
|
* available once the row-storage migration is applied; object-kind reads need
|
|
139
188
|
* the binding and its provider configured. Writes require an explicit opt-in
|
|
140
189
|
* on the owning store.
|
|
190
|
+
*
|
|
191
|
+
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
141
192
|
*/
|
|
142
193
|
export declare class ReportingRowStorageV1 {
|
|
143
194
|
private readonly pool;
|
|
@@ -152,12 +203,17 @@ export declare class ReportingRowStorageV1 {
|
|
|
152
203
|
constructor(pool: QueryableV1, options?: ReportingRowStorageOptionsV1);
|
|
153
204
|
/** Deadline budget a writer must still hold on its lease before uploading. */
|
|
154
205
|
get writeDeadlineMilliseconds(): number;
|
|
206
|
+
/** Every writable object binding's key template must include `{revision_key}`; throws `INVALID_INPUT`. */
|
|
207
|
+
private assertBindingKeyTemplates;
|
|
155
208
|
/**
|
|
156
209
|
* Refuse a configuration in which compaction could delete an object a concurrent commit is
|
|
157
210
|
* adopting. An object binding whose key template omits `{revision_key}` can map two revisions
|
|
158
211
|
* with identical chunk content to one object key, and a create-only write adopts an existing
|
|
159
212
|
* object with identical bytes. Compaction deleting that object at the same moment would leave
|
|
160
|
-
* the newer revision without its rows.
|
|
213
|
+
* the newer revision without its rows. Every writable binding is already required to include
|
|
214
|
+
* `{revision_key}`, so this cannot fail for a validated configuration. A `readOnly` binding is
|
|
215
|
+
* skipped: it never takes commits, so nothing can adopt through it, and every delete is
|
|
216
|
+
* reference-checked.
|
|
161
217
|
*
|
|
162
218
|
* Since the reference-checked, per-object-locked delete this is no longer the only guard: every
|
|
163
219
|
* delete path now skips an object another row set still references. It is kept as defense in
|
|
@@ -178,8 +234,8 @@ export declare class ReportingRowStorageV1 {
|
|
|
178
234
|
* write intent.
|
|
179
235
|
*/
|
|
180
236
|
upload(prepared: ReportingPreparedRowSetV1, intentId: string, onCreated: (object: {
|
|
181
|
-
|
|
182
|
-
|
|
237
|
+
objectRef: string;
|
|
238
|
+
nativeVersionRef: string;
|
|
183
239
|
}) => Promise<void>, signal?: AbortSignal): Promise<ReportingRowChunkLocatorV1[]>;
|
|
184
240
|
/**
|
|
185
241
|
* Persist a prepared row set inside the caller's ledger transaction:
|
|
@@ -210,19 +266,26 @@ export declare class ReportingRowStorageV1 {
|
|
|
210
266
|
* `absent` counts as success. Only object-kind bindings are accepted.
|
|
211
267
|
*/
|
|
212
268
|
deleteObjects(bindingId: string, objects: readonly {
|
|
213
|
-
|
|
214
|
-
|
|
269
|
+
objectRef: string;
|
|
270
|
+
nativeVersionRef: string;
|
|
215
271
|
}[], signal?: AbortSignal): Promise<void>;
|
|
216
272
|
/**
|
|
217
|
-
* Prove each object is still present at its recorded version with the recorded
|
|
273
|
+
* Prove each object is still present at its recorded version with the recorded size.
|
|
218
274
|
* A commit that adopted an object another row set created calls this under the object's
|
|
219
275
|
* lock, so a concurrent delete either finished first (this throws, the commit fails and
|
|
220
276
|
* the writer re-uploads) or sees the commit's chunk reference and skips the delete.
|
|
277
|
+
*
|
|
278
|
+
* Native versions are write-unique (S3 VersionId, Azure versionId, GCS generation, filesystem
|
|
279
|
+
* `ino:birthtime:mtime:size`), so a version-pinned metadata check, "this exact version exists at the
|
|
280
|
+
* recorded size", proves the object unchanged without downloading it while the commit holds its
|
|
281
|
+
* locks. Bytes were verified when the object was uploaded or adopted. A custom provider without
|
|
282
|
+
* `stat` falls back to reading the whole object and comparing its physical digest.
|
|
221
283
|
*/
|
|
222
284
|
assertObjectsPresent(bindingId: string, objects: readonly {
|
|
223
|
-
|
|
224
|
-
|
|
285
|
+
objectRef: string;
|
|
286
|
+
nativeVersionRef: string;
|
|
225
287
|
physicalSha256: string;
|
|
288
|
+
sizeBytes: number;
|
|
226
289
|
}[], signal?: AbortSignal): Promise<void>;
|
|
227
290
|
/**
|
|
228
291
|
* A live row set in the same obligation and binding whose rows are
|
|
@@ -245,5 +308,9 @@ export declare class ReportingRowStorageV1 {
|
|
|
245
308
|
private provider;
|
|
246
309
|
private register;
|
|
247
310
|
}
|
|
248
|
-
/**
|
|
311
|
+
/**
|
|
312
|
+
* Fresh opaque intent identifier for one upload attempt.
|
|
313
|
+
*
|
|
314
|
+
* @experimental Reliable Reporting storage surface: breaking changes may ship in minor releases. See https://github.com/adcontextprotocol/adcp-client/blob/main/docs/guides/REPORTING-STABILITY.md
|
|
315
|
+
*/
|
|
249
316
|
export declare function reportingRowWriteIntentIdV1(): string;
|