@datagrok/bio 2.23.2 → 2.24.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 (48) hide show
  1. package/.eslintrc.json +0 -2
  2. package/CHANGELOG.md +5 -0
  3. package/README.md +1 -1
  4. package/dist/package-test.js +3 -3
  5. package/dist/package-test.js.map +1 -1
  6. package/dist/package.js +2 -2
  7. package/dist/package.js.map +1 -1
  8. package/package.json +2 -2
  9. package/src/package-types.ts +1 -1
  10. package/src/package.ts +9 -3
  11. package/src/tests/activity-cliffs-tests.ts +2 -2
  12. package/src/tests/monomer-libraries-tests.ts +8 -6
  13. package/src/tests/renderers-monomer-placer-tests.ts +1 -1
  14. package/src/tests/scoring.ts +1 -1
  15. package/src/tests/seq-handler-get-helm-tests.ts +1 -1
  16. package/src/tests/splitters-test.ts +2 -2
  17. package/src/tests/substructure-filters-tests.ts +11 -11
  18. package/src/tests/to-atomic-level-tests.ts +2 -2
  19. package/src/tests/to-atomic-level-ui-tests.ts +13 -14
  20. package/src/utils/cell-renderer.ts +1 -1
  21. package/src/utils/helm-to-molfile/converter/converter.ts +1 -1
  22. package/src/utils/helm-to-molfile/converter/mol-bonds.ts +1 -1
  23. package/src/utils/helm-to-molfile/converter/monomer-wrapper.ts +1 -1
  24. package/src/utils/helm-to-molfile/converter/polymer.ts +1 -1
  25. package/src/utils/helm-to-molfile/utils.ts +3 -2
  26. package/src/utils/monomer-cell-renderer-base.ts +1 -2
  27. package/src/utils/monomer-lib/consts.ts +1 -6
  28. package/src/utils/monomer-lib/lib-manager.ts +239 -112
  29. package/src/utils/monomer-lib/library-file-manager/monomers-lib-provider.ts +378 -0
  30. package/src/utils/monomer-lib/library-file-manager/ui.ts +119 -80
  31. package/src/utils/monomer-lib/monomer-colors.ts +37 -39
  32. package/src/utils/monomer-lib/monomer-lib-base.ts +3 -4
  33. package/src/utils/monomer-lib/monomer-lib.ts +7 -7
  34. package/src/utils/monomer-lib/monomer-manager/duplicate-monomer-manager.ts +3 -3
  35. package/src/utils/monomer-lib/monomer-manager/monomer-manager.ts +90 -81
  36. package/src/utils/monomer-lib/web-editor-monomer-of-library.ts +2 -1
  37. package/src/utils/seq-helper/seq-handler.ts +16 -3
  38. package/src/utils/seq-helper/seq-helper.ts +1 -2
  39. package/src/utils/sequence-to-mol.ts +1 -1
  40. package/src/viewers/web-logo-viewer.ts +1 -1
  41. package/src/widgets/composition-analysis-widget.ts +1 -1
  42. package/src/widgets/sequence-scrolling-widget.ts +1 -2
  43. package/test-console-output-1.log +672 -720
  44. package/test-record-1.mp4 +0 -0
  45. package/src/utils/monomer-lib/library-file-manager/custom-monomer-lib-handlers.ts +0 -41
  46. package/src/utils/monomer-lib/library-file-manager/event-manager.ts +0 -93
  47. package/src/utils/monomer-lib/library-file-manager/file-manager.ts +0 -317
  48. package/src/utils/monomer-lib/monomer-set.ts +0 -61
@@ -6,19 +6,21 @@ import * as DG from 'datagrok-api/dg';
6
6
 
7
7
  import $ from 'cash-dom';
8
8
  import {Subject} from 'rxjs';
9
- import './style.css';
10
9
 
11
10
  import {
12
11
  getUserLibSettings, setUserLibSettings
13
12
  } from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
14
13
  import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
15
- import {getMonomerLibHelper, IMonomerLibFileManager} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';
14
+ import {findProviderWithLibraryName,
15
+ getMonomerLibHelper, IMonomerLibHelper,
16
+ IMonomerLibProvider} from '@datagrok-libraries/bio/src/types/monomer-library';
16
17
 
17
- import {MonomerLibFileEventManager} from './event-manager';
18
18
  import {_package} from '../../../package';
