myrole-docx-editor 0.3.0 → 0.4.0
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/assistant-mcp.mjs +385 -0
- package/dist/chunks/{sdk-CU9i-NwD.js → sdk-BIAG7DE-.js} +10189 -9550
- package/dist/chunks/sdk-BIAG7DE-.js.map +1 -0
- package/dist/chunks/{vars-blockly-CBim6Ow0.js → vars-blockly-CMA3qyLP.js} +2 -2
- package/dist/chunks/{vars-blockly-CBim6Ow0.js.map → vars-blockly-CMA3qyLP.js.map} +1 -1
- package/dist/index.js +10 -9
- package/dist/react.js +25 -23
- package/dist/react.js.map +1 -1
- package/dist/types/packages/docx-editor/src/assistant-tools.d.ts +16 -0
- package/dist/types/packages/docx-editor/src/assistant.d.ts +24 -0
- package/dist/types/packages/docx-editor/src/editor.d.ts +14 -0
- package/dist/types/packages/docx-editor/src/index.d.ts +2 -1
- package/dist/types/packages/docx-editor/src/react.d.ts +1 -0
- package/dist/types/packages/docx-editor/src/sdk.d.ts +5 -0
- package/dist/types/packages/docx-model/src/index.d.ts +2 -0
- package/dist/types/packages/docx-model/src/paste.d.ts +12 -1
- package/package.json +8 -4
- package/dist/chunks/sdk-CU9i-NwD.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as s from "blockly";
|
|
2
|
-
import { k as p, T as u, m, n as f, o as g, q as h } from "./sdk-
|
|
2
|
+
import { k as p, T as u, m, n as f, o as g, q as h } from "./sdk-BIAG7DE-.js";
|
|
3
3
|
let r = !1;
|
|
4
4
|
function b(o, n, i) {
|
|
5
5
|
r || (p(), r = !0), o.replaceChildren();
|
|
@@ -39,4 +39,4 @@ function b(o, n, i) {
|
|
|
39
39
|
export {
|
|
40
40
|
b as mountBlockly
|
|
41
41
|
};
|
|
42
|
-
//# sourceMappingURL=vars-blockly-
|
|
42
|
+
//# sourceMappingURL=vars-blockly-CMA3qyLP.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vars-blockly-
|
|
1
|
+
{"version":3,"file":"vars-blockly-CMA3qyLP.js","sources":["../../src/vars-blockly.ts"],"sourcesContent":["import * as Blockly from 'blockly'\nimport {\n decorate, defineBlocks, fieldLibrary, setFields, THEME, TOOLBOX,\n type BlockJson,\n} from '@myrole/docx-vars'\nimport type { Tag } from '@myrole/docx-tags'\n\n/**\n * Le mode Blockly, chargé à la demande.\n *\n * Le canvas ne se replie pas — c'est ce qui a fait choisir le rendu DOM par\n * défaut — mais il sait ce que le DOM ne fait pas encore aussi bien :\n * restructurer librement une expression au glisser-déposer, avec sa poubelle,\n * son annulation et ses connexions typées.\n *\n * Il vit dans son propre module pour ne peser que si on l'ouvre : un\n * mégaoctet et demi qu'un utilisateur qui ne bascule jamais ne télécharge pas.\n */\n\nlet defined = false\n\nexport interface BlocklyView {\n load(tree: BlockJson): void\n read(): BlockJson | null\n resize(): void\n dispose(): void\n}\n\nexport function mountBlockly(\n holder: HTMLElement, onChange: () => void, tags: () => Tag[],\n): BlocklyView {\n if (!defined) { defineBlocks(); defined = true }\n holder.replaceChildren()\n const host = document.createElement('div')\n host.className = 'vp-canvas-host'\n holder.append(host)\n\n const ws = Blockly.inject(host, {\n // La boîte à outils : sans elle, on peut lire une expression et la\n // rebrancher, mais pas y AJOUTER quoi que ce soit — c'est la moitié de ce\n // qu'on vient chercher dans un canvas de blocs.\n toolbox: TOOLBOX,\n theme: THEME,\n renderer: 'geras',\n trashcan: true,\n sounds: false,\n grid: { spacing: 20, length: 1, colour: '#e8e9ed', snap: false },\n zoom: { controls: true, wheel: true, startScale: 0.95, minScale: 0.3, maxScale: 2 },\n move: { scrollbars: true, drag: true, wheel: true },\n })\n ws.addChangeListener((e) => { if (!e.isUiEvent) onChange() })\n\n return {\n load(tree) {\n // `setFields` alimente le sélecteur du bloc « champ » : sans lui, un clic\n // sur un champ n'ouvre rien.\n const groups = fieldLibrary(tags())\n setFields(groups.flatMap((g) => g.fields.map((f) => ({ path: f.path, label: f.label }))))\n Blockly.serialization.workspaces.load({ blocks: { languageVersion: 0, blocks: [tree] } }, ws)\n decorate(ws)\n Blockly.svgResize(ws)\n },\n read() {\n const state = Blockly.serialization.workspaces.save(ws) as {\n blocks?: { blocks?: BlockJson[] }\n }\n return state?.blocks?.blocks?.[0] ?? null\n },\n resize() { Blockly.svgResize(ws) },\n dispose() { ws.dispose() },\n }\n}\n"],"names":["defined","mountBlockly","holder","onChange","tags","defineBlocks","host","ws","Blockly","TOOLBOX","THEME","e","tree","groups","fieldLibrary","setFields","g","f","decorate"],"mappings":";;AAmBA,IAAIA,IAAU;AASP,SAASC,EACdC,GAAqBC,GAAsBC,GAC9B;AACb,EAAKJ,MAAWK,EAAA,GAAgBL,IAAU,KAC1CE,EAAO,gBAAA;AACP,QAAMI,IAAO,SAAS,cAAc,KAAK;AACzC,EAAAA,EAAK,YAAY,kBACjBJ,EAAO,OAAOI,CAAI;AAElB,QAAMC,IAAKC,EAAQ,OAAOF,GAAM;AAAA;AAAA;AAAA;AAAA,IAI9B,SAASG;AAAA,IACT,OAAOC;AAAA,IACP,UAAU;AAAA,IACV,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,MAAM,EAAE,SAAS,IAAI,QAAQ,GAAG,QAAQ,WAAW,MAAM,GAAA;AAAA,IACzD,MAAM,EAAE,UAAU,IAAM,OAAO,IAAM,YAAY,MAAM,UAAU,KAAK,UAAU,EAAA;AAAA,IAChF,MAAM,EAAE,YAAY,IAAM,MAAM,IAAM,OAAO,GAAA;AAAA,EAAK,CACnD;AACD,SAAAH,EAAG,kBAAkB,CAACI,MAAM;AAAE,IAAKA,EAAE,aAAWR,EAAA;AAAA,EAAW,CAAC,GAErD;AAAA,IACL,KAAKS,GAAM;AAGT,YAAMC,IAASC,EAAaV,GAAM;AAClC,MAAAW,EAAUF,EAAO,QAAQ,CAACG,MAAMA,EAAE,OAAO,IAAI,CAACC,OAAO,EAAE,MAAMA,EAAE,MAAM,OAAOA,EAAE,MAAA,EAAQ,CAAC,CAAC,GACxFT,EAAQ,cAAc,WAAW,KAAK,EAAE,QAAQ,EAAE,iBAAiB,GAAG,QAAQ,CAACI,CAAI,EAAA,EAAE,GAAKL,CAAE,GAC5FW,EAASX,CAAE,GACXC,EAAQ,UAAUD,CAAE;AAAA,IACtB;AAAA,IACA,OAAO;AAIL,aAHcC,EAAQ,cAAc,WAAW,KAAKD,CAAE,GAGxC,QAAQ,SAAS,CAAC,KAAK;AAAA,IACvC;AAAA,IACA,SAAS;AAAE,MAAAC,EAAQ,UAAUD,CAAE;AAAA,IAAE;AAAA,IACjC,UAAU;AAAE,MAAAA,EAAG,QAAA;AAAA,IAAU;AAAA,EAAA;AAE7B;"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { i as f, r as m, e as w, f as p, p as u, l as y, a as g, b as h, c as x } from "./chunks/sdk-
|
|
2
|
-
import { d as
|
|
3
|
-
async function
|
|
1
|
+
import { i as f, r as m, e as w, f as p, p as u, l as y, a as g, b as h, c as x } from "./chunks/sdk-BIAG7DE-.js";
|
|
2
|
+
import { D as v, d as b, g as E, h as I, j as U, s as C } from "./chunks/sdk-BIAG7DE-.js";
|
|
3
|
+
async function R(a, o, r = {}) {
|
|
4
4
|
const i = performance.now(), [c] = await Promise.all([
|
|
5
5
|
typeof a == "string" ? fetch(a).then((e) => e.ok ? e.arrayBuffer() : Promise.reject(new Error(`${e.status} ${a}`))) : Promise.resolve(a),
|
|
6
6
|
f(r.fontsUrl)
|
|
@@ -22,12 +22,13 @@ async function P(a, o, r = {}) {
|
|
|
22
22
|
}), { pages: [...o.querySelectorAll("canvas")], ms: Math.round(performance.now() - i) };
|
|
23
23
|
}
|
|
24
24
|
export {
|
|
25
|
-
|
|
26
|
-
b as
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
v as DOCX_EDITOR_VERSION,
|
|
26
|
+
b as createDocxEditor,
|
|
27
|
+
E as createDocxViewer,
|
|
28
|
+
I as defaultFontsUrl,
|
|
29
|
+
U as evaluateTags,
|
|
29
30
|
f as installFonts,
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
R as renderDocx,
|
|
32
|
+
C as sampleValues
|
|
32
33
|
};
|
|
33
34
|
//# sourceMappingURL=index.js.map
|
package/dist/react.js
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
import { jsx as h } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as v, useRef as
|
|
3
|
-
import { d as y } from "./chunks/sdk-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import { forwardRef as v, useRef as f, useEffect as n } from "react";
|
|
3
|
+
import { d as y } from "./chunks/sdk-BIAG7DE-.js";
|
|
4
|
+
import { D as I } from "./chunks/sdk-BIAG7DE-.js";
|
|
5
|
+
const s = v(function({ src: u, className: b, style: i, onReady: g, ...e }, o) {
|
|
6
|
+
const l = f(null), c = f(null), a = f(e);
|
|
7
|
+
a.current = e;
|
|
7
8
|
const m = (r) => {
|
|
8
|
-
typeof
|
|
9
|
+
typeof o == "function" ? o(r) : o && (o.current = r);
|
|
9
10
|
};
|
|
10
|
-
return
|
|
11
|
+
return n(() => {
|
|
11
12
|
const r = y(l.current, {
|
|
12
13
|
...e,
|
|
13
|
-
onSave: e.onSave ? (t, d) =>
|
|
14
|
-
onError: (t) =>
|
|
15
|
-
onSaveState: (t) =>
|
|
16
|
-
onLockState: (t) =>
|
|
17
|
-
onChange: () =>
|
|
14
|
+
onSave: e.onSave ? (t, d) => a.current.onSave(t, d) : void 0,
|
|
15
|
+
onError: (t) => a.current.onError?.(t),
|
|
16
|
+
onSaveState: (t) => a.current.onSaveState?.(t),
|
|
17
|
+
onLockState: (t) => a.current.onLockState?.(t),
|
|
18
|
+
onChange: () => a.current.onChange?.(),
|
|
18
19
|
feedback: typeof e.feedback == "object" ? {
|
|
19
20
|
...e.feedback,
|
|
20
21
|
onSubmit: e.feedback.onSubmit ? (t) => {
|
|
21
|
-
const d =
|
|
22
|
+
const d = a.current.feedback;
|
|
22
23
|
if (typeof d != "object" || !d.onSubmit) throw new Error("Feedback submission handler is no longer configured");
|
|
23
24
|
return d.onSubmit(t);
|
|
24
25
|
} : void 0
|
|
@@ -27,28 +28,29 @@ const s = v(function({ src: u, className: b, style: S, onReady: g, ...e }, f) {
|
|
|
27
28
|
return c.current = r, m(r), g?.(r), () => {
|
|
28
29
|
r.destroy(), c.current = null, m(null);
|
|
29
30
|
};
|
|
30
|
-
}, [e.draftKey, e.chrome, !!e.onSave]),
|
|
31
|
-
u && c.current && c.current.load(u).catch((r) =>
|
|
32
|
-
}, [u, e.draftKey, e.chrome, !!e.onSave]),
|
|
31
|
+
}, [e.draftKey, e.chrome, !!e.onSave]), n(() => {
|
|
32
|
+
u && c.current && c.current.load(u).catch((r) => a.current.onError?.(r));
|
|
33
|
+
}, [u, e.draftKey, e.chrome, !!e.onSave]), n(() => {
|
|
33
34
|
e.theme && c.current?.setTheme(e.theme);
|
|
34
|
-
}, [e.theme]),
|
|
35
|
+
}, [e.theme]), n(() => {
|
|
35
36
|
c.current?.setReadOnly(e.readOnly ?? !1);
|
|
36
|
-
}, [e.readOnly]),
|
|
37
|
+
}, [e.readOnly]), n(() => {
|
|
37
38
|
e.zoom !== void 0 && c.current?.setZoom(e.zoom);
|
|
38
|
-
}, [e.zoom]),
|
|
39
|
+
}, [e.zoom]), n(() => {
|
|
39
40
|
e.badges !== void 0 && c.current?.variables.setDisplay(e.badges);
|
|
40
|
-
}, [typeof e.badges == "boolean" ? e.badges : e.badges?.variables, typeof e.badges == "boolean" ? e.badges : e.badges?.expressions]), /* @__PURE__ */ h("div", { ref: l, className: b, style: { height: "100%", minHeight: 320, minWidth: 0, ...
|
|
41
|
+
}, [typeof e.badges == "boolean" ? e.badges : e.badges?.variables, typeof e.badges == "boolean" ? e.badges : e.badges?.expressions]), /* @__PURE__ */ h("div", { ref: l, className: b, style: { height: "100%", minHeight: 320, minWidth: 0, ...i } });
|
|
41
42
|
});
|
|
42
|
-
function
|
|
43
|
-
return
|
|
43
|
+
function x() {
|
|
44
|
+
return f(null);
|
|
44
45
|
}
|
|
45
46
|
const O = v(function(u, b) {
|
|
46
47
|
return /* @__PURE__ */ h(s, { ...u, ref: b, chrome: "viewer", readOnly: !0 });
|
|
47
48
|
}), w = 1;
|
|
48
49
|
export {
|
|
50
|
+
I as DOCX_EDITOR_VERSION,
|
|
49
51
|
w as DOCX_LOCKING_VERSION,
|
|
50
52
|
s as DocxEditor,
|
|
51
53
|
O as DocxViewer,
|
|
52
|
-
|
|
54
|
+
x as useDocxEditor
|
|
53
55
|
};
|
|
54
56
|
//# sourceMappingURL=react.js.map
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","sources":["../src/react.tsx"],"sourcesContent":["/**\n * The React face of the SDK.\n *\n * <DocxEditor src={file} onSave={(bytes) => upload(bytes)} style={{ height: '100vh' }} />\n *\n * The component owns one `createDocxEditor` for its lifetime; `src` changes\n * reload the document in place, every other option is read at mount. React is\n * an optional peer: nothing here runs unless `myrole-docx-editor/react` is\n * imported.\n */\nimport { useEffect, useRef, forwardRef, type CSSProperties } from 'react'\nimport { createDocxEditor, type DocxEditorHandle, type DocxEditorOptions } from './sdk'\n\nexport interface DocxEditorProps extends Omit<DocxEditorOptions, 'onReady'> {\n /** the document: bytes, a Blob/File, or a URL */\n src?: ArrayBuffer | Uint8Array | Blob | string\n className?: string\n style?: CSSProperties\n /** the handle, once mounted */\n onReady?: (editor: DocxEditorHandle) => void\n}\n\nexport const DocxEditor = forwardRef<DocxEditorHandle | null, DocxEditorProps>(function DocxEditor(\n { src, className, style, onReady, ...options }, ref,\n) {\n const host = useRef<HTMLDivElement>(null)\n const handle = useRef<DocxEditorHandle | null>(null)\n // The latest callbacks, without remounting the editor when they change.\n const latest = useRef(options)\n latest.current = options\n\n // The forwarded ref is filled HERE, not by useImperativeHandle: that one\n // runs in the layout phase, before this effect has created anything, and\n // would hand the parent a null for the component's whole life.\n const give = (h: DocxEditorHandle | null) => {\n if (typeof ref === 'function') ref(h)\n else if (ref) ref.current = h\n }\n\n useEffect(() => {\n const h = createDocxEditor(host.current!, {\n ...options,\n onSave: options.onSave ? (b, context) => latest.current.onSave!(b, context) : undefined,\n onError: e => latest.current.onError?.(e),\n onSaveState: state => latest.current.onSaveState?.(state),\n onLockState: state => latest.current.onLockState?.(state),\n onChange: () => latest.current.onChange?.(),\n feedback: typeof options.feedback === 'object' ? {\n ...options.feedback,\n onSubmit: options.feedback.onSubmit ? report => {\n const feedback = latest.current.feedback\n if (typeof feedback !== 'object' || !feedback.onSubmit) throw new Error('Feedback submission handler is no longer configured')\n return feedback.onSubmit(report)\n } : undefined,\n } : options.feedback,\n })\n handle.current = h\n give(h)\n onReady?.(h)\n return () => { h.destroy(); handle.current = null; give(null) }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [options.draftKey, options.chrome, !!options.onSave])\n\n useEffect(() => {\n if (src && handle.current) void handle.current.load(src).catch(e => latest.current.onError?.(e))\n }, [src, options.draftKey, options.chrome, !!options.onSave])\n useEffect(() => { if (options.theme) handle.current?.setTheme(options.theme) }, [options.theme])\n useEffect(() => { handle.current?.setReadOnly(options.readOnly ?? false) }, [options.readOnly])\n useEffect(() => { if (options.zoom !== undefined) handle.current?.setZoom(options.zoom) }, [options.zoom])\n useEffect(() => { if (options.badges !== undefined) handle.current?.variables.setDisplay(options.badges) }, [typeof options.badges === 'boolean' ? options.badges : options.badges?.variables, typeof options.badges === 'boolean' ? options.badges : options.badges?.expressions])\n\n return <div ref={host} className={className} style={{ height: '100%', minHeight: 320, minWidth: 0, ...style }} />\n})\n\n/** A ref to hand to `<DocxEditor ref={…}>`, and the handle once it exists. */\nexport function useDocxEditor() {\n return useRef<DocxEditorHandle | null>(null)\n}\n\nexport type { DocxEditorHandle, DocxEditorOptions } from './sdk'\n\n/** Read-only companion, with the same rendering and lifecycle as the editor. */\nexport const DocxViewer = forwardRef<DocxEditorHandle | null, DocxEditorProps>(function DocxViewer(props, ref) {\n return <DocxEditor {...props} ref={ref} chrome=\"viewer\" readOnly />\n})\n\nexport const DOCX_LOCKING_VERSION = 1\n"],"names":["DocxEditor","forwardRef","src","className","style","onReady","options","ref","host","useRef","handle","latest","give","h","useEffect","createDocxEditor","b","context","e","state","report","feedback","jsx","useDocxEditor","DocxViewer","props","DOCX_LOCKING_VERSION"],"mappings":"
|
|
1
|
+
{"version":3,"file":"react.js","sources":["../src/react.tsx"],"sourcesContent":["/**\n * The React face of the SDK.\n *\n * <DocxEditor src={file} onSave={(bytes) => upload(bytes)} style={{ height: '100vh' }} />\n *\n * The component owns one `createDocxEditor` for its lifetime; `src` changes\n * reload the document in place, every other option is read at mount. React is\n * an optional peer: nothing here runs unless `myrole-docx-editor/react` is\n * imported.\n */\nimport { useEffect, useRef, forwardRef, type CSSProperties } from 'react'\nimport { createDocxEditor, type DocxEditorHandle, type DocxEditorOptions } from './sdk'\n\nexport interface DocxEditorProps extends Omit<DocxEditorOptions, 'onReady'> {\n /** the document: bytes, a Blob/File, or a URL */\n src?: ArrayBuffer | Uint8Array | Blob | string\n className?: string\n style?: CSSProperties\n /** the handle, once mounted */\n onReady?: (editor: DocxEditorHandle) => void\n}\n\nexport const DocxEditor = forwardRef<DocxEditorHandle | null, DocxEditorProps>(function DocxEditor(\n { src, className, style, onReady, ...options }, ref,\n) {\n const host = useRef<HTMLDivElement>(null)\n const handle = useRef<DocxEditorHandle | null>(null)\n // The latest callbacks, without remounting the editor when they change.\n const latest = useRef(options)\n latest.current = options\n\n // The forwarded ref is filled HERE, not by useImperativeHandle: that one\n // runs in the layout phase, before this effect has created anything, and\n // would hand the parent a null for the component's whole life.\n const give = (h: DocxEditorHandle | null) => {\n if (typeof ref === 'function') ref(h)\n else if (ref) ref.current = h\n }\n\n useEffect(() => {\n const h = createDocxEditor(host.current!, {\n ...options,\n onSave: options.onSave ? (b, context) => latest.current.onSave!(b, context) : undefined,\n onError: e => latest.current.onError?.(e),\n onSaveState: state => latest.current.onSaveState?.(state),\n onLockState: state => latest.current.onLockState?.(state),\n onChange: () => latest.current.onChange?.(),\n feedback: typeof options.feedback === 'object' ? {\n ...options.feedback,\n onSubmit: options.feedback.onSubmit ? report => {\n const feedback = latest.current.feedback\n if (typeof feedback !== 'object' || !feedback.onSubmit) throw new Error('Feedback submission handler is no longer configured')\n return feedback.onSubmit(report)\n } : undefined,\n } : options.feedback,\n })\n handle.current = h\n give(h)\n onReady?.(h)\n return () => { h.destroy(); handle.current = null; give(null) }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [options.draftKey, options.chrome, !!options.onSave])\n\n useEffect(() => {\n if (src && handle.current) void handle.current.load(src).catch(e => latest.current.onError?.(e))\n }, [src, options.draftKey, options.chrome, !!options.onSave])\n useEffect(() => { if (options.theme) handle.current?.setTheme(options.theme) }, [options.theme])\n useEffect(() => { handle.current?.setReadOnly(options.readOnly ?? false) }, [options.readOnly])\n useEffect(() => { if (options.zoom !== undefined) handle.current?.setZoom(options.zoom) }, [options.zoom])\n useEffect(() => { if (options.badges !== undefined) handle.current?.variables.setDisplay(options.badges) }, [typeof options.badges === 'boolean' ? options.badges : options.badges?.variables, typeof options.badges === 'boolean' ? options.badges : options.badges?.expressions])\n\n return <div ref={host} className={className} style={{ height: '100%', minHeight: 320, minWidth: 0, ...style }} />\n})\n\n/** A ref to hand to `<DocxEditor ref={…}>`, and the handle once it exists. */\nexport function useDocxEditor() {\n return useRef<DocxEditorHandle | null>(null)\n}\n\nexport type { DocxEditorHandle, DocxEditorOptions } from './sdk'\nexport { DOCX_EDITOR_VERSION } from './sdk'\n\n/** Read-only companion, with the same rendering and lifecycle as the editor. */\nexport const DocxViewer = forwardRef<DocxEditorHandle | null, DocxEditorProps>(function DocxViewer(props, ref) {\n return <DocxEditor {...props} ref={ref} chrome=\"viewer\" readOnly />\n})\n\nexport const DOCX_LOCKING_VERSION = 1\n"],"names":["DocxEditor","forwardRef","src","className","style","onReady","options","ref","host","useRef","handle","latest","give","h","useEffect","createDocxEditor","b","context","e","state","report","feedback","jsx","useDocxEditor","DocxViewer","props","DOCX_LOCKING_VERSION"],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The assistant's tools as an MCP client sees them: names, descriptions, input
|
|
3
|
+
* schemas. Data only — `scripts/assistant-mcp.ts` bundles this file into the
|
|
4
|
+
* relay, and the relay must not carry the editor. `assistant.ts` runs them.
|
|
5
|
+
*
|
|
6
|
+
* Every description has to stand on its own: some MCP clients never show the
|
|
7
|
+
* server's `instructions`, all of them show these.
|
|
8
|
+
*/
|
|
9
|
+
export interface AssistantTool {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
inputSchema: Record<string, unknown>;
|
|
13
|
+
/** reads only: no undo step, no fake-cursor walk */
|
|
14
|
+
readOnly: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare const ASSISTANT_TOOLS: AssistantTool[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type DocxEditorHandle } from './sdk';
|
|
2
|
+
import { type LibraryExtras } from './vars-library';
|
|
3
|
+
/**
|
|
4
|
+
* The editor as the tool provider of a LOCAL MCP server.
|
|
5
|
+
*
|
|
6
|
+
* The tools run here, on the document open in this tab; `scripts/assistant-mcp.ts`
|
|
7
|
+
* only relays them between the MCP client and the tab, and `assistant-tools.ts`
|
|
8
|
+
* describes them. Exactly one tab is connected at a time: the one where the
|
|
9
|
+
* user last pressed « Assistant ». The model never chooses which editor it
|
|
10
|
+
* drives, and it never sees a URL, a token or the package — only paragraphs,
|
|
11
|
+
* addressed by index.
|
|
12
|
+
*
|
|
13
|
+
* Every writing call runs in `Editor.batch`: one Ctrl/Cmd+Z takes it back, and
|
|
14
|
+
* a call that fails halfway leaves nothing behind.
|
|
15
|
+
*/
|
|
16
|
+
export interface AssistantOptions {
|
|
17
|
+
/** the relay started by `scripts/assistant-mcp.ts` */
|
|
18
|
+
url?: string;
|
|
19
|
+
}
|
|
20
|
+
type Args = Record<string, unknown>;
|
|
21
|
+
export declare function runTool(handle: DocxEditorHandle, name: string, args: Args, library?: () => LibraryExtras): unknown;
|
|
22
|
+
/** The « Assistant » button of the status bar, and the connection it opens. */
|
|
23
|
+
export declare function mountAssistant(status: HTMLElement, handle: DocxEditorHandle, options?: AssistantOptions, library?: () => LibraryExtras): () => void;
|
|
24
|
+
export {};
|
|
@@ -194,6 +194,16 @@ export declare function createEditor(setup: EditorSetup): {
|
|
|
194
194
|
replaceAll(query: string, replacement: string, matchCase?: boolean): number;
|
|
195
195
|
/** Insère du texte au curseur, ou remplace la sélection. */
|
|
196
196
|
insert: (text: string, patch?: RunPatch) => void;
|
|
197
|
+
/**
|
|
198
|
+
* Pastes HTML after the caret's paragraph, as one undo step, through the
|
|
199
|
+
* clipboard's own path: whatever `htmlToBlocks` cannot express is dropped.
|
|
200
|
+
*/
|
|
201
|
+
pasteHtml(html: string): boolean;
|
|
202
|
+
/**
|
|
203
|
+
* Inserts raw `w:p` / `w:tbl` XML after a body paragraph, as one undo step,
|
|
204
|
+
* and returns how many paragraphs it added. Throws why the XML was refused.
|
|
205
|
+
*/
|
|
206
|
+
insertOoxml(para: number, xml: string): number;
|
|
197
207
|
deleteSelection: () => void;
|
|
198
208
|
deleteObject: () => void;
|
|
199
209
|
splitAtCaret: () => void;
|
|
@@ -213,6 +223,10 @@ export declare function createEditor(setup: EditorSetup): {
|
|
|
213
223
|
currentSection: () => number;
|
|
214
224
|
/** Section à laquelle appartient une page dessinée — ce que la règle suit. */
|
|
215
225
|
sectionOfPage(page: number): number;
|
|
226
|
+
batch: <T>(fn: () => T) => {
|
|
227
|
+
value: T;
|
|
228
|
+
changed: boolean;
|
|
229
|
+
};
|
|
216
230
|
undo: () => void;
|
|
217
231
|
redo: () => void;
|
|
218
232
|
canUndo: () => boolean;
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
*
|
|
8
8
|
* React: `import { DocxEditor } from 'myrole-docx-editor/react'`.
|
|
9
9
|
*/
|
|
10
|
-
export { createDocxEditor } from './sdk';
|
|
10
|
+
export { createDocxEditor, DOCX_EDITOR_VERSION } from './sdk';
|
|
11
11
|
export type { DocxEditorHandle, DocxEditorOptions, DocxEditorUiOptions, DocxEditorEvent, ChromeMode, Theme } from './sdk';
|
|
12
12
|
export type { FeedbackReport, FeedbackContext, FeedbackOptions } from './feedback';
|
|
13
|
+
export type { AssistantOptions } from './assistant';
|
|
13
14
|
export { renderDocx } from './embed';
|
|
14
15
|
export type { Rendered } from './embed';
|
|
15
16
|
export { installFonts, defaultFontsUrl } from './fonts';
|
|
@@ -22,6 +22,7 @@ export declare const DocxEditor: import("react").ForwardRefExoticComponent<DocxE
|
|
|
22
22
|
/** A ref to hand to `<DocxEditor ref={…}>`, and the handle once it exists. */
|
|
23
23
|
export declare function useDocxEditor(): import("react").RefObject<DocxEditorHandle | null>;
|
|
24
24
|
export type { DocxEditorHandle, DocxEditorOptions } from './sdk';
|
|
25
|
+
export { DOCX_EDITOR_VERSION } from './sdk';
|
|
25
26
|
/** Read-only companion, with the same rendering and lifecycle as the editor. */
|
|
26
27
|
export declare const DocxViewer: import("react").ForwardRefExoticComponent<DocxEditorProps & import("react").RefAttributes<DocxEditorHandle | null>>;
|
|
27
28
|
export declare const DOCX_LOCKING_VERSION = 1;
|
|
@@ -21,6 +21,9 @@ import { type CommentRange } from './comments';
|
|
|
21
21
|
import { type Panel, type DocxEditorUiOptions } from './ui/shell';
|
|
22
22
|
import { type Draft } from './drafts';
|
|
23
23
|
import { type FeedbackOptions } from './feedback';
|
|
24
|
+
import { type AssistantOptions } from './assistant';
|
|
25
|
+
/** The published version of this package, as the status bar shows it. */
|
|
26
|
+
export declare const DOCX_EDITOR_VERSION: string;
|
|
24
27
|
export type ChromeMode = 'full' | 'viewer' | 'none';
|
|
25
28
|
export type Theme = 'light' | 'dark' | 'system';
|
|
26
29
|
export type { DocxEditorUiOptions } from './ui/shell';
|
|
@@ -70,6 +73,8 @@ export interface DocxEditorOptions {
|
|
|
70
73
|
comments?: boolean;
|
|
71
74
|
/** Opt-in feedback button: true exports JSON; onSubmit routes the report to the host. */
|
|
72
75
|
feedback?: boolean | FeedbackOptions;
|
|
76
|
+
/** Opt-in « Assistant » button: lends this tab's document to the local MCP relay (`scripts/assistant-mcp.ts`). */
|
|
77
|
+
assistant?: boolean | AssistantOptions;
|
|
73
78
|
}
|
|
74
79
|
export interface DocxEditorHandle {
|
|
75
80
|
load(src: ArrayBuffer | Uint8Array | Blob | string, options?: {
|
|
@@ -17,6 +17,8 @@ export interface DocxDocument {
|
|
|
17
17
|
/** ordre original des entrées du zip, pour rebuild déterministe */
|
|
18
18
|
order: string[];
|
|
19
19
|
}
|
|
20
|
+
/** Parses XML into the same ordered tree as a package part. */
|
|
21
|
+
export declare const parseXml: (xml: string) => XmlTree;
|
|
20
22
|
export declare function readDocx(buf: Uint8Array): DocxDocument;
|
|
21
23
|
export declare function writeDocx(doc: DocxDocument): Uint8Array;
|
|
22
24
|
/** Nom de balise d'un noeud ordonné (les clés `:@` / `#text` sont des métadonnées). */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DocxDocument } from './index';
|
|
1
|
+
import { type DocxDocument, type XmlNode } from './index';
|
|
2
2
|
import { type DocPos } from './editor';
|
|
3
3
|
import { type PastedRun } from './insert';
|
|
4
4
|
/**
|
|
@@ -55,3 +55,14 @@ export declare function ensureListNum(doc: DocxDocument, ordered: boolean): numb
|
|
|
55
55
|
* paragraphe comme un autre dans l'adressage du modèle.
|
|
56
56
|
*/
|
|
57
57
|
export declare function pasteBlocks(doc: DocxDocument, at: DocPos, blocks: PastedBlock[]): DocPos | null;
|
|
58
|
+
/**
|
|
59
|
+
* Parses, checks and orders `w:p` / `w:tbl` blocks written as XML text, for
|
|
60
|
+
* `insertBlocksAfter`. Throws with the reason, phrased for the writer to fix it.
|
|
61
|
+
*/
|
|
62
|
+
export declare function ooxmlBlocks(doc: DocxDocument, xml: string): XmlNode[];
|
|
63
|
+
/**
|
|
64
|
+
* Inserts blocks after a body paragraph — in its cell when it has one — and
|
|
65
|
+
* returns how many paragraphs that adds. A table never ends a cell or the body:
|
|
66
|
+
* Word wants a paragraph after it.
|
|
67
|
+
*/
|
|
68
|
+
export declare function insertBlocksAfter(doc: DocxDocument, para: number, blocks: XmlNode[]): number | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myrole-docx-editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Word-faithful .docx editor and renderer on canvas — the MyRole engine as an embeddable SDK, with a React component.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"react": "^19.2.8",
|
|
46
46
|
"react-dom": "^19.2.8",
|
|
47
47
|
"vite": "^6.4.3",
|
|
48
|
-
"@myrole/docx-model": "0.0.0",
|
|
49
48
|
"@myrole/docx-render": "0.0.0",
|
|
50
49
|
"@myrole/docx-tags": "0.0.0",
|
|
50
|
+
"@myrole/docx-model": "0.0.0",
|
|
51
51
|
"@myrole/docx-vars": "0.0.0",
|
|
52
52
|
"@myrole/fonts": "0.1.0"
|
|
53
53
|
},
|
|
@@ -56,11 +56,15 @@
|
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"fonts": "node scripts/pack-fonts.mjs",
|
|
59
|
-
"build": "node scripts/pack-fonts.mjs && vite build && node scripts/types.mjs",
|
|
59
|
+
"build": "node scripts/pack-fonts.mjs && vite build && vite build --config vite.assistant.config.ts && node scripts/types.mjs",
|
|
60
60
|
"watch": "vite build --watch",
|
|
61
|
-
"check": "node scripts/pack-fonts.mjs && tsc -p tsconfig.json && tsx scripts/locking.test.ts",
|
|
61
|
+
"check": "node scripts/pack-fonts.mjs && tsc -p tsconfig.json && tsx scripts/locking.test.ts && tsx scripts/assistant-mcp.test.ts",
|
|
62
|
+
"assistant": "tsx scripts/assistant-mcp.ts",
|
|
62
63
|
"types": "node scripts/types.mjs"
|
|
63
64
|
},
|
|
65
|
+
"bin": {
|
|
66
|
+
"myrole-docx-assistant": "./dist/assistant-mcp.mjs"
|
|
67
|
+
},
|
|
64
68
|
"typesVersions": {
|
|
65
69
|
"*": {
|
|
66
70
|
"react": [
|