@sesionario/blocks 1.13.0 → 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 +169 -74
- 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 +169 -74
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6185,7 +6185,7 @@ function MessageScrollerButton({
|
|
|
6185
6185
|
"data-size": size,
|
|
6186
6186
|
direction,
|
|
6187
6187
|
className: cn(
|
|
6188
|
-
"absolute
|
|
6188
|
+
"absolute left-1/2 -translate-x-1/2 border-border bg-background text-foreground transition-[translate,scale,opacity] duration-200 hover:bg-muted hover:text-foreground data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full data-[direction=start]:[&_svg]:rotate-180",
|
|
6189
6189
|
className
|
|
6190
6190
|
),
|
|
6191
6191
|
render: render ?? /* @__PURE__ */ jsxRuntime.jsx(Button, { variant, size }),
|
|
@@ -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
|
}
|