@adcp/sdk 6.11.0 → 6.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/bin/adcp-config.js +7 -1
  2. package/bin/adcp.js +191 -4
  3. package/dist/lib/adapters/index.d.ts +0 -2
  4. package/dist/lib/adapters/index.d.ts.map +1 -1
  5. package/dist/lib/adapters/index.js +1 -8
  6. package/dist/lib/adapters/index.js.map +1 -1
  7. package/dist/lib/index.d.ts +1 -1
  8. package/dist/lib/index.d.ts.map +1 -1
  9. package/dist/lib/index.js +2 -7
  10. package/dist/lib/index.js.map +1 -1
  11. package/dist/lib/mock-server/index.d.ts +2 -0
  12. package/dist/lib/mock-server/index.d.ts.map +1 -1
  13. package/dist/lib/mock-server/index.js +17 -0
  14. package/dist/lib/mock-server/index.js.map +1 -1
  15. package/dist/lib/mock-server/sales-guaranteed/recipe.d.ts +155 -0
  16. package/dist/lib/mock-server/sales-guaranteed/recipe.d.ts.map +1 -0
  17. package/dist/lib/mock-server/sales-guaranteed/recipe.js +107 -0
  18. package/dist/lib/mock-server/sales-guaranteed/recipe.js.map +1 -0
  19. package/dist/lib/mock-server/sales-guaranteed/server.d.ts.map +1 -1
  20. package/dist/lib/mock-server/sales-guaranteed/server.js +212 -0
  21. package/dist/lib/mock-server/sales-guaranteed/server.js.map +1 -1
  22. package/dist/lib/mock-server/sales-non-guaranteed/recipe.d.ts +123 -0
  23. package/dist/lib/mock-server/sales-non-guaranteed/recipe.d.ts.map +1 -0
  24. package/dist/lib/mock-server/sales-non-guaranteed/recipe.js +81 -0
  25. package/dist/lib/mock-server/sales-non-guaranteed/recipe.js.map +1 -0
  26. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  27. package/dist/lib/server/ctx-metadata/index.d.ts +1 -1
  28. package/dist/lib/server/ctx-metadata/index.d.ts.map +1 -1
  29. package/dist/lib/server/ctx-metadata/index.js +3 -1
  30. package/dist/lib/server/ctx-metadata/index.js.map +1 -1
  31. package/dist/lib/server/ctx-metadata/wire-shape.d.ts +21 -0
  32. package/dist/lib/server/ctx-metadata/wire-shape.d.ts.map +1 -1
  33. package/dist/lib/server/ctx-metadata/wire-shape.js +111 -0
  34. package/dist/lib/server/ctx-metadata/wire-shape.js.map +1 -1
  35. package/dist/lib/server/decisioning/context.d.ts +19 -0
  36. package/dist/lib/server/decisioning/context.d.ts.map +1 -1
  37. package/dist/lib/server/decisioning/index.d.ts +3 -0
  38. package/dist/lib/server/decisioning/index.d.ts.map +1 -1
  39. package/dist/lib/server/decisioning/index.js +16 -1
  40. package/dist/lib/server/decisioning/index.js.map +1 -1
  41. package/dist/lib/server/decisioning/platform.d.ts +17 -0
  42. package/dist/lib/server/decisioning/platform.d.ts.map +1 -1
  43. package/dist/lib/server/decisioning/platform.js.map +1 -1
  44. package/dist/lib/server/decisioning/proposal/dispatch.d.ts +203 -0
  45. package/dist/lib/server/decisioning/proposal/dispatch.d.ts.map +1 -0
  46. package/dist/lib/server/decisioning/proposal/dispatch.js +395 -0
  47. package/dist/lib/server/decisioning/proposal/dispatch.js.map +1 -0
  48. package/dist/lib/server/decisioning/proposal/index.d.ts +21 -0
  49. package/dist/lib/server/decisioning/proposal/index.d.ts.map +1 -0
  50. package/dist/lib/server/decisioning/proposal/index.js +37 -0
  51. package/dist/lib/server/decisioning/proposal/index.js.map +1 -0
  52. package/dist/lib/server/decisioning/proposal/lifecycle.d.ts +195 -0
  53. package/dist/lib/server/decisioning/proposal/lifecycle.d.ts.map +1 -0
  54. package/dist/lib/server/decisioning/proposal/lifecycle.js +366 -0
  55. package/dist/lib/server/decisioning/proposal/lifecycle.js.map +1 -0
  56. package/dist/lib/server/decisioning/proposal/mock-manager.d.ts +93 -0
  57. package/dist/lib/server/decisioning/proposal/mock-manager.d.ts.map +1 -0
  58. package/dist/lib/server/decisioning/proposal/mock-manager.js +109 -0
  59. package/dist/lib/server/decisioning/proposal/mock-manager.js.map +1 -0
  60. package/dist/lib/server/decisioning/proposal/store.d.ts +279 -0
  61. package/dist/lib/server/decisioning/proposal/store.d.ts.map +1 -0
  62. package/dist/lib/server/decisioning/proposal/store.js +291 -0
  63. package/dist/lib/server/decisioning/proposal/store.js.map +1 -0
  64. package/dist/lib/server/decisioning/proposal/types.d.ts +394 -0
  65. package/dist/lib/server/decisioning/proposal/types.d.ts.map +1 -0
  66. package/dist/lib/server/decisioning/proposal/types.js +58 -0
  67. package/dist/lib/server/decisioning/proposal/types.js.map +1 -0
  68. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +25 -0
  69. package/dist/lib/server/decisioning/runtime/from-platform.d.ts.map +1 -1
  70. package/dist/lib/server/decisioning/runtime/from-platform.js +198 -15
  71. package/dist/lib/server/decisioning/runtime/from-platform.js.map +1 -1
  72. package/dist/lib/server/index.d.ts +1 -1
  73. package/dist/lib/server/index.d.ts.map +1 -1
  74. package/dist/lib/server/index.js +3 -1
  75. package/dist/lib/server/index.js.map +1 -1
  76. package/dist/lib/testing/client.d.ts.map +1 -1
  77. package/dist/lib/testing/client.js +7 -1
  78. package/dist/lib/testing/client.js.map +1 -1
  79. package/dist/lib/testing/storyboard/task-map.d.ts.map +1 -1
  80. package/dist/lib/testing/storyboard/task-map.js +1 -0
  81. package/dist/lib/testing/storyboard/task-map.js.map +1 -1
  82. package/dist/lib/testing/storyboard/test-kit.d.ts.map +1 -1
  83. package/dist/lib/testing/storyboard/test-kit.js +4 -0
  84. package/dist/lib/testing/storyboard/test-kit.js.map +1 -1
  85. package/dist/lib/testing/types.d.ts +10 -0
  86. package/dist/lib/testing/types.d.ts.map +1 -1
  87. package/dist/lib/version.d.ts +3 -3
  88. package/dist/lib/version.js +3 -3
  89. package/examples/hello_seller_adapter_guaranteed.ts +29 -2
  90. package/examples/hello_seller_adapter_proposal_mode.ts +575 -0
  91. package/package.json +1 -1
  92. package/dist/lib/adapters/proposal-manager.d.ts +0 -142
  93. package/dist/lib/adapters/proposal-manager.d.ts.map +0 -1
  94. package/dist/lib/adapters/proposal-manager.js +0 -184
  95. package/dist/lib/adapters/proposal-manager.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-manager.d.ts","sourceRoot":"","sources":["../../../../../src/lib/server/decisioning/proposal/mock-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC9F,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtG;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;;;;OAMG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,uBAAuB,CAAC;IAE1C;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAElD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED;;;;;GAKG;AACH,qBAAa,mBAAmB,CAAC,OAAO,SAAS,MAAM,GAAG,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAE,YAAW,eAAe,CAC9G,OAAO,EACP,QAAQ,CACT;IACC,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAC;IAC5C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;gBAExC,OAAO,EAAE,0BAA0B;IAsB/C,+DAA+D;IAC/D,IAAI,eAAe,IAAI,MAAM,CAE5B;IAEK,WAAW,CAAC,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAI3G,cAAc,CAAC,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAatG,OAAO;CA2BtB"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ /**
