mikser-io 9.0.3 → 9.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/render.js +37 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mikser-io",
3
- "version": "9.0.3",
3
+ "version": "9.0.4",
4
4
  "description": "<p align=\"center\"> <img src=\"mikser-lockup-stacked.svg\" alt=\"mikser\" width=\"198\" /> </p>",
5
5
  "main": "index.js",
6
6
  "exports": {
package/src/render.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { readFileSync, existsSync } from 'node:fs'
2
+ import { readFile, unlink } from 'node:fs/promises'
2
3
  import { createRequire } from 'node:module'
3
4
  import { randomUUID } from 'node:crypto'
4
5
  import path from 'node:path'
@@ -290,7 +291,42 @@ export function useRenderer(runtime, { defaultTimeout = 30_000 } = {}) {
290
291
  if (!isFinal) return
291
292
  remaining.delete(cid)
292
293
  clearTimeout(item.timer)
293
- item.resolve({ output: entry.output, entity: entry.entity })
294
+
295
+ // The postprocess chain writes the final bytes straight to
296
+ // disk and its dispatcher (src/postprocess.js) returns
297
+ // undefined, so a postprocessed completion arrives with
298
+ // output.result empty — even though the bytes exist on disk.
299
+ // Our contract (see the render() JSDoc below) is to hand back
300
+ // the FINAL pipeline output, so read it from where the chain
301
+ // wrote it: <destination> under outputFolder, or under
302
+ // previewFolder when the caller passed save:false (the engine
303
+ // swaps the postprocess outputFolder to previewFolder in that
304
+ // case — see engine.js onBeforePostprocess). Render-only
305
+ // entities already carry their bytes in output.result and
306
+ // skip this entirely.
307
+ let output = entry.output
308
+ if (hasPostprocessor && output?.result == null && entry.entity?.destination) {
309
+ const saveOff = entry.entity.options?.save === false
310
+ const folder = saveOff
311
+ ? runtime.options.previewFolder
312
+ : runtime.options.outputFolder
313
+ const file = path.join(folder, entry.entity.destination.replace(/^\/+/, ''))
314
+ try {
315
+ const bytes = await readFile(file)
316
+ output = { success: true, result: bytes }
317
+ // save:false → that previewFolder file is engine
318
+ // scratch the caller explicitly opted out of
319
+ // persisting. Hand back the bytes, leave nothing on
320
+ // disk.
321
+ if (saveOff) await unlink(file).catch(() => {})
322
+ } catch (err) {
323
+ useLogger()?.warn?.(
324
+ 'useRenderer: postprocessed output for %s not found at %s — returning empty result: %s',
325
+ entry.entity.id, file, err.message,
326
+ )
327
+ }
328
+ }
329
+ item.resolve({ output, entity: entry.entity })
294
330
  }
295
331
  completedHooks.push(hook)
296
332