@izara_project/izara-core-library-asynchronous-flow 1.0.14 → 1.0.16

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/index.js CHANGED
@@ -33,7 +33,10 @@ module.exports = {
33
33
  // Awaiting Multiple Steps
34
34
  createAwaitingMultipleStepsWithAdditionalAttributes: asyncFlowSharedLib.createAwaitingMultipleStepsWithAdditionalAttributes,
35
35
  createAwaitingMultipleSteps: asyncFlowSharedLib.createAwaitingMultipleSteps,
36
-
36
+ findPendingStepIdsAwaitingMultipleSteps: asyncFlowSharedLib.findPendingStepIdsAwaitingMultipleSteps,
37
+ findPendingStepsAwaitingMultipleSteps: asyncFlowSharedLib.findPendingStepIdsAwaitingMultipleSteps,
38
+ findPendingStepAwaitingMultipleSteps: asyncFlowSharedLib.findPendingStepIdsAwaitingMultipleSteps,
39
+ findAwaitingMultipleStepByPending: asyncFlowSharedLib.findAwaitingMultipleStepByPending,
37
40
  // Awaiting Step
38
41
  createAwaitingStep: asyncFlowSharedLib.createAwaitingStep,
39
42
  findPendingStepIdsAwaitingStep: asyncFlowSharedLib.findPendingStepIdsAwaitingStep,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@izara_project/izara-core-library-asynchronous-flow",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "Shared asynchronous flow logic",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -28,6 +28,13 @@ const sqsSharedLib = require('@izara_project/izara-core-library-sqs');
28
28
  // External service interactions
29
29
  const { sqs } = require('@izara_project/izara-core-library-external-request');
30
30
 
31
+
32
+ /**
33
+ * Create a field name for storing the unique-request id, with optional prefix.
34
+ * @param {string} prefix
35
+ * @param {string} [uniqueRequestIdFieldName='UniqueRequestId']
36
+ * @returns {string}
37
+ */
31
38
  function createFieldNameUniqueRequestId(
32
39
  prefix,
33
40
  uniqueRequestIdFieldName = 'UniqueRequestId'
@@ -35,6 +42,13 @@ function createFieldNameUniqueRequestId(
35
42
  return prefix + uniqueRequestIdFieldName;
36
43
  }
37
44
 
45
+ /**
46
+ * Create a concatenated awaitingStepId from composite parts.
47
+ * @param {string} partitionKey
48
+ * @param {string|number} sortId
49
+ * @param {string} [prefix=""]
50
+ * @returns {string}
51
+ */
38
52
  function createConcatenatedAwaitingStepId(
39
53
  partitionKey,
40
54
  sortId,
@@ -43,6 +57,12 @@ function createConcatenatedAwaitingStepId(
43
57
  return prefix + partitionKey + "_" + sortId
44
58
  }
45
59
 
60
+ /**
61
+ * Create a concatenated pendingStepId from parent/child ids.
62
+ * @param {string} parentId
63
+ * @param {string} childId
64
+ * @returns {string}
65
+ */
46
66
  function createConcatenatedPendingStepId(
47
67
  parentId,
48
68
  childId
@@ -50,6 +70,12 @@ function createConcatenatedPendingStepId(
50
70
  return parentId + "_" + childId
51
71
  }
52
72
 
73
+ /**
74
+ * Create a simple awaitingStepId (prefix + partitionKey).
75
+ * @param {string} partitionKey
76
+ * @param {string} [prefix=""]
77
+ * @returns {string}
78
+ */
53
79
  function createAwaitingStepId(
54
80
  partitionKey,
55
81
  prefix = ""
@@ -57,6 +83,12 @@ function createAwaitingStepId(
57
83
  return prefix + partitionKey
58
84
  }
59
85
 
86
+ /**
87
+ * Create a simple pendingStepId (prefix + identifierId).
88
+ * @param {string} identifierId
89
+ * @param {string} [prefix=""]
90
+ * @returns {string}
91
+ */
60
92
  function createPendingStepId(
61
93
  identifierId,
62
94
  prefix = ""
@@ -64,6 +96,14 @@ function createPendingStepId(
64
96
  return prefix + identifierId
65
97
  }
66
98
 
99
+ /**
100
+ * Remove the known prefix from a pendingStepId and validate it is not equal to the prefix.
101
+ * If prefix is empty, the original ID is returned.
102
+ * @param {string} pendingStepId
103
+ * @param {string} [prefix=""]
104
+ * @returns {string}
105
+ * @throws {NoRetryError} If the stripped value equals the prefix (invalid)
106
+ */
67
107
  function explodePendingStepId(
68
108
  pendingStepId,
69
109
  prefix = ""
@@ -84,20 +124,40 @@ function explodePendingStepId(
84
124
  }
85
125
 
86
126
  // copy from izara-core-library-trigger-cache
127
+ /**
128
+ * Build the field name that stores "cache complete" marker.
129
+ * @param {string} [prefix='cache']
130
+ * @returns {string}
131
+ */
87
132
  function createFieldNameCacheComplete(prefix = 'cache') {
88
133
  return prefix + 'CacheComplete';
89
134
  }
135
+
136
+ /**
137
+ * Build the field name that stores a cache "status".
138
+ * @param {string} [prefix='cache']
139
+ * @returns {string}
140
+ */
90
141
  function createFieldNameStatus(prefix = 'cache') {
91
142
  return prefix + 'Status';
92
143
  }
93
144
 
145
+
94
146
  //====================================== AwaitingMultipleSteps
95
147
  // AwaitingMultipleSteps is when a flow is awaiting multiple external flows before it can continue
96
148
  // One awaitingStepId can have multiple pendingStepIds that are awaiting it
97
149
  // One pendingStepId can have multiple awaitingStepIds it is awaiting
98
150
  // logic can prepend any prefix to awaitingStepId if want to be share one table and differentiate different external step ids
99
151
 
100
- //not yet used ?
152
+ /**
153
+ * Create multiple awaiting records with optional per-record additional attributes.
154
+ * Writes to both "AwaitingMultipleSteps" and "AwaitingMultipleStepByPending".
155
+ * @async
156
+ * @param {IzContext} _izContext
157
+ * @param {AwaitingMultiInputRecord[]} records
158
+ * @param {string} pendingStepId
159
+ * @returns {Promise<void>}
160
+ */
101
161
  async function createAwaitingMultipleStepsWithAdditionalAttributes(
102
162
  _izContext,
103
163
  records, // array of object including properties: awaitingStepId / (optional) additionalAttributes
@@ -142,6 +202,15 @@ async function createAwaitingMultipleStepsWithAdditionalAttributes(
142
202
 
143
203
  }
144
204
 
205
+ /**
206
+ * Create multiple awaiting records given an array of awaitingStepIds.
207
+ * Writes to both "AwaitingMultipleSteps" and "AwaitingMultipleStepByPending".
208
+ * @async
209
+ * @param {IzContext} _izContext
210
+ * @param {string[]} records - array of awaitingStepIds
211
+ * @param {string} pendingStepId
212
+ * @returns {Promise<void>}
213
+ */
145
214
  async function createAwaitingMultipleSteps(
146
215
  _izContext,
147
216
  records, // array of awaitingStepIds
@@ -188,11 +257,130 @@ async function createAwaitingMultipleSteps(
188
257
 
189
258
  }
190
259
 
260
+ /**
261
+ * Find all pendingStepIds that are waiting on a given awaitingStepId (multiple).
262
+ * @async
263
+ * @param {IzContext} _izContext
264
+ * @param {string} awaitingStepId
265
+ * @returns {Promise<string[]>}
266
+ */
267
+ async function findPendingStepIdsAwaitingMultipleSteps(
268
+ _izContext,
269
+ awaitingStepId
270
+ ) {
271
+
272
+ let pendingStepIds = [];
273
+
274
+ let listPendingStepIds = await dynamodbSharedLib.query(
275
+ _izContext,
276
+ await dynamodbSharedLib.tableName(_izContext, "AwaitingMultipleSteps"),
277
+ {
278
+ awaitingStepId: awaitingStepId
279
+ }
280
+ );
281
+
282
+ for (let idx = 0; idx < listPendingStepIds.Items.length; idx++) {
283
+ pendingStepIds.push(listPendingStepIds.Items[idx].pendingStepId)
284
+ }
285
+
286
+ return pendingStepIds
287
+ }
288
+
289
+ /**
290
+ * Return the raw items waiting on a given awaitingStepId (multiple).
291
+ * @async
292
+ * @param {IzContext} _izContext
293
+ * @param {string} awaitingStepId
294
+ * @returns {Promise<AwaitingMultipleStepsItem[]>}
295
+ */
296
+ async function findPendingStepsAwaitingMultipleSteps(
297
+ _izContext,
298
+ awaitingStepId
299
+ ) {
300
+
301
+ let listPendingSteps = await dynamodbSharedLib.query(
302
+ _izContext,
303
+ await dynamodbSharedLib.tableName(_izContext, "AwaitingMultipleSteps"),
304
+ {
305
+ awaitingStepId: awaitingStepId
306
+ }
307
+ );
308
+ _izContext.logger.debug("Record of awaitingStepId", listPendingSteps);
309
+ return listPendingSteps.Items;
310
+ }
311
+
312
+ /**
313
+ * Fetch exactly one pending step for a given awaitingStepId (throws if not 1).
314
+ * @async
315
+ * @param {IzContext} _izContext
316
+ * @param {string} awaitingStepId
317
+ * @returns {Promise<AwaitingMultipleStepsItem>}
318
+ * @throws {NoRetryError} if there is not exactly one item
319
+ */
320
+ async function findPendingStepAwaitingMultipleSteps(
321
+ _izContext,
322
+ awaitingStepId
323
+ ) {
324
+
325
+ let listPendingSteps = await dynamodbSharedLib.query(
326
+ _izContext,
327
+ await dynamodbSharedLib.tableName(_izContext, "AwaitingMultipleSteps"),
328
+ {
329
+ awaitingStepId: awaitingStepId
330
+ }
331
+ );
332
+ _izContext.logger.debug("Record of awaitingStepId", listPendingSteps)
333
+
334
+ if (listPendingSteps.Items.length !== 1) {
335
+ throw new NoRetryError("listPendingSteps not equals 1")
336
+ };
337
+ return listPendingSteps.Items[0];
338
+ }
339
+
340
+ // Use case:
341
+ // Use only after checkAllAwaitingStepsFinished
342
+ // Do NOT delete records in both tables (AwaitingMultipleSteps, AwaitingMultipleStepByPending) if AwaitingMultipleSteps is not yet finished
343
+ // Delete records from both tables only when checkAllAwaitingStepsFinished = true
344
+ // Example usage: flow validateCart lambda ProcessCartOrderFromTraversal
345
+ /**
346
+ * Given a pendingStepId, return all awaiting steps (by the ByPending table).
347
+ * Use only after confirming all awaiting steps are finished, and clean up both tables accordingly.
348
+ * @async
349
+ * @param {IzContext} _izContext
350
+ * @param {string} pendingStepId
351
+ * @returns {Promise<AwaitingMultipleStepByPendingItem[]>}
352
+ */
353
+ async function findAwaitingMultipleStepByPending(
354
+ _izContext,
355
+ pendingStepId
356
+ ) {
357
+
358
+ let listAwitingSteps = await dynamodbSharedLib.query(
359
+ _izContext,
360
+ await dynamodbSharedLib.tableName(_izContext, "AwaitingMultipleStepByPending"),
361
+ {
362
+ pendingStepId: pendingStepId
363
+ }
364
+ );
365
+ _izContext.logger.debug("Record of AwaitingMultipleStepByPending", listAwitingSteps);
366
+ return listAwitingSteps.Items;
367
+ }
368
+
191
369
  //====================================== AwaitingStep //======================================
192
370
  // AwaitingStep is when a flow is awaiting one external flow, and will continue it's flow once that one external flow is complete
193
371
  // One awaitingStepId can have multiple pendingStepIds that are awaiting it
194
372
  // logic can prepend any prefix to awaitingStepId if want to be share one table and differentiate different external step ids
195
373
 
374
+ /**
375
+ * Create a single AwaitingStep record, optionally attaching additional attributes and callingFlowConfig.
376
+ * @async
377
+ * @param {IzContext} _izContext
378
+ * @param {string} awaitingStepId
379
+ * @param {string} pendingStepId
380
+ * @param {Attrs} [additionalAttributes={}]
381
+ * @param {Attrs} [callingFlowConfig={}]
382
+ * @returns {Promise<void>}
383
+ */
196
384
  async function createAwaitingStep(
197
385
  _izContext,
198
386
  awaitingStepId,
@@ -228,7 +416,13 @@ async function createAwaitingStep(
228
416
  );
229
417
  }
230
418
 
231
-
419
+ /**
420
+ * Find all pendingStepIds that are waiting on a given awaitingStepId (single).
421
+ * @async
422
+ * @param {IzContext} _izContext
423
+ * @param {string} awaitingStepId
424
+ * @returns {Promise<string[]>}
425
+ */
232
426
  async function findPendingStepIdsAwaitingStep(
233
427
  _izContext,
234
428
  awaitingStepId
@@ -251,6 +445,13 @@ async function findPendingStepIdsAwaitingStep(
251
445
  return pendingStepIds
252
446
  }
253
447
 
448
+ /**
449
+ * Return the raw items waiting on a given awaitingStepId (single).
450
+ * @async
451
+ * @param {IzContext} _izContext
452
+ * @param {string} awaitingStepId
453
+ * @returns {Promise<AwaitingStepItem[]>}
454
+ */
254
455
  async function findPendingStepsAwaitingStep(
255
456
  _izContext,
256
457
  awaitingStepId
@@ -267,6 +468,14 @@ async function findPendingStepsAwaitingStep(
267
468
  return listPendingSteps.Items;
268
469
  }
269
470
 
471
+ /**
472
+ * Fetch exactly one pending step for a given awaitingStepId (throws if not 1).
473
+ * @async
474
+ * @param {IzContext} _izContext
475
+ * @param {string} awaitingStepId
476
+ * @returns {Promise<AwaitingStepItem>}
477
+ * @throws {NoRetryError} if there is not exactly one item
478
+ */
270
479
  async function findPendingStepAwaitingStep(
271
480
  _izContext,
272
481
  awaitingStepId
@@ -287,7 +496,15 @@ async function findPendingStepAwaitingStep(
287
496
  return listPendingSteps.Items[0];
288
497
  }
289
498
 
290
- // for get callingFlow save in awaitingStpe and remove property callingFlow in awaitingStpe
499
+ // for get callingFlow save in awaitingStep and remove property callingFlow in awaitingStep
500
+ /**
501
+ * Get one awaiting step by id and also extract (and remove) its callingFlowConfig (if present).
502
+ * Returns a tuple: [AwaitingStepItemWithoutCallingFlow, callingFlowConfig|null].
503
+ * @async
504
+ * @param {IzContext} _izContext
505
+ * @param {string} awaitingStepId
506
+ * @returns {Promise<[AwaitingStepItem, Attrs|null]>}
507
+ */
291
508
  async function findPendingStepAwaitingStepWithCallingFlow(
292
509
  _izContext,
293
510
  awaitingStepId,
@@ -300,7 +517,7 @@ async function findPendingStepAwaitingStepWithCallingFlow(
300
517
  );
301
518
 
302
519
  // callingFlowConfig.
303
- // cleaning object awaitingStep not have callingFlowComfig after return.
520
+ // cleaning object awaitingStep not have callingFlowConfig after return.
304
521
  if (awaitingStep.hasOwnProperty("callingFlowConfig")) {
305
522
  callingFlowConfig = awaitingStep.callingFlowConfig
306
523
  delete awaitingStep.callingFlowConfig
@@ -310,29 +527,51 @@ async function findPendingStepAwaitingStepWithCallingFlow(
310
527
  return [awaitingStep, callingFlowConfig]
311
528
  }
312
529
 
530
+ /**
531
+ * Mark current awaiting step as complete (in *_ByPending), then check if all awaiting steps are done.
532
+ * Returns true if all are finished; false otherwise.
533
+ * @async
534
+ * @param {IzContext} _izContext
535
+ * @param {string} pendingStepId
536
+ * @param {string|null} [currentAwaitingStepId=null]
537
+ * @param {any[]} [errorsFound=[]]
538
+ * @param {Attrs} [additionalAttributes={}]
539
+ * @returns {Promise<boolean>}
540
+ */
313
541
  async function checkAllAwaitingStepsFinished(
314
542
  _izContext,
315
543
  pendingStepId,
316
544
  currentAwaitingStepId = null,
317
- errorsFound = []
545
+ errorsFound = [],
546
+ additionalAttributes = {}
318
547
  ) {
319
548
 
320
549
  let remaining = await checkAllAwaitingStepsFinishedWithError(
321
550
  _izContext,
322
551
  pendingStepId,
323
552
  currentAwaitingStepId,
324
- errorsFound
553
+ errorsFound,
554
+ additionalAttributes
325
555
  );
326
556
  return remaining;
327
557
  }
328
558
 
329
-
330
-
559
+ /**
560
+ * Same as checkAllAwaitingStepsFinished but writes errors/additionalAttributes to the *_ByPending row.
561
+ * @async
562
+ * @param {IzContext} _izContext
563
+ * @param {string} pendingStepId
564
+ * @param {string|null} [currentAwaitingStepId=null]
565
+ * @param {any[]} [errorsFound=[]]
566
+ * @param {Attrs} [additionalAttributes={}]
567
+ * @returns {Promise<boolean>}
568
+ */
331
569
  async function checkAllAwaitingStepsFinishedWithError(
332
570
  _izContext,
333
571
  pendingStepId,
334
572
  currentAwaitingStepId = null,
335
- errorsFound = []
573
+ errorsFound = [],
574
+ additionalAttributes = {}
336
575
  ) {
337
576
  _izContext.logger.debug("Lib:checkAllAwaitingStepsFinishedWithError", {
338
577
  pendingStepId: pendingStepId,
@@ -350,7 +589,8 @@ async function checkAllAwaitingStepsFinishedWithError(
350
589
  },
351
590
  {
352
591
  complete: true,
353
- errorsFound: errorsFound
592
+ errorsFound: errorsFound,
593
+ ...additionalAttributes
354
594
  },
355
595
  );
356
596
 
@@ -362,12 +602,12 @@ async function checkAllAwaitingStepsFinishedWithError(
362
602
  pendingStepId: pendingStepId
363
603
  },
364
604
  {
365
- limit: 50 // arbritrary limit so not pull too many results, need >2 because some others might be marked as "complete" = true
605
+ limit: 50 // arbitrary limit so not pull too many results, need >2 because some others might be marked as "complete" = true
366
606
  }
367
607
  );
368
608
  for (let idx = 0; idx < listPendingStepIds.Items.length; idx++) {
369
609
 
370
- // if have error found return errorfound
610
+ // if have error found return errorsFound
371
611
  // wrap function
372
612
 
373
613
  if (currentAwaitingStepId && listPendingStepIds.Items[idx].awaitingStepId == currentAwaitingStepId) {
@@ -409,7 +649,7 @@ async function checkAllAwaitingStepsFinishedWithError(
409
649
  // },
410
650
  // {
411
651
  // indexName: dynamodbSharedLib.tableName(tableName + 'Index'),
412
- // limit: 50 // arbritrary limit so not pull too many results, need >2 because some others might be marked as "complete" = true
652
+ // limit: 50 // arbitrary limit so not pull too many results, need >2 because some others might be marked as "complete" = true
413
653
  // }
414
654
  // );
415
655
  // for (let idx = 0; idx < listPendingStepIds.Items.length; idx++) {
@@ -426,8 +666,13 @@ async function checkAllAwaitingStepsFinishedWithError(
426
666
  // return true;
427
667
  }
428
668
 
429
-
430
-
669
+ /**
670
+ * Remove all awaiting records for a given pendingStepId from both tables.
671
+ * @async
672
+ * @param {IzContext} _izContext
673
+ * @param {string} pendingStepId
674
+ * @returns {Promise<boolean>} true if delete flow processed
675
+ */
431
676
  async function clearAllAwaitingSteps(
432
677
  _izContext,
433
678
  pendingStepId
@@ -476,7 +721,14 @@ async function clearAllAwaitingSteps(
476
721
  return true;
477
722
  }
478
723
 
479
-
724
+ /**
725
+ * Remove a single AwaitingStep record (single dependency table).
726
+ * @async
727
+ * @param {IzContext} _izContext
728
+ * @param {string} awaitingStepId
729
+ * @param {string} pendingStepId
730
+ * @returns {Promise<void>}
731
+ */
480
732
  async function removeAwaitingStep(
481
733
  _izContext,
482
734
  awaitingStepId,
@@ -493,6 +745,16 @@ async function removeAwaitingStep(
493
745
  );
494
746
  }
495
747
 
748
+ /**
749
+ * Remove items for AwaitingMultipleSteps and (conditionally) AwaitingMultipleStepByPending.
750
+ * If errorsFound is empty, delete from ByPending table as well.
751
+ * @async
752
+ * @param {IzContext} _izContext
753
+ * @param {string} awaitingStepId
754
+ * @param {string} pendingStepId
755
+ * @param {any[]} [errorsFound=[]]
756
+ * @returns {Promise<void>}
757
+ */
496
758
  async function removeAwaitingMultipleStep(
497
759
  _izContext,
498
760
  awaitingStepId,
@@ -543,6 +805,17 @@ async function removeAwaitingMultipleStep(
543
805
  }
544
806
 
545
807
  // only works with AwaitingStep, does not work with AwaitingMultipleSteps, need to make new function that checks conditional pass? If pass delete from byPending table too
808
+ /**
809
+ * Remove an AwaitingStep item only if its stored UniqueRequestId matches `checkUniqueRequestId`.
810
+ * Uses a conditional expression; will not error if the condition fails.
811
+ * @async
812
+ * @param {IzContext} _izContext
813
+ * @param {string} awaitingStepId
814
+ * @param {string} pendingStepId
815
+ * @param {string} checkUniqueRequestId
816
+ * @param {string} [prefix=""] - Optional prefix for UniqueRequestId field name
817
+ * @returns {Promise<void>}
818
+ */
546
819
  async function removeAwaitingStepWithCheckUniqueRequestId(
547
820
  _izContext,
548
821
  awaitingStepId,
@@ -581,14 +854,8 @@ async function removeAwaitingStepWithCheckUniqueRequestId(
581
854
  );
582
855
  }
583
856
 
584
-
585
-
586
857
  //====================================== end AwaitingStep
587
858
 
588
-
589
-
590
-
591
-
592
859
  /**
593
860
  * Checks if record has uniqueRequestId set, if not set to this requests uniqueRequestId and continue to process
594
861
  * if already set check if matches this request uniqueRequestId, if yes continue to process, if not then stop processing
@@ -601,6 +868,27 @@ async function removeAwaitingStepWithCheckUniqueRequestId(
601
868
 
602
869
  * @returns [string] [returnStatus, existingRecord]
603
870
  */
871
+
872
+
873
+ /**
874
+ * Coordinate unique-request processing over a record:
875
+ * - If no record: returns ["recordNotFound", {}]
876
+ * - If record exists but no uniqueRequestId: tries to set it via conditional update
877
+ * - If record has a different uniqueRequestId: returns ["stop", existingRecord]
878
+ * - If record has the same uniqueRequestId: returns ["process", existingRecord]
879
+ *
880
+ * Will loop up to 2 attempts to avoid races; throws on 3rd iteration.
881
+ *
882
+ * @async
883
+ * @param {IzContext} _izContext
884
+ * @param {string} tableName - Logical table name known by dynamodbSharedLib.tableName
885
+ * @param {DynamoKey} primaryKey - Primary key for the target record
886
+ * @param {string} [prefix=''] - Optional field-name prefix
887
+ * @param {string|null} [overwriteUniqueRequestId=null] - If provided, use this as the "current" unique request id
888
+ * @param {string} [uniqueRequestIdFieldName="UniqueRequestId"] - Base field name before prefix
889
+ * @returns {Promise<[UniqueRequestStatus, Attrs]>}
890
+ * @throws {NoRetryError} If unable to set uniqueRequestId after 2 tries
891
+ */
604
892
  async function checkUniqueRequestProcessing(
605
893
  _izContext,
606
894
  tableName,
@@ -706,6 +994,17 @@ async function checkUniqueRequestProcessing(
706
994
  };
707
995
 
708
996
  // ----- Helper funtion, common use case in triggerFlow ---------
997
+ /**
998
+ * Convenience wrapper around checkAndGetTimeCacheComplete.
999
+ * Returns [isSameOrUnset, uniqueRequestIdWhenComplete].
1000
+ * @async
1001
+ * @param {IzContext} _izContext
1002
+ * @param {string} fullMainTableName - Fully resolved table name (not logical)
1003
+ * @param {DynamoKey} keyValues
1004
+ * @param {number|string} timeCacheComplete - Caller’s expected cache mark
1005
+ * @param {string} prefix - Field prefix used in cache fields
1006
+ * @returns {Promise<[boolean, string|undefined]>}
1007
+ */
709
1008
  async function checkTimeCacheComplete(
710
1009
  _izContext,
711
1010
  fullMainTableName,
@@ -722,6 +1021,20 @@ async function checkTimeCacheComplete(
722
1021
  );
723
1022
  return [returnValue, uniqueRequestId];
724
1023
  }
1024
+
1025
+ /**
1026
+ * Read cache fields from a record and compare cacheComplete value to caller’s `timeCacheComplete`.
1027
+ * If stored differs (and is present), returns [false, storedValue].
1028
+ * Otherwise returns [true, storedValue, uniqueRequestId].
1029
+ * @async
1030
+ * @param {IzContext} _izContext
1031
+ * @param {string} fullMainTableName - Fully resolved table name (not logical)
1032
+ * @param {DynamoKey} keyValues
1033
+ * @param {number|string} timeCacheComplete
1034
+ * @param {string} prefix
1035
+ * @returns {Promise<[boolean, any, string|undefined]>}
1036
+ * @throws {NoRetryError} If record cannot be fetched
1037
+ */
725
1038
  async function checkAndGetTimeCacheComplete(
726
1039
  _izContext,
727
1040
  fullMainTableName,
@@ -774,6 +1087,16 @@ async function checkAndGetTimeCacheComplete(
774
1087
 
775
1088
 
776
1089
  // ----- shared both stored cache and triggered cache, check uniqueRequestId changed ---------
1090
+ /**
1091
+ * Ensure the cache object’s "uniqueRequestIdCompleteFieldName" equals the given checkUniqueRequestId.
1092
+ * @async
1093
+ * @param {IzContext} _izContext
1094
+ * @param {string} fullMainTableName
1095
+ * @param {DynamoKey} keyValues
1096
+ * @param {string} checkUniqueRequestId
1097
+ * @param {string} uniqueRequestIdCompleteFieldName
1098
+ * @returns {Promise<boolean>}
1099
+ */
777
1100
  async function checkCacheUniqueRequestId(
778
1101
  _izContext,
779
1102
  fullMainTableName,
@@ -797,10 +1120,6 @@ async function checkCacheUniqueRequestId(
797
1120
  }
798
1121
 
799
1122
 
800
-
801
-
802
-
803
-
804
1123
  // use shared findPendingStepIdsAwaitingStep
805
1124
  // module.exports.findPendingStepIdsAwaitingStepM = async (
806
1125
  // _izContext,
@@ -826,8 +1145,6 @@ async function checkCacheUniqueRequestId(
826
1145
  // }
827
1146
 
828
1147
 
829
-
830
-
831
1148
  // use shared removeAwaitingStep
832
1149
  // module.exports.removeAwaitingStep = async (
833
1150
  // _izContext,
@@ -853,6 +1170,17 @@ async function checkCacheUniqueRequestId(
853
1170
 
854
1171
  //====================================== end Multiple Lambda Invocations (Logic pagination of handling results)
855
1172
 
1173
+ /**
1174
+ * Validate and normalize a DynamoDB pagination startKey object.
1175
+ * Ensures partitionKeyFieldName/sortKeyFieldName are alphanumeric/underscore/hyphen.
1176
+ * If startKey is empty object, returns `null` for easier processing downstream.
1177
+ * @param {IzContext} _izContext
1178
+ * @param {Attrs|null|undefined} startKey
1179
+ * @param {string} partitionKeyFieldName
1180
+ * @param {string} sortKeyFieldName
1181
+ * @returns {Attrs|null}
1182
+ * @throws {NoRetryError} On invalid field names or malformed startKey
1183
+ */
856
1184
  function validateStartKeyParam(
857
1185
  _izContext,
858
1186
  startKey,
@@ -880,7 +1208,19 @@ function validateStartKeyParam(
880
1208
  return startKey;
881
1209
  }
882
1210
 
883
-
1211
+ /**
1212
+ * For paginated multi-invocation flows: validates the current invocation count,
1213
+ * attaches the (optional) next startKey to the message, increments the count,
1214
+ * and re-enqueues the message to the specified SQS queue.
1215
+ * @async
1216
+ * @param {IzContext} _izContext
1217
+ * @param {Attrs} messageProperty - The message body object to re-dispatch
1218
+ * @param {Attrs} [passOnStartKey={}] - Optional startKey to pass along
1219
+ * @param {number} numberInvocation - Current invocation count
1220
+ * @param {string} queueName - Logical queue name resolvable via sqsSharedLib.sqsQueueUrl
1221
+ * @returns {Promise<void>}
1222
+ * @throws {NoRetryError} If `numberInvocation` exceeds internal safety limit
1223
+ */
884
1224
  async function validateMultipleInvocations(
885
1225
  _izContext,
886
1226
  messageProperty,
@@ -939,6 +1279,10 @@ module.exports = {
939
1279
  checkAllAwaitingStepsFinished,
940
1280
  clearAllAwaitingSteps,
941
1281
  removeAwaitingMultipleStep,
1282
+ findPendingStepIdsAwaitingMultipleSteps,
1283
+ findPendingStepsAwaitingMultipleSteps,
1284
+ findPendingStepAwaitingMultipleSteps,
1285
+ findAwaitingMultipleStepByPending,
942
1286
 
943
1287
  // AwaitingStep functions
944
1288
  createAwaitingStep,