@plotday/twister 0.56.0 → 0.58.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 (331) hide show
  1. package/README.md +53 -44
  2. package/bin/commands/create.js +9 -14
  3. package/bin/commands/create.js.map +1 -1
  4. package/bin/commands/deploy.js +2 -0
  5. package/bin/commands/deploy.js.map +1 -1
  6. package/bin/commands/generate.js +8 -5
  7. package/bin/commands/generate.js.map +1 -1
  8. package/bin/index.js +2 -2
  9. package/bin/index.js.map +1 -1
  10. package/bin/templates/AGENTS.template.md +110 -94
  11. package/bin/templates/README.template.md +36 -33
  12. package/cli/templates/AGENTS.template.md +110 -94
  13. package/cli/templates/README.template.md +36 -33
  14. package/dist/connector.d.ts +24 -17
  15. package/dist/connector.d.ts.map +1 -1
  16. package/dist/connector.js +19 -12
  17. package/dist/connector.js.map +1 -1
  18. package/dist/docs/assets/hierarchy.js +1 -1
  19. package/dist/docs/assets/navigation.js +1 -1
  20. package/dist/docs/assets/search.js +1 -1
  21. package/dist/docs/classes/index.Connector.html +66 -60
  22. package/dist/docs/classes/index.FileNotFoundError.html +2 -2
  23. package/dist/docs/classes/index.Files.html +4 -4
  24. package/dist/docs/classes/index.Imap.html +10 -10
  25. package/dist/docs/classes/index.Options.html +2 -2
  26. package/dist/docs/classes/index.Smtp.html +6 -6
  27. package/dist/docs/classes/tool.ITool.html +2 -2
  28. package/dist/docs/classes/tool.Tool.html +23 -23
  29. package/dist/docs/classes/tools_ai.AI.html +5 -5
  30. package/dist/docs/classes/tools_callbacks.Callbacks.html +8 -8
  31. package/dist/docs/classes/tools_integrations.Integrations.html +26 -12
  32. package/dist/docs/classes/tools_network.Network.html +9 -9
  33. package/dist/docs/classes/tools_plot.Plot.html +34 -33
  34. package/dist/docs/classes/tools_store.Store.html +8 -8
  35. package/dist/docs/classes/tools_tasks.Tasks.html +6 -6
  36. package/dist/docs/classes/tools_twists.Twists.html +12 -11
  37. package/dist/docs/classes/twist.Twist.html +28 -28
  38. package/dist/docs/documents/Building_Connectors.html +42 -28
  39. package/dist/docs/documents/Built-in_Tools.html +170 -67
  40. package/dist/docs/documents/CLI_Reference.html +68 -47
  41. package/dist/docs/documents/Core_Concepts.html +52 -81
  42. package/dist/docs/documents/Getting_Started.html +28 -31
  43. package/dist/docs/documents/MULTI_USER_AUTH.html +45 -0
  44. package/dist/docs/documents/Runtime_Environment.html +13 -12
  45. package/dist/docs/documents/SYNC_STRATEGIES.html +373 -0
  46. package/dist/docs/enums/plot.ActionType.html +9 -9
  47. package/dist/docs/enums/plot.ActorType.html +4 -4
  48. package/dist/docs/enums/plot.ConferencingProvider.html +6 -6
  49. package/dist/docs/enums/plot.ThemeColor.html +9 -9
  50. package/dist/docs/enums/tag.Tag.html +3 -3
  51. package/dist/docs/enums/tools_ai.AIModel.html +3 -3
  52. package/dist/docs/enums/tools_integrations.AuthProvider.html +13 -13
  53. package/dist/docs/enums/tools_plot.ContactAccess.html +2 -2
  54. package/dist/docs/enums/tools_plot.FocusAccess.html +3 -3
  55. package/dist/docs/enums/tools_plot.LinkAccess.html +3 -3
  56. package/dist/docs/enums/tools_plot.ThreadAccess.html +4 -4
  57. package/dist/docs/functions/index.Uuid.Generate.html +1 -1
  58. package/dist/docs/functions/utils_hash.quickHash.html +1 -1
  59. package/dist/docs/hierarchy.html +1 -1
  60. package/dist/docs/index.html +7 -8
  61. package/dist/docs/interfaces/tools_ai.AIRequest.html +13 -13
  62. package/dist/docs/interfaces/tools_ai.AIResponse.html +9 -9
  63. package/dist/docs/interfaces/tools_ai.FilePart.html +5 -5
  64. package/dist/docs/interfaces/tools_ai.ImagePart.html +4 -4
  65. package/dist/docs/interfaces/tools_ai.ReasoningPart.html +4 -4
  66. package/dist/docs/interfaces/tools_ai.RedactedReasoningPart.html +3 -3
  67. package/dist/docs/interfaces/tools_ai.TextPart.html +3 -3
  68. package/dist/docs/interfaces/tools_ai.ToolCallPart.html +5 -5
  69. package/dist/docs/interfaces/tools_ai.ToolExecutionOptions.html +4 -4
  70. package/dist/docs/interfaces/tools_ai.ToolResultPart.html +5 -5
  71. package/dist/docs/interfaces/tools_twists.TwistSource.html +3 -3
  72. package/dist/docs/interfaces/utils_types.ToolShed.html +5 -5
  73. package/dist/docs/media/AGENTS.md +101 -74
  74. package/dist/docs/modules/index.html +1 -1
  75. package/dist/docs/modules/tools_integrations.html +1 -1
  76. package/dist/docs/modules.html +1 -1
  77. package/dist/docs/types/index.BooleanDef.html +2 -2
  78. package/dist/docs/types/index.CreateLinkDraft.html +9 -9
  79. package/dist/docs/types/index.ImapAddress.html +3 -3
  80. package/dist/docs/types/index.ImapConnectOptions.html +6 -6
  81. package/dist/docs/types/index.ImapFetchOptions.html +4 -4
  82. package/dist/docs/types/index.ImapFlagOperation.html +1 -1
  83. package/dist/docs/types/index.ImapMailbox.html +5 -5
  84. package/dist/docs/types/index.ImapMailboxStatus.html +7 -7
  85. package/dist/docs/types/index.ImapMessage.html +14 -14
  86. package/dist/docs/types/index.ImapSearchCriteria.html +9 -9
  87. package/dist/docs/types/index.ImapSession.html +1 -1
  88. package/dist/docs/types/index.NewSchedule.html +13 -13
  89. package/dist/docs/types/index.NewScheduleContact.html +2 -2
  90. package/dist/docs/types/index.NewScheduleOccurrence.html +1 -1
  91. package/dist/docs/types/index.NoteWriteBackResult.html +3 -3
  92. package/dist/docs/types/index.NumberDef.html +2 -2
  93. package/dist/docs/types/index.OptionDef.html +1 -1
  94. package/dist/docs/types/index.OptionalScopeGroup.html +6 -6
  95. package/dist/docs/types/index.OptionsSchema.html +1 -1
  96. package/dist/docs/types/index.ReactionCapabilities.html +1 -1
  97. package/dist/docs/types/index.ResolvedOptions.html +1 -1
  98. package/dist/docs/types/index.ResolvedRecipient.html +5 -5
  99. package/dist/docs/types/index.Schedule.html +12 -12
  100. package/dist/docs/types/index.ScheduleContact.html +2 -2
  101. package/dist/docs/types/index.ScheduleContactRole.html +1 -1
  102. package/dist/docs/types/index.ScheduleContactStatus.html +1 -1
  103. package/dist/docs/types/index.ScheduleOccurrence.html +6 -6
  104. package/dist/docs/types/index.ScheduleOccurrenceUpdate.html +1 -1
  105. package/dist/docs/types/index.ScopeConfig.html +3 -3
  106. package/dist/docs/types/index.SelectDef.html +2 -2
  107. package/dist/docs/types/index.Serializable.html +1 -1
  108. package/dist/docs/types/index.SmtpAddress.html +3 -3
  109. package/dist/docs/types/index.SmtpConnectOptions.html +7 -7
  110. package/dist/docs/types/index.SmtpMessage.html +12 -12
  111. package/dist/docs/types/index.SmtpSendResult.html +4 -4
  112. package/dist/docs/types/index.SmtpSession.html +1 -1
  113. package/dist/docs/types/index.TextDef.html +2 -2
  114. package/dist/docs/types/index.Uuid.html +1 -1
  115. package/dist/docs/types/plot.Action.html +1 -1
  116. package/dist/docs/types/plot.Actor.html +5 -5
  117. package/dist/docs/types/plot.ActorId.html +4 -4
  118. package/dist/docs/types/plot.Contact.html +4 -4
  119. package/dist/docs/types/plot.ContentType.html +1 -1
  120. package/dist/docs/types/plot.Focus.html +8 -8
  121. package/dist/docs/types/plot.FocusUpdate.html +1 -1
  122. package/dist/docs/types/plot.Link.html +17 -17
  123. package/dist/docs/types/plot.LinkUpdate.html +1 -1
  124. package/dist/docs/types/plot.NewActor.html +1 -1
  125. package/dist/docs/types/plot.NewContact.html +1 -1
  126. package/dist/docs/types/plot.NewFocus.html +1 -1
  127. package/dist/docs/types/plot.NewLink.html +5 -2
  128. package/dist/docs/types/plot.NewLinkWithNotes.html +1 -1
  129. package/dist/docs/types/plot.NewNote.html +1 -1
  130. package/dist/docs/types/plot.NewReactions.html +1 -1
  131. package/dist/docs/types/plot.NewTags.html +1 -1
  132. package/dist/docs/types/plot.NewThread.html +1 -1
  133. package/dist/docs/types/plot.NewThreadWithNotes.html +1 -1
  134. package/dist/docs/types/plot.Note.html +1 -1
  135. package/dist/docs/types/plot.NoteUpdate.html +1 -1
  136. package/dist/docs/types/plot.PlanOperation.html +1 -1
  137. package/dist/docs/types/plot.Reaction.html +3 -3
  138. package/dist/docs/types/plot.Reactions.html +1 -1
  139. package/dist/docs/types/plot.Tags.html +1 -1
  140. package/dist/docs/types/plot.Thread.html +1 -1
  141. package/dist/docs/types/plot.ThreadAccessLevel.html +1 -1
  142. package/dist/docs/types/plot.ThreadCommon.html +6 -6
  143. package/dist/docs/types/plot.ThreadFilter.html +2 -2
  144. package/dist/docs/types/plot.ThreadMeta.html +1 -1
  145. package/dist/docs/types/plot.ThreadType.html +1 -1
  146. package/dist/docs/types/plot.ThreadUpdate.html +1 -1
  147. package/dist/docs/types/plot.ThreadWithNotes.html +1 -1
  148. package/dist/docs/types/tools_ai.AIAssistantMessage.html +2 -2
  149. package/dist/docs/types/tools_ai.AICapabilities.html +4 -4
  150. package/dist/docs/types/tools_ai.AIMessage.html +1 -1
  151. package/dist/docs/types/tools_ai.AIOptions.html +2 -2
  152. package/dist/docs/types/tools_ai.AISource.html +1 -1
  153. package/dist/docs/types/tools_ai.AISystemMessage.html +2 -2
  154. package/dist/docs/types/tools_ai.AITool.html +1 -1
  155. package/dist/docs/types/tools_ai.AIToolMessage.html +2 -2
  156. package/dist/docs/types/tools_ai.AIToolSet.html +1 -1
  157. package/dist/docs/types/tools_ai.AIUsage.html +5 -5
  158. package/dist/docs/types/tools_ai.AIUserMessage.html +2 -2
  159. package/dist/docs/types/tools_ai.DataContent.html +1 -1
  160. package/dist/docs/types/tools_ai.ModelPreferences.html +5 -5
  161. package/dist/docs/types/tools_callbacks.Callback.html +2 -2
  162. package/dist/docs/types/tools_integrations.ArchiveLinkFilter.html +5 -5
  163. package/dist/docs/types/tools_integrations.ArchiveNotesFilter.html +5 -0
  164. package/dist/docs/types/tools_integrations.AuthToken.html +6 -5
  165. package/dist/docs/types/tools_integrations.Authorization.html +4 -4
  166. package/dist/docs/types/tools_integrations.Channel.html +6 -6
  167. package/dist/docs/types/tools_integrations.ComposeConfig.html +4 -4
  168. package/dist/docs/types/tools_integrations.ContactRoleConfig.html +5 -5
  169. package/dist/docs/types/tools_integrations.LinkTypeConfig.html +21 -21
  170. package/dist/docs/types/tools_integrations.NewCustomEmoji.html +8 -8
  171. package/dist/docs/types/tools_integrations.StatusIcon.html +1 -1
  172. package/dist/docs/types/tools_integrations.SyncContext.html +4 -4
  173. package/dist/docs/types/tools_network.WebhookRequest.html +6 -6
  174. package/dist/docs/types/tools_plot.LinkFilter.html +5 -5
  175. package/dist/docs/types/tools_plot.LinkSearchResult.html +1 -1
  176. package/dist/docs/types/tools_plot.NoteIntentHandler.html +4 -4
  177. package/dist/docs/types/tools_plot.NoteSearchResult.html +1 -1
  178. package/dist/docs/types/tools_plot.SearchOptions.html +4 -4
  179. package/dist/docs/types/tools_plot.SearchResult.html +1 -1
  180. package/dist/docs/types/tools_twists.Log.html +2 -2
  181. package/dist/docs/types/tools_twists.TwistPermissions.html +1 -1
  182. package/dist/docs/types/utils_types.BuiltInTools.html +2 -2
  183. package/dist/docs/types/utils_types.ExtractBuildReturn.html +1 -1
  184. package/dist/docs/types/utils_types.InferOptions.html +1 -1
  185. package/dist/docs/types/utils_types.InferTools.html +1 -1
  186. package/dist/docs/types/utils_types.JSONValue.html +1 -1
  187. package/dist/docs/types/utils_types.PromiseValues.html +1 -1
  188. package/dist/docs/types/utils_types.ToolBuilder.html +1 -1
  189. package/dist/docs/variables/tools_plot.SEARCH_DEFAULT_LIMIT.html +1 -1
  190. package/dist/docs/variables/tools_plot.SEARCH_MAX_LIMIT.html +1 -1
  191. package/dist/facets.d.ts +30 -0
  192. package/dist/facets.d.ts.map +1 -0
  193. package/dist/facets.js +16 -0
  194. package/dist/facets.js.map +1 -0
  195. package/dist/llm-docs/connector.d.ts +1 -1
  196. package/dist/llm-docs/connector.d.ts.map +1 -1
  197. package/dist/llm-docs/connector.js +1 -1
  198. package/dist/llm-docs/connector.js.map +1 -1
  199. package/dist/llm-docs/facets.d.ts +9 -0
  200. package/dist/llm-docs/facets.d.ts.map +1 -0
  201. package/dist/llm-docs/facets.js +8 -0
  202. package/dist/llm-docs/facets.js.map +1 -0
  203. package/dist/llm-docs/index.d.ts.map +1 -1
  204. package/dist/llm-docs/index.js +2 -0
  205. package/dist/llm-docs/index.js.map +1 -1
  206. package/dist/llm-docs/plot.d.ts +1 -1
  207. package/dist/llm-docs/plot.d.ts.map +1 -1
  208. package/dist/llm-docs/plot.js +1 -1
  209. package/dist/llm-docs/plot.js.map +1 -1
  210. package/dist/llm-docs/tool.d.ts +1 -1
  211. package/dist/llm-docs/tool.d.ts.map +1 -1
  212. package/dist/llm-docs/tool.js +1 -1
  213. package/dist/llm-docs/tool.js.map +1 -1
  214. package/dist/llm-docs/tools/ai.d.ts +1 -1
  215. package/dist/llm-docs/tools/ai.d.ts.map +1 -1
  216. package/dist/llm-docs/tools/ai.js +1 -1
  217. package/dist/llm-docs/tools/ai.js.map +1 -1
  218. package/dist/llm-docs/tools/callbacks.d.ts +1 -1
  219. package/dist/llm-docs/tools/callbacks.d.ts.map +1 -1
  220. package/dist/llm-docs/tools/callbacks.js +1 -1
  221. package/dist/llm-docs/tools/callbacks.js.map +1 -1
  222. package/dist/llm-docs/tools/files.d.ts +1 -1
  223. package/dist/llm-docs/tools/files.d.ts.map +1 -1
  224. package/dist/llm-docs/tools/files.js +1 -1
  225. package/dist/llm-docs/tools/files.js.map +1 -1
  226. package/dist/llm-docs/tools/imap.d.ts +1 -1
  227. package/dist/llm-docs/tools/imap.d.ts.map +1 -1
  228. package/dist/llm-docs/tools/imap.js +1 -1
  229. package/dist/llm-docs/tools/imap.js.map +1 -1
  230. package/dist/llm-docs/tools/integrations.d.ts +1 -1
  231. package/dist/llm-docs/tools/integrations.d.ts.map +1 -1
  232. package/dist/llm-docs/tools/integrations.js +1 -1
  233. package/dist/llm-docs/tools/integrations.js.map +1 -1
  234. package/dist/llm-docs/tools/network.d.ts +1 -1
  235. package/dist/llm-docs/tools/network.d.ts.map +1 -1
  236. package/dist/llm-docs/tools/network.js +1 -1
  237. package/dist/llm-docs/tools/network.js.map +1 -1
  238. package/dist/llm-docs/tools/plot.d.ts +1 -1
  239. package/dist/llm-docs/tools/plot.d.ts.map +1 -1
  240. package/dist/llm-docs/tools/plot.js +1 -1
  241. package/dist/llm-docs/tools/plot.js.map +1 -1
  242. package/dist/llm-docs/tools/smtp.d.ts +1 -1
  243. package/dist/llm-docs/tools/smtp.d.ts.map +1 -1
  244. package/dist/llm-docs/tools/smtp.js +1 -1
  245. package/dist/llm-docs/tools/smtp.js.map +1 -1
  246. package/dist/llm-docs/tools/tasks.d.ts +1 -1
  247. package/dist/llm-docs/tools/tasks.d.ts.map +1 -1
  248. package/dist/llm-docs/tools/tasks.js +1 -1
  249. package/dist/llm-docs/tools/tasks.js.map +1 -1
  250. package/dist/llm-docs/tools/twists.d.ts +1 -1
  251. package/dist/llm-docs/tools/twists.d.ts.map +1 -1
  252. package/dist/llm-docs/tools/twists.js +1 -1
  253. package/dist/llm-docs/tools/twists.js.map +1 -1
  254. package/dist/llm-docs/twist-guide-template.d.ts +1 -1
  255. package/dist/llm-docs/twist-guide-template.d.ts.map +1 -1
  256. package/dist/llm-docs/twist-guide-template.js +1 -1
  257. package/dist/llm-docs/twist-guide-template.js.map +1 -1
  258. package/dist/llm-docs/twist.d.ts +1 -1
  259. package/dist/llm-docs/twist.d.ts.map +1 -1
  260. package/dist/llm-docs/twist.js +1 -1
  261. package/dist/llm-docs/twist.js.map +1 -1
  262. package/dist/plot.d.ts +15 -8
  263. package/dist/plot.d.ts.map +1 -1
  264. package/dist/plot.js.map +1 -1
  265. package/dist/tool.d.ts +4 -4
  266. package/dist/tool.js +4 -4
  267. package/dist/tools/ai.d.ts +12 -13
  268. package/dist/tools/ai.d.ts.map +1 -1
  269. package/dist/tools/ai.js +8 -9
  270. package/dist/tools/ai.js.map +1 -1
  271. package/dist/tools/callbacks.d.ts +1 -1
  272. package/dist/tools/files.d.ts +2 -2
  273. package/dist/tools/imap.d.ts +1 -1
  274. package/dist/tools/imap.js +1 -1
  275. package/dist/tools/integrations.d.ts +29 -2
  276. package/dist/tools/integrations.d.ts.map +1 -1
  277. package/dist/tools/integrations.js.map +1 -1
  278. package/dist/tools/network.d.ts +5 -5
  279. package/dist/tools/plot.d.ts +42 -37
  280. package/dist/tools/plot.d.ts.map +1 -1
  281. package/dist/tools/plot.js +16 -12
  282. package/dist/tools/plot.js.map +1 -1
  283. package/dist/tools/smtp.d.ts +1 -1
  284. package/dist/tools/smtp.js +1 -1
  285. package/dist/tools/tasks.d.ts +6 -8
  286. package/dist/tools/tasks.d.ts.map +1 -1
  287. package/dist/tools/tasks.js +5 -7
  288. package/dist/tools/tasks.js.map +1 -1
  289. package/dist/tools/twists.d.ts +15 -14
  290. package/dist/tools/twists.d.ts.map +1 -1
  291. package/dist/tools/twists.js +2 -2
  292. package/dist/tools/twists.js.map +1 -1
  293. package/dist/twist-guide.d.ts +1 -1
  294. package/dist/twist-guide.d.ts.map +1 -1
  295. package/dist/twist.d.ts +2 -2
  296. package/dist/twist.js +2 -2
  297. package/package.json +6 -1
  298. package/src/connector.ts +23 -16
  299. package/src/facets.ts +40 -0
  300. package/src/llm-docs/connector.ts +1 -1
  301. package/src/llm-docs/facets.ts +8 -0
  302. package/src/llm-docs/index.ts +2 -0
  303. package/src/llm-docs/plot.ts +1 -1
  304. package/src/llm-docs/tool.ts +1 -1
  305. package/src/llm-docs/tools/ai.ts +1 -1
  306. package/src/llm-docs/tools/callbacks.ts +1 -1
  307. package/src/llm-docs/tools/files.ts +1 -1
  308. package/src/llm-docs/tools/imap.ts +1 -1
  309. package/src/llm-docs/tools/integrations.ts +1 -1
  310. package/src/llm-docs/tools/network.ts +1 -1
  311. package/src/llm-docs/tools/plot.ts +1 -1
  312. package/src/llm-docs/tools/smtp.ts +1 -1
  313. package/src/llm-docs/tools/tasks.ts +1 -1
  314. package/src/llm-docs/tools/twists.ts +1 -1
  315. package/src/llm-docs/twist-guide-template.ts +1 -1
  316. package/src/llm-docs/twist.ts +1 -1
  317. package/src/plot.ts +15 -8
  318. package/src/tool.ts +4 -4
  319. package/src/tools/ai.ts +12 -13
  320. package/src/tools/callbacks.ts +1 -1
  321. package/src/tools/files.ts +2 -2
  322. package/src/tools/imap.ts +1 -1
  323. package/src/tools/integrations.ts +34 -1
  324. package/src/tools/network.ts +5 -5
  325. package/src/tools/plot.ts +42 -37
  326. package/src/tools/smtp.ts +1 -1
  327. package/src/tools/tasks.ts +6 -8
  328. package/src/tools/twists.ts +15 -14
  329. package/src/twist.ts +2 -2
  330. package/dist/docs/media/MULTI_USER_AUTH.md +0 -116
  331. package/dist/docs/media/SYNC_STRATEGIES.md +0 -818
