@abloatai/transaction 0.37.1 → 0.38.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 (148) hide show
  1. package/dist/ai-sdk/index.d.ts +3 -1
  2. package/dist/ai-sdk/index.d.ts.map +1 -1
  3. package/dist/ai-sdk/index.js +2 -1
  4. package/dist/ai-sdk/index.js.map +1 -1
  5. package/dist/ai-sdk/modelTools.d.ts +67 -0
  6. package/dist/ai-sdk/modelTools.d.ts.map +1 -0
  7. package/dist/ai-sdk/modelTools.js +89 -0
  8. package/dist/ai-sdk/modelTools.js.map +1 -0
  9. package/dist/ai-sdk/toolOptions.d.ts +8 -0
  10. package/dist/ai-sdk/toolOptions.d.ts.map +1 -0
  11. package/dist/ai-sdk/toolOptions.js +2 -0
  12. package/dist/ai-sdk/toolOptions.js.map +1 -0
  13. package/dist/ai-sdk/{coordinatedTool.d.ts → updateTool.d.ts} +21 -28
  14. package/dist/ai-sdk/updateTool.d.ts.map +1 -0
  15. package/dist/ai-sdk/{coordinatedTool.js → updateTool.js} +39 -50
  16. package/dist/ai-sdk/updateTool.js.map +1 -0
  17. package/dist/auth/capability.d.ts +6 -0
  18. package/dist/auth/capability.d.ts.map +1 -1
  19. package/dist/auth/capability.js +4 -0
  20. package/dist/auth/capability.js.map +1 -1
  21. package/dist/auth/capabilityLifecycle.d.ts +3 -0
  22. package/dist/auth/capabilityLifecycle.d.ts.map +1 -1
  23. package/dist/auth/identity.d.ts +6 -4
  24. package/dist/auth/identity.d.ts.map +1 -1
  25. package/dist/auth/identity.js +7 -11
  26. package/dist/auth/identity.js.map +1 -1
  27. package/dist/auth/schemas.d.ts +5 -5
  28. package/dist/auth/schemas.d.ts.map +1 -1
  29. package/dist/auth/schemas.js +5 -2
  30. package/dist/auth/schemas.js.map +1 -1
  31. package/dist/auth/sessionMint.d.ts.map +1 -1
  32. package/dist/auth/sessionMint.js +3 -0
  33. package/dist/auth/sessionMint.js.map +1 -1
  34. package/dist/branches.d.ts +251 -0
  35. package/dist/branches.d.ts.map +1 -0
  36. package/dist/branches.js +108 -0
  37. package/dist/branches.js.map +1 -0
  38. package/dist/coordination/awaitClaimGrant.d.ts +2 -0
  39. package/dist/coordination/awaitClaimGrant.d.ts.map +1 -1
  40. package/dist/coordination/awaitClaimGrant.js +15 -2
  41. package/dist/coordination/awaitClaimGrant.js.map +1 -1
  42. package/dist/coordination/schema.d.ts +2 -0
  43. package/dist/coordination/schema.d.ts.map +1 -1
  44. package/dist/coordination/schema.js +2 -0
  45. package/dist/coordination/schema.js.map +1 -1
  46. package/dist/docs/catalog.d.ts +5 -5
  47. package/dist/docs/catalog.d.ts.map +1 -1
  48. package/dist/docs/catalog.js +12 -12
  49. package/dist/docs/catalog.js.map +1 -1
  50. package/dist/footprint.d.ts +3 -5
  51. package/dist/footprint.d.ts.map +1 -1
  52. package/dist/footprint.js +0 -0
  53. package/dist/footprint.js.map +1 -1
  54. package/dist/index.d.ts +1 -0
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +1 -0
  57. package/dist/index.js.map +1 -1
  58. package/dist/keys/index.d.ts +15 -7
  59. package/dist/keys/index.d.ts.map +1 -1
  60. package/dist/keys/index.js +45 -14
  61. package/dist/keys/index.js.map +1 -1
  62. package/dist/schema/openapi.d.ts +1 -1
  63. package/dist/schema/openapi.d.ts.map +1 -1
  64. package/dist/schema/openapi.js +308 -29
  65. package/dist/schema/openapi.js.map +1 -1
  66. package/dist/server/commit.d.ts +2 -15
  67. package/dist/server/commit.d.ts.map +1 -1
  68. package/dist/source/adapter.d.ts +7 -2
  69. package/dist/source/adapter.d.ts.map +1 -1
  70. package/dist/source/adapter.js +4 -2
  71. package/dist/source/adapter.js.map +1 -1
  72. package/dist/source/adapterFactory.d.ts +10 -0
  73. package/dist/source/adapterFactory.d.ts.map +1 -0
  74. package/dist/source/adapterFactory.js +33 -0
  75. package/dist/source/adapterFactory.js.map +1 -0
  76. package/dist/source/adapterProfile.d.ts +55 -0
  77. package/dist/source/adapterProfile.d.ts.map +1 -0
  78. package/dist/source/adapterProfile.js +54 -0
  79. package/dist/source/adapterProfile.js.map +1 -0
  80. package/dist/source/adapters/drizzle.d.ts.map +1 -1
  81. package/dist/source/adapters/drizzle.js +5 -2
  82. package/dist/source/adapters/drizzle.js.map +1 -1
  83. package/dist/source/adapters/kysely.d.ts.map +1 -1
  84. package/dist/source/adapters/kysely.js +7 -4
  85. package/dist/source/adapters/kysely.js.map +1 -1
  86. package/dist/source/adapters/memory.d.ts.map +1 -1
  87. package/dist/source/adapters/memory.js +5 -2
  88. package/dist/source/adapters/memory.js.map +1 -1
  89. package/dist/source/adapters/prisma.d.ts.map +1 -1
  90. package/dist/source/adapters/prisma.js +5 -2
  91. package/dist/source/adapters/prisma.js.map +1 -1
  92. package/dist/source/conformance.d.ts.map +1 -1
  93. package/dist/source/conformance.js +18 -0
  94. package/dist/source/conformance.js.map +1 -1
  95. package/dist/source/index.d.ts +2 -0
  96. package/dist/source/index.d.ts.map +1 -1
  97. package/dist/source/index.js +2 -0
  98. package/dist/source/index.js.map +1 -1
  99. package/dist/source/types.d.ts +3 -14
  100. package/dist/source/types.d.ts.map +1 -1
  101. package/dist/source/types.js.map +1 -1
  102. package/dist/syncLog/contract.d.ts +1 -1
  103. package/dist/syncLog/contract.d.ts.map +1 -1
  104. package/dist/syncLog/contract.js +1 -2
  105. package/dist/syncLog/contract.js.map +1 -1
  106. package/dist/wire/accountResponses.d.ts +5 -9
  107. package/dist/wire/accountResponses.d.ts.map +1 -1
  108. package/dist/wire/accountResponses.js +5 -6
  109. package/dist/wire/accountResponses.js.map +1 -1
  110. package/dist/wire/delta.d.ts +11 -0
  111. package/dist/wire/delta.d.ts.map +1 -1
  112. package/dist/wire/delta.js +11 -0
  113. package/dist/wire/delta.js.map +1 -1
  114. package/dist/wire/inboundFrames.d.ts +2 -0
  115. package/dist/wire/inboundFrames.d.ts.map +1 -1
  116. package/package.json +8 -2
  117. package/src/ai-sdk/index.ts +19 -6
  118. package/src/ai-sdk/modelTools.ts +165 -0
  119. package/src/ai-sdk/toolOptions.ts +18 -0
  120. package/src/ai-sdk/{coordinatedTool.ts → updateTool.ts} +59 -69
  121. package/src/auth/capability.ts +4 -0
  122. package/src/auth/identity.ts +16 -16
  123. package/src/auth/schemas.ts +5 -2
  124. package/src/auth/sessionMint.ts +3 -0
  125. package/src/branches.ts +134 -0
  126. package/src/coordination/awaitClaimGrant.ts +18 -2
  127. package/src/coordination/schema.ts +2 -0
  128. package/src/docs/catalog.ts +24 -12
  129. package/src/footprint.ts +0 -0
  130. package/src/index.ts +1 -0
  131. package/src/keys/index.ts +56 -17
  132. package/src/schema/openapi.ts +366 -38
  133. package/src/server/commit.ts +2 -15
  134. package/src/source/adapter.ts +7 -2
  135. package/src/source/adapterFactory.ts +60 -0
  136. package/src/source/adapterProfile.ts +75 -0
  137. package/src/source/adapters/drizzle.ts +5 -2
  138. package/src/source/adapters/kysely.ts +10 -4
  139. package/src/source/adapters/memory.ts +5 -2
  140. package/src/source/adapters/prisma.ts +5 -2
  141. package/src/source/conformance.ts +18 -0
  142. package/src/source/index.ts +14 -0
  143. package/src/source/types.ts +3 -14
  144. package/src/syncLog/contract.ts +1 -2
  145. package/src/wire/accountResponses.ts +5 -6
  146. package/src/wire/delta.ts +11 -0
  147. package/dist/ai-sdk/coordinatedTool.d.ts.map +0 -1
  148. package/dist/ai-sdk/coordinatedTool.js.map +0 -1
