Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@lwc/compiler

Package Overview
Dependencies
Maintainers
14
Versions
783
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lwc/compiler - npm Package Compare versions

Comparing version 6.6.3 to 7.0.0-alpha.0

99

dist/index.cjs.js

@@ -214,3 +214,5 @@ /**

try {
result = templateCompiler.compile(src, {
result = templateCompiler.compile(src, filename, {
name,
namespace,
experimentalDynamicDirective,

@@ -237,98 +239,11 @@ // TODO [#3370]: remove experimental template expression flag

const warnings = result.warnings.filter((_) => _.level === errors.DiagnosticLevel.Warning);
// TODO [#3733]: remove support for legacy scope tokens
const { scopeToken, legacyScopeToken } = generateScopeTokens(filename, namespace, name);
// Rollup only cares about the mappings property on the map. Since producing a source map for
// the template doesn't make sense, the transform returns an empty mappings.
return {
code: serialize(result.code, filename, scopeToken, legacyScopeToken, apiVersion),
code: result.code,
map: { mappings: '' },
warnings,
cssScopeTokens: [
scopeToken,
`${scopeToken}-host`, // implicit scope token created by `makeHostToken()` in `@lwc/engine-core`
// The legacy tokens must be returned as well since we technically don't know what we're going to render
// This is not strictly required since this is only used for Jest serialization (as of this writing),
// and people are unlikely to set runtime flags in Jest, but it is technically correct to include this.
legacyScopeToken,
`${legacyScopeToken}-host`,
],
cssScopeTokens: result.cssScopeTokens,
};
}
// The reason this hash code implementation [1] is chosen is because:
// 1. It has a very low hash collision rate - testing a list of 466,551 English words [2], it generates no collisions
// 2. It is fast - it can hash those 466k words in 70ms (Node 16, 2020 MacBook Pro)
// 3. The output size is reasonable (32-bit - this can be base-32 encoded at 10-11 characters)
//
// Also note that the reason we're hashing rather than generating a random number is because
// we want the output to be predictable given the input, which helps with caching.
//
// [1]: https://stackoverflow.com/a/52171480
// [2]: https://github.com/dwyl/english-words/blob/a77cb15f4f5beb59c15b945f2415328a6b33c3b0/words.txt
function generateHashCode(str) {
const seed = 0;
let h1 = 0xdeadbeef ^ seed;
let h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);
h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507);
h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}
function escapeScopeToken(input) {
// Minimal escape for strings containing the "@" and "#" characters, which are disallowed
// in certain cases in attribute names
return input.replace(/@/g, '___at___').replace(/#/g, '___hash___');
}
function generateScopeTokens(filename, namespace, name) {
const uniqueToken = `${namespace}-${name}_${path__namespace.basename(filename, path__namespace.extname(filename))}`;
// This scope token is all lowercase so that it works correctly in case-sensitive namespaces (e.g. SVG).
// It is deliberately designed to discourage people from relying on it by appearing somewhat random.
// (But not totally random, because it's nice to have stable scope tokens for our own tests.)
// Base-32 is chosen because it is not case-sensitive (0-v), and generates short strings with the given hash
// code implementation (10-11 characters).
const hashCode = generateHashCode(uniqueToken);
const scopeToken = `lwc-${hashCode.toString(32)}`;
// This scope token is based on the namespace and name, and contains a mix of uppercase/lowercase chars
const legacyScopeToken = escapeScopeToken(uniqueToken);
return {
scopeToken,
legacyScopeToken,
};
}
function serialize(code, filename, scopeToken, legacyScopeToken, apiVersion) {
const cssRelPath = `./${path__namespace.basename(filename, path__namespace.extname(filename))}.css`;
const scopedCssRelPath = `./${path__namespace.basename(filename, path__namespace.extname(filename))}.scoped.css`;
let buffer = '';
buffer += `import { freezeTemplate } from "lwc";\n\n`;
buffer += `import _implicitStylesheets from "${cssRelPath}";\n\n`;
buffer += `import _implicitScopedStylesheets from "${scopedCssRelPath}?scoped=true";\n\n`;
buffer += code;
buffer += '\n\n';
buffer += 'if (_implicitStylesheets) {\n';
buffer += ` tmpl.stylesheets.push.apply(tmpl.stylesheets, _implicitStylesheets);\n`;
buffer += `}\n`;
buffer += 'if (_implicitScopedStylesheets) {\n';
buffer += ` tmpl.stylesheets.push.apply(tmpl.stylesheets, _implicitScopedStylesheets);\n`;
buffer += `}\n`;
if (shared.isAPIFeatureEnabled(0 /* APIFeature.LOWERCASE_SCOPE_TOKENS */, apiVersion)) {
// Include both the new and legacy tokens, so that the runtime can decide based on a flag whether
// we need to render the legacy one. This is designed for cases where the legacy one is required
// for backwards compat (e.g. global stylesheets that rely on the legacy format for a CSS selector).
buffer += `tmpl.stylesheetToken = "${scopeToken}";\n`;
buffer += `tmpl.legacyStylesheetToken = "${legacyScopeToken}";\n`;
}
else {
// In old API versions, we can just keep doing what we always did
buffer += `tmpl.stylesheetToken = "${legacyScopeToken}";\n`;
}
// Note that `renderMode` and `slots` are already rendered in @lwc/template-compiler and appear
// as `code` above. At this point, no more expando props should be added to `tmpl`.
buffer += 'freezeTemplate(tmpl);\n';
return buffer;
}

