@abloatai/ablo 0.35.0 → 0.36.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 (215) hide show
  1. package/CHANGELOG.md +713 -629
  2. package/README.md +56 -519
  3. package/bin/ablo.cjs +39 -0
  4. package/dist/BaseSyncedStore.d.ts +24 -4
  5. package/dist/BaseSyncedStore.js +53 -37
  6. package/dist/Database.d.ts +8 -20
  7. package/dist/Database.js +61 -59
  8. package/dist/InstanceCache.d.ts +6 -2
  9. package/dist/InstanceCache.js +18 -16
  10. package/dist/Model.d.ts +17 -7
  11. package/dist/Model.js +17 -7
  12. package/dist/ModelRegistry.d.ts +4 -0
  13. package/dist/ModelRegistry.js +17 -15
  14. package/dist/NetworkMonitor.d.ts +3 -1
  15. package/dist/NetworkMonitor.js +7 -5
  16. package/dist/SyncClient.d.ts +5 -15
  17. package/dist/SyncClient.js +60 -57
  18. package/dist/client/Ablo.js +30 -19
  19. package/dist/client/createInternalComponents.d.ts +4 -0
  20. package/dist/client/createInternalComponents.js +8 -2
  21. package/dist/client/createModelProxy.d.ts +21 -1
  22. package/dist/client/createModelProxy.js +123 -57
  23. package/dist/client/humans.d.ts +30 -9
  24. package/dist/client/humans.js +45 -19
  25. package/dist/client/reactiveEngine.d.ts +16 -11
  26. package/dist/client/reactiveEngine.js +113 -335
  27. package/dist/client/storeCluster.d.ts +47 -0
  28. package/dist/client/storeCluster.js +118 -0
  29. package/dist/client/storeLifecycle.d.ts +61 -0
  30. package/dist/client/storeLifecycle.js +231 -0
  31. package/dist/context.d.ts +13 -0
  32. package/dist/context.js +23 -0
  33. package/dist/core/index.d.ts +1 -1
  34. package/dist/docs/catalog.js +6 -3
  35. package/dist/index.d.ts +4 -2
  36. package/dist/index.js +4 -2
  37. package/dist/query/client.d.ts +3 -0
  38. package/dist/query/client.js +6 -5
  39. package/dist/react/AbloProvider.d.ts +13 -1
  40. package/dist/react/AbloProvider.js +5 -2
  41. package/dist/react/context.d.ts +2 -2
  42. package/dist/react/createAbloReact.d.ts +56 -0
  43. package/dist/react/createAbloReact.js +51 -0
  44. package/dist/react/index.d.ts +1 -0
  45. package/dist/react/index.js +3 -0
  46. package/dist/react/useAblo.d.ts +9 -2
  47. package/dist/react/useAblo.js +25 -7
  48. package/dist/schema/coordination.js +5 -1
  49. package/dist/schema/index.d.ts +1 -0
  50. package/dist/schema/index.js +4 -0
  51. package/dist/schema/select.js +3 -0
  52. package/dist/schema/serialize.js +3 -0
  53. package/dist/source/adapter.d.ts +7 -5
  54. package/dist/source/adapter.js +7 -5
  55. package/dist/source/index.d.ts +1 -1
  56. package/dist/source/index.js +1 -1
  57. package/dist/{core/storeContract.d.ts → storeContract.d.ts} +5 -5
  58. package/dist/{core → stores}/DatabaseManager.d.ts +3 -1
  59. package/dist/{core → stores}/DatabaseManager.js +13 -12
  60. package/dist/{core → stores}/StoreManager.d.ts +5 -3
  61. package/dist/{core → stores}/StoreManager.js +24 -22
  62. package/dist/stores/SyncActionStore.d.ts +3 -1
  63. package/dist/stores/SyncActionStore.js +9 -7
  64. package/dist/sync/BootstrapFetcher.d.ts +4 -0
  65. package/dist/sync/BootstrapFetcher.js +28 -26
  66. package/dist/sync/OnDemandLoader.d.ts +3 -0
  67. package/dist/sync/OnDemandLoader.js +1 -0
  68. package/dist/sync/bootstrapApply.d.ts +3 -0
  69. package/dist/sync/bootstrapApply.js +2 -2
  70. package/dist/sync/deltaPipeline.d.ts +13 -12
  71. package/dist/sync/deltaPipeline.js +21 -4
  72. package/dist/sync/groupChange.d.ts +3 -0
  73. package/dist/sync/groupChange.js +16 -14
  74. package/dist/sync/participants.d.ts +19 -2
  75. package/dist/sync/participants.js +3 -1
  76. package/dist/sync/schemas.d.ts +2 -1
  77. package/dist/sync/schemas.js +3 -3
  78. package/dist/syncLog/contract.d.ts +20 -0
  79. package/dist/syncLog/contract.js +19 -0
  80. package/dist/syncLog/index.d.ts +1 -0
  81. package/dist/syncLog/index.js +1 -0
  82. package/dist/transaction/auth/capability.d.ts +35 -0
  83. package/dist/transaction/auth/capability.js +25 -0
  84. package/dist/transaction/coordination/awaitClaimGrant.d.ts +7 -0
  85. package/dist/transaction/coordination/awaitClaimGrant.js +12 -0
  86. package/dist/transaction/coordination/claimHeartbeatLoop.d.ts +34 -0
  87. package/dist/transaction/coordination/claimHeartbeatLoop.js +20 -0
  88. package/dist/transaction/coordination/index.d.ts +4 -4
  89. package/dist/transaction/coordination/index.js +4 -3
  90. package/dist/transaction/coordination/locator.d.ts +23 -2
  91. package/dist/transaction/coordination/locator.js +22 -2
  92. package/dist/transaction/coordination/schema.d.ts +125 -62
  93. package/dist/transaction/coordination/schema.js +228 -64
  94. package/dist/transaction/coordination/targetConflict.js +32 -28
  95. package/dist/transaction/errorCodes.d.ts +2 -2
  96. package/dist/transaction/errorCodes.js +13 -9
  97. package/dist/transaction/plugin.d.ts +95 -2
  98. package/dist/transaction/plugin.js +21 -2
  99. package/dist/transaction/resources/httpResources.d.ts +57 -2
  100. package/dist/transaction/resources/modelOperations.d.ts +148 -40
  101. package/dist/transaction/resources/where.d.ts +16 -0
  102. package/dist/transaction/resources/where.js +45 -0
  103. package/dist/transaction/schema/field.d.ts +12 -18
  104. package/dist/transaction/schema/fieldRef.d.ts +38 -0
  105. package/dist/transaction/schema/fieldRef.js +11 -0
  106. package/dist/transaction/schema/openapi.d.ts +16 -15
  107. package/dist/transaction/schema/openapi.js +186 -25
  108. package/dist/transaction/schema/relation.d.ts +7 -2
  109. package/dist/transaction/schema/schema.d.ts +27 -0
  110. package/dist/transaction/schema/schema.js +20 -0
  111. package/dist/transaction/transactions/settlement/commitEnvelope.d.ts +1 -1
  112. package/dist/transaction/transactions/settlement/pendingWrite.d.ts +1 -1
  113. package/dist/transaction/transport/httpClient.d.ts +9 -1
  114. package/dist/transaction/transport/httpClient.js +1 -0
  115. package/dist/transaction/transport/httpTransport.js +156 -44
  116. package/dist/transaction/transport/wsTransport.d.ts +2 -4
  117. package/dist/transaction/transport/wsTransport.js +16 -10
  118. package/dist/transaction/types/streams.d.ts +10 -0
  119. package/dist/transaction/utils/duration.d.ts +25 -0
  120. package/dist/transaction/utils/duration.js +32 -0
  121. package/dist/transaction/wire/accountResponses.d.ts +69 -0
  122. package/dist/transaction/wire/accountResponses.js +36 -1
  123. package/dist/transaction/wire/auth.d.ts +9 -2
  124. package/dist/transaction/wire/auth.js +7 -1
  125. package/dist/transaction/wire/claims.d.ts +164 -97
  126. package/dist/transaction/wire/claims.js +126 -28
  127. package/dist/transaction/wire/commit.d.ts +1 -1
  128. package/dist/transaction/wire/feedEvent.d.ts +27 -0
  129. package/dist/transaction/wire/feedEvent.js +27 -1
  130. package/dist/transaction/wire/frames.d.ts +2 -2
  131. package/dist/transaction/wire/inboundFrames.d.ts +12 -2
  132. package/dist/transaction/wire/index.d.ts +10 -6
  133. package/dist/transaction/wire/index.js +12 -3
  134. package/dist/transaction/wire/modelMutations.d.ts +31 -0
  135. package/dist/transaction/wire/modelMutations.js +52 -0
  136. package/dist/transaction/wire/modelShape.d.ts +78 -0
  137. package/dist/transaction/wire/modelShape.js +74 -0
  138. package/dist/transactions/mutations/MutationQueue.d.ts +6 -0
  139. package/dist/transactions/mutations/MutationQueue.js +55 -45
  140. package/dist/transactions/mutations/commitPayload.d.ts +3 -2
  141. package/dist/transactions/mutations/commitPayload.js +5 -5
  142. package/dist/transactions/mutations/deltaConfirmation.d.ts +4 -0
  143. package/dist/transactions/mutations/deltaConfirmation.js +10 -8
  144. package/dist/transactions/mutations/replayValidation.d.ts +2 -1
  145. package/dist/transactions/mutations/replayValidation.js +3 -2
  146. package/dist/{core → views}/QueryView.d.ts +1 -1
  147. package/dist/{core → views}/QueryView.js +1 -1
  148. package/dist/{core → views}/ViewRegistry.d.ts +1 -1
  149. package/dist/{core/queryUtils.d.ts → views/incrementalView.d.ts} +6 -6
  150. package/dist/{core/queryUtils.js → views/incrementalView.js} +6 -6
  151. package/docs/agents.md +1 -1
  152. package/docs/api-keys.md +6 -6
  153. package/docs/api.md +5 -43
  154. package/docs/audit.md +4 -3
  155. package/docs/cli.md +11 -11
  156. package/docs/client-behavior.md +4 -4
  157. package/docs/concurrency-convention.md +28 -42
  158. package/docs/coordination.md +235 -83
  159. package/docs/data-sources.md +4 -4
  160. package/docs/debugging.md +34 -12
  161. package/docs/deployment.md +8 -8
  162. package/docs/examples/scoped-agent.md +3 -3
  163. package/docs/groups.md +57 -3
  164. package/docs/guarantees.md +37 -10
  165. package/docs/how-it-works.md +29 -5
  166. package/docs/idempotency.md +6 -6
  167. package/docs/identity.md +22 -23
  168. package/docs/index.md +8 -8
  169. package/docs/integration-guide.md +14 -3
  170. package/docs/mcp.md +7 -7
  171. package/docs/migration.md +34 -15
  172. package/docs/projects.md +1 -1
  173. package/docs/react.md +19 -8
  174. package/docs/sessions.md +1 -1
  175. package/docs/webhooks.md +9 -9
  176. package/llms.txt +4 -4
  177. package/package.json +13 -20
  178. package/dist/cli.cjs +0 -288600
  179. package/dist/testing/fixtures/bootstrap.d.ts +0 -49
  180. package/dist/testing/fixtures/bootstrap.js +0 -59
  181. package/dist/testing/fixtures/deltas.d.ts +0 -83
  182. package/dist/testing/fixtures/deltas.js +0 -136
  183. package/dist/testing/fixtures/httpResponses.d.ts +0 -70
  184. package/dist/testing/fixtures/httpResponses.js +0 -90
  185. package/dist/testing/fixtures/models.d.ts +0 -83
  186. package/dist/testing/fixtures/models.js +0 -272
  187. package/dist/testing/helpers/reactWrapper.d.ts +0 -69
  188. package/dist/testing/helpers/reactWrapper.js +0 -67
  189. package/dist/testing/helpers/syncEngineHarness.d.ts +0 -54
  190. package/dist/testing/helpers/syncEngineHarness.js +0 -73
  191. package/dist/testing/helpers/wait.d.ts +0 -30
  192. package/dist/testing/helpers/wait.js +0 -49
  193. package/dist/testing/index.d.ts +0 -23
  194. package/dist/testing/index.js +0 -33
  195. package/dist/testing/mocks/FakeDatabase.d.ts +0 -18
  196. package/dist/testing/mocks/FakeDatabase.js +0 -10
  197. package/dist/testing/mocks/MockMutationExecutor.d.ts +0 -87
  198. package/dist/testing/mocks/MockMutationExecutor.js +0 -186
  199. package/dist/testing/mocks/MockNetworkMonitor.d.ts +0 -20
  200. package/dist/testing/mocks/MockNetworkMonitor.js +0 -46
  201. package/dist/testing/mocks/MockSyncContext.d.ts +0 -51
  202. package/dist/testing/mocks/MockSyncContext.js +0 -72
  203. package/dist/testing/mocks/MockSyncStore.d.ts +0 -88
  204. package/dist/testing/mocks/MockSyncStore.js +0 -171
  205. package/dist/testing/mocks/MockWebSocket.d.ts +0 -71
  206. package/dist/testing/mocks/MockWebSocket.js +0 -118
  207. package/docs/interaction-model.md +0 -99
  208. /package/dist/{core → query}/QueryProcessor.d.ts +0 -0
  209. /package/dist/{core → query}/QueryProcessor.js +0 -0
  210. /package/dist/{core/storeContract.js → storeContract.js} +0 -0
  211. /package/dist/{core → stores}/openIDBWithTimeout.d.ts +0 -0
  212. /package/dist/{core → stores}/openIDBWithTimeout.js +0 -0
  213. /package/dist/{source → transaction}/footprint.d.ts +0 -0
  214. /package/dist/{source → transaction}/footprint.js +0 -0
  215. /package/dist/{core → views}/ViewRegistry.js +0 -0
