@gwakko/shared-websocket 0.8.1 → 0.8.2

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 +97 -0
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1468,6 +1468,66 @@ function notifyNewOrder(order: Order) {
1468
1468
  });
1469
1469
  // Only clients who called ws.subscribe('notifications:orders') receive this
1470
1470
  }
1471
+
1472
+ // ─── Push Notifications ──────────────────────────
1473
+
1474
+ // Client listens via: ws.push('notification', { render: ... })
1475
+ // Server sends 'notification' event — client shows toast/push
1476
+ function sendPushNotification(
1477
+ targetUserId: string,
1478
+ notification: { id: string; title: string; body: string; type: string; url?: string },
1479
+ ) {
1480
+ for (const [ws, state] of clients) {
1481
+ if (state.userId === targetUserId) {
1482
+ send(ws, 'notification', notification);
1483
+ }
1484
+ }
1485
+ }
1486
+
1487
+ // Broadcast push to all connected clients
1488
+ function broadcastPush(notification: { id: string; title: string; body: string; type: string }) {
1489
+ for (const [ws] of clients) {
1490
+ send(ws, 'notification', notification);
1491
+ }
1492
+ }
1493
+
1494
+ // ─── Usage examples ──────────────────────────────
1495
+
1496
+ // After order created — notify the merchant
1497
+ async function onOrderCreated(order: Order) {
1498
+ // 1. Notify via topic (only subscribers)
1499
+ broadcastToTopic('notifications:orders', 'new', order);
1500
+
1501
+ // 2. Push notification to specific user
1502
+ sendPushNotification(order.merchantId, {
1503
+ id: `order-${order.id}`,
1504
+ title: `New Order #${order.id}`,
1505
+ body: `$${order.total} from ${order.customerName}`,
1506
+ type: 'success',
1507
+ url: `/orders/${order.id}`,
1508
+ });
1509
+ }
1510
+
1511
+ // Payment failed — critical alert to user
1512
+ async function onPaymentFailed(payment: Payment) {
1513
+ sendPushNotification(payment.userId, {
1514
+ id: `payment-${payment.id}`,
1515
+ title: 'Payment Failed',
1516
+ body: `Your payment of $${payment.amount} could not be processed`,
1517
+ type: 'error',
1518
+ url: `/payments/${payment.id}`,
1519
+ });
1520
+ }
1521
+
1522
+ // System maintenance — broadcast to everyone
1523
+ async function onMaintenanceScheduled(time: string) {
1524
+ broadcastPush({
1525
+ id: `maintenance-${Date.now()}`,
1526
+ title: 'Scheduled Maintenance',
1527
+ body: `System will be down for maintenance at ${time}`,
1528
+ type: 'warning',
1529
+ });
1530
+ }
1471
1531
  ```
1472
1532
 
1473
1533
  ### Go — Server Example
@@ -1509,6 +1569,21 @@ func handleMessage(conn *websocket.Conn, state *ClientState, msg Message) {
1509
1569
  conn.WriteJSON(Message{Event: "pong"})
1510
1570
  }
1511
1571
  }
1572
+
1573
+ // Send push notification to specific user
1574
+ func sendPushNotification(userID string, title, body, notifType string) {
1575
+ for conn, state := range clients {
1576
+ if state.UserID == userID {
1577
+ conn.WriteJSON(Message{
1578
+ Event: "notification",
1579
+ Data: json.RawMessage(fmt.Sprintf(
1580
+ `{"id":"%s","title":"%s","body":"%s","type":"%s"}`,
1581
+ uuid.NewString(), title, body, notifType,
1582
+ )),
1583
+ })
1584
+ }
1585
+ }
1586
+ }
1512
1587
  ```
1513
1588
 
1514
1589
  ### PHP (Laravel + Ratchet/Swoole) — Server Example
@@ -1544,6 +1619,28 @@ public function notifyTopic(string $topic, string $event, array $data): void
1544
1619
  }
1545
1620
  }
1546
1621
  }
1622
+
1623
+ // Send push notification to user
1624
+ public function sendPushNotification(string $userId, array $notification): void
1625
+ {
1626
+ foreach ($this->connections as $conn) {
1627
+ if ($this->getUserId($conn) === $userId) {
1628
+ $conn->send(json_encode([
1629
+ 'event' => 'notification',
1630
+ 'data' => $notification,
1631
+ ]));
1632
+ }
1633
+ }
1634
+ }
1635
+
1636
+ // Usage:
1637
+ // $this->sendPushNotification($order->merchant_id, [
1638
+ // 'id' => Str::uuid(),
1639
+ // 'title' => "New Order #{$order->id}",
1640
+ // 'body' => "\${$order->total} from {$order->customer_name}",
1641
+ // 'type' => 'success',
1642
+ // 'url' => "/orders/{$order->id}",
1643
+ // ]);
1547
1644
  ```
1548
1645
 
1549
1646
  ## Exported Types
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gwakko/shared-websocket",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
4
4
  "description": "Share ONE WebSocket connection across browser tabs — leader election, BroadcastChannel sync, optional Web Worker",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",