@karmaniverous/entity-manager 6.7.4 → 6.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/cjs/BaseEntityClient.js +1 -1
  2. package/dist/cjs/{BaseShardQueryMapBuilder.js → BaseQueryBuilder.js} +4 -4
  3. package/dist/cjs/EntityManager.js +8 -8
  4. package/dist/cjs/ParsedConfig.js +143 -113
  5. package/dist/cjs/addKeys.js +6 -6
  6. package/dist/{mjs/decodeEntityElement.js → cjs/decodeElement.js} +10 -12
  7. package/dist/cjs/decodeGeneratedProperty.js +6 -10
  8. package/dist/cjs/dehydrateIndexItem.js +12 -11
  9. package/dist/cjs/dehydratePageKeyMap.js +10 -7
  10. package/dist/{mjs/encodeEntityElement.js → cjs/encodeElement.js} +8 -10
  11. package/dist/cjs/encodeGeneratedProperty.js +13 -14
  12. package/dist/cjs/getHashKeySpace.js +6 -6
  13. package/dist/cjs/getIndexComponents.js +6 -8
  14. package/dist/cjs/getShardBump.js +1 -1
  15. package/dist/cjs/index.js +2 -2
  16. package/dist/cjs/query.js +1 -1
  17. package/dist/cjs/rehydrateIndexItem.js +12 -10
  18. package/dist/cjs/rehydratePageKeyMap.js +18 -11
  19. package/dist/cjs/removeKeys.js +3 -2
  20. package/dist/cjs/unwrapIndex.js +25 -11
  21. package/dist/cjs/updateItemHashKey.js +5 -3
  22. package/dist/cjs/updateItemRangeKey.js +6 -4
  23. package/dist/cjs/validateGeneratedProperty.js +23 -0
  24. package/dist/cjs/validateIndexToken.js +16 -0
  25. package/dist/cjs/validateTranscodedProperty.js +16 -0
  26. package/dist/index.d.ts +178 -531
  27. package/dist/mjs/BaseEntityClient.js +1 -1
  28. package/dist/mjs/{BaseShardQueryMapBuilder.js → BaseQueryBuilder.js} +4 -4
  29. package/dist/mjs/EntityManager.js +8 -8
  30. package/dist/mjs/ParsedConfig.js +143 -113
  31. package/dist/mjs/addKeys.js +6 -6
  32. package/dist/{cjs/decodeEntityElement.js → mjs/decodeElement.js} +8 -14
  33. package/dist/mjs/decodeGeneratedProperty.js +6 -10
  34. package/dist/mjs/dehydrateIndexItem.js +12 -11
  35. package/dist/mjs/dehydratePageKeyMap.js +10 -7
  36. package/dist/{cjs/encodeEntityElement.js → mjs/encodeElement.js} +7 -13
  37. package/dist/mjs/encodeGeneratedProperty.js +13 -14
  38. package/dist/mjs/getHashKeySpace.js +6 -6
  39. package/dist/mjs/getIndexComponents.js +6 -8
  40. package/dist/mjs/getShardBump.js +1 -1
  41. package/dist/mjs/index.js +1 -1
  42. package/dist/mjs/query.js +1 -1
  43. package/dist/mjs/rehydrateIndexItem.js +12 -10
  44. package/dist/mjs/rehydratePageKeyMap.js +18 -11
  45. package/dist/mjs/removeKeys.js +3 -2
  46. package/dist/mjs/unwrapIndex.js +26 -12
  47. package/dist/mjs/updateItemHashKey.js +5 -3
  48. package/dist/mjs/updateItemRangeKey.js +6 -4
  49. package/dist/mjs/validateGeneratedProperty.js +21 -0
  50. package/dist/mjs/validateIndexToken.js +14 -0
  51. package/dist/mjs/validateTranscodedProperty.js +14 -0
  52. package/package.json +5 -5
  53. package/dist/cjs/validateEntityGeneratedProperty.js +0 -29
  54. package/dist/cjs/validateEntityIndexToken.js +0 -22
  55. package/dist/mjs/validateEntityGeneratedProperty.js +0 -27
  56. package/dist/mjs/validateEntityIndexToken.js +0 -20
@@ -2,8 +2,8 @@
2
2
 
3
3
  var decodeGeneratedProperty = require('./decodeGeneratedProperty.js');
4
4
  var dehydrateIndexItem = require('./dehydrateIndexItem.js');
5
- var validateEntityIndexToken = require('./validateEntityIndexToken.js');
6
5
  var validateEntityToken = require('./validateEntityToken.js');
6
+ var validateIndexToken = require('./validateIndexToken.js');
7
7
 
