@player-tools/devtools-messenger 0.8.0-next.0 → 0.8.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.
- package/dist/cjs/index.cjs +107 -74
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.legacy-esm.js +107 -74
- package/dist/index.mjs +107 -74
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -8
- package/src/__tests__/helpers/index.ts +12 -2
- package/src/__tests__/index.test.ts +200 -52
- package/src/index.ts +134 -106
- package/types/index.d.ts +10 -5
package/dist/cjs/index.cjs
CHANGED
|
@@ -34,7 +34,12 @@ __export(src_exports, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(src_exports);
|
|
36
36
|
var import_tiny_uid = __toESM(require("tiny-uid"));
|
|
37
|
-
var
|
|
37
|
+
var internalEvents = [
|
|
38
|
+
"MESSENGER_BEACON",
|
|
39
|
+
"MESSENGER_DISCONNECT",
|
|
40
|
+
"MESSENGER_REQUEST_LOST_EVENTS",
|
|
41
|
+
"MESSENGER_EVENT_BATCH"
|
|
42
|
+
];
|
|
38
43
|
var Messenger = class _Messenger {
|
|
39
44
|
constructor(options) {
|
|
40
45
|
this.options = options;
|
|
@@ -46,14 +51,11 @@ var Messenger = class _Messenger {
|
|
|
46
51
|
);
|
|
47
52
|
this.handleMessage = this._handleMessage.bind(this);
|
|
48
53
|
this.options.addListener(this.handleMessage);
|
|
49
|
-
if (!_Messenger.contextEvents[this.options.context]) {
|
|
50
|
-
_Messenger.contextEvents[this.options.context] = [];
|
|
51
|
-
}
|
|
52
54
|
}
|
|
53
|
-
/** static record of events
|
|
54
|
-
static
|
|
55
|
-
/** connections record */
|
|
56
|
-
connections = {};
|
|
55
|
+
/** static record of events by isntance ID */
|
|
56
|
+
static events = {};
|
|
57
|
+
/** static connections record by instance ID */
|
|
58
|
+
static connections = {};
|
|
57
59
|
/** beacon interval */
|
|
58
60
|
beaconInterval = null;
|
|
59
61
|
/** time between beacons milliseconds */
|
|
@@ -69,30 +71,50 @@ var Messenger = class _Messenger {
|
|
|
69
71
|
);
|
|
70
72
|
}
|
|
71
73
|
}
|
|
74
|
+
getConnection(id) {
|
|
75
|
+
if (!_Messenger.connections[this.id]) {
|
|
76
|
+
_Messenger.connections[this.id] = {};
|
|
77
|
+
}
|
|
78
|
+
return _Messenger.connections[this.id][id];
|
|
79
|
+
}
|
|
80
|
+
addConnection(id) {
|
|
81
|
+
_Messenger.connections[this.id][id] = {
|
|
82
|
+
id,
|
|
83
|
+
messagesReceived: 0,
|
|
84
|
+
messagesSent: 0,
|
|
85
|
+
desync: false
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
getEvents() {
|
|
89
|
+
if (!_Messenger.events[this.id]) {
|
|
90
|
+
_Messenger.events[this.id] = [];
|
|
91
|
+
}
|
|
92
|
+
return _Messenger.events[this.id];
|
|
93
|
+
}
|
|
94
|
+
addEvent(event) {
|
|
95
|
+
const events = this.getEvents();
|
|
96
|
+
events.push(event);
|
|
97
|
+
}
|
|
72
98
|
/** generate a sequential id for each non-internal message */
|
|
73
|
-
getTransactionID(message
|
|
74
|
-
|
|
75
|
-
"MESSENGER_BEACON",
|
|
76
|
-
"MESSENGER_DISCONNECT",
|
|
77
|
-
"MESSENGER_REQUEST_LOST_EVENTS",
|
|
78
|
-
"MESSENGER_EVENT_BATCH"
|
|
79
|
-
];
|
|
80
|
-
if (!target || internalEvents.includes(message.type)) {
|
|
99
|
+
getTransactionID(message) {
|
|
100
|
+
if (!message.target || internalEvents.includes(message.type)) {
|
|
81
101
|
return -1;
|
|
82
102
|
}
|
|
83
|
-
if (!
|
|
84
|
-
|
|
103
|
+
if (!this.getConnection(message.target)) {
|
|
104
|
+
this.addConnection(message.target);
|
|
85
105
|
}
|
|
86
|
-
|
|
106
|
+
const connection = this.getConnection(message.target);
|
|
107
|
+
connection.messagesSent += 1;
|
|
108
|
+
return connection.messagesSent;
|
|
87
109
|
}
|
|
88
|
-
addTransactionMetadata(event
|
|
110
|
+
addTransactionMetadata(event) {
|
|
89
111
|
const metadata = {
|
|
90
112
|
_messenger_: true,
|
|
91
|
-
id: this.getTransactionID(event
|
|
113
|
+
id: this.getTransactionID(event),
|
|
92
114
|
sender: this.id,
|
|
93
115
|
timestamp: Date.now(),
|
|
94
116
|
context: this.options.context,
|
|
95
|
-
...target && { target }
|
|
117
|
+
...event.target && { target: event.target }
|
|
96
118
|
};
|
|
97
119
|
return {
|
|
98
120
|
...metadata,
|
|
@@ -114,8 +136,9 @@ var Messenger = class _Messenger {
|
|
|
114
136
|
const isFromMessenger = parsed._messenger_;
|
|
115
137
|
const isFromSelf = parsed.sender === this.id;
|
|
116
138
|
const isFromSameContext = parsed.context === this.options.context;
|
|
117
|
-
const isTargetingOthers = parsed.target
|
|
118
|
-
const
|
|
139
|
+
const isTargetingOthers = parsed.target ? parsed.target !== this.id : false;
|
|
140
|
+
const connection = this.getConnection(parsed.sender);
|
|
141
|
+
const isKnownConnection = Boolean(connection);
|
|
119
142
|
if (!isFromMessenger || isFromSelf || isFromSameContext || isTargetingOthers || isKnownConnection && parsed.type === "MESSENGER_BEACON") {
|
|
120
143
|
return;
|
|
121
144
|
}
|
|
@@ -132,29 +155,31 @@ var Messenger = class _Messenger {
|
|
|
132
155
|
if (isKnownConnection) {
|
|
133
156
|
const isBatch = parsed.type === "MESSENGER_EVENT_BATCH";
|
|
134
157
|
const transactionID = isBatch ? parsed.payload.events[0].id : parsed.id;
|
|
135
|
-
const {
|
|
136
|
-
if (transactionID <=
|
|
158
|
+
const { messagesReceived, desync } = connection;
|
|
159
|
+
if (transactionID > -1 && transactionID <= messagesReceived) {
|
|
137
160
|
return;
|
|
138
161
|
}
|
|
139
|
-
if (!desync && transactionID >
|
|
162
|
+
if (!desync && transactionID > -1 && transactionID > messagesReceived + 1) {
|
|
140
163
|
const message = {
|
|
141
164
|
type: "MESSENGER_REQUEST_LOST_EVENTS",
|
|
142
165
|
payload: {
|
|
143
|
-
|
|
144
|
-
}
|
|
166
|
+
messagesReceived
|
|
167
|
+
},
|
|
168
|
+
target: parsed.sender
|
|
145
169
|
};
|
|
146
170
|
this.options.sendMessage(this.addTransactionMetadata(message));
|
|
147
171
|
this.log(
|
|
148
172
|
`requesting lost messages from ${parsed.context}:${parsed.sender}`
|
|
149
173
|
);
|
|
150
|
-
|
|
174
|
+
connection.desync = true;
|
|
151
175
|
return;
|
|
152
176
|
}
|
|
153
177
|
if (isBatch) {
|
|
154
|
-
|
|
178
|
+
connection.desync = false;
|
|
179
|
+
connection.messagesReceived += parsed.payload.events.length;
|
|
180
|
+
} else {
|
|
181
|
+
connection.messagesReceived += 1;
|
|
155
182
|
}
|
|
156
|
-
const newLastMessageIdx = isBatch ? parsed.payload.events.slice(-1)[0].id : parsed.id;
|
|
157
|
-
this.connections[parsed.sender].lastReceivedMessageId = newLastMessageIdx;
|
|
158
183
|
}
|
|
159
184
|
this.options.messageCallback(parsed);
|
|
160
185
|
this.log(
|
|
@@ -162,67 +187,71 @@ var Messenger = class _Messenger {
|
|
|
162
187
|
);
|
|
163
188
|
}
|
|
164
189
|
handleBeaconMessage(parsed) {
|
|
165
|
-
if (
|
|
190
|
+
if (this.getConnection(parsed.sender)) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
this.addConnection(parsed.sender);
|
|
194
|
+
const events = this.getEvents();
|
|
195
|
+
if (events.length > 0) {
|
|
166
196
|
const message = {
|
|
167
197
|
type: "MESSENGER_EVENT_BATCH",
|
|
168
198
|
payload: {
|
|
169
|
-
events:
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
199
|
+
events: events.map((event) => this.addTransactionMetadata(event))
|
|
200
|
+
},
|
|
201
|
+
target: parsed.sender
|
|
173
202
|
};
|
|
174
|
-
this.options.sendMessage(
|
|
175
|
-
this.addTransactionMetadata(message, parsed.sender)
|
|
176
|
-
);
|
|
203
|
+
this.options.sendMessage(this.addTransactionMetadata(message));
|
|
177
204
|
this.log(
|
|
178
|
-
`messages [0 - ${
|
|
205
|
+
`messages [0 - ${events.length - 1}] sent to ${parsed.context}:${parsed.sender}`
|
|
179
206
|
);
|
|
207
|
+
const connection = this.getConnection(parsed.sender);
|
|
208
|
+
connection.messagesSent = events.length;
|
|
180
209
|
}
|
|
181
|
-
const newConnection = {
|
|
182
|
-
id: parsed.sender,
|
|
183
|
-
lastSentMessageId: _Messenger.contextEvents[this.options.context].length - 1,
|
|
184
|
-
lastReceivedMessageId: -1,
|
|
185
|
-
desync: false
|
|
186
|
-
};
|
|
187
|
-
this.connections[parsed.sender] = newConnection;
|
|
188
210
|
this.log(`new connection added - ${parsed.context}:${parsed.sender}`);
|
|
189
211
|
}
|
|
190
212
|
handleLostEventsRequest(parsed) {
|
|
191
|
-
const
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
213
|
+
const connection = this.getConnection(parsed.sender);
|
|
214
|
+
const events = this.getEvents();
|
|
215
|
+
if (!connection || events.length === 0) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const missingEvents = events.slice(connection.messagesSent, events.length);
|
|
219
|
+
if (missingEvents.length === 0) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
196
222
|
const message = {
|
|
197
223
|
type: "MESSENGER_EVENT_BATCH",
|
|
198
224
|
payload: {
|
|
199
225
|
events: missingEvents.map(
|
|
200
|
-
(event) => this.addTransactionMetadata(event
|
|
226
|
+
(event) => this.addTransactionMetadata(event)
|
|
201
227
|
)
|
|
202
|
-
}
|
|
228
|
+
},
|
|
229
|
+
target: parsed.sender
|
|
203
230
|
};
|
|
204
231
|
this.options.sendMessage(this.addTransactionMetadata(message));
|
|
232
|
+
connection.messagesSent = events.length;
|
|
205
233
|
this.log(
|
|
206
|
-
`messages [0 - ${
|
|
234
|
+
`messages [0 - ${events.length - 1}] sent to ${parsed.context}:${parsed.sender}`
|
|
207
235
|
);
|
|
208
236
|
}
|
|
209
237
|
handleDisconnectMessage(parsed) {
|
|
210
|
-
delete
|
|
238
|
+
delete _Messenger.connections[parsed.sender];
|
|
211
239
|
this.log(`disconnected - ${parsed.context}:${parsed.sender}`);
|
|
212
240
|
}
|
|
213
241
|
sendMessage(message) {
|
|
214
242
|
const parsed = typeof message === "string" ? JSON.parse(message) : message;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
243
|
+
this.addEvent(parsed);
|
|
244
|
+
const target = parsed.target || null;
|
|
245
|
+
const msg = this.addTransactionMetadata(parsed);
|
|
246
|
+
const connection = target ? this.getConnection(target) : null;
|
|
247
|
+
if (connection) {
|
|
248
|
+
connection.messagesSent += 1;
|
|
249
|
+
}
|
|
250
|
+
this.options.sendMessage(msg).catch(() => {
|
|
251
|
+
this.options.handleFailedMessage?.(msg);
|
|
252
|
+
this.log(
|
|
253
|
+
`failed to send message: ${parsed.type} from ${this.id} to ${target || "all"}`
|
|
254
|
+
);
|
|
226
255
|
});
|
|
227
256
|
}
|
|
228
257
|
destroy() {
|
|
@@ -230,18 +259,22 @@ var Messenger = class _Messenger {
|
|
|
230
259
|
clearInterval(this.beaconInterval);
|
|
231
260
|
}
|
|
232
261
|
this.options.removeListener(this.handleMessage);
|
|
233
|
-
Object.keys(
|
|
262
|
+
Object.keys(_Messenger.connections).forEach((connection) => {
|
|
234
263
|
const event = {
|
|
235
264
|
type: "MESSENGER_DISCONNECT",
|
|
236
|
-
payload: null
|
|
265
|
+
payload: null,
|
|
266
|
+
target: connection
|
|
237
267
|
};
|
|
238
|
-
const message = this.addTransactionMetadata(event
|
|
268
|
+
const message = this.addTransactionMetadata(event);
|
|
239
269
|
this.options.sendMessage(message);
|
|
240
270
|
});
|
|
271
|
+
_Messenger.reset();
|
|
241
272
|
this.log("destroyed");
|
|
242
273
|
}
|
|
243
|
-
static
|
|
244
|
-
|
|
274
|
+
/** reset static records */
|
|
275
|
+
static reset() {
|
|
276
|
+
_Messenger.events = {};
|
|
277
|
+
_Messenger.connections = {};
|
|
245
278
|
}
|
|
246
279
|
};
|
|
247
280
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/messenger/src/index.ts"],"sourcesContent":["import uid from \"tiny-uid\";\nimport type {\n BaseEvent,\n Connection,\n DisconnectEvent,\n EventsBatchEvent,\n InternalEvent,\n MessengerEvent,\n MessengerOptions,\n RequestLostEventsEvent,\n Transaction,\n TransactionMetadata,\n} from \"@player-tools/devtools-types\";\n\nconst counters: Record<string, number> = {};\n\n/**\n * Messenger<EventsType>\n *\n * Self-sufficient, lossless communication between instances.\n *\n * @param options\n * @param options.context - context to use for this instance\n * @param options.id - unique id for this instance, will be generated if not provided\n * @param options.beaconIntervalMS - time to wait between beacons in milliseconds, defaults to 1000\n * @param options.debug - if true, will log debug messages to console, defaults to false\n * @param options.messageCallback - callback to handle messages\n * @param options.sendMessage - function to send messages\n * @param options.addListener - function to add a listener\n * @param options.removeListener - function to remove a listener\n * @param options.handleFailedMessage - function to handle failed messages\n * @param option.log - function to handle logging\n * @returns Messenger\n * @example\n * ```typescript\n * const messenger = new Messenger({{\n * context: \"devtools\",\n * target: \"player\",\n * messageCallback: (message) => dispatch(message),\n * sendMessage: (message) =>\n * browser.tabs\n * ? browser.tabs\n * .query({ active: true, currentWindow: true })\n * .then((tabs) => {\n * if (tabs[0].id) {\n * browser.tabs.sendMessage(tabs[0].id, message);\n * }\n * })\n * : browser.runtime.sendMessage(message),\n * addListener: (callback) => {\n * browser.runtime.onMessage.addListener(callback);\n * },\n * removeListener: (callback) => {\n * browser.runtime.onMessage.removeListener(callback);\n * },\n * });\n * ```\n */\nexport class Messenger<T extends BaseEvent<string, unknown>> {\n /** static record of events per context */\n private static contextEvents: Record<\n string,\n Array<BaseEvent<string, unknown>>\n > = {};\n\n /** connections record */\n private connections: Record<string, Connection> = {};\n\n /** beacon interval */\n private beaconInterval: NodeJS.Timeout | null = null;\n\n /** time between beacons milliseconds */\n private beaconIntervalMS: number;\n\n /** callback to handle messages, here for instance binding */\n private handleMessage: (\n message: TransactionMetadata & MessengerEvent<T>\n ) => void;\n\n /** unique id */\n private id: string;\n\n constructor(private options: MessengerOptions<T>) {\n // set defaults:\n this.id = options.id || uid();\n this.beaconIntervalMS = options.beaconIntervalMS || 1000;\n\n // start beacon interval:\n this.beaconInterval = setInterval(\n this.beacon.bind(this),\n this.beaconIntervalMS\n );\n\n // bind message handler:\n this.handleMessage = this._handleMessage.bind(this);\n\n // add listener:\n this.options.addListener(this.handleMessage);\n\n // if events for this context don't exist, create an empty array\n if (!(Messenger.contextEvents[this.options.context] as T[])) {\n (Messenger.contextEvents[this.options.context] as T[]) = [];\n }\n }\n\n private log(message: string) {\n if (this.options.debug) {\n this.options.logger.log(\n `[MESSENGER-${this.id}](${this.options.context}): ${message}`\n );\n }\n }\n\n /** generate a sequential id for each non-internal message */\n private getTransactionID(message: MessengerEvent<T>, target?: string) {\n const internalEvents: Array<InternalEvent<T>[\"type\"]> = [\n \"MESSENGER_BEACON\",\n \"MESSENGER_DISCONNECT\",\n \"MESSENGER_REQUEST_LOST_EVENTS\",\n \"MESSENGER_EVENT_BATCH\",\n ];\n\n if (\n !target ||\n internalEvents.includes(message.type as InternalEvent<T>[\"type\"])\n ) {\n return -1;\n }\n\n if (!counters[target]) {\n counters[target] = 0;\n }\n\n return counters[target]++;\n }\n\n private addTransactionMetadata(\n event: MessengerEvent<T>,\n target?: string\n ): Transaction<T> {\n const metadata = {\n _messenger_: true,\n id: this.getTransactionID(event, target),\n sender: this.id,\n timestamp: Date.now(),\n context: this.options.context,\n ...(target && { target }),\n };\n\n return {\n ...metadata,\n ...event,\n };\n }\n\n /** there is no persistent layer bookkeeping connections,\n * so beacon to inform others of its presence */\n private beacon() {\n this.options.sendMessage(\n this.addTransactionMetadata({\n type: \"MESSENGER_BEACON\",\n payload: null,\n })\n );\n }\n\n private _handleMessage(transaction: Transaction<T>) {\n const parsed: Transaction<T> =\n typeof transaction === \"string\" ? JSON.parse(transaction) : transaction;\n\n const isFromMessenger = parsed._messenger_;\n const isFromSelf = parsed.sender === this.id;\n const isFromSameContext = parsed.context === this.options.context;\n const isTargetingOthers = parsed.target && parsed.target !== this.id;\n const isKnownConnection = this.connections[parsed.sender];\n\n if (\n !isFromMessenger ||\n isFromSelf ||\n isFromSameContext ||\n isTargetingOthers ||\n (isKnownConnection && parsed.type === \"MESSENGER_BEACON\")\n ) {\n return;\n }\n\n const handlers: Record<string, (parsed: Transaction<T>) => void> = {\n MESSENGER_BEACON: this.handleBeaconMessage.bind(this),\n MESSENGER_DISCONNECT: this.handleDisconnectMessage.bind(this),\n MESSENGER_REQUEST_LOST_EVENTS: this.handleLostEventsRequest.bind(this),\n };\n\n const handler = handlers[(parsed as BaseEvent<string, unknown>).type];\n\n if (handler) {\n handler(parsed);\n return;\n }\n\n if (isKnownConnection) {\n const isBatch = parsed.type === \"MESSENGER_EVENT_BATCH\";\n\n // if batch, get the first message id, so we can check for missing messages:\n const transactionID = isBatch\n ? (parsed.payload as EventsBatchEvent<T>[\"payload\"]).events[0].id\n : parsed.id;\n\n const { lastReceivedMessageId, desync } = this.connections[parsed.sender];\n\n // if we already received this message, ignore:\n if (transactionID <= lastReceivedMessageId) {\n return;\n }\n\n // if we missed messages, request them, unless we already did:\n if (!desync && transactionID > lastReceivedMessageId + 1) {\n const message: RequestLostEventsEvent = {\n type: \"MESSENGER_REQUEST_LOST_EVENTS\",\n payload: {\n lastReceivedMessageId,\n },\n };\n\n this.options.sendMessage(this.addTransactionMetadata(message));\n\n this.log(\n `requesting lost messages from ${parsed.context}:${parsed.sender}`\n );\n\n // set desync, so we don't request again:\n this.connections[parsed.sender].desync = true;\n\n // don't process this message, since we requested missing ones:\n return;\n }\n\n if (isBatch) {\n // clear desync flag on event batch:\n this.connections[parsed.sender].desync = false;\n }\n\n // if batch, get the last message id:\n const newLastMessageIdx = isBatch\n ? (parsed.payload as EventsBatchEvent<T>[\"payload\"]).events.slice(-1)[0]\n .id\n : parsed.id;\n\n // update last received message id:\n this.connections[parsed.sender].lastReceivedMessageId = newLastMessageIdx;\n }\n\n this.options.messageCallback(parsed);\n\n this.log(\n `message received: ${(parsed as BaseEvent<string, unknown>).type}`\n );\n }\n\n private handleBeaconMessage(parsed: Transaction<T>) {\n // if we reach here, we assume a new connection and send all events:\n if ((Messenger.contextEvents[this.options.context] as T[]).length > 0) {\n const message: EventsBatchEvent<T> = {\n type: \"MESSENGER_EVENT_BATCH\",\n payload: {\n events: (Messenger.contextEvents[this.options.context] as T[]).map(\n (event) => this.addTransactionMetadata(event, parsed.sender)\n ),\n },\n };\n\n this.options.sendMessage(\n this.addTransactionMetadata(message, parsed.sender)\n );\n\n this.log(\n `messages [0 - ${\n (Messenger.contextEvents[this.options.context] as T[]).length - 1\n }] sent to ${parsed.context}:${parsed.sender}`\n );\n }\n\n const newConnection: Connection = {\n id: parsed.sender,\n lastSentMessageId:\n (Messenger.contextEvents[this.options.context] as T[]).length - 1,\n lastReceivedMessageId: -1,\n desync: false,\n };\n\n this.connections[parsed.sender] = newConnection;\n\n this.log(`new connection added - ${parsed.context}:${parsed.sender}`);\n }\n\n private handleLostEventsRequest(parsed: Transaction<T>) {\n const lastMessageIdx = (parsed.payload as RequestLostEventsEvent[\"payload\"])\n .lastReceivedMessageId;\n\n const missingEvents = (\n Messenger.contextEvents[this.options.context] as T[]\n ).slice(\n lastMessageIdx + 1,\n (Messenger.contextEvents[this.options.context] as T[]).length\n );\n\n const message: EventsBatchEvent<T> = {\n type: \"MESSENGER_EVENT_BATCH\",\n payload: {\n events: missingEvents.map((event) =>\n this.addTransactionMetadata(event, parsed.sender)\n ),\n },\n };\n\n this.options.sendMessage(this.addTransactionMetadata(message));\n\n this.log(\n `messages [0 - ${\n (Messenger.contextEvents[this.options.context] as T[]).length - 1\n }] sent to ${parsed.context}:${parsed.sender}`\n );\n }\n\n private handleDisconnectMessage(\n parsed: TransactionMetadata & MessengerEvent<T>\n ) {\n delete this.connections[parsed.sender];\n\n this.log(`disconnected - ${parsed.context}:${parsed.sender}`);\n }\n\n public sendMessage(message: T | string) {\n const parsed: T =\n typeof message === \"string\" ? JSON.parse(message) : message;\n\n (Messenger.contextEvents[this.options.context] as T[]).push(parsed);\n\n // send to all connections:\n Object.values(this.connections).forEach(({ id }) => {\n const msg = this.addTransactionMetadata(parsed, id);\n\n this.options\n .sendMessage(msg)\n .then(() => {\n this.connections[id].lastSentMessageId = msg.id;\n })\n .catch(() => {\n this.options.handleFailedMessage?.(msg);\n\n this.log(\n `message failed: ${msg.context}:${id} - index: ${\n (Messenger.contextEvents[this.options.context] as T[]).length\n }`\n );\n });\n });\n }\n\n public destroy() {\n if (this.beaconInterval) {\n clearInterval(this.beaconInterval);\n }\n\n this.options.removeListener(this.handleMessage);\n\n Object.keys(this.connections).forEach((connection) => {\n const event: DisconnectEvent = {\n type: \"MESSENGER_DISCONNECT\",\n payload: null,\n };\n const message = this.addTransactionMetadata(event, connection);\n this.options.sendMessage(message);\n });\n\n this.log(\"destroyed\");\n }\n\n static resetEvents() {\n Messenger.contextEvents = {};\n }\n}\n"],"mappings":"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","names":["uid"]}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/messenger/src/index.ts"],"sourcesContent":["import uid from \"tiny-uid\";\nimport type {\n BaseEvent,\n Connection,\n DisconnectEvent,\n EventsBatchEvent,\n InternalEvent,\n MessengerEvent,\n MessengerOptions,\n RequestLostEventsEvent,\n Transaction,\n TransactionMetadata,\n} from \"@player-tools/devtools-types\";\n\nconst internalEvents: Array<InternalEvent<BaseEvent<string, unknown>>[\"type\"]> =\n [\n \"MESSENGER_BEACON\",\n \"MESSENGER_DISCONNECT\",\n \"MESSENGER_REQUEST_LOST_EVENTS\",\n \"MESSENGER_EVENT_BATCH\",\n ];\n\n/**\n * Messenger<EventsType>\n *\n * Self-sufficient, lossless communication between instances.\n *\n * @param options\n * @param options.context - context to use for this instance\n * @param options.id - unique id for this instance, will be generated if not provided\n * @param options.beaconIntervalMS - time to wait between beacons in milliseconds, defaults to 1000\n * @param options.debug - if true, will log debug messages to console, defaults to false\n * @param options.messageCallback - callback to handle messages\n * @param options.sendMessage - function to send messages\n * @param options.addListener - function to add a listener\n * @param options.removeListener - function to remove a listener\n * @param options.handleFailedMessage - function to handle failed messages\n * @param option.log - function to handle logging\n * @returns Messenger\n * @example\n * ```typescript\n * const messenger = new Messenger({{\n * context: \"devtools\",\n * target: \"player\",\n * messageCallback: (message) => dispatch(message),\n * sendMessage: (message) =>\n * browser.tabs\n * ? browser.tabs\n * .query({ active: true, currentWindow: true })\n * .then((tabs) => {\n * if (tabs[0].id) {\n * browser.tabs.sendMessage(tabs[0].id, message);\n * }\n * })\n * : browser.runtime.sendMessage(message),\n * addListener: (callback) => {\n * browser.runtime.onMessage.addListener(callback);\n * },\n * removeListener: (callback) => {\n * browser.runtime.onMessage.removeListener(callback);\n * },\n * });\n * ```\n */\nexport class Messenger<T extends BaseEvent<string, unknown>> {\n /** static record of events by isntance ID */\n private static events: Record<\n string,\n Array<MessageEvent<BaseEvent<string, unknown>>>\n > = {};\n\n /** static connections record by instance ID */\n private static connections: Record<string, Record<string, Connection>> = {};\n\n /** beacon interval */\n private beaconInterval: NodeJS.Timeout | null = null;\n\n /** time between beacons milliseconds */\n private beaconIntervalMS: number;\n\n /** callback to handle messages, here for instance binding */\n private handleMessage: (\n message: TransactionMetadata & MessengerEvent<T>\n ) => void;\n\n /** unique id */\n private id: string;\n\n constructor(private options: MessengerOptions<T>) {\n // set defaults:\n this.id = options.id || uid();\n this.beaconIntervalMS = options.beaconIntervalMS || 1000;\n\n // start beacon interval:\n this.beaconInterval = setInterval(\n this.beacon.bind(this),\n this.beaconIntervalMS\n );\n\n // bind message handler:\n this.handleMessage = this._handleMessage.bind(this);\n\n // add listener:\n this.options.addListener(this.handleMessage);\n }\n\n private log(message: string) {\n if (this.options.debug) {\n this.options.logger.log(\n `[MESSENGER-${this.id}](${this.options.context}): ${message}`\n );\n }\n }\n\n private getConnection(id: string) {\n if (!Messenger.connections[this.id]) {\n Messenger.connections[this.id] = {};\n }\n\n return Messenger.connections[this.id][id];\n }\n\n private addConnection(id: string) {\n Messenger.connections[this.id][id] = {\n id,\n messagesReceived: 0,\n messagesSent: 0,\n desync: false,\n };\n }\n\n private getEvents() {\n if (!Messenger.events[this.id]) {\n Messenger.events[this.id] = [];\n }\n\n return Messenger.events[this.id] as unknown as MessengerEvent<T>[];\n }\n\n private addEvent(event: MessengerEvent<T>) {\n const events = this.getEvents();\n events.push(event);\n }\n\n /** generate a sequential id for each non-internal message */\n private getTransactionID(message: MessengerEvent<T>) {\n if (\n !message.target ||\n internalEvents.includes(message.type as InternalEvent<T>[\"type\"])\n ) {\n return -1;\n }\n\n if (!this.getConnection(message.target)) {\n this.addConnection(message.target);\n }\n\n const connection = this.getConnection(message.target);\n connection.messagesSent += 1;\n return connection.messagesSent;\n }\n\n private addTransactionMetadata(event: MessengerEvent<T>): Transaction<T> {\n const metadata = {\n _messenger_: true,\n id: this.getTransactionID(event),\n sender: this.id,\n timestamp: Date.now(),\n context: this.options.context,\n ...(event.target && { target: event.target }),\n };\n\n return {\n ...metadata,\n ...event,\n };\n }\n\n /** there is no persistent layer bookkeeping connections,\n * so beacon to inform others of its presence */\n private beacon() {\n this.options.sendMessage(\n this.addTransactionMetadata({\n type: \"MESSENGER_BEACON\",\n payload: null,\n })\n );\n }\n\n private _handleMessage(transaction: Transaction<T>) {\n const parsed: Transaction<T> =\n typeof transaction === \"string\" ? JSON.parse(transaction) : transaction;\n\n const isFromMessenger = parsed._messenger_;\n const isFromSelf = parsed.sender === this.id;\n const isFromSameContext = parsed.context === this.options.context;\n const isTargetingOthers = parsed.target ? parsed.target !== this.id : false;\n const connection = this.getConnection(parsed.sender);\n const isKnownConnection = Boolean(connection);\n\n if (\n !isFromMessenger ||\n isFromSelf ||\n isFromSameContext ||\n isTargetingOthers ||\n (isKnownConnection && parsed.type === \"MESSENGER_BEACON\")\n ) {\n return;\n }\n\n const handlers: Record<string, (parsed: Transaction<T>) => void> = {\n MESSENGER_BEACON: this.handleBeaconMessage.bind(this),\n MESSENGER_DISCONNECT: this.handleDisconnectMessage.bind(this),\n MESSENGER_REQUEST_LOST_EVENTS: this.handleLostEventsRequest.bind(this),\n };\n\n const handler = handlers[(parsed as BaseEvent<string, unknown>).type];\n\n if (handler) {\n handler(parsed);\n return;\n }\n\n if (isKnownConnection) {\n const isBatch = parsed.type === \"MESSENGER_EVENT_BATCH\";\n\n const transactionID = isBatch\n ? (parsed.payload as EventsBatchEvent<T>[\"payload\"]).events[0].id\n : parsed.id;\n\n const { messagesReceived, desync } = connection;\n\n // if we already received this message, ignore:\n if (transactionID > -1 && transactionID <= messagesReceived) {\n return;\n }\n\n // if we missed messages, request them, unless we already did:\n if (\n !desync &&\n transactionID > -1 &&\n transactionID > messagesReceived + 1\n ) {\n const message: RequestLostEventsEvent = {\n type: \"MESSENGER_REQUEST_LOST_EVENTS\",\n payload: {\n messagesReceived,\n },\n target: parsed.sender,\n };\n\n this.options.sendMessage(this.addTransactionMetadata(message));\n\n this.log(\n `requesting lost messages from ${parsed.context}:${parsed.sender}`\n );\n\n // set desync, so we don't request again:\n connection.desync = true;\n\n // don't process this message, since we requested missing ones:\n return;\n }\n\n if (isBatch) {\n // clear desync flag on event batch:\n connection.desync = false;\n connection.messagesReceived += (\n parsed.payload as EventsBatchEvent<T>[\"payload\"]\n ).events.length;\n } else {\n connection.messagesReceived += 1;\n }\n }\n\n this.options.messageCallback(parsed);\n\n this.log(\n `message received: ${(parsed as BaseEvent<string, unknown>).type}`\n );\n }\n\n private handleBeaconMessage(parsed: Transaction<T>) {\n if (this.getConnection(parsed.sender)) {\n return;\n }\n\n this.addConnection(parsed.sender);\n const events = this.getEvents();\n\n if (events.length > 0) {\n const message: EventsBatchEvent<T> = {\n type: \"MESSENGER_EVENT_BATCH\",\n payload: {\n events: events.map((event) => this.addTransactionMetadata(event)),\n },\n target: parsed.sender,\n };\n\n this.options.sendMessage(this.addTransactionMetadata(message));\n\n this.log(\n `messages [0 - ${events.length - 1}] sent to ${parsed.context}:${\n parsed.sender\n }`\n );\n\n const connection = this.getConnection(parsed.sender);\n connection.messagesSent = events.length;\n }\n\n this.log(`new connection added - ${parsed.context}:${parsed.sender}`);\n }\n\n private handleLostEventsRequest(parsed: Transaction<T>) {\n const connection = this.getConnection(parsed.sender);\n const events = this.getEvents();\n\n if (!connection || events.length === 0) {\n return;\n }\n\n const missingEvents = events.slice(connection.messagesSent, events.length);\n\n if (missingEvents.length === 0) {\n return;\n }\n\n const message: EventsBatchEvent<T> = {\n type: \"MESSENGER_EVENT_BATCH\",\n payload: {\n events: missingEvents.map((event) =>\n this.addTransactionMetadata(event)\n ),\n },\n target: parsed.sender,\n };\n\n this.options.sendMessage(this.addTransactionMetadata(message));\n\n connection.messagesSent = events.length;\n\n this.log(\n `messages [0 - ${events.length - 1}] sent to ${parsed.context}:${\n parsed.sender\n }`\n );\n }\n\n private handleDisconnectMessage(\n parsed: TransactionMetadata & MessengerEvent<T>\n ) {\n delete Messenger.connections[parsed.sender];\n\n this.log(`disconnected - ${parsed.context}:${parsed.sender}`);\n }\n\n public sendMessage(message: T | string) {\n const parsed: T =\n typeof message === \"string\" ? JSON.parse(message) : message;\n\n this.addEvent(parsed);\n\n const target = parsed.target || null;\n const msg = this.addTransactionMetadata(parsed);\n const connection = target ? this.getConnection(target) : null;\n\n if (connection) {\n connection.messagesSent += 1;\n }\n\n this.options.sendMessage(msg).catch(() => {\n this.options.handleFailedMessage?.(msg);\n\n this.log(\n `failed to send message: ${\n (parsed as BaseEvent<string, unknown>).type\n } from ${this.id} to ${target || \"all\"}`\n );\n });\n }\n\n public destroy() {\n if (this.beaconInterval) {\n clearInterval(this.beaconInterval);\n }\n\n this.options.removeListener(this.handleMessage);\n\n Object.keys(Messenger.connections).forEach((connection) => {\n const event: DisconnectEvent = {\n type: \"MESSENGER_DISCONNECT\",\n payload: null,\n target: connection,\n };\n const message = this.addTransactionMetadata(event);\n this.options.sendMessage(message);\n });\n\n Messenger.reset();\n this.log(\"destroyed\");\n }\n\n /** reset static records */\n static reset() {\n Messenger.events = {};\n Messenger.connections = {};\n }\n}\n"],"mappings":"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","names":["uid"]}
|
package/dist/index.legacy-esm.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// ../../../../../../../../../../execroot/_main/bazel-out/k8-fastbuild/bin/devtools/messenger/src/index.ts
|
|
2
2
|
import uid from "tiny-uid";
|
|
3
|
-
var
|
|
3
|
+
var internalEvents = [
|
|
4
|
+
"MESSENGER_BEACON",
|
|
5
|
+
"MESSENGER_DISCONNECT",
|
|
6
|
+
"MESSENGER_REQUEST_LOST_EVENTS",
|
|
7
|
+
"MESSENGER_EVENT_BATCH"
|
|
8
|
+
];
|
|
4
9
|
var Messenger = class _Messenger {
|
|
5
10
|
constructor(options) {
|
|
6
11
|
this.options = options;
|
|
@@ -12,14 +17,11 @@ var Messenger = class _Messenger {
|
|
|
12
17
|
);
|
|
13
18
|
this.handleMessage = this._handleMessage.bind(this);
|
|
14
19
|
this.options.addListener(this.handleMessage);
|
|
15
|
-
if (!_Messenger.contextEvents[this.options.context]) {
|
|
16
|
-
_Messenger.contextEvents[this.options.context] = [];
|
|
17
|
-
}
|
|
18
20
|
}
|
|
19
|
-
/** static record of events
|
|
20
|
-
static
|
|
21
|
-
/** connections record */
|
|
22
|
-
connections = {};
|
|
21
|
+
/** static record of events by isntance ID */
|
|
22
|
+
static events = {};
|
|
23
|
+
/** static connections record by instance ID */
|
|
24
|
+
static connections = {};
|
|
23
25
|
/** beacon interval */
|
|
24
26
|
beaconInterval = null;
|
|
25
27
|
/** time between beacons milliseconds */
|
|
@@ -35,30 +37,50 @@ var Messenger = class _Messenger {
|
|
|
35
37
|
);
|
|
36
38
|
}
|
|
37
39
|
}
|
|
40
|
+
getConnection(id) {
|
|
41
|
+
if (!_Messenger.connections[this.id]) {
|
|
42
|
+
_Messenger.connections[this.id] = {};
|
|
43
|
+
}
|
|
44
|
+
return _Messenger.connections[this.id][id];
|
|
45
|
+
}
|
|
46
|
+
addConnection(id) {
|
|
47
|
+
_Messenger.connections[this.id][id] = {
|
|
48
|
+
id,
|
|
49
|
+
messagesReceived: 0,
|
|
50
|
+
messagesSent: 0,
|
|
51
|
+
desync: false
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
getEvents() {
|
|
55
|
+
if (!_Messenger.events[this.id]) {
|
|
56
|
+
_Messenger.events[this.id] = [];
|
|
57
|
+
}
|
|
58
|
+
return _Messenger.events[this.id];
|
|
59
|
+
}
|
|
60
|
+
addEvent(event) {
|
|
61
|
+
const events = this.getEvents();
|
|
62
|
+
events.push(event);
|
|
63
|
+
}
|
|
38
64
|
/** generate a sequential id for each non-internal message */
|
|
39
|
-
getTransactionID(message
|
|
40
|
-
|
|
41
|
-
"MESSENGER_BEACON",
|
|
42
|
-
"MESSENGER_DISCONNECT",
|
|
43
|
-
"MESSENGER_REQUEST_LOST_EVENTS",
|
|
44
|
-
"MESSENGER_EVENT_BATCH"
|
|
45
|
-
];
|
|
46
|
-
if (!target || internalEvents.includes(message.type)) {
|
|
65
|
+
getTransactionID(message) {
|
|
66
|
+
if (!message.target || internalEvents.includes(message.type)) {
|
|
47
67
|
return -1;
|
|
48
68
|
}
|
|
49
|
-
if (!
|
|
50
|
-
|
|
69
|
+
if (!this.getConnection(message.target)) {
|
|
70
|
+
this.addConnection(message.target);
|
|
51
71
|
}
|
|
52
|
-
|
|
72
|
+
const connection = this.getConnection(message.target);
|
|
73
|
+
connection.messagesSent += 1;
|
|
74
|
+
return connection.messagesSent;
|
|
53
75
|
}
|
|
54
|
-
addTransactionMetadata(event
|
|
76
|
+
addTransactionMetadata(event) {
|
|
55
77
|
const metadata = {
|
|
56
78
|
_messenger_: true,
|
|
57
|
-
id: this.getTransactionID(event
|
|
79
|
+
id: this.getTransactionID(event),
|
|
58
80
|
sender: this.id,
|
|
59
81
|
timestamp: Date.now(),
|
|
60
82
|
context: this.options.context,
|
|
61
|
-
...target && { target }
|
|
83
|
+
...event.target && { target: event.target }
|
|
62
84
|
};
|
|
63
85
|
return {
|
|
64
86
|
...metadata,
|
|
@@ -80,8 +102,9 @@ var Messenger = class _Messenger {
|
|
|
80
102
|
const isFromMessenger = parsed._messenger_;
|
|
81
103
|
const isFromSelf = parsed.sender === this.id;
|
|
82
104
|
const isFromSameContext = parsed.context === this.options.context;
|
|
83
|
-
const isTargetingOthers = parsed.target
|
|
84
|
-
const
|
|
105
|
+
const isTargetingOthers = parsed.target ? parsed.target !== this.id : false;
|
|
106
|
+
const connection = this.getConnection(parsed.sender);
|
|
107
|
+
const isKnownConnection = Boolean(connection);
|
|
85
108
|
if (!isFromMessenger || isFromSelf || isFromSameContext || isTargetingOthers || isKnownConnection && parsed.type === "MESSENGER_BEACON") {
|
|
86
109
|
return;
|
|
87
110
|
}
|
|
@@ -98,29 +121,31 @@ var Messenger = class _Messenger {
|
|
|
98
121
|
if (isKnownConnection) {
|
|
99
122
|
const isBatch = parsed.type === "MESSENGER_EVENT_BATCH";
|
|
100
123
|
const transactionID = isBatch ? parsed.payload.events[0].id : parsed.id;
|
|
101
|
-
const {
|
|
102
|
-
if (transactionID <=
|
|
124
|
+
const { messagesReceived, desync } = connection;
|
|
125
|
+
if (transactionID > -1 && transactionID <= messagesReceived) {
|
|
103
126
|
return;
|
|
104
127
|
}
|
|
105
|
-
if (!desync && transactionID >
|
|
128
|
+
if (!desync && transactionID > -1 && transactionID > messagesReceived + 1) {
|
|
106
129
|
const message = {
|
|
107
130
|
type: "MESSENGER_REQUEST_LOST_EVENTS",
|
|
108
131
|
payload: {
|
|
109
|
-
|
|
110
|
-
}
|
|
132
|
+
messagesReceived
|
|
133
|
+
},
|
|
134
|
+
target: parsed.sender
|
|
111
135
|
};
|
|
112
136
|
this.options.sendMessage(this.addTransactionMetadata(message));
|
|
113
137
|
this.log(
|
|
114
138
|
`requesting lost messages from ${parsed.context}:${parsed.sender}`
|
|
115
139
|
);
|
|
116
|
-
|
|
140
|
+
connection.desync = true;
|
|
117
141
|
return;
|
|
118
142
|
}
|
|
119
143
|
if (isBatch) {
|
|
120
|
-
|
|
144
|
+
connection.desync = false;
|
|
145
|
+
connection.messagesReceived += parsed.payload.events.length;
|
|
146
|
+
} else {
|
|
147
|
+
connection.messagesReceived += 1;
|
|
121
148
|
}
|
|
122
|
-
const newLastMessageIdx = isBatch ? parsed.payload.events.slice(-1)[0].id : parsed.id;
|
|
123
|
-
this.connections[parsed.sender].lastReceivedMessageId = newLastMessageIdx;
|
|
124
149
|
}
|
|
125
150
|
this.options.messageCallback(parsed);
|
|
126
151
|
this.log(
|
|
@@ -128,67 +153,71 @@ var Messenger = class _Messenger {
|
|
|
128
153
|
);
|
|
129
154
|
}
|
|
130
155
|
handleBeaconMessage(parsed) {
|
|
131
|
-
if (
|
|
156
|
+
if (this.getConnection(parsed.sender)) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
this.addConnection(parsed.sender);
|
|
160
|
+
const events = this.getEvents();
|
|
161
|
+
if (events.length > 0) {
|
|
132
162
|
const message = {
|
|
133
163
|
type: "MESSENGER_EVENT_BATCH",
|
|
134
164
|
payload: {
|
|
135
|
-
events:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
165
|
+
events: events.map((event) => this.addTransactionMetadata(event))
|
|
166
|
+
},
|
|
167
|
+
target: parsed.sender
|
|
139
168
|
};
|
|
140
|
-
this.options.sendMessage(
|
|
141
|
-
this.addTransactionMetadata(message, parsed.sender)
|
|
142
|
-
);
|
|
169
|
+
this.options.sendMessage(this.addTransactionMetadata(message));
|
|
143
170
|
this.log(
|
|
144
|
-
`messages [0 - ${
|
|
171
|
+
`messages [0 - ${events.length - 1}] sent to ${parsed.context}:${parsed.sender}`
|
|
145
172
|
);
|
|
173
|
+
const connection = this.getConnection(parsed.sender);
|
|
174
|
+
connection.messagesSent = events.length;
|
|
146
175
|
}
|
|
147
|
-
const newConnection = {
|
|
148
|
-
id: parsed.sender,
|
|
149
|
-
lastSentMessageId: _Messenger.contextEvents[this.options.context].length - 1,
|
|
150
|
-
lastReceivedMessageId: -1,
|
|
151
|
-
desync: false
|
|
152
|
-
};
|
|
153
|
-
this.connections[parsed.sender] = newConnection;
|
|
154
176
|
this.log(`new connection added - ${parsed.context}:${parsed.sender}`);
|
|
155
177
|
}
|
|
156
178
|
handleLostEventsRequest(parsed) {
|
|
157
|
-
const
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
179
|
+
const connection = this.getConnection(parsed.sender);
|
|
180
|
+
const events = this.getEvents();
|
|
181
|
+
if (!connection || events.length === 0) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const missingEvents = events.slice(connection.messagesSent, events.length);
|
|
185
|
+
if (missingEvents.length === 0) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
162
188
|
const message = {
|
|
163
189
|
type: "MESSENGER_EVENT_BATCH",
|
|
164
190
|
payload: {
|
|
165
191
|
events: missingEvents.map(
|
|
166
|
-
(event) => this.addTransactionMetadata(event
|
|
192
|
+
(event) => this.addTransactionMetadata(event)
|
|
167
193
|
)
|
|
168
|
-
}
|
|
194
|
+
},
|
|
195
|
+
target: parsed.sender
|
|
169
196
|
};
|
|
170
197
|
this.options.sendMessage(this.addTransactionMetadata(message));
|
|
198
|
+
connection.messagesSent = events.length;
|
|
171
199
|
this.log(
|
|
172
|
-
`messages [0 - ${
|
|
200
|
+
`messages [0 - ${events.length - 1}] sent to ${parsed.context}:${parsed.sender}`
|
|
173
201
|
);
|
|
174
202
|
}
|
|
175
203
|
handleDisconnectMessage(parsed) {
|
|
176
|
-
delete
|
|
204
|
+
delete _Messenger.connections[parsed.sender];
|
|
177
205
|
this.log(`disconnected - ${parsed.context}:${parsed.sender}`);
|
|
178
206
|
}
|
|
179
207
|
sendMessage(message) {
|
|
180
208
|
const parsed = typeof message === "string" ? JSON.parse(message) : message;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
209
|
+
this.addEvent(parsed);
|
|
210
|
+
const target = parsed.target || null;
|
|
211
|
+
const msg = this.addTransactionMetadata(parsed);
|
|
212
|
+
const connection = target ? this.getConnection(target) : null;
|
|
213
|
+
if (connection) {
|
|
214
|
+
connection.messagesSent += 1;
|
|
215
|
+
}
|
|
216
|
+
this.options.sendMessage(msg).catch(() => {
|
|
217
|
+
this.options.handleFailedMessage?.(msg);
|
|
218
|
+
this.log(
|
|
219
|
+
`failed to send message: ${parsed.type} from ${this.id} to ${target || "all"}`
|
|
220
|
+
);
|
|
192
221
|
});
|
|
193
222
|
}
|
|
194
223
|
destroy() {
|
|
@@ -196,18 +225,22 @@ var Messenger = class _Messenger {
|
|
|
196
225
|
clearInterval(this.beaconInterval);
|
|
197
226
|
}
|
|
198
227
|
this.options.removeListener(this.handleMessage);
|
|
199
|
-
Object.keys(
|
|
228
|
+
Object.keys(_Messenger.connections).forEach((connection) => {
|
|
200
229
|
const event = {
|
|
201
230
|
type: "MESSENGER_DISCONNECT",
|
|
202
|
-
payload: null
|
|
231
|
+
payload: null,
|
|
232
|
+
target: connection
|
|
203
233
|
};
|
|
204
|
-
const message = this.addTransactionMetadata(event
|
|
234
|
+
const message = this.addTransactionMetadata(event);
|
|
205
235
|
this.options.sendMessage(message);
|
|
206
236
|
});
|
|
237
|
+
_Messenger.reset();
|
|
207
238
|
this.log("destroyed");
|
|
208
239
|
}
|
|
209
|
-
static
|
|
210
|
-
|
|
240
|
+
/** reset static records */
|
|
241
|
+
static reset() {
|
|
242
|
+
_Messenger.events = {};
|
|
243
|
+
_Messenger.connections = {};
|
|
211
244
|
}
|
|
212
245
|
};
|
|
213
246
|
export {
|