@karmaniverous/entity-manager 6.7.5 → 6.8.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.
Files changed (59) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/BaseEntityClient.js +1 -1
  3. package/dist/cjs/BaseQueryBuilder.js +5 -1
  4. package/dist/cjs/EntityManager.js +18 -9
  5. package/dist/cjs/ParsedConfig.js +143 -113
  6. package/dist/cjs/addKeys.js +6 -6
  7. package/dist/{mjs/decodeEntityElement.js → cjs/decodeElement.js} +10 -12
  8. package/dist/cjs/decodeGeneratedProperty.js +6 -10
  9. package/dist/cjs/dehydrateIndexItem.js +12 -11
  10. package/dist/cjs/dehydratePageKeyMap.js +10 -7
  11. package/dist/{mjs/encodeEntityElement.js → cjs/encodeElement.js} +8 -10
  12. package/dist/cjs/encodeGeneratedProperty.js +14 -18
  13. package/dist/cjs/getHashKeySpace.js +6 -6
  14. package/dist/cjs/getIndexComponents.js +6 -8
  15. package/dist/cjs/getShardBump.js +1 -1
  16. package/dist/cjs/index.js +0 -2
  17. package/dist/cjs/query.js +1 -1
  18. package/dist/cjs/rehydrateIndexItem.js +12 -10
  19. package/dist/cjs/rehydratePageKeyMap.js +18 -11
  20. package/dist/cjs/removeKeys.js +3 -2
  21. package/dist/cjs/unwrapIndex.js +25 -11
  22. package/dist/cjs/updateItemHashKey.js +5 -3
  23. package/dist/cjs/updateItemRangeKey.js +6 -4
  24. package/dist/cjs/validateGeneratedProperty.js +23 -0
  25. package/dist/cjs/validateIndexToken.js +16 -0
  26. package/dist/cjs/validateTranscodedProperty.js +16 -0
  27. package/dist/index.d.ts +265 -538
  28. package/dist/mjs/BaseEntityClient.js +1 -1
  29. package/dist/mjs/BaseQueryBuilder.js +5 -1
  30. package/dist/mjs/EntityManager.js +18 -9
  31. package/dist/mjs/ParsedConfig.js +143 -113
  32. package/dist/mjs/addKeys.js +6 -6
  33. package/dist/{cjs/decodeEntityElement.js → mjs/decodeElement.js} +8 -14
  34. package/dist/mjs/decodeGeneratedProperty.js +6 -10
  35. package/dist/mjs/dehydrateIndexItem.js +12 -11
  36. package/dist/mjs/dehydratePageKeyMap.js +10 -7
  37. package/dist/{cjs/encodeEntityElement.js → mjs/encodeElement.js} +7 -13
  38. package/dist/mjs/encodeGeneratedProperty.js +14 -18
  39. package/dist/mjs/getHashKeySpace.js +6 -6
  40. package/dist/mjs/getIndexComponents.js +6 -8
  41. package/dist/mjs/getShardBump.js +1 -1
  42. package/dist/mjs/index.js +0 -1
  43. package/dist/mjs/query.js +1 -1
  44. package/dist/mjs/rehydrateIndexItem.js +12 -10
  45. package/dist/mjs/rehydratePageKeyMap.js +18 -11
  46. package/dist/mjs/removeKeys.js +3 -2
  47. package/dist/mjs/unwrapIndex.js +26 -12
  48. package/dist/mjs/updateItemHashKey.js +5 -3
  49. package/dist/mjs/updateItemRangeKey.js +6 -4
  50. package/dist/mjs/validateGeneratedProperty.js +21 -0
  51. package/dist/mjs/validateIndexToken.js +14 -0
  52. package/dist/mjs/validateTranscodedProperty.js +14 -0
  53. package/package.json +6 -6
  54. package/dist/cjs/conditionalize.js +0 -25
  55. package/dist/cjs/validateEntityGeneratedProperty.js +0 -29
  56. package/dist/cjs/validateEntityIndexToken.js +0 -22
  57. package/dist/mjs/conditionalize.js +0 -23
  58. package/dist/mjs/validateEntityGeneratedProperty.js +0 -27
  59. package/dist/mjs/validateEntityIndexToken.js +0 -20
package/dist/index.d.ts CHANGED
@@ -1,7 +1,22 @@
1
+ import { EntityMap, TranscodeMap, FlattenEntityMap, ConditionalProperty, Exactify, PropertiesOfType, TranscodableProperties, Transcodes, SortOrder, MutuallyExclusive, NotNever, DefaultTranscodeMap } from '@karmaniverous/entity-tools';
1
2
  import { BatchProcessOptions } from '@karmaniverous/batch-process';
2
- import { Entity, Exactify, TranscodeMap, PropertiesOfType, TranscodableProperties, Transcodes, DefaultTranscodeMap, SortOrder } from '@karmaniverous/entity-tools';
3
3
  import { z } from 'zod';
4
4
 
5
+ /**
6
+ * Default type parameter for {@link ConfigMap | `ConfigMap`}.
7
+ *
8
+ * @category EntityManager
9
+ */
10
+ interface BaseConfigMap {
11
+ EntityMap: EntityMap;
12
+ HashKey: string;
13
+ RangeKey: string;
14
+ ShardedKeys: string;
15
+ UnshardedKeys: string;
16
+ TranscodedProperties: string;
17
+ TranscodeMap: TranscodeMap;
18
+ }
19
+
5
20
  /**
6
21
  * Base EntityClient options.
7
22
  *
@@ -25,61 +40,52 @@ declare abstract class BaseEntityClient {
25
40
  /**
26
41
  * DynamoDB EntityClient constructor.
27
42
  *
28
- * @param options - {@link EntityClientOptions | `EntityClientOptions`} object.
43
+ * @param options - {@link BaseEntityClientOptions | `BaseEntityClientOptions`} object.
29
44
  */
30
45
  constructor(options: BaseEntityClientOptions);
31
46
  }
32
47
 
33
48
  /**
34
- * The base EntityMap type. All EntityMaps should extend this type.
35
- *
36
- * @category Entities
37
- */
38
- type EntityMap = Record<string, Entity>;
39
- /**
40
- * Tests a string literal type to determine whether it is a key of any {@link Entity | `Entity`} in an {@link EntityMap | `EntityMap`} or is a member of a union of reserved keys.
41
- *
42
- * @typeParam K - The string literal type to test.
43
- * @typeParam M - The {@link EntityMap | `EntityMap`}.
44
- * @typeParam R - The reserved set of string literal types.
49
+ * Extracts a database-facing partial item type from a {@link BaseConfigMap | `ConfigMap`}.
45
50
  *
46
- * @returns `K` if `K` is exclusive or `never` otherwise.
51
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
47
52
  *
48
- * @category Config
53
+ * @category EntityManager
49
54
  * @protected
50
55
  */
51
- type ExclusiveKey<K extends string, M extends EntityMap, R extends string = never> = keyof {
52
- [E in keyof Exactify<M> as K extends keyof Exactify<M[E]> | R ? K : never]: never;
53
- } extends never ? K : never;
56
+ type EntityItem<C extends BaseConfigMap> = Partial<FlattenEntityMap<C['EntityMap']> & Record<C['HashKey'] | C['RangeKey'] | C['ShardedKeys'] | C['UnshardedKeys'], string>> & Record<string, unknown>;
57
+
54
58
  /**
55
- * Returns the `generated` property of a Config entity.
59
+ * A result returned by a query across multiple shards, where each shard may receive multiple page queries via a dynamically-generated {@link ShardQueryFunction | `ShardQueryFunction`}.
56
60
  *
57
- * @typeParam EntityToken - The {@link Entity | `Entity`} token.
58
- * @typeParam M - The {@link EntityMap | `EntityMap`}.
59
- * @typeParam T - The {@link TranscodeMap | `TranscodeMap`} identifying transcodable property types.
61
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
60
62
  *
61
- * @remarks
62
- * All Entity properties of type `never` must be represented, and no extra properties are allowed.
63
- *
64
- * @category Config
63
+ * @category EntityManager
65
64
  * @protected
66
65
  */