@@ -1,11 +1,13 @@
1
1
  /**
2
2
  * The canonical interface every data-source backend implements, together with the bridge
3
3
  * that wires an implementation into the `dataSource()` HTTP handler. This package
4
- * defines the contract and ships adapters for three object-relational mappers —
4
+ * defines the contract and ships PostgreSQL bindings for three object-relational mappers —
5
5
  * {@link prismaDataSource}, {@link drizzleDataSource}, and {@link kyselyDataSource} —
6
6
  * each verified by shared mutation checks plus endpoint-only outbox checks. The
7
7
  * direct Kysely wrapper runs only the shared mutation contract. You can also
8
- * write your own.
8
+ * write your own through the `defineDatabaseAdapter` factory. PostgreSQL, the ORM
9
+ * binding, and WAL/outbox observation are recorded as separate profile axes;
10
+ * an ORM name never implies database portability.
9
11
  *
10
12
  * An endpoint adapter reads and writes your database, and it owns the transactional
11
13
  * outbox and idempotency bookkeeping as well, so you never write those by hand.
@@ -29,6 +31,7 @@ import type {
29
31
  EventsPage,
30
32
  Migration,
31
33
  } from './contract.js';
34
+ import type { DatabaseAdapterProfile } from './adapterProfile.js';
32
35
 
33
36
  /**
34
37
  * A single row keyed by the schema's field names (for example `operatorId`), not
@@ -57,6 +60,8 @@ export interface AdapterCommitResult {
57
60
  * transaction id is never used as that namespace.
58
61
  */
