Files
pezkuwi-apps/packages/react-hooks/src/useTeleport.ts
T
Satoshi Qazi Muhammed 45d479d2ec Move to @pezkuwi/dev 0.86.4 (eslint 10 toolchain)
- dev ^0.86.4 at the root and in packages/apps; directives renamed by
  pezkuwi-dev-migrate-eslint10.
- eslint --fix with the 0.86.4 config; one fix broke syntax
  (typescript-eslint prefer-optional-chain turned
  `(isStarted && onStart) && onStart()` into `(isStarted && onStart?.();`
  in TxButton) and is corrected by hand.
- The remaining findings fixed rather than disabled: optional chains
  (each suggestion reviewed), `cause` on rethrown errors, `if` instead of
  `a && promise` in effects, parallel instead of sequential awaits in
  Promise.all, Error rejections, no `delete` on arrays (the storage query
  cache is a Map; an upload's file list no longer keeps a hole), no
  `[object Object]` stringification (TFunction's second argument is text
  or options), dead code removed (referenda's never-shown expand button,
  react-query's unused CoreDescriptor).
2026-10-10 02:06:12 +04:00

121 lines
3.5 KiB
TypeScript

// Copyright 2017-2026 @pezkuwi/react-hooks authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { LinkOption } from '@pezkuwi/apps-config/endpoints/types';
import type { ParaId } from '@pezkuwi/types/interfaces';
import { useEffect, useState } from 'react';
import { createWsEndpoints } from '@pezkuwi/apps-config';
import { isNumber } from '@pezkuwi/util';
import { createNamedHook } from './createNamedHook.js';
import { useApi } from './useApi.js';
import { useCall } from './useCall.js';
interface Teleport {
allowTeleport: boolean;
destinations: LinkOption[];
isParaTeleport?: boolean;
isRelayTeleport?: boolean;
oneWay: number[]
}
interface ExtLinkOption extends LinkOption {
teleport: number[];
}
const DEFAULT_STATE: Teleport = {
allowTeleport: false,
destinations: [],
oneWay: []
};
const endpoints = createWsEndpoints((k, v) => (typeof v === 'string' && v) || k).filter((v): v is ExtLinkOption => !!v.teleport);
function extractRelayDestinations (relayGenesis: string, filter: (l: ExtLinkOption) => boolean): ExtLinkOption[] {
return endpoints
.filter((l) =>
(
l.genesisHashRelay === relayGenesis ||
l.genesisHash === relayGenesis
) && filter(l)
)
.reduce((result: ExtLinkOption[], curr): ExtLinkOption[] => {
const isExisting = result.some(({ genesisHash, paraId }) =>
paraId === curr.paraId ||
(genesisHash && genesisHash === curr.genesisHash)
);
if (!isExisting) {
result.push(curr);
}
return result;
}, [])
.sort((a, b) =>
a.isRelay === b.isRelay
? 0
: a.isRelay
? -1
: 1
);
}
function useTeleportImpl (): Teleport {
const { api, apiUrl, isApiReady } = useApi();
const paraId = useCall<ParaId>(isApiReady && api.query.teyrchainInfo?.teyrchainId);
const [state, setState] = useState<Teleport>(() => ({ ...DEFAULT_STATE }));
useEffect((): void => {
if (isApiReady) {
const relayGenesis = api.genesisHash.toHex();
const endpoint = endpoints.find(({ genesisHash }) => genesisHash === relayGenesis);
if (endpoint) {
const destinations = extractRelayDestinations(relayGenesis, ({ paraId }) =>
isNumber(paraId) &&
endpoint.teleport.includes(paraId)
);
const oneWay = extractRelayDestinations(relayGenesis, ({ paraId, teleport }) =>
isNumber(paraId) &&
!teleport.includes(-1)
).map(({ paraId }) => paraId || -1);
setState({
allowTeleport: destinations.length !== 0,
destinations,
isRelayTeleport: true,
oneWay
});
}
}
}, [api, isApiReady]);
useEffect((): void => {
if (paraId) {
const endpoint = endpoints.find(({ value }) => value === apiUrl);
if (endpoint?.genesisHashRelay) {
const destinations = extractRelayDestinations(endpoint.genesisHashRelay, ({ paraId }) =>
endpoint.teleport.includes(isNumber(paraId) ? paraId : -1)
);
const oneWay = extractRelayDestinations(endpoint.genesisHashRelay, ({ paraId, teleport }) =>
!teleport.includes(isNumber(paraId) ? paraId : -1)
).map(({ paraId }) => paraId || -1);
setState({
allowTeleport: destinations.length !== 0,
destinations,
isParaTeleport: true,
oneWay
});
}
}
}, [apiUrl, paraId]);
return state;
}
export const useTeleport = createNamedHook('useTeleport', useTeleportImpl);