cspell-trie-lib
Advanced tools
Comparing version 4.1.1 to 4.1.2
@@ -0,6 +1,7 @@ | ||
import { Sequence } from 'gensequence'; | ||
import { TrieNode } from './TrieNode'; | ||
import { Sequence } from 'gensequence'; | ||
export interface ExportOptions { | ||
base?: number; | ||
comment?: string; | ||
version?: number; | ||
} | ||
@@ -14,2 +15,2 @@ /** | ||
export declare function serializeTrie(root: TrieNode, options?: ExportOptions | number): Sequence<string>; | ||
export declare function importTrie(linesX: Iterable<string> | IterableIterator<string>): TrieNode; | ||
export declare function importTrie(lines: Iterable<string> | IterableIterator<string>): TrieNode; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const TrieNode_1 = require("./TrieNode"); | ||
const trieRef_1 = require("./trieRef"); | ||
const gensequence_1 = require("gensequence"); | ||
function leaves(node) { | ||
function* walk(node, k, p) { | ||
if (!node.c) { | ||
yield { n: node, p, k }; | ||
} | ||
else { | ||
for (const n of node.c) { | ||
yield* walk(n[1], n[0], node); | ||
} | ||
} | ||
} | ||
return gensequence_1.genSequence(walk(node, '')); | ||
} | ||
function flattenToReferences(node) { | ||
function* walk() { | ||
let iterations = 100; | ||
let processed = 0; | ||
let index = 0; | ||
function signature(node) { | ||
const flags = node.f ? '*' : ''; | ||
const refs = node.r ? '{' + [...node.r].sort((a, b) => a[0] < b[0] ? -1 : 1).map(a => a.join(':')).join(',') + '}' : ''; | ||
return flags + refs; | ||
} | ||
do { | ||
processed = 0; | ||
let signatureMap = new Map(); | ||
for (const leaf of leaves(node)) { | ||
const h = signature(leaf.n); | ||
let m = signatureMap.get(h); | ||
if (m === undefined) { | ||
// first time, add it to hash | ||
yield leaf.n; | ||
m = index; | ||
signatureMap.set(h, m); | ||
index += 1; | ||
} | ||
// Fix up the parent | ||
/* istanbul ignore else */ | ||
if (leaf.p && leaf.p.c) { | ||
leaf.p.r = leaf.p.r || new trieRef_1.RefMap(); | ||
leaf.p.r.set(leaf.k, m); | ||
leaf.p.c.delete(leaf.k); | ||
if (!leaf.p.c.size) { | ||
delete leaf.p.c; | ||
} | ||
} | ||
processed += 1; | ||
} | ||
iterations -= 1; | ||
} while (processed && iterations && node.c); | ||
yield node; | ||
} | ||
return gensequence_1.genSequence(walk()); | ||
} | ||
const regExpEscapeChars = /([\[\]\\,:{}*])/; | ||
const regExTrailingComma = /,(\}|\n)/g; | ||
function escapeChar(char) { | ||
return char.replace(regExpEscapeChars, '\\$1'); | ||
} | ||
function trieToExportString(node, base) { | ||
function* walk(node) { | ||
if (node.f) { | ||
yield '*'; | ||
} | ||
if (node.r) { | ||
const refs = [...node.r].sort((a, b) => a[0] < b[0] ? -1 : 1); | ||
for (const n of refs) { | ||
const [c, r] = n; | ||
const ref = r ? r.toString(base) : ''; | ||
yield escapeChar(c) + ref + ','; | ||
} | ||
} | ||
} | ||
return gensequence_1.genSequence(walk(node)); | ||
} | ||
function generateHeader(base, comment) { | ||
const header = [ | ||
'#!/usr/bin/env cspell-trie reader', | ||
'TrieXv1', | ||
'base=' + base, | ||
] | ||
.concat(comment | ||
? comment.split('\n').map(a => '# ' + a) | ||
: []) | ||
.concat([ | ||
'# Data:' | ||
]); | ||
return gensequence_1.genSequence(header) | ||
.map(a => a + '\n'); | ||
} | ||
const iv1 = require("./importExportV1"); | ||
const iv2 = require("./importExportV2"); | ||
const iv3 = require("./importExportV3"); | ||
const serializers = [ | ||
iv1.serializeTrie, | ||
iv1.serializeTrie, | ||
iv2.serializeTrie, | ||
iv3.serializeTrie, | ||
]; | ||
const deserializers = [ | ||
iv1.importTrie, | ||
iv1.importTrie, | ||
iv2.importTrie, | ||
iv3.importTrie, | ||
]; | ||
/** | ||
@@ -103,32 +26,23 @@ * Serialize a TrieNode. | ||
function serializeTrie(root, options = 16) { | ||
options = typeof options === 'number' ? { base: options } : options; | ||
const { base = 16, comment = '' } = options; | ||
const radix = base > 36 ? 36 : base < 10 ? 10 : base; | ||
const rows = flattenToReferences(root) | ||
.map(node => { | ||
const row = [ | ||
...trieToExportString(node, radix), | ||
'\n', | ||
] | ||
.join('').replace(regExTrailingComma, '$1'); | ||
return row; | ||
}); | ||
return generateHeader(radix, comment) | ||
.concat(rows); | ||
const version = typeof options !== 'number' && options.version ? options.version : 0; | ||
const method = serializers[version]; | ||
if (!method) { | ||
throw new Error(`Unknown version: ${version}`); | ||
} | ||
return method(root, options); | ||
} | ||
exports.serializeTrie = serializeTrie; | ||
function* toIterableIterator(iter) { | ||
yield* iter; | ||
} | ||
function importTrie(linesX) { | ||
let radix = 16; | ||
function importTrie(lines) { | ||
const comment = /^\s*#/; | ||
const iter = toIterableIterator(linesX); | ||
function* arrayToIterableIterator(i) { | ||
yield* i; | ||
} | ||
function parseHeaderRows(headerRows) { | ||
const header = headerRows.slice(0, 2).join('\n'); | ||
const headerReg = /^TrieXv1\nbase=(\d+)$/; | ||
const header = headerRows.join('\n'); | ||
const headerReg = /\bTrieXv(\d+)/; | ||
/* istanbul ignore if */ | ||
if (!headerReg.test(header)) | ||
const match = header.match(headerReg); | ||
if (!match) | ||
throw new Error('Unknown file format'); | ||
radix = Number.parseInt(header.replace(headerReg, '$1'), 10); | ||
return parseInt(match[1], 10); | ||
} | ||
@@ -146,47 +60,20 @@ function readHeader(iter) { | ||
} | ||
if (line === '*') { | ||
headerRows.push(line); | ||
if (line === iv1.DATA || line === iv2.DATA) { | ||
break; | ||
} | ||
headerRows.push(line); | ||
} | ||
parseHeaderRows(headerRows); | ||
return headerRows; | ||
} | ||
const regNotEscapedCommas = /(^|[^\\]),/g; | ||
const regUnescapeCommas = /__COMMA__/g; | ||
const regUnescape = /[\\](.)/g; | ||
const flagsWord = { f: TrieNode_1.FLAG_WORD }; | ||
function splitLine(line) { | ||
const pattern = '$1__COMMA__'; | ||
return line | ||
.replace(regNotEscapedCommas, pattern) | ||
.split(regUnescapeCommas) | ||
.map(a => a.replace(regUnescape, '$1')); | ||
const input = arrayToIterableIterator(lines); | ||
const headerLines = readHeader(input); | ||
const version = parseHeaderRows(headerLines); | ||
const stream = gensequence_1.genSequence(headerLines).concat(input); | ||
const method = deserializers[version]; | ||
if (!method) { | ||
throw new Error(`Unsupported version: ${version}`); | ||
} | ||
function decodeLine(line, nodes) { | ||
const isWord = line[0] === '*'; | ||
line = isWord ? line.slice(1) : line; | ||
const flags = isWord ? flagsWord : {}; | ||
const children = splitLine(line) | ||
.filter(a => !!a) | ||
.map(a => [ | ||
a[0], | ||
Number.parseInt((a.slice(1) || '0'), radix), | ||
]) | ||
.map(([k, i]) => [k, nodes[i]]); | ||
const cNode = children.length ? { c: new TrieNode_1.ChildMap(children) } : {}; | ||
return Object.assign(Object.assign({}, cNode), flags); | ||
} | ||
readHeader(iter); | ||
const n = gensequence_1.genSequence(['*']).concat(iter) | ||
.map(a => a.replace(/\r?\n/, '')) | ||
.filter(a => !!a) | ||
.reduce((acc, line) => { | ||
const { lines, nodes } = acc; | ||
const root = decodeLine(line, nodes); | ||
nodes[lines] = root; | ||
return { lines: lines + 1, root, nodes }; | ||
}, { lines: 0, nodes: [], root: {} }); | ||
return n.root; | ||
return method(stream); | ||
} | ||
exports.importTrie = importTrie; | ||
//# sourceMappingURL=importExport.js.map |
@@ -6,2 +6,4 @@ export * from './trie'; | ||
export * from './importExport'; | ||
export * from './TrieBuilder'; | ||
export * from './consolidate'; | ||
export { SuggestionResult, MaxCost, suggestionCollector, SuggestionCollector, CompoundWordsMethod } from './suggest'; |
@@ -11,2 +11,4 @@ "use strict"; | ||
__export(require("./importExport")); | ||
__export(require("./TrieBuilder")); | ||
__export(require("./consolidate")); | ||
var suggest_1 = require("./suggest"); | ||
@@ -13,0 +15,0 @@ exports.suggestionCollector = suggest_1.suggestionCollector; |
@@ -12,3 +12,5 @@ "use strict"; | ||
// The root can be a word | ||
root.f = root.f ? (root.f & ~TrieNode_1.FLAG_WORD) : root.f; | ||
if (root.f) { | ||
root.f = root.f ? (root.f & ~TrieNode_1.FLAG_WORD) : root.f; | ||
} | ||
} | ||
@@ -15,0 +17,0 @@ find(text, minCompoundLength = false) { |
@@ -1,6 +0,5 @@ | ||
import { TrieNode } from './TrieNode'; | ||
export declare class RefMap extends Map<string, number> { | ||
export declare type RefList = [string, number][]; | ||
export interface TrieRefNode { | ||
f?: number; | ||
r?: RefList; | ||
} | ||
export interface TrieRefNode extends TrieNode { | ||
r?: RefMap; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
class RefMap extends Map { | ||
} | ||
exports.RefMap = RefMap; | ||
//# sourceMappingURL=trieRef.js.map |
{ | ||
"name": "cspell-trie-lib", | ||
"version": "4.1.1", | ||
"version": "4.1.2", | ||
"description": "Trie Data Structure to support cspell.", | ||
@@ -36,3 +36,3 @@ "main": "dist/index.js", | ||
"dependencies": { | ||
"gensequence": "^2.1.3", | ||
"gensequence": "^3.0.1", | ||
"js-xxhash": "^1.0.4" | ||
@@ -61,3 +61,3 @@ }, | ||
}, | ||
"gitHead": "c528fdc4f86777aefbc23a18c3ac7a51c0c9d2bd" | ||
"gitHead": "f0658565489fa4a2fd38e2f31820ce9fbbe9bfba" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
71327
40
1891
+ Addedgensequence@3.1.1(transitive)
- Removedgensequence@2.3.0(transitive)
Updatedgensequence@^3.0.1