@cero-base/cero 1.14.1 → 1.15.1
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/package.json +3 -3
- package/src/handle/index.js +10 -7
- package/src/index.js +17 -0
- package/types/index.d.ts +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cero-base/cero",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.1",
|
|
4
4
|
"description": "The ideal p2p API — everything is a handle, handles contain refs, refs contain rows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -95,13 +95,13 @@
|
|
|
95
95
|
"test:node": "ls test/*.test.js | xargs -P1 -n1 brittle-node"
|
|
96
96
|
},
|
|
97
97
|
"dependencies": {
|
|
98
|
-
"@cero-base/core": "^1.
|
|
98
|
+
"@cero-base/core": "^1.15.1",
|
|
99
99
|
"b4a": "^1.8.1",
|
|
100
100
|
"bare-abort-controller": "^1.1.2",
|
|
101
101
|
"bare-crypto": "^1.15.3",
|
|
102
102
|
"bare-fs": "^4.8.1",
|
|
103
103
|
"bare-path": "^3.1.1",
|
|
104
|
-
"ble-swarm": "^2.
|
|
104
|
+
"ble-swarm": "^2.3.0",
|
|
105
105
|
"compact-encoding": "^3.3.2",
|
|
106
106
|
"corestore": "^7.12.2",
|
|
107
107
|
"hrpc": "^4.3.1",
|
package/src/handle/index.js
CHANGED
|
@@ -732,12 +732,14 @@ export class Handle extends ReadyResource {
|
|
|
732
732
|
async _pair(invite, type, { routes, timeout } = {}, target = null) {
|
|
733
733
|
const deadline = timeout || TIMEOUT
|
|
734
734
|
|
|
735
|
-
// Idempotent: if the invite targets a handle we already have AND
|
|
736
|
-
//
|
|
737
|
-
// waiting on a peer to confirm.
|
|
738
|
-
//
|
|
739
|
-
//
|
|
740
|
-
// re-admission path, so fall through to a real pairing
|
|
735
|
+
// Idempotent: if the invite targets a handle we already have AND our
|
|
736
|
+
// stored writer is still admitted, return it — without pairing, so
|
|
737
|
+
// there's no waiting on a peer to confirm. A removed writer's core is
|
|
738
|
+
// frozen: the old session can never become writable again, and reusing
|
|
739
|
+
// its keypair would only get it re-removed. Holding a fresh invite is
|
|
740
|
+
// exactly the re-admission path, so fall through to a real pairing —
|
|
741
|
+
// which mints a fresh keypair the host admits. Our member row can outlive
|
|
742
|
+
// our writer (one revoked device), so the device row is the real test.
|
|
741
743
|
if (target) {
|
|
742
744
|
const { data: joined } = await this.store.get('handles')
|
|
743
745
|
const existing = joined.find(
|
|
@@ -746,7 +748,8 @@ export class Handle extends ReadyResource {
|
|
|
746
748
|
if (existing) {
|
|
747
749
|
const known = await this._load(type, existing.id)
|
|
748
750
|
const { data: me } = await known.store.get('members', this.identity.id)
|
|
749
|
-
|
|
751
|
+
const { data: device } = await known.store.get('devices', toId(known.store.writerKey))
|
|
752
|
+
if (me && device) return known
|
|
750
753
|
await known.close().catch(safetyCatch)
|
|
751
754
|
}
|
|
752
755
|
}
|
package/src/index.js
CHANGED
|
@@ -64,6 +64,7 @@ export { t, schema } from './lib/spec.js'
|
|
|
64
64
|
* @property {string | null} [name] Friendly device name persisted on the identity claim.
|
|
65
65
|
* @property {boolean} [isMobile] Marks this device as mobile.
|
|
66
66
|
* @property {Array<{ host: string, port: number }>} [bootstrap] Custom DHT bootstrap nodes.
|
|
67
|
+
* @property {number[]} [backoffs] Swarm reconnect backoff tiers in ms (testing/tuning).
|
|
67
68
|
* @property {string} [channel] Optional network-isolation label; only same-channel peers connect.
|
|
68
69
|
* @property {Array<string | Uint8Array>} [mirrors] Blind-peer public keys. Rooms and files are mirrored through them so peers sync even when never online at the same time. Mirrors hold only encrypted blocks — they never read your data.
|
|
69
70
|
* @property {Uint8Array} [key] Pre-existing database key (skip bootstrap).
|
|
@@ -127,6 +128,7 @@ export async function cero(dir, spec, opts = {}) {
|
|
|
127
128
|
|
|
128
129
|
network = new Network({
|
|
129
130
|
bootstrap: opts.bootstrap,
|
|
131
|
+
backoffs: opts.backoffs,
|
|
130
132
|
channel: opts.channel,
|
|
131
133
|
store,
|
|
132
134
|
mirrors: opts.mirrors
|
|
@@ -155,6 +157,21 @@ export async function cero(dir, spec, opts = {}) {
|
|
|
155
157
|
})
|
|
156
158
|
await me.ready()
|
|
157
159
|
|
|
160
|
+
// a supplied or stored identity may already have history elsewhere —
|
|
161
|
+
// authoring genesis twice forks the seed-derived writer core (a writable
|
|
162
|
+
// core has one author, ever). Give discovery a moment; any replicated
|
|
163
|
+
// history means the caller wanted { recovery: true }. Offline reuse is
|
|
164
|
+
// undetectable — this catches the reachable-peer case loudly.
|
|
165
|
+
if (!writer && !opts.key && !opts.recovery && !fresh) {
|
|
166
|
+
const until = Date.now() + 1500
|
|
167
|
+
while (Date.now() < until) {
|
|
168
|
+
if (network.connections.size > 0) await me.store.bee.update().catch(safetyCatch)
|
|
169
|
+
if (me.store.length > 0 || me.store.bee.local.length > 0) {
|
|
170
|
+
throw CeroError.CONFLICT('identity already has history — open with { recovery: true }')
|
|
171
|
+
}
|
|
172
|
+
await new Promise((r) => setTimeout(r, 100))
|
|
173
|
+
}
|
|
174
|
+
}
|
|
158
175
|
if (!writer && me.store.length === 0 && (!opts.key || opts.recovery)) {
|
|
159
176
|
const result = await me.bootstrap({
|
|
160
177
|
name: opts.name || null,
|
package/types/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* @property {string | null} [name] Friendly device name persisted on the identity claim.
|
|
11
11
|
* @property {boolean} [isMobile] Marks this device as mobile.
|
|
12
12
|
* @property {Array<{ host: string, port: number }>} [bootstrap] Custom DHT bootstrap nodes.
|
|
13
|
+
* @property {number[]} [backoffs] Swarm reconnect backoff tiers in ms (testing/tuning).
|
|
13
14
|
* @property {string} [channel] Optional network-isolation label; only same-channel peers connect.
|
|
14
15
|
* @property {Array<string | Uint8Array>} [mirrors] Blind-peer public keys. Rooms and files are mirrored through them so peers sync even when never online at the same time. Mirrors hold only encrypted blocks — they never read your data.
|
|
15
16
|
* @property {Uint8Array} [key] Pre-existing database key (skip bootstrap).
|
|
@@ -99,6 +100,10 @@ export type CeroOpts = {
|
|
|
99
100
|
host: string;
|
|
100
101
|
port: number;
|
|
101
102
|
}>;
|
|
103
|
+
/**
|
|
104
|
+
* Swarm reconnect backoff tiers in ms (testing/tuning).
|
|
105
|
+
*/
|
|
106
|
+
backoffs?: number[];
|
|
102
107
|
/**
|
|
103
108
|
* Optional network-isolation label; only same-channel peers connect.
|
|
104
109
|
*/
|