@salesforce/pwa-kit-react-sdk 3.8.0-preview.0-basepath → 3.8.0-preview.0

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.
Files changed (52) hide show
  1. package/CHANGELOG.md +3 -7
  2. package/package.json +6 -5
  3. package/ssr/browser/main.js +130 -0
  4. package/ssr/browser/main.test.js +54 -0
  5. package/ssr/server/react-rendering.js +434 -0
  6. package/ssr/server/react-rendering.test.js +745 -0
  7. package/ssr/universal/compatibility.js +31 -0
  8. package/ssr/universal/components/_app/index.js +35 -0
  9. package/ssr/universal/components/_app/index.test.js +20 -0
  10. package/ssr/universal/components/_app-config/index.js +87 -0
  11. package/ssr/universal/components/_app-config/index.test.js +21 -0
  12. package/ssr/universal/components/_document/index.js +92 -0
  13. package/ssr/universal/components/_document/index.test.js +58 -0
  14. package/ssr/universal/components/_error/index.js +55 -0
  15. package/ssr/universal/components/_error/index.test.js +28 -0
  16. package/ssr/universal/components/app-error-boundary/index.js +113 -0
  17. package/ssr/universal/components/app-error-boundary/index.test.js +109 -0
  18. package/ssr/universal/components/fetch-strategy/index.js +42 -0
  19. package/ssr/universal/components/refresh/index.js +123 -0
  20. package/ssr/universal/components/refresh/index.test.js +78 -0
  21. package/ssr/universal/components/route-component/index.js +415 -0
  22. package/ssr/universal/components/route-component/index.test.js +378 -0
  23. package/ssr/universal/components/switch/index.js +62 -0
  24. package/ssr/universal/components/throw-404/index.js +36 -0
  25. package/ssr/universal/components/throw-404/index.test.js +26 -0
  26. package/ssr/universal/components/with-correlation-id/index.js +36 -0
  27. package/ssr/universal/components/with-legacy-get-props/index.js +100 -0
  28. package/ssr/universal/components/with-legacy-get-props/index.test.js +35 -0
  29. package/ssr/universal/components/with-react-query/index.js +130 -0
  30. package/ssr/universal/components/with-react-query/index.test.js +101 -0
  31. package/ssr/universal/contexts/index.js +72 -0
  32. package/ssr/universal/contexts/index.test.js +101 -0
  33. package/ssr/universal/errors.js +34 -0
  34. package/ssr/universal/errors.test.js +20 -0
  35. package/ssr/universal/events.js +38 -0
  36. package/ssr/universal/events.test.js +39 -0
  37. package/ssr/universal/hooks/index.js +84 -0
  38. package/ssr/universal/routes.js +15 -0
  39. package/ssr/universal/utils.client.test.js +46 -0
  40. package/ssr/universal/utils.js +61 -0
  41. package/ssr/universal/utils.server.test.js +24 -0
  42. package/utils/assets.js +120 -0
  43. package/utils/assets.test.js +106 -0
  44. package/utils/logger-instance.js +19 -0
  45. package/utils/performance.js +126 -0
  46. package/utils/performance.test.js +50 -0
  47. package/utils/url.js +41 -0
  48. package/utils/url.test.js +47 -0
  49. package/utils/uuidv4.client.js +21 -0
  50. package/utils/uuidv4.client.test.js +27 -0
  51. package/utils/warnings.js +81 -0
  52. package/utils/warnings.test.js +48 -0
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ var utils = _interopRequireWildcard(require("./utils"));
4
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
5
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
6
+ /*
7
+ * Copyright (c) 2021, salesforce.com, inc.
8
+ * All rights reserved.
9
+ * SPDX-License-Identifier: BSD-3-Clause
10
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
11
+ */
12
+
13
+ describe('getProxyConfigs (client-side)', () => {
14
+ const configs = [{
15
+ foo: 'bar'
16
+ }];
17
+ beforeEach(() => {
18
+ global.Progressive = {
19
+ ssrOptions: {
20
+ proxyConfigs: configs
21
+ }
22
+ };
23
+ });
24
+ afterEach(() => {
25
+ delete global.Progressive;
26
+ });
27
+ test('should return proxy configs set on window.Progressive', () => {
28
+ expect(utils.getProxyConfigs()).toEqual(configs);
29
+ });
30
+ });
31
+ describe('getAssetUrl (client-side)', () => {
32
+ beforeEach(() => {
33
+ global.Progressive = {
34
+ buildOrigin: 'test.com'
35
+ };
36
+ });
37
+ afterEach(() => {
38
+ delete global.Progressive;
39
+ });
40
+ test('should return build origin when path is undefined', () => {
41
+ expect(utils.getAssetUrl()).toBe('test.com');
42
+ });
43
+ test('should return origin + path', () => {
44
+ expect(utils.getAssetUrl('/path')).toBe('test.com/path');
45
+ });
46
+ });
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getProxyConfigs = exports.getAssetUrl = void 0;
7
+ var _ssrShared = require("@salesforce/pwa-kit-runtime/utils/ssr-shared");
8
+ var _ssrNamespacePaths = require("@salesforce/pwa-kit-runtime/utils/ssr-namespace-paths");
9
+ 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; }
10
+ 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; }
11
+ 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; }
12
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
13
+ 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); } /*
14
+ * Copyright (c) 2021, salesforce.com, inc.
15
+ * All rights reserved.
16
+ * SPDX-License-Identifier: BSD-3-Clause
17
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
18
+ */ /**
19
+ * @module progressive-web-sdk/ssr/universal/utils
20
+ */
21
+ const onClient = typeof window !== 'undefined';
22
+
23
+ /**
24
+ * Get the URL that should be used to load an asset from the bundle.
25
+ *
26
+ * @param {string} path - relative path from the build directory to the asset
27
+ * @function
28
+ * @returns {string}
29
+ */
30
+ const getAssetUrl = path => {
31
+ /* istanbul ignore next */
32
+ const publicPath = onClient ? `${window.Progressive.buildOrigin}` : `${_ssrNamespacePaths.bundleBasePath}/${process.env.BUNDLE_ID || 'development'}/`;
33
+ return path ? `${publicPath}${path}` : publicPath;
34
+ };
35
+
36
+ /**
37
+ * @typedef {Object} ProxyConfig
38
+ * @property {String} protocol - http or https
39
+ * @property {String} host - the hostname
40
+ * @property {String} path - the path element that follows "mobify/proxy"
41
+ */
42
+
43
+ /**
44
+ * Return the set of proxies configured for the app.
45
+ *
46
+ * The result is an array of objects, each of which has 'protocol'
47
+ * (either 'http' or 'https'), 'host' (the hostname) and 'path' (the
48
+ * path element that follows "/mobify/proxy/", defaulting to 'base' for
49
+ * the first proxy, and 'base2' for the next).
50
+ *
51
+ * @function
52
+ * @returns {Array<ProxyConfig>}
53
+ */
54
+ exports.getAssetUrl = getAssetUrl;
55
+ const getProxyConfigs = () => {
56
+ const configs = onClient ? (window.Progressive.ssrOptions || {}).proxyConfigs || [] : _ssrShared.proxyConfigs;
57
+
58
+ // Clone to avoid accidental mutation of important configuration variables.
59
+ return configs.map(config => _objectSpread({}, config));
60
+ };
61
+ exports.getProxyConfigs = getProxyConfigs;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ var utils = _interopRequireWildcard(require("./utils"));
4
+ var _ssrShared = require("@salesforce/pwa-kit-runtime/utils/ssr-shared");
5
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
6
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
7
+ /**
8
+ * @jest-environment node
9
+ */
10
+ /*
11
+ * Copyright (c) 2022, Salesforce, Inc.
12
+ * All rights reserved.
13
+ * SPDX-License-Identifier: BSD-3-Clause
14
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
15
+ */
16
+ // Jest requires the @jest-environment comment at the start of file, which
17
+ // conflicts with the eslint header rule.
18
+ /* eslint-disable header/header */
19
+
20
+ describe('getProxyConfigs (server-side)', () => {
21
+ test('should return the currently used proxy configs', () => {
22
+ expect(utils.getProxyConfigs()).toEqual(_ssrShared.proxyConfigs);
23
+ });
24
+ });
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.loadScript = void 0;
7
+ 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); }
8
+ /*
9
+ * Copyright (c) 2021, salesforce.com, inc.
10
+ * All rights reserved.
11
+ * SPDX-License-Identifier: BSD-3-Clause
12
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
13
+ */
14
+
15
+ /**
16
+ * loadScriptCounter is used as a key to the window.Mobify object handlers. We
17
+ * Want this outside the loadScript function so that it can be updated every
18
+ * loadScript is called with a new script to be embedded to the head tag.
19
+ * @private
20
+ */
21
+ let loadScriptCounter = 0;
22
+
23
+ /**
24
+ * Writes script tag to the document, head tag
25
+ * @function
26
+ * @param {string} id - The id for script
27
+ * @param {string} src - The path to script
28
+ * @param {boolean} isAsync=true - Writes an asynchronous function
29
+ * @param {boolean} docwrite=false - Writes a string of text to a document
30
+ * @param {function} onload - The onload callback function
31
+ * @param {boolean} onerror - Rejects the function
32
+ * @example
33
+ * import {loadScript} from '@salesforce/pwa-kit-react-sdk/utils/utils'
34
+ *
35
+ * loadScript({
36
+ * id: 'loadScriptTest1',
37
+ * src: 'loadScriptTest1src'
38
+ * })
39
+ */
40
+ const loadScript = ({
41
+ id,
42
+ src,
43
+ isAsync = true,
44
+ docwrite = false,
45
+ onload,
46
+ onerror
47
+ }) => {
48
+ const hasTriedLoadScript = ({
49
+ id,
50
+ src,
51
+ method
52
+ }) => {
53
+ const idQuery = id ? `[id="${id}"]` : '';
54
+ return document.querySelectorAll(`script${idQuery}` + `[src="${src}"]` + `[data-load-method="${method}"]`).length > 0;
55
+ };
56
+ const loadMethod = docwrite ? 'document.write()' : 'DOM';
57
+ if (hasTriedLoadScript({
58
+ id,
59
+ src,
60
+ method: loadMethod
61
+ })) {
62
+ console.warn(`[mobify.progressive] loadScript() already called for this script. Ignoring call. (method='${loadMethod}' id='${id}' src='${src}')`);
63
+ return;
64
+ }
65
+ if (onload && typeof onload !== 'function') {
66
+ throw new Error(`loadScript()'s 'onload' parameter must be a function but was passed a ${typeof onload}!`);
67
+ }
68
+ if (onerror && typeof onerror !== 'function') {
69
+ throw new Error(`loadScript()'s 'onerror' parameter must be a function but was passed a ${typeof onerror}!`);
70
+ }
71
+
72
+ // TODO: Check for navigator.connection. Need Android for this.
73
+ /* istanbul ignore next */
74
+ if (docwrite && document.readyState === 'loading') {
75
+ window.Mobify = window.Mobify || {};
76
+ let onLoadString = '';
77
+ let onErrorString = '';
78
+ if (typeof onload === 'function') {
79
+ window.Mobify.scriptOnLoads = _extends({}, window.Mobify.scriptOnLoads, {
80
+ [loadScriptCounter]: onload
81
+ });
82
+ // Space prefix is important for valid rendered HTML
83
+ onLoadString = ` onload="window.Mobify.scriptOnLoads['${loadScriptCounter}'] && window.Mobify.scriptOnLoads['${loadScriptCounter}']()"`;
84
+ }
85
+ if (typeof onerror === 'function') {
86
+ window.Mobify.scriptOnErrors = _extends({}, window.Mobify.scriptOnErrors, {
87
+ [loadScriptCounter]: onerror
88
+ });
89
+ // Space prefix is important for valid rendered HTML
90
+ onErrorString = ` onerror="window.Mobify.scriptOnErrors['${loadScriptCounter}'] && window.Mobify.scriptOnErrors['${loadScriptCounter}']()"`;
91
+ }
92
+ document.write(`<script id='${id}' src='${src}' data-load-method='${loadMethod}' charset='utf-8'${onLoadString}${onErrorString}></script>`);
93
+ loadScriptCounter++;
94
+ } else {
95
+ const script = document.createElement('script');
96
+
97
+ // Setting UTF-8 as our encoding ensures that certain strings (i.e.
98
+ // Japanese text) are not improperly converted to something else. We
99
+ // do this on the vendor scripts also just in case any libs we
100
+ // import have localized strings in them.
101
+ script.charset = 'utf-8';
102
+ script.async = isAsync;
103
+ if (id) {
104
+ script.id = id;
105
+ }
106
+ script.src = src;
107
+ script.dataset.loadMethod = loadMethod;
108
+
109
+ /* istanbul ignore next */
110
+ if (typeof onload === 'function') {
111
+ script.onload = onload;
112
+ }
113
+ /* istanbul ignore next */
114
+ if (typeof onerror === 'function') {
115
+ script.onerror = onerror;
116
+ }
117
+ document.getElementsByTagName('head')[0].appendChild(script);
118
+ }
119
+ };
120
+ exports.loadScript = loadScript;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+
3
+ var _assets = require("./assets");
4
+ var _sinon = _interopRequireDefault(require("sinon"));
5
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
6
+ /*
7
+ * Copyright (c) 2021, salesforce.com, inc.
8
+ * All rights reserved.
9
+ * SPDX-License-Identifier: BSD-3-Clause
10
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
11
+ */
12
+
13
+ const sandbox = _sinon.default.createSandbox();
14
+
15
+ // Silence the error messages, they're on purpose here
16
+ let consoleError;
17
+ beforeEach(() => {
18
+ consoleError = console.error;
19
+ console.error = jest.fn();
20
+ });
21
+ afterEach(() => {
22
+ console.error = consoleError;
23
+ sandbox.restore();
24
+ });
25
+ describe('loadScript', () => {
26
+ let fakeScriptElement;
27
+ const headElement = document.getElementsByTagName('head')[0];
28
+ const originalReadyState = document.readyState;
29
+ beforeEach(() => {
30
+ fakeScriptElement = {
31
+ id: null,
32
+ src: null,
33
+ async: null,
34
+ charset: null,
35
+ onload: null,
36
+ onerror: null,
37
+ dataset: {}
38
+ };
39
+
40
+ // Mock out createElement and body.appendChild so that we don't have
41
+ // to fetch an actual script
42
+ sandbox.stub(document, 'createElement').returns(fakeScriptElement);
43
+ sandbox.stub(headElement, 'appendChild');
44
+ sandbox.stub(document, 'write');
45
+ Object.defineProperty(document, 'readyState', {
46
+ value: 'loading',
47
+ writable: true
48
+ });
49
+
50
+ // If you need to actually see the logging from these modules,
51
+ // change these `.stub()` calls to `.spy()`. Tests won't be affected.
52
+ sandbox.stub(console, 'log');
53
+ sandbox.stub(console, 'warn');
54
+ });
55
+ afterAll(() => {
56
+ sandbox.restore();
57
+ document.readyState = originalReadyState;
58
+ });
59
+ test('loadScript defaults to using the DOM to load the script', () => {
60
+ (0, _assets.loadScript)({
61
+ id: 'loadScriptTest1',
62
+ src: 'loadScriptTest1src'
63
+ });
64
+ expect(document.createElement.called).toBe(true);
65
+ expect(headElement.appendChild.called).toBe(true);
66
+ const element = headElement.appendChild.getCall(0).args[0];
67
+ expect(element.id).toBe('loadScriptTest1');
68
+ expect(element.src).toBe('loadScriptTest1src');
69
+ });
70
+ test('loadScript uses document.write when the flag is enabled', () => {
71
+ (0, _assets.loadScript)({
72
+ id: 'loadScriptTest1',
73
+ src: 'loadScriptTest1src',
74
+ docwrite: true
75
+ });
76
+ expect(document.write.called).toBe(true);
77
+ });
78
+ test('loadScript aborts if it finds the requested script has already been attempted', () => {
79
+ sandbox.stub(document, 'querySelectorAll').returns([1]);
80
+ (0, _assets.loadScript)({
81
+ id: 'loadScriptTest1',
82
+ src: 'loadScriptTest1src'
83
+ });
84
+
85
+ // Shouldn't have tried either method of inserting the script
86
+ expect(document.createElement.called).toBe(false);
87
+ expect(headElement.appendChild.called).toBe(false);
88
+ expect(document.write.called).toBe(false);
89
+ });
90
+ test('loadScript throws if `onload` is provided but is not a function', () => {
91
+ expect(() => {
92
+ (0, _assets.loadScript)({
93
+ src: 'loadScriptTest2src',
94
+ onload: 'onload expects this to be a function'
95
+ });
96
+ }).toThrow();
97
+ });
98
+ test('loadScript throws if `onerror` is provided but is not a function', () => {
99
+ expect(() => {
100
+ (0, _assets.loadScript)({
101
+ src: 'loadScriptTest2src',
102
+ onerror: 'onerror expects this to be a function'
103
+ });
104
+ }).toThrow();
105
+ });
106
+ });
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _loggerFactory = _interopRequireDefault(require("@salesforce/pwa-kit-runtime/utils/logger-factory"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ /*
10
+ * Copyright (c) 2024, Salesforce, Inc.
11
+ * All rights reserved.
12
+ * SPDX-License-Identifier: BSD-3-Clause
13
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
14
+ */
15
+
16
+ const logger = Object.freeze((0, _loggerFactory.default)({
17
+ packageName: 'pwa-kit-react-sdk'
18
+ }));
19
+ var _default = exports.default = logger;
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.PERFORMANCE_MARKS = void 0;
7
+ var _loggerInstance = _interopRequireDefault(require("./logger-instance"));
8
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
+ /*
10
+ * Copyright (c) 2024, Salesforce, Inc.
11
+ * All rights reserved.
12
+ * SPDX-License-Identifier: BSD-3-Clause
13
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
14
+ */
15
+
16
+ const PERFORMANCE_MARKS = exports.PERFORMANCE_MARKS = {
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
+ };
26
+
27
+ /**
28
+ * This is an SDK internal class that is responsible for measuring server side performance.
29
+ *
30
+ * This class manages two types of performance marks: start and end.
31
+ *
32
+ * By default, this timer is disabled. Only certain environment variables and feature flags turns it on.
33
+ *
34
+ * @private
35
+ */
36
+ class PerformanceTimer {
37
+ MARKER_TYPES = {
38
+ START: 'start',
39
+ END: 'end'
40
+ };
41
+ constructor(options = {}) {
42
+ this.enabled = options.enabled || false;
43
+ this.marks = {
44
+ start: new Map(),
45
+ end: new Map()
46
+ };
47
+ this.metrics = [];
48
+ }
49
+
50
+ /**
51
+ * This is a utility function to build the Server-Timing header.
52
+ * The function receives an array of performance metrics and returns a string that represents the Server-Timing header.
53
+ *
54
+ * see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing
55
+ *
56
+ * @function
57
+ * @private
58
+ *
59
+ * @return {String}
60
+ */
61
+ buildServerTimingHeader() {
62
+ const header = this.metrics.map(metric => {
63
+ return `${metric.name};dur=${metric.duration}`;
64
+ }).join(', ');
65
+ return header;
66
+ }
67
+
68
+ /**
69
+ * A utility function to format and log the performance metrics.
70
+ *
71
+ * @function
72
+ * @private
73
+ */
74
+ log() {
75
+ this.metrics.forEach(metric => {
76
+ _loggerInstance.default.info(`${metric.name} - ${metric.duration}ms ${metric.detail || ''}`, {
77
+ namespace: 'performance'
78
+ });
79
+ });
80
+ }
81
+
82
+ /**
83
+ * This is a utility function to create performance marks.
84
+ * The data will be used in console logs and the http response header `server-timing`.
85
+ *
86
+ * @function
87
+ * @private
88
+ */
89
+ mark(name, type, options = {}) {
90
+ if (!this.enabled) {
91
+ return;
92
+ }
93
+ if (!name) {
94
+ _loggerInstance.default.warn('Performance mark cannot be created because the name is undefined.', {
95
+ namespace: 'performance'
96
+ });
97
+ return;
98
+ }
99
+ if (type !== this.MARKER_TYPES.START && type !== this.MARKER_TYPES.END) {
100
+ _loggerInstance.default.warn('Performance mark cannot be created because the type must be either "start" or "end".', {
101
+ namespace: 'performance'
102
+ });
103
+ return;
104
+ }
105
+ const timestamp = performance.now();
106
+ const isEnd = type === this.MARKER_TYPES.END;
107
+ const storage = isEnd ? this.marks.end : this.marks.start;
108
+ storage.set(name, {
109
+ name,
110
+ timestamp,
111
+ detail: options.detail
112
+ });
113
+ if (isEnd) {
114
+ const startMark = this.marks.start.get(name);
115
+ if (startMark) {
116
+ const measurement = {
117
+ name,
118
+ duration: (timestamp - startMark.timestamp).toFixed(2),
119
+ detail: options.detail
120
+ };
121
+ this.metrics.push(measurement);
122
+ }
123
+ }
124
+ }
125
+ }
126
+ exports.default = PerformanceTimer;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ var _performance = _interopRequireDefault(require("./performance"));
4
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
5
+ /**
6
+ * @jest-environment node
7
+ */
8
+ /*
9
+ * Copyright (c) 2024, Salesforce, Inc.
10
+ * All rights reserved.
11
+ * SPDX-License-Identifier: BSD-3-Clause
12
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
13
+ */
14
+ // The @jest-environment comment block *MUST* be the first line of the file for the tests to pass.
15
+ // That conflicts with the monorepo header rule, so we must disable the rule!
16
+ /* eslint-disable header/header */
17
+
18
+ describe('PerformanceTimer', () => {
19
+ test('is disabled by default', () => {
20
+ const timer = new _performance.default();
21
+ timer.mark('test', 'start');
22
+ expect(timer.marks.start.size).toBe(0);
23
+ });
24
+ test('can be enabled', () => {
25
+ const timer = new _performance.default({
26
+ enabled: true
27
+ });
28
+ timer.mark('test', 'start');
29
+ expect(timer.marks.start.size).toBe(1);
30
+ });
31
+ test('marks can be added for both types', () => {
32
+ const timer = new _performance.default({
33
+ enabled: true
34
+ });
35
+ timer.mark('test', 'start');
36
+ timer.mark('test', 'end');
37
+ expect(timer.marks.start.size).toBe(1);
38
+ expect(timer.marks.end.size).toBe(1);
39
+ });
40
+ test('measurements are created when a pair of marks is added', () => {
41
+ const timer = new _performance.default({
42
+ enabled: true
43
+ });
44
+ timer.mark('test', 'start');
45
+ timer.mark('test', 'end');
46
+ expect(timer.metrics).toHaveLength(1);
47
+ expect(timer.metrics[0].name).toBe('test');
48
+ expect(parseFloat(timer.metrics[0].duration)).toBeGreaterThan(0);
49
+ });
50
+ });
package/utils/url.js ADDED
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getAppOrigin = void 0;
7
+ /*
8
+ * Copyright (c) 2024, salesforce.com, inc.
9
+ * All rights reserved.
10
+ * SPDX-License-Identifier: BSD-3-Clause
11
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
12
+ */
13
+
14
+ /**
15
+ * Returns the application's origin.
16
+ *
17
+ * NOTE: This utility can only be used server-side after your application has been
18
+ * initialized using the `_createApp` method (This happens in your /app/ssr.js file).
19
+ *
20
+ * @function
21
+ * @deprecated use `useOrigin()` instead.
22
+ * This function will be removed in version 4.0.0.
23
+ * @returns {string} Returns the ORIGIN under which we are serving the page.
24
+ * @example
25
+ * import {getAppOrigin} from '@salesforce/pwa-kit-react-sdk/utils/url'
26
+ *
27
+ * const url = `${getAppOrigin()}/path`
28
+ */
29
+ const getAppOrigin = () => {
30
+ if (typeof window !== 'undefined') {
31
+ return window.location.origin;
32
+ }
33
+ const {
34
+ APP_ORIGIN
35
+ } = process.env;
36
+ if (!APP_ORIGIN) {
37
+ throw new Error(`Application is not initialized. Please ensure '_createApp' has been invoked before using this method.`);
38
+ }
39
+ return process.env.APP_ORIGIN;
40
+ };
41
+ exports.getAppOrigin = getAppOrigin;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ var _url = require("./url");
4
+ 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; }
5
+ 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; }
6
+ 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; }
7
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
8
+ 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
+ * Copyright (c) 2021, salesforce.com, inc.
10
+ * All rights reserved.
11
+ * SPDX-License-Identifier: BSD-3-Clause
12
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
13
+ */
14
+ describe('getAppOrigin', () => {
15
+ const OLD_ENV = process.env;
16
+ const OLD_WINDOW = global.window;
17
+ const TEST_ORIGIN = 'https://www.example.com';
18
+ beforeEach(() => {
19
+ jest.resetModules();
20
+ process.env = _objectSpread({}, OLD_ENV);
21
+ });
22
+ afterEach(() => {
23
+ process.env = OLD_ENV;
24
+ global.window = OLD_WINDOW;
25
+ });
26
+ test('returns `process.env.APP_ORIGIN` when on server', () => {
27
+ // Simulate being on the server by deleting the window.
28
+ delete global.window;
29
+
30
+ // Simulate starting the app server by simply setting the `APP_ORIGIN`
31
+ process.env.APP_ORIGIN = TEST_ORIGIN;
32
+ expect((0, _url.getAppOrigin)()).toBe(TEST_ORIGIN);
33
+ });
34
+ test('returns `window.location.origin` when on client', () => {
35
+ expect((0, _url.getAppOrigin)()).toBe('http://localhost');
36
+ });
37
+ test('throws error when APP_ORIGIN is not defined on server.', () => {
38
+ // Simulate being on the server by deleting the window.
39
+ delete global.window;
40
+
41
+ // Simulate app server not being initialized.
42
+ process.env.APP_ORIGIN = undefined;
43
+ expect(() => {
44
+ (0, _url.getAppOrigin)();
45
+ }).toThrow();
46
+ });
47
+ });
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.uuidv4 = uuidv4;
7
+ /*
8
+ * Copyright (c) 2022, salesforce.com, inc.
9
+ * All rights reserved.
10
+ * SPDX-License-Identifier: BSD-3-Clause
11
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
12
+ */
13
+
14
+ /**
15
+ * Simple implementation to create a uuid using crypto
16
+ * See: https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid
17
+ * @returns {*}
18
+ */
19
+ function uuidv4() {
20
+ return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
21
+ }