@stencil/core 5.0.0-beta.35 → 5.0.0-beta.36

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 { E as SERVER_BUILD_FLAGS, T as HYDRATED_CSS, w as CLIENT_BUILD_FLAGS } from "./client-UbH-XkYu.mjs";
2
+ import { A as SSR_PROP_REF_PREFIX, D as HYDRATE_ID, E as HYDRATE_CHILD_ID, O as SERVER_BUILD_FLAGS, T as HYDRATED_CSS, k as SSR_PROPS_REGISTRY_KEY, w as CLIENT_BUILD_FLAGS } from "./client-CqQpuOUk.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-BlVm1Vu0.mjs";
5
5
  import { $ as buildWarn, A as isOutputTargetDocsVscode, B as isValidConfigOutputTarget, C as isOutputTargetDistLazy, D as isOutputTargetDocsCustomElementsManifest, E as isOutputTargetDocsCustom, F as isOutputTargetSsrWasm, G as normalizeFsPath, H as shouldExcludeComponent, I as isOutputTargetStandalone, J as relative$1, K as normalizeFsPathQuery, L as isOutputTargetStats, M as isOutputTargetLoaderBundle, N as isOutputTargetServerRenderer, O as isOutputTargetDocsJson, P as isOutputTargetSsr, Q as buildJsonFileError, R as isOutputTargetTypes, S as isOutputTargetCustom, T as isOutputTargetDocsAgentSkill, U as join$2, V as relativeImport, Y as resolve$2, Z as buildError, a as hasDependency, b as isOutputTargetCollection, d as parsePackageJson, et as catchError, f as readOnlyArrayHasStringMember, g as getComponentsDtsSrcFilePath, h as filterExcludedComponents, i as getTextDocs, it as isGlob, j as isOutputTargetGlobalStyle, k as isOutputTargetDocsReadme, l as isTsFile, m as filterActiveTargets, n as createJsVarName, nt as hasWarning, o as isDtsFile, p as readPackageJson, q as normalizePath, r as generatePreamble, t as addDocBlock, tt as hasError, u as isTsxFile, v as getComponentsFromModules, w as isOutputTargetDocs, x as isOutputTargetCopy, y as isOutputTargetAssets, z as isOutputTargetWww } from "./util-C-H1H84W.mjs";
6
- import { i as CustomElementsExportBehaviorOptions, o as buildEvents, r as createNodeLogger, t as createNodeSys } from "./node-eg7pofz5.mjs";
6
+ import { i as CustomElementsExportBehaviorOptions, o as buildEvents, r as createNodeLogger, t as createNodeSys } from "./node-DwwBX_GL.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";
@@ -461,9 +461,9 @@ const scopeCss = (cssText, scopeId, commentOriginalSelector) => {
461
461
  };
462
462
  //#endregion
463
463
  //#region src/version.ts
464
- const version = "5.0.0-beta.35";
465
- const buildId = "1794002503";
466
- const vermoji = "🚅";
464
+ const version = "5.0.0-beta.36";
465
+ const buildId = "1794253443";
466
+ const vermoji = "🌎";
467
467
  /**
468
468
  * Get the installed version of a tool/dependency.
469
469
  * Handles packages with exports maps that point to subdirectories.
@@ -3049,6 +3049,9 @@ const objectLiteralToObjectMap = (objectLiteral, typeChecker, diagnostics, error
3049
3049
  case ts.SyntaxKind.FalseKeyword:
3050
3050
  val = false;
3051
3051
  break;
3052
+ case ts.SyntaxKind.NullKeyword:
3053
+ val = null;
3054
+ break;
3052
3055
  case ts.SyntaxKind.Identifier:
3053
3056
  const escapedText = propAssignment.initializer.escapedText;
3054
3057
  if (escapedText === "String") val = String;
@@ -3235,7 +3238,7 @@ const getAllTypeReferences = (checker, node) => {
3235
3238
  */
