@stencil/core 5.0.0-beta.14 → 5.0.0-beta.16

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.
@@ -1,9 +1,9 @@
1
1
  import { n as __require } from "./rolldown-runtime-BhDjJH2R.mjs";
2
- import { S as HYDRATED_CSS } from "./client-CAQvc3hT.mjs";
2
+ import { E as SERVER_BUILD_FLAGS, T as HYDRATED_CSS, w as CLIENT_BUILD_FLAGS } from "./client-BUal4Vkx.mjs";
3
3
  import { $ as VALID_CONFIG_OUTPUT_TARGETS, A as DIST_LAZY, D as COPY, E as COLLECTION_MANIFEST_FILE_NAME, J as STANDALONE, L as EVENT_FLAGS, P as DOCS_JSON, Q as TYPES, R as GENERATED_DTS, S as ASSETS, T as COLLECTION_APP_DATA_FILE_NAME, U as LOADER_BUNDLE, X as STYLE_EXT, Y as STATS, a as isBoolean$1, b as unique, c as isFunction, d as isObject, et as WATCH_FLAGS, f as isString$1, g as sortBy, i as fromEntries, l as isIterable, m as noop, p as mergeIntoWith, r as flatOne, t as dashToPascalCase, u as isNumber$1, v as toDashCase, w as COLLECTION, y as toTitleCase, z as GLOBAL_STYLE } from "./helpers-Cpp3qc3u.mjs";
4
4
  import { E as escapeRegExpSpecialCharacters, S as formatComponentRuntimeMeta, T as byteSize, _ as loadRolldownDiagnostics, a as getSourceMappingUrlForEndOfFile, b as splitLineBreaks, c as err, f as augmentDiagnosticWithNode, g as isRolldownError, h as createOnWarnFn, i as getInlineSourceMappingUrlLinker, l as map, m as loadTypeScriptDiagnostics, n as validateComponentTag, p as loadTypeScriptDiagnostic, r as isRemoteUrl, s as rolldownToStencilSourceMap, t as validateComponentModes, u as ok, w as stringifyRuntimeData, x as isRootPath, y as normalizeDiagnostics } from "./validation-DAdGTrys.mjs";
5
5
  import { $ as catchError, A as isOutputTargetDocsVscode, B as relativeImport, C as isOutputTargetDistLazy, D as isOutputTargetDocsCustomElementsManifest, E as isOutputTargetDocsCustom, F as isOutputTargetStandalone, G as normalizeFsPathQuery, H as join$2, I as isOutputTargetStats, J as resolve$2, K as normalizePath, L as isOutputTargetTypes, M as isOutputTargetLoaderBundle, N as isOutputTargetSsr, O as isOutputTargetDocsJson, P as isOutputTargetSsrWasm, Q as buildWarn, R as isOutputTargetWww, S as isOutputTargetCustom, T as isOutputTargetDocsAgentSkill, V as shouldExcludeComponent, W as normalizeFsPath, X as buildError, Z as buildJsonFileError, a as hasDependency, b as isOutputTargetCollection, d as parsePackageJson, et as hasError, f as readOnlyArrayHasStringMember, g as getComponentsDtsSrcFilePath, h as filterExcludedComponents, i as getTextDocs, j as isOutputTargetGlobalStyle, k as isOutputTargetDocsReadme, l as isTsFile, m as filterActiveTargets, n as createJsVarName, o as isDtsFile, p as readPackageJson, q as relative$1, r as generatePreamble, rt as isGlob, t as addDocBlock, tt as hasWarning, u as isTsxFile, v as getComponentsFromModules, w as isOutputTargetDocs, x as isOutputTargetCopy, y as isOutputTargetAssets, z as isValidConfigOutputTarget } from "./util-IKfWWLJo.mjs";
6
- import { i as CustomElementsExportBehaviorOptions, o as buildEvents, r as createNodeLogger, t as createNodeSys } from "./node-Bw9pHJOq.mjs";
6
+ import { i as CustomElementsExportBehaviorOptions, o as buildEvents, r as createNodeLogger, t as createNodeSys } from "./node-DGo5Qu7U.mjs";
7
7
  import ts, { default as ts$1 } from "typescript";
8
8
  import { readFileSync } from "node:fs";
9
9
  import { basename, dirname, isAbsolute, join, resolve } from "node:path";
@@ -23,7 +23,6 @@ import { minify } from "terser";
23
23
  import { SelectorType, parse, stringify } from "css-what";
24
24
  import { execFile } from "node:child_process";
25
25
  import { promisify } from "node:util";
26
- import { execSync } from "child_process";
27
26
  import * as os from "os";
28
27
  import browserslist from "browserslist";
29
28
  import { browserslistToTargets, transform } from "lightningcss";
@@ -462,9 +461,9 @@ const scopeCss = (cssText, scopeId, commentOriginalSelector) => {
462
461
  };
463
462
  //#endregion
464
463
  //#region src/version.ts
465
- const version = "5.0.0-beta.14";
466
- const buildId = "1790782456";
467
- const vermoji = "🐬";
464
+ const version = "5.0.0-beta.16";
465
+ const buildId = "1791325639";
466
+ const vermoji = "🔮";
468
467
  /**
469
468
  * Get the installed version of a tool/dependency.
470
469
  * Handles packages with exports maps that point to subdirectories.
@@ -2293,12 +2292,10 @@ const updateBuildConditionals = (config, b) => {
2293
2292
  const CREATE_EVENT = "__stencil_createEvent";
2294
2293
  const DEFINE_CUSTOM_ELEMENT = "__stencil_defineCustomElement";
2295
2294
  const GET_ELEMENT = "__stencil_getElement";
2296
- const HOST = "__stencil_Host";
2297
2295
  const HTML_ELEMENT = "HTMLElement";
2298
2296
  const PROXY_CUSTOM_ELEMENT = "__stencil_proxyCustomElement";
2299
2297
  const REGISTER_INSTANCE = "__stencil_registerInstance";
2300
2298
  const REGISTER_HOST = "__stencil_registerHost";
2301
- const H = "__stencil_h";
2302
2299
  const TRANSFORM_TAG = "__stencil_transformTag";
2303
2300
  const GET_REGISTRY = "__stencil_getRegistry";
2304
2301
  const INJECT_SIDE_EFFECT_STYLE = "__stencil_injectSideEffectStyle";
@@ -2306,9 +2303,7 @@ const RUNTIME_APIS = {
2306
2303
  createEvent: `createEvent as ${CREATE_EVENT}`,
2307
2304
  defineCustomElement: `defineCustomElement as ${DEFINE_CUSTOM_ELEMENT}`,
2308
2305
  getElement: `getElement as ${GET_ELEMENT}`,
2309
- h: `h as ${H}`,
2310
2306
  legacyH: `h`,
2311
- Host: `Host as ${HOST}`,
2312
2307
  HTMLElement: HTML_ELEMENT,
2313
2308
  proxyCustomElement: `proxyCustomElement as ${PROXY_CUSTOM_ELEMENT}`,
2314
2309
  registerHost: `registerHost as ${REGISTER_HOST}`,
@@ -4498,7 +4493,7 @@ const appDataPlugin = (config, compilerCtx, buildCtx, buildConditionals, platfor
4498
4493
  name: "appDataPlugin",
4499
4494
  resolveId: {
4500
4495
  filter: { id: /^@stencil\/core\/app-(data|globals)$/ },
4501
- handler(id, importer) {
4496
+ handler(id) {
4502
4497
  if (id === "@stencil/core/app-data" || id === "@stencil/core/app-globals") {
4503
4498
  if (platform === "worker") this.error("@stencil/core packages cannot be imported from a worker.");
4504
4499
  return id;
@@ -4687,19 +4682,6 @@ const appendNamespace = (config, s) => {
4687
4682
  };
4688
4683
  //#endregion
4689
4684
  //#region src/compiler/sys/fetch/fetch-utils.ts
4690
- /**
4691
- * A fetch wrapper which dispatches to `sys.fetch` if present, and otherwise
4692
- * uses `global.fetch`.
4693
- *
4694
- * @param sys a compiler system object
4695
- * @param input a `RequestInfo` object
4696
- * @param init an optional `RequestInit` object
4697
- * @returns a Promise wrapping a response
4698
- */
4699
- const httpFetch = (sys, input, init) => {
4700
- if (sys && isFunction(sys.fetch)) return sys.fetch(input, init);
4701
- return fetch(input, init);
4702
- };
4703
4685
  const packageVersions = /* @__PURE__ */ new Map();
