@immense/vue-pom-generator 1.0.41 → 1.0.43

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.
package/dist/index.cjs CHANGED
@@ -26,13 +26,13 @@ const path = require("node:path");
26
26
  const process = require("node:process");
27
27
  const node_url = require("node:url");
28
28
  const fs = require("node:fs");
29
+ const compilerDom = require("@vue/compiler-dom");
30
+ const compilerSfc = require("@vue/compiler-sfc");
29
31
  const parser = require("@babel/parser");
30
32
  const jsdom = require("jsdom");
31
33
  const compilerCore = require("@vue/compiler-core");
32
34
  const types = require("@babel/types");
33
35
  const node_perf_hooks = require("node:perf_hooks");
34
- const compilerDom = require("@vue/compiler-dom");
35
- const compilerSfc = require("@vue/compiler-sfc");
36
36
  const virtualImport = require("vite-plugin-virtual");
37
37
  const vue = require("@vitejs/plugin-vue");
38
38
  var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
@@ -4768,148 +4768,6 @@ function getConstructor(childrenComponent, componentHierarchyMap, attachmentsFor
4768
4768
  return `${content}
4769
4769
  `;
4770
4770
  }
4771
- function summarizeHierarchyMap(componentHierarchyMap) {
4772
- let interactiveComponentCount = 0;
4773
- let dataTestIdCount = 0;
4774
- for (const dependencies of componentHierarchyMap.values()) {
4775
- const selectorCount = dependencies.dataTestIdSet?.size ?? 0;
4776
- if (selectorCount > 0) {
4777
- interactiveComponentCount += 1;
4778
- dataTestIdCount += selectorCount;
4779
- }
4780
- }
4781
- return {
4782
- entryCount: componentHierarchyMap.size,
4783
- interactiveComponentCount,
4784
- dataTestIdCount
4785
- };
4786
- }
4787
- function isLessRich(candidate, previous) {
4788
- if (candidate.dataTestIdCount !== previous.dataTestIdCount) {
4789
- return candidate.dataTestIdCount < previous.dataTestIdCount;
4790
- }
4791
- if (candidate.interactiveComponentCount !== previous.interactiveComponentCount) {
4792
- return candidate.interactiveComponentCount < previous.interactiveComponentCount;
4793
- }
4794
- return candidate.entryCount < previous.entryCount;
4795
- }
4796
- function createBuildProcessorPlugin(options) {
4797
- const {
4798
- componentHierarchyMap,
4799
- vueFilesPathMap,
4800
- viewsDir,
4801
- scanDirs,
4802
- basePageClassPath,
4803
- normalizedBasePagePath,
4804
- outDir,
4805
- emitLanguages,
4806
- csharp,
4807
- generateFixtures,
4808
- customPomAttachments,
4809
- projectRootRef,
4810
- customPomDir,
4811
- customPomImportAliases,
4812
- customPomImportNameCollisionBehavior,
4813
- testIdAttribute,
4814
- routerAwarePoms,
4815
- resolvedRouterEntry,
4816
- routerType,
4817
- routerModuleShims,
4818
- loggerRef
4819
- } = options;
4820
- let lastGeneratedMetrics = {
4821
- entryCount: 0,
4822
- interactiveComponentCount: 0,
4823
- dataTestIdCount: 0
4824
- };
4825
- return {
4826
- name: "vue-pom-generator-build",
4827
- // This plugin exists to generate code on build output; it is not needed during dev-server HMR.
4828
- apply: "build",
4829
- enforce: "pre",
4830
- async buildStart() {
4831
- if (!routerAwarePoms) {
4832
- setRouteNameToComponentNameMap(/* @__PURE__ */ new Map());
4833
- setResolveToComponentNameFn(() => null);
4834
- return;
4835
- }
4836
- let result;
4837
- if (routerType === "nuxt") {
4838
- result = await introspectNuxtPages(projectRootRef.current);
4839
- } else {
4840
- if (!resolvedRouterEntry)
4841
- throw new Error("[vue-pom-generator] router.entry is required when router introspection is enabled.");
4842
- result = await parseRouterFileFromCwd(resolvedRouterEntry, {
4843
- moduleShims: routerModuleShims,
4844
- componentNaming: {
4845
- projectRoot: projectRootRef.current,
4846
- viewsDirAbs: path.isAbsolute(viewsDir) ? viewsDir : path.resolve(projectRootRef.current, viewsDir),
4847
- scanDirs
4848
- }
4849
- });
4850
- }
4851
- const { routeNameMap, routePathMap } = result;
4852
- setRouteNameToComponentNameMap(routeNameMap);
4853
- setResolveToComponentNameFn((to) => {
4854
- if (typeof to === "string") {
4855
- return routePathMap.get(to) ?? null;
4856
- }
4857
- const maybe = to;
4858
- if (typeof maybe.name === "string" && maybe.name.length) {
4859
- const key = toPascalCase(maybe.name);
4860
- return routeNameMap.get(key) ?? null;
4861
- }
4862
- if (typeof maybe.path === "string" && maybe.path.length) {
4863
- return routePathMap.get(maybe.path) ?? null;
4864
- }
4865
- return null;
4866
- });
4867
- if (!fs.existsSync(basePageClassPath)) {
4868
- this.error(`BasePage.ts not found at ${basePageClassPath}. Ensure it is included in the build.`);
4869
- }
4870
- this.addWatchFile(basePageClassPath);
4871
- const pointerPath = path.resolve(path.dirname(basePageClassPath), "Pointer.ts");
4872
- if (!fs.existsSync(pointerPath)) {
4873
- this.error(`Pointer.ts not found at ${pointerPath}. Ensure it is included in the build.`);
4874
- }
4875
- this.addWatchFile(pointerPath);
4876
- },
4877
- async buildEnd(error) {
4878
- if (error) {
4879
- return;
4880
- }
4881
- const metrics = summarizeHierarchyMap(componentHierarchyMap);
4882
- if (metrics.dataTestIdCount <= 0) {
4883
- return;
4884
- }
4885
- if (isLessRich(metrics, lastGeneratedMetrics)) {
4886
- return;
4887
- }
4888
- await generateFiles(componentHierarchyMap, vueFilesPathMap, normalizedBasePagePath, {
4889
- outDir,
4890
- emitLanguages,
4891
- csharp,
4892
- generateFixtures,
4893
- customPomAttachments,
4894
- projectRoot: projectRootRef.current,
4895
- customPomDir,
4896
- customPomImportAliases,
4897
- customPomImportNameCollisionBehavior,
4898
- testIdAttribute,
4899
- vueRouterFluentChaining: routerAwarePoms,
4900
- routerEntry: resolvedRouterEntry,
4901
- routerType,
4902
- viewsDir,
4903
- scanDirs
4904
- });
4905
- lastGeneratedMetrics = metrics;
4906
- loggerRef.current.info(`generated POMs (${metrics.entryCount} entries, ${metrics.interactiveComponentCount} interactive components, ${metrics.dataTestIdCount} selectors)`);
4907
- },
4908
- closeBundle() {
4909
- loggerRef.current.info("build complete");
4910
- }
4911
- };
4912
- }
4913
4771
  const TESTID_CLICK_EVENT_NAME = "__testid_event__";
