@bamboocss/parser 1.33.0 → 1.34.1

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
@@ -884,6 +884,15 @@ var ParserResult = class {
884
884
  * absent from the element — silently. Only the surprising half is collected; see `setCss`.
885
885
  */
886
886
  unresolved = [];
887
+ /**
888
+ * Calls to a name the pattern or recipe entrypoint no longer exports.
889
+ *
890
+ * Separate from `unresolved`, which grades a call the build *did* see and could only
891
+ * partly resolve. These it saw and could not resolve at all: the binding is dead, so every
892
+ * rule the call would have contributed is absent rather than incomplete. Reported by
893
+ * `assertNoDeadCalls` rather than warned about, for that reason.
894
+ */
895
+ deadCalls = [];
887
896
  constructor(context, encoder) {
888
897
  this.context = context;
889
898
  this.encoder = encoder ?? context.encoder;
@@ -1261,6 +1270,7 @@ function createParser(context) {
1261
1270
  }
1262
1271
  });
1263
1272
  });
1273
+ parserResult.deadCalls = file.getDeadCalls();
1264
1274
  return parserResult;
1265
1275
  };
1266
1276
  }
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Context, ParserOptions, StyleDecoder, Stylesheet } from "@bamboocss/core";
1
+ import { Context, DeadImport, ParserOptions, StyleDecoder, Stylesheet } from "@bamboocss/core";
2
2
  import { ArtifactId, BambooHooks, ConfigTsOptions, CssArtifactType, LoadConfigResult, ParserResultConfigureOptions, ParserResultInterface, ResultItem, Runtime, SpecFile, SpecType, SpecTypeMap } from "@bamboocss/types";
3
3
  import { FileSystemRefreshResult, Project as Project$1, ProjectOptions as ProjectOptions$1, SourceFile } from "ts-morph";
4
4
 
