synthesisui 0.16.54 → 0.16.56
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 +25 -1
- package/dist/doctor/crosswalk.js +47 -1
- package/package.json +1 -1
package/dist/commands/import.js
CHANGED
|
@@ -317,7 +317,31 @@ 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
|
+
* Carried BESIDE the usage rather than written into it. The first attempt
|
|
332
|
+
* merged the declaration into `props` and broke the two readings that need
|
|
333
|
+
* `props` to mean "what the code passed": the composition list started
|
|
334
|
+
* showing declared options as composed, and the dead-option check went quiet
|
|
335
|
+
* because every declared option now looked used.
|
|
336
|
+
*/
|
|
337
|
+
const declaredBy = new Map(defined.map((d) => [d.name, d]));
|
|
338
|
+
const enriched = inventory.map((c) => {
|
|
339
|
+
const d = declaredBy.get(c.name);
|
|
340
|
+
if (!d || Object.keys(d.axes).length === 0)
|
|
341
|
+
return c;
|
|
342
|
+
return { ...c, declaredAxes: d.axes };
|
|
343
|
+
});
|
|
344
|
+
const merged = [...enriched, ...fromTypes];
|
|
321
345
|
// The verdict travels WITH the payload: the platform reads one reading rather
|
|
322
346
|
// than computing a second opinion from the same numbers, which is how two
|
|
323
347
|
// implementations of the same judgement start disagreeing.
|
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