UNPKG

cspell

Version:

A Spelling Checker for Code!

127 lines 3.52 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ const compare = Intl.Collator().compare; export class ShallowObjectCollection { tree = {}; get(v) { if (typeof v !== 'object' || v === null) { return v; } const keys = Object.entries(v) .filter((entry) => entry[1] !== undefined) .sort((a, b) => compare(a[0], b[0])); let t = this.tree; for (const [key, obj] of keys) { if (!t.c) { t.c = new Map(); } const c0 = t.c.get(key); const cc = c0 || new Map(); if (!c0) { t.c.set(key, cc); } const c1 = cc.get(obj); const ccc = c1 || {}; if (!c1) { cc.set(obj, ccc); } t = ccc; } if (t.v) return t.v; t.v = v; return v; } } export class Collection { col = { contains: new Map() }; /** * Add a plain object to the collection. * The actual object used is returned. * By adding the object to the collection, it is now owned by the collection. * Do not add class objects. * @param v any object or primitive * @returns v or the matching object. */ add(v) { return addToCollection(this.col, v); } } // const objectLike: TypeMask = { // array: true, // object: true, // }; function addToCollection(root, v) { const known = root.contains; function addValToCol(c, v) { const t = toValueType(v); const val = c.v || Object.create(null); const r = val[t] ?? v; val[t] = r; c.v = val; return val[t]; } function walk(col, path) { path = path.filter((entry) => entry[1] !== undefined).sort((a, b) => compare(a[0], b[0])); for (const [k, v] of path) { const c = col.c || Object.create(null); col.c = c; const m = c[k] || new Map(); c[k] = m; const has = m.get(v); col = has || Object.create(null); if (!has) { m.set(v, col); } } return col; } function normalizeObjectEntries(entries) { for (const entry of entries) { entry[1] = add(entry[1]); } return entries; } function normalizeToPath(v) { if (typeof v !== 'object' || !v) { return [['', v]]; } const entries = normalizeObjectEntries(Object.entries(v)); const obj = v; if (!Object.isFrozen(v)) { for (const [k, v] of entries) { obj[k] = v; } Object.freeze(obj); } return entries; } function add(v) { const isObjectLike = typeof v === 'object' && !!v; if (isObjectLike) { const cached = known.get(v); if (cached !== undefined) { return cached; } known.set(v, v); } const path = normalizeToPath(v); const c = walk(root, path); const r = addValToCol(c, v); if (isObjectLike) { known.set(v, r); } return r; } return add(v); } function toValueType(v) { const t = typeof v; if (t !== 'object') return t; if (Array.isArray(v)) return 'array'; if (v === null) return 'null'; return t; } //# sourceMappingURL=ObjectCollection.js.map