@@ -39,10 +39,7 @@ declare class Generator extends Context {
39
39
  * `keep` carries references this cannot see for itself; see `collectTokenReferences`.
40
40
  */
41
41
  pruneTokens: (sheet: Stylesheet, keep?: Set<string>, tokensReachableFromJs?: boolean) => {
42
- removed: number;
43
- kept: number;
44
- removedProperties?: undefined;
45
- } | {
42
+ reachable: Set<string> | undefined;
46
43
  removed: number;
47
44
  removedProperties: number;
48
45
  kept: number;
@@ -65,8 +62,21 @@ declare class Generator extends Context {
65
62
  * unused for want of a utility to reference it.
66
63
  *
67
64
  * `keep` carries names this cannot see for itself; see `collectKeyframeReferences`.
65
+ *
66
+ * `reachableVars` is `pruneTokens`' answer about custom properties, which has to be handed
67
+ * over rather than re-derived here. A token kept by a reader outside the stylesheet — a
68
+ * `token()` call, a `prune.keepTokens` pattern, a theme, a `globalCss` export — is
69
+ * reachable to that pass and invisible to this one, so deriving it again from the css
70
+ * deletes the `@keyframes` out from under a declaration that ships. Every caller that
71
+ * prunes both hands it over.
72
+ *
73
+ * Omitting it falls back to what `prune.tokens` implies. Under `off` that is `'all'`: no
74
+ * token declaration is removable, so each one ships and keeps the keyframe it names —
75
+ * and `off` is precisely the setting chosen because something outside the stylesheet
76
+ * reads them. Otherwise it is the css alone, which is what a caller running this pass
77
+ * without the other one is asking for.
68
78
  */
69
- pruneKeyframes: (sheet: Stylesheet, keep?: Set<string>) => {
79
+ pruneKeyframes: (sheet: Stylesheet, keep?: Set<string>, reachableVars?: Set<string> | "all") => {
70
80
  removed: number;
71
81
  kept: number;
72
82
  } | undefined;
@@ -121,6 +131,51 @@ declare class Generator extends Context {
121
131
  private getAlwaysKeptTokenVars;
122
132
  getParserCss: (decoder: StyleDecoder) => string;
123
133
  getCss: (stylesheet?: Stylesheet) => string;
134
+ /**
135
+ * Fail on a style value shaped like a token path that names no token.
136
+ *
137
+ * Only under `unresolvedToken: 'error'` — see that option for why this one is graded and a
138
+ * dead binding is not.
139
+ *
140
+ * Two sources, because neither sees the whole build.
141
+ *
142
+ * **Atomic styles are read off the decoded sheet** rather than accumulated as `transform`
143
+ * runs, and that is the load-bearing part for them. A `Context` outlives rebuilds while the
144
+ * decoder memoizes each atom by hash, so on the second build of the same source `transform`
145
+ * is never re-entered: an accumulating record either keeps a finding past the edit that
146
+ * fixed it — wedging a dev server — or is cleared and then never refilled, which passes a
147
+ * build whose source is still broken. That second one is the worse failure and is what an
148
+ * earlier version of this did.
149
+ *
150
+ * `decoder.atomic` has neither problem, because it is not a record of what happened — it is
151
+ * what the sheet is built from, and each result keeps the `prop` and `value` it was written
152
+ * with. So the question asked is the one that matters: does the stylesheet *being emitted*
153
+ * contain a declaration the browser will drop.
154
+ *
155
+ * Within a watch process that set is cumulative, and so is the css: extraction is additive,
156
+ * so the rule for a style deleted from source is still in the sheet until the process
157
+ * restarts. This reports the same way for the same reason — the declaration really is still
158
+ * in the file being written, and saying otherwise would be a check that disagreed with its
159
+ * own output. A production build is a fresh process and sees only what its source asked
160
+ * for.
161
+ *
162
+ * **Config-derived styles are not in that set at all**, which is the gap this used to have.
163
+ * `globalCss`, the reset, config recipes and compositions serialize through
164
+ * `transformStyles`, and that clones the decoder — so their atoms land in a throwaway and
165
+ * `decoder.atomic` never hears about them. Reading only the sheet made `'error'` *quieter*
166
+ * than the default on exactly those styles: the warning was suppressed in favour of a check
167
+ * that could not see them, so a bad token in `globalCss` warned with the option unset and
168
+ * then passed silently with it set to `'error'`. `utility.unresolvedTokens` is the record of
169
+ * what only `transform` can see; see it for why accumulating is right for that half.
170
+ *
171
+ * Both halves key on `property:path` with shorthands resolved, so a value that does reach
172
+ * both — every atomic style is transformed once before it is memoized — is one finding.
173
+ *
174
+ * Here rather than beside the asserts in `BambooContext` because this is where the sheet
175
+ * exists: those all run during extraction, before anything has been decoded. Every path
176
+ * that emits css comes through `getCss`.
177
+ */
178
+ assertNoUnresolvedTokens: () => void;
124
179
  /**
125
180
  * Get CSS for a specific layer from the stylesheet
126
181
  */
@@ -211,6 +266,15 @@ declare class ParserResult implements ParserResultInterface {
211
266
  * absent from the element — silently. Only the surprising half is collected; see `setCss`.
212
267
  */
213
268
  unresolved: UnresolvedStyle[];
269
+ /**
270
+ * Calls to a name the pattern or recipe entrypoint no longer exports.
271
+ *
272
+ * Separate from `unresolved`, which grades a call the build *did* see and could only
273
+ * partly resolve. These it saw and could not resolve at all: the binding is dead, so every
274
+ * rule the call would have contributed is absent rather than incomplete. Reported by
275
+ * `assertNoDeadCalls` rather than warned about, for that reason.
276
+ */
277
+ deadCalls: DeadImport[];
214
278
  constructor(context: ParserOptions, encoder?: ParserOptions['encoder']);
215
279
  append(result: ResultItem): ResultItem;
216
280
  set(name: 'cva' | 'css' | 'sva' | 'token', result: ResultItem): void;
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { FileSystemRefreshResult, Project as Project$1, ProjectOptions as ProjectOptions$1, SourceFile } from "ts-morph";
2
- import { Context, ParserOptions, StyleDecoder, Stylesheet } from "@bamboocss/core";
2
+ import { Context, DeadImport, ParserOptions, StyleDecoder, Stylesheet } from "@bamboocss/core";
3
3
  import { ArtifactId, BambooHooks, ConfigTsOptions, CssArtifactType, LoadConfigResult, ParserResultConfigureOptions, ParserResultInterface, ResultItem, Runtime, SpecFile, SpecType, SpecTypeMap } from "@bamboocss/types";
4
4
 
5
5
  //#region ../generator/dist/index.d.cts
@@ -39,10 +39,7 @@ declare class Generator extends Context {
39
39
  * `keep` carries references this cannot see for itself; see `collectTokenReferences`.
40
40
  */
41
41
  pruneTokens: (sheet: Stylesheet, keep?: Set<string>, tokensReachableFromJs?: boolean) => {
42
- removed: number;
43
- kept: number;
44
- removedProperties?: undefined;
45
- } | {
42
+ reachable: Set<string> | undefined;
46
43
  removed: number;
47
44
  removedProperties: number;
48
45
  kept: number;
@@ -65,8 +62,21 @@ declare class Generator extends Context {
65
62
  * unused for want of a utility to reference it.
66
63
  *
67
64
  * `keep` carries names this cannot see for itself; see `collectKeyframeReferences`.
65
+ *
66
+ * `reachableVars` is `pruneTokens`' answer about custom properties, which has to be handed
67
+ * over rather than re-derived here. A token kept by a reader outside the stylesheet — a
68
+ * `token()` call, a `prune.keepTokens` pattern, a theme, a `globalCss` export — is
69
+ * reachable to that pass and invisible to this one, so deriving it again from the css
70
+ * deletes the `@keyframes` out from under a declaration that ships. Every caller that
71
+ * prunes both hands it over.
72
+ *
73
+ * Omitting it falls back to what `prune.tokens` implies. Under `off` that is `'all'`: no
74
+ * token declaration is removable, so each one ships and keeps the keyframe it names —
75
+ * and `off` is precisely the setting chosen because something outside the stylesheet
76
+ * reads them. Otherwise it is the css alone, which is what a caller running this pass
77
+ * without the other one is asking for.
68
78
  */
69
- pruneKeyframes: (sheet: Stylesheet, keep?: Set<string>) => {
79
+ pruneKeyframes: (sheet: Stylesheet, keep?: Set<string>, reachableVars?: Set<string> | "all") => {
70
80
  removed: number;
71
81
  kept: number;
72
82
  } | undefined;
@@ -121,6 +131,51 @@ declare class Generator extends Context {
121
131
  private getAlwaysKeptTokenVars;
122
132
  getParserCss: (decoder: StyleDecoder) => string;
123
133
  getCss: (stylesheet?: Stylesheet) => string;
134
+ /**
135
+ * Fail on a style value shaped like a token path that names no token.
136
+ *
137
+ * Only under `unresolvedToken: 'error'` — see that option for why this one is graded and a
138
+ * dead binding is not.
139
+ *
140
+ * Two sources, because neither sees the whole build.
141
+ *
142
+ * **Atomic styles are read off the decoded sheet** rather than accumulated as `transform`
143
+ * runs, and that is the load-bearing part for them. A `Context` outlives rebuilds while the
144
+ * decoder memoizes each atom by hash, so on the second build of the same source `transform`
145
+ * is never re-entered: an accumulating record either keeps a finding past the edit that
146
+ * fixed it — wedging a dev server — or is cleared and then never refilled, which passes a
147
+ * build whose source is still broken. That second one is the worse failure and is what an
148
+ * earlier version of this did.
149
+ *
150
+ * `decoder.atomic` has neither problem, because it is not a record of what happened — it is
151
+ * what the sheet is built from, and each result keeps the `prop` and `value` it was written
152
+ * with. So the question asked is the one that matters: does the stylesheet *being emitted*
153
+ * contain a declaration the browser will drop.
154
+ *
155
+ * Within a watch process that set is cumulative, and so is the css: extraction is additive,
156
+ * so the rule for a style deleted from source is still in the sheet until the process
157
+ * restarts. This reports the same way for the same reason — the declaration really is still
158
+ * in the file being written, and saying otherwise would be a check that disagreed with its
159
+ * own output. A production build is a fresh process and sees only what its source asked
160
+ * for.
161
+ *
162
+ * **Config-derived styles are not in that set at all**, which is the gap this used to have.
163
+ * `globalCss`, the reset, config recipes and compositions serialize through
164
+ * `transformStyles`, and that clones the decoder — so their atoms land in a throwaway and
165
+ * `decoder.atomic` never hears about them. Reading only the sheet made `'error'` *quieter*
166
+ * than the default on exactly those styles: the warning was suppressed in favour of a check
167
+ * that could not see them, so a bad token in `globalCss` warned with the option unset and
168
+ * then passed silently with it set to `'error'`. `utility.unresolvedTokens` is the record of
169
+ * what only `transform` can see; see it for why accumulating is right for that half.
170
+ *
171
+ * Both halves key on `property:path` with shorthands resolved, so a value that does reach
172
+ * both — every atomic style is transformed once before it is memoized — is one finding.
173
+ *
174
+ * Here rather than beside the asserts in `BambooContext` because this is where the sheet
175
+ * exists: those all run during extraction, before anything has been decoded. Every path
176
+ * that emits css comes through `getCss`.
177
+ */
178
+ assertNoUnresolvedTokens: () => void;
124
179
  /**
125
180
  * Get CSS for a specific layer from the stylesheet
126
181
  */
@@ -211,6 +266,15 @@ declare class ParserResult implements ParserResultInterface {
211
266
  * absent from the element — silently. Only the surprising half is collected; see `setCss`.
212
267
  */
213
268
  unresolved: UnresolvedStyle[];
269
+ /**
270
+ * Calls to a name the pattern or recipe entrypoint no longer exports.
271
+ *
272
+ * Separate from `unresolved`, which grades a call the build *did* see and could only
273
+ * partly resolve. These it saw and could not resolve at all: the binding is dead, so every
274
+ * rule the call would have contributed is absent rather than incomplete. Reported by
275
+ * `assertNoDeadCalls` rather than warned about, for that reason.
276
+ */
277
+ deadCalls: DeadImport[];
214
278
  constructor(context: ParserOptions, encoder?: ParserOptions['encoder']);
215
279
  append(result: ResultItem): ResultItem;
216
280
  set(name: 'cva' | 'css' | 'sva' | 'token', result: ResultItem): void;
package/dist/index.mjs CHANGED
@@ -883,6 +883,15 @@ var ParserResult = class {
883
883
  * absent from the element — silently. Only the surprising half is collected; see `setCss`.
884
884
  */
885
885
  unresolved = [];
886
+ /**
887
+ * Calls to a name the pattern or recipe entrypoint no longer exports.
888
+ *
889
+ * Separate from `unresolved`, which grades a call the build *did* see and could only
890
+ * partly resolve. These it saw and could not resolve at all: the binding is dead, so every
891
+ * rule the call would have contributed is absent rather than incomplete. Reported by
892
+ * `assertNoDeadCalls` rather than warned about, for that reason.
893
+ */
894
+ deadCalls = [];
886
895
  constructor(context, encoder) {
887
896
  this.context = context;
888
897
  this.encoder = encoder ?? context.encoder;
@@ -1260,6 +1269,7 @@ function createParser(context) {
1260
1269
  }
1261
1270
  });
1262
1271
  });
1272
+ parserResult.deadCalls = file.getDeadCalls();
1263
1273
  return parserResult;
1264
1274
  };
1265
1275
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bamboocss/parser",
3
- "version": "1.33.0",
3
+ "version": "1.34.1",
4
4
  "description": "The static parser for bamboo css",
5
5
  "homepage": "https://bamboocss.com",
6
6
  "license": "MIT",
@@ -34,17 +34,17 @@
34
34
  "dependencies": {
35
35
  "ts-morph": "28.0.0",
36
36
  "ts-pattern": "5.9.0",
37
- "@bamboocss/config": "^1.33.0",
38
- "@bamboocss/core": "^1.33.0",
39
- "@bamboocss/extractor": "1.33.0",
40
- "@bamboocss/logger": "1.33.0",
41
- "@bamboocss/shared": "1.33.0",
42
- "@bamboocss/types": "1.33.0"
37
+ "@bamboocss/config": "^1.34.1",
38
+ "@bamboocss/core": "^1.34.1",
39
+ "@bamboocss/extractor": "1.34.1",
40
+ "@bamboocss/logger": "1.34.1",
41
+ "@bamboocss/shared": "1.34.1",
42
+ "@bamboocss/types": "1.34.1"
43
43
  },
44
44
  "devDependencies": {
45
- "@bamboocss/generator": "1.33.0",
46
- "@bamboocss/plugin-svelte": "1.33.0",
47
- "@bamboocss/plugin-vue": "1.33.0"
45
+ "@bamboocss/generator": "1.34.1",
46
+ "@bamboocss/plugin-svelte": "1.34.1",
47
+ "@bamboocss/plugin-vue": "1.34.1"
48
48
  },
49
49
  "scripts": {
50
50
  "build": "tsdown src/index.ts --format=esm,cjs --dts",