synthesisui 0.16.327 → 0.16.329
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.
|
@@ -318,7 +318,24 @@ export function anatomyFromSketch(sketch, defines,
|
|
|
318
318
|
* from `recharts: ^2.12.0`, since both are spelled the same way. See
|
|
319
319
|
* `frontierOf`.
|
|
320
320
|
*/
|
|
321
|
-
versionOf
|
|
321
|
+
versionOf,
|
|
322
|
+
/**
|
|
323
|
+
* QUAL NÓ JÁ FOI ABSORVIDO EM `base` - ver `CensusLook.consumedAt`, onde o fato nasce.
|
|
324
|
+
*
|
|
325
|
+
* number consuma EXATAMENTE esse nó
|
|
326
|
+
* "none" a coleta mediu e não absorveu nenhum - não consuma nenhum
|
|
327
|
+
* undefined censo LEGADO - a regra antiga, byte a byte
|
|
328
|
+
*
|
|
329
|
+
* `undefined` NUNCA é `"none"`: um censo gravado antes desta medição existir não disse que não
|
|
330
|
+
* absorveu nada; ele não disse nada. Tratá-lo como `"none"` mudaria retroativamente a leitura de
|
|
331
|
+
* 386 componentes num app real, dos quais 26 mudariam de fato - e mudar dado antigo sem uma nova
|
|
332
|
+
* medição é a definição de reinterpretar o passado.
|
|
333
|
+
*
|
|
334
|
+
* Opcional porque 37 dos 39 chamadores são specs que montam um sketch à mão e testam a regra
|
|
335
|
+
* legada de propósito. Os chamadores de PRODUÇÃO são dois, e `anatomy-consumed.guard.spec.ts`
|
|
336
|
+
* nomeia os dois: um parâmetro opcional que se pode esquecer é o defeito que este item desfaz.
|
|
337
|
+
*/
|
|
338
|
+
consumedAt) {
|
|
322
339
|
const notes = [];
|
|
323
340
|
const libraries = [];
|
|
324
341
|
if (!Array.isArray(sketch) || sketch.length === 0)
|
|
@@ -662,10 +679,33 @@ versionOf) {
|
|
|
662
679
|
* root arriving as a sibling (dono, 03/08). The reader stamps which node the
|
|
663
680
|
* component returns - see `SketchNode.root`.
|
|
664
681
|
*/
|
|
665
|
-
|
|
666
|
-
|
|
682
|
+
/**
|
|
683
|
+
* ═══ DADO NOVO NÃO DEDUZ NADA (28/08, T43-b) ═══
|
|
684
|
+
*
|
|
685
|
+
* A linha abaixo era uma dedução por POSIÇÃO - "o nó carimbado, senão o primeiro de d0, senão o
|
|
686
|
+
* zero" - e ela discordava do coletor exatamente onde a âncora falha. Num componente que devolve
|
|
687
|
+
* um Fragment o coletor não absorve nada em `base`, e esta linha consumia um nó mesmo assim: as
|
|
688
|
+
* classes daquele nó caíam no vazio. Medido no `frontend-hub`: 8 componentes.
|
|
689
|
+
*
|
|
690
|
+
* Com o fato, não há o que deduzir. Sem o fato - censo legado - a dedução antiga fica INTEIRA,
|
|
691
|
+
* porque um censo velho não disse "não absorvi nada": ele não disse nada.
|
|
692
|
+
*/
|
|
693
|
+
const top = consumedAt === "none"
|
|
694
|
+
? -1
|
|
695
|
+
: typeof consumedAt === "number"
|
|
696
|
+
? consumedAt
|
|
697
|
+
: /** LEGADO, e esta é a regra antiga sem uma vírgula mudada. */
|
|
698
|
+
(() => {
|
|
699
|
+
const stamped = sketch.findIndex((node) => node?.root);
|
|
700
|
+
return stamped >= 0 ? stamped : roots.length > 0 ? roots[0] : 0;
|
|
701
|
+
})();
|
|
702
|
+
/**
|
|
703
|
+
* `top === -1` é "nenhum nó foi consumido", e então TODO nó de d0 é emitido com as classes dele -
|
|
704
|
+
* que é o conserto: nada se perde e nada é inventado. `roots.filter(at => at !== top)` já devolve
|
|
705
|
+
* todos quando `top` não é um índice, então a mesma linha serve aos dois casos.
|
|
706
|
+
*/
|
|
667
707
|
const read = [
|
|
668
|
-
...(kids[top] ?? []).flatMap((child) => build(child, 0)),
|
|
708
|
+
...(top >= 0 ? (kids[top] ?? []).flatMap((child) => build(child, 0)) : []),
|
|
669
709
|
...roots.filter((at) => at !== top).flatMap((sibling) => build(sibling, 0)),
|
|
670
710
|
];
|
|
671
711
|
/**
|
|
@@ -678,7 +718,7 @@ versionOf) {
|
|
|
678
718
|
* as empty boxes: a Chat that says nothing about messages reads as a component
|
|
679
719
|
* we failed to extract (dono, 01/08).
|
|
680
720
|
*/
|
|
681
|
-
const rootNode = sketch[top];
|
|
721
|
+
const rootNode = top >= 0 ? sketch[top] : undefined;
|
|
682
722
|
if (rootNode?.slot) {
|
|
683
723
|
const only = EXPECTS[String(rootNode.tag ?? "").toLowerCase()];
|
|
684
724
|
/**
|
package/dist/commands/import.js
CHANGED
|
@@ -829,6 +829,22 @@ export async function takeCensus(root, opts) {
|
|
|
829
829
|
if (esize > 0 || etag || esketch.length > 0) {
|
|
830
830
|
looks[extra.name] = {
|
|
831
831
|
...(esketch.length > 0 ? { sketch: esketch } : {}),
|
|
832
|
+
/**
|
|
833
|
+
* O MESMO FATO NO SEGUNDO COMPONENTE DO ARQUIVO - ver `CensusLook.consumedAt`.
|
|
834
|
+
*
|
|
835
|
+
* Escrever só no caminho primário deixaria metade dos looks de um arquivo com dois
|
|
836
|
+
* componentes no estado LEGADO para sempre, e o deriver voltaria a deduzir por posição
|
|
837
|
+
* exatamente neles. Um campo que só metade dos caminhos escreve é um campo que mente
|
|
838
|
+
* sobre o que a medição cobriu.
|
|
839
|
+
*/
|
|
840
|
+
...(esketch.length > 0
|
|
841
|
+
? {
|
|
842
|
+
consumedAt: (() => {
|
|
843
|
+
const at = esketch.findIndex((n) => n.root);
|
|
844
|
+
return at >= 0 ? at : "none";
|
|
845
|
+
})(),
|
|
846
|
+
}
|
|
847
|
+
: {}),
|
|
832
848
|
/**
|
|
833
849
|
* Ver `CensusLook.aside` - o segundo componente do arquivo também.
|
|
834
850
|
*
|
|
@@ -1030,6 +1046,23 @@ export async function takeCensus(root, opts) {
|
|
|
1030
1046
|
* the owner's rule, adopted verbatim (dono, 01/08).
|
|
1031
1047
|
*/
|
|
1032
1048
|
const sketch = sketchOf(src, found[0].name);
|
|
1049
|
+
/**
|
|
1050
|
+
* QUAL NÓ FOI ABSORVIDO EM `base` - o fato, medido onde ele acontece. Ver
|
|
1051
|
+
* `CensusLook.consumedAt`.
|
|
1052
|
+
*
|
|
1053
|
+
* `rootClasses` acha o elemento pela âncora `returnAt` → primeiro `<`, e `sketchOf` carimba
|
|
1054
|
+
* `root` com a MESMA âncora. Quando ela acha um elemento, é o className DELE que entra em
|
|
1055
|
+
* `base` - com classes ou sem, e sem é o caso comum. Quando ela não acha (retorno em
|
|
1056
|
+
* Fragment, ou `returnAt` = -1), nada é absorvido e nenhum nó pode ser consumido.
|
|
1057
|
+
*
|
|
1058
|
+
* Provado nos dois repositórios reais, 139 arquivos: NUNCA existe um caso sem carimbo em que
|
|
1059
|
+
* `rootClasses` tenha lido alguma classe. As duas leituras falham juntas, sempre.
|
|
1060
|
+
*
|
|
1061
|
+
* E o carimbo `root` continua sendo outra coisa - a raiz ESTRUTURAL. Este campo é derivado
|
|
1062
|
+
* dele hoje porque hoje eles coincidem; ele não passa a ser ele.
|
|
1063
|
+
*/
|
|
1064
|
+
const consumedIndex = sketch.findIndex((n) => n.root);
|
|
1065
|
+
const consumed = consumedIndex >= 0 ? consumedIndex : "none";
|
|
1033
1066
|
/**
|
|
1034
1067
|
* THE CSS THE COMPONENT CARRIES INSIDE ITSELF.
|
|
1035
1068
|
*
|
|
@@ -1192,6 +1225,8 @@ export async function takeCensus(root, opts) {
|
|
|
1192
1225
|
}
|
|
1193
1226
|
: {}),
|
|
1194
1227
|
...withoutDark,
|
|
1228
|
+
/** SEMPRE, inclusive `"none"` - ver `CensusLook.consumedAt`: o vazio é a medição. */
|
|
1229
|
+
consumedAt: consumed,
|
|
1195
1230
|
base,
|
|
1196
1231
|
states,
|
|
1197
1232
|
/**
|
|
@@ -3545,7 +3580,9 @@ quiet = false) {
|
|
|
3545
3580
|
*/
|
|
3546
3581
|
const derived = Array.isArray(anatomy) && anatomy.length > 0
|
|
3547
3582
|
? null
|
|
3548
|
-
: anatomyFromSketch(looks[component]?.sketch, resolveRef, (pkg) => deps[pkg]
|
|
3583
|
+
: anatomyFromSketch(looks[component]?.sketch, resolveRef, (pkg) => deps[pkg],
|
|
3584
|
+
/** O fato medido na coleta, ou `undefined` num look legado - ver `CensusLook.consumedAt`. */
|
|
3585
|
+
looks[component]?.consumedAt);
|
|
3549
3586
|
if (derived?.read.length) {
|
|
3550
3587
|
for (const note of derived.notes)
|
|
3551
3588
|
notes.add(note);
|
|
@@ -2253,14 +2253,103 @@ export function rootClasses(source, name) {
|
|
|
2253
2253
|
if (end === -1)
|
|
2254
2254
|
return [];
|
|
2255
2255
|
const tag = source.slice(open, end);
|
|
2256
|
-
|
|
2257
|
-
|
|
2256
|
+
/**
|
|
2257
|
+
* O `className` DO PRÓPRIO ELEMENTO, e não o primeiro que aparece no texto.
|
|
2258
|
+
*
|
|
2259
|
+
* ═══ O DEFEITO, medido em 28/08 ═══
|
|
2260
|
+
*
|
|
2261
|
+
* Era `tag.search(/className\s*=/)` seguido de casar todo literal de string até o fim da tag.
|
|
2262
|
+
* Numa tag de abertura que carrega JSX dentro de uma prop, o primeiro `className=` do texto é o
|
|
2263
|
+
* daquele JSX aninhado - e as classes dele eram atribuídas à RAIZ.
|
|
2264
|
+
*
|
|
2265
|
+
* <ReactMarkdown components={{ p: (props) => <p className={"py-2 " + className} /> }}>
|
|
2266
|
+
*
|
|
2267
|
+
* A raiz ali não escreve classe nenhuma, e o leitor lhe dava `py-2` - junto com pedaços de código
|
|
2268
|
+
* (`}`, `/>`, `...props`) que a varredura de literais recolhia pelo caminho.
|
|
2269
|
+
*
|
|
2270
|
+
* A consequência VISÍVEL, medida: o contrato `editions-performance-list` chegava com
|
|
2271
|
+
* `animation: var(--animate-spin)` na raiz. O giro é de um spinner que vive dentro de uma prop, e
|
|
2272
|
+
* a receita dizia que o componente inteiro gira.
|
|
2273
|
+
*
|
|
2274
|
+
* ═══ A PROPRIEDADE ═══
|
|
2275
|
+
*
|
|
2276
|
+
* Uma classe só pode ser atribuída a um elemento se AQUELE elemento a escreveu. Classe de JSX
|
|
2277
|
+
* aninhado em prop, callback, render prop ou objeto não pertence à raiz.
|
|
2278
|
+
*
|
|
2279
|
+
* A regra é ESTRUTURAL e não tem exceção por nome: nada aqui conhece `components`, `ReactMarkdown`
|
|
2280
|
+
* ou qualquer exemplar. O atributo do elemento é o que está em profundidade ZERO dentro da tag de
|
|
2281
|
+
* abertura, e é só ele que é lido.
|
|
2282
|
+
*
|
|
2283
|
+
* E o VALOR também é delimitado, não varrido até o fim: um `className="a"` seguido de
|
|
2284
|
+
* `onClick={() => <span className="b"/>}` dava `a b` antes, porque a varredura ia até o `>`.
|
|
2285
|
+
*/
|
|
2286
|
+
const own = ownClassNameExpr(tag);
|
|
2287
|
+
if (own == null)
|
|
2258
2288
|
return [];
|
|
2259
2289
|
// Every string literal inside the className expression. Template literals and
|
|
2260
2290
|
// computed values are skipped on purpose: a class we cannot see in full is a
|
|
2261
2291
|
// class we would be guessing at.
|
|
2262
|
-
|
|
2263
|
-
return [...expr.matchAll(/["']([^"']+)["']/g)]
|
|
2292
|
+
return [...own.matchAll(/["']([^"']+)["']/g)]
|
|
2264
2293
|
.flatMap((m) => m[1].split(/\s+/))
|
|
2265
2294
|
.filter((c) => c.length > 0 && !c.includes("${"));
|
|
2266
2295
|
}
|
|
2296
|
+
/**
|
|
2297
|
+
* A EXPRESSÃO do `className` que é atributo DIRETO desta tag de abertura, ou `null`.
|
|
2298
|
+
*
|
|
2299
|
+
* Duas travas, e as duas nasceram medidas:
|
|
2300
|
+
*
|
|
2301
|
+
* PROFUNDIDADE ZERO um `className` dentro de `{...}`, `(...)` ou `[...]` é de outro elemento -
|
|
2302
|
+
* objeto de prop, callback, render prop, JSX passado como prop.
|
|
2303
|
+
* FRONTEIRA DE PALAVRA `wrapperClassName=` não é `className=`. O regex antigo casava dentro dele,
|
|
2304
|
+
* e a classe de um wrapper virava classe da raiz.
|
|
2305
|
+
*
|
|
2306
|
+
* O valor é DELIMITADO: a string entre aspas, ou o bloco `{...}` balanceado. Ler até o fim da tag
|
|
2307
|
+
* misturaria o atributo com tudo que vem depois dele.
|
|
2308
|
+
*/
|
|
2309
|
+
function ownClassNameExpr(tag) {
|
|
2310
|
+
let depth = 0;
|
|
2311
|
+
for (let i = 0; i < tag.length; i++) {
|
|
2312
|
+
const ch = tag[i];
|
|
2313
|
+
if (ch === "{" || ch === "(" || ch === "[") {
|
|
2314
|
+
depth += 1;
|
|
2315
|
+
continue;
|
|
2316
|
+
}
|
|
2317
|
+
if (ch === "}" || ch === ")" || ch === "]") {
|
|
2318
|
+
depth -= 1;
|
|
2319
|
+
continue;
|
|
2320
|
+
}
|
|
2321
|
+
if (depth !== 0 || !tag.startsWith("className", i))
|
|
2322
|
+
continue;
|
|
2323
|
+
/** Atributo é palavra inteira: o que vem antes tem que ser separador, nunca letra. */
|
|
2324
|
+
const before = i > 0 ? tag[i - 1] : " ";
|
|
2325
|
+
if (/[A-Za-z0-9_$]/.test(before))
|
|
2326
|
+
continue;
|
|
2327
|
+
let j = i + "className".length;
|
|
2328
|
+
while (j < tag.length && /\s/.test(tag[j]))
|
|
2329
|
+
j += 1;
|
|
2330
|
+
if (tag[j] !== "=")
|
|
2331
|
+
continue;
|
|
2332
|
+
j += 1;
|
|
2333
|
+
while (j < tag.length && /\s/.test(tag[j]))
|
|
2334
|
+
j += 1;
|
|
2335
|
+
const quote = tag[j];
|
|
2336
|
+
if (quote === '"' || quote === "'") {
|
|
2337
|
+
const close = tag.indexOf(quote, j + 1);
|
|
2338
|
+
return close === -1 ? tag.slice(j) : tag.slice(j, close + 1);
|
|
2339
|
+
}
|
|
2340
|
+
if (tag[j] !== "{")
|
|
2341
|
+
return "";
|
|
2342
|
+
let d = 0;
|
|
2343
|
+
for (let k = j; k < tag.length; k++) {
|
|
2344
|
+
if (tag[k] === "{")
|
|
2345
|
+
d += 1;
|
|
2346
|
+
else if (tag[k] === "}") {
|
|
2347
|
+
d -= 1;
|
|
2348
|
+
if (d === 0)
|
|
2349
|
+
return tag.slice(j, k + 1);
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
return tag.slice(j);
|
|
2353
|
+
}
|
|
2354
|
+
return null;
|
|
2355
|
+
}
|
package/dist/install-marks.js
CHANGED
|
@@ -352,7 +352,22 @@ export const CHECKER_SINCE = "0.16.308";
|
|
|
352
352
|
* nenhum dos 22 apps dourados tem componente com nome de tag de SVG. Quem tem só vê a correção
|
|
353
353
|
* depois de remedir.
|
|
354
354
|
*/
|
|
355
|
-
|
|
355
|
+
/**
|
|
356
|
+
* 0.16.324 -> 0.16.328 em 28/08 (T43-b): o censo passou a carregar `consumedAt` - qual nó do sketch
|
|
357
|
+
* teve as classes absorvidas em `base`, ou `"none"` quando nenhum teve.
|
|
358
|
+
*
|
|
359
|
+
* A marca sobe porque a medição ANTERIOR não tem como produzir o conserto: sem o campo o look cai no
|
|
360
|
+
* estado legado e o deriver volta a deduzir por posição, que é o defeito. Medido no app real: 8
|
|
361
|
+
* componentes que devolvem um Fragment recuperam as classes que hoje caem no vazio, e 386 de 386
|
|
362
|
+
* looks legados leem exatamente como liam.
|
|
363
|
+
*
|
|
364
|
+
* 0.16.328 -> 0.16.329 em 28/08: `rootClasses` passou a ler só o `className` do PRÓPRIO elemento.
|
|
365
|
+
* Antes ele ancorava no primeiro `className=` do texto da tag de abertura, então a classe de um JSX
|
|
366
|
+
* escrito dentro de uma prop virava classe da raiz - e o `className` da raiz, quando vinha depois,
|
|
367
|
+
* nunca era alcançado. Medido: 1134 componentes, 77 mudaram, e a receita que o cliente recebe muda
|
|
368
|
+
* com eles. Uma medição anterior não produz o conserto, então a marca sobe.
|
|
369
|
+
*/
|
|
370
|
+
export const READER_SINCE = "0.16.329";
|
|
356
371
|
/**
|
|
357
372
|
* O QUE ESTÁ INSTALADO AQUI FICOU PARA TRÁS - e as DUAS condições que fazem isso ser verdade.
|
|
358
373
|
*
|
package/dist/naming-queue.js
CHANGED
|
@@ -59,7 +59,10 @@ export function namingQueue(looks, defines, versionOf) {
|
|
|
59
59
|
const sketch = looks[component]?.sketch;
|
|
60
60
|
if (!Array.isArray(sketch) || sketch.length === 0)
|
|
61
61
|
continue;
|
|
62
|
-
const derived = anatomyFromSketch(sketch, defines, versionOf
|
|
62
|
+
const derived = anatomyFromSketch(sketch, defines, versionOf,
|
|
63
|
+
/** O fato medido na coleta, ou `undefined` num look legado - ver `CensusLook.consumedAt`. */
|
|
64
|
+
looks[component]
|
|
65
|
+
?.consumedAt);
|
|
63
66
|
if (derived.read.length === 0)
|
|
64
67
|
continue;
|
|
65
68
|
components += 1;
|
|
@@ -51,6 +51,27 @@ export const CODELEVEL_CENSUS = join(POPULATIONS, "codelevel-ui.census.json");
|
|
|
51
51
|
* `signalui` viraram provas apagadas. Ver `fixtures/populations/README.md`.
|
|
52
52
|
*/
|
|
53
53
|
export const CODELEVEL_LEDGER = join(POPULATIONS, "codelevel-ui.ledger.jsonl");
|
|
54
|
+
/**
|
|
55
|
+
* O MESMO REPOSITÓRIO, MEDIDO DEPOIS - e os dois instantes ficam, porque cada um carrega uma
|
|
56
|
+
* dimensão que o outro não tem.
|
|
57
|
+
*
|
|
58
|
+
* O ledger ao lado é de 26/08, de um CLI que ainda não transportava OCORRÊNCIAS. Este é de 28/08,
|
|
59
|
+
* medido pelo `doctor` 0.16.327 publicado, e carrega `unrepresentedMatches`.
|
|
60
|
+
*
|
|
61
|
+
* POR QUE O ANTIGO NÃO FOI SUBSTITUÍDO. Ele não é evidência velha: ele é a evidência do estado
|
|
62
|
+
* LEGADO, que é onde todo cliente está até sincronizar. Medido ao trocar um pelo outro - a causa
|
|
63
|
+
* `cross-family-suggestion` deixa de nascer da fonte `repo` e passa a nascer de `judged`, e a fonte
|
|
64
|
+
* `repo` some da população inteira. `screen.real` precisa das TRÊS fontes vivas ao mesmo tempo;
|
|
65
|
+
* sobrescrever apagaria uma dimensão para ganhar outra.
|
|
66
|
+
*
|
|
67
|
+
* 26/08 crossFamily 1 · matched 22 · sem o campo recount 11 · judged 1 · repo 1
|
|
68
|
+
* 28/08 crossFamily 1 · matched 22 · 4 ocorrências recount 11 · judged 2 · repo 0
|
|
69
|
+
*
|
|
70
|
+
* INSPECIONADO ANTES DE VERSIONAR (28/08): zero caminhos absolutos, zero `/home/`, zero e-mails,
|
|
71
|
+
* zero credenciais, zero URLs. Ele carrega o que o campo novo promete carregar - caminhos RELATIVOS
|
|
72
|
+
* de origem, com a linha.
|
|
73
|
+
*/
|
|
74
|
+
export const CODELEVEL_LEDGER_WITH_OCCURRENCES = join(POPULATIONS, "codelevel-ui.ledger.with-occurrences.jsonl");
|
|
54
75
|
/**
|
|
55
76
|
* OS DOIS DOCUMENTOS HISTÓRICOS - a exceção autorizada à regra do derivável (dono, 28/08).
|
|
56
77
|
*
|
package/package.json
CHANGED