@morscherlab/mint-sdk 1.3.0 → 1.3.1

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.
Files changed (67) hide show
  1. package/dist/__tests__/components/AutoGroupModal.anatomy.test.d.ts +1 -0
  2. package/dist/__tests__/components/AutoGroupModal.wiring.test.d.ts +1 -0
  3. package/dist/__tests__/composables/autoGroup/fieldEdits.test.d.ts +1 -0
  4. package/dist/__tests__/composables/autoGroup/golden.test.d.ts +1 -0
  5. package/dist/components/AutoGroupModal.adapter.d.ts +27 -4
  6. package/dist/components/SmartGroup.types.d.ts +22 -0
  7. package/dist/components/SmartGroupFieldRecipe.groups.d.ts +10 -2
  8. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +3 -0
  9. package/dist/components/index.js +1 -1
  10. package/dist/{components-vHfxV2PB.js → components-bbanLd1u.js} +499 -263
  11. package/dist/components-bbanLd1u.js.map +1 -0
  12. package/dist/composables/autoGroup/classify.d.ts +7 -1
  13. package/dist/composables/autoGroup/columns.d.ts +16 -1
  14. package/dist/composables/autoGroup/index.d.ts +5 -7
  15. package/dist/composables/autoGroup/tokenize.d.ts +36 -1
  16. package/dist/composables/index.js +2 -2
  17. package/dist/composables/useAutoGroup.d.ts +13 -2
  18. package/dist/{composables-D6uqp0UF.js → composables-BbHozlA7.js} +2 -2
  19. package/dist/{composables-D6uqp0UF.js.map → composables-BbHozlA7.js.map} +1 -1
  20. package/dist/index.js +3 -3
  21. package/dist/install.js +1 -1
  22. package/dist/permissions.js +2 -2
  23. package/dist/permissions.js.map +1 -1
  24. package/dist/styles.css +71 -82
  25. package/dist/types/auto-group.d.ts +1 -1
  26. package/dist/{validation-Dmp9Q5W0.js → validation-CukfLjy-.js} +323 -187
  27. package/dist/validation-CukfLjy-.js.map +1 -0
  28. package/package.json +2 -2
  29. package/src/__tests__/components/AutoGroupModal.anatomy.test.ts +86 -0
  30. package/src/__tests__/components/AutoGroupModal.wiring.test.ts +53 -0
  31. package/src/__tests__/components/SampleSelector.test.ts +14 -16
  32. package/src/__tests__/components/SmartGroupFieldRecipe.groups.test.ts +23 -0
  33. package/src/__tests__/components/SmartGroupFieldRecipe.test.ts +176 -0
  34. package/src/__tests__/composables/autoGroup/columns.test.ts +100 -11
  35. package/src/__tests__/composables/autoGroup/fieldEdits.test.ts +74 -0
  36. package/src/__tests__/composables/autoGroup/fingerprint.test.ts +9 -0
  37. package/src/__tests__/composables/autoGroup/golden.test.ts +187 -0
  38. package/src/__tests__/composables/autoGroup/groupByOrder.test.ts +7 -7
  39. package/src/__tests__/composables/autoGroup/tokenLength.test.ts +7 -0
  40. package/src/__tests__/composables/autoGroup/tokenize.test.ts +78 -1
  41. package/src/__tests__/composables/useAutoGroup.test.ts +2 -1
  42. package/src/__tests__/fixtures/auto-group/share-exp021.txt +103 -0
  43. package/src/__tests__/fixtures/auto-group/share-exp031.txt +39 -0
  44. package/src/__tests__/fixtures/auto-group/share-exp114.txt +123 -0
  45. package/src/__tests__/fixtures/auto-group/share-exp214.txt +63 -0
  46. package/src/__tests__/utils/permissions.test.ts +15 -0
  47. package/src/components/AutoGroupModal.adapter.ts +80 -9
  48. package/src/components/AutoGroupModal.vue +41 -8
  49. package/src/components/SmartGroup.types.ts +23 -0
  50. package/src/components/SmartGroupFieldRecipe.groups.ts +14 -2
  51. package/src/components/SmartGroupFieldRecipe.vue +289 -169
  52. package/src/composables/autoGroup/classify.ts +26 -7
  53. package/src/composables/autoGroup/columns.ts +144 -36
  54. package/src/composables/autoGroup/compose.ts +8 -10
  55. package/src/composables/autoGroup/fingerprint.ts +1 -1
  56. package/src/composables/autoGroup/index.ts +5 -12
  57. package/src/composables/autoGroup/tokenLength.ts +8 -0
  58. package/src/composables/autoGroup/tokenize.ts +148 -1
  59. package/src/composables/autoGroup/vocab.json +5 -11
  60. package/src/composables/useAutoGroup.ts +92 -79
  61. package/src/permissions.ts +3 -2
  62. package/src/styles/components/smart-group.css +71 -82
  63. package/src/types/auto-group.ts +1 -0
  64. package/dist/components-vHfxV2PB.js.map +0 -1
  65. package/dist/composables/autoGroup/replicatePreGroup.d.ts +0 -36
  66. package/dist/validation-Dmp9Q5W0.js.map +0 -1
  67. package/src/composables/autoGroup/replicatePreGroup.ts +0 -124
