@peerbit/document 6.0.7 → 7.0.0-3a75d6e

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.
Files changed (66) hide show
  1. package/README.md +2 -2
  2. package/dist/benchmark/index.d.ts +2 -0
  3. package/dist/benchmark/index.d.ts.map +1 -0
  4. package/dist/benchmark/index.js +125 -0
  5. package/dist/benchmark/index.js.map +1 -0
  6. package/dist/benchmark/memory/index.d.ts +2 -0
  7. package/dist/benchmark/memory/index.d.ts.map +1 -0
  8. package/dist/benchmark/memory/index.js +122 -0
  9. package/dist/benchmark/memory/index.js.map +1 -0
  10. package/dist/benchmark/memory/insert.d.ts +2 -0
  11. package/dist/benchmark/memory/insert.d.ts.map +1 -0
  12. package/dist/benchmark/memory/insert.js +133 -0
  13. package/dist/benchmark/memory/insert.js.map +1 -0
  14. package/dist/benchmark/memory/utils.d.ts +13 -0
  15. package/dist/benchmark/memory/utils.d.ts.map +1 -0
  16. package/dist/benchmark/memory/utils.js +2 -0
  17. package/dist/benchmark/memory/utils.js.map +1 -0
  18. package/dist/benchmark/replication.d.ts +2 -0
  19. package/dist/benchmark/replication.d.ts.map +1 -0
  20. package/dist/benchmark/replication.js +172 -0
  21. package/dist/benchmark/replication.js.map +1 -0
  22. package/dist/src/borsh.d.ts +2 -0
  23. package/dist/src/borsh.d.ts.map +1 -0
  24. package/dist/src/borsh.js +16 -0
  25. package/dist/src/borsh.js.map +1 -0
  26. package/dist/src/constants.d.ts +2 -0
  27. package/dist/src/constants.d.ts.map +1 -0
  28. package/dist/src/constants.js +2 -0
  29. package/dist/src/constants.js.map +1 -0
  30. package/dist/src/index.d.ts +4 -0
  31. package/dist/src/index.d.ts.map +1 -0
  32. package/dist/src/index.js +4 -0
  33. package/dist/src/index.js.map +1 -0
  34. package/dist/src/program.d.ts +87 -0
  35. package/dist/src/program.d.ts.map +1 -0
  36. package/{lib/esm/document-store.js → dist/src/program.js} +159 -138
  37. package/dist/src/program.js.map +1 -0
  38. package/dist/src/search.d.ts +132 -0
  39. package/dist/src/search.d.ts.map +1 -0
  40. package/dist/src/search.js +845 -0
  41. package/dist/src/search.js.map +1 -0
  42. package/package.json +74 -43
  43. package/src/borsh.ts +19 -0
  44. package/src/constants.ts +1 -0
  45. package/src/index.ts +3 -3
  46. package/src/program.ts +580 -0
  47. package/src/search.ts +1217 -0
  48. package/LICENSE +0 -202
  49. package/lib/esm/document-index.d.ts +0 -147
  50. package/lib/esm/document-index.js +0 -942
  51. package/lib/esm/document-index.js.map +0 -1
  52. package/lib/esm/document-store.d.ts +0 -72
  53. package/lib/esm/document-store.js.map +0 -1
  54. package/lib/esm/index.d.ts +0 -3
  55. package/lib/esm/index.js +0 -4
  56. package/lib/esm/index.js.map +0 -1
  57. package/lib/esm/query.d.ts +0 -191
  58. package/lib/esm/query.js +0 -615
  59. package/lib/esm/query.js.map +0 -1
  60. package/lib/esm/utils.d.ts +0 -3
  61. package/lib/esm/utils.js +0 -12
  62. package/lib/esm/utils.js.map +0 -1
  63. package/src/document-index.ts +0 -1268
  64. package/src/document-store.ts +0 -547
  65. package/src/query.ts +0 -525
  66. package/src/utils.ts +0 -17
@@ -0,0 +1,16 @@
1
+ import { getSchema } from "@dao-xyz/borsh";
2
+ export const copySerialization = (sourceClazz, targetClazz) => {
3
+ const copiedFromAlready = targetClazz["__copiedFrom"] || [];
4
+ if (copiedFromAlready?.includes(sourceClazz)) {
5
+ return;
6
+ }
7
+ copiedFromAlready.push(sourceClazz);
8
+ targetClazz["__copiedFrom"] = copiedFromAlready;
9
+ const targetSchema = getSchema(targetClazz);
10
+ const sourceSchema = getSchema(sourceClazz);
11
+ targetSchema.fields = [...sourceSchema.fields, ...targetSchema.fields];
12
+ targetSchema.variant = sourceSchema.variant;
13
+ targetSchema.getDependencies =
14
+ sourceSchema.getDependencies.bind(sourceSchema);
15
+ };
16
+ //# sourceMappingURL=borsh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"borsh.js","sourceRoot":"","sources":["../../src/borsh.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,WAAgB,EAAE,WAAgB,EAAE,EAAE;IACvE,MAAM,iBAAiB,GAAU,WAAW,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IACnE,IAAI,iBAAiB,EAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9C,OAAO;IACR,CAAC;IAED,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACpC,WAAW,CAAC,cAAc,CAAC,GAAG,iBAAiB,CAAC;IAEhD,MAAM,YAAY,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IAC5C,MAAM,YAAY,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IAE5C,YAAY,CAAC,MAAM,GAAG,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACvE,YAAY,CAAC,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC;IAC5C,YAAY,CAAC,eAAe;QAC3B,YAAY,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAClD,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const MAX_BATCH_SIZE = 5000000;
2
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,UAAM,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const MAX_BATCH_SIZE = 5e6;
2
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./program.js";
2
+ export * from "./search.js";
3
+ export { MAX_BATCH_SIZE as MAX_DOCUMENT_SIZE } from "./constants.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,cAAc,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from "./program.js";
2
+ export * from "./search.js";
3
+ export { MAX_BATCH_SIZE as MAX_DOCUMENT_SIZE } from "./constants.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,cAAc,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,87 @@
1
+ import { type AbstractType } from "@dao-xyz/borsh";
2
+ import * as indexerTypes from "@peerbit/indexer-interface";
3
+ import { type Change, Entry, type ShallowOrFullEntry, type TrimOptions } from "@peerbit/log";
4
+ import { Program, type ProgramEvents } from "@peerbit/program";
5
+ import { type SharedAppendOptions, SharedLog, type SharedLogOptions } from "@peerbit/shared-log";
6
+ import { type CanRead, type CanSearch, DeleteOperation, DocumentIndex, Operation, PutOperation, type TransformOptions } from "./search.js";
7
+ export declare class OperationError extends Error {
8
+ constructor(message?: string);
9
+ }
10
+ export interface DocumentsChange<T> {
11
+ added: T[];
12
+ removed: T[];
13
+ }
14
+ export interface DocumentEvents<T> {
15
+ change: CustomEvent<DocumentsChange<T>>;
16
+ }
17
+ type MaybePromise<T> = Promise<T> | T;
18
+ type CanPerformPut<T> = {
19
+ type: "put";
20
+ value: T;
21
+ operation: PutOperation;
22
+ entry: Entry<PutOperation>;
23
+ };
24
+ type CanPerformDelete<T> = {
25
+ type: "delete";
26
+ operation: DeleteOperation;
27
+ entry: Entry<DeleteOperation>;
28
+ };
29
+ export type CanPerformOperations<T> = CanPerformPut<T> | CanPerformDelete<T>;
30
+ export type CanPerform<T> = (properties: CanPerformOperations<T>) => MaybePromise<boolean>;
31
+ export type SetupOptions<T, I = T> = {
32
+ type: AbstractType<T>;
33
+ canOpen?: (program: T) => MaybePromise<boolean>;
34
+ canPerform?: CanPerform<T>;
35
+ id?: (obj: any) => indexerTypes.IdPrimitive;
36
+ index?: {
37
+ canSearch?: CanSearch;
38
+ canRead?: CanRead<T>;
39
+ idProperty?: string | string[];
40
+ } & TransformOptions<T, I>;
41
+ log?: {
42
+ trim?: TrimOptions;
43
+ };
44
+ } & SharedLogOptions<Operation>;
45
+ export declare class Documents<T, I extends Record<string, any> = T extends Record<string, any> ? T : any> extends Program<SetupOptions<T, I>, DocumentEvents<T> & ProgramEvents> {
46
+ log: SharedLog<Operation>;
47
+ immutable: boolean;
48
+ private _index;
49
+ private _clazz;
50
+ private _optionCanPerform?;
51
+ private _manuallySynced;
52
+ private idResolver;
53
+ canOpen?: (program: T, entry: Entry<Operation>) => Promise<boolean> | boolean;
54
+ constructor(properties?: {
55
+ id?: Uint8Array;
56
+ immutable?: boolean;
57
+ index?: DocumentIndex<T, I>;
58
+ });
59
+ get index(): DocumentIndex<T, I>;
60
+ open(options: SetupOptions<T, I>): Promise<void>;
61
+ recover(): Promise<void>;
62
+ private _resolveEntry;
63
+ canAppend(entry: Entry<Operation>, reference?: {
64
+ document: T;
65
+ operation: PutOperation;
66
+ }): Promise<boolean>;
67
+ _canAppend(entry: Entry<Operation>, reference?: {
68
+ document: T;
69
+ operation: PutOperation;
70
+ }): Promise<PutOperation | DeleteOperation | false>;
71
+ put(doc: T, options?: SharedAppendOptions<Operation> & {
72
+ unique?: boolean;
73
+ }): Promise<{
74
+ entry: Entry<Operation>;
75
+ removed: ShallowOrFullEntry<Operation>[];
76
+ }>;
77
+ del(id: indexerTypes.Ideable, options?: SharedAppendOptions<Operation>): Promise<{
78
+ entry: Entry<Operation>;
79
+ removed: ShallowOrFullEntry<Operation>[];
80
+ }>;
81
+ handleChanges(change: Change<Operation>, reference?: {
82
+ document: T;
83
+ operation: PutOperation;
84
+ }): Promise<void>;
85
+ }
86
+ export {};
87
+ //# sourceMappingURL=program.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../src/program.ts"],"names":[],"mappings":"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"}
@@ -7,17 +7,17 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
- import { BorshError, deserialize, field, serialize, variant } from "@dao-xyz/borsh";
11
- import { Entry, EntryType } from "@peerbit/log";
12
- import { Program } from "@peerbit/program";
10
+ import { BorshError, field, serialize, variant, } from "@dao-xyz/borsh";
11
+ import { CustomEvent } from "@libp2p/interface";
13
12
  import { AccessError, DecryptedThing } from "@peerbit/crypto";
