@karmaniverous/entity-manager 6.0.0 → 6.1.0-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,14 @@
1
- # entity-manager
1
+ <!-- TYPEDOC_EXCLUDE -->
2
+
3
+ > [API Documentation](https://docs.karmanivero.us/entity-manager/) • [CHANGELOG](https://github.com/karmaniverous/entity-manager/tree/main/CHANGELOG.md)
2
4
 
3
- > [API Documentation](https://karmanivero.us/entity-manager/) • [CHANGELOG](https://github.com/karmaniverous/entity-manager/tree/main/CHANGELOG.md)
5
+ <!-- /TYPEDOC_EXCLUDE -->
6
+
7
+ # entity-manager
4
8
 
5
9
  **EntityManager implements rational indexing & cross-shard querying at scale in your NoSQL database so you can focus on your application logic.**
6
10
 
7
- I've just released a full Typescript refactor. Everything works beatuifully, but I'm still fleshing out the documentation.
11
+ I've just released a full Typescript refactor. Everything works beatuifully, but I'm still fleshing out [the documentation](https://karmanivero.us/projects/entity-manager/intro/).
8
12
 
9
13
  If you have any questions, please [start a discussion](https://github.com/karmaniverous/entity-manager/discussions). Otherwise stay tuned!
10
14
 
@@ -29,4 +33,3 @@ With EntityManager, you can:
29
33
  ---
30
34
 
31
35
  Built for you with ❤️ on Bali! Find more great tools & templates on [my GitHub Profile](https://github.com/karmaniverous).
32
-
@@ -0,0 +1,37 @@
1
+ 'use strict';
2
+
3
+ var tslib_es6 = require('../node_modules/tslib/tslib.es6.js');
4
+ var conditionalize = require('./conditionalize.js');
5
+
6
+ var _EntityManagerClient_options;
7
+ /**
8
+ * EntityManagerClient base class.
9
+ *
10
+ * @category Client
11
+ */
12
+ class EntityManagerClient {
13
+ constructor({ batchSize = 25, delayIncrement = 100, maxRetries = 5, throttle = 10, logger = console, logInternals = false, ...options }) {
14
+ _EntityManagerClient_options.set(this, void 0);
15
+ tslib_es6.__classPrivateFieldSet(this, _EntityManagerClient_options, {
16
+ ...options,
17
+ batchSize,
18
+ delayIncrement,
19
+ maxRetries,
20
+ throttle,
21
+ logInternals,
22
+ logger: {
23
+ ...logger,
24
+ debug: conditionalize.conditionalize(logger.debug, logInternals),
25
+ },
26
+ }, "f");
27
+ }
28
+ /**
29
+ * Returns the options used to create the EntityManagerClient instance.
30
+ */
31
+ get options() {
32
+ return tslib_es6.__classPrivateFieldGet(this, _EntityManagerClient_options, "f");
33
+ }
34
+ }
35
+ _EntityManagerClient_options = new WeakMap();
36
+
37
+ exports.EntityManagerClient = EntityManagerClient;
@@ -55,7 +55,7 @@ const configSchema = index.default
55
55
  .optional())
56
56
  .optional()
57
57
  .default({}),
58
- elementTypes: index.default.record(index.default.string()).optional().default({}),
58
+ elementTranscodes: index.default.record(index.default.string()).optional().default({}),
59
59
  indexes: index.default
60
60
  .record(index.default
61
61
  .array(index.default.string().min(1))
@@ -184,16 +184,16 @@ const configSchema = index.default
184
184
  const transcodes = Object.keys(data.transcodes);
185
185
  for (const [entityToken, entity] of Object.entries(data.entities)) {
186
186
  // validate all entity generated element type values are transcode keys.
187
- for (const [element, generatedElementType] of Object.entries(entity.elementTypes))
187
+ for (const [element, generatedElementType] of Object.entries(entity.elementTranscodes))
188
188
  if (!transcodes.includes(generatedElementType))
189
189
  ctx.addIssue({
190
190
  code: index.default.ZodIssueCode.invalid_enum_value,
191
191
  options: transcodes,
192
- path: ['entities', entityToken, 'elementTypes', element],
192
+ path: ['entities', entityToken, 'elementTranscodes', element],
193
193
  received: generatedElementType,
194
194
  });
195
195
  // validate all entity generated property elements have a corresponding entity element type.
196
- const typedElements = Object.keys(entity.elementTypes);
196
+ const typedElements = Object.keys(entity.elementTranscodes);
197
197
  for (const [generatedKey, generated] of Object.entries(entity.generated))
198
198
  for (const element of generated?.elements ?? [])
199
199
  if (!typedElements.includes(element))
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Transforms a function such that it only executes when `condition` is truthy.
5
+ *
6
+ * @param fn - The function to conditionally execute.
7
+ * @param condition - The condition to check before executing `fn`.
8
+ *
9
+ * @typeParam F - The type of the function to conditionally execute.
10
+ *
11
+ * @returns The conditionalized function with the same signature as `fn`.
12
+ *
13
+ */
14
+ function conditionalize(fn, condition) {
15
+ return (...args) => {
16
+ if (condition) {
17
+ return fn(...args);
18
+ }
19
+ else {
20
+ return undefined;
21
+ }
22
+ };
23
+ }
24
+
25
+ exports.conditionalize = conditionalize;
@@ -26,7 +26,7 @@ function decodeEntityElement(entityManager, value, entityToken, element) {
26
26
  return;
27
27
  if ([hashKey, rangeKey].includes(element))
28
28
  return value;
29
- const decoded = transcodes[entities[entityToken].elementTypes[element]].decode(value);
29
+ const decoded = transcodes[entities[entityToken].elementTranscodes[element]].decode(value);
30
30
  return decoded;
31
31
  }
32
32
  catch (error) {
@@ -25,7 +25,7 @@ function encodeEntityElement(entityManager, item, entityToken, element) {
25
25
  const value = item[element];
26
26
  if (value === undefined || [hashKey, rangeKey].includes(element))
27
27
  return value;
28
- const encoded = transcodes[entities[entityToken].elementTypes[element]].encode(item[element]) || undefined;
28
+ const encoded = transcodes[entities[entityToken].elementTranscodes[element]].encode(item[element]) || undefined;
29
29
  return encoded;
30
30
  }
31
31
  catch (error) {
@@ -1,7 +1,11 @@
1
1
  'use strict';
2
2
 
3
+ var conditionalize = require('./conditionalize.js');
3
4
  var EntityManager = require('./EntityManager.js');
5
+ var EntityManagerClient = require('./EntityManagerClient.js');
4
6
 
5
7
 
6
8
 
9
+ exports.conditionalize = conditionalize.conditionalize;
7
10
  exports.EntityManager = EntityManager.EntityManager;
11
+ exports.EntityManagerClient = EntityManagerClient.EntityManagerClient;
package/dist/index.d.cts CHANGED
@@ -2,6 +2,19 @@ import { Entity, Exactify, TranscodeMap, PropertiesOfType, TranscodablePropertie
2
2
  export { DefaultTranscodeMap, Entity, PropertiesOfType, SortOrder, TranscodableProperties, TranscodeMap, Transcodes, defaultTranscodes } from '@karmaniverous/entity-tools';
3
3
  import { z } from 'zod';
4
4
 
5
+ /**
6
+ * Transforms a function such that it only executes when `condition` is truthy.
7
+ *
8
+ * @param fn - The function to conditionally execute.
9
+ * @param condition - The condition to check before executing `fn`.
10
+ *
11
+ * @typeParam F - The type of the function to conditionally execute.
12
+ *
13
+ * @returns The conditionalized function with the same signature as `fn`.
14
+ *
15
+ */
16
+ declare function conditionalize<F extends (...args: Parameters<F>) => ReturnType<F>>(fn: F, condition?: unknown): (...args: Parameters<F>) => ReturnType<F> | undefined;
17
+
5
18
  /**
6
19
  * The base EntityMap type. All EntityMaps should extend this type.
7
20
  *
@@ -153,7 +166,7 @@ type ConfigEntity<EntityToken extends keyof Exactify<M>, M extends EntityMap, Ha
153
166
  * };
154
167
  * ```
155
168
  */
156
- elementTypes?: ([TranscodableProperties<M[EntityToken], T>] extends [never] ? never : {
169
+ elementTranscodes?: ([TranscodableProperties<M[EntityToken], T>] extends [never] ? never : {
157
170
  [P in TranscodableProperties<M[EntityToken], T>]?: PropertiesOfType<T, M[EntityToken][P]>;
158
171
  }) | ([TranscodableProperties<M[EntityToken], T>] extends [never] ? Record<string, never> : never);
159
172
  /**
@@ -366,7 +379,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
366
379
  atomic?: boolean | undefined;
367
380
  sharded?: boolean | undefined;
368
381
  }>>>>>;
369
- elementTypes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
382
+ elementTranscodes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
370
383
  indexes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodArray<z.ZodString, "atleastone">, [string, ...string[]], [string, ...string[]]>>>>;
371
384
  shardBumps: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
372
385
  timestamp: z.ZodNumber;
@@ -410,7 +423,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
410
423
  }, "strict", z.ZodTypeAny, {
411
424
  defaultLimit: number;
412
425
  defaultPageSize: number;
413
- elementTypes: Record<string, string>;
426
+ elementTranscodes: Record<string, string>;
414
427
  indexes: Record<string, [string, ...string[]]>;
415
428
  shardBumps: {
416
429
  timestamp: number;
@@ -429,7 +442,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
429
442
  uniqueProperty: string;
430
443
  defaultLimit?: number | undefined;
431
444
  defaultPageSize?: number | undefined;
432
- elementTypes?: Record<string, string> | undefined;
445
+ elementTranscodes?: Record<string, string> | undefined;
433
446
  indexes?: Record<string, [string, ...string[]]> | undefined;
434
447
  shardBumps?: {
435
448
  timestamp: number;
@@ -444,7 +457,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
444
457
  }>, {
445
458
  defaultLimit: number;
446
459
  defaultPageSize: number;
447
- elementTypes: Record<string, string>;
460
+ elementTranscodes: Record<string, string>;
448
461
  indexes: Record<string, [string, ...string[]]>;
449
462
  shardBumps: {
450
463
  timestamp: number;
@@ -463,7 +476,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
463
476
  uniqueProperty: string;
464
477
  defaultLimit?: number | undefined;
465
478
  defaultPageSize?: number | undefined;
466
- elementTypes?: Record<string, string> | undefined;
479
+ elementTranscodes?: Record<string, string> | undefined;
467
480
  indexes?: Record<string, [string, ...string[]]> | undefined;
468
481
  shardBumps?: {
469
482
  timestamp: number;
@@ -498,7 +511,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
498
511
  entities: Record<string, {
499
512
  defaultLimit: number;
500
513
  defaultPageSize: number;
501
- elementTypes: Record<string, string>;
514
+ elementTranscodes: Record<string, string>;
502
515
  indexes: Record<string, [string, ...string[]]>;
503
516
  shardBumps: {
504
517
  timestamp: number;
@@ -529,7 +542,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
529
542
  uniqueProperty: string;
530
543
  defaultLimit?: number | undefined;
531
544
  defaultPageSize?: number | undefined;
532
- elementTypes?: Record<string, string> | undefined;
545
+ elementTranscodes?: Record<string, string> | undefined;
533
546
  indexes?: Record<string, [string, ...string[]]> | undefined;
534
547
  shardBumps?: {
535
548
  timestamp: number;
@@ -556,7 +569,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
556
569
  entities: Record<string, {
557
570
  defaultLimit: number;
558
571
  defaultPageSize: number;
559
- elementTypes: Record<string, string>;
572
+ elementTranscodes: Record<string, string>;
560
573
  indexes: Record<string, [string, ...string[]]>;
561
574
  shardBumps: {
562
575
  timestamp: number;
@@ -587,7 +600,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
587
600
  uniqueProperty: string;
588
601
  defaultLimit?: number | undefined;
589
602
  defaultPageSize?: number | undefined;
590
- elementTypes?: Record<string, string> | undefined;
603
+ elementTranscodes?: Record<string, string> | undefined;
591
604
  indexes?: Record<string, [string, ...string[]]> | undefined;
592
605
  shardBumps?: {
593
606
  timestamp: number;
@@ -823,4 +836,65 @@ declare class EntityManager<M extends EntityMap, HashKey extends string, RangeKe
823
836
  query<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string>(options: QueryOptions<Item, EntityToken, M, HashKey, RangeKey, T>): Promise<QueryResult<Item, EntityToken, M, HashKey, RangeKey>>;
824
837
  }
825
838
 
826
- export { type Config, type ConfigEntities, type ConfigEntity, type ConfigEntityGenerated, type ConfigKeys, type ConfigTranscodes, EntityManager, type EntityMap, type ExclusiveKey, type ItemMap, type ParsedConfig, type QueryOptions, type QueryResult, type ShardBump, type ShardQueryFunction, type ShardQueryResult, type Unwrap };
839
+ /**
840
+ * Options for EntityManager client methods that support batch operations.
841
+ */
842
+ interface EntityManagerClientBatchOptions {
843
+ /** Batch size. */
844
+ batchSize?: number;
845
+ /** Delay increment in ms for retry operations. Doubles on each retry. */
846
+ delayIncrement?: number;
847
+ /** Max retries for retry operations. */
848
+ maxRetries?: number;
849
+ /** Throttle for parallel operations. */
850
+ throttle?: number;
851
+ }
852
+
853
+ /**
854
+ * Generic logger endpoint type.
855
+ *
856
+ * @category Logger
857
+ */
858
+ type LoggerEndpoint = (...args: unknown[]) => void;
859
+ /**
860
+ * Logger interface.
861
+ *
862
+ * @category Logger
863
+ */
864
+ interface Logger {
865
+ debug: LoggerEndpoint;
866
+ error: LoggerEndpoint;
867
+ }
868
+ /**
869
+ * Logger options.
870
+ *
871
+ * @category Logger
872
+ */
873
+ interface LoggerOptions {
874
+ /** Logger to use for internal logging. Must support the `debug` & `error` methods. Defaults to `console`. */
875
+ logger?: Logger;
876
+ /** Enables internal logging when `true`. */
877
+ logInternals?: boolean;
878
+ }
879
+
880
+ /**
881
+ * EntityManagerClient base class options.
882
+ *
883
+ * @category Client
884
+ */
885
+ type EntityManagerClientOptions = EntityManagerClientBatchOptions & LoggerOptions;
886
+ /**
887
+ * EntityManagerClient base class.
888
+ *
889
+ * @category Client
890
+ */
891
+ declare abstract class EntityManagerClient<O extends EntityManagerClientOptions> {
892
+ #private;
893
+ constructor({ batchSize, delayIncrement, maxRetries, throttle, logger, logInternals, ...options }: O);
894
+ /**
895
+ * Returns the options used to create the EntityManagerClient instance.
896
+ */
897
+ get options(): Required<O>;
898
+ }
899
+
900
+ export { type Config, type ConfigEntities, type ConfigEntity, type ConfigEntityGenerated, type ConfigKeys, type ConfigTranscodes, EntityManager, EntityManagerClient, type EntityManagerClientBatchOptions, type EntityManagerClientOptions, type EntityMap, type ExclusiveKey, type ItemMap, type Logger, type LoggerEndpoint, type LoggerOptions, type ParsedConfig, type QueryOptions, type QueryResult, type ShardBump, type ShardQueryFunction, type ShardQueryResult, type Unwrap, conditionalize };
package/dist/index.d.mts CHANGED
@@ -2,6 +2,19 @@ import { Entity, Exactify, TranscodeMap, PropertiesOfType, TranscodablePropertie
2
2
  export { DefaultTranscodeMap, Entity, PropertiesOfType, SortOrder, TranscodableProperties, TranscodeMap, Transcodes, defaultTranscodes } from '@karmaniverous/entity-tools';
3
3
  import { z } from 'zod';
4
4
 
5
+ /**
6
+ * Transforms a function such that it only executes when `condition` is truthy.
7
+ *
8
+ * @param fn - The function to conditionally execute.
9
+ * @param condition - The condition to check before executing `fn`.
10
+ *
11
+ * @typeParam F - The type of the function to conditionally execute.
12
+ *
13
+ * @returns The conditionalized function with the same signature as `fn`.
14
+ *
15
+ */
16
+ declare function conditionalize<F extends (...args: Parameters<F>) => ReturnType<F>>(fn: F, condition?: unknown): (...args: Parameters<F>) => ReturnType<F> | undefined;
17
+
5
18
  /**
6
19
  * The base EntityMap type. All EntityMaps should extend this type.
7
20
  *
@@ -153,7 +166,7 @@ type ConfigEntity<EntityToken extends keyof Exactify<M>, M extends EntityMap, Ha
153
166
  * };
154
167
  * ```
155
168
  */
156
- elementTypes?: ([TranscodableProperties<M[EntityToken], T>] extends [never] ? never : {
169
+ elementTranscodes?: ([TranscodableProperties<M[EntityToken], T>] extends [never] ? never : {
157
170
  [P in TranscodableProperties<M[EntityToken], T>]?: PropertiesOfType<T, M[EntityToken][P]>;
158
171
  }) | ([TranscodableProperties<M[EntityToken], T>] extends [never] ? Record<string, never> : never);
159
172
  /**
@@ -366,7 +379,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
366
379
  atomic?: boolean | undefined;
367
380
  sharded?: boolean | undefined;
368
381
  }>>>>>;
369
- elementTypes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
382
+ elementTranscodes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
370
383
  indexes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodArray<z.ZodString, "atleastone">, [string, ...string[]], [string, ...string[]]>>>>;
371
384
  shardBumps: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
372
385
  timestamp: z.ZodNumber;
@@ -410,7 +423,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
410
423
  }, "strict", z.ZodTypeAny, {
411
424
  defaultLimit: number;
412
425
  defaultPageSize: number;
413
- elementTypes: Record<string, string>;
426
+ elementTranscodes: Record<string, string>;
414
427
  indexes: Record<string, [string, ...string[]]>;
415
428
  shardBumps: {
416
429
  timestamp: number;
@@ -429,7 +442,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
429
442
  uniqueProperty: string;
430
443
  defaultLimit?: number | undefined;
431
444
  defaultPageSize?: number | undefined;
432
- elementTypes?: Record<string, string> | undefined;
445
+ elementTranscodes?: Record<string, string> | undefined;
433
446
  indexes?: Record<string, [string, ...string[]]> | undefined;
434
447
  shardBumps?: {
435
448
  timestamp: number;
@@ -444,7 +457,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
444
457
  }>, {
445
458
  defaultLimit: number;
446
459
  defaultPageSize: number;
447
- elementTypes: Record<string, string>;
460
+ elementTranscodes: Record<string, string>;
448
461
  indexes: Record<string, [string, ...string[]]>;
449
462
  shardBumps: {
450
463
  timestamp: number;
@@ -463,7 +476,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
463
476
  uniqueProperty: string;
464
477
  defaultLimit?: number | undefined;
465
478
  defaultPageSize?: number | undefined;
466
- elementTypes?: Record<string, string> | undefined;
479
+ elementTranscodes?: Record<string, string> | undefined;
467
480
  indexes?: Record<string, [string, ...string[]]> | undefined;
468
481
  shardBumps?: {
469
482
  timestamp: number;
@@ -498,7 +511,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
498
511
  entities: Record<string, {
499
512
  defaultLimit: number;
500
513
  defaultPageSize: number;
501
- elementTypes: Record<string, string>;
514
+ elementTranscodes: Record<string, string>;
502
515
  indexes: Record<string, [string, ...string[]]>;
503
516
  shardBumps: {
504
517
  timestamp: number;
@@ -529,7 +542,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
529
542
  uniqueProperty: string;
530
543
  defaultLimit?: number | undefined;
531
544
  defaultPageSize?: number | undefined;
532
- elementTypes?: Record<string, string> | undefined;
545
+ elementTranscodes?: Record<string, string> | undefined;
533
546
  indexes?: Record<string, [string, ...string[]]> | undefined;
534
547
  shardBumps?: {
535
548
  timestamp: number;
@@ -556,7 +569,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
556
569
  entities: Record<string, {
557
570
  defaultLimit: number;
558
571
  defaultPageSize: number;
559
- elementTypes: Record<string, string>;
572
+ elementTranscodes: Record<string, string>;
560
573
  indexes: Record<string, [string, ...string[]]>;
561
574
  shardBumps: {
562
575
  timestamp: number;
@@ -587,7 +600,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
587
600
  uniqueProperty: string;
588
601
  defaultLimit?: number | undefined;
589
602
  defaultPageSize?: number | undefined;
590
- elementTypes?: Record<string, string> | undefined;
603
+ elementTranscodes?: Record<string, string> | undefined;
591
604
  indexes?: Record<string, [string, ...string[]]> | undefined;
592
605
  shardBumps?: {
593
606
  timestamp: number;
@@ -823,4 +836,65 @@ declare class EntityManager<M extends EntityMap, HashKey extends string, RangeKe
823
836
  query<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string>(options: QueryOptions<Item, EntityToken, M, HashKey, RangeKey, T>): Promise<QueryResult<Item, EntityToken, M, HashKey, RangeKey>>;
824
837
  }
825
838
 
826
- export { type Config, type ConfigEntities, type ConfigEntity, type ConfigEntityGenerated, type ConfigKeys, type ConfigTranscodes, EntityManager, type EntityMap, type ExclusiveKey, type ItemMap, type ParsedConfig, type QueryOptions, type QueryResult, type ShardBump, type ShardQueryFunction, type ShardQueryResult, type Unwrap };
839
+ /**
840
+ * Options for EntityManager client methods that support batch operations.
841
+ */
842
+ interface EntityManagerClientBatchOptions {
843
+ /** Batch size. */
844
+ batchSize?: number;
845
+ /** Delay increment in ms for retry operations. Doubles on each retry. */
846
+ delayIncrement?: number;
847
+ /** Max retries for retry operations. */
848
+ maxRetries?: number;
849
+ /** Throttle for parallel operations. */
850
+ throttle?: number;
851
+ }
852
+
853
+ /**
854
+ * Generic logger endpoint type.
855
+ *
856
+ * @category Logger
857
+ */
858
+ type LoggerEndpoint = (...args: unknown[]) => void;
859
+ /**
860
+ * Logger interface.
861
+ *
862
+ * @category Logger
863
+ */
864
+ interface Logger {
865
+ debug: LoggerEndpoint;
866
+ error: LoggerEndpoint;
867
+ }
868
+ /**
869
+ * Logger options.
870
+ *
871
+ * @category Logger
872
+ */
873
+ interface LoggerOptions {
874
+ /** Logger to use for internal logging. Must support the `debug` & `error` methods. Defaults to `console`. */
875
+ logger?: Logger;
876
+ /** Enables internal logging when `true`. */
877
+ logInternals?: boolean;
878
+ }
879
+
880
+ /**
881
+ * EntityManagerClient base class options.
882
+ *
883
+ * @category Client
884
+ */
885
+ type EntityManagerClientOptions = EntityManagerClientBatchOptions & LoggerOptions;
886
+ /**
887
+ * EntityManagerClient base class.
888
+ *
889
+ * @category Client
890
+ */
891
+ declare abstract class EntityManagerClient<O extends EntityManagerClientOptions> {
892
+ #private;
893
+ constructor({ batchSize, delayIncrement, maxRetries, throttle, logger, logInternals, ...options }: O);
894
+ /**
895
+ * Returns the options used to create the EntityManagerClient instance.
896
+ */
897
+ get options(): Required<O>;
898
+ }
899
+
900
+ export { type Config, type ConfigEntities, type ConfigEntity, type ConfigEntityGenerated, type ConfigKeys, type ConfigTranscodes, EntityManager, EntityManagerClient, type EntityManagerClientBatchOptions, type EntityManagerClientOptions, type EntityMap, type ExclusiveKey, type ItemMap, type Logger, type LoggerEndpoint, type LoggerOptions, type ParsedConfig, type QueryOptions, type QueryResult, type ShardBump, type ShardQueryFunction, type ShardQueryResult, type Unwrap, conditionalize };
package/dist/index.d.ts CHANGED
@@ -2,6 +2,19 @@ import { Entity, Exactify, TranscodeMap, PropertiesOfType, TranscodablePropertie
2
2
  export { DefaultTranscodeMap, Entity, PropertiesOfType, SortOrder, TranscodableProperties, TranscodeMap, Transcodes, defaultTranscodes } from '@karmaniverous/entity-tools';
3
3
  import { z } from 'zod';
4
4
 
5
+ /**
6
+ * Transforms a function such that it only executes when `condition` is truthy.
7
+ *
8
+ * @param fn - The function to conditionally execute.
9
+ * @param condition - The condition to check before executing `fn`.
10
+ *
11
+ * @typeParam F - The type of the function to conditionally execute.
12
+ *
13
+ * @returns The conditionalized function with the same signature as `fn`.
14
+ *
15
+ */
16
+ declare function conditionalize<F extends (...args: Parameters<F>) => ReturnType<F>>(fn: F, condition?: unknown): (...args: Parameters<F>) => ReturnType<F> | undefined;
17
+
5
18
  /**
6
19
  * The base EntityMap type. All EntityMaps should extend this type.
7
20
  *
@@ -153,7 +166,7 @@ type ConfigEntity<EntityToken extends keyof Exactify<M>, M extends EntityMap, Ha
153
166
  * };
154
167
  * ```
155
168
  */
156
- elementTypes?: ([TranscodableProperties<M[EntityToken], T>] extends [never] ? never : {
169
+ elementTranscodes?: ([TranscodableProperties<M[EntityToken], T>] extends [never] ? never : {
157
170
  [P in TranscodableProperties<M[EntityToken], T>]?: PropertiesOfType<T, M[EntityToken][P]>;
158
171
  }) | ([TranscodableProperties<M[EntityToken], T>] extends [never] ? Record<string, never> : never);
159
172
  /**
@@ -366,7 +379,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
366
379
  atomic?: boolean | undefined;
367
380
  sharded?: boolean | undefined;
368
381
  }>>>>>;
369
- elementTypes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
382
+ elementTranscodes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
370
383
  indexes: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodArray<z.ZodString, "atleastone">, [string, ...string[]], [string, ...string[]]>>>>;
371
384
  shardBumps: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
372
385
  timestamp: z.ZodNumber;
@@ -410,7 +423,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
410
423
  }, "strict", z.ZodTypeAny, {
411
424
  defaultLimit: number;
412
425
  defaultPageSize: number;
413
- elementTypes: Record<string, string>;
426
+ elementTranscodes: Record<string, string>;
414
427
  indexes: Record<string, [string, ...string[]]>;
415
428
  shardBumps: {
416
429
  timestamp: number;
@@ -429,7 +442,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
429
442
  uniqueProperty: string;
430
443
  defaultLimit?: number | undefined;
431
444
  defaultPageSize?: number | undefined;
432
- elementTypes?: Record<string, string> | undefined;
445
+ elementTranscodes?: Record<string, string> | undefined;
433
446
  indexes?: Record<string, [string, ...string[]]> | undefined;
434
447
  shardBumps?: {
435
448
  timestamp: number;
@@ -444,7 +457,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
444
457
  }>, {
445
458
  defaultLimit: number;
446
459
  defaultPageSize: number;
447
- elementTypes: Record<string, string>;
460
+ elementTranscodes: Record<string, string>;
448
461
  indexes: Record<string, [string, ...string[]]>;
449
462
  shardBumps: {
450
463
  timestamp: number;
@@ -463,7 +476,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
463
476
  uniqueProperty: string;
464
477
  defaultLimit?: number | undefined;
465
478
  defaultPageSize?: number | undefined;
466
- elementTypes?: Record<string, string> | undefined;
479
+ elementTranscodes?: Record<string, string> | undefined;
467
480
  indexes?: Record<string, [string, ...string[]]> | undefined;
468
481
  shardBumps?: {
469
482
  timestamp: number;
@@ -498,7 +511,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
498
511
  entities: Record<string, {
499
512
  defaultLimit: number;
500
513
  defaultPageSize: number;
501
- elementTypes: Record<string, string>;
514
+ elementTranscodes: Record<string, string>;
502
515
  indexes: Record<string, [string, ...string[]]>;
503
516
  shardBumps: {
504
517
  timestamp: number;
@@ -529,7 +542,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
529
542
  uniqueProperty: string;
530
543
  defaultLimit?: number | undefined;
531
544
  defaultPageSize?: number | undefined;
532
- elementTypes?: Record<string, string> | undefined;
545
+ elementTranscodes?: Record<string, string> | undefined;
533
546
  indexes?: Record<string, [string, ...string[]]> | undefined;
534
547
  shardBumps?: {
535
548
  timestamp: number;
@@ -556,7 +569,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
556
569
  entities: Record<string, {
557
570
  defaultLimit: number;
558
571
  defaultPageSize: number;
559
- elementTypes: Record<string, string>;
572
+ elementTranscodes: Record<string, string>;
560
573
  indexes: Record<string, [string, ...string[]]>;
561
574
  shardBumps: {
562
575
  timestamp: number;
@@ -587,7 +600,7 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
587
600
  uniqueProperty: string;
588
601
  defaultLimit?: number | undefined;
589
602
  defaultPageSize?: number | undefined;
590
- elementTypes?: Record<string, string> | undefined;
603
+ elementTranscodes?: Record<string, string> | undefined;
591
604
  indexes?: Record<string, [string, ...string[]]> | undefined;
592
605
  shardBumps?: {
593
606
  timestamp: number;
@@ -823,4 +836,65 @@ declare class EntityManager<M extends EntityMap, HashKey extends string, RangeKe
823
836
  query<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string>(options: QueryOptions<Item, EntityToken, M, HashKey, RangeKey, T>): Promise<QueryResult<Item, EntityToken, M, HashKey, RangeKey>>;
824
837
  }
825
838
 
826
- export { type Config, type ConfigEntities, type ConfigEntity, type ConfigEntityGenerated, type ConfigKeys, type ConfigTranscodes, EntityManager, type EntityMap, type ExclusiveKey, type ItemMap, type ParsedConfig, type QueryOptions, type QueryResult, type ShardBump, type ShardQueryFunction, type ShardQueryResult, type Unwrap };
839
+ /**
840
+ * Options for EntityManager client methods that support batch operations.
841
+ */
842
+ interface EntityManagerClientBatchOptions {
843
+ /** Batch size. */
844
+ batchSize?: number;
845
+ /** Delay increment in ms for retry operations. Doubles on each retry. */
846
+ delayIncrement?: number;
847
+ /** Max retries for retry operations. */
848
+ maxRetries?: number;
849
+ /** Throttle for parallel operations. */
850
+ throttle?: number;
851
+ }
852
+
853
+ /**
854
+ * Generic logger endpoint type.
855
+ *
856
+ * @category Logger
857
+ */
858
+ type LoggerEndpoint = (...args: unknown[]) => void;
859
+ /**
860
+ * Logger interface.
861
+ *
862
+ * @category Logger
863
+ */
864
+ interface Logger {
865
+ debug: LoggerEndpoint;
866
+ error: LoggerEndpoint;
867
+ }
868
+ /**
869
+ * Logger options.
870
+ *
871
+ * @category Logger
872
+ */
873
+ interface LoggerOptions {
874
+ /** Logger to use for internal logging. Must support the `debug` & `error` methods. Defaults to `console`. */
875
+ logger?: Logger;
876
+ /** Enables internal logging when `true`. */
877
+ logInternals?: boolean;
878
+ }
879
+
880
+ /**
881
+ * EntityManagerClient base class options.
882
+ *
883
+ * @category Client
884
+ */
885
+ type EntityManagerClientOptions = EntityManagerClientBatchOptions & LoggerOptions;
886
+ /**
887
+ * EntityManagerClient base class.
888
+ *
889
+ * @category Client
890
+ */
891
+ declare abstract class EntityManagerClient<O extends EntityManagerClientOptions> {
892
+ #private;
893
+ constructor({ batchSize, delayIncrement, maxRetries, throttle, logger, logInternals, ...options }: O);
894
+ /**
895
+ * Returns the options used to create the EntityManagerClient instance.
896
+ */
897
+ get options(): Required<O>;
898
+ }
899
+
900
+ export { type Config, type ConfigEntities, type ConfigEntity, type ConfigEntityGenerated, type ConfigKeys, type ConfigTranscodes, EntityManager, EntityManagerClient, type EntityManagerClientBatchOptions, type EntityManagerClientOptions, type EntityMap, type ExclusiveKey, type ItemMap, type Logger, type LoggerEndpoint, type LoggerOptions, type ParsedConfig, type QueryOptions, type QueryResult, type ShardBump, type ShardQueryFunction, type ShardQueryResult, type Unwrap, conditionalize };
@@ -0,0 +1,35 @@
1
+ import { __classPrivateFieldSet, __classPrivateFieldGet } from '../node_modules/tslib/tslib.es6.js';
2
+ import { conditionalize } from './conditionalize.js';
3
+
4
+ var _EntityManagerClient_options;
5
+ /**
6
+ * EntityManagerClient base class.
7
+ *
8
+ * @category Client
9
+ */
10
+ class EntityManagerClient {
11
+ constructor({ batchSize = 25, delayIncrement = 100, maxRetries = 5, throttle = 10, logger = console, logInternals = false, ...options }) {
12
+ _EntityManagerClient_options.set(this, void 0);
13
+ __classPrivateFieldSet(this, _EntityManagerClient_options, {
14
+ ...options,
15
+ batchSize,
16
+ delayIncrement,
17
+ maxRetries,
18
+ throttle,
19
+ logInternals,
20
+ logger: {
21
+ ...logger,
22
+ debug: conditionalize(logger.debug, logInternals),
23
+ },
24
+ }, "f");
25
+ }
26
+ /**
27
+ * Returns the options used to create the EntityManagerClient instance.
28
+ */
29
+ get options() {
30
+ return __classPrivateFieldGet(this, _EntityManagerClient_options, "f");
31
+ }
32
+ }
33
+ _EntityManagerClient_options = new WeakMap();
34
+
35
+ export { EntityManagerClient };
@@ -53,7 +53,7 @@ const configSchema = z
53
53
  .optional())
54
54
  .optional()
55
55
  .default({}),
56
- elementTypes: z.record(z.string()).optional().default({}),
56
+ elementTranscodes: z.record(z.string()).optional().default({}),
57
57
  indexes: z
58
58
  .record(z
59
59
  .array(z.string().min(1))
@@ -182,16 +182,16 @@ const configSchema = z
182
182
  const transcodes = Object.keys(data.transcodes);
183
183
  for (const [entityToken, entity] of Object.entries(data.entities)) {
184
184
  // validate all entity generated element type values are transcode keys.
185
- for (const [element, generatedElementType] of Object.entries(entity.elementTypes))
185
+ for (const [element, generatedElementType] of Object.entries(entity.elementTranscodes))
186
186
  if (!transcodes.includes(generatedElementType))
187
187
  ctx.addIssue({
188
188
  code: z.ZodIssueCode.invalid_enum_value,
189
189
  options: transcodes,
190
- path: ['entities', entityToken, 'elementTypes', element],
190
+ path: ['entities', entityToken, 'elementTranscodes', element],
191
191
  received: generatedElementType,
192
192
  });
193
193
  // validate all entity generated property elements have a corresponding entity element type.
194
- const typedElements = Object.keys(entity.elementTypes);
194
+ const typedElements = Object.keys(entity.elementTranscodes);
195
195
  for (const [generatedKey, generated] of Object.entries(entity.generated))
196
196
  for (const element of generated?.elements ?? [])
197
197
  if (!typedElements.includes(element))
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Transforms a function such that it only executes when `condition` is truthy.
3
+ *
4
+ * @param fn - The function to conditionally execute.
5
+ * @param condition - The condition to check before executing `fn`.
6
+ *
7
+ * @typeParam F - The type of the function to conditionally execute.
8
+ *
9
+ * @returns The conditionalized function with the same signature as `fn`.
10
+ *
11
+ */
12
+ function conditionalize(fn, condition) {
13
+ return (...args) => {
14
+ if (condition) {
15
+ return fn(...args);
16
+ }
17
+ else {
18
+ return undefined;
19
+ }
20
+ };
21
+ }
22
+
23
+ export { conditionalize };
@@ -24,7 +24,7 @@ function decodeEntityElement(entityManager, value, entityToken, element) {
24
24
  return;
25
25
  if ([hashKey, rangeKey].includes(element))
26
26
  return value;
27
- const decoded = transcodes[entities[entityToken].elementTypes[element]].decode(value);
27
+ const decoded = transcodes[entities[entityToken].elementTranscodes[element]].decode(value);
28
28
  return decoded;
29
29
  }
30
30
  catch (error) {
@@ -23,7 +23,7 @@ function encodeEntityElement(entityManager, item, entityToken, element) {
23
23
  const value = item[element];
24
24
  if (value === undefined || [hashKey, rangeKey].includes(element))
25
25
  return value;
26
- const encoded = transcodes[entities[entityToken].elementTypes[element]].encode(item[element]) || undefined;
26
+ const encoded = transcodes[entities[entityToken].elementTranscodes[element]].encode(item[element]) || undefined;
27
27
  return encoded;
28
28
  }
29
29
  catch (error) {
@@ -1 +1,3 @@
1
+ export { conditionalize } from './conditionalize.js';
1
2
  export { EntityManager } from './EntityManager.js';
3
+ export { EntityManagerClient } from './EntityManagerClient.js';
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "string-hash": "^1.1.3",
13
13
  "zod": "^3.23.8"
14
14
  },
15
- "description": "Configurably decorate entity objects with sharded index keys.",
15
+ "description": "Rational indexing & cross-shard querying at scale in your NoSQL database so you can focus on your application logic.",
16
16
  "devDependencies": {
17
17
  "@dotenvx/dotenvx": "^1.14.1",
18
18
  "@eslint/js": "^9.10.0",
@@ -132,5 +132,5 @@
132
132
  },
133
133
  "type": "module",
134
134
  "types": "dist/index.d.ts",
135
- "version": "6.0.0"
135
+ "version": "6.1.0-0"
136
136
  }