@morscherlab/mint-sdk 1.0.44 → 1.0.46

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 (53) hide show
  1. package/dist/__tests__/components/SmartGroupFieldRecipe.groups.test.d.ts +1 -0
  2. package/dist/__tests__/components/SmartGroupManual.cohorts.test.d.ts +1 -0
  3. package/dist/components/AutoGroupModal.adapter.d.ts +42 -0
  4. package/dist/components/AutoGroupModal.vue.d.ts +1 -105
  5. package/dist/components/DataFrame.vue.d.ts +15 -0
  6. package/dist/components/SmartGroup.types.d.ts +71 -0
  7. package/dist/components/SmartGroupFieldRecipe.groups.d.ts +53 -0
  8. package/dist/components/SmartGroupFieldRecipe.vue.d.ts +37 -0
  9. package/dist/components/SmartGroupManual.cohorts.d.ts +52 -0
  10. package/dist/components/SmartGroupManual.vue.d.ts +17 -0
  11. package/dist/components/SmartGroupModal.vue.d.ts +27 -0
  12. package/dist/components/index.d.ts +3 -0
  13. package/dist/components/index.js +2 -2
  14. package/dist/{components-BGVwavdd.js → components-C7UFkNIp.js} +3036 -2751
  15. package/dist/components-C7UFkNIp.js.map +1 -0
  16. package/dist/composables/index.js +2 -2
  17. package/dist/{composables-C_hPF0Gn.js → composables-CpBhNKHf.js} +7 -147
  18. package/dist/composables-CpBhNKHf.js.map +1 -0
  19. package/dist/index.js +4 -4
  20. package/dist/install.js +1 -1
  21. package/dist/styles.css +12824 -12195
  22. package/dist/{useProtocolTemplates-BbvlHoPD.js → useProtocolTemplates-C8-YlHj1.js} +206 -66
  23. package/dist/useProtocolTemplates-C8-YlHj1.js.map +1 -0
  24. package/package.json +1 -1
  25. package/src/__tests__/components/AutoGroupModal.adapter.test.ts +164 -0
  26. package/src/__tests__/components/DataFrame.test.ts +100 -0
  27. package/src/__tests__/components/SampleSelector.test.ts +176 -16
  28. package/src/__tests__/components/SmartGroupFieldRecipe.groups.test.ts +96 -0
  29. package/src/__tests__/components/SmartGroupManual.cohorts.test.ts +97 -0
  30. package/src/components/AutoGroupModal.adapter.ts +147 -0
  31. package/src/components/AutoGroupModal.vue +176 -1321
  32. package/src/components/DataFrame.vue +97 -5
  33. package/src/components/SampleSelector.vue +8 -23
  34. package/src/components/SmartGroup.types.ts +93 -0
  35. package/src/components/SmartGroupFieldRecipe.groups.ts +105 -0
  36. package/src/components/SmartGroupFieldRecipe.story.vue +58 -0
  37. package/src/components/SmartGroupFieldRecipe.vue +427 -0
  38. package/src/components/SmartGroupManual.cohorts.ts +112 -0
  39. package/src/components/SmartGroupManual.story.vue +55 -0
  40. package/src/components/SmartGroupManual.vue +398 -0
  41. package/src/components/SmartGroupModal.story.vue +61 -0
  42. package/src/components/SmartGroupModal.vue +61 -0
  43. package/src/components/index.ts +3 -0
  44. package/src/styles/components/dataframe.css +79 -0
  45. package/src/styles/components/sample-selector.css +1 -5
  46. package/src/styles/components/smart-group.css +708 -0
  47. package/src/styles/index.css +1 -1
  48. package/dist/components-BGVwavdd.js.map +0 -1
  49. package/dist/composables-C_hPF0Gn.js.map +0 -1
  50. package/dist/useProtocolTemplates-BbvlHoPD.js.map +0 -1
  51. package/src/__tests__/components/AutoGroupModal.preview.test.ts +0 -46
  52. package/src/styles/components/auto-group-modal.css +0 -1336
  53. /package/dist/__tests__/components/{AutoGroupModal.preview.test.d.ts → AutoGroupModal.adapter.test.d.ts} +0 -0
