@tailuge/messaging 1.2.0 → 1.3.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 (2) hide show
  1. package/SKILL.md +37 -116
  2. package/package.json +1 -1
package/SKILL.md CHANGED
@@ -1,30 +1,33 @@
1
- # @tailuge/messaging Agent Skill
1
+ ---
2
+ name: tailuge-messaging
3
+ description: |
4
+ Integration guide for @tailuge/messaging library. Use when building applications with:
5
+ - Real-time presence/lobby systems
6
+ - User matchmaking via challenges
7
+ - Game table communication with players and spectators
8
+ - Nchan-powered transport layer
9
+ ---
2
10
 
3
- Use this skill when integrating the `@tailuge/messaging` library into a new project or codebase.
11
+ # @tailuge/messaging
4
12
 
5
- ## Installation
13
+ Quick integration guide. See [MESSAGING_SPEC.md](./MESSAGING_SPEC.md) for full API contract.
14
+
15
+ ## Install
6
16
 
7
17
  ```bash
8
18
  npm install @tailuge/messaging
9
19
  ```
10
20
 
11
- ## Initialization
12
-
13
- Create a `MessagingClient` instance with your Nchan server base URL:
21
+ ## Quick Start
14
22
 
15
23
  ```typescript
16
24
  import { MessagingClient } from '@tailuge/messaging';
17
25
 
18
- const client = new MessagingClient({
19
- baseUrl: "https://your-nchan-server.com",
20
- });
21
-
22
- await client.start();
26
+ const client = new MessagingClient({ baseUrl: "https://your-nchan-server.com" });
27
+ client.start();
23
28
  ```
24
29
 
25
- ## Getting Online User Count
26
-
27
- Join the lobby and listen for user changes:
30
+ ## Lobby & Presence
28
31
 
29
32
  ```typescript
30
33
  const lobby = await client.joinLobby({
@@ -35,57 +38,27 @@ const lobby = await client.joinLobby({
35
38
  });
36
39
 
37
40
  lobby.onUsersChange((users) => {
38
- console.log("Online users:", users.length);
39
- });
40
- ```
41
-
42
- ## Getting User List
43
-
44
- The same `onUsersChange` callback provides the full user list:
45
-
46
- ```typescript
47
- lobby.onUsersChange((users) => {
48
- // Users are sorted alphabetically by userName
49
- users.forEach(user => {
50
- console.log(`${user.userName} (${user.userId})`);
51
- if (user.tableId) {
52
- console.log(` Playing at table: ${user.tableId}`);
53
- }
41
+ console.log(`Online: ${users.length}`);
42
+ users.forEach(u => {
43
+ const flag = countryToFlag(u._meta?.country);
44
+ console.log(`${flag} ${u.userName}`);
54
45
  });
55
46
  });
56
47
  ```
57
48
 
58
- ## Sending a Challenge
59
-
60
- To challenge another user to a game:
49
+ ## Challenge Opponent
61
50
 
62
51
  ```typescript
63
- // challenge(userId, ruleType) returns the table ID
64
52
  const tableId = await lobby.challenge(targetUserId, "billiards");
65
- console.log(`Challenge sent, table created: ${tableId}`);
66
- ```
67
53
 
68
- ## Receiving Challenges
69
-
70
- Listen for incoming challenges:
71
-
72
- ```typescript
73
54
  lobby.onChallenge((challenge) => {
74
- console.log(`${challenge.challengerName} challenged you to ${challenge.ruleType}`);
75
-
76
55
  if (challenge.type === "offer") {
77
- // Accept the challenge
78
56
  lobby.acceptChallenge(challenge.challengerId, challenge.ruleType, challenge.tableId);
79
-
80
- // Or decline
81
- // lobby.declineChallenge(challenge.challengerId, challenge.ruleType);
82
57
  }
83
58
  });
84
59
  ```
85
60
 
86
- ## Joining a Table
87
-
88
- Connect to a specific game table:
61
+ ## Table Messaging
89
62
 
