synthesisui 0.16.331 → 0.16.334

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.
@@ -42,6 +42,7 @@ import { variantCallsIn } from "../doctor/variant-calls.js";
42
42
  import { transcribeVariants } from "../doctor/variant-read.js";
43
43
  import { frontierKind, packageRoot } from "../frontier-kind.js";
44
44
  import { keyframesInSheets } from "../global-keyframes.js";
45
+ import { globalClassesWorn } from "../global-wear.js";
45
46
  import { withLibraryStructure } from "../library-structure.js";
46
47
  import { mergeCensus } from "../merge-census.js";
47
48
  import { claimName } from "../name-claim.js";
@@ -1880,7 +1881,20 @@ export async function takeCensus(root, opts) {
1880
1881
  */
1881
1882
  const declaredForms = await readDeclaredForms(root);
1882
1883
  const ledger = buildLedger(opts?.cli ?? "unknown", judgeFragments([...fragments.flat(), ...styleFiles.flatMap((s) => s.fragments)], declaredValues, admittedStyles, {
1883
- wornGlobal: globalClassesClaimed,
1884
+ /**
1885
+ * QUEM VESTE, REIVINDICA - e a resposta vem da SAÍDA, não do caminho.
1886
+ *
1887
+ * `globalClassesClaimed` é o que os caminhos foram lembrando de registrar, e ele perdia
1888
+ * tudo que chega por tabela de variantes: no sistema do dono, 20 das 23 classes globais
1889
+ * são vestidas SÓ assim, e as 80 declarações delas apareciam na Coverage como não lidas
1890
+ * enquanto chegavam ao componente. `globalClassesWorn` deriva do `looks` já montado, então
1891
+ * um caminho novo não precisa lembrar de nada. A união mantém o que só o island e o
1892
+ * sketch sabem.
1893
+ */
1894
+ wornGlobal: new Set([
1895
+ ...globalClassesClaimed,
1896
+ ...globalClassesWorn(looks, globalClasses),
1897
+ ]),
1884
1898
  islandRead: islandClassesRead,
1885
1899
  refused: new Set(skips.map((s) => s.file)),
1886
1900
  },
@@ -169,6 +169,26 @@ function rules(css, media = null, out = []) {
169
169
  }
170
170
  return out;
171
171
  }
172
+ /**
173
+ * UMA DECLARAÇÃO DE CUSTOM PROPERTY É UMA DECLARAÇÃO - e descartá-la fazia a receita
174
+ * apontar para um nome que a nossa saída não declara.
175
+ *
176
+ * O padrão anterior era `^-?[a-z][a-z-]*$`: um hífen inicial (o prefixo de fabricante),
177
+ * nunca dois. Toda `--nome` caía fora, em `base`, em `dark` e em `states`, para toda
178
+ * classe. Medido no codelevel em 29/08: 0 de 23 classes globais carregavam uma, e a folha
179
+ * declara duas dentro de `@utility holo-card`.
180
+ *
181
+ * O QUE O CLIENTE VIVIA: a receita do `Card variant="holo"` sai com
182
+ * `background: linear-gradient(var(--holo-inner-bg), …)` e a variável não era declarada em
183
+ * lugar nenhum da nossa saída - nem o claro `#ffffff`, nem o escuro `#1a1a21`. Um `var()`
184
+ * sem fallback para propriedade não declarada invalida a declaração em tempo de valor
185
+ * computado, e o `background` volta ao inicial: o preenchimento E a borda cônica somem.
186
+ *
187
+ * Isto NÃO a promove a foundation. Ela continua morando na classe, e é `parseSchemeBlocks`
188
+ * quem decide o que é vocabulário de documento - lá a régua exige escopo de documento, e
189
+ * uma variável de componente nunca passa por ela.
190
+ */
191
+ const PROPERTY = /^(--[a-zA-Z0-9_-]+|-?[a-z][a-z-]*)$/;
172
192
  /** `prop: value;` pairs, in the camelCase the contract uses. */
173
193
  function declarations(body) {
174
194
  const out = {};
@@ -194,12 +214,21 @@ function declarations(body) {
194
214
  continue;
195
215
  const prop = piece.slice(0, colon).trim();
196
216
  const value = piece.slice(colon + 1).trim();
197
- if (!/^-?[a-z][a-z-]*$/.test(prop) || !value)
217
+ if (!PROPERTY.test(prop) || !value)
198
218
  continue;
199
219
  // A value that could break out of the stylesheet is not a value we carry.
200
220
  if (/[<>{}@]/.test(value))
201
221
  continue;
202
- out[camel(prop)] = value;
222
+ /**
223
+ * O NOME DE UMA CUSTOM PROPERTY É A CHAVE DE UMA REFERÊNCIA, e por isso ele não passa
224
+ * pelo `camel`.
225
+ *
226
+ * `--holo-inner-bg` viraria `-HoloInnerBg`, e o `var(--holo-inner-bg)` que a mesma regra
227
+ * escreve deixaria de encontrá-la. Uma propriedade padrão é um NOME que o contrato
228
+ * escreve em camelCase e o compilador devolve em kebab; uma custom property é um
229
+ * IDENTIFICADOR que o autor escolheu, e ela viaja verbatim nas duas pontas.
230
+ */
231
+ out[prop.startsWith("--") ? prop : camel(prop)] = value;
203
232
  }
204
233
  return out;
205
234
  }
@@ -284,6 +284,32 @@ const STRUCTURE = new Set([
284
284
  "inline",
285
285
  "contents",
286
286
  ]);
287
+ /**
288
+ * QUAL CLASSE A REGRA ALVEJA - a última do seletor, que é a que o navegador pinta.
289
+ *
290
+ * O QUE O CLIENTE VIVIA: a régua anterior era `^\.classe\s*{`, então só a forma mais simples de
291
+ * seletor contava. Uma regra de FACE ESCURA se escreve `html.dark .plate { … }` e uma de estado
292
+ * `.plate:hover { … }` - as duas chegam ao componente pelo leitor de classe global, e as duas
293
+ * apareciam na Coverage como não lidas. Medido no corpus em 29/08: das 4 declarações do app de
294
+ * face escura, 2 eram reconhecidas e 2 não, e as 2 perdidas eram exatamente a face escura.
295
+ *
296
+ * A ÚLTIMA, e não qualquer uma: em `.plate .interna` quem recebe a declaração é `.interna`, e
297
+ * dizer que a regra foi lida porque `.plate` é vestida reivindicaria o que não chegou. Em
298
+ * `html.dark .plate` o alvo é `.plate`, e o `dark` do prefixo é escopo, não alvo.
299
+ *
300
+ * Vírgula é uma LISTA de alvos: basta um deles ser vestido para a declaração chegar em algum lugar.
301
+ */
302
+ function targetClass(text) {
303
+ const brace = text.indexOf("{");
304
+ const selector = brace === -1 ? text : text.slice(0, brace);
305
+ for (const group of selector.split(",")) {
306
+ const classes = group.match(/\.[A-Za-z][\w-]*/g);
307
+ /** Sem o ponto: o nome que `globalClasses` indexa. */
308
+ if (classes?.length)
309
+ return classes[classes.length - 1].slice(1);
310
+ }
311
+ return null;
312
+ }
287
313
  /**
288
314
  * UMA FORMA DECLARADA POR ELE RESOLVE ISTO? - o portão que transforma `computed` em lido.
289
315
  *
@@ -336,7 +362,7 @@ forms = []) {
336
362
  * era a última ocorrência de `value-not-read` do repo real (12/08).
337
363
  */
338
364
  if (f.shape === "css" && f.reason === "shape-not-read") {
339
- const cls = /^\.([A-Za-z][\w-]*)\s*\{/.exec(f.text)?.[1];
365
+ const cls = targetClass(f.text);
340
366
  if (cls && wornGlobal.has(cls)) {
341
367
  const { reason: _clear, ...rest } = f;
342
368
  return { ...rest, read: true };
@@ -28,7 +28,11 @@
28
28
  */
29
29
  import { READER } from "../reader-version.js";
30
30
  import { formOf } from "./form-identity.js";
31
- const SHAPES = [
31
+ /**
32
+ * AS FORMAS QUE O CONTADOR CONHECE, e a lista é exportada para o corpus dourado poder cobrar
33
+ * uma forma nova sem que ninguém lembre de copiar o nome dela para lá.
34
+ */
35
+ export const SHAPES = [
32
36
  "class",
33
37
  "template",
34
38
  "inline",
@@ -1,13 +1,10 @@
1
1
  import { parseClass } from "./doctor/transcribe.js";
2
- export function wearGlobal(classes, globals,
3
- /** Registra quais classes a folha global reivindicou, para o juiz de duplicidade. */
4
- claimed) {
2
+ export function wearGlobal(classes, globals) {
5
3
  const worn = { base: {}, dark: {}, states: {} };
6
4
  for (const cls of classes) {
7
5
  const rule = globals.get(cls);
8
6
  if (!rule)
9
7
  continue;
10
- claimed?.add(cls);
11
8
  Object.assign(worn.base, rule.base);
12
9
  Object.assign(worn.dark, rule.dark);
13
10
  for (const [state, block] of Object.entries(rule.states))
@@ -42,3 +39,41 @@ globals) {
42
39
  states: Object.fromEntries([...new Set([...Object.keys(worn.states), ...Object.keys(t.states)])].map((k) => [k, { ...worn.states[k], ...t.states[k] }])),
43
40
  };
44
41
  }
42
+ /**
43
+ * QUAL CLASSE DA FOLHA GLOBAL ALGUM COMPONENTE VESTE - derivado da SAÍDA, não coletado no caminho.
44
+ *
45
+ * O QUE O CLIENTE VIVIA: a plataforma dizia não saber ler o que ela já lia. No sistema do dono, 20
46
+ * das 23 classes globais são vestidas SÓ por tabela de variantes - `stroke-text`, `text-grad-fire`,
47
+ * `holo-card`, `megaword` e as outras 16, somando 80 declarações. Todas chegavam ao componente, e
48
+ * todas apareciam na Coverage como não lidas, com a triagem mandando escrever *"a reader here is a
49
+ * new module"* para um leitor que já existe. Uma lacuna FALSA custa o mesmo que uma escondida: manda
50
+ * alguém consertar o que não está quebrado.
51
+ *
52
+ * POR QUE DERIVAR, e não registrar no caminho. A reivindicação era um `Set` opcional que `wearGlobal`
53
+ * aceitava e nenhum dos dois chamadores passava - o mesmo defeito do argumento que dá para esquecer.
54
+ * Fechar a porta aqui não é passar o argumento nos dois lugares: é parar de perguntar ao CAMINHO e
55
+ * perguntar à SAÍDA. Uma classe foi vestida quando ela aparece no look - no markup do componente ou
56
+ * na camada de uma opção de variante -, e um leitor futuro que faça a classe chegar lá reivindica
57
+ * sozinho, sem lembrar de nada.
58
+ *
59
+ * OS DOIS LUGARES onde uma classe existe num look, e são só estes: `sketch[].classes`, que é o
60
+ * markup dele verbatim, e `layers[].classes`, que é a tabela de variantes.
61
+ */
62
+ export function globalClassesWorn(looks, globals) {
63
+ const worn = new Set();
64
+ if (!globals || globals.size === 0)
65
+ return worn;
66
+ const claim = (cls) => {
67
+ if (cls && globals.has(cls))
68
+ worn.add(cls);
69
+ };
70
+ for (const look of Object.values(looks)) {
71
+ for (const node of look.sketch ?? [])
72
+ for (const cls of (node.classes ?? "").split(/\s+/))
73
+ claim(cls);
74
+ for (const layer of look.layers ?? [])
75
+ for (const cls of layer.classes ?? [])
76
+ claim(cls);
77
+ }
78
+ return worn;
79
+ }
@@ -367,7 +367,7 @@ export const CHECKER_SINCE = "0.16.308";
367
367
  * nunca era alcançado. Medido: 1134 componentes, 77 mudaram, e a receita que o cliente recebe muda
368
368
  * com eles. Uma medição anterior não produz o conserto, então a marca sobe.
369
369
  */
370
- export const READER_SINCE = "0.16.331";
370
+ export const READER_SINCE = "0.16.334";
371
371
  /**
372
372
  * O QUE ESTÁ INSTALADO AQUI FICOU PARA TRÁS - e as DUAS condições que fazem isso ser verdade.
373
373
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.331",
3
+ "version": "0.16.334",
4
4
  "description": "Bring SynthesisUI design systems into any project - tokens, typed components, whole pages and an agent-ready CLAUDE.md manifest.",
5
5
  "type": "module",
6
6
  "bin": {