@datagrok/sequence-translator 1.2.6 → 1.2.9

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 (102) hide show
  1. package/.eslintrc.json +5 -5
  2. package/CHANGELOG.md +12 -0
  3. package/dist/package-test.js +2 -1
  4. package/dist/package-test.js.LICENSE.txt +8 -0
  5. package/dist/package-test.js.map +1 -1
  6. package/dist/package.js +2 -1
  7. package/dist/package.js.LICENSE.txt +8 -0
  8. package/dist/package.js.map +1 -1
  9. package/files/pattern-app-data.json +80 -0
  10. package/package.json +21 -14
  11. package/src/{model → apps/common/model}/const.ts +1 -1
  12. package/src/{model/data-loading-utils → apps/common/model/data-loader}/const.ts +7 -2
  13. package/src/apps/common/model/data-loader/json-loader.ts +48 -0
  14. package/src/{model/data-loading-utils → apps/common/model/data-loader}/types.ts +13 -6
  15. package/src/{model → apps/common/model}/monomer-lib/lib-wrapper.ts +9 -12
  16. package/src/apps/common/model/oligo-toolkit-package.ts +30 -0
  17. package/src/{model → apps/common/model}/parsing-validation/format-detector.ts +5 -5
  18. package/src/{model → apps/common/model}/parsing-validation/format-handler.ts +18 -19
  19. package/src/{model → apps/common/model}/parsing-validation/sequence-validator.ts +1 -1
  20. package/src/apps/common/view/app-ui-base.ts +28 -0
  21. package/src/apps/common/view/combined-app-ui.ts +66 -0
  22. package/src/{view/utils → apps/common/view/components}/colored-input/colored-text-input.ts +1 -1
  23. package/src/{view/utils → apps/common/view/components}/draw-molecule.ts +1 -1
  24. package/src/{view/utils → apps/common/view/components}/molecule-img.ts +3 -3
  25. package/src/{view/const/ui.ts → apps/common/view/const.ts} +4 -4
  26. package/src/apps/common/view/isolated-app-ui.ts +43 -0
  27. package/src/{view/monomer-lib-viewer/viewer.ts → apps/common/view/monomer-lib-viewer.ts} +2 -2
  28. package/src/apps/common/view/utils.ts +29 -0
  29. package/src/apps/pattern/model/const.ts +121 -0
  30. package/src/apps/pattern/model/data-manager.ts +297 -0
  31. package/src/apps/pattern/model/event-bus.ts +470 -0
  32. package/src/apps/pattern/model/router.ts +46 -0
  33. package/src/apps/pattern/model/subscription-manager.ts +21 -0
  34. package/src/apps/pattern/model/translator.ts +68 -0
  35. package/src/apps/pattern/model/types.ts +52 -0
  36. package/src/apps/pattern/model/utils.ts +110 -0
  37. package/src/apps/pattern/view/components/bulk-convert/column-input.ts +69 -0
  38. package/src/apps/pattern/view/components/bulk-convert/table-controls.ts +37 -0
  39. package/src/apps/pattern/view/components/bulk-convert/table-input.ts +95 -0
  40. package/src/apps/pattern/view/components/edit-block-controls.ts +196 -0
  41. package/src/apps/pattern/view/components/left-section.ts +44 -0
  42. package/src/apps/pattern/view/components/load-block-controls.ts +198 -0
  43. package/src/apps/pattern/view/components/numeric-label-visibility-controls.ts +69 -0
  44. package/src/apps/pattern/view/components/right-section.ts +148 -0
  45. package/src/apps/pattern/view/components/strand-editor/dialog.ts +79 -0
  46. package/src/apps/pattern/view/components/strand-editor/header-controls.ts +105 -0
  47. package/src/apps/pattern/view/components/strand-editor/strand-controls.ts +159 -0
  48. package/src/apps/pattern/view/components/terminal-modification-editor.ts +127 -0
  49. package/src/apps/pattern/view/components/translation-examples-block.ts +139 -0
  50. package/src/{view/style/pattern-app.css → apps/pattern/view/style.css} +4 -0
  51. package/src/apps/pattern/view/svg-utils/const.ts +63 -0
  52. package/src/apps/pattern/view/svg-utils/dimensions-calculator.ts +498 -0
  53. package/src/apps/pattern/view/svg-utils/svg-display-manager.ts +45 -0
  54. package/src/apps/pattern/view/svg-utils/svg-element-factory.ts +82 -0
  55. package/src/apps/pattern/view/svg-utils/svg-renderer.ts +396 -0
  56. package/src/apps/pattern/view/svg-utils/utils.ts +37 -0
  57. package/src/apps/pattern/view/types.ts +14 -0
  58. package/src/apps/pattern/view/ui.ts +61 -0
  59. package/src/{model/structure-app → apps/structure/model}/mol-transformations.ts +3 -3
  60. package/src/{model/structure-app → apps/structure/model}/monomer-code-parser.ts +9 -10
  61. package/src/{model/structure-app → apps/structure/model}/oligo-structure.ts +4 -4
  62. package/src/{model/structure-app → apps/structure/model}/sequence-to-molfile.ts +2 -2
  63. package/src/{view/apps/oligo-structure.ts → apps/structure/view/ui.ts} +31 -17
  64. package/src/{model/translator-app → apps/translator/model}/conversion-utils.ts +25 -7
  65. package/src/{model/translator-app → apps/translator/model}/format-converter.ts +7 -12
  66. package/src/{view/const/oligo-translator.ts → apps/translator/view/const.ts} +2 -0
  67. package/src/apps/translator/view/ui.ts +547 -0
  68. package/src/demo/demo-st-ui.ts +12 -32
  69. package/src/package.ts +76 -56
  70. package/src/plugins/mermade.ts +9 -9
  71. package/src/polytool/const.ts +40 -0
  72. package/src/polytool/csv-to-json-monomer-lib-converter.ts +40 -0
  73. package/src/polytool/cyclized.ts +56 -0
  74. package/src/polytool/monomer-lib-handler.ts +115 -0
  75. package/src/polytool/transformation.ts +326 -0
  76. package/src/polytool/ui.ts +59 -0
  77. package/src/polytool/utils.ts +20 -0
  78. package/src/tests/const.ts +5 -5
  79. package/src/tests/formats-support.ts +6 -6
  80. package/src/tests/formats-to-helm.ts +5 -5
  81. package/src/tests/helm-to-nucleotides.ts +5 -5
  82. package/tsconfig.json +4 -10
  83. package/webpack.config.js +3 -0
  84. package/files/axolabs-style.json +0 -97
  85. package/src/model/data-loading-utils/json-loader.ts +0 -38
  86. package/src/model/pattern-app/const.ts +0 -33
  87. package/src/model/pattern-app/draw-svg.ts +0 -193
  88. package/src/model/pattern-app/helpers.ts +0 -96
  89. package/src/model/pattern-app/oligo-pattern.ts +0 -111
  90. package/src/view/app-ui.ts +0 -193
  91. package/src/view/apps/oligo-pattern.ts +0 -759
  92. package/src/view/apps/oligo-translator.ts +0 -184
  93. /package/src/{model → apps/common/model}/helpers.ts +0 -0
  94. /package/src/{model → apps/common/model}/monomer-lib/const.ts +0 -0
  95. /package/src/{view/utils → apps/common/view/components}/app-info-dialog.ts +0 -0
  96. /package/src/{view/utils → apps/common/view/components}/colored-input/input-painters.ts +0 -0
  97. /package/src/{view/style/colored-text-input.css → apps/common/view/components/colored-input/style.css} +0 -0
  98. /package/src/{view/utils → apps/common/view/components}/router.ts +0 -0
  99. /package/src/{model/structure-app → apps/structure/model}/const.ts +0 -0
  100. /package/src/{view/style/structure-app.css → apps/structure/view/style.css} +0 -0
  101. /package/src/{model/translator-app → apps/translator/model}/const.ts +0 -0
  102. /package/src/{view/style/translator-app.css → apps/translator/view/style.css} +0 -0
