@cero-base/cero 0.8.7 → 0.8.9

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cero-base/cero",
3
- "version": "0.8.7",
3
+ "version": "0.8.9",
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",
@@ -78,7 +78,7 @@
78
78
  "test": "ls test/*.test.js | xargs -P1 -n1 brittle-node"
79
79
  },
80
80
  "dependencies": {
81
- "@cero-base/core": "^0.8.7",
81
+ "@cero-base/core": "^0.8.9",
82
82
  "b4a": "^1.8.1",
83
83
  "bare-abort-controller": "^1.1.2",
84
84
  "bare-crypto": "^1.14.1",
@@ -120,7 +120,14 @@ function isPlainHandle(v) {
120
120
  }
121
121
 
122
122
  function compile(root, ns, scope = 'main') {
123
- const ctx = { types: [], collections: [], dispatches: [], meta: { ns, refs: {} }, ns }
123
+ const ctx = {
124
+ types: [],
125
+ collections: [],
126
+ dispatches: [],
127
+ indexes: [],
128
+ meta: { ns, refs: {} },
129
+ ns
130
+ }
124
131
 
125
132
  Object.assign(ctx.meta.refs, builtinRefs(ns, scope))
126
133
 
@@ -136,6 +143,7 @@ function compile(root, ns, scope = 'main') {
136
143
  types: ctx.types,
137
144
  collections: ctx.collections,
138
145
  dispatches: ctx.dispatches,
146
+ indexes: ctx.indexes,
139
147
  meta: ctx.meta
140
148
  }
141
149
  }
@@ -173,6 +181,12 @@ function register(name, node, ctx) {
173
181
  ctx.dispatches.push({ name: `set-${name}`, requestType: fqn })
174
182
  ctx.dispatches.push({ name: `del-${name}`, requestType: `@${ctx.ns}/del-by-id` })
175
183
  ctx.meta.refs[name] = { kind: 'collection', path: [name], schema: fqn }
184
+ if (node.indexes) {
185
+ for (const [idx, fields] of Object.entries(node.indexes)) {
186
+ ctx.indexes.push({ name: `${name}-${idx}`, collection: fqn, key: fields })
187
+ }
188
+ ctx.meta.refs[name].indexes = node.indexes
189
+ }
176
190
  }
177
191
  }
178
192
 
@@ -184,7 +198,7 @@ function fieldsFor(fields) {
184
198
  }))
185
199
  }
186
200
 
