@xyo-network/diviner-payload-indexeddb 2.87.0-rc.2 → 2.87.0-rc.4
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/browser/Diviner.d.cts +7 -13
- package/dist/browser/Diviner.d.cts.map +1 -1
- package/dist/browser/Diviner.d.mts +7 -13
- package/dist/browser/Diviner.d.mts.map +1 -1
- package/dist/browser/Diviner.d.ts +7 -13
- package/dist/browser/Diviner.d.ts.map +1 -1
- package/dist/browser/index.cjs +41 -23
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +41 -23
- package/dist/browser/index.js.map +1 -1
- package/dist/node/Diviner.d.cts +7 -13
- package/dist/node/Diviner.d.cts.map +1 -1
- package/dist/node/Diviner.d.mts +7 -13
- package/dist/node/Diviner.d.mts.map +1 -1
- package/dist/node/Diviner.d.ts +7 -13
- package/dist/node/Diviner.d.ts.map +1 -1
- package/dist/node/index.cjs +41 -24
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.js +41 -24
- package/dist/node/index.js.map +1 -1
- package/package.json +15 -13
- package/src/Diviner.ts +50 -23
|
@@ -5,25 +5,19 @@ import { Payload } from '@xyo-network/payload-model';
|
|
|
5
5
|
import { IndexedDbPayloadDivinerParams } from './Params';
|
|
6
6
|
export declare class IndexedDbPayloadDiviner<TParams extends IndexedDbPayloadDivinerParams = IndexedDbPayloadDivinerParams, TIn extends PayloadDivinerQueryPayload = PayloadDivinerQueryPayload, TOut extends Payload = Payload, TEventData extends DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut> = DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut>> extends PayloadDiviner<TParams, TIn, TOut, TEventData> {
|
|
7
7
|
static configSchemas: string[];
|
|
8
|
-
static defaultDbName: string;
|
|
9
|
-
static defaultDbVersion: number;
|
|
10
|
-
static defaultStoreName: string;
|
|
11
8
|
private _db;
|
|
12
9
|
/**
|
|
13
|
-
* The database name. If not supplied via config it defaults
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
* The database name. If not supplied via config, it defaults
|
|
11
|
+
* to the archivist's name and if archivist's name is not supplied,
|
|
12
|
+
* it defaults to `archivist`. This behavior
|
|
13
|
+
* biases towards a single, isolated DB per archivist which seems to
|
|
14
|
+
* make the most sense for 99% of use cases.
|
|
17
15
|
*/
|
|
18
16
|
get dbName(): string;
|
|
19
17
|
/**
|
|
20
|
-
* The database version. If not supplied via config, it defaults to
|
|
18
|
+
* The database version. If not supplied via config, it defaults to the archivist default version.
|
|
21
19
|
*/
|
|
22
20
|
get dbVersion(): number;
|
|
23
|
-
/**
|
|
24
|
-
* The database indexes.
|
|
25
|
-
*/
|
|
26
|
-
get indexes(): import("@xyo-network/archivist-model").IndexDescription[];
|
|
27
21
|
/**
|
|
28
22
|
* The name of the object store. If not supplied via config, it defaults
|
|
29
23
|
* to `payloads`.
|
|
@@ -32,7 +26,7 @@ export declare class IndexedDbPayloadDiviner<TParams extends IndexedDbPayloadDiv
|
|
|
32
26
|
private get db();
|
|
33
27
|
protected divineHandler(payloads?: TIn[]): Promise<TOut[]>;
|
|
34
28
|
protected startHandler(): Promise<boolean>;
|
|
35
|
-
private
|
|
29
|
+
private getKeyRangeValue;
|
|
36
30
|
private selectBestIndex;
|
|
37
31
|
}
|
|
38
32
|
//# sourceMappingURL=Diviner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Diviner.d.ts","sourceRoot":"","sources":["../../src/Diviner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Diviner.d.ts","sourceRoot":"","sources":["../../src/Diviner.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAA;AACtE,OAAO,EAAgC,0BAA0B,EAAE,MAAM,oCAAoC,CAAA;AAG7G,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AAIpD,OAAO,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAA;AAoBxD,qBAAa,uBAAuB,CAClC,OAAO,SAAS,6BAA6B,GAAG,6BAA6B,EAC7E,GAAG,SAAS,0BAA0B,GAAG,0BAA0B,EACnE,IAAI,SAAS,OAAO,GAAG,OAAO,EAC9B,UAAU,SAAS,sBAAsB,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,sBAAsB,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CACxI,SAAQ,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC;IACtD,OAAgB,aAAa,WAAwC;IAErE,OAAO,CAAC,GAAG,CAAwC;IAEnD;;;;;;OAMG;IACH,IAAI,MAAM,WAET;IAED;;OAEG;IACH,IAAI,SAAS,WAEZ;IAED;;;OAGG;IACH,IAAI,SAAS,WAEZ;IAED,OAAO,KAAK,EAAE,GAEb;cAEwB,aAAa,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;cAuDhD,YAAY;IAQrC,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,eAAe;CA2BxB"}
|
|
@@ -5,25 +5,19 @@ import { Payload } from '@xyo-network/payload-model';
|
|
|
5
5
|
import { IndexedDbPayloadDivinerParams } from './Params';
|
|
6
6
|
export declare class IndexedDbPayloadDiviner<TParams extends IndexedDbPayloadDivinerParams = IndexedDbPayloadDivinerParams, TIn extends PayloadDivinerQueryPayload = PayloadDivinerQueryPayload, TOut extends Payload = Payload, TEventData extends DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut> = DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut>> extends PayloadDiviner<TParams, TIn, TOut, TEventData> {
|
|
7
7
|
static configSchemas: string[];
|
|
8
|
-
static defaultDbName: string;
|
|
9
|
-
static defaultDbVersion: number;
|
|
10
|
-
static defaultStoreName: string;
|
|
11
8
|
private _db;
|
|
12
9
|
/**
|
|
13
|
-
* The database name. If not supplied via config it defaults
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
* The database name. If not supplied via config, it defaults
|
|
11
|
+
* to the archivist's name and if archivist's name is not supplied,
|
|
12
|
+
* it defaults to `archivist`. This behavior
|
|
13
|
+
* biases towards a single, isolated DB per archivist which seems to
|
|
14
|
+
* make the most sense for 99% of use cases.
|
|
17
15
|
*/
|
|
18
16
|
get dbName(): string;
|
|
19
17
|
/**
|
|
20
|
-
* The database version. If not supplied via config, it defaults to
|
|
18
|
+
* The database version. If not supplied via config, it defaults to the archivist default version.
|
|
21
19
|
*/
|
|
22
20
|
get dbVersion(): number;
|
|
23
|
-
/**
|
|
24
|
-
* The database indexes.
|
|
25
|
-
*/
|
|
26
|
-
get indexes(): import("@xyo-network/archivist-model").IndexDescription[];
|
|
27
21
|
/**
|
|
28
22
|
* The name of the object store. If not supplied via config, it defaults
|
|
29
23
|
* to `payloads`.
|
|
@@ -32,7 +26,7 @@ export declare class IndexedDbPayloadDiviner<TParams extends IndexedDbPayloadDiv
|
|
|
32
26
|
private get db();
|
|
33
27
|
protected divineHandler(payloads?: TIn[]): Promise<TOut[]>;
|
|
34
28
|
protected startHandler(): Promise<boolean>;
|
|
35
|
-
private
|
|
29
|
+
private getKeyRangeValue;
|
|
36
30
|
private selectBestIndex;
|
|
37
31
|
}
|
|
38
32
|
//# sourceMappingURL=Diviner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Diviner.d.ts","sourceRoot":"","sources":["../../src/Diviner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Diviner.d.ts","sourceRoot":"","sources":["../../src/Diviner.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAA;AACtE,OAAO,EAAgC,0BAA0B,EAAE,MAAM,oCAAoC,CAAA;AAG7G,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AAIpD,OAAO,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAA;AAoBxD,qBAAa,uBAAuB,CAClC,OAAO,SAAS,6BAA6B,GAAG,6BAA6B,EAC7E,GAAG,SAAS,0BAA0B,GAAG,0BAA0B,EACnE,IAAI,SAAS,OAAO,GAAG,OAAO,EAC9B,UAAU,SAAS,sBAAsB,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,sBAAsB,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CACxI,SAAQ,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC;IACtD,OAAgB,aAAa,WAAwC;IAErE,OAAO,CAAC,GAAG,CAAwC;IAEnD;;;;;;OAMG;IACH,IAAI,MAAM,WAET;IAED;;OAEG;IACH,IAAI,SAAS,WAEZ;IAED;;;OAGG;IACH,IAAI,SAAS,WAEZ;IAED,OAAO,KAAK,EAAE,GAEb;cAEwB,aAAa,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;cAuDhD,YAAY;IAQrC,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,eAAe;CA2BxB"}
|
|
@@ -5,25 +5,19 @@ import { Payload } from '@xyo-network/payload-model';
|
|
|
5
5
|
import { IndexedDbPayloadDivinerParams } from './Params';
|
|
6
6
|
export declare class IndexedDbPayloadDiviner<TParams extends IndexedDbPayloadDivinerParams = IndexedDbPayloadDivinerParams, TIn extends PayloadDivinerQueryPayload = PayloadDivinerQueryPayload, TOut extends Payload = Payload, TEventData extends DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut> = DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut>> extends PayloadDiviner<TParams, TIn, TOut, TEventData> {
|
|
7
7
|
static configSchemas: string[];
|
|
8
|
-
static defaultDbName: string;
|
|
9
|
-
static defaultDbVersion: number;
|
|
10
|
-
static defaultStoreName: string;
|
|
11
8
|
private _db;
|
|
12
9
|
/**
|
|
13
|
-
* The database name. If not supplied via config it defaults
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
* The database name. If not supplied via config, it defaults
|
|
11
|
+
* to the archivist's name and if archivist's name is not supplied,
|
|
12
|
+
* it defaults to `archivist`. This behavior
|
|
13
|
+
* biases towards a single, isolated DB per archivist which seems to
|
|
14
|
+
* make the most sense for 99% of use cases.
|
|
17
15
|
*/
|
|
18
16
|
get dbName(): string;
|
|
19
17
|
/**
|
|
20
|
-
* The database version. If not supplied via config, it defaults to
|
|
18
|
+
* The database version. If not supplied via config, it defaults to the archivist default version.
|
|
21
19
|
*/
|
|
22
20
|
get dbVersion(): number;
|
|
23
|
-
/**
|
|
24
|
-
* The database indexes.
|
|
25
|
-
*/
|
|
26
|
-
get indexes(): import("@xyo-network/archivist-model").IndexDescription[];
|
|
27
21
|
/**
|
|
28
22
|
* The name of the object store. If not supplied via config, it defaults
|
|
29
23
|
* to `payloads`.
|
|
@@ -32,7 +26,7 @@ export declare class IndexedDbPayloadDiviner<TParams extends IndexedDbPayloadDiv
|
|
|
32
26
|
private get db();
|
|
33
27
|
protected divineHandler(payloads?: TIn[]): Promise<TOut[]>;
|
|
34
28
|
protected startHandler(): Promise<boolean>;
|
|
35
|
-
private
|
|
29
|
+
private getKeyRangeValue;
|
|
36
30
|
private selectBestIndex;
|
|
37
31
|
}
|
|
38
32
|
//# sourceMappingURL=Diviner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Diviner.d.ts","sourceRoot":"","sources":["../../src/Diviner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Diviner.d.ts","sourceRoot":"","sources":["../../src/Diviner.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAA;AACtE,OAAO,EAAgC,0BAA0B,EAAE,MAAM,oCAAoC,CAAA;AAG7G,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AAIpD,OAAO,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAA;AAoBxD,qBAAa,uBAAuB,CAClC,OAAO,SAAS,6BAA6B,GAAG,6BAA6B,EAC7E,GAAG,SAAS,0BAA0B,GAAG,0BAA0B,EACnE,IAAI,SAAS,OAAO,GAAG,OAAO,EAC9B,UAAU,SAAS,sBAAsB,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,sBAAsB,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CACxI,SAAQ,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC;IACtD,OAAgB,aAAa,WAAwC;IAErE,OAAO,CAAC,GAAG,CAAwC;IAEnD;;;;;;OAMG;IACH,IAAI,MAAM,WAET;IAED;;OAEG;IACH,IAAI,SAAS,WAEZ;IAED;;;OAGG;IACH,IAAI,SAAS,WAEZ;IAED,OAAO,KAAK,EAAE,GAEb;cAEwB,aAAa,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;cAuDhD,YAAY;IAQrC,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,eAAe;CA2BxB"}
|
package/dist/browser/index.cjs
CHANGED
|
@@ -35,50 +35,57 @@ var IndexedDbPayloadDivinerSchema = `${import_diviner_payload_model.PayloadDivin
|
|
|
35
35
|
var IndexedDbPayloadDivinerConfigSchema = `${IndexedDbPayloadDivinerSchema}.config`;
|
|
36
36
|
|
|
37
37
|
// src/Diviner.ts
|
|
38
|
+
var import_array = require("@xylabs/array");
|
|
38
39
|
var import_assert = require("@xylabs/assert");
|
|
40
|
+
var import_exists = require("@xylabs/exists");
|
|
41
|
+
var import_archivist_indexeddb = require("@xyo-network/archivist-indexeddb");
|
|
39
42
|
var import_archivist_model = require("@xyo-network/archivist-model");
|
|
40
43
|
var import_diviner_payload_abstract = require("@xyo-network/diviner-payload-abstract");
|
|
41
44
|
var import_diviner_payload_model2 = require("@xyo-network/diviner-payload-model");
|
|
42
45
|
var import_hash = require("@xyo-network/hash");
|
|
43
46
|
var import_idb = require("idb");
|
|
44
|
-
var
|
|
47
|
+
var payloadValueFilter = /* @__PURE__ */ __name((key, value) => {
|
|
48
|
+
if (!value)
|
|
49
|
+
return void 0;
|
|
50
|
+
return (payload) => {
|
|
51
|
+
if (!payload)
|
|
52
|
+
return false;
|
|
53
|
+
const sourceValue = payload?.[key];
|
|
54
|
+
if (sourceValue === void 0)
|
|
55
|
+
return false;
|
|
56
|
+
return Array.isArray(sourceValue) && Array.isArray(value) ? (0, import_array.containsAll)(sourceValue, value) : sourceValue == value;
|
|
57
|
+
};
|
|
58
|
+
}, "payloadValueFilter");
|
|
59
|
+
var IndexedDbPayloadDiviner = class extends import_diviner_payload_abstract.PayloadDiviner {
|
|
45
60
|
static {
|
|
46
61
|
__name(this, "IndexedDbPayloadDiviner");
|
|
47
62
|
}
|
|
48
63
|
static configSchemas = [
|
|
49
64
|
IndexedDbPayloadDivinerConfigSchema
|
|
50
65
|
];
|
|
51
|
-
static defaultDbName = "archivist";
|
|
52
|
-
static defaultDbVersion = 1;
|
|
53
|
-
static defaultStoreName = "payloads";
|
|
54
66
|
_db;
|
|
55
67
|
/**
|
|
56
|
-
* The database name. If not supplied via config it defaults
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
68
|
+
* The database name. If not supplied via config, it defaults
|
|
69
|
+
* to the archivist's name and if archivist's name is not supplied,
|
|
70
|
+
* it defaults to `archivist`. This behavior
|
|
71
|
+
* biases towards a single, isolated DB per archivist which seems to
|
|
72
|
+
* make the most sense for 99% of use cases.
|
|
60
73
|
*/
|
|
61
74
|
get dbName() {
|
|
62
|
-
return this.config?.dbName ??
|
|
75
|
+
return this.config?.dbName ?? this.config?.archivist ?? import_archivist_indexeddb.IndexedDbArchivist.defaultDbName;
|
|
63
76
|
}
|
|
64
77
|
/**
|
|
65
|
-
* The database version. If not supplied via config, it defaults to
|
|
78
|
+
* The database version. If not supplied via config, it defaults to the archivist default version.
|
|
66
79
|
*/
|
|
67
80
|
get dbVersion() {
|
|
68
|
-
return this.config?.dbVersion ??
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* The database indexes.
|
|
72
|
-
*/
|
|
73
|
-
get indexes() {
|
|
74
|
-
return this.config?.storage?.indexes ?? [];
|
|
81
|
+
return this.config?.dbVersion ?? import_archivist_indexeddb.IndexedDbArchivist.defaultDbVersion;
|
|
75
82
|
}
|
|
76
83
|
/**
|
|
77
84
|
* The name of the object store. If not supplied via config, it defaults
|
|
78
85
|
* to `payloads`.
|
|
79
86
|
*/
|
|
80
87
|
get storeName() {
|
|
81
|
-
return this.config?.storeName ??
|
|
88
|
+
return this.config?.storeName ?? import_archivist_indexeddb.IndexedDbArchivist.defaultStoreName;
|
|
82
89
|
}
|
|
83
90
|
get db() {
|
|
84
91
|
return (0, import_assert.assertEx)(this._db, "DB not initialized");
|
|
@@ -103,14 +110,24 @@ var IndexedDbPayloadDiviner = class _IndexedDbPayloadDiviner extends import_divi
|
|
|
103
110
|
};
|
|
104
111
|
const direction = order === "desc" ? "prev" : "next";
|
|
105
112
|
const suggestedIndex = this.selectBestIndex(filter, store);
|
|
106
|
-
const
|
|
107
|
-
|
|
113
|
+
const keyRangeValue = this.getKeyRangeValue(suggestedIndex, filter);
|
|
114
|
+
const valueFilters = props ? Object.entries(props).map(([key, value]) => payloadValueFilter(key, value)).filter(import_exists.exists) : [];
|
|
115
|
+
let cursor = suggestedIndex ? await store.index(suggestedIndex).openCursor(IDBKeyRange.only(keyRangeValue), direction) : await store.openCursor(suggestedIndex, direction);
|
|
108
116
|
while (cursor && parsedOffset > 0) {
|
|
109
117
|
cursor = await cursor.advance(parsedOffset);
|
|
110
118
|
parsedOffset = 0;
|
|
111
119
|
}
|
|
112
120
|
while (cursor && results.length < parsedLimit) {
|
|
113
|
-
|
|
121
|
+
const value = cursor.value;
|
|
122
|
+
if (value) {
|
|
123
|
+
if (valueFilters.length > 0) {
|
|
124
|
+
if (valueFilters.every((filter2) => filter2(value))) {
|
|
125
|
+
results.push(value);
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
results.push(value);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
114
131
|
cursor = await cursor.continue();
|
|
115
132
|
}
|
|
116
133
|
await tx.done;
|
|
@@ -121,14 +138,15 @@ var IndexedDbPayloadDiviner = class _IndexedDbPayloadDiviner extends import_divi
|
|
|
121
138
|
this._db = await (0, import_idb.openDB)(this.dbName, this.dbVersion);
|
|
122
139
|
return true;
|
|
123
140
|
}
|
|
124
|
-
|
|
141
|
+
getKeyRangeValue(indexName, query) {
|
|
125
142
|
if (!indexName)
|
|
126
143
|
return [];
|
|
127
144
|
const extractFields = /* @__PURE__ */ __name((indexName2) => {
|
|
128
145
|
return indexName2.slice(3).split(import_archivist_model.IndexSeparator).map((field) => field.toLowerCase());
|
|
129
146
|
}, "extractFields");
|
|
130
147
|
const indexFields = extractFields(indexName);
|
|
131
|
-
|
|
148
|
+
const keyRangeValue = indexFields.map((field) => query[field]);
|
|
149
|
+
return keyRangeValue.length === 1 ? keyRangeValue[0] : keyRangeValue;
|
|
132
150
|
}
|
|
133
151
|
selectBestIndex(query, store) {
|
|
134
152
|
const { indexNames } = store;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/Schema.ts","../../src/Config.ts","../../src/Diviner.ts"],"sourcesContent":["export * from './Config'\nexport * from './Diviner'\nexport * from './Params'\nexport * from './Schema'\n","import { PayloadDivinerSchema } from '@xyo-network/diviner-payload-model'\n\nexport const IndexedDbPayloadDivinerSchema = `${PayloadDivinerSchema}.indexeddb`\nexport type IndexedDbPayloadDivinerSchema = typeof IndexedDbPayloadDivinerSchema\n","import { IndexDescription } from '@xyo-network/archivist-model'\nimport { DivinerConfig } from '@xyo-network/diviner-model'\n\nimport { IndexedDbPayloadDivinerSchema } from './Schema'\n\nexport const IndexedDbPayloadDivinerConfigSchema = `${IndexedDbPayloadDivinerSchema}.config`\nexport type IndexedDbPayloadDivinerConfigSchema = typeof IndexedDbPayloadDivinerConfigSchema\n\nexport type IndexedDbPayloadDivinerConfig = DivinerConfig<{\n /**\n * The database name\n */\n dbName?: string\n /**\n * The version of the DB, defaults to 1\n */\n dbVersion?: number\n schema: IndexedDbPayloadDivinerConfigSchema\n /**\n * The storage configuration\n * // TODO: Hoist to main diviner config\n */\n storage?: {\n /**\n * The indexes to create on the object store\n */\n indexes?: IndexDescription[]\n }\n /**\n * The name of the object store\n */\n storeName?: string\n}>\n","import { assertEx } from '@xylabs/assert'\nimport { IndexSeparator } from '@xyo-network/archivist-model'\nimport { DivinerModule, DivinerModuleEventData } from '@xyo-network/diviner-model'\nimport { PayloadDiviner } from '@xyo-network/diviner-payload-abstract'\nimport { isPayloadDivinerQueryPayload, PayloadDivinerQueryPayload } from '@xyo-network/diviner-payload-model'\nimport { PayloadHasher } from '@xyo-network/hash'\nimport { AnyObject } from '@xyo-network/object'\nimport { Payload } from '@xyo-network/payload-model'\nimport { IDBPDatabase, IDBPObjectStore, openDB } from 'idb'\n\nimport { IndexedDbPayloadDivinerConfigSchema } from './Config'\nimport { IndexedDbPayloadDivinerParams } from './Params'\n\ninterface PayloadStore {\n [s: string]: Payload\n}\n\nexport class IndexedDbPayloadDiviner<\n TParams extends IndexedDbPayloadDivinerParams = IndexedDbPayloadDivinerParams,\n TIn extends PayloadDivinerQueryPayload = PayloadDivinerQueryPayload,\n TOut extends Payload = Payload,\n TEventData extends DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut> = DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut>,\n> extends PayloadDiviner<TParams, TIn, TOut, TEventData> {\n static override configSchemas = [IndexedDbPayloadDivinerConfigSchema]\n static defaultDbName = 'archivist'\n static defaultDbVersion = 1\n static defaultStoreName = 'payloads'\n\n private _db: IDBPDatabase<PayloadStore> | undefined\n\n /**\n * The database name. If not supplied via config it defaults to\n * `archivist`. This behavior biases towards a single, isolated\n * DB per archivist which seems to make the most sense for 99% of\n * use cases.\n */\n get dbName() {\n return this.config?.dbName ?? IndexedDbPayloadDiviner.defaultDbName\n }\n\n /**\n * The database version. If not supplied via config, it defaults to 1.\n */\n get dbVersion() {\n return this.config?.dbVersion ?? IndexedDbPayloadDiviner.defaultDbVersion\n }\n\n /**\n * The database indexes.\n */\n get indexes() {\n return this.config?.storage?.indexes ?? []\n }\n\n /**\n * The name of the object store. If not supplied via config, it defaults\n * to `payloads`.\n */\n get storeName() {\n return this.config?.storeName ?? IndexedDbPayloadDiviner.defaultStoreName\n }\n\n private get db(): IDBPDatabase<PayloadStore> {\n return assertEx(this._db, 'DB not initialized')\n }\n\n protected override async divineHandler(payloads?: TIn[]): Promise<TOut[]> {\n const query = assertEx(payloads?.filter(isPayloadDivinerQueryPayload)?.pop(), 'Missing query payload')\n if (!query) return []\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { schemas, limit, offset, hash, order, schema: _schema, sources, ...props } = query as unknown as TIn & { sources?: string[] }\n const tx = this.db.transaction(this.storeName, 'readonly')\n const store = tx.objectStore(this.storeName)\n const results: TOut[] = []\n let parsedOffset = offset ?? 0\n const parsedLimit = limit ?? 10\n assertEx((schemas?.length ?? 1) === 1, 'IndexedDbPayloadDiviner: Only one filter schema supported')\n const filterSchema = schemas?.[0]\n const filter = filterSchema ? { schema: filterSchema, ...props } : { ...props }\n const direction: IDBCursorDirection = order === 'desc' ? 'prev' : 'next'\n const suggestedIndex = this.selectBestIndex(filter, store)\n const filterValues = this.getKeyValuesFromQuery(suggestedIndex, filter)\n let cursor = suggestedIndex\n ? // Conditionally filter on schemas\n await store.index(suggestedIndex).openCursor(IDBKeyRange.only(filterValues.length === 1 ? filterValues[0] : filterValues), direction)\n : // Just iterate all records\n await store.openCursor(suggestedIndex, direction)\n\n // Skip records until the offset is reached\n while (cursor && parsedOffset > 0) {\n cursor = await cursor.advance(parsedOffset)\n parsedOffset = 0 // Reset offset after skipping\n }\n // Collect results up to the limit\n while (cursor && results.length < parsedLimit) {\n results.push(cursor.value)\n cursor = await cursor.continue()\n }\n await tx.done\n // Remove any metadata before returning to the client\n return results.map((payload) => PayloadHasher.jsonPayload(payload))\n }\n\n protected override async startHandler() {\n await super.startHandler()\n // NOTE: We could defer this creation to first access but we\n // want to fail fast here in case something is wrong\n this._db = await openDB<PayloadStore>(this.dbName, this.dbVersion)\n return true\n }\n\n private getKeyValuesFromQuery(indexName: string | null, query: AnyObject): unknown[] {\n if (!indexName) return []\n // Function to extract fields from an index name\n const extractFields = (indexName: string): string[] => {\n return indexName\n .slice(3)\n .split(IndexSeparator)\n .map((field) => field.toLowerCase())\n }\n\n // Extracting the relevant fields from the index name\n const indexFields = extractFields(indexName)\n\n // Collecting the values for these fields from the query object\n return indexFields.map((field) => query[field as keyof AnyObject])\n }\n\n private selectBestIndex(query: AnyObject, store: IDBPObjectStore<PayloadStore>): string | null {\n // List of available indexes\n const { indexNames } = store\n\n // Function to extract fields from an index name\n const extractFields = (indexName: string): string[] => {\n return indexName\n .slice(3)\n .split(IndexSeparator)\n .map((field) => field.toLowerCase())\n }\n\n // Convert query object keys to a set for easier comparison\n const queryKeys = new Set(Object.keys(query).map((key) => key.toLowerCase()))\n\n // Find the best matching index\n let bestMatch: { indexName: string; matchCount: number } = { indexName: '', matchCount: 0 }\n\n for (const indexName of indexNames) {\n const indexFields = extractFields(indexName)\n const matchCount = indexFields.filter((field) => queryKeys.has(field)).length\n if (matchCount > bestMatch.matchCount) {\n bestMatch = { indexName, matchCount }\n }\n }\n return bestMatch.matchCount > 0 ? bestMatch.indexName : null\n }\n}\n"],"mappings":"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","names":["IndexedDbPayloadDivinerSchema","PayloadDivinerSchema","IndexedDbPayloadDivinerConfigSchema","IndexedDbPayloadDivinerSchema","import_diviner_payload_model","IndexedDbPayloadDiviner","PayloadDiviner","configSchemas","IndexedDbPayloadDivinerConfigSchema","defaultDbName","defaultDbVersion","defaultStoreName","_db","dbName","config","dbVersion","indexes","storage","storeName","db","assertEx","divineHandler","payloads","query","filter","isPayloadDivinerQueryPayload","pop","schemas","limit","offset","hash","order","schema","_schema","sources","props","tx","transaction","store","objectStore","results","parsedOffset","parsedLimit","length","filterSchema","direction","suggestedIndex","selectBestIndex","filterValues","getKeyValuesFromQuery","cursor","index","openCursor","IDBKeyRange","only","advance","push","value","continue","done","map","payload","PayloadHasher","jsonPayload","startHandler","openDB","indexName","extractFields","slice","split","IndexSeparator","field","toLowerCase","indexFields","indexNames","queryKeys","Set","Object","keys","key","bestMatch","matchCount","has"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/Schema.ts","../../src/Config.ts","../../src/Diviner.ts"],"sourcesContent":["export * from './Config'\nexport * from './Diviner'\nexport * from './Params'\nexport * from './Schema'\n","import { PayloadDivinerSchema } from '@xyo-network/diviner-payload-model'\n\nexport const IndexedDbPayloadDivinerSchema = `${PayloadDivinerSchema}.indexeddb`\nexport type IndexedDbPayloadDivinerSchema = typeof IndexedDbPayloadDivinerSchema\n","import { IndexDescription } from '@xyo-network/archivist-model'\nimport { DivinerConfig } from '@xyo-network/diviner-model'\n\nimport { IndexedDbPayloadDivinerSchema } from './Schema'\n\nexport const IndexedDbPayloadDivinerConfigSchema = `${IndexedDbPayloadDivinerSchema}.config`\nexport type IndexedDbPayloadDivinerConfigSchema = typeof IndexedDbPayloadDivinerConfigSchema\n\nexport type IndexedDbPayloadDivinerConfig = DivinerConfig<{\n /**\n * The database name\n */\n dbName?: string\n /**\n * The version of the DB, defaults to 1\n */\n dbVersion?: number\n schema: IndexedDbPayloadDivinerConfigSchema\n /**\n * The storage configuration\n * // TODO: Hoist to main diviner config\n */\n storage?: {\n /**\n * The indexes to create on the object store\n */\n indexes?: IndexDescription[]\n }\n /**\n * The name of the object store\n */\n storeName?: string\n}>\n","import { containsAll } from '@xylabs/array'\nimport { assertEx } from '@xylabs/assert'\nimport { exists } from '@xylabs/exists'\nimport { IndexedDbArchivist } from '@xyo-network/archivist-indexeddb'\nimport { IndexSeparator } from '@xyo-network/archivist-model'\nimport { DivinerModule, DivinerModuleEventData } from '@xyo-network/diviner-model'\nimport { PayloadDiviner } from '@xyo-network/diviner-payload-abstract'\nimport { isPayloadDivinerQueryPayload, PayloadDivinerQueryPayload } from '@xyo-network/diviner-payload-model'\nimport { PayloadHasher } from '@xyo-network/hash'\nimport { AnyObject } from '@xyo-network/object'\nimport { Payload } from '@xyo-network/payload-model'\nimport { IDBPDatabase, IDBPObjectStore, openDB } from 'idb'\n\nimport { IndexedDbPayloadDivinerConfigSchema } from './Config'\nimport { IndexedDbPayloadDivinerParams } from './Params'\n\ninterface PayloadStore {\n [s: string]: Payload\n}\n\ntype AnyPayload = Payload<Record<string, unknown>>\n\ntype ValueFilter = (payload?: AnyPayload | null) => boolean\n\nconst payloadValueFilter = (key: keyof AnyPayload, value?: unknown | unknown[]): ValueFilter | undefined => {\n if (!value) return undefined\n return (payload) => {\n if (!payload) return false\n const sourceValue = payload?.[key]\n if (sourceValue === undefined) return false\n return Array.isArray(sourceValue) && Array.isArray(value) ? containsAll(sourceValue, value) : sourceValue == value\n }\n}\n\nexport class IndexedDbPayloadDiviner<\n TParams extends IndexedDbPayloadDivinerParams = IndexedDbPayloadDivinerParams,\n TIn extends PayloadDivinerQueryPayload = PayloadDivinerQueryPayload,\n TOut extends Payload = Payload,\n TEventData extends DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut> = DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut>,\n> extends PayloadDiviner<TParams, TIn, TOut, TEventData> {\n static override configSchemas = [IndexedDbPayloadDivinerConfigSchema]\n\n private _db: IDBPDatabase<PayloadStore> | undefined\n\n /**\n * The database name. If not supplied via config, it defaults\n * to the archivist's name and if archivist's name is not supplied,\n * it defaults to `archivist`. This behavior\n * biases towards a single, isolated DB per archivist which seems to\n * make the most sense for 99% of use cases.\n */\n get dbName() {\n return this.config?.dbName ?? this.config?.archivist ?? IndexedDbArchivist.defaultDbName\n }\n\n /**\n * The database version. If not supplied via config, it defaults to the archivist default version.\n */\n get dbVersion() {\n return this.config?.dbVersion ?? IndexedDbArchivist.defaultDbVersion\n }\n\n /**\n * The name of the object store. If not supplied via config, it defaults\n * to `payloads`.\n */\n get storeName() {\n return this.config?.storeName ?? IndexedDbArchivist.defaultStoreName\n }\n\n private get db(): IDBPDatabase<PayloadStore> {\n return assertEx(this._db, 'DB not initialized')\n }\n\n protected override async divineHandler(payloads?: TIn[]): Promise<TOut[]> {\n const query = assertEx(payloads?.filter(isPayloadDivinerQueryPayload)?.pop(), 'Missing query payload')\n if (!query) return []\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { schemas, limit, offset, hash, order, schema: _schema, sources, ...props } = query as unknown as TIn & { sources?: string[] }\n const tx = this.db.transaction(this.storeName, 'readonly')\n const store = tx.objectStore(this.storeName)\n const results: TOut[] = []\n let parsedOffset = offset ?? 0\n const parsedLimit = limit ?? 10\n assertEx((schemas?.length ?? 1) === 1, 'IndexedDbPayloadDiviner: Only one filter schema supported')\n const filterSchema = schemas?.[0]\n const filter = filterSchema ? { schema: filterSchema, ...props } : { ...props }\n const direction: IDBCursorDirection = order === 'desc' ? 'prev' : 'next'\n const suggestedIndex = this.selectBestIndex(filter, store)\n const keyRangeValue = this.getKeyRangeValue(suggestedIndex, filter)\n const valueFilters: ValueFilter[] = props\n ? Object.entries(props)\n .map(([key, value]) => payloadValueFilter(key, value))\n .filter(exists)\n : []\n let cursor = suggestedIndex\n ? // Conditionally filter on schemas\n await store.index(suggestedIndex).openCursor(IDBKeyRange.only(keyRangeValue), direction)\n : // Just iterate all records\n await store.openCursor(suggestedIndex, direction)\n\n // Skip records until the offset is reached\n while (cursor && parsedOffset > 0) {\n cursor = await cursor.advance(parsedOffset)\n parsedOffset = 0 // Reset offset after skipping\n }\n // Collect results up to the limit\n while (cursor && results.length < parsedLimit) {\n const value = cursor.value\n if (value) {\n // If we're filtering on more than just the schema\n if (valueFilters.length > 0) {\n // Ensure all filters pass\n if (valueFilters.every((filter) => filter(value))) {\n // Then save the value\n results.push(value)\n }\n } else {\n // Otherwise just save the value\n results.push(value)\n }\n }\n cursor = await cursor.continue()\n }\n await tx.done\n // Remove any metadata before returning to the client\n return results.map((payload) => PayloadHasher.jsonPayload(payload))\n }\n\n protected override async startHandler() {\n await super.startHandler()\n // NOTE: We could defer this creation to first access but we\n // want to fail fast here in case something is wrong\n this._db = await openDB<PayloadStore>(this.dbName, this.dbVersion)\n return true\n }\n\n private getKeyRangeValue(indexName: string | null, query: AnyObject): unknown | unknown[] {\n if (!indexName) return []\n // Function to extract fields from an index name\n const extractFields = (indexName: string): string[] => {\n return indexName\n .slice(3)\n .split(IndexSeparator)\n .map((field) => field.toLowerCase())\n }\n\n // Extracting the relevant fields from the index name\n const indexFields = extractFields(indexName)\n\n // Collecting the values for these fields from the query object\n const keyRangeValue = indexFields.map((field) => query[field as keyof AnyObject])\n return keyRangeValue.length === 1 ? keyRangeValue[0] : keyRangeValue\n }\n\n private selectBestIndex(query: AnyObject, store: IDBPObjectStore<PayloadStore>): string | null {\n // List of available indexes\n const { indexNames } = store\n\n // Function to extract fields from an index name\n const extractFields = (indexName: string): string[] => {\n return indexName\n .slice(3)\n .split(IndexSeparator)\n .map((field) => field.toLowerCase())\n }\n\n // Convert query object keys to a set for easier comparison\n const queryKeys = new Set(Object.keys(query).map((key) => key.toLowerCase()))\n\n // Find the best matching index\n let bestMatch: { indexName: string; matchCount: number } = { indexName: '', matchCount: 0 }\n\n for (const indexName of indexNames) {\n const indexFields = extractFields(indexName)\n const matchCount = indexFields.filter((field) => queryKeys.has(field)).length\n if (matchCount > bestMatch.matchCount) {\n bestMatch = { indexName, matchCount }\n }\n }\n return bestMatch.matchCount > 0 ? bestMatch.indexName : null\n }\n}\n"],"mappings":"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","names":["IndexedDbPayloadDivinerSchema","PayloadDivinerSchema","IndexedDbPayloadDivinerConfigSchema","IndexedDbPayloadDivinerSchema","import_diviner_payload_model","payloadValueFilter","key","value","undefined","payload","sourceValue","Array","isArray","containsAll","IndexedDbPayloadDiviner","PayloadDiviner","configSchemas","IndexedDbPayloadDivinerConfigSchema","_db","dbName","config","archivist","IndexedDbArchivist","defaultDbName","dbVersion","defaultDbVersion","storeName","defaultStoreName","db","assertEx","divineHandler","payloads","query","filter","isPayloadDivinerQueryPayload","pop","schemas","limit","offset","hash","order","schema","_schema","sources","props","tx","transaction","store","objectStore","results","parsedOffset","parsedLimit","length","filterSchema","direction","suggestedIndex","selectBestIndex","keyRangeValue","getKeyRangeValue","valueFilters","Object","entries","map","exists","cursor","index","openCursor","IDBKeyRange","only","advance","every","push","continue","done","PayloadHasher","jsonPayload","startHandler","openDB","indexName","extractFields","slice","split","IndexSeparator","field","toLowerCase","indexFields","indexNames","queryKeys","Set","keys","bestMatch","matchCount","has"]}
|
package/dist/browser/index.js
CHANGED
|
@@ -9,50 +9,57 @@ var IndexedDbPayloadDivinerSchema = `${PayloadDivinerSchema}.indexeddb`;
|
|
|
9
9
|
var IndexedDbPayloadDivinerConfigSchema = `${IndexedDbPayloadDivinerSchema}.config`;
|
|
10
10
|
|
|
11
11
|
// src/Diviner.ts
|
|
12
|
+
import { containsAll } from "@xylabs/array";
|
|
12
13
|
import { assertEx } from "@xylabs/assert";
|
|
14
|
+
import { exists } from "@xylabs/exists";
|
|
15
|
+
import { IndexedDbArchivist } from "@xyo-network/archivist-indexeddb";
|
|
13
16
|
import { IndexSeparator } from "@xyo-network/archivist-model";
|
|
14
17
|
import { PayloadDiviner } from "@xyo-network/diviner-payload-abstract";
|
|
15
18
|
import { isPayloadDivinerQueryPayload } from "@xyo-network/diviner-payload-model";
|
|
16
19
|
import { PayloadHasher } from "@xyo-network/hash";
|
|
17
20
|
import { openDB } from "idb";
|
|
18
|
-
var
|
|
21
|
+
var payloadValueFilter = /* @__PURE__ */ __name((key, value) => {
|
|
22
|
+
if (!value)
|
|
23
|
+
return void 0;
|
|
24
|
+
return (payload) => {
|
|
25
|
+
if (!payload)
|
|
26
|
+
return false;
|
|
27
|
+
const sourceValue = payload?.[key];
|
|
28
|
+
if (sourceValue === void 0)
|
|
29
|
+
return false;
|
|
30
|
+
return Array.isArray(sourceValue) && Array.isArray(value) ? containsAll(sourceValue, value) : sourceValue == value;
|
|
31
|
+
};
|
|
32
|
+
}, "payloadValueFilter");
|
|
33
|
+
var IndexedDbPayloadDiviner = class extends PayloadDiviner {
|
|
19
34
|
static {
|
|
20
35
|
__name(this, "IndexedDbPayloadDiviner");
|
|
21
36
|
}
|
|
22
37
|
static configSchemas = [
|
|
23
38
|
IndexedDbPayloadDivinerConfigSchema
|
|
24
39
|
];
|
|
25
|
-
static defaultDbName = "archivist";
|
|
26
|
-
static defaultDbVersion = 1;
|
|
27
|
-
static defaultStoreName = "payloads";
|
|
28
40
|
_db;
|
|
29
41
|
/**
|
|
30
|
-
* The database name. If not supplied via config it defaults
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
42
|
+
* The database name. If not supplied via config, it defaults
|
|
43
|
+
* to the archivist's name and if archivist's name is not supplied,
|
|
44
|
+
* it defaults to `archivist`. This behavior
|
|
45
|
+
* biases towards a single, isolated DB per archivist which seems to
|
|
46
|
+
* make the most sense for 99% of use cases.
|
|
34
47
|
*/
|
|
35
48
|
get dbName() {
|
|
36
|
-
return this.config?.dbName ??
|
|
49
|
+
return this.config?.dbName ?? this.config?.archivist ?? IndexedDbArchivist.defaultDbName;
|
|
37
50
|
}
|
|
38
51
|
/**
|
|
39
|
-
* The database version. If not supplied via config, it defaults to
|
|
52
|
+
* The database version. If not supplied via config, it defaults to the archivist default version.
|
|
40
53
|
*/
|
|
41
54
|
get dbVersion() {
|
|
42
|
-
return this.config?.dbVersion ??
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* The database indexes.
|
|
46
|
-
*/
|
|
47
|
-
get indexes() {
|
|
48
|
-
return this.config?.storage?.indexes ?? [];
|
|
55
|
+
return this.config?.dbVersion ?? IndexedDbArchivist.defaultDbVersion;
|
|
49
56
|
}
|
|
50
57
|
/**
|
|
51
58
|
* The name of the object store. If not supplied via config, it defaults
|
|
52
59
|
* to `payloads`.
|
|
53
60
|
*/
|
|
54
61
|
get storeName() {
|
|
55
|
-
return this.config?.storeName ??
|
|
62
|
+
return this.config?.storeName ?? IndexedDbArchivist.defaultStoreName;
|
|
56
63
|
}
|
|
57
64
|
get db() {
|
|
58
65
|
return assertEx(this._db, "DB not initialized");
|
|
@@ -77,14 +84,24 @@ var IndexedDbPayloadDiviner = class _IndexedDbPayloadDiviner extends PayloadDivi
|
|
|
77
84
|
};
|
|
78
85
|
const direction = order === "desc" ? "prev" : "next";
|
|
79
86
|
const suggestedIndex = this.selectBestIndex(filter, store);
|
|
80
|
-
const
|
|
81
|
-
|
|
87
|
+
const keyRangeValue = this.getKeyRangeValue(suggestedIndex, filter);
|
|
88
|
+
const valueFilters = props ? Object.entries(props).map(([key, value]) => payloadValueFilter(key, value)).filter(exists) : [];
|
|
89
|
+
let cursor = suggestedIndex ? await store.index(suggestedIndex).openCursor(IDBKeyRange.only(keyRangeValue), direction) : await store.openCursor(suggestedIndex, direction);
|
|
82
90
|
while (cursor && parsedOffset > 0) {
|
|
83
91
|
cursor = await cursor.advance(parsedOffset);
|
|
84
92
|
parsedOffset = 0;
|
|
85
93
|
}
|
|
86
94
|
while (cursor && results.length < parsedLimit) {
|
|
87
|
-
|
|
95
|
+
const value = cursor.value;
|
|
96
|
+
if (value) {
|
|
97
|
+
if (valueFilters.length > 0) {
|
|
98
|
+
if (valueFilters.every((filter2) => filter2(value))) {
|
|
99
|
+
results.push(value);
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
results.push(value);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
88
105
|
cursor = await cursor.continue();
|
|
89
106
|
}
|
|
90
107
|
await tx.done;
|
|
@@ -95,14 +112,15 @@ var IndexedDbPayloadDiviner = class _IndexedDbPayloadDiviner extends PayloadDivi
|
|
|
95
112
|
this._db = await openDB(this.dbName, this.dbVersion);
|
|
96
113
|
return true;
|
|
97
114
|
}
|
|
98
|
-
|
|
115
|
+
getKeyRangeValue(indexName, query) {
|
|
99
116
|
if (!indexName)
|
|
100
117
|
return [];
|
|
101
118
|
const extractFields = /* @__PURE__ */ __name((indexName2) => {
|
|
102
119
|
return indexName2.slice(3).split(IndexSeparator).map((field) => field.toLowerCase());
|
|
103
120
|
}, "extractFields");
|
|
104
121
|
const indexFields = extractFields(indexName);
|
|
105
|
-
|
|
122
|
+
const keyRangeValue = indexFields.map((field) => query[field]);
|
|
123
|
+
return keyRangeValue.length === 1 ? keyRangeValue[0] : keyRangeValue;
|
|
106
124
|
}
|
|
107
125
|
selectBestIndex(query, store) {
|
|
108
126
|
const { indexNames } = store;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/Schema.ts","../../src/Config.ts","../../src/Diviner.ts"],"sourcesContent":["import { PayloadDivinerSchema } from '@xyo-network/diviner-payload-model'\n\nexport const IndexedDbPayloadDivinerSchema = `${PayloadDivinerSchema}.indexeddb`\nexport type IndexedDbPayloadDivinerSchema = typeof IndexedDbPayloadDivinerSchema\n","import { IndexDescription } from '@xyo-network/archivist-model'\nimport { DivinerConfig } from '@xyo-network/diviner-model'\n\nimport { IndexedDbPayloadDivinerSchema } from './Schema'\n\nexport const IndexedDbPayloadDivinerConfigSchema = `${IndexedDbPayloadDivinerSchema}.config`\nexport type IndexedDbPayloadDivinerConfigSchema = typeof IndexedDbPayloadDivinerConfigSchema\n\nexport type IndexedDbPayloadDivinerConfig = DivinerConfig<{\n /**\n * The database name\n */\n dbName?: string\n /**\n * The version of the DB, defaults to 1\n */\n dbVersion?: number\n schema: IndexedDbPayloadDivinerConfigSchema\n /**\n * The storage configuration\n * // TODO: Hoist to main diviner config\n */\n storage?: {\n /**\n * The indexes to create on the object store\n */\n indexes?: IndexDescription[]\n }\n /**\n * The name of the object store\n */\n storeName?: string\n}>\n","import { assertEx } from '@xylabs/assert'\nimport { IndexSeparator } from '@xyo-network/archivist-model'\nimport { DivinerModule, DivinerModuleEventData } from '@xyo-network/diviner-model'\nimport { PayloadDiviner } from '@xyo-network/diviner-payload-abstract'\nimport { isPayloadDivinerQueryPayload, PayloadDivinerQueryPayload } from '@xyo-network/diviner-payload-model'\nimport { PayloadHasher } from '@xyo-network/hash'\nimport { AnyObject } from '@xyo-network/object'\nimport { Payload } from '@xyo-network/payload-model'\nimport { IDBPDatabase, IDBPObjectStore, openDB } from 'idb'\n\nimport { IndexedDbPayloadDivinerConfigSchema } from './Config'\nimport { IndexedDbPayloadDivinerParams } from './Params'\n\ninterface PayloadStore {\n [s: string]: Payload\n}\n\nexport class IndexedDbPayloadDiviner<\n TParams extends IndexedDbPayloadDivinerParams = IndexedDbPayloadDivinerParams,\n TIn extends PayloadDivinerQueryPayload = PayloadDivinerQueryPayload,\n TOut extends Payload = Payload,\n TEventData extends DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut> = DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut>,\n> extends PayloadDiviner<TParams, TIn, TOut, TEventData> {\n static override configSchemas = [IndexedDbPayloadDivinerConfigSchema]\n static defaultDbName = 'archivist'\n static defaultDbVersion = 1\n static defaultStoreName = 'payloads'\n\n private _db: IDBPDatabase<PayloadStore> | undefined\n\n /**\n * The database name. If not supplied via config it defaults to\n * `archivist`. This behavior biases towards a single, isolated\n * DB per archivist which seems to make the most sense for 99% of\n * use cases.\n */\n get dbName() {\n return this.config?.dbName ?? IndexedDbPayloadDiviner.defaultDbName\n }\n\n /**\n * The database version. If not supplied via config, it defaults to 1.\n */\n get dbVersion() {\n return this.config?.dbVersion ?? IndexedDbPayloadDiviner.defaultDbVersion\n }\n\n /**\n * The database indexes.\n */\n get indexes() {\n return this.config?.storage?.indexes ?? []\n }\n\n /**\n * The name of the object store. If not supplied via config, it defaults\n * to `payloads`.\n */\n get storeName() {\n return this.config?.storeName ?? IndexedDbPayloadDiviner.defaultStoreName\n }\n\n private get db(): IDBPDatabase<PayloadStore> {\n return assertEx(this._db, 'DB not initialized')\n }\n\n protected override async divineHandler(payloads?: TIn[]): Promise<TOut[]> {\n const query = assertEx(payloads?.filter(isPayloadDivinerQueryPayload)?.pop(), 'Missing query payload')\n if (!query) return []\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { schemas, limit, offset, hash, order, schema: _schema, sources, ...props } = query as unknown as TIn & { sources?: string[] }\n const tx = this.db.transaction(this.storeName, 'readonly')\n const store = tx.objectStore(this.storeName)\n const results: TOut[] = []\n let parsedOffset = offset ?? 0\n const parsedLimit = limit ?? 10\n assertEx((schemas?.length ?? 1) === 1, 'IndexedDbPayloadDiviner: Only one filter schema supported')\n const filterSchema = schemas?.[0]\n const filter = filterSchema ? { schema: filterSchema, ...props } : { ...props }\n const direction: IDBCursorDirection = order === 'desc' ? 'prev' : 'next'\n const suggestedIndex = this.selectBestIndex(filter, store)\n const filterValues = this.getKeyValuesFromQuery(suggestedIndex, filter)\n let cursor = suggestedIndex\n ? // Conditionally filter on schemas\n await store.index(suggestedIndex).openCursor(IDBKeyRange.only(filterValues.length === 1 ? filterValues[0] : filterValues), direction)\n : // Just iterate all records\n await store.openCursor(suggestedIndex, direction)\n\n // Skip records until the offset is reached\n while (cursor && parsedOffset > 0) {\n cursor = await cursor.advance(parsedOffset)\n parsedOffset = 0 // Reset offset after skipping\n }\n // Collect results up to the limit\n while (cursor && results.length < parsedLimit) {\n results.push(cursor.value)\n cursor = await cursor.continue()\n }\n await tx.done\n // Remove any metadata before returning to the client\n return results.map((payload) => PayloadHasher.jsonPayload(payload))\n }\n\n protected override async startHandler() {\n await super.startHandler()\n // NOTE: We could defer this creation to first access but we\n // want to fail fast here in case something is wrong\n this._db = await openDB<PayloadStore>(this.dbName, this.dbVersion)\n return true\n }\n\n private getKeyValuesFromQuery(indexName: string | null, query: AnyObject): unknown[] {\n if (!indexName) return []\n // Function to extract fields from an index name\n const extractFields = (indexName: string): string[] => {\n return indexName\n .slice(3)\n .split(IndexSeparator)\n .map((field) => field.toLowerCase())\n }\n\n // Extracting the relevant fields from the index name\n const indexFields = extractFields(indexName)\n\n // Collecting the values for these fields from the query object\n return indexFields.map((field) => query[field as keyof AnyObject])\n }\n\n private selectBestIndex(query: AnyObject, store: IDBPObjectStore<PayloadStore>): string | null {\n // List of available indexes\n const { indexNames } = store\n\n // Function to extract fields from an index name\n const extractFields = (indexName: string): string[] => {\n return indexName\n .slice(3)\n .split(IndexSeparator)\n .map((field) => field.toLowerCase())\n }\n\n // Convert query object keys to a set for easier comparison\n const queryKeys = new Set(Object.keys(query).map((key) => key.toLowerCase()))\n\n // Find the best matching index\n let bestMatch: { indexName: string; matchCount: number } = { indexName: '', matchCount: 0 }\n\n for (const indexName of indexNames) {\n const indexFields = extractFields(indexName)\n const matchCount = indexFields.filter((field) => queryKeys.has(field)).length\n if (matchCount > bestMatch.matchCount) {\n bestMatch = { indexName, matchCount }\n }\n }\n return bestMatch.matchCount > 0 ? bestMatch.indexName : null\n }\n}\n"],"mappings":";;;;AAAA,SAASA,4BAA4B;AAE9B,IAAMC,gCAAgC,GAAGD,oBAAAA;;;ACGzC,IAAME,sCAAsC,GAAGC,6BAAAA;;;ACLtD,SAASC,gBAAgB;AACzB,SAASC,sBAAsB;AAE/B,SAASC,sBAAsB;AAC/B,SAASC,oCAAgE;AACzE,SAASC,qBAAqB;AAG9B,SAAwCC,cAAc;AAS/C,IAAMC,0BAAN,MAAMA,iCAKHC,eAAAA;EAtBV,OAsBUA;;;EACR,OAAgBC,gBAAgB;IAACC;;EACjC,OAAOC,gBAAgB;EACvB,OAAOC,mBAAmB;EAC1B,OAAOC,mBAAmB;EAElBC;;;;;;;EAQR,IAAIC,SAAS;AACX,WAAO,KAAKC,QAAQD,UAAUR,yBAAwBI;EACxD;;;;EAKA,IAAIM,YAAY;AACd,WAAO,KAAKD,QAAQC,aAAaV,yBAAwBK;EAC3D;;;;EAKA,IAAIM,UAAU;AACZ,WAAO,KAAKF,QAAQG,SAASD,WAAW,CAAA;EAC1C;;;;;EAMA,IAAIE,YAAY;AACd,WAAO,KAAKJ,QAAQI,aAAab,yBAAwBM;EAC3D;EAEA,IAAYQ,KAAiC;AAC3C,WAAOC,SAAS,KAAKR,KAAK,oBAAA;EAC5B;EAEA,MAAyBS,cAAcC,UAAmC;AACxE,UAAMC,QAAQH,SAASE,UAAUE,OAAOC,4BAAAA,GAA+BC,IAAAA,GAAO,uBAAA;AAC9E,QAAI,CAACH;AAAO,aAAO,CAAA;AAEnB,UAAM,EAAEI,SAASC,OAAOC,QAAQC,MAAMC,OAAOC,QAAQC,SAASC,SAAS,GAAGC,MAAAA,IAAUZ;AACpF,UAAMa,KAAK,KAAKjB,GAAGkB,YAAY,KAAKnB,WAAW,UAAA;AAC/C,UAAMoB,QAAQF,GAAGG,YAAY,KAAKrB,SAAS;AAC3C,UAAMsB,UAAkB,CAAA;AACxB,QAAIC,eAAeZ,UAAU;AAC7B,UAAMa,cAAcd,SAAS;AAC7BR,cAAUO,SAASgB,UAAU,OAAO,GAAG,2DAAA;AACvC,UAAMC,eAAejB,UAAU,CAAA;AAC/B,UAAMH,SAASoB,eAAe;MAAEZ,QAAQY;MAAc,GAAGT;IAAM,IAAI;MAAE,GAAGA;IAAM;AAC9E,UAAMU,YAAgCd,UAAU,SAAS,SAAS;AAClE,UAAMe,iBAAiB,KAAKC,gBAAgBvB,QAAQc,KAAAA;AACpD,UAAMU,eAAe,KAAKC,sBAAsBH,gBAAgBtB,MAAAA;AAChE,QAAI0B,SAASJ,iBAET,MAAMR,MAAMa,MAAML,cAAAA,EAAgBM,WAAWC,YAAYC,KAAKN,aAAaL,WAAW,IAAIK,aAAa,CAAA,IAAKA,YAAAA,GAAeH,SAAAA,IAE3H,MAAMP,MAAMc,WAAWN,gBAAgBD,SAAAA;AAG3C,WAAOK,UAAUT,eAAe,GAAG;AACjCS,eAAS,MAAMA,OAAOK,QAAQd,YAAAA;AAC9BA,qBAAe;IACjB;AAEA,WAAOS,UAAUV,QAAQG,SAASD,aAAa;AAC7CF,cAAQgB,KAAKN,OAAOO,KAAK;AACzBP,eAAS,MAAMA,OAAOQ,SAAQ;IAChC;AACA,UAAMtB,GAAGuB;AAET,WAAOnB,QAAQoB,IAAI,CAACC,YAAYC,cAAcC,YAAYF,OAAAA,CAAAA;EAC5D;EAEA,MAAyBG,eAAe;AACtC,UAAM,MAAMA,aAAAA;AAGZ,SAAKpD,MAAM,MAAMqD,OAAqB,KAAKpD,QAAQ,KAAKE,SAAS;AACjE,WAAO;EACT;EAEQkC,sBAAsBiB,WAA0B3C,OAA6B;AACnF,QAAI,CAAC2C;AAAW,aAAO,CAAA;AAEvB,UAAMC,gBAAgB,wBAACD,eAAAA;AACrB,aAAOA,WACJE,MAAM,CAAA,EACNC,MAAMC,cAAAA,EACNV,IAAI,CAACW,UAAUA,MAAMC,YAAW,CAAA;IACrC,GALsB;AAQtB,UAAMC,cAAcN,cAAcD,SAAAA;AAGlC,WAAOO,YAAYb,IAAI,CAACW,UAAUhD,MAAMgD,KAAAA,CAAyB;EACnE;EAEQxB,gBAAgBxB,OAAkBe,OAAqD;AAE7F,UAAM,EAAEoC,WAAU,IAAKpC;AAGvB,UAAM6B,gBAAgB,wBAACD,cAAAA;AACrB,aAAOA,UACJE,MAAM,CAAA,EACNC,MAAMC,cAAAA,EACNV,IAAI,CAACW,UAAUA,MAAMC,YAAW,CAAA;IACrC,GALsB;AAQtB,UAAMG,YAAY,IAAIC,IAAIC,OAAOC,KAAKvD,KAAAA,EAAOqC,IAAI,CAACmB,QAAQA,IAAIP,YAAW,CAAA,CAAA;AAGzE,QAAIQ,YAAuD;MAAEd,WAAW;MAAIe,YAAY;IAAE;AAE1F,eAAWf,aAAaQ,YAAY;AAClC,YAAMD,cAAcN,cAAcD,SAAAA;AAClC,YAAMe,aAAaR,YAAYjD,OAAO,CAAC+C,UAAUI,UAAUO,IAAIX,KAAAA,CAAAA,EAAQ5B;AACvE,UAAIsC,aAAaD,UAAUC,YAAY;AACrCD,oBAAY;UAAEd;UAAWe;QAAW;MACtC;IACF;AACA,WAAOD,UAAUC,aAAa,IAAID,UAAUd,YAAY;EAC1D;AACF;","names":["PayloadDivinerSchema","IndexedDbPayloadDivinerSchema","IndexedDbPayloadDivinerConfigSchema","IndexedDbPayloadDivinerSchema","assertEx","IndexSeparator","PayloadDiviner","isPayloadDivinerQueryPayload","PayloadHasher","openDB","IndexedDbPayloadDiviner","PayloadDiviner","configSchemas","IndexedDbPayloadDivinerConfigSchema","defaultDbName","defaultDbVersion","defaultStoreName","_db","dbName","config","dbVersion","indexes","storage","storeName","db","assertEx","divineHandler","payloads","query","filter","isPayloadDivinerQueryPayload","pop","schemas","limit","offset","hash","order","schema","_schema","sources","props","tx","transaction","store","objectStore","results","parsedOffset","parsedLimit","length","filterSchema","direction","suggestedIndex","selectBestIndex","filterValues","getKeyValuesFromQuery","cursor","index","openCursor","IDBKeyRange","only","advance","push","value","continue","done","map","payload","PayloadHasher","jsonPayload","startHandler","openDB","indexName","extractFields","slice","split","IndexSeparator","field","toLowerCase","indexFields","indexNames","queryKeys","Set","Object","keys","key","bestMatch","matchCount","has"]}
|
|
1
|
+
{"version":3,"sources":["../../src/Schema.ts","../../src/Config.ts","../../src/Diviner.ts"],"sourcesContent":["import { PayloadDivinerSchema } from '@xyo-network/diviner-payload-model'\n\nexport const IndexedDbPayloadDivinerSchema = `${PayloadDivinerSchema}.indexeddb`\nexport type IndexedDbPayloadDivinerSchema = typeof IndexedDbPayloadDivinerSchema\n","import { IndexDescription } from '@xyo-network/archivist-model'\nimport { DivinerConfig } from '@xyo-network/diviner-model'\n\nimport { IndexedDbPayloadDivinerSchema } from './Schema'\n\nexport const IndexedDbPayloadDivinerConfigSchema = `${IndexedDbPayloadDivinerSchema}.config`\nexport type IndexedDbPayloadDivinerConfigSchema = typeof IndexedDbPayloadDivinerConfigSchema\n\nexport type IndexedDbPayloadDivinerConfig = DivinerConfig<{\n /**\n * The database name\n */\n dbName?: string\n /**\n * The version of the DB, defaults to 1\n */\n dbVersion?: number\n schema: IndexedDbPayloadDivinerConfigSchema\n /**\n * The storage configuration\n * // TODO: Hoist to main diviner config\n */\n storage?: {\n /**\n * The indexes to create on the object store\n */\n indexes?: IndexDescription[]\n }\n /**\n * The name of the object store\n */\n storeName?: string\n}>\n","import { containsAll } from '@xylabs/array'\nimport { assertEx } from '@xylabs/assert'\nimport { exists } from '@xylabs/exists'\nimport { IndexedDbArchivist } from '@xyo-network/archivist-indexeddb'\nimport { IndexSeparator } from '@xyo-network/archivist-model'\nimport { DivinerModule, DivinerModuleEventData } from '@xyo-network/diviner-model'\nimport { PayloadDiviner } from '@xyo-network/diviner-payload-abstract'\nimport { isPayloadDivinerQueryPayload, PayloadDivinerQueryPayload } from '@xyo-network/diviner-payload-model'\nimport { PayloadHasher } from '@xyo-network/hash'\nimport { AnyObject } from '@xyo-network/object'\nimport { Payload } from '@xyo-network/payload-model'\nimport { IDBPDatabase, IDBPObjectStore, openDB } from 'idb'\n\nimport { IndexedDbPayloadDivinerConfigSchema } from './Config'\nimport { IndexedDbPayloadDivinerParams } from './Params'\n\ninterface PayloadStore {\n [s: string]: Payload\n}\n\ntype AnyPayload = Payload<Record<string, unknown>>\n\ntype ValueFilter = (payload?: AnyPayload | null) => boolean\n\nconst payloadValueFilter = (key: keyof AnyPayload, value?: unknown | unknown[]): ValueFilter | undefined => {\n if (!value) return undefined\n return (payload) => {\n if (!payload) return false\n const sourceValue = payload?.[key]\n if (sourceValue === undefined) return false\n return Array.isArray(sourceValue) && Array.isArray(value) ? containsAll(sourceValue, value) : sourceValue == value\n }\n}\n\nexport class IndexedDbPayloadDiviner<\n TParams extends IndexedDbPayloadDivinerParams = IndexedDbPayloadDivinerParams,\n TIn extends PayloadDivinerQueryPayload = PayloadDivinerQueryPayload,\n TOut extends Payload = Payload,\n TEventData extends DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut> = DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut>,\n> extends PayloadDiviner<TParams, TIn, TOut, TEventData> {\n static override configSchemas = [IndexedDbPayloadDivinerConfigSchema]\n\n private _db: IDBPDatabase<PayloadStore> | undefined\n\n /**\n * The database name. If not supplied via config, it defaults\n * to the archivist's name and if archivist's name is not supplied,\n * it defaults to `archivist`. This behavior\n * biases towards a single, isolated DB per archivist which seems to\n * make the most sense for 99% of use cases.\n */\n get dbName() {\n return this.config?.dbName ?? this.config?.archivist ?? IndexedDbArchivist.defaultDbName\n }\n\n /**\n * The database version. If not supplied via config, it defaults to the archivist default version.\n */\n get dbVersion() {\n return this.config?.dbVersion ?? IndexedDbArchivist.defaultDbVersion\n }\n\n /**\n * The name of the object store. If not supplied via config, it defaults\n * to `payloads`.\n */\n get storeName() {\n return this.config?.storeName ?? IndexedDbArchivist.defaultStoreName\n }\n\n private get db(): IDBPDatabase<PayloadStore> {\n return assertEx(this._db, 'DB not initialized')\n }\n\n protected override async divineHandler(payloads?: TIn[]): Promise<TOut[]> {\n const query = assertEx(payloads?.filter(isPayloadDivinerQueryPayload)?.pop(), 'Missing query payload')\n if (!query) return []\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { schemas, limit, offset, hash, order, schema: _schema, sources, ...props } = query as unknown as TIn & { sources?: string[] }\n const tx = this.db.transaction(this.storeName, 'readonly')\n const store = tx.objectStore(this.storeName)\n const results: TOut[] = []\n let parsedOffset = offset ?? 0\n const parsedLimit = limit ?? 10\n assertEx((schemas?.length ?? 1) === 1, 'IndexedDbPayloadDiviner: Only one filter schema supported')\n const filterSchema = schemas?.[0]\n const filter = filterSchema ? { schema: filterSchema, ...props } : { ...props }\n const direction: IDBCursorDirection = order === 'desc' ? 'prev' : 'next'\n const suggestedIndex = this.selectBestIndex(filter, store)\n const keyRangeValue = this.getKeyRangeValue(suggestedIndex, filter)\n const valueFilters: ValueFilter[] = props\n ? Object.entries(props)\n .map(([key, value]) => payloadValueFilter(key, value))\n .filter(exists)\n : []\n let cursor = suggestedIndex\n ? // Conditionally filter on schemas\n await store.index(suggestedIndex).openCursor(IDBKeyRange.only(keyRangeValue), direction)\n : // Just iterate all records\n await store.openCursor(suggestedIndex, direction)\n\n // Skip records until the offset is reached\n while (cursor && parsedOffset > 0) {\n cursor = await cursor.advance(parsedOffset)\n parsedOffset = 0 // Reset offset after skipping\n }\n // Collect results up to the limit\n while (cursor && results.length < parsedLimit) {\n const value = cursor.value\n if (value) {\n // If we're filtering on more than just the schema\n if (valueFilters.length > 0) {\n // Ensure all filters pass\n if (valueFilters.every((filter) => filter(value))) {\n // Then save the value\n results.push(value)\n }\n } else {\n // Otherwise just save the value\n results.push(value)\n }\n }\n cursor = await cursor.continue()\n }\n await tx.done\n // Remove any metadata before returning to the client\n return results.map((payload) => PayloadHasher.jsonPayload(payload))\n }\n\n protected override async startHandler() {\n await super.startHandler()\n // NOTE: We could defer this creation to first access but we\n // want to fail fast here in case something is wrong\n this._db = await openDB<PayloadStore>(this.dbName, this.dbVersion)\n return true\n }\n\n private getKeyRangeValue(indexName: string | null, query: AnyObject): unknown | unknown[] {\n if (!indexName) return []\n // Function to extract fields from an index name\n const extractFields = (indexName: string): string[] => {\n return indexName\n .slice(3)\n .split(IndexSeparator)\n .map((field) => field.toLowerCase())\n }\n\n // Extracting the relevant fields from the index name\n const indexFields = extractFields(indexName)\n\n // Collecting the values for these fields from the query object\n const keyRangeValue = indexFields.map((field) => query[field as keyof AnyObject])\n return keyRangeValue.length === 1 ? keyRangeValue[0] : keyRangeValue\n }\n\n private selectBestIndex(query: AnyObject, store: IDBPObjectStore<PayloadStore>): string | null {\n // List of available indexes\n const { indexNames } = store\n\n // Function to extract fields from an index name\n const extractFields = (indexName: string): string[] => {\n return indexName\n .slice(3)\n .split(IndexSeparator)\n .map((field) => field.toLowerCase())\n }\n\n // Convert query object keys to a set for easier comparison\n const queryKeys = new Set(Object.keys(query).map((key) => key.toLowerCase()))\n\n // Find the best matching index\n let bestMatch: { indexName: string; matchCount: number } = { indexName: '', matchCount: 0 }\n\n for (const indexName of indexNames) {\n const indexFields = extractFields(indexName)\n const matchCount = indexFields.filter((field) => queryKeys.has(field)).length\n if (matchCount > bestMatch.matchCount) {\n bestMatch = { indexName, matchCount }\n }\n }\n return bestMatch.matchCount > 0 ? bestMatch.indexName : null\n }\n}\n"],"mappings":"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","names":["PayloadDivinerSchema","IndexedDbPayloadDivinerSchema","IndexedDbPayloadDivinerConfigSchema","IndexedDbPayloadDivinerSchema","containsAll","assertEx","exists","IndexedDbArchivist","IndexSeparator","PayloadDiviner","isPayloadDivinerQueryPayload","PayloadHasher","openDB","payloadValueFilter","key","value","undefined","payload","sourceValue","Array","isArray","containsAll","IndexedDbPayloadDiviner","PayloadDiviner","configSchemas","IndexedDbPayloadDivinerConfigSchema","_db","dbName","config","archivist","IndexedDbArchivist","defaultDbName","dbVersion","defaultDbVersion","storeName","defaultStoreName","db","assertEx","divineHandler","payloads","query","filter","isPayloadDivinerQueryPayload","pop","schemas","limit","offset","hash","order","schema","_schema","sources","props","tx","transaction","store","objectStore","results","parsedOffset","parsedLimit","length","filterSchema","direction","suggestedIndex","selectBestIndex","keyRangeValue","getKeyRangeValue","valueFilters","Object","entries","map","exists","cursor","index","openCursor","IDBKeyRange","only","advance","every","push","continue","done","PayloadHasher","jsonPayload","startHandler","openDB","indexName","extractFields","slice","split","IndexSeparator","field","toLowerCase","indexFields","indexNames","queryKeys","Set","keys","bestMatch","matchCount","has"]}
|
package/dist/node/Diviner.d.cts
CHANGED
|
@@ -5,25 +5,19 @@ import { Payload } from '@xyo-network/payload-model';
|
|
|
5
5
|
import { IndexedDbPayloadDivinerParams } from './Params';
|
|
6
6
|
export declare class IndexedDbPayloadDiviner<TParams extends IndexedDbPayloadDivinerParams = IndexedDbPayloadDivinerParams, TIn extends PayloadDivinerQueryPayload = PayloadDivinerQueryPayload, TOut extends Payload = Payload, TEventData extends DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut> = DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut>> extends PayloadDiviner<TParams, TIn, TOut, TEventData> {
|
|
7
7
|
static configSchemas: string[];
|
|
8
|
-
static defaultDbName: string;
|
|
9
|
-
static defaultDbVersion: number;
|
|
10
|
-
static defaultStoreName: string;
|
|
11
8
|
private _db;
|
|
12
9
|
/**
|
|
13
|
-
* The database name. If not supplied via config it defaults
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
* The database name. If not supplied via config, it defaults
|
|
11
|
+
* to the archivist's name and if archivist's name is not supplied,
|
|
12
|
+
* it defaults to `archivist`. This behavior
|
|
13
|
+
* biases towards a single, isolated DB per archivist which seems to
|
|
14
|
+
* make the most sense for 99% of use cases.
|
|
17
15
|
*/
|
|
18
16
|
get dbName(): string;
|
|
19
17
|
/**
|
|
20
|
-
* The database version. If not supplied via config, it defaults to
|
|
18
|
+
* The database version. If not supplied via config, it defaults to the archivist default version.
|
|
21
19
|
*/
|
|
22
20
|
get dbVersion(): number;
|
|
23
|
-
/**
|
|
24
|
-
* The database indexes.
|
|
25
|
-
*/
|
|
26
|
-
get indexes(): import("@xyo-network/archivist-model").IndexDescription[];
|
|
27
21
|
/**
|
|
28
22
|
* The name of the object store. If not supplied via config, it defaults
|
|
29
23
|
* to `payloads`.
|
|
@@ -32,7 +26,7 @@ export declare class IndexedDbPayloadDiviner<TParams extends IndexedDbPayloadDiv
|
|
|
32
26
|
private get db();
|
|
33
27
|
protected divineHandler(payloads?: TIn[]): Promise<TOut[]>;
|
|
34
28
|
protected startHandler(): Promise<boolean>;
|
|
35
|
-
private
|
|
29
|
+
private getKeyRangeValue;
|
|
36
30
|
private selectBestIndex;
|
|
37
31
|
}
|
|
38
32
|
//# sourceMappingURL=Diviner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Diviner.d.ts","sourceRoot":"","sources":["../../src/Diviner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Diviner.d.ts","sourceRoot":"","sources":["../../src/Diviner.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAA;AACtE,OAAO,EAAgC,0BAA0B,EAAE,MAAM,oCAAoC,CAAA;AAG7G,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAA;AAIpD,OAAO,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAA;AAoBxD,qBAAa,uBAAuB,CAClC,OAAO,SAAS,6BAA6B,GAAG,6BAA6B,EAC7E,GAAG,SAAS,0BAA0B,GAAG,0BAA0B,EACnE,IAAI,SAAS,OAAO,GAAG,OAAO,EAC9B,UAAU,SAAS,sBAAsB,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,sBAAsB,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CACxI,SAAQ,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC;IACtD,OAAgB,aAAa,WAAwC;IAErE,OAAO,CAAC,GAAG,CAAwC;IAEnD;;;;;;OAMG;IACH,IAAI,MAAM,WAET;IAED;;OAEG;IACH,IAAI,SAAS,WAEZ;IAED;;;OAGG;IACH,IAAI,SAAS,WAEZ;IAED,OAAO,KAAK,EAAE,GAEb;cAEwB,aAAa,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;cAuDhD,YAAY;IAQrC,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,eAAe;CA2BxB"}
|
package/dist/node/Diviner.d.mts
CHANGED
|
@@ -5,25 +5,19 @@ import { Payload } from '@xyo-network/payload-model';
|
|
|
5
5
|
import { IndexedDbPayloadDivinerParams } from './Params';
|
|
6
6
|
export declare class IndexedDbPayloadDiviner<TParams extends IndexedDbPayloadDivinerParams = IndexedDbPayloadDivinerParams, TIn extends PayloadDivinerQueryPayload = PayloadDivinerQueryPayload, TOut extends Payload = Payload, TEventData extends DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut> = DivinerModuleEventData<DivinerModule<TParams>, TIn, TOut>> extends PayloadDiviner<TParams, TIn, TOut, TEventData> {
|
|
7
7
|
static configSchemas: string[];
|
|
8
|
-
static defaultDbName: string;
|
|
9
|
-
static defaultDbVersion: number;
|
|
10
|
-
static defaultStoreName: string;
|
|
11
8
|
private _db;
|
|
12
9
|
/**
|
|
13
|
-
* The database name. If not supplied via config it defaults
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
* The database name. If not supplied via config, it defaults
|
|
11
|
+
* to the archivist's name and if archivist's name is not supplied,
|
|
12
|
+
* it defaults to `archivist`. This behavior
|
|
13
|
+
* biases towards a single, isolated DB per archivist which seems to
|
|
14
|
+
* make the most sense for 99% of use cases.
|
|
17
15
|
*/
|
|
18
16
|
get dbName(): string;
|
|
19
17
|
/**
|
|
20
|
-
* The database version. If not supplied via config, it defaults to
|
|
18
|
+
* The database version. If not supplied via config, it defaults to the archivist default version.
|
|
21
19
|
*/
|
|
22
20
|
get dbVersion(): number;
|
|
23
|
-
/**
|
|
24
|
-
* The database indexes.
|
|
25
|
-
*/
|
|
26
|
-
get indexes(): import("@xyo-network/archivist-model").IndexDescription[];
|
|
27
21
|
/**
|
|
28
22
|
* The name of the object store. If not supplied via config, it defaults
|
|
29
23
|
* to `payloads`.
|
|
@@ -32,7 +26,7 @@ export declare class IndexedDbPayloadDiviner<TParams extends IndexedDbPayloadDiv
|
|
|
32
26
|
private get db();
|
|
33
27
|
protected divineHandler(payloads?: TIn[]): Promise<TOut[]>;
|
|
34
28
|
protected startHandler(): Promise<boolean>;
|
|
35
|
-
private
|
|
29
|
+
private getKeyRangeValue;
|
|
36
30
|
private selectBestIndex;
|
|
37
31
|
}
|
|
38
32
|
//# sourceMappingURL=Diviner.d.ts.map
|