@abloatai/ablo 0.3.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 (278) hide show
  1. package/CHANGELOG.md +208 -0
  2. package/LICENSE +201 -0
  3. package/NOTICE +12 -0
  4. package/README.md +230 -0
  5. package/dist/BaseSyncedStore.d.ts +709 -0
  6. package/dist/BaseSyncedStore.js +1843 -0
  7. package/dist/Database.d.ts +344 -0
  8. package/dist/Database.js +1259 -0
  9. package/dist/LazyReferenceCollection.d.ts +181 -0
  10. package/dist/LazyReferenceCollection.js +460 -0
  11. package/dist/Model.d.ts +339 -0
  12. package/dist/Model.js +715 -0
  13. package/dist/ModelRegistry.d.ts +200 -0
  14. package/dist/ModelRegistry.js +535 -0
  15. package/dist/NetworkMonitor.d.ts +27 -0
  16. package/dist/NetworkMonitor.js +73 -0
  17. package/dist/ObjectPool.d.ts +202 -0
  18. package/dist/ObjectPool.js +1106 -0
  19. package/dist/SyncClient.d.ts +489 -0
  20. package/dist/SyncClient.js +1555 -0
  21. package/dist/SyncEngineContext.d.ts +46 -0
  22. package/dist/SyncEngineContext.js +74 -0
  23. package/dist/adapters/alwaysOnline.d.ts +16 -0
  24. package/dist/adapters/alwaysOnline.js +19 -0
  25. package/dist/adapters/inMemoryStorage.d.ts +30 -0
  26. package/dist/adapters/inMemoryStorage.js +94 -0
  27. package/dist/agent/Agent.d.ts +358 -0
  28. package/dist/agent/Agent.js +500 -0
  29. package/dist/agent/index.d.ts +115 -0
  30. package/dist/agent/index.js +128 -0
  31. package/dist/agent/session.d.ts +90 -0
  32. package/dist/agent/session.js +156 -0
  33. package/dist/agent/types.d.ts +73 -0
  34. package/dist/agent/types.js +10 -0
  35. package/dist/ai-sdk/coordination-context.d.ts +51 -0
  36. package/dist/ai-sdk/coordination-context.js +107 -0
  37. package/dist/ai-sdk/index.d.ts +68 -0
  38. package/dist/ai-sdk/index.js +68 -0
  39. package/dist/ai-sdk/intent-broadcast.d.ts +77 -0
  40. package/dist/ai-sdk/intent-broadcast.js +72 -0
  41. package/dist/ai-sdk/wrap.d.ts +67 -0
  42. package/dist/ai-sdk/wrap.js +45 -0
  43. package/dist/api/index.d.ts +10 -0
  44. package/dist/api/index.js +9 -0
  45. package/dist/auth/index.d.ts +137 -0
  46. package/dist/auth/index.js +246 -0
  47. package/dist/client/Ablo.d.ts +835 -0
  48. package/dist/client/Ablo.js +1440 -0
  49. package/dist/client/ApiClient.d.ts +200 -0
  50. package/dist/client/ApiClient.js +659 -0
  51. package/dist/client/auth.d.ts +79 -0
  52. package/dist/client/auth.js +81 -0
  53. package/dist/client/createInternalComponents.d.ts +44 -0
  54. package/dist/client/createInternalComponents.js +88 -0
  55. package/dist/client/createModelProxy.d.ts +152 -0
  56. package/dist/client/createModelProxy.js +199 -0
  57. package/dist/client/identity.d.ts +63 -0
  58. package/dist/client/identity.js +156 -0
  59. package/dist/client/index.d.ts +36 -0
  60. package/dist/client/index.js +33 -0
  61. package/dist/client/persistence.d.ts +7 -0
  62. package/dist/client/persistence.js +11 -0
  63. package/dist/client/validateAbloOptions.d.ts +42 -0
  64. package/dist/client/validateAbloOptions.js +43 -0
  65. package/dist/config/index.d.ts +10 -0
  66. package/dist/config/index.js +12 -0
  67. package/dist/context.d.ts +27 -0
  68. package/dist/context.js +58 -0
  69. package/dist/core/DatabaseManager.d.ts +108 -0
  70. package/dist/core/DatabaseManager.js +361 -0
  71. package/dist/core/QueryProcessor.d.ts +77 -0
  72. package/dist/core/QueryProcessor.js +262 -0
  73. package/dist/core/QueryView.d.ts +64 -0
  74. package/dist/core/QueryView.js +219 -0
  75. package/dist/core/StoreManager.d.ts +131 -0
  76. package/dist/core/StoreManager.js +334 -0
  77. package/dist/core/ViewRegistry.d.ts +20 -0
  78. package/dist/core/ViewRegistry.js +55 -0
  79. package/dist/core/index.d.ts +34 -0
  80. package/dist/core/index.js +59 -0
  81. package/dist/core/openIDBWithTimeout.d.ts +27 -0
  82. package/dist/core/openIDBWithTimeout.js +63 -0
  83. package/dist/core/query-utils.d.ts +37 -0
  84. package/dist/core/query-utils.js +60 -0
  85. package/dist/errors.d.ts +235 -0
  86. package/dist/errors.js +243 -0
  87. package/dist/index.d.ts +41 -0
  88. package/dist/index.js +82 -0
  89. package/dist/interfaces/headless.d.ts +95 -0
  90. package/dist/interfaces/headless.js +41 -0
  91. package/dist/interfaces/index.d.ts +321 -0
  92. package/dist/interfaces/index.js +8 -0
  93. package/dist/mutators/RecordingTransaction.d.ts +36 -0
  94. package/dist/mutators/RecordingTransaction.js +216 -0
  95. package/dist/mutators/Transaction.d.ts +48 -0
  96. package/dist/mutators/Transaction.js +64 -0
  97. package/dist/mutators/UndoManager.d.ts +114 -0
  98. package/dist/mutators/UndoManager.js +143 -0
  99. package/dist/mutators/defineMutators.d.ts +55 -0
  100. package/dist/mutators/defineMutators.js +28 -0
  101. package/dist/policy/index.d.ts +19 -0
  102. package/dist/policy/index.js +18 -0
  103. package/dist/policy/types.d.ts +74 -0
  104. package/dist/policy/types.js +17 -0
  105. package/dist/principal.d.ts +44 -0
  106. package/dist/principal.js +49 -0
  107. package/dist/query/client.d.ts +43 -0
  108. package/dist/query/client.js +84 -0
  109. package/dist/query/index.d.ts +6 -0
  110. package/dist/query/index.js +5 -0
  111. package/dist/query/types.d.ts +143 -0
  112. package/dist/query/types.js +36 -0
  113. package/dist/react/AbloProvider.d.ts +205 -0
  114. package/dist/react/AbloProvider.js +398 -0
  115. package/dist/react/ClientSideSuspense.d.ts +36 -0
  116. package/dist/react/ClientSideSuspense.js +17 -0
  117. package/dist/react/DefaultFallback.d.ts +24 -0
  118. package/dist/react/DefaultFallback.js +43 -0
  119. package/dist/react/SyncGroupProvider.d.ts +19 -0
  120. package/dist/react/SyncGroupProvider.js +44 -0
  121. package/dist/react/context.d.ts +161 -0
  122. package/dist/react/context.js +35 -0
  123. package/dist/react/index.d.ts +64 -0
  124. package/dist/react/index.js +73 -0
  125. package/dist/react/internalContext.d.ts +35 -0
  126. package/dist/react/internalContext.js +3 -0
  127. package/dist/react/useAblo.d.ts +72 -0
  128. package/dist/react/useAblo.js +63 -0
  129. package/dist/react/useCurrentUserId.d.ts +21 -0
  130. package/dist/react/useCurrentUserId.js +33 -0
  131. package/dist/react/useErrorListener.d.ts +20 -0
  132. package/dist/react/useErrorListener.js +39 -0
  133. package/dist/react/useIntent.d.ts +29 -0
  134. package/dist/react/useIntent.js +42 -0
  135. package/dist/react/useMutate.d.ts +83 -0
  136. package/dist/react/useMutate.js +122 -0
  137. package/dist/react/useMutationFailureListener.d.ts +26 -0
  138. package/dist/react/useMutationFailureListener.js +38 -0
  139. package/dist/react/useMutators.d.ts +56 -0
  140. package/dist/react/useMutators.js +66 -0
  141. package/dist/react/usePresence.d.ts +32 -0
  142. package/dist/react/usePresence.js +41 -0
  143. package/dist/react/useQuery.d.ts +123 -0
  144. package/dist/react/useQuery.js +145 -0
  145. package/dist/react/useReactive.d.ts +35 -0
  146. package/dist/react/useReactive.js +111 -0
  147. package/dist/react/useReader.d.ts +69 -0
  148. package/dist/react/useReader.js +73 -0
  149. package/dist/react/useSyncStatus.d.ts +61 -0
  150. package/dist/react/useSyncStatus.js +76 -0
  151. package/dist/react/useUndoScope.d.ts +36 -0
  152. package/dist/react/useUndoScope.js +73 -0
  153. package/dist/realtime/index.d.ts +10 -0
  154. package/dist/realtime/index.js +9 -0
  155. package/dist/schema/field.d.ts +134 -0
  156. package/dist/schema/field.js +264 -0
  157. package/dist/schema/index.d.ts +29 -0
  158. package/dist/schema/index.js +38 -0
  159. package/dist/schema/model.d.ts +326 -0
  160. package/dist/schema/model.js +89 -0
  161. package/dist/schema/queries.d.ts +203 -0
  162. package/dist/schema/queries.js +145 -0
  163. package/dist/schema/relation.d.ts +172 -0
  164. package/dist/schema/relation.js +104 -0
  165. package/dist/schema/schema.d.ts +259 -0
  166. package/dist/schema/schema.js +188 -0
  167. package/dist/schema/sugar.d.ts +129 -0
  168. package/dist/schema/sugar.js +94 -0
  169. package/dist/source/index.d.ts +423 -0
  170. package/dist/source/index.js +320 -0
  171. package/dist/source/pushQueue.d.ts +112 -0
  172. package/dist/source/pushQueue.js +249 -0
  173. package/dist/stores/ObjectStore.d.ts +103 -0
  174. package/dist/stores/ObjectStore.js +371 -0
  175. package/dist/stores/ObjectStoreContract.d.ts +39 -0
  176. package/dist/stores/ObjectStoreContract.js +1 -0
  177. package/dist/stores/SyncActionStore.d.ts +101 -0
  178. package/dist/stores/SyncActionStore.js +481 -0
  179. package/dist/sync/BootstrapHelper.d.ts +127 -0
  180. package/dist/sync/BootstrapHelper.js +434 -0
  181. package/dist/sync/ConnectionManager.d.ts +136 -0
  182. package/dist/sync/ConnectionManager.js +465 -0
  183. package/dist/sync/HydrationCoordinator.d.ts +137 -0
  184. package/dist/sync/HydrationCoordinator.js +468 -0
  185. package/dist/sync/NetworkProbe.d.ts +43 -0
  186. package/dist/sync/NetworkProbe.js +113 -0
  187. package/dist/sync/OfflineFlush.d.ts +9 -0
  188. package/dist/sync/OfflineFlush.js +22 -0
  189. package/dist/sync/OfflineTransactionStore.d.ts +37 -0
  190. package/dist/sync/OfflineTransactionStore.js +263 -0
  191. package/dist/sync/SyncWebSocket.d.ts +663 -0
  192. package/dist/sync/SyncWebSocket.js +1336 -0
  193. package/dist/sync/createIntentStream.d.ts +33 -0
  194. package/dist/sync/createIntentStream.js +243 -0
  195. package/dist/sync/createPresenceStream.d.ts +46 -0
  196. package/dist/sync/createPresenceStream.js +192 -0
  197. package/dist/sync/createSnapshot.d.ts +33 -0
  198. package/dist/sync/createSnapshot.js +124 -0
  199. package/dist/sync/participants.d.ts +114 -0
  200. package/dist/sync/participants.js +336 -0
  201. package/dist/sync/schemas.d.ts +79 -0
  202. package/dist/sync/schemas.js +78 -0
  203. package/dist/testing/fixtures/bootstrap.d.ts +45 -0
  204. package/dist/testing/fixtures/bootstrap.js +53 -0
  205. package/dist/testing/fixtures/deltas.d.ts +86 -0
  206. package/dist/testing/fixtures/deltas.js +139 -0
  207. package/dist/testing/fixtures/models.d.ts +82 -0
  208. package/dist/testing/fixtures/models.js +270 -0
  209. package/dist/testing/helpers/react-wrapper.d.ts +66 -0
  210. package/dist/testing/helpers/react-wrapper.js +64 -0
  211. package/dist/testing/helpers/sync-engine-harness.d.ts +55 -0
  212. package/dist/testing/helpers/sync-engine-harness.js +70 -0
  213. package/dist/testing/helpers/wait.d.ts +25 -0
  214. package/dist/testing/helpers/wait.js +44 -0
  215. package/dist/testing/index.d.ts +21 -0
  216. package/dist/testing/index.js +32 -0
  217. package/dist/testing/mocks/MockMutationExecutor.d.ts +65 -0
  218. package/dist/testing/mocks/MockMutationExecutor.js +139 -0
  219. package/dist/testing/mocks/MockNetworkMonitor.d.ts +20 -0
  220. package/dist/testing/mocks/MockNetworkMonitor.js +46 -0
  221. package/dist/testing/mocks/MockSyncContext.d.ts +64 -0
  222. package/dist/testing/mocks/MockSyncContext.js +100 -0
  223. package/dist/testing/mocks/MockSyncStore.d.ts +88 -0
  224. package/dist/testing/mocks/MockSyncStore.js +171 -0
  225. package/dist/testing/mocks/MockWebSocket.d.ts +66 -0
  226. package/dist/testing/mocks/MockWebSocket.js +117 -0
  227. package/dist/transactions/OptimisticEchoTracker.d.ts +82 -0
  228. package/dist/transactions/OptimisticEchoTracker.js +104 -0
  229. package/dist/transactions/TransactionQueue.d.ts +499 -0
  230. package/dist/transactions/TransactionQueue.js +1895 -0
  231. package/dist/transactions/index.d.ts +16 -0
  232. package/dist/transactions/index.js +7 -0
  233. package/dist/transactions/mutation-error-handler.d.ts +5 -0
  234. package/dist/transactions/mutation-error-handler.js +39 -0
  235. package/dist/types/global.d.ts +107 -0
  236. package/dist/types/global.js +38 -0
  237. package/dist/types/index.d.ts +241 -0
  238. package/dist/types/index.js +70 -0
  239. package/dist/types/streams.d.ts +495 -0
  240. package/dist/types/streams.js +11 -0
  241. package/dist/utils/asyncIterator.d.ts +41 -0
  242. package/dist/utils/asyncIterator.js +142 -0
  243. package/dist/utils/duration.d.ts +28 -0
  244. package/dist/utils/duration.js +47 -0
  245. package/dist/utils/mobx-setup.d.ts +42 -0
  246. package/dist/utils/mobx-setup.js +381 -0
  247. package/docs/api-keys.md +24 -0
  248. package/docs/api.md +230 -0
  249. package/docs/audit.md +81 -0
  250. package/docs/capabilities.md +163 -0
  251. package/docs/client-behavior.md +202 -0
  252. package/docs/data-sources.md +214 -0
  253. package/docs/examples/agent-human.md +84 -0
  254. package/docs/examples/ai-sdk-tool.md +92 -0
  255. package/docs/examples/existing-python-backend.md +249 -0
  256. package/docs/examples/nextjs.md +88 -0
  257. package/docs/examples/server-agent.md +86 -0
  258. package/docs/guarantees.md +148 -0
  259. package/docs/index.md +97 -0
  260. package/docs/integration-guide.md +493 -0
  261. package/docs/interaction-model.md +140 -0
  262. package/docs/mcp/claude-code.md +43 -0
  263. package/docs/mcp/cursor.md +53 -0
  264. package/docs/mcp/windsurf.md +46 -0
  265. package/docs/mcp.md +59 -0
  266. package/docs/quickstart.md +152 -0
  267. package/docs/react.md +115 -0
  268. package/docs/roadmap.md +45 -0
  269. package/examples/README.md +54 -0
  270. package/examples/data-source/README.md +102 -0
  271. package/examples/data-source/ablo-driver.ts +89 -0
  272. package/examples/data-source/customer-server.ts +208 -0
  273. package/examples/data-source/run.ts +101 -0
  274. package/examples/data-source/schema.ts +25 -0
  275. package/examples/quickstart.ts +54 -0
  276. package/examples/tsconfig.json +16 -0
  277. package/llms.txt +143 -0
  278. package/package.json +147 -0
