@peerbit/document 2.0.1 → 3.0.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.
@@ -5,10 +5,9 @@ import {
5
5
  serialize,
6
6
  variant,
7
7
  } from "@dao-xyz/borsh";
8
- import { CanAppend, Change, Entry, EntryType, TrimOptions } from "@peerbit/log";
8
+ import { Change, Entry, EntryType, TrimOptions } from "@peerbit/log";
9
9
  import { Program, ProgramEvents } from "@peerbit/program";
10
- import { CanRead } from "@peerbit/rpc";
11
- import { AccessError, DecryptedThing } from "@peerbit/crypto";
10
+ import { AccessError, DecryptedThing, PublicSignKey } from "@peerbit/crypto";
12
11
  import { logger as loggerFn } from "@peerbit/logger";
13
12
  import { AppendOptions } from "@peerbit/log";
14
13
  import { CustomEvent } from "@libp2p/interfaces/events";
@@ -18,16 +17,19 @@ import {
18
17
  Replicator,
19
18
  SharedLog,
20
19
  SharedLogOptions,
20
+ SharedAppendOptions,
21
21
  } from "@peerbit/shared-log";
22
22
  export { Role, Observer, Replicator }; // For convenience (so that consumers does not have to do the import above from shared-log packages)
23
23
 
24
24
  import {
25
- Indexable,
25
+ IndexableFields,
26
26
  BORSH_ENCODING_OPERATION,
27
27
  DeleteOperation,
28
28
  DocumentIndex,
29
29
  Operation,
30
30
  PutOperation,
31
+ CanSearch,
32
+ CanRead,
31
33
  } from "./document-index.js";
32
34
  import { asString, checkKeyable, Keyable } from "./utils.js";
33
35
  import { Context, Results } from "./query.js";
@@ -47,16 +49,30 @@ export interface DocumentEvents<T> {
47
49
  change: CustomEvent<DocumentsChange<T>>;
48
50
  }
49
51
 
52
+ export type TransactionContext<T> = {
53
+ entry: Entry<Operation<T>>;
54
+ };
55
+
56
+ type MaybePromise = Promise<boolean> | boolean;
57
+
58
+ type CanPerform<T> = (
59
+ operation: PutOperation<T> | DeleteOperation,
60
+ context: TransactionContext<T>
61
+ ) => MaybePromise;
62
+
50
63
  export type SetupOptions<T> = {
51
64
  type: AbstractType<T>;
52
- canRead?: CanRead;
53
- canAppend?: CanAppend<Operation<T>>;
54
- canOpen?: (program: T) => Promise<boolean> | boolean;
65
+ canOpen?: (program: T) => MaybePromise;
66
+ canPerform?: CanPerform<T>;
55
67
  index?: {
56
68
  key?: string | string[];
57
- fields?: Indexable<T>;
69
+ fields?: IndexableFields<T>;
70
+ canSearch?: CanSearch;
71
+ canRead?: CanRead<T>;
72
+ };
73
+ log?: {
74
+ trim?: TrimOptions;
58
75
  };
59
- trim?: TrimOptions;
60
76
  } & SharedLogOptions;
61
77
 
62
78
  @variant("documents")
@@ -75,7 +91,8 @@ export class Documents<T extends Record<string, any>> extends Program<
75
91
 
76
92
  private _clazz?: AbstractType<T>;
77
93
 
78
- private _optionCanAppend?: CanAppend<Operation<T>>;
94
+ private _optionCanPerform?: CanPerform<T>;
95
+
79
96
  canOpen?: (
80
97
  program: T,
81
98
  entry: Entry<Operation<T>>
@@ -109,14 +126,14 @@ export class Documents<T extends Record<string, any>> extends Program<
109
126
  );
110
127
  }
111
128
  }
112
- if (options.canAppend) {
113
- this._optionCanAppend = options.canAppend;
114
- }
129
+
130
+ this._optionCanPerform = options.canPerform;
115
131
 
116
132
  await this._index.open({
117
133
  type: this._clazz,
118
134
  log: this.log,
119
- canRead: options.canRead || (() => Promise.resolve(true)),
135
+ canRead: options?.index?.canRead,
136
+ canSearch: options.index?.canSearch,
120
137
  fields: options.index?.fields || ((obj) => obj),
121
138
  indexBy: options.index?.key,
122
139
  sync: async (result: Results<T>) =>
@@ -125,12 +142,13 @@ export class Documents<T extends Record<string, any>> extends Program<
125
142
 
126
143
  await this.log.open({
127
144
  encoding: BORSH_ENCODING_OPERATION,
145
+ canReplicate: options?.canReplicate,
128
146
  canAppend: this.canAppend.bind(this),
129
147
  onChange: this.handleChanges.bind(this),
130
- trim: options?.trim,
148
+ trim: options?.log?.trim,
131
149
  sync: options?.sync,
132
150
  role: options?.role,
133
- minReplicas: options?.minReplicas,
151
+ replicas: options?.replicas,
134
152
  });
135
153
  }
136
154
 
@@ -150,8 +168,22 @@ export class Documents<T extends Record<string, any>> extends Program<
150
168
  return false;
151
169
  }
152
170
 
