@vkcha/svg-core 0.1.2 → 1.1.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/README.md +149 -1
- package/dist/index.cjs +1142 -0
- package/dist/index.d.ts +47 -1
- package/dist/index.js +1137 -0
- package/dist/vkcha.min.js +1 -1
- package/package.json +8 -6
- package/src/SvgCore.ts +0 -623
- package/src/canvas/PanZoomCanvas.ts +0 -302
- package/src/index.ts +0 -11
- package/src/scene/Node.ts +0 -66
- package/src/scene/fragment.ts +0 -146
- package/src/utils/dom.ts +0 -17
package/dist/vkcha.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).SvgCore={})}(this,function(t){"use strict";const e={wheelMode:"pan",zoomRequiresCtrlKey:!1,panRequiresSpaceKey:!1,minZoom:.2,maxZoom:8,zoomSpeed:1,invertZoom:!1,invertPan:!1};class n{svg;world;state={zoom:1,panX:0,panY:0};options={...e};listeners=new Set;notifyScheduled=!1;dragPointerId=null;panStart=null;isSpaceDown=!1;windowKeyDownHandler=null;windowKeyUpHandler=null;svgWheelHandler=null;svgPointerDownHandler=null;svgPointerMoveHandler=null;svgPointerUpHandler=null;svgPointerCancelHandler=null;svgPointerLeaveHandler=null;constructor(t,e={}){this.svg=t,this.world=function(t,e={}){const n=document.createElementNS("http://www.w3.org/2000/svg",t);for(const[t,s]of Object.entries(e))n.setAttribute(t,s);return n}("g"),this.world.dataset.layer="world",this.svg.replaceChildren(this.world),this.setOptions(e),this.svg.style.touchAction="none",this.svg.style.userSelect="none",this.attach(),this.render()}setOptions(t){this.options={...e,...this.options,...t}}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}setState(t){const e={...this.state,...t};e.zoom===this.state.zoom&&e.panX===this.state.panX&&e.panY===this.state.panY||(this.state=e,this.render(),this.scheduleNotify())}reset(){this.setState({zoom:1,panX:0,panY:0})}destroy(){if(this.windowKeyDownHandler&&(window.removeEventListener("keydown",this.windowKeyDownHandler),this.windowKeyDownHandler=null),this.windowKeyUpHandler&&(window.removeEventListener("keyup",this.windowKeyUpHandler),this.windowKeyUpHandler=null),this.svgWheelHandler&&(this.svg.removeEventListener("wheel",this.svgWheelHandler),this.svgWheelHandler=null),this.svgPointerDownHandler&&(this.svg.removeEventListener("pointerdown",this.svgPointerDownHandler),this.svgPointerDownHandler=null),this.svgPointerMoveHandler&&(this.svg.removeEventListener("pointermove",this.svgPointerMoveHandler),this.svgPointerMoveHandler=null),this.svgPointerUpHandler&&(this.svg.removeEventListener("pointerup",this.svgPointerUpHandler),this.svgPointerUpHandler=null),this.svgPointerCancelHandler&&(this.svg.removeEventListener("pointercancel",this.svgPointerCancelHandler),this.svgPointerCancelHandler=null),this.svgPointerLeaveHandler&&(this.svg.removeEventListener("pointerleave",this.svgPointerLeaveHandler),this.svgPointerLeaveHandler=null),null!==this.dragPointerId){try{this.svg.releasePointerCapture(this.dragPointerId)}catch{}this.dragPointerId=null}this.panStart=null,this.isSpaceDown=!1,this.listeners.clear()}scheduleNotify(){this.notifyScheduled||(this.notifyScheduled=!0,requestAnimationFrame(()=>{this.notifyScheduled=!1;for(const t of this.listeners)t(this.state)}))}attach(){this.windowKeyDownHandler=t=>{"Space"===t.code&&(this.isSpaceDown=!0)},this.windowKeyUpHandler=t=>{"Space"===t.code&&(this.isSpaceDown=!1)},window.addEventListener("keydown",this.windowKeyDownHandler),window.addEventListener("keyup",this.windowKeyUpHandler),this.svgWheelHandler=t=>{t.preventDefault();const e=this.svgPoint(t.clientX,t.clientY),{wheelMode:n,zoomRequiresCtrlKey:s,invertZoom:i,invertPan:o}=this.options,r=t.ctrlKey||t.metaKey;if("pan"===n&&!r){const e=o?-1:1;return void this.setState({panX:this.state.panX-t.deltaX*e,panY:this.state.panY-t.deltaY*e})}if("zoom"===n&&s&&!r)return;const l=this.screenToWorld(e.x,e.y),a=i?-t.deltaY:t.deltaY,h=Math.exp(.001*-a*this.options.zoomSpeed),d=(c=this.state.zoom*h,u=this.options.minZoom,g=this.options.maxZoom,Math.max(u,Math.min(g,c)));var c,u,g;const v=e.x-l.x*d,p=e.y-l.y*d;this.setState({zoom:d,panX:v,panY:p})},this.svg.addEventListener("wheel",this.svgWheelHandler,{passive:!1}),this.svgPointerDownHandler=t=>{if(null!==this.dragPointerId)return;if(this.options.panRequiresSpaceKey&&!this.isSpaceDown)return;this.dragPointerId=t.pointerId,this.svg.setPointerCapture(t.pointerId);const e=this.svgPoint(t.clientX,t.clientY);this.panStart={panX:this.state.panX,panY:this.state.panY,x:e.x,y:e.y}},this.svg.addEventListener("pointerdown",this.svgPointerDownHandler),this.svgPointerMoveHandler=t=>{if(null===this.dragPointerId)return;if(t.pointerId!==this.dragPointerId)return;if(!this.panStart)return;const e=this.svgPoint(t.clientX,t.clientY),n=e.x-this.panStart.x,s=e.y-this.panStart.y;this.setState({panX:this.panStart.panX+n,panY:this.panStart.panY+s})},this.svg.addEventListener("pointermove",this.svgPointerMoveHandler);const t=t=>{null!==this.dragPointerId&&t.pointerId===this.dragPointerId&&(this.dragPointerId=null,this.panStart=null)};this.svgPointerUpHandler=t,this.svgPointerCancelHandler=t,this.svgPointerLeaveHandler=()=>{this.dragPointerId=null,this.panStart=null},this.svg.addEventListener("pointerup",this.svgPointerUpHandler),this.svg.addEventListener("pointercancel",this.svgPointerCancelHandler),this.svg.addEventListener("pointerleave",this.svgPointerLeaveHandler)}render(){const{zoom:t,panX:e,panY:n}=this.state;this.world.setAttribute("transform",`matrix(${t} 0 0 ${t} ${e} ${n})`)}svgPoint(t,e){const n=this.svg.getBoundingClientRect();return{x:t-n.left,y:e-n.top}}screenToWorld(t,e){const{zoom:n,panX:s,panY:i}=this.state;return{x:(t-s)/n,y:(e-i)/n}}}const s=new Map;let i=null,o=null;function r(t){t.hasAttribute("xmlns")&&t.removeAttribute("xmlns");for(const e of Array.from(t.attributes))e.name.startsWith("xmlns:")&&t.removeAttribute(e.name);for(const e of Array.from(t.children))r(e)}function l(t){const e=t.trim();if(!e)return"";const n=`<svg xmlns="http://www.w3.org/2000/svg">${e}</svg>`;try{const t=(new DOMParser).parseFromString(n,"image/svg+xml"),e=t.documentElement;if(!e||"svg"!==e.nodeName.toLowerCase())return"";t.querySelectorAll("script, foreignObject").forEach(t=>t.remove()),t.querySelectorAll("*").forEach(t=>{for(const e of Array.from(t.attributes))e.name.toLowerCase().startsWith("on")&&t.removeAttribute(e.name),("xmlns"===e.name||e.name.startsWith("xmlns:"))&&t.removeAttribute(e.name)});const s=e.innerHTML;return"string"==typeof s?s.trim():(new XMLSerializer).serializeToString(e).replace(/^<svg[^>]*>|<\/svg>$/g,"").trim()}catch{return""}}function a(t){const e=t.trim();if(!e)return[];const n=`<svg xmlns="http://www.w3.org/2000/svg">${e}</svg>`;try{const t=(new DOMParser).parseFromString(n,"image/svg+xml"),e=t.documentElement;if(!e||"svg"!==e.nodeName.toLowerCase())return[];t.querySelectorAll("script, foreignObject").forEach(t=>t.remove()),t.querySelectorAll("*").forEach(t=>{for(const e of Array.from(t.attributes))e.name.toLowerCase().startsWith("on")&&t.removeAttribute(e.name),("xmlns"===e.name||e.name.startsWith("xmlns:"))&&t.removeAttribute(e.name)});const s=Array.from(e.children).map(t=>document.importNode(t,!0));for(const t of s)r(t);return s}catch{return[]}}function h(t){const e=l(t);if(!e)return null;const n=s.get(e);if(n)return n;const{svg:r,g:h}=function(){if(i&&o)return{svg:i,g:o};const t=document.createElementNS("http://www.w3.org/2000/svg","svg");t.setAttribute("width","0"),t.setAttribute("height","0"),t.style.position="absolute",t.style.left="-10000px",t.style.top="-10000px",t.style.visibility="hidden",t.style.pointerEvents="none";const e=document.createElementNS("http://www.w3.org/2000/svg","g");return t.appendChild(e),i=t,o=e,{svg:t,g:e}}();!function(t){t.isConnected||document.body.appendChild(t)}(r),h.replaceChildren();const d=a(e);for(const t of d)h.appendChild(t.cloneNode(!0));try{const t=h.getBBox();let n=0;h.querySelectorAll("*").forEach(t=>{try{const e=getComputedStyle(t),s=e.stroke;if(!s||"none"===s||"transparent"===s)return;const i=Number.parseFloat(e.strokeWidth??"0");Number.isFinite(i)&&i>n&&(n=i)}catch{}});const i=Math.max(0,n/2),o={bbox:{x:t.x,y:t.y,width:t.width,height:t.height},pad:i};return s.set(e,o),o}catch{return null}finally{!function(t){t.isConnected&&t.remove()}(r)}}t.Node=class{id;fragment;x;y;width;height;onClick;onDoubleClick;onRightClick;_el=null;constructor(t){if(!t||"string"!=typeof t.id||""===t.id)throw new Error("Node requires a non-empty 'id' property");this.id=t.id,this.fragment=t.fragment??"",this.x=Number.isFinite(t?.x)?t?.x:0,this.y=Number.isFinite(t?.y)?t?.y:0;const e=t?.width,n=t?.height;this.width="number"==typeof e&&Number.isFinite(e)&&e>0?e:null,this.height="number"==typeof n&&Number.isFinite(n)&&n>0?n:null,this.onClick=t?.onClick,this.onDoubleClick=t?.onDoubleClick,this.onRightClick=t?.onRightClick}get el(){if(!this._el){const t=document.createElementNS("http://www.w3.org/2000/svg","g");t.dataset.nodeId=this.id,this._el=t}return this._el}},t.PanZoomCanvas=n,t.SvgCore=class{canvas;nodesLayer;nodes=[];nodeIdToIndex=new Map;nodeBounds=null;cullingEnabled=!0;cullingOverscanPx=30;resizeObserver=null;unsubPanZoom=null;unsubSvgEvents=null;svgClickTimer=null;suppressNextClick=!1;dragWatch=null;cullingListeners=new Set;lastCullingStats={visible:0,hidden:0,total:0};cullingNotifyScheduled=!1;get svg(){return this.canvas.svg}get world(){return this.canvas.world}get state(){return this.canvas.state}get panZoomOptions(){return this.canvas.options}constructor(t,e){this.canvas=new n(t,e?.panZoom),this.nodesLayer=document.createElementNS("http://www.w3.org/2000/svg","g"),this.nodesLayer.dataset.layer="nodes",this.world.appendChild(this.nodesLayer),this.world.style.pointerEvents="none";const s=e?.culling;"boolean"==typeof s?this.cullingEnabled=s:s&&("boolean"==typeof s.enabled&&(this.cullingEnabled=s.enabled),"number"==typeof s.overscanPx&&(this.cullingOverscanPx=Math.max(0,s.overscanPx))),this.unsubPanZoom=this.canvas.subscribe(()=>this.applyCulling()),this.resizeObserver=new ResizeObserver(()=>this.applyCulling()),this.resizeObserver.observe(this.svg);const i=()=>{null!==this.svgClickTimer&&(window.clearTimeout(this.svgClickTimer),this.svgClickTimer=null)},o=t=>{0===t.button&&(this.dragWatch={pointerId:t.pointerId,startClientX:t.clientX,startClientY:t.clientY,moved:!1})},r=t=>{const e=this.dragWatch;if(!e)return;if(t.pointerId!==e.pointerId)return;if(1&~t.buttons)return;const n=t.clientX-e.startClientX,s=t.clientY-e.startClientY;!e.moved&&Math.hypot(n,s)>=5&&(e.moved=!0)},l=t=>{const e=this.dragWatch;e&&t.pointerId===e.pointerId&&(this.dragWatch=null,e.moved&&(this.suppressNextClick=!0,i()))},a=t=>{if(this.suppressNextClick)this.suppressNextClick=!1;else{if(null!==this.svgClickTimer){i();const e=this.hitTestVisibleNodeAtClient(t.clientX,t.clientY);return void(e?.onDoubleClick&&e.onDoubleClick(e))}this.svgClickTimer=window.setTimeout(()=>{this.svgClickTimer=null;const e=this.hitTestVisibleNodeAtClient(t.clientX,t.clientY);e?.onClick&&e.onClick(e)},300)}},h=t=>{t.preventDefault(),i();const e=this.hitTestVisibleNodeAtClient(t.clientX,t.clientY);e?.onRightClick&&e.onRightClick(e)};this.svg.addEventListener("click",a),this.svg.addEventListener("contextmenu",h),this.svg.addEventListener("pointerdown",o),this.svg.addEventListener("pointermove",r),this.svg.addEventListener("pointerup",l),this.svg.addEventListener("pointercancel",l),this.unsubSvgEvents=()=>{this.svg.removeEventListener("click",a),this.svg.removeEventListener("contextmenu",h),this.svg.removeEventListener("pointerdown",o),this.svg.removeEventListener("pointermove",r),this.svg.removeEventListener("pointerup",l),this.svg.removeEventListener("pointercancel",l),i()}}setZoom(t,e){const n=this.canvas.options.minZoom,s=this.canvas.options.maxZoom,i=Math.min(s,Math.max(n,t)),o=this.svg.getBoundingClientRect(),r=e?.x??Math.max(1,o.width)/2,l=e?.y??Math.max(1,o.height)/2,a=this.state,h=r-(r-a.panX)/Math.max(1e-9,a.zoom)*i,d=l-(l-a.panY)/Math.max(1e-9,a.zoom)*i;this.setState({zoom:i,panX:h,panY:d})}clientToCanvas(t,e){const n=this.svg.getBoundingClientRect(),s=t-n.left,i=e-n.top,{panX:o,panY:r,zoom:l}=this.state,a=Math.max(1e-9,l);return{x:(s-o)/a,y:(i-r)/a}}hitTestVisibleNodeAtClient(t,e){if(!this.nodeBounds||0===this.nodes.length)return null;const n=this.clientToCanvas(t,e),s=this.nodesLayer.children;for(let t=s.length-1;t>=0;t--){const e=s.item(t);if(!e)continue;const i=e.dataset.nodeId;if(!i)continue;const o=this.nodeIdToIndex.get(i);if(void 0===o)continue;const r=this.nodeBounds[o];if(r&&(n.x>=r.x0&&n.x<=r.x1&&n.y>=r.y0&&n.y<=r.y1))return this.nodes[o]}return null}zoomBy(t,e){const n=Number.isFinite(t)?t:1;n<=0||this.setZoom(this.state.zoom*n,e)}setState(t){this.canvas.setState(t)}resetView(){this.canvas.reset()}configurePanZoom(t){this.canvas.setOptions(t)}setNodes(t){const e=new Set,n=new Set;for(let s=0;s<t.length;s++){const i=t[s].id;e.has(i)?n.add(i):e.add(i)}n.size>0&&console.warn(`Duplicate node ids found: ${Array.from(n).map(t=>`"${t}"`).join(", ")}. Each node should have a unique id.`),this.nodes=t,this.nodeIdToIndex.clear();for(let e=0;e<t.length;e++)this.nodeIdToIndex.set(t[e].id,e);this.redraw()}redraw(t){Array.isArray(t)&&t.length>0?(this.renderNodes(t),this.applyCulling()):(this.renderNodes(),this.applyCulling())}setCullingEnabled(t){this.cullingEnabled=t,this.applyCulling()}setCullingOverscanPx(t){this.cullingOverscanPx=Math.max(0,t),this.applyCulling()}onCullingStatsChange(t){return this.cullingListeners.add(t),t(this.lastCullingStats),()=>this.cullingListeners.delete(t)}onPanZoomChange(t){return this.canvas.subscribe(t)}remove(t){if(!t||0===t.length)return this.nodes=[],this.nodeIdToIndex.clear(),this.nodesLayer.replaceChildren(),this.nodeBounds=null,void this.setCullingStats({visible:0,hidden:0,total:0});const e=new Set;for(const n of t){const t=this.nodeIdToIndex.get(n);void 0!==t&&e.add(t)}if(0===e.size)return;const n=Array.from(e).sort((t,e)=>e-t);for(const t of n){const e=this.nodes[t];e&&(e.el.parentElement&&e.el.remove(),this.nodeIdToIndex.delete(e.id)),this.nodes.splice(t,1)}this.nodeIdToIndex.clear();for(let t=0;t<this.nodes.length;t++)this.nodeIdToIndex.set(this.nodes[t].id,t);if(this.nodeBounds){const t=[];for(let e=0;e<this.nodes.length;e++){const n=this.nodes[e],s=h(n.fragment),i=s?.bbox??{width:240,height:160},o=s?.pad??0,r=n.width??Math.max(1,i.width+2*o),l=n.height??Math.max(1,i.height+2*o);t.push({x0:n.x,y0:n.y,x1:n.x+r,y1:n.y+l})}this.nodeBounds=t}this.applyCulling()}destroy(){this.resizeObserver?.disconnect(),this.resizeObserver=null,this.unsubPanZoom?.(),this.unsubPanZoom=null,this.unsubSvgEvents?.(),this.unsubSvgEvents=null,this.cullingListeners.clear(),this.canvas.destroy()}renderNodes(t){if(t&&t.length>0){for(const e of t){const t=this.nodeIdToIndex.get(e);if(void 0===t)continue;const n=this.nodes[t];if(!n)continue;const s=n.el;s.replaceChildren(),s.setAttribute("transform",`translate(${n.x} ${n.y})`);const i=l(n.fragment);if(i){const e=a(i),o=h(i),r=o?.bbox??{x:0,y:0,width:240,height:160},l=o?.pad??0,d=Math.max(1,r.width+2*l),c=Math.max(1,r.height+2*l),u=-r.x+l,g=-r.y+l,v=document.createElementNS("http://www.w3.org/2000/svg","g");v.setAttribute("transform",`translate(${u} ${g})`);for(const t of e)v.appendChild(t.cloneNode(!0));if(s.appendChild(v),this.nodeBounds){const e=n.width??d,s=n.height??c;this.nodeBounds[t]={x0:n.x,y0:n.y,x1:n.x+e,y1:n.y+s}}}s.parentElement||this.nodesLayer.appendChild(s)}return}if(this.nodesLayer.replaceChildren(),this.nodeBounds=null,0===this.nodes.length)return;const e=new Map;for(const t of this.nodes){const n=l(t.fragment);if(!n)continue;if(e.has(n))continue;const s=a(n),i=h(n),o=i?.bbox??{x:0,y:0,width:240,height:160},r=i?.pad??0,d=Math.max(1,o.width+2*r),c=Math.max(1,o.height+2*r),u=-o.x+r,g=-o.y+r;e.set(n,{children:s,w:d,h:c,offsetX:u,offsetY:g})}const n=this.nodes.length,s=document.createDocumentFragment(),i=new Array(n);for(let t=0;t<n;t++){const n=this.nodes[t],o=n.el;o.replaceChildren(),o.setAttribute("transform",`translate(${n.x} ${n.y})`);const r=l(n.fragment),a=r?e.get(r):null;if(a){const t=document.createElementNS("http://www.w3.org/2000/svg","g");t.setAttribute("transform",`translate(${a.offsetX} ${a.offsetY})`);for(const e of a.children)t.appendChild(e.cloneNode(!0));o.appendChild(t)}const h=n.width??a?.w??240,d=n.height??a?.h??160;i[t]={x0:n.x,y0:n.y,x1:n.x+h,y1:n.y+d},s.appendChild(o)}this.nodesLayer.appendChild(s),this.nodeBounds=i}applyCulling(){if(!this.nodeBounds)return void this.setCullingStats({visible:0,hidden:0,total:this.nodes.length});const t=this.nodes.length;if(!this.cullingEnabled){this.nodesLayer.replaceChildren(...this.nodes.map(t=>t.el));for(const t of this.nodes)t.el.removeAttribute("display");return void this.setCullingStats({visible:t,hidden:0,total:t})}const e=this.getWorldViewport(this.state,this.cullingOverscanPx),n=[];for(let s=0;s<t;s++){const t=this.nodeBounds[s];if(t&&this.rectsIntersect(t,e)){const t=this.nodes[s].el;t.removeAttribute("display"),n.push(t)}}this.nodesLayer.replaceChildren(...n),this.setCullingStats({visible:n.length,hidden:t-n.length,total:t})}setCullingStats(t){const e=this.lastCullingStats;e.visible===t.visible&&e.hidden===t.hidden&&e.total===t.total||(this.lastCullingStats=t,this.scheduleCullingNotify())}scheduleCullingNotify(){this.cullingNotifyScheduled||(this.cullingNotifyScheduled=!0,requestAnimationFrame(()=>{this.cullingNotifyScheduled=!1;for(const t of this.cullingListeners)t(this.lastCullingStats)}))}rectsIntersect(t,e){return!(t.x1<e.x0||t.x0>e.x1||t.y1<e.y0||t.y0>e.y1)}getWorldViewport(t,e){const n=this.svg.getBoundingClientRect(),s=Math.max(1,n.width),i=Math.max(1,n.height),o=Math.max(1e-9,t.zoom),r=Math.max(0,e)/o;return{x0:-t.panX/o-r,y0:-t.panY/o-r,x1:(s-t.panX)/o+r,y1:(i-t.panY)/o+r}}},t.measureFragmentMetrics=h});
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).SvgCore={})}(this,function(t){"use strict";function e(t,e={}){const n=document.createElementNS("http://www.w3.org/2000/svg",t);for(const[t,i]of Object.entries(e))n.setAttribute(t,i);return n}const n={wheelMode:"pan",zoomRequiresCtrlKey:!1,panRequiresSpaceKey:!1,minZoom:.2,maxZoom:8,zoomSpeed:1,pinchZoomSpeed:2,invertZoom:!1,invertPan:!1};class i{svg;world;state={zoom:1,panX:0,panY:0};options={...n};listeners=new Set;notifyScheduled=!1;dragPointerId=null;panStart=null;isPanning=!1;isSpaceDown=!1;static DRAG_THRESHOLD_PX=5;animationFrameId=null;windowKeyDownHandler=null;windowKeyUpHandler=null;svgWheelHandler=null;svgPointerDownHandler=null;svgPointerMoveHandler=null;svgPointerUpHandler=null;svgPointerCancelHandler=null;svgPointerLeaveHandler=null;constructor(t,n={}){this.svg=t,this.world=e("g"),this.world.dataset.layer="world",this.svg.replaceChildren(this.world),this.setOptions(n),this.applyWorldGroupConfig(),this.svg.style.touchAction="none",this.svg.style.userSelect="none";const i=this.svg.style;i.webkitUserSelect="none",i.webkitTapHighlightColor="transparent",this.svg.style.outline="none",this.svg.setAttribute("tabindex","-1"),this.world.style.outline="none",this.attach(),this.render()}applyWorldGroupConfig(){const t=this.options.worldGroup;if(t&&(t.id&&(this.world.id=t.id),t.attributes))for(const[e,n]of Object.entries(t.attributes))this.world.setAttribute(e,n)}createLayer(t,n){const i=e("g");return t&&(i.dataset.layer=t),n?.pointerEvents&&(i.style.pointerEvents=n.pointerEvents),"back"===n?.position&&this.world.firstChild?this.world.insertBefore(i,this.world.firstChild):this.world.appendChild(i),i}setOptions(t){this.options={...n,...this.options,...t},t.worldGroup&&(this.applyWorldGroupConfig(),this.render())}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}setState(t){const e={...this.state,...t};e.zoom===this.state.zoom&&e.panX===this.state.panX&&e.panY===this.state.panY||(this.state=e,this.render(),this.scheduleNotify())}animateTo(t,e=300,n=t=>t){return new Promise(i=>{null!==this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null);const s={zoom:this.state.zoom,panX:this.state.panX,panY:this.state.panY},o=t.zoom??s.zoom,r=t.panX??s.panX,a=t.panY??s.panY,l=performance.now(),h=t=>{const d=t-l,c=Math.min(1,d/e),u=n(c);this.setState({zoom:s.zoom+(o-s.zoom)*u,panX:s.panX+(r-s.panX)*u,panY:s.panY+(a-s.panY)*u}),c<1?this.animationFrameId=requestAnimationFrame(h):(this.animationFrameId=null,i())};this.animationFrameId=requestAnimationFrame(h)})}stopAnimation(){null!==this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}reset(){this.setState({zoom:1,panX:0,panY:0})}destroy(){if(this.stopAnimation(),this.windowKeyDownHandler&&(window.removeEventListener("keydown",this.windowKeyDownHandler),this.windowKeyDownHandler=null),this.windowKeyUpHandler&&(window.removeEventListener("keyup",this.windowKeyUpHandler),this.windowKeyUpHandler=null),this.svgWheelHandler&&(this.svg.removeEventListener("wheel",this.svgWheelHandler),this.svgWheelHandler=null),this.svgPointerDownHandler&&(this.svg.removeEventListener("pointerdown",this.svgPointerDownHandler),this.svgPointerDownHandler=null),this.svgPointerMoveHandler&&(this.svg.removeEventListener("pointermove",this.svgPointerMoveHandler),this.svgPointerMoveHandler=null),this.svgPointerUpHandler&&(this.svg.removeEventListener("pointerup",this.svgPointerUpHandler),this.svgPointerUpHandler=null),this.svgPointerCancelHandler&&(this.svg.removeEventListener("pointercancel",this.svgPointerCancelHandler),this.svgPointerCancelHandler=null),this.svgPointerLeaveHandler&&(this.svg.removeEventListener("pointerleave",this.svgPointerLeaveHandler),this.svgPointerLeaveHandler=null),null!==this.dragPointerId){try{this.svg.releasePointerCapture(this.dragPointerId)}catch{}this.dragPointerId=null}this.panStart=null,this.isPanning=!1,this.isSpaceDown=!1,this.listeners.clear()}scheduleNotify(){this.notifyScheduled||(this.notifyScheduled=!0,requestAnimationFrame(()=>{this.notifyScheduled=!1;for(const t of this.listeners)t(this.state)}))}attach(){this.windowKeyDownHandler=t=>{"Space"===t.code&&(this.isSpaceDown=!0)},this.windowKeyUpHandler=t=>{"Space"===t.code&&(this.isSpaceDown=!1)},window.addEventListener("keydown",this.windowKeyDownHandler),window.addEventListener("keyup",this.windowKeyUpHandler),this.svgWheelHandler=t=>{t.preventDefault();const e=this.svgPoint(t.clientX,t.clientY),{wheelMode:n,zoomRequiresCtrlKey:i,invertZoom:s,invertPan:o}=this.options,r=t.ctrlKey||t.metaKey,a=t.ctrlKey&&!t.metaKey;if("pan"===n&&!r){const e=o?-1:1;return void this.setState({panX:this.state.panX-t.deltaX*e,panY:this.state.panY-t.deltaY*e})}if("zoom"===n&&i&&!r)return;const l=this.screenToWorld(e.x,e.y),h=s?-t.deltaY:t.deltaY,d=a&&t.deltaMode===WheelEvent.DOM_DELTA_PIXEL?this.options.pinchZoomSpeed:1,c=Math.exp(.001*-h*this.options.zoomSpeed*d),u=(p=this.state.zoom*c,g=this.options.minZoom,v=this.options.maxZoom,Math.max(g,Math.min(v,p)));var p,g,v;const m=e.x-l.x*u,f=e.y-l.y*u;this.setState({zoom:u,panX:m,panY:f})},this.svg.addEventListener("wheel",this.svgWheelHandler,{passive:!1}),this.svgPointerDownHandler=t=>{if(0!==t.button)return;if(null!==this.dragPointerId)return;if(this.options.panRequiresSpaceKey&&!this.isSpaceDown)return;this.dragPointerId=t.pointerId,this.isPanning=!1;const e=this.svgPoint(t.clientX,t.clientY);this.panStart={panX:this.state.panX,panY:this.state.panY,x:e.x,y:e.y}},this.svg.addEventListener("pointerdown",this.svgPointerDownHandler),this.svgPointerMoveHandler=t=>{if(null===this.dragPointerId)return;if(t.pointerId!==this.dragPointerId)return;if(!this.panStart)return;const e=this.svgPoint(t.clientX,t.clientY),n=e.x-this.panStart.x,s=e.y-this.panStart.y;if(!this.isPanning){if(Math.hypot(n,s)<i.DRAG_THRESHOLD_PX)return;this.isPanning=!0,this.svg.setPointerCapture(t.pointerId)}this.setState({panX:this.panStart.panX+n,panY:this.panStart.panY+s})},this.svg.addEventListener("pointermove",this.svgPointerMoveHandler);const t=t=>{if(null!==this.dragPointerId&&t.pointerId===this.dragPointerId){if(this.isPanning)try{this.svg.releasePointerCapture(t.pointerId)}catch{}this.dragPointerId=null,this.panStart=null,this.isPanning=!1}};this.svgPointerUpHandler=t,this.svgPointerCancelHandler=t,this.svgPointerLeaveHandler=()=>{if(this.isPanning&&null!==this.dragPointerId)try{this.svg.releasePointerCapture(this.dragPointerId)}catch{}this.dragPointerId=null,this.panStart=null,this.isPanning=!1},this.svg.addEventListener("pointerup",this.svgPointerUpHandler),this.svg.addEventListener("pointercancel",this.svgPointerCancelHandler),this.svg.addEventListener("pointerleave",this.svgPointerLeaveHandler)}render(){const{zoom:t,panX:e,panY:n}=this.state;this.world.setAttribute("transform",`matrix(${t} 0 0 ${t} ${e} ${n})`);const i=this.options.worldGroup?.dynamicAttributes;if(i)for(const[e,n]of Object.entries(i))this.world.setAttribute(e,n(t))}svgPoint(t,e){const n=this.svg.getBoundingClientRect();return{x:t-n.left,y:e-n.top}}screenToWorld(t,e){const{zoom:n,panX:i,panY:s}=this.state;return{x:(t-i)/n,y:(e-s)/n}}}const s=new Map;let o=null,r=null;function a(t){t.hasAttribute("xmlns")&&t.removeAttribute("xmlns");for(const e of Array.from(t.attributes))e.name.startsWith("xmlns:")&&t.removeAttribute(e.name);for(const e of Array.from(t.children))a(e)}function l(t){const e=t.trim();if(!e)return"";const n=`<svg xmlns="http://www.w3.org/2000/svg">${e}</svg>`;try{const t=(new DOMParser).parseFromString(n,"image/svg+xml"),e=t.documentElement;if(!e||"svg"!==e.nodeName.toLowerCase())return"";t.querySelectorAll("script, foreignObject").forEach(t=>t.remove()),t.querySelectorAll("*").forEach(t=>{for(const e of Array.from(t.attributes))e.name.toLowerCase().startsWith("on")&&t.removeAttribute(e.name),("xmlns"===e.name||e.name.startsWith("xmlns:"))&&t.removeAttribute(e.name)});const i=e.innerHTML;return"string"==typeof i?i.trim():(new XMLSerializer).serializeToString(e).replace(/^<svg[^>]*>|<\/svg>$/g,"").trim()}catch{return""}}function h(t){const e=t.trim();if(!e)return[];const n=`<svg xmlns="http://www.w3.org/2000/svg">${e}</svg>`;try{const t=(new DOMParser).parseFromString(n,"image/svg+xml"),e=t.documentElement;if(!e||"svg"!==e.nodeName.toLowerCase())return[];t.querySelectorAll("script, foreignObject").forEach(t=>t.remove()),t.querySelectorAll("*").forEach(t=>{for(const e of Array.from(t.attributes))e.name.toLowerCase().startsWith("on")&&t.removeAttribute(e.name),("xmlns"===e.name||e.name.startsWith("xmlns:"))&&t.removeAttribute(e.name)});const i=Array.from(e.children).map(t=>document.importNode(t,!0));for(const t of i)a(t);return i}catch{return[]}}function d(t){const e=l(t);if(!e)return null;const n=s.get(e);if(n)return n;const{svg:i,g:a}=function(){if(o&&r)return{svg:o,g:r};const t=document.createElementNS("http://www.w3.org/2000/svg","svg");t.setAttribute("width","0"),t.setAttribute("height","0"),t.style.position="absolute",t.style.left="-10000px",t.style.top="-10000px",t.style.visibility="hidden",t.style.pointerEvents="none";const e=document.createElementNS("http://www.w3.org/2000/svg","g");return t.appendChild(e),o=t,r=e,{svg:t,g:e}}();!function(t){t.isConnected||document.body.appendChild(t)}(i),a.replaceChildren();const d=h(e);for(const t of d)a.appendChild(t.cloneNode(!0));try{const t=a.getBBox();let n=0;a.querySelectorAll("*").forEach(t=>{try{const e=getComputedStyle(t),i=e.stroke;if(!i||"none"===i||"transparent"===i)return;const s=Number.parseFloat(e.strokeWidth??"0");Number.isFinite(s)&&s>n&&(n=s)}catch{}});const i=Math.max(0,n/2),o={bbox:{x:t.x,y:t.y,width:t.width,height:t.height},pad:i};return s.set(e,o),o}catch{return null}finally{!function(t){t.isConnected&&t.remove()}(i)}}t.Node=class{id;fragment;x;y;width;height;onClick;onDoubleClick;onRightClick;_el=null;constructor(t){if(!t||"string"!=typeof t.id||""===t.id)throw new Error("Node requires a non-empty 'id' property");this.id=t.id,this.fragment=t.fragment??"",this.x=Number.isFinite(t?.x)?t?.x:0,this.y=Number.isFinite(t?.y)?t?.y:0;const e=t?.width,n=t?.height;this.width="number"==typeof e&&Number.isFinite(e)&&e>0?e:null,this.height="number"==typeof n&&Number.isFinite(n)&&n>0?n:null,this.onClick=t?.onClick,this.onDoubleClick=t?.onDoubleClick,this.onRightClick=t?.onRightClick}get el(){if(!this._el){const t=document.createElementNS("http://www.w3.org/2000/svg","g");t.dataset.nodeId=this.id,this._el=t}return this._el}},t.PanZoomCanvas=i,t.SvgCore=class{canvas;nodesLayer;nodes=[];nodeIdToIndex=new Map;nodeBounds=null;cullingEnabled=!0;cullingOverscanPx=30;resizeObserver=null;unsubPanZoom=null;unsubSvgEvents=null;svgClickTimer=null;suppressNextClick=!1;dragWatch=null;cullingListeners=new Set;lastCullingStats={visible:0,hidden:0,total:0};cullingNotifyScheduled=!1;get svg(){return this.canvas.svg}get world(){return this.canvas.world}createWorldLayer(t,n){const i=e("g");t&&(i.dataset.layer=t),n?.pointerEvents&&(i.style.pointerEvents=n.pointerEvents);return"below-nodes"===(n?.position??"below-nodes")?this.world.insertBefore(i,this.nodesLayer):this.world.appendChild(i),i}get state(){return this.canvas.state}get panZoomOptions(){return this.canvas.options}constructor(t,e){t instanceof i?(this.canvas=t,e?.panZoom&&this.canvas.setOptions(e.panZoom)):this.canvas=new i(t,e?.panZoom),this.nodesLayer=document.createElementNS("http://www.w3.org/2000/svg","g"),this.nodesLayer.dataset.layer="nodes",this.world.appendChild(this.nodesLayer),this.world.style.pointerEvents="none";const n=e?.culling;"boolean"==typeof n?this.cullingEnabled=n:n&&("boolean"==typeof n.enabled&&(this.cullingEnabled=n.enabled),"number"==typeof n.overscanPx&&(this.cullingOverscanPx=Math.max(0,n.overscanPx))),this.unsubPanZoom=this.canvas.subscribe(()=>this.applyCulling()),this.resizeObserver=new ResizeObserver(()=>this.applyCulling()),this.resizeObserver.observe(this.svg);const s=()=>{null!==this.svgClickTimer&&(window.clearTimeout(this.svgClickTimer),this.svgClickTimer=null)},o=t=>{0===t.button&&(this.dragWatch={pointerId:t.pointerId,startClientX:t.clientX,startClientY:t.clientY,moved:!1})},r=t=>{const e=this.dragWatch;if(!e)return;if(t.pointerId!==e.pointerId)return;if(1&~t.buttons)return;const n=t.clientX-e.startClientX,i=t.clientY-e.startClientY;!e.moved&&Math.hypot(n,i)>=5&&(e.moved=!0)},a=t=>{const e=this.dragWatch;e&&t.pointerId===e.pointerId&&(this.dragWatch=null,e.moved&&(this.suppressNextClick=!0,s()))},l=t=>{if(this.suppressNextClick)this.suppressNextClick=!1;else{if(null!==this.svgClickTimer){s();const e=this.hitTestVisibleNodeAtClient(t.clientX,t.clientY);return void(e?.onDoubleClick&&e.onDoubleClick(e))}this.svgClickTimer=window.setTimeout(()=>{this.svgClickTimer=null;const e=this.hitTestVisibleNodeAtClient(t.clientX,t.clientY);e?.onClick&&e.onClick(e)},300)}},h=t=>{t.preventDefault(),s();const e=this.hitTestVisibleNodeAtClient(t.clientX,t.clientY);e?.onRightClick&&e.onRightClick(e)};this.svg.addEventListener("click",l),this.svg.addEventListener("contextmenu",h),this.svg.addEventListener("pointerdown",o),this.svg.addEventListener("pointermove",r),this.svg.addEventListener("pointerup",a),this.svg.addEventListener("pointercancel",a),this.unsubSvgEvents=()=>{this.svg.removeEventListener("click",l),this.svg.removeEventListener("contextmenu",h),this.svg.removeEventListener("pointerdown",o),this.svg.removeEventListener("pointermove",r),this.svg.removeEventListener("pointerup",a),this.svg.removeEventListener("pointercancel",a),s()}}setZoom(t,e){const n=this.canvas.options.minZoom,i=this.canvas.options.maxZoom,s=Math.min(i,Math.max(n,t)),o=this.svg.getBoundingClientRect(),r=e?.x??Math.max(1,o.width)/2,a=e?.y??Math.max(1,o.height)/2,l=this.state,h=r-(r-l.panX)/Math.max(1e-9,l.zoom)*s,d=a-(a-l.panY)/Math.max(1e-9,l.zoom)*s;this.setState({zoom:s,panX:h,panY:d})}clientToCanvas(t,e){const n=this.svg.getBoundingClientRect(),i=t-n.left,s=e-n.top,{panX:o,panY:r,zoom:a}=this.state,l=Math.max(1e-9,a);return{x:(i-o)/l,y:(s-r)/l}}hitTestVisibleNodeAtClient(t,e){if(!this.nodeBounds||0===this.nodes.length)return null;const n=this.clientToCanvas(t,e),i=this.nodesLayer.children;for(let t=i.length-1;t>=0;t--){const e=i.item(t);if(!e)continue;const s=e.dataset.nodeId;if(!s)continue;const o=this.nodeIdToIndex.get(s);if(void 0===o)continue;const r=this.nodeBounds[o];if(r&&(n.x>=r.x0&&n.x<=r.x1&&n.y>=r.y0&&n.y<=r.y1))return this.nodes[o]}return null}zoomBy(t,e){const n=Number.isFinite(t)?t:1;n<=0||this.setZoom(this.state.zoom*n,e)}setState(t){this.canvas.setState(t)}resetView(){this.canvas.reset()}configurePanZoom(t){this.canvas.setOptions(t)}setNodes(t){const e=new Set,n=new Set;for(let i=0;i<t.length;i++){const s=t[i].id;e.has(s)?n.add(s):e.add(s)}n.size>0&&console.warn(`Duplicate node ids found: ${Array.from(n).map(t=>`"${t}"`).join(", ")}. Each node should have a unique id.`),this.nodes=t,this.nodeIdToIndex.clear();for(let e=0;e<t.length;e++)this.nodeIdToIndex.set(t[e].id,e);this.redraw()}redraw(t){Array.isArray(t)&&t.length>0?(this.renderNodes(t),this.applyCulling()):(this.renderNodes(),this.applyCulling())}setCullingEnabled(t){this.cullingEnabled=t,this.applyCulling()}setCullingOverscanPx(t){this.cullingOverscanPx=Math.max(0,t),this.applyCulling()}onCullingStatsChange(t){return this.cullingListeners.add(t),t(this.lastCullingStats),()=>this.cullingListeners.delete(t)}onPanZoomChange(t){return this.canvas.subscribe(t)}remove(t){if(!t||0===t.length)return this.nodes=[],this.nodeIdToIndex.clear(),this.nodesLayer.replaceChildren(),this.nodeBounds=null,void this.setCullingStats({visible:0,hidden:0,total:0});const e=new Set;for(const n of t){const t=this.nodeIdToIndex.get(n);void 0!==t&&e.add(t)}if(0===e.size)return;const n=Array.from(e).sort((t,e)=>e-t);for(const t of n){const e=this.nodes[t];e&&(e.el.parentElement&&e.el.remove(),this.nodeIdToIndex.delete(e.id)),this.nodes.splice(t,1)}this.nodeIdToIndex.clear();for(let t=0;t<this.nodes.length;t++)this.nodeIdToIndex.set(this.nodes[t].id,t);if(this.nodeBounds){const t=[];for(let e=0;e<this.nodes.length;e++){const n=this.nodes[e],i=d(n.fragment),s=i?.bbox??{width:240,height:160},o=i?.pad??0,r=n.width??Math.max(1,s.width+2*o),a=n.height??Math.max(1,s.height+2*o);t.push({x0:n.x,y0:n.y,x1:n.x+r,y1:n.y+a})}this.nodeBounds=t}this.applyCulling()}destroy(){this.resizeObserver?.disconnect(),this.resizeObserver=null,this.unsubPanZoom?.(),this.unsubPanZoom=null,this.unsubSvgEvents?.(),this.unsubSvgEvents=null,this.cullingListeners.clear(),this.canvas.destroy()}renderNodes(t){if(t&&t.length>0){for(const e of t){const t=this.nodeIdToIndex.get(e);if(void 0===t)continue;const n=this.nodes[t];if(!n)continue;const i=n.el;i.replaceChildren(),i.setAttribute("transform",`translate(${n.x} ${n.y})`);const s=l(n.fragment);if(s){const e=h(s),o=d(s),r=o?.bbox??{x:0,y:0,width:240,height:160},a=o?.pad??0,l=Math.max(1,r.width+2*a),c=Math.max(1,r.height+2*a),u=-r.x+a,p=-r.y+a,g=document.createElementNS("http://www.w3.org/2000/svg","g");g.setAttribute("transform",`translate(${u} ${p})`);for(const t of e)g.appendChild(t.cloneNode(!0));if(i.appendChild(g),this.nodeBounds){const e=n.width??l,i=n.height??c;this.nodeBounds[t]={x0:n.x,y0:n.y,x1:n.x+e,y1:n.y+i}}}i.parentElement||this.nodesLayer.appendChild(i)}return}if(this.nodesLayer.replaceChildren(),this.nodeBounds=null,0===this.nodes.length)return;const e=new Map;for(const t of this.nodes){const n=l(t.fragment);if(!n)continue;if(e.has(n))continue;const i=h(n),s=d(n),o=s?.bbox??{x:0,y:0,width:240,height:160},r=s?.pad??0,a=Math.max(1,o.width+2*r),c=Math.max(1,o.height+2*r),u=-o.x+r,p=-o.y+r;e.set(n,{children:i,w:a,h:c,offsetX:u,offsetY:p})}const n=this.nodes.length,i=document.createDocumentFragment(),s=new Array(n);for(let t=0;t<n;t++){const n=this.nodes[t],o=n.el;o.replaceChildren(),o.setAttribute("transform",`translate(${n.x} ${n.y})`);const r=l(n.fragment),a=r?e.get(r):null;if(a){const t=document.createElementNS("http://www.w3.org/2000/svg","g");t.setAttribute("transform",`translate(${a.offsetX} ${a.offsetY})`);for(const e of a.children)t.appendChild(e.cloneNode(!0));o.appendChild(t)}const h=n.width??a?.w??240,d=n.height??a?.h??160;s[t]={x0:n.x,y0:n.y,x1:n.x+h,y1:n.y+d},i.appendChild(o)}this.nodesLayer.appendChild(i),this.nodeBounds=s}applyCulling(){if(!this.nodeBounds)return void this.setCullingStats({visible:0,hidden:0,total:this.nodes.length});const t=this.nodes.length;if(!this.cullingEnabled){this.nodesLayer.replaceChildren(...this.nodes.map(t=>t.el));for(const t of this.nodes)t.el.removeAttribute("display");return void this.setCullingStats({visible:t,hidden:0,total:t})}const e=this.getWorldViewport(this.state,this.cullingOverscanPx),n=[];for(let i=0;i<t;i++){const t=this.nodeBounds[i];if(t&&this.rectsIntersect(t,e)){const t=this.nodes[i].el;t.removeAttribute("display"),n.push(t)}}this.nodesLayer.replaceChildren(...n),this.setCullingStats({visible:n.length,hidden:t-n.length,total:t})}setCullingStats(t){const e=this.lastCullingStats;e.visible===t.visible&&e.hidden===t.hidden&&e.total===t.total||(this.lastCullingStats=t,this.scheduleCullingNotify())}scheduleCullingNotify(){this.cullingNotifyScheduled||(this.cullingNotifyScheduled=!0,requestAnimationFrame(()=>{this.cullingNotifyScheduled=!1;for(const t of this.cullingListeners)t(this.lastCullingStats)}))}rectsIntersect(t,e){return!(t.x1<e.x0||t.x0>e.x1||t.y1<e.y0||t.y0>e.y1)}getWorldViewport(t,e){const n=this.svg.getBoundingClientRect(),i=Math.max(1,n.width),s=Math.max(1,n.height),o=Math.max(1e-9,t.zoom),r=Math.max(0,e)/o;return{x0:-t.panX/o-r,y0:-t.panY/o-r,x1:(i-t.panX)/o+r,y1:(s-t.panY)/o+r}}},t.measureFragmentMetrics=d});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vkcha/svg-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A lightweight SVG rendering core library in TypeScript for the web: scene graph, viewport culling, zoom/pan, event handling",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"svg",
|
|
@@ -24,25 +24,27 @@
|
|
|
24
24
|
"homepage": "https://vkcha.com",
|
|
25
25
|
"private": false,
|
|
26
26
|
"type": "module",
|
|
27
|
-
"main": "dist/
|
|
27
|
+
"main": "dist/index.cjs",
|
|
28
|
+
"module": "dist/index.js",
|
|
28
29
|
"types": "dist/index.d.ts",
|
|
29
30
|
"exports": {
|
|
30
31
|
".": {
|
|
31
32
|
"types": "./dist/index.d.ts",
|
|
32
|
-
"import": "./dist/
|
|
33
|
-
"require": "./dist/
|
|
33
|
+
"import": "./dist/index.js",
|
|
34
|
+
"require": "./dist/index.cjs"
|
|
34
35
|
}
|
|
35
36
|
},
|
|
37
|
+
"unpkg": "dist/vkcha.min.js",
|
|
38
|
+
"jsdelivr": "dist/vkcha.min.js",
|
|
36
39
|
"files": [
|
|
37
40
|
"dist",
|
|
38
|
-
"src",
|
|
39
41
|
"README.md",
|
|
40
42
|
"LICENSE"
|
|
41
43
|
],
|
|
42
44
|
"scripts": {
|
|
43
45
|
"dev": "vite",
|
|
44
46
|
"build:demo": "vite build",
|
|
45
|
-
"build:lib": "rollup -c && node scripts/minify.js",
|
|
47
|
+
"build:lib": "rm -rf dist && rollup -c && node scripts/minify.js",
|
|
46
48
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
47
49
|
"preview": "vite preview"
|
|
48
50
|
},
|