@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.
- package/AGENTS.md +5 -3
- package/CHANGELOG.md +33 -0
- package/README.md +45 -36
- package/dist/BaseSyncedStore.d.ts +72 -195
- package/dist/BaseSyncedStore.js +240 -625
- package/dist/Database.d.ts +8 -9
- package/dist/Database.js +9 -14
- package/dist/LazyReferenceCollection.js +5 -0
- package/dist/Model.js +6 -8
- package/dist/ModelRegistry.d.ts +25 -6
- package/dist/ModelRegistry.js +12 -6
- package/dist/NetworkMonitor.js +1 -1
- package/dist/ObjectPool.js +9 -3
- package/dist/SyncClient.d.ts +15 -5
- package/dist/SyncClient.js +152 -66
- package/dist/SyncEngineContext.d.ts +1 -3
- package/dist/SyncEngineContext.js +1 -2
- package/dist/agent/Agent.d.ts +21 -8
- package/dist/agent/Agent.js +26 -13
- package/dist/ai-sdk/coordination-context.js +9 -3
- package/dist/ai-sdk/wrap.d.ts +1 -1
- package/dist/ai-sdk/wrap.js +1 -1
- package/dist/auth/credentialPolicy.d.ts +10 -2
- package/dist/auth/credentialSource.d.ts +1 -13
- package/dist/auth/credentialSource.js +6 -13
- package/dist/auth/index.js +3 -3
- package/dist/cli.cjs +583 -287
- package/dist/client/Ablo.d.ts +35 -764
- package/dist/client/Ablo.js +64 -688
- package/dist/client/ApiClient.d.ts +14 -1
- package/dist/client/ApiClient.js +63 -9
- package/dist/client/auth.d.ts +8 -17
- package/dist/client/auth.js +42 -6
- package/dist/client/consoleLogger.d.ts +36 -0
- package/dist/client/consoleLogger.js +45 -0
- package/dist/client/createInternalComponents.js +1 -1
- package/dist/client/createModelProxy.js +10 -6
- package/dist/client/credentialEndpoint.d.ts +63 -0
- package/dist/client/credentialEndpoint.js +87 -0
- package/dist/client/hostedEndpoints.d.ts +24 -0
- package/dist/client/hostedEndpoints.js +24 -0
- package/dist/client/httpClient.d.ts +1 -1
- package/dist/client/identity.js +2 -1
- package/dist/client/modelRegistration.d.ts +14 -0
- package/dist/client/modelRegistration.js +321 -0
- package/dist/client/options.d.ts +396 -0
- package/dist/client/options.js +10 -0
- package/dist/client/resourceTypes.d.ts +344 -0
- package/dist/client/resourceTypes.js +13 -0
- package/dist/client/schemaConfig.d.ts +56 -0
- package/dist/client/schemaConfig.js +188 -0
- package/dist/client/sessionMint.d.ts +1 -1
- package/dist/client/validateAbloOptions.js +1 -1
- package/dist/client/wsMutationExecutor.d.ts +33 -0
- package/dist/client/wsMutationExecutor.js +77 -0
- package/dist/context.js +0 -3
- package/dist/coordination/index.d.ts +8 -1
- package/dist/coordination/index.js +24 -1
- package/dist/coordination/trace.d.ts +0 -1
- package/dist/coordination/trace.js +0 -1
- package/dist/core/DatabaseManager.d.ts +0 -1
- package/dist/core/DatabaseManager.js +26 -24
- package/dist/core/QueryProcessor.js +7 -8
- package/dist/core/QueryView.d.ts +14 -2
- package/dist/core/QueryView.js +4 -5
- package/dist/core/StoreManager.d.ts +2 -2
- package/dist/core/StoreManager.js +5 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/openIDBWithTimeout.js +15 -11
- package/dist/core/query-utils.js +1 -1
- package/dist/core/storeContract.d.ts +143 -0
- package/dist/core/storeContract.js +16 -0
- package/dist/errorCodes.d.ts +11 -2
- package/dist/errorCodes.js +155 -137
- package/dist/errors.d.ts +18 -7
- package/dist/errors.js +14 -1
- package/dist/index.js +5 -0
- package/dist/interfaces/index.d.ts +6 -20
- package/dist/keys/index.js +18 -9
- package/dist/mutators/UndoManager.js +6 -1
- package/dist/mutators/defineMutators.d.ts +1 -3
- package/dist/policy/types.d.ts +1 -1
- package/dist/query/client.d.ts +11 -0
- package/dist/query/client.js +81 -52
- package/dist/react/AbloProvider.d.ts +6 -10
- package/dist/react/AbloProvider.js +22 -15
- package/dist/react/context.d.ts +2 -118
- package/dist/react/useAblo.js +1 -1
- package/dist/react/useErrorListener.js +1 -1
- package/dist/react/useMutationFailureListener.js +1 -1
- package/dist/react/useMutators.js +7 -1
- package/dist/react/useReactive.js +0 -1
- package/dist/react/useUndoScope.js +2 -2
- package/dist/schema/ddlLock.d.ts +39 -0
- package/dist/schema/ddlLock.js +51 -0
- package/dist/schema/field.js +1 -1
- package/dist/schema/index.d.ts +4 -3
- package/dist/schema/index.js +15 -5
- package/dist/schema/model.d.ts +3 -3
- package/dist/schema/model.js +2 -2
- package/dist/schema/openapi.js +5 -1
- package/dist/schema/queries.d.ts +1 -1
- package/dist/schema/queries.js +1 -0
- package/dist/schema/residency.d.ts +35 -0
- package/dist/schema/residency.js +27 -0
- package/dist/schema/roles.d.ts +25 -0
- package/dist/schema/roles.js +37 -0
- package/dist/schema/schema.d.ts +3 -3
- package/dist/schema/schema.js +11 -7
- package/dist/schema/serialize.d.ts +8 -8
- package/dist/schema/sync-delta-row.d.ts +2 -2
- package/dist/schema/sync-delta-row.js +2 -2
- package/dist/server/storage-mode.d.ts +8 -1
- package/dist/server/storage-mode.js +14 -4
- package/dist/source/adapter.d.ts +1 -1
- package/dist/source/adapters/drizzle.js +4 -3
- package/dist/source/adapters/kysely.js +4 -3
- package/dist/source/adapters/memory.js +1 -1
- package/dist/source/adapters/prisma.js +5 -4
- package/dist/source/conformance.js +10 -8
- package/dist/source/connector.js +4 -2
- package/dist/source/factory.d.ts +106 -0
- package/dist/source/factory.js +273 -0
- package/dist/source/index.d.ts +11 -461
- package/dist/source/index.js +14 -416
- package/dist/source/next.d.ts +1 -1
- package/dist/source/next.js +1 -1
- package/dist/source/pushQueue.d.ts +1 -1
- package/dist/source/pushQueue.js +6 -3
- package/dist/source/signing.d.ts +59 -0
- package/dist/source/signing.js +142 -0
- package/dist/source/types.d.ts +334 -0
- package/dist/source/types.js +44 -0
- package/dist/stores/ObjectStore.d.ts +1 -1
- package/dist/stores/ObjectStore.js +23 -23
- package/dist/stores/SyncActionStore.d.ts +1 -1
- package/dist/stores/SyncActionStore.js +70 -35
- package/dist/surface.d.ts +1 -1
- package/dist/surface.js +1 -0
- package/dist/sync/AreaOfInterestManager.d.ts +2 -2
- package/dist/sync/AreaOfInterestManager.js +1 -1
- package/dist/sync/BootstrapHelper.d.ts +1 -3
- package/dist/sync/BootstrapHelper.js +29 -8
- package/dist/sync/ConnectionManager.d.ts +8 -0
- package/dist/sync/ConnectionManager.js +19 -4
- package/dist/sync/HydrationCoordinator.d.ts +12 -0
- package/dist/sync/HydrationCoordinator.js +25 -5
- package/dist/sync/NetworkProbe.d.ts +3 -2
- package/dist/sync/NetworkProbe.js +7 -6
- package/dist/sync/SyncWebSocket.d.ts +71 -120
- package/dist/sync/SyncWebSocket.js +324 -630
- package/dist/sync/awaitClaimGrant.js +27 -19
- package/dist/sync/bootstrapApply.d.ts +60 -0
- package/dist/sync/bootstrapApply.js +65 -0
- package/dist/sync/commitFrames.d.ts +43 -0
- package/dist/sync/commitFrames.js +94 -0
- package/dist/sync/createClaimStream.js +3 -2
- package/dist/sync/createSnapshot.d.ts +1 -3
- package/dist/sync/credentialLifecycle.d.ts +175 -0
- package/dist/sync/credentialLifecycle.js +329 -0
- package/dist/sync/deltaPipeline.d.ts +111 -0
- package/dist/sync/deltaPipeline.js +262 -0
- package/dist/sync/groupChange.d.ts +111 -0
- package/dist/sync/groupChange.js +246 -0
- package/dist/sync/heartbeat.d.ts +62 -0
- package/dist/sync/heartbeat.js +91 -0
- package/dist/sync/participants.d.ts +8 -8
- package/dist/sync/syncCursor.d.ts +44 -0
- package/dist/sync/syncCursor.js +59 -0
- package/dist/sync/syncPlan.d.ts +62 -0
- package/dist/sync/syncPlan.js +51 -0
- package/dist/sync/wsFrameHandlers.d.ts +117 -0
- package/dist/sync/wsFrameHandlers.js +378 -0
- package/dist/testing/fixtures/bootstrap.d.ts +9 -11
- package/dist/testing/fixtures/deltas.d.ts +1 -1
- package/dist/testing/fixtures/models.js +1 -0
- package/dist/testing/helpers/sync-engine-harness.d.ts +0 -3
- package/dist/testing/helpers/sync-engine-harness.js +2 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/testing/mocks/MockSyncContext.d.ts +1 -17
- package/dist/testing/mocks/MockSyncContext.js +1 -32
- package/dist/testing/mocks/MockSyncStore.d.ts +4 -4
- package/dist/testing/mocks/MockWebSocket.d.ts +2 -2
- package/dist/transactions/TransactionQueue.d.ts +20 -56
- package/dist/transactions/TransactionQueue.js +101 -487
- package/dist/transactions/TransactionStore.d.ts +18 -0
- package/dist/transactions/TransactionStore.js +51 -0
- package/dist/transactions/coalesceRules.d.ts +34 -0
- package/dist/transactions/coalesceRules.js +117 -0
- package/dist/transactions/commitPayload.d.ts +134 -0
- package/dist/transactions/commitPayload.js +152 -0
- package/dist/transactions/deltaConfirmation.d.ts +60 -0
- package/dist/transactions/deltaConfirmation.js +223 -0
- package/dist/transactions/optimistic.d.ts +24 -0
- package/dist/transactions/optimistic.js +45 -0
- package/dist/transactions/persistedReplay.d.ts +93 -0
- package/dist/transactions/persistedReplay.js +105 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.js +0 -5
- package/dist/types/modelData.d.ts +12 -0
- package/dist/types/modelData.js +11 -0
- package/dist/types/participant.d.ts +21 -0
- package/dist/types/participant.js +12 -0
- package/dist/types/streams.d.ts +8 -14
- package/dist/utils/mobx-setup.d.ts +1 -1
- package/dist/utils/mobx-setup.js +2 -2
- package/dist/wire/errorEnvelope.d.ts +11 -2
- package/dist/wire/errorEnvelope.js +14 -2
- package/dist/wire/frames.d.ts +90 -0
- package/dist/wire/frames.js +55 -1
- package/dist/wire/index.d.ts +4 -1
- package/dist/wire/index.js +20 -1
- package/dist/wire/protocol.d.ts +45 -0
- package/dist/wire/protocol.js +45 -0
- package/dist/wire/protocolVersion.d.ts +56 -0
- package/dist/wire/protocolVersion.js +63 -0
- package/docs/api-keys.md +4 -3
- package/docs/data-sources.md +12 -5
- package/docs/examples/existing-python-backend.md +3 -3
- package/docs/identity.md +4 -4
- package/docs/integration-guide.md +1 -1
- package/docs/react.md +1 -1
- package/docs/sessions.md +5 -7
- package/llms.txt +4 -2
- package/package.json +15 -13
- package/dist/client/index.d.ts +0 -36
- package/dist/client/index.js +0 -33
- package/dist/config/index.d.ts +0 -10
- package/dist/config/index.js +0 -12
- package/dist/interfaces/headless.d.ts +0 -95
- package/dist/interfaces/headless.js +0 -41
- package/dist/query/index.d.ts +0 -6
- package/dist/query/index.js +0 -5
- package/dist/realtime/index.d.ts +0 -10
- package/dist/realtime/index.js +0 -9
- package/dist/schema/plane.d.ts +0 -23
- package/dist/schema/plane.js +0 -19
- package/dist/server/next.d.ts +0 -51
- package/dist/server/next.js +0 -47
- package/dist/sync/OfflineFlush.d.ts +0 -9
- package/dist/sync/OfflineFlush.js +0 -22
- package/dist/sync/OfflineTransactionStore.d.ts +0 -37
- package/dist/sync/OfflineTransactionStore.js +0 -263
- package/dist/transactions/index.d.ts +0 -16
- package/dist/transactions/index.js +0 -7
package/docs/sessions.md
CHANGED
|
@@ -53,7 +53,7 @@ return Response.json({ token }); // return ONLY the token to the browser
|
|
|
53
53
|
A user session has **full data authority** within its org — no operation
|
|
54
54
|
allowlist. It's the human acting as themselves.
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
Point a browser `Ablo` client's `authEndpoint` at that route, and pass
|
|
57
57
|
the **instance** to [`<AbloProvider>`](/react). The client fetches the token,
|
|
58
58
|
opens the connection, and re-mints before expiry — your app writes no token
|
|
59
59
|
plumbing:
|
|
@@ -67,10 +67,7 @@ import { schema } from '@/ablo.schema';
|
|
|
67
67
|
|
|
68
68
|
const ablo = Ablo({
|
|
69
69
|
schema,
|
|
70
|
-
|
|
71
|
-
fetch('/api/ablo-session', { method: 'POST' })
|
|
72
|
-
.then((r) => r.json())
|
|
73
|
-
.then((d) => d.token),
|
|
70
|
+
authEndpoint: '/api/ablo-session',
|
|
74
71
|
});
|
|
75
72
|
|
|
76
73
|
export function Providers({ children }: { children: React.ReactNode }) {
|
|
@@ -81,8 +78,9 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
|
|
81
78
|
The client owns auth, the credential lifecycle, and the connection; the provider
|
|
82
79
|
is the thin reactive binding over it (Stripe's `<Elements stripe={...}>` model).
|
|
83
80
|
Build the client **once** at module scope — a new instance per render tears down
|
|
84
|
-
the socket.
|
|
85
|
-
`
|
|
81
|
+
the socket. Need custom headers or a
|
|
82
|
+
body on the exchange? `authEndpoint` also accepts an async resolver that
|
|
83
|
+
returns the token.
|
|
86
84
|
|
|
87
85
|
## Agent sessions (`rk_`)
|
|
88
86
|
|
package/llms.txt
CHANGED
|
@@ -122,9 +122,11 @@ A schema is model fields and relations. Advanced schema helpers such as `mutable
|
|
|
122
122
|
|
|
123
123
|
## Storage Boundary
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
THE ONE PATH IS LOGICAL REPLICATION. In production every schema model is backed by YOUR OWN database, and Ablo connects to it by CONSUMING ITS WRITE-AHEAD LOG (logical replication) — the Electric/PowerSync/Zero model. Ablo tails the WAL and fans changes out; YOUR APPLICATION CONTINUES TO OWN THE WRITE PATH (your own backend, your existing API). Ablo never runs DDL on, writes to, owns, or migrates your database. Connect once with `npx ablo connect` (prints the setup SQL: `wal_level=logical`, a publication, a `REPLICATION` role) then `npx ablo connect --register`. Validate with `npx ablo connect --check`. The role's privilege footprint is narrow but real — a `REPLICATION`-attributed role that streams the WAL and `SELECT`s; do NOT describe it as "read-only" (a security reviewer will push back — it is a replication privilege, just tightly scoped).
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
FALLBACK (only when the database can't grant a `REPLICATION` role, e.g. a locked-down managed DB): a signed Data Source endpoint that hands Ablo an ORM `adapter` (Drizzle default; Prisma and Kysely supported) — it owns the transaction, exactly-once idempotency, and outbox in ONE pass; your credentials never leave your infrastructure.
|
|
128
|
+
|
|
129
|
+
DEPRECATED — being removed, do NOT recommend or scaffold: the `databaseUrl` constructor option (the dial-in, where Ablo held a read/write connection and committed directly to your DB). The end-state constructor is `Ablo({ schema, apiKey })`; the database is connected out of band via `ablo connect`, not through `databaseUrl`. (Note: `ablo init` still defaults to `--storage direct` scaffolding `databaseUrl` — that default is itself slated to lead with `ablo connect`; prefer logical replication regardless of what `init` scaffolds.)
|
|
128
130
|
|
|
129
131
|
GOTCHA the user WILL hit: `DATABASE_URL` must use a NON-superuser, NON-BYPASSRLS role (Ablo enforces row-level security; owner roles are rejected with `database_role_cannot_enforce_rls`). Neon's and Supabase's default dashboard connection strings use the database OWNER (e.g. `neondb_owner`) and are rejected. EASIEST: `npx ablo migrate` detects the unsafe role and creates the scoped one automatically from the user's machine (owner credential never reaches Ablo; new DATABASE_URL written to the env file). Manual alternative — create a scoped role first: `CREATE ROLE ablo_app LOGIN PASSWORD '...' NOSUPERUSER NOBYPASSRLS; GRANT CREATE, CONNECT ON DATABASE <db> TO ablo_app; GRANT CREATE, USAGE ON SCHEMA public TO ablo_app;` — then swap user/password into the same host/db string.
|
|
130
132
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abloatai/ablo",
|
|
3
|
-
"version": "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
|
-
"
|
|
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
|
-
"
|
|
240
|
+
"ws": "^8.18.0"
|
|
239
241
|
}
|
|
240
242
|
}
|
package/dist/client/index.d.ts
DELETED
|
@@ -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';
|
package/dist/client/index.js
DELETED
|
@@ -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';
|
package/dist/config/index.d.ts
DELETED
|
@@ -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';
|
package/dist/config/index.js
DELETED
|
@@ -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 } { ... }
|
package/dist/query/index.d.ts
DELETED
|
@@ -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';
|
package/dist/query/index.js
DELETED
package/dist/realtime/index.d.ts
DELETED
|
@@ -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;
|
package/dist/realtime/index.js
DELETED
|
@@ -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;
|
package/dist/schema/plane.d.ts
DELETED
|
@@ -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;
|
package/dist/schema/plane.js
DELETED
|
@@ -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';
|
package/dist/server/next.d.ts
DELETED
|
@@ -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;
|
package/dist/server/next.js
DELETED
|
@@ -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,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;
|