UNPKG

@hazae41/glacier

Version:

Yet another React data (re)fetching library

273 lines (269 loc) 11 kB
'use strict'; var option = require('@hazae41/option'); var result = require('@hazae41/result'); var ref = require('../../../../libs/react/ref.cjs'); var index = require('../../../../libs/request/index.cjs'); var index$1 = require('../../../../libs/signals/index.cjs'); var time = require('../../../../libs/time/time.cjs'); var core = require('../../../core/core.cjs'); var helper = require('../../../queries/simple/helper.cjs'); var react = require('react'); function useQuery(factory, deps) { const query = react.useMemo(() => { return factory(...deps); }, deps); if (query == null) return useSimpleSkeletonQuery(); if (query.settings.fetcher == null) return useSimpleFetcherlessQuery(query.settings); return useSimpleFetcherfulQuery(query.settings); } function useSimpleSkeletonQuery() { ref.useRenderRef(undefined); const cacheKey = react.useMemo(() => { // NOOP }, [undefined]); react.useState(0); react.useRef(); react.useRef(); react.useMemo(() => { // NOOP }, [cacheKey]); react.useCallback(() => { // NOOP }, [cacheKey]); react.useCallback(() => { // NOOP }, [cacheKey]); react.useEffect(() => { // NOOP }, [cacheKey]); react.useEffect(() => { // NOOP }, [cacheKey]); const mutateOrThrow = react.useCallback(async (mutator) => { throw new core.MissingKeyError(); }, [cacheKey]); const deleteOrThrow = react.useCallback(async () => { throw new core.MissingKeyError(); }, [cacheKey]); const fetchOrThrow = react.useCallback(async (aborter = new AbortController()) => { throw new core.MissingKeyError(); }, [cacheKey]); const refetchOrThrow = react.useCallback(async (aborter = new AbortController()) => { throw new core.MissingKeyError(); }, [cacheKey]); const updateOrThrow = react.useCallback(async (updater, aborter = new AbortController()) => { throw new core.MissingKeyError(); }, [cacheKey]); return { mutateOrThrow, deleteOrThrow, fetchOrThrow, refetchOrThrow, updateOrThrow }; } function useSimpleFetcherlessQuery(settings) { const settingsRef = ref.useRenderRef(settings); const cacheKey = react.useMemo(() => { return helper.Simple.getCacheKey(settings.key); }, [settings.key]); const [, setCounter] = react.useState(0); const stateRef = react.useRef(); const aborterRef = react.useRef(); react.useMemo(() => { stateRef.current = core.core.getStateSync(cacheKey); aborterRef.current = core.core.getAborterSync(cacheKey); }, [cacheKey]); const setState = react.useCallback((state) => { stateRef.current = state; setCounter(c => c + 1); }, [cacheKey]); const setAborter = react.useCallback((aborter) => { aborterRef.current = aborter; setCounter(c => c + 1); }, [cacheKey]); react.useEffect(() => { if (stateRef.current != null) return; core.core.getOrThrow(cacheKey, settingsRef.current).then(setState).catch(console.warn); }, [cacheKey]); react.useEffect(() => { const onState = () => { core.core.getOrThrow(cacheKey, settingsRef.current).then(setState).catch(console.warn); return new option.None(); }; const onAborter = () => { setAborter(core.core.getAborterSync(cacheKey)); return new option.None(); }; core.core.onState.on(cacheKey, onState, { passive: true }); core.core.onAborter.on(cacheKey, onAborter, { passive: true }); core.core.increment(cacheKey, settingsRef.current); return () => { core.core.decrementOrThrow(cacheKey, settingsRef.current); core.core.onState.off(cacheKey, onState); core.core.onAborter.off(cacheKey, onAborter); }; }, [cacheKey]); const mutateOrThrow = react.useCallback(async (mutator) => { return await core.core.mutateOrThrow(cacheKey, mutator, settingsRef.current); }, [cacheKey]); const deleteOrThrow = react.useCallback(async () => { return await core.core.deleteOrThrow(cacheKey, settingsRef.current); }, [cacheKey]); const fetchOrThrow = react.useCallback(async (init) => { throw new core.MissingFetcherError(); }, [cacheKey]); const refetchOrThrow = react.useCallback(async (init) => { throw new core.MissingFetcherError(); }, [cacheKey]); const updateOrThrow = react.useCallback(async (updater, init) => { throw new core.MissingFetcherError(); }, [cacheKey]); const state = stateRef.current; const aborter = aborterRef.current; const ready = state != null; const fetching = aborter != null; const optimistic = state?.isFake(); const current = state?.current; const data = state?.data; const error = state?.error; const real = state?.real; const fake = state?.fake; return { ...settings, cacheKey, current, data, error, real, fake, ready, optimistic, fetching, aborter, mutateOrThrow, fetchOrThrow, refetchOrThrow, updateOrThrow, deleteOrThrow, }; } function useSimpleFetcherfulQuery(settings) { const settingsRef = ref.useRenderRef(settings); const cacheKey = react.useMemo(() => { return helper.Simple.getCacheKey(settings.key); }, [settings.key]); const [, setCounter] = react.useState(0); const stateRef = react.useRef(); const aborterRef = react.useRef(); react.useMemo(() => { stateRef.current = core.core.getStateSync(cacheKey); aborterRef.current = core.core.getAborterSync(cacheKey); }, [cacheKey]); const setState = react.useCallback((state) => { stateRef.current = state; setCounter(c => c + 1); }, [cacheKey]); const setAborter = react.useCallback((aborter) => { aborterRef.current = aborter; setCounter(c => c + 1); }, [cacheKey]); react.useEffect(() => { if (stateRef.current != null) return; core.core.getOrThrow(cacheKey, settingsRef.current).then(setState).catch(console.warn); }, [cacheKey]); react.useEffect(() => { const onState = () => { core.core.getOrThrow(cacheKey, settingsRef.current).then(setState).catch(console.warn); return new option.None(); }; const onAborter = () => { setAborter(core.core.getAborterSync(cacheKey)); return new option.None(); }; core.core.onState.on(cacheKey, onState, { passive: true }); core.core.onAborter.on(cacheKey, onAborter, { passive: true }); core.core.increment(cacheKey, settingsRef.current); return () => { core.core.decrementOrThrow(cacheKey, settingsRef.current); core.core.onState.off(cacheKey, onState); core.core.onAborter.off(cacheKey, onAborter); }; }, [cacheKey]); const mutateOrThrow = react.useCallback(async (mutator) => { return await core.core.mutateOrThrow(cacheKey, mutator, settingsRef.current); }, [cacheKey]); const deleteOrThrow = react.useCallback(async () => { return await core.core.deleteOrThrow(cacheKey, settingsRef.current); }, [cacheKey]); const fetchOrThrow = react.useCallback(async (init) => { const state = stateRef.current; const settings = settingsRef.current; if (index.shouldUseCacheIfFresh(init?.cache) && time.Time.isAfterNow(state?.real?.current.cooldown)) return new result.Err(state); if (index.shouldUseCacheIfStale(init?.cache) && time.Time.isAfterNow(state?.real?.current.expiration)) return new result.Err(state); if (!index.shouldUseNetwork(init?.cache)) throw new Error(`Could not fetch using the provided cache directive`); const aborter = new AbortController(); const signal = AbortSignal.any([aborter.signal, index$1.AbortSignals.getOrNever(init?.signal)]); return new result.Ok(await core.core.runOrJoin(cacheKey, aborter, () => helper.Simple.fetchOrThrow(cacheKey, signal, settings))); }, [cacheKey]); const refetchOrThrow = react.useCallback(async (init) => { const state = stateRef.current; const settings = settingsRef.current; if (index.shouldUseCacheIfFresh(init?.cache) && time.Time.isAfterNow(state?.real?.current.cooldown)) return new result.Err(state); if (index.shouldUseCacheIfStale(init?.cache) && time.Time.isAfterNow(state?.real?.current.expiration)) return new result.Err(state); if (!index.shouldUseNetwork(init?.cache)) throw new Error(`Could not fetch using the provided cache directive`); const aborter = new AbortController(); const signal = AbortSignal.any([aborter.signal, index$1.AbortSignals.getOrNever(init?.signal)]); return new result.Ok(await core.core.runOrReplace(cacheKey, aborter, () => helper.Simple.fetchOrThrow(cacheKey, signal, settings))); }, [cacheKey]); const updateOrThrow = react.useCallback(async (updater, init) => { const state = stateRef.current; const settings = settingsRef.current; if (index.shouldUseCacheIfFresh(init?.cache) && time.Time.isAfterNow(state?.real?.current.cooldown)) return new result.Err(state); if (index.shouldUseCacheIfStale(init?.cache) && time.Time.isAfterNow(state?.real?.current.expiration)) return new result.Err(state); if (!index.shouldUseNetwork(init?.cache)) throw new Error(`Could not fetch using the provided cache directive`); const aborter = new AbortController(); const signal = AbortSignal.any([aborter.signal, index$1.AbortSignals.getOrNever(init?.signal)]); return new result.Ok(await helper.Simple.updateOrThrow(cacheKey, updater, signal, settings)); }, [cacheKey]); const state = stateRef.current; const aborter = aborterRef.current; const ready = state != null; const fetching = aborter != null; const optimistic = state?.isFake(); const current = state?.current; const data = state?.data; const error = state?.error; const real = state?.real; const fake = state?.fake; return { ...settings, cacheKey, current, data, error, real, fake, ready, optimistic, fetching, aborter, mutateOrThrow, fetchOrThrow, refetchOrThrow, updateOrThrow, deleteOrThrow, }; } exports.useQuery = useQuery; exports.useSimpleFetcherfulQuery = useSimpleFetcherfulQuery; exports.useSimpleFetcherlessQuery = useSimpleFetcherlessQuery; exports.useSimpleSkeletonQuery = useSimpleSkeletonQuery; //# sourceMappingURL=simple.cjs.map