chore(ui-conversation): add lexical dependencies and jsdom spike

This commit is contained in:
Yichen Jiang
2026-08-20 16:46:57 +08:00
parent e333dfc8f5
commit 2279fd19b0
4 changed files with 509 additions and 13 deletions
+6
View File
@@ -38,6 +38,10 @@ External packages that a workspace package resolves at runtime. The tier covers
| [`@earendil-works/pi-ai`](https://github.com/earendil-works/pi) | MIT |
| [`@joplin/turndown-plugin-gfm`](https://github.com/laurent22/joplin-turndown-plugin-gfm) | MIT |
| [`@jridgewell/gen-mapping`](https://github.com/jridgewell/sourcemaps) | MIT |
| [`@lexical/history`](https://github.com/facebook/lexical) | MIT |
| [`@lexical/plain-text`](https://github.com/facebook/lexical) | MIT |
| [`@lexical/text`](https://github.com/facebook/lexical) | MIT |
| [`@lexical/utils`](https://github.com/facebook/lexical) | MIT |
| [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk) | MIT |
| [`@openai/codex`](https://github.com/openai/codex) | Apache-2.0 |
| [`@opentelemetry/api`](https://github.com/open-telemetry/opentelemetry-js) | Apache-2.0 |
@@ -63,6 +67,7 @@ External packages that a workspace package resolves at runtime. The tier covers
| [`js-yaml`](https://github.com/nodeca/js-yaml) | MIT |
| [`katex`](https://github.com/KaTeX/KaTeX) | MIT |
| [`koffi`](https://github.com/Koromix/koffi) | MIT |
| [`lexical`](https://github.com/facebook/lexical) | MIT |
| [`mdast-util-from-markdown`](https://github.com/syntax-tree/mdast-util-from-markdown) | MIT |
| [`mdast-util-gfm`](https://github.com/syntax-tree/mdast-util-gfm) | MIT |
| [`mdast-util-math`](https://github.com/syntax-tree/mdast-util-math) | MIT |
@@ -122,6 +127,7 @@ External packages **directly declared** only by repository tooling, test infrast
| Package | License |
| --- | --- |
| [`@braintree/sanitize-url`](https://github.com/braintree/sanitize-url) | MIT |
| [`@lexical/headless`](https://github.com/facebook/lexical) | MIT |
| [`@modelcontextprotocol/server-everything`](https://github.com/modelcontextprotocol/servers) | MIT / Apache-2.0 |
| [`@modelcontextprotocol/server-filesystem`](https://github.com/modelcontextprotocol/servers) | MIT / Apache-2.0 |
| [`@stylistic/eslint-plugin`](https://github.com/eslint-stylistic/eslint-stylistic) | MIT |
+10 -2
View File
@@ -49,7 +49,12 @@
"license": "MIT",
"dependencies": {
"clsx": "^2.0.0",
"@deepseek-ai/schemastery": "workspace:^"
"@deepseek-ai/schemastery": "workspace:^",
"@lexical/history": "^0.49.0",
"@lexical/plain-text": "^0.49.0",
"@lexical/text": "^0.49.0",
"@lexical/utils": "^0.49.0",
"lexical": "^0.49.0"
},
"peerDependencies": {
"@deepseek-ai/cordis": "workspace:^",
@@ -105,7 +110,10 @@
"@deepseek-ai/dsh-tools": "workspace:^",
"@types/react": "~18.3.1",
"react": "^18.2.0",
"@deepseek-ai/dsh-settings": "workspace:^"
"@deepseek-ai/dsh-settings": "workspace:^",
"@lexical/headless": "^0.49.0",
"react-dom": "^18.2.0",
"@types/react-dom": "~18.3.0"
},
"files": [
"lib/index.js",
@@ -0,0 +1,199 @@
// @vitest-environment jsdom
/**
* SPIKE (Phase 0): validates the jsdom driving model for the Lexical composer
* before the real implementation lands. Answers three questions: (1) can a
* shell-owned headful editor render into jsdom and accept update-driven
* edits; (2) can synthetic beforeinput/keyboard events drive Lexical in
* jsdom, or must component tests drive through the command layer; (3) do
* DecoratorNode portals render and keep DOM identity when text is inserted
* before them. Deleted/absorbed into the real suites at the end of Phase 4.
*/
import { describe, expect, it } from 'vitest'
import * as React from 'react'
import { createPortal } from 'react-dom'
import { act, render } from '@testing-library/react'
import type { EditorConfig, LexicalEditor, NodeKey, SerializedLexicalNode } from 'lexical'
import {
$createParagraphNode, $createTextNode, $getRoot, $getSelection, $isRangeSelection,
createEditor, DecoratorNode,
} from 'lexical'
import { registerPlainText } from '@lexical/plain-text'
/** Minimal inline atomic chip for the spike (real node lands in Phase 1). */
class SpikeChipNode extends DecoratorNode<React.JSX.Element> {
static getType(): string {
return 'spike-chip'
}
static clone(node: SpikeChipNode): SpikeChipNode {
return new SpikeChipNode(node.__key)
}
static importJSON(): SpikeChipNode {
return new SpikeChipNode()
}
exportJSON(): SerializedLexicalNode {
return { type: 'spike-chip', version: 1 }
}
createDOM(_config: EditorConfig): HTMLElement {
const el = document.createElement('span')
el.dataset['spikeChip'] = 'true'
return el
}
updateDOM(): boolean {
return false
}
isInline(): boolean {
return true
}
getTextContent(): string {
return '/chip-clipboard'
}
decorate(): React.JSX.Element {
return <button type="button" data-chip-button>chip-label</button>
}
}
function makeEditor(): { editor: LexicalEditor; rootEl: HTMLDivElement } {
const editor = createEditor({
namespace: 'spike',
nodes: [SpikeChipNode],
onError: (error) => { throw error },
})
const rootEl = document.createElement('div')
rootEl.contentEditable = 'true'
document.body.appendChild(rootEl)
editor.setRootElement(rootEl)
registerPlainText(editor)
return { editor, rootEl }
}
describe('lexical jsdom spike', () => {
it('renders update-driven text into the DOM and reports projections', async () => {
const { editor, rootEl } = makeEditor()
editor.update(() => {
const p = $createParagraphNode()
p.append($createTextNode('hello world'))
$getRoot().append(p)
}, { discrete: true })
await Promise.resolve() // reconciliation is sync inside update; flush microtasks anyway
expect(rootEl.textContent).toBe('hello world')
const text = editor.getEditorState().read(() => $getRoot().getTextContent())
expect(text).toBe('hello world')
})
it('answers whether synthetic beforeinput insertText drives Lexical under jsdom', () => {
const { editor, rootEl } = makeEditor()
editor.update(() => {
const p = $createParagraphNode()
p.append($createTextNode('ab'))
$getRoot().append(p)
}, { discrete: true })
// Place a real DOM selection at the end of the text node.
const walker = document.createTreeWalker(rootEl, NodeFilter.SHOW_TEXT)
const textDom = walker.nextNode()
const selectable = textDom !== null && textDom !== undefined
if (selectable) {
const sel = document.getSelection()
const range = document.createRange()
range.setStart(textDom, 2)
range.collapse(true)
sel?.removeAllRanges()
sel?.addRange(range)
document.dispatchEvent(new Event('selectionchange'))
}
const event = new InputEvent('beforeinput', {
inputType: 'insertText', data: 'X', bubbles: true, cancelable: true,
})
rootEl.dispatchEvent(event)
const after = editor.getEditorState().read(() => $getRoot().getTextContent())
// Record the verdict either way — the spike's job is the answer, not a pass.
console.log(`SPIKE beforeinput verdict: selectable=${selectable} after=${JSON.stringify(after)}`)
expect(typeof after).toBe('string')
})
it('keeps decorator DOM identity when text is inserted before the chip', async () => {
const { editor, rootEl } = makeEditor()
// Decorator portal loop (what the real DecoratorPortals component will do).
function Portals(): React.JSX.Element {
const [decorators, setDecorators] = React.useState<Record<NodeKey, React.JSX.Element>>(
() => editor.getDecorators<React.JSX.Element>(),
)
React.useLayoutEffect(
() => editor.registerDecoratorListener<React.JSX.Element>((next) => { setDecorators(next) }),
[],
)
return (
<>
{Object.entries(decorators).map(([key, jsx]) => {
const el = editor.getElementByKey(key)
return el === null ? null : createPortal(jsx, el, key)
})}
</>
)
}
render(<Portals />)
let chipKey = ''
act(() => {
editor.update(() => {
const p = $createParagraphNode()
const chip = new SpikeChipNode()
chipKey = chip.getKey()
p.append($createTextNode('before '), chip, $createTextNode(' after'))
$getRoot().append(p)
}, { discrete: true })
})
await Promise.resolve()
const chipButton = rootEl.querySelector('[data-chip-button]')
expect(chipButton).not.toBeNull()
const chipSpan = rootEl.querySelector('[data-spike-chip]')
// Insert text before the chip through the node API (the transaction path).
act(() => {
editor.update(() => {
const p = $getRoot().getFirstChild()
if (p === null) throw new Error('paragraph missing')
const first = (p as ReturnType<typeof $createParagraphNode>).getFirstChild()
if (first === null) throw new Error('text missing')
;(first as ReturnType<typeof $createTextNode>).spliceText(0, 0, '@')
}, { discrete: true })
})
await Promise.resolve()
// Chip DOM node identity survives (bug #2793's structural fix).
expect(rootEl.querySelector('[data-spike-chip]')).toBe(chipSpan)
expect(rootEl.querySelector('[data-chip-button]')).toBe(chipButton)
// Chip node identity survives in the tree (bug #2813's structural fix).
const stillThere = editor.getEditorState().read(() => {
const node = editor.getEditorState()._nodeMap.get(chipKey)
return node !== undefined
})
expect(stillThere).toBe(true)
// Text content projection sees the clipboard form.
const text = editor.getEditorState().read(() => $getRoot().getTextContent())
expect(text).toBe('@before /chip-clipboard after')
})
it('reports whether selection APIs let update-driven caret placement work', () => {
const { editor } = makeEditor()
editor.update(() => {
const p = $createParagraphNode()
const t = $createTextNode('abc')
p.append(t)
$getRoot().append(p)
t.select(1, 1)
}, { discrete: true })
const verdict = editor.getEditorState().read(() => {
const sel = $getSelection()
return $isRangeSelection(sel) ? `range@${sel.anchor.offset}` : String(sel)
})
console.log(`SPIKE selection verdict: ${verdict}`)
expect(verdict).toBe('range@1')
})
})
+294 -11
View File
@@ -122,7 +122,7 @@ importers:
version: 6.1.1(typescript@6.0.3)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
vitest:
specifier: ^4.1.8
version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.8)(happy-dom@20.11.2)(jsdom@29.1.1)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
apps/cli:
dependencies:
@@ -411,7 +411,7 @@ importers:
version: 6.4.3(@types/node@22.20.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)(yaml@2.9.0)
vitest:
specifier: ^4.1.8
version: 4.1.8(@opentelemetry/api@1.9.0)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1)(vite@6.4.3(@types/node@22.20.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.8(@opentelemetry/api@1.9.0)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.8)(happy-dom@20.11.2)(jsdom@29.1.1)(vite@6.4.3(@types/node@22.20.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)(yaml@2.9.0))
examples:
dependencies:
@@ -1858,9 +1858,24 @@ importers:
'@deepseek-ai/schemastery':
specifier: link:../../../vendor/schemastery
version: link:../../../vendor/schemastery
'@lexical/history':
specifier: ^0.49.0
version: 0.49.0(typescript@6.0.3)
'@lexical/plain-text':
specifier: ^0.49.0
version: 0.49.0(typescript@6.0.3)
'@lexical/text':
specifier: ^0.49.0
version: 0.49.0(typescript@6.0.3)
'@lexical/utils':
specifier: ^0.49.0
version: 0.49.0(typescript@6.0.3)
clsx:
specifier: ^2.0.0
version: 2.1.1
lexical:
specifier: ^0.49.0
version: 0.49.0(typescript@6.0.3)
devDependencies:
'@deepseek-ai/cordis':
specifier: workspace:^
@@ -1943,12 +1958,21 @@ importers:
'@deepseek-ai/dsh-tools':
specifier: workspace:^
version: link:../../core/tools
'@lexical/headless':
specifier: ^0.49.0
version: 0.49.0(typescript@6.0.3)
'@types/react':
specifier: ~18.3.1
version: 18.3.31
'@types/react-dom':
specifier: ~18.3.0
version: 18.3.7(@types/react@18.3.31)
react:
specifier: ^18.2.0
version: 18.3.1
react-dom:
specifier: ^18.2.0
version: 18.3.1(react@18.3.1)
packages/client/ui-deliverables:
devDependencies:
@@ -7982,7 +8006,7 @@ importers:
version: link:../loader-smoke
vitest:
specifier: ^4.1.8
version: 4.1.8(@opentelemetry/api@1.9.0)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1)(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.8(@opentelemetry/api@1.9.0)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(happy-dom@20.11.2)(jsdom@29.1.1)(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
devDependencies:
'@deepseek-ai/cordis':
specifier: workspace:^
@@ -8031,7 +8055,7 @@ importers:
version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@18.3.7(@types/react@18.3.31))(@types/react@18.3.31)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
vitest:
specifier: ^4.1.8
version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1)(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(happy-dom@20.11.2)(jsdom@29.1.1)(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
devDependencies:
'@deepseek-ai/cordis':
specifier: workspace:^
@@ -10450,6 +10474,102 @@ packages:
cpu: [x64]
os: [win32]
'@lexical/clipboard@0.49.0':
resolution: {integrity: sha512-AVKj21xH1qU7JAFA/v0hCoafa+Yti1I7cHG+JQIgc/EqCtP8ePeJyIfTPNN/tXskoCdq++HewQoiSXRwwlocVg==}
peerDependencies:
typescript: '>=5.2'
peerDependenciesMeta:
typescript:
optional: true
'@lexical/dragon@0.49.0':
resolution: {integrity: sha512-62/4DP5qyX/l4Yf5qRyyQrs9BV725eRU3OmLUW6g7T5xrcHXxAo7tia/NvqjqvXdpvQzyHjWgsy7dMitGITUsw==}
peerDependencies:
typescript: '>=5.2'
peerDependenciesMeta:
typescript:
optional: true
'@lexical/extension@0.49.0':
resolution: {integrity: sha512-Wv0VsuqxorbxHCK4ms1PwAu6cXIGNLtflq66auF+zwxOtBprkSFV8VzzzdKLOYD2admP0VK6EqVCeGXFK1GggA==}
peerDependencies:
typescript: '>=5.2'
peerDependenciesMeta:
typescript:
optional: true
'@lexical/headless@0.49.0':
resolution: {integrity: sha512-3fQiKMAZ+K5/YlnGli9MId4LM8TPuOdLXIy1eUszfA/8hTZyPMcAxLjG99940UClgcoW9XxP03T37PJpFvpqIA==}
peerDependencies:
typescript: '>=5.2'
peerDependenciesMeta:
typescript:
optional: true
'@lexical/history@0.49.0':
resolution: {integrity: sha512-uQdtEd34gIJklXNSdHS2Wko1zxx1xUMVXbiodcLO6a3GeFTE5bKnx6af1zGX78KpYhUQYnHWorKuUvtdZlJPaA==}
peerDependencies:
typescript: '>=5.2'
peerDependenciesMeta:
typescript:
optional: true
'@lexical/html@0.49.0':
resolution: {integrity: sha512-NQqAydKzRjQl7Jx+bTTyC2iuz5uhuDaQX0SSPrdfgaFDCPjqQEejcBkCt1QXnu1CkbVHutZKVGVzljx40Y6y+Q==}
peerDependencies:
typescript: '>=5.2'
peerDependenciesMeta:
typescript:
optional: true
'@lexical/internal@0.49.0':
resolution: {integrity: sha512-s+XjPC7Qb39A/Xx9ahcz1s69CPix4ultaqyW+MDG0AXYW2quDr7m0USqReKIAiuoLIWtGN5HW8BwV2Y6t4qr6Q==}
peerDependencies:
typescript: '>=5.2'
peerDependenciesMeta:
typescript:
optional: true
'@lexical/list@0.49.0':
resolution: {integrity: sha512-zs6wYkxakDRcJO0KmwrPPHgeLLIxzjD+P2CRu+scJCHRuA5e2iSw2iFjH5n/LlWBrlnPMSjeQse4QqsRy9nnqA==}
peerDependencies:
typescript: '>=5.2'
peerDependenciesMeta:
typescript:
optional: true
'@lexical/plain-text@0.49.0':
resolution: {integrity: sha512-l7IuUj9n9CtFfz4Fz6zU6mmO+VkcnvyyebABx+lHevvTa7B6YI5PPVgABFfzdyPanyW/FGs7qpKBf59inAqbkg==}
peerDependencies:
typescript: '>=5.2'
peerDependenciesMeta:
typescript:
optional: true
'@lexical/selection@0.49.0':
resolution: {integrity: sha512-08Vd1+VoC6YnztWOFWVsqF/Hxw5EP8qeL1c7t3+rVCV8revLzXxdQw+vbPX3tgM4fmjOBDUXk6Ws1+rTtsqjcQ==}
peerDependencies:
typescript: '>=5.2'
peerDependenciesMeta:
typescript:
optional: true
'@lexical/text@0.49.0':
resolution: {integrity: sha512-mowedvbvx0HDaW+ymVdYmWVhueqgauhhqIWaCtbJj33tPk8pOu1BB0pZuJQbOB+1bDnFiZhkJV8W/CvR2M9lEA==}
peerDependencies:
typescript: '>=5.2'
peerDependenciesMeta:
typescript:
optional: true
'@lexical/utils@0.49.0':
resolution: {integrity: sha512-Jaa6DERBqxiFOFa49VPRV1WOb7mzRbMZ5U+v+RFagjzTmBhfxDmEkbQQ9nYTU3n3DPfdT8Hkyffextmw04etXg==}
peerDependencies:
typescript: '>=5.2'
peerDependenciesMeta:
typescript:
optional: true
'@mermaid-js/mermaid-mindmap@9.3.0':
resolution: {integrity: sha512-IhtYSVBBRYviH1Ehu8gk69pMDF8DSRqXBRDMWrEfHoaMruHeaP2DXA3PBnuwsMaCdPQhlUUcy/7DBLAEIXvCAw==}
@@ -11003,6 +11123,9 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
'@preact/signals-core@1.14.4':
resolution: {integrity: sha512-HNB6HYeYKhQbJ1aKl+YRjrS4+QWHLKX6qKoUsfS/m0vqzsVaEBiZiaKbG/e+NKk2ch5ALQr/ihWaMHxiCuuWHA==}
'@protobufjs/aspromise@1.1.2':
resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
@@ -11716,6 +11839,9 @@ packages:
'@types/web-bluetooth@0.0.21':
resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
'@types/whatwg-mimetype@3.0.2':
resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==}
'@types/ws@8.18.1':
resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}
@@ -12068,6 +12194,10 @@ packages:
buffer-equal-constant-time@1.0.1:
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
buffer-image-size@0.6.4:
resolution: {integrity: sha512-nEh+kZOPY1w+gcCMobZ6ETUp9WfibndnosbpwB1iJk/8Gt5ZF2bhS6+B6bPYz424KtwsR6Rflc3tCz1/ghX2dQ==}
engines: {node: '>=4.0'}
builtin-modules@3.3.0:
resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
engines: {node: '>=6'}
@@ -12811,6 +12941,10 @@ packages:
hachure-fill@0.5.2:
resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==}
happy-dom@20.11.2:
resolution: {integrity: sha512-7MB+bJLkxu3SowAfBJbjW+c55kNz5tkR45gu2qzrxznezhLeN5YIlJbwUgSzlGc+qWoZ8Ykg71H5ezz69xixrw==}
engines: {node: '>=20.0.0'}
has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
@@ -13180,6 +13314,14 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
lexical@0.49.0:
resolution: {integrity: sha512-9V1ZIzGpJEd8rIN+nN7veL4fW4fFWbS66Un4JNqSZB4D5t9euzN9+3+jEXy83FjNjNy0MiiUI3+DQaGCLYko0w==}
peerDependencies:
typescript: '>=5.2'
peerDependenciesMeta:
typescript:
optional: true
lie@3.3.0:
resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
@@ -14566,6 +14708,10 @@ packages:
resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==}
engines: {node: '>=20'}
whatwg-mimetype@3.0.0:
resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==}
engines: {node: '>=12'}
whatwg-mimetype@5.0.0:
resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==}
engines: {node: '>=20'}
@@ -15853,6 +15999,111 @@ snapshots:
'@koromix/koffi-win32-x64@3.1.1':
optional: true
'@lexical/clipboard@0.49.0(typescript@6.0.3)':
dependencies:
'@lexical/extension': 0.49.0(typescript@6.0.3)
'@lexical/html': 0.49.0(typescript@6.0.3)
'@lexical/internal': 0.49.0(typescript@6.0.3)
'@lexical/list': 0.49.0(typescript@6.0.3)
'@lexical/selection': 0.49.0(typescript@6.0.3)
'@lexical/utils': 0.49.0(typescript@6.0.3)
'@types/trusted-types': 2.0.7
lexical: 0.49.0(typescript@6.0.3)
optionalDependencies:
typescript: 6.0.3
'@lexical/dragon@0.49.0(typescript@6.0.3)':
dependencies:
'@lexical/extension': 0.49.0(typescript@6.0.3)
lexical: 0.49.0(typescript@6.0.3)
optionalDependencies:
typescript: 6.0.3
'@lexical/extension@0.49.0(typescript@6.0.3)':
dependencies:
'@lexical/internal': 0.49.0(typescript@6.0.3)
'@lexical/utils': 0.49.0(typescript@6.0.3)
'@preact/signals-core': 1.14.4
lexical: 0.49.0(typescript@6.0.3)
optionalDependencies:
typescript: 6.0.3
'@lexical/headless@0.49.0(typescript@6.0.3)':
dependencies:
'@lexical/internal': 0.49.0(typescript@6.0.3)
happy-dom: 20.11.2
lexical: 0.49.0(typescript@6.0.3)
optionalDependencies:
typescript: 6.0.3
transitivePeerDependencies:
- bufferutil
- utf-8-validate
'@lexical/history@0.49.0(typescript@6.0.3)':
dependencies:
'@lexical/extension': 0.49.0(typescript@6.0.3)
'@lexical/utils': 0.49.0(typescript@6.0.3)
lexical: 0.49.0(typescript@6.0.3)
optionalDependencies:
typescript: 6.0.3
'@lexical/html@0.49.0(typescript@6.0.3)':
dependencies:
'@lexical/extension': 0.49.0(typescript@6.0.3)
'@lexical/internal': 0.49.0(typescript@6.0.3)
'@lexical/selection': 0.49.0(typescript@6.0.3)
'@lexical/utils': 0.49.0(typescript@6.0.3)
lexical: 0.49.0(typescript@6.0.3)
optionalDependencies:
typescript: 6.0.3
'@lexical/internal@0.49.0(typescript@6.0.3)':
optionalDependencies:
typescript: 6.0.3
'@lexical/list@0.49.0(typescript@6.0.3)':
dependencies:
'@lexical/extension': 0.49.0(typescript@6.0.3)
'@lexical/html': 0.49.0(typescript@6.0.3)
'@lexical/internal': 0.49.0(typescript@6.0.3)
'@lexical/utils': 0.49.0(typescript@6.0.3)
lexical: 0.49.0(typescript@6.0.3)
optionalDependencies:
typescript: 6.0.3
'@lexical/plain-text@0.49.0(typescript@6.0.3)':
dependencies:
'@lexical/clipboard': 0.49.0(typescript@6.0.3)
'@lexical/dragon': 0.49.0(typescript@6.0.3)
'@lexical/extension': 0.49.0(typescript@6.0.3)
'@lexical/selection': 0.49.0(typescript@6.0.3)
'@lexical/utils': 0.49.0(typescript@6.0.3)
lexical: 0.49.0(typescript@6.0.3)
optionalDependencies:
typescript: 6.0.3
'@lexical/selection@0.49.0(typescript@6.0.3)':
dependencies:
'@lexical/internal': 0.49.0(typescript@6.0.3)
lexical: 0.49.0(typescript@6.0.3)
optionalDependencies:
typescript: 6.0.3
'@lexical/text@0.49.0(typescript@6.0.3)':
dependencies:
'@lexical/internal': 0.49.0(typescript@6.0.3)
lexical: 0.49.0(typescript@6.0.3)
optionalDependencies:
typescript: 6.0.3
'@lexical/utils@0.49.0(typescript@6.0.3)':
dependencies:
'@lexical/internal': 0.49.0(typescript@6.0.3)
'@lexical/selection': 0.49.0(typescript@6.0.3)
lexical: 0.49.0(typescript@6.0.3)
optionalDependencies:
typescript: 6.0.3
'@mermaid-js/mermaid-mindmap@9.3.0':
dependencies:
'@braintree/sanitize-url': 6.0.4
@@ -16254,6 +16505,8 @@ snapshots:
'@pkgjs/parseargs@0.11.0':
optional: true
'@preact/signals-core@1.14.4': {}
'@protobufjs/aspromise@1.1.2': {}
'@protobufjs/base64@1.1.2': {}
@@ -16863,8 +17116,7 @@ snapshots:
'@types/tough-cookie@4.0.5': {}
'@types/trusted-types@2.0.7':
optional: true
'@types/trusted-types@2.0.7': {}
'@types/turndown@5.0.6': {}
@@ -16872,6 +17124,8 @@ snapshots:
'@types/web-bluetooth@0.0.21': {}
'@types/whatwg-mimetype@3.0.2': {}
'@types/ws@8.18.1':
dependencies:
'@types/node': 22.20.0
@@ -16914,7 +17168,7 @@ snapshots:
obug: 2.1.3
std-env: 4.1.0
tinyrainbow: 3.1.0
vitest: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
vitest: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.8)(happy-dom@20.11.2)(jsdom@29.1.1)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
'@vitest/expect@4.1.8':
dependencies:
@@ -17263,6 +17517,10 @@ snapshots:
buffer-equal-constant-time@1.0.1: {}
buffer-image-size@0.6.4:
dependencies:
'@types/node': 22.20.0
builtin-modules@3.3.0: {}
bundle-name@4.1.0:
@@ -18124,6 +18382,19 @@ snapshots:
hachure-fill@0.5.2: {}
happy-dom@20.11.2:
dependencies:
'@types/node': 22.20.0
'@types/whatwg-mimetype': 3.0.2
'@types/ws': 8.18.1
buffer-image-size: 0.6.4
entities: 7.0.1
whatwg-mimetype: 3.0.0
ws: 8.21.0
transitivePeerDependencies:
- bufferutil
- utf-8-validate
has-flag@4.0.0: {}
has-symbols@1.1.0: {}
@@ -18483,6 +18754,12 @@ snapshots:
prelude-ls: 1.2.1
type-check: 0.4.0
lexical@0.49.0(typescript@6.0.3):
dependencies:
'@lexical/internal': 0.49.0(typescript@6.0.3)
optionalDependencies:
typescript: 6.0.3
lie@3.3.0:
dependencies:
immediate: 3.0.6
@@ -20042,7 +20319,7 @@ snapshots:
- typescript
- universal-cookie
vitest@4.1.8(@opentelemetry/api@1.9.0)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1)(vite@6.4.3(@types/node@22.20.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)(yaml@2.9.0)):
vitest@4.1.8(@opentelemetry/api@1.9.0)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.8)(happy-dom@20.11.2)(jsdom@29.1.1)(vite@6.4.3(@types/node@22.20.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)(yaml@2.9.0)):
dependencies:
'@vitest/expect': 4.1.8
'@vitest/mocker': 4.1.8(vite@6.4.3(@types/node@22.20.0)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.22.4)(yaml@2.9.0))
@@ -20068,11 +20345,12 @@ snapshots:
'@opentelemetry/api': 1.9.0
'@types/node': 22.20.0
'@vitest/coverage-v8': 4.1.8(vitest@4.1.8)
happy-dom: 20.11.2
jsdom: 29.1.1
transitivePeerDependencies:
- msw
vitest@4.1.8(@opentelemetry/api@1.9.0)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1)(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)):
vitest@4.1.8(@opentelemetry/api@1.9.0)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(happy-dom@20.11.2)(jsdom@29.1.1)(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)):
dependencies:
'@vitest/expect': 4.1.8
'@vitest/mocker': 4.1.8(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
@@ -20098,11 +20376,12 @@ snapshots:
'@opentelemetry/api': 1.9.0
'@types/node': 25.9.3
'@vitest/coverage-v8': 4.1.8(vitest@4.1.8)
happy-dom: 20.11.2
jsdom: 29.1.1
transitivePeerDependencies:
- msw
vitest@4.1.8(@opentelemetry/api@1.9.1)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)):
vitest@4.1.8(@opentelemetry/api@1.9.1)(@types/node@22.20.0)(@vitest/coverage-v8@4.1.8)(happy-dom@20.11.2)(jsdom@29.1.1)(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)):
dependencies:
'@vitest/expect': 4.1.8
'@vitest/mocker': 4.1.8(vite@8.0.16(@types/node@22.20.0)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
@@ -20128,11 +20407,12 @@ snapshots:
'@opentelemetry/api': 1.9.1
'@types/node': 22.20.0
'@vitest/coverage-v8': 4.1.8(vitest@4.1.8)
happy-dom: 20.11.2
jsdom: 29.1.1
transitivePeerDependencies:
- msw
vitest@4.1.8(@opentelemetry/api@1.9.1)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(jsdom@29.1.1)(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)):
vitest@4.1.8(@opentelemetry/api@1.9.1)(@types/node@25.9.3)(@vitest/coverage-v8@4.1.8)(happy-dom@20.11.2)(jsdom@29.1.1)(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0)):
dependencies:
'@vitest/expect': 4.1.8
'@vitest/mocker': 4.1.8(vite@8.0.16(@types/node@26.1.2)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.22.4)(yaml@2.9.0))
@@ -20158,6 +20438,7 @@ snapshots:
'@opentelemetry/api': 1.9.1
'@types/node': 25.9.3
'@vitest/coverage-v8': 4.1.8(vitest@4.1.8)
happy-dom: 20.11.2
jsdom: 29.1.1
transitivePeerDependencies:
- msw
@@ -20195,6 +20476,8 @@ snapshots:
webidl-conversions@8.0.1: {}
whatwg-mimetype@3.0.0: {}
whatwg-mimetype@5.0.0: {}
whatwg-url@16.0.1: