@salesforce/pwa-kit-react-sdk 3.9.1 → 3.10.0-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +5 -5
- package/ssr/browser/main.test.js +2 -2
- package/ssr/server/react-rendering.js +4 -4
- package/ssr/universal/components/_app/index.test.js +1 -1
- package/ssr/universal/components/_document/index.test.js +1 -1
- package/ssr/universal/components/_error/index.test.js +1 -1
- package/ssr/universal/components/app-error-boundary/index.test.js +3 -3
- package/ssr/universal/components/redirect-with-status/index.js +2 -2
- package/ssr/universal/components/redirect-with-status/index.test.js +2 -2
- package/ssr/universal/components/refresh/index.test.js +5 -5
- package/ssr/universal/components/route-component/index.js +2 -2
- package/ssr/universal/components/route-component/index.test.js +11 -11
- package/ssr/universal/components/switch/index.js +2 -2
- package/ssr/universal/components/throw-404/index.test.js +1 -1
- package/ssr/universal/components/with-legacy-get-props/index.js +2 -2
- package/ssr/universal/components/with-legacy-get-props/index.test.js +1 -1
- package/ssr/universal/components/with-react-query/index.js +3 -3
- package/ssr/universal/components/with-react-query/index.test.js +111 -5
- package/ssr/universal/contexts/index.test.js +4 -4
- package/utils/performance.js +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## v3.10.0-dev (Feb 18, 2025)
|
|
2
|
+
- Fix the performance logging util to use the correct delimiter for the server-timing header. [#2225](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2295)
|
|
3
|
+
|
|
4
|
+
## v3.9.2 (Mar 07, 2025)
|
|
5
|
+
- Update PWA-Kit SDKs to v3.9.2 [#2304](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2304)
|
|
6
|
+
|
|
1
7
|
## v3.9.1 (Mar 05, 2025)
|
|
2
8
|
- Update PWA-Kit SDKs to v3.9.1 [#2301](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2301)
|
|
3
9
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/pwa-kit-react-sdk",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.0-dev",
|
|
4
4
|
"description": "A library that supports the isomorphic React rendering pipeline for Commerce Cloud Managed Runtime apps",
|
|
5
5
|
"homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/pwa-kit-react-sdk#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@loadable/babel-plugin": "^5.15.3",
|
|
38
38
|
"@loadable/server": "^5.15.3",
|
|
39
39
|
"@loadable/webpack-plugin": "^5.15.2",
|
|
40
|
-
"@salesforce/pwa-kit-runtime": "3.
|
|
40
|
+
"@salesforce/pwa-kit-runtime": "3.10.0-dev",
|
|
41
41
|
"@tanstack/react-query": "^4.28.0",
|
|
42
42
|
"cross-env": "^5.2.1",
|
|
43
43
|
"event-emitter": "^0.3.5",
|
|
@@ -50,11 +50,11 @@
|
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@loadable/component": "^5.15.3",
|
|
53
|
-
"@salesforce/pwa-kit-dev": "3.
|
|
53
|
+
"@salesforce/pwa-kit-dev": "3.10.0-dev",
|
|
54
54
|
"@testing-library/jest-dom": "^5.16.5",
|
|
55
55
|
"@testing-library/react": "^14.0.0",
|
|
56
56
|
"@testing-library/user-event": "^14.4.3",
|
|
57
|
-
"internal-lib-build": "3.
|
|
57
|
+
"internal-lib-build": "3.10.0-dev",
|
|
58
58
|
"node-html-parser": "^3.3.6",
|
|
59
59
|
"nodemon": "^2.0.22",
|
|
60
60
|
"react": "^18.2.0",
|
|
@@ -79,5 +79,5 @@
|
|
|
79
79
|
"publishConfig": {
|
|
80
80
|
"directory": "dist"
|
|
81
81
|
},
|
|
82
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "d86dc7bea3fe03a0f475ecf1a0ab878374f07026"
|
|
83
83
|
}
|
package/ssr/browser/main.test.js
CHANGED
|
@@ -32,7 +32,7 @@ describe('main', function () {
|
|
|
32
32
|
routes: (0, _routeComponent.getRoutes)(locals),
|
|
33
33
|
WrappedApp: (0, _routeComponent.routeComponent)(App, false, locals)
|
|
34
34
|
};
|
|
35
|
-
(0, _react2.render)(
|
|
35
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_main.OuterApp, props));
|
|
36
36
|
expect(_react2.screen.getByText('App')).toBeInTheDocument();
|
|
37
37
|
window.__PRELOADED_STATE__ = oldPreloadedState;
|
|
38
38
|
});
|
|
@@ -47,7 +47,7 @@ describe('main', function () {
|
|
|
47
47
|
routes: (0, _routeComponent.getRoutes)(locals),
|
|
48
48
|
WrappedApp: (0, _routeComponent.routeComponent)(App, false, locals)
|
|
49
49
|
};
|
|
50
|
-
(0, _react2.render)(
|
|
50
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_main.OuterApp, props));
|
|
51
51
|
expect(_react2.screen.getByText('Error Status: 404')).toBeInTheDocument();
|
|
52
52
|
window.__ERROR__ = oldWindowError;
|
|
53
53
|
});
|
|
@@ -122,7 +122,7 @@ exports.getLocationSearch = getLocationSearch;
|
|
|
122
122
|
const render = exports.render = /*#__PURE__*/function () {
|
|
123
123
|
var _ref = _asyncToGenerator(function* (req, res, next) {
|
|
124
124
|
var _config$app, _config$app$url;
|
|
125
|
-
const includeServerTimingHeader =
|
|
125
|
+
const includeServerTimingHeader = '__server_timing' in req.query;
|
|
126
126
|
const shouldTrackPerformance = includeServerTimingHeader || process.env.SERVER_TIMING;
|
|
127
127
|
res.__performanceTimer = new _performance.default({
|
|
128
128
|
enabled: shouldTrackPerformance
|
|
@@ -315,7 +315,7 @@ const renderApp = args => {
|
|
|
315
315
|
|
|
316
316
|
try {
|
|
317
317
|
routerContext = {};
|
|
318
|
-
appHtml = renderToString(
|
|
318
|
+
appHtml = renderToString(/*#__PURE__*/_react.default.cloneElement(appJSX, {
|
|
319
319
|
routerContext
|
|
320
320
|
}), extractor);
|
|
321
321
|
} catch (e) {
|
|
@@ -323,7 +323,7 @@ const renderApp = args => {
|
|
|
323
323
|
// to the AppErrorBoundary component, and renders the error page.
|
|
324
324
|
routerContext = {};
|
|
325
325
|
renderError = logAndFormatError(e);
|
|
326
|
-
appHtml = renderToString(
|
|
326
|
+
appHtml = renderToString(/*#__PURE__*/_react.default.cloneElement(appJSX, {
|
|
327
327
|
routerContext,
|
|
328
328
|
error: renderError
|
|
329
329
|
}), extractor);
|
|
@@ -384,7 +384,7 @@ const renderApp = args => {
|
|
|
384
384
|
}
|
|
385
385
|
})];
|
|
386
386
|
const helmetHeadTags = VALID_TAG_NAMES.map(tag => helmet[tag] && helmet[tag].toComponent()).filter(tag => tag);
|
|
387
|
-
const html = _server.default.renderToString(
|
|
387
|
+
const html = _server.default.renderToString(/*#__PURE__*/_react.default.createElement(_document.default, {
|
|
388
388
|
head: [...helmetHeadTags],
|
|
389
389
|
html: appHtml,
|
|
390
390
|
afterBodyStart: svgs,
|
|
@@ -14,7 +14,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
14
14
|
describe('App', () => {
|
|
15
15
|
test('Renders correctly', () => {
|
|
16
16
|
const body = /*#__PURE__*/_react.default.createElement("p", null, "Hello world");
|
|
17
|
-
(0, _react2.render)(
|
|
17
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_index.default, null, body));
|
|
18
18
|
expect(_react2.screen.getByText(/hello world/i)).toBeInTheDocument();
|
|
19
19
|
});
|
|
20
20
|
});
|
|
@@ -32,7 +32,7 @@ describe('Document', () => {
|
|
|
32
32
|
const htmlAttributes = {
|
|
33
33
|
lang: 'en'
|
|
34
34
|
};
|
|
35
|
-
(0, _react2.render)(
|
|
35
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_index.default, {
|
|
36
36
|
head: [style],
|
|
37
37
|
html: html,
|
|
38
38
|
afterBodyStart: [sprite],
|
|
@@ -16,7 +16,7 @@ describe('Error Page', () => {
|
|
|
16
16
|
const status = 500;
|
|
17
17
|
const message = 'Error message';
|
|
18
18
|
test('Renders correctly', () => {
|
|
19
|
-
(0, _react2.render)(
|
|
19
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_index.default, {
|
|
20
20
|
message: message,
|
|
21
21
|
stack: stack,
|
|
22
22
|
status: status
|
|
@@ -62,7 +62,7 @@ describe('AppErrorBoundary', () => {
|
|
|
62
62
|
}) => {
|
|
63
63
|
test(`Displays errors correctly (variation: ${variation})`, () => {
|
|
64
64
|
const ref = /*#__PURE__*/_react.default.createRef();
|
|
65
|
-
(0, _react2.render)(
|
|
65
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_index.AppErrorBoundaryWithoutRouter, {
|
|
66
66
|
ref: ref
|
|
67
67
|
}, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, content)));
|
|
68
68
|
expect(_react2.screen.getByText(content)).toBeInTheDocument();
|
|
@@ -77,7 +77,7 @@ describe('AppErrorBoundary', () => {
|
|
|
77
77
|
listen: _sinon.default.stub().returns(_sinon.default.stub())
|
|
78
78
|
};
|
|
79
79
|
const ref = /*#__PURE__*/_react.default.createRef();
|
|
80
|
-
(0, _react2.render)(
|
|
80
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_index.AppErrorBoundaryWithoutRouter, {
|
|
81
81
|
ref: ref,
|
|
82
82
|
history: history
|
|
83
83
|
}, /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, content)));
|
|
@@ -100,7 +100,7 @@ describe('AppErrorBoundary', () => {
|
|
|
100
100
|
const history = {
|
|
101
101
|
listen: jest.fn().mockReturnValue(unlisten)
|
|
102
102
|
};
|
|
103
|
-
const wrapper = (0, _react2.render)(
|
|
103
|
+
const wrapper = (0, _react2.render)(/*#__PURE__*/_react.default.createElement(_index.AppErrorBoundaryWithoutRouter, {
|
|
104
104
|
history: history
|
|
105
105
|
}, "test"));
|
|
106
106
|
wrapper.unmount();
|
|
@@ -15,8 +15,8 @@ const _excluded = ["status", "staticContext"];
|
|
|
15
15
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
16
16
|
*/
|
|
17
17
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
|
-
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], t.indexOf(o)
|
|
19
|
-
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n)
|
|
18
|
+
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
19
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
20
20
|
/**
|
|
21
21
|
* The `RedirectWithStatus` component is used to specify a different status code when redirecting via
|
|
22
22
|
* the Redirect component.
|
|
@@ -18,7 +18,7 @@ describe('RedirectWithStatus', () => {
|
|
|
18
18
|
const targetUrl = '/target';
|
|
19
19
|
const history = (0, _history.createMemoryHistory)();
|
|
20
20
|
history.push('/redirect');
|
|
21
|
-
(0, _react2.render)(
|
|
21
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_reactRouterDom.Router, {
|
|
22
22
|
history: history
|
|
23
23
|
}, /*#__PURE__*/_react.default.createElement(_reactRouterDom.Route, {
|
|
24
24
|
path: "/redirect"
|
|
@@ -31,7 +31,7 @@ describe('RedirectWithStatus', () => {
|
|
|
31
31
|
const context = {};
|
|
32
32
|
const status = 303;
|
|
33
33
|
const targetUrl = '/target';
|
|
34
|
-
(0, _react2.render)(
|
|
34
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_reactRouterDom.StaticRouter, {
|
|
35
35
|
location: "/redirect",
|
|
36
36
|
context: context
|
|
37
37
|
}, /*#__PURE__*/_react.default.createElement(_reactRouterDom.Route, {
|
|
@@ -35,11 +35,11 @@ jest.mock('@tanstack/react-query', () => {
|
|
|
35
35
|
};
|
|
36
36
|
});
|
|
37
37
|
test('renders a loading spinner initially', () => {
|
|
38
|
-
(0, _react.render)(
|
|
38
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(_index.default, null));
|
|
39
39
|
expect(_react.screen.getByTestId('loading-spinner')).toBeInTheDocument();
|
|
40
40
|
});
|
|
41
41
|
test('wait for react-query cache to be invalidated', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
42
|
-
(0, _react.render)(
|
|
42
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(_index.default, null));
|
|
43
43
|
yield (0, _react.waitFor)(() => {
|
|
44
44
|
expect((0, _reactQuery.useQueryClient)().invalidateQueries).toHaveBeenCalled();
|
|
45
45
|
});
|
|
@@ -49,7 +49,7 @@ test('a project not using react-query', /*#__PURE__*/_asyncToGenerator(function*
|
|
|
49
49
|
_reactQuery.useQueryClient.mockImplementationOnce(() => {
|
|
50
50
|
throw new Error();
|
|
51
51
|
});
|
|
52
|
-
(0, _react.render)(
|
|
52
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(_index.default, null));
|
|
53
53
|
jest.runAllTimers();
|
|
54
54
|
yield (0, _react.waitFor)(() => {
|
|
55
55
|
// Expect to still continue despite the project not using react-query,
|
|
@@ -58,7 +58,7 @@ test('a project not using react-query', /*#__PURE__*/_asyncToGenerator(function*
|
|
|
58
58
|
});
|
|
59
59
|
}));
|
|
60
60
|
test('wait for soft navigation to the referrer', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
61
|
-
(0, _react.render)(
|
|
61
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(_index.default, null));
|
|
62
62
|
jest.runAllTimers();
|
|
63
63
|
yield (0, _react.waitFor)(() => {
|
|
64
64
|
expect((0, _reactRouterDom.useHistory)().replace).toHaveBeenCalledWith(referrerURL);
|
|
@@ -69,7 +69,7 @@ test('navigate to homepage if `referrer` search param cannot be found in the pag
|
|
|
69
69
|
_reactRouterDom.useLocation.mockImplementationOnce(() => ({
|
|
70
70
|
search: ''
|
|
71
71
|
}));
|
|
72
|
-
(0, _react.render)(
|
|
72
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(_index.default, null));
|
|
73
73
|
jest.runAllTimers();
|
|
74
74
|
yield (0, _react.waitFor)(() => {
|
|
75
75
|
expect(console.warn).toHaveBeenCalled();
|
|
@@ -17,8 +17,8 @@ var _withLegacyGetProps = require("../../components/with-legacy-get-props");
|
|
|
17
17
|
var _refresh = _interopRequireDefault(require("../refresh"));
|
|
18
18
|
const _excluded = ["component"];
|
|
19
19
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
20
|
-
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], t.indexOf(o)
|
|
21
|
-
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n)
|
|
20
|
+
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
21
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
22
22
|
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
23
23
|
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
24
24
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
@@ -94,7 +94,7 @@ describe('The routeComponent component', () => {
|
|
|
94
94
|
test('Is a higher-order component', () => {
|
|
95
95
|
const Mock = getMockComponent();
|
|
96
96
|
const Component = (0, _index.routeComponent)(Mock);
|
|
97
|
-
(0, _react2.render)(
|
|
97
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(Component, {
|
|
98
98
|
isHydrating: false
|
|
99
99
|
}));
|
|
100
100
|
expect(_react2.screen.getByText(/mockComponent/i)).toBeInTheDocument();
|
|
@@ -112,7 +112,7 @@ describe('The routeComponent component', () => {
|
|
|
112
112
|
}).then(() => {
|
|
113
113
|
// Simulate the initial client-side mount (hydrating=true)
|
|
114
114
|
return new Promise(resolve => {
|
|
115
|
-
wrapper = (0, _react2.render)(
|
|
115
|
+
wrapper = (0, _react2.render)(/*#__PURE__*/_react.default.createElement(Component, {
|
|
116
116
|
history: {
|
|
117
117
|
location: {
|
|
118
118
|
pathname: '/home/'
|
|
@@ -130,7 +130,7 @@ describe('The routeComponent component', () => {
|
|
|
130
130
|
}).then(() => {
|
|
131
131
|
// Simulate visiting a different URL, which should trigger shouldMount() and getProps()
|
|
132
132
|
return new Promise(resolve => {
|
|
133
|
-
wrapper.rerender(
|
|
133
|
+
wrapper.rerender(/*#__PURE__*/_react.default.createElement(Component, {
|
|
134
134
|
history: {
|
|
135
135
|
location: {
|
|
136
136
|
pathname: '/plp/'
|
|
@@ -211,7 +211,7 @@ describe('The routeComponent component', () => {
|
|
|
211
211
|
throw error;
|
|
212
212
|
};
|
|
213
213
|
const Component = (0, _index.routeComponent)(Mock, {}, true);
|
|
214
|
-
return new Promise(resolve => (0, _react2.render)(
|
|
214
|
+
return new Promise(resolve => (0, _react2.render)(/*#__PURE__*/_react.default.createElement(Component, {
|
|
215
215
|
isHydrating: false,
|
|
216
216
|
onGetPropsError: resolve
|
|
217
217
|
}))).then(caught => expect(caught).toBe(error));
|
|
@@ -222,7 +222,7 @@ describe('The routeComponent component', () => {
|
|
|
222
222
|
Mock.shouldGetProps = trueOnceThenFalse();
|
|
223
223
|
Mock.getProps = () => delay(10).then(() => Promise.reject(errorText));
|
|
224
224
|
const Component = (0, _index.routeComponent)(Mock);
|
|
225
|
-
return new Promise(resolve => (0, _react2.render)(
|
|
225
|
+
return new Promise(resolve => (0, _react2.render)(/*#__PURE__*/_react.default.createElement(Component, {
|
|
226
226
|
isHydrating: false,
|
|
227
227
|
onGetPropsError: resolve
|
|
228
228
|
}))).then(caught => expect(caught).toBe(errorText));
|
|
@@ -239,7 +239,7 @@ describe('The routeComponent component', () => {
|
|
|
239
239
|
Mock.shouldGetProps = trueOnceThenFalse();
|
|
240
240
|
const Component = (0, _index.routeComponent)(Mock, {}, true);
|
|
241
241
|
yield new Promise(resolve => {
|
|
242
|
-
(0, _react2.render)(
|
|
242
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(Component, {
|
|
243
243
|
onUpdateComplete: () => {
|
|
244
244
|
resolve();
|
|
245
245
|
}
|
|
@@ -302,7 +302,7 @@ describe('Handles race conditions for getProps', () => {
|
|
|
302
302
|
};
|
|
303
303
|
yield new Promise(resolve => {
|
|
304
304
|
resolver.push(resolve);
|
|
305
|
-
wrapper = (0, _react2.render)(
|
|
305
|
+
wrapper = (0, _react2.render)(/*#__PURE__*/_react.default.createElement(Component, {
|
|
306
306
|
onUpdateComplete: onUpdateComplete
|
|
307
307
|
}));
|
|
308
308
|
});
|
|
@@ -311,13 +311,13 @@ describe('Handles race conditions for getProps', () => {
|
|
|
311
311
|
// twice, but only the later should call `setStateAsync` causing a re-render.
|
|
312
312
|
const p1 = new Promise(resolve => {
|
|
313
313
|
resolver.push(resolve);
|
|
314
|
-
wrapper.rerender(
|
|
314
|
+
wrapper.rerender(/*#__PURE__*/_react.default.createElement(Component, {
|
|
315
315
|
onUpdateComplete: onUpdateComplete
|
|
316
316
|
}));
|
|
317
317
|
});
|
|
318
318
|
const p2 = new Promise(resolve => {
|
|
319
319
|
resolver.push(resolve);
|
|
320
|
-
wrapper.rerender(
|
|
320
|
+
wrapper.rerender(/*#__PURE__*/_react.default.createElement(Component, {
|
|
321
321
|
onUpdateComplete: onUpdateComplete
|
|
322
322
|
}));
|
|
323
323
|
});
|
|
@@ -343,7 +343,7 @@ describe('Uses preloaded props on initial clientside page load', () => {
|
|
|
343
343
|
Mock.displayName = 'MockComponent';
|
|
344
344
|
const Component = (0, _index.routeComponent)(Mock, true, {});
|
|
345
345
|
yield new Promise(resolve => {
|
|
346
|
-
const wrapper = (0, _react2.render)(
|
|
346
|
+
const wrapper = (0, _react2.render)(/*#__PURE__*/_react.default.createElement(Component, {
|
|
347
347
|
preloadedProps: preloadedProps,
|
|
348
348
|
onUpdateComplete: () => resolve(wrapper)
|
|
349
349
|
}));
|
|
@@ -366,7 +366,7 @@ describe('Uses preloaded props on initial clientside page load', () => {
|
|
|
366
366
|
Mock.displayName = 'MockComponent';
|
|
367
367
|
const Component = (0, _index.routeComponent)(Mock, true, {});
|
|
368
368
|
yield new Promise(resolve => {
|
|
369
|
-
const wrapper = (0, _react2.render)(
|
|
369
|
+
const wrapper = (0, _react2.render)(/*#__PURE__*/_react.default.createElement(Component, {
|
|
370
370
|
preloadedProps: preloadedProps,
|
|
371
371
|
onUpdateComplete: () => resolve(wrapper)
|
|
372
372
|
}));
|
|
@@ -18,8 +18,8 @@ const _excluded = ["component"];
|
|
|
18
18
|
*/
|
|
19
19
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
20
20
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
21
|
-
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], t.indexOf(o)
|
|
22
|
-
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.indexOf(n)
|
|
21
|
+
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
22
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
23
23
|
/**
|
|
24
24
|
* The Switch component packages up the bits of rendering that are shared between
|
|
25
25
|
* server and client-side. It's *mostly* a react-router Switch component, hence the
|
|
@@ -16,7 +16,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
16
16
|
|
|
17
17
|
describe('Throw404', () => {
|
|
18
18
|
test('Renders correctly', () => {
|
|
19
|
-
(0, _react2.render)(
|
|
19
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_index.default, null));
|
|
20
20
|
const content = document.querySelector('body').firstElementChild.innerHTML;
|
|
21
21
|
expect(content).toBe('<div></div>');
|
|
22
22
|
});
|
|
@@ -49,7 +49,7 @@ const withLegacyGetProps = Wrapped => {
|
|
|
49
49
|
// to avoid blocking the execution of the getProps function to maximize performance
|
|
50
50
|
// getTemplateName should be very fast, under 0.2ms
|
|
51
51
|
c.getTemplateName().then(templateName => {
|
|
52
|
-
res.__performanceTimer.mark(`${_performance.PERFORMANCE_MARKS.getProps}
|
|
52
|
+
res.__performanceTimer.mark(`${_performance.PERFORMANCE_MARKS.getProps}.${templateName}`, 'start');
|
|
53
53
|
});
|
|
54
54
|
return c.getProps ? c.getProps({
|
|
55
55
|
req,
|
|
@@ -58,7 +58,7 @@ const withLegacyGetProps = Wrapped => {
|
|
|
58
58
|
location
|
|
59
59
|
}).then(result => {
|
|
60
60
|
c.getTemplateName().then(templateName => {
|
|
61
|
-
res.__performanceTimer.mark(`${_performance.PERFORMANCE_MARKS.getProps}
|
|
61
|
+
res.__performanceTimer.mark(`${_performance.PERFORMANCE_MARKS.getProps}.${templateName}`, 'end');
|
|
62
62
|
});
|
|
63
63
|
return result;
|
|
64
64
|
}) : Promise.resolve({});
|
|
@@ -15,7 +15,7 @@ describe('withLegacyGetProps', function () {
|
|
|
15
15
|
test('Renders correctly', () => {
|
|
16
16
|
const Wrapped = () => /*#__PURE__*/_react2.default.createElement("p", null, "Hello world");
|
|
17
17
|
const Component = (0, _index.withLegacyGetProps)(Wrapped);
|
|
18
|
-
(0, _react.render)(
|
|
18
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(Component, {
|
|
19
19
|
locals: {}
|
|
20
20
|
}));
|
|
21
21
|
expect(_react.screen.getByText(/Hello world/i)).toBeInTheDocument();
|
|
@@ -83,10 +83,10 @@ const withReactQuery = (Wrapped, options = {}) => {
|
|
|
83
83
|
yield Promise.all(queries.map((q, i) => {
|
|
84
84
|
var _q$meta, _q$meta2;
|
|
85
85
|
// always include the index to avoid duplicate entries
|
|
86
|
-
const displayName = (_q$meta = q.meta) !== null && _q$meta !== void 0 && _q$meta.displayName ? `${(_q$meta2 = q.meta) === null || _q$meta2 === void 0 ? void 0 : _q$meta2.displayName}
|
|
87
|
-
res.__performanceTimer.mark(`${_performance.PERFORMANCE_MARKS.reactQueryUseQuery}
|
|
86
|
+
const displayName = (_q$meta = q.meta) !== null && _q$meta !== void 0 && _q$meta.displayName ? `${(_q$meta2 = q.meta) === null || _q$meta2 === void 0 ? void 0 : _q$meta2.displayName}-${i}` : `${i}`;
|
|
87
|
+
res.__performanceTimer.mark(`${_performance.PERFORMANCE_MARKS.reactQueryUseQuery}.${displayName}`, 'start');
|
|
88
88
|
return q.fetch().then(result => {
|
|
89
|
-
res.__performanceTimer.mark(`${_performance.PERFORMANCE_MARKS.reactQueryUseQuery}
|
|
89
|
+
res.__performanceTimer.mark(`${_performance.PERFORMANCE_MARKS.reactQueryUseQuery}.${displayName}`, 'end', {
|
|
90
90
|
detail: q.queryHash
|
|
91
91
|
});
|
|
92
92
|
return result;
|
|
@@ -4,14 +4,23 @@ var _index = require("./index");
|
|
|
4
4
|
var _react = require("@testing-library/react");
|
|
5
5
|
var _react2 = _interopRequireDefault(require("react"));
|
|
6
6
|
var _loggerInstance = _interopRequireDefault(require("../../../../utils/logger-instance"));
|
|
7
|
+
var _performance = require("../../../../utils/performance");
|
|
7
8
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
-
|
|
9
|
+
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
10
|
+
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
11
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
12
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
13
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
14
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
15
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /*
|
|
9
16
|
* Copyright (c) 2022, Salesforce, Inc.
|
|
10
17
|
* All rights reserved.
|
|
11
18
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
12
19
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
13
20
|
*/
|
|
14
|
-
|
|
21
|
+
jest.mock('@tanstack/react-query', () => _objectSpread(_objectSpread({}, jest.requireActual('@tanstack/react-query')), {}, {
|
|
22
|
+
dehydrate: jest.fn().mockReturnValue({})
|
|
23
|
+
}));
|
|
15
24
|
jest.mock('../../../../utils/logger-instance', () => {
|
|
16
25
|
return {
|
|
17
26
|
error: jest.fn()
|
|
@@ -32,7 +41,7 @@ describe('withReactQuery', function () {
|
|
|
32
41
|
test('Renders correctly', () => {
|
|
33
42
|
const Wrapped = () => /*#__PURE__*/_react2.default.createElement("p", null, "Hello world");
|
|
34
43
|
const Component = (0, _index.withReactQuery)(Wrapped);
|
|
35
|
-
(0, _react.render)(
|
|
44
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(Component, {
|
|
36
45
|
locals: {}
|
|
37
46
|
}));
|
|
38
47
|
expect(_react.screen.getByText(/Hello world/i)).toBeInTheDocument();
|
|
@@ -49,7 +58,7 @@ describe('withReactQuery', function () {
|
|
|
49
58
|
window.__PRELOADED_STATE__ = {
|
|
50
59
|
__reactQuery: mockPreloadedState
|
|
51
60
|
};
|
|
52
|
-
(0, _react.render)(
|
|
61
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(Component, {
|
|
53
62
|
locals: {}
|
|
54
63
|
}));
|
|
55
64
|
expect(_react.screen.getByText(/Hello world/i)).toBeInTheDocument();
|
|
@@ -72,7 +81,7 @@ describe('withReactQuery', function () {
|
|
|
72
81
|
__reactQuery: mockPreloadedState
|
|
73
82
|
};
|
|
74
83
|
_loggerInstance.default.error = jest.fn();
|
|
75
|
-
(0, _react.render)(
|
|
84
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(Component, {
|
|
76
85
|
locals: {}
|
|
77
86
|
}));
|
|
78
87
|
expect(_react.screen.getByText(/Hello world/i)).toBeInTheDocument();
|
|
@@ -98,4 +107,101 @@ describe('withReactQuery', function () {
|
|
|
98
107
|
getHOCsInUse: () => ['xyz']
|
|
99
108
|
}).getHOCsInUse()).toHaveLength(2);
|
|
100
109
|
});
|
|
110
|
+
test('Performance markers use hyphen as delimiter for displayName', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
111
|
+
const mockPerformanceTimer = {
|
|
112
|
+
mark: jest.fn()
|
|
113
|
+
};
|
|
114
|
+
const mockQueryMeta = {
|
|
115
|
+
displayName: 'TestQuery'
|
|
116
|
+
};
|
|
117
|
+
const mockQueryCache = {
|
|
118
|
+
getAll: jest.fn().mockReturnValue([{
|
|
119
|
+
options: {
|
|
120
|
+
enabled: true
|
|
121
|
+
},
|
|
122
|
+
meta: mockQueryMeta,
|
|
123
|
+
queryHash: 'test-hash',
|
|
124
|
+
fetch: jest.fn().mockResolvedValue({})
|
|
125
|
+
}])
|
|
126
|
+
};
|
|
127
|
+
const mockQueryClient = {
|
|
128
|
+
getQueryCache: jest.fn().mockReturnValue(mockQueryCache)
|
|
129
|
+
};
|
|
130
|
+
const res = {
|
|
131
|
+
locals: {
|
|
132
|
+
__queryClient: mockQueryClient
|
|
133
|
+
},
|
|
134
|
+
__performanceTimer: mockPerformanceTimer
|
|
135
|
+
};
|
|
136
|
+
const Component = (0, _index.withReactQuery)({});
|
|
137
|
+
yield Component.doInitAppState({
|
|
138
|
+
res,
|
|
139
|
+
appJSX: /*#__PURE__*/_react2.default.createElement("div", null, "Test")
|
|
140
|
+
});
|
|
141
|
+
expect(mockPerformanceTimer.mark).toHaveBeenCalledWith(`${_performance.PERFORMANCE_MARKS.reactQueryUseQuery}.TestQuery-0`, 'start');
|
|
142
|
+
expect(mockPerformanceTimer.mark).toHaveBeenCalledWith(`${_performance.PERFORMANCE_MARKS.reactQueryUseQuery}.TestQuery-0`, 'end', expect.objectContaining({
|
|
143
|
+
detail: 'test-hash'
|
|
144
|
+
}));
|
|
145
|
+
}));
|
|
146
|
+
test('Performance markers use index as displayName when meta.displayName is not available', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
147
|
+
const mockPerformanceTimer = {
|
|
148
|
+
mark: jest.fn()
|
|
149
|
+
};
|
|
150
|
+
const mockQueryCache = {
|
|
151
|
+
getAll: jest.fn().mockReturnValue([{
|
|
152
|
+
options: {
|
|
153
|
+
enabled: true
|
|
154
|
+
},
|
|
155
|
+
meta: {},
|
|
156
|
+
queryHash: 'test-hash',
|
|
157
|
+
fetch: jest.fn().mockResolvedValue({})
|
|
158
|
+
}])
|
|
159
|
+
};
|
|
160
|
+
const mockQueryClient = {
|
|
161
|
+
getQueryCache: jest.fn().mockReturnValue(mockQueryCache)
|
|
162
|
+
};
|
|
163
|
+
const res = {
|
|
164
|
+
locals: {
|
|
165
|
+
__queryClient: mockQueryClient
|
|
166
|
+
},
|
|
167
|
+
__performanceTimer: mockPerformanceTimer
|
|
168
|
+
};
|
|
169
|
+
const Component = (0, _index.withReactQuery)({});
|
|
170
|
+
yield Component.doInitAppState({
|
|
171
|
+
res,
|
|
172
|
+
appJSX: /*#__PURE__*/_react2.default.createElement("div", null, "Test")
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Verify the performance marker uses just the index when no displayName is available
|
|
176
|
+
expect(mockPerformanceTimer.mark).toHaveBeenCalledWith(`${_performance.PERFORMANCE_MARKS.reactQueryUseQuery}.0`, 'start');
|
|
177
|
+
expect(mockPerformanceTimer.mark).toHaveBeenCalledWith(`${_performance.PERFORMANCE_MARKS.reactQueryUseQuery}.0`, 'end', expect.objectContaining({
|
|
178
|
+
detail: 'test-hash'
|
|
179
|
+
}));
|
|
180
|
+
}));
|
|
181
|
+
test('Performance markers for reactQueryPrerender are set correctly', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
182
|
+
const mockPerformanceTimer = {
|
|
183
|
+
mark: jest.fn()
|
|
184
|
+
};
|
|
185
|
+
const mockQueryCache = {
|
|
186
|
+
getAll: jest.fn().mockReturnValue([])
|
|
187
|
+
};
|
|
188
|
+
const mockQueryClient = {
|
|
189
|
+
getQueryCache: jest.fn().mockReturnValue(mockQueryCache)
|
|
190
|
+
};
|
|
191
|
+
const res = {
|
|
192
|
+
locals: {
|
|
193
|
+
__queryClient: mockQueryClient
|
|
194
|
+
},
|
|
195
|
+
__performanceTimer: mockPerformanceTimer
|
|
196
|
+
};
|
|
197
|
+
const Component = (0, _index.withReactQuery)({});
|
|
198
|
+
yield Component.doInitAppState({
|
|
199
|
+
res,
|
|
200
|
+
appJSX: /*#__PURE__*/_react2.default.createElement("div", null, "Test")
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Verify the performance markers for reactQueryPrerender are set correctly
|
|
204
|
+
expect(mockPerformanceTimer.mark).toHaveBeenCalledWith(_performance.PERFORMANCE_MARKS.reactQueryPrerender, 'start');
|
|
205
|
+
expect(mockPerformanceTimer.mark).toHaveBeenCalledWith(_performance.PERFORMANCE_MARKS.reactQueryPrerender, 'end');
|
|
206
|
+
}));
|
|
101
207
|
});
|
|
@@ -44,7 +44,7 @@ describe('CorrelationIdProvider', function () {
|
|
|
44
44
|
test('Renders without errors', () => {
|
|
45
45
|
const history = (0, _history.createMemoryHistory)();
|
|
46
46
|
const id = _crypto.default.randomUUID();
|
|
47
|
-
(0, _react2.render)(
|
|
47
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_reactRouterDom.Router, {
|
|
48
48
|
history: history
|
|
49
49
|
}, /*#__PURE__*/_react.default.createElement(SampleProvider, {
|
|
50
50
|
correlationId: () => id
|
|
@@ -54,7 +54,7 @@ describe('CorrelationIdProvider', function () {
|
|
|
54
54
|
test('renders when correlationId is passed as a function', () => {
|
|
55
55
|
const id = _crypto.default.randomUUID();
|
|
56
56
|
const history = (0, _history.createMemoryHistory)();
|
|
57
|
-
(0, _react2.render)(
|
|
57
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_reactRouterDom.Router, {
|
|
58
58
|
history: history
|
|
59
59
|
}, /*#__PURE__*/_react.default.createElement(SampleProvider, {
|
|
60
60
|
correlationId: () => id
|
|
@@ -64,7 +64,7 @@ describe('CorrelationIdProvider', function () {
|
|
|
64
64
|
test('renders when correlationId is passed as a string', () => {
|
|
65
65
|
const id = _crypto.default.randomUUID();
|
|
66
66
|
const history = (0, _history.createMemoryHistory)();
|
|
67
|
-
(0, _react2.render)(
|
|
67
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_reactRouterDom.Router, {
|
|
68
68
|
history: history
|
|
69
69
|
}, /*#__PURE__*/_react.default.createElement(SampleProvider, {
|
|
70
70
|
correlationId: id,
|
|
@@ -86,7 +86,7 @@ describe('CorrelationIdProvider', function () {
|
|
|
86
86
|
onClick: () => history.push('/page-1')
|
|
87
87
|
}, "Go to another page"));
|
|
88
88
|
};
|
|
89
|
-
(0, _react2.render)(
|
|
89
|
+
(0, _react2.render)(/*#__PURE__*/_react.default.createElement(_reactRouterDom.Router, {
|
|
90
90
|
history: history
|
|
91
91
|
}, /*#__PURE__*/_react.default.createElement(SampleProvider, {
|
|
92
92
|
correlationId: () => _crypto.default.randomUUID()
|
package/utils/performance.js
CHANGED
|
@@ -14,14 +14,14 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
const PERFORMANCE_MARKS = exports.PERFORMANCE_MARKS = {
|
|
17
|
-
total: 'ssr
|
|
18
|
-
renderToString: 'ssr
|
|
19
|
-
routeMatching: 'ssr
|
|
20
|
-
loadComponent: 'ssr
|
|
21
|
-
fetchStrategies: 'ssr
|
|
22
|
-
reactQueryPrerender: 'ssr
|
|
23
|
-
reactQueryUseQuery: 'ssr
|
|
24
|
-
getProps: 'ssr
|
|
17
|
+
total: 'ssr.total',
|
|
18
|
+
renderToString: 'ssr.render-to-string',
|
|
19
|
+
routeMatching: 'ssr.route-matching',
|
|
20
|
+
loadComponent: 'ssr.load-component',
|
|
21
|
+
fetchStrategies: 'ssr.fetch-strategies',
|
|
22
|
+
reactQueryPrerender: 'ssr.fetch-strategies.react-query.pre-render',
|
|
23
|
+
reactQueryUseQuery: 'ssr.fetch-strategies.react-query.use-query',
|
|
24
|
+
getProps: 'ssr.fetch-strategies.get-prop'
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
/**
|