UNPKG

@memori.ai/memori-react

Version:

[![npm version](https://img.shields.io/github/package-json/v/memori-ai/memori-react)](https://www.npmjs.com/package/@memori.ai/memori-react) ![Tests](https://github.com/memori-ai/memori-react/workflows/CI/badge.svg?branch=main) ![TypeScript Support](https

447 lines (394 loc) 11.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createChatPDFDocument = exports.formatChatHistoryForPDF = exports.generateChatPDFCSS = void 0; const message_1 = require("./message"); const utils_1 = require("./utils"); const generateChatPDFCSS = (options = {}) => { const { fontSize = '12pt', fontFamily = 'system-ui, -apple-system, sans-serif', lineHeight = '1.6', color = '#333', backgroundColor = '#fff', } = options; const baseStyles = ` @page { margin: 1in; size: A4; } @media print { * { -webkit-print-color-adjust: exact !important; color-adjust: exact !important; } body { font-family: ${fontFamily}; font-size: ${fontSize}; line-height: ${lineHeight}; color: ${color}; background-color: ${backgroundColor}; margin: 0; padding: 0; max-width: none; word-wrap: break-word; overflow-wrap: break-word; } h1, h2, h3, h4, h5, h6 { page-break-after: avoid; margin-top: 1.5em; margin-bottom: 0.5em; font-weight: 600; } h1 { font-size: 1.8em; } h2 { font-size: 1.5em; } h3 { font-size: 1.3em; } p { margin: 0 0 1em 0; orphans: 3; widows: 3; } pre, code { font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-size: 0.9em; background-color: #f5f5f5; border: 1px solid #ddd; border-radius: 3px; padding: 0.2em 0.4em; page-break-inside: avoid; } pre { padding: 1em; overflow-x: auto; white-space: pre; margin: 1em 0; } pre code { background: none; border: none; padding: 0; } blockquote { margin: 1em 0; padding-left: 1em; border-left: 3px solid #ddd; font-style: italic; page-break-inside: avoid; } ul, ol { margin: 1em 0; padding-left: 2em; } li { margin: 0.25em 0; page-break-inside: avoid; } table { border-collapse: collapse; width: 100%; margin: 1em 0; page-break-inside: avoid; } th, td { border: 1px solid #ddd; padding: 0.5em; text-align: left; } th { background-color: #f5f5f5; font-weight: 600; } a { color: #0066cc; text-decoration: none; } a:hover { text-decoration: underline; } img { max-width: 100%; height: auto; page-break-inside: avoid; } hr { margin: 2em 0; border: none; border-top: 1px solid #ddd; } .page-break { page-break-before: always; } .no-print { display: none !important; } } @media screen { body { font-family: ${fontFamily}; font-size: ${fontSize}; line-height: ${lineHeight}; color: ${color}; background-color: ${backgroundColor}; margin: 20px; padding: 20px; max-width: 800px; margin: 0 auto; } } `; const chatBubbleStyles = generateChatBubbleStyles(options.primaryColorRgb); return `<style>${baseStyles}${chatBubbleStyles}</style>`; }; exports.generateChatPDFCSS = generateChatPDFCSS; const generateChatBubbleStyles = (primaryColorRgb) => { const rgbValue = primaryColorRgb || '130, 70, 175'; return ` :root { --memori-primary-rgb: ${rgbValue}; } .chat-export-header { margin-bottom: 2em; padding-bottom: 1em; border-bottom: 2px solid #e5e7eb; } .chat-export-date { margin-top: 0.5em; color: #6b7280; font-size: 0.9em; } .chat-bubble-container { display: flex; align-items: flex-end; margin-bottom: 1em; page-break-inside: avoid; } .chat-bubble { display: inline-flex; max-width: 75%; flex-direction: column; padding: 10px 16px; border-radius: 12px; margin-bottom: 5px; box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.1), 0 1px 3px 0 rgba(0, 0, 0, 0.08); font-size: 0.9em; line-height: 1.5; word-wrap: break-word; overflow-wrap: break-word; } .chat-bubble-assistant { border-radius: 12px 12px 12px 0; margin-left: 0; margin-right: auto; background: #ffffff; color: #141515; border: 1px solid #e5e7eb; } .chat-bubble-user { border-radius: 12px 12px 0 12px; margin-left: auto; margin-right: 0; background: rgb(var(--memori-primary-rgb)); color: #ffffff; } .chat-bubble-content { margin: 0; } .chat-bubble-content p { margin: 0 0 0.5em 0; } .chat-bubble-content p:last-child { margin-bottom: 0; } .chat-bubble-content ul, .chat-bubble-content ol { padding-left: 1.5em; margin: 0.5em 0; } .chat-bubble-content a { color: inherit; text-decoration: underline; } .chat-bubble-user .chat-bubble-content a { color: #ffffff; text-decoration: underline; } .chat-bubble-assistant .chat-bubble-content a { color:rgb(var(--memori-primary-rgb)); text-decoration: underline; } .chat-bubble-timestamp { margin-top: 0.25em; font-size: 0.75em; opacity: 0.7; text-align: right; } .chat-bubble-assistant .chat-bubble-timestamp { text-align: left; } .chat-bubble-media { margin: 0.5em 0 0 0; padding-left: 1.5em; list-style-type: disc; } .chat-bubble-media li { margin: 0.25em 0; } .chat-bubble-content code { background-color: rgba(0, 0, 0, 0.1); padding: 0.2em 0.4em; border-radius: 3px; font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; font-size: 0.9em; } .chat-bubble-user .chat-bubble-content code { background-color: rgba(255, 255, 255, 0.2); } .chat-bubble-content pre { background-color: rgba(0, 0, 0, 0.05); padding: 1em; border-radius: 5px; overflow-x: auto; margin: 0.5em 0; border: 1px solid rgba(0, 0, 0, 0.1); } .chat-bubble-user .chat-bubble-content pre { background-color: rgba(255, 255, 255, 0.15); border-color: rgba(255, 255, 255, 0.2); } .chat-bubble-content pre code { background: none; padding: 0; } .chat-bubble-content table { width: 100%; border-collapse: collapse; margin: 0.5em 0; } .chat-bubble-content table th, .chat-bubble-content table td { border: 1px solid rgba(0, 0, 0, 0.1); padding: 0.5em; text-align: left; } .chat-bubble-user .chat-bubble-content table th, .chat-bubble-user .chat-bubble-content table td { border-color: rgba(255, 255, 255, 0.2); } .chat-bubble-content table th { background-color: rgba(0, 0, 0, 0.05); font-weight: 600; } .chat-bubble-user .chat-bubble-content table th { background-color: rgba(255, 255, 255, 0.1); } .chat-bubble-content blockquote { margin: 0.5em 0; padding-left: 1em; border-left: 3px solid rgba(0, 0, 0, 0.2); font-style: italic; } .chat-bubble-user .chat-bubble-content blockquote { border-left-color: rgba(255, 255, 255, 0.3); } .chat-bubble-content img { max-width: 100%; height: auto; border-radius: 5px; margin: 0.5em 0; } .chat-bubble-content h1, .chat-bubble-content h2, .chat-bubble-content h3, .chat-bubble-content h4, .chat-bubble-content h5, .chat-bubble-content h6 { margin: 0.5em 0 0.25em 0; font-weight: 600; } .chat-bubble-content h1 { font-size: 1.5em; } .chat-bubble-content h2 { font-size: 1.3em; } .chat-bubble-content h3 { font-size: 1.1em; } `; }; const formatMessageBubble = (message, language = 'en') => { const timestamp = message.timestamp ? new Intl.DateTimeFormat(language, { dateStyle: 'short', timeStyle: 'short', }).format(new Date(message.timestamp.endsWith('Z') ? message.timestamp : `${message.timestamp}Z`)) : ''; const cleanText = (0, message_1.stripAllInternalTags)(message.text || ''); const { text: renderedText } = (0, message_1.renderMsg)(cleanText, false, 'Reasoning...', false); const messageText = message.fromUser ? renderedText : (0, utils_1.stripOutputTags)(renderedText); const bubbleClass = message.fromUser ? 'chat-bubble chat-bubble-user' : 'chat-bubble chat-bubble-assistant'; let html = `<div class="chat-bubble-container">`; html += `<div class="${bubbleClass}">`; if (messageText.trim()) { html += `<div class="chat-bubble-content">${messageText}</div>`; } if (message.media && message.media.length > 0) { html += `<ul class="chat-bubble-media">`; message.media.forEach(media => { if (media.title) { html += `<li><a href="${media.url || '#'}">${media.title}</a></li>`; } else if (media.url) { html += `<li><a href="${media.url}">${media.url}</a></li>`; } }); html += `</ul>`; } if (timestamp) { html += `<div class="chat-bubble-timestamp">${timestamp}</div>`; } html += `</div>`; html += `</div>`; return html; }; const formatChatHeader = (memoriName, exportDate, conversationStartedLabel) => { return ` <div class="chat-export-header"> <h1>${memoriName} - Chat Export</h1> <p class="chat-export-date"> <strong>${conversationStartedLabel}</strong>: ${exportDate} </p> </div> `; }; const formatChatHistoryForPDF = (params) => { const { messages, memori, conversationStartedLabel, language = 'en' } = params; if (!messages || messages.length === 0) { return ''; } const memoriName = (memori === null || memori === void 0 ? void 0 : memori.name) || 'Assistant'; const exportDate = new Intl.DateTimeFormat(language, { dateStyle: 'long', timeStyle: 'short', }).format(new Date()); let html = formatChatHeader(memoriName, exportDate, conversationStartedLabel); messages.forEach(message => { html += formatMessageBubble(message, language); }); return html; }; exports.formatChatHistoryForPDF = formatChatHistoryForPDF; const createChatPDFDocument = (htmlContent, title, options = {}) => { const css = (0, exports.generateChatPDFCSS)(options); return ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>${title}</title> ${css} </head> <body> <div class="content"> ${htmlContent} </div> </body> </html> `; }; exports.createChatPDFDocument = createChatPDFDocument; //# sourceMappingURL=chatPdfExport.js.map