@@ -499,3 +414,3 @@ /*

/** The version of LWC being used. */
const version = "6.6.3";
const version = "7.0.0-alpha.0";

@@ -505,3 +420,3 @@ exports.transform = transform;

exports.version = version;
/** version: 6.6.3 */
/** version: 7.0.0-alpha.0 */
//# sourceMappingURL=index.cjs.js.map

@@ -189,3 +189,5 @@ /**

try {
result = compile(src, {
result = compile(src, filename, {
name,
namespace,
experimentalDynamicDirective,

@@ -212,98 +214,11 @@ // TODO [#3370]: remove experimental template expression flag

const warnings = result.warnings.filter((_) => _.level === DiagnosticLevel.Warning);
// TODO [#3733]: remove support for legacy scope tokens
const { scopeToken, legacyScopeToken } = generateScopeTokens(filename, namespace, name);
// Rollup only cares about the mappings property on the map. Since producing a source map for
// the template doesn't make sense, the transform returns an empty mappings.
return {
code: serialize(result.code, filename, scopeToken, legacyScopeToken, apiVersion),
code: result.code,
map: { mappings: '' },
warnings,
cssScopeTokens: [
scopeToken,
`${scopeToken}-host`, // implicit scope token created by `makeHostToken()` in `@lwc/engine-core`
// The legacy tokens must be returned as well since we technically don't know what we're going to render
// This is not strictly required since this is only used for Jest serialization (as of this writing),
// and people are unlikely to set runtime flags in Jest, but it is technically correct to include this.
legacyScopeToken,
`${legacyScopeToken}-host`,
],
cssScopeTokens: result.cssScopeTokens,
};
}
// The reason this hash code implementation [1] is chosen is because:
// 1. It has a very low hash collision rate - testing a list of 466,551 English words [2], it generates no collisions
// 2. It is fast - it can hash those 466k words in 70ms (Node 16, 2020 MacBook Pro)
// 3. The output size is reasonable (32-bit - this can be base-32 encoded at 10-11 characters)
//
// Also note that the reason we're hashing rather than generating a random number is because
// we want the output to be predictable given the input, which helps with caching.
//
// [1]: https://stackoverflow.com/a/52171480
// [2]: https://github.com/dwyl/english-words/blob/a77cb15f4f5beb59c15b945f2415328a6b33c3b0/words.txt
function generateHashCode(str) {
const seed = 0;
let h1 = 0xdeadbeef ^ seed;
let h2 = 0x41c6ce57 ^ seed;
for (let i = 0, ch; i < str.length; i++) {
ch = str.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);
h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507);
h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}
function escapeScopeToken(input) {
// Minimal escape for strings containing the "@" and "#" characters, which are disallowed
// in certain cases in attribute names
return input.replace(/@/g, '___at___').replace(/#/g, '___hash___');
}
function generateScopeTokens(filename, namespace, name) {
const uniqueToken = `${namespace}-${name}_${path.basename(filename, path.extname(filename))}`;
// This scope token is all lowercase so that it works correctly in case-sensitive namespaces (e.g. SVG).
// It is deliberately designed to discourage people from relying on it by appearing somewhat random.
// (But not totally random, because it's nice to have stable scope tokens for our own tests.)
// Base-32 is chosen because it is not case-sensitive (0-v), and generates short strings with the given hash
// code implementation (10-11 characters).
const hashCode = generateHashCode(uniqueToken);
const scopeToken = `lwc-${hashCode.toString(32)}`;
// This scope token is based on the namespace and name, and contains a mix of uppercase/lowercase chars
const legacyScopeToken = escapeScopeToken(uniqueToken);
return {
scopeToken,
legacyScopeToken,
};
}
function serialize(code, filename, scopeToken, legacyScopeToken, apiVersion) {
const cssRelPath = `./${path.basename(filename, path.extname(filename))}.css`;
const scopedCssRelPath = `./${path.basename(filename, path.extname(filename))}.scoped.css`;
let buffer = '';
buffer += `import { freezeTemplate } from "lwc";\n\n`;
buffer += `import _implicitStylesheets from "${cssRelPath}";\n\n`;
buffer += `import _implicitScopedStylesheets from "${scopedCssRelPath}?scoped=true";\n\n`;
buffer += code;
buffer += '\n\n';
buffer += 'if (_implicitStylesheets) {\n';
buffer += ` tmpl.stylesheets.push.apply(tmpl.stylesheets, _implicitStylesheets);\n`;
buffer += `}\n`;
buffer += 'if (_implicitScopedStylesheets) {\n';
buffer += ` tmpl.stylesheets.push.apply(tmpl.stylesheets, _implicitScopedStylesheets);\n`;
buffer += `}\n`;
if (isAPIFeatureEnabled(0 /* APIFeature.LOWERCASE_SCOPE_TOKENS */, apiVersion)) {
// Include both the new and legacy tokens, so that the runtime can decide based on a flag whether
// we need to render the legacy one. This is designed for cases where the legacy one is required
// for backwards compat (e.g. global stylesheets that rely on the legacy format for a CSS selector).
buffer += `tmpl.stylesheetToken = "${scopeToken}";\n`;
buffer += `tmpl.legacyStylesheetToken = "${legacyScopeToken}";\n`;
}
else {
// In old API versions, we can just keep doing what we always did
buffer += `tmpl.stylesheetToken = "${legacyScopeToken}";\n`;
}
// Note that `renderMode` and `slots` are already rendered in @lwc/template-compiler and appear
// as `code` above. At this point, no more expando props should be added to `tmpl`.
buffer += 'freezeTemplate(tmpl);\n';
return buffer;
}