187
- function emitMain(dir, ns, { types, collections, dispatches }, { rpc, extend = {} }) {
201
+ function emitMain(dir, ns, { types, collections, dispatches, indexes = [] }, { rpc, extend = {} }) {
188
202
  const schemaDir = join(dir, 'schema')
189
203
  const dbDir = join(dir, 'db')
190
204
  const dispatchDir = join(dir, 'dispatch')
@@ -201,6 +215,7 @@ function emitMain(dir, ns, { types, collections, dispatches }, { rpc, extend = {
201
215
  const dns = db.namespace(ns)
202
216
  for (const desc of builtinCollections(ns, 'main')) dns.collections.register(desc)
203
217
  for (const desc of collections) dns.collections.register(desc)
218
+ for (const desc of indexes) dns.indexes.register(desc)
204
219
  HyperdbBuilder.toDisk(db, dbDir, { esm: true })
205
220
 
206
221
  const d = Hyperdispatch.from(schemaDir, dispatchDir)
@@ -217,7 +232,7 @@ function emitMain(dir, ns, { types, collections, dispatches }, { rpc, extend = {
217
232
  }
218
233
  }
219
234
 
220
- function emitLocal(dir, ns, { types, collections }) {
235
+ function emitLocal(dir, ns, { types, collections, indexes = [] }) {
221
236
  const schemaDir = join(dir, 'schema')
222
237
  const dbDir = join(dir, 'db')
223
238
 
@@ -231,6 +246,7 @@ function emitLocal(dir, ns, { types, collections }) {
231
246
  const dns = db.namespace(ns)
232
247
  for (const desc of builtinCollections(ns, 'local')) dns.collections.register(desc)
233
248
  for (const desc of collections) dns.collections.register(desc)
249
+ for (const desc of indexes) dns.indexes.register(desc)
234
250
  HyperdbBuilder.toDisk(db, dbDir, { esm: true })
235
251
  }
236
252
 
@@ -1,11 +1,12 @@
1
1
  import { Readable } from 'streamx'
2
- import HypercoreStorage from 'hypercore-storage'
3
- import Corestore from 'corestore'
4
2
 
5
3
  import { CeroError } from '@cero-base/core/errors'
6
4
 
7
5
  import { onAbort } from './utils.js'
8
- import { Local } from '../local/index.js'
6
+
7
+ // `peek` (below) lazy-imports hypercore-storage / corestore / local so this
8
+ // module — which the lightweight RPC client re-exports — stays free of native
9
+ // deps. A client never calls `peek`, so the heavy imports load only on the core.
9
10
 
10
11
  /**
11
12
  * @typedef {import('./utils.js').Ref} Ref
@@ -205,6 +206,10 @@ export async function peek(dir, spec) {
205
206
  if (typeof dir !== 'string' || !dir) throw CeroError.INVALID('dir must be a non-empty string')
206
207
  if (!spec) throw CeroError.REQUIRED('spec')
207
208
 
209
+ const { default: HypercoreStorage } = await import('hypercore-storage')
210
+ const { default: Corestore } = await import('corestore')
211
+ const { Local } = await import('../local/index.js')
212
+
208
213
  const root = new HypercoreStorage(`${dir}/main`)
209
214
  await root.ready()
210
215
  const store = new Corestore(root, { manifestVersion: 2 })
package/src/rpc/client.js CHANGED
@@ -2,9 +2,10 @@ import { Readable } from 'streamx'
2
2
  import { RPCClient, bindCodec } from '@cero-base/core/rpc'
3
3
 
4
4
  import { attachRefs } from '../lib/utils.js'
5
- import { bind } from '../lib/operators.js'
5
+ import { put, set, get, del, count, watch, call, open, bind, define } from '../lib/operators.js'
6
+ import { t, schema } from '../lib/spec.js'
6
7
 
7
- export { put, set, get, del, count, watch, call, open } from '../lib/operators.js'
8
+ export { put, set, get, del, count, watch, call, open, bind, define, t, schema }
8
9
 
9
10
  /**
10
11
  * @typedef {import('@cero-base/core/rpc').RPCClient} BaseRPCClient
@@ -397,3 +398,34 @@ export async function connect(ipc, spec) {
397
398
  await client.ready()
398
399
  return client
399
400
  }
401
+
402
+ /**
403
+ * Symmetric client entry. Mirrors the main `cero`, but `cero(ipc, spec)` connects
404
+ * to a server (via `connect`) instead of opening a local store. The same operator
405
+ * surface is attached, so `import { cero } from '@cero-base/cero/client'` works
406
+ * just like `import { cero } from '@cero-base/cero'`.
407
+ *
408
+ * Note: `before`/`after`/`peek` are intentionally not exposed here — they hook the
409
+ * local write path / probe a local store, which a client proxy has no notion of.
410
+ *
411
+ * @param {any} ipc Framed IPC duplex stream.
412
+ * @param {any} spec Built cero spec.
413
+ * @returns {Promise<Client>}
414
+ */
415
+ export function cero(ipc, spec) {
416
+ return connect(ipc, spec)
417
+ }
418
+ cero.connect = connect
419
+ cero.restore = restore
420
+ cero.t = t
421
+ cero.put = put
422
+ cero.set = set
423
+ cero.get = get
424
+ cero.del = del
425
+ cero.count = count
426
+ cero.watch = watch
427
+ cero.call = call
428
+ cero.open = open
429
+ cero.bind = bind
430
+ cero.define = define
431
+ cero.schema = schema
@@ -15,6 +15,36 @@ export function restore(me: Client, phrase: string): Promise<Client>;
15
15
  * @returns {Promise<Client>}
16
16
  */
17
17
  export function connect(ipc: any, spec: object): Promise<Client>;
18
+ /**
19
+ * Symmetric client entry. Mirrors the main `cero`, but `cero(ipc, spec)` connects
20
+ * to a server (via `connect`) instead of opening a local store. The same operator
21
+ * surface is attached, so `import { cero } from '@cero-base/cero/client'` works
22
+ * just like `import { cero } from '@cero-base/cero'`.
23
+ *
24
+ * Note: `before`/`after`/`peek` are intentionally not exposed here — they hook the
25
+ * local write path / probe a local store, which a client proxy has no notion of.
26
+ *
27
+ * @param {any} ipc Framed IPC duplex stream.
28
+ * @param {any} spec Built cero spec.
29
+ * @returns {Promise<Client>}
30
+ */
31
+ export function cero(ipc: any, spec: any): Promise<Client>;
32
+ export namespace cero {
33
+ export { connect };
34
+ export { restore };
35
+ export { t };
36
+ export { put };
37
+ export { set };
38
+ export { get };
39
+ export { del };
40
+ export { count };
41
+ export { watch };
42
+ export { call };
43
+ export { open };
44
+ export { bind };
45
+ export { define };
46
+ export { schema };
47
+ }
18
48
  /**
19
49
  * IPC-side RPC client for cero. Wraps an `hrpc` channel and exposes the
20
50
  * same handle/ref/row API as a local cero instance, transparently
@@ -100,6 +130,18 @@ export type HandleStub = {
100
130
  type: string;
101
131
  name: string | null;
102
132
  };
133
+ import { t } from '../lib/spec.js';
134
+ import { put } from '../lib/operators.js';
135
+ import { set } from '../lib/operators.js';
136
+ import { get } from '../lib/operators.js';
137
+ import { del } from '../lib/operators.js';
138
+ import { count } from '../lib/operators.js';
139
+ import { watch } from '../lib/operators.js';
140
+ import { call } from '../lib/operators.js';
141
+ import { open } from '../lib/operators.js';
142
+ import { bind } from '../lib/operators.js';
143
+ import { define } from '../lib/operators.js';
144
+ import { schema } from '../lib/spec.js';
103
145
  import { RPCClient } from '@cero-base/core/rpc';
104
146
  /**
105
147
  * Per-device `local`-namespace surface on a Client. Exposes each app-defined
@@ -145,4 +187,4 @@ declare class Handle {
145
187
  /** Tear down the remote handle and drop membership. */
146
188
  leave(): any;
147
189
  }
148
- export { put, set, get, del, count, watch, call, open } from "../lib/operators.js";
190
+ export { put, set, get, del, count, watch, call, open, bind, define, t, schema };