sdf-parser
Version:
56 lines • 2.09 kB
JavaScript
import { parseString } from 'dynamic-typing';
import { MolfileStream } from "./MolfileStream.js";
/**
* Asynchronously iterate over molecules from a text-decoded SDF stream.
* @param readStream - A `ReadableStream<string>` supplying SDF text content.
* @param options - Iterator options.
* @yields {IteratorMolecule} Individual molecule objects.
* @example
* ```ts
* import { openAsBlob } from 'node:fs';
* import { iterator } from 'sdf-parser';
*
* const blob = await openAsBlob('compounds.sdf');
* const textDecoder = new TextDecoderStream();
* for await (const molecule of iterator(blob.stream().pipeThrough(textDecoder))) {
* console.log(molecule.molfile);
* }
* ```
*/
export async function* iterator(readStream, options = {}) {
const { eol = '\n', mixedEOL, dynamicTyping = true } = options;
const moleculeStream = readStream.pipeThrough(new MolfileStream({ mixedEOL }));
const effectiveEol = mixedEOL !== false ? '\n' : eol;
for await (const entry of moleculeStream) {
const molecule = parseMolecule(entry, { eol: effectiveEol, dynamicTyping });
if (!options.filter || options.filter(molecule)) {
yield molecule;
}
}
}
function parseMolecule(sdfPart, options) {
const { eol, dynamicTyping } = options;
const parts = sdfPart.split(`${eol}>`);
const molecule = {
molfile: parts.length > 0 && parts[0].length > 5 ? parts[0] + eol : '',
};
for (let j = 1; j < parts.length; j++) {
const lines = parts[j].split(eol);
const from = lines[0].indexOf('<');
const to = lines[0].indexOf('>');
const label = lines[0].slice(from + 1, to);
for (let k = 1; k < lines.length - 1; k++) {
if (molecule[label]) {
molecule[label] = `${molecule[label]}${eol}${lines[k]}`;
}
else {
molecule[label] = lines[k];
}
}
if (dynamicTyping) {
molecule[label] = parseString(molecule[label]);
}
}
return molecule;
}
//# sourceMappingURL=iterator.js.map