67
- type ConfigEntityGenerated<EntityToken extends keyof Exactify<M>, M extends EntityMap, T extends TranscodeMap> = ([PropertiesOfType<M[EntityToken], never>] extends [never] ? never : Record<PropertiesOfType<M[EntityToken], never>, {
68
- atomic?: boolean;
69
- elements: TranscodableProperties<M[EntityToken], T>[];
70
- sharded?: boolean;
71
- }>) | ([PropertiesOfType<M[EntityToken], never>] extends [never] ? Record<string, never> : never);
66
+ interface QueryResult<C extends BaseConfigMap> {
67
+ /** Total number of records returned across all shards. */
68
+ count: number;
69
+ /** The returned records. */
70
+ items: EntityItem<C>[];
71
+ /**
72
+ * A compressed, two-layer map of page keys, used to query the next page of
73
+ * data for a given sort key on each shard of a given hash key.
74
+ */
75
+ pageKeyMap: string;
76
+ }
77
+
72
78
  /**
73
- * Defines a single time period in an {@link Entity | `Entity`} sharding strategy.
79
+ * Defines a single time period in an entity sharding strategy.
74
80
  *
75
- * @category Config
81
+ * @category EntityManager
76
82
  * @protected
77
83
  */
78
84
  interface ShardBump {
79
85
  /**
80
86
  * The timestamp marking the beginning of the time period. Must be a non-negative integer.
81
87
  *
82
- * This value must be unique across all {@link ShardBump | `ShardBumps`} for the {@link Entity | `Entity`}.
88
+ * This value must be unique across all {@link ShardBump | `ShardBumps`} for the entity.
83
89
  */
84
90
  timestamp: number;
85
91
  /**
@@ -96,351 +102,52 @@ interface ShardBump {
96
102
  */
97
103
  chars: number;
98
104
  }
99
- /**
100
- * Returns a Config entity index component type.
101
- *
102
- * @typeParam EntityToken - The {@link Entity | `Entity`} token.
103
- * @typeParam M - The {@link EntityMap | `EntityMap`}.
104
- * @typeParam HashKey - The property used across the configuration to store an {@link Entity | `Entity`}'s sharded hash key. Should be configured as the table hash key. Must not conflict with any {@link Entity | `Entity`} property.
105
- * @typeParam RangeKey - The property used across the configuration to store an {@link Entity | `Entity`}'s range key. Should be configured as the table range key. Must not conflict with any {@link Entity | `Entity`} property.
106
- * @typeParam T - The {@link TranscodeMap | `TranscodeMap`} identifying transcodable property types. Only {@link Entity | `Entity`} properties of these types can be components of an {@link ConfigEntity.indexes | index} or a {@link ConfigEntityGenerated | generated property}.
107
105
 
108
- * @category Config
109
- * @protected
110
- */
111
- type ConfigEntityIndexComponent<EntityToken extends keyof Exactify<M>, M extends EntityMap, HashKey extends string, RangeKey extends string, T extends TranscodeMap> = TranscodableProperties<M[EntityToken], T> | PropertiesOfType<M[EntityToken], never> | HashKey | RangeKey;
112
106
  /**
113
- * Returns a Config entity type.
107
+ * Configuration object for an {@link EntityManager | `EntityManager`} instance.
114
108
  *
115
- * @typeParam EntityToken - The {@link Entity | `Entity`} token.
116
- * @typeParam M - The {@link EntityMap | `EntityMap`}.
117
- * @typeParam HashKey - The property used across the configuration to store an {@link Entity | `Entity`}'s sharded hash key. Should be configured as the table hash key. Must not conflict with any {@link Entity | `Entity`} property.
118
- * @typeParam RangeKey - The property used across the configuration to store an {@link Entity | `Entity`}'s range key. Should be configured as the table range key. Must not conflict with any {@link Entity | `Entity`} property.
119
- * @typeParam T - The {@link TranscodeMap | `TranscodeMap`} identifying transcodable property types. Only {@link Entity | `Entity`} properties of these types can be components of an {@link ConfigEntity.indexes | index} or a {@link ConfigEntityGenerated | generated property}.
120
-
121
- * @remarks
122
- * `generated` is optional if `E` has no properties of type `never`.
109
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines the configuration's {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
123
110
  *
124
- * @category Config
125
- * @protected
111
+ * @category EntityManager
126
112
  */
