@platforma-sdk/ui-vue 1.41.19 → 1.42.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.
- package/.turbo/turbo-build.log +18 -18
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +18 -0
- package/dist/components/PlAgDataTable/sources/table-source-v2.js +11 -11
- package/dist/components/PlMultiSequenceAlignment/Legend.vue.d.ts +2 -2
- package/dist/components/PlMultiSequenceAlignment/Legend.vue.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/Legend.vue2.js +11 -11
- package/dist/components/PlMultiSequenceAlignment/Legend.vue3.js +8 -8
- package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue.d.ts +12 -6
- package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue2.js +80 -65
- package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue2.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue3.js +14 -12
- package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue3.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue.d.ts +36 -1
- package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue2.js +146 -111
- package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue2.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/Toolbar.vue.d.ts +2 -0
- package/dist/components/PlMultiSequenceAlignment/Toolbar.vue.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/Toolbar.vue2.js +71 -68
- package/dist/components/PlMultiSequenceAlignment/Toolbar.vue2.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/chemical-properties.d.ts +42 -6
- package/dist/components/PlMultiSequenceAlignment/chemical-properties.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/chemical-properties.js +96 -130
- package/dist/components/PlMultiSequenceAlignment/chemical-properties.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/data.d.ts +3 -9
- package/dist/components/PlMultiSequenceAlignment/data.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/data.js +197 -211
- package/dist/components/PlMultiSequenceAlignment/data.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/markup.d.ts +7 -5
- package/dist/components/PlMultiSequenceAlignment/markup.d.ts.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/markup.js +47 -26
- package/dist/components/PlMultiSequenceAlignment/markup.js.map +1 -1
- package/dist/components/PlMultiSequenceAlignment/types.d.ts +1 -1
- package/dist/components/PlMultiSequenceAlignment/types.d.ts.map +1 -1
- package/dist/components/PlTableFilters/PlTableFiltersV2.vue2.js +18 -18
- package/dist/defineApp.js +6 -6
- package/dist/internal/createAppV2.js +12 -12
- package/dist/lib/model/common/dist/index.js +24 -24
- package/dist/lib/ui/uikit/dist/components/PlFileInput/PlFileInput.vue.js +7 -7
- package/dist/lib/ui/uikit/dist/lib/model/common/dist/index.js +8 -8
- package/dist/lib/ui/uikit/dist/lib/model/common/dist/index.js.map +1 -1
- package/dist/lib/ui/uikit/dist/sdk/model/dist/index.js +1 -1
- package/dist/node_modules/.pnpm/@vueuse_core@13.3.0_vue@3.5.13_typescript@5.6.3_/node_modules/@vueuse/core/index.js +111 -165
- package/dist/node_modules/.pnpm/@vueuse_core@13.3.0_vue@3.5.13_typescript@5.6.3_/node_modules/@vueuse/core/index.js.map +1 -1
- package/dist/node_modules/.pnpm/@vueuse_shared@13.3.0_vue@3.5.13_typescript@5.6.3_/node_modules/@vueuse/shared/index.js +1 -1
- package/dist/sdk/model/dist/index.js +1 -1
- package/package.json +4 -4
- package/src/components/PlMultiSequenceAlignment/Legend.vue +4 -3
- package/src/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue +66 -46
- package/src/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue +85 -34
- package/src/components/PlMultiSequenceAlignment/README.md +10 -8
- package/src/components/PlMultiSequenceAlignment/Toolbar.vue +4 -1
- package/src/components/PlMultiSequenceAlignment/chemical-properties.ts +154 -161
- package/src/components/PlMultiSequenceAlignment/data.ts +65 -85
- package/src/components/PlMultiSequenceAlignment/markup.ts +47 -15
- package/src/components/PlMultiSequenceAlignment/types.ts +1 -1
|
@@ -1,293 +1,279 @@
|
|
|
1
|
-
import { isJsonEqual as
|
|
2
|
-
import { getRawPlatformaInstance as
|
|
3
|
-
import { ref as
|
|
4
|
-
import {
|
|
5
|
-
import { parseMarkup as
|
|
6
|
-
import { multiSequenceAlignment as
|
|
7
|
-
import { getResidueCounts as
|
|
8
|
-
import { ensureError as
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
),
|
|
12
|
-
|
|
13
|
-
),
|
|
14
|
-
|
|
15
|
-
),
|
|
16
|
-
|
|
1
|
+
import { isJsonEqual as J } from "../../lib/util/helpers/dist/index.js";
|
|
2
|
+
import { getRawPlatformaInstance as z, isLabelColumn as N, isLinkerColumn as W, createRowSelectionColumn as X } from "../../sdk/model/dist/index.js";
|
|
3
|
+
import { ref as M, watch as G } from "vue";
|
|
4
|
+
import { highlightByChemicalProperties as H } from "./chemical-properties.js";
|
|
5
|
+
import { parseMarkup as K, markupAlignedSequence as Q, highlightByMarkup as Y } from "./markup.js";
|
|
6
|
+
import { multiSequenceAlignment as Z } from "./multi-sequence-alignment.js";
|
|
7
|
+
import { getResidueCounts as nn } from "./residue-counts.js";
|
|
8
|
+
import { ensureError as tn, canonicalizeJson as A, getAxisId as E, parseJson as D, matchAxisId as en, pTableValue as q } from "../../lib/model/common/dist/index.js";
|
|
9
|
+
const S = () => z().pFrameDriver, O = 1e3, gn = k(
|
|
10
|
+
an
|
|
11
|
+
), hn = k(
|
|
12
|
+
on
|
|
13
|
+
), wn = k(
|
|
14
|
+
rn
|
|
15
|
+
), bn = k(
|
|
16
|
+
sn
|
|
17
17
|
);
|
|
18
|
-
async function
|
|
18
|
+
async function an({
|
|
19
19
|
pFrame: c,
|
|
20
|
-
sequenceColumnPredicate:
|
|
20
|
+
sequenceColumnPredicate: e
|
|
21
21
|
}) {
|
|
22
22
|
if (!c) return;
|
|
23
|
-
const
|
|
23
|
+
const t = (await S().listColumns(c)).values().filter((o) => e(o)).map(({ spec: o, columnId: u }) => {
|
|
24
24
|
var m;
|
|
25
25
|
return {
|
|
26
|
-
label: ((m =
|
|
27
|
-
value:
|
|
26
|
+
label: ((m = o.annotations) == null ? void 0 : m["pl7.app/label"]) ?? "Unlabelled column",
|
|
27
|
+
value: u
|
|
28
28
|
};
|
|
29
|
-
}),
|
|
30
|
-
return { options:
|
|
29
|
+
}).toArray(), l = t.map(({ value: o }) => o);
|
|
30
|
+
return { options: t, defaults: l };
|
|
31
31
|
}
|
|
32
|
-
async function
|
|
32
|
+
async function on({
|
|
33
33
|
pFrame: c,
|
|
34
|
-
sequenceColumnIds:
|
|
34
|
+
sequenceColumnIds: e
|
|
35
35
|
}) {
|
|
36
|
-
var f,
|
|
37
|
-
if (!c || !
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
36
|
+
var f, h, b;
|
|
37
|
+
if (!c || !e) return;
|
|
38
|
+
const y = S(), p = await y.listColumns(c), t = /* @__PURE__ */ new Map(), l = new Map(
|
|
39
|
+
e.values().flatMap((i) => {
|
|
40
|
+
const d = p.find(({ columnId: a }) => a === i);
|
|
41
|
+
if (!d)
|
|
42
|
+
throw new Error(`Couldn't find sequence column (ID: \`${i}\`).`);
|
|
43
|
+
return d.spec.axesSpec.values().map((a) => [A(E(a)), a]);
|
|
44
|
+
})
|
|
45
|
+
);
|
|
46
|
+
for (const [i, d] of l.entries()) {
|
|
47
|
+
const a = D(i), g = p.find(
|
|
48
|
+
({ spec: v }) => N(v) && en(a, E(v.axesSpec[0]))
|
|
47
49
|
);
|
|
48
|
-
|
|
49
|
-
g ? A({ type: "column", id: g.columnId }) : A({ type: "axis", id:
|
|
50
|
-
((f = g == null ? void 0 : g.spec.annotations) == null ? void 0 : f["pl7.app/label"]) ?? ((
|
|
50
|
+
t.set(
|
|
51
|
+
g ? A({ type: "column", id: g.columnId }) : A({ type: "axis", id: a }),
|
|
52
|
+
((f = g == null ? void 0 : g.spec.annotations) == null ? void 0 : f["pl7.app/label"]) ?? ((h = d.annotations) == null ? void 0 : h["pl7.app/label"]) ?? "Unlabelled axis"
|
|
51
53
|
);
|
|
52
54
|
}
|
|
53
|
-
const { hits:
|
|
55
|
+
const { hits: o } = await y.findColumns(c, {
|
|
54
56
|
columnFilter: {},
|
|
55
|
-
compatibleWith:
|
|
56
|
-
s.keys(),
|
|
57
|
-
(r) => D(r)
|
|
58
|
-
),
|
|
57
|
+
compatibleWith: l.keys().map((i) => D(i)).toArray(),
|
|
59
58
|
strictlyCompatible: !1
|
|
60
59
|
});
|
|
61
|
-
for (const { columnId:
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
((
|
|
60
|
+
for (const { columnId: i, spec: d } of o) {
|
|
61
|
+
const a = A({ type: "column", id: i });
|
|
62
|
+
t.has(a) || t.set(
|
|
63
|
+
a,
|
|
64
|
+
((b = d.annotations) == null ? void 0 : b["pl7.app/label"]) ?? "Unlabelled column"
|
|
66
65
|
);
|
|
67
66
|
}
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}).map(({ value: r }) => r);
|
|
75
|
-
return { options: p, defaults: m };
|
|
67
|
+
const u = t.entries().map(([i, d]) => ({ label: d, value: D(i) })).toArray(), m = u.values().filter(({ value: i }) => {
|
|
68
|
+
if (i.type === "axis") return !0;
|
|
69
|
+
const d = p.find(({ columnId: a }) => a === i.id);
|
|
70
|
+
return d && N(d.spec);
|
|
71
|
+
}).map(({ value: i }) => i).toArray();
|
|
72
|
+
return { options: u, defaults: m };
|
|
76
73
|
}
|
|
77
|
-
async function
|
|
74
|
+
async function rn({
|
|
78
75
|
pFrame: c,
|
|
79
|
-
sequenceColumnIds:
|
|
76
|
+
sequenceColumnIds: e
|
|
80
77
|
}) {
|
|
81
|
-
if (!c || (
|
|
82
|
-
const
|
|
83
|
-
(
|
|
78
|
+
if (!c || (e == null ? void 0 : e.length) !== 1) return;
|
|
79
|
+
const p = await S().listColumns(c), t = p.find(
|
|
80
|
+
(l) => l.columnId === e[0]
|
|
84
81
|
);
|
|
85
|
-
if (!
|
|
82
|
+
if (!t)
|
|
86
83
|
throw new Error(
|
|
87
|
-
`Couldn't find sequence column (ID: \`${
|
|
84
|
+
`Couldn't find sequence column (ID: \`${e[0]}\`).`
|
|
88
85
|
);
|
|
89
|
-
return
|
|
90
|
-
(
|
|
91
|
-
var
|
|
92
|
-
return ((
|
|
86
|
+
return p.values().filter(
|
|
87
|
+
(l) => {
|
|
88
|
+
var o;
|
|
89
|
+
return ((o = l.spec.annotations) == null ? void 0 : o["pl7.app/sequence/isAnnotation"]) === "true" && J(t.spec.axesSpec, l.spec.axesSpec) && Object.entries(t.spec.domain ?? {}).every(([u, m]) => {
|
|
93
90
|
var f;
|
|
94
|
-
return ((f =
|
|
91
|
+
return ((f = l.spec.domain) == null ? void 0 : f[u]) === m;
|
|
95
92
|
});
|
|
96
93
|
}
|
|
97
|
-
).map(({ columnId:
|
|
98
|
-
var
|
|
94
|
+
).map(({ columnId: l, spec: o }) => {
|
|
95
|
+
var u;
|
|
99
96
|
return {
|
|
100
|
-
value:
|
|
101
|
-
label: ((
|
|
97
|
+
value: l,
|
|
98
|
+
label: ((u = o.annotations) == null ? void 0 : u["pl7.app/label"]) ?? "Unlabelled column"
|
|
102
99
|
};
|
|
103
|
-
});
|
|
100
|
+
}).toArray();
|
|
104
101
|
}
|
|
105
|
-
async function
|
|
102
|
+
async function sn({
|
|
106
103
|
pframe: c,
|
|
107
|
-
sequenceColumnIds:
|
|
108
|
-
labelColumnIds:
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
alignmentParams: i
|
|
104
|
+
sequenceColumnIds: e,
|
|
105
|
+
labelColumnIds: y,
|
|
106
|
+
selection: p,
|
|
107
|
+
colorScheme: t,
|
|
108
|
+
alignmentParams: l
|
|
113
109
|
}) {
|
|
114
|
-
var
|
|
115
|
-
if (!c || !(
|
|
116
|
-
const
|
|
117
|
-
let
|
|
110
|
+
var F, I;
|
|
111
|
+
if (!c || !(e != null && e.length) || !y) return;
|
|
112
|
+
const o = S(), u = await o.listColumns(c), m = u.filter((n) => W(n.spec)), f = X({ selection: p });
|
|
113
|
+
let h = {
|
|
118
114
|
type: "inner",
|
|
119
|
-
entries:
|
|
115
|
+
entries: e.map((n) => ({
|
|
120
116
|
type: "column",
|
|
121
|
-
column:
|
|
117
|
+
column: n
|
|
122
118
|
}))
|
|
123
119
|
};
|
|
124
|
-
|
|
120
|
+
m.length > 0 && (h = {
|
|
125
121
|
type: "outer",
|
|
126
|
-
primary:
|
|
127
|
-
secondary:
|
|
122
|
+
primary: h,
|
|
123
|
+
secondary: m.map(({ columnId: n }) => ({
|
|
128
124
|
type: "column",
|
|
129
|
-
column:
|
|
125
|
+
column: n
|
|
130
126
|
}))
|
|
131
|
-
}),
|
|
127
|
+
}), f && (h = {
|
|
132
128
|
type: "inner",
|
|
133
129
|
entries: [
|
|
134
|
-
|
|
130
|
+
h,
|
|
135
131
|
{
|
|
136
132
|
type: "inlineColumn",
|
|
137
|
-
column:
|
|
133
|
+
column: f
|
|
138
134
|
}
|
|
139
135
|
]
|
|
140
136
|
});
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
const
|
|
144
|
-
new Set(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
137
|
+
const b = y.flatMap((n) => n.type !== "column" ? [] : { type: "column", column: n.id });
|
|
138
|
+
t.type === "markup" && b.push({ type: "column", column: t.columnId });
|
|
139
|
+
const i = Array.from(
|
|
140
|
+
new Set(
|
|
141
|
+
e.values().flatMap((n) => {
|
|
142
|
+
const r = u.find(({ columnId: s }) => s === n);
|
|
143
|
+
if (!r)
|
|
144
|
+
throw new Error(`Couldn't find sequence column (ID: ${n})`);
|
|
145
|
+
return r.spec.axesSpec.map((s) => A(E(s)));
|
|
146
|
+
})
|
|
147
|
+
)
|
|
148
|
+
).sort().map((n) => ({
|
|
149
|
+
column: { type: "axis", id: D(n) },
|
|
152
150
|
ascending: !0,
|
|
153
151
|
naAndAbsentAreLeastValues: !0
|
|
154
|
-
})),
|
|
152
|
+
})), d = {
|
|
155
153
|
src: {
|
|
156
154
|
type: "outer",
|
|
157
|
-
primary:
|
|
158
|
-
secondary:
|
|
155
|
+
primary: h,
|
|
156
|
+
secondary: b
|
|
159
157
|
},
|
|
160
158
|
filters: [],
|
|
161
|
-
sorting:
|
|
162
|
-
},
|
|
159
|
+
sorting: i
|
|
160
|
+
}, a = await o.calculateTableData(
|
|
163
161
|
c,
|
|
164
|
-
JSON.parse(JSON.stringify(
|
|
162
|
+
JSON.parse(JSON.stringify(d)),
|
|
165
163
|
{
|
|
166
164
|
offset: 0,
|
|
167
165
|
// +1 is a hack to check whether the selection is over the limit
|
|
168
|
-
length:
|
|
166
|
+
length: O + 1
|
|
169
167
|
}
|
|
170
168
|
);
|
|
171
|
-
let
|
|
172
|
-
|
|
173
|
-
const
|
|
174
|
-
const
|
|
175
|
-
if (!
|
|
176
|
-
throw new Error(`Couldn't find sequence column (ID: \`${
|
|
177
|
-
return
|
|
178
|
-
}),
|
|
179
|
-
const
|
|
180
|
-
if (
|
|
181
|
-
return
|
|
182
|
-
if (
|
|
183
|
-
return
|
|
169
|
+
let g = (a == null ? void 0 : a[0].data.data.length) ?? 0, v = !1;
|
|
170
|
+
g > O && (g = O, v = !0);
|
|
171
|
+
const L = e.map((n) => {
|
|
172
|
+
const r = a.find(({ spec: s }) => s.id === n);
|
|
173
|
+
if (!r)
|
|
174
|
+
throw new Error(`Couldn't find sequence column (ID: \`${n}\`).`);
|
|
175
|
+
return r;
|
|
176
|
+
}), _ = y.map((n) => {
|
|
177
|
+
const r = a.find(({ spec: s }) => {
|
|
178
|
+
if (n.type === "axis" && s.type === "axis")
|
|
179
|
+
return J(n.id, s.id);
|
|
180
|
+
if (n.type === "column" && s.type === "column")
|
|
181
|
+
return n.id === s.id;
|
|
184
182
|
});
|
|
185
|
-
if (!
|
|
186
|
-
throw new Error(`Couldn't find label column (ID: \`${
|
|
187
|
-
return
|
|
188
|
-
}),
|
|
189
|
-
|
|
190
|
-
(
|
|
183
|
+
if (!r)
|
|
184
|
+
throw new Error(`Couldn't find label column (ID: \`${n}\`).`);
|
|
185
|
+
return r;
|
|
186
|
+
}), j = await Promise.all(
|
|
187
|
+
L.map(
|
|
188
|
+
(n) => Z(
|
|
191
189
|
Array.from(
|
|
192
|
-
{ length:
|
|
193
|
-
(
|
|
194
|
-
var
|
|
195
|
-
return ((
|
|
190
|
+
{ length: g },
|
|
191
|
+
(r, s) => {
|
|
192
|
+
var w;
|
|
193
|
+
return ((w = q(n.data, s, { na: "", absent: "" })) == null ? void 0 : w.toString()) ?? "";
|
|
196
194
|
}
|
|
197
195
|
),
|
|
198
|
-
|
|
196
|
+
l
|
|
199
197
|
)
|
|
200
198
|
)
|
|
201
|
-
),
|
|
202
|
-
{ length:
|
|
203
|
-
(
|
|
204
|
-
),
|
|
205
|
-
(
|
|
206
|
-
var
|
|
207
|
-
return ((
|
|
199
|
+
), R = Array.from(
|
|
200
|
+
{ length: g },
|
|
201
|
+
(n, r) => j.map((s) => s[r])
|
|
202
|
+
), B = L.map(
|
|
203
|
+
(n) => {
|
|
204
|
+
var r;
|
|
205
|
+
return ((r = n.spec.spec.annotations) == null ? void 0 : r["pl7.app/label"]) ?? "Unlabelled column";
|
|
208
206
|
}
|
|
209
|
-
),
|
|
210
|
-
{ length:
|
|
211
|
-
(
|
|
212
|
-
(
|
|
213
|
-
var
|
|
214
|
-
return ((
|
|
207
|
+
), T = Array.from(
|
|
208
|
+
{ length: g },
|
|
209
|
+
(n, r) => _.map(
|
|
210
|
+
(s) => {
|
|
211
|
+
var w;
|
|
212
|
+
return ((w = q(s.data, r, { na: "", absent: "" })) == null ? void 0 : w.toString()) ?? "";
|
|
215
213
|
}
|
|
216
214
|
)
|
|
217
|
-
),
|
|
218
|
-
sequences:
|
|
219
|
-
sequenceNames:
|
|
220
|
-
|
|
221
|
-
exceedsLimit:
|
|
222
|
-
residueCounts:
|
|
215
|
+
), x = R.map((n) => n.join(" ")), $ = nn(x), C = {
|
|
216
|
+
sequences: x,
|
|
217
|
+
sequenceNames: B,
|
|
218
|
+
labelRows: T,
|
|
219
|
+
exceedsLimit: v,
|
|
220
|
+
residueCounts: $
|
|
223
221
|
};
|
|
224
|
-
if (
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
222
|
+
if (t.type === "chemical-properties")
|
|
223
|
+
C.highlightImage = H({
|
|
224
|
+
sequences: x,
|
|
225
|
+
residueCounts: $
|
|
226
|
+
});
|
|
227
|
+
else if (t.type === "markup") {
|
|
228
|
+
const n = a.find(
|
|
229
|
+
({ spec: w }) => w.id === t.columnId
|
|
230
|
+
);
|
|
231
|
+
if (!n)
|
|
232
|
+
throw new Error(
|
|
233
|
+
`Couldn't find markup column (ID: \`${t.columnId}\`).`
|
|
234
|
+
);
|
|
235
|
+
const r = Array.from(
|
|
236
|
+
{ length: g },
|
|
237
|
+
(w, P) => {
|
|
238
|
+
var U;
|
|
239
|
+
const V = K(
|
|
240
|
+
((U = q(n.data, P, { na: "", absent: "" })) == null ? void 0 : U.toString()) ?? ""
|
|
233
241
|
);
|
|
234
|
-
return
|
|
242
|
+
return Q(R[P][0], V);
|
|
235
243
|
}
|
|
244
|
+
), s = JSON.parse(
|
|
245
|
+
((F = n.spec.spec.annotations) == null ? void 0 : F["pl7.app/sequence/annotation/mapping"]) ?? "{}"
|
|
236
246
|
);
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
blob: await ee({
|
|
243
|
-
sequences: v,
|
|
244
|
-
residueCounts: U,
|
|
245
|
-
colorMap: e
|
|
246
|
-
}),
|
|
247
|
-
colorMap: e
|
|
248
|
-
};
|
|
249
|
-
} else if (s.type === "markup") {
|
|
250
|
-
const e = Object.fromEntries(
|
|
251
|
-
Object.entries(
|
|
252
|
-
((j = S.markup) == null ? void 0 : j.labels) ?? {}
|
|
253
|
-
).map(([n, o], h) => [
|
|
254
|
-
n,
|
|
255
|
-
{ label: o, color: T[h % T.length] }
|
|
256
|
-
])
|
|
257
|
-
);
|
|
258
|
-
S.highlightImage = {
|
|
259
|
-
blob: await oe({
|
|
260
|
-
markupRows: ((N = S.markup) == null ? void 0 : N.data) ?? [],
|
|
261
|
-
colorMap: e,
|
|
262
|
-
columnCount: ((_ = v.at(0)) == null ? void 0 : _.length) ?? 0
|
|
263
|
-
}),
|
|
264
|
-
colorMap: e
|
|
265
|
-
};
|
|
247
|
+
C.highlightImage = Y({
|
|
248
|
+
markupRows: r,
|
|
249
|
+
columnCount: ((I = x.at(0)) == null ? void 0 : I.length) ?? 0,
|
|
250
|
+
labels: s
|
|
251
|
+
});
|
|
266
252
|
}
|
|
267
|
-
return
|
|
253
|
+
return C;
|
|
268
254
|
}
|
|
269
255
|
function k(c) {
|
|
270
|
-
const
|
|
271
|
-
let
|
|
272
|
-
return (
|
|
273
|
-
if (
|
|
274
|
-
const m =
|
|
256
|
+
const e = M(), y = M(!0), p = M();
|
|
257
|
+
let t;
|
|
258
|
+
return (l) => (G(l, async (o, u) => {
|
|
259
|
+
if (J(o, u)) return;
|
|
260
|
+
const m = t = Symbol();
|
|
275
261
|
try {
|
|
276
|
-
|
|
277
|
-
const f = await c(
|
|
278
|
-
m ===
|
|
262
|
+
p.value = void 0, y.value = !0;
|
|
263
|
+
const f = await c(o);
|
|
264
|
+
m === t && (e.value = f);
|
|
279
265
|
} catch (f) {
|
|
280
|
-
console.error(f), m ===
|
|
266
|
+
console.error(f), m === t && (p.value = tn(f));
|
|
281
267
|
} finally {
|
|
282
|
-
m ===
|
|
268
|
+
m === t && (y.value = !1);
|
|
283
269
|
}
|
|
284
|
-
}, { immediate: !0 }), { data:
|
|
270
|
+
}, { immediate: !0 }), { data: e, isLoading: y, error: p });
|
|
285
271
|
}
|
|
286
272
|
export {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
273
|
+
O as sequenceLimit,
|
|
274
|
+
hn as useLabelColumnsOptions,
|
|
275
|
+
wn as useMarkupColumnsOptions,
|
|
276
|
+
bn as useMultipleAlignmentData,
|
|
277
|
+
gn as useSequenceColumnsOptions
|
|
292
278
|
};
|
|
293
279
|
//# sourceMappingURL=data.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.js","sources":["../../../src/components/PlMultiSequenceAlignment/data.ts"],"sourcesContent":["import { isJsonEqual } from '@milaboratories/helpers';\nimport type { ListOptionNormalized } from '@milaboratories/uikit';\nimport {\n type CalculateTableDataRequest,\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} from '@platforma-sdk/model';\nimport { ref, watch } from 'vue';\nimport {\n chemicalPropertiesColorMap,\n colorizeSequencesByChemicalProperties,\n} from './chemical-properties';\nimport {\n colorizeSequencesByMarkup,\n type Markup,\n markupAlignedSequence,\n markupColors,\n parseMarkup,\n} from './markup';\nimport { multiSequenceAlignment } from './multi-sequence-alignment';\nimport { getResidueCounts } from './residue-counts';\nimport type { ColorMap, ResidueCounts } from './types';\n\nconst getPFrameDriver = () => getRawPlatformaInstance().pFrameDriver;\n\nexport const sequenceLimit = 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({\n pFrame,\n sequenceColumnPredicate,\n}: {\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 const options = columns\n .filter((column) => sequenceColumnPredicate(column))\n .map(({ spec, columnId }) => ({\n label: spec.annotations?.['pl7.app/label'] ?? 'Unlabelled column',\n value: columnId,\n }));\n const defaults = options.map(({ value }) => value);\n return { options, defaults };\n}\n\nasync function getLabelColumnsOptions({\n pFrame,\n sequenceColumnIds,\n}: {\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 const optionMap = new Map<CanonicalizedJson<PTableColumnId>, string>();\n\n const sequenceColumnsAxes = new Map(sequenceColumnIds.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)), spec]);\n }));\n\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 labelColumn?.spec.annotations?.['pl7.app/label']\n ?? axisSpec.annotations?.['pl7.app/label']\n ?? 'Unlabelled axis',\n );\n }\n\n const { hits: compatibleColumns } = await pFrameDriver.findColumns(pFrame, {\n columnFilter: {},\n compatibleWith: Array.from(\n sequenceColumnsAxes.keys(),\n (axisIdJson) => parseJson(axisIdJson),\n ),\n strictlyCompatible: false,\n });\n\n for (const { columnId, spec } of compatibleColumns) {\n const columnIdJson = canonicalizeJson({ type: 'column', id: columnId });\n if (optionMap.has(columnIdJson)) continue;\n optionMap.set(\n columnIdJson,\n spec.annotations?.['pl7.app/label'] ?? 'Unlabelled column',\n );\n }\n\n const options = Array.from(optionMap).map(\n ([value, label]) => ({ label, value: parseJson(value) }),\n );\n\n const defaults = options\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 return { options, defaults };\n}\n\nasync function getMarkupColumnsOptions({\n pFrame,\n sequenceColumnIds,\n}: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnIds: PObjectId[] | undefined;\n}): Promise<ListOptionNormalized<PObjectId>[] | undefined> {\n if (!pFrame || sequenceColumnIds?.length !== 1) return;\n\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n const sequenceColumn = columns.find((column) =>\n column.columnId === sequenceColumnIds[0],\n );\n if (!sequenceColumn) {\n throw new Error(\n `Couldn't find sequence column (ID: \\`${sequenceColumnIds[0]}\\`).`,\n );\n }\n return columns\n .filter((column) =>\n column.spec.annotations?.['pl7.app/sequence/isAnnotation'] === 'true'\n && isJsonEqual(sequenceColumn.spec.axesSpec, column.spec.axesSpec)\n && Object.entries(sequenceColumn.spec.domain ?? {}).every((\n [key, value],\n ) => column.spec.domain?.[key] === value),\n ).map(({ columnId, spec }) => ({\n value: columnId,\n label: spec.annotations?.['pl7.app/label'] ?? 'Unlabelled column',\n }));\n}\n\nasync function getMultipleAlignmentData({\n pframe,\n sequenceColumnIds,\n labelColumnIds,\n markupColumnId,\n selection,\n colorScheme,\n alignmentParams,\n}: {\n pframe: PFrameHandle | undefined;\n sequenceColumnIds: PObjectId[] | undefined;\n labelColumnIds: PTableColumnId[] | undefined;\n markupColumnId: PObjectId | undefined;\n selection: PlSelectionModel | undefined;\n colorScheme: PlMultiSequenceAlignmentColorSchemeOption;\n alignmentParams: PlMultiSequenceAlignmentSettings['alignmentParams'];\n}): Promise<MultipleAlignmentData | undefined> {\n if (!pframe || !sequenceColumnIds?.length || !labelColumnIds) return;\n\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 (markupColumnId) {\n secondaryEntry.push({ type: 'column', column: markupColumnId });\n }\n\n const sorting: PTableSorting[] = Array.from(\n new Set(sequenceColumnIds.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 .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 const table = await 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: sequenceLimit + 1,\n },\n );\n\n let rowCount = table?.[0].data.data.length ?? 0;\n let exceedsLimit = false;\n if (rowCount > sequenceLimit) {\n rowCount = sequenceLimit;\n exceedsLimit = true;\n }\n\n const sequenceColumns = sequenceColumnIds.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 return column;\n });\n\n const labelColumns = labelColumnIds.map((labelColumn) => {\n const column = table.find(({ spec }) => {\n if (labelColumn.type === 'axis' && spec.type === 'axis') {\n return isJsonEqual(labelColumn.id, spec.id);\n }\n if (labelColumn.type === 'column' && spec.type === 'column') {\n return labelColumn.id === spec.id;\n }\n });\n if (!column) {\n throw new Error(`Couldn't find label column (ID: \\`${labelColumn}\\`).`);\n }\n return column;\n });\n\n const markupColumn = markupColumnId\n && table.find(({ spec }) => spec.id === markupColumnId);\n\n const alignedSequences = await Promise.all(\n sequenceColumns.map((column) =>\n multiSequenceAlignment(\n Array.from(\n { length: rowCount },\n (_, row) =>\n pTableValue(column.data, row, { na: '', absent: '' })?.toString()\n ?? '',\n ),\n alignmentParams,\n ),\n ),\n );\n\n const sequences = Array.from(\n { length: rowCount },\n (_, row) => alignedSequences.map((column) => column[row]),\n );\n\n const sequenceNames = sequenceColumns.map((column) =>\n column.spec.spec.annotations?.['pl7.app/label'] ?? 'Unlabelled column',\n );\n\n const labels = Array.from(\n { length: rowCount },\n (_, row) =>\n labelColumns.map((column) =>\n pTableValue(column.data, row, { na: '', absent: '' })?.toString() ?? '',\n ),\n );\n\n const concatenatedSequences = sequences.map((row) => row.join(' '));\n const residueCounts = getResidueCounts(concatenatedSequences);\n\n const result: MultipleAlignmentData = {\n sequences: concatenatedSequences,\n sequenceNames,\n labelsRows: labels,\n exceedsLimit,\n residueCounts,\n };\n\n if (markupColumn) {\n const labels = JSON.parse(\n markupColumn.spec.spec.annotations\n ?.['pl7.app/sequence/annotation/mapping'] ?? '{}',\n );\n const data = Array.from(\n { length: rowCount },\n (_, row) => {\n const markup = parseMarkup(\n pTableValue(markupColumn.data, row, { na: '', absent: '' })\n ?.toString()\n ?? '',\n );\n return markupAlignedSequence(sequences[row][0], markup);\n },\n );\n result.markup = { labels, data };\n }\n\n if (colorScheme.type === 'chemical-properties') {\n const colorMap = chemicalPropertiesColorMap;\n result.highlightImage = {\n blob: await colorizeSequencesByChemicalProperties({\n sequences: concatenatedSequences,\n residueCounts,\n colorMap,\n }),\n colorMap,\n };\n } else if (colorScheme.type === 'markup') {\n const colorMap = Object.fromEntries(\n Object.entries(\n result.markup?.labels ?? {},\n ).map(([id, label], index) => [\n id,\n { label, color: markupColors[index % markupColors.length] },\n ]),\n );\n result.highlightImage = {\n blob: await colorizeSequencesByMarkup({\n markupRows: result.markup?.data ?? [],\n colorMap,\n columnCount: concatenatedSequences.at(0)?.length ?? 0,\n }),\n colorMap,\n };\n }\n\n return result;\n}\n\nfunction refreshOnDeepChange<T, P>(cb: (params: P) => Promise<T>) {\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 currentRequestId = requestId = Symbol();\n try {\n error.value = undefined;\n isLoading.value = true;\n const result = await cb(params);\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: string[];\n sequenceNames: string[];\n labelsRows: string[][];\n residueCounts: ResidueCounts;\n markup?: {\n labels: Record<string, string>;\n data: Markup[];\n };\n highlightImage?: {\n blob: Blob;\n colorMap: ColorMap;\n };\n exceedsLimit: boolean;\n};\n\ntype OptionsWithDefaults<T> = {\n options: ListOptionNormalized<T>[];\n defaults: T[];\n};\n"],"names":["getPFrameDriver","getRawPlatformaInstance","sequenceLimit","useSequenceColumnsOptions","refreshOnDeepChange","getSequenceColumnsOptions","useLabelColumnsOptions","getLabelColumnsOptions","useMarkupColumnsOptions","getMarkupColumnsOptions","useMultipleAlignmentData","getMultipleAlignmentData","pFrame","sequenceColumnPredicate","options","column","spec","columnId","_a","defaults","value","sequenceColumnIds","pFrameDriver","columns","optionMap","sequenceColumnsAxes","id","canonicalizeJson","getAxisId","axisIdJson","axisSpec","axisId","parseJson","labelColumn","isLabelColumn","matchAxisId","_b","compatibleColumns","columnIdJson","_c","label","sequenceColumn","isJsonEqual","key","pframe","labelColumnIds","markupColumnId","selection","colorScheme","alignmentParams","linkerColumns","isLinkerColumn","filterColumn","createRowSelectionColumn","primaryEntry","secondaryEntry","sorting","request","table","rowCount","exceedsLimit","sequenceColumns","labelColumns","markupColumn","alignedSequences","multiSequenceAlignment","_","row","pTableValue","sequences","sequenceNames","labels","concatenatedSequences","residueCounts","getResidueCounts","result","data","markup","parseMarkup","markupAlignedSequence","colorMap","chemicalPropertiesColorMap","colorizeSequencesByChemicalProperties","index","markupColors","colorizeSequencesByMarkup","_d","cb","ref","isLoading","error","requestId","paramsGetter","watch","params","prevParams","currentRequestId","err","ensureError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"data.js","sources":["../../../src/components/PlMultiSequenceAlignment/data.ts"],"sourcesContent":["import { isJsonEqual } from '@milaboratories/helpers';\nimport type { ListOptionNormalized } from '@milaboratories/uikit';\nimport {\n type CalculateTableDataRequest,\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} from '@platforma-sdk/model';\nimport { ref, watch } from 'vue';\nimport { highlightByChemicalProperties } from './chemical-properties';\nimport {\n highlightByMarkup,\n markupAlignedSequence,\n parseMarkup,\n} from './markup';\nimport { multiSequenceAlignment } from './multi-sequence-alignment';\nimport { getResidueCounts } from './residue-counts';\nimport type { HighlightLegend, ResidueCounts } from './types';\n\nconst getPFrameDriver = () => getRawPlatformaInstance().pFrameDriver;\n\nexport const sequenceLimit = 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({\n pFrame,\n sequenceColumnPredicate,\n}: {\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 const options = columns.values()\n .filter((column) => sequenceColumnPredicate(column))\n .map(({ spec, columnId }) => ({\n label: spec.annotations?.['pl7.app/label'] ?? 'Unlabelled column',\n value: columnId,\n }))\n .toArray();\n const defaults = options.map(({ value }) => value);\n return { options, defaults };\n}\n\nasync function getLabelColumnsOptions({\n pFrame,\n sequenceColumnIds,\n}: {\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 const optionMap = new Map<CanonicalizedJson<PTableColumnId>, string>();\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 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 labelColumn?.spec.annotations?.['pl7.app/label']\n ?? axisSpec.annotations?.['pl7.app/label']\n ?? 'Unlabelled 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({ type: 'column', id: columnId });\n if (optionMap.has(columnIdJson)) continue;\n optionMap.set(\n columnIdJson,\n spec.annotations?.['pl7.app/label'] ?? 'Unlabelled 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 return { options, defaults };\n}\n\nasync function getMarkupColumnsOptions({\n pFrame,\n sequenceColumnIds,\n}: {\n pFrame: PFrameHandle | undefined;\n sequenceColumnIds: PObjectId[] | undefined;\n}): Promise<ListOptionNormalized<PObjectId>[] | undefined> {\n if (!pFrame || sequenceColumnIds?.length !== 1) return;\n\n const pFrameDriver = getPFrameDriver();\n const columns = await pFrameDriver.listColumns(pFrame);\n const sequenceColumn = columns.find((column) =>\n column.columnId === sequenceColumnIds[0],\n );\n if (!sequenceColumn) {\n throw new Error(\n `Couldn't find sequence column (ID: \\`${sequenceColumnIds[0]}\\`).`,\n );\n }\n return columns.values()\n .filter((column) =>\n column.spec.annotations?.['pl7.app/sequence/isAnnotation'] === 'true'\n && isJsonEqual(sequenceColumn.spec.axesSpec, column.spec.axesSpec)\n && Object.entries(sequenceColumn.spec.domain ?? {}).every((\n [key, value],\n ) => column.spec.domain?.[key] === value),\n ).map(({ columnId, spec }) => ({\n value: columnId,\n label: spec.annotations?.['pl7.app/label'] ?? 'Unlabelled column',\n }))\n .toArray();\n}\n\nasync function getMultipleAlignmentData({\n pframe,\n sequenceColumnIds,\n labelColumnIds,\n selection,\n colorScheme,\n alignmentParams,\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}): Promise<MultipleAlignmentData | undefined> {\n if (!pframe || !sequenceColumnIds?.length || !labelColumnIds) return;\n\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 secondaryEntry.push({ type: 'column', column: colorScheme.columnId });\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 const table = await 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: sequenceLimit + 1,\n },\n );\n\n let rowCount = table?.[0].data.data.length ?? 0;\n let exceedsLimit = false;\n if (rowCount > sequenceLimit) {\n rowCount = sequenceLimit;\n exceedsLimit = true;\n }\n\n const sequenceColumns = sequenceColumnIds.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 return column;\n });\n\n const labelColumns = labelColumnIds.map((labelColumn) => {\n const column = table.find(({ spec }) => {\n if (labelColumn.type === 'axis' && spec.type === 'axis') {\n return isJsonEqual(labelColumn.id, spec.id);\n }\n if (labelColumn.type === 'column' && spec.type === 'column') {\n return labelColumn.id === spec.id;\n }\n });\n if (!column) {\n throw new Error(`Couldn't find label column (ID: \\`${labelColumn}\\`).`);\n }\n return column;\n });\n\n const alignedSequences = await Promise.all(\n sequenceColumns.map((column) =>\n multiSequenceAlignment(\n Array.from(\n { length: rowCount },\n (_, row) =>\n pTableValue(column.data, row, { na: '', absent: '' })?.toString()\n ?? '',\n ),\n alignmentParams,\n ),\n ),\n );\n\n const sequences = Array.from(\n { length: rowCount },\n (_, row) => alignedSequences.map((column) => column[row]),\n );\n\n const sequenceNames = sequenceColumns.map((column) =>\n column.spec.spec.annotations?.['pl7.app/label'] ?? 'Unlabelled column',\n );\n\n const labels = Array.from(\n { length: rowCount },\n (_, row) =>\n labelColumns.map((column) =>\n pTableValue(column.data, row, { na: '', absent: '' })?.toString() ?? '',\n ),\n );\n\n const concatenatedSequences = sequences.map((row) => row.join(' '));\n const residueCounts = getResidueCounts(concatenatedSequences);\n\n const result: MultipleAlignmentData = {\n sequences: concatenatedSequences,\n sequenceNames,\n labelRows: labels,\n exceedsLimit,\n residueCounts,\n };\n\n if (colorScheme.type === 'chemical-properties') {\n result.highlightImage = highlightByChemicalProperties({\n sequences: concatenatedSequences,\n residueCounts,\n });\n } else if (colorScheme.type === 'markup') {\n const markupColumn = table.find(({ spec }) =>\n spec.id === colorScheme.columnId,\n );\n if (!markupColumn) {\n throw new Error(\n `Couldn't find markup column (ID: \\`${colorScheme.columnId}\\`).`,\n );\n }\n const markupRows = Array.from(\n { length: rowCount },\n (_, row) => {\n const markup = parseMarkup(\n pTableValue(markupColumn.data, row, { na: '', absent: '' })\n ?.toString()\n ?? '',\n );\n return markupAlignedSequence(sequences[row][0], markup);\n },\n );\n const labels: Record<string, string> = JSON.parse(\n markupColumn.spec.spec.annotations\n ?.['pl7.app/sequence/annotation/mapping'] ?? '{}',\n );\n result.highlightImage = highlightByMarkup({\n markupRows,\n columnCount: concatenatedSequences.at(0)?.length ?? 0,\n labels,\n });\n }\n\n return result;\n}\n\nfunction refreshOnDeepChange<T, P>(cb: (params: P) => Promise<T>) {\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 currentRequestId = requestId = Symbol();\n try {\n error.value = undefined;\n isLoading.value = true;\n const result = await cb(params);\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: string[];\n sequenceNames: string[];\n labelRows: string[][];\n residueCounts: ResidueCounts;\n highlightImage?: {\n blob: Blob;\n legend: HighlightLegend;\n };\n exceedsLimit: boolean;\n};\n\ntype OptionsWithDefaults<T> = {\n options: ListOptionNormalized<T>[];\n defaults: T[];\n};\n"],"names":["getPFrameDriver","getRawPlatformaInstance","sequenceLimit","useSequenceColumnsOptions","refreshOnDeepChange","getSequenceColumnsOptions","useLabelColumnsOptions","getLabelColumnsOptions","useMarkupColumnsOptions","getMarkupColumnsOptions","useMultipleAlignmentData","getMultipleAlignmentData","pFrame","sequenceColumnPredicate","options","column","spec","columnId","_a","defaults","value","sequenceColumnIds","pFrameDriver","columns","optionMap","sequenceColumnsAxes","id","canonicalizeJson","getAxisId","axisIdJson","axisSpec","axisId","parseJson","labelColumn","isLabelColumn","matchAxisId","_b","compatibleColumns","columnIdJson","_c","label","sequenceColumn","isJsonEqual","key","pframe","labelColumnIds","selection","colorScheme","alignmentParams","linkerColumns","isLinkerColumn","filterColumn","createRowSelectionColumn","primaryEntry","secondaryEntry","sorting","request","table","rowCount","exceedsLimit","sequenceColumns","labelColumns","alignedSequences","multiSequenceAlignment","_","row","pTableValue","sequences","sequenceNames","labels","concatenatedSequences","residueCounts","getResidueCounts","result","highlightByChemicalProperties","markupColumn","markupRows","markup","parseMarkup","markupAlignedSequence","highlightByMarkup","cb","data","ref","isLoading","error","requestId","paramsGetter","watch","params","prevParams","currentRequestId","err","ensureError"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HighlightLegend } from './types';
|
|
2
2
|
export type Markup = {
|
|
3
3
|
id: string;
|
|
4
4
|
start: number;
|
|
@@ -6,10 +6,12 @@ export type Markup = {
|
|
|
6
6
|
}[];
|
|
7
7
|
export declare function parseMarkup(row: string): Markup;
|
|
8
8
|
export declare function markupAlignedSequence(alignedSequence: string, markup: Markup): Markup;
|
|
9
|
-
export declare function
|
|
9
|
+
export declare function highlightByMarkup({ markupRows, columnCount, labels }: {
|
|
10
10
|
markupRows: Markup[];
|
|
11
11
|
columnCount: number;
|
|
12
|
-
|
|
13
|
-
}):
|
|
14
|
-
|
|
12
|
+
labels: Record<string, string>;
|
|
13
|
+
}): {
|
|
14
|
+
blob: Blob;
|
|
15
|
+
legend: HighlightLegend;
|
|
16
|
+
};
|
|
15
17
|
//# sourceMappingURL=markup.d.ts.map
|