4704
4686
  const known404Urls = /* @__PURE__ */ new Set();
4705
4687
  /**
@@ -4770,7 +4752,7 @@ const writeFetchSuccessAsync = async (sys, inMemoryFs, url, filePath, content, p
4770
4752
  const fetchModuleAsync = async (sys, inMemoryFs, pkgVersions, url, filePath) => {
4771
4753
  if (skipFilePathFetch(filePath) || known404Urls.has(url) || skipUrlFetch(url)) return;
4772
4754
  try {
4773
- const rsp = await httpFetch(sys, url);
4755
+ const rsp = await fetch(url);
4774
4756
  if (rsp) {
4775
4757
  if (rsp.ok) {
4776
4758
  const content = await rsp.clone().text();
@@ -4837,13 +4819,11 @@ const coreResolvePlugin = (config, compilerCtx, platform, externalRuntime, lazyL
4837
4819
  if (filePath && !filePath.startsWith("\0")) {
4838
4820
  filePath = normalizeFsPath(filePath);
4839
4821
  if (filePath === internalClient || filePath === internalSsr) {
4840
- if (platform === "worker") return `
4841
- export const Build = {
4842
- isDev: ${config.devMode},
4843
- isBrowser: true,
4844
- isServer: false,
4845
- isTesting: false,
4846
- };`;
4822
+ if (platform === "worker") return `export const Build = ${JSON.stringify({
4823
+ ...CLIENT_BUILD_FLAGS,
4824
+ isDev: config.devMode,
4825
+ isTesting: false
4826
+ })};`;
4847
4827
  const cached = transformedCodeCache.get(filePath);
4848
4828
  if (cached) return cached;
4849
4829
  let code = await compilerCtx.fs.readFile(filePath);
@@ -4956,6 +4936,139 @@ const buildConditionalsPlugin = (config, buildConditionals) => {
4956
4936
  };
4957
4937
  };
4958
4938
  //#endregion
4939
+ //#region src/compiler/bundle/build-flags-plugin.ts
4940
+ const STENCIL_CORE_IMPORT_RE = /^@stencil\/core(?:\/runtime(?:\/(?:client(?:\/(?:standalone|lazy))?|server))?)?$/;
4941
+ const BUILD_IMPORT_RE = /\bimport\s*\{[^}]*\bBuild\b[^}]*\}\s*from\s*['"]@stencil\/core/;
4942
+ /**
4943
+ * Rolldown plugin that folds user-code `Build.<flag>` reads to literals (see {@link foldBuildFlags}),
4944
+ * so rolldown can tree-shake gated branches - and anything only they import - before chunking.
4945
+ *
4946
+ * Only flags whose value is fixed for this bundle are folded. With an external runtime,
4947
+ * `isDev` / `isTesting` come from the consumer's app-data, so they're left as runtime reads.
4948
+ *
4949
+ * @param bundleOpts the options for this bundle
4950
+ * @returns a rolldown plugin
4951
+ */
4952
+ const buildFlagsPlugin = (bundleOpts) => {
4953
+ const flags = getFoldableBuildFlags(bundleOpts);
4954
+ return {
4955
+ name: "stencil-build-flags",
4956
+ transform: {
4957
+ filter: { code: BUILD_IMPORT_RE },
4958
+ handler(code, id) {
4959
+ if (id.startsWith("\0")) return null;
4960
+ const folded = foldBuildFlags(code, id.split("?")[0], flags);
4961
+ return folded === null ? null : {
4962
+ code: folded,
4963
+ map: null
4964
+ };
4965
+ }
4966
+ }
4967
+ };
4968
+ };
4969
+ /**
4970
+ * The `Build` flags with a fixed value in this bundle.
4971
+ *
4972
+ * @param bundleOpts the options for this bundle
4973
+ * @returns the foldable flags
4974
+ */
4975
+ const getFoldableBuildFlags = (bundleOpts) => {
4976
+ if (bundleOpts.platform === "ssr") return { ...SERVER_BUILD_FLAGS };
4977
+ const flags = { ...CLIENT_BUILD_FLAGS };
4978
+ const conditionals = bundleOpts.conditionals;
4979
+ if (bundleOpts.platform === "client" && !bundleOpts.externalRuntime && conditionals) {
4980
+ if (typeof conditionals.isDev === "boolean") flags.isDev = conditionals.isDev;
4981
+ if (typeof conditionals.isTesting === "boolean") flags.isTesting = conditionals.isTesting;
4982
+ }
4983
+ return flags;
4984
+ };
4985
+ /**
4986
+ * Replaces `Build.<flag>` reads (where `Build` is imported from `@stencil/core`) with literals,
4987
+ * letting bundlers / minify-ers drop dead branches. Neither oxc nor terser can fold a property
4988
+ * read on the runtime's `Build` object.
4989
+ *
4990
+ * e.g. with `{ isServer: false }`:
4991
+ * ```ts
4992
+ * if (Build.isServer) { … } // before
4993
+ * if (false ) { … } // after
4994
+ * ```
4995
+ *
4996
+ * Replacements are padded to the original length (newlines kept), so an existing sourcemap
4997
+ * for `code` stays valid. A `Build` binding that is shadowed or written to in the module is left alone.
4998
+ *
4999
+ * @param code JS or TS source
5000
+ * @param fileName used to pick the parser's script kind
5001
+ * @param flags the flag values to fold; flags not present are left as runtime reads
5002
+ * @returns the folded code, or `null` if nothing was folded
5003
+ */
5004
+ const foldBuildFlags = (code, fileName, flags) => {
5005
+ if (!BUILD_IMPORT_RE.test(code)) return null;
5006
+ const sourceFile = ts.createSourceFile(fileName, code, ts.ScriptTarget.Latest, true, getScriptKind(fileName));
5007
+ const buildSpecifiers = /* @__PURE__ */ new Set();
5008
+ for (const stmt of sourceFile.statements) if (ts.isImportDeclaration(stmt) && stmt.importClause?.phaseModifier !== ts.SyntaxKind.TypeKeyword && ts.isStringLiteral(stmt.moduleSpecifier) && STENCIL_CORE_IMPORT_RE.test(stmt.moduleSpecifier.text) && stmt.importClause?.namedBindings && ts.isNamedImports(stmt.importClause.namedBindings)) {
5009
+ for (const el of stmt.importClause.namedBindings.elements) if (!el.isTypeOnly && (el.propertyName ?? el.name).text === "Build") buildSpecifiers.add(el);
5010
+ }
5011
+ if (buildSpecifiers.size === 0) return null;
5012
+ const locals = new Set([...buildSpecifiers].map((el) => el.name.text));
5013
+ const unsafe = /* @__PURE__ */ new Set();
5014
+ const reads = [];
5015
+ const visit = (node) => {
5016
+ if (ts.isIdentifier(node) && locals.has(node.text)) {
5017
+ const parent = node.parent;
5018
+ if (isDeclarationName(node) && !buildSpecifiers.has(parent)) unsafe.add(node.text);
5019
+ else {
5020
+ const flag = getAccessedFlag(parent, node);
5021
+ if (flag !== void 0) {
5022
+ const access = parent;
5023
+ if (isWriteTarget(access)) unsafe.add(node.text);
5024
+ else {
5025
+ const value = flags[flag];
5026
+ if (typeof value === "boolean") reads.push({
5027
+ local: node.text,
5028
+ start: access.getStart(sourceFile),
5029
+ end: access.end,
5030
+ value
5031
+ });
5032
+ }
5033
+ }
5034
+ }
5035
+ }
5036
+ ts.forEachChild(node, visit);
5037
+ };
5038
+ visit(sourceFile);
5039
+ const toFold = reads.filter((r) => !unsafe.has(r.local));
5040
+ if (toFold.length === 0) return null;
5041
+ let out = code;
5042
+ for (const { start, end, value } of toFold.sort((a, b) => b.start - a.start)) {
5043
+ const original = code.slice(start, end);
5044
+ const nl = original.search(/[\r\n]/);
5045
+ const head = nl === -1 ? original : original.slice(0, nl);
5046
+ const tail = nl === -1 ? "" : original.slice(nl).replace(/[^\r\n]/g, " ");
5047
+ out = out.slice(0, start) + String(value).padEnd(head.length) + tail + out.slice(end);
5048
+ }
5049
+ return out;
5050
+ };
5051
+ const getScriptKind = (fileName) => {
5052
+ if (/\.tsx$/.test(fileName)) return ts.ScriptKind.TSX;
5053
+ if (/\.[mc]?ts$/.test(fileName)) return ts.ScriptKind.TS;
5054
+ if (/\.jsx$/.test(fileName)) return ts.ScriptKind.JSX;
5055
+ return ts.ScriptKind.JS;
5056
+ };
5057
+ const isDeclarationName = (node) => {
5058
+ const p = node.parent;
5059
+ return (ts.isVariableDeclaration(p) || ts.isParameter(p) || ts.isBindingElement(p) || ts.isFunctionDeclaration(p) || ts.isFunctionExpression(p) || ts.isClassDeclaration(p) || ts.isClassExpression(p) || ts.isEnumDeclaration(p) || ts.isModuleDeclaration(p) || ts.isImportEqualsDeclaration(p) || ts.isImportClause(p) || ts.isNamespaceImport(p) || ts.isImportSpecifier(p)) && p.name === node;
5060
+ };
5061
+ const getAccessedFlag = (parent, node) => {
5062
+ if (ts.isPropertyAccessExpression(parent) && parent.expression === node) return parent.name.text;
5063
+ if (ts.isElementAccessExpression(parent) && parent.expression === node && ts.isStringLiteralLike(parent.argumentExpression)) return parent.argumentExpression.text;
5064
+ };
5065
+ const isWriteTarget = (access) => {
5066
+ const p = access.parent;
5067
+ if (ts.isBinaryExpression(p)) return p.left === access && p.operatorToken.kind >= ts.SyntaxKind.FirstAssignment && p.operatorToken.kind <= ts.SyntaxKind.LastAssignment;
5068
+ if (ts.isPrefixUnaryExpression(p) || ts.isPostfixUnaryExpression(p)) return p.operator === ts.SyntaxKind.PlusPlusToken || p.operator === ts.SyntaxKind.MinusMinusToken;
5069
+ return ts.isDeleteExpression(p);
5070
+ };
5071
+ //#endregion
4959
5072
  //#region src/compiler/bundle/constants.ts
4960
5073
  const DEV_MODULE_DIR = `~dev-module`;
4961
5074
  //#endregion
@@ -6506,6 +6619,7 @@ const getRolldownOptions = (config, compilerCtx, buildCtx, bundleOpts) => {
6506
6619
  loaderPlugin(bundleOpts.loader),
6507
6620
  userIndexPlugin(config, compilerCtx),
6508
6621
  typescriptPlugin(compilerCtx, bundleOpts, config),
6622
+ buildFlagsPlugin(bundleOpts),
6509
6623
  extFormatPlugin(config),
6510
6624
  extTransformsPlugin(config, compilerCtx, buildCtx),
6511
6625
  workerPlugin(config, compilerCtx, buildCtx, bundleOpts.platform, !!bundleOpts.inlineWorkers),
@@ -7238,31 +7352,6 @@ const createIdentifierFromStyleIdentifier = (styleIdentifier, externalStyleIds)
7238
7352
  return ts.factory.createBinaryExpression(createIdentifierFromStyleIdentifier(styleIdentifier, [id]), ts.SyntaxKind.PlusToken, createIdentifierFromStyleIdentifier(styleIdentifier, externalStyleIds.slice(1)));
7239
7353
  };
7240
7354
  //#endregion
7241
- //#region src/compiler/transformers/host-data-transform.ts
7242
- const transformHostData = (classElements, moduleFile) => {
7243
- if (classElements.some((e) => ts.isMethodDeclaration(e) && e.name.escapedText === "hostData")) {
7244
- const renderIndex = classElements.findIndex((e) => ts.isMethodDeclaration(e) && e.name.escapedText === "render");
7245
- if (renderIndex >= 0) {
7246
- const renderMethod = classElements[renderIndex];
7247
- classElements[renderIndex] = ts.factory.updateMethodDeclaration(renderMethod, retrieveModifierLike(renderMethod), renderMethod.asteriskToken, ts.factory.createIdentifier(INTERNAL_RENDER), renderMethod.questionToken, renderMethod.typeParameters, renderMethod.parameters, renderMethod.type, renderMethod.body);
7248
- }
7249
- classElements.push(syntheticRender(moduleFile, renderIndex >= 0));
7250
- }
7251
- };
7252
- const syntheticRender = (moduleFile, hasRender) => {
7253
- addCoreRuntimeApi(moduleFile, RUNTIME_APIS.Host);
7254
- addCoreRuntimeApi(moduleFile, RUNTIME_APIS.h);
7255
- const hArguments = [ts.factory.createIdentifier(HOST), ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createThis(), "hostData"), void 0, void 0)];
7256
- if (hasRender) hArguments.push(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createThis(), INTERNAL_RENDER), void 0, void 0));
7257
- /**
7258
- * render() {
7259
- * return h(arguments);
7260
- * }
7261
- */
7262
- return ts.factory.createMethodDeclaration(void 0, void 0, "render", void 0, void 0, [], void 0, ts.factory.createBlock([ts.factory.createReturnStatement(ts.factory.createCallExpression(ts.factory.createIdentifier(H), void 0, hArguments))]));
7263
- };
7264
- const INTERNAL_RENDER = "__stencil_render";
7265
- //#endregion
7266
7355
  //#region src/compiler/transformers/reactive-handler-meta-transform.ts
7267
7356
  /**
7268
7357
  * Add a getter to a class for a static representation of the watchers
@@ -7344,7 +7433,6 @@ const updateLazyComponentMembers = (transformOpts, styleStatements, classNode, m
7344
7433
  addReactivePropHandlers(classMembers, cmp, "watchers");
7345
7434
  addReactivePropHandlers(classMembers, cmp, "serializers");
7346
7435
  addReactivePropHandlers(classMembers, cmp, "deserializers");
7347
- transformHostData(classMembers, moduleFile);
7348
7436
  if (transformOpts.style === "static") addStaticStylePropertyToClass(styleStatements, cmp, buildCtx);
7349
7437
  return classMembers;
7350
7438
  };
@@ -11158,7 +11246,6 @@ const generateEventDetailTypes = (cmp) => {
11158
11246
  //#endregion
11159
11247
  //#region src/compiler/types/types-utils.ts
11160
11248
  const COMPONENTS_DTS_HEADER = `/* eslint-disable */
11161
- /* tslint:disable */
11162
11249
  /**
11163
11250
  * This is an autogenerated file created by the Stencil compiler.
11164
11251
  * It contains typing information for all components that exist in this project.
@@ -11505,14 +11592,16 @@ export declare function setAssetPath(path: string): string;
11505
11592
  };
11506
11593
  /**
11507
11594
  * Generate standalone.d.ts file for the standalone output target.
11508
- * This provides types for setNonce and setPlatformOptions.
11595
+ * This provides types for setNonce and setPlatformOptions, and re-exports the component
11596
+ * types (as loader.d.ts does) so they're reachable from a standalone-only package root.
11509
11597
  *
11510
11598
  * @param compilerCtx the current compiler context
11511
11599
  * @param typesDir the directory to write the standalone.d.ts file to
11512
11600
  * @param hasAssets whether any component declares assets, matching whether setAssetPath is actually exported
11513
11601
  */
11514
11602
  const generateStandaloneApiTypes = async (compilerCtx, typesDir, hasAssets) => {
11515
- const standaloneDtsContent = `/**
11603
+ const standaloneDtsContent = `export * from './components';
11604
+ /**
11516
11605
  * Used to specify a nonce value that corresponds with an application's CSP.
11517
11606
  * When set, the nonce will be added to all dynamically created script and style tags at runtime.
11518
11607
  * Alternatively, the nonce value can be set on a meta tag in the DOM head
@@ -12136,7 +12225,6 @@ const getHydrateAttrsToReflect = (cmp) => {
12136
12225
  * - Updating the constructor to be lazy (only initialize when needed in the app factory)
12137
12226
  * - Adding a static getter for the lazy element (which is used in the app factory to determine which components are needed)
12138
12227
  * - Adding reactive property handlers for watchers, serializers, and deserializers (which are used in the app factory to set up reactive properties)
12139
- * - Transforming the `hostData` method to be compatible with SSR
12140
12228
  *
12141
12229
  * @param classNode the class declaration to transform
12142
12230
  * @param moduleFile the module file containing the class declaration
@@ -12155,7 +12243,6 @@ const updateSsrHostComponentMembers = (classNode, moduleFile, cmp, buildCtx) =>
12155
12243
  addReactivePropHandlers(classMembers, cmp, "serializers");
12156
12244
  addReactivePropHandlers(classMembers, cmp, "deserializers");
12157
12245
  addHydrateRuntimeCmpMeta(classMembers, cmp, buildCtx);
12158
- transformHostData(classMembers, moduleFile);
12159
12246
  return classMembers;
12160
12247
  };
12161
12248
  //#endregion
@@ -13515,7 +13602,6 @@ const updateNativeHostComponentMembers = (transformOpts, classNode, moduleFile,
13515
13602
  addReactivePropHandlers(classMembers, cmp, "deserializers");
13516
13603
  if (cmp.isPlain) addNativeComponentMeta(classMembers, cmp);
13517
13604
  if (transformOpts.style === "static") addNativeStaticStyle(classMembers, cmp, buildCtx);
13518
- transformHostData(classMembers, moduleFile);
13519
13605
  return classMembers;
13520
13606
  };
13521
13607
  //#endregion
@@ -17701,7 +17787,6 @@ function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceF
17701
17787
  //#region src/compiler/transformers/static-to-meta/class-methods.ts
17702
17788
  const parseClassMethods = (classMethods, cmpMeta) => {
17703
17789
  if (!classMethods?.length) return;
17704
- const hasHostData = classMethods.includes("hostData");
17705
17790
  cmpMeta.hasAttributeChangedCallbackFn = classMethods.includes("attributeChangedCallback");
17706
17791
  cmpMeta.hasConnectedCallbackFn = classMethods.includes("connectedCallback");
17707
17792
  cmpMeta.hasDisconnectedCallbackFn = classMethods.includes("disconnectedCallback");
@@ -17713,8 +17798,7 @@ const parseClassMethods = (classMethods, cmpMeta) => {
17713
17798
  cmpMeta.hasComponentShouldUpdateFn = classMethods.includes("componentShouldUpdate");
17714
17799
  cmpMeta.hasComponentDidUpdateFn = classMethods.includes("componentDidUpdate");
17715
17800
  cmpMeta.hasLifecycle = cmpMeta.hasComponentWillLoadFn || cmpMeta.hasComponentDidLoadFn || cmpMeta.hasComponentWillUpdateFn || cmpMeta.hasComponentDidUpdateFn;
17716
- cmpMeta.hasRenderFn = classMethods.includes("render") || hasHostData;
17717
- cmpMeta.hasVdomRender = cmpMeta.hasVdomRender || hasHostData;
17801
+ cmpMeta.hasRenderFn = classMethods.includes("render");
17718
17802
  };
17719
17803
  //#endregion
17720
17804
  //#region src/compiler/transformers/static-to-meta/element-ref.ts
@@ -18950,13 +19034,13 @@ const getRelativeDts = (config, srcPath, emitDtsPath) => {
18950
19034
  const previousComponentStyles = /* @__PURE__ */ new Map();
18951
19035
  /**
18952
19036
  * Generate the Hot Module Replacement (HMR) data for the current build.
18953
- * @param config a user-supplied config
19037
+ * @param config the validated Stencil config
18954
19038
  * @param compilerCtx the compiler context
18955
19039
  * @param buildCtx the build context
18956
19040
  * @returns the HMR data
18957
19041
  */
18958
19042
  const generateHmr = (config, compilerCtx, buildCtx) => {
18959
- if (config.devServer?.reloadStrategy == null) return null;
19043
+ if (config.devServer.reloadStrategy == null) return null;
18960
19044
  const hmr = {
18961
19045
  reloadStrategy: config.devServer.reloadStrategy,
18962
19046
  versionId: Date.now().toString().substring(6) + "" + Math.round(Math.random() * 89999 + 1e4)
@@ -19052,7 +19136,7 @@ const addTsFileImporters = (allModuleFiles, filesToLookForImporters, checkedFile
19052
19136
  };
19053
19137
  const getExternalStylesUpdated = (config, buildCtx) => {
19054
19138
  if (!buildCtx.isRebuild) return null;
19055
- const globalStyleFileNames = /* @__PURE__ */ new Set([...config.fsNamespace ? [getStencilCssFileName(config.fsNamespace)] : [], ...config.outputTargets.filter(isOutputTargetGlobalStyle).map((o) => o.fileName)]);
19139
+ const globalStyleFileNames = /* @__PURE__ */ new Set([getStencilCssFileName(config.fsNamespace), ...config.outputTargets.filter(isOutputTargetGlobalStyle).map((o) => o.fileName)]);
19056
19140
  const cssFiles = buildCtx.filesWritten.filter((f) => f.endsWith(".css")).map((f) => basename$1(f)).filter((fileName) => !globalStyleFileNames.has(fileName));
19057
19141
  if (cssFiles.length === 0) return null;
19058
19142
  return cssFiles.sort();
@@ -19072,7 +19156,7 @@ const getImagesUpdated = (buildCtx, outputTargetsWww) => {
19072
19156
  /**
19073
19157
  * Determine a list of files (if any) which should be excluded from HMR updates.
19074
19158
  *
19075
- * @param config a user-supplied config
19159
+ * @param config the validated Stencil config
19076
19160
  * @param excludeHmr a list of glob patterns that should be used to determine
19077
19161
  * whether to exclude a file or not (a file will be excluded if it matches one
19078
19162
  * @param filesChanged an array of files which are changed in the HMR update
@@ -19430,7 +19514,7 @@ const cleanupUpdateMsg = (logger, msg, fileNames) => {
19430
19514
  */
19431
19515
  const cleanDiagnosticsRelativePath = (config, diagnostics) => {
19432
19516
  diagnostics.forEach((diagnostic) => {
19433
- if (!diagnostic.relFilePath && diagnostic.absFilePath && !isRemoteUrl(diagnostic.absFilePath) && config.rootDir) diagnostic.relFilePath = relative$1(config.rootDir, diagnostic.absFilePath);
19517
+ if (!diagnostic.relFilePath && diagnostic.absFilePath && !isRemoteUrl(diagnostic.absFilePath)) diagnostic.relFilePath = relative$1(config.rootDir, diagnostic.absFilePath);
19434
19518
  });
19435
19519
  };
19436
19520
  //#endregion
@@ -19810,149 +19894,199 @@ const validateBuildFiles = (config, compilerCtx, buildCtx) => {
19810
19894
  };
19811
19895
  //#endregion
19812
19896
  //#region src/compiler/build/write-export-maps.ts
19897
+ const OWNED_CONDITIONS = [
19898
+ "types",
19899
+ "import",
19900
+ "require"
19901
+ ];
19902
+ const isJsonObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
19813
19903
  /**
19814
- * Create the shared {@link NpmPkgSet} used across a single `writeExportMaps` run.
19815
- * @param buildCtx The build context to report a warning diagnostic on if `npm` can't be run
19816
- * @returns A function that shells out to `npm pkg set`, swallowing failure after warning once
19817
- */
19818
- const createNpmPkgSet = (buildCtx) => {
19819
- let npmAvailable = true;
19820
- return (cmd) => {
19821
- if (!npmAvailable) return;
19822
- try {
19823
- execSync(`npm pkg set ${cmd}`);
19824
- } catch (e) {
19825
- npmAvailable = false;
19826
- const warn = buildWarn(buildCtx.diagnostics);
19827
- warn.messageText = `Unable to generate "exports" map in package.json: the "npm" CLI could not be run (${e.message ?? e}). Set "generateExportMaps: false" in your Stencil config to silence this warning.`;
19828
- }
19829
- };
19830
- };
19831
- /**
19832
- * Create export map entry point definitions for the `package.json` file using the npm CLI.
19904
+ * Write the `exports` map entry points into the project's `package.json`.
19833
19905
  *
19834
- * In v5, this uses a "smart default" approach:
19835
- * - Check if exports["."] already points to a valid output (loader-bundle or standalone)
19836
- * - If valid, leave it alone (respect user customization)
19837
- * - If missing or invalid, set a sensible default (loader-bundle > standalone priority)
19838
- * - Always ensure types field is set correctly
19839
- * - Generate per-component exports for standalone output
19906
+ * - `exports["."]`: an `import` / `types` target that exists on disk is left alone
19907
+ * (respects user customization), otherwise a default is set (loader-bundle > standalone)
19908
+ * - every other generated entry is owned by Stencil and rewritten on each build
19909
+ * - per-component entries whose component no longer exists are removed
19910
+ * - entries Stencil doesn't generate are left untouched
19840
19911
  *
19841
19912
  * @param config The validated Stencil config
19842
- * @param compilerCtx The compiler context (used to detect a user-authored src/index.ts)
19913
+ * @param compilerCtx The compiler context
19843
19914
  * @param buildCtx The build context containing the components to generate export maps for
19844
19915
  */
19845
- const writeExportMaps = (config, compilerCtx, buildCtx) => {
19916
+ const writeExportMaps = async (config, compilerCtx, buildCtx) => {
19846
19917
  const loaderBundle = config.outputTargets.find(isOutputTargetLoaderBundle);
19847
19918
  const standalone = config.outputTargets.find(isOutputTargetStandalone);
19919
+ const ssr = config.outputTargets.find(isOutputTargetSsr);
19848
19920
  const types = config.outputTargets.find(isOutputTargetTypes);
19849
- const npmPkgSet = createNpmPkgSet(buildCtx);
19850
- generateRootExport(config, compilerCtx, buildCtx, loaderBundle, standalone, types, npmPkgSet);
19851
- if (loaderBundle) generateLoaderExport(config, loaderBundle, types, npmPkgSet);
19852
- if (standalone) generateComponentExports(config, buildCtx, standalone, npmPkgSet);
19921
+ if (!loaderBundle && !standalone && !ssr) return;
19922
+ const source = await readPackageJsonSource(config, compilerCtx);
19923
+ const pkg = source ? parsePackageJson(source, config.packageJsonFilePath).data : null;
19924
+ if (!source || !isJsonObject(pkg)) return;
19925
+ let exportMap = toExportMap(pkg.exports);
19926
+ if (loaderBundle || standalone) {
19927
+ const root = getRootExport(config, compilerCtx, exportMap["."], loaderBundle, standalone, types);
19928
+ exportMap = "." in exportMap ? {
19929
+ ...exportMap,
19930
+ ".": root
19931
+ } : {
19932
+ ".": root,
19933
+ ...exportMap
19934
+ };
19935
+ }
19936
+ const generated = getGeneratedExports(config, buildCtx, loaderBundle, standalone, ssr, types);
19937
+ if (standalone?.dir) removeStaleComponentExports(exportMap, generated, toRelativePath(config, standalone.dir));
19938
+ for (const [key, entry] of Object.entries(generated)) exportMap[key] = isString$1(entry) ? entry : mergeConditions(exportMap[key], entry);
19939
+ pkg.exports = exportMap;
19940
+ const eol = source.includes("\r\n") ? "\r\n" : "\n";
19941
+ const indent = /^([ \t]+)"/m.exec(source)?.[1] ?? 2;
19942
+ let output = JSON.stringify(pkg, null, indent);
19943
+ if (/\n\s*$/.test(source)) output += "\n";
19944
+ output = output.replace(/\n/g, eol);
19945
+ if (output !== source) await compilerCtx.fs.writeFile(config.packageJsonFilePath, output, { immediateWrite: true });
19946
+ };
19947
+ const readPackageJsonSource = async (config, compilerCtx) => {
19948
+ try {
19949
+ return await compilerCtx.fs.readFile(config.packageJsonFilePath);
19950
+ } catch {
19951
+ return;
19952
+ }
19953
+ };
19954
+ /**
19955
+ * Normalize a `package.json` `exports` value into its subpath-keyed form.
19956
+ * @param current The current `exports` value
19957
+ * @returns A new subpath-keyed `exports` object
19958
+ */
19959
+ const toExportMap = (current) => {
19960
+ if (isString$1(current)) return { ".": current };
19961
+ if (!isJsonObject(current)) return {};
19962
+ const keys = Object.keys(current);
19963
+ return keys.length > 0 && keys.every((key) => !key.startsWith(".")) ? { ".": current } : { ...current };
19964
+ };
19965
+ /**
19966
+ * Build an entry with Stencil's conditions first (`types` has to precede `import` / `require`
19967
+ * to be picked up by TypeScript), followed by any other conditions already on the entry.
19968
+ * @param current The entry's current value
19969
+ * @param owned The conditions to set; any owned condition left out is removed
19970
+ * @returns The merged entry
19971
+ */
19972
+ const mergeConditions = (current, owned) => {
19973
+ const others = isJsonObject(current) ? Object.entries(current).filter(([key]) => !OWNED_CONDITIONS.includes(key)) : [];
19974
+ const { types, import: importPath, require: requirePath } = owned;
19975
+ return Object.fromEntries([...Object.entries({
19976
+ types,
19977
+ import: importPath,
19978
+ require: requirePath
19979
+ }).filter(([, value]) => value !== void 0), ...others]);
19853
19980
  };
19854
19981
  /**
19855
- * Generate the root export `exports["."]`.
19982
+ * Get the root export `exports["."]`.
19856
19983
  *
19857
- * Uses smart default approach:
19858
- * - Check if current root export points to a valid loader-bundle or standalone output
19859
- * - If valid, leave it alone
19860
- * - If missing or invalid, set default (loader-bundle > standalone priority)
19861
19984
  * @param config The validated Stencil config
19862
- * @param compilerCtx The compiler context (used to detect a user-authored src/index.ts)
19863
- * @param buildCtx The build context containing the components to generate export maps for
19985
+ * @param compilerCtx The compiler context
19986
+ * @param current The current root entry
19864
19987
  * @param loaderBundle The loader-bundle output target, if it exists
19865
19988
  * @param standalone The standalone output target, if it exists
19866
19989
  * @param types The types output target, if it exists
19867
- * @param npmPkgSet Function used to run `npm pkg set`, tolerating an unavailable npm CLI
19990
+ * @returns The root entry to write
19868
19991
  */
19869
- const generateRootExport = (config, compilerCtx, buildCtx, loaderBundle, standalone, types, npmPkgSet) => {
19870
- if (!loaderBundle && !standalone) return;
19992
+ const getRootExport = (config, compilerCtx, current, loaderBundle, standalone, types) => {
19993
+ const isUsable = (target) => isString$1(target) ? compilerCtx.fs.accessSync(join$2(config.rootDir, target)) : target != null;
19994
+ if (isString$1(current) && isUsable(current)) return current;
19995
+ const existing = isJsonObject(current) ? current : {};
19871
19996
  const hasSrcIndex = compilerCtx.fs.accessSync(join$2(config.srcDir, "index.ts"));
19872
19997
  const rootUsesEmptyLoaderIndex = !!loaderBundle && !hasSrcIndex;
19873
- const currentImport = ((buildCtx.packageJson?.exports)?.["."])?.import;
19874
- if (!(currentImport && isValidRootExport(config, currentImport, loaderBundle, standalone))) {
19998
+ const conditions = {
19999
+ types: existing.types,
20000
+ import: existing.import,
20001
+ require: existing.require
20002
+ };
20003
+ if (!isUsable(existing.import)) {
19875
20004
  const primaryDir = loaderBundle?.dir ?? standalone?.dir;
19876
20005
  if (primaryDir) {
19877
20006
  const entryFile = rootUsesEmptyLoaderIndex ? join$2("esm", "loader.js") : "index.js";
19878
- npmPkgSet(`"exports[.][import]"="${normalizePath(relative$1(config.rootDir, join$2(primaryDir, entryFile)))}"`);
20007
+ conditions.import = toRelativePath(config, join$2(primaryDir, entryFile));
19879
20008
  if (loaderBundle?.cjs) {
19880
20009
  const cjsEntryFile = rootUsesEmptyLoaderIndex ? join$2("cjs", "loader.cjs") : "index.cjs";
19881
- npmPkgSet(`"exports[.][require]"="${normalizePath(relative$1(config.rootDir, join$2(loaderBundle.dir, cjsEntryFile)))}"`);
20010
+ conditions.require = toRelativePath(config, join$2(loaderBundle.dir, cjsEntryFile));
19882
20011
  }
19883
20012
  }
19884
20013
  }
19885
- if (types?.dir) {
19886
- const typesFile = rootUsesEmptyLoaderIndex ? "loader.d.ts" : "index.d.ts";
19887
- npmPkgSet(`"exports[.][types]"="${normalizePath(relative$1(config.rootDir, join$2(types.dir, typesFile)))}"`);
20014
+ if (types?.dir && !isUsable(existing.types)) {
20015
+ const typesFile = hasSrcIndex ? "index.d.ts" : loaderBundle ? "loader.d.ts" : "standalone.d.ts";
20016
+ conditions.types = toRelativePath(config, join$2(types.dir, typesFile));
19888
20017
  }
20018
+ return mergeConditions(existing, conditions);
19889
20019
  };
19890
20020
  /**
19891
- * Check if the current root export import path is valid
19892
- * (points to either loader-bundle or standalone output).
20021
+ * Get every non-root entry Stencil generates for the configured output targets.
20022
+ *
19893
20023
  * @param config The validated Stencil config
19894
- * @param currentImport The current import path from exports["."]
20024
+ * @param buildCtx The build context containing the components to generate export maps for
19895
20025
  * @param loaderBundle The loader-bundle output target, if it exists
19896
20026
  * @param standalone The standalone output target, if it exists
19897
- * @returns True if the current import path points to a valid output, false otherwise
20027
+ * @param ssr The ssr output target, if it exists
20028
+ * @param types The types output target, if it exists
20029
+ * @returns The generated entries, keyed by subpath
19898
20030
  */
19899
- const isValidRootExport = (config, currentImport, loaderBundle, standalone) => {
19900
- const normalizedCurrent = normalizePath(currentImport);
19901
- if (loaderBundle?.dir) {
19902
- const loaderBundlePath = normalizePath(relative$1(config.rootDir, loaderBundle.dir));
19903
- if (normalizedCurrent.includes(loaderBundlePath)) return true;
19904
- }
20031
+ const getGeneratedExports = (config, buildCtx, loaderBundle, standalone, ssr, types) => {
20032
+ const generated = {};
20033
+ if (loaderBundle) generated["./loader"] = {
20034
+ types: types?.dir ? toRelativePath(config, join$2(types.dir, "loader.d.ts")) : void 0,
20035
+ import: toRelativePath(config, join$2(loaderBundle.dir, "esm", "loader.js")),
20036
+ require: loaderBundle.cjs ? toRelativePath(config, join$2(loaderBundle.dir, "cjs", "loader.cjs")) : void 0
20037
+ };
19905
20038
  if (standalone?.dir) {
19906
- const standalonePath = normalizePath(relative$1(config.rootDir, standalone.dir));
19907
- if (normalizedCurrent.includes(standalonePath)) return true;
20039
+ const outDir = toRelativePath(config, standalone.dir);
20040
+ generated["./standalone"] = {
20041
+ types: `${outDir}/index.d.ts`,
20042
+ import: `${outDir}/index.js`
20043
+ };
20044
+ for (const cmp of buildCtx.components) generated[`./${cmp.tagName}`] = {
20045
+ types: `${outDir}/${cmp.tagName}.d.ts`,
20046
+ import: `${outDir}/${cmp.tagName}.js`
20047
+ };
19908
20048
  }
19909
- return false;
19910
- };
19911
- /**
19912
- * Ensure a path has a relative prefix (./ or ../).
19913
- * Handles cases where normalizePath/relative may or may not add the prefix.
19914
- * @param path The path to ensure has a relative prefix
19915
- * @returns The path with a relative prefix
19916
- */
19917
- const ensureRelativePrefix = (path) => {
19918
- if (path.startsWith("./") || path.startsWith("../")) return path;
19919
- return "./" + path;
20049
+ if (ssr?.dir) {
20050
+ const outDir = toRelativePath(config, ssr.dir);
20051
+ generated["./ssr"] = {
20052
+ types: `${outDir}/index.d.ts`,
20053
+ import: `${outDir}/index.js`,
20054
+ require: ssr.cjs ? `${outDir}/index.cjs` : void 0
20055
+ };
20056
+ }
20057
+ if (loaderBundle || standalone) {
20058
+ const globalStyles = config.outputTargets.filter(isOutputTargetGlobalStyle);
20059
+ const assetsDir = (config.outputTargets.find(isOutputTargetAssets) ?? globalStyles[0])?.dir;
20060
+ if (assetsDir) generated["./assets/*"] = `${toRelativePath(config, assetsDir)}/*`;
20061
+ for (const globalStyle of globalStyles) if (globalStyle.dir && globalStyle.fileName && globalStyle.dir !== assetsDir) generated[`./assets/${globalStyle.fileName}`] = toRelativePath(config, join$2(globalStyle.dir, globalStyle.fileName));
20062
+ }
20063
+ return generated;
19920
20064
  };
19921
20065
  /**
19922
- * Generate the loader export `exports["./loader"]`.
20066
+ * Remove per-component entries Stencil generated for components that no longer exist.
20067
+ * Only an entry in the exact shape Stencil writes (`./<tag>` → `<standalone dir>/<tag>.js`)
20068
+ * is removed, so entries added by the author are left alone.
19923
20069
  *
19924
- * Points directly to the esm/loader.js file in the loader-bundle output.
19925
- * No separate loader directory is generated - package.json exports handle the mapping.
19926
- *
19927
- * @param config The validated Stencil config
19928
- * @param loaderBundle The loader-bundle output target
19929
- * @param types The types output target, if it exists
19930
- * @param npmPkgSet Function used to run `npm pkg set`, tolerating an unavailable npm CLI
20070
+ * @param exportMap The export map to remove entries from
20071
+ * @param generated The entries generated by this build
20072
+ * @param standaloneDir The standalone output directory, relative to the project root
19931
20073
  */
19932
- const generateLoaderExport = (config, loaderBundle, types, npmPkgSet) => {
19933
- const esmDir = join$2(loaderBundle.dir, "esm");
19934
- npmPkgSet(`"exports[./loader][import]"="${ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(esmDir, "loader.js"))))}"`);
19935
- if (loaderBundle.cjs) {
19936
- const cjsDir = join$2(loaderBundle.dir, "cjs");
19937
- npmPkgSet(`"exports[./loader][require]"="${ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(cjsDir, "loader.cjs"))))}"`);
20074
+ const removeStaleComponentExports = (exportMap, generated, standaloneDir) => {
20075
+ for (const [key, entry] of Object.entries(exportMap)) {
20076
+ const name = key.slice(2);
20077
+ if (!key.startsWith("./") || !name.includes("-") || key in generated) continue;
20078
+ if ((isJsonObject(entry) ? entry.import : entry) === `${standaloneDir}/${name}.js`) delete exportMap[key];
19938
20079
  }
19939
- if (types?.dir) npmPkgSet(`"exports[./loader][types]"="${ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(types.dir, "loader.d.ts"))))}"`);
19940
20080
  };
19941
20081
  /**
19942
- * Generate per-component exports for standalone output.
19943
- * Each component gets its own subpath export: `exports["./my-component"]`
20082
+ * Get a path relative to the project root, in the `./`-prefixed form `exports` targets require.
19944
20083
  * @param config The validated Stencil config
19945
- * @param buildCtx The build context containing the components to generate export maps for
19946
- * @param standalone The standalone output target
19947
- * @param npmPkgSet Function used to run `npm pkg set`, tolerating an unavailable npm CLI
19948
- */
19949
- const generateComponentExports = (config, buildCtx, standalone, npmPkgSet) => {
19950
- let outDir = relative$1(config.rootDir, standalone.dir);
19951
- if (!outDir.startsWith(".")) outDir = "./" + outDir;
19952
- buildCtx.components.forEach((cmp) => {
19953
- npmPkgSet(`"exports[./${cmp.tagName}][import]"="${outDir}/${cmp.tagName}.js"`);
19954
- npmPkgSet(`"exports[./${cmp.tagName}][types]"="${outDir}/${cmp.tagName}.d.ts"`);
19955
- });
20084
+ * @param path The absolute path
20085
+ * @returns The relative path
20086
+ */
20087
+ const toRelativePath = (config, path) => {
20088
+ const relativePath = normalizePath(relative$1(config.rootDir, path));
20089
+ return relativePath.startsWith("./") || relativePath.startsWith("../") ? relativePath : "./" + relativePath;
19956
20090
  };
19957
20091
  //#endregion
19958
20092
  //#region src/compiler/build/write-build.ts
@@ -19975,7 +20109,7 @@ const writeBuild = async (config, compilerCtx, buildCtx) => {
19975
20109
  await compilerCtx.cache.commit();
19976
20110
  buildCtx.debug(`in-memory-fs: ${compilerCtx.fs.getMemoryStats()}`);
19977
20111
  buildCtx.debug(`cache: ${compilerCtx.cache.getMemoryStats()}`);
19978
- if (config.generateExportMaps && !config.devMode) writeExportMaps(config, compilerCtx, buildCtx);
20112
+ if (config.generateExportMaps && !config.devMode) await writeExportMaps(config, compilerCtx, buildCtx);
19979
20113
  await outputServiceWorkers(config, buildCtx);
19980
20114
  await validateBuildFiles(config, compilerCtx, buildCtx);
19981
20115
  } catch (e) {
@@ -20892,7 +21026,7 @@ var Cache = class {
20892
21026
  return typeof await this.get(key) === "string";
20893
21027
  }
20894
21028
  async createKey(domain, ...args) {
20895
- if (!this.config.enableCache || !this.sys.generateContentHash) return domain + Math.random() * 9999999;
21029
+ if (!this.config.enableCache) return domain + Math.random() * 9999999;
20896
21030
  const hash = await this.sys.generateContentHash(JSON.stringify(args), 32);
20897
21031
  return domain + "_" + hash;
20898
21032
  }
@@ -20901,35 +21035,36 @@ var Cache = class {
20901
21035
  this.skip = false;
20902
21036
  this.failed = 0;
20903
21037
  await this.cacheFs.commit();
20904
- await this.clearExpiredCache();
21038
+ await this.pruneExpired();
20905
21039
  }
20906
21040
  }
21041
+ /**
21042
+ * Remove cache files last written over a week ago. Runs at most once a day,
21043
+ * throttled by the mtime of a marker file in the cache dir.
21044
+ */
21045
+ async pruneExpired() {
21046
+ if (!this.buildCacheDir) return;
21047
+ const now = Date.now();
21048
+ const markerPath = join$2(this.buildCacheDir, PRUNE_MARKER);
21049
+ const marker = await this.sys.stat(markerPath);
21050
+ if (marker.isFile && marker.mtimeMs && now - marker.mtimeMs < ONE_DAY) return;
21051
+ const filePaths = await this.sys.readDir(this.buildCacheDir);
21052
+ let removed = 0;
21053
+ await Promise.all(filePaths.map(async (filePath) => {
21054
+ if (basename$1(filePath).startsWith("_")) return;
21055
+ const { isFile, mtimeMs } = await this.sys.stat(filePath);
21056
+ if (isFile && mtimeMs && now - mtimeMs > ONE_WEEK) {
21057
+ await this.sys.removeFile(filePath);
21058
+ this.cacheFs.clearFileCache(filePath);
21059
+ removed++;
21060
+ }
21061
+ }));
21062
+ this.logger.debug(`cache prune: removed ${removed} of ${filePaths.length} files`);
21063
+ await this.sys.writeFile(markerPath, "");
21064
+ }
20907
21065
  clear() {
20908
21066
  if (this.cacheFs != null) this.cacheFs.clearCache();
20909
21067
  }
20910
- async clearExpiredCache() {
20911
- if (this.cacheFs == null || this.sys.cacheStorage == null) return;
20912
- const now = Date.now();
20913
- const lastClear = await this.sys.cacheStorage.get(EXP_STORAGE_KEY);
20914
- if (lastClear != null) {
20915
- if (now - lastClear < ONE_DAY) return;
20916
- const fs = this.cacheFs.sys;
20917
- const cachedFileNames = await fs.readDir(this.buildCacheDir);
20918
- const cachedFilePaths = cachedFileNames.map((f) => join$2(this.buildCacheDir, f));
20919
- let totalCleared = 0;
20920
- const promises = cachedFilePaths.map(async (filePath) => {
20921
- const lastModified = (await fs.stat(filePath)).mtimeMs;
20922
- if (lastModified && now - lastModified > ONE_WEEK) {
20923
- await fs.removeFile(filePath);
20924
- totalCleared++;
20925
- }
20926
- });
20927
- await Promise.all(promises);
20928
- this.logger.debug(`clearExpiredCache, cachedFileNames: ${cachedFileNames.length}, totalCleared: ${totalCleared}`);
20929
- }
20930
- this.logger.debug(`clearExpiredCache, set last clear`);
20931
- await this.sys.cacheStorage.set(EXP_STORAGE_KEY, now);
20932
- }
20933
21068
  async clearDiskCache() {
20934
21069
  if (this.cacheFs != null) {
20935
21070
  if (await this.cacheFs.access(this.buildCacheDir)) {
@@ -20949,7 +21084,7 @@ var Cache = class {
20949
21084
  const MAX_FAILED = 100;
20950
21085
  const ONE_DAY = 864e5;
20951
21086
  const ONE_WEEK = ONE_DAY * 7;
20952
- const EXP_STORAGE_KEY = `last_clear_expired_cache`;
21087
+ const PRUNE_MARKER = "_last_prune.log";
20953
21088
  const CACHE_DIR_README = `# Stencil Cache Directory
20954
21089
 
20955
21090
  This directory contains files which the compiler has
@@ -22038,7 +22173,7 @@ const validateConfig = (userConfig = {}, bootstrapConfig) => {
22038
22173
  ...config,
22039
22174
  devMode,
22040
22175
  compat: config.compat || {},
22041
- generateExportMaps: isBoolean$1(config.generateExportMaps) ? config.generateExportMaps : !isString$1(config.configPath),
22176
+ generateExportMaps: config.generateExportMaps === true,
22042
22177
  enableCssOnlyComponents: config.enableCssOnlyComponents ?? true,
22043
22178
  hydratedFlag: validateHydrated(config),
22044
22179
  logLevel,
@@ -25968,15 +26103,6 @@ const createSystem = (c) => {
25968
26103
  }
25969
26104
  return results;
25970
26105
  };
25971
- /**
25972
- * `self` is the global namespace object used within a web worker.
25973
- * `window` is the browser's global namespace object (I reorganized this to check the reference on that second)
25974
- * `global` is Node's global namespace object. https://nodejs.org/api/globals.html#globals_global
25975
- *
25976
- * loading in this order should allow workers, which are most common, then browser,
25977
- * then Node to grab the reference to fetch correctly.
25978
- */
25979
- const fetch = typeof self !== "undefined" ? self?.fetch : typeof window !== "undefined" ? window?.fetch : typeof global !== "undefined" ? global?.fetch : void 0;
25980
26106
  const writeFile = async (p, data) => writeFileSync(p, data);
25981
26107
  const tmpDirSync = () => "/.tmp";
25982
26108
  const tick = Promise.resolve();
@@ -25987,6 +26113,7 @@ const createSystem = (c) => {
25987
26113
  if (typeof hashLength === "number") hashHex = hashHex.slice(0, hashLength);
25988
26114
  return hashHex;
25989
26115
  };
26116
+ const generateFileHash = async (filePath, hashLength) => generateContentHash(readFileSync(filePath), hashLength);
25990
26117
  const copy = async (copyTasks, srcDir) => {
25991
26118
  const results = {
25992
26119
  diagnostics: [],
@@ -25996,9 +26123,6 @@ const createSystem = (c) => {
25996
26123
  logger.info("todo, copy task", copyTasks.length, srcDir);
25997
26124
  return results;
25998
26125
  };
25999
- const getEnvironmentVar = (key) => {
26000
- return process$1?.env[key];
26001
- };
26002
26126
  const getLocalModulePath = (opts) => join$2(opts.rootDir, "node_modules", opts.moduleId, opts.path);
26003
26127
  const getRemoteModuleUrl = (opts) => {
26004
26128
  const npmBaseUrl = "https://cdn.jsdelivr.net/npm/";
@@ -26014,13 +26138,14 @@ const createSystem = (c) => {
26014
26138
  access,
26015
26139
  accessSync,
26016
26140
  addDestroy,
26141
+ checkVersion: async () => noop,
26017
26142
  copyFile,
26018
26143
  createDir,
26019
26144
  createDirSync,
26020
26145
  homeDir,
26021
26146
  isTTY,
26022
- getEnvironmentVar,
26023
26147
  destroy,
26148
+ dynamicImport: (p) => import(p),
26024
26149
  encodeToBase64,
26025
26150
  exit: async (exitCode) => logger.warn(`exit ${exitCode}`),
26026
26151
  getCurrentDirectory,
@@ -26031,6 +26156,7 @@ const createSystem = (c) => {
26031
26156
  isSymbolicLink,
26032
26157
  nextTick,
26033
26158
  normalizePath: normalize,
26159
+ onProcessInterrupt: noop,
26034
26160
  platformPath: path,
26035
26161
  readDir,
26036
26162
  readDirSync,
@@ -26040,7 +26166,6 @@ const createSystem = (c) => {
26040
26166
  realpathSync,
26041
26167
  removeDestroy,
26042
26168
  rename,
26043
- fetch,
26044
26169
  resolvePath,
26045
26170
  removeDir,
26046
26171
  removeDirSync,
@@ -26055,6 +26180,7 @@ const createSystem = (c) => {
26055
26180
  writeFile,
26056
26181
  writeFileSync,
26057
26182
  generateContentHash,
26183
+ generateFileHash,
26058
26184
  createWorkerController: null,
26059
26185
  details: {
26060
26186
  cpuModel: "",
@@ -26254,6 +26380,7 @@ const transpileModule = (config, input, transformOpts) => {
26254
26380
  ...config,
26255
26381
  logger: createNodeLogger()
26256
26382
  };
26383
+ resetDeprecatedApiWarning();
26257
26384
  const compilerCtx = new CompilerContext();
26258
26385
  const buildCtx = new BuildContext(config, compilerCtx);
26259
26386
  const tsCompilerOptions = { ...config.tsCompilerOptions };
@@ -26457,4 +26584,4 @@ const shouldTranspileModule = (ext) => [
26457
26584
  "js"
26458
26585
  ].includes(ext);
26459
26586
  //#endregion
26460
- export { versions as A, replaceStencilCssComponentsImport as C, buildId as D, parseCssOnlyComponents as E, vermoji as O, hasStencilHydrateImport as S, replaceStencilHydrateImport as T, cmpMetaToDocsComponent as _, createPrerenderer as a, hasStencilCssComponentsImport as b, createWorkerContext as c, nodeRequire as d, optimizeCss as f, generateManifest as g, generateComponentTypesFile as h, createSystem as i, scopeCss as j, version as k, createWorkerMessageHandler as l, validateHydrated as m, transpile as n, loadConfig as o, validateConfig as p, transpileSync as r, createCompiler as s, ts$1 as t, optimizeJs as u, getScopeId as v, replaceStencilGlobalsImport as w, hasStencilGlobalsImport as x, buildHydrateCss as y };
26587
+ export { version as A, hasStencilHydrateImport as C, parseCssOnlyComponents as D, replaceStencilHydrateImport as E, scopeCss as M, buildId as O, hasStencilGlobalsImport as S, replaceStencilGlobalsImport as T, cmpMetaToDocsComponent as _, createPrerenderer as a, buildHydrateCss as b, createWorkerContext as c, nodeRequire as d, optimizeCss as f, generateManifest as g, generateComponentTypesFile as h, createSystem as i, versions as j, vermoji as k, createWorkerMessageHandler as l, validateHydrated as m, transpile as n, loadConfig as o, validateConfig as p, transpileSync as r, createCompiler as s, ts$1 as t, optimizeJs as u, getScopeId as v, replaceStencilCssComponentsImport as w, hasStencilCssComponentsImport as x, foldBuildFlags as y };