@cero-base/cero 0.8.1 → 0.8.3
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 +7 -2
- package/src/handle/index.js +25 -3
- package/src/index.js +8 -3
- package/types/handle/index.d.ts +14 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cero-base/cero",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"description": "The ideal p2p API — everything is a handle, handles contain refs, refs contain rows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -64,6 +64,10 @@
|
|
|
64
64
|
"crypto": {
|
|
65
65
|
"bare": "bare-crypto",
|
|
66
66
|
"default": "crypto"
|
|
67
|
+
},
|
|
68
|
+
"abort-controller": {
|
|
69
|
+
"bare": "bare-abort-controller",
|
|
70
|
+
"default": "bare-abort-controller"
|
|
67
71
|
}
|
|
68
72
|
},
|
|
69
73
|
"scripts": {
|
|
@@ -74,8 +78,9 @@
|
|
|
74
78
|
"test": "ls test/*.test.js | xargs -P1 -n1 brittle-node"
|
|
75
79
|
},
|
|
76
80
|
"dependencies": {
|
|
77
|
-
"@cero-base/core": "^0.8.
|
|
81
|
+
"@cero-base/core": "^0.8.3",
|
|
78
82
|
"b4a": "^1.8.1",
|
|
83
|
+
"bare-abort-controller": "^1.1.2",
|
|
79
84
|
"bare-crypto": "^1.13.7",
|
|
80
85
|
"bare-fs": "^4.7.1",
|
|
81
86
|
"bare-path": "^3.0.0",
|
package/src/handle/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import AbortController from 'abort-controller'
|
|
1
2
|
import b4a from 'b4a'
|
|
2
3
|
import Hypercore from 'hypercore'
|
|
3
4
|
import { discoveryKey } from 'hypercore-crypto'
|
|
@@ -110,6 +111,7 @@ export class Handle extends ReadyResource {
|
|
|
110
111
|
this._opts = opts.opts || {}
|
|
111
112
|
this._onerror = this._opts.onerror || safetyCatch
|
|
112
113
|
this.children = parent ? null : new Set()
|
|
114
|
+
this._loading = parent ? null : new Map()
|
|
113
115
|
this._owned = new Set()
|
|
114
116
|
|
|
115
117
|
this.store = new Database({
|
|
@@ -458,9 +460,9 @@ export class Handle extends ReadyResource {
|
|
|
458
460
|
}
|
|
459
461
|
|
|
460
462
|
/**
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
*
|
|
463
|
+
* Get an open child by id, or re-open it. Concurrent calls for the same id
|
|
464
|
+
* share one in-flight load, so the child is built — and `handle` emitted —
|
|
465
|
+
* exactly once.
|
|
464
466
|
*
|
|
465
467
|
* @param {string} type
|
|
466
468
|
* @param {string} id
|
|
@@ -468,6 +470,26 @@ export class Handle extends ReadyResource {
|
|
|
468
470
|
*/
|
|
469
471
|
async _load(type, id) {
|
|
470
472
|
for (const c of this.children) if (c.id === id) return c
|
|
473
|
+
const existing = this._loading.get(id)
|
|
474
|
+
if (existing) return existing
|
|
475
|
+
const loading = this._reopen(type, id)
|
|
476
|
+
this._loading.set(id, loading)
|
|
477
|
+
try {
|
|
478
|
+
return await loading
|
|
479
|
+
} finally {
|
|
480
|
+
this._loading.delete(id)
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Reconstruct a child handle by id. Reuses the stored writer keypair if
|
|
486
|
+
* available; otherwise generates a fresh one and claims writer capability.
|
|
487
|
+
*
|
|
488
|
+
* @param {string} type
|
|
489
|
+
* @param {string} id
|
|
490
|
+
* @returns {Promise<Handle>}
|
|
491
|
+
*/
|
|
492
|
+
async _reopen(type, id) {
|
|
471
493
|
const { data } = await this.store.get('handles', id)
|
|
472
494
|
if (!data) throw CeroError.UNKNOWN('handle', id)
|
|
473
495
|
if (data.type !== type) throw new Error(`handle ${id} is type ${data.type}, not ${type}`)
|
package/src/index.js
CHANGED
|
@@ -113,9 +113,14 @@ export async function cero(dir, spec, opts = {}) {
|
|
|
113
113
|
}
|
|
114
114
|
if (opts.recovery) await me.recover({ timeout: opts.recoveryTimeout })
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
116
|
+
try {
|
|
117
|
+
for (const ext of internal.extensions) {
|
|
118
|
+
const off = await ext.setup?.(me)
|
|
119
|
+
if (typeof off === 'function') me.once('close', off)
|
|
120
|
+
}
|
|
121
|
+
} catch (err) {
|
|
122
|
+
await me.close().catch(() => {}) // a failed setup must not leak the half-built instance
|
|
123
|
+
throw err
|
|
119
124
|
}
|
|
120
125
|
|
|
121
126
|
return me
|
package/types/handle/index.d.ts
CHANGED
|
@@ -86,6 +86,7 @@ export class Handle extends ReadyResource {
|
|
|
86
86
|
_opts: any;
|
|
87
87
|
_onerror: any;
|
|
88
88
|
children: Set<any>;
|
|
89
|
+
_loading: Map<any, any>;
|
|
89
90
|
_owned: Set<any>;
|
|
90
91
|
store: Database;
|
|
91
92
|
pair: Pairing;
|
|
@@ -215,15 +216,24 @@ export class Handle extends ReadyResource {
|
|
|
215
216
|
*/
|
|
216
217
|
_join(invite: string, type: string, { routes, timeout }?: JoinChildOpts): Promise<Handle>;
|
|
217
218
|
/**
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
219
|
+
* Get an open child by id, or re-open it. Concurrent calls for the same id
|
|
220
|
+
* share one in-flight load, so the child is built — and `handle` emitted —
|
|
221
|
+
* exactly once.
|
|
221
222
|
*
|
|
222
223
|
* @param {string} type
|
|
223
224
|
* @param {string} id
|
|
224
225
|
* @returns {Promise<Handle>}
|
|
225
226
|
*/
|
|
226
227
|
_load(type: string, id: string): Promise<Handle>;
|
|
228
|
+
/**
|
|
229
|
+
* Reconstruct a child handle by id. Reuses the stored writer keypair if
|
|
230
|
+
* available; otherwise generates a fresh one and claims writer capability.
|
|
231
|
+
*
|
|
232
|
+
* @param {string} type
|
|
233
|
+
* @param {string} id
|
|
234
|
+
* @returns {Promise<Handle>}
|
|
235
|
+
*/
|
|
236
|
+
_reopen(type: string, id: string): Promise<Handle>;
|
|
227
237
|
/**
|
|
228
238
|
* Pause networking + storage. Idempotent; no-op on child handles.
|
|
229
239
|
*
|
|
@@ -379,4 +389,5 @@ export type Child = Handle & HandleExtra;
|
|
|
379
389
|
import ReadyResource from 'ready-resource';
|
|
380
390
|
import { Database } from '@cero-base/core/database';
|
|
381
391
|
import { Pairing } from '@cero-base/core/pairing';
|
|
392
|
+
import AbortController from 'abort-controller';
|
|
382
393
|
import { Identity } from '@cero-base/core/identity';
|