@salesforce/pwa-kit-react-sdk 4.0.0-extensibility-preview.2 → 4.0.0-extensibility-preview.4

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 (41) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/package.json +10 -10
  3. package/ssr/browser/main.d.ts.map +1 -1
  4. package/ssr/browser/main.js +7 -3
  5. package/ssr/browser/main.test.js +8 -8
  6. package/ssr/server/react-rendering.d.ts.map +1 -1
  7. package/ssr/server/react-rendering.js +22 -5
  8. package/ssr/server/react-rendering.test.js +23 -0
  9. package/ssr/universal/components/redirect-with-status/index.d.ts +3 -0
  10. package/ssr/universal/components/redirect-with-status/index.d.ts.map +1 -0
  11. package/ssr/universal/components/redirect-with-status/index.js +46 -0
  12. package/ssr/universal/components/redirect-with-status/index.test.js +46 -0
  13. package/ssr/universal/components/route-component/index.d.ts +1 -1
  14. package/ssr/universal/components/route-component/index.d.ts.map +1 -1
  15. package/ssr/universal/components/route-component/index.js +41 -39
  16. package/ssr/universal/components/route-component/index.test.js +4 -4
  17. package/ssr/universal/components/switch/index.d.ts.map +1 -1
  18. package/ssr/universal/components/switch/index.js +28 -11
  19. package/ssr/universal/components/with-legacy-get-props/index.js +2 -2
  20. package/ssr/universal/components/with-react-query/index.js +3 -3
  21. package/ssr/universal/components/with-react-query/index.test.js +108 -2
  22. package/ssr/universal/contexts/index.d.ts +18 -0
  23. package/ssr/universal/contexts/index.d.ts.map +1 -1
  24. package/ssr/universal/contexts/index.js +25 -1
  25. package/ssr/universal/contexts/index.test.js +26 -0
  26. package/ssr/universal/errors.d.ts +6 -10
  27. package/ssr/universal/errors.d.ts.map +1 -1
  28. package/ssr/universal/errors.js +0 -5
  29. package/ssr/universal/events.d.ts +1 -1
  30. package/ssr/universal/events.d.ts.map +1 -1
  31. package/ssr/universal/events.js +7 -6
  32. package/ssr/universal/events.test.js +4 -4
  33. package/ssr/universal/hooks/index.d.ts +4 -0
  34. package/ssr/universal/hooks/index.d.ts.map +1 -1
  35. package/ssr/universal/hooks/index.js +49 -3
  36. package/ssr/universal/utils.d.ts +1 -1
  37. package/ssr/universal/utils.d.ts.map +1 -1
  38. package/ssr/universal/utils.js +8 -7
  39. package/utils/performance.js +11 -11
  40. package/utils/url.d.ts.map +1 -1
  41. package/utils/url.js +3 -1
@@ -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}::${templateName}`, 'start');
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}::${templateName}`, 'end');
61
+ res.__performanceTimer.mark(`${_performance.PERFORMANCE_MARKS.getProps}.${templateName}`, 'end');
62
62
  });
63
63
  return result;
64
64
  }) : Promise.resolve({});
@@ -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}:${i}` : `${i}`;
87
- res.__performanceTimer.mark(`${_performance.PERFORMANCE_MARKS.reactQueryUseQuery}::${displayName}`, 'start');
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}::${displayName}`, 'end', {
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()
@@ -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
  });
@@ -21,6 +21,24 @@ export namespace CorrelationIdProvider {
21
21
  }
22
22
  }
23
23
  export const ServerContext: React.Context<any>;
24
+ export const RoutesContext: React.Context<any>;
25
+ /**
26
+ * This provider initializes the routes
27
+ * @param children
28
+ * @param routes - array of routes
29
+ */
30
+ export function RoutesProvider({ routes, children }: {
31
+ routes: any;
32
+ children: any;
33
+ }): import("react/jsx-runtime").JSX.Element;
34
+ export namespace RoutesProvider {
35
+ export namespace propTypes_1 {
36
+ export const routes: PropTypes.Validator<any[]>;
37
+ const children_1: PropTypes.Validator<NonNullable<PropTypes.ReactNodeLike>>;
38
+ export { children_1 as children };
39
+ }
40
+ export { propTypes_1 as propTypes };
41
+ }
24
42
  import React from "react";
