Introduce platform-mixin-assign-manifest.js (59 rows, same assign order) and manifest-driven apply-platform-mixins loop. Add json-export-gossip-alignment- validate.js, platform-ipc-contract.js; digest-json uses per-entry gossip keys. No observable behavior or mesh semantics changes. Co-authored-by: Cursor <[email protected]>
55 lines
2.2 KiB
JavaScript
55 lines
2.2 KiB
JavaScript
'use strict'
|
|
|
|
/**
|
|
* Shared static checks for combined vs dedicated JSON export gossip alignment.
|
|
* Used by app smokes; no runtime platform dependency.
|
|
*/
|
|
function validateGossipAlignmentRow (row, combinedSrc, dedicatedSrc) {
|
|
if (!combinedSrc.includes(row.keysField)) {
|
|
throw new Error(`${row.combined} missing keysField ${row.keysField}`)
|
|
}
|
|
if (!combinedSrc.includes(row.initMethod)) {
|
|
throw new Error(`${row.combined} missing initMethod ${row.initMethod}`)
|
|
}
|
|
if (!dedicatedSrc.includes(`keysField: '${row.keysField}'`)) {
|
|
throw new Error(`${row.dedicated} keysField mismatch vs ${row.combined}`)
|
|
}
|
|
if (row.gossipHashPrefix && !combinedSrc.includes(`gossipHashPrefix: '${row.gossipHashPrefix}'`)) {
|
|
throw new Error(`${row.combined} missing gossipHashPrefix ${row.gossipHashPrefix}`)
|
|
}
|
|
if (row.method && !combinedSrc.includes(row.method)) {
|
|
throw new Error(`${row.combined} missing gossip method ${row.method}`)
|
|
}
|
|
}
|
|
|
|
function validateDualHealPerEntryGossipKeys (src, fileName, opts = {}) {
|
|
const minEntries = opts.minEntries ?? 2
|
|
if (!src.includes('createJsonExportDualHealMixin')) return
|
|
const block = src.match(/gossipEntries:\s*\[([\s\S]*?)\]\s*,\s*heals:/)
|
|
if (!block) {
|
|
throw new Error(`${fileName} dual-heal missing gossipEntries block`)
|
|
}
|
|
const entries = block[1]
|
|
const entryCount = (entries.match(/method:\s*'/g) || []).length
|
|
if (entryCount < minEntries) {
|
|
throw new Error(`${fileName} expected at least ${minEntries} gossip entries, got ${entryCount}`)
|
|
}
|
|
const keysCount = (entries.match(/keysField:\s*'/g) || []).length
|
|
if (keysCount < entryCount) {
|
|
throw new Error(`${fileName} expected per-entry keysField on all gossip rows (${keysCount}/${entryCount})`)
|
|
}
|
|
const initCount = (entries.match(/initMethod:\s*'/g) || []).length
|
|
if (initCount < entryCount) {
|
|
throw new Error(`${fileName} expected per-entry initMethod on all gossip rows (${initCount}/${entryCount})`)
|
|
}
|
|
const cfgHead = src.match(/createJsonExportDualHealMixin\(\{\s*([\s\S]*?)\n\s*gossipEntries:/)
|
|
if (cfgHead && /keysField\s*:/.test(cfgHead[1])) {
|
|
throw new Error(`${fileName} must not use top-level keysField on dual-heal factory`)
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
validateGossipAlignmentRow,
|
|
validateDualHealPerEntryGossipKeys
|
|
}
|