mikser-io 11.10.2 → 11.10.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.
- package/docs/diagnostics.md +6 -0
- package/package.json +1 -1
- package/src/manifest/cycle.js +41 -2
package/docs/diagnostics.md
CHANGED
|
@@ -1039,6 +1039,12 @@ distinction is the whole of [Faults](#faults) above.
|
|
|
1039
1039
|
| `preset-no-match` | warn | A configured preset matched none of the entities evaluated this run. Phrased as what was observed: an incremental cycle legitimately evaluates a handful. |
|
|
1040
1040
|
| `preset-unknown` | warn | `--render-presets` named a preset that is not configured. |
|
|
1041
1041
|
|
|
1042
|
+
### Extraction (`mikser-io-ocr`)
|
|
1043
|
+
|
|
1044
|
+
| Code | Severity | Means |
|
|
1045
|
+
| --- | --- | --- |
|
|
1046
|
+
| `ocr-schema-changed` | notice | A step's schema changed, so stored answers no longer match it by hash. Says how many documents are in the pass and which fields are being asked for. Answers that still satisfy the new schema are reused without a model call; the rest are asked only for the fields they are missing. |
|
|
1047
|
+
|
|
1042
1048
|
### Configuration and stores
|
|
1043
1049
|
|
|
1044
1050
|
| Code | Severity | Means |
|
package/package.json
CHANGED
package/src/manifest/cycle.js
CHANGED
|
@@ -53,8 +53,47 @@ onFinalize(async () => {
|
|
|
53
53
|
const newDestinationsByParent = new Map()
|
|
54
54
|
const lostPagination = new Set()
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
// A DELETE only counts if nothing re-created the entity after it.
|
|
57
|
+
//
|
|
58
|
+
// Collected with no regard for supersession, this unlinked a page that
|
|
59
|
+
// had just been written. A file created, deleted and re-created AT THE
|
|
60
|
+
// SAME PATH while one cycle was held open leaves that cycle holding
|
|
61
|
+
// CREATE, DELETE and CREATE for one id — and since 11.10.2 a cancelled
|
|
62
|
+
// cycle's entries are carried rather than dropped, which is what lets
|
|
63
|
+
// the stale DELETE reach the cycle that finally renders the entity. That
|
|
64
|
+
// fix is right; this is the other end of it.
|
|
65
|
+
//
|
|
66
|
+
// The staging below and the `claimedByThisCycle` guard were both written
|
|
67
|
+
// for the RENAME case, where the DELETE carries the OLD id and the RENDER
|
|
68
|
+
// a NEW one. There the new destination is correctly protected. When the
|
|
69
|
+
// id is the SAME, the guard skipped the very destination just written,
|
|
70
|
+
// `stillClaimed` was empty because a first render has no snapshot row
|
|
71
|
+
// yet, and the unlink ran: an empty output directory, no snapshot, no
|
|
72
|
+
// failure, `Rendered: 1` and a green build. Nothing recovered it — the
|
|
73
|
+
// source gate saw the file unchanged, and missingOutputIds() iterates
|
|
74
|
+
// SNAPSHOTS, so an entity that never got one is invisible to it.
|
|
75
|
+
//
|
|
76
|
+
// ORDER, not catalog presence. Catalog presence gives the same answers
|
|
77
|
+
// today, but only because catalog.js's finalize drain happens to be
|
|
78
|
+
// registered before this one (index.js exports catalog.js first), so the
|
|
79
|
+
// row is already gone when cleanup reads it. That is an invisible
|
|
80
|
+
// coupling: reordering two exports would silently restore this bug. The
|
|
81
|
+
// journal knows the answer on its own, and mikser-io-layouts already
|
|
82
|
+
// reconciles the same journal by order when it seeds dispatch.
|
|
83
|
+
const lastDelete = new Map()
|
|
84
|
+
const lastWrite = new Map()
|
|
85
|
+
for await (const { id: seq, operation, entity } of useJournal(
|
|
86
|
+
'Manifest cleanup', [OPERATION.DELETE, OPERATION.CREATE, OPERATION.UPDATE])) {
|
|
87
|
+
if (!entity?.id) continue
|
|
88
|
+
const seen = operation === OPERATION.DELETE ? lastDelete : lastWrite
|
|
89
|
+
const prior = seen.get(entity.id)
|
|
90
|
+
if (prior === undefined || seq > prior) seen.set(entity.id, seq)
|
|
91
|
+
}
|
|
92
|
+
for (const [id, seq] of lastDelete) {
|
|
93
|
+
// `>` and not `>=`: a render that opts out of the catalog journals its
|
|
94
|
+
// DELETE after the entity's own CREATE, so the DELETE is genuinely
|
|
95
|
+
// later and must win — the rule 2e documents.
|
|
96
|
+
if (seq > (lastWrite.get(id) ?? -1)) deletedIds.push(id)
|
|
58
97
|
}
|
|
59
98
|
|
|
60
99
|
// Every destination claimed by a render task this cycle — whether it
|