Skip to content

Commit 884ebfb

Browse files
committed
update
1 parent 7029482 commit 884ebfb

4 files changed

Lines changed: 94 additions & 188 deletions

File tree

subscriber.js renamed to event-bus.js

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,51 @@
1-
import { EventSource } from 'eventsource'
2-
import eventTypes from './event-types.json' with { type: 'json' }
1+
import { createConnection } from 'net'
32

4-
export default class Subscriber {
3+
export default class EventBus {
4+
#useState = null
55
#useConfig = null
6+
#lastEventState = null
7+
#client = null
68

7-
constructor(useConfig) {
9+
constructor(useState, useConfig) {
10+
this.#useState = useState
811
this.#useConfig = useConfig
9-
this.#subscribe()
12+
this.#client = createConnection(process.env.TALKOPS_SOCKET, () => {
13+
this.publishEvent({ type: 'init' })
14+
this.#publishStatePeriodically()
15+
})
16+
this.#client.on('data', (data) => {
17+
this.#onEvent(JSON.parse(data.toString()))
18+
})
1019
}
1120

12-
#subscribe() {
13-
const config = this.#useConfig()
14-
const url = `${config.mercure.url}?topic=${encodeURIComponent(config.mercure.subscriber.topic)}`
21+
#generateEventState() {
22+
return { type: 'state', state: this.#useState() }
23+
}
1524

16-
const es = new EventSource(url, {
17-
fetch: (input, init) =>
18-
fetch(input, {
19-
...init,
20-
headers: {
21-
...init.headers,
22-
Authorization: `Bearer ${config.mercure.subscriber.token}`,
23-
},
24-
}),
25-
})
25+
async #publishState() {
26+
const event = this.#generateEventState()
27+
this.#lastEventState = JSON.stringify(event)
28+
await this.publishEvent(event)
29+
}
2630

