@sockethub/client 5.0.0-alpha.11 → 5.0.0-alpha.13

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/README.md CHANGED
@@ -1,55 +1,93 @@
1
1
  # @sockethub/client
2
2
 
3
- JavaScript client for [Sockethub](https://github.com/sockethub/sockethub) - a protocol
4
- gateway that translates ActivityStreams messages into various protocols (XMPP, IRC, RSS, etc.).
5
-
6
- Works in Node.js and browsers.
3
+ The Sockethub client is a small JavaScript SDK for app developers to connect to a
4
+ Sockethub server via Socket.IO and send/receive ActivityStreams messages. It works
5
+ in both Node.js and browsers, with schema-driven validation, automatic
6
+ reconnection, and credential replay.
7
+
8
+ ## What's Included
9
+
10
+ - `SockethubClient` for connection and message handling
11
+ - Schema-driven validation of outbound ActivityStreams messages (via `@sockethub/schemas`)
12
+ - `contextFor(platform)` builds canonical `@context` arrays from server metadata
13
+ - `ready()` promise and `ready`/`init_error` observability events
14
+ - Automatic outbound queuing until initialization is complete
15
+ - Auto-replay of credentials and connections on reconnect
16
+ - A browser-ready bundle in `dist/`
17
+
18
+ ## How It Works
19
+
20
+ `SockethubClient` wraps a [Socket.IO](https://socket.io) connection and manages
21
+ everything between your app and the Sockethub server:
22
+
23
+ 1. **Schema registry handshake.** On connect (and every reconnect) the client
24
+ requests the server's *platform schema registry* — the contexts, versions,
25
+ and JSON schemas for each platform the server has loaded. It caches that
26
+ registry along with a content fingerprint the server provides. On reconnect
27
+ the client echoes the fingerprint; if nothing has changed the server replies
28
+ `unchanged` instead of re-sending the full schema set, so the (potentially
29
+ large) registry crosses the wire only when it actually changes.
30
+ 2. **Initialization lifecycle.** `ready()` resolves once the registry is
31
+ applied; `getInitState()` and the `ready` / `init_error` events expose the
32
+ same lifecycle. Outbound events emitted before the client is ready are queued
33
+ in memory and flushed automatically once initialization completes.
34
+ 3. **Message handling.** Outgoing `message`/`credentials` events are normalized
35
+ (string `actor`/`target` references are expanded to objects) and validated
36
+ against the originating platform's schema before they leave the client;
37
+ incoming platform events are normalized before being handed to your
38
+ `message` listener. Validation uses the same schemas the server enforces, so
39
+ malformed activities are caught locally rather than round-tripping.
40
+ 4. **Context composition.** `contextFor(platform)` builds the canonical
41
+ `@context` array for a platform from the cached registry.
42
+ 5. **Reconnect resilience.** Credentials, platform connections, and room joins
43
+ are kept in memory and replayed when the socket reconnects (see
44
+ [Security & State Management](#security--state-management)).
7
45
 
8
46
  ## Install
9
47
 
10
48
  ### Node.js
11
49
 
12
- `$ npm install @sockethub/client`
50
+ `$ npm install @sockethub/client socket.io-client`
13
51
 
14
52
  ### Bun
15
53
 
16
- `$ bun install @sockethub/client`
17
-
18
- #### CommonJS
19
-
20
- ```javascript
21
- const SockethubClient = require('@sockethub/client');
22
- const io = require('@socket.io-client');
23
- const SOCKETHUB_SERVER = 'http://localhost:10550';
24
- const sc = SockethubClient(io(SOCKETHUB_SERVER));
25
- ```
26
-
27
- #### ESM
54
+ `$ bun install @sockethub/client socket.io-client`
28
55
 
29
56
  ```javascript
30
57
  import SockethubClient from '@sockethub/client';
31
- import { io } from '@socket.io-client';
58
+ import { io } from 'socket.io-client';
32
59
  const SOCKETHUB_SERVER = 'http://localhost:10550';
33
- const sc = SockethubClient(io(SOCKETHUB_SERVER));
60
+ const sc = new SockethubClient(io(SOCKETHUB_SERVER));
34
61
  ```
35
62
 
36
63
  ### Browser
37
64
 
38
- The browser bundle is available in the dist folder:
65
+ Two browser builds are published in `dist/`:
39
66
 
40
- ```
41
- import '@sockethub/client/dist/sockethub-client.js';
42
- ```
67
+ - `dist/sockethub-client.browser.js` is the IIFE/global build for plain `<script>` tags
68
+ - `dist/sockethub-client.js` is the ESM build for `<script type="module">`
43
69
 
44
- You can place it somewhere accessible from the web and include
45
- it via a `script` tag.
70
+ If you are serving assets from a Sockethub server, use the pre-copied global build
71
+ at `/sockethub-client.js` along with `/socket.io.js`:
46
72
 
73
+ ```html
74
+ <script src="/socket.io.js"></script>
75
+ <script src="/sockethub-client.js"></script>
47
76
  ```
48
- <script src="http://example.com/sockethub-client.js" type="module"></script>
49
- ```
50
77
 
51
- Once included in a web-page, the `SockethubClient` base object
52
- should be on the global scope.
78
+ These scripts set `io` and `SockethubClient` as globals.
79
+
80
+ If you are hosting the package files yourself and want ESM instead, serve
81
+ `dist/sockethub-client.js` and import it from a module script:
82
+
83
+ ```html
84
+ <script type="module">
85
+ import SockethubClient from '/dist/sockethub-client.js';
86
+ import { io } from '/socket.io.esm.min.js';
87
+
88
+ const sc = new SockethubClient(io('http://localhost:10550', { path: '/sockethub' }));
89
+ </script>
90
+ ```
53
91
 
54
92
  ## Quick Start
55
93
 
@@ -58,20 +96,102 @@ import SockethubClient from '@sockethub/client';
58
96
  import { io } from 'socket.io-client';
59
97
 
60
98
  const socket = io('http://localhost:10550', { path: '/sockethub' });
61
- const sc = new SockethubClient(socket);
99
+ const sc = new SockethubClient(socket, { initTimeoutMs: 5000 });
62
100
 
63
101
  sc.socket.on('message', (msg) => console.log(msg));
102
+ sc.socket.on('ready', (info) => {
103
+ console.log('Sockethub ready:', info.reason, info.sockethubVersion,
104
+ info.platforms.map((p) => ({ id: p.id, version: p.version })));
105
+ });
106
+ sc.socket.on('init_error', (e) => {
107
+ console.warn('Sockethub init issue:', e.error);
108
+ });
109
+
110
+ // Wait for schema registry, then send a message
111
+ try {
112
+ await sc.ready();
113
+ sc.socket.emit('message', {
114
+ '@context': sc.contextFor('dummy'),
115
+ type: 'echo',
116
+ actor: { id: 'test@dummy', type: 'person' },
117
+ object: { type: 'message', content: 'hello world' }
118
+ }, (ack) => {
119
+ if (ack?.error) {
120
+ console.error('Send failed:', ack.error);
121
+ return;
122
+ }
123
+ console.log('Ack:', ack);
124
+ });
125
+ } catch (err) {
126
+ console.error('Sockethub failed to initialize:', err);
127
+ }
64
128
  ```
65
129
 
66
130
  See the [Client Guide](../../docs/client-guide.md) for detailed usage and examples.
67
131
 
68
132
  ## API
69
133
 
70
- - **`new SockethubClient(socket)`** - Create client instance
71
- - **`sc.socket.emit(event, data)`** - Send messages
134
+ - **`new SockethubClient(socket, options?)`** - Create client instance with optional init/queue settings
135
+ - **`sc.ready(timeoutMs?)`** - Wait for initialization to complete
136
+ - **`sc.isReady()`** - Check whether client is initialized
137
+ - **`sc.getInitState()`** - Return `"idle" | "initializing" | "ready" | "init_error" | "closed"`
138
+ - **`sc.contextFor(platform)`** - Build canonical `@context` for a platform from server registry
139
+ - **`sc.getRegisteredPlatforms()`** - Get server-registered platforms/contexts
140
+ - **`sc.getRegisteredBaseContexts()`** - Get AS2 and Sockethub base context URLs
141
+ - **`sc.getPlatformSchema(platform, schemaType?)`** - Get platform JSON schema
142
+ - **`sc.validateActivity(activity)`** - Validate against registered schemas
143
+ - **`sc.socket.emit(event, data, callback)`** - Send messages (queued until ready)
72
144
  - **`sc.socket.on(event, handler)`** - Listen for messages
73
145
  - **`sc.clearCredentials()`** - Clear stored credentials
74
- - **`sc.ActivityStreams`** - ActivityStreams library
146
+
147
+ Send a full `actor` object on each `credentials` and `message` event.
148
+
149
+ ## Result Handling
150
+
151
+ For client-initiated requests, pass a callback to `emit` and treat an `error`
152
+ field as failure:
153
+
154
+ ```javascript
155
+ sc.socket.emit("message", {
156
+ type: "echo",
157
+ "@context": sc.contextFor("dummy"),
158
+ actor: { id: "test", type: "person" },
159
+ object: { type: "message", content: "Hello!" },
160
+ }, (result) => {
161
+ if (result?.error) {
162
+ console.error("Sockethub request failed:", result.error);
163
+ return;
164
+ }
165
+
166
+ console.log("Sockethub request succeeded:", result);
167
+ });
168
+ ```
169
+
170
+ Also listen for ongoing platform events:
171
+
172
+ ```javascript
173
+ sc.socket.on("message", (msg) => {
174
+ console.log("incoming platform event:", msg);
175
+ });
176
+ ```
177
+
178
+ ## Sending messages
179
+
180
+ Include `id`, `type`, and usually `name` on the `actor` for `credentials` and
181
+ `message` events. Before sending, the client validates each outgoing activity
182
+ against the originating platform's schema from the server registry, surfacing a
183
+ client-side error instead of dispatching a malformed message.
184
+
185
+ ```javascript
186
+ sc.socket.emit("message", {
187
+ type: "join",
188
+ "@context": sc.contextFor("irc"),
189
+ actor: { id: "mynick", type: "person", name: "My IRC Nick" },
190
+ target: { id: "#sockethub", type: "room" },
191
+ }, (result) => {
192
+ if (result?.error) console.error(result.error);
193
+ });
194
+ ```
75
195
 
76
196
  ## Security & State Management
77
197
 
@@ -83,7 +203,6 @@ memory and replaying it when the connection is re-established.
83
203
  #### What Gets Stored
84
204
 
85
205
  - Credentials (passwords, tokens, API keys)
86
- - Actor definitions
87
206
  - Platform connections
88
207
  - Channel/room joins
89
208