@lwrjs/client-modules 0.13.0-alpha.2 → 0.13.0-alpha.21
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/build/bundle/prod/lwr/lockerDefine/lockerDefine.js +1 -1
- package/build/bundle/prod/lwr/servicesESM/servicesESM.js +1 -1
- package/build/es/modules/lwr/declarativeShadow/declarativeShadow.d.ts +2 -0
- package/build/es/modules/lwr/declarativeShadow/declarativeShadow.js +27 -0
- package/build/es/modules/lwr/environment/environment.d.ts +6 -0
- package/build/es/modules/lwr/environment/environment.js +11 -0
- package/build/es/modules/lwr/init/init.d.ts +23 -0
- package/build/es/modules/lwr/init/init.js +118 -0
- package/build/es/modules/lwr/lockerSandbox/lockerSandbox.d.ts +2 -0
- package/build/es/modules/lwr/lockerSandbox/lockerSandbox.js +2 -0
- package/build/es/modules/lwr/metrics/metrics.d.ts +35 -0
- package/build/es/modules/lwr/metrics/metrics.js +39 -0
- package/build/es/modules/lwr/profiler/profiler.d.ts +28 -0
- package/build/es/modules/lwr/profiler/profiler.js +67 -0
- package/build/es/modules/lwr/serverDataCallback/serverDataCallback.d.ts +7 -0
- package/build/es/modules/lwr/serverDataCallback/serverDataCallback.js +11 -0
- package/build/modules/lwr/hmr/hmr.js +30 -26
- package/build/modules/lwr/init/init.js +0 -6
- package/build/modules/lwr/lockerDefine/lockerDefine.js +41 -13
- package/build/modules/lwr/lockerSandbox/lockerSandbox.js +41 -13
- package/build/modules/lwr/metrics/metrics.js +1 -1
- package/build/modules/lwr/serverDataCallback/serverDataCallback.js +16 -0
- package/build/modules/lwr/servicesESM/servicesESM.js +2 -4
- package/package.json +7 -6
- package/build/modules/lwr/hmr/util/swap.js +0 -12
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=[];let o;const n=globalThis.LWR;
|
|
1
|
+
const e=[];let o;const n=globalThis.LWR;n.define||n.env?globalThis.LWR=Object.freeze({define:n.define,env:n.env}):delete globalThis.LWR;const t={addLoaderPlugin:()=>{console.warn("API is not supported in ESM format")},handleStaleModule:function(n){e.push(n),o||(o=new WebSocket(`ws://${location.host}`),o.addEventListener("message",(async({data:o})=>{const n=JSON.parse(o);if("moduleUpdate"===n.eventType){const{oldHash:o,newHash:t,module:{specifier:a}}=n.payload;for(let n=0;n<e.length;n++){if(null!==(0,e[n])({name:a,oldHash:o,newHash:t}))break}}})))},appMetadata:function(){const{appId:e,bootstrapModule:o,rootComponent:t,rootComponents:a}=n;return{appId:e,bootstrapModule:o,rootComponent:t,rootComponents:a}}(),addServerDataCallback:function(e){}};export{t as services};
|
|
2
2
|
//# sourceMappingURL=servicesESM.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Polyfill the Declarative ShadowDOM spec - call this function AFTER the DOM has been parsed and BEFORE hydrateComponent() is invoked
|
|
2
|
+
// See https://github.com/salesforce/lwc-rfcs/blob/master/text/0129-declarative-shadow-dom-polyfill.md#single-loop-script-shadow-root-attachment-reference
|
|
3
|
+
// Note we handle both the old (Chrome-only) `shadowroot` attribute as well as the standard `shadowrootmode` attribute.
|
|
4
|
+
// As of this writing, Chrome supports both formats but Safari only supports the standard format.
|
|
5
|
+
function applyShadowRoots(node, attributeName) {
|
|
6
|
+
// if this browser DOES NOT support Declarative ShadowDOM
|
|
7
|
+
node.querySelectorAll(`template[${attributeName}]`).forEach((template) => {
|
|
8
|
+
const mode = (template.getAttribute(attributeName) || 'open');
|
|
9
|
+
const shadowRoot = template.parentNode?.attachShadow({ mode });
|
|
10
|
+
shadowRoot.appendChild(template.content);
|
|
11
|
+
template.remove();
|
|
12
|
+
applyShadowRoots(shadowRoot, attributeName);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export function polyfillDeclarativeShadowDom(node = document) {
|
|
16
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
17
|
+
if (!HTMLTemplateElement.prototype.hasOwnProperty('shadowRootMode')) {
|
|
18
|
+
// this browser does not support the standard format
|
|
19
|
+
applyShadowRoots(node, 'shadowrootmode');
|
|
20
|
+
}
|
|
21
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
22
|
+
if (!HTMLTemplateElement.prototype.hasOwnProperty('shadowRoot')) {
|
|
23
|
+
// this browser does not support the non-standard format
|
|
24
|
+
applyShadowRoots(node, 'shadowroot');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=declarativeShadow.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const environment = globalThis?.LWR?.env || {};
|
|
2
|
+
export const isServer = environment && (environment.SSR === 'true' || environment.SSR === true);
|
|
3
|
+
// The baseBath from the config or set from the request (e.g. /shop)
|
|
4
|
+
export const basePath = environment && environment.basePath;
|
|
5
|
+
// The locale set from the request or the defaultLocale from the config (e.g. en-US)
|
|
6
|
+
export const locale = environment && environment.locale;
|
|
7
|
+
// Root base path for static assets (e.g. /shop/mobify/bundle/1234/site)
|
|
8
|
+
export const assetBasePath = environment && environment.assetBasePath;
|
|
9
|
+
// Base path for UI routing (e.g. /shop/en-US)
|
|
10
|
+
export const uiBasePath = environment && environment.uiBasePath;
|
|
11
|
+
//# sourceMappingURL=environment.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { LightningElement } from 'lwc';
|
|
2
|
+
import type { ServerData } from '@lwrjs/types';
|
|
3
|
+
/**
|
|
4
|
+
* Convert a module specifier into a valid CustomElement registry name:
|
|
5
|
+
* - remove any version linking
|
|
6
|
+
* - change / to -
|
|
7
|
+
* - convert uppercase letters into "-${lowercase}"
|
|
8
|
+
* eg: "c/app" => "c-app"
|
|
9
|
+
* eg: "my/helloWorld" => "my-hello-world"
|
|
10
|
+
* eg: "lwr/example/v/1.0.0" => "lwr-example"
|
|
11
|
+
* @param specifier The bare specifier to convert
|
|
12
|
+
*/
|
|
13
|
+
export declare function toKebabCase(specifier: string): string;
|
|
14
|
+
export declare function getPropFromAttrName(propName: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Import any requested static application dependencies, define the root
|
|
17
|
+
* application component(s) into the CustomElement registry, and inject them.
|
|
18
|
+
* @param rootModules - An array of arrays, each one holding a pair of
|
|
19
|
+
* bare specifier and corresponding LightningElement constructor
|
|
20
|
+
* @example - [['x/appRoot', appCtor], ['x/nav', navCtor]]
|
|
21
|
+
*/
|
|
22
|
+
export declare function init(rootModules: [string, LightningElement][], serverData?: ServerData): void;
|
|
23
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { BOOTSTRAP_END, INIT, INIT_MODULE } from 'lwr/metrics';
|
|
2
|
+
import { logOperationStart, logOperationEnd } from 'lwr/profiler';
|
|
3
|
+
// TODO: This is a temporal workaround until https://github.com/salesforce/lwc/pull/2083 is sorted - tmp
|
|
4
|
+
import { createElement } from 'lwc';
|
|
5
|
+
// <hydrateComponentProxy> - This code is removed in core
|
|
6
|
+
import { hydrateComponent } from 'lwc';
|
|
7
|
+
function hydrateComponentProxy(customElement, Ctor, props) {
|
|
8
|
+
hydrateComponent(customElement, Ctor, props);
|
|
9
|
+
}
|
|
10
|
+
// </hydrateComponentProxy>
|
|
11
|
+
function initializeWebComponent(elementName, Ctor) {
|
|
12
|
+
return createElement(elementName, { is: Ctor });
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Convert a module specifier into a valid CustomElement registry name:
|
|
16
|
+
* - remove any version linking
|
|
17
|
+
* - change / to -
|
|
18
|
+
* - convert uppercase letters into "-${lowercase}"
|
|
19
|
+
* eg: "c/app" => "c-app"
|
|
20
|
+
* eg: "my/helloWorld" => "my-hello-world"
|
|
21
|
+
* eg: "lwr/example/v/1.0.0" => "lwr-example"
|
|
22
|
+
* @param specifier The bare specifier to convert
|
|
23
|
+
*/
|
|
24
|
+
export function toKebabCase(specifier) {
|
|
25
|
+
return specifier
|
|
26
|
+
.replace(/\/v\/[a-zA-Z0-9-_.]+$/, '')
|
|
27
|
+
.replace('/', '-')
|
|
28
|
+
.replace(/([A-Z])/g, (c) => `-${c.toLowerCase()}`);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* This method maps between attribute names
|
|
32
|
+
* and the corresponding props name.
|
|
33
|
+
*/
|
|
34
|
+
const CAMEL_REGEX = /-([a-z])/g;
|
|
35
|
+
export function getPropFromAttrName(propName) {
|
|
36
|
+
return propName.replace(CAMEL_REGEX, (g) => g[1].toUpperCase());
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Import any requested static application dependencies, define the root
|
|
40
|
+
* application component(s) into the CustomElement registry, and inject them.
|
|
41
|
+
* @param rootModules - An array of arrays, each one holding a pair of
|
|
42
|
+
* bare specifier and corresponding LightningElement constructor
|
|
43
|
+
* @example - [['x/appRoot', appCtor], ['x/nav', navCtor]]
|
|
44
|
+
*/
|
|
45
|
+
export function init(rootModules, serverData = {}) {
|
|
46
|
+
if (typeof customElements === 'undefined' || typeof document === 'undefined') {
|
|
47
|
+
logOperationStart({ id: BOOTSTRAP_END });
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
logOperationStart({ id: INIT });
|
|
51
|
+
let index = 0;
|
|
52
|
+
for (const [specifier, ctor] of rootModules) {
|
|
53
|
+
const elementName = toKebabCase(specifier);
|
|
54
|
+
// initialize and inject the root module into the LWR Root or DOM if it is missing
|
|
55
|
+
if (!document.body.querySelector(elementName)) {
|
|
56
|
+
logOperationStart({ id: INIT_MODULE, specifier, specifierIndex: ++index });
|
|
57
|
+
// this is for SPA like routes (one component at the root level) utilizing the lwr-root directive
|
|
58
|
+
const component = initializeWebComponent(elementName, ctor);
|
|
59
|
+
const container = document.querySelector('[lwr-root]');
|
|
60
|
+
container ? container.appendChild(component) : document.body.appendChild(component);
|
|
61
|
+
logOperationEnd({
|
|
62
|
+
id: INIT_MODULE,
|
|
63
|
+
specifier,
|
|
64
|
+
specifierIndex: index,
|
|
65
|
+
metadata: { renderMode: 'spa' },
|
|
66
|
+
});
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
// the page has been rendered or SSR'd, and each component needs to initialized(or hydrated)
|
|
70
|
+
const elements = document.querySelectorAll(elementName);
|
|
71
|
+
for (const element of elements) {
|
|
72
|
+
logOperationStart({ id: INIT_MODULE, specifier, specifierIndex: ++index });
|
|
73
|
+
const propsId = element.dataset.lwrPropsId;
|
|
74
|
+
// hydrate SSR'd components
|
|
75
|
+
if (propsId) {
|
|
76
|
+
hydrateComponentProxy(element, ctor, serverData[propsId] || {});
|
|
77
|
+
logOperationEnd({
|
|
78
|
+
id: INIT_MODULE,
|
|
79
|
+
specifier,
|
|
80
|
+
specifierIndex: index,
|
|
81
|
+
metadata: { renderMode: 'ssr' },
|
|
82
|
+
});
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
// Note: due to the bug described at the top of this file, each CSR'd custom element
|
|
86
|
+
// must be replaced with the new synthetic constructor. Attributes and children are
|
|
87
|
+
// copied over to the new component.
|
|
88
|
+
const component = initializeWebComponent(elementName, ctor);
|
|
89
|
+
// copy the attributes
|
|
90
|
+
for (const { name, value } of element.attributes) {
|
|
91
|
+
component.setAttribute(name, value);
|
|
92
|
+
const prop = getPropFromAttrName(name);
|
|
93
|
+
if (prop in component) {
|
|
94
|
+
// set attributes as properties for reactivity
|
|
95
|
+
component[prop] = value;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// save the children
|
|
99
|
+
while (element.childNodes.length > 0) {
|
|
100
|
+
component.appendChild(element.childNodes[0]);
|
|
101
|
+
}
|
|
102
|
+
// swap the element out with the initialized component
|
|
103
|
+
const parent = element.parentElement;
|
|
104
|
+
if (parent) {
|
|
105
|
+
parent.replaceChild(component, element);
|
|
106
|
+
}
|
|
107
|
+
logOperationEnd({
|
|
108
|
+
id: INIT_MODULE,
|
|
109
|
+
specifier,
|
|
110
|
+
specifierIndex: index,
|
|
111
|
+
metadata: { renderMode: 'csr' },
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
logOperationEnd({ id: INIT });
|
|
116
|
+
logOperationStart({ id: BOOTSTRAP_END });
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type LWRMetric = 'lwr.bootstrap.end' | 'lwr.bootstrap.error' | 'lwr.bootstrap.init' | 'lwr.bootstrap.init.module' | 'lwr.loader.module.define' | 'lwr.loader.module.fetch' | 'lwr.loader.mappings.fetch' | 'lwr.loader.module.error' | 'lwr.loader.mappings.error' | 'lwr.router.navigate' | 'lwr.router.view' | 'lwr.router.error' | 'lwr.loader.module.dynamicLoad';
|
|
2
|
+
export declare const BOOTSTRAP_PREFIX = "lwr.bootstrap.";
|
|
3
|
+
export declare const BOOTSTRAP_END: LWRMetric;
|
|
4
|
+
export declare const BOOTSTRAP_ERROR: LWRMetric;
|
|
5
|
+
export declare const BOOTSTRAP_ERROR_COUNT: string;
|
|
6
|
+
export declare const BOOTSTRAP_DURATION: string;
|
|
7
|
+
export declare const INIT = "lwr.bootstrap.init";
|
|
8
|
+
export declare const INIT_DURATION: string;
|
|
9
|
+
export declare const INIT_MODULE = "lwr.bootstrap.init.module";
|
|
10
|
+
export declare const INIT_MODULE_DURATION: string;
|
|
11
|
+
export declare const INIT_MODULE_COUNT: string;
|
|
12
|
+
export declare const LOADER_PREFIX = "lwr.loader.";
|
|
13
|
+
export declare const MODULE_DEFINE: LWRMetric;
|
|
14
|
+
export declare const MODULE_DEFINE_COUNT: string;
|
|
15
|
+
export declare const MODULE_DYNAMIC_LOAD: LWRMetric;
|
|
16
|
+
export declare const MODULE_DYNAMIC_LOAD_COUNT: string;
|
|
17
|
+
export declare const MODULE_FETCH: LWRMetric;
|
|
18
|
+
export declare const MODULE_FETCH_COUNT: string;
|
|
19
|
+
export declare const MODULE_FETCH_DURATION: string;
|
|
20
|
+
export declare const MODULE_ERROR: LWRMetric;
|
|
21
|
+
export declare const MODULE_ERROR_COUNT: string;
|
|
22
|
+
export declare const MAPPINGS_FETCH: LWRMetric;
|
|
23
|
+
export declare const MAPPINGS_FETCH_COUNT: string;
|
|
24
|
+
export declare const MAPPINGS_FETCH_DURATION: string;
|
|
25
|
+
export declare const MAPPINGS_ERROR: LWRMetric;
|
|
26
|
+
export declare const MAPPINGS_ERROR_COUNT: string;
|
|
27
|
+
export declare const ROUTER_PREFIX = "lwr.router.";
|
|
28
|
+
export declare const ROUTER_NAV: LWRMetric;
|
|
29
|
+
export declare const ROUTER_NAV_COUNT: string;
|
|
30
|
+
export declare const ROUTER_NAV_DURATION: string;
|
|
31
|
+
export declare const ROUTER_VIEW: LWRMetric;
|
|
32
|
+
export declare const ROUTER_VIEW_DURATION: string;
|
|
33
|
+
export declare const ROUTER_ERROR: LWRMetric;
|
|
34
|
+
export declare const ROUTER_ERROR_COUNT: string;
|
|
35
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Bootstrap / shim
|
|
2
|
+
export const BOOTSTRAP_PREFIX = 'lwr.bootstrap.';
|
|
3
|
+
export const BOOTSTRAP_END = `${BOOTSTRAP_PREFIX}end`;
|
|
4
|
+
export const BOOTSTRAP_ERROR = `${BOOTSTRAP_PREFIX}error`;
|
|
5
|
+
export const BOOTSTRAP_ERROR_COUNT = `${BOOTSTRAP_ERROR}.count`;
|
|
6
|
+
export const BOOTSTRAP_DURATION = `${BOOTSTRAP_PREFIX}duration`;
|
|
7
|
+
// Initialization
|
|
8
|
+
export const INIT = 'lwr.bootstrap.init';
|
|
9
|
+
export const INIT_DURATION = `${INIT}.duration`;
|
|
10
|
+
export const INIT_MODULE = `lwr.bootstrap.init.module`;
|
|
11
|
+
export const INIT_MODULE_DURATION = `${INIT_MODULE}.duration`;
|
|
12
|
+
export const INIT_MODULE_COUNT = `${INIT_MODULE}.count`;
|
|
13
|
+
// Loader: modules
|
|
14
|
+
export const LOADER_PREFIX = 'lwr.loader.';
|
|
15
|
+
export const MODULE_DEFINE = `${LOADER_PREFIX}module.define`;
|
|
16
|
+
export const MODULE_DEFINE_COUNT = `${MODULE_DEFINE}.count`;
|
|
17
|
+
export const MODULE_DYNAMIC_LOAD = `${LOADER_PREFIX}module.dynamicLoad`;
|
|
18
|
+
export const MODULE_DYNAMIC_LOAD_COUNT = `${MODULE_DYNAMIC_LOAD}.count`;
|
|
19
|
+
export const MODULE_FETCH = `${LOADER_PREFIX}module.fetch`;
|
|
20
|
+
export const MODULE_FETCH_COUNT = `${MODULE_FETCH}.count`;
|
|
21
|
+
export const MODULE_FETCH_DURATION = `${MODULE_FETCH}.duration`;
|
|
22
|
+
export const MODULE_ERROR = `${LOADER_PREFIX}module.error`;
|
|
23
|
+
export const MODULE_ERROR_COUNT = `${MODULE_ERROR}.count`;
|
|
24
|
+
// Loader: mappings
|
|
25
|
+
export const MAPPINGS_FETCH = `${LOADER_PREFIX}mappings.fetch`;
|
|
26
|
+
export const MAPPINGS_FETCH_COUNT = `${MAPPINGS_FETCH}.count`;
|
|
27
|
+
export const MAPPINGS_FETCH_DURATION = `${MAPPINGS_FETCH}.duration`;
|
|
28
|
+
export const MAPPINGS_ERROR = `${LOADER_PREFIX}mappings.error`;
|
|
29
|
+
export const MAPPINGS_ERROR_COUNT = `${MAPPINGS_ERROR}.count`;
|
|
30
|
+
// Router
|
|
31
|
+
export const ROUTER_PREFIX = 'lwr.router.';
|
|
32
|
+
export const ROUTER_NAV = `${ROUTER_PREFIX}navigate`;
|
|
33
|
+
export const ROUTER_NAV_COUNT = `${ROUTER_NAV}.count`;
|
|
34
|
+
export const ROUTER_NAV_DURATION = `${ROUTER_NAV}.duration`;
|
|
35
|
+
export const ROUTER_VIEW = `${ROUTER_PREFIX}view`;
|
|
36
|
+
export const ROUTER_VIEW_DURATION = `${ROUTER_VIEW}.duration`;
|
|
37
|
+
export const ROUTER_ERROR = `${ROUTER_PREFIX}error`;
|
|
38
|
+
export const ROUTER_ERROR_COUNT = `${ROUTER_ERROR}.count`;
|
|
39
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { LWRMetric } from '../metrics/metrics.js';
|
|
2
|
+
declare const enum Phase {
|
|
3
|
+
Start = 0,
|
|
4
|
+
End = 1
|
|
5
|
+
}
|
|
6
|
+
export type Metadata = {
|
|
7
|
+
[key: string]: string | number | boolean;
|
|
8
|
+
};
|
|
9
|
+
interface LWRLogInfo {
|
|
10
|
+
id: LWRMetric;
|
|
11
|
+
specifier?: string;
|
|
12
|
+
specifierIndex?: number;
|
|
13
|
+
metadata?: Metadata;
|
|
14
|
+
}
|
|
15
|
+
interface LWRDispatcherInfo extends LWRLogInfo {
|
|
16
|
+
phase: Phase;
|
|
17
|
+
}
|
|
18
|
+
type LogOperation = (info: LWRLogInfo) => void;
|
|
19
|
+
export type LogDispatcher = (info: LWRDispatcherInfo) => void;
|
|
20
|
+
export interface ProfilerAPI {
|
|
21
|
+
logOperationStart: LogOperation;
|
|
22
|
+
logOperationEnd: LogOperation;
|
|
23
|
+
}
|
|
24
|
+
export declare function attachDispatcher(dispatcher: LogDispatcher): void;
|
|
25
|
+
export declare function logOperationStart({ id, specifier, specifierIndex, metadata }: LWRLogInfo): void;
|
|
26
|
+
export declare function logOperationEnd({ id, specifier, specifierIndex, metadata }: LWRLogInfo): void;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=profiler.d.ts.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
var Phase;
|
|
2
|
+
(function (Phase) {
|
|
3
|
+
Phase[Phase["Start"] = 0] = "Start";
|
|
4
|
+
Phase[Phase["End"] = 1] = "End";
|
|
5
|
+
})(Phase || (Phase = {}));
|
|
6
|
+
// Attach a custom dispatcher
|
|
7
|
+
let customDispatcher;
|
|
8
|
+
export function attachDispatcher(dispatcher) {
|
|
9
|
+
customDispatcher = dispatcher;
|
|
10
|
+
}
|
|
11
|
+
// Check if the Performance API is available
|
|
12
|
+
// e.g. JSDom (used in Jest) doesn't implement these
|
|
13
|
+
const perf = globalThis.performance;
|
|
14
|
+
const isPerfSupported = typeof perf !== 'undefined' &&
|
|
15
|
+
typeof perf.mark === 'function' &&
|
|
16
|
+
typeof perf.clearMarks === 'function' &&
|
|
17
|
+
typeof perf.measure === 'function' &&
|
|
18
|
+
typeof perf.clearMeasures === 'function';
|
|
19
|
+
function getMeasureName(id, specifier) {
|
|
20
|
+
return specifier ? `${id}-${specifier}` : id;
|
|
21
|
+
}
|
|
22
|
+
function getMarkName(id, specifier, specifierIndex) {
|
|
23
|
+
const measureName = getMeasureName(id, specifier);
|
|
24
|
+
return specifier && specifierIndex ? `${measureName}_${specifierIndex}` : measureName;
|
|
25
|
+
}
|
|
26
|
+
function getDetail(specifier, metadata) {
|
|
27
|
+
const detail = specifier || metadata ? { ...metadata } : null;
|
|
28
|
+
if (detail && specifier) {
|
|
29
|
+
detail['specifier'] = specifier;
|
|
30
|
+
}
|
|
31
|
+
return detail;
|
|
32
|
+
}
|
|
33
|
+
// For marking request metrics
|
|
34
|
+
// Fallback to the Performance API if there is no custom dispatcher
|
|
35
|
+
export function logOperationStart({ id, specifier, specifierIndex, metadata }) {
|
|
36
|
+
if (customDispatcher) {
|
|
37
|
+
customDispatcher({ id, phase: Phase.Start, specifier, metadata });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (isPerfSupported) {
|
|
41
|
+
const markName = getMarkName(id, specifier, specifierIndex);
|
|
42
|
+
const detail = getDetail(specifier, metadata);
|
|
43
|
+
perf.mark(markName, { detail });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// For measuring duration metrics
|
|
47
|
+
// Fallback to the Performance API if there is no custom dispatcher
|
|
48
|
+
/* istanbul ignore next */
|
|
49
|
+
export function logOperationEnd({ id, specifier, specifierIndex, metadata }) {
|
|
50
|
+
if (customDispatcher) {
|
|
51
|
+
customDispatcher({ id, phase: Phase.End, specifier, metadata });
|
|
52
|
+
}
|
|
53
|
+
else if (isPerfSupported) {
|
|
54
|
+
const markName = getMarkName(id, specifier, specifierIndex);
|
|
55
|
+
const measureName = getMeasureName(id, specifier);
|
|
56
|
+
const detail = getDetail(specifier, metadata);
|
|
57
|
+
perf.measure(measureName, {
|
|
58
|
+
start: markName,
|
|
59
|
+
detail,
|
|
60
|
+
});
|
|
61
|
+
// Clear the created mark and measure to avoid filling the performance entry buffer
|
|
62
|
+
// Even if they get deleted, existing PerformanceObservers preserve copies of the entries
|
|
63
|
+
perf.clearMarks(markName);
|
|
64
|
+
perf.clearMeasures(measureName);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=profiler.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side module implementation of the serverDataCallback bootstrap service.
|
|
3
|
+
*/
|
|
4
|
+
import type { ServerData, ServerDataCallback } from '@lwrjs/types';
|
|
5
|
+
export declare function registerServerDataCallbacks(hook: ServerDataCallback): void;
|
|
6
|
+
export declare function evaluateServerDataCallbacks(serverData?: ServerData): void;
|
|
7
|
+
//# sourceMappingURL=serverDataCallback.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const serverDataCallbacks = [];
|
|
2
|
+
export function registerServerDataCallbacks(hook) {
|
|
3
|
+
serverDataCallbacks.push(hook);
|
|
4
|
+
}
|
|
5
|
+
export function evaluateServerDataCallbacks(serverData = {}) {
|
|
6
|
+
// now that we have server data, run the server data hooks
|
|
7
|
+
for (const serverDataCallback of serverDataCallbacks) {
|
|
8
|
+
serverDataCallback({ serverData });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=serverDataCallback.js.map
|
|
@@ -1,34 +1,43 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { swapTemplate, swapStyle, swapComponent } from 'lwc';
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
// The server will always return the same canonical "latest URL"
|
|
5
|
-
// So we need to track the last new URI instead
|
|
3
|
+
// Track the newest URI for each module.
|
|
6
4
|
const URI_MAPPING = new Map();
|
|
7
5
|
|
|
8
6
|
async function moduleUpdate(payload) {
|
|
9
7
|
const {
|
|
8
|
+
format,
|
|
10
9
|
oldUri,
|
|
11
10
|
newUri,
|
|
12
11
|
module: { specifier },
|
|
13
12
|
} = payload;
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
if (format === 'amd') {
|
|
15
|
+
// Need to integrate new LWC APIs to support inline HMR for AMD+CSR
|
|
16
|
+
window.location.reload();
|
|
17
|
+
} else {
|
|
18
|
+
const lastEvalutedUri = URI_MAPPING.get(oldUri) || oldUri;
|
|
19
|
+
const oldModule = await import(lastEvalutedUri);
|
|
20
|
+
const newModule = await import(newUri);
|
|
21
|
+
URI_MAPPING.set(oldUri, newUri);
|
|
22
|
+
updateStaleModule({ oldModule, newModule, specifier });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
})
|
|
26
|
+
function updateStaleModule({ oldModule, newModule, specifier }) {
|
|
27
|
+
if (specifier.endsWith('html') && newModule.default) {
|
|
28
|
+
console.log(`Swapping HTML template for module "${specifier}"`);
|
|
29
|
+
swapTemplate(oldModule.default, newModule.default);
|
|
30
|
+
} else if (specifier.endsWith('css') && newModule.default) {
|
|
31
|
+
console.log(`Swapping CSS for module "${specifier}"`);
|
|
32
|
+
swapStyle(oldModule.default[0], newModule.default[0]);
|
|
33
|
+
} else {
|
|
34
|
+
console.log(`Swapping JS for module "${specifier}"`);
|
|
35
|
+
swapComponent(oldModule.default, newModule.default);
|
|
36
|
+
}
|
|
25
37
|
}
|
|
26
38
|
|
|
27
39
|
function viewUpdate(payload, metadata) {
|
|
28
|
-
const viewId = payload
|
|
29
|
-
const assetId = payload.assetId;
|
|
30
|
-
|
|
31
|
-
// eslint-disable-next-line no-undef
|
|
40
|
+
const { assetId, viewId } = payload;
|
|
32
41
|
if (metadata.templates.includes(viewId) || metadata.assetReferences.includes(assetId)) {
|
|
33
42
|
window.location.reload();
|
|
34
43
|
}
|
|
@@ -38,8 +47,8 @@ async function waitForSuccessfulPing(socketUrl) {
|
|
|
38
47
|
// eslint-disable-next-line no-constant-condition
|
|
39
48
|
while (true) {
|
|
40
49
|
try {
|
|
41
|
-
//
|
|
42
|
-
// server comes back online, it
|
|
50
|
+
// Poll for the socket URL; reject with a network error if not available.
|
|
51
|
+
// If the dev server comes back online, it resolves with a 404 HTTP response.
|
|
43
52
|
await fetch(`http://${socketUrl}`);
|
|
44
53
|
break;
|
|
45
54
|
} catch (error) {
|
|
@@ -49,19 +58,14 @@ async function waitForSuccessfulPing(socketUrl) {
|
|
|
49
58
|
}
|
|
50
59
|
|
|
51
60
|
export function initHMR(serverURI = '', metadata) {
|
|
52
|
-
const normalizedMeta = {
|
|
53
|
-
...{ assetReferences: [], templates: [] },
|
|
54
|
-
...metadata,
|
|
55
|
-
};
|
|
56
|
-
|
|
61
|
+
const normalizedMeta = { ...{ assetReferences: [], templates: [] }, ...metadata };
|
|
57
62
|
// {apiVersion}/hmr/{format}/{compat}?debug
|
|
58
63
|
const host = serverURI.startsWith('/') ? location.host : '';
|
|
59
64
|
const socketUrl = `${host}${serverURI}`;
|
|
60
|
-
|
|
61
65
|
const socket = new WebSocket(`ws://${socketUrl}`);
|
|
62
66
|
|
|
63
67
|
socket.addEventListener('close', async (evt) => {
|
|
64
|
-
// Don't do anything
|
|
68
|
+
// Don't do anything if the socket close event was initiated by the client.
|
|
65
69
|
if (evt.wasClean) {
|
|
66
70
|
return;
|
|
67
71
|
}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2
|
-
// @ts-ignore
|
|
3
1
|
import { BOOTSTRAP_END, INIT, INIT_MODULE } from 'lwr/metrics';
|
|
4
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
5
|
-
// @ts-ignore
|
|
6
2
|
import { logOperationStart, logOperationEnd } from 'lwr/profiler';
|
|
7
3
|
|
|
8
4
|
// TODO: This is a temporal workaround until https://github.com/salesforce/lwc/pull/2083 is sorted - tmp
|
|
@@ -100,8 +96,6 @@ export function init(rootModules, serverData = {}) {
|
|
|
100
96
|
|
|
101
97
|
// hydrate SSR'd components
|
|
102
98
|
if (propsId) {
|
|
103
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
104
|
-
// @ts-ignore
|
|
105
99
|
hydrateComponentProxy(element, ctor, serverData[propsId] || {});
|
|
106
100
|
logOperationEnd({
|
|
107
101
|
id: INIT_MODULE,
|