dyno-table 1.7.0 → 2.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.
Files changed (45) hide show
  1. package/dist/{batch-builder-Dz1yPGrJ.d.ts → batch-builder-BOBwOIUE.d.ts} +1 -1
  2. package/dist/{batch-builder-DNsz6zvh.d.cts → batch-builder-CKYnMRyz.d.cts} +1 -1
  3. package/dist/{builder-types-DlaUSc-b.d.cts → builder-types-BTVhQSHI.d.cts} +55 -5
  4. package/dist/{builder-types-B_tCpn9F.d.ts → builder-types-CzuLR4Th.d.ts} +55 -5
  5. package/dist/builders/condition-check-builder.d.cts +1 -1
  6. package/dist/builders/condition-check-builder.d.ts +1 -1
  7. package/dist/builders/delete-builder.d.cts +2 -2
  8. package/dist/builders/delete-builder.d.ts +2 -2
  9. package/dist/builders/paginator.cjs +21 -3
  10. package/dist/builders/paginator.cjs.map +1 -1
  11. package/dist/builders/paginator.d.cts +3 -3
  12. package/dist/builders/paginator.d.ts +3 -3
  13. package/dist/builders/paginator.js +21 -3
  14. package/dist/builders/paginator.js.map +1 -1
  15. package/dist/builders/put-builder.d.cts +2 -2
  16. package/dist/builders/put-builder.d.ts +2 -2
  17. package/dist/builders/query-builder.cjs +115 -22
  18. package/dist/builders/query-builder.cjs.map +1 -1
  19. package/dist/builders/query-builder.d.cts +2 -2
  20. package/dist/builders/query-builder.d.ts +2 -2
  21. package/dist/builders/query-builder.js +115 -22
  22. package/dist/builders/query-builder.js.map +1 -1
  23. package/dist/builders/transaction-builder.d.cts +1 -1
  24. package/dist/builders/transaction-builder.d.ts +1 -1
  25. package/dist/builders/update-builder.d.cts +1 -1
  26. package/dist/builders/update-builder.d.ts +1 -1
  27. package/dist/entity.d.cts +4 -4
  28. package/dist/entity.d.ts +4 -4
  29. package/dist/index.cjs +131 -36
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +4 -4
  32. package/dist/index.d.ts +4 -4
  33. package/dist/index.js +131 -36
  34. package/dist/index.js.map +1 -1
  35. package/dist/{query-builder-C6XjVEFH.d.ts → query-builder-CaHzZmDf.d.ts} +31 -29
  36. package/dist/{query-builder-BDuHHrb-.d.cts → query-builder-DFkxojBM.d.cts} +31 -29
  37. package/dist/{table-DAKlzQsK.d.cts → table-CHitMHXE.d.cts} +18 -20
  38. package/dist/{table-BWa4tx63.d.ts → table-m7DQk5dK.d.ts} +18 -20
  39. package/dist/table.cjs +131 -36
  40. package/dist/table.cjs.map +1 -1
  41. package/dist/table.d.cts +4 -4
  42. package/dist/table.d.ts +4 -4
  43. package/dist/table.js +131 -36
  44. package/dist/table.js.map +1 -1
  45. package/package.json +1 -1
package/dist/table.cjs CHANGED
@@ -309,13 +309,31 @@ var Paginator = class {
309
309
  page: this.currentPage
310
310
  };
311
311
  }
312
- effectivePageSize = Math.min(effectivePageSize, remainingItems);
312
+ if (effectivePageSize !== void 0) {
313
+ effectivePageSize = Math.min(effectivePageSize, remainingItems);
314
+ } else {
315
+ effectivePageSize = remainingItems;
316
+ }
317
+ }
318
+ const query = this.queryBuilder.clone();
319
+ if (effectivePageSize !== void 0) {
320
+ query.limit(effectivePageSize);
313
321
  }
314
- const query = this.queryBuilder.clone().limit(effectivePageSize);
315
322
  if (this.lastEvaluatedKey) {
316
323
  query.startFrom(this.lastEvaluatedKey);
317
324
  }
318
- const result = await query.execute();
325
+ const generator = await query.execute();
326
+ const items = [];
327
+ let itemCount = 0;
328
+ for await (const item of generator) {
329
+ if (effectivePageSize !== void 0 && itemCount >= effectivePageSize) {
330
+ break;
331
+ }
332
+ items.push(item);
333
+ itemCount++;
334
+ }
335
+ const lastEvaluatedKey = generator.getLastEvaluatedKey();
336
+ const result = { items, lastEvaluatedKey };
319
337
  this.currentPage += 1;
320
338
  this.lastEvaluatedKey = result.lastEvaluatedKey;
321
339
  this.totalItemsRetrieved += result.items.length;
