@karmaniverous/entity-manager 6.13.3 → 6.14.1
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/README.md +330 -16
- package/dist/cjs/{EntityManager.js → EntityManager/EntityManager.js} +18 -44
- package/dist/cjs/{ParsedConfig.js → EntityManager/ParsedConfig.js} +46 -55
- package/dist/cjs/{addKeys.js → EntityManager/addKeys.js} +1 -0
- package/dist/cjs/{decodeElement.js → EntityManager/decodeElement.js} +2 -1
- package/dist/cjs/{dehydratePageKeyMap.js → EntityManager/dehydratePageKeyMap.js} +3 -1
- package/dist/cjs/{encodeElement.js → EntityManager/encodeElement.js} +2 -2
- package/dist/cjs/{encodeGeneratedProperty.js → EntityManager/encodeGeneratedProperty.js} +1 -1
- package/dist/cjs/EntityManager/getPrimaryKey.js +25 -0
- package/dist/cjs/{rehydratePageKeyMap.js → EntityManager/rehydratePageKeyMap.js} +3 -1
- package/dist/cjs/{removeKeys.js → EntityManager/removeKeys.js} +10 -8
- package/dist/cjs/{updateItemHashKey.js → EntityManager/updateItemHashKey.js} +4 -1
- package/dist/cjs/index.js +5 -3
- package/dist/index.d.ts +109 -252
- package/dist/mjs/{EntityManager.js → EntityManager/EntityManager.js} +18 -44
- package/dist/mjs/{ParsedConfig.js → EntityManager/ParsedConfig.js} +46 -55
- package/dist/mjs/{addKeys.js → EntityManager/addKeys.js} +1 -0
- package/dist/mjs/{decodeElement.js → EntityManager/decodeElement.js} +2 -1
- package/dist/mjs/{dehydratePageKeyMap.js → EntityManager/dehydratePageKeyMap.js} +3 -1
- package/dist/mjs/{encodeElement.js → EntityManager/encodeElement.js} +2 -2
- package/dist/mjs/{encodeGeneratedProperty.js → EntityManager/encodeGeneratedProperty.js} +1 -1
- package/dist/mjs/EntityManager/getPrimaryKey.js +23 -0
- package/dist/mjs/{rehydratePageKeyMap.js → EntityManager/rehydratePageKeyMap.js} +3 -1
- package/dist/mjs/{removeKeys.js → EntityManager/removeKeys.js} +10 -8
- package/dist/mjs/{updateItemHashKey.js → EntityManager/updateItemHashKey.js} +4 -1
- package/dist/mjs/index.js +4 -3
- package/package.json +44 -45
- /package/dist/cjs/{BaseEntityClient.js → BaseEntityClient/BaseEntityClient.js} +0 -0
- /package/dist/cjs/{BaseQueryBuilder.js → BaseQueryBuilder/BaseQueryBuilder.js} +0 -0
- /package/dist/cjs/{decodeGeneratedProperty.js → EntityManager/decodeGeneratedProperty.js} +0 -0
- /package/dist/cjs/{dehydrateIndexItem.js → EntityManager/dehydrateIndexItem.js} +0 -0
- /package/dist/cjs/{findIndexToken.js → EntityManager/findIndexToken.js} +0 -0
- /package/dist/cjs/{getHashKeySpace.js → EntityManager/getHashKeySpace.js} +0 -0
- /package/dist/cjs/{getIndexComponents.js → EntityManager/getIndexComponents.js} +0 -0
- /package/dist/cjs/{getShardBump.js → EntityManager/getShardBump.js} +0 -0
- /package/dist/cjs/{query.js → EntityManager/query.js} +0 -0
- /package/dist/cjs/{rehydrateIndexItem.js → EntityManager/rehydrateIndexItem.js} +0 -0
- /package/dist/cjs/{unwrapIndex.js → EntityManager/unwrapIndex.js} +0 -0
- /package/dist/cjs/{updateItemRangeKey.js → EntityManager/updateItemRangeKey.js} +0 -0
- /package/dist/cjs/{validateEntityToken.js → EntityManager/validateEntityToken.js} +0 -0
- /package/dist/cjs/{validateGeneratedProperty.js → EntityManager/validateGeneratedProperty.js} +0 -0
- /package/dist/cjs/{validateIndexToken.js → EntityManager/validateIndexToken.js} +0 -0
- /package/dist/cjs/{validateTranscodedProperty.js → EntityManager/validateTranscodedProperty.js} +0 -0
- /package/dist/mjs/{BaseEntityClient.js → BaseEntityClient/BaseEntityClient.js} +0 -0
- /package/dist/mjs/{BaseQueryBuilder.js → BaseQueryBuilder/BaseQueryBuilder.js} +0 -0
- /package/dist/mjs/{decodeGeneratedProperty.js → EntityManager/decodeGeneratedProperty.js} +0 -0
- /package/dist/mjs/{dehydrateIndexItem.js → EntityManager/dehydrateIndexItem.js} +0 -0
- /package/dist/mjs/{findIndexToken.js → EntityManager/findIndexToken.js} +0 -0
- /package/dist/mjs/{getHashKeySpace.js → EntityManager/getHashKeySpace.js} +0 -0
- /package/dist/mjs/{getIndexComponents.js → EntityManager/getIndexComponents.js} +0 -0
- /package/dist/mjs/{getShardBump.js → EntityManager/getShardBump.js} +0 -0
- /package/dist/mjs/{query.js → EntityManager/query.js} +0 -0
- /package/dist/mjs/{rehydrateIndexItem.js → EntityManager/rehydrateIndexItem.js} +0 -0
- /package/dist/mjs/{unwrapIndex.js → EntityManager/unwrapIndex.js} +0 -0
- /package/dist/mjs/{updateItemRangeKey.js → EntityManager/updateItemRangeKey.js} +0 -0
- /package/dist/mjs/{validateEntityToken.js → EntityManager/validateEntityToken.js} +0 -0
- /package/dist/mjs/{validateGeneratedProperty.js → EntityManager/validateGeneratedProperty.js} +0 -0
- /package/dist/mjs/{validateIndexToken.js → EntityManager/validateIndexToken.js} +0 -0
- /package/dist/mjs/{validateTranscodedProperty.js → EntityManager/validateTranscodedProperty.js} +0 -0
|
@@ -10,7 +10,7 @@ const validateArrayUnique = (arr, ctx, identity = (item) => item, path = []) =>
|
|
|
10
10
|
for (const [element, count] of Object.entries(counts)) {
|
|
11
11
|
if (count > 1)
|
|
12
12
|
ctx.addIssue({
|
|
13
|
-
code:
|
|
13
|
+
code: 'custom',
|
|
14
14
|
message: `duplicate array element`,
|
|
15
15
|
params: { element },
|
|
16
16
|
path,
|
|
@@ -21,7 +21,7 @@ const validateKeysExclusive = (keys, label, ref, ctx) => {
|
|
|
21
21
|
const intersection = keys.filter((key) => ref.includes(key));
|
|
22
22
|
if (intersection.length)
|
|
23
23
|
ctx.addIssue({
|
|
24
|
-
code:
|
|
24
|
+
code: 'custom',
|
|
25
25
|
message: `${label} key collision: ${intersection.toString()}`,
|
|
26
26
|
});
|
|
27
27
|
};
|
|
@@ -32,26 +32,14 @@ const componentArray = zod.z
|
|
|
32
32
|
const configSchema = zod.z
|
|
33
33
|
.object({
|
|
34
34
|
entities: zod.z
|
|
35
|
-
.record(zod.z
|
|
35
|
+
.record(zod.z.string(), zod.z
|
|
36
36
|
.object({
|
|
37
|
-
defaultLimit: zod.z
|
|
38
|
-
|
|
39
|
-
.int()
|
|
40
|
-
.positive()
|
|
41
|
-
.safe()
|
|
42
|
-
.optional()
|
|
43
|
-
.default(10),
|
|
44
|
-
defaultPageSize: zod.z
|
|
45
|
-
.number()
|
|
46
|
-
.int()
|
|
47
|
-
.positive()
|
|
48
|
-
.safe()
|
|
49
|
-
.optional()
|
|
50
|
-
.default(10),
|
|
37
|
+
defaultLimit: zod.z.number().int().positive().optional().default(10),
|
|
38
|
+
defaultPageSize: zod.z.number().int().positive().optional().default(10),
|
|
51
39
|
shardBumps: zod.z
|
|
52
40
|
.array(zod.z
|
|
53
41
|
.object({
|
|
54
|
-
timestamp: zod.z.number().
|
|
42
|
+
timestamp: zod.z.number().int().nonnegative(),
|
|
55
43
|
charBits: zod.z.number().int().min(1).max(5),
|
|
56
44
|
chars: zod.z.number().int().min(0).max(40),
|
|
57
45
|
})
|
|
@@ -79,7 +67,7 @@ const configSchema = zod.z
|
|
|
79
67
|
for (let i = 1; i < val.length; i++)
|
|
80
68
|
if (val[i].chars <= val[i - 1].chars)
|
|
81
69
|
ctx.addIssue({
|
|
82
|
-
code:
|
|
70
|
+
code: 'custom',
|
|
83
71
|
message: `shardBump chars do not monotonically increase at timestamp ${val[i].timestamp.toString()}`,
|
|
84
72
|
path: [i],
|
|
85
73
|
});
|
|
@@ -93,14 +81,14 @@ const configSchema = zod.z
|
|
|
93
81
|
.default({}),
|
|
94
82
|
generatedProperties: zod.z
|
|
95
83
|
.object({
|
|
96
|
-
sharded: zod.z.record(componentArray).optional().default({}),
|
|
97
|
-
unsharded: zod.z.record(componentArray).optional().default({}),
|
|
84
|
+
sharded: zod.z.record(zod.z.string(), componentArray).optional().default({}),
|
|
85
|
+
unsharded: zod.z.record(zod.z.string(), componentArray).optional().default({}),
|
|
98
86
|
})
|
|
99
87
|
.optional()
|
|
100
88
|
.default({ sharded: {}, unsharded: {} }),
|
|
101
89
|
hashKey: zod.z.string(),
|
|
102
90
|
indexes: zod.z
|
|
103
|
-
.record(zod.z.object({
|
|
91
|
+
.record(zod.z.string(), zod.z.object({
|
|
104
92
|
hashKey: zod.z.string().min(1),
|
|
105
93
|
rangeKey: zod.z.string().min(1),
|
|
106
94
|
projections: zod.z
|
|
@@ -112,15 +100,18 @@ const configSchema = zod.z
|
|
|
112
100
|
.default({}),
|
|
113
101
|
generatedKeyDelimiter: zod.z.string().regex(/\W+/).optional().default('|'),
|
|
114
102
|
generatedValueDelimiter: zod.z.string().regex(/\W+/).optional().default('#'),
|
|
115
|
-
propertyTranscodes: zod.z.record(zod.z.string()).optional().default({}),
|
|
103
|
+
propertyTranscodes: zod.z.record(zod.z.string(), zod.z.string()).optional().default({}),
|
|
116
104
|
rangeKey: zod.z.string(),
|
|
117
105
|
shardKeyDelimiter: zod.z.string().regex(/\W+/).optional().default('!'),
|
|
118
|
-
throttle: zod.z.number().int().positive().
|
|
106
|
+
throttle: zod.z.number().int().positive().optional().default(10),
|
|
119
107
|
transcodes: zod.z
|
|
120
|
-
.record(zod.z
|
|
108
|
+
.record(zod.z.string(), zod.z
|
|
121
109
|
.object({
|
|
122
|
-
|
|
123
|
-
|
|
110
|
+
// Accept function shapes without relying on z.function()
|
|
111
|
+
// to avoid TS inference conflicts across Zod versions and
|
|
112
|
+
// to remain compatible with narrower parameter types.
|
|
113
|
+
encode: zod.z.custom((fn) => typeof fn === 'function'),
|
|
114
|
+
decode: zod.z.custom((fn) => typeof fn === 'function'),
|
|
124
115
|
})
|
|
125
116
|
.strict())
|
|
126
117
|
.optional()
|
|
@@ -131,7 +122,7 @@ const configSchema = zod.z
|
|
|
131
122
|
// validate no generated key delimiter collision
|
|
132
123
|
if (data.generatedKeyDelimiter.includes(data.generatedValueDelimiter))
|
|
133
124
|
ctx.addIssue({
|
|
134
|
-
code:
|
|
125
|
+
code: 'custom',
|
|
135
126
|
message: 'generatedKeyDelimiter contains generatedValueDelimiter',
|
|
136
127
|
params: {
|
|
137
128
|
generatedKeyDelimiter: data.generatedKeyDelimiter,
|
|
@@ -141,7 +132,7 @@ const configSchema = zod.z
|
|
|
141
132
|
});
|
|
142
133
|
if (data.generatedKeyDelimiter.includes(data.shardKeyDelimiter))
|
|
143
134
|
ctx.addIssue({
|
|
144
|
-
code:
|
|
135
|
+
code: 'custom',
|
|
145
136
|
message: 'generatedKeyDelimiter contains shardKeyDelimiter',
|
|
146
137
|
params: {
|
|
147
138
|
generatedKeyDelimiter: data.generatedKeyDelimiter,
|
|
@@ -152,7 +143,7 @@ const configSchema = zod.z
|
|
|
152
143
|
// validate no generated value delimiter collision
|
|
153
144
|
if (data.generatedValueDelimiter.includes(data.generatedKeyDelimiter))
|
|
154
145
|
ctx.addIssue({
|
|
155
|
-
code:
|
|
146
|
+
code: 'custom',
|
|
156
147
|
message: 'generatedValueDelimiter contains generatedKeyDelimiter',
|
|
157
148
|
params: {
|
|
158
149
|
generatedValueDelimiter: data.generatedValueDelimiter,
|
|
@@ -162,7 +153,7 @@ const configSchema = zod.z
|
|
|
162
153
|
});
|
|
163
154
|
if (data.generatedValueDelimiter.includes(data.shardKeyDelimiter))
|
|
164
155
|
ctx.addIssue({
|
|
165
|
-
code:
|
|
156
|
+
code: 'custom',
|
|
166
157
|
message: 'generatedValueDelimiter contains shardKeyDelimiter',
|
|
167
158
|
params: {
|
|
168
159
|
generatedValueDelimiter: data.generatedValueDelimiter,
|
|
@@ -173,7 +164,7 @@ const configSchema = zod.z
|
|
|
173
164
|
// validate no shard key delimiter collision
|
|
174
165
|
if (data.shardKeyDelimiter.includes(data.generatedKeyDelimiter))
|
|
175
166
|
ctx.addIssue({
|
|
176
|
-
code:
|
|
167
|
+
code: 'custom',
|
|
177
168
|
message: 'shardKeyDelimiter contains generatedKeyDelimiter',
|
|
178
169
|
params: {
|
|
179
170
|
generatedKeyDelimiter: data.generatedKeyDelimiter,
|
|
@@ -183,7 +174,7 @@ const configSchema = zod.z
|
|
|
183
174
|
});
|
|
184
175
|
if (data.shardKeyDelimiter.includes(data.generatedValueDelimiter))
|
|
185
176
|
ctx.addIssue({
|
|
186
|
-
code:
|
|
177
|
+
code: 'custom',
|
|
187
178
|
message: 'shardKeyDelimiter contains generatedValueDelimiter',
|
|
188
179
|
params: {
|
|
189
180
|
generatedValueDelimiter: data.generatedValueDelimiter,
|
|
@@ -213,19 +204,17 @@ const configSchema = zod.z
|
|
|
213
204
|
for (const [property, transcode] of Object.entries(data.propertyTranscodes))
|
|
214
205
|
if (!transcodes.includes(transcode))
|
|
215
206
|
ctx.addIssue({
|
|
216
|
-
code:
|
|
217
|
-
|
|
207
|
+
code: 'custom',
|
|
208
|
+
message: `propertyTranscodes['${property}'] references unknown transcode '${transcode}'`,
|
|
218
209
|
path: ['propertyTranscodes', property],
|
|
219
|
-
received: transcode,
|
|
220
210
|
});
|
|
221
211
|
// Validate all sharded property elements are transcoded properties.
|
|
222
212
|
for (const [property, elements] of Object.entries(data.generatedProperties.sharded))
|
|
223
213
|
for (const element of elements)
|
|
224
214
|
if (!transcodedProperties.includes(element))
|
|
225
215
|
ctx.addIssue({
|
|
226
|
-
code:
|
|
227
|
-
|
|
228
|
-
received: element,
|
|
216
|
+
code: 'custom',
|
|
217
|
+
message: `generatedProperties.sharded['${property}'] contains non-transcoded element '${element}'`,
|
|
229
218
|
path: ['generatedProperties', 'sharded', property],
|
|
230
219
|
});
|
|
231
220
|
// Validate all unsharded property elements are transcoded properties.
|
|
@@ -233,9 +222,8 @@ const configSchema = zod.z
|
|
|
233
222
|
for (const element of elements)
|
|
234
223
|
if (!transcodedProperties.includes(element))
|
|
235
224
|
ctx.addIssue({
|
|
236
|
-
code:
|
|
237
|
-
|
|
238
|
-
received: element,
|
|
225
|
+
code: 'custom',
|
|
226
|
+
message: `generatedProperties.unsharded['${property}'] contains non-transcoded element '${element}'`,
|
|
239
227
|
path: ['generatedProperties', 'unsharded', property],
|
|
240
228
|
});
|
|
241
229
|
// Validate indexes.
|
|
@@ -244,19 +232,24 @@ const configSchema = zod.z
|
|
|
244
232
|
// Validate hash key is sharded.
|
|
245
233
|
if (![data.hashKey, ...shardedKeys].includes(hashKey)) {
|
|
246
234
|
ctx.addIssue({
|
|
247
|
-
code:
|
|
248
|
-
|
|
235
|
+
code: 'custom',
|
|
236
|
+
message: `index '${indexKey}' hashKey '${hashKey}' must be one of [${[
|
|
237
|
+
data.hashKey,
|
|
238
|
+
...shardedKeys,
|
|
239
|
+
].join(', ')}]`,
|
|
249
240
|
path: ['indexes', indexKey, 'hashKey'],
|
|
250
|
-
received: hashKey,
|
|
251
241
|
});
|
|
252
242
|
}
|
|
253
243
|
// Validate range key is unsharded or transcodable.
|
|
254
244
|
if (![data.rangeKey, ...unshardedKeys, ...transcodedProperties].includes(rangeKey)) {
|
|
255
245
|
ctx.addIssue({
|
|
256
|
-
code:
|
|
257
|
-
|
|
246
|
+
code: 'custom',
|
|
247
|
+
message: `index '${indexKey}' rangeKey '${rangeKey}' must be one of [${[
|
|
248
|
+
data.rangeKey,
|
|
249
|
+
...unshardedKeys,
|
|
250
|
+
...transcodedProperties,
|
|
251
|
+
].join(', ')}]`,
|
|
258
252
|
path: ['indexes', indexKey, 'rangeKey'],
|
|
259
|
-
received: rangeKey,
|
|
260
253
|
});
|
|
261
254
|
}
|
|
262
255
|
// Validate no index projections are keys.
|
|
@@ -271,7 +264,7 @@ const configSchema = zod.z
|
|
|
271
264
|
...unshardedKeys,
|
|
272
265
|
].includes(projection))
|
|
273
266
|
ctx.addIssue({
|
|
274
|
-
code:
|
|
267
|
+
code: 'custom',
|
|
275
268
|
message: 'index projection is a key',
|
|
276
269
|
params: { projection },
|
|
277
270
|
path: ['indexes', indexKey, 'projections'],
|
|
@@ -282,18 +275,16 @@ const configSchema = zod.z
|
|
|
282
275
|
// validate timestampProperty is a transcoded property.
|
|
283
276
|
if (!transcodedProperties.includes(timestampProperty))
|
|
284
277
|
ctx.addIssue({
|
|
285
|
-
code:
|
|
286
|
-
|
|
278
|
+
code: 'custom',
|
|
279
|
+
message: `entities['${entityToken}'].timestampProperty '${timestampProperty}' must be one of [${transcodedProperties.join(', ')}]`,
|
|
287
280
|
path: ['entities', entityToken, 'timestampProperty'],
|
|
288
|
-
received: timestampProperty,
|
|
289
281
|
});
|
|
290
282
|
// validate uniqueProperty is a transcoded property.
|
|
291
283
|
if (!transcodedProperties.includes(uniqueProperty))
|
|
292
284
|
ctx.addIssue({
|
|
293
|
-
code:
|
|
294
|
-
|
|
285
|
+
code: 'custom',
|
|
286
|
+
message: `entities['${entityToken}'].uniqueProperty '${uniqueProperty}' must be one of [${transcodedProperties.join(', ')}]`,
|
|
295
287
|
path: ['entities', entityToken, 'uniqueProperty'],
|
|
296
|
-
received: uniqueProperty,
|
|
297
288
|
});
|
|
298
289
|
}
|
|
299
290
|
});
|
|
@@ -24,7 +24,8 @@ function decodeElement(entityManager, element, value) {
|
|
|
24
24
|
if (!value)
|
|
25
25
|
return;
|
|
26
26
|
const { propertyTranscodes, transcodes } = entityManager.config;
|
|
27
|
-
const
|
|
27
|
+
const decodeFn = transcodes[propertyTranscodes[element]].decode;
|
|
28
|
+
const decoded = decodeFn(value);
|
|
28
29
|
entityManager.logger.debug('decoded entity element', {
|
|
29
30
|
element,
|
|
30
31
|
value,
|
|
@@ -40,7 +40,9 @@ 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) =>
|
|
43
|
+
indexes.map((index) => {
|
|
44
|
+
validateIndexToken.validateIndexToken(entityManager, index);
|
|
45
|
+
});
|
|
44
46
|
// Extract & sort hash keys.
|
|
45
47
|
const hashKeys = Object.keys(pageKeyMap[indexes[0]]);
|
|
46
48
|
// Dehydrate page keys.
|
|
@@ -21,8 +21,8 @@ function encodeElement(entityManager, element, item) {
|
|
|
21
21
|
const value = item[element];
|
|
22
22
|
if (value === undefined || [hashKey, rangeKey].includes(element))
|
|
23
23
|
return value;
|
|
24
|
-
const
|
|
25
|
-
|
|
24
|
+
const encodeFn = transcodes[propertyTranscodes[element]].encode;
|
|
25
|
+
const encoded = encodeFn(item[element]) || undefined;
|
|
26
26
|
entityManager.logger.debug('encoded entity element', {
|
|
27
27
|
element,
|
|
28
28
|
item,
|
|
@@ -30,7 +30,7 @@ function encodeGeneratedProperty(entityManager, property, item) {
|
|
|
30
30
|
...(sharded
|
|
31
31
|
? [item[entityManager.config.hashKey]]
|
|
32
32
|
: []),
|
|
33
|
-
...elementMap.map(([element, value]) => [element,
|
|
33
|
+
...elementMap.map(([element, value]) => [element, `${value ?? ''}`].join(entityManager.config.generatedValueDelimiter)),
|
|
34
34
|
].join(entityManager.config.generatedKeyDelimiter);
|
|
35
35
|
entityManager.logger.debug('encoded generated property', {
|
|
36
36
|
property,
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var radash = require('radash');
|
|
4
|
+
var addKeys = require('./addKeys.js');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Convert an {@link EntityItem | `EntityItem`} into an {@link EntityKey | `EntityKey`}.
|
|
8
|
+
*
|
|
9
|
+
* @param entityManager - {@link EntityManager | `EntityManager`} instance.
|
|
10
|
+
* @param entityToken - {@link Config | `Config`} `entities` key.
|
|
11
|
+
* @param item - {@link EntityItem | `EntityItem`} object.
|
|
12
|
+
* @param overwrite - Overwrite existing properties (default `false`).
|
|
13
|
+
*
|
|
14
|
+
* @returns {@link EntityKey | `EntityKey`} extracted from shallow clone of `item` with updated properties.
|
|
15
|
+
*
|
|
16
|
+
* @throws `Error` if `entityToken` is invalid.
|
|
17
|
+
*/
|
|
18
|
+
function getPrimaryKey(entityManager, entityToken, item, overwrite = false) {
|
|
19
|
+
const { hashKey, rangeKey } = entityManager.config;
|
|
20
|
+
return radash.pick(!overwrite && item[hashKey] && item[rangeKey]
|
|
21
|
+
? item
|
|
22
|
+
: addKeys.addKeys(entityManager, entityToken, item, overwrite), [entityManager.config.hashKey, entityManager.config.rangeKey]);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
exports.getPrimaryKey = getPrimaryKey;
|
|
@@ -47,7 +47,9 @@ function rehydratePageKeyMap(entityManager, entityToken, indexTokens, item, dehy
|
|
|
47
47
|
if (hashKeys.length > 1)
|
|
48
48
|
throw new Error('inconsistent hashKeys');
|
|
49
49
|
const [hashKeyToken] = hashKeys;
|
|
50
|
-
indexTokens.map((index) =>
|
|
50
|
+
indexTokens.map((index) => {
|
|
51
|
+
validateIndexToken.validateIndexToken(entityManager, index);
|
|
52
|
+
});
|
|
51
53
|
// Shortcut empty dehydrated.
|
|
52
54
|
if (dehydrated && !dehydrated.length)
|
|
53
55
|
return [hashKeyToken, {}];
|
|
@@ -17,14 +17,16 @@ function removeKeys(entityManager, entityToken, item) {
|
|
|
17
17
|
try {
|
|
18
18
|
// Validate params.
|
|
19
19
|
validateEntityToken.validateEntityToken(entityManager, entityToken);
|
|
20
|
-
//
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
+
const newItem = Object.fromEntries(Object.entries(item).filter(([key]) => !keysToStrip.has(key)));
|
|
28
30
|
entityManager.logger.debug('stripped entity item generated properties', {
|
|
29
31
|
entityToken,
|
|
30
32
|
item,
|
|
@@ -42,12 +42,15 @@ function updateItemHashKey(entityManager, entityToken, item, overwrite = false)
|
|
|
42
42
|
if (chars) {
|
|
43
43
|
// Radix is the numerical base of the shardKey.
|
|
44
44
|
const radix = 2 ** charBits;
|
|
45
|
+
// Compute the full shard space for this bump. Use radix ** chars to ensure
|
|
46
|
+
// all placeholders are utilized (e.g., chars=2, charBits=2 => 16 combos).
|
|
47
|
+
const space = radix ** chars;
|
|
45
48
|
// Get item unique property & validate.
|
|
46
49
|
const uniqueId = item[entityManager.config.entities[entityToken]
|
|
47
50
|
.uniqueProperty];
|
|
48
51
|
if (entityTools.isNil(uniqueId))
|
|
49
52
|
throw new Error(`missing item unique property`);
|
|
50
|
-
hashKey += (stringHash(uniqueId
|
|
53
|
+
hashKey += (stringHash(uniqueId) % space)
|
|
51
54
|
.toString(radix)
|
|
52
55
|
.padStart(chars, '0');
|
|
53
56
|
}
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var BaseEntityClient = require('./BaseEntityClient.js');
|
|
4
|
-
var BaseQueryBuilder = require('./BaseQueryBuilder.js');
|
|
5
|
-
var EntityManager = require('./EntityManager.js');
|
|
3
|
+
var BaseEntityClient = require('./BaseEntityClient/BaseEntityClient.js');
|
|
4
|
+
var BaseQueryBuilder = require('./BaseQueryBuilder/BaseQueryBuilder.js');
|
|
5
|
+
var EntityManager = require('./EntityManager/EntityManager.js');
|
|
6
|
+
var ParsedConfig = require('./EntityManager/ParsedConfig.js');
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
exports.BaseEntityClient = BaseEntityClient.BaseEntityClient;
|
|
10
11
|
exports.BaseQueryBuilder = BaseQueryBuilder.BaseQueryBuilder;
|
|
11
12
|
exports.EntityManager = EntityManager.EntityManager;
|
|
13
|
+
exports.configSchema = ParsedConfig.configSchema;
|