@@ -1,19 +1,20 @@
1
1
  /* Do not change these import lines to match external modules in webpack configuration */
2
+ import * as DG from 'datagrok-api/dg';
2
3
  import * as grok from 'datagrok-api/grok';
3
4
  import * as ui from 'datagrok-api/ui';
4
- import * as DG from 'datagrok-api/dg';
5
5
 
6
- import * as rxjs from 'rxjs';
7
- import '../style/structure-app.css';
8
6
  import $ from 'cash-dom';
7
+ import * as rxjs from 'rxjs';
8
+ import './style.css';
9
9
 
10
10
  import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
11
11
 
12
- import {highlightInvalidSubsequence} from '../utils/colored-input/input-painters';
13
- import {getLinkedMolfile, saveSdf} from '../../model/structure-app/oligo-structure';
14
- import {ColoredTextInput} from '../utils/colored-input/colored-text-input';
15
- import {MoleculeImage} from '../utils/molecule-img';
16
- import {StrandData} from '../../model/structure-app/oligo-structure';
12
+ import {ColoredTextInput} from '../../common/view/components/colored-input/colored-text-input';
13
+ import {highlightInvalidSubsequence} from '../../common/view/components/colored-input/input-painters';
14
+ import {MoleculeImage} from '../../common/view/components/molecule-img';
15
+ import {APP_NAME} from '../../common/view/const';
16
+ import {IsolatedAppUIBase} from '../../common/view/isolated-app-ui';
17
+ import {getLinkedMolfile, saveSdf, StrandData} from '../model/oligo-structure';
17
18
 
