@hashtree/worker 0.1.14 → 0.1.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.
@@ -0,0 +1,201 @@
1
+ /**
2
+ * TreeRootRegistry - Browser-side single source of truth for tree root data
3
+ *
4
+ * This module provides:
5
+ * - Unified record format for all root data
6
+ * - Subscription API that emits cached data immediately, then updates
7
+ * - Async resolve with timeout for waiting on first resolution
8
+ * - Local write tracking with dirty flag for publish throttling
9
+ * - Pluggable persistence (localStorage by default)
10
+ *
11
+ * This module lives under @hashtree/worker because it coordinates with worker
12
+ * updates and publish flows, but it runs on the app/main thread.
13
+ */
14
+ import type { Hash, TreeVisibility } from '@hashtree/core';
15
+ /**
16
+ * Source of the tree root update
17
+ */
18
+ export type TreeRootSource = 'local-write' | 'nostr' | 'prefetch' | 'worker';
19
+ /**
20
+ * Core record format - single source of truth for all root data
21
+ */
22
+ export interface TreeRootRecord {
23
+ hash: Hash;
24
+ key?: Hash;
25
+ visibility: TreeVisibility;
26
+ labels?: string[];
27
+ updatedAt: number;
28
+ source: TreeRootSource;
29
+ dirty: boolean;
30
+ encryptedKey?: string;
31
+ keyId?: string;
32
+ selfEncryptedKey?: string;
33
+ selfEncryptedLinkKey?: string;
34
+ }
35
+ /**
36
+ * Listener callback type
37
+ */
38
+ type Listener = (record: TreeRootRecord | null) => void;
39
+ /**
40
+ * Persistence interface - allows swapping localStorage for IndexedDB/etc
41
+ */
42
+ export interface RegistryPersistence {
43
+ save(key: string, record: TreeRootRecord): void;
44
+ load(key: string): TreeRootRecord | null;
45
+ delete(key: string): void;
46
+ loadAll(): Map<string, TreeRootRecord>;
47
+ }
48
+ /**
49
+ * TreeRootRegistry - singleton class for managing tree root data
50
+ */
51
+ declare class TreeRootRegistryImpl {
52
+ private records;
53
+ private listeners;
54
+ private globalListeners;
55
+ private persistence;
56
+ private publishTimers;
57
+ private publishFn;
58
+ private publishDelay;
59
+ private retryDelay;
60
+ constructor(persistence?: RegistryPersistence);
61
+ /**
62
+ * Hydrate from persistence on startup
63
+ */
64
+ private hydrate;
65
+ /**
66
+ * Set the publish function (called with throttling for dirty records)
67
+ */
68
+ setPublishFn(fn: (npub: string, treeName: string, record: TreeRootRecord) => Promise<boolean>): void;
69
+ /**
70
+ * Build cache key from npub and treeName
71
+ */
72
+ private makeKey;
73
+ /**
74
+ * Notify listeners of a record change
75
+ */
76
+ private notify;
77
+ private shouldAcceptUpdate;
78
+ private mergeSameHashMetadata;
79
+ /**
80
+ * Sync lookup - returns cached record or null (no side effects)
81
+ */
82
+ get(npub: string, treeName: string): TreeRootRecord | null;
83
+ /**
84
+ * Get by key directly
85
+ */
86
+ getByKey(key: string): TreeRootRecord | null;
87
+ /**
88
+ * Async resolve - returns current record if cached, otherwise waits for first resolve
89
+ */
90
+ resolve(npub: string, treeName: string, options?: {
91
+ timeoutMs?: number;
92
+ }): Promise<TreeRootRecord | null>;
93
+ /**
94
+ * Subscribe to updates for a specific tree
95
+ * Emits current snapshot immediately if available, then future updates
96
+ */
97
+ subscribe(npub: string, treeName: string, callback: Listener): () => void;
98
+ /**
99
+ * Subscribe to all registry updates (for bridges like Tauri/worker)
100
+ */
101
+ subscribeAll(callback: (key: string, record: TreeRootRecord | null) => void): () => void;
102
+ /**
103
+ * Set record from local write - marks dirty and schedules publish
104
+ */
105
+ setLocal(npub: string, treeName: string, hash: Hash, options?: {
106
+ key?: Hash;
107
+ visibility?: TreeVisibility;
108
+ labels?: string[];
109
+ encryptedKey?: string;
110
+ keyId?: string;
111
+ selfEncryptedKey?: string;
112
+ selfEncryptedLinkKey?: string;
113
+ }): void;
114
+ /**
115
+ * Set record from resolver (Nostr event) - only updates if newer
116
+ */
117
+ setFromResolver(npub: string, treeName: string, hash: Hash, updatedAt: number, options?: {
118
+ key?: Hash;
119
+ visibility?: TreeVisibility;
120
+ labels?: string[];
121
+ encryptedKey?: string;
122
+ keyId?: string;
123
+ selfEncryptedKey?: string;
124
+ selfEncryptedLinkKey?: string;
125
+ }): boolean;
126
+ /**
127
+ * Merge a decrypted key into an existing record without changing updatedAt/source.
128
+ * Returns true if the record was updated.
129
+ */
130
+ mergeKey(npub: string, treeName: string, hash: Hash, key: Hash): boolean;
131
+ /**
132
+ * Set record from worker (Nostr subscription routed through worker)
133
+ * Similar to setFromResolver but source is 'worker'
134
+ */
135
+ setFromWorker(npub: string, treeName: string, hash: Hash, updatedAt: number, options?: {
136
+ key?: Hash;
137
+ visibility?: TreeVisibility;
138
+ labels?: string[];
139
+ encryptedKey?: string;
140
+ keyId?: string;
141
+ selfEncryptedKey?: string;
142
+ selfEncryptedLinkKey?: string;
143
+ }): boolean;
144
+ /**
145
+ * Set record from external source (Tauri, worker, prefetch)
146
+ */
147
+ setFromExternal(npub: string, treeName: string, hash: Hash, source: TreeRootSource, options?: {
148
+ key?: Hash;
149
+ visibility?: TreeVisibility;
150
+ labels?: string[];
151
+ updatedAt?: number;
152
+ encryptedKey?: string;
153
+ keyId?: string;
154
+ selfEncryptedKey?: string;
155
+ selfEncryptedLinkKey?: string;
156
+ }): void;
157
+ /**
158
+ * Delete a record
159
+ */
160
+ delete(npub: string, treeName: string): void;
161
+ /**
162
+ * Schedule a throttled publish
163
+ */
164
+ private schedulePublish;
165
+ /**
166
+ * Execute the publish
167
+ */
168
+ private doPublish;
169
+ /**
170
+ * Force immediate publish of all dirty records
171
+ */
172
+ flushPendingPublishes(): Promise<void>;
173
+ /**
174
+ * Cancel pending publish (call before delete to prevent "undelete")
175
+ */
176
+ cancelPendingPublish(npub: string, treeName: string): void;
177
+ /**
178
+ * Get all records (for debugging/migration)
179
+ */
180
+ getAllRecords(): Map<string, TreeRootRecord>;
181
+ /**
182
+ * Check if a record exists
183
+ */
184
+ has(npub: string, treeName: string): boolean;
185
+ /**
186
+ * Get visibility for a tree
187
+ */
188
+ getVisibility(npub: string, treeName: string): TreeVisibility | undefined;
189
+ /**
190
+ * Get labels for a tree
191
+ */
192
+ getLabels(npub: string, treeName: string): string[] | undefined;
193
+ }
194
+ declare global {
195
+ interface Window {
196
+ __treeRootRegistry?: TreeRootRegistryImpl;
197
+ }
198
+ }
199
+ export declare const treeRootRegistry: TreeRootRegistryImpl;
200
+ export type { TreeRootRecord as TreeRootEntry };
201
+ //# sourceMappingURL=tree-root.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-root.d.ts","sourceRoot":"","sources":["../src/tree-root.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAG3D;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE7E;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,IAAI,CAAC;IACX,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,cAAc,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IAGf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAmBD;;GAEG;AACH,KAAK,QAAQ,GAAG,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAAC;IACzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACxC;AAqHD;;GAEG;AACH,cAAM,oBAAoB;IACxB,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,eAAe,CAAmE;IAC1F,OAAO,CAAC,WAAW,CAAsB;IAGzC,OAAO,CAAC,aAAa,CAAoD;IACzE,OAAO,CAAC,SAAS,CAA+F;IAChH,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,UAAU,CAAQ;gBAEd,WAAW,CAAC,EAAE,mBAAmB;IAK7C;;OAEG;IACH,OAAO,CAAC,OAAO;IAgBf;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAIpG;;OAEG;IACH,OAAO,CAAC,OAAO;IAIf;;OAEG;IACH,OAAO,CAAC,MAAM;IAsBd,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,qBAAqB;IA0D7B;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAI1D;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAI5C;;OAEG;IACG,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAC/B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAgCjC;;;OAGG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,IAAI;IA4BzE;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI;IAOxF;;OAEG;IACH,QAAQ,CACN,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE;QACR,GAAG,CAAC,EAAE,IAAI,CAAC;QACX,UAAU,CAAC,EAAE,cAAc,CAAC;QAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,GACA,IAAI;IA2BP;;OAEG;IACH,eAAe,CACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;QACR,GAAG,CAAC,EAAE,IAAI,CAAC;QACX,UAAU,CAAC,EAAE,cAAc,CAAC;QAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,GACA,OAAO;IAoCV;;;OAGG;IACH,QAAQ,CACN,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,IAAI,GACR,OAAO;IAcV;;;OAGG;IACH,aAAa,CACX,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;QACR,GAAG,CAAC,EAAE,IAAI,CAAC;QACX,UAAU,CAAC,EAAE,cAAc,CAAC;QAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,GACA,OAAO;IAoCV;;OAEG;IACH,eAAe,CACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE;QACR,GAAG,CAAC,EAAE,IAAI,CAAC;QACX,UAAU,CAAC,EAAE,cAAc,CAAC;QAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,GACA,IAAI;IAwCP;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAe5C;;OAEG;IACH,OAAO,CAAC,eAAe;IAkBvB;;OAEG;YACW,SAAS;IA8BvB;;OAEG;IACG,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB5C;;OAEG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAS1D;;OAEG;IACH,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAI5C;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI5C;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIzE;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;CAGhE;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;KAC3C;CACF;AAoCD,eAAO,MAAM,gBAAgB,sBAAgB,CAAC;AAG9C,YAAY,EAAE,cAAc,IAAI,aAAa,EAAE,CAAC"}
@@ -0,0 +1,632 @@
1
+ /**
2
+ * TreeRootRegistry - Browser-side single source of truth for tree root data
3
+ *
4
+ * This module provides:
5
+ * - Unified record format for all root data
6
+ * - Subscription API that emits cached data immediately, then updates
7
+ * - Async resolve with timeout for waiting on first resolution
8
+ * - Local write tracking with dirty flag for publish throttling
9
+ * - Pluggable persistence (localStorage by default)
10
+ *
11
+ * This module lives under @hashtree/worker because it coordinates with worker
12
+ * updates and publish flows, but it runs on the app/main thread.
13
+ */
14
+ import { fromHex, toHex } from '@hashtree/core';
15
+ const STORAGE_KEY = 'hashtree:localRootCache';
16
+ /**
17
+ * Default localStorage persistence
18
+ */
19
+ class LocalStoragePersistence {
20
+ cache = null;
21
+ serializeRecord(record) {
22
+ return {
23
+ hash: toHex(record.hash),
24
+ key: record.key ? toHex(record.key) : undefined,
25
+ visibility: record.visibility,
26
+ labels: record.labels,
27
+ updatedAt: record.updatedAt,
28
+ source: record.source,
29
+ dirty: record.dirty,
30
+ encryptedKey: record.encryptedKey,
31
+ keyId: record.keyId,
32
+ selfEncryptedKey: record.selfEncryptedKey,
33
+ selfEncryptedLinkKey: record.selfEncryptedLinkKey,
34
+ };
35
+ }
36
+ deserializeRecord(data) {
37
+ try {
38
+ return {
39
+ hash: fromHex(data.hash),
40
+ key: data.key ? fromHex(data.key) : undefined,
41
+ visibility: data.visibility,
42
+ labels: uniqueLabels(data.labels),
43
+ updatedAt: data.updatedAt,
44
+ source: data.source,
45
+ dirty: data.dirty,
46
+ encryptedKey: data.encryptedKey,
47
+ keyId: data.keyId,
48
+ selfEncryptedKey: data.selfEncryptedKey,
49
+ selfEncryptedLinkKey: data.selfEncryptedLinkKey,
50
+ };
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ }
56
+ save(key, record) {
57
+ if (typeof window === 'undefined')
58
+ return;
59
+ // Update in-memory cache
60
+ if (!this.cache) {
61
+ this.cache = this.loadAll();
62
+ }
63
+ this.cache.set(key, record);
64
+ // Persist to localStorage
65
+ try {
66
+ const data = {};
67
+ for (const [k, r] of this.cache.entries()) {
68
+ data[k] = this.serializeRecord(r);
69
+ }
70
+ window.localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
71
+ }
72
+ catch {
73
+ // Ignore persistence errors (storage may be full/unavailable)
74
+ }
75
+ }
76
+ load(key) {
77
+ if (!this.cache) {
78
+ this.cache = this.loadAll();
79
+ }
80
+ return this.cache.get(key) ?? null;
81
+ }
82
+ delete(key) {
83
+ if (typeof window === 'undefined')
84
+ return;
85
+ if (!this.cache) {
86
+ this.cache = this.loadAll();
87
+ }
88
+ this.cache.delete(key);
89
+ try {
90
+ const data = {};
91
+ for (const [k, r] of this.cache.entries()) {
92
+ data[k] = this.serializeRecord(r);
93
+ }
94
+ window.localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
95
+ }
96
+ catch {
97
+ // Ignore persistence errors
98
+ }
99
+ }
100
+ loadAll() {
101
+ const result = new Map();
102
+ if (typeof window === 'undefined')
103
+ return result;
104
+ try {
105
+ const raw = window.localStorage.getItem(STORAGE_KEY);
106
+ if (!raw)
107
+ return result;
108
+ const data = JSON.parse(raw);
109
+ for (const [key, persisted] of Object.entries(data)) {
110
+ const record = this.deserializeRecord(persisted);
111
+ if (record) {
112
+ result.set(key, record);
113
+ }
114
+ }
115
+ }
116
+ catch {
117
+ // Ignore parse errors
118
+ }
119
+ this.cache = result;
120
+ return result;
121
+ }
122
+ }
123
+ /**
124
+ * TreeRootRegistry - singleton class for managing tree root data
125
+ */
126
+ class TreeRootRegistryImpl {
127
+ records = new Map();
128
+ listeners = new Map();
129
+ globalListeners = new Set();
130
+ persistence;
131
+ // Publish throttling
132
+ publishTimers = new Map();
133
+ publishFn = null;
134
+ publishDelay = 1000;
135
+ retryDelay = 5000;
136
+ constructor(persistence) {
137
+ this.persistence = persistence ?? new LocalStoragePersistence();
138
+ this.hydrate();
139
+ }
140
+ /**
141
+ * Hydrate from persistence on startup
142
+ */
143
+ hydrate() {
144
+ const persisted = this.persistence.loadAll();
145
+ for (const [key, record] of persisted.entries()) {
146
+ this.records.set(key, record);
147
+ // Schedule publish for dirty entries
148
+ if (record.dirty) {
149
+ const [npub, ...treeNameParts] = key.split('/');
150
+ const treeName = treeNameParts.join('/');
151
+ if (npub && treeName) {
152
+ this.schedulePublish(npub, treeName);
153
+ }
154
+ }
155
+ }
156
+ }
157
+ /**
158
+ * Set the publish function (called with throttling for dirty records)
159
+ */
160
+ setPublishFn(fn) {
161
+ this.publishFn = fn;
162
+ }
163
+ /**
164
+ * Build cache key from npub and treeName
165
+ */
166
+ makeKey(npub, treeName) {
167
+ return `${npub}/${treeName}`;
168
+ }
169
+ /**
170
+ * Notify listeners of a record change
171
+ */
172
+ notify(key, record) {
173
+ const keyListeners = this.listeners.get(key);
174
+ if (keyListeners) {
175
+ for (const listener of keyListeners) {
176
+ try {
177
+ listener(record);
178
+ }
179
+ catch (e) {
180
+ console.error('[TreeRootRegistry] Listener error:', e);
181
+ }
182
+ }
183
+ }
184
+ // Notify global listeners
185
+ for (const listener of this.globalListeners) {
186
+ try {
187
+ listener(key, record);
188
+ }
189
+ catch (e) {
190
+ console.error('[TreeRootRegistry] Global listener error:', e);
191
+ }
192
+ }
193
+ }
194
+ shouldAcceptUpdate(existing, hash, key, updatedAt) {
195
+ if (!existing)
196
+ return true;
197
+ if (existing.dirty)
198
+ return false;
199
+ if (existing.updatedAt > updatedAt)
200
+ return false;
201
+ if (existing.updatedAt === updatedAt) {
202
+ if (toHex(existing.hash) === toHex(hash)) {
203
+ if (!key)
204
+ return false;
205
+ if (existing.key && toHex(existing.key) === toHex(key))
206
+ return false;
207
+ }
208
+ }
209
+ return true;
210
+ }
211
+ mergeSameHashMetadata(existing, hash, options) {
212
+ if (!existing)
213
+ return false;
214
+ if (existing.dirty)
215
+ return false;
216
+ if (toHex(existing.hash) !== toHex(hash))
217
+ return false;
218
+ let changed = false;
219
+ if (!existing.key && options?.key) {
220
+ existing.key = options.key;
221
+ changed = true;
222
+ }
223
+ if (existing.visibility === 'public' && options?.visibility && options.visibility !== 'public') {
224
+ existing.visibility = options.visibility;
225
+ changed = true;
226
+ }
227
+ const mergedLabels = mergeLabels(options?.labels, existing.labels);
228
+ if (mergedLabels && JSON.stringify(mergedLabels) !== JSON.stringify(existing.labels)) {
229
+ existing.labels = mergedLabels;
230
+ changed = true;
231
+ }
232
+ if (!existing.encryptedKey && options?.encryptedKey) {
233
+ existing.encryptedKey = options.encryptedKey;
234
+ changed = true;
235
+ }
236
+ if (!existing.keyId && options?.keyId) {
237
+ existing.keyId = options.keyId;
238
+ changed = true;
239
+ }
240
+ if (!existing.selfEncryptedKey && options?.selfEncryptedKey) {
241
+ existing.selfEncryptedKey = options.selfEncryptedKey;
242
+ changed = true;
243
+ }
244
+ if (!existing.selfEncryptedLinkKey && options?.selfEncryptedLinkKey) {
245
+ existing.selfEncryptedLinkKey = options.selfEncryptedLinkKey;
246
+ changed = true;
247
+ }
248
+ return changed;
249
+ }
250
+ /**
251
+ * Sync lookup - returns cached record or null (no side effects)
252
+ */
253
+ get(npub, treeName) {
254
+ return this.records.get(this.makeKey(npub, treeName)) ?? null;
255
+ }
256
+ /**
257
+ * Get by key directly
258
+ */
259
+ getByKey(key) {
260
+ return this.records.get(key) ?? null;
261
+ }
262
+ /**
263
+ * Async resolve - returns current record if cached, otherwise waits for first resolve
264
+ */
265
+ async resolve(npub, treeName, options) {
266
+ const key = this.makeKey(npub, treeName);
267
+ const existing = this.records.get(key);
268
+ if (existing) {
269
+ return existing;
270
+ }
271
+ const timeoutMs = options?.timeoutMs ?? 10000;
272
+ return new Promise((resolve) => {
273
+ let resolved = false;
274
+ let unsubscribe = null;
275
+ const timeout = setTimeout(() => {
276
+ if (!resolved) {
277
+ resolved = true;
278
+ unsubscribe?.();
279
+ resolve(null);
280
+ }
281
+ }, timeoutMs);
282
+ unsubscribe = this.subscribe(npub, treeName, (record) => {
283
+ if (!resolved && record) {
284
+ resolved = true;
285
+ clearTimeout(timeout);
286
+ unsubscribe?.();
287
+ resolve(record);
288
+ }
289
+ });
290
+ });
291
+ }
292
+ /**
293
+ * Subscribe to updates for a specific tree
294
+ * Emits current snapshot immediately if available, then future updates
295
+ */
296
+ subscribe(npub, treeName, callback) {
297
+ const key = this.makeKey(npub, treeName);
298
+ let keyListeners = this.listeners.get(key);
299
+ if (!keyListeners) {
300
+ keyListeners = new Set();
301
+ this.listeners.set(key, keyListeners);
302
+ }
303
+ keyListeners.add(callback);
304
+ // Emit current snapshot if available
305
+ const existing = this.records.get(key);
306
+ if (existing) {
307
+ // Use queueMicrotask to ensure callback is async
308
+ queueMicrotask(() => callback(existing));
309
+ }
310
+ return () => {
311
+ const listeners = this.listeners.get(key);
312
+ if (listeners) {
313
+ listeners.delete(callback);
314
+ if (listeners.size === 0) {
315
+ this.listeners.delete(key);
316
+ }
317
+ }
318
+ };
319
+ }
320
+ /**
321
+ * Subscribe to all registry updates (for bridges like Tauri/worker)
322
+ */
323
+ subscribeAll(callback) {
324
+ this.globalListeners.add(callback);
325
+ return () => {
326
+ this.globalListeners.delete(callback);
327
+ };
328
+ }
329
+ /**
330
+ * Set record from local write - marks dirty and schedules publish
331
+ */
332
+ setLocal(npub, treeName, hash, options) {
333
+ const cacheKey = this.makeKey(npub, treeName);
334
+ const existing = this.records.get(cacheKey);
335
+ // Preserve existing visibility if not provided
336
+ const visibility = options?.visibility ?? existing?.visibility ?? 'public';
337
+ const record = {
338
+ hash,
339
+ key: options?.key,
340
+ visibility,
341
+ labels: uniqueLabels(options?.labels) ?? existing?.labels,
342
+ updatedAt: Math.floor(Date.now() / 1000),
343
+ source: 'local-write',
344
+ dirty: true,
345
+ encryptedKey: options?.encryptedKey ?? existing?.encryptedKey,
346
+ keyId: options?.keyId ?? existing?.keyId,
347
+ selfEncryptedKey: options?.selfEncryptedKey ?? existing?.selfEncryptedKey,
348
+ selfEncryptedLinkKey: options?.selfEncryptedLinkKey ?? existing?.selfEncryptedLinkKey,
349
+ };
350
+ this.records.set(cacheKey, record);
351
+ this.persistence.save(cacheKey, record);
352
+ this.notify(cacheKey, record);
353
+ this.schedulePublish(npub, treeName);
354
+ }
355
+ /**
356
+ * Set record from resolver (Nostr event) - only updates if newer
357
+ */
358
+ setFromResolver(npub, treeName, hash, updatedAt, options) {
359
+ const cacheKey = this.makeKey(npub, treeName);
360
+ const existing = this.records.get(cacheKey);
361
+ const sameHash = !!existing && toHex(existing.hash) === toHex(hash);
362
+ // Only update if newer (based on updatedAt timestamp), or same timestamp with new hash/key
363
+ if (!this.shouldAcceptUpdate(existing ?? undefined, hash, options?.key, updatedAt)) {
364
+ if (this.mergeSameHashMetadata(existing ?? undefined, hash, options)) {
365
+ this.persistence.save(cacheKey, existing);
366
+ this.notify(cacheKey, existing);
367
+ return true;
368
+ }
369
+ return false;
370
+ }
371
+ const record = {
372
+ hash,
373
+ // Preserve known key when newer resolver updates omit it for the same hash.
374
+ key: options?.key ?? (sameHash ? existing?.key : undefined),
375
+ visibility: options?.visibility ?? 'public',
376
+ labels: uniqueLabels(options?.labels) ?? existing?.labels,
377
+ updatedAt,
378
+ source: 'nostr',
379
+ dirty: false,
380
+ encryptedKey: options?.encryptedKey ?? (sameHash ? existing?.encryptedKey : undefined),
381
+ keyId: options?.keyId ?? (sameHash ? existing?.keyId : undefined),
382
+ selfEncryptedKey: options?.selfEncryptedKey ?? (sameHash ? existing?.selfEncryptedKey : undefined),
383
+ selfEncryptedLinkKey: options?.selfEncryptedLinkKey ?? (sameHash ? existing?.selfEncryptedLinkKey : undefined),
384
+ };
385
+ this.records.set(cacheKey, record);
386
+ this.persistence.save(cacheKey, record);
387
+ this.notify(cacheKey, record);
388
+ return true;
389
+ }
390
+ /**
391
+ * Merge a decrypted key into an existing record without changing updatedAt/source.
392
+ * Returns true if the record was updated.
393
+ */
394
+ mergeKey(npub, treeName, hash, key) {
395
+ const cacheKey = this.makeKey(npub, treeName);
396
+ const existing = this.records.get(cacheKey);
397
+ if (!existing)
398
+ return false;
399
+ if (toHex(existing.hash) !== toHex(hash))
400
+ return false;
401
+ if (existing.key)
402
+ return false;
403
+ existing.key = key;
404
+ this.persistence.save(cacheKey, existing);
405
+ this.notify(cacheKey, existing);
406
+ return true;
407
+ }
408
+ /**
409
+ * Set record from worker (Nostr subscription routed through worker)
410
+ * Similar to setFromResolver but source is 'worker'
411
+ */
412
+ setFromWorker(npub, treeName, hash, updatedAt, options) {
413
+ const cacheKey = this.makeKey(npub, treeName);
414
+ const existing = this.records.get(cacheKey);
415
+ const sameHash = !!existing && toHex(existing.hash) === toHex(hash);
416
+ // Only update if newer (based on updatedAt timestamp), or same timestamp with new hash/key
417
+ if (!this.shouldAcceptUpdate(existing ?? undefined, hash, options?.key, updatedAt)) {
418
+ if (this.mergeSameHashMetadata(existing ?? undefined, hash, options)) {
419
+ this.persistence.save(cacheKey, existing);
420
+ this.notify(cacheKey, existing);
421
+ return true;
422
+ }
423
+ return false;
424
+ }
425
+ const record = {
426
+ hash,
427
+ // Preserve known key when worker updates omit it for the same hash.
428
+ key: options?.key ?? (sameHash ? existing?.key : undefined),
429
+ visibility: options?.visibility ?? 'public',
430
+ labels: uniqueLabels(options?.labels) ?? existing?.labels,
431
+ updatedAt,
432
+ source: 'worker',
433
+ dirty: false,
434
+ encryptedKey: options?.encryptedKey ?? (sameHash ? existing?.encryptedKey : undefined),
435
+ keyId: options?.keyId ?? (sameHash ? existing?.keyId : undefined),
436
+ selfEncryptedKey: options?.selfEncryptedKey ?? (sameHash ? existing?.selfEncryptedKey : undefined),
437
+ selfEncryptedLinkKey: options?.selfEncryptedLinkKey ?? (sameHash ? existing?.selfEncryptedLinkKey : undefined),
438
+ };
439
+ this.records.set(cacheKey, record);
440
+ this.persistence.save(cacheKey, record);
441
+ this.notify(cacheKey, record);
442
+ return true;
443
+ }
444
+ /**
445
+ * Set record from external source (Tauri, worker, prefetch)
446
+ */
447
+ setFromExternal(npub, treeName, hash, source, options) {
448
+ const cacheKey = this.makeKey(npub, treeName);
449
+ const existing = this.records.get(cacheKey);
450
+ const sameHash = !!existing && toHex(existing.hash) === toHex(hash);
451
+ // Don't overwrite dirty local writes
452
+ if (existing?.dirty) {
453
+ return;
454
+ }
455
+ const updatedAt = options?.updatedAt ?? Math.floor(Date.now() / 1000);
456
+ // Only update if newer (based on updatedAt timestamp), or same timestamp with new hash/key
457
+ if (!this.shouldAcceptUpdate(existing ?? undefined, hash, options?.key, updatedAt)) {
458
+ if (this.mergeSameHashMetadata(existing ?? undefined, hash, options)) {
459
+ this.persistence.save(cacheKey, existing);
460
+ this.notify(cacheKey, existing);
461
+ }
462
+ return;
463
+ }
464
+ const record = {
465
+ hash,
466
+ key: options?.key ?? (sameHash ? existing?.key : undefined),
467
+ visibility: options?.visibility ?? existing?.visibility ?? 'public',
468
+ labels: uniqueLabels(options?.labels) ?? existing?.labels,
469
+ updatedAt,
470
+ source,
471
+ dirty: false,
472
+ encryptedKey: options?.encryptedKey ?? (sameHash ? existing?.encryptedKey : undefined),
473
+ keyId: options?.keyId ?? (sameHash ? existing?.keyId : undefined),
474
+ selfEncryptedKey: options?.selfEncryptedKey ?? (sameHash ? existing?.selfEncryptedKey : undefined),
475
+ selfEncryptedLinkKey: options?.selfEncryptedLinkKey ?? (sameHash ? existing?.selfEncryptedLinkKey : undefined),
476
+ };
477
+ this.records.set(cacheKey, record);
478
+ this.persistence.save(cacheKey, record);
479
+ this.notify(cacheKey, record);
480
+ }
481
+ /**
482
+ * Delete a record
483
+ */
484
+ delete(npub, treeName) {
485
+ const key = this.makeKey(npub, treeName);
486
+ // Cancel any pending publish
487
+ const timer = this.publishTimers.get(key);
488
+ if (timer) {
489
+ clearTimeout(timer);
490
+ this.publishTimers.delete(key);
491
+ }
492
+ this.records.delete(key);
493
+ this.persistence.delete(key);
494
+ this.notify(key, null);
495
+ }
496
+ /**
497
+ * Schedule a throttled publish
498
+ */
499
+ schedulePublish(npub, treeName, delay = this.publishDelay) {
500
+ const key = this.makeKey(npub, treeName);
501
+ // Clear existing timer
502
+ const existingTimer = this.publishTimers.get(key);
503
+ if (existingTimer) {
504
+ clearTimeout(existingTimer);
505
+ }
506
+ // Schedule new publish
507
+ const timer = setTimeout(() => {
508
+ this.publishTimers.delete(key);
509
+ this.doPublish(npub, treeName);
510
+ }, delay);
511
+ this.publishTimers.set(key, timer);
512
+ }
513
+ /**
514
+ * Execute the publish
515
+ */
516
+ async doPublish(npub, treeName) {
517
+ const key = this.makeKey(npub, treeName);
518
+ const record = this.records.get(key);
519
+ if (!record || !record.dirty || !this.publishFn) {
520
+ return;
521
+ }
522
+ try {
523
+ const success = await this.publishFn(npub, treeName, record);
524
+ if (success) {
525
+ // Mark as clean (published)
526
+ // Re-check record in case it changed during async publish
527
+ const currentRecord = this.records.get(key);
528
+ if (currentRecord && toHex(currentRecord.hash) === toHex(record.hash)) {
529
+ currentRecord.dirty = false;
530
+ this.persistence.save(key, currentRecord);
531
+ }
532
+ }
533
+ else if (!this.publishTimers.has(key)) {
534
+ this.schedulePublish(npub, treeName, this.retryDelay);
535
+ }
536
+ }
537
+ catch (e) {
538
+ console.error('[TreeRootRegistry] Publish failed:', e);
539
+ if (!this.publishTimers.has(key)) {
540
+ this.schedulePublish(npub, treeName, this.retryDelay);
541
+ }
542
+ }
543
+ }
544
+ /**
545
+ * Force immediate publish of all dirty records
546
+ */
547
+ async flushPendingPublishes() {
548
+ if (!this.publishFn) {
549
+ console.warn('[TreeRootRegistry] flushPendingPublishes: publishFn not set');
550
+ return;
551
+ }
552
+ const promises = [];
553
+ for (const [key, timer] of this.publishTimers) {
554
+ clearTimeout(timer);
555
+ this.publishTimers.delete(key);
556
+ const [npub, ...treeNameParts] = key.split('/');
557
+ const treeName = treeNameParts.join('/');
558
+ if (npub && treeName) {
559
+ promises.push(this.doPublish(npub, treeName));
560
+ }
561
+ }
562
+ await Promise.all(promises);
563
+ }
564
+ /**
565
+ * Cancel pending publish (call before delete to prevent "undelete")
566
+ */
567
+ cancelPendingPublish(npub, treeName) {
568
+ const key = this.makeKey(npub, treeName);
569
+ const timer = this.publishTimers.get(key);
570
+ if (timer) {
571
+ clearTimeout(timer);
572
+ this.publishTimers.delete(key);
573
+ }
574
+ }
575
+ /**
576
+ * Get all records (for debugging/migration)
577
+ */
578
+ getAllRecords() {
579
+ return new Map(this.records);
580
+ }
581
+ /**
582
+ * Check if a record exists
583
+ */
584
+ has(npub, treeName) {
585
+ return this.records.has(this.makeKey(npub, treeName));
586
+ }
587
+ /**
588
+ * Get visibility for a tree
589
+ */
590
+ getVisibility(npub, treeName) {
591
+ return this.records.get(this.makeKey(npub, treeName))?.visibility;
592
+ }
593
+ /**
594
+ * Get labels for a tree
595
+ */
596
+ getLabels(npub, treeName) {
597
+ return this.records.get(this.makeKey(npub, treeName))?.labels;
598
+ }
599
+ }
600
+ function getRegistry() {
601
+ if (typeof window !== 'undefined' && window.__treeRootRegistry) {
602
+ return window.__treeRootRegistry;
603
+ }
604
+ const registry = new TreeRootRegistryImpl();
605
+ if (typeof window !== 'undefined') {
606
+ window.__treeRootRegistry = registry;
607
+ }
608
+ return registry;
609
+ }
610
+ function uniqueLabels(labels) {
611
+ if (!labels?.length)
612
+ return undefined;
613
+ const deduped = [];
614
+ const seen = new Set();
615
+ for (const label of labels) {
616
+ if (!label || seen.has(label))
617
+ continue;
618
+ seen.add(label);
619
+ deduped.push(label);
620
+ }
621
+ return deduped.length > 0 ? deduped : undefined;
622
+ }
623
+ function mergeLabels(primary, fallback) {
624
+ if (!primary?.length)
625
+ return uniqueLabels(fallback);
626
+ if (!fallback?.length)
627
+ return uniqueLabels(primary);
628
+ return uniqueLabels([...primary, ...fallback]);
629
+ }
630
+ // Export singleton instance
631
+ export const treeRootRegistry = getRegistry();
632
+ //# sourceMappingURL=tree-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-root.js","sourceRoot":"","sources":["../src/tree-root.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hashtree/worker",
3
- "version": "0.1.14",
4
- "description": "Modular browser worker for hashtree blob caching and Blossom connectivity",
3
+ "version": "0.1.16",
4
+ "description": "Modular browser worker for hashtree blob caching, tree-root state, and Blossom connectivity",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -33,6 +33,10 @@
33
33
  "./htree-path": {
34
34
  "types": "./dist/htree-path.d.ts",
35
35
  "import": "./dist/htree-path.js"
36
+ },
37
+ "./tree-root": {
38
+ "types": "./dist/tree-root.d.ts",
39
+ "import": "./dist/tree-root.js"
36
40
  }
37
41
  },
38
42
  "files": [
@@ -59,8 +63,8 @@
59
63
  "dexie": "^4.2.1",
60
64
  "nostr-tools": "^2.18.2",
61
65
  "@hashtree/core": "0.1.3",
62
- "@hashtree/nostr": "0.1.3",
63
- "@hashtree/dexie": "0.1.3"
66
+ "@hashtree/dexie": "0.1.3",
67
+ "@hashtree/nostr": "0.1.4"
64
68
  },
65
69
  "peerDependencies": {
66
70
  "ndk": "*",
@@ -81,9 +85,9 @@
81
85
  "devDependencies": {
82
86
  "typescript": "^5.3.0",
83
87
  "vitest": "^2.1.9",
84
- "ndk": "0.1.1",
85
88
  "ndk-cache": "0.1.1",
86
- "nostr-social-graph": "1.0.36"
89
+ "nostr-social-graph": "1.0.36",
90
+ "ndk": "0.1.1"
87
91
  },
88
92
  "scripts": {
89
93
  "build": "tsc",