All files snapshot.ts

100% Statements 39/39
100% Branches 14/14
100% Functions 15/15
100% Lines 33/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96      24x               119x   262x 78x                   18x   18x 79x 29x 21x   20x 20x 19x   1x       18x 18x 19x     18x     3x 31x 24x 24x 24x 24x 24x   24x               8x       4x       12x       4x       3x       9x       5x       4x        
import type { DecorationKind, DecorationRecord, RegistryMetadataSnapshot } from './types';
 
function cloneRecords(records: readonly DecorationRecord[]): readonly DecorationRecord[] {
  return Object.freeze(records.slice());
}
 
function filterRecords(
  records: readonly DecorationRecord[],
  kind: DecorationKind,
  decorator?: string,
): readonly DecorationRecord[] {
  return Object.freeze(
    records.filter((record) => {
      if (record.kind !== kind) return false;
      return decorator === undefined || record.decorator === decorator;
    }),
  );
}
 
function memberMap(
  records: readonly DecorationRecord[],
  kind: 'property' | 'method' | 'accessor',
  decorator?: string,
): ReadonlyMap<string | symbol, readonly DecorationRecord[]> {
  const mutable = new Map<string | symbol, DecorationRecord[]>();
 
  for (const record of records) {
    if (record.kind !== kind) continue;
    if (decorator !== undefined && record.decorator !== decorator) continue;
    if (record.memberName === undefined) continue;
 
    const existing = mutable.get(record.memberName);
    if (existing === undefined) {
      mutable.set(record.memberName, [record]);
    } else {
      existing.push(record);
    }
  }
 
  const frozen = new Map<string | symbol, readonly DecorationRecord[]>();
  for (const [key, value] of mutable.entries()) {
    frozen.set(key, Object.freeze(value.slice()));
  }
 
  return frozen;
}
 
export function createSnapshot(records: readonly DecorationRecord[]): RegistryMetadataSnapshot {
  const sorted = records.slice().sort((left, right) => left.order - right.order);
  const all = cloneRecords(sorted);
  const classes = filterRecords(all, 'class');
  const properties = filterRecords(all, 'property');
  const methods = filterRecords(all, 'method');
  const accessors = filterRecords(all, 'accessor');
 
  return Object.freeze({
    all,
    classes,
    properties,
    methods,
    accessors,
 
    firstClass(decorator: string) {
      return classes.find((record) => record.decorator === decorator);
    },
 
    classRecords(decorator?: string) {
      return filterRecords(all, 'class', decorator);
    },
 
    propertyRecords(decorator?: string) {
      return filterRecords(all, 'property', decorator);
    },
 
    methodRecords(decorator?: string) {
      return filterRecords(all, 'method', decorator);
    },
 
    accessorRecords(decorator?: string) {
      return filterRecords(all, 'accessor', decorator);
    },
 
    propertyMap(decorator?: string) {
      return memberMap(all, 'property', decorator);
    },
 
    methodMap(decorator?: string) {
      return memberMap(all, 'method', decorator);
    },
 
    accessorMap(decorator?: string) {
      return memberMap(all, 'accessor', decorator);
    },
  });
}