@drakkar.software/starfish-client 3.0.0-alpha.13 → 3.0.0-alpha.16
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 +17 -0
- package/dist/bindings/zustand.d.ts +27 -1
- package/dist/bindings/zustand.js +142 -9
- package/dist/bindings/zustand.js.map +2 -2
- package/dist/client.d.ts +27 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +121 -4
- package/dist/index.js.map +2 -2
- package/dist/sync.d.ts +28 -0
- package/dist/types.d.ts +43 -0
- package/package.json +2 -2
package/dist/sync.d.ts
CHANGED
|
@@ -70,13 +70,41 @@ export declare class SyncManager {
|
|
|
70
70
|
private lastCheckpoint;
|
|
71
71
|
private localData;
|
|
72
72
|
private aborted;
|
|
73
|
+
private lastFromCache;
|
|
73
74
|
constructor(options: SyncManagerOptions);
|
|
74
75
|
abort(): void;
|
|
75
76
|
get isAborted(): boolean;
|
|
76
77
|
getData(): Record<string, unknown>;
|
|
78
|
+
/**
|
|
79
|
+
* Merge a remote snapshot with local (optimistic) data using this manager's
|
|
80
|
+
* conflict resolver — the same resolver the push-conflict path uses. A plain
|
|
81
|
+
* {@link pull} overwrites the store's data with the server snapshot, which
|
|
82
|
+
* would drop un-pushed local writes (they live only in the store, never in
|
|
83
|
+
* `localData` until a push succeeds). The zustand binding calls this on pull
|
|
84
|
+
* while the store is dirty so those writes survive. `local` wins by the same
|
|
85
|
+
* rules as a push conflict.
|
|
86
|
+
*/
|
|
87
|
+
resolve(local: Record<string, unknown>, remote: Record<string, unknown>): Record<string, unknown>;
|
|
77
88
|
getHash(): string | null;
|
|
78
89
|
/** Set the last-known server hash. Used by persistence layers to restore state across restarts. */
|
|
79
90
|
setHash(hash: string | null): void;
|
|
91
|
+
/**
|
|
92
|
+
* Whether the most recent {@link pull} (or {@link seedFromCache}) was served
|
|
93
|
+
* from the client's offline read-through cache rather than a live server
|
|
94
|
+
* response. The binding surfaces this as a `stale` flag so the UI can show an
|
|
95
|
+
* offline indicator without treating a cache hit as "reachable". Reset to
|
|
96
|
+
* false by the next successful network pull.
|
|
97
|
+
*/
|
|
98
|
+
getLastPullFromCache(): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Cache-first paint: seed `localData` from the client's read-through cache
|
|
101
|
+
* WITHOUT touching the network, decrypting in memory for E2E collections.
|
|
102
|
+
* Returns whether anything was seeded (false on a miss, an expired entry, or
|
|
103
|
+
* a decrypt failure — e.g. keyring skew). Call once on store creation before
|
|
104
|
+
* the initial live {@link pull}, which then supersedes the seeded snapshot.
|
|
105
|
+
* Requires the client to have been built with a `cache`.
|
|
106
|
+
*/
|
|
107
|
+
seedFromCache(): Promise<boolean>;
|
|
80
108
|
getCheckpoint(): number;
|
|
81
109
|
pull(): Promise<PullResult>;
|
|
82
110
|
push(data: Record<string, unknown>): Promise<{
|
package/dist/types.d.ts
CHANGED
|
@@ -36,6 +36,26 @@ export interface StarfishCapProvider {
|
|
|
36
36
|
pubHex?: string;
|
|
37
37
|
}>;
|
|
38
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* A minimal async key-value store the client uses as a read-through cache for
|
|
41
|
+
* {@link StarfishClient.pull} (offline-first reads). Host-provided so the SDK
|
|
42
|
+
* stays storage-agnostic — back it by `localStorage`, `AsyncStorage`, a file,
|
|
43
|
+
* etc. Shaped like a subset of zustand's `StateStorage` so an existing adapter
|
|
44
|
+
* fits.
|
|
45
|
+
*
|
|
46
|
+
* IMPORTANT — what gets stored: the client caches the RAW server response only
|
|
47
|
+
* (`data`/`hash`/`timestamp`). For E2E (`delegated`) collections that payload is
|
|
48
|
+
* the SEALED ciphertext the server holds — never the decrypted form — so this
|
|
49
|
+
* cache is ciphertext-at-rest by construction. Decryption always happens in
|
|
50
|
+
* memory on read (see {@link SyncManager}). Public/plaintext collections cache
|
|
51
|
+
* their plaintext, exactly as the server stores it.
|
|
52
|
+
*/
|
|
53
|
+
export interface PullCache {
|
|
54
|
+
/** Return the previously-stored string for `key`, or null if absent. Must not throw. */
|
|
55
|
+
get(key: string): Promise<string | null>;
|
|
56
|
+
/** Store `value` under `key`. Must not throw (failures are swallowed by the client). */
|
|
57
|
+
set(key: string, value: string): Promise<void>;
|
|
58
|
+
}
|
|
39
59
|
/** Options for creating a StarfishClient. */
|
|
40
60
|
export interface StarfishClientOptions {
|
|
41
61
|
/** Base URL of the Starfish server (e.g. "https://api.example.com/v1"). */
|
|
@@ -66,6 +86,29 @@ export interface StarfishClientOptions {
|
|
|
66
86
|
capProvider?: StarfishCapProvider;
|
|
67
87
|
/** Optional fetch implementation (defaults to global fetch). */
|
|
68
88
|
fetch?: typeof fetch;
|
|
89
|
+
/**
|
|
90
|
+
* Optional read-through cache for {@link StarfishClient.pull} — the basis for
|
|
91
|
+
* offline-first reads. When set, every successful non-append pull is written
|
|
92
|
+
* through to the cache (keyed by document path), and a pull that fails because
|
|
93
|
+
* the TRANSPORT is unreachable (offline / DNS / timeout — `fetch` rejects)
|
|
94
|
+
* falls back to the cached response, tagged so callers can tell it's stale.
|
|
95
|
+
*
|
|
96
|
+
* A real HTTP error (404/403/5xx) is a genuine server answer and always
|
|
97
|
+
* propagates — the cache is NOT consulted — so "no document yet" and
|
|
98
|
+
* "access denied" keep their meaning. Caches ciphertext for E2E collections
|
|
99
|
+
* (the server only ever holds sealed payloads); never decrypted data.
|
|
100
|
+
*/
|
|
101
|
+
cache?: PullCache;
|
|
102
|
+
/**
|
|
103
|
+
* Optional max age (ms) for {@link cache} entries. An entry older than this is
|
|
104
|
+
* treated as a cache MISS on every read — both cache-first paint and the
|
|
105
|
+
* offline fallback — so a stale-beyond-policy snapshot is never served (the
|
|
106
|
+
* pull then goes to the network, or rethrows the transport error offline).
|
|
107
|
+
* Each cached snapshot records its write time; expiry is `now - cachedAt >
|
|
108
|
+
* cacheMaxAgeMs`. Omit (default) for entries that never expire — recommended
|
|
109
|
+
* for an offline-first app where any last-synced data beats none.
|
|
110
|
+
*/
|
|
111
|
+
cacheMaxAgeMs?: number;
|
|
69
112
|
/**
|
|
70
113
|
* Optional list of client-side plugins. The list is stored on the client
|
|
71
114
|
* instance but does not fire any hooks yet — the contract is plumbed so
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drakkar.software/starfish-client",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.16",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/Drakkar-Software/starfish.git",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@drakkar.software/starfish-protocol": "3.0.0-alpha.
|
|
63
|
+
"@drakkar.software/starfish-protocol": "3.0.0-alpha.16"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@legendapp/state": "^2.0.0",
|