@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.
@@ -1003,7 +1003,9 @@ const patchTextContent = (hostElementPrototype) => {
1003
1003
  Object.defineProperty(hostElementPrototype, "textContent", {
1004
1004
  get: function() {
1005
1005
  let text = "";
1006
- (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => text += node.textContent || "");
1006
+ (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => {
1007
+ if (node.nodeType !== NODE_TYPE.CommentNode) text += node.textContent || "";
1008
+ });
1007
1009
  return text;
1008
1010
  },
1009
1011
  set: function(value) {
@@ -1011,7 +1013,7 @@ const patchTextContent = (hostElementPrototype) => {
1011
1013
  if (node["s-ol"]) node["s-ol"].remove();
1012
1014
  node.remove();
1013
1015
  });
1014
- this.insertAdjacentHTML("beforeend", value);
1016
+ if (value != null && value !== "") this.append(this.ownerDocument.createTextNode(String(value)));
1015
1017
  }
1016
1018
  });
1017
1019
  };
@@ -1652,7 +1654,7 @@ let _registry;
1652
1654
  const setRegistry = (registry) => {
1653
1655
  _registry = registry;
1654
1656
  };
1655
- const getRegistry = () => _registry ?? customElements;
1657
+ const getRegistry = () => _registry ?? globalThis.customElements;
1656
1658
  /**
1657
1659
  * @param elm a defined component host
1658
1660
  * @returns the registry the host's class was defined in, else the active registry
@@ -3627,6 +3629,11 @@ const addSlottedNodes = (slottedNodes, slotNodeId, slotName, slotNode, hostId) =
3627
3629
  * @returns the first corresponding node of the type
3628
3630
  */