@@ -6,7 +6,7 @@
6
6
  <li><a href="#batching-long-operations">Batching Long Operations</a></li>
7
7
  <li><a href="#memory-considerations">Memory Considerations</a></li>
8
8
  <li><a href="#performance-optimization">Performance Optimization</a></li>
9
- <li><a href="#timeout-handling">Timeout Handling</a></li>
9
+ <li><a href="#request-limits-and-timeouts">Request Limits and Timeouts</a></li>
10
10
  </ul>
11
11
  <hr>
12
12
  <h2 id="execution-model" class="tsd-anchor-link">Execution Model<a href="#execution-model" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Plot twists run in a <strong>sandboxed, serverless environment</strong> with the following characteristics:</p>
@@ -19,7 +19,7 @@
19
19
  <h3 id="event-driven" class="tsd-anchor-link">Event-Driven<a href="#event-driven" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Twists respond to events:</p>
20
20
  <ul>
21
21
  <li><strong>Lifecycle events</strong> - activate, upgrade, deactivate</li>
22
- <li><strong>Activity events</strong> - New or updated activities</li>
22
+ <li><strong>Thread events</strong> - New or updated threads, notes, and links</li>
23
23
  <li><strong>Webhook events</strong> - External service notifications</li>
24
24
  <li><strong>Scheduled events</strong> - Tasks queued with runTask()</li>
