UNPKG

@struktoai/mirage-core

Version:

A Unified Virtual Filesystem For AI Agents

150 lines • 4.87 kB
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ========= Copyright 2026 @ Strukto.AI All Rights Reserved. ========= import { BsonTypeTag, PRIMARY_KEY } from "./types.js"; import { isPlainObject } from "../../utils/records.js"; import { compareCodePoints } from "../../utils/sort.js"; function bump(counts, path, tag) { let inner = counts.get(path); if (inner === undefined) { inner = new Map(); counts.set(path, inner); } inner.set(tag, (inner.get(tag) ?? 0) + 1); } function isObjectIdLike(v) { if (typeof v !== 'object' || v === null) return false; const proto = v._bsontype; return proto === 'ObjectId' || proto === 'ObjectID'; } function isDecimalLike(v) { if (typeof v !== 'object' || v === null) return false; return v._bsontype === 'Decimal128'; } function isBinaryLike(v) { if (typeof v !== 'object' || v === null) return false; return v._bsontype === 'Binary'; } function isLongLike(v) { if (typeof v !== 'object' || v === null) return false; return v._bsontype === 'Long'; } function isTimestampLike(v) { if (typeof v !== 'object' || v === null) return false; return v._bsontype === 'Timestamp'; } function isRegexLike(v) { if (v instanceof RegExp) return true; if (typeof v !== 'object' || v === null) return false; return v._bsontype === 'BSONRegExp'; } function isDBRefLike(v) { if (typeof v !== 'object' || v === null) return false; return v._bsontype === 'DBRef'; } function scalarTag(v) { if (typeof v === 'boolean') return BsonTypeTag.BOOL; if (isLongLike(v)) return BsonTypeTag.LONG; if (typeof v === 'number') return Number.isInteger(v) ? BsonTypeTag.INT : BsonTypeTag.DOUBLE; if (typeof v === 'string') return BsonTypeTag.STRING; if (isObjectIdLike(v)) return BsonTypeTag.OBJECT_ID; if (isDecimalLike(v)) return BsonTypeTag.DECIMAL; if (v instanceof Date) return BsonTypeTag.DATE; if (isTimestampLike(v)) return BsonTypeTag.TIMESTAMP; if (isBinaryLike(v)) return BsonTypeTag.BINARY; if (isRegexLike(v)) return BsonTypeTag.REGEX; if (isDBRefLike(v)) return BsonTypeTag.OBJECT; if (v === null) return BsonTypeTag.NULL; return BsonTypeTag.UNKNOWN; } function arrayTag(items) { if (items.length === 0) return BsonTypeTag.ARRAY; if (items.every((x) => typeof x === 'number' && Number.isFinite(x))) { return `array<${BsonTypeTag.DOUBLE}>(${String(items.length)})`; } if (items.every((x) => typeof x === 'string')) { return `array<${BsonTypeTag.STRING}>`; } return BsonTypeTag.ARRAY; } function walk(value, prefix, counts) { if (isPlainObject(value)) { if (prefix !== '') bump(counts, prefix, BsonTypeTag.OBJECT); for (const [k, v] of Object.entries(value)) { const next = prefix === '' ? k : `${prefix}.${k}`; walk(v, next, counts); } return; } if (Array.isArray(value)) { if (prefix !== '') bump(counts, prefix, arrayTag(value)); return; } if (prefix !== '') bump(counts, prefix, scalarTag(value)); } export async function sampleFieldTypes(accessor, database, collection, sampleSize = 100) { const counts = new Map(); let total = 0; for await (const doc of accessor.driver.iterDocuments(database, collection, { batchSize: sampleSize, sort: { _id: 1 }, })) { total++; walk(doc, '', counts); if (total >= sampleSize) break; } if (total === 0) return []; const fields = []; for (const path of [...counts.keys()].sort(compareCodePoints)) { if (path === PRIMARY_KEY) continue; const inner = counts.get(path) ?? new Map(); const presenceCount = [...inner.values()].reduce((a, b) => a + b, 0); const types = {}; for (const [t, c] of inner) types[t] = c / total; fields.push({ path, presence: presenceCount / total, types, }); } return fields; } //# sourceMappingURL=_sampler.js.map