18
19
  const enum DIRECTION {
19
20
  STRAIGHT = '5′ → 3′',
@@ -21,7 +22,7 @@ const enum DIRECTION {
21
22
  };
22
23
  const STRANDS = ['ss', 'as', 'as2'] as const;
23
24
 
24
- export class StructureLayoutHandler {
25
+ class StructureAppLayout {
25
26
  constructor() {
26
27
  this.onInput = new rxjs.Subject<string>();
27
28
  this.onInvalidInput = new rxjs.Subject<string>();
@@ -98,7 +99,7 @@ export class StructureLayoutHandler {
98
99
  const selected = (idx === 0) ? DIRECTION.STRAIGHT : DIRECTION.INVERSE;
99
100
  return [key, ui.choiceInput(
100
101
  `${key.toUpperCase()} direction`, selected, [DIRECTION.STRAIGHT, DIRECTION.INVERSE]
101
- )]
102
+ )];
102
103
  }
103
104
  )
104
105
  );
@@ -106,8 +107,9 @@ export class StructureLayoutHandler {
106
107
  STRANDS.forEach((strand, idx) => {
107
108
  directionChoiceInput[strand].onChanged(() => {
108
109
  let value = directionChoiceInput[strand].value === DIRECTION.INVERSE;
109
- // warning: the next line is necessary until the legacy notion of direction used in the molfile generation gets fixed
110
- if (idx > 0) { value = !value; }
110
+ // warning: the next line is necessary
111
+ // until the legacy notion of direction used in the molfile generation gets fixed
112
+ if (idx > 0) value = !value;
111
113
  this.directionInversion[strand] = value;
112
114
  this.onInput.next();
113
115
  });
@@ -126,7 +128,7 @@ export class StructureLayoutHandler {
126
128
  const clearBlock = Object.fromEntries(
127
129
  STRANDS.map(
128
130
  (key) => {
129
- const clearIcon = ui.icons.delete(() => { coloredInput[key].inputBase.value = '' });
131
+ const clearIcon = ui.icons.delete(() => { coloredInput[key].inputBase.value = ''; });
130
132
  const clearButton = ui.button(clearIcon, () => {});
131
133
  ui.tooltip.bind(clearButton, `Clear ${key.toUpperCase()}`);
132
134
  return [key, clearIcon];
@@ -163,12 +165,12 @@ export class StructureLayoutHandler {
163
165
 
164
166
  private getStrandData() {
165
167
  return Object.fromEntries(
166
- STRANDS.map((strand, idx) => {
167
- let invert = this.directionInversion[strand];
168
+ STRANDS.map((strand) => {
169
+ const invert = this.directionInversion[strand];
168
170
  return [strand, {
169
171
  strand: this.inputBase[strand].value.replace(/\s*/g, ''),
170
172
  invert: invert
171
- }]
173
+ }];
172
174
  })
173
175
  );
174
176
  }
@@ -192,7 +194,7 @@ export class StructureLayoutHandler {
192
194
  const errStr = errorToConsole(err);
193
195
  console.error(errStr);
194
196
  }
195
- // todo: calculate relative numbers
197
+ // todo: compute relative numbers
196
198
  const canvasWidth = 650;
197
199
  const canvasHeight = 150;
198
200
  const molImgObj = new MoleculeImage(molfile);
@@ -201,3 +203,15 @@ export class StructureLayoutHandler {
201
203
  $(this.moleculeImgDiv).find('canvas').css('float', 'inherit');
202
204
  }
203
205
  }
206
+
207
+ export class OligoStructureUI extends IsolatedAppUIBase {
208
+ constructor() {
209
+ super(APP_NAME.STRUCTURE);
210
+ this.layout = new StructureAppLayout();
211
+ }
212
+ private readonly layout: StructureAppLayout;
213
+
214
+ protected getContent(): Promise<HTMLDivElement> {
215
+ return this.layout.getHtmlDivElement();
216
+ }
217
+ }
@@ -1,17 +1,18 @@
1
- import {DEFAULT_FORMATS, NUCLEOTIDES} from '../const';
1
+ import {DEFAULT_FORMATS, NUCLEOTIDES} from '../../common/model/const';
2
+ import {NUCLEOTIDES_FORMAT} from '../view/const';
2
3
  import {UNKNOWN_SYMBOL} from './const';
3
4
  import {FormatConverter} from './format-converter';
4
- import {codesToHelmDictionary} from '../data-loading-utils/json-loader';
5
- import {MonomerLibWrapper} from '../monomer-lib/lib-wrapper';
5
+ import {CODES_TO_HELM_DICT} from '../../common/model/data-loader/json-loader';
6
+ import {MonomerLibWrapper} from '../../common/model/monomer-lib/lib-wrapper';
6
7
 
7
8
  export function getTranslatedSequences(sequence: string, indexOfFirstInvalidChar: number, sourceFormat: string): {[key: string]: string} {
8
- const supportedFormats = Object.keys(codesToHelmDictionary).concat([DEFAULT_FORMATS.HELM]) as string[];
9
+ const supportedFormats = Object.keys(CODES_TO_HELM_DICT).concat([DEFAULT_FORMATS.HELM]) as string[];
9
10
 
10
11
  if (!sequence || (indexOfFirstInvalidChar !== -1 && sourceFormat !== DEFAULT_FORMATS.HELM))
11
12
  return {};
12
13
 
13
14
  if (!supportedFormats.includes(sourceFormat))
14
- throw new Error(`${sourceFormat} format is not supported by SequenceTranslator`)
15
+ throw new Error(`${sourceFormat} format is not supported by SequenceTranslator`);
15
16
 
16
17
  const outputFormats = supportedFormats.filter((el) => el != sourceFormat)
17
18
  .sort((a, b) => a.localeCompare(b));
@@ -25,8 +26,8 @@ export function getTranslatedSequences(sequence: string, indexOfFirstInvalidChar
25
26
  translation = null;
26
27
  }
27
28
  return [format, translation];
28
- }).filter(([format, translation]) => translation)
29
- )
29
+ }).filter(([_, translation]) => translation)
30
+ );
30
31
  const helm = (sourceFormat === DEFAULT_FORMATS.HELM) ? sequence : result[DEFAULT_FORMATS.HELM];
31
32
  const nucleotides = getNucleotidesSequence(helm, MonomerLibWrapper.getInstance());
32
33
  if (nucleotides)
@@ -47,3 +48,20 @@ export function getNucleotidesSequence(helmString: string, monomerLib: MonomerLi
47
48
  }).map((el) => el ? el : UNKNOWN_SYMBOL).join('');
48
49
  return nucleotides;
49
50
  }
