@clivly/sdk 0.9.1 → 0.9.2
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/README.md +67 -22
- package/dist/chat-session.d.cts +1 -1
- package/dist/chat-session.d.mts +1 -1
- package/dist/drizzle.d.cts +1 -1
- package/dist/drizzle.d.mts +1 -1
- package/dist/index.cjs +765 -44
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +755 -46
- package/dist/{types-QPbki8ur.d.cts → types-DxG4rHyo.d.cts} +64 -2
- package/dist/{types-QPbki8ur.d.mts → types-DxG4rHyo.d.mts} +64 -2
- package/dist/vite.d.cts +1 -1
- package/dist/vite.d.mts +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# @clivly/sdk
|
|
2
2
|
|
|
3
|
-
Connect your app to Clivly Cloud. The SDK
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Connect your app to Clivly Cloud. The SDK reports your schema for entity mapping
|
|
4
|
+
and mirrors your contacts and companies over outbound HTTPS. Long-lived Node
|
|
5
|
+
hosts can opt into WebSocket presence, which replaces the periodic HTTP
|
|
6
|
+
liveness heartbeat while the socket is ready and falls back automatically if it
|
|
7
|
+
is not.
|
|
7
8
|
|
|
8
9
|
Clivly never connects to your database — the SDK runs inside your app and is the
|
|
9
10
|
only thing that touches your data.
|
|
@@ -69,6 +70,9 @@ export default createClivlySDK({
|
|
|
69
70
|
cursorField: "updatedAt",
|
|
70
71
|
}),
|
|
71
72
|
},
|
|
73
|
+
presence: {
|
|
74
|
+
transport: "websocket", // long-lived Node hosts only; HTTP fallback is automatic
|
|
75
|
+
},
|
|
72
76
|
});
|
|
73
77
|
```
|
|
74
78
|
|
|
@@ -96,13 +100,44 @@ The single most consequential decision in the setup.
|
|
|
96
100
|
|
|
97
101
|
| Host runtime | Use | Why |
|
|
98
102
|
| --- | --- | --- |
|
|
99
|
-
| Long-lived Node server, Vite dev | `clivlyVite(sdk)` or `await sdk.start()` | The
|
|
103
|
+
| Long-lived Node server, Vite dev | `clivlyVite(sdk)` or `await sdk.start()` | The keep-alive loop persists; optionally use WebSocket presence |
|
|
100
104
|
| Cloudflare Workers, Vercel, Lambda | `sdk.createClivlyHandler()` at a route, and/or `sdk.runScheduled()` from cron | `setInterval` does **not** survive between invocations |
|
|
101
105
|
| One-off health check | `await sdk.connect()` | Structured `{ ok, status, reason, retryable, org? }` |
|
|
102
106
|
|
|
103
107
|
`start()` emits a console warning when it detects a serverless runtime, because
|
|
104
108
|
there it stops ticking after the first response.
|
|
105
109
|
|
|
110
|
+
### WebSocket presence
|
|
111
|
+
|
|
112
|
+
HTTP is the default presence transport. To replace the 60-second HTTP liveness
|
|
113
|
+
cadence on a long-lived Node host, opt in:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
createClivlySDK({
|
|
117
|
+
// ...the rest of your configuration
|
|
118
|
+
presence: {
|
|
119
|
+
transport: "websocket",
|
|
120
|
+
deploymentId: process.env.CLIVLY_DEPLOYMENT_ID, // optional
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`start()` performs its initial HTTP check-in, then opens an authenticated
|
|
126
|
+
outbound socket. When the server confirms it is ready, the socket becomes the
|
|
127
|
+
liveness signal and the periodic HTTP heartbeat pauses. A closed or unavailable
|
|
128
|
+
socket reconnects with backoff while the SDK resumes HTTP heartbeat
|
|
129
|
+
automatically. This does not alter `sync.intervalMs`; it only changes presence.
|
|
130
|
+
|
|
131
|
+
Keep the default HTTP transport for serverless and edge runtimes. They cannot
|
|
132
|
+
retain a WebSocket across invocations, so use `runScheduled()` or
|
|
133
|
+
`createClivlyHandler()` there.
|
|
134
|
+
|
|
135
|
+
For rollout reliability, enabled WebSocket presence emits bounded lifecycle
|
|
136
|
+
metrics (event, transport, outcome, state, duration and attempt). It never
|
|
137
|
+
includes credentials, organization or deployment identifiers, host URLs, row
|
|
138
|
+
data, error messages, or stack traces. See
|
|
139
|
+
[SECURITY.md](../../SECURITY.md#telemetry).
|
|
140
|
+
|
|
106
141
|
### Entities vs. sources — the distinction that bites
|
|
107
142
|
|
|
108
143
|
```ts
|
|
@@ -397,7 +432,9 @@ is honoured. Other `4xx` responses return immediately.
|
|
|
397
432
|
| `schema` | `DiscoveredTable[]` | — | Use `discoverFromDrizzle(schema)`. It reports keys, types, nullability and FK edges alongside column names; [derived objects](#derived-objects) cannot be authored without them, so prefer it over a hand-written array |
|
|
398
433
|
| `source` | `{ contacts, companies?, deals?, custom? }` | — | Keyed by CRM concept. `contacts` is required when `source` is present |
|
|
399
434
|
| `cursorStore` | `CursorStore` | in-memory | Persist on serverless |
|
|
400
|
-
| `heartbeatIntervalMs` | `number` | `60000` | |
|
|
435
|
+
| `heartbeatIntervalMs` | `number` | `60000` | HTTP presence cadence and default sync cadence; paused when opt-in WebSocket presence is ready |
|
|
436
|
+
| `presence.transport` | `"http" \\| "websocket"` | `"http"` | WebSocket is for long-lived Node hosts; HTTP resumes during reconnect/fallback |
|
|
437
|
+
| `presence.deploymentId` | `string` | platform-derived | Optional release identity for a WebSocket deployment |
|
|
401
438
|
| `sync.onBoot` | `boolean` | `true` | Only affects `start()` |
|
|
402
439
|
| `sync.intervalMs` | `number` | `heartbeatIntervalMs` | |
|
|
403
440
|
| `sync.batchSize` | `number` | `500` | Rows per page |
|
|
@@ -417,7 +454,7 @@ is honoured. Other `4xx` responses return immediately.
|
|
|
417
454
|
| --- | --- | --- |
|
|
418
455
|
| `connect()` | `Promise<ClivlyConnectResult>` | One heartbeat, structured. Never throws |
|
|
419
456
|
| `heartbeat()` | `Promise<boolean>` | One heartbeat, boolean |
|
|
420
|
-
| `start()` | `Promise<void>` | Heartbeat + boot sync + timers. Long-lived hosts only |
|
|
457
|
+
| `start()` | `Promise<void>` | Heartbeat + boot sync + timers. Long-lived hosts only; opens opt-in WebSocket presence |
|
|
421
458
|
| `stop()` | `void` | Clears the timers |
|
|
422
459
|
| `sync(options?)` | `Promise<void>` | `{ mode?: "delta" \| "full", runId?: string }`. Throws on push failure |
|
|
423
460
|
| `runScheduled(options?)` | `Promise<void>` | One heartbeat + one sync, no timers. Throws on push failure |
|
|
@@ -444,21 +481,27 @@ response).
|
|
|
444
481
|
|
|
445
482
|
A custom object can be derived from a base table plus explicit joins, instead of
|
|
446
483
|
mapping exactly one table — an `Enrollment` built from `enrollments` joined to
|
|
447
|
-
`students` and `courses`. You
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
484
|
+
`students` and `courses`. You declare one on an entity in `clivly.config.ts`,
|
|
485
|
+
alongside the object it materializes into; `validateEntitiesConfig` checks it in
|
|
486
|
+
CI.
|
|
487
|
+
|
|
488
|
+
Two things have to line up:
|
|
489
|
+
|
|
490
|
+
- **Discovery must be rich enough.** `discoverFromDrizzle` sends primary keys,
|
|
491
|
+
unique constraints, nullability, column types and foreign-key edges.
|
|
492
|
+
Validation is fail-closed, so if your config hand-writes `schema` as
|
|
493
|
+
`{ name, columns }` pairs, every table is rejected with *"has no key/column
|
|
494
|
+
metadata — upgrade `@clivly/sdk` and re-run discovery"*. Pass
|
|
495
|
+
`discoverFromDrizzle(schema)` and redeploy so a fresh heartbeat carries the
|
|
496
|
+
richer payload — and re-run it after schema changes, since projections
|
|
497
|
+
validate against the last reported snapshot.
|
|
498
|
+
- **The server must have the capability enabled.** Authoring sits behind
|
|
499
|
+
`CLIVLY_PROJECTION_MAPPINGS=true` while the surface settles. Reading and
|
|
500
|
+
syncing an existing derived object is never gated.
|
|
501
|
+
|
|
502
|
+
> Requires `clivly@0.9.0` / `@clivly/sdk@0.9.0` or later for the discovery
|
|
503
|
+
> metadata. Earlier versions reported names only, so no host app could author a
|
|
504
|
+
> derived object.
|
|
462
505
|
|
|
463
506
|
Full guide: [`docs/guides/derived-objects.md`](../../docs/guides/derived-objects.md).
|
|
464
507
|
|
|
@@ -466,6 +509,8 @@ Full guide: [`docs/guides/derived-objects.md`](../../docs/guides/derived-objects
|
|
|
466
509
|
|
|
467
510
|
- `start()` is for long-lived runtimes only. On serverless/edge, use
|
|
468
511
|
`runScheduled()` or `createClivlyHandler()`.
|
|
512
|
+
- WebSocket presence is opt-in and long-lived Node-only. It does not replace
|
|
513
|
+
HTTP presence on serverless or edge hosts.
|
|
469
514
|
- `fromDrizzle` is the only generated source path. Non-Drizzle hosts write
|
|
470
515
|
`fetchPage` by hand.
|
|
471
516
|
- The flat `contactEntity` / `contactFields` config still works but is
|
package/dist/chat-session.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as CreateChatSessionHandlerOptions } from "./types-
|
|
1
|
+
import { c as CreateChatSessionHandlerOptions } from "./types-DxG4rHyo.cjs";
|
|
2
2
|
//#region src/chat-session.d.ts
|
|
3
3
|
declare function createChatSessionHandler({ allowedOrigins, apiKey, apiUrl, fetchImpl, resolveUser }: CreateChatSessionHandlerOptions): (request: Request) => Promise<Response>;
|
|
4
4
|
//#endregion
|
package/dist/chat-session.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as CreateChatSessionHandlerOptions } from "./types-
|
|
1
|
+
import { c as CreateChatSessionHandlerOptions } from "./types-DxG4rHyo.mjs";
|
|
2
2
|
//#region src/chat-session.d.ts
|
|
3
3
|
declare function createChatSessionHandler({ allowedOrigins, apiKey, apiUrl, fetchImpl, resolveUser }: CreateChatSessionHandlerOptions): (request: Request) => Promise<Response>;
|
|
4
4
|
//#endregion
|
package/dist/drizzle.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as NamespaceIntrospector, g as SyncSource } from "./types-DxG4rHyo.cjs";
|
|
2
2
|
import { Table } from "drizzle-orm";
|
|
3
3
|
import { buildUniqueConstraints, discoverFromDrizzle } from "@clivly/core/drizzle";
|
|
4
4
|
//#region src/drizzle.d.ts
|
package/dist/drizzle.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as NamespaceIntrospector, g as SyncSource } from "./types-DxG4rHyo.mjs";
|
|
2
2
|
import { buildUniqueConstraints, discoverFromDrizzle } from "@clivly/core/drizzle";
|
|
3
3
|
import { Table } from "drizzle-orm";
|
|
4
4
|
//#region src/drizzle.d.ts
|