153
- if (this._optionCanAppend && !(await this._optionCanAppend(entry))) {
154
- return false;
171
+ if (this._optionCanPerform) {
172
+ const payload = await entry.getPayloadValue();
173
+
174
+ if (payload instanceof PutOperation) {
175
+ payload.getValue(this.index.valueEncoding); // Decode they value so callbacks can jsut do .value
176
+ }
177
+ if (
178
+ !(await this._optionCanPerform(
179
+ payload as PutOperation<T> | DeleteOperation,
180
+ {
181
+ entry,
182
+ }
183
+ ))
184
+ ) {
185
+ return false;
186
+ }
155
187
  }
156
188
  return true;
157
189
  }
@@ -248,7 +280,7 @@ export class Documents<T extends Record<string, any>> extends Program<
248
280
 
249
281
  public async put(
250
282
  doc: T,
251
- options?: AppendOptions<Operation<T>> & { unique?: boolean }
283
+ options?: SharedAppendOptions<Operation<T>> & { unique?: boolean }
252
284
  ) {
253
285
  const key = this._index.indexByResolver(doc as any as Keyable);
254
286
  checkKeyable(key);
@@ -269,10 +301,13 @@ export class Documents<T extends Record<string, any>> extends Program<
269
301
  value: doc,
270
302
  }),
271
303
  {
272
- nexts: existingDocument
273
- ? [await this._resolveEntry(existingDocument.context.head)]
274
- : [], //
275
304
  ...options,
305
+ meta: {
306
+ next: existingDocument
307
+ ? [await this._resolveEntry(existingDocument.context.head)]
308
+ : [],
309
+ ...options?.meta,
310
+ }, //
276
311
  }
277
312
  );
278
313
  }
@@ -293,9 +328,12 @@ export class Documents<T extends Record<string, any>> extends Program<
293
328
  key: asString(key),
294
329
  }),
295
330
  {
296
- nexts: [await this._resolveEntry(existing.context.head)],
297
- type: EntryType.CUT,
298
331
  ...options,
332
+ meta: {
333
+ next: [await this._resolveEntry(existing.context.head)],
334
+ type: EntryType.CUT,
335
+ ...options?.meta,
336
+ },
299
337
  } //
300
338
  );
301
339
  }
@@ -358,8 +396,8 @@ export class Documents<T extends Record<string, any>> extends Program<
358
396
  const context = new Context({
359
397
  created:
360
398
  this._index.index.get(key)?.context.created ||
361
- item.metadata.clock.timestamp.wallTime,
362
- modified: item.metadata.clock.timestamp.wallTime,
399
+ item.meta.clock.timestamp.wallTime,
400
+ modified: item.meta.clock.timestamp.wallTime,
363
401
  head: item.hash,
364
402
  });
365
403
 
@@ -378,7 +416,7 @@ export class Documents<T extends Record<string, any>> extends Program<
378
416
  if (
379
417
  (await this.canOpen!(value, item)) &&
380
418
  this.log.role instanceof Replicator &&
381
- (await this.log.replicator(item.gid)) // TODO types, throw runtime error if replicator is not provided
419
+ (await this.log.replicator(item)) // TODO types, throw runtime error if replicator is not provided
382
420
  ) {
383
421
  await this.node.open(value, {
384
422
  parent: this as Program<any, any>,
package/src/query.ts CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  variant,
7
7
  vec,
8
8
  } from "@dao-xyz/borsh";
9
+
9
10
  import { asString } from "./utils.js";
10
11
  import { randomBytes, sha256Base64Sync } from "@peerbit/crypto";
11
12
 
@@ -431,8 +432,10 @@ export class ResultWithSource<T> extends Result {
431
432
  }
432
433
  }
433
434
 
435
+ export abstract class AbstractSearchResult<T> {}
436
+
434
437
  @variant(0)
435
- export class Results<T> {
438
+ export class Results<T> extends AbstractSearchResult<T> {
436
439
  @field({ type: vec(ResultWithSource) })
437
440
  results: ResultWithSource<T>[];
438
441
 
@@ -440,11 +443,15 @@ export class Results<T> {
440
443
  kept: bigint; // how many results that were not sent, but can be collected later
441
444
 
442
445
  constructor(properties: { results: ResultWithSource<T>[]; kept: bigint }) {
446
+ super();
443
447
  this.kept = properties.kept;
444
448
  this.results = properties.results;
445
449
  }
446
450
  }
447
451
 
452
+ @variant(1)
453
+ export class NoAccess extends AbstractSearchResult<any> {}
454
+
448
455
  /* @variant(5)
449
456
  export class LogQuery extends Query { } */
450
457
 
@@ -464,7 +471,7 @@ export class EntryEncryptedByQuery
464
471
  >
465
472
  {
466
473
  @field({ type: vec(X25519PublicKey) })
467
- metadata: X25519PublicKey[];
474
+ meta: X25519PublicKey[];
468
475
 
469
476
  @field({ type: vec(X25519PublicKey) })
470
477
  payload: X25519PublicKey[];
@@ -476,7 +483,7 @@ export class EntryEncryptedByQuery
476
483
  signatures: X25519PublicKey[];
477
484
 
478
485
  constructor(properties?: {
479
- metadata: X25519PublicKey[];
486
+ meta: X25519PublicKey[];
480
487
  next: X25519PublicKey[];
481
488
  payload: X25519PublicKey[];
482
489
  signatures: X25519PublicKey[];