25
25
  </ul>
@@ -39,12 +39,12 @@
39
39
  <p>When any of these limits is exceeded, the twist is <strong>auto-suspended</strong>:</p>
40
40
  <ul>
41
41
  <li>All callbacks (webhooks, runTask handlers, scheduled tasks) immediately stop executing.</li>
42
- <li>A suspension log is written to the twist log stream (visible in the connector logs UI) and a note is posted to the workspace owner's Help &amp; Feedback thread.</li>
42
+ <li>A suspension log is written to the twist log stream (visible in the connector logs UI) and a note is posted to the twist owner's Help &amp; Feedback thread.</li>
43
43
  <li><strong>Suspension is lifted automatically on the next deploy of the twist.</strong> Each new version starts with a clean rate-limit budget. If the same pattern repeats, the twist will be re-suspended within minutes — fix the root cause before redeploying.</li>
44
44
  </ul>
45
45
  <p>Manual/operator suspensions (set directly in the database without a recorded version) are durable across deploys.</p>
46
46
  <h4 id="avoiding-auto-suspension" class="tsd-anchor-link">Avoiding auto-suspension<a href="#avoiding-auto-suspension" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><p>The most common cause of auto-suspension is a callback that re-queues itself with no exit condition:</p>
47
- <pre><code class="typescript"><span class="hl-7">// ❌ WRONG — unbounded self-chain. Each call queues another with no</span><br/><span class="hl-7">// completion check. Even with delays, this will exceed the burst</span><br/><span class="hl-7">// limit (200 / 5 min) in under a minute.</span><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">reconcileComments</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processOne</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;reconcileComments&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">); </span><span class="hl-7">// recurses forever</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-7">// ✅ CORRECT — explicit exit condition based on remaining work</span><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">reconcileComments</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">state</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;{ </span><span class="hl-2">cursor</span><span class="hl-1">: </span><span class="hl-5">string</span><span class="hl-1"> | </span><span class="hl-5">null</span><span class="hl-1"> }&gt;(</span><span class="hl-3">&quot;reconcile_state&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">result</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processOne</span><span class="hl-1">(</span><span class="hl-2">state</span><span class="hl-1">?.</span><span class="hl-2">cursor</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">result</span><span class="hl-1">.</span><span class="hl-2">hasMore</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;reconcile_state&quot;</span><span class="hl-1">, { </span><span class="hl-2">cursor:</span><span class="hl-1"> </span><span class="hl-2">result</span><span class="hl-1">.</span><span class="hl-2">nextCursor</span><span class="hl-1"> });</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;reconcileComments&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-0">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;reconcile_state&quot;</span><span class="hl-1">, { </span><span class="hl-2">cursor:</span><span class="hl-1"> </span><span class="hl-4">null</span><span class="hl-1"> });</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-7">// ✅ CORRECT — periodic background work uses runAt, not a self-chain</span><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">pollForChanges</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processBatch</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;pollForChanges&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Schedule the next run 5 minutes from now. Cloudflare&#39;s queue stays</span><br/><span class="hl-1"> </span><span class="hl-7">// out of the loop entirely between runs.</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">runAt:</span><span class="hl-1"> </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">Date</span><span class="hl-1">(</span><span class="hl-2">Date</span><span class="hl-1">.</span><span class="hl-6">now</span><span class="hl-1">() + </span><span class="hl-14">5</span><span class="hl-1"> * </span><span class="hl-14">60</span><span class="hl-1"> * </span><span class="hl-14">1000</span><span class="hl-1">),</span><br/><span class="hl-1"> });</span><br/><span class="hl-1">}</span>
47
+ <pre><code class="typescript"><span class="hl-7">// ❌ WRONG — unbounded self-chain. Each call queues another with no</span><br/><span class="hl-7">// completion check. Even with delays, this will exceed the burst</span><br/><span class="hl-7">// limit (200 / 5 min) in under a minute.</span><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">reconcileComments</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processOne</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">reconcileComments</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">); </span><span class="hl-7">// recurses forever</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-7">// ✅ CORRECT — explicit exit condition based on remaining work</span><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">reconcileComments</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">state</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;{ </span><span class="hl-2">cursor</span><span class="hl-1">: </span><span class="hl-5">string</span><span class="hl-1"> | </span><span class="hl-5">null</span><span class="hl-1"> }&gt;(</span><span class="hl-3">&quot;reconcile_state&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">result</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processOne</span><span class="hl-1">(</span><span class="hl-2">state</span><span class="hl-1">?.</span><span class="hl-2">cursor</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">result</span><span class="hl-1">.</span><span class="hl-2">hasMore</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;reconcile_state&quot;</span><span class="hl-1">, { </span><span class="hl-2">cursor:</span><span class="hl-1"> </span><span class="hl-2">result</span><span class="hl-1">.</span><span class="hl-2">nextCursor</span><span class="hl-1"> });</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">reconcileComments</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-0">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;reconcile_state&quot;</span><span class="hl-1">, { </span><span class="hl-2">cursor:</span><span class="hl-1"> </span><span class="hl-4">null</span><span class="hl-1"> });</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-7">// ✅ CORRECT — periodic background work uses runAt, not a self-chain</span><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">pollForChanges</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processBatch</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">pollForChanges</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Schedule the next run 5 minutes from now. Cloudflare&#39;s queue stays</span><br/><span class="hl-1"> </span><span class="hl-7">// out of the loop entirely between runs.</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">runAt:</span><span class="hl-1"> </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">Date</span><span class="hl-1">(</span><span class="hl-2">Date</span><span class="hl-1">.</span><span class="hl-6">now</span><span class="hl-1">() + </span><span class="hl-14">5</span><span class="hl-1"> * </span><span class="hl-14">60</span><span class="hl-1"> * </span><span class="hl-14">1000</span><span class="hl-1">),</span><br/><span class="hl-1"> });</span><br/><span class="hl-1">}</span>
48
48
  </code><button type="button">Copy</button></pre>