127
- type ConfigEntity<EntityToken extends keyof Exactify<M>, M extends EntityMap, HashKey extends string, RangeKey extends string, T extends TranscodeMap> = {
128
- /**
129
- * The default maximum number of records to return from a query.
130
- *
131
- * @defaultValue `10`
132
- *
133
- * @remarks
134
- * Can be overridden at {@link QueryOptions.limit | `QueryOptions.limit`}.
135
- *
136
- * In cross-shard queries, the actual number of records returned is heavily influenced by {@link QueryOptions.pageSize | query pageSize} and the number of shards queried. Actual results may significantly exceed this limit.
137
- */
138
- defaultLimit?: number;
139
- /**
140
- * The default maximum number of records to return per data page on an individual shard query.
141
- *
142
- * @defaultValue `10`
143
- *
144
- * @remarks
145
- * Shard queries will be repeated internally until either the shard is exhausted or the number of records returned exceeds the {@link QueryOptions.limit | query limit}.
146
- *
147
- * Can be overridden at {@link QueryOptions.pageSize | `QueryOptions.pageSize`}.
148
- */
149
- defaultPageSize?: number;
150
- /**
151
- * This object assigns transcodes to {@link Entity | `Entity`} generated property & ungenerated index elements.
152
- *
153
- * These transcodes are used to encode and decode generated property values & pageKeys.
154
- *
155
- * The keys of this object must be transcodable properties of the {@link Entity | `Entity`}.
156
- *
157
- * The values of this object must be one of the keys of the {@link Config | `Config`} `T` type parameter (the config's {@link TranscodeMap | `TranscodeMap`}).
158
- *
159
- * The types of the related {@link Entity | `Entity`} and {@link TranscodeMap | `TranscodeMap`} properties should match.
160
- *
161
- * If any entity generated property element or ungenerated index element is not included here, the {@link Config | `Config`} object will fail to parse.
162
- *
163
- * @example
164
- * ```
165
- * // Default transcodable types.
166
- * interface DefaultTranscodeMap extends TranscodeMap {
167
- * string: string;
168
- * number: number;
169
- * boolean: boolean;
170
- * bigint: bigint;
171
- * }
172
- *
173
- * interface MyEntityMap extends EntityMap {
174
- * user: {
175
- * created: number;
176
- * data?: Json; // Not a Stringifiable type
177
- * userId: string;
178
- * };
179
- * }
180
- *
181
- * // T type param defaults to DefaultTranscodeMap.
182
- * const config: Config<MyEntityMap> = {
183
- * entities: {
184
- * user: {
185
- * ...,
186
- * types: { // All Stringafiable properties required!
187
- * created: 'number',
188
- * userId: 'string',
189
- * // 'data' not allowed: not a Stringifiable type
190
- * }
191
- * }
192
- * },
193
- * ...
194
- * };
195
- * ```
196
- */
197
- elementTranscodes?: ([TranscodableProperties<M[EntityToken], T>] extends [never] ? never : {
198
- [P in TranscodableProperties<M[EntityToken], T>]?: PropertiesOfType<T, M[EntityToken][P]>;
199
- }) | ([TranscodableProperties<M[EntityToken], T>] extends [never] ? Record<string, never> : never);
200
- /**
201
- * Indexes defined for the {@link Entity | `Entity`}. Should reflect the underlying database table indexes.
202
- *
203
- * Each key is the name of an index, and each value defines the hash key, range key, and projected properties of the index.
204
- *
205
- * hashKey and rangeKey types must align with the {@link Config | `Config`} `T` type parameter. Note that all {@link ConfigEntityGenerated | generated property} types are transcodable by definition.
206
- */
207
- indexes?: Record<string, {
208
- hashKey: ConfigEntityIndexComponent<EntityToken, M, HashKey, RangeKey, T>;
209
- rangeKey: ConfigEntityIndexComponent<EntityToken, M, HashKey, RangeKey, T>;
210
- projections?: (keyof M[EntityToken])[];
211
- }>;
212
- /**
213
- * An array of {@link ShardBump | `ShardBump`} objects representing the {@link Entity | `Entity`}'s sharding strategy.
214
- *
215
- * If omitted, or if configured without a zero-{@link ShardBump.timestamp | `timestamp`} {@link ShardBump | `ShardBump`}, this array will be initialized with the following {@link ShardBump | `ShardBump`} as its first member:
216
- *
217
- * ```
218
- * { timestamp: 0, charBits: 0, chars: 1 }
219
- * ```
220
- *
221
- * Members must be unique by {@link ShardBump.timestamp | `timestamp`}.
222
- *
223
- * {@link ShardBump.chars | `chars`} must increase monotonically with {@link ShardBump.timestamp | `timestamp`}
224
- *
225
- * Array will be sorted in ascending order by {@link ShardBump.timestamp | `timestamp`} on initialization.
226
- *
227
- * Future {@link ShardBump | `ShardBumps`} can be changed as required, but past {@link ShardBump | `ShardBumps`} should not be modified or data integrity will be compromised!
228
- */
229
- shardBumps?: ShardBump[];
230
- /**
231
- * Identifies the {@link Entity | `Entity`} property used as the timestamp for shard key calculations.
232
- *
233
- * This property must be of type `number`. Its value should not change over the life of the record. A `created` timestamp is ideal.
234
- *
235
- * Once in production, this configuration property should not be changed or data integrity will be compromised!
236
- */
237
- timestampProperty: PropertiesOfType<M[EntityToken], number>;
238
- /**
239
- * Identifies the {@link Entity | `Entity`} used as the basis for both shard key calculations and the table's {@link ConfigKeys.rangeKey | range key}.
240
- *
241
- * This property must be of type `string` or `number`. Its value should be a unique record identifier and should not change over the life of the record.
242
- *
243
- * Once in production, this configuration property should not be changed or data integrity will be compromised!
244
- */
245
- uniqueProperty: PropertiesOfType<M[EntityToken], number | string>;
246
- } & ([PropertiesOfType<M[EntityToken], never>] extends [never] ? {
247
- generated?: ConfigEntityGenerated<EntityToken, M, T>;
248
- } : {
249
- /**
250
- * {@link Entity | `Entity`} properties whose values will be generated by EntityManager.
251
- *
252
- * These properties should be indicated by a `never` type in the {@link Config | `Config`} `EntityMap` type parameter.
253
- *
254
- * All such properties must be accounted for in the `generated` object, and no additional properties are permitted..
255
- */
256
- generated: ConfigEntityGenerated<EntityToken, M, T>;
257
- });
258
- /**
259
- * Returns the `entities` property of the {@link Config | `Config`} tyoe.
260
- *
261
- * @typeParam M - The {@link EntityMap | `EntityMap`} type that identitfies the {@link Entity | `Entity`} & related property types to be managed by EntityManager.
262
- * @typeParam HashKey - The property used across the configuration to store an {@link Entity | `Entity`}'s sharded hash key. Should be configured as the table hash key. Must not conflict with any {@link Entity | `Entity`} property.
263
- * @typeParam RangeKey - The property used across the configuration to store an {@link Entity | `Entity`}'s range key. Should be configured as the table range key. Must not conflict with any {@link Entity | `Entity`} property.
264
- * @typeParam T - The {@link TranscodeMap | `TranscodeMap`} identifying transcodable property types. Only {@link Entity | `Entity`} properties of these types can be components of an {@link ConfigEntity.indexes | index} or a {@link ConfigEntityGenerated | generated property}.
265
- *
266
- * @remarks
267
- * All properties of `M` must be represented, and no extra properties are allowed.
268
- *
269
- * @category Config
270
- * @protected
271
- */
272
- type ConfigEntities<M extends EntityMap, HashKey extends string, RangeKey extends string, T extends TranscodeMap> = ([keyof Exactify<M>] extends [never] ? never : {
273
- [E in keyof Exactify<M>]: ConfigEntity<E, M, HashKey, RangeKey, T>;
274
- }) | Record<string, never>;
275
- /**
276
- * Returns variably-optional properties of the {@link Config | `Config`} type as optional.
277
-
278
- * @typeParam M - The {@link EntityMap | `EntityMap`} type that identitfies the {@link Entity | `Entity`} & related property types to be managed by EntityManager.
279
- * @typeParam HashKey - The property used across the configuration to store an {@link Entity | `Entity`}'s sharded hash key. Should be configured as the table hash key. Must not conflict with any {@link Entity | `Entity`} property.
280
- * @typeParam RangeKey - The property used across the configuration to store an {@link Entity | `Entity`}'s range key. Should be configured as the table range key. Must not conflict with any {@link Entity | `Entity`} property.
281
- * @typeParam T - The {@link TranscodeMap | `TranscodeMap`} identifying transcodable property types. Only {@link Entity | `Entity`} properties of these types can be components of an {@link ConfigEntity.indexes | index} or a {@link ConfigEntityGenerated | generated property}.
282
- *
283
- * @category Config
284
- * @protected
285
- */
286
- interface ConfigKeys<M extends EntityMap, HashKey extends string, RangeKey extends string, T extends TranscodeMap> {
287
- /**
288
- * Defines options for each {@link Entity | `Entity`} in the {@link Config | `Config`} `EntityMap` type parameter.
289
- *
290
- * The properties of this object must exactly match the keys of the {@link Config | `Config`} `EntityMap` type parameter.
291
- */
292
- entities?: ConfigEntities<M, HashKey, RangeKey, T>;
293
- /**
294
- * The property used across the configuration to store an {@link Entity | `Entity`}'s sharded hash key. Should be configured as the table hash key.
295
- *
296
- * This value must exactly match the {@link Config | `Config`} `HashKey` type parameter, and must not conflict with any {@link Entity | `Entity`} property.
297
- *
298
- * @defaultValue `'hashKey'`
299
- *
300
- * @category Config
301
- * @protected
302
- */
303
- hashKey?: ExclusiveKey<HashKey, M, RangeKey>;
304
- /**
305
- * The property used across the configuration to store an {@link Entity | `Entity`}'s range key. Should be configured as the table range key.
306
- *
307
- * This value must exactly match the {@link Config | `Config`} `RangeKey` type parameter, and must not conflict with any {@link Entity | `Entity`} property.
308
- *
309
- * @defaultValue `'rangeKey'`
310
- */
311
- rangeKey?: ExclusiveKey<RangeKey, M, HashKey>;
312
- }
313
- /**
314
- * @category Config
315
- * @protected
316
- */
317
- type ConfigTranscodes<T extends TranscodeMap> = ([keyof Exactify<T>] extends [never] ? never : Transcodes<T>) | ([keyof Exactify<T>] extends [never] ? Record<string, never> : never);
318
- /**
319
- * EntityManager Config type.
320
- *
321
- * @typeParam M - The {@link EntityMap | `EntityMap`} type that identitfies the {@link Entity | `Entity`} & related property types to be managed by EntityManager.
322
- * @typeParam HashKey - The property used across the configuration to store an {@link Entity | `Entity`}'s sharded hash key. Should be configured as the table hash key. Must not conflict with any {@link Entity | `Entity`} property. Defaults to `'hashKey'`.
323
- * @typeParam RangeKey - The property used across the configuration to store an {@link Entity | `Entity`}'s range key. Should be configured as the table range key. Must not conflict with any {@link Entity | `Entity`} property. Defaults to `'rangeKey'`.
324
- * @typeParam T - The {@link TranscodeMap | `TranscodeMap`} identifying transcodable property types. Only {@link Entity | `Entity`} properties of these types can be components of an {@link ConfigEntity.indexes | index} or a {@link ConfigEntityGenerated | generated property}. Defaults to {@link DefaultTranscodeMap | `DefaultTranscodeMap`}.
325
- *
326
- * @remarks
327
- * `entities` is optional if `M` is empty.
328
- *
329
- * @category Config
330
- */
331
- type Config<M extends EntityMap = Record<string, never>, HashKey extends string = 'hashKey', RangeKey extends string = 'rangeKey', T extends TranscodeMap = DefaultTranscodeMap> = ([keyof Exactify<M>] extends [never] ? ConfigKeys<M, HashKey, RangeKey, T> : Required<ConfigKeys<M, HashKey, RangeKey, T>>) & {
332
- /**
333
- * Defines the delimiter used to separate key-value pairs in a generated property value.
334
- *
335
- * Must consist of one or more non-word characters, and must not intersect with {@link Config.generatedValueDelimiter | `generatedValueDelimiter`} or {@link Config.shardKeyDelimiter | `shardKeyDelimiter`}.
336
- *
337
- * @defaultValue `'|'`
338
- */
113
+ type Config<C extends BaseConfigMap = BaseConfigMap> = ConditionalProperty<'entities', keyof Exactify<C['EntityMap']>, {
114
+ [E in keyof Exactify<C['EntityMap']>]: {
115
+ defaultLimit?: number;
116
+ defaultPageSize?: number;
117
+ shardBumps?: ShardBump[];
118
+ timestampProperty: C['TranscodedProperties'] & PropertiesOfType<C['EntityMap'][E], number> & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>;
119
+ uniqueProperty: C['TranscodedProperties'] & keyof C['EntityMap'][E] & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>;
120
+ };
121
+ }> & ConditionalProperty<'generatedProperties', C['ShardedKeys'] | C['UnshardedKeys'], ConditionalProperty<'sharded', C['ShardedKeys'], Record<C['ShardedKeys'], (C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>)[]>> & ConditionalProperty<'unsharded', C['UnshardedKeys'], Record<C['UnshardedKeys'], (C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>)[]>>> & ConditionalProperty<'propertyTranscodes', C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>, {
122
+ [P in C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>]: PropertiesOfType<C['TranscodeMap'], FlattenEntityMap<C['EntityMap']>[P]>;
123
+ }> & ConditionalProperty<'transcodes', keyof C['TranscodeMap'], Transcodes<C['TranscodeMap']>> & {
339
124
  generatedKeyDelimiter?: string;
340
- /**
341
- * Defines the delimiter used to separate keys & values in a generated property value.
342
- *
343
- * Must consist of one or more non-word characters, and must not intersect with {@link Config.generatedKeyDelimiter | `generatedKeyDelimiter`} or {@link Config.shardKeyDelimiter | `shardKeyDelimiter`}.
344
- *
345
- * @defaultValue `'#'`
346
- */
347
125
  generatedValueDelimiter?: string;
348
- /**
349
- * Defines the delimiter used to construct an Entity's hashKey value from its Entity key and shard key.
350
- *
351
- * Must consist of one or more non-word characters, and must not intersect with {@link Config.generatedKeyDelimiter | `generatedKeyDelimiter`} or {@link Config.generatedValueDelimiter | `generatedValueDelimiter`}.
352
- *
353
- * @defaultValue `'!'`
354
- */
126
+ hashKey: C['HashKey'];
127
+ indexes?: Record<string, {
128
+ hashKey: C['HashKey'] | C['ShardedKeys'];
129
+ rangeKey: C['RangeKey'] | C['UnshardedKeys'] | (C['TranscodedProperties'] & TranscodableProperties<C['EntityMap'], C['TranscodeMap']>);
130
+ projections?: string[];
131
+ }>;
132
+ rangeKey: C['RangeKey'];
355
133
  shardKeyDelimiter?: string;
356
- /**
357
- * The default maximum number of shards to query in parallel. Can be overridden at {@link QueryOptions.throttle | `QueryOptions.throttle`}.
358
- *
359
- * @defaultValue `10`
360
- */
361
134
  throttle?: number;
362
- } & ([keyof Exactify<T>] extends [never] ? {
363
- transcodes?: ConfigTranscodes<T>;
364
- } : DefaultTranscodeMap extends T ? {
365
- transcodes?: ConfigTranscodes<T>;
366
- } : {
367
- transcodes: ConfigTranscodes<T>;
368
- });
369
- /**
370
- * Flattens the top layer of logic in a type.
371
- *
372
- * @category Utility
373
- * @protected
374
- */
375
- type Unwrap<T> = {
376
- [P in keyof T]: T[P];
377
135
  };
136
+
378
137
  /**
379
- * Extracts a map of {@link Entity | `Entity`} item types decorated with {@link ConfigKeys.hashKey | hashKey}, {@link ConfigKeys.rangeKey | rangeKey}, and {@link ConfigEntityGenerated | generated properties}.
138
+ * Extracts entity tokens from a {@link ConfigMap | `ConfigMap`}.
380
139
  *
381
- * @typeParam M - The {@link EntityMap | `EntityMap`} type that identitfies the {@link Entity | `Entity`} & related property types to be managed by EntityManager.
382
- * @typeParam HashKey - The property used across the configuration to store an {@link Entity | `Entity`}'s sharded hash key. Should be configured as the table hash key. Must not conflict with any {@link Entity | `Entity`} property. Defaults to `'hashKey'`.
383
- * @typeParam RangeKey - The property used across the configuration to store an {@link Entity | `Entity`}'s range key. Should be configured as the table range key. Must not conflict with any {@link Entity | `Entity`} property. Defaults to `'rangeKey'`.
140
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
384
141
  *
385
- * @category Entities
142
+ * @category EntityManager
143
+ * @protected
386
144
  */
387
- type ItemMap<M extends EntityMap, HashKey extends string = 'hashKey', RangeKey extends string = 'rangeKey'> = {
388
- [EntityToken in keyof Exactify<M>]: Unwrap<{
389
- [P in keyof Exactify<M[EntityToken]>]: [
390
- NonNullable<M[EntityToken][P]>
391
- ] extends [never] ? string : M[EntityToken][P];
392
- } & Partial<Record<HashKey | RangeKey, string>>>;
393
- };
394
-
395
- /**
396
- * A result returned by a query across multiple shards, where each shard may
397
- * receive multiple page queries via a dynamically-generated {@link ShardQueryFunction | `ShardQueryFunction`}.
398
- *
399
- * @category Query
400
- */
401
- interface QueryResult<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string, M extends EntityMap, HashKey extends string, RangeKey extends string> {
402
- /** Total number of records returned across all shards. */
403
- count: number;
404
- /** The returned records. */
405
- items: Item[];
406
- /**
407
- * A compressed, two-layer map of page keys, used to query the next page of
408
- * data for a given sort key on each shard of a given hash key.
409
- */
410
- pageKeyMap: string;
411
- }
145
+ type EntityToken<C extends BaseConfigMap> = keyof Exactify<C['EntityMap']> & string;
412
146
 
413
147
  declare const configSchema: z.ZodEffects<z.ZodObject<{
414
- entities: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodObject<{
148
+ entities: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
415
149
  defaultLimit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
416
150
  defaultPageSize: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
417
- generated: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodOptional<z.ZodObject<{
418
- atomic: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
419
- elements: z.ZodEffects<z.ZodArray<z.ZodString, "atleastone">, [string, ...string[]], [string, ...string[]]>;
420
- sharded: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
421
- }, "strip", z.ZodTypeAny, {
422
- atomic: boolean;
423
- elements: [string, ...string[]];
424
- sharded: boolean;
425
- }, {
426
- elements: [string, ...string[]];
427
- atomic?: boolean | undefined;
428
- sharded?: boolean | undefined;
429
- }>>>>>;
430
- elementTranscodes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
431
- indexes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
432
- hashKey: z.ZodString;
433
- rangeKey: z.ZodString;
434
- projections: z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodString, "atleastone">, [string, ...string[]], [string, ...string[]]>>;
435
- }, "strip", z.ZodTypeAny, {
436
- hashKey: string;
437
- rangeKey: string;
438
- projections?: [string, ...string[]] | undefined;
439
- }, {
440
- hashKey: string;
441
- rangeKey: string;
442
- projections?: [string, ...string[]] | undefined;
443
- }>>>>;
444
151
  shardBumps: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
445
152
  timestamp: z.ZodNumber;
446
153
  charBits: z.ZodNumber;
@@ -483,12 +190,6 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
483
190
  }, "strict", z.ZodTypeAny, {
484
191
  defaultLimit: number;
485
192
  defaultPageSize: number;
486
- elementTranscodes: Record<string, string>;
487
- indexes: Record<string, {
488
- hashKey: string;
489
- rangeKey: string;
490
- projections?: [string, ...string[]] | undefined;
491
- }>;
492
193
  shardBumps: {
493
194
  timestamp: number;
494
195
  charBits: number;
@@ -496,80 +197,46 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
496
197
  }[];
497
198
  timestampProperty: string;
498
199
  uniqueProperty: string;
499
- generated: Record<string, {
500
- atomic: boolean;
501
- elements: [string, ...string[]];
502
- sharded: boolean;
503
- } | undefined>;
504
200
  }, {
505
201
  timestampProperty: string;
506
202
  uniqueProperty: string;
507
203
  defaultLimit?: number | undefined;
508
204
  defaultPageSize?: number | undefined;
509
- elementTranscodes?: Record<string, string> | undefined;
510
- indexes?: Record<string, {
511
- hashKey: string;
512
- rangeKey: string;
513
- projections?: [string, ...string[]] | undefined;
514
- }> | undefined;
515
205
  shardBumps?: {
516
206
  timestamp: number;
517
207
  charBits: number;
518
208
  chars: number;
519
209
  }[] | undefined;
520
- generated?: Record<string, {
521
- elements: [string, ...string[]];
522
- atomic?: boolean | undefined;
523
- sharded?: boolean | undefined;
524
- } | undefined> | undefined;
525
- }>, {
526
- defaultLimit: number;
527
- defaultPageSize: number;
528
- elementTranscodes: Record<string, string>;
529
- indexes: Record<string, {
530
- hashKey: string;
531
- rangeKey: string;
532
- projections?: [string, ...string[]] | undefined;
533
- }>;
534
- shardBumps: {
535
- timestamp: number;
536
- charBits: number;
537
- chars: number;
538
- }[];
539
- timestampProperty: string;
540
- uniqueProperty: string;
541
- generated: Record<string, {
542
- atomic: boolean;
543
- elements: [string, ...string[]];
544
- sharded: boolean;
545
- } | undefined>;
210
+ }>>>>;
211
+ generatedProperties: z.ZodDefault<z.ZodOptional<z.ZodObject<{
212
+ sharded: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodArray<z.ZodString, "atleastone">, [string, ...string[]], [string, ...string[]]>>>>;
213
+ unsharded: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodArray<z.ZodString, "atleastone">, [string, ...string[]], [string, ...string[]]>>>>;
214
+ }, "strip", z.ZodTypeAny, {
215
+ sharded: Record<string, [string, ...string[]]>;
216
+ unsharded: Record<string, [string, ...string[]]>;
546
217
  }, {
547
- timestampProperty: string;
548
- uniqueProperty: string;
549
- defaultLimit?: number | undefined;
550
- defaultPageSize?: number | undefined;
551
- elementTranscodes?: Record<string, string> | undefined;
552
- indexes?: Record<string, {
553
- hashKey: string;
554
- rangeKey: string;
555
- projections?: [string, ...string[]] | undefined;
556
- }> | undefined;
557
- shardBumps?: {
558
- timestamp: number;
559
- charBits: number;
560
- chars: number;
561
- }[] | undefined;
562
- generated?: Record<string, {
563
- elements: [string, ...string[]];
564
- atomic?: boolean | undefined;
565
- sharded?: boolean | undefined;
566
- } | undefined> | undefined;
218
+ sharded?: Record<string, [string, ...string[]]> | undefined;
219
+ unsharded?: Record<string, [string, ...string[]]> | undefined;
220
+ }>>>;
221
+ hashKey: z.ZodString;
222
+ indexes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
223
+ hashKey: z.ZodString;
224
+ rangeKey: z.ZodString;
225
+ projections: z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodString, "atleastone">, [string, ...string[]], [string, ...string[]]>>;
226
+ }, "strip", z.ZodTypeAny, {
227
+ hashKey: string;
228
+ rangeKey: string;
229
+ projections?: [string, ...string[]] | undefined;
230
+ }, {
231
+ hashKey: string;
232
+ rangeKey: string;
233
+ projections?: [string, ...string[]] | undefined;
567
234
  }>>>>;