51
+
52
+ // todo: remove after refactoring as a workaround
53
+ export function convert(sequence: string, sourceFormat: string, targetFormat: string): string | null {
54
+ const converter = new FormatConverter(sequence, sourceFormat);
55
+ if (targetFormat === NUCLEOTIDES_FORMAT) {
56
+ const helm = converter.convertTo(DEFAULT_FORMATS.HELM);
57
+ const nucleotides = getNucleotidesSequence(helm, MonomerLibWrapper.getInstance());
58
+ return nucleotides;
59
+ }
60
+
61
+ return converter.convertTo(targetFormat);
62
+ }
63
+
64
+ export function getSupportedTargetFormats(): string[] {
65
+ const supportedTargetFormats = Object.keys(CODES_TO_HELM_DICT).concat([DEFAULT_FORMATS.HELM, NUCLEOTIDES_FORMAT]).sort() as string[];
66
+ return supportedTargetFormats;
67
+ }
@@ -1,7 +1,7 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
- import {DEFAULT_FORMATS} from '../const';
2
+ import {DEFAULT_FORMATS} from '../../common/model/const';
3
3
  import {PHOSPHATE_SYMBOL, UNKNOWN_SYMBOL} from './const';
4
- import {FormatHandler, getRegExpPattern} from '../parsing-validation/format-handler';
4
+ import {FormatHandler, getRegExpPattern} from '../../common/model/parsing-validation/format-handler';
5
5
 
