@girardmedia/bootspring 3.3.2 → 3.4.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 (171) hide show
  1. package/assets/agents/accessibility-auditor.md +39 -0
  2. package/assets/agents/api-designer.md +40 -0
  3. package/assets/agents/auth-implementer.md +64 -0
  4. package/assets/agents/bug-hunter.md +42 -0
  5. package/assets/agents/bundle-analyzer.md +40 -0
  6. package/assets/agents/cache-optimizer.md +55 -0
  7. package/assets/agents/changelog-writer.md +55 -0
  8. package/assets/agents/ci-cd-builder.md +40 -0
  9. package/assets/agents/code-explainer.md +39 -0
  10. package/assets/agents/code-reviewer.md +39 -0
  11. package/assets/agents/cost-optimizer.md +57 -0
  12. package/assets/agents/cron-scheduler.md +51 -0
  13. package/assets/agents/data-seeder.md +56 -0
  14. package/assets/agents/database-architect.md +40 -0
  15. package/assets/agents/dependency-updater.md +40 -0
  16. package/assets/agents/deploy-checker.md +40 -0
  17. package/assets/agents/docker-optimizer.md +40 -0
  18. package/assets/agents/documentation-writer.md +40 -0
  19. package/assets/agents/email-builder.md +55 -0
  20. package/assets/agents/env-setup.md +40 -0
  21. package/assets/agents/error-handler.md +40 -0
  22. package/assets/agents/eslint-fixer.md +46 -0
  23. package/assets/agents/feature-flagger.md +69 -0
  24. package/assets/agents/git-detective.md +39 -0
  25. package/assets/agents/graphql-builder.md +60 -0
  26. package/assets/agents/incident-responder.md +59 -0
  27. package/assets/agents/log-analyzer.md +39 -0
  28. package/assets/agents/migration-planner.md +41 -0
  29. package/assets/agents/monorepo-navigator.md +39 -0
  30. package/assets/agents/nextjs-expert.md +57 -0
  31. package/assets/agents/notification-builder.md +56 -0
  32. package/assets/agents/onboarding-guide.md +39 -0
  33. package/assets/agents/performance-profiler.md +40 -0
  34. package/assets/agents/prisma-expert.md +57 -0
  35. package/assets/agents/rate-limiter.md +58 -0
  36. package/assets/agents/react-expert.md +58 -0
  37. package/assets/agents/refactorer.md +42 -0
  38. package/assets/agents/regex-builder.md +46 -0
  39. package/assets/agents/release-manager.md +40 -0
  40. package/assets/agents/s3-manager.md +58 -0
  41. package/assets/agents/schema-validator.md +40 -0
  42. package/assets/agents/search-builder.md +62 -0
  43. package/assets/agents/security-auditor.md +39 -0
  44. package/assets/agents/sitemap-generator.md +53 -0
  45. package/assets/agents/stripe-integrator.md +59 -0
  46. package/assets/agents/tailwind-expert.md +55 -0
  47. package/assets/agents/tech-debt-tracker.md +39 -0
  48. package/assets/agents/test-writer.md +42 -0
  49. package/assets/agents/type-fixer.md +45 -0
  50. package/assets/agents/webhook-builder.md +54 -0
  51. package/assets/rules/cpp.md +53 -0
  52. package/assets/rules/css.md +52 -0
  53. package/assets/rules/go.md +50 -0
  54. package/assets/rules/html.md +52 -0
  55. package/assets/rules/java.md +51 -0
  56. package/assets/rules/kotlin.md +50 -0
  57. package/assets/rules/php.md +51 -0
  58. package/assets/rules/python.md +51 -0
  59. package/assets/rules/ruby.md +51 -0
  60. package/assets/rules/rust.md +49 -0
  61. package/assets/rules/shell.md +52 -0
  62. package/assets/rules/sql.md +49 -0
  63. package/assets/rules/swift.md +50 -0
  64. package/assets/rules/typescript.md +52 -0
  65. package/assets/rules/yaml-json.md +51 -0
  66. package/assets/skills/accessibility.md +210 -0
  67. package/assets/skills/agent-patterns.md +387 -0
  68. package/assets/skills/ai-integration.md +263 -0
  69. package/assets/skills/animation-patterns.md +224 -0
  70. package/assets/skills/api-design.md +218 -0
  71. package/assets/skills/api-gateway.md +341 -0
  72. package/assets/skills/api-versioning.md +226 -0
  73. package/assets/skills/astro-patterns.md +233 -0
  74. package/assets/skills/auth-patterns.md +248 -0
  75. package/assets/skills/aws-patterns.md +171 -0
  76. package/assets/skills/background-jobs.md +162 -0
  77. package/assets/skills/browser-extensions.md +309 -0
  78. package/assets/skills/caching-patterns.md +253 -0
  79. package/assets/skills/ci-cd.md +251 -0
  80. package/assets/skills/cli-development.md +296 -0
  81. package/assets/skills/code-review.md +185 -0
  82. package/assets/skills/cron-patterns.md +327 -0
  83. package/assets/skills/data-fetching.md +231 -0
  84. package/assets/skills/database-migrations.md +346 -0
  85. package/assets/skills/database-patterns.md +219 -0
  86. package/assets/skills/debugging.md +281 -0
  87. package/assets/skills/design-system.md +289 -0
  88. package/assets/skills/django-patterns.md +182 -0
  89. package/assets/skills/docker-patterns.md +235 -0
  90. package/assets/skills/e2e-testing.md +287 -0
  91. package/assets/skills/edge-computing.md +268 -0
  92. package/assets/skills/electron-patterns.md +266 -0
  93. package/assets/skills/email-templates.md +206 -0
  94. package/assets/skills/error-handling.md +265 -0
  95. package/assets/skills/event-driven.md +232 -0
  96. package/assets/skills/express-patterns.md +239 -0
  97. package/assets/skills/fastapi-patterns.md +198 -0
  98. package/assets/skills/feature-flags.md +212 -0
  99. package/assets/skills/figma-to-code.md +298 -0
  100. package/assets/skills/file-upload.md +228 -0
  101. package/assets/skills/forms-patterns.md +264 -0
  102. package/assets/skills/gcp-patterns.md +189 -0
  103. package/assets/skills/git-workflow.md +187 -0
  104. package/assets/skills/golang-patterns.md +185 -0
  105. package/assets/skills/graphql-patterns.md +244 -0
  106. package/assets/skills/i18n-patterns.md +172 -0
  107. package/assets/skills/image-processing.md +350 -0
  108. package/assets/skills/java-springboot.md +226 -0
  109. package/assets/skills/kotlin-patterns.md +207 -0
  110. package/assets/skills/kubernetes-patterns.md +326 -0
  111. package/assets/skills/laravel-patterns.md +261 -0
  112. package/assets/skills/llm-fine-tuning.md +335 -0
  113. package/assets/skills/load-testing.md +303 -0
  114. package/assets/skills/logging-observability.md +228 -0
  115. package/assets/skills/markdown-processing.md +318 -0
  116. package/assets/skills/mcp-server-patterns.md +292 -0
  117. package/assets/skills/microservices.md +272 -0
  118. package/assets/skills/migration-patterns.md +239 -0
  119. package/assets/skills/mongodb-patterns.md +189 -0
  120. package/assets/skills/monorepo-patterns.md +287 -0
  121. package/assets/skills/nextjs-app-router.md +237 -0
  122. package/assets/skills/notification-patterns.md +348 -0
  123. package/assets/skills/oauth-patterns.md +246 -0
  124. package/assets/skills/payment-integration.md +222 -0
  125. package/assets/skills/pdf-generation.md +307 -0
  126. package/assets/skills/performance-optimization.md +277 -0
  127. package/assets/skills/php-patterns.md +210 -0
  128. package/assets/skills/prisma-patterns.md +241 -0
  129. package/assets/skills/prompt-engineering.md +193 -0
  130. package/assets/skills/pwa-patterns.md +247 -0
  131. package/assets/skills/python-patterns.md +158 -0
  132. package/assets/skills/python-testing.md +172 -0
  133. package/assets/skills/queue-patterns.md +295 -0
  134. package/assets/skills/rag-patterns.md +159 -0
  135. package/assets/skills/rate-limiting.md +319 -0
  136. package/assets/skills/react-components.md +201 -0
  137. package/assets/skills/react-native-patterns.md +299 -0
  138. package/assets/skills/real-time-patterns.md +181 -0
  139. package/assets/skills/redis-patterns.md +188 -0
  140. package/assets/skills/refactoring.md +218 -0
  141. package/assets/skills/regex-patterns.md +191 -0
  142. package/assets/skills/remix-patterns.md +262 -0
  143. package/assets/skills/responsive-design.md +199 -0
  144. package/assets/skills/ruby-rails-patterns.md +178 -0
  145. package/assets/skills/rust-patterns.md +211 -0
  146. package/assets/skills/search-patterns.md +227 -0
  147. package/assets/skills/security-hardening.md +237 -0
  148. package/assets/skills/seo-patterns.md +179 -0
  149. package/assets/skills/serverless-patterns.md +223 -0
  150. package/assets/skills/sql-optimization.md +154 -0
  151. package/assets/skills/state-management.md +254 -0
  152. package/assets/skills/storybook-patterns.md +330 -0
  153. package/assets/skills/svelte-patterns.md +258 -0
  154. package/assets/skills/swift-patterns.md +227 -0
  155. package/assets/skills/tailwind-patterns.md +272 -0
  156. package/assets/skills/tdd-workflow.md +199 -0
  157. package/assets/skills/terraform-patterns.md +270 -0
  158. package/assets/skills/testing-react.md +240 -0
  159. package/assets/skills/testing-vitest.md +232 -0
  160. package/assets/skills/typescript-strict.md +159 -0
  161. package/assets/skills/video-processing.md +340 -0
  162. package/assets/skills/vue-patterns.md +247 -0
  163. package/assets/skills/web-workers.md +327 -0
  164. package/assets/skills/webhooks-patterns.md +283 -0
  165. package/assets/skills/websocket-patterns.md +306 -0
  166. package/dist/cli/index.js +941 -958
  167. package/dist/core/index.d.ts +341 -11
  168. package/dist/core.js +58 -95
  169. package/dist/mcp/index.d.ts +33 -1
  170. package/dist/mcp-server.js +177 -255
  171. package/package.json +4 -1
