UNPKG

@apollo/client

Version:

A fully-featured caching GraphQL client.

222 lines 9.65 kB
var _a, _b; import { __assign, __awaiter, __extends, __generator } from "tslib"; import * as React from "react"; import { TextEncoder, TextDecoder } from "util"; (_a = global.TextEncoder) !== null && _a !== void 0 ? _a : (global.TextEncoder = TextEncoder); (_b = global.TextDecoder) !== null && _b !== void 0 ? _b : (global.TextDecoder = TextDecoder); import { RenderInstance } from "./Render.js"; import { applyStackTrace, captureStackTrace } from "./traces.js"; var _stackTrace = Symbol(); export function profile(_a) { var Component = _a.Component, onRender = _a.onRender, _b = _a.snapshotDOM, snapshotDOM = _b === void 0 ? false : _b, initialSnapshot = _a.initialSnapshot; var currentRender; var nextRender; var resolveNextRender; var rejectNextRender; var snapshotRef = { current: initialSnapshot }; var updateSnapshot = function (snap) { if (typeof snap === "function") { if (!initialSnapshot) { throw new Error("Cannot use a function to update the snapshot if no initial snapshot was provided."); } snapshotRef.current = snap(typeof snapshotRef.current === "object" ? __assign({}, snapshotRef.current) : snapshotRef.current); } else { snapshotRef.current = snap; } }; var profilerOnRender = function (id, phase, actualDuration, baseDuration, startTime, commitTime) { var baseRender = { id: id, phase: phase, actualDuration: actualDuration, baseDuration: baseDuration, startTime: startTime, commitTime: commitTime, count: Profiled.renders.length + 1, }; try { onRender === null || onRender === void 0 ? void 0 : onRender(__assign(__assign({}, baseRender), { updateSnapshot: updateSnapshot, snapshot: snapshotRef.current })); var snapshot = snapshotRef.current; var domSnapshot = snapshotDOM ? window.document.body.innerHTML : undefined; var render = new RenderInstance(baseRender, snapshot, domSnapshot); currentRender = render; Profiled.renders.push(render); resolveNextRender === null || resolveNextRender === void 0 ? void 0 : resolveNextRender(render); } catch (error) { Profiled.renders.push({ phase: "snapshotError", count: Profiled.renders.length, error: error, }); rejectNextRender === null || rejectNextRender === void 0 ? void 0 : rejectNextRender(error); } finally { nextRender = resolveNextRender = rejectNextRender = undefined; } }; var iteratorPosition = 0; var Profiled = Object.assign(function (props) { return (React.createElement(React.Profiler, { id: "test", onRender: profilerOnRender }, React.createElement(Component, __assign({}, props)))); }, { updateSnapshot: updateSnapshot, }, { renders: new Array(), currentRenderCount: function () { return Profiled.renders.length; }, peekRender: function (options) { if (options === void 0) { options = {}; } return __awaiter(this, void 0, void 0, function () { var render_1, render; var _a; return __generator(this, function (_b) { if (iteratorPosition < Profiled.renders.length) { render_1 = Profiled.renders[iteratorPosition]; if (render_1.phase === "snapshotError") { throw render_1.error; } return [2, render_1]; } render = Profiled.waitForNextRender(__assign((_a = {}, _a[_stackTrace] = captureStackTrace(Profiled.peekRender), _a), options)); return [2, render]; }); }); }, takeRender: function (options) { if (options === void 0) { options = {}; } return __awaiter(this, void 0, void 0, function () { var error, e_1; var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: error = undefined; _b.label = 1; case 1: _b.trys.push([1, 3, 4, 5]); return [4, Profiled.peekRender(__assign((_a = {}, _a[_stackTrace] = captureStackTrace(Profiled.takeRender), _a), options))]; case 2: return [2, _b.sent()]; case 3: e_1 = _b.sent(); error = e_1; throw e_1; case 4: if (!(error && error instanceof WaitForRenderTimeoutError)) { iteratorPosition++; } return [7]; case 5: return [2]; } }); }); }, getCurrentRender: function () { if (!currentRender) { throw new Error("Has not been rendered yet!"); } return currentRender; }, takeUntilRenderCount: function (count, optionsPerRender) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(Profiled.renders.length < count)) return [3, 2]; return [4, Profiled.takeRender(optionsPerRender)]; case 1: _a.sent(); return [3, 0]; case 2: return [2]; } }); }); }, waitForNextRender: function (_a) { var _b = _a === void 0 ? {} : _a, _c = _b.timeout, timeout = _c === void 0 ? 1000 : _c, _d = _stackTrace, _e = _b[_d], stackTrace = _e === void 0 ? captureStackTrace(Profiled.waitForNextRender) : _e; if (!nextRender) { nextRender = Promise.race([ new Promise(function (resolve, reject) { resolveNextRender = resolve; rejectNextRender = reject; }), new Promise(function (_, reject) { return setTimeout(function () { return reject(applyStackTrace(new WaitForRenderTimeoutError(), stackTrace)); }, timeout); }), ]); } return nextRender; }, }); return Profiled; } var WaitForRenderTimeoutError = (function (_super) { __extends(WaitForRenderTimeoutError, _super); function WaitForRenderTimeoutError() { var _newTarget = this.constructor; var _this = _super.call(this, "Exceeded timeout waiting for next render.") || this; Object.setPrototypeOf(_this, _newTarget.prototype); return _this; } return WaitForRenderTimeoutError; }(Error)); export { WaitForRenderTimeoutError }; export function profileHook(renderCallback) { var returnValue; var Component = function (props) { ProfiledComponent.updateSnapshot(renderCallback(props)); return null; }; var ProfiledComponent = profile({ Component: Component, onRender: function () { return returnValue; }, }); return Object.assign(function ProfiledHook(props) { return React.createElement(ProfiledComponent, __assign({}, props)); }, { ProfiledComponent: ProfiledComponent, }, { renders: ProfiledComponent.renders, currentSnapshotCount: ProfiledComponent.currentRenderCount, peekSnapshot: function (options) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, ProfiledComponent.peekRender(options)]; case 1: return [2, (_a.sent()).snapshot]; } }); }); }, takeSnapshot: function (options) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, ProfiledComponent.takeRender(options)]; case 1: return [2, (_a.sent()).snapshot]; } }); }); }, getCurrentSnapshot: function () { return ProfiledComponent.getCurrentRender().snapshot; }, takeUntilSnapshotCount: ProfiledComponent.takeUntilRenderCount, waitForNextSnapshot: function (options) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, ProfiledComponent.waitForNextRender(options)]; case 1: return [2, (_a.sent()).snapshot]; } }); }); }, }); } //# sourceMappingURL=profile.js.map