@adcp/sdk 17.0.0-beta.0 → 17.0.0-beta.2
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/3.1/bidding.js +1 -1
- package/dist/lib/adapters/version/3.1/bidding.mjs +1 -1
- 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/ResponseValidator.js +1 -1
- package/dist/lib/core/ResponseValidator.mjs +1 -1
- package/dist/lib/core/SingleAgentClient.d.mts +122 -7
- package/dist/lib/core/SingleAgentClient.d.ts +122 -7
- package/dist/lib/core/SingleAgentClient.js +601 -96
- package/dist/lib/core/SingleAgentClient.mjs +590 -84
- package/dist/lib/core/TaskExecutor.d.mts +7 -0
- package/dist/lib/core/TaskExecutor.d.ts +7 -0
- package/dist/lib/core/TaskExecutor.js +23 -8
- package/dist/lib/core/TaskExecutor.mjs +23 -8
- 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/errors/index.d.mts +22 -0
- package/dist/lib/errors/index.d.ts +22 -0
- package/dist/lib/errors/index.js +43 -0
- package/dist/lib/errors/index.mjs +42 -0
- 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 +34 -21
- package/dist/lib/identity-3.3/trust.mjs +34 -21
- 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 +7 -53
- package/dist/lib/index.d.ts +7 -53
- package/dist/lib/index.js +13 -0
- package/dist/lib/index.mjs +9 -0
- package/dist/lib/media-buy/compatibility.js +6 -1
- package/dist/lib/media-buy/compatibility.mjs +6 -1
- package/dist/lib/protocols/mcp-modern.d.mts +2 -0
- package/dist/lib/protocols/mcp-modern.d.ts +2 -0
- package/dist/lib/protocols/mcp-modern.js +31 -5
- package/dist/lib/protocols/mcp-modern.mjs +31 -5
- package/dist/lib/protocols/mcp-scope.d.mts +6 -1
- package/dist/lib/protocols/mcp-scope.d.ts +6 -1
- package/dist/lib/protocols/mcp-scope.js +25 -3
- package/dist/lib/protocols/mcp-scope.mjs +24 -3
- package/dist/lib/protocols/mcp.js +12 -6
- package/dist/lib/protocols/mcp.mjs +13 -6
- 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/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/create-adcp-server.js +33 -20
- package/dist/lib/server/create-adcp-server.mjs +36 -12
- 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/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/client.d.mts +1 -0
- package/dist/lib/testing/client.d.ts +1 -0
- package/dist/lib/testing/client.js +6 -5
- package/dist/lib/testing/client.mjs +6 -5
- package/dist/lib/testing/storyboard/agent-routing.d.mts +5 -2
- package/dist/lib/testing/storyboard/agent-routing.d.ts +5 -2
- package/dist/lib/testing/storyboard/agent-routing.js +11 -4
- package/dist/lib/testing/storyboard/agent-routing.mjs +11 -4
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.js +60 -14
- package/dist/lib/testing/storyboard/canonical-format-satisfaction.mjs +60 -14
- 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/context.d.mts +13 -3
- package/dist/lib/testing/storyboard/context.d.ts +13 -3
- package/dist/lib/testing/storyboard/context.js +15 -10
- package/dist/lib/testing/storyboard/context.mjs +15 -10
- 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 +141 -13
- package/dist/lib/testing/storyboard/runner.mjs +141 -13
- 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/validations.js +4 -1
- package/dist/lib/testing/storyboard/validations.mjs +4 -1
- package/dist/lib/testing/test-controller.js +3 -0
- package/dist/lib/testing/test-controller.mjs +3 -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/envelope-status-compat.d.mts +18 -1
- package/dist/lib/utils/envelope-status-compat.d.ts +18 -1
- package/dist/lib/utils/envelope-status-compat.js +11 -5
- package/dist/lib/utils/envelope-status-compat.mjs +11 -5
- package/dist/lib/utils/response-unwrapper.js +18 -10
- package/dist/lib/utils/response-unwrapper.mjs +18 -10
- 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 +159 -39
- package/dist/lib/v2/projection/creative-delivery.mjs +163 -39
- 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 +136 -43
- package/dist/lib/validation/schema-validator.mjs +140 -44
- 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/COLLECTION-FIXTURE-FOUNDATION.md +11 -0
- package/docs/guides/DELIVERY-WEBHOOK-PARSING.md +142 -0
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +27 -1
- 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 +202 -2
- package/docs/migration-6.6-to-6.7.md +14 -0
- package/docs/migration-account-change-feed.md +15 -0
- package/docs/migration-reporting-storage-package.md +1 -1
- package/docs/recipes/verifying-inbound-webhooks.md +18 -2
- package/package.json +2 -2
|
@@ -16,6 +16,7 @@ import { is401Error } from "../errors/index.mjs";
|
|
|
16
16
|
import { withSpan, injectTraceHeaders } from "../observability/tracing.mjs";
|
|
17
17
|
import {
|
|
18
18
|
currentMCPConnectionScopeKey,
|
|
19
|
+
markMCPConnectionScopeInterrupted,
|
|
19
20
|
isMCPConnectionScopeCacheKeyActive,
|
|
20
21
|
registerMCPConnectionScopeCleanup,
|
|
21
22
|
registerMCPConnectionScopePending
|
|
@@ -255,9 +256,15 @@ async function createNegotiatedClient(cacheKey, options, authHeaders, useCachedD
|
|
|
255
256
|
getCapability: options.signingContext.getCapability,
|
|
256
257
|
adcpVersion: options.signingContext.adcpVersion
|
|
257
258
|
}) : diagnosticFetch;
|
|
259
|
+
const transportFetch = wrapFetchWithCapture(withPerRequestTraceHeaders(signedFetch));
|
|
260
|
+
let throttleRetryAfter;
|
|
258
261
|
const transport = new StreamableHTTPClientTransport(new URL(options.agentUrl), {
|
|
259
262
|
requestInit: { headers: splitConnectionHeaders(authHeaders).identity, redirect: "manual" },
|
|
260
|
-
fetch:
|
|
263
|
+
fetch: async (input, init) => {
|
|
264
|
+
const response = await transportFetch(input, init);
|
|
265
|
+
throttleRetryAfter = response.status === 429 || response.status === 503 ? response.headers.get("retry-after") ?? void 0 : void 0;
|
|
266
|
+
return response;
|
|
267
|
+
},
|
|
261
268
|
...options.authProvider && {
|
|
262
269
|
authProvider: options.authProvider
|
|
263
270
|
}
|
|
@@ -300,8 +307,22 @@ async function createNegotiatedClient(cacheKey, options, authHeaders, useCachedD
|
|
|
300
307
|
if (isNegotiationAuthFailure(error) && !skipProbe && presentedStaticCredential(authHeaders, options.authProvider)) {
|
|
301
308
|
return createNegotiatedClient(cacheKey, options, authHeaders, useCachedDiscovery, true);
|
|
302
309
|
}
|
|
303
|
-
throw error;
|
|
310
|
+
throw withRetryAfter(error, throttleRetryAfter);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
function withRetryAfter(error, retryAfter) {
|
|
314
|
+
if (retryAfter === void 0 || !error || typeof error !== "object") return error;
|
|
315
|
+
const status = httpStatusOf(error);
|
|
316
|
+
if (status !== 429 && status !== 503) return error;
|
|
317
|
+
try {
|
|
318
|
+
Object.defineProperty(error, "retryAfter", { value: retryAfter, enumerable: false, configurable: true });
|
|
319
|
+
} catch {
|
|
304
320
|
}
|
|
321
|
+
return error;
|
|
322
|
+
}
|
|
323
|
+
function retryAfterOf(error) {
|
|
324
|
+
const value = error && typeof error === "object" ? error.retryAfter : void 0;
|
|
325
|
+
return typeof value === "string" ? value : void 0;
|
|
305
326
|
}
|
|
306
327
|
async function getOrCreateModernConnection(cacheKey, options, authHeaders) {
|
|
307
328
|
for (let attempt = 0; ; attempt++) {
|
|
@@ -321,12 +342,12 @@ function createSharedModernConnection(cacheKey, options, authHeaders) {
|
|
|
321
342
|
const promise = createNegotiatedClient(cacheKey, options, authHeaders).then(async (client) => {
|
|
322
343
|
if ((client.getProtocolEra() === "modern" || options.handleLegacy === true) && generation === connectionGeneration) {
|
|
323
344
|
modernConnections.set(cacheKey, client);
|
|
324
|
-
registerMCPConnectionScopeCleanup("modern", cacheKey, async () => {
|
|
345
|
+
registerMCPConnectionScopeCleanup("modern", cacheKey, async (terminateSession) => {
|
|
325
346
|
if (modernConnections.get(cacheKey) !== client) return;
|
|
326
347
|
modernConnections.delete(cacheKey);
|
|
327
348
|
legacyConnectionExpiresAt.delete(cacheKey);
|
|
328
349
|
modernDiscoveries.delete(cacheKey);
|
|
329
|
-
await closeModernClient(client);
|
|
350
|
+
await closeModernClient(client, terminateSession);
|
|
330
351
|
});
|
|
331
352
|
if (client.getProtocolEra() === "legacy") {
|
|
332
353
|
legacyConnectionExpiresAt.set(cacheKey, Date.now() + LEGACY_CLASSIFICATION_TTL_MS);
|
|
@@ -348,7 +369,10 @@ function createSharedModernConnection(cacheKey, options, authHeaders) {
|
|
|
348
369
|
return promise;
|
|
349
370
|
}
|
|
350
371
|
async function retireFailedConnection(cacheKey, client, error) {
|
|
351
|
-
if (isAbortOrTimeoutError(error))
|
|
372
|
+
if (isAbortOrTimeoutError(error)) {
|
|
373
|
+
markMCPConnectionScopeInterrupted();
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
352
376
|
if (modernConnections.get(cacheKey) === client) {
|
|
353
377
|
modernConnections.delete(cacheKey);
|
|
354
378
|
legacyConnectionExpiresAt.delete(cacheKey);
|
|
@@ -517,6 +541,7 @@ async function probeModernMCPConnection(agentUrl, authToken, customHeaders, opti
|
|
|
517
541
|
options.allowPrivateIp
|
|
518
542
|
);
|
|
519
543
|
const scoped = shouldReuseMCPConnection(options.fetchFn !== void 0);
|
|
544
|
+
if (isKnownLegacy(cacheKey)) return { connected: false };
|
|
520
545
|
let client;
|
|
521
546
|
return runWithMCPCallContext(
|
|
522
547
|
callContextFor({ customHeaders, requestTimeoutMs: options.requestTimeoutMs }),
|
|
@@ -656,6 +681,7 @@ async function closeModernMCPConnections() {
|
|
|
656
681
|
export {
|
|
657
682
|
closeModernMCPConnections,
|
|
658
683
|
probeModernMCPConnection,
|
|
684
|
+
retryAfterOf,
|
|
659
685
|
tryCallModernMCPTool,
|
|
660
686
|
tryListModernMCPTools
|
|
661
687
|
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
type ScopeCleanup = () => Promise<void>;
|
|
1
|
+
type ScopeCleanup = (terminateSession: boolean) => Promise<void>;
|
|
2
2
|
/** Cache-key suffix for the current caller-owned MCP workflow. */
|
|
3
3
|
export declare function currentMCPConnectionScopeKey(): string | undefined;
|
|
4
|
+
/** Preserve seller work even when a higher layer handles a request timeout. */
|
|
5
|
+
export declare function markMCPConnectionScopeInterrupted(): void;
|
|
4
6
|
/** Whether an LRU entry belongs to a workflow that has not finished yet. */
|
|
5
7
|
export declare function isMCPConnectionScopeCacheKeyActive(cacheKey: string): boolean;
|
|
6
8
|
/** Register one idempotent cache-entry cleanup with the current workflow. */
|
|
@@ -20,6 +22,9 @@ export declare function closeCurrentMCPConnectionScope(): Promise<boolean>;
|
|
|
20
22
|
* Per-call correlation headers, `AbortSignal`s and timeouts do not choose the
|
|
21
23
|
* session. The scope terminates its sessions once, when `fn` settles; pass
|
|
22
24
|
* `{ isolate: true }` to force a fresh scope even when called from inside one.
|
|
25
|
+
* Explicit workflows terminate sessions at exit even if an inner call returned
|
|
26
|
+
* submitted/working; the caller owns that lifetime. Implicit task scopes may
|
|
27
|
+
* close only their local clients when their final result remains nonterminal.
|
|
23
28
|
*
|
|
24
29
|
* @example
|
|
25
30
|
* ```ts
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
type ScopeCleanup = () => Promise<void>;
|
|
1
|
+
type ScopeCleanup = (terminateSession: boolean) => Promise<void>;
|
|
2
2
|
/** Cache-key suffix for the current caller-owned MCP workflow. */
|
|
3
3
|
export declare function currentMCPConnectionScopeKey(): string | undefined;
|
|
4
|
+
/** Preserve seller work even when a higher layer handles a request timeout. */
|
|
5
|
+
export declare function markMCPConnectionScopeInterrupted(): void;
|
|
4
6
|
/** Whether an LRU entry belongs to a workflow that has not finished yet. */
|
|
5
7
|
export declare function isMCPConnectionScopeCacheKeyActive(cacheKey: string): boolean;
|
|
6
8
|
/** Register one idempotent cache-entry cleanup with the current workflow. */
|
|
@@ -20,6 +22,9 @@ export declare function closeCurrentMCPConnectionScope(): Promise<boolean>;
|
|
|
20
22
|
* Per-call correlation headers, `AbortSignal`s and timeouts do not choose the
|
|
21
23
|
* session. The scope terminates its sessions once, when `fn` settles; pass
|
|
22
24
|
* `{ isolate: true }` to force a fresh scope even when called from inside one.
|
|
25
|
+
* Explicit workflows terminate sessions at exit even if an inner call returned
|
|
26
|
+
* submitted/working; the caller owns that lifetime. Implicit task scopes may
|
|
27
|
+
* close only their local clients when their final result remains nonterminal.
|
|
23
28
|
*
|
|
24
29
|
* @example
|
|
25
30
|
* ```ts
|
|
@@ -21,18 +21,24 @@ __export(mcp_scope_exports, {
|
|
|
21
21
|
closeCurrentMCPConnectionScope: () => closeCurrentMCPConnectionScope,
|
|
22
22
|
currentMCPConnectionScopeKey: () => currentMCPConnectionScopeKey,
|
|
23
23
|
isMCPConnectionScopeCacheKeyActive: () => isMCPConnectionScopeCacheKeyActive,
|
|
24
|
+
markMCPConnectionScopeInterrupted: () => markMCPConnectionScopeInterrupted,
|
|
24
25
|
registerMCPConnectionScopeCleanup: () => registerMCPConnectionScopeCleanup,
|
|
25
26
|
registerMCPConnectionScopePending: () => registerMCPConnectionScopePending,
|
|
26
27
|
withMCPConnectionScope: () => withMCPConnectionScope
|
|
27
28
|
});
|
|
28
29
|
module.exports = __toCommonJS(mcp_scope_exports);
|
|
29
30
|
var import_node_async_hooks = require("node:async_hooks");
|
|
31
|
+
var import_abort = require('./abort.js');
|
|
30
32
|
const scopeStorage = new import_node_async_hooks.AsyncLocalStorage();
|
|
31
33
|
const activeScopeKeys = /* @__PURE__ */ new Set();
|
|
32
34
|
let nextScopeId = 0;
|
|
33
35
|
function currentMCPConnectionScopeKey() {
|
|
34
36
|
return scopeStorage.getStore()?.cacheKey;
|
|
35
37
|
}
|
|
38
|
+
function markMCPConnectionScopeInterrupted() {
|
|
39
|
+
const scope = scopeStorage.getStore();
|
|
40
|
+
if (scope?.preserveOnInterruption) scope.interrupted = true;
|
|
41
|
+
}
|
|
36
42
|
function isMCPConnectionScopeCacheKeyActive(cacheKey) {
|
|
37
43
|
const marker = cacheKey.lastIndexOf("::scope:");
|
|
38
44
|
return marker >= 0 && activeScopeKeys.has(cacheKey.slice(marker + 2));
|
|
@@ -55,17 +61,32 @@ async function closeCurrentMCPConnectionScope() {
|
|
|
55
61
|
}
|
|
56
62
|
const cleanups = [...scope.cleanups.values()];
|
|
57
63
|
scope.cleanups.clear();
|
|
58
|
-
await Promise.allSettled(
|
|
64
|
+
await Promise.allSettled(
|
|
65
|
+
cleanups.map((cleanup) => cleanup(!scope.signal?.aborted && !scope.interrupted && !scope.preserveSession))
|
|
66
|
+
);
|
|
59
67
|
return true;
|
|
60
68
|
}
|
|
61
69
|
async function withMCPConnectionScope(fn, options = {}) {
|
|
62
70
|
if (scopeStorage.getStore() && options.isolate !== true) return fn();
|
|
63
71
|
const id = ++nextScopeId;
|
|
64
|
-
const scope = {
|
|
72
|
+
const scope = {
|
|
73
|
+
id,
|
|
74
|
+
cacheKey: `scope:${id}`,
|
|
75
|
+
pending: /* @__PURE__ */ new Set(),
|
|
76
|
+
cleanups: /* @__PURE__ */ new Map(),
|
|
77
|
+
signal: options.signal,
|
|
78
|
+
preserveOnInterruption: options.preserveOnInterruption,
|
|
79
|
+
preserveSessionOnResult: options.preserveSessionOnResult
|
|
80
|
+
};
|
|
65
81
|
activeScopeKeys.add(scope.cacheKey);
|
|
66
82
|
return scopeStorage.run(scope, async () => {
|
|
67
83
|
try {
|
|
68
|
-
|
|
84
|
+
const result = await fn();
|
|
85
|
+
scope.preserveSession = scope.preserveSessionOnResult?.(result) === true;
|
|
86
|
+
return result;
|
|
87
|
+
} catch (error) {
|
|
88
|
+
if ((0, import_abort.isAbortOrTimeoutError)(error)) markMCPConnectionScopeInterrupted();
|
|
89
|
+
throw error;
|
|
69
90
|
} finally {
|
|
70
91
|
try {
|
|
71
92
|
await closeCurrentMCPConnectionScope();
|
|
@@ -80,6 +101,7 @@ async function withMCPConnectionScope(fn, options = {}) {
|
|
|
80
101
|
closeCurrentMCPConnectionScope,
|
|
81
102
|
currentMCPConnectionScopeKey,
|
|
82
103
|
isMCPConnectionScopeCacheKeyActive,
|
|
104
|
+
markMCPConnectionScopeInterrupted,
|
|
83
105
|
registerMCPConnectionScopeCleanup,
|
|
84
106
|
registerMCPConnectionScopePending,
|
|
85
107
|
withMCPConnectionScope
|
|
@@ -4,12 +4,17 @@ import { createRequire as __adcpCreateRequire } from "node:module";
|
|
|
4
4
|
const __dirname = __adcpDirname(__adcpFileURLToPath(import.meta.url));
|
|
5
5
|
const require2 = __adcpCreateRequire(import.meta.url);
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
|
+
import { isAbortOrTimeoutError } from "./abort.mjs";
|
|
7
8
|
const scopeStorage = new AsyncLocalStorage();
|
|
8
9
|
const activeScopeKeys = /* @__PURE__ */ new Set();
|
|
9
10
|
let nextScopeId = 0;
|
|
10
11
|
function currentMCPConnectionScopeKey() {
|
|
11
12
|
return scopeStorage.getStore()?.cacheKey;
|
|
12
13
|
}
|
|
14
|
+
function markMCPConnectionScopeInterrupted() {
|
|
15
|
+
const scope = scopeStorage.getStore();
|
|
16
|
+
if (scope?.preserveOnInterruption) scope.interrupted = true;
|
|
17
|
+
}
|
|
13
18
|
function isMCPConnectionScopeCacheKeyActive(cacheKey) {
|
|
14
19
|
const marker = cacheKey.lastIndexOf("::scope:");
|
|
15
20
|
return marker >= 0 && activeScopeKeys.has(cacheKey.slice(marker + 2));
|
|
@@ -32,17 +37,32 @@ async function closeCurrentMCPConnectionScope() {
|
|
|
32
37
|
}
|
|
33
38
|
const cleanups = [...scope.cleanups.values()];
|
|
34
39
|
scope.cleanups.clear();
|
|
35
|
-
await Promise.allSettled(
|
|
40
|
+
await Promise.allSettled(
|
|
41
|
+
cleanups.map((cleanup) => cleanup(!scope.signal?.aborted && !scope.interrupted && !scope.preserveSession))
|
|
42
|
+
);
|
|
36
43
|
return true;
|
|
37
44
|
}
|
|
38
45
|
async function withMCPConnectionScope(fn, options = {}) {
|
|
39
46
|
if (scopeStorage.getStore() && options.isolate !== true) return fn();
|
|
40
47
|
const id = ++nextScopeId;
|
|
41
|
-
const scope = {
|
|
48
|
+
const scope = {
|
|
49
|
+
id,
|
|
50
|
+
cacheKey: `scope:${id}`,
|
|
51
|
+
pending: /* @__PURE__ */ new Set(),
|
|
52
|
+
cleanups: /* @__PURE__ */ new Map(),
|
|
53
|
+
signal: options.signal,
|
|
54
|
+
preserveOnInterruption: options.preserveOnInterruption,
|
|
55
|
+
preserveSessionOnResult: options.preserveSessionOnResult
|
|
56
|
+
};
|
|
42
57
|
activeScopeKeys.add(scope.cacheKey);
|
|
43
58
|
return scopeStorage.run(scope, async () => {
|
|
44
59
|
try {
|
|
45
|
-
|
|
60
|
+
const result = await fn();
|
|
61
|
+
scope.preserveSession = scope.preserveSessionOnResult?.(result) === true;
|
|
62
|
+
return result;
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (isAbortOrTimeoutError(error)) markMCPConnectionScopeInterrupted();
|
|
65
|
+
throw error;
|
|
46
66
|
} finally {
|
|
47
67
|
try {
|
|
48
68
|
await closeCurrentMCPConnectionScope();
|
|
@@ -56,6 +76,7 @@ export {
|
|
|
56
76
|
closeCurrentMCPConnectionScope,
|
|
57
77
|
currentMCPConnectionScopeKey,
|
|
58
78
|
isMCPConnectionScopeCacheKeyActive,
|
|
79
|
+
markMCPConnectionScopeInterrupted,
|
|
59
80
|
registerMCPConnectionScopeCleanup,
|
|
60
81
|
registerMCPConnectionScopePending,
|
|
61
82
|
withMCPConnectionScope
|
|
@@ -207,10 +207,10 @@ async function getOrCreateConnection(cacheKey, baseUrl, authHeaders, debugLogs,
|
|
|
207
207
|
throw new Error(`MCP ${label} completed after connection teardown`);
|
|
208
208
|
}
|
|
209
209
|
connectionCache.set(cacheKey, client);
|
|
210
|
-
(0, import_mcp_scope.registerMCPConnectionScopeCleanup)("legacy", cacheKey, async () => {
|
|
210
|
+
(0, import_mcp_scope.registerMCPConnectionScopeCleanup)("legacy", cacheKey, async (terminateSession) => {
|
|
211
211
|
if (connectionCache.get(cacheKey) !== client) return;
|
|
212
212
|
connectionCache.delete(cacheKey);
|
|
213
|
-
await closeMCPClient(client);
|
|
213
|
+
await closeMCPClient(client, terminateSession);
|
|
214
214
|
});
|
|
215
215
|
evictLeastRecentlyUsed();
|
|
216
216
|
return client;
|
|
@@ -280,10 +280,10 @@ async function getOrCreateOAuthConnection(cacheKey, options) {
|
|
|
280
280
|
throw new Error("OAuth MCP connection completed after connection teardown");
|
|
281
281
|
}
|
|
282
282
|
oauthConnectionCache.set(cacheKey, client);
|
|
283
|
-
(0, import_mcp_scope.registerMCPConnectionScopeCleanup)("oauth", cacheKey, async () => {
|
|
283
|
+
(0, import_mcp_scope.registerMCPConnectionScopeCleanup)("oauth", cacheKey, async (terminateSession) => {
|
|
284
284
|
if (oauthConnectionCache.get(cacheKey) !== client) return;
|
|
285
285
|
oauthConnectionCache.delete(cacheKey);
|
|
286
|
-
await closeMCPClient(client);
|
|
286
|
+
await closeMCPClient(client, terminateSession);
|
|
287
287
|
});
|
|
288
288
|
evictLeastRecentlyUsedOAuth();
|
|
289
289
|
return client;
|
|
@@ -337,7 +337,10 @@ async function withCachedOAuthConnectionImpl(options, label, fn) {
|
|
|
337
337
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
338
338
|
error
|
|
339
339
|
});
|
|
340
|
-
if ((0, import_abort.isAbortOrTimeoutError)(error))
|
|
340
|
+
if ((0, import_abort.isAbortOrTimeoutError)(error)) {
|
|
341
|
+
(0, import_mcp_scope.markMCPConnectionScopeInterrupted)();
|
|
342
|
+
throw error;
|
|
343
|
+
}
|
|
341
344
|
if ((0, import_errors.is401Error)(error)) {
|
|
342
345
|
options.debugLogs.push({
|
|
343
346
|
type: "warning",
|
|
@@ -405,7 +408,10 @@ async function withCachedConnectionImpl(agentUrl, authToken, authHeaders, debugL
|
|
|
405
408
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
406
409
|
error
|
|
407
410
|
});
|
|
408
|
-
if ((0, import_abort.isAbortOrTimeoutError)(error))
|
|
411
|
+
if ((0, import_abort.isAbortOrTimeoutError)(error)) {
|
|
412
|
+
(0, import_mcp_scope.markMCPConnectionScopeInterrupted)();
|
|
413
|
+
throw error;
|
|
414
|
+
}
|
|
409
415
|
if ((0, import_errors.is401Error)(error)) {
|
|
410
416
|
debugLogs.push({
|
|
411
417
|
type: "warning",
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
import { closeModernMCPConnections, tryCallModernMCPTool } from "./mcp-modern.mjs";
|
|
36
36
|
import {
|
|
37
37
|
currentMCPConnectionScopeKey,
|
|
38
|
+
markMCPConnectionScopeInterrupted,
|
|
38
39
|
isMCPConnectionScopeCacheKeyActive,
|
|
39
40
|
registerMCPConnectionScopeCleanup,
|
|
40
41
|
registerMCPConnectionScopePending
|
|
@@ -208,10 +209,10 @@ async function getOrCreateConnection(cacheKey, baseUrl, authHeaders, debugLogs,
|
|
|
208
209
|
throw new Error(`MCP ${label} completed after connection teardown`);
|
|
209
210
|
}
|
|
210
211
|
connectionCache.set(cacheKey, client);
|
|
211
|
-
registerMCPConnectionScopeCleanup("legacy", cacheKey, async () => {
|
|
212
|
+
registerMCPConnectionScopeCleanup("legacy", cacheKey, async (terminateSession) => {
|
|
212
213
|
if (connectionCache.get(cacheKey) !== client) return;
|
|
213
214
|
connectionCache.delete(cacheKey);
|
|
214
|
-
await closeMCPClient(client);
|
|
215
|
+
await closeMCPClient(client, terminateSession);
|
|
215
216
|
});
|
|
216
217
|
evictLeastRecentlyUsed();
|
|
217
218
|
return client;
|
|
@@ -281,10 +282,10 @@ async function getOrCreateOAuthConnection(cacheKey, options) {
|
|
|
281
282
|
throw new Error("OAuth MCP connection completed after connection teardown");
|
|
282
283
|
}
|
|
283
284
|
oauthConnectionCache.set(cacheKey, client);
|
|
284
|
-
registerMCPConnectionScopeCleanup("oauth", cacheKey, async () => {
|
|
285
|
+
registerMCPConnectionScopeCleanup("oauth", cacheKey, async (terminateSession) => {
|
|
285
286
|
if (oauthConnectionCache.get(cacheKey) !== client) return;
|
|
286
287
|
oauthConnectionCache.delete(cacheKey);
|
|
287
|
-
await closeMCPClient(client);
|
|
288
|
+
await closeMCPClient(client, terminateSession);
|
|
288
289
|
});
|
|
289
290
|
evictLeastRecentlyUsedOAuth();
|
|
290
291
|
return client;
|
|
@@ -338,7 +339,10 @@ async function withCachedOAuthConnectionImpl(options, label, fn) {
|
|
|
338
339
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
339
340
|
error
|
|
340
341
|
});
|
|
341
|
-
if (isAbortOrTimeoutError(error))
|
|
342
|
+
if (isAbortOrTimeoutError(error)) {
|
|
343
|
+
markMCPConnectionScopeInterrupted();
|
|
344
|
+
throw error;
|
|
345
|
+
}
|
|
342
346
|
if (is401Error(error)) {
|
|
343
347
|
options.debugLogs.push({
|
|
344
348
|
type: "warning",
|
|
@@ -406,7 +410,10 @@ async function withCachedConnectionImpl(agentUrl, authToken, authHeaders, debugL
|
|
|
406
410
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
407
411
|
error
|
|
408
412
|
});
|
|
409
|
-
if (isAbortOrTimeoutError(error))
|
|
413
|
+
if (isAbortOrTimeoutError(error)) {
|
|
414
|
+
markMCPConnectionScopeInterrupted();
|
|
415
|
+
throw error;
|
|
416
|
+
}
|
|
410
417
|
if (is401Error(error)) {
|
|
411
418
|
debugLogs.push({
|
|
412
419
|
type: "warning",
|
|
@@ -502,6 +502,7 @@ function compileRowSchema(schema, maxCompileMs, deadline) {
|
|
|
502
502
|
assertInspectionDeadline(deadline);
|
|
503
503
|
const startedAt = Date.now();
|
|
504
504
|
const ajv = new Ajv2020({
|
|
505
|
+
inlineRefs: false,
|
|
505
506
|
strictSchema: true,
|
|
506
507
|
strictTypes: false,
|
|
507
508
|
allErrors: true,
|
|
@@ -472,6 +472,7 @@ function compileRowSchema(schema, maxCompileMs, deadline) {
|
|
|
472
472
|
assertInspectionDeadline(deadline);
|
|
473
473
|
const startedAt = Date.now();
|
|
474
474
|
const ajv = new Ajv2020({
|
|
475
|
+
inlineRefs: false,
|
|
475
476
|
strictSchema: true,
|
|
476
477
|
strictTypes: false,
|
|
477
478
|
allErrors: true,
|
|
@@ -19,3 +19,8 @@ export declare function evaluateReportingLedgerCoverageV1(query: ReportingLedger
|
|
|
19
19
|
complete: boolean;
|
|
20
20
|
retainedFrom: string;
|
|
21
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Store-side guard, evaluated under the same account lock as generation writes.
|
|
24
|
+
* @experimental Storage-facing building block; see docs/guides/REPORTING-STABILITY.md.
|
|
25
|
+
*/
|
|
26
|
+
export declare function assertReportingLedgerHistoryDoesNotOverlap(configuration: ReportingLedgerConfigurationV1, configurations: readonly ReportingLedgerConfigurationV1[]): void;
|
|
@@ -19,3 +19,8 @@ export declare function evaluateReportingLedgerCoverageV1(query: ReportingLedger
|
|
|
19
19
|
complete: boolean;
|
|
20
20
|
retainedFrom: string;
|
|
21
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Store-side guard, evaluated under the same account lock as generation writes.
|
|
24
|
+
* @experimental Storage-facing building block; see docs/guides/REPORTING-STABILITY.md.
|
|
25
|
+
*/
|
|
26
|
+
export declare function assertReportingLedgerHistoryDoesNotOverlap(configuration: ReportingLedgerConfigurationV1, configurations: readonly ReportingLedgerConfigurationV1[]): void;
|
|
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var coverage_exports = {};
|
|
20
20
|
__export(coverage_exports, {
|
|
21
|
+
assertReportingLedgerHistoryDoesNotOverlap: () => assertReportingLedgerHistoryDoesNotOverlap,
|
|
21
22
|
evaluateReportingLedgerCoverageV1: () => evaluateReportingLedgerCoverageV1,
|
|
22
23
|
matchingReportingLedgerConfigurations: () => matchingReportingLedgerConfigurations,
|
|
23
24
|
relevantReportingLedgerConfigurations: () => relevantReportingLedgerConfigurations,
|
|
@@ -56,7 +57,7 @@ function relevantReportingLedgerConfigurations(configurations, periodStart, peri
|
|
|
56
57
|
const start = Date.parse(periodStart);
|
|
57
58
|
const end = Date.parse(periodEnd);
|
|
58
59
|
return configurations.filter((configuration) => {
|
|
59
|
-
const installed = Date.parse(configuration.installedAt);
|
|
60
|
+
const installed = Date.parse(configuration.historyStart ?? configuration.installedAt);
|
|
60
61
|
const successor = reportingLedgerSuccessor(configuration, configurations);
|
|
61
62
|
const superseded = Math.min(
|
|
62
63
|
successor ? Date.parse(successor.installedAt) : Number.POSITIVE_INFINITY,
|
|
@@ -83,7 +84,7 @@ function evaluateReportingLedgerCoverageV1(query, configurations, obligations, l
|
|
|
83
84
|
let complete = true;
|
|
84
85
|
let retainedFrom;
|
|
85
86
|
for (const configuration of configurations.filter((value) => reportingLedgerConfigurationMatchesScope(query, value))) {
|
|
86
|
-
const installedAt = Date.parse(configuration.installedAt);
|
|
87
|
+
const installedAt = Date.parse(configuration.historyStart ?? configuration.installedAt);
|
|
87
88
|
const successor = reportingLedgerSuccessor(configuration, configurations);
|
|
88
89
|
const ownershipEnd = Math.min(
|
|
89
90
|
successor ? Date.parse(successor.installedAt) : Number.POSITIVE_INFINITY,
|
|
@@ -108,7 +109,7 @@ function evaluateReportingLedgerCoverageV1(query, configurations, obligations, l
|
|
|
108
109
|
}
|
|
109
110
|
continue;
|
|
110
111
|
}
|
|
111
|
-
const firstOwned = Math.max(0, schedule.ceil(installedAt));
|
|
112
|
+
const firstOwned = configuration.historyStartOrdinal ?? Math.max(0, schedule.ceil(installedAt));
|
|
112
113
|
const ownershipLast = Number.isFinite(ownershipEnd) ? schedule.ceil(ownershipEnd) - 1 : Number.POSITIVE_INFINITY;
|
|
113
114
|
if (ownershipLast < firstOwned) continue;
|
|
114
115
|
const end = Number.isFinite(ownershipLast) ? schedule.boundary(ownershipLast + 1) : Number.POSITIVE_INFINITY;
|
|
@@ -135,8 +136,41 @@ function evaluateReportingLedgerCoverageV1(query, configurations, obligations, l
|
|
|
135
136
|
}
|
|
136
137
|
return { complete, retainedFrom: retainedFrom ?? period.start };
|
|
137
138
|
}
|
|
139
|
+
function assertReportingLedgerHistoryDoesNotOverlap(configuration, configurations) {
|
|
140
|
+
if (configuration.historyStart === void 0) return;
|
|
141
|
+
const all = [
|
|
142
|
+
...configurations.filter((value) => value.configurationId !== configuration.configurationId),
|
|
143
|
+
configuration
|
|
144
|
+
];
|
|
145
|
+
const range = (value) => {
|
|
146
|
+
const schedule2 = (0, import_schedule.reportingPeriodSchedule)(value);
|
|
147
|
+
const first = value.historyStartOrdinal ?? Math.max(0, schedule2.ceil(Date.parse(value.installedAt)));
|
|
148
|
+
const successor = reportingLedgerSuccessor(value, all);
|
|
149
|
+
const end2 = Math.min(
|
|
150
|
+
successor ? Date.parse(successor.installedAt) : Infinity,
|
|
151
|
+
value.supersededAt ? Date.parse(value.supersededAt) : Infinity
|
|
152
|
+
);
|
|
153
|
+
return [schedule2.boundary(first), Number.isFinite(end2) ? schedule2.boundary(schedule2.ceil(end2)) : Infinity];
|
|
154
|
+
};
|
|
155
|
+
const [start, ownershipEnd] = range(configuration);
|
|
156
|
+
const previous = configurations.find((value) => value.configurationId === configuration.configurationId);
|
|
157
|
+
const schedule = (0, import_schedule.reportingPeriodSchedule)(configuration);
|
|
158
|
+
const previousStart = previous?.historyStart !== void 0 ? Date.parse(previous.historyStart) : schedule.boundary(Math.max(0, schedule.ceil(Date.parse(configuration.installedAt))));
|
|
159
|
+
const end = Math.min(ownershipEnd, previousStart);
|
|
160
|
+
if (start >= end) return;
|
|
161
|
+
for (const other of all) {
|
|
162
|
+
if (other.configurationId === configuration.configurationId || other.account.account_id !== configuration.account.account_id || other.delivery_config_id !== configuration.delivery_config_id)
|
|
163
|
+
continue;
|
|
164
|
+
if (Date.parse(other.historyStart ?? other.installedAt) >= end) continue;
|
|
165
|
+
const [otherStart, otherEnd] = range(other);
|
|
166
|
+
if (start < end && otherStart < otherEnd && start < otherEnd && otherStart < end) {
|
|
167
|
+
throw new RangeError("Reporting history overlaps another configuration generation");
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
138
171
|
// Annotate the CommonJS export names for ESM import in node:
|
|
139
172
|
0 && (module.exports = {
|
|
173
|
+
assertReportingLedgerHistoryDoesNotOverlap,
|
|
140
174
|
evaluateReportingLedgerCoverageV1,
|
|
141
175
|
matchingReportingLedgerConfigurations,
|
|
142
176
|
relevantReportingLedgerConfigurations,
|
|
@@ -31,7 +31,7 @@ function relevantReportingLedgerConfigurations(configurations, periodStart, peri
|
|
|
31
31
|
const start = Date.parse(periodStart);
|
|
32
32
|
const end = Date.parse(periodEnd);
|
|
33
33
|
return configurations.filter((configuration) => {
|
|
34
|
-
const installed = Date.parse(configuration.installedAt);
|
|
34
|
+
const installed = Date.parse(configuration.historyStart ?? configuration.installedAt);
|
|
35
35
|
const successor = reportingLedgerSuccessor(configuration, configurations);
|
|
36
36
|
const superseded = Math.min(
|
|
37
37
|
successor ? Date.parse(successor.installedAt) : Number.POSITIVE_INFINITY,
|
|
@@ -58,7 +58,7 @@ function evaluateReportingLedgerCoverageV1(query, configurations, obligations, l
|
|
|
58
58
|
let complete = true;
|
|
59
59
|
let retainedFrom;
|
|
60
60
|
for (const configuration of configurations.filter((value) => reportingLedgerConfigurationMatchesScope(query, value))) {
|
|
61
|
-
const installedAt = Date.parse(configuration.installedAt);
|
|
61
|
+
const installedAt = Date.parse(configuration.historyStart ?? configuration.installedAt);
|
|
62
62
|
const successor = reportingLedgerSuccessor(configuration, configurations);
|
|
63
63
|
const ownershipEnd = Math.min(
|
|
64
64
|
successor ? Date.parse(successor.installedAt) : Number.POSITIVE_INFINITY,
|
|
@@ -83,7 +83,7 @@ function evaluateReportingLedgerCoverageV1(query, configurations, obligations, l
|
|
|
83
83
|
}
|
|
84
84
|
continue;
|
|
85
85
|
}
|
|
86
|
-
const firstOwned = Math.max(0, schedule.ceil(installedAt));
|
|
86
|
+
const firstOwned = configuration.historyStartOrdinal ?? Math.max(0, schedule.ceil(installedAt));
|
|
87
87
|
const ownershipLast = Number.isFinite(ownershipEnd) ? schedule.ceil(ownershipEnd) - 1 : Number.POSITIVE_INFINITY;
|
|
88
88
|
if (ownershipLast < firstOwned) continue;
|
|
89
89
|
const end = Number.isFinite(ownershipLast) ? schedule.boundary(ownershipLast + 1) : Number.POSITIVE_INFINITY;
|
|
@@ -110,7 +110,40 @@ function evaluateReportingLedgerCoverageV1(query, configurations, obligations, l
|
|
|
110
110
|
}
|
|
111
111
|
return { complete, retainedFrom: retainedFrom ?? period.start };
|
|
112
112
|
}
|
|
113
|
+
function assertReportingLedgerHistoryDoesNotOverlap(configuration, configurations) {
|
|
114
|
+
if (configuration.historyStart === void 0) return;
|
|
115
|
+
const all = [
|
|
116
|
+
...configurations.filter((value) => value.configurationId !== configuration.configurationId),
|
|
117
|
+
configuration
|
|
118
|
+
];
|
|
119
|
+
const range = (value) => {
|
|
120
|
+
const schedule2 = reportingPeriodSchedule(value);
|
|
121
|
+
const first = value.historyStartOrdinal ?? Math.max(0, schedule2.ceil(Date.parse(value.installedAt)));
|
|
122
|
+
const successor = reportingLedgerSuccessor(value, all);
|
|
123
|
+
const end2 = Math.min(
|
|
124
|
+
successor ? Date.parse(successor.installedAt) : Infinity,
|
|
125
|
+
value.supersededAt ? Date.parse(value.supersededAt) : Infinity
|
|
126
|
+
);
|
|
127
|
+
return [schedule2.boundary(first), Number.isFinite(end2) ? schedule2.boundary(schedule2.ceil(end2)) : Infinity];
|
|
128
|
+
};
|
|
129
|
+
const [start, ownershipEnd] = range(configuration);
|
|
130
|
+
const previous = configurations.find((value) => value.configurationId === configuration.configurationId);
|
|
131
|
+
const schedule = reportingPeriodSchedule(configuration);
|
|
132
|
+
const previousStart = previous?.historyStart !== void 0 ? Date.parse(previous.historyStart) : schedule.boundary(Math.max(0, schedule.ceil(Date.parse(configuration.installedAt))));
|
|
133
|
+
const end = Math.min(ownershipEnd, previousStart);
|
|
134
|
+
if (start >= end) return;
|
|
135
|
+
for (const other of all) {
|
|
136
|
+
if (other.configurationId === configuration.configurationId || other.account.account_id !== configuration.account.account_id || other.delivery_config_id !== configuration.delivery_config_id)
|
|
137
|
+
continue;
|
|
138
|
+
if (Date.parse(other.historyStart ?? other.installedAt) >= end) continue;
|
|
139
|
+
const [otherStart, otherEnd] = range(other);
|
|
140
|
+
if (start < end && otherStart < otherEnd && start < otherEnd && otherStart < end) {
|
|
141
|
+
throw new RangeError("Reporting history overlaps another configuration generation");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
113
145
|
export {
|
|
146
|
+
assertReportingLedgerHistoryDoesNotOverlap,
|
|
114
147
|
evaluateReportingLedgerCoverageV1,
|
|
115
148
|
matchingReportingLedgerConfigurations,
|
|
116
149
|
relevantReportingLedgerConfigurations,
|
|
@@ -922,11 +922,14 @@ function nextExpectedAt(health, selected, query, configurations, ledgerAsOf) {
|
|
|
922
922
|
}
|
|
923
923
|
function nextActivePeriodStart(configuration, configurations, ledgerAsOf) {
|
|
924
924
|
const asOf = Date.parse(ledgerAsOf);
|
|
925
|
-
const installed = Date.parse(configuration.installedAt);
|
|
925
|
+
const installed = Date.parse(configuration.historyStart ?? configuration.installedAt);
|
|
926
926
|
const ownershipEnd = reportingLedgerConfigurationOwnershipEnd(configuration, configurations);
|
|
927
927
|
if (installed > asOf || ownershipEnd <= asOf) return [];
|
|
928
928
|
const schedule = (0, import_schedule.reportingPeriodSchedule)(configuration);
|
|
929
|
-
const ordinal = Math.max(
|
|
929
|
+
const ordinal = Math.max(
|
|
930
|
+
configuration.historyStartOrdinal ?? Math.max(0, schedule.ceil(installed)),
|
|
931
|
+
schedule.floor(asOf) + 1
|
|
932
|
+
);
|
|
930
933
|
const start = schedule.boundary(ordinal);
|
|
931
934
|
if (start >= ownershipEnd) return [];
|
|
932
935
|
schedule.period(ordinal);
|
|
@@ -934,13 +937,13 @@ function nextActivePeriodStart(configuration, configurations, ledgerAsOf) {
|
|
|
934
937
|
}
|
|
935
938
|
function nextObligationDue(configuration, configurations, query, ledgerAsOf) {
|
|
936
939
|
const schedule = (0, import_schedule.reportingPeriodSchedule)(configuration);
|
|
937
|
-
const installed = Date.parse(configuration.installedAt);
|
|
940
|
+
const installed = Date.parse(configuration.historyStart ?? configuration.installedAt);
|
|
938
941
|
const ownershipEnd = reportingLedgerConfigurationOwnershipEnd(configuration, configurations);
|
|
939
942
|
const period = (0, import_coverage.reportingLedgerEffectivePeriod)(query, ledgerAsOf);
|
|
940
943
|
const periodStart = Date.parse(period.start);
|
|
941
944
|
const periodEnd = Date.parse(period.end);
|
|
942
945
|
const expectedOffset = configuration.schedule.deliverySlaMilliseconds;
|
|
943
|
-
const firstOwned = Math.max(0, schedule.ceil(installed));
|
|
946
|
+
const firstOwned = configuration.historyStartOrdinal ?? Math.max(0, schedule.ceil(installed));
|
|
944
947
|
const lastOwned = schedule.ceil(ownershipEnd) - 1;
|
|
945
948
|
if (lastOwned < firstOwned) return [];
|
|
946
949
|
const end = Number.isFinite(lastOwned) ? schedule.boundary(lastOwned + 1) : Number.POSITIVE_INFINITY;
|
|
@@ -906,11 +906,14 @@ function nextExpectedAt(health, selected, query, configurations, ledgerAsOf) {
|
|
|
906
906
|
}
|
|
907
907
|
function nextActivePeriodStart(configuration, configurations, ledgerAsOf) {
|
|
908
908
|
const asOf = Date.parse(ledgerAsOf);
|
|
909
|
-
const installed = Date.parse(configuration.installedAt);
|
|
909
|
+
const installed = Date.parse(configuration.historyStart ?? configuration.installedAt);
|
|
910
910
|
const ownershipEnd = reportingLedgerConfigurationOwnershipEnd(configuration, configurations);
|
|
911
911
|
if (installed > asOf || ownershipEnd <= asOf) return [];
|
|
912
912
|
const schedule = reportingPeriodSchedule(configuration);
|
|
913
|
-
const ordinal = Math.max(
|
|
913
|
+
const ordinal = Math.max(
|
|
914
|
+
configuration.historyStartOrdinal ?? Math.max(0, schedule.ceil(installed)),
|
|
915
|
+
schedule.floor(asOf) + 1
|
|
916
|
+
);
|
|
914
917
|
const start = schedule.boundary(ordinal);
|
|
915
918
|
if (start >= ownershipEnd) return [];
|
|
916
919
|
schedule.period(ordinal);
|
|
@@ -918,13 +921,13 @@ function nextActivePeriodStart(configuration, configurations, ledgerAsOf) {
|
|
|
918
921
|
}
|
|
919
922
|
function nextObligationDue(configuration, configurations, query, ledgerAsOf) {
|
|
920
923
|
const schedule = reportingPeriodSchedule(configuration);
|
|
921
|
-
const installed = Date.parse(configuration.installedAt);
|
|
924
|
+
const installed = Date.parse(configuration.historyStart ?? configuration.installedAt);
|
|
922
925
|
const ownershipEnd = reportingLedgerConfigurationOwnershipEnd(configuration, configurations);
|
|
923
926
|
const period = reportingLedgerEffectivePeriod(query, ledgerAsOf);
|
|
924
927
|
const periodStart = Date.parse(period.start);
|
|
925
928
|
const periodEnd = Date.parse(period.end);
|
|
926
929
|
const expectedOffset = configuration.schedule.deliverySlaMilliseconds;
|
|
927
|
-
const firstOwned = Math.max(0, schedule.ceil(installed));
|
|
930
|
+
const firstOwned = configuration.historyStartOrdinal ?? Math.max(0, schedule.ceil(installed));
|
|
928
931
|
const lastOwned = schedule.ceil(ownershipEnd) - 1;
|
|
929
932
|
if (lastOwned < firstOwned) return [];
|
|
930
933
|
const end = Number.isFinite(lastOwned) ? schedule.boundary(lastOwned + 1) : Number.POSITIVE_INFINITY;
|