UNPKG

pomljs

Version:

Prompt Orchestration Markup Language

137 lines (133 loc) 4.24 kB
'use strict'; var fs = require('./fs.cjs'); var path = require('path'); function replaceBuffers(value) { if (Buffer.isBuffer(value)) { const wrapper = { __base64__: value.toString('base64') }; return wrapper; } else if (Array.isArray(value)) { return value.map(replaceBuffers); } else if (value && typeof value === 'object') { const result = {}; for (const k of Object.keys(value)) { result[k] = replaceBuffers(value[k]); } return result; } return value; } function parseJsonWithBuffers(text) { return JSON.parse(text, (_key, value) => { if (value && typeof value === 'object' && value.__base64__) { return Buffer.from(value.__base64__, 'base64'); } return value; }); } let traceEnabled = false; let traceDir; function setTrace(enabled = true, dir) { traceEnabled = enabled; if (!enabled) { traceDir = undefined; return undefined; } const envDir = process.env.POML_TRACE; if (dir) { const base = path.resolve(dir); fs.mkdirSync(base, { recursive: true }); traceDir = base; } else if (envDir) { fs.mkdirSync(envDir, { recursive: true }); traceDir = envDir; } else { traceDir = undefined; } return traceDir; } function clearTrace() { traceEnabled = false; traceDir = undefined; } function isTracing() { return traceEnabled && !!traceDir; } function nextIndex(sourcePath) { if (!traceDir) { return [0, '', -1]; } const fileName = sourcePath ? path.basename(sourcePath, '.poml') : ''; for (let i = 1;; i++) { const idxStr = i.toString().padStart(4, '0'); // 1) If ANY file in traceDir starts with this index, skip it. // This makes the sequence independent of fileName. const entries = fs.readdirSync(traceDir); const indexTaken = entries.some((entry) => entry.startsWith(idxStr)); if (indexTaken) { continue; } // 2) Build our own target using the (possibly present) fileName. const prefix = path.join(traceDir, idxStr) + (fileName ? `.${fileName}` : ''); const filePath = `${prefix}.poml`; try { // 3) Atomically create our file. If it races and now exists, loop again. const fd = fs.openSync(filePath, 'wx'); return [i, prefix, fd]; } catch (err) { if (err.code === 'EEXIST') { // Someone created a file with this index between steps (1) and (3); try next i. continue; } throw err; } } } function dumpTrace(markup, context, stylesheet, result, sourcePath, prettyResult) { if (!isTracing()) { return; } const [_idx, prefix, fd] = nextIndex(sourcePath); try { fs.writeSync(fd, markup); } finally { fs.closeSync(fd); } if (sourcePath) { const envFile = `${prefix}.env`; fs.writeFileSync(envFile, `SOURCE_PATH=${sourcePath}\n`); const linkPath = `${prefix}.source.poml`; try { fs.symlinkSync(sourcePath, linkPath); } catch { console.warn(`Failed to create symlink for source path: ${sourcePath}`); } } if (context && Object.keys(context).length > 0) { fs.writeFileSync(`${prefix}.context.json`, JSON.stringify(replaceBuffers(context), null, 2)); } if (stylesheet && Object.keys(stylesheet).length > 0) { fs.writeFileSync(`${prefix}.stylesheet.json`, JSON.stringify(replaceBuffers(stylesheet), null, 2)); } if (result !== undefined) { fs.writeFileSync(`${prefix}.result.json`, JSON.stringify(replaceBuffers(result), null, 2)); if (prettyResult !== undefined) { fs.writeFileSync(`${prefix}.result.txt`, prettyResult); } } } if (process.env.POML_TRACE) { setTrace(true, process.env.POML_TRACE); } exports.clearTrace = clearTrace; exports.dumpTrace = dumpTrace; exports.isTracing = isTracing; exports.parseJsonWithBuffers = parseJsonWithBuffers; exports.setTrace = setTrace; //# sourceMappingURL=trace.cjs.map