zilmate 1.8.1 → 1.8.5

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 (313) hide show
  1. package/.agents/skills/copywriting/SKILL.md +252 -0
  2. package/.agents/skills/copywriting/evals/evals.json +111 -0
  3. package/.agents/skills/copywriting/references/copy-frameworks.md +344 -0
  4. package/.agents/skills/copywriting/references/natural-transitions.md +272 -0
  5. package/.agents/skills/firecrawl-deep-research/SKILL.md +108 -0
  6. package/.agents/skills/shadcn/SKILL.md +267 -0
  7. package/.agents/skills/shadcn/agents/openai.yml +5 -0
  8. package/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
  9. package/.agents/skills/shadcn/assets/shadcn.png +0 -0
  10. package/.agents/skills/shadcn/cli.md +290 -0
  11. package/.agents/skills/shadcn/customization.md +209 -0
  12. package/.agents/skills/shadcn/evals/evals.json +47 -0
  13. package/.agents/skills/shadcn/mcp.md +105 -0
  14. package/.agents/skills/shadcn/registry.md +277 -0
  15. package/.agents/skills/shadcn/rules/base-vs-radix.md +306 -0
  16. package/.agents/skills/shadcn/rules/composition.md +195 -0
  17. package/.agents/skills/shadcn/rules/forms.md +192 -0
  18. package/.agents/skills/shadcn/rules/icons.md +101 -0
  19. package/.agents/skills/shadcn/rules/styling.md +162 -0
  20. package/.agents/skills/tavily-research/SKILL.md +100 -0
  21. package/.agents/skills/upstash/SKILL.md +48 -0
  22. package/.agents/skills/upstash/upstash-box-js/overview.md +243 -0
  23. package/.agents/skills/upstash/upstash-box-py/overview.md +275 -0
  24. package/.agents/skills/upstash/upstash-cli/overview.md +138 -0
  25. package/.agents/skills/upstash/upstash-qstash-js/advanced/callbacks.md +147 -0
  26. package/.agents/skills/upstash/upstash-qstash-js/advanced/deduplication.md +86 -0
  27. package/.agents/skills/upstash/upstash-qstash-js/advanced/dlq.md +164 -0
  28. package/.agents/skills/upstash/upstash-qstash-js/advanced/multi-region/summary.md +388 -0
  29. package/.agents/skills/upstash/upstash-qstash-js/advanced/multi-region/verify-multi-region-setup.ts +388 -0
  30. package/.agents/skills/upstash/upstash-qstash-js/fundamentals/local-development.md +106 -0
  31. package/.agents/skills/upstash/upstash-qstash-js/fundamentals/publishing-messages.md +144 -0
  32. package/.agents/skills/upstash/upstash-qstash-js/fundamentals/queues-and-flow-control.md +148 -0
  33. package/.agents/skills/upstash/upstash-qstash-js/fundamentals/schedules.md +177 -0
  34. package/.agents/skills/upstash/upstash-qstash-js/fundamentals/url-groups.md +127 -0
  35. package/.agents/skills/upstash/upstash-qstash-js/overview.md +81 -0
  36. package/.agents/skills/upstash/upstash-qstash-js/verification/platform-specific/nextjs.md +171 -0
  37. package/.agents/skills/upstash/upstash-qstash-js/verification/receiver.md +213 -0
  38. package/.agents/skills/upstash/upstash-ratelimit-js/algorithms.md +84 -0
  39. package/.agents/skills/upstash/upstash-ratelimit-js/features.md +117 -0
  40. package/.agents/skills/upstash/upstash-ratelimit-js/methods-getting-started.md +77 -0
  41. package/.agents/skills/upstash/upstash-ratelimit-js/overview.md +26 -0
  42. package/.agents/skills/upstash/upstash-ratelimit-js/pricing-cost.md +146 -0
  43. package/.agents/skills/upstash/upstash-ratelimit-js/traffic-protection.md +77 -0
  44. package/.agents/skills/upstash/upstash-redis-js/advanced-features/auto-pipeline.md +49 -0
  45. package/.agents/skills/upstash/upstash-redis-js/advanced-features/pipeline-and-transactions.md +42 -0
  46. package/.agents/skills/upstash/upstash-redis-js/advanced-features/scripting.md +124 -0
  47. package/.agents/skills/upstash/upstash-redis-js/data-structures/hashes.md +71 -0
  48. package/.agents/skills/upstash/upstash-redis-js/data-structures/json.md +133 -0
  49. package/.agents/skills/upstash/upstash-redis-js/data-structures/lists.md +72 -0
  50. package/.agents/skills/upstash/upstash-redis-js/data-structures/sets.md +90 -0
  51. package/.agents/skills/upstash/upstash-redis-js/data-structures/sorted-sets.md +126 -0
  52. package/.agents/skills/upstash/upstash-redis-js/data-structures/streams.md +196 -0
  53. package/.agents/skills/upstash/upstash-redis-js/data-structures/strings.md +73 -0
  54. package/.agents/skills/upstash/upstash-redis-js/migrations/from-ioredis.md +163 -0
  55. package/.agents/skills/upstash/upstash-redis-js/migrations/from-redis-node.md +205 -0
  56. package/.agents/skills/upstash/upstash-redis-js/overview.md +183 -0
  57. package/.agents/skills/upstash/upstash-redis-js/patterns/caching.md +58 -0
  58. package/.agents/skills/upstash/upstash-redis-js/patterns/distributed-locks.md +130 -0
  59. package/.agents/skills/upstash/upstash-redis-js/patterns/leaderboard.md +134 -0
  60. package/.agents/skills/upstash/upstash-redis-js/patterns/rate-limiting.md +187 -0
  61. package/.agents/skills/upstash/upstash-redis-js/patterns/session-management.md +217 -0
  62. package/.agents/skills/upstash/upstash-redis-js/performance/batching-operations.md +76 -0
  63. package/.agents/skills/upstash/upstash-redis-js/performance/data-serialization.md +134 -0
  64. package/.agents/skills/upstash/upstash-redis-js/performance/error-handling.md +118 -0
  65. package/.agents/skills/upstash/upstash-redis-js/performance/pipeline-optimization.md +105 -0
  66. package/.agents/skills/upstash/upstash-redis-js/performance/redis-replicas.md +14 -0
  67. package/.agents/skills/upstash/upstash-redis-js/performance/ttl-expiration.md +32 -0
  68. package/.agents/skills/upstash/upstash-redis-js/search/adapters.md +99 -0
  69. package/.agents/skills/upstash/upstash-redis-js/search/commands/aggregating.md +234 -0
  70. package/.agents/skills/upstash/upstash-redis-js/search/commands/aliases.md +76 -0
  71. package/.agents/skills/upstash/upstash-redis-js/search/commands/index-management.md +124 -0
  72. package/.agents/skills/upstash/upstash-redis-js/search/commands/querying.md +315 -0
  73. package/.agents/skills/upstash/upstash-redis-js/search/overview.md +155 -0
  74. package/.agents/skills/upstash/upstash-redis-start/overview.md +71 -0
  75. package/.agents/skills/upstash/upstash-search-js/overview.md +48 -0
  76. package/.agents/skills/upstash/upstash-search-js/quick-start.md +158 -0
  77. package/.agents/skills/upstash/upstash-search-js/sdk-overview.md +158 -0
  78. package/.agents/skills/upstash/upstash-vector-js/features/filtering-and-metadata.md +82 -0
  79. package/.agents/skills/upstash/upstash-vector-js/features/index-structure.md +193 -0
  80. package/.agents/skills/upstash/upstash-vector-js/features/namespaces.md +32 -0
  81. package/.agents/skills/upstash/upstash-vector-js/overview.md +44 -0
  82. package/.agents/skills/upstash/upstash-vector-js/sdk-methods.md +210 -0
  83. package/.agents/skills/upstash/upstash-workflow-js/agents.md +248 -0
  84. package/.agents/skills/upstash/upstash-workflow-js/basics/client.md +180 -0
  85. package/.agents/skills/upstash/upstash-workflow-js/basics/context.md +230 -0
  86. package/.agents/skills/upstash/upstash-workflow-js/basics/serve.md +70 -0
  87. package/.agents/skills/upstash/upstash-workflow-js/features/flow-control.md +145 -0
  88. package/.agents/skills/upstash/upstash-workflow-js/features/invoke.md +97 -0
  89. package/.agents/skills/upstash/upstash-workflow-js/features/retries-failures-reliability.md +239 -0
  90. package/.agents/skills/upstash/upstash-workflow-js/features/wait-for-event.md +97 -0
  91. package/.agents/skills/upstash/upstash-workflow-js/features/webhooks.md +79 -0
  92. package/.agents/skills/upstash/upstash-workflow-js/how-to/local-dev.md +177 -0
  93. package/.agents/skills/upstash/upstash-workflow-js/how-to/middleware.md +166 -0
  94. package/.agents/skills/upstash/upstash-workflow-js/how-to/migrations.md +201 -0
  95. package/.agents/skills/upstash/upstash-workflow-js/how-to/realtime.md +186 -0
  96. package/.agents/skills/upstash/upstash-workflow-js/overview.md +55 -0
  97. package/.agents/skills/upstash/upstash-workflow-js/rest-api.md +156 -0
  98. package/.agents/skills/upstash/upstash-workflow-js/troubleshooting.md +201 -0
  99. package/.agents/skills/upstash-box-js/SKILL.md +248 -0
  100. package/.agents/skills/upstash-box-py/SKILL.md +280 -0
  101. package/.agents/skills/upstash-cli/SKILL.md +143 -0
  102. package/.agents/skills/upstash-qstash-js/SKILL.md +86 -0
  103. package/.agents/skills/upstash-qstash-js/advanced/callbacks.md +147 -0
  104. package/.agents/skills/upstash-qstash-js/advanced/deduplication.md +86 -0
  105. package/.agents/skills/upstash-qstash-js/advanced/dlq.md +164 -0
  106. package/.agents/skills/upstash-qstash-js/advanced/multi-region/summary.md +388 -0
  107. package/.agents/skills/upstash-qstash-js/advanced/multi-region/verify-multi-region-setup.ts +388 -0
  108. package/.agents/skills/upstash-qstash-js/fundamentals/local-development.md +106 -0
  109. package/.agents/skills/upstash-qstash-js/fundamentals/publishing-messages.md +144 -0
  110. package/.agents/skills/upstash-qstash-js/fundamentals/queues-and-flow-control.md +148 -0
  111. package/.agents/skills/upstash-qstash-js/fundamentals/schedules.md +177 -0
  112. package/.agents/skills/upstash-qstash-js/fundamentals/url-groups.md +127 -0
  113. package/.agents/skills/upstash-qstash-js/verification/platform-specific/nextjs.md +171 -0
  114. package/.agents/skills/upstash-qstash-js/verification/receiver.md +213 -0
  115. package/.agents/skills/upstash-ratelimit-js/SKILL.md +31 -0
  116. package/.agents/skills/upstash-ratelimit-js/algorithms.md +84 -0
  117. package/.agents/skills/upstash-ratelimit-js/features.md +117 -0
  118. package/.agents/skills/upstash-ratelimit-js/methods-getting-started.md +77 -0
  119. package/.agents/skills/upstash-ratelimit-js/pricing-cost.md +146 -0
  120. package/.agents/skills/upstash-ratelimit-js/traffic-protection.md +77 -0
  121. package/.agents/skills/upstash-redis-js/SKILL.md +188 -0
  122. package/.agents/skills/upstash-redis-js/advanced-features/auto-pipeline.md +49 -0
  123. package/.agents/skills/upstash-redis-js/advanced-features/pipeline-and-transactions.md +42 -0
  124. package/.agents/skills/upstash-redis-js/advanced-features/scripting.md +124 -0
  125. package/.agents/skills/upstash-redis-js/data-structures/hashes.md +71 -0
  126. package/.agents/skills/upstash-redis-js/data-structures/json.md +133 -0
  127. package/.agents/skills/upstash-redis-js/data-structures/lists.md +72 -0
  128. package/.agents/skills/upstash-redis-js/data-structures/sets.md +90 -0
  129. package/.agents/skills/upstash-redis-js/data-structures/sorted-sets.md +126 -0
  130. package/.agents/skills/upstash-redis-js/data-structures/streams.md +196 -0
  131. package/.agents/skills/upstash-redis-js/data-structures/strings.md +73 -0
  132. package/.agents/skills/upstash-redis-js/migrations/from-ioredis.md +163 -0
  133. package/.agents/skills/upstash-redis-js/migrations/from-redis-node.md +205 -0
  134. package/.agents/skills/upstash-redis-js/patterns/caching.md +58 -0
  135. package/.agents/skills/upstash-redis-js/patterns/distributed-locks.md +130 -0
  136. package/.agents/skills/upstash-redis-js/patterns/leaderboard.md +134 -0
  137. package/.agents/skills/upstash-redis-js/patterns/rate-limiting.md +187 -0
  138. package/.agents/skills/upstash-redis-js/patterns/session-management.md +217 -0
  139. package/.agents/skills/upstash-redis-js/performance/batching-operations.md +76 -0
  140. package/.agents/skills/upstash-redis-js/performance/data-serialization.md +134 -0
  141. package/.agents/skills/upstash-redis-js/performance/error-handling.md +118 -0
  142. package/.agents/skills/upstash-redis-js/performance/pipeline-optimization.md +105 -0
  143. package/.agents/skills/upstash-redis-js/performance/redis-replicas.md +14 -0
  144. package/.agents/skills/upstash-redis-js/performance/ttl-expiration.md +32 -0
  145. package/.agents/skills/upstash-redis-js/search/adapters.md +99 -0
  146. package/.agents/skills/upstash-redis-js/search/commands/aggregating.md +234 -0
  147. package/.agents/skills/upstash-redis-js/search/commands/aliases.md +76 -0
  148. package/.agents/skills/upstash-redis-js/search/commands/index-management.md +124 -0
  149. package/.agents/skills/upstash-redis-js/search/commands/querying.md +315 -0
  150. package/.agents/skills/upstash-redis-js/search/overview.md +155 -0
  151. package/.agents/skills/upstash-redis-start/SKILL.md +76 -0
  152. package/.agents/skills/upstash-search-js/SKILL.md +53 -0
  153. package/.agents/skills/upstash-search-js/quick-start.md +158 -0
  154. package/.agents/skills/upstash-search-js/sdk-overview.md +158 -0
  155. package/.agents/skills/upstash-vector-js/SKILL.md +49 -0
  156. package/.agents/skills/upstash-vector-js/features/filtering-and-metadata.md +82 -0
  157. package/.agents/skills/upstash-vector-js/features/index-structure.md +193 -0
  158. package/.agents/skills/upstash-vector-js/features/namespaces.md +32 -0
  159. package/.agents/skills/upstash-vector-js/sdk-methods.md +210 -0
  160. package/.agents/skills/upstash-workflow-js/SKILL.md +60 -0
  161. package/.agents/skills/upstash-workflow-js/agents.md +248 -0
  162. package/.agents/skills/upstash-workflow-js/basics/client.md +180 -0
  163. package/.agents/skills/upstash-workflow-js/basics/context.md +230 -0
  164. package/.agents/skills/upstash-workflow-js/basics/serve.md +70 -0
  165. package/.agents/skills/upstash-workflow-js/features/flow-control.md +145 -0
  166. package/.agents/skills/upstash-workflow-js/features/invoke.md +97 -0
  167. package/.agents/skills/upstash-workflow-js/features/retries-failures-reliability.md +239 -0
  168. package/.agents/skills/upstash-workflow-js/features/wait-for-event.md +97 -0
  169. package/.agents/skills/upstash-workflow-js/features/webhooks.md +79 -0
  170. package/.agents/skills/upstash-workflow-js/how-to/local-dev.md +177 -0
  171. package/.agents/skills/upstash-workflow-js/how-to/middleware.md +166 -0
  172. package/.agents/skills/upstash-workflow-js/how-to/migrations.md +201 -0
  173. package/.agents/skills/upstash-workflow-js/how-to/realtime.md +186 -0
  174. package/.agents/skills/upstash-workflow-js/rest-api.md +156 -0
  175. package/.agents/skills/upstash-workflow-js/troubleshooting.md +201 -0
  176. package/dist/agents/coding.agent.d.ts +185 -42
  177. package/dist/agents/coding.agent.d.ts.map +1 -1
  178. package/dist/agents/coding.agent.js +42 -5
  179. package/dist/agents/coding.agent.js.map +1 -1
  180. package/dist/agents/manager.d.ts +216 -41
  181. package/dist/agents/manager.d.ts.map +1 -1
  182. package/dist/agents/manager.js +103 -140
  183. package/dist/agents/manager.js.map +1 -1
  184. package/dist/agents/security.agent.d.ts +3 -3
  185. package/dist/agents/swarm/development/lead.d.ts +3 -0
  186. package/dist/agents/swarm/development/lead.d.ts.map +1 -0
  187. package/dist/agents/swarm/development/lead.js +24 -0
  188. package/dist/agents/swarm/development/lead.js.map +1 -0
  189. package/dist/agents/swarm/main.d.ts +69 -0
  190. package/dist/agents/swarm/main.d.ts.map +1 -1
  191. package/dist/agents/swarm/main.js +65 -11
  192. package/dist/agents/swarm/main.js.map +1 -1
  193. package/dist/agents/swarm/registry.d.ts +2 -1
  194. package/dist/agents/swarm/registry.d.ts.map +1 -1
  195. package/dist/agents/swarm/registry.js +225 -95
  196. package/dist/agents/swarm/registry.js.map +1 -1
  197. package/dist/cli/composer.d.ts.map +1 -1
  198. package/dist/cli/composer.js +85 -30
  199. package/dist/cli/composer.js.map +1 -1
  200. package/dist/cli/confirm.d.ts +2 -2
  201. package/dist/cli/confirm.d.ts.map +1 -1
  202. package/dist/cli/confirm.js +373 -4
  203. package/dist/cli/confirm.js.map +1 -1
  204. package/dist/cli/doctor.d.ts +1 -0
  205. package/dist/cli/doctor.d.ts.map +1 -1
  206. package/dist/cli/doctor.js +47 -2
  207. package/dist/cli/doctor.js.map +1 -1
  208. package/dist/cli/format.d.ts +4 -0
  209. package/dist/cli/format.d.ts.map +1 -1
  210. package/dist/cli/format.js +352 -65
  211. package/dist/cli/format.js.map +1 -1
  212. package/dist/cli/interactive.d.ts.map +1 -1
  213. package/dist/cli/interactive.js +80 -2
  214. package/dist/cli/interactive.js.map +1 -1
  215. package/dist/cli/menu.d.ts.map +1 -1
  216. package/dist/cli/menu.js +93 -83
  217. package/dist/cli/menu.js.map +1 -1
  218. package/dist/cli/render.d.ts.map +1 -1
  219. package/dist/cli/render.js +2 -1
  220. package/dist/cli/render.js.map +1 -1
  221. package/dist/cli/setup.d.ts.map +1 -1
  222. package/dist/cli/setup.js +262 -27
  223. package/dist/cli/setup.js.map +1 -1
  224. package/dist/cli/swarm.d.ts.map +1 -1
  225. package/dist/cli/swarm.js +13 -10
  226. package/dist/cli/swarm.js.map +1 -1
  227. package/dist/cli/theme.d.ts +7 -1
  228. package/dist/cli/theme.d.ts.map +1 -1
  229. package/dist/cli/theme.js +4 -16
  230. package/dist/cli/theme.js.map +1 -1
  231. package/dist/cli/update.d.ts.map +1 -1
  232. package/dist/cli/update.js +12 -4
  233. package/dist/cli/update.js.map +1 -1
  234. package/dist/config/env.d.ts +3 -1
  235. package/dist/config/env.d.ts.map +1 -1
  236. package/dist/config/env.js +22 -2
  237. package/dist/config/env.js.map +1 -1
  238. package/dist/config/models.d.ts +1 -0
  239. package/dist/config/models.d.ts.map +1 -1
  240. package/dist/config/models.js +17 -1
  241. package/dist/config/models.js.map +1 -1
  242. package/dist/documents/pdf.d.ts.map +1 -1
  243. package/dist/documents/pdf.js +282 -22
  244. package/dist/documents/pdf.js.map +1 -1
  245. package/dist/documents/slides.d.ts.map +1 -1
  246. package/dist/documents/slides.js +160 -30
  247. package/dist/documents/slides.js.map +1 -1
  248. package/dist/index.js +73 -18
  249. package/dist/index.js.map +1 -1
  250. package/dist/memory/history.js +1 -1
  251. package/dist/observability/doctor.d.ts.map +1 -1
  252. package/dist/observability/doctor.js +3 -0
  253. package/dist/observability/doctor.js.map +1 -1
  254. package/dist/runtime/progress.d.ts +5 -1
  255. package/dist/runtime/progress.d.ts.map +1 -1
  256. package/dist/runtime/progress.js.map +1 -1
  257. package/dist/runtime/swarm.d.ts +1 -1
  258. package/dist/runtime/swarm.d.ts.map +1 -1
  259. package/dist/runtime/swarm.js +19 -3
  260. package/dist/runtime/swarm.js.map +1 -1
  261. package/dist/runtime/tool-utils.d.ts +2 -0
  262. package/dist/runtime/tool-utils.d.ts.map +1 -1
  263. package/dist/runtime/tool-utils.js +91 -0
  264. package/dist/runtime/tool-utils.js.map +1 -1
  265. package/dist/server.js +1 -1
  266. package/dist/server.js.map +1 -1
  267. package/dist/skills/loader.d.ts.map +1 -1
  268. package/dist/skills/loader.js +16 -0
  269. package/dist/skills/loader.js.map +1 -1
  270. package/dist/test-call.d.ts +2 -0
  271. package/dist/test-call.d.ts.map +1 -0
  272. package/dist/test-call.js +29 -0
  273. package/dist/test-call.js.map +1 -0
  274. package/dist/test-manager-call.d.ts +2 -0
  275. package/dist/test-manager-call.d.ts.map +1 -0
  276. package/dist/test-manager-call.js +138 -0
  277. package/dist/test-manager-call.js.map +1 -0
  278. package/dist/test-manager-filtered.d.ts +2 -0
  279. package/dist/test-manager-filtered.d.ts.map +1 -0
  280. package/dist/test-manager-filtered.js +130 -0
  281. package/dist/test-manager-filtered.js.map +1 -0
  282. package/dist/test-mcp-call.d.ts +2 -0
  283. package/dist/test-mcp-call.d.ts.map +1 -0
  284. package/dist/test-mcp-call.js +103 -0
  285. package/dist/test-mcp-call.js.map +1 -0
  286. package/dist/tools/composio.tool.d.ts +1 -1
  287. package/dist/tools/composio.tool.d.ts.map +1 -1
  288. package/dist/tools/composio.tool.js +7 -16
  289. package/dist/tools/composio.tool.js.map +1 -1
  290. package/dist/tools/executive.tool.d.ts +40 -0
  291. package/dist/tools/executive.tool.d.ts.map +1 -0
  292. package/dist/tools/executive.tool.js +74 -0
  293. package/dist/tools/executive.tool.js.map +1 -0
  294. package/dist/tools/filesystem.tool.d.ts +183 -40
  295. package/dist/tools/filesystem.tool.d.ts.map +1 -1
  296. package/dist/tools/filesystem.tool.js +564 -111
  297. package/dist/tools/filesystem.tool.js.map +1 -1
  298. package/dist/tools/mcp.tool.d.ts +56 -0
  299. package/dist/tools/mcp.tool.d.ts.map +1 -0
  300. package/dist/tools/mcp.tool.js +285 -0
  301. package/dist/tools/mcp.tool.js.map +1 -0
  302. package/dist/tools/osint.tool.d.ts +4 -4
  303. package/dist/tools/pentest.tool.d.ts +2 -2
  304. package/dist/tools/setup-assistant.tool.d.ts +1 -1
  305. package/dist/tools/setup-assistant.tool.js +1 -1
  306. package/dist/tools/setup-assistant.tool.js.map +1 -1
  307. package/dist/workspace/paths.d.ts +1 -0
  308. package/dist/workspace/paths.d.ts.map +1 -1
  309. package/dist/workspace/paths.js +3 -4
  310. package/dist/workspace/paths.js.map +1 -1
  311. package/package.json +7 -3
  312. package/scripts/postinstall.mjs +19 -4
  313. package/scripts/release-github.mjs +11 -11
