@sockethub/platform-irc 4.0.0-alpha.10 → 4.0.0-alpha.11
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/dist/index.js +45 -795
- package/dist/index.js.map +5 -12
- package/package.json +6 -5
- package/src/index.test.ts +10 -6
- package/src/index.ts +52 -37
package/src/index.test.ts
CHANGED
|
@@ -45,7 +45,12 @@ describe("Initialize IRC Platform", () => {
|
|
|
45
45
|
let platform;
|
|
46
46
|
beforeEach(() => {
|
|
47
47
|
platform = new IRC({
|
|
48
|
-
|
|
48
|
+
log: {
|
|
49
|
+
error: () => {},
|
|
50
|
+
warn: () => {},
|
|
51
|
+
info: () => {},
|
|
52
|
+
debug: () => {},
|
|
53
|
+
},
|
|
49
54
|
updateActor: function async() {
|
|
50
55
|
return Promise.resolve();
|
|
51
56
|
},
|
|
@@ -84,7 +89,6 @@ describe("Initialize IRC Platform", () => {
|
|
|
84
89
|
connectTimeoutMs: 30000,
|
|
85
90
|
persist: true,
|
|
86
91
|
requireCredentials: ["connect", "update"],
|
|
87
|
-
initialized: false,
|
|
88
92
|
});
|
|
89
93
|
});
|
|
90
94
|
|
|
@@ -247,7 +251,7 @@ describe("Initialize IRC Platform", () => {
|
|
|
247
251
|
});
|
|
248
252
|
|
|
249
253
|
it("disconnect()", (done) => {
|
|
250
|
-
expect(platform.
|
|
254
|
+
expect(platform.isInitialized()).toEqual(true);
|
|
251
255
|
let cleanupCalled = false;
|
|
252
256
|
platform.cleanup = (cb) => {
|
|
253
257
|
cleanupCalled = true;
|
|
@@ -259,16 +263,16 @@ describe("Initialize IRC Platform", () => {
|
|
|
259
263
|
actor: actor,
|
|
260
264
|
},
|
|
261
265
|
() => {
|
|
262
|
-
expect(platform.
|
|
266
|
+
expect(platform.isInitialized()).toEqual(true);
|
|
263
267
|
expect(cleanupCalled).toEqual(true);
|
|
264
268
|
done();
|
|
265
269
|
});
|
|
266
270
|
});
|
|
267
271
|
|
|
268
272
|
it("cleanup()", (done) => {
|
|
269
|
-
expect(platform.
|
|
273
|
+
expect(platform.isInitialized()).toEqual(true);
|
|
270
274
|
platform.cleanup(() => {
|
|
271
|
-
expect(platform.
|
|
275
|
+
expect(platform.isInitialized()).toEqual(false);
|
|
272
276
|
done();
|
|
273
277
|
});
|
|
274
278
|
});
|
package/src/index.ts
CHANGED
|
@@ -77,12 +77,11 @@ interface IrcSocketOptions {
|
|
|
77
77
|
* @param {object} cfg a unique config object for this instance
|
|
78
78
|
*/
|
|
79
79
|
export default class IRC implements PersistentPlatformInterface {
|
|
80
|
-
|
|
80
|
+
private readonly log: Logger;
|
|
81
81
|
credentialsHash: string;
|
|
82
82
|
config: PersistentPlatformConfig = {
|
|
83
83
|
persist: true,
|
|
84
84
|
requireCredentials: ["connect", "update"],
|
|
85
|
-
initialized: false,
|
|
86
85
|
connectTimeoutMs: 30000,
|
|
87
86
|
};
|
|
88
87
|
private readonly updateActor: PlatformUpdateActor;
|
|
@@ -90,13 +89,14 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
90
89
|
private irc2as: typeof IrcToActivityStreams;
|
|
91
90
|
private forceDisconnect = false;
|
|
92
91
|
private clientConnecting = false;
|
|
92
|
+
private initialized = false;
|
|
93
93
|
private client: typeof IrcSocket;
|
|
94
94
|
private jobQueue = []; // list of handlers to confirm when message delivery confirmed
|
|
95
95
|
private channels = new Set();
|
|
96
96
|
private handledActors = new Set();
|
|
97
97
|
|
|
98
98
|
constructor(session: PlatformSession) {
|
|
99
|
-
this.
|
|
99
|
+
this.log = session.log;
|
|
100
100
|
this.sendToClient = session.sendToClient;
|
|
101
101
|
this.updateActor = session.updateActor;
|
|
102
102
|
}
|
|
@@ -146,6 +146,14 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
146
146
|
return PlatformIrcSchema;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Returns whether the platform is ready to handle jobs.
|
|
151
|
+
* For IRC, this means we have successfully connected to the server.
|
|
152
|
+
*/
|
|
153
|
+
isInitialized(): boolean {
|
|
154
|
+
return this.initialized;
|
|
155
|
+
}
|
|
156
|
+
|
|
149
157
|
/**
|
|
150
158
|
* Function: connect
|
|
151
159
|
*
|
|
@@ -196,13 +204,13 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
196
204
|
*
|
|
197
205
|
*/
|
|
198
206
|
join(job: ActivityStream, done: PlatformCallback) {
|
|
199
|
-
this.debug(`join() called for ${job.actor.id}`);
|
|
207
|
+
this.log.debug(`join() called for ${job.actor.id}`);
|
|
200
208
|
this.getClient(job.actor.id, false, (err, client) => {
|
|
201
209
|
if (err) {
|
|
202
210
|
return done(err);
|
|
203
211
|
}
|
|
204
212
|
if (this.channels.has(job.target.name)) {
|
|
205
|
-
this.debug(`channel ${job.target.name} already joined`);
|
|
213
|
+
this.log.debug(`channel ${job.target.name} already joined`);
|
|
206
214
|
return done();
|
|
207
215
|
}
|
|
208
216
|
// join channel
|
|
@@ -210,7 +218,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
210
218
|
this.hasJoined(job.target.name);
|
|
211
219
|
done();
|
|
212
220
|
});
|
|
213
|
-
this.debug(`sending join ${job.target.name}`);
|
|
221
|
+
this.log.debug(`sending join ${job.target.name}`);
|
|
214
222
|
client.raw(["JOIN", job.target.name]);
|
|
215
223
|
client.raw(`PING ${job.actor.name}`);
|
|
216
224
|
});
|
|
@@ -243,7 +251,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
243
251
|
*
|
|
244
252
|
*/
|
|
245
253
|
leave(job: ActivityStream, done: PlatformCallback) {
|
|
246
|
-
this.debug(`leave() called for ${job.actor.name}`);
|
|
254
|
+
this.log.debug(`leave() called for ${job.actor.name}`);
|
|
247
255
|
this.getClient(job.actor.id, false, (err, client) => {
|
|
248
256
|
if (err) {
|
|
249
257
|
return done(err);
|
|
@@ -287,7 +295,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
287
295
|
*
|
|
288
296
|
*/
|
|
289
297
|
send(job: ActivityStream, done: PlatformCallback) {
|
|
290
|
-
this.debug(
|
|
298
|
+
this.log.debug(
|
|
291
299
|
`send() called for ${job.actor.id} target: ${job.target.id}`,
|
|
292
300
|
);
|
|
293
301
|
this.getClient(job.actor.id, false, async (err, client) => {
|
|
@@ -398,13 +406,13 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
398
406
|
credentials: PlatformIrcCredentialsObject,
|
|
399
407
|
done: PlatformCallback,
|
|
400
408
|
) {
|
|
401
|
-
this.debug(`update() called for ${job.actor.id}`);
|
|
409
|
+
this.log.debug(`update() called for ${job.actor.id}`);
|
|
402
410
|
this.getClient(job.actor.id, false, (err, client) => {
|
|
403
411
|
if (err) {
|
|
404
412
|
return done(err);
|
|
405
413
|
}
|
|
406
414
|
if (job.object.type === "address") {
|
|
407
|
-
this.debug(
|
|
415
|
+
this.log.debug(
|
|
408
416
|
`changing nick from ${job.actor.name} to ${job.target.name}`,
|
|
409
417
|
);
|
|
410
418
|
this.handledActors.add(job.target.id);
|
|
@@ -423,7 +431,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
423
431
|
client.raw(["NICK", job.target.name]);
|
|
424
432
|
} else if (job.object.type === "topic") {
|
|
425
433
|
// update topic
|
|
426
|
-
this.debug(`changing topic in channel ${job.target.name}`);
|
|
434
|
+
this.log.debug(`changing topic in channel ${job.target.name}`);
|
|
427
435
|
this.jobQueue.push(done);
|
|
428
436
|
client.raw(["topic", job.target.name, job.object.content]);
|
|
429
437
|
} else {
|
|
@@ -487,14 +495,16 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
487
495
|
*
|
|
488
496
|
*/
|
|
489
497
|
query(job: ActivityStream, done: PlatformCallback) {
|
|
490
|
-
this.debug(`query() called for ${job.actor.id}`);
|
|
498
|
+
this.log.debug(`query() called for ${job.actor.id}`);
|
|
491
499
|
this.getClient(job.actor.id, false, (err, client) => {
|
|
492
500
|
if (err) {
|
|
493
501
|
return done(err);
|
|
494
502
|
}
|
|
495
503
|
|
|
496
504
|
if (job.object.type === "attendance") {
|
|
497
|
-
this.debug(
|
|
505
|
+
this.log.debug(
|
|
506
|
+
`query() - sending NAMES for ${job.target.name}`,
|
|
507
|
+
);
|
|
498
508
|
client.raw(["NAMES", job.target.name]);
|
|
499
509
|
done();
|
|
500
510
|
} else {
|
|
@@ -520,13 +530,13 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
520
530
|
* }
|
|
521
531
|
*/
|
|
522
532
|
disconnect(job: ActivityStream, done: PlatformCallback) {
|
|
523
|
-
this.debug(`disconnect called for ${job.actor.id}`);
|
|
533
|
+
this.log.debug(`disconnect called for ${job.actor.id}`);
|
|
524
534
|
this.cleanup(done);
|
|
525
535
|
}
|
|
526
536
|
|
|
527
537
|
cleanup(done: PlatformCallback) {
|
|
528
|
-
this.debug("cleanup() called");
|
|
529
|
-
this.
|
|
538
|
+
this.log.debug("cleanup() called");
|
|
539
|
+
this.initialized = false;
|
|
530
540
|
this.forceDisconnect = true;
|
|
531
541
|
if (typeof this.client === "object") {
|
|
532
542
|
if (typeof this.client.end === "function") {
|
|
@@ -551,7 +561,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
551
561
|
}
|
|
552
562
|
|
|
553
563
|
private hasJoined(channel: string) {
|
|
554
|
-
this.debug(`joined ${channel}`);
|
|
564
|
+
this.log.debug(`joined ${channel}`);
|
|
555
565
|
// keep track of channels joined
|
|
556
566
|
if (!this.channels.has(channel)) {
|
|
557
567
|
this.channels.add(channel);
|
|
@@ -559,7 +569,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
559
569
|
}
|
|
560
570
|
|
|
561
571
|
private hasLeft(channel: string) {
|
|
562
|
-
this.debug(`left ${channel}`);
|
|
572
|
+
this.log.debug(`left ${channel}`);
|
|
563
573
|
// keep track of channels left
|
|
564
574
|
if (this.channels.has(channel)) {
|
|
565
575
|
this.channels.delete(channel);
|
|
@@ -571,7 +581,9 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
571
581
|
credentials: PlatformIrcCredentialsObject | false,
|
|
572
582
|
cb: GetClientCallback,
|
|
573
583
|
) {
|
|
574
|
-
this.debug(
|
|
584
|
+
this.log.debug(
|
|
585
|
+
`getClient called, connecting: ${this.clientConnecting}`,
|
|
586
|
+
);
|
|
575
587
|
if (this.client) {
|
|
576
588
|
this.handledActors.add(key);
|
|
577
589
|
return cb(null, this.client);
|
|
@@ -581,7 +593,9 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
581
593
|
// client is in the process of connecting, wait
|
|
582
594
|
setTimeout(() => {
|
|
583
595
|
if (this.client) {
|
|
584
|
-
this.debug(
|
|
596
|
+
this.log.debug(
|
|
597
|
+
`resolving delayed getClient call for ${key}`,
|
|
598
|
+
);
|
|
585
599
|
this.handledActors.add(key);
|
|
586
600
|
return cb(null, this.client);
|
|
587
601
|
}
|
|
@@ -598,13 +612,13 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
598
612
|
|
|
599
613
|
this.ircConnect(credentials, (err, client) => {
|
|
600
614
|
if (err) {
|
|
601
|
-
this.
|
|
615
|
+
this.initialized = false;
|
|
602
616
|
return cb(err);
|
|
603
617
|
}
|
|
604
618
|
this.handledActors.add(key);
|
|
605
619
|
this.client = client;
|
|
606
620
|
this.registerListeners(credentials.object.server);
|
|
607
|
-
this.
|
|
621
|
+
this.initialized = true;
|
|
608
622
|
return cb(null, client);
|
|
609
623
|
});
|
|
610
624
|
}
|
|
@@ -645,7 +659,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
645
659
|
module_options.capabilities = { requires: ["sasl"] };
|
|
646
660
|
}
|
|
647
661
|
|
|
648
|
-
this.debug(
|
|
662
|
+
this.log.debug(
|
|
649
663
|
`attempting to connect to ${module_options.server}:${module_options.port} transport: ${
|
|
650
664
|
is_secure ? "secure" : "clear"
|
|
651
665
|
} sasl: ${is_sasl}`,
|
|
@@ -669,17 +683,17 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
669
683
|
};
|
|
670
684
|
|
|
671
685
|
client.once("error", (err: string) => {
|
|
672
|
-
this.debug(`irc client 'error' occurred. `, err);
|
|
686
|
+
this.log.debug(`irc client 'error' occurred. `, err);
|
|
673
687
|
forceDisconnect("error connecting to server.");
|
|
674
688
|
});
|
|
675
689
|
|
|
676
690
|
client.once("close", () => {
|
|
677
|
-
this.debug(`irc client 'close' event fired.`);
|
|
691
|
+
this.log.debug(`irc client 'close' event fired.`);
|
|
678
692
|
forceDisconnect("connection to server closed.");
|
|
679
693
|
});
|
|
680
694
|
|
|
681
695
|
client.once("timeout", () => {
|
|
682
|
-
this.debug("timeout occurred, force-disconnect");
|
|
696
|
+
this.log.debug("timeout occurred, force-disconnect");
|
|
683
697
|
forceDisconnect("connection timeout to server.");
|
|
684
698
|
});
|
|
685
699
|
|
|
@@ -694,7 +708,7 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
694
708
|
return cb("force disconnect active, aborting connect.");
|
|
695
709
|
}
|
|
696
710
|
|
|
697
|
-
this.debug(
|
|
711
|
+
this.log.debug(
|
|
698
712
|
`connected to ${module_options.server} capabilities: `,
|
|
699
713
|
capabilities,
|
|
700
714
|
);
|
|
@@ -703,16 +717,16 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
703
717
|
}
|
|
704
718
|
|
|
705
719
|
private completeJob(err?: string) {
|
|
706
|
-
this.debug(`completing job, queue count: ${this.jobQueue.length}`);
|
|
720
|
+
this.log.debug(`completing job, queue count: ${this.jobQueue.length}`);
|
|
707
721
|
const done = this.jobQueue.shift();
|
|
708
722
|
if (typeof done === "function") {
|
|
709
723
|
done(err);
|
|
710
724
|
} else if (this.jobQueue.length === 0) {
|
|
711
|
-
this.debug(
|
|
725
|
+
this.log.debug(
|
|
712
726
|
"WARNING: job completion event received with an empty job queue.",
|
|
713
727
|
);
|
|
714
728
|
} else {
|
|
715
|
-
this.debug(
|
|
729
|
+
this.log.debug(
|
|
716
730
|
`WARNING: job completion found non-function in queue (${typeof done}), ${this.jobQueue.length} items remain.`,
|
|
717
731
|
);
|
|
718
732
|
}
|
|
@@ -732,32 +746,33 @@ export default class IRC implements PersistentPlatformInterface {
|
|
|
732
746
|
) {
|
|
733
747
|
this.completeJob();
|
|
734
748
|
} else {
|
|
735
|
-
this.debug(
|
|
736
|
-
|
|
737
|
-
|
|
749
|
+
this.log.debug(
|
|
750
|
+
`calling sendToClient for ${asObject.actor.id}`,
|
|
751
|
+
[...this.handledActors.keys()],
|
|
752
|
+
);
|
|
738
753
|
this.sendToClient(asObject);
|
|
739
754
|
}
|
|
740
755
|
});
|
|
741
756
|
|
|
742
757
|
this.irc2as.events.on("unprocessed", (s: string) => {
|
|
743
|
-
this.debug(`unprocessed irc message:> ${s}`);
|
|
758
|
+
this.log.debug(`unprocessed irc message:> ${s}`);
|
|
744
759
|
});
|
|
745
760
|
|
|
746
761
|
// The generated eslint error expects that the `error` event is propagating an Error object
|
|
747
762
|
// however for irc2as this event delivers an AS object of type `error`.
|
|
748
763
|
|
|
749
764
|
this.irc2as.events.on("error", (asObject: ActivityStream) => {
|
|
750
|
-
this.debug(`message error response ${asObject.object.content}`);
|
|
765
|
+
this.log.debug(`message error response ${asObject.object.content}`);
|
|
751
766
|
this.completeJob(asObject.object.content);
|
|
752
767
|
});
|
|
753
768
|
|
|
754
769
|
this.irc2as.events.on("pong", (timestamp: string) => {
|
|
755
|
-
this.debug(`received PONG at ${timestamp}`);
|
|
770
|
+
this.log.debug(`received PONG at ${timestamp}`);
|
|
756
771
|
this.completeJob();
|
|
757
772
|
});
|
|
758
773
|
|
|
759
774
|
this.irc2as.events.on("ping", (timestamp: string) => {
|
|
760
|
-
this.debug(`received PING at ${timestamp}`);
|
|
775
|
+
this.log.debug(`received PING at ${timestamp}`);
|
|
761
776
|
this.client.raw("PONG");
|
|
762
777
|
});
|
|
763
778
|
}
|