@@ -554,11 +572,16 @@ var FilterBuilder = class {
554
572
  *
555
573
  * @example
556
574
  * ```typescript
557
- * // Create a paginator for dinosaur records
575
+ * // Create a paginator for dinosaur records with specific page size
558
576
  * const paginator = builder
559
577
  * .filter(op => op.eq('status', 'ACTIVE'))
560
578
  * .paginate(10);
561
579
  *
580
+ * // Create a paginator with automatic DynamoDB paging (no page size limit)
581
+ * const autoPaginator = builder
582
+ * .filter(op => op.eq('status', 'ACTIVE'))
583
+ * .paginate();
584
+ *
562
585
  * // Process pages of dinosaur results
563
586
  * while (paginator.hasNextPage()) {
564
587
  * const page = await paginator.getNextPage();
@@ -567,7 +590,7 @@ var FilterBuilder = class {
567
590
  * }
568
591
  * ```
569
592
  *
570
- * @param pageSize - The number of items to return per page
593
+ * @param pageSize - The number of items to return per page. If not provided, DynamoDB will automatically determine page sizes.
571
594
  * @returns A Paginator instance that manages the pagination state
572
595
  * @see Paginator for more pagination control options
573
596
  */
@@ -588,15 +611,17 @@ var FilterBuilder = class {
588
611
  * .limit(5)
589
612
  * .execute();
590
613
  *
591
- * if (result1.lastEvaluatedKey) {
614
+ * const lastKey = result1.getLastEvaluatedKey();
615
+ * if (lastKey) {
592
616
  * // Continue listing dinosaurs
593
617
  * const result2 = await builder
594
618
  * .filter(op => op.eq('status', 'ACTIVE'))
595
- * .startFrom(result1.lastEvaluatedKey)
619
+ * .startFrom(lastKey)
596
620
  * .limit(5)
597
621
  * .execute();
598
622
  *
599
- * console.log('Additional dinosaurs:', result2.items);
623
+ * const items = await result2.toArray();
624
+ * console.log('Additional dinosaurs:', items);
600
625
  * }
601
626
  * ```
602
627
  *
@@ -609,6 +634,72 @@ var FilterBuilder = class {
609
634
  }
610
635
  };
611
636
 
637
+ // src/builders/result-iterator.ts
638
+ var ResultIterator = class {
639
+ constructor(queryBuilder, directExecutor) {
640
+ this.queryBuilder = queryBuilder;
641
+ this.directExecutor = directExecutor;
642
+ this.overallLimit = queryBuilder.getLimit();
643
+ }
644
+ lastEvaluatedKey;
645
+ itemsYielded = 0;
646
+ overallLimit;
647
+ /**
648
+ * Async iterator with automatic pagination
649
+ */
650
+ async *[Symbol.asyncIterator]() {
651
+ let hasMorePages = true;
652
+ while (hasMorePages) {
653
+ const result = await this.directExecutor();
654
+ for (const item of result.items) {
655
+ if (this.overallLimit !== void 0 && this.itemsYielded >= this.overallLimit) {
656
+ return;
657
+ }
658
+ yield item;
659
+ this.itemsYielded++;
660
+ }
661
+ if (result.lastEvaluatedKey !== null && result.lastEvaluatedKey !== void 0) {
662
+ this.lastEvaluatedKey = result.lastEvaluatedKey;
663
+ this.queryBuilder.startFrom(result.lastEvaluatedKey);
664
+ } else if (result.lastEvaluatedKey === null) {
665
+ if (this.lastEvaluatedKey === void 0) {
666
+ this.lastEvaluatedKey = null;
667
+ }
668
+ }
669
+ hasMorePages = !!result.lastEvaluatedKey && (this.overallLimit === void 0 || this.itemsYielded < this.overallLimit);
670
+ }
671
+ }
672
+ /**
673
+ * Convert to array (loads all pages).
674
+ *
675
+ * ```ts
676
+ * const result = await table.query({ pk: "foo" }).execute();
677
+ * const allItemsFromDynamo = await result.toArray();
678
+ * ```
679
+ *
680
+ * Note: This will load all pages into memory. For large datasets, consider using async iteration instead.
681
+ *```ts
682
+ * const result = await table.query({ pk: "foo" }).execute();
683
+ * for await (const item of result) {
684
+ * // Process each item
685
+ * }
686
+ * ```
687
+ */
688
+ async toArray() {
689
+ const items = [];
690
+ for await (const item of this) {
691
+ items.push(item);
692
+ }
693
+ return items;
694
+ }
695
+ /**
696
+ * Get the last evaluated key
697
+ */
698
+ getLastEvaluatedKey() {
699
+ return this.lastEvaluatedKey === null ? void 0 : this.lastEvaluatedKey;
700
+ }
701
+ };
702
+
612
703
  // src/builders/query-builder.ts
613
704
  var QueryBuilder = class _QueryBuilder extends FilterBuilder {
614
705
  keyCondition;
@@ -730,16 +821,16 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
730
821
  return clone;
731
822
  }
732
823
  /**
733
- * Executes the query against DynamoDB.
824
+ * Executes the query against DynamoDB and returns a generator that behaves like an array.
734
825
  *
735
- * The method returns both the matched items and, if there are more results,
736
- * a lastEvaluatedKey that can be used with startFrom() to continue the query.
826
+ * The generator automatically handles pagination and provides array-like methods
827
+ * for processing results efficiently without loading everything into memory at once.
737
828
  *
738
829
  * @example
739
830
  * ```typescript
740
831
  * try {
741
- * // Find active carnivores in specific habitat
742
- * const result = await new QueryBuilder(executor, eq('habitatId', 'PADDOCK-A'))
832
+ * // Find active carnivores with automatic pagination
833
+ * const results = await new QueryBuilder(executor, eq('habitatId', 'PADDOCK-A'))
743
834
  * .useIndex('species-status-index')
744
835
  * .filter(op =>
745
836
  * op.and([
@@ -749,25 +840,27 @@ var QueryBuilder = class _QueryBuilder extends FilterBuilder {
749
840
  * ])
750
841
  * )
751
842
  * .sortDescending()
752
- * .limit(5)
753
843
  * .execute();
754
844
  *
755
- * console.log(`Found ${result.items.length} dangerous dinosaurs`);
756
- *
757
- * if (result.lastEvaluatedKey) {
758
- * console.log('Additional threats detected');
845
+ * // Use like an array with automatic pagination
846
+ * for await (const dinosaur of results) {
847
+ * console.log(`Processing ${dinosaur.name}`);
759
848
  * }
849
+ *
850
+ * // Or convert to array and use array methods
851
+ * const allItems = await results.toArray();
852
+ * const dangerousOnes = allItems.filter(dino => dino.aggressionLevel > 9);
853
+ * const totalCount = allItems.length;
760
854
  * } catch (error) {
761
855
  * console.error('Security scan failed:', error);
762
856
  * }
763
857
  * ```
764
858
  *
765
- * @returns A promise that resolves to an object containing:
766
- * - items: Array of items matching the query
767
- * - lastEvaluatedKey: Token for continuing the query, if more items exist
859
+ * @returns A promise that resolves to a ResultGenerator that behaves like an array
768
860
  */
769
861
  async execute() {
770
- return this.executor(this.keyCondition, this.options);
862
+ const directExecutor = () => this.executor(this.keyCondition, this.options);
863
+ return new ResultIterator(this, directExecutor);
771
864
  }
772
865
  };
773
866
 
@@ -3050,41 +3143,43 @@ var ScanBuilder = class _ScanBuilder extends FilterBuilder {
3050
3143
  return clone;
3051
3144
  }
3052
3145
  /**
3053
- * Executes the scan against DynamoDB.
3146
+ * Executes the scan against DynamoDB and returns a generator that behaves like an array.
3054
3147
  *
3055
- * The method returns both the matched items and, if there are more results,
3056
- * a lastEvaluatedKey that can be used with startFrom() to continue the scan.
3148
+ * The generator automatically handles pagination and provides array-like methods
3149
+ * for processing results efficiently without loading everything into memory at once.
3057
3150
  *
3058
3151
  * @example
3059
3152
  * ```typescript
3060
3153
  * try {
3061
- * // Find all dinosaurs with high aggression levels
3062
- * const result = await new ScanBuilder(executor)
3154
+ * // Find all dinosaurs with high aggression levels with automatic pagination
3155
+ * const results = await new ScanBuilder(executor)
3063
3156
  * .filter(op =>
3064
3157
  * op.and([
3065
3158
  * op.eq('status', 'ACTIVE'),
3066
3159
  * op.gt('aggressionLevel', 7)
3067
3160
  * ])
3068
3161
  * )
3069
- * .limit(20)
3070
3162
  * .execute();
3071
3163
  *
3072
- * console.log(`Found ${result.items.length} potentially dangerous dinosaurs`);
3073
- *
3074
- * if (result.lastEvaluatedKey) {
3075
- * console.log('More results available');
3164
+ * // Use like an array with automatic pagination
3165
+ * for await (const dinosaur of results) {
3166
+ * console.log(`Processing dangerous dinosaur: ${dinosaur.name}`);
3076
3167
  * }
3168
+ *
3169
+ * // Or convert to array and use array methods
3170
+ * const allItems = await results.toArray();
3171
+ * const criticalThreats = allItems.filter(dino => dino.aggressionLevel > 9);
3172
+ * const totalCount = allItems.length;
3077
3173
  * } catch (error) {
3078
3174
  * console.error('Security scan failed:', error);
3079
3175
  * }
3080
3176
  * ```
3081
3177
  *
3082
- * @returns A promise that resolves to an object containing:
3083
- * - items: Array of items matching the scan criteria
3084
- * - lastEvaluatedKey: Token for continuing the scan, if more items exist
3178
+ * @returns A promise that resolves to a ResultGenerator that behaves like an array
3085
3179
  */
3086
3180
  async execute() {
3087
- return this.executor(this.options);
3181
+ const directExecutor = () => this.executor(this.options);
3182
+ return new ResultIterator(this, directExecutor);
3088
3183
  }
3089
3184
  };
3090
3185