49
49
 
50
50
  <p><strong>Guidelines:</strong></p>
@@ -65,7 +65,7 @@
65
65
  <li><strong>Calling a callback</strong> (via <code>this.run()</code>) continues the same execution and shares the request count</li>
66
66
  <li><strong>Running a task</strong> (via <code>this.runTask()</code>) creates a NEW execution with a fresh set of ~1000 requests</li>
67
67
  </ul>
68
- <pre><code class="typescript"><span class="hl-7">// ❌ WRONG - May exceed request limit!</span><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">syncAllEvents</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">events</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">fetchAllEvents</span><span class="hl-1">(); </span><span class="hl-7">// Could be thousands</span><br/><span class="hl-1"> </span><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">event</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-2">events</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-7">// Each iteration makes multiple requests (fetch event details, create activity, etc.)</span><br/><span class="hl-1"> </span><span class="hl-7">// With 500 events × 3 requests each = 1500 requests total - exceeds limit!</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processEvent</span><span class="hl-1">(</span><span class="hl-2">event</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-7">// ✅ CORRECT - Batch processing with fresh request limits</span><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">startSync</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">, { </span><span class="hl-2">page:</span><span class="hl-1"> </span><span class="hl-14">1</span><span class="hl-1">, </span><span class="hl-2">total:</span><span class="hl-1"> </span><span class="hl-14">0</span><span class="hl-1"> });</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;syncBatch&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// runTask creates a NEW execution with fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">syncBatch</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">state</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;{ </span><span class="hl-2">page</span><span class="hl-1">: </span><span class="hl-5">number</span><span class="hl-1">; </span><span class="hl-2">total</span><span class="hl-1">: </span><span class="hl-5">number</span><span class="hl-1"> }&gt;(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (!</span><span class="hl-2">state</span><span class="hl-1">) </span><span class="hl-0">return</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Process one page (e.g., 50 events)</span><br/><span class="hl-1"> </span><span class="hl-7">// Keep batch size small enough to stay under ~1000 request limit</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">events</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">fetchEventsPage</span><span class="hl-1">(</span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">page</span><span class="hl-1">, </span><span class="hl-14">50</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processEvents</span><span class="hl-1">(</span><span class="hl-2">events</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Queue next batch if needed</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">events</span><span class="hl-1">.</span><span class="hl-2">hasMore</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">page:</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">page</span><span class="hl-1"> + </span><span class="hl-14">1</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">total:</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">total</span><span class="hl-1"> + </span><span class="hl-2">events</span><span class="hl-1">.</span><span class="hl-2">length</span><br/><span class="hl-1"> });</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;syncBatch&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Each runTask creates a NEW execution with fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
68
+ <pre><code class="typescript"><span class="hl-7">// ❌ WRONG - May exceed request limit!</span><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">syncAllEvents</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">events</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">fetchAllEvents</span><span class="hl-1">(); </span><span class="hl-7">// Could be thousands</span><br/><span class="hl-1"> </span><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">event</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-2">events</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-7">// Each iteration makes multiple requests (fetch event details, save link, etc.)</span><br/><span class="hl-1"> </span><span class="hl-7">// With 500 events × 3 requests each = 1500 requests total - exceeds limit!</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processEvent</span><span class="hl-1">(</span><span class="hl-2">event</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-7">// ✅ CORRECT - Batch processing with fresh request limits</span><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">startSync</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">, { </span><span class="hl-2">page:</span><span class="hl-1"> </span><span class="hl-14">1</span><span class="hl-1">, </span><span class="hl-2">total:</span><span class="hl-1"> </span><span class="hl-14">0</span><span class="hl-1"> });</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">syncBatch</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// runTask creates a NEW execution with fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">syncBatch</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">state</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;{ </span><span class="hl-2">page</span><span class="hl-1">: </span><span class="hl-5">number</span><span class="hl-1">; </span><span class="hl-2">total</span><span class="hl-1">: </span><span class="hl-5">number</span><span class="hl-1"> }&gt;(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (!</span><span class="hl-2">state</span><span class="hl-1">) </span><span class="hl-0">return</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Process one page (e.g., 50 events)</span><br/><span class="hl-1"> </span><span class="hl-7">// Keep batch size small enough to stay under ~1000 request limit</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">events</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">fetchEventsPage</span><span class="hl-1">(</span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">page</span><span class="hl-1">, </span><span class="hl-14">50</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processEvents</span><span class="hl-1">(</span><span class="hl-2">events</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Queue next batch if needed</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">events</span><span class="hl-1">.</span><span class="hl-2">hasMore</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">page:</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">page</span><span class="hl-1"> + </span><span class="hl-14">1</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">total:</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">total</span><span class="hl-1"> + </span><span class="hl-2">events</span><span class="hl-1">.</span><span class="hl-2">length</span><br/><span class="hl-1"> });</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">syncBatch</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Each runTask creates a NEW execution with fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
69
69
  </code><button type="button">Copy</button></pre>