6
6
  const HELM_WRAPPER = {
7
7
  LEFT: 'RNA1{',
@@ -16,21 +16,16 @@ export class FormatConverter {
16
16
  convertTo(targetFormat: string): string {
17
17
  const formats = this.formats.getFormatNames();
18
18
 
19
- if (this.sourceFormat === DEFAULT_FORMATS.HELM && formats.includes(targetFormat))
20
- return this.helmToFormat(this.sequence, targetFormat);
21
- else if (formats.includes(this.sourceFormat) && targetFormat === DEFAULT_FORMATS.HELM)
22
- return this.formatToHelm(this.sequence, this.sourceFormat);
23
- else if ([this.sourceFormat, targetFormat].every((el) => formats.includes(el))) {
19
+ if (this.sourceFormat === DEFAULT_FORMATS.HELM && formats.includes(targetFormat)) { return this.helmToFormat(this.sequence, targetFormat); } else if (formats.includes(this.sourceFormat) && targetFormat === DEFAULT_FORMATS.HELM) { return this.formatToHelm(this.sequence, this.sourceFormat); } else if ([this.sourceFormat, targetFormat].every((el) => formats.includes(el))) {
24
20
  const helm = this.formatToHelm(this.sequence, this.sourceFormat);
25
21
  return this.helmToFormat(helm, targetFormat);
26
- }
27
- else {
28
- throw new Error (`ST: unsupported translation direction ${this.sourceFormat} -> ${targetFormat}`);
22
+ } else {
23
+ throw new Error(`ST: unsupported translation direction ${this.sourceFormat} -> ${targetFormat}`);
29
24
  }
30
25
  }
31
26
 
32
27
  private helmToFormat(helmSequence: string, targetFormat: string): string {
33
- const wrapperRegExp = new RegExp(getRegExpPattern(Object.values(HELM_WRAPPER)), 'g')
28
+ const wrapperRegExp = new RegExp(getRegExpPattern(Object.values(HELM_WRAPPER)), 'g');
34
29
  let result = helmSequence.replace(wrapperRegExp, '');
35
30
 
36
31
  const dict = this.formats.getHelmToFormatDict(targetFormat);
@@ -54,7 +49,7 @@ export class FormatConverter {
54
49
  const phosphateRegExp = this.formats.getPhosphateHelmCodesRegExp(sourceFormat);
55
50
 
56
51
  let helm = sequence.replace(formatRegExp, (match) => {
57
- const result = formatCodes.includes(match) ? dict[match] + '.' : '?';
52
+ const result = formatCodes.includes(match) ? dict[match] + '.' : '?';
58
53
  return result;
59
54
  });
60
55
  helm = helm.replace(/\?+/g, `${UNKNOWN_SYMBOL}.`);
@@ -1,3 +1,5 @@
1
1
  export const DEFAULT_INPUT = 'fAmCmGmAmCpsmU';
2
2
  export const SEQUENCE_COPIED_MSG = 'Copied';
3
3
  export const SEQ_TOOLTIP_MSG = 'Copy sequence';
4
+
5
+ export const NUCLEOTIDES_FORMAT = 'Nucleotides';