@karmaniverous/entity-manager
Advanced tools
Comparing version 0.0.12 to 0.1.0
@@ -7,2 +7,5 @@ "use strict"; | ||
exports.EntityManager = void 0; | ||
var _isUndefined2 = _interopRequireDefault(require("lodash/isUndefined")); | ||
var _map2 = _interopRequireDefault(require("lodash/map")); | ||
var _fromPairs2 = _interopRequireDefault(require("lodash/fromPairs")); | ||
var _sortedUniq2 = _interopRequireDefault(require("lodash/sortedUniq")); | ||
@@ -98,4 +101,4 @@ var _forEach2 = _interopRequireDefault(require("lodash/forEach")); | ||
* @param {string} entityToken - Entity token. | ||
* @param {object} item - Entity item. | ||
* @param {string} keyToken - Key token. | ||
* @param {object} item - Entity item sufficiently populated to generate property keyToken. | ||
* @param {number} timestamp - Timestamp. | ||
@@ -108,3 +111,3 @@ * @returns {string[]} Array of keys. | ||
*/ | ||
getKeySpace(entityToken, item, keyToken) { | ||
getKeySpace(entityToken, keyToken, item) { | ||
let timestamp = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : Date.now(); | ||
@@ -120,3 +123,74 @@ _classPrivateFieldGet(this, _entityManager).logger.debug(`getting shard key space for ${entityToken} on key '${keyToken}' at timestamp ${timestamp}...`, item); | ||
} | ||
/** | ||
* @typedef {object} ShardQueryResult | ||
* @property {any[]} items - Query result array. | ||
* @property {*} pageKey - Shard page key. | ||
*/ | ||
/** | ||
* Shard query function | ||
* | ||
* @callback ShardQueryFunction | ||
* @param {string} shardedKey - Sharded key. | ||
* @param {*} [pageKey] - Page key. | ||
* @returns {Promise<ShardQueryResult>} Sharded query result. | ||
*/ | ||
/** | ||
* @typedef {object} ShardedQueryResult | ||
* @property {any[]} items - Query result array. | ||
* @property {object} shardPageKeys - Shard page keys. | ||
*/ | ||
/** | ||
* Query an entity across shards. | ||
* | ||
* @param {string} entityToken - Entity token. | ||
* @param {string} keyToken - Key token. | ||
* @param {object} item - Entity item sufficiently populated to generate property keyToken. | ||
* @param {ShardQueryFunction} shardQuery - Sharded query function. | ||
* @param {object} [shardPageKeys] - Map of shard page keys. | ||
* @returns {Promise<ShardedQueryResult>} Sharded query result. | ||
*/ | ||
async query(entityToken, keyToken, item, shardQuery, shardPageKeys) { | ||
// Generate default shardPageKeys if not provided | ||
shardPageKeys ??= (0, _fromPairs2.default)(this.getKeySpace(entityToken, keyToken, item).map(shardedKey => [shardedKey, undefined])); | ||
// Query every shard in shardPageKeys. | ||
const shardQueryResults = await Promise.all((0, _map2.default)(shardPageKeys, (pageKey, shardedKey) => new Promise(resolve => shardQuery(shardedKey, pageKey).then(_ref2 => { | ||
let { | ||
items, | ||
pageKey | ||
} = _ref2; | ||
return resolve({ | ||
shardedKey, | ||
items, | ||
pageKey | ||
}); | ||
})))); | ||
// Reduce shardQueryResults into a single result. | ||
const result = shardQueryResults.reduce((shardedQueryResult, _ref3) => { | ||
let { | ||
shardedKey, | ||
items, | ||
pageKey | ||
} = _ref3; | ||
return { | ||
items: [...shardedQueryResult.items, ...items], | ||
shardPageKeys: { | ||
...shardedQueryResult.shardPageKeys, | ||
...((0, _isUndefined2.default)(pageKey) ? {} : { | ||
[shardedKey]: pageKey | ||
}) | ||
} | ||
}; | ||
}, { | ||
items: [], | ||
shardPageKeys: {} | ||
}); | ||
return result; | ||
} | ||
} | ||
exports.EntityManager = EntityManager; |
@@ -81,4 +81,4 @@ /** | ||
* @param {string} entityToken - Entity token. | ||
* @param {object} item - Entity item. | ||
* @param {string} keyToken - Key token. | ||
* @param {object} item - Entity item sufficiently populated to generate property keyToken. | ||
* @param {number} timestamp - Timestamp. | ||
@@ -91,3 +91,3 @@ * @returns {string[]} Array of keys. | ||
*/ | ||
getKeySpace(entityToken, item, keyToken, timestamp = Date.now()) { | ||
getKeySpace(entityToken, keyToken, item, timestamp = Date.now()) { | ||
this.#entityManager.logger.debug( | ||
@@ -118,2 +118,70 @@ `getting shard key space for ${entityToken} on key '${keyToken}' at timestamp ${timestamp}...`, | ||
} | ||
/** | ||
* @typedef {object} ShardQueryResult | ||
* @property {any[]} items - Query result array. | ||
* @property {*} pageKey - Shard page key. | ||
*/ | ||
/** | ||
* Shard query function | ||
* | ||
* @callback ShardQueryFunction | ||
* @param {string} shardedKey - Sharded key. | ||
* @param {*} [pageKey] - Page key. | ||
* @returns {Promise<ShardQueryResult>} Sharded query result. | ||
*/ | ||
/** | ||
* @typedef {object} ShardedQueryResult | ||
* @property {any[]} items - Query result array. | ||
* @property {object} shardPageKeys - Shard page keys. | ||
*/ | ||
/** | ||
* Query an entity across shards. | ||
* | ||
* @param {string} entityToken - Entity token. | ||
* @param {string} keyToken - Key token. | ||
* @param {object} item - Entity item sufficiently populated to generate property keyToken. | ||
* @param {ShardQueryFunction} shardQuery - Sharded query function. | ||
* @param {object} [shardPageKeys] - Map of shard page keys. | ||
* @returns {Promise<ShardedQueryResult>} Sharded query result. | ||
*/ | ||
async query(entityToken, keyToken, item, shardQuery, shardPageKeys) { | ||
// Generate default shardPageKeys if not provided | ||
shardPageKeys ??= _.fromPairs( | ||
this.getKeySpace(entityToken, keyToken, item).map((shardedKey) => [ | ||
shardedKey, | ||
undefined, | ||
]) | ||
); | ||
// Query every shard in shardPageKeys. | ||
const shardQueryResults = await Promise.all( | ||
_.map( | ||
shardPageKeys, | ||
(pageKey, shardedKey) => | ||
new Promise((resolve) => | ||
shardQuery(shardedKey, pageKey).then(({ items, pageKey }) => | ||
resolve({ shardedKey, items, pageKey }) | ||
) | ||
) | ||
) | ||
); | ||
// Reduce shardQueryResults into a single result. | ||
const result = shardQueryResults.reduce( | ||
(shardedQueryResult, { shardedKey, items, pageKey }) => ({ | ||
items: [...shardedQueryResult.items, ...items], | ||
shardPageKeys: { | ||
...shardedQueryResult.shardPageKeys, | ||
...(_.isUndefined(pageKey) ? {} : { [shardedKey]: pageKey }), | ||
}, | ||
}), | ||
{ items: [], shardPageKeys: {} } | ||
); | ||
return result; | ||
} | ||
} |
{ | ||
"name": "@karmaniverous/entity-manager", | ||
"version": "0.0.12", | ||
"version": "0.1.0", | ||
"publishConfig": { | ||
@@ -66,3 +66,4 @@ "access": "public" | ||
], | ||
"spec": "./**/*.test.!(*.*)" | ||
"spec": "./**/*.test.!(*.*)", | ||
"timeout": 60000 | ||
}, | ||
@@ -69,0 +70,0 @@ "release-it": { |
@@ -41,4 +41,4 @@ # entity-manager | ||
// sn2e - Template literal returns empty string if any expression is nil. | ||
// sn2n - Template literal returns undefined if any expression is nil. | ||
import { sn2e, sn2n } from '@karmaniverous/tagged-templates'; | ||
// sn2u - Template literal returns undefined if any expression is nil. | ||
import { sn2e, sn2u } from '@karmaniverous/tagged-templates'; | ||
@@ -61,27 +61,27 @@ // Entity config object named export. | ||
entitySK: ({ timestamp, transactionId }) => | ||
sn2n`timestamp#${timestamp}|transactionId#${transactionId}`, | ||
sn2u`timestamp#${timestamp}|transactionId#${transactionId}`, | ||
// merchants GSI HASH key. Note the optional shardId. | ||
merchantPK: ({ merchantId, shardId }) => | ||
sn2n`merchantId#${merchantId}|transaction${sn2e`!${shardId}`}`, | ||
sn2u`merchantId#${merchantId}|transaction${sn2e`!${shardId}`}`, | ||
// merchants GSI RANGE key. | ||
merchantSK: ({ methodId, timestamp, transactionId }) => | ||
sn2n`timestamp#${timestamp}|methodId#${methodId}|transactionId#${transactionId}`, | ||
sn2u`timestamp#${timestamp}|methodId#${methodId}|transactionId#${transactionId}`, | ||
// methods GSI HASH key. Note the optional shardId. | ||
methodPK: ({ methodId, shardId }) => | ||
sn2n`method#${methodId}|transaction${sn2e`!${shardId}`}`, | ||
sn2u`method#${methodId}|transaction${sn2e`!${shardId}`}`, | ||
// methods GSI RANGE key. | ||
methodSK: ({ merchantId, timestamp, transactionId }) => | ||
sn2n`timestamp#${timestamp}|merchantId#${merchantId}|transactionId#${transactionId}`, | ||
sn2u`timestamp#${timestamp}|merchantId#${merchantId}|transactionId#${transactionId}`, | ||
// users GSI HASH key. Note the optional shardId. | ||
userPK: ({ shardId, userId }) => | ||
sn2n`user#${userId}|transaction${sn2e`!${shardId}`}`, | ||
sn2u`user#${userId}|transaction${sn2e`!${shardId}`}`, | ||
// users GSI RANGE key. | ||
userSK: ({ merchantId, timestamp, transactionId }) => | ||
sn2n`timestamp#${timestamp}|merchantId#${merchantId}|transactionId#${transactionId}`, | ||
sn2u`timestamp#${timestamp}|merchantId#${merchantId}|transactionId#${transactionId}`, | ||
}, | ||
@@ -221,6 +221,12 @@ | ||
* [entity-manager](#module_entity-manager) | ||
* [.EntityManager](#module_entity-manager.EntityManager) | ||
* [new exports.EntityManager(options)](#new_module_entity-manager.EntityManager_new) | ||
* [.addKeys(entityToken, item, [overwrite])](#module_entity-manager.EntityManager+addKeys) ⇒ <code>object</code> | ||
* [.getKeySpace(entityToken, item, keyToken, timestamp)](#module_entity-manager.EntityManager+getKeySpace) ⇒ <code>Array.<string></code> | ||
* _static_ | ||
* [.EntityManager](#module_entity-manager.EntityManager) | ||
* [new exports.EntityManager(options)](#new_module_entity-manager.EntityManager_new) | ||
* [.addKeys(entityToken, item, [overwrite])](#module_entity-manager.EntityManager+addKeys) ⇒ <code>object</code> | ||
* [.getKeySpace(entityToken, keyToken, item, timestamp)](#module_entity-manager.EntityManager+getKeySpace) ⇒ <code>Array.<string></code> | ||
* [.query(entityToken, keyToken, item, shardQuery, [shardPageKeys])](#module_entity-manager.EntityManager+query) ⇒ <code>Promise.<ShardedQueryResult></code> | ||
* _inner_ | ||
* [~ShardQueryResult](#module_entity-manager..ShardQueryResult) : <code>object</code> | ||
* [~ShardQueryFunction](#module_entity-manager..ShardQueryFunction) ⇒ <code>Promise.<ShardQueryResult></code> | ||
* [~ShardedQueryResult](#module_entity-manager..ShardedQueryResult) : <code>object</code> | ||
@@ -237,3 +243,4 @@ <a name="module_entity-manager.EntityManager"></a> | ||
* [.addKeys(entityToken, item, [overwrite])](#module_entity-manager.EntityManager+addKeys) ⇒ <code>object</code> | ||
* [.getKeySpace(entityToken, item, keyToken, timestamp)](#module_entity-manager.EntityManager+getKeySpace) ⇒ <code>Array.<string></code> | ||
* [.getKeySpace(entityToken, keyToken, item, timestamp)](#module_entity-manager.EntityManager+getKeySpace) ⇒ <code>Array.<string></code> | ||
* [.query(entityToken, keyToken, item, shardQuery, [shardPageKeys])](#module_entity-manager.EntityManager+query) ⇒ <code>Promise.<ShardedQueryResult></code> | ||
@@ -279,3 +286,3 @@ <a name="new_module_entity-manager.EntityManager_new"></a> | ||
#### entityManager.getKeySpace(entityToken, item, keyToken, timestamp) ⇒ <code>Array.<string></code> | ||
#### entityManager.getKeySpace(entityToken, keyToken, item, timestamp) ⇒ <code>Array.<string></code> | ||
Return an array of sharded keys valid for a given entity token & timestamp. | ||
@@ -296,7 +303,58 @@ | ||
| entityToken | <code>string</code> | Entity token. | | ||
| item | <code>object</code> | Entity item. | | ||
| keyToken | <code>string</code> | Key token. | | ||
| item | <code>object</code> | Entity item sufficiently populated to generate property keyToken. | | ||
| timestamp | <code>number</code> | Timestamp. | | ||
<a name="module_entity-manager.EntityManager+query"></a> | ||
#### entityManager.query(entityToken, keyToken, item, shardQuery, [shardPageKeys]) ⇒ <code>Promise.<ShardedQueryResult></code> | ||
Query an entity across shards. | ||
**Kind**: instance method of [<code>EntityManager</code>](#module_entity-manager.EntityManager) | ||
**Returns**: <code>Promise.<ShardedQueryResult></code> - Sharded query result. | ||
| Param | Type | Description | | ||
| --- | --- | --- | | ||
| entityToken | <code>string</code> | Entity token. | | ||
| keyToken | <code>string</code> | Key token. | | ||
| item | <code>object</code> | Entity item sufficiently populated to generate property keyToken. | | ||
| shardQuery | <code>ShardQueryFunction</code> | Sharded query function. | | ||
| [shardPageKeys] | <code>object</code> | Map of shard page keys. | | ||
<a name="module_entity-manager..ShardQueryResult"></a> | ||
### entity-manager~ShardQueryResult : <code>object</code> | ||
**Kind**: inner typedef of [<code>entity-manager</code>](#module_entity-manager) | ||
**Properties** | ||
| Name | Type | Description | | ||
| --- | --- | --- | | ||
| items | <code>Array.<any></code> | Query result array. | | ||
| pageKey | <code>\*</code> | Shard page key. | | ||
<a name="module_entity-manager..ShardQueryFunction"></a> | ||
### entity-manager~ShardQueryFunction ⇒ <code>Promise.<ShardQueryResult></code> | ||
Shard query function | ||
**Kind**: inner typedef of [<code>entity-manager</code>](#module_entity-manager) | ||
**Returns**: <code>Promise.<ShardQueryResult></code> - Sharded query result. | ||
| Param | Type | Description | | ||
| --- | --- | --- | | ||
| shardedKey | <code>string</code> | Sharded key. | | ||
| [pageKey] | <code>\*</code> | Page key. | | ||
<a name="module_entity-manager..ShardedQueryResult"></a> | ||
### entity-manager~ShardedQueryResult : <code>object</code> | ||
**Kind**: inner typedef of [<code>entity-manager</code>](#module_entity-manager) | ||
**Properties** | ||
| Name | Type | Description | | ||
| --- | --- | --- | | ||
| items | <code>Array.<any></code> | Query result array. | | ||
| shardPageKeys | <code>object</code> | Shard page keys. | | ||
--- | ||
@@ -303,0 +361,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
59612
1084
358