synthesisui 0.16.50 → 0.16.51
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/import.js
CHANGED
|
@@ -3,7 +3,7 @@ import { basename, join, relative } from "node:path";
|
|
|
3
3
|
import { readToken, resolveRegistry } from "../config.js";
|
|
4
4
|
import { isNearDuplicate } from "../doctor/color-distance.js";
|
|
5
5
|
import { emptyTally, internalSpecifiers, scanComponentsInto, tallyToInventory, } from "../doctor/components-scan.js";
|
|
6
|
-
import { crosswalk } from "../doctor/crosswalk.js";
|
|
6
|
+
import { crosswalk, observedRules } from "../doctor/crosswalk.js";
|
|
7
7
|
import { diagnose, scanSource } from "../doctor/scan.js";
|
|
8
8
|
import { parseSchemeBlocks } from "../doctor/scheme-blocks.js";
|
|
9
9
|
import { buildTable } from "../doctor/tokens.js";
|
|
@@ -293,9 +293,14 @@ export async function takeCensus(root) {
|
|
|
293
293
|
r.component.name,
|
|
294
294
|
{ bucket: r.bucket, canonical: r.canonical, because: r.because },
|
|
295
295
|
]));
|
|
296
|
+
const laws = new Map();
|
|
297
|
+
for (const r of observedRules(inventory)) {
|
|
298
|
+
laws.set(r.component, [...(laws.get(r.component) ?? []), r.text]);
|
|
299
|
+
}
|
|
296
300
|
const components = inventory.map((c) => ({
|
|
297
301
|
...c,
|
|
298
302
|
...(verdicts.get(c.name) ?? {}),
|
|
303
|
+
...(laws.has(c.name) ? { laws: laws.get(c.name) } : {}),
|
|
299
304
|
}));
|
|
300
305
|
const pkgRaw = await readFile(join(root, "package.json"), "utf8").catch(() => null);
|
|
301
306
|
let name = null;
|
|
@@ -402,6 +407,29 @@ function printComponents(c) {
|
|
|
402
407
|
console.log(body(paint.faint(`(${mine.length - 12} more of yours)`)));
|
|
403
408
|
}
|
|
404
409
|
printCrosswalk(mine);
|
|
410
|
+
printObserved(mine);
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Laws their code already obeys, printed with the evidence that found them.
|
|
414
|
+
*
|
|
415
|
+
* Not applied and not sent as decisions - they ride along on the contract as
|
|
416
|
+
* `usage`, which is where a law about one component belongs and what the GUIDE
|
|
417
|
+
* and the build script already read.
|
|
418
|
+
*/
|
|
419
|
+
function printObserved(mine) {
|
|
420
|
+
const rules = observedRules(mine);
|
|
421
|
+
if (rules.length === 0)
|
|
422
|
+
return;
|
|
423
|
+
console.log("");
|
|
424
|
+
console.log(section("Laws your code already obeys"));
|
|
425
|
+
console.log(body(paint.faint("A prop with one value across many files is not a choice being made - it is a rule nobody wrote down.")));
|
|
426
|
+
console.log("");
|
|
427
|
+
for (const r of rules.slice(0, 8)) {
|
|
428
|
+
console.log(body(` ${paint.strong(r.component)} ${paint.dim(r.text.replace(/^Always /, "always "))}`));
|
|
429
|
+
}
|
|
430
|
+
if (rules.length > 8) {
|
|
431
|
+
console.log(body(paint.faint(` (${rules.length - 8} more)`)));
|
|
432
|
+
}
|
|
405
433
|
}
|
|
406
434
|
/**
|
|
407
435
|
* The crosswalk, printed and nothing else.
|
|
@@ -106,6 +106,7 @@ internal = []) {
|
|
|
106
106
|
count: 0,
|
|
107
107
|
files: new Set(),
|
|
108
108
|
props: new Map(),
|
|
109
|
+
propFiles: new Map(),
|
|
109
110
|
...(owner ? { from: owner } : {}),
|
|
110
111
|
};
|
|
111
112
|
tally.set(name, hit);
|
|
@@ -122,6 +123,9 @@ internal = []) {
|
|
|
122
123
|
const bucket = hit.props.get(prop) ?? new Map();
|
|
123
124
|
bucket.set(value, (bucket.get(value) ?? 0) + 1);
|
|
124
125
|
hit.props.set(prop, bucket);
|
|
126
|
+
const seenIn = hit.propFiles.get(prop) ?? new Set();
|
|
127
|
+
seenIn.add(file);
|
|
128
|
+
hit.propFiles.set(prop, seenIn);
|
|
125
129
|
}
|
|
126
130
|
// Bare booleans, minus anything already read as a valued prop.
|
|
127
131
|
// Strip the WHOLE pair, name included: stripping only the value left
|
|
@@ -138,6 +142,9 @@ internal = []) {
|
|
|
138
142
|
const bucket = hit.props.get(prop) ?? new Map();
|
|
139
143
|
bucket.set("true", (bucket.get("true") ?? 0) + 1);
|
|
140
144
|
hit.props.set(prop, bucket);
|
|
145
|
+
const seenIn = hit.propFiles.get(prop) ?? new Set();
|
|
146
|
+
seenIn.add(file);
|
|
147
|
+
hit.propFiles.set(prop, seenIn);
|
|
141
148
|
}
|
|
142
149
|
}
|
|
143
150
|
}
|
|
@@ -149,6 +156,7 @@ export function tallyToInventory(tally, max = 80) {
|
|
|
149
156
|
...(v.from ? { from: v.from } : {}),
|
|
150
157
|
count: v.count,
|
|
151
158
|
files: v.files.size,
|
|
159
|
+
propFiles: Object.fromEntries([...v.propFiles.entries()].map(([p, files]) => [p, files.size])),
|
|
152
160
|
props: Object.fromEntries([...v.props.entries()].map(([p, values]) => [
|
|
153
161
|
p,
|
|
154
162
|
[...values.entries()]
|
package/dist/doctor/crosswalk.js
CHANGED
|
@@ -337,3 +337,41 @@ export function crosswalk(components) {
|
|
|
337
337
|
})
|
|
338
338
|
.sort((a, b) => b.component.files - a.component.files);
|
|
339
339
|
}
|
|
340
|
+
/** Below this a repetition is a coincidence rather than a habit. */
|
|
341
|
+
export const RULE_MIN_FILES = 3;
|
|
342
|
+
export function observedRules(components) {
|
|
343
|
+
const out = [];
|
|
344
|
+
for (const c of components) {
|
|
345
|
+
if (c.from)
|
|
346
|
+
continue;
|
|
347
|
+
for (const [prop, values] of Object.entries(c.props)) {
|
|
348
|
+
if (values.length !== 1)
|
|
349
|
+
continue;
|
|
350
|
+
const value = values[0];
|
|
351
|
+
// A law is about a DESIGN AXIS or a flag. `marginBottom="1em"` and
|
|
352
|
+
// `textAlign="center"` are CSS escaping through a prop - a real finding,
|
|
353
|
+
// and a different one, but writing "always textAlign=center" as a law of
|
|
354
|
+
// the component is nonsense (dono, 31/07).
|
|
355
|
+
const isAxis = AXIS_SYNONYM[prop.toLowerCase()] != null;
|
|
356
|
+
if (!isAxis && value !== "true")
|
|
357
|
+
continue;
|
|
358
|
+
// The prop's OWN reach, never the component's: `Text` lives in 66 files
|
|
359
|
+
// and `textAlign` may appear in one of them, and the first version
|
|
360
|
+
// claimed all 66 agreed.
|
|
361
|
+
const files = c.propFiles?.[prop] ?? 0;
|
|
362
|
+
if (files < RULE_MIN_FILES)
|
|
363
|
+
continue;
|
|
364
|
+
out.push({
|
|
365
|
+
component: c.name,
|
|
366
|
+
prop,
|
|
367
|
+
value,
|
|
368
|
+
files,
|
|
369
|
+
count: c.count,
|
|
370
|
+
text: value === "true"
|
|
371
|
+
? `Always set ${prop} - every one of the ${files} files that passes it does.`
|
|
372
|
+
: `Always ${prop}="${value}" - all ${files} files that pass it agree.`,
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return out.sort((a, b) => b.files - a.files || b.count - a.count);
|
|
377
|
+
}
|
package/package.json
CHANGED