59
62
  export interface MutationAdapter {
63
+ /** Database, binding, and observation are separate, explicit axes. */
64
+ readonly profile: DatabaseAdapterProfile;
60
65
  readonly capabilities: AdapterCapabilities;
61
66
  /** Infrastructure migrations required by this wrapper's advertised capabilities. */
62
67
  migrations(): readonly Migration[];
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Normalizes and validates a database adapter declaration.
3
+ *
4
+ * Database integrations should return through this function rather than
5
+ * assembling an object directly. It is the single place that relates database,
6
+ * binding, observation, and advertised guarantees.
7
+ */
8
+
9
+ import { AbloValidationError } from '../errors.js';
10
+ import type { MutationAdapter } from './adapter.js';
11
+ import { databaseAdapterProfileSchema } from './adapterProfile.js';
12
+
13
+ export function defineDatabaseAdapter<T extends MutationAdapter>(
14
+ adapter: T,
15
+ ): T {
16
+ const profile = databaseAdapterProfileSchema.parse(adapter.profile);
17
+ const { capabilities } = adapter;
18
+
19
+ if (!capabilities.transactions) {
20
+ throw new AbloValidationError(
21
+ `Database adapter "${profile.id}" cannot provide Ablo commits without atomic transactions`,
22
+ { code: 'source_adapter_misconfigured' },
23
+ );
24
+ }
25
+
26
+ if (
27
+ capabilities.postgresWalEcho === true &&
28
+ profile.database !== 'postgresql'
29
+ ) {
30
+ throw new AbloValidationError(
31
+ `Database adapter "${profile.id}" advertises a PostgreSQL WAL marker on ${profile.database}`,
32
+ { code: 'source_adapter_misconfigured' },
33
+ );
34
+ }
35
+
36
+ if (profile.observation.kind === 'postgres-wal') {
37
+ if (
38
+ profile.database !== 'postgresql' ||
39
+ capabilities.postgresWalEcho !== true ||
40
+ capabilities.outboxEvents
41
+ ) {
42
+ throw new AbloValidationError(
43
+ `Database adapter "${profile.id}" has an invalid PostgreSQL WAL capability combination`,
44
+ { code: 'source_adapter_misconfigured' },
45
+ );
46
+ }
47
+ }
48
+
49
+ if (
50
+ profile.observation.kind === 'transactional-outbox' &&
51
+ !capabilities.outboxEvents
52
+ ) {
53
+ throw new AbloValidationError(
54
+ `Database adapter "${profile.id}" declares an outbox observation profile without outbox events`,
55
+ { code: 'source_adapter_misconfigured' },
56
+ );
57
+ }
58
+
59
+ return { ...adapter, profile } as T;
60
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * The three independent axes of a customer-database adapter.
3
+ *
4
+ * An ORM binding is not a database, and a database is not an observation
5
+ * strategy. Keeping them separate prevents a Prisma or Kysely adapter from
6
+ * looking portable while depending on PostgreSQL SQL or WAL underneath.
7
+ */
8
+
9
+ import { z } from 'zod';
10
+
11
+ export const databaseKindSchema = z.enum(['postgresql', 'memory']);
12
+ export type DatabaseKind = z.infer<typeof databaseKindSchema>;
13
+
14
+ export const adapterBindingSchema = z.enum([
15
+ 'prisma',
16
+ 'drizzle',
17
+ 'kysely',
18
+ 'memory',
19
+ 'custom',
20
+ ]);
21
+ export type AdapterBinding = z.infer<typeof adapterBindingSchema>;
22
+
23
+ export const observationProfileSchema = z.discriminatedUnion('kind', [
24
+ z.strictObject({
25
+ kind: z.literal('transactional-outbox'),
26
+ externalWrites: z.boolean(),
27
+ }),
28
+ z.strictObject({
29
+ kind: z.literal('postgres-wal'),
30
+ externalWrites: z.literal(true),
31
+ }),
32
+ ]);
33
+ export type ObservationProfile = z.infer<typeof observationProfileSchema>;
34
+
35
+ export const databaseAdapterProfileSchema = z.strictObject({
36
+ id: z.string().min(1),
37
+ database: databaseKindSchema,
38
+ binding: adapterBindingSchema,
39
+ observation: observationProfileSchema,
40
+ });
41
+ export type DatabaseAdapterProfile = z.infer<
42
+ typeof databaseAdapterProfileSchema
43
+ >;
44
+
45
+ export type PostgresBinding = Extract<
46
+ AdapterBinding,
47
+ 'prisma' | 'drizzle' | 'kysely' | 'custom'
48
+ >;
49
+
50
+ export function postgresAdapterProfile(
51
+ binding: PostgresBinding,
52
+ observation: 'transactional-outbox' | 'postgres-wal',
53
+ ): DatabaseAdapterProfile {
54
+ return {
55
+ id: `postgresql-${binding}-${observation}`,
56
+ database: 'postgresql',
57
+ binding,
58
+ observation:
59
+ observation === 'postgres-wal'
60
+ ? { kind: 'postgres-wal', externalWrites: true }
61
+ : { kind: 'transactional-outbox', externalWrites: false },
62
+ };
63
+ }
64
+
65
+ export function memoryAdapterProfile(): DatabaseAdapterProfile {
66
+ return {
67
+ id: 'memory-native-transactional-outbox',
68
+ database: 'memory',
69
+ binding: 'memory',
70
+ observation: {
71
+ kind: 'transactional-outbox',
72
+ externalWrites: false,
73
+ },
74
+ };
75
+ }
@@ -42,6 +42,8 @@ import type {
42
42
  DataSourceAdapter,
43
43
  Row,
44
44
  } from '../adapter.js';
45
+ import { defineDatabaseAdapter } from '../adapterFactory.js';
46
+ import { postgresAdapterProfile } from '../adapterProfile.js';
45
47
  import type { ChangeSet, EventsPage, Migration, Operation } from '../contract.js';
46
48
  import { outboxEventSchema } from '../contract.js';
47
49
  import { adapterTableMigrations } from '../migrations.js';
@@ -188,7 +190,8 @@ export function drizzleDataSource<S extends SchemaRecord>(
188
190
  return updated[0] ? toFields(mc, updated[0]) : { id, ...input };
189
191
  };
190
192
 
191
- return {
193
+ return defineDatabaseAdapter({
194
+ profile: postgresAdapterProfile('drizzle', 'transactional-outbox'),
192
195
  capabilities: {
193
196
  transactions: true,
194
197
  propose: false,
@@ -287,5 +290,5 @@ export function drizzleDataSource<S extends SchemaRecord>(
287
290
  );
288
291
  return { events, nextCursor: events.at(-1)?.cursor ?? null };
289
292
  },
290
- };
293
+ });
291
294
  }
@@ -25,6 +25,8 @@ import type {
25
25
  MutationAdapter,
26
26
  Row,
27
27
  } from '../adapter.js';
28
+ import { defineDatabaseAdapter } from '../adapterFactory.js';
29
+ import { postgresAdapterProfile } from '../adapterProfile.js';
28
30
  import type { ChangeSet, EventsPage, Migration } from '../contract.js';
29
31
  import {
30
32
  changeSetSchema,
@@ -199,7 +201,11 @@ export function createKyselyMutationAdapter(
199
201
  options: KyselyMutationAdapterOptions = {},
200
202
  ): MutationAdapter {
201
203
  const markerModelFor = options.markerModelFor ?? ((model: string) => model);
202
- return {
204
+ return defineDatabaseAdapter({
205
+ profile: postgresAdapterProfile(
206
+ 'kysely',
207
+ mode === 'direct' ? 'postgres-wal' : 'transactional-outbox',
208
+ ),
203
209
  capabilities: {
204
210
  transactions: true,
205
211
  propose: false,
@@ -281,7 +287,7 @@ export function createKyselyMutationAdapter(
281
287
  return { rows };
282
288
  });
283
289
  },
284
- };
290
+ });
285
291
  }
286
292
 
287
293
  /** Endpoint wrapper: mutation + ledger + outbox, with an optional marker. */
@@ -295,7 +301,7 @@ export function kyselyDataSource<S extends SchemaRecord>(
295
301
  'endpoint',
296
302
  );
297
303
 
298
- return {
304
+ return defineDatabaseAdapter({
299
305
  ...mutation,
300
306
  capabilities: { ...mutation.capabilities, outboxEvents: true },
301
307
 
@@ -324,7 +330,7 @@ export function kyselyDataSource<S extends SchemaRecord>(
324
330
  );
325
331
  return { events, nextCursor: events.at(-1)?.cursor ?? null };
326
332
  },
327
- };
333
+ });
328
334
  }
