@bigmi/client
Version:
Reactive primitives for Bitcoin apps.
85 lines (84 loc) • 2.88 kB
JavaScript
import { retryUntil, withTimeout } from "@bigmi/core";
//#region src/actions/reconnect.ts
let isReconnecting = false;
async function reconnect(config, parameters = {}) {
if (isReconnecting) return [];
isReconnecting = true;
config.setState((x) => ({
...x,
status: x.current ? "reconnecting" : "connecting"
}));
const connectors = [];
if (parameters.connectors?.length) for (const connector_ of parameters.connectors) {
let connector;
if (typeof connector_ === "function") connector = config._internal.connectors.setup(connector_);
else connector = connector_;
connectors.push(connector);
}
else connectors.push(...config.connectors);
let recentConnectorId;
try {
recentConnectorId = await config.storage?.getItem("recentConnectorId");
} catch {}
const scores = {};
for (const [, connection] of config.state.connections) scores[connection.connector.id] = 1;
if (recentConnectorId) scores[recentConnectorId] = 0;
const sorted = Object.keys(scores).length > 0 ? [...connectors].sort((a, b) => (scores[a.id] ?? 10) - (scores[b.id] ?? 10)) : connectors;
const processedProviders = /* @__PURE__ */ new Set();
const connectionPromises = sorted.map(async (connector) => {
try {
const provider = await retryUntil(() => connector.getProvider().catch(() => void 0), {
timeout: 5e3,
interval: 100
});
if (!provider) return null;
if (processedProviders.has(provider)) return null;
processedProviders.add(provider);
if (!await withTimeout(() => connector.isAuthorized(), { timeout: 5e3 })) return null;
const data = await withTimeout(() => connector.connect({ isReconnecting: true }), { timeout: 5e3 });
if (!data || !data.accounts || data.accounts.length === 0) return null;
connector.emitter.off("connect", config._internal.events.connect);
connector.emitter.on("change", config._internal.events.change);
connector.emitter.on("disconnect", config._internal.events.disconnect);
config.setState((x) => {
const connections = new Map(x.connections);
connections.set(connector.uid, {
accounts: data.accounts,
chainId: data.chainId,
connector
});
return {
...x,
connections,
current: x.current || connector.uid,
status: "connected"
};
});
return {
connector,
data
};
} catch {
return null;
}
});
const connectionResults = await Promise.allSettled(connectionPromises);
const connections = [];
for (const result of connectionResults) if (result.status === "fulfilled" && result.value) {
const { connector, data } = result.value;
connections.push({
accounts: data.accounts,
chainId: data.chainId,
connector
});
}
if (connections.length === 0) config.setState((x) => ({
...x,
status: "disconnected"
}));
isReconnecting = false;
return connections;
}
//#endregion
export { reconnect };
//# sourceMappingURL=reconnect.js.map