synthesisui 0.16.355 → 0.16.357

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.
@@ -150,10 +150,38 @@ const BECAUSE = {
150
150
  * look, e reter as duas cópias é o que dobraria o censo.
151
151
  */
152
152
  /**
153
- * TETO DE FORMAS POR GRUPO. Medido: as 706 folhas do app inteiro comprimem 18 473 declarações em
154
- * 194 formas - 64 por grupo cobre as populações reais com folga e segura o patológico.
153
+ * TETO DE FORMAS POR GRUPO - o MESMO número do texto, e a razão de serem iguais é a razão de os dois
154
+ * existirem: proteger contra um censo patológico, não escolher quanto do repositório dele viaja.
155
+ *
156
+ * ERA 64, sobre uma medição que não era a deste campo: *"as 706 folhas do app inteiro comprimem
157
+ * 18 473 declarações em 194 formas - 64 por grupo cobre as populações reais com folga"*. As 194 são
158
+ * do APP INTEIRO; o teto é POR GRUPO, e um grupo concentra muito mais. Remedido em 03/09, com o
159
+ * teto solto, o maior grupo de cada população:
160
+ *
161
+ * web-subscribe css/component-not-admitted 1 480 formas
162
+ * wellcell-official-app css/shape-not-read 752
163
+ * frontend-hub/dashboard css/component-not-admitted 245
164
+ * web-onboarding css/shape-not-read 15
165
+ *
166
+ * Com 64, o que chegava era 424 de 2 481 formas no `web-subscribe` (17%), 124 de 812 no `wellcell`
167
+ * (15%) e 230 de 411 no `frontend-hub` (56%).
168
+ *
169
+ * POR QUE A FORMA E NÃO O TEXTO, que é a escolha que este número representa. Subir `DISTINCT_CAP`
170
+ * para cobrir os textos do `web-subscribe` custaria **+1,12 MB** num censo de 1,50 MB (+75%), e
171
+ * levaria o texto-fonte dele de 67% para 81% do arquivo - 18 426 declarações verbatim, que é o CSS
172
+ * dele praticamente inteiro. Cobrir todas as FORMAS custa **+93 KB** (+6%), doze vezes menos, e
173
+ * entrega o que um leitor novo precisa: `form-identity` existe porque *"quem ensina a ler
174
+ * `text-<word>-<n>` ensinou as centenas de uma vez"*.
175
+ *
176
+ * E A FORMA TEM OS VALORES ABSTRAÍDOS - `background: <gradient>`, `text-<word>-<n>` -, então
177
+ * carregá-la inteira não muda a resposta que a gente dá quando um cliente pergunta se guardamos o
178
+ * código dele. Carregar o texto inteiro mudaria.
179
+ *
180
+ * O TETO CONTINUA EXISTINDO, e `formsTotal` continua dizendo quando ele corta (`INV-COB-14`): 4 096
181
+ * é 2,7x o maior grupo medido, o que segura o patológico sem dimensionar pela amostra - que foi
182
+ * exatamente o erro que escolheu 4096 para o texto em 24/08 e 64 para a forma.
155
183
  */
156
- const FORM_CAP = 64;
184
+ const FORM_CAP = DISTINCT_CAP;
157
185
  export function buildLedger(cli, seen,
158
186
  /**
159
187
  * OS NOMES QUE ELE DECLARA - para a contagem de `withTheirTokens`.
@@ -59,23 +59,49 @@ const segments = (name) => name.replace(/^--/, "").split("-");
59
59
  *
60
60
  * 1. quantos segmentos ele compartilha com o nosso token daquela família
61
61
  * `--ds-radius-xs` puxa `--radius-xs` (2) e não `--spacing` (0)
62
- * 2. a convenção dominante dele - o primeiro segmento mais frequente entre os tokens dele
62
+ * 2. quantos segmentos dele são um PAPEL que este sistema declara - ver `roles`
63
+ * 3. a convenção dominante dele - o primeiro segmento mais frequente entre os tokens dele
63
64
  * no repo real, `--color-*` (57) contra `--dashboard-*` (25)
64
- * 3. ordem de declaração, que é o desempate que sempre existe e nunca inventa
65
+ * 4. ordem de declaração, que é o desempate que sempre existe e nunca inventa
66
+ *
67
+ * O CRITÉRIO 2 NASCEU DE UMA DECISÃO DO DONO (03/09), e o critério 1 não alcançava o caso. No
68
+ * sistema dele `#f59e0b` é `--color-tier-gold` E `--color-feedback-warning`, e medindo o censo:
69
+ * `tier-gold` tem 59 menções contra 7, e uma escada própria (bronze 13, prata 13). Pela contagem
70
+ * bruta ele venceria - e vencia, sempre que o nosso token daquele valor não existisse para o
71
+ * critério 1 comparar: aí caía na ORDEM DE DECLARAÇÃO, e `tier-gold` vem antes no CSS dele.
72
+ *
73
+ * A ESCOLHA NÃO É PELO MAIS FREQUENTE, É PELO ERRO QUE SE ANUNCIA. `feedback-warning` escrito num
74
+ * badge de nível mostra "warning" onde devia ser ouro, e quem lê corrige. `tier-gold` escrito num
75
+ * alerta pinta a cor CERTA com o nome de outro domínio - a tela fica visualmente correta e ninguém
76
+ * corrige nunca. Entre dois nomes dele, o que descreve um PAPEL erra alto; o que descreve um
77
+ * domínio de negócio erra calado.
65
78
  */
66
- function pick(candidates, ours, convention) {
79
+ function pick(candidates, ours, convention,
80
+ /**
81
+ * OS PAPÉIS QUE ESTE SISTEMA DECLARA - o critério 2, e o único que decide quando não há token
82
+ * nosso daquele valor para comparar.
83
+ *
84
+ * DERIVADO, nunca escrito: são os segmentos finais dos papéis semânticos do próprio sistema, e
85
+ * por isso a regra vale em qualquer projeto. Um projeto que chame o aviso de `atencao` puxa
86
+ * `atencao`; nenhum nome de família deste ou daquele repositório entra aqui (`INV-GERAL-07`).
87
+ */
88
+ roles) {
67
89
  const mine = ours ? new Set(segments(ours)) : null;
68
90
  let best = candidates[0];
69
- let bestScore = [-1, -1];
91
+ let bestScore = [-1, -1, -1];
70
92
  for (const name of candidates) {
71
93
  const parts = segments(name);
72
94
  const shared = mine ? parts.filter((p) => mine.has(p)).length : 0;
73
95
  const score = [
74
96
  shared,
97
+ parts.filter((p) => roles.has(p)).length,
75
98
  convention.get(parts[0] ?? "") ?? 0,
76
99
  ];
77
100
  if (score[0] > bestScore[0] ||
78
- (score[0] === bestScore[0] && score[1] > bestScore[1])) {
101
+ (score[0] === bestScore[0] && score[1] > bestScore[1]) ||
102
+ (score[0] === bestScore[0] &&
103
+ score[1] === bestScore[1] &&
104
+ score[2] > bestScore[2])) {
79
105
  best = name;
80
106
  bestScore = score;
81
107
  }
@@ -106,14 +132,29 @@ function pick(candidates, ours, convention) {
106
132
  * sistema do dono, `#f59e0b` é `--color-tier-gold` E `--color-feedback-warning` - dois conceitos
107
133
  * dele, gamificação e estado -, e o relatório dizia `→ {color.tier-gold}` como se fosse fato.
108
134
  */
109
- function escolha(candidates, ours, convention) {
110
- const name = pick(candidates, ours, convention);
135
+ function escolha(candidates, ours, convention, roles) {
136
+ const name = pick(candidates, ours, convention, roles);
111
137
  return { name, also: candidates.filter((c) => c !== name) };
112
138
  }
113
139
  export function theirNames(ours, theirs) {
114
140
  const out = new Map();
115
141
  if (theirs.byName.size === 0)
116
142
  return out;
143
+ /**
144
+ * OS PAPÉIS QUE ESTE SISTEMA DECLARA, derivados dos NOSSOS nomes - ver o critério 2 de `pick`.
145
+ *
146
+ * O último segmento de cada token semântico é o papel: `--ds-color-semantic-warning` dá
147
+ * `warning`. Sai daqui e não de uma lista escrita porque uma lista seria o nosso vocabulário
148
+ * virando régua - um sistema que chame o aviso de `atencao` tem que puxar `atencao`.
149
+ */
150
+ const roles = new Set();
151
+ for (const name of ours.byName.keys()) {
152
+ if (!name.includes("-semantic-"))
153
+ continue;
154
+ const last = segments(name).at(-1);
155
+ if (last)
156
+ roles.add(last);
157
+ }
117
158
  /** A convenção dominante dele, contada e não suposta - ver `pick`. */
118
159
  const convention = new Map();
119
160
  for (const name of theirs.byName.keys()) {
@@ -151,7 +192,7 @@ export function theirNames(ours, theirs) {
151
192
  : candidates.filter((n) => familySays(kind, n));
152
193
  if (usable.length === 0)
153
194
  continue;
154
- out.set(key, escolha(usable, name, convention));
195
+ out.set(key, escolha(usable, name, convention, roles));
155
196
  }
156
197
  }
157
198
  for (const [value, candidates] of theirs.byValue) {
@@ -161,7 +202,7 @@ export function theirNames(ours, theirs) {
161
202
  const key = `${kind}:${value}`;
162
203
  if (out.has(key))
163
204
  continue;
164
- out.set(key, escolha(candidates, null, convention));
205
+ out.set(key, escolha(candidates, null, convention, roles));
165
206
  }
166
207
  }
167
208
  return out;
@@ -616,7 +616,24 @@ export const CHECKER_SINCE = "0.16.308";
616
616
  * QUEM NÃO É AFETADO: quem não escreve `rotate-x`, `skew-x/y` ou `scale-x/y`. As formas SEM eixo -
617
617
  * `rotate-180`, `scale-95` - não se movem, e há asserção disso.
618
618
  */
619
- export const READER_SINCE = "0.16.354";
619
+ /**
620
+ * 0.16.355 -> 0.16.356 em 03/09 (`INV-COB-14`): a FORMA de cada declaração não lida passa a viajar
621
+ * inteira, e é a decisão 24 no seu outro lado - declarar não move a marca, AMPLIAR move.
622
+ *
623
+ * O QUE ELE GANHA COM O `sync`: o teto de formas por grupo era 64, sobre uma medição do app inteiro
624
+ * (194 formas) aplicada a um limite POR GRUPO. Remedido em 03/09, o maior grupo do `web-subscribe`
625
+ * tem 1 480 formas - então chegavam 424 de 2 481 (17%), 124 de 812 no `wellcell` (15%) e 230 de 411
626
+ * no `frontend-hub` (56%). Um leitor novo escrito sobre o censo guardado alcançava um sexto do que
627
+ * existe no repositório dele, e o censo não tinha como dizer isso até `formsTotal` existir.
628
+ *
629
+ * POR QUE A FORMA E NÃO O TEXTO: cobrir os textos do `web-subscribe` custava +1,12 MB num censo de
630
+ * 1,50 MB (+75%), levando o texto-fonte dele a 81% do arquivo. Cobrir as formas custa +93 KB (+6%),
631
+ * e a forma tem os valores abstraídos - ela ensina o leitor sem guardar o código dele.
632
+ *
633
+ * QUEM NÃO É AFETADO: quem tem menos de 4 096 formas em todo grupo - `web-onboarding` já chegava
634
+ * com 39 de 39. O `sync` daquele repositório não muda um byte.
635
+ */
636
+ export const READER_SINCE = "0.16.356";
620
637
  /**
621
638
  * O QUE ESTÁ INSTALADO AQUI FICOU PARA TRÁS - e as DUAS condições que fazem isso ser verdade.
622
639
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synthesisui",
3
- "version": "0.16.355",
3
+ "version": "0.16.357",
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": {