@spooky-sync/client-solid 0.0.1-canary.16 → 0.0.1-canary.160
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 +68 -0
- package/README.md +20 -0
- package/dist/index.cjs +385 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +216 -21
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +216 -21
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +380 -66
- package/dist/index.js.map +1 -1
- package/package.json +9 -7
- package/skills/sp00ky-solid/SKILL.md +335 -0
- package/skills/sp00ky-solid/references/file-hooks.md +112 -0
- package/src/cache/index.ts +1 -1
- package/src/cache/surrealdb-wasm-factory.ts +4 -1
- package/src/index.ts +164 -61
- package/src/lib/Sp00kyProvider.ts +102 -0
- package/src/lib/context.ts +3 -3
- package/src/lib/create-preload.ts +111 -0
- package/src/lib/models.ts +1 -1
- package/src/lib/use-app-release.ts +89 -0
- package/src/lib/use-crdt-field.ts +68 -0
- package/src/lib/use-download-file.ts +2 -2
- package/src/lib/use-feature-flag.ts +50 -0
- package/src/lib/use-file-upload.ts +2 -1
- package/src/lib/use-query.ts +143 -28
- package/src/lib/use-storage-status.ts +44 -0
- package/src/lib/use-sync-status.ts +50 -0
- package/src/types/index.ts +3 -4
- package/src/lib/SpookyProvider.ts +0 -55
package/AGENTS.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# `@spooky-sync/client-solid` — agent guide
|
|
2
|
+
|
|
3
|
+
## What this package is
|
|
4
|
+
|
|
5
|
+
The SolidJS binding for sp00ky. Exposes a `Sp00kyProvider` that initializes a `Sp00kyClient` and a set of reactive hooks (`useDb`, `useQuery`, `useCrdtField`, `useFileUpload`, `useDownloadFile`). All hooks expect to be called inside a `<Sp00kyProvider>` boundary.
|
|
6
|
+
|
|
7
|
+
## Setup pattern
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
// db.ts
|
|
11
|
+
import type { SyncedDbConfig } from '@spooky-sync/client-solid';
|
|
12
|
+
import { schema, SURQL_SCHEMA } from './schema.gen'; // generated by `spky generate`
|
|
13
|
+
|
|
14
|
+
export const dbConfig: SyncedDbConfig<typeof schema> = {
|
|
15
|
+
schema,
|
|
16
|
+
schemaSurql: SURQL_SCHEMA,
|
|
17
|
+
database: {
|
|
18
|
+
namespace: 'main',
|
|
19
|
+
database: 'app',
|
|
20
|
+
endpoint: 'ws://localhost:8666/rpc',
|
|
21
|
+
store: 'memory', // or 'indexeddb' for persistence
|
|
22
|
+
persistenceClient: 'localstorage',
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
// App.tsx
|
|
29
|
+
<Sp00kyProvider config={dbConfig}>{/* app */}</Sp00kyProvider>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Key hooks
|
|
33
|
+
|
|
34
|
+
- **`useDb<typeof schema>()`** — returns the `SyncedDb<S>` instance. Methods:
|
|
35
|
+
- `db.create(id, payload)` — `id` is a full record ID like `'thread:abc'`.
|
|
36
|
+
- `db.update(table, id, payload, options?)` — `options.debounced` coalesces updates.
|
|
37
|
+
- `db.delete(table, idOrSelector)`.
|
|
38
|
+
- `db.query(table)` — returns a `QueryBuilder`. Chain `.related()`, `.orderBy()`, `.limit()`, etc., end with `.build()`.
|
|
39
|
+
- `db.preload(query, options?)` — cache-aware, awaitable prewarm. Cold (nothing cached in the bucket) fetches + persists and the promise awaits it (blocks); warm returns instantly. `options.refresh` (`'onUse'` default / `'background'` / `'stale'`) + `options.staleTime` control warm-refresh. One-shot snapshot, no live view — freshens on use.
|
|
40
|
+
- `db.run(backend, route, payload)` — call a backend RPC route.
|
|
41
|
+
- `db.bucket(name)` — get a `BucketHandle` for file storage.
|
|
42
|
+
- `db.useRemote(fn)` — escape hatch to the raw `Surreal` client (skips cache).
|
|
43
|
+
- `db.authenticate(token)`, `db.signOut()`, `db.auth`.
|
|
44
|
+
- `db.pendingMutationCount`, `db.subscribeToPendingMutations(cb)`.
|
|
45
|
+
- **`useQuery(() => db.query(...).build())`** — reactive query. Returns `{ data, status, error, ... }` accessors. The factory function is tracked, so passing reactive params (signals) re-runs the query.
|
|
46
|
+
- **`createPreload(() => db.query(...).build(), options?)`** — reactive, fire-and-forget prewarm (same overloads/`enabled` as `useQuery`, plus `refresh`/`staleTime`). Warms a query the user is likely to open next (e.g. a list row's detail) into the local cache. For blocking first-load, use the `Sp00kyProvider` `preload` prop instead.
|
|
47
|
+
- **`useCrdtField(table, () => recordId, field, () => valueAccessor)`** — wires a CRDT text field to a Loro doc. Pair with `db.update(table, id, { [field]: newValue }, { debounced: true })` so rapid keystrokes don't flood the queue. *All four arguments take accessor functions where reactive — that's deliberate, for SolidJS tracking.*
|
|
48
|
+
- **`useFileUpload()`** / **`useDownloadFile()`** — bucket helpers; the upload result includes the storage path you write into a record column.
|
|
49
|
+
|
|
50
|
+
## Re-exports for convenience
|
|
51
|
+
|
|
52
|
+
- `RecordId`, `Uuid` from `surrealdb`.
|
|
53
|
+
- Query-builder types: `TableModel`, `TableNames`, `GetTable`, `QueryResult`, etc. (see `@spooky-sync/query-builder/AGENTS.md`).
|
|
54
|
+
- `Model<S, T>`, `GenericModel`, `ModelPayload` — typed row shapes.
|
|
55
|
+
|
|
56
|
+
## Common gotchas
|
|
57
|
+
|
|
58
|
+
- **`useDb()` requires `<typeof schema>`.** Without the generic, all calls fall back to `unknown` and you lose type safety.
|
|
59
|
+
- **CRDT fields are not regular columns.** Don't read or write them via `useQuery` — read with `useCrdtField`, write via `db.update` with `{ debounced: true }`.
|
|
60
|
+
- **Generate IDs explicitly.** `const id = new Uuid().toString()`, then `db.create(\`thread:\${id}\`, ...)`. SurrealDB's auto-id only fires on direct DB writes, not through the sync queue.
|
|
61
|
+
- **`useQuery` factories must call `.build()` (or `.all()`, `.first()`, etc.).** A bare `db.query('thread')` is a builder, not a query — `useQuery` will throw or return forever-loading.
|
|
62
|
+
- **Provider is mandatory.** Calling any hook outside `<Sp00kyProvider>` throws.
|
|
63
|
+
|
|
64
|
+
## Pointers
|
|
65
|
+
|
|
66
|
+
- Sync engine: `node_modules/@spooky-sync/core/AGENTS.md`
|
|
67
|
+
- Query builder DSL: `node_modules/@spooky-sync/query-builder/AGENTS.md`
|
|
68
|
+
- Schema authoring + codegen: `node_modules/@spooky-sync/cli/AGENTS.md`
|
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ A SurrealDB client for Solid.js with automatic cache synchronization and live qu
|
|
|
11
11
|
- **Type-Safe**: Full TypeScript support with generated schema types
|
|
12
12
|
- **Reactive**: Seamless integration with Solid.js reactivity
|
|
13
13
|
- **Offline Support**: Local cache works even when remote is temporarily unavailable
|
|
14
|
+
- **Preload / Prewarm**: Warm data into the local cache ahead of time so screens open instantly — awaitable to gate first load, reactive to prefetch what's next
|
|
14
15
|
|
|
15
16
|
## Quick Start
|
|
16
17
|
|
|
@@ -215,6 +216,25 @@ const liveQuery = await db.query.thread
|
|
|
215
216
|
.orderBy('created_at', 'desc'); // ✅ Field names autocompleted
|
|
216
217
|
```
|
|
217
218
|
|
|
219
|
+
### Preload / Prewarm
|
|
220
|
+
|
|
221
|
+
Warm a query's results into the local cache before they're needed, so a later `useQuery` paints
|
|
222
|
+
instantly instead of waiting on the network. Preload is a one-shot snapshot — it does not register
|
|
223
|
+
a live view; the data freshens on use when the real `useQuery` mounts.
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
// Awaitable + cache-aware: blocks on the FIRST load (nothing cached), returns
|
|
227
|
+
// instantly on later loads (already cached). Great for gating the UI on config.
|
|
228
|
+
await db.preload(db.query('config').build());
|
|
229
|
+
|
|
230
|
+
// Opt into a one-time background refresh when the cache is stale:
|
|
231
|
+
await db.preload(db.query('config').build(), { refresh: 'stale', staleTime: '1d' });
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Block first-load UI on essential data via the `Sp00kyProvider` `preload` prop, or reactively
|
|
235
|
+
prefetch what the user is likely to open next with `createPreload(() => …build())`. Full details
|
|
236
|
+
in the [SKILL guide](./skills/sp00ky-solid/SKILL.md#preload).
|
|
237
|
+
|
|
218
238
|
## Documentation
|
|
219
239
|
|
|
220
240
|
- **[Quick Start Guide](./QUICK_START.md)**: Get up and running quickly
|