@iodev/patch-and-resolve 1.0.6
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/LICENSE +674 -0
- package/README.md +402 -0
- package/dist/components/ConflictModal.d.ts +23 -0
- package/dist/components/PatchManager.d.ts +10 -0
- package/dist/hooks/usePatchManager.d.ts +17 -0
- package/dist/index.d.ts +9 -0
- package/dist/patch-and-resolve.es.js +1450 -0
- package/dist/patch-and-resolve.umd.js +30 -0
- package/dist/services/ConflictResolver.d.ts +41 -0
- package/dist/types/index.d.ts +76 -0
- package/dist/utils/deepPath.d.ts +40 -0
- package/dist/utils/jsonPatchAdapter.d.ts +44 -0
- package/package.json +79 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
(function(O,w){typeof exports=="object"&&typeof module<"u"?w(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],w):(O=typeof globalThis<"u"?globalThis:O||self,w(O.PatchAndResolve={},O.React))})(this,(function(O,w){"use strict";var re={exports:{}},G={};/**
|
|
2
|
+
* @license React
|
|
3
|
+
* react-jsx-runtime.production.min.js
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
6
|
+
*
|
|
7
|
+
* This source code is licensed under the MIT license found in the
|
|
8
|
+
* LICENSE file in the root directory of this source tree.
|
|
9
|
+
*/var xe;function He(){if(xe)return G;xe=1;var s=w,o=Symbol.for("react.element"),u=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,a=s.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,g={key:!0,ref:!0,__self:!0,__source:!0};function v(y,d,C){var m,l={},p=null,j=null;C!==void 0&&(p=""+C),d.key!==void 0&&(p=""+d.key),d.ref!==void 0&&(j=d.ref);for(m in d)i.call(d,m)&&!g.hasOwnProperty(m)&&(l[m]=d[m]);if(y&&y.defaultProps)for(m in d=y.defaultProps,d)l[m]===void 0&&(l[m]=d[m]);return{$$typeof:o,type:y,key:p,ref:j,props:l,_owner:a.current}}return G.Fragment=u,G.jsx=v,G.jsxs=v,G}var X={};/**
|
|
10
|
+
* @license React
|
|
11
|
+
* react-jsx-runtime.development.js
|
|
12
|
+
*
|
|
13
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
14
|
+
*
|
|
15
|
+
* This source code is licensed under the MIT license found in the
|
|
16
|
+
* LICENSE file in the root directory of this source tree.
|
|
17
|
+
*/var ye;function Ke(){return ye||(ye=1,process.env.NODE_ENV!=="production"&&(function(){var s=w,o=Symbol.for("react.element"),u=Symbol.for("react.portal"),i=Symbol.for("react.fragment"),a=Symbol.for("react.strict_mode"),g=Symbol.for("react.profiler"),v=Symbol.for("react.provider"),y=Symbol.for("react.context"),d=Symbol.for("react.forward_ref"),C=Symbol.for("react.suspense"),m=Symbol.for("react.suspense_list"),l=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),j=Symbol.for("react.offscreen"),P=Symbol.iterator,N="@@iterator";function V(e){if(e===null||typeof e!="object")return null;var r=P&&e[P]||e[N];return typeof r=="function"?r:null}var A=s.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;function k(e){{for(var r=arguments.length,t=new Array(r>1?r-1:0),c=1;c<r;c++)t[c-1]=arguments[c];L("error",e,t)}}function L(e,r,t){{var c=A.ReactDebugCurrentFrame,b=c.getStackAddendum();b!==""&&(r+="%s",t=t.concat([b]));var R=t.map(function(x){return String(x)});R.unshift("Warning: "+r),Function.prototype.apply.call(console[e],console,R)}}var D=!1,J=!1,f=!1,S=!1,_=!1,te;te=Symbol.for("react.module.reference");function ie(e){return!!(typeof e=="string"||typeof e=="function"||e===i||e===g||_||e===a||e===C||e===m||S||e===j||D||J||f||typeof e=="object"&&e!==null&&(e.$$typeof===p||e.$$typeof===l||e.$$typeof===v||e.$$typeof===y||e.$$typeof===d||e.$$typeof===te||e.getModuleId!==void 0))}function le(e,r,t){var c=e.displayName;if(c)return c;var b=r.displayName||r.name||"";return b!==""?t+"("+b+")":t}function Q(e){return e.displayName||"Context"}function W(e){if(e==null)return null;if(typeof e.tag=="number"&&k("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case i:return"Fragment";case u:return"Portal";case g:return"Profiler";case a:return"StrictMode";case C:return"Suspense";case m:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case y:var r=e;return Q(r)+".Consumer";case v:var t=e;return Q(t._context)+".Provider";case d:return le(e,e.render,"ForwardRef");case l:var c=e.displayName||null;return c!==null?c:W(e.type)||"Memo";case p:{var b=e,R=b._payload,x=b._init;try{return W(x(R))}catch{return null}}}return null}var U=Object.assign,q=0,Ce,Se,Pe,Ee,we,_e,Te;function ke(){}ke.__reactDisabledLog=!0;function qe(){{if(q===0){Ce=console.log,Se=console.info,Pe=console.warn,Ee=console.error,we=console.group,_e=console.groupCollapsed,Te=console.groupEnd;var e={configurable:!0,enumerable:!0,value:ke,writable:!0};Object.defineProperties(console,{info:e,log:e,warn:e,error:e,group:e,groupCollapsed:e,groupEnd:e})}q++}}function er(){{if(q--,q===0){var e={configurable:!0,enumerable:!0,writable:!0};Object.defineProperties(console,{log:U({},e,{value:Ce}),info:U({},e,{value:Se}),warn:U({},e,{value:Pe}),error:U({},e,{value:Ee}),group:U({},e,{value:we}),groupCollapsed:U({},e,{value:_e}),groupEnd:U({},e,{value:Te})})}q<0&&k("disabledDepth fell below zero. This is a bug in React. Please file an issue.")}}var ce=A.ReactCurrentDispatcher,ue;function ne(e,r,t){{if(ue===void 0)try{throw Error()}catch(b){var c=b.stack.trim().match(/\n( *(at )?)/);ue=c&&c[1]||""}return`
|
|
18
|
+
`+ue+e}}var fe=!1,oe;{var rr=typeof WeakMap=="function"?WeakMap:Map;oe=new rr}function Oe(e,r){if(!e||fe)return"";{var t=oe.get(e);if(t!==void 0)return t}var c;fe=!0;var b=Error.prepareStackTrace;Error.prepareStackTrace=void 0;var R;R=ce.current,ce.current=null,qe();try{if(r){var x=function(){throw Error()};if(Object.defineProperty(x.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(x,[])}catch(I){c=I}Reflect.construct(e,[],x)}else{try{x.call()}catch(I){c=I}e.call(x.prototype)}}else{try{throw Error()}catch(I){c=I}e()}}catch(I){if(I&&c&&typeof I.stack=="string"){for(var h=I.stack.split(`
|
|
19
|
+
`),F=c.stack.split(`
|
|
20
|
+
`),E=h.length-1,T=F.length-1;E>=1&&T>=0&&h[E]!==F[T];)T--;for(;E>=1&&T>=0;E--,T--)if(h[E]!==F[T]){if(E!==1||T!==1)do if(E--,T--,T<0||h[E]!==F[T]){var M=`
|
|
21
|
+
`+h[E].replace(" at new "," at ");return e.displayName&&M.includes("<anonymous>")&&(M=M.replace("<anonymous>",e.displayName)),typeof e=="function"&&oe.set(e,M),M}while(E>=1&&T>=0);break}}}finally{fe=!1,ce.current=R,er(),Error.prepareStackTrace=b}var K=e?e.displayName||e.name:"",B=K?ne(K):"";return typeof e=="function"&&oe.set(e,B),B}function tr(e,r,t){return Oe(e,!1)}function nr(e){var r=e.prototype;return!!(r&&r.isReactComponent)}function se(e,r,t){if(e==null)return"";if(typeof e=="function")return Oe(e,nr(e));if(typeof e=="string")return ne(e);switch(e){case C:return ne("Suspense");case m:return ne("SuspenseList")}if(typeof e=="object")switch(e.$$typeof){case d:return tr(e.render);case l:return se(e.type,r,t);case p:{var c=e,b=c._payload,R=c._init;try{return se(R(b),r,t)}catch{}}}return""}var ee=Object.prototype.hasOwnProperty,Ae={},Fe=A.ReactDebugCurrentFrame;function ae(e){if(e){var r=e._owner,t=se(e.type,e._source,r?r.type:null);Fe.setExtraStackFrame(t)}else Fe.setExtraStackFrame(null)}function or(e,r,t,c,b){{var R=Function.call.bind(ee);for(var x in e)if(R(e,x)){var h=void 0;try{if(typeof e[x]!="function"){var F=Error((c||"React class")+": "+t+" type `"+x+"` is invalid; it must be a function, usually from the `prop-types` package, but received `"+typeof e[x]+"`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");throw F.name="Invariant Violation",F}h=e[x](r,x,c,t,null,"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED")}catch(E){h=E}h&&!(h instanceof Error)&&(ae(b),k("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).",c||"React class",t,x,typeof h),ae(null)),h instanceof Error&&!(h.message in Ae)&&(Ae[h.message]=!0,ae(b),k("Failed %s type: %s",t,h.message),ae(null))}}}var sr=Array.isArray;function de(e){return sr(e)}function ar(e){{var r=typeof Symbol=="function"&&Symbol.toStringTag,t=r&&e[Symbol.toStringTag]||e.constructor.name||"Object";return t}}function ir(e){try{return De(e),!1}catch{return!0}}function De(e){return""+e}function Ie(e){if(ir(e))return k("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.",ar(e)),De(e)}var Ne=A.ReactCurrentOwner,lr={key:!0,ref:!0,__self:!0,__source:!0},Ve,Me;function cr(e){if(ee.call(e,"ref")){var r=Object.getOwnPropertyDescriptor(e,"ref").get;if(r&&r.isReactWarning)return!1}return e.ref!==void 0}function ur(e){if(ee.call(e,"key")){var r=Object.getOwnPropertyDescriptor(e,"key").get;if(r&&r.isReactWarning)return!1}return e.key!==void 0}function fr(e,r){typeof e.ref=="string"&&Ne.current}function dr(e,r){{var t=function(){Ve||(Ve=!0,k("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",r))};t.isReactWarning=!0,Object.defineProperty(e,"key",{get:t,configurable:!0})}}function pr(e,r){{var t=function(){Me||(Me=!0,k("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)",r))};t.isReactWarning=!0,Object.defineProperty(e,"ref",{get:t,configurable:!0})}}var hr=function(e,r,t,c,b,R,x){var h={$$typeof:o,type:e,key:r,ref:t,props:x,_owner:R};return h._store={},Object.defineProperty(h._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:!1}),Object.defineProperty(h,"_self",{configurable:!1,enumerable:!1,writable:!1,value:c}),Object.defineProperty(h,"_source",{configurable:!1,enumerable:!1,writable:!1,value:b}),Object.freeze&&(Object.freeze(h.props),Object.freeze(h)),h};function vr(e,r,t,c,b){{var R,x={},h=null,F=null;t!==void 0&&(Ie(t),h=""+t),ur(r)&&(Ie(r.key),h=""+r.key),cr(r)&&(F=r.ref,fr(r,b));for(R in r)ee.call(r,R)&&!lr.hasOwnProperty(R)&&(x[R]=r[R]);if(e&&e.defaultProps){var E=e.defaultProps;for(R in E)x[R]===void 0&&(x[R]=E[R])}if(h||F){var T=typeof e=="function"?e.displayName||e.name||"Unknown":e;h&&dr(x,T),F&&pr(x,T)}return hr(e,h,F,b,c,Ne.current,x)}}var pe=A.ReactCurrentOwner,We=A.ReactDebugCurrentFrame;function H(e){if(e){var r=e._owner,t=se(e.type,e._source,r?r.type:null);We.setExtraStackFrame(t)}else We.setExtraStackFrame(null)}var he;he=!1;function ve(e){return typeof e=="object"&&e!==null&&e.$$typeof===o}function Je(){{if(pe.current){var e=W(pe.current.type);if(e)return`
|
|
22
|
+
|
|
23
|
+
Check the render method of \``+e+"`."}return""}}function gr(e){return""}var Ye={};function xr(e){{var r=Je();if(!r){var t=typeof e=="string"?e:e.displayName||e.name;t&&(r=`
|
|
24
|
+
|
|
25
|
+
Check the top-level render call using <`+t+">.")}return r}}function ze(e,r){{if(!e._store||e._store.validated||e.key!=null)return;e._store.validated=!0;var t=xr(r);if(Ye[t])return;Ye[t]=!0;var c="";e&&e._owner&&e._owner!==pe.current&&(c=" It was passed a child from "+W(e._owner.type)+"."),H(e),k('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.',t,c),H(null)}}function Le(e,r){{if(typeof e!="object")return;if(de(e))for(var t=0;t<e.length;t++){var c=e[t];ve(c)&&ze(c,r)}else if(ve(e))e._store&&(e._store.validated=!0);else if(e){var b=V(e);if(typeof b=="function"&&b!==e.entries)for(var R=b.call(e),x;!(x=R.next()).done;)ve(x.value)&&ze(x.value,r)}}}function yr(e){{var r=e.type;if(r==null||typeof r=="string")return;var t;if(typeof r=="function")t=r.propTypes;else if(typeof r=="object"&&(r.$$typeof===d||r.$$typeof===l))t=r.propTypes;else return;if(t){var c=W(r);or(t,e.props,"prop",c,e)}else if(r.PropTypes!==void 0&&!he){he=!0;var b=W(r);k("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?",b||"Unknown")}typeof r.getDefaultProps=="function"&&!r.getDefaultProps.isReactClassApproved&&k("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.")}}function mr(e){{for(var r=Object.keys(e.props),t=0;t<r.length;t++){var c=r[t];if(c!=="children"&&c!=="key"){H(e),k("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.",c),H(null);break}}e.ref!==null&&(H(e),k("Invalid attribute `ref` supplied to `React.Fragment`."),H(null))}}var Ue={};function Be(e,r,t,c,b,R){{var x=ie(e);if(!x){var h="";(e===void 0||typeof e=="object"&&e!==null&&Object.keys(e).length===0)&&(h+=" You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");var F=gr();F?h+=F:h+=Je();var E;e===null?E="null":de(e)?E="array":e!==void 0&&e.$$typeof===o?(E="<"+(W(e.type)||"Unknown")+" />",h=" Did you accidentally export a JSX literal instead of a component?"):E=typeof e,k("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s",E,h)}var T=vr(e,r,t,b,R);if(T==null)return T;if(x){var M=r.children;if(M!==void 0)if(c)if(de(M)){for(var K=0;K<M.length;K++)Le(M[K],e);Object.freeze&&Object.freeze(M)}else k("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else Le(M,e)}if(ee.call(r,"key")){var B=W(e),I=Object.keys(r).filter(function(Pr){return Pr!=="key"}),ge=I.length>0?"{key: someKey, "+I.join(": ..., ")+": ...}":"{key: someKey}";if(!Ue[B+ge]){var Sr=I.length>0?"{"+I.join(": ..., ")+": ...}":"{}";k(`A props object containing a "key" prop is being spread into JSX:
|
|
26
|
+
let props = %s;
|
|
27
|
+
<%s {...props} />
|
|
28
|
+
React keys must be passed directly to JSX without using spread:
|
|
29
|
+
let props = %s;
|
|
30
|
+
<%s key={someKey} {...props} />`,ge,B,Sr,B),Ue[B+ge]=!0}}return e===i?mr(T):yr(T),T}}function br(e,r,t){return Be(e,r,t,!0)}function Rr(e,r,t){return Be(e,r,t,!1)}var jr=Rr,Cr=br;X.Fragment=i,X.jsx=jr,X.jsxs=Cr})()),X}var me;function Ge(){return me||(me=1,process.env.NODE_ENV==="production"?re.exports=He():re.exports=Ke()),re.exports}var n=Ge();const be=({conflicts:s,onResolveAll:o,onClose:u,renderConflictValue:i})=>{const[a,g]=w.useState(0),[v,y]=w.useState(new Map),d=s[a],C=s.length,m=a===0,l=a===C-1,p=v.get(a),j=D=>{y(new Map(v.set(a,D)))},P=D=>n.jsx("pre",{style:{backgroundColor:"#f5f5f5",padding:"15px",borderRadius:"4px",overflow:"auto",maxHeight:"300px",fontSize:"13px",margin:0},children:JSON.stringify(D,null,2)}),N=(D,J)=>{const f=p===(J==="local"?"use-local":"use-remote");return i?i(D,{conflict:d,side:J,isSelected:f}):P(D)},V=()=>{m||g(a-1)},A=()=>{!l&&p&&g(a+1)},k=()=>{if(v.size===C){const D=[];v.forEach((J,f)=>{D.push({conflictIndex:f,strategy:J})}),o(D)}},L=v.size===C;return n.jsx("div",{style:{position:"fixed",top:0,left:0,right:0,bottom:0,backgroundColor:"rgba(0, 0, 0, 0.5)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:1e3},children:n.jsxs("div",{style:{backgroundColor:"white",padding:"30px",borderRadius:"8px",maxWidth:"900px",width:"90%",maxHeight:"80vh",overflow:"auto"},children:[n.jsx("h2",{children:"Patch Conflict Resolution"}),n.jsxs("p",{style:{color:"#666"},children:["Conflict ",a+1," of ",C]}),n.jsxs("div",{style:{backgroundColor:"#fff3cd",padding:"15px",borderRadius:"4px",marginTop:"20px",border:"1px solid #ffc107"},children:[n.jsxs("div",{style:{marginBottom:"10px"},children:[n.jsx("strong",{children:"Field:"})," ",n.jsx("code",{children:d.path})]}),d.remotePatchIndex!==void 0&&n.jsxs("div",{style:{marginBottom:"10px",fontSize:"14px",color:"#666"},children:["Conflict from remote patch #",d.remotePatchIndex+1]})]}),n.jsxs("div",{style:{display:"flex",gap:"20px",marginTop:"20px"},children:[n.jsxs("div",{style:{flex:1},children:[n.jsx("h3",{children:"Local Value"}),n.jsx("div",{style:{border:p==="use-local"?"2px solid #4CAF50":"1px solid #ddd",borderRadius:"4px"},children:N(d.localValue,"local")}),n.jsx("button",{onClick:()=>j("use-local"),style:{marginTop:"10px",padding:"10px 20px",backgroundColor:p==="use-local"?"#4CAF50":"#ddd",color:p==="use-local"?"white":"#333",border:"none",borderRadius:"4px",cursor:"pointer",width:"100%",fontWeight:p==="use-local"?"bold":"normal"},children:p==="use-local"?"✓ Selected":"Use Local"})]}),n.jsxs("div",{style:{flex:1},children:[n.jsx("h3",{children:"Remote Value"}),n.jsx("div",{style:{border:p==="use-remote"?"2px solid #2196F3":"1px solid #ddd",borderRadius:"4px"},children:N(d.remoteValue,"remote")}),n.jsx("button",{onClick:()=>j("use-remote"),style:{marginTop:"10px",padding:"10px 20px",backgroundColor:p==="use-remote"?"#2196F3":"#ddd",color:p==="use-remote"?"white":"#333",border:"none",borderRadius:"4px",cursor:"pointer",width:"100%",fontWeight:p==="use-remote"?"bold":"normal"},children:p==="use-remote"?"✓ Selected":"Use Remote"})]})]}),n.jsxs("div",{style:{display:"flex",gap:"10px",marginTop:"30px",justifyContent:"space-between"},children:[n.jsxs("div",{style:{display:"flex",gap:"10px"},children:[n.jsx("button",{onClick:V,disabled:m,style:{padding:"10px 20px",backgroundColor:m?"#e0e0e0":"#757575",color:"white",border:"none",borderRadius:"4px",cursor:m?"not-allowed":"pointer"},children:"← Previous"}),n.jsx("button",{onClick:A,disabled:l||!p,style:{padding:"10px 20px",backgroundColor:l||!p?"#e0e0e0":"#757575",color:"white",border:"none",borderRadius:"4px",cursor:l||!p?"not-allowed":"pointer"},children:"Next →"})]}),n.jsxs("div",{style:{display:"flex",gap:"10px"},children:[n.jsx("button",{onClick:u,style:{padding:"10px 20px",backgroundColor:"#999",color:"white",border:"none",borderRadius:"4px",cursor:"pointer"},children:"Cancel"}),n.jsxs("button",{onClick:k,disabled:!L,style:{padding:"10px 20px",backgroundColor:L?"#4CAF50":"#e0e0e0",color:"white",border:"none",borderRadius:"4px",cursor:L?"pointer":"not-allowed",fontWeight:"bold"},children:["Finish (",v.size,"/",C,")"]})]})]}),!p&&n.jsx("p",{style:{marginTop:"15px",color:"#ff9800",fontSize:"14px",textAlign:"center"},children:"Please select either Local or Remote to continue"})]})})};function Y(s,o){const u=o.split(".");let i=s;for(const a of u){if(i==null)return;i=i[a]}return i}function Z(s,o,u){const i=o.split(".");let a=s;for(let g=0;g<i.length-1;g++){const v=i[g];(a[v]===null||typeof a[v]!="object")&&(a[v]={}),a=a[v]}a[i[i.length-1]]=u}function Xe(s,o){const u=o.split(".");let i=s;for(const a of u){if(i===null||typeof i!="object"||!(a in i))return!1;i=i[a]}return!0}function z(s,o=""){const u=[];if(s===null||typeof s!="object"||Array.isArray(s))return o?[o]:[];const i=Object.keys(s);if(i.length===0)return o?[o]:[];for(const a of i){if(a==="version")continue;const g=o?`${o}.${a}`:a,v=s[a];if(v===null||typeof v!="object"||Array.isArray(v))u.push(g);else{const y=z(v,g);u.push(...y)}}return u}function $(s,o){if(s===o)return!0;if(s===null||o===null||typeof s!="object"||typeof o!="object"||Array.isArray(s)!==Array.isArray(o))return!1;if(Array.isArray(s))return s.length!==o.length?!1:s.every((a,g)=>$(a,o[g]));const u=Object.keys(s),i=Object.keys(o);return u.length!==i.length?!1:u.every(a=>i.includes(a)&&$(s[a],o[a]))}class Re{mergePatches(o,u){const i=[],a=z(o),g=JSON.parse(JSON.stringify(o)),v=new Set(a);for(let y=0;y<u.length;y++){const d=u[y],C=z(d);for(const l of C){if(v.has(l)){const j=Y(o,l),P=Y(d,l);$(j,P)||i.find(V=>V.path===l)||i.push({path:l,localValue:j,remoteValue:P,remotePatchIndex:y})}const p=Y(d,l);Z(g,l,p)}const m=this.getHigherVersion(g.version,d.version);m!==void 0&&(g.version=m)}return i.length===0?{success:!0,merged:g}:{success:!1,conflicts:i,basePatch:o}}applyResolutions(o,u,i){const a=JSON.parse(JSON.stringify(o)),g=new Map;i.forEach(l=>{g.set(l.conflictIndex,l)});const v=[],y=z(o),d=new Set(y);for(let l=0;l<u.length;l++){const p=u[l],j=z(p);for(const P of j)if(d.has(P)){const N=Y(o,P),V=Y(p,P);$(N,V)||v.push({path:P,localValue:N,remoteValue:V,remotePatchIndex:l})}}const C=new Set;v.forEach((l,p)=>{C.add(l.path);const j=g.get(p);j&&(j.strategy==="use-local"?Z(a,l.path,l.localValue):Z(a,l.path,l.remoteValue))}),u.forEach(l=>{z(l).forEach(j=>{if(!C.has(j)){const P=Y(l,j);Z(a,j,P)}})});const m=[o.version,...u.map(l=>l.version)].filter(l=>l!==void 0);return m.length>0&&(a.version=Math.max(...m)),{resolutions:i,resolved:a}}getHigherVersion(o,u){if(!(o===void 0&&u===void 0))return o===void 0?u:u===void 0?o:Math.max(o,u)}}function je(s){const[o,u]=w.useState(null),[i,a]=w.useState(!1),[g,v]=w.useState(null),[y,d]=w.useState([]),C=new Re,m=w.useCallback((j,P)=>{var N,V;a(!0),v(j),d(P);try{const A=C.mergePatches(j,P);return u(A),A.success&&A.merged?(N=s==null?void 0:s.onMergeSuccess)==null||N.call(s,A.merged):(V=s==null?void 0:s.onConflict)==null||V.call(s,A),A}finally{a(!1)}},[s]),l=w.useCallback(j=>{if(!g||y.length===0)return null;const P=C.applyResolutions(g,y,j);return u(null),v(null),d([]),P.resolved},[g,y]),p=w.useCallback(()=>{u(null),v(null),d([])},[]);return{merging:i,mergeResult:o,hasConflict:o&&!o.success,mergePatches:m,applyResolutions:l,clearConflict:p}}const Ze=({onMergeComplete:s})=>{var D,J;const[o,u]=w.useState(JSON.stringify({version:15,message:"Hello from desktop",x:100,y:50,user:{name:"Alice",location:{city:"Boston",state:"MA",zip:"02101"}}},null,2)),[i,a]=w.useState([{version:16,message:"Hello from mobile",x:110,y:60,user:{name:"Alice",location:{city:"New York",state:"NY",zip:"10001"}}},{version:17,z:300}]),[g,v]=w.useState([JSON.stringify({version:16,message:"Hello from mobile",x:110,y:60,user:{name:"Alice",location:{city:"New York",state:"NY",zip:"10001"}}},null,2),JSON.stringify({version:17,z:300},null,2)]),[y,d]=w.useState(null),[C,m]=w.useState(!1),{mergePatches:l,applyResolutions:p}=je({onMergeSuccess:f=>{d({success:!0,merged:f}),s==null||s(f)},onConflict:f=>{d(f),m(!0)}}),j=()=>{d(null);try{const f=JSON.parse(o),S=g.map(_=>JSON.parse(_));l(f,S)}catch(f){d({success:!1,conflicts:[{path:"JSON Parse Error",localValue:"Invalid JSON",remoteValue:String(f)}]})}},P=f=>{const S=p(f);S&&(d({success:!0,merged:S}),m(!1),s==null||s(S))},N=f=>{u(f)},V=(f,S)=>{const _=[...g];_[f]=S,v(_)},A=()=>{const S={version:Math.max(...i.map(_=>_.version||0))+1};a([...i,S]),v([...g,JSON.stringify(S,null,2)])},k=f=>{a(i.filter((S,_)=>_!==f)),v(g.filter((S,_)=>_!==f))},L=(f,S)=>{const{isSelected:_}=S;if(typeof f=="string")return n.jsx("div",{style:{backgroundColor:_?"#e8f5e9":"#f5f5f5",padding:"20px",borderRadius:"4px",display:"flex",alignItems:"center",justifyContent:"center",minHeight:"80px"},children:n.jsx("div",{style:{fontSize:"18px",fontWeight:"bold",color:_?"#2e7d32":"#1976d2"},children:f})});const te=f&&typeof f=="object"&&"message"in f,ie=f&&typeof f=="object"&&("x"in f||"y"in f);if(te||ie){const le=f.message||"Preview",Q=f.x||0,W=f.y||0;return n.jsxs("div",{style:{backgroundColor:_?"#e8f5e9":"#f5f5f5",padding:"20px",borderRadius:"4px",minHeight:"150px",position:"relative"},children:[n.jsxs("div",{style:{fontSize:"12px",color:"#666",marginBottom:"10px",fontFamily:"monospace"},children:["Position: x=",Q,", y=",W]}),n.jsx("div",{style:{position:"absolute",left:`${20+Q}px`,top:`${40+W/10}px`,padding:"8px 12px",backgroundColor:_?"#4CAF50":"#2196F3",color:"white",borderRadius:"4px",fontSize:"14px",boxShadow:"0 2px 4px rgba(0,0,0,0.2)",maxWidth:"200px",wordWrap:"break-word"},children:le}),n.jsx("pre",{style:{marginTop:"80px",fontSize:"11px",color:"#666",backgroundColor:"rgba(255,255,255,0.5)",padding:"8px",borderRadius:"4px",overflow:"auto"},children:JSON.stringify(f,null,2)})]})}return n.jsx("pre",{style:{backgroundColor:_?"#e8f5e9":"#f5f5f5",padding:"15px",borderRadius:"4px",overflow:"auto",maxHeight:"300px",fontSize:"13px",margin:0},children:JSON.stringify(f,null,2)})};return n.jsxs("div",{style:{padding:"20px",fontFamily:"system-ui, sans-serif"},children:[n.jsx("h1",{children:"Patch Merge Demo"}),n.jsx("p",{children:"Merge multiple remote patches into a local patch. Example: Desktop has version 15, server has versions 16-20. Patches are merged sequentially. If any conflicts occur, step through them one at a time."}),n.jsxs("div",{style:{display:"flex",gap:"20px",marginBottom:"20px"},children:[n.jsxs("div",{style:{flex:1},children:[n.jsx("h2",{children:"Local Patch (Your Changes)"}),n.jsx("textarea",{value:o,onChange:f=>N(f.target.value),rows:10,style:{width:"100%",fontFamily:"monospace",padding:"10px"}})]}),n.jsxs("div",{style:{flex:1},children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[n.jsx("h2",{children:"Remote Patches (From Server)"}),n.jsx("button",{onClick:A,style:{padding:"5px 10px",fontSize:"14px",cursor:"pointer",backgroundColor:"#2196F3",color:"white",border:"none",borderRadius:"4px"},children:"+ Add Patch"})]}),i.map((f,S)=>n.jsxs("div",{style:{marginBottom:"10px",position:"relative"},children:[n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"5px"},children:[n.jsxs("small",{style:{color:"#666"},children:["Remote Patch #",S+1," ",f.version?`(v${f.version})`:""]}),n.jsx("button",{onClick:()=>k(S),style:{padding:"2px 6px",fontSize:"12px",cursor:"pointer",backgroundColor:"#f44336",color:"white",border:"none",borderRadius:"4px"},children:"× Remove"})]}),n.jsx("textarea",{value:g[S],onChange:_=>V(S,_.target.value),rows:4,style:{width:"100%",fontFamily:"monospace",padding:"10px",fontSize:"12px"}})]},S))]})]}),n.jsx("button",{onClick:j,style:{padding:"10px 20px",fontSize:"16px",cursor:"pointer",backgroundColor:"#4CAF50",color:"white",border:"none",borderRadius:"4px"},children:"Merge Patches"}),y&&n.jsx("div",{style:{marginTop:"20px"},children:y.success?n.jsxs("div",{style:{backgroundColor:"#d4edda",border:"1px solid #c3e6cb",padding:"15px",borderRadius:"4px"},children:[n.jsx("h3",{style:{marginTop:0,color:"#155724"},children:"✓ Merged Successfully!"}),n.jsx("pre",{style:{backgroundColor:"#fff",padding:"10px",borderRadius:"4px"},children:JSON.stringify(y.merged,null,2)})]}):n.jsxs("div",{style:{backgroundColor:"#fff3cd",border:"1px solid #ffc107",padding:"15px",borderRadius:"4px"},children:[n.jsxs("h3",{style:{marginTop:0,color:"#856404"},children:["⚠ ",(D=y.conflicts)==null?void 0:D.length," Conflict",((J=y.conflicts)==null?void 0:J.length)!==1?"s":""," Detected"]}),n.jsx("p",{children:"The patches modify the same fields. A modal will help you resolve them one at a time."})]})}),C&&y&&!y.success&&y.conflicts&&n.jsx(be,{conflicts:y.conflicts,onResolveAll:P,onClose:()=>m(!1),renderConflictValue:L})]})};function $e(s){const o={};for(const u of s){if(u.op!=="add"&&u.op!=="replace")continue;const i=u.path.match(/^\/([^/]+)$/);if(!i){console.warn(`jsonPatchToDiff: Ignoring nested or invalid path: ${u.path}`);continue}const a=i[1];o[a]=u.value}return o}function Qe(s){return Object.entries(s).filter(([o])=>o!=="version").map(([o,u])=>({op:"replace",path:`/${o}`,value:u}))}O.ConflictModal=be,O.ConflictResolver=Re,O.PatchManager=Ze,O.deepEqual=$,O.diffToJsonPatch=Qe,O.getAllPaths=z,O.getNestedValue=Y,O.hasNestedPath=Xe,O.jsonPatchToDiff=$e,O.setNestedValue=Z,O.usePatchMerger=je,Object.defineProperty(O,Symbol.toStringTag,{value:"Module"})}));
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Patch, MergeResult, ConflictResolution, ResolveResult } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Service for merging patches and resolving conflicts
|
|
4
|
+
*/
|
|
5
|
+
export declare class ConflictResolver {
|
|
6
|
+
/**
|
|
7
|
+
* Merge multiple remote patches into a local patch with deep (nested) conflict detection.
|
|
8
|
+
*
|
|
9
|
+
* **Conflict Rules:**
|
|
10
|
+
* - Conflicts occur ONLY when the exact same path is modified by both local and remote patches
|
|
11
|
+
* - Different paths merge automatically, even if they share a parent object
|
|
12
|
+
* - Example: local changes `user.name`, remote changes `user.address.city` → No conflict (different paths)
|
|
13
|
+
* - Example: local changes `user.name`, remote changes `user.name` → Conflict (same path)
|
|
14
|
+
*
|
|
15
|
+
* **Path Format:**
|
|
16
|
+
* - Uses dot notation: "user.name", "pages.0.container.text.fontSize"
|
|
17
|
+
* - Arrays are treated as single values (conflicts if entire array differs)
|
|
18
|
+
* - Flat objects work perfectly fine (treated as depth-1 nested objects)
|
|
19
|
+
*
|
|
20
|
+
* **Note:** Later remote patches can overwrite earlier remote patches without conflict.
|
|
21
|
+
* Conflicts only occur between the local patch and remote patches.
|
|
22
|
+
*
|
|
23
|
+
* @param localPatch - The base patch with potential nested structure
|
|
24
|
+
* @param remotePatches - Array of remote patches to merge
|
|
25
|
+
* @returns MergeResult with either merged patch or conflicts requiring resolution
|
|
26
|
+
*/
|
|
27
|
+
mergePatches(localPatch: Patch, remotePatches: Patch[]): MergeResult;
|
|
28
|
+
/**
|
|
29
|
+
* Apply conflict resolutions to produce the final merged patch.
|
|
30
|
+
*
|
|
31
|
+
* @param localPatch - The base patch with potential nested structure
|
|
32
|
+
* @param remotePatches - Array of remote patches
|
|
33
|
+
* @param resolutions - Array of conflict resolutions
|
|
34
|
+
* @returns Final resolved patch with deep merging
|
|
35
|
+
*/
|
|
36
|
+
applyResolutions(localPatch: Patch, remotePatches: Patch[], resolutions: ConflictResolution[]): ResolveResult;
|
|
37
|
+
/**
|
|
38
|
+
* Get the higher version number from two optional versions
|
|
39
|
+
*/
|
|
40
|
+
private getHigherVersion;
|
|
41
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a patch - changes to be applied to a document
|
|
3
|
+
*/
|
|
4
|
+
export type Patch = Record<string, any>;
|
|
5
|
+
/**
|
|
6
|
+
* Represents a single conflict between local and remote values
|
|
7
|
+
*/
|
|
8
|
+
export interface Conflict {
|
|
9
|
+
/**
|
|
10
|
+
* Field path that has conflicting values
|
|
11
|
+
*/
|
|
12
|
+
path: string;
|
|
13
|
+
/**
|
|
14
|
+
* Value from the local patch
|
|
15
|
+
*/
|
|
16
|
+
localValue: any;
|
|
17
|
+
/**
|
|
18
|
+
* Value from the remote patch
|
|
19
|
+
*/
|
|
20
|
+
remoteValue: any;
|
|
21
|
+
/**
|
|
22
|
+
* Index of the remote patch that caused this conflict (if merging multiple patches)
|
|
23
|
+
*/
|
|
24
|
+
remotePatchIndex?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Result of attempting to merge patches
|
|
28
|
+
*/
|
|
29
|
+
export interface MergeResult {
|
|
30
|
+
/**
|
|
31
|
+
* Whether the patches were successfully merged automatically
|
|
32
|
+
*/
|
|
33
|
+
success: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* The merged patch if successful
|
|
36
|
+
*/
|
|
37
|
+
merged?: Patch;
|
|
38
|
+
/**
|
|
39
|
+
* Conflicts that require manual resolution
|
|
40
|
+
*/
|
|
41
|
+
conflicts?: Conflict[];
|
|
42
|
+
/**
|
|
43
|
+
* Base patch that was being merged into
|
|
44
|
+
*/
|
|
45
|
+
basePatch?: Patch;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Strategy for resolving a single conflict
|
|
49
|
+
*/
|
|
50
|
+
export type ResolveStrategy = 'use-local' | 'use-remote';
|
|
51
|
+
/**
|
|
52
|
+
* Resolution for a single conflict
|
|
53
|
+
*/
|
|
54
|
+
export interface ConflictResolution {
|
|
55
|
+
/**
|
|
56
|
+
* Index of the conflict being resolved
|
|
57
|
+
*/
|
|
58
|
+
conflictIndex: number;
|
|
59
|
+
/**
|
|
60
|
+
* Strategy chosen to resolve this conflict
|
|
61
|
+
*/
|
|
62
|
+
strategy: ResolveStrategy;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Result of manual conflict resolution
|
|
66
|
+
*/
|
|
67
|
+
export interface ResolveResult {
|
|
68
|
+
/**
|
|
69
|
+
* All resolutions applied
|
|
70
|
+
*/
|
|
71
|
+
resolutions: ConflictResolution[];
|
|
72
|
+
/**
|
|
73
|
+
* The final resolved patch
|
|
74
|
+
*/
|
|
75
|
+
resolved: Patch;
|
|
76
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for working with nested object paths
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Get a value from a nested object using a dot-notation path
|
|
6
|
+
* @param obj - The object to get the value from
|
|
7
|
+
* @param path - Dot-notation path (e.g., "user.address.city")
|
|
8
|
+
* @returns The value at the path, or undefined if not found
|
|
9
|
+
*/
|
|
10
|
+
export declare function getNestedValue(obj: any, path: string): any;
|
|
11
|
+
/**
|
|
12
|
+
* Set a value in a nested object using a dot-notation path
|
|
13
|
+
* Creates intermediate objects as needed
|
|
14
|
+
* @param obj - The object to modify (will be mutated)
|
|
15
|
+
* @param path - Dot-notation path (e.g., "user.address.city")
|
|
16
|
+
* @param value - The value to set
|
|
17
|
+
*/
|
|
18
|
+
export declare function setNestedValue(obj: any, path: string, value: any): void;
|
|
19
|
+
/**
|
|
20
|
+
* Check if a path exists in an object
|
|
21
|
+
* @param obj - The object to check
|
|
22
|
+
* @param path - Dot-notation path
|
|
23
|
+
* @returns true if the path exists
|
|
24
|
+
*/
|
|
25
|
+
export declare function hasNestedPath(obj: any, path: string): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Get all leaf paths from a nested object
|
|
28
|
+
* @param obj - The object to extract paths from
|
|
29
|
+
* @param prefix - Current path prefix (used recursively)
|
|
30
|
+
* @returns Array of dot-notation paths to all leaf values
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const obj = { user: { name: "John", address: { city: "NYC" } } };
|
|
34
|
+
* getAllPaths(obj) // ["user.name", "user.address.city"]
|
|
35
|
+
*/
|
|
36
|
+
export declare function getAllPaths(obj: any, prefix?: string): string[];
|
|
37
|
+
/**
|
|
38
|
+
* Deep equality check for values
|
|
39
|
+
*/
|
|
40
|
+
export declare function deepEqual(a: any, b: any): boolean;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Patch } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* JSON Patch operation types (RFC 6902)
|
|
4
|
+
*/
|
|
5
|
+
export interface JsonPatchOperation {
|
|
6
|
+
op: 'add' | 'remove' | 'replace' | 'move' | 'copy' | 'test';
|
|
7
|
+
path: string;
|
|
8
|
+
value?: any;
|
|
9
|
+
from?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Converts a JSON Patch (RFC 6902) array of operations to a simple diff object.
|
|
13
|
+
* Only processes 'add' and 'replace' operations for top-level paths.
|
|
14
|
+
* Ignores 'remove', 'move', 'copy', and 'test' operations as they don't map to simple diffs.
|
|
15
|
+
* Nested paths (e.g., "/user/name") are not supported - only top-level fields (e.g., "/name").
|
|
16
|
+
*
|
|
17
|
+
* @param operations - Array of JSON Patch operations
|
|
18
|
+
* @returns A patch object representing the changes
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* const operations = [
|
|
22
|
+
* { op: "replace", path: "/message", value: "Hello" },
|
|
23
|
+
* { op: "add", path: "/x", value: 100 }
|
|
24
|
+
* ];
|
|
25
|
+
* const diff = jsonPatchToDiff(operations);
|
|
26
|
+
* // Returns: { message: "Hello", x: 100 }
|
|
27
|
+
*/
|
|
28
|
+
export declare function jsonPatchToDiff(operations: JsonPatchOperation[]): Patch;
|
|
29
|
+
/**
|
|
30
|
+
* Converts a simple diff object to a JSON Patch (RFC 6902) array of operations.
|
|
31
|
+
* All changes are converted to 'replace' operations.
|
|
32
|
+
*
|
|
33
|
+
* @param diff - A patch object representing changes
|
|
34
|
+
* @returns Array of JSON Patch operations
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* const diff = { message: "Hello", x: 100 };
|
|
38
|
+
* const operations = diffToJsonPatch(diff);
|
|
39
|
+
* // Returns: [
|
|
40
|
+
* // { op: "replace", path: "/message", value: "Hello" },
|
|
41
|
+
* // { op: "replace", path: "/x", value: 100 }
|
|
42
|
+
* // ]
|
|
43
|
+
*/
|
|
44
|
+
export declare function diffToJsonPatch(diff: Patch): JsonPatchOperation[];
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@iodev/patch-and-resolve",
|
|
3
|
+
"version": "1.0.6",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/patch-and-resolve.umd.js",
|
|
7
|
+
"module": "./dist/patch-and-resolve.es.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/patch-and-resolve.es.js",
|
|
13
|
+
"require": "./dist/patch-and-resolve.umd.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"dev": "vite",
|
|
21
|
+
"build": "tsc && vite build",
|
|
22
|
+
"build:lib": "tsc && vite build --mode library",
|
|
23
|
+
"preview": "vite preview",
|
|
24
|
+
"type-check": "tsc --noEmit",
|
|
25
|
+
"lint": "eslint . --ext .ts,.tsx --report-unused-disable-directives --max-warnings 40",
|
|
26
|
+
"lint:fix": "eslint . --ext .ts,.tsx --fix",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"test:unit": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"test:ui": "vitest --ui",
|
|
31
|
+
"test:e2e": "playwright test --project=chromium",
|
|
32
|
+
"test:e2e:ui": "playwright test --project=chromium --ui",
|
|
33
|
+
"test:e2e:headed": "playwright test --project=chromium --headed",
|
|
34
|
+
"test:all": "npm run test:unit && npm run test:e2e",
|
|
35
|
+
"prepare": "husky",
|
|
36
|
+
"semantic-release": "semantic-release"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"react": "^18.0.0",
|
|
40
|
+
"react-dom": "^18.0.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@commitlint/cli": "^19.6.0",
|
|
44
|
+
"@commitlint/config-conventional": "^19.6.0",
|
|
45
|
+
"@eslint/js": "^9.39.2",
|
|
46
|
+
"@playwright/test": "^1.49.1",
|
|
47
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
48
|
+
"@semantic-release/git": "^10.0.1",
|
|
49
|
+
"@types/react": "^18.3.18",
|
|
50
|
+
"@types/react-dom": "^18.3.5",
|
|
51
|
+
"@typescript-eslint/eslint-plugin": "^8.21.0",
|
|
52
|
+
"@typescript-eslint/parser": "^8.21.0",
|
|
53
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
54
|
+
"@vitest/ui": "^2.1.8",
|
|
55
|
+
"eslint": "^9.18.0",
|
|
56
|
+
"eslint-plugin-react": "^7.37.3",
|
|
57
|
+
"eslint-plugin-react-hooks": "^5.1.0",
|
|
58
|
+
"eslint-plugin-react-refresh": "^0.4.16",
|
|
59
|
+
"globals": "^15.15.0",
|
|
60
|
+
"husky": "^9.1.7",
|
|
61
|
+
"jsdom": "^25.0.1",
|
|
62
|
+
"semantic-release": "^24.2.0",
|
|
63
|
+
"typescript": "^5.7.2",
|
|
64
|
+
"vite": "^6.0.3",
|
|
65
|
+
"vite-plugin-dts": "^4.3.0",
|
|
66
|
+
"vitest": "^2.1.8"
|
|
67
|
+
},
|
|
68
|
+
"peerDependencies": {
|
|
69
|
+
"react": "^18.0.0",
|
|
70
|
+
"react-dom": "^18.0.0"
|
|
71
|
+
},
|
|
72
|
+
"repository": {
|
|
73
|
+
"type": "git",
|
|
74
|
+
"url": "https://github.com/isaac76/patchAndResolve.git"
|
|
75
|
+
},
|
|
76
|
+
"publishConfig": {
|
|
77
|
+
"access": "public"
|
|
78
|
+
}
|
|
79
|
+
}
|