@spooky-sync/client-solid2 0.0.1-canary.332 → 0.0.1-canary.334
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 +2 -2
- package/QUICK_START.md +2 -2
- package/dist/index.cjs +6 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -9
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +16 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/skills/sp00ky-solid2/SKILL.md +2 -2
- package/src/lib/__tests__/create-query.rebind.test.ts +126 -0
- package/src/lib/create-query.ts +39 -28
package/AGENTS.md
CHANGED
|
@@ -41,8 +41,8 @@ Provider props are identical to client-solid: `config`, `fallback`, `preload` (a
|
|
|
41
41
|
- `error()` — registration/sync failure (e.g. SSP 503 NOT_READY). Never thrown into the render tree; the sync scheduler retries underneath.
|
|
42
42
|
- `isLoading()` — cold first load only (nothing painted for this identity, server not heard, no error). A cached paint ends it; an authoritative empty answer ends it. Never true again for the same identity.
|
|
43
43
|
- `isFetching()` — a fetch cycle is in flight (registration, a sync round).
|
|
44
|
-
- `isAuthoritative()`
|
|
45
|
-
- `isSettled()
|
|
44
|
+
- `isAuthoritative()`: `data()` holds the rendered rows of a known membership (the server's, or one a previous session left on this device); a known set whose rows are not painted yet, as right after a sign-in, does not count. Latched until the identity changes. `hasData()`: `data()` holds something. `isEmpty()`: authoritative AND no data: the server said "no rows"; render empty states on this, not on `!hasData()`.
|
|
45
|
+
- `isSettled()`: authoritative AND idle; gate windowed-list end detection and create-if-missing on it (the re-registration that confirms a cached answer counts as fetching). Not monotonic; latch it (a `createMemo(prev => prev || q.isSettled())`) for a verdict that must stick.
|
|
46
46
|
- Options: `enabled?: () => boolean`, `deregisterOnCleanup?: boolean`.
|
|
47
47
|
- **`createSubmission(fn)`** — button pending/error state around a mutation: `submit()`, `pending()`, `error()`, `result()`, `clearError()`. There is deliberately no `action()` / `createOptimisticStore` layer (see `src/lib/create-submission.ts`).
|
|
48
48
|
- **`useSyncActivity(options?)`** — `{ fetchingQueries, pendingMutations, isDownloading, isUploading }`. One subscription on the engine's aggregate fetch count (queries with traffic the user waits on: a first registration or rows to download; a re-registration of a query that already shows rows, as after a reload, is left out) plus the outbox depth; both are debounced ON by their delay (`downloadDelayMs` 200, `uploadDelayMs` 150) and off at once, and `isUploading()` additionally needs `pendingMutations() > uploadThreshold` (0, so any unacknowledged write counts). Drive a logo/traffic indicator off it; pair with `useSyncStatus().connection()` / `.isOffline()` to switch the same mark to a reconnecting or offline state and show the unsaved count.
|
package/QUICK_START.md
CHANGED
|
@@ -83,10 +83,10 @@ import { Loading } from 'solid-js';
|
|
|
83
83
|
| `error()` | Registration/sync error (e.g. SSP 503 during bootstrap). Never thrown into the render tree; the sync scheduler retries underneath. |
|
|
84
84
|
| `isLoading()` | Cold first load only: nothing painted for this identity yet, server not heard, no error. A cached paint ends it; so does the server answering with zero rows. |
|
|
85
85
|
| `isFetching()` | Sync engine is pulling records for this query. |
|
|
86
|
-
| `isAuthoritative()` |
|
|
86
|
+
| `isAuthoritative()` | `data()` holds the rendered rows of a known membership for this identity: the server's answer (once its rows are local) or the membership a previous session left on this device. A known set whose rows are not painted yet (right after a sign-in or on boot) does not count. Latched until the identity changes. |
|
|
87
87
|
| `hasData()` | `data()` holds rows (or the `.one()` row). |
|
|
88
88
|
| `isEmpty()` | Authoritative AND no data — the server said "no rows". Render empty states on this. |
|
|
89
|
-
| `isSettled()` | Authoritative AND idle
|
|
89
|
+
| `isSettled()` | Authoritative AND idle: windowed lists may trust a short result as the true end of the list, and a missing row is missing. The re-registration that confirms a cached answer counts as fetching. Re-enters on later sync rounds; latch it for a sticky verdict. |
|
|
90
90
|
|
|
91
91
|
Options: `{ enabled?: () => boolean, deregisterOnCleanup?: boolean }` — both as in client-solid.
|
|
92
92
|
|
package/dist/index.cjs
CHANGED
|
@@ -246,12 +246,6 @@ function createQuery(dbOrQuery, queryOrOptions, maybeOptions) {
|
|
|
246
246
|
if (disposed || myRun !== runId) return;
|
|
247
247
|
activeHash = hash;
|
|
248
248
|
addCleanup(sp00ky.subscribeQueryStatus(hash, (status) => setIsFetching(status === "fetching"), { immediate: true }));
|
|
249
|
-
addCleanup(sp00ky.subscribeQueryAuthority(hash, (known) => {
|
|
250
|
-
if (disposed || myRun !== runId) return;
|
|
251
|
-
setIsAuthoritative(known);
|
|
252
|
-
if (known) wakeReady();
|
|
253
|
-
else setHasPainted(false);
|
|
254
|
-
}, { immediate: true }));
|
|
255
249
|
addCleanup(sp00ky.subscribe(hash, (rows) => {
|
|
256
250
|
if (disposed || myRun !== runId) return;
|
|
257
251
|
const queryData = query.isOne ? rows[0] ?? null : rows;
|
|
@@ -266,6 +260,12 @@ function createQuery(dbOrQuery, queryOrOptions, maybeOptions) {
|
|
|
266
260
|
});
|
|
267
261
|
sp00ky.reportFrontendTiming(hash, performance.now() - t0);
|
|
268
262
|
}, { immediate: true }));
|
|
263
|
+
addCleanup(sp00ky.subscribeQueryAuthority(hash, (known) => {
|
|
264
|
+
if (disposed || myRun !== runId) return;
|
|
265
|
+
setIsAuthoritative(known);
|
|
266
|
+
if (known) wakeReady();
|
|
267
|
+
else setHasPainted(false);
|
|
268
|
+
}, { immediate: true }));
|
|
269
269
|
}).catch((err) => {
|
|
270
270
|
if (disposed || myRun !== runId) return;
|
|
271
271
|
setError(err instanceof Error ? err : new Error(String(err)));
|