@nostr-wot/graph 0.2.0 → 0.3.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 +46 -3
- package/dist/index.cjs +283 -124
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -12
- package/dist/index.d.ts +36 -12
- package/dist/index.js +282 -125
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +280 -133
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +6 -2
- package/dist/react/index.d.ts +6 -2
- package/dist/react/index.js +280 -133
- package/dist/react/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -43,7 +43,8 @@ wg.filterByWoT(pubkeys); // trusted subset, sorted by score desc
|
|
|
43
43
|
|---|---|
|
|
44
44
|
| `load()` | Hydrate the cached graph from IndexedDB. |
|
|
45
45
|
| `crawl(root, opts)` | BFS-fetch kind:3 to build/refresh the graph. Concurrent calls share one in-flight promise. |
|
|
46
|
-
| `getDistance(pubkey)` | `{ hops, paths }` from the crawled root, or `null`. |
|
|
46
|
+
| `getDistance(pubkey, maxHops=6)` | `{ hops, paths }` from the crawled root, or `null`. |
|
|
47
|
+
| `getDistances(pubkeys, maxHops=6)` | Batch distances sharing one traversal. |
|
|
47
48
|
| `getScore(pubkey)` | Trust score `0..1` (`calculateScore`). |
|
|
48
49
|
| `isInWoT(pubkey, maxHops=2)` | Within `maxHops` of the root. |
|
|
49
50
|
| `filterByWoT(pubkeys, opts?)` | Trusted subset, sorted by score descending. |
|
|
@@ -58,13 +59,14 @@ wg.filterByWoT(pubkeys); // trusted subset, sorted by score desc
|
|
|
58
59
|
|
|
59
60
|
```ts
|
|
60
61
|
crawl(rootPubkey, {
|
|
61
|
-
maxDepth?: number; // default 2
|
|
62
|
+
maxDepth?: number; // inclusive fetched author depth, default 2
|
|
63
|
+
maxHops?: number; // optional hop boundary; overrides maxDepth
|
|
62
64
|
onProgress?: (p) => void; // { depth, fetched, queued }
|
|
63
65
|
signal?: AbortSignal; // cancel
|
|
64
66
|
}): Promise<CrawlResult>; // { fetched, nodes, edges, depth, durationMs, stoppedEarly }
|
|
65
67
|
```
|
|
66
68
|
|
|
67
|
-
Crawls tolerate
|
|
69
|
+
Crawls tolerate missing relay responses. Zero configured relays throw `CrawlError`; invalid options, transport exceptions and persistence failures propagate. In Node without an IndexedDB polyfill the store runs memory-only (crawl/query work, nothing persists).
|
|
68
70
|
|
|
69
71
|
## React (`/react`)
|
|
70
72
|
|
|
@@ -102,3 +104,44 @@ await wot.getDistance(target);
|
|
|
102
104
|
## License
|
|
103
105
|
|
|
104
106
|
MIT
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
## Graph efficiency and compatibility
|
|
110
|
+
|
|
111
|
+
Crawling batches up to 100 authors per subscription (configurable through
|
|
112
|
+
`GraphCrawler.batchSize`). The filter has no global event limit, so one author's
|
|
113
|
+
history cannot consume another author's slot. The newest kind:3 wins by timestamp,
|
|
114
|
+
then lowest event ID; versions persist with follow rows so stale refreshes cannot
|
|
115
|
+
replace a newer list. A missing response retains cached follows for traversal.
|
|
116
|
+
Unrequested authors, other kinds and timestamps more than 60 seconds in the future
|
|
117
|
+
are ignored. The supplied pool remains responsible for event signature verification.
|
|
118
|
+
|
|
119
|
+
`maxDepth` keeps its existing inclusive author-depth meaning: `maxDepth: 1` fetches
|
|
120
|
+
the root and its direct follows, discovering people two hops away. Use `maxHops: 2`
|
|
121
|
+
to fetch just the lists needed for two-hop reachability; authors at distance two
|
|
122
|
+
are not fetched. `maxHops: 0` sends no requests. Query defaults remain six hops;
|
|
123
|
+
pass an explicit query bound when exploring further.
|
|
124
|
+
|
|
125
|
+
Storage interns keys, deduplicates adjacency and maintains edge counts as rows
|
|
126
|
+
change. IndexedDB schema version 2 writes delta-varint rows; existing version-1
|
|
127
|
+
fixed-width rows load without a full rewrite and migrate when updated. Older SDK
|
|
128
|
+
versions cannot reopen an upgraded namespace (IndexedDB reports `VersionError`),
|
|
129
|
+
so rolling back requires a different namespace or clearing the upgraded database.
|
|
130
|
+
Transactions preserve pending rows on failure, serialize flushes, and atomically
|
|
131
|
+
write each batch of follow rows with its key mappings and event versions. Metadata
|
|
132
|
+
writes use one separate transaction. A crawl is **not** a whole-graph transaction:
|
|
133
|
+
partial results remain queryable, and stopped crawls are marked stale.
|
|
134
|
+
|
|
135
|
+
One numeric BFS serves repeated queries and shallower bounds until edges change
|
|
136
|
+
or a deeper traversal is needed. Duplicate follows do not inflate paths. Distances
|
|
137
|
+
use 32-bit arrays and path counts use 64-bit floats, saturated at
|
|
138
|
+
`Number.MAX_SAFE_INTEGER`; this uses more traversal memory than the former 8-bit
|
|
139
|
+
hops/32-bit paths while avoiding overflow. No TTL-based incremental relay sync,
|
|
140
|
+
root-based pruning or cross-instance live cache synchronization is implemented.
|
|
141
|
+
|
|
142
|
+
Run `npm run benchmark -w @nostr-wot/graph` from the repository root for reproducible
|
|
143
|
+
synthetic construction, cold traversal and warm retrieval timings. Regression
|
|
144
|
+
fixtures verify 251 authors use 4 requests instead of 251 (98.4% fewer), 1,000 dense
|
|
145
|
+
follow IDs use 1,000 encoded bytes instead of 4,000 (75% smaller payload), and 1,000
|
|
146
|
+
unchanged queries traverse a three-node graph only once. These figures describe
|
|
147
|
+
fixtures; relay latency and IndexedDB record overhead are not included.
|