@abloatai/ablo 0.25.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 (244) hide show
  1. package/AGENTS.md +5 -3
  2. package/CHANGELOG.md +20 -0
  3. package/README.md +3 -3
  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 +328 -262
  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/examples/existing-python-backend.md +3 -3
  220. package/docs/identity.md +4 -4
  221. package/docs/integration-guide.md +1 -1
  222. package/docs/react.md +1 -1
  223. package/docs/sessions.md +5 -7
  224. package/package.json +15 -13
  225. package/dist/client/index.d.ts +0 -36
  226. package/dist/client/index.js +0 -33
  227. package/dist/config/index.d.ts +0 -10
  228. package/dist/config/index.js +0 -12
  229. package/dist/interfaces/headless.d.ts +0 -95
  230. package/dist/interfaces/headless.js +0 -41
  231. package/dist/query/index.d.ts +0 -6
  232. package/dist/query/index.js +0 -5
  233. package/dist/realtime/index.d.ts +0 -10
  234. package/dist/realtime/index.js +0 -9
  235. package/dist/schema/plane.d.ts +0 -23
  236. package/dist/schema/plane.js +0 -19
  237. package/dist/server/next.d.ts +0 -51
  238. package/dist/server/next.js +0 -47
  239. package/dist/sync/OfflineFlush.d.ts +0 -9
  240. package/dist/sync/OfflineFlush.js +0 -22
  241. package/dist/sync/OfflineTransactionStore.d.ts +0 -37
  242. package/dist/sync/OfflineTransactionStore.js +0 -263
  243. package/dist/transactions/index.d.ts +0 -16
  244. package/dist/transactions/index.js +0 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abloatai/ablo",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "description": "The Collaboration Layer For AI Agents",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -108,11 +108,6 @@
108
108
  "import": "./dist/server/index.js",
109
109
  "default": "./dist/server/index.js"
110
110
  },
111
- "./server/next": {
112
- "types": "./dist/server/next.d.ts",
113
- "import": "./dist/server/next.js",
114
- "default": "./dist/server/next.js"
115
- },
116
111
  "./webhooks": {
117
112
  "types": "./dist/webhooks/index.d.ts",
118
113
  "import": "./dist/webhooks/index.js",
@@ -121,7 +116,6 @@
121
116
  },
122
117
  "files": [
123
118
  "dist",
124
- "!dist/internal/**",
125
119
  "!dist/__type_probe.*",
126
120
  "docs/*.md",
127
121
  "docs/examples/*.md",
@@ -139,7 +133,9 @@
139
133
  "build": "npm run clean && tsc -p tsconfig.build.json && npm run build:cli",
140
134
  "build:cli": "tsup --config tsup.cli.config.ts",
141
135
  "typecheck:cli": "tsc -p tsconfig.cli.json",
142
- "pack:check": "npm_config_cache=${TMPDIR:-/tmp}/ablo-npm-cache npm pack --dry-run",
136
+ "prepack": "node scripts/strip-source-condition.mjs",
137
+ "postpack": "node scripts/restore-source-condition.mjs",
138
+ "pack:check": "node scripts/pack-check.mjs",
143
139
  "lint": "npm run lint:imports && npm run lint:errors && npm run lint:docs && npm run lint:mintlify",
144
140
  "build:docs": "node scripts/build-mintlify-docs.mjs",
145
141
  "lint:mintlify": "node scripts/build-mintlify-docs.mjs --check",
@@ -147,6 +143,7 @@
147
143
  "generate:errors": "tsx scripts/generate-error-docs.mts",
148
144
  "lint:errors": "tsx scripts/check-error-docs.mts",
149
145
  "lint:docs": "node scripts/check-doc-drift.mjs",
146
+ "lint:eslint": "eslint . --cache",
150
147
  "lint:pkg": "publint",
151
148
  "prepublishOnly": "npm run build && npm run lint:pkg",
152
149
  "check:dist": "node scripts/check-dist-fresh.mjs",
@@ -191,7 +188,8 @@
191
188
  },
192
189
  "peerDependencies": {
193
190
  "react": "^19.0.0",
194
- "drizzle-orm": ">=0.44.0"
191
+ "drizzle-orm": ">=0.44.0",
192
+ "ai": "^6.0.0"
195
193
  },
