@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/package.json CHANGED
@@ -1,21 +1,20 @@
1
1
  {
2
2
  "name": "@sockethub/client",
3
- "version": "5.0.0-alpha.11",
3
+ "version": "5.0.0-alpha.13",
4
4
  "description": "A JavaScript client for the Sockethub protocol gateway",
5
5
  "main": "./dist/sockethub-client.js",
6
6
  "exports": {
7
7
  ".": {
8
- "bun": "./src/sockethub-client.ts",
8
+ "types": "./dist/sockethub-client.d.ts",
9
9
  "import": "./dist/sockethub-client.js",
10
10
  "default": "./dist/sockethub-client.js"
11
11
  }
12
12
  },
13
13
  "files": [
14
- "src/",
15
14
  "dist/"
16
15
  ],
17
16
  "engines": {
18
- "bun": ">=1.2"
17
+ "node": ">=20"
19
18
  },
20
19
  "repository": {
21
20
  "type": "git",
@@ -47,11 +46,10 @@
47
46
  "test:browser": "wtr dist/**/*.test.js --node-resolve --puppeteer"
48
47
  },
49
48
  "dependencies": {
49
+ "@sockethub/schemas": "^3.0.0-alpha.13",
50
50
  "eventemitter3": "^5.0.4"
51
51
  },
52
52
  "devDependencies": {
53
- "@sockethub/activity-streams": "^4.4.0-alpha.11",
54
- "@sockethub/schemas": "^3.0.0-alpha.11",
55
53
  "@types/bun": "latest",
56
54
  "@types/sinon": "^17.0.4",
57
55
  "@web/test-runner": "^0.19.0",
@@ -59,5 +57,6 @@
59
57
  "sinon": "^17.0.2",
60
58
  "socket.io-client": "^4.8.3"
61
59
  },
62
- "gitHead": "c243fa9e76c688ce5ffcf524400b1dd27dcce615"
60
+ "gitHead": "864733e5b34449ef39542eceb4ff11aa308081bc",
61
+ "types": "./dist/sockethub-client.d.ts"
63
62
  }
