@cero-base/cero 1.0.1 → 1.1.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/README.md +1 -0
- package/package.json +2 -2
- package/src/build/CLAUDE.md +3 -0
- package/src/build/builtins.js +2 -1
- package/src/build/schemas.js +3 -0
- package/src/handle/CLAUDE.md +3 -0
- package/src/index.js +18 -4
- package/types/build/builtins.d.ts +4 -0
- package/types/build/schemas.d.ts +3 -0
- package/types/index.d.ts +7 -2
package/README.md
CHANGED
|
@@ -49,6 +49,7 @@ Ships with TypeScript declarations (`.d.ts`) generated from JSDoc.
|
|
|
49
49
|
| Opt | Meaning |
|
|
50
50
|
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
51
51
|
| `bootstrap` | Hyperswarm bootstrap nodes. |
|
|
52
|
+
| `channel` | Optional network-isolation label. Peers connect only to peers on the **same** channel (it salts every swarm topic); omit it for the global network. A storage remembers its channel and refuses to reopen under a different one. Any string works. |
|
|
52
53
|
| `name` / `isMobile` | Stamped on the device's `add-writer` event. |
|
|
53
54
|
| `seed` / `phrase` | Restore from explicit 16-/32-byte entropy or a BIP-39 mnemonic. Without either, a stored identity is loaded if present, else a fresh one is generated. |
|
|
54
55
|
| `key` | Open against an existing bee key (multi-device flow). |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cero-base/cero",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.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,
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"test": "ls test/*.test.js | xargs -P1 -n1 brittle-node"
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
|
-
"@cero-base/core": "^1.
|
|
86
|
+
"@cero-base/core": "^1.1.1",
|
|
87
87
|
"b4a": "^1.8.1",
|
|
88
88
|
"bare-abort-controller": "^1.1.2",
|
|
89
89
|
"bare-crypto": "^1.15.3",
|
package/src/build/builtins.js
CHANGED
|
@@ -19,7 +19,8 @@ export const refs = {
|
|
|
19
19
|
local: {
|
|
20
20
|
master: { type: 'master', kind: 'single' },
|
|
21
21
|
keypair: { type: 'keypair', kind: 'single' },
|
|
22
|
-
'handle-keypairs': { type: 'handle-keypair' }
|
|
22
|
+
'handle-keypairs': { type: 'handle-keypair' },
|
|
23
|
+
environment: { type: 'environment', kind: 'single' }
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
|
package/src/build/schemas.js
CHANGED
package/src/index.js
CHANGED
|
@@ -59,12 +59,13 @@ export { t, schema } from './lib/spec.js'
|
|
|
59
59
|
* @property {string | null} [name] Friendly device name persisted on the identity claim.
|
|
60
60
|
* @property {boolean} [isMobile] Marks this device as mobile.
|
|
61
61
|
* @property {Array<{ host: string, port: number }>} [bootstrap] Custom DHT bootstrap nodes.
|
|
62
|
+
* @property {string} [channel] Optional network-isolation label; only same-channel peers connect.
|
|
62
63
|
* @property {Uint8Array} [key] Pre-existing database key (skip bootstrap).
|
|
63
64
|
* @property {Uint8Array} [encryptionKey] Pre-existing encryption key.
|
|
64
65
|
* @property {Record<string, Function>} [routes] Custom RPC routes for the database dispatcher.
|
|
65
66
|
* @property {(err: any) => void} [onerror] Background-task error handler.
|
|
66
67
|
* @property {boolean} [recovery] Recovery flow — wipe local state and re-claim a writer slot.
|
|
67
|
-
* @property {number} [recoveryTimeout] Max wait for writer capability during recovery.
|
|
68
|
+
* @property {number} [recoveryTimeout] Max wait for peer data + writer capability during recovery.
|
|
68
69
|
*/
|
|
69
70
|
|
|
70
71
|
/**
|
|
@@ -103,7 +104,16 @@ export async function cero(dir, spec, opts = {}) {
|
|
|
103
104
|
const identity = await resolveIdentity(opts, local)
|
|
104
105
|
const writer = local ? (await local.store.get('keypair')).data : null
|
|
105
106
|
|
|
106
|
-
|
|
107
|
+
// Channel stamp: a storage remembers its channel; reopening it under a different channel is a
|
|
108
|
+
// misconfiguration that could leak data across networks, so reject it. Only when a channel is
|
|
109
|
+
// set (no channel = global, no stamp, unchanged).
|
|
110
|
+
if (local && opts.channel) {
|
|
111
|
+
const stored = (await local.store.get('environment')).data?.channel
|
|
112
|
+
if (stored == null) await local.store.set('environment', { channel: opts.channel })
|
|
113
|
+
else if (stored !== opts.channel) throw CeroError.CHANNEL_MISMATCH()
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
network = new Network({ bootstrap: opts.bootstrap, channel: opts.channel })
|
|
107
117
|
await network.ready()
|
|
108
118
|
discovery = network.join(identity.topic)
|
|
109
119
|
await Promise.race([discovery.flush(), new Promise((r) => setTimeout(r, FLUSH))])
|
|
@@ -130,7 +140,8 @@ export async function cero(dir, spec, opts = {}) {
|
|
|
130
140
|
const result = await me.bootstrap({
|
|
131
141
|
name: opts.name || null,
|
|
132
142
|
isMobile: opts.isMobile === true,
|
|
133
|
-
recovering: opts.recovery === true
|
|
143
|
+
recovering: opts.recovery === true,
|
|
144
|
+
...(opts.recoveryTimeout ? { timeout: opts.recoveryTimeout } : {})
|
|
134
145
|
})
|
|
135
146
|
if (local && result?.writer) {
|
|
136
147
|
await local.store.set('keypair', {
|
|
@@ -192,7 +203,9 @@ export async function restore(me, phrase) {
|
|
|
192
203
|
if (current.id === me.identity.id) return me
|
|
193
204
|
|
|
194
205
|
const { _dir: dir, spec, _opts: opts } = me
|
|
195
|
-
|
|
206
|
+
// channel must carry over — without it the recovered instance rejoins the
|
|
207
|
+
// global identity topic and never meets its channeled peers (recovery timeout).
|
|
208
|
+
const { name, bootstrap, isMobile, onerror, routes, recoveryTimeout, channel } = opts
|
|
196
209
|
|
|
197
210
|
await me.close()
|
|
198
211
|
await fs.promises.rm(`${dir}/main`, { recursive: true, force: true })
|
|
@@ -204,6 +217,7 @@ export async function restore(me, phrase) {
|
|
|
204
217
|
onerror,
|
|
205
218
|
routes,
|
|
206
219
|
recoveryTimeout,
|
|
220
|
+
channel,
|
|
207
221
|
phrase,
|
|
208
222
|
recovery: true
|
|
209
223
|
})
|
package/types/build/schemas.d.ts
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -10,12 +10,13 @@
|
|
|
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 {string} [channel] Optional network-isolation label; only same-channel peers connect.
|
|
13
14
|
* @property {Uint8Array} [key] Pre-existing database key (skip bootstrap).
|
|
14
15
|
* @property {Uint8Array} [encryptionKey] Pre-existing encryption key.
|
|
15
16
|
* @property {Record<string, Function>} [routes] Custom RPC routes for the database dispatcher.
|
|
16
17
|
* @property {(err: any) => void} [onerror] Background-task error handler.
|
|
17
18
|
* @property {boolean} [recovery] Recovery flow — wipe local state and re-claim a writer slot.
|
|
18
|
-
* @property {number} [recoveryTimeout] Max wait for writer capability during recovery.
|
|
19
|
+
* @property {number} [recoveryTimeout] Max wait for peer data + writer capability during recovery.
|
|
19
20
|
*/
|
|
20
21
|
/**
|
|
21
22
|
* Open (or create) a cero handle at `dir`. Sets up storage, network and
|
|
@@ -92,6 +93,10 @@ export type CeroOpts = {
|
|
|
92
93
|
host: string;
|
|
93
94
|
port: number;
|
|
94
95
|
}>;
|
|
96
|
+
/**
|
|
97
|
+
* Optional network-isolation label; only same-channel peers connect.
|
|
98
|
+
*/
|
|
99
|
+
channel?: string;
|
|
95
100
|
/**
|
|
96
101
|
* Pre-existing database key (skip bootstrap).
|
|
97
102
|
*/
|
|
@@ -113,7 +118,7 @@ export type CeroOpts = {
|
|
|
113
118
|
*/
|
|
114
119
|
recovery?: boolean;
|
|
115
120
|
/**
|
|
116
|
-
* Max wait for writer capability during recovery.
|
|
121
|
+
* Max wait for peer data + writer capability during recovery.
|
|
117
122
|
*/
|
|
118
123
|
recoveryTimeout?: number;
|
|
119
124
|
};
|