@hivehub/rulebook 5.1.3 → 5.2.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.
- package/.claude/commands/continue.md +33 -33
- package/.claude/commands/ralph-config.md +112 -112
- package/.claude/commands/ralph-history.md +110 -110
- package/.claude/commands/ralph-init.md +72 -72
- package/.claude/commands/ralph-pause-resume.md +105 -105
- package/.claude/commands/ralph-run.md +101 -101
- package/.claude/commands/ralph-status.md +76 -76
- package/.claude/commands/rulebook-decision-create.md +55 -55
- package/.claude/commands/rulebook-decision-list.md +15 -15
- package/.claude/commands/rulebook-knowledge-add.md +41 -41
- package/.claude/commands/rulebook-knowledge-list.md +15 -15
- package/.claude/commands/rulebook-learn-capture.md +48 -48
- package/.claude/commands/rulebook-learn-list.md +13 -13
- package/.claude/commands/rulebook-memory-save.md +48 -48
- package/.claude/commands/rulebook-memory-search.md +47 -47
- package/.claude/commands/rulebook-task-apply.md +85 -67
- package/.claude/commands/rulebook-task-archive.md +103 -94
- package/.claude/commands/rulebook-task-create.md +93 -93
- package/.claude/commands/rulebook-task-list.md +42 -42
- package/.claude/commands/rulebook-task-show.md +52 -52
- package/.claude/commands/rulebook-task-validate.md +53 -53
- package/.claude-plugin/marketplace.json +28 -28
- package/.claude-plugin/plugin.json +8 -8
- package/README.md +25 -43
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +11 -0
- package/dist/cli/commands.js.map +1 -1
- package/dist/core/agent-template-engine.js +28 -28
- package/dist/core/generator.js +28 -28
- package/dist/core/task-manager.d.ts +23 -0
- package/dist/core/task-manager.d.ts.map +1 -1
- package/dist/core/task-manager.js +161 -27
- package/dist/core/task-manager.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/mcp/rulebook-server.js +3 -3
- package/dist/mcp/rulebook-server.js.map +1 -1
- package/dist/memory/memory-store.js +91 -91
- package/package.json +21 -22
- package/templates/agents/accessibility-reviewer.md +43 -43
- package/templates/agents/api-designer.md +42 -42
- package/templates/agents/architect.md +51 -51
- package/templates/agents/build-engineer.md +36 -36
- package/templates/agents/code-reviewer.md +47 -47
- package/templates/agents/compiler/codegen-debugger.md +34 -34
- package/templates/agents/compiler/stdlib-engineer.md +28 -28
- package/templates/agents/compiler/test-coverage-guardian.md +31 -31
- package/templates/agents/context-intelligence.md +52 -52
- package/templates/agents/database-architect.md +41 -41
- package/templates/agents/devops-engineer.md +42 -42
- package/templates/agents/docs-writer.md +38 -38
- package/templates/agents/game-engine/cpp-core-expert.md +35 -35
- package/templates/agents/game-engine/render-engineer.md +22 -22
- package/templates/agents/game-engine/shader-engineer.md +38 -38
- package/templates/agents/game-engine/systems-integration.md +43 -43
- package/templates/agents/generic/code-reviewer.md +41 -41
- package/templates/agents/generic/docs-writer.md +25 -25
- package/templates/agents/generic/project-manager.md +36 -36
- package/templates/agents/generic/researcher.md +34 -34
- package/templates/agents/generic/test-engineer.md +41 -41
- package/templates/agents/i18n-engineer.md +42 -42
- package/templates/agents/implementer.md +42 -42
- package/templates/agents/migration-engineer.md +42 -42
- package/templates/agents/mobile/platform-specialist.md +22 -22
- package/templates/agents/mobile/ui-engineer.md +22 -22
- package/templates/agents/performance-engineer.md +49 -49
- package/templates/agents/refactoring-agent.md +41 -41
- package/templates/agents/researcher.md +38 -38
- package/templates/agents/security-reviewer.md +40 -40
- package/templates/agents/team-lead.md +37 -37
- package/templates/agents/tester.md +48 -48
- package/templates/agents/ux-reviewer.md +43 -43
- package/templates/agents/web-app/api-designer.md +22 -22
- package/templates/agents/web-app/backend-engineer.md +30 -30
- package/templates/agents/web-app/database-engineer.md +22 -22
- package/templates/agents/web-app/frontend-engineer.md +29 -29
- package/templates/agents/web-app/security-reviewer.md +32 -32
- package/templates/ci/rulebook-review.yml +26 -26
- package/templates/cli/AIDER.md +49 -49
- package/templates/cli/AMAZON_Q.md +25 -25
- package/templates/cli/AUGGIE.md +32 -32
- package/templates/cli/CLAUDE.md +117 -117
- package/templates/cli/CLINE.md +99 -99
- package/templates/cli/CODEBUDDY.md +20 -20
- package/templates/cli/CODEIUM.md +20 -20
- package/templates/cli/CODEX.md +21 -21
- package/templates/cli/CONTINUE.md +34 -34
- package/templates/cli/CURSOR_CLI.md +62 -62
- package/templates/cli/FACTORY.md +18 -18
- package/templates/cli/GEMINI.md +35 -35
- package/templates/cli/KILOCODE.md +18 -18
- package/templates/cli/OPENCODE.md +18 -18
- package/templates/cli/_GENERIC_TEMPLATE.md +29 -29
- package/templates/commands/rulebook-decision-create.md +55 -55
- package/templates/commands/rulebook-decision-list.md +15 -15
- package/templates/commands/rulebook-knowledge-add.md +41 -41
- package/templates/commands/rulebook-knowledge-list.md +15 -15
- package/templates/commands/rulebook-learn-capture.md +48 -48
- package/templates/commands/rulebook-learn-list.md +13 -13
- package/templates/commands/rulebook-memory-save.md +48 -48
- package/templates/commands/rulebook-memory-search.md +47 -47
- package/templates/commands/rulebook-task-apply.md +67 -67
- package/templates/commands/rulebook-task-archive.md +94 -94
- package/templates/commands/rulebook-task-create.md +93 -93
- package/templates/commands/rulebook-task-list.md +42 -42
- package/templates/commands/rulebook-task-show.md +52 -52
- package/templates/commands/rulebook-task-validate.md +53 -53
- package/templates/core/AGENTS_LEAN.md +25 -25
- package/templates/core/AGENTS_OVERRIDE.md +16 -16
- package/templates/core/AGENT_AUTOMATION.md +296 -296
- package/templates/core/DAG.md +304 -304
- package/templates/core/DECISIONS.md +38 -38
- package/templates/core/DOCUMENTATION_RULES.md +36 -36
- package/templates/core/KNOWLEDGE.md +49 -49
- package/templates/core/MULTI_AGENT.md +74 -74
- package/templates/core/PLANS.md +28 -28
- package/templates/core/QUALITY_ENFORCEMENT.md +68 -68
- package/templates/core/RALPH.md +471 -471
- package/templates/core/RULEBOOK.md +1947 -1947
- package/templates/core/TIER1_PROHIBITIONS.md +154 -154
- package/templates/core/TOKEN_OPTIMIZATION.md +49 -49
- package/templates/frameworks/ANGULAR.md +36 -36
- package/templates/frameworks/DJANGO.md +83 -83
- package/templates/frameworks/ELECTRON.md +147 -147
- package/templates/frameworks/FLASK.md +38 -38
- package/templates/frameworks/FLUTTER.md +55 -55
- package/templates/frameworks/JQUERY.md +32 -32
- package/templates/frameworks/LARAVEL.md +38 -38
- package/templates/frameworks/NESTJS.md +43 -43
- package/templates/frameworks/NEXTJS.md +127 -127
- package/templates/frameworks/NUXT.md +40 -40
- package/templates/frameworks/RAILS.md +66 -66
- package/templates/frameworks/REACT.md +38 -38
- package/templates/frameworks/REACT_NATIVE.md +47 -47
- package/templates/frameworks/SPRING.md +39 -39
- package/templates/frameworks/SYMFONY.md +36 -36
- package/templates/frameworks/VUE.md +36 -36
- package/templates/frameworks/ZEND.md +35 -35
- package/templates/git/CI_CD_PATTERNS.md +661 -661
- package/templates/git/GITHUB_ACTIONS.md +728 -728
- package/templates/git/GITLAB_CI.md +730 -730
- package/templates/git/GIT_WORKFLOW.md +1192 -1192
- package/templates/git/SECRETS_MANAGEMENT.md +585 -585
- package/templates/hooks/COMMIT_MSG.md +530 -530
- package/templates/hooks/POST_CHECKOUT.md +546 -546
- package/templates/hooks/PREPARE_COMMIT_MSG.md +619 -619
- package/templates/hooks/PRE_COMMIT.md +414 -414
- package/templates/hooks/PRE_PUSH.md +601 -601
- package/templates/ides/CONTINUE_RULES.md +16 -16
- package/templates/ides/COPILOT.md +37 -37
- package/templates/ides/COPILOT_INSTRUCTIONS.md +23 -23
- package/templates/ides/CURSOR.md +43 -43
- package/templates/ides/GEMINI_RULES.md +17 -17
- package/templates/ides/JETBRAINS_AI.md +35 -35
- package/templates/ides/REPLIT.md +36 -36
- package/templates/ides/TABNINE.md +29 -29
- package/templates/ides/VSCODE.md +40 -40
- package/templates/ides/WINDSURF.md +36 -36
- package/templates/ides/WINDSURF_RULES.md +14 -14
- package/templates/ides/ZED.md +32 -32
- package/templates/ides/cursor-mdc/go.mdc +24 -24
- package/templates/ides/cursor-mdc/python.mdc +24 -24
- package/templates/ides/cursor-mdc/quality.mdc +25 -25
- package/templates/ides/cursor-mdc/ralph.mdc +39 -39
- package/templates/ides/cursor-mdc/rulebook.mdc +38 -38
- package/templates/ides/cursor-mdc/rust.mdc +24 -24
- package/templates/ides/cursor-mdc/typescript.mdc +25 -25
- package/templates/languages/C.md +333 -333
- package/templates/languages/CPP.md +743 -743
- package/templates/languages/CSHARP.md +417 -417
- package/templates/languages/ELIXIR.md +454 -454
- package/templates/languages/ERLANG.md +361 -361
- package/templates/languages/GO.md +645 -645
- package/templates/languages/HASKELL.md +177 -177
- package/templates/languages/JAVA.md +607 -607
- package/templates/languages/JAVASCRIPT.md +631 -631
- package/templates/languages/JULIA.md +97 -97
- package/templates/languages/KOTLIN.md +511 -511
- package/templates/languages/LISP.md +100 -100
- package/templates/languages/LUA.md +74 -74
- package/templates/languages/OBJECTIVEC.md +90 -90
- package/templates/languages/PHP.md +416 -416
- package/templates/languages/PYTHON.md +682 -682
- package/templates/languages/RUBY.md +421 -421
- package/templates/languages/RUST.md +477 -477
- package/templates/languages/SAS.md +73 -73
- package/templates/languages/SCALA.md +348 -348
- package/templates/languages/SOLIDITY.md +580 -580
- package/templates/languages/SQL.md +137 -137
- package/templates/languages/SWIFT.md +466 -466
- package/templates/languages/TYPESCRIPT.md +591 -591
- package/templates/languages/ZIG.md +265 -265
- package/templates/modules/ATLASSIAN.md +255 -255
- package/templates/modules/CONTEXT7.md +54 -54
- package/templates/modules/FIGMA.md +267 -267
- package/templates/modules/GITHUB_MCP.md +64 -64
- package/templates/modules/GRAFANA.md +328 -328
- package/templates/modules/MEMORY.md +126 -126
- package/templates/modules/NOTION.md +247 -247
- package/templates/modules/PLAYWRIGHT.md +90 -90
- package/templates/modules/RULEBOOK_MCP.md +156 -156
- package/templates/modules/SERENA.md +337 -337
- package/templates/modules/SUPABASE.md +223 -223
- package/templates/modules/SYNAP.md +69 -69
- package/templates/modules/VECTORIZER.md +63 -63
- package/templates/modules/sequential-thinking.md +42 -42
- package/templates/ralph/ralph-history.bat +4 -4
- package/templates/ralph/ralph-history.sh +5 -5
- package/templates/ralph/ralph-init.bat +5 -5
- package/templates/ralph/ralph-init.sh +5 -5
- package/templates/ralph/ralph-pause.bat +5 -5
- package/templates/ralph/ralph-pause.sh +5 -5
- package/templates/ralph/ralph-run.bat +5 -5
- package/templates/ralph/ralph-run.sh +5 -5
- package/templates/ralph/ralph-status.bat +4 -4
- package/templates/ralph/ralph-status.sh +5 -5
- package/templates/rules/follow-task-sequence.md +36 -36
- package/templates/rules/git-safety.md +29 -29
- package/templates/rules/incremental-tests.md +29 -29
- package/templates/rules/knowledge-base-usage.md +41 -0
- package/templates/rules/no-deferred.md +31 -31
- package/templates/rules/no-shortcuts.md +30 -30
- package/templates/rules/research-first.md +30 -30
- package/templates/rules/sequential-editing.md +21 -21
- package/templates/rules/session-workflow.md +24 -24
- package/templates/rules/task-decomposition.md +32 -32
- package/templates/services/AZURE_BLOB.md +184 -184
- package/templates/services/CASSANDRA.md +239 -239
- package/templates/services/DATADOG.md +26 -26
- package/templates/services/DOCKER.md +124 -124
- package/templates/services/DOCKER_COMPOSE.md +168 -168
- package/templates/services/DYNAMODB.md +308 -308
- package/templates/services/ELASTICSEARCH.md +347 -347
- package/templates/services/GCS.md +178 -178
- package/templates/services/HELM.md +194 -194
- package/templates/services/INFLUXDB.md +265 -265
- package/templates/services/KAFKA.md +341 -341
- package/templates/services/KUBERNETES.md +208 -208
- package/templates/services/MARIADB.md +183 -183
- package/templates/services/MEMCACHED.md +242 -242
- package/templates/services/MINIO.md +201 -201
- package/templates/services/MONGODB.md +268 -268
- package/templates/services/MYSQL.md +358 -358
- package/templates/services/NEO4J.md +247 -247
- package/templates/services/OPENTELEMETRY.md +25 -25
- package/templates/services/ORACLE.md +290 -290
- package/templates/services/PINO.md +24 -24
- package/templates/services/POSTGRESQL.md +326 -326
- package/templates/services/PROMETHEUS.md +33 -33
- package/templates/services/RABBITMQ.md +286 -286
- package/templates/services/REDIS.md +292 -292
- package/templates/services/S3.md +298 -298
- package/templates/services/SENTRY.md +23 -23
- package/templates/services/SQLITE.md +294 -294
- package/templates/services/SQLSERVER.md +294 -294
- package/templates/services/WINSTON.md +30 -30
- package/templates/skills/cli/aider/SKILL.md +59 -59
- package/templates/skills/cli/amazon-q/SKILL.md +35 -35
- package/templates/skills/cli/auggie/SKILL.md +42 -42
- package/templates/skills/cli/claude/SKILL.md +42 -42
- package/templates/skills/cli/cline/SKILL.md +42 -42
- package/templates/skills/cli/codebuddy/SKILL.md +30 -30
- package/templates/skills/cli/codeium/SKILL.md +30 -30
- package/templates/skills/cli/codex/SKILL.md +31 -31
- package/templates/skills/cli/continue/SKILL.md +44 -44
- package/templates/skills/cli/cursor-cli/SKILL.md +38 -38
- package/templates/skills/cli/factory/SKILL.md +28 -28
- package/templates/skills/cli/gemini/SKILL.md +45 -45
- package/templates/skills/cli/kilocode/SKILL.md +28 -28
- package/templates/skills/cli/opencode/SKILL.md +28 -28
- package/templates/skills/core/agent-automation/SKILL.md +194 -194
- package/templates/skills/core/dag/SKILL.md +314 -314
- package/templates/skills/core/documentation-rules/SKILL.md +46 -46
- package/templates/skills/core/quality-enforcement/SKILL.md +78 -78
- package/templates/skills/core/rulebook/SKILL.md +176 -176
- package/templates/skills/dev/accessibility/SKILL.md +17 -17
- package/templates/skills/dev/api-design/SKILL.md +15 -15
- package/templates/skills/dev/architect/SKILL.md +17 -17
- package/templates/skills/dev/build-fix/SKILL.md +17 -17
- package/templates/skills/dev/db-design/SKILL.md +15 -15
- package/templates/skills/dev/debug/SKILL.md +16 -16
- package/templates/skills/dev/deploy/SKILL.md +17 -17
- package/templates/skills/dev/docs/SKILL.md +17 -17
- package/templates/skills/dev/migrate/SKILL.md +15 -15
- package/templates/skills/dev/perf/SKILL.md +17 -17
- package/templates/skills/dev/refactor/SKILL.md +17 -17
- package/templates/skills/dev/research/SKILL.md +14 -14
- package/templates/skills/dev/review/SKILL.md +18 -18
- package/templates/skills/dev/security-audit/SKILL.md +17 -17
- package/templates/skills/frameworks/angular/SKILL.md +46 -46
- package/templates/skills/frameworks/django/SKILL.md +93 -93
- package/templates/skills/frameworks/electron/SKILL.md +157 -157
- package/templates/skills/frameworks/flask/SKILL.md +48 -48
- package/templates/skills/frameworks/flutter/SKILL.md +65 -65
- package/templates/skills/frameworks/jquery/SKILL.md +42 -42
- package/templates/skills/frameworks/laravel/SKILL.md +48 -48
- package/templates/skills/frameworks/nestjs/SKILL.md +53 -53
- package/templates/skills/frameworks/nextjs/SKILL.md +137 -137
- package/templates/skills/frameworks/nuxt/SKILL.md +50 -50
- package/templates/skills/frameworks/rails/SKILL.md +76 -76
- package/templates/skills/frameworks/react/SKILL.md +48 -48
- package/templates/skills/frameworks/react-native/SKILL.md +57 -57
- package/templates/skills/frameworks/spring/SKILL.md +49 -49
- package/templates/skills/frameworks/symfony/SKILL.md +46 -46
- package/templates/skills/frameworks/vue/SKILL.md +46 -46
- package/templates/skills/frameworks/zend/SKILL.md +45 -45
- package/templates/skills/ides/copilot/SKILL.md +47 -47
- package/templates/skills/ides/cursor/SKILL.md +53 -53
- package/templates/skills/ides/jetbrains-ai/SKILL.md +45 -45
- package/templates/skills/ides/replit/SKILL.md +46 -46
- package/templates/skills/ides/tabnine/SKILL.md +39 -39
- package/templates/skills/ides/vscode/SKILL.md +50 -50
- package/templates/skills/ides/windsurf/SKILL.md +46 -46
- package/templates/skills/ides/zed/SKILL.md +42 -42
- package/templates/skills/languages/c/SKILL.md +343 -343
- package/templates/skills/languages/cpp/SKILL.md +753 -753
- package/templates/skills/languages/csharp/SKILL.md +427 -427
- package/templates/skills/languages/elixir/SKILL.md +464 -464
- package/templates/skills/languages/erlang/SKILL.md +371 -371
- package/templates/skills/languages/go/SKILL.md +655 -655
- package/templates/skills/languages/haskell/SKILL.md +187 -187
- package/templates/skills/languages/java/SKILL.md +617 -617
- package/templates/skills/languages/javascript/SKILL.md +641 -641
- package/templates/skills/languages/julia/SKILL.md +107 -107
- package/templates/skills/languages/kotlin/SKILL.md +521 -521
- package/templates/skills/languages/lisp/SKILL.md +110 -110
- package/templates/skills/languages/lua/SKILL.md +84 -84
- package/templates/skills/languages/objectivec/SKILL.md +100 -100
- package/templates/skills/languages/php/SKILL.md +426 -426
- package/templates/skills/languages/python/SKILL.md +692 -692
- package/templates/skills/languages/ruby/SKILL.md +431 -431
- package/templates/skills/languages/rust/SKILL.md +487 -487
- package/templates/skills/languages/sas/SKILL.md +83 -83
- package/templates/skills/languages/scala/SKILL.md +358 -358
- package/templates/skills/languages/solidity/SKILL.md +590 -590
- package/templates/skills/languages/sql/SKILL.md +147 -147
- package/templates/skills/languages/swift/SKILL.md +476 -476
- package/templates/skills/languages/typescript/SKILL.md +302 -302
- package/templates/skills/languages/zig/SKILL.md +275 -275
- package/templates/skills/modules/atlassian/SKILL.md +265 -265
- package/templates/skills/modules/context7/SKILL.md +64 -64
- package/templates/skills/modules/figma/SKILL.md +277 -277
- package/templates/skills/modules/github-mcp/SKILL.md +74 -74
- package/templates/skills/modules/grafana/SKILL.md +338 -338
- package/templates/skills/modules/memory/SKILL.md +73 -73
- package/templates/skills/modules/notion/SKILL.md +257 -257
- package/templates/skills/modules/playwright/SKILL.md +100 -100
- package/templates/skills/modules/rulebook-mcp/SKILL.md +166 -166
- package/templates/skills/modules/serena/SKILL.md +347 -347
- package/templates/skills/modules/supabase/SKILL.md +233 -233
- package/templates/skills/modules/synap/SKILL.md +79 -79
- package/templates/skills/modules/vectorizer/SKILL.md +73 -73
- package/templates/skills/services/azure-blob/SKILL.md +194 -194
- package/templates/skills/services/cassandra/SKILL.md +249 -249
- package/templates/skills/services/dynamodb/SKILL.md +318 -318
- package/templates/skills/services/elasticsearch/SKILL.md +357 -357
- package/templates/skills/services/gcs/SKILL.md +188 -188
- package/templates/skills/services/influxdb/SKILL.md +275 -275
- package/templates/skills/services/kafka/SKILL.md +351 -351
- package/templates/skills/services/mariadb/SKILL.md +193 -193
- package/templates/skills/services/memcached/SKILL.md +252 -252
- package/templates/skills/services/minio/SKILL.md +211 -211
- package/templates/skills/services/mongodb/SKILL.md +278 -278
- package/templates/skills/services/mysql/SKILL.md +368 -368
- package/templates/skills/services/neo4j/SKILL.md +257 -257
- package/templates/skills/services/oracle/SKILL.md +300 -300
- package/templates/skills/services/postgresql/SKILL.md +336 -336
- package/templates/skills/services/rabbitmq/SKILL.md +296 -296
- package/templates/skills/services/redis/SKILL.md +302 -302
- package/templates/skills/services/s3/SKILL.md +308 -308
- package/templates/skills/services/sqlite/SKILL.md +304 -304
- package/templates/skills/services/sqlserver/SKILL.md +304 -304
- package/templates/skills/workflows/ralph/SKILL.md +309 -309
- package/templates/skills/workflows/ralph/install.sh +87 -87
- package/templates/skills/workflows/ralph/manifest.json +158 -158
|
@@ -1,292 +1,292 @@
|
|
|
1
|
-
<!-- REDIS:START -->
|
|
2
|
-
# Redis Cache Instructions
|
|
3
|
-
|
|
4
|
-
**CRITICAL**: Use Redis for high-performance caching, session storage, pub/sub messaging, and real-time features.
|
|
5
|
-
|
|
6
|
-
## Core Features
|
|
7
|
-
|
|
8
|
-
### Connection
|
|
9
|
-
```typescript
|
|
10
|
-
// Using redis (Node.js)
|
|
11
|
-
import { createClient } from 'redis'
|
|
12
|
-
|
|
13
|
-
const client = createClient({
|
|
14
|
-
url: process.env.REDIS_URL || 'redis://localhost:6379',
|
|
15
|
-
socket: {
|
|
16
|
-
reconnectStrategy: (retries) => {
|
|
17
|
-
if (retries > 10) {
|
|
18
|
-
return new Error('Too many reconnection attempts')
|
|
19
|
-
}
|
|
20
|
-
return Math.min(retries * 100, 3000)
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
await client.connect()
|
|
26
|
-
|
|
27
|
-
// Using ioredis
|
|
28
|
-
import Redis from 'ioredis'
|
|
29
|
-
|
|
30
|
-
const redis = new Redis({
|
|
31
|
-
host: process.env.REDIS_HOST || 'localhost',
|
|
32
|
-
port: parseInt(process.env.REDIS_PORT || '6379'),
|
|
33
|
-
password: process.env.REDIS_PASSWORD,
|
|
34
|
-
retryStrategy: (times) => Math.min(times * 50, 2000),
|
|
35
|
-
maxRetriesPerRequest: 3,
|
|
36
|
-
})
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### Basic Operations
|
|
40
|
-
```typescript
|
|
41
|
-
// String operations
|
|
42
|
-
await client.set('user:1', JSON.stringify({ name: 'John', email: 'john@example.com' }))
|
|
43
|
-
await client.set('user:1', 'value', { EX: 3600 }) // Expire in 1 hour
|
|
44
|
-
const user = await client.get('user:1')
|
|
45
|
-
await client.del('user:1')
|
|
46
|
-
|
|
47
|
-
// Multiple operations
|
|
48
|
-
await client.mSet({
|
|
49
|
-
'key1': 'value1',
|
|
50
|
-
'key2': 'value2',
|
|
51
|
-
})
|
|
52
|
-
const values = await client.mGet(['key1', 'key2'])
|
|
53
|
-
|
|
54
|
-
// Increment/Decrement
|
|
55
|
-
await client.incr('counter')
|
|
56
|
-
await client.incrBy('counter', 5)
|
|
57
|
-
await client.decr('counter')
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### Data Structures
|
|
61
|
-
```typescript
|
|
62
|
-
// Lists
|
|
63
|
-
await client.lPush('tasks', 'task1', 'task2')
|
|
64
|
-
await client.rPush('tasks', 'task3')
|
|
65
|
-
const task = await client.lPop('tasks')
|
|
66
|
-
const tasks = await client.lRange('tasks', 0, -1)
|
|
67
|
-
|
|
68
|
-
// Sets
|
|
69
|
-
await client.sAdd('tags', 'javascript', 'typescript', 'nodejs')
|
|
70
|
-
const tags = await client.sMembers('tags')
|
|
71
|
-
const exists = await client.sIsMember('tags', 'javascript')
|
|
72
|
-
await client.sRem('tags', 'javascript')
|
|
73
|
-
|
|
74
|
-
// Sorted Sets
|
|
75
|
-
await client.zAdd('leaderboard', {
|
|
76
|
-
score: 100,
|
|
77
|
-
value: 'player1',
|
|
78
|
-
})
|
|
79
|
-
const topPlayers = await client.zRange('leaderboard', 0, 9, { REV: true })
|
|
80
|
-
|
|
81
|
-
// Hashes
|
|
82
|
-
await client.hSet('user:1', {
|
|
83
|
-
name: 'John',
|
|
84
|
-
email: 'john@example.com',
|
|
85
|
-
age: '30',
|
|
86
|
-
})
|
|
87
|
-
const user = await client.hGetAll('user:1')
|
|
88
|
-
await client.hIncrBy('user:1', 'age', 1)
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Advanced Features
|
|
92
|
-
```typescript
|
|
93
|
-
// Pub/Sub
|
|
94
|
-
const publisher = client.duplicate()
|
|
95
|
-
await publisher.connect()
|
|
96
|
-
|
|
97
|
-
const subscriber = client.duplicate()
|
|
98
|
-
await subscriber.connect()
|
|
99
|
-
|
|
100
|
-
await subscriber.subscribe('notifications', (message) => {
|
|
101
|
-
console.log('Received:', message)
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
await publisher.publish('notifications', JSON.stringify({ type: 'alert', message: 'Hello' }))
|
|
105
|
-
|
|
106
|
-
// Streams
|
|
107
|
-
await client.xAdd('events', '*', {
|
|
108
|
-
type: 'user_login',
|
|
109
|
-
userId: '123',
|
|
110
|
-
timestamp: Date.now().toString(),
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
const events = await client.xRead({
|
|
114
|
-
key: 'events',
|
|
115
|
-
id: '0',
|
|
116
|
-
}, {
|
|
117
|
-
COUNT: 10,
|
|
118
|
-
BLOCK: 1000,
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
// Transactions
|
|
122
|
-
const multi = client.multi()
|
|
123
|
-
multi.set('key1', 'value1')
|
|
124
|
-
multi.set('key2', 'value2')
|
|
125
|
-
multi.incr('counter')
|
|
126
|
-
await multi.exec()
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
## Common Patterns
|
|
130
|
-
|
|
131
|
-
### Caching
|
|
132
|
-
```typescript
|
|
133
|
-
async function getCachedUser(userId: string) {
|
|
134
|
-
const cached = await client.get(`user:${userId}`)
|
|
135
|
-
if (cached) {
|
|
136
|
-
return JSON.parse(cached)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const user = await fetchUserFromDatabase(userId)
|
|
140
|
-
await client.set(`user:${userId}`, JSON.stringify(user), { EX: 3600 })
|
|
141
|
-
return user
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Cache with tags (for invalidation)
|
|
145
|
-
async function cacheWithTags(key: string, value: any, tags: string[], ttl: number) {
|
|
146
|
-
await client.set(key, JSON.stringify(value), { EX: ttl })
|
|
147
|
-
for (const tag of tags) {
|
|
148
|
-
await client.sAdd(`tag:${tag}`, key)
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
async function invalidateByTag(tag: string) {
|
|
153
|
-
const keys = await client.sMembers(`tag:${tag}`)
|
|
154
|
-
if (keys.length > 0) {
|
|
155
|
-
await client.del(...keys)
|
|
156
|
-
}
|
|
157
|
-
await client.del(`tag:${tag}`)
|
|
158
|
-
}
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### Rate Limiting
|
|
162
|
-
```typescript
|
|
163
|
-
async function checkRateLimit(userId: string, limit: number, window: number): Promise<boolean> {
|
|
164
|
-
const key = `ratelimit:${userId}`
|
|
165
|
-
const current = await client.incr(key)
|
|
166
|
-
|
|
167
|
-
if (current === 1) {
|
|
168
|
-
await client.expire(key, window)
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return current <= limit
|
|
172
|
-
}
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
### Session Storage
|
|
176
|
-
```typescript
|
|
177
|
-
async function setSession(sessionId: string, data: any, ttl: number) {
|
|
178
|
-
await client.set(`session:${sessionId}`, JSON.stringify(data), { EX: ttl })
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
async function getSession(sessionId: string) {
|
|
182
|
-
const data = await client.get(`session:${sessionId}`)
|
|
183
|
-
return data ? JSON.parse(data) : null
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
async function deleteSession(sessionId: string) {
|
|
187
|
-
await client.del(`session:${sessionId}`)
|
|
188
|
-
}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### Distributed Locks
|
|
192
|
-
```typescript
|
|
193
|
-
async function acquireLock(key: string, ttl: number): Promise<boolean> {
|
|
194
|
-
const result = await client.set(key, 'locked', {
|
|
195
|
-
EX: ttl,
|
|
196
|
-
NX: true, // Only set if not exists
|
|
197
|
-
})
|
|
198
|
-
return result === 'OK'
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
async function releaseLock(key: string) {
|
|
202
|
-
await client.del(key)
|
|
203
|
-
}
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
## Best Practices
|
|
207
|
-
|
|
208
|
-
✅ **DO:**
|
|
209
|
-
- Use connection pooling
|
|
210
|
-
- Set appropriate TTL for cached data
|
|
211
|
-
- Use pipelining for multiple operations
|
|
212
|
-
- Use transactions (MULTI/EXEC) for atomic operations
|
|
213
|
-
- Monitor memory usage
|
|
214
|
-
- Use appropriate data structures (hash for objects, set for unique values)
|
|
215
|
-
- Implement cache invalidation strategies
|
|
216
|
-
- Use Redis Cluster for high availability
|
|
217
|
-
- Enable persistence (RDB or AOF) for production
|
|
218
|
-
- Use Redis Sentinel for failover
|
|
219
|
-
|
|
220
|
-
❌ **DON'T:**
|
|
221
|
-
- Store large values (> 100KB, use compression or external storage)
|
|
222
|
-
- Use Redis as primary database (it's a cache)
|
|
223
|
-
- Skip error handling
|
|
224
|
-
- Ignore memory limits
|
|
225
|
-
- Hardcode connection strings
|
|
226
|
-
- Use KEYS command in production (use SCAN instead)
|
|
227
|
-
- Store sensitive data without encryption
|
|
228
|
-
- Skip connection retry logic
|
|
229
|
-
- Ignore eviction policies
|
|
230
|
-
- Use blocking operations without timeouts
|
|
231
|
-
|
|
232
|
-
## Configuration
|
|
233
|
-
|
|
234
|
-
### Environment Variables
|
|
235
|
-
```bash
|
|
236
|
-
REDIS_URL=redis://localhost:6379
|
|
237
|
-
REDIS_URL=redis://:password@host:6379
|
|
238
|
-
REDIS_URL=rediss://host:6380 # SSL
|
|
239
|
-
REDIS_HOST=localhost
|
|
240
|
-
REDIS_PORT=6379
|
|
241
|
-
REDIS_PASSWORD=securepassword
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### Docker Compose
|
|
245
|
-
```yaml
|
|
246
|
-
services:
|
|
247
|
-
redis:
|
|
248
|
-
image: redis:7-alpine
|
|
249
|
-
ports:
|
|
250
|
-
- "6379:6379"
|
|
251
|
-
command: redis-server --requirepass securepassword --appendonly yes
|
|
252
|
-
volumes:
|
|
253
|
-
- redis_data:/data
|
|
254
|
-
healthcheck:
|
|
255
|
-
test: ["CMD", "redis-cli", "ping"]
|
|
256
|
-
interval: 10s
|
|
257
|
-
timeout: 5s
|
|
258
|
-
retries: 5
|
|
259
|
-
|
|
260
|
-
volumes:
|
|
261
|
-
redis_data:
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
## Integration with Development
|
|
265
|
-
|
|
266
|
-
### Testing
|
|
267
|
-
```typescript
|
|
268
|
-
// Use test Redis instance
|
|
269
|
-
const testClient = createClient({
|
|
270
|
-
url: 'redis://localhost:6380', // Different port for tests
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
// Clean up after tests
|
|
274
|
-
afterEach(async () => {
|
|
275
|
-
await testClient.flushDb()
|
|
276
|
-
})
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
### Health Checks
|
|
280
|
-
```typescript
|
|
281
|
-
async function checkRedisHealth(): Promise<boolean> {
|
|
282
|
-
try {
|
|
283
|
-
await client.ping()
|
|
284
|
-
return true
|
|
285
|
-
} catch {
|
|
286
|
-
return false
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
<!-- REDIS:END -->
|
|
292
|
-
|
|
1
|
+
<!-- REDIS:START -->
|
|
2
|
+
# Redis Cache Instructions
|
|
3
|
+
|
|
4
|
+
**CRITICAL**: Use Redis for high-performance caching, session storage, pub/sub messaging, and real-time features.
|
|
5
|
+
|
|
6
|
+
## Core Features
|
|
7
|
+
|
|
8
|
+
### Connection
|
|
9
|
+
```typescript
|
|
10
|
+
// Using redis (Node.js)
|
|
11
|
+
import { createClient } from 'redis'
|
|
12
|
+
|
|
13
|
+
const client = createClient({
|
|
14
|
+
url: process.env.REDIS_URL || 'redis://localhost:6379',
|
|
15
|
+
socket: {
|
|
16
|
+
reconnectStrategy: (retries) => {
|
|
17
|
+
if (retries > 10) {
|
|
18
|
+
return new Error('Too many reconnection attempts')
|
|
19
|
+
}
|
|
20
|
+
return Math.min(retries * 100, 3000)
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
await client.connect()
|
|
26
|
+
|
|
27
|
+
// Using ioredis
|
|
28
|
+
import Redis from 'ioredis'
|
|
29
|
+
|
|
30
|
+
const redis = new Redis({
|
|
31
|
+
host: process.env.REDIS_HOST || 'localhost',
|
|
32
|
+
port: parseInt(process.env.REDIS_PORT || '6379'),
|
|
33
|
+
password: process.env.REDIS_PASSWORD,
|
|
34
|
+
retryStrategy: (times) => Math.min(times * 50, 2000),
|
|
35
|
+
maxRetriesPerRequest: 3,
|
|
36
|
+
})
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Basic Operations
|
|
40
|
+
```typescript
|
|
41
|
+
// String operations
|
|
42
|
+
await client.set('user:1', JSON.stringify({ name: 'John', email: 'john@example.com' }))
|
|
43
|
+
await client.set('user:1', 'value', { EX: 3600 }) // Expire in 1 hour
|
|
44
|
+
const user = await client.get('user:1')
|
|
45
|
+
await client.del('user:1')
|
|
46
|
+
|
|
47
|
+
// Multiple operations
|
|
48
|
+
await client.mSet({
|
|
49
|
+
'key1': 'value1',
|
|
50
|
+
'key2': 'value2',
|
|
51
|
+
})
|
|
52
|
+
const values = await client.mGet(['key1', 'key2'])
|
|
53
|
+
|
|
54
|
+
// Increment/Decrement
|
|
55
|
+
await client.incr('counter')
|
|
56
|
+
await client.incrBy('counter', 5)
|
|
57
|
+
await client.decr('counter')
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Data Structures
|
|
61
|
+
```typescript
|
|
62
|
+
// Lists
|
|
63
|
+
await client.lPush('tasks', 'task1', 'task2')
|
|
64
|
+
await client.rPush('tasks', 'task3')
|
|
65
|
+
const task = await client.lPop('tasks')
|
|
66
|
+
const tasks = await client.lRange('tasks', 0, -1)
|
|
67
|
+
|
|
68
|
+
// Sets
|
|
69
|
+
await client.sAdd('tags', 'javascript', 'typescript', 'nodejs')
|
|
70
|
+
const tags = await client.sMembers('tags')
|
|
71
|
+
const exists = await client.sIsMember('tags', 'javascript')
|
|
72
|
+
await client.sRem('tags', 'javascript')
|
|
73
|
+
|
|
74
|
+
// Sorted Sets
|
|
75
|
+
await client.zAdd('leaderboard', {
|
|
76
|
+
score: 100,
|
|
77
|
+
value: 'player1',
|
|
78
|
+
})
|
|
79
|
+
const topPlayers = await client.zRange('leaderboard', 0, 9, { REV: true })
|
|
80
|
+
|
|
81
|
+
// Hashes
|
|
82
|
+
await client.hSet('user:1', {
|
|
83
|
+
name: 'John',
|
|
84
|
+
email: 'john@example.com',
|
|
85
|
+
age: '30',
|
|
86
|
+
})
|
|
87
|
+
const user = await client.hGetAll('user:1')
|
|
88
|
+
await client.hIncrBy('user:1', 'age', 1)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Advanced Features
|
|
92
|
+
```typescript
|
|
93
|
+
// Pub/Sub
|
|
94
|
+
const publisher = client.duplicate()
|
|
95
|
+
await publisher.connect()
|
|
96
|
+
|
|
97
|
+
const subscriber = client.duplicate()
|
|
98
|
+
await subscriber.connect()
|
|
99
|
+
|
|
100
|
+
await subscriber.subscribe('notifications', (message) => {
|
|
101
|
+
console.log('Received:', message)
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
await publisher.publish('notifications', JSON.stringify({ type: 'alert', message: 'Hello' }))
|
|
105
|
+
|
|
106
|
+
// Streams
|
|
107
|
+
await client.xAdd('events', '*', {
|
|
108
|
+
type: 'user_login',
|
|
109
|
+
userId: '123',
|
|
110
|
+
timestamp: Date.now().toString(),
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
const events = await client.xRead({
|
|
114
|
+
key: 'events',
|
|
115
|
+
id: '0',
|
|
116
|
+
}, {
|
|
117
|
+
COUNT: 10,
|
|
118
|
+
BLOCK: 1000,
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
// Transactions
|
|
122
|
+
const multi = client.multi()
|
|
123
|
+
multi.set('key1', 'value1')
|
|
124
|
+
multi.set('key2', 'value2')
|
|
125
|
+
multi.incr('counter')
|
|
126
|
+
await multi.exec()
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Common Patterns
|
|
130
|
+
|
|
131
|
+
### Caching
|
|
132
|
+
```typescript
|
|
133
|
+
async function getCachedUser(userId: string) {
|
|
134
|
+
const cached = await client.get(`user:${userId}`)
|
|
135
|
+
if (cached) {
|
|
136
|
+
return JSON.parse(cached)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const user = await fetchUserFromDatabase(userId)
|
|
140
|
+
await client.set(`user:${userId}`, JSON.stringify(user), { EX: 3600 })
|
|
141
|
+
return user
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Cache with tags (for invalidation)
|
|
145
|
+
async function cacheWithTags(key: string, value: any, tags: string[], ttl: number) {
|
|
146
|
+
await client.set(key, JSON.stringify(value), { EX: ttl })
|
|
147
|
+
for (const tag of tags) {
|
|
148
|
+
await client.sAdd(`tag:${tag}`, key)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function invalidateByTag(tag: string) {
|
|
153
|
+
const keys = await client.sMembers(`tag:${tag}`)
|
|
154
|
+
if (keys.length > 0) {
|
|
155
|
+
await client.del(...keys)
|
|
156
|
+
}
|
|
157
|
+
await client.del(`tag:${tag}`)
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Rate Limiting
|
|
162
|
+
```typescript
|
|
163
|
+
async function checkRateLimit(userId: string, limit: number, window: number): Promise<boolean> {
|
|
164
|
+
const key = `ratelimit:${userId}`
|
|
165
|
+
const current = await client.incr(key)
|
|
166
|
+
|
|
167
|
+
if (current === 1) {
|
|
168
|
+
await client.expire(key, window)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return current <= limit
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Session Storage
|
|
176
|
+
```typescript
|
|
177
|
+
async function setSession(sessionId: string, data: any, ttl: number) {
|
|
178
|
+
await client.set(`session:${sessionId}`, JSON.stringify(data), { EX: ttl })
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async function getSession(sessionId: string) {
|
|
182
|
+
const data = await client.get(`session:${sessionId}`)
|
|
183
|
+
return data ? JSON.parse(data) : null
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async function deleteSession(sessionId: string) {
|
|
187
|
+
await client.del(`session:${sessionId}`)
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Distributed Locks
|
|
192
|
+
```typescript
|
|
193
|
+
async function acquireLock(key: string, ttl: number): Promise<boolean> {
|
|
194
|
+
const result = await client.set(key, 'locked', {
|
|
195
|
+
EX: ttl,
|
|
196
|
+
NX: true, // Only set if not exists
|
|
197
|
+
})
|
|
198
|
+
return result === 'OK'
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async function releaseLock(key: string) {
|
|
202
|
+
await client.del(key)
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Best Practices
|
|
207
|
+
|
|
208
|
+
✅ **DO:**
|
|
209
|
+
- Use connection pooling
|
|
210
|
+
- Set appropriate TTL for cached data
|
|
211
|
+
- Use pipelining for multiple operations
|
|
212
|
+
- Use transactions (MULTI/EXEC) for atomic operations
|
|
213
|
+
- Monitor memory usage
|
|
214
|
+
- Use appropriate data structures (hash for objects, set for unique values)
|
|
215
|
+
- Implement cache invalidation strategies
|
|
216
|
+
- Use Redis Cluster for high availability
|
|
217
|
+
- Enable persistence (RDB or AOF) for production
|
|
218
|
+
- Use Redis Sentinel for failover
|
|
219
|
+
|
|
220
|
+
❌ **DON'T:**
|
|
221
|
+
- Store large values (> 100KB, use compression or external storage)
|
|
222
|
+
- Use Redis as primary database (it's a cache)
|
|
223
|
+
- Skip error handling
|
|
224
|
+
- Ignore memory limits
|
|
225
|
+
- Hardcode connection strings
|
|
226
|
+
- Use KEYS command in production (use SCAN instead)
|
|
227
|
+
- Store sensitive data without encryption
|
|
228
|
+
- Skip connection retry logic
|
|
229
|
+
- Ignore eviction policies
|
|
230
|
+
- Use blocking operations without timeouts
|
|
231
|
+
|
|
232
|
+
## Configuration
|
|
233
|
+
|
|
234
|
+
### Environment Variables
|
|
235
|
+
```bash
|
|
236
|
+
REDIS_URL=redis://localhost:6379
|
|
237
|
+
REDIS_URL=redis://:password@host:6379
|
|
238
|
+
REDIS_URL=rediss://host:6380 # SSL
|
|
239
|
+
REDIS_HOST=localhost
|
|
240
|
+
REDIS_PORT=6379
|
|
241
|
+
REDIS_PASSWORD=securepassword
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Docker Compose
|
|
245
|
+
```yaml
|
|
246
|
+
services:
|
|
247
|
+
redis:
|
|
248
|
+
image: redis:7-alpine
|
|
249
|
+
ports:
|
|
250
|
+
- "6379:6379"
|
|
251
|
+
command: redis-server --requirepass securepassword --appendonly yes
|
|
252
|
+
volumes:
|
|
253
|
+
- redis_data:/data
|
|
254
|
+
healthcheck:
|
|
255
|
+
test: ["CMD", "redis-cli", "ping"]
|
|
256
|
+
interval: 10s
|
|
257
|
+
timeout: 5s
|
|
258
|
+
retries: 5
|
|
259
|
+
|
|
260
|
+
volumes:
|
|
261
|
+
redis_data:
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Integration with Development
|
|
265
|
+
|
|
266
|
+
### Testing
|
|
267
|
+
```typescript
|
|
268
|
+
// Use test Redis instance
|
|
269
|
+
const testClient = createClient({
|
|
270
|
+
url: 'redis://localhost:6380', // Different port for tests
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
// Clean up after tests
|
|
274
|
+
afterEach(async () => {
|
|
275
|
+
await testClient.flushDb()
|
|
276
|
+
})
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Health Checks
|
|
280
|
+
```typescript
|
|
281
|
+
async function checkRedisHealth(): Promise<boolean> {
|
|
282
|
+
try {
|
|
283
|
+
await client.ping()
|
|
284
|
+
return true
|
|
285
|
+
} catch {
|
|
286
|
+
return false
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
<!-- REDIS:END -->
|
|
292
|
+
|