25
43
  import PropTypes from "prop-types";
26
44
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ssr/universal/contexts/index.js"],"names":[],"mappings":"AAYA,sDAAkD;AAGlD;;;;;;;GAOG;AACH;;;;4CAiCC;;;;;;;;;AA3CD,+CAA2C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ssr/universal/contexts/index.js"],"names":[],"mappings":"AAYA,sDAAkD;AAGlD;;;;;;;GAOG;AACH;;;;4CAiCC;;;;;;;;;AA3CD,+CAA2C;AAoD3C,+CAA2C;AAE3C;;;;GAIG;AACH;;;4CAQC"}
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.ServerContext = exports.CorrelationIdProvider = exports.CorrelationIdContext = void 0;
6
+ exports.ServerContext = exports.RoutesProvider = exports.RoutesContext = exports.CorrelationIdProvider = exports.CorrelationIdContext = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _reactRouterDom = require("react-router-dom");
@@ -69,4 +69,28 @@ CorrelationIdProvider.propTypes = {
69
69
  resetOnPageChange: _propTypes.default.bool,
70
70
  correlationId: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.func]).isRequired,
71
71
  location: _propTypes.default.object
72
+ };
73
+ const RoutesContext = exports.RoutesContext = /*#__PURE__*/_react.default.createContext();
74
+
75
+ /**
76
+ * This provider initializes the routes
77
+ * @param children
78
+ * @param routes - array of routes
79
+ */
80
+ const RoutesProvider = ({
81
+ routes,
82
+ children
83
+ }) => {
84
+ const [_routes, setRoutes] = (0, _react.useState)(routes);
85
+ return /*#__PURE__*/_react.default.createElement(RoutesContext.Provider, {
86
+ value: {
87
+ routes: _routes,
88
+ setRoutes
89
+ }
90
+ }, children);
91
+ };
92
+ exports.RoutesProvider = RoutesProvider;
93
+ RoutesProvider.propTypes = {
94
+ routes: _propTypes.default.array.isRequired,
95
+ children: _propTypes.default.node.isRequired
72
96
  };
@@ -98,4 +98,30 @@ describe('CorrelationIdProvider', function () {
98
98
  // expecting the provider to have a different correlation id when a page navigation happens
99
99
  expect(firstRenderedId).not.toEqual(secondRenderedId);
100
100
  }));
101
+ });
102
+ describe('RoutesProvider', () => {
103
+ it('provides routes via context', () => {
104
+ const testRoutes = [{
105
+ path: '/home'
106
+ }, {
107
+ path: '/about'
108
+ }];
109
+ const TestComponent = () => {
110
+ const {
111
+ routes
112
+ } = (0, _hooks.useRoutes)();
113
+ return /*#__PURE__*/_react.default.createElement("div", null, routes.map(route => route.path).join(', '));
114
+ };
115
+ (0, _react2.render)(/*#__PURE__*/_react.default.createElement(_index.RoutesProvider, {
116
+ routes: testRoutes
117
+ }, /*#__PURE__*/_react.default.createElement(TestComponent, null)));
118
+ expect(_react2.screen.getByText('/home, /about')).toBeInTheDocument();
119
+ });
120
+ it('throws an error when useRoutes is used outside RoutesProvider', () => {
121
+ const TestComponent = () => {
122
+ (0, _hooks.useRoutes)();
123
+ return null;
124
+ };
125
+ expect(() => (0, _react2.render)(/*#__PURE__*/_react.default.createElement(TestComponent, null))).toThrow('useRoutes must be used within a RoutesProvider');
126
+ });
101
127
  });
