synthesisui 0.16.332 → 0.16.335

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
  },
@@ -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",
@@ -198,10 +198,35 @@ const NON_RENDERING = new Set([
198
198
  */
199
199
  "root",
200
200
  ]);
201
- /** `BaseDialog.Portal` → true. `BaseSelect.Positioner` with `z-50 pt-1` → false. */
201
+ /**
202
+ * `BaseDialog.Portal` → true. `BaseSelect.Positioner` with `z-50 pt-1` → false.
203
+ *
204
+ * AND THE ROLE IS READ AT THE END OF THE NAME, not only as the whole of it. React's own
205
+ * vocabulary composes: a context provider is spelled `ThemeProvider`, `ConfigProvider`,
206
+ * `LocalizationProvider` - never the bare word - and every one of them renders no element
207
+ * at all. Reading only the exact word meant the list named the role and missed every
208
+ * component that carries it.
209
+ *
210
+ * Measured on the two populations before widening (29/08), and the class gate is what keeps
211
+ * it honest - it is still the fact that separates a role from a real box:
212
+ *
213
+ * frontend-hub 14 nodes end in `Provider`, and NONE of them carries a class
214
+ * 3 end in `Root` (`DialogRoot`, `RadioCardRoot`), none with classes
215
+ * codelevel-ui none of either
216
+ *
217
+ * A styled `Positioner` still survives as a real box, which is exactly what happens in
218
+ * their Select - the gate above reads the class list first and answers `false`.
219
+ */
202
220
  export function rendersNothing(tag, classes) {
203
221
  if (classes?.trim())
204
222
  return false;
205
- const member = tag.includes(".") ? tag.split(".").pop() : tag;
206
- return NON_RENDERING.has((member ?? "").toLowerCase());
223
+ const member = (tag.includes(".") ? tag.split(".").pop() : tag)?.toLowerCase();
224
+ if (!member)
225
+ return false;
226
+ if (NON_RENDERING.has(member))
227
+ return true;
228
+ for (const role of NON_RENDERING)
229
+ if (member.endsWith(role))
230
+ return true;
231
+ return false;
207
232
  }
@@ -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.332";
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.332",
3
+ "version": "0.16.335",
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": {