@@ -1,389 +0,0 @@
1
- import type { ASManager } from "@sockethub/activity-streams";
2
- import { expect } from "chai";
3
- import EventEmitter from "eventemitter3";
4
- import { createSandbox, restore } from "sinon";
5
-
6
- import SockethubClient from "./sockethub-client";
7
-
8
- describe("SockethubClient bad initialization", () => {
9
- it("no socket.io instance", () => {
10
- class TestSockethubClient extends SockethubClient {
11
- initActivityStreams() {
12
- this.ActivityStreams = {} as ASManager;
13
- }
14
- }
15
- expect(() => {
16
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
17
- // @ts-ignore
18
- new TestSockethubClient();
19
- }).to.throw("SockethubClient requires a socket.io instance");
20
- });
21
- });
22
-
23
- describe("SockethubClient", () => {
24
- let asInstance: any, socket: any, sc: any, sandbox: any;
25
-
26
- beforeEach(() => {
27
- sandbox = sandbox = createSandbox();
28
- socket = new EventEmitter();
29
- socket.connected = false;
30
- socket.__instance = "socketio"; // used to uniquely identify the object we're passing in
31
- sandbox.spy(socket, "on");
32
- sandbox.spy(socket, "emit");
33
- asInstance = new EventEmitter();
34
- sandbox.spy(asInstance, "on");
35
- sandbox.spy(asInstance, "emit");
36
- asInstance.Stream = sandbox.stub().returnsArg(0);
37
- asInstance.Object = {
38
- create: sandbox.stub(),
39
- };
40
- class TestSockethubClient extends SockethubClient {
41
- initActivityStreams() {
42
- this.ActivityStreams = asInstance as ASManager;
43
- }
44
- }
45
- sc = new TestSockethubClient(socket);
46
- sandbox.spy(sc.socket, "on");
47
- sandbox.spy(sc.socket, "emit");
48
- sandbox.spy(sc.socket, "_emit");
49
- });
50
-
51
- afterEach(() => {
52
- restore();
53
- });
54
-
55
- it("contains the ActivityStreams property", () => {
56
- expect(asInstance).to.be.eql(sc.ActivityStreams);
57
- expect(typeof asInstance.Stream).to.equal("function");
58
- expect(typeof sc.ActivityStreams.Object.create).to.equal("function");
59
- });
60
-
61
- it("contains the socket property", () => {
62
- expect(sc.socket instanceof EventEmitter).to.be.true;
63
- // the object we passed in should not be the publicly available one
64
- expect(sc.socket.__instance).to.not.equal("socketio");
65
- expect(sc.debug).to.be.true;
66
- expect(sc.socket.connected).to.be.false;
67
- });
68
-
69
- it("registers listeners for ActivityStream events", () => {
70
- expect(asInstance.on.callCount).to.equal(1);
71
- expect(asInstance.on.calledWithMatch("activity-object-create")).to.be
72
- .true;
73
- });
74
-
75
- it("registers a listeners for socket events", () => {
76
- expect(socket.on.callCount).to.equal(5);
77
- expect(socket.on.calledWithMatch("activity-object")).to.be.true;
78
- expect(socket.on.calledWithMatch("connect")).to.be.true;
79
- expect(socket.on.calledWithMatch("connect_error")).to.be.true;
80
- expect(socket.on.calledWithMatch("disconnect")).to.be.true;
81
- expect(socket.on.calledWithMatch("message")).to.be.true;
82
- });
83
-
84
- describe("event handling", () => {
85
- it("activity-object", (done) => {
86
- socket.emit("activity-object", { foo: "bar" });
87
- setTimeout(() => {
88
- sandbox.assert.calledWith(asInstance.Object.create, {
89
- foo: "bar",
90
- });
91
- done();
92
- }, 0);
93
- });
94
-
95
- it("activity-object-create", (done) => {
96
- asInstance.emit("activity-object-create", { foo: "bar" });
97
- setTimeout(() => {
98
- expect(socket.emit.callCount).to.equal(1);
99
- expect(
100
- socket.emit.calledWithMatch("activity-object", {
101
- foo: "bar",
102
- }),
103
- ).to.be.true;
104
- done();
105
- }, 0);
106
- });
107
-
108
- it("connect", (done) => {
109
- expect(sc.socket.connected).to.be.false;
110
- sc.socket.on("connect", () => {
111
- expect(sc.socket.connected).to.be.true;
112
- expect(sc.socket._emit.callCount).to.equal(1);
113
- expect(sc.socket._emit.calledWithMatch("connect"));
114
- done();
115
- });
116
- socket.emit("connect");
117
- });
118
-
119
- it("disconnect", (done) => {
120
- sc.socket.connected = true;
121
- sc.socket.on("disconnect", () => {
122
- expect(sc.socket.connected).to.be.false;
123
- expect(sc.socket._emit.callCount).to.equal(1);
124
- expect(sc.socket._emit.calledWithMatch("disconnect"));
125
- done();
126
- });
127
- socket.emit("disconnect");
128
- });
129
-
130
- it("connect_error", (done) => {
131
- sc.socket.on("connect_error", () => {
132
- expect(sc.socket._emit.callCount).to.equal(1);
133
- expect(sc.socket._emit.calledWithMatch("connect_error"));
134
- done();
135
- });
136
- socket.emit("connect_error");
137
- });
138
-
139
- it("message", (done) => {
140
- sc.socket.on("message", () => {
141
- expect(sc.socket._emit.callCount).to.equal(1);
142
- expect(sc.socket._emit.calledWithMatch("message"));
143
- done();
144
- });
145
- socket.emit("message");
146
- });
147
- });
148
-
149
- describe("event emitting", () => {
150
- it("message (no actor)", () => {
151
- sc._socket.connected = true;
152
- const callback = () => {
153
- };
154
- expect(() => {
155
- sc.socket.emit("message", { foo: "bar" }, callback);
156
- }).to.throw("actor property not present");
157
- });
158
-
159
- it("message", (done) => {
160
- sc.socket.connected = true;
161
- const callback = () => {};
162
- socket.once("message", (data: any, cb: any) => {
163
- expect(data).to.be.eql({ actor: "bar", type: "bar" });
164
- expect(cb).to.be.eql(callback);
165
- done();
166
- });
167
- sc.socket.emit("message", { actor: "bar", type: "bar" }, callback);
168
- });
169
-
170
- it("message (join)", (done) => {
171
- sc.socket.connected = true;
172
- const callback = () => {};
173
- socket.once("message", (data: any, cb: any) => {
174
- expect(data).to.be.eql({ actor: "bar", type: "join" });
175
- expect(cb).to.be.eql(callback);
176
- done();
177
- });
178
- sc.socket.emit("message", { actor: "bar", type: "join" }, callback);
179
- });
180
-
181
- it("message (leave)", (done) => {
182
- sc.socket.connected = true;
183
- const callback = () => {};
184
- socket.once("message", (data: any, cb: any) => {
185
- expect(data).to.be.eql({ actor: "bar", type: "leave" });
186
- expect(cb).to.be.eql(callback);
187
- done();
188
- });
189
- sc.socket.emit(
190
- "message",
191
- { actor: "bar", type: "leave" },
192
- callback,
193
- );
194
- });
195
-
196
- it("message (connect)", (done) => {
197
- sc.socket.connected = true;
198
- const callback = () => {};
199
- socket.once("message", (data: any, cb: any) => {
200
- expect(data).to.be.eql({ actor: "bar", type: "connect" });
201
- expect(cb).to.be.eql(callback);
202
- done();
203
- });
204
- sc.socket.emit(
205
- "message",
206
- { actor: "bar", type: "connect" },
207
- callback,
208
- );
209
- });
210
-
211
- it("message (disconnect)", (done) => {
212
- sc.socket.connected = true;
213
- const callback = () => {};
214
- socket.once("message", (data: any, cb: any) => {
215
- expect(data).to.be.eql({ actor: "bar", type: "disconnect" });
216
- expect(cb).to.be.eql(callback);
217
- done();
218
- });
219
- sc.socket.emit(
220
- "message",
221
- { actor: "bar", type: "disconnect" },
222
- callback,
223
- );
224
- });
225
-
226
- it("message (offline)", (done) => {
227
- sc.socket.connected = false;
228
- const callback = () => {};
229
- socket.once("message", (data: any, cb: any) => {
230
- expect(data).to.be.eql({ actor: "bar" });
231
- expect(cb).to.be.eql(callback);
232
- done();
233
- });
234
- sc.socket.emit("message", { actor: "bar" }, callback);
235
- });
236
-
237
- it("activity-object", (done) => {
238
- sc.socket.connected = true;
239
- const callback = () => {};
240
- socket.once("activity-object", (data: any, cb: any) => {
241
- expect(data).to.be.eql({ actor: "bar" });
242
- expect(cb).to.be.eql(callback);
243
- done();
244
- });
245
- sc.socket.emit("activity-object", { actor: "bar" }, callback);
246
- });
247
-
248
- it("credentials", (done) => {
249
- sc.socket.connected = true;
250
- const callback = () => {};
251
- socket.once("credentials", (data: any, cb: any) => {
252
- expect(data).to.be.eql({ actor: "bar" });
253
- expect(cb).to.be.eql(callback);
254
- done();
255
- });
256
- sc.socket.emit("credentials", { actor: "bar" }, callback);
257
- });
258
- });
259
-
260
- describe("replay functionality", () => {
261
- it("replays map values, not [key, val] pairs", (done) => {
262
- // Directly populate the activity-object map to test replay
263
- const testObj = { id: "test1", type: "like", content: "test" };
264
- sc.events["activity-object"].set("test1", testObj);
265
-
266
- // Reset socket spy and trigger replay
267
- socket.emit.resetHistory();
268
- socket.emit("connect");
269
-
270
- setTimeout(() => {
271
- const replayCalls = socket.emit.getCalls().filter(call => call.args[0] === "activity-object");
272
-
273
- expect(replayCalls).to.have.length(1);
274
- expect(replayCalls[0].args[1]).to.deep.equal(testObj);
275
- expect(Array.isArray(replayCalls[0].args[1])).to.be.false;
276
-
277
- done();
278
- }, 0);
279
- });
280
-
281
- it("does not call ActivityStreams.Stream() on activity-objects", (done) => {
282
- // Store an activity-object directly
283
- const activityObject = {
284
- id: "test-actor@example.com",
285
- type: "person",
286
- name: "Test Actor",
287
- };
288
- sc.events["activity-object"].set(activityObject.id, activityObject);
289
-
290
- // Reset spies
291
- socket.emit.resetHistory();
292
- asInstance.Stream.resetHistory();
293
-
294
- // Trigger reconnect which calls replay
295
- socket.emit("connect");
296
-
297
- setTimeout(() => {
298
- // Stream() should NOT be called for activity-objects
299
- const streamCalls = asInstance.Stream.getCalls();
300
- const activityObjectStreamCalls = streamCalls.filter(
301
- (call: any) => call.args[0]?.id === "test-actor@example.com",
302
- );
303
- expect(activityObjectStreamCalls).to.have.length(0);
304
-
305
- // But the activity-object should still be emitted
306
- const replayCalls = socket.emit
307
- .getCalls()
308
- .filter((call: any) => call.args[0] === "activity-object");
309
- expect(replayCalls).to.have.length(1);
310
- expect(replayCalls[0].args[1]).to.deep.equal(activityObject);
311
-
312
- done();
313
- }, 0);
314
- });
315
-
316
- it("calls ActivityStreams.Stream() on credentials during replay", (done) => {
317
- // Store credentials
318
- const credentials = {
319
- actor: { id: "user@example.com", type: "person" },
320
- object: { type: "credentials", password: "secret" },
321
- };
322
- sc.events.credentials.set(credentials.actor.id, credentials);
323
-
324
- // Reset spies
325
- socket.emit.resetHistory();
326
- asInstance.Stream.resetHistory();
327
-
328
- // Trigger reconnect
329
- socket.emit("connect");
330
-
331
- setTimeout(() => {
332
- // Stream() SHOULD be called for credentials
333
- expect(asInstance.Stream.called).to.be.true;
334
-
335
- // Credentials should be emitted
336
- const replayCalls = socket.emit
337
- .getCalls()
338
- .filter((call: any) => call.args[0] === "credentials");
339
- expect(replayCalls).to.have.length(1);
340
-
341
- done();
342
- }, 0);
343
- });
344
- });
345
-
346
- describe("clearCredentials", () => {
347
- it("clears stored credentials", () => {
348
- // Store some credentials
349
- sc.socket.emit("credentials", {
350
- actor: { id: "user@example.com" },
351
- object: { type: "credentials", username: "user", password: "pass" },
352
- });
353
-
354
- // Verify credentials are stored
355
- expect(sc.events.credentials.size).to.equal(1);
356
-
357
- // Clear credentials
358
- sc.clearCredentials();
359
-
360
- // Verify credentials are cleared
361
- expect(sc.events.credentials.size).to.equal(0);
362
- });
363
-
364
- it("prevents credential replay after clearing", (done) => {
365
- // Store credentials
366
- sc.socket.emit("credentials", {
367
- actor: { id: "user@example.com" },
368
- object: { type: "credentials", username: "user", password: "pass" },
369
- });
370
-
371
- // Clear credentials
372
- sc.clearCredentials();
373
-
374
- // Trigger reconnect
375
- let replayAttempts = 0;
376
- socket.on("credentials", () => {
377
- replayAttempts++;
378
- });
379
-
380
- socket.emit("connect");
381
-
382
- setTimeout(() => {
383
- // No credentials should have been replayed
384
- expect(replayAttempts).to.equal(0);
385
- done();
386
- }, 10);
387
- });
388
- });
389
- });