@stencil/core 5.0.0-alpha.1 → 5.0.0-alpha.11

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.
Files changed (50) hide show
  1. package/dist/app-data/index.d.ts +2 -0
  2. package/dist/{runtime/app-data → app-data}/index.js +17 -12
  3. package/dist/{client-B1nuvCd2.mjs → client-aTQ7xHxx.mjs} +2432 -2278
  4. package/dist/compiler/index.d.mts +6 -6
  5. package/dist/compiler/index.mjs +2 -2
  6. package/dist/compiler/utils/index.d.mts +2 -2
  7. package/dist/compiler/utils/index.mjs +3 -3
  8. package/dist/{compiler-LX4_RKKd.mjs → compiler-DCN7Np2A.mjs} +14854 -13500
  9. package/dist/declarations/stencil-public-compiler.d.ts +4374 -2
  10. package/dist/declarations/stencil-public-compiler.js +2 -4
  11. package/dist/declarations/stencil-public-docs.d.ts +504 -1
  12. package/dist/declarations/stencil-public-runtime.d.ts +1982 -2
  13. package/dist/{index-fIuYTL9f.d.mts → index-BvkyxSY6.d.mts} +29 -2
  14. package/dist/{index-D-LlB2nw.d.mts → index-vY35H18z.d.mts} +795 -1188
  15. package/dist/{index-BONzXKJt.d.ts → index-xAkMgLX_.d.ts} +88 -39
  16. package/dist/index.d.mts +1 -1
  17. package/dist/index.mjs +2 -2
  18. package/dist/jsx-runtime.d.mts +18 -0
  19. package/dist/jsx-runtime.mjs +2 -0
  20. package/dist/{node-SxQIOCZE.mjs → node--akYC-sG.mjs} +20 -30
  21. package/dist/regular-expression-CFVJOTUh.mjs +508 -0
  22. package/dist/{runtime-CF9DJtSu.js → runtime/client/lazy.js} +2675 -2493
  23. package/dist/runtime/client/{index.d.ts → runtime.d.ts} +106 -78
  24. package/dist/runtime/client/{index.js → runtime.js} +2545 -2487
  25. package/dist/runtime/index.d.ts +58 -29
  26. package/dist/runtime/index.js +4795 -2
  27. package/dist/runtime/server/index.d.mts +103 -70
  28. package/dist/runtime/server/index.mjs +2545 -2350
  29. package/dist/runtime/server/runner.d.mts +44 -48
  30. package/dist/runtime/server/runner.mjs +347 -751
  31. package/dist/signals/index.d.ts +47 -0
  32. package/dist/signals/index.js +199 -0
  33. package/dist/sys/node/index.d.mts +1 -1
  34. package/dist/sys/node/index.mjs +1 -1
  35. package/dist/sys/node/worker.mjs +2 -2
  36. package/dist/testing/index.d.mts +97 -3
  37. package/dist/testing/index.mjs +367 -59
  38. package/dist/{validation-CaCgjw-f.mjs → validation-ByxKj8bC.mjs} +116 -99
  39. package/package.json +47 -38
  40. package/dist/index-CHjZtib0.d.ts +0 -30
  41. package/dist/jsx-runtime-DBzBJLKk.d.ts +0 -28
  42. package/dist/jsx-runtime.d.ts +0 -2
  43. package/dist/jsx-runtime.js +0 -2
  44. package/dist/runtime/app-data/index.d.ts +0 -2
  45. package/dist/serialize-BkYHk7Mi.mjs +0 -766
  46. package/dist/stencil-public-compiler-C_X1iolo.d.ts +0 -4455
  47. package/dist/stencil-public-runtime-DlV8o7-z.d.ts +0 -1845
  48. /package/dist/{runtime/app-globals → app-globals}/index.d.ts +0 -0
  49. /package/dist/{runtime/app-globals → app-globals}/index.js +0 -0
  50. /package/dist/{chunk-CjcI7cDX.mjs → chunk-z9aeyW2b.mjs} +0 -0