70
70
 
71
71
  <h3 id="3-no-file-system-access" class="tsd-anchor-link">3. No File System Access<a href="#3-no-file-system-access" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Cannot read or write files:</p>
@@ -86,21 +86,21 @@
86
86
  </code><button type="button">Copy</button></pre>
87
87
 
88
88
  <h3 id="state-cleanup" class="tsd-anchor-link">State Cleanup<a href="#state-cleanup" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Clean up state in deactivate:</p>
89
- <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">deactivate</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-7">// Option 1: Clear all</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clearAll</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Option 2: Clear specific keys</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;sync:page_token&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;cache:user:123&quot;</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Option 3: Clear by prefix (manually)</span><br/><span class="hl-1"> </span><span class="hl-7">// Store doesn&#39;t have native prefix clearing,</span><br/><span class="hl-1"> </span><span class="hl-7">// so track keys if needed</span><br/><span class="hl-1">}</span>
89
+ <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">deactivate</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-7">// Option 1: Clear all</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clearAll</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Option 2: Clear specific keys</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;sync:page_token&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;cache:user:123&quot;</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Option 3: Clear by prefix — list matching keys, then clear each</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">keys</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">store</span><span class="hl-1">.</span><span class="hl-6">list</span><span class="hl-1">(</span><span class="hl-3">&quot;cache:&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">key</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-2">keys</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-2">key</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
90
90
  </code><button type="button">Copy</button></pre>
91
91
 
92
92
  <hr>
93
93
  <h2 id="batching-long-operations" class="tsd-anchor-link">Batching Long Operations<a href="#batching-long-operations" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Break long operations into smaller batches to stay under the request limit (~1000 requests per execution). Each task creates a new execution with a fresh request count.</p>
94
94
  <h3 id="pattern-1-page-based-batching" class="tsd-anchor-link">Pattern 1: Page-Based Batching<a href="#pattern-1-page-based-batching" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>For paginated APIs. Each page is processed in a separate task with its own request limit.</p>
95
- <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">startSync</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">page:</span><span class="hl-1"> </span><span class="hl-14">1</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">totalProcessed:</span><span class="hl-1"> </span><span class="hl-14">0</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">startTime:</span><span class="hl-1"> </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">Date</span><span class="hl-1">().</span><span class="hl-6">toISOString</span><span class="hl-1">()</span><br/><span class="hl-1"> });</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;syncPage&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Creates new execution with fresh ~1000 request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">syncPage</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">state</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">SyncState</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (!</span><span class="hl-2">state</span><span class="hl-1">) </span><span class="hl-0">return</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-0">try</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-7">// Fetch one page (keep page size reasonable to stay under request limit)</span><br/><span class="hl-1"> </span><span class="hl-7">// Example: 50 items × ~10 requests per item = ~500 requests (well under limit)</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">response</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">fetch</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-3">`https://api.example.com/items?page=</span><span class="hl-4">${</span><span class="hl-2">state</span><span class="hl-13">.</span><span class="hl-2">page</span><span class="hl-4">}</span><span class="hl-3">&amp;per_page=50`</span><br/><span class="hl-1"> );</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">data</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">response</span><span class="hl-1">.</span><span class="hl-6">json</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Process items in this execution</span><br/><span class="hl-1"> </span><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">item</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">items</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processItem</span><span class="hl-1">(</span><span class="hl-2">item</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Update state</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">newState</span><span class="hl-1"> = {</span><br/><span class="hl-1"> </span><span class="hl-2">page:</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">page</span><span class="hl-1"> + </span><span class="hl-14">1</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">totalProcessed:</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">totalProcessed</span><span class="hl-1"> + </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-2">length</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">startTime:</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">startTime</span><br/><span class="hl-1"> };</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Queue next page if more exist</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">hasMore</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">, </span><span class="hl-2">newState</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;syncPage&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Each runTask creates NEW execution with fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-0">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-7">// Sync complete</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">`Sync complete: </span><span class="hl-4">${</span><span class="hl-2">newState</span><span class="hl-13">.</span><span class="hl-2">totalProcessed</span><span class="hl-4">}</span><span class="hl-3"> items`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> } </span><span class="hl-0">catch</span><span class="hl-1"> (</span><span class="hl-2">error</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">error</span><span class="hl-1">(</span><span class="hl-3">&quot;Sync error:&quot;</span><span class="hl-1">, </span><span class="hl-2">error</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Could implement retry logic here</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
95
+ <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">startSync</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">page:</span><span class="hl-1"> </span><span class="hl-14">1</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">totalProcessed:</span><span class="hl-1"> </span><span class="hl-14">0</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">startTime:</span><span class="hl-1"> </span><span class="hl-4">new</span><span class="hl-1"> </span><span class="hl-6">Date</span><span class="hl-1">().</span><span class="hl-6">toISOString</span><span class="hl-1">()</span><br/><span class="hl-1"> });</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">syncPage</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Creates new execution with fresh ~1000 request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">syncPage</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">state</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">SyncState</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (!</span><span class="hl-2">state</span><span class="hl-1">) </span><span class="hl-0">return</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-0">try</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-7">// Fetch one page (keep page size reasonable to stay under request limit)</span><br/><span class="hl-1"> </span><span class="hl-7">// Example: 50 items × ~10 requests per item = ~500 requests (well under limit)</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">response</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">fetch</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-3">`https://api.example.com/items?page=</span><span class="hl-4">${</span><span class="hl-2">state</span><span class="hl-13">.</span><span class="hl-2">page</span><span class="hl-4">}</span><span class="hl-3">&amp;per_page=50`</span><br/><span class="hl-1"> );</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">data</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">response</span><span class="hl-1">.</span><span class="hl-6">json</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Process items in this execution</span><br/><span class="hl-1"> </span><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">item</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">items</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processItem</span><span class="hl-1">(</span><span class="hl-2">item</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Update state</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">newState</span><span class="hl-1"> = {</span><br/><span class="hl-1"> </span><span class="hl-2">page:</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">page</span><span class="hl-1"> + </span><span class="hl-14">1</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">totalProcessed:</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">totalProcessed</span><span class="hl-1"> + </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-2">length</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">startTime:</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">startTime</span><br/><span class="hl-1"> };</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Queue next page if more exist</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">hasMore</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">, </span><span class="hl-2">newState</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">syncPage</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Each runTask creates NEW execution with fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-0">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-7">// Sync complete</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">`Sync complete: </span><span class="hl-4">${</span><span class="hl-2">newState</span><span class="hl-13">.</span><span class="hl-2">totalProcessed</span><span class="hl-4">}</span><span class="hl-3"> items`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> } </span><span class="hl-0">catch</span><span class="hl-1"> (</span><span class="hl-2">error</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">error</span><span class="hl-1">(</span><span class="hl-3">&quot;Sync error:&quot;</span><span class="hl-1">, </span><span class="hl-2">error</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Could implement retry logic here</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
96
96
  </code><button type="button">Copy</button></pre>
