@milaboratories/multi-sequence-alignment 1.45.0

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 (114) hide show
  1. package/.turbo/turbo-build.log +52 -0
  2. package/.turbo/turbo-lint.log +12 -0
  3. package/.turbo/turbo-test.log +13 -0
  4. package/.turbo/turbo-type-check.log +6 -0
  5. package/dist/Consensus.vue.d.ts +9 -0
  6. package/dist/Consensus.vue.js +10 -0
  7. package/dist/Consensus.vue.js.map +1 -0
  8. package/dist/Consensus.vue2.js +122 -0
  9. package/dist/Consensus.vue2.js.map +1 -0
  10. package/dist/Consensus.vue3.js +9 -0
  11. package/dist/Consensus.vue3.js.map +1 -0
  12. package/dist/Legend.vue.d.ts +6 -0
  13. package/dist/Legend.vue.js +10 -0
  14. package/dist/Legend.vue.js.map +1 -0
  15. package/dist/Legend.vue2.js +28 -0
  16. package/dist/Legend.vue2.js.map +1 -0
  17. package/dist/Legend.vue3.js +13 -0
  18. package/dist/Legend.vue3.js.map +1 -0
  19. package/dist/MultiSequenceAlignmentView.vue.d.ts +25 -0
  20. package/dist/MultiSequenceAlignmentView.vue.js +10 -0
  21. package/dist/MultiSequenceAlignmentView.vue.js.map +1 -0
  22. package/dist/MultiSequenceAlignmentView.vue2.js +138 -0
  23. package/dist/MultiSequenceAlignmentView.vue2.js.map +1 -0
  24. package/dist/MultiSequenceAlignmentView.vue3.js +31 -0
  25. package/dist/MultiSequenceAlignmentView.vue3.js.map +1 -0
  26. package/dist/PhylogeneticTree.vue.d.ts +8 -0
  27. package/dist/PhylogeneticTree.vue.js +10 -0
  28. package/dist/PhylogeneticTree.vue.js.map +1 -0
  29. package/dist/PhylogeneticTree.vue2.js +77 -0
  30. package/dist/PhylogeneticTree.vue2.js.map +1 -0
  31. package/dist/PhylogeneticTree.vue3.js +9 -0
  32. package/dist/PhylogeneticTree.vue3.js.map +1 -0
  33. package/dist/PlMultiSequenceAlignment.vue.d.ts +71 -0
  34. package/dist/PlMultiSequenceAlignment.vue.js +10 -0
  35. package/dist/PlMultiSequenceAlignment.vue.js.map +1 -0
  36. package/dist/PlMultiSequenceAlignment.vue2.js +224 -0
  37. package/dist/PlMultiSequenceAlignment.vue2.js.map +1 -0
  38. package/dist/PlMultiSequenceAlignment.vue3.js +9 -0
  39. package/dist/PlMultiSequenceAlignment.vue3.js.map +1 -0
  40. package/dist/SeqLogo.vue.d.ts +8 -0
  41. package/dist/SeqLogo.vue.js +10 -0
  42. package/dist/SeqLogo.vue.js.map +1 -0
  43. package/dist/SeqLogo.vue2.js +127 -0
  44. package/dist/SeqLogo.vue2.js.map +1 -0
  45. package/dist/SeqLogo.vue3.js +9 -0
  46. package/dist/SeqLogo.vue3.js.map +1 -0
  47. package/dist/Toolbar.vue.d.ts +16 -0
  48. package/dist/Toolbar.vue.js +10 -0
  49. package/dist/Toolbar.vue.js.map +1 -0
  50. package/dist/Toolbar.vue2.js +228 -0
  51. package/dist/Toolbar.vue2.js.map +1 -0
  52. package/dist/Toolbar.vue3.js +19 -0
  53. package/dist/Toolbar.vue3.js.map +1 -0
  54. package/dist/_virtual/_plugin-vue_export-helper.js +10 -0
  55. package/dist/_virtual/_plugin-vue_export-helper.js.map +1 -0
  56. package/dist/assets/multi-sequence-alignment.worker-Cm0gZp19.js +6 -0
  57. package/dist/assets/multi-sequence-alignment.worker-Cm0gZp19.js.map +1 -0
  58. package/dist/assets/phylogenetic-tree.worker-4CrExYEo.js +5 -0
  59. package/dist/assets/phylogenetic-tree.worker-4CrExYEo.js.map +1 -0
  60. package/dist/cell-size.d.ts +4 -0
  61. package/dist/cell-size.js +8 -0
  62. package/dist/cell-size.js.map +1 -0
  63. package/dist/chemical-properties.d.ts +44 -0
  64. package/dist/chemical-properties.js +132 -0
  65. package/dist/chemical-properties.js.map +1 -0
  66. package/dist/data.d.ts +61 -0
  67. package/dist/data.js +370 -0
  68. package/dist/data.js.map +1 -0
  69. package/dist/index.d.ts +1 -0
  70. package/dist/index.js +6 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/markup.d.ts +16 -0
  73. package/dist/markup.js +84 -0
  74. package/dist/markup.js.map +1 -0
  75. package/dist/migrations.d.ts +3 -0
  76. package/dist/migrations.js +24 -0
  77. package/dist/migrations.js.map +1 -0
  78. package/dist/multi-sequence-alignment.worker.d.ts +6 -0
  79. package/dist/node_modules/.pnpm/@milaboratories_helpers@1.12.0/node_modules/@milaboratories/helpers/dist/objects.js +33 -0
  80. package/dist/node_modules/.pnpm/@milaboratories_helpers@1.12.0/node_modules/@milaboratories/helpers/dist/objects.js.map +1 -0
  81. package/dist/phylogenetic-tree.worker.d.ts +7 -0
  82. package/dist/residue-counts.d.ts +2 -0
  83. package/dist/residue-counts.js +13 -0
  84. package/dist/residue-counts.js.map +1 -0
  85. package/dist/settings.d.ts +2 -0
  86. package/dist/settings.js +9 -0
  87. package/dist/settings.js.map +1 -0
  88. package/dist/types.d.ts +5 -0
  89. package/dist/useMiPlots.d.ts +4 -0
  90. package/dist/useMiPlots.js +19 -0
  91. package/dist/useMiPlots.js.map +1 -0
  92. package/eslint.config.js +66 -0
  93. package/package.json +45 -0
  94. package/src/Consensus.vue +165 -0
  95. package/src/Legend.vue +44 -0
  96. package/src/MultiSequenceAlignmentView.vue +299 -0
  97. package/src/PhylogeneticTree.vue +110 -0
  98. package/src/PlMultiSequenceAlignment.vue +314 -0
  99. package/src/README.md +216 -0
  100. package/src/SeqLogo.vue +166 -0
  101. package/src/Toolbar.vue +228 -0
  102. package/src/cell-size.ts +4 -0
  103. package/src/chemical-properties.ts +199 -0
  104. package/src/data.ts +661 -0
  105. package/src/index.ts +2 -0
  106. package/src/markup.ts +141 -0
  107. package/src/migrations.ts +46 -0
  108. package/src/multi-sequence-alignment.worker.ts +54 -0
  109. package/src/phylogenetic-tree.worker.ts +89 -0
  110. package/src/residue-counts.ts +124 -0
  111. package/src/settings.ts +7 -0
  112. package/src/types.ts +3 -0
  113. package/src/useMiPlots.ts +23 -0
  114. package/tsconfig.json +10 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sources":["../src/data.ts"],"sourcesContent":["import { isJsonEqual } from '@milaboratories/helpers';\nimport type { ListOptionNormalized } from '@milaboratories/uikit';\nimport {\n Annotation,\n type CalculateTableDataRequest,\n type CalculateTableDataResponse,\n type CanonicalizedJson,\n canonicalizeJson,\n createRowSelectionColumn,\n ensureError,\n getAxisId,\n getRawPlatformaInstance,\n isLabelColumn,\n isLinkerColumn,\n type JoinEntry,\n matchAxisId,\n parseJson,\n type PColumnIdAndSpec,\n type PFrameHandle,\n type PlMultiSequenceAlignmentColorSchemeOption,\n type PlMultiSequenceAlignmentSettings,\n type PlSelectionModel,\n type PObjectId,\n type PTableColumnId,\n type PTableSorting,\n pTableValue,\n readAnnotation,\n readAnnotationJson,\n} from '@platforma-sdk/model';\nimport { onWatcherCleanup, ref, watch } from 'vue';\nimport { objectHash } from '@platforma-sdk/ui-vue';\nimport { highlightByChemicalProperties } from './chemical-properties';\nimport type { Markup } from './markup';\nimport {\n highlightByMarkup,\n markupAlignedSequence,\n parseMarkup,\n} from './markup';\nimport type * as MultiSequenceAlignmentWorker from './multi-sequence-alignment.worker';\nimport type * as PhylogeneticTreeWorker from './phylogenetic-tree.worker';\nimport { getResidueCounts } from './residue-counts';\nimport type { HighlightLegend, ResidueCounts } from './types';\n\nconst getPFrameDriver = () => getRawPlatformaInstance().pFrameDriver;\n\nexport const SEQUENCE_LIMIT = 1000;\n\nexport const useSequenceColumnsOptions = refreshOnDeepChange(\n getSequenceColumnsOptions,\n);\n\nexport const useLabelColumnsOptions = refreshOnDeepChange(\n getLabelColumnsOptions,\n);\n\nexport const useMarkupColumnsOptions = refreshOnDeepChange(\n getMarkupColumnsOptions,\n);\n\nexport const useMultipleAlignmentData = refreshOnDeepChange(\n getMultipleAlignmentData,\n);\n\nasync function getSequenceColumnsOptions({ pFrame, sequenceColumnPredicate }: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnPredicate: (column: PColumnIdAndSpec) => boolean;\n}): Promise<OptionsWithDefaults<PObjectId> | undefined> {\n if (!pFrame) return;\n\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n\n const options = columns.values()\n .filter((column) => sequenceColumnPredicate(column))\n .map(({ spec, columnId }) => ({\n label: readAnnotation(spec, Annotation.Label) ?? 'Unlabeled column',\n value: columnId,\n }))\n .toArray();\n\n const defaults = options.map(({ value }) => value);\n\n return { options, defaults };\n}\n\nasync function getLabelColumnsOptions({ pFrame, sequenceColumnIds }: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnIds: PObjectId[] | undefined;\n}): Promise<OptionsWithDefaults<PTableColumnId> | undefined> {\n if (!pFrame || !sequenceColumnIds) return;\n\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n\n const sequenceColumnsAxes = new Map(\n sequenceColumnIds.values().flatMap((id) => {\n const column = columns.find(({ columnId }) => columnId === id);\n if (!column) {\n throw new Error(`Couldn't find sequence column (ID: \\`${id}\\`).`);\n }\n return column.spec.axesSpec.values()\n .map((spec) => [canonicalizeJson(getAxisId(spec)), spec]);\n }),\n );\n\n const optionMap = new Map<CanonicalizedJson<PTableColumnId>, string>();\n for (const [axisIdJson, axisSpec] of sequenceColumnsAxes.entries()) {\n const axisId = parseJson(axisIdJson);\n const labelColumn = columns.find(({ spec }) =>\n isLabelColumn(spec) && matchAxisId(axisId, getAxisId(spec.axesSpec[0])),\n );\n optionMap.set(\n labelColumn\n ? canonicalizeJson({ type: 'column', id: labelColumn.columnId })\n : canonicalizeJson({ type: 'axis', id: axisId }),\n readAnnotation(labelColumn?.spec, Annotation.Label)\n ?? readAnnotation(axisSpec, Annotation.Label)\n ?? 'Unlabeled axis',\n );\n }\n\n const { hits: compatibleColumns } = await pFrameDriver.findColumns(pFrame, {\n columnFilter: {},\n compatibleWith: sequenceColumnsAxes.keys()\n .map((axisIdJson) => parseJson(axisIdJson))\n .toArray(),\n strictlyCompatible: false,\n });\n\n for (const { columnId, spec } of compatibleColumns) {\n const columnIdJson = canonicalizeJson<PTableColumnId>({\n type: 'column',\n id: columnId,\n });\n if (optionMap.has(columnIdJson)) continue;\n optionMap.set(\n columnIdJson,\n readAnnotation(spec, Annotation.Label) ?? 'Unlabeled column',\n );\n }\n\n const options = optionMap.entries()\n .map(([value, label]) => ({ label, value: parseJson(value) }))\n .toArray();\n\n const defaults = options.values()\n .filter(({ value }) => {\n if (value.type === 'axis') return true;\n const column = columns.find(({ columnId }) => columnId === value.id);\n return column && isLabelColumn(column.spec);\n })\n .map(({ value }) => value)\n .toArray();\n\n return { options, defaults };\n}\n\nasync function getMarkupColumnsOptions({ pFrame, sequenceColumnIds }: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnIds: PObjectId[] | undefined;\n}): Promise<ListOptionNormalized<PObjectId[]>[] | undefined> {\n if (!pFrame || !sequenceColumnIds) return;\n\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n\n const sequenceColumns = sequenceColumnIds.map((columnId) => {\n const column = columns.find((column) => column.columnId === columnId);\n if (!column) {\n throw new Error(\n `Couldn't find sequence column (ID: \\`${sequenceColumnIds[0]}\\`).`,\n );\n }\n return column;\n });\n\n const columnPairs = sequenceColumns\n .flatMap((sequenceColumn) =>\n columns\n .filter((column) =>\n readAnnotationJson(column.spec, Annotation.Sequence.IsAnnotation)\n && isJsonEqual(sequenceColumn.spec.axesSpec, column.spec.axesSpec)\n && Object.entries(sequenceColumn.spec.domain ?? {})\n .every(([key, value]) => column.spec.domain?.[key] === value),\n )\n .map((markupColumn) => ({ markupColumn, sequenceColumn })),\n );\n\n const groupedByDomainDiff = Map.groupBy(\n columnPairs,\n ({ markupColumn, sequenceColumn }) => {\n const domainDiff = Object.fromEntries(\n Object.entries(markupColumn.spec.domain ?? {})\n .filter(([key]) => sequenceColumn.spec.domain?.[key] == undefined),\n );\n return canonicalizeJson(domainDiff);\n },\n );\n\n return groupedByDomainDiff.entries()\n .map(([domainDiffJson, columnPairs]) => ({\n label: Object.values(parseJson(domainDiffJson)).join(', '),\n value: columnPairs.map(({ markupColumn }) => markupColumn.columnId),\n }))\n .toArray();\n}\n\nasync function getMultipleAlignmentData(\n {\n pFrame,\n sequenceColumnIds,\n labelColumnIds,\n selection,\n colorScheme,\n alignmentParams,\n shouldBuildPhylogeneticTree,\n }: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnIds: PObjectId[] | undefined;\n labelColumnIds: PTableColumnId[] | undefined;\n selection: PlSelectionModel | undefined;\n colorScheme: PlMultiSequenceAlignmentColorSchemeOption;\n alignmentParams: PlMultiSequenceAlignmentSettings['alignmentParams'];\n shouldBuildPhylogeneticTree: boolean;\n },\n abortSignal: AbortSignal,\n): Promise<MultipleAlignmentData | undefined> {\n if (!pFrame || !sequenceColumnIds?.length || !labelColumnIds) return;\n\n const table = await getTableData({\n pFrame,\n sequenceColumnIds,\n labelColumnIds,\n selection,\n colorScheme,\n });\n\n const rowCount = table.at(0)?.data.data.length ?? 0;\n\n if (rowCount < 2) return;\n\n const exceedsLimit = rowCount > SEQUENCE_LIMIT;\n const rawSequences = extractSequences(sequenceColumnIds, table);\n const labels = extractLabels(labelColumnIds, table);\n const markups = colorScheme.type === 'markup'\n ? extractMarkups(colorScheme.columnIds, table)\n : undefined;\n\n const highlightLegend: HighlightLegend = {};\n\n const alignedSequences = await Promise.all(\n rawSequences.map(async ({ name, rows }) => ({\n name,\n rows: await alignSequences(\n rows,\n JSON.parse(JSON.stringify(alignmentParams)),\n abortSignal,\n ),\n })),\n );\n\n let phylogeneticTree: PhylogeneticTreeWorker.TreeNodeData[] | undefined;\n if (shouldBuildPhylogeneticTree) {\n phylogeneticTree = await buildPhylogeneticTree(\n alignedSequences,\n abortSignal,\n );\n const rowOrder = phylogeneticTree.values()\n .filter(({ id }) => id >= 0)\n .map(({ id }) => id)\n .toArray();\n for (const sequencesColumn of alignedSequences) {\n sequencesColumn.rows = rowOrder.map((i) => sequencesColumn.rows[i]);\n }\n for (const labelsColumn of labels) {\n labelsColumn.rows = rowOrder.map((i) => labelsColumn.rows[i]);\n }\n for (const markupsColumn of markups ?? []) {\n markupsColumn.rows = rowOrder.map((i) => markupsColumn.rows[i]);\n }\n }\n\n const sequences = await Promise.all(\n alignedSequences.map(async ({ name, rows }, index) => {\n const residueCounts = getResidueCounts(rows);\n const image = generateHighlightImage({\n colorScheme,\n sequences: rows,\n residueCounts,\n markup: markups?.at(index),\n });\n if (image) {\n Object.assign(highlightLegend, image.legend);\n }\n return {\n name,\n rows,\n residueCounts,\n ...image && {\n highlightImageUrl: await blobToBase64(image.blob),\n },\n } satisfies MultipleAlignmentData['sequences'][number];\n }),\n );\n\n return {\n sequences,\n labels,\n ...Object.keys(highlightLegend).length && {\n highlightLegend,\n },\n ...phylogeneticTree && {\n phylogeneticTree,\n },\n exceedsLimit,\n };\n}\n\nasync function getTableData(\n { pFrame, sequenceColumnIds, labelColumnIds, selection, colorScheme }: {\n pFrame: PFrameHandle;\n sequenceColumnIds: PObjectId[];\n labelColumnIds: PTableColumnId[];\n selection: PlSelectionModel | undefined;\n colorScheme: PlMultiSequenceAlignmentColorSchemeOption;\n },\n): Promise<CalculateTableDataResponse> {\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n const linkerColumns = columns.filter((column) => isLinkerColumn(column.spec));\n\n const filterColumn = createRowSelectionColumn({ selection });\n\n // inner join of sequence columns\n let primaryEntry: JoinEntry<PObjectId> = {\n type: 'inner',\n entries: sequenceColumnIds.map((column) => ({\n type: 'column',\n column,\n })),\n };\n\n // if we have linkers, left join them\n if (linkerColumns.length > 0) {\n primaryEntry = {\n type: 'outer',\n primary: primaryEntry,\n secondary: linkerColumns.map(({ columnId }) => ({\n type: 'column',\n column: columnId,\n })),\n };\n }\n\n // inner join with filters\n if (filterColumn) {\n primaryEntry = {\n type: 'inner',\n entries: [\n primaryEntry,\n {\n type: 'inlineColumn',\n column: filterColumn,\n },\n ],\n };\n }\n\n // left join with labels\n const secondaryEntry: JoinEntry<PObjectId>[] = labelColumnIds\n .flatMap((column) => {\n if (column.type !== 'column') return [];\n return { type: 'column', column: column.id };\n });\n\n // and markup\n if (colorScheme.type === 'markup') {\n for (const column of colorScheme.columnIds) {\n secondaryEntry.push({ type: 'column', column });\n }\n }\n\n const sorting: PTableSorting[] = Array.from(\n new Set(\n sequenceColumnIds.values().flatMap((id) => {\n const column = columns.find(({ columnId }) => columnId === id);\n if (!column) {\n throw new Error(`Couldn't find sequence column (ID: ${id})`);\n }\n return column.spec.axesSpec\n .map((spec) => canonicalizeJson(getAxisId(spec)));\n }),\n ),\n )\n .sort()\n .map((id) => ({\n column: { type: 'axis', id: parseJson(id) },\n ascending: true,\n naAndAbsentAreLeastValues: true,\n }));\n\n const request: CalculateTableDataRequest<PObjectId> = {\n src: {\n type: 'outer',\n primary: primaryEntry,\n secondary: secondaryEntry,\n },\n filters: [],\n sorting,\n };\n\n return pFrameDriver.calculateTableData(\n pFrame,\n JSON.parse(JSON.stringify(request)),\n {\n offset: 0,\n // +1 is a hack to check whether the selection is over the limit\n length: SEQUENCE_LIMIT + 1,\n },\n );\n}\n\nconst extractSequences = (\n columnIds: PObjectId[],\n table: CalculateTableDataResponse,\n): { name: string; rows: string[] }[] =>\n columnIds.map((columnId) => {\n const column = table.find(({ spec }) => spec.id === columnId);\n if (!column) {\n throw new Error(`Couldn't find sequence column (ID: \\`${columnId}\\`).`);\n }\n const name = readAnnotation(column.spec.spec, Annotation.Label)\n ?? 'Unlabeled column';\n const rows = column.data.data\n .keys()\n .take(SEQUENCE_LIMIT)\n .map((row) =>\n pTableValue(column.data, row, { absent: '', na: '' })?.toString()\n ?? '',\n )\n .toArray();\n return { name, rows };\n });\n\nconst extractLabels = (\n columnIds: PTableColumnId[],\n table: CalculateTableDataResponse,\n): { rows: string[] }[] =>\n columnIds.map((columnId) => {\n const column = table.find(({ spec }) => {\n if (columnId.type === 'axis' && spec.type === 'axis') {\n return isJsonEqual(columnId.id, spec.id);\n }\n if (columnId.type === 'column' && spec.type === 'column') {\n return columnId.id === spec.id;\n }\n });\n if (!column) {\n throw new Error(`Couldn't find label column (ID: \\`${columnId}\\`).`);\n }\n const rows = column.data.data\n .keys()\n .take(SEQUENCE_LIMIT)\n .map((row) =>\n pTableValue(column.data, row, { absent: '', na: '' })?.toString()\n ?? '',\n )\n .toArray();\n return { rows };\n });\n\nconst extractMarkups = (\n columnIds: PObjectId[],\n table: CalculateTableDataResponse,\n): { labels: Record<string, string>; rows: Markup[] }[] =>\n columnIds.map((columnId) => {\n const column = table.find(({ spec }) => spec.id === columnId);\n if (!column) {\n throw new Error(`Couldn't find markup column (ID: \\`${columnId}\\`).`);\n }\n const labels = readAnnotationJson(\n column.spec.spec,\n Annotation.Sequence.Annotation.Mapping,\n ) ?? {};\n const rows = column.data.data\n .keys()\n .take(SEQUENCE_LIMIT)\n .map((row) =>\n parseMarkup(\n pTableValue(column.data, row, { absent: '', na: '' })?.toString()\n ?? '',\n ),\n )\n .toArray();\n return { labels, rows };\n });\n\nconst alignSequences = (() => {\n const cache = new Map<string, string[]>();\n return async (\n sequences: string[],\n alignmentParams: PlMultiSequenceAlignmentSettings['alignmentParams'],\n abortSignal: AbortSignal,\n ): Promise<string[]> => {\n const hash = await objectHash([sequences, alignmentParams]);\n let result = cache.get(hash);\n if (result) return result;\n result = await runInWorker<\n MultiSequenceAlignmentWorker.RequestMessage,\n MultiSequenceAlignmentWorker.ResponseMessage\n >(\n new Worker(\n new URL('./multi-sequence-alignment.worker.ts', import.meta.url),\n { type: 'module' },\n ),\n { sequences, params: alignmentParams },\n abortSignal,\n );\n cache.set(hash, result);\n return result;\n };\n})();\n\nfunction generateHighlightImage(\n { colorScheme, sequences, residueCounts, markup }: {\n colorScheme: PlMultiSequenceAlignmentColorSchemeOption;\n sequences: string[];\n residueCounts: ResidueCounts;\n markup: { labels: Record<string, string>; rows: Markup[] } | undefined;\n },\n): { blob: Blob; legend: HighlightLegend } | undefined {\n if (colorScheme.type === 'chemical-properties') {\n return highlightByChemicalProperties({ sequences, residueCounts });\n }\n if (colorScheme.type === 'markup') {\n if (!markup) {\n throw new Error('Missing markup data.');\n }\n return highlightByMarkup({\n markupRows: sequences.map((sequence, row) => {\n const markupRow = markup.rows.at(row);\n if (!markupRow) throw new Error(`Missing markup for row ${row}.`);\n return markupAlignedSequence(sequence, markupRow);\n }),\n columnCount: sequences.at(0)?.length ?? 0,\n labels: markup.labels,\n });\n }\n}\n\nconst blobToBase64 = (blob: Blob): Promise<string> =>\n new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.addEventListener('load', () => resolve(reader.result as string));\n reader.addEventListener('error', () => reject(reader.error));\n reader.readAsDataURL(blob);\n });\n\nconst buildPhylogeneticTree = (() => {\n const cache = new Map<string, PhylogeneticTreeWorker.TreeNodeData[]>();\n return async (data: { rows: string[] }[], abortSignal: AbortSignal) => {\n const concatenatedSequences = data.at(0)?.rows\n .keys()\n .map((row) => data.map((column) => column.rows.at(row) ?? '').join(''))\n .toArray() ?? [];\n const hash = await objectHash(concatenatedSequences);\n let result = cache.get(hash);\n if (result) return result;\n result = await runInWorker<\n PhylogeneticTreeWorker.RequestMessage,\n PhylogeneticTreeWorker.ResponseMessage\n >(\n new Worker(\n new URL('./phylogenetic-tree.worker.ts', import.meta.url),\n { type: 'module' },\n ),\n concatenatedSequences,\n abortSignal,\n );\n cache.set(hash, result);\n return result;\n };\n})();\n\nconst runInWorker = <RequestMessage, ResponseMessage>(\n worker: Worker,\n message: RequestMessage,\n abortSignal: AbortSignal,\n) =>\n new Promise<ResponseMessage>((resolve, reject) => {\n worker.addEventListener('message', ({ data }) => {\n resolve(data);\n worker.terminate();\n });\n worker.addEventListener('error', ({ error, message }) => {\n reject(error ?? message);\n worker.terminate();\n });\n abortSignal.addEventListener('abort', () => {\n reject(abortSignal.reason);\n worker.terminate();\n });\n worker.postMessage(message);\n });\n\nfunction refreshOnDeepChange<T, P>(\n cb: (params: P, abortSignal: AbortSignal) => Promise<T>,\n) {\n const data = ref<T>();\n const isLoading = ref(true);\n const error = ref<Error>();\n let requestId: symbol;\n return (paramsGetter: () => P) => {\n watch(paramsGetter, async (params, prevParams) => {\n if (isJsonEqual(params, prevParams)) return;\n const abortController = new AbortController();\n const currentRequestId = requestId = Symbol();\n onWatcherCleanup(() => {\n abortController.abort();\n });\n try {\n error.value = undefined;\n isLoading.value = true;\n const result = await cb(params, abortController.signal);\n if (currentRequestId === requestId) {\n data.value = result;\n }\n } catch (err) {\n console.error(err);\n if (currentRequestId === requestId) {\n error.value = ensureError(err);\n }\n } finally {\n if (currentRequestId === requestId) {\n isLoading.value = false;\n }\n }\n }, { immediate: true });\n return { data, isLoading, error };\n };\n}\n\ntype MultipleAlignmentData = {\n sequences: {\n name: string;\n rows: string[];\n residueCounts: ResidueCounts;\n highlightImageUrl?: string;\n }[];\n labels: {\n rows: string[];\n }[];\n highlightLegend?: HighlightLegend;\n phylogeneticTree?: PhylogeneticTreeWorker.TreeNodeData[];\n exceedsLimit: boolean;\n};\n\ntype OptionsWithDefaults<T> = {\n options: ListOptionNormalized<T>[];\n defaults: T[];\n};\n"],"names":["getPFrameDriver","getRawPlatformaInstance","SEQUENCE_LIMIT","useSequenceColumnsOptions","refreshOnDeepChange","getSequenceColumnsOptions","useLabelColumnsOptions","getLabelColumnsOptions","useMarkupColumnsOptions","getMarkupColumnsOptions","useMultipleAlignmentData","getMultipleAlignmentData","pFrame","sequenceColumnPredicate","options","column","spec","columnId","readAnnotation","Annotation","defaults","value","sequenceColumnIds","pFrameDriver","columns","sequenceColumnsAxes","id","canonicalizeJson","getAxisId","optionMap","axisIdJson","axisSpec","axisId","parseJson","labelColumn","isLabelColumn","matchAxisId","compatibleColumns","columnIdJson","label","columnPairs","sequenceColumn","readAnnotationJson","isJsonEqual","key","_a","markupColumn","domainDiff","domainDiffJson","labelColumnIds","selection","colorScheme","alignmentParams","shouldBuildPhylogeneticTree","abortSignal","table","getTableData","rowCount","exceedsLimit","rawSequences","extractSequences","labels","extractLabels","markups","extractMarkups","highlightLegend","alignedSequences","name","rows","alignSequences","phylogeneticTree","buildPhylogeneticTree","rowOrder","sequencesColumn","i","labelsColumn","markupsColumn","index","residueCounts","getResidueCounts","image","generateHighlightImage","blobToBase64","linkerColumns","isLinkerColumn","filterColumn","createRowSelectionColumn","primaryEntry","secondaryEntry","sorting","request","columnIds","row","pTableValue","parseMarkup","cache","sequences","hash","objectHash","result","runInWorker","markup","highlightByChemicalProperties","highlightByMarkup","sequence","markupRow","markupAlignedSequence","blob","resolve","reject","reader","data","concatenatedSequences","worker","message","error","cb","ref","isLoading","requestId","paramsGetter","watch","params","prevParams","abortController","currentRequestId","onWatcherCleanup","err","ensureError"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { default as PlMultiSequenceAlignment } from './PlMultiSequenceAlignment.vue';
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ import { default as n } from "./PlMultiSequenceAlignment.vue.js";
2
+ console.log("new msa very new msa");
3
+ export {
4
+ n as PlMultiSequenceAlignment
5
+ };
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["console.log('new msa very new msa')\nexport { default as PlMultiSequenceAlignment } from './PlMultiSequenceAlignment.vue';\n"],"names":[],"mappings":";AAAA,QAAQ,IAAI,sBAAsB;"}
@@ -0,0 +1,16 @@
1
+ import { HighlightLegend } from './types';
2
+ export type Markup = {
3
+ id: string;
4
+ start: number;
5
+ length: number;
6
+ }[];
7
+ export declare function parseMarkup(row: string): Markup;
8
+ export declare function markupAlignedSequence(alignedSequence: string, markup: Markup): Markup;
9
+ export declare function highlightByMarkup({ markupRows, columnCount, labels }: {
10
+ markupRows: Markup[];
11
+ columnCount: number;
12
+ labels: Record<string, string>;
13
+ }): {
14
+ blob: Blob;
15
+ legend: HighlightLegend;
16
+ };
package/dist/markup.js ADDED
@@ -0,0 +1,84 @@
1
+ function E(o) {
2
+ return Array.from(o.matchAll(
3
+ /(?<id>[^:]*):(?<start>[0-9A-Za-z]*)(?:\+(?<length>[0-9A-Za-z]*))?\|?/g
4
+ )).map((l) => {
5
+ const r = l.groups, n = Number.parseInt(r.start, 36), t = r.length ? Number.parseInt(r.length, 36) : 0;
6
+ return {
7
+ id: r.id,
8
+ start: n,
9
+ length: t
10
+ };
11
+ });
12
+ }
13
+ function f(o, l) {
14
+ const r = o.split("").reduce(
15
+ (t, a, e) => (a !== "-" && t.push(e), t),
16
+ []
17
+ );
18
+ return l.map((t) => {
19
+ const a = r[t.start], e = r[t.start + t.length - 1] + 1;
20
+ return {
21
+ id: t.id,
22
+ start: a,
23
+ length: e - a
24
+ };
25
+ });
26
+ }
27
+ function C({ markupRows: o, columnCount: l, labels: r }) {
28
+ const n = /* @__PURE__ */ new Map();
29
+ for (const [e, F] of o.entries())
30
+ for (const { id: s, start: u, length: c } of F) {
31
+ let i = n.get(s);
32
+ i || n.set(s, i = []), i.push({ row: e, start: u, length: c });
33
+ }
34
+ const t = Object.fromEntries(
35
+ Object.entries(r).map(
36
+ ([e, F], s) => [
37
+ e,
38
+ {
39
+ label: F,
40
+ color: g[s % g.length]
41
+ }
42
+ ]
43
+ ).filter(([e]) => n.has(e))
44
+ );
45
+ return { blob: new Blob(
46
+ (function* () {
47
+ yield `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${`0 0 ${l} ${o.length * 2}`}" stroke-width="2" preserveAspectRatio="none">`;
48
+ for (const [F, s] of n) {
49
+ const { color: u } = t[F];
50
+ yield `<path stroke="${u}" d="`;
51
+ let c = 0, i = 0;
52
+ for (const { row: d, start: p, length: h } of s)
53
+ yield `m${p - c},${d * 2 + 1 - i}h${h}`, c = p + h, i = d * 2 + 1;
54
+ yield '"/>';
55
+ }
56
+ yield "</svg>";
57
+ })().toArray(),
58
+ { type: "image/svg+xml" }
59
+ ), legend: t };
60
+ }
61
+ const g = [
62
+ "#E5F2FF",
63
+ "#FFE8E8",
64
+ "#F0EBFF",
65
+ "#FFFFE3",
66
+ "#E5F7E5",
67
+ "#FEEAFE",
68
+ "#FDEED6",
69
+ "#E8FDFE",
70
+ "#CCDFF2",
71
+ "#F2CCCD",
72
+ "#D5CCF2",
73
+ "#F2F2CC",
74
+ "#CCF2CC",
75
+ "#F2CCF2",
76
+ "#EFDDBF",
77
+ "#DEEEEF"
78
+ ];
79
+ export {
80
+ C as highlightByMarkup,
81
+ f as markupAlignedSequence,
82
+ E as parseMarkup
83
+ };
84
+ //# sourceMappingURL=markup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markup.js","sources":["../src/markup.ts"],"sourcesContent":["import type { HighlightLegend } from './types';\n\nexport type Markup = { id: string; start: number; length: number }[];\n\nexport function parseMarkup(row: string): Markup {\n return Array.from(row.matchAll(\n /(?<id>[^:]*):(?<start>[0-9A-Za-z]*)(?:\\+(?<length>[0-9A-Za-z]*))?\\|?/g,\n )).map((match) => {\n const matchGroups = match.groups as {\n id: string;\n start: string;\n length: string | undefined;\n };\n const start = Number.parseInt(matchGroups.start, 36);\n const length = matchGroups.length\n ? Number.parseInt(matchGroups.length, 36)\n : 0;\n return {\n id: matchGroups.id,\n start,\n length,\n };\n });\n}\n\nexport function markupAlignedSequence(\n alignedSequence: string,\n markup: Markup,\n): Markup {\n const indexMap = alignedSequence.split('').reduce<number[]>(\n (acc, char, index) => {\n if (char !== '-') acc.push(index);\n return acc;\n },\n [],\n );\n const adjusted = markup.map((segment) => {\n const start = indexMap[segment.start];\n const end = indexMap[segment.start + segment.length - 1] + 1;\n return {\n id: segment.id,\n start: start,\n length: end - start,\n };\n });\n return adjusted;\n}\n\nexport function highlightByMarkup(\n { markupRows, columnCount, labels }: {\n markupRows: Markup[];\n columnCount: number;\n labels: Record<string, string>;\n },\n): { blob: Blob; legend: HighlightLegend } {\n const linesById: Map<string, {\n row: number;\n start: number;\n length: number;\n }[]> = new Map();\n for (const [row, markup] of markupRows.entries()) {\n for (const { id, start, length } of markup) {\n let bucket = linesById.get(id);\n if (!bucket) linesById.set(id, bucket = []);\n bucket.push({ row, start, length });\n }\n }\n const legend: HighlightLegend = Object.fromEntries(\n Object.entries(labels)\n .map(([id, label], index) =>\n [\n id,\n {\n label,\n color: markupColors[index % markupColors.length],\n },\n ] as const,\n )\n .filter(([id]) => linesById.has(id)),\n );\n const blob = new Blob(\n (function*() {\n const viewBox = `0 0 ${columnCount} ${markupRows.length * 2}`;\n yield `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${viewBox}\" stroke-width=\"2\" preserveAspectRatio=\"none\">`;\n for (const [id, lines] of linesById) {\n const { color } = legend[id];\n yield `<path stroke=\"${color}\" d=\"`;\n let x = 0, y = 0;\n for (const { row, start, length } of lines) {\n yield `m${start - x},${row * 2 + 1 - y}h${length}`;\n x = start + length;\n y = row * 2 + 1;\n }\n yield '\"/>';\n }\n yield '</svg>';\n })().toArray(),\n { type: 'image/svg+xml' },\n );\n return { blob, legend };\n}\n\nconst markupColors = [\n '#E5F2FF',\n '#FFE8E8',\n '#F0EBFF',\n '#FFFFE3',\n '#E5F7E5',\n '#FEEAFE',\n '#FDEED6',\n '#E8FDFE',\n '#CCDFF2',\n '#F2CCCD',\n '#D5CCF2',\n '#F2F2CC',\n '#CCF2CC',\n '#F2CCF2',\n '#EFDDBF',\n '#DEEEEF',\n];\n\nif (import.meta.vitest) {\n const { test, expect } = import.meta.vitest;\n test('annotateAlignedRow', () => {\n const alignedSequence\n = 'EVRLVESGGALVQPGGSLRLSCVAASGFTFINNWVTWVRQAPGKGLEWVANIKEDGSQKYYVDSVKGRFTISRDNAEKSVYLQMSSLRVDDTAVYYCAR------------GRAV----D---QWGQGTLVTVSS';\n // 0 10 20 30 40 50 60 70 80 90 100 110 120 130\n // EVRLVESGGALVQPGGSLRLSCVAASGFTFINNWVTWVRQAPGKGLEWVANIKEDGSQKYYVDSVKGRFTISRDNAEKSVYLQMSSLRVDDTAVYYCARGRAVDQWGQGTLVTVSS\n const markup = [\n { id: '1', start: 0, length: 99 },\n { id: '2', start: 99, length: 3 },\n { id: '3', start: 102, length: 14 },\n ];\n const alignedMarkup = markupAlignedSequence(alignedSequence, markup);\n expect(alignedMarkup).toEqual([\n { id: '1', start: 0, length: 99 },\n { id: '2', start: 111, length: 3 },\n { id: '3', start: 114, length: 21 },\n ]);\n });\n}\n"],"names":["parseMarkup","row","match","matchGroups","start","length","markupAlignedSequence","alignedSequence","markup","indexMap","acc","char","index","segment","end","highlightByMarkup","markupRows","columnCount","labels","linesById","id","bucket","legend","label","markupColors","lines","color","x","y"],"mappings":"AAIO,SAASA,EAAYC,GAAqB;AAC/C,SAAO,MAAM,KAAKA,EAAI;AAAA,IACpB;AAAA,EAAA,CACD,EAAE,IAAI,CAACC,MAAU;AAChB,UAAMC,IAAcD,EAAM,QAKpBE,IAAQ,OAAO,SAASD,EAAY,OAAO,EAAE,GAC7CE,IAASF,EAAY,SACvB,OAAO,SAASA,EAAY,QAAQ,EAAE,IACtC;AACJ,WAAO;AAAA,MACL,IAAIA,EAAY;AAAA,MAChB,OAAAC;AAAA,MACA,QAAAC;AAAA,IAAA;AAAA,EAEJ,CAAC;AACH;AAEO,SAASC,EACdC,GACAC,GACQ;AACR,QAAMC,IAAWF,EAAgB,MAAM,EAAE,EAAE;AAAA,IACzC,CAACG,GAAKC,GAAMC,OACND,MAAS,OAAKD,EAAI,KAAKE,CAAK,GACzBF;AAAA,IAET,CAAA;AAAA,EAAC;AAWH,SATiBF,EAAO,IAAI,CAACK,MAAY;AACvC,UAAMT,IAAQK,EAASI,EAAQ,KAAK,GAC9BC,IAAML,EAASI,EAAQ,QAAQA,EAAQ,SAAS,CAAC,IAAI;AAC3D,WAAO;AAAA,MACL,IAAIA,EAAQ;AAAA,MACZ,OAAAT;AAAA,MACA,QAAQU,IAAMV;AAAA,IAAA;AAAA,EAElB,CAAC;AAEH;AAEO,SAASW,EACd,EAAE,YAAAC,GAAY,aAAAC,GAAa,QAAAC,KAKc;AACzC,QAAMC,wBAIK,IAAA;AACX,aAAW,CAAClB,GAAKO,CAAM,KAAKQ,EAAW;AACrC,eAAW,EAAE,IAAAI,GAAI,OAAAhB,GAAO,QAAAC,EAAA,KAAYG,GAAQ;AAC1C,UAAIa,IAASF,EAAU,IAAIC,CAAE;AAC7B,MAAKC,KAAQF,EAAU,IAAIC,GAAIC,IAAS,EAAE,GAC1CA,EAAO,KAAK,EAAE,KAAApB,GAAK,OAAAG,GAAO,QAAAC,GAAQ;AAAA,IACpC;AAEF,QAAMiB,IAA0B,OAAO;AAAA,IACrC,OAAO,QAAQJ,CAAM,EAClB;AAAA,MAAI,CAAC,CAACE,GAAIG,CAAK,GAAGX,MACjB;AAAA,QACEQ;AAAA,QACA;AAAA,UACE,OAAAG;AAAA,UACA,OAAOC,EAAaZ,IAAQY,EAAa,MAAM;AAAA,QAAA;AAAA,MACjD;AAAA,IACF,EAED,OAAO,CAAC,CAACJ,CAAE,MAAMD,EAAU,IAAIC,CAAE,CAAC;AAAA,EAAA;AAqBvC,SAAO,EAAE,MAnBI,IAAI;AAAA,KACd,aAAY;AAEX,YAAM,oDADU,OAAOH,CAAW,IAAID,EAAW,SAAS,CAAC,EACM;AACjE,iBAAW,CAACI,GAAIK,CAAK,KAAKN,GAAW;AACnC,cAAM,EAAE,OAAAO,EAAA,IAAUJ,EAAOF,CAAE;AAC3B,cAAM,iBAAiBM,CAAK;AAC5B,YAAIC,IAAI,GAAGC,IAAI;AACf,mBAAW,EAAE,KAAA3B,GAAK,OAAAG,GAAO,QAAAC,EAAA,KAAYoB;AACnC,gBAAM,IAAIrB,IAAQuB,CAAC,IAAI1B,IAAM,IAAI,IAAI2B,CAAC,IAAIvB,CAAM,IAChDsB,IAAIvB,IAAQC,GACZuB,IAAI3B,IAAM,IAAI;AAEhB,cAAM;AAAA,MACR;AACA,YAAM;AAAA,IACR,GAAA,EAAK,QAAA;AAAA,IACL,EAAE,MAAM,gBAAA;AAAA,EAAgB,GAEX,QAAAqB,EAAA;AACjB;AAEA,MAAME,IAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;"}
@@ -0,0 +1,3 @@
1
+ import { PlMultiSequenceAlignmentModel } from '@platforma-sdk/model';
2
+ import { Ref } from 'vue';
3
+ export declare function runMigrations(model: Ref<PlMultiSequenceAlignmentModel>): void;
@@ -0,0 +1,24 @@
1
+ import { parseJson as u } from "@platforma-sdk/model";
2
+ const o = 2;
3
+ function l(r) {
4
+ var t;
5
+ const n = s(r.value);
6
+ try {
7
+ if (n < 1) {
8
+ const e = r.value.labelColumnIds;
9
+ e && (r.value.labelColumnIds = e.map((i) => u(i)));
10
+ }
11
+ n < 2 && ((t = r.value.colorScheme) == null ? void 0 : t.type) === "markup" && delete r.value.colorScheme;
12
+ } catch (e) {
13
+ console.error(e), r.value = {};
14
+ } finally {
15
+ r.value.version = o;
16
+ }
17
+ }
18
+ function s(r) {
19
+ return r.version !== void 0 ? r.version : Object.keys(r).length ? 0 : o;
20
+ }
21
+ export {
22
+ l as runMigrations
23
+ };
24
+ //# sourceMappingURL=migrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.js","sources":["../src/migrations.ts"],"sourcesContent":["import {\n type CanonicalizedJson,\n parseJson,\n type PlMultiSequenceAlignmentModel,\n type PTableColumnId,\n} from '@platforma-sdk/model';\nimport { type Ref } from 'vue';\n\nconst latestVersion = 2;\n\nexport function runMigrations(model: Ref<PlMultiSequenceAlignmentModel>) {\n const currentVersion = getCurrentVersion(model.value);\n try {\n if (currentVersion < 1) {\n const oldLabelColumnIds = model.value.labelColumnIds as unknown as\n | CanonicalizedJson<PTableColumnId>[]\n | undefined;\n if (oldLabelColumnIds) {\n model.value.labelColumnIds = oldLabelColumnIds\n .map((id) => parseJson(id));\n }\n }\n if (currentVersion < 2) {\n if (model.value.colorScheme?.type === 'markup') {\n delete model.value.colorScheme;\n }\n }\n } catch (error) {\n console.error(error);\n model.value = {};\n } finally {\n model.value.version = latestVersion;\n }\n}\n\n/**\n * If a model has a version, return it.\n * If it doesn't, but contains anything at all, that's version 0,\n * which is a pre-versioning version.\n * Otherwise, emtpy model is treated as the latest model.\n */\nfunction getCurrentVersion(model: PlMultiSequenceAlignmentModel) {\n if (model.version !== undefined) return model.version;\n if (Object.keys(model).length) return 0;\n return latestVersion;\n}\n"],"names":["latestVersion","runMigrations","model","currentVersion","getCurrentVersion","oldLabelColumnIds","id","parseJson","_a","error"],"mappings":";AAQA,MAAMA,IAAgB;AAEf,SAASC,EAAcC,GAA2C;;AACvE,QAAMC,IAAiBC,EAAkBF,EAAM,KAAK;AACpD,MAAI;AACF,QAAIC,IAAiB,GAAG;AACtB,YAAME,IAAoBH,EAAM,MAAM;AAGtC,MAAIG,MACFH,EAAM,MAAM,iBAAiBG,EAC1B,IAAI,CAACC,MAAOC,EAAUD,CAAE,CAAC;AAAA,IAEhC;AACA,IAAIH,IAAiB,OACfK,IAAAN,EAAM,MAAM,gBAAZ,gBAAAM,EAAyB,UAAS,YACpC,OAAON,EAAM,MAAM;AAAA,EAGzB,SAASO,GAAO;AACd,YAAQ,MAAMA,CAAK,GACnBP,EAAM,QAAQ,CAAA;AAAA,EAChB,UAAA;AACE,IAAAA,EAAM,MAAM,UAAUF;AAAA,EACxB;AACF;AAQA,SAASI,EAAkBF,GAAsC;AAC/D,SAAIA,EAAM,YAAY,SAAkBA,EAAM,UAC1C,OAAO,KAAKA,CAAK,EAAE,SAAe,IAC/BF;AACT;"}
@@ -0,0 +1,6 @@
1
+ import { PlMultiSequenceAlignmentSettings } from '@platforma-sdk/model';
2
+ export type RequestMessage = {
3
+ sequences: string[];
4
+ params: PlMultiSequenceAlignmentSettings['alignmentParams'];
5
+ };
6
+ export type ResponseMessage = string[];
@@ -0,0 +1,33 @@
1
+ const n = Array.isArray;
2
+ function i(e) {
3
+ return e !== null && typeof e == "object";
4
+ }
5
+ function c(e) {
6
+ return typeof e == "object" && e !== null;
7
+ }
8
+ function o(e) {
9
+ if (!c(e))
10
+ return !1;
11
+ const t = Object.getPrototypeOf(e);
12
+ return t === null || t === Object.prototype || Object.getPrototypeOf(t) === null;
13
+ }
14
+ function u(e) {
15
+ return Object.values(e).reduce((t, r) => r !== void 0 ? t + 1 : t, 0);
16
+ }
17
+ function f(e, t) {
18
+ if (!(i(e) && i(t)))
19
+ return e === t;
20
+ if (n(e) && n(t))
21
+ return e.length !== t.length ? !1 : [...e.keys()].every((r) => f(e[r], t[r]));
22
+ if (o(e) && o(t))
23
+ return u(e) !== u(t) ? !1 : Object.keys(e).every((r) => f(e[r], t[r]));
24
+ throw Error(`Cannot compare a ${String(e)} and b ${String(t)}`);
25
+ }
26
+ export {
27
+ n as isArray,
28
+ f as isJsonEqual,
29
+ i as isNonPrimitive,
30
+ c as isObject,
31
+ o as isPlainObject
32
+ };
33
+ //# sourceMappingURL=objects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"objects.js","sources":["../../../../../../../../../../node_modules/.pnpm/@milaboratories+helpers@1.12.0/node_modules/@milaboratories/helpers/src/objects.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { PartialBy, PlainObject } from './types';\nimport { isNil } from './utils';\n\n/**\n * Alias to Array.isArray\n */\nexport const isArray = Array.isArray;\n\n// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\nexport function isNonPrimitive<V, T extends PlainObject<V> | V[]>(obj: T | unknown): obj is T {\n return obj !== null && typeof obj === 'object';\n}\n\nexport function isObject(value: unknown): value is object {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Checks if the given value is a plain object.\n *\n * A plain object is defined as an object created by the `{}` literal,\n * an object created with `Object.create(null)`, or an object with a\n * prototype that resolves to `Object.prototype`.\n *\n * @param value - The value to check.\n * @returns `true` if the value is a plain object, otherwise `false`.\n *\n * @example\n * ```typescript\n * isPlainObject({}); // true\n * isPlainObject(Object.create(null)); // true\n * isPlainObject(new Date()); // false\n * isPlainObject(null); // false\n * isPlainObject([]); // false\n * ```\n */\nexport function isPlainObject(value: unknown): value is PlainObject {\n if (!isObject(value)) {\n return false;\n }\n\n const prototype: unknown = Object.getPrototypeOf(value);\n\n return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null);\n}\n\nexport function map<U, T extends Record<string, unknown>>(obj: T, callback: (curr: T[keyof T], key: keyof T) => U) {\n const keys = Object.keys(obj) as Array<keyof T>;\n\n return keys.map((key: keyof T) => {\n return callback(obj[key], key);\n });\n}\n\nfunction definedKeysSize(obj: PlainObject) {\n return Object.values(obj).reduce((length: number, v) => {\n return v !== undefined ? length + 1 : length;\n }, 0);\n}\n\n/**\n * Performs a deep equality check between two values, `a` and `b`, to determine if they are JSON-equivalent.\n *\n * JSON equivalence means that the two values are strictly equal in structure and content, including arrays and plain objects.\n * Non-primitive values that are neither arrays nor plain objects will throw an error.\n *\n * @param a - The first value to compare.\n * @param b - The second value to compare.\n * @returns `true` if the values are JSON-equivalent, otherwise `false`.\n *\n * @throws If the values are non-primitive and not arrays or plain objects.\n *\n * @example\n * ```typescript\n * isJsonEqual(1, 1); // true\n * isJsonEqual({ a: 1 }, { a: 1 }); // true\n * isJsonEqual([1, 2], [1, 2]); // true\n * isJsonEqual({ a: 1 }, { a: 2 }); // false\n * isJsonEqual([1, 2], [2, 1]); // false\n * isJsonEqual(new Date(), new Date()); // Error\n * ```\n */\nexport function isJsonEqual(a: unknown, b: unknown): boolean {\n if (!(isNonPrimitive(a) && isNonPrimitive(b))) {\n return a === b;\n }\n\n if (isArray(a) && isArray(b)) {\n if (a.length !== b.length) {\n return false;\n } else {\n return [...a.keys()].every((k) => isJsonEqual(a[k], b[k]));\n }\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n if (definedKeysSize(a) !== definedKeysSize(b)) {\n return false;\n }\n\n return Object.keys(a).every((k) => isJsonEqual(a[k], b[k]));\n }\n\n /* eslint-disable @typescript-eslint/no-base-to-string */\n throw Error(`Cannot compare a ${String(a)} and b ${String(b)}`);\n}\n\n/**\n * Alias to isJsonEqual function\n * @deprecated change to isJsonEqual\n */\nexport const deepEqual = isJsonEqual;\n\nexport function deepClone<T>(obj: T): T {\n if (Array.isArray(obj)) {\n const copy: any[] = [];\n for (let i = 0; i < obj.length; i++) {\n copy[i] = deepClone(obj[i]) as unknown;\n }\n return copy as T;\n } else if (isPlainObject(obj)) {\n const copy: Record<string, any> = {};\n Object.keys(obj).forEach((k) => {\n copy[k] = deepClone(obj[k]);\n });\n return copy as T;\n } else {\n return obj;\n }\n}\n\nexport function shallowClone<T>(obj: T): T {\n if (isNil(obj)) return obj;\n if (Array.isArray(obj)) return obj.slice() as T;\n if (isPlainObject(obj)) return Object.assign({}, obj) as T;\n if (obj instanceof Map) return new Map(obj) as T;\n if (obj instanceof Set) return new Set(obj) as T;\n throw Error(`Not implemented clone strategy for ${JSON.stringify(obj)}`);\n}\n\nexport function shallowDiff<T>(to: T, from: T): Partial<T> {\n const diff: Partial<T> = {};\n\n for (const key in from) {\n if (from[key] !== to[key]) {\n diff[key] = to[key];\n }\n }\n\n return diff;\n}\n\nexport function bindMethods<O extends Record<string, unknown>>(obj: O) {\n Object.entries(obj).forEach(([key, m]) => {\n if (m instanceof Function) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n obj[key as keyof O] = m.bind(obj);\n }\n });\n\n return obj;\n}\n\nexport function setProp<O, K extends keyof O>(obj: O, key: K, value: O[K]) {\n obj[key] = value;\n return obj;\n}\n\nexport function getProp<O, K extends keyof O>(obj: O, key: K): O[K] {\n return obj[key];\n}\n\nexport function shiftProp<O, K extends keyof O>(obj: O, key: K): [O[K], Omit<O, K>] {\n obj = { ...obj };\n const val = obj[key];\n delete obj[key];\n return [val, obj];\n}\n\nexport function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {\n return Object.assign({}, ...keys.map((k) => ({ [k]: obj[k] }))) as Pick<T, K>;\n}\n\nexport function pickValues<T, K extends keyof T>(obj: T, ...keys: K[]) {\n return keys.map((k) => obj[k]);\n}\n\nexport function omit<T, K extends keyof T>(obj: T, ...keys: K[]): Omit<T, K> {\n const o = Object.assign({}, obj) as PartialBy<T, K>;\n keys.forEach((k) => delete o[k]);\n return o;\n}\n\n/**\n * Performs a deep patch of the target object or array using the source object or array.\n *\n * This function recursively merges properties of the source into the target:\n * - If a property in both target and source is a plain object, they are recursively merged.\n * - If a property in both target and source is an array of the same length, the arrays are recursively patched element by element.\n * - Otherwise, the property value in the target is replaced by the corresponding value from the source.\n *\n * The patch is applied in-place to the target object or array, which is also returned for convenience.\n *\n * @typeParam T - The type of the target and source, which must be either a plain object or an array.\n * @param target - The target object or array to be patched. This object/array is modified in-place.\n * @param source - The source object or array providing the new values for the patch.\n * @returns The modified target object or array.\n *\n * @example\n * ```typescript\n * const target = { a: { b: 1 }, c: [1, 2] };\n * const source = { a: { b: 2 }, c: [3, 4], d: 5 };\n * const result = deepPatch(target, source);\n * // target is now: { a: { b: 2 }, c: [3, 4], d: 5 }\n * // result is the same reference as target.\n *\n * const targetArray = [{ a: 1 }, { b: 2 }];\n * const sourceArray = [{ a: 2 }, { b: 3 }];\n * const resultArray = deepPatch(targetArray, sourceArray);\n * // targetArray is now: [{ a: 2 }, { b: 3 }]\n * ```\n */\nexport function deepPatch<T extends PlainObject | unknown[]>(target: T, source: T) {\n const sk = new Set<keyof T>([...Object.keys(target) as (keyof T)[], ...Object.keys(source) as (keyof T)[]]);\n\n sk.forEach((key) => {\n const t = target[key];\n const s = source[key];\n if (isPlainObject(t) && isPlainObject(s)) {\n deepPatch(t, s);\n } else if (isArray(t) && isArray(s) && t.length === s.length) {\n deepPatch(t, s);\n } else {\n target[key] = s;\n }\n });\n\n return target;\n}\n"],"names":["isArray","isNonPrimitive","obj","isObject","value","isPlainObject","prototype","definedKeysSize","length","v","isJsonEqual","a","b","k"],"mappings":"AAQO,MAAMA,IAAU,MAAM;AAGvB,SAAUC,EAAkDC,GAAgB;AAChF,SAAOA,MAAQ,QAAQ,OAAOA,KAAQ;AACxC;AAEM,SAAUC,EAASC,GAAc;AACrC,SAAO,OAAOA,KAAU,YAAYA,MAAU;AAChD;AAqBM,SAAUC,EAAcD,GAAc;AAC1C,MAAI,CAACD,EAASC,CAAK;AACjB,WAAO;AAGT,QAAME,IAAqB,OAAO,eAAeF,CAAK;AAEtD,SAAQE,MAAc,QAAQA,MAAc,OAAO,aAAa,OAAO,eAAeA,CAAS,MAAM;AACvG;AAUA,SAASC,EAAgBL,GAAgB;AACvC,SAAO,OAAO,OAAOA,CAAG,EAAE,OAAO,CAACM,GAAgBC,MACzCA,MAAM,SAAYD,IAAS,IAAIA,GACrC,CAAC;AACN;AAwBM,SAAUE,EAAYC,GAAYC,GAAU;AAChD,MAAI,EAAEX,EAAeU,CAAC,KAAKV,EAAeW,CAAC;AACzC,WAAOD,MAAMC;AAGf,MAAIZ,EAAQW,CAAC,KAAKX,EAAQY,CAAC;AACzB,WAAID,EAAE,WAAWC,EAAE,SACV,KAEA,CAAC,GAAGD,EAAE,KAAI,CAAE,EAAE,MAAM,CAACE,MAAMH,EAAYC,EAAEE,CAAC,GAAGD,EAAEC,CAAC,CAAC,CAAC;AAI7D,MAAIR,EAAcM,CAAC,KAAKN,EAAcO,CAAC;AACrC,WAAIL,EAAgBI,CAAC,MAAMJ,EAAgBK,CAAC,IACnC,KAGF,OAAO,KAAKD,CAAC,EAAE,MAAM,CAACE,MAAMH,EAAYC,EAAEE,CAAC,GAAGD,EAAEC,CAAC,CAAC,CAAC;AAI5D,QAAM,MAAM,oBAAoB,OAAOF,CAAC,CAAC,UAAU,OAAOC,CAAC,CAAC,EAAE;AAChE;","x_google_ignoreList":[0]}
@@ -0,0 +1,7 @@
1
+ export type RequestMessage = string[];
2
+ export type ResponseMessage = TreeNodeData[];
3
+ export interface TreeNodeData {
4
+ id: number;
5
+ length?: number;
6
+ parentId?: number;
7
+ }
@@ -0,0 +1,2 @@
1
+ import { ResidueCounts } from './types';
2
+ export declare function getResidueCounts(alignedSequences: string[]): ResidueCounts;
@@ -0,0 +1,13 @@
1
+ function c(n) {
2
+ const e = [];
3
+ for (const r of n)
4
+ for (const [t, o] of r.split("").entries()) {
5
+ const s = e[t] ?? (e[t] = {});
6
+ s[o] = (s[o] ?? 0) + 1;
7
+ }
8
+ return e;
9
+ }
10
+ export {
11
+ c as getResidueCounts
12
+ };
13
+ //# sourceMappingURL=residue-counts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"residue-counts.js","sources":["../src/residue-counts.ts"],"sourcesContent":["import type { ResidueCounts } from './types';\n\nexport function getResidueCounts(\n alignedSequences: string[],\n): ResidueCounts {\n const columns: ResidueCounts = [];\n for (const sequence of alignedSequences) {\n for (const [columnIndex, residue] of sequence.split('').entries()) {\n const column = columns[columnIndex] ??= {};\n column[residue] = (column[residue] ?? 0) + 1;\n }\n }\n return columns;\n}\n\nif (import.meta.vitest) {\n const { test, expect } = import.meta.vitest;\n\n test('getAlignmentStats', () => {\n const alignedSequences = [\n 'GKGDPKKPRG-KMSSYAFFVQTSREEHKKKHPDASVNFSEFSKKCSERWKTMSAKEKGKFEDMAKADKARYEREMKTY-IPPKGE---------',\n '-----MQDRV-KRPMNAFIVWSRDQRRKMALENPRMRNSEISKQLGYQWKMLTEAEKWPFFQEAQKLQAMHREKYPNYKYRPRRKAKMLPK---',\n 'MKKLKKHPDFPKKPLTPYFRFFMEKRAKYAKLHPEMSNLDLTKILSKKYKELPEKKKMKYIQDFQREKQ-EFERNLARFREDHPDLIQNAKK--',\n '-----MHI---KKPLNAFMLYMKEMRANVVAESTLKESAAINQILGRRWHALSREEQAKYYELARKERQLHMQLYPGWSARDNYGKKKKRKREK',\n ];\n\n expect(getResidueCounts(alignedSequences)).toEqual([\n { '-': 2, 'G': 1, 'M': 1 },\n { '-': 2, 'K': 2 },\n { '-': 2, 'G': 1, 'K': 1 },\n { '-': 2, 'D': 1, 'L': 1 },\n { '-': 2, 'K': 1, 'P': 1 },\n { K: 2, M: 2 },\n { H: 2, K: 1, Q: 1 },\n { D: 1, I: 1, P: 2 },\n { '-': 1, 'D': 1, 'R': 2 },\n { '-': 1, 'F': 1, 'G': 1, 'V': 1 },\n { '-': 3, 'P': 1 },\n { K: 4 },\n { K: 2, M: 1, R: 1 },\n { P: 3, S: 1 },\n { L: 2, M: 1, S: 1 },\n { N: 2, T: 1, Y: 1 },\n { A: 3, P: 1 },\n { F: 3, Y: 1 },\n { F: 2, I: 1, M: 1 },\n { L: 1, R: 1, V: 2 },\n { F: 1, Q: 1, W: 1, Y: 1 },\n { F: 1, M: 1, S: 1, T: 1 },\n { K: 1, M: 1, R: 1, S: 1 },\n { D: 1, E: 2, R: 1 },\n { E: 1, K: 1, M: 1, Q: 1 },\n { E: 1, R: 3 },\n { A: 2, H: 1, R: 1 },\n { K: 3, N: 1 },\n { K: 1, M: 1, V: 1, Y: 1 },\n { A: 2, K: 1, V: 1 },\n { A: 1, H: 1, K: 1, L: 1 },\n { E: 2, L: 1, P: 1 },\n { D: 1, H: 1, N: 1, S: 1 },\n { A: 1, P: 2, T: 1 },\n { E: 1, L: 1, R: 1, S: 1 },\n { K: 1, M: 2, V: 1 },\n { E: 1, N: 1, R: 1, S: 1 },\n { F: 1, N: 2, S: 1 },\n { A: 1, L: 1, S: 2 },\n { A: 1, D: 1, E: 2 },\n { F: 1, I: 2, L: 1 },\n { N: 1, S: 2, T: 1 },\n { K: 3, Q: 1 },\n { I: 2, K: 1, Q: 1 },\n { C: 1, L: 3 },\n { G: 2, S: 2 },\n { E: 1, K: 1, R: 1, Y: 1 },\n { K: 1, Q: 1, R: 2 },\n { W: 3, Y: 1 },\n { H: 1, K: 3 },\n { A: 1, E: 1, M: 1, T: 1 },\n { L: 3, M: 1 },\n { P: 1, S: 2, T: 1 },\n { A: 1, E: 2, R: 1 },\n { A: 1, E: 1, K: 2 },\n { E: 3, K: 1 },\n { K: 3, Q: 1 },\n { A: 1, G: 1, M: 1, W: 1 },\n { K: 3, P: 1 },\n { F: 2, Y: 2 },\n { E: 1, F: 1, I: 1, Y: 1 },\n { D: 1, E: 1, Q: 2 },\n { D: 1, E: 1, L: 1, M: 1 },\n { A: 3, F: 1 },\n { K: 1, Q: 2, R: 1 },\n { A: 1, K: 2, R: 1 },\n { D: 1, E: 2, L: 1 },\n { K: 2, Q: 1, R: 1 },\n { A: 2, Q: 2 },\n { '-': 1, 'L': 1, 'M': 1, 'R': 1 },\n { E: 1, H: 2, Y: 1 },\n { E: 1, F: 1, M: 1, R: 1 },\n { E: 2, Q: 1, R: 1 },\n { E: 1, K: 1, L: 1, R: 1 },\n { M: 1, N: 1, Y: 2 },\n { K: 1, L: 1, P: 2 },\n { A: 1, G: 1, N: 1, T: 1 },\n { R: 1, W: 1, Y: 2 },\n { '-': 1, 'F': 1, 'K': 1, 'S': 1 },\n { A: 1, I: 1, R: 1, Y: 1 },\n { E: 1, P: 1, R: 2 },\n { D: 2, P: 2 },\n { H: 1, K: 1, N: 1, R: 1 },\n { G: 1, P: 1, R: 1, Y: 1 },\n { D: 1, E: 1, G: 1, K: 1 },\n { '-': 1, 'A': 1, 'K': 1, 'L': 1 },\n { '-': 1, 'I': 1, 'K': 2 },\n { '-': 1, 'K': 1, 'M': 1, 'Q': 1 },\n { '-': 1, 'K': 1, 'L': 1, 'N': 1 },\n { '-': 1, 'A': 1, 'P': 1, 'R': 1 },\n { '-': 1, 'K': 3 },\n { '-': 2, 'K': 1, 'R': 1 },\n { '-': 3, 'E': 1 },\n { '-': 3, 'K': 1 },\n ]);\n });\n}\n"],"names":["getResidueCounts","alignedSequences","columns","sequence","columnIndex","residue","column"],"mappings":"AAEO,SAASA,EACdC,GACe;AACf,QAAMC,IAAyB,CAAA;AAC/B,aAAWC,KAAYF;AACrB,eAAW,CAACG,GAAaC,CAAO,KAAKF,EAAS,MAAM,EAAE,EAAE,WAAW;AACjE,YAAMG,IAASJ,EAAAE,OAAAF,EAAAE,KAAyB,CAAA;AACxC,MAAAE,EAAOD,CAAO,KAAKC,EAAOD,CAAO,KAAK,KAAK;AAAA,IAC7C;AAEF,SAAOH;AACT;"}
@@ -0,0 +1,2 @@
1
+ import { PlMultiSequenceAlignmentSettings } from '@platforma-sdk/model';
2
+ export declare const defaultSettings: PlMultiSequenceAlignmentSettings;
@@ -0,0 +1,9 @@
1
+ const e = {
2
+ colorScheme: { type: "chemical-properties" },
3
+ widgets: ["seqLogo", "consensus", "legend"],
4
+ alignmentParams: { gpo: 5.5, gpe: 2, tgpe: 1 }
5
+ };
6
+ export {
7
+ e as defaultSettings
8
+ };
9
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sources":["../src/settings.ts"],"sourcesContent":["import type { PlMultiSequenceAlignmentSettings } from '@platforma-sdk/model';\n\nexport const defaultSettings: PlMultiSequenceAlignmentSettings = {\n colorScheme: { type: 'chemical-properties' },\n widgets: ['seqLogo', 'consensus', 'legend'],\n alignmentParams: { gpo: 5.5, gpe: 2.0, tgpe: 1.0 },\n};\n"],"names":["defaultSettings"],"mappings":"AAEO,MAAMA,IAAoD;AAAA,EAC/D,aAAa,EAAE,MAAM,sBAAA;AAAA,EACrB,SAAS,CAAC,WAAW,aAAa,QAAQ;AAAA,EAC1C,iBAAiB,EAAE,KAAK,KAAK,KAAK,GAAK,MAAM,EAAA;AAC/C;"}
@@ -0,0 +1,5 @@
1
+ export type HighlightLegend = Record<string, {
2
+ label: string;
3
+ color: string;
4
+ }>;
5
+ export type ResidueCounts = Record<string, number>[];
@@ -0,0 +1,4 @@
1
+ export declare function useMiPlots(): {
2
+ miplots: import('vue').ShallowRef<typeof import('@milaboratories/miplots4').MiPlots | undefined, typeof import('@milaboratories/miplots4').MiPlots | undefined>;
3
+ error: import('vue').ShallowRef<Error | undefined, Error | undefined>;
4
+ };
@@ -0,0 +1,19 @@
1
+ import { ensureError as s } from "@platforma-sdk/model";
2
+ import { shallowRef as n, onMounted as a } from "vue";
3
+ function l() {
4
+ const e = async () => {
5
+ const { MiPlots: o } = await import("@milaboratories/miplots4");
6
+ return o;
7
+ }, r = n(), t = n();
8
+ return a(async () => {
9
+ try {
10
+ r.value = await e();
11
+ } catch (o) {
12
+ t.value = s(o);
13
+ }
14
+ }), { miplots: r, error: t };
15
+ }
16
+ export {
17
+ l as useMiPlots
18
+ };
19
+ //# sourceMappingURL=useMiPlots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMiPlots.js","sources":["../src/useMiPlots.ts"],"sourcesContent":["import { ensureError } from '@platforma-sdk/model';\nimport { onMounted, shallowRef } from 'vue';\n\nexport function useMiPlots() {\n const load = async () => {\n const { MiPlots } = await import('@milaboratories/miplots4');\n return MiPlots;\n };\n\n const miplots = shallowRef<Awaited<ReturnType<typeof load>>>();\n\n const error = shallowRef<Error>();\n\n onMounted(async () => {\n try {\n miplots.value = await load();\n } catch (err) {\n error.value = ensureError(err);\n }\n });\n\n return { miplots, error };\n}\n"],"names":["useMiPlots","load","MiPlots","miplots","shallowRef","error","onMounted","err","ensureError"],"mappings":";;AAGO,SAASA,IAAa;AAC3B,QAAMC,IAAO,YAAY;AACvB,UAAM,EAAE,SAAAC,EAAA,IAAY,MAAM,OAAO,0BAA0B;AAC3D,WAAOA;AAAA,EACT,GAEMC,IAAUC,EAAA,GAEVC,IAAQD,EAAA;AAEd,SAAAE,EAAU,YAAY;AACpB,QAAI;AACF,MAAAH,EAAQ,QAAQ,MAAMF,EAAA;AAAA,IACxB,SAASM,GAAK;AACZ,MAAAF,EAAM,QAAQG,EAAYD,CAAG;AAAA,IAC/B;AAAA,EACF,CAAC,GAEM,EAAE,SAAAJ,GAAS,OAAAE,EAAA;AACpB;"}
@@ -0,0 +1,66 @@
1
+ import eslint from '@eslint/js';
2
+ import tseslint from '@typescript-eslint/eslint-plugin';
3
+ import tsparser from '@typescript-eslint/parser';
4
+ import prettierConfig from 'eslint-config-prettier';
5
+
6
+ export default [
7
+ {
8
+ ignores: ['node_modules/**', '**/dist/**', 'eslint.config.js', '**/*.vue']
9
+ },
10
+ {
11
+ files: ['**/*.ts', '**/*.tsx'],
12
+ languageOptions: {
13
+ parser: tsparser,
14
+ parserOptions: {
15
+ project: ['./tsconfig.json'],
16
+ ecmaVersion: 'latest',
17
+ sourceType: 'module'
18
+ },
19
+ globals: {
20
+ console: 'readonly',
21
+ process: 'readonly',
22
+ Buffer: 'readonly',
23
+ __dirname: 'readonly',
24
+ __filename: 'readonly',
25
+ module: 'readonly',
26
+ require: 'readonly',
27
+ exports: 'writable',
28
+ document: 'readonly',
29
+ window: 'readonly',
30
+ navigator: 'readonly',
31
+ HTMLElement: 'readonly',
32
+ Element: 'readonly',
33
+ Node: 'readonly',
34
+ setTimeout: 'readonly',
35
+ clearTimeout: 'readonly',
36
+ setInterval: 'readonly',
37
+ clearInterval: 'readonly',
38
+ addEventListener: 'readonly',
39
+ postMessage: 'readonly',
40
+ reportError: 'readonly'
41
+ }
42
+ },
43
+ plugins: {
44
+ '@typescript-eslint': tseslint
45
+ },
46
+ rules: {
47
+ ...eslint.configs.recommended.rules,
48
+ ...tseslint.configs.recommended.rules,
49
+ ...prettierConfig.rules,
50
+ '@typescript-eslint/no-var-requires': 'off',
51
+ '@typescript-eslint/consistent-type-imports': 'error',
52
+ '@typescript-eslint/no-explicit-any': 'error',
53
+ semi: ['warn', 'always'],
54
+ quotes: ['warn', 'single'],
55
+ '@typescript-eslint/no-unused-vars': [
56
+ 'warn',
57
+ {
58
+ argsIgnorePattern: '^_',
59
+ varsIgnorePattern: '^_',
60
+ caughtErrorsIgnorePattern: '^_'
61
+ }
62
+ ]
63
+ }
64
+ }
65
+ ];
66
+
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@milaboratories/multi-sequence-alignment",
3
+ "version": "1.45.0",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "styles": "dist/index.js",
7
+ "exports": {
8
+ ".": {
9
+ "sources": "./src/index.ts",
10
+ "default": "./dist/index.js"
11
+ },
12
+ "./styles": "./dist/index.js"
13
+ },
14
+ "dependencies": {
15
+ "@milaboratories/biowasm-tools": "^2.0.0",
16
+ "@milaboratories/uikit": "^2.5.2",
17
+ "@platforma-sdk/ui-vue": "^1.45.21",
18
+ "@platforma-sdk/model": "^1.45.17",
19
+ "vue": "^3.5.13",
20
+ "@milaboratories/miplots4": "1.0.157"
21
+ },
22
+ "devDependencies": {
23
+ "@milaboratories/ts-configs": "^1.0.4",
24
+ "@milaboratories/build-configs": "^1.0.4",
25
+ "@milaboratories/helpers": "^1.6.15",
26
+ "@milaboratories/ts-builder": "^1.0.4",
27
+ "@types/node": "24.10.0 ",
28
+ "@vitejs/plugin-vue": "^6.0.1",
29
+ "sass": "^1.69.5",
30
+ "typescript": "^5.8.3",
31
+ "vite": "^6.3.5",
32
+ "vitest": "^4.0.7"
33
+ },
34
+ "scripts": {
35
+ "test": "vitest run --passWithNoTests",
36
+ "dev": "ts-builder serve --target browser-lib",
37
+ "build": "ts-builder build --target browser-lib",
38
+ "watch": "ts-builder build --target browser-lib --watch",
39
+ "type-check": "ts-builder types --target browser-lib",
40
+ "preview": "vite preview",
41
+ "lint": "eslint .",
42
+ "check": "yarpm type-check && yarpm lint && yarpm test",
43
+ "do-pack": "rm -f *.tgz && pnpm pack && mv *.tgz package.tgz"
44
+ }
45
+ }