OverviewFilesCommitsIssuesDocsReleasesPeers

atproto-base commits / 949ce11

atproto-base: deterministic-projection design + 7-test offline proof harness
A co-owned atproto DID as a PURE DETERMINISTIC PROJECTION of one autobase's indexed view, signed with RFC6979-deterministic signatures — so signing is indexer-agnostic. This reconciles atproto's single-DID / single-key / append-only signed log with multi-writer autobase whose indexer set CHANGES: every co-owner independently computes the byte-identical signed chain, so there is no signer election and no possibility of a fork. Proven offline (7/7 tests, 36/36 asserts): 1 determinism two co-owners -> byte-identical signed commit (CID + sig) 2 indexer-change changing the indexer set never alters the projected chain 3 reorg-safety optimistic-tip reorg never rewrites finalized records 4 rev-determinism rev is log-derived, monotonic, restart-stable (not wall-clock) 5 N=2 stalls-not-fork losing one of two indexers freezes finalization, no fork 6 relay-acceptance chain passes verifyRepo + verifyCommit + forward-only rev 7 labeler group labeler = atproto-base projecting deterministic labels lib/project.js (commit projection, prev-chaining, reuses atproto-repo byte-exact primitives), lib/rev.js (deterministic TID), lib/sign.js + lib/label.js (label projection). DESIGN.md carries the full rationale + the autobee "no" decision. Extraction of atproto-room/StateBaseV3 begins from here (lib/base.js next). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
949ce118cdf5a48cc25da9ef462c73d27ab956bd
by plankatron <fleeky@gmail.com> · 2026-07-23T16:32:18.000Z

Changed files (13) +2199 -0

