prosemirror-suggestcat-plugin 0.0.9 → 0.0.11

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.
@@ -0,0 +1 @@
1
+ import{PluginKey as t,Plugin as e}from"prosemirror-state";import{Decoration as n,DecorationSet as o}from"prosemirror-view";import r from"fast-diff";import i from"lodash.debounce";const s=new t("grammarSuggestPlugin"),a=t=>{let e="";return t.descendants(((t,n)=>{t.isText&&(e+=`${t.text}\n`)})),e},c=(t,e)=>{if(t===e)return{start:t.length,end:t.length,oldStart:t.length,oldEnd:t.length,oldText:"",newText:""};const n=r(t,e),o=n[0],i=o[0]===r.EQUAL?o[1].length-1:0,s=((t,e)=>{if(e[e.length-1][0]!==r.EQUAL)return t.length;const n=e.slice(0,e.length-1);let o=0;for(const t of n){const[e,n]=t;e===r.EQUAL&&(o+=n.length),e===r.DELETE&&(o+=n.length)}return o})(t,n),a=t.lastIndexOf("\n",i),c=t.indexOf("\n",s),l=-1===a?0:a+1,p=-1===c?t.length:c,g=t.slice(l,p),d=e.slice(l,e.length-(t.length-p));return{start:l,end:l+d.length,oldStart:l,oldEnd:p,oldText:g,newText:d}};var l,p;function g(t,e,n,o){return new(n||(n=Promise))((function(r,i){function s(t){try{c(o.next(t))}catch(t){i(t)}}function a(t){try{c(o.throw(t))}catch(t){i(t)}}function c(t){var e;t.done?r(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,a)}c((o=o.apply(t,e||[])).next())}))}!function(t){t.suggestionUpdate="suggestionUpdate",t.acceptSuggestion="acceptSuggestion",t.openSuggestion="openSuggestion",t.closeSuggestion="closeSuggestion",t.discardSuggestion="discardSuggestion"}(l||(l={})),function(t){t.grammarSuggestPopup="grammar-suggest-popup"}(p||(p={}));const d=[{docPos:1,textPos:0}],u=t=>{let e="";const n=[];return t.descendants(((t,o)=>{t.isText&&(n.push({docPos:o,textPos:e.length}),e+=`${t.text}\n`)})),{text:e,mapping:n.length?n:d}},m=(t,e)=>{for(let n=0;n<e.length;n++)if(t>=e[n].textPos&&(void 0===e[n+1]||t<e[n+1].textPos))return e[n].docPos+(t-e[n].textPos);throw new Error("textPositionToDocumentPosition: textPos not found in mapping")},f=(t,e)=>g(void 0,void 0,void 0,(function*(){const n=[...e.split("\n")];return fetch("https://prosemirror-ai-plugin.web.app/api/suggestion",{method:"POST",cache:"no-cache",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:"gpt-3.5-turbo",modelParams:{input:n}})}).then((t=>t.ok?t.json():Promise.reject(t))).then((t=>t&&t.some((t=>(t=>{try{JSON.parse(t)}catch(t){return!1}return!0})(t)))?{result:t.map((t=>JSON.parse(t).result)).join("\n"),fixed:!0}:{fixed:!1,result:e})).catch((t=>(t.text().then((e=>{console.error({status:t.status,text:e})})),{fixed:!1,result:e})))})),h=t=>t.replacement===t.original,x=t=>t.reduce(((t,e)=>{const n=t[t.length-1],o=t.slice(0,t.length-1);if(!n)return[e];return[...o,...((t,e)=>{if(t.to!==e.from)throw new Error(`Replace pairs must be adjacent\n\n, ${JSON.stringify({leftReplace:t,rightReplace:e})}`);if(t.replacement.endsWith("\n"))return[t,e];if(h(t)&&h(e))return[{from:t.from,to:e.to,original:t.original+e.original,replacement:t.replacement+e.replacement}];if(h(t)){if(e.replacement.startsWith(" ")&&""===e.original||e.original.startsWith(" ")&&""===e.replacement)return[t,e];const n=t.original.split(" "),o=n.pop()||"",r=n.join(" ")+(n.length?" ":"");return[...r.length?[{from:t.from,to:t.from+r.length,original:r,replacement:r}]:[],{from:t.from+r.length,to:e.to,original:o+e.original,replacement:o+e.replacement}]}if(h(e)){if(t.replacement.endsWith(" ")&&""===t.original||t.original.endsWith(" ")&&""===t.replacement)return[t,e];const n=e.original.split(" "),o=n.shift()||"",r=(n.length?" ":"")+n.join(" ");return" "===r?[{from:t.from,to:e.to,original:t.original+e.original,replacement:t.replacement+e.replacement}]:[{from:t.from,to:t.to+o.length,original:t.original+o,replacement:t.replacement+o},...r.length?[{from:t.to+o.length,to:e.to,original:r,replacement:r}]:[]]}return[{from:t.from,to:e.to,original:t.original+e.original,replacement:t.replacement+e.replacement}]})(n,e)]}),[]),S=(t,e)=>{const n=(t=>{let e=0;return t.map((([t,n])=>{switch(t){case r.EQUAL:const t=n.lastIndexOf("\n"),o={from:e,to:e+n.length,original:n,replacement:n};if(-1!==t&&"\n"!==n){const o=[{from:e,to:e+t+1,original:n.slice(0,t+1),replacement:n.slice(0,t+1)},{from:e+t+1,to:e+n.length,original:n.slice(t+1),replacement:n.slice(t+1)}];return e+=n.length,o}return e+=n.length,[o];case r.DELETE:const i={from:e,to:e+n.length,original:n,replacement:""};return e+=n.length,[i];case r.INSERT:return[{from:e,to:e,original:"",replacement:n}]}})).flat()})(r(t,e));return x(x(n))},v=(t,e)=>{var n;const o=null===(n=s.getState(t.state))||void 0===n?void 0:n.decorations.find(0,t.state.doc.nodeSize,(t=>t.id===e.spec.id))[0];if(!o)return;const{text:r}=o.spec,{from:i,to:a}=o,c={type:l.acceptSuggestion,id:e.spec.id},p=t.state.tr.insertText(r,i,a).setMeta(s,c);t.dispatch(p)},y=(t,e)=>{const{spec:n}=e,o={type:l.discardSuggestion,id:n.id},r=t.state.tr.setMeta(s,o);t.dispatch(r)},w=(t,e)=>{const n=s.getState(t.state);if(!n)return!1;const{decorations:o}=n,r=o.find(e,e)[0];if(!r){const e={type:l.closeSuggestion};return t.dispatch(t.state.tr.setMeta(s,e)),!1}const i=n.popupDecoration.find()[0];if((null==i?void 0:i.spec.id)===r.spec.id)return!1;const a={type:l.openSuggestion,decoration:r};return t.dispatch(t.state.tr.setMeta(s,a)),!1},T={debounceMs:2e3,createUpdatePopup:(t,e,n,o,r)=>{const i=document.createElement("div");i.className="grammar-suggest-tooltip";const{spec:s}=e,a=t.dom.getBoundingClientRect();i.id=p.grammarSuggestPopup;const c=t.coordsAtPos(n);i.style.left=c.left-a.left+"px",i.style.top=c.bottom-a.top+5+"px";const l=document.createElement("div");l.className="grammar-suggest-tooltip-apply",l.innerText=s.text||s.originalText,s.text||(l.style.textDecoration="line-through",l.style.color="red"),l.onclick=()=>{o(t,e)},i.appendChild(l);const g=document.createElement("div");return g.innerHTML="<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'><path d='M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 10.5858L14.8284 7.75736L16.2426 9.17157L13.4142 12L16.2426 14.8284L14.8284 16.2426L12 13.4142L9.17157 16.2426L7.75736 14.8284L10.5858 12L7.75736 9.17157L9.17157 7.75736L12 10.5858Z'></path></svg>",g.className="grammar-suggest-tooltip-discard",g.onclick=()=>{r(t,e)},i.appendChild(g),i}},b=(t,r=T)=>{let p=!1;return new e({key:s,state:{init:()=>({lastText:"",decorations:o.empty,popupDecoration:o.empty}),apply(t,e,i,p){const g=t.getMeta(s);return(null==g?void 0:g.type)===l.suggestionUpdate?((t,e,o)=>{const{changedRegion:r,fix:i,mapping:s,text:a}=e,c=S(r.newText,i.result).filter((t=>!h(t))).filter((t=>t.original!==`${t.replacement}\n`)).map((({from:t,to:e,original:o,replacement:i})=>{const a=m(r.start+t,s),c=m(r.start+(i.endsWith("\n")?e-1:e),s),l={text:i.endsWith("\n")?i.slice(0,-1):i,originalText:o,id:{}};return n.inline(a,c,{class:"grammarSuggestion "+(""===i?"removalSuggestion":"")},l)}));return Object.assign(Object.assign({},t),{decorations:t.decorations.add(o.doc,c),lastText:a})})(e,g,t):(null==g?void 0:g.type)===l.acceptSuggestion?((t,e,n)=>{const r=t.decorations.remove(t.decorations.find(0,n.doc.nodeSize,(t=>t.id===e.id)));return Object.assign(Object.assign({},t),{lastText:a(n.doc),decorations:r.map(n.mapping,n.doc),popupDecoration:o.empty})})(e,g,t):(null==g?void 0:g.type)===l.openSuggestion?((t,e,r,i)=>{const{decoration:s}=e,a={id:s.spec.id};return Object.assign(Object.assign({},t),{popupDecoration:o.create(r.doc,[n.widget(s.from,((t,e)=>{const n=e();return n?i.createUpdatePopup(t,s,n,v,y):document.createElement("div")}),Object.assign(Object.assign({},a),{stopEvent:()=>!0}))])})})(e,g,t,r):(null==g?void 0:g.type)===l.closeSuggestion?Object.assign(Object.assign({},e),{popupDecoration:o.empty}):(null==g?void 0:g.type)===l.discardSuggestion?((t,e,n)=>Object.assign(Object.assign({},t),{decorations:t.decorations.remove(t.decorations.find(0,n.doc.nodeSize,(t=>t.id===e.id))),popupDecoration:o.empty}))(e,g,t):t.docChanged?((t,e,n)=>{const o=u(n.doc).text,{text:r,mapping:i}=u(e.doc);if(r===o)return t;const s=c(o,r),a=t.decorations.map(e.mapping,e.doc),l=m(s.start,i),p=m(s.end,i),g=t.popupDecoration.map(e.mapping,e.doc);return Object.assign(Object.assign({},t),{decorations:a.remove(a.find(l,p)),popupDecoration:g.remove(g.find(l,p))})})(e,t,i):e}},props:{handleClick:w,decorations:t=>{const e=s.getState(t);return e?e.decorations.add(t.doc,e.popupDecoration.find()):null}},view(){const e=((t,e)=>i((t=>{var n;const o=u(t.state.doc),r=(null===(n=s.getState(t.state))||void 0===n?void 0:n.lastText)||"",i=c(r,o.text);f(e,i.newText).then((e=>{if(a(t.state.doc)!==o.text)return;const n={type:l.suggestionUpdate,fix:e,changedRegion:i,mapping:o.mapping,text:o.text};t.dispatch(t.state.tr.setMeta(s,n))})).catch((t=>{console.error("Grammar suggest API error",t)}))}),t.debounceMs))(r,t);return{update(t,n){const o=s.getState(t.state);t.state.doc.textBetween(0,t.state.doc.nodeSize-2,"/n")===n.doc.textBetween(0,n.doc.nodeSize-2,"/n")&&p||!o||o.lastText===a(t.state.doc)||(p=!0,e(t))}}}})};export{T as defaultOptions,b as grammarSuggestPlugin};
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var t=require("prosemirror-state"),e=require("prosemirror-view"),n=require("fast-diff"),o=require("lodash.debounce");const r=new t.PluginKey("grammarSuggestPlugin"),i=t=>{let e="";return t.descendants(((t,n)=>{t.isText&&(e+=`${t.text}\n`)})),e},s=(t,e)=>{if(t===e)return{start:t.length,end:t.length,oldStart:t.length,oldEnd:t.length,oldText:"",newText:""};const o=n(t,e),r=o[0],i=r[0]===n.EQUAL?r[1].length-1:0,s=((t,e)=>{if(e[e.length-1][0]!==n.EQUAL)return t.length;const o=e.slice(0,e.length-1);let r=0;for(const t of o){const[e,o]=t;e===n.EQUAL&&(r+=o.length),e===n.DELETE&&(r+=o.length)}return r})(t,o),a=t.lastIndexOf("\n",i),c=t.indexOf("\n",s),l=-1===a?0:a+1,g=-1===c?t.length:c,p=t.slice(l,g),d=e.slice(l,e.length-(t.length-g));return{start:l,end:l+d.length,oldStart:l,oldEnd:g,oldText:p,newText:d}};var a,c;function l(t,e,n,o){return new(n||(n=Promise))((function(r,i){function s(t){try{c(o.next(t))}catch(t){i(t)}}function a(t){try{c(o.throw(t))}catch(t){i(t)}}function c(t){var e;t.done?r(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,a)}c((o=o.apply(t,e||[])).next())}))}!function(t){t.suggestionUpdate="suggestionUpdate",t.acceptSuggestion="acceptSuggestion",t.openSuggestion="openSuggestion",t.closeSuggestion="closeSuggestion",t.discardSuggestion="discardSuggestion"}(a||(a={})),function(t){t.grammarSuggestPopup="grammar-suggest-popup"}(c||(c={}));const g=[{docPos:1,textPos:0}],p=t=>{let e="";const n=[];return t.descendants(((t,o)=>{t.isText&&(n.push({docPos:o,textPos:e.length}),e+=`${t.text}\n`)})),{text:e,mapping:n.length?n:g}},d=(t,e)=>{for(let n=0;n<e.length;n++)if(t>=e[n].textPos&&(void 0===e[n+1]||t<e[n+1].textPos))return e[n].docPos+(t-e[n].textPos);throw new Error("textPositionToDocumentPosition: textPos not found in mapping")},u=(t,e)=>l(void 0,void 0,void 0,(function*(){const n=[...e.split("\n")];return fetch("https://prosemirror-ai-plugin.web.app/api/suggestion",{method:"POST",cache:"no-cache",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:"gpt-3.5-turbo",modelParams:{input:n}})}).then((t=>t.ok?t.json():Promise.reject(t))).then((t=>t&&t.some((t=>(t=>{try{JSON.parse(t)}catch(t){return!1}return!0})(t)))?{result:t.map((t=>JSON.parse(t).result)).join("\n"),fixed:!0}:{fixed:!1,result:e})).catch((t=>(t.text().then((e=>{console.error({status:t.status,text:e})})),{fixed:!1,result:e})))})),m=t=>t.replacement===t.original,f=t=>t.reduce(((t,e)=>{const n=t[t.length-1],o=t.slice(0,t.length-1);if(!n)return[e];return[...o,...((t,e)=>{if(t.to!==e.from)throw new Error(`Replace pairs must be adjacent\n\n, ${JSON.stringify({leftReplace:t,rightReplace:e})}`);if(t.replacement.endsWith("\n"))return[t,e];if(m(t)&&m(e))return[{from:t.from,to:e.to,original:t.original+e.original,replacement:t.replacement+e.replacement}];if(m(t)){if(e.replacement.startsWith(" ")&&""===e.original||e.original.startsWith(" ")&&""===e.replacement)return[t,e];const n=t.original.split(" "),o=n.pop()||"",r=n.join(" ")+(n.length?" ":"");return[...r.length?[{from:t.from,to:t.from+r.length,original:r,replacement:r}]:[],{from:t.from+r.length,to:e.to,original:o+e.original,replacement:o+e.replacement}]}if(m(e)){if(t.replacement.endsWith(" ")&&""===t.original||t.original.endsWith(" ")&&""===t.replacement)return[t,e];const n=e.original.split(" "),o=n.shift()||"",r=(n.length?" ":"")+n.join(" ");return" "===r?[{from:t.from,to:e.to,original:t.original+e.original,replacement:t.replacement+e.replacement}]:[{from:t.from,to:t.to+o.length,original:t.original+o,replacement:t.replacement+o},...r.length?[{from:t.to+o.length,to:e.to,original:r,replacement:r}]:[]]}return[{from:t.from,to:e.to,original:t.original+e.original,replacement:t.replacement+e.replacement}]})(n,e)]}),[]),h=(t,e)=>{const o=(t=>{let e=0;return t.map((([t,o])=>{switch(t){case n.EQUAL:const t=o.lastIndexOf("\n"),r={from:e,to:e+o.length,original:o,replacement:o};if(-1!==t&&"\n"!==o){const n=[{from:e,to:e+t+1,original:o.slice(0,t+1),replacement:o.slice(0,t+1)},{from:e+t+1,to:e+o.length,original:o.slice(t+1),replacement:o.slice(t+1)}];return e+=o.length,n}return e+=o.length,[r];case n.DELETE:const i={from:e,to:e+o.length,original:o,replacement:""};return e+=o.length,[i];case n.INSERT:return[{from:e,to:e,original:"",replacement:o}]}})).flat()})(n(t,e));return f(f(o))},x=(t,e)=>{var n;const o=null===(n=r.getState(t.state))||void 0===n?void 0:n.decorations.find(0,t.state.doc.nodeSize,(t=>t.id===e.spec.id))[0];if(!o)return;const{text:i}=o.spec,{from:s,to:c}=o,l={type:a.acceptSuggestion,id:e.spec.id},g=t.state.tr.insertText(i,s,c).setMeta(r,l);t.dispatch(g)},S=(t,e)=>{const{spec:n}=e,o={type:a.discardSuggestion,id:n.id},i=t.state.tr.setMeta(r,o);t.dispatch(i)},v=(t,e)=>{const n=r.getState(t.state);if(!n)return!1;const{decorations:o}=n,i=o.find(e,e)[0];if(!i){const e={type:a.closeSuggestion};return t.dispatch(t.state.tr.setMeta(r,e)),!1}const s=n.popupDecoration.find()[0];if((null==s?void 0:s.spec.id)===i.spec.id)return!1;const c={type:a.openSuggestion,decoration:i};return t.dispatch(t.state.tr.setMeta(r,c)),!1},y={debounceMs:2e3,createUpdatePopup:(t,e,n,o,r)=>{const i=document.createElement("div");i.className="grammar-suggest-tooltip";const{spec:s}=e,a=t.dom.getBoundingClientRect();i.id=c.grammarSuggestPopup;const l=t.coordsAtPos(n);i.style.left=l.left-a.left+"px",i.style.top=l.bottom-a.top+5+"px";const g=document.createElement("div");g.className="grammar-suggest-tooltip-apply",g.innerText=s.text,g.onclick=()=>{o(t,e)},i.appendChild(g);const p=document.createElement("div");return p.innerHTML="<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'><path d='M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 10.5858L14.8284 7.75736L16.2426 9.17157L13.4142 12L16.2426 14.8284L14.8284 16.2426L12 13.4142L9.17157 16.2426L7.75736 14.8284L10.5858 12L7.75736 9.17157L9.17157 7.75736L12 10.5858Z'></path></svg>",p.className="grammar-suggest-tooltip-discard",p.onclick=()=>{r(t,e)},i.appendChild(p),i}};exports.defaultOptions=y,exports.grammarSuggestPlugin=(n,c=y)=>{let l=!1;return new t.Plugin({key:r,state:{init:()=>({lastText:"",decorations:e.DecorationSet.empty,popupDecoration:e.DecorationSet.empty}),apply(t,n,o,l){const g=t.getMeta(r);return(null==g?void 0:g.type)===a.suggestionUpdate?((t,n,o)=>{const{changedRegion:r,fix:i,mapping:s,text:a}=n,c=h(r.newText,i.result).filter((t=>!m(t))).filter((t=>t.original!==`${t.replacement}\n`)).map((({from:t,to:n,original:o,replacement:i})=>{const a=d(r.start+t,s),c=d(r.start+(i.endsWith("\n")?n-1:n),s),l={text:i.endsWith("\n")?i.slice(0,-1):i,originalText:o,id:{}};return e.Decoration.inline(a,c,{class:"grammarSuggestion"+(""===o?"removalSuggestion":"")},l)}));return Object.assign(Object.assign({},t),{decorations:t.decorations.add(o.doc,c),lastText:a})})(n,g,t):(null==g?void 0:g.type)===a.acceptSuggestion?((t,n,o)=>{const r=t.decorations.remove(t.decorations.find(0,o.doc.nodeSize,(t=>t.id===n.id)));return Object.assign(Object.assign({},t),{lastText:i(o.doc),decorations:r.map(o.mapping,o.doc),popupDecoration:e.DecorationSet.empty})})(n,g,t):(null==g?void 0:g.type)===a.openSuggestion?((t,n,o,r)=>{const{decoration:i}=n,s={id:i.spec.id};return Object.assign(Object.assign({},t),{popupDecoration:e.DecorationSet.create(o.doc,[e.Decoration.widget(i.from,((t,e)=>{const n=e();return n?r.createUpdatePopup(t,i,n,x,S):document.createElement("div")}),Object.assign(Object.assign({},s),{stopEvent:()=>!0}))])})})(n,g,t,c):(null==g?void 0:g.type)===a.closeSuggestion?Object.assign(Object.assign({},n),{popupDecoration:e.DecorationSet.empty}):(null==g?void 0:g.type)===a.discardSuggestion?((t,n,o)=>Object.assign(Object.assign({},t),{decorations:t.decorations.remove(t.decorations.find(0,o.doc.nodeSize,(t=>t.id===n.id))),popupDecoration:e.DecorationSet.empty}))(n,g,t):t.docChanged?((t,e,n)=>{const o=p(n.doc).text,{text:r,mapping:i}=p(e.doc);if(r===o)return t;const a=s(o,r),c=t.decorations.map(e.mapping,e.doc),l=d(a.start,i),g=d(a.end,i),u=t.popupDecoration.map(e.mapping,e.doc);return Object.assign(Object.assign({},t),{decorations:c.remove(c.find(l,g)),popupDecoration:u.remove(u.find(l,g))})})(n,t,o):n}},props:{handleClick:v,decorations:t=>{const e=r.getState(t);return e?e.decorations.add(t.doc,e.popupDecoration.find()):null}},view(){const t=((t,e)=>o((t=>{var n;const o=p(t.state.doc),c=(null===(n=r.getState(t.state))||void 0===n?void 0:n.lastText)||"",l=s(c,o.text);u(e,l.newText).then((e=>{if(i(t.state.doc)!==o.text)return;const n={type:a.suggestionUpdate,fix:e,changedRegion:l,mapping:o.mapping,text:o.text};t.dispatch(t.state.tr.setMeta(r,n))})).catch((t=>{console.error("Grammar suggest API error",t)}))}),t.debounceMs))(c,n);return{update(e,n){const o=r.getState(e.state);e.state.doc.textBetween(0,e.state.doc.nodeSize-2,"/n")===n.doc.textBetween(0,n.doc.nodeSize-2,"/n")&&l||!o||o.lastText===i(e.state.doc)||(l=!0,t(e))}}}})};
1
+ "use strict";var t=require("prosemirror-state"),e=require("prosemirror-view"),n=require("fast-diff"),o=require("lodash.debounce");const r=new t.PluginKey("grammarSuggestPlugin"),i=t=>{let e="";return t.descendants(((t,n)=>{t.isText&&(e+=`${t.text}\n`)})),e},s=(t,e)=>{if(t===e)return{start:t.length,end:t.length,oldStart:t.length,oldEnd:t.length,oldText:"",newText:""};const o=n(t,e),r=o[0],i=r[0]===n.EQUAL?r[1].length-1:0,s=((t,e)=>{if(e[e.length-1][0]!==n.EQUAL)return t.length;const o=e.slice(0,e.length-1);let r=0;for(const t of o){const[e,o]=t;e===n.EQUAL&&(r+=o.length),e===n.DELETE&&(r+=o.length)}return r})(t,o),a=t.lastIndexOf("\n",i),c=t.indexOf("\n",s),l=-1===a?0:a+1,g=-1===c?t.length:c,p=t.slice(l,g),d=e.slice(l,e.length-(t.length-g));return{start:l,end:l+d.length,oldStart:l,oldEnd:g,oldText:p,newText:d}};var a,c;function l(t,e,n,o){return new(n||(n=Promise))((function(r,i){function s(t){try{c(o.next(t))}catch(t){i(t)}}function a(t){try{c(o.throw(t))}catch(t){i(t)}}function c(t){var e;t.done?r(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(s,a)}c((o=o.apply(t,e||[])).next())}))}!function(t){t.suggestionUpdate="suggestionUpdate",t.acceptSuggestion="acceptSuggestion",t.openSuggestion="openSuggestion",t.closeSuggestion="closeSuggestion",t.discardSuggestion="discardSuggestion"}(a||(a={})),function(t){t.grammarSuggestPopup="grammar-suggest-popup"}(c||(c={}));const g=[{docPos:1,textPos:0}],p=t=>{let e="";const n=[];return t.descendants(((t,o)=>{t.isText&&(n.push({docPos:o,textPos:e.length}),e+=`${t.text}\n`)})),{text:e,mapping:n.length?n:g}},d=(t,e)=>{for(let n=0;n<e.length;n++)if(t>=e[n].textPos&&(void 0===e[n+1]||t<e[n+1].textPos))return e[n].docPos+(t-e[n].textPos);throw new Error("textPositionToDocumentPosition: textPos not found in mapping")},u=(t,e)=>l(void 0,void 0,void 0,(function*(){const n=[...e.split("\n")];return fetch("https://prosemirror-ai-plugin.web.app/api/suggestion",{method:"POST",cache:"no-cache",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:"gpt-3.5-turbo",modelParams:{input:n}})}).then((t=>t.ok?t.json():Promise.reject(t))).then((t=>t&&t.some((t=>(t=>{try{JSON.parse(t)}catch(t){return!1}return!0})(t)))?{result:t.map((t=>JSON.parse(t).result)).join("\n"),fixed:!0}:{fixed:!1,result:e})).catch((t=>(t.text().then((e=>{console.error({status:t.status,text:e})})),{fixed:!1,result:e})))})),m=t=>t.replacement===t.original,f=t=>t.reduce(((t,e)=>{const n=t[t.length-1],o=t.slice(0,t.length-1);if(!n)return[e];return[...o,...((t,e)=>{if(t.to!==e.from)throw new Error(`Replace pairs must be adjacent\n\n, ${JSON.stringify({leftReplace:t,rightReplace:e})}`);if(t.replacement.endsWith("\n"))return[t,e];if(m(t)&&m(e))return[{from:t.from,to:e.to,original:t.original+e.original,replacement:t.replacement+e.replacement}];if(m(t)){if(e.replacement.startsWith(" ")&&""===e.original||e.original.startsWith(" ")&&""===e.replacement)return[t,e];const n=t.original.split(" "),o=n.pop()||"",r=n.join(" ")+(n.length?" ":"");return[...r.length?[{from:t.from,to:t.from+r.length,original:r,replacement:r}]:[],{from:t.from+r.length,to:e.to,original:o+e.original,replacement:o+e.replacement}]}if(m(e)){if(t.replacement.endsWith(" ")&&""===t.original||t.original.endsWith(" ")&&""===t.replacement)return[t,e];const n=e.original.split(" "),o=n.shift()||"",r=(n.length?" ":"")+n.join(" ");return" "===r?[{from:t.from,to:e.to,original:t.original+e.original,replacement:t.replacement+e.replacement}]:[{from:t.from,to:t.to+o.length,original:t.original+o,replacement:t.replacement+o},...r.length?[{from:t.to+o.length,to:e.to,original:r,replacement:r}]:[]]}return[{from:t.from,to:e.to,original:t.original+e.original,replacement:t.replacement+e.replacement}]})(n,e)]}),[]),h=(t,e)=>{const o=(t=>{let e=0;return t.map((([t,o])=>{switch(t){case n.EQUAL:const t=o.lastIndexOf("\n"),r={from:e,to:e+o.length,original:o,replacement:o};if(-1!==t&&"\n"!==o){const n=[{from:e,to:e+t+1,original:o.slice(0,t+1),replacement:o.slice(0,t+1)},{from:e+t+1,to:e+o.length,original:o.slice(t+1),replacement:o.slice(t+1)}];return e+=o.length,n}return e+=o.length,[r];case n.DELETE:const i={from:e,to:e+o.length,original:o,replacement:""};return e+=o.length,[i];case n.INSERT:return[{from:e,to:e,original:"",replacement:o}]}})).flat()})(n(t,e));return f(f(o))},x=(t,e)=>{var n;const o=null===(n=r.getState(t.state))||void 0===n?void 0:n.decorations.find(0,t.state.doc.nodeSize,(t=>t.id===e.spec.id))[0];if(!o)return;const{text:i}=o.spec,{from:s,to:c}=o,l={type:a.acceptSuggestion,id:e.spec.id},g=t.state.tr.insertText(i,s,c).setMeta(r,l);t.dispatch(g)},S=(t,e)=>{const{spec:n}=e,o={type:a.discardSuggestion,id:n.id},i=t.state.tr.setMeta(r,o);t.dispatch(i)},v=(t,e)=>{const n=r.getState(t.state);if(!n)return!1;const{decorations:o}=n,i=o.find(e,e)[0];if(!i){const e={type:a.closeSuggestion};return t.dispatch(t.state.tr.setMeta(r,e)),!1}const s=n.popupDecoration.find()[0];if((null==s?void 0:s.spec.id)===i.spec.id)return!1;const c={type:a.openSuggestion,decoration:i};return t.dispatch(t.state.tr.setMeta(r,c)),!1},y={debounceMs:2e3,createUpdatePopup:(t,e,n,o,r)=>{const i=document.createElement("div");i.className="grammar-suggest-tooltip";const{spec:s}=e,a=t.dom.getBoundingClientRect();i.id=c.grammarSuggestPopup;const l=t.coordsAtPos(n);i.style.left=l.left-a.left+"px",i.style.top=l.bottom-a.top+5+"px";const g=document.createElement("div");g.className="grammar-suggest-tooltip-apply",g.innerText=s.text||s.originalText,s.text||(g.style.textDecoration="line-through",g.style.color="red"),g.onclick=()=>{o(t,e)},i.appendChild(g);const p=document.createElement("div");return p.innerHTML="<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'><path d='M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM12 10.5858L14.8284 7.75736L16.2426 9.17157L13.4142 12L16.2426 14.8284L14.8284 16.2426L12 13.4142L9.17157 16.2426L7.75736 14.8284L10.5858 12L7.75736 9.17157L9.17157 7.75736L12 10.5858Z'></path></svg>",p.className="grammar-suggest-tooltip-discard",p.onclick=()=>{r(t,e)},i.appendChild(p),i}};exports.defaultOptions=y,exports.grammarSuggestPlugin=(n,c=y)=>{let l=!1;return new t.Plugin({key:r,state:{init:()=>({lastText:"",decorations:e.DecorationSet.empty,popupDecoration:e.DecorationSet.empty}),apply(t,n,o,l){const g=t.getMeta(r);return(null==g?void 0:g.type)===a.suggestionUpdate?((t,n,o)=>{const{changedRegion:r,fix:i,mapping:s,text:a}=n,c=h(r.newText,i.result).filter((t=>!m(t))).filter((t=>t.original!==`${t.replacement}\n`)).map((({from:t,to:n,original:o,replacement:i})=>{const a=d(r.start+t,s),c=d(r.start+(i.endsWith("\n")?n-1:n),s),l={text:i.endsWith("\n")?i.slice(0,-1):i,originalText:o,id:{}};return e.Decoration.inline(a,c,{class:"grammarSuggestion "+(""===i?"removalSuggestion":"")},l)}));return Object.assign(Object.assign({},t),{decorations:t.decorations.add(o.doc,c),lastText:a})})(n,g,t):(null==g?void 0:g.type)===a.acceptSuggestion?((t,n,o)=>{const r=t.decorations.remove(t.decorations.find(0,o.doc.nodeSize,(t=>t.id===n.id)));return Object.assign(Object.assign({},t),{lastText:i(o.doc),decorations:r.map(o.mapping,o.doc),popupDecoration:e.DecorationSet.empty})})(n,g,t):(null==g?void 0:g.type)===a.openSuggestion?((t,n,o,r)=>{const{decoration:i}=n,s={id:i.spec.id};return Object.assign(Object.assign({},t),{popupDecoration:e.DecorationSet.create(o.doc,[e.Decoration.widget(i.from,((t,e)=>{const n=e();return n?r.createUpdatePopup(t,i,n,x,S):document.createElement("div")}),Object.assign(Object.assign({},s),{stopEvent:()=>!0}))])})})(n,g,t,c):(null==g?void 0:g.type)===a.closeSuggestion?Object.assign(Object.assign({},n),{popupDecoration:e.DecorationSet.empty}):(null==g?void 0:g.type)===a.discardSuggestion?((t,n,o)=>Object.assign(Object.assign({},t),{decorations:t.decorations.remove(t.decorations.find(0,o.doc.nodeSize,(t=>t.id===n.id))),popupDecoration:e.DecorationSet.empty}))(n,g,t):t.docChanged?((t,e,n)=>{const o=p(n.doc).text,{text:r,mapping:i}=p(e.doc);if(r===o)return t;const a=s(o,r),c=t.decorations.map(e.mapping,e.doc),l=d(a.start,i),g=d(a.end,i),u=t.popupDecoration.map(e.mapping,e.doc);return Object.assign(Object.assign({},t),{decorations:c.remove(c.find(l,g)),popupDecoration:u.remove(u.find(l,g))})})(n,t,o):n}},props:{handleClick:v,decorations:t=>{const e=r.getState(t);return e?e.decorations.add(t.doc,e.popupDecoration.find()):null}},view(){const t=((t,e)=>o((t=>{var n;const o=p(t.state.doc),c=(null===(n=r.getState(t.state))||void 0===n?void 0:n.lastText)||"",l=s(c,o.text);u(e,l.newText).then((e=>{if(i(t.state.doc)!==o.text)return;const n={type:a.suggestionUpdate,fix:e,changedRegion:l,mapping:o.mapping,text:o.text};t.dispatch(t.state.tr.setMeta(r,n))})).catch((t=>{console.error("Grammar suggest API error",t)}))}),t.debounceMs))(c,n);return{update(e,n){const o=r.getState(e.state);e.state.doc.textBetween(0,e.state.doc.nodeSize-2,"/n")===n.doc.textBetween(0,n.doc.nodeSize-2,"/n")&&l||!o||o.lastText===i(e.state.doc)||(l=!0,t(e))}}}})};
@@ -6,7 +6,7 @@
6
6
  background-color: green;