@@ -1,9 +1,11 @@
1
- import { B as Env, T as reWireGetterSetter, _ as h, a as Mixin, c as forceUpdate, d as createEvent, f as getElement, g as Host, l as getRenderingRef, o as Fragment, p as getMode, s as bootstrapLazy, t as insertVdomAnnotations, u as renderVdom, v as getAssetPath, y as setAssetPath, z as BUILD } from "../client-B1nuvCd2.mjs";
2
- import { D as CMP_FLAGS, G as EVENT_FLAGS, y as noop } from "../serialize-BkYHk7Mi.mjs";
3
- import { _ as getBuildFeatures, c as createWorkerContext, h as BuildContext, i as createSystem, m as Cache, p as createInMemoryFs } from "../compiler-LX4_RKKd.mjs";
4
- import { St as formatLazyBundleRuntimeMeta } from "../validation-CaCgjw-f.mjs";
5
- import { o as buildEvents } from "../node-SxQIOCZE.mjs";
1
+ import { A as HYDRATE_ID, C as setAssetPath, D as DEFAULT_DOC_DATA, F as reWireGetterSetter, M as STENCIL_DOC_DATA, P as getHostRef$1, S as getAssetPath, X as Env, Y as BUILD, _ as insertBefore, b as getElement, c as Fragment, g as getRenderingRef, h as forceUpdate, j as NODE_TYPE, k as HYDRATE_CHILD_ID, l as bootstrapLazy, m as h, p as Host, s as Mixin, u as getMode, v as renderVdom, y as createEvent } from "../client-aTQ7xHxx.mjs";
2
+ import { L as EVENT_FLAGS, h as noop, w as CMP_FLAGS } from "../regular-expression-CFVJOTUh.mjs";
3
+ import { _ as getBuildFeatures, c as createWorkerContext, g as BuildContext, h as Cache, i as createSystem, o as loadConfig, p as createInMemoryFs, s as createCompiler } from "../compiler-DCN7Np2A.mjs";
4
+ import { wt as formatLazyBundleRuntimeMeta } from "../validation-ByxKj8bC.mjs";
5
+ import { o as buildEvents } from "../node--akYC-sG.mjs";
6
+ import fs from "node:fs";
6
7
  import path from "node:path";
8
+ import { fileURLToPath } from "node:url";
7
9
  import path$1 from "path";
8
10
  import { MockWindow, setupGlobal } from "@stencil/mock-doc";
9
11
  import { createHash } from "crypto";