@@ -836,70 +836,6 @@ function useWellPlateEditor(initialState, options = {}) {
836
836
  };
837
837
  }
838
838
  //#endregion
839
- //#region src/composables/useExpansionSet.ts
840
- /** Shared expansion state for trees, grouped selectors, and disclosure lists. */
841
- function useExpansionSet(options = {}) {
842
- const expandedIds = ref(new Set(normalizeIds(toValue(options.defaultIds))));
843
- const expandedList = computed(() => [...expandedIds.value]);
844
- if (options.expandAll !== void 0) watch(() => toValue(options.expandAll), (shouldExpandAll) => {
845
- if (shouldExpandAll === void 0 || shouldExpandAll === null) return;
846
- if (shouldExpandAll) setExpanded(normalizeIds(toValue(options.allIds)));
847
- else reset();
848
- }, { immediate: true });
849
- if (options.allIds !== void 0) watch(() => normalizeIds(toValue(options.allIds)), (ids) => {
850
- if (toValue(options.expandAll)) setExpanded(ids);
851
- });
852
- function isExpanded(id) {
853
- return expandedIds.value.has(id);
854
- }
855
- function expand(id) {
856
- if (expandedIds.value.has(id)) return;
857
- expandedIds.value = new Set([...expandedIds.value, id]);
858
- }
859
- function collapse(id) {
860
- if (!expandedIds.value.has(id)) return;
861
- const next = new Set(expandedIds.value);
862
- next.delete(id);
863
- expandedIds.value = next;
864
- }
865
- function toggle(id) {
866
- if (expandedIds.value.has(id)) {
867
- collapse(id);
868
- return false;
869
- }
870
- expand(id);
871
- return true;
872
- }
873
- function expandMany(ids) {
874
- expandedIds.value = new Set([...expandedIds.value, ...normalizeIds(ids)]);
875
- }
876
- function setExpanded(ids) {
877
- expandedIds.value = new Set(normalizeIds(ids));
878
- }
879
- function collapseAll() {
880
- expandedIds.value = /* @__PURE__ */ new Set();
881
- }
882
- function reset() {
883
- setExpanded(normalizeIds(toValue(options.defaultIds)));
884
- }
885
- return {
886
- expandedIds,
887
- expandedList,
888
- isExpanded,
889
- expand,
890
- collapse,
891
- toggle,
892
- expandMany,
893
- setExpanded,
894
- collapseAll,
895
- reset
896
- };
897
- }
898
- function normalizeIds(ids) {
899
- if (!ids) return [];
900
- return [...new Set(ids.filter(Boolean))];
901
- }
902
- //#endregion
903
839
  //#region src/composables/autoGroup/tokenize.ts
904
840
  var DELIMITER_CANDIDATES = [
905
841
  "_",
@@ -2406,6 +2342,146 @@ function constrainParsedSamplesToInput(parsed, samples) {
2406
2342
  };
2407
2343
  }
2408
2344
  //#endregion