package/dist/styles.css CHANGED
@@ -10244,22 +10244,6 @@ html.dark .mint-toast__item {
10244
10244
  }
10245
10245
  .sg-field__toggle { grid-row: 1 / 3; grid-column: 2; align-self: center; }
10246
10246
 
10247
- /* toggle switch */
10248
- .sg-switch {
10249
- position: relative; width: 1.65rem; height: 0.95rem;
10250
- border-radius: 9999px; background: var(--bg-tertiary);
10251
- border: none; cursor: pointer; flex-shrink: 0;
10252
- transition: background 0.15s ease;
10253
- }
10254
- .sg-switch.on { background: var(--color-primary); }
10255
- .sg-switch::after {
10256
- content: ''; position: absolute; top: 0.125rem; left: 0.125rem;
10257
- width: 0.7rem; height: 0.7rem; border-radius: 9999px;
10258
- background: #fff; box-shadow: 0 1px 2px rgb(0 0 0 / 0.25);
10259
- transition: transform 0.15s ease;
10260
- }
10261
- .sg-switch.on::after { transform: translateX(0.7rem); }
10262
-
10263
10247
  /* ==========================================================================
10264
10248
  Shared — live group preview (right rail)
10265
10249
  ========================================================================== */
@@ -10313,18 +10297,8 @@ html.dark .mint-toast__item {
10313
10297
  font-size: 0.6875rem; font-weight: 600;
10314
10298
  color: var(--text-secondary);
10315
10299
  }