8
8
  /**
9
9
  * Dehydrate a {@link PageKeyMap | `PageKeyMap`} object into an array of dehydrated page keys.
@@ -11,7 +11,7 @@ var validateEntityToken = require('./validateEntityToken.js');
11
11
  * Reverses {@link EntityManager.rehydratePageKeyMap | `rehydratePageKeyMap`}.
12
12
  *
13
13
  * @param entityManager - {@link EntityManager | `EntityManager`} instance.
14
- * @param entityToken - {@link ConfigKeys.entities | `entityManager.config.entities`} key.
14
+ * @param entityToken - {@link Config.entities | `entityManager.config.entities`} key.
15
15
  * @param pageKeyMap - {@link PageKeyMap | `PageKeyMap`} object to dehydrate.
16
16
  *
17
17
  * @returns Array of dehydrated page keys.
@@ -40,7 +40,7 @@ function dehydratePageKeyMap(entityManager, entityToken, pageKeyMap) {
40
40
  }
41
41
  // Extract, sort & validate indexs.
42
42
  const indexes = Object.keys(pageKeyMap).sort();
43
- indexes.map((index) => validateEntityIndexToken.validateEntityIndexToken(entityManager, entityToken, index));
43
+ indexes.map((index) => validateIndexToken.validateIndexToken(entityManager, index));
44
44
  // Extract & sort hash keys.
45
45
  const hashKeys = Object.keys(pageKeyMap[indexes[0]]);
46
46
  // Dehydrate page keys.
@@ -54,13 +54,16 @@ function dehydratePageKeyMap(entityManager, entityToken, pageKeyMap) {
54
54
  }
55
55
  // Compose item from page key
56
56
  const item = Object.entries(pageKeyMap[index][hashKey]).reduce((item, [property, value]) => {
57
- if (property in entityManager.config.entities[entityToken].generated ||
58
- property === entityManager.config.rangeKey)
59
- Object.assign(item, decodeGeneratedProperty.decodeGeneratedProperty(entityManager, entityToken, value));
57
+ if (property === entityManager.config.rangeKey ||
58
+ property in entityManager.config.generatedProperties.sharded ||
59
+ property in entityManager.config.generatedProperties.unsharded)
60
+ Object.assign(item, decodeGeneratedProperty.decodeGeneratedProperty(entityManager, value));
60
61
  else
61
62
  Object.assign(item, { [property]: value });
62
63
  return item;
63
- }, {});
64
+ },
65
+ // eslint-disable-next-line @typescript-eslint/prefer-reduce-type-parameter
66
+ {});
64
67
  // Dehydrate index from item.
65
68
  dehydrated.push(dehydrateIndexItem.dehydrateIndexItem(entityManager, entityToken, index, item));
66
69
  }
@@ -1,14 +1,13 @@
1
- import { validateEntityToken } from './validateEntityToken.js';
1
+ 'use strict';
2
2
 
3
3
  /**
4
- * Encode an {@link Entity | `Entity`} generated property element or ungenerated index component using the associated {@link Transcodes | Transcodes} `encode` function.
4
+ * Encode an {@link EntityItem | `EntityItem`} generated property element or ungenerated index component using the associated {@link Transcodes | Transcodes} `encode` function.
5
5
  *
6
6
  * Returns all `undefined` values.
7
7
  *
8
8
  * If `element` is the {@link Config.hashKey | `hashKey`} or {@link Config.rangeKey | `rangeKey`}, returns the value as-is.
9
9
  *
10
10
  * @param entityManager - {@link EntityManager | `EntityManager`} instance.
11
- * @param entityToken - {@link ConfigKeys.entities | `entityManager.config.entities`} key.
12
11
  * @param element - The {@link Entity | `Entity`} generated property element or ungenerated index component to encode.
13
12
  * @param item - Partial {@link ItemMap | `ItemMap`} object.
14
13
  *
@@ -16,16 +15,15 @@ import { validateEntityToken } from './validateEntityToken.js';
16
15
  *
17
16
  * @throws `Error` if `entityToken` is invalid.
18
17
  */