2345
+ //#region src/composables/useFileImport.ts
2346
+ /** Stateful file reader for plugin import flows with shared validation and error handling. */
2347
+ function useFileImport(options = {}) {
2348
+ const loading = shallowRef(false);
2349
+ const error = ref(null);
2350
+ const fileName = ref("");
2351
+ const result = ref(null);
2352
+ function clear() {
2353
+ loading.value = false;
2354
+ error.value = null;
2355
+ fileName.value = "";
2356
+ result.value = null;
2357
+ }
2358
+ async function importFile(file) {
2359
+ loading.value = true;
2360
+ error.value = null;
2361
+ fileName.value = file.name;
2362
+ try {
2363
+ validateImportFile(file, options);
2364
+ const text = await readFileAsText(file, options.encoding);
2365
+ const parsed = options.parse ? await options.parse(text, file) : text;
2366
+ result.value = parsed;
2367
+ return parsed;
2368
+ } catch (err) {
2369
+ error.value = readErrorMessage(err);
2370
+ throw err;
2371
+ } finally {
2372
+ loading.value = false;
2373
+ }
2374
+ }
2375
+ return {
2376
+ loading,
2377
+ error,
2378
+ fileName,
2379
+ result,
2380
+ importFile,
2381
+ clear
2382
+ };
2383
+ }
2384
+ function validateImportFile(file, options = {}) {
2385
+ if (options.maxSizeBytes !== void 0 && file.size > options.maxSizeBytes) throw new Error(`File is too large. Maximum size is ${formatBytes(options.maxSizeBytes)}.`);
2386
+ const accept = normalizeAccept(options.accept);
2387
+ if (accept.length === 0) return;
2388
+ const name = file.name.toLowerCase();
2389
+ const type = file.type.toLowerCase();
2390
+ if (!accept.some((entry) => {
2391
+ if (entry.startsWith(".")) return name.endsWith(entry);
2392
+ if (entry.endsWith("/*")) return type.startsWith(entry.slice(0, -1));
2393
+ return type === entry;
2394
+ })) throw new Error(`Unsupported file type. Expected ${accept.join(", ")}.`);
2395
+ }
2396
+ function readFileAsText(file, encoding) {
2397
+ if (typeof FileReader === "undefined" && typeof file.text === "function") return file.text();
2398
+ return new Promise((resolve, reject) => {
2399
+ const reader = new FileReader();
2400
+ reader.onload = () => resolve(String(reader.result ?? ""));
2401
+ reader.onerror = () => reject(reader.error ?? /* @__PURE__ */ new Error("Failed to read file."));
2402
+ reader.readAsText(file, encoding);
2403
+ });
2404
+ }
2405
+ function parseDelimitedText(text, options = {}) {
2406
+ const trim = options.trim ?? true;
2407
+ const delimiter = options.delimiter ?? detectDelimiter(text);
2408
+ const rawRows = parseDelimitedRows(text, delimiter).filter((row) => row.some((cell) => cell.trim().length > 0)).map((row) => trim ? row.map((cell) => cell.trim()) : row);
2409
+ const hasHeaderRow = options.hasHeaderRow ?? !options.headers;
2410
+ const columns = options.headers ? [...options.headers] : hasHeaderRow ? rawRows[0] ?? [] : createColumnNames(maxRowLength(rawRows));
2411
+ return {
2412
+ columns,
2413
+ rows: (hasHeaderRow && !options.headers ? rawRows.slice(1) : rawRows).map((row) => Object.fromEntries(columns.map((column, index) => [column, row[index] ?? ""]))),
2414
+ rawRows,
2415
+ delimiter
2416
+ };
2417
+ }
2418
+ function detectDelimiter(text) {
2419
+ const firstLine = text.split(/\r?\n/, 1)[0] ?? "";
2420
+ const commaCount = countChar(firstLine, ",");
2421
+ const tabCount = countChar(firstLine, " ");
2422
+ const semicolonCount = countChar(firstLine, ";");
2423
+ if (tabCount > commaCount && tabCount >= semicolonCount) return " ";
2424
+ if (semicolonCount > commaCount) return ";";
2425
+ return ",";
2426
+ }
2427
+ function parseDelimitedRows(text, delimiter) {
2428
+ const rows = [];
2429
+ let row = [];
2430
+ let field = "";
2431
+ let quoted = false;
2432
+ for (let index = 0; index < text.length; index++) {
2433
+ const char = text[index];
2434
+ const next = text[index + 1];
2435
+ if (char === "\"") {
2436
+ if (quoted && next === "\"") {
2437
+ field += "\"";
2438
+ index++;
2439
+ } else quoted = !quoted;
2440
+ continue;
2441
+ }
2442
+ if (!quoted && char === delimiter) {
2443
+ row.push(field);
2444
+ field = "";
2445
+ continue;
2446
+ }
2447
+ if (!quoted && (char === "\n" || char === "\r")) {
2448
+ if (char === "\r" && next === "\n") index++;
2449
+ row.push(field);
2450
+ rows.push(row);
2451
+ row = [];
2452
+ field = "";
2453
+ continue;
2454
+ }
2455
+ field += char;
2456
+ }
2457
+ row.push(field);
2458
+ rows.push(row);
2459
+ return rows;
2460
+ }
2461
+ function normalizeAccept(accept) {
2462
+ if (!accept) return [];
2463
+ return (typeof accept === "string" ? accept.split(",") : [...accept]).map((entry) => entry.trim().toLowerCase()).filter(Boolean);
2464
+ }
2465
+ function createColumnNames(count) {
2466
+ return Array.from({ length: count }, (_, index) => `column_${index + 1}`);
2467
+ }
2468
+ function maxRowLength(rows) {
2469
+ return rows.reduce((max, row) => Math.max(max, row.length), 0);
2470
+ }
2471
+ function countChar(value, char) {
2472
+ return [...value].filter((candidate) => candidate === char).length;
2473
+ }
2474
+ function formatBytes(bytes) {
2475
+ if (bytes < 1024) return `${bytes} B`;
2476
+ if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
2477
+ return `${Math.round(bytes / (1024 * 1024))} MB`;
2478
+ }
2479
+ function readErrorMessage(value) {
2480
+ if (value instanceof Error && value.message) return value.message;
2481
+ if (typeof value === "string" && value.trim()) return value;
2482
+ return "Failed to import file.";
2483
+ }
2484
+ //#endregion
2409
2485
  //#region src/utils/color.ts
