UNPKG

@helenejs/react

Version:

Real-time Web Apps for Node.js

125 lines 4.57 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.useMethod = void 0; const utils_1 = require("@helenejs/utils"); const isFunction_1 = __importDefault(require("lodash/isFunction")); const noop_1 = __importDefault(require("lodash/noop")); const react_1 = require("react"); const use_debounce_1 = require("use-debounce"); const use_caller_1 = require("./use-caller"); const use_circuit_breaker_1 = require("./use-circuit-breaker"); const use_client_1 = require("./use-client"); const use_event_1 = require("./use-event"); const use_method_refresh_1 = require("./use-method-refresh"); const useMethod = ({ method = null, params: _params = undefined, event = null, channel = utils_1.NO_CHANNEL, defaultValue: _defaultValue = null, cache = false, maxAge = 60000, deps = [], authenticated = false, debounced = null, parse = null, lazy = false, required = [], ...methodOptions }) => { if (!method) { throw new Error('Method name is required.'); } const client = (0, use_client_1.useClient)(); const defaultValue = (0, react_1.useMemo)(() => _defaultValue, deps); const params = (0, react_1.useMemo)(() => _params, deps); const [error, setError] = (0, react_1.useState)(null); const [result, setResult] = (0, react_1.useState)(null); const [loading, setLoading] = (0, react_1.useState)(!lazy); const { shouldCall, placeholderValue } = (0, use_circuit_breaker_1.useCircuitBreaker)({ parse, params, required, deps, }); const optimistic = (0, react_1.useCallback)(cb => { if (!(0, isFunction_1.default)(cb)) throw new Error('Function Expected'); const simulatedResult = cb(result); setResult(simulatedResult); }, [result, setResult]); /** * Starts loading only after a few milliseconds as humans do not perceive * small timeframes, and the loading indicator can be annoying. */ const startLoading = (0, use_debounce_1.useDebouncedCallback)(() => { setLoading(true); }, 100); const caller = (0, use_caller_1.useCaller)({ cache, client, maxAge }); const refresh = (0, use_method_refresh_1.useMethodRefresh)({ authenticated, caller, client, params, method, setError, setLoading, setResult, shouldCall, startLoading, methodOptions, defaultValue, deps, }); const debouncedRefresh = (0, use_debounce_1.useDebouncedCallback)(refresh, debounced ?? 100); const refreshCallback = (0, react_1.useMemo)(() => (debounced ? debouncedRefresh : refresh), [debounced, debouncedRefresh, refresh]); (0, use_event_1.useLocalEvent)({ event: utils_1.ClientEvents.INITIALIZING, }, () => { if (authenticated) { setLoading(true); } }, [authenticated]); (0, use_event_1.useLocalEvent)({ event: utils_1.ClientEvents.INITIALIZED, }, () => { if (authenticated) { refreshCallback(); } }, [refreshCallback, authenticated]); (0, use_event_1.useLocalEvent)({ event: utils_1.ClientEvents.LOGOUT, }, () => { if (authenticated) { refreshCallback(); } }, [refreshCallback, authenticated]); (0, react_1.useEffect)(() => { if (!method) return; if (!client) return; if (!lazy) refreshCallback(); }, [client, method, params, debounced]); (0, use_event_1.useLocalEvent)({ event, channel }, refreshCallback, [refreshCallback]); (0, use_event_1.useRemoteEvent)({ event: utils_1.HeleneEvents.METHOD_REFRESH, channel, }, (refreshMethod) => { if (refreshMethod === method) { refreshCallback(); } }, [refreshCallback]); (0, react_1.useEffect)(() => () => { debouncedRefresh.cancel(); }, []); if (!shouldCall) { return { result: placeholderValue ?? defaultValue, error, loading: false, refresh: noop_1.default, optimistic: noop_1.default, client, }; } return { result: result ?? defaultValue, error, loading, refresh: refreshCallback, optimistic, client, }; }; exports.useMethod = useMethod; //# sourceMappingURL=use-method.js.map