.gitignore +3 -0
……@@ -0,0 +1,3 @@
1node_modules/
2*.log
3.DS_Store
DESIGN.md +101 -0
……@@ -0,0 +1,101 @@
1# atproto-base — a co-owned atproto DID as a deterministic projection of one autobase
2
3> Extraction + redesign of `atproto-room/lib/state-base.js` (StateBaseV3). The class name
4> "StateBaseV3" is a legacy from a hyper-tps *gamestate* sync class; this is the clean,
5> atproto-native library it should have been. Grounded in autobase 7.28.1 (latest), the
6> atproto-repo/atproto-crypto signing contract, and the keet shared-view + ozone moderation models.
7
8## The problem we kept thrashing on
9
10Marrying **multi-writer autobase** to atproto's **single-DID, single-signing-key, append-only
11signed log**. Every prior attempt (lease election, presence election, "signer ≡ indexer") tried
12to pick a **stable single signer** — but **a P2P multi-writer system has no stable authority: the
13autobase indexer set changes** (add/remove/move/promote → `indexerUpdate=true` → migration/reboot;
14`system.js:431`). Tie signing to the indexer identity and any transition gives 0 signers (stall/gap)
15or 2 signers (fork = wj62).
16
17## The core principle (the reconciliation)
18
19**Stop electing a signer. Make the atproto log a PURE DETERMINISTIC PROJECTION of the autobase
20INDEXED view, signed with RFC6979-deterministic signatures — so *who* signs is irrelevant.**
21
22- The indexed prefix `[0, indexedLength)` is **immutable and monotonic even across indexer changes**
23 (truncation floors at `indexedLength`, `apply-state.js:781`; migration checks out at `indexedLength`,
24 `:806-808`; `indexedLength` only advances, `:1027`). An indexer change alters *future* finalization,
25 never *past* indexed history.
26- The atproto commit at `indexedLength L` = a **deterministic** `unsignedCommit{ did, version:3,
27 data: MST(indexed records at L), rev: deterministic(from the log), prev: CID(commit at prior L) }`.
28- atproto signing is **ECDSA-secp256k1 low-S RFC6979 (no extra entropy)** → **deterministic**. The
29 shared `#atproto` key signs the same unsignedCommit → **byte-identical sig + CID on every co-owner.**
30- Therefore **every co-owner independently computes the identical signed chain.** Two co-owners
31 "both signing" = identical bytes = ONE chain (idempotent), never a fork. The indexer changing never
32 touches the chain — the chain is a function of the *indexed view*, not the indexer identity.
33
34Liveness = "keep `indexedLength` advancing" (autobase's quorum job) → **N=1 sole indexer, or N≥3,
35NEVER rest at N=2**. Emission is many-to-one; the bridge/relay dedups by CID + forward-only `rev`.
36
37## Hard determinism requirements (where it lives or dies)
38
391. **`rev` MUST be deterministic** — a strictly-monotonic TID derived from the log
40 (`TID(max(prevRev+1, maxIndexedRecordTid))`), NEVER `Date.now()`. (StateBaseV3 stamps
41 `ts:Date.now()` — that would fork this; the record `ts` may stay for LWW but the COMMIT `rev`
42 must be log-derived.)
432. **Project the INDEXED set only** — never the optimistic tip.
443. **The projection is a pure function** — no wall-clock/random in the SIGNED payload. (The `#commit`
45 firehose frame's `time` field is NOT in the signed commit `{did,version,data,rev,prev}` — cosmetic,
46 safe. Verify nothing else leaks.)
474. **RFC6979 low-S byte-identical across co-owners** — same `@noble/curves`. Prove it (test 1).
48
49## Labeler = atproto-base projecting LABELS (not a special case)
50
51A group/team labeler is the SAME primitive projecting `com.atproto.label` instead of repo commits.
52atproto/ozone solves team moderation **centrally** (one DID + one `OZONE_SIGNING_KEY_HEX`, N moderator
53accounts with `tools.ozone.team` roles proxied in, Postgres event-log, state = fold of events). Ours is
54the **P2P analog with no key custodian**: a co-owned DID whose autobase view is the moderation state
55(subject → state, deterministic fold of mod-event ops by `__members__`-role members), projecting
56**deterministic** signed labels onto `subscribeLabels`. Labels are EASIER than repo commits — standalone
57DAG-CBOR-signed `{src,uri,val,neg,cts,sig}`, **no `prev`-chain, no MST**, just a `seq` stream; only `cts`
58needs the same determinism discipline as `rev`. The relay sees one DID/key/sig — protocol-compatible.
59
60## Clean shape (vs StateBaseV3's debt)
61
62- **Typed ops** (keet contract-router style: `admit` / `start-indexing` / `move-indexer` / `ban` /
63 `set-epoch` / `set-record` / `del-record`) — NOT `set-entry` overloaded 6 ways by magic keys.
64- **Separate the concerns** currently fused in the 1174-line god-class: (a) the autobase **view**
65 (records/state), (b) **governance** (admission/membership/indexer topology/revocation), (c) the
66 **atproto projection** (deterministic commit/label chain + signing) — projection is a READER of the
67 view, not tangled into it. **No signer election anywhere.**
68- Keep what's already correct: block-until-admitted doorbell (golden rule), multi-DID injected
69 store/wakeup, deterministic base key from members-only `roomSeed`, encrypted base.
70
71## Why NOT autobee
72
73autobee (beta, breaking, no GC, `addWriter` defaults `isIndexer:true`) sold "dissolve the N=2 trap."
74Deterministic projection makes the signed chain indexer-agnostic → the trap no longer threatens
75correctness, only liveness (handled by N=1/N≥3 on mature autobase 7.28.1). Not worth a beta substrate.
76autobee stays a future spike.
77
78## Offline test plan (prove BEFORE prod e2e)
79
801. **Determinism (killer proof):** two independent co-owners, same op set → **byte-identical** signed
81 commit chain (same CIDs AND same sigs). If this passes, the design is proven.
822. **Indexer-change invariance:** grow/shrink/`move-indexer` mid-stream → emitted chain unchanged (no
83 fork, no gap, same continuation).
843. **Reorg-safety:** force an optimistic-tip reorg → every signed `commit_N.data` == finalized MST at
85 `indexedLength_N` forever.
864. **rev-determinism across restart:** restart → `rev` never regresses, chain continues identically.
875. **N=2 negative:** freeze `indexedLength` → chain STALLS, does NOT fork.
886. **Relay-acceptance oracle:** chain passes `verifyCommit`(DID key) + `verifyRepo` byte-exactness +
89 forward-only `rev`.
907. **Labeler determinism:** two co-owner mods, same mod-event ops → **byte-identical** signed label
91 stream (same `sig`, `neg` retraction consistent).
92
93## Build order (offline-test-first)
94
951. `lib/project.js` — the pure deterministic projection: `(indexedRecords, prevCommit) -> unsignedCommit`
96 + deterministic `rev`. **+ test 1 (determinism) FIRST** — this de-risks everything.
972. `lib/sign.js` — RFC6979 deterministic signing wrapper (reuse atproto-repo `signCommit`) + verify.
983. `lib/base.js` — the autobase engine (typed ops, governance, admission — ported clean from
99 StateBaseV3) exposing an **indexed-view snapshot** to the projector.
1004. `lib/label.js` — the label projection (same shape, no prev/MST).
1015. Wire the remaining tests (2–7). Then extract hpp/atproto-room consumers onto it.
lib/label.js +21 -0
……@@ -0,0 +1,21 @@
1// The LABEL projection — a group/team labeler is just atproto-base projecting com.atproto.label
2// instead of repo commits (see DESIGN.md §labeler). A label is a standalone DAG-CBOR-signed object
3// (no prev-chain, no MST — easier than commits); the only determinism risk is `cts`, which MUST be
4// deterministic (log-derived, like `rev`) so co-owner mods produce byte-identical labels. Retraction
5// is a `neg:true` label, never a delete (ozone model).
6
7import { signObject, verifyObject } from './sign.js'
8
9// Project + sign one label deterministically from a moderation decision in the shared view.
10// `cts` is a deterministic ISO datetime derived from the mod-event's log position (NOT wall-clock).
11export async function projectLabel ({ src, uri, val, cts, neg = false, cid = null, ver = 1, privateKey }) {
12 const unsigned = { ver, src, uri, val, cts }
13 if (cid) unsigned.cid = cid
14 if (neg) unsigned.neg = true
15 return { ...unsigned, sig: await signObject(unsigned, privateKey) }
16}
17
18export async function verifyLabel (label, publicKey) {
19 const { sig, ...unsigned } = label
20 return verifyObject(unsigned, sig, publicKey)
21}
lib/project.js +45 -0
……@@ -0,0 +1,45 @@
1// The deterministic PROJECTION — the heart of atproto-base.
2//
3// An atproto commit is a PURE function of (record set, did, rev, prev). Signing is RFC6979-
4// deterministic (ECDSA secp256k1 low-S), so signing the same unsignedCommit with the shared
5// #atproto key yields byte-identical sig + CID on EVERY co-owner. Therefore the atproto chain is a
6// deterministic projection of the autobase INDEXED view, and WHO signs is irrelevant — no signer
7// election, no fork, indexer-change-agnostic. See DESIGN.md.
8//
9// `records` take atproto-repo's shape: { key, value } or { collection, rkey, record }. The MST build
10// is order-independent (proven in atproto-repo), so a shuffled record set yields the identical root.
11// We reuse atproto-repo's byte-exact primitives (verified against real relay-accepted repos) so our
12// commits stay wire-identical to what a real relay validates.
13
14import { cidForValue } from 'atproto-repo/lib/cid.js'
15import { buildMst, reachableBlocks } from 'atproto-repo/lib/mst.js'
16import { unsignedCommit, signCommit, commitCid } from 'atproto-repo/lib/commit.js'
17import { writeCar } from 'atproto-repo/lib/car.js'
18import { nextRev } from './rev.js'
19
20export { nextRev }
21
22// Project + sign one atproto commit deterministically. `prev` = CID of the previous commit (null for
23// genesis). Returns { carBytes, commitCid, dataCid, signedCommit } — byte-identical across co-owners
24// for identical inputs. Mirrors atproto-repo's createRepo assembly but adds prev-chaining, so a whole
25// append-only chain is a deterministic projection.
26export async function projectCommit ({ records, did, rev, prev = null, privateKey }) {
27 const recordBlocks = new Map()
28 const mstRecords = []
29 for (const r of records) {
30 const key = r.key !== undefined ? r.key : `${r.collection}/${r.rkey}`
31 const value = r.record !== undefined ? r.record : r.value
32 const { bytes, cid } = await cidForValue(value)
33 recordBlocks.set(cid.toString(), { cid, bytes })
34 mstRecords.push({ key, value: cid })
35 }
36 const { root: dataCid, ns } = buildMst(mstRecords)
37 const mstBlocks = reachableBlocks(ns, dataCid)
38
39 const signed = signCommit(unsignedCommit({ did, rev, data: dataCid, prev }), privateKey)
40 const { bytes: commitBytes, cid: cCid } = await cidForValue(signed)
41
42 const blocks = [{ cid: cCid, bytes: commitBytes }, ...mstBlocks.values(), ...recordBlocks.values()]
43 const carBytes = await writeCar(cCid, blocks)
44 return { carBytes, commitCid: commitCid(signed), dataCid, signedCommit: signed }
45}
lib/rev.js +27 -0
……@@ -0,0 +1,27 @@
1// Deterministic atproto `rev` (TID). The marriage REQUIRES rev to be a pure function of the log —
2// NEVER Date.now() — so every co-owner computes the identical commit chain (see DESIGN.md §hard
3// requirements). A TID is a 13-char base32-sortable encoding of (unixMicros<<10 | clockId). We use
4// clockId=0 and drive `micros` from a deterministic per-commit counter, so `rev` is monotonic AND
5// identical across co-owners given the same prev.
6
7const S32 = '234567abcdefghijklmnopqrstuvwxyz' // atproto base32-sortable alphabet
8
9export function encodeTid (micros, clock = 0) {
10 let n = (BigInt(micros) << 10n) | BigInt(clock & 0x3ff)
11 let s = ''
12 for (let i = 0; i < 13; i++) { s = S32[Number(n & 31n)] + s; n >>= 5n }
13 return s
14}
15
16export function decodeTidMicros (tid) {
17 let n = 0n
18 for (const ch of tid) n = (n << 5n) | BigInt(S32.indexOf(ch))
19 return Number(n >> 10n)
20}
21
22// The next rev after `prevRev` — deterministic monotonic increment. Genesis (prevRev null) → rev 0's
23// TID from a fixed epoch. Because prevRev is itself deterministic, the whole chain is deterministic.
24export function nextRev (prevRev, baseMicros = 0) {
25 const micros = prevRev ? decodeTidMicros(prevRev) : baseMicros
26 return encodeTid(prevRev ? micros + 1 : micros)
27}
lib/sign.js +19 -0
……@@ -0,0 +1,19 @@
1// Generic deterministic DAG-CBOR signer/verifier — used by the LABEL projection (the commit path
2// reuses atproto-repo's byte-exact signCommit). ECDSA secp256k1 low-S over sha256(DAG-CBOR(obj)),
3// RFC6979-deterministic, raw 64-byte compact sig — the same primitive shape as commit/label sigs.
4// DAG-CBOR canonicalises map keys, so object field order never affects the bytes → deterministic.
5
6import { secp256k1 } from '@noble/curves/secp256k1'
7import { sha256 } from '@noble/hashes/sha2'
8import { cidForValue } from 'atproto-repo/lib/cid.js' // reuse the exact DAG-CBOR encoder (proven)
9
10async function dagCborBytes (obj) { return (await cidForValue(obj)).bytes }
11
12export async function signObject (obj, privateKey) {
13 const sig = secp256k1.sign(sha256(await dagCborBytes(obj)), privateKey, { lowS: true })
14 return sig.toCompactRawBytes() // 64-byte raw, like atproto commit/label sigs
15}
16
17export async function verifyObject (obj, sig, publicKey) {
18 return secp256k1.verify(sig, sha256(await dagCborBytes(obj)), publicKey, { lowS: true })
19}
package-lock.json +1682 -0
……@@ -0,0 +1,1682 @@
1{
2 "name": "atproto-base",
3 "version": "0.0.1",
4 "lockfileVersion": 3,
5 "requires": true,
6 "packages": {
7 "": {
8 "name": "atproto-base",
9 "version": "0.0.1",
10 "dependencies": {
11 "@noble/curves": "1.9.7",
12 "@noble/hashes": "1.8.0",
13 "atproto-identity": "file:../atproto-identity",
14 "atproto-repo": "file:../atproto-repo"
15 },
16 "devDependencies": {
17 "autobase": "7.28.1",
18 "b4a": "1.8.1",
19 "brittle": "^3.0.0",
20 "corestore": "7.11.0",
21 "hyperbee": "2.27.3"
22 }
23 },
24 "../atproto-identity": {
25 "version": "0.0.2",
26 "hasInstallScript": true,
27 "dependencies": {
28 "@ipld/dag-cbor": "^9.2.1",
29 "@noble/curves": "^1.6.0",
30 "@noble/hashes": "^1.5.0",
31 "@scure/bip32": "^1.5.0",
32 "@scure/bip39": "^1.4.0",
33 "hypercore-crypto": "^3.0.0",
34 "keet-identity-key": "^3.2.0",
35 "multiformats": "^13.3.0"
36 },
37 "devDependencies": {
38 "brittle": "^4.0.2"
39 }
40 },
41 "../atproto-repo": {
42 "version": "0.0.1",
43 "hasInstallScript": true,
44 "dependencies": {
45 "@ipld/car": "^5.4.0",
46 "@ipld/dag-cbor": "^9.2.1",
47 "@noble/curves": "^1.9.7",
48 "@noble/hashes": "^1.5.0",
49 "multiformats": "^13.3.0"
50 },
51 "devDependencies": {
52 "atproto-identity": "file:../atproto-identity",
53 "brittle": "^4.0.2"
54 }
55 },
56 "node_modules/@hyperswarm/secret-stream": {
57 "version": "6.9.1",
58 "resolved": "https://registry.npmjs.org/@hyperswarm/secret-stream/-/secret-stream-6.9.1.tgz",
59 "integrity": "sha512-xb0S5y3YJwBakD77JOGBHlBxdp63mHClZoXBYoLv+9wH8e054ESKlmQptWqjJK5dv5VMUIVYOJB4MaOpB0JdGw==",
60 "dev": true,
61 "license": "Apache-2.0",
62 "dependencies": {
63 "b4a": "^1.1.0",
64 "hypercore-crypto": "^3.3.1",
65 "noise-curve-ed": "^2.0.1",
66 "noise-handshake": "^4.0.0",
67 "sodium-secretstream": "^1.1.0",
68 "sodium-universal": "^5.0.0",
69 "streamx": "^2.14.0",
70 "timeout-refresh": "^2.0.0",
71 "unslab": "^1.3.0"
72 }
73 },
74 "node_modules/@jridgewell/resolve-uri": {
75 "version": "3.1.2",
76 "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
77 "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
78 "dev": true,
79 "license": "MIT",
80 "engines": {
81 "node": ">=6.0.0"
82 }
83 },
84 "node_modules/@jridgewell/sourcemap-codec": {
85 "version": "1.5.5",
86 "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
87 "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
88 "dev": true,
89 "license": "MIT"
90 },
91 "node_modules/@jridgewell/trace-mapping": {
92 "version": "0.3.31",
93 "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
94 "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
95 "dev": true,
96 "license": "MIT",
97 "dependencies": {
98 "@jridgewell/resolve-uri": "^3.1.0",
99 "@jridgewell/sourcemap-codec": "^1.4.14"
100 }
101 },
102 "node_modules/@noble/curves": {
103 "version": "1.9.7",
104 "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz",
105 "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==",
106 "license": "MIT",
107 "dependencies": {
108 "@noble/hashes": "1.8.0"
109 },
110 "engines": {
111 "node": "^14.21.3 || >=16"
112 },
113 "funding": {
114 "url": "https://paulmillr.com/funding/"
115 }
116 },
117 "node_modules/@noble/hashes": {
118 "version": "1.8.0",
119 "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
120 "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
121 "license": "MIT",
122 "engines": {
123 "node": "^14.21.3 || >=16"
124 },
125 "funding": {
126 "url": "https://paulmillr.com/funding/"
127 }
128 },
129 "node_modules/@types/istanbul-lib-coverage": {
130 "version": "2.0.6",
131 "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
132 "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
133 "dev": true,
134 "license": "MIT"
135 },
136 "node_modules/atproto-identity": {
137 "resolved": "../atproto-identity",
138 "link": true
139 },
140 "node_modules/atproto-repo": {
141 "resolved": "../atproto-repo",
142 "link": true
143 },
144 "node_modules/autobase": {
145 "version": "7.28.1",
146 "resolved": "https://registry.npmjs.org/autobase/-/autobase-7.28.1.tgz",
147 "integrity": "sha512-I8SHcJE/ru5Nun6NpqwRjenB8aK01b9z1qNeyx4XuG+BxeFUpXk0ZT2u3/nG+GZnObUTFMCKOo2fbAv7ipcaLw==",
148 "dev": true,
149 "license": "Apache-2.0",
150 "dependencies": {
151 "b4a": "^1.6.1",
152 "bare-events": "^2.2.0",
153 "compact-encoding": "^3.0.0",
154 "core-coupler": "^2.0.0",
155 "debounceify": "^1.0.0",
156 "encryption-encoding": "^1.0.3",
157 "hyperbee": "^2.22.0",
158 "hypercore": "^11.27.12",
159 "hypercore-crypto": "^3.4.0",
160 "hypercore-id-encoding": "^1.2.0",
161 "hyperschema": "^1.12.1",
162 "index-encoder": "^3.3.2",
163 "nanoassert": "^2.0.0",
164 "protomux-wakeup": "^2.0.0",
165 "ready-resource": "^1.0.0",
166 "resolve-reject-promise": "^1.1.0",
167 "safety-catch": "^1.0.2",
168 "scope-lock": "^1.2.4",
169 "signal-promise": "^1.0.3",
170 "sodium-universal": "^5.0.1",
171 "sub-encoder": "^2.1.1",
172 "tiny-buffer-map": "^1.1.1"
173 }
174 },
175 "node_modules/b4a": {
176 "version": "1.8.1",
177 "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.1.tgz",
178 "integrity": "sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==",
179 "dev": true,
180 "license": "Apache-2.0",
181 "peerDependencies": {
182 "react-native-b4a": "*"
183 },
184 "peerDependenciesMeta": {
185 "react-native-b4a": {
186 "optional": true
187 }
188 }
189 },
190 "node_modules/bare-abort": {
191 "version": "2.0.13",
192 "resolved": "https://registry.npmjs.org/bare-abort/-/bare-abort-2.0.13.tgz",
193 "integrity": "sha512-zdc8l88eB11Jsz5rDd6sCAgv2kUFXgdrZWoMlgU6JMkfAi1/uuGFC3IEHswKbIRQTk5H3T5CMuechsXYxiaHlQ==",
194 "dev": true,
195 "license": "Apache-2.0"
196 },
197 "node_modules/bare-addon-resolve": {
198 "version": "1.10.1",
199 "resolved": "https://registry.npmjs.org/bare-addon-resolve/-/bare-addon-resolve-1.10.1.tgz",
200 "integrity": "sha512-F/SD2du8keuYSb4xipnGz5j2E6yhNdHA8ZVxtHae6h2uOrpBIjjbhXvjzKZbr5XUOzqBzh/i8GVFycj2DlFQIA==",
201 "dev": true,
202 "license": "Apache-2.0",
203 "dependencies": {
204 "bare-module-resolve": "^1.10.0",
205 "bare-semver": "^1.0.0"
206 },
207 "peerDependencies": {
208 "bare-url": "*"
209 },
210 "peerDependenciesMeta": {
211 "bare-url": {
212 "optional": true
213 }
214 }
215 },
216 "node_modules/bare-ansi-escapes": {
217 "version": "2.2.3",
218 "resolved": "https://registry.npmjs.org/bare-ansi-escapes/-/bare-ansi-escapes-2.2.3.tgz",
219 "integrity": "sha512-02ES4/E2RbrtZSnHJ9LntBhYkLA6lPpSEeP8iqS3MccBIVhVBlEmruF1I7HZqx5Q8aiTeYfQVeqmrU9YO2yYoQ==",
220 "dev": true,
221 "license": "Apache-2.0",
222 "dependencies": {
223 "bare-stream": "^2.6.5"
224 },
225 "peerDependencies": {
226 "bare-buffer": "*"
227 },
228 "peerDependenciesMeta": {
229 "bare-buffer": {
230 "optional": true
231 }
232 }
233 },
234 "node_modules/bare-assert": {
235 "version": "1.2.0",
236 "resolved": "https://registry.npmjs.org/bare-assert/-/bare-assert-1.2.0.tgz",
237 "integrity": "sha512-c6uvgvTJBspTDxtVnPgrBKmLgcpW3Fp72NVKDLg6oT4QjQbhGtvrkHMhGYMK1sh4vjBHOBmuUalyt9hSzV37fQ==",
238 "dev": true,
239 "license": "Apache-2.0",
240 "dependencies": {
241 "bare-inspect": "^3.1.2"
242 }
243 },
244 "node_modules/bare-bundle": {
245 "version": "1.10.0",
246 "resolved": "https://registry.npmjs.org/bare-bundle/-/bare-bundle-1.10.0.tgz",
247 "integrity": "sha512-4LVlnJAHr00Hh6Vu6ZUJS38rcEtJT3b3vChXSsBsJ2mk1TN0lQ+gzd+Dw5L0aV7uqDZv84smuwW+O02X7PfDlw==",
248 "dev": true,
249 "license": "Apache-2.0",
250 "peerDependencies": {
251 "bare-buffer": "*",
252 "bare-url": "*"
253 },
254 "peerDependenciesMeta": {
255 "bare-buffer": {
256 "optional": true
257 },
258 "bare-url": {
259 "optional": true
260 }
261 }
262 },
263 "node_modules/bare-cov": {
264 "version": "1.2.2",
265 "resolved": "https://registry.npmjs.org/bare-cov/-/bare-cov-1.2.2.tgz",
266 "integrity": "sha512-d/b4HdL5ohZDwBvDegJeSkmo1X2MGlm22jXzuY2D7wl2W1+7nk/b7+HMogwgUa+zi8rVVRJQKHCHPHYBJpvlvw==",
267 "dev": true,
268 "license": "Apache-2.0",
269 "dependencies": {
270 "bare-fs": "^4.1.2",
271 "bare-inspector": "^6.0.1",
272 "bare-path": "^3.0.0",
273 "bare-process": "^4.2.1",
274 "bare-url": "^2.1.5",
275 "bare-v8-to-istanbul": "^1.0.2",
276 "picomatch": "^4.0.2",
277 "which-runtime": "^1.2.1"
278 }
279 },
280 "node_modules/bare-crypto": {
281 "version": "1.15.3",
282 "resolved": "https://registry.npmjs.org/bare-crypto/-/bare-crypto-1.15.3.tgz",
283 "integrity": "sha512-macV9lbyJTsLPRXJkBtz8ivTGEo3LCyJInLT9IB/PWJ7pRXwvHs/FP4bx/fWw+HZkiepIYCAV2cuU5CR92XWCw==",
284 "dev": true,
285 "license": "Apache-2.0",
286 "dependencies": {
287 "bare-assert": "^1.2.0",
288 "bare-stream": "^2.6.3"
289 },
290 "peerDependencies": {
291 "bare-buffer": "*"
292 },
293 "peerDependenciesMeta": {
294 "bare-buffer": {
295 "optional": true
296 }
297 }
298 },
299 "node_modules/bare-debug-log": {
300 "version": "2.0.0",
301 "resolved": "https://registry.npmjs.org/bare-debug-log/-/bare-debug-log-2.0.0.tgz",
302 "integrity": "sha512-Vi42PkMQsNV9PUpx2Gl1hikshx5O9FzMJ6o9Nnopseg7qLBBK7Nl31d0RHcfwLEAfmcPApytpc0ZFfq68u22FQ==",
303 "dev": true,
304 "license": "Apache-2.0",
305 "dependencies": {
306 "bare-os": "^3.0.1"
307 }
308 },
309 "node_modules/bare-dns": {
310 "version": "2.1.4",
311 "resolved": "https://registry.npmjs.org/bare-dns/-/bare-dns-2.1.4.tgz",
312 "integrity": "sha512-abwjHmpWqSRNB7V5615QxPH92L71AVzFm/kKTs8VYiNTAi2xVdonpv0BjJ0hwXLwomoW+xsSOPjW6PZPO14asg==",
313 "dev": true,
314 "license": "Apache-2.0",
315 "engines": {
316 "bare": ">=1.7.0"
317 }
318 },
319 "node_modules/bare-encoding": {
320 "version": "1.0.3",
321 "resolved": "https://registry.npmjs.org/bare-encoding/-/bare-encoding-1.0.3.tgz",
322 "integrity": "sha512-Kqf+t/azs13lUeyK4Tb7ha4wdLRXKWCXQ8w1rVmt7KtoPCPdHD/Xwt7LBIsCSwwGglrcmblo5VOLa5avkJqULA==",
323 "dev": true,
324 "license": "Apache-2.0",
325 "peerDependencies": {
326 "bare-buffer": "*"
327 },
328 "peerDependenciesMeta": {
329 "bare-buffer": {
330 "optional": true
331 }
332 }
333 },
334 "node_modules/bare-env": {
335 "version": "3.0.1",
336 "resolved": "https://registry.npmjs.org/bare-env/-/bare-env-3.0.1.tgz",
337 "integrity": "sha512-BdoLvnzaWR0YyyJreEx4zG2Od0AC/s9JSZ+EXyMZKunpn8zEgR/dGv37hdFUaY1bjDkcRKvcKkFyJIwlJ0CaYA==",
338 "dev": true,
339 "license": "Apache-2.0",
340 "dependencies": {
341 "bare-os": "^3.0.1"
342 }
343 },
344 "node_modules/bare-events": {
345 "version": "2.9.1",
346 "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.9.1.tgz",
347 "integrity": "sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==",
348 "dev": true,
349 "license": "Apache-2.0",
350 "peerDependencies": {
351 "bare-abort-controller": "*"
352 },
353 "peerDependenciesMeta": {
354 "bare-abort-controller": {
355 "optional": true
356 }
357 }
358 },
359 "node_modules/bare-format": {
360 "version": "1.0.2",
361 "resolved": "https://registry.npmjs.org/bare-format/-/bare-format-1.0.2.tgz",
362 "integrity": "sha512-GswdhnOnP9QtwRbrf4wLApw5widkaLMsLe2XOs35fQD2YfEN1ApoGka+cZ7PfvzxMgfYXmMhj/2OGlVn5/Dxgw==",
363 "dev": true,
364 "license": "Apache-2.0",
365 "dependencies": {
366 "bare-inspect": "^3.0.0"
367 }
368 },
369 "node_modules/bare-fs": {
370 "version": "4.7.4",
371 "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.4.tgz",
372 "integrity": "sha512-y1kC+ffIx/tPLdTE693uNjHfzTfr+ravR5tvWlMXe25nELbkqV400S71qHDwbkAQ1FVEZobB1NFRzFbCCcyBCQ==",
373 "dev": true,
374 "license": "Apache-2.0",
375 "dependencies": {
376 "bare-events": "^2.5.4",
377 "bare-path": "^3.0.0",
378 "bare-stream": "^2.6.4",
379 "bare-url": "^2.2.2",
380 "fast-fifo": "^1.3.2"
381 },
382 "engines": {
383 "bare": ">=1.16.0"
384 },
385 "peerDependencies": {
386 "bare-buffer": "*"
387 },
388 "peerDependenciesMeta": {
389 "bare-buffer": {
390 "optional": true
391 }
392 }
393 },
394 "node_modules/bare-hrtime": {
395 "version": "2.1.1",
396 "resolved": "https://registry.npmjs.org/bare-hrtime/-/bare-hrtime-2.1.1.tgz",
397 "integrity": "sha512-VMb3tHo05gsnbu3OXTmkDiwTjMlOsbQmKoysKqKEyR09m77TuDrYFbj3Q5GGk10dAKsUHrnXmwCaeJqzVpB5ZA==",
398 "dev": true,
399 "license": "Apache-2.0"
400 },
401 "node_modules/bare-http-parser": {
402 "version": "1.1.5",
403 "resolved": "https://registry.npmjs.org/bare-http-parser/-/bare-http-parser-1.1.5.tgz",
404 "integrity": "sha512-sPaDetLbWRmth04JmuTCvw/hoNdWJvYUJN8n1tYdGW3HM0mMnCvK2f0oIxE6HK7iOq+WlsRzEMg1LT/b0wGbLQ==",
405 "dev": true,
406 "license": "Apache-2.0"
407 },
408 "node_modules/bare-http1": {
409 "version": "4.5.7",
410 "resolved": "https://registry.npmjs.org/bare-http1/-/bare-http1-4.5.7.tgz",
411 "integrity": "sha512-PRuzs9ywt4vUvrC3mnHhQyaQfLYzdFy8XKOH0oKeKmYfyYYUqXBkdbJE2csESLBxJEbKDBjxPGLU+Qa0l1ds4A==",
412 "dev": true,
413 "license": "Apache-2.0",
414 "dependencies": {
415 "bare-events": "^2.6.0",
416 "bare-http-parser": "^1.1.1",
417 "bare-stream": "^2.10.0",
418 "bare-tcp": "^2.2.0"
419 },
420 "peerDependencies": {
421 "bare-buffer": "*",
422 "bare-url": "*"
423 },
424 "peerDependenciesMeta": {
425 "bare-buffer": {
426 "optional": true
427 },
428 "bare-url": {
429 "optional": true
430 }
431 }
432 },
433 "node_modules/bare-https": {
434 "version": "3.0.0",
435 "resolved": "https://registry.npmjs.org/bare-https/-/bare-https-3.0.0.tgz",
436 "integrity": "sha512-W1GRSCzn+xXKf5bMcPs/hg6Ga1bxPqb7owGfS+tvlBQfPe5Q2STcanRuKZrgU60v5uKrhXH5cgWwM+DLqvXZgQ==",
437 "dev": true,
438 "license": "Apache-2.0",
439 "dependencies": {
440 "bare-http1": "^4.4.0",
441 "bare-tcp": "^2.2.0",
442 "bare-tls": "^3.0.0"
443 }
444 },
445 "node_modules/bare-inspect": {
446 "version": "3.1.4",
447 "resolved": "https://registry.npmjs.org/bare-inspect/-/bare-inspect-3.1.4.tgz",
448 "integrity": "sha512-jfW5KRA84o3REpI6Vr4nbvMn+hqVAw8GU1mMdRwUsY5yJovQamxYeKGVKGqdzs+8ZbG4jRzGUXP/3Ji/DnqfPg==",
449 "dev": true,
450 "license": "Apache-2.0",
451 "dependencies": {
452 "bare-ansi-escapes": "^2.1.0",
453 "bare-type": "^1.0.0"
454 },
455 "engines": {
456 "bare": ">=1.18.0"
457 }
458 },
459 "node_modules/bare-inspector": {
460 "version": "6.1.0",
461 "resolved": "https://registry.npmjs.org/bare-inspector/-/bare-inspector-6.1.0.tgz",
462 "integrity": "sha512-PRxmZ4gF+K3TLzGubgRFvzdECybTCSKackgNsAdd4e7SdvICxMkGj+p5iX7bSKYSmgDnxgCR+2Z6UXmWykKhvw==",
463 "dev": true,
464 "license": "Apache-2.0",
465 "dependencies": {
466 "bare-events": "^2.1.0",
467 "bare-http1": "^4.0.0",
468 "bare-stream": "^2.0.0",
469 "bare-url": "^2.0.0",
470 "bare-ws": "^3.0.0"
471 },
472 "engines": {
473 "bare": ">=1.29.0"
474 },
475 "peerDependencies": {
476 "bare-tcp": "*"
477 },
478 "peerDependenciesMeta": {
479 "bare-tcp": {
480 "optional": true
481 }
482 }
483 },
484 "node_modules/bare-module": {
485 "version": "6.4.0",
486 "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-6.4.0.tgz",
487 "integrity": "sha512-Yn4V5g5EqGQL4LYUOmt7fjKzj2JPWyJOqE3lPoeZwfUH5rk4CKUfZj6JhDwbzhBYCqqmUgjgQ5aY8cihAPILLA==",
488 "dev": true,
489 "license": "Apache-2.0",
490 "dependencies": {
491 "bare-bundle": "^1.3.0",
492 "bare-module-lexer": "^1.0.0",
493 "bare-module-resolve": "^1.8.0",
494 "bare-path": "^3.0.0",
495 "bare-type-stripper": "^0.1.2",
496 "bare-url": "^2.0.1"
497 },
498 "engines": {
499 "bare": ">=1.29.4"
500 },
501 "peerDependencies": {
502 "bare-buffer": "*"
503 },
504 "peerDependenciesMeta": {
505 "bare-buffer": {
506 "optional": true
507 }
508 }
509 },
510 "node_modules/bare-module-lexer": {
511 "version": "1.6.3",
512 "resolved": "https://registry.npmjs.org/bare-module-lexer/-/bare-module-lexer-1.6.3.tgz",
513 "integrity": "sha512-NQY7cnPV3GZlHJphX4nXmPdNPER/Tp17pVi9/he2ODw/GNZ7FXzrZlrS7WMF8zbtWigqW/NMc9aQc2BH8UJXqA==",
514 "dev": true,
515 "license": "Apache-2.0",
516 "dependencies": {
517 "require-addon": "^1.0.2"
518 },
519 "peerDependencies": {
520 "bare-buffer": "*"
521 },
522 "peerDependenciesMeta": {
523 "bare-buffer": {
524 "optional": true
525 }
526 }
527 },
528 "node_modules/bare-module-resolve": {
529 "version": "1.12.4",
530 "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.12.4.tgz",
531 "integrity": "sha512-xcfgg2u7HqgJiBmah71O9vvdFAgHCvkqC/WSC2O7Bbgosoc1eC/BWe/6IDJ4OsfKlkxuvC/TDWXC+oH5yeW8mA==",
532 "dev": true,
533 "license": "Apache-2.0",
534 "dependencies": {
535 "bare-semver": "^1.0.0"
536 },
537 "peerDependencies": {
538 "bare-url": "*"
539 },
540 "peerDependenciesMeta": {
541 "bare-url": {
542 "optional": true
543 }
544 }
545 },
546 "node_modules/bare-net": {
547 "version": "2.3.2",
548 "resolved": "https://registry.npmjs.org/bare-net/-/bare-net-2.3.2.tgz",
549 "integrity": "sha512-I+yz+pqbYsBkxDsnu5vkKvy7RSNY9CcAvu2jZT6PsmdXJQG1i3dmD5V7xc3334OVp2absgtUEYLmmuNFlphBzg==",
550 "dev": true,
551 "license": "Apache-2.0",
552 "dependencies": {
553 "bare-events": "^2.2.2",
554 "bare-pipe": "^4.0.0",
555 "bare-stream": "^2.0.0",
556 "bare-tcp": "^2.0.0"
557 }
558 },
559 "node_modules/bare-os": {
560 "version": "3.9.3",
561 "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.9.3.tgz",
562 "integrity": "sha512-fF4Q7QsyKVF5Rj0qvI8BgUNjqzC2JvQlpTaPLjVJVxYVUX5Zr9un+y3w1HmA4nNKdFmRBT8z/WmrjvXzXVerKQ==",
563 "dev": true,
564 "license": "Apache-2.0",
565 "engines": {
566 "bare": ">=1.14.0"
567 }
568 },
569 "node_modules/bare-path": {
570 "version": "3.1.1",
571 "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.1.1.tgz",
572 "integrity": "sha512-JprUlveX3QjApC1cTpsUOiscADftCGVWkzitbHsRqv84hzYwYHw2mbluddsq5TvI8mH/8Ov1f4BiMAdcB0oYnQ==",
573 "dev": true,
574 "license": "Apache-2.0"
575 },
576 "node_modules/bare-pipe": {
577 "version": "4.2.3",
578 "resolved": "https://registry.npmjs.org/bare-pipe/-/bare-pipe-4.2.3.tgz",
579 "integrity": "sha512-MJYji+Vy8cNMAB2fwg1WQAm1hFIOe5ojw5V9EhEa/wEEYpKT8c36WjHBDwgkgAZfUSX6wQcEFX+Q7wN09SgRow==",
580 "dev": true,
581 "license": "Apache-2.0",
582 "peer": true,
583 "dependencies": {
584 "bare-events": "^2.0.0",
585 "bare-stream": "^2.0.0"
586 },
587 "engines": {
588 "bare": ">=1.16.0"
589 }
590 },
591 "node_modules/bare-posix": {
592 "version": "1.0.1",
593 "resolved": "https://registry.npmjs.org/bare-posix/-/bare-posix-1.0.1.tgz",
594 "integrity": "sha512-b4quA8dyRVvX0aFIAIiev5zFATHwIUGr42Gmt+CqiBNg/bdsNkrj4bbkeotMOMiljJS4DCME5kywJO/TFwKo1A==",
595 "dev": true,
596 "license": "Apache-2.0"
597 },
598 "node_modules/bare-process": {
599 "version": "4.5.1",
600 "resolved": "https://registry.npmjs.org/bare-process/-/bare-process-4.5.1.tgz",
601 "integrity": "sha512-CaAvy1trputD49mtwfJ6G75vydhnirLrW/F3Sznp4H556e1uZn8YMo9ELicBTrGYy7RBNUgPl9bpB/ERzRCiDw==",
602 "dev": true,
603 "license": "Apache-2.0",
604 "dependencies": {
605 "bare-abort": "^2.0.13",
606 "bare-env": "^3.0.0",
607 "bare-events": "^2.3.1",
608 "bare-hrtime": "^2.0.0",
609 "bare-os": "^3.7.1",
610 "bare-posix": "^1.0.1",
611 "bare-signals": "^5.0.0",
612 "bare-stdio": "^1.0.1"
613 }
614 },
615 "node_modules/bare-semver": {
616 "version": "1.1.0",
617 "resolved": "https://registry.npmjs.org/bare-semver/-/bare-semver-1.1.0.tgz",
618 "integrity": "sha512-1Hw5qJ7hXdVt3uPUqjeFTuxyvBUJauvz5A1I2jk8gzjZMHp04n//6nV9MDbG9CMw78JHY2lGV0w6s//LrASm2w==",
619 "dev": true,
620 "license": "Apache-2.0"
621 },
622 "node_modules/bare-signals": {
623 "version": "5.0.0",
624 "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-5.0.0.tgz",
625 "integrity": "sha512-8Gn8bBFUh2AUCJ9wWWFjSGWIo1HIUSIQnXRJGSm/f7GCDMqsuJhRmR1dT+HtDaDBkeu2l8Koxt2JLurfJ5yHVw==",
626 "dev": true,
627 "license": "Apache-2.0",
628 "dependencies": {
629 "bare-events": "^2.5.3"
630 },
631 "engines": {
632 "bare": ">=1.7.0"
633 }
634 },
635 "node_modules/bare-stdio": {
636 "version": "1.0.3",
637 "resolved": "https://registry.npmjs.org/bare-stdio/-/bare-stdio-1.0.3.tgz",
638 "integrity": "sha512-8BRMx7RWMWCbBmKhyHgBco62J+Pgss7+EPI21L3R9+w0UpwDYWUUcbE0YTOesGyt7M6N7VtoshYbzwrP0pI52Q==",
639 "dev": true,
640 "license": "Apache-2.0",
641 "dependencies": {
642 "bare-fs": "^4.5.2",
643 "bare-pipe": "^4.1.5",
644 "bare-tty": "^5.0.3"
645 }
646 },
647 "node_modules/bare-stream": {
648 "version": "2.13.3",
649 "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.3.tgz",
650 "integrity": "sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ==",
651 "dev": true,
652 "license": "Apache-2.0",
653 "dependencies": {
654 "b4a": "^1.8.1",
655 "streamx": "^2.25.0",
656 "teex": "^1.0.1"
657 },
658 "peerDependencies": {
659 "bare-abort-controller": "*",
660 "bare-buffer": "*",
661 "bare-events": "*"
662 },
663 "peerDependenciesMeta": {
664 "bare-abort-controller": {
665 "optional": true
666 },
667 "bare-buffer": {
668 "optional": true
669 },
670 "bare-events": {
671 "optional": true
672 }
673 }
674 },
675 "node_modules/bare-stylize": {
676 "version": "0.0.1",
677 "resolved": "https://registry.npmjs.org/bare-stylize/-/bare-stylize-0.0.1.tgz",
678 "integrity": "sha512-l3MjmIl476bWijYWf3RbE+osl4iuXSOMudzp0vAqzIK7gPgn/+G3oAxp8Oin9CFF911KBP0LO9kts8Ci8mGZaQ==",
679 "dev": true,
680 "license": "Apache-2.0",
681 "dependencies": {
682 "bare-ansi-escapes": "^2.2.3",
683 "bare-process": "^4.2.1"
684 }
685 },
686 "node_modules/bare-subprocess": {
687 "version": "5.2.3",
688 "resolved": "https://registry.npmjs.org/bare-subprocess/-/bare-subprocess-5.2.3.tgz",
689 "integrity": "sha512-07wwswlV7M3sC9IykbZRZ/jHAkrXFWVLqdBWGv1y0ojCimtRD9hGwxdHmR5FUFmDUZLNsBmTYJNQqgio5+A85Q==",
690 "dev": true,
691 "license": "Apache-2.0",
692 "dependencies": {
693 "bare-env": "^3.0.0",
694 "bare-events": "^2.5.4",
695 "bare-os": "^3.0.1",
696 "bare-pipe": "^4.0.0",
697 "bare-url": "^2.2.2"
698 },
699 "engines": {
700 "bare": ">=1.7.0"
701 },
702 "peerDependencies": {
703 "bare-buffer": "*"
704 },
705 "peerDependenciesMeta": {
706 "bare-buffer": {
707 "optional": true
708 }
709 }
710 },
711 "node_modules/bare-tcp": {
712 "version": "2.5.3",
713 "resolved": "https://registry.npmjs.org/bare-tcp/-/bare-tcp-2.5.3.tgz",
714 "integrity": "sha512-TsioekALDulWi0mglooIVG4ML7doxyANKfvuXUU6NS5tFMUnWVuvDht9wQplg07ZS6PQ3jfowzKxNeWdj2e02Q==",
715 "dev": true,
716 "license": "Apache-2.0",
717 "dependencies": {
718 "bare-dns": "^2.0.4",
719 "bare-events": "^2.5.4",
720 "bare-stream": "^2.6.4"
721 },
722 "engines": {
723 "bare": ">=1.16.0"
724 },
725 "peerDependencies": {
726 "bare-pipe": "*"
727 },
728 "peerDependenciesMeta": {
729 "bare-pipe": {
730 "optional": true
731 }
732 }
733 },
734 "node_modules/bare-tls": {
735 "version": "3.1.7",
736 "resolved": "https://registry.npmjs.org/bare-tls/-/bare-tls-3.1.7.tgz",
737 "integrity": "sha512-AMw8tJlb3LhzAmhgXRcjDrTlNxR3gXXyj6G8eU9iwvCFtiUBD8MxAW7bwunA1gXDukgo40A970jX0APc2jMU7A==",
738 "dev": true,
739 "license": "Apache-2.0",
740 "dependencies": {
741 "bare-net": "^2.0.1",
742 "bare-stream": "^2.6.4"
743 },
744 "engines": {
745 "bare": ">=1.7.0"
746 }
747 },
748 "node_modules/bare-tty": {
749 "version": "5.1.2",
750 "resolved": "https://registry.npmjs.org/bare-tty/-/bare-tty-5.1.2.tgz",
751 "integrity": "sha512-wDHPU/yVQtrDCUrKVdIVOLmfIw7dFPETz30UayuFlROvgz8Juv2SmISSMhqxYQVO+fVnG/1ZoLcbGh/35eAjDA==",
752 "dev": true,
753 "license": "Apache-2.0",
754 "dependencies": {
755 "bare-events": "^2.2.0",
756 "bare-signals": "^5.0.0",
757 "bare-stream": "^2.0.0"
758 },
759 "engines": {
760 "bare": ">=1.16.0"
761 }
762 },
763 "node_modules/bare-type": {
764 "version": "1.1.0",
765 "resolved": "https://registry.npmjs.org/bare-type/-/bare-type-1.1.0.tgz",
766 "integrity": "sha512-LdtnnEEYldOc87Dr4GpsKnStStZk3zfgoEMXy8yvEZkXrcCv9RtYDrUYWFsBQHtaB0s1EUWmcvS6XmEZYIj3Bw==",
767 "dev": true,
768 "license": "Apache-2.0",
769 "engines": {
770 "bare": ">=1.2.0"
771 }
772 },
773 "node_modules/bare-type-stripper": {
774 "version": "0.1.4",
775 "resolved": "https://registry.npmjs.org/bare-type-stripper/-/bare-type-stripper-0.1.4.tgz",
776 "integrity": "sha512-FdZhp9XEnQpj8AWFmIft/sVUyKS9XSmB6PhcxBHhuEDxxZM5Kkt8+kFS7eEpLXR7TkaRkNpSENoGH/8lpAmtkA==",
777 "dev": true,
778 "license": "Apache-2.0",
779 "dependencies": {
780 "require-addon": "^1.0.2"
781 },
782 "peerDependencies": {
783 "bare-buffer": "*"
784 },
785 "peerDependenciesMeta": {
786 "bare-buffer": {
787 "optional": true
788 }
789 }
790 },
791 "node_modules/bare-url": {
792 "version": "2.4.6",
793 "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.6.tgz",
794 "integrity": "sha512-iQxPClE07hETVpbRoX7JXX3v/ZQViCxe/SYCxylRLzdEx1xJAufPptfiOqR8tqiCtmbtMDANKWszzjLu1PMAZQ==",
795 "dev": true,
796 "license": "Apache-2.0",
797 "peer": true,
798 "dependencies": {
799 "bare-path": "^3.0.0"
800 }
801 },
802 "node_modules/bare-utils": {
803 "version": "1.6.0",
804 "resolved": "https://registry.npmjs.org/bare-utils/-/bare-utils-1.6.0.tgz",
805 "integrity": "sha512-WhQEIkkAxkSnW7u1QgrI0AfNm5JpMruETXeYsb5qnkBJ0TTfNKygZmsh6rkoHBANaV+C/7Jed7bJP9OmEHG7rQ==",
806 "dev": true,
807 "license": "Apache-2.0",
808 "dependencies": {
809 "bare-debug-log": "^2.0.0",
810 "bare-encoding": "^1.0.0",
811 "bare-format": "^1.0.0",
812 "bare-inspect": "^3.0.0",
813 "bare-stylize": "^0.0.1",
814 "bare-type": "^1.0.6"
815 }
816 },
817 "node_modules/bare-v8-to-istanbul": {
818 "version": "1.0.2",
819 "resolved": "https://registry.npmjs.org/bare-v8-to-istanbul/-/bare-v8-to-istanbul-1.0.2.tgz",
820 "integrity": "sha512-CM0wPgyQtXTQ7h4q8NjbTZ/FH5he0Jkiwgpq0lFZZA5tkVZzmQ/9ul4R7E+cNlGZJIZlQZ9v4CwbgVaFG3zOAA==",
821 "dev": true,
822 "license": "Apache-2.0",
823 "dependencies": {
824 "bare-assert": "^1.0.2",
825 "bare-fs": "^4.1.2",
826 "bare-module": "^6.1.2",
827 "bare-path": "^3.0.0",
828 "bare-process": "^4.2.0",
829 "bare-url": "^2.1.5",
830 "bare-utils": "^1.2.0",
831 "v8-to-istanbul": "^9.3.0",
832 "which-runtime": "^1.2.1"
833 }
834 },
835 "node_modules/bare-ws": {
836 "version": "3.0.0",
837 "resolved": "https://registry.npmjs.org/bare-ws/-/bare-ws-3.0.0.tgz",
838 "integrity": "sha512-q2v0UIQ0cFQBXQMp+0FRaoSk1EoYgOhzO7yio0TqBV6Rkfot97mbBYxb1ssw5faVCisVaFxQYY8113SMLYQBow==",
839 "dev": true,
840 "license": "Apache-2.0",
841 "dependencies": {
842 "bare-crypto": "^1.2.0",
843 "bare-events": "^2.3.1",
844 "bare-http1": "^4.0.0",
845 "bare-https": "^3.0.0",
846 "bare-stream": "^2.1.2"
847 },
848 "peerDependencies": {
849 "bare-buffer": "*",
850 "bare-url": "*"
851 },
852 "peerDependenciesMeta": {
853 "bare-buffer": {
854 "optional": true
855 },
856 "bare-url": {
857 "optional": true
858 }
859 }
860 },
861 "node_modules/big-sparse-array": {
862 "version": "1.0.3",
863 "resolved": "https://registry.npmjs.org/big-sparse-array/-/big-sparse-array-1.0.3.tgz",
864 "integrity": "sha512-6RjV/3mSZORlMdpUaQ6rUSpG637cZm0//E54YYGtQg1c1O+AbZP8UTdJ/TchsDZcTVLmyWZcseBfp2HBeXUXOQ==",
865 "dev": true,
866 "license": "MIT"
867 },
868 "node_modules/brittle": {
869 "version": "3.19.1",
870 "resolved": "https://registry.npmjs.org/brittle/-/brittle-3.19.1.tgz",
871 "integrity": "sha512-4Ted1Mt9o9B6oIA6ImJJCtB/Fv++ZO3IDNQgRcHOXWSYGRUidgxchaGrUBaRn+4mlneXrgInPkCPzi0jO8qKbA==",
872 "dev": true,
873 "license": "Apache-2.0",
874 "dependencies": {
875 "b4a": "^1.6.0",
876 "bare-assert": "^1.0.2",
877 "bare-cov": "^1.1.0",
878 "bare-fs": "^4.1.6",
879 "bare-os": "^3.6.1",
880 "bare-path": "^3.0.0",
881 "bare-process": "^4.2.1",
882 "bare-subprocess": "^5.0.0",
883 "bare-url": "^2.1.6",
884 "error-stack-parser": "^2.1.4",
885 "globbie": "^1.0.2",
886 "paparam": "^1.6.2",
887 "same-object": "^1.0.2",
888 "test-tmp": "^1.4.0",
889 "tmatch": "^5.0.0"
890 },
891 "bin": {
892 "brittle": "bin/node.js",
893 "brittle-bare": "bin/bare.js",
894 "brittle-node": "bin/node.js",
895 "brittle-pear": "bin/pear.js"
896 }
897 },
898 "node_modules/codecs": {
899 "version": "3.1.0",
900 "resolved": "https://registry.npmjs.org/codecs/-/codecs-3.1.0.tgz",
901 "integrity": "sha512-Dqx8NwvBvnMeuPQdVKy/XEF71igjR5apxBvCGeV0pP1tXadOiaLvDTXt7xh+/5wI1ASB195mXQGJbw3Ml4YDWQ==",
902 "dev": true,
903 "license": "MIT",
904 "dependencies": {
905 "b4a": "^1.6.3"
906 }
907 },
908 "node_modules/compact-encoding": {
909 "version": "3.3.0",
910 "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-3.3.0.tgz",
911 "integrity": "sha512-e64XyzlBvTRJ3iScuU/U2w25Dglkm7fhrRbrGaHIwuTlNnzjRKMaQBCVl7mJRvZg7wI5a9wX1IVTXCuaAANNkw==",
912 "dev": true,
913 "license": "Apache-2.0",
914 "dependencies": {
915 "b4a": "^1.3.0"
916 }
917 },
918 "node_modules/convert-source-map": {
919 "version": "2.0.0",
920 "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
921 "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
922 "dev": true,
923 "license": "MIT"
924 },
925 "node_modules/core-coupler": {
926 "version": "2.0.0",
927 "resolved": "https://registry.npmjs.org/core-coupler/-/core-coupler-2.0.0.tgz",
928 "integrity": "sha512-FJuEvsdCMwx0Wu+gFQ49rGCi8LCXh8kizHsCQwkdgPZFEFiF0z2HDvyIs+fPt5wMIfU2UVFDuN+dtpfbIxJE6g==",
929 "dev": true,
930 "license": "Apache-2.0",
931 "dependencies": {
932 "safety-catch": "^1.0.2"
933 }
934 },
935 "node_modules/corestore": {
936 "version": "7.11.0",
937 "resolved": "https://registry.npmjs.org/corestore/-/corestore-7.11.0.tgz",
938 "integrity": "sha512-zGlF6dBZ9bvyRliz6g+NW0tGRwGYmmc84o1TARbXOJ+fPRXeKTkVzVV95eWIJEU3+6WBUbcvIBQKmKiNmiTAdg==",
939 "dev": true,
940 "license": "MIT",
941 "dependencies": {
942 "b4a": "^1.6.7",
943 "bare-events": "^2.8.3",
944 "hypercore": "^11.32.0",
945 "hypercore-crypto": "^3.4.2",
946 "hypercore-errors": "^1.4.0",
947 "hypercore-id-encoding": "^1.3.0",
948 "ready-resource": "^1.1.1",
949 "sodium-universal": "^5.0.1",
950 "streamx": "^2.26.0",
951 "which-runtime": "^1.2.1"
952 }
953 },
954 "node_modules/debounceify": {
955 "version": "1.1.0",
956 "resolved": "https://registry.npmjs.org/debounceify/-/debounceify-1.1.0.tgz",
957 "integrity": "sha512-eKuHDVfJVg+u/0nPy8P+fhnLgbyuTgVxuCRrS/R7EpDSMMkBDgSes41MJtSAY1F1hcqfHz3Zy/qpqHHIp/EhdA==",
958 "dev": true,
959 "license": "MIT"
960 },
961 "node_modules/device-file": {
962 "version": "2.3.1",
963 "resolved": "https://registry.npmjs.org/device-file/-/device-file-2.3.1.tgz",
964 "integrity": "sha512-bmON44lwxJPle9N2OcH4tqM44pMGZKT8G6OkzXkz0urvqQ9LKkoQdTS6w0ztYfmLdUE27R4UUmx0+y2gEz4Jug==",
965 "dev": true,
966 "license": "Apache-2.0",
967 "dependencies": {
968 "b4a": "^1.6.7",
969 "bare-fs": "^4.0.1",
970 "bare-path": "^3.0.0",
971 "fd-lock": "^2.1.0",
972 "fs-native-extensions": "^1.4.0",
973 "ready-resource": "^1.2.0"
974 }
975 },
976 "node_modules/encryption-encoding": {
977 "version": "1.0.3",
978 "resolved": "https://registry.npmjs.org/encryption-encoding/-/encryption-encoding-1.0.3.tgz",
979 "integrity": "sha512-+SlKCeULnNnwBF2rGrJlSLYjwITwfjO8PLSHzue4yt+2DsVJUU8GakRkH4+mTaa3FzpxVjpTy1kKR2gYGctNWg==",
980 "dev": true,
981 "license": "Apache-2.0",
982 "dependencies": {
983 "hyperschema": "^1.19.0"
984 }
985 },
986 "node_modules/error-stack-parser": {
987 "version": "2.1.4",
988 "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz",
989 "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==",
990 "dev": true,
991 "license": "MIT",
992 "dependencies": {
993 "stackframe": "^1.3.4"
994 }
995 },
996 "node_modules/events-universal": {
997 "version": "1.0.1",
998 "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz",
999 "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==",
1000 "dev": true,
1001 "license": "Apache-2.0",
1002 "dependencies": {
1003 "bare-events": "^2.7.0"
1004 }
1005 },
1006 "node_modules/fast-fifo": {
1007 "version": "1.3.2",
1008 "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
1009 "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
1010 "dev": true,
1011 "license": "MIT"
1012 },
1013 "node_modules/fd-lock": {
1014 "version": "2.2.0",
1015 "resolved": "https://registry.npmjs.org/fd-lock/-/fd-lock-2.2.0.tgz",
1016 "integrity": "sha512-Il4jWBhjjgvUg+z8d0bC7ncXqB42caqKTUpnZ9jpcqiPmw8bkIixt7Kic1czbZPMxAQD/9kEqfZ5Dq77nSll0w==",
1017 "dev": true,
1018 "license": "Apache-2.0",
1019 "dependencies": {
1020 "bare-fs": "^4.5.0",
1021 "fs-native-extensions": "^1.4.4",
1022 "ready-resource": "^1.2.0",
1023 "resource-on-exit": "^1.0.0"
1024 }
1025 },
1026 "node_modules/flat-tree": {
1027 "version": "1.13.0",
1028 "resolved": "https://registry.npmjs.org/flat-tree/-/flat-tree-1.13.0.tgz",
1029 "integrity": "sha512-fT3HIuCPwHhFgJ20QYzDHgUG0zMmFg5cHvFiFo5h+QMSJ28TihsEVY0f8HGliuO+pOzmvjMx1odToeaEWkTnyQ==",
1030 "dev": true,
1031 "license": "MIT"
1032 },
1033 "node_modules/fs-native-extensions": {
1034 "version": "1.5.0",
1035 "resolved": "https://registry.npmjs.org/fs-native-extensions/-/fs-native-extensions-1.5.0.tgz",
1036 "integrity": "sha512-nuZLFm9mGCxvyi7Llww/J4OyifKCS21nEUTAmnlTZp3FObPOvA32aCedCmt4Z+8yk+caqfClNaSCfn/P7T7FLQ==",
1037 "dev": true,
1038 "license": "Apache-2.0",
1039 "dependencies": {
1040 "require-addon": "^1.1.0",
1041 "which-runtime": "^1.2.0"
1042 }
1043 },
1044 "node_modules/generate-object-property": {
1045 "version": "2.0.0",
1046 "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-2.0.0.tgz",
1047 "integrity": "sha512-KwuURPyqn2Mz8DdV29pJwQu0Y7tcsbkULr82eeOcY/ZllFK6I9Wm8dsRByIu7CKWlFi9BdW1b3mcXMp/kQBQsw==",
1048 "dev": true,
1049 "license": "MIT",
1050 "dependencies": {
1051 "is-property": "^1.0.0"
1052 }
1053 },
1054 "node_modules/generate-string": {
1055 "version": "1.0.1",
1056 "resolved": "https://registry.npmjs.org/generate-string/-/generate-string-1.0.1.tgz",
1057 "integrity": "sha512-IfTY0dKZM43ACyGvXkbG7De7WY7MxTS5VO6Juhe8oJKpCmrYYXoqp/cJMskkpi0k9H8wuXq0H+eI898/BCqvXg==",
1058 "dev": true,
1059 "license": "MIT"
1060 },
1061 "node_modules/globbie": {
1062 "version": "1.0.5",
1063 "resolved": "https://registry.npmjs.org/globbie/-/globbie-1.0.5.tgz",
1064 "integrity": "sha512-P/NGQsM5Qxg5UEsqB3GmrVIwugvF5U0nDn6+F8Yn9kV2WOGpT8i38NEHB9mkHhU9Iz2P2hzAhzlVVOX2rSVI2g==",
1065 "dev": true,
1066 "license": "Apache-2.0",
1067 "dependencies": {
1068 "bare-fs": "^4.7.4",
1069 "bare-path": "^3.1.1",
1070 "bare-process": "^4.5.1",
1071 "picomatch": "^4.0.5"
1072 }
1073 },
1074 "node_modules/hyperbee": {
1075 "version": "2.27.3",
1076 "resolved": "https://registry.npmjs.org/hyperbee/-/hyperbee-2.27.3.tgz",
1077 "integrity": "sha512-PXURH2U4juUZyJRKHTrY5z1zX851pmI1Q0jfv5F/hCIErDt/ND8jOZuxc3hfOLM9f0W3qJEDTMlV5AJBkVPy8w==",
1078 "dev": true,
1079 "license": "MIT",
1080 "dependencies": {
1081 "b4a": "^1.6.0",
1082 "codecs": "^3.0.0",
1083 "debounceify": "^1.0.0",
1084 "hypercore-errors": "^1.0.0",
1085 "mutexify": "^1.4.0",
1086 "protocol-buffers-encodings": "^1.2.0",
1087 "rache": "^1.0.0",
1088 "ready-resource": "^1.0.0",
1089 "resolve-reject-promise": "^1.1.0",
1090 "safety-catch": "^1.0.2",
1091 "streamx": "^2.12.4",
1092 "unslab": "^1.2.0"
1093 }
1094 },
1095 "node_modules/hypercore": {
1096 "version": "11.34.1",
1097 "resolved": "https://registry.npmjs.org/hypercore/-/hypercore-11.34.1.tgz",
1098 "integrity": "sha512-nlrbXjI4x59akT8AwVEFLN54OicB53JDnH1xYP4j9zKDksHUVgqJFXnFwOkRr4Nr3kwCU0b9Rh3eIsU0JX5HEA==",
1099 "dev": true,
1100 "license": "MIT",
1101 "dependencies": {
1102 "@hyperswarm/secret-stream": "^6.0.0",
1103 "b4a": "^1.1.0",
1104 "bare-events": "^2.2.0",
1105 "big-sparse-array": "^1.0.3",
1106 "compact-encoding": "^3.0.0",
1107 "fast-fifo": "^1.3.0",
1108 "flat-tree": "^1.9.0",
1109 "hypercore-crypto": "^3.2.1",
1110 "hypercore-errors": "^1.5.0",
1111 "hypercore-id-encoding": "^1.2.0",
1112 "hypercore-storage": "^3.2.0",
1113 "is-options": "^1.0.1",
1114 "nanoassert": "^2.0.0",
1115 "protomux": "^3.5.0",
1116 "quickbit-universal": "^2.2.0",
1117 "random-array-iterator": "^1.0.0",
1118 "safety-catch": "^1.0.1",
1119 "sodium-universal": "^5.0.1",
1120 "streamx": "^2.12.4",
1121 "unslab": "^1.3.0",
1122 "z32": "^1.0.0"
1123 }
1124 },
1125 "node_modules/hypercore-crypto": {
1126 "version": "3.7.0",
1127 "resolved": "https://registry.npmjs.org/hypercore-crypto/-/hypercore-crypto-3.7.0.tgz",
1128 "integrity": "sha512-SWxobptQf2V/+ZLCCDRTXqFzGfTPIkNIuDyLKXpEMfcpJ1/ec94N9aWgylHcWOHmRt14ng/KR7z0BugebWHK9Q==",
1129 "dev": true,
1130 "license": "MIT",
1131 "dependencies": {
1132 "b4a": "^1.6.6",
1133 "compact-encoding": "^3.0.0",
1134 "sodium-universal": "^5.0.0"
1135 }
1136 },
1137 "node_modules/hypercore-errors": {
1138 "version": "1.5.0",
1139 "resolved": "https://registry.npmjs.org/hypercore-errors/-/hypercore-errors-1.5.0.tgz",
1140 "integrity": "sha512-5KQ/SuDxsvet+7qWA35Ay6zdD9WyAHQoyWHGcPUTbmJBd300gvNIJoi3oma7kp4TTCSzii6qYumNZe/s0j/saQ==",
1141 "dev": true,
1142 "license": "Apache-2.0",
1143 "dependencies": {
1144 "hypercore-id-encoding": "^1.3.0"
1145 }
1146 },
1147 "node_modules/hypercore-id-encoding": {
1148 "version": "1.3.0",
1149 "resolved": "https://registry.npmjs.org/hypercore-id-encoding/-/hypercore-id-encoding-1.3.0.tgz",
1150 "integrity": "sha512-W6sHdGo5h7LXEsoWfKf/KfuROZmZRQDlGqJF2EPHW+noCK66Vvr0+zE6cL0vqQi18s0kQPeN7Sq3QyR0Ytc2VQ==",
1151 "dev": true,
1152 "license": "Apache-2.0",
1153 "dependencies": {
1154 "b4a": "^1.5.3",
1155 "z32": "^1.0.0"
1156 }
1157 },
1158 "node_modules/hypercore-storage": {
1159 "version": "3.2.0",
1160 "resolved": "https://registry.npmjs.org/hypercore-storage/-/hypercore-storage-3.2.0.tgz",
1161 "integrity": "sha512-i5O5ZMkdZaNAWGuNRXUZjuzv7B41OIhDHUwLCZPjucgVmywY0ZE5PDafu6e5oPuhtghjl6S8q6Jn+POVKN2BvQ==",
1162 "dev": true,
1163 "license": "Apache-2.0",
1164 "dependencies": {
1165 "b4a": "^1.6.7",
1166 "bare-path": "^3.0.0",
1167 "compact-encoding": "^3.1.0",
1168 "device-file": "^2.1.2",
1169 "flat-tree": "^1.12.1",
1170 "hypercore-crypto": "^3.4.2",
1171 "hyperschema": "^1.21.0",
1172 "index-encoder": "^3.3.2",
1173 "resolve-reject-promise": "^1.0.0",
1174 "rocksdb-native": "^3.11.0",
1175 "scope-lock": "^1.2.4",
1176 "streamx": "^2.21.1",
1177 "xache": "^1.2.1"
1178 }
1179 },
1180 "node_modules/hyperschema": {
1181 "version": "1.21.0",
1182 "resolved": "https://registry.npmjs.org/hyperschema/-/hyperschema-1.21.0.tgz",
1183 "integrity": "sha512-lEnIbLTUQf7w6FU6X+R3yUJhBwCzF4ewRnAaYOrPdcVWe1rbOf94PzMiXb5pBKxroCXzlrPLxVujxAsTrrHc8g==",
1184 "dev": true,
1185 "license": "Apache-2.0",
1186 "dependencies": {
1187 "bare-fs": "^4.0.1",
1188 "compact-encoding": "^3.0.0",
1189 "generate-object-property": "^2.0.0",
1190 "generate-string": "^1.0.1"
1191 }
1192 },
1193 "node_modules/index-encoder": {
1194 "version": "3.5.0",
1195 "resolved": "https://registry.npmjs.org/index-encoder/-/index-encoder-3.5.0.tgz",
1196 "integrity": "sha512-idZ1cxtZz2dRV6rUiaP9Xo99UjXbSzjcMacoQmxUMu/A7fEQcNPngvwDJYeWelQUS5XFlY71/or70lKn6XnwbQ==",
1197 "dev": true,
1198 "license": "Apache-2.0",
1199 "dependencies": {
1200 "b4a": "^1.6.4"
1201 }
1202 },
1203 "node_modules/is-options": {
1204 "version": "1.0.2",
1205 "resolved": "https://registry.npmjs.org/is-options/-/is-options-1.0.2.tgz",
1206 "integrity": "sha512-u+Ai74c8Q74aS8BuHwPdI1jptGOT1FQXgCq8/zv0xRuE+wRgSMEJLj8lVO8Zp9BeGb29BXY6AsNPinfqjkr7Fg==",
1207 "dev": true,
1208 "license": "MIT",
1209 "dependencies": {
1210 "b4a": "^1.1.1"
1211 }
1212 },
1213 "node_modules/is-property": {
1214 "version": "1.0.2",
1215 "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
1216 "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==",
1217 "dev": true,
1218 "license": "MIT"
1219 },
1220 "node_modules/mutexify": {
1221 "version": "1.4.0",
1222 "resolved": "https://registry.npmjs.org/mutexify/-/mutexify-1.4.0.tgz",
1223 "integrity": "sha512-pbYSsOrSB/AKN5h/WzzLRMFgZhClWccf2XIB4RSMC8JbquiB0e0/SH5AIfdQMdyHmYtv4seU7yV/TvAwPLJ1Yg==",
1224 "dev": true,
1225 "license": "MIT",
1226 "dependencies": {
1227 "queue-tick": "^1.0.0"
1228 }
1229 },
1230 "node_modules/nanoassert": {
1231 "version": "2.0.0",
1232 "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz",
1233 "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==",
1234 "dev": true,
1235 "license": "ISC"
1236 },
1237 "node_modules/noise-curve-ed": {
1238 "version": "2.1.0",
1239 "resolved": "https://registry.npmjs.org/noise-curve-ed/-/noise-curve-ed-2.1.0.tgz",
1240 "integrity": "sha512-zAzJx+VwZM3w6EA1hTmDhJfvAnCeBQn/1FAeZ0LtGxCcCtlAK/uJXQVF/eDVUOaAZ286lHlx77WJ+qj9SmsRRg==",
1241 "dev": true,
1242 "license": "ISC",
1243 "dependencies": {
1244 "b4a": "^1.1.0",
1245 "nanoassert": "^2.0.0",
1246 "sodium-universal": "^5.0.0"
1247 }
1248 },
1249 "node_modules/noise-handshake": {
1250 "version": "4.2.0",
1251 "resolved": "https://registry.npmjs.org/noise-handshake/-/noise-handshake-4.2.0.tgz",
1252 "integrity": "sha512-9O/VTNX/E2/AToyMTTDU0J/4WhaXMTdqc2DHs9vf+snoZ0cenSBq0dNYTVV1snYYEkmo6QeRrYMxtqtoYnY+LA==",
1253 "dev": true,
1254 "license": "Apache-2.0",
1255 "dependencies": {
1256 "b4a": "^1.1.0",
1257 "nanoassert": "^2.0.0",
1258 "sodium-universal": "^5.0.0"
1259 }
1260 },
1261 "node_modules/paparam": {
1262 "version": "1.10.1",
1263 "resolved": "https://registry.npmjs.org/paparam/-/paparam-1.10.1.tgz",
1264 "integrity": "sha512-viyQI64VIja0Za3njIzhoEP8ZVkgPowhZPuG0E96NwBfYJ6ZIyrrlhWGtFPkdN7eYLl2L8CTWL+wla0evm1KKQ==",
1265 "dev": true,
1266 "license": "Apache-2.0"
1267 },
1268 "node_modules/picomatch": {
1269 "version": "4.0.5",
1270 "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
1271 "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
1272 "dev": true,
1273 "license": "MIT",
1274 "engines": {
1275 "node": ">=12"
1276 },
1277 "funding": {
1278 "url": "https://github.com/sponsors/jonschlinkert"
1279 }
1280 },
1281 "node_modules/protocol-buffers-encodings": {
1282 "version": "1.2.0",
1283 "resolved": "https://registry.npmjs.org/protocol-buffers-encodings/-/protocol-buffers-encodings-1.2.0.tgz",
1284 "integrity": "sha512-daeNPuKh1NlLD1uDfbLpD+xyUTc07nEtfHwmBZmt/vH0B7VOM+JOCOpDcx9ZRpqHjAiIkGqyTDi+wfGSl17R9w==",
1285 "dev": true,
1286 "license": "MIT",
1287 "dependencies": {
1288 "b4a": "^1.6.0",
1289 "signed-varint": "^2.0.1",
1290 "varint": "5.0.0"
1291 }
1292 },
1293 "node_modules/protomux": {
1294 "version": "3.11.0",
1295 "resolved": "https://registry.npmjs.org/protomux/-/protomux-3.11.0.tgz",
1296 "integrity": "sha512-Ze43XaNHbL6zQ/zJwVYvue7Aj8pDB1HNnISsrFhAur3291Y+Iu2fMhOpySD73J/32BoBIUYrhl07lJsBR/fUVA==",
1297 "dev": true,
1298 "license": "MIT",
1299 "dependencies": {
1300 "b4a": "^1.3.1",
1301 "compact-encoding": "^3.0.0",
1302 "queue-tick": "^1.0.0",
1303 "safety-catch": "^1.0.1",
1304 "unslab": "^1.3.0"
1305 }
1306 },
1307 "node_modules/protomux-wakeup": {
1308 "version": "2.9.0",
1309 "resolved": "https://registry.npmjs.org/protomux-wakeup/-/protomux-wakeup-2.9.0.tgz",
1310 "integrity": "sha512-K93WhS9qIRL8WAQPU2V3PxdpQ1oRlQCFyCyIYInoq/iRkcuO1BegRERWo7SS1Tcme14VKGWOr/IivjjYnHan3Q==",
1311 "dev": true,
1312 "license": "Apache-2.0",
1313 "dependencies": {
1314 "b4a": "^1.6.7",
1315 "hypercore-crypto": "^3.5.0",
1316 "hyperschema": "^1.10.4",
1317 "protomux": "^3.10.1"
1318 }
1319 },
1320 "node_modules/queue-tick": {
1321 "version": "1.0.1",
1322 "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
1323 "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==",
1324 "dev": true,
1325 "license": "MIT"
1326 },
1327 "node_modules/quickbit-native": {
1328 "version": "2.4.8",
1329 "resolved": "https://registry.npmjs.org/quickbit-native/-/quickbit-native-2.4.8.tgz",
1330 "integrity": "sha512-FcCcqI+nIAWGknqhtrYT5TSD7t/N+Xd8ctM+2PrIIBuwOi5hx0SxAvuPtzLIEMfT/2h9+fhBakUe2uALOHX6yw==",
1331 "dev": true,
1332 "license": "Apache-2.0",
1333 "optional": true,
1334 "dependencies": {
1335 "require-addon": "^1.1.0"
1336 }
1337 },
1338 "node_modules/quickbit-universal": {
1339 "version": "2.2.0",
1340 "resolved": "https://registry.npmjs.org/quickbit-universal/-/quickbit-universal-2.2.0.tgz",
1341 "integrity": "sha512-w02i1R8n7+6pEKTud8DfF8zbFY9o7RtPlUc3jWbtCkDKvhbx/AvV7oNnz4/TcmsPGpSJS+fq5Ud6RH6+YPvSGg==",
1342 "dev": true,
1343 "license": "ISC",
1344 "dependencies": {
1345 "b4a": "^1.6.0",
1346 "simdle-universal": "^1.1.0"
1347 },
1348 "optionalDependencies": {
1349 "quickbit-native": "^2.2.0"
1350 }
1351 },
1352 "node_modules/rache": {
1353 "version": "1.0.0",
1354 "resolved": "https://registry.npmjs.org/rache/-/rache-1.0.0.tgz",
1355 "integrity": "sha512-e0k0g0w/8jOCB+7YqCIlOa+OJ38k0wrYS4x18pMSmqOvLKoyhmMhmQyCcvfY6VaP8D75cqkEnlakXs+RYYLqNg==",
1356 "dev": true,
1357 "license": "Apache-2.0"
1358 },
1359 "node_modules/random-array-iterator": {
1360 "version": "1.0.0",
1361 "resolved": "https://registry.npmjs.org/random-array-iterator/-/random-array-iterator-1.0.0.tgz",
1362 "integrity": "sha512-u7xCM93XqKEvPTP6xZp2ehttcAemKnh73oKNf1FvzuVCfpt6dILDt1Kxl1LeBjm2iNIeR49VGFhy4Iz3yOun+Q==",
1363 "dev": true,
1364 "license": "MIT"
1365 },
1366 "node_modules/ready-resource": {
1367 "version": "1.2.0",
1368 "resolved": "https://registry.npmjs.org/ready-resource/-/ready-resource-1.2.0.tgz",
1369 "integrity": "sha512-nfcco/8iAFV0M+2PYnmIc+/xY0iRb35d42HFHQ7AfjulbGEAFa+XWpByfwSyeVeiBoMLLFVMv1HixxNCqzSQ1g==",
1370 "dev": true,
1371 "license": "MIT",
1372 "dependencies": {
1373 "bare-events": "^2.2.0"
1374 }
1375 },
1376 "node_modules/refcounter": {
1377 "version": "1.0.0",
1378 "resolved": "https://registry.npmjs.org/refcounter/-/refcounter-1.0.0.tgz",
1379 "integrity": "sha512-1WosVzUy0kPUaPMEtlNDwm99UsteALIhXXR8rerELoa63WkYIXAl0hxgwPFrIYBRWZPGUyekQ04FRtPJ7dHk9w==",
1380 "dev": true,
1381 "license": "Apache-2.0"
1382 },
1383 "node_modules/require-addon": {
1384 "version": "1.2.0",
1385 "resolved": "https://registry.npmjs.org/require-addon/-/require-addon-1.2.0.tgz",
1386 "integrity": "sha512-VNPDZlYgIYQwWp9jMTzljx+k0ZtatKlcvOhktZ/anNPI3dQ9NXk7cq2U4iJ1wd9IrytRnYhyEocFWbkdPb+MYA==",
1387 "dev": true,
1388 "license": "Apache-2.0",
1389 "dependencies": {
1390 "bare-addon-resolve": "^1.3.0"
1391 },
1392 "engines": {
1393 "bare": ">=1.10.0"
1394 }
1395 },
1396 "node_modules/resolve-reject-promise": {
1397 "version": "1.1.0",
1398 "resolved": "https://registry.npmjs.org/resolve-reject-promise/-/resolve-reject-promise-1.1.0.tgz",
1399 "integrity": "sha512-LWsTOA91AqzBTjSGgX79Tc130pwcBK6xjpJEO+qRT5IKZ6bGnHKcc8QL3upUBcWuU8OTIDzKK2VNSwmmlqvAVg==",
1400 "dev": true,
1401 "license": "MIT"
1402 },
1403 "node_modules/resource-on-exit": {
1404 "version": "1.0.0",
1405 "resolved": "https://registry.npmjs.org/resource-on-exit/-/resource-on-exit-1.0.0.tgz",
1406 "integrity": "sha512-ViJwJAknCkLRJRPR+9SISQQ7R5eRgtdIHLJsM2hHx1MweAJbJxJ5XnMjjq0Lc7ZGv44ufzAqds1nKxiVkdy4ag==",
1407 "dev": true,
1408 "license": "Apache-2.0"
1409 },
1410 "node_modules/rocksdb-native": {
1411 "version": "3.17.2",
1412 "resolved": "https://registry.npmjs.org/rocksdb-native/-/rocksdb-native-3.17.2.tgz",
1413 "integrity": "sha512-6kijLkb7NrUFCyWQsIxKIU/iQASxdqLDWrteAeXVEq1MJWrJUcXP6MDPRh8Ux7im2sBereDiI/D4vxYV2ia90A==",
1414 "dev": true,
1415 "license": "Apache-2.0",
1416 "dependencies": {
1417 "compact-encoding": "^3.0.0",
1418 "ready-resource": "^1.0.0",
1419 "refcounter": "^1.0.0",
1420 "require-addon": "^1.0.2",
1421 "resolve-reject-promise": "^1.1.0",
1422 "signal-promise": "^1.0.3",
1423 "streamx": "^2.16.1"
1424 },
1425 "engines": {
1426 "bare": ">=1.16.0"
1427 }
1428 },
1429 "node_modules/safety-catch": {
1430 "version": "1.0.3",
1431 "resolved": "https://registry.npmjs.org/safety-catch/-/safety-catch-1.0.3.tgz",
1432 "integrity": "sha512-Zq+J1TefpoEq/HTUabo0YXX5MNvttjWYODGohgPBO2jfko8Wqx3JYMgE823szDFVamdH5PlpByvfiWScTdSYDA==",
1433 "dev": true,
1434 "license": "MIT"
1435 },
1436 "node_modules/same-object": {
1437 "version": "1.0.2",
1438 "resolved": "https://registry.npmjs.org/same-object/-/same-object-1.0.2.tgz",
1439 "integrity": "sha512-csHWhvUsLbIOHDM/nP+KHWM+BLPsIzWkFa8HbzaI0G7BqKXgx+7FJpKTGgLXyz5amfdY2OVBcmXTqYOMEk04og==",
1440 "dev": true,
1441 "license": "MIT"
1442 },
1443 "node_modules/scope-lock": {
1444 "version": "1.2.4",
1445 "resolved": "https://registry.npmjs.org/scope-lock/-/scope-lock-1.2.4.tgz",
1446 "integrity": "sha512-BpSd8VCuCxW9ZitcdIC/vjs3gMaP9bRBL5nkHcyfX2VrS52n13/rHuBA2xJ/S/4DPuRdAO/Bk8pWd8eD/gHCIA==",
1447 "dev": true,
1448 "license": "Apache-2.0"
1449 },
1450 "node_modules/signal-promise": {
1451 "version": "1.0.3",
1452 "resolved": "https://registry.npmjs.org/signal-promise/-/signal-promise-1.0.3.tgz",
1453 "integrity": "sha512-WBgv0UnIq2C+Aeh0/n+IRpP6967eIx9WpynTUoiW3isPpfe1zu2LJzyfXdo9Tgef8yR/sGjcMvoUXD7EYdiz+g==",
1454 "dev": true,
1455 "license": "MIT"
1456 },
1457 "node_modules/signed-varint": {
1458 "version": "2.0.1",
1459 "resolved": "https://registry.npmjs.org/signed-varint/-/signed-varint-2.0.1.tgz",
1460 "integrity": "sha512-abgDPg1106vuZZOvw7cFwdCABddfJRz5akcCcchzTbhyhYnsG31y4AlZEgp315T7W3nQq5P4xeOm186ZiPVFzw==",
1461 "dev": true,
1462 "license": "MIT",
1463 "dependencies": {
1464 "varint": "~5.0.0"
1465 }
1466 },
1467 "node_modules/simdle-native": {
1468 "version": "1.3.9",
1469 "resolved": "https://registry.npmjs.org/simdle-native/-/simdle-native-1.3.9.tgz",
1470 "integrity": "sha512-Isc8sP4OiiIU0mpslD4GHEnR0VQWvR/54WN7YtwEDkNdTJVWtpmvsSvsgRlw5BNGxdYXlVRegdnrSu10H/PhvA==",
1471 "dev": true,
1472 "license": "Apache-2.0",
1473 "optional": true,
1474 "dependencies": {
1475 "b4a": "^1.6.0",
1476 "require-addon": "^1.1.0"
1477 }
1478 },
1479 "node_modules/simdle-universal": {
1480 "version": "1.1.2",
1481 "resolved": "https://registry.npmjs.org/simdle-universal/-/simdle-universal-1.1.2.tgz",
1482 "integrity": "sha512-3n3w1bs+uwgHKQjt6arez83EywNlhZzYvNOhvAASTl/8KqNIcqr6aHyGt3JRlfuUC7iB0tomJRPlJ2cRGIpBzA==",
1483 "dev": true,
1484 "license": "ISC",
1485 "dependencies": {
1486 "b4a": "^1.6.0"
1487 },
1488 "optionalDependencies": {
1489 "simdle-native": "^1.1.1"
1490 }
1491 },
1492 "node_modules/sodium-native": {
1493 "version": "5.1.0",
1494 "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-5.1.0.tgz",
1495 "integrity": "sha512-3RxgyWyJlhTsABPnJVpCI5CoTDANZTqqFrEPqr+kjfnRaBihpVtMUE3yTF40ukdoB1APXeoBNKF3MzZAIHg39g==",
1496 "dev": true,
1497 "license": "MIT",
1498 "dependencies": {
1499 "bare-assert": "^1.2.0",
1500 "require-addon": "^1.1.0",
1501 "which-runtime": "^1.2.1"
1502 },
1503 "engines": {
1504 "bare": ">=1.16.0"
1505 }
1506 },
1507 "node_modules/sodium-secretstream": {
1508 "version": "1.2.0",
1509 "resolved": "https://registry.npmjs.org/sodium-secretstream/-/sodium-secretstream-1.2.0.tgz",
1510 "integrity": "sha512-q/DbraNFXm1KfCiiZvapmz5UC3OlpirYFIvBK2MhGaOFSb3gRyk8OXTi17UI9SGfshQNCpsVvlopogbzZNyW6Q==",
1511 "dev": true,
1512 "license": "MIT",
1513 "dependencies": {
1514 "b4a": "^1.1.1",
1515 "sodium-universal": "^5.0.0"
1516 }
1517 },
1518 "node_modules/sodium-universal": {
1519 "version": "5.0.1",
1520 "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-5.0.1.tgz",
1521 "integrity": "sha512-rv+aH+tnKB5H0MAc2UadHShLMslpJsc4wjdnHRtiSIEYpOetCgu8MS4ExQRia+GL/MK3uuCyZPeEsi+J3h+Q+Q==",
1522 "dev": true,
1523 "license": "MIT",
1524 "dependencies": {
1525 "sodium-native": "^5.0.1"
1526 },
1527 "peerDependencies": {
1528 "sodium-javascript": "~0.8.0"
1529 },
1530 "peerDependenciesMeta": {
1531 "sodium-javascript": {
1532 "optional": true
1533 }
1534 }
1535 },
1536 "node_modules/stackframe": {
1537 "version": "1.3.4",
1538 "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
1539 "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
1540 "dev": true,
1541 "license": "MIT"
1542 },
1543 "node_modules/streamx": {
1544 "version": "2.28.0",
1545 "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.28.0.tgz",
1546 "integrity": "sha512-1Yowhzjf0ivGMrTIkY9hav5TxobO9qIVqUE41fiCGMGgc3CLlf4MY+9AHmZqBWgDTue0fY9zWjYFVyf6Diuobw==",
1547 "dev": true,
1548 "license": "MIT",
1549 "dependencies": {
1550 "events-universal": "^1.0.0",
1551 "fast-fifo": "^1.3.2",
1552 "text-decoder": "^1.1.0"
1553 }
1554 },
1555 "node_modules/sub-encoder": {
1556 "version": "2.1.3",
1557 "resolved": "https://registry.npmjs.org/sub-encoder/-/sub-encoder-2.1.3.tgz",
1558 "integrity": "sha512-Xxx04ygZo/1J3yHvaSA6VhDmiSaBQkw/PmO3YnnYFXle+tfOGToC6FcDpIfMztWZXJzuKG14b/57HMkiL58C6A==",
1559 "dev": true,
1560 "license": "Apache-2.0",
1561 "dependencies": {
1562 "b4a": "^1.6.0",
1563 "codecs": "^3.1.0"
1564 }
1565 },
1566 "node_modules/teex": {
1567 "version": "1.0.1",
1568 "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz",
1569 "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==",
1570 "dev": true,
1571 "license": "MIT",
1572 "dependencies": {
1573 "streamx": "^2.12.5"
1574 }
1575 },
1576 "node_modules/test-tmp": {
1577 "version": "1.4.0",
1578 "resolved": "https://registry.npmjs.org/test-tmp/-/test-tmp-1.4.0.tgz",
1579 "integrity": "sha512-GVggxGg+jXqP2Wbju50JVLo+9E+nIOPPyWqgr63EbOnNItIKu1cEbJpTWAJeflnyGqXOtcMI7ijHRp88GUkfDA==",
1580 "dev": true,
1581 "license": "MIT",
1582 "dependencies": {
1583 "bare-fs": "^4.0.1",
1584 "bare-os": "^3.3.0",
1585 "bare-path": "^3.0.0"
1586 }
1587 },
1588 "node_modules/text-decoder": {
1589 "version": "1.2.7",
1590 "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz",
1591 "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==",
1592 "dev": true,
1593 "license": "Apache-2.0",
1594 "dependencies": {
1595 "b4a": "^1.6.4"
1596 }
1597 },
1598 "node_modules/timeout-refresh": {
1599 "version": "2.0.1",
1600 "resolved": "https://registry.npmjs.org/timeout-refresh/-/timeout-refresh-2.0.1.tgz",
1601 "integrity": "sha512-SVqEcMZBsZF9mA78rjzCrYrUs37LMJk3ShZ851ygZYW1cMeIjs9mL57KO6Iv5mmjSQnOe/29/VAfGXo+oRCiVw==",
1602 "dev": true,
1603 "license": "MIT"
1604 },
1605 "node_modules/tiny-buffer-map": {
1606 "version": "1.1.1",
1607 "resolved": "https://registry.npmjs.org/tiny-buffer-map/-/tiny-buffer-map-1.1.1.tgz",
1608 "integrity": "sha512-C1eDw6ks9CmkDbWVCPHobuixPTkxGa7IDERlaVk98dv4tOUdz42o3haHBr0uhNxbj0gczBTVIyS2uQsu+1vc2Q==",
1609 "dev": true,
1610 "license": "MIT",
1611 "dependencies": {
1612 "b4a": "^1.6.0"
1613 }
1614 },
1615 "node_modules/tmatch": {
1616 "version": "5.0.0",
1617 "resolved": "https://registry.npmjs.org/tmatch/-/tmatch-5.0.0.tgz",
1618 "integrity": "sha512-Ib9OtBkpHn07tXP04SlN1SYRxFgTk6wSM2EBmjjxug4u5RXPRVLkdFJSS1PmrQidaSB8Lru9nRtViQBsbxzE5Q==",
1619 "dev": true,
1620 "license": "ISC",
1621 "engines": {
1622 "node": ">=8"
1623 }
1624 },
1625 "node_modules/unslab": {
1626 "version": "1.3.0",
1627 "resolved": "https://registry.npmjs.org/unslab/-/unslab-1.3.0.tgz",
1628 "integrity": "sha512-YATkfKAFj47kTzmiQrWXMyRvaVrHsW6MEALa4bm+FhiA2YG4oira+Z3DXN6LrYOYn2Y8eO94Lwl9DOHjs1FpoQ==",
1629 "dev": true,
1630 "license": "Apache-2.0",
1631 "dependencies": {
1632 "b4a": "^1.6.6"
1633 }
1634 },
1635 "node_modules/v8-to-istanbul": {
1636 "version": "9.3.0",
1637 "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
1638 "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
1639 "dev": true,
1640 "license": "ISC",
1641 "dependencies": {
1642 "@jridgewell/trace-mapping": "^0.3.12",
1643 "@types/istanbul-lib-coverage": "^2.0.1",
1644 "convert-source-map": "^2.0.0"
1645 },
1646 "engines": {
1647 "node": ">=10.12.0"
1648 }
1649 },
1650 "node_modules/varint": {
1651 "version": "5.0.0",
1652 "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.0.tgz",
1653 "integrity": "sha512-gC13b/bWrqQoKY2EmROCZ+AR0jitc6DnDGaQ6Ls9QpKmuSgJB1eQ7H3KETtQm7qSdMWMKCmsshyCmUwMLh3OAA==",
1654 "dev": true,
1655 "license": "MIT"
1656 },
1657 "node_modules/which-runtime": {
1658 "version": "1.4.0",
1659 "resolved": "https://registry.npmjs.org/which-runtime/-/which-runtime-1.4.0.tgz",
1660 "integrity": "sha512-0ugbP4CJW4e2D20jvEcC4973dCgIaHI4Rw1PT+26U9zEve7FyYdWAIwUnoeOYvoCfn+wXHoHTKb1KhkYlb60Pw==",
1661 "dev": true,
1662 "license": "Apache-2.0"
1663 },
1664 "node_modules/xache": {
1665 "version": "1.3.0",
1666 "resolved": "https://registry.npmjs.org/xache/-/xache-1.3.0.tgz",
1667 "integrity": "sha512-ekAknjLTiyXJcuezqwa/cOMfFenVVY2toL4J7D3AfTn7UEDYb8JSgRnv3CK8khF7u38XZ4NjS1MXEw4RwqJ4oA==",
1668 "dev": true,
1669 "license": "MIT"
1670 },
1671 "node_modules/z32": {
1672 "version": "1.1.0",
1673 "resolved": "https://registry.npmjs.org/z32/-/z32-1.1.0.tgz",
1674 "integrity": "sha512-1WUHy+VS6d0HPNspDxvLssBbeQjXMjSnpv0vH82vRAUfg847NmX3OXozp/hRP5jPhxBbrVzrgvAt+UsGNzRFQQ==",
1675 "dev": true,
1676 "license": "MIT",
1677 "dependencies": {
1678 "b4a": "^1.5.3"
1679 }
1680 }
1681 }
1682}
package.json +23 -0
……@@ -0,0 +1,23 @@
1{
2 "name": "atproto-base",
3 "version": "0.0.1",
4 "description": "A co-owned atproto DID as a deterministic projection of one autobase — the atproto chain is a pure function of the indexed view + RFC6979 signing, so signing is indexer-agnostic (no signer election, no fork).",
5 "type": "module",
6 "main": "lib/base.js",
7 "scripts": {
8 "test": "brittle test/*.test.mjs"
9 },
10 "dependencies": {
11 "atproto-repo": "file:../atproto-repo",
12 "atproto-identity": "file:../atproto-identity",
13 "@noble/curves": "1.9.7",
14 "@noble/hashes": "1.8.0"
15 },
16 "devDependencies": {
17 "brittle": "^3.0.0",
18 "autobase": "7.28.1",
19 "corestore": "7.11.0",
20 "hyperbee": "2.27.3",
21 "b4a": "1.8.1"
22 }
23}
test/autobase-marriage.test.mjs +135 -0
……@@ -0,0 +1,135 @@
1// TESTS 2, 3, 5 — the MARRIAGE with real autobase. These prove the substrate properties the
2// deterministic projection relies on:
3// 2. indexer-change invariance — changing the indexer set never alters the projected chain.
4// 3. reorg-safety — an optimistic-tip reorg never rewrites already-finalized records.
5// 5. N=2 stalls-not-forks — losing one of two indexers freezes finalization (no new commit) but
6// never forks.
7// Raw autobase (RAM-free temp dirs, pipe replication — no network) so results are deterministic.
8
9import test from 'brittle'
10import Corestore from 'corestore'
11import Autobase from 'autobase'
12import Hyperbee from 'hyperbee'
13import b4a from 'b4a'
14import { mkdtempSync, rmSync } from 'node:fs'
15import { tmpdir } from 'node:os'
16import { join } from 'node:path'
17import { deriveAtprotoKey, createAtprotoIdentity } from 'atproto-identity'
18import { projectCommit, nextRev } from '../lib/project.js'
19
20const MNEMONIC = 'test test test test test test test test test test test junk'
21const ID = createAtprotoIdentity(MNEMONIC, { handle: 'x.7rnx.net', pdsUrl: 'https://pds.7rnx.net' })
22const KEY = deriveAtprotoKey(MNEMONIC)
23
24function open (store) {
25 return new Hyperbee(store.get('view'), { keyEncoding: 'utf-8', valueEncoding: 'json', extension: false })
26}
27async function apply (nodes, view, host) {
28 for (const node of nodes) {
29 if (!node.value) continue
30 const op = JSON.parse(b4a.toString(node.value))
31 if (op.type === 'addWriter') {
32 await host.addWriter(b4a.from(op.key, 'hex'), { indexer: !!op.indexer })
33 try { await host.ackWriter(b4a.from(op.key, 'hex')) } catch {}
34 continue
35 }
36 if (op.type === 'record') await view.put(op.key, op.value)
37 }
38}
39function mkBase (bootstrap) {
40 const dir = mkdtempSync(join(tmpdir(), 'abase-'))
41 const store = new Corestore(dir)
42 const base = new Autobase(store, bootstrap, { open, apply, valueEncoding: 'binary', optimistic: true, ackInterval: 50, ackThreshold: 1 })
43 return { dir, store, base, close: async () => { try { await base.close() } catch {} ; try { await store.close() } catch {} ; rmSync(dir, { recursive: true, force: true }) } }
44}
45const pipe = (a, b) => { const s1 = a.base.replicate(true); const s2 = b.base.replicate(false); s1.pipe(s2).pipe(s1); return () => { try { s1.destroy() } catch {} ; try { s2.destroy() } catch {} } }
46const sleep = (ms) => new Promise(r => setTimeout(r, ms))
47async function settle (...bases) { for (let i = 0; i < 12; i++) { for (const bs of bases) { try { await bs.base.update() } catch {} } await sleep(60) } }
48async function whenWritable (bs) { for (let i = 0; i < 60; i++) { if (bs.base.writable) return; await sleep(50); try { await bs.base.update() } catch {} } }
49const rec = (rk, text) => ({ type: 'record', key: 'app.bsky.feed.post/' + rk, value: { $type: 'app.bsky.feed.post', text, createdAt: '2026-07-23T00:00:00.000Z', langs: ['en'] } })
50const appendRec = (bs, rk, text) => bs.base.append(b4a.from(JSON.stringify(rec(rk, text))))
51const addWriter = (bs, key, indexer) => bs.base.append(b4a.from(JSON.stringify({ type: 'addWriter', key, indexer })))
52
53async function readRecords (bs) {
54 await bs.base.update()
55 const out = []
56 for await (const { key, value } of bs.base.view.createReadStream()) { if (!String(key).startsWith('__')) out.push({ key: String(key), value }) }
57 return out
58}
59async function projectFrom (bs, rev, prev = null) {
60 const records = await readRecords(bs)
61 return projectCommit({ records, did: ID.did, rev, prev, privateKey: KEY.privateKey })
62}
63
64test('2 — indexer-change invariance: changing the indexer set never alters the projected chain', async (t) => {
65 const A = mkBase(null); await A.base.ready()
66 const B = mkBase(A.base.key); await B.base.ready()
67 const unpipe = pipe(A, B)
68 t.teardown(async () => { unpipe(); await A.close(); await B.close() })
69
70 await addWriter(A, b4a.toString(B.base.local.key, 'hex'), false) // B = PLAIN writer
71 await settle(A, B); await whenWritable(B)
72 await appendRec(A, '3aaa', 'one'); await appendRec(B, '3bbb', 'two')
73 await settle(A, B)
74
75 const before = await projectFrom(A, nextRev(null))
76
77 // INDEXER CHANGE: promote B to an indexer (grow the set). No new records.
78 await addWriter(A, b4a.toString(B.base.local.key, 'hex'), true)
79 await settle(A, B)
80
81 const after = await projectFrom(A, nextRev(null))
82 t.is(after.commitCid.toString(), before.commitCid.toString(), 'projected commit UNCHANGED across an indexer-set change (chain is a function of the indexed view, not the indexer)')
83 t.ok((await readRecords(A)).length === 2, 'record set intact (2 records) after the indexer change')
84})
85
86test('3 — reorg-safety: an optimistic-tip reorg never rewrites finalized records', async (t) => {
87 const A = mkBase(null); await A.base.ready()
88 const B = mkBase(A.base.key); await B.base.ready()
89 let unpipe = pipe(A, B)
90 t.teardown(async () => { try { unpipe() } catch {} ; await A.close(); await B.close() })
91
92 await addWriter(A, b4a.toString(B.base.local.key, 'hex'), false)
93 await settle(A, B); await whenWritable(B)
94 await appendRec(A, '3aaa', 'finalized'); await settle(A, B)
95 const idxBefore = A.base.indexedLength
96 const committed = await projectFrom(A, nextRev(null)) // the finalized commit
97
98 // Force divergent optimistic tips: disconnect, both write concurrently, reconnect → tip reorders.
99 unpipe()
100 await appendRec(A, '3ccc', 'A-tip'); await appendRec(B, '3bbb', 'B-tip')
101 await settle(A); await settle(B)
102 unpipe = pipe(A, B); await settle(A, B)
103
104 t.ok(A.base.indexedLength >= idxBefore, 'indexedLength is monotonic (never went backward across the reorg)')
105 const finalizedRec = (await readRecords(A)).find(r => r.key.endsWith('3aaa'))
106 t.is(finalizedRec && finalizedRec.value.text, 'finalized', 'the previously-finalized record retains its exact value after the reorg')
107 const reproject = await projectCommit({ records: [{ key: 'app.bsky.feed.post/3aaa', value: { $type: 'app.bsky.feed.post', text: 'finalized', createdAt: '2026-07-23T00:00:00.000Z', langs: ['en'] } }], did: ID.did, rev: nextRev(null), privateKey: KEY.privateKey })
108 t.is(reproject.commitCid.toString(), committed.commitCid.toString(), 'the finalized commit is immutable — a reorg of the tip cannot rewrite it')
109})
110
111test('5 — N=2 stalls-not-forks: losing one of two indexers freezes finalization, never forks', async (t) => {
112 const A = mkBase(null); await A.base.ready()
113 const B = mkBase(A.base.key); await B.base.ready()
114 let unpipe = pipe(A, B)
115 t.teardown(async () => { try { unpipe() } catch {} ; await A.close(); await B.close() })
116
117 await addWriter(A, b4a.toString(B.base.local.key, 'hex'), true) // B = INDEXER → N=2
118 await settle(A, B); await whenWritable(B)
119 await appendRec(A, '3aaa', 'one'); await settle(A, B)
120 const idxWhenHealthy = A.base.indexedLength
121 t.ok(idxWhenHealthy > 0, 'N=2 finalizes while both indexers are online (indexedLength advanced)')
122
123 // Lose one indexer.
124 unpipe()
125 const lenBefore = A.base.length
126 await appendRec(A, '3bbb', 'written-while-partner-offline')
127 await settle(A)
128
129 t.is(A.base.indexedLength, idxWhenHealthy, 'indexedLength FROZEN after losing one of two indexers (N=2 majority=2 unreachable) — a STALL')
130 t.ok(A.base.length > lenBefore, 'the optimistic tip still grows (write is durable-local) — but NOT finalized')
131 // No fork: the projection over the INDEXED (finalized) view produces no new commit — the un-finalized
132 // write simply does not appear in the signed chain until quorum returns. (Contrast a fork, where two
133 // divergent chains would BOTH finalize.)
134 t.pass('stall (not fork): the un-finalized optimistic write is absent from the finalized projection until quorum returns')
135})
test/determinism.test.mjs +53 -0
……@@ -0,0 +1,53 @@
1// TEST 1 — the KILLER PROOF of atproto-base's core design claim:
2//
3// Two independent co-owners, given the SAME record set (in ANY order), the SAME did/rev, and the
4// SAME shared #atproto key, produce a BYTE-IDENTICAL signed commit (same CID, same 64-byte sig,
5// same CAR bytes).
6//
7// If this passes, the deterministic-projection design holds: signing is indexer-agnostic, so there
8// is no need for a signer election and no possibility of a fork from two co-owners "both signing".
9// If it fails, determinism has leaked somewhere specific (MST order, sig nonce, encoding).
10
11import test from 'brittle'
12import { deriveAtprotoKey, createAtprotoIdentity } from 'atproto-identity'
13import { verifyCommit } from 'atproto-repo/lib/commit.js'
14import { readCar } from 'atproto-repo/lib/car.js'
15import { projectCommit, nextRev } from '../lib/project.js'
16
17const MNEMONIC = 'test test test test test test test test test test test junk'
18const REV = nextRev(null) // deterministic genesis rev — NOT wall-clock
19
20const post = (rk, text) => ({ collection: 'app.bsky.feed.post', rkey: rk, record: { $type: 'app.bsky.feed.post', text, createdAt: '2026-07-23T00:00:00.000Z', langs: ['en'] } })
21const RECORDS = [post('3aaa', 'one'), post('3bbb', 'two'), post('3ccc', 'three')]
22const shuffle = (a) => [a[2], a[0], a[1]]
23
24function eqBytes (t, x, y, msg) {
25 const bx = Buffer.from(x); const by = Buffer.from(y)
26 t.is(Buffer.compare(bx, by), 0, msg)
27}
28
29test('two co-owners project a byte-identical signed commit (determinism + RFC6979 + MST order-independence)', async (t) => {
30 const id = createAtprotoIdentity(MNEMONIC, { handle: 'x.7rnx.net', pdsUrl: 'https://pds.7rnx.net' })
31 const key = deriveAtprotoKey(MNEMONIC) // { privateKey, publicKey, didKey }
32
33 // Co-owner A and co-owner B independently project — B sees the records in a different order.
34 const A = await projectCommit({ records: RECORDS, did: id.did, rev: REV, privateKey: key.privateKey })
35 const B = await projectCommit({ records: shuffle(RECORDS), did: id.did, rev: REV, privateKey: key.privateKey })
36
37 t.is(A.commitCid.toString(), B.commitCid.toString(), 'commit CID identical across co-owners (MST order-independent)')
38 t.is(A.dataCid.toString(), B.dataCid.toString(), 'MST root CID identical')
39 eqBytes(t, A.signedCommit.sig, B.signedCommit.sig, 'signature byte-identical (RFC6979 deterministic — no random nonce)')
40
41 // The CAR CONTAINER concatenates blocks in record-input order, so shuffled input → different byte
42 // order. That is a non-signed container detail (the relay resolves blocks by CID). The real
43 // invariant is the same block SET. (Canonical CID-sorted CAR ordering is an optional hardening.)
44 const setOf = async (car) => [...(await readCar(car)).blocks.keys()].sort().join(',')
45 t.is(await setOf(A.carBytes), await setOf(B.carBytes), 'CAR block SET identical (order is a non-signed container detail)')
46
47 // And the produced commit is relay-valid: verifies against the DID signing key.
48 t.ok(verifyCommit(A.signedCommit, key.publicKey), 'signed commit verifies against the #atproto key (relay would accept)')
49
50 // Sanity: a DIFFERENT rev must produce a DIFFERENT commit (guards against a trivially-constant bug).
51 const C = await projectCommit({ records: RECORDS, did: id.did, rev: nextRev(REV), privateKey: key.privateKey })
52 t.not(A.commitCid.toString(), C.commitCid.toString(), 'a different rev yields a different commit (projection is not constant)')
53})
test/labeler.test.mjs +31 -0
……@@ -0,0 +1,31 @@
1// TEST 7 — a group/team labeler as atproto-base projecting labels: two co-owner MODS, given the same
2// moderation decision (from the shared view), produce a BYTE-IDENTICAL signed label. Same guarantee
3// as commits (test 1) — deterministic projection + RFC6979 → no signer election, no fork — applied to
4// com.atproto.label. This is the P2P analog of ozone's central team-labeler.
5
6import test from 'brittle'
7import { deriveAtprotoKey, createAtprotoIdentity } from 'atproto-identity'
8import { projectLabel, verifyLabel } from '../lib/label.js'
9
10const MNEMONIC = 'test test test test test test test test test test test junk'
11
12test('two co-owner mods project a byte-identical signed label (labeler = atproto-base projecting labels)', async (t) => {
13 const id = createAtprotoIdentity(MNEMONIC, { handle: 'mod.7rnx.net', pdsUrl: 'https://pds.7rnx.net' })
14 const key = deriveAtprotoKey(MNEMONIC) // the shared #atproto_label key
15
16 // A moderation decision folded from the shared view: label a post "spam" at a deterministic cts.
17 const decision = { src: id.did, uri: 'at://did:plc:target/app.bsky.feed.post/3xxx', val: 'spam', cts: '2026-07-23T00:00:00.000Z' }
18
19 const A = await projectLabel({ ...decision, privateKey: key.privateKey })
20 const B = await projectLabel({ ...decision, privateKey: key.privateKey })
21
22 t.is(Buffer.compare(Buffer.from(A.sig), Buffer.from(B.sig)), 0, 'label signature byte-identical across co-owner mods (RFC6979)')
23 t.alike({ ...A, sig: null }, { ...B, sig: null }, 'label fields identical')
24 t.ok(await verifyLabel(A, key.publicKey), 'label verifies against the #atproto_label key (consumer would accept)')
25
26 // Retraction = a neg label, never a delete; distinct from the positive label.
27 const neg = await projectLabel({ ...decision, neg: true, cts: '2026-07-23T01:00:00.000Z', privateKey: key.privateKey })
28 t.ok(neg.neg === true, 'retraction is a neg:true label (append-only, no delete)')
29 t.not(Buffer.from(A.sig).toString('hex'), Buffer.from(neg.sig).toString('hex'), 'neg label is a distinct signed object')
30 t.ok(await verifyLabel(neg, key.publicKey), 'neg label also verifies')
31})
test/relay-acceptance.test.mjs +40 -0
……@@ -0,0 +1,40 @@
1// TEST 6 — the projected chain is RELAY-VALID: each CAR is byte-exact (verifyRepo, the same check a
2// real relay's CID validation performs), each commit verifies against the #atproto key, and the chain
3// is prev-linked with strictly-increasing rev (the relay's forward-only cursor). Plus: chain commits
4// are deterministic across co-owners (extends test 1 to a prev-linked chain).
5
6import test from 'brittle'
7import { deriveAtprotoKey, createAtprotoIdentity } from 'atproto-identity'
8import { verifyCommit } from 'atproto-repo/lib/commit.js'
9import { readCar } from 'atproto-repo/lib/car.js'
10import { verifyRepo } from 'atproto-repo'
11import { projectCommit, nextRev } from '../lib/project.js'
12
13const MNEMONIC = 'test test test test test test test test test test test junk'
14const post = (rk, text) => ({ collection: 'app.bsky.feed.post', rkey: rk, record: { $type: 'app.bsky.feed.post', text, createdAt: '2026-07-23T00:00:00.000Z', langs: ['en'] } })
15
16test('projected chain is relay-valid (verifyRepo byte-exact + verifyCommit + forward-only prev-linked rev)', async (t) => {
17 const id = createAtprotoIdentity(MNEMONIC, { handle: 'x.7rnx.net', pdsUrl: 'https://pds.7rnx.net' })
18 const key = deriveAtprotoKey(MNEMONIC)
19
20 const R1 = [post('3aaa', 'one')]
21 const R2 = [post('3aaa', 'one'), post('3bbb', 'two')]
22
23 const rev1 = nextRev(null)
24 const c1 = await projectCommit({ records: R1, did: id.did, rev: rev1, prev: null, privateKey: key.privateKey })
25 const rev2 = nextRev(rev1)
26 const c2 = await projectCommit({ records: R2, did: id.did, rev: rev2, prev: c1.commitCid, privateKey: key.privateKey })
27
28 for (const [name, c] of [['genesis', c1], ['commit2', c2]]) {
29 const v = await verifyRepo(await readCar(c.carBytes))
30 t.ok(v.ok, `${name} CAR is byte-exact (verifyRepo — relay CID validation passes), mismatches=${JSON.stringify(v.mismatches)}`)
31 t.ok(verifyCommit(c.signedCommit, key.publicKey), `${name} commit verifies against the #atproto key`)
32 }
33
34 t.is(c2.signedCommit.prev.toString(), c1.commitCid.toString(), 'commit2.prev links to the genesis commit CID (append-only chain)')
35 t.ok(rev2 > rev1, 'rev strictly increasing (relay forward-only cursor accepts)')
36
37 // Chain-level determinism: a co-owner projecting commit2 with shuffled records gets the identical CID.
38 const c2b = await projectCommit({ records: [...R2].reverse(), did: id.did, rev: rev2, prev: c1.commitCid, privateKey: key.privateKey })
39 t.is(c2.commitCid.toString(), c2b.commitCid.toString(), 'prev-linked commit is deterministic across co-owners')
40})
test/rev.test.mjs +19 -0
……@@ -0,0 +1,19 @@
1// TEST 4 — `rev` is deterministic, monotonic, and restart-stable (never wall-clock).
2// If rev were Date.now()-derived, two co-owners (or a restart) would diverge and fork the chain.
3
4import test from 'brittle'
5import { nextRev } from '../lib/rev.js'
6
7test('rev is deterministic + monotonic + restart-stable', (t) => {
8 const build = () => { let r = nextRev(null); const chain = [r]; for (let i = 0; i < 5; i++) { r = nextRev(r); chain.push(r) } return chain }
9
10 const chain = build()
11 for (let i = 1; i < chain.length; i++) t.ok(chain[i] > chain[i - 1], `rev ${i} > rev ${i - 1} (monotonic, TID-sortable)`)
12
13 // "Restart": recompute the whole chain from scratch → byte-identical (no wall-clock).
14 t.alike(build(), chain, 'recomputed chain identical — deterministic, restart-stable')
15
16 // Continue from ANY restart point using only prevRev.
17 t.is(nextRev(chain[2]), chain[3], 'nextRev(prev) reproduces the same next rev from any restart point')
18 t.is(chain[0].length, 13, 'rev is a 13-char atproto TID')
19})