4914
4772
  const TESTID_CLICK_EVENT_STRICT_FLAG = "__testid_click_event_strict__";
4915
4773
  const CLICK_EVENT_NAME = TESTID_CLICK_EVENT_NAME;
@@ -5992,6 +5850,265 @@ Fix: remove the explicit ${attrLabel}, or change existingIdBehavior to "overwrit
5992
5850
  }
5993
5851
  };
5994
5852
  }
5853
+ function summarizeHierarchyMap(componentHierarchyMap) {
5854
+ let interactiveComponentCount = 0;
5855
+ let dataTestIdCount = 0;
5856
+ for (const dependencies of componentHierarchyMap.values()) {
5857
+ const selectorCount = dependencies.dataTestIdSet?.size ?? 0;
5858
+ if (selectorCount > 0) {
5859
+ interactiveComponentCount += 1;
5860
+ dataTestIdCount += selectorCount;
5861
+ }
5862
+ }
5863
+ return {
5864
+ entryCount: componentHierarchyMap.size,
5865
+ interactiveComponentCount,
5866
+ dataTestIdCount
5867
+ };
5868
+ }
5869
+ function isLessRich(candidate, previous) {
5870
+ if (candidate.dataTestIdCount !== previous.dataTestIdCount) {
5871
+ return candidate.dataTestIdCount < previous.dataTestIdCount;
5872
+ }
5873
+ if (candidate.interactiveComponentCount !== previous.interactiveComponentCount) {
5874
+ return candidate.interactiveComponentCount < previous.interactiveComponentCount;
5875
+ }
5876
+ return candidate.entryCount < previous.entryCount;
5877
+ }
5878
+ function createBuildProcessorPlugin(options) {
5879
+ const {
5880
+ componentHierarchyMap,
5881
+ vueFilesPathMap,
5882
+ viewsDir,
5883
+ scanDirs,
5884
+ basePageClassPath,
5885
+ normalizedBasePagePath,
5886
+ outDir,
5887
+ emitLanguages,
5888
+ csharp,
5889
+ generateFixtures,
5890
+ customPomAttachments,
5891
+ projectRootRef,
5892
+ customPomDir,
5893
+ customPomImportAliases,
5894
+ customPomImportNameCollisionBehavior,
5895
+ testIdAttribute,
5896
+ nameCollisionBehavior,
5897
+ existingIdBehavior,
5898
+ nativeWrappers,
5899
+ excludedComponents,
5900
+ getWrapperSearchRoots,
5901
+ routerAwarePoms,
5902
+ resolvedRouterEntry,
5903
+ routerType,
5904
+ routerModuleShims,
5905
+ loggerRef
5906
+ } = options;
5907
+ let lastGeneratedMetrics = {
5908
+ entryCount: 0,
5909
+ interactiveComponentCount: 0,
5910
+ dataTestIdCount: 0
5911
+ };
5912
+ const getViewsDirAbs = () => path.isAbsolute(viewsDir) ? viewsDir : path.resolve(projectRootRef.current, viewsDir);
5913
+ const getScriptInfo = (source, filename) => {
5914
+ try {
5915
+ const { descriptor } = compilerSfc.parse(source, { filename });
5916
+ if (!descriptor.script && !descriptor.scriptSetup)
5917
+ return { bindings: void 0, isScriptSetup: false };
5918
+ const scriptBlock = compilerSfc.compileScript(descriptor, { id: filename });
5919
+ return { bindings: scriptBlock.bindings, isScriptSetup: !!descriptor.scriptSetup };
5920
+ } catch {
5921
+ return { bindings: void 0, isScriptSetup: false };
5922
+ }
5923
+ };
5924
+ const supplementHierarchyFromFilesystem = () => {
5925
+ const walkFilesRecursive = (rootDir) => {
5926
+ const out = [];
5927
+ const stack = [rootDir];
5928
+ while (stack.length) {
5929
+ const dir = stack.pop();
5930
+ if (!dir) continue;
5931
+ let entries = [];
5932
+ try {
5933
+ entries = fs.readdirSync(dir, { withFileTypes: true });
5934
+ } catch {
5935
+ continue;
5936
+ }
5937
+ for (const ent of entries) {
5938
+ if (ent.isDirectory()) {
5939
+ if (ent.name === "node_modules" || ent.name === ".git" || ent.name === "dist")
5940
+ continue;
5941
+ stack.push(path.join(dir, ent.name));
5942
+ continue;
5943
+ }
5944
+ if (ent.isFile() && ent.name.endsWith(".vue")) {
5945
+ out.push(path.join(dir, ent.name));
5946
+ }
5947
+ }
5948
+ }
5949
+ return out;
5950
+ };
5951
+ let supplemented = 0;
5952
+ for (const dir of scanDirs) {
5953
+ const absDir = path.resolve(projectRootRef.current, dir);
5954
+ if (!fs.existsSync(absDir))
5955
+ continue;
5956
+ for (const filePath of walkFilesRecursive(absDir)) {
5957
+ const absolutePath = path.resolve(filePath);
5958
+ const componentName = resolveComponentNameFromPath({
5959
+ filename: absolutePath,
5960
+ projectRoot: projectRootRef.current,
5961
+ viewsDirAbs: getViewsDirAbs(),
5962
+ scanDirs,
5963
+ extraRoots: [process.cwd()]
5964
+ });
5965
+ if (componentHierarchyMap.has(componentName))
5966
+ continue;
5967
+ let sfc = "";
5968
+ try {
5969
+ sfc = fs.readFileSync(absolutePath, "utf8");
5970
+ } catch {
5971
+ continue;
5972
+ }
5973
+ const { descriptor } = compilerSfc.parse(sfc, { filename: absolutePath });
5974
+ const template = descriptor.template?.content ?? "";
5975
+ if (!template.trim()) {
5976
+ vueFilesPathMap.set(componentName, absolutePath);
5977
+ componentHierarchyMap.set(componentName, {
5978
+ filePath: absolutePath,
5979
+ childrenComponentSet: /* @__PURE__ */ new Set(),
5980
+ usedComponentSet: /* @__PURE__ */ new Set(),
5981
+ dataTestIdSet: /* @__PURE__ */ new Set(),
5982
+ isView: false,
5983
+ methodsContent: ""
5984
+ });
5985
+ supplemented++;
5986
+ continue;
5987
+ }
5988
+ const { bindings: bindingMetadata, isScriptSetup } = getScriptInfo(sfc, absolutePath);
5989
+ vueFilesPathMap.set(componentName, absolutePath);
5990
+ try {
5991
+ compilerDom__namespace.compile(template, {
5992
+ filename: absolutePath,
5993
+ prefixIdentifiers: true,
5994
+ inline: isScriptSetup,
5995
+ bindingMetadata,
5996
+ nodeTransforms: [
5997
+ createTestIdTransform(
5998
+ componentName,
5999
+ componentHierarchyMap,
6000
+ nativeWrappers,
6001
+ excludedComponents,
6002
+ getViewsDirAbs(),
6003
+ {
6004
+ existingIdBehavior: existingIdBehavior ?? "preserve",
6005
+ testIdAttribute,
6006
+ nameCollisionBehavior,
6007
+ warn: (message) => loggerRef.current.warn(message),
6008
+ vueFilesPathMap,
6009
+ wrapperSearchRoots: getWrapperSearchRoots()
6010
+ }
6011
+ )
6012
+ ]
6013
+ });
6014
+ } catch {
6015
+ }
6016
+ supplemented++;
6017
+ }
6018
+ }
6019
+ if (supplemented > 0) {
6020
+ loggerRef.current.info(`supplemented ${supplemented} components from filesystem walk (not in build graph)`);
6021
+ }
6022
+ };
6023
+ return {
6024
+ name: "vue-pom-generator-build",
6025
+ // This plugin exists to generate code on build output; it is not needed during dev-server HMR.
6026
+ apply: "build",
6027
+ enforce: "pre",
6028
+ async buildStart() {
6029
+ if (!routerAwarePoms) {
6030
+ setRouteNameToComponentNameMap(/* @__PURE__ */ new Map());
6031
+ setResolveToComponentNameFn(() => null);
6032
+ return;
6033
+ }
6034
+ let result;
6035
+ if (routerType === "nuxt") {
6036
+ result = await introspectNuxtPages(projectRootRef.current);
6037
+ } else {
6038
+ if (!resolvedRouterEntry)
6039
+ throw new Error("[vue-pom-generator] router.entry is required when router introspection is enabled.");
6040
+ result = await parseRouterFileFromCwd(resolvedRouterEntry, {
6041
+ moduleShims: routerModuleShims,
6042
+ componentNaming: {
6043
+ projectRoot: projectRootRef.current,
6044
+ viewsDirAbs: path.isAbsolute(viewsDir) ? viewsDir : path.resolve(projectRootRef.current, viewsDir),
6045
+ scanDirs
6046
+ }
6047
+ });
6048
+ }
6049
+ const { routeNameMap, routePathMap } = result;
6050
+ setRouteNameToComponentNameMap(routeNameMap);
6051
+ setResolveToComponentNameFn((to) => {
6052
+ if (typeof to === "string") {
6053
+ return routePathMap.get(to) ?? null;
6054
+ }
6055
+ const maybe = to;
6056
+ if (typeof maybe.name === "string" && maybe.name.length) {
6057
+ const key = toPascalCase(maybe.name);
6058
+ return routeNameMap.get(key) ?? null;
6059
+ }
6060
+ if (typeof maybe.path === "string" && maybe.path.length) {
6061
+ return routePathMap.get(maybe.path) ?? null;
6062
+ }
6063
+ return null;
6064
+ });
6065
+ if (!fs.existsSync(basePageClassPath)) {
6066
+ this.error(`BasePage.ts not found at ${basePageClassPath}. Ensure it is included in the build.`);
6067
+ }
6068
+ this.addWatchFile(basePageClassPath);
6069
+ const pointerPath = path.resolve(path.dirname(basePageClassPath), "Pointer.ts");
6070
+ if (!fs.existsSync(pointerPath)) {
6071
+ this.error(`Pointer.ts not found at ${pointerPath}. Ensure it is included in the build.`);
6072
+ }
6073
+ this.addWatchFile(pointerPath);
6074
+ },
6075
+ async buildEnd(error) {
6076
+ if (error) {
6077
+ return;
6078
+ }
6079
+ supplementHierarchyFromFilesystem();
6080
+ const metrics = summarizeHierarchyMap(componentHierarchyMap);
6081
+ if (metrics.dataTestIdCount <= 0) {
6082
+ return;
6083
+ }
6084
+ if (isLessRich(metrics, lastGeneratedMetrics)) {
6085
+ return;
6086
+ }
6087
+ await generateFiles(componentHierarchyMap, vueFilesPathMap, normalizedBasePagePath, {
6088
+ outDir,
6089
+ emitLanguages,
6090
+ csharp,
6091
+ generateFixtures,
6092
+ customPomAttachments,
6093
+ projectRoot: projectRootRef.current,
6094
+ customPomDir,
6095
+ customPomImportAliases,
6096
+ customPomImportNameCollisionBehavior,
6097
+ testIdAttribute,
6098
+ vueRouterFluentChaining: routerAwarePoms,
6099
+ routerEntry: resolvedRouterEntry,
6100
+ routerType,
6101
+ viewsDir,
6102
+ scanDirs
6103
+ });
6104
+ lastGeneratedMetrics = metrics;
6105
+ loggerRef.current.info(`generated POMs (${metrics.entryCount} entries, ${metrics.interactiveComponentCount} interactive components, ${metrics.dataTestIdCount} selectors)`);
6106
+ },
6107
+ closeBundle() {
6108
+ loggerRef.current.info("build complete");
6109
+ }
6110
+ };
6111
+ }
5995
6112
  function createDevProcessorPlugin(options) {
5996
6113
  const {
5997
6114
  nativeWrappers,
@@ -6011,6 +6128,7 @@ function createDevProcessorPlugin(options) {
6011
6128
  customPomImportAliases,
6012
6129
  customPomImportNameCollisionBehavior,
6013
6130
  nameCollisionBehavior = "suffix",
6131
+ existingIdBehavior,
6014
6132
  testIdAttribute,
6015
6133
  routerAwarePoms,
6016
6134
  resolvedRouterEntry,
@@ -6037,7 +6155,7 @@ function createDevProcessorPlugin(options) {
6037
6155
  return;
6038
6156
  scheduleVueFileRegen(ctx.file, "hmr");
6039
6157
  },
6040
- configureServer(server) {
6158
+ async configureServer(server) {
6041
6159
  const getViewsDirAbs = () => path.isAbsolute(viewsDir) ? viewsDir : path.resolve(projectRootRef.current, viewsDir);
6042
6160
  const routerInitPromise = (async () => {
6043
6161
  if (!routerAwarePoms) {
@@ -6088,6 +6206,17 @@ function createDevProcessorPlugin(options) {
6088
6206
  });
6089
6207
  return descriptor.template?.content ?? "";
6090
6208
  };
6209
+ const getScriptInfo = (source, filename) => {
6210
+ try {
6211
+ const { descriptor } = compilerSfc.parse(source, { filename });
6212
+ if (!descriptor.script && !descriptor.scriptSetup)
6213
+ return { bindings: void 0, isScriptSetup: false };
6214
+ const scriptBlock = compilerSfc.compileScript(descriptor, { id: filename });
6215
+ return { bindings: scriptBlock.bindings, isScriptSetup: !!descriptor.scriptSetup };
6216
+ } catch {
6217
+ return { bindings: void 0, isScriptSetup: false };
6218
+ }
6219
+ };
6091
6220
  const walkFilesRecursive = (rootDir) => {
6092
6221
  const out = [];
6093
6222
  const stack = [rootDir];
@@ -6114,8 +6243,8 @@ function createDevProcessorPlugin(options) {
6114
6243
  }
6115
6244
  return out;
6116
6245
  };
6117
- const snapshotHierarchy = /* @__PURE__ */ new Map();
6118
- const snapshotVuePathMap = /* @__PURE__ */ new Map();
6246
+ let snapshotHierarchy = /* @__PURE__ */ new Map();
6247
+ let snapshotVuePathMap = /* @__PURE__ */ new Map();
6119
6248
  const filePathToComponentName = /* @__PURE__ */ new Map();
6120
6249
  const getComponentNameForFile = (filePath) => {
6121
6250
  const normalized = path.resolve(filePath);
@@ -6132,12 +6261,12 @@ function createDevProcessorPlugin(options) {
6132
6261
  filePathToComponentName.set(normalized, name);
6133
6262
  return name;
6134
6263
  };
6135
- const compileVueFileIntoSnapshot = (filePath) => {
6264
+ const compileVueFileIntoSnapshot = (filePath, targetHierarchy = snapshotHierarchy, targetVuePathMap = snapshotVuePathMap) => {
6136
6265
  const started = node_perf_hooks.performance.now();
6137
6266
  const absolutePath = path.resolve(filePath);
6138
6267
  const componentName = getComponentNameForFile(absolutePath);
6139
- snapshotVuePathMap.set(componentName, absolutePath);
6140
- snapshotHierarchy.delete(componentName);
6268
+ targetVuePathMap.set(componentName, absolutePath);
6269
+ targetHierarchy.delete(componentName);
6141
6270
  let sfc = "";
6142
6271
  try {
6143
6272
  sfc = fs.readFileSync(absolutePath, "utf8");
@@ -6147,36 +6276,36 @@ function createDevProcessorPlugin(options) {
6147
6276
  const template = extractTemplateFromSfc(sfc, absolutePath);
6148
6277
  if (!template.trim())
6149
6278
  return { componentName, ms: node_perf_hooks.performance.now() - started, compiled: true };
6150
- try {
6151
- compilerDom__namespace.compile(template, {
6152
- filename: absolutePath,
6153
- prefixIdentifiers: true,
6154
- nodeTransforms: [
6155
- createTestIdTransform(
6156
- componentName,
6157
- snapshotHierarchy,
6158
- nativeWrappers,
6159
- excludedComponents,
6160
- getViewsDirAbs(),
6161
- {
6162
- existingIdBehavior: "preserve",
6163
- nameCollisionBehavior,
6164
- testIdAttribute,
6165
- warn: (message) => loggerRef.current.warn(message),
6166
- vueFilesPathMap: snapshotVuePathMap,
6167
- wrapperSearchRoots: getWrapperSearchRoots()
6168
- }
6169
- )
6170
- ]
6171
- });
6172
- } catch {
6173
- }
6279
+ const { bindings: bindingMetadata, isScriptSetup } = getScriptInfo(sfc, absolutePath);
6280
+ compilerDom__namespace.compile(template, {
6281
+ filename: absolutePath,
6282
+ prefixIdentifiers: true,
6283
+ inline: isScriptSetup,
6284
+ bindingMetadata,
6285
+ nodeTransforms: [
6286
+ createTestIdTransform(
6287
+ componentName,
6288
+ targetHierarchy,
6289
+ nativeWrappers,
6290
+ excludedComponents,
6291
+ getViewsDirAbs(),
6292
+ {
6293
+ existingIdBehavior: existingIdBehavior ?? "preserve",
6294
+ nameCollisionBehavior,
6295
+ testIdAttribute,
6296
+ warn: (message) => loggerRef.current.warn(message),
6297
+ vueFilesPathMap: targetVuePathMap,
6298
+ wrapperSearchRoots: getWrapperSearchRoots()
6299
+ }
6300
+ )
6301
+ ]
6302
+ });
6174
6303
  return { componentName, ms: node_perf_hooks.performance.now() - started, compiled: true };
6175
6304
  };
6176
6305
  const fullRebuildSnapshotFromFilesystem = () => {
6177
6306
  const t0 = node_perf_hooks.performance.now();
6178
- snapshotHierarchy.clear();
6179
- snapshotVuePathMap.clear();
6307
+ const nextHierarchy = /* @__PURE__ */ new Map();
6308
+ const nextVuePathMap = /* @__PURE__ */ new Map();
6180
6309
  filePathToComponentName.clear();
6181
6310
  let totalVueFiles = 0;
6182
6311
  let compiledCount = 0;
@@ -6187,11 +6316,13 @@ function createDevProcessorPlugin(options) {
6187
6316
  const vueFiles = walkFilesRecursive(absDir);
6188
6317
  totalVueFiles += vueFiles.length;
6189
6318
  for (const file of vueFiles) {
6190
- const res = compileVueFileIntoSnapshot(file);
6319
+ const res = compileVueFileIntoSnapshot(file, nextHierarchy, nextVuePathMap);
6191
6320
  if (res.compiled)
6192
6321
  compiledCount++;
6193
6322
  }
6194
6323
  }
6324
+ snapshotHierarchy = nextHierarchy;
6325
+ snapshotVuePathMap = nextVuePathMap;
6195
6326
  const t1 = node_perf_hooks.performance.now();
6196
6327
  logInfo(`initial scan: found ${totalVueFiles} .vue files in ${scanDirs.join(", ")}`);
6197
6328
  logInfo(`initial compile: ${compiledCount}/${totalVueFiles} files in ${formatMs(t1 - t0)} (components=${snapshotHierarchy.size})`);
@@ -6218,6 +6349,10 @@ function createDevProcessorPlugin(options) {
6218
6349
  const t1 = node_perf_hooks.performance.now();
6219
6350
  logInfo(`generate(${reason}): components=${snapshotHierarchy.size} in ${formatMs(t1 - t0)}`);
6220
6351
  };
6352
+ let timer = null;
6353
+ let maxWaitTimer = null;
6354
+ const pendingChangedVueFiles = /* @__PURE__ */ new Set();
6355
+ const pendingDeletedComponents = /* @__PURE__ */ new Set();
6221
6356
  const initialBuildPromise = (async () => {
6222
6357
  const t0 = node_perf_hooks.performance.now();
6223
6358
  await routerInitPromise;
@@ -6226,13 +6361,44 @@ function createDevProcessorPlugin(options) {
6226
6361
  const t1 = node_perf_hooks.performance.now();
6227
6362
  logInfo(`startup total: ${formatMs(t1 - t0)}`);
6228
6363
  })();
6364
+ const logGenerationError = (reason, message) => {
6365
+ server.config.logger.error(`[vue-pom-generator] dev generation failed during ${reason}: ${message}`);
6366
+ };
6367
+ const regenerateFromPending = async (reason) => {
6368
+ const t0 = node_perf_hooks.performance.now();
6369
+ await initialBuildPromise;
6370
+ const nextHierarchy = new Map(snapshotHierarchy);
6371
+ const nextVuePathMap = new Map(snapshotVuePathMap);
6372
+ for (const componentName of pendingDeletedComponents) {
6373
+ nextHierarchy.delete(componentName);
6374
+ nextVuePathMap.delete(componentName);
6375
+ }
6376
+ const files = Array.from(pendingChangedVueFiles);
6377
+ const deletedCount = pendingDeletedComponents.size;
6378
+ pendingChangedVueFiles.clear();
6379
+ pendingDeletedComponents.clear();
6380
+ let compileMs = 0;
6381
+ for (const f of files) {
6382
+ const res = compileVueFileIntoSnapshot(f, nextHierarchy, nextVuePathMap);
6383
+ compileMs += res.ms;
6384
+ }
6385
+ snapshotHierarchy = nextHierarchy;
6386
+ snapshotVuePathMap = nextVuePathMap;
6387
+ const t1 = node_perf_hooks.performance.now();
6388
+ generateAggregatedFromSnapshot(reason);
6389
+ const t2 = node_perf_hooks.performance.now();
6390
+ return {
6391
+ files,
6392
+ deletedCount,
6393
+ compileMs,
6394
+ preGenerateMs: t1 - t0,
6395
+ generateMs: t2 - t1,
6396
+ totalMs: t2 - t0
6397
+ };
6398
+ };
6229
6399
  const watchedVueGlobs = scanDirs.map((dir) => path.resolve(projectRootRef.current, dir, "**", "*.vue"));
6230
6400
  const watchedPluginGlob = path.resolve(projectRootRef.current, "vite-plugins", "vue-pom-generator", "**", "*.ts");
6231
6401
  server.watcher.add([...watchedVueGlobs, watchedPluginGlob, basePageClassPath]);
6232
- let timer = null;
6233
- let maxWaitTimer = null;
6234
- const pendingChangedVueFiles = /* @__PURE__ */ new Set();
6235
- const pendingDeletedComponents = /* @__PURE__ */ new Set();
6236
6402
  scheduleVueFileRegenLocal = (filePath, source) => {
6237
6403
  pendingChangedVueFiles.add(filePath);
6238
6404
  logDebug(`queued(${source}): files=${pendingChangedVueFiles.size} deleted=${pendingDeletedComponents.size}`);
@@ -6249,29 +6415,14 @@ function createDevProcessorPlugin(options) {
6249
6415
  timer = null;
6250
6416
  }
6251
6417
  maxWaitTimer = null;
6252
- void (async () => {
6253
- const t0 = node_perf_hooks.performance.now();
6254
- await initialBuildPromise;
6255
- for (const componentName of pendingDeletedComponents) {
6256
- snapshotHierarchy.delete(componentName);
6257
- snapshotVuePathMap.delete(componentName);
6258
- }
6259
- const files = Array.from(pendingChangedVueFiles);
6260
- const deletedCount = pendingDeletedComponents.size;
6261
- pendingChangedVueFiles.clear();
6262
- pendingDeletedComponents.clear();
6263
- let compileMs = 0;
6264
- for (const f of files) {
6265
- const res = compileVueFileIntoSnapshot(f);
6266
- compileMs += res.ms;
6267
- }
6268
- const t1 = node_perf_hooks.performance.now();
6269
- generateAggregatedFromSnapshot("max-wait");
6270
- const t2 = node_perf_hooks.performance.now();
6418
+ void regenerateFromPending("max-wait").then(({ files, deletedCount, compileMs, preGenerateMs, generateMs, totalMs }) => {
6271
6419
  logInfo(
6272
- `max-wait: files=${files.length} deleted=${deletedCount} compile=${formatMs(compileMs)} wall=${formatMs(t1 - t0)} gen=${formatMs(t2 - t1)} total=${formatMs(t2 - t0)}`
6420
+ `max-wait: files=${files.length} deleted=${deletedCount} compile=${formatMs(compileMs)} wall=${formatMs(preGenerateMs)} gen=${formatMs(generateMs)} total=${formatMs(totalMs)}`
6273
6421
  );
6274
- })();
6422
+ }).catch((error) => {
6423
+ const message = error instanceof Error ? error.message : String(error);
6424
+ logGenerationError("max-wait", message);
6425
+ });
6275
6426
  }, MAX_WAIT_MS);
6276
6427
  }
6277
6428
  if (wasEmpty) {
@@ -6287,31 +6438,17 @@ function createDevProcessorPlugin(options) {
6287
6438
  clearTimeout(maxWaitTimer);
6288
6439
  maxWaitTimer = null;
6289
6440
  }
6290
- void (async () => {
6291
- const t0 = node_perf_hooks.performance.now();
6292
- await initialBuildPromise;
6293
- for (const componentName of pendingDeletedComponents) {
6294
- snapshotHierarchy.delete(componentName);
6295
- snapshotVuePathMap.delete(componentName);
6296
- }
6297
- const files = Array.from(pendingChangedVueFiles);
6298
- const deletedCount = pendingDeletedComponents.size;
6299
- pendingChangedVueFiles.clear();
6300
- pendingDeletedComponents.clear();
6301
- let compileMs = 0;
6302
- for (const f of files) {
6303
- const res = compileVueFileIntoSnapshot(f);
6304
- compileMs += res.ms;
6305
- }
6306
- const t1 = node_perf_hooks.performance.now();
6307
- generateAggregatedFromSnapshot(files.length || deletedCount ? "batched" : "noop");
6308
- const t2 = node_perf_hooks.performance.now();
6441
+ const reason = pendingChangedVueFiles.size || pendingDeletedComponents.size ? "batched" : "noop";
6442
+ void regenerateFromPending(reason).then(({ files, deletedCount, compileMs, preGenerateMs, generateMs, totalMs }) => {
6309
6443
  if (files.length || deletedCount) {
6310
6444
  logInfo(
6311
- `batched: files=${files.length} deleted=${deletedCount} compile=${formatMs(compileMs)} wall=${formatMs(t1 - t0)} gen=${formatMs(t2 - t1)} total=${formatMs(t2 - t0)}`
6445
+ `batched: files=${files.length} deleted=${deletedCount} compile=${formatMs(compileMs)} wall=${formatMs(preGenerateMs)} gen=${formatMs(generateMs)} total=${formatMs(totalMs)}`
6312
6446
  );
6313
6447
  }
6314
- })();
6448
+ }).catch((error) => {
6449
+ const message = error instanceof Error ? error.message : String(error);
6450
+ logGenerationError(reason, message);
6451
+ });
6315
6452
  }, 75);
6316
6453
  }
6317
6454
  server.watcher.on("change", async (changedPath) => {
@@ -6363,6 +6500,7 @@ function createDevProcessorPlugin(options) {
6363
6500
  });
6364
6501
  setTimeout(() => {
6365
6502
  }, 250);
6503
+ await initialBuildPromise;
6366
6504
  }
6367
6505
  };
6368
6506
  }
@@ -6394,6 +6532,7 @@ function createSupportPlugins(options) {
6394
6532
  scanDirs,
6395
6533
  getWrapperSearchRoots,
6396
6534
  nameCollisionBehavior = "suffix",
6535
+ existingIdBehavior,
6397
6536
  outDir,
6398
6537
  emitLanguages,
6399
6538
  csharp,
@@ -6447,6 +6586,11 @@ function createSupportPlugins(options) {
6447
6586
  customPomImportAliases,
6448
6587
  customPomImportNameCollisionBehavior,
6449
6588
  testIdAttribute,
6589
+ nameCollisionBehavior,
6590
+ existingIdBehavior,
6591
+ nativeWrappers,
6592
+ excludedComponents,
6593
+ getWrapperSearchRoots,
6450
6594
  routerAwarePoms,
6451
6595
  routerType,
6452
6596
  resolvedRouterEntry,
@@ -6471,6 +6615,7 @@ function createSupportPlugins(options) {
6471
6615
  customPomImportAliases,
6472
6616
  customPomImportNameCollisionBehavior,
6473
6617
  nameCollisionBehavior,
6618
+ existingIdBehavior,
6474
6619
  testIdAttribute,
6475
6620
  routerAwarePoms,
6476
6621
  routerType,
@@ -7052,6 +7197,7 @@ function createVuePomGeneratorPlugins(options = {}) {
7052
7197
  scanDirs,
7053
7198
  getWrapperSearchRoots: getWrapperSearchRootsAbs,
7054
7199
  nameCollisionBehavior,
7200
+ existingIdBehavior,
7055
7201
  outDir,
7056
7202
  emitLanguages,
7057
7203
  csharp,