@@ -13,7 +13,7 @@
13
13
  * sequence; {@link FeedCursor} is what carries both positions.
14
14
  */
15
15
  import { z } from 'zod';
16
- import { logEventSchema } from './accountResponses.js';
16
+ import { logEventSchema, logOpSchema } from './accountResponses.js';
17
17
  import { claimEventSchema } from './claimEvent.js';
18
18
  import { listEnvelopeSchema } from './listEnvelope.js';
19
19
  /**
@@ -27,6 +27,32 @@ export const feedEventSchema = z.discriminatedUnion('object', [
27
27
  ]);
28
28
  /** `GET /v1/logs` — the canonical list envelope over the feed. */
29
29
  export const logListResponseSchema = listEnvelopeSchema(feedEventSchema);
30
+ /**
31
+ * The query string on `GET /v1/logs`.
32
+ *
33
+ * Values arrive as strings, so this describes the wire spelling rather than the
34
+ * parsed result — the same reason {@link listQuerySchema} does.
35
+ *
36
+ * Scope is NOT here and never will be: the plane, the organization and the sync
37
+ * groups all come off the credential. A caller cannot widen what it sees by
38
+ * asking, which is what makes this feed safe to hand an agent.
39
+ */
40
+ export const logQuerySchema = z.object({
41
+ /**
42
+ * The `next_cursor` from the previous page, copied back unchanged. Omit it to
43
+ * start from the most recent entries — this is a tail, so the first page is
44
+ * the end of the log and `after` walks forward from there.
45
+ */
46
+ after: z.string().optional(),
47
+ /** Entries per page. Clamped server-side; the default is a short tail. */
48
+ limit: z.string().optional(),
49
+ /** Only this model's entries. */
50
+ model: z.string().optional(),
51
+ /** Only this kind of change. */
52
+ op: logOpSchema.optional(),
53
+ /** Only entries at or after this ISO 8601 timestamp. */
54
+ since: z.string().optional(),
55
+ });
30
56
  /**
31
57
  * The claim arm has no producer yet: claim transitions are broadcast today and
32
58
  * recorded nowhere, so there is no sequence to read `seq` from. Until that log
@@ -122,8 +122,8 @@ export declare const commitPayloadSchema: z.ZodObject<{
122
122
  }>>;
123
123
  }, z.core.$strip>]>>>>;
124
124
  track: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
125
- model: z.ZodString;
126
125
  id: z.ZodString;
126
+ model: z.ZodString;
127
127
  readAt: z.ZodOptional<z.ZodNumber>;
128
128
  }, z.core.$strip>, z.ZodObject<{
129
129
  group: z.ZodString;
@@ -176,8 +176,8 @@ export declare const commitMessageSchema: z.ZodObject<{
176
176
  }>>;
177
177
  }, z.core.$strip>]>>>>;
178
178
  track: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
179
- model: z.ZodString;
180
179
  id: z.ZodString;
180
+ model: z.ZodString;
181
181
  readAt: z.ZodOptional<z.ZodNumber>;
182
182
  }, z.core.$strip>, z.ZodObject<{
183
183
  group: z.ZodString;
@@ -298,7 +298,12 @@ export declare const WS_INBOUND_FRAMES: {
298
298
  readonly validation: "schema";
299
299
  readonly payload: z.ZodObject<{
300
300
  claimId: z.ZodString;
301
- reason: z.ZodString;
301
+ reason: z.ZodPreprocess<z.ZodOptional<z.ZodEnum<{
302
+ conflict: "conflict";
303
+ expired: "expired";
304
+ coordination_unavailable: "coordination_unavailable";
305
+ preempted: "preempted";
306
+ }>>>;
302
307
  target: z.ZodOptional<z.ZodObject<{
303
308
  entityType: z.ZodString;
304
309
  entityId: z.ZodString;
@@ -423,7 +428,12 @@ export declare const WS_INBOUND_FRAMES: {
423
428
  }, z.core.$strip>>;
424
429
  policyReason: z.ZodOptional<z.ZodString>;
425
430
  position: z.ZodNumber;
426
- reason: z.ZodOptional<z.ZodString>;
431
+ reason: z.ZodOptional<z.ZodPreprocess<z.ZodOptional<z.ZodEnum<{
432
+ conflict: "conflict";
433
+ expired: "expired";
434
+ coordination_unavailable: "coordination_unavailable";
435
+ preempted: "preempted";
436
+ }>>>>;
427
437
  }, z.core.$strip>;
428
438
  };
429
439
  readonly claim_granted: {
@@ -21,8 +21,8 @@ export { listEnvelopeSchema, listEnvelope } from './listEnvelope.js';
21
21
  export type { ListEnvelope } from './listEnvelope.js';
22
22
  export { claimEventSchema } from './claimEvent.js';
23
23
  export type { ClaimEvent } from './claimEvent.js';
24
- export { feedEventSchema, logListResponseSchema } from './feedEvent.js';
25
- export type { FeedEvent, LogListResponse } from './feedEvent.js';
24
+ export { feedEventSchema, logListResponseSchema, logQuerySchema, } from './feedEvent.js';
25
+ export type { FeedEvent, LogListResponse, LogQuery } from './feedEvent.js';
26
26
  export { feedCursorSchema, parseFeedCursor, formatFeedCursor, feedCursorAdvanced, FEED_CURSOR_START, FEED_CURSOR_FORMAT, FEED_CURSOR_EXAMPLE, } from './feedCursor.js';
27
27
  export type { FeedCursor } from './feedCursor.js';
28
28
  export { bootstrapReasonSchema } from './bootstrapReason.js';
@@ -38,13 +38,17 @@ export type { ParticipantKind, ConfirmationState, SyncDeltaAction, WireDeltaData
38
38
  export { AbloError, AbloAuthenticationError, AbloPermissionError, AbloValidationError, AbloRateLimitError, AbloIdempotencyError, AbloConnectionError, AbloNotFoundError, AbloServerError, AbloStaleContextError, AbloContentionError, AbloClaimedError, CapabilityError, AbloSessionError, SyncSessionError, docUrlForCode, translateHttpError, errorFromWire, toAbloError, ERROR_CONTRACT_VERSION, errorCodeSpec, } from '../errors.js';
39
39
  export type { ErrorCode, WireErrorCode, RequiredCapability } from '../errors.js';
40
40
  export { PING_INTERVAL_MS, LEASE_TTL_MS, WS_BEARER_SUBPROTOCOL_PREFIX, WS_SYNC_SUBPROTOCOL, } from './protocol.js';
41
- export { claimTargetSchema, claimRequestSchema, claimHeartbeatRequestSchema, listQuerySchema, claimListQuerySchema, claimStateSchema, claimAcquiredResponseSchema, claimQueuedResponseSchema, claimAcquireResponseSchema, claimHeartbeatReplySchema, claimHeartbeatBatchReplySchema, claimListResponseSchema, } from './claims.js';
42
- export type { ClaimTargetBody, ClaimRequest, ClaimHeartbeatRequest, ListQuery, ClaimListQuery, ClaimState, ClaimAcquiredResponse, ClaimQueuedResponse, ClaimAcquireResponse, ClaimHeartbeatReply, ClaimHeartbeatBatchReply, ClaimListResponse, } from './claims.js';
41
+ export { DEFAULT_CLAIM_TTL_MS, claimTtlSchema, claimTtlMs, claimTargetSchema, claimRequestSchema, claimHeartbeatRequestSchema, listQuerySchema, claimListQuerySchema, claimStateSchema, claimAcquiredResponseSchema, claimQueuedResponseSchema, claimAcquireResponseSchema, claimHeartbeatReplySchema, claimHeartbeatBatchReplySchema, claimListResponseSchema, claimReorderRequestSchema, claimReorderReplySchema, claimReleaseReplySchema, } from './claims.js';
42
+ export type { ClaimTargetBody, ClaimRequest, ClaimHeartbeatRequest, ListQuery, ClaimListQuery, ClaimState, ClaimAcquiredResponse, ClaimQueuedResponse, ClaimAcquireResponse, ClaimHeartbeatReply, ClaimHeartbeatBatchReply, ClaimListResponse, ClaimReorderRequest, ClaimReorderReply, ClaimReleaseReply, } from './claims.js';
43
43
  export { modelReadResponseSchema, modelListResponseSchema, } from './modelResponses.js';
44
44
  export type { ModelReadResponse, ModelListResponse } from './modelResponses.js';
45
+ export { fieldTypeSchema, fieldMetaSchema, relationTypeSchema, relationMetaSchema, } from './modelShape.js';
46
+ export type { FieldType, FieldMeta, RelationType, RelationMeta, } from './modelShape.js';
47
+ export { modelMutationRequestSchema } from './modelMutations.js';
48
+ export type { ModelMutationRequest } from './modelMutations.js';
45
49
  export { projectResponseSchema, projectListResponseSchema, provisionedKeySchema, provisionKeyResponseSchema, conflictAxisWireSchema, schemaModelResponseSchema, schemaReadResponseSchema, logOpSchema, LOG_OP_BY_ACTION, logEventSchema, usageBucketSchema, usageReportResponseSchema, controlKeySchema, controlKeyListResponseSchema, keyMintedResponseSchema, keyRevokedResponseSchema, } from './accountResponses.js';
46
50
  export type { ProjectResponse, ProjectListResponse, ProvisionedKey, ProvisionKeyResponse, SchemaModelResponse, SchemaReadResponse, LogOp, LogEvent, UsageBucket, UsageReportResponse, ControlKey, ControlKeyListResponse, KeyMintedResponse, KeyRevokedResponse, } from './accountResponses.js';
47
51
  export { WS_INBOUND_FRAMES, wsInboundEnvelopeSchema, isKnownInboundFrame, isSchemaValidatedFrame, } from './inboundFrames.js';
48
52
  export type { InboundFrameContract, InboundFrameType, InboundFramePayload, SchemaValidatedFrameType, WsInboundEnvelope, } from './inboundFrames.js';
49
- export { ephemeralKeyUserSchema, ephemeralKeyRequestSchema, capabilityRequestSchema, } from './auth.js';
50
- export type { EphemeralKeyUser, EphemeralKeyRequest, CapabilityRequest, } from './auth.js';
53
+ export { ephemeralKeyUserSchema, ephemeralKeyRequestSchema, capabilityRequestSchema, capabilityMintResponseSchema, } from './auth.js';
54
+ export type { EphemeralKeyUser, EphemeralKeyRequest, CapabilityRequest, CapabilityMintResponse, } from './auth.js';
@@ -20,7 +20,7 @@ export { listEnvelopeSchema, listEnvelope } from './listEnvelope.js';
20
20
  // The `GET /v1/logs` feed — the two arms, their envelope, and the cursor that
21
21
  // carries a position in each.
22
22
  export { claimEventSchema } from './claimEvent.js';
23
- export { feedEventSchema, logListResponseSchema } from './feedEvent.js';
23
+ export { feedEventSchema, logListResponseSchema, logQuerySchema, } from './feedEvent.js';
24
24
  export { feedCursorSchema, parseFeedCursor, formatFeedCursor, feedCursorAdvanced, FEED_CURSOR_START, FEED_CURSOR_FORMAT, FEED_CURSOR_EXAMPLE, } from './feedCursor.js';
25
25
  export { bootstrapReasonSchema } from './bootstrapReason.js';
26
26
  // The write-path frame contract: the message shapes shared by the client and
@@ -59,10 +59,19 @@ export { PING_INTERVAL_MS, LEASE_TTL_MS, WS_BEARER_SUBPROTOCOL_PREFIX, WS_SYNC_S
59
59
  // the commit body for the same reason: the server answers in these shapes, the
60
60
  // client reads them back through the same schemas, and the OpenAPI reference
61
61
  // derives from them rather than describing them from memory.
62
- export { claimTargetSchema, claimRequestSchema, claimHeartbeatRequestSchema, listQuerySchema, claimListQuerySchema, claimStateSchema, claimAcquiredResponseSchema, claimQueuedResponseSchema, claimAcquireResponseSchema, claimHeartbeatReplySchema, claimHeartbeatBatchReplySchema, claimListResponseSchema, } from './claims.js';
62
+ export {
63
+ // The lease grammar and its one reading. The server parses TTLs with
64
+ // `claimTtlMs` rather than carrying a second parser — which is how a bare
65
+ // number came to mean seconds on one side and milliseconds on the other.
66
+ DEFAULT_CLAIM_TTL_MS, claimTtlSchema, claimTtlMs, claimTargetSchema, claimRequestSchema, claimHeartbeatRequestSchema, listQuerySchema, claimListQuerySchema, claimStateSchema, claimAcquiredResponseSchema, claimQueuedResponseSchema, claimAcquireResponseSchema, claimHeartbeatReplySchema, claimHeartbeatBatchReplySchema, claimListResponseSchema, claimReorderRequestSchema, claimReorderReplySchema, claimReleaseReplySchema, } from './claims.js';
63
67
  // The model read routes' responses — the envelope around a row, which is
64
68
  // protocol, around `data`, which is the caller's schema.
65
69
  export { modelReadResponseSchema, modelListResponseSchema, } from './modelResponses.js';
70
+ // What a model is made of — the artifact's own field and relation shapes, which
71
+ // the schema read reports and every other layer derives its types from.
72
+ export { fieldTypeSchema, fieldMetaSchema, relationTypeSchema, relationMetaSchema, } from './modelShape.js';
73
+ // The model write routes' body — the record in `data`, the guards beside it.
74
+ export { modelMutationRequestSchema } from './modelMutations.js';
66
75
  // The account routes' responses — projects, the deployed schema, the commit
67
76
  // log, usage. What the server, the CLI, and the MCP server agree on.
68
77
  export { projectResponseSchema, projectListResponseSchema, provisionedKeySchema, provisionKeyResponseSchema, conflictAxisWireSchema, schemaModelResponseSchema, schemaReadResponseSchema, logOpSchema, LOG_OP_BY_ACTION, logEventSchema, usageBucketSchema, usageReportResponseSchema, controlKeySchema, controlKeyListResponseSchema, keyMintedResponseSchema, keyRevokedResponseSchema, } from './accountResponses.js';
@@ -71,4 +80,4 @@ export { projectResponseSchema, projectListResponseSchema, provisionedKeySchema,
71
80
  export { WS_INBOUND_FRAMES, wsInboundEnvelopeSchema, isKnownInboundFrame, isSchemaValidatedFrame, } from './inboundFrames.js';
72
81
  // Credential minting — the first call any caller makes, so the contract cannot
73
82
  // omit it. Response side lives in `auth/schemas.ts`.
74
- export { ephemeralKeyUserSchema, ephemeralKeyRequestSchema, capabilityRequestSchema, } from './auth.js';
83
+ export { ephemeralKeyUserSchema, ephemeralKeyRequestSchema, capabilityRequestSchema, capabilityMintResponseSchema, } from './auth.js';
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The body of a model-scoped write — `POST /v1/models/{model}`,
3
+ * `PATCH /v1/models/{model}/{id}`, `DELETE /v1/models/{model}/{id}`.
4
+ *
5
+ * The record travels in `data`, and everything else is a control field beside
6
+ * it rather than inside it. That separation is the point: a row with a column
7
+ * called `claim` or `readAt` is not a reason for a write to stop being guarded,
8
+ * and a flat body would make the two indistinguishable.
9
+ *
10
+ * This lived in `routes/commit.ts` and the published reference described these
11
+ * routes as taking a bare row — so a client built from the document sent the
12
+ * record flat, and every field of it went missing at once. The failure surfaced
13
+ * as `not_null_violation` from the column, which reads as a schema problem
14
+ * rather than an envelope one. One definition, derived, is what stops that:
15
+ * the server validates against this and the reference is generated from it.
16
+ */
17
+ import { z } from 'zod';
18
+ export declare const modelMutationRequestSchema: z.ZodObject<{
19
+ data: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
20
+ id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
21
+ claim: z.ZodOptional<z.ZodNullable<z.ZodString>>;
22
+ onStale: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
23
+ reject: "reject";
24
+ overwrite: "overwrite";
25
+ notify: "notify";
26
+ }>>>;
27
+ readAt: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
28
+ fenceToken: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
29
+ idempotencyKey: z.ZodOptional<z.ZodString>;
30
+ }, z.core.$strip>;
31
+ export type ModelMutationRequest = z.infer<typeof modelMutationRequestSchema>;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * The body of a model-scoped write — `POST /v1/models/{model}`,
3
+ * `PATCH /v1/models/{model}/{id}`, `DELETE /v1/models/{model}/{id}`.
4
+ *
5
+ * The record travels in `data`, and everything else is a control field beside
6
+ * it rather than inside it. That separation is the point: a row with a column
7
+ * called `claim` or `readAt` is not a reason for a write to stop being guarded,
8
+ * and a flat body would make the two indistinguishable.
9
+ *
10
+ * This lived in `routes/commit.ts` and the published reference described these
11
+ * routes as taking a bare row — so a client built from the document sent the
12
+ * record flat, and every field of it went missing at once. The failure surfaced
13
+ * as `not_null_violation` from the column, which reads as a schema problem
14
+ * rather than an envelope one. One definition, derived, is what stops that:
15
+ * the server validates against this and the reference is generated from it.
16
+ */
17
+ import { z } from 'zod';
18
+ import { onStaleModeSchema } from '../coordination/schema.js';
19
+ export const modelMutationRequestSchema = z.object({
20
+ /** The record. Its shape is your schema's; everything around it is protocol. */
21
+ data: z.record(z.string(), z.unknown()).nullish(),
22
+ /**
23
+ * The row id.
24
+ *
25
+ * On `POST` this is where it comes from, and it is **yours to choose** —
26
+ * Ablo mints none. Derive it as UUID v5 of `"<model>:<Idempotency-Key>"` in
27
+ * namespace `aa4ba6d4-bf0b-5b38-9c45-116f79a6e548` and a retry after a lost
28
+ * response inserts the same id, colliding with the original rather than
29
+ * writing a second row — with no server state to consult, so it holds across
30
+ * instances and outlives any idempotency record.
31
+ *
32
+ * On `PATCH` and `DELETE` the path names the row and this is redundant.
33
+ */
34
+ id: z.string().nullish(),
35
+ /** The claim this write is made under — a claim id you hold. */
36
+ claim: z.string().nullish(),
37
+ /** What to do when the row moved since `readAt`. Defaults to rejecting. */
38
+ onStale: onStaleModeSchema.nullish(),
39
+ /**
40
+ * The watermark this write's decision was made against — the `stamp` from
41
+ * the read. Ablo rejects the write if the row moved in between, which is
42
+ * what makes read → decide → write safe without a lock across the deciding.
43
+ */
44
+ readAt: z.number().nullish(),
45
+ /**
46
+ * The fencing token from the claim's grant. Closes the window `readAt` alone
47
+ * cannot: a lease that lapsed and whose successor came and went.
48
+ */
49
+ fenceToken: z.number().nullish(),
50
+ /** @compat HTTP idempotency belongs in the `Idempotency-Key` header. */
51
+ idempotencyKey: z.string().optional(),
52
+ });
@@ -0,0 +1,78 @@
1
+ /**
2
+ * What a model is made of — its fields and its edges.
3
+ *
4
+ * These shapes travel twice: they are what `ablo push` serializes into the
5
+ * schema artifact, and what `GET /api/schema` reports back about the artifact
6
+ * that is deployed. Two crossings, one definition, and the definition lives
7
+ * here because `wire/` is the leaf every other layer may depend on.
8
+ *
9
+ * They were TypeScript interfaces, so the schema-read route could not send them
10
+ * without hand-writing a second copy of the record it was refusing to send — the
11
+ * shadow type wearing the fix's clothes. Declared as Zod and derived back into
12
+ * TypeScript, there is nowhere for a second copy to live.
13
+ *
14
+ * **Vocabulary ownership.** `type` is a CLOSED enum: the engine owns the set of
15
+ * types it can store and serialize, so a value outside it is a bug, not an
16
+ * extension. `enumValues` is an OPEN list: the values belong to the application
17
+ * that declared them, and the protocol never interprets one.
18
+ */
19
+ import { z } from 'zod';
20
+ /**
21
+ * The engine's type vocabulary — closed, and owned by the engine.
22
+ *
23
+ * Each member maps to storage and serialization behaviour, so this is the whole
24
+ * set by construction. A schema's own richer types (a `z.email()`, a branded id)
25
+ * narrow one of these; they do not add a member.
26
+ */
27
+ export declare const fieldTypeSchema: z.ZodEnum<{
28
+ string: "string";
29
+ number: "number";
30
+ boolean: "boolean";
31
+ date: "date";
32
+ enum: "enum";
33
+ json: "json";
34
+ }>;
35
+ export type FieldType = z.infer<typeof fieldTypeSchema>;
36
+ /** One field of a model, as the schema artifact records it. */
37
+ export declare const fieldMetaSchema: z.ZodObject<{
38
+ type: z.ZodEnum<{
39
+ string: "string";
40
+ number: "number";
41
+ boolean: "boolean";
42
+ date: "date";
43
+ enum: "enum";
44
+ json: "json";
45
+ }>;
46
+ isOptional: z.ZodBoolean;
47
+ isIndexed: z.ZodBoolean;
48
+ column: z.ZodOptional<z.ZodString>;
49
+ enumValues: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
50
+ }, z.core.$strip>;
51
+ export type FieldMeta = z.infer<typeof fieldMetaSchema>;
52
+ /**
53
+ * How one model points at another. Closed, like {@link fieldTypeSchema}: the
54
+ * engine resolves exactly these three when it plans a read.
55
+ */
56
+ export declare const relationTypeSchema: z.ZodEnum<{
57
+ belongsTo: "belongsTo";
58
+ hasMany: "hasMany";
59
+ hasOne: "hasOne";
60
+ }>;
61
+ export type RelationType = z.infer<typeof relationTypeSchema>;
62
+ /**
63
+ * One edge of a model — what a caller may expand, and what it expands into.
64
+ *
65
+ * Reported alongside the fields because half the answer is not an answer: an
66
+ * agent asking what a model looks like wants its shape AND its edges, and
67
+ * shipping only the scalars invites the second question immediately.
68
+ */
69
+ export declare const relationMetaSchema: z.ZodObject<{
70
+ type: z.ZodEnum<{
71
+ belongsTo: "belongsTo";
72
+ hasMany: "hasMany";
73
+ hasOne: "hasOne";
74
+ }>;
75
+ target: z.ZodString;
76
+ foreignKey: z.ZodString;
77
+ }, z.core.$strip>;
78
+ export type RelationMeta = z.infer<typeof relationMetaSchema>;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * What a model is made of — its fields and its edges.
3
+ *
4
+ * These shapes travel twice: they are what `ablo push` serializes into the
5
+ * schema artifact, and what `GET /api/schema` reports back about the artifact
6
+ * that is deployed. Two crossings, one definition, and the definition lives
7
+ * here because `wire/` is the leaf every other layer may depend on.
8
+ *
9
+ * They were TypeScript interfaces, so the schema-read route could not send them
10
+ * without hand-writing a second copy of the record it was refusing to send — the
11
+ * shadow type wearing the fix's clothes. Declared as Zod and derived back into
12
+ * TypeScript, there is nowhere for a second copy to live.
13
+ *
14
+ * **Vocabulary ownership.** `type` is a CLOSED enum: the engine owns the set of
15
+ * types it can store and serialize, so a value outside it is a bug, not an
16
+ * extension. `enumValues` is an OPEN list: the values belong to the application
17
+ * that declared them, and the protocol never interprets one.
18
+ */
19
+ import { z } from 'zod';
20
+ /**
21
+ * The engine's type vocabulary — closed, and owned by the engine.
22
+ *
23
+ * Each member maps to storage and serialization behaviour, so this is the whole
24
+ * set by construction. A schema's own richer types (a `z.email()`, a branded id)
25
+ * narrow one of these; they do not add a member.
26
+ */
27
+ export const fieldTypeSchema = z.enum([
28
+ 'string',
29
+ 'number',
30
+ 'boolean',
31
+ 'date',
32
+ 'enum',
33
+ 'json',
34
+ ]);
35
+ /** One field of a model, as the schema artifact records it. */
36
+ export const fieldMetaSchema = z.object({
37
+ /** Sync-engine type tag, which maps to storage and serialization hints. */
38
+ type: fieldTypeSchema,
39
+ /** Whether the field was marked optional via `.optional()` or `.nullable()`. */
40
+ isOptional: z.boolean(),
41
+ /** Whether the field was marked indexed via `.indexed()`. */
42
+ isIndexed: z.boolean(),
43
+ /**
44
+ * Physical database column name override. When absent, SQL layers derive the
45
+ * column from the field name using the active casing convention.
46
+ */
47
+ column: z.string().optional(),
48
+ /**
49
+ * For enums: the allowed values.
50
+ *
51
+ * The application's vocabulary, carried verbatim — an open list, because the
52
+ * protocol has no opinion about what a caller's statuses are called.
53
+ */
54
+ enumValues: z.array(z.string()).readonly().optional(),
55
+ });
56
+ /**
57
+ * How one model points at another. Closed, like {@link fieldTypeSchema}: the
58
+ * engine resolves exactly these three when it plans a read.
59
+ */
60
+ export const relationTypeSchema = z.enum(['belongsTo', 'hasMany', 'hasOne']);
61
+ /**
62
+ * One edge of a model — what a caller may expand, and what it expands into.
63
+ *
64
+ * Reported alongside the fields because half the answer is not an answer: an
65
+ * agent asking what a model looks like wants its shape AND its edges, and
66
+ * shipping only the scalars invites the second question immediately.
67
+ */
68
+ export const relationMetaSchema = z.object({
69
+ type: relationTypeSchema,
70
+ /** The schema key of the model on the other end. */
71
+ target: z.string(),
72
+ /** The field on the owning side that carries the link. */
73
+ foreignKey: z.string(),
74
+ });
@@ -14,6 +14,7 @@
14
14
  import { EventEmitter } from 'events';
