nodedb-json
Version:
A lightweight JSON-based database for Node.js with TypeScript support, indexing, and complex query capabilities
127 lines • 4.46 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeIndexDefinitions = mergeIndexDefinitions;
exports.validateIndexDefinition = validateIndexDefinition;
exports.encodeIndexValue = encodeIndexValue;
const lodash_1 = __importDefault(require("lodash"));
function mergeIndexDefinitions(target, source) {
if (!source || typeof source !== 'object') {
return;
}
for (const [key, definitions] of Object.entries(source)) {
if (!target[key]) {
target[key] = {};
}
if (Array.isArray(definitions)) {
definitions.forEach(indexDefinition => {
validateIndexDefinition(indexDefinition);
target[key][indexDefinition.field] = lodash_1.default.cloneDeep(indexDefinition);
});
}
else if (definitions && typeof definitions === 'object') {
for (const [field, indexDefinition] of Object.entries(definitions)) {
validateIndexDefinition(indexDefinition);
const normalizedDefinition = lodash_1.default.cloneDeep(indexDefinition);
normalizedDefinition.field = normalizedDefinition.field || field;
target[key][normalizedDefinition.field] = normalizedDefinition;
}
}
}
}
function validateIndexDefinition(indexDefinition) {
if (!indexDefinition || typeof indexDefinition !== 'object') {
throw new Error('Index definition must be an object.');
}
if (typeof indexDefinition.field !== 'string' || indexDefinition.field.length === 0) {
throw new Error('Index definition field must be a non-empty string.');
}
if (indexDefinition.type !== 'unique' && indexDefinition.type !== 'multi') {
throw new Error('Index definition type must be "unique" or "multi".');
}
}
function encodeIndexValue(value, mode = 'strict') {
var _a;
if (mode === 'coerce') {
return String(value);
}
if (value === null) {
return 'null:';
}
if (value === undefined) {
return 'undefined:';
}
switch (typeof value) {
case 'string':
return `string:${value}`;
case 'number':
return `number:${Object.is(value, -0) ? '-0' : String(value)}`;
case 'boolean':
return `boolean:${value}`;
case 'bigint':
return `bigint:${value.toString()}`;
case 'symbol':
return `symbol:${String((_a = value.description) !== null && _a !== void 0 ? _a : '')}`;
case 'object':
return `json:${stableStringify(value)}`;
default:
return `${typeof value}:${String(value)}`;
}
}
function stableStringify(value) {
return JSON.stringify(normalizeForIndex(value));
}
function normalizeForIndex(value) {
var _a;
if (value === undefined) {
return { type: 'undefined' };
}
if (value === null) {
return { type: 'null' };
}
if (typeof value === 'string') {
return { type: 'string', value };
}
if (typeof value === 'number') {
if (Number.isNaN(value)) {
return { type: 'number', value: 'NaN' };
}
if (value === Infinity) {
return { type: 'number', value: 'Infinity' };
}
if (value === -Infinity) {
return { type: 'number', value: '-Infinity' };
}
if (Object.is(value, -0)) {
return { type: 'number', value: '-0' };
}
return { type: 'number', value };
}
if (typeof value === 'boolean') {
return { type: 'boolean', value };
}
if (typeof value === 'bigint') {
return { type: 'bigint', value: value.toString() };
}
if (typeof value === 'symbol') {
return { type: 'symbol', value: (_a = value.description) !== null && _a !== void 0 ? _a : '' };
}
if (typeof value === 'function') {
return { type: 'function' };
}
if (Array.isArray(value)) {
return {
type: 'array',
value: value.map(item => normalizeForIndex(item))
};
}
return {
type: 'object',
value: Object.keys(value)
.sort()
.map(key => [key, normalizeForIndex(value[key])])
};
}
//# sourceMappingURL=index-codec.js.map