@adcp/sdk 17.0.0-beta.1 → 17.0.0-beta.3
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/dist/lib/adapters/keyed-account-store.js +1 -1
- package/dist/lib/adapters/keyed-account-store.mjs +1 -1
- package/dist/lib/adapters/version/3.0/brand-fields.d.mts +7 -1
- package/dist/lib/adapters/version/3.0/brand-fields.d.ts +7 -1
- package/dist/lib/adapters/version/3.0/brand-fields.js +139 -3
- package/dist/lib/adapters/version/3.0/brand-fields.mjs +136 -2
- package/dist/lib/adapters/version/3.0/index.js +6 -0
- package/dist/lib/adapters/version/3.0/index.mjs +7 -1
- package/dist/lib/adapters/version/index.d.mts +9 -0
- package/dist/lib/adapters/version/index.d.ts +9 -0
- package/dist/lib/adapters/version/index.js +20 -6
- package/dist/lib/adapters/version/index.mjs +15 -2
- package/dist/lib/adapters/version/types.d.mts +5 -0
- package/dist/lib/adapters/version/types.d.ts +5 -0
- package/dist/lib/canonical-references/index.js +2 -0
- package/dist/lib/canonical-references/index.mjs +2 -0
- package/dist/lib/client/account-changes.d.mts +3 -1
- package/dist/lib/client/account-changes.d.ts +3 -1
- package/dist/lib/client/account-changes.js +22 -2
- package/dist/lib/client/account-changes.mjs +22 -2
- package/dist/lib/conformance/oracle.js +3 -2
- package/dist/lib/conformance/oracle.mjs +3 -2
- package/dist/lib/core/AgentClient.d.mts +165 -1
- package/dist/lib/core/AgentClient.d.ts +165 -1
- package/dist/lib/core/AgentClient.js +446 -8
- package/dist/lib/core/AgentClient.mjs +446 -8
- package/dist/lib/core/ConversationTypes.d.mts +8 -0
- package/dist/lib/core/ConversationTypes.d.ts +8 -0
- package/dist/lib/core/ProtocolResponseParser.d.mts +1 -1
- package/dist/lib/core/ProtocolResponseParser.d.ts +1 -1
- package/dist/lib/core/ProtocolResponseParser.js +28 -18
- package/dist/lib/core/ProtocolResponseParser.mjs +11 -1
- package/dist/lib/core/SingleAgentClient.d.mts +115 -2
- package/dist/lib/core/SingleAgentClient.d.ts +115 -2
- package/dist/lib/core/SingleAgentClient.js +547 -67
- package/dist/lib/core/SingleAgentClient.mjs +534 -54
- package/dist/lib/core/TaskExecutor.d.mts +7 -0
- package/dist/lib/core/TaskExecutor.d.ts +7 -0
- package/dist/lib/core/TaskExecutor.js +18 -5
- package/dist/lib/core/TaskExecutor.mjs +18 -5
- package/dist/lib/core/task-status.d.mts +2 -0
- package/dist/lib/core/task-status.d.ts +2 -0
- package/dist/lib/core/task-status.js +11 -2
- package/dist/lib/core/task-status.mjs +9 -1
- package/dist/lib/identity-3.3/trust.d.mts +1 -4
- package/dist/lib/identity-3.3/trust.d.ts +1 -4
- package/dist/lib/identity-3.3/trust.js +43 -23
- package/dist/lib/identity-3.3/trust.mjs +43 -23
- package/dist/lib/identity-3.3/validation.js +5 -3
- package/dist/lib/identity-3.3/validation.mjs +6 -4
- package/dist/lib/index.d.mts +6 -52
- package/dist/lib/index.d.ts +6 -52
- package/dist/lib/index.js +11 -0
- package/dist/lib/index.mjs +7 -0
- package/dist/lib/media-buy/compatibility.js +6 -1
- package/dist/lib/media-buy/compatibility.mjs +6 -1
- package/dist/lib/protocols/mcp-scope.d.mts +3 -0
- package/dist/lib/protocols/mcp-scope.d.ts +3 -0
- package/dist/lib/protocols/mcp-scope.js +8 -3
- package/dist/lib/protocols/mcp-scope.mjs +8 -3
- package/dist/lib/reporting/inspection.js +1 -0
- package/dist/lib/reporting/inspection.mjs +1 -0
- package/dist/lib/reporting/ledger/coverage.d.mts +5 -0
- package/dist/lib/reporting/ledger/coverage.d.ts +5 -0
- package/dist/lib/reporting/ledger/coverage.js +37 -3
- package/dist/lib/reporting/ledger/coverage.mjs +36 -3
- package/dist/lib/reporting/ledger/handler.js +7 -4
- package/dist/lib/reporting/ledger/handler.mjs +7 -4
- package/dist/lib/reporting/ledger/producer.js +215 -69
- package/dist/lib/reporting/ledger/producer.mjs +217 -70
- package/dist/lib/reporting/ledger/schedule.d.mts +2 -2
- package/dist/lib/reporting/ledger/schedule.d.ts +2 -2
- package/dist/lib/reporting/ledger/schedule.js +8 -5
- package/dist/lib/reporting/ledger/schedule.mjs +8 -5
- package/dist/lib/reporting/ledger/status-ingest.d.mts +1 -1
- package/dist/lib/reporting/ledger/status-ingest.d.ts +1 -1
- package/dist/lib/reporting/ledger/status-ingest.js +4 -3
- package/dist/lib/reporting/ledger/status-ingest.mjs +4 -3
- package/dist/lib/reporting/ledger/types.d.mts +36 -1
- package/dist/lib/reporting/ledger/types.d.ts +36 -1
- package/dist/lib/reporting/service/index.d.mts +14 -1
- package/dist/lib/reporting/service/index.d.ts +14 -1
- package/dist/lib/reporting/service/index.js +24 -12
- package/dist/lib/reporting/service/index.mjs +24 -12
- package/dist/lib/schemas/browser.d.mts +2 -0
- package/dist/lib/schemas/browser.d.ts +2 -0
- package/dist/lib/schemas/browser.js +3 -0
- package/dist/lib/schemas/browser.mjs +2 -0
- package/dist/lib/schemas/index.d.mts +5 -3
- package/dist/lib/schemas/index.d.ts +5 -3
- package/dist/lib/schemas/index.js +5 -0
- package/dist/lib/schemas/index.mjs +4 -0
- package/dist/lib/server/a2a-adapter.js +2 -1
- package/dist/lib/server/a2a-adapter.mjs +2 -1
- package/dist/lib/server/account-response-identity.d.mts +17 -0
- package/dist/lib/server/account-response-identity.d.ts +17 -0
- package/dist/lib/server/account-response-identity.js +52 -0
- package/dist/lib/server/account-response-identity.mjs +28 -0
- package/dist/lib/server/account-sync-contract.js +2 -2
- package/dist/lib/server/account-sync-contract.mjs +2 -2
- package/dist/lib/server/auth-signature.d.mts +2 -2
- package/dist/lib/server/auth-signature.d.ts +2 -2
- package/dist/lib/server/auth-signature.js +3 -0
- package/dist/lib/server/auth-signature.mjs +3 -0
- package/dist/lib/server/create-adcp-server.d.mts +2 -2
- package/dist/lib/server/create-adcp-server.d.ts +2 -2
- package/dist/lib/server/create-adcp-server.js +58 -23
- package/dist/lib/server/create-adcp-server.mjs +61 -15
- package/dist/lib/server/decisioning/account.d.mts +36 -10
- package/dist/lib/server/decisioning/account.d.ts +36 -10
- package/dist/lib/server/decisioning/account.js +33 -14
- package/dist/lib/server/decisioning/account.mjs +33 -14
- package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -5
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -5
- package/dist/lib/server/decisioning/runtime/from-platform.js +4 -4
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +4 -4
- package/dist/lib/server/media-buy-store.d.mts +26 -12
- package/dist/lib/server/media-buy-store.d.ts +26 -12
- package/dist/lib/server/media-buy-store.js +69 -21
- package/dist/lib/server/media-buy-store.mjs +69 -21
- package/dist/lib/server/notification-subscriptions/runtime.d.mts +1 -1
- package/dist/lib/server/notification-subscriptions/runtime.d.ts +1 -1
- package/dist/lib/server/notification-subscriptions/runtime.js +4 -0
- package/dist/lib/server/notification-subscriptions/runtime.mjs +4 -0
- package/dist/lib/server/responses.js +9 -1
- package/dist/lib/server/responses.mjs +9 -1
- package/dist/lib/server/serve.js +3 -1
- package/dist/lib/server/serve.mjs +3 -1
- package/dist/lib/server/signed-request-transport.d.mts +1 -0
- package/dist/lib/server/signed-request-transport.d.ts +1 -0
- package/dist/lib/server/signed-request-transport.js +46 -0
- package/dist/lib/server/signed-request-transport.mjs +20 -0
- package/dist/lib/server/test-controller.d.mts +1 -0
- package/dist/lib/server/test-controller.d.ts +1 -0
- package/dist/lib/server/test-controller.js +5 -1
- package/dist/lib/server/test-controller.mjs +5 -1
- package/dist/lib/signing/agent-fetch.d.mts +1 -1
- package/dist/lib/signing/agent-fetch.d.ts +1 -1
- package/dist/lib/signing/agent-fetch.js +3 -3
- package/dist/lib/signing/agent-fetch.mjs +3 -3
- 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/storyboard/canonical-format-satisfaction.js +61 -29
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +61 -29
- package/dist/lib/testing/storyboard/compliance.d.mts +2 -5
- package/dist/lib/testing/storyboard/compliance.d.ts +2 -5
- package/dist/lib/testing/storyboard/compliance.js +62 -13
- package/dist/lib/testing/storyboard/compliance.mjs +63 -14
- package/dist/lib/testing/storyboard/index.d.mts +1 -0
- package/dist/lib/testing/storyboard/index.d.ts +1 -0
- package/dist/lib/testing/storyboard/index.js +3 -0
- package/dist/lib/testing/storyboard/index.mjs +2 -0
- package/dist/lib/testing/storyboard/loader.js +7 -0
- package/dist/lib/testing/storyboard/loader.mjs +7 -0
- package/dist/lib/testing/storyboard/request-builder.js +9 -6
- package/dist/lib/testing/storyboard/request-builder.mjs +9 -6
- package/dist/lib/testing/storyboard/request-signing/vector-loader.d.mts +2 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.d.ts +2 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.js +11 -0
- package/dist/lib/testing/storyboard/request-signing/vector-loader.mjs +10 -0
- package/dist/lib/testing/storyboard/runner.js +59 -6
- package/dist/lib/testing/storyboard/runner.mjs +59 -6
- package/dist/lib/testing/storyboard/types.d.mts +18 -0
- package/dist/lib/testing/storyboard/types.d.ts +18 -0
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/testing/storyboard/web-bot-auth.d.mts +10 -0
- package/dist/lib/testing/storyboard/web-bot-auth.d.ts +10 -0
- package/dist/lib/testing/storyboard/web-bot-auth.js +80 -0
- package/dist/lib/testing/storyboard/web-bot-auth.mjs +56 -0
- package/dist/lib/types/accept-proposal.d.ts +20 -28
- package/dist/lib/types/asset-instances.d.mts +1 -1
- package/dist/lib/types/asset-instances.d.ts +1 -1
- package/dist/lib/types/buy-products.d.ts +20 -28
- package/dist/lib/types/check-governance.d.ts +20 -28
- package/dist/lib/types/comply-test-controller.d.ts +20 -28
- package/dist/lib/types/control-media-buy.d.ts +20 -28
- package/dist/lib/types/core.generated.d.mts +273 -184
- package/dist/lib/types/core.generated.d.ts +273 -184
- package/dist/lib/types/create-media-buy.d.ts +20 -28
- package/dist/lib/types/get-media-buys.d.ts +20 -28
- package/dist/lib/types/get-products.d.ts +20 -28
- package/dist/lib/types/index.d.mts +6 -1
- package/dist/lib/types/index.d.ts +6 -1
- package/dist/lib/types/index.js +6 -1
- package/dist/lib/types/index.mjs +4 -1
- package/dist/lib/types/inline-enums.generated.d.mts +30 -4
- package/dist/lib/types/inline-enums.generated.d.ts +30 -4
- package/dist/lib/types/inline-enums.generated.js +41 -2
- package/dist/lib/types/inline-enums.generated.mjs +28 -2
- package/dist/lib/types/list-products.d.ts +20 -28
- package/dist/lib/types/list-proposals.d.ts +20 -28
- package/dist/lib/types/media-buy-delivery-report.d.mts +6 -0
- package/dist/lib/types/media-buy-delivery-report.d.ts +6 -0
- package/dist/lib/types/media-buy-delivery-report.js +16 -0
- package/dist/lib/types/media-buy-delivery-report.mjs +0 -0
- package/dist/lib/types/refine-proposals.d.ts +20 -28
- package/dist/lib/types/request-proposals.d.ts +20 -28
- package/dist/lib/types/schemas.generated.d.ts +63113 -127273
- package/dist/lib/types/schemas.generated.js +759 -770
- package/dist/lib/types/schemas.generated.mjs +759 -770
- package/dist/lib/types/targeting-keys.generated.d.mts +4 -0
- package/dist/lib/types/targeting-keys.generated.d.ts +4 -0
- package/dist/lib/types/targeting-keys.generated.js +109 -0
- package/dist/lib/types/targeting-keys.generated.mjs +84 -0
- package/dist/lib/types/tools.generated.d.mts +2 -68
- package/dist/lib/types/tools.generated.d.ts +2 -68
- package/dist/lib/types/update-media-buy.d.ts +20 -28
- package/dist/lib/utils/adcp-version-config.js +5 -2
- package/dist/lib/utils/adcp-version-config.mjs +5 -2
- package/dist/lib/utils/response-unwrapper.js +6 -1
- package/dist/lib/utils/response-unwrapper.mjs +6 -1
- package/dist/lib/v2/format-schema/resolver.js +1 -1
- package/dist/lib/v2/format-schema/resolver.mjs +1 -1
- package/dist/lib/v2/projection/creative-delivery.js +104 -29
- package/dist/lib/v2/projection/creative-delivery.mjs +108 -29
- package/dist/lib/v2/projection/index.d.mts +1 -0
- package/dist/lib/v2/projection/index.d.ts +1 -0
- package/dist/lib/v2/projection/index.js +3 -0
- package/dist/lib/v2/projection/index.mjs +2 -0
- package/dist/lib/v2/projection/legacy-metadata.d.mts +19 -0
- package/dist/lib/v2/projection/legacy-metadata.d.ts +19 -0
- package/dist/lib/v2/projection/legacy-metadata.js +91 -0
- package/dist/lib/v2/projection/legacy-metadata.mjs +86 -0
- package/dist/lib/v2/projection/v1-to-v2.d.mts +1 -1
- package/dist/lib/v2/projection/v1-to-v2.d.ts +1 -1
- package/dist/lib/v2/projection/v1-to-v2.js +12 -9
- package/dist/lib/v2/projection/v1-to-v2.mjs +12 -9
- package/dist/lib/validation/budget-allocation.d.mts +3 -3
- package/dist/lib/validation/budget-allocation.d.ts +3 -3
- package/dist/lib/validation/compact-schema.d.mts +27 -0
- package/dist/lib/validation/compact-schema.d.ts +27 -0
- package/dist/lib/validation/compact-schema.js +276 -0
- package/dist/lib/validation/compact-schema.mjs +250 -0
- package/dist/lib/validation/media-buy-delivery-report.d.mts +8 -0
- package/dist/lib/validation/media-buy-delivery-report.d.ts +8 -0
- package/dist/lib/validation/media-buy-delivery-report.js +31 -0
- package/dist/lib/validation/media-buy-delivery-report.mjs +7 -0
- package/dist/lib/validation/nonempty-array.d.mts +15 -0
- package/dist/lib/validation/nonempty-array.d.ts +15 -0
- package/dist/lib/validation/nonempty-array.js +41 -0
- package/dist/lib/validation/nonempty-array.mjs +7 -0
- package/dist/lib/validation/schema-diagnostic-origins.d.mts +21 -0
- package/dist/lib/validation/schema-diagnostic-origins.d.ts +21 -0
- package/dist/lib/validation/schema-diagnostic-origins.js +193 -0
- package/dist/lib/validation/schema-diagnostic-origins.mjs +169 -0
- package/dist/lib/validation/schema-loader.js +86 -16
- package/dist/lib/validation/schema-loader.mjs +82 -16
- package/dist/lib/validation/schema-validator.d.mts +10 -19
- package/dist/lib/validation/schema-validator.d.ts +10 -19
- package/dist/lib/validation/schema-validator.js +135 -42
- package/dist/lib/validation/schema-validator.mjs +139 -43
- package/dist/lib/validation/sync-creatives.d.mts +22 -22
- package/dist/lib/validation/sync-creatives.d.ts +22 -22
- 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/dist/lib/webhooks/index.d.mts +3 -0
- package/dist/lib/webhooks/index.d.ts +3 -0
- package/dist/lib/webhooks/index.js +3 -0
- package/dist/lib/webhooks/index.mjs +2 -0
- package/dist/lib/webhooks/media-buy-delivery.d.mts +43 -0
- package/dist/lib/webhooks/media-buy-delivery.d.ts +43 -0
- package/dist/lib/webhooks/media-buy-delivery.js +119 -0
- package/dist/lib/webhooks/media-buy-delivery.mjs +94 -0
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/guides/DELIVERY-WEBHOOK-PARSING.md +142 -0
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +15 -0
- package/docs/guides/REPORTING-LEDGER.md +93 -0
- package/docs/guides/REPORTING-STABILITY.md +1 -1
- package/docs/guides/TYPED-CLIENT-TOOLS.md +49 -0
- package/docs/llms.txt +2 -2
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-16-to-17.md +218 -14
- package/docs/migration-6.6-to-6.7.md +14 -0
- package/docs/migration-account-change-feed.md +15 -0
- package/docs/migration-agent-identity-3.3.md +106 -4
- package/docs/recipes/verifying-inbound-webhooks.md +18 -2
- package/package.json +16 -3
|
@@ -54,7 +54,10 @@ function createReportingProducer(options) {
|
|
|
54
54
|
subscribersByAccount.set(subscriber.account_id, count);
|
|
55
55
|
}
|
|
56
56
|
return {
|
|
57
|
-
async installConfiguration(input) {
|
|
57
|
+
async installConfiguration(input, installOptions = {}) {
|
|
58
|
+
if (Object.hasOwn(input, "historyStart") || Object.hasOwn(input, "historyStartOrdinal")) {
|
|
59
|
+
throw new TypeError("Reporting history must be supplied through trusted install options");
|
|
60
|
+
}
|
|
58
61
|
const normalizedInput = {
|
|
59
62
|
...structuredClone(input),
|
|
60
63
|
schedule: {
|
|
@@ -81,6 +84,19 @@ function createReportingProducer(options) {
|
|
|
81
84
|
if (!replayFingerprints.includes(replay.semanticFingerprint)) {
|
|
82
85
|
throw new Error("Reporting configuration generation is immutable");
|
|
83
86
|
}
|
|
87
|
+
if (installOptions.historyStart !== void 0) {
|
|
88
|
+
const requested = historyInstant(installOptions.historyStart);
|
|
89
|
+
const ownedStart = replay.historyStart !== void 0 ? Date.parse(replay.historyStart) : void 0;
|
|
90
|
+
if (ownedStart !== void 0 && requested === ownedStart) return replay;
|
|
91
|
+
if (requested > Date.now()) throw new RangeError("Reporting historyStart must not be in the future");
|
|
92
|
+
if (ownedStart !== void 0 && requested >= ownedStart) return replay;
|
|
93
|
+
const schedule = (0, import_schedule.reportingPeriodSchedule)(replay);
|
|
94
|
+
const start = schedule.boundary(schedule.ceil(requested));
|
|
95
|
+
const previous = ownedStart ?? schedule.boundary(Math.max(0, schedule.ceil(Date.parse(replay.installedAt))));
|
|
96
|
+
if (start < previous) {
|
|
97
|
+
throw new Error("Use extendConfigurationHistory to change an installed history boundary");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
84
100
|
return replay;
|
|
85
101
|
}
|
|
86
102
|
validateConfigurationAgainstOffering(normalizedInput, requiredOffering(offeringById, normalizedInput.offeringId));
|
|
@@ -113,12 +129,59 @@ function createReportingProducer(options) {
|
|
|
113
129
|
installedAt,
|
|
114
130
|
semanticFingerprint: calendarRules ? (0, import_schedule.reportingCalendarDayFingerprint)(normalizedInput, calendarRules) : semanticFingerprint
|
|
115
131
|
};
|
|
116
|
-
|
|
132
|
+
if (installOptions.historyStart !== void 0) {
|
|
133
|
+
Object.assign(
|
|
134
|
+
configuration,
|
|
135
|
+
normalizeConfigurationHistory(
|
|
136
|
+
configuration,
|
|
137
|
+
installOptions.historyStart,
|
|
138
|
+
requiredOffering(offeringById, configuration.offeringId),
|
|
139
|
+
Date.parse(installedAt)
|
|
140
|
+
)
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
(0, import_coverage.assertReportingLedgerHistoryDoesNotOverlap)(configuration, existing);
|
|
144
|
+
const stored = (await options.store.putConfiguration(configuration)).value;
|
|
145
|
+
if (configuration.historyStart !== void 0) {
|
|
146
|
+
const storedSchedule = stored.historyStart === void 0 ? (0, import_schedule.reportingPeriodSchedule)(stored) : void 0;
|
|
147
|
+
const storedStart = stored.historyStart !== void 0 ? Date.parse(stored.historyStart) : storedSchedule.boundary(Math.max(0, storedSchedule.ceil(Date.parse(stored.installedAt))));
|
|
148
|
+
if (storedStart > Date.parse(configuration.historyStart)) {
|
|
149
|
+
throw new Error("Use extendConfigurationHistory to change an installed history boundary");
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return stored;
|
|
153
|
+
},
|
|
154
|
+
async extendConfigurationHistory(input) {
|
|
155
|
+
if (!options.store.extendConfigurationHistory) {
|
|
156
|
+
throw new TypeError("Reporting ledger store does not support history extension");
|
|
157
|
+
}
|
|
158
|
+
const configuration = (await options.store.listConfigurations()).find(
|
|
159
|
+
(value) => value.configurationId === input.configurationId
|
|
160
|
+
);
|
|
161
|
+
if (!configuration) throw new Error("Unknown reporting configuration");
|
|
162
|
+
if (configuration.historyStart !== void 0) {
|
|
163
|
+
const requested = historyInstant(input.historyStart);
|
|
164
|
+
if (requested === Date.parse(configuration.historyStart)) return configuration;
|
|
165
|
+
const schedule = (0, import_schedule.reportingPeriodSchedule)(configuration);
|
|
166
|
+
if (schedule.boundary(schedule.ceil(requested)) === Date.parse(configuration.historyStart)) {
|
|
167
|
+
return configuration;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const history = normalizeConfigurationHistory(
|
|
171
|
+
configuration,
|
|
172
|
+
input.historyStart,
|
|
173
|
+
requiredOffering(offeringById, configuration.offeringId),
|
|
174
|
+
Date.now()
|
|
175
|
+
);
|
|
176
|
+
return options.store.extendConfigurationHistory({ configurationId: input.configurationId, ...history });
|
|
117
177
|
},
|
|
118
178
|
async planObligations(now = (/* @__PURE__ */ new Date()).toISOString(), planOptions = {}) {
|
|
119
179
|
const nowMs = instant(now, "now");
|
|
120
180
|
const maxObligations = planOptions.maxObligations ?? 1e3;
|
|
121
181
|
positiveInteger(maxObligations, "maxObligations");
|
|
182
|
+
const maxHistory = planOptions.maxHistoryObligationsPerSource ?? maxObligations;
|
|
183
|
+
nonnegativeInteger(maxHistory, "maxHistoryObligationsPerSource");
|
|
184
|
+
const historyBySource = /* @__PURE__ */ new Map();
|
|
122
185
|
const created = [];
|
|
123
186
|
let attempted = 0;
|
|
124
187
|
const configurations = (await options.store.listConfigurations(planOptions.account_id)).sort(
|
|
@@ -126,74 +189,86 @@ function createReportingProducer(options) {
|
|
|
126
189
|
);
|
|
127
190
|
const obligationsByAccount = /* @__PURE__ */ new Map();
|
|
128
191
|
const retiredByAccount = /* @__PURE__ */ new Map();
|
|
129
|
-
for (const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
192
|
+
for (const historyPass of [false, true]) {
|
|
193
|
+
for (const configuration of configurations) {
|
|
194
|
+
const successor = (0, import_coverage.reportingLedgerSuccessor)(configuration, configurations);
|
|
195
|
+
const anchor = instant(configuration.schedule.anchor, "schedule.anchor");
|
|
196
|
+
const effectiveFrom = configuration.historyStart ? instant(configuration.historyStart, "historyStart") : Math.max(anchor, instant(configuration.installedAt, "installedAt"));
|
|
197
|
+
let schedule;
|
|
198
|
+
try {
|
|
199
|
+
schedule = (0, import_schedule.reportingPeriodSchedule)(configuration);
|
|
200
|
+
} catch (error) {
|
|
201
|
+
const predecessor = configurations.find(
|
|
202
|
+
(candidate) => (0, import_coverage.reportingLedgerSuccessor)(candidate, configurations)?.configurationId === configuration.configurationId
|
|
203
|
+
);
|
|
204
|
+
if ((0, import_schedule.isFrozenCalendarRulesMismatch)(error) && !successor && predecessor && runtimeCanResolveCalendarGeneration(predecessor)) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (!(0, import_schedule.isFrozenCalendarRulesMismatch)(error) || !await supersededCalendarGenerationIsDurablyCovered(options.store, configuration, successor)) {
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
141
210
|
continue;
|
|
142
211
|
}
|
|
143
|
-
|
|
144
|
-
|
|
212
|
+
const generationEndValue = Math.min(
|
|
213
|
+
successor ? instant(successor.installedAt, "successor.installedAt") : Number.POSITIVE_INFINITY,
|
|
214
|
+
configuration.supersededAt ? instant(configuration.supersededAt, "supersededAt") : Number.POSITIVE_INFINITY
|
|
215
|
+
);
|
|
216
|
+
const generationEnd = Number.isFinite(generationEndValue) ? generationEndValue : void 0;
|
|
217
|
+
const effectiveUntil = Math.min(nowMs, generationEnd ?? nowMs);
|
|
218
|
+
const ownedFirst = configuration.historyStartOrdinal ?? Math.max(0, schedule.ceil(effectiveFrom));
|
|
219
|
+
const liveFirst = Math.max(0, schedule.ceil(instant(configuration.installedAt, "installedAt")));
|
|
220
|
+
const first = historyPass ? ownedFirst : Math.max(ownedFirst, liveFirst);
|
|
221
|
+
const ownershipLast = generationEnd ? schedule.ceil(effectiveUntil) - 1 : Number.POSITIVE_INFINITY;
|
|
222
|
+
if (ownershipLast < first) continue;
|
|
223
|
+
const latestClosed = schedule.floor(
|
|
224
|
+
Number.isFinite(ownershipLast) ? Math.min(nowMs, schedule.boundary(ownershipLast + 1)) : nowMs
|
|
225
|
+
) - 1;
|
|
226
|
+
const last = Math.min(ownershipLast, latestClosed, historyPass ? liveFirst - 1 : Number.POSITIVE_INFINITY);
|
|
227
|
+
let accountObligations = obligationsByAccount.get(configuration.account.account_id);
|
|
228
|
+
if (!accountObligations) {
|
|
229
|
+
accountObligations = await options.store.listObligations(configuration.account.account_id);
|
|
230
|
+
obligationsByAccount.set(configuration.account.account_id, accountObligations);
|
|
145
231
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
// A fallback clock, never a pinned cutoff. `now` is this host's
|
|
186
|
-
// instant: a host running fast pinned a cutoff ahead of the
|
|
187
|
-
// database, the watermark was stamped with it, and every
|
|
188
|
-
// database-timestamped change inside that skew — a revocation,
|
|
189
|
-
// a receipt — landed behind the watermark and never made the
|
|
190
|
-
// obligation due again, so a `complete` transition and its
|
|
191
|
-
// webhook stood over state that had already contradicted it.
|
|
192
|
-
now: () => new Date(now),
|
|
193
|
-
subscribers: options.subscribers
|
|
194
|
-
});
|
|
232
|
+
let accountRetired = retiredByAccount.get(configuration.account.account_id);
|
|
233
|
+
if (!accountRetired) {
|
|
234
|
+
accountRetired = await options.store.listRetiredObligationOrdinals?.(configuration.account.account_id) ?? [];
|
|
235
|
+
retiredByAccount.set(configuration.account.account_id, accountRetired);
|
|
236
|
+
}
|
|
237
|
+
const existingOrdinals = [
|
|
238
|
+
...accountObligations.filter((value) => value.configurationId === configuration.configurationId).map((value) => value.periodOrdinal),
|
|
239
|
+
...accountRetired.filter((value) => value.configurationId === configuration.configurationId).map((value) => value.periodOrdinal)
|
|
240
|
+
];
|
|
241
|
+
const historyRemaining = maxHistory - (historyBySource.get(configuration.offeringId) ?? 0);
|
|
242
|
+
const candidates = missingOrdinals(
|
|
243
|
+
first,
|
|
244
|
+
last,
|
|
245
|
+
existingOrdinals,
|
|
246
|
+
Math.min(maxObligations - attempted, historyPass ? historyRemaining : maxObligations)
|
|
247
|
+
);
|
|
248
|
+
for (const ordinal of candidates) {
|
|
249
|
+
attempted += 1;
|
|
250
|
+
if (historyPass)
|
|
251
|
+
historyBySource.set(configuration.offeringId, (historyBySource.get(configuration.offeringId) ?? 0) + 1);
|
|
252
|
+
const obligation = planObligation(configuration, ordinal, now);
|
|
253
|
+
const written = await options.store.putObligation(obligation);
|
|
254
|
+
if (written.inserted) {
|
|
255
|
+
created.push(written.value);
|
|
256
|
+
await (0, import_lifecycle.reconcileReportingStatusLifecycleV1)({
|
|
257
|
+
store: options.store,
|
|
258
|
+
reporting_obligation_id: written.value.reporting_obligation_id,
|
|
259
|
+
// A fallback clock, never a pinned cutoff. `now` is this host's
|
|
260
|
+
// instant: a host running fast pinned a cutoff ahead of the
|
|
261
|
+
// database, the watermark was stamped with it, and every
|
|
262
|
+
// database-timestamped change inside that skew — a revocation,
|
|
263
|
+
// a receipt — landed behind the watermark and never made the
|
|
264
|
+
// obligation due again, so a `complete` transition and its
|
|
265
|
+
// webhook stood over state that had already contradicted it.
|
|
266
|
+
now: () => new Date(now),
|
|
267
|
+
subscribers: options.subscribers
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
if (attempted >= maxObligations) return created;
|
|
195
271
|
}
|
|
196
|
-
if (attempted >= maxObligations) return created;
|
|
197
272
|
}
|
|
198
273
|
}
|
|
199
274
|
return created;
|
|
@@ -201,6 +276,9 @@ function createReportingProducer(options) {
|
|
|
201
276
|
async runWorker(workerOptions = {}) {
|
|
202
277
|
const now = workerOptions.now ?? (() => /* @__PURE__ */ new Date());
|
|
203
278
|
const maxIterations = workerOptions.maxIterations ?? 25;
|
|
279
|
+
const maxHistory = workerOptions.maxHistorySlicesPerSource ?? 10;
|
|
280
|
+
nonnegativeInteger(maxHistory, "maxHistorySlicesPerSource");
|
|
281
|
+
const historyBySource = /* @__PURE__ */ new Map();
|
|
204
282
|
const retryDelay = workerOptions.retryDelayMilliseconds ?? 3e4;
|
|
205
283
|
const executionDeadline = workerOptions.executionDeadlineMilliseconds ?? EXECUTION_DEADLINE_MS;
|
|
206
284
|
const settlementGrace = workerOptions.settlementGraceMilliseconds ?? DEFAULT_SETTLEMENT_GRACE_MS;
|
|
@@ -214,6 +292,10 @@ function createReportingProducer(options) {
|
|
|
214
292
|
if (settlementGrace > MAX_SETTLEMENT_GRACE_MS) {
|
|
215
293
|
throw new RangeError(`settlementGraceMilliseconds must not exceed ${MAX_SETTLEMENT_GRACE_MS}`);
|
|
216
294
|
}
|
|
295
|
+
const historyOfferingIds = /* @__PURE__ */ new Set([
|
|
296
|
+
...offeringById.keys(),
|
|
297
|
+
...(await options.store.listConfigurations(workerOptions.account_id)).map((value) => value.offeringId)
|
|
298
|
+
]);
|
|
217
299
|
const owner = `reporting-worker-${(0, import_node_crypto.randomUUID)()}`;
|
|
218
300
|
const counts = { claimed: 0, revisionsCommitted: 0, notReady: 0, failed: 0, reconcilesDeferred: 0 };
|
|
219
301
|
const reconcileQuietly = async (reporting_obligation_id, nowAt) => {
|
|
@@ -254,14 +336,35 @@ function createReportingProducer(options) {
|
|
|
254
336
|
owner,
|
|
255
337
|
now: nowValue.toISOString(),
|
|
256
338
|
leaseMilliseconds: DEFAULT_LEASE_MS,
|
|
339
|
+
excludeHistoryOfferingIds: [.../* @__PURE__ */ new Set([...historyOfferingIds, ...historyBySource.keys()])].filter(
|
|
340
|
+
(id) => (historyBySource.get(id) ?? 0) >= maxHistory
|
|
341
|
+
),
|
|
257
342
|
...workerOptions.account_id ? { account_id: workerOptions.account_id } : {}
|
|
258
343
|
});
|
|
259
344
|
if (!lease) break;
|
|
345
|
+
if (lease.obligation.history && (historyBySource.get(lease.obligation.offeringId) ?? 0) >= maxHistory) {
|
|
346
|
+
await options.store.releaseObligationLease(lease);
|
|
347
|
+
throw new TypeError("Reporting ledger store must honor excludeHistoryOfferingIds");
|
|
348
|
+
}
|
|
260
349
|
counts.claimed += 1;
|
|
350
|
+
if (lease.obligation.history) {
|
|
351
|
+
const sourceId = lease.obligation.offeringId;
|
|
352
|
+
historyBySource.set(sourceId, (historyBySource.get(sourceId) ?? 0) + 1);
|
|
353
|
+
}
|
|
261
354
|
let executionDeadlineTimer;
|
|
262
|
-
let activeRecoveryDeadlineAt = lease.obligation.recoveryDeadlineAt;
|
|
355
|
+
let activeRecoveryDeadlineAt = lease.obligation.historyRecoveryDeadlineAt ?? lease.obligation.recoveryDeadlineAt;
|
|
263
356
|
try {
|
|
264
357
|
const obligation = lease.obligation;
|
|
358
|
+
if (obligation.history && !obligation.historyRecoveryDeadlineAt) {
|
|
359
|
+
obligation.historyRecoveryDeadlineAt = new Date(
|
|
360
|
+
Math.max(
|
|
361
|
+
Date.parse(obligation.recoveryDeadlineAt),
|
|
362
|
+
nowValue.getTime() + obligation.schedule.recoveryWindowMilliseconds
|
|
363
|
+
)
|
|
364
|
+
).toISOString();
|
|
365
|
+
activeRecoveryDeadlineAt = obligation.historyRecoveryDeadlineAt;
|
|
366
|
+
await options.store.updateObligation(obligation, lease);
|
|
367
|
+
}
|
|
265
368
|
const offering = requiredOffering(offeringById, obligation.offeringId);
|
|
266
369
|
if ((0, import_schedule.isReportingCalendarDay)(obligation.schedule, obligation.period.sourceTimezone)) {
|
|
267
370
|
try {
|
|
@@ -287,7 +390,10 @@ function createReportingProducer(options) {
|
|
|
287
390
|
if (scheduledAt) {
|
|
288
391
|
const recoveryWindow = instant(obligation.recoveryDeadlineAt, "recoveryDeadlineAt") - instant(obligation.expectedAt, "expectedAt");
|
|
289
392
|
activeRecoveryDeadlineAt = new Date(
|
|
290
|
-
|
|
393
|
+
Math.max(
|
|
394
|
+
obligation.history ? Date.parse(activeRecoveryDeadlineAt) : Number.NEGATIVE_INFINITY,
|
|
395
|
+
instant(scheduledAt, "nextPublicationAt") + recoveryWindow
|
|
396
|
+
)
|
|
291
397
|
).toISOString();
|
|
292
398
|
}
|
|
293
399
|
}
|
|
@@ -458,6 +564,42 @@ async function supersededCalendarGenerationIsDurablyCovered(store, configuration
|
|
|
458
564
|
await store.listObligations(configuration.account.account_id)
|
|
459
565
|
);
|
|
460
566
|
}
|
|
567
|
+
function historyInstant(value) {
|
|
568
|
+
const parsed = import_source.ReportingInstantV1Schema.safeParse(value);
|
|
569
|
+
if (!parsed.success) {
|
|
570
|
+
throw new TypeError("historyStart must be a valid RFC 3339 instant with at most millisecond precision");
|
|
571
|
+
}
|
|
572
|
+
return instant(parsed.data, "historyStart");
|
|
573
|
+
}
|
|
574
|
+
function normalizeConfigurationHistory(configuration, requested, offering, now) {
|
|
575
|
+
const requestedMs = historyInstant(requested);
|
|
576
|
+
if (requestedMs < now - offering.retentionDays * 864e5) {
|
|
577
|
+
throw new RangeError("Reporting historyStart is outside source retentionDays");
|
|
578
|
+
}
|
|
579
|
+
if (requestedMs > now) throw new RangeError("Reporting historyStart must not be in the future");
|
|
580
|
+
const schedule = (0, import_schedule.reportingPeriodSchedule)(configuration);
|
|
581
|
+
const ordinal = schedule.ceil(requestedMs);
|
|
582
|
+
const start = schedule.boundary(ordinal);
|
|
583
|
+
const previousStart = configuration.historyStart ? Date.parse(configuration.historyStart) : schedule.boundary(
|
|
584
|
+
Math.max(
|
|
585
|
+
0,
|
|
586
|
+
schedule.ceil(Math.max(Date.parse(configuration.schedule.anchor), Date.parse(configuration.installedAt)))
|
|
587
|
+
)
|
|
588
|
+
);
|
|
589
|
+
if (requestedMs > previousStart || start > previousStart) {
|
|
590
|
+
throw new RangeError("Reporting historyStart may only move earlier");
|
|
591
|
+
}
|
|
592
|
+
if ((0, import_schedule.isReportingCalendarDay)(configuration.schedule, configuration.sourceTimezone)) {
|
|
593
|
+
(0, import_schedule.assertReportingCalendarDaySource)(configuration.schedule, configuration.sourceTimezone, offering, now, start);
|
|
594
|
+
const previousFirst = configuration.historyStartOrdinal ?? Math.max(0, schedule.ceil(previousStart));
|
|
595
|
+
for (let selected = ordinal; selected < previousFirst; selected += 1) schedule.period(selected);
|
|
596
|
+
} else if (configuration.schedule.alignment && configuration.schedule.alignment !== "billing_cycle") {
|
|
597
|
+
if ((0, import_source.reportingUtcOffsetChangesV1)(configuration.sourceTimezone, start, Math.max(now, start))) {
|
|
598
|
+
throw new Error("Reporting history crosses a timezone offset change; install a calendar-day generation");
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
return { historyStart: new Date(start).toISOString(), historyStartOrdinal: ordinal };
|
|
602
|
+
}
|
|
461
603
|
function planObligation(configuration, periodOrdinal, createdAt) {
|
|
462
604
|
const schedule = (0, import_schedule.reportingPeriodSchedule)(configuration);
|
|
463
605
|
const { start, end } = schedule.period(periodOrdinal);
|
|
@@ -486,6 +628,7 @@ function planObligation(configuration, periodOrdinal, createdAt) {
|
|
|
486
628
|
...configuration.finalityPolicy ? { finalityPolicy: structuredClone(configuration.finalityPolicy) } : {},
|
|
487
629
|
...configuration.canonicalization ? { canonicalization: structuredClone(configuration.canonicalization) } : {},
|
|
488
630
|
periodOrdinal,
|
|
631
|
+
...configuration.historyStart !== void 0 && periodOrdinal < Math.max(0, schedule.ceil(Date.parse(configuration.installedAt))) ? { history: true } : {},
|
|
489
632
|
period: {
|
|
490
633
|
start: new Date(start).toISOString(),
|
|
491
634
|
end: new Date(end).toISOString(),
|
|
@@ -552,7 +695,10 @@ function sourceRequest(obligation, offering, previous, adjustments, now) {
|
|
|
552
695
|
windowing: structuredClone(offering.windowing)
|
|
553
696
|
},
|
|
554
697
|
finality: revisionKind === "correction" ? { revisionKind, supersedesPublicationId: latest.sourcePublicationId } : { revisionKind },
|
|
555
|
-
trigger: {
|
|
698
|
+
trigger: {
|
|
699
|
+
kind: obligation.attemptCount ? "retry" : obligation.history ? "backfill" : "scheduled_poll",
|
|
700
|
+
id: `trigger-${obligation.attemptCount}`
|
|
701
|
+
},
|
|
556
702
|
sourceRequest: { groupIds: [] },
|
|
557
703
|
coverage: {
|
|
558
704
|
expected: "full",
|