mikser-io 9.40.0 → 9.40.2
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/explain.js +26 -0
- package/src/render.js +17 -3
package/package.json
CHANGED
package/src/explain.js
CHANGED
|
@@ -228,6 +228,16 @@ export async function explain(reference) {
|
|
|
228
228
|
: 'unknown',
|
|
229
229
|
outputHash: snap.outputHash ?? null,
|
|
230
230
|
parent: snap.parent ?? null,
|
|
231
|
+
// Which keys of its OWN meta the render read, and which keys it
|
|
232
|
+
// read off OTHER entities.
|
|
233
|
+
//
|
|
234
|
+
// refClosure answers "what would re-render this". These answer
|
|
235
|
+
// "what does it actually use", which is the question behind a
|
|
236
|
+
// document that renders to a hole: a key the layout never touches
|
|
237
|
+
// is either a typo or dead weight, and nothing else on this report
|
|
238
|
+
// distinguishes them. Empty when the catalog predates the record.
|
|
239
|
+
metaReads: snap.metaReads ?? [],
|
|
240
|
+
consumedReads: (snap.consumedReads ?? []).map(([id, keys]) => ({ entity: id, keys })),
|
|
231
241
|
refClosure: (snap.refClosure ?? []).map(entry =>
|
|
232
242
|
entry.kind === 'query'
|
|
233
243
|
? {
|
|
@@ -383,6 +393,22 @@ export function formatExplain(report) {
|
|
|
383
393
|
const gone = e.gone?.length ? ' [TARGET DELETED SINCE]' : ''
|
|
384
394
|
out.push(` ${e.kind.padEnd(10)} ${e.target}${bound}${e.hash ? ` ${e.hash}` : ''}${gone}`)
|
|
385
395
|
}
|
|
396
|
+
|
|
397
|
+
// What the render actually READ, as against what would re-render it.
|
|
398
|
+
// Capped, because a large page reads a lot and a wall of keys buries
|
|
399
|
+
// the rest of the report — the full list is in --json.
|
|
400
|
+
const SHOWN = 12
|
|
401
|
+
const shown = (keys) => keys.length > SHOWN
|
|
402
|
+
? `${keys.slice(0, SHOWN).join(', ')} … +${keys.length - SHOWN} more`
|
|
403
|
+
: keys.join(', ')
|
|
404
|
+
if (r.metaReads?.length) {
|
|
405
|
+
row('metaReads', `${r.metaReads.length} key${r.metaReads.length === 1 ? '' : 's'} of its own meta`)
|
|
406
|
+
out.push(` ${shown(r.metaReads)}`)
|
|
407
|
+
}
|
|
408
|
+
for (const c of r.consumedReads ?? []) {
|
|
409
|
+
row('consumed', `${c.entity} (${c.keys.length})`)
|
|
410
|
+
out.push(` ${shown(c.keys)}`)
|
|
411
|
+
}
|
|
386
412
|
}
|
|
387
413
|
|
|
388
414
|
out.push('')
|
package/src/render.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from 'node:fs'
|
|
2
2
|
import { readFile, unlink } from 'node:fs/promises'
|
|
3
3
|
import { createRequire } from 'node:module'
|
|
4
|
-
import { createTrack, recordReads, serializeTrack } from './track.js'
|
|
4
|
+
import { createTrack, recordReads, serializeTrack, observeConsumed } from './track.js'
|
|
5
5
|
import { randomUUID } from 'node:crypto'
|
|
6
6
|
import path from 'node:path'
|
|
7
7
|
import _ from 'lodash'
|
|
@@ -110,7 +110,8 @@ export default async ({ entity, options, config, context, state, logger, port, t
|
|
|
110
110
|
// so the worker makes its own track here and returns its CONTENTS with the
|
|
111
111
|
// result, where the engine folds them into the real one.
|
|
112
112
|
const ownTrack = !track
|
|
113
|
-
track = track ?? createTrack({ meta: options?.metaReads !== false
|
|
113
|
+
track = track ?? createTrack({ meta: options?.metaReads !== false,
|
|
114
|
+
consumed: options?.metaReads !== false })
|
|
114
115
|
|
|
115
116
|
logger = logger || {
|
|
116
117
|
info(...args) {
|
|
@@ -259,7 +260,20 @@ export default async ({ entity, options, config, context, state, logger, port, t
|
|
|
259
260
|
: typeof result.id === 'string' ? [result.id]
|
|
260
261
|
: Object.values(result).map(e => e?.id).filter(Boolean)
|
|
261
262
|
track?.lookup?.(href, ids)
|
|
262
|
-
|
|
263
|
+
// The entity goes to the TEMPLATE, which then reads fields off it.
|
|
264
|
+
// Recording those against the entity they belong to is what gives a
|
|
265
|
+
// document that never renders a contract — and this is the second
|
|
266
|
+
// way one reaches a render, alongside a sidecar's findEntity.
|
|
267
|
+
//
|
|
268
|
+
// `lookupUrl` needs no equivalent: it hands back a URL string, so
|
|
269
|
+
// nothing is ever read off an entity by the caller.
|
|
270
|
+
if (!result) return result
|
|
271
|
+
if (typeof result.id === 'string') return observeConsumed(result, track)
|
|
272
|
+
const observedByLang = {}
|
|
273
|
+
for (const [lang, row] of Object.entries(result)) {
|
|
274
|
+
observedByLang[lang] = row?.id ? observeConsumed(row, track) : row
|
|
275
|
+
}
|
|
276
|
+
return observedByLang
|
|
263
277
|
},
|
|
264
278
|
// Resolve a served-entity reference to its deployed URL, absolute
|
|
265
279
|
// when runtime.options.url is set (ADR-0011).
|