27-
es.addEventListener('message', (message) => this.#onEvent(JSON.parse(message.data)))
31+
async publishEvent(event) {
32+
this.#client.write(JSON.stringify(event))
33+
}
2834

29-
es.onerror = () => {
30-
es.close()
31-
setTimeout(() => this.#subscribe(), 1000)
35+
async #publishStatePeriodically() {
36+
while (true) {
37+
await new Promise((resolve) => setTimeout(resolve, 500))
38+
const event = this.#generateEventState()
39+
const lastEventState = JSON.stringify(event)
40+
if (this.#lastEventState !== lastEventState) {
41+
this.#lastEventState = lastEventState
42+
this.publishEvent(event)
43+
}
3244
}
3345
}
3446

3547
async #onEvent(event) {
3648
const config = this.#useConfig()
37-
if (event.type === 'ping') {
38-
config.publisher.onPing()
39-
return
40-
}
41-
if (event.type === 'function_call') {
42-
for (const fn of config.functions) {
43-
if (fn.name !== event.name) continue
44-
const match = fn.toString().match(/\(([^)]*)\)/)
45-
const argumentsList = (match ? match[1].split(',').map((p) => p.trim()) : []).map(
46-
(name) => event.args[name] ?? event.defaultArgs[name],
47-
)
48-
event.output = await Reflect.apply(fn, null, argumentsList)
49-
config.publisher.publishEvent(event)
50-
return
51-
}
52-
}
5349
if (event.type === 'boot') {
5450
for (const name of Object.keys(event.parameters)) {
5551
for (const parameter of config.parameters) {
@@ -65,10 +61,22 @@ export default class Subscriber {
6561
if (parameter.hasValue()) continue
6662
ready = false
6763
}
68-
config.publisher.publishState()
64+
this.#publishState()
6965
if (!ready) return
7066
}
71-
if (eventTypes.includes(event.type) && config.callbacks[event.type]) {
67+
if (event.type === 'function_call') {
68+
for (const fn of config.functions) {
69+
if (fn.name !== event.name) continue
70+
const match = fn.toString().match(/\(([^)]*)\)/)
71+
const argumentsList = (match ? match[1].split(',').map((p) => p.trim()) : []).map(
72+
(name) => event.args[name] ?? event.defaultArgs[name],
73+
)
74+
event.output = await Reflect.apply(fn, null, argumentsList)
75+
this.publishEvent(event)
76+
return
77+
}
78+
}
79+
if (config.callbacks[event.type]) {
7280
const match = config.callbacks[event.type].toString().match(/\(([^)]*)\)/)
7381
const argumentsList = (match ? match[1].split(',').map((p) => p.trim()) : []).map(
7482
(name) => event.args[name],

extension.js

Lines changed: 44 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1+
import EventBus from './event-bus.js'
12
import Media from './media.js'
2-
import Publisher from './publisher.js'
3-
import Subscriber from './subscriber.js'
43
import Parameter from './parameter.js'
54
import Readme from './readme.js'
65
import Manifest from './manifest.js'
@@ -17,6 +16,7 @@ export default class Extension {
1716
#callbacks = {}
1817
#category = null
1918
#demo = false
19+
#eventBus = null
2020
#features = []
2121
#functions = []
2222
#functionSchemas = []
@@ -27,81 +27,58 @@ export default class Extension {
2727
#parameters = []
2828
#softwareVersion = null
2929
#started = false
30-
#token = null
3130
#website = null
3231

33-
#publisher = null
34-
35-
/**
36-
* @param {String} token - The token of the extension.
37-
* @returns {Extension} The created extension instance.
38-
*/
39-
constructor(token) {
40-
this.#token = token || process.argv[2] || process.env.TALKOPS_TOKEN
41-
}
42-
4332
async #setup() {
44-
if (this.#token) {
45-
const mercure = JSON.parse(Buffer.from(this.#token, 'base64').toString())
46-
this.#publisher = new Publisher(
47-
() => {
48-
return {
49-
mercure,
50-
}
51-
},
52-
() => {
53-
return {
54-
category: this.#category,
55-
demo: this.#demo,
56-
icon: this.#icon,
57-
installationSteps: this.#installationSteps,
58-
instructions: this.#instructions,
59-
name: this.#name,
60-
parameters: this.#parameters,
61-
sdk: {
62-
name: 'nodejs',
63-
version: pkg.version,
64-
},
65-
softwareVersion: this.#softwareVersion,
66-
functionSchemas: this.#functionSchemas,
67-
}
68-
},
69-
)
70-
new Subscriber(() => {
71-
return {
72-
callbacks: this.#callbacks,
73-
extension: this,
74-
functions: this.#functions,
75-
mercure,
76-
parameters: this.#parameters,
77-
publisher: this.#publisher,
78-
}
79-
})
80-
}
81-
82-
if (process.env.NODE_ENV && process.env.NODE_ENV === 'development') {
83-
new Readme(() => {
84-
return {
85-
features: this.#features,
86-
name: this.#name,
87-
}
88-
})
89-
new Manifest(() => {
33+
this.#eventBus = new EventBus(
34+
() => {
9035
return {
9136
category: this.#category,
9237
demo: this.#demo,
93-
features: this.#features,
9438
icon: this.#icon,
39+
installationSteps: this.#installationSteps,
40+
instructions: this.#instructions,
9541
name: this.#name,
42+
parameters: this.#parameters,
9643
sdk: {
9744
name: 'nodejs',
9845
version: pkg.version,
9946
},
10047
softwareVersion: this.#softwareVersion,
101-
website: this.#website,
48+
functionSchemas: this.#functionSchemas,
10249
}
103-
})
104-
}
50+
},
51+
() => {
52+
return {
53+
callbacks: this.#callbacks,
54+
functions: this.#functions,
55+
parameters: this.#parameters,
56+
}
57+
},
58+
)
59+
60+
new Readme(() => {
61+
return {
62+
features: this.#features,
63+
name: this.#name,
64+
}
65+
})
66+
67+
new Manifest(() => {
68+
return {
69+
category: this.#category,
70+
demo: this.#demo,
71+
features: this.#features,
72+
icon: this.#icon,
73+
name: this.#name,
74+
sdk: {
75+
name: 'nodejs',
76+
version: pkg.version,
77+
},
78+
softwareVersion: this.#softwareVersion,
79+
website: this.#website,
80+
}
81+
})
10582
}
10683

10784
/**
@@ -298,7 +275,7 @@ export default class Extension {
298275
* Enables alarm.
299276
*/
300277
enableAlarm() {
301-
this.#publisher.publishEvent({ type: 'alarm' })
278+
this.#eventBus.publishEvent({ type: 'alarm' })
302279
}
303280

304281
/**
@@ -310,7 +287,7 @@ export default class Extension {
310287
if (!medias.every((item) => item instanceof Media)) {
311288
throw new Error('medias must be an array of Media instances.')
312289
}
313-
this.#publisher.publishEvent({
290+
this.#eventBus.publishEvent({
314291
type: 'medias',
315292
medias: medias.map((media) => media.toJSON()),
316293
})
@@ -324,7 +301,7 @@ export default class Extension {
324301
if (typeof text !== 'string' || text.trim() === '') {
325302
throw new TypeError('text must be a non-empty string.')
326303
}
327-
this.#publisher.publishEvent({ type: 'message', text })
304+
this.#eventBus.publishEvent({ type: 'message', text })
328305
}
329306

330307
/**
@@ -335,6 +312,6 @@ export default class Extension {
335312
if (typeof text !== 'string' || text.trim() === '') {
336313
throw new TypeError('text must be a non-empty string.')
337314
}
338-
this.#publisher.publishEvent({ type: 'notification', text })
315+
this.#eventBus.publishEvent({ type: 'notification', text })
339316
}
340317
}

package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
{
22
"name": "talkops",
33
"description": "TalkOps SDK",
4-
"version": "2.15.1",
4+
"version": "2.15.2",
55
"author": "PicoUX",
66
"license": "MIT",
77
"main": "index.mjs",
88
"dependencies": {
9-
"axios": "^1.8.3",
10-
"ejs": "^3.1.10",
11-
"eventsource": "^3.0.5"
9+
"ejs": "^3.1.10"
1210
},
1311
"scripts": {
1412
"doc": "documentation readme *.js -s Documentation"

publisher.js

Lines changed: 0 additions & 77 deletions
This file was deleted.

0 commit comments

Comments
 (0)