UNPKG

swr-devtools

Version:

A React component for SWR DevTools

218 lines 8.76 kB
"use strict"; 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