synthesisui 0.16.53 → 0.16.55
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 +32 -7
- package/dist/doctor/crosswalk.js +47 -1
- package/package.json +1 -1
package/dist/commands/import.js
CHANGED
|
@@ -317,7 +317,25 @@ export async function takeCensus(root) {
|
|
|
317
317
|
},
|
|
318
318
|
propFiles: {},
|
|
319
319
|
}));
|
|
320
|
-
|
|
320
|
+
/**
|
|
321
|
+
* A composed component that is ALSO defined keeps its usage and gains the
|
|
322
|
+
* axes its type declares - the declaration wins per axis, because it is the
|
|
323
|
+
* closed set the author designed.
|
|
324
|
+
*
|
|
325
|
+
* Without this the usage silently truncated the contract: `MetricCard` is
|
|
326
|
+
* composed once with `size="xsm"`, so its axis had ONE option and was dropped
|
|
327
|
+
* by the two-option rule, while its type declares four sizes and three
|
|
328
|
+
* variants (dono, 31/07). The component would have reached the platform with
|
|
329
|
+
* no contract at all, which is the exact thing reading definitions was for.
|
|
330
|
+
*/
|
|
331
|
+
const declaredBy = new Map(defined.map((d) => [d.name, d]));
|
|
332
|
+
const enriched = inventory.map((c) => {
|
|
333
|
+
const d = declaredBy.get(c.name);
|
|
334
|
+
if (!d || Object.keys(d.axes).length === 0)
|
|
335
|
+
return c;
|
|
336
|
+
return { ...c, props: { ...c.props, ...d.axes } };
|
|
337
|
+
});
|
|
338
|
+
const merged = [...enriched, ...fromTypes];
|
|
321
339
|
// The verdict travels WITH the payload: the platform reads one reading rather
|
|
322
340
|
// than computing a second opinion from the same numbers, which is how two
|
|
323
341
|
// implementations of the same judgement start disagreeing.
|
|
@@ -388,9 +406,13 @@ function summarize(c) {
|
|
|
388
406
|
// The inventory, phase one: what this project composes. Printed, never
|
|
389
407
|
// mapped - deciding that their `Pill` is our `ds-badge` is a judgement a
|
|
390
408
|
// person approves, and it does not happen in a census.
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
409
|
+
// COMPOSED means composed. The payload also carries components that are only
|
|
410
|
+
// DECLARED (a library exports what it never uses), and counting those here
|
|
411
|
+
// made the line say 108 where 80 things are actually composed (dono, 31/07).
|
|
412
|
+
const composedOnly = (c.components ?? []).filter((x) => x.count > 0);
|
|
413
|
+
if (composedOnly.length > 0) {
|
|
414
|
+
const withProps = composedOnly.filter((x) => Object.keys(x.props).length > 0).length;
|
|
415
|
+
console.log(body(`${composedOnly.length} components composed here, ${withProps} of them with props written literally`));
|
|
394
416
|
}
|
|
395
417
|
if (c.totals.named > 0) {
|
|
396
418
|
console.log(body(`${paint.strong(String(c.totals.named))} of those values ALREADY have a name in your system - ${c.totals.coverage}% of your design values come from it today`));
|
|
@@ -422,7 +444,7 @@ function printComponents(c) {
|
|
|
422
444
|
if (list.length === 0)
|
|
423
445
|
return;
|
|
424
446
|
console.log("");
|
|
425
|
-
const mine = list.filter((x) => !x.from);
|
|
447
|
+
const mine = list.filter((x) => !x.from && x.count > 0);
|
|
426
448
|
const theirs = list.filter((x) => x.from);
|
|
427
449
|
console.log(section("What this project composes"));
|
|
428
450
|
if (theirs.length > 0) {
|
|
@@ -439,7 +461,7 @@ function printComponents(c) {
|
|
|
439
461
|
if (mine.length > 12) {
|
|
440
462
|
console.log(body(paint.faint(`(${mine.length - 12} more of yours)`)));
|
|
441
463
|
}
|
|
442
|
-
printCrosswalk(
|
|
464
|
+
printCrosswalk(list.filter((x) => !x.from));
|
|
443
465
|
printObserved(mine);
|
|
444
466
|
printDefined(c, mine);
|
|
445
467
|
}
|
|
@@ -468,7 +490,10 @@ function printDefined(census, used) {
|
|
|
468
490
|
if (withAxes.length > 8) {
|
|
469
491
|
console.log(body(paint.faint(` (${withAxes.length - 8} more)`)));
|
|
470
492
|
}
|
|
471
|
-
|
|
493
|
+
// Orphans are found by asking what has no USAGE, so this has to see the
|
|
494
|
+
// composed list alone: handing it the union made every declared component
|
|
495
|
+
// look used by itself, and 29 orphans became 1.
|
|
496
|
+
const crossed = reconcile(defined, used.filter((u) => u.count > 0));
|
|
472
497
|
const dead = crossed.filter((r) => r.deadOptions.length > 0);
|
|
473
498
|
const stray = crossed.filter((r) => r.undeclared.length > 0);
|
|
474
499
|
const orphans = crossed.filter((r) => r.orphan);
|
package/dist/doctor/crosswalk.js
CHANGED
|
@@ -238,6 +238,28 @@ export const TWIN_OVERLAP = 0.5;
|
|
|
238
238
|
* the colour work learned twice: a ratio over a tiny set says nothing.
|
|
239
239
|
*/
|
|
240
240
|
export const TWIN_MIN_SHARED = 2;
|
|
241
|
+
/**
|
|
242
|
+
* Axes that measure rather than mean.
|
|
243
|
+
*
|
|
244
|
+
* Every component has a size, and `sm|md|lg` is the same three words in all of
|
|
245
|
+
* them - so a shared size scale is a shared SCALE, never a shared purpose. It
|
|
246
|
+
* paired a metric card with a text input at 50% (dono, 31/07), which is the
|
|
247
|
+
* kind of finding that teaches a person to stop reading the list.
|
|
248
|
+
*
|
|
249
|
+
* `intent`, `tone`, `status` and their kin are what say what a thing IS, and a
|
|
250
|
+
* pair needs at least one of those in common before its sizes count for
|
|
251
|
+
* anything.
|
|
252
|
+
*/
|
|
253
|
+
const DIMENSIONAL = new Set(["size", "density"]);
|
|
254
|
+
/**
|
|
255
|
+
* Values that are the absence of a choice.
|
|
256
|
+
*
|
|
257
|
+
* `default` and `neutral` appear on almost every axis and mean "nothing in
|
|
258
|
+
* particular", so sharing them is not agreement. With sizes excluded, a metric
|
|
259
|
+
* card and a text input still paired because both offer a `default` variant
|
|
260
|
+
* (dono, 31/07) - the same false positive one level down.
|
|
261
|
+
*/
|
|
262
|
+
const UNCHOSEN = new Set(["neutral", "default", "none", "normal", "base"]);
|
|
241
263
|
function sharedCount(a, b) {
|
|
242
264
|
const va = new Set();
|
|
243
265
|
const vb = new Set();
|
|
@@ -259,6 +281,29 @@ function sharedCount(a, b) {
|
|
|
259
281
|
n += 1;
|
|
260
282
|
return n;
|
|
261
283
|
}
|
|
284
|
+
/** Shared values on an axis that MEANS something, not one that measures. */
|
|
285
|
+
function sharedMeaning(a, b) {
|
|
286
|
+
const pick = (x) => {
|
|
287
|
+
const out = new Set();
|
|
288
|
+
for (const [p, values] of Object.entries(x)) {
|
|
289
|
+
const axis = AXIS_SYNONYM[p.toLowerCase()];
|
|
290
|
+
if (!axis || DIMENSIONAL.has(axis))
|
|
291
|
+
continue;
|
|
292
|
+
for (const v of canonicalValues(values)) {
|
|
293
|
+
if (!UNCHOSEN.has(v))
|
|
294
|
+
out.add(v);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return out;
|
|
298
|
+
};
|
|
299
|
+
const va = pick(a);
|
|
300
|
+
const vb = pick(b);
|
|
301
|
+
let n = 0;
|
|
302
|
+
for (const v of va)
|
|
303
|
+
if (vb.has(v))
|
|
304
|
+
n += 1;
|
|
305
|
+
return n;
|
|
306
|
+
}
|
|
262
307
|
export function crosswalk(components) {
|
|
263
308
|
const mine = components.filter((c) => !c.from);
|
|
264
309
|
// Two of THEIR components reading as the same catalogue entry is the
|
|
@@ -294,7 +339,8 @@ export function crosswalk(components) {
|
|
|
294
339
|
overlap: axisOverlap(component.props, o.props),
|
|
295
340
|
}))
|
|
296
341
|
.filter((t) => t.overlap >= TWIN_OVERLAP &&
|
|
297
|
-
sharedCount(component.props, mine.find((m) => m.name === t.name)?.props ?? {}) >= TWIN_MIN_SHARED
|
|
342
|
+
sharedCount(component.props, mine.find((m) => m.name === t.name)?.props ?? {}) >= TWIN_MIN_SHARED &&
|
|
343
|
+
sharedMeaning(component.props, mine.find((m) => m.name === t.name)?.props ?? {}) >= 1)
|
|
298
344
|
.sort((a, b) => b.overlap - a.overlap);
|
|
299
345
|
if (canonical && CATALOGUE[canonical]) {
|
|
300
346
|
const alsoClaiming = (claims.get(canonical) ?? []).filter((n) => n !== component.name);
|
package/package.json
CHANGED