@helenejs/react
Version:
Real-time Web Apps for Node.js
125 lines • 4.57 kB
JavaScript
;
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