196
194
  "peerDependenciesMeta": {
197
195
  "react": {
@@ -199,6 +197,9 @@
199
197
  },
200
198
  "drizzle-orm": {
201
199
  "optional": true
200
+ },
201
+ "ai": {
202
+ "optional": true
202
203
  }
203
204
  },
204
205
  "dependencies": {
@@ -211,21 +212,21 @@
211
212
  "devDependencies": {
212
213
  "@ai-sdk/provider": "^3.0.0",
213
214
  "@clack/prompts": "^0.11.0",
215
+ "@jest/globals": "^29.7.0",
214
216
  "@prisma/client": "^7.3.0",
215
217
  "@types/jest": "^29.5.0",
216
218
  "@types/node": "^22.0.0",
217
219
  "@types/react": "^19.0.0",
218
220
  "@types/uuid": "^10.0.0",
219
221
  "@testing-library/react": "^16.0.0",
220
- "@testing-library/jest-dom": "^6.6.0",
221
222
  "ai": "^6.0.0",
222
223
  "drizzle-orm": "^0.45.2",
224
+ "eslint-plugin-react-hooks": "^7.0.1",
223
225
  "fake-indexeddb": "^6.0.0",
224
226
  "fast-check": "^3.0.0",
227
+ "globals": "^16.5.0",
225
228
  "jest": "^29.7.0",
226
229
  "jest-environment-jsdom": "^29.7.0",
227
- "jiti": "^2.7.0",
228
- "mobx": "^6.13.7",
229
230
  "picocolors": "^1.1.0",
230
231
  "postgres": "^3.4.0",
231
232
  "react": "^19.0.0",
@@ -233,8 +234,9 @@
233
234
  "ts-jest": "^29.4.0",
234
235
  "ts-morph": "^26.0.0",
235
236
  "tsup": "^8.0.0",
237
+ "tsx": "^4.19.0",
236
238
  "typescript": "^5.8.3",
237
239
  "publint": "^0.3.21",
238
- "yjs": "^13.6.29"
240
+ "ws": "^8.18.0"
239
241
  }
240
242
  }