19
- function encodeEntityElement(entityManager, entityToken, element, item) {
18
+ function encodeElement(entityManager, element, item) {
20
19
  try {
21
- validateEntityToken(entityManager, entityToken);
22
- const { entities, hashKey, rangeKey, transcodes } = entityManager.config;
20
+ const { hashKey, rangeKey, propertyTranscodes, transcodes } = entityManager.config;
23
21
  const value = item[element];
24
22
  if (value === undefined || [hashKey, rangeKey].includes(element))
25
23
  return value;
26
- const encoded = transcodes[entities[entityToken].elementTranscodes[element]].encode(item[element]) || undefined;
24
+ const encoded = transcodes[propertyTranscodes[element]].encode(item[element]) ||
25
+ undefined;
27
26
  entityManager.logger.debug('encoded entity element', {
28
- entityToken,
29
27
  element,
30
28
  item,
31
29
  encoded,
@@ -34,9 +32,9 @@ function encodeEntityElement(entityManager, entityToken, element, item) {
34
32
  }
35
33
  catch (error) {
36
34
  if (error instanceof Error)
37
- entityManager.logger.error(error.message, { entityToken, element, item });
35
+ entityManager.logger.error(error.message, { element, item });
38
36
  throw error;
39
37
  }
40
38
  }
41
39
 
42
- export { encodeEntityElement };
40
+ exports.encodeElement = encodeElement;
@@ -1,41 +1,41 @@
1
1
  'use strict';
2
2
 
3
3
  var entityTools = require('@karmaniverous/entity-tools');
4
- var validateEntityGeneratedProperty = require('./validateEntityGeneratedProperty.js');
4
+ var validateGeneratedProperty = require('./validateGeneratedProperty.js');
5
5
 
6
6
  /**
7
- * Encode a generated property value. Returns a string or undefined if atomicity requirement not met.
7
+ * Encode a generated property value. Returns a string or undefined if atomicity requirement of sharded properties not met.
8
8
  *
9
9
  * @param entityManager - {@link EntityManager | `EntityManager`} instance.
10
- * @param entityToken - `entityManager.config.entities` key.
11
- * @param property - {@link ConfigEntityGenerated | `entityManager.config.entities.<entityToken>.generated`} key.
10
+ * @param property - {@link Config.generatedProperties | Generated property} key.
12
11
  * @param item - Partial {@link ItemMap | `ItemMap`} object.
13
12
  *
14
13
  * @returns Encoded generated property value.
15
14
  *
16
- * @throws `Error` if `entityToken` is invalid.
17
- * @throws `Error` if `property` is invalid.
15
+ * @throws `Error` if `property` is not a {@link Config.generatedProperties | generated property}.
18
16
  */
19
- function encodeGeneratedProperty(entityManager, entityToken, property, item) {
17
+ function encodeGeneratedProperty(entityManager, property, item) {
20
18
  try {
21
19
  // Validate params.
22
- validateEntityGeneratedProperty.validateEntityGeneratedProperty(entityManager, entityToken, property);
23
- const { atomic, elements, sharded } = entityManager.config.entities[entityToken].generated[property];
20
+ validateGeneratedProperty.validateGeneratedProperty(entityManager, property);
21
+ const sharded = property in entityManager.config.generatedProperties.sharded;
22
+ const elements = entityManager.config.generatedProperties[sharded ? 'sharded' : 'unsharded'][property];
24
23
  // Map elements to [element, value] pairs.
25
24
  const elementMap = elements.map((element) => [
26
25
  element,
27
26
  item[element],
28
27
  ]);
29
- // Validate atomicity requirement.
30
- if (atomic && elementMap.some(([, value]) => entityTools.isNil(value)))
28
+ // Return undefined if sharded & atomicity requirement fails.
29
+ if (sharded && elementMap.some(([, value]) => entityTools.isNil(value)))
31
30
  return;
32
31
  // Encode property value.
33
32
  const encoded = [
34
- ...(sharded ? [item[entityManager.config.hashKey]] : []),
33
+ ...(sharded
34
+ ? [item[entityManager.config.hashKey]]
35
+ : []),
35
36
  ...elementMap.map(([element, value]) => [element, (value ?? '').toString()].join(entityManager.config.generatedValueDelimiter)),
36
37
  ].join(entityManager.config.generatedKeyDelimiter);
37
38
  entityManager.logger.debug('encoded generated property', {
38
- entityToken,
39
39
  property,
40
40
  item,
41
41
  encoded,
@@ -45,7 +45,6 @@ function encodeGeneratedProperty(entityManager, entityToken, property, item) {
45
45
  catch (error) {
46
46
  if (error instanceof Error)
47
47
  entityManager.logger.error(error.message, {
48
- entityToken,
49
48
  property,
50
49
  item,
51
50
  });
@@ -2,15 +2,15 @@
2
2
 
3
3
  var radash = require('radash');
4
4
  var encodeGeneratedProperty = require('./encodeGeneratedProperty.js');
5
- var validateEntityGeneratedProperty = require('./validateEntityGeneratedProperty.js');
5
+ var validateGeneratedProperty = require('./validateGeneratedProperty.js');
6
6
 
7
7
  /**
8
8
  * Return an array of {@link ConfigKeys.hashKey | `entityManager.config.hashKey`} property values covering the shard space bounded by `timestampFrom` & `timestampTo`.
9
9
  *
10
10
  * @param entityManager - {@link EntityManager | `EntityManager`} instance.
11
- * @param entityToken - {@link ConfigKeys.entities | `entityManager.config.entities`} key.
12
- * @param hashKeyToken - {@link ParsedConfig | `entityManager.config.hashKey`} or {@link ParsedConfig | `entityManager.config.entities.<entityToken>.generated`} key. If a generated property, must be shardable.
13
- * @param item - Partial {@link ItemMap | `ItemMap[EntityToken]`} object. Must include all properties required to generate the hash key space.
11
+ * @param entityToken - {@link Config.entities | `entityManager.config.entities`} key.
12
+ * @param hashKeyToken - {@link ParsedConfig | `entityManager.config.hashKey`} or {@link ParsedConfig | `entityManager.config.generatedProperties.sharded`} key.
13
+ * @param item - {@link EntityItem | `EntityItem`} object. Must include all properties required to generate the hash key space.
14
14
  * @param timestampFrom - Lower timestanp limit. Defaults to `0`.
15
15
  * @param timestampTo - Upper timestamp limit. Defaults to `Date.now()`.
16
16
  *
@@ -22,7 +22,7 @@ function getHashKeySpace(entityManager, entityToken, hashKeyToken, item, timesta
22
22
  try {
23
23
  // Validate hashKeyToken is either the global hash key or a sharded generated property.
24
24
  if (hashKeyToken !== entityManager.config.hashKey)
25
- validateEntityGeneratedProperty.validateEntityGeneratedProperty(entityManager, entityToken, hashKeyToken, true);
25
+ validateGeneratedProperty.validateGeneratedProperty(entityManager, hashKeyToken, true);
26
26
  const { shardBumps } = entityManager.config.entities[entityToken];
27
27
  const hashKeySpace = shardBumps
28
28
  // Filter shard bumps by timestamp range.
@@ -42,7 +42,7 @@ function getHashKeySpace(entityManager, entityToken, hashKeyToken, item, timesta
42
42
  let hashKey = `${entityToken}${entityManager.config.shardKeyDelimiter}${shardKey}`;
43
43
  // If hash key space basis is a different property, encode it.
44
44
  if (hashKeyToken !== entityManager.config.hashKey)
45
- hashKey = encodeGeneratedProperty.encodeGeneratedProperty(entityManager, entityToken, hashKeyToken, {
45
+ hashKey = encodeGeneratedProperty.encodeGeneratedProperty(entityManager, hashKeyToken, {
46
46
  ...item,
47
47
  [entityManager.config.hashKey]: hashKey,
48
48
  });
@@ -1,24 +1,22 @@
1
1
  'use strict';
2
2
 
3
3
  var radash = require('radash');
4
- var validateEntityIndexToken = require('./validateEntityIndexToken.js');
4
+ var validateIndexToken = require('./validateIndexToken.js');
5
5
 
6
6
  /**
7
7
  * Get the index components of an entity index. Adds the hash and range keys to the index components.
8
8
  *
9
9
  * @param entityManager - {@link EntityManager | `EntityManager`} instance.
10
- * @param entityToken - {@link ConfigKeys.entities | `entityManager.config.entities`} key.
11
- * @param indexToken - {@link ConfigEntity.indexes | `entityManager.config.entities.<entityToken>.indexes`} key.
10
+ * @param indexToken - {@link Config.indexes | `entityManager.config.indexes`} key.
12
11
  *
13
12
  * @returns Array of index components.
14
13
  *
15
- * @throws `Error` if `entityToken` is invalid.
16
14
  * @throws `Error` if `indexToken` is invalid.
17
15
  */
18
- function getIndexComponents(entityManager, entityToken, indexToken) {
19
- validateEntityIndexToken.validateEntityIndexToken(entityManager, entityToken, indexToken);
20
- const { hashKey, rangeKey, entities } = entityManager.config;
21
- const { hashKey: indexHashKey, rangeKey: indexRangeKey } = entities[entityToken].indexes[indexToken];
16
+ function getIndexComponents(entityManager, indexToken) {
17
+ validateIndexToken.validateIndexToken(entityManager, indexToken);
18
+ const { hashKey, rangeKey, indexes } = entityManager.config;
19
+ const { hashKey: indexHashKey, rangeKey: indexRangeKey } = indexes[indexToken];
22
20
  return radash.unique([hashKey, rangeKey, indexHashKey, indexRangeKey]);
23
21
  }
24
22
 
@@ -6,7 +6,7 @@ var validateEntityToken = require('./validateEntityToken.js');
6
6
  * Get first entity shard bump before timestamp.
7
7
  *
8
8
  * @param entityManager - {@link EntityManager | `EntityManager`} instance.
9
- * @param entityToken - {@link ConfigKeys.entities | `this.config.entities`} key.
9
+ * @param entityToken - {@link Config.entities | `this.config.entities`} key.
10
10
  * @param timestamp - Timestamp in milliseconds.
11
11
  *
12
12
  * @returns {@link ShardBump | `ShardBump`} object.
package/dist/cjs/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
3
  var BaseEntityClient = require('./BaseEntityClient.js');
4
- var BaseShardQueryMapBuilder = require('./BaseShardQueryMapBuilder.js');
4
+ var BaseQueryBuilder = require('./BaseQueryBuilder.js');
5
5
  var conditionalize = require('./conditionalize.js');
6
6
  var EntityManager = require('./EntityManager.js');
7
7
 
8
8
 
9
9
 
10
10
  exports.BaseEntityClient = BaseEntityClient.BaseEntityClient;
11
- exports.BaseShardQueryMapBuilder = BaseShardQueryMapBuilder.BaseShardQueryMapBuilder;
11
+ exports.BaseQueryBuilder = BaseQueryBuilder.BaseQueryBuilder;
12
12
  exports.conditionalize = conditionalize.conditionalize;
13
13
  exports.EntityManager = EntityManager.EntityManager;
package/dist/cjs/query.js CHANGED
@@ -13,7 +13,7 @@ const { compressToEncodedURIComponent, decompressFromEncodedURIComponent } = lzS
13
13
  * @remarks
14
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
15
  *
16
- * Individual shard query results will be combined, deduped by {@link ConfigEntity.uniqueProperty} property value, and sorted by {@link QueryOptions.sortOrder | `sortOrder`}.
16
+ * Individual shard query results will be combined, deduped by {@link Config.uniqueProperty} property value, and sorted by {@link QueryOptions.sortOrder | `sortOrder`}.
17
17
  *
18
18
  * In queries on sharded data, expect the leading and trailing edges of returned data pages to interleave somewhat with preceding & following pages.
19
19
  *
@@ -1,12 +1,13 @@
1
1
  'use strict';
2
2
 
3
3
  var radash = require('radash');
4
- var decodeEntityElement = require('./decodeEntityElement.js');
4
+ var decodeElement = require('./decodeElement.js');
5
5
  var unwrapIndex = require('./unwrapIndex.js');
6
- var validateEntityIndexToken = require('./validateEntityIndexToken.js');
6
+ var validateEntityToken = require('./validateEntityToken.js');
7
+ var validateIndexToken = require('./validateIndexToken.js');
7
8
 
8
9
  /**
9
- * Convert a delimited string into a partial {@link ItemMap | `ItemMap`} object representing the ungenerated component elements of a Config entity index.
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.
10
11
  *
11
12
  * @remarks
12
13
  * Reverses {@link EntityManager.dehydrateIndexItem | `dehydrateIndexItem`}.
@@ -14,31 +15,32 @@ var validateEntityIndexToken = require('./validateEntityIndexToken.js');
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.
15
16
  *
16
17
  * @param entityManager - {@link EntityManager | `EntityManager`} instance.
17
- * @param entityToken - {@link ConfigKeys.entities | `entityManager.config.entities`} key.
18
- * @param indexToken - {@link ConfigEntity.indexes | `entityManager.config.entities.<entityToken>.indexes`} key.
18
+ * @param entityToken - {@link Config.entities | `entityManager.config.entities`} key.
19
+ * @param indexToken - {@link Config.indexes | `entityManager.config.indexes`} key.
19
20
  * @param dehydrated - Dehydrated index value.
20
21
  *
21
- * @returns Partial {@link ItemMap | `ItemMap`} object containing rehydrated index component elements.
22
+ * @returns {@link EntityItem | `EntityItem`} object containing rehydrated index component elements.
22
23
  *
23
24
  * @throws `Error` if `entityToken` is invalid.
24
25
  * @throws `Error` if `indexToken` is invalid.
25
26
  */
26
27
  function rehydrateIndexItem(entityManager, entityToken, indexToken, dehydrated) {
27
28
  try {
28
- const { generatedKeyDelimiter } = entityManager.config;
29
29
  // Validate params.
30
- validateEntityIndexToken.validateEntityIndexToken(entityManager, entityToken, indexToken);
30
+ validateEntityToken.validateEntityToken(entityManager, entityToken);
31
+ validateIndexToken.validateIndexToken(entityManager, indexToken);
31
32
  // Unwrap index elements.
32
- const { hashKey } = entityManager.config.entities[entityToken].indexes[indexToken];
33
+ const { hashKey } = entityManager.config.indexes[indexToken];
33
34
  const elements = unwrapIndex.unwrapIndex(entityManager, entityToken, indexToken, [
34
35
  hashKey,
35
36
  ]);
36
37
  // Split dehydrated value & validate.
38
+ const { generatedKeyDelimiter } = entityManager.config;
37
39
  const values = dehydrated.split(generatedKeyDelimiter);
38
40
  if (elements.length !== values.length)
39
41
  throw new Error('index rehydration key-value mismatch');
40
42
  // Assign values to elements.
41
- const rehydrated = radash.shake(radash.zipToObject(elements, values.map((value, i) => decodeEntityElement.decodeEntityElement(entityManager, entityToken, elements[i], value))));
43
+ const rehydrated = radash.shake(radash.zipToObject(elements, values.map((value, i) => decodeElement.decodeElement(entityManager, elements[i], value))));
42
44
  entityManager.logger.debug('rehydrated index', {
43
45
  entityToken,
44
46
  indexToken,
@@ -7,7 +7,8 @@ var getHashKeySpace = require('./getHashKeySpace.js');
7
7
  var getIndexComponents = require('./getIndexComponents.js');
8
8
  var rehydrateIndexItem = require('./rehydrateIndexItem.js');
9
9
  var updateItemRangeKey = require('./updateItemRangeKey.js');
10
- var validateEntityIndexToken = require('./validateEntityIndexToken.js');
10
+ var validateEntityToken = require('./validateEntityToken.js');
11
+ var validateIndexToken = require('./validateIndexToken.js');
11
12
 
12
13
  /**
13
14
  * Rehydrate an array of dehydrated page keys into a {@link PageKeyMap | `PageKeyMap`} object.
@@ -15,8 +16,8 @@ var validateEntityIndexToken = require('./validateEntityIndexToken.js');
15
16
  * Reverses the {@link EntityManager.dehydratePageKeyMap | `dehydratePageKeyMap`} method.
16
17
  *
17
18
  * @param entityManager - {@link EntityManager | `EntityManager`} instance.
18
- * @param entityToken - {@link ConfigKeys.entities | `entityManager.config.entities`} key.
19
- * @param indexTokens - Array of {@link ConfigEntity.indexes | `entityManager.config.entities.<entityToken>.indexes`} keys used as keys of the original {@link PageKeyMap | `PageKeyMap`}.
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`}.
20
21
  * @param item - Partial item object sufficiently populated to generate index hash keys.
21
22
  * @param dehydrated - Array of dehydrated page keys or undefined if new query.
22
23
  * @param timestampFrom - Lower timestanp limit used to generate the original {@link PageKeyMap | `PageKeyMap`}. Defaults to `0`.
@@ -32,20 +33,21 @@ var validateEntityIndexToken = require('./validateEntityIndexToken.js');
32
33
  */
33
34
  function rehydratePageKeyMap(entityManager, entityToken, indexTokens, item, dehydrated, timestampFrom = 0, timestampTo = Date.now()) {
34
35
  try {
36
+ // Validate params.
37
+ validateEntityToken.validateEntityToken(entityManager, entityToken);
35
38
  // Validate indexTokens populated.
36
39
  if (!indexTokens.length)
37
40
  throw new Error('indexTokens empty');
38
41
  // Validate indexTokens exist.
39
42
  const hashKeys = radash.unique(indexTokens.map((indexToken) => {
40
- validateEntityIndexToken.validateEntityIndexToken(entityManager, entityToken, indexToken);
41
- return entityManager.config.entities[entityToken].indexes[indexToken]
42
- .hashKey;
43
+ validateIndexToken.validateIndexToken(entityManager, indexToken);
44
+ return entityManager.config.indexes[indexToken].hashKey;
43
45
  }));
44
46
  // Validate hashKeys consistent.
45
47
  if (hashKeys.length > 1)
46
48
  throw new Error('inconsistent hashKeys');
47
49
  const [hashKeyToken] = hashKeys;
48
- indexTokens.map((index) => validateEntityIndexToken.validateEntityIndexToken(entityManager, entityToken, index));
50
+ indexTokens.map((index) => validateIndexToken.validateIndexToken(entityManager, index));
49
51
  // Shortcut empty dehydrated.
50
52
  if (dehydrated && !dehydrated.length)
51
53
  return [hashKeyToken, {}];
@@ -57,17 +59,22 @@ function rehydratePageKeyMap(entityManager, entityToken, indexTokens, item, dehy
57
59
  if (dehydrated.length !== hashKeySpace.length * indexTokens.length)
58
60
  throw new Error('dehydrated length mismatch');
59
61
  // Rehydrate pageKeys.
62
+ const uniqueProperty = entityManager.config.entities[entityToken]
63
+ .uniqueProperty;
64
+ const { sharded, unsharded } = entityManager.config.generatedProperties;
60
65
  const rehydrated = radash.mapValues(radash.zipToObject(indexTokens, radash.cluster(dehydrated, hashKeySpace.length)), (dehydratedIndexPageKeyMaps, index) => radash.zipToObject(hashKeySpace, (hashKey, i) => {
61
66
  if (!dehydratedIndexPageKeyMaps[i])
62
67
  return;
63
68
  let pageKeyItem = {
64
- ...decodeGeneratedProperty.decodeGeneratedProperty(entityManager, entityToken, hashKey),
69
+ ...decodeGeneratedProperty.decodeGeneratedProperty(entityManager, hashKey),
65
70
  ...rehydrateIndexItem.rehydrateIndexItem(entityManager, entityToken, index, dehydratedIndexPageKeyMaps[i]),
66
71
  };
67
72
  pageKeyItem = updateItemRangeKey.updateItemRangeKey(entityManager, entityToken, pageKeyItem);
68
- return radash.zipToObject(getIndexComponents.getIndexComponents(entityManager, entityToken, index), (component) => entityManager.config.entities[entityToken].generated[component]
69
- ? encodeGeneratedProperty.encodeGeneratedProperty(entityManager, entityToken, component, pageKeyItem)
70
- : pageKeyItem[component]);
73
+ return radash.zipToObject(getIndexComponents.getIndexComponents(entityManager, index), (component) => component === entityManager.config.rangeKey
74
+ ? [uniqueProperty, pageKeyItem[uniqueProperty]].join(entityManager.config.generatedValueDelimiter)
75
+ : component in sharded || component in unsharded
76
+ ? encodeGeneratedProperty.encodeGeneratedProperty(entityManager, component, pageKeyItem)
77
+ : pageKeyItem[component]);
71
78
  }));
72
79
  entityManager.logger.debug('rehydrated page key map', {
73
80
  entityToken,
@@ -6,7 +6,7 @@ var validateEntityToken = require('./validateEntityToken.js');
6
6
  * Strips generated properties, hash key, and range key from an {@link ItemMap | `ItemMap`} object.
7
7
  *
8
8
  * @param entityManager - {@link EntityManager | `EntityManager`} instance.
9
- * @param entityToken - {@link ConfigKeys.entities | `entityManager.config.entities`} key.
9
+ * @param entityToken - {@link Config.entities | `entityManager.config.entities`} key.
10
10
  * @param item - {@link ItemMap | `ItemMap`} object.
11
11
  *
12
12
  * @returns Shallow clone of `item` without generated properties, hash key or range key.
@@ -22,7 +22,8 @@ function removeKeys(entityManager, entityToken, item) {
22
22
  delete newItem[entityManager.config.hashKey];
23
23
  delete newItem[entityManager.config.rangeKey];
24
24
  // Delete generated properties.
25
- for (const property in entityManager.config.entities[entityToken].generated)
25
+ const { sharded, unsharded } = entityManager.config.generatedProperties;
26
+ for (const property in { ...sharded, ...unsharded })
26
27
  delete newItem[property];
27
28
  entityManager.logger.debug('stripped entity item generated properties', {
28
29
  entityToken,
@@ -2,13 +2,14 @@
2
2
 
3
3
  var radash = require('radash');
4
4
  var getIndexComponents = require('./getIndexComponents.js');
5
- var validateEntityIndexToken = require('./validateEntityIndexToken.js');
5
+ var validateEntityToken = require('./validateEntityToken.js');
6
+ var validateIndexToken = require('./validateIndexToken.js');
6
7
 
7
8
  /**
8
- * Unwraps an {@link ConfigEntity.indexes | Entity index} into deduped, sorted, ungenerated index component elements.
9
+ * Unwraps an {@link Config.indexes | index} into deduped, sorted, ungenerated index component elements.
9
10
  *
10
11
  * @param entityManager - {@link EntityManager | `EntityManager`} instance.
11
- * @param entityToken - {@link ConfigKeys.entities | `entityManager.config.entities`} key.
12
+ * @param entityToken - {@link Config.entities | `entityManager.config.entities`} key.
12
13
  * @param indexToken - {@link ConfigEntity.indexes | `entityManager.config.entities.<entityToken>.indexes`} key.
13
14
  * @param omit - Array of index components or elements to omit from the output value.
14
15
  *
@@ -20,24 +21,37 @@ var validateEntityIndexToken = require('./validateEntityIndexToken.js');
20
21
  function unwrapIndex(entityManager, entityToken, indexToken, omit = []) {
21
22
  try {
22
23
  // Validate params.
23
- validateEntityIndexToken.validateEntityIndexToken(entityManager, entityToken, indexToken);
24
- const generated = entityManager.config.entities[entityToken].generated;
25
- const generatedKeys = Object.keys(radash.shake(generated));
26
- return radash.unique(getIndexComponents.getIndexComponents(entityManager, entityToken, indexToken)
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)
27
28
  .filter((component) => !omit.includes(component))
28
29
  .map((component) => component === entityManager.config.hashKey
29
30
  ? entityManager.config.entities[entityToken].timestampProperty
30
31
  : component === entityManager.config.rangeKey
31
32
  ? entityManager.config.entities[entityToken].uniqueProperty
32
- : generatedKeys.includes(component)
33
- ? generated[component].elements
34
- : component)
33
+ : component in sharded
34
+ ? sharded[component]
35
+ : component in unsharded
36
+ ? unsharded[component]
37
+ : component)
35
38
  .flat()
36
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;
37
47
  }
38
48
  catch (error) {
39
49
  if (error instanceof Error)
40
- entityManager.logger.error(error.message, { indexToken, entityToken });
50
+ entityManager.logger.error(error.message, {
51
+ entityToken,
52
+ indexToken,
53
+ omit,
54
+ });
41
55
  throw error;
42
56
  }
43
57
  }
@@ -9,7 +9,7 @@ var validateEntityToken = require('./validateEntityToken.js');
9
9
  * Update the hash key on a partial {@link ItemMap | `ItemMap`} object.
10
10
  *
11
11
  * @param entityManager - {@link EntityManager | `EntityManager`} instance.
12
- * @param entityToken - {@link ConfigKeys.entities | `this.config.entities`} key.
12
+ * @param entityToken - {@link Config.entities | `this.config.entities`} key.
13
13
  * @param item - Partial {@link ItemMap | `ItemMap`} object.
14
14
  * @param overwrite - Overwrite existing {@link ConfigKeys.hashKey | `this.config.hashKey`} property value (default `false`).
15
15
  *
@@ -22,7 +22,8 @@ function updateItemHashKey(entityManager, entityToken, item, overwrite = false)
22
22
  // Validate params.
23
23
  validateEntityToken.validateEntityToken(entityManager, entityToken);
24
24
  // Return current item if hashKey exists and overwrite is false.
25
- if (item[entityManager.config.hashKey] && !overwrite) {
25
+ if (item[entityManager.config.hashKey] &&
26
+ !overwrite) {
26
27
  entityManager.logger.debug('did not overwrite existing entity item hash key', {
27
28
  item,
28
29
  entityToken,
@@ -31,7 +32,8 @@ function updateItemHashKey(entityManager, entityToken, item, overwrite = false)
31
32
  return { ...item };
32
33
  }
33
34
  // Get item timestamp property & validate.
34
- const timestamp = item[entityManager.config.entities[entityToken].timestampProperty];
35
+ const timestamp = item[entityManager.config.entities[entityToken]
36
+ .timestampProperty];
35
37
  if (entityTools.isNil(timestamp))
36
38
  throw new Error(`missing item timestamp property`);
37
39
  // Find first entity sharding bump before timestamp.
@@ -7,21 +7,22 @@ var validateEntityToken = require('./validateEntityToken.js');
7
7
  * Update the range key on a partial {@link ItemMap | `ItemMap`} object.
8
8
  *
9
9
  * @param entityManager - {@link EntityManager | `EntityManager`} instance.
10
- * @param entityToken - {@link ConfigKeys.entities | `this.config.entities`} key.
10
+ * @param entityToken - {@link Config.entities | `this.config.entities`} key.
11
11
  * @param item - Partial {@link ItemMap | `ItemMap`} object.
12
12
  * @param overwrite - Overwrite existing {@link ConfigKeys.rangeKey | `this.config.rangeKey`} property value (default `false`).
13
13
  *
14
14
  * @returns Shallow clone of `item` with updated range key.
15
15
  *
16
16
  * @throws `Error` if `entityToken` is invalid.
17
- * @throws `Error` if `item` {@link ConfigEntity.uniqueProperty | `this.config.entities<entityToken>.uniqueProperty`} property value is missing.
17
+ * @throws `Error` if `item` {@link Config.uniqueProperty | `this.config.entities<entityToken>.uniqueProperty`} property value is missing.
18
18
  */
19
19
  function updateItemRangeKey(entityManager, entityToken, item, overwrite = false) {
20
20
  try {
21
21
  // Validate params.
22
22
  validateEntityToken.validateEntityToken(entityManager, entityToken);
23
23
  // Return current item if rangeKey exists and overwrite is false.
24
- if (item[entityManager.config.rangeKey] && !overwrite) {
24
+ if (item[entityManager.config.rangeKey] &&
25
+ !overwrite) {
25
26
  entityManager.logger.debug('did not overwrite existing entity item range key', {
26
27
  entityToken,
27
28
  item,
@@ -30,7 +31,8 @@ function updateItemRangeKey(entityManager, entityToken, item, overwrite = false)
30
31
  return { ...item };
31
32
  }
32
33
  // Get item unique property & validate.
33
- const uniqueProperty = item[entityManager.config.entities[entityToken].uniqueProperty];
34
+ const uniqueProperty = item[entityManager.config.entities[entityToken]
35
+ .uniqueProperty];
34
36
  if (entityTools.isNil(uniqueProperty))
35
37
  throw new Error(`missing item unique property`);
36
38
  // Update range key.
@@ -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;