90
63
  ```typescript
91
64
  interface Move { x: number; y: number }
@@ -93,18 +66,14 @@ const table = await client.joinTable<Move>("table-xyz", "user-123");
93
66
 
94
67
  table.onMessage((msg) => {
95
68
  if (msg.type === "MOVE") {
96
- const move = msg.data as Move;
97
- console.log(`Move received at: ${msg._meta?.ts}`);
69
+ console.log(`Move at: ${msg._meta?.ts}`);
98
70
  }
99
71
  });
100
72
 
101
- // Send a move
102
73
  await table.publish("MOVE", { x: 10, y: 20 });
103
74
  ```
104
75
 
105
- ## Spectator Updates
106
-
107
- Listen for spectator changes at a table:
76
+ ## Spectators
108
77
 
109
78
  ```typescript
110
79
  table.onSpectatorChange((spectators) => {
@@ -114,79 +83,31 @@ table.onSpectatorChange((spectators) => {
114
83
 
115
84
  ## Cleanup
116
85
 
117
- When done, stop the client:
118
-
119
86
  ```typescript
120
87
  await client.stop();
121
88
  ```
122
89
 
123
- ## Key Interfaces
124
-
125
- ### PresenceMessage
126
- ```typescript
127
- interface PresenceMessage {
128
- messageType: "presence";
129
- type: "join" | "heartbeat" | "leave";
130
- userId: string;
131
- userName: string;
132
- ruleType?: string;
133
- tableId?: string;
134
- // ... other fields
135
- }
136
- ```
137
-
138
- ### Meta
139
- ```typescript
140
- interface Meta {
141
- ts: string; // ISO timestamp from server
142
- locale: string; // Accept-Language header
143
- ua: string; // User-Agent header
144
- ip: string; // Client remote address
145
- origin: string; // Origin header value
146
- host: string; // Host header value
147
- path: string; // Request URI path
148
- method: string; // HTTP method
149
- country: string; // Country code from IP (e.g., "US", "GB", "XX")
150
- }
151
- ```
152
-
153
- ### ChallengeMessage
154
- ```typescript
155
- interface ChallengeMessage {
156
- messageType: "challenge";
157
- type: "offer" | "accept" | "decline" | "cancel";
158
- challengerId: string;
159
- challengerName: string;
160
- recipientId: string;
161
- ruleType: string;
162
- tableId?: string;
163
- }
164
- ```
90
+ ## Key Imports
165
91
 
166
- ### TableMessage<T>
167
92
  ```typescript
168
- interface TableMessage<T = any> {
169
- type: string;
170
- senderId: string;
171
- data: T;
172
- _meta?: Meta;
173
- }
93
+ import {
94
+ MessagingClient,
95
+ canChallenge,
96
+ canSpectate,
97
+ activeGames,
98
+ } from '@tailuge/messaging';
174
99
  ```
175
100
 
176
- ## Helper Predicates
177
-
178
- The library exports helper functions:
101
+ ## Predicates
179
102
 
180
103
  ```typescript
181
- import { canChallenge, canSpectate } from '@tailuge/messaging';
182
-
183
- // Check if you can challenge a user
184
104
  if (canChallenge(targetUser, currentUserId)) {
185
- lobby.challenge(targetUser.userId, "billiards");
105
+ await lobby.challenge(targetUser.userId, "billiards");
186
106
  }
187
107
 
188
- // Check if you can spectate a user
189
108
  if (canSpectate(targetUser, currentTableId)) {
190
- const table = await client.joinTable(targetUser.tableId, currentUserId);
109
+ await client.joinTable(targetUser.tableId, currentUserId);
191
110
  }
192
111
  ```
112
+
113
+ See [MESSAGING_SPEC.md](./MESSAGING_SPEC.md) for complete interface definitions.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailuge/messaging",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "description": "A stateful messaging library for Nchan-powered real-time applications.",
6
6
  "main": "./dist/index.js",