@drakkar.software/starfish-client 3.0.0-alpha.11 → 3.0.0-alpha.12
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/dist/append-log.d.ts +1 -3
- package/dist/append-log.js +267 -0
- package/dist/background-sync.js +29 -0
- package/dist/bindings/suspense.js +49 -0
- package/dist/bindings/zustand.js +6 -14
- package/dist/bindings/zustand.js.map +2 -2
- package/dist/client.js +391 -0
- package/dist/config.js +18 -0
- package/dist/debounced-sync.js +120 -0
- package/dist/dedup.js +35 -0
- package/dist/export.js +115 -0
- package/dist/history.js +61 -0
- package/dist/index.js +8 -17
- package/dist/index.js.map +3 -3
- package/dist/logger.js +80 -0
- package/dist/migrate.js +38 -0
- package/dist/mobile-lifecycle.js +94 -0
- package/dist/multi-store.js +92 -0
- package/dist/polling.js +52 -0
- package/dist/resolvers.js +223 -0
- package/dist/service-worker.js +55 -0
- package/dist/storage/indexeddb.js +59 -0
- package/dist/sync.js +181 -0
- package/dist/types.d.ts +1 -9
- package/dist/types.js +18 -0
- package/dist/validate.js +28 -0
- package/package.json +2 -2
package/dist/history.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export class SnapshotHistory {
|
|
2
|
+
snapshots = [];
|
|
3
|
+
maxSnapshots;
|
|
4
|
+
storageKey;
|
|
5
|
+
constructor(options) {
|
|
6
|
+
this.maxSnapshots = options?.maxSnapshots ?? 20;
|
|
7
|
+
this.storageKey = options?.storageKey;
|
|
8
|
+
if (this.storageKey) {
|
|
9
|
+
try {
|
|
10
|
+
const raw = localStorage.getItem(this.storageKey);
|
|
11
|
+
if (raw) {
|
|
12
|
+
const parsed = JSON.parse(raw);
|
|
13
|
+
if (Array.isArray(parsed))
|
|
14
|
+
this.snapshots = parsed;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
catch { /* corrupted or unavailable — start fresh */ }
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** Take a labeled snapshot of the given data. */
|
|
21
|
+
take(label, data) {
|
|
22
|
+
this.snapshots.push({
|
|
23
|
+
timestamp: Date.now(),
|
|
24
|
+
label,
|
|
25
|
+
data: JSON.stringify(data),
|
|
26
|
+
});
|
|
27
|
+
if (this.snapshots.length > this.maxSnapshots) {
|
|
28
|
+
this.snapshots = this.snapshots.slice(-this.maxSnapshots);
|
|
29
|
+
}
|
|
30
|
+
this.persist();
|
|
31
|
+
}
|
|
32
|
+
/** Restore data from a snapshot at the given index. Returns undefined if index is invalid or data is corrupt. */
|
|
33
|
+
restore(index) {
|
|
34
|
+
const snapshot = this.snapshots[index];
|
|
35
|
+
if (!snapshot)
|
|
36
|
+
return undefined;
|
|
37
|
+
try {
|
|
38
|
+
return JSON.parse(snapshot.data);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** List available snapshots (metadata only, no data payload). */
|
|
45
|
+
list() {
|
|
46
|
+
return this.snapshots.map(({ timestamp, label }) => ({ timestamp, label }));
|
|
47
|
+
}
|
|
48
|
+
/** Clear all snapshots. */
|
|
49
|
+
clear() {
|
|
50
|
+
this.snapshots = [];
|
|
51
|
+
this.persist();
|
|
52
|
+
}
|
|
53
|
+
persist() {
|
|
54
|
+
if (!this.storageKey)
|
|
55
|
+
return;
|
|
56
|
+
try {
|
|
57
|
+
localStorage.setItem(this.storageKey, JSON.stringify(this.snapshots));
|
|
58
|
+
}
|
|
59
|
+
catch { /* quota exceeded — skip silently */ }
|
|
60
|
+
}
|
|
61
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -15,11 +15,9 @@ import {
|
|
|
15
15
|
HEADER_SIG,
|
|
16
16
|
HEADER_TS,
|
|
17
17
|
HEADER_NONCE,
|
|
18
|
-
HEADER_ALG,
|
|
19
18
|
HEADER_PUB,
|
|
20
19
|
HEADER_CONTENT_TYPE,
|
|
21
20
|
HEADER_ACCEPT,
|
|
22
|
-
DEFAULT_ALG,
|
|
23
21
|
signAppendAuthor,
|
|
24
22
|
signRequest,
|
|
25
23
|
stableStringify
|
|
@@ -129,23 +127,19 @@ var StarfishClient = class {
|
|
|
129
127
|
* presenter` bind the server checks.
|
|
130
128
|
*/
|
|
131
129
|
async capRequestHeaders(capCtx, method, pathAndQuery, body) {
|
|
132
|
-
const { cap, devEdPrivHex, pubHex
|
|
130
|
+
const { cap, devEdPrivHex, pubHex } = capCtx;
|
|
133
131
|
const req = {
|
|
134
132
|
method,
|
|
135
133
|
pathAndQuery,
|
|
136
134
|
body,
|
|
137
135
|
host: this.signingHost()
|
|
138
136
|
};
|
|
139
|
-
const
|
|
140
|
-
const { alg, sig, ts, nonce } = await signRequest(req, devEdPrivHex, {
|
|
141
|
-
alg: signAlg
|
|
142
|
-
});
|
|
137
|
+
const { sig, ts, nonce } = await signRequest(req, devEdPrivHex);
|
|
143
138
|
const headers = {
|
|
144
139
|
[HEADER_AUTHORIZATION]: `Cap ${encodeCapAuth(cap)}`,
|
|
145
140
|
[HEADER_SIG]: sig,
|
|
146
141
|
[HEADER_TS]: String(ts),
|
|
147
|
-
[HEADER_NONCE]: nonce
|
|
148
|
-
[HEADER_ALG]: alg
|
|
142
|
+
[HEADER_NONCE]: nonce
|
|
149
143
|
};
|
|
150
144
|
if (pubHex !== void 0) headers[HEADER_PUB] = pubHex;
|
|
151
145
|
return headers;
|
|
@@ -159,11 +153,10 @@ var StarfishClient = class {
|
|
|
159
153
|
* unsigned and a server requiring signatures rejects it.
|
|
160
154
|
*/
|
|
161
155
|
appendAuthorKey(capCtx) {
|
|
162
|
-
const { cap, pubHex
|
|
156
|
+
const { cap, pubHex } = capCtx;
|
|
163
157
|
const authorPubHex = pubHex ?? cap.sub;
|
|
164
158
|
if (authorPubHex === void 0) return null;
|
|
165
|
-
|
|
166
|
-
return { authorPubHex, signAlg };
|
|
159
|
+
return { authorPubHex };
|
|
167
160
|
}
|
|
168
161
|
async pull(path, checkpointOrOptions) {
|
|
169
162
|
let pathAndQuery = this.applyNamespace(path);
|
|
@@ -326,8 +319,7 @@ var StarfishClient = class {
|
|
|
326
319
|
documentKey,
|
|
327
320
|
data,
|
|
328
321
|
authorKey.authorPubHex,
|
|
329
|
-
capCtx.devEdPrivHex
|
|
330
|
-
authorKey.signAlg
|
|
322
|
+
capCtx.devEdPrivHex
|
|
331
323
|
);
|
|
332
324
|
bodyObj[AUTHOR_PUBKEY_FIELD] = authorPubkey;
|
|
333
325
|
bodyObj[AUTHOR_SIGNATURE_FIELD] = authorSignature;
|
|
@@ -571,7 +563,6 @@ var SyncManager = class {
|
|
|
571
563
|
|
|
572
564
|
// src/append-log.ts
|
|
573
565
|
import {
|
|
574
|
-
DEFAULT_ALG as DEFAULT_ALG2,
|
|
575
566
|
verifyAppendAuthor
|
|
576
567
|
} from "@drakkar.software/starfish-protocol";
|
|
577
568
|
var PULL_PATH_PREFIX = "/pull/";
|
|
@@ -718,12 +709,12 @@ var AppendLogCursor = class {
|
|
|
718
709
|
if (policy.expectedAuthorPubkey && authorPubkey.toLowerCase() !== policy.expectedAuthorPubkey.toLowerCase()) {
|
|
719
710
|
throw new AppendAuthorError(el.ts);
|
|
720
711
|
}
|
|
712
|
+
void policy;
|
|
721
713
|
const ok = verifyAppendAuthor(
|
|
722
714
|
this.documentKey,
|
|
723
715
|
el.data,
|
|
724
716
|
authorPubkey,
|
|
725
|
-
authorSignature
|
|
726
|
-
policy.alg ?? DEFAULT_ALG2
|
|
717
|
+
authorSignature
|
|
727
718
|
);
|
|
728
719
|
if (!ok) throw new AppendAuthorError(el.ts);
|
|
729
720
|
}
|