19
19
  import {MonomerManager} from '../monomer-manager/monomer-manager';
20
20
  import {DuplicateMonomerManager} from '../monomer-manager/duplicate-monomer-manager';
21
21
  import {MonomerLibManager} from '../lib-manager';
22
+ // @ts-ignore
23
+ import './style.css';
22
24
 
23
25
  export async function showManageLibrariesDialog(): Promise<void> {
24
26
  await DialogWrapper.showDialog();
@@ -38,8 +40,6 @@ export async function getMonomerLibraryManagerLink(): Promise<DG.Widget> {
38
40
  }
39
41
 
40
42
  class MonomerLibraryManagerWidget {
41
- private _fileManager: IMonomerLibFileManager;
42
-
43
43
  private _widget: DG.Widget;
44
44
  public get widget(): DG.Widget { return this._widget; }
45
45
 
@@ -47,12 +47,14 @@ class MonomerLibraryManagerWidget {
47
47
 
48
48
  private static instancePromise?: Promise<MonomerLibraryManagerWidget>;
49
49
 
50
+ private libHelper: IMonomerLibHelper;
51
+
50
52
  static async getInstance(): Promise<MonomerLibraryManagerWidget> {
51
53
  if (MonomerLibraryManagerWidget.instancePromise === undefined) {
52
54
  MonomerLibraryManagerWidget.instancePromise = (async () => {
53
55
  const instance = new MonomerLibraryManagerWidget();
54
56
  const libHelper = await getMonomerLibHelper();
55
- instance._fileManager = await libHelper.getFileManager();
57
+ instance.libHelper = libHelper;
56
58
  instance._widget = await instance.createWidget();
57
59
  return instance;
58
60
  })();
@@ -69,7 +71,7 @@ class MonomerLibraryManagerWidget {
69
71
  const content = await this.getWidgetContent();
70
72
  const monomerLibHelper = await getMonomerLibHelper();
71
73
  // eslint-disable-next-line rxjs/no-ignored-subscription
72
- monomerLibHelper.eventManager.addLibraryFileRequested$.subscribe(
74
+ monomerLibHelper.fileUploadRequested.subscribe(
73
75
  () => this.promptToAddLibraryFiles()
74
76
  );
75
77
  return new DG.Widget(content);
@@ -89,17 +91,38 @@ class MonomerLibraryManagerWidget {
89
91
  DG.Utils.openFile({
90
92
  accept: '.json',
91
93
  open: async (selectedFile) => {
92
- const content = await selectedFile.text();
93
- const name = selectedFile.name;
94
- const progressIndicator = DG.TaskBarProgressIndicator.create(`Adding ${name} as a monomer library`);
95
- try {
96
- await this._fileManager.addLibraryFile(content, name);
94
+ const doAdd = async (provider: IMonomerLibProvider) => {
95
+ const content = await selectedFile.text();
96
+ const name = selectedFile.name;
97
+ const progressIndicator = DG.TaskBarProgressIndicator.create(`Adding ${name} as a monomer library`);
98
+ try {
99
+ await provider.addOrUpdateLibraryString(name, content);
97
100
  // this.eventManager.updateLibrarySelectionStatus(name, true);
98
- } catch (e) {
99
- grok.shell.error(`File ${name} is not a valid monomer library, verify it is aligned to HELM JSON schema.`);
100
- } finally {
101
- progressIndicator.close();
101
+ } catch (e) {
102
+ grok.shell.error(`File ${name} is not a valid monomer library, verify it is aligned to HELM JSON schema.`);
103
+ } finally {
104
+ progressIndicator.close();
105
+ }
106
+ };
107
+ const providers = await this.libHelper.getProviders();
108
+ if (providers.length === 0) {
109
+ grok.shell.error('No monomer library providers available to add the library.');
110
+ return;
102
111
  }
112
+ if (providers.length === 1) {
113
+ await doAdd(providers[0]);
114
+ return;
115
+ }
116
+ const dialog = ui.dialog('Select storage for new monomer library');
117
+ const providersInput =
118
+ ui.input.choice('Storage', {items: providers.map((p) => p.name), value: providers[0].name,
119
+ nullable: false, tooltipText: 'Storage provider for new monomer library'});
120
+ dialog
121
+ .add(providersInput)
122
+ .onOK(async () => {
123
+ const provider = providers.find((p) => p.name === providersInput.value)!; // should not be null
124
+ await doAdd(provider);
125
+ });
103
126
  },
104
127
  });
105
128
  }
@@ -107,16 +130,11 @@ class MonomerLibraryManagerWidget {
107
130
 
108
131
  class LibraryControlsManager {
109
132
  private constructor(
110
- private fileManager: IMonomerLibFileManager,
133
+ private readonly libHelper: IMonomerLibHelper,
111
134
  private readonly userLibSettings: UserLibSettings,
112
135
  ) {
113
- // eslint-disable-next-line rxjs/no-ignored-subscription
114
- this.fileManager.eventManager.updateUIControlsRequested$.subscribe(() => {
115
- this.updateControlsForm();
116
- });
117
- // eslint-disable-next-line rxjs/no-ignored-subscription
118
- this.fileManager.eventManager.librarySelectionRequested$.subscribe(([fileName, isSelected]) => {
119
- this.updateLibrarySelectionStatus(isSelected, fileName);
136
+ this.libHelper.providersDataChanged.subscribe(async () => {
137
+ await this.updateControlsForm();
120
138
  });
121
139
  }
122
140
 
@@ -127,30 +145,28 @@ class LibraryControlsManager {
127
145
  static async createControlsForm(): Promise<HTMLElement> {
128
146
  const logPrefix = 'LibraryControlsForm.createControlsForm()';
129
147
  _package.logger.debug(`${logPrefix}, start`);
130
- const [fileManager, userLibSettings] = await Promise.all([
131
- getMonomerLibHelper().then((libHelper) => libHelper.getFileManager()),
132
- await getUserLibSettings(),
133
- ]);
134
- const manager = new LibraryControlsManager(fileManager, userLibSettings);
148
+ const userLibSettings = await getUserLibSettings();
149
+ const libHelper = await getMonomerLibHelper();
150
+ const manager = new LibraryControlsManager(libHelper, userLibSettings);
135
151
 
136
152
  return manager._createControlsForm();
137
153
  }
138
154
 
139
- private _createControlsForm(): HTMLElement {
140
- const libraryControls = this.createLibraryControls();
155
+ private async _createControlsForm(): Promise<HTMLElement> {
156
+ const libraryControls = await this.createLibraryControls();
141
157
  const inputsForm = ui.wideForm(libraryControls, undefined);
142
158
  $(inputsForm).addClass('monomer-lib-controls-form');
143
159
 
144
160
  return inputsForm;
145
161
  }
146
162
 
147
- public updateControlsForm(): void {
148
- const updatedForm = this._createControlsForm();
163
+ public async updateControlsForm(): Promise<void> {
164
+ const updatedForm = await this._createControlsForm();
149
165
  $('.monomer-lib-controls-form').replaceWith(updatedForm);
150
166
  }
151
167
 
152
- private createLibraryControls(): DG.InputBase<boolean | null>[] {
153
- const libFileNameList: string[] = this.fileManager.getValidLibraryPaths();
168
+ private async createLibraryControls(): Promise<DG.InputBase<boolean | null>[]> {
169
+ const libFileNameList: string[] = await this.libHelper.getAvaliableLibraryNames();
154
170
  return libFileNameList.map((libFileName) => this.createLibInput(libFileName));
155
171
  }
156
172
 
@@ -159,7 +175,7 @@ class LibraryControlsManager {
159
175
  _package.logger.debug(`${logPrefix}, libFileName = '${libFileName}', start`);
160
176
  const isMonomerLibrarySelected = !this.userLibSettings.exclude.includes(libFileName);
161
177
  const libInput = ui.input.bool(libFileName, {value: isMonomerLibrarySelected, onValueChanged: () => {
162
- this.fileManager.eventManager.updateLibrarySelectionStatus(libFileName, libInput.value);
178
+ updateLibrarySelectionStatus(libInput.value, libFileName);
163
179
  }});
164
180
  ui.tooltip.bind(libInput.root, `Include monomers from ${libFileName}`);
165
181
  const deleteIcon = ui.iconFA('trash-alt', () => this.promptForLibraryDeletion(libFileName));
@@ -173,38 +189,19 @@ class LibraryControlsManager {
173
189
  return libInput;
174
190
  }
175
191
 
176
- private async updateLibrarySelectionStatus(
177
- isMonomerLibrarySelected: boolean,
178
- libFileName: string
179
- ): Promise<void> {
180
- this.updateLibrarySettings(isMonomerLibrarySelected, libFileName);
181
- await setUserLibSettings(this.userLibSettings);
182
- const monomerLibHelper = await getMonomerLibHelper();
183
- await monomerLibHelper.loadMonomerLib(true);
184
- grok.shell.info('Monomer library user settings saved');
185
- }
186
-
187
- private updateLibrarySettings(
188
- isLibrarySelected: boolean | null,
189
- libFileName: string,
190
- ): void {
191
- if (isLibrarySelected) {
192
- // Remove selected library from exclusion list
193
- this.userLibSettings.exclude = this.userLibSettings.exclude.filter((libName) => libName !== libFileName);
194
- } else if (!this.userLibSettings.exclude.includes(libFileName)) {
195
- // Add unselected library to exclusion list
196
- this.userLibSettings.exclude.push(libFileName);
197
- }
198
- }
199
192
 
200
193
  private promptForLibraryDeletion(fileName: string): void {
201
194
  const dialog = ui.dialog('Warning');
202
- dialog.add(ui.divText(`Delete file ${fileName}?`))
195
+ dialog.add(ui.divText(`Are you sure you want to delete library "${fileName}"?`))
203
196
  .onOK(async () => {
204
197
  try {
205
198
  const progressIndicator = DG.TaskBarProgressIndicator.create(`Deleting ${fileName} library`);
206
- await this.updateLibrarySelectionStatus(false, fileName);
207
- await this.fileManager.deleteLibraryFile(fileName);
199
+ await updateLibrarySelectionStatus(false, fileName);
200
+ const provider = await findProviderWithLibraryName(await this.libHelper.getProviders(), fileName);
201
+ if (!provider)
202
+ throw new Error(`Cannot find provider for library ${fileName}`);
203
+ await provider.deleteLibrary(fileName);
204
+ // await this.fileManager.deleteLibraryFile(fileName);
208
205
  progressIndicator.close();
209
206
  } catch (e) {
210
207
  console.error(e);
@@ -215,6 +212,33 @@ class LibraryControlsManager {
215
212
  }
216
213
  }
217
214
 
215
+ async function updateLibrarySelectionStatus(
216
+ isMonomerLibrarySelected: boolean,
217
+ libFileName: string
218
+ ): Promise<void> {
219
+ const userLibSettings = await getUserLibSettings();
220
+ updateLibrarySettings(userLibSettings, isMonomerLibrarySelected, libFileName);
221
+ await setUserLibSettings(userLibSettings);
222
+ const monomerLibHelper = await getMonomerLibHelper();
223
+ await monomerLibHelper.loadMonomerLib(true);
224
+ grok.shell.info('Monomer library user settings saved');
225
+ monomerLibHelper.notifyLibrarySelectionChanged();
226
+ }
227
+
228
+ function updateLibrarySettings(
229
+ userLibSettings: UserLibSettings,
230
+ isLibrarySelected: boolean | null,
231
+ libFileName: string,
232
+ ): void {
233
+ if (isLibrarySelected) {
234
+ // Remove selected library from exclusion list
235
+ userLibSettings.exclude = userLibSettings.exclude.filter((libName) => libName !== libFileName);
236
+ } else if (!userLibSettings.exclude.includes(libFileName)) {
237
+ // Add unselected library to exclusion list
238
+ userLibSettings.exclude.push(libFileName);
239
+ }
240
+ }
241
+
218
242
  class DialogWrapper {
219
243
  private constructor() { }
220
244
 
@@ -238,8 +262,8 @@ class DialogWrapper {
238
262
  }
239
263
 
240
264
  private async getDialog(): Promise<DG.Dialog> {
241
- const eventManager = MonomerLibFileEventManager.getInstance();
242
265
  const widget = (await MonomerLibraryManagerWidget.getInstance()).widget;
266
+ const libHelper = await getMonomerLibHelper();
243
267
  const dialog = ui.dialog(
244
268
  {
245
269
  title: 'Manage monomer libraries',
@@ -250,7 +274,7 @@ class DialogWrapper {
250
274
  dialog.clear();
251
275
  dialog.addButton(
252
276
  'Add',
253
- () => eventManager.addLibraryFile(),
277
+ () => libHelper.requestFileUpload(),
254
278
  undefined,
255
279
  'Upload new HELM monomer library'
256
280
  );
@@ -264,17 +288,17 @@ class DialogWrapper {
264
288
  }
265
289
 
266
290
  class LibManagerView {
267
- private constructor() {};
291
+ private constructor(
292
+ ) {};
268
293
  private static _instance: LibManagerView;
269
294
  static viewName = 'Manage Monomer Libraries';
270
295
  private _view: DG.View;
271
296
  private _duplicateManager: DuplicateMonomerManager;
272
297
  private libManager: MonomerLibManager;
273
298
  private async getView(addView = true) {
274
- const eventManager = MonomerLibFileEventManager.getInstance();
275
299
  const widget = (await MonomerLibraryManagerWidget.getInstance()).widget;
276
300
  const addButton = ui.bigButton('Add',
277
- () => eventManager.addLibraryFile(), 'Upload new HELM monomer library');
301
+ () => this.libManager.requestFileUpload(), 'Upload new HELM monomer library');
278
302
  const mergeButton =
279
303
  ui.bigButton('Merge', () => { this.mergeSelectedLibs(); }, 'Merge selected libraries into one');
280
304
 
@@ -349,7 +373,6 @@ class LibManagerView {
349
373
  const libraryExistsError = 'Library with this name already exists';
350
374
  const libManager = await MonomerLibManager.getInstance();
351
375
  await libManager.awaitLoaded();
352
- await libManager.loadLibrariesPromise;
353
376
  if (!libManager.duplicatesHandled) {
354
377
  grok.shell.warning(`Selected libraries contain repeating symbols with different monomers.
355
378
  Please choose the correct monomer for each symbol using duplicate monomomer manager.`);
@@ -366,37 +389,53 @@ class LibManagerView {
366
389
  dialog.getButton('Save')?.classList?.toggle('d4-disabled', !!res);
367
390
  }
368
391
  });
369
- const validLibPaths = (await this.libManager.getFileManager()).getValidLibraryPaths();
392
+ const validLibPaths = await this.libManager.getAvaliableLibraryNames();
370
393
  newFileNameInput.addValidator(validateInput);
371
- function getFileNameInputValue() {
372
- let fileName = newFileNameInput.value;
373
- if (!fileName.endsWith('.json'))
374
- fileName += '.json';
375
- return fileName;
376
- };
377
394
 
378
395
  function validateInput(v: string) {
379
396
  if (!v || !v.trim()) return 'Library name cannot be empty';
380
- if ((v.endsWith('.json') && validLibPaths.includes(v)) || validLibPaths.includes(v + '.json'))
397
+ if (validLibPaths.includes(v) || validLibPaths.includes(v + '.json'))
381
398
  return libraryExistsError;
382
399
  return null;
383
400
  }
401
+ const providers = await this.libManager.getProviders();
402
+ if (providers.length === 0) {
403
+ grok.shell.error('No monomer library providers available to save the merged library.');
404
+ return; // I mean, this should not happen, but ....
405
+ }
406
+ const providersInput = ui.input.choice('Storage', {items: providers.map((p) => p.name), value: providers[0].name,
407
+ nullable: false, tooltipText: 'Storage provider for saving new monomer library'});
408
+
409
+ const getFileNameInputValue = () => {
410
+ let fileName = newFileNameInput.value.trim();
411
+ if (!fileName)
412
+ fileName = 'New';
413
+ if (!fileName.toLowerCase().endsWith('.json'))
414
+ fileName += '.json';
415
+ return fileName;
416
+ };
384
417
  dialog
418
+ .add(providersInput)
385
419
  .add(newFileNameInput)
386
420
  .add(ui.divText(`Total monomers: ${libJSON.length}`))
387
421
  .addButton('Download', () => { DG.Utils.download(getFileNameInputValue(), JSON.stringify(libJSON)); })
388
422
  .addButton('Save', async () => {
423
+ if (!newFileNameInput.value || !newFileNameInput.value.trim() || !providersInput.value) {
424
+ providersInput.validate();
425
+ newFileNameInput.validate(); // this will force showing validation error
426
+ return;
427
+ }
389
428
  dialog.close();
390
- const fileName = getFileNameInputValue();
429
+ const fileName = newFileNameInput.value!;
391
430
  const content = JSON.stringify(libJSON);
392
- const fileManager = await this.libManager.getFileManager();
393
431
  this._view && ui.setUpdateIndicator(this._view.root, true);
394
432
  try {
395
- await fileManager.addLibraryFile(content, fileName, false); // we will reload after updating settings
433
+ const provider = providers.find((p) => p.name === providersInput.value)!; // should not be null
434
+ await provider.addOrUpdateLibraryString(fileName, content); // we will reload after updating settings
396
435
  const settings = await getUserLibSettings();
397
436
  settings.exclude = validLibPaths; // exclude all previous libraries
398
437
  await setUserLibSettings(settings);
399
- await this.libManager.loadLibraries(true);
438
+ await this.libManager.loadMonomerLib(true);
400
439
  await MonomerLibraryManagerWidget.reloadWidget();
401
440
  } catch (e) {
402
441
  grok.shell.error(`Failed to save library ${fileName}. see console for details.`);
@@ -1,6 +1,4 @@
1
1
  import {HelmTypes} from '@datagrok-libraries/bio/src/helm/consts';
2
- import {Helm} from '../helm-to-molfile/converter/helm';
3
- import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
4
2
 
5
3
  /**
6
4
  * MonomerColors class from HelmWebEditor for natural monomers
@@ -8,64 +6,64 @@ import {HelmType} from '@datagrok-libraries/bio/src/helm/types';
8
6
  export const naturalMonomerColors = {
9
7
  [HelmTypes.BASE]: {
10
8
  // Chromatogram palette // HELMWebEditor monomerColors
11
- A: "#20E040", // "#A0A0FF",
12
- G: "#040404", // "#FF7070",
13
- T: "#FF8080", // "#A0FFA0",
14
- C: "#2060FF", // "#FF8C4B",
15
- U: "#FF8080", // "#FF8080"
9
+ A: '#20E040', // "#A0A0FF",
10
+ G: '#040404', // "#FF7070",
11
+ T: '#FF8080', // "#A0FFA0",
12
+ C: '#2060FF', // "#FF8C4B",
13
+ U: '#FF8080', // "#FF8080"
16
14
  },
17
15
 
18
16
  [HelmTypes.NUCLEOTIDE]: {
19
17
  // Chromatogram palette // HELMWebEditor monomerColors
20
- A: "#20E040", // "#A0A0FF",
21
- G: "#040404", // "#FF7070",
22
- T: "#FF8080", // "#A0FFA0",
23
- C: "#2060FF", // "#FF8C4B",
24
- U: "#FF8080", // "#FF8080"
18
+ A: '#20E040', // "#A0A0FF",
19
+ G: '#040404', // "#FF7070",
20
+ T: '#FF8080', // "#A0FFA0",
21
+ C: '#2060FF', // "#FF8C4B",
22
+ U: '#FF8080', // "#FF8080"
25
23
  },
26
24
 
27
25
  [HelmTypes.LINKER]: {
28
- P: "#9aa5e1",
29
- p: "#9aa5e1"
26
+ P: '#9aa5e1',
27
+ p: '#9aa5e1'
30
28
  },
31
29
 
32
30
  [HelmTypes.SUGAR]: {
33
- R: "#7a85c1",
34
- r: "#7a85c1",
31
+ R: '#7a85c1',
32
+ r: '#7a85c1',
35
33
  // TODO: deoxyribose
36
34
  },
37
35
 
38
36
  [HelmTypes.AA]: {
39
37
  // GrokGroups palette // HELMWebEditor monomerColors
40
- A: "rgb(44,160,44)", // "#C8C8C8",
41
- R: "rgb(23,190,207)", // "#145AFF",
42
- N: "rgb(235,137,70)", // "#00DCDC",
43
- D: "rgb(31,119,180)", // "#E60A0A",
44
- C: "rgb(188,189,34)", // "#E6E600",
45
- E: "rgb(31, 120, 150)", // "#00DCDC",
46
- Q: "rgb(205, 111, 71)", // "#E60A0A",
47
- G: "rgb(214,39,40)", // "#EBEBEB",
48
- H: "rgb(158,218,229)", // "#8282D2",
49
- I: "rgb(23,103,57)", // "#0F820F",
50
- L: "rgb(30,110,96)", // "#0F820F",
51
- K: "rgb(108, 218, 229)", //"#145AFF",
52
- M: "rgb(60,131,95)", // "#E6E600",
53
- F: "rgb(24,110,79)", // "#3232AA",
54
- P: "rgb(255,152,150)", // "#DC9682",
55
- S: "rgb(255,187,120)", // "#FA9600",
56
- T: "rgb(245,167,100)", // "#FA9600",
57
- W: "rgb(182, 223, 138)", // "#B45AB4",
58
- Y: "rgb(152,223,138)", // "#3232AA",
59
- V: "rgb(74,160,74)", // "#0F820F",
38
+ A: 'rgb(44,160,44)', // "#C8C8C8",
39
+ R: 'rgb(23,190,207)', // "#145AFF",
40
+ N: 'rgb(235,137,70)', // "#00DCDC",
41
+ D: 'rgb(31,119,180)', // "#E60A0A",
42
+ C: 'rgb(188,189,34)', // "#E6E600",
43
+ E: 'rgb(31, 120, 150)', // "#00DCDC",
44
+ Q: 'rgb(205, 111, 71)', // "#E60A0A",
45
+ G: 'rgb(214,39,40)', // "#EBEBEB",
46
+ H: 'rgb(158,218,229)', // "#8282D2",
47
+ I: 'rgb(23,103,57)', // "#0F820F",
48
+ L: 'rgb(30,110,96)', // "#0F820F",
49
+ K: 'rgb(108, 218, 229)', //"#145AFF",
50
+ M: 'rgb(60,131,95)', // "#E6E600",
51
+ F: 'rgb(24,110,79)', // "#3232AA",
52
+ P: 'rgb(255,152,150)', // "#DC9682",
53
+ S: 'rgb(255,187,120)', // "#FA9600",
54
+ T: 'rgb(245,167,100)', // "#FA9600",
55
+ W: 'rgb(182, 223, 138)', // "#B45AB4",
56
+ Y: 'rgb(152,223,138)', // "#3232AA",
57
+ V: 'rgb(74,160,74)', // "#0F820F",
60
58
  },
61
59
 
62
60
  [HelmTypes.CHEM]: {
63
- R: "#eeeeee",
61
+ R: '#eeeeee',
64
62
  },
65
63
 
66
64
  [HelmTypes.BLOB]: {
67
- B: "#999999",
68
- G: "#e2e2e2"
65
+ B: '#999999',
66
+ G: '#e2e2e2'
69
67
  }
70
68
  };
71
69
 
@@ -6,7 +6,7 @@ import * as DG from 'datagrok-api/dg';
6
6
  import wu from 'wu';
7
7
  import {Observable, Subject} from 'rxjs';
8
8
 
9
- import {IMonomerLibBase, Monomer, RGroup} from '@datagrok-libraries/bio/src/types/index';
9
+ import {IMonomerLibBase, Monomer, RGroup} from '@datagrok-libraries/bio/src/types/monomer-library';
10
10
  import {HelmAtom, HelmType, IMonomerColors,
11
11
  IWebEditorMonomer, MonomerType, PolymerType} from '@datagrok-libraries/bio/src/helm/types';
12
12
  import {getMonomerHandleArgs} from '@datagrok-libraries/bio/src/helm/helm-helper';
@@ -23,6 +23,7 @@ import {LibraryWebEditorMonomer} from './web-editor-monomer-of-library';
23
23
  import {naturalMonomerColors} from './monomer-colors';
24
24
 
25
25
  import {_package} from '../../package';
26
+ import {MonomerLibData} from '@datagrok-libraries/bio/src/types/monomer-library';
26
27
 
27
28
  const monomerRe = /[\w()]+/;
28
29
  //** Do not mess with monomer symbol with parenthesis enclosed in square brackets */
@@ -34,8 +35,6 @@ const drawMoleculeCall = (s: string) => {
34
35
  return canvas;
35
36
  };
36
37
 
37
- export type MonomerLibDataType = { [polymerType: string]: { [monomerSymbol: string]: Monomer } };
38
-
39
38
  const whiteColorV = new Vector([255.0, 255.0, 255.0]);
40
39
  const blackColorV = new Vector([0.0, 0.0, 0.0]);
41
40
  const maxTextColorVLen = vectorLength(whiteColorV) * 0.7;
@@ -50,7 +49,7 @@ export class MonomerLibBase implements IMonomerLibBase {
50
49
 
51
50
 
52
51
  constructor(
53
- protected _monomers: MonomerLibDataType,
52
+ protected _monomers: MonomerLibData,
54
53
  public readonly source: string,
55
54
  ) {
56
55
  this._isEmpty = !this._monomers || Object.keys(this._monomers).length === 0 ||
@@ -12,16 +12,17 @@ import {
12
12
  MonomerSetType, PolymerType,
13
13
  } from '@datagrok-libraries/bio/src/helm/types';
14
14
  import {IMonomerLibBase, IMonomerLib, Monomer,
15
- MonomerLibData, MonomerLibSummaryType} from '@datagrok-libraries/bio/src/types';
15
+ MonomerLibData, MonomerLibSummaryType} from '@datagrok-libraries/bio/src/types/monomer-library';
16
16
  import {MolfileHandler} from '@datagrok-libraries/chem-meta/src/parsing-utils/molfile-handler';
17
17
  import {helmTypeToPolymerType} from '@datagrok-libraries/bio/src/monomer-works/monomer-works';
18
18
  import {getUserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
19
19
  import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
20
20
 
21
- import {MonomerLibBase, MonomerLibDataType} from './monomer-lib-base';
21
+ import {MonomerLibBase} from './monomer-lib-base';
22
22
 
23
23
  import {_package} from '../../package';
24
24
 
25
+ //@ts-ignore
25
26
  import '../../../css/cell-renderer.css';
26
27
 
27
28
  /** Wrapper for monomers obtained from different sources. For managing monomere
@@ -38,7 +39,7 @@ export class MonomerLib extends MonomerLibBase implements IMonomerLib {
38
39
  private duplicatesNotified: boolean = false;
39
40
 
40
41
  constructor(
41
- monomers: MonomerLibDataType,
42
+ monomers: MonomerLibData,
42
43
  source: string,
43
44
  public readonly error: string | undefined = undefined,
44
45
  ) {
@@ -158,7 +159,7 @@ export class MonomerLib extends MonomerLibBase implements IMonomerLib {
158
159
  this._isEmpty = this.isEmpty && lib.isEmpty;
159
160
  }
160
161
 
161
- public updateLibs(libList: IMonomerLib[], reload: boolean = false): void {
162
+ public async updateLibs(libList: IMonomerLib[], reload: boolean = false): Promise<void> {
162
163
  if (reload) {
163
164
  this._monomers = {};
164
165
  this._isEmpty = true;
@@ -167,9 +168,8 @@ export class MonomerLib extends MonomerLibBase implements IMonomerLib {
167
168
  for (const lib of libList)
168
169
  if (!lib.error) this._updateLibInt(lib);
169
170
  if (Object.entries(this.duplicateMonomers).length > 0) {
170
- getUserLibSettings().then((settings) => {
171
- this.assignDuplicatePreferences(settings);
172
- });
171
+ const settings = await getUserLibSettings();
172
+ this.assignDuplicatePreferences(settings);
173
173
  } else
174
174
  this._duplicatesHandled = true;
175
175
 
@@ -3,11 +3,12 @@ import * as grok from 'datagrok-api/grok';
3
3
  import * as ui from 'datagrok-api/ui';
4
4
  import * as DG from 'datagrok-api/dg';
5
5
 
6
- import {Monomer} from '@datagrok-libraries/bio/src/types';
6
+ import {Monomer} from '@datagrok-libraries/bio/src/types/monomer-library';
7
7
  import {UserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/types';
8
8
  import {getUserLibSettings, setUserLibSettings} from '@datagrok-libraries/bio/src/monomer-works/lib-settings';
9
- import '../../../../css/monomer-manager.css';
10
9
  import {MonomerLibManager} from '../lib-manager';
10
+ // @ts-ignore
11
+ import '../../../../css/monomer-manager.css';
11
12
 
12
13
  class MonomerCard {
13
14
  root: HTMLElement = ui.divV([], {classes: 'monomer-card-root'});
@@ -109,7 +110,6 @@ export class DuplicateMonomerManager {
109
110
  this.settings = await getUserLibSettings();
110
111
  const libManager = await MonomerLibManager.getInstance();
111
112
  await libManager.awaitLoaded();
112
- await libManager.loadLibrariesPromise;
113
113
  this.monomers = libManager.duplicateMonomers;
114
114
  this.monomerCardRows = [];
115
115
  for (const polymerType in this.monomers) {