swr-devtools
Version:
A React component for SWR DevTools
218 lines • 8.76 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSWRDevtools = exports.EventEmitter = void 0;
var swr_cache_1 = require("./swr-cache");
var serialize_1 = require("./swr/serialize");
var EventEmitter = /** @class */ (function () {
function EventEmitter() {
this.listeners = [];
}
EventEmitter.prototype.subscribe = function (fn) {
var _this = this;
this.listeners.push(fn);
return function () {
var index = _this.listeners.indexOf(fn);
_this.listeners.splice(index, 1);
};
};
EventEmitter.prototype.emit = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
this.listeners.forEach(function (fn) { return fn.apply(void 0, args); });
};
return EventEmitter;
}());
exports.EventEmitter = EventEmitter;
var debug = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
// console.log(...args);
};
var injected = new WeakSet();
var devToolsPanelIsOpen = false;
var inject = function (cache) {
return (0, swr_cache_1.injectSWRCache)(cache, function (key, value) {
if (devToolsPanelIsOpen) {
window.postMessage({
type: "updated_swr_cache",
payload: (0, swr_cache_1.serializePayload)({
key: key,
value: value,
}),
}, "*");
}
});
};
var noop = function () {
/* noop */
};
var dummyHooks = {
useLayoutEffect: noop,
useEffect: noop,
useRef: function (a) { return ({
current: a,
}); },
};
var createSWRDevtools = function () {
var events = new EventEmitter();
if (typeof window !== "undefined") {
window.addEventListener("message", function (e) {
var _a, _b, _c, _d, _e;
if (((_a = e.data) === null || _a === void 0 ? void 0 : _a.type) === "panelshow") {
devToolsPanelIsOpen = true;
}
else if (((_b = e.data) === null || _b === void 0 ? void 0 : _b.type) === "panelhide") {
devToolsPanelIsOpen = false;
}
else if (((_c = e.data) === null || _c === void 0 ? void 0 : _c.type) === "load") {
devToolsPanelIsOpen = (_e = (_d = e.data) === null || _d === void 0 ? void 0 : _d.payload) === null || _e === void 0 ? void 0 : _e.panelIsOpen;
}
});
}
// use the same React instance with the application
var _a = typeof window !== "undefined" &&
// @ts-expect-error
typeof window.__SWR_DEVTOOLS_REACT__ !== "undefined"
? // @ts-expect-error
window.__SWR_DEVTOOLS_REACT__
: dummyHooks, useLayoutEffect = _a.useLayoutEffect, useEffect = _a.useEffect, useRef = _a.useRef;
var swrdevtools = function (useSWRNext) { return function (key, fn, config) {
useLayoutEffect(function () {
window.postMessage({ type: "initialized" }, "*");
}, []);
// FIXME: I'll use mutate to support mutating from a devtool panel.
// const { cache /* , mutate */ } = useSWRConfig();
var cache = config.cache;
if (!injected.has(cache)) {
inject(cache);
injected.add(cache);
}
var requestIdRef = useRef(0);
var serializedKey = (0, serialize_1.serialize)(key);
useEffect(function () {
return function () {
if (!devToolsPanelIsOpen)
return;
// When the key changes or unmounts, ongoing requests should be discarded.
// This only affects React 17.
// https://github.com/vercel/swr/blob/bcc39321dd12133a0c42207ef4bdef7e214d9b1e/core/use-swr.ts#L245-L254
if (requestIdRef.current) {
events.emit("request_discarded", {
key: serializedKey,
id: requestIdRef.current,
});
window.postMessage({
type: "request_discarded",
payload: (0, swr_cache_1.serializePayload)({
key: serializedKey,
id: requestIdRef.current,
}),
}, "*");
}
};
}, [serializedKey]);
debug({ devToolsPanelIsOpen: devToolsPanelIsOpen });
// If DevToolsPanel is not opened, we don't do anything.
if (!devToolsPanelIsOpen) {
return useSWRNext(key, fn, config);
}
var wrappedFn = fn
? function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var id = ~~(Math.random() * 1e8);
events.emit("request_start", {
key: (0, serialize_1.serialize)(args[0]),
id: id,
});
window.postMessage({
type: "request_start",
payload: (0, swr_cache_1.serializePayload)({
key: (0, serialize_1.serialize)(args[0]),
id: id,
}),
}, "*");
try {
var res = fn.apply(void 0, args);
if (res && "then" in res && typeof res.then === "function") {
return res
.then(function (r) {
requestIdRef.current = id;
var payload = {
key: (0, serialize_1.serialize)(args[0]),
id: id,
data: r,
};
events.emit("request_success", payload);
window.postMessage({
type: "request_success",
payload: (0, swr_cache_1.serializePayload)(payload),
}, "*");
return r;
})
.catch(function (e) {
requestIdRef.current = id;
var payload = {
key: (0, serialize_1.serialize)(args[0]),
id: id,
error: e,
};
events.emit("request_error", payload);
window.postMessage({
type: "request_error",
payload: (0, swr_cache_1.serializePayload)(payload),
}, "*");
throw e;
});
}
requestIdRef.current = id;
return res;
}
catch (e) {
requestIdRef.current = id;
throw e;
}
}
: fn;
// FIXME: we should get the id of discarded fetcher request. requestIdRef is the latest id of ongoing requests
var onDiscarded = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
events.emit("request_discarded", {
key: (0, serialize_1.serialize)(args[0]),
id: requestIdRef.current,
});
window.postMessage({
type: "request_discarded",
payload: (0, swr_cache_1.serializePayload)({
key: (0, serialize_1.serialize)(args[0]),
id: requestIdRef.current,
}),
}, "*");
return config.onDiscarded ? config.onDiscarded.apply(null, args) : null;
};
return useSWRNext(key, wrappedFn, __assign(__assign({}, config), { onDiscarded: onDiscarded }));
}; };
return [swrdevtools, events];
};
exports.createSWRDevtools = createSWRDevtools;
//# sourceMappingURL=createSWRDevTools.js.map