mikser-io 10.10.0 → 10.10.1
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.
- package/package.json +1 -1
- package/src/plugins/assets.js +68 -37
package/package.json
CHANGED
package/src/plugins/assets.js
CHANGED
|
@@ -418,11 +418,12 @@ export function assets(options = {}) {
|
|
|
418
418
|
}
|
|
419
419
|
|
|
420
420
|
async function forgetPresetMarkers(entity) {
|
|
421
|
-
|
|
421
|
+
const destination = path.resolve(entity.destination)
|
|
422
|
+
for (const marker of markersByDestination.get(destination) ?? []) {
|
|
422
423
|
await rm(marker, { force: true })
|
|
423
424
|
checksumMap.delete(marker)
|
|
424
425
|
}
|
|
425
|
-
markersByDestination.delete(
|
|
426
|
+
markersByDestination.delete(destination)
|
|
426
427
|
}
|
|
427
428
|
|
|
428
429
|
async function renderPresets(entities, { rendererChanged = new Set() } = {}) {
|
|
@@ -702,27 +703,22 @@ export function assets(options = {}) {
|
|
|
702
703
|
|
|
703
704
|
checksumMap.clear()
|
|
704
705
|
markersByDestination.clear()
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
const presetFolders = Object.keys(runtime.state.assets.presets).map(name => `${name}/**/*`)
|
|
710
|
-
const files = presetFolders.length
|
|
711
|
-
? await globby(presetFolders, { cwd: runtime.options.assetsFolder, onlyFiles: true })
|
|
712
|
-
: []
|
|
713
|
-
const derivatives = new Set()
|
|
714
|
-
for (let file of files) {
|
|
715
|
-
const absolute = path.join(runtime.options.assetsFolder, file)
|
|
716
|
-
if (!file.endsWith('.md5')) {
|
|
717
|
-
derivatives.add(absolute)
|
|
718
|
-
continue
|
|
719
|
-
}
|
|
720
|
-
checksumMap.add(absolute)
|
|
706
|
+
const checksumFiles = await globby('**/*.md5', { cwd: runtime.options.assetsFolder })
|
|
707
|
+
for (let checksumFile of checksumFiles) {
|
|
708
|
+
const marker = path.join(runtime.options.assetsFolder, checksumFile)
|
|
709
|
+
checksumMap.add(marker)
|
|
721
710
|
// `<destination>.<revision>.md5` — the same shape the orphan
|
|
722
711
|
// sweep strips to get back to the derivative.
|
|
723
|
-
|
|
712
|
+
//
|
|
713
|
+
// Resolved on both sides of the comparison, because the other
|
|
714
|
+
// side is a manifest destination and these two are built by
|
|
715
|
+
// different subsystems. It is a no-op while assetsFolder is
|
|
716
|
+
// derived from workingFolder (see onLoaded), which is why no test
|
|
717
|
+
// can tell it apart — normalization at the boundary, not a
|
|
718
|
+
// transform anything depends on.
|
|
719
|
+
const destination = path.resolve(marker.replace(/\.[^.]+\.md5$/, ''))
|
|
724
720
|
if (!markersByDestination.has(destination)) markersByDestination.set(destination, [])
|
|
725
|
-
markersByDestination.get(destination).push(
|
|
721
|
+
markersByDestination.get(destination).push(marker)
|
|
726
722
|
}
|
|
727
723
|
|
|
728
724
|
const entitiesToRender = new Map()
|
|
@@ -745,28 +741,63 @@ export function assets(options = {}) {
|
|
|
745
741
|
// Empty on any healthy build, and the catalog walk is behind that
|
|
746
742
|
// emptiness: this costs one Set lookup per cycle until something has
|
|
747
743
|
// actually gone wrong.
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
744
|
+
// Asked of the MANIFEST, not of the folder.
|
|
745
|
+
//
|
|
746
|
+
// The first version walked every file under each preset folder and
|
|
747
|
+
// called anything without a marker an interrupted render. But only
|
|
748
|
+
// the destination the engine hands the preset gets a marker, so a
|
|
749
|
+
// preset that legitimately writes MORE than one file — a poster frame
|
|
750
|
+
// beside a video — left permanent evidence of a failure that never
|
|
751
|
+
// happened. It warned on every build for ever, said the derivative
|
|
752
|
+
// was "being re-derived", and re-derived nothing, because no entity's
|
|
753
|
+
// destination ever matched the extra file. A warning that cries wolf
|
|
754
|
+
// on every build is worse than the silence it replaced, and it
|
|
755
|
+
// teaches people to ignore the one that matters.
|
|
756
|
+
//
|
|
757
|
+
// A file nothing claims is an ORPHAN, which is a different fault with
|
|
758
|
+
// its own report. This asks only about outputs the manifest recorded,
|
|
759
|
+
// which is also what makes the recovery possible: a snapshot carries
|
|
760
|
+
// the entity id, so there is nothing to reverse-map and no catalog to
|
|
761
|
+
// walk.
|
|
762
|
+
const presetRoots = Object.keys(presets)
|
|
763
|
+
.map(name => path.resolve(runtime.options.assetsFolder, name) + path.sep)
|
|
764
|
+
const unfinished = new Map()
|
|
765
|
+
for (const snapshot of runtime.manifest?.all?.() ?? []) {
|
|
766
|
+
if (!snapshot.destination) continue
|
|
767
|
+
const destination = path.resolve(snapshot.destination)
|
|
768
|
+
if (!presetRoots.some(root => destination.startsWith(root))) continue
|
|
769
|
+
if (markersByDestination.has(destination)) continue
|
|
770
|
+
// Gone entirely is a different fault, and the engine's
|
|
771
|
+
// missing-output path already has it. Reporting it here as well
|
|
772
|
+
// would name the wrong cause.
|
|
773
|
+
if (outputMissing(snapshot.destination)) continue
|
|
774
|
+
unfinished.set(snapshot.id, destination)
|
|
751
775
|
}
|
|
752
|
-
if (
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
const
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
776
|
+
if (unfinished.size) {
|
|
777
|
+
const damaged = []
|
|
778
|
+
for (const [id, destination] of unfinished) {
|
|
779
|
+
const entity = await findEntity({ id })
|
|
780
|
+
// Source gone: the orphan sweep removes the derivative at
|
|
781
|
+
// finalize. Nothing to re-derive and nothing to say.
|
|
782
|
+
if (!entity) continue
|
|
783
|
+
assetsMap[entity.id] ??= await getEntityPresets(entity)
|
|
759
784
|
// Forced past the reuse check as well as scheduled: the file
|
|
760
785
|
// on disk is exactly what must not be trusted, and
|
|
761
|
-
// isPresetRendered
|
|
786
|
+
// isPresetRendered cannot tell half-written bytes from
|
|
762
787
|
// finished ones.
|
|
763
|
-
presetMoved.add(
|
|
764
|
-
entitiesToRender.set(
|
|
788
|
+
presetMoved.add(entity.id)
|
|
789
|
+
entitiesToRender.set(entity.id, entity)
|
|
790
|
+
damaged.push(destination)
|
|
791
|
+
}
|
|
792
|
+
// Only when something is actually being re-derived. The warning
|
|
793
|
+
// claimed the action rather than reporting it, so a build that
|
|
794
|
+
// scheduled nothing still announced a recovery.
|
|
795
|
+
if (damaged.length) {
|
|
796
|
+
useLogger().warn({ code: 'preset-unfinished', derivatives: damaged },
|
|
797
|
+
'Assets: %d derivative(s) have no completed-render marker and are being re-derived. '
|
|
798
|
+
+ 'A preset render did not finish — the file left behind is not trustworthy.',
|
|
799
|
+
damaged.length)
|
|
765
800
|
}
|
|
766
|
-
useLogger().warn({ code: 'preset-unfinished', derivatives: [...unmarked], sources: entitiesToRender.size },
|
|
767
|
-
'Assets: %d derivative(s) have no completed-render marker and are being re-derived. '
|
|
768
|
-
+ 'A preset render did not finish — the file left behind is not trustworthy.',
|
|
769
|
-
unmarked.size)
|
|
770
801
|
}
|
|
771
802
|
|
|
772
803
|
// --render-presets [name]: re-derive though nothing moved.
|