10316
- .sg-qc__route {
10317
- margin-left: auto;
10318
- font: inherit; font-size: 0.75rem; font-weight: 500;
10319
- color: var(--text-secondary);
10320
- padding: 0.1875rem 1.5rem 0.1875rem 0.5rem;
10321
- background: var(--bg-secondary);
10322
- background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%2394a3b8' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
10323
- background-position: right 0.25rem center; background-repeat: no-repeat;
10324
- background-size: 1.1em 1.1em;
10325
- border: 1px solid var(--border-color); border-radius: var(--radius-sm);
10326
- appearance: none; cursor: pointer;
10327
- }
10300
+ .fr-qc__route { margin-left: auto; }
10301
+ .fr-qc__chips { display: flex; flex-wrap: wrap; gap: 0.25rem; }
10328
10302
  .sg-qc__chip {
10329
10303
  display: inline-flex; align-items: center; gap: 0.375rem;
10330
10304
  padding: 0.25rem 0.5rem; border-radius: var(--radius);
@@ -10371,47 +10345,85 @@ html.dark .mint-toast__item {
10371
10345
  /* ==========================================================================
10372
10346
  Field Recipe refinements (layered on the shared chrome above)
10373
10347
  ========================================================================== */
10348
+ /* Section label above the anatomy and each field list. */
10349
+ .fr-label { font-size: 0.75rem; font-weight: 600; color: var(--text-secondary); }
10350
+
10351
+ /* One-line field row: [grip] [layer] name [rename] values [hint] [toggle]. */
10374
10352
  .fr .sg-field {
10375
- grid-template-columns: 1fr auto;
10376
- grid-template-rows: auto auto;
10377
- row-gap: 0.25rem;
10378
- padding: 0.5rem 0.75rem;
10353
+ display: flex; align-items: center; gap: 0.5rem;
10354
+ padding: 0.375rem 0.625rem;
10379
10355
  }
10380
- .fr-field__head { display: flex; align-items: center; gap: 0.5rem; }
10381
- .fr .sg-field__role { margin-left: 0; }
10382
- .fr .sg-field__vals { grid-column: 1 / 2; grid-row: 2; }
10383
- .fr-switch { grid-column: 2; grid-row: 1 / 3; align-self: center; }
10384
-
10385
- /* Layer-order controls: which hierarchy layer this field forms, plus reorder. */
10386
- .sg-field__order {
10387
- grid-column: 1 / 3;
10388
- display: flex; align-items: center; gap: 0.25rem;
10356
+ .fr .sg-field__name { white-space: nowrap; }
10357
+ .fr .sg-field__role { margin-left: 0; white-space: nowrap; }
10358
+ .fr .sg-field__vals { flex: 1; min-width: 0; }
10359
+ .fr-row__grip,
10360
+ .fr-row__rename {
10361
+ display: inline-flex; align-items: center; justify-content: center;
10362
+ width: 1.25rem; height: 1.25rem; padding: 0; flex-shrink: 0;
10363
+ border: none; border-radius: var(--radius-sm); background: none;
10364
+ color: var(--text-muted); cursor: pointer;
10365
+ transition: background 0.15s ease, color 0.15s ease;
10389
10366
  }
10390
- .sg-field__layer {
10391
- font-size: 0.6875rem; font-weight: 600;
10392
- color: var(--color-primary);
10393
- padding: 0.0625rem 0.375rem; border-radius: 9999px;
10394
- background: var(--color-primary-soft);
10395
- margin-right: auto;
10367
+ .fr-row__grip { cursor: grab; }
10368
+ .fr-row__grip:hover,
10369
+ .fr-row__rename:hover { color: var(--text-primary); background: var(--bg-hover); }
10370
+ .fr-row__grip:focus-visible,
10371
+ .fr-row__rename:focus-visible { outline: none; box-shadow: var(--focus-ring-soft); }
10372
+ /* Which hierarchy layer this field forms (1 = the sample selector's major group). */
10373
+ .fr-row__layer {
10374
+ display: inline-grid; place-items: center; flex-shrink: 0;
10375
+ width: 1.25rem; height: 1.25rem; border-radius: 9999px;
10376
+ border: 1px solid var(--color-primary);
10377
+ background: var(--bg-secondary); color: var(--_ink-primary);
10378
+ font-size: 0.6875rem; font-weight: 700; font-variant-numeric: tabular-nums;
10396
10379
  }
10397
- .sg-field__order-btn {
10398
- display: inline-flex; align-items: center; justify-content: center;
10399
- width: 1.25rem; height: 1.25rem; padding: 0;
10400
- border: 1px solid var(--border-color); border-radius: 0.375rem;
10401
- background: var(--bg-primary); color: var(--text-secondary);
10402
- cursor: pointer; transition: background 0.15s ease, color 0.15s ease;
10380
+ .fr-row__name-input {
10381
+ width: 9rem; padding: 0.0625rem 0.375rem;
10382
+ font: inherit; font-size: 0.875rem; font-weight: 600; color: var(--text-primary);
10383
+ border: 1px solid var(--color-primary); border-radius: var(--radius-sm);
10384
+ background: var(--bg-secondary);
10385
+ }
10386
+ .fr-row__name-input:focus-visible { outline: none; box-shadow: var(--focus-ring-soft); }
10387
+ /* Groups that remain when this field is switched off. */
10388
+ .fr-row__hint {
10389
+ font-size: 0.75rem; font-weight: 500; color: var(--text-secondary-strong);
10390
+ white-space: nowrap; font-variant-numeric: tabular-nums;
10403
10391
  }
10404
- .sg-field__order-btn:hover:not(:disabled) { background: var(--bg-tertiary); color: var(--text-primary); }
10405
- .sg-field__order-btn:disabled { opacity: 0.4; cursor: default; }
10392
+ /* The message is dark text (AA on the tinted row); the input border carries the error colour. */
10393
+ .fr-row__error { font-size: 0.75rem; font-weight: 600; color: var(--text-primary); white-space: nowrap; }
10394
+ .fr-row__name-input[aria-invalid='true'] { border-color: var(--_ink-error); box-shadow: var(--focus-ring-error); }
10395
+ .fr-row--dragging { opacity: 0.5; }
10396
+ .fr-row--over { box-shadow: inset 0 2px 0 var(--color-primary); }
10406
10397
 
10407
- /* Replicate-on: the field card itself warns instead of silently shattering. */
10398
+ /* Replicate-on: the field row itself warns instead of silently shattering. */
10408
10399
  .fr-field--warn.sg-field--on {
10409
10400
  border-color: var(--mint-warning-border);
10410
10401
  background: var(--mint-warning-bg);
10411
10402
  }
10412
- .fr-field--warn.sg-field--on .fr-switch.on { background: var(--mint-warning); }
10413
- .fr-field--warn.sg-field--on .sg-field__role--rep {
10414
- color: #fff; background: var(--mint-warning);
10403
+ .fr-field--warn.sg-field--on .fr-row__layer { border-color: var(--mint-warning); color: var(--text-primary); }
10404
+
10405
+ /* Name anatomy: the tokens of one example sample and the role of each. */
10406
+ .fr-anatomy { display: flex; flex-direction: column; gap: 0.375rem; }
10407
+ .fr-anatomy__tokens { display: flex; flex-wrap: wrap; gap: 0.375rem 0.5rem; }
10408
+ .fr-token { display: inline-flex; flex-direction: column; align-items: center; gap: 0.125rem; }
10409
+ .fr-token__text {
10410
+ font-family: var(--font-mono); font-size: 0.75rem; font-weight: 500;
10411
+ padding: 0.125rem 0.375rem; border-radius: var(--radius-sm);
10412
+ border: 1px solid var(--border-color); background: var(--bg-tertiary);
10413
+ color: var(--text-secondary-strong);
10414
+ }
10415
+ .fr-token__caption { font-size: 0.6875rem; color: var(--text-secondary-strong); white-space: nowrap; }
10416
+ .fr-token--on .fr-token__text {
10417
+ border-color: var(--color-primary); background: var(--color-primary-soft);
10418
+ color: var(--text-primary);
10419
+ }
10420
+ .fr-token--on .fr-token__caption { color: var(--_ink-primary); font-weight: 700; }
10421
+ .fr-token--off .fr-token__text { border-style: dashed; background: transparent; }
10422
+
10423
+ /* No samples: say what to do. */
10424
+ .fr-blank {
10425
+ display: flex; flex-direction: column; align-items: flex-start; gap: 0.5rem;
10426
+ padding: 1rem 0;
10415
10427
  }
10416
10428
 
10417
10429
  /* Neutral (no-selection) summary variant. */
@@ -10736,29 +10748,6 @@ html.dark .sg-summary code { background: rgba(255, 255, 255, 0.1); }
10736
10748
  background: var(--bg-tertiary); color: var(--text-primary); border-color: var(--text-muted);
10737
10749
  }
10738
10750
  .fr-upload:focus-visible { outline: none; box-shadow: var(--focus-ring-soft); }
10739
- .fr-csv { position: relative; }
10740
- .fr-csv-menu {
10741
- position: absolute; top: calc(100% + 0.25rem); right: 0; z-index: 10;
10742
- min-width: 11rem; padding: 0.25rem;
10743
- display: flex; flex-direction: column; gap: 0.0625rem;
10744
- background: var(--bg-secondary);
10745
- border: 1px solid var(--border-color); border-radius: var(--radius-md);
10746
- box-shadow: var(--shadow-lg);
10747
- }
10748
- .fr-csv-item {
10749
- display: flex; align-items: center; gap: 0.5rem;
10750
- font: inherit; font-size: 0.8125rem; font-weight: 500; text-align: left;
10751
- color: var(--text-primary); cursor: pointer;
10752
- padding: 0.4375rem 0.5rem; border: none; border-radius: var(--radius);
10753
- background: none; transition: background 0.12s ease, color 0.12s ease;
10754
- }
10755
- .fr-csv-item:hover { background: var(--bg-hover); }
10756
- .fr-csv-item:disabled {
10757
- /* disabled cue: muted colour + struck label + not-allowed, not opacity alone */
10758
- color: var(--text-muted); cursor: not-allowed; opacity: 0.7;
10759
- text-decoration: line-through; text-decoration-color: var(--text-muted);
10760
- }
10761
- .fr-csv-item:disabled:hover { background: none; }
10762
10751
  /* anchor the drop overlay to the main panel */
10763
10752
  .sg-body__main { position: relative; }
10764
10753
  .fr-dropzone {
@@ -35,7 +35,7 @@ export interface SampleClass {
35
35
  */
36
36
  tokenLength?: number;
37
37
  }
38
- export type ColumnRole = 'constant' | 'factor' | 'replicate' | 'run-order' | 'numeric' | 'class-tag' | 'ignore';
38
+ export type ColumnRole = 'constant' | 'factor' | 'replicate' | 'run-order' | 'id' | 'numeric' | 'class-tag' | 'ignore';
39
39
  export interface NumericParse {
40
40
  value: number;
41
41
  unit: string;