@pixerate/editor 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/extensions/index.cjs +2 -1
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +1 -1
- package/dist/extensions/index.d.ts +1 -1
- package/dist/extensions/index.js +2 -1
- package/dist/extensions/index.js.map +1 -1
- package/dist/grammar/index.cjs.map +1 -1
- package/dist/grammar/index.d.cts +2 -2
- package/dist/grammar/index.d.ts +2 -2
- package/dist/grammar/index.js.map +1 -1
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/{tokens-CE6SS_hd.d.cts → tokens-7kRTEtPb.d.cts} +5 -3
- package/dist/{tokens-CE6SS_hd.d.ts → tokens-7kRTEtPb.d.ts} +5 -3
- package/package.json +23 -18
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/grammar/tokens.ts","../src/grammar/tokenizer.ts","../src/grammar/resolver.ts","../src/grammar/sourcemap.ts","../src/extensions/gradient-text.ts","../src/extensions/slash-commands.ts","../src/extensions/template-suggestions.ts","../src/extensions/loading-node.ts","../src/extensions/SmilieReplacer.ts","../src/extensions/ColorHighlighter.ts","../src/extensions/FontSize.ts","../src/extensions/rich-text-preset.ts","../src/serializers/plain-text.ts","../src/controller.ts"],"sourcesContent":["/**\n * Canonical regex patterns for prompt editing tokens.\n */\nexport const TEMPLATE_REGEX = /{{\\s*([^}]+?)\\s*}}/g;\nexport const VARIABLE_REGEX = /(?<!\\{)\\{([^{}]+)\\}(?!\\})/g;\nexport const INSTRUCTION_REGEX = /__(.+?)__/g;\n\n// Backward-compatible camelCase aliases\nexport const templateRegex = TEMPLATE_REGEX;\nexport const variableRegex = VARIABLE_REGEX;\nexport const instructionRegex = INSTRUCTION_REGEX;\n\nexport type TokenType = \"template\" | \"variable\" | \"instruction\" | \"text\";\n\nexport interface Token {\n type: TokenType;\n raw: string;\n value: string;\n start: number;\n end: number;\n}\n\nexport interface TemplateVersion {\n id: string;\n version: string;\n body: string;\n createdAt?: string;\n}\n\nexport interface Template {\n id?: string;\n name: string;\n body?: string;\n latestVersion?: string;\n versions?: TemplateVersion[];\n color?: string;\n}\n\nexport interface ColorGradient {\n from: string;\n to: string;\n}\n","import {\n TEMPLATE_REGEX,\n VARIABLE_REGEX,\n INSTRUCTION_REGEX,\n Token,\n} from \"./tokens\";\n\ninterface RawMatch {\n type: \"template\" | \"variable\" | \"instruction\";\n raw: string;\n value: string;\n start: number;\n end: number;\n}\n\n/**\n * Parses any prompt string into an array of typed tokens in linear order.\n * Plain text between tokens is preserved as `{ type: 'text' }`.\n */\nexport function tokenizePrompt(text: string): Token[] {\n if (!text) {\n return [];\n }\n\n const rawMatches: RawMatch[] = [];\n\n // Match {{template}}\n const tmplRegex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = tmplRegex.exec(text)) !== null) {\n rawMatches.push({\n type: \"template\",\n raw: match[0],\n value: match[1].trim(),\n start: match.index,\n end: match.index + match[0].length,\n });\n }\n\n // Match {variable}\n const varRegex = new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags);\n while ((match = varRegex.exec(text)) !== null) {\n // Avoid double matching if overlapping with template\n const start = match.index;\n const end = start + match[0].length;\n const overlaps = rawMatches.some(\n (m) => !(end <= m.start || start >= m.end),\n );\n if (!overlaps) {\n rawMatches.push({\n type: \"variable\",\n raw: match[0],\n value: match[1].trim(),\n start,\n end,\n });\n }\n }\n\n // Match __instruction__\n const instRegex = new RegExp(\n INSTRUCTION_REGEX.source,\n INSTRUCTION_REGEX.flags,\n );\n while ((match = instRegex.exec(text)) !== null) {\n const start = match.index;\n const end = start + match[0].length;\n const overlaps = rawMatches.some(\n (m) => !(end <= m.start || start >= m.end),\n );\n if (!overlaps) {\n rawMatches.push({\n type: \"instruction\",\n raw: match[0],\n value: match[1].trim(),\n start,\n end,\n });\n }\n }\n\n // Sort matches by start index\n rawMatches.sort((a, b) => a.start - b.start);\n\n const tokens: Token[] = [];\n let currentIdx = 0;\n\n for (const m of rawMatches) {\n if (m.start > currentIdx) {\n const textChunk = text.slice(currentIdx, m.start);\n tokens.push({\n type: \"text\",\n raw: textChunk,\n value: textChunk,\n start: currentIdx,\n end: m.start,\n });\n }\n tokens.push({\n type: m.type,\n raw: m.raw,\n value: m.value,\n start: m.start,\n end: m.end,\n });\n currentIdx = m.end;\n }\n\n if (currentIdx < text.length) {\n const textChunk = text.slice(currentIdx);\n tokens.push({\n type: \"text\",\n raw: textChunk,\n value: textChunk,\n start: currentIdx,\n end: text.length,\n });\n }\n\n return tokens;\n}\n","import {\n TEMPLATE_REGEX,\n VARIABLE_REGEX,\n INSTRUCTION_REGEX,\n Template,\n TemplateVersion,\n} from \"./tokens\";\n\n/**\n * Finds the latest version of a template based on `latestVersion` or last version entry.\n */\nexport function getLatestVersion(\n template: Template,\n): TemplateVersion | undefined {\n if (!template.versions || template.versions.length === 0) {\n if (template.body !== undefined) {\n return {\n id: template.id || \"default\",\n version: \"1.0\",\n body: template.body,\n };\n }\n return undefined;\n }\n if (template.latestVersion) {\n const found = template.versions.find(\n (v) => v.version === template.latestVersion,\n );\n if (found) return found;\n }\n return template.versions[template.versions.length - 1];\n}\n\nexport interface ResolveTemplatesOptions {\n bindings?: Record<string, string>;\n maxDepth?: number;\n}\n\n/**\n * Recursively resolves template tags `{{template_name}}` in a given text.\n * Detects circular dependencies and returns \"[Template loop detected]\".\n */\nexport function resolveTemplates(\n text: string,\n templates: Template[] = [],\n options?: ResolveTemplatesOptions,\n): string {\n const templateMap = new Map<string, Template>();\n for (const t of templates) {\n templateMap.set(t.name, t);\n }\n\n const maxDepth = options?.maxDepth ?? 10;\n\n function resolveRecursive(\n currentText: string,\n visited: Set<string>,\n depth: number,\n ): string {\n if (depth > maxDepth) {\n return \"[Template max depth exceeded]\";\n }\n\n let result = currentText;\n const regex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(result)) !== null) {\n const [fullMatch, rawTemplateName] = match;\n const templateName = rawTemplateName.trim();\n\n if (visited.has(templateName)) {\n return \"[Template loop detected]\";\n }\n\n const template = templateMap.get(templateName);\n if (!template) {\n continue;\n }\n\n let versionBody: string | undefined;\n const boundVersionId = options?.bindings?.[templateName];\n\n if (boundVersionId && template.versions) {\n const boundVersion = template.versions.find(\n (v) => v.id === boundVersionId || v.version === boundVersionId,\n );\n versionBody = boundVersion?.body;\n } else {\n const latest = getLatestVersion(template);\n versionBody = latest?.body ?? template.body;\n }\n\n if (versionBody === undefined) {\n continue;\n }\n\n const nextVisited = new Set(visited);\n nextVisited.add(templateName);\n\n const resolvedBody = resolveRecursive(\n versionBody,\n nextVisited,\n depth + 1,\n );\n\n if (\n resolvedBody === \"[Template loop detected]\" ||\n resolvedBody === \"[Template max depth exceeded]\"\n ) {\n return resolvedBody;\n }\n\n result = result.replace(fullMatch, resolvedBody);\n regex.lastIndex = 0;\n }\n\n return result;\n }\n\n return resolveRecursive(text, new Set(), 0);\n}\n\n/**\n * Replaces `{variableName}` with values from a dictionary.\n */\nexport function resolveVariables(\n text: string,\n values: Record<string, string | number>,\n): string {\n if (!text) return \"\";\n return text.replace(\n new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags),\n (fullMatch, varName) => {\n const key = varName.trim();\n if (Object.prototype.hasOwnProperty.call(values, key)) {\n return String(values[key]);\n }\n return fullMatch;\n },\n );\n}\n\n/**\n * Extracts unique template names referenced in text.\n */\nexport function extractTemplateNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n\n/**\n * Extracts unique variable names referenced in text.\n */\nexport function extractVariableNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n\n/**\n * Extracts unique instruction names referenced in text.\n */\nexport function extractInstructionNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(INSTRUCTION_REGEX.source, INSTRUCTION_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n","import { Template } from \"./tokens\";\nimport { getLatestVersion, resolveTemplates } from \"./resolver\";\n\nexport interface SourceMapSegment {\n resolvedStart: number;\n resolvedEnd: number;\n source: \"raw\" | \"template\";\n rawStart: number;\n rawEnd: number;\n templateName?: string;\n}\n\n/**\n * Resolves templates in text while tracking character offset mapping\n * between the raw input and the fully resolved output.\n */\nexport function resolveTemplatesWithMapping(\n text: string,\n templates: Template[] = [],\n templateBindings?: Record<string, string>,\n): { text: string; map: SourceMapSegment[] } {\n if (!templates || templates.length === 0 || !text.includes(\"{{\")) {\n return {\n text,\n map: [\n {\n resolvedStart: 0,\n resolvedEnd: text.length,\n source: \"raw\",\n rawStart: 0,\n rawEnd: text.length,\n },\n ],\n };\n }\n\n const templateMap = new Map(templates.map((t) => [t.name, t]));\n const regex = /{{\\s*([^}]+?)\\s*}}/g;\n let match: RegExpExecArray | null;\n let lastIndex = 0;\n let resolvedText = \"\";\n const map: SourceMapSegment[] = [];\n\n while ((match = regex.exec(text)) !== null) {\n const [fullMatch, rawTemplateName] = match;\n const templateName = rawTemplateName.trim();\n const matchIndex = match.index;\n\n // Add raw text preceding this template match\n if (matchIndex > lastIndex) {\n const rawSegment = text.substring(lastIndex, matchIndex);\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + rawSegment.length,\n source: \"raw\",\n rawStart: lastIndex,\n rawEnd: matchIndex,\n });\n resolvedText += rawSegment;\n }\n\n let resolvedBody = fullMatch;\n let isTemplate = false;\n\n if (templateMap.has(templateName)) {\n const template = templateMap.get(templateName)!;\n let versionBody: string | undefined;\n const boundVersionId = templateBindings?.[templateName];\n\n if (boundVersionId && template.versions) {\n const boundVersion = template.versions.find(\n (v) => v.id === boundVersionId || v.version === boundVersionId,\n );\n versionBody = boundVersion?.body;\n } else {\n const latestVersion = getLatestVersion(template);\n versionBody = latestVersion?.body ?? template.body;\n }\n\n if (versionBody !== undefined) {\n resolvedBody = resolveTemplates(versionBody, templates, {\n bindings: templateBindings,\n });\n isTemplate = true;\n }\n }\n\n if (isTemplate) {\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + resolvedBody.length,\n source: \"template\",\n rawStart: matchIndex,\n rawEnd: matchIndex + fullMatch.length,\n templateName,\n });\n resolvedText += resolvedBody;\n } else {\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + fullMatch.length,\n source: \"raw\",\n rawStart: matchIndex,\n rawEnd: matchIndex + fullMatch.length,\n });\n resolvedText += fullMatch;\n }\n\n lastIndex = matchIndex + fullMatch.length;\n }\n\n // Add any remaining raw text after the final match\n if (lastIndex < text.length) {\n const rawSegment = text.substring(lastIndex);\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + rawSegment.length,\n source: \"raw\",\n rawStart: lastIndex,\n rawEnd: text.length,\n });\n resolvedText += rawSegment;\n }\n\n return { text: resolvedText, map };\n}\n\n/**\n * Maps an offset in resolved text back to the corresponding offset in raw text.\n */\nexport function mapResolvedOffsetToRaw(\n resolvedOffset: number,\n map: SourceMapSegment[],\n): number {\n for (let i = 0; i < map.length; i++) {\n const seg = map[i];\n const isLast = i === map.length - 1;\n const inRange = isLast\n ? resolvedOffset >= seg.resolvedStart && resolvedOffset <= seg.resolvedEnd\n : resolvedOffset >= seg.resolvedStart && resolvedOffset < seg.resolvedEnd;\n\n if (inRange) {\n if (seg.source === \"raw\") {\n return seg.rawStart + (resolvedOffset - seg.resolvedStart);\n } else {\n // Pointing into a resolved template - return start of template tag\n return seg.rawStart;\n }\n }\n }\n return resolvedOffset;\n}\n\n/**\n * Maps an offset in raw text to the corresponding offset in resolved text.\n */\nexport function mapRawOffsetToResolved(\n rawOffset: number,\n map: SourceMapSegment[],\n): number {\n for (let i = 0; i < map.length; i++) {\n const seg = map[i];\n const isLast = i === map.length - 1;\n const inRange = isLast\n ? rawOffset >= seg.rawStart && rawOffset <= seg.rawEnd\n : rawOffset >= seg.rawStart && rawOffset < seg.rawEnd;\n\n if (inRange) {\n if (seg.source === \"raw\") {\n return seg.resolvedStart + (rawOffset - seg.rawStart);\n } else {\n return seg.resolvedStart;\n }\n }\n }\n return rawOffset;\n}\n","import { Mark } from \"@tiptap/core\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport type { Node as ProsemirrorNode } from \"@tiptap/pm/model\";\nimport type { EditorState } from \"@tiptap/pm/state\";\nimport { TEMPLATE_REGEX, VARIABLE_REGEX, INSTRUCTION_REGEX, ColorGradient } from \"../grammar/tokens\";\n\nexport interface GradientTextOptions {\n templateColorMap: Map<string, ColorGradient>;\n speed?: number;\n jsonVariables?: string[] | Set<string>;\n onTemplateClick?: (templateName: string, event: MouseEvent) => void;\n}\n\nconst createGradientDecorations = (\n doc: ProsemirrorNode,\n options: GradientTextOptions,\n): Decoration[] => {\n const decorations: Decoration[] = [];\n const speed = options.speed ?? 1;\n const jsonVarSet = options.jsonVariables\n ? options.jsonVariables instanceof Set\n ? options.jsonVariables\n : new Set(options.jsonVariables)\n : null;\n\n doc.descendants((node, pos) => {\n if (node.isText) {\n const text = node.text || \"\";\n let match: RegExpExecArray | null;\n\n // 1. Template: {{templateName}}\n const tmplRegex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n while ((match = tmplRegex.exec(text)) !== null) {\n const templateName = match[1].trim();\n const colors = options.templateColorMap?.get(templateName);\n\n if (colors) {\n const start = pos + match.index;\n const end = start + match[0].length;\n const { from: colorFrom, to: colorTo } = colors;\n\n const style = `--bg-size: ${\n speed * 300\n }%; --color-from: ${colorFrom}; --color-to: ${colorTo}; caret-color: #111 !important;`;\n\n decorations.push(\n Decoration.inline(start, end, {\n class:\n \"inline animate-gradient bg-gradient-to-r from-[var(--color-from)] via-[var(--color-to)] to-[var(--color-from)] bg-[length:var(--bg-size)_100%] bg-clip-text text-transparent border border-(--color-to)/20 px-1 py-0.5 rounded-sm cursor-pointer\",\n style,\n \"data-template\": templateName,\n }),\n );\n }\n }\n\n // 2. Instruction: __text__\n const instRegex = new RegExp(\n INSTRUCTION_REGEX.source,\n INSTRUCTION_REGEX.flags,\n );\n while ((match = instRegex.exec(text)) !== null) {\n const content = match[1].trim();\n const colors = options.templateColorMap?.get(content) || {\n from: \"#ffaa40\",\n to: \"#9c40ff\",\n };\n\n const start = pos + match.index;\n const end = start + match[0].length;\n const { from: colorFrom, to: colorTo } = colors;\n\n const style = `--bg-size: ${\n speed * 300\n }%; --color-from: ${colorFrom}; --color-to: ${colorTo}; caret-color: #111 !important;`;\n\n decorations.push(\n Decoration.inline(start, end, {\n class:\n \"italic animate-gradient bg-gradient-to-r from-rose-400 from-50% to-violet-500 to-50% bg-size-[200%_100%] bg-clip-text text-transparent inline-flex items-baseline gap-0.5\",\n style,\n }),\n );\n }\n\n // 3. Variable: {variableName}\n const varRegex = new RegExp(\n VARIABLE_REGEX.source,\n VARIABLE_REGEX.flags,\n );\n while ((match = varRegex.exec(text)) !== null) {\n const variableName = match[1].trim();\n const start = pos + match.index;\n const end = start + match[0].length;\n const isJsonVar = jsonVarSet?.has(variableName);\n\n decorations.push(\n Decoration.inline(start, end, {\n class: isJsonVar\n ? \"bg-violet-400/40 border-b-4 border-rose-300 dark:border-rose-800 inline-flex items-baseline px-1 py-0 text-foreground/80 gap-0.5 rounded-xs\"\n : \"bg-rose-400/40 border-b-4 border-violet-300 dark:border-violet-800 inline-flex items-baseline px-1 py-0 text-foreground/80 gap-0.5 rounded-xs\",\n \"data-variable\": variableName,\n }),\n );\n }\n }\n });\n\n return decorations;\n};\n\nexport const GradientText = Mark.create<GradientTextOptions>({\n name: \"gradientText\",\n\n addOptions() {\n return {\n templateColorMap: new Map(),\n speed: 1,\n jsonVariables: undefined,\n onTemplateClick: undefined,\n };\n },\n\n renderHTML({ HTMLAttributes }) {\n const defaultColors = {\n from: \"#ffaa40\",\n to: \"#9c40ff\",\n };\n const speed = this.options.speed ?? 1;\n const style = `--bg-size: ${speed * 300}%; --color-from: ${\n defaultColors.from\n }; --color-to: ${defaultColors.to}; caret-color: #111 !important;`;\n\n return [\n \"span\",\n {\n class:\n \"inline animate-gradient bg-gradient-to-r from-[var(--color-from)] via-[var(--color-to)] to-[var(--color-from)] bg-[length:var(--bg-size)_100%] bg-clip-text text-transparent\",\n style,\n ...HTMLAttributes,\n },\n 0,\n ];\n },\n\n parseHTML() {\n return [\n {\n tag: \"span\",\n getAttrs: (node) =>\n (node as HTMLElement).classList.contains(\"animate-gradient\") &&\n (node as HTMLElement).classList.contains(\"bg-clip-text\") &&\n null,\n },\n ];\n },\n\n addProseMirrorPlugins() {\n const markOptions = this.options;\n\n return [\n new Plugin({\n state: {\n init(_, { doc }) {\n return DecorationSet.create(\n doc,\n createGradientDecorations(doc, markOptions),\n );\n },\n apply(tr, value: DecorationSet) {\n const newDoc = tr.doc;\n if (tr.docChanged) {\n return DecorationSet.create(\n newDoc,\n createGradientDecorations(newDoc, markOptions),\n );\n }\n return value.map(tr.mapping, newDoc);\n },\n },\n props: {\n decorations(state: EditorState) {\n return (this as any).getState(state) as DecorationSet;\n },\n handleClickOn(view, pos, _node, _nodePos, event) {\n const decorationSet = (this as any).getState(\n view.state,\n ) as DecorationSet;\n const decorations = decorationSet.find(pos, pos + 1);\n\n for (const decoration of decorations) {\n const decorationWithAttrs = decoration as any;\n const templateName =\n decorationWithAttrs.type?.attrs?.[\"data-template\"];\n if (templateName) {\n if (markOptions.onTemplateClick) {\n markOptions.onTemplateClick(templateName, event as MouseEvent);\n }\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(\n new CustomEvent(\"show-gradient-popover\", {\n detail: {\n templateName,\n target: event.target,\n },\n }),\n );\n }\n return true;\n }\n }\n return false;\n },\n },\n }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin } from \"@tiptap/pm/state\";\n\nexport interface SlashCommandMatchData {\n match: RegExpMatchArray;\n query: string;\n from: number;\n to: number;\n coords: { top: number; left: number; bottom: number; right: number };\n}\n\nexport interface SlashCommandsOptions {\n trigger?: string;\n onMatch?: (data: SlashCommandMatchData) => void;\n onClear?: () => void;\n containerId?: string;\n}\n\nexport const SlashCommands = Extension.create<SlashCommandsOptions>({\n name: \"slashCommands\",\n\n addOptions() {\n return {\n trigger: \"/\",\n onMatch: undefined,\n onClear: undefined,\n containerId: undefined,\n };\n },\n\n addProseMirrorPlugins() {\n const opts = this.options;\n\n return [\n new Plugin({\n view() {\n return {\n update(view) {\n const { state } = view;\n const { selection } = state;\n const { $from } = selection;\n\n if (!$from.parent.isTextblock) {\n opts.onClear?.();\n return;\n }\n\n const textBeforeCursor = $from.parent.textBetween(\n 0,\n $from.parentOffset,\n );\n\n const slashMatch = textBeforeCursor.match(\n /(?:^|\\s)\\/([a-zA-Z0-9_-]*)$/,\n );\n\n if (slashMatch) {\n const matchIndex = slashMatch.index ?? 0;\n const offsetInParent =\n matchIndex + (slashMatch[0].startsWith(\" \") ? 1 : 0);\n const matchFrom = $from.start() + offsetInParent;\n const matchTo = $from.pos;\n const coords = view.coordsAtPos($from.pos);\n\n let relativeCoords = {\n top: coords.top,\n left: coords.left,\n bottom: coords.bottom,\n right: coords.right,\n };\n\n if (opts.containerId && typeof document !== \"undefined\") {\n const container = document.getElementById(opts.containerId);\n if (container) {\n const rect = container.getBoundingClientRect();\n relativeCoords = {\n top: coords.bottom - rect.top + 5,\n left: coords.left - rect.left,\n bottom: coords.bottom - rect.top,\n right: coords.right - rect.left,\n };\n }\n }\n\n opts.onMatch?.({\n match: slashMatch,\n query: slashMatch[1] || \"\",\n from: matchFrom,\n to: matchTo,\n coords: relativeCoords,\n });\n } else {\n opts.onClear?.();\n }\n },\n };\n },\n }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport Suggestion, { SuggestionOptions } from \"@tiptap/suggestion\";\nimport { Template } from \"../grammar/tokens\";\n\nexport interface TemplateSuggestionsOptions {\n templates: Template[];\n char?: string;\n onSuggestion?: (props: {\n query: string;\n range: { from: number; to: number };\n clientRect?: (() => DOMRect | null) | null;\n items: Template[];\n command: (props: { name: string }) => void;\n }) => void;\n}\n\nexport const TemplateSuggestions = Extension.create<TemplateSuggestionsOptions>({\n name: \"templateSuggestions\",\n\n addOptions() {\n return {\n templates: [],\n char: \"{{\",\n onSuggestion: undefined,\n };\n },\n\n addProseMirrorPlugins() {\n const opts = this.options;\n\n const suggestionConfig: Omit<SuggestionOptions<Template>, \"editor\"> = {\n char: opts.char || \"{{\",\n items: ({ query }) => {\n const lower = query.toLowerCase();\n return (opts.templates || []).filter((t) =>\n t.name.toLowerCase().includes(lower),\n );\n },\n command: ({ editor, range, props }) => {\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .insertContent(`{{${props.name}}}`)\n .run();\n },\n render: () => {\n return {\n onStart: (props) => {\n opts.onSuggestion?.(props as any);\n },\n onUpdate: (props) => {\n opts.onSuggestion?.(props as any);\n },\n onExit: () => {\n opts.onSuggestion?.({\n query: \"\",\n range: { from: 0, to: 0 },\n items: [],\n command: () => {},\n });\n },\n };\n },\n };\n\n return [\n Suggestion({\n editor: this.editor,\n ...suggestionConfig,\n }),\n ];\n },\n});\n","import { Node, mergeAttributes } from \"@tiptap/core\";\n\nexport const LoadingNode = Node.create({\n name: \"loadingNode\",\n group: \"inline\",\n inline: true,\n selectable: true,\n atom: true,\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-id\"),\n renderHTML: (attributes) => {\n if (!attributes.id) return {};\n return { \"data-id\": attributes.id };\n },\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'span[data-type=\"loading\"]',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-type\": \"loading\",\n class: \"inline-flex items-center px-1.5 py-0.5 text-xs text-muted-foreground animate-pulse\",\n }),\n \"⏳\",\n ];\n },\n});\n","import { Extension, textInputRule } from \"@tiptap/core\";\n\nexport const SmilieReplacer = Extension.create({\n name: \"smilieReplacer\",\n\n addInputRules() {\n return [\n textInputRule({ find: /-___- $/, replace: \"😑 \" }),\n textInputRule({ find: /:'-\\) $/, replace: \"😂 \" }),\n textInputRule({ find: /':-\\) $/, replace: \"😅 \" }),\n textInputRule({ find: /':-D $/, replace: \"😅 \" }),\n textInputRule({ find: />:-\\) $/, replace: \"😆 \" }),\n textInputRule({ find: /-__- $/, replace: \"😑 \" }),\n textInputRule({ find: /':-\\( $/, replace: \"😓 \" }),\n textInputRule({ find: /:'-\\( $/, replace: \"😢 \" }),\n textInputRule({ find: />:-\\( $/, replace: \"😠 \" }),\n textInputRule({ find: /O:-\\) $/, replace: \"😇 \" }),\n textInputRule({ find: /:'\\) $/, replace: \"😂 \" }),\n textInputRule({ find: /:-D $/, replace: \"😃 \" }),\n textInputRule({ find: /':\\) $/, replace: \"😅 \" }),\n textInputRule({ find: /;-\\) $/, replace: \"😉 \" }),\n textInputRule({ find: /B-\\) $/, replace: \"😎 \" }),\n textInputRule({ find: /:-\\* $/, replace: \"😘 \" }),\n textInputRule({ find: /:-\\) $/, replace: \"🙂 \" }),\n textInputRule({ find: /-_- $/, replace: \"😑 \" }),\n textInputRule({ find: /:-O $/, replace: \"😮 \" }),\n textInputRule({ find: /:-P $/, replace: \"😛 \" }),\n textInputRule({ find: /:-p $/, replace: \"😛 \" }),\n textInputRule({ find: /:-\\/ $/, replace: \"😕 \" }),\n textInputRule({ find: /:-\\( $/, replace: \"😞 \" }),\n textInputRule({ find: /:'\\( $/, replace: \"😢 \" }),\n textInputRule({ find: /:D $/, replace: \"😃 \" }),\n textInputRule({ find: /=D $/, replace: \"😃 \" }),\n textInputRule({ find: /;\\) $/, replace: \"😉 \" }),\n textInputRule({ find: /B\\) $/, replace: \"😎 \" }),\n textInputRule({ find: /:\\) $/, replace: \"🙂 \" }),\n textInputRule({ find: /=\\) $/, replace: \"🙂 \" }),\n textInputRule({ find: /:O $/, replace: \"😮 \" }),\n textInputRule({ find: /:P $/, replace: \"😛 \" }),\n textInputRule({ find: /:p $/, replace: \"😛 \" }),\n textInputRule({ find: /:\\/ $/, replace: \"😕 \" }),\n textInputRule({ find: /:\\( $/, replace: \"😞 \" }),\n textInputRule({ find: /<3 $/, replace: \"❤️ \" }),\n textInputRule({ find: /<\\/3 $/, replace: \"💔 \" }),\n textInputRule({ find: /\\/shrug $/, replace: \"¯\\\\_(ツ)_/¯ \" }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport type { Node as ProsemirrorNode } from \"@tiptap/pm/model\";\n\nexport function findHexColors(doc: ProsemirrorNode): DecorationSet {\n const hexColorRegex = /(#[0-9a-fA-F]{3,8})\\b/g;\n const decorations: Decoration[] = [];\n\n doc.descendants((node, position) => {\n if (!node.text) return;\n\n let match: RegExpExecArray | null;\n while ((match = hexColorRegex.exec(node.text)) !== null) {\n const color = match[0];\n const from = position + match.index;\n const to = from + color.length;\n\n decorations.push(\n Decoration.inline(from, to, {\n class: \"color-highlight px-1 py-0.5 rounded text-xs font-mono border\",\n style: `--color: ${color}; background-color: ${color}20; border-color: ${color}; color: ${color};`,\n }),\n );\n }\n });\n\n return DecorationSet.create(doc, decorations);\n}\n\nexport const ColorHighlighter = Extension.create({\n name: \"colorHighlighter\",\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n state: {\n init(_, { doc }) {\n return findHexColors(doc);\n },\n apply(transaction, oldState) {\n return transaction.docChanged ? findHexColors(transaction.doc) : oldState;\n },\n },\n props: {\n decorations(state) {\n return (this as any).getState(state);\n },\n },\n }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport \"@tiptap/extension-text-style\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n fontSize: {\n setFontSize: (size: string) => ReturnType;\n unsetFontSize: () => ReturnType;\n };\n }\n}\n\nexport const FontSize = Extension.create({\n name: \"fontSize\",\n\n addOptions() {\n return {\n types: [\"textStyle\"],\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n fontSize: {\n default: null,\n parseHTML: (element) =>\n element.style.fontSize.replace(/['\"]+/g, \"\"),\n renderHTML: (attributes) => {\n if (!attributes.fontSize) {\n return {};\n }\n return {\n style: `font-size: ${attributes.fontSize}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setFontSize:\n (fontSize: string) =>\n ({ chain }) =>\n chain().setMark(\"textStyle\", { fontSize }).run(),\n unsetFontSize:\n () =>\n ({ chain }) =>\n chain()\n .setMark(\"textStyle\", { fontSize: null })\n .removeEmptyTextStyle()\n .run(),\n };\n },\n});\n\nexport default FontSize;\n","import type { Extensions } from \"@tiptap/core\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport Color from \"@tiptap/extension-color\";\nimport Highlight from \"@tiptap/extension-highlight\";\nimport Link from \"@tiptap/extension-link\";\nimport TaskList from \"@tiptap/extension-task-list\";\nimport TaskItem from \"@tiptap/extension-task-item\";\nimport TextAlign from \"@tiptap/extension-text-align\";\nimport TextStyle from \"@tiptap/extension-text-style\";\nimport Typography from \"@tiptap/extension-typography\";\nimport Underline from \"@tiptap/extension-underline\";\nimport Placeholder from \"@tiptap/extension-placeholder\";\nimport CharacterCount from \"@tiptap/extension-character-count\";\n\nimport { SmilieReplacer } from \"./SmilieReplacer\";\nimport { ColorHighlighter } from \"./ColorHighlighter\";\nimport { FontSize } from \"./FontSize\";\n\nexport interface RichTextPresetOptions {\n placeholder?: string | ((props: { node: any }) => string);\n characterLimit?: number;\n openLinksOnClick?: boolean;\n enableSmilies?: boolean;\n enableColorHighlighter?: boolean;\n headingLevels?: (1 | 2 | 3 | 4 | 5 | 6)[];\n}\n\n/**\n * Creates a standard rich-text extensions bundle with full formatting support.\n */\nexport function createRichTextPreset(\n options: RichTextPresetOptions = {},\n): Extensions {\n const {\n placeholder = \"Start typing...\",\n characterLimit,\n openLinksOnClick = false,\n enableSmilies = true,\n enableColorHighlighter = true,\n headingLevels = [1, 2, 3, 4],\n } = options;\n\n const extensions: Extensions = [\n StarterKit.configure({\n orderedList: {\n HTMLAttributes: {\n class: \"list-decimal pl-4\",\n },\n },\n bulletList: {\n HTMLAttributes: {\n class: \"list-disc pl-4\",\n },\n },\n heading: {\n levels: headingLevels,\n HTMLAttributes: {\n class: \"font-bold tracking-tight\",\n },\n },\n }),\n TextStyle,\n Color,\n Highlight.configure({ multicolor: true }),\n Underline,\n Typography,\n TextAlign.configure({\n types: [\"heading\", \"paragraph\"],\n }),\n Link.configure({\n openOnClick: openLinksOnClick,\n autolink: true,\n defaultProtocol: \"https\",\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n class: \"text-blue-500 underline underline-offset-2\",\n },\n }),\n TaskList,\n TaskItem.configure({\n nested: true,\n }),\n FontSize,\n Placeholder.configure({\n emptyEditorClass: \"is-empty\",\n placeholder:\n typeof placeholder === \"function\"\n ? placeholder\n : () => placeholder,\n }),\n ];\n\n if (characterLimit) {\n extensions.push(\n CharacterCount.configure({\n limit: characterLimit,\n }),\n );\n }\n\n if (enableSmilies) {\n extensions.push(SmilieReplacer);\n }\n\n if (enableColorHighlighter) {\n extensions.push(ColorHighlighter);\n }\n\n return extensions;\n}\n","/**\n * Escapes characters that have syntactic meaning in HTML text.\n */\nexport function escapeHtml(text: string): string {\n if (!text) return \"\";\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n/**\n * Converts a plain-text string with newlines into HTML paragraphs suitable\n * for TipTap initial content or setContent, preserving line breaks.\n */\nexport function plainTextToTipTapHtml(text: string): string {\n if (!text) return \"<p></p>\";\n if (/<p[\\s>]/i.test(text)) {\n return text;\n }\n return text\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\\n\")\n .split(\"\\n\")\n .map((line) => `<p>${escapeHtml(line)}</p>`)\n .join(\"\");\n}\n\n/**\n * Extracts plain text from an HTML string or TipTap HTML, preserving newlines between block tags.\n */\nexport function htmlToPlainText(html: string): string {\n if (!html) return \"\";\n if (typeof document !== \"undefined\") {\n const tempDiv = document.createElement(\"div\");\n tempDiv.innerHTML = html;\n tempDiv\n .querySelectorAll(\"br.ProseMirror-trailingBreak\")\n .forEach((br) => br.remove());\n tempDiv.querySelectorAll(\"br\").forEach((br) => br.replaceWith(\"\\n\"));\n const paragraphs = tempDiv.querySelectorAll(\"p, div, li, h1, h2, h3, h4, h5, h6\");\n if (paragraphs.length > 0) {\n const textParts: string[] = [];\n paragraphs.forEach((p) => {\n textParts.push(p.textContent || \"\");\n });\n return textParts.join(\"\\n\");\n }\n return tempDiv.textContent || \"\";\n }\n\n // Node.js fallback regex\n return html\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n .replace(/<\\/p>/gi, \"\\n\")\n .replace(/<\\/div>/gi, \"\\n\")\n .replace(/<\\/li>/gi, \"\\n\")\n .replace(/<[^>]+>/g, \"\")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .trim();\n}\n\n/**\n * Extracts plain text from a TipTap editor instance, preserving newline separators\n * between block nodes.\n */\nexport function getEditorText(editor: any): string {\n if (!editor) return \"\";\n const html = typeof editor.getHTML === \"function\" ? editor.getHTML() : \"\";\n if (html) {\n return htmlToPlainText(html);\n }\n if (typeof editor.getText === \"function\") {\n try {\n return editor.getText({ blockSeparator: \"\\n\" });\n } catch {\n return editor.getText();\n }\n }\n return \"\";\n}\n","import { Editor, EditorOptions, Content, Extensions } from \"@tiptap/core\";\nimport { Slice, Fragment, Node as ProsemirrorNode } from \"@tiptap/pm/model\";\nimport { Token, tokenizePrompt } from \"./grammar\";\nimport { plainTextToTipTapHtml, getEditorText } from \"./serializers\";\n\nexport interface EditorControllerOptions\n extends Partial<Omit<EditorOptions, \"element\" | \"content\">> {\n element?: Element | HTMLElement | null;\n content?: string | Content;\n plainTextMode?: boolean;\n extensions?: Extensions;\n onPlainTextChange?: (text: string) => void;\n onTokensChange?: (tokens: Token[]) => void;\n onSelectionChange?: (range: { from: number; to: number } | null) => void;\n}\n\n/**\n * UI-agnostic controller managing the lifecycle, commands, and plain-text/token\n * synchronization of a rich text or prompt editor.\n */\nexport class EditorController {\n public readonly editor: Editor;\n private readonly plainTextMode: boolean;\n private readonly onPlainTextChange?: (text: string) => void;\n private readonly onTokensChange?: (tokens: Token[]) => void;\n private readonly onSelectionChange?: (range: { from: number; to: number } | null) => void;\n\n constructor(options: EditorControllerOptions = {}) {\n const {\n element,\n content,\n plainTextMode = false,\n extensions = [],\n onPlainTextChange,\n onTokensChange,\n onSelectionChange,\n ...editorOptions\n } = options;\n\n this.plainTextMode = plainTextMode;\n this.onPlainTextChange = onPlainTextChange;\n this.onTokensChange = onTokensChange;\n this.onSelectionChange = onSelectionChange;\n\n const initialContent =\n plainTextMode && typeof content === \"string\"\n ? plainTextToTipTapHtml(content)\n : content;\n\n this.editor = new Editor({\n element: element || undefined,\n content: initialContent,\n extensions,\n ...editorOptions,\n onUpdate: (props) => {\n editorOptions.onUpdate?.(props);\n this.handleUpdate();\n },\n onSelectionUpdate: (props) => {\n editorOptions.onSelectionUpdate?.(props);\n this.handleSelectionUpdate();\n },\n });\n\n if (plainTextMode) {\n this.enforcePlainTextClipboard();\n }\n }\n\n private enforcePlainTextClipboard() {\n this.editor.setOptions({\n editorProps: {\n ...this.editor.options.editorProps,\n clipboardTextParser: (text: string, context: any, _plain: boolean, view?: any) => {\n const schema =\n context?.doc?.type?.schema ||\n context?.schema ||\n view?.state?.schema ||\n this.editor.schema;\n\n if (!schema) return Slice.empty;\n\n const blocks = text.replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n const nodes: ProsemirrorNode[] = [];\n\n blocks.forEach((line) => {\n const nodeJson: any = { type: \"paragraph\" };\n if (line.length > 0) {\n nodeJson.content = [{ type: \"text\", text: line }];\n }\n try {\n const node = ProsemirrorNode.fromJSON(schema, nodeJson);\n nodes.push(node);\n } catch {\n // Ignore invalid node\n }\n });\n\n return Slice.maxOpen(Fragment.fromArray(nodes));\n },\n },\n });\n }\n\n private handleUpdate() {\n if (this.plainTextMode || this.onPlainTextChange || this.onTokensChange) {\n const text = this.getPlainText();\n this.onPlainTextChange?.(text);\n\n if (this.onTokensChange) {\n const tokens = tokenizePrompt(text);\n this.onTokensChange(tokens);\n }\n }\n }\n\n private handleSelectionUpdate() {\n if (this.onSelectionChange) {\n const { from, to } = this.editor.state.selection;\n this.onSelectionChange({ from, to });\n }\n }\n\n public getPlainText(): string {\n return getEditorText(this.editor);\n }\n\n public setPlainText(text: string, emitUpdate = true) {\n const html = plainTextToTipTapHtml(text);\n this.editor.commands.setContent(html, emitUpdate);\n }\n\n public insertText(text: string) {\n this.editor.commands.insertContent(text);\n }\n\n public insertTextAt(pos: number, text: string) {\n this.editor.chain().focus().insertContentAt(pos, text).run();\n }\n\n public replaceRange(from: number, to: number, text: string) {\n this.editor.chain().focus().deleteRange({ from, to }).insertContentAt(from, text).run();\n }\n\n public destroy() {\n this.editor.destroy();\n }\n}\n\n/**\n * Creates and initializes an EditorController instance.\n */\nexport function createEditor(options: EditorControllerOptions = {}): EditorController {\n return new EditorController(options);\n}\n"],"mappings":"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","names":["Plugin","Extension","Extension","Extension","Plugin","Decoration","DecorationSet","Extension"]}
|
|
1
|
+
{"version":3,"sources":["../src/grammar/tokens.ts","../src/grammar/tokenizer.ts","../src/grammar/resolver.ts","../src/grammar/sourcemap.ts","../src/extensions/gradient-text.ts","../src/extensions/slash-commands.ts","../src/extensions/template-suggestions.ts","../src/extensions/loading-node.ts","../src/extensions/SmilieReplacer.ts","../src/extensions/ColorHighlighter.ts","../src/extensions/FontSize.ts","../src/extensions/rich-text-preset.ts","../src/serializers/plain-text.ts","../src/controller.ts"],"sourcesContent":["/**\n * Canonical regex patterns for prompt editing tokens.\n */\nexport const TEMPLATE_REGEX = /{{\\s*([^}]+?)\\s*}}/g;\nexport const VARIABLE_REGEX = /(?<!\\{)\\{([^{}]+)\\}(?!\\})/g;\nexport const INSTRUCTION_REGEX = /__(.+?)__/g;\n\n// Backward-compatible camelCase aliases\nexport const templateRegex = TEMPLATE_REGEX;\nexport const variableRegex = VARIABLE_REGEX;\nexport const instructionRegex = INSTRUCTION_REGEX;\n\nexport type TokenType = \"template\" | \"variable\" | \"instruction\" | \"text\";\n\nexport interface Token {\n type: TokenType;\n raw: string;\n value: string;\n start: number;\n end: number;\n}\n\nexport interface TemplateVersion {\n id: string;\n version: string | number;\n body: string;\n createdAt?: any;\n [key: string]: any;\n}\n\nexport interface Template {\n id?: string;\n name: string;\n body?: string;\n latestVersion?: string | number;\n versions?: TemplateVersion[];\n color?: string;\n [key: string]: any;\n}\n\nexport interface ColorGradient {\n from: string;\n to: string;\n}\n","import {\n TEMPLATE_REGEX,\n VARIABLE_REGEX,\n INSTRUCTION_REGEX,\n Token,\n} from \"./tokens\";\n\ninterface RawMatch {\n type: \"template\" | \"variable\" | \"instruction\";\n raw: string;\n value: string;\n start: number;\n end: number;\n}\n\n/**\n * Parses any prompt string into an array of typed tokens in linear order.\n * Plain text between tokens is preserved as `{ type: 'text' }`.\n */\nexport function tokenizePrompt(text: string): Token[] {\n if (!text) {\n return [];\n }\n\n const rawMatches: RawMatch[] = [];\n\n // Match {{template}}\n const tmplRegex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = tmplRegex.exec(text)) !== null) {\n rawMatches.push({\n type: \"template\",\n raw: match[0],\n value: match[1].trim(),\n start: match.index,\n end: match.index + match[0].length,\n });\n }\n\n // Match {variable}\n const varRegex = new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags);\n while ((match = varRegex.exec(text)) !== null) {\n // Avoid double matching if overlapping with template\n const start = match.index;\n const end = start + match[0].length;\n const overlaps = rawMatches.some(\n (m) => !(end <= m.start || start >= m.end),\n );\n if (!overlaps) {\n rawMatches.push({\n type: \"variable\",\n raw: match[0],\n value: match[1].trim(),\n start,\n end,\n });\n }\n }\n\n // Match __instruction__\n const instRegex = new RegExp(\n INSTRUCTION_REGEX.source,\n INSTRUCTION_REGEX.flags,\n );\n while ((match = instRegex.exec(text)) !== null) {\n const start = match.index;\n const end = start + match[0].length;\n const overlaps = rawMatches.some(\n (m) => !(end <= m.start || start >= m.end),\n );\n if (!overlaps) {\n rawMatches.push({\n type: \"instruction\",\n raw: match[0],\n value: match[1].trim(),\n start,\n end,\n });\n }\n }\n\n // Sort matches by start index\n rawMatches.sort((a, b) => a.start - b.start);\n\n const tokens: Token[] = [];\n let currentIdx = 0;\n\n for (const m of rawMatches) {\n if (m.start > currentIdx) {\n const textChunk = text.slice(currentIdx, m.start);\n tokens.push({\n type: \"text\",\n raw: textChunk,\n value: textChunk,\n start: currentIdx,\n end: m.start,\n });\n }\n tokens.push({\n type: m.type,\n raw: m.raw,\n value: m.value,\n start: m.start,\n end: m.end,\n });\n currentIdx = m.end;\n }\n\n if (currentIdx < text.length) {\n const textChunk = text.slice(currentIdx);\n tokens.push({\n type: \"text\",\n raw: textChunk,\n value: textChunk,\n start: currentIdx,\n end: text.length,\n });\n }\n\n return tokens;\n}\n","import {\n TEMPLATE_REGEX,\n VARIABLE_REGEX,\n INSTRUCTION_REGEX,\n Template,\n TemplateVersion,\n} from \"./tokens\";\n\n/**\n * Finds the latest version of a template based on `latestVersion` or last version entry.\n */\nexport function getLatestVersion(\n template: Template,\n): TemplateVersion | undefined {\n if (!template.versions || template.versions.length === 0) {\n if (template.body !== undefined) {\n return {\n id: template.id || \"default\",\n version: \"1.0\",\n body: template.body,\n };\n }\n return undefined;\n }\n if (template.latestVersion) {\n const found = template.versions.find(\n (v) => v.version === template.latestVersion,\n );\n if (found) return found;\n }\n return template.versions[template.versions.length - 1];\n}\n\nexport interface ResolveTemplatesOptions {\n bindings?: Record<string, string>;\n maxDepth?: number;\n}\n\n/**\n * Recursively resolves template tags `{{template_name}}` in a given text.\n * Detects circular dependencies and returns \"[Template loop detected]\".\n */\nexport function resolveTemplates(\n text: string,\n templates: Template[] = [],\n options?: ResolveTemplatesOptions,\n): string {\n const templateMap = new Map<string, Template>();\n for (const t of templates) {\n templateMap.set(t.name, t);\n }\n\n const maxDepth = options?.maxDepth ?? 10;\n\n function resolveRecursive(\n currentText: string,\n visited: Set<string>,\n depth: number,\n ): string {\n if (depth > maxDepth) {\n return \"[Template max depth exceeded]\";\n }\n\n let result = currentText;\n const regex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(result)) !== null) {\n const [fullMatch, rawTemplateName] = match;\n const templateName = rawTemplateName.trim();\n\n if (visited.has(templateName)) {\n return \"[Template loop detected]\";\n }\n\n const template = templateMap.get(templateName);\n if (!template) {\n continue;\n }\n\n let versionBody: string | undefined;\n const boundVersionId = options?.bindings?.[templateName];\n\n if (boundVersionId && template.versions) {\n const boundVersion = template.versions.find(\n (v) => v.id === boundVersionId || v.version === boundVersionId,\n );\n versionBody = boundVersion?.body;\n } else {\n const latest = getLatestVersion(template);\n versionBody = latest?.body ?? template.body;\n }\n\n if (versionBody === undefined) {\n continue;\n }\n\n const nextVisited = new Set(visited);\n nextVisited.add(templateName);\n\n const resolvedBody = resolveRecursive(\n versionBody,\n nextVisited,\n depth + 1,\n );\n\n if (\n resolvedBody === \"[Template loop detected]\" ||\n resolvedBody === \"[Template max depth exceeded]\"\n ) {\n return resolvedBody;\n }\n\n result = result.replace(fullMatch, resolvedBody);\n regex.lastIndex = 0;\n }\n\n return result;\n }\n\n return resolveRecursive(text, new Set(), 0);\n}\n\n/**\n * Replaces `{variableName}` with values from a dictionary.\n */\nexport function resolveVariables(\n text: string,\n values: Record<string, string | number>,\n): string {\n if (!text) return \"\";\n return text.replace(\n new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags),\n (fullMatch, varName) => {\n const key = varName.trim();\n if (Object.prototype.hasOwnProperty.call(values, key)) {\n return String(values[key]);\n }\n return fullMatch;\n },\n );\n}\n\n/**\n * Extracts unique template names referenced in text.\n */\nexport function extractTemplateNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n\n/**\n * Extracts unique variable names referenced in text.\n */\nexport function extractVariableNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(VARIABLE_REGEX.source, VARIABLE_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n\n/**\n * Extracts unique instruction names referenced in text.\n */\nexport function extractInstructionNames(text: string): string[] {\n if (!text) return [];\n const set = new Set<string>();\n const regex = new RegExp(INSTRUCTION_REGEX.source, INSTRUCTION_REGEX.flags);\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n set.add(match[1].trim());\n }\n return Array.from(set);\n}\n","import { Template } from \"./tokens\";\nimport { getLatestVersion, resolveTemplates } from \"./resolver\";\n\nexport interface SourceMapSegment {\n resolvedStart: number;\n resolvedEnd: number;\n source: \"raw\" | \"template\";\n rawStart: number;\n rawEnd: number;\n templateName?: string;\n}\n\n/**\n * Resolves templates in text while tracking character offset mapping\n * between the raw input and the fully resolved output.\n */\nexport function resolveTemplatesWithMapping(\n text: string,\n templates: Template[] = [],\n templateBindings?: Record<string, string>,\n): { text: string; map: SourceMapSegment[] } {\n if (!templates || templates.length === 0 || !text.includes(\"{{\")) {\n return {\n text,\n map: [\n {\n resolvedStart: 0,\n resolvedEnd: text.length,\n source: \"raw\",\n rawStart: 0,\n rawEnd: text.length,\n },\n ],\n };\n }\n\n const templateMap = new Map(templates.map((t) => [t.name, t]));\n const regex = /{{\\s*([^}]+?)\\s*}}/g;\n let match: RegExpExecArray | null;\n let lastIndex = 0;\n let resolvedText = \"\";\n const map: SourceMapSegment[] = [];\n\n while ((match = regex.exec(text)) !== null) {\n const [fullMatch, rawTemplateName] = match;\n const templateName = rawTemplateName.trim();\n const matchIndex = match.index;\n\n // Add raw text preceding this template match\n if (matchIndex > lastIndex) {\n const rawSegment = text.substring(lastIndex, matchIndex);\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + rawSegment.length,\n source: \"raw\",\n rawStart: lastIndex,\n rawEnd: matchIndex,\n });\n resolvedText += rawSegment;\n }\n\n let resolvedBody = fullMatch;\n let isTemplate = false;\n\n if (templateMap.has(templateName)) {\n const template = templateMap.get(templateName)!;\n let versionBody: string | undefined;\n const boundVersionId = templateBindings?.[templateName];\n\n if (boundVersionId && template.versions) {\n const boundVersion = template.versions.find(\n (v) => v.id === boundVersionId || v.version === boundVersionId,\n );\n versionBody = boundVersion?.body;\n } else {\n const latestVersion = getLatestVersion(template);\n versionBody = latestVersion?.body ?? template.body;\n }\n\n if (versionBody !== undefined) {\n resolvedBody = resolveTemplates(versionBody, templates, {\n bindings: templateBindings,\n });\n isTemplate = true;\n }\n }\n\n if (isTemplate) {\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + resolvedBody.length,\n source: \"template\",\n rawStart: matchIndex,\n rawEnd: matchIndex + fullMatch.length,\n templateName,\n });\n resolvedText += resolvedBody;\n } else {\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + fullMatch.length,\n source: \"raw\",\n rawStart: matchIndex,\n rawEnd: matchIndex + fullMatch.length,\n });\n resolvedText += fullMatch;\n }\n\n lastIndex = matchIndex + fullMatch.length;\n }\n\n // Add any remaining raw text after the final match\n if (lastIndex < text.length) {\n const rawSegment = text.substring(lastIndex);\n map.push({\n resolvedStart: resolvedText.length,\n resolvedEnd: resolvedText.length + rawSegment.length,\n source: \"raw\",\n rawStart: lastIndex,\n rawEnd: text.length,\n });\n resolvedText += rawSegment;\n }\n\n return { text: resolvedText, map };\n}\n\n/**\n * Maps an offset in resolved text back to the corresponding offset in raw text.\n */\nexport function mapResolvedOffsetToRaw(\n resolvedOffset: number,\n map: SourceMapSegment[],\n): number {\n for (let i = 0; i < map.length; i++) {\n const seg = map[i];\n const isLast = i === map.length - 1;\n const inRange = isLast\n ? resolvedOffset >= seg.resolvedStart && resolvedOffset <= seg.resolvedEnd\n : resolvedOffset >= seg.resolvedStart && resolvedOffset < seg.resolvedEnd;\n\n if (inRange) {\n if (seg.source === \"raw\") {\n return seg.rawStart + (resolvedOffset - seg.resolvedStart);\n } else {\n // Pointing into a resolved template - return start of template tag\n return seg.rawStart;\n }\n }\n }\n return resolvedOffset;\n}\n\n/**\n * Maps an offset in raw text to the corresponding offset in resolved text.\n */\nexport function mapRawOffsetToResolved(\n rawOffset: number,\n map: SourceMapSegment[],\n): number {\n for (let i = 0; i < map.length; i++) {\n const seg = map[i];\n const isLast = i === map.length - 1;\n const inRange = isLast\n ? rawOffset >= seg.rawStart && rawOffset <= seg.rawEnd\n : rawOffset >= seg.rawStart && rawOffset < seg.rawEnd;\n\n if (inRange) {\n if (seg.source === \"raw\") {\n return seg.resolvedStart + (rawOffset - seg.rawStart);\n } else {\n return seg.resolvedStart;\n }\n }\n }\n return rawOffset;\n}\n","import { Mark } from \"@tiptap/core\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport type { Node as ProsemirrorNode } from \"@tiptap/pm/model\";\nimport type { EditorState } from \"@tiptap/pm/state\";\nimport { TEMPLATE_REGEX, VARIABLE_REGEX, INSTRUCTION_REGEX, ColorGradient } from \"../grammar/tokens\";\n\nexport interface GradientTextOptions {\n templateColorMap: Map<string, ColorGradient>;\n speed?: number;\n jsonVariables?: string[] | Set<string>;\n onTemplateClick?: (templateName: string, event: MouseEvent) => void;\n}\n\nconst createGradientDecorations = (\n doc: ProsemirrorNode,\n options: GradientTextOptions,\n): Decoration[] => {\n const decorations: Decoration[] = [];\n const speed = options.speed ?? 1;\n const jsonVarSet = options.jsonVariables\n ? options.jsonVariables instanceof Set\n ? options.jsonVariables\n : new Set(options.jsonVariables)\n : null;\n\n doc.descendants((node, pos) => {\n if (node.isText) {\n const text = node.text || \"\";\n let match: RegExpExecArray | null;\n\n // 1. Template: {{templateName}}\n const tmplRegex = new RegExp(TEMPLATE_REGEX.source, TEMPLATE_REGEX.flags);\n while ((match = tmplRegex.exec(text)) !== null) {\n const templateName = match[1].trim();\n const colors = options.templateColorMap?.get(templateName);\n\n if (colors) {\n const start = pos + match.index;\n const end = start + match[0].length;\n const { from: colorFrom, to: colorTo } = colors;\n\n const style = `--bg-size: ${\n speed * 300\n }%; --color-from: ${colorFrom}; --color-to: ${colorTo}; caret-color: #111 !important;`;\n\n decorations.push(\n Decoration.inline(start, end, {\n class:\n \"inline animate-gradient bg-gradient-to-r from-[var(--color-from)] via-[var(--color-to)] to-[var(--color-from)] bg-[length:var(--bg-size)_100%] bg-clip-text text-transparent border border-(--color-to)/20 px-1 py-0.5 rounded-sm cursor-pointer\",\n style,\n \"data-template\": templateName,\n }),\n );\n }\n }\n\n // 2. Instruction: __text__\n const instRegex = new RegExp(\n INSTRUCTION_REGEX.source,\n INSTRUCTION_REGEX.flags,\n );\n while ((match = instRegex.exec(text)) !== null) {\n const content = match[1].trim();\n const colors = options.templateColorMap?.get(content) || {\n from: \"#ffaa40\",\n to: \"#9c40ff\",\n };\n\n const start = pos + match.index;\n const end = start + match[0].length;\n const { from: colorFrom, to: colorTo } = colors;\n\n const style = `--bg-size: ${\n speed * 300\n }%; --color-from: ${colorFrom}; --color-to: ${colorTo}; caret-color: #111 !important;`;\n\n decorations.push(\n Decoration.inline(start, end, {\n class:\n \"italic animate-gradient bg-gradient-to-r from-rose-400 from-50% to-violet-500 to-50% bg-size-[200%_100%] bg-clip-text text-transparent inline-flex items-baseline gap-0.5\",\n style,\n }),\n );\n }\n\n // 3. Variable: {variableName}\n const varRegex = new RegExp(\n VARIABLE_REGEX.source,\n VARIABLE_REGEX.flags,\n );\n while ((match = varRegex.exec(text)) !== null) {\n const variableName = match[1].trim();\n const start = pos + match.index;\n const end = start + match[0].length;\n const isJsonVar = jsonVarSet?.has(variableName);\n\n decorations.push(\n Decoration.inline(start, end, {\n class: isJsonVar\n ? \"bg-violet-400/40 border-b-4 border-rose-300 dark:border-rose-800 inline-flex items-baseline px-1 py-0 text-foreground/80 gap-0.5 rounded-xs\"\n : \"bg-rose-400/40 border-b-4 border-violet-300 dark:border-violet-800 inline-flex items-baseline px-1 py-0 text-foreground/80 gap-0.5 rounded-xs\",\n \"data-variable\": variableName,\n }),\n );\n }\n }\n });\n\n return decorations;\n};\n\nexport const GradientText = Mark.create<GradientTextOptions>({\n name: \"gradientText\",\n\n addOptions() {\n return {\n templateColorMap: new Map(),\n speed: 1,\n jsonVariables: undefined,\n onTemplateClick: undefined,\n };\n },\n\n renderHTML({ HTMLAttributes }) {\n const defaultColors = {\n from: \"#ffaa40\",\n to: \"#9c40ff\",\n };\n const speed = this.options.speed ?? 1;\n const style = `--bg-size: ${speed * 300}%; --color-from: ${\n defaultColors.from\n }; --color-to: ${defaultColors.to}; caret-color: #111 !important;`;\n\n return [\n \"span\",\n {\n class:\n \"inline animate-gradient bg-gradient-to-r from-[var(--color-from)] via-[var(--color-to)] to-[var(--color-from)] bg-[length:var(--bg-size)_100%] bg-clip-text text-transparent\",\n style,\n ...HTMLAttributes,\n },\n 0,\n ];\n },\n\n parseHTML() {\n return [\n {\n tag: \"span\",\n getAttrs: (node) =>\n (node as HTMLElement).classList.contains(\"animate-gradient\") &&\n (node as HTMLElement).classList.contains(\"bg-clip-text\") &&\n null,\n },\n ];\n },\n\n addProseMirrorPlugins() {\n const markOptions = this.options;\n\n return [\n new Plugin({\n state: {\n init(_, { doc }) {\n return DecorationSet.create(\n doc,\n createGradientDecorations(doc, markOptions),\n );\n },\n apply(tr, value: DecorationSet) {\n const newDoc = tr.doc;\n if (tr.docChanged) {\n return DecorationSet.create(\n newDoc,\n createGradientDecorations(newDoc, markOptions),\n );\n }\n return value.map(tr.mapping, newDoc);\n },\n },\n props: {\n decorations(state: EditorState) {\n return (this as any).getState(state) as DecorationSet;\n },\n handleClickOn(view, pos, _node, _nodePos, event) {\n const decorationSet = (this as any).getState(\n view.state,\n ) as DecorationSet;\n const decorations = decorationSet.find(pos, pos + 1);\n\n for (const decoration of decorations) {\n const decorationWithAttrs = decoration as any;\n const templateName =\n decorationWithAttrs.type?.attrs?.[\"data-template\"];\n if (templateName) {\n if (markOptions.onTemplateClick) {\n markOptions.onTemplateClick(templateName, event as MouseEvent);\n }\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(\n new CustomEvent(\"show-gradient-popover\", {\n detail: {\n templateName,\n target: event.target,\n },\n }),\n );\n }\n return true;\n }\n }\n return false;\n },\n },\n }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin } from \"@tiptap/pm/state\";\n\nexport interface SlashCommandMatchData {\n match: RegExpMatchArray;\n query: string;\n from: number;\n to: number;\n coords: { top: number; left: number; bottom: number; right: number };\n}\n\nexport interface SlashCommandsOptions {\n trigger?: string;\n onMatch?: (data: SlashCommandMatchData) => void;\n onClear?: () => void;\n containerId?: string;\n}\n\nexport const SlashCommands = Extension.create<SlashCommandsOptions>({\n name: \"slashCommands\",\n\n addOptions() {\n return {\n trigger: \"/\",\n onMatch: undefined,\n onClear: undefined,\n containerId: undefined,\n };\n },\n\n addProseMirrorPlugins() {\n const opts = this.options;\n\n return [\n new Plugin({\n view() {\n return {\n update(view) {\n const { state } = view;\n const { selection } = state;\n const { $from } = selection;\n\n if (!$from.parent.isTextblock) {\n opts.onClear?.();\n return;\n }\n\n const textBeforeCursor = $from.parent.textBetween(\n 0,\n $from.parentOffset,\n );\n\n const slashMatch = textBeforeCursor.match(\n /(?:^|\\s)\\/([a-zA-Z0-9_-]*)$/,\n );\n\n if (slashMatch) {\n const matchIndex = slashMatch.index ?? 0;\n const offsetInParent =\n matchIndex + (slashMatch[0].startsWith(\" \") ? 1 : 0);\n const matchFrom = $from.start() + offsetInParent;\n const matchTo = $from.pos;\n const coords = view.coordsAtPos($from.pos);\n\n let relativeCoords = {\n top: coords.top,\n left: coords.left,\n bottom: coords.bottom,\n right: coords.right,\n };\n\n if (opts.containerId && typeof document !== \"undefined\") {\n const container = document.getElementById(opts.containerId);\n if (container) {\n const rect = container.getBoundingClientRect();\n relativeCoords = {\n top: coords.bottom - rect.top + 5,\n left: coords.left - rect.left,\n bottom: coords.bottom - rect.top,\n right: coords.right - rect.left,\n };\n }\n }\n\n opts.onMatch?.({\n match: slashMatch,\n query: slashMatch[1] || \"\",\n from: matchFrom,\n to: matchTo,\n coords: relativeCoords,\n });\n } else {\n opts.onClear?.();\n }\n },\n };\n },\n }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport Suggestion, { SuggestionOptions } from \"@tiptap/suggestion\";\nimport { Template } from \"../grammar/tokens\";\n\nexport interface TemplateSuggestionsOptions {\n templates: Template[];\n char?: string;\n onSuggestion?: (props: {\n query: string;\n range: { from: number; to: number };\n clientRect?: (() => DOMRect | null) | null;\n items: Template[];\n command: (props: { name: string }) => void;\n }) => void;\n}\n\nexport const TemplateSuggestions = Extension.create<TemplateSuggestionsOptions>({\n name: \"templateSuggestions\",\n\n addOptions() {\n return {\n templates: [],\n char: \"{{\",\n onSuggestion: undefined,\n };\n },\n\n addProseMirrorPlugins() {\n const opts = this.options;\n\n const suggestionConfig: Omit<SuggestionOptions<Template>, \"editor\"> = {\n char: opts.char || \"{{\",\n items: ({ query }) => {\n const lower = query.toLowerCase();\n return (opts.templates || []).filter((t) =>\n t.name.toLowerCase().includes(lower),\n );\n },\n command: ({ editor, range, props }) => {\n editor\n .chain()\n .focus()\n .deleteRange(range)\n .insertContent(`{{${props.name}}}`)\n .run();\n },\n render: () => {\n return {\n onStart: (props) => {\n opts.onSuggestion?.(props as any);\n },\n onUpdate: (props) => {\n opts.onSuggestion?.(props as any);\n },\n onExit: () => {\n opts.onSuggestion?.({\n query: \"\",\n range: { from: 0, to: 0 },\n items: [],\n command: () => {},\n });\n },\n };\n },\n };\n\n const SuggestionFn =\n typeof Suggestion === \"function\"\n ? Suggestion\n : (Suggestion as any)?.default || (Suggestion as any)?.Suggestion;\n\n return [\n SuggestionFn({\n editor: this.editor,\n ...suggestionConfig,\n }),\n ];\n },\n});\n","import { Node, mergeAttributes } from \"@tiptap/core\";\n\nexport const LoadingNode = Node.create({\n name: \"loadingNode\",\n group: \"inline\",\n inline: true,\n selectable: true,\n atom: true,\n\n addAttributes() {\n return {\n id: {\n default: null,\n parseHTML: (element) => element.getAttribute(\"data-id\"),\n renderHTML: (attributes) => {\n if (!attributes.id) return {};\n return { \"data-id\": attributes.id };\n },\n },\n };\n },\n\n parseHTML() {\n return [\n {\n tag: 'span[data-type=\"loading\"]',\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-type\": \"loading\",\n class: \"inline-flex items-center px-1.5 py-0.5 text-xs text-muted-foreground animate-pulse\",\n }),\n \"⏳\",\n ];\n },\n});\n","import { Extension, textInputRule } from \"@tiptap/core\";\n\nexport const SmilieReplacer = Extension.create({\n name: \"smilieReplacer\",\n\n addInputRules() {\n return [\n textInputRule({ find: /-___- $/, replace: \"😑 \" }),\n textInputRule({ find: /:'-\\) $/, replace: \"😂 \" }),\n textInputRule({ find: /':-\\) $/, replace: \"😅 \" }),\n textInputRule({ find: /':-D $/, replace: \"😅 \" }),\n textInputRule({ find: />:-\\) $/, replace: \"😆 \" }),\n textInputRule({ find: /-__- $/, replace: \"😑 \" }),\n textInputRule({ find: /':-\\( $/, replace: \"😓 \" }),\n textInputRule({ find: /:'-\\( $/, replace: \"😢 \" }),\n textInputRule({ find: />:-\\( $/, replace: \"😠 \" }),\n textInputRule({ find: /O:-\\) $/, replace: \"😇 \" }),\n textInputRule({ find: /:'\\) $/, replace: \"😂 \" }),\n textInputRule({ find: /:-D $/, replace: \"😃 \" }),\n textInputRule({ find: /':\\) $/, replace: \"😅 \" }),\n textInputRule({ find: /;-\\) $/, replace: \"😉 \" }),\n textInputRule({ find: /B-\\) $/, replace: \"😎 \" }),\n textInputRule({ find: /:-\\* $/, replace: \"😘 \" }),\n textInputRule({ find: /:-\\) $/, replace: \"🙂 \" }),\n textInputRule({ find: /-_- $/, replace: \"😑 \" }),\n textInputRule({ find: /:-O $/, replace: \"😮 \" }),\n textInputRule({ find: /:-P $/, replace: \"😛 \" }),\n textInputRule({ find: /:-p $/, replace: \"😛 \" }),\n textInputRule({ find: /:-\\/ $/, replace: \"😕 \" }),\n textInputRule({ find: /:-\\( $/, replace: \"😞 \" }),\n textInputRule({ find: /:'\\( $/, replace: \"😢 \" }),\n textInputRule({ find: /:D $/, replace: \"😃 \" }),\n textInputRule({ find: /=D $/, replace: \"😃 \" }),\n textInputRule({ find: /;\\) $/, replace: \"😉 \" }),\n textInputRule({ find: /B\\) $/, replace: \"😎 \" }),\n textInputRule({ find: /:\\) $/, replace: \"🙂 \" }),\n textInputRule({ find: /=\\) $/, replace: \"🙂 \" }),\n textInputRule({ find: /:O $/, replace: \"😮 \" }),\n textInputRule({ find: /:P $/, replace: \"😛 \" }),\n textInputRule({ find: /:p $/, replace: \"😛 \" }),\n textInputRule({ find: /:\\/ $/, replace: \"😕 \" }),\n textInputRule({ find: /:\\( $/, replace: \"😞 \" }),\n textInputRule({ find: /<3 $/, replace: \"❤️ \" }),\n textInputRule({ find: /<\\/3 $/, replace: \"💔 \" }),\n textInputRule({ find: /\\/shrug $/, replace: \"¯\\\\_(ツ)_/¯ \" }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\nimport type { Node as ProsemirrorNode } from \"@tiptap/pm/model\";\n\nexport function findHexColors(doc: ProsemirrorNode): DecorationSet {\n const hexColorRegex = /(#[0-9a-fA-F]{3,8})\\b/g;\n const decorations: Decoration[] = [];\n\n doc.descendants((node, position) => {\n if (!node.text) return;\n\n let match: RegExpExecArray | null;\n while ((match = hexColorRegex.exec(node.text)) !== null) {\n const color = match[0];\n const from = position + match.index;\n const to = from + color.length;\n\n decorations.push(\n Decoration.inline(from, to, {\n class: \"color-highlight px-1 py-0.5 rounded text-xs font-mono border\",\n style: `--color: ${color}; background-color: ${color}20; border-color: ${color}; color: ${color};`,\n }),\n );\n }\n });\n\n return DecorationSet.create(doc, decorations);\n}\n\nexport const ColorHighlighter = Extension.create({\n name: \"colorHighlighter\",\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n state: {\n init(_, { doc }) {\n return findHexColors(doc);\n },\n apply(transaction, oldState) {\n return transaction.docChanged ? findHexColors(transaction.doc) : oldState;\n },\n },\n props: {\n decorations(state) {\n return (this as any).getState(state);\n },\n },\n }),\n ];\n },\n});\n","import { Extension } from \"@tiptap/core\";\nimport \"@tiptap/extension-text-style\";\n\ndeclare module \"@tiptap/core\" {\n interface Commands<ReturnType> {\n fontSize: {\n setFontSize: (size: string) => ReturnType;\n unsetFontSize: () => ReturnType;\n };\n }\n}\n\nexport const FontSize = Extension.create({\n name: \"fontSize\",\n\n addOptions() {\n return {\n types: [\"textStyle\"],\n };\n },\n\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n fontSize: {\n default: null,\n parseHTML: (element) =>\n element.style.fontSize.replace(/['\"]+/g, \"\"),\n renderHTML: (attributes) => {\n if (!attributes.fontSize) {\n return {};\n }\n return {\n style: `font-size: ${attributes.fontSize}`,\n };\n },\n },\n },\n },\n ];\n },\n\n addCommands() {\n return {\n setFontSize:\n (fontSize: string) =>\n ({ chain }) =>\n chain().setMark(\"textStyle\", { fontSize }).run(),\n unsetFontSize:\n () =>\n ({ chain }) =>\n chain()\n .setMark(\"textStyle\", { fontSize: null })\n .removeEmptyTextStyle()\n .run(),\n };\n },\n});\n\nexport default FontSize;\n","import type { Extensions } from \"@tiptap/core\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport Color from \"@tiptap/extension-color\";\nimport Highlight from \"@tiptap/extension-highlight\";\nimport Link from \"@tiptap/extension-link\";\nimport TaskList from \"@tiptap/extension-task-list\";\nimport TaskItem from \"@tiptap/extension-task-item\";\nimport TextAlign from \"@tiptap/extension-text-align\";\nimport TextStyle from \"@tiptap/extension-text-style\";\nimport Typography from \"@tiptap/extension-typography\";\nimport Underline from \"@tiptap/extension-underline\";\nimport Placeholder from \"@tiptap/extension-placeholder\";\nimport CharacterCount from \"@tiptap/extension-character-count\";\n\nimport { SmilieReplacer } from \"./SmilieReplacer\";\nimport { ColorHighlighter } from \"./ColorHighlighter\";\nimport { FontSize } from \"./FontSize\";\n\nexport interface RichTextPresetOptions {\n placeholder?: string | ((props: { node: any }) => string);\n characterLimit?: number;\n openLinksOnClick?: boolean;\n enableSmilies?: boolean;\n enableColorHighlighter?: boolean;\n headingLevels?: (1 | 2 | 3 | 4 | 5 | 6)[];\n}\n\n/**\n * Creates a standard rich-text extensions bundle with full formatting support.\n */\nexport function createRichTextPreset(\n options: RichTextPresetOptions = {},\n): Extensions {\n const {\n placeholder = \"Start typing...\",\n characterLimit,\n openLinksOnClick = false,\n enableSmilies = true,\n enableColorHighlighter = true,\n headingLevels = [1, 2, 3, 4],\n } = options;\n\n const extensions: Extensions = [\n StarterKit.configure({\n orderedList: {\n HTMLAttributes: {\n class: \"list-decimal pl-4\",\n },\n },\n bulletList: {\n HTMLAttributes: {\n class: \"list-disc pl-4\",\n },\n },\n heading: {\n levels: headingLevels,\n HTMLAttributes: {\n class: \"font-bold tracking-tight\",\n },\n },\n }),\n TextStyle,\n Color,\n Highlight.configure({ multicolor: true }),\n Underline,\n Typography,\n TextAlign.configure({\n types: [\"heading\", \"paragraph\"],\n }),\n Link.configure({\n openOnClick: openLinksOnClick,\n autolink: true,\n defaultProtocol: \"https\",\n HTMLAttributes: {\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n class: \"text-blue-500 underline underline-offset-2\",\n },\n }),\n TaskList,\n TaskItem.configure({\n nested: true,\n }),\n FontSize,\n Placeholder.configure({\n emptyEditorClass: \"is-empty\",\n placeholder:\n typeof placeholder === \"function\"\n ? placeholder\n : () => placeholder,\n }),\n ];\n\n if (characterLimit) {\n extensions.push(\n CharacterCount.configure({\n limit: characterLimit,\n }),\n );\n }\n\n if (enableSmilies) {\n extensions.push(SmilieReplacer);\n }\n\n if (enableColorHighlighter) {\n extensions.push(ColorHighlighter);\n }\n\n return extensions;\n}\n","/**\n * Escapes characters that have syntactic meaning in HTML text.\n */\nexport function escapeHtml(text: string): string {\n if (!text) return \"\";\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n/**\n * Converts a plain-text string with newlines into HTML paragraphs suitable\n * for TipTap initial content or setContent, preserving line breaks.\n */\nexport function plainTextToTipTapHtml(text: string): string {\n if (!text) return \"<p></p>\";\n if (/<p[\\s>]/i.test(text)) {\n return text;\n }\n return text\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\r/g, \"\\n\")\n .split(\"\\n\")\n .map((line) => `<p>${escapeHtml(line)}</p>`)\n .join(\"\");\n}\n\n/**\n * Extracts plain text from an HTML string or TipTap HTML, preserving newlines between block tags.\n */\nexport function htmlToPlainText(html: string): string {\n if (!html) return \"\";\n if (typeof document !== \"undefined\") {\n const tempDiv = document.createElement(\"div\");\n tempDiv.innerHTML = html;\n tempDiv\n .querySelectorAll(\"br.ProseMirror-trailingBreak\")\n .forEach((br) => br.remove());\n tempDiv.querySelectorAll(\"br\").forEach((br) => br.replaceWith(\"\\n\"));\n const paragraphs = tempDiv.querySelectorAll(\"p, div, li, h1, h2, h3, h4, h5, h6\");\n if (paragraphs.length > 0) {\n const textParts: string[] = [];\n paragraphs.forEach((p) => {\n textParts.push(p.textContent || \"\");\n });\n return textParts.join(\"\\n\");\n }\n return tempDiv.textContent || \"\";\n }\n\n // Node.js fallback regex\n return html\n .replace(/<br\\s*\\/?>/gi, \"\\n\")\n .replace(/<\\/p>/gi, \"\\n\")\n .replace(/<\\/div>/gi, \"\\n\")\n .replace(/<\\/li>/gi, \"\\n\")\n .replace(/<[^>]+>/g, \"\")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .trim();\n}\n\n/**\n * Extracts plain text from a TipTap editor instance, preserving newline separators\n * between block nodes.\n */\nexport function getEditorText(editor: any): string {\n if (!editor) return \"\";\n const html = typeof editor.getHTML === \"function\" ? editor.getHTML() : \"\";\n if (html) {\n return htmlToPlainText(html);\n }\n if (typeof editor.getText === \"function\") {\n try {\n return editor.getText({ blockSeparator: \"\\n\" });\n } catch {\n return editor.getText();\n }\n }\n return \"\";\n}\n","import { Editor, EditorOptions, Content, Extensions } from \"@tiptap/core\";\nimport { Slice, Fragment, Node as ProsemirrorNode } from \"@tiptap/pm/model\";\nimport { Token, tokenizePrompt } from \"./grammar\";\nimport { plainTextToTipTapHtml, getEditorText } from \"./serializers\";\n\nexport interface EditorControllerOptions\n extends Partial<Omit<EditorOptions, \"element\" | \"content\">> {\n element?: Element | HTMLElement | null;\n content?: string | Content;\n plainTextMode?: boolean;\n extensions?: Extensions;\n onPlainTextChange?: (text: string) => void;\n onTokensChange?: (tokens: Token[]) => void;\n onSelectionChange?: (range: { from: number; to: number } | null) => void;\n}\n\n/**\n * UI-agnostic controller managing the lifecycle, commands, and plain-text/token\n * synchronization of a rich text or prompt editor.\n */\nexport class EditorController {\n public readonly editor: Editor;\n private readonly plainTextMode: boolean;\n private readonly onPlainTextChange?: (text: string) => void;\n private readonly onTokensChange?: (tokens: Token[]) => void;\n private readonly onSelectionChange?: (range: { from: number; to: number } | null) => void;\n\n constructor(options: EditorControllerOptions = {}) {\n const {\n element,\n content,\n plainTextMode = false,\n extensions = [],\n onPlainTextChange,\n onTokensChange,\n onSelectionChange,\n ...editorOptions\n } = options;\n\n this.plainTextMode = plainTextMode;\n this.onPlainTextChange = onPlainTextChange;\n this.onTokensChange = onTokensChange;\n this.onSelectionChange = onSelectionChange;\n\n const initialContent =\n plainTextMode && typeof content === \"string\"\n ? plainTextToTipTapHtml(content)\n : content;\n\n this.editor = new Editor({\n element: element || undefined,\n content: initialContent,\n extensions,\n ...editorOptions,\n onUpdate: (props) => {\n editorOptions.onUpdate?.(props);\n this.handleUpdate();\n },\n onSelectionUpdate: (props) => {\n editorOptions.onSelectionUpdate?.(props);\n this.handleSelectionUpdate();\n },\n });\n\n if (plainTextMode) {\n this.enforcePlainTextClipboard();\n }\n }\n\n private enforcePlainTextClipboard() {\n this.editor.setOptions({\n editorProps: {\n ...this.editor.options.editorProps,\n clipboardTextParser: (text: string, context: any, _plain: boolean, view?: any) => {\n const schema =\n context?.doc?.type?.schema ||\n context?.schema ||\n view?.state?.schema ||\n this.editor.schema;\n\n if (!schema) return Slice.empty;\n\n const blocks = text.replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n const nodes: ProsemirrorNode[] = [];\n\n blocks.forEach((line) => {\n const nodeJson: any = { type: \"paragraph\" };\n if (line.length > 0) {\n nodeJson.content = [{ type: \"text\", text: line }];\n }\n try {\n const node = ProsemirrorNode.fromJSON(schema, nodeJson);\n nodes.push(node);\n } catch {\n // Ignore invalid node\n }\n });\n\n return Slice.maxOpen(Fragment.fromArray(nodes));\n },\n },\n });\n }\n\n private handleUpdate() {\n if (this.plainTextMode || this.onPlainTextChange || this.onTokensChange) {\n const text = this.getPlainText();\n this.onPlainTextChange?.(text);\n\n if (this.onTokensChange) {\n const tokens = tokenizePrompt(text);\n this.onTokensChange(tokens);\n }\n }\n }\n\n private handleSelectionUpdate() {\n if (this.onSelectionChange) {\n const { from, to } = this.editor.state.selection;\n this.onSelectionChange({ from, to });\n }\n }\n\n public getPlainText(): string {\n return getEditorText(this.editor);\n }\n\n public setPlainText(text: string, emitUpdate = true) {\n const html = plainTextToTipTapHtml(text);\n this.editor.commands.setContent(html, emitUpdate);\n }\n\n public insertText(text: string) {\n this.editor.commands.insertContent(text);\n }\n\n public insertTextAt(pos: number, text: string) {\n this.editor.chain().focus().insertContentAt(pos, text).run();\n }\n\n public replaceRange(from: number, to: number, text: string) {\n this.editor.chain().focus().deleteRange({ from, to }).insertContentAt(from, text).run();\n }\n\n public destroy() {\n this.editor.destroy();\n }\n}\n\n/**\n * Creates and initializes an EditorController instance.\n */\nexport function createEditor(options: EditorControllerOptions = {}): EditorController {\n return new EditorController(options);\n}\n"],"mappings":"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","names":["Plugin","Extension","Extension","Extension","Plugin","Decoration","DecorationSet","Extension"]}
|
|
@@ -17,17 +17,19 @@ interface Token {
|
|
|
17
17
|
}
|
|
18
18
|
interface TemplateVersion {
|
|
19
19
|
id: string;
|
|
20
|
-
version: string;
|
|
20
|
+
version: string | number;
|
|
21
21
|
body: string;
|
|
22
|
-
createdAt?:
|
|
22
|
+
createdAt?: any;
|
|
23
|
+
[key: string]: any;
|
|
23
24
|
}
|
|
24
25
|
interface Template {
|
|
25
26
|
id?: string;
|
|
26
27
|
name: string;
|
|
27
28
|
body?: string;
|
|
28
|
-
latestVersion?: string;
|
|
29
|
+
latestVersion?: string | number;
|
|
29
30
|
versions?: TemplateVersion[];
|
|
30
31
|
color?: string;
|
|
32
|
+
[key: string]: any;
|
|
31
33
|
}
|
|
32
34
|
interface ColorGradient {
|
|
33
35
|
from: string;
|
|
@@ -17,17 +17,19 @@ interface Token {
|
|
|
17
17
|
}
|
|
18
18
|
interface TemplateVersion {
|
|
19
19
|
id: string;
|
|
20
|
-
version: string;
|
|
20
|
+
version: string | number;
|
|
21
21
|
body: string;
|
|
22
|
-
createdAt?:
|
|
22
|
+
createdAt?: any;
|
|
23
|
+
[key: string]: any;
|
|
23
24
|
}
|
|
24
25
|
interface Template {
|
|
25
26
|
id?: string;
|
|
26
27
|
name: string;
|
|
27
28
|
body?: string;
|
|
28
|
-
latestVersion?: string;
|
|
29
|
+
latestVersion?: string | number;
|
|
29
30
|
versions?: TemplateVersion[];
|
|
30
31
|
color?: string;
|
|
32
|
+
[key: string]: any;
|
|
31
33
|
}
|
|
32
34
|
interface ColorGradient {
|
|
33
35
|
from: string;
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixerate/editor",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "UI-agnostic rich text and media editing core library",
|
|
5
5
|
"author": "Pixerate",
|
|
6
6
|
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/Pixerate/editor.git",
|
|
10
|
+
"directory": "packages/core"
|
|
11
|
+
},
|
|
7
12
|
"type": "module",
|
|
8
13
|
"main": "./dist/index.cjs",
|
|
9
14
|
"module": "./dist/index.js",
|
|
@@ -34,23 +39,23 @@
|
|
|
34
39
|
"dist"
|
|
35
40
|
],
|
|
36
41
|
"dependencies": {
|
|
37
|
-
"@tiptap/core": "^2.11.5",
|
|
38
|
-
"@tiptap/extension-character-count": "^2.11.5",
|
|
39
|
-
"@tiptap/extension-color": "^2.11.5",
|
|
40
|
-
"@tiptap/extension-highlight": "^2.11.5",
|
|
41
|
-
"@tiptap/extension-link": "^2.11.5",
|
|
42
|
-
"@tiptap/extension-placeholder": "^2.11.5",
|
|
43
|
-
"@tiptap/extension-subscript": "^2.11.5",
|
|
44
|
-
"@tiptap/extension-superscript": "^2.11.5",
|
|
45
|
-
"@tiptap/extension-task-item": "^2.11.5",
|
|
46
|
-
"@tiptap/extension-task-list": "^2.11.5",
|
|
47
|
-
"@tiptap/extension-text-align": "^2.11.5",
|
|
48
|
-
"@tiptap/extension-text-style": "^2.11.5",
|
|
49
|
-
"@tiptap/extension-typography": "^2.11.5",
|
|
50
|
-
"@tiptap/extension-underline": "^2.11.5",
|
|
51
|
-
"@tiptap/pm": "^2.11.5",
|
|
52
|
-
"@tiptap/starter-kit": "^2.11.5",
|
|
53
|
-
"@tiptap/suggestion": "^2.11.5"
|
|
42
|
+
"@tiptap/core": "^2.11.5 || ^3.0.0",
|
|
43
|
+
"@tiptap/extension-character-count": "^2.11.5 || ^3.0.0",
|
|
44
|
+
"@tiptap/extension-color": "^2.11.5 || ^3.0.0",
|
|
45
|
+
"@tiptap/extension-highlight": "^2.11.5 || ^3.0.0",
|
|
46
|
+
"@tiptap/extension-link": "^2.11.5 || ^3.0.0",
|
|
47
|
+
"@tiptap/extension-placeholder": "^2.11.5 || ^3.0.0",
|
|
48
|
+
"@tiptap/extension-subscript": "^2.11.5 || ^3.0.0",
|
|
49
|
+
"@tiptap/extension-superscript": "^2.11.5 || ^3.0.0",
|
|
50
|
+
"@tiptap/extension-task-item": "^2.11.5 || ^3.0.0",
|
|
51
|
+
"@tiptap/extension-task-list": "^2.11.5 || ^3.0.0",
|
|
52
|
+
"@tiptap/extension-text-align": "^2.11.5 || ^3.0.0",
|
|
53
|
+
"@tiptap/extension-text-style": "^2.11.5 || ^3.0.0",
|
|
54
|
+
"@tiptap/extension-typography": "^2.11.5 || ^3.0.0",
|
|
55
|
+
"@tiptap/extension-underline": "^2.11.5 || ^3.0.0",
|
|
56
|
+
"@tiptap/pm": "^2.11.5 || ^3.0.0",
|
|
57
|
+
"@tiptap/starter-kit": "^2.11.5 || ^3.0.0",
|
|
58
|
+
"@tiptap/suggestion": "^2.11.5 || ^3.0.0"
|
|
54
59
|
},
|
|
55
60
|
"devDependencies": {
|
|
56
61
|
"@types/node": "^24.0.0",
|