3
+ * MockProposalManager — v1 default forwarder.
4
+ *
5
+ * Symmetric with the mock-mode dispatch pattern adopters use to point
6
+ * `DecisioningPlatform` upstreams at a running `bin/adcp.js mock-server`.
7
+ * Adopters who don't yet have proposal logic of their own start with this
8
+ * class pointed at the appropriate mock-server specialism; their first
9
+ * working seller agent runs against the mock fixtures with zero adopter
10
+ * code on the proposal side. They implement their own
11
+ * {@link ProposalManager} subtype incrementally as they replace
12
+ * mock-served slices with real assembly logic.
13
+ *
14
+ * The mock-server lifecycle is **not** managed by the SDK. Adopters or CI
15
+ * start it as needed (`bin/adcp.js mock-server sales-non-guaranteed`) and
16
+ * pass the resulting URL to this class's constructor.
17
+ *
18
+ * Ports `adcp-client-python.src/adcp/decisioning/proposal_manager.py`'s
19
+ * `MockProposalManager` (PR #504).
20
+ *
21
+ * **Runtime requirement**: uses `globalThis.fetch`, which lands as a built-in
22
+ * on Node 18+ (the package declares `"engines": { "node": ">=18.0.0" }`).
23
+ * Adopters running on older Node, on Bun without the global, or in any
24
+ * environment without a global `fetch` should pass an explicit `fetch`
25
+ * implementation via the `fetch` constructor option.
26
+ *
27
+ * @public
28
+ * @packageDocumentation
29
+ */
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.MockProposalManager = void 0;
32
+ /**
33
+ * v1 default forwarder. Dispatches `getProducts` / `refineProducts` to
34
+ * a running mock-server.
35
+ *
36
+ * @public
37
+ */
38
+ class MockProposalManager {
39
+ capabilities;
40
+ url;
41
+ headers;
42
+ timeoutMs;
43
+ fetchImpl;
44
+ constructor(options) {
45
+ if (!options.mockUpstreamUrl || typeof options.mockUpstreamUrl !== 'string') {
46
+ throw new Error('MockProposalManager requires a non-empty `mockUpstreamUrl` pointing at a ' +
47
+ 'running `bin/adcp.js mock-server <specialism>` instance.');
48
+ }
49
+ this.capabilities = {
50
+ salesSpecialism: options.salesSpecialism ?? 'sales-non-guaranteed',
51
+ refine: options.refine ?? false,
52
+ };
53
+ // Strip trailing slashes (loop-based, not regex) so we keep
54
+ // `${url}/get_products` clean without a quantifier-and-anchor
55
+ // pattern CodeQL flags as polynomial-ReDoS-adjacent.
56
+ let trimmed = options.mockUpstreamUrl;
57
+ while (trimmed.endsWith('/'))
58
+ trimmed = trimmed.slice(0, -1);
59
+ this.url = trimmed;
60
+ this.headers = options.defaultHeaders ?? {};
61
+ this.timeoutMs = options.timeoutMs ?? 30_000;
62
+ this.fetchImpl = options.fetch ?? globalThis.fetch;
63
+ }
64
+ /** The configured mock-server URL — useful for diagnostics. */
65
+ get mockUpstreamUrl() {
66
+ return this.url;
67
+ }
68
+ async getProducts(req, _ctx) {
69
+ return this.forward('/get_products', req);
70
+ }
71
+ async refineProducts(req, _ctx) {
72
+ if (!this.capabilities.refine) {
73
+ // Adopter wired the manager without refine but the framework
74
+ // dispatched here anyway — surface the inconsistency rather than
75
+ // silently forwarding.
76
+ throw new Error('MockProposalManager.refineProducts called but capabilities.refine is false. ' +
77
+ 'Pass `refine: true` to the constructor to enable refine forwarding.');
78
+ }
79
+ return this.forward('/refine_products', req);
80
+ }
81
+ async forward(path, body) {
82
+ const controller = new AbortController();
83
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
84
+ try {
85
+ const response = await this.fetchImpl(`${this.url}${path}`, {
86
+ method: 'POST',
87
+ headers: {
88
+ 'content-type': 'application/json',
89
+ accept: 'application/json',
90
+ ...this.headers,
91
+ },
92
+ body: JSON.stringify(body),
93
+ signal: controller.signal,
94
+ });
95
+ if (!response.ok) {
96
+ const text = await response.text().catch(() => '');
97
+ throw new Error(`MockProposalManager: mock-server returned ${response.status} for ${path}` +
98
+ (text ? `: ${text.slice(0, 500)}` : ''));
99
+ }
100
+ const json = (await response.json());
101
+ return json;
102
+ }
103
+ finally {
104
+ clearTimeout(timer);
105
+ }
106
+ }
107
+ }
108
+ exports.MockProposalManager = MockProposalManager;
109
+ //# sourceMappingURL=mock-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-manager.js","sourceRoot":"","sources":["../../../../../src/lib/server/decisioning/proposal/mock-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,279 @@
1
+ /**
2
+ * ProposalStore — per-tenant proposal lifecycle persistence.
3
+ *
4
+ * The single ledger for proposal recipes across the entire lifecycle:
5
+ * draft (in-flight refine iterations) → committed (post-finalize, with
6
+ * `expires_at` hold window) → consumed (post-`create_media_buy`).
7
+ *
8
+ * Ports `adcp-client-python.src/adcp/decisioning/proposal_store.py`.
9
+ *
10
+ * State machine the framework drives:
11
+ *
12
+ * ```
13
+ * ┌──── releaseConsumption ────┐
14
+ * ▼ │
15
+ * putDraft ─► DRAFT ─► commit ─► COMMITTED ─► tryReserveConsumption ─► CONSUMING
16
+ * ▲ │
17
+ * │ │
18
+ * (refine finalizeConsumption
19
+ * iteration) │
20
+ * │ ▼
21
+ * └─ putDraft (overwrite while DRAFT) ─┘ CONSUMED
22
+ * (terminal)
23
+ * ```
24
+ *
25
+ * The `COMMITTED → CONSUMING → CONSUMED` two-phase transition prevents the
26
+ * inventory double-spend race that a check-then-act sequence on `COMMITTED`
27
+ * would expose. Two parallel `create_media_buy(proposal_id=X)` calls cannot
28
+ * both reserve the proposal — the second `tryReserveConsumption` raises
29
+ * `PROPOSAL_NOT_COMMITTED` once the first transitions the record. Adapter
30
+ * dispatch runs against the reservation; on success the framework calls
31
+ * `finalizeConsumption`; on failure `releaseConsumption` rolls back to
32
+ * COMMITTED so the buyer can retry.
33
+ *
34
+ * Transitions outside this graph (commit-from-COMMITTED with mismatched
35
+ * payload, finalize-from-DRAFT, etc.) throw `AdcpError` with `INTERNAL_ERROR`
36
+ * — those are framework / adopter bugs, not buyer-facing rejections.
37
+ *
38
+ * @public
39
+ * @packageDocumentation
40
+ */
41
+ import type { MaybePromise } from '../../create-adcp-server';
42
+ import type { Recipe } from './types';
43
+ /**
44
+ * Lifecycle states for a stored proposal.
45
+ *
46
+ * No `EXPIRED` member: the framework computes expiry from
47
+ * {@link ProposalRecord.expiresAt} + the current clock + the adopter's
48
+ * grace window. Storing expiry as a state would create a clock-driven
49
+ * write the framework doesn't actually need.
50
+ *
51
+ * @public
52
+ */
53
+ export type ProposalState = 'draft' | 'committed' | 'consuming' | 'consumed';
54
+ /**
55
+ * The framework's per-proposal storage row.
56
+ *
57
+ * @public
58
+ */
59
+ export interface ProposalRecord<TRecipe extends Recipe = Recipe> {
60
+ /** Stable identifier the buyer receives in the `proposals[]` wire array. */
61
+ proposalId: string;
62
+ /** Account that owns the proposal. Drives the cross-tenant check on `get`. */
63
+ accountId: string;
64
+ /** Current lifecycle state. */
65
+ state: ProposalState;
66
+ /**
67
+ * `productId -> Recipe` mapping. The {@link ProposalManager} returned these
68
+ * alongside products on `getProducts` / `refineProducts`; the framework
69
+ * persists them so `DecisioningPlatform.createMediaBuy` can hydrate
70
+ * `ctx.recipes` from this same record.
71
+ */
72
+ recipes: ReadonlyMap<string, TRecipe>;
73
+ /**
74
+ * The wire `Proposal` shape. Stored so the framework can re-emit it on
75
+ * refine iterations or replay it post-finalize without round-tripping
76
+ * through the manager again.
77
+ */
78
+ proposalPayload: Record<string, unknown>;
79
+ /**
80
+ * Set on `commit`. The inventory hold window; framework rejects
81
+ * `create_media_buy` calls past this deadline (plus the adopter's grace).
82
+ */
83
+ expiresAt?: Date;
84
+ /**
85
+ * Set on `finalizeConsumption`. The accepted proposal's terminal binding
86
+ * to a media buy; reverse-index lookups via `getByMediaBuyId` use this.
87
+ */
88
+ mediaBuyId?: string;
89
+ /**
90
+ * Captured at `putDraft` time. Adopters whose Recipe subtypes add required
91
+ * fields later bump the schema and write a migration (or evict pre-bump
92
+ * records). Framework reads but does not enforce.
93
+ */
94
+ recipeSchemaVersion?: number;
95
+ }
96
+ /**
97
+ * Per-tenant proposal lifecycle persistence.
98
+ *
99
+ * Methods may return `T` or `Promise<T>` — the framework awaits at call time.
100
+ * Mirrors the in-tree `MediaBuyStore` posture.
101
+ *
102
+ * @public
103
+ */
104
+ export interface ProposalStore<TRecipe extends Recipe = Recipe> {
105
+ /**
106
+ * Drives the production-mode gate. `false` for {@link InMemoryProposalStore};
107
+ * `true` for adopter-supplied durable backings (Postgres / Redis).
108
+ */
109
+ readonly isDurable: boolean;
110
+ /**
111
+ * Store / replace a draft proposal.
112
+ *
113
+ * Refine iterations call this with the same `proposalId` to overwrite.
114
+ * Calling on a record currently in COMMITTED, CONSUMING, or CONSUMED is
115
+ * rejected.
116
+ */
117
+ putDraft(args: {
118
+ proposalId: string;
119
+ accountId: string;
120
+ recipes: ReadonlyMap<string, TRecipe>;
121
+ proposalPayload: Record<string, unknown>;
122
+ }): MaybePromise<void>;
123
+ /**
124
+ * Look up a proposal record. Cross-tenant probes return `null` rather
125
+ * than the raw record — required to defeat principal-enumeration via
126
+ * `proposalId` probing. The dispatch path always passes the
127
+ * authenticated principal's `accountId`.
128
+ *
129
+ * **`expectedAccountId` is required.** Earlier preview made it optional
130
+ * for "framework-internal raw read" callers, but every call site that
131
+ * loads a record into a buyer-visible response path needs the tenant
132
+ * gate. Direct-debug callers that legitimately want a raw record across
133
+ * tenants should reach for a separate operator-tool surface, not bypass
134
+ * this gate. Closes a sharp edge an adopter would silently miss.
135
+ */
136
+ get(proposalId: string, args: {
137
+ expectedAccountId: string;
138
+ }): MaybePromise<ProposalRecord<TRecipe> | null>;
139
+ /**
140
+ * Promote DRAFT → COMMITTED. Idempotent on re-call with equal `expiresAt`
141
+ * + `proposalPayload`. A second commit with different values raises
142
+ * `INTERNAL_ERROR`.
143
+ */
144
+ commit(proposalId: string, args: {
145
+ expiresAt: Date;
146
+ proposalPayload: Record<string, unknown>;
147
+ }): MaybePromise<void>;
148
+ /**
149
+ * Atomic CAS: COMMITTED → CONSUMING.
150
+ *
151
+ * The framework calls this BEFORE dispatching `createMediaBuy`. Holds
152
+ * the reservation until `finalizeConsumption` (success) or
153
+ * `releaseConsumption` (rollback). Two parallel callers cannot both
154
+ * reserve; the loser raises `PROPOSAL_NOT_COMMITTED`. SQL-backed
155
+ * implementations use `SELECT … FOR UPDATE` or equivalent.
156
+ *
157
+ * @throws AdcpError `PROPOSAL_NOT_FOUND` when no record exists,
158
+ * `PROPOSAL_NOT_COMMITTED` when state is not COMMITTED.
159
+ */
160
+ tryReserveConsumption(proposalId: string, args: {
161
+ expectedAccountId: string;
162
+ }): MaybePromise<ProposalRecord<TRecipe>>;
163
+ /**
164
+ * Promote CONSUMING → CONSUMED and record the `mediaBuyId` back-reference
165
+ * for `getByMediaBuyId` lookups.
166
+ */
167
+ finalizeConsumption(proposalId: string, args: {
168
+ mediaBuyId: string;
169
+ expectedAccountId: string;
170
+ }): MaybePromise<void>;
171
+ /**
172
+ * Rollback path: CONSUMING → COMMITTED. Idempotent on a record already
173
+ * in COMMITTED. Called when the adapter's `createMediaBuy` raises so
174
+ * the buyer can retry without `PROPOSAL_NOT_COMMITTED`.
175
+ */
176
+ releaseConsumption(proposalId: string, args: {
177
+ expectedAccountId: string;
178
+ }): MaybePromise<void>;
179
+ /**
180
+ * Discard a proposal record. Idempotent — discarding an unknown id is
181
+ * a no-op (no throw).
182
+ */
183
+ discard(proposalId: string): MaybePromise<void>;
184
+ /**
185
+ * Reverse-index lookup. Hydrate the (consumed) proposal that produced
186
+ * this `mediaBuyId` for the given tenant.
187
+ *
188
+ * `expectedAccountId` is required (no default) because `mediaBuyId` is
189
+ * adopter-controlled and can collide across tenants. SQL-backed impls
190
+ * add a uniqueness constraint on `(accountId, mediaBuyId)` where
191
+ * `mediaBuyId IS NOT NULL`.
192
+ */
193
+ getByMediaBuyId(mediaBuyId: string, args: {
194
+ expectedAccountId: string;
195
+ }): MaybePromise<ProposalRecord<TRecipe> | null>;
196
+ }
197
+ /**
198
+ * Construction options for {@link InMemoryProposalStore}.
199
+ *
200
+ * @public
201
+ */
202
+ export interface InMemoryProposalStoreOptions {
203
+ /**
204
+ * How long a draft proposal lives without a commit before being evicted.
205
+ * Default 24h. Pass as milliseconds.
206
+ */
207
+ draftTtlMs?: number;
208
+ /**
209
+ * How long a committed (or consumed) proposal lives past its `expiresAt`
210
+ * before eviction. Default 7 days. Pass as milliseconds.
211
+ */
212
+ committedGraceMs?: number;
213
+ /**
214
+ * Test-injectable clock. Defaults to `() => new Date()`.
215
+ */
216
+ clock?: () => Date;
217
+ }
218
+ /**
219
+ * Process-local {@link ProposalStore} reference implementation.
220
+ *
221
+ * Storage is a plain `Map` — JS event-loop atomicity covers the critical
222
+ * sections (no preemption between awaits within a method body since there
223
+ * are no awaits). Adequate for local dev, CI, and tests; production
224
+ * deployments wire a durable backing implementing the same interface.
225
+ *
226
+ * Eviction:
227
+ *
228
+ * - Drafts older than `draftTtlMs` (default 24h) are evicted on every
229
+ * read / write.
230
+ * - Committed proposals more than `committedGraceMs` past `expiresAt`
231
+ * (default 7 days) are evicted.
232
+ *
233
+ * Eviction runs lazily — no background timer thread.
234
+ *
235
+ * Cross-tenant safety: `get` and `getByMediaBuyId` honor `expectedAccountId`
236
+ * — cross-tenant probes return `null`, not the raw record.
237
+ *
238
+ * @public
239
+ */
240
+ export declare class InMemoryProposalStore<TRecipe extends Recipe = Recipe> implements ProposalStore<TRecipe> {
241
+ readonly isDurable = false;
242
+ private readonly records;
243
+ private readonly mediaBuyIndex;
244
+ private readonly creationTimes;
245
+ private readonly draftTtlMs;
246
+ private readonly committedGraceMs;
247
+ private readonly clock;
248
+ constructor(options?: InMemoryProposalStoreOptions);
249
+ private mediaBuyKey;
250
+ private evictExpired;
251
+ putDraft(args: {
252
+ proposalId: string;
253
+ accountId: string;
254
+ recipes: ReadonlyMap<string, TRecipe>;
255
+ proposalPayload: Record<string, unknown>;
256
+ }): void;
257
+ get(proposalId: string, args: {
258
+ expectedAccountId: string;
259
+ }): ProposalRecord<TRecipe> | null;
260
+ commit(proposalId: string, args: {
261
+ expiresAt: Date;
262
+ proposalPayload: Record<string, unknown>;
263
+ }): void;
264
+ tryReserveConsumption(proposalId: string, args: {
265
+ expectedAccountId: string;
266
+ }): ProposalRecord<TRecipe>;
267
+ finalizeConsumption(proposalId: string, args: {
268
+ mediaBuyId: string;
269
+ expectedAccountId: string;
270
+ }): void;
271
+ releaseConsumption(proposalId: string, args: {
272
+ expectedAccountId: string;
273
+ }): void;
274
+ discard(proposalId: string): void;
275
+ getByMediaBuyId(mediaBuyId: string, args: {
276
+ expectedAccountId: string;
277
+ }): ProposalRecord<TRecipe> | null;
278
+ }
279
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../../../src/lib/server/decisioning/proposal/store.ts"],"names":[],"mappings":"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"}