@interop/was-react 0.19.0 → 0.20.0
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 +4 -3
- package/dist/auth/verifyResponse.d.ts.map +1 -1
- package/dist/auth/verifyResponse.js +10 -5
- package/dist/auth/verifyResponse.js.map +1 -1
- package/dist/identity/agents.d.ts +5 -0
- package/dist/identity/agents.d.ts.map +1 -1
- package/dist/identity/agents.js +10 -3
- package/dist/identity/agents.js.map +1 -1
- package/dist/identity/seedCredential.d.ts +5 -1
- package/dist/identity/seedCredential.d.ts.map +1 -1
- package/dist/identity/seedCredential.js +15 -28
- package/dist/identity/seedCredential.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/dist/react/hooks.d.ts +3 -2
- package/dist/react/hooks.d.ts.map +1 -1
- package/dist/react/hooks.js +8 -4
- package/dist/react/hooks.js.map +1 -1
- package/dist/session/authStore.d.ts +9 -0
- package/dist/session/authStore.d.ts.map +1 -1
- package/dist/session/authStore.js +69 -40
- package/dist/session/authStore.js.map +1 -1
- package/dist/session/localWipe.d.ts +1 -1
- package/dist/session/localWipe.js +2 -2
- package/dist/session/localWipe.js.map +1 -1
- package/dist/storage/adopt.d.ts +4 -1
- package/dist/storage/adopt.d.ts.map +1 -1
- package/dist/storage/adopt.js +4 -3
- package/dist/storage/adopt.js.map +1 -1
- package/dist/storage/entityStore.d.ts.map +1 -1
- package/dist/storage/entityStore.js +3 -0
- package/dist/storage/entityStore.js.map +1 -1
- package/dist/storage/publicUrl.js +3 -3
- package/dist/storage/storageContext.d.ts +175 -0
- package/dist/storage/storageContext.d.ts.map +1 -0
- package/dist/storage/storageContext.js +327 -0
- package/dist/storage/storageContext.js.map +1 -0
- package/dist/storage/storageManager.d.ts +57 -76
- package/dist/storage/storageManager.d.ts.map +1 -1
- package/dist/storage/storageManager.js +55 -150
- package/dist/storage/storageManager.js.map +1 -1
- package/dist/storage/syncController.d.ts +10 -1
- package/dist/storage/syncController.d.ts.map +1 -1
- package/dist/storage/syncController.js +12 -4
- package/dist/storage/syncController.js.map +1 -1
- package/dist/storage/syncStatusStore.d.ts +23 -2
- package/dist/storage/syncStatusStore.d.ts.map +1 -1
- package/dist/storage/syncStatusStore.js +22 -13
- package/dist/storage/syncStatusStore.js.map +1 -1
- package/dist/storage/writerId.d.ts +36 -0
- package/dist/storage/writerId.d.ts.map +1 -0
- package/dist/storage/writerId.js +76 -0
- package/dist/storage/writerId.js.map +1 -0
- package/package.json +9 -9
- package/dist/storage/rehydrate.d.ts +0 -64
- package/dist/storage/rehydrate.d.ts.map +0 -1
- package/dist/storage/rehydrate.js +0 -132
- package/dist/storage/rehydrate.js.map +0 -1
|
@@ -2,20 +2,29 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* The per-collection replication status store, mirroring the WAS per-replica
|
|
6
|
+
* sync-status vocabulary, keyed by the registry's logical collection key. One
|
|
7
|
+
* is created per {@link StorageContext} (so per session provider, never
|
|
8
|
+
* process-wide): the sync controller writes to it off the RxDB replication
|
|
9
|
+
* `active$` / `error$` streams, and `useSyncStatus` reads it through the
|
|
10
|
+
* provider. In-memory only, like the session -- reset on logout.
|
|
10
11
|
*/
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
import { createStore } from 'zustand/vanilla';
|
|
13
|
+
/**
|
|
14
|
+
* Creates one session's sync status store (a vanilla zustand store; subscribe
|
|
15
|
+
* to it from React with zustand's `useStore`).
|
|
16
|
+
*
|
|
17
|
+
* @returns {SyncStatusStore}
|
|
18
|
+
*/
|
|
19
|
+
export function createSyncStatusStore() {
|
|
20
|
+
return createStore()(set => ({
|
|
21
|
+
statuses: {},
|
|
22
|
+
setStatus: (collectionKey, status) => set(state => ({
|
|
23
|
+
statuses: { ...state.statuses, [collectionKey]: status }
|
|
24
|
+
})),
|
|
25
|
+
reset: () => set({ statuses: {} })
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
19
28
|
/**
|
|
20
29
|
* Rolls the per-collection replication statuses up to a single aggregate plus
|
|
21
30
|
* its display copy. With no collections registered it reports `offline`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncStatusStore.js","sourceRoot":"","sources":["../../src/storage/syncStatusStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"syncStatusStore.js","sourceRoot":"","sources":["../../src/storage/syncStatusStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;GAOG;AACH,OAAO,EAAE,WAAW,EAAiB,MAAM,iBAAiB,CAAA;AA0B5D;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,WAAW,EAAmB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5C,QAAQ,EAAE,EAAE;QACZ,SAAS,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,CACnC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACZ,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE;SACzD,CAAC,CAAC;QACL,KAAK,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;KACnC,CAAC,CAAC,CAAA;AACL,CAAC;AASD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAsB;IAKrD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,mDAAmD;SAC3D,CAAA;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL,KAAK,EAAE,OAAO;YACd,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,+DAA+D;SACvE,CAAA;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9D,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,SAAS;YAChB,KAAK,EAAE,sDAAsD;SAC9D,CAAA;IACH,CAAC;IACD,OAAO;QACL,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE,oDAAoD;KAC5D,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A stable per-install writer id (the last-write-wins tiebreak stamped into
|
|
3
|
+
* every payload), persisted in localStorage under `<prefix>writerId`. In an
|
|
4
|
+
* environment without `localStorage` it falls back to a process-stable
|
|
5
|
+
* unpersisted id instead of throwing.
|
|
6
|
+
*
|
|
7
|
+
* The id is an unkeyed, clearable attribution label -- never an identity. On a
|
|
8
|
+
* miss it adopts a value left under the pre-rename `<prefix>clientId` key and
|
|
9
|
+
* removes the old one, so an existing install keeps stamping the same id
|
|
10
|
+
* across the rename rather than looking like a second writer.
|
|
11
|
+
*
|
|
12
|
+
* @param [options] {object}
|
|
13
|
+
* @param [options.storageKeyPrefix] {string} the localStorage key prefix
|
|
14
|
+
* (defaults to {@link DEFAULT_STORAGE_KEY_PREFIX})
|
|
15
|
+
* @returns {string}
|
|
16
|
+
*/
|
|
17
|
+
export declare function getWriterId({ storageKeyPrefix }?: {
|
|
18
|
+
storageKeyPrefix?: string;
|
|
19
|
+
}): string;
|
|
20
|
+
/**
|
|
21
|
+
* Clears the persisted writer id (the clear-data grade of the wipe): removes
|
|
22
|
+
* both the current key and the pre-rename one, so nothing this library wrote
|
|
23
|
+
* survives in localStorage. Only persistence is touched; the running session's
|
|
24
|
+
* in-memory id is replaced by {@link StorageContext.resetWriterId}, because the
|
|
25
|
+
* session keeps running over its new anonymous replica and its write verbs
|
|
26
|
+
* still have to stamp.
|
|
27
|
+
*
|
|
28
|
+
* @param [options] {object}
|
|
29
|
+
* @param [options.storageKeyPrefix] {string} the localStorage key prefix
|
|
30
|
+
* (defaults to {@link DEFAULT_STORAGE_KEY_PREFIX})
|
|
31
|
+
* @returns {void}
|
|
32
|
+
*/
|
|
33
|
+
export declare function clearPersistedWriterId({ storageKeyPrefix }?: {
|
|
34
|
+
storageKeyPrefix?: string;
|
|
35
|
+
}): void;
|
|
36
|
+
//# sourceMappingURL=writerId.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writerId.d.ts","sourceRoot":"","sources":["../../src/storage/writerId.ts"],"names":[],"mappings":"AAqBA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,EAC1B,gBAA6C,EAC9C,GAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAe7C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,gBAA6C,EAC9C,GAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,IAAI,CAQ3C"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Persistence of the per-install writer id: the last-write-wins tiebreak the
|
|
6
|
+
* storage context stamps into every payload. {@link getWriterId} resolves it
|
|
7
|
+
* from localStorage (minting one on a miss), {@link clearPersistedWriterId}
|
|
8
|
+
* removes it (the clear-data grade of the wipe). The in-memory value a session
|
|
9
|
+
* stamps with lives on its {@link StorageContext}; nothing here holds state
|
|
10
|
+
* beyond the no-localStorage fallback.
|
|
11
|
+
*/
|
|
12
|
+
import { uuidv7 } from 'uuidv7';
|
|
13
|
+
import { DEFAULT_STORAGE_KEY_PREFIX } from '../config.js';
|
|
14
|
+
/**
|
|
15
|
+
* The unpersisted fallback writer id for environments without `localStorage`
|
|
16
|
+
* (tests, SSR): process-stable, so every resolution within one run agrees,
|
|
17
|
+
* minted fresh on the next run.
|
|
18
|
+
*/
|
|
19
|
+
let fallbackWriterId = null;
|
|
20
|
+
/**
|
|
21
|
+
* A stable per-install writer id (the last-write-wins tiebreak stamped into
|
|
22
|
+
* every payload), persisted in localStorage under `<prefix>writerId`. In an
|
|
23
|
+
* environment without `localStorage` it falls back to a process-stable
|
|
24
|
+
* unpersisted id instead of throwing.
|
|
25
|
+
*
|
|
26
|
+
* The id is an unkeyed, clearable attribution label -- never an identity. On a
|
|
27
|
+
* miss it adopts a value left under the pre-rename `<prefix>clientId` key and
|
|
28
|
+
* removes the old one, so an existing install keeps stamping the same id
|
|
29
|
+
* across the rename rather than looking like a second writer.
|
|
30
|
+
*
|
|
31
|
+
* @param [options] {object}
|
|
32
|
+
* @param [options.storageKeyPrefix] {string} the localStorage key prefix
|
|
33
|
+
* (defaults to {@link DEFAULT_STORAGE_KEY_PREFIX})
|
|
34
|
+
* @returns {string}
|
|
35
|
+
*/
|
|
36
|
+
export function getWriterId({ storageKeyPrefix = DEFAULT_STORAGE_KEY_PREFIX } = {}) {
|
|
37
|
+
const writerIdKey = `${storageKeyPrefix}writerId`;
|
|
38
|
+
const legacyKey = `${storageKeyPrefix}clientId`;
|
|
39
|
+
try {
|
|
40
|
+
let id = localStorage.getItem(writerIdKey);
|
|
41
|
+
if (!id) {
|
|
42
|
+
id = localStorage.getItem(legacyKey) || uuidv7();
|
|
43
|
+
localStorage.setItem(writerIdKey, id);
|
|
44
|
+
localStorage.removeItem(legacyKey);
|
|
45
|
+
}
|
|
46
|
+
return id;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
fallbackWriterId ??= uuidv7();
|
|
50
|
+
return fallbackWriterId;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Clears the persisted writer id (the clear-data grade of the wipe): removes
|
|
55
|
+
* both the current key and the pre-rename one, so nothing this library wrote
|
|
56
|
+
* survives in localStorage. Only persistence is touched; the running session's
|
|
57
|
+
* in-memory id is replaced by {@link StorageContext.resetWriterId}, because the
|
|
58
|
+
* session keeps running over its new anonymous replica and its write verbs
|
|
59
|
+
* still have to stamp.
|
|
60
|
+
*
|
|
61
|
+
* @param [options] {object}
|
|
62
|
+
* @param [options.storageKeyPrefix] {string} the localStorage key prefix
|
|
63
|
+
* (defaults to {@link DEFAULT_STORAGE_KEY_PREFIX})
|
|
64
|
+
* @returns {void}
|
|
65
|
+
*/
|
|
66
|
+
export function clearPersistedWriterId({ storageKeyPrefix = DEFAULT_STORAGE_KEY_PREFIX } = {}) {
|
|
67
|
+
try {
|
|
68
|
+
localStorage.removeItem(`${storageKeyPrefix}writerId`);
|
|
69
|
+
localStorage.removeItem(`${storageKeyPrefix}clientId`);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// No localStorage in this environment: nothing was persisted to clear.
|
|
73
|
+
}
|
|
74
|
+
fallbackWriterId = null;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=writerId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writerId.js","sourceRoot":"","sources":["../../src/storage/writerId.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;GAOG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAA;AAEzD;;;;GAIG;AACH,IAAI,gBAAgB,GAAkB,IAAI,CAAA;AAE1C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,gBAAgB,GAAG,0BAA0B,KACZ,EAAE;IACnC,MAAM,WAAW,GAAG,GAAG,gBAAgB,UAAU,CAAA;IACjD,MAAM,SAAS,GAAG,GAAG,gBAAgB,UAAU,CAAA;IAC/C,IAAI,CAAC;QACH,IAAI,EAAE,GAAG,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;QAC1C,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,EAAE,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,MAAM,EAAE,CAAA;YAChD,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;YACrC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;QACpC,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB,KAAK,MAAM,EAAE,CAAA;QAC7B,OAAO,gBAAgB,CAAA;IACzB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CAAC,EACrC,gBAAgB,GAAG,0BAA0B,KACZ,EAAE;IACnC,IAAI,CAAC;QACH,YAAY,CAAC,UAAU,CAAC,GAAG,gBAAgB,UAAU,CAAC,CAAA;QACtD,YAAY,CAAC,UAAU,CAAC,GAAG,gBAAgB,UAAU,CAAC,CAAA;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;IACzE,CAAC;IACD,gBAAgB,GAAG,IAAI,CAAA;AACzB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interop/was-react",
|
|
3
3
|
"description": "React library for building 'Bring Your Own Everything' (BYOE) apps on Wallet Attached Storage: DID Auth login via CHAPI wallet, local-first encrypted storage, and background sync to a WAS server.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.20.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "pnpm run clear && tsc",
|
|
@@ -47,15 +47,15 @@
|
|
|
47
47
|
"sideEffects": false,
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@interop/data-integrity-core": "^8.7.1",
|
|
50
|
-
"@interop/did-method-webvh": "^5.6.
|
|
51
|
-
"@interop/ed25519-signature": "^7.
|
|
52
|
-
"@interop/ezcap": "^7.4.
|
|
53
|
-
"@interop/security-document-loader": "^10.0
|
|
50
|
+
"@interop/did-method-webvh": "^5.6.1",
|
|
51
|
+
"@interop/ed25519-signature": "^7.2.0",
|
|
52
|
+
"@interop/ezcap": "^7.4.5",
|
|
53
|
+
"@interop/security-document-loader": "^10.1.0",
|
|
54
54
|
"@interop/vc": "^11.0.7",
|
|
55
55
|
"@interop/verifier-core": "^3.5.5",
|
|
56
|
-
"@interop/wallet-core": "^0.
|
|
57
|
-
"@interop/was-client": "^0.
|
|
58
|
-
"@interop/webkms-client": "^14.7.
|
|
56
|
+
"@interop/wallet-core": "^0.66.0",
|
|
57
|
+
"@interop/was-client": "^0.47.0",
|
|
58
|
+
"@interop/webkms-client": "^14.7.4",
|
|
59
59
|
"@scure/base": "^2.2.0",
|
|
60
60
|
"byoe-context": "^0.5.0",
|
|
61
61
|
"credential-handler-polyfill": "^4.1.0",
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"typescript-eslint": "^8.59.4",
|
|
111
111
|
"vite": "^8.0.14",
|
|
112
112
|
"vitest": "^4.1.7",
|
|
113
|
-
"was-teaching-server": "^0.
|
|
113
|
+
"was-teaching-server": "^0.25.1",
|
|
114
114
|
"zustand": "^5.0.12"
|
|
115
115
|
},
|
|
116
116
|
"publishConfig": {
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* The hydration MECHANISM: the per-collection re-hydrate hooks (decrypt the
|
|
6
|
-
* localStore rows into the app's stores) plus the debounced remote-change
|
|
7
|
-
* scheduler used by every sync entry point. Generic over an injected
|
|
8
|
-
* {@link StoreRegistry} -- the app supplies the concrete per-collection
|
|
9
|
-
* handlers; nothing here knows the domain entities.
|
|
10
|
-
*/
|
|
11
|
-
import type { Json } from '../sync/index.js';
|
|
12
|
-
import type { StoreRegistry } from '../config.js';
|
|
13
|
-
/**
|
|
14
|
-
* Hydrates every registered store from the (already opened) localStore.
|
|
15
|
-
*
|
|
16
|
-
* @param registry {StoreRegistry}
|
|
17
|
-
* @returns {Promise<void>}
|
|
18
|
-
*/
|
|
19
|
-
export declare function hydrateAll(registry: StoreRegistry): Promise<void>;
|
|
20
|
-
/**
|
|
21
|
-
* Empties every registered store (logout).
|
|
22
|
-
*
|
|
23
|
-
* @param registry {StoreRegistry}
|
|
24
|
-
* @returns {void}
|
|
25
|
-
*/
|
|
26
|
-
export declare function clearAllEntityStores(registry: StoreRegistry): void;
|
|
27
|
-
/**
|
|
28
|
-
* Patches ONE store from a single RxDB change event (per-doc, no whole-collection
|
|
29
|
-
* re-hydrate): decrypt the changed envelope, then upsert the payload (INSERT /
|
|
30
|
-
* UPDATE, including conflict-resolved rows) or drop it (DELETE / tombstone). The
|
|
31
|
-
* `uuid -> envelopeId` index is kept in step so a later local edit of a
|
|
32
|
-
* remotely-created doc still finds its envelope. Falls back to a debounced
|
|
33
|
-
* whole-collection re-hydrate if the envelope is missing or fails to decrypt.
|
|
34
|
-
*
|
|
35
|
-
* @param registry {StoreRegistry}
|
|
36
|
-
* @param collectionKey {string}
|
|
37
|
-
* @param event {object} an RxDB change event (operation + documentData)
|
|
38
|
-
* @returns {Promise<void>}
|
|
39
|
-
*/
|
|
40
|
-
export declare function patchFromChange(registry: StoreRegistry, collectionKey: string, event: {
|
|
41
|
-
operation: string;
|
|
42
|
-
documentData?: {
|
|
43
|
-
id: string;
|
|
44
|
-
data?: Json;
|
|
45
|
-
_deleted?: boolean;
|
|
46
|
-
};
|
|
47
|
-
}): Promise<void>;
|
|
48
|
-
/**
|
|
49
|
-
* Schedules a debounced re-hydrate of one collection's store after a pull.
|
|
50
|
-
*
|
|
51
|
-
* @param registry {StoreRegistry}
|
|
52
|
-
* @param collectionKey {string}
|
|
53
|
-
* @returns {void}
|
|
54
|
-
*/
|
|
55
|
-
export declare function scheduleRehydrate(registry: StoreRegistry, collectionKey: string): void;
|
|
56
|
-
/**
|
|
57
|
-
* Cancels every pending debounced re-hydrate. Called on logout so a timer that
|
|
58
|
-
* fires after the LocalStore is torn down does not reach a `requireStore()` that
|
|
59
|
-
* throws (an unhandled rejection).
|
|
60
|
-
*
|
|
61
|
-
* @returns {void}
|
|
62
|
-
*/
|
|
63
|
-
export declare function cancelScheduledRehydrates(): void;
|
|
64
|
-
//# sourceMappingURL=rehydrate.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rehydrate.d.ts","sourceRoot":"","sources":["../../src/storage/rehydrate.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAGjD;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAIlE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,aAAa,EACvB,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE;IACL,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,IAAI,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAC/D,GACA,OAAO,CAAC,IAAI,CAAC,CAsDf;AAOD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,aAAa,EACvB,aAAa,EAAE,MAAM,GACpB,IAAI,CAqBN;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAKhD"}
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { hasStore, requireStore } from './storageManager.js';
|
|
2
|
-
/**
|
|
3
|
-
* Hydrates every registered store from the (already opened) localStore.
|
|
4
|
-
*
|
|
5
|
-
* @param registry {StoreRegistry}
|
|
6
|
-
* @returns {Promise<void>}
|
|
7
|
-
*/
|
|
8
|
-
export async function hydrateAll(registry) {
|
|
9
|
-
await Promise.all(Object.values(registry).map(entry => entry.hydrate()));
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Empties every registered store (logout).
|
|
13
|
-
*
|
|
14
|
-
* @param registry {StoreRegistry}
|
|
15
|
-
* @returns {void}
|
|
16
|
-
*/
|
|
17
|
-
export function clearAllEntityStores(registry) {
|
|
18
|
-
for (const entry of Object.values(registry)) {
|
|
19
|
-
entry.clear();
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Patches ONE store from a single RxDB change event (per-doc, no whole-collection
|
|
24
|
-
* re-hydrate): decrypt the changed envelope, then upsert the payload (INSERT /
|
|
25
|
-
* UPDATE, including conflict-resolved rows) or drop it (DELETE / tombstone). The
|
|
26
|
-
* `uuid -> envelopeId` index is kept in step so a later local edit of a
|
|
27
|
-
* remotely-created doc still finds its envelope. Falls back to a debounced
|
|
28
|
-
* whole-collection re-hydrate if the envelope is missing or fails to decrypt.
|
|
29
|
-
*
|
|
30
|
-
* @param registry {StoreRegistry}
|
|
31
|
-
* @param collectionKey {string}
|
|
32
|
-
* @param event {object} an RxDB change event (operation + documentData)
|
|
33
|
-
* @returns {Promise<void>}
|
|
34
|
-
*/
|
|
35
|
-
export async function patchFromChange(registry, collectionKey, event) {
|
|
36
|
-
const entry = registry[collectionKey];
|
|
37
|
-
if (!entry) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
const row = event.documentData;
|
|
41
|
-
const envelope = row?.data;
|
|
42
|
-
const deleted = event.operation === 'DELETE' || row?._deleted === true;
|
|
43
|
-
if (!row || envelope === undefined) {
|
|
44
|
-
scheduleRehydrate(registry, collectionKey);
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
// Capture the store BEFORE the decrypt await. This patch is fired floating
|
|
48
|
-
// off the RxDB change stream, so a logout/login teardown can clear or SWAP
|
|
49
|
-
// the process-wide holder while the decrypt is in flight; re-resolving the
|
|
50
|
-
// holder after the await would either throw (an unhandled rejection) or --
|
|
51
|
-
// worse -- write the previous session's payload and envelope id into the
|
|
52
|
-
// NEW session's replica. The captured store plus the identity re-check
|
|
53
|
-
// below makes a patch that outlives its store a silent no-op.
|
|
54
|
-
if (!hasStore()) {
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
const store = requireStore();
|
|
58
|
-
let payload;
|
|
59
|
-
try {
|
|
60
|
-
payload = await store.decryptEnvelope(collectionKey, envelope);
|
|
61
|
-
}
|
|
62
|
-
catch {
|
|
63
|
-
scheduleRehydrate(registry, collectionKey);
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
// Bail if the holder changed or closed across the await: this event belongs
|
|
67
|
-
// to the torn-down session, not the one now live.
|
|
68
|
-
if (!hasStore() || requireStore() !== store) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
if (deleted) {
|
|
72
|
-
// Only honor a tombstone for the envelope the entity currently lives in.
|
|
73
|
-
// A delete of a DIFFERENT envelope that decrypts to the same logical id is
|
|
74
|
-
// a stale duplicate being cleaned up (a reconciled singleton loser, or the
|
|
75
|
-
// pre-resurrection row of a locally re-created doc) -- dropping the live
|
|
76
|
-
// doc for it would undo the reconciliation/resurrection.
|
|
77
|
-
const mapped = store.envelopeIdFor(collectionKey, payload.id);
|
|
78
|
-
if (mapped !== undefined && mapped !== row.id) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
store.forgetEnvelope(collectionKey, payload.id);
|
|
82
|
-
entry.drop(payload.id);
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
store.rememberEnvelope(collectionKey, payload.id, row.id);
|
|
86
|
-
entry.upsert(payload);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Per-collection debounce timers coalescing a pull burst into one hydrate.
|
|
91
|
-
*/
|
|
92
|
-
const rehydrateTimers = new Map();
|
|
93
|
-
/**
|
|
94
|
-
* Schedules a debounced re-hydrate of one collection's store after a pull.
|
|
95
|
-
*
|
|
96
|
-
* @param registry {StoreRegistry}
|
|
97
|
-
* @param collectionKey {string}
|
|
98
|
-
* @returns {void}
|
|
99
|
-
*/
|
|
100
|
-
export function scheduleRehydrate(registry, collectionKey) {
|
|
101
|
-
const entry = registry[collectionKey];
|
|
102
|
-
if (!entry) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
const existing = rehydrateTimers.get(collectionKey);
|
|
106
|
-
if (existing) {
|
|
107
|
-
clearTimeout(existing);
|
|
108
|
-
}
|
|
109
|
-
rehydrateTimers.set(collectionKey, setTimeout(() => {
|
|
110
|
-
rehydrateTimers.delete(collectionKey);
|
|
111
|
-
// A timer that outlived logout must not touch a torn-down store: hydrate
|
|
112
|
-
// reaches for `requireStore()`, which throws once the store is cleared.
|
|
113
|
-
if (!hasStore()) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
void entry.hydrate();
|
|
117
|
-
}, 50));
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Cancels every pending debounced re-hydrate. Called on logout so a timer that
|
|
121
|
-
* fires after the LocalStore is torn down does not reach a `requireStore()` that
|
|
122
|
-
* throws (an unhandled rejection).
|
|
123
|
-
*
|
|
124
|
-
* @returns {void}
|
|
125
|
-
*/
|
|
126
|
-
export function cancelScheduledRehydrates() {
|
|
127
|
-
for (const timer of rehydrateTimers.values()) {
|
|
128
|
-
clearTimeout(timer);
|
|
129
|
-
}
|
|
130
|
-
rehydrateTimers.clear();
|
|
131
|
-
}
|
|
132
|
-
//# sourceMappingURL=rehydrate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rehydrate.js","sourceRoot":"","sources":["../../src/storage/rehydrate.ts"],"names":[],"mappings":"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"}
|