@@ -474,6 +389,6 @@ /*

/** The version of LWC being used. */
const version = "6.6.3";
const version = "7.0.0-alpha.0";
export { transform, transformSync, version };
/** version: 6.6.3 */
/** version: 7.0.0-alpha.0 */
//# sourceMappingURL=index.js.map

22

LICENSE.md

@@ -18,4 +18,24 @@ # LWC core license

MIT license defined in package.json in v0.4.0.
The MIT License (MIT)
Copyright © 2024 James Garbutt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
## entities

@@ -22,0 +42,0 @@

@@ -7,3 +7,3 @@ {

"name": "@lwc/compiler",
"version": "6.6.3",
"version": "7.0.0-alpha.0",
"description": "LWC compiler",

@@ -46,3 +46,3 @@ "keywords": [

"dependencies": {
"@babel/core": "7.24.4",
"@babel/core": "7.24.5",
"@babel/plugin-transform-async-generator-functions": "7.24.3",

@@ -53,9 +53,9 @@ "@babel/plugin-transform-async-to-generator": "7.24.1",

"@locker/babel-plugin-transform-unforgeables": "0.20.0",
"@lwc/babel-plugin-component": "6.6.3",
"@lwc/errors": "6.6.3",
"@lwc/shared": "6.6.3",
"@lwc/ssr-compiler": "6.6.3",
"@lwc/style-compiler": "6.6.3",
"@lwc/template-compiler": "6.6.3"
"@lwc/babel-plugin-component": "7.0.0-alpha.0",
"@lwc/errors": "7.0.0-alpha.0",
"@lwc/shared": "7.0.0-alpha.0",
"@lwc/ssr-compiler": "7.0.0-alpha.0",
"@lwc/style-compiler": "7.0.0-alpha.0",
"@lwc/template-compiler": "7.0.0-alpha.0"
}
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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