synthesisui 0.16.205 → 0.16.208
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/commands/align.js +18 -11
- package/dist/commands/doctor.js +20 -0
- package/dist/doctor/fragments.js +33 -1
- package/dist/doctor/transcribe.js +49 -3
- package/dist/install-marks.js +33 -0
- package/dist/reader-version.js +17 -1
- package/package.json +1 -1
package/dist/commands/align.js
CHANGED
|
@@ -5,22 +5,27 @@ import { pinnedHookVersion } from "../agent-wiring.js";
|
|
|
5
5
|
import { isOlderCli } from "../cli-version.js";
|
|
6
6
|
import { readToken, resolveRegistry } from "../config.js";
|
|
7
7
|
import { unsentEvents } from "../doctor/ledger.js";
|
|
8
|
-
import { CHECKER_SINCE, MATERIALISER_SINCE } from "../install-marks.js";
|
|
8
|
+
import { CHECKER_SINCE, MATERIALISER_SINCE, READER_SINCE, } from "../install-marks.js";
|
|
9
9
|
import { measuredScope } from "../measured-scope.js";
|
|
10
|
-
import { READER } from "../reader-version.js";
|
|
11
10
|
/**
|
|
12
|
-
*
|
|
11
|
+
* QUAL CLI MEDIU O CENSO EM DISCO - e era o `reader`, um inteiro, até 11/08.
|
|
13
12
|
*
|
|
14
|
-
* `
|
|
15
|
-
*
|
|
13
|
+
* O carimbo `ledger.reader` existe e continua sendo gravado, mas ele não serve para responder esta
|
|
14
|
+
* pergunta: ficou parado em 1 enquanto os leitores mudavam, então censos de julho e de ontem levam
|
|
15
|
+
* o mesmo número e nada os separa. A versão que mediu separa - ver `READER_SINCE`.
|
|
16
|
+
*
|
|
17
|
+
* `null` para censo que não diz quem o mediu: um censo assim não prova nada, e supor que ele é
|
|
18
|
+
* velho faria toda pessoa que ainda não re-mediu ver o aviso para sempre.
|
|
16
19
|
*/
|
|
17
|
-
async function
|
|
20
|
+
async function censusMeasuredBy(root) {
|
|
18
21
|
const raw = await readFile(join(root, "_synthesisui", "census.json"), "utf8").catch(() => null);
|
|
19
22
|
if (!raw)
|
|
20
23
|
return null;
|
|
21
24
|
try {
|
|
22
25
|
const c = JSON.parse(raw);
|
|
23
|
-
return typeof c.ledger?.
|
|
26
|
+
return typeof c.ledger?.cli === "string" && c.ledger.cli
|
|
27
|
+
? c.ledger.cli
|
|
28
|
+
: null;
|
|
24
29
|
}
|
|
25
30
|
catch {
|
|
26
31
|
return null;
|
|
@@ -121,11 +126,13 @@ opts = {}) {
|
|
|
121
126
|
* leitura de antes e NENHUMA re-interpretação nossa alcança isso. Só uma medição nova alcança, e
|
|
122
127
|
* ela é um comando que ninguém tinha motivo para rodar.
|
|
123
128
|
*
|
|
124
|
-
* Compara `
|
|
125
|
-
* leitor - pedir re-medição em cada bump faria a pessoa parar de ler estas
|
|
129
|
+
* Compara contra `READER_SINCE`, e não contra a string do CLI: em 07/08 o CLI subiu quatro vezes e
|
|
130
|
+
* nenhuma delas mudou um leitor - pedir re-medição em cada bump faria a pessoa parar de ler estas
|
|
131
|
+
* linhas. E não contra o carimbo `reader`, que ficou parado em 1 enquanto os leitores andavam:
|
|
132
|
+
* medido em 11/08, 12 de 36 componentes têm árvore diferente entre o leitor de 07/08 e o de hoje.
|
|
126
133
|
*/
|
|
127
|
-
const
|
|
128
|
-
if (
|
|
134
|
+
const measuredBy = await censusMeasuredBy(root);
|
|
135
|
+
if (behind(measuredBy, cli, READER_SINCE))
|
|
129
136
|
out.push({
|
|
130
137
|
says: `the measurement stored in this repo was read by an older reader, so what the platform knows about your components is what that reader could see. A re-measure is the only thing that reaches it - the fix lives on this machine, not on the server.`,
|
|
131
138
|
run: "npx synthesisui sync",
|
package/dist/commands/doctor.js
CHANGED
|
@@ -758,6 +758,26 @@ export async function doctor(opts) {
|
|
|
758
758
|
console.log("");
|
|
759
759
|
console.log(body(`Token coverage ${meter(d.coverage)} ${paint.strong(`${String(d.coverage).padStart(3)}%`)}`));
|
|
760
760
|
console.log(body(paint.dim(` ${d.tokenUses} from the system, ${d.findings.length} by hand${d.phantomUses > 0 ? `, ${d.phantomUses} naming nothing` : ""}`)));
|
|
761
|
+
/**
|
|
762
|
+
* ZERO NUM REPO QUE ORIGINOU O SISTEMA É O ESTADO CERTO, e sem esta linha ele lê como falha
|
|
763
|
+
* NOSSA.
|
|
764
|
+
*
|
|
765
|
+
* "Token coverage 0% - 1 from the system, 4433 by hand" é literalmente verdade e ainda assim
|
|
766
|
+
* engana: quando o sistema foi medido A PARTIR daqui, esses valores escritos à mão são a FONTE
|
|
767
|
+
* de onde os tokens saíram, não um desvio deles. Não há nada consertado ainda porque não havia
|
|
768
|
+
* nada quebrado - o passo seguinte é o código passar a apontar para os nomes que agora existem.
|
|
769
|
+
*
|
|
770
|
+
* O sinal é `measured.system`: a pasta de onde o import mediu. Ele só existe quando este
|
|
771
|
+
* repositório é a origem, então a frase não aparece para quem instalou um sistema de fora - ali
|
|
772
|
+
* um zero significa outra coisa e merece outra frase.
|
|
773
|
+
*
|
|
774
|
+
* A lei 14 em uma linha: um zero pelado lê como falha nossa, um zero com motivo lê como fato.
|
|
775
|
+
*/
|
|
776
|
+
if (d.tokenUses === 0 && measured.system) {
|
|
777
|
+
console.log(body(paint.dim(` zero is the expected start here - this system was measured FROM`)));
|
|
778
|
+
console.log(body(paint.dim(` \`${measured.system}\`, so these values are its source, not a drift`)));
|
|
779
|
+
console.log(body(paint.dim(` from it. They count once the code points at the names they became.`)));
|
|
780
|
+
}
|
|
761
781
|
// The strongest number leads, not trails: it used to sit two screens
|
|
762
782
|
// down, after the phantom list (30/07). For the reader who already owns
|
|
763
783
|
// a system - the ICP - THIS line is the report.
|
package/dist/doctor/fragments.js
CHANGED
|
@@ -58,6 +58,36 @@ const MODULE_REF = /\$\{\s*[A-Za-z_$][\w$]*\.[A-Za-z_$][\w$]*\s*\}/g;
|
|
|
58
58
|
* que nenhum leitor cobre (`sx`, `styled`, `runtime`) já saem com o motivo, porque nesses casos o
|
|
59
59
|
* motivo é a própria forma e não depende de leitura.
|
|
60
60
|
*/
|
|
61
|
+
/**
|
|
62
|
+
* O QUE ESTÁ DENTRO DE UM `cn(...)` E NÃO É CLASSE - e por que isto vira número na tela dele.
|
|
63
|
+
*
|
|
64
|
+
* O corpo da chamada é varrido por literal, e todo literal virava um fragmento de estilo. Dois deles
|
|
65
|
+
* nunca foram estilo, e a esteira estava dizendo ao cliente que não conseguia ler o que ele nem
|
|
66
|
+
* escreveu:
|
|
67
|
+
*
|
|
68
|
+
* status === "success" ? "bg-success-500" : ... "success" é OPERANDO da comparação
|
|
69
|
+
* // ... to prevent the "short width" issue "short width" está num COMENTÁRIO
|
|
70
|
+
*
|
|
71
|
+
* MEDIDO EM 11/08 no repo real, sobre as 26 declarações que o censo listava como `value-not-read`:
|
|
72
|
+
*
|
|
73
|
+
* 8 (31%) operando de === Card, RadioCard x4, SelectionCard x2
|
|
74
|
+
* 2 (8%) comentário Input, Tag
|
|
75
|
+
* 16 (61%) classe de verdade sr-only, flex flex-col, data-[side=top]:top-full, ...
|
|
76
|
+
*
|
|
77
|
+
* Ou seja: 10 das 26 eram acusação NOSSA. E a lei 8 é explícita - lacuna declarada é confiança,
|
|
78
|
+
* mas lacuna FALSA custa o mesmo que a escondida: ela manda a pessoa procurar um problema que não
|
|
79
|
+
* existe no código dela, e gasta a credibilidade do número que está certo.
|
|
80
|
+
*/
|
|
81
|
+
/** Apaga comentários preservando o COMPRIMENTO, senão todo índice depois deles aponta para a linha errada. */
|
|
82
|
+
function blankComments(body) {
|
|
83
|
+
return body
|
|
84
|
+
.replace(/\/\*[\s\S]*?\*\//g, (m) => " ".repeat(m.length))
|
|
85
|
+
.replace(/\/\/[^\n]*/g, (m) => " ".repeat(m.length));
|
|
86
|
+
}
|
|
87
|
+
/** `size === "md"`: o literal é o que está sendo COMPARADO, e comparar não é vestir. */
|
|
88
|
+
function isComparedTo(body, index) {
|
|
89
|
+
return /(?:===|!==|==|!=)\s*$/.test(body.slice(0, index));
|
|
90
|
+
}
|
|
61
91
|
export function fragmentsOfSource(file, source) {
|
|
62
92
|
const out = [];
|
|
63
93
|
const at = (index) => source.slice(0, index).split("\n").length;
|
|
@@ -93,12 +123,14 @@ export function fragmentsOfSource(file, source) {
|
|
|
93
123
|
* classe escrita à mão - a forma mais comum do repo dele (113 arquivos).
|
|
94
124
|
*/
|
|
95
125
|
for (const call of source.matchAll(CALL_LITERAL)) {
|
|
96
|
-
const body = call[1] ?? "";
|
|
126
|
+
const body = blankComments(call[1] ?? "");
|
|
97
127
|
const base = (call.index ?? 0) + (call[0].length - body.length - 1);
|
|
98
128
|
for (const s of body.matchAll(STRING_IN_CALL)) {
|
|
99
129
|
const text = s[1] ?? s[2] ?? "";
|
|
100
130
|
if (!LOOKS_LIKE_CLASS.test(text))
|
|
101
131
|
continue;
|
|
132
|
+
if (isComparedTo(body, s.index ?? 0))
|
|
133
|
+
continue;
|
|
102
134
|
push("class", base + (s.index ?? 0), text);
|
|
103
135
|
}
|
|
104
136
|
}
|
|
@@ -1325,12 +1325,44 @@ function layerFor(out, when, at) {
|
|
|
1325
1325
|
* attempt.
|
|
1326
1326
|
*/
|
|
1327
1327
|
const INLINE_STYLE = /style=\{\{([^{}]*(?:\{[^{}]*\}[^{}]*)*)\}\}/;
|
|
1328
|
+
/**
|
|
1329
|
+
* AS PROPRIEDADES, SEPARADAS PELA VÍRGULA QUE SEPARA - e não pela que está dentro de um valor.
|
|
1330
|
+
*
|
|
1331
|
+
* `split(",")` partia `var(--color-track, var(--color-darkgray-300))` ao meio e entregava duas
|
|
1332
|
+
* metades que não são nada. Vírgula dentro de parêntese ou de aspas pertence ao valor.
|
|
1333
|
+
*/
|
|
1334
|
+
function splitProperties(body) {
|
|
1335
|
+
const out = [];
|
|
1336
|
+
let depth = 0;
|
|
1337
|
+
let quote = null;
|
|
1338
|
+
let start = 0;
|
|
1339
|
+
for (let i = 0; i < body.length; i += 1) {
|
|
1340
|
+
const c = body[i];
|
|
1341
|
+
if (quote) {
|
|
1342
|
+
if (c === quote && body[i - 1] !== "\\")
|
|
1343
|
+
quote = null;
|
|
1344
|
+
continue;
|
|
1345
|
+
}
|
|
1346
|
+
if (c === '"' || c === "'" || c === "`")
|
|
1347
|
+
quote = c;
|
|
1348
|
+
else if (c === "(" || c === "[")
|
|
1349
|
+
depth += 1;
|
|
1350
|
+
else if (c === ")" || c === "]")
|
|
1351
|
+
depth -= 1;
|
|
1352
|
+
else if (c === "," && depth === 0) {
|
|
1353
|
+
out.push(body.slice(start, i));
|
|
1354
|
+
start = i + 1;
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
out.push(body.slice(start));
|
|
1358
|
+
return out;
|
|
1359
|
+
}
|
|
1328
1360
|
export function readInlineStyle(source) {
|
|
1329
1361
|
const m = INLINE_STYLE.exec(source);
|
|
1330
1362
|
if (!m)
|
|
1331
1363
|
return {};
|
|
1332
1364
|
const out = {};
|
|
1333
|
-
for (const piece of m[1]
|
|
1365
|
+
for (const piece of splitProperties(m[1])) {
|
|
1334
1366
|
const colon = piece.indexOf(":");
|
|
1335
1367
|
if (colon === -1)
|
|
1336
1368
|
continue;
|
|
@@ -1339,10 +1371,24 @@ export function readInlineStyle(source) {
|
|
|
1339
1371
|
.trim()
|
|
1340
1372
|
.replace(/^["']|["']$/g, "");
|
|
1341
1373
|
let value = piece.slice(colon + 1).trim();
|
|
1374
|
+
/**
|
|
1375
|
+
* UMA STRING ENTRE ASPAS ESTÁ NO FONTE, e o que ela tem dentro não muda isso.
|
|
1376
|
+
*
|
|
1377
|
+
* O guarda descartava todo valor com parêntese, e com isso todo `var()`, `linear-gradient()`,
|
|
1378
|
+
* `calc()` e `rgb()` escrito em estilo inline - que são exatamente os valores que carregam
|
|
1379
|
+
* decisão de design. Medido em 11/08 no repo dele: 2 dos 6 fragmentos que o censo chamava de
|
|
1380
|
+
* `computed` eram literais, entre eles
|
|
1381
|
+
* `style={{ stroke: "var(--color-track, var(--color-darkgray-300))" }}`.
|
|
1382
|
+
*
|
|
1383
|
+
* A distinção certa não é "tem parêntese", é "está no fonte": literal entre aspas se lê inteiro,
|
|
1384
|
+
* e só o que NÃO está entre aspas passa pelo guarda de expressão.
|
|
1385
|
+
*/
|
|
1386
|
+
const quoted = /^(["'])([\s\S]*)\1$/.exec(value);
|
|
1387
|
+
if (quoted)
|
|
1388
|
+
value = quoted[2];
|
|
1342
1389
|
// A value computed at runtime is not in the source, so there is nothing to read.
|
|
1343
|
-
if (!value || /[`$]|\?|=>|\(/.test(value))
|
|
1390
|
+
else if (!value || /[`$]|\?|=>|\(/.test(value))
|
|
1344
1391
|
continue;
|
|
1345
|
-
value = value.replace(/^["']|["']$/g, "");
|
|
1346
1392
|
if (!/^[a-zA-Z][\w]*$/.test(prop))
|
|
1347
1393
|
continue;
|
|
1348
1394
|
if (/[<>{}@;]/.test(value))
|
package/dist/install-marks.js
CHANGED
|
@@ -64,3 +64,36 @@ export const MATERIALISER_SINCE = "0.16.204";
|
|
|
64
64
|
* Os arquivos que decidem: `doctor/` inteiro e `commands/hook.ts`.
|
|
65
65
|
*/
|
|
66
66
|
export const CHECKER_SINCE = "0.16.202";
|
|
67
|
+
/**
|
|
68
|
+
* A ÚLTIMA VERSÃO EM QUE OS LEITORES PASSARAM A PRODUZIR UM CENSO DIFERENTE.
|
|
69
|
+
*
|
|
70
|
+
* A terceira do mesmo bolo, e a que tinha o desenho MAIS antigo e mais errado. O `READER` era um
|
|
71
|
+
* inteiro carimbado no censo na hora da medição, e a comparação era `carimbo !== READER`. O defeito
|
|
72
|
+
* disso não é ruído, é PERDA DE INFORMAÇÃO: com o número parado em 1 desde 07/08, um censo medido
|
|
73
|
+
* ontem e um medido em julho carregam o mesmo `1` e nada os separa. Subir o número para 2 chamaria
|
|
74
|
+
* os dois para re-medir - inclusive quem já está em dia.
|
|
75
|
+
*
|
|
76
|
+
* Uma versão não perde nada, porque o censo já grava QUEM mediu (`StyleLedger.cli`).
|
|
77
|
+
*
|
|
78
|
+
* MEDIDO EM 11/08, rodando o leitor de 07/08 e o de hoje sobre os mesmos 35 componentes do repo
|
|
79
|
+
* real, e comparando o censo canônico:
|
|
80
|
+
*
|
|
81
|
+
* 12 de 36 componentes com ÁRVORE diferente - 10 lendo mais (LineChart +556 bytes)
|
|
82
|
+
* 8 de 36 com FRONTEIRA diferente - Tooltip, Menu, Modal, Select, ColorPicker, ...
|
|
83
|
+
* 2 custom properties que eram descartadas: --loader-color, --color-track
|
|
84
|
+
*
|
|
85
|
+
* Ou seja, o `READER` estava errado e ninguém tinha sido avisado. A marca nasceu em `0.16.202`,
|
|
86
|
+
* bisseccionada: o censo de 0.16.201 difere do de então, o de 0.16.202 é byte a byte igual.
|
|
87
|
+
*
|
|
88
|
+
* ANDOU DUAS VEZES no mesmo dia, e nas duas foi o portão que mandou:
|
|
89
|
+
*
|
|
90
|
+
* 0.16.207 `fragmentsOfSource` parou de tomar operando de `===` e texto de comentário por
|
|
91
|
+
* classe - 11 das 26 declarações que o censo dele listava como ilegíveis eram
|
|
92
|
+
* acusação NOSSA
|
|
93
|
+
* 0.16.208 `readInlineStyle` parou de descartar valor com parêntese - `var()` e
|
|
94
|
+
* `linear-gradient()` em `style={{}}` chegam na receita, e 2 dos 6 fragmentos
|
|
95
|
+
* chamados de `computed` eram literais no fonte
|
|
96
|
+
*
|
|
97
|
+
* Um censo medido antes disto carrega as duas leituras erradas.
|
|
98
|
+
*/
|
|
99
|
+
export const READER_SINCE = "0.16.208";
|
package/dist/reader-version.js
CHANGED
|
@@ -20,5 +20,21 @@
|
|
|
20
20
|
* READER a medição na máquina dela -> npx synthesisui sync
|
|
21
21
|
* COMPILER o CSS de uma versão já instalada -> npx synthesisui connect
|
|
22
22
|
* INTERPRETATION a nossa metade, sobre censos já guardados -> roda no servidor, sem comando
|
|
23
|
+
*
|
|
24
|
+
* A DECISÃO SAIU DAQUI EM 11/08, e este número virou só um carimbo.
|
|
25
|
+
*
|
|
26
|
+
* O desenho acima está certo na intenção e errado no formato: um inteiro gravado no censo NO
|
|
27
|
+
* MOMENTO DA MEDIÇÃO só separa duas medições se ele tiver subido entre elas. Ele não subiu - ficou
|
|
28
|
+
* em 1 desde 07/08 - enquanto os leitores andavam. Medido rodando o leitor daquele dia e o de hoje
|
|
29
|
+
* sobre os mesmos 35 componentes do repo real: 12 de 36 componentes com ÁRVORE diferente, 8 com
|
|
30
|
+
* FRONTEIRA diferente, e 2 custom properties que eram descartadas. Todos esses censos carregam `1`,
|
|
31
|
+
* e a informação para separá-los não existe mais.
|
|
32
|
+
*
|
|
33
|
+
* Subir para 2 agora chamaria para re-medir também quem já está em dia. Então quem responde
|
|
34
|
+
* *"este censo está velho?"* passou a ser `READER_SINCE`, em `install-marks.ts`, comparado contra a
|
|
35
|
+
* VERSÃO que mediu (`StyleLedger.cli`) - que o censo sempre gravou e nunca se perde.
|
|
36
|
+
*
|
|
37
|
+
* O carimbo continua sendo escrito porque ele é barato e é registro; ele só não decide mais nada.
|
|
38
|
+
* Sobe para 2 aqui por honestidade com o que foi medido.
|
|
23
39
|
*/
|
|
24
|
-
export const READER =
|
|
40
|
+
export const READER = 2;
|
package/package.json
CHANGED