@reopt-ai/data-contract 0.1.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.
@@ -0,0 +1,83 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * `@reopt-ai/data-contract` — the wire contract between reopt-data and its
5
+ * server-credential consumers (RFC-0023).
6
+ *
7
+ * Subpaths:
8
+ * `@reopt-ai/data-contract` this module — version, shared primitives, errors
9
+ * `@reopt-ai/data-contract/ingest` POST /api/track request + response schemas
10
+ * `@reopt-ai/data-contract/query` POST /api/v1/query/* request + response schemas
11
+ * `@reopt-ai/data-contract/client` createDataClient() — typed fetch over both
12
+ *
13
+ * Only `/client` touches `fetch`; everything else is pure zod. The single
14
+ * runtime dependency is zod, deliberately — consumers bundle this.
15
+ */
16
+
17
+ /**
18
+ * Contract version. Bumped on any breaking change to a schema in this package.
19
+ * The server echoes the version it was built against in `x-reopt-contract-version`;
20
+ * `createDataClient` surfaces a mismatch rather than guessing.
21
+ */
22
+ declare const CONTRACT_VERSION = "0.1.0";
23
+ /** Response header carrying the server's contract version. */
24
+ declare const CONTRACT_VERSION_HEADER = "x-reopt-contract-version";
25
+ /** Request header names shared by the ingest and query planes. */
26
+ declare const CLIENT_ID_HEADER = "reopt-client-id";
27
+ declare const CLIENT_SECRET_HEADER = "reopt-client-secret";
28
+ declare const WRITE_KEY_HEADER = "reopt-write-key";
29
+ declare const DEVICE_ID_HEADER = "reopt-device-id";
30
+ declare const REQUEST_ID_HEADER = "x-request-id";
31
+ /**
32
+ * A UTC calendar date. Windows are inclusive on both ends and are widened
33
+ * server-side to `startDate T00:00:00Z` .. `endDate T23:59:59Z`.
34
+ */
35
+ declare const zDate: z.ZodString;
36
+ /** ISO-8601 instant, as produced by `Date#toISOString()`. */
37
+ declare const zInstant: z.ZodString;
38
+ /**
39
+ * Client credentials. The same pair authenticates both planes; what a given
40
+ * client may reach is decided server-side by `Client.scopes`
41
+ * (`"ingest"` / `"query"` / `"provision"`).
42
+ */
43
+ interface ClientCredentials {
44
+ clientId: string;
45
+ clientSecret: string;
46
+ }
47
+ /**
48
+ * Every non-2xx response from either plane, plus the two failures the client
49
+ * itself raises (`contract_mismatch`, `network_error`).
50
+ */
51
+ declare class DataApiError extends Error {
52
+ /**
53
+ * Brand for {@link DataApiError.is}. A bundler that inlines this module into
54
+ * more than one entry point produces two distinct classes, and `instanceof`
55
+ * silently stops matching — the brand survives that, and realm boundaries.
56
+ */
57
+ readonly isDataApiError: true;
58
+ readonly status: number;
59
+ readonly code: string;
60
+ readonly requestId?: string;
61
+ /** Parsed from `Retry-After`, in milliseconds. Only set on 429. */
62
+ readonly retryAfterMs?: number;
63
+ /** zod issues for `validation_failed`, or the raw body when unparseable. */
64
+ readonly details?: unknown;
65
+ constructor(init: {
66
+ message: string;
67
+ status: number;
68
+ code: string;
69
+ requestId?: string;
70
+ retryAfterMs?: number;
71
+ details?: unknown;
72
+ });
73
+ /** 429 and 5xx are worth retrying; 4xx are the caller's fault and are not. */
74
+ get retryable(): boolean;
75
+ /**
76
+ * Prefer this over `instanceof` in a `catch`. It holds even when the class
77
+ * has been duplicated — across CJS entry points, across bundler chunks, or
78
+ * across realms — where `instanceof` quietly returns false.
79
+ */
80
+ static is(value: unknown): value is DataApiError;
81
+ }
82
+
83
+ export { CLIENT_ID_HEADER, CLIENT_SECRET_HEADER, CONTRACT_VERSION, CONTRACT_VERSION_HEADER, type ClientCredentials, DEVICE_ID_HEADER, DataApiError, REQUEST_ID_HEADER, WRITE_KEY_HEADER, zDate, zInstant };
@@ -0,0 +1,83 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * `@reopt-ai/data-contract` — the wire contract between reopt-data and its
5
+ * server-credential consumers (RFC-0023).
6
+ *
7
+ * Subpaths:
8
+ * `@reopt-ai/data-contract` this module — version, shared primitives, errors
9
+ * `@reopt-ai/data-contract/ingest` POST /api/track request + response schemas
10
+ * `@reopt-ai/data-contract/query` POST /api/v1/query/* request + response schemas
11
+ * `@reopt-ai/data-contract/client` createDataClient() — typed fetch over both
12
+ *
13
+ * Only `/client` touches `fetch`; everything else is pure zod. The single
14
+ * runtime dependency is zod, deliberately — consumers bundle this.
15
+ */
16
+
17
+ /**
18
+ * Contract version. Bumped on any breaking change to a schema in this package.
19
+ * The server echoes the version it was built against in `x-reopt-contract-version`;
20
+ * `createDataClient` surfaces a mismatch rather than guessing.
21
+ */
22
+ declare const CONTRACT_VERSION = "0.1.0";
23
+ /** Response header carrying the server's contract version. */
24
+ declare const CONTRACT_VERSION_HEADER = "x-reopt-contract-version";
25
+ /** Request header names shared by the ingest and query planes. */
26
+ declare const CLIENT_ID_HEADER = "reopt-client-id";
27
+ declare const CLIENT_SECRET_HEADER = "reopt-client-secret";
28
+ declare const WRITE_KEY_HEADER = "reopt-write-key";
29
+ declare const DEVICE_ID_HEADER = "reopt-device-id";
30
+ declare const REQUEST_ID_HEADER = "x-request-id";
31
+ /**
32
+ * A UTC calendar date. Windows are inclusive on both ends and are widened
33
+ * server-side to `startDate T00:00:00Z` .. `endDate T23:59:59Z`.
34
+ */
35
+ declare const zDate: z.ZodString;
36
+ /** ISO-8601 instant, as produced by `Date#toISOString()`. */
37
+ declare const zInstant: z.ZodString;
38
+ /**
39
+ * Client credentials. The same pair authenticates both planes; what a given
40
+ * client may reach is decided server-side by `Client.scopes`
41
+ * (`"ingest"` / `"query"` / `"provision"`).
42
+ */
43
+ interface ClientCredentials {
44
+ clientId: string;
45
+ clientSecret: string;
46
+ }
47
+ /**
48
+ * Every non-2xx response from either plane, plus the two failures the client
49
+ * itself raises (`contract_mismatch`, `network_error`).
50
+ */
51
+ declare class DataApiError extends Error {
52
+ /**
53
+ * Brand for {@link DataApiError.is}. A bundler that inlines this module into
54
+ * more than one entry point produces two distinct classes, and `instanceof`
55
+ * silently stops matching — the brand survives that, and realm boundaries.
56
+ */
57
+ readonly isDataApiError: true;
58
+ readonly status: number;
59
+ readonly code: string;
60
+ readonly requestId?: string;
61
+ /** Parsed from `Retry-After`, in milliseconds. Only set on 429. */
62
+ readonly retryAfterMs?: number;
63
+ /** zod issues for `validation_failed`, or the raw body when unparseable. */
64
+ readonly details?: unknown;
65
+ constructor(init: {
66
+ message: string;
67
+ status: number;
68
+ code: string;
69
+ requestId?: string;
70
+ retryAfterMs?: number;
71
+ details?: unknown;
72
+ });
73
+ /** 429 and 5xx are worth retrying; 4xx are the caller's fault and are not. */
74
+ get retryable(): boolean;
75
+ /**
76
+ * Prefer this over `instanceof` in a `catch`. It holds even when the class
77
+ * has been duplicated — across CJS entry points, across bundler chunks, or
78
+ * across realms — where `instanceof` quietly returns false.
79
+ */
80
+ static is(value: unknown): value is DataApiError;
81
+ }
82
+
83
+ export { CLIENT_ID_HEADER, CLIENT_SECRET_HEADER, CONTRACT_VERSION, CONTRACT_VERSION_HEADER, type ClientCredentials, DEVICE_ID_HEADER, DataApiError, REQUEST_ID_HEADER, WRITE_KEY_HEADER, zDate, zInstant };
package/dist/index.js ADDED
@@ -0,0 +1,25 @@
1
+ import {
2
+ CLIENT_ID_HEADER,
3
+ CLIENT_SECRET_HEADER,
4
+ CONTRACT_VERSION,
5
+ CONTRACT_VERSION_HEADER,
6
+ DEVICE_ID_HEADER,
7
+ DataApiError,
8
+ REQUEST_ID_HEADER,
9
+ WRITE_KEY_HEADER,
10
+ zDate,
11
+ zInstant
12
+ } from "./chunk-IAOPUBJU.js";
13
+ export {
14
+ CLIENT_ID_HEADER,
15
+ CLIENT_SECRET_HEADER,
16
+ CONTRACT_VERSION,
17
+ CONTRACT_VERSION_HEADER,
18
+ DEVICE_ID_HEADER,
19
+ DataApiError,
20
+ REQUEST_ID_HEADER,
21
+ WRITE_KEY_HEADER,
22
+ zDate,
23
+ zInstant
24
+ };
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,43 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+ var _chunkHRKELGGHcjs = require('./chunk-HRKELGGH.cjs');
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+ exports.INGEST_ERROR_CODES = _chunkHRKELGGHcjs.INGEST_ERROR_CODES; exports.INGEST_MODES = _chunkHRKELGGHcjs.INGEST_MODES; exports.INGEST_REJECTION_REASONS = _chunkHRKELGGHcjs.INGEST_REJECTION_REASONS; exports.MAX_TRACK_PAYLOAD_BYTES = _chunkHRKELGGHcjs.MAX_TRACK_PAYLOAD_BYTES; exports.RESERVED_EVENT_NAMES = _chunkHRKELGGHcjs.RESERVED_EVENT_NAMES; exports.reconcileIngestResponse = _chunkHRKELGGHcjs.reconcileIngestResponse; exports.zDecrementPayload = _chunkHRKELGGHcjs.zDecrementPayload; exports.zIdentifyPayload = _chunkHRKELGGHcjs.zIdentifyPayload; exports.zIncrementPayload = _chunkHRKELGGHcjs.zIncrementPayload; exports.zIngestAcceptedResponse = _chunkHRKELGGHcjs.zIngestAcceptedResponse; exports.zIngestError = _chunkHRKELGGHcjs.zIngestError; exports.zIngestErrorCode = _chunkHRKELGGHcjs.zIngestErrorCode; exports.zIngestMode = _chunkHRKELGGHcjs.zIngestMode; exports.zIngestOkResponse = _chunkHRKELGGHcjs.zIngestOkResponse; exports.zIngestRejection = _chunkHRKELGGHcjs.zIngestRejection; exports.zIngestRejectionReason = _chunkHRKELGGHcjs.zIngestRejectionReason; exports.zIngestResponse = _chunkHRKELGGHcjs.zIngestResponse; exports.zTrackHandlerPayload = _chunkHRKELGGHcjs.zTrackHandlerPayload; exports.zTrackPayload = _chunkHRKELGGHcjs.zTrackPayload;
43
+ //# sourceMappingURL=ingest.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/eric/reopt-ai/reopt-data/packages/data-contract/dist/ingest.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,0uCAAC","file":"/Users/eric/reopt-ai/reopt-data/packages/data-contract/dist/ingest.cjs"}
@@ -0,0 +1,270 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * `POST /api/track` — the ingest contract.
5
+ *
6
+ * The request shape is shared by both credential modes. The *response* shape
7
+ * is where server-ingest differs: it reports per-event rejections instead of
8
+ * failing a whole batch, because a forwarder that stalls on one malformed row
9
+ * stops forwarding forever.
10
+ *
11
+ * Absorbed from the former internal `@reopt/ingest-contract`; that package is
12
+ * now a deprecated re-export of this module.
13
+ */
14
+
15
+ /** Event names the pipeline reserves for its own session bookkeeping. */
16
+ declare const RESERVED_EVENT_NAMES: readonly ["session_start", "session_end", "screen_view"];
17
+ /** Hard cap enforced by the route before the body is even parsed. */
18
+ declare const MAX_TRACK_PAYLOAD_BYTES = 512000;
19
+ declare const zTrackPayload: z.ZodObject<{
20
+ name: z.ZodString;
21
+ properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
22
+ profileId: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
23
+ }, z.core.$strip>;
24
+ declare const zIdentifyPayload: z.ZodObject<{
25
+ profileId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
26
+ firstName: z.ZodOptional<z.ZodString>;
27
+ lastName: z.ZodOptional<z.ZodString>;
28
+ email: z.ZodOptional<z.ZodEmail>;
29
+ avatar: z.ZodOptional<z.ZodURL>;
30
+ properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
31
+ }, z.core.$strip>;
32
+ declare const zIncrementPayload: z.ZodObject<{
33
+ profileId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
34
+ property: z.ZodString;
35
+ value: z.ZodOptional<z.ZodNumber>;
36
+ }, z.core.$strip>;
37
+ declare const zDecrementPayload: z.ZodObject<{
38
+ profileId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
39
+ property: z.ZodString;
40
+ value: z.ZodOptional<z.ZodNumber>;
41
+ }, z.core.$strip>;
42
+ declare const zTrackHandlerPayload: z.ZodDiscriminatedUnion<[z.ZodObject<{
43
+ eventId: z.ZodUUID;
44
+ timestamp: z.ZodNumber;
45
+ type: z.ZodLiteral<"track">;
46
+ payload: z.ZodObject<{
47
+ name: z.ZodString;
48
+ properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
49
+ profileId: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
50
+ }, z.core.$strip>;
51
+ }, z.core.$strip>, z.ZodObject<{
52
+ eventId: z.ZodUUID;
53
+ timestamp: z.ZodNumber;
54
+ type: z.ZodLiteral<"identify">;
55
+ payload: z.ZodObject<{
56
+ profileId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
57
+ firstName: z.ZodOptional<z.ZodString>;
58
+ lastName: z.ZodOptional<z.ZodString>;
59
+ email: z.ZodOptional<z.ZodEmail>;
60
+ avatar: z.ZodOptional<z.ZodURL>;
61
+ properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
62
+ }, z.core.$strip>;
63
+ }, z.core.$strip>, z.ZodObject<{
64
+ eventId: z.ZodUUID;
65
+ timestamp: z.ZodNumber;
66
+ type: z.ZodLiteral<"increment">;
67
+ payload: z.ZodObject<{
68
+ profileId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
69
+ property: z.ZodString;
70
+ value: z.ZodOptional<z.ZodNumber>;
71
+ }, z.core.$strip>;
72
+ }, z.core.$strip>, z.ZodObject<{
73
+ eventId: z.ZodUUID;
74
+ timestamp: z.ZodNumber;
75
+ type: z.ZodLiteral<"decrement">;
76
+ payload: z.ZodObject<{
77
+ profileId: z.ZodUnion<[z.ZodString, z.ZodNumber]>;
78
+ property: z.ZodString;
79
+ value: z.ZodOptional<z.ZodNumber>;
80
+ }, z.core.$strip>;
81
+ }, z.core.$strip>], "type">;
82
+ type ITrackPayload = z.infer<typeof zTrackPayload>;
83
+ type IIdentifyPayload = z.infer<typeof zIdentifyPayload>;
84
+ type IIncrementPayload = z.infer<typeof zIncrementPayload>;
85
+ type IDecrementPayload = z.infer<typeof zDecrementPayload>;
86
+ type ITrackHandlerPayload = z.infer<typeof zTrackHandlerPayload>;
87
+ /**
88
+ * Decided by the credential presented, never by a header the caller sets:
89
+ * `reopt-write-key` alone → `browser`, `reopt-client-id` + `reopt-client-secret`
90
+ * → `server`. A separate mode header could disagree with the credential; this
91
+ * cannot.
92
+ *
93
+ * `browser` keeps the 5-second click dedup and device-scoped sessions.
94
+ * `server` drops both and relies solely on `eventId` idempotency — a server
95
+ * batch legitimately contains the same event name many times within one second,
96
+ * and its "device" is a process, not a person.
97
+ */
98
+ declare const INGEST_MODES: readonly ["browser", "server"];
99
+ declare const zIngestMode: z.ZodEnum<{
100
+ browser: "browser";
101
+ server: "server";
102
+ }>;
103
+ type IngestMode = z.infer<typeof zIngestMode>;
104
+ /**
105
+ * Why a single event in a batch was dropped. These are permanent: re-sending
106
+ * the same row produces the same rejection, so a forwarder should count it as
107
+ * skipped and advance its cursor rather than retry.
108
+ */
109
+ declare const INGEST_REJECTION_REASONS: readonly ["validation_failed", "reserved_name", "duplicate_in_batch"];
110
+ declare const zIngestRejectionReason: z.ZodEnum<{
111
+ validation_failed: "validation_failed";
112
+ reserved_name: "reserved_name";
113
+ duplicate_in_batch: "duplicate_in_batch";
114
+ }>;
115
+ type IngestRejectionReason = z.infer<typeof zIngestRejectionReason>;
116
+ declare const zIngestRejection: z.ZodObject<{
117
+ eventId: z.ZodString;
118
+ index: z.ZodNumber;
119
+ reason: z.ZodEnum<{
120
+ validation_failed: "validation_failed";
121
+ reserved_name: "reserved_name";
122
+ duplicate_in_batch: "duplicate_in_batch";
123
+ }>;
124
+ message: z.ZodOptional<z.ZodString>;
125
+ }, z.core.$strip>;
126
+ type IngestRejection = z.infer<typeof zIngestRejection>;
127
+ /** 200 — accepted and handed to the materialize queue. */
128
+ declare const zIngestOkResponse: z.ZodObject<{
129
+ queued: z.ZodBoolean;
130
+ accepted: z.ZodNumber;
131
+ duplicates: z.ZodNumber;
132
+ rejected: z.ZodArray<z.ZodObject<{
133
+ eventId: z.ZodString;
134
+ index: z.ZodNumber;
135
+ reason: z.ZodEnum<{
136
+ validation_failed: "validation_failed";
137
+ reserved_name: "reserved_name";
138
+ duplicate_in_batch: "duplicate_in_batch";
139
+ }>;
140
+ message: z.ZodOptional<z.ZodString>;
141
+ }, z.core.$strip>>;
142
+ status: z.ZodLiteral<"ok">;
143
+ requestId: z.ZodString;
144
+ mode: z.ZodEnum<{
145
+ browser: "browser";
146
+ server: "server";
147
+ }>;
148
+ }, z.core.$strip>;
149
+ /**
150
+ * 202 — raw events landed, but enqueueing the materialize task failed. No data
151
+ * is lost: the `replay-unmaterialized` cron picks these up. A forwarder should
152
+ * treat this as success and advance its cursor. Carries the same counts as 200
153
+ * so the reconciliation below works here too.
154
+ */
155
+ declare const zIngestAcceptedResponse: z.ZodObject<{
156
+ backgroundQueued: z.ZodLiteral<false>;
157
+ replay: z.ZodLiteral<"unmaterialized-raw-events">;
158
+ accepted: z.ZodNumber;
159
+ duplicates: z.ZodNumber;
160
+ rejected: z.ZodArray<z.ZodObject<{
161
+ eventId: z.ZodString;
162
+ index: z.ZodNumber;
163
+ reason: z.ZodEnum<{
164
+ validation_failed: "validation_failed";
165
+ reserved_name: "reserved_name";
166
+ duplicate_in_batch: "duplicate_in_batch";
167
+ }>;
168
+ message: z.ZodOptional<z.ZodString>;
169
+ }, z.core.$strip>>;
170
+ status: z.ZodLiteral<"accepted">;
171
+ requestId: z.ZodString;
172
+ mode: z.ZodEnum<{
173
+ browser: "browser";
174
+ server: "server";
175
+ }>;
176
+ }, z.core.$strip>;
177
+ declare const zIngestResponse: z.ZodDiscriminatedUnion<[z.ZodObject<{
178
+ queued: z.ZodBoolean;
179
+ accepted: z.ZodNumber;
180
+ duplicates: z.ZodNumber;
181
+ rejected: z.ZodArray<z.ZodObject<{
182
+ eventId: z.ZodString;
183
+ index: z.ZodNumber;
184
+ reason: z.ZodEnum<{
185
+ validation_failed: "validation_failed";
186
+ reserved_name: "reserved_name";
187
+ duplicate_in_batch: "duplicate_in_batch";
188
+ }>;
189
+ message: z.ZodOptional<z.ZodString>;
190
+ }, z.core.$strip>>;
191
+ status: z.ZodLiteral<"ok">;
192
+ requestId: z.ZodString;
193
+ mode: z.ZodEnum<{
194
+ browser: "browser";
195
+ server: "server";
196
+ }>;
197
+ }, z.core.$strip>, z.ZodObject<{
198
+ backgroundQueued: z.ZodLiteral<false>;
199
+ replay: z.ZodLiteral<"unmaterialized-raw-events">;
200
+ accepted: z.ZodNumber;
201
+ duplicates: z.ZodNumber;
202
+ rejected: z.ZodArray<z.ZodObject<{
203
+ eventId: z.ZodString;
204
+ index: z.ZodNumber;
205
+ reason: z.ZodEnum<{
206
+ validation_failed: "validation_failed";
207
+ reserved_name: "reserved_name";
208
+ duplicate_in_batch: "duplicate_in_batch";
209
+ }>;
210
+ message: z.ZodOptional<z.ZodString>;
211
+ }, z.core.$strip>>;
212
+ status: z.ZodLiteral<"accepted">;
213
+ requestId: z.ZodString;
214
+ mode: z.ZodEnum<{
215
+ browser: "browser";
216
+ server: "server";
217
+ }>;
218
+ }, z.core.$strip>], "status">;
219
+ type IngestOkResponse = z.infer<typeof zIngestOkResponse>;
220
+ type IngestAcceptedResponse = z.infer<typeof zIngestAcceptedResponse>;
221
+ type IngestResponse = z.infer<typeof zIngestResponse>;
222
+ /**
223
+ * The reconciliation a forwarder runs on every 2xx:
224
+ *
225
+ * accepted + duplicates + rejected.length === events sent
226
+ *
227
+ * A mismatch means the server silently dropped something, which is exactly the
228
+ * failure mode this contract exists to make impossible to miss.
229
+ */
230
+ declare function reconcileIngestResponse(response: IngestResponse, sentCount: number): boolean;
231
+ /**
232
+ * Stable machine-readable codes. Branch on these, never on `error`/`message`,
233
+ * which are prose and may be reworded.
234
+ */
235
+ declare const INGEST_ERROR_CODES: readonly ["unauthorized", "invalid_json", "payload_too_large", "empty_batch", "alias_unsupported", "project_without_organization", "validation_failed", "rate_limited", "quota_exceeded", "internal_error"];
236
+ declare const zIngestErrorCode: z.ZodEnum<{
237
+ unauthorized: "unauthorized";
238
+ validation_failed: "validation_failed";
239
+ rate_limited: "rate_limited";
240
+ internal_error: "internal_error";
241
+ invalid_json: "invalid_json";
242
+ payload_too_large: "payload_too_large";
243
+ empty_batch: "empty_batch";
244
+ alias_unsupported: "alias_unsupported";
245
+ project_without_organization: "project_without_organization";
246
+ quota_exceeded: "quota_exceeded";
247
+ }>;
248
+ type IngestErrorCode = z.infer<typeof zIngestErrorCode>;
249
+ declare const zIngestError: z.ZodObject<{
250
+ status: z.ZodNumber;
251
+ code: z.ZodEnum<{
252
+ unauthorized: "unauthorized";
253
+ validation_failed: "validation_failed";
254
+ rate_limited: "rate_limited";
255
+ internal_error: "internal_error";
256
+ invalid_json: "invalid_json";
257
+ payload_too_large: "payload_too_large";
258
+ empty_batch: "empty_batch";
259
+ alias_unsupported: "alias_unsupported";
260
+ project_without_organization: "project_without_organization";
261
+ quota_exceeded: "quota_exceeded";
262
+ }>;
263
+ error: z.ZodString;
264
+ message: z.ZodOptional<z.ZodString>;
265
+ errors: z.ZodOptional<z.ZodUnknown>;
266
+ requestId: z.ZodOptional<z.ZodString>;
267
+ }, z.core.$strip>;
268
+ type IngestError = z.infer<typeof zIngestError>;
269
+
270
+ export { type IDecrementPayload, type IIdentifyPayload, type IIncrementPayload, INGEST_ERROR_CODES, INGEST_MODES, INGEST_REJECTION_REASONS, type ITrackHandlerPayload, type ITrackPayload, type IngestAcceptedResponse, type IngestError, type IngestErrorCode, type IngestMode, type IngestOkResponse, type IngestRejection, type IngestRejectionReason, type IngestResponse, MAX_TRACK_PAYLOAD_BYTES, RESERVED_EVENT_NAMES, reconcileIngestResponse, zDecrementPayload, zIdentifyPayload, zIncrementPayload, zIngestAcceptedResponse, zIngestError, zIngestErrorCode, zIngestMode, zIngestOkResponse, zIngestRejection, zIngestRejectionReason, zIngestResponse, zTrackHandlerPayload, zTrackPayload };