@lwrjs/client-modules
Advanced tools
Comparing version 0.0.2-alpha1 to 0.0.2-alpha10
@@ -29,4 +29,5 @@ "use strict"; | ||
specifier, | ||
path: absFilepath, | ||
type: 'text/javascript', | ||
type: 'application/javascript', | ||
defer: true, | ||
stream: fs_1.default.createReadStream(absFilepath), | ||
src: this.context.resourceRegistry.resolveResourceUri(resource, context), | ||
@@ -33,0 +34,0 @@ }; |
@@ -1,14 +0,10 @@ | ||
// @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'; | ||
const isDevMode = process.env.NODE_ENV === 'dev'; | ||
if (isDevMode) { | ||
const socket = new WebSocket(`ws://${location.host}`); | ||
socket.addEventListener('message', async ({ data }) => { | ||
const event = JSON.parse(data); | ||
if (event.eventType === 'moduleUpdate') { | ||
@@ -20,14 +16,9 @@ const { | ||
} = event.payload; | ||
const oldModule = await import(oldUri); | ||
const newModule = await import(newUri); | ||
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); | ||
} | ||
updateStaleModule({ | ||
oldModule, | ||
newModule, | ||
specifier: `${namespace}/${name}`, | ||
}); | ||
} | ||
@@ -34,0 +25,0 @@ }); |
@@ -15,14 +15,40 @@ /** | ||
/** | ||
* 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) | ||
* 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]] | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export function init(rootAppSpecifier, rootApp) { | ||
if (typeof customElements !== 'undefined') { | ||
const elementName = toKebabCase(rootAppSpecifier); | ||
customElements.define(elementName, rootApp.CustomElementConstructor); | ||
export function init(rootModules) { | ||
if (typeof customElements !== 'undefined' && typeof document !== 'undefined') { | ||
const uniqueRoot = rootModules.length === 1; | ||
rootModules.forEach(([moduleSpecifier, ctor]) => { | ||
// Kebab-case the specifier | ||
const elementName = toKebabCase(moduleSpecifier); // Add the root to the CustomElementRegistry | ||
customElements.define(elementName, ctor.CustomElementConstructor); | ||
}); | ||
if (uniqueRoot) { | ||
// Append the root element to the DOM, if it does not exist | ||
const rootElementName = toKebabCase(rootModules[0][0]); | ||
const rootEl = document.body.querySelector(rootElementName); | ||
if (!rootEl) { | ||
const el = document.createElement(rootElementName); | ||
const container = document.querySelector('[lwr-root]'); | ||
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); | ||
} | ||
} | ||
} | ||
} | ||
} |
@@ -6,5 +6,5 @@ # 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) | ||
- defining the _root application 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 application 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], | ||
]); | ||
``` | ||
@@ -38,9 +42,11 @@ | ||
// 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_: | ||
@@ -47,0 +53,0 @@ ```json |
@@ -1,14 +0,10 @@ | ||
// @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'; | ||
const isDevMode = process.env.NODE_ENV === 'dev'; | ||
if (isDevMode) { | ||
const socket = new WebSocket(`ws://${location.host}`); | ||
socket.addEventListener('message', async ({ data }) => { | ||
const event = JSON.parse(data); | ||
if (event.eventType === 'moduleUpdate') { | ||
@@ -20,14 +16,9 @@ const { | ||
} = event.payload; | ||
const oldModule = await import(oldUri); | ||
const newModule = await import(newUri); | ||
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); | ||
} | ||
updateStaleModule({ | ||
oldModule, | ||
newModule, | ||
specifier: `${namespace}/${name}`, | ||
}); | ||
} | ||
@@ -34,0 +25,0 @@ }); |
import { init } from '../init'; | ||
const LauraCmp = { | ||
CustomElementConstructor: class Fake {}, | ||
const TestCmp = { | ||
CustomElementConstructor: class Fake extends HTMLElement {}, | ||
}; | ||
const KhangCmp = { | ||
CustomElementConstructor: class Fake {}, | ||
const TestCmp2 = { | ||
CustomElementConstructor: class Fake extends HTMLElement {}, | ||
}; | ||
const TestCmp3 = { | ||
CustomElementConstructor: class Fake extends HTMLElement {}, | ||
}; | ||
const TestCmp4 = { | ||
CustomElementConstructor: class Fake extends HTMLElement {}, | ||
}; | ||
const TestCmp5 = { | ||
CustomElementConstructor: class Fake extends HTMLElement {}, | ||
}; | ||
describe('LWR init', () => { | ||
it('init()', () => { | ||
init('generated/lauraHomePage', LauraCmp); | ||
it('initializes and appends root element to <body>', () => { | ||
init([['generated/lauraHomePage', TestCmp]]); | ||
expect(customElements.get('generated-laura-home-page')).toBeDefined(); | ||
}); | ||
it('init() headless', () => { | ||
it('initializes and append root element to lwr-root node', () => { | ||
const container = document.createElement('div'); | ||
container.setAttribute('lwr-root', ''); | ||
document.body.appendChild(container); | ||
init([['c/darrell', TestCmp2]]); | ||
expect(customElements.get('c-darrell')).toBeDefined(); | ||
}); | ||
it('initializes and skips appending the root element', () => { | ||
document.body.appendChild(document.createElement('c-diego')); | ||
init([['c/diego', TestCmp3]]); | ||
expect(customElements.get('c-diego')).toBeDefined(); | ||
}); | ||
it('initializes and appends multiple root elements to <body>', () => { | ||
init([ | ||
['c/hunter', TestCmp4], | ||
['c/brian', TestCmp5], | ||
]); | ||
expect(customElements.get('c-hunter')).toBeDefined(); | ||
expect(customElements.get('c-brian')).toBeDefined(); | ||
}); | ||
it('initializes in a headless environment', () => { | ||
const oldCustomElements = customElements; | ||
delete globalThis.customElements; | ||
init('c/khang', KhangCmp); | ||
init([['c/khang', TestCmp]]); | ||
globalThis.customElements = oldCustomElements; | ||
@@ -20,0 +49,0 @@ expect(customElements.get('c-khang')).toBeUndefined(); |
@@ -0,1 +1,3 @@ | ||
import type { LightningElement } from 'lwc/types'; | ||
/** | ||
@@ -19,12 +21,38 @@ * Convert a module specifier into a valid CustomElement registry name: | ||
/** | ||
* 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) | ||
* 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(rootAppSpecifier: string, rootApp): void { | ||
if (typeof customElements !== 'undefined') { | ||
const elementName = toKebabCase(rootAppSpecifier); | ||
customElements.define(elementName, rootApp.CustomElementConstructor); | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export function init(rootModules: [string, LightningElement][]): void { | ||
if (typeof customElements !== 'undefined' && typeof document !== 'undefined') { | ||
const uniqueRoot = rootModules.length === 1; | ||
rootModules.forEach(([moduleSpecifier, ctor]) => { | ||
// Kebab-case the specifier | ||
const elementName = toKebabCase(moduleSpecifier); | ||
// Add the root to the CustomElementRegistry | ||
customElements.define(elementName, ctor.CustomElementConstructor); | ||
}); | ||
if (uniqueRoot) { | ||
// Append the root element to the DOM, if it does not exist | ||
const rootElementName = toKebabCase(rootModules[0][0]); | ||
const rootEl = document.body.querySelector(rootElementName); | ||
if (!rootEl) { | ||
const el = document.createElement(rootElementName); | ||
const container = document.querySelector('[lwr-root]'); | ||
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); | ||
} | ||
} | ||
} | ||
} | ||
} |
@@ -6,5 +6,5 @@ # 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) | ||
- defining the _root application 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 application 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], | ||
]); | ||
``` | ||
@@ -38,9 +42,11 @@ | ||
// 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_: | ||
@@ -47,0 +53,0 @@ ```json |
@@ -7,3 +7,12 @@ { | ||
}, | ||
"version": "0.0.2-alpha1", | ||
"version": "0.0.2-alpha10", | ||
"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" | ||
}, | ||
"types": "build/index.d.ts", | ||
@@ -20,2 +29,8 @@ "main": "build/index.js", | ||
}, | ||
"dependencies": { | ||
"@lwrjs/shared-utils": "0.0.2-alpha10" | ||
}, | ||
"devDependencies": { | ||
"lwc": "1.6.3" | ||
}, | ||
"lwc": { | ||
@@ -38,3 +53,3 @@ "modules": [ | ||
}, | ||
"gitHead": "ae4583dba86a00596d3641f60144d8c1f39a0d78" | ||
"gitHead": "cb54d75e833b0ecb269a74ae40da0337a18846c1" | ||
} |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
248900
13
6306
1
58
1
1
3
+ Added@lwrjs/shared-utils@0.0.2-alpha10(transitive)
+ Addedparse5@6.0.1(transitive)
+ Addedparse5-sax-parser@6.0.1(transitive)
+ Addedslugify@1.6.6(transitive)