3236
3239
  const getTypeReferenceLocation = (typeName, type, sourceFile, checker, program) => {
3237
3240
  const importTypeDeclaration = sourceFile.statements.find((st) => {
3238
- if (!(ts.isImportDeclaration(st) && st.importClause && ts.isImportClause(st.importClause) && st.importClause.namedBindings && ts.isNamedImports(st.importClause.namedBindings) && Array.isArray(st.importClause.namedBindings.elements) && st.importClause.namedBindings.elements.find((nbe) => nbe.name.getText() === typeName))) return false;
3241
+ if (!(ts.isImportDeclaration(st) && st.importClause && ts.isImportClause(st.importClause) && st.importClause.namedBindings && ts.isNamedImports(st.importClause.namedBindings) && Array.isArray(st.importClause.namedBindings.elements) && st.importClause.namedBindings.elements.find((nbe) => nbe.name.text === typeName))) return false;
3239
3242
  return true;
3240
3243
  });
3241
3244
  const namedImportBindings = importTypeDeclaration?.importClause?.namedBindings;
@@ -3244,7 +3247,7 @@ const getTypeReferenceLocation = (typeName, type, sourceFile, checker, program)
3244
3247
  const options = program.getCompilerOptions();
3245
3248
  const importHomeModule = getHomeModule(sourceFile, localImportPath, options, ts.createCompilerHost(options), program);
3246
3249
  if (importHomeModule) {
3247
- const importElement = namedImportBindings.elements.find((nbe) => nbe.name.getText() === typeName);
3250
+ const importElement = namedImportBindings.elements.find((nbe) => nbe.name.text === typeName);
3248
3251
  const importName = importElement.name;
3249
3252
  const originalTypeName = getOriginalTypeName(importName, checker);
3250
3253
  const importedAs = importElement.propertyName ? importElement.propertyName.getText() : typeName;
@@ -7705,9 +7708,9 @@ const updateStencilCoreImports = (updatedCoreImportPath) => {
7705
7708
  }
7706
7709
  if (moduleSpecifierText === "@stencil/core") {
7707
7710
  if (s.importClause && s.importClause.namedBindings && s.importClause.namedBindings.kind === ts.SyntaxKind.NamedImports) {
7708
- const keepImports = s.importClause.namedBindings.elements.map((e) => e.getText()).filter((name) => KEEP_IMPORTS.has(name));
7711
+ const keepImports = s.importClause.namedBindings.elements.filter((e) => KEEP_IMPORTS.has((e.propertyName ?? e.name).text));
7709
7712
  if (keepImports.length > 0) {
7710
- const newImport = ts.factory.updateImportDeclaration(s, void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports(keepImports.map((name) => ts.factory.createImportSpecifier(false, void 0, ts.factory.createIdentifier(name))))), ts.factory.createStringLiteral(updatedCoreImportPath), void 0);
7713
+ const newImport = ts.factory.updateImportDeclaration(s, void 0, ts.factory.createImportClause(false, void 0, ts.factory.createNamedImports(keepImports.map((e) => ts.factory.createImportSpecifier(false, e.propertyName ? ts.factory.createIdentifier(e.propertyName.text) : void 0, ts.factory.createIdentifier(e.name.text))))), ts.factory.createStringLiteral(updatedCoreImportPath), void 0);
7711
7714
  newStatements.push(newImport);
7712
7715
  }
7713
7716
  }
@@ -12524,6 +12527,8 @@ const SSR_FACTORY_INTRO = `
12524
12527
  // Used for the hydrate timeout timer to avoid being affected by constrainTimeouts.
12525
12528
  var $nativeSetTimeout = (typeof globalThis !== 'undefined' ? globalThis : global).setTimeout;
12526
12529
  var $nativeClearTimeout = (typeof globalThis !== 'undefined' ? globalThis : global).clearTimeout;
12530
+ // Holds the \`ssrProp()\` registry, which template code writes to outside the factory.
12531
+ var $stencilNativeGlobal = typeof globalThis !== 'undefined' ? globalThis : global;
12527
12532
  // Used to abort in-flight fetch() calls and to call any user defined AbortControllers when ssr times out.
12528
12533
  var $stencilNativeAbortController = AbortController;
12529
12534
 
@@ -12848,6 +12853,7 @@ const writeSsrOutput = async (config, compilerCtx, buildCtx, outputTarget, rolld
12848
12853
  const hydrateAppDirPath = outputTarget.dir;
12849
12854
  if (!hydrateAppDirPath) throw new Error(`outputTarget config missing the "dir" property`);
12850
12855
  await copySsrRunnerDts(config, compilerCtx, hydrateAppDirPath);
12856
+ await writeSsrPropModule(compilerCtx, hydrateAppDirPath, outputTarget.cjs === true);
12851
12857
  buildCtx.ssrAppFilePath = join$2(hydrateAppDirPath, "index.js");
12852
12858
  const minify = outputTarget.minify === true;
12853
12859
  await Promise.all(rolldownOutput.output.map(async (output) => {
@@ -12871,7 +12877,86 @@ const copySsrRunnerDts = async (config, compilerCtx, hydrateAppDirPath) => {
12871
12877
  const packageDir = join$2(config.sys.getCompilerExecutingPath(), "..", "..");
12872
12878
  const srcSsrDir = join$2(packageDir, "runtime", "server", "runner.d.mts");
12873
12879
  const runnerDtsDestPath = join$2(hydrateAppDirPath, "index.d.ts");
12874
- await compilerCtx.fs.copyFile(srcSsrDir, runnerDtsDestPath);
12880
+ const dts = await config.sys.readFile(srcSsrDir);
12881
+ if (dts == null) return;
12882
+ await compilerCtx.fs.writeFile(runnerDtsDestPath, stripSideEffectImports(dts), { immediateWrite: true });
12883
+ };
12884
+ /**
12885
+ * The bundled runner types keep bare imports (`import "rolldown";`) of modules whose types were
12886
+ * tree-shaken away. They declare nothing, but a library's consumers won't have those packages
12887
+ * (often not even `@stencil/core`), which breaks under `noUncheckedSideEffectImports`.
12888
+ * @param dts the runner's `.d.mts` contents
12889
+ * @returns the contents without bare imports
12890
+ */
12891
+ const stripSideEffectImports = (dts) => dts.replace(/^import\s*["'][^"']+["'];?[ \t]*\r?\n/gm, "");
12892
+ const SSR_PROP_JS = `const PREFIX = ${JSON.stringify(SSR_PROP_REF_PREFIX)};
12893
+ const REGISTRY = Symbol.for(${JSON.stringify(SSR_PROPS_REGISTRY_KEY)});
12894
+ // a value nothing picked up (the page never reached renderToString()) is dropped after this long
12895
+ const TTL = 60000;
12896
+ let nextSweep = 0;
12897
+
12898
+ /**
12899
+ * Pass a value to a component's property from a framework template, so it reaches the component
12900
+ * when it's rendered on the server too. In the browser, returns the value. On the server, keeps
12901
+ * the value and returns a reference to it, which the template renders as an attribute and the
12902
+ * SSR module (in the same process) turns back into the value. Getting it on to the browser is the
12903
+ * prop's job: @Prop({ serialize: 'json' }), or a @PropSerialize() / @AttrDeserialize() pair.
12904
+ */
12905
+ export function ssrProp(value) {
12906
+ if (typeof window !== 'undefined') return value;
12907
+ const registry = globalThis[REGISTRY] || (globalThis[REGISTRY] = new Map());
12908
+ const now = Date.now();
12909
+ if (now > nextSweep) {
12910
+ nextSweep = now + TTL;
12911
+ for (const [id, entry] of registry) if (entry.expires < now) registry.delete(id);
12912
+ }
12913
+ const id = globalThis.crypto && globalThis.crypto.randomUUID
12914
+ ? globalThis.crypto.randomUUID()
12915
+ : Math.random().toString(36).slice(2) + now.toString(36);
12916
+ registry.set(id, { value, expires: now + TTL });
12917
+ return PREFIX + id;
12918
+ }
12919
+ `;
12920
+ const SSR_PROP_DTS = `/**
12921
+ * Pass a value to a component's property from a framework template, so it reaches the component
12922
+ * when it's rendered on the server too.
12923
+ *
12924
+ * \`\`\`vue
12925
+ * <my-chart :data="ssrProp(data)" />
12926
+ * \`\`\`
12927
+ *
12928
+ * In the browser, returns the value. On the server, keeps the value and returns a reference to it
12929
+ * (a string the template renders as an attribute), which the SSR module turns back into the
12930
+ * value. Nothing is serialized, so any value works: a \`Map\`, a \`Date\`, a class instance.
12931
+ *
12932
+ * The SSR module must render the page in the same process, soon after the template runs: the
12933
+ * whole-document \`renderToString()\` hook every framework integration uses.
12934
+ *
12935
+ * This gets the value into the server render only. For the component to have it when it first
12936
+ * renders in the browser too, before the framework sets the property, the prop needs to carry it
12937
+ * in its attribute: \`@Prop({ serialize: 'json' })\`, or a \`@PropSerialize()\` /
12938
+ * \`@AttrDeserialize()\` pair for other formats. Without either, \`renderToString()\` adds a
12939
+ * warning to its \`diagnostics\`.
12940
+ * @param value the property value
12941
+ * @returns \`value\` in the browser, a reference to it (a string) typed as \`T\` on the server
12942
+ */
12943
+ export declare function ssrProp<T>(value: T): T;
12944
+ `;
12945
+ /**
12946
+ * Write `ssr-prop.js` (`./ssr-prop` in export maps): `ssrProp()`, for framework templates. It runs
12947
+ * on both server and client, so it's separate from the server-only SSR module.
12948
+ * @param compilerCtx the compiler context
12949
+ * @param dir the ssr output directory
12950
+ * @param cjs whether to also write a CommonJS copy
12951
+ */
12952
+ const writeSsrPropModule = async (compilerCtx, dir, cjs) => {
12953
+ const opts = { immediateWrite: true };
12954
+ await compilerCtx.fs.writeFile(join$2(dir, "ssr-prop.js"), SSR_PROP_JS, opts);
12955
+ await compilerCtx.fs.writeFile(join$2(dir, "ssr-prop.d.ts"), SSR_PROP_DTS, opts);
12956
+ if (cjs) {
12957
+ const cjsCode = SSR_PROP_JS.replace("export function ssrProp", "function ssrProp") + "exports.ssrProp = ssrProp;\n";
12958
+ await compilerCtx.fs.writeFile(join$2(dir, "ssr-prop.cjs"), cjsCode, opts);
12959
+ }
12875
12960
  };
12876
12961
  //#endregion
12877
12962
  //#region src/compiler/output-targets/ssr/generate-ssr-app.ts
@@ -12984,10 +13069,42 @@ const generateSsrFactoryEntry = async (buildCtx) => {
12984
13069
  return s.toString();
12985
13070
  };
12986
13071
  //#endregion
13072
+ //#region src/compiler/output-targets/ssr/validate-reserved-attributes.ts
13073
+ /** Attributes server rendering writes on component hosts and the nodes they render. */
13074
+ const SSR_ATTRIBUTES = /* @__PURE__ */ new Set([
13075
+ HYDRATE_ID,
13076
+ HYDRATE_CHILD_ID,
13077
+ "s-sn",
13078
+ "s-mode"
13079
+ ]);
13080
+ /**
13081
+ * Report props whose attribute would collide with one server rendering writes (`@Prop() sId` is
13082
+ * `s-id`): the server would overwrite or remove the value and the client would misread it. Only
13083
+ * relevant to builds that render on a server, so it's run by the `ssr` and `ssr-wasm` outputs.
13084
+ *
13085
+ * Complex props have no attribute of their own, but templates bind `ssrProp()` values under the
13086
+ * dash-cased prop name, so that's checked too.
13087
+ *
13088
+ * @param config the validated config
13089
+ * @param buildCtx the current build context
13090
+ */
13091
+ const validateSsrReservedAttributes = (config, buildCtx) => {
13092
+ for (const cmp of buildCtx.components) for (const prop of cmp.properties) {
13093
+ const attribute = prop.attribute ?? toDashCase(prop.name);
13094
+ if (!SSR_ATTRIBUTES.has(attribute)) continue;
13095
+ const err = buildError(buildCtx.diagnostics);
13096
+ err.header = "Reserved Attribute Name";
13097
+ err.messageText = `The "${prop.name}" prop of <${cmp.tagName}> uses the attribute "${attribute}", which Stencil writes when it renders on the server. Rename the prop, or give it another attribute name: @Prop({ attribute: '...' }).`;
13098
+ err.absFilePath = cmp.sourceFilePath;
13099
+ err.relFilePath = relative$1(config.rootDir, cmp.sourceFilePath);
13100
+ }
13101
+ };
13102
+ //#endregion
12987
13103
  //#region src/compiler/output-targets/ssr/index.ts
12988
13104
  const outputSsr = async (config, compilerCtx, buildCtx) => {
12989
13105
  const ssrOutputTargets = filterActiveTargets(config.outputTargets.filter(isOutputTargetSsr), config.devMode);
12990
13106
  if (ssrOutputTargets.length > 0) {
13107
+ validateSsrReservedAttributes(config, buildCtx);
12991
13108
  const timespan = buildCtx.createTimeSpan(`generate SSR app started`);
12992
13109
  await generateSsrApp(config, compilerCtx, buildCtx, ssrOutputTargets);
12993
13110
  timespan.finish(`generate SSR app finished`);
@@ -13284,6 +13401,7 @@ const compileToWasm = async (buildCtx, jsPath, interfacePath, wasmPath) => {
13284
13401
  const outputSsrWasm = async (config, compilerCtx, buildCtx) => {
13285
13402
  const ssrWasmTargets = filterActiveTargets(config.outputTargets.filter(isOutputTargetSsrWasm), config.devMode);
13286
13403
  if (ssrWasmTargets.length > 0) {
13404
+ if (filterActiveTargets(config.outputTargets.filter(isOutputTargetSsr), config.devMode).length === 0) validateSsrReservedAttributes(config, buildCtx);
13287
13405
  const timespan = buildCtx.createTimeSpan(`generate SSR WASM started`);
13288
13406
  await generateSsrWasmApp(config, compilerCtx, buildCtx, ssrWasmTargets);
13289
13407
  timespan.finish(`generate SSR WASM finished`);
@@ -13364,17 +13482,9 @@ const createDefineCase = (tagName, actionExpression) => {
13364
13482
  return ts.factory.createCaseClause(ts.factory.createStringLiteral(tagName), [ts.factory.createIfStatement(getCheck, ts.factory.createBlock([ts.factory.createExpressionStatement(actionExpression)])), ts.factory.createBreakStatement()]);
13365
13483
  };
13366
13484
  /**
13367
- * Adds the exported `defineCustomElement` function declaration.
13368
- *
13369
- * Global path:
13370
- * ```js
13371
- * export function defineCustomElement() {
13372
- * if (typeof customElements === 'undefined') return;
13373
- * ['my-comp', ...].forEach(tagName => { switch (tagName) { ... } });
13374
- * }
13375
- * ```
13485
+ * Adds the exported `defineCustomElement` function declaration. `__stencil_getRegistry()` returns
13486
+ * `undefined` where there's no `customElements` (e.g. on a server), so the call is a no-op there.
13376
13487
  *
13377
- * Scoped path:
13378
13488
  * ```js
13379
13489
  * export function defineCustomElement(opts) {
13380
13490
  * const _storeReg = __stencil_getRegistry();
@@ -15897,8 +16007,8 @@ var ImportAliasMap = class extends Map {
15897
16007
  for (const importDeclaration of importDeclarations) if (importDeclaration.moduleSpecifier.getText().includes("@stencil/core")) {
15898
16008
  const namedBindings = importDeclaration.importClause?.namedBindings;
15899
16009
  if (namedBindings && ts.isNamedImports(namedBindings)) for (const element of namedBindings.elements) {
15900
- const importName = element.name.getText();
15901
- const originalImportName = element.propertyName?.getText() ?? importName;
16010
+ const importName = element.name.text;
16011
+ const originalImportName = element.propertyName?.text ?? importName;
15902
16012
  if (STENCIL_DECORATORS.includes(originalImportName)) this.set(originalImportName, importName);
15903
16013
  }
15904
16014
  }
@@ -15908,6 +16018,102 @@ var ImportAliasMap = class extends Map {
15908
16018
  }
15909
16019
  };
15910
16020
  //#endregion
16021
+ //#region src/compiler/transformers/decorators-to-static/json-serialize-prop.ts
16022
+ /**
16023
+ * `@Prop({ serialize: 'json' })` is shorthand for a `@PropSerialize()` / `@AttrDeserialize()` pair
16024
+ * that writes the value to the prop's attribute as JSON on the server, and reads it back in the
16025
+ * browser. These are the generated methods' names (no leading `_`: the runtime metadata drops
16026
+ * those keys), and the alias of the `Build` import they use.
16027
+ */
16028
+ const JSON_SERIALIZE_METHOD = "stencilSerializeJson";
16029
+ const JSON_DESERIALIZE_METHOD = "stencilDeserializeJson";
16030
+ const BUILD_ALIAS = "__stencil_Build";
16031
+ /**
16032
+ * Find the props declared `@Prop({ serialize: 'json' })`, reporting invalid combinations.
16033
+ * @param diagnostics for surfacing errors
16034
+ * @param typeChecker a TypeScript typechecker instance
16035
+ * @param decoratedMembers the class's decorated members
16036
+ * @param propDecoratorName the name `@Prop` is imported as
16037
+ * @param handWritten serializers and deserializers written with the decorators
16038
+ * @returns the names of the props to serialize as JSON
16039
+ */
16040
+ const getJsonSerializedProps = (diagnostics, typeChecker, decoratedMembers, propDecoratorName, handWritten) => decoratedMembers.flatMap((member) => {
16041
+ if (!ts.isPropertyDeclaration(member) && !ts.isGetAccessor(member)) return [];
16042
+ const decorator = retrieveTsDecorators(member)?.find(isDecoratorNamed(propDecoratorName));
16043
+ if (!decorator) return [];
16044
+ const [options] = getDecoratorParameters(decorator, typeChecker);
16045
+ if (options?.serialize == null) return [];
16046
+ const { staticName: propName } = tsPropDeclName(member, typeChecker);
16047
+ const error = (messageText) => {
16048
+ const err = buildError(diagnostics);
16049
+ err.messageText = messageText;
16050
+ augmentDiagnosticWithNode(err, decorator);
16051
+ };
16052
+ if (options.serialize !== "json") {
16053
+ error(`@Prop({ serialize }) on "${propName}" must be 'json'. For other formats, use @PropSerialize() and @AttrDeserialize().`);
16054
+ return [];
16055
+ }
16056
+ if (options.attribute === null) {
16057
+ error(`@Prop({ serialize: 'json' }) on "${propName}" needs an attribute to write to, but it has "attribute: null".`);
16058
+ return [];
16059
+ }
16060
+ if (handWritten.some((h) => h.propName === propName)) {
16061
+ error(`"${propName}" has both @Prop({ serialize: 'json' }) and its own @PropSerialize() / @AttrDeserialize(). Use one or the other.`);
16062
+ return [];
16063
+ }
16064
+ return [propName];
16065
+ });
16066
+ /**
16067
+ * The methods `@Prop({ serialize: 'json' })` uses, shared by every such prop in a class:
16068
+ *
16069
+ * ```ts
16070
+ * stencilSerializeJson(value) {
16071
+ * return __stencil_Build.isServer ? JSON.stringify(value) : null;
16072
+ * }
16073
+ * stencilDeserializeJson(value, propName) {
16074
+ * try {
16075
+ * return JSON.parse(value);
16076
+ * } catch {
16077
+ * if (__stencil_Build.isDev) console.warn(...);
16078
+ * // leave the prop as it is
16079
+ * return __stencil_Build.isServer ? undefined : this[propName];
16080
+ * }
16081
+ * }
16082
+ * ```
16083
+ *
16084
+ * The serializer only writes on the server, like a hand-written one should: in the browser the
16085
+ * attribute's job is done, and rewriting it on every change would be wasted work.
16086
+ * @returns the two method declarations
16087
+ */
16088
+ const createJsonSerializerMethods = () => {
16089
+ const f = ts.factory;
16090
+ const build = (flag) => f.createPropertyAccessExpression(f.createIdentifier(BUILD_ALIAS), flag);
16091
+ const jsonCall = (method, arg) => f.createCallExpression(f.createPropertyAccessExpression(f.createIdentifier("JSON"), method), void 0, [arg]);
16092
+ const param = (name) => f.createParameterDeclaration(void 0, void 0, name);
16093
+ const method = (name, params, body) => f.createMethodDeclaration(void 0, void 0, name, void 0, void 0, params.map(param), void 0, f.createBlock(body, true));
16094
+ const serialize = method(JSON_SERIALIZE_METHOD, ["value"], [f.createReturnStatement(f.createConditionalExpression(build("isServer"), void 0, jsonCall("stringify", f.createIdentifier("value")), void 0, f.createNull()))]);
16095
+ const warn = f.createIfStatement(build("isDev"), f.createExpressionStatement(f.createCallExpression(f.createPropertyAccessExpression(f.createIdentifier("console"), "warn"), void 0, [f.createTemplateExpression(f.createTemplateHead("The \""), [f.createTemplateSpan(f.createIdentifier("propName"), f.createTemplateMiddle(`" attribute isn't valid JSON, so the prop was left as it is: `)), f.createTemplateSpan(f.createIdentifier("value"), f.createTemplateTail(""))])])));
16096
+ return [serialize, method(JSON_DESERIALIZE_METHOD, ["value", "propName"], [f.createTryStatement(f.createBlock([f.createReturnStatement(jsonCall("parse", f.createIdentifier("value")))], true), f.createCatchClause(void 0, f.createBlock([warn, f.createReturnStatement(f.createConditionalExpression(build("isServer"), void 0, f.createIdentifier("undefined"), void 0, f.createElementAccessExpression(f.createThis(), f.createIdentifier("propName"))))], true)), void 0)])];
16097
+ };
16098
+ /**
16099
+ * Import `Build` (as {@link BUILD_ALIAS}) from `@stencil/core`, for the generated methods. Added
16100
+ * to an existing `@stencil/core` import, which a component's source always has.
16101
+ * @param sourceFile the source file
16102
+ * @returns the source file with the import
16103
+ */
16104
+ const addBuildImport = (sourceFile) => {
16105
+ const f = ts.factory;
16106
+ const specifier = f.createImportSpecifier(false, f.createIdentifier("Build"), f.createIdentifier(BUILD_ALIAS));
16107
+ let added = false;
16108
+ const statements = sourceFile.statements.map((s) => {
16109
+ if (added || !ts.isImportDeclaration(s) || !ts.isStringLiteral(s.moduleSpecifier) || s.moduleSpecifier.text !== "@stencil/core" || !s.importClause?.namedBindings || !ts.isNamedImports(s.importClause.namedBindings) || s.importClause.isTypeOnly) return s;
16110
+ added = true;
16111
+ return f.updateImportDeclaration(s, s.modifiers, f.updateImportClause(s.importClause, false, s.importClause.name, f.updateNamedImports(s.importClause.namedBindings, [...s.importClause.namedBindings.elements, specifier])), s.moduleSpecifier, s.attributes);
16112
+ });
16113
+ if (!added) statements.unshift(f.createImportDeclaration(void 0, f.createImportClause(false, void 0, f.createNamedImports([specifier])), f.createStringLiteral(STENCIL_CORE_ID)));
16114
+ return f.updateSourceFile(sourceFile, statements);
16115
+ };
16116
+ //#endregion
15911
16117
  //#region src/compiler/transformers/decorators-to-static/listen-decorator.ts
15912
16118
  const listenDecoratorsToStatic = (diagnostics, typeChecker, decoratedMembers, newMembers, decoratorName) => {
15913
16119
  const listeners = decoratedMembers.filter(ts.isMethodDeclaration).map((method) => parseListenDecorators(diagnostics, typeChecker, method, decoratorName));
@@ -16321,7 +16527,7 @@ const isTypePromise = (typeStr) => {
16321
16527
  };
16322
16528
  const validateMethods = (diagnostics, members) => {
16323
16529
  members.filter(ts.isMethodDeclaration).map((method) => {
16324
- if (method.name.getText() === "componentDidUnload") {
16530
+ if (ts.isIdentifier(method.name) && method.name.text === "componentDidUnload") {
16325
16531
  const err = buildError(diagnostics);
16326
16532
  err.header = `Replace "componentDidUnload()" with "disconnectedCallback()"`;
16327
16533
  err.messageText = `The "componentDidUnload()" method was removed in Stencil 2. Please use the "disconnectedCallback()" method instead.`;
@@ -16686,7 +16892,7 @@ const getPropertyNameText = (name) => {
16686
16892
  };
16687
16893
  //#endregion
16688
16894
  //#region src/compiler/transformers/decorators-to-static/serialize-decorators.ts
16689
- const serializeDecoratorsToStatic = (typeChecker, decoratedProps, newMembers, decoratorName, translateType, propDecoratorName) => {
16895
+ const serializeDecoratorsToStatic = (typeChecker, decoratedProps, newMembers, decoratorName, translateType, propDecoratorName, generated = []) => {
16690
16896
  const props = decoratedProps.filter((prop) => ts.isPropertyDeclaration(prop) || ts.isGetAccessor(prop)).flatMap((prop) => {
16691
16897
  if (retrieveTsDecorators(prop)?.find(isDecoratorNamed(propDecoratorName))) {
16692
16898
  const { staticName } = tsPropDeclName(prop, typeChecker);
@@ -16694,7 +16900,7 @@ const serializeDecoratorsToStatic = (typeChecker, decoratedProps, newMembers, de
16694
16900
  }
16695
16901
  return [];
16696
16902
  });
16697
- const serializers = decoratedProps.filter(ts.isMethodDeclaration).flatMap((method) => parseSerializeDecorator(typeChecker, method, decoratorName, props));
16903
+ const serializers = [...decoratedProps.filter(ts.isMethodDeclaration).flatMap((method) => parseSerializeDecorator(typeChecker, method, decoratorName, props)), ...generated];
16698
16904
  if (serializers.length > 0) {
16699
16905
  if (translateType === "PropSerialize") newMembers.push(createStaticGetter("serializers", convertValueToLiteral(serializers)));
16700
16906
  else newMembers.push(createStaticGetter("deserializers", convertValueToLiteral(serializers)));
@@ -16794,6 +17000,8 @@ const parseWatchDecorator = (typeChecker, method, decoratorName) => {
16794
17000
  * @returns a TypeScript transformer factory which can be passed to
16795
17001
  * TypeScript to transform source code during the compilation process
16796
17002
  */
17003
+ /** Source files with a `@Prop({ serialize: 'json' })`, which need a `Build` import. */
17004
+ const filesWithJsonProps = /* @__PURE__ */ new WeakSet();
16797
17005
  const convertDecoratorsToStatic = (config, diagnostics, typeChecker, program, includeClassExpressions = false) => {
16798
17006
  return (transformCtx) => {
16799
17007
  let sourceFile;
@@ -16803,7 +17011,8 @@ const convertDecoratorsToStatic = (config, diagnostics, typeChecker, program, in
16803
17011
  };
16804
17012
  return (tsSourceFile) => {
16805
17013
  sourceFile = tsSourceFile;
16806
- return ts.visitEachChild(tsSourceFile, visit, transformCtx);
17014
+ const updated = ts.visitEachChild(tsSourceFile, visit, transformCtx);
17015
+ return filesWithJsonProps.has(tsSourceFile) ? addBuildImport(updated) : updated;
16807
17016
  };
16808
17017
  };
16809
17018
  };
@@ -16841,8 +17050,20 @@ const visitClassDeclaration = (config, diagnostics, typeChecker, program, classN
16841
17050
  const filteredMethodsAndFields = removeStencilMethodDecorators(Array.from(classMembers), diagnostics, importAliasMap);
16842
17051
  if (componentDecorator && ts.isClassDeclaration(classNode)) componentDecoratorToStatic(config, typeChecker, diagnostics, classNode, filteredMethodsAndFields, componentDecorator);
16843
17052
  if (decoratedMembers.length > 0) {
16844
- const serializers = serializeDecoratorsToStatic(typeChecker, decoratedMembers, filteredMethodsAndFields, importAliasMap.get("PropSerialize"), "PropSerialize", importAliasMap.get("Prop"));
16845
- const deserializers = serializeDecoratorsToStatic(typeChecker, decoratedMembers, filteredMethodsAndFields, importAliasMap.get("AttrDeserialize"), "AttrDeserialize", importAliasMap.get("Prop"));
17053
+ const handWritten = serializeDecoratorsToStatic(typeChecker, decoratedMembers, [], importAliasMap.get("PropSerialize"), "PropSerialize", importAliasMap.get("Prop")).concat(serializeDecoratorsToStatic(typeChecker, decoratedMembers, [], importAliasMap.get("AttrDeserialize"), "AttrDeserialize", importAliasMap.get("Prop")));
17054
+ const jsonProps = getJsonSerializedProps(diagnostics, typeChecker, decoratedMembers, importAliasMap.get("Prop"), handWritten);
17055
+ if (jsonProps.length > 0) {
17056
+ filteredMethodsAndFields.push(...createJsonSerializerMethods());
17057
+ filesWithJsonProps.add(sourceFile);
17058
+ }
17059
+ const serializers = serializeDecoratorsToStatic(typeChecker, decoratedMembers, filteredMethodsAndFields, importAliasMap.get("PropSerialize"), "PropSerialize", importAliasMap.get("Prop"), jsonProps.map((propName) => ({
17060
+ propName,
17061
+ methodName: JSON_SERIALIZE_METHOD
17062
+ })));
17063
+ const deserializers = serializeDecoratorsToStatic(typeChecker, decoratedMembers, filteredMethodsAndFields, importAliasMap.get("AttrDeserialize"), "AttrDeserialize", importAliasMap.get("Prop"), jsonProps.map((propName) => ({
17064
+ propName,
17065
+ methodName: JSON_DESERIALIZE_METHOD
17066
+ })));
16846
17067
  propDecoratorsToStatic(config, diagnostics, decoratedMembers, typeChecker, program, filteredMethodsAndFields, importAliasMap.get("Prop"), serializers, deserializers);
16847
17068
  stateDecoratorsToStatic(decoratedMembers, filteredMethodsAndFields, typeChecker, importAliasMap.get("State"));
16848
17069
  eventDecoratorsToStatic(config, diagnostics, decoratedMembers, typeChecker, program, filteredMethodsAndFields, importAliasMap.get("Event"));
@@ -19089,7 +19310,7 @@ const performAutomaticKeyInsertion = (transformCtx) => {
19089
19310
  * @returns the result of handling the node
19090
19311
  */
19091
19312
  function findRenderMethodVisitor(node) {
19092
- if (ts.isMethodDeclaration(node) && node.name.getText() === "render" && numReturnStatements(node) === 1) {
19313
+ if (ts.isMethodDeclaration(node) && ts.isIdentifier(node.name) && node.name.text === "render" && numReturnStatements(node) === 1) {
19093
19314
  resetKeyCounter();
19094
19315
  return ts.visitEachChild(node, jsxElementVisitor, transformCtx);
19095
19316
  } else return ts.visitEachChild(node, findRenderMethodVisitor, transformCtx);
@@ -20451,6 +20672,11 @@ const getGeneratedExports = (config, buildCtx, loaderBundle, standalone, ssr, ty
20451
20672
  import: `${outDir}/index.js`,
20452
20673
  require: ssr.cjs ? `${outDir}/index.cjs` : void 0
20453
20674
  };
20675
+ generated["./ssr-prop"] = {
20676
+ types: `${outDir}/ssr-prop.d.ts`,
20677
+ import: `${outDir}/ssr-prop.js`,
20678
+ require: ssr.cjs ? `${outDir}/ssr-prop.cjs` : void 0
20679
+ };
20454
20680
  }
20455
20681
  if (loaderBundle || standalone) {
20456
20682
  const globalStyles = config.outputTargets.filter(isOutputTargetGlobalStyle);
@@ -191,6 +191,16 @@ interface PropOptions {
191
191
  * In this case you can set the `reflect` option to `true`, since it defaults to `false`:
192
192
  */
193
193
  reflect?: boolean;
194
+ /**
195
+ * Carry the prop's value from a server render to the browser in its attribute, as JSON:
196
+ * shorthand for a `@PropSerialize()` that writes `JSON.stringify(value)` on the server and an
197
+ * `@AttrDeserialize()` that reads it back with `JSON.parse()`. Attribute values that aren't
198
+ * valid JSON leave the prop as it is (with a warning in dev builds).
199
+ *
200
+ * For other formats (a `Map`, a `Date`...), write the `@PropSerialize()` /
201
+ * `@AttrDeserialize()` pair yourself.
202
+ */
203
+ serialize?: 'json';
194
204
  }
195
205
  interface MethodDecorator {
196
206
  (opts?: MethodOptions): CustomMethodDecorator<any>;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { C as Build, S as setErrorHandler, _ as getAssetPath, a as transformTag, b as writeTask, c as Mixin, d as Host, f as h, g as getShadowRoot, h as getElement, i as setTagTransformer, l as getMode, m as getRenderingRef, o as render, p as forceUpdate, s as ReactiveControllerHost, u as setMode, v as setAssetPath, x as setPlatformHelpers, y as readTask } from "./client-UbH-XkYu.mjs";
1
+ import { C as Build, S as setErrorHandler, _ as getAssetPath, a as transformTag, b as writeTask, c as Mixin, d as Host, f as h, g as getShadowRoot, h as getElement, i as setTagTransformer, l as getMode, m as getRenderingRef, o as render, p as forceUpdate, s as ReactiveControllerHost, u as setMode, v as setAssetPath, x as setPlatformHelpers, y as readTask } from "./client-CqQpuOUk.mjs";
2
2
  import { t as Fragment } from "./fragment-Di1hWOC8.mjs";
3
3
  //#region src/client/client-decorators.ts
4
4
  /**
@@ -1,3 +1,3 @@
1
- import { n as jsxDEV, r as jsxs, t as jsx } from "./client-UbH-XkYu.mjs";
1
+ import { n as jsxDEV, r as jsxs, t as jsx } from "./client-CqQpuOUk.mjs";
2
2
  import { t as Fragment } from "./fragment-Di1hWOC8.mjs";
3
3
  export { Fragment, jsx, jsxDEV, jsxs };
@@ -1,5 +1,5 @@
1
1
  import { n as __require } from "./rolldown-runtime-BhDjJH2R.mjs";
2
- import "./client-UbH-XkYu.mjs";
2
+ import "./client-CqQpuOUk.mjs";
3
3
  import { c as isFunction, f as isString, m as noop, r as flatOne } from "./helpers-Cpp3qc3u.mjs";
4
4
  import { X as TASK_CANCELED_MSG, Z as buildError, et as catchError, it as isGlob, q as normalizePath, rt as shouldIgnoreError } from "./util-C-H1H84W.mjs";
5
5
  import fs from "node:fs";
@@ -1137,7 +1137,9 @@ const patchTextContent = (hostElementPrototype) => {
1137
1137
  Object.defineProperty(hostElementPrototype, "textContent", {
1138
1138
  get: function() {
1139
1139
  let text = "";
1140
- (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => text += node.textContent || "");
1140
+ (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => {
1141
+ if (node.nodeType !== NODE_TYPE.CommentNode) text += node.textContent || "";
1142
+ });
1141
1143
  return text;
1142
1144
  },
1143
1145
  set: function(value) {
@@ -1145,7 +1147,7 @@ const patchTextContent = (hostElementPrototype) => {
1145
1147
  if (node["s-ol"]) node["s-ol"].remove();
1146
1148
  node.remove();
1147
1149
  });
1148
- this.insertAdjacentHTML("beforeend", value);
1150
+ if (value != null && value !== "") this.append(this.ownerDocument.createTextNode(String(value)));
1149
1151
  }
1150
1152
  });
1151
1153
  };
@@ -1786,7 +1788,7 @@ let _registry;
1786
1788
  const setRegistry = (registry) => {
1787
1789
  _registry = registry;
1788
1790
  };
1789
- const getRegistry = () => _registry ?? customElements;
1791
+ const getRegistry = () => _registry ?? globalThis.customElements;
1790
1792
  /**
1791
1793
  * @param elm a defined component host
1792
1794
  * @returns the registry the host's class was defined in, else the active registry
@@ -3761,6 +3763,11 @@ const addSlottedNodes = (slottedNodes, slotNodeId, slotName, slotNode, hostId) =
3761
3763
  * @returns the first corresponding node of the type
3762
3764
  */
3763
3765
  const findCorrespondingNode = (node, type) => {
3766
+ if (type === NODE_TYPE.TextNode) {
3767
+ const next = node.nextSibling;
3768
+ if (next?.nodeType === NODE_TYPE.TextNode) return next;
3769
+ return node.parentNode.insertBefore(node.ownerDocument.createTextNode(""), next);
3770
+ }
3764
3771
  let sibling = node;
3765
3772
  do
3766
3773
  sibling = sibling.nextSibling;
@@ -5434,4 +5441,4 @@ function hasKeys(obj) {
5434
5441
  return false;
5435
5442
  }
5436
5443
  //#endregion
5437
- export { AttachInternals, AttrDeserialize, BUILD, Build, Component, Element$1 as Element, Env, Event, Fragment, H, H as HTMLElement, HYDRATED_STYLE_ID, Host, Listen, Method, Mixin, NAMESPACE, Prop, PropSerialize, ReactiveControllerHost, STENCIL_DEV_MODE, State, Watch, addHostEventListeners, bootstrapLazy, cmpModules, connectedCallback, consoleDevError, consoleDevInfo, consoleDevWarn, consoleError, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, isMemberInElement, jsx, jsxDEV, jsxs, loadModule, modeResolver, needsScopedSSR, nextTick, normalizeWatchers, parsePropertyValue, plt, postUpdateComponent, promiseResolve, proxyComponent, proxyCustomElement, readTask, registerHost, registerInstance, registerSideEffectStyleTarget, render, resolveVar, setAssetPath, setErrorHandler, setLazyLoadBasePath, setMode, setNonce, setPlatformHelpers, setPlatformOptions, setRegistry, setScopedSSR, setTagTransformer, setValue, styles, supportsConstructableStylesheets, supportsListenerOptions, supportsMutableAdoptedStyleSheets, transformTag, unregisterSideEffectStyleTarget, win, writeTask };
5444
+ export { AttachInternals, AttrDeserialize, BUILD, Build, Component, Element$1 as Element, Env, Event, Fragment, H, H as HTMLElement, HYDRATED_STYLE_ID, Host, Listen, Method, Mixin, NAMESPACE, Prop, PropSerialize, ReactiveControllerHost, STENCIL_DEV_MODE, State, Watch, addHostEventListeners, applySerializers, bootstrapLazy, cmpModules, connectedCallback, consoleDevError, consoleDevInfo, consoleDevWarn, consoleError, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, isMemberInElement, jsx, jsxDEV, jsxs, loadModule, modeResolver, needsScopedSSR, nextTick, normalizeWatchers, parsePropertyValue, plt, postUpdateComponent, promiseResolve, proxyComponent, proxyCustomElement, readTask, registerHost, registerInstance, registerSideEffectStyleTarget, render, resolveVar, setAssetPath, setErrorHandler, setLazyLoadBasePath, setMode, setNonce, setPlatformHelpers, setPlatformOptions, setRegistry, setScopedSSR, setTagTransformer, setValue, styles, supportsConstructableStylesheets, supportsListenerOptions, supportsMutableAdoptedStyleSheets, transformTag, unregisterSideEffectStyleTarget, win, writeTask };
@@ -2527,6 +2527,7 @@ declare function render(vnode: VNode, container: Element): void;
2527
2527
  declare const HYDRATED_STYLE_ID = "sty-id";
2528
2528
  //#endregion
2529
2529
  //#region src/runtime/set-value.d.ts
2530
+ declare const applySerializers: (hostRef: HostRef, cmpMeta: ComponentRuntimeMeta, propName: string, val: any, instance: any) => void;
2530
2531
  declare const getValue: (ref: RuntimeRef, propName: string) => any;
2531
2532
  declare const setValue: (ref: RuntimeRef, propName: string, newVal: any, cmpMeta: ComponentRuntimeMeta) => void;
2532
2533
  //#endregion
@@ -2563,4 +2564,4 @@ declare const jsxs: typeof jsx;
2563
2564
  */
2564
2565
  declare const jsxDEV: typeof jsx;
2565
2566
  //#endregion
2566
- export { AttachInternals, AttrDeserialize, BUILD, Build, Component, Element$1 as Element, Env, Event, Fragment, H, H as HTMLElement, type HTMLStencilElement, HYDRATED_STYLE_ID, Host, type JSXBase, Listen, Method, Mixin, NAMESPACE, Prop, PropSerialize, ReactiveControllerHost, STENCIL_DEV_MODE, State, Watch, addHostEventListeners, bootstrapLazy, cmpModules, connectedCallback, consoleDevError, consoleDevInfo, consoleDevWarn, consoleError, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, isMemberInElement, jsx, jsxDEV, jsxs, loadModule, modeResolver, needsScopedSSR, nextTick, normalizeWatchers, parsePropertyValue, plt, postUpdateComponent, promiseResolve, proxyComponent, proxyCustomElement, readTask, registerHost, registerInstance, registerSideEffectStyleTarget, render, resolveVar, setAssetPath, setErrorHandler, setLazyLoadBasePath, setMode, setNonce, setPlatformHelpers, setPlatformOptions, setRegistry, setScopedSSR, setTagTransformer, setValue, styles, supportsConstructableStylesheets, supportsListenerOptions, supportsMutableAdoptedStyleSheets, transformTag, unregisterSideEffectStyleTarget, win, writeTask };
2567
+ export { AttachInternals, AttrDeserialize, BUILD, Build, Component, Element$1 as Element, Env, Event, Fragment, H, H as HTMLElement, type HTMLStencilElement, HYDRATED_STYLE_ID, Host, type JSXBase, Listen, Method, Mixin, NAMESPACE, Prop, PropSerialize, ReactiveControllerHost, STENCIL_DEV_MODE, State, Watch, addHostEventListeners, applySerializers, bootstrapLazy, cmpModules, connectedCallback, consoleDevError, consoleDevInfo, consoleDevWarn, consoleError, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, isMemberInElement, jsx, jsxDEV, jsxs, loadModule, modeResolver, needsScopedSSR, nextTick, normalizeWatchers, parsePropertyValue, plt, postUpdateComponent, promiseResolve, proxyComponent, proxyCustomElement, readTask, registerHost, registerInstance, registerSideEffectStyleTarget, render, resolveVar, setAssetPath, setErrorHandler, setLazyLoadBasePath, setMode, setNonce, setPlatformHelpers, setPlatformOptions, setRegistry, setScopedSSR, setTagTransformer, setValue, styles, supportsConstructableStylesheets, supportsListenerOptions, supportsMutableAdoptedStyleSheets, transformTag, unregisterSideEffectStyleTarget, win, writeTask };
@@ -1131,7 +1131,9 @@ const patchTextContent = (hostElementPrototype) => {
1131
1131
  Object.defineProperty(hostElementPrototype, "textContent", {
1132
1132
  get: function() {
1133
1133
  let text = "";
1134
- (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => text += node.textContent || "");
1134
+ (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => {
1135
+ if (node.nodeType !== NODE_TYPE.CommentNode) text += node.textContent || "";
1136
+ });
1135
1137
  return text;
1136
1138
  },
1137
1139
  set: function(value) {
@@ -1139,7 +1141,7 @@ const patchTextContent = (hostElementPrototype) => {
1139
1141
  if (node["s-ol"]) node["s-ol"].remove();
1140
1142
  node.remove();
1141
1143
  });
1142
- this.insertAdjacentHTML("beforeend", value);
1144
+ if (value != null && value !== "") this.append(this.ownerDocument.createTextNode(String(value)));
1143
1145
  }
1144
1146
  });
1145
1147
  };
@@ -1780,7 +1782,7 @@ let _registry;
1780
1782
  const setRegistry = (registry) => {
1781
1783
  _registry = registry;
1782
1784
  };
1783
- const getRegistry = () => _registry ?? customElements;
1785
+ const getRegistry = () => _registry ?? globalThis.customElements;
1784
1786
  /**
1785
1787
  * @param elm a defined component host
1786
1788
  * @returns the registry the host's class was defined in, else the active registry
@@ -3755,6 +3757,11 @@ const addSlottedNodes = (slottedNodes, slotNodeId, slotName, slotNode, hostId) =
3755
3757
  * @returns the first corresponding node of the type
3756
3758
  */
3757
3759
  const findCorrespondingNode = (node, type) => {
3760
+ if (type === NODE_TYPE.TextNode) {
3761
+ const next = node.nextSibling;
3762
+ if (next?.nodeType === NODE_TYPE.TextNode) return next;
3763
+ return node.parentNode.insertBefore(node.ownerDocument.createTextNode(""), next);
3764
+ }
3758
3765
  let sibling = node;
3759
3766
  do
3760
3767
  sibling = sibling.nextSibling;
@@ -5428,4 +5435,4 @@ function hasKeys(obj) {
5428
5435
  return false;
5429
5436
  }
5430
5437
  //#endregion
5431
- export { AttachInternals, AttrDeserialize, BUILD, Build, Component, Element$1 as Element, Env, Event, Fragment, H, H as HTMLElement, HYDRATED_STYLE_ID, Host, Listen, Method, Mixin, NAMESPACE, Prop, PropSerialize, ReactiveControllerHost, STENCIL_DEV_MODE, State, Watch, addHostEventListeners, bootstrapLazy, cmpModules, connectedCallback, consoleDevError, consoleDevInfo, consoleDevWarn, consoleError, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, isMemberInElement, jsx, jsxDEV, jsxs, loadModule, modeResolver, needsScopedSSR, nextTick, normalizeWatchers, parsePropertyValue, plt, postUpdateComponent, promiseResolve, proxyComponent, proxyCustomElement, readTask, registerHost, registerInstance, registerSideEffectStyleTarget, render, resolveVar, setAssetPath, setErrorHandler, setLazyLoadBasePath, setMode, setNonce, setPlatformHelpers, setPlatformOptions, setRegistry, setScopedSSR, setTagTransformer, setValue, styles, supportsConstructableStylesheets, supportsListenerOptions, supportsMutableAdoptedStyleSheets, transformTag, unregisterSideEffectStyleTarget, win, writeTask };
5438
+ export { AttachInternals, AttrDeserialize, BUILD, Build, Component, Element$1 as Element, Env, Event, Fragment, H, H as HTMLElement, HYDRATED_STYLE_ID, Host, Listen, Method, Mixin, NAMESPACE, Prop, PropSerialize, ReactiveControllerHost, STENCIL_DEV_MODE, State, Watch, addHostEventListeners, applySerializers, bootstrapLazy, cmpModules, connectedCallback, consoleDevError, consoleDevInfo, consoleDevWarn, consoleError, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, isMemberInElement, jsx, jsxDEV, jsxs, loadModule, modeResolver, needsScopedSSR, nextTick, normalizeWatchers, parsePropertyValue, plt, postUpdateComponent, promiseResolve, proxyComponent, proxyCustomElement, readTask, registerHost, registerInstance, registerSideEffectStyleTarget, render, resolveVar, setAssetPath, setErrorHandler, setLazyLoadBasePath, setMode, setNonce, setPlatformHelpers, setPlatformOptions, setRegistry, setScopedSSR, setTagTransformer, setValue, styles, supportsConstructableStylesheets, supportsListenerOptions, supportsMutableAdoptedStyleSheets, transformTag, unregisterSideEffectStyleTarget, win, writeTask };
@@ -199,6 +199,7 @@ declare function render(vnode: VNode, container: Element): void;
199
199
  declare const HYDRATED_STYLE_ID = "sty-id";
200
200
  //#endregion
201
201
  //#region src/runtime/set-value.d.ts
202
+ declare const applySerializers: (hostRef: HostRef, cmpMeta: ComponentRuntimeMeta, propName: string, val: any, instance: any) => void;
202
203
  declare const getValue: (ref: RuntimeRef, propName: string) => any;
203
204
  declare const setValue: (ref: RuntimeRef, propName: string, newVal: any, cmpMeta: ComponentRuntimeMeta) => void;
204
205
  //#endregion
@@ -235,4 +236,4 @@ declare const jsxs: typeof jsx;
235
236
  */
236
237
  declare const jsxDEV: typeof jsx;
237
238
  //#endregion
238
- export { Fragment, type HTMLStencilElement, HYDRATED_STYLE_ID, Host, type JSXBase, Mixin, ReactiveControllerHost, addHostEventListeners, bootstrapLazy, connectedCallback, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, jsx, jsxDEV, jsxs, normalizeWatchers, parsePropertyValue, postUpdateComponent, proxyComponent, proxyCustomElement, registerSideEffectStyleTarget, render, setAssetPath, setMode, setNonce, setPlatformOptions, setRegistry, setTagTransformer, setValue, transformTag, unregisterSideEffectStyleTarget };
239
+ export { Fragment, type HTMLStencilElement, HYDRATED_STYLE_ID, Host, type JSXBase, Mixin, ReactiveControllerHost, addHostEventListeners, applySerializers, bootstrapLazy, connectedCallback, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, jsx, jsxDEV, jsxs, normalizeWatchers, parsePropertyValue, postUpdateComponent, proxyComponent, proxyCustomElement, registerSideEffectStyleTarget, render, setAssetPath, setMode, setNonce, setPlatformOptions, setRegistry, setTagTransformer, setValue, transformTag, unregisterSideEffectStyleTarget };