@@ -192,12 +194,15 @@ const mockComponentMeta = (overrides = {}) => ({
192
194
  hasListenerTarget: false,
193
195
  hasListenerTargetBody: false,
194
196
  hasListenerTargetDocument: false,
195
- hasListenerTargetParent: false,
196
197
  hasListenerTargetWindow: false,
197
198
  hasMember: false,
198
199
  hasMethod: false,
199
200
  hasMode: false,
200
201
  hasModernPropertyDecls: false,
202
+ hasPatchAll: false,
203
+ hasPatchChildren: false,
204
+ hasPatchClone: false,
205
+ hasPatchInsert: false,
201
206
  hasProp: false,
202
207
  hasPropBoolean: false,
203
208
  hasPropMutable: false,
@@ -220,6 +225,7 @@ const mockComponentMeta = (overrides = {}) => ({
220
225
  hasVdomStyle: false,
221
226
  hasVdomText: false,
222
227
  hasVdomXlink: false,
228
+ hasSignalsImport: false,
223
229
  hasWatchCallback: false,
224
230
  htmlAttrNames: [],
225
231
  htmlParts: [],
@@ -231,16 +237,19 @@ const mockComponentMeta = (overrides = {}) => ({
231
237
  jsFilePath: "/some/stubbed/path/my-component.js",
232
238
  listeners: [],
233
239
  methods: [],
240
+ patches: null,
234
241
  potentialCmpRefs: [],
235
242
  properties: [],
236
243
  serializers: [],
237
244
  shadowDelegatesFocus: false,
245
+ shadowMode: null,
238
246
  slotAssignment: null,
239
247
  sourceFilePath: "/some/stubbed/path/my-component.tsx",
240
248
  sourceMapPath: "/some/stubbed/path/my-component.js.map",
241
249
  states: [],
242
250
  styleDocs: [],
243
251
  styles: [],
252
+ globalStyles: [],
244
253
  tagName: "stub-cmp",
245
254
  virtualProperties: [],
246
255
  watchers: [],
@@ -258,14 +267,11 @@ function mockValidatedConfig(overrides = {}) {
258
267
  const rootDir = path.resolve("/");
259
268
  return {
260
269
  ...baseConfig,
261
- buildEs5: false,
262
270
  cacheDir: ".stencil",
263
271
  devMode: true,
264
272
  devServer: {},
265
- extras: {},
273
+ compat: {},
266
274
  fsNamespace: "testing",
267
- hashFileNames: false,
268
- hashedFileNameLength: 8,
269
275
  hydratedFlag: null,
270
276
  logLevel: "info",
271
277
  logger: mockLogger(),
@@ -279,14 +285,10 @@ function mockValidatedConfig(overrides = {}) {
279
285
  srcDir: "/src",
280
286
  srcIndexHtml: "src/index.html",
281
287
  suppressReservedPublicNameWarnings: false,
288
+ suppressReservedEventNameWarnings: false,
282
289
  sys: createTestingSystem(),
283
- testing: {},
284
290
  transformAliasedImportPaths: true,
285
- rollupConfig: {
286
- inputOptions: {},
287
- outputOptions: {}
288
- },
289
- validatePrimaryPackageOutputTarget: false,
291
+ rolldownConfig: {},
290
292
  ...overrides
291
293
  };
292
294
  }
@@ -305,30 +307,27 @@ function mockConfig(overrides = {}) {
305
307
  return {
306
308
  _isTesting: true,
307
309
  buildAppCore: false,
308
- buildDist: true,
309
- buildEs5: false,
310
310
  bundles: null,
311
311
  devMode: true,
312
312
  enableCache: false,
313
- extras: {},
313
+ compat: {},
314
314
  globalScript: null,
315
- hashFileNames: false,
316
315
  logger: new TestingLogger(),
317
316
  maxConcurrentWorkers: 0,
318
317
  minifyCss: false,
319
318
  minifyJs: false,
320
319
  namespace: "Testing",
321
- nodeResolve: { customResolveOptions: {} },
320
+ nodeResolve: {},
322
321
  outputTargets: null,
323
- rollupPlugins: {
322
+ rolldownPlugins: {
324
323
  before: [],
325
324
  after: []
326
325
  },
327
326
  rootDir,
328
327
  sourceMap: true,
329
328
  suppressReservedPublicNameWarnings: false,
329
+ suppressReservedEventNameWarnings: false,
330
330
  sys,
331
- testing: null,
332
331
  validateTypes: false,
333
332
  ...overrides
334
333
  };
@@ -347,7 +346,6 @@ const mockLoadConfigInit = (overrides) => {
347
346
  return {
348
347
  config: {},
349
348
  configPath: void 0,
350
- initTsConfig: true,
351
349
  logger: void 0,
352
350
  sys: void 0,
353
351
  ...overrides
@@ -365,7 +363,7 @@ function mockCompilerCtx(config) {
365
363
  activeFilesUpdated: [],
366
364
  addWatchDir: noop,
367
365
  addWatchFile: noop,
368
- cachedGlobalStyle: null,
366
+ globalStyleCache: /* @__PURE__ */ new Map(),
369
367
  changedFiles: /* @__PURE__ */ new Set(),
370
368
  changedModules: /* @__PURE__ */ new Set(),
371
369
  collections: [],
@@ -381,12 +379,15 @@ function mockCompilerCtx(config) {
381
379
  nodeMap: /* @__PURE__ */ new WeakMap(),
382
380
  reset: noop,
383
381
  resolvedCollections: /* @__PURE__ */ new Set(),
384
- rollupCache: /* @__PURE__ */ new Map(),
385
- rollupCacheHydrate: null,
386
- rollupCacheLazy: null,
387
- rollupCacheNative: null,
382
+ rolldownCache: /* @__PURE__ */ new Map(),
383
+ rolldownCacheSsr: null,
384
+ rolldownCacheLazy: null,
385
+ rolldownCacheNative: null,
386
+ transpileCache: /* @__PURE__ */ new Map(),
387
+ prevStylesMap: /* @__PURE__ */ new Map(),
388
388
  styleModeNames: /* @__PURE__ */ new Set(),
389
- worker: createWorkerContext(innerConfig.sys)
389
+ worker: createWorkerContext(innerConfig.sys),
390
+ cssTransformCache: /* @__PURE__ */ new Map()
390
391
  };
391
392
  Object.defineProperty(compilerCtx, "fs", { get() {
392
393
  if (this._fs == null) this._fs = createInMemoryFs(innerConfig.sys);
@@ -476,9 +477,171 @@ const mockModule = (mod = {}) => ({
476
477
  hasVdomStyle: false,
477
478
  hasVdomText: false,
478
479
  hasVdomXlink: false,
480
+ hasSignalsImport: false,
479
481
  ...mod
480
482
  });
481
483
  //#endregion
484
+ //#region src/testing/create-test-compiler.ts
485
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
486
+ const TESTING_TSCONFIG = path.resolve(__dirname, "fixtures/tsconfig.testing.json");
487
+ /**
488
+ * Builds a patched sys that falls through to real disk for TypeScript lib files.
489
+ *
490
+ * @returns A compiler system instance with patched readFileSync, readFile, accessSync, and statSync methods
491
+ */
492
+ const createPatchedSys = () => {
493
+ const sys = mockCompilerSystem();
494
+ const originalReadFileSync = sys.readFileSync.bind(sys);
495
+ sys.readFileSync = (p) => {
496
+ const mem = originalReadFileSync(p);
497
+ if (mem !== void 0) return mem;
498
+ try {
499
+ return fs.readFileSync(p, "utf-8");
500
+ } catch {
501
+ return;
502
+ }
503
+ };
504
+ const originalReadFile = sys.readFile.bind(sys);
505
+ sys.readFile = async (p) => {
506
+ const mem = await originalReadFile(p);
507
+ if (mem !== void 0) return mem;
508
+ try {
509
+ return fs.readFileSync(p, "utf-8");
510
+ } catch {
511
+ return;
512
+ }
513
+ };
514
+ const originalAccessSync = sys.accessSync.bind(sys);
515
+ sys.accessSync = (p) => {
516
+ if (originalAccessSync(p)) return true;
517
+ try {
518
+ fs.accessSync(p);
519
+ return true;
520
+ } catch {
521
+ return false;
522
+ }
523
+ };
524
+ const originalStatSync = sys.statSync.bind(sys);
525
+ sys.statSync = (p) => {
526
+ const mem = originalStatSync(p);
527
+ if (!mem.error) return mem;
528
+ try {
529
+ const s = fs.statSync(p);
530
+ return {
531
+ isDirectory: s.isDirectory(),
532
+ isFile: s.isFile(),
533
+ isSymbolicLink: s.isSymbolicLink(),
534
+ size: s.size,
535
+ error: null
536
+ };
537
+ } catch {
538
+ return mem;
539
+ }
540
+ };
541
+ sys.getCompilerExecutingPath = () => path.resolve(__dirname, "../../dist/compiler/index.mjs");
542
+ return sys;
543
+ };
544
+ /**
545
+ * Runs the expensive one-time setup for a test compiler suite: patching the
546
+ * sys, reading and validating the tsconfig. Use this in a `beforeAll` block
547
+ * when a describe block contains multiple tests that each need a fresh
548
+ * compiler, to avoid repeating `loadConfig` on every test.
549
+ *
550
+ * @param options - Configuration options for preparing the test compiler
551
+ * @returns A {@link PreparedTestCompiler} that can be passed to {@link createTestCompiler}
552
+ *
553
+ * @example
554
+ * ```ts
555
+ * let setup: PreparedTestCompiler;
556
+ * beforeAll(async () => { setup = await prepareTestCompiler(); });
557
+ * beforeEach(async () => {
558
+ * const { compiler } = await createTestCompiler({ setup });
559
+ * });
560
+ * ```
561
+ */
562
+ const prepareTestCompiler = async (options = {}) => {
563
+ const sys = createPatchedSys();
564
+ const tsconfigPath = options.tsconfig ?? TESTING_TSCONFIG;
565
+ const { config: validatedConfig } = await loadConfig({
566
+ sys,
567
+ config: {
568
+ devMode: true,
569
+ sourceMap: false,
570
+ enableCache: false,
571
+ minifyJs: false,
572
+ minifyCss: false,
573
+ namespace: "Testing",
574
+ tsconfig: tsconfigPath,
575
+ ...options.config
576
+ }
577
+ });
578
+ return {
579
+ _validatedConfig: validatedConfig,
580
+ _tsconfigPath: tsconfigPath
581
+ };
582
+ };
583
+ /**
584
+ * Creates a test compiler instance with a hybrid filesystem (reads from disk, writes to memory).
585
+ * This utility handles the common setup pattern for compiler tests.
586
+ *
587
+ * When multiple tests in the same suite need independent compiler instances,
588
+ * pass a {@link PreparedTestCompiler} from {@link prepareTestCompiler} as
589
+ * `options.setup` to skip the expensive `loadConfig` step on each test.
590
+ *
591
+ * @param options - Configuration options for the test compiler
592
+ * @returns An object with the compiler, validated config, and system instance
593
+ *
594
+ * @example
595
+ * ```ts
596
+ * const { compiler, config } = await createTestCompiler({
597
+ * config: { minifyCss: true }
598
+ * });
599
+ * await compiler.fs.writeFile('/src/index.html', '<cmp-a></cmp-a>');
600
+ * const result = await compiler.build();
601
+ * ```
602
+ */
603
+ const createTestCompiler = async (options = {}) => {
604
+ let validatedConfig;
605
+ let tsconfigPath;
606
+ if (options.setup) {
607
+ const freshSys = createPatchedSys();
608
+ validatedConfig = {
609
+ ...options.setup._validatedConfig,
610
+ sys: freshSys
611
+ };
612
+ tsconfigPath = options.setup._tsconfigPath;
613
+ } else {
614
+ const sys = createPatchedSys();
615
+ tsconfigPath = options.tsconfig ?? TESTING_TSCONFIG;
616
+ const { config } = await loadConfig({
617
+ sys,
618
+ config: {
619
+ devMode: true,
620
+ sourceMap: false,
621
+ enableCache: false,
622
+ minifyJs: false,
623
+ minifyCss: false,
624
+ namespace: "Testing",
625
+ tsconfig: tsconfigPath,
626
+ ...options.config
627
+ }
628
+ });
629
+ validatedConfig = config;
630
+ }
631
+ const compiler = await createCompiler(validatedConfig);
632
+ const tsconfigObj = JSON.parse(fs.readFileSync(tsconfigPath, "utf-8"));
633
+ await compiler.fs.writeFile(tsconfigPath, JSON.stringify({
634
+ ...tsconfigObj,
635
+ include: [validatedConfig.srcDir]
636
+ }));
637
+ await compiler.fs.writeFile(path.join(validatedConfig.srcDir, "components.d.ts"), "");
638
+ return {
639
+ compiler,
640
+ config: validatedConfig,
641
+ sys: validatedConfig.sys
642
+ };
643
+ };
644
+ //#endregion
482
645
  //#region src/testing/platform/testing-constants.ts
483
646
  const styles = /* @__PURE__ */ new Map();
484
647
  const modeResolutionChain = [];
@@ -514,7 +677,7 @@ const Build = {
514
677
  * @returns the corresponding Stencil reference data structure, or undefined if one cannot be found
515
678
  */
516
679
  const getHostRef = (elm) => {
517
- if (elm.__stencil__getHostRef) return elm.__stencil__getHostRef();
680
+ if (elm.__s_ghr) return elm.__s_ghr();
518
681
  };
519
682
  /**
520
683
  * Add the provided `hostRef` instance to the global {@link hostRefs} map, using the provided `lazyInstance` as a key.
@@ -535,7 +698,7 @@ const registerInstance = (lazyInstance, hostRef) => {
535
698
  });
536
699
  hostRef = getHostRef(elm);
537
700
  }
538
- lazyInstance.__stencil__getHostRef = () => hostRef;
701
+ lazyInstance.__s_ghr = () => hostRef;
539
702
  hostRef.$lazyInstance$ = lazyInstance;
540
703
  if (hostRef.$cmpMeta$?.$flags$ & CMP_FLAGS.hasModernPropertyDecls && (BUILD.state || BUILD.prop)) reWireGetterSetter(lazyInstance, hostRef);
541
704
  const Cstr = lazyInstance.constructor;
@@ -586,7 +749,7 @@ const registerHost = (elm, cmpMeta) => {
586
749
  hostRef.$onReadyPromise$ = new Promise((r) => hostRef.$onReadyResolve$ = r);
587
750
  elm["s-p"] = [];
588
751
  elm["s-rc"] = [];
589
- elm.__stencil__getHostRef = () => hostRef;
752
+ elm.__s_ghr = () => hostRef;
590
753
  };
591
754
  const setErrorHandler = (handler) => handler;
592
755
  //#endregion
@@ -726,6 +889,8 @@ function flushLoadModule(bundleId) {
726
889
  const isVitestEnvironment = typeof process !== "undefined" && process.env?.VITEST;
727
890
  const existingWindow = typeof globalThis !== "undefined" && globalThis.window;
728
891
  const win = isVitestEnvironment && existingWindow ? existingWindow : setupGlobal(global);
892
+ //#endregion
893
+ //#region src/testing/platform/testing-platform.ts
729
894
  const plt = {
730
895
  $flags$: 0,
731
896
  $resourcesUrl$: "",
@@ -736,14 +901,6 @@ const plt = {
736
901
  ce: (eventName, opts) => new win.CustomEvent(eventName, opts)
737
902
  };
738
903
  /**
739
- * Helper function to programmatically set shadow DOM support in testing scenarios.
740
- *
741
- * This function modifies the global {@link supportsShadow} variable.
742
- *
743
- * @param supports `true` if shadow DOM is supported, `false` otherwise
744
- */
745
- const setSupportsShadowDom = (supports) => {};
746
- /**
747
904
  * Resets global testing variables and collections, so that a new set of tests can be started with a "clean slate".
748
905
  *
749
906
  * It is expected that this function be called between spec tests, and should be automatically configured by Stencil to
@@ -807,6 +964,161 @@ function registerModule(bundleId, Cstr) {
807
964
  moduleLoaded.set(bundleId, Cstr);
808
965
  }
809
966
  //#endregion
967
+ //#region src/runtime/vdom/vdom-annotations.ts
968
+ /**
969
+ * Updates the DOM generated on the server with annotations such as node attributes and
970
+ * comment nodes to facilitate future client-side hydration. These annotations are used for things
971
+ * like moving elements back to their original hosts if using Shadow DOM on the client, and for quickly
972
+ * reconstructing the vNode representations of the DOM.
973
+ *
974
+ * @param doc The DOM generated by the server.
975
+ * @param staticComponents Any components that should be considered static and do not need client-side hydration.
976
+ */
977
+ const insertVdomAnnotations = (doc, staticComponents) => {
978
+ if (doc != null) {
979
+ /**
980
+ * Initiated `docData` object from the document if it exists to ensure we
981
+ * maintain the same `docData` object across multiple hydration hydration runs.
982
+ */
983
+ const docData = "_stencilDocData" in doc ? doc[STENCIL_DOC_DATA] : { ...DEFAULT_DOC_DATA };
984
+ docData.staticComponents = new Set(staticComponents);
985
+ const orgLocationNodes = [];
986
+ parseVNodeAnnotations(doc, doc.body, docData, orgLocationNodes);
987
+ orgLocationNodes.forEach((orgLocationNode) => {
988
+ if (orgLocationNode != null && orgLocationNode["s-nr"]) {
989
+ const nodeRef = orgLocationNode["s-nr"];
990
+ let hostId = nodeRef["s-host-id"];
991
+ let nodeId = nodeRef["s-node-id"];
992
+ let childId = `${hostId}.${nodeId}`;
993
+ if (hostId == null) {
994
+ hostId = 0;
995
+ docData.rootLevelIds++;
996
+ nodeId = docData.rootLevelIds;
997
+ childId = `${hostId}.${nodeId}`;
998
+ if (nodeRef.nodeType === NODE_TYPE.ElementNode) {
999
+ nodeRef.setAttribute(HYDRATE_CHILD_ID, childId);
1000
+ if (typeof nodeRef["s-sn"] === "string" && !nodeRef.getAttribute("slot")) nodeRef.setAttribute("s-sn", nodeRef["s-sn"]);
1001
+ } else if (nodeRef.nodeType === NODE_TYPE.TextNode) {
1002
+ if (hostId === 0) {
1003
+ if (nodeRef.nodeValue?.trim() === "") {
1004
+ orgLocationNode.remove();
1005
+ return;
1006
+ }
1007
+ }
1008
+ const commentBeforeTextNode = doc.createComment(childId);
1009
+ commentBeforeTextNode.nodeValue = `t.${childId}`;
1010
+ insertBefore(nodeRef.parentNode, commentBeforeTextNode, nodeRef);
1011
+ } else if (nodeRef.nodeType === NODE_TYPE.CommentNode) {
1012
+ const commentBeforeTextNode = doc.createComment(childId);
1013
+ commentBeforeTextNode.nodeValue = `c.${childId}`;
1014
+ nodeRef.parentNode.insertBefore(commentBeforeTextNode, nodeRef);
1015
+ }
1016
+ }
1017
+ let orgLocationNodeId = `o.${childId}`;
1018
+ const orgLocationParentNode = orgLocationNode.parentElement;
1019
+ if (orgLocationParentNode) {
1020
+ if (orgLocationParentNode["s-en"] === "") orgLocationNodeId += `.`;
1021
+ else if (orgLocationParentNode["s-en"] === "c") orgLocationNodeId += `.c`;
1022
+ }
1023
+ orgLocationNode.nodeValue = orgLocationNodeId;
1024
+ }
1025
+ });
1026
+ }
1027
+ };
1028
+ /**
1029
+ * Recursively parses a node generated by the server and its children to set host and child id
1030
+ * attributes read during client-side hydration. This function also tracks whether each node is
1031
+ * an original location reference node meaning that a node has been moved via slot relocation.
1032
+ *
1033
+ * @param doc The DOM generated by the server.
1034
+ * @param node The node to parse.
1035
+ * @param docData An object containing metadata about the document.
1036
+ * @param orgLocationNodes An array of nodes that have been moved via slot relocation.
1037
+ */
1038
+ const parseVNodeAnnotations = (doc, node, docData, orgLocationNodes) => {
1039
+ if (node == null) return;
1040
+ if (node["s-nr"] != null) orgLocationNodes.push(node);
1041
+ if (node.nodeType === NODE_TYPE.ElementNode) [...Array.from(node.childNodes), ...Array.from(node.shadowRoot?.childNodes || [])].forEach((childNode) => {
1042
+ const hostRef = getHostRef$1(childNode);
1043
+ if (hostRef != null && !docData.staticComponents.has(childNode.nodeName.toLowerCase())) insertVNodeAnnotations(doc, childNode, hostRef.$vnode$, docData, { nodeIds: 0 });
1044
+ parseVNodeAnnotations(doc, childNode, docData, orgLocationNodes);
1045
+ });
1046
+ };
1047
+ /**
1048
+ * Insert attribute annotations on an element for its host ID and, potentially, its child ID.
1049
+ * Also makes calls to insert annotations on the element's children, keeping track of the depth of
1050
+ * the component tree.
1051
+ *
1052
+ * @param doc The DOM generated by the server.
1053
+ * @param hostElm The element to insert annotations for.
1054
+ * @param vnode The vNode representation of the element.
1055
+ * @param docData An object containing metadata about the document.
1056
+ * @param cmpData An object containing metadata about the component.
1057
+ */
1058
+ const insertVNodeAnnotations = (doc, hostElm, vnode, docData, cmpData) => {
1059
+ if (vnode != null) {
1060
+ const hostId = ++docData.hostIds;
1061
+ hostElm.setAttribute(HYDRATE_ID, hostId);
1062
+ if (hostElm["s-cr"] != null) hostElm["s-cr"].nodeValue = `r.${hostId}`;
1063
+ if (vnode.$children$ != null) {
1064
+ const depth = 0;
1065
+ vnode.$children$.forEach((vnodeChild, index) => {
1066
+ insertChildVNodeAnnotations(doc, vnodeChild, cmpData, hostId, depth, index);
1067
+ });
1068
+ }
1069
+ if (hostElm && vnode && vnode.$elm$ && !hostElm.hasAttribute("c-id")) {
1070
+ const parent = hostElm.parentElement;
1071
+ if (parent && parent.childNodes) {
1072
+ const parentChildNodes = Array.from(parent.childNodes);
1073
+ const comment = parentChildNodes.find((node) => node.nodeType === NODE_TYPE.CommentNode && node["s-sr"]);
1074
+ if (comment) {
1075
+ const index = parentChildNodes.indexOf(hostElm) - 1;
1076
+ vnode.$elm$.setAttribute(HYDRATE_CHILD_ID, `${comment["s-host-id"]}.${comment["s-node-id"]}.0.${index}`);
1077
+ }
1078
+ }
1079
+ }
1080
+ }
1081
+ };
1082
+ /**
1083
+ * Recursively analyzes the type of a child vNode and inserts annotations on the vNodes's element based on its type.
1084
+ * Element nodes receive a child ID attribute, text nodes have a comment with the child ID inserted before them,
1085
+ * and comment nodes representing a slot have their node value set to a slot node ID containing the child ID.
1086
+ *
1087
+ * @param doc The DOM generated by the server.
1088
+ * @param vnodeChild The vNode to insert annotations for.
1089
+ * @param cmpData An object containing metadata about the component.
1090
+ * @param hostId The host ID of this element's parent.
1091
+ * @param depth How deep this element sits in the component tree relative to its parent.
1092
+ * @param index The index of this element in its parent's children array.
1093
+ */
1094
+ const insertChildVNodeAnnotations = (doc, vnodeChild, cmpData, hostId, depth, index) => {
1095
+ const childElm = vnodeChild.$elm$;
1096
+ if (childElm == null) return;
1097
+ const nodeId = cmpData.nodeIds++;
1098
+ const childId = `${hostId}.${nodeId}.${depth}.${index}`;
1099
+ childElm["s-host-id"] = hostId;
1100
+ childElm["s-node-id"] = nodeId;
1101
+ if (childElm.nodeType === NODE_TYPE.ElementNode) {
1102
+ childElm.setAttribute(HYDRATE_CHILD_ID, childId);
1103
+ if (typeof childElm["s-sn"] === "string" && !childElm.getAttribute("slot")) childElm.setAttribute("s-sn", childElm["s-sn"]);
1104
+ } else if (childElm.nodeType === NODE_TYPE.TextNode) {
1105
+ const parentNode = childElm.parentNode;
1106
+ const nodeName = parentNode?.nodeName;
1107
+ if (nodeName !== "STYLE" && nodeName !== "SCRIPT") {
1108
+ const textNodeId = `t.${childId}`;
1109
+ insertBefore(parentNode, doc.createComment(textNodeId), childElm);
1110
+ }
1111
+ } else if (childElm.nodeType === NODE_TYPE.CommentNode) {
1112
+ if (childElm["s-sr"]) childElm.nodeValue = `s.${childId}.${childElm["s-sn"] || ""}`;
1113
+ }
1114
+ if (vnodeChild.$children$ != null) {
1115
+ const childDepth = depth + 1;
1116
+ vnodeChild.$children$.forEach((vnode, childIndex) => {
1117
+ insertChildVNodeAnnotations(doc, vnode, cmpData, hostId, childDepth, childIndex);
1118
+ });
1119
+ }
1120
+ };
1121
+ //#endregion
810
1122
  //#region src/testing/platform/index.ts
811
1123
  const setMode = (handler) => {
812
1124
  modeResolutionChain.length = 0;
@@ -859,13 +1171,13 @@ function resetBuildConditionals(b) {
859
1171
  b.hydratedAttribute = false;
860
1172
  b.hydratedClass = true;
861
1173
  b.invisiblePrehydration = true;
862
- b.appendChildSlotFix = false;
863
- b.cloneNodeFix = false;
1174
+ b.staticHydrationStyles = false;
1175
+ b.lightDomPatches = false;
1176
+ b.slotChildNodes = false;
1177
+ b.slotCloneNode = false;
1178
+ b.slotDomMutations = false;
1179
+ b.slotTextContent = false;
864
1180
  b.hotModuleReplacement = false;
865
- b.scopedSlotTextContentFix = false;
866
- b.slotChildNodesFix = false;
867
- b.experimentalSlotFixes = false;
868
- b.experimentalScopedSlotChanges = false;
869
1181
  }
870
1182
  //#endregion
871
1183
  //#region src/testing/spec-page.ts
@@ -885,14 +1197,8 @@ async function newSpecPage(opts) {
885
1197
  resetBuildConditionals(BUILD);
886
1198
  if (Array.isArray(opts.components)) registerComponents(opts.components);
887
1199
  if (opts.hydrateClientSide) opts.includeAnnotations = true;
888
- if (opts.hydrateServerSide) {
889
- opts.includeAnnotations = true;
890
- setSupportsShadowDom(false);
891
- } else {
892
- opts.includeAnnotations = !!opts.includeAnnotations;
893
- if (opts.supportsShadowDom === false) setSupportsShadowDom(false);
894
- else setSupportsShadowDom(true);
895
- }
1200
+ if (opts.hydrateServerSide) opts.includeAnnotations = true;
1201
+ else opts.includeAnnotations = !!opts.includeAnnotations;
896
1202
  BUILD.cssAnnotations = opts.includeAnnotations;
897
1203
  const cmpTags = /* @__PURE__ */ new Set();
898
1204
  win["__stencil_spec_options"] = opts;
@@ -946,9 +1252,8 @@ async function newSpecPage(opts) {
946
1252
  BUILD.hydrateServerSide = true;
947
1253
  BUILD.hydrateClientSide = false;
948
1254
  }
949
- BUILD.cloneNodeFix = false;
950
- BUILD.shadowDomShim = false;
951
- BUILD.attachStyles = !!opts.attachStyles;
1255
+ BUILD.slotCloneNode = false;
1256
+ if (opts.buildFlags) Object.assign(BUILD, opts.buildFlags);
952
1257
  if (typeof opts.url === "string") page.win.location.href = opts.url;
953
1258
  if (typeof opts.direction === "string") page.doc.documentElement.setAttribute("dir", opts.direction);
954
1259
  if (typeof opts.language === "string") page.doc.documentElement.setAttribute("lang", opts.language);
@@ -961,6 +1266,9 @@ async function newSpecPage(opts) {
961
1266
  if (typeof opts.userAgent === "string") try {
962
1267
  page.win.navigator.userAgent = opts.userAgent;
963
1268
  } catch {}
1269
+ if (opts.hydrateServerSide && opts.serializeShadowRoot === "scoped") {
1270
+ for (const [, cmps] of lazyBundles) for (const cmp of cmps) if (cmp[0] & CMP_FLAGS.shadowDomEncapsulation) cmp[0] |= CMP_FLAGS.shadowNeedsScopedCss;
1271
+ }
964
1272
  bootstrapLazy(lazyBundles);
965
1273
  if (typeof opts.template === "function") renderVdom({
966
1274
  $ancestorComponent$: void 0,
@@ -1166,4 +1474,4 @@ function setupConsoleMocker() {
1166
1474
  };
1167
1475
  }
1168
1476
  //#endregion
1169
- export { Build, Env, Fragment, Host, Mixin, createEvent, createTestingSystem, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRenderingRef, h, mockBuildCtx, mockCompilerCtx, mockCompilerSystem, mockComponentMeta, mockConfig, mockDocument, mockLoadConfigInit, mockLogger, mockModule, mockValidatedConfig, mockWindow, newSpecPage, readTask, registerHost, registerInstance, setAssetPath, setErrorHandler, setMode, setupConsoleMocker, shuffleArray, writeTask };
1477
+ export { Build, Env, Fragment, Host, Mixin, createEvent, createTestCompiler, createTestingSystem, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRenderingRef, h, mockBuildCtx, mockCompilerCtx, mockCompilerSystem, mockComponentMeta, mockConfig, mockDocument, mockLoadConfigInit, mockLogger, mockModule, mockValidatedConfig, mockWindow, newSpecPage, prepareTestCompiler, readTask, registerHost, registerInstance, setAssetPath, setErrorHandler, setMode, setupConsoleMocker, shuffleArray, writeTask };