2410
2486
  var HEX_RE = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i;
2411
2487
  function clamp(n, min, max) {
@@ -2566,6 +2642,70 @@ function getMajorGroupName(groupName, separator) {
2566
2642
  return parts.length > 1 ? parts[0] : groupName;
2567
2643
  }
2568
2644
  //#endregion
2645
+ //#region src/composables/useExpansionSet.ts
2646
+ /** Shared expansion state for trees, grouped selectors, and disclosure lists. */
2647
+ function useExpansionSet(options = {}) {
2648
+ const expandedIds = ref(new Set(normalizeIds(toValue(options.defaultIds))));
2649
+ const expandedList = computed(() => [...expandedIds.value]);
2650
+ if (options.expandAll !== void 0) watch(() => toValue(options.expandAll), (shouldExpandAll) => {
2651
+ if (shouldExpandAll === void 0 || shouldExpandAll === null) return;
2652
+ if (shouldExpandAll) setExpanded(normalizeIds(toValue(options.allIds)));
2653
+ else reset();
2654
+ }, { immediate: true });
2655
+ if (options.allIds !== void 0) watch(() => normalizeIds(toValue(options.allIds)), (ids) => {
2656
+ if (toValue(options.expandAll)) setExpanded(ids);
2657
+ });
2658
+ function isExpanded(id) {
2659
+ return expandedIds.value.has(id);
2660
+ }
2661
+ function expand(id) {
2662
+ if (expandedIds.value.has(id)) return;
2663
+ expandedIds.value = new Set([...expandedIds.value, id]);
2664
+ }
2665
+ function collapse(id) {
2666
+ if (!expandedIds.value.has(id)) return;
2667
+ const next = new Set(expandedIds.value);
2668
+ next.delete(id);
2669
+ expandedIds.value = next;
2670
+ }
2671
+ function toggle(id) {
2672
+ if (expandedIds.value.has(id)) {
2673
+ collapse(id);
2674
+ return false;
2675
+ }
2676
+ expand(id);
2677
+ return true;
2678
+ }
2679
+ function expandMany(ids) {
2680
+ expandedIds.value = new Set([...expandedIds.value, ...normalizeIds(ids)]);
2681
+ }
2682
+ function setExpanded(ids) {
2683
+ expandedIds.value = new Set(normalizeIds(ids));
2684
+ }
2685
+ function collapseAll() {
2686
+ expandedIds.value = /* @__PURE__ */ new Set();
2687
+ }
2688
+ function reset() {
2689
+ setExpanded(normalizeIds(toValue(options.defaultIds)));
2690
+ }
2691
+ return {
2692
+ expandedIds,
2693
+ expandedList,
2694
+ isExpanded,
2695
+ expand,
2696
+ collapse,
2697
+ toggle,
2698
+ expandMany,
2699
+ setExpanded,
2700
+ collapseAll,
2701
+ reset
2702
+ };
2703
+ }
2704
+ function normalizeIds(ids) {
2705
+ if (!ids) return [];
2706
+ return [...new Set(ids.filter(Boolean))];
2707
+ }
2708
+ //#endregion
2569
2709
  //#region src/composables/platformContextHelpers.ts
2570
2710
  function getInjectedPlatformContext() {
2571
2711
  if (typeof window === "undefined") return void 0;
@@ -4348,6 +4488,6 @@ function useProtocolTemplates() {
4348
4488
  };
4349
4489
  }
4350
4490
  //#endregion
4351
- export { extractSampleNamesFromDesignData as A, APP_EXPERIMENT_KEY as B, useSampleGroups as C, extractSamplesFromDesignData as D, hslToHex as E, useExpansionSet as F, normalizeSearchQuery as G, useTheme as H, useWellPlateEditor as I, useSortedItems as J, useTextSearch as K, useDoseCalculator as L, unwrapExperimentDesignData as M, DEFAULT_COLORS as N, useAutoGroup as O, classKey as P, DEFAULT_MOBILE_VIEWPORT_QUERY as R, resolveCurrentExperimentId as S, hexToHsl as T, useToast as U, useAppExperiment as V, candidateMatchesSearch as W, useScheduleDrag as _, useReagentSeries as a, currentExperimentFromContext as b, useBioTemplatePresetWorkspace as c, getBioTemplateComponentProps as d, toBioTemplateComponentPropsByComponent as f, useExperimentSave as g, useTemplateCollection as h, generateDilutionSeries as i, extractSampleOptionsFromDesignData as j, parseCSV as k, useBioTemplatePackWorkspace as l, useBioTemplateControls as m, DEFAULT_PRESETS as n, useGroupAssignment as o, useBioTemplateComponents as p, compareSortValues as q, DEFAULT_UNITS as r, useRackEditor as s, useProtocolTemplates as t, useBioTemplateWorkspace as u, useExperimentSamples as v, deriveShade as w, getInjectedPlatformContext as x, useExperimentData as y, useMobileSupportGate as z };
4491
+ export { readFileAsText as A, useWellPlateEditor as B, useExpansionSet as C, hslToHex as D, hexToHsl as E, parseCSV as F, useAppExperiment as G, DEFAULT_MOBILE_VIEWPORT_QUERY as H, extractSampleNamesFromDesignData as I, candidateMatchesSearch as J, useTheme as K, extractSampleOptionsFromDesignData as L, validateImportFile as M, extractSamplesFromDesignData as N, detectDelimiter as O, useAutoGroup as P, useSortedItems as Q, unwrapExperimentDesignData as R, resolveCurrentExperimentId as S, deriveShade as T, useMobileSupportGate as U, useDoseCalculator as V, APP_EXPERIMENT_KEY as W, useTextSearch as X, normalizeSearchQuery as Y, compareSortValues as Z, useScheduleDrag as _, useReagentSeries as a, currentExperimentFromContext as b, useBioTemplatePresetWorkspace as c, getBioTemplateComponentProps as d, toBioTemplateComponentPropsByComponent as f, useExperimentSave as g, useTemplateCollection as h, generateDilutionSeries as i, useFileImport as j, parseDelimitedText as k, useBioTemplatePackWorkspace as l, useBioTemplateControls as m, DEFAULT_PRESETS as n, useGroupAssignment as o, useBioTemplateComponents as p, useToast as q, DEFAULT_UNITS as r, useRackEditor as s, useProtocolTemplates as t, useBioTemplateWorkspace as u, useExperimentSamples as v, useSampleGroups as w, getInjectedPlatformContext as x, useExperimentData as y, DEFAULT_COLORS as z };
4352
4492
 
4353
- //# sourceMappingURL=useProtocolTemplates-BbvlHoPD.js.map
4493
+ //# sourceMappingURL=useProtocolTemplates-C8-YlHj1.js.map