@karmaniverous/entity-manager 6.7.1 → 6.7.2

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.
@@ -29,6 +29,16 @@ class BaseShardQueryMapBuilder {
29
29
  build() {
30
30
  return radash.mapValues(this.indexParamsMap, (indexConfig, indexToken) => this.getShardQueryFunction(indexToken));
31
31
  }
32
+ async query(options) {
33
+ const { entityManager, entityToken, pageKeyMap } = this;
34
+ const shardQueryMap = this.build();
35
+ return await entityManager.query({
36
+ ...options,
37
+ entityToken,
38
+ pageKeyMap,
39
+ shardQueryMap,
40
+ });
41
+ }
32
42
  }
33
43
 
34
44
  exports.BaseShardQueryMapBuilder = BaseShardQueryMapBuilder;
package/dist/index.d.ts CHANGED
@@ -363,6 +363,137 @@ type ItemMap<M extends EntityMap, HashKey extends string = 'hashKey', RangeKey e
363
363
  } & Partial<Record<HashKey | RangeKey, string>>>;
364
364
  };
365
365
 
366
+ /**
367
+ * A result returned by a query across multiple shards, where each shard may
368
+ * receive multiple page queries via a dynamically-generated {@link ShardQueryFunction | `ShardQueryFunction`}.
369
+ *
370
+ * @category Query
371
+ */
372
+ interface QueryResult<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string, M extends EntityMap, HashKey extends string, RangeKey extends string> {
373
+ /** Total number of records returned across all shards. */
374
+ count: number;
375
+ /** The returned records. */
376
+ items: Item[];
377
+ /**
378
+ * A compressed, two-layer map of page keys, used to query the next page of
379
+ * data for a given sort key on each shard of a given hash key.
380
+ */
381
+ pageKeyMap: string;
382
+ }
383
+
384
+ /**
385
+ * A result returned by a {@link ShardQueryFunction | `ShardQueryFunction`} querying an individual shard.
386
+ *
387
+ * @typeParam Item - The {@link Item | `Item`} type being queried.
388
+
389
+ * @category Query
390
+ */
391
+ interface ShardQueryResult<Item extends Entity> {
392
+ /** The number of records returned. */
393
+ count: number;
394
+ /** The returned records. */
395
+ items: Item[];
396
+ /** The page key for the next query on this shard. */
397
+ pageKey?: Partial<Item>;
398
+ }
399
+
400
+ /**
401
+ * A query function that returns a single page of results from an individual
402
+ * shard. This function will typically be composed dynamically to express a
403
+ * specific query index & logic. The arguments to this function will be
404
+ * provided by the {@link EntityManager.query | `EntityManager.query`} method, which assembles many returned
405
+ * pages queried across multiple shards into a single query result.
406
+ *
407
+ * @typeParam Item - The {@link Item | `Item`} type being queried.
408
+
409
+ * @param hashKey - The hash key value of the shard being queried.
410
+ * @param pageKey - The page key returned by the previous query on this shard.
411
+ * @param pageSize - The maximum number of items to return from this query.
412
+ *
413
+ * @category Query
414
+ */
415
+ type ShardQueryFunction<Item extends Entity> = (hashKey: string, pageKey?: Partial<Item>, pageSize?: number) => Promise<ShardQueryResult<Item>>;
416
+
417
+ type ShardQueryMap<Item extends Entity> = Record<string, ShardQueryFunction<Item>>;
418
+
419
+ /**
420
+ * Options passed to the {@link query | `query`} function.
421
+ *
422
+ * @category Query
423
+ */
424
+ interface QueryOptions<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string, M extends EntityMap, HashKey extends string, RangeKey extends string> {
425
+ /** Identifies the entity to be queried. Key of {@link Config | `EntityManager.config.entities`}. */
426
+ entityToken: EntityToken;
427
+ /**
428
+ * Partial item object sufficiently populated to generate index hash keys.
429
+ */
430
+ item: Partial<Item>;
431
+ /**
432
+ * The target maximum number of records to be returned by the query across
433
+ * all shards.
434
+ *
435
+ * The actual number of records returned will be a product of {@link QueryOptions.pageSize | `pageSize`} and the
436
+ * number of shards queried, unless limited by available records in a given
437
+ * shard.
438
+ */
439
+ limit?: number;
440
+ /**
441
+ * {@link QueryResult.pageKeyMap | `pageKeyMap`} returned by the previous iteration of this query.
442
+ */
443
+ pageKeyMap?: string;
444
+ /**
445
+ * The maximum number of records to be returned by each individual query to a
446
+ * single shard (i.e. {@link ShardQueryFunction | `ShardQueryFunction`} execution).
447
+ *
448
+ * Note that, within a given {@link EntityManager.query | `query`} method execution, these queries will be
449
+ * repeated until either available data is exhausted or the {@link QueryOptions.limit | `limit`} value is
450
+ * reached.
451
+ */
452
+ pageSize?: number;
453
+ /**
454
+ * Each key in this object is a valid entity index token. Each value is a valid
455
+ * {@link ShardQueryFunction | 'ShardQueryFunction'} that specifies the query of a single page of data on a
456
+ * single shard for the mapped index.
457
+ *
458
+ * This allows simultaneous queries on multiple sort keys to share a single
459
+ * page key, e.g. to match the same string against `firstName` and `lastName`
460
+ * properties without performing a table scan for either.
461
+ */
462
+ shardQueryMap: ShardQueryMap<Item>;
463
+ /**
464
+ * A {@link SortOrder | `SortOrder`} object specifying the sort order of the result set. Defaults to `[]`.
465
+ */
466
+ sortOrder?: SortOrder<Item>;
467
+ /**
468
+ * Lower limit to query shard space.
469
+ *
470
+ * Only valid if the query is constrained along the dimension used by the
471
+ * {@link Config | `EntityManager.config.entities.<entityToken>.sharding.timestamptokens.timestamp`}
472
+ * function to generate `shardKey`.
473
+ *
474
+ * @defaultValue `0`
475
+ */
476
+ timestampFrom?: number;
477
+ /**
478
+ * Upper limit to query shard space.
479
+ *
480
+ * Only valid if the query is constrained along the dimension used by the
481
+ * {@link Config | `EntityManager.config.entities.<entityToken>.sharding.timestamptokens.timestamp`}
482
+ * function to generate `shardKey`.
483
+ *
484
+ * @defaultValue `Date.now()`
485
+ */
486
+ timestampTo?: number;
487
+ /**
488
+ * The maximum number of shards to query in parallel. Overrides options `throttle`.
489
+ *
490
+ * @defaultValue `options.throttle`
491
+ */
492
+ throttle?: number;
493
+ }
494
+
495
+ type BuilderQueryOptions<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'>;
496
+
366
497
  declare const configSchema: z.ZodEffects<z.ZodObject<{
367
498
  entities: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodObject<{
368
499
  defaultLimit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
@@ -674,135 +805,6 @@ declare const configSchema: z.ZodEffects<z.ZodObject<{
674
805
  */
675
806
  type ParsedConfig = z.infer<typeof configSchema>;
676
807
 
677
- /**
678
- * A result returned by a {@link ShardQueryFunction | `ShardQueryFunction`} querying an individual shard.
679
- *
680
- * @typeParam Item - The {@link Item | `Item`} type being queried.
681
-
682
- * @category Query
683
- */
684
- interface ShardQueryResult<Item extends Entity> {
685
- /** The number of records returned. */
686
- count: number;
687
- /** The returned records. */
688
- items: Item[];
689
- /** The page key for the next query on this shard. */
690
- pageKey?: Partial<Item>;
691
- }
692
-
693
- /**
694
- * A query function that returns a single page of results from an individual
695
- * shard. This function will typically be composed dynamically to express a
696
- * specific query index & logic. The arguments to this function will be
697
- * provided by the {@link EntityManager.query | `EntityManager.query`} method, which assembles many returned
698
- * pages queried across multiple shards into a single query result.
699
- *
700
- * @typeParam Item - The {@link Item | `Item`} type being queried.
701
-
702
- * @param hashKey - The hash key value of the shard being queried.
703
- * @param pageKey - The page key returned by the previous query on this shard.
704
- * @param pageSize - The maximum number of items to return from this query.
705
- *
706
- * @category Query
707
- */
708
- type ShardQueryFunction<Item extends Entity> = (hashKey: string, pageKey?: Partial<Item>, pageSize?: number) => Promise<ShardQueryResult<Item>>;
709
-
710
- type ShardQueryMap<Item extends Entity> = Record<string, ShardQueryFunction<Item>>;
711
-
712
- /**
713
- * Options passed to the {@link query | `query`} function.
714
- *
715
- * @category Query
716
- */
717
- interface QueryOptions<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string, M extends EntityMap, HashKey extends string, RangeKey extends string> {
718
- /** Identifies the entity to be queried. Key of {@link Config | `EntityManager.config.entities`}. */
719
- entityToken: EntityToken;
720
- /**
721
- * Partial item object sufficiently populated to generate index hash keys.
722
- */
723
- item: Partial<Item>;
724
- /**
725
- * The target maximum number of records to be returned by the query across
726
- * all shards.
727
- *
728
- * The actual number of records returned will be a product of {@link QueryOptions.pageSize | `pageSize`} and the
729
- * number of shards queried, unless limited by available records in a given
730
- * shard.
731
- */
732
- limit?: number;
733
- /**
734
- * {@link QueryResult.pageKeyMap | `pageKeyMap`} returned by the previous iteration of this query.
735
- */
736
- pageKeyMap?: string;
737
- /**
738
- * The maximum number of records to be returned by each individual query to a
739
- * single shard (i.e. {@link ShardQueryFunction | `ShardQueryFunction`} execution).
740
- *
741
- * Note that, within a given {@link EntityManager.query | `query`} method execution, these queries will be
742
- * repeated until either available data is exhausted or the {@link QueryOptions.limit | `limit`} value is
743
- * reached.
744
- */
745
- pageSize?: number;
746
- /**
747
- * Each key in this object is a valid entity index token. Each value is a valid
748
- * {@link ShardQueryFunction | 'ShardQueryFunction'} that specifies the query of a single page of data on a
749
- * single shard for the mapped index.
750
- *
751
- * This allows simultaneous queries on multiple sort keys to share a single
752
- * page key, e.g. to match the same string against `firstName` and `lastName`
753
- * properties without performing a table scan for either.
754
- */
755
- shardQueryMap: ShardQueryMap<Item>;
756
- /**
757
- * A {@link SortOrder | `SortOrder`} object specifying the sort order of the result set. Defaults to `[]`.
758
- */
759
- sortOrder?: SortOrder<Item>;
760
- /**
761
- * Lower limit to query shard space.
762
- *
763
- * Only valid if the query is constrained along the dimension used by the
764
- * {@link Config | `EntityManager.config.entities.<entityToken>.sharding.timestamptokens.timestamp`}
765
- * function to generate `shardKey`.
766
- *
767
- * @defaultValue `0`
768
- */
769
- timestampFrom?: number;
770
- /**
771
- * Upper limit to query shard space.
772
- *
773
- * Only valid if the query is constrained along the dimension used by the
774
- * {@link Config | `EntityManager.config.entities.<entityToken>.sharding.timestamptokens.timestamp`}
775
- * function to generate `shardKey`.
776
- *
777
- * @defaultValue `Date.now()`
778
- */
779
- timestampTo?: number;
780
- /**
781
- * The maximum number of shards to query in parallel. Overrides options `throttle`.
782
- *
783
- * @defaultValue `options.throttle`
784
- */
785
- throttle?: number;
786
- }
787
-
788
- /**
789
- * A result returned by a query across multiple shards, where each shard may
790
- * receive multiple page queries via a dynamically-generated {@link ShardQueryFunction | `ShardQueryFunction`}.
791
- *
792
- * @category Query
793
- */
794
- interface QueryResult<Item extends ItemMap<M, HashKey, RangeKey>[EntityToken], EntityToken extends keyof Exactify<M> & string, M extends EntityMap, HashKey extends string, RangeKey extends string> {
795
- /** Total number of records returned across all shards. */
796
- count: number;
797
- /** The returned records. */
798
- items: Item[];
799
- /**
800
- * A compressed, two-layer map of page keys, used to query the next page of
801
- * data for a given sort key on each shard of a given hash key.
802
- */
803
- pageKeyMap: string;
804
- }
805
-
806
808
  /**
807
809
  * The EntityManager class applies a configuration-driven sharded data model &
808
810
  * query strategy to NoSql data.
@@ -900,6 +902,7 @@ declare abstract class BaseShardQueryMapBuilder<IndexParams, Item extends ItemMa
900
902
  * @returns - The {@link ShardQueryMap | `ShardQueryMap`} object.
901
903
  */
902
904
  build(): ShardQueryMap<Item>;
905
+ query(options: BuilderQueryOptions<Item, EntityToken, M, HashKey, RangeKey>): Promise<QueryResult<Item, EntityToken, M, HashKey, RangeKey>>;
903
906
  }
904
907
 
905
908
  /**
@@ -27,6 +27,16 @@ class BaseShardQueryMapBuilder {
27
27
  build() {
28
28
  return mapValues(this.indexParamsMap, (indexConfig, indexToken) => this.getShardQueryFunction(indexToken));
29
29
  }
30
+ async query(options) {
31
+ const { entityManager, entityToken, pageKeyMap } = this;
32
+ const shardQueryMap = this.build();
33
+ return await entityManager.query({
34
+ ...options,
35
+ entityToken,
36
+ pageKeyMap,
37
+ shardQueryMap,
38
+ });
39
+ }
30
40
  }
31
41
 
32
42
  export { BaseShardQueryMapBuilder };
package/package.json CHANGED
@@ -131,5 +131,5 @@
131
131
  },
132
132
  "type": "module",
133
133
  "types": "dist/index.d.ts",
134
- "version": "6.7.1"
134
+ "version": "6.7.2"
135
135
  }