3629
3631
  const findCorrespondingNode = (node, type) => {
3632
+ if (type === NODE_TYPE.TextNode) {
3633
+ const next = node.nextSibling;
3634
+ if (next?.nodeType === NODE_TYPE.TextNode) return next;
3635
+ return node.parentNode.insertBefore(node.ownerDocument.createTextNode(""), next);
3636
+ }
3630
3637
  let sibling = node;
3631
3638
  do
3632
3639
  sibling = sibling.nextSibling;
@@ -5300,4 +5307,4 @@ function hasKeys(obj) {
5300
5307
  return false;
5301
5308
  }
5302
5309
  //#endregion
5303
- export { Fragment, HYDRATED_STYLE_ID, Host, 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 };
5310
+ export { Fragment, HYDRATED_STYLE_ID, Host, 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 };
@@ -50,6 +50,8 @@ const NODE_TYPE = {
50
50
  const HYDRATE_ID = "s-id";
51
51
  const HYDRATED_STYLE_ID = "sty-id";
52
52
  const HYDRATE_CHILD_ID = "c-id";
53
+ /** `Symbol.for()` key of the `ssrProp()` registry on the server's real global object. */
54
+ const SSR_PROPS_REGISTRY_KEY = "stencil.ssrProps";
53
55
  const HYDRATED_CSS = "{visibility:hidden}.hydrated{visibility:inherit}";
54
56
  const STENCIL_DOC_DATA = "_stencilDocData";
55
57
  const DEFAULT_DOC_DATA = {
@@ -799,7 +801,9 @@ const patchTextContent = (hostElementPrototype) => {
799
801
  Object.defineProperty(hostElementPrototype, "textContent", {
800
802
  get: function() {
801
803
  let text = "";
802
- (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => text += node.textContent || "");
804
+ (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => {
805
+ if (node.nodeType !== NODE_TYPE.CommentNode) text += node.textContent || "";
806
+ });
803
807
  return text;
804
808
  },
805
809
  set: function(value) {
@@ -807,7 +811,7 @@ const patchTextContent = (hostElementPrototype) => {
807
811
  if (node["s-ol"]) node["s-ol"].remove();
808
812
  node.remove();
809
813
  });
810
- this.insertAdjacentHTML("beforeend", value);
814
+ if (value != null && value !== "") this.append(this.ownerDocument.createTextNode(String(value)));
811
815
  }
812
816
  });
813
817
  };
@@ -1373,6 +1377,13 @@ const hydrateScopedToShadow = () => {
1373
1377
  */
1374
1378
  const isDef = (v) => v != null && v !== void 0;
1375
1379
  /**
1380
+ * Convert a string from PascalCase to dash-case
1381
+ *
1382
+ * @param str the string to convert
1383
+ * @returns a converted string
1384
+ */
1385
+ const toDashCase = (str) => str.replace(/([A-Z0-9])/g, (match) => ` ${match[0]}`).trim().split(" ").join("-").toLowerCase();
1386
+ /**
1376
1387
  * Check whether a value is a 'complex type', defined here as an object or a
1377
1388
  * function.
1378
1389
  *
@@ -1416,7 +1427,7 @@ const emitEvent = (elm, name, opts) => {
1416
1427
  elm.dispatchEvent(ev);
1417
1428
  return ev;
1418
1429
  };
1419
- const getRegistry = () => customElements;
1430
+ const getRegistry = () => globalThis.customElements;
1420
1431
  /**
1421
1432
  * @param elm a defined component host
1422
1433
  * @returns the registry the host's class was defined in, else the active registry
@@ -3389,6 +3400,11 @@ const addSlottedNodes = (slottedNodes, slotNodeId, slotName, slotNode, hostId) =
3389
3400
  * @returns the first corresponding node of the type
3390
3401
  */
3391
3402
  const findCorrespondingNode = (node, type) => {
3403
+ if (type === NODE_TYPE.TextNode) {
3404
+ const next = node.nextSibling;
3405
+ if (next?.nodeType === NODE_TYPE.TextNode) return next;
3406
+ return node.parentNode.insertBefore(node.ownerDocument.createTextNode(""), next);
3407
+ }
3392
3408
  let sibling = node;
3393
3409
  do
3394
3410
  sibling = sibling.nextSibling;
@@ -5029,7 +5045,10 @@ const insertVNodeAnnotations = (doc, hostElm, vnode, docData, cmpData) => {
5029
5045
  if (vnode != null) {
5030
5046
  const hostId = ++docData.hostIds;
5031
5047
  hostElm.setAttribute(HYDRATE_ID, hostId);
5032
- if (hostElm["s-cr"] != null) hostElm["s-cr"].nodeValue = `r.${hostId}`;
5048
+ if (hostElm["s-cr"] != null) {
5049
+ if (hostElm.shadowRoot) hostElm["s-cr"].remove();
5050
+ else hostElm["s-cr"].nodeValue = `r.${hostId}`;
5051
+ }
5033
5052
  if (vnode.$children$ != null) {
5034
5053
  const depth = 0;
5035
5054
  vnode.$children$.forEach((vnodeChild, index) => {
@@ -5091,7 +5110,14 @@ const insertChildVNodeAnnotations = (doc, vnodeChild, cmpData, hostId, depth, in
5091
5110
  };
5092
5111
  //#endregion
5093
5112
  //#region src/server/platform/proxy-host-element.ts
5094
- function proxyHostElement(elm, cstr) {
5113
+ /**
5114
+ * Set up a component's host element on the server: its props (from attributes, values set on
5115
+ * the element before it was defined, and `ssrProp()` references), getters/setters and shadow root.
5116
+ * @param elm the host element
5117
+ * @param cstr the component's constructor
5118
+ * @param warn report a problem with the render (to its `diagnostics`)
5119
+ */
5120
+ function proxyHostElement(elm, cstr, warn = () => {}) {
5095
5121
  const cmpMeta = cstr.cmpMeta;
5096
5122
  cmpMeta.$watchers$ = cmpMeta.$watchers$ || cstr.watchers;
5097
5123
  cmpMeta.$deserializers$ = cmpMeta.$deserializers$ || cstr.deserializers;
@@ -5108,7 +5134,9 @@ function proxyHostElement(elm, cstr) {
5108
5134
  Object.entries(cmpMeta.$members$).forEach(([memberName, [memberFlags, metaAttributeName]]) => {
5109
5135
  if (memberFlags & MEMBER_FLAGS.Prop) {
5110
5136
  const attributeName = metaAttributeName || memberName;
5111
- const attrValue = elm.getAttribute(attributeName);
5137
+ let attrValue = elm.getAttribute(attributeName);
5138
+ const ssrProp = takeSsrProp(elm, attributeName, memberName, warn);
5139
+ if (ssrProp) attrValue = null;
5112
5140
  const propValue = elm[memberName];
5113
5141
  let attrPropVal;
5114
5142
  const { get: origGetter, set: origSetter } = Object.getOwnPropertyDescriptor(cstr.prototype, memberName) || {};
@@ -5119,12 +5147,18 @@ function proxyHostElement(elm, cstr) {
5119
5147
  }
5120
5148
  else attrPropVal = parsePropertyValue(attrValue, memberFlags);
5121
5149
  }
5150
+ if (ssrProp?.value !== void 0) attrPropVal = ssrProp.value;
5122
5151
  if (propValue !== void 0) {
5123
5152
  attrPropVal = propValue;
5124
5153
  delete elm[memberName];
5125
5154
  }
5155
+ const setFromOutside = ssrProp?.value !== void 0 || propValue !== void 0;
5156
+ if (setFromOutside && typeof attrPropVal === "object" && attrPropVal !== null && !cmpMeta.$serializers$?.[memberName]) warn(`<${cmpMeta.$tagName$}>'s "${memberName}" prop was given an object on the server, but has no @PropSerialize(), so the browser won't get it: the component will first render there without it. To keep it, use @Prop({ serialize: 'json' }), or a @PropSerialize() / @AttrDeserialize() pair for other formats.`);
5126
5157
  const userSetter = !cstr.isProxied ? origSetter : void 0;
5127
- if (attrPropVal !== void 0 && !userSetter) hostRef?.$instanceValues$?.set(memberName, attrPropVal);
5158
+ if (attrPropVal !== void 0 && !userSetter) {
5159
+ hostRef?.$instanceValues$?.set(memberName, attrPropVal);
5160
+ if (setFromOutside && cmpMeta.$serializers$?.[memberName]) applySerializers(hostRef, cmpMeta, memberName, attrPropVal, void 0);
5161
+ }
5128
5162
  const getterSetterDescriptor = {
5129
5163
  get: function() {
5130
5164
  return getValue(this, memberName);
@@ -5172,6 +5206,34 @@ function componentOnReady() {
5172
5206
  return getHostRef(this)?.$onReadyPromise$;
5173
5207
  }
5174
5208
  function forceUpdate$1() {}
5209
+ /**
5210
+ * Read and remove an `ssrProp()` reference: a value a framework template passed to this prop,
5211
+ * which reached the server as an attribute pointing into the `ssrProp()` registry. Templates bind
5212
+ * it under the prop name, which HTML lower-cases (`chartData` -> `chartdata`), or dash-cased
5213
+ * (`chart-data`); complex props usually have no attribute name of their own.
5214
+ * @param elm the component's host element
5215
+ * @param attributeName the prop's attribute name
5216
+ * @param memberName the prop's name
5217
+ * @param warn report a problem with the render
5218
+ * @returns `undefined` if there's no reference, otherwise its value (`undefined` if it's gone)
5219
+ */
5220
+ const takeSsrProp = (elm, attributeName, memberName, warn) => {
5221
+ for (const name of /* @__PURE__ */ new Set([
5222
+ attributeName,
5223
+ memberName,
5224
+ toDashCase(memberName)
5225
+ ])) {
5226
+ const attr = elm.getAttribute(name);
5227
+ if (!attr?.startsWith("__stencil_ssr_ref:")) continue;
5228
+ elm.removeAttribute(name);
5229
+ const id = attr.slice(18);
5230
+ const registry = (typeof $stencilNativeGlobal !== "undefined" ? $stencilNativeGlobal : globalThis)[Symbol.for(SSR_PROPS_REGISTRY_KEY)];
5231
+ const entry = registry?.get(id);
5232
+ registry?.delete(id);
5233
+ if (!entry) warn(`<${elm.tagName.toLowerCase()}>'s "${memberName}" was passed with ssrProp(), but its value isn't available here: it's only available to renderToString() in the same process, for a short time after the template ran.`);
5234
+ return { value: entry?.value };
5235
+ }
5236
+ };
5175
5237
  //#endregion
5176
5238
  //#region src/server/platform/ssr-app.ts
5177
5239
  /**
@@ -5253,7 +5315,13 @@ function ssrApp(win, opts, results, afterSsr, resolve, abortController) {
5253
5315
  createdElements.add(elm);
5254
5316
  elm.connectedCallback = patchedConnectedCallback;
5255
5317
  registerHost(elm, Cstr.cmpMeta);
5256
- proxyHostElement(elm, Cstr);
5318
+ proxyHostElement(elm, Cstr, (messageText) => results.diagnostics.push({
5319
+ level: "warn",
5320
+ type: "hydrate",
5321
+ header: "SSR Warning",
5322
+ messageText,
5323
+ lines: []
5324
+ }));
5257
5325
  }
5258
5326
  }
5259
5327
  }
@@ -6772,7 +6772,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
6772
6772
  value: mod,
6773
6773
  enumerable: true
6774
6774
  }) : target, mod));
6775
- const HYDRATE_ID = "s-id";
6776
6775
  const XML_NS = "http://www.w3.org/XML/1998/namespace";
6777
6776
  const XMLNS_NS = "http://www.w3.org/2000/xmlns/";
6778
6777
  /**
@@ -7767,19 +7766,7 @@ function* streamToHtml(node, opts, output) {
7767
7766
  const isWithinWhitespaceSensitiveNode = opts.newLines || (opts.indentSpaces ?? 0) > 0 ? isWithinWhitespaceSensitive(node) : false;
7768
7767
  if (!isWithinWhitespaceSensitiveNode && (opts.indentSpaces ?? 0) > 0 && ignoreTag === false) output.indent = output.indent + (opts.indentSpaces ?? 0);
7769
7768
  for (let i = 0; i < childNodeLength; i++) {
7770
- /**
7771
- * In cases where a user would pass in a declarative shadow dom of a
7772
- * Stencil component, we want to skip over the template tag as we
7773
- * will be parsing the shadow root of the component again.
7774
- *
7775
- * We know it is a hydrated Stencil component by checking if the `HYDRATE_ID`
7776
- * is set on the node.
7777
- */
7778
- const sId = node.attributes.getNamedItem(HYDRATE_ID);
7779
- if (childNodes[i].nodeName.toLowerCase() === "template" && sId) {
7780
- yield `\n${" ".repeat(output.indent)}<!--r.${sId.value}-->`;
7781
- continue;
7782
- }
7769
+ if (childNodes[i].nodeName.toLowerCase() === "template" && node.attributes.getNamedItem("s-id")) continue;
7783
7770
  yield* streamToHtml(childNodes[i], opts, output);
7784
7771
  }
7785
7772
  if (ignoreTag === false) {
@@ -1,2 +1,2 @@
1
- import { n as setupNodeProcess, r as createNodeLogger, t as createNodeSys } from "../../node-eg7pofz5.mjs";
1
+ import { n as setupNodeProcess, r as createNodeLogger, t as createNodeSys } from "../../node-DwwBX_GL.mjs";
2
2
  export { createNodeLogger, createNodeSys, setupNodeProcess };
@@ -1,5 +1,5 @@
1
- import { l as createWorkerMessageHandler } from "../../compiler-BpfMxpfR.mjs";
2
- import { t as createNodeSys } from "../../node-eg7pofz5.mjs";
1
+ import { l as createWorkerMessageHandler } from "../../compiler-DHNkXDvK.mjs";
2
+ import { t as createNodeSys } from "../../node-DwwBX_GL.mjs";
3
3
  //#region src/sys/node/node-worker-thread.ts
4
4
  /**
5
5
  * Initialize a worker thread, setting up various machinery for managing
@@ -33,7 +33,7 @@ import "@rollup/pluginutils";
33
33
  import { createHash } from "crypto";
34
34
  import { afterAll, vi } from "vitest";
35
35
  //#region src/version.ts
36
- const version = "5.0.0-beta.35";
36
+ const version = "5.0.0-beta.36";
37
37
  const MEMBER_FLAGS = {
38
38
  String: 1,
39
39
  Number: 2,
@@ -1184,6 +1184,13 @@ const NODE_TYPE = {
1184
1184
  const HYDRATE_ID = "s-id";
1185
1185
  const HYDRATED_STYLE_ID = "sty-id";
1186
1186
  const HYDRATE_CHILD_ID = "c-id";
1187
+ /**
1188
+ * Starts an attribute value written by the `ssr` output's `ssrProp()` on a server: a reference to
1189
+ * a value it put in the registry below, for the SSR runtime to take out and set as the prop.
1190
+ */
1191
+ const SSR_PROP_REF_PREFIX = "__stencil_ssr_ref:";
1192
+ /** `Symbol.for()` key of the `ssrProp()` registry on the server's real global object. */
1193
+ const SSR_PROPS_REGISTRY_KEY = "stencil.ssrProps";
1187
1194
  const HYDRATED_CSS = "{visibility:hidden}.hydrated{visibility:inherit}";
1188
1195
  const STENCIL_DOC_DATA = "_stencilDocData";
1189
1196
  const DEFAULT_DOC_DATA = {
@@ -1631,7 +1638,9 @@ const patchTextContent = (hostElementPrototype) => {
1631
1638
  Object.defineProperty(hostElementPrototype, "textContent", {
1632
1639
  get: function() {
1633
1640
  let text = "";
1634
- (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => text += node.textContent || "");
1641
+ (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => {
1642
+ if (node.nodeType !== NODE_TYPE.CommentNode) text += node.textContent || "";
1643
+ });
1635
1644
  return text;
1636
1645
  },
1637
1646
  set: function(value) {
@@ -1639,7 +1648,7 @@ const patchTextContent = (hostElementPrototype) => {
1639
1648
  if (node["s-ol"]) node["s-ol"].remove();
1640
1649
  node.remove();
1641
1650
  });
1642
- this.insertAdjacentHTML("beforeend", value);
1651
+ if (value != null && value !== "") this.append(this.ownerDocument.createTextNode(String(value)));
1643
1652
  }
1644
1653
  });
1645
1654
  };
@@ -2171,7 +2180,7 @@ const effect = (fn, options) => getCore().effect(fn, options);
2171
2180
  function signal(value, options) {
2172
2181
  return getCore().signal(value, options);
2173
2182
  }
2174
- const getRegistry = () => customElements;
2183
+ const getRegistry = () => globalThis.customElements;
2175
2184
  /**
2176
2185
  * @param elm a defined component host
2177
2186
  * @returns the registry the host's class was defined in, else the active registry
@@ -4146,6 +4155,11 @@ const addSlottedNodes = (slottedNodes, slotNodeId, slotName, slotNode, hostId) =
4146
4155
  * @returns the first corresponding node of the type
4147
4156
  */
4148
4157
  const findCorrespondingNode = (node, type) => {
4158
+ if (type === NODE_TYPE.TextNode) {
4159
+ const next = node.nextSibling;
4160
+ if (next?.nodeType === NODE_TYPE.TextNode) return next;
4161
+ return node.parentNode.insertBefore(node.ownerDocument.createTextNode(""), next);
4162
+ }
4149
4163
  let sibling = node;
4150
4164
  do
4151
4165
  sibling = sibling.nextSibling;
@@ -5615,7 +5629,10 @@ const insertVNodeAnnotations = (doc, hostElm, vnode, docData, cmpData) => {
5615
5629
  if (vnode != null) {
5616
5630
  const hostId = ++docData.hostIds;
5617
5631
  hostElm.setAttribute(HYDRATE_ID, hostId);
5618
- if (hostElm["s-cr"] != null) hostElm["s-cr"].nodeValue = `r.${hostId}`;
5632
+ if (hostElm["s-cr"] != null) {
5633
+ if (hostElm.shadowRoot) hostElm["s-cr"].remove();
5634
+ else hostElm["s-cr"].nodeValue = `r.${hostId}`;
5635
+ }
5619
5636
  if (vnode.$children$ != null) {
5620
5637
  const depth = 0;
5621
5638
  vnode.$children$.forEach((vnodeChild, index) => {
@@ -5975,6 +5992,7 @@ new RegExp(`^(${[.../* @__PURE__ */ new Set([
5975
5992
  "vm",
5976
5993
  "zlib"
5977
5994
  ])].join("|")})$`);
5995
+ `${JSON.stringify(SSR_PROP_REF_PREFIX)}${JSON.stringify(SSR_PROPS_REGISTRY_KEY)}`;
5978
5996
  promisify(execFile);
5979
5997
  process.platform;
5980
5998
  new Set([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stencil/core",
3
- "version": "5.0.0-beta.35",
3
+ "version": "5.0.0-beta.36",
4
4
  "description": "A Compiler for Web Components and Progressive Web Apps",
5
5
  "keywords": [
6
6
  "components",
@@ -126,9 +126,9 @@
126
126
  "terser": "^5.50.0",
127
127
  "tinyglobby": "^0.2.17",
128
128
  "typescript": ">5.0.0 <7.0.0",
129
- "@stencil/cli": "5.0.0-beta.35",
130
- "@stencil/dev-server": "5.0.0-beta.35",
131
- "@stencil/mock-doc": "5.0.0-beta.35"
129
+ "@stencil/dev-server": "5.0.0-beta.36",
130
+ "@stencil/cli": "5.0.0-beta.36",
131
+ "@stencil/mock-doc": "5.0.0-beta.36"
132
132
  },
133
133
  "devDependencies": {
134
134
  "@ionic/prettier-config": "^4.0.0",