93 lines
3.4 KiB
JavaScript
93 lines
3.4 KiB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
var useSWR = require('../index/index.js');
|
|
var index_js = require('../_internal/index.js');
|
|
|
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
|
var useSWR__default = /*#__PURE__*/_interopDefault(useSWR);
|
|
|
|
const subscriptionStorage = new WeakMap();
|
|
const SUBSCRIPTION_PREFIX = '$sub$';
|
|
const subscription = (useSWRNext)=>(_key, subscribe, config)=>{
|
|
const [key, args] = index_js.serialize(_key);
|
|
// Prefix the key to avoid conflicts with other SWR resources.
|
|
const subscriptionKey = key ? SUBSCRIPTION_PREFIX + key : undefined;
|
|
const swr = useSWRNext(subscriptionKey, null, config);
|
|
const { cache } = config;
|
|
// Ensure that the subscription state is scoped by the cache boundary, so
|
|
// you can have multiple SWR zones with subscriptions having the same key.
|
|
if (!subscriptionStorage.has(cache)) {
|
|
subscriptionStorage.set(cache, [
|
|
new Map(),
|
|
new Map()
|
|
]);
|
|
}
|
|
const [subscriptions, disposers] = subscriptionStorage.get(cache);
|
|
index_js.useIsomorphicLayoutEffect(()=>{
|
|
if (!subscriptionKey) return;
|
|
const [, set] = index_js.createCacheHelper(cache, subscriptionKey);
|
|
const refCount = subscriptions.get(subscriptionKey) || 0;
|
|
const next = (error, data)=>{
|
|
if (error !== null && typeof error !== 'undefined') {
|
|
set({
|
|
error
|
|
});
|
|
} else {
|
|
set({
|
|
error: undefined
|
|
});
|
|
swr.mutate(data, false);
|
|
}
|
|
};
|
|
// Increment the ref count.
|
|
subscriptions.set(subscriptionKey, refCount + 1);
|
|
if (!refCount) {
|
|
const dispose = subscribe(args, {
|
|
next
|
|
});
|
|
if (typeof dispose !== 'function') {
|
|
throw new Error('The `subscribe` function must return a function to unsubscribe.');
|
|
}
|
|
disposers.set(subscriptionKey, dispose);
|
|
}
|
|
return ()=>{
|
|
const count = subscriptions.get(subscriptionKey) - 1;
|
|
subscriptions.set(subscriptionKey, count);
|
|
// Dispose if it's the last one.
|
|
if (!count) {
|
|
const dispose = disposers.get(subscriptionKey);
|
|
dispose == null ? void 0 : dispose();
|
|
}
|
|
};
|
|
}, [
|
|
subscriptionKey
|
|
]);
|
|
return {
|
|
get data () {
|
|
return swr.data;
|
|
},
|
|
get error () {
|
|
return swr.error;
|
|
}
|
|
};
|
|
};
|
|
/**
|
|
* A hook to subscribe a SWR resource to an external data source for continuous updates.
|
|
* @experimental This API is experimental and might change in the future.
|
|
* @example
|
|
* ```jsx
|
|
* import useSWRSubscription from 'swr/subscription'
|
|
*
|
|
* const { data, error } = useSWRSubscription(key, (key, { next }) => {
|
|
* const unsubscribe = dataSource.subscribe(key, (err, data) => {
|
|
* next(err, data)
|
|
* })
|
|
* return unsubscribe
|
|
* })
|
|
* ```
|
|
*/ const useSWRSubscription = index_js.withMiddleware(useSWR__default.default, subscription);
|
|
|
|
exports.default = useSWRSubscription;
|
|
exports.subscription = subscription;
|