@abloatai/ablo 0.24.0 → 0.26.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 (246) hide show
  1. package/AGENTS.md +5 -3
  2. package/CHANGELOG.md +33 -0
  3. package/README.md +45 -36
  4. package/dist/BaseSyncedStore.d.ts +72 -195
  5. package/dist/BaseSyncedStore.js +240 -625
  6. package/dist/Database.d.ts +8 -9
  7. package/dist/Database.js +9 -14
  8. package/dist/LazyReferenceCollection.js +5 -0
  9. package/dist/Model.js +6 -8
  10. package/dist/ModelRegistry.d.ts +25 -6
  11. package/dist/ModelRegistry.js +12 -6
  12. package/dist/NetworkMonitor.js +1 -1
  13. package/dist/ObjectPool.js +9 -3
  14. package/dist/SyncClient.d.ts +15 -5
  15. package/dist/SyncClient.js +152 -66
  16. package/dist/SyncEngineContext.d.ts +1 -3
  17. package/dist/SyncEngineContext.js +1 -2
  18. package/dist/agent/Agent.d.ts +21 -8
  19. package/dist/agent/Agent.js +26 -13
  20. package/dist/ai-sdk/coordination-context.js +9 -3
  21. package/dist/ai-sdk/wrap.d.ts +1 -1
  22. package/dist/ai-sdk/wrap.js +1 -1
  23. package/dist/auth/credentialPolicy.d.ts +10 -2
  24. package/dist/auth/credentialSource.d.ts +1 -13
  25. package/dist/auth/credentialSource.js +6 -13
  26. package/dist/auth/index.js +3 -3
  27. package/dist/cli.cjs +583 -287
  28. package/dist/client/Ablo.d.ts +35 -764
  29. package/dist/client/Ablo.js +64 -688
  30. package/dist/client/ApiClient.d.ts +14 -1
  31. package/dist/client/ApiClient.js +63 -9
  32. package/dist/client/auth.d.ts +8 -17
  33. package/dist/client/auth.js +42 -6
  34. package/dist/client/consoleLogger.d.ts +36 -0
  35. package/dist/client/consoleLogger.js +45 -0
  36. package/dist/client/createInternalComponents.js +1 -1
  37. package/dist/client/createModelProxy.js +10 -6
  38. package/dist/client/credentialEndpoint.d.ts +63 -0
  39. package/dist/client/credentialEndpoint.js +87 -0
  40. package/dist/client/hostedEndpoints.d.ts +24 -0
  41. package/dist/client/hostedEndpoints.js +24 -0
  42. package/dist/client/httpClient.d.ts +1 -1
  43. package/dist/client/identity.js +2 -1
  44. package/dist/client/modelRegistration.d.ts +14 -0
  45. package/dist/client/modelRegistration.js +321 -0
  46. package/dist/client/options.d.ts +396 -0
  47. package/dist/client/options.js +10 -0
  48. package/dist/client/resourceTypes.d.ts +344 -0
  49. package/dist/client/resourceTypes.js +13 -0
  50. package/dist/client/schemaConfig.d.ts +56 -0
  51. package/dist/client/schemaConfig.js +188 -0
  52. package/dist/client/sessionMint.d.ts +1 -1
  53. package/dist/client/validateAbloOptions.js +1 -1
  54. package/dist/client/wsMutationExecutor.d.ts +33 -0
  55. package/dist/client/wsMutationExecutor.js +77 -0
  56. package/dist/context.js +0 -3
  57. package/dist/coordination/index.d.ts +8 -1
  58. package/dist/coordination/index.js +24 -1
  59. package/dist/coordination/trace.d.ts +0 -1
  60. package/dist/coordination/trace.js +0 -1
  61. package/dist/core/DatabaseManager.d.ts +0 -1
  62. package/dist/core/DatabaseManager.js +26 -24
  63. package/dist/core/QueryProcessor.js +7 -8
  64. package/dist/core/QueryView.d.ts +14 -2
  65. package/dist/core/QueryView.js +4 -5
  66. package/dist/core/StoreManager.d.ts +2 -2
  67. package/dist/core/StoreManager.js +5 -1
  68. package/dist/core/index.d.ts +1 -1
  69. package/dist/core/openIDBWithTimeout.js +15 -11
  70. package/dist/core/query-utils.js +1 -1
  71. package/dist/core/storeContract.d.ts +143 -0
  72. package/dist/core/storeContract.js +16 -0
  73. package/dist/errorCodes.d.ts +11 -2
  74. package/dist/errorCodes.js +155 -137
  75. package/dist/errors.d.ts +18 -7
  76. package/dist/errors.js +14 -1
  77. package/dist/index.js +5 -0
  78. package/dist/interfaces/index.d.ts +6 -20
  79. package/dist/keys/index.js +18 -9
  80. package/dist/mutators/UndoManager.js +6 -1
  81. package/dist/mutators/defineMutators.d.ts +1 -3
  82. package/dist/policy/types.d.ts +1 -1
  83. package/dist/query/client.d.ts +11 -0
  84. package/dist/query/client.js +81 -52
  85. package/dist/react/AbloProvider.d.ts +6 -10
  86. package/dist/react/AbloProvider.js +22 -15
  87. package/dist/react/context.d.ts +2 -118
  88. package/dist/react/useAblo.js +1 -1
  89. package/dist/react/useErrorListener.js +1 -1
  90. package/dist/react/useMutationFailureListener.js +1 -1
  91. package/dist/react/useMutators.js +7 -1
  92. package/dist/react/useReactive.js +0 -1
  93. package/dist/react/useUndoScope.js +2 -2
  94. package/dist/schema/ddlLock.d.ts +39 -0
  95. package/dist/schema/ddlLock.js +51 -0
  96. package/dist/schema/field.js +1 -1
  97. package/dist/schema/index.d.ts +4 -3
  98. package/dist/schema/index.js +15 -5
  99. package/dist/schema/model.d.ts +3 -3
  100. package/dist/schema/model.js +2 -2
  101. package/dist/schema/openapi.js +5 -1
  102. package/dist/schema/queries.d.ts +1 -1
  103. package/dist/schema/queries.js +1 -0
  104. package/dist/schema/residency.d.ts +35 -0
  105. package/dist/schema/residency.js +27 -0
  106. package/dist/schema/roles.d.ts +25 -0
  107. package/dist/schema/roles.js +37 -0
  108. package/dist/schema/schema.d.ts +3 -3
  109. package/dist/schema/schema.js +11 -7
  110. package/dist/schema/serialize.d.ts +8 -8
  111. package/dist/schema/sync-delta-row.d.ts +2 -2
  112. package/dist/schema/sync-delta-row.js +2 -2
  113. package/dist/server/storage-mode.d.ts +8 -1
  114. package/dist/server/storage-mode.js +14 -4
  115. package/dist/source/adapter.d.ts +1 -1
  116. package/dist/source/adapters/drizzle.js +4 -3
  117. package/dist/source/adapters/kysely.js +4 -3
  118. package/dist/source/adapters/memory.js +1 -1
  119. package/dist/source/adapters/prisma.js +5 -4
  120. package/dist/source/conformance.js +10 -8
  121. package/dist/source/connector.js +4 -2
  122. package/dist/source/factory.d.ts +106 -0
  123. package/dist/source/factory.js +273 -0
  124. package/dist/source/index.d.ts +11 -461
  125. package/dist/source/index.js +14 -416
  126. package/dist/source/next.d.ts +1 -1
  127. package/dist/source/next.js +1 -1
  128. package/dist/source/pushQueue.d.ts +1 -1
  129. package/dist/source/pushQueue.js +6 -3
  130. package/dist/source/signing.d.ts +59 -0
  131. package/dist/source/signing.js +142 -0
  132. package/dist/source/types.d.ts +334 -0
  133. package/dist/source/types.js +44 -0
  134. package/dist/stores/ObjectStore.d.ts +1 -1
  135. package/dist/stores/ObjectStore.js +23 -23
  136. package/dist/stores/SyncActionStore.d.ts +1 -1
  137. package/dist/stores/SyncActionStore.js +70 -35
  138. package/dist/surface.d.ts +1 -1
  139. package/dist/surface.js +1 -0
  140. package/dist/sync/AreaOfInterestManager.d.ts +2 -2
  141. package/dist/sync/AreaOfInterestManager.js +1 -1
  142. package/dist/sync/BootstrapHelper.d.ts +1 -3
  143. package/dist/sync/BootstrapHelper.js +29 -8
  144. package/dist/sync/ConnectionManager.d.ts +8 -0
  145. package/dist/sync/ConnectionManager.js +19 -4
  146. package/dist/sync/HydrationCoordinator.d.ts +12 -0
  147. package/dist/sync/HydrationCoordinator.js +25 -5
  148. package/dist/sync/NetworkProbe.d.ts +3 -2
  149. package/dist/sync/NetworkProbe.js +7 -6
  150. package/dist/sync/SyncWebSocket.d.ts +71 -120
  151. package/dist/sync/SyncWebSocket.js +324 -630
  152. package/dist/sync/awaitClaimGrant.js +27 -19
  153. package/dist/sync/bootstrapApply.d.ts +60 -0
  154. package/dist/sync/bootstrapApply.js +65 -0
  155. package/dist/sync/commitFrames.d.ts +43 -0
  156. package/dist/sync/commitFrames.js +94 -0
  157. package/dist/sync/createClaimStream.js +3 -2
  158. package/dist/sync/createSnapshot.d.ts +1 -3
  159. package/dist/sync/credentialLifecycle.d.ts +175 -0
  160. package/dist/sync/credentialLifecycle.js +329 -0
  161. package/dist/sync/deltaPipeline.d.ts +111 -0
  162. package/dist/sync/deltaPipeline.js +262 -0
  163. package/dist/sync/groupChange.d.ts +111 -0
  164. package/dist/sync/groupChange.js +246 -0
  165. package/dist/sync/heartbeat.d.ts +62 -0
  166. package/dist/sync/heartbeat.js +91 -0
  167. package/dist/sync/participants.d.ts +8 -8
  168. package/dist/sync/syncCursor.d.ts +44 -0
  169. package/dist/sync/syncCursor.js +59 -0
  170. package/dist/sync/syncPlan.d.ts +62 -0
  171. package/dist/sync/syncPlan.js +51 -0
  172. package/dist/sync/wsFrameHandlers.d.ts +117 -0
  173. package/dist/sync/wsFrameHandlers.js +378 -0
  174. package/dist/testing/fixtures/bootstrap.d.ts +9 -11
  175. package/dist/testing/fixtures/deltas.d.ts +1 -1
  176. package/dist/testing/fixtures/models.js +1 -0
  177. package/dist/testing/helpers/sync-engine-harness.d.ts +0 -3
  178. package/dist/testing/helpers/sync-engine-harness.js +2 -1
  179. package/dist/testing/index.d.ts +1 -1
  180. package/dist/testing/index.js +1 -1
  181. package/dist/testing/mocks/MockSyncContext.d.ts +1 -17
  182. package/dist/testing/mocks/MockSyncContext.js +1 -32
  183. package/dist/testing/mocks/MockSyncStore.d.ts +4 -4
  184. package/dist/testing/mocks/MockWebSocket.d.ts +2 -2
  185. package/dist/transactions/TransactionQueue.d.ts +20 -56
  186. package/dist/transactions/TransactionQueue.js +101 -487
  187. package/dist/transactions/TransactionStore.d.ts +18 -0
  188. package/dist/transactions/TransactionStore.js +51 -0
  189. package/dist/transactions/coalesceRules.d.ts +34 -0
  190. package/dist/transactions/coalesceRules.js +117 -0
  191. package/dist/transactions/commitPayload.d.ts +134 -0
  192. package/dist/transactions/commitPayload.js +152 -0
  193. package/dist/transactions/deltaConfirmation.d.ts +60 -0
  194. package/dist/transactions/deltaConfirmation.js +223 -0
  195. package/dist/transactions/optimistic.d.ts +24 -0
  196. package/dist/transactions/optimistic.js +45 -0
  197. package/dist/transactions/persistedReplay.d.ts +93 -0
  198. package/dist/transactions/persistedReplay.js +105 -0
  199. package/dist/types/index.d.ts +3 -3
  200. package/dist/types/index.js +0 -5
  201. package/dist/types/modelData.d.ts +12 -0
  202. package/dist/types/modelData.js +11 -0
  203. package/dist/types/participant.d.ts +21 -0
  204. package/dist/types/participant.js +12 -0
  205. package/dist/types/streams.d.ts +8 -14
  206. package/dist/utils/mobx-setup.d.ts +1 -1
  207. package/dist/utils/mobx-setup.js +2 -2
  208. package/dist/wire/errorEnvelope.d.ts +11 -2
  209. package/dist/wire/errorEnvelope.js +14 -2
  210. package/dist/wire/frames.d.ts +90 -0
  211. package/dist/wire/frames.js +55 -1
  212. package/dist/wire/index.d.ts +4 -1
  213. package/dist/wire/index.js +20 -1
  214. package/dist/wire/protocol.d.ts +45 -0
  215. package/dist/wire/protocol.js +45 -0
  216. package/dist/wire/protocolVersion.d.ts +56 -0
  217. package/dist/wire/protocolVersion.js +63 -0
  218. package/docs/api-keys.md +4 -3
  219. package/docs/data-sources.md +12 -5
  220. package/docs/examples/existing-python-backend.md +3 -3
  221. package/docs/identity.md +4 -4
  222. package/docs/integration-guide.md +1 -1
  223. package/docs/react.md +1 -1
  224. package/docs/sessions.md +5 -7
  225. package/llms.txt +4 -2
  226. package/package.json +15 -13
  227. package/dist/client/index.d.ts +0 -36
  228. package/dist/client/index.js +0 -33
  229. package/dist/config/index.d.ts +0 -10
  230. package/dist/config/index.js +0 -12
  231. package/dist/interfaces/headless.d.ts +0 -95
  232. package/dist/interfaces/headless.js +0 -41
  233. package/dist/query/index.d.ts +0 -6
  234. package/dist/query/index.js +0 -5
  235. package/dist/realtime/index.d.ts +0 -10
  236. package/dist/realtime/index.js +0 -9
  237. package/dist/schema/plane.d.ts +0 -23
  238. package/dist/schema/plane.js +0 -19
  239. package/dist/server/next.d.ts +0 -51
  240. package/dist/server/next.js +0 -47
  241. package/dist/sync/OfflineFlush.d.ts +0 -9
  242. package/dist/sync/OfflineFlush.js +0 -22
  243. package/dist/sync/OfflineTransactionStore.d.ts +0 -37
  244. package/dist/sync/OfflineTransactionStore.js +0 -263
  245. package/dist/transactions/index.d.ts +0 -16
  246. package/dist/transactions/index.js +0 -7