15
15
  import type { Database } from '../../Database.js';
16
16
  import { Model } from '../../Model.js';
17
+ import type { RuntimeContext } from '../../RuntimeContext.js';
17
18
  import { LogPosition } from '../../transaction/logPosition.js';
18
19
  import type { WriteOptions } from '../../interfaces/index.js';
19
20
  import type { OnStaleMode, StaleNotification, ReadDependency, TrackDependency } from '../../transaction/coordination/schema.js';
@@ -74,6 +75,8 @@ interface ConflictResolution {
74
75
  interface MutationQueueConfig {
75
76
  /** Shared client position (see logPosition.ts). One per client. */
76
77
  position?: LogPosition;
78
+ /** The owning client's runtime. Defaults to the module-global bridge. */
79
+ runtime?: RuntimeContext;
77
80
  maxBatchSize: number;
78
81
  batchDelay: number;
79
82
  maxRetries: number;
@@ -124,6 +127,7 @@ export declare class MutationQueue extends EventEmitter {
124
127
  private lastPermanentErrorSig?;
125
128
  private _mutationExecutor;
126
129
  private get mutationExecutor();
130
+ private readonly runtime;
127
131
  private executionQueue;
128
132
  private isProcessing;
129
133
  private processTimer?;
@@ -561,6 +565,8 @@ export declare class MutationQueue extends EventEmitter {
561
565
  config: {
562
566
  /** Shared client position (see logPosition.ts). One per client. */
563
567
  position?: LogPosition;
568
+ /** The owning client's runtime. Defaults to the module-global bridge. */
569
+ runtime?: RuntimeContext;
564
570
  maxBatchSize: number;
565
571
  batchDelay: number;
566
572
  maxRetries: number;