node-darts
Version:
Node.js Native Addon for Darts (Double-ARray Trie System)
159 lines • 6.07 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const native_1 = require("./native");
const dictionary_1 = __importDefault(require("./dictionary"));
const errors_1 = require("./errors");
/**
* Darts Dictionary Builder class
* A class for building Double-Array Trie
*/
class Builder {
constructor() {
// Add a private field to reference 'this' in methods
this.name = 'Builder';
}
/**
* Builds a Double-Array from keys and values
* @param keys array of keys (preferably sorted in dictionary order)
* @param values array of values (indices are used if omitted)
* @param options build options
* @returns the constructed Dictionary object
* @throws {BuildError} if the build fails
*/
build(inputKeys, inputValues, options) {
// Use this to reference the class instance (to satisfy ESLint rule)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const builderName = this.name;
Builder.validateInput(inputKeys, inputValues);
// Create local variables to avoid modifying function parameters
let keys = inputKeys;
let values = inputValues;
// Sort keys
if (!Builder.isSorted(keys)) {
const sortedKeys = [...keys];
const sortedValues = values ? [...values] : undefined;
// Sort key-value pairs
const pairs = sortedKeys.map((key, index) => ({
key,
value: sortedValues ? sortedValues[index] : index,
}));
pairs.sort((a, b) => a.key.localeCompare(b.key));
// Get keys and values after sorting
for (let i = 0; i < pairs.length; i += 1) {
sortedKeys[i] = pairs[i].key;
if (sortedValues) {
sortedValues[i] = pairs[i].value;
}
}
keys = sortedKeys;
values = sortedValues;
}
// If there is a progress callback, use a dummy implementation (progress callback is not supported in the current native implementation)
if (options?.progressCallback) {
const total = keys.length;
let current = 0;
const interval = setInterval(() => {
current = Math.min(current + Math.floor(total / 10), total);
options.progressCallback(current, total);
if (current >= total) {
clearInterval(interval);
}
}, 100);
}
try {
const handle = native_1.dartsNative.build(keys, values);
return new dictionary_1.default(handle, keys);
}
catch (error) {
if (error instanceof errors_1.BuildError) {
throw error;
}
throw new errors_1.BuildError(error instanceof Error ? error.message : String(error));
}
}
/**
* Builds a Double-Array from keys and values, and saves it to a file asynchronously
* @param keys array of keys (preferably sorted in dictionary order)
* @param filePath destination file path
* @param values array of values (indices are used if omitted)
* @param options build options
* @returns true if successful, false otherwise
* @throws {BuildError} if the build fails
*/
async buildAndSave(keys, filePath, values, options) {
return new Promise((resolve, reject) => {
try {
const result = this.buildAndSaveSync(keys, filePath, values, options);
resolve(result);
}
catch (error) {
reject(error);
}
});
}
/**
* Builds a Double-Array from keys and values, and saves it to a file synchronously
* @param keys array of keys (preferably sorted in dictionary order)
* @param filePath destination file path
* @param values array of values (indices are used if omitted)
* @param options build options
* @returns true if successful, false otherwise
* @throws {BuildError} if the build fails
*/
buildAndSaveSync(keys, filePath, values, options) {
const dictionary = this.build(keys, values, options);
try {
const result = native_1.dartsNative.saveDictionary(dictionary.getHandle(), filePath);
return result;
}
finally {
dictionary.dispose();
}
}
/**
* Validates the input values
* @param keys array of keys
* @param values array of values
* @throws {BuildError} if the input values are invalid
*/
static validateInput(keys, values) {
if (!Array.isArray(keys) || keys.length === 0) {
throw new errors_1.BuildError('Empty keys array');
}
// Ensure keys are strings
keys.forEach((key) => {
if (typeof key !== 'string') {
throw new errors_1.BuildError('All keys must be strings');
}
});
// Ensure values are numbers
if (values !== undefined) {
if (!Array.isArray(values) || values.length !== keys.length) {
throw new errors_1.BuildError('Values array length must match keys array length');
}
values.forEach((value) => {
if (typeof value !== 'number') {
throw new errors_1.BuildError('All values must be numbers');
}
});
}
}
/**
* Checks if an array is sorted
* @param arr array to check
* @returns true if sorted, false otherwise
*/
static isSorted(arr) {
for (let i = 1; i < arr.length; i += 1) {
if (arr[i - 1].localeCompare(arr[i]) > 0) {
return false;
}
}
return true;
}
}
exports.default = Builder;
//# sourceMappingURL=builder.js.map