@@ -1,13 +1,9 @@
1
- export class HTTPError extends Error {
2
- constructor(status: any, message: any);
3
- constructor: typeof HTTPError;
4
- __proto__: HTTPError;
5
- message: any;
6
- status: any;
1
+ export declare class HTTPError extends Error {
2
+ status: number;
3
+ constructor(status: number, message: string);
4
+ toString(): string;
7
5
  }
8
- export class HTTPNotFound extends HTTPError {
9
- constructor(message: any);
10
- constructor: typeof HTTPNotFound;
11
- __proto__: HTTPNotFound;
6
+ export declare class HTTPNotFound extends HTTPError {
7
+ constructor(message: string);
12
8
  }
13
9
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/ssr/universal/errors.js"],"names":[],"mappings":"AAOA;IACI,uCAMC;IAJG,8BAA4B;IAC5B,qBAAoC;IACpC,aAAsB;IACtB,YAAoB;CAM3B;AAED;IACI,0BAIC;IAFG,iCAA+B;IAC/B,wBAAuC;CAE9C"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/ssr/universal/errors.ts"],"names":[],"mappings":"AAOA,qBAAa,SAAU,SAAQ,KAAK;IAChC,MAAM,EAAE,MAAM,CAAA;gBAEF,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAK3C,QAAQ;CAGX;AAED,qBAAa,YAAa,SAAQ,SAAS;gBAC3B,OAAO,EAAE,MAAM;CAG9B"}
@@ -14,9 +14,6 @@ exports.HTTPNotFound = exports.HTTPError = void 0;
14
14
  class HTTPError extends Error {
15
15
  constructor(status, message) {
16
16
  super(message);
17
- this.constructor = HTTPError;
18
- this.__proto__ = HTTPError.prototype;
19
- this.message = message;
20
17
  this.status = status;
21
18
  }
22
19
  toString() {
@@ -27,8 +24,6 @@ exports.HTTPError = HTTPError;
27
24
  class HTTPNotFound extends HTTPError {
28
25
  constructor(message) {
29
26
  super(404, message);
30
- this.constructor = HTTPNotFound;
31
- this.__proto__ = HTTPNotFound.prototype;
32
27
  }
33
28
  }
34
29
  exports.HTTPNotFound = HTTPNotFound;
@@ -3,7 +3,7 @@ export namespace PAGEEVENTS {
3
3
  const ERROR: string;
4
4
  }
5
5
  export const pages: Pages;
6
- declare class Pages {
6
+ declare class Pages extends EventTarget {
7
7
  pageLoad(templateName: any, start: any, end: any): void;
8
8
  error(name: any, content: any): void;
9
9
  }
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/ssr/universal/events.js"],"names":[],"mappings":";;;;AAiCA,0BAAgC;AApBhC;IACI,wDAOC;IACD,qCAMC;CACJ"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/ssr/universal/events.js"],"names":[],"mappings":";;;;AA6BA,0BAAgC;AAlBhC;IACI,wDAOC;IACD,qCAMC;CACJ"}
@@ -4,8 +4,6 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.pages = exports.PAGEEVENTS = void 0;
7
- var _eventEmitter = _interopRequireDefault(require("event-emitter"));
8
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
7
  /*
10
8
  * Copyright (c) 2021, salesforce.com, inc.
11
9
  * All rights reserved.
@@ -17,22 +15,25 @@ const PAGEEVENTS = exports.PAGEEVENTS = {
17
15
  PAGELOAD: 'PAGELOAD',
18
16
  ERROR: 'ERROR'
19
17
  };
20
- class Pages {
18
+ class Pages extends EventTarget {
21
19
  pageLoad(templateName, start, end) {
22
20
  const payload = {
23
21
  templateName,
24
22
  start,
25
23
  end
26
24
  };
27
- this.emit(PAGEEVENTS.PAGELOAD, payload);
25
+ this.dispatchEvent(new CustomEvent(PAGEEVENTS.PAGELOAD, {
26
+ detail: payload
27
+ }));
28
28
  }
29
29
  error(name, content) {
30
30
  const payload = {
31
31
  name,
32
32
  content
33
33
  };
34
- this.emit(PAGEEVENTS.ERROR, payload);
34
+ this.dispatchEvent(new CustomEvent(PAGEEVENTS.ERROR, {
35
+ detail: payload
36
+ }));
35
37
  }
36
38
  }
37
- (0, _eventEmitter.default)(Pages.prototype);
38
39
  const pages = exports.pages = new Pages();
@@ -12,8 +12,8 @@ describe('Page Events', () => {
12
12
  test('emit and receive a PAGELOAD Page Event', () => {
13
13
  expect.assertions(1);
14
14
  return new Promise(resolve => {
15
- _events.pages.on(_events.PAGEEVENTS.PAGELOAD, evt => {
16
- expect(JSON.stringify(evt)).toEqual(JSON.stringify({
15
+ _events.pages.addEventListener(_events.PAGEEVENTS.PAGELOAD, evt => {
16
+ expect(JSON.stringify(evt.detail)).toEqual(JSON.stringify({
17
17
  templateName: 'blah',
18
18
  start: 123,
19
19
  end: 456
@@ -26,8 +26,8 @@ describe('Page Events', () => {
26
26
  test('emit and receive a ERROR Page Event', () => {
27
27
  expect.assertions(1);
28
28
  return new Promise(resolve => {
29
- _events.pages.on(_events.PAGEEVENTS.ERROR, evt => {
30
- expect(JSON.stringify(evt)).toEqual(JSON.stringify({
29
+ _events.pages.addEventListener(_events.PAGEEVENTS.ERROR, evt => {
30
+ expect(JSON.stringify(evt.detail)).toEqual(JSON.stringify({
31
31
  name: 'blah',
32
32
  content: 'more blah'
33
33
  }));
@@ -1,5 +1,9 @@
1
1
  export function useCorrelationId(): object;
2
2
  export function useServerContext(): ServerContext;
3
+ export function useOrigin({ fromXForwardedHeader }: {
4
+ fromXForwardedHeader?: boolean | undefined;
5
+ }): string;
6
+ export function useRoutes(): object;
3
7
  /**
4
8
  * Server context
5
9
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ssr/universal/hooks/index.js"],"names":[],"mappings":"AAgBO,oCAFM,MAAM,CAQlB;AAiBM,oCANM,aAAa,CAUzB;;;;;;;;SAhBa,MAAM;;;;SACN,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ssr/universal/hooks/index.js"],"names":[],"mappings":"AAgBO,oCAFM,MAAM,CAQlB;AAiBM,oCANM,aAAa,CAUzB;AAcM;;IAHM,MAAM,CAiBlB;AAOM,6BAFM,MAAM,CAQlB;;;;;;;;SAzDa,MAAM;;;;SACN,MAAM"}
@@ -3,13 +3,13 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.useServerContext = exports.useCorrelationId = void 0;
6
+ exports.useServerContext = exports.useRoutes = exports.useOrigin = exports.useCorrelationId = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _contexts = require("../contexts");
9
9
  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); }
10
10
  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; }
11
11
  /*
12
- * Copyright (c) 2022, salesforce.com, inc.
12
+ * Copyright (c) 2024, salesforce.com, inc.
13
13
  * All rights reserved.
14
14
  * SPDX-License-Identifier: BSD-3-Clause
15
15
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
@@ -49,4 +49,50 @@ const useServerContext = () => {
49
49
  const serverContext = (0, _react.useContext)(_contexts.ServerContext);
50
50
  return serverContext;
51
51
  };
52
- exports.useServerContext = useServerContext;
52
+
53
+ /**
54
+ * Returns the application's origin.
55
+ *
56
+ * By default, it will return the ORIGIN under which we are serving the page.
57
+ *
58
+ * If `fromXForwardedHeader` is true, it will use the value of `x-forwarded-proto` and `x-forwarded-host` headers in req
59
+ * to build origin. (it is false by default)
60
+ *
61
+ * NOTE: this is a React hook, so it has to be used in a React rendering pipeline.
62
+ * @returns {string} origin string
63
+ *
64
+ */
65
+ exports.useServerContext = useServerContext;
66
+ const useOrigin = ({
67
+ fromXForwardedHeader = false
68
+ }) => {
69
+ const {
70
+ res
71
+ } = useServerContext();
72
+ if (typeof window !== 'undefined') {
73
+ return window.location.origin;
74
+ }
75
+ const {
76
+ APP_ORIGIN
77
+ } = process.env;
78
+ const xForwardedOrigin = res.locals.xForwardedOrigin;
79
+ if (fromXForwardedHeader && xForwardedOrigin) {
80
+ return xForwardedOrigin;
81
+ }
82
+ return APP_ORIGIN;
83
+ };
84
+
85
+ /**
86
+ * Use this hook to get the routes value of the closest RoutesProvider component.
87
+ *
88
+ * @returns {object} array of routes
89
+ */
90
+ exports.useOrigin = useOrigin;
91
+ const useRoutes = () => {
92
+ const context = (0, _react.useContext)(_contexts.RoutesContext);
93
+ if (!context) {
94
+ throw new Error('useRoutes must be used within a RoutesProvider');
95
+ }
96
+ return context;
97
+ };
98
+ exports.useRoutes = useRoutes;
@@ -18,7 +18,7 @@ export declare const getAssetUrl: (path: string) => string;
18
18
  * @function
19
19
  * @returns {string} The full URL to the static asset.
20
20
  */
21
- export declare const getStaticAssetUrl: (path: string, opts: GetAssetUrlOptions) => string;
21
+ export declare const getStaticAssetUrl: (path?: string, opts?: GetAssetUrlOptions) => string;
22
22
  /**
23
23
  * @typedef {Object} ProxyConfig
24
24
  * @property {String} protocol - http or https
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/ssr/universal/utils.ts"],"names":[],"mappings":"AAuBA,KAAK,kBAAkB,GAAG;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAA;CACnC,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,SAAU,MAAM,WAQvC,CAAA;AAID;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,SAAU,MAAM,QAAQ,kBAAkB,WAiBvE,CAAA;AAED;;;;;GAKG;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,WAS3B,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/ssr/universal/utils.ts"],"names":[],"mappings":"AAuBA,KAAK,kBAAkB,GAAG;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAA;CACnC,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,SAAU,MAAM,WAQvC,CAAA;AAID;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,yBAAqB,kBAAkB,WAkBpE,CAAA;AAED;;;;;GAKG;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,WAS3B,CAAA"}
@@ -20,7 +20,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
20
20
  */ /* eslint-disable @typescript-eslint/ban-ts-comment */ // @ts-ignore
21
21
  // @ts-ignore
22
22
  const onClient = typeof window !== 'undefined';
23
- const EXTENIONS_NAMESPACE = '__extensions';
23
+ const EXTENSIONS_NAMESPACE = '__extensions';
24
24
  const STATIC_FOLDER = 'static';
25
25
  /**
26
26
  * Get the URL that should be used to load an asset from the bundle.
@@ -38,7 +38,7 @@ const getAssetUrl = path => {
38
38
  };
39
39
 
40
40
  // TODO: Once we establish that we have a new @salesforce/pwa-kit-extensibility package, we can move this utility to
41
- // it as to not have direct references to extensibilty in the sdk. This will also reduce duplicate code.
41
+ // it as to not have direct references to extensibility in the sdk. This will also reduce duplicate code.
42
42
  /**
43
43
  * Get the URL that should be used to load a static asset from the bundle.
44
44
  *
@@ -49,21 +49,22 @@ const getAssetUrl = path => {
49
49
  * @returns {string} The full URL to the static asset.
50
50
  */
51
51
  exports.getAssetUrl = getAssetUrl;
52
- const getStaticAssetUrl = (path, opts) => {
52
+ const getStaticAssetUrl = (path = '', opts = {}) => {
53
53
  const {
54
54
  appExtensionPackageName = ''
55
55
  } = opts || {};
56
56
 
57
57
  /* istanbul ignore next */
58
- const publicPath = onClient ?
59
- // @ts-ignore
60
- `${window.Progressive.buildOrigin}` : `${_ssrNamespacePaths.bundleBasePath}/${process.env.BUNDLE_ID || 'development'}/`;
58
+ let publicPath = getAssetUrl('');
61
59
 
62
60
  // Ensure all defined path arguments start with `/`.
63
61
  if (path && !path.startsWith('/')) {
64
62
  path = `/${path}`;
65
63
  }
66
- return `${publicPath}/${STATIC_FOLDER}${appExtensionPackageName ? `/${EXTENIONS_NAMESPACE}/${appExtensionPackageName}` : ''}${path ? path : ''}`;
64
+ if (publicPath && !publicPath.endsWith('/')) {
65
+ publicPath = `${publicPath}/`;
66
+ }
67
+ return `${publicPath}${STATIC_FOLDER}${appExtensionPackageName ? `/${EXTENSIONS_NAMESPACE}/${appExtensionPackageName}` : ''}${path ? path : ''}`;
67
68
  };
68
69
 
69
70
  /**
@@ -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: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'
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
  /**
@@ -60,7 +60,7 @@ class PerformanceTimer {
60
60
  */
61
61
  buildServerTimingHeader() {
62
62
  const header = this.metrics.map(metric => {
63
- return `${metric.name};dur=${metric.duration}`;
63
+ return `${metric.name};dur=${metric.duration.toFixed(2)}`;
64
64
  }).join(', ');
65
65
  return header;
66
66
  }
@@ -73,7 +73,7 @@ class PerformanceTimer {
73
73
  */
74
74
  log() {
75
75
  this.metrics.forEach(metric => {
76
- _loggerInstance.default.info(`${metric.name} - ${metric.duration}ms ${metric.detail || ''}`, {
76
+ _loggerInstance.default.info(`${metric.name} - ${metric.duration.toFixed(4)}ms ${metric.detail || ''}`, {
77
77
  namespace: 'performance'
78
78
  });
79
79
  });
@@ -115,7 +115,7 @@ class PerformanceTimer {
115
115
  if (startMark) {
116
116
  const measurement = {
117
117
  name,
118
- duration: (timestamp - startMark.timestamp).toFixed(2),
118
+ duration: timestamp - startMark.timestamp,
119
119
  detail: options.detail
120
120
  };
121
121
  this.metrics.push(measurement);
@@ -1 +1 @@
1
- {"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../src/utils/url.js"],"names":[],"mappings":"AAoBO,gCANM,MAAM,CAoBlB"}
1
+ {"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../src/utils/url.js"],"names":[],"mappings":"AAsBO,gCANM,MAAM,CAoBlB"}
package/utils/url.js CHANGED
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.getAppOrigin = void 0;
7
7
  /*
8
- * Copyright (c) 2021, salesforce.com, inc.
8
+ * Copyright (c) 2024, salesforce.com, inc.
9
9
  * All rights reserved.
10
10
  * SPDX-License-Identifier: BSD-3-Clause
11
11
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
@@ -18,6 +18,8 @@ exports.getAppOrigin = void 0;
18
18
  * initialized using the `_createApp` method (This happens in your /app/ssr.js file).
19
19
  *
20
20
  * @function
21
+ * @deprecated use `useOrigin()` instead.
22
+ * This function will be removed in version 4.0.0.
21
23
  * @returns {string} Returns the ORIGIN under which we are serving the page.
22
24
  * @example
23
25
  * import {getAppOrigin} from '@salesforce/pwa-kit-react-sdk/utils/url'