97
97
 
98
98
  <h3 id="pattern-2-token-based-batching" class="tsd-anchor-link">Pattern 2: Token-Based Batching<a href="#pattern-2-token-based-batching" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>For APIs using continuation tokens. Each batch gets its own execution and request limit.</p>
99
- <pre><code class="typescript"><span class="hl-4">interface</span><span class="hl-1"> </span><span class="hl-5">SyncState</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">nextToken</span><span class="hl-1">: </span><span class="hl-5">string</span><span class="hl-1"> | </span><span class="hl-5">null</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">totalProcessed</span><span class="hl-1">: </span><span class="hl-5">number</span><span class="hl-1">;</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">startSync</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">&lt;</span><span class="hl-5">SyncState</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">nextToken:</span><span class="hl-1"> </span><span class="hl-4">null</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">totalProcessed:</span><span class="hl-1"> </span><span class="hl-14">0</span><br/><span class="hl-1"> });</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;syncBatch&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Creates new execution with fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">syncBatch</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">state</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">SyncState</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (!</span><span class="hl-2">state</span><span class="hl-1">) </span><span class="hl-0">return</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Fetch batch from API (1 request)</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">response</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">fetch</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-3">`https://api.example.com/items</span><span class="hl-4">${</span><span class="hl-2">state</span><span class="hl-13">.</span><span class="hl-2">nextToken</span><span class="hl-13"> </span><span class="hl-1">?</span><span class="hl-13"> </span><span class="hl-3">`?token=</span><span class="hl-4">${</span><span class="hl-2">state</span><span class="hl-13">.</span><span class="hl-2">nextToken</span><span class="hl-4">}</span><span class="hl-3">`</span><span class="hl-13"> </span><span class="hl-1">:</span><span class="hl-13"> </span><span class="hl-3">&quot;&quot;</span><span class="hl-4">}</span><span class="hl-3">`</span><br/><span class="hl-1"> );</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">data</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">response</span><span class="hl-1">.</span><span class="hl-6">json</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Process batch (each item may make multiple requests)</span><br/><span class="hl-1"> </span><span class="hl-7">// Keep batch small enough to stay under ~1000 request limit</span><br/><span class="hl-1"> </span><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">item</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">items</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processItem</span><span class="hl-1">(</span><span class="hl-2">item</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Update state and continue if needed</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">nextToken</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">&lt;</span><span class="hl-5">SyncState</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">nextToken:</span><span class="hl-1"> </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">nextToken</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">totalProcessed:</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">totalProcessed</span><span class="hl-1"> + </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-2">length</span><br/><span class="hl-1"> });</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;syncBatch&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// New execution = fresh request limit for next batch</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-0">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">`Complete: </span><span class="hl-4">${</span><span class="hl-2">state</span><span class="hl-13">.</span><span class="hl-2">totalProcessed</span><span class="hl-13"> </span><span class="hl-1">+</span><span class="hl-13"> </span><span class="hl-2">data</span><span class="hl-13">.</span><span class="hl-2">items</span><span class="hl-13">.</span><span class="hl-2">length</span><span class="hl-4">}</span><span class="hl-3"> items`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
99
+ <pre><code class="typescript"><span class="hl-4">interface</span><span class="hl-1"> </span><span class="hl-5">SyncState</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">nextToken</span><span class="hl-1">: </span><span class="hl-5">string</span><span class="hl-1"> | </span><span class="hl-5">null</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-2">totalProcessed</span><span class="hl-1">: </span><span class="hl-5">number</span><span class="hl-1">;</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">startSync</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">&lt;</span><span class="hl-5">SyncState</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">nextToken:</span><span class="hl-1"> </span><span class="hl-4">null</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">totalProcessed:</span><span class="hl-1"> </span><span class="hl-14">0</span><br/><span class="hl-1"> });</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">syncBatch</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Creates new execution with fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">syncBatch</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">state</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">SyncState</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (!</span><span class="hl-2">state</span><span class="hl-1">) </span><span class="hl-0">return</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Fetch batch from API (1 request)</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">response</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">fetch</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-3">`https://api.example.com/items</span><span class="hl-4">${</span><span class="hl-2">state</span><span class="hl-13">.</span><span class="hl-2">nextToken</span><span class="hl-13"> </span><span class="hl-1">?</span><span class="hl-13"> </span><span class="hl-3">`?token=</span><span class="hl-4">${</span><span class="hl-2">state</span><span class="hl-13">.</span><span class="hl-2">nextToken</span><span class="hl-4">}</span><span class="hl-3">`</span><span class="hl-13"> </span><span class="hl-1">:</span><span class="hl-13"> </span><span class="hl-3">&quot;&quot;</span><span class="hl-4">}</span><span class="hl-3">`</span><br/><span class="hl-1"> );</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">data</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-2">response</span><span class="hl-1">.</span><span class="hl-6">json</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Process batch (each item may make multiple requests)</span><br/><span class="hl-1"> </span><span class="hl-7">// Keep batch small enough to stay under ~1000 request limit</span><br/><span class="hl-1"> </span><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">item</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">items</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processItem</span><span class="hl-1">(</span><span class="hl-2">item</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Update state and continue if needed</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">nextToken</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">&lt;</span><span class="hl-5">SyncState</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">, {</span><br/><span class="hl-1"> </span><span class="hl-2">nextToken:</span><span class="hl-1"> </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">nextToken</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">totalProcessed:</span><span class="hl-1"> </span><span class="hl-2">state</span><span class="hl-1">.</span><span class="hl-2">totalProcessed</span><span class="hl-1"> + </span><span class="hl-2">data</span><span class="hl-1">.</span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-2">length</span><br/><span class="hl-1"> });</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">syncBatch</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// New execution = fresh request limit for next batch</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-0">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">`Complete: </span><span class="hl-4">${</span><span class="hl-2">state</span><span class="hl-13">.</span><span class="hl-2">totalProcessed</span><span class="hl-13"> </span><span class="hl-1">+</span><span class="hl-13"> </span><span class="hl-2">data</span><span class="hl-13">.</span><span class="hl-2">items</span><span class="hl-13">.</span><span class="hl-2">length</span><span class="hl-4">}</span><span class="hl-3"> items`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;sync_state&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
100
100
  </code><button type="button">Copy</button></pre>
101
101
 
102
102
  <h3 id="pattern-3-item-based-batching" class="tsd-anchor-link">Pattern 3: Item-Based Batching<a href="#pattern-3-item-based-batching" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>For processing arrays of items. Size batches to stay under the request limit.</p>
103
- <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">processLargeArray</span><span class="hl-1">(</span><span class="hl-2">items</span><span class="hl-1">: </span><span class="hl-2">Item</span><span class="hl-1">[]) {</span><br/><span class="hl-1"> </span><span class="hl-7">// Save items and start processing</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;items_to_process&quot;</span><span class="hl-1">, </span><span class="hl-2">items</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;process_index&quot;</span><span class="hl-1">, </span><span class="hl-14">0</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;processBatch&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Creates new execution with fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">processBatch</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">items</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">Item</span><span class="hl-1">[]&gt;(</span><span class="hl-3">&quot;items_to_process&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">index</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">number</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;process_index&quot;</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (!</span><span class="hl-2">items</span><span class="hl-1"> || </span><span class="hl-2">index</span><span class="hl-1"> === </span><span class="hl-4">null</span><span class="hl-1"> || </span><span class="hl-2">index</span><span class="hl-1"> &gt;= </span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-2">length</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;items_to_process&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;process_index&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1">;</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Choose batch size based on requests per item</span><br/><span class="hl-1"> </span><span class="hl-7">// Example: If each item needs ~20 requests, use batch size of 50</span><br/><span class="hl-1"> </span><span class="hl-7">// 50 items × 20 requests = 1000 requests (at limit)</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">batchSize</span><span class="hl-1"> = </span><span class="hl-14">10</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">batch</span><span class="hl-1"> = </span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-6">slice</span><span class="hl-1">(</span><span class="hl-2">index</span><span class="hl-1">, </span><span class="hl-2">index</span><span class="hl-1"> + </span><span class="hl-2">batchSize</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">item</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-2">batch</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processItem</span><span class="hl-1">(</span><span class="hl-2">item</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Update index and continue</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">newIndex</span><span class="hl-1"> = </span><span class="hl-2">index</span><span class="hl-1"> + </span><span class="hl-2">batchSize</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">newIndex</span><span class="hl-1"> &lt; </span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-2">length</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;process_index&quot;</span><span class="hl-1">, </span><span class="hl-2">newIndex</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;processBatch&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Each runTask gets fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-0">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-7">// Complete</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;items_to_process&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;process_index&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
103
+ <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">processLargeArray</span><span class="hl-1">(</span><span class="hl-2">items</span><span class="hl-1">: </span><span class="hl-2">Item</span><span class="hl-1">[]) {</span><br/><span class="hl-1"> </span><span class="hl-7">// Save items and start processing</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;items_to_process&quot;</span><span class="hl-1">, </span><span class="hl-2">items</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;process_index&quot;</span><span class="hl-1">, </span><span class="hl-14">0</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">processBatch</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Creates new execution with fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">processBatch</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">items</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">Item</span><span class="hl-1">[]&gt;(</span><span class="hl-3">&quot;items_to_process&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">index</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">number</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;process_index&quot;</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (!</span><span class="hl-2">items</span><span class="hl-1"> || </span><span class="hl-2">index</span><span class="hl-1"> === </span><span class="hl-4">null</span><span class="hl-1"> || </span><span class="hl-2">index</span><span class="hl-1"> &gt;= </span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-2">length</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;items_to_process&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;process_index&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1">;</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Choose batch size based on requests per item</span><br/><span class="hl-1"> </span><span class="hl-7">// Example: If each item needs ~20 requests, use batch size of 50</span><br/><span class="hl-1"> </span><span class="hl-7">// 50 items × 20 requests = 1000 requests (at limit)</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">batchSize</span><span class="hl-1"> = </span><span class="hl-14">10</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">batch</span><span class="hl-1"> = </span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-6">slice</span><span class="hl-1">(</span><span class="hl-2">index</span><span class="hl-1">, </span><span class="hl-2">index</span><span class="hl-1"> + </span><span class="hl-2">batchSize</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">item</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-2">batch</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processItem</span><span class="hl-1">(</span><span class="hl-2">item</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Update index and continue</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">newIndex</span><span class="hl-1"> = </span><span class="hl-2">index</span><span class="hl-1"> + </span><span class="hl-2">batchSize</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">newIndex</span><span class="hl-1"> &lt; </span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-2">length</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;process_index&quot;</span><span class="hl-1">, </span><span class="hl-2">newIndex</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">processBatch</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// Each runTask gets fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1"> } </span><span class="hl-0">else</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-7">// Complete</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;items_to_process&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">clear</span><span class="hl-1">(</span><span class="hl-3">&quot;process_index&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
104
104
  </code><button type="button">Copy</button></pre>
105
105
 
106
106
  <hr>
@@ -114,9 +114,10 @@
114
114
 
115
115
  <hr>
116
116
  <h2 id="performance-optimization" class="tsd-anchor-link">Performance Optimization<a href="#performance-optimization" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><h3 id="1-minimize-api-calls" class="tsd-anchor-link">1. Minimize API Calls<a href="#1-minimize-api-calls" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Batch operations where possible:</p>
117
- <pre><code class="typescript"><span class="hl-7">// ❌ SLOW - Multiple round trips</span><br/><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">item</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-2">items</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createActivity</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">.</span><span class="hl-2">Action</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-2">item</span><span class="hl-1">.</span><span class="hl-2">title</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">notes:</span><span class="hl-1"> [{ </span><span class="hl-2">content:</span><span class="hl-1"> </span><span class="hl-2">item</span><span class="hl-1">.</span><span class="hl-2">description</span><span class="hl-1"> }],</span><br/><span class="hl-1"> });</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-7">// ✅ FAST - Batch create (always include initial notes)</span><br/><span class="hl-7">// Note: Store UUID mappings separately for tracking</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createActivities</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-6">map</span><span class="hl-1">((</span><span class="hl-2">item</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> ({</span><br/><span class="hl-1"> </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-2">Uuid</span><span class="hl-1">.</span><span class="hl-6">Generate</span><span class="hl-1">(),</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">ActivityType</span><span class="hl-1">.</span><span class="hl-2">Action</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-2">item</span><span class="hl-1">.</span><span class="hl-2">title</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">notes:</span><span class="hl-1"> [{ </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-2">Uuid</span><span class="hl-1">.</span><span class="hl-6">Generate</span><span class="hl-1">(), </span><span class="hl-2">content:</span><span class="hl-1"> </span><span class="hl-2">item</span><span class="hl-1">.</span><span class="hl-2">description</span><span class="hl-1"> }],</span><br/><span class="hl-1"> }))</span><br/><span class="hl-1">);</span>
117
+ <pre><code class="typescript"><span class="hl-7">// ❌ SLOW - Multiple round trips</span><br/><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">item</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-2">items</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createThread</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-3">&quot;action&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-2">item</span><span class="hl-1">.</span><span class="hl-2">title</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">notes:</span><span class="hl-1"> [{ </span><span class="hl-2">content:</span><span class="hl-1"> </span><span class="hl-2">item</span><span class="hl-1">.</span><span class="hl-2">description</span><span class="hl-1"> }],</span><br/><span class="hl-1"> });</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-7">// ✅ FAST - Batch create (always include initial notes)</span><br/><span class="hl-7">// Note: Store UUID mappings separately for tracking</span><br/><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">tools</span><span class="hl-1">.</span><span class="hl-2">plot</span><span class="hl-1">.</span><span class="hl-6">createThreads</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-6">map</span><span class="hl-1">((</span><span class="hl-2">item</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> ({</span><br/><span class="hl-1"> </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-2">Uuid</span><span class="hl-1">.</span><span class="hl-6">Generate</span><span class="hl-1">(),</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-3">&quot;action&quot;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-2">item</span><span class="hl-1">.</span><span class="hl-2">title</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">notes:</span><span class="hl-1"> [{ </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-2">Uuid</span><span class="hl-1">.</span><span class="hl-6">Generate</span><span class="hl-1">(), </span><span class="hl-2">content:</span><span class="hl-1"> </span><span class="hl-2">item</span><span class="hl-1">.</span><span class="hl-2">description</span><span class="hl-1"> }],</span><br/><span class="hl-1"> }))</span><br/><span class="hl-1">);</span>
118
118
  </code><button type="button">Copy</button></pre>
119
119
 
120
+ <p>Connectors batch the same way with <code>integrations.saveLinks()</code> — each <code>saveLink</code> call counts against the per-execution request budget, so collapsing a page of items into one <code>saveLinks</code> call matters.</p>
120
121
  <h3 id="2-parallel-operations" class="tsd-anchor-link">2. Parallel Operations<a href="#2-parallel-operations" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Run independent operations in parallel:</p>
121
122
  <pre><code class="typescript"><span class="hl-7">// ❌ SLOW - Sequential</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">user</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">fetchUser</span><span class="hl-1">();</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">repos</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">fetchRepos</span><span class="hl-1">();</span><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">issues</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">fetchIssues</span><span class="hl-1">();</span><br/><br/><span class="hl-7">// ✅ FAST - Parallel</span><br/><span class="hl-4">const</span><span class="hl-1"> [</span><span class="hl-8">user</span><span class="hl-1">, </span><span class="hl-8">repos</span><span class="hl-1">, </span><span class="hl-8">issues</span><span class="hl-1">] = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-5">Promise</span><span class="hl-1">.</span><span class="hl-6">all</span><span class="hl-1">([</span><br/><span class="hl-1"> </span><span class="hl-6">fetchUser</span><span class="hl-1">(),</span><br/><span class="hl-1"> </span><span class="hl-6">fetchRepos</span><span class="hl-1">(),</span><br/><span class="hl-1"> </span><span class="hl-6">fetchIssues</span><span class="hl-1">()</span><br/><span class="hl-1">]);</span>
122
123
  </code><button type="button">Copy</button></pre>
@@ -126,7 +127,7 @@
126
127
  </code><button type="button">Copy</button></pre>
127
128
 
128
129
  <h3 id="4-debouncing" class="tsd-anchor-link">4. Debouncing<a href="#4-debouncing" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Avoid processing duplicate events:</p>
129
- <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">onWebhook</span><span class="hl-1">(</span><span class="hl-2">request</span><span class="hl-1">: </span><span class="hl-2">WebhookRequest</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">eventId</span><span class="hl-1"> = </span><span class="hl-2">request</span><span class="hl-1">.</span><span class="hl-2">body</span><span class="hl-1">.</span><span class="hl-2">id</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Check if already processed</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">processed</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">boolean</span><span class="hl-1">&gt;(</span><span class="hl-3">`processed:</span><span class="hl-4">${</span><span class="hl-2">eventId</span><span class="hl-4">}</span><span class="hl-3">`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">processed</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&quot;Event already processed&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1">;</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Process and mark as done</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processEvent</span><span class="hl-1">(</span><span class="hl-2">request</span><span class="hl-1">.</span><span class="hl-2">body</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">`processed:</span><span class="hl-4">${</span><span class="hl-2">eventId</span><span class="hl-4">}</span><span class="hl-3">`</span><span class="hl-1">, </span><span class="hl-4">true</span><span class="hl-1">);</span><br/><span class="hl-1">}</span>
130
+ <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">onWebhook</span><span class="hl-1">(</span><span class="hl-2">request</span><span class="hl-1">: </span><span class="hl-2">WebhookRequest</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">eventId</span><span class="hl-1"> = (</span><span class="hl-2">request</span><span class="hl-1">.</span><span class="hl-2">body</span><span class="hl-1"> </span><span class="hl-0">as</span><span class="hl-1"> { </span><span class="hl-2">id</span><span class="hl-1">: </span><span class="hl-5">string</span><span class="hl-1"> }).</span><span class="hl-2">id</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Check if already processed</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">processed</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">boolean</span><span class="hl-1">&gt;(</span><span class="hl-3">`processed:</span><span class="hl-4">${</span><span class="hl-2">eventId</span><span class="hl-4">}</span><span class="hl-3">`</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">processed</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-2">console</span><span class="hl-1">.</span><span class="hl-6">log</span><span class="hl-1">(</span><span class="hl-3">&quot;Event already processed&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1">;</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Process and mark as done</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processEvent</span><span class="hl-1">(</span><span class="hl-2">request</span><span class="hl-1">.</span><span class="hl-2">body</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">`processed:</span><span class="hl-4">${</span><span class="hl-2">eventId</span><span class="hl-4">}</span><span class="hl-3">`</span><span class="hl-1">, </span><span class="hl-4">true</span><span class="hl-1">);</span><br/><span class="hl-1">}</span>
130
131
  </code><button type="button">Copy</button></pre>
131
132
 
132
133
  <hr>
@@ -141,7 +142,7 @@
141
142
  <li><strong>Use runTask()</strong> - Each task gets a fresh execution with new request limit</li>
142
143
  <li><strong>Size batches appropriately</strong> - Calculate requests per item to determine safe batch size</li>
143
144
  </ol>
144
- <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">longOperation</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">items</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">fetchItems</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Calculate safe batch size based on requests per item</span><br/><span class="hl-1"> </span><span class="hl-7">// If each item makes ~10 requests, batch size = 1000 / 10 = 100 items</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">requestsPerItem</span><span class="hl-1"> = </span><span class="hl-14">10</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">safeItemsPerBatch</span><span class="hl-1"> = </span><span class="hl-2">Math</span><span class="hl-1">.</span><span class="hl-6">floor</span><span class="hl-1">(</span><span class="hl-14">1000</span><span class="hl-1"> / </span><span class="hl-2">requestsPerItem</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Process in batches to stay under request limit</span><br/><span class="hl-1"> </span><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">let</span><span class="hl-1"> </span><span class="hl-2">i</span><span class="hl-1"> = </span><span class="hl-14">0</span><span class="hl-1">; </span><span class="hl-2">i</span><span class="hl-1"> &lt; </span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-2">length</span><span class="hl-1">; </span><span class="hl-2">i</span><span class="hl-1"> += </span><span class="hl-2">safeItemsPerBatch</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">batch</span><span class="hl-1"> = </span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-6">slice</span><span class="hl-1">(</span><span class="hl-2">i</span><span class="hl-1">, </span><span class="hl-2">i</span><span class="hl-1"> + </span><span class="hl-2">safeItemsPerBatch</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;remaining_items&quot;</span><span class="hl-1">, </span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-6">slice</span><span class="hl-1">(</span><span class="hl-2">i</span><span class="hl-1"> + </span><span class="hl-2">safeItemsPerBatch</span><span class="hl-1">));</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;processed_count&quot;</span><span class="hl-1">, </span><span class="hl-2">i</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-3">&quot;processBatch&quot;</span><span class="hl-1">, </span><span class="hl-2">batch</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// New execution = fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">processBatch</span><span class="hl-1">(</span><span class="hl-2">args</span><span class="hl-1">: </span><span class="hl-2">any</span><span class="hl-1">, </span><span class="hl-2">batch</span><span class="hl-1">: </span><span class="hl-2">Item</span><span class="hl-1">[]) {</span><br/><span class="hl-1"> </span><span class="hl-7">// Process items within this execution&#39;s request limit</span><br/><span class="hl-1"> </span><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">item</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-2">batch</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processItem</span><span class="hl-1">(</span><span class="hl-2">item</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">remaining</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">Item</span><span class="hl-1">[]&gt;(</span><span class="hl-3">&quot;remaining_items&quot;</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">remaining</span><span class="hl-1"> &amp;&amp; </span><span class="hl-2">remaining</span><span class="hl-1">.</span><span class="hl-2">length</span><span class="hl-1"> &gt; </span><span class="hl-14">0</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-7">// Continue with next batch in new execution</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">longOperation</span><span class="hl-1">();</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
145
+ <pre><code class="typescript"><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">longOperation</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">items</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-6">fetchItems</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Calculate safe batch size based on requests per item</span><br/><span class="hl-1"> </span><span class="hl-7">// If each item makes ~10 requests, batch size = 1000 / 10 = 100 items</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">requestsPerItem</span><span class="hl-1"> = </span><span class="hl-14">10</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">safeItemsPerBatch</span><span class="hl-1"> = </span><span class="hl-2">Math</span><span class="hl-1">.</span><span class="hl-6">floor</span><span class="hl-1">(</span><span class="hl-14">1000</span><span class="hl-1"> / </span><span class="hl-2">requestsPerItem</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;remaining_items&quot;</span><span class="hl-1">, </span><span class="hl-2">items</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;batch_size&quot;</span><span class="hl-1">, </span><span class="hl-2">safeItemsPerBatch</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">processBatch</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-7">// New execution = fresh request limit</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-2">async</span><span class="hl-1"> </span><span class="hl-6">processBatch</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">items</span><span class="hl-1"> = (</span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">Item</span><span class="hl-1">[]&gt;(</span><span class="hl-3">&quot;remaining_items&quot;</span><span class="hl-1">)) ?? [];</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">batchSize</span><span class="hl-1"> = (</span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">get</span><span class="hl-1">&lt;</span><span class="hl-5">number</span><span class="hl-1">&gt;(</span><span class="hl-3">&quot;batch_size&quot;</span><span class="hl-1">)) ?? </span><span class="hl-14">50</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">batch</span><span class="hl-1"> = </span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-6">slice</span><span class="hl-1">(</span><span class="hl-14">0</span><span class="hl-1">, </span><span class="hl-2">batchSize</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-7">// Process items within this execution&#39;s request limit</span><br/><span class="hl-1"> </span><span class="hl-0">for</span><span class="hl-1"> (</span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">item</span><span class="hl-1"> </span><span class="hl-4">of</span><span class="hl-1"> </span><span class="hl-2">batch</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">processItem</span><span class="hl-1">(</span><span class="hl-2">item</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">remaining</span><span class="hl-1"> = </span><span class="hl-2">items</span><span class="hl-1">.</span><span class="hl-6">slice</span><span class="hl-1">(</span><span class="hl-2">batchSize</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">set</span><span class="hl-1">(</span><span class="hl-3">&quot;remaining_items&quot;</span><span class="hl-1">, </span><span class="hl-2">remaining</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">remaining</span><span class="hl-1">.</span><span class="hl-2">length</span><span class="hl-1"> &gt; </span><span class="hl-14">0</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-7">// Continue with next batch in a new execution</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-8">callback</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">callback</span><span class="hl-1">(</span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-2">processBatch</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-4">this</span><span class="hl-1">.</span><span class="hl-6">runTask</span><span class="hl-1">(</span><span class="hl-2">callback</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span>
145
146
  </code><button type="button">Copy</button></pre>
146
147
 
147
148
  <hr>