import type { ScopeKind, ScopeRef } from "./stream.ts"; export class InvalidScopeError extends Error { override readonly name = "InvalidScopeError"; } const VALID_KINDS: readonly ScopeKind[] = ["task", "session", "machine"]; function sanitizeToken(s: string): string { return s.replace(/[.\s-]/g, "_").toLowerCase(); } function validate(scope: ScopeRef): void { if (!VALID_KINDS.includes(scope.scopeKind)) { throw new InvalidScopeError( `scopeKind must be one of ${VALID_KINDS.join("|")}, got: ${scope.scopeKind}`, ); } if (!scope.scopeId || scope.scopeId.length === 0) { throw new InvalidScopeError("scopeId must be a non-empty string"); } } export function messagesBucket(scope: ScopeRef): string { validate(scope); return `sesh_messages_${sanitizeToken(scope.scopeKind)}_${sanitizeToken(scope.scopeId)}`; } export function tasksBucket(scope: ScopeRef): string { validate(scope); return `sesh_tasks_${sanitizeToken(scope.scopeKind)}_${sanitizeToken(scope.scopeId)}`; } export function artifactsBucket(scope: ScopeRef): string { validate(scope); return `sesh_artifacts_${sanitizeToken(scope.scopeKind)}_${sanitizeToken(scope.scopeId)}`; } export function objectsBucket(scope: ScopeRef): string { validate(scope); return `sesh_objects_${sanitizeToken(scope.scopeKind)}_${sanitizeToken(scope.scopeId)}`; } export type { ScopeKind, ScopeRef } from "./stream.ts";