13
+ import * as documentsTypes from "@peerbit/document-interface";
14
+ import * as indexerTypes from "@peerbit/indexer-interface";
15
+ import { Entry, EntryType, } from "@peerbit/log";
14
16
  import { logger as loggerFn } from "@peerbit/logger";
15
- import { CustomEvent } from "@libp2p/interface";
16
- import { Replicator, SharedLog } from "@peerbit/shared-log";
17
- import { BORSH_ENCODING_OPERATION, DeleteOperation, DocumentIndex, PutOperation, MAX_DOCUMENT_SIZE } from "./document-index.js";
18
- import { asString, checkKeyable } from "./utils.js";
19
- import { Context } from "./query.js";
20
- export { MAX_DOCUMENT_SIZE };
17
+ import { Program } from "@peerbit/program";
18
+ import { SharedLog, } from "@peerbit/shared-log";
19
+ import { MAX_BATCH_SIZE } from "./constants.js";
20
+ import { BORSH_ENCODING_OPERATION, DeleteOperation, DocumentIndex, Operation, PutOperation, } from "./search.js";
21
21
  const logger = loggerFn({ module: "document" });
22
22
  export class OperationError extends Error {
23
23
  constructor(message) {
@@ -31,6 +31,7 @@ let Documents = class Documents extends Program {
31
31
  _clazz;
32
32
  _optionCanPerform;
33
33
  _manuallySynced;
34
+ idResolver;
34
35
  canOpen;
35
36
  constructor(properties) {
36
37
  super();
@@ -52,13 +53,19 @@ let Documents = class Documents extends Program {
52
53
  }
53
54
  this._optionCanPerform = options.canPerform;
54
55
  this._manuallySynced = new Set();
56
+ const idProperty = options.index?.idProperty || "id";
57
+ const idResolver = options.id ||
58
+ (typeof idProperty === "string"
59
+ ? (obj) => obj[idProperty]
60
+ : (obj) => indexerTypes.extractFieldValue(obj, idProperty));
61
+ this.idResolver = idResolver;
55
62
  await this._index.open({
56
- type: this._clazz,
57
63
  log: this.log,
58
64
  canRead: options?.index?.canRead,
59
65
  canSearch: options.index?.canSearch,
60
- fields: options.index?.fields || ((obj) => obj),
61
- indexBy: options.index?.key,
66
+ documentType: this._clazz,
67
+ transform: options.index,
68
+ indexBy: idProperty,
62
69
  sync: async (result) => {
63
70
  // here we arrive for all the results we want to persist.
64
71
  // we we need to do here is
@@ -70,7 +77,7 @@ let Documents = class Documents extends Program {
70
77
  }
71
78
  return this.log.log.join(heads);
72
79
  },
73
- dbType: this.constructor
80
+ dbType: this.constructor,
74
81
  });
75
82
  await this.log.open({
76
83
  encoding: BORSH_ENCODING_OPERATION,
@@ -78,13 +85,13 @@ let Documents = class Documents extends Program {
78
85
  canAppend: this.canAppend.bind(this),
79
86
  onChange: this.handleChanges.bind(this),
80
87
  trim: options?.log?.trim,
81
- role: options?.role,
88
+ replicate: options?.replicate,
82
89
  replicas: options?.replicas,
83
90
  sync: (entry) => {
84
91
  // here we arrive when ever a insertion/pruning behaviour processes an entry
85
92
  // returning true means that it should persist
86
93
  return this._manuallySynced.has(entry.gid);
87
- }
94
+ },
88
95
  });
89
96
  }
90
97
  async recover() {
@@ -96,26 +103,43 @@ let Documents = class Documents extends Program {
96
103
  (await Entry.fromMultihash(this.log.log.blocks, history))
97
104
  : history;
98
105
  }
99
- async updateRole(role) {
100
- await this.log.updateRole(role);
101
- }
102
- get role() {
103
- return this.log.role;
104
- }
105
- async canAppend(entry) {
106
- const l0 = await this._canAppend(entry);
106
+ async canAppend(entry, reference) {
107
+ const l0 = await this._canAppend(entry, reference);
107
108
  if (!l0) {
108
109
  return false;
109
110
  }
110
111
  try {
111
- const payload = await entry.getPayloadValue();
112
- if (payload instanceof PutOperation) {
113
- payload.getValue(this.index.valueEncoding); // Decode they value so callbacks can jsut do .value
112
+ let operation = l0;
113
+ let document = reference?.document;
114
+ if (!document) {
115
+ if (l0 instanceof PutOperation) {
116
+ document = this._index.valueEncoding.decoder(l0.data);
117
+ if (!document) {
118
+ return false;
119
+ }
120
+ }
121
+ else if (l0 instanceof DeleteOperation) {
122
+ // Nothing to do here by default
123
+ // checking if the document exists is not necessary
124
+ // since it might already be deleted
125
+ }
126
+ else {
127
+ throw new Error("Unsupported operation");
128
+ }
114
129
  }
115
130
  if (this._optionCanPerform) {
116
- if (!(await this._optionCanPerform(payload, {
117
- entry
118
- }))) {
131
+ if (!(await this._optionCanPerform(operation instanceof PutOperation
132
+ ? {
133
+ type: "put",
134
+ value: document,
135
+ operation,
136
+ entry: entry,
137
+ }
138
+ : {
139
+ type: "delete",
140
+ operation,
141
+ entry: entry,
142
+ }))) {
119
143
  return false;
120
144
  }
121
145
  }
@@ -129,7 +153,7 @@ let Documents = class Documents extends Program {
129
153
  }
130
154
  return true;
131
155
  }
132
- async _canAppend(entry) {
156
+ async _canAppend(entry, reference) {
133
157
  const resolve = async (history) => {
134
158
  return typeof history === "string"
135
159
  ? this.log.log.get(history) ||
@@ -153,18 +177,22 @@ let Documents = class Documents extends Program {
153
177
  try {
154
178
  entry.init({
155
179
  encoding: this.log.log.encoding,
156
- keychain: this.node.services.keychain
180
+ keychain: this.node.services.keychain,
157
181
  });
158
- const operation = entry._payload instanceof DecryptedThing
182
+ const operation = reference?.operation || entry._payload instanceof DecryptedThing
159
183
  ? entry.payload.getValue(entry.encoding)
160
184
  : await entry.getPayloadValue();
161
185
  if (operation instanceof PutOperation) {
162
186
  // check nexts
163
187
  const putOperation = operation;
164
- const key = this._index.indexByResolver(putOperation.getValue(this.index.valueEncoding));
165
- checkKeyable(key);
166
- const existingDocument = this.index.index.get(asString(key));
167
- if (existingDocument) {
188
+ let value = reference?.document ??
189
+ this.index.valueEncoding.decoder(putOperation.data);
190
+ const keyValue = this.idResolver(value);
191
+ const key = indexerTypes.toId(keyValue);
192
+ const existingDocument = (await this.index.getDetailed(key))?.[0]
193
+ ?.results[0];
194
+ if (existingDocument && existingDocument.context.head !== entry.hash) {
195
+ // econd condition can false if we reset the operation log, while not resetting the index. For example when doing .recover
168
196
  if (this.immutable) {
169
197
  //Key already exist and this instance Documents can note overrite/edit'
170
198
  return false;
@@ -177,7 +205,8 @@ let Documents = class Documents extends Program {
177
205
  logger.error("Failed to find Document from head");
178
206
  return false;
179
207
  }
180
- return pointsToHistory(doc);
208
+ const referenceHistoryCorrectly = await pointsToHistory(doc);
209
+ return referenceHistoryCorrectly ? putOperation : false;
181
210
  }
182
211
  else {
183
212
  if (entry.next.length !== 0) {
@@ -189,18 +218,26 @@ let Documents = class Documents extends Program {
189
218
  if (entry.next.length !== 1) {
190
219
  return false;
191
220
  }
192
- const existingDocument = this._index.index.get(operation.key);
221
+ const existingDocument = (await this.index.getDetailed(operation.key))?.[0].results[0];
193
222
  if (!existingDocument) {
194
223
  // already deleted
195
- return true; // assume ok
224
+ return operation; // assume ok
196
225
  }
197
226
  let doc = await this.log.log.get(existingDocument.context.head);
198
227
  if (!doc) {
199
228
  logger.error("Failed to find Document from head");
200
229
  return false;
201
230
  }
202
- return pointsToHistory(doc); // references the existing document
231
+ if (await pointsToHistory(doc)) {
232
+ // references the existing document
233
+ return operation;
234
+ }
235
+ return false;
203
236
  }
237
+ else {
238
+ throw new Error("Unsupported operation");
239
+ }
240
+ return operation;
204
241
  }
205
242
  catch (error) {
206
243
  if (error instanceof AccessError) {
@@ -212,144 +249,145 @@ let Documents = class Documents extends Program {
212
249
  }
213
250
  throw error;
214
251
  }
215
- return true;
216
252
  }
217
253
  async put(doc, options) {
218
- const key = this._index.indexByResolver(doc);
219
- checkKeyable(key);
254
+ const keyValue = this.idResolver(doc);
255
+ // type check the key
256
+ indexerTypes.checkId(keyValue);
220
257
  const ser = serialize(doc);
221
- if (ser.length > MAX_DOCUMENT_SIZE) {
222
- throw new Error(`Document is too large (${ser.length * 1e-6}) mb). Needs to be less than ${MAX_DOCUMENT_SIZE * 1e-6} mb`);
258
+ if (ser.length > MAX_BATCH_SIZE) {
259
+ throw new Error(`Document is too large (${ser.length * 1e-6}) mb). Needs to be less than ${MAX_BATCH_SIZE * 1e-6} mb`);
223
260
  }
224
261
  const existingDocument = options?.unique
225
262
  ? undefined
226
- : (await this._index.getDetailed(key, {
263
+ : (await this._index.getDetailed(keyValue, {
227
264
  local: true,
228
- remote: { sync: true } // only query remote if we know they exist
265
+ remote: { sync: true }, // only query remote if we know they exist
229
266
  }))?.[0]?.results[0];
230
- return this.log.append(new PutOperation({
231
- key: asString(key),
267
+ const operation = new PutOperation({
232
268
  data: ser,
233
- value: doc
234
- }), {
269
+ });
270
+ const appended = await this.log.append(operation, {
235
271
  ...options,
236
272
  meta: {
237
273
  next: existingDocument
238
274
  ? [await this._resolveEntry(existingDocument.context.head)]
239
275
  : [],
240
- ...options?.meta
241
- } //
276
+ ...options?.meta,
277
+ },
278
+ canAppend: (entry) => {
279
+ return this.canAppend(entry, { document: doc, operation });
280
+ },
281
+ onChange: (change) => {
282
+ return this.handleChanges(change, { document: doc, operation });
283
+ },
242
284
  });
285
+ return appended;
243
286
  }
244
- async del(key, options) {
287
+ async del(id, options) {
288
+ const key = indexerTypes.toId(id);
245
289
  const existing = (await this._index.getDetailed(key, {
246
290
  local: true,
247
- remote: { sync: true }
291
+ remote: { sync: true },
248
292
  }))?.[0]?.results[0];
249
293
  if (!existing) {
250
- throw new Error(`No entry with key '${key}' in the database`);
294
+ throw new Error(`No entry with key '${key.primitive}' in the database`);
251
295
  }
252
296
  return this.log.append(new DeleteOperation({
253
- key: asString(key)
297
+ key,
254
298
  }), {
255
299
  ...options,
256
300
  meta: {
257
301
  next: [await this._resolveEntry(existing.context.head)],
258
302
  type: EntryType.CUT,
259
- ...options?.meta
260
- }
261
- } //
262
- );
303
+ ...options?.meta,
304
+ },
305
+ });
263
306
  }
264
- async handleChanges(change) {
265
- const removed = [...(change.removed || [])];
307
+ async handleChanges(change, reference) {
308
+ const isAppendOperation = change?.added.length === 1 ? !!change.added[0] : false;
266
309
  const removedSet = new Map();
267
- for (const r of removed) {
310
+ for (const r of change.removed) {
268
311
  removedSet.set(r.hash, r);
269
312
  }
270
- const entries = [...change.added, ...(removed || [])]
271
- .sort(this.log.log.sortFn)
272
- .reverse(); // sort so we get newest to oldest
313
+ const sortedEntries = [
314
+ ...change.added,
315
+ ...((await Promise.all(change.removed.map((x) => x instanceof Entry ? x : this.log.log.entryIndex.get(x.hash)))) || []),
316
+ ]; // TODO assert sorting
317
+ /*
318
+ const sortedEntries = [...change.added, ...(removed || [])]
319
+ .sort(this.log.log.sortFn)
320
+ .reverse(); // sort so we get newest to oldest */
273
321
  // There might be a case where change.added and change.removed contains the same document id. Usaully because you use the "trim" option
274
322
  // in combination with inserting the same document. To mitigate this, we loop through the changes and modify the behaviour for this
275
- let visited = new Map();
276
- for (const item of entries) {
277
- const payload = item._payload instanceof DecryptedThing
278
- ? item.payload.getValue(item.encoding)
279
- : await item.getPayloadValue();
280
- let itemKey;
281
- if (payload instanceof PutOperation ||
282
- payload instanceof DeleteOperation) {
283
- itemKey = payload.key;
284
- }
285
- else {
286
- throw new Error("Unsupported operation type");
287
- }
288
- let arr = visited.get(itemKey);
289
- if (!arr) {
290
- arr = [];
291
- visited.set(itemKey, arr);
292
- }
293
- arr.push(item);
294
- }
295
323
  let documentsChanged = {
296
324
  added: [],
297
- removed: []
325
+ removed: [],
298
326
  };
299
- for (const [_key, entries] of visited) {
327
+ let modified = new Set();
328
+ for (const item of sortedEntries) {
329
+ if (!item)
330
+ continue;
300
331
  try {
301
- const item = entries[0];
302
332
  const payload = item._payload instanceof DecryptedThing
303
333
  ? item.payload.getValue(item.encoding)
304
334
  : await item.getPayloadValue();
305
335
  if (payload instanceof PutOperation && !removedSet.has(item.hash)) {
306
- const key = payload.key;
307
- let value = this.deserializeOrPass(payload);
336
+ let value = (isAppendOperation &&
337
+ reference?.operation === payload &&
338
+ reference?.document) ||
339
+ this.index.valueEncoding.decoder(payload.data);
340
+ // get index key from value
341
+ const keyObject = this.idResolver(value);
342
+ const key = indexerTypes.toId(keyObject);
343
+ // document is already updated with more recent entry
344
+ if (modified.has(key.primitive)) {
345
+ continue;
346
+ }
308
347
  // Program specific
309
348
  if (value instanceof Program) {
310
349
  // if replicator, then open
311
350
  if ((await this.canOpen(value, item)) &&
312
- this.log.role instanceof Replicator &&
313
- (await this.log.replicator(item)) // TODO types, throw runtime error if replicator is not provided
351
+ (await this.log.isReplicator(item)) // TODO types, throw runtime error if replicator is not provided
314
352
  ) {
315
353
  value = (await this.node.open(value, {
316
354
  parent: this,
317
- existing: "reuse"
355
+ existing: "reuse",
318
356
  })); // TODO types
319
357
  }
320
358
  }
321
359
  documentsChanged.added.push(value);
322
- const context = new Context({
323
- created: this._index.index.get(key)?.context.created ||
324
- item.meta.clock.timestamp.wallTime,
325
- modified: item.meta.clock.timestamp.wallTime,
326
- head: item.hash,
327
- gid: item.gid
328
- });
329
- const valueToIndex = this._index.toIndex(value, context);
330
- this._index.index.set(key, {
331
- key: payload.key,
332
- value: isPromise(valueToIndex) ? await valueToIndex : valueToIndex,
333
- context,
334
- reference: valueToIndex === value || value instanceof Program
335
- ? { value, last: payload }
336
- : undefined
337
- });
360
+ await this._index.put(value, item, key);
361
+ modified.add(key.primitive);
338
362
  }
339
363
  else if ((payload instanceof DeleteOperation && !removedSet.has(item.hash)) ||
340
364
  payload instanceof PutOperation ||
341
365
  removedSet.has(item.hash)) {
342
366
  this._manuallySynced.delete(item.gid);
343
- const key = payload.key;
344
- if (!this.index.index.has(key)) {
345
- continue;
346
- }
347
367
  let value;
368
+ let key;
348
369
  if (payload instanceof PutOperation) {
349
- value = this.deserializeOrPass(payload);
370
+ value = this.index.valueEncoding.decoder(payload.data);
371
+ key = indexerTypes.toId(this.idResolver(value));
372
+ // document is already updated with more recent entry
373
+ if (modified.has(key.primitive)) {
374
+ continue;
375
+ }
350
376
  }
351
377
  else if (payload instanceof DeleteOperation) {
352
- value = await this.getDocumentFromEntry(entries[1]);
378
+ key = payload.key;
379
+ // document is already updated with more recent entry
380
+ if (modified.has(key.primitive)) {
381
+ continue;
382
+ }
383
+ const document = await this._index.get(key, {
384
+ local: true,
385
+ remote: false,
386
+ });
387
+ if (!document) {
388
+ continue;
389
+ }
390
+ value = document;
353
391
  }
354
392
  else {
355
393
  throw new Error("Unexpected");
@@ -359,10 +397,12 @@ let Documents = class Documents extends Program {
359
397
  await value.drop(this);
360
398
  }
361
399
  // update index
362
- this._index.index.delete(key);
400
+ await this._index.del(key);
401
+ modified.add(key.primitive);
363
402
  }
364
403
  else {
365
404
  // Unknown operation
405
+ throw new OperationError("Unknown operation");
366
406
  }
367
407
  }
368
408
  catch (error) {
@@ -374,22 +414,6 @@ let Documents = class Documents extends Program {
374
414
  }
375
415
  this.events.dispatchEvent(new CustomEvent("change", { detail: documentsChanged }));
376
416
  }
377
- async getDocumentFromEntry(entry) {
378
- const payloadValue = await entry.getPayloadValue();
379
- if (payloadValue instanceof PutOperation) {
380
- return payloadValue.getValue(this.index.valueEncoding);
381
- }
382
- throw new Error("Unexpected");
383
- }
384
- deserializeOrPass(value) {
385
- if (value._value) {
386
- return value._value;
387
- }
388
- else {
389
- value._value = deserialize(value.data, this.index.type);
390
- return value._value;
391
- }
392
- }
393
417
  };
394
418
  __decorate([
395
419
  field({ type: SharedLog }),
@@ -408,7 +432,4 @@ Documents = __decorate([
408
432
  __metadata("design:paramtypes", [Object])
409
433
  ], Documents);
410
434
  export { Documents };
411
- function isPromise(value) {
412
- return Boolean(value && typeof value.then === "function");
413
- }
414
- //# sourceMappingURL=document-store.js.map
435
+ //# sourceMappingURL=program.js.map