npm.io
3.9.1 • Published 5h ago

@ifc-lite/parser

Licence
MPL-2.0
Version
3.9.1
Deps
5
Size
4.8 MB
Vulns
0
Weekly
0
Stars
276

@ifc-lite/parser

High-performance IFC parser. Tokenizes STEP files at high throughput, builds columnar TypedArray storage, and ships full type-safe coverage of all 776 IFC4 entities. IFC2X3, IFC4, and IFC4X3 files are detected and parsed at runtime; IFC5 (IFCX) files are handled via parseAuto.

Installation

npm install @ifc-lite/parser

Parse a file

import { IfcParser } from '@ifc-lite/parser';

const parser = new IfcParser();
const buffer = await fetch('model.ifc').then(r => r.arrayBuffer());

const t0 = performance.now();
const store = await parser.parseColumnar(buffer, {
  onProgress: ({ phase, percent }) => console.log(`${phase}: ${percent.toFixed(1)}%`),
});

console.log(`Parsed ${store.entityCount} entities in ${(performance.now() - t0).toFixed(0)}ms`);

parseColumnar() is the canonical STEP parser. It uses TypedArray-backed storage, shared scan selection, and on-demand extraction for properties, quantities, materials, classifications, documents, and attributes.

const store = await parser.parseColumnar(buffer);

// store.entities    - typed access by expressId
// store.properties  - flattened pset table
// store.quantities  - flattened qset table
// store.spatialHierarchy.byStorey  - Map<storeyId, elementIds[]>
console.log(`${store.entityCount} entities, schema ${store.schemaVersion}`);

To handle IFC5 (IFCX) files with the same entry point, use parseAuto:

import { parseAuto } from '@ifc-lite/parser';

const result = await parseAuto(buffer);
// result.format is 'ifc' (STEP -> IfcDataStore) or 'ifcx' (JSON -> IfcxParseResult + meshes)

Type-safe entity access

All 776 IFC4 entities ship as TypeScript types via the generated schema.

import type { IfcWall, IfcDoor, IfcSlab } from '@ifc-lite/parser';
import { isKnownEntity, getEntityMetadata } from '@ifc-lite/parser';

// Schema metadata
const meta = getEntityMetadata('IfcWall');
console.log(meta.parent);              // 'IfcBuildingElement'
console.log(meta.inheritanceChain);    // ['IfcRoot', ..., 'IfcWall']
console.log(meta.allAttributes);       // every attribute including inherited

// Schema membership check
console.log(isKnownEntity('IfcWall'));     // true
console.log(isKnownEntity('IfcWidget'));   // false

On-demand property extraction

Properties and quantities are extracted lazily — pay only for what you read.

import {
  extractPropertiesOnDemand,
  extractQuantitiesOnDemand,
  extractMaterialsOnDemand,
  extractClassificationsOnDemand,
} from '@ifc-lite/parser';

const wallId = 12345;

const psets = extractPropertiesOnDemand(store, wallId);
//   [{ name: 'Pset_WallCommon', properties: [{ name: 'FireRating', value: 'REI 60' }, ...] }]

const qsets = extractQuantitiesOnDemand(store, wallId);
//   [{ name: 'Qto_WallBaseQuantities', quantities: [{ name: 'Length', value: 5.0 }, ...] }]

const material = extractMaterialsOnDemand(store, wallId);
//   { name: 'Concrete C30/37', layers: [{ name: 'Concrete', thickness: 0.15 }, ...] }

const classifications = extractClassificationsOnDemand(store, wallId);
//   [{ system: 'Uniclass 2015', identification: 'Pr_60_10_32', name: 'External walls', ... }]

Georeferencing

import { extractGeoreferencingOnDemand } from '@ifc-lite/parser';

const georef = extractGeoreferencingOnDemand(store);

if (georef?.hasGeoreference) {
  console.log(`CRS: ${georef.projectedCRS?.name}`);
  console.log(`Origin: ${georef.mapConversion?.eastings}, ${georef.mapConversion?.northings}, ${georef.mapConversion?.orthogonalHeight}`);
  console.log(`Grid north: ${georef.mapConversion?.xAxisAbscissa}, ${georef.mapConversion?.xAxisOrdinate}`);
}

Performance

Model size Parse time
10 MB ~100–200 ms
50 MB ~600–700 ms
200 MB ~2.5–3 s
  • Tokenization: high single-pass throughput on M1/M2 laptops
  • Bundle: ~200 KB gzipped (schema registry included)
  • Memory: TypedArray columnar storage

API

See the Parsing Guide and API Reference.

License

MPL-2.0

Keywords