@blinkdotnew/sdk 0.14.4 → 0.14.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 (2) hide show
  1. package/README.md +66 -0
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1263,6 +1263,72 @@ All `{{secret_name}}` placeholders are replaced with encrypted values from your
1263
1263
 
1264
1264
  ## 🌍 Framework Examples
1265
1265
 
1266
+ ### React + Realtime Connections
1267
+
1268
+ **⚠️ Critical: Avoid Multiple WebSocket Connections**
1269
+
1270
+ ```typescript
1271
+ // ❌ WRONG - Creates new connection on every user change
1272
+ useEffect(() => {
1273
+ const channel = blink.realtime.channel('room')
1274
+ await channel.subscribe({ userId: user.id, metadata: { name: user.name } })
1275
+ return () => channel.unsubscribe()
1276
+ }, [user]) // ❌ Full user object dependency causes reconnections
1277
+ ```
1278
+
1279
+ ```typescript
1280
+ // ✅ CORRECT - Single stable connection
1281
+ const userRef = useRef(user)
1282
+ const [isConnected, setIsConnected] = useState(false)
1283
+
1284
+ useEffect(() => { userRef.current = user }, [user])
1285
+
1286
+ useEffect(() => {
1287
+ if (!user?.id) return
1288
+
1289
+ const channel = blink.realtime.channel('room')
1290
+ let isMounted = true, isSubscribed = false
1291
+
1292
+ const setup = async () => {
1293
+ if (!isMounted) return
1294
+ try {
1295
+ await channel.subscribe({
1296
+ userId: userRef.current.id,
1297
+ metadata: { name: userRef.current.name }
1298
+ })
1299
+ if (!isMounted) return
1300
+ isSubscribed = true
1301
+ setIsConnected(true)
1302
+
1303
+ channel.onMessage((msg) => {
1304
+ if (!isMounted) return
1305
+ // handle message
1306
+ })
1307
+ } catch (error) {
1308
+ console.error('Connection failed:', error)
1309
+ }
1310
+ }
1311
+
1312
+ setup()
1313
+ return () => {
1314
+ isMounted = false
1315
+ setIsConnected(false)
1316
+ if (isSubscribed) channel.unsubscribe()
1317
+ }
1318
+ }, [user.id]) // ✅ Only user.id dependency
1319
+
1320
+ // Only publish when connected
1321
+ if (isConnected) {
1322
+ await blink.realtime.publish('room', 'message', data)
1323
+ }
1324
+ ```
1325
+
1326
+ **Rules:**
1327
+ 1. **useEffect dependency**: `[user.id]` not `[user]`
1328
+ 2. **Use useRef**: Store user data to avoid re-connections
1329
+ 3. **Add isMounted**: Prevent operations on unmounted components
1330
+ 4. **Track connection state**: Only publish when actually connected
1331
+
1266
1332
  ### React
1267
1333
 
1268
1334
  ```typescript
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blinkdotnew/sdk",
3
- "version": "0.14.4",
3
+ "version": "0.14.5",
4
4
  "description": "Blink TypeScript SDK for client-side applications - Zero-boilerplate CRUD + auth + AI + analytics + notifications for modern SaaS/AI apps",
5
5
  "keywords": [
6
6
  "blink",