329
335
 
330
336
  /** Direct wrapper: mutation + ledger + required logical marker, never outbox. */
@@ -17,6 +17,8 @@ import type {
17
17
  DataSourceAdapter,
18
18
  Row,
19
19
  } from '../adapter.js';
20
+ import { defineDatabaseAdapter } from '../adapterFactory.js';
21
+ import { memoryAdapterProfile } from '../adapterProfile.js';
20
22
  import type { ChangeSet, EventsPage, Migration, Operation, OutboxEvent } from '../contract.js';
21
23
  import {
22
24
  assertSourceIdempotencyIntent,
@@ -81,7 +83,8 @@ export function memoryDataSource(): DataSourceAdapter {
81
83
  }
82
84
  };
83
85
 
84
- return {
86
+ return defineDatabaseAdapter({
87
+ profile: memoryAdapterProfile(),
85
88
  capabilities: {
86
89
  transactions: true,
87
90
  propose: false,
@@ -150,5 +153,5 @@ export function memoryDataSource(): DataSourceAdapter {
150
153
  nextCursor: page.at(-1)?.cursor ?? null,
151
154
  };
152
155
  },
153
- };
156
+ });
154
157
  }
@@ -21,6 +21,8 @@ import type {
21
21
  DataSourceAdapter,
22
22
  Row,
23
23
  } from '../adapter.js';
