@peerbit/indexer-interface 0.0.1-cccc078
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/dist/src/id.d.ts +47 -0
- package/dist/src/id.d.ts.map +1 -0
- package/dist/src/id.js +203 -0
- package/dist/src/id.js.map +1 -0
- package/dist/src/index-engine.d.ts +83 -0
- package/dist/src/index-engine.d.ts.map +1 -0
- package/dist/src/index-engine.js +106 -0
- package/dist/src/index-engine.js.map +1 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +6 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/query.d.ts +170 -0
- package/dist/src/query.d.ts.map +1 -0
- package/dist/src/query.js +579 -0
- package/dist/src/query.js.map +1 -0
- package/dist/src/store.d.ts +7 -0
- package/dist/src/store.d.ts.map +1 -0
- package/dist/src/store.js +2 -0
- package/dist/src/store.js.map +1 -0
- package/dist/src/utils.d.ts +9 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/utils.js +88 -0
- package/dist/src/utils.js.map +1 -0
- package/package.json +65 -0
- package/src/id.ts +191 -0
- package/src/index-engine.ts +213 -0
- package/src/index.ts +5 -0
- package/src/query.ts +549 -0
- package/src/store.ts +5 -0
- package/src/utils.ts +115 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { field, getSchema, } from "@dao-xyz/borsh";
|
|
2
|
+
import { SortDirection } from "./query.js";
|
|
3
|
+
export const stringArraysEquals = (a, b) => {
|
|
4
|
+
if (a.length !== b.length) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
for (let i = 0; i < a.length; i++) {
|
|
8
|
+
if (a[i] !== b[i]) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return true;
|
|
13
|
+
};
|
|
14
|
+
/* export const resolvedSort = async <
|
|
15
|
+
Q extends { indexed: Record<string, any> }
|
|
16
|
+
>(
|
|
17
|
+
arr: Q[],
|
|
18
|
+
sorts: Sort[],
|
|
19
|
+
aliases?: Map<string, string>
|
|
20
|
+
) => {
|
|
21
|
+
arr.sort((a, b) => extractSortCompare(a.indexed, b.indexed, sorts));
|
|
22
|
+
return arr;
|
|
23
|
+
};
|
|
24
|
+
*/
|
|
25
|
+
export const extractSortCompare = (a, b, sorts, aliases) => {
|
|
26
|
+
for (const sort of sorts) {
|
|
27
|
+
const av = extractFieldValue(a, sort.key, aliases);
|
|
28
|
+
const bv = extractFieldValue(b, sort.key, aliases);
|
|
29
|
+
const cmp = sortCompare(av, bv);
|
|
30
|
+
if (cmp !== 0) {
|
|
31
|
+
if (sort.direction === SortDirection.ASC) {
|
|
32
|
+
return cmp;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
return -cmp;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return 0;
|
|
40
|
+
};
|
|
41
|
+
export const sortCompare = (av, bv) => {
|
|
42
|
+
if (typeof av === "string" && typeof bv === "string") {
|
|
43
|
+
return av.localeCompare(bv);
|
|
44
|
+
}
|
|
45
|
+
if (av < bv) {
|
|
46
|
+
return -1;
|
|
47
|
+
}
|
|
48
|
+
else if (av > bv) {
|
|
49
|
+
return 1;
|
|
50
|
+
}
|
|
51
|
+
return 0;
|
|
52
|
+
};
|
|
53
|
+
export const extractFieldValue = (doc, path, aliases) => {
|
|
54
|
+
for (let i = 0; i < path.length; i++) {
|
|
55
|
+
doc = doc[aliases?.get(path[i]) || path[i]];
|
|
56
|
+
}
|
|
57
|
+
return doc;
|
|
58
|
+
};
|
|
59
|
+
const INDEXED_ID_META_PROPERY = "_index_id";
|
|
60
|
+
export function id(properties) {
|
|
61
|
+
const innerFn = field(properties);
|
|
62
|
+
return (target, name) => {
|
|
63
|
+
innerFn(target, name);
|
|
64
|
+
target.constructor[INDEXED_ID_META_PROPERY] = name;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export const getIdProperty = (clazz) => {
|
|
68
|
+
// TODO nested id property
|
|
69
|
+
const property = clazz[INDEXED_ID_META_PROPERY];
|
|
70
|
+
if (!property) {
|
|
71
|
+
// look into children
|
|
72
|
+
const fields = getSchema(clazz)?.fields;
|
|
73
|
+
if (!fields) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
for (const field of fields) {
|
|
77
|
+
if (typeof field.type === "function") {
|
|
78
|
+
const idFromChild = getIdProperty(field.type);
|
|
79
|
+
if (idFromChild) {
|
|
80
|
+
return [field.key, ...idFromChild];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
return [property];
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@peerbit/indexer-interface",
|
|
3
|
+
"version": "0.0.1-cccc078",
|
|
4
|
+
"description": "Indexer store interface",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "./dist/src/index.d.ts",
|
|
8
|
+
"typesVersions": {
|
|
9
|
+
"*": {
|
|
10
|
+
"*": [
|
|
11
|
+
"*",
|
|
12
|
+
"dist/*",
|
|
13
|
+
"dist/src/*",
|
|
14
|
+
"dist/src/*/index"
|
|
15
|
+
],
|
|
16
|
+
"src/*": [
|
|
17
|
+
"*",
|
|
18
|
+
"dist/*",
|
|
19
|
+
"dist/src/*",
|
|
20
|
+
"dist/src/*/index"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"src",
|
|
26
|
+
"dist",
|
|
27
|
+
"!dist/e2e",
|
|
28
|
+
"!dist/test",
|
|
29
|
+
"!**/*.tsbuildinfo"
|
|
30
|
+
],
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/src/index.d.ts",
|
|
34
|
+
"import": "./dist/src/index.js"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"eslintConfig": {
|
|
38
|
+
"extends": "peerbit",
|
|
39
|
+
"parserOptions": {
|
|
40
|
+
"project": true,
|
|
41
|
+
"sourceType": "module"
|
|
42
|
+
},
|
|
43
|
+
"ignorePatterns": [
|
|
44
|
+
"!.aegir.js",
|
|
45
|
+
"test/ts-use",
|
|
46
|
+
"*.d.ts"
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"access": "public"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"clean": "aegir clean",
|
|
54
|
+
"build": "aegir build --no-bundle",
|
|
55
|
+
"test": "aegir test",
|
|
56
|
+
"lint": "aegir lint"
|
|
57
|
+
},
|
|
58
|
+
"author": "dao.xyz",
|
|
59
|
+
"license": "MIT",
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"uuid": "^9.0.0",
|
|
62
|
+
"@dao-xyz/borsh": "^5.2.3",
|
|
63
|
+
"@peerbit/crypto": "2.2.0-cccc078"
|
|
64
|
+
}
|
|
65
|
+
}
|
package/src/id.ts
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { field, variant } from "@dao-xyz/borsh";
|
|
2
|
+
import { toBase64 } from "@peerbit/crypto";
|
|
3
|
+
import {
|
|
4
|
+
decodeUint8Array,
|
|
5
|
+
encodeUint8Array,
|
|
6
|
+
encodingLength,
|
|
7
|
+
} from "uint8-varint";
|
|
8
|
+
|
|
9
|
+
export abstract class PrimitiveValue {}
|
|
10
|
+
|
|
11
|
+
@variant(0)
|
|
12
|
+
export class StringValue extends PrimitiveValue {
|
|
13
|
+
@field({ type: "string" })
|
|
14
|
+
string: string;
|
|
15
|
+
|
|
16
|
+
constructor(string: string) {
|
|
17
|
+
super();
|
|
18
|
+
this.string = string;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@variant(1)
|
|
23
|
+
export abstract class NumberValue extends PrimitiveValue {
|
|
24
|
+
abstract get value(): number | bigint;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@variant(0)
|
|
28
|
+
export abstract class IntegerValue extends NumberValue {}
|
|
29
|
+
|
|
30
|
+
@variant(0)
|
|
31
|
+
export class UnsignedIntegerValue extends IntegerValue {
|
|
32
|
+
@field({ type: "u32" })
|
|
33
|
+
number: number;
|
|
34
|
+
|
|
35
|
+
constructor(number: number) {
|
|
36
|
+
super();
|
|
37
|
+
if (!Number.isInteger(number) || number > 4294967295 || number < 0) {
|
|
38
|
+
throw new Error("Number is not u32");
|
|
39
|
+
}
|
|
40
|
+
this.number = number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get value() {
|
|
44
|
+
return this.number;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@variant(1)
|
|
49
|
+
export class BigUnsignedIntegerValue extends IntegerValue {
|
|
50
|
+
@field({ type: "u64" })
|
|
51
|
+
number: bigint;
|
|
52
|
+
|
|
53
|
+
constructor(number: bigint) {
|
|
54
|
+
super();
|
|
55
|
+
if (number > 18446744073709551615n || number < 0) {
|
|
56
|
+
throw new Error("Number is not u32");
|
|
57
|
+
}
|
|
58
|
+
this.number = number;
|
|
59
|
+
}
|
|
60
|
+
get value() {
|
|
61
|
+
return this.number;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type IdPrimitive = string | number | bigint;
|
|
66
|
+
|
|
67
|
+
export abstract class IdKey {
|
|
68
|
+
abstract get key(): string | bigint | number | Uint8Array;
|
|
69
|
+
abstract get primitive(): IdPrimitive;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@variant(0)
|
|
73
|
+
export class StringKey extends IdKey {
|
|
74
|
+
@field({ type: "string" })
|
|
75
|
+
key: string;
|
|
76
|
+
|
|
77
|
+
constructor(key: string) {
|
|
78
|
+
super();
|
|
79
|
+
this.key = key;
|
|
80
|
+
}
|
|
81
|
+
get primitive() {
|
|
82
|
+
return this.key;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@variant(1)
|
|
87
|
+
export class Uint8ArrayKey extends IdKey {
|
|
88
|
+
@field({ type: Uint8Array })
|
|
89
|
+
key: Uint8Array;
|
|
90
|
+
|
|
91
|
+
constructor(key: Uint8Array) {
|
|
92
|
+
super();
|
|
93
|
+
this.key = key;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private _keyString: string;
|
|
97
|
+
get primitive(): string {
|
|
98
|
+
return this._keyString || (this._keyString = toBase64(this.key));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const varint53 = {
|
|
103
|
+
deserialize: (reader: any) => {
|
|
104
|
+
const number = decodeUint8Array(reader._buf, reader._offset);
|
|
105
|
+
const len = encodingLength(number);
|
|
106
|
+
reader._offset += len;
|
|
107
|
+
return number;
|
|
108
|
+
},
|
|
109
|
+
serialize: (value: any, writer: any) => {
|
|
110
|
+
const offset = writer.totalSize;
|
|
111
|
+
writer["_writes"] = writer["_writes"].next = () =>
|
|
112
|
+
encodeUint8Array(value, writer["_buf"], offset);
|
|
113
|
+
writer.totalSize += encodingLength(value);
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
@variant(2)
|
|
118
|
+
export class IntegerKey extends IdKey {
|
|
119
|
+
@field(varint53) // max value is 2^53 - 1 (9007199254740991)
|
|
120
|
+
key: number;
|
|
121
|
+
|
|
122
|
+
constructor(key: number) {
|
|
123
|
+
super();
|
|
124
|
+
this.key = key;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
get primitive() {
|
|
128
|
+
return this.key;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export type Ideable = string | number | bigint | Uint8Array;
|
|
133
|
+
|
|
134
|
+
const idKeyTypes = new Set(["string", "number", "bigint"]);
|
|
135
|
+
|
|
136
|
+
export const toId = (obj: Ideable): IdKey => {
|
|
137
|
+
if (typeof obj === "string") {
|
|
138
|
+
return new StringKey(obj);
|
|
139
|
+
}
|
|
140
|
+
if (typeof obj === "number") {
|
|
141
|
+
return new IntegerKey(obj);
|
|
142
|
+
}
|
|
143
|
+
if (typeof obj === "bigint") {
|
|
144
|
+
if (obj <= Number.MAX_SAFE_INTEGER && obj >= 0) {
|
|
145
|
+
return new IntegerKey(Number(obj));
|
|
146
|
+
}
|
|
147
|
+
throw new Error(
|
|
148
|
+
"BigInt is not less than 2^53. Max value is 9007199254740991",
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
if (obj instanceof Uint8Array) {
|
|
152
|
+
return new Uint8ArrayKey(obj);
|
|
153
|
+
}
|
|
154
|
+
throw new Error(
|
|
155
|
+
"Unexpected index key: " +
|
|
156
|
+
typeof obj +
|
|
157
|
+
", expected: string, number, bigint or Uint8Array",
|
|
158
|
+
);
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export const toIdeable = (
|
|
162
|
+
key: IdKey | Ideable,
|
|
163
|
+
): string | number | bigint | Uint8Array => {
|
|
164
|
+
if (key instanceof IdKey) {
|
|
165
|
+
return key.key;
|
|
166
|
+
}
|
|
167
|
+
return key;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export const checkId = (obj: Ideable) => {
|
|
171
|
+
if (obj == null) {
|
|
172
|
+
throw new Error(
|
|
173
|
+
`The provided key value is null or undefined, expecting string, number, bigint, or Uint8array`,
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
const type = typeof obj;
|
|
177
|
+
|
|
178
|
+
if (type === "number") {
|
|
179
|
+
if (!Number.isInteger(obj)) {
|
|
180
|
+
throw new Error(`The provided key number value is not an integer`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (idKeyTypes.has(type) || obj instanceof Uint8Array) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
throw new Error(
|
|
189
|
+
`Key is not ${[...idKeyTypes]}, provided key value type: ${typeof obj}`,
|
|
190
|
+
);
|
|
191
|
+
};
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import type { AbstractType } from "@dao-xyz/borsh";
|
|
2
|
+
import { type IdKey } from "./id.js";
|
|
3
|
+
import {
|
|
4
|
+
CloseIteratorRequest,
|
|
5
|
+
CollectNextRequest,
|
|
6
|
+
type CountRequest,
|
|
7
|
+
type DeleteRequest,
|
|
8
|
+
type SearchRequest,
|
|
9
|
+
type SumRequest,
|
|
10
|
+
} from "./query.js";
|
|
11
|
+
|
|
12
|
+
type MaybePromise<T = void> = Promise<T> | T;
|
|
13
|
+
|
|
14
|
+
export interface IndexedResult<
|
|
15
|
+
T extends Record<string, any> = Record<string, any>,
|
|
16
|
+
> {
|
|
17
|
+
id: IdKey;
|
|
18
|
+
value: T;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface IndexedResults<
|
|
22
|
+
T extends Record<string, any> = Record<string, any>,
|
|
23
|
+
> {
|
|
24
|
+
results: IndexedResult<T>[];
|
|
25
|
+
kept: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface IndexedValue<T = Record<string, any>> {
|
|
29
|
+
id: IdKey;
|
|
30
|
+
value: T;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type NestedProperties<T> = {
|
|
34
|
+
match: (obj: any) => obj is T;
|
|
35
|
+
query: (nested: T, query: SearchRequest) => Promise<Record<string, any>[]>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type IteratorBatchProperties = {
|
|
39
|
+
maxSize: number;
|
|
40
|
+
sizeProperty: string[];
|
|
41
|
+
};
|
|
42
|
+
export type IndexEngineInitProperties<T, N> = {
|
|
43
|
+
indexBy?: string[];
|
|
44
|
+
nested?: NestedProperties<N>;
|
|
45
|
+
schema: AbstractType<T>;
|
|
46
|
+
/* iterator: { batch: IteratorBatchProperties }; */
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/* type ResolveOptions = 'match' | 'full';
|
|
50
|
+
export type QueryOptions = { resolve: ResolveOptions };
|
|
51
|
+
export type ReturnTypeFromQueryOptions<T, O> = O extends { resolve: 'full' } ? T : Partial<T>;
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
export type Shape = { [key: string]: true | Shape };
|
|
55
|
+
export interface Index<T extends Record<string, any>, NestedType = any> {
|
|
56
|
+
init(
|
|
57
|
+
properties: IndexEngineInitProperties<T, NestedType>,
|
|
58
|
+
): MaybePromise<Index<T, NestedType>>;
|
|
59
|
+
drop(): MaybePromise<void>;
|
|
60
|
+
get(
|
|
61
|
+
id: IdKey,
|
|
62
|
+
options?: { shape: Shape },
|
|
63
|
+
): MaybePromise<IndexedResult<T> | undefined>;
|
|
64
|
+
put(value: T, id?: IdKey): MaybePromise<void>;
|
|
65
|
+
del(query: DeleteRequest): MaybePromise<IdKey[]>;
|
|
66
|
+
sum(query: SumRequest): MaybePromise<bigint | number>;
|
|
67
|
+
count(query: CountRequest): MaybePromise<number>;
|
|
68
|
+
query(
|
|
69
|
+
query: SearchRequest,
|
|
70
|
+
options?: { shape?: Shape; reference?: boolean },
|
|
71
|
+
): MaybePromise<IndexedResults<T>>;
|
|
72
|
+
next(
|
|
73
|
+
query: CollectNextRequest,
|
|
74
|
+
options?: { shape?: Shape },
|
|
75
|
+
): MaybePromise<IndexedResults<T>>;
|
|
76
|
+
close(query: CloseIteratorRequest): MaybePromise<void>;
|
|
77
|
+
|
|
78
|
+
/*
|
|
79
|
+
query<O extends QueryOptions>(query: SearchRequest, options?: O): MaybePromise<IndexedResults<ReturnTypeFromQueryOptions<T, O>>>;
|
|
80
|
+
next<O extends QueryOptions>(query: CollectNextRequest, options?: O): MaybePromise<IndexedResults<ReturnTypeFromQueryOptions<T, O>>>;
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
getSize(): MaybePromise<number>;
|
|
84
|
+
getPending(cursorId: string): number | undefined;
|
|
85
|
+
start(): MaybePromise<void>;
|
|
86
|
+
stop(): MaybePromise<void>;
|
|
87
|
+
get cursorCount(): number;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export type IndexIterator<T> = ReturnType<typeof iterate<T>>;
|
|
91
|
+
export const iterate = <T>(index: Index<T, any>, query: SearchRequest) => {
|
|
92
|
+
let isDone = false;
|
|
93
|
+
let fetchedOnce = false;
|
|
94
|
+
const next = async (count: number, options?: { shape?: Shape }) => {
|
|
95
|
+
let res: IndexedResults<T>;
|
|
96
|
+
if (!fetchedOnce) {
|
|
97
|
+
fetchedOnce = true;
|
|
98
|
+
query.fetch = count;
|
|
99
|
+
res = await index.query(query, options);
|
|
100
|
+
} else {
|
|
101
|
+
res = await index.next(
|
|
102
|
+
new CollectNextRequest({ id: query.id, amount: count }),
|
|
103
|
+
options,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
isDone = res.kept === 0;
|
|
107
|
+
return res;
|
|
108
|
+
};
|
|
109
|
+
const done = () => isDone;
|
|
110
|
+
const close = () => {
|
|
111
|
+
return index.close(new CloseIteratorRequest({ id: query.id }));
|
|
112
|
+
};
|
|
113
|
+
return {
|
|
114
|
+
next,
|
|
115
|
+
done,
|
|
116
|
+
close,
|
|
117
|
+
all: async (options?: { shape: Shape }) => {
|
|
118
|
+
const results: IndexedResult<T>[] = [];
|
|
119
|
+
while (!done()) {
|
|
120
|
+
for (const element of (await next(100, options)).results) {
|
|
121
|
+
results.push(element);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
await close();
|
|
125
|
+
return results;
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export type ResultsIterator<T> = ReturnType<typeof iterate<T>>;
|
|
131
|
+
|
|
132
|
+
export const iteratorInSeries = <T>(...iterators: IndexIterator<T>[]) => {
|
|
133
|
+
let i = 0;
|
|
134
|
+
const done = () => i >= iterators.length;
|
|
135
|
+
let current = iterators[i];
|
|
136
|
+
const next = async (count: number) => {
|
|
137
|
+
let acc: IndexedResults<T> = {
|
|
138
|
+
kept: 0,
|
|
139
|
+
results: [],
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
while (!current.done() && i < iterators.length) {
|
|
143
|
+
const next = await current.next(count);
|
|
144
|
+
acc.kept += next.kept;
|
|
145
|
+
acc.results.push(...next.results);
|
|
146
|
+
|
|
147
|
+
if (current.done()) {
|
|
148
|
+
i++;
|
|
149
|
+
if (i >= iterators.length) {
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
current = iterators[i];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (acc.results.length >= count) {
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return acc;
|
|
161
|
+
};
|
|
162
|
+
return {
|
|
163
|
+
next,
|
|
164
|
+
done,
|
|
165
|
+
close: async () => {
|
|
166
|
+
for (const iterator of iterators) {
|
|
167
|
+
await iterator.close();
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
all: async () => {
|
|
171
|
+
const results = [];
|
|
172
|
+
while (!done()) {
|
|
173
|
+
for (const element of (await next(100)).results) {
|
|
174
|
+
results.push(element);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return results;
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
export interface Indices {
|
|
183
|
+
init<T extends Record<string, any>, NestedType>(
|
|
184
|
+
properties: IndexEngineInitProperties<T, NestedType>,
|
|
185
|
+
): MaybePromise<Index<T, NestedType>>;
|
|
186
|
+
scope(name: string): MaybePromise<Indices>;
|
|
187
|
+
start(): MaybePromise<void>;
|
|
188
|
+
stop(): MaybePromise<void>;
|
|
189
|
+
drop(): MaybePromise<void>;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* export interface IndexEngine<T extends Record<string, any> = Record<string, any>, NestedType = any> {
|
|
193
|
+
init(properties: IndexEngineInitProperties<NestedType>): MaybePromise<void>
|
|
194
|
+
start?(): MaybePromise<void>;
|
|
195
|
+
stop?(): MaybePromise<void>;
|
|
196
|
+
clear(): MaybePromise<void>;
|
|
197
|
+
scope: <TS extends Record<string, any> = Record<string, any>>(name: string) => MaybePromise<IndexEngine<TS>>;
|
|
198
|
+
get(
|
|
199
|
+
id: IdKey
|
|
200
|
+
): MaybePromise<IndexedResult<T> | undefined>;
|
|
201
|
+
put(value: IndexedValue<T>): MaybePromise<void>;
|
|
202
|
+
del(id: IdKey): MaybePromise<void>;
|
|
203
|
+
sum(query: SumRequest): MaybePromise<number>;
|
|
204
|
+
count(query: CountRequest): MaybePromise<number>;
|
|
205
|
+
query(query: SearchRequest, from: PublicSignKey): MaybePromise<IndexedResults<T>>;
|
|
206
|
+
next(query: CollectNextRequest, from: PublicSignKey): MaybePromise<IndexedResults<T>>;
|
|
207
|
+
close(query: CloseIteratorRequest, from: PublicSignKey): MaybePromise<void>;
|
|
208
|
+
getSize(): MaybePromise<number>;
|
|
209
|
+
getPending(cursorId: string): number | undefined;
|
|
210
|
+
get cursorCount(): number;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export type IndexEngineConstuctor<T extends Record<string, any>> = (directory?: string) => MaybePromise<IndexEngine<T, any>>; */
|