@@ -1,36 +0,0 @@
1
- /**
2
- * @abloatai/ablo/client — Consumer API
3
- *
4
- * The one-liner entry point for external consumers.
5
- *
6
- * `Ablo({ apiKey })` is the stateless HTTP API client. Add `schema`
7
- * when you want the realtime sync engine with typed model proxies.
8
- *
9
- * ```ts
10
- * import { Ablo } from '@abloatai/ablo/client';
11
- * import { schema } from './schema';
12
- *
13
- * const ablo = Ablo({
14
- * schema,
15
- * apiKey: process.env.ABLO_API_KEY,
16
- * });
17
- *
18
- * const reports = ablo.weatherReports.list({ where: { status: 'pending' } });
19
- * await ablo.weatherReports.create({ location: 'Stockholm', status: 'pending' });
20
- * ```
21
- *
22
- * For headless agents (workers, bots), pass the same schema and an API key
23
- * scoped for that server runtime:
24
- *
25
- * ```ts
26
- * const bot = Ablo({
27
- * schema,
28
- * apiKey: process.env.ABLO_API_KEY,
29
- * });
30
- * ```
31
- */
32
- export { Ablo, computeFKDepthPriority, type AbloOptions, type InternalAbloOptions, type ClaimedOptions, type IfClaimedPolicy, type ClaimWaitOptions, type LocalCountOptions, type LocalReadOptions, type ModelListScope, type ServerReadOptions, type ModelOperations, type ModelReadOptions, } from './Ablo.js';
33
- export { ABLO_DEFAULT_BASE_URL, ABLO_HOSTED_API_DOMAIN, ABLO_HOSTED_HTTP_BASE_URL, normalizeAbloHostedBaseUrl, } from './auth.js';
34
- export type { AbloPersistence } from './persistence.js';
35
- export type { AbloApi, AbloApiClientOptions, AbloApiClaims, Capability, CapabilityCreateOptions, CapabilityParticipantKind, CapabilityRecord, CapabilityResource, CapabilityRevocation, CapabilityScope, } from './ApiClient.js';
36
- export type { EngineParticipant, JoinedParticipant, ParticipantJoinOptions, ParticipantManager, ParticipantScope, ParticipantStatus, ScopedClaims, ScopedPresence, } from '../sync/participants.js';
@@ -1,33 +0,0 @@
1
- /**
2
- * @abloatai/ablo/client — Consumer API
3
- *
4
- * The one-liner entry point for external consumers.
5
- *
6
- * `Ablo({ apiKey })` is the stateless HTTP API client. Add `schema`
7
- * when you want the realtime sync engine with typed model proxies.
8
- *
9
- * ```ts
10
- * import { Ablo } from '@abloatai/ablo/client';
11
- * import { schema } from './schema';
12
- *
13
- * const ablo = Ablo({
14
- * schema,
15
- * apiKey: process.env.ABLO_API_KEY,
16
- * });
17
- *
18
- * const reports = ablo.weatherReports.list({ where: { status: 'pending' } });
19
- * await ablo.weatherReports.create({ location: 'Stockholm', status: 'pending' });
20
- * ```
21
- *
22
- * For headless agents (workers, bots), pass the same schema and an API key
23
- * scoped for that server runtime:
24
- *
25
- * ```ts
26
- * const bot = Ablo({
27
- * schema,
28
- * apiKey: process.env.ABLO_API_KEY,
29
- * });
30
- * ```
31
- */
32
- export { Ablo, computeFKDepthPriority, } from './Ablo.js';
33
- export { ABLO_DEFAULT_BASE_URL, ABLO_HOSTED_API_DOMAIN, ABLO_HOSTED_HTTP_BASE_URL, normalizeAbloHostedBaseUrl, } from './auth.js';
@@ -1,10 +0,0 @@
1
- /**
2
- * @abloatai/ablo/config — App initialization
3
- *
4
- * One-time setup at app boot. Provides DI interface types
5
- * and the initSyncEngine() function to wire real implementations.
6
- */
7
- export { initSyncEngine, resetSyncEngine, isSyncEngineInitialized } from '../context.js';
8
- export { noopLogger, noopObservability, noopAnalytics, browserOnlineStatus, defaultSessionErrorDetector, emptyConfig, type SyncEngineContext, } from '../SyncEngineContext.js';
9
- export type { SyncEngineConfig, SyncLogger, SyncObservabilityProvider, SyncAnalytics, MutationExecutor, MutationDispatcher, SessionErrorDetector, OnlineStatusProvider, CommitResult, MutationOperation, BreadcrumbLevel, SyncBreadcrumbCategory, TransactionFailureDetails, BootstrapFailureDetails, WebSocketErrorDetails, RollbackDetails, SpanAttributes, } from '../interfaces/index.js';
10
- export { SyncSessionError } from '../errors.js';
@@ -1,12 +0,0 @@
1
- /**
2
- * @abloatai/ablo/config — App initialization
3
- *
4
- * One-time setup at app boot. Provides DI interface types
5
- * and the initSyncEngine() function to wire real implementations.
6
- */
7
- // Context lifecycle
8
- export { initSyncEngine, resetSyncEngine, isSyncEngineInitialized } from '../context.js';
9
- // Context type + no-op defaults (for testing or gradual adoption)
10
- export { noopLogger, noopObservability, noopAnalytics, browserOnlineStatus, defaultSessionErrorDetector, emptyConfig, } from '../SyncEngineContext.js';
11
- // Errors
12
- export { SyncSessionError } from '../errors.js';
@@ -1,95 +0,0 @@
1
- /**
2
- * Headless DI interfaces — the three abstractions createSyncEngine needs
3
- * to run in Node.js without browser globals.
4
- *
5
- * STATUS: Type stubs only. No implementation yet. These interfaces are
6
- * the deliverable of Path C Phase 1. When all three have both a browser
7
- * implementation and a Node implementation, the SDK is truly headless.
8
- *
9
- * Usage (once implemented):
10
- *
11
- * // Browser (default — no DI needed, uses browser globals)
12
- * const engine = createSyncEngine({ url, userId, organizationId });
13
- *
14
- * // Node.js / agent / sidecar (headless — DI overrides)
15
- * import { inMemoryStorage, alwaysOnline } from '@abloatai/ablo/headless';
16
- * const engine = createSyncEngine({
17
- * url, userId, organizationId,
18
- * storage: inMemoryStorage(),
19
- * network: alwaysOnline(),
20
- * });
21
- *
22
- * The `transport` override is optional because Node 22 has a built-in
23
- * global `WebSocket` class. It's included for testing (mock WebSocket)
24
- * and for environments where the built-in WebSocket isn't available
25
- * (Node 20, Deno, Bun — each has its own WebSocket story).
26
- *
27
- * See also: apps/sync-server/src/sdk-headless-entrypoint.test.ts
28
- * (the skipped tests that become the acceptance tests for Phase 1)
29
- */
30
- /** A record in an object store. */
31
- export type StorageRecord = Record<string, unknown> & {
32
- id: string;
33
- };
34
- /** An object store — analogous to an IDBObjectStore. */
35
- export interface ObjectStore {
36
- get(id: string): Promise<StorageRecord | undefined>;
37
- getAll(): Promise<StorageRecord[]>;
38
- getAllFromIndex(indexName: string, value: string): Promise<StorageRecord[]>;
39
- put(record: StorageRecord): Promise<void>;
40
- delete(id: string): Promise<void>;
41
- clear(): Promise<void>;
42
- }
43
- /** A database — analogous to an IDBDatabase. */
44
- export interface StorageDatabase {
45
- getStore(name: string): ObjectStore | undefined;
46
- close(): void;
47
- }
48
- /**
49
- * Opens or creates a named database.
50
- *
51
- * Browser: wraps indexedDB.open(name, version)
52
- * Node: returns an in-memory database backed by Maps
53
- */
54
- export interface StorageProvider {
55
- open(name: string, version?: number): Promise<StorageDatabase>;
56
- delete(name: string): Promise<void>;
57
- }
58
- export interface NetworkProvider {
59
- /** Current online status. */
60
- isOnline(): boolean;
61
- /**
62
- * Subscribe to online/offline transitions. Returns an unsubscribe function.
63
- * The callback receives `true` when coming online, `false` when going offline.
64
- *
65
- * Browser: listens for window 'online'/'offline' events + visibilitychange
66
- * Node: never fires (always online)
67
- * Test: fires when the test calls setOnline(true/false)
68
- */
69
- onStatusChange(callback: (online: boolean) => void): () => void;
70
- }
71
- /** Minimal WebSocket interface that SyncWebSocket uses. */
72
- export interface WebSocketLike {
73
- readonly readyState: number;
74
- readonly bufferedAmount: number;
75
- send(data: string | ArrayBuffer): void;
76
- close(code?: number, reason?: string): void;
77
- ping?(): void;
78
- addEventListener(type: 'open', handler: () => void): void;
79
- addEventListener(type: 'close', handler: (event: {
80
- code: number;
81
- reason: string;
82
- }) => void): void;
83
- addEventListener(type: 'message', handler: (event: {
84
- data: unknown;
85
- }) => void): void;
86
- addEventListener(type: 'error', handler: (event: unknown) => void): void;
87
- removeEventListener(type: string, handler: (...args: unknown[]) => void): void;
88
- }
89
- export interface TransportProvider {
90
- /**
91
- * Create a WebSocket connection to the given URL.
92
- * Returns an object satisfying the WebSocketLike interface.
93
- */
94
- connect(url: string): WebSocketLike;
95
- }
@@ -1,41 +0,0 @@
1
- /**
2
- * Headless DI interfaces — the three abstractions createSyncEngine needs
3
- * to run in Node.js without browser globals.
4
- *
5
- * STATUS: Type stubs only. No implementation yet. These interfaces are
6
- * the deliverable of Path C Phase 1. When all three have both a browser
7
- * implementation and a Node implementation, the SDK is truly headless.
8
- *
9
- * Usage (once implemented):
10
- *
11
- * // Browser (default — no DI needed, uses browser globals)
12
- * const engine = createSyncEngine({ url, userId, organizationId });
13
- *
14
- * // Node.js / agent / sidecar (headless — DI overrides)
15
- * import { inMemoryStorage, alwaysOnline } from '@abloatai/ablo/headless';
16
- * const engine = createSyncEngine({
17
- * url, userId, organizationId,
18
- * storage: inMemoryStorage(),
19
- * network: alwaysOnline(),
20
- * });
21
- *
22
- * The `transport` override is optional because Node 22 has a built-in
23
- * global `WebSocket` class. It's included for testing (mock WebSocket)
24
- * and for environments where the built-in WebSocket isn't available
25
- * (Node 20, Deno, Bun — each has its own WebSocket story).
26
- *
27
- * See also: apps/sync-server/src/sdk-headless-entrypoint.test.ts
28
- * (the skipped tests that become the acceptance tests for Phase 1)
29
- */
30
- export {};
31
- // ── Factory functions (to be implemented in Phase 1) ─────────────────────
32
- //
33
- // These will be the public API that headless consumers import:
34
- //
35
- // import { inMemoryStorage, alwaysOnline } from '@abloatai/ablo/headless';
36
- //
37
- // Stubs below show the intended signatures. Implementation is Phase 1 work.
38
- // export function inMemoryStorage(): StorageProvider { ... }
39
- // export function alwaysOnline(): NetworkProvider { ... }
40
- // export function nodeWebSocket(): TransportProvider { ... }
41
- // export function controllableNetwork(): NetworkProvider & { setOnline(v: boolean): void } { ... }
@@ -1,6 +0,0 @@
1
- /**
2
- * Query module barrel — re-exports the public surface for convenience.
3
- * See types.ts and client.ts for the actual definitions.
4
- */
5
- export type { Query, QueryBatch, QueryBatchResult } from './types.js';
6
- export { postQuery, type PostQueryOptions } from './client.js';
@@ -1,5 +0,0 @@
1
- /**
2
- * Query module barrel — re-exports the public surface for convenience.
3
- * See types.ts and client.ts for the actual definitions.
4
- */
5
- export { postQuery } from './client.js';
@@ -1,10 +0,0 @@
1
- /**
2
- * Internal compatibility entrypoint for the schema-powered realtime client.
3
- *
4
- * Use this build for applications that need typed model proxies,
5
- * subscriptions, presence, offline queueing, and a long-lived WebSocket.
6
- */
7
- export { Ablo, computeFKDepthPriority } from '../client/Ablo.js';
8
- export type { AbloOptions, InternalAbloOptions, LocalCountOptions, LocalReadOptions, ModelListScope, ServerReadOptions, ModelOperations, } from '../client/Ablo.js';
9
- import { Ablo } from '../client/Ablo.js';
10
- export default Ablo;
@@ -1,9 +0,0 @@
1
- /**
2
- * Internal compatibility entrypoint for the schema-powered realtime client.
3
- *
4
- * Use this build for applications that need typed model proxies,
5
- * subscriptions, presence, offline queueing, and a long-lived WebSocket.
6
- */
7
- export { Ablo, computeFKDepthPriority } from '../client/Ablo.js';
8
- import { Ablo } from '../client/Ablo.js';
9
- export default Ablo;
@@ -1,23 +0,0 @@
1
- /**
2
- * Database PLANE — which database a model's rows live in. A sibling axis to
3
- * `tenancy` (which says how rows are isolated *within* a database):
4
- *
5
- * - `tenant` — the tenant data plane. For a BYO/dedicated customer this is
6
- * THEIR database; provisioning emits these tables there.
7
- * - `control` — Ablo's control plane (the sync log, attribution, audit, …).
8
- * Never emitted into a customer DB; lives only in Ablo's own DB.
9
- *
10
- * P1 of the sync-delta decomposition (`docs/plans/sync-delta-zod-decomposition.md`):
11
- * declaring the boundary lets BYO provisioning *derive* "what a customer DB gets"
12
- * (`plane === 'tenant'`) instead of hand-coding it. Defaults to `tenant` —
13
- * today every `defineSchema` model is the customer's own data; only Ablo's
14
- * internal tables (once modeled in P2) declare `control`.
15
- */
16
- import { z } from 'zod';
17
- export declare const planeSchema: z.ZodEnum<{
18
- tenant: "tenant";
19
- control: "control";
20
- }>;
21
- export type SchemaPlane = z.infer<typeof planeSchema>;
22
- /** Default plane for a model that doesn't declare one — the tenant data plane. */
23
- export declare const DEFAULT_PLANE: SchemaPlane;
@@ -1,19 +0,0 @@
1
- /**
2
- * Database PLANE — which database a model's rows live in. A sibling axis to
3
- * `tenancy` (which says how rows are isolated *within* a database):
4
- *
5
- * - `tenant` — the tenant data plane. For a BYO/dedicated customer this is
6
- * THEIR database; provisioning emits these tables there.
7
- * - `control` — Ablo's control plane (the sync log, attribution, audit, …).
8
- * Never emitted into a customer DB; lives only in Ablo's own DB.
9
- *
10
- * P1 of the sync-delta decomposition (`docs/plans/sync-delta-zod-decomposition.md`):
11
- * declaring the boundary lets BYO provisioning *derive* "what a customer DB gets"
12
- * (`plane === 'tenant'`) instead of hand-coding it. Defaults to `tenant` —
13
- * today every `defineSchema` model is the customer's own data; only Ablo's
14
- * internal tables (once modeled in P2) declare `control`.
15
- */
16
- import { z } from 'zod';
17
- export const planeSchema = z.enum(['tenant', 'control']);
18
- /** Default plane for a model that doesn't declare one — the tenant data plane. */
19
- export const DEFAULT_PLANE = 'tenant';
@@ -1,51 +0,0 @@
1
- /**
2
- * `@abloatai/ablo/server/next` — mount Ablo's HTTP surface in a consumer's
3
- * Next.js App Router, the Better-Auth `toNextJsHandler` way:
4
- *
5
- * ```ts
6
- * // app/api/ablo/[...all]/route.ts
7
- * import { toAbloHandler } from '@abloatai/ablo/server/next';
8
- * import { ablo } from '@/lib/ablo'; // your configured Ablo HTTP app
9
- * export const { GET, POST } = toAbloHandler(ablo);
10
- * ```
11
- *
12
- * Ablo's HTTP endpoints (bootstrap / query / the commit fallback) are stateless
13
- * request→response, so they drop straight into a route handler. The realtime
14
- * WebSocket channel is deliberately NOT served here — it is a persistent
15
- * connection a serverless route handler cannot host, and stays an Ablo-hosted
16
- * (or long-running Node) service. That is the HTTP/WSS split the architecture
17
- * draws on purpose (see docs/plans/sync-gateway-audit-log-architecture.md).
18
- *
19
- * The package owns this MOUNT PRIMITIVE; the host owns the infra-bound app it
20
- * wraps (the Hono app holding the Hub + routes + auth). Mirrors Better Auth,
21
- * where `betterAuth()` builds the `.handler` and `toNextJsHandler` just maps it
22
- * onto the HTTP verbs.
23
- */
24
- /**
25
- * Anything that resolves a Web `Request` to a `Response` — e.g. a Hono app's
26
- * `.fetch`, a Better-Auth-style `{ handler }`, or a bare function.
27
- */
28
- export type AbloFetchHandler = (request: Request) => Response | Promise<Response>;
29
- /** The shapes `toAbloHandler` accepts: a Hono-style `{ fetch }`, a
30
- * `{ handler }`, or a bare `(Request) => Response`. */
31
- export type AbloHttpApp = {
32
- readonly fetch: AbloFetchHandler;
33
- } | {
34
- readonly handler: AbloFetchHandler;
35
- } | AbloFetchHandler;
36
- /** The route-handler object a Next.js App Router `route.ts` re-exports. One
37
- * handler bound to every method the `[...all]` catch-all may receive. */
38
- export interface AbloRouteHandlers {
39
- readonly GET: AbloFetchHandler;
40
- readonly POST: AbloFetchHandler;
41
- readonly PATCH: AbloFetchHandler;
42
- readonly PUT: AbloFetchHandler;
43
- readonly DELETE: AbloFetchHandler;
44
- readonly OPTIONS: AbloFetchHandler;
45
- }
46
- /**
47
- * Wrap a configured Ablo HTTP app into Next.js App Router route handlers.
48
- * Mirrors Better Auth's `toNextJsHandler` — accepts the app's `fetch`/`handler`
49
- * (or a bare function) and returns one handler per verb.
50
- */
51
- export declare function toAbloHandler(app: AbloHttpApp): AbloRouteHandlers;
@@ -1,47 +0,0 @@
1
- /**
2
- * `@abloatai/ablo/server/next` — mount Ablo's HTTP surface in a consumer's
3
- * Next.js App Router, the Better-Auth `toNextJsHandler` way:
4
- *
5
- * ```ts
6
- * // app/api/ablo/[...all]/route.ts
7
- * import { toAbloHandler } from '@abloatai/ablo/server/next';
8
- * import { ablo } from '@/lib/ablo'; // your configured Ablo HTTP app
9
- * export const { GET, POST } = toAbloHandler(ablo);
10
- * ```
11
- *
12
- * Ablo's HTTP endpoints (bootstrap / query / the commit fallback) are stateless
13
- * request→response, so they drop straight into a route handler. The realtime
14
- * WebSocket channel is deliberately NOT served here — it is a persistent
15
- * connection a serverless route handler cannot host, and stays an Ablo-hosted
16
- * (or long-running Node) service. That is the HTTP/WSS split the architecture
17
- * draws on purpose (see docs/plans/sync-gateway-audit-log-architecture.md).
18
- *
19
- * The package owns this MOUNT PRIMITIVE; the host owns the infra-bound app it
20
- * wraps (the Hono app holding the Hub + routes + auth). Mirrors Better Auth,
21
- * where `betterAuth()` builds the `.handler` and `toNextJsHandler` just maps it
22
- * onto the HTTP verbs.
23
- */
24
- function resolveFetch(app) {
25
- if (typeof app === 'function')
26
- return app;
27
- if ('fetch' in app)
28
- return app.fetch;
29
- return app.handler;
30
- }
31
- /**
32
- * Wrap a configured Ablo HTTP app into Next.js App Router route handlers.
33
- * Mirrors Better Auth's `toNextJsHandler` — accepts the app's `fetch`/`handler`
34
- * (or a bare function) and returns one handler per verb.
35
- */
36
- export function toAbloHandler(app) {
37
- const fetch = resolveFetch(app);
38
- const handler = (request) => fetch(request);
39
- return {
40
- GET: handler,
41
- POST: handler,
42
- PATCH: handler,
43
- PUT: handler,
44
- DELETE: handler,
45
- OPTIONS: handler,
46
- };
47
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * OfflineFlush — Replays queued offline mutations on reconnect.
3
- *
4
- * SDK-generic version: delegates to MutationDispatcher from context.
5
- */
6
- export declare function flushOfflineQueueOnce(): Promise<{
7
- processed: number;
8
- failed: number;
9
- }>;
@@ -1,22 +0,0 @@
1
- /**
2
- * OfflineFlush — Replays queued offline mutations on reconnect.
3
- *
4
- * SDK-generic version: delegates to MutationDispatcher from context.
5
- */
6
- import { OfflineTransactionStore } from './OfflineTransactionStore.js';
7
- import { getContext } from '../context.js';
8
- let _offlineTxStore = null;
9
- function getOfflineTxStore() {
10
- if (!_offlineTxStore) {
11
- _offlineTxStore = new OfflineTransactionStore();
12
- }
13
- return _offlineTxStore;
14
- }
15
- export async function flushOfflineQueueOnce() {
16
- const store = getOfflineTxStore();
17
- await store.init();
18
- const dispatcher = getContext().mutationDispatcher;
19
- return store.flush(async (tx) => {
20
- await dispatcher.dispatch(tx.opName, tx.request.variables || {});
21
- });
22
- }
@@ -1,37 +0,0 @@
1
- export declare enum Priority {
2
- CRITICAL = 0,
3
- HIGH = 1,
4
- NORMAL = 2,
5
- LOW = 3
6
- }
7
- export type OfflineTransaction = {
8
- id: string;
9
- opName: string;
10
- priority: Priority;
11
- createdAt: number;
12
- dependsOn?: string[];
13
- request: {
14
- gqlId?: string;
15
- document?: string;
16
- variables?: Record<string, any>;
17
- headers?: Record<string, string>;
18
- method?: string;
19
- url?: string;
20
- body?: any;
21
- };
22
- };
23
- export declare class OfflineTransactionStore {
24
- private db;
25
- private key;
26
- init(): Promise<void>;
27
- enqueue(tx: Omit<OfflineTransaction, 'createdAt'>): Promise<string>;
28
- listAll(): Promise<OfflineTransaction[]>;
29
- getOptimizedSyncOrder(): Promise<OfflineTransaction[]>;
30
- remove(id: string): Promise<void>;
31
- clear(): Promise<void>;
32
- flush(processor: (tx: OfflineTransaction) => Promise<void>): Promise<{
33
- processed: number;
34
- failed: number;
35
- }>;
36
- }
37
- export declare const offlineTxStore: OfflineTransactionStore;