New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@lwrjs/client-modules

Package Overview
Dependencies
Maintainers
8
Versions
499
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lwrjs/client-modules - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2-alpha.9

build/modules/lwr/hmr/util/swap.js

70

build/modules/lwr/hmr/hmr.js

@@ -1,35 +0,51 @@

// @ts-nocheck
import { registerTemplateSwap, registerStyleSwap, registerComponentSwap } from 'lwc';
import { updateStaleModule } from './util/swap';
export function initHMR() {
// eslint-disable-next-line no-undef
const isDevMode = globalThis.process.env.NODE_ENV === 'dev';
// This is a workaround until we don't change the way HMR works
// The server will always return the same canonical "latest URL"
// So we need to track the last new URI instead
const URI_MAPPING = new Map();
if (isDevMode) {
const socket = new WebSocket(`ws://${location.host}`);
async function moduleUpdate(payload) {
const {
oldUri,
newUri,
module: { specifier },
} = payload;
socket.addEventListener('message', async ({ data }) => {
const event = JSON.parse(data);
const lastEvalutedUri = URI_MAPPING.get(oldUri) || oldUri;
const oldModule = await import(lastEvalutedUri);
const newModule = await import(newUri);
URI_MAPPING.set(oldUri, newUri);
if (event.eventType === 'moduleUpdate') {
const {
oldUri,
newUri,
module: { namespace, name },
} = event.payload;
updateStaleModule({
oldModule,
newModule,
specifier,
});
}
const oldModule = await import(oldUri);
const newModule = await import(newUri);
async function viewUpdate(payload) {
const pathName = window.location.pathname;
const requestPath = payload.viewId.requestPath;
if (name.endsWith('html') && newModule.default) {
console.log(`Swapping html template for module "${namespace}/${name}"`);
registerTemplateSwap(oldModule.default, newModule.default);
} else if (name.endsWith('css') && newModule.default) {
registerStyleSwap(oldModule.default[0], newModule.default[0]);
} else {
registerComponentSwap(oldModule.default, newModule.default);
}
}
});
if (requestPath === pathName) {
window.location.reload();
}
}
export function initHMR(serverURI = '') {
// {apiVersion}/hmr/{format}/{compat}?debug
const socket = new WebSocket(`ws://${location.host}/${serverURI}`);
socket.addEventListener('message', async ({ data }) => {
const { eventType, payload } = JSON.parse(data);
switch (eventType) {
case 'moduleUpdate':
return moduleUpdate(payload);
case 'viewUpdate':
return viewUpdate(payload);
default:
return;
}
});
}

@@ -0,1 +1,11 @@

// TODO: This is a temporal workaround until https://github.com/salesforce/lwc/pull/2083 is sorted
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { createElement } from 'lwc';
function initializeWebComponent(elementName, Ctor) {
return createElement(elementName, {
is: Ctor
});
}
/**

@@ -11,2 +21,4 @@ * Convert a module specifier into a valid CustomElement registry name:

*/
function toKebabCase(specifier) {

@@ -16,14 +28,70 @@ return specifier.replace(/\/v\/[a-zA-Z0-9-_.]+$/, '').replace('/', '-').replace(/([A-Z])/g, c => `-${c.toLowerCase()}`);

/**
* Import any requested static application dependencies and
* define the root application component into the CustomElement registry.
* @param rootAppSpecifier - The bare specifier for the component, eg: 'x/appRoot'
* @param rootApp - A reference to the Constructor (extended from LightningElement)
* This method maps between attribute names
* and the corresponding props name.
*/
export function init(rootAppSpecifier, rootApp) {
if (typeof customElements !== 'undefined') {
const elementName = toKebabCase(rootAppSpecifier);
customElements.define(elementName, rootApp.CustomElementConstructor);
const CAMEL_REGEX = /-([a-z])/g;
export function getPropFromAttrName(propName) {
return propName.replace(CAMEL_REGEX, g => g[1].toUpperCase());
}
/**
* Import any requested static application dependencies, define the root
* application component(s) into the CustomElement registry, and inject them.
* @param rootModules - An array of arrays, each one holding a pair of
* bare specifier and corresponding LightningElement constructor
* @example - [['x/appRoot', appCtor], ['x/nav', navCtor]]
*/
export function init(rootModules) {
if (typeof customElements !== 'undefined' && typeof document !== 'undefined') {
const container = document.querySelector('[lwr-root]');
rootModules.forEach(([moduleSpecifier, ctor]) => {
// Kebab-case the specifier
const elementName = toKebabCase(moduleSpecifier); // Append the root element to the DOM, if it does not exist
// this is for SPA like routes (one component at the root level) utilizing the lwr-root directive
let el = document.body.querySelector(elementName);
if (!el) {
el = initializeWebComponent(elementName, ctor);
if (container) {
// Append to a node with the "lwr-root" attribute
container.appendChild(el);
} else {
// Otherwise, add the root to the <body>
document.body.appendChild(el);
}
} else {
// We have rendered/ssred an HTML page and we need to reify the components
// Due to the bug described on the header, for each custom element
// we collect the attributes and we replace the element with the new synthetic contructor
const customElements = document.querySelectorAll(elementName);
customElements.forEach(customElement => {
const newElement = initializeWebComponent(elementName, ctor);
for (const {
name,
value
} of customElement.attributes) {
newElement.setAttribute(name, value);
const prop = getPropFromAttrName(name);
if (prop in newElement) {
// Set attributes as properties too for reactivity
newElement[prop] = value;
}
} // Move the children
while (customElement.childNodes.length > 0) {
newElement.appendChild(customElement.childNodes[0]);
}
customElement.parentElement.replaceChild(newElement, customElement);
});
}
});
}
}

@@ -5,6 +5,6 @@ # Lightning Web Runtime :: Application Initialization

- importing static application dependencies
- defining the _root application component_ into the [`CustomElementRegistry`](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry)
- importing static dependencies
- defining the _root component(s)_ into the [`CustomElementRegistry`](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry)
This results in the _root application component_ being renderable by the DOM on first page load.
This results in the _root component(s)_ being renderable by the DOM on first page load.

@@ -15,3 +15,3 @@ ## Definition

interface InitAPI {
init(rootAppSpecifier: string, rootApp: LightningElement): void;
init(rootModules: [string, LightningElement][]): void;
}

@@ -25,4 +25,8 @@ ```

import xAppRoot from 'x/appRoot';
import xNav from 'x/nav';
init('x/appRoot', xAppRoot);
init([
['x/appRoot', xAppRoot],
['x/nav', xNav],
]);
```

@@ -32,3 +36,3 @@

The default `lwr/init` module used by an LWR application can be overridden with these steps:
The default `lwr/init` module used by an LWR route can be overridden with these steps:

@@ -39,18 +43,21 @@ 1. Create a module exporting an `init` function which implements the `InitAPI` interface:

// src/modules/example/init/init.js
export function init(rootAppSpecifier, rootApp) {
const elementName = rootAppSpecifier.replace(/\//, '-');
customElements.define(elementName, rootApp.CustomElementConstructor);
export function init(rootModules) {
rootModules.forEach(([moduleSpecifier, ctor]) => {
const elementName = toKebabCase(moduleSpecifier);
customElements.define(elementName, ctor.CustomElementConstructor);
});
}
```
2. Configure the module specifier in _lwr.config.json_:
2. Configure the `init` module specifier in _lwr.config.json_:
```json
{
"modules": [],
"application": {
"root": "example/app",
"init": "example/init"
}
"routes": [
{
"id": "example",
"init": "example/init"
}
]
}
```

@@ -7,32 +7,49 @@ {

},
"version": "0.0.1",
"types": "build/index.d.ts",
"main": "build/index.js",
"version": "0.0.2-alpha.9+8e3fccca",
"homepage": "https://lwr.dev/",
"repository": {
"type": "git",
"url": "https://github.com/salesforce/lwr.git",
"directory": "packages/@lwrjs/client-modules"
},
"bugs": {
"url": "https://github.com/salesforce/lwr/issues"
},
"type": "module",
"types": "build/es/index.d.ts",
"main": "build/es/index.js",
"module": "build/es/index.js",
"exports": {
".": "./build/es/index.js"
},
"files": [
"build/**/*.js",
"build/**/*.d.ts",
"modules",
"assets"
"build/**/*.d.ts"
],
"scripts": {
"build": "node ../../../bin/pack-lwc --dir modules build/modules"
"build": "node ../../../bin/pack-lwc --dir modules build/modules && yarn build:locker",
"build:locker": "rollup --config ./scripts/rollup.config.locker.js"
},
"dependencies": {
"@locker/sandbox": "^0.12.4",
"@lwrjs/shared-utils": "0.0.2-alpha.9+8e3fccca"
},
"lwc": {
"modules": [
{
"name": "lwc",
"path": "assets/lwc/engine.js",
"description": "Temporal Hack: We need to fix the lwc package to make npm: 'lwc' work"
},
{
"dir": "modules"
"dir": "build/modules"
}
],
"expose": [
"lwc",
"lwr/hmr",
"lwr/init"
"lwr/init",
"lwr/servicesESM",
"lwr/lockerDefine",
"lwr/lockerSandbox"
]
},
"gitHead": "638109b1e3e85483bc63c87ed2a6c3d582f28e04"
"engines": {
"node": ">=14.15.1 <15"
},
"gitHead": "8e3fcccaba5138a3c6fac4c75d4506987b6460b7"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc