@needle-tools/engine
Version:
Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.
60 lines (53 loc) • 2.47 kB
JavaScript
// @ts-check
/**
* File writer — the only module that performs I/O writes.
*
* Orchestrates scanning, codegen, and writes the output files.
* Returns false if content was already up-to-date (no write performed).
*/
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
import { join, dirname } from 'path';
import { scanBindings } from './dts.scan.js';
import { generateDts, generateHtmlCustomData } from './dts.codegen.js';
/**
* Scan assets and write `needle-bindings.d.ts` and `needle-html-data.json`
* to the output directory.
* Returns the number of bindings written, or `false` if content was already up-to-date.
*
* @param {object} opts
* @param {string} opts.assetsDir Absolute path to assets directory
* @param {string} opts.outputPath Absolute path to write needle-bindings.d.ts
* @param {string} [opts.projectRoot] Project root — enables entrypoint GLB detection
* @param {string} [opts.codegenDir] Codegen directory — used to find gen.js and write needle-html-data.json (no binding copy written here)
* @returns {Promise<number | false>}
*/
export async function generateBindingsDts({ assetsDir, outputPath, projectRoot, codegenDir }) {
const entries = await scanBindings(assetsDir, projectRoot, codegenDir);
const content = generateDts(entries);
const htmlContent = generateHtmlCustomData(entries);
mkdirSync(dirname(outputPath), { recursive: true });
let dtsChanged = false;
try {
const existing = existsSync(outputPath) ? readFileSync(outputPath, "utf8") : "";
if (existing !== content) {
writeFileSync(outputPath, content, "utf8");
dtsChanged = true;
}
} catch (_e) {
writeFileSync(outputPath, content, "utf8");
dtsChanged = true;
}
const htmlDataPath = join(dirname(outputPath), "needle-html-data.json");
try {
const existingHtml = existsSync(htmlDataPath) ? readFileSync(htmlDataPath, "utf8") : "";
if (existingHtml !== htmlContent) {
writeFileSync(htmlDataPath, htmlContent, "utf8");
}
} catch (_e) {
writeFileSync(htmlDataPath, htmlContent, "utf8");
}
if (!dtsChanged) return false;
const nodeCount = new Set(entries.map(e => e.nodeName)).size;
const bindingCount = new Set(entries.filter(e => e.componentName).map(e => `${e.nodeName}/${e.componentName}`)).size;
return bindingCount > 0 ? bindingCount : nodeCount;
}