UNPKG

@v4fire/core

Version:
202 lines (156 loc) 3.77 kB
/*! * V4Fire Core * https://github.com/V4Fire/Core * * Released under the MIT license * https://github.com/V4Fire/Core/blob/master/LICENSE */ /** * [[include:core/net/README.md]] * @packageDocumentation */ import config from 'config'; import * as netEngine from 'core/net/engines'; import { state, emitter } from 'core/net/const'; import type { NetStatus, NetEngine } from 'core/net/interface'; import { IS_NODE } from 'core/prelude/env'; export * from 'core/net/const'; export * from 'core/net/interface'; const {online} = config; let storage, cache; //#if runtime has core/kv-storage // eslint-disable-next-line prefer-const storage = import('core/kv-storage').then(({asyncLocal}) => asyncLocal.namespace('[[NET]]')); //#endif /** * Returns information about the internet connection status * * @param [engine] - engine to test online connection * * @emits `online()` * @emits `offline(lastOnline: Date)` * @emits `status(value:` [[NetStatus]] `)` */ export function isOnline( engine: NetEngine = netEngine ): Promise<NetStatus> { //#if runtime has core/net if (cache != null) { return cache; } const res = (async () => { const prevStatus = state.status; // eslint-disable-next-line require-atomic-updates state.status = await engine.isOnline(); if (state.status == null) { return { status: true, lastOnline: undefined }; } if (online.persistence && state.lastOnline == null) { if (storage == null) { throw new ReferenceError("kv-storage module isn't loaded"); } try { const lastStoredOnline = await (await storage).get('lastOnline'); if (lastStoredOnline != null) { // eslint-disable-next-line require-atomic-updates state.lastOnline = lastStoredOnline; } } catch {} } if (online.cacheTTL != null) { setTimeout(() => cache = undefined, online.cacheTTL); } if (prevStatus === undefined || state.status !== prevStatus) { if (state.status) { emitter.emit('online', state.lastOnline); } else { emitter.emit('offline'); } syncStatusWithStorage().catch(stderr); emitter.emit('status', {...<NetStatus>state}); } return {...<NetStatus>state}; })(); if (online.cacheTTL != null) { cache = res; } return res; //#endif // eslint-disable-next-line no-unreachable return Promise.resolve({ status: true }); } let storageSyncTimer; /** * Synchronizes the online status with a local storage */ export async function syncStatusWithStorage(): Promise<void> { if (state.status !== true) { return; } state.lastOnline = new Date(); const clear = () => { if (storageSyncTimer != null) { clearTimeout(storageSyncTimer); storageSyncTimer = undefined; } }; clear(); if (online.persistence) { if (storage == null) { throw new ReferenceError("kv-storage module isn't loaded"); } try { await (await storage).set('lastOnline', state.lastOnline); } catch (err) { stderr(err); } } if (online.lastDateSyncInterval != null) { clear(); storageSyncTimer = setTimeout(() => { storageSyncTimer = undefined; syncStatusWithStorage().catch(stderr); }, online.lastDateSyncInterval); } } let checkTimer; /** * Updates the online status */ export async function updateStatus(): Promise<void> { const clear = () => { if (checkTimer != null) { clearTimeout(checkTimer); checkTimer = undefined; } }; clear(); try { await isOnline(); } catch (err) { stderr(err); } if (online.checkInterval != null) { clear(); checkTimer = setTimeout(() => { checkTimer = undefined; updateStatus().catch(stderr); }, online.checkInterval); if (IS_NODE) { checkTimer.unref(); } } } emitter.on('sync', updateStatus); updateStatus().catch(stderr);