@frontmeans/doqry
Advanced tools
+5
-718
@@ -0,1 +1,6 @@ | ||
| import { escapeCSS, escapeCSSVal } from '@frontmeans/httongue'; | ||
| import { isQualifiedName, compareNames, newNamespaceAliaser, id__naming, css__naming, html__naming, namesEqual } from '@frontmeans/namespace-aliaser'; | ||
| import { isArrayOfElements, arraysAreEqual } from '@proc7ts/primitives'; | ||
| import { flatMapIt } from '@proc7ts/push-iterator'; | ||
| /** | ||
@@ -12,720 +17,2 @@ * Checks whether the given value is a {@DoqryCombinator CSS selector combinator}. | ||
| /** | ||
| * Decodes URL component. | ||
| * | ||
| * In contrast to standard [decodeURIComponent] function this one decodes `+` signs as spaces. | ||
| * | ||
| * [decodeURIComponent]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent | ||
| * | ||
| * @param url - URL component to decode. | ||
| * | ||
| * @returns Decoded URL component. | ||
| */ | ||
| /** | ||
| * Escapes CSS identifier accordingly to the rules defined for [CSS.escape()](https://drafts.csswg.org/cssom/#the-css.escape%28%29-method) | ||
| * utility method. | ||
| * | ||
| * Can be applied to CSS values as well, although it escapes characters that don't strictly need to be escaped. | ||
| * A {@link escapeCSSVal} is a better alternative for that. | ||
| * | ||
| * @param text - A text to escape. | ||
| * | ||
| * @returns A string safe to be used as CSS identifier, e.g. as CSS selector. | ||
| */ | ||
| function escapeCSS(text) { | ||
| const len = text.length; | ||
| const first = text.charCodeAt(0); | ||
| let out = ''; | ||
| let i = 0; | ||
| if (first === 0x2d) { | ||
| // If the first character is a "-" (U+002D) | ||
| const second = text.charCodeAt(1); | ||
| // ... and the second character is in the range [0-9] (U+0030 to U+0039). | ||
| if (second > 0x2f && second < 0x3a) { | ||
| // then '-' followed by the character escaped as code point. | ||
| out += `-\\${second.toString(16)} `; | ||
| i = 2; | ||
| } | ||
| else { | ||
| out = '-'; | ||
| i = 1; | ||
| } | ||
| if (len === 1) { | ||
| // ... and there is no second character, then the escaped character. | ||
| return '\\-'; | ||
| } | ||
| } | ||
| else if (first > 0x2f && first < 0x3a) { | ||
| // If the first character is in the range [0-9] (U+0030 to U+0039), | ||
| // then the character escaped as code point. | ||
| out += `\\${first.toString(16)} `; | ||
| i = 1; | ||
| } | ||
| for (; i < len; ++i) { | ||
| const c = text.charCodeAt(i); | ||
| if ( | ||
| // Is in range [a-z] (U+0061 to U+007A), | ||
| (c > 0x60 && c < 0x7b) | ||
| // or is "-" (U+002D), | ||
| || c === 0x2d | ||
| // or is "_" (U+005F) | ||
| || c === 0x5f | ||
| // or is in range [0-9] (U+0030 to U+0039), | ||
| || (c > 0x2f && c < 0x3a) | ||
| // or is in range [A-Z] (U+0041 to U+005A) | ||
| || (c > 0x40 && c < 0x5b)) { | ||
| // then the character itself. | ||
| out += text[i]; | ||
| } | ||
| else if (c > 0x7e) { | ||
| out += c === 0x7f | ||
| // If the character is U+007F | ||
| // then the character escaped as code point. | ||
| ? `\\${c.toString(16)} ` | ||
| // If the character is greater than or equal to U+0080, | ||
| // then the character itself | ||
| : text[i]; | ||
| } | ||
| else if (c < 0x20) { | ||
| out += c | ||
| // If the character is in the range [\1-\1f] (U+0001 to U+001F) | ||
| // then the character escaped as code point. | ||
| ? `\\${c.toString(16)} ` | ||
| // If the character is NULL (U+0000) | ||
| // then the REPLACEMENT CHARACTER (U+FFFD). | ||
| : '\uFFFD'; | ||
| } | ||
| else { | ||
| // Otherwise, the escaped character. | ||
| out += `\\${text[i]}`; | ||
| } | ||
| } | ||
| return out; | ||
| } | ||
| /** | ||
| * Escapes CSS value to be included into CSS string. | ||
| * | ||
| * Escapes accordingly to [serialize a string] algorithm. | ||
| * | ||
| * [serialize a string]: https://drafts.csswg.org/cssom/#serialize-a-string | ||
| * | ||
| * @param text - A text to escape. | ||
| * | ||
| * @returns A string safe to be included into CSS value, e.g. within CSS string. | ||
| */ | ||
| function escapeCSSVal(text) { | ||
| let out = ''; | ||
| const len = text.length; | ||
| for (let i = 0; i < len; ++i) { | ||
| const c = text.charCodeAt(i); | ||
| out += c < 0x20 || c === 0x7f | ||
| ? (c | ||
| // If the character is in the range [\1-\1f] (U+0001 to U+001F), | ||
| // the character escaped as code point. | ||
| ? `\\${c.toString(16)} ` | ||
| // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD).; | ||
| : '\uFFFD') | ||
| : (c === 0x22 || c === 0x5c | ||
| // If the character is '"' (U+0022) or "\" (U+005C), | ||
| // the escaped character. | ||
| ? `\\${text[i]}` | ||
| // Otherwise, the character itself. | ||
| : text[i]); | ||
| } | ||
| return out; | ||
| } | ||
| /** | ||
| * Naming schema is responsible for applying namespace aliases to simple names. E.g. by appending alias as prefix or | ||
| * suffix of the name. | ||
| */ | ||
| class Naming { | ||
| /** | ||
| * Converts the given qualified `name` into simple one accordingly to this naming schema. | ||
| * | ||
| * @param name Qualified name to convert. | ||
| * @param nsAlias Namespace aliaser to use. | ||
| */ | ||
| name(name, nsAlias) { | ||
| if (typeof name === 'string') { | ||
| return name; | ||
| } | ||
| const [local, ns] = name; | ||
| return ns.name(nsAlias(ns), local, this); | ||
| } | ||
| } | ||
| class DefaultNaming extends Naming { | ||
| applyAlias(name, alias) { | ||
| return `${alias}-${name}`; | ||
| } | ||
| } | ||
| /** | ||
| * Default naming schema. | ||
| * | ||
| * Prefixes a name with namespace alias separating them by dash. | ||
| * | ||
| * The result looks like `<alias>-<name>`. | ||
| */ | ||
| const default__naming = ( /*#__PURE__*/new DefaultNaming()); | ||
| /** | ||
| * HTML elements naming schema. | ||
| * | ||
| * Prefixes a name with namespace alias separating them by dash. | ||
| * | ||
| * The result looks like `<alias>-<name>`. | ||
| */ | ||
| const html__naming = ( /*#__PURE__*/new DefaultNaming()); | ||
| class XmlNaming extends Naming { | ||
| applyAlias(name, alias) { | ||
| return `${alias}:${name}`; | ||
| } | ||
| } | ||
| /** | ||
| * Element identifiers naming schema. | ||
| * | ||
| * Prefixes a name with namespace alias separating them by colon. | ||
| * | ||
| * The result looks like `<alias>:<name>`. | ||
| */ | ||
| const id__naming = ( /*#__PURE__*/new XmlNaming()); | ||
| class CssNaming extends Naming { | ||
| applyAlias(name, alias) { | ||
| return `${name}@${alias}`; | ||
| } | ||
| } | ||
| /** | ||
| * CSS classes naming scheme. | ||
| * | ||
| * Appends namespace alias as a name suffix separated by `@` sign. | ||
| * | ||
| * The result looks like `<name>@<alias>`. | ||
| */ | ||
| const css__naming = ( /*#__PURE__*/new CssNaming()); | ||
| /** | ||
| * Namespace definition. | ||
| * | ||
| * Namespaces are identified by their URLs. | ||
| */ | ||
| class NamespaceDef { | ||
| /** | ||
| * Constructs new namespace definition. | ||
| * | ||
| * @param url - Unique namespace URL. | ||
| * @param aliases - Preferred namespace aliases. It is expected that each alias is an ASCII letter followed by | ||
| * any number of ASCII letters, digits, `-`, or `_` signs. Aliases starting with `xml` are reserved. Empty alias | ||
| * is reserved for {@link DEFAULT__NS default namespace}. | ||
| */ | ||
| constructor(url, ...aliases) { | ||
| this.url = url; | ||
| this.aliases = aliases; | ||
| } | ||
| /** | ||
| * The most preferred namespace alias. | ||
| * | ||
| * By default this is the first preferred alias, or `ns` if there is no preferred aliases. | ||
| */ | ||
| get alias() { | ||
| return this.aliases[0] || 'ns'; | ||
| } | ||
| /** | ||
| * Converts a local `name` belonging to this namespace to simple one according to the given `naming` schema. | ||
| * | ||
| * Calls {@link Naming.applyAlias} by default. | ||
| * | ||
| * @param alias - Namespace alias to apply to the name. | ||
| * @param name - A name to convert. | ||
| * @param naming - Naming schema to use. {@link default__naming default naming schema} is used when omitted. | ||
| * | ||
| * @returns A simple name with this namespace alias applied. | ||
| */ | ||
| name(alias, name, naming = default__naming) { | ||
| return naming.applyAlias(name, alias, this); | ||
| } | ||
| } | ||
| /** | ||
| * Checks whether the given `value` is a name+namespace tuple. | ||
| * | ||
| * @param value - A value to check. | ||
| * | ||
| * @returns `true` if the given `value` is an array consisting of exactly two elements, where the first element is a | ||
| * non-empty string, and the second element is an instance of {@link NamespaceDef}. Or `false` otherwise. | ||
| */ | ||
| function isNameAndNamespace(value) { | ||
| return Array.isArray(value) | ||
| && value.length === 2 | ||
| && typeof value[0] === 'string' | ||
| && isNamespaceDef(value[1]); | ||
| } | ||
| function isNamespaceDef(value) { | ||
| if (value instanceof NamespaceDef) { | ||
| return true; | ||
| } | ||
| return typeof value === 'object' | ||
| && typeof value.url === 'string' | ||
| && typeof value.alias === 'string' | ||
| && Array.isArray(value.aliases) | ||
| && typeof value.name === 'function'; | ||
| } | ||
| /** | ||
| * Checks whether the given `value` is a qualified name. | ||
| * | ||
| * @param value - A value to check. | ||
| * | ||
| * @returns `true` if the given `value` is a string, or an array consisting of exactly two elements, where the first | ||
| * element is a non-empty string, and the second element is an instance of {@link NamespaceDef}. `false` otherwise. | ||
| */ | ||
| function isQualifiedName(value) { | ||
| return typeof value === 'string' || isNameAndNamespace(value); | ||
| } | ||
| /** | ||
| * Checks whether two qualified names are equal to each other. | ||
| * | ||
| * @param first - First qualified name to compare. | ||
| * @param second - Second qualified name to compare. | ||
| * | ||
| * @returns `true` if both names are equal, or `false` otherwise. | ||
| */ | ||
| function namesEqual(first, second) { | ||
| if (typeof first === 'string') { | ||
| return typeof second === 'string' ? first === second : !second[1].url && second[0] === first; | ||
| } | ||
| const [firstName, { url: firstUrl }] = first; | ||
| if (typeof second === 'string') { | ||
| return !firstUrl && firstName === second; | ||
| } | ||
| return firstName === second[0] && firstUrl === second[1].url; | ||
| } | ||
| /** | ||
| * Compares two qualified names. | ||
| * | ||
| * Names in default namespace considered less than other names. Namespaces are compared by their URLs. | ||
| * | ||
| * @param first - First qualified name to compare. | ||
| * @param second - Second qualified name to compare. | ||
| * | ||
| * @returns `-1` if the `first` name is less than the `second` one, `0` if they are equal, or `1` if the `first` name | ||
| * is greater than the `second` one. | ||
| */ | ||
| function compareNames(first, second) { | ||
| if (typeof first === 'string') { | ||
| if (typeof second === 'string') { | ||
| return compareStrings(first, second); | ||
| } | ||
| if (!second[1].url) { | ||
| return compareStrings(first, second[0]); | ||
| } | ||
| return -1; | ||
| } | ||
| const [firstName, { url: firstUrl }] = first; | ||
| if (typeof second === 'string') { | ||
| if (!firstUrl) { | ||
| return compareStrings(firstName, second); | ||
| } | ||
| return 1; | ||
| } | ||
| return compareStrings(firstUrl, second[1].url) || compareStrings(firstName, second[0]); | ||
| } | ||
| function compareStrings(first, second) { | ||
| return first < second ? -1 : first > second ? 1 : 0; | ||
| } | ||
| /** | ||
| * Creates a namespace aliaser. | ||
| * | ||
| * The returned function tries to find a registered alias for the given namespace. If not found then tries to use one | ||
| * of its preferred aliases. If all of them are reserved already for another namespaces, generates a new unique alias. | ||
| * | ||
| * @returns New instance of namespace aliaser. | ||
| */ | ||
| function newNamespaceAliaser() { | ||
| const aliasesByNs = new Map(); | ||
| const nsNumPerAlias = new Map(); | ||
| return function nsAlias(ns) { | ||
| const found = aliasesByNs.get(ns.url); | ||
| if (found) { | ||
| return found; | ||
| } | ||
| const mostPreferred = ns.alias; | ||
| let nsNumRegistered = 0; | ||
| for (const preferred of [mostPreferred, ...ns.aliases]) { | ||
| const ids = nsNumPerAlias.get(preferred); | ||
| if (!ids) { | ||
| aliasesByNs.set(ns.url, preferred); | ||
| nsNumPerAlias.set(preferred, 1); | ||
| return preferred; | ||
| } | ||
| if (!nsNumRegistered) { | ||
| // Use the first one | ||
| nsNumRegistered = ids; | ||
| } | ||
| } | ||
| const generated = `${mostPreferred}${++nsNumRegistered}`; | ||
| aliasesByNs.set(ns.url, generated); | ||
| nsNumPerAlias.set(mostPreferred, nsNumRegistered); | ||
| return generated; | ||
| }; | ||
| } | ||
| function isArrayOfElements(value) { | ||
| return Array.isArray(value); | ||
| } | ||
| /** | ||
| * Checks whether two values are the same. I.e. strictly equal to each other. | ||
| * | ||
| * @typeParam T - A type of values. | ||
| * @param first - First value to compare. | ||
| * @param second - Second value to compare. | ||
| * | ||
| * @returns `true` if `first === second`, or `false` otherwise. | ||
| */ | ||
| function areTheSame(first, second) { | ||
| return first === second; | ||
| } | ||
| function arraysAreEqual(first, second, compareOrFromOrLength, fromOrLength, to) { | ||
| return typeof compareOrFromOrLength === 'function' | ||
| ? arrayElementsAreEqual(first, second, compareOrFromOrLength, fromOrLength, to) | ||
| : arrayElementsAreEqual(first, second, areTheSame, compareOrFromOrLength, fromOrLength); | ||
| } | ||
| function arrayElementsAreEqual(first, second, elementsAreEqual, fromOrLength, to) { | ||
| let start; | ||
| let end; | ||
| if (to !== undefined) { | ||
| start = fromOrLength ? Math.max(fromOrLength, 0) : 0; | ||
| end = to != null ? to : Math.max(first.length, second.length); | ||
| } | ||
| else if (fromOrLength != null) { | ||
| start = 0; | ||
| end = fromOrLength; | ||
| } | ||
| else { | ||
| start = 0; | ||
| end = Math.max(first.length, second.length); | ||
| } | ||
| if ((first.length <= end || second.length <= end) && first.length !== second.length) { | ||
| return false; | ||
| } | ||
| for (let i = start; i < end; ++i) { | ||
| if (!elementsAreEqual(first[i], second[i], i)) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| /** | ||
| * A key of {@link PushIterable} iteration method. | ||
| */ | ||
| const PushIterator__symbol = ( /*#__PURE__*/Symbol('push-iterator')); | ||
| function isPushIterable(iterable) { | ||
| return !!iterable[PushIterator__symbol]; | ||
| } | ||
| /** | ||
| * Creates a push iterable implementation. | ||
| * | ||
| * @typeParam T - Iterated elements type. | ||
| * @param iterate - A function iterating over iterable elements conforming to {@link PushIterable.Iterate} requirements. | ||
| * | ||
| * @returns New push iterable instance performing iteration by `forNext` function. | ||
| */ | ||
| function makePushIterable(iterate) { | ||
| return { | ||
| [Symbol.iterator]: PushIterable$iterator, | ||
| [PushIterator__symbol]: iterate, | ||
| }; | ||
| } | ||
| function PushIterable$iterator() { | ||
| return this[PushIterator__symbol](); | ||
| } | ||
| function PushIterator$iterator() { | ||
| return this; | ||
| } | ||
| function PushIterator$next() { | ||
| for (;;) { | ||
| let result; | ||
| const tail = this[PushIterator__symbol](value => { | ||
| result = { value }; | ||
| return true; | ||
| }); | ||
| if (result) { | ||
| return result; | ||
| } | ||
| if (tail.isOver()) { | ||
| return { done: true }; | ||
| } | ||
| } | ||
| } | ||
| const PushIterator$empty = { | ||
| [Symbol.iterator]: PushIterator$iterator, | ||
| [PushIterator__symbol](_accept) { | ||
| return this; | ||
| }, | ||
| next: PushIterator$noNext, | ||
| isOver: PushIterator$over, | ||
| }; | ||
| function PushIterator$noNext() { | ||
| return { done: true }; | ||
| } | ||
| function PushIterator$dontIterate(_accept) { | ||
| // Do not iterate | ||
| } | ||
| function PushIterator$over() { | ||
| return true; | ||
| } | ||
| /** | ||
| * Creates a push iterator implementation. | ||
| * | ||
| * @typeParam T - Iterated elements type. | ||
| * @param forNext - A function iterating over elements conforming to push iteration protocol. | ||
| * | ||
| * @returns New push iterator instance performing iteration by `forNext` function. | ||
| */ | ||
| function makePushIterator(forNext) { | ||
| let over = false; | ||
| let iterate = (accept) => { | ||
| if (accept && !forNext(accept)) { | ||
| over = true; | ||
| iterate = PushIterator$dontIterate; | ||
| } | ||
| }; | ||
| return { | ||
| [Symbol.iterator]: PushIterator$iterator, | ||
| [PushIterator__symbol](accept) { | ||
| iterate(accept); | ||
| return this; | ||
| }, | ||
| next: PushIterator$next, | ||
| isOver: () => over, | ||
| }; | ||
| } | ||
| function iterateOverIndexed(indexed, elementOf) { | ||
| return accept => { | ||
| let i = 0; | ||
| const forNext = (accept) => { | ||
| if (i >= indexed.length) { | ||
| return false; | ||
| } | ||
| for (;;) { | ||
| const goOn = accept(elementOf(indexed, i++)); | ||
| if (i >= indexed.length || goOn === false) { | ||
| return false; | ||
| } | ||
| if (goOn === true) { | ||
| return true; | ||
| } | ||
| } | ||
| }; | ||
| if (accept && !forNext(accept)) { | ||
| return PushIterator$empty; | ||
| } | ||
| let over = false; | ||
| let iterate = (accept) => { | ||
| if (accept && !forNext(accept)) { | ||
| over = true; | ||
| iterate = PushIterator$dontIterate; | ||
| // eslint-disable-next-line @typescript-eslint/no-use-before-define | ||
| next = PushIterator$noNext; | ||
| } | ||
| }; | ||
| let next = () => { | ||
| if (i < indexed.length) { | ||
| return { value: elementOf(indexed, i++) }; | ||
| } | ||
| over = true; | ||
| iterate = PushIterator$dontIterate; | ||
| next = PushIterator$noNext; | ||
| return { done: true }; | ||
| }; | ||
| return { | ||
| [Symbol.iterator]: PushIterator$iterator, | ||
| [PushIterator__symbol](accept) { | ||
| iterate(accept); | ||
| return this; | ||
| }, | ||
| next: () => next(), | ||
| isOver: () => over, | ||
| }; | ||
| }; | ||
| } | ||
| function arrayElementOf(array, index) { | ||
| return array[index]; | ||
| } | ||
| function iterateOverArray(array) { | ||
| return iterateOverIndexed(array, arrayElementOf); | ||
| } | ||
| function toPushIterator(it, forNext) { | ||
| let over = false; | ||
| let iterate = (accept) => { | ||
| if ((over = !!accept && !forNext(accept))) { | ||
| iterate = PushIterator$dontIterate; | ||
| // eslint-disable-next-line @typescript-eslint/no-use-before-define | ||
| next = PushIterator$noNext; | ||
| } | ||
| }; | ||
| let next = () => { | ||
| const res = it.next(); | ||
| if (res.done) { | ||
| over = true; | ||
| iterate = PushIterator$dontIterate; | ||
| next = PushIterator$noNext; | ||
| } | ||
| return res; | ||
| }; | ||
| return { | ||
| [Symbol.iterator]: PushIterator$iterator, | ||
| [PushIterator__symbol](accept) { | ||
| iterate(accept); | ||
| return this; | ||
| }, | ||
| next() { | ||
| return next(); | ||
| }, | ||
| isOver: () => over, | ||
| }; | ||
| } | ||
| function rawIteratorPusher(it) { | ||
| return accept => { | ||
| for (;;) { | ||
| const res = it.next(); | ||
| if (res.done) { | ||
| return false; | ||
| } | ||
| const status = accept(res.value); | ||
| if (typeof status === 'boolean') { | ||
| return status; | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| /** | ||
| * Iterates over elements of the given iterable. | ||
| * | ||
| * Calls `accept` method for each iterated element until there are elements to iterate, or `accept` returned either | ||
| * `true` or `false`. | ||
| * | ||
| * @typeParam T - Iterated elements type. | ||
| * @param iterable - An iterable to iterate elements of. | ||
| * @param accept - A function to push iterated elements to. Accepts iterated element as its only parameter. May return | ||
| * `true` to suspend iteration, or `false` to stop it. | ||
| * | ||
| * @returns A push iterator instance representing the tail of the given iterable. This iterator can be used to continue | ||
| * iteration with, unless `accept` returned `false`. In the latter case the further iteration won't be possible. | ||
| */ | ||
| function iterateIt(iterable, accept) { | ||
| if (isPushIterable(iterable)) { | ||
| return iterable[PushIterator__symbol](accept); | ||
| } | ||
| if (Array.isArray(iterable)) { | ||
| return iterateIt$array(iterable, accept); | ||
| } | ||
| return iterateIt$raw(iterable, accept); | ||
| } | ||
| function iterateIt$array(array, accept) { | ||
| return array.length ? iterateOverArray(array)(accept) : PushIterator$empty; | ||
| } | ||
| function iterateIt$raw(iterable, accept) { | ||
| const it = iterable[Symbol.iterator](); | ||
| if (isPushIterable(it)) { | ||
| return it[PushIterator__symbol](accept); | ||
| } | ||
| const forEach = rawIteratorPusher(it); | ||
| return forEach(accept) ? toPushIterator(it, forEach) : PushIterator$empty; | ||
| } | ||
| /** | ||
| * Returns a {@link PushIterator push iterator} without elements. | ||
| * | ||
| * @typeParam T - Iterated elements type. | ||
| * | ||
| * @returns Empty push iterator instance. | ||
| */ | ||
| function overNone() { | ||
| return PushIterator$empty; | ||
| } | ||
| function flatMapIt(source, convert = flatMapIt$defaultConverter) { | ||
| return makePushIterable(accept => { | ||
| const forNext = isPushIterable(source) | ||
| ? flatMap$(source, convert) | ||
| : flatMap$raw(source, convert); | ||
| return accept && !forNext(accept) ? overNone() : makePushIterator(forNext); | ||
| }); | ||
| } | ||
| function flatMap$(source, convert) { | ||
| let subs; | ||
| let lastSrc = false; | ||
| return accept => { | ||
| for (;;) { | ||
| while (!subs) { | ||
| const sourceTail = source[PushIterator__symbol](src => { | ||
| subs = convert(src); | ||
| return true; | ||
| }); | ||
| source = sourceTail; | ||
| if (sourceTail.isOver()) { | ||
| if (!subs) { | ||
| return false; | ||
| } | ||
| lastSrc = true; | ||
| } | ||
| } | ||
| let status; | ||
| const subsTail = iterateIt(subs, element => status = accept(element)); | ||
| if (subsTail.isOver()) { | ||
| subs = undefined; | ||
| if (lastSrc) { | ||
| return false; | ||
| } | ||
| } | ||
| else { | ||
| subs = subsTail; | ||
| } | ||
| if (typeof status === 'boolean') { | ||
| return status; | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| function flatMap$raw(source, convert) { | ||
| const it = source[Symbol.iterator](); | ||
| if (isPushIterable(it)) { | ||
| return flatMap$(it, convert); | ||
| } | ||
| let subs; | ||
| return accept => { | ||
| for (;;) { | ||
| if (!subs) { | ||
| const next = it.next(); | ||
| if (next.done) { | ||
| return false; | ||
| } | ||
| subs = convert(next.value); | ||
| } | ||
| // eslint-disable-next-line @typescript-eslint/no-invalid-void-type | ||
| let status; | ||
| const subsTail = iterateIt(subs, element => status = accept(element)); | ||
| subs = subsTail.isOver() ? undefined : subsTail; | ||
| if (typeof status === 'boolean') { | ||
| return status; | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| function flatMapIt$defaultConverter(element) { | ||
| return element; | ||
| } | ||
| const DoqryPicker__symbol = ( /*#__PURE__*/Symbol('DoqryPicker')); | ||
@@ -732,0 +19,0 @@ class DoqryPicker$Mutable extends Array { |
+5
-4
| { | ||
| "name": "@frontmeans/doqry", | ||
| "version": "1.0.1", | ||
| "version": "1.0.2", | ||
| "description": "Document query notation for CSS selectors", | ||
@@ -26,8 +26,9 @@ "keywords": [ | ||
| "@proc7ts/primitives": "^3.0.2", | ||
| "@proc7ts/push-iterator": "^3.0.0" | ||
| "@proc7ts/push-iterator": "^3.1.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@jest/globals": "^27.0.6", | ||
| "@rollup/plugin-node-resolve": "^13.0.0", | ||
| "@rollup/plugin-node-resolve": "^13.0.2", | ||
| "@run-z/eslint-config": "^1.3.0", | ||
| "@run-z/rollup-helpers": "^1.1.1", | ||
| "@typescript-eslint/eslint-plugin": "^4.28.3", | ||
@@ -47,3 +48,3 @@ "@typescript-eslint/parser": "^4.28.3", | ||
| "rollup-plugin-typescript2": "^0.30.0", | ||
| "run-z": "^1.9.1", | ||
| "run-z": "^1.9.2", | ||
| "shx": "^0.3.3", | ||
@@ -50,0 +51,0 @@ "ts-jest": "^27.0.3", |
| import nodeResolve from '@rollup/plugin-node-resolve'; | ||
| import { externalModules } from '@run-z/rollup-helpers'; | ||
| import { defineConfig } from 'rollup'; | ||
@@ -21,2 +22,3 @@ import flatDts from 'rollup-plugin-flat-dts'; | ||
| ], | ||
| external: externalModules(), | ||
| output: { | ||
@@ -23,0 +25,0 @@ dir: '.', |
Sorry, the diff of this file is too big to display
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
7
-63.16%69974
-52.22%24
4.35%826
-45.55%