Files
bare-operating-system/scripts/sync-bare-module-manifest-from-catalog.mjs
T
Raven Scott 9bdecc4170
Release rolling / release (push) Successful in 11m16s
Sync Holepunch modules to current clone/npm latest
Bump published pins (compact-encoding 3, bare-fetch/tls/https/ws 3,
bare-subprocess 6, bare-signals 5, corestore 7.12, protomux 3.11,
hypercore-crypto 3.7, bare-runtime 1.31) and regenerate catalogs,
manifests, and kernel/seeder bundles.

Adapt call sites to the new APIs:
- Corestore: explicit session flush before suspend(); treeCache ctor opts
- bare-crypto: KeyObject.export() instead of removed ._key
- Protomux 3.11: wait for fullyOpened()/fullyClosed() on chat channels
- bare-fetch: surface response.type and Headers.getSetCookie
- host snapshots: bare-os 3.9 / bare-posix / bare-fs.statfs frsize
- bare-subprocess 6: optional IPC channel + json serialization

Keep catalog sync from wiping curated pearEntries. Teach the Node test
shim to stub bare-thread/bare-worker (ESM absolute paths) and chain
Bare.on so bare-timers can load. Booter 479, protocol 34, seeder 14.
2026-08-12 20:56:28 -04:00

282 lines
7.3 KiB
JavaScript

