@karmaniverous/entity-manager 5.0.8 → 5.0.10
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/.github/FUNDING.yml +3 -0
- package/README.md +1 -2
- package/dist/cjs/BaseEntityClient/BaseEntityClient.js +28 -0
- package/dist/cjs/BaseQueryBuilder/BaseQueryBuilder.js +62 -0
- package/dist/cjs/EntityManager/EntityManager.js +131 -0
- package/dist/cjs/EntityManager/ParsedConfig.js +385 -0
- package/dist/cjs/EntityManager/addKeys.js +60 -0
- package/dist/cjs/EntityManager/createEntityManager.js +46 -0
- package/dist/cjs/EntityManager/decodeElement.js +46 -0
- package/dist/cjs/EntityManager/decodeGeneratedProperty.js +53 -0
- package/dist/cjs/EntityManager/dehydrateIndexItem.js +68 -0
- package/dist/cjs/EntityManager/dehydratePageKeyMap.js +93 -0
- package/dist/cjs/EntityManager/encodeElement.js +40 -0
- package/dist/cjs/EntityManager/encodeGeneratedProperty.js +55 -0
- package/dist/cjs/EntityManager/findIndexToken.js +10 -0
- package/dist/cjs/EntityManager/getHashKeySpace.js +89 -0
- package/dist/cjs/EntityManager/getIndexComponents.js +23 -0
- package/dist/cjs/EntityManager/getPrimaryKey.js +76 -0
- package/dist/cjs/EntityManager/getShardBump.js +24 -0
- package/dist/cjs/EntityManager/query.js +130 -0
- package/dist/cjs/EntityManager/rehydrateIndexItem.js +65 -0
- package/dist/cjs/EntityManager/rehydratePageKeyMap.js +103 -0
- package/dist/cjs/EntityManager/removeKeys.js +51 -0
- package/dist/cjs/EntityManager/unwrapIndex.js +59 -0
- package/dist/cjs/EntityManager/updateItemHashKey.js +79 -0
- package/dist/cjs/EntityManager/updateItemRangeKey.js +65 -0
- package/dist/cjs/EntityManager/validateEntityToken.js +17 -0
- package/dist/cjs/EntityManager/validateGeneratedProperty.js +23 -0
- package/dist/cjs/EntityManager/validateIndexToken.js +16 -0
- package/dist/cjs/EntityManager/validateTranscodedProperty.js +16 -0
- package/dist/cjs/index.js +15 -0
- package/dist/default/lib/EntityManager/EntityManager.js +46 -69
- package/dist/default/lib/EntityManager/PrivateEntityManager.js +44 -51
- package/dist/index.d.ts +1163 -0
- package/dist/mjs/BaseEntityClient/BaseEntityClient.js +26 -0
- package/dist/mjs/BaseQueryBuilder/BaseQueryBuilder.js +60 -0
- package/dist/mjs/EntityManager/EntityManager.js +129 -0
- package/dist/mjs/EntityManager/ParsedConfig.js +383 -0
- package/dist/mjs/EntityManager/addKeys.js +58 -0
- package/dist/mjs/EntityManager/createEntityManager.js +44 -0
- package/dist/mjs/EntityManager/decodeElement.js +44 -0
- package/dist/mjs/EntityManager/decodeGeneratedProperty.js +51 -0
- package/dist/mjs/EntityManager/dehydrateIndexItem.js +66 -0
- package/dist/mjs/EntityManager/dehydratePageKeyMap.js +91 -0
- package/dist/mjs/EntityManager/encodeElement.js +38 -0
- package/dist/mjs/EntityManager/encodeGeneratedProperty.js +53 -0
- package/dist/mjs/EntityManager/findIndexToken.js +8 -0
- package/dist/mjs/EntityManager/getHashKeySpace.js +87 -0
- package/dist/mjs/EntityManager/getIndexComponents.js +21 -0
- package/dist/mjs/EntityManager/getPrimaryKey.js +74 -0
- package/dist/mjs/EntityManager/getShardBump.js +22 -0
- package/dist/mjs/EntityManager/query.js +128 -0
- package/dist/mjs/EntityManager/rehydrateIndexItem.js +63 -0
- package/dist/mjs/EntityManager/rehydratePageKeyMap.js +101 -0
- package/dist/mjs/EntityManager/removeKeys.js +49 -0
- package/dist/mjs/EntityManager/unwrapIndex.js +57 -0
- package/dist/mjs/EntityManager/updateItemHashKey.js +77 -0
- package/dist/mjs/EntityManager/updateItemRangeKey.js +63 -0
- package/dist/mjs/EntityManager/validateEntityToken.js +15 -0
- package/dist/mjs/EntityManager/validateGeneratedProperty.js +21 -0
- package/dist/mjs/EntityManager/validateIndexToken.js +14 -0
- package/dist/mjs/EntityManager/validateTranscodedProperty.js +14 -0
- package/dist/mjs/index.js +5 -0
- package/docs/.nojekyll +1 -0
- package/docs/assets/hierarchy.js +1 -0
- package/docs/assets/highlight.css +99 -0
- package/docs/assets/icons.js +18 -0
- package/docs/assets/icons.svg +1 -0
- package/docs/assets/main.js +60 -0
- package/docs/assets/navigation.js +1 -0
- package/docs/assets/search.js +1 -0
- package/docs/assets/style.css +1648 -0
- package/docs/classes/index.BaseEntityClient.html +124 -0
- package/docs/classes/index.BaseQueryBuilder.html +229 -0
- package/docs/classes/index.EntityManager.html +510 -0
- package/docs/documents/CHANGELOG.html +1432 -0
- package/docs/documents/guides_stan-assistant-guide.html +431 -0
- package/docs/functions/index.createEntityManager.html +60 -0
- package/docs/hierarchy.html +31 -0
- package/docs/index.html +212 -0
- package/docs/interfaces/index.BaseConfigMap.html +113 -0
- package/docs/interfaces/index.BaseEntityClientOptions.html +82 -0
- package/docs/interfaces/index.BaseQueryBuilderOptions.html +92 -0
- package/docs/interfaces/index.CapturedConfigMapFrom.html +126 -0
- package/docs/interfaces/index.ConfigInput.html +189 -0
- package/docs/interfaces/index.ParsedConfig.html +144 -0
- package/docs/interfaces/index.ParsedEntityConfig.html +91 -0
- package/docs/interfaces/index.ParsedGeneratedPropertiesConfig.html +67 -0
- package/docs/interfaces/index.ParsedIndexConfig.html +79 -0
- package/docs/interfaces/index.ParsedTranscoder.html +71 -0
- package/docs/interfaces/index.QueryOptions.html +180 -0
- package/docs/interfaces/index.QueryResult.html +91 -0
- package/docs/interfaces/index.ShardBump.html +79 -0
- package/docs/interfaces/index.ShardQueryResult.html +93 -0
- package/docs/modules/index.html +47 -0
- package/docs/modules.html +38 -0
- package/docs/sitemap.xml +263 -0
- package/docs/types/index.BaseKeyTokens.html +39 -0
- package/docs/types/index.Config.html +75 -0
- package/docs/types/index.ConfigMap.html +41 -0
- package/docs/types/index.ConfigOfClient.html +45 -0
- package/docs/types/index.EntitiesFromSchema.html +39 -0
- package/docs/types/index.EntityClientItemByToken.html +45 -0
- package/docs/types/index.EntityClientRecordByToken.html +43 -0
- package/docs/types/index.EntityItem.html +41 -0
- package/docs/types/index.EntityItemPartial.html +44 -0
- package/docs/types/index.EntityKey.html +40 -0
- package/docs/types/index.EntityOfToken.html +39 -0
- package/docs/types/index.EntityRecord.html +39 -0
- package/docs/types/index.EntityRecordPartial.html +40 -0
- package/docs/types/index.EntityToken.html +40 -0
- package/docs/types/index.FallbackIndexTokenSet.html +40 -0
- package/docs/types/index.HasIndexFor.html +43 -0
- package/docs/types/index.HashKeyFrom.html +38 -0
- package/docs/types/index.IndexComponentTokens.html +45 -0
- package/docs/types/index.IndexHashKeyOf.html +42 -0
- package/docs/types/index.IndexRangeKeyOf.html +41 -0
- package/docs/types/index.IndexTokensFrom.html +41 -0
- package/docs/types/index.IndexTokensOf.html +40 -0
- package/docs/types/index.KeysFrom.html +38 -0
- package/docs/types/index.PageKey.html +40 -0
- package/docs/types/index.PageKeyByIndex.html +46 -0
- package/docs/types/index.PresentIndexTokenSet.html +45 -0
- package/docs/types/index.Projected.html +39 -0
- package/docs/types/index.QueryBuilderQueryOptions.html +45 -0
- package/docs/types/index.QueryOptionsByCC.html +49 -0
- package/docs/types/index.QueryOptionsByCF.html +47 -0
- package/docs/types/index.RangeKeyFrom.html +38 -0
- package/docs/types/index.ShardQueryFunction.html +63 -0
- package/docs/types/index.ShardQueryMap.html +56 -0
- package/docs/types/index.ShardQueryMapByCC.html +49 -0
- package/docs/types/index.ShardQueryMapByCF.html +47 -0
- package/docs/types/index.ShardedKeysFrom.html +38 -0
- package/docs/types/index.StorageItem.html +42 -0
- package/docs/types/index.StorageRecord.html +40 -0
- package/docs/types/index.TranscodedPropertiesFrom.html +38 -0
- package/docs/types/index.UnshardedKeysFrom.html +38 -0
- package/docs/types/index.ValidateConfigMap.html +40 -0
- package/lib/EntityManager/PrivateEntityManager.js +4 -0
- package/package.json +6 -6
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var entityTools = require('@karmaniverous/entity-tools');
|
|
4
|
+
var lzString = require('lz-string');
|
|
5
|
+
var radash = require('radash');
|
|
6
|
+
var dehydratePageKeyMap = require('./dehydratePageKeyMap.js');
|
|
7
|
+
var rehydratePageKeyMap = require('./rehydratePageKeyMap.js');
|
|
8
|
+
|
|
9
|
+
const { compressToEncodedURIComponent, decompressFromEncodedURIComponent } = lzString;
|
|
10
|
+
/**
|
|
11
|
+
* Query a database entity across shards in a provider-generic fashion.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* The provided {@link ShardQueryFunction | `ShardQueryFunction`} performs the actual query of individual data pages on individual shards. This function is presumed to express provider-specific query logic, including any necessary indexing or search constraints.
|
|
15
|
+
*
|
|
16
|
+
* Individual shard query results will be combined, deduped by {@link Config.uniqueProperty} property value, and sorted by {@link QueryOptions.sortOrder | `sortOrder`}.
|
|
17
|
+
*
|
|
18
|
+
* In queries on sharded data, expect the leading and trailing edges of returned data pages to interleave somewhat with preceding & following pages.
|
|
19
|
+
*
|
|
20
|
+
* Unsharded query results should sort & page as expected.
|
|
21
|
+
*
|
|
22
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
23
|
+
* @param options - {@link QueryOptions | `QueryOptions`} object.
|
|
24
|
+
*
|
|
25
|
+
* @returns {@link QueryResult} object.
|
|
26
|
+
*
|
|
27
|
+
* @throws Error if {@link QueryOptions.pageKeyMap | `pageKeyMap`} keys do not match {@link QueryOptions.shardQueryMap | `shardQueryMap`} keys.
|
|
28
|
+
*/
|
|
29
|
+
async function query(entityManager, options) {
|
|
30
|
+
try {
|
|
31
|
+
// Get defaults (avoid unsafe destructuring on generic access).
|
|
32
|
+
const entityDefaults = entityManager.config.entities[options.entityToken];
|
|
33
|
+
const defaultLimit = entityDefaults.defaultLimit;
|
|
34
|
+
const defaultPageSize = entityDefaults.defaultPageSize;
|
|
35
|
+
// Extract params.
|
|
36
|
+
const { entityToken, limit = defaultLimit, item, pageKeyMap, pageSize = defaultPageSize, shardQueryMap, sortOrder = [], timestampFrom = 0, timestampTo = Date.now(), throttle = entityManager.config.throttle, } = options;
|
|
37
|
+
// Validate params.
|
|
38
|
+
if (!(limit === Infinity || (radash.isInt(limit) && limit >= 1)))
|
|
39
|
+
throw new Error('limit must be a positive integer or Infinity.');
|
|
40
|
+
if (!(radash.isInt(pageSize) && pageSize >= 1))
|
|
41
|
+
throw new Error('pageSize must be a positive integer');
|
|
42
|
+
// Rehydrate pageKeyMap.
|
|
43
|
+
const [hashKeyToken, rehydratedPageKeyMap] = rehydratePageKeyMap.rehydratePageKeyMap(entityManager, entityToken, Object.keys(shardQueryMap).sort(), item, pageKeyMap
|
|
44
|
+
? JSON.parse(decompressFromEncodedURIComponent(pageKeyMap))
|
|
45
|
+
: undefined, timestampFrom, timestampTo);
|
|
46
|
+
// Shortcut if pageKeyMap is empty.
|
|
47
|
+
if (!Object.keys(rehydratedPageKeyMap).length)
|
|
48
|
+
return {
|
|
49
|
+
count: 0,
|
|
50
|
+
items: [],
|
|
51
|
+
pageKeyMap: compressToEncodedURIComponent(JSON.stringify([])),
|
|
52
|
+
};
|
|
53
|
+
// Iterate search over pages.
|
|
54
|
+
let workingResult = {
|
|
55
|
+
items: [],
|
|
56
|
+
pageKeyMap: rehydratedPageKeyMap,
|
|
57
|
+
};
|
|
58
|
+
do {
|
|
59
|
+
// TODO: This loop will blow up as shards scale, since at a minimum it will return shardCount * pageSize
|
|
60
|
+
// items, which may be >> limit. Probably the way to fix entityManager is to limit the number of shards queried per
|
|
61
|
+
// iteration in order to keep shardsQueried * pageSize > (limit - items.length) but only just.
|
|
62
|
+
// TODO: Test for invalid characters (path delimiters) in index keys & shard key values.
|
|
63
|
+
// Build typed tasks (indexToken, hashKey, pageKey).
|
|
64
|
+
const tasks = [];
|
|
65
|
+
for (const [indexToken, indexPageKeys] of Object.entries(rehydratedPageKeyMap)) {
|
|
66
|
+
for (const [hashKey, pk] of Object.entries(indexPageKeys)) {
|
|
67
|
+
tasks.push([indexToken, hashKey, pk]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Query every shard on every index in pageKeyMap.
|
|
71
|
+
const shardQueryResults = await radash.parallel(throttle, tasks, async ([indexToken, hashKey, pageKey]) => ({
|
|
72
|
+
indexToken,
|
|
73
|
+
queryResult: await shardQueryMap[indexToken](hashKey, pageKey, pageSize),
|
|
74
|
+
hashKey,
|
|
75
|
+
}));
|
|
76
|
+
// Reduce shardQueryResults & update working result.
|
|
77
|
+
workingResult = shardQueryResults.reduce(({ items, pageKeyMap }, { indexToken, queryResult, hashKey }) => {
|
|
78
|
+
Object.assign(rehydratedPageKeyMap[indexToken], {
|
|
79
|
+
[hashKey]: queryResult.pageKey,
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
items: [...items, ...queryResult.items],
|
|
83
|
+
pageKeyMap,
|
|
84
|
+
};
|
|
85
|
+
}, workingResult);
|
|
86
|
+
// Repeat while pages remain & limit is not reached.
|
|
87
|
+
let pagesRemain = false;
|
|
88
|
+
for (const idx of Object.keys(workingResult.pageKeyMap)) {
|
|
89
|
+
const inner = workingResult.pageKeyMap[idx];
|
|
90
|
+
for (const h of Object.keys(inner)) {
|
|
91
|
+
if (inner[h] !== undefined) {
|
|
92
|
+
pagesRemain = true;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (pagesRemain)
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
if (!pagesRemain)
|
|
100
|
+
break;
|
|
101
|
+
} while (workingResult.items.length < limit);
|
|
102
|
+
// Dedupe & sort working result.
|
|
103
|
+
// Note: when projecting, callers may omit uniqueProperty/sort keys.
|
|
104
|
+
// We perform operations on the full item shape and then cast back.
|
|
105
|
+
const itemsForOps = workingResult.items;
|
|
106
|
+
const dedupedSorted = entityTools.sort(radash.unique(itemsForOps, (i) => i[entityManager.config.entities[entityToken]
|
|
107
|
+
.uniqueProperty].toString()), sortOrder);
|
|
108
|
+
workingResult.items = dedupedSorted;
|
|
109
|
+
const result = {
|
|
110
|
+
count: workingResult.items.length,
|
|
111
|
+
items: workingResult.items,
|
|
112
|
+
pageKeyMap: compressToEncodedURIComponent(JSON.stringify(dehydratePageKeyMap.dehydratePageKeyMap(entityManager, entityToken, workingResult.pageKeyMap))),
|
|
113
|
+
};
|
|
114
|
+
entityManager.logger.debug('queried entityToken across shards', {
|
|
115
|
+
options,
|
|
116
|
+
hashKeyToken,
|
|
117
|
+
rehydratedPageKeyMap,
|
|
118
|
+
workingResult,
|
|
119
|
+
result,
|
|
120
|
+
});
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
if (error instanceof Error)
|
|
125
|
+
entityManager.logger.error(error.message, options);
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
exports.query = query;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var radash = require('radash');
|
|
4
|
+
var decodeElement = require('./decodeElement.js');
|
|
5
|
+
var unwrapIndex = require('./unwrapIndex.js');
|
|
6
|
+
var validateEntityToken = require('./validateEntityToken.js');
|
|
7
|
+
var validateIndexToken = require('./validateIndexToken.js');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Convert a delimited string into an {@link EntityItem | `EntityItem`} object representing the ungenerated component elements of a Config entity index, minus its hash key.
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* Reverses {@link EntityManager.dehydrateIndexItem | `dehydrateIndexItem`}.
|
|
14
|
+
*
|
|
15
|
+
* {@link EntityManager.dehydrateIndexItem | `dehydrateIndexItem`} alphebetically sorts unwrapped index elements during the dehydration process. This method assumes delimited element values are presented in the same order.
|
|
16
|
+
*
|
|
17
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
18
|
+
* @param entityToken - {@link Config.entities | `entityManager.config.entities`} key.
|
|
19
|
+
* @param indexToken - {@link Config.indexes | `entityManager.config.indexes`} key.
|
|
20
|
+
* @param dehydrated - Dehydrated index value.
|
|
21
|
+
*
|
|
22
|
+
* @returns {@link EntityItem | `EntityItem`} object containing rehydrated index component elements.
|
|
23
|
+
*
|
|
24
|
+
* @throws `Error` if `entityToken` is invalid.
|
|
25
|
+
* @throws `Error` if `indexToken` is invalid.
|
|
26
|
+
*/
|
|
27
|
+
function rehydrateIndexItem(entityManager, entityToken, indexToken, dehydrated) {
|
|
28
|
+
try {
|
|
29
|
+
// Validate params.
|
|
30
|
+
validateEntityToken.validateEntityToken(entityManager, entityToken);
|
|
31
|
+
validateIndexToken.validateIndexToken(entityManager, indexToken);
|
|
32
|
+
// Unwrap index elements.
|
|
33
|
+
const { hashKey } = entityManager.config.indexes[indexToken];
|
|
34
|
+
const elements = unwrapIndex.unwrapIndex(entityManager, entityToken, indexToken, [
|
|
35
|
+
hashKey,
|
|
36
|
+
]);
|
|
37
|
+
// Split dehydrated value & validate.
|
|
38
|
+
const { generatedKeyDelimiter } = entityManager.config;
|
|
39
|
+
const values = dehydrated.split(generatedKeyDelimiter);
|
|
40
|
+
if (elements.length !== values.length)
|
|
41
|
+
throw new Error('index rehydration key-value mismatch');
|
|
42
|
+
// Assign values to elements.
|
|
43
|
+
const rehydrated = radash.shake(radash.zipToObject(elements, values.map((value, i) => decodeElement.decodeElement(entityManager, elements[i], value))));
|
|
44
|
+
entityManager.logger.debug('rehydrated index', {
|
|
45
|
+
entityToken,
|
|
46
|
+
indexToken,
|
|
47
|
+
dehydrated,
|
|
48
|
+
elements,
|
|
49
|
+
values,
|
|
50
|
+
rehydrated,
|
|
51
|
+
});
|
|
52
|
+
return rehydrated;
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (error instanceof Error)
|
|
56
|
+
entityManager.logger.error(error.message, {
|
|
57
|
+
entityToken,
|
|
58
|
+
indexToken,
|
|
59
|
+
dehydrated,
|
|
60
|
+
});
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
exports.rehydrateIndexItem = rehydrateIndexItem;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var radash = require('radash');
|
|
4
|
+
var decodeGeneratedProperty = require('./decodeGeneratedProperty.js');
|
|
5
|
+
var encodeGeneratedProperty = require('./encodeGeneratedProperty.js');
|
|
6
|
+
var getHashKeySpace = require('./getHashKeySpace.js');
|
|
7
|
+
var getIndexComponents = require('./getIndexComponents.js');
|
|
8
|
+
var rehydrateIndexItem = require('./rehydrateIndexItem.js');
|
|
9
|
+
var updateItemRangeKey = require('./updateItemRangeKey.js');
|
|
10
|
+
var validateEntityToken = require('./validateEntityToken.js');
|
|
11
|
+
var validateIndexToken = require('./validateIndexToken.js');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Rehydrate an array of dehydrated page keys into a {@link PageKeyMap | `PageKeyMap`} object.
|
|
15
|
+
*
|
|
16
|
+
* Reverses the {@link EntityManager.dehydratePageKeyMap | `dehydratePageKeyMap`} method.
|
|
17
|
+
*
|
|
18
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
19
|
+
* @param entityToken - {@link Config.entities | `entityManager.config.entities`} key.
|
|
20
|
+
* @param indexTokens - Array of {@link Config.indexes | `entityManager.config.indexes`} keys used as keys of the original {@link PageKeyMap | `PageKeyMap`}.
|
|
21
|
+
* @param item - Partial item object sufficiently populated to generate index hash keys.
|
|
22
|
+
* @param dehydrated - Array of dehydrated page keys or undefined if new query.
|
|
23
|
+
* @param timestampFrom - Lower timestanp limit used to generate the original {@link PageKeyMap | `PageKeyMap`}. Defaults to `0`.
|
|
24
|
+
* @param timestampTo - Upper timestamp limit used to generate the original {@link PageKeyMap | `PageKeyMap`}. Defaults to `Date.now()`.
|
|
25
|
+
*
|
|
26
|
+
* @returns A tuple of `hashKeyToken` and rehydrated {@link PageKeyMap | `PageKeyMap`} object.
|
|
27
|
+
*
|
|
28
|
+
* @throws `Error` if `entityToken` is invalid.
|
|
29
|
+
* @throws `Error` if `indexTokens` is empty.
|
|
30
|
+
* @throws `Error` if any `indexTokens` are invalid.
|
|
31
|
+
* @throws `Error` if `indexTokens` represent indexes with inconsistent hashKeys.
|
|
32
|
+
* @throws `Error` if `dehydrated` has invalid length.
|
|
33
|
+
*/
|
|
34
|
+
function rehydratePageKeyMap(entityManager, entityToken, indexTokens, item, dehydrated, timestampFrom = 0, timestampTo = Date.now()) {
|
|
35
|
+
try {
|
|
36
|
+
// Validate params.
|
|
37
|
+
validateEntityToken.validateEntityToken(entityManager, entityToken);
|
|
38
|
+
// Validate indexTokens populated.
|
|
39
|
+
if (!indexTokens.length)
|
|
40
|
+
throw new Error('indexTokens empty');
|
|
41
|
+
// Validate indexTokens exist and capture hashKeys.
|
|
42
|
+
const hashKeys = radash.unique(indexTokens.map((indexToken) => {
|
|
43
|
+
validateIndexToken.validateIndexToken(entityManager, indexToken);
|
|
44
|
+
return entityManager.config.indexes[indexToken].hashKey;
|
|
45
|
+
}));
|
|
46
|
+
// Validate hashKeys consistent.
|
|
47
|
+
if (hashKeys.length > 1)
|
|
48
|
+
throw new Error('inconsistent hashKeys');
|
|
49
|
+
const [hashKeyToken] = hashKeys;
|
|
50
|
+
indexTokens.map((index) => {
|
|
51
|
+
validateIndexToken.validateIndexToken(entityManager, index);
|
|
52
|
+
});
|
|
53
|
+
// Shortcut empty dehydrated.
|
|
54
|
+
if (dehydrated && !dehydrated.length)
|
|
55
|
+
return [
|
|
56
|
+
hashKeyToken,
|
|
57
|
+
{},
|
|
58
|
+
];
|
|
59
|
+
// Get hash key space.
|
|
60
|
+
const hashKeySpace = getHashKeySpace.getHashKeySpace(entityManager, entityToken, hashKeyToken, item, timestampFrom, timestampTo);
|
|
61
|
+
// Default dehydrated.
|
|
62
|
+
dehydrated ?? (dehydrated = [...radash.range(1, hashKeySpace.length * indexTokens.length, '')]);
|
|
63
|
+
// Validate dehydrated length
|
|
64
|
+
if (dehydrated.length !== hashKeySpace.length * indexTokens.length)
|
|
65
|
+
throw new Error('dehydrated length mismatch');
|
|
66
|
+
// Rehydrate pageKeys.
|
|
67
|
+
const uniqueProperty = entityManager.config.entities[entityToken]
|
|
68
|
+
.uniqueProperty;
|
|
69
|
+
const { sharded, unsharded } = entityManager.config.generatedProperties;
|
|
70
|
+
const rehydrated = radash.mapValues(radash.zipToObject(indexTokens, radash.cluster(dehydrated, hashKeySpace.length)), (dehydratedIndexPageKeyMaps, index) => radash.zipToObject(hashKeySpace, (hashKey, i) => {
|
|
71
|
+
if (!dehydratedIndexPageKeyMaps[i])
|
|
72
|
+
return;
|
|
73
|
+
let pageKeyItem = {
|
|
74
|
+
...decodeGeneratedProperty.decodeGeneratedProperty(entityManager, entityToken, hashKey),
|
|
75
|
+
...rehydrateIndexItem.rehydrateIndexItem(entityManager, entityToken, index, dehydratedIndexPageKeyMaps[i]),
|
|
76
|
+
};
|
|
77
|
+
pageKeyItem = updateItemRangeKey.updateItemRangeKey(entityManager, entityToken, pageKeyItem);
|
|
78
|
+
return radash.zipToObject(getIndexComponents.getIndexComponents(entityManager, index), (component) => component === entityManager.config.rangeKey
|
|
79
|
+
? [uniqueProperty, pageKeyItem[uniqueProperty]].join(entityManager.config.generatedValueDelimiter)
|
|
80
|
+
: component in sharded || component in unsharded
|
|
81
|
+
? encodeGeneratedProperty.encodeGeneratedProperty(entityManager, component, pageKeyItem)
|
|
82
|
+
: pageKeyItem[component]);
|
|
83
|
+
}));
|
|
84
|
+
entityManager.logger.debug('rehydrated page key map', {
|
|
85
|
+
entityToken,
|
|
86
|
+
indexTokens,
|
|
87
|
+
dehydrated,
|
|
88
|
+
rehydrated,
|
|
89
|
+
});
|
|
90
|
+
return [hashKeyToken, rehydrated];
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
if (error instanceof Error)
|
|
94
|
+
entityManager.logger.error(error.message, {
|
|
95
|
+
entityToken,
|
|
96
|
+
indexTokens,
|
|
97
|
+
dehydrated,
|
|
98
|
+
});
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
exports.rehydratePageKeyMap = rehydratePageKeyMap;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var validateEntityToken = require('./validateEntityToken.js');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Strips generated properties, hash key, and range key from an {@link EntityRecord | `EntityRecord`} object.
|
|
7
|
+
*
|
|
8
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
9
|
+
* @param entityToken - {@link Config.entities | `entityManager.config.entities`} key.
|
|
10
|
+
* @param item - {@link EntityRecord | `EntityRecord`} object.
|
|
11
|
+
*
|
|
12
|
+
* @returns {@link EntityItem | `EntityItem`} with generated properties, hash key & range key removed.
|
|
13
|
+
*
|
|
14
|
+
* @throws `Error` if `entityToken` is invalid.
|
|
15
|
+
*/
|
|
16
|
+
function removeKeys(entityManager, entityToken, item) {
|
|
17
|
+
try {
|
|
18
|
+
// Validate params.
|
|
19
|
+
validateEntityToken.validateEntityToken(entityManager, entityToken);
|
|
20
|
+
// Build a set of keys to strip (hash, range, and all generated properties).
|
|
21
|
+
const { hashKey, rangeKey, generatedProperties: { sharded, unsharded }, } = entityManager.config;
|
|
22
|
+
const keysToStrip = new Set([
|
|
23
|
+
hashKey,
|
|
24
|
+
rangeKey,
|
|
25
|
+
...Object.keys(sharded),
|
|
26
|
+
...Object.keys(unsharded),
|
|
27
|
+
]);
|
|
28
|
+
// Create a shallow copy of item omitting the keys above (no delete operator),
|
|
29
|
+
// avoiding any-typed assignments.
|
|
30
|
+
const source = item;
|
|
31
|
+
const newItemObj = {};
|
|
32
|
+
for (const [key, value] of Object.entries(source)) {
|
|
33
|
+
if (!keysToStrip.has(key)) {
|
|
34
|
+
newItemObj[key] = value;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
entityManager.logger.debug('stripped entity item generated properties', {
|
|
38
|
+
entityToken,
|
|
39
|
+
item,
|
|
40
|
+
newItem: newItemObj,
|
|
41
|
+
});
|
|
42
|
+
return newItemObj;
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (error instanceof Error)
|
|
46
|
+
entityManager.logger.error(error.message, { entityToken, item });
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
exports.removeKeys = removeKeys;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var radash = require('radash');
|
|
4
|
+
var getIndexComponents = require('./getIndexComponents.js');
|
|
5
|
+
var validateEntityToken = require('./validateEntityToken.js');
|
|
6
|
+
var validateIndexToken = require('./validateIndexToken.js');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Unwraps an {@link Config.indexes | index} into deduped, sorted, ungenerated index component elements.
|
|
10
|
+
*
|
|
11
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
12
|
+
* @param entityToken - {@link Config.entities | `entityManager.config.entities`} key.
|
|
13
|
+
* @param indexToken - {@link ConfigEntity.indexes | `entityManager.config.entities.<entityToken>.indexes`} key.
|
|
14
|
+
* @param omit - Array of index components or elements to omit from the output value.
|
|
15
|
+
*
|
|
16
|
+
* @returns Deduped, sorted array of ungenerated index component elements.
|
|
17
|
+
*
|
|
18
|
+
* @throws `Error` if `entityToken` is invalid.
|
|
19
|
+
* @throws `Error` if `indexToken` is invalid.
|
|
20
|
+
*/
|
|
21
|
+
function unwrapIndex(entityManager, entityToken, indexToken, omit = []) {
|
|
22
|
+
try {
|
|
23
|
+
// Validate params.
|
|
24
|
+
validateEntityToken.validateEntityToken(entityManager, entityToken);
|
|
25
|
+
validateIndexToken.validateIndexToken(entityManager, indexToken);
|
|
26
|
+
const { sharded, unsharded } = entityManager.config.generatedProperties;
|
|
27
|
+
const unwrapped = radash.unique(getIndexComponents.getIndexComponents(entityManager, indexToken)
|
|
28
|
+
.filter((component) => !omit.includes(component))
|
|
29
|
+
.map((component) => component === entityManager.config.hashKey
|
|
30
|
+
? entityManager.config.entities[entityToken].timestampProperty
|
|
31
|
+
: component === entityManager.config.rangeKey
|
|
32
|
+
? entityManager.config.entities[entityToken].uniqueProperty
|
|
33
|
+
: component in sharded
|
|
34
|
+
? sharded[component]
|
|
35
|
+
: component in unsharded
|
|
36
|
+
? unsharded[component]
|
|
37
|
+
: component)
|
|
38
|
+
.flat()
|
|
39
|
+
.filter((element) => !omit.includes(element))).sort();
|
|
40
|
+
entityManager.logger.debug('unwrapped index', {
|
|
41
|
+
entityToken,
|
|
42
|
+
indexToken,
|
|
43
|
+
omit,
|
|
44
|
+
unwrapped,
|
|
45
|
+
});
|
|
46
|
+
return unwrapped;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (error instanceof Error)
|
|
50
|
+
entityManager.logger.error(error.message, {
|
|
51
|
+
entityToken,
|
|
52
|
+
indexToken,
|
|
53
|
+
omit,
|
|
54
|
+
});
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
exports.unwrapIndex = unwrapIndex;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var entityTools = require('@karmaniverous/entity-tools');
|
|
4
|
+
var stringHash = require('string-hash');
|
|
5
|
+
var getShardBump = require('./getShardBump.js');
|
|
6
|
+
var validateEntityToken = require('./validateEntityToken.js');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Update the hash key on an {@link EntityItemPartial | `EntityItemPartial`} object.
|
|
10
|
+
*
|
|
11
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
12
|
+
* @param entityToken - {@link Config.entities | `this.config.entities`} key.
|
|
13
|
+
* @param item - {@link StorageItem | `StorageItem`} object.
|
|
14
|
+
* @param overwrite - Overwrite existing {@link ConfigKeys.hashKey | `this.config.hashKey`} property value (default `false`).
|
|
15
|
+
*
|
|
16
|
+
* @returns Shallow clone of `item` with updated hash key.
|
|
17
|
+
*
|
|
18
|
+
* @throws `Error` if `entityToken` is invalid.
|
|
19
|
+
*/
|
|
20
|
+
function updateItemHashKey(entityManager, entityToken, item, overwrite = false) {
|
|
21
|
+
try {
|
|
22
|
+
// Validate params.
|
|
23
|
+
validateEntityToken.validateEntityToken(entityManager, entityToken);
|
|
24
|
+
// Return current item if hashKey exists and overwrite is false.
|
|
25
|
+
if (item[entityManager.config.hashKey] &&
|
|
26
|
+
!overwrite) {
|
|
27
|
+
entityManager.logger.debug('did not overwrite existing entity item hash key', {
|
|
28
|
+
item,
|
|
29
|
+
entityToken,
|
|
30
|
+
overwrite,
|
|
31
|
+
});
|
|
32
|
+
return { ...item };
|
|
33
|
+
}
|
|
34
|
+
// Get item timestamp property & validate.
|
|
35
|
+
const tsProp = entityManager.config.entities[entityToken]
|
|
36
|
+
.timestampProperty;
|
|
37
|
+
const timestamp = item[tsProp];
|
|
38
|
+
if (entityTools.isNil(timestamp))
|
|
39
|
+
throw new Error(`missing item timestamp property`);
|
|
40
|
+
// Find first entity sharding bump before timestamp.
|
|
41
|
+
const { charBits, chars } = getShardBump.getShardBump(entityManager, entityToken, timestamp);
|
|
42
|
+
let hashKey = `${String(entityToken)}${entityManager.config.shardKeyDelimiter}`;
|
|
43
|
+
if (chars) {
|
|
44
|
+
// Radix is the numerical base of the shardKey.
|
|
45
|
+
const radix = 2 ** charBits;
|
|
46
|
+
// Compute the full shard space for this bump. Use radix ** chars to ensure
|
|
47
|
+
// all placeholders are utilized (e.g., chars=2, charBits=2 => 16 combos).
|
|
48
|
+
const space = radix ** chars;
|
|
49
|
+
// Get item unique property & validate.
|
|
50
|
+
const upProp = entityManager.config.entities[entityToken]
|
|
51
|
+
.uniqueProperty;
|
|
52
|
+
const uniqueId = item[upProp];
|
|
53
|
+
if (entityTools.isNil(uniqueId))
|
|
54
|
+
throw new Error(`missing item unique property`);
|
|
55
|
+
hashKey += (stringHash(uniqueId) % space)
|
|
56
|
+
.toString(radix)
|
|
57
|
+
.padStart(chars, '0');
|
|
58
|
+
}
|
|
59
|
+
const newItem = Object.assign({ ...item }, { [entityManager.config.hashKey]: hashKey });
|
|
60
|
+
entityManager.logger.debug('updated entity item hash key', {
|
|
61
|
+
entityToken,
|
|
62
|
+
overwrite,
|
|
63
|
+
item,
|
|
64
|
+
newItem,
|
|
65
|
+
});
|
|
66
|
+
return newItem;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (error instanceof Error)
|
|
70
|
+
entityManager.logger.error(error.message, {
|
|
71
|
+
entityToken,
|
|
72
|
+
item,
|
|
73
|
+
overwrite,
|
|
74
|
+
});
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
exports.updateItemHashKey = updateItemHashKey;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var entityTools = require('@karmaniverous/entity-tools');
|
|
4
|
+
var validateEntityToken = require('./validateEntityToken.js');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Update the range key on an {@link EntityItemPartial | `EntityItemPartial`} object.
|
|
8
|
+
*
|
|
9
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
10
|
+
* @param entityToken - {@link Config.entities | `this.config.entities`} key.
|
|
11
|
+
* @param item - {@link StorageItem | `StorageItem`} object.
|
|
12
|
+
* @param overwrite - Overwrite existing {@link ConfigKeys.rangeKey | `this.config.rangeKey`} property value (default `false`).
|
|
13
|
+
*
|
|
14
|
+
* @returns Shallow clone of `item` with updated range key.
|
|
15
|
+
*
|
|
16
|
+
* @throws `Error` if `entityToken` is invalid.
|
|
17
|
+
* @throws `Error` if `item` {@link Config.uniqueProperty | `this.config.entities<entityToken>.uniqueProperty`} property value is missing.
|
|
18
|
+
*/
|
|
19
|
+
function updateItemRangeKey(entityManager, entityToken, item, overwrite = false) {
|
|
20
|
+
try {
|
|
21
|
+
// Validate params.
|
|
22
|
+
validateEntityToken.validateEntityToken(entityManager, entityToken);
|
|
23
|
+
// Return current item if rangeKey exists and overwrite is false.
|
|
24
|
+
const rkProp = entityManager.config.rangeKey;
|
|
25
|
+
if (item[rkProp] && !overwrite) {
|
|
26
|
+
entityManager.logger.debug('did not overwrite existing entity item range key', {
|
|
27
|
+
entityToken,
|
|
28
|
+
item,
|
|
29
|
+
overwrite,
|
|
30
|
+
});
|
|
31
|
+
return { ...item };
|
|
32
|
+
}
|
|
33
|
+
// Get item unique property & validate.
|
|
34
|
+
const upProp = entityManager.config.entities[entityToken]
|
|
35
|
+
.uniqueProperty;
|
|
36
|
+
const uniqueValue = item[upProp];
|
|
37
|
+
if (entityTools.isNil(uniqueValue))
|
|
38
|
+
throw new Error(`missing item unique property`);
|
|
39
|
+
// Update range key.
|
|
40
|
+
const newItem = Object.assign({ ...item }, {
|
|
41
|
+
[entityManager.config.rangeKey]: [
|
|
42
|
+
entityManager.config.entities[entityToken].uniqueProperty,
|
|
43
|
+
uniqueValue,
|
|
44
|
+
].join(entityManager.config.generatedValueDelimiter),
|
|
45
|
+
});
|
|
46
|
+
entityManager.logger.debug('updated entity item range key', {
|
|
47
|
+
entityToken,
|
|
48
|
+
overwrite,
|
|
49
|
+
item,
|
|
50
|
+
newItem,
|
|
51
|
+
});
|
|
52
|
+
return newItem;
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (error instanceof Error)
|
|
56
|
+
entityManager.logger.error(error.message, {
|
|
57
|
+
entityToken,
|
|
58
|
+
item,
|
|
59
|
+
overwrite,
|
|
60
|
+
});
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
exports.updateItemRangeKey = updateItemRangeKey;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Validate that an entity is defined in the EntityManager config.
|
|
5
|
+
*
|
|
6
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
7
|
+
* @param entityToken - `entityManager.config.entities` key.
|
|
8
|
+
*
|
|
9
|
+
* @throws `Error` if `entityToken` is invalid.
|
|
10
|
+
*/
|
|
11
|
+
function validateEntityToken(entityManager, entityToken) {
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
13
|
+
if (!entityManager.config.entities[entityToken])
|
|
14
|
+
throw new Error('invalid entity token');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
exports.validateEntityToken = validateEntityToken;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Validate that a property is defined as an {@link EntityManager | `EntityManager`} {@link Config.generatedProperties | generated property}.
|
|
5
|
+
*
|
|
6
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
7
|
+
* @param property - {@link Config.generatedProperties | Generated property} key.
|
|
8
|
+
* @param isSharded - Whether the generated property is sharded. `undefined` indicates no constraint.
|
|
9
|
+
*
|
|
10
|
+
* @throws `Error` if `property` is not a {@link Config.generatedProperties | generated property}.
|
|
11
|
+
* @throws `Error` if `sharded` is specified & does not match {@link Config.generatedProperties | generated property} type.
|
|
12
|
+
*/
|
|
13
|
+
function validateGeneratedProperty(entityManager, property, isSharded) {
|
|
14
|
+
const { sharded, unsharded } = entityManager.config.generatedProperties;
|
|
15
|
+
if (!(property in sharded) && !(property in unsharded))
|
|
16
|
+
throw new Error('invalid generated property');
|
|
17
|
+
if (isSharded !== undefined &&
|
|
18
|
+
((isSharded && !(property in sharded)) ||
|
|
19
|
+
(!isSharded && !(property in unsharded))))
|
|
20
|
+
throw new Error(`generated property ${isSharded ? 'not ' : ''}sharded`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
exports.validateGeneratedProperty = validateGeneratedProperty;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Validate that an entity index is defined in EntityManager config.
|
|
5
|
+
*
|
|
6
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
7
|
+
* @param indexToken - {@link Config.indexes | `entityManager.config.indexes`} key.
|
|
8
|
+
*
|
|
9
|
+
* @throws `Error` if `indexToken` is invalid.
|
|
10
|
+
*/
|
|
11
|
+
function validateIndexToken(entityManager, indexToken) {
|
|
12
|
+
if (!(indexToken in entityManager.config.indexes))
|
|
13
|
+
throw new Error('invalid index token');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.validateIndexToken = validateIndexToken;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Validate that a property is defined as an {@link EntityManager | `EntityManager`} {@link Config.propertyTranscodes | transcoded property}.
|
|
5
|
+
*
|
|
6
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
7
|
+
* @param property - {@link Config.propertyTranscodes | Transcoded property} key.
|
|
8
|
+
*
|
|
9
|
+
* @throws `Error` if `property` is not a {@link Config.propertyTranscodes | transcoded property}.
|
|
10
|
+
*/
|
|
11
|
+
function validateTranscodedProperty(entityManager, property) {
|
|
12
|
+
if (!(property in entityManager.config.propertyTranscodes))
|
|
13
|
+
throw new Error('invalid transcoded property');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.validateTranscodedProperty = validateTranscodedProperty;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var BaseEntityClient = require('./BaseEntityClient/BaseEntityClient.js');
|
|
4
|
+
var BaseQueryBuilder = require('./BaseQueryBuilder/BaseQueryBuilder.js');
|
|
5
|
+
var createEntityManager = require('./EntityManager/createEntityManager.js');
|
|
6
|
+
var EntityManager = require('./EntityManager/EntityManager.js');
|
|
7
|
+
var ParsedConfig = require('./EntityManager/ParsedConfig.js');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
exports.BaseEntityClient = BaseEntityClient.BaseEntityClient;
|
|
12
|
+
exports.BaseQueryBuilder = BaseQueryBuilder.BaseQueryBuilder;
|
|
13
|
+
exports.createEntityManager = createEntityManager.createEntityManager;
|
|
14
|
+
exports.EntityManager = EntityManager.EntityManager;
|
|
15
|
+
exports.configSchema = ParsedConfig.configSchema;
|