@bamboocss/parser 1.51.1 → 1.51.3

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
@@ -1879,7 +1879,25 @@ var Project = class {
1879
1879
  }
1880
1880
  return [root, spelledRoot].some((boundary) => target === boundary || target.startsWith(`${boundary}/`));
1881
1881
  };
1882
- resolveSpecifier = (moduleName, from) => {
1882
+ /**
1883
+ * Resolve one specifier, stopping short of installing what it names.
1884
+ *
1885
+ * Split from the install because installing is a round trip, and a round trip per resolved
1886
+ * module is quadratic. Every install moves the project's membership, which rewrites the
1887
+ * synthesized tsconfig's whole `files` list and tells the compiler its config changed — so
1888
+ * the compiler re-derives the program each time, over a list one entry longer than the last.
1889
+ * Measured against the bulk path on a synthetic project: 2,000 modules cost 27.4s installed
1890
+ * one at a time against 92ms installed together, and the gap widens with the project.
1891
+ *
1892
+ * That cost lands on exactly the modules a monorepo has most of. `node_modules` is excluded
1893
+ * from the walk, but a workspace sibling resolves to a real path inside the checkout, so
1894
+ * every cross-package import is a module outside the `include` glob that was bulk-installed
1895
+ * — and each one was paying a full program reload.
1896
+ *
1897
+ * So this answers what it can and reports what it *would* install; `ensureResolutionFacts`
1898
+ * collects those across one importer and installs them together.
1899
+ */
1900
+ #planSpecifier = (moduleName, from) => {
1883
1901
  this.#assertNotLoading();
1884
1902
  const project = this.project;
1885
1903
  const compilerOptions = project.getCompilerOptions();
@@ -1945,16 +1963,13 @@ var Project = class {
1945
1963
  try {
1946
1964
  this.resolutionWork.sourceFilesRead++;
1947
1965
  const content = project.getFileSystem().readFileSync(name);
1948
- const sourceFile = project.createSourceFile(name, content, { scriptKind: scriptKindFor(name) });
1949
- if (!sourceFile) throw new Error(`bamboo: resolved ${name} but the project produced no source file`);
1950
- this.resolutionWork.sourceFilesAdded++;
1951
- this.canonicalPaths.set(name, this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile)));
1952
- return {
1966
+ return { install: {
1953
1967
  configurationFiles: [...configurationFiles].sort(),
1968
+ content,
1954
1969
  local: true,
1955
- pendingCandidates,
1956
- sourceFile
1957
- };
1970
+ name,
1971
+ pendingCandidates
1972
+ } };
1958
1973
  } catch (error) {
1959
1974
  if (error?.code !== "ENOENT") throw error;
1960
1975
  return {
@@ -1964,6 +1979,25 @@ var Project = class {
1964
1979
  };
1965
1980
  }
1966
1981
  };