@@ -0,0 +1,835 @@
1
+ /**
2
+ * Ablo — The one-liner consumer API.
3
+ *
4
+ * Hides all internal wiring (ObjectPool, Database, SyncClient, WebSocket,
5
+ * bootstrap, offline queue, DI adapters) behind a single function call.
6
+ *
7
+ * Usage:
8
+ * import { Ablo } from '@ablo/sync-engine/client';
9
+ * import { schema } from './schema';
10
+ *
11
+ * const sync = Ablo({ schema, apiKey: process.env.ABLO_API_KEY });
12
+ *
13
+ * const tasks = sync.tasks.list({ where: { status: 'todo' } });
14
+ * await sync.tasks.create({ title: 'Fix bug' });
15
+ * await sync.tasks.update(taskId, { status: 'done' });
16
+ * await sync.tasks.delete(taskId);
17
+ */
18
+ import type { Schema, SchemaRecord, InferModel, InferCreate } from '../schema/schema.js';
19
+ import type { SyncEngineConfig, SyncLogger, MutationExecutor, MutationDispatcher, SyncObservabilityProvider, SyncAnalytics, SessionErrorDetector, OnlineStatusProvider } from '../interfaces/index.js';
20
+ import { ObjectPool } from '../ObjectPool.js';
21
+ import type { SyncStoreContract } from '../react/context.js';
22
+ import type { SyncWebSocket } from '../sync/SyncWebSocket.js';
23
+ import { type SyncStatus } from '../BaseSyncedStore.js';
24
+ import type { IntentStream, PresenceStream, Snapshot } from '../types/streams.js';
25
+ import type { ParticipantManager } from '../sync/participants.js';
26
+ import type { ActiveIntent, Duration, TargetRange } from '../types/streams.js';
27
+ import { type AbloApi, type AbloApiClientOptions, type AbloApiIntents } from './ApiClient.js';
28
+ /**
29
+ * Handle returned by `engine.beginTurn()`. While alive, every commit
30
+ * automatically carries this turn's id on the wire. Call `close(stats?)`
31
+ * when the turn finishes, or `dispose()` to abandon without recording
32
+ * usage. Idempotent.
33
+ */
34
+ export interface Turn {
35
+ readonly turnId: string;
36
+ close(stats?: {
37
+ readonly costInputTokens?: number;
38
+ readonly costOutputTokens?: number;
39
+ readonly costComputeMs?: number;
40
+ }): Promise<void>;
41
+ dispose(): void;
42
+ [Symbol.asyncDispose](): Promise<void>;
43
+ }
44
+ /**
45
+ * Async function that resolves an apiKey at request time. Use for
46
+ * credential rotation — rotate from a vault, refresh from session
47
+ * storage, or pull from a Better Auth session. Mirrors Anthropic's
48
+ * `ApiKeySetter` exactly so any rotation pattern that works with
49
+ * `@anthropic-ai/sdk` works here.
50
+ *
51
+ * Re-exported from `./auth` so existing import paths (`@ablo/sync-engine`)
52
+ * keep resolving; the canonical definition lives there alongside the
53
+ * resolvers that consume it.
54
+ */
55
+ export type { ApiKeySetter } from './auth.js';
56
+ import type { ApiKeySetter } from './auth.js';
57
+ import { type AbloPersistence } from './persistence.js';
58
+ export interface AbloOptions<S extends SchemaRecord = SchemaRecord> {
59
+ /**
60
+ * API key used for authentication.
61
+ *
62
+ * Accepts a static string (`sk_live_...`) or an async function that
63
+ * resolves to one. Defaults to `process.env['ABLO_API_KEY']`.
64
+ */
65
+ apiKey?: string | ApiKeySetter | null | undefined;
66
+ /**
67
+ * Bearer auth token. Hosted-cloud consumers pass `apiKey`; self-hosted
68
+ * deployments may pass a bearer token minted by their own auth layer.
69
+ */
70
+ authToken?: string | null | undefined;
71
+ /**
72
+ * Override the Ablo API base URL. Defaults to hosted production and reads
73
+ * `process.env['ABLO_BASE_URL']` if unset.
74
+ */
75
+ baseURL?: string | null | undefined;
76
+ /** Per-request timeout in milliseconds. */
77
+ timeout?: number | undefined;
78
+ /** Number of retries for transient failures. */
79
+ maxRetries?: number | undefined;
80
+ /** Custom fetch implementation for tests, proxies, or non-standard runtimes. */
81
+ fetch?: typeof fetch | undefined;
82
+ /** Default headers sent with every API request. */
83
+ defaultHeaders?: Record<string, string | null | undefined> | undefined;
84
+ /** Default query parameters sent with every API request. */
85
+ defaultQuery?: Record<string, string | undefined> | undefined;
86
+ /**
87
+ * Client-side use is disabled by default because private API keys should
88
+ * not ship to browsers. Set this only when using a publishable/browser-safe
89
+ * key or a controlled server proxy.
90
+ */
91
+ dangerouslyAllowBrowser?: boolean | undefined;
92
+ /**
93
+ * TypeScript schema defined with `defineSchema()`. This enables typed
94
+ * resources such as `ablo.tasks.update(...)`.
95
+ */
96
+ schema: Schema<S>;
97
+ /**
98
+ * Local persistence mode. Defaults to `volatile`. Pass `indexeddb` only
99
+ * when you want offline queueing and a reload-surviving browser cache.
100
+ */
101
+ persistence?: AbloPersistence;
102
+ }
103
+ export interface InternalAbloOptions<S extends SchemaRecord = SchemaRecord> {
104
+ /**
105
+ * API key used for authentication.
106
+ *
107
+ * Accepts a static string (`sk_live_...`) or an async function that
108
+ * resolves to one. Defaults to `process.env['ABLO_API_KEY']`.
109
+ *
110
+ * When a function is provided, it's invoked before each request so
111
+ * you can rotate or refresh credentials at runtime. The function
112
+ * must return a non-empty string; otherwise an `AbloAuthenticationError`
113
+ * is thrown. If the function throws, the error is wrapped with the
114
+ * original available as `cause`.
115
+ *
116
+ * Mirrors Anthropic / OpenAI / Stripe SDK shape exactly.
117
+ */
118
+ apiKey?: string | ApiKeySetter | null | undefined;
119
+ /**
120
+ * Bearer auth token. Sent as `Authorization: Bearer <token>` on
121
+ * every request. Defaults to `process.env['ABLO_AUTH_TOKEN']`.
122
+ *
123
+ * Use this for self-hosted deployments where your auth layer mints
124
+ * cap tokens directly. Hosted-cloud consumers pass `apiKey` instead;
125
+ * the server handles cap-mint internally.
126
+ */
127
+ authToken?: string | null | undefined;
128
+ /**
129
+ * Override the default base URL. Defaults to
130
+ * `wss://mesh.ablo.finance` for hosted production; pass an explicit
131
+ * URL for self-hosted or staging (e.g. `wss://mesh-staging.ablo.finance`).
132
+ * Reads `process.env['ABLO_BASE_URL']` if unset.
133
+ */
134
+ baseURL?: string | null | undefined;
135
+ /**
136
+ * Maximum amount of time (ms) the client waits for a response
137
+ * before timing out a single request. Defaults to 10 minutes
138
+ * (600_000ms). Retried requests can wait longer in worst case.
139
+ */
140
+ timeout?: number | undefined;
141
+ /**
142
+ * Maximum number of times the client will retry a request on
143
+ * transient failure (5xx / 429 / network error). Defaults to 2.
144
+ * Honors `Retry-After` and `retry-after-ms` response headers.
145
+ */
146
+ maxRetries?: number | undefined;
147
+ /**
148
+ * Custom `fetch` implementation. Defaults to `globalThis.fetch`.
149
+ * Override for testing, custom transports, or runtime shims.
150
+ */
151
+ fetch?: typeof fetch | undefined;
152
+ /**
153
+ * Default headers to include with every request to the API.
154
+ * Removed per-request by setting the header to `null` in request
155
+ * options.
156
+ */
157
+ defaultHeaders?: Record<string, string | null | undefined> | undefined;
158
+ /**
159
+ * Default query parameters to include with every request.
160
+ * Removed per-request by setting the param to `undefined`.
161
+ */
162
+ defaultQuery?: Record<string, string | undefined> | undefined;
163
+ /**
164
+ * Client-side use of this SDK is disabled by default — your apiKey
165
+ * would ship to every visitor's network tab. Only set this to
166
+ * `true` if you've understood the risk and have appropriate
167
+ * mitigations (a publishable key, a server-side proxy, etc).
168
+ */
169
+ dangerouslyAllowBrowser?: boolean | undefined;
170
+ /**
171
+ * TypeScript schema defined with `defineSchema()`.
172
+ *
173
+ * The root `Ablo(...)` client is schema-first so consumers get typed
174
+ * model resources such as `ablo.tasks.update(...)`. Omit `schema`
175
+ * only for the advanced Resource / Intent / Commit client.
176
+ */
177
+ schema: Schema<S>;
178
+ /**
179
+ * @deprecated Server derives participant kind from the apiKey's
180
+ * scope. Pass apiKey only; this option will be removed once the
181
+ * server-internal cap-mint flow lands.
182
+ */
183
+ kind?: 'user' | 'agent' | 'system';
184
+ /**
185
+ * @deprecated Server derives user identity from the apiKey's
186
+ * scope (or from `Ablo-Acting-User` request header for B2B2C).
187
+ * Removed once Phase 3 ships.
188
+ */
189
+ user?: {
190
+ id: string;
191
+ teamIds?: string[];
192
+ };
193
+ /**
194
+ * @deprecated Server derives agent identity from the apiKey's
195
+ * scope. Removed once Phase 3 ships.
196
+ */
197
+ agentId?: string;
198
+ /**
199
+ * @deprecated Cap-mint moves server-internal in Phase 3. Pass
200
+ * `apiKey` only; the server handles capability issuance.
201
+ */
202
+ capabilityToken?: string;
203
+ /** Custom logger (default: console) */
204
+ logger?: SyncLogger;
205
+ /** ObjectPool size limit (default: 10000) */
206
+ maxPoolSize?: number;
207
+ /**
208
+ * Local persistence mode. Defaults to `volatile` so Ablo behaves like a
209
+ * point solution for shared state instead of silently bolting IndexedDB
210
+ * durability onto every browser consumer.
211
+ *
212
+ * Pass `persistence: 'indexeddb'` only when you want offline queueing
213
+ * and a reload-surviving local cache in a browser.
214
+ */
215
+ persistence?: AbloPersistence;
216
+ /** @deprecated Use `persistence: 'indexeddb'` for durable browser storage. */
217
+ offline?: boolean;
218
+ /**
219
+ * @deprecated Internal/testing escape hatch. Use `persistence` in
220
+ * production code. `true` maps to `volatile`; `false` maps to
221
+ * `indexeddb` in browsers.
222
+ */
223
+ inMemory?: boolean;
224
+ /**
225
+ * If true, initialization starts immediately in the background so
226
+ * `sync.tasks.findMany()` works after `await sync.ready()`.
227
+ *
228
+ * If false (default), the consumer MUST call `await sync.ready()` before
229
+ * using the engine — any query before that returns empty results.
230
+ *
231
+ * Default: false (explicit is better — prevents silent init failures).
232
+ */
233
+ autoStart?: boolean;
234
+ /**
235
+ * How aggressively this client should pull baseline state at
236
+ * startup.
237
+ *
238
+ * - `'full'`: pull every delta in the configured sync groups before
239
+ * `ready()` resolves. Default for `kind: 'user'`.
240
+ * - `'none'`: open the WS and process live deltas only — no baseline
241
+ * fetch. Reads round-trip via `resource.retrieve()`; subscriptions
242
+ * populate the pool lazily via covering deltas. Default for
243
+ * `kind: 'agent'` because agent-worker / routine runners don't
244
+ * need (or want) a local replica of the org's tenant plane.
245
+ */
246
+ bootstrapMode?: 'full' | 'none';
247
+ /**
248
+ * Custom observability provider (Sentry, Honeycomb, OTel, etc.).
249
+ * Default: a noop implementation that drops all breadcrumbs and spans.
250
+ */
251
+ observability?: SyncObservabilityProvider;
252
+ /**
253
+ * Custom analytics provider (PostHog, Amplitude, Segment, etc.).
254
+ * Default: a noop implementation that drops all events.
255
+ */
256
+ analytics?: SyncAnalytics;
257
+ /**
258
+ * Detect whether an error from a mutation/bootstrap response means the
259
+ * user's session has expired. Used to surface re-auth prompts. Default:
260
+ * heuristic that matches `401 Unauthorized` and a few common error shapes.
261
+ */
262
+ sessionErrorDetector?: SessionErrorDetector;
263
+ /**
264
+ * Detect whether the browser is currently online. Default: reads
265
+ * `navigator.onLine` and listens to the `online`/`offline` events.
266
+ */
267
+ onlineStatus?: OnlineStatusProvider;
268
+ /**
269
+ * Replace the built-in `MutationExecutor` (which posts a hardcoded
270
+ * `commit` method against `${url}/graphql`) with one that uses your own
271
+ * GraphQL client, auth headers, retry policy, and observability hooks.
272
+ *
273
+ * Default: a fetch-based executor that targets `${url}/graphql` with
274
+ * `credentials: 'include'` (cookie auth) when no `apiKey` is set.
275
+ */
276
+ mutationExecutor?: MutationExecutor;
277
+ /**
278
+ * Replace the built-in `MutationDispatcher` (used by the offline queue
279
+ * to replay mutations on reconnect). If you override `mutationExecutor`
280
+ * you almost always want to override this too so the two paths share
281
+ * the same auth/retry behavior.
282
+ *
283
+ * Default: a thin dispatcher that routes to the built-in executor.
284
+ */
285
+ mutationDispatcher?: MutationDispatcher;
286
+ /**
287
+ * Partial overrides for the auto-derived `SyncEngineConfig`. Merged on
288
+ * top of `deriveConfigFromSchema(schema)`. Use this when you need
289
+ * specific `modelCreatePriority`, `batchableModels`, or
290
+ * `essentialFields` settings that the schema cannot express.
291
+ */
292
+ configOverrides?: Partial<SyncEngineConfig>;
293
+ /**
294
+ * @deprecated Server derives sync groups from the apiKey's scope.
295
+ * Required today as a runtime holdover; removed once Phase 3 ships.
296
+ */
297
+ syncGroups?: string[];
298
+ /**
299
+ * Override the bootstrap endpoint base URL. Use this when your sync
300
+ * server's HTTP API lives on a different host than the WebSocket URL.
301
+ *
302
+ * Must include the `/api` prefix — `BootstrapHelper` appends
303
+ * `/sync/bootstrap` directly. Example:
304
+ * `'http://api.example.com/api'` → `http://api.example.com/api/sync/bootstrap`.
305
+ *
306
+ * Default: `${url.replace(/^ws/, 'http')}/api`.
307
+ */
308
+ bootstrapBaseUrl?: string;
309
+ /**
310
+ * Ablo-owned account scope. Required for Branch 3 identity resolution
311
+ * in `identity.ts` — without it the SDK falls through to the
312
+ * `/api/identity` HTTP-derived path (Branch 2).
313
+ */
314
+ organizationId?: string;
315
+ }
316
+ /**
317
+ * Operations available on each model in the sync engine.
318
+ *
319
+ * Naming aligns with Stripe / OpenAI / Anthropic conventions:
320
+ * `retrieve(id)` — single entity by id (sync, from local pool)
321
+ * `list({where})` — collection with filter (sync, from local pool)
322
+ * `count({where})` — count (sync, from local pool)
323
+ * `load({where})` — async hydrate through pool → IDB → network
324
+ * `create / update / delete` — optimistic writes
325
+ *
326
+ * The old verb set (`findById`, `findMany`, `findFirst`) is kept as
327
+ * deprecated aliases for one release cycle so consumers can migrate
328
+ * without a flag day.
329
+ */
330
+ export type { ModelCountOptions, ModelListOptions, ModelListScope, ModelLoadOptions, ModelEditHandle, ModelEditOptions, ModelOperations, } from './createModelProxy.js';
331
+ import type { ModelOperations } from './createModelProxy.js';
332
+ export type ResourceOperationAction = 'create' | 'update' | 'delete' | 'archive' | 'unarchive';
333
+ export type CommitWait = 'queued' | 'confirmed';
334
+ export interface ResourceTarget {
335
+ readonly resource: string;
336
+ readonly id: string;
337
+ readonly path?: string;
338
+ readonly range?: TargetRange;
339
+ readonly field?: string;
340
+ readonly meta?: Record<string, unknown>;
341
+ }
342
+ export interface ResourceIntent {
343
+ readonly id: string;
344
+ readonly actor: string;
345
+ readonly participantKind: ActiveIntent['participantKind'];
346
+ readonly action: string;
347
+ readonly field?: string;
348
+ readonly expiresAt: string;
349
+ readonly target: ResourceTarget;
350
+ }
351
+ export interface ResourceRead<T = Record<string, unknown>> {
352
+ readonly data: T;
353
+ readonly stamp: number;
354
+ readonly intents: readonly ResourceIntent[];
355
+ }
356
+ export type BusyPolicy = 'return' | 'wait' | 'fail';
357
+ export interface BusyOptions {
358
+ /**
359
+ * What to do when another participant has an active intent on the
360
+ * target. `return` includes the intents in the response, `wait`
361
+ * resolves after they clear, and `fail` throws `AbloBusyError`.
362
+ */
363
+ readonly ifBusy?: BusyPolicy;
364
+ /** Max time to wait for peer intents to clear, in milliseconds. */
365
+ readonly busyTimeout?: number;
366
+ /** HTTP API polling interval while waiting. WebSocket clients ignore it. */
367
+ readonly busyPollInterval?: number;
368
+ }
369
+ export interface IntentWaitOptions {
370
+ readonly timeout?: number;
371
+ readonly pollInterval?: number;
372
+ readonly signal?: AbortSignal;
373
+ }
374
+ export interface ResourceReadOptions extends BusyOptions {
375
+ }
376
+ export interface IntentCreateOptions {
377
+ readonly target: ResourceTarget;
378
+ readonly action: string;
379
+ readonly ttl?: Duration;
380
+ }
381
+ export interface IntentHandle extends AsyncDisposable {
382
+ readonly id: string;
383
+ release(): Promise<void>;
384
+ revoke(): void;
385
+ }
386
+ export interface CommitOperationInput {
387
+ readonly action: ResourceOperationAction;
388
+ readonly resource?: string;
389
+ readonly target?: ResourceTarget;
390
+ readonly id?: string | null;
391
+ readonly data?: Record<string, unknown> | null;
392
+ readonly transactionId?: string | null;
393
+ readonly readAt?: number | null;
394
+ readonly onStale?: 'reject' | 'force' | 'flag' | 'merge' | null;
395
+ }
396
+ export interface CommitCreateOptions {
397
+ readonly intent?: string | {
398
+ readonly id: string;
399
+ } | null;
400
+ readonly idempotencyKey?: string | null;
401
+ readonly readAt?: number | null;
402
+ readonly onStale?: 'reject' | 'force' | 'flag' | 'merge' | null;
403
+ readonly operation?: CommitOperationInput;
404
+ readonly operations?: readonly CommitOperationInput[];
405
+ readonly wait?: CommitWait;
406
+ readonly timeout?: number;
407
+ }
408
+ export interface CommitReceipt {
409
+ readonly id: string;
410
+ readonly status: CommitWait;
411
+ readonly lastSyncId?: number;
412
+ }
413
+ export interface CommitResource {
414
+ create(options: CommitCreateOptions): Promise<CommitReceipt>;
415
+ }
416
+ export interface IntentResource extends IntentStream {
417
+ create(options: IntentCreateOptions): Promise<IntentHandle>;
418
+ list(target?: Partial<ResourceTarget>): readonly ResourceIntent[];
419
+ waitFor(target: Partial<ResourceTarget>, options?: IntentWaitOptions): Promise<void>;
420
+ }
421
+ export interface ResourceMutationOptions extends BusyOptions {
422
+ readonly intent?: string | {
423
+ readonly id: string;
424
+ } | null;
425
+ readonly idempotencyKey?: string | null;
426
+ readonly readAt?: number | null;
427
+ readonly onStale?: 'reject' | 'force' | 'flag' | 'merge' | null;
428
+ readonly wait?: CommitWait;
429
+ readonly timeout?: number;
430
+ }
431
+ export interface ResourceClient<T = Record<string, unknown>> {
432
+ retrieve(id: string, options?: ResourceReadOptions): Promise<ResourceRead<T>>;
433
+ create(data: Record<string, unknown>, options?: ResourceMutationOptions & {
434
+ readonly id?: string | null;
435
+ }): Promise<CommitReceipt>;
436
+ update(id: string, data: Record<string, unknown>, options?: ResourceMutationOptions): Promise<CommitReceipt>;
437
+ delete(id: string, options?: ResourceMutationOptions): Promise<CommitReceipt>;
438
+ }
439
+ /** The typed sync engine client — one property per model in the schema */
440
+ export type Ablo<S extends SchemaRecord> = {
441
+ readonly [K in keyof S & string]: ModelOperations<InferModel<Schema<S>, K>, InferCreate<Schema<S>, K>>;
442
+ } & {
443
+ /**
444
+ * Wait for the sync engine to finish its initial bootstrap.
445
+ * Resolves once entity data is loaded and the WebSocket is connected.
446
+ *
447
+ * ```ts
448
+ * const sync = Ablo({ schema, user });
449
+ * await sync.ready();
450
+ * const tasks = sync.tasks.findMany(); // data is available
451
+ * ```
452
+ *
453
+ * If bootstrap fails, this rejects with the underlying error (unreachable
454
+ * server, invalid API key, 500 from bootstrap endpoint, etc.).
455
+ *
456
+ * Idempotent — calling it multiple times returns the same promise.
457
+ */
458
+ ready(): Promise<void>;
459
+ /**
460
+ * Wait for all pending mutations to be confirmed by the server.
461
+ *
462
+ * Sync engine mutations (`create`/`update`/`delete`) are optimistic and
463
+ * resolve immediately. Use this when you need to know the server has
464
+ * acknowledged everything before continuing — for example, before
465
+ * navigating away, before triggering a server-side workflow, or in tests.
466
+ *
467
+ * Resolves when `syncStatus.pendingChanges` reaches 0. If the engine is
468
+ * offline, this waits until reconnect + flush completes.
469
+ *
470
+ * ```ts
471
+ * await sync.tasks.create({ title: 'A' });
472
+ * await sync.tasks.create({ title: 'B' });
473
+ * await sync.waitForFlush(); // server has both tasks
474
+ * ```
475
+ *
476
+ * @param timeoutMs - Optional timeout. Default: no timeout (wait forever).
477
+ * Throws `Error('Flush timeout')` if reached with pending changes.
478
+ */
479
+ waitForFlush(timeoutMs?: number): Promise<void>;
480
+ /** Disconnect and clean up */
481
+ dispose(): Promise<void>;
482
+ /**
483
+ * Destroy every IndexedDB database owned by this engine. Disconnects
484
+ * the WebSocket, releases timers, and deletes all `ablo_*` / `ablo-*`
485
+ * databases. Use on session expiry or explicit logout. Best-effort.
486
+ */
487
+ purge(): Promise<void>;
488
+ /**
489
+ * Subscribe to session-error events (server rejected the session).
490
+ * Returns an unsubscribe function. Multiple subscribers supported.
491
+ * Typically called by `<AbloProvider>`, which calls `purge()` on fire
492
+ * and forwards to the consumer's `onSessionExpired` callback.
493
+ */
494
+ onSessionError(listener: (error: Error) => void): () => void;
495
+ /**
496
+ * Subscribe to mutation failures with the full payload (transaction,
497
+ * error, permanent flag). Use this for user-visible failure surfaces —
498
+ * toasts keyed by `AbloError.type`, route-level "this entity reverted"
499
+ * boundaries, telemetry. Fires for both permanent rejections and
500
+ * `max_retries_exhausted` rollbacks.
501
+ *
502
+ * Distinct from `onSessionError` (server killed the session, requires
503
+ * re-auth) and from the `tx.isPersisted` per-call promise (call-site
504
+ * await, single transaction). This is the app-wide fan-in.
505
+ */
506
+ onMutationFailure(listener: (payload: {
507
+ transaction: import('../transactions/TransactionQueue.js').Transaction;
508
+ error: Error;
509
+ permanent?: boolean;
510
+ }) => void): () => void;
511
+ /**
512
+ * Wait for the most-recent in-flight transaction for (modelName, modelId)
513
+ * to be confirmed by the server. Rejects with the same error that the
514
+ * queue's `transaction:failed` event would carry if the mutation is
515
+ * permanently rolled back. Resolves immediately when no transaction is
516
+ * in flight (already-confirmed or never-staged).
517
+ *
518
+ * Matches the queue's `'confirmed'` status vocabulary (see also
519
+ * `commits.create({wait:'confirmed'})`). Use this for the routing-
520
+ * grace-window pattern: stage a write, then
521
+ * `Promise.race([ablo.waitForConfirmation(...), gracePromise])` before
522
+ * navigating to a route whose URL depends on the optimistic id.
523
+ */
524
+ waitForConfirmation(modelName: string, modelId: string): Promise<void>;
525
+ /**
526
+ * Reactive sync status — a MobX observable.
527
+ *
528
+ * Single source of truth for "what's the sync engine doing?" Contains:
529
+ * - `state`: `'idle' | 'syncing' | 'error' | 'offline' | 'reconnecting'`
530
+ * - `progress`: 0-100 for bootstrap progress
531
+ * - `error?`: Error object when `state === 'error'`
532
+ * - `pendingChanges`: Number of unconfirmed mutations in the queue
533
+ * - `lastSyncAt?`: Timestamp of the last successful delta processing
534
+ * - `offlineSince?`: When the connection dropped
535
+ * - `isSessionError`: True when the error requires re-authentication
536
+ *
537
+ * React components using `observer()` re-render automatically when
538
+ * any field changes — no manual subscription or polling needed.
539
+ *
540
+ * ```tsx
541
+ * import { observer } from 'mobx-react-lite';
542
+ *
543
+ * const SyncIndicator = observer(() => {
544
+ * if (sync.syncStatus.state === 'syncing') return <Spinner />;
545
+ * if (sync.syncStatus.state === 'error') return <Error msg={sync.syncStatus.error} />;
546
+ * if (sync.syncStatus.state === 'offline') return <OfflineBadge />;
547
+ * return null;
548
+ * });
549
+ * ```
550
+ */
551
+ readonly syncStatus: SyncStatus;
552
+ /** The underlying schema */
553
+ readonly schema: Schema<S>;
554
+ /**
555
+ * Real-time presence livestream — who else is connected on this
556
+ * engine's sync groups, what they're doing, and a write surface for
557
+ * announcing this user's own activity. Rides the engine's existing
558
+ * WebSocket; opening a participant for presence does NOT open a
559
+ * second socket. See `PresenceStream` in `types/streams.ts`.
560
+ *
561
+ * Stable reference for the engine's lifetime — the underlying
562
+ * connection is rotated on `dispose()` but this object is the same.
563
+ */
564
+ readonly presence: PresenceStream;
565
+ /**
566
+ * Cooperative-mutex layer over presence — announce "I'm about to do
567
+ * X on Y" so peers can yield before colliding. Server enforces the
568
+ * mutex; rejected announcements surface via `intents.onRejected(...)`.
569
+ * Same socket as entity sync, no second connection.
570
+ */
571
+ readonly intents: IntentResource;
572
+ /**
573
+ * Canonical low-level mutation API. Every resource convenience write
574
+ * compiles down to `commits.create(...)`.
575
+ */
576
+ readonly commits: CommitResource;
577
+ /**
578
+ * Canonical untyped resource API. This is the portable API shape that maps
579
+ * cleanly to HTTP/Python/Ruby/Go clients. Typed `ablo.<model>` properties
580
+ * are schema-powered sugar over the same resource model.
581
+ */
582
+ resource<T = Record<string, unknown>>(name: string): ResourceClient<T>;
583
+ /**
584
+ * Canonical multiplayer participant surface. Joins a structured app
585
+ * target, derives the transport scope internally, opens a scoped
586
+ * claim on the existing WebSocket, and returns target-bound presence
587
+ * + intent helpers.
588
+ *
589
+ * ```ts
590
+ * const participant = await ablo.participants.join({
591
+ * type: 'File',
592
+ * id: 'src/foo.ts',
593
+ * path: 'src/foo.ts',
594
+ * range: { startLine: 10, endLine: 40 },
595
+ * });
596
+ * participant.presence.editing();
597
+ * const claim = participant.intents.claim('rewrite imports');
598
+ * ```
599
+ */
600
+ readonly participants: ParticipantManager;
601
+ /**
602
+ * Capture a context-staleness watermark over a set of entities.
603
+ * Returns a flat snapshot with `stamp` (thread into writes as
604
+ * `readAt`), `signal` (aborts on any captured-entity delta), and
605
+ * `onChange` (callback form). Reads from the engine's ObjectPool;
606
+ * subscription is on the engine's existing transport.
607
+ *
608
+ * Use before an LLM call to prevent the model from completing
609
+ * against now-stale data:
610
+ * ```ts
611
+ * const snap = engine.snapshot({ slides: deck.slideIds });
612
+ * await streamText({ messages, signal: snap.signal });
613
+ * ```
614
+ */
615
+ snapshot<ModelName extends keyof S & string>(entities: {
616
+ readonly [M in ModelName]: string | readonly string[];
617
+ }): Snapshot<Schema<S>, ModelName>;
618
+ /**
619
+ * Open a turn — every commit issued while the returned handle is
620
+ * alive carries `caused_by_task_id` on the wire so the server
621
+ * stamps it onto each delta. Powers `agent_tasks` audit trails.
622
+ * Server: `POST /api/agent/turn` with the capability bearer.
623
+ */
624
+ beginTurn(options: {
625
+ readonly prompt: string;
626
+ readonly parentTaskId?: string;
627
+ readonly surface?: string;
628
+ readonly metadata?: Record<string, unknown>;
629
+ }): Promise<Turn>;
630
+ /**
631
+ * The internal BaseSyncedStore. Implements SyncStoreContract — pass to
632
+ * SyncContext.Provider so the SDK's useModel/useModels/useMutations hooks
633
+ * can access it. Also satisfies useSyncStore() consumers during migration.
634
+ */
635
+ readonly _store: SyncStoreContract;
636
+ /** The ObjectPool — for demand loaders and direct pool operations. */
637
+ readonly _pool: ObjectPool;
638
+ /**
639
+ * The SyncWebSocket handle — for collaboration events (slide selection,
640
+ * cursor broadcast). Null until the engine connects.
641
+ */
642
+ readonly _ws: SyncWebSocket | null;
643
+ };
644
+ /**
645
+ * Compute a create-priority map from schema `belongsTo` relations using
646
+ * Tarjan's strongly-connected-components algorithm.
647
+ *
648
+ * The FK graph has an edge `child → parent` for every `belongsTo`. Tarjan
649
+ * runs a single linear DFS that simultaneously (a) detects cycles by
650
+ * grouping mutually-reachable nodes into SCCs and (b) emits those SCCs
651
+ * in reverse topological order of the condensation graph. In this edge
652
+ * convention a "sink" SCC has no outgoing edges — i.e. no parents — so
653
+ * it is an *FK root* (`organizations`, `themes`, etc.). Tarjan emits
654
+ * roots first and leaves last, exactly the order in which rows must be
655
+ * inserted to satisfy FK constraints.
656
+ *
657
+ * Priorities are assigned by emit order: SCC #0 → 10, SCC #1 → 20, …
658
+ * Members of the same SCC share a priority, so insertion order wins the
659
+ * tiebreak inside a cycle (this matters for cyclic schemas like
660
+ * `slideDecks ↔ layouts`, where one direction is the user's chosen
661
+ * "soft" edge — only the consumer's mutator sequence knows which one).
662
+ *
663
+ * This algorithm is iteration-order-independent: starting the DFS from
664
+ * any node yields the same SCC partitioning, and SCCs always come out
665
+ * in valid topological order. The previous DFS-with-memoization
666
+ * heuristic broke under cycles by treating the back-edge as depth 0,
667
+ * which made priorities depend on which node the walk happened to
668
+ * enter the cycle at.
669
+ *
670
+ * Schema authors can mark one side of a cycle with
671
+ * `belongsTo(target, fk, { defer: true })`. Those edges are excluded
672
+ * from the dependency graph entirely, which deterministically breaks
673
+ * the cycle and turns the SCC into a chain — the marked child gets a
674
+ * strictly higher priority than its parent instead of being tied with
675
+ * it. Pair with a Postgres `DEFERRABLE INITIALLY DEFERRED` constraint
676
+ * if you want the database side of the cycle to also relax. See
677
+ * {@link BelongsToOptions.defer}.
678
+ *
679
+ * The returned map is keyed by {@link ModelDef.typename} (falling back
680
+ * to the schema key), because that is what `Model.getModelName()`
681
+ * returns at transaction time — keying by schema key would silently
682
+ * miss the lookup and every model would fall through to
683
+ * `defaultCreatePriority`.
684
+ *
685
+ * Reference: Tarjan, R. (1972), "Depth-first search and linear graph
686
+ * algorithms." Linear in V + E.
687
+ */
688
+ export declare function computeFKDepthPriority(schema: Schema): ReadonlyMap<string, number>;
689
+ /**
690
+ * Create a sync engine client in one call.
691
+ *
692
+ * ```ts
693
+ * const sync = Ablo({ schema, apiKey: process.env.ABLO_API_KEY });
694
+ *
695
+ * const tasks = sync.tasks.list({ where: { status: 'todo' } });
696
+ * await sync.tasks.create({ title: 'New task' });
697
+ * ```
698
+ */
699
+ export declare function Ablo<const S extends SchemaRecord>(options: AbloOptions<S>): Ablo<S>;
700
+ export declare function Ablo(options: AbloApiClientOptions): AbloApi;
701
+ import type * as _Streams from '../types/streams.js';
702
+ import type * as _Participants from '../sync/participants.js';
703
+ import type * as _Policy from '../policy/types.js';
704
+ import type * as _Mutators from '../mutators/defineMutators.js';
705
+ import type * as _Tx from '../mutators/Transaction.js';
706
+ import type * as _Undo from '../mutators/UndoManager.js';
707
+ import type * as _SchemaTypes from '../schema/schema.js';
708
+ /**
709
+ * Canonical type namespace.
710
+ *
711
+ * Locked rules — apply uniformly to every future addition:
712
+ *
713
+ * 1. Flat by default. `Ablo.X`. Fewest dots wins.
714
+ * 2. Sub-namespace ONLY when (a) 4+ types share a single conceptual
715
+ * prefix, AND (b) names read better with the prefix (`Conflict.Kind`
716
+ * over `ConflictKind`). If the cluster is heterogeneous (streams +
717
+ * data + handles), keep flat.
718
+ * 3. Only types a consumer would write `: Ablo.X` for. Inferred-only
719
+ * types stay un-exported.
720
+ * 4. Wire shapes never on `Ablo.*`. Engine vocabulary only.
721
+ * 5. Advanced / framework-integration types stay internal unless they
722
+ * graduate into one of the public subpaths.
723
+ *
724
+ * Anything not on this list stays internal.
725
+ */
726
+ export declare namespace Ablo {
727
+ type Options<S extends SchemaRecord = SchemaRecord> = AbloOptions<S>;
728
+ type Api = AbloApi;
729
+ type ApiIntents = AbloApiIntents;
730
+ type Agent = import('./ApiClient.js').Agent;
731
+ type AgentOptions = import('./ApiClient.js').AgentOptions;
732
+ type AgentRunOptions = import('./ApiClient.js').AgentRunOptions;
733
+ type AgentRunStatus = import('./ApiClient.js').AgentRunStatus;
734
+ type AgentRunResult<T> = import('./ApiClient.js').AgentRunResult<T>;
735
+ type AgentRunContext = import('./ApiClient.js').AgentRunContext;
736
+ type AgentResourceClient<T = Record<string, unknown>> = import('./ApiClient.js').AgentResourceClient<T>;
737
+ type AgentResourceReadOptions = import('./ApiClient.js').AgentResourceReadOptions;
738
+ type AgentResourceMutationOptions = import('./ApiClient.js').AgentResourceMutationOptions;
739
+ type AgentIntentOptions = import('./ApiClient.js').AgentIntentOptions;
740
+ type AgentIntentInput = import('./ApiClient.js').AgentIntentInput;
741
+ type Capability = import('./ApiClient.js').Capability;
742
+ type CapabilityCreateOptions = import('./ApiClient.js').CapabilityCreateOptions;
743
+ type CapabilityRecord = import('./ApiClient.js').CapabilityRecord;
744
+ type CapabilityResource = import('./ApiClient.js').CapabilityResource;
745
+ type CapabilityRevocation = import('./ApiClient.js').CapabilityRevocation;
746
+ type Task = import('./ApiClient.js').Task;
747
+ type TaskCreateOptions = import('./ApiClient.js').TaskCreateOptions;
748
+ type TaskCloseOptions = import('./ApiClient.js').TaskCloseOptions;
749
+ type TaskCloseResult = import('./ApiClient.js').TaskCloseResult;
750
+ type TaskResource = import('./ApiClient.js').TaskResource;
751
+ type BusyPolicy = import('./Ablo.js').BusyPolicy;
752
+ type BusyOptions = import('./Ablo.js').BusyOptions;
753
+ type EntityRef = _Streams.EntityRef;
754
+ type PresenceTarget = _Streams.PresenceTarget;
755
+ type TargetRange = _Streams.TargetRange;
756
+ type Duration = _Streams.Duration;
757
+ type PresenceStream = _Streams.PresenceStream;
758
+ type IntentStream = _Streams.IntentStream;
759
+ type Peer = _Streams.Peer;
760
+ type Activity = _Streams.Activity;
761
+ type ActiveIntent = _Streams.ActiveIntent;
762
+ type Claim = _Streams.Claim;
763
+ type IntentRejection = _Streams.IntentRejection;
764
+ type Snapshot<TSchema extends _SchemaTypes.Schema = _SchemaTypes.Schema, K extends keyof TSchema['models'] = keyof TSchema['models']> = _Streams.Snapshot<TSchema, K>;
765
+ type Turn = import('./Ablo.js').Turn;
766
+ namespace Auth {
767
+ type Principal = _Streams.Principal;
768
+ type Session = _Streams.SessionRef;
769
+ type Agent = _Streams.AgentRef;
770
+ type Actor = _Streams.ParticipantRef;
771
+ }
772
+ namespace Participant {
773
+ type Manager = _Participants.ParticipantManager;
774
+ type Joined = _Participants.JoinedParticipant;
775
+ type Scope = _Participants.ParticipantScope;
776
+ type Status = _Participants.ParticipantStatus;
777
+ type JoinOptions = _Participants.ParticipantJoinOptions;
778
+ }
779
+ type Schema<S extends _SchemaTypes.SchemaRecord = _SchemaTypes.SchemaRecord> = _SchemaTypes.Schema<S>;
780
+ namespace Schema {
781
+ type InferModel<S extends _SchemaTypes.Schema, K extends keyof S['models']> = _SchemaTypes.InferModel<S, K>;
782
+ type InferCreate<S extends _SchemaTypes.Schema, K extends keyof S['models']> = _SchemaTypes.InferCreate<S, K>;
783
+ type InferModelNames<S extends _SchemaTypes.Schema> = _SchemaTypes.InferModelNames<S>;
784
+ }
785
+ type Conflict = _Policy.Conflict;
786
+ namespace Conflict {
787
+ type Kind = _Policy.ConflictKind;
788
+ type Operation = _Policy.ConflictOperation;
789
+ type Decision = _Policy.ConflictDecision;
790
+ type Policy = _Policy.ConflictPolicy;
791
+ }
792
+ namespace Commit {
793
+ type Wait = import('./Ablo.js').CommitWait;
794
+ type OperationAction = import('./Ablo.js').ResourceOperationAction;
795
+ type OperationInput = import('./Ablo.js').CommitOperationInput;
796
+ type CreateOptions = import('./Ablo.js').CommitCreateOptions;
797
+ type Receipt = import('./Ablo.js').CommitReceipt;
798
+ type Resource = import('./Ablo.js').CommitResource;
799
+ }
800
+ namespace Intent {
801
+ type Handle = import('./Ablo.js').IntentHandle;
802
+ type CreateOptions = import('./Ablo.js').IntentCreateOptions;
803
+ type WaitOptions = import('./Ablo.js').IntentWaitOptions;
804
+ type Resource = import('./Ablo.js').IntentResource;
805
+ }
806
+ namespace Resource {
807
+ type Target = import('./Ablo.js').ResourceTarget;
808
+ type Intent = import('./Ablo.js').ResourceIntent;
809
+ type Read<T = Record<string, unknown>> = import('./Ablo.js').ResourceRead<T>;
810
+ type Client<T = Record<string, unknown>> = import('./Ablo.js').ResourceClient<T>;
811
+ type ReadOptions = import('./Ablo.js').ResourceReadOptions;
812
+ type MutationOptions = import('./Ablo.js').ResourceMutationOptions;
813
+ }
814
+ namespace Source {
815
+ type Operation = import('../source/index.js').SourceOperation;
816
+ type Event = import('../source/index.js').SourceEvent;
817
+ type EventsResult = import('../source/index.js').SourceEventsResult;
818
+ type Scope = import('../source/index.js').SourceScope;
819
+ type Secret = import('../source/index.js').SourceSecret;
820
+ type Options<S extends _SchemaTypes.SchemaRecord = _SchemaTypes.SchemaRecord, TAuth = unknown> = import('../source/index.js').AbloSourceOptions<S, TAuth>;
821
+ type ModelHandlers<Row, CreateInput, TAuth = unknown> = import('../source/index.js').SourceModelHandlers<Row, CreateInput, TAuth>;
822
+ type SignatureVerificationResult = import('../source/index.js').SourceSignatureVerificationResult;
823
+ namespace Commit {
824
+ type Params<TAuth = unknown> = import('../source/index.js').SourceCommitParams<TAuth>;
825
+ type Result<Row = Record<string, unknown>> = import('../source/index.js').SourceCommitResult<Row>;
826
+ }
827
+ }
828
+ namespace Mutator {
829
+ type Fn<S extends _SchemaTypes.Schema, TArgs, TResult = void> = _Mutators.MutatorFn<S, TArgs, TResult>;
830
+ type Transaction<S extends _SchemaTypes.Schema> = _Tx.Transaction<S>;
831
+ type UndoEntry = _Undo.UndoEntry;
832
+ type UndoScope<S extends _SchemaTypes.Schema = _SchemaTypes.Schema> = _Undo.UndoScope<S>;
833
+ type InverseOp = _Undo.InverseOp;
834
+ }
835
+ }