Files
bare-operating-system/packages/bare-os-booter/lib/identity/bare-user-session-stack.js
T
2026-08-18 18:11:28 -04:00

126 lines
4.2 KiB
JavaScript

/**
* WWW + managed Holesail + swarm chat initd units — registered and started only after identity unlock,
* stopped on logout. Guest boot skips this stack entirely.
*/
import {
findBareServiceDefinition,
startBareService,
stopBareService
} from './bare-initd.js'
import { maybeRegisterBareHolesailInitd } from './bare-holesail.js'
import { maybeRegisterBareOsChatInitd } from './bare-os-chat-initd.js'
import { maybeRegisterBareOsWwwInitd } from './bare-os-www-initd.js'
import {
maybeStartBareOsDiscordAfterIdentity,
stopBareOsDiscordInitd
} from './bare-os-discord-initd.js'
import { bareOpensshGetListenEndpoint } from './bare-openssh.js'
import { ensureBareOsSshHolesailTunnel } from './bare-os-ssh-holesail.js'
import {
bareOsChatMuxEnabled,
ensureDiskBareOsChatTransport
} from './bare-os-chat-service.js'
import {
bareOsMeshdropMuxEnabled,
ensureDiskBareOsMeshdropTransport
} from './bare-os-meshdrop-service.js'
/** @param {Record<string, string | undefined>} env */
export function registerBareUserSessionStackUnits(env) {
maybeRegisterBareHolesailInitd(env)
maybeRegisterBareOsWwwInitd(env)
maybeRegisterBareOsChatInitd(env)
}
/**
* Idempotent: registers units once, attaches chat service to `ctx.disk` when mux is enabled, then starts
* **bare-os-www** → **bare-holesail** → **bare-os-chat** (initd DAG order).
* @param {Record<string, unknown>} ctx
*/
export async function startBareUserSessionStack(ctx) {
const env =
ctx.env && typeof ctx.env === 'object'
? /** @type {Record<string, string | undefined>} */ (ctx.env)
: /** @type {Record<string, string | undefined>} */ ({})
registerBareUserSessionStackUnits(env)
const disk = /** @type {{ bareOsChatService?: unknown }} */ (ctx.disk)
if (disk && bareOsChatMuxEnabled(globalThis.process?.env)) {
ensureDiskBareOsChatTransport(
/** @type {import('./swarm-disk.js').SwarmDisk} */ (disk),
env
)
}
if (disk && bareOsMeshdropMuxEnabled(globalThis.process?.env)) {
ensureDiskBareOsMeshdropTransport(
/** @type {import('./swarm-disk.js').SwarmDisk} */ (disk),
env
)
}
/** Peers may have connected during guest boot; pair chat after this tick (avoid mux re-entrancy). */
if (disk && typeof disk.pairBareOsChatExistingPeers === 'function') {
await new Promise((r) => setImmediate(r))
disk.pairBareOsChatExistingPeers()
}
if (disk && typeof disk.pairBareOsMeshdropExistingPeers === 'function') {
await new Promise((r) => setImmediate(r))
disk.pairBareOsMeshdropExistingPeers()
}
await maybeStartBareOsDiscordAfterIdentity(ctx)
const order = ['bare-os-www', 'bare-holesail', 'bare-os-chat']
for (const name of order) {
if (!findBareServiceDefinition(name)) continue
try {
await startBareService(ctx, name)
} catch (e) {
const msg = (e && /** @type {{ message?: string }} */ (e).message) || String(e)
try {
ctx.console?.error?.(`[bare-user-stack] start ${name}: ${msg}`)
} catch {
/* ignore */
}
}
}
/** bare-openssh may already be listening from guest boot — run managed tunnel ensure after holesail is up. */
try {
const ep = bareOpensshGetListenEndpoint()
if (ep) await ensureBareOsSshHolesailTunnel(ctx, env, ep.port, ep.host)
} catch (e) {
const msg = (e && /** @type {{ message?: string }} */ (e).message) || String(e)
try {
ctx.console?.error?.(`[bare-user-stack] ssh holesail ensure: ${msg}`)
} catch {
/* ignore */
}
}
}
/**
* Stops **bare-holesail** (before www so the tunnel drops first), **bare-os-www**, **bare-os-chat**.
* Swarm chat **transport** (`disk.bareOsChatService`) stays; `logoutIdentity` refreshes it for guest.
* @param {Record<string, unknown>} ctx
*/
export async function stopBareUserSessionStack(ctx) {
await stopBareOsDiscordInitd(ctx)
const order = ['bare-holesail', 'bare-os-www', 'bare-os-chat']
for (const name of order) {
if (!findBareServiceDefinition(name)) continue
try {
await stopBareService(ctx, name)
} catch (e) {
const msg = (e && /** @type {{ message?: string }} */ (e).message) || String(e)
try {
ctx.console?.error?.(`[bare-user-stack] stop ${name}: ${msg}`)
} catch {
/* ignore */
}
}
}
}