@@ -0,0 +1,306 @@
1
+ ---
2
+ name: websocket-patterns
3
+ description: WebSocket patterns for connection management, heartbeat, reconnection, rooms, binary data, and scaling.
4
+ ---
5
+
6
+ # WebSocket Patterns
7
+
8
+ ## When to Use
9
+
10
+ Apply these patterns when building real-time features: chat, live dashboards,
11
+ collaborative editing, notifications, or streaming data. Use this skill for
12
+ managing connections reliably, implementing heartbeat/ping-pong, handling
13
+ reconnection on the client, organizing connections into rooms, and scaling
14
+ across multiple server instances.
15
+
16
+ ## How It Works
17
+
18
+ ### Connection Manager
19
+
20
+ Track active connections in a Map keyed by user/session ID. Handle connect,
21
+ disconnect, and broadcast operations. Clean up stale connections.
22
+
23
+ ```typescript
24
+ interface Connection {
25
+ ws: WebSocket
26
+ userId: string
27
+ connectedAt: number
28
+ lastPing: number
29
+ }
30
+
31
+ class ConnectionManager {
32
+ private connections = new Map<string, Connection>()
33
+
34
+ add(userId: string, ws: WebSocket): void {
35
+ // Close existing connection for same user (prevent duplicates)
36
+ const existing = this.connections.get(userId)
37
+ if (existing) {
38
+ existing.ws.close(4000, 'Replaced by new connection')
39
+ }
40
+ this.connections.set(userId, {
41
+ ws, userId, connectedAt: Date.now(), lastPing: Date.now(),
42
+ })
43
+ }
44
+
45
+ remove(userId: string): void {
46
+ this.connections.delete(userId)
47
+ }
48
+
49
+ send(userId: string, data: unknown): boolean {
50
+ const conn = this.connections.get(userId)
51
+ if (conn && conn.ws.readyState === WebSocket.OPEN) {
52
+ conn.ws.send(JSON.stringify(data))
53
+ return true
54
+ }
55
+ return false
56
+ }
57
+
58
+ broadcast(data: unknown, exclude?: string): void {
59
+ const payload = JSON.stringify(data)
60
+ for (const [userId, conn] of this.connections) {
61
+ if (userId !== exclude && conn.ws.readyState === WebSocket.OPEN) {
62
+ conn.ws.send(payload)
63
+ }
64
+ }
65
+ }
66
+
67
+ get size(): number {
68
+ return this.connections.size
69
+ }
70
+ }
71
+ ```
72
+
73
+ ### Heartbeat (Server-Side Ping/Pong)
74
+
75
+ Send periodic pings to detect dead connections. Close connections that miss
76
+ two consecutive pongs. Run the heartbeat on a fixed interval.
77
+
78
+ ```typescript
79
+ class HeartbeatMonitor {
80
+ private interval: NodeJS.Timeout | null = null
81
+
82
+ start(manager: ConnectionManager, intervalMs = 30_000): void {
83
+ this.interval = setInterval(() => {
84
+ const now = Date.now()
85
+ const staleThreshold = now - intervalMs * 2
86
+
87
+ for (const [userId, conn] of manager.allConnections()) {
88
+ if (conn.lastPing < staleThreshold) {
89
+ console.log(`Closing stale connection: ${userId}`)
90
+ conn.ws.terminate()
91
+ manager.remove(userId)
92
+ continue
93
+ }
94
+ if (conn.ws.readyState === WebSocket.OPEN) {
95
+ conn.ws.ping()
96
+ }
97
+ }
98
+ }, intervalMs)
99
+ }
100
+
101
+ stop(): void {
102
+ if (this.interval) clearInterval(this.interval)
103
+ }
104
+ }
105
+
106
+ // On the WebSocket server:
107
+ wss.on('connection', (ws, req) => {
108
+ const userId = authenticate(req)
109
+ manager.add(userId, ws)
110
+
111
+ ws.on('pong', () => {
112
+ manager.updatePing(userId)
113
+ })
114
+
115
+ ws.on('close', () => {
116
+ manager.remove(userId)
117
+ })
118
+ })
119
+ ```
120
+
121
+ ### Client-Side Reconnection
122
+
123
+ Implement exponential backoff with jitter. Track connection state for UI feedback.
124
+ Re-authenticate after reconnecting.
125
+
126
+ ```typescript
127
+ class ReconnectingWebSocket {
128
+ private ws: WebSocket | null = null
129
+ private attempt = 0
130
+ private maxAttempts = 10
131
+ private baseDelay = 1000
132
+ private maxDelay = 30_000
133
+
134
+ constructor(
135
+ private url: string,
136
+ private onMessage: (data: unknown) => void,
137
+ private onStateChange: (state: 'connecting' | 'open' | 'closed') => void,
138
+ ) {}
139
+
140
+ connect(): void {
141
+ this.onStateChange('connecting')
142
+ this.ws = new WebSocket(this.url)
143
+
144
+ this.ws.onopen = () => {
145
+ this.attempt = 0
146
+ this.onStateChange('open')
147
+ }
148
+
149
+ this.ws.onmessage = (event) => {
150
+ this.onMessage(JSON.parse(event.data))
151
+ }
152
+
153
+ this.ws.onclose = (event) => {
154
+ this.onStateChange('closed')
155
+ if (event.code !== 4000 && this.attempt < this.maxAttempts) {
156
+ this.scheduleReconnect()
157
+ }
158
+ }
159
+ }
160
+
161
+ private scheduleReconnect(): void {
162
+ const delay = Math.min(
163
+ this.baseDelay * Math.pow(2, this.attempt) + Math.random() * 1000,
164
+ this.maxDelay,
165
+ )
166
+ this.attempt++
167
+ setTimeout(() => this.connect(), delay)
168
+ }
169
+
170
+ send(data: unknown): void {
171
+ if (this.ws?.readyState === WebSocket.OPEN) {
172
+ this.ws.send(JSON.stringify(data))
173
+ }
174
+ }
175
+
176
+ close(): void {
177
+ this.ws?.close(4000, 'Client closed')
178
+ }
179
+ }
180
+ ```
181
+
182
+ ### Room-Based Broadcasting
183
+
184
+ Group connections by topic/channel. Users can join/leave rooms. Broadcast to
185
+ all members of a room.
186
+
187
+ ```typescript
188
+ class RoomManager {
189
+ private rooms = new Map<string, Set<string>>() // roomId -> Set<userId>
190
+
191
+ join(roomId: string, userId: string): void {
192
+ if (!this.rooms.has(roomId)) {
193
+ this.rooms.set(roomId, new Set())
194
+ }
195
+ this.rooms.get(roomId)!.add(userId)
196
+ }
197
+
198
+ leave(roomId: string, userId: string): void {
199
+ this.rooms.get(roomId)?.delete(userId)
200
+ if (this.rooms.get(roomId)?.size === 0) {
201
+ this.rooms.delete(roomId)
202
+ }
203
+ }
204
+
205
+ leaveAll(userId: string): void {
206
+ for (const [roomId, members] of this.rooms) {
207
+ members.delete(userId)
208
+ if (members.size === 0) this.rooms.delete(roomId)
209
+ }
210
+ }
211
+
212
+ broadcast(roomId: string, data: unknown, connManager: ConnectionManager, exclude?: string): void {
213
+ const members = this.rooms.get(roomId)
214
+ if (!members) return
215
+ for (const userId of members) {
216
+ if (userId !== exclude) {
217
+ connManager.send(userId, data)
218
+ }
219
+ }
220
+ }
221
+
222
+ members(roomId: string): string[] {
223
+ return [...(this.rooms.get(roomId) ?? [])]
224
+ }
225
+ }
226
+ ```
227
+
228
+ ### Message Protocol
229
+
230
+ Define a typed message protocol. Use a `type` field for routing. Include a
231
+ message ID for acknowledgment.
232
+
233
+ ```typescript
234
+ type ClientMessage =
235
+ | { type: 'join'; roomId: string }
236
+ | { type: 'leave'; roomId: string }
237
+ | { type: 'chat'; roomId: string; text: string; msgId: string }
238
+ | { type: 'ping' }
239
+
240
+ type ServerMessage =
241
+ | { type: 'chat'; roomId: string; text: string; userId: string; timestamp: number }
242
+ | { type: 'ack'; msgId: string }
243
+ | { type: 'error'; code: string; message: string }
244
+ | { type: 'members'; roomId: string; users: string[] }
245
+ | { type: 'pong' }
246
+
247
+ function handleMessage(userId: string, raw: string): void {
248
+ const msg: ClientMessage = JSON.parse(raw)
249
+ switch (msg.type) {
250
+ case 'join': rooms.join(msg.roomId, userId); break
251
+ case 'leave': rooms.leave(msg.roomId, userId); break
252
+ case 'chat': handleChat(userId, msg); break
253
+ case 'ping': connManager.send(userId, { type: 'pong' }); break
254
+ }
255
+ }
256
+ ```
257
+
258
+ ### Scaling with Redis Pub/Sub
259
+
260
+ When running multiple server instances, use Redis pub/sub to fan out messages
261
+ across all instances. Each instance subscribes to relevant channels.
262
+
263
+ ```typescript
264
+ import Redis from 'ioredis'
265
+
266
+ const pub = new Redis(REDIS_URL)
267
+ const sub = new Redis(REDIS_URL)
268
+
269
+ // Subscribe to room channels
270
+ sub.on('message', (channel, message) => {
271
+ const roomId = channel.replace('room:', '')
272
+ const data = JSON.parse(message)
273
+ rooms.broadcast(roomId, data, connManager)
274
+ })
275
+
276
+ function publishToRoom(roomId: string, data: unknown): void {
277
+ pub.publish(`room:${roomId}`, JSON.stringify(data))
278
+ }
279
+ ```
280
+
281
+ ## Examples
282
+
283
+ **Pattern: Binary data with ArrayBuffer**
284
+ ```typescript
285
+ ws.binaryType = 'arraybuffer'
286
+ ws.onmessage = (event) => {
287
+ if (event.data instanceof ArrayBuffer) {
288
+ const view = new DataView(event.data)
289
+ const messageType = view.getUint8(0)
290
+ // handle binary protocol
291
+ }
292
+ }
293
+ ```
294
+
295
+ ## Checklist
296
+
297
+ - [ ] Connection manager tracks all active connections with metadata
298
+ - [ ] Server-side ping/pong heartbeat detects and cleans up dead connections
299
+ - [ ] Client reconnects with exponential backoff + jitter
300
+ - [ ] Connections closed with meaningful close codes (4000+ for application codes)
301
+ - [ ] Room manager for topic-based broadcasting with join/leave/leaveAll
302
+ - [ ] Typed message protocol with `type` field for routing
303
+ - [ ] Message acknowledgments (`ack`) for delivery confirmation
304
+ - [ ] Redis pub/sub for multi-instance broadcasting
305
+ - [ ] Authentication on initial connection (token in query string or first message)
306
+ - [ ] Connection state exposed to UI (`connecting`, `open`, `closed`)