@@ -1,468 +1,18 @@
1
- import type { Schema, SchemaRecord, InferCreate } from '../schema/schema.js';
2
- import type { Environment } from '../environment.js';
3
- import type { DataSourceAdapter } from './adapter.js';
4
- export type SourcePrimitive = string | number | boolean | null;
5
- export type SourceWhere = readonly [field: string, value: SourcePrimitive] | readonly [
6
- field: string,
7
- op: '=' | '!=' | '<' | '<=' | '>' | '>=' | 'IN' | 'NOT IN' | 'IS' | 'IS NOT' | 'LIKE' | 'NOT LIKE' | 'ILIKE' | 'NOT ILIKE',
8
- value: SourcePrimitive | readonly SourcePrimitive[]
9
- ];
10
- export interface SourceListQuery {
11
- readonly where?: readonly SourceWhere[];
12
- readonly limit?: number;
13
- readonly orderBy?: string;
14
- readonly order?: 'asc' | 'desc';
15
- readonly related?: readonly string[];
16
- /**
17
- * Opaque cursor returned by a previous `list` call. The customer's
18
- * `list` handler defines what this encodes (page index, last id,
19
- * keyset). Ablo treats it as a black box — round-trips it back to
20
- * fetch the next page until the handler returns no `nextCursor`.
21
- */
22
- readonly cursor?: string;
23
- }
24
1
  /**
25
- * Optional structured shape for a `list` handler that supports
26
- * pagination. Handlers may keep returning a plain `Row[]` (no
27
- * pagination, single-shot) or upgrade to this shape to expose a
28
- * cursor that Ablo will round-trip on the next request.
29
- */
30
- export interface SourceListPage<Row> {
31
- readonly rows: readonly Row[];
32
- readonly nextCursor?: string;
33
- }
34
- export type SourceListResult<Row> = readonly Row[] | SourceListPage<Row>;
35
- /**
36
- * Read-side scope context that Ablo attaches to source requests so
37
- * the customer's `authorize` / model handlers can refuse calls that
38
- * fall outside the participant's permitted syncGroups.
39
- *
40
- * This is informational — the customer is the only side that can
41
- * actually enforce, since the canonical data lives in their store.
42
- * Mirrors how Auth0 Custom DB scripts receive the requested scope and
43
- * trust the script to honor it.
44
- */
45
- export interface SourceRequestContext {
46
- readonly participantId?: string;
47
- readonly participantKind?: 'user' | 'agent' | 'system';
48
- readonly organizationId?: string;
49
- readonly requiredSyncGroups?: readonly string[];
50
- /**
51
- * Production/sandbox mode for this request. Customers branch their source
52
- * handlers on this (`if (mode === 'sandbox') db = sandboxDb`) so sandbox
53
- * traffic exercises the same code path against an isolated store.
54
- *
55
- * Mirrors Stripe's `sk_test_` / `sk_live_` prefixes: same wire
56
- * shape, same handler code, different namespace. Ablo's server-side
57
- * fan-out does not yet partition deltas by mode — that lands when
58
- * `sync_deltas.mode` ships. Until then, isolation is enforced
59
- * customer-side via this field, which is the right boundary anyway
60
- * (the customer's database is where the canonical data lives).
61
- *
62
- * Defaults to `'production'` when omitted so callers that don't opt in
63
- * keep the existing behavior.
64
- */
65
- readonly mode?: Environment;
66
- }
67
- export interface SourceOperation {
68
- readonly type: 'CREATE' | 'UPDATE' | 'DELETE' | 'ARCHIVE' | 'UNARCHIVE';
69
- readonly model: string;
70
- readonly id?: string | null;
71
- readonly input?: Record<string, unknown> | null;
72
- readonly transactionId?: string | null;
73
- readonly readAt?: number | null;
74
- readonly onStale?: 'reject' | 'overwrite' | 'notify' | null;
75
- }
76
- export interface SourceDelta {
77
- readonly model: string;
78
- readonly id: string;
79
- readonly type: SourceOperation['type'];
80
- readonly data?: Record<string, unknown> | null;
81
- readonly transactionId?: string | null;
82
- }
83
- /**
84
- * A change that happened in the customer's store. The source's
85
- * `events` handler returns these so Ablo can append them to
86
- * `sync_deltas` and fan them out to connected clients exactly like
87
- * SDK-originated commits.
88
- *
89
- * The events handler can return everything from the outbox unfiltered. Ablo
90
- * dedupes stable `event.id` values and uses `clientTxId` to filter SDK-origin
91
- * echoes after the direct append has already succeeded. If the direct append
92
- * failed, the same outbox event repairs it on poll/push because no matching
93
- * `mutation_log` row exists yet.
94
- */
95
- export interface SourceEvent {
96
- /**
97
- * Globally unique event id from the customer's outbox. Used by Ablo
98
- * for replay protection — re-delivering the same id is a no-op.
99
- */
100
- readonly id: string;
101
- readonly model: string;
102
- readonly entityId: string;
103
- readonly type: SourceOperation['type'];
104
- readonly data?: Record<string, unknown> | null;
105
- /**
106
- * Tenant the event belongs to. Multi-tenant customers populate this
107
- * from the row's organization column. Single-tenant deployments may
108
- * omit it and let the poller fall back to its configured default.
109
- * Drives the sync-group fan-out: clients in `org:${organizationId}`
110
- * receive the resulting delta.
111
- */
112
- readonly organizationId?: string;
113
- /**
114
- * Originating Ablo SDK commit id, when known. If the customer's
115
- * outbox stores the `clientTxId` Ablo passed into the matching
116
- * `commit` handler, round-trip it here and Ablo will skip events
117
- * whose commit already produced a delta. External-origin events
118
- * (cron jobs, batch imports, manual edits) leave this unset.
119
- */
120
- readonly clientTxId?: string;
121
- /**
122
- * Wall-clock time the event occurred in the source. Optional; used
123
- * only for ordering hints. Ablo trusts the customer's response order
124
- * over this field.
125
- */
126
- readonly occurredAt?: number;
127
- }
128
- export interface SourceEventForOperationOptions {
129
- /**
130
- * Stable id from the customer's outbox table. This is Ablo's replay-
131
- * protection key; retries must return the same id.
132
- */
133
- readonly eventId: string;
134
- readonly operation: SourceOperation;
135
- /**
136
- * Committed row id. Defaults to `operation.id`; pass this for generated-id
137
- * CREATEs where the database assigns the id inside the transaction.
138
- */
139
- readonly entityId?: string;
140
- /**
141
- * Canonical row payload after the write. Pass `null` for DELETE. When omitted
142
- * the event carries no row payload, which is valid but less useful for
143
- * realtime hydration.
144
- */
145
- readonly data?: Record<string, unknown> | null;
146
- /**
147
- * Batch idempotency key from the Data Source commit request. Round-tripping it
148
- * lets Ablo filter SDK-origin echoes after the direct append succeeds, while
149
- * still using the outbox event to repair a failed direct append.
150
- */
151
- readonly clientTxId?: string;
152
- readonly organizationId?: string;
153
- readonly occurredAt?: number | Date;
154
- }
155
- /**
156
- * Build the source-event marker customers should write to their outbox table in
157
- * the SAME transaction as their app-row mutation.
2
+ * `@abloatai/ablo/source` the Data Source barrel.
158
3
  *
159
- * This helper does not persist anything. It only standardizes the marker shape
160
- * so Prisma/Drizzle/Kysely/raw-SQL adapters all emit the fields Ablo's
161
- * reconciler expects.
162
- */
163
- export declare function sourceEventForOperation(options: SourceEventForOperationOptions): SourceEvent;
164
- export interface SourceCommitResult<Row = Record<string, unknown>> {
165
- /**
166
- * Canonical rows after the write. Ablo uses these to update hosted
167
- * realtime projections and append deltas.
168
- */
169
- readonly rows?: readonly Row[];
170
- /**
171
- * Optional explicit deltas when the source already computes them.
172
- * Most sources can return rows and let Ablo derive the delta payload.
173
- */
174
- readonly deltas?: readonly SourceDelta[];
175
- }
176
- export interface SourceCommitParams<TAuth = unknown> {
177
- readonly operations: readonly SourceOperation[];
178
- readonly clientTxId?: string;
179
- readonly context: SourceHandlerContext<TAuth>;
180
- }
181
- /**
182
- * Operation-level permission tag used by `resolveScopes`. Mirrors the
183
- * four wire request types: an API key carries the set of operations
184
- * it's allowed to invoke. Stripe's restricted-key model at the
185
- * operation granularity — model-level scoping is a future addition.
186
- */
187
- export type SourceScope = 'load' | 'list' | 'commit' | 'events';
188
- export interface SourceEventsResult {
189
- readonly events: readonly SourceEvent[];
190
- /**
191
- * Cursor for the next poll. When omitted Ablo treats the feed as
192
- * fully drained for this round and uses the last event's cursor (or
193
- * the initial cursor) for the next call.
194
- */
195
- readonly nextCursor?: string;
196
- }
197
- export type SourceEventsHandler<TAuth = unknown> = (params: {
198
- /**
199
- * Cursor returned by a previous `events` call. Undefined on the
200
- * first poll for a freshly-onboarded source. The customer decides
201
- * what it encodes (last event id, timestamp, LSN, etc).
202
- */
203
- readonly cursor?: string;
204
- /**
205
- * Caller-suggested upper bound on returned events. Customers may
206
- * return fewer; returning more risks tripping Ablo's per-poll cap.
207
- */
208
- readonly limit?: number;
209
- readonly context: SourceHandlerContext<TAuth>;
210
- }) => Promise<SourceEventsResult> | SourceEventsResult;
211
- export interface SourceAuthorizeContext {
212
- readonly request: Request;
213
- readonly body: unknown;
214
- readonly rawBody: string;
215
- }
216
- export interface SourceHandlerContext<TAuth = unknown> {
217
- readonly auth: TAuth;
218
- readonly request: Request;
219
- /**
220
- * `webhook-id` from the signed request — globally unique per the
221
- * Standard Webhooks spec. Customers should dedupe by this id to
222
- * defend against replay (Ablo doesn't dedupe at the source-handler
223
- * boundary; commit idempotency is `clientTxId`, and event replay
224
- * protection is the outbox event `id`).
225
- */
226
- readonly messageId?: string;
227
- readonly signedAt?: number;
228
- /**
229
- * Scope context Ablo attached to this request. Present when the
230
- * caller (sync-server) opted into scope-aware source mode. Customers
231
- * can use it in `authorize` (to reject out-of-scope calls) and in
232
- * `list` / `load` (to filter rows the participant is allowed to see).
233
- *
234
- * Absent for calls made without scope context, such as tests or
235
- * single-tenant deployments that do not need scoped fan-out yet.
236
- */
237
- readonly scope?: SourceRequestContext;
238
- }
239
- export interface SourceModelHandlers<Row, CreateInput, TAuth = unknown> {
240
- load?(params: {
241
- readonly id: string;
242
- readonly context: SourceHandlerContext<TAuth>;
243
- }): Promise<Row | null> | Row | null;
244
- list?(params: {
245
- readonly query: SourceListQuery;
246
- readonly context: SourceHandlerContext<TAuth>;
247
- }): Promise<SourceListResult<Row>> | SourceListResult<Row>;
248
- /**
249
- * Apply one or more operations for this model in the customer's own
250
- * transaction. The source must be idempotent by operation/clientTxId.
251
- */
252
- commit?(params: {
253
- readonly operations: readonly SourceOperation[];
254
- readonly clientTxId?: string;
255
- readonly context: SourceHandlerContext<TAuth>;
256
- }): Promise<SourceCommitResult<Row>> | SourceCommitResult<Row>;
257
- }
258
- export type SourceCommitHandler<TAuth = unknown> = (params: SourceCommitParams<TAuth>) => Promise<SourceCommitResult> | SourceCommitResult;
259
- type SourceModels<S extends SchemaRecord, TAuth> = Partial<{
260
- readonly [K in keyof S & string]: SourceModelHandlers<InferCreate<Schema<S>, K> & {
261
- readonly id: string;
262
- } & Record<string, unknown>, InferCreate<Schema<S>, K>, TAuth>;
263
- }>;
264
- export type SourceApiKey = string | ((context: SourceAuthorizeContext) => Promise<string> | string);
265
- export interface SourceSignatureOptions {
266
- readonly apiKey: string;
267
- readonly body: string;
268
- /**
269
- * Unique message id (`webhook-id` per the Standard Webhooks spec).
270
- * Required: it goes into the HMAC input for replay defense, and
271
- * receivers may dedupe by it.
272
- */
273
- readonly messageId: string;
274
- /**
275
- * Unix timestamp in seconds. Defaults to the current time.
276
- */
277
- readonly timestamp?: number;
278
- }
279
- export interface SourceSignatureVerificationOptions {
280
- readonly request: Request;
281
- readonly body: string;
282
- readonly apiKey: string;
283
- readonly toleranceMs?: number;
284
- }
285
- export interface SourceSignatureVerificationResult {
286
- readonly messageId: string;
287
- readonly signedAt: number;
288
- }
289
- /**
290
- * HTTP headers used on signed source requests. Conforms to the
291
- * Standard Webhooks specification (https://www.standardwebhooks.com/)
292
- * so customer code can verify our signatures with any of the official
293
- * libraries (svix, standardwebhooks, hookdeck, etc.) — no Ablo-
294
- * specific verifier required.
295
- */
296
- export declare const ABLO_SOURCE_HEADERS: {
297
- readonly signature: "webhook-signature";
298
- readonly timestamp: "webhook-timestamp";
299
- readonly id: "webhook-id";
300
- readonly idempotencyKey: "Idempotency-Key";
301
- };
302
- export declare class SourceSignatureError extends Error {
303
- readonly code: 'source_signature_missing' | 'source_id_missing' | 'source_timestamp_missing' | 'source_timestamp_invalid' | 'source_timestamp_expired' | 'source_signature_invalid' | 'source_forbidden';
304
- constructor(code: SourceSignatureError['code'], message: string);
305
- }
306
- export type AbloSourceOptions<S extends SchemaRecord, TAuth = unknown> = {
307
- readonly schema: Schema<S>;
308
- /**
309
- * Customer-visible Ablo credential. In the API-key-only onboarding
310
- * path, Ablo signs Data Source calls with the same project API key
311
- * that the customer's server-side SDK uses. This keeps the customer
312
- * env surface to one Ablo credential while preserving signed request
313
- * verification before any handler runs.
314
- */
315
- readonly apiKey: SourceApiKey;
316
- /**
317
- * Clock-skew window for signed source requests. Default: 5 minutes.
318
- */
319
- readonly signatureToleranceMs?: number;
320
- /**
321
- * Verify the Ablo request and return customer-owned context such as
322
- * a database handle, account scope, or current actor. Keep database
323
- * credentials in this function's environment; never send them to Ablo.
324
- *
325
- * Signature verification is handled by `apiKey` before this function
326
- * runs. `authorize` should only attach business context.
327
- */
328
- readonly authorize?: (context: SourceAuthorizeContext) => Promise<TAuth> | TAuth;
329
- /**
330
- * Optional per-request scope resolver. When set, the helper checks
331
- * the resolved scope set against the request's operation
332
- * (`load`/`list`/`commit`/`events`) and returns 403
333
- * `source_forbidden` if not allowed — before any model handler
334
- * runs.
335
- *
336
- * Customers typically extract a key id from the request (e.g.
337
- * `webhook-id` prefix, a custom header, or the API key itself) and
338
- * look up the scopes for that key in their store.
339
- *
340
- * When omitted, all operations are allowed. Returning an empty set
341
- * denies all operations.
342
- */
343
- readonly resolveScopes?: (params: {
344
- readonly auth: TAuth;
345
- readonly request: Request;
346
- readonly body: SourceRequest;
347
- }) => Promise<ReadonlySet<SourceScope> | readonly SourceScope[]> | ReadonlySet<SourceScope> | readonly SourceScope[];
348
- /**
349
- * Top-level atomic commit handler. Prefer this for real applications:
350
- * one UI/action commit can span several models and should run inside
351
- * one customer-owned transaction.
352
- */
353
- readonly commit?: SourceCommitHandler<TAuth>;
354
- /**
355
- * External-write feed. Ablo polls this to learn about changes that
356
- * happened outside the SDK (cron jobs, dashboard edits, batch
357
- * imports). Each returned event becomes a delta and fans out to
358
- * connected clients.
359
- *
360
- * Handlers may return the raw outbox feed. Ablo dedupes stable
361
- * `event.id` values and filters SDK-origin echoes when rows carry
362
- * the originating `clientTxId`; customers should persist both fields
363
- * in their outbox table.
364
- */
365
- readonly events?: SourceEventsHandler<TAuth>;
366
- /**
367
- * Optional grouped form. The object-key form below is usually terser:
368
- * `abloSource({ schema, files: { load, list, commit } })`.
369
- */
370
- readonly models?: SourceModels<S, TAuth>;
371
- /**
372
- * An ORM adapter (`prismaDataSource(prisma, schema)`, …). When set, it serves
373
- * ALL four operations — read (load/list), commit (idempotent + outbox), and
374
- * events — so no hand-written `commit`/`events`/model handlers are needed. The
375
- * adapter is consumed at the generic dispatch layer (rows are JSON on the wire),
376
- * which is why it carries no per-model types and needs no cast at the call site.
377
- * Mutually exclusive with hand-written handlers.
378
- */
379
- readonly adapter?: DataSourceAdapter;
380
- } & SourceModels<S, TAuth>;
381
- export type SourceLoadRequest = {
382
- readonly type: 'load';
383
- readonly model: string;
384
- readonly id: string;
385
- readonly scope?: SourceRequestContext;
386
- };
387
- export type SourceListRequest = {
388
- readonly type: 'list';
389
- readonly model: string;
390
- readonly query?: SourceListQuery;
391
- readonly scope?: SourceRequestContext;
392
- };
393
- export type SourceCommitRequest = {
394
- readonly type: 'commit';
395
- /**
396
- * Optional single-model hint. Omit for cross-model commits; top-level
397
- * `commit` receives the whole operation array unchanged.
398
- */
399
- readonly model?: string;
400
- readonly operations: readonly SourceOperation[];
401
- readonly clientTxId?: string;
402
- readonly scope?: SourceRequestContext;
403
- };
404
- export type SourceEventsRequest = {
405
- readonly type: 'events';
406
- readonly cursor?: string;
407
- readonly limit?: number;
408
- readonly scope?: SourceRequestContext;
409
- };
410
- export type SourceRequest = SourceLoadRequest | SourceListRequest | SourceCommitRequest | SourceEventsRequest;
411
- export type SourceResponse<Row = Record<string, unknown>> = {
412
- readonly row: Row | null;
413
- } | {
414
- readonly rows: readonly Row[];
415
- readonly nextCursor?: string;
416
- } | {
417
- readonly rows?: readonly Row[];
418
- readonly deltas?: readonly SourceDelta[];
419
- };
420
- export declare function signAbloSourceRequest(options: SourceSignatureOptions): Promise<{
421
- readonly headers: Record<string, string>;
422
- readonly signedAt: number;
423
- readonly signature: string;
424
- }>;
425
- export declare function verifyAbloSourceRequest(options: SourceSignatureVerificationOptions): Promise<SourceSignatureVerificationResult>;
426
- /**
427
- * Create a customer-owned data source endpoint.
4
+ * Pure re-exports only: the implementation lives in cohesive leaf modules so
5
+ * sibling source/* files (`pushQueue.ts`, `adapter.ts`, `contract.ts`, the ORM
6
+ * adapters) import the leaves directly instead of routing a runtime circular
7
+ * dependency through this barrel.
428
8
  *
429
- * App code still talks to Ablo with `ablo.files.load/list/update`.
430
- * This helper is only for customers who keep canonical rows in their own
431
- * database and want Ablo Cloud to call a narrow, signed endpoint instead
432
- * of receiving database credentials.
9
+ * - `types.ts` — shared wire/handler types + `sourceEventForOperation`
10
+ * - `signing.ts` Standard Webhooks request signing/verification
11
+ * - `factory.ts` the `abloSource()` / `dataSource()` endpoint factory
433
12
  */