24
+ import { defineDatabaseAdapter } from '../adapterFactory.js';
25
+ import { postgresAdapterProfile } from '../adapterProfile.js';
24
26
  import type { ChangeSet, EventsPage, Migration, Operation, OutboxEvent } from '../contract.js';
25
27
  import { outboxEventSchema } from '../contract.js';
26
28
  import { adapterTableMigrations } from '../migrations.js';
@@ -163,7 +165,8 @@ export function prismaDataSource<S extends SchemaRecord>(
163
165
  }
164
166
  };
165
167
 
166
- return {
168
+ return defineDatabaseAdapter({
169
+ profile: postgresAdapterProfile('prisma', 'transactional-outbox'),
167
170
  capabilities: {
168
171
  transactions: true,
169
172
  propose: false,
@@ -278,5 +281,5 @@ export function prismaDataSource<S extends SchemaRecord>(
278
281
  nextCursor: events.at(-1)?.cursor ?? null,
279
282
  };
280
283
  },
281
- };
284
+ });
282
285
  }
@@ -59,6 +59,16 @@ export function mutationConformanceChecks(
59
59
  return options.prepareChange?.(value) ?? value;
60
60
  };
61
61
  return [
62
+ {
63
+ name: 'adapter declares database, binding, and observation independently',
64
+ run: async () => {
65
+ const adapter = await make();
66
+ assert.ok(adapter.profile.id.length > 0);
67
+ assert.ok(adapter.profile.database.length > 0);
68
+ assert.ok(adapter.profile.binding.length > 0);
69
+ assert.ok(adapter.profile.observation.kind.length > 0);
70
+ },
71
+ },
62
72
  {
63
73
  name: 'commit applies a CREATE and returns the canonical row',
64
74
  run: async () => {
@@ -174,6 +184,14 @@ export function mutationConformanceChecks(
174
184
  /** Guarantees that apply only to endpoint wrappers with an outbox/events feed. */
175
185
  export function endpointConformanceChecks(make: MakeAdapter): ConformanceCheck[] {
176
186
  return [
187
+ {
188
+ name: 'endpoint adapter declares transactional-outbox observation',
189
+ run: async () => {
190
+ const adapter = await make();
191
+ assert.equal(adapter.profile.observation.kind, 'transactional-outbox');
192
+ assert.equal(adapter.capabilities.outboxEvents, true);
193
+ },
194
+ },
177
195
  {
178
196
  name: 'endpoint replay does not append its correlated outbox event twice',
179
197
  run: async () => {
@@ -109,6 +109,20 @@ export {
109
109
  type AdapterCommitResult,
110
110
  type Row as AdapterRow,
111
111
  } from './adapter.js';
112
+ export {
113
+ adapterBindingSchema,
114
+ databaseAdapterProfileSchema,
115
+ databaseKindSchema,
116
+ memoryAdapterProfile,
117
+ observationProfileSchema,
118
+ postgresAdapterProfile,
119
+ type AdapterBinding,
120
+ type DatabaseAdapterProfile,
121
+ type DatabaseKind,
122
+ type ObservationProfile,
123
+ type PostgresBinding,
124
+ } from './adapterProfile.js';
125
+ export { defineDatabaseAdapter } from './adapterFactory.js';
112
126
  export {
113
127
  operationSchema,
114
128
  operationTypeSchema,
@@ -11,7 +11,6 @@
11
11
  */
12
12
 
13
13
  import { AbloValidationError } from '../errors.js';
14
- import type { Environment } from '../environment.js';
15
14
  import type { CommitOperationType, OnStaleMode } from '../coordination/schema.js';
16
15
  import type { ParticipantKind } from '../types/participant.js';
17
16
 
@@ -88,21 +87,11 @@ export interface SourceRequestContext {
88
87
  readonly participantId?: string;
89
88
  readonly participantKind?: ParticipantKind;
90
89
  readonly organizationId?: string;
91
- /** Trusted project plane selected by the authenticating credential. */
90
+ /** Immutable branch selected by the authenticating credential. */
91
+ readonly branchId?: string;
92
+ /** Trusted project selected by the authenticating credential. */
92
93
  readonly projectId?: string;
93
- /** Trusted sandbox plane selected by the authenticating credential. */
94
- readonly sandboxId?: string;
95
94
  readonly requiredSyncGroups?: readonly string[];
96
- /**
97
- * Whether this request runs in production or sandbox mode. Branch your
98
- * handlers on it — for example, read and write a separate sandbox database
99
- * when `mode === 'sandbox'` — so sandbox traffic exercises the same code
100
- * against isolated data. Keeping the two apart is your handler's
101
- * responsibility, since your database holds the canonical rows.
102
- *
103
- * Defaults to `'production'` when omitted.
104
- */
105
- readonly mode?: Environment;
106
95
  }
107
96
 
108
97
  /**
@@ -1,7 +1,6 @@
1
1
  /** Canonical sync-log identity and position contracts shared by client/server. */
2
2
 
3
3
  import { z } from 'zod';
4
- import { environmentSchema } from '../environment.js';
5
4
 
6
5
  export const deltaPositionSchema = z.number().int().nonnegative();
7
6
  export type DeltaPosition = z.infer<typeof deltaPositionSchema>;
@@ -21,7 +20,7 @@ export type ReplicationLSN = z.infer<typeof replicationLsnSchema>;
21
20
  export const commitDispatchMarkerSchema = z.strictObject({
22
21
  kind: z.literal('sync_deltas'),
23
22
  organizationId: z.string().min(1),
24
- environment: environmentSchema,
23
+ branchId: z.string().min(1),
25
24
  firstSyncId: deltaPositionSchema,
26
25
  lastSyncId: deltaPositionSchema,
27
26
  }).superRefine((value, ctx) => {
@@ -63,18 +63,17 @@ export type ProvisionedKey = z.infer<typeof provisionedKeySchema>;
63
63
 
64
64
  /**
65
65
  * What the CLI device flow gets back once a browser approval is exchanged for
66
- * credentials: the sandbox key `ablo push` authors with, and the restricted
67
- * production key that only observes.
66
+ * a project-scoped control-plane management credential. Runtime branch
67
+ * credentials are minted separately by `ablo dev` / `ablo branch credential`.
68
68
  *
69
- * `project` is the project both keys are scoped to, resolved SERVER-SIDE from
69
+ * `project` is the project the management credential is scoped to, resolved SERVER-SIDE from
70
70
  * the requested slug — null means the organization's default. The server's
71
71
  * answer is authoritative because it is what resolved the slug to an id, so the
72
- * CLI stores keys under the project named here rather than the one it asked
72
+ * CLI stores the credential under the project named here rather than the one it asked
73
73
  * for.
74
74
  */
75
75
  export const provisionKeyResponseSchema = z.object({
76
- test: provisionedKeySchema,
77
- live: provisionedKeySchema.optional(),
76
+ management: provisionedKeySchema,
78
77
  organizationId: z.string().optional(),
79
78
  organizationSlug: z.string().optional(),
80
79
  project: z.object({ id: z.string(), slug: z.string() }).nullable().optional(),
package/src/wire/delta.ts CHANGED
@@ -66,6 +66,17 @@ export type SyncDeltaAction = z.infer<typeof syncDeltaActionSchema>;
66
66
  * serialized string (used by the group-change frames on `G` and `S` deltas), or
67
67
  * `null` on deletes. This is wider than the stored row's payload — which is only a
68
68
  * row or null — because the group-change frames encode their payload as a string.
69
+ *
70
+ * The record branch costs more than its contract suggests: it walks
71
+ * `Reflect.ownKeys` and rebuilds the payload into a fresh object on every parse,
72
+ * so client-side validation scales with a row's field count on a path that runs
73
+ * once per delta (2.7 microseconds at 23 fields, against 0.15 for a predicate).
74
+ * Replacing it was tried and reverted, because every faster spelling gives up
75
+ * something this contract owns: `z.custom` cannot be represented in JSON Schema
76
+ * and breaks the derived spec, and `z.unknown().refine` derives to an empty
77
+ * schema and infers `unknown`, which would widen {@link WireDeltaData}. A
78
+ * predicate must also match this schema's real acceptance, which is
79
+ * plain-object: `z.record` rejects `Date`, `Map`, and class instances.
69
80
  */
70
81
  export const wireDeltaDataSchema = z
71
82
  .union([z.record(z.string(), z.unknown()), z.string()])
@@ -1 +0,0 @@
1
- {"version":3,"file":"coordinatedTool.d.ts","sourceRoot":"","sources":["../../src/ai-sdk/coordinatedTool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AAGH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EACV,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACxF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAE/D,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB,CAAC,CAAC;IACvC;;;;;OAKG;IACH,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC1C,0CAA0C;IAC1C,GAAG,CAAC,EAAE,CAAC,CAAC;IACR,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB,CAAC,MAAM,EAAE,CAAC;IAC/C,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,sFAAsF;IACtF,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,iEAAiE;IACjE,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC9B;;;;;;OAMG;IACH,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACjD,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,kHAAkH;IAClH,KAAK,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,kGAAkG;IAClG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,IAAI,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACpD;AAID;;;;GAIG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,GAAG,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IACzD,qCAAqC;IACrC,QAAQ,CAAC,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC/D,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,CACJ,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EACxB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC1B,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;CACtD;AAED,wBAAgB,eAAe,CAC7B,MAAM,EACN,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3B,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,sBAAsB,CAAC,MAAM,EAAE,CAAC,CAAC,wDA4EvE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"coordinatedTool.js","sourceRoot":"","sources":["../../src/ai-sdk/coordinatedTool.ts"],"names":[],"mappings":"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"}