@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.
- package/README.md +2 -2
- package/dist/benchmark/index.d.ts +2 -0
- package/dist/benchmark/index.d.ts.map +1 -0
- package/dist/benchmark/index.js +125 -0
- package/dist/benchmark/index.js.map +1 -0
- package/dist/benchmark/memory/index.d.ts +2 -0
- package/dist/benchmark/memory/index.d.ts.map +1 -0
- package/dist/benchmark/memory/index.js +122 -0
- package/dist/benchmark/memory/index.js.map +1 -0
- package/dist/benchmark/memory/insert.d.ts +2 -0
- package/dist/benchmark/memory/insert.d.ts.map +1 -0
- package/dist/benchmark/memory/insert.js +133 -0
- package/dist/benchmark/memory/insert.js.map +1 -0
- package/dist/benchmark/memory/utils.d.ts +13 -0
- package/dist/benchmark/memory/utils.d.ts.map +1 -0
- package/dist/benchmark/memory/utils.js +2 -0
- package/dist/benchmark/memory/utils.js.map +1 -0
- package/dist/benchmark/replication.d.ts +2 -0
- package/dist/benchmark/replication.d.ts.map +1 -0
- package/dist/benchmark/replication.js +172 -0
- package/dist/benchmark/replication.js.map +1 -0
- package/dist/src/borsh.d.ts +2 -0
- package/dist/src/borsh.d.ts.map +1 -0
- package/dist/src/borsh.js +16 -0
- package/dist/src/borsh.js.map +1 -0
- package/dist/src/constants.d.ts +2 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +2 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/program.d.ts +87 -0
- package/dist/src/program.d.ts.map +1 -0
- package/{lib/esm/document-store.js → dist/src/program.js} +159 -138
- package/dist/src/program.js.map +1 -0
- package/dist/src/search.d.ts +132 -0
- package/dist/src/search.d.ts.map +1 -0
- package/dist/src/search.js +845 -0
- package/dist/src/search.js.map +1 -0
- package/package.json +74 -43
- package/src/borsh.ts +19 -0
- package/src/constants.ts +1 -0
- package/src/index.ts +3 -3
- package/src/program.ts +580 -0
- package/src/search.ts +1217 -0
- package/LICENSE +0 -202
- package/lib/esm/document-index.d.ts +0 -147
- package/lib/esm/document-index.js +0 -942
- package/lib/esm/document-index.js.map +0 -1
- package/lib/esm/document-store.d.ts +0 -72
- package/lib/esm/document-store.js.map +0 -1
- package/lib/esm/index.d.ts +0 -3
- package/lib/esm/index.js +0 -4
- package/lib/esm/index.js.map +0 -1
- package/lib/esm/query.d.ts +0 -191
- package/lib/esm/query.js +0 -615
- package/lib/esm/query.js.map +0 -1
- package/lib/esm/utils.d.ts +0 -3
- package/lib/esm/utils.js +0 -12
- package/lib/esm/utils.js.map +0 -1
- package/src/document-index.ts +0 -1268
- package/src/document-store.ts +0 -547
- package/src/query.ts +0 -525
- 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 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,UAAM,CAAC"}
|
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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,
|
|
11
|
-
import {
|
|
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 {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
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
|
-
|
|
61
|
-
|
|
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
|
-
|
|
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
|
|
100
|
-
await this.
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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(
|
|
117
|
-
|
|
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
|
-
|
|
165
|
-
|
|
166
|
-
const
|
|
167
|
-
|
|
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
|
-
|
|
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.
|
|
221
|
+
const existingDocument = (await this.index.getDetailed(operation.key))?.[0].results[0];
|
|
193
222
|
if (!existingDocument) {
|
|
194
223
|
// already deleted
|
|
195
|
-
return
|
|
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
|
-
|
|
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
|
|
219
|
-
|
|
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 >
|
|
222
|
-
throw new Error(`Document is too large (${ser.length * 1e-6}) mb). Needs to be less than ${
|
|
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(
|
|
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
|
-
|
|
231
|
-
key: asString(key),
|
|
267
|
+
const operation = new PutOperation({
|
|
232
268
|
data: ser,
|
|
233
|
-
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
271
|
-
.
|
|
272
|
-
.
|
|
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
|
-
|
|
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
|
-
|
|
307
|
-
|
|
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.
|
|
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
|
-
|
|
323
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
412
|
-
return Boolean(value && typeof value.then === "function");
|
|
413
|
-
}
|
|
414
|
-
//# sourceMappingURL=document-store.js.map
|
|
435
|
+
//# sourceMappingURL=program.js.map
|