function registryError(message, code) { return Object.assign(new Error(message), { code }); } function requireMethod(target, methodName, code) { if (!target || typeof target[methodName] !== 'function') { throw registryError(`MindSpace conversation package registry requires ${methodName}`, code); } } export function createConversationPackageRegistry({ store, service } = {}) { requireMethod(store, 'upsertPackage', 'missing_conversation_package_store'); requireMethod(store, 'upsertArtifact', 'missing_conversation_package_store'); requireMethod(store, 'getPackageBySession', 'missing_conversation_package_store'); requireMethod(store, 'listArtifacts', 'missing_conversation_package_store'); requireMethod(service, 'putConversationManifest', 'missing_mindspace_service'); requireMethod(service, 'buildConversationManifest', 'missing_mindspace_service'); requireMethod(service, 'putPackageObject', 'missing_mindspace_service'); requireMethod(service, 'getPackageObject', 'missing_mindspace_service'); return { async ensurePackage(input) { return store.upsertPackage(input); }, async recordArtifact(input) { return store.upsertArtifact(input); }, async writeManifestForSession({ userId, sessionId }) { const packageRecord = await store.getPackageBySession(userId, sessionId); if (!packageRecord) return null; const artifacts = await store.listArtifacts(packageRecord.id); return service.putConversationManifest({ packageRecord, artifacts }); }, async putObjectForSession({ userId, sessionId, title = null, relativePath, body }) { const packageRecord = await store.upsertPackage({ userId, sessionId, title }); const writeResult = await service.putPackageObject({ packageRecord, relativePath, body }); return { packageRecord, writeResult }; }, async readManifestForSession({ userId, sessionId }) { const packageRecord = await store.getPackageBySession(userId, sessionId); if (!packageRecord) return null; const artifacts = await store.listArtifacts(packageRecord.id); return service.buildConversationManifest({ packageRecord, artifacts }); }, async readArtifactObject({ userId, sessionId, artifactId }) { const packageRecord = await store.getPackageBySession(userId, sessionId); if (!packageRecord) return null; const artifacts = await store.listArtifacts(packageRecord.id); const artifact = artifacts.find((item) => item.id === artifactId); if (!artifact?.storageKey) return null; const prefix = `${packageRecord.storagePrefix}/`; if (!artifact.storageKey.startsWith(prefix)) { throw registryError('conversation artifact storage key is outside package', 'invalid_artifact_storage_key'); } const body = await service.getPackageObject({ packageRecord, relativePath: artifact.storageKey.slice(prefix.length), }); return { packageRecord, artifact, body }; }, }; } export const conversationPackageRegistryInternals = { registryError, requireMethod, };