1982
+ /**
1983
+ * Turn a plan into a resolution, reading back anything the batch installed.
1984
+ *
1985
+ * The lookup is free after the first: `addSourceFiles` only queues, and whichever read comes
1986
+ * first flushes the whole batch — so every later one is served from the same snapshot
1987
+ * without another round trip.
1988
+ */
1989
+ #completeResolution = (plan) => {
1990
+ if (!("install" in plan)) return plan;
1991
+ const { content: _content, name, ...resolution } = plan.install;
1992
+ const sourceFile = this.project.getSourceFile(name);
1993
+ if (!sourceFile) throw new Error(`bamboo: resolved ${name} but the project produced no source file`);
1994
+ this.resolutionWork.sourceFilesAdded++;
1995
+ this.canonicalPaths.set(name, this.normalizePath((0, _bamboocss_ts_ast.pathOf)(sourceFile)));
1996
+ return {
1997
+ ...resolution,
1998
+ sourceFile
1999
+ };
2000
+ };
1967
2001
  retractImporter = (importer) => {
1968
2002
  for (const previous of this.dependencies.get(importer) ?? []) {
1969
2003
  const reverse = this.dependents.get(previous);
@@ -2016,10 +2050,23 @@ var Project = class {
2016
2050
  const facts = [];
2017
2051
  const pendingCandidates = [];
2018
2052
  const configurationFiles = [];
2053
+ const planned = [];
2054
+ const pendingInstalls = /* @__PURE__ */ new Map();
2019
2055
  for (const [ordinal, { declaration, kind }] of declarations.entries()) {
2020
2056
  const specifier = (0, _bamboocss_ts_ast.getModuleSpecifierValue)(declaration);
2021
2057
  if (!specifier) continue;
2022
- const resolved = this.resolveSpecifier(specifier, sourceFile);
2058
+ const plan = this.#planSpecifier(specifier, sourceFile);
2059
+ planned.push({
2060
+ kind,
2061
+ ordinal,
2062
+ plan,
2063
+ specifier
2064
+ });
2065
+ if ("install" in plan) pendingInstalls.set(plan.install.name, plan.install.content);
2066
+ }
2067
+ if (pendingInstalls.size) this.project.addSourceFiles(pendingInstalls);
2068
+ for (const { kind, ordinal, plan, specifier } of planned) {
2069
+ const resolved = this.#completeResolution(plan);
2023
2070
  if (!resolved.local) continue;
2024
2071
  facts.push(Object.freeze({
2025
2072
  importer,
package/dist/index.d.cts CHANGED
@@ -572,7 +572,6 @@ declare class Project {
572
572
  private getLocalFailedLookupCandidates;
573
573
  private isUnresolvedLocalSpecifier;
574
574
  private isInCheckout;
575
- private resolveSpecifier;
576
575
  private retractImporter;
577
576
  private publishResolutionFacts;
578
577
  private ensureResolutionFacts;
package/dist/index.d.mts CHANGED
@@ -572,7 +572,6 @@ declare class Project {
572
572
  private getLocalFailedLookupCandidates;
573
573
  private isUnresolvedLocalSpecifier;
574
574
  private isInCheckout;
575
- private resolveSpecifier;
576
575
  private retractImporter;
577
576
  private publishResolutionFacts;
578
577
  private ensureResolutionFacts;
package/dist/index.mjs CHANGED
@@ -1878,7 +1878,25 @@ var Project = class {
1878
1878
  }
1879
1879
  return [root, spelledRoot].some((boundary) => target === boundary || target.startsWith(`${boundary}/`));
1880
1880
  };
1881
- resolveSpecifier = (moduleName, from) => {
1881
+ /**
1882
+ * Resolve one specifier, stopping short of installing what it names.
1883
+ *
1884
+ * Split from the install because installing is a round trip, and a round trip per resolved
1885
+ * module is quadratic. Every install moves the project's membership, which rewrites the
1886
+ * synthesized tsconfig's whole `files` list and tells the compiler its config changed — so
1887
+ * the compiler re-derives the program each time, over a list one entry longer than the last.
1888
+ * Measured against the bulk path on a synthetic project: 2,000 modules cost 27.4s installed
1889
+ * one at a time against 92ms installed together, and the gap widens with the project.
1890
+ *
1891
+ * That cost lands on exactly the modules a monorepo has most of. `node_modules` is excluded
1892
+ * from the walk, but a workspace sibling resolves to a real path inside the checkout, so
1893
+ * every cross-package import is a module outside the `include` glob that was bulk-installed
1894
+ * — and each one was paying a full program reload.
1895
+ *
1896
+ * So this answers what it can and reports what it *would* install; `ensureResolutionFacts`
1897
+ * collects those across one importer and installs them together.
1898
+ */
1899
+ #planSpecifier = (moduleName, from) => {
1882
1900
  this.#assertNotLoading();
1883
1901
  const project = this.project;
1884
1902
  const compilerOptions = project.getCompilerOptions();
@@ -1944,16 +1962,13 @@ var Project = class {
1944
1962
  try {
1945
1963
  this.resolutionWork.sourceFilesRead++;
1946
1964
  const content = project.getFileSystem().readFileSync(name);
1947
- const sourceFile = project.createSourceFile(name, content, { scriptKind: scriptKindFor(name) });
1948
- if (!sourceFile) throw new Error(`bamboo: resolved ${name} but the project produced no source file`);
1949
- this.resolutionWork.sourceFilesAdded++;
1950
- this.canonicalPaths.set(name, this.normalizePath(pathOf(sourceFile)));
1951
- return {
1965
+ return { install: {
1952
1966
  configurationFiles: [...configurationFiles].sort(),
1967
+ content,
1953
1968
  local: true,
1954
- pendingCandidates,
1955
- sourceFile
1956
- };
1969
+ name,
1970
+ pendingCandidates
1971
+ } };
1957
1972
  } catch (error) {
1958
1973
  if (error?.code !== "ENOENT") throw error;
1959
1974
  return {
@@ -1963,6 +1978,25 @@ var Project = class {
1963
1978
  };
1964
1979
  }
1965
1980
  };
1981
+ /**
1982
+ * Turn a plan into a resolution, reading back anything the batch installed.
1983
+ *
1984
+ * The lookup is free after the first: `addSourceFiles` only queues, and whichever read comes
1985
+ * first flushes the whole batch — so every later one is served from the same snapshot
1986
+ * without another round trip.
1987
+ */
1988
+ #completeResolution = (plan) => {
1989
+ if (!("install" in plan)) return plan;
1990
+ const { content: _content, name, ...resolution } = plan.install;
1991
+ const sourceFile = this.project.getSourceFile(name);
1992
+ if (!sourceFile) throw new Error(`bamboo: resolved ${name} but the project produced no source file`);
1993
+ this.resolutionWork.sourceFilesAdded++;
1994
+ this.canonicalPaths.set(name, this.normalizePath(pathOf(sourceFile)));
1995
+ return {
1996
+ ...resolution,
1997
+ sourceFile
1998
+ };
1999
+ };
1966
2000
  retractImporter = (importer) => {
1967
2001
  for (const previous of this.dependencies.get(importer) ?? []) {
1968
2002
  const reverse = this.dependents.get(previous);
@@ -2015,10 +2049,23 @@ var Project = class {
2015
2049
  const facts = [];
2016
2050
  const pendingCandidates = [];
2017
2051
  const configurationFiles = [];
2052
+ const planned = [];
2053
+ const pendingInstalls = /* @__PURE__ */ new Map();
2018
2054
  for (const [ordinal, { declaration, kind }] of declarations.entries()) {
2019
2055
  const specifier = getModuleSpecifierValue(declaration);
2020
2056
  if (!specifier) continue;
2021
- const resolved = this.resolveSpecifier(specifier, sourceFile);
2057
+ const plan = this.#planSpecifier(specifier, sourceFile);
2058
+ planned.push({
2059
+ kind,
2060
+ ordinal,
2061
+ plan,
2062
+ specifier
2063
+ });
2064
+ if ("install" in plan) pendingInstalls.set(plan.install.name, plan.install.content);
2065
+ }
2066
+ if (pendingInstalls.size) this.project.addSourceFiles(pendingInstalls);
2067
+ for (const { kind, ordinal, plan, specifier } of planned) {
2068
+ const resolved = this.#completeResolution(plan);
2022
2069
  if (!resolved.local) continue;
2023
2070
  facts.push(Object.freeze({
2024
2071
  importer,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bamboocss/parser",
3
- "version": "1.51.1",
3
+ "version": "1.51.3",
4
4
  "description": "The static parser for bamboo css",
5
5
  "homepage": "https://bamboocss.com",
6
6
  "license": "MIT",
@@ -33,20 +33,20 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "ts-pattern": "5.9.0",
36
- "@bamboocss/config": "^1.51.1",
37
- "@bamboocss/core": "^1.51.1",
38
- "@bamboocss/extractor": "1.51.1",
39
- "@bamboocss/logger": "1.51.1",
40
- "@bamboocss/shared": "1.51.1",
41
- "@bamboocss/ts-ast": "1.51.1",
42
- "@bamboocss/types": "1.51.1"
36
+ "@bamboocss/config": "^1.51.3",
37
+ "@bamboocss/core": "^1.51.3",
38
+ "@bamboocss/extractor": "1.51.3",
39
+ "@bamboocss/logger": "1.51.3",
40
+ "@bamboocss/shared": "1.51.3",
41
+ "@bamboocss/ts-ast": "1.51.3",
42
+ "@bamboocss/types": "1.51.3"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@typescript/api": "npm:typescript@7.1.0-dev.20260826.1",
46
46
  "ts-morph": "28.0.0",
47
- "@bamboocss/generator": "1.51.1",
48
- "@bamboocss/plugin-svelte": "1.51.1",
49
- "@bamboocss/plugin-vue": "1.51.1"
47
+ "@bamboocss/generator": "1.51.3",
48
+ "@bamboocss/plugin-svelte": "1.51.3",
49
+ "@bamboocss/plugin-vue": "1.51.3"
50
50
  },
51
51
  "scripts": {
52
52
  "build": "tsdown src/index.ts --format=esm,cjs --dts",