tinycoll
Version:
A minimal reactive document store with Mongo-like querying, reactivity, TTL support, and optional persistence.
58 lines (57 loc) • 2.04 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.matches = matches;
function getValue(obj, path) {
return path.split('.').reduce((o, k) => o?.[k], obj);
}
function matchField(val, cond) {
// { key: undefined } and { key: { $eq: undefined } } are intentional different things
if (cond === undefined)
return true;
if (typeof cond !== 'object' || cond === null)
return val === cond;
return Object.entries(cond).every(([op, expected]) => {
switch (op) {
case '$eq':
return val === expected;
case '$ne':
return val !== expected;
case '$gt':
return val > expected;
case '$gte':
return val >= expected;
case '$lt':
return val < expected;
case '$lte':
return val <= expected;
case '$in':
return Array.isArray(expected) && expected.includes(val);
case '$nin':
return Array.isArray(expected) && !expected.includes(val);
case '$exists':
return expected ? val !== undefined : val === undefined;
case '$regex':
return typeof val === 'string' && new RegExp(expected).test(val);
case '$size':
return Array.isArray(val) && val.length === expected;
default:
return false;
}
});
}
function matches(doc, query) {
return Object.entries(query).every(([key, cond]) => {
switch (key) {
case '$or':
return Array.isArray(cond) && cond.some((q) => matches(doc, q));
case '$and':
return Array.isArray(cond) && cond.every((q) => matches(doc, q));
case '$not':
return !matches(doc, cond);
default: {
const val = getValue(doc, key);
return matchField(val, cond);
}
}
});
}