7
7
  }
8
8
 
9
- .grammarSuggestion .removalSuggestion {
9
+ .removalSuggestion {
10
10
  background-color: red;
11
11
  }
12
12
 
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "prosemirror-suggestcat-plugin",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "module": "dist/index.es.js",
7
8
  "scripts": {
8
9
  "prebuild": "rimraf dist",
9
10
  "build": "rollup -c --bundleConfigAsCjs",
@@ -42,14 +43,12 @@
42
43
  "prosemirror-model": "^1.18.3",
43
44
  "prosemirror-state": "^1.4.2",
44
45
  "prosemirror-test-builder": "^1.1.1",
45
- "prosemirror-view": "^1.29.1"
46
+ "prosemirror-transform": "^1.7.3",
47
+ "prosemirror-view": "^1.31.5"
46
48
  },
47
49
  "devDependencies": {
48
50
  "@types/jest": "^29.5.1",
49
51
  "@types/lodash.debounce": "^4.0.7",
50
- "@types/prosemirror-model": "^1.17.0",
51
- "@types/prosemirror-state": "^1.4.0",
52
- "@types/prosemirror-view": "^1.24.0",
53
52
  "@typescript-eslint/eslint-plugin": "^5.59.11",
54
53
  "jest": "^29.5.0",
55
54
  "np": "^7.6.2",
@@ -59,7 +58,7 @@
59
58
  "rollup-plugin-copy": "^3.4.0",
60
59
  "rollup-plugin-minification": "^0.2.0",
61
60
  "rollup-plugin-peer-deps-external": "^2.2.4",
62
- "rollup-plugin-typescript2": "^0.34.1",
61
+ "rollup-plugin-typescript2": "^0.35.0",
63
62
  "ts-jest": "^29.1.0",
64
63
  "typescript": "^4.9.4"
65
64
  }