@cendarsoss/pusher-js 8.4.16 → 8.4.18
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/node/pusher.js +56 -43
- package/dist/node/pusher.js.map +1 -1
- package/dist/web/pusher.mjs +677 -129
- package/dist/web/pusher.mjs.map +1 -1
- package/package.json +2 -1
- package/src/core/connection/protocol/protocol.ts +4 -3
- package/src/core/delta/channel_state.ts +13 -5
- package/src/core/delta/manager.ts +58 -32
- package/src/core/pusher.ts +3 -21
- package/types/src/core/delta/channel_state.d.ts +2 -1
package/dist/node/pusher.js
CHANGED
|
@@ -4,6 +4,7 @@ const base64 = require("@stablelib/base64");
|
|
|
4
4
|
const fayeWebsocket = require("faye-websocket");
|
|
5
5
|
const xmlhttprequest = require("xmlhttprequest");
|
|
6
6
|
const crypto = require("crypto");
|
|
7
|
+
const lruCache = require("lru-cache");
|
|
7
8
|
const fossilDelta = require("fossil-delta");
|
|
8
9
|
const vcdiffDecoder = require("@ably/vcdiff-decoder");
|
|
9
10
|
function encode(s) {
|
|
@@ -840,8 +841,8 @@ const Protocol = {
|
|
|
840
841
|
if (messageData.user_id) {
|
|
841
842
|
pusherEvent.user_id = messageData.user_id;
|
|
842
843
|
}
|
|
843
|
-
const sequence = messageData.
|
|
844
|
-
const conflationKey = messageData.
|
|
844
|
+
const sequence = messageData.seq;
|
|
845
|
+
const conflationKey = messageData.conflation_key;
|
|
845
846
|
if (typeof sequence === "number") {
|
|
846
847
|
pusherEvent.sequence = sequence;
|
|
847
848
|
}
|
|
@@ -3545,12 +3546,15 @@ class UserFacade extends Dispatcher {
|
|
|
3545
3546
|
this._signinDoneResolve = resolve;
|
|
3546
3547
|
}
|
|
3547
3548
|
}
|
|
3549
|
+
const MAX_CONFLATION_CACHE_KEYS = 2e3;
|
|
3548
3550
|
class ChannelState {
|
|
3549
3551
|
constructor(channelName) {
|
|
3550
3552
|
this.channelName = channelName;
|
|
3551
3553
|
this.conflationKey = null;
|
|
3552
3554
|
this.maxMessagesPerKey = 30;
|
|
3553
|
-
this.conflationCaches =
|
|
3555
|
+
this.conflationCaches = new lruCache.LRUCache({
|
|
3556
|
+
max: MAX_CONFLATION_CACHE_KEYS
|
|
3557
|
+
});
|
|
3554
3558
|
this.baseMessage = null;
|
|
3555
3559
|
this.baseSequence = null;
|
|
3556
3560
|
this.lastSequence = null;
|
|
@@ -3591,7 +3595,7 @@ class ChannelState {
|
|
|
3591
3595
|
return this.baseMessage;
|
|
3592
3596
|
}
|
|
3593
3597
|
const key = conflationKeyValue || "";
|
|
3594
|
-
const cache = this.conflationCaches.
|
|
3598
|
+
const cache = this.conflationCaches.peek(key);
|
|
3595
3599
|
if (!cache || baseIndex === void 0) {
|
|
3596
3600
|
console.error("[ChannelState] No cache or baseIndex undefined", {
|
|
3597
3601
|
hasCache: !!cache,
|
|
@@ -3611,6 +3615,7 @@ class ChannelState {
|
|
|
3611
3615
|
});
|
|
3612
3616
|
return null;
|
|
3613
3617
|
}
|
|
3618
|
+
this.conflationCaches.get(key);
|
|
3614
3619
|
return message.content;
|
|
3615
3620
|
}
|
|
3616
3621
|
/**
|
|
@@ -3618,10 +3623,9 @@ class ChannelState {
|
|
|
3618
3623
|
*/
|
|
3619
3624
|
updateConflationCache(conflationKeyValue, message, sequence) {
|
|
3620
3625
|
const key = conflationKeyValue || "";
|
|
3621
|
-
let cache = this.conflationCaches.
|
|
3626
|
+
let cache = this.conflationCaches.peek(key);
|
|
3622
3627
|
if (!cache) {
|
|
3623
3628
|
cache = [];
|
|
3624
|
-
this.conflationCaches.set(key, cache);
|
|
3625
3629
|
}
|
|
3626
3630
|
if (cache.length > 0) {
|
|
3627
3631
|
const lastCacheItem = cache[cache.length - 1];
|
|
@@ -3633,6 +3637,7 @@ class ChannelState {
|
|
|
3633
3637
|
while (cache.length > this.maxMessagesPerKey) {
|
|
3634
3638
|
cache.shift();
|
|
3635
3639
|
}
|
|
3640
|
+
this.conflationCaches.set(key, cache);
|
|
3636
3641
|
}
|
|
3637
3642
|
/**
|
|
3638
3643
|
* Check if we have a valid base
|
|
@@ -3959,27 +3964,24 @@ class DeltaCompressionManager {
|
|
|
3959
3964
|
deltaSize: deltaBytes.length,
|
|
3960
3965
|
compressionRatio: (deltaBytes.length / reconstructedMessage.length * 100).toFixed(1) + "%"
|
|
3961
3966
|
});
|
|
3967
|
+
let reconstructedData;
|
|
3962
3968
|
try {
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
try {
|
|
3967
|
-
data = JSON.parse(data);
|
|
3968
|
-
} catch (e) {
|
|
3969
|
-
}
|
|
3970
|
-
}
|
|
3971
|
-
return {
|
|
3972
|
-
event,
|
|
3969
|
+
reconstructedData = JSON.parse(JSON.parse(reconstructedMessage));
|
|
3970
|
+
} catch (parseError) {
|
|
3971
|
+
this.error("Failed to parse reconstructed message as JSON", {
|
|
3973
3972
|
channel,
|
|
3974
|
-
data
|
|
3975
|
-
};
|
|
3976
|
-
} catch (e) {
|
|
3977
|
-
return {
|
|
3978
3973
|
event,
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3974
|
+
sequence,
|
|
3975
|
+
parseError: parseError.message,
|
|
3976
|
+
reconstructedMessageLength: reconstructedMessage.length
|
|
3977
|
+
});
|
|
3978
|
+
reconstructedData = reconstructedMessage;
|
|
3982
3979
|
}
|
|
3980
|
+
return {
|
|
3981
|
+
event,
|
|
3982
|
+
channel,
|
|
3983
|
+
data: reconstructedData
|
|
3984
|
+
};
|
|
3983
3985
|
} catch (error) {
|
|
3984
3986
|
this.error("Delta decode failed", {
|
|
3985
3987
|
channel,
|
|
@@ -4000,10 +4002,19 @@ class DeltaCompressionManager {
|
|
|
4000
4002
|
* Handle regular (full) message with delta sequence markers
|
|
4001
4003
|
*/
|
|
4002
4004
|
handleFullMessage(channel, rawMessage, sequence, conflationKey) {
|
|
4005
|
+
let parsedMessage;
|
|
4006
|
+
try {
|
|
4007
|
+
parsedMessage = JSON.parse(rawMessage);
|
|
4008
|
+
} catch (e) {
|
|
4009
|
+
this.log("handleFullMessage parse failed", {
|
|
4010
|
+
channel,
|
|
4011
|
+
hasSequence: sequence === 0 || !!sequence
|
|
4012
|
+
});
|
|
4013
|
+
return;
|
|
4014
|
+
}
|
|
4003
4015
|
if (!sequence && sequence !== 0) {
|
|
4004
4016
|
try {
|
|
4005
|
-
const
|
|
4006
|
-
const candidate = typeof parsed.data === "string" ? JSON.parse(parsed.data).__delta_seq ?? parsed.__delta_seq : parsed.data?.__delta_seq ?? parsed.__delta_seq;
|
|
4017
|
+
const candidate = typeof parsedMessage.data === "string" ? JSON.parse(parsedMessage.data).__delta_seq ?? parsedMessage.__delta_seq : parsedMessage.data?.__delta_seq ?? parsedMessage.__delta_seq;
|
|
4007
4018
|
if (candidate === 0 || candidate) {
|
|
4008
4019
|
sequence = candidate;
|
|
4009
4020
|
} else {
|
|
@@ -4021,7 +4032,22 @@ class DeltaCompressionManager {
|
|
|
4021
4032
|
return;
|
|
4022
4033
|
}
|
|
4023
4034
|
}
|
|
4024
|
-
|
|
4035
|
+
if (parsedMessage?.data === void 0) {
|
|
4036
|
+
this.log("handleFullMessage missing data field, skipping", {
|
|
4037
|
+
channel,
|
|
4038
|
+
hasSequence: sequence === 0 || !!sequence
|
|
4039
|
+
});
|
|
4040
|
+
return;
|
|
4041
|
+
}
|
|
4042
|
+
const baseMessage = JSON.stringify(parsedMessage.data);
|
|
4043
|
+
if (typeof baseMessage !== "string") {
|
|
4044
|
+
this.log("handleFullMessage base serialization failed, skipping", {
|
|
4045
|
+
channel,
|
|
4046
|
+
hasSequence: sequence === 0 || !!sequence
|
|
4047
|
+
});
|
|
4048
|
+
return;
|
|
4049
|
+
}
|
|
4050
|
+
const messageSize = baseMessage.length;
|
|
4025
4051
|
let channelState = this.channelStates.get(channel);
|
|
4026
4052
|
if (!channelState) {
|
|
4027
4053
|
channelState = new ChannelState(channel);
|
|
@@ -4034,8 +4060,7 @@ class DeltaCompressionManager {
|
|
|
4034
4060
|
if (channelState.conflationKey && finalConflationKey !== void 0) {
|
|
4035
4061
|
channelState.updateConflationCache(
|
|
4036
4062
|
finalConflationKey,
|
|
4037
|
-
|
|
4038
|
-
// Store raw message directly
|
|
4063
|
+
baseMessage,
|
|
4039
4064
|
sequence
|
|
4040
4065
|
);
|
|
4041
4066
|
this.log("Stored full message (conflation)", {
|
|
@@ -4045,7 +4070,7 @@ class DeltaCompressionManager {
|
|
|
4045
4070
|
size: messageSize
|
|
4046
4071
|
});
|
|
4047
4072
|
} else {
|
|
4048
|
-
channelState.setBase(
|
|
4073
|
+
channelState.setBase(baseMessage, sequence);
|
|
4049
4074
|
this.log("Stored full message", {
|
|
4050
4075
|
channel,
|
|
4051
4076
|
sequence,
|
|
@@ -4287,22 +4312,10 @@ class Pusher {
|
|
|
4287
4312
|
if (typeof event.conflation_key === "string") {
|
|
4288
4313
|
conflationKey = event.conflation_key;
|
|
4289
4314
|
}
|
|
4290
|
-
|
|
4291
|
-
if (fullMessage && sequence !== void 0) {
|
|
4292
|
-
fullMessage = fullMessage.replace(/,"__delta_seq":\d+/g, "");
|
|
4293
|
-
fullMessage = fullMessage.replace(/"__delta_seq":\d+,/g, "");
|
|
4294
|
-
fullMessage = fullMessage.replace(
|
|
4295
|
-
/,"__conflation_key":"[^"]*"/g,
|
|
4296
|
-
""
|
|
4297
|
-
);
|
|
4298
|
-
fullMessage = fullMessage.replace(
|
|
4299
|
-
/"__conflation_key":"[^"]*",/g,
|
|
4300
|
-
""
|
|
4301
|
-
);
|
|
4302
|
-
}
|
|
4315
|
+
const rawMessage = event.rawMessage || "";
|
|
4303
4316
|
this.deltaCompression.handleFullMessage(
|
|
4304
4317
|
event.channel,
|
|
4305
|
-
|
|
4318
|
+
rawMessage,
|
|
4306
4319
|
sequence,
|
|
4307
4320
|
conflationKey
|
|
4308
4321
|
);
|