@@ -0,0 +1,187 @@
1
+ # Rate Limiting
2
+
3
+ ## Overview
4
+
5
+ Control request rates to prevent abuse and ensure fair resource usage. Use counters with TTL for simple rate limiting, or @upstash/ratelimit for production.
6
+
7
+ ## Good For
8
+
9
+ - API rate limiting (requests per user/IP)
10
+ - Preventing brute force attacks
11
+ - Throttling expensive operations
12
+ - Fair resource allocation
13
+
14
+ ## Limitations
15
+
16
+ - Simple counters can be imprecise at window boundaries
17
+ - Distributed rate limiting requires careful coordination
18
+ - Use @upstash/ratelimit for production (supports multiple algorithms)
19
+
20
+ ## Examples
21
+
22
+ ```typescript
23
+ import { Redis } from "@upstash/redis";
24
+
25
+ const redis = Redis.fromEnv();
26
+
27
+ // Simple fixed-window rate limiter
28
+ async function simpleRateLimit(userId: string, limit: number = 10, window: number = 60) {
29
+ const key = `ratelimit:${userId}`;
30
+
31
+ const count = await redis.incr(key);
32
+
33
+ if (count === 1) {
34
+ await redis.expire(key, window);
35
+ }
36
+
37
+ return {
38
+ allowed: count <= limit,
39
+ remaining: Math.max(0, limit - count),
40
+ reset: window,
41
+ };
42
+ }
43
+
44
+ // Usage
45
+ const result = await simpleRateLimit("user:123", 10, 60);
46
+
47
+ if (!result.allowed) {
48
+ throw new Error("Rate limit exceeded");
49
+ }
50
+
51
+ // Sliding window rate limiter using sorted set
52
+ async function slidingWindowRateLimit(userId: string, limit: number = 10, window: number = 60) {
53
+ const key = `ratelimit:sliding:${userId}`;
54
+ const now = Date.now();
55
+ const windowStart = now - window * 1000;
56
+
57
+ // Remove old entries
58
+ await redis.zremrangebyscore(key, 0, windowStart);
59
+
60
+ // Count requests in window
61
+ const count = await redis.zcard(key);
62
+
63
+ if (count >= limit) {
64
+ return { allowed: false, remaining: 0 };
65
+ }
66
+
67
+ // Add current request
68
+ await redis.zadd(key, { score: now, member: `${now}:${Math.random()}` });
69
+ await redis.expire(key, window * 2); // Cleanup
70
+
71
+ return {
72
+ allowed: true,
73
+ remaining: limit - count - 1,
74
+ };
75
+ }
76
+
77
+ // Token bucket using Lua script
78
+ const tokenBucketScript = `
79
+ local key = KEYS[1]
80
+ local capacity = tonumber(ARGV[1])
81
+ local rate = tonumber(ARGV[2])
82
+ local now = tonumber(ARGV[3])
83
+
84
+ local bucket = redis.call('HMGET', key, 'tokens', 'last_refill')
85
+ local tokens = tonumber(bucket[1] or capacity)
86
+ local last_refill = tonumber(bucket[2] or now)
87
+
88
+ -- Refill tokens based on time elapsed
89
+ local elapsed = now - last_refill
90
+ local refill = math.floor(elapsed * rate)
91
+ tokens = math.min(capacity, tokens + refill)
92
+
93
+ if tokens >= 1 then
94
+ tokens = tokens - 1
95
+ redis.call('HMSET', key, 'tokens', tokens, 'last_refill', now)
96
+ redis.call('EXPIRE', key, 3600)
97
+ return 1
98
+ else
99
+ return 0
100
+ end
101
+ `;
102
+
103
+ async function tokenBucketRateLimit(userId: string, capacity: number = 10, rate: number = 1) {
104
+ const key = `ratelimit:bucket:${userId}`;
105
+ const now = Date.now() / 1000;
106
+
107
+ const allowed = await redis.eval<number>(tokenBucketScript, [key], [capacity, rate, now]);
108
+
109
+ return { allowed: allowed === 1 };
110
+ }
111
+
112
+ // Production: Use @upstash/ratelimit
113
+ // npm install @upstash/ratelimit
114
+ import { Ratelimit } from "@upstash/ratelimit";
115
+
116
+ // Fixed window
117
+ const fixedWindowLimiter = new Ratelimit({
118
+ redis,
119
+ limiter: Ratelimit.fixedWindow(10, "60 s"),
120
+ });
121
+
122
+ // Sliding window
123
+ const slidingWindowLimiter = new Ratelimit({
124
+ redis,
125
+ limiter: Ratelimit.slidingWindow(10, "60 s"),
126
+ });
127
+
128
+ // Token bucket
129
+ const tokenBucketLimiter = new Ratelimit({
130
+ redis,
131
+ limiter: Ratelimit.tokenBucket(10, "1 s", 10),
132
+ });
133
+
134
+ // Usage
135
+ async function handleRequest(userId: string) {
136
+ const { success, limit, remaining, reset } = await fixedWindowLimiter.limit(userId);
137
+
138
+ if (!success) {
139
+ return {
140
+ error: "Rate limit exceeded",
141
+ limit,
142
+ remaining,
143
+ reset,
144
+ };
145
+ }
146
+
147
+ // Process request
148
+ return { data: "Success", remaining };
149
+ }
150
+
151
+ // Multi-tier rate limiting
152
+ async function multiTierRateLimit(userId: string, tier: "free" | "pro") {
153
+ const limits = {
154
+ free: { requests: 100, window: 3600 },
155
+ pro: { requests: 1000, window: 3600 },
156
+ };
157
+
158
+ const config = limits[tier];
159
+ return await simpleRateLimit(userId, config.requests, config.window);
160
+ }
161
+
162
+ // Per-endpoint rate limiting
163
+ async function endpointRateLimit(userId: string, endpoint: string) {
164
+ const key = `${userId}:${endpoint}`;
165
+ return await simpleRateLimit(key, 10, 60);
166
+ }
167
+
168
+ // IP-based rate limiting
169
+ async function ipRateLimit(ip: string) {
170
+ return await simpleRateLimit(`ip:${ip}`, 100, 60);
171
+ }
172
+
173
+ // Combined rate limiting (both user and IP)
174
+ async function combinedRateLimit(userId: string, ip: string) {
175
+ const [userLimit, ipLimit] = await Promise.all([
176
+ simpleRateLimit(`user:${userId}`, 100, 60),
177
+ simpleRateLimit(`ip:${ip}`, 1000, 60),
178
+ ]);
179
+
180
+ return {
181
+ allowed: userLimit.allowed && ipLimit.allowed,
182
+ limits: { user: userLimit, ip: ipLimit },
183
+ };
184
+ }
185
+ ```
186
+
187
+ **Recommendation**: For production, use `@upstash/ratelimit` which provides battle-tested algorithms, analytics, and better accuracy.
@@ -0,0 +1,217 @@
1
+ # Session Management
2
+
3
+ ## Overview
4
+
5
+ Store user sessions in Redis with automatic serialization and TTL-based expiration. Sessions contain user state, authentication data, and preferences.
6
+
7
+ ## Good For
8
+
9
+ - User authentication sessions
10
+ - Shopping carts
11
+ - Temporary user state
12
+ - Multi-page form data
13
+ - "Remember me" tokens
14
+
15
+ ## Limitations
16
+
17
+ - Sessions expire after TTL (must be renewed)
18
+ - Large session objects consume memory
19
+ - Shared sessions require coordination across devices
20
+
21
+ ## Examples
22
+
23
+ ```typescript
24
+ import { Redis } from "@upstash/redis";
25
+
26
+ const redis = Redis.fromEnv();
27
+
28
+ // Create session with 1-hour expiration
29
+ async function createSession(userId: string, userData: any) {
30
+ const sessionId = crypto.randomUUID();
31
+
32
+ await redis.set(
33
+ `session:${sessionId}`,
34
+ {
35
+ userId,
36
+ ...userData,
37
+ createdAt: Date.now(),
38
+ },
39
+ { ex: 3600 } // 1 hour TTL
40
+ );
41
+
42
+ return sessionId;
43
+ }
44
+
45
+ // Get session
46
+ async function getSession(sessionId: string) {
47
+ const session = await redis.get<any>(`session:${sessionId}`);
48
+ return session;
49
+ }
50
+
51
+ // Update session and refresh TTL
52
+ async function updateSession(sessionId: string, updates: any) {
53
+ const current = await redis.get<any>(`session:${sessionId}`);
54
+
55
+ if (!current) {
56
+ throw new Error("Session not found");
57
+ }
58
+
59
+ await redis.set(
60
+ `session:${sessionId}`,
61
+ { ...current, ...updates, updatedAt: Date.now() },
62
+ { ex: 3600 } // Reset TTL
63
+ );
64
+ }
65
+
66
+ // Extend session (refresh TTL without updating data)
67
+ async function extendSession(sessionId: string) {
68
+ await redis.expire(`session:${sessionId}`, 3600);
69
+ }
70
+
71
+ // Delete session (logout)
72
+ async function deleteSession(sessionId: string) {
73
+ await redis.del(`session:${sessionId}`);
74
+ }
75
+
76
+ // User login flow
77
+ async function login(email: string, password: string) {
78
+ // Verify credentials (not shown)
79
+ const user = await verifyCredentials(email, password);
80
+
81
+ if (!user) {
82
+ throw new Error("Invalid credentials");
83
+ }
84
+
85
+ // Create session
86
+ const sessionId = await createSession(user.id, {
87
+ email: user.email,
88
+ name: user.name,
89
+ role: user.role,
90
+ });
91
+
92
+ return sessionId;
93
+ }
94
+
95
+ // User logout
96
+ async function logout(sessionId: string) {
97
+ await deleteSession(sessionId);
98
+ }
99
+
100
+ // Session with sliding expiration (extends on each access)
101
+ async function getSessionWithSliding(sessionId: string) {
102
+ const session = await redis.get<any>(`session:${sessionId}`);
103
+
104
+ if (session) {
105
+ // Extend session on access
106
+ await redis.expire(`session:${sessionId}`, 3600);
107
+ }
108
+
109
+ return session;
110
+ }
111
+
112
+ // Shopping cart session
113
+ async function addToCartSession(sessionId: string, item: any) {
114
+ const key = `cart:${sessionId}`;
115
+
116
+ const cart = (await redis.get<any[]>(key)) || [];
117
+ cart.push(item);
118
+
119
+ await redis.set(key, cart, { ex: 86400 }); // 24 hour cart
120
+
121
+ return cart;
122
+ }
123
+
124
+ // Multi-device sessions (track all user sessions)
125
+ async function createMultiDeviceSession(userId: string, deviceInfo: any) {
126
+ const sessionId = crypto.randomUUID();
127
+
128
+ // Store session
129
+ await redis.set(
130
+ `session:${sessionId}`,
131
+ { userId, ...deviceInfo, createdAt: Date.now() },
132
+ { ex: 3600 }
133
+ );
134
+
135
+ // Track in user's session list
136
+ await redis.sadd(`user:${userId}:sessions`, sessionId);
137
+
138
+ return sessionId;
139
+ }
140
+
141
+ // Logout from all devices
142
+ async function logoutAllDevices(userId: string) {
143
+ const sessions = await redis.smembers(`user:${userId}:sessions`);
144
+
145
+ // Delete all sessions
146
+ const pipeline = redis.pipeline();
147
+ sessions.forEach((sessionId) => {
148
+ pipeline.del(`session:${sessionId}`);
149
+ });
150
+ pipeline.del(`user:${userId}:sessions`);
151
+
152
+ await pipeline.exec();
153
+ }
154
+
155
+ // "Remember me" token (long-lived)
156
+ async function createRememberMeToken(userId: string) {
157
+ const token = crypto.randomUUID();
158
+
159
+ await redis.set(
160
+ `remember:${token}`,
161
+ { userId, createdAt: Date.now() },
162
+ { ex: 2592000 } // 30 days
163
+ );
164
+
165
+ return token;
166
+ }
167
+
168
+ async function loginWithRememberMe(token: string) {
169
+ const data = await redis.get<any>(`remember:${token}`);
170
+
171
+ if (!data) {
172
+ return null;
173
+ }
174
+
175
+ // Create new session
176
+ const sessionId = await createSession(data.userId, {});
177
+
178
+ return sessionId;
179
+ }
180
+
181
+ // Session with user activity tracking
182
+ async function trackActivity(sessionId: string, action: string) {
183
+ const session = await redis.get<any>(`session:${sessionId}`);
184
+
185
+ if (!session) return;
186
+
187
+ session.lastActivity = {
188
+ action,
189
+ timestamp: Date.now(),
190
+ };
191
+
192
+ await redis.set(`session:${sessionId}`, session, { ex: 3600 });
193
+ }
194
+
195
+ // Clean up expired sessions manually (if needed)
196
+ async function cleanupExpiredSessions(userId: string) {
197
+ const sessions = await redis.smembers(`user:${userId}:sessions`);
198
+
199
+ const pipeline = redis.pipeline();
200
+ sessions.forEach((sessionId) => {
201
+ pipeline.exists(`session:${sessionId}`);
202
+ });
203
+
204
+ const results = await pipeline.exec();
205
+
206
+ // Remove invalid sessions from set
207
+ const invalid = sessions.filter((_, i) => results[i] === 0);
208
+ if (invalid.length > 0) {
209
+ await redis.srem(`user:${userId}:sessions`, ...invalid);
210
+ }
211
+ }
212
+
213
+ // Helper placeholder
214
+ async function verifyCredentials(email: string, password: string) {
215
+ return { id: "123", email, name: "User", role: "user" };
216
+ }
217
+ ```
@@ -0,0 +1,76 @@
1
+ # Batching Operations
2
+
3
+ ## Overview
4
+
5
+ Batch multiple Redis operations into single commands to reduce network round trips. Use MGET/MSET for strings, HMGET/HMSET for hashes, pipelines for mixed operations.
6
+
7
+ ## Good For
8
+
9
+ - Fetching multiple keys at once
10
+ - Bulk data loading
11
+ - Reducing latency in high-latency networks
12
+ - Operations on related data
13
+
14
+ ## Limitations
15
+
16
+ - Batch operations are atomic per command, not across commands
17
+ - Some commands don't have batch equivalents
18
+
19
+ ## Examples
20
+
21
+ ```typescript
22
+ import { Redis } from "@upstash/redis";
23
+
24
+ const redis = Redis.fromEnv();
25
+
26
+ // MGET - batch get multiple keys
27
+ const [user1, user2, user3] = await redis.mget<any[]>("user:1", "user:2", "user:3");
28
+
29
+ // MSET - batch set multiple keys
30
+ await redis.mset({
31
+ "user:1": { name: "Alice", age: 30 },
32
+ "user:2": { name: "Bob", age: 25 },
33
+ "user:3": { name: "Charlie", age: 35 },
34
+ });
35
+
36
+ // Compare: individual operations (3 round trips)
37
+ const u1 = await redis.get("user:1");
38
+ const u2 = await redis.get("user:2");
39
+ const u3 = await redis.get("user:3");
40
+
41
+ // vs batch operation (1 round trip)
42
+ const users = await redis.mget("user:1", "user:2", "user:3");
43
+
44
+ // HMGET - batch get hash fields
45
+ const [name, email] = await redis.hmget("user:123", "name", "email");
46
+
47
+ // HMSET - batch set hash fields
48
+ await redis.hset("user:123", {
49
+ name: "Alice",
50
+ email: "alice@example.com",
51
+ age: 30,
52
+ });
53
+
54
+ // Batch with mixed operations - use pipeline
55
+ const pipeline = redis.pipeline();
56
+ userIds.forEach((id) => {
57
+ pipeline.get(`user:${id}`);
58
+ pipeline.hgetall(`user:${id}:profile`);
59
+ pipeline.zrank("leaderboard", id);
60
+ });
61
+ const results = await pipeline.exec();
62
+
63
+ // Batch delete
64
+ await redis.del("key1", "key2", "key3", "key4");
65
+
66
+ // Batch SADD
67
+ await redis.sadd("tags", "redis", "nodejs", "typescript", "upstash");
68
+
69
+ // Batch with Promise.all (for independent operations)
70
+ const [userCount, postCount, commentCount] = await Promise.all([
71
+ redis.get("count:users"),
72
+ redis.get("count:posts"),
73
+ redis.get("count:comments"),
74
+ ]);
75
+ // Note: With auto-pipelining enabled, these batch automatically
76
+ ```
@@ -0,0 +1,134 @@
1
+ # Data Serialization and Deserialization
2
+
3
+ ## Overview
4
+
5
+ Automatic serialization preserves JavaScript types across Redis operations. Numbers stay numbers, objects stay objects, arrays stay arrays.
6
+
7
+ ## Good For
8
+
9
+ - Storing any JavaScript value without JSON.stringify/parse
10
+ - Type preservation across GET/SET
11
+ - Cleaner code (no manual serialization)
12
+ - Storing numbers, booleans, objects, arrays, null
13
+
14
+ ## Limitations
15
+
16
+ - undefined, functions, symbols cannot be serialized
17
+ - Date objects serialize as ISO strings
18
+ - Class instances lose their prototype
19
+ - Map and Set serialize to `{}` (their contents are lost) — convert to a plain object/array first
20
+ - Binary data requires special handling
21
+
22
+ ## Examples
23
+
24
+ ### Basic Type Preservation
25
+
26
+ ```typescript
27
+ import { Redis } from "@upstash/redis";
28
+
29
+ const redis = Redis.fromEnv();
30
+
31
+ // Numbers preserved
32
+ await redis.set("age", 42);
33
+ const age = await redis.get("age");
34
+ console.log(typeof age); // "number"
35
+ console.log(age === 42); // true
36
+
37
+ // Compare with other SDKs
38
+ // ioredis: returns "42" (string)
39
+ // @upstash/redis: returns 42 (number)
40
+
41
+ // Booleans preserved
42
+ await redis.set("active", true);
43
+ const active = await redis.get("active");
44
+ console.log(typeof active); // "boolean"
45
+
46
+ // Objects preserved
47
+ await redis.set("user", { name: "Alice", age: 30 });
48
+ const user = await redis.get("user");
49
+ console.log(user.name); // "Alice"
50
+ console.log(user.age); // 30 (number, not string)
51
+
52
+ // Arrays preserved
53
+ await redis.set("scores", [100, 200, 300]);
54
+ const scores = await redis.get<number[]>("scores");
55
+ console.log(scores[0]); // 100 (number)
56
+
57
+ // Nested structures preserved
58
+ await redis.set("data", {
59
+ user: { name: "Alice", age: 30 },
60
+ scores: [100, 200, 300],
61
+ active: true,
62
+ count: 42,
63
+ });
64
+
65
+ const data = await redis.get<any>("data");
66
+ console.log(typeof age); // "number"
67
+ console.log(Array.isArray(data.scores)); // true
68
+ ```
69
+
70
+ ### Complex Types
71
+
72
+ ```typescript
73
+ import { Redis } from "@upstash/redis";
74
+
75
+ const redis = Redis.fromEnv();
76
+
77
+ // Date objects become ISO strings
78
+ await redis.set("created", new Date());
79
+ const created = await redis.get<string>("created");
80
+ console.log(typeof created); // "string"
81
+ console.log(created); // "2024-01-01T00:00:00.000Z"
82
+
83
+ // Convert back to Date
84
+ const createdDate = new Date(created);
85
+
86
+ // Class instances lose prototype
87
+ class User {
88
+ constructor(public name: string) {}
89
+ greet() {
90
+ return `Hello, ${this.name}`;
91
+ }
92
+ }
93
+
94
+ const alice = new User("Alice");
95
+ await redis.set("instance", alice);
96
+
97
+ const retrieved = await redis.get<any>("instance");
98
+ console.log(retrieved.name); // "Alice"
99
+ console.log(retrieved.greet); // undefined (method lost)
100
+
101
+ // Solution: serialize/deserialize manually
102
+ class SerializableUser {
103
+ constructor(public name: string) {}
104
+
105
+ static toRedis(user: SerializableUser) {
106
+ return { name: user.name };
107
+ }
108
+
109
+ static fromRedis(data: any) {
110
+ return new SerializableUser(data.name);
111
+ }
112
+ }
113
+
114
+ await redis.set("ser_user", SerializableUser.toRedis(alice));
115
+ const serRetrieved = SerializableUser.fromRedis(await redis.get("ser_user"));
116
+ ```
117
+
118
+ ### Disabling Auto-Serialization
119
+
120
+ ```typescript
121
+ import { Redis } from "@upstash/redis";
122
+
123
+ // Disable auto-serialization if needed
124
+ const redis = new Redis({
125
+ url: process.env.UPSTASH_REDIS_REST_URL!,
126
+ token: process.env.UPSTASH_REDIS_REST_TOKEN!,
127
+ automaticDeserialization: false,
128
+ });
129
+
130
+ await redis.set("key", JSON.stringify({ value: 42 }));
131
+ const raw = await redis.get("key");
132
+ console.log(typeof raw); // "string"
133
+ const parsed = JSON.parse(raw as string);
134
+ ```