Files
memind/mindspace-conversation-package-store.mjs
T
2026-07-02 21:14:43 +08:00

167 lines
5.3 KiB
JavaScript

import {
buildConversationPackageManifest,
createConversationArtifact,
createConversationPackageRecord,
} from './mindspace-conversation-package.mjs';
function storeError(message, code) {
return Object.assign(new Error(message), { code });
}
function requirePool(pool) {
if (!pool || typeof pool.query !== 'function') {
throw storeError('MindSpace conversation package store requires a queryable pool', 'missing_query_pool');
}
return pool;
}
function packageFromRow(row) {
if (!row) return null;
return createConversationPackageRecord({
id: row.id,
userId: row.user_id,
sessionId: row.session_id,
title: row.title,
status: row.status,
storagePrefix: row.storage_prefix,
manifestAssetId: row.manifest_asset_id,
createdAt: Number(row.created_at),
updatedAt: Number(row.updated_at),
});
}
function artifactFromRow(row) {
if (!row) return null;
return createConversationArtifact({
id: row.id,
packageId: row.package_id,
artifactKind: row.artifact_kind,
role: row.role,
assetId: row.asset_id,
pageId: row.page_id,
publicationId: row.publication_id,
agentRunId: row.agent_run_id,
messageId: row.message_id,
displayName: row.display_name,
mimeType: row.mime_type,
sizeBytes: row.size_bytes == null ? null : Number(row.size_bytes),
storageKey: row.storage_key,
canonicalUrl: row.canonical_url,
sortOrder: Number(row.sort_order ?? 0),
createdAt: Number(row.created_at),
});
}
export function createConversationPackageStore(pool) {
const db = requirePool(pool);
return {
async upsertPackage(input) {
const record = createConversationPackageRecord(input);
await db.query(
`INSERT INTO h5_conversation_packages
(id, user_id, session_id, title, status, storage_prefix, manifest_asset_id, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
title = VALUES(title),
status = VALUES(status),
storage_prefix = VALUES(storage_prefix),
manifest_asset_id = VALUES(manifest_asset_id),
updated_at = VALUES(updated_at)`,
[
record.id,
record.userId,
record.sessionId,
record.title,
record.status,
record.storagePrefix,
record.manifestAssetId,
record.createdAt,
record.updatedAt,
],
);
return record;
},
async getPackageBySession(userId, sessionId) {
const [rows] = await db.query(
`SELECT id, user_id, session_id, title, status, storage_prefix, manifest_asset_id, created_at, updated_at
FROM h5_conversation_packages
WHERE user_id = ? AND session_id = ?
LIMIT 1`,
[userId, sessionId],
);
return packageFromRow(rows?.[0]);
},
async upsertArtifact(input) {
const artifact = createConversationArtifact(input);
await db.query(
`INSERT INTO h5_conversation_artifacts
(id, package_id, artifact_kind, role, asset_id, page_id, publication_id, agent_run_id,
message_id, display_name, mime_type, size_bytes, storage_key, canonical_url, sort_order, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
artifact_kind = VALUES(artifact_kind),
role = VALUES(role),
asset_id = VALUES(asset_id),
page_id = VALUES(page_id),
publication_id = VALUES(publication_id),
agent_run_id = VALUES(agent_run_id),
message_id = VALUES(message_id),
display_name = VALUES(display_name),
mime_type = VALUES(mime_type),
size_bytes = VALUES(size_bytes),
storage_key = VALUES(storage_key),
canonical_url = VALUES(canonical_url),
sort_order = VALUES(sort_order)`,
[
artifact.id,
artifact.packageId,
artifact.artifactKind,
artifact.role,
artifact.assetId,
artifact.pageId,
artifact.publicationId,
artifact.agentRunId,
artifact.messageId,
artifact.displayName,
artifact.mimeType,
artifact.sizeBytes,
artifact.storageKey,
artifact.canonicalUrl,
artifact.sortOrder,
artifact.createdAt,
],
);
return artifact;
},
async listArtifacts(packageId) {
const [rows] = await db.query(
`SELECT id, package_id, artifact_kind, role, asset_id, page_id, publication_id, agent_run_id,
message_id, display_name, mime_type, size_bytes, storage_key, canonical_url, sort_order, created_at
FROM h5_conversation_artifacts
WHERE package_id = ?
ORDER BY sort_order ASC, created_at ASC, id ASC`,
[packageId],
);
return (rows ?? []).map(artifactFromRow);
},
async buildManifestForSession({ userId, sessionId }) {
const packageRecord = await this.getPackageBySession(userId, sessionId);
if (!packageRecord) return null;
const artifacts = await this.listArtifacts(packageRecord.id);
return buildConversationPackageManifest({ packageRecord, artifacts });
},
};
}
export const conversationPackageStoreInternals = {
artifactFromRow,
packageFromRow,
requirePool,
storeError,
};