434
- export type DataSourcePrimitive = SourcePrimitive;
435
- export type DataSourceWhere = SourceWhere;
436
- export type DataSourceListQuery = SourceListQuery;
437
- export type DataSourceListPage<Row> = SourceListPage<Row>;
438
- export type DataSourceListResult<Row> = SourceListResult<Row>;
439
- export type DataSourceRequestContext = SourceRequestContext;
440
- export type DataSourceOperation = SourceOperation;
441
- export type DataSourceDelta = SourceDelta;
442
- export type DataSourceEvent = SourceEvent;
443
- export type DataSourceEventForOperationOptions = SourceEventForOperationOptions;
444
- export type DataSourceCommitResult<Row = Record<string, unknown>> = SourceCommitResult<Row>;
445
- export type DataSourceCommitParams<TAuth = unknown> = SourceCommitParams<TAuth>;
446
- export type DataSourceScope = SourceScope;
447
- export type DataSourceEventsResult = SourceEventsResult;
448
- export type DataSourceEventsHandler<TAuth = unknown> = SourceEventsHandler<TAuth>;
449
- export type DataSourceAuthorizeContext = SourceAuthorizeContext;
450
- export type DataSourceHandlerContext<TAuth = unknown> = SourceHandlerContext<TAuth>;
451
- export type DataSourceModelHandlers<Row, CreateInput, TAuth = unknown> = SourceModelHandlers<Row, CreateInput, TAuth>;
452
- export type DataSourceCommitHandler<TAuth = unknown> = SourceCommitHandler<TAuth>;
453
- export type DataSourceApiKey = SourceApiKey;
454
- export type DataSourceSignatureOptions = SourceSignatureOptions;
455
- export type DataSourceSignatureVerificationOptions = SourceSignatureVerificationOptions;
456
- export type DataSourceSignatureVerificationResult = SourceSignatureVerificationResult;
457
- export type DataSourceOptions<S extends SchemaRecord, TAuth = unknown> = AbloSourceOptions<S, TAuth>;
458
- export type DataSourceLoadRequest = SourceLoadRequest;
459
- export type DataSourceListRequest = SourceListRequest;
460
- export type DataSourceCommitRequest = SourceCommitRequest;
461
- export type DataSourceEventsRequest = SourceEventsRequest;
462
- export type DataSourceRequest = SourceRequest;
463
- export type DataSourceResponse<Row = Record<string, unknown>> = SourceResponse<Row>;
464
- export declare function abloSource<const S extends SchemaRecord, TAuth = unknown>(options: AbloSourceOptions<S, TAuth>): (request: Request) => Promise<Response>;
465
- export declare function dataSource<const S extends SchemaRecord, TAuth = unknown>(options: DataSourceOptions<S, TAuth>): (request: Request) => Promise<Response>;
13
+ export { sourceEventForOperation, type SourcePrimitive, type SourceWhere, type SourceListQuery, type SourceListPage, type SourceListResult, type SourceRequestContext, type SourceOperation, type SourceDelta, type SourceEvent, type SourceEventForOperationOptions, type SourceCommitResult, type SourceCommitParams, type SourceScope, type SourceEventsResult, type SourceEventsHandler, type SourceAuthorizeContext, type SourceHandlerContext, type SourceModelHandlers, type SourceCommitHandler, type SourceApiKey, type SourceLoadRequest, type SourceListRequest, type SourceCommitRequest, type SourceEventsRequest, type SourceRequest, type SourceResponse, type DataSourcePrimitive, type DataSourceWhere, type DataSourceListQuery, type DataSourceListPage, type DataSourceListResult, type DataSourceRequestContext, type DataSourceOperation, type DataSourceDelta, type DataSourceEvent, type DataSourceEventForOperationOptions, type DataSourceCommitResult, type DataSourceCommitParams, type DataSourceScope, type DataSourceEventsResult, type DataSourceEventsHandler, type DataSourceAuthorizeContext, type DataSourceHandlerContext, type DataSourceModelHandlers, type DataSourceCommitHandler, type DataSourceApiKey, type DataSourceLoadRequest, type DataSourceListRequest, type DataSourceCommitRequest, type DataSourceEventsRequest, type DataSourceRequest, type DataSourceResponse, } from './types.js';
14
+ export { ABLO_SOURCE_HEADERS, SourceSignatureError, signAbloSourceRequest, verifyAbloSourceRequest, type SourceSignatureOptions, type SourceSignatureVerificationOptions, type SourceSignatureVerificationResult, type DataSourceSignatureOptions, type DataSourceSignatureVerificationOptions, type DataSourceSignatureVerificationResult, } from './signing.js';
15
+ export { abloSource, dataSource, type AbloSourceOptions, type DataSourceOptions, } from './factory.js';
466
16
  export { createPushQueue, InMemoryPushQueueStorage, STANDARD_WEBHOOKS_RETRY_SCHEDULE, type PushQueue, type PushQueueItem, type PushQueueOptions, type PushQueueStorage, } from './pushQueue.js';
467
17
  export { createSourceConnector, DEFAULT_RECONNECT_SCHEDULE, type SourceConnector, type SourceConnectorOptions, type ConnectorWebSocket, type ConnectorWebSocketFactory, type ConnectorStatus, } from './connector.js';
468
18
  export { SOURCE_CONNECTOR_PROTOCOL_VERSION, SOURCE_CONNECTOR_WS_PATH, WS_SOURCE_SUBPROTOCOL, sourceConnectorSubprotocols, encodeFrame, decodeFrame, ConnectorProtocolError, connectorFrameSchema, type ConnectorFrame, type RegisterFrame, type ReadyFrame, type RequestFrame, type ResponseFrame, type ErrorFrame, } from './connector-protocol.js';