#!/usr/bin/env node
/**
* Merge docs/bare-holepunch-catalog.json into bare-module-manifest.json and
* sync bare-os-booter optionalDependencies for every included bare-* not
* already listed in dependencies.
*
* node scripts/sync-bare-module-manifest-from-catalog.mjs
*/
import { readFile, writeFile } from 'node:fs/promises'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import process from 'node:process'
import { manifestCtxKeyForPackage } from './gen-bare-holepunch-catalog.mjs'
import { generateBareModuleManifestData } from './generate-bare-module-manifest-data.mjs'
const __dirname = dirname(fileURLToPath(import.meta.url))
const root = join(__dirname, '..')
const catalogPath = join(root, 'docs', 'bare-holepunch-catalog.json')
const manifestPath = join(
root,
'packages/bare-os-booter/lib/bare-module-manifest.json'
)
const manifestDataPath = join(
root,
'packages/bare-os-booter/lib/bare-module-manifest.data.mjs'
)
const booterPkgPath = join(root, 'packages/bare-os-booter/package.json')
const ctxImportOverridesPath = join(__dirname, 'bare-ctx-import-overrides.json')
/** Fixed first rows: non-org + curated bare-* (order preserved). */
const BASE_ENTRIES = [
{
ctxKey: 'b4a',
package: 'b4a',
export: 'default',
bundle: true,
optional: false,
nativeHint: false
},
{
ctxKey: 'compactEncoding',
package: 'compact-encoding',
export: 'default',
bundle: true,
optional: false,
nativeHint: false
},
{
ctxKey: 'safetyCatch',
package: 'safety-catch',
export: 'default',
bundle: true,
optional: false,
nativeHint: false
},
{
ctxKey: 'hypercoreIdEncoding',
package: 'hypercore-id-encoding',
export: 'default',
bundle: true,
optional: false,
nativeHint: false
},
{
ctxKey: 'protomux',
package: 'protomux',
export: 'default',
bundle: true,
optional: false,
nativeHint: false
},
{
ctxKey: 'holesail',
package: 'holesail',
export: 'default',
bundle: true,
optional: false,
nativeHint: false
},
{
ctxKey: 'bareUrl',
package: 'bare-url',
export: 'default',
bundle: false,
optional: true,
nativeHint: false,
skipReason: 'Requires Bare global; host import on Pear/Bare only'
},
{
ctxKey: 'barePath',
package: 'bare-path',
export: 'default',
bundle: false,
optional: true,
nativeHint: false,
skipReason: 'Requires Bare global; host import on Pear/Bare only'
},
{
ctxKey: 'bareEncoding',
package: 'bare-encoding',
export: 'default',
bundle: true,
optional: true,
nativeHint: false
},
{
ctxKey: 'bareEvents',
package: 'bare-events',
export: 'default',
bundle: true,
optional: true,
nativeHint: false
},
{
ctxKey: 'fetch',
package: 'bare-fetch',
export: 'default',
bundle: false,
optional: true,
nativeHint: true,
skipReason: 'Native / runtime-specific deps; host import only'
},
{
ctxKey: 'bareReadline',
package: 'bare-readline',
export: 'default',
bundle: false,
optional: true,
nativeHint: false,
skipReason: 'TTY integration; host import only'
},
{
ctxKey: 'bareCrypto',
package: 'bare-crypto',
export: 'default',
bundle: false,
optional: true,
nativeHint: true,
skipReason: 'Native addon; host import only'
}
]
const basePackages = new Set(BASE_ENTRIES.map((e) => e.package))
/** @param {Record<string, unknown>} raw */
function applyCtxImportOverrides(ent, npmName, raw) {
const ns = new Set(
Array.isArray(raw.namespaceExportPackages)
? raw.namespaceExportPackages
: []
)
const se = new Set(
Array.isArray(raw.sideEffectImportPackages)
? raw.sideEffectImportPackages
: []
)
const sub =
raw.packageImportSpecifiers &&
typeof raw.packageImportSpecifiers === 'object'
? raw.packageImportSpecifiers
: {}
const out = { ...ent }
if (ns.has(npmName)) out.export = '*'
if (typeof sub[npmName] === 'string') out.package = sub[npmName]
if (se.has(npmName)) out.sideEffectImport = true
return out
}
function buildManifestEntries(catalog, importOverrides) {
const byPackage = new Map(BASE_ENTRIES.map((e) => [e.package, { ...e }]))
for (const row of catalog.entries || []) {
if (!row.includedInBooter || !row.npmName) continue
const name = row.npmName
if (byPackage.has(name)) continue
const ctxKey = row.manifestCtxKey || manifestCtxKeyForPackage(name)
byPackage.set(name, {
ctxKey,
package: name,
export: 'default',
bundle: false,
optional: true,
nativeHint: true,
skipReason:
'Optional Holepunch bare-*; may be native, platform-specific, or Bare-only'
})
}
const finalized = new Map()
for (const [npmName, ent] of byPackage) {
finalized.set(
npmName,
applyCtxImportOverrides(ent, npmName, importOverrides)
)
}
const extras = [...finalized.entries()]
.filter(([pkg]) => !basePackages.has(pkg))
.map(([, ent]) => ent)
.sort((a, b) => a.package.localeCompare(b.package))
return [
...BASE_ENTRIES.map((e) => ({ ...finalized.get(e.package) })),
...extras
]
}
function mergeOptionalDeps(pkgJson, catalog) {
const deps = pkgJson.dependencies || {}
const have = new Set([
...Object.keys(deps),
...Object.keys(pkgJson.devDependencies || {})
])
const opt = {}
for (const row of catalog.entries || []) {
if (!row.includedInBooter || !row.npmName || !row.npmVersion) continue
const n = row.npmName
if (have.has(n)) continue
opt[n] = `^${row.npmVersion}`
}
const sorted = {}
for (const k of Object.keys(opt).sort()) sorted[k] = opt[k]
pkgJson.optionalDependencies = sorted
}
async function main() {
let importOverrides = {}
try {
importOverrides = JSON.parse(await readFile(ctxImportOverridesPath, 'utf8'))
} catch {
/* optional */
}
const catalogRaw = await readFile(catalogPath, 'utf8')
const catalog = JSON.parse(catalogRaw)
const entries = buildManifestEntries(catalog, importOverrides)
const keys = new Set()
for (const e of entries) {
if (keys.has(e.ctxKey)) throw new Error(`Duplicate ctxKey: ${e.ctxKey}`)
keys.add(e.ctxKey)
}
/** Preserve curated ctx.pear rows; catalog sync only rewrites `entries`. */
let pearEntries
try {
const prev = JSON.parse(await readFile(manifestPath, 'utf8'))
if (Array.isArray(prev.pearEntries) && prev.pearEntries.length) {
pearEntries = prev.pearEntries
}
} catch {
/* first generate */
}
const manifest = pearEntries
? { version: 1, entries, pearEntries }
: { version: 1, entries }
await writeFile(
manifestPath,
JSON.stringify(manifest, null, 2) + '\n',
'utf8'
)
await generateBareModuleManifestData({
manifestPath,
dataPath: manifestDataPath
})
const pkgRaw = await readFile(booterPkgPath, 'utf8')
const pkgJson = JSON.parse(pkgRaw)
mergeOptionalDeps(pkgJson, catalog)
await writeFile(
booterPkgPath,
JSON.stringify(pkgJson, null, 2) + '\n',
'utf8'
)
console.log(
'[sync-bare-module-manifest] manifest entries=',
entries.length,
'optionalDependencies=',
Object.keys(pkgJson.optionalDependencies || {}).length
)
}
main().catch((e) => {
console.error(e)
process.exit(1)
})