@cero-base/core 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/database/bootstrap.js +8 -1
- package/src/database/dispatch.js +7 -5
- package/src/database/index.js +5 -12
- package/src/lib/schema.js +20 -1
- package/types/database/index.d.ts +3 -6
- package/types/lib/schema.d.ts +13 -0
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Hypercore from 'hypercore'
|
|
2
2
|
import { Identity } from '../identity/index.js'
|
|
3
|
+
import { toId } from '../lib/utils.js'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* First-run device provisioning: mint a device writer keypair, persist it as a
|
|
@@ -45,7 +46,13 @@ async function saveWriter(db, writerKey, { name, isMobile }) {
|
|
|
45
46
|
{
|
|
46
47
|
master: db.identity.publicKey,
|
|
47
48
|
writer: writerKey,
|
|
48
|
-
sig: db.identity.sign(writerKey)
|
|
49
|
+
sig: db.identity.sign(writerKey)
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
[
|
|
53
|
+
'set-device',
|
|
54
|
+
{
|
|
55
|
+
id: toId(writerKey),
|
|
49
56
|
name: name || null,
|
|
50
57
|
isMobile: isMobile === true
|
|
51
58
|
}
|
package/src/database/dispatch.js
CHANGED
|
@@ -47,8 +47,6 @@ export function makeDispatcher(spec, ns, routes) {
|
|
|
47
47
|
await insert(ctx.view, 'devices', `@${ns}/devices`, {
|
|
48
48
|
id: toId(op.writer),
|
|
49
49
|
memberId: toId(op.master),
|
|
50
|
-
name: op.name || null,
|
|
51
|
-
isMobile: op.isMobile === true,
|
|
52
50
|
createdAt: ts,
|
|
53
51
|
updatedAt: ts
|
|
54
52
|
})
|
|
@@ -69,8 +67,6 @@ export function makeDispatcher(spec, ns, routes) {
|
|
|
69
67
|
await insert(ctx.view, 'devices', `@${ns}/devices`, {
|
|
70
68
|
id: toId(op.writer),
|
|
71
69
|
memberId,
|
|
72
|
-
name: op.name || null,
|
|
73
|
-
isMobile: op.isMobile === true,
|
|
74
70
|
createdAt: ts,
|
|
75
71
|
updatedAt: ts
|
|
76
72
|
})
|
|
@@ -120,7 +116,13 @@ export function makeDispatcher(spec, ns, routes) {
|
|
|
120
116
|
})
|
|
121
117
|
add(`set-${b.verb}`, async (op, ctx) => {
|
|
122
118
|
const existing = await device(ctx.view, op.id)
|
|
123
|
-
|
|
119
|
+
const ts = Date.now()
|
|
120
|
+
await insert(ctx.view, b.name, col, {
|
|
121
|
+
...op,
|
|
122
|
+
memberId: existing?.memberId ?? op.memberId ?? null,
|
|
123
|
+
createdAt: existing?.createdAt ?? ts,
|
|
124
|
+
updatedAt: ts
|
|
125
|
+
})
|
|
124
126
|
})
|
|
125
127
|
continue
|
|
126
128
|
}
|
package/src/database/index.js
CHANGED
|
@@ -422,12 +422,12 @@ export class Database extends ReadyResource {
|
|
|
422
422
|
|
|
423
423
|
/**
|
|
424
424
|
* Claim writership on an existing room by signing our writer key with the
|
|
425
|
-
* member identity and appending optimistically.
|
|
425
|
+
* member identity and appending optimistically. Admission only — the device
|
|
426
|
+
* is named separately (bootstrap → set-device).
|
|
426
427
|
*
|
|
427
|
-
* @param {{ name?: string | null, isMobile?: boolean }} [opts]
|
|
428
428
|
* @returns {Promise<void>}
|
|
429
429
|
*/
|
|
430
|
-
async claim(
|
|
430
|
+
async claim() {
|
|
431
431
|
this.guard()
|
|
432
432
|
if (this.bee.writable) return
|
|
433
433
|
|
|
@@ -436,9 +436,7 @@ export class Database extends ReadyResource {
|
|
|
436
436
|
const encoded = this.spec.dispatch.encode(`@${this.ns}/claim-writer`, {
|
|
437
437
|
identity: this.identity.publicKey,
|
|
438
438
|
writer: writerKey,
|
|
439
|
-
sig
|
|
440
|
-
name,
|
|
441
|
-
isMobile
|
|
439
|
+
sig
|
|
442
440
|
})
|
|
443
441
|
await this.bee.append(encoded, { optimistic: true })
|
|
444
442
|
await this.bee.update()
|
|
@@ -549,12 +547,7 @@ export class Database extends ReadyResource {
|
|
|
549
547
|
signers: [{ publicKey }]
|
|
550
548
|
})
|
|
551
549
|
const sig = this.identity.sign(writerKey)
|
|
552
|
-
await this.write([
|
|
553
|
-
[
|
|
554
|
-
verb,
|
|
555
|
-
{ master: this.identity.publicKey, writer: writerKey, sig, name: null, isMobile: false }
|
|
556
|
-
]
|
|
557
|
-
])
|
|
550
|
+
await this.write([[verb, { master: this.identity.publicKey, writer: writerKey, sig }]])
|
|
558
551
|
await this.runAfter(hook, ctx)
|
|
559
552
|
}
|
|
560
553
|
}
|
package/src/lib/schema.js
CHANGED
|
@@ -2,7 +2,7 @@ import { CeroError } from './errors.js'
|
|
|
2
2
|
import { SINGLE, COLLECTION, ACTION } from './constants.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @typedef {{ prim: string }} Prim
|
|
5
|
+
* @typedef {{ prim: string, required?: boolean }} Prim
|
|
6
6
|
* @typedef {{ kind: 'single' | 'collection' | 'action', fields: Record<string, Prim> }} TypeDef
|
|
7
7
|
* @typedef {{ [name: string]: TypeDef | Record<string, TypeDef> } & { local?: Record<string, TypeDef> }} SchemaDefs
|
|
8
8
|
* @typedef {{ defs: SchemaDefs }} Schema
|
|
@@ -25,6 +25,14 @@ export const t = {
|
|
|
25
25
|
fixed32: prim('fixed32'),
|
|
26
26
|
fixed64: prim('fixed64'),
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Mark a field as required. Fields are optional by default.
|
|
30
|
+
*
|
|
31
|
+
* @param {Prim} marker
|
|
32
|
+
* @returns {Prim}
|
|
33
|
+
*/
|
|
34
|
+
required: (marker) => ({ ...marker, required: true }),
|
|
35
|
+
|
|
28
36
|
/**
|
|
29
37
|
* Single-row table (one record, set/get by name).
|
|
30
38
|
*
|
|
@@ -53,6 +61,17 @@ export const t = {
|
|
|
53
61
|
*/
|
|
54
62
|
action(fields) {
|
|
55
63
|
return { kind: ACTION, fields }
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Add fields to a builtin type (members, devices, …). Merged into the
|
|
68
|
+
* builtin's base fields at build time; redeclaring a base field throws.
|
|
69
|
+
*
|
|
70
|
+
* @param {Record<string, Prim>} fields
|
|
71
|
+
* @returns {{ kind: 'extend', fields: Record<string, Prim> }}
|
|
72
|
+
*/
|
|
73
|
+
extend(fields) {
|
|
74
|
+
return { kind: 'extend', fields }
|
|
56
75
|
}
|
|
57
76
|
}
|
|
58
77
|
|
|
@@ -210,15 +210,12 @@ export class Database extends ReadyResource {
|
|
|
210
210
|
}>;
|
|
211
211
|
/**
|
|
212
212
|
* Claim writership on an existing room by signing our writer key with the
|
|
213
|
-
* member identity and appending optimistically.
|
|
213
|
+
* member identity and appending optimistically. Admission only — the device
|
|
214
|
+
* is named separately (bootstrap → set-device).
|
|
214
215
|
*
|
|
215
|
-
* @param {{ name?: string | null, isMobile?: boolean }} [opts]
|
|
216
216
|
* @returns {Promise<void>}
|
|
217
217
|
*/
|
|
218
|
-
claim(
|
|
219
|
-
name?: string | null;
|
|
220
|
-
isMobile?: boolean;
|
|
221
|
-
}): Promise<void>;
|
|
218
|
+
claim(): Promise<void>;
|
|
222
219
|
/**
|
|
223
220
|
* Resolve once the bee becomes writable, or reject after `timeout` ms.
|
|
224
221
|
*
|
package/types/lib/schema.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export namespace t {
|
|
|
14
14
|
let json: Prim;
|
|
15
15
|
let fixed32: Prim;
|
|
16
16
|
let fixed64: Prim;
|
|
17
|
+
function required(marker: Prim): Prim;
|
|
17
18
|
/**
|
|
18
19
|
* Single-row table (one record, set/get by name).
|
|
19
20
|
*
|
|
@@ -35,9 +36,21 @@ export namespace t {
|
|
|
35
36
|
* @returns {TypeDef}
|
|
36
37
|
*/
|
|
37
38
|
function action(fields: Record<string, Prim>): TypeDef;
|
|
39
|
+
/**
|
|
40
|
+
* Add fields to a builtin type (members, devices, …). Merged into the
|
|
41
|
+
* builtin's base fields at build time; redeclaring a base field throws.
|
|
42
|
+
*
|
|
43
|
+
* @param {Record<string, Prim>} fields
|
|
44
|
+
* @returns {{ kind: 'extend', fields: Record<string, Prim> }}
|
|
45
|
+
*/
|
|
46
|
+
function extend(fields: Record<string, Prim>): {
|
|
47
|
+
kind: "extend";
|
|
48
|
+
fields: Record<string, Prim>;
|
|
49
|
+
};
|
|
38
50
|
}
|
|
39
51
|
export type Prim = {
|
|
40
52
|
prim: string;
|
|
53
|
+
required?: boolean;
|
|
41
54
|
};
|
|
42
55
|
export type TypeDef = {
|
|
43
56
|
kind: "single" | "collection" | "action";
|