@sesionario/blocks 1.13.1 → 1.14.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/index.cjs +168 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +168 -73
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6985,6 +6985,162 @@ function createSupportChatClient(basePath = "/api/chat-svc") {
|
|
|
6985
6985
|
}
|
|
6986
6986
|
var DEFAULT_RECONNECT_MS = 2e3;
|
|
6987
6987
|
var MAX_RECONNECT_MS = 3e4;
|
|
6988
|
+
var HEARTBEAT_MS = 3e4;
|
|
6989
|
+
var registry = /* @__PURE__ */ new Map();
|
|
6990
|
+
function channelKeyFromUrl(url) {
|
|
6991
|
+
const q = url.indexOf("?");
|
|
6992
|
+
return q === -1 ? url : url.slice(0, q);
|
|
6993
|
+
}
|
|
6994
|
+
function stopHeartbeat(shared) {
|
|
6995
|
+
if (shared.heartbeatTimer) {
|
|
6996
|
+
clearInterval(shared.heartbeatTimer);
|
|
6997
|
+
shared.heartbeatTimer = null;
|
|
6998
|
+
}
|
|
6999
|
+
}
|
|
7000
|
+
function startHeartbeat(shared, gen) {
|
|
7001
|
+
stopHeartbeat(shared);
|
|
7002
|
+
shared.heartbeatTimer = setInterval(() => {
|
|
7003
|
+
if (gen !== shared.gen) return;
|
|
7004
|
+
if (shared.ws?.readyState === WebSocket.OPEN) {
|
|
7005
|
+
try {
|
|
7006
|
+
shared.ws.send("ping");
|
|
7007
|
+
} catch {
|
|
7008
|
+
}
|
|
7009
|
+
}
|
|
7010
|
+
}, HEARTBEAT_MS);
|
|
7011
|
+
}
|
|
7012
|
+
function clearReconnect(shared) {
|
|
7013
|
+
if (shared.reconnectTimer) {
|
|
7014
|
+
clearTimeout(shared.reconnectTimer);
|
|
7015
|
+
shared.reconnectTimer = null;
|
|
7016
|
+
}
|
|
7017
|
+
}
|
|
7018
|
+
function openSocket(shared, url) {
|
|
7019
|
+
const gen = ++shared.gen;
|
|
7020
|
+
clearReconnect(shared);
|
|
7021
|
+
if (shared.ws) {
|
|
7022
|
+
try {
|
|
7023
|
+
shared.ws.close();
|
|
7024
|
+
} catch {
|
|
7025
|
+
}
|
|
7026
|
+
}
|
|
7027
|
+
const ws = new WebSocket(url);
|
|
7028
|
+
shared.ws = ws;
|
|
7029
|
+
ws.onopen = () => {
|
|
7030
|
+
if (gen !== shared.gen) return;
|
|
7031
|
+
shared.attempt = 0;
|
|
7032
|
+
startHeartbeat(shared, gen);
|
|
7033
|
+
};
|
|
7034
|
+
ws.onmessage = (msg) => {
|
|
7035
|
+
if (gen !== shared.gen) return;
|
|
7036
|
+
let data;
|
|
7037
|
+
try {
|
|
7038
|
+
data = JSON.parse(String(msg.data));
|
|
7039
|
+
} catch {
|
|
7040
|
+
return;
|
|
7041
|
+
}
|
|
7042
|
+
if (typeof data?.type !== "string") return;
|
|
7043
|
+
if (data.type === "pong") return;
|
|
7044
|
+
for (const listener of shared.listeners) {
|
|
7045
|
+
listener(data);
|
|
7046
|
+
}
|
|
7047
|
+
};
|
|
7048
|
+
ws.onclose = () => {
|
|
7049
|
+
if (gen !== shared.gen) return;
|
|
7050
|
+
shared.ws = null;
|
|
7051
|
+
stopHeartbeat(shared);
|
|
7052
|
+
scheduleReconnect(shared);
|
|
7053
|
+
};
|
|
7054
|
+
ws.onerror = () => {
|
|
7055
|
+
};
|
|
7056
|
+
}
|
|
7057
|
+
function scheduleReconnect(shared) {
|
|
7058
|
+
if (shared.listeners.size === 0) return;
|
|
7059
|
+
clearReconnect(shared);
|
|
7060
|
+
const delay = Math.min(
|
|
7061
|
+
shared.reconnectDelayMs * 2 ** shared.attempt,
|
|
7062
|
+
MAX_RECONNECT_MS
|
|
7063
|
+
);
|
|
7064
|
+
shared.attempt += 1;
|
|
7065
|
+
shared.reconnectTimer = setTimeout(() => {
|
|
7066
|
+
shared.reconnectTimer = null;
|
|
7067
|
+
void connectShared(shared);
|
|
7068
|
+
}, delay);
|
|
7069
|
+
}
|
|
7070
|
+
async function connectShared(shared) {
|
|
7071
|
+
if (shared.connecting || shared.listeners.size === 0) return;
|
|
7072
|
+
shared.connecting = true;
|
|
7073
|
+
let url = null;
|
|
7074
|
+
try {
|
|
7075
|
+
url = await shared.getWsUrl();
|
|
7076
|
+
} finally {
|
|
7077
|
+
shared.connecting = false;
|
|
7078
|
+
}
|
|
7079
|
+
if (shared.listeners.size === 0) return;
|
|
7080
|
+
if (!url) return;
|
|
7081
|
+
openSocket(shared, url);
|
|
7082
|
+
}
|
|
7083
|
+
function destroyShared(shared) {
|
|
7084
|
+
shared.gen += 1;
|
|
7085
|
+
clearReconnect(shared);
|
|
7086
|
+
stopHeartbeat(shared);
|
|
7087
|
+
if (shared.ws) {
|
|
7088
|
+
try {
|
|
7089
|
+
shared.ws.close();
|
|
7090
|
+
} catch {
|
|
7091
|
+
}
|
|
7092
|
+
shared.ws = null;
|
|
7093
|
+
}
|
|
7094
|
+
}
|
|
7095
|
+
function joinChannel(key, url, getWsUrl, reconnectDelayMs, listener) {
|
|
7096
|
+
ensureVisibilityHook();
|
|
7097
|
+
let shared = registry.get(key);
|
|
7098
|
+
if (!shared) {
|
|
7099
|
+
shared = {
|
|
7100
|
+
key,
|
|
7101
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
7102
|
+
getWsUrl,
|
|
7103
|
+
reconnectDelayMs,
|
|
7104
|
+
ws: null,
|
|
7105
|
+
attempt: 0,
|
|
7106
|
+
reconnectTimer: null,
|
|
7107
|
+
heartbeatTimer: null,
|
|
7108
|
+
connecting: false,
|
|
7109
|
+
gen: 0
|
|
7110
|
+
};
|
|
7111
|
+
registry.set(key, shared);
|
|
7112
|
+
shared.listeners.add(listener);
|
|
7113
|
+
openSocket(shared, url);
|
|
7114
|
+
return;
|
|
7115
|
+
}
|
|
7116
|
+
shared.getWsUrl = getWsUrl;
|
|
7117
|
+
shared.listeners.add(listener);
|
|
7118
|
+
if (!shared.ws && !shared.connecting && !shared.reconnectTimer) {
|
|
7119
|
+
openSocket(shared, url);
|
|
7120
|
+
}
|
|
7121
|
+
}
|
|
7122
|
+
function leaveChannel(key, listener) {
|
|
7123
|
+
const shared = registry.get(key);
|
|
7124
|
+
if (!shared) return;
|
|
7125
|
+
shared.listeners.delete(listener);
|
|
7126
|
+
if (shared.listeners.size === 0) {
|
|
7127
|
+
destroyShared(shared);
|
|
7128
|
+
registry.delete(key);
|
|
7129
|
+
}
|
|
7130
|
+
}
|
|
7131
|
+
var visibilityHooked = false;
|
|
7132
|
+
function ensureVisibilityHook() {
|
|
7133
|
+
if (visibilityHooked || typeof document === "undefined") return;
|
|
7134
|
+
visibilityHooked = true;
|
|
7135
|
+
document.addEventListener("visibilitychange", () => {
|
|
7136
|
+
if (document.visibilityState !== "visible") return;
|
|
7137
|
+
for (const shared of registry.values()) {
|
|
7138
|
+
if (!shared.ws && !shared.reconnectTimer && !shared.connecting) {
|
|
7139
|
+
void connectShared(shared);
|
|
7140
|
+
}
|
|
7141
|
+
}
|
|
7142
|
+
});
|
|
7143
|
+
}
|
|
6988
7144
|
function useRealtimeChannel({
|
|
6989
7145
|
getWsUrl,
|
|
6990
7146
|
onEvent,
|
|
@@ -6998,87 +7154,26 @@ function useRealtimeChannel({
|
|
|
6998
7154
|
React7.useEffect(() => {
|
|
6999
7155
|
if (!enabled) return;
|
|
7000
7156
|
let cancelled = false;
|
|
7001
|
-
let
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
const
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
};
|
|
7011
|
-
const scheduleReconnect = () => {
|
|
7012
|
-
if (cancelled) return;
|
|
7013
|
-
clearReconnect();
|
|
7014
|
-
const delay = Math.min(reconnectDelayMs * 2 ** attempt, MAX_RECONNECT_MS);
|
|
7015
|
-
attempt += 1;
|
|
7016
|
-
reconnectTimer = setTimeout(() => {
|
|
7017
|
-
void connect();
|
|
7018
|
-
}, delay);
|
|
7019
|
-
};
|
|
7020
|
-
const connect = async () => {
|
|
7021
|
-
const gen = ++connectGen.current;
|
|
7022
|
-
clearReconnect();
|
|
7023
|
-
const url = await getWsUrlRef.current();
|
|
7024
|
-
if (cancelled || gen !== connectGen.current) return;
|
|
7025
|
-
if (!url) {
|
|
7026
|
-
scheduleReconnect();
|
|
7027
|
-
return;
|
|
7028
|
-
}
|
|
7029
|
-
if (socket) {
|
|
7030
|
-
try {
|
|
7031
|
-
socket.close();
|
|
7032
|
-
} catch {
|
|
7033
|
-
}
|
|
7034
|
-
socket = null;
|
|
7035
|
-
}
|
|
7036
|
-
const ws = new WebSocket(url);
|
|
7037
|
-
socket = ws;
|
|
7038
|
-
ws.onopen = () => {
|
|
7039
|
-
if (cancelled || gen !== connectGen.current) return;
|
|
7040
|
-
attempt = 0;
|
|
7041
|
-
};
|
|
7042
|
-
ws.onmessage = (msg) => {
|
|
7043
|
-
if (cancelled || gen !== connectGen.current) return;
|
|
7044
|
-
let data;
|
|
7045
|
-
try {
|
|
7046
|
-
data = JSON.parse(String(msg.data));
|
|
7047
|
-
} catch {
|
|
7048
|
-
return;
|
|
7049
|
-
}
|
|
7050
|
-
if (typeof data?.type !== "string") return;
|
|
7051
|
-
if (data.type === "pong") return;
|
|
7052
|
-
onEventRef.current(data);
|
|
7053
|
-
};
|
|
7054
|
-
ws.onclose = () => {
|
|
7055
|
-
if (cancelled || gen !== connectGen.current) return;
|
|
7056
|
-
socket = null;
|
|
7057
|
-
scheduleReconnect();
|
|
7058
|
-
};
|
|
7059
|
-
ws.onerror = () => {
|
|
7060
|
-
};
|
|
7157
|
+
let joinedKey = null;
|
|
7158
|
+
const listener = (event) => onEventRef.current(event);
|
|
7159
|
+
const resolver = () => getWsUrlRef.current();
|
|
7160
|
+
const join = async () => {
|
|
7161
|
+
if (cancelled || joinedKey) return;
|
|
7162
|
+
const url = await resolver();
|
|
7163
|
+
if (cancelled || !url) return;
|
|
7164
|
+
joinedKey = channelKeyFromUrl(url);
|
|
7165
|
+
joinChannel(joinedKey, url, resolver, reconnectDelayMs, listener);
|
|
7061
7166
|
};
|
|
7062
7167
|
const onVisibility = () => {
|
|
7063
7168
|
if (document.visibilityState !== "visible" || cancelled) return;
|
|
7064
|
-
if (!
|
|
7065
|
-
void connect();
|
|
7066
|
-
}
|
|
7169
|
+
if (!joinedKey) void join();
|
|
7067
7170
|
};
|
|
7068
|
-
void
|
|
7171
|
+
void join();
|
|
7069
7172
|
document.addEventListener("visibilitychange", onVisibility);
|
|
7070
7173
|
return () => {
|
|
7071
7174
|
cancelled = true;
|
|
7072
|
-
connectGen.current += 1;
|
|
7073
|
-
clearReconnect();
|
|
7074
7175
|
document.removeEventListener("visibilitychange", onVisibility);
|
|
7075
|
-
if (
|
|
7076
|
-
try {
|
|
7077
|
-
socket.close();
|
|
7078
|
-
} catch {
|
|
7079
|
-
}
|
|
7080
|
-
socket = null;
|
|
7081
|
-
}
|
|
7176
|
+
if (joinedKey) leaveChannel(joinedKey, listener);
|
|
7082
7177
|
};
|
|
7083
7178
|
}, [enabled, reconnectDelayMs]);
|
|
7084
7179
|
}
|