568
235
  generatedKeyDelimiter: z.ZodDefault<z.ZodOptional<z.ZodString>>;
569
236
  generatedValueDelimiter: z.ZodDefault<z.ZodOptional<z.ZodString>>;
237
+ propertyTranscodes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
238
+ rangeKey: z.ZodString;
570
239
  shardKeyDelimiter: z.ZodDefault<z.ZodOptional<z.ZodString>>;
571
- hashKey: z.ZodDefault<z.ZodOptional<z.ZodString>>;
572
- rangeKey: z.ZodDefault<z.ZodOptional<z.ZodString>>;
573
240
  throttle: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
574
241
  transcodes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
575
242
  encode: z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodString>;
@@ -582,18 +249,12 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
582
249
  decode: (args_0: string, ...args: unknown[]) => any;
583
250
  }>>>>;
584
251
  }, "strict", z.ZodTypeAny, {
585
- throttle: number;
586
252
  hashKey: string;
587
253
  rangeKey: string;
254
+ throttle: number;
588
255
  entities: Record<string, {
589
256
  defaultLimit: number;
590
257
  defaultPageSize: number;
591
- elementTranscodes: Record<string, string>;
592
- indexes: Record<string, {
593
- hashKey: string;
594
- rangeKey: string;
595
- projections?: [string, ...string[]] | undefined;
596
- }>;
597
258
  shardBumps: {
598
259
  timestamp: number;
599
260
  charBits: number;
@@ -601,65 +262,63 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
601
262
  }[];
602
263
  timestampProperty: string;
603
264
  uniqueProperty: string;
604
- generated: Record<string, {
605
- atomic: boolean;
606
- elements: [string, ...string[]];
607
- sharded: boolean;
608
- } | undefined>;
265
+ }>;
266
+ generatedProperties: {
267
+ sharded: Record<string, [string, ...string[]]>;
268
+ unsharded: Record<string, [string, ...string[]]>;
269
+ };
270
+ indexes: Record<string, {
271
+ hashKey: string;
272
+ rangeKey: string;
273
+ projections?: [string, ...string[]] | undefined;
609
274
  }>;
610
275
  generatedKeyDelimiter: string;
611
276
  generatedValueDelimiter: string;
277
+ propertyTranscodes: Record<string, string>;
612
278
  shardKeyDelimiter: string;
613
279
  transcodes: Record<string, {
614
280
  encode: (args_0: any, ...args: unknown[]) => string;
615
281
  decode: (args_0: string, ...args: unknown[]) => any;
616
282
  }>;
617
283
  }, {
284
+ hashKey: string;
285
+ rangeKey: string;
618
286
  throttle?: number | undefined;
619
- hashKey?: string | undefined;
620
- rangeKey?: string | undefined;
621
287
  entities?: Record<string, {
622
288
  timestampProperty: string;
623
289
  uniqueProperty: string;
624
290
  defaultLimit?: number | undefined;
625
291
  defaultPageSize?: number | undefined;
626
- elementTranscodes?: Record<string, string> | undefined;
627
- indexes?: Record<string, {
628
- hashKey: string;
629
- rangeKey: string;
630
- projections?: [string, ...string[]] | undefined;
631
- }> | undefined;
632
292
  shardBumps?: {
633
293
  timestamp: number;
634
294
  charBits: number;
635
295
  chars: number;
636
296
  }[] | undefined;
637
- generated?: Record<string, {
638
- elements: [string, ...string[]];
639
- atomic?: boolean | undefined;
640
- sharded?: boolean | undefined;
641
- } | undefined> | undefined;
297
+ }> | undefined;
298
+ generatedProperties?: {
299
+ sharded?: Record<string, [string, ...string[]]> | undefined;
300
+ unsharded?: Record<string, [string, ...string[]]> | undefined;
301
+ } | undefined;
302
+ indexes?: Record<string, {
303
+ hashKey: string;
304
+ rangeKey: string;
305
+ projections?: [string, ...string[]] | undefined;
642
306
  }> | undefined;
643
307
  generatedKeyDelimiter?: string | undefined;
644
308
  generatedValueDelimiter?: string | undefined;
309
+ propertyTranscodes?: Record<string, string> | undefined;
645
310
  shardKeyDelimiter?: string | undefined;
646
311
  transcodes?: Record<string, {
647
312
  encode: (args_0: any, ...args: unknown[]) => string;
648
313
  decode: (args_0: string, ...args: unknown[]) => any;
649
314
  }> | undefined;
650
315
  }>, {
651
- throttle: number;
652
316
  hashKey: string;
653
317
  rangeKey: string;
318
+ throttle: number;
654
319
  entities: Record<string, {
655
320
  defaultLimit: number;
656
321
  defaultPageSize: number;
657
- elementTranscodes: Record<string, string>;
658
- indexes: Record<string, {
659
- hashKey: string;
660
- rangeKey: string;
661
- projections?: [string, ...string[]] | undefined;
662
- }>;
663
322
  shardBumps: {
664
323
  timestamp: number;
665
324
  charBits: number;
@@ -667,47 +326,51 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
667
326
  }[];
668
327
  timestampProperty: string;
669
328
  uniqueProperty: string;
670
- generated: Record<string, {
671
- atomic: boolean;
672
- elements: [string, ...string[]];
673
- sharded: boolean;
674
- } | undefined>;
329
+ }>;
330
+ generatedProperties: {
331
+ sharded: Record<string, [string, ...string[]]>;
332
+ unsharded: Record<string, [string, ...string[]]>;
333
+ };
334
+ indexes: Record<string, {
335
+ hashKey: string;
336
+ rangeKey: string;
337
+ projections?: [string, ...string[]] | undefined;
675
338
  }>;
676
339
  generatedKeyDelimiter: string;
677
340
  generatedValueDelimiter: string;
341
+ propertyTranscodes: Record<string, string>;
678
342
  shardKeyDelimiter: string;
679
343
  transcodes: Record<string, {
680
344
  encode: (args_0: any, ...args: unknown[]) => string;
681
345
  decode: (args_0: string, ...args: unknown[]) => any;
682
346
  }>;
683
347
  }, {
348
+ hashKey: string;
349
+ rangeKey: string;
684
350
  throttle?: number | undefined;
685
- hashKey?: string | undefined;
686
- rangeKey?: string | undefined;
687
351
  entities?: Record<string, {
688
352
  timestampProperty: string;
689
353
  uniqueProperty: string;
690
354
  defaultLimit?: number | undefined;
691
355
  defaultPageSize?: number | undefined;
692
- elementTranscodes?: Record<string, string> | undefined;
693
- indexes?: Record<string, {
694
- hashKey: string;
695
- rangeKey: string;
696
- projections?: [string, ...string[]] | undefined;
697
- }> | undefined;
698
356
  shardBumps?: {
699
357
  timestamp: number;
700
358
  charBits: number;
701
359
  chars: number;
702
360
  }[] | undefined;
703
- generated?: Record<string, {
704
- elements: [string, ...string[]];
705
- atomic?: boolean | undefined;
706
- sharded?: boolean | undefined;
707
- } | undefined> | undefined;
361
+ }> | undefined;
362
+ generatedProperties?: {
363
+ sharded?: Record<string, [string, ...string[]]> | undefined;
364
+ unsharded?: Record<string, [string, ...string[]]> | undefined;
365
+ } | undefined;
366
+ indexes?: Record<string, {
367
+ hashKey: string;
368
+ rangeKey: string;
369
+ projections?: [string, ...string[]] | undefined;
708
370
  }> | undefined;
709
371
  generatedKeyDelimiter?: string | undefined;
710
372
  generatedValueDelimiter?: string | undefined;
373
+ propertyTranscodes?: Record<string, string> | undefined;
711
374
  shardKeyDelimiter?: string | undefined;
712
375
  transcodes?: Record<string, {
713
376
  encode: (args_0: any, ...args: unknown[]) => string;
@@ -717,57 +380,68 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
717
380
  /**
718
381
  * Simplified type taken on by a {@link Config | `Config`} object after parsing in the {@link EntityManager | `EntityManager`} constructor.
719
382
  *
720
- * @category Config
383
+ * @category EntityManager
721
384
  */
722
385
  type ParsedConfig = z.infer<typeof configSchema>;
723
386
 
724
387
  /**
725
388
  * A result returned by a {@link ShardQueryFunction | `ShardQueryFunction`} querying an individual shard.
726
389
  *
727
- * @typeParam Item - The {@link Item | `Item`} type being queried.
728
-
729
- * @category Query
390
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
391
+ *
392
+ * @category EntityManager
393
+ * @protected
730
394
  */
731
- interface ShardQueryResult<Item extends Entity> {
395
+ interface ShardQueryResult<C extends BaseConfigMap> {
732
396
  /** The number of records returned. */
733
397
  count: number;
734
398
  /** The returned records. */
735
- items: Item[];
399
+ items: EntityItem<C>[];
736
400
  /** The page key for the next query on this shard. */
737
- pageKey?: Partial<Item>;
401
+ pageKey?: EntityItem<C>;
738
402
  }
739
403
 
740
404
  /**
741
- * A query function that returns a single page of results from an individual
742
- * shard. This function will typically be composed dynamically to express a
743
- * specific query index & logic. The arguments to this function will be
744
- * provided by the {@link EntityManager.query | `EntityManager.query`} method, which assembles many returned
745
- * pages queried across multiple shards into a single query result.
405
+ * A query function that returns a single page of results from an individual shard.
406
+ *
407
+ * This function will typically be composed dynamically to express a specific query index & logic. The arguments to this function will be provided by the {@link EntityManager.query | `EntityManager.query`} method, which assembles many returned pages queried across multiple shards into a single query result.
746
408
  *
747
- * @typeParam Item - The {@link Item | `Item`} type being queried.
748
-
749
409
  * @param hashKey - The hash key value of the shard being queried.
750
410
  * @param pageKey - The page key returned by the previous query on this shard.
751
411
  * @param pageSize - The maximum number of items to return from this query.
752
412
  *
753
- * @category Query
413
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
414
+ *
415
+ * @category EntityManager
416
+ * @protected
754
417
  */
755
- type ShardQueryFunction<Item extends Entity> = (hashKey: string, pageKey?: Partial<Item>, pageSize?: number) => Promise<ShardQueryResult<Item>>;
418
+ type ShardQueryFunction<C extends BaseConfigMap> = (hashKey: string, pageKey?: EntityItem<C>, pageSize?: number) => Promise<ShardQueryResult<C>>;
756
419
 
757
- type ShardQueryMap<Item extends Entity> = Record<string, ShardQueryFunction<Item>>;
420
+ /**
421
+ * Relates a specific index token to a {@link ShardQueryFunction | `ShardQueryFunction`} to be performed on that index.
422
+ *
423
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
424
+ *
425
+ * @category EntityManager
426
+ * @protected
427
+ */
428
+ type ShardQueryMap<C extends BaseConfigMap> = Record<string, ShardQueryFunction<C>>;
758
429
 
759
430
  /**
760
- * Options passed to the {@link query | `query`} function.
431
+ * Options passed to the {@link EntityManager.query | `EntityManager.query`} method.
432
+ *
433
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
761
434
  *
762
- * @category Query
435
+ * @category EntityManager
436
+ * @protected
763
437
  */
764
- interface QueryOptions<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string, M extends EntityMap, HashKey extends string, RangeKey extends string> {
765
- /** Identifies the entity to be queried. Key of {@link Config | `EntityManager.config.entities`}. */
766
- entityToken: EntityToken;
438
+ interface QueryOptions<C extends BaseConfigMap> {
439
+ /** Identifies the entity to be queried. Key of {@link Config | `Config`} `entities`. */
440
+ entityToken: EntityToken<C>;
767
441
  /**
768
442
  * Partial item object sufficiently populated to generate index hash keys.
769
443
  */
770
- item: Partial<Item>;
444
+ item: EntityItem<C>;
771
445
  /**
772
446
  * The target maximum number of records to be returned by the query across
773
447
  * all shards.
@@ -799,11 +473,11 @@ interface QueryOptions<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken],
799
473
  * page key, e.g. to match the same string against `firstName` and `lastName`
800
474
  * properties without performing a table scan for either.
801
475
  */
802
- shardQueryMap: ShardQueryMap<Item>;
476
+ shardQueryMap: ShardQueryMap<C>;
803
477
  /**
804
478
  * A {@link SortOrder | `SortOrder`} object specifying the sort order of the result set. Defaults to `[]`.
805
479
  */
806
- sortOrder?: SortOrder<Item>;
480
+ sortOrder?: SortOrder<EntityItem<C>>;
807
481
  /**
808
482
  * Lower limit to query shard space.
809
483
  *
@@ -836,18 +510,23 @@ interface QueryOptions<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken],
836
510
  * The EntityManager class applies a configuration-driven sharded data model &
837
511
  * query strategy to NoSql data.
838
512
  *
839
- * @category Entity Manager
513
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines the configuration's {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
514
+ *
515
+ * @remarks
516
+ * While the {@link EntityManager.query | `query`} method is `public`, normally it should not be called directly. The `query` method is used by a platform-specific {@link BaseQueryBuilder.query | `QueryBuilder.query`} method to provide a fluent query API.
517
+ *
518
+ * @category EntityManager
840
519
  */
841
- declare class EntityManager<M extends EntityMap, HashKey extends string, RangeKey extends string, T extends TranscodeMap> {
520
+ declare class EntityManager<C extends BaseConfigMap = BaseConfigMap> {
842
521
  #private;
843
- logger: Pick<Console, 'debug' | 'error'>;
522
+ readonly logger: Pick<Console, 'debug' | 'error'>;
844
523
  /**
845
524
  * Create an EntityManager instance.
846
525
  *
847
526
  * @param config - EntityManager {@link Config | `Config`} object.
848
527
  * @param logger - Logger object (defaults to `console`, must support `debug` & `error` methods).
849
528
  */
850
- constructor(config: Config<M, HashKey, RangeKey, T>, logger?: Pick<Console, 'debug' | 'error'>);
529
+ constructor(config: Config<C>, logger?: Pick<Console, 'debug' | 'error'>);
851
530
  /**
852
531
  * Get the current EntityManager {@link Config | `Config`} object.
853
532
  *
@@ -861,83 +540,103 @@ declare class EntityManager<M extends EntityMap, HashKey extends string, RangeKe
861
540
  */
862
541
  set config(value: ParsedConfig);
863
542
  /**
864
- * Update generated properties, hash key, and range key on an {@link ItemMap | `ItemMap`} object.
543
+ * Update generated properties, hash key, and range key on an {@link EntityItem | `EntityItem`} object.
865
544
  *
866
- * @param entityToken - {@link ConfigKeys.entities | `this.config.entities`} key.
867
- * @param item - {@link ItemMap | `ItemMap`} object.
545
+ * @param entityToken - {@link Config | `Config`} `entities` key.
546
+ * @param item - {@link EntityItem | `EntityItem`} object.
868
547
  * @param overwrite - Overwrite existing properties (default `false`).
869
548
  *
870
549
  * @returns Shallow clone of `item` with updated properties.
871
550
  *
872
551
  * @throws `Error` if `entityToken` is invalid.
873
552
  */
874
- addKeys<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string>(entityToken: EntityToken, item: Partial<Item>, overwrite?: boolean): Partial<Item>;
553
+ addKeys(entityToken: EntityToken<C>, item: EntityItem<C>, overwrite?: boolean): EntityItem<C>;
875
554
  /**
876
- * Strips generated properties, hash key, and range key from an {@link ItemMap | `ItemMap`} object.
555
+ * Strips generated properties, hash key, and range key from an {@link EntityItem | `EntityItem`} object.
877
556
  *
878
- * @param entityToken - {@link ConfigKeys.entities | `this.config.entities`} key.
879
- * @param item - {@link ItemMap | `ItemMap`} object.
557
+ * @param entityToken - {@link Config | `Config`} `entities` key.
558
+ * @param item - {@link EntityItem | `EntityItem`} object.
880
559
  *
881
560
  * @returns Shallow clone of `item` without generated properties, hash key or range key.
882
561
  *
883
562
  * @throws `Error` if `entityToken` is invalid.
884
563
  */
885
- removeKeys<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string>(entityToken: EntityToken, item: Partial<Item>): Partial<Item>;
564
+ removeKeys(entityToken: EntityToken<C>, item: EntityItem<C>): EntityItem<C>;
886
565
  /**
887
566
  * Query a database entity across shards in a provider-generic fashion.
888
567
  *
889
568
  * @remarks
890
569
  * The provided `shardQueryMap` performs the actual query of individual data pages on individual index/shard combinations.
891
570
  *
892
- * Individual shard query results will be combined, deduped by {@link ConfigEntity.uniqueProperty} property value, and sorted by {@link QueryOptions.sortOrder | `sortOrder`}.
571
+ * Individual shard query results will be combined, deduped by {@link Config | `Config`} `uniqueProperty` value, and sorted by {@link QueryOptions.sortOrder | `sortOrder`}.
893
572
  *
894
573
  * In queries on sharded data, expect the leading and trailing edges of returned data pages to interleave somewhat with preceding & following pages.
895
574
  *
896
575
  * Unsharded query results should sort & page as expected.
897
576
  *
577
+ * **Normally this method should not be called directly!** It is used by a platform-specific {@link BaseQueryBuilder.query | `QueryBuilder.query`} method to provide a fluent query API.
578
+ *
898
579
  * @param options - {@link QueryOptions | `QueryOptions`} object.
899
580
  *
900
581
  * @returns {@link QueryResult} object.
901
582
  *
902
- * @throws Error if {@link QueryOptions.shardQueryMapBuilder | `shardQueryMapBuilder`} `pageKeyMap` keys do not match its `shardQueryMap` keys.
583
+ * @throws Error if `options` {@link QueryOptions.pageKeyMap | `pageKeyMap`} `pageKeyMap` keys do not match {@link QueryOptions.shardQueryMap | `shardQueryMap`} keys.
584
+ *
585
+ * @protected
903
586
  */
904
- query<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string>(options: QueryOptions<Item, EntityToken, M, HashKey, RangeKey>): Promise<QueryResult<Item, EntityToken, M, HashKey, RangeKey>>;
587
+ query(options: QueryOptions<C>): Promise<QueryResult<C>>;
905
588
  }
906
589
 
907
590
  /**
908
591
  * Constructor options for {@link BaseQueryBuilder | `BaseQueryBuilder`}.
909
592
  *
910
- * @category ShardQueryMapBuilder
593
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
594
+ * @typeParam EntityClient - {@link BaseEntityClient | `BaseEntityClient`} derived class instance.
595
+ *
596
+ * @category QueryBuilder
911
597
  */
912
- interface BaseQueryBuilderOptions<EntityClient extends BaseEntityClient, EntityToken extends keyof Exactify<M> & string, M extends EntityMap, HashKey extends string, RangeKey extends string, T extends TranscodeMap> {
598
+ interface BaseQueryBuilderOptions<C extends BaseConfigMap, EntityClient extends BaseEntityClient> {
913
599
  /** {@link BaseEntityClient | `EntityClient`} instance. */
914
600
  entityClient: EntityClient;
915
601
  /** {@link EntityManager | `EntityManager`} instance. */
916
- entityManager: EntityManager<M, HashKey, RangeKey, T>;
602
+ entityManager: EntityManager<C>;
917
603
  /** Entity token. */
918
- entityToken: EntityToken;
604
+ entityToken: EntityToken<C>;
919
605
  /** Hash key token. */
920
- hashKeyToken: PropertiesOfType<M[EntityToken], never> | HashKey;
606
+ hashKeyToken: C['HashKey'] | C['ShardedKeys'];
921
607
  /** Dehydrated page key map. */
922
608
  pageKeyMap?: string;
923
609
  }
924
610
 
925
- type QueryBuilderQueryOptions<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string, M extends EntityMap, HashKey extends string, RangeKey extends string> = Omit<QueryOptions<Item, EntityToken, M, HashKey, RangeKey>, 'entityToken' | 'pageKeyMap' | 'shardQueryMap'>;
611
+ /**
612
+ * Options for {@link BaseQueryBuilder.query | `query`} method on all derived classes.
613
+ *
614
+ * Same as {@link QueryOptions | `QueryOptions`} for {@link EntityManager.query | `EntityManager.query`}, excluding `entityToken`, `pageKeyMap`, and `shardQueryMap`.
615
+ *
616
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
617
+ *
618
+ * @category QueryBuilder
619
+ */
620
+ type QueryBuilderQueryOptions<C extends BaseConfigMap> = Omit<QueryOptions<C>, 'entityToken' | 'pageKeyMap' | 'shardQueryMap'>;
926
621
 
927
622
  /**
928
623
  * Abstract base class supporting a fluent API for building a {@link ShardQueryMap | `ShardQueryMap`} using a database client.
929
624
  *
930
- * @category ShardQueryMapBuilder
625
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
626
+ * @typeParam EntityClient - {@link BaseEntityClient | `BaseEntityClient`} derived class instance.
627
+ * @typeParam IndexParams - Database platform-specific, index-specific query parameters.
628
+ *
629
+ * @category QueryBuilder
931
630
  */
932
- declare abstract class BaseQueryBuilder<IndexParams, EntityClient extends BaseEntityClient, Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string, M extends EntityMap, HashKey extends string, RangeKey extends string, T extends TranscodeMap> {
631
+ declare abstract class BaseQueryBuilder<C extends BaseConfigMap, EntityClient extends BaseEntityClient, IndexParams> {
933
632
  /** {@link BaseEntityClient | `EntityClient`} instance. */
934
633
  readonly entityClient: EntityClient;
935
634
  /** {@link EntityManager | `EntityManager`} instance. */
936
- readonly entityManager: EntityManager<M, HashKey, RangeKey, T>;
635
+ readonly entityManager: EntityManager<C>;
937
636
  /** Entity token. */
938
- readonly entityToken: EntityToken;
637
+ readonly entityToken: EntityToken<C>;
939
638
  /** Hash key token. */
940
- readonly hashKeyToken: PropertiesOfType<M[EntityToken], never> | HashKey;
639
+ readonly hashKeyToken: C['HashKey'] | C['ShardedKeys'];
941
640
  /** Dehydrated page key map. */
942
641
  readonly pageKeyMap?: string;
943
642
  /**
@@ -947,28 +646,56 @@ declare abstract class BaseQueryBuilder<IndexParams, EntityClient extends BaseEn
947
646
  */
948
647
  readonly indexParamsMap: Record<string, IndexParams>;
949
648
  /** BaseQueryBuilder constructor. */
950
- constructor(options: BaseQueryBuilderOptions<EntityClient, EntityToken, M, HashKey, RangeKey, T>);
951
- protected abstract getShardQueryFunction(indexToken: string): ShardQueryFunction<Item>;
649
+ constructor(options: BaseQueryBuilderOptions<C, EntityClient>);
650
+ protected abstract getShardQueryFunction(indexToken: string): ShardQueryFunction<C>;
952
651
  /**
953
652
  * Builds a {@link ShardQueryMap | `ShardQueryMap`} object.
954
653
  *
955
654
  * @returns - The {@link ShardQueryMap | `ShardQueryMap`} object.
956
655
  */
957
- build(): ShardQueryMap<Item>;
958
- query(options: QueryBuilderQueryOptions<Item, EntityToken, M, HashKey, RangeKey>): Promise<QueryResult<Item, EntityToken, M, HashKey, RangeKey>>;
656
+ build(): ShardQueryMap<C>;
657
+ query(options: QueryBuilderQueryOptions<C>): Promise<QueryResult<C>>;
959
658
  }
960
659
 
961
660
  /**
962
- * Transforms a function such that it only executes when `condition` is truthy.
661
+ * Validates a type derived from {@link BaseConfigMap | `BaseConfigMap`} to ensure HashKey and RangeKey are both defined and that all sets of special keys are mutually exclusive.
963
662
  *
964
- * @param fn - The function to conditionally execute.
965
- * @param condition - The condition to check before executing `fn`.
663
+ * @typeParam C - {@link ConfigMap | `ConfigMap`} that defines an {@link Config | `EntityManager configuration`}'s {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
966
664
  *
967
- * @typeParam F - The type of the function to conditionally execute.
665
+ * @category EntityManager
666
+ * @protected
667
+ */
668
+ type ValidateConfigMap<C extends BaseConfigMap> = MutuallyExclusive<[
669
+ C['HashKey'],
670
+ C['RangeKey'],
671
+ C['ShardedKeys'],
672
+ C['UnshardedKeys'],
673
+ keyof FlattenEntityMap<C['EntityMap']>
674
+ ]> extends true ? NotNever<C, ['HashKey' | 'RangeKey']> extends true ? C : Exclude<NotNever<C, ['HashKey' | 'RangeKey']>, true> : Exclude<MutuallyExclusive<[
675
+ C['HashKey'],
676
+ C['RangeKey'],
677
+ C['ShardedKeys'],
678
+ C['UnshardedKeys'],
679
+ keyof FlattenEntityMap<C['EntityMap']>
680
+ ]>, true>;
681
+
682
+ /**
683
+ * Generates & validates the map defining defines an {@link EntityManager | `EntityManager`} configuration's {@link EntityMap | `EntityMap`}, key properties, and {@link TranscodeMap | `TranscodeMap`}.
684
+ *
685
+ * Unspecified properties will default to those defined in {@link BaseConfigMap | `BaseConfigMap`}.
968
686
  *
969
- * @returns The conditionalized function with the same signature as `fn`.
687
+ * @typeParam M - {@link BaseConfigMap | `BaseConfigMap`} extension. If omitted, defaults to {@link BaseConfigMap | `BaseConfigMap`}.
970
688
  *
689
+ * @category EntityManager
971
690
  */
972
- declare function conditionalize<F extends (...args: Parameters<F>) => ReturnType<F>>(fn: F, condition?: unknown): (...args: Parameters<F>) => ReturnType<F> | undefined;
691
+ type ConfigMap<M extends Partial<BaseConfigMap> = Partial<BaseConfigMap>> = ValidateConfigMap<{
692
+ EntityMap: 'EntityMap' extends keyof M ? NonNullable<M['EntityMap']> : Record<string, never>;
693
+ HashKey: 'HashKey' extends keyof M ? NonNullable<M['HashKey']> : 'hashKey';
694
+ RangeKey: 'RangeKey' extends keyof M ? NonNullable<M['RangeKey']> : 'rangeKey';
695
+ ShardedKeys: 'ShardedKeys' extends keyof M ? NonNullable<M['ShardedKeys']> : never;
696
+ UnshardedKeys: 'UnshardedKeys' extends keyof M ? NonNullable<M['UnshardedKeys']> : never;
697
+ TranscodedProperties: 'TranscodedProperties' extends keyof M ? NonNullable<M['TranscodedProperties']> : never;
698
+ TranscodeMap: 'TranscodeMap' extends keyof M ? NonNullable<M['TranscodeMap']> : DefaultTranscodeMap;
699
+ }>;
973
700
 
974
- export { BaseEntityClient, type BaseEntityClientOptions, BaseQueryBuilder, type BaseQueryBuilderOptions, type Config, type ConfigEntities, type ConfigEntity, type ConfigEntityGenerated, type ConfigEntityIndexComponent, type ConfigKeys, type ConfigTranscodes, EntityManager, type EntityMap, type ExclusiveKey, type ItemMap, type ParsedConfig, type QueryBuilderQueryOptions, type QueryOptions, type QueryResult, type ShardBump, type ShardQueryFunction, type ShardQueryMap, type ShardQueryResult, type Unwrap, conditionalize };
701
+ export { type BaseConfigMap, BaseEntityClient, type BaseEntityClientOptions, BaseQueryBuilder, type BaseQueryBuilderOptions, type Config, type ConfigMap, type EntityItem, EntityManager, type EntityToken, type ParsedConfig, type QueryBuilderQueryOptions, type QueryOptions, type QueryResult, type ShardBump, type ShardQueryFunction, type ShardQueryMap, type ShardQueryResult, type ValidateConfigMap };