niimbot-canvas-sdk 1.0.3 → 1.0.4

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
+ "use strict";var be=Object.defineProperty;var Ae=(e,n,t)=>n in e?be(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t;var g=(e,n,t)=>(Ae(e,typeof n!="symbol"?n+"":n,t),t),X=(e,n,t)=>{if(!n.has(e))throw TypeError("Cannot "+t)};var h=(e,n,t)=>(X(e,n,"read from private field"),t?t.call(e):n.get(e)),A=(e,n,t)=>{if(n.has(e))throw TypeError("Cannot add the same private member more than once");n instanceof WeakSet?n.add(e):n.set(e,t)},_=(e,n,t,s)=>(X(e,n,"write to private field"),s?s.call(e,t):n.set(e,t),t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var Ee=class extends Error{constructor(n,t){super(t);g(this,"code");this.name="PenpalError",this.code=n}},P=Ee,we=e=>({name:e.name,message:e.message,stack:e.stack,penpalCode:e instanceof P?e.code:void 0}),Ie=({name:e,message:n,stack:t,penpalCode:s})=>{const r=s?new P(s,n):new Error(n);return r.name=e,r.stack=t,r},Me=Symbol("Reply"),G,re,Pe=(re=class{constructor(e,n){g(this,"value");g(this,"transferables");A(this,G,Me);this.value=e,this.transferables=n==null?void 0:n.transferables}},G=new WeakMap,re),Ce=Pe,M="penpal",W=e=>typeof e=="object"&&e!==null,ce=e=>typeof e=="function",_e=e=>W(e)&&e.namespace===M,z=e=>e.type==="SYN",Z=e=>e.type==="ACK1",B=e=>e.type==="ACK2",de=e=>e.type==="CALL",he=e=>e.type==="REPLY",Se=e=>e.type==="DESTROY",ue=(e,n=[])=>{const t=[];for(const s of Object.keys(e)){const r=e[s];ce(r)?t.push([...n,s]):W(r)&&t.push(...ue(r,[...n,s]))}return t},Oe=(e,n)=>{const t=e.reduce((s,r)=>W(s)?s[r]:void 0,n);return ce(t)?t:void 0},N=e=>e.join("."),ee=(e,n,t)=>({namespace:M,channel:e,type:"REPLY",callId:n,isError:!0,...t instanceof Error?{value:we(t),isSerializedErrorInstance:!0}:{value:t}}),Re=(e,n,t,s)=>{let r=!1;const p=async u=>{if(r||!de(u))return;s==null||s(`Received ${N(u.methodPath)}() call`,u);const{methodPath:l,args:c,id:a}=u;let i,o;try{const f=Oe(l,n);if(!f)throw new P("METHOD_NOT_FOUND",`Method \`${N(l)}\` is not found.`);let v=await f(...c);v instanceof Ce&&(o=v.transferables,v=await v.value),i={namespace:M,channel:t,type:"REPLY",callId:a,value:v}}catch(f){i=ee(t,a,f)}if(!r)try{s==null||s(`Sending ${N(l)}() reply`,i),e.sendMessage(i,o)}catch(f){throw f.name==="DataCloneError"&&(i=ee(t,a,f),s==null||s(`Sending ${N(l)}() reply`,i),e.sendMessage(i)),f}};return e.addMessageHandler(p),()=>{r=!0,e.removeMessageHandler(p)}},Ne=Re,ie,le=((ie=crypto.randomUUID)==null?void 0:ie.bind(crypto))??(()=>new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-")),Te=Symbol("CallOptions"),J,ae,De=(ae=class{constructor(e){g(this,"transferables");g(this,"timeout");A(this,J,Te);this.transferables=e==null?void 0:e.transferables,this.timeout=e==null?void 0:e.timeout}},J=new WeakMap,ae),ke=De,Le=new Set(["apply","call","bind"]),fe=(e,n,t=[])=>new Proxy(t.length?()=>{}:Object.create(null),{get(s,r){if(r!=="then")return t.length&&Le.has(r)?Reflect.get(s,r):fe(e,n,[...t,r])},apply(s,r,p){return e(t,p)}}),te=e=>new P("CONNECTION_DESTROYED",`Method call ${N(e)}() failed due to destroyed connection`),xe=(e,n,t)=>{let s=!1;const r=new Map,p=c=>{if(!he(c))return;const{callId:a,value:i,isError:o,isSerializedErrorInstance:f}=c,v=r.get(a);v&&(r.delete(a),t==null||t(`Received ${N(v.methodPath)}() call`,c),o?v.reject(f?Ie(i):i):v.resolve(i))};return e.addMessageHandler(p),{remoteProxy:fe((c,a)=>{if(s)throw te(c);const i=le(),o=a[a.length-1],f=o instanceof ke,{timeout:v,transferables:b}=f?o:{},E=f?a.slice(0,-1):a;return new Promise((d,w)=>{const C=v!==void 0?window.setTimeout(()=>{r.delete(i),w(new P("METHOD_CALL_TIMEOUT",`Method call ${N(c)}() timed out after ${v}ms`))},v):void 0;r.set(i,{methodPath:c,resolve:d,reject:w,timeoutId:C});try{const y={namespace:M,channel:n,type:"CALL",id:i,methodPath:c,args:E};t==null||t(`Sending ${N(c)}() call`,y),e.sendMessage(y,b)}catch(y){w(new P("TRANSMISSION_FAILED",y.message))}})},t),destroy:()=>{s=!0,e.removeMessageHandler(p);for(const{methodPath:c,reject:a,timeoutId:i}of r.values())clearTimeout(i),a(te(c));r.clear()}}},He=xe,Ue=()=>{let e,n;return{promise:new Promise((s,r)=>{e=s,n=r}),resolve:e,reject:n}},$e=Ue,je=class extends Error{constructor(e){super(`You've hit a bug in Penpal. Please file an issue with the following information: ${e}`)}},Y=je,Q="deprecated-penpal",qe=e=>W(e)&&"penpal"in e,Fe=e=>e.split("."),ne=e=>e.join("."),ve=e=>new Y(`Unexpected message to translate: ${JSON.stringify(e)}`),Ve=e=>{if(e.penpal==="syn")return{namespace:M,channel:void 0,type:"SYN",participantId:Q};if(e.penpal==="ack")return{namespace:M,channel:void 0,type:"ACK2"};if(e.penpal==="call")return{namespace:M,channel:void 0,type:"CALL",id:e.id,methodPath:Fe(e.methodName),args:e.args};if(e.penpal==="reply")return e.resolution==="fulfilled"?{namespace:M,channel:void 0,type:"REPLY",callId:e.id,value:e.returnValue}:{namespace:M,channel:void 0,type:"REPLY",callId:e.id,isError:!0,...e.returnValueIsError?{value:e.returnValue,isSerializedErrorInstance:!0}:{value:e.returnValue}};throw ve(e)},ze=e=>{if(Z(e))return{penpal:"synAck",methodNames:e.methodPaths.map(ne)};if(de(e))return{penpal:"call",id:e.id,methodName:ne(e.methodPath),args:e.args};if(he(e))return e.isError?{penpal:"reply",id:e.callId,resolution:"rejected",...e.isSerializedErrorInstance?{returnValue:e.value,returnValueIsError:!0}:{returnValue:e.value}}:{penpal:"reply",id:e.callId,resolution:"fulfilled",returnValue:e.value};throw ve(e)},Ye=({messenger:e,methods:n,timeout:t,channel:s,log:r})=>{const p=le();let u;const l=[];let c=!1;const a=ue(n),{promise:i,resolve:o,reject:f}=$e(),v=t!==void 0?setTimeout(()=>{f(new P("CONNECTION_TIMEOUT",`Connection timed out after ${t}ms`))},t):void 0,b=()=>{for(const m of l)m()},E=()=>{if(c)return;l.push(Ne(e,n,s,r));const{remoteProxy:m,destroy:T}=He(e,s,r);l.push(T),clearTimeout(v),c=!0,o({remoteProxy:m,destroy:b})},d=()=>{const m={namespace:M,type:"SYN",channel:s,participantId:p};r==null||r("Sending handshake SYN",m);try{e.sendMessage(m)}catch(T){f(new P("TRANSMISSION_FAILED",T.message))}},w=m=>{if(r==null||r("Received handshake SYN",m),m.participantId===u&&u!==Q||(u=m.participantId,d(),!(p>u||u===Q)))return;const V={namespace:M,channel:s,type:"ACK1",methodPaths:a};r==null||r("Sending handshake ACK1",V);try{e.sendMessage(V)}catch(me){f(new P("TRANSMISSION_FAILED",me.message));return}},C=m=>{r==null||r("Received handshake ACK1",m);const T={namespace:M,channel:s,type:"ACK2"};r==null||r("Sending handshake ACK2",T);try{e.sendMessage(T)}catch(V){f(new P("TRANSMISSION_FAILED",V.message));return}E()},y=m=>{r==null||r("Received handshake ACK2",m),E()},F=m=>{z(m)&&w(m),Z(m)&&C(m),B(m)&&y(m)};return e.addMessageHandler(F),l.push(()=>e.removeMessageHandler(F)),d(),i},Ke=Ye,We=e=>{let n=!1,t;return(...s)=>(n||(n=!0,t=e(...s)),t)},Be=We,se=new WeakSet,Qe=({messenger:e,methods:n={},timeout:t,channel:s,log:r})=>{if(!e)throw new P("INVALID_ARGUMENT","messenger must be defined");if(se.has(e))throw new P("INVALID_ARGUMENT","A messenger can only be used for a single connection");se.add(e);const p=[e.destroy],u=Be(a=>{if(a){const i={namespace:M,channel:s,type:"DESTROY"};try{e.sendMessage(i)}catch{}}for(const i of p)i();r==null||r("Connection destroyed")}),l=a=>_e(a)&&a.channel===s;return{promise:(async()=>{try{e.initialize({log:r,validateReceivedMessage:l}),e.addMessageHandler(o=>{Se(o)&&u(!1)});const{remoteProxy:a,destroy:i}=await Ke({messenger:e,methods:n,timeout:t,channel:s,log:r});return p.push(i),a}catch(a){throw u(!0),a}})(),destroy:()=>{u(!0)}}},Ge=Qe,O,D,x,H,k,R,I,L,K,U,j,q,$,oe,Je=(oe=class{constructor({remoteWindow:e,allowedOrigins:n}){A(this,O,void 0);A(this,D,void 0);A(this,x,void 0);A(this,H,void 0);A(this,k,void 0);A(this,R,new Set);A(this,I,void 0);A(this,L,!1);g(this,"initialize",({log:e,validateReceivedMessage:n})=>{_(this,x,e),_(this,H,n),window.addEventListener("message",h(this,q))});g(this,"sendMessage",(e,n)=>{if(z(e)){const t=h(this,U).call(this,e);h(this,O).postMessage(e,{targetOrigin:t,transfer:n});return}if(Z(e)||h(this,L)){const t=h(this,L)?ze(e):e,s=h(this,U).call(this,e);h(this,O).postMessage(t,{targetOrigin:s,transfer:n});return}if(B(e)){const{port1:t,port2:s}=new MessageChannel;_(this,I,t),t.addEventListener("message",h(this,$)),t.start();const r=[s,...n||[]],p=h(this,U).call(this,e);h(this,O).postMessage(e,{targetOrigin:p,transfer:r});return}if(h(this,I)){h(this,I).postMessage(e,{transfer:n});return}throw new Y("Port is undefined")});g(this,"addMessageHandler",e=>{h(this,R).add(e)});g(this,"removeMessageHandler",e=>{h(this,R).delete(e)});g(this,"destroy",()=>{window.removeEventListener("message",h(this,q)),h(this,j).call(this),h(this,R).clear()});A(this,K,e=>h(this,D).some(n=>n instanceof RegExp?n.test(e):n===e||n==="*"));A(this,U,e=>{if(z(e))return"*";if(!h(this,k))throw new Y("Concrete remote origin not set");return h(this,k)==="null"&&h(this,D).includes("*")?"*":h(this,k)});A(this,j,()=>{var e,n;(e=h(this,I))==null||e.removeEventListener("message",h(this,$)),(n=h(this,I))==null||n.close(),_(this,I,void 0)});A(this,q,({source:e,origin:n,ports:t,data:s})=>{var r,p,u;if(e===h(this,O)&&(qe(s)&&((r=h(this,x))==null||r.call(this,"Please upgrade the child window to the latest version of Penpal."),_(this,L,!0),s=Ve(s)),!!((p=h(this,H))!=null&&p.call(this,s)))){if(!h(this,K).call(this,n)){(u=h(this,x))==null||u.call(this,`Received a message from origin \`${n}\` which did not match allowed origins \`[${h(this,D).join(", ")}]\``);return}if(z(s)&&(h(this,j).call(this),_(this,k,n)),B(s)&&!h(this,L)){if(_(this,I,t[0]),!h(this,I))throw new Y("No port received on ACK2");h(this,I).addEventListener("message",h(this,$)),h(this,I).start()}for(const l of h(this,R))l(s)}});A(this,$,({data:e})=>{var n;if((n=h(this,H))!=null&&n.call(this,e))for(const t of h(this,R))t(e)});if(!e)throw new P("INVALID_ARGUMENT","remoteWindow must be defined");_(this,O,e),_(this,D,n!=null&&n.length?n:[window.origin])}},O=new WeakMap,D=new WeakMap,x=new WeakMap,H=new WeakMap,k=new WeakMap,R=new WeakMap,I=new WeakMap,L=new WeakMap,K=new WeakMap,U=new WeakMap,j=new WeakMap,q=new WeakMap,$=new WeakMap,oe),Ze=Je,Xe=e=>(...n)=>{console.log(`✍️ %c${e}%c`,"font-weight: bold;","",...n)},et=Xe;function tt(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var pe={exports:{}};(function(e){var n=Object.prototype.hasOwnProperty,t="~";function s(){}Object.create&&(s.prototype=Object.create(null),new s().__proto__||(t=!1));function r(c,a,i){this.fn=c,this.context=a,this.once=i||!1}function p(c,a,i,o,f){if(typeof i!="function")throw new TypeError("The listener must be a function");var v=new r(i,o||c,f),b=t?t+a:a;return c._events[b]?c._events[b].fn?c._events[b]=[c._events[b],v]:c._events[b].push(v):(c._events[b]=v,c._eventsCount++),c}function u(c,a){--c._eventsCount===0?c._events=new s:delete c._events[a]}function l(){this._events=new s,this._eventsCount=0}l.prototype.eventNames=function(){var a=[],i,o;if(this._eventsCount===0)return a;for(o in i=this._events)n.call(i,o)&&a.push(t?o.slice(1):o);return Object.getOwnPropertySymbols?a.concat(Object.getOwnPropertySymbols(i)):a},l.prototype.listeners=function(a){var i=t?t+a:a,o=this._events[i];if(!o)return[];if(o.fn)return[o.fn];for(var f=0,v=o.length,b=new Array(v);f<v;f++)b[f]=o[f].fn;return b},l.prototype.listenerCount=function(a){var i=t?t+a:a,o=this._events[i];return o?o.fn?1:o.length:0},l.prototype.emit=function(a,i,o,f,v,b){var E=t?t+a:a;if(!this._events[E])return!1;var d=this._events[E],w=arguments.length,C,y;if(d.fn){switch(d.once&&this.removeListener(a,d.fn,void 0,!0),w){case 1:return d.fn.call(d.context),!0;case 2:return d.fn.call(d.context,i),!0;case 3:return d.fn.call(d.context,i,o),!0;case 4:return d.fn.call(d.context,i,o,f),!0;case 5:return d.fn.call(d.context,i,o,f,v),!0;case 6:return d.fn.call(d.context,i,o,f,v,b),!0}for(y=1,C=new Array(w-1);y<w;y++)C[y-1]=arguments[y];d.fn.apply(d.context,C)}else{var F=d.length,m;for(y=0;y<F;y++)switch(d[y].once&&this.removeListener(a,d[y].fn,void 0,!0),w){case 1:d[y].fn.call(d[y].context);break;case 2:d[y].fn.call(d[y].context,i);break;case 3:d[y].fn.call(d[y].context,i,o);break;case 4:d[y].fn.call(d[y].context,i,o,f);break;default:if(!C)for(m=1,C=new Array(w-1);m<w;m++)C[m-1]=arguments[m];d[y].fn.apply(d[y].context,C)}}return!0},l.prototype.on=function(a,i,o){return p(this,a,i,o,!1)},l.prototype.once=function(a,i,o){return p(this,a,i,o,!0)},l.prototype.removeListener=function(a,i,o,f){var v=t?t+a:a;if(!this._events[v])return this;if(!i)return u(this,v),this;var b=this._events[v];if(b.fn)b.fn===i&&(!f||b.once)&&(!o||b.context===o)&&u(this,v);else{for(var E=0,d=[],w=b.length;E<w;E++)(b[E].fn!==i||f&&!b[E].once||o&&b[E].context!==o)&&d.push(b[E]);d.length?this._events[v]=d.length===1?d[0]:d:u(this,v)}return this},l.prototype.removeAllListeners=function(a){var i;return a?(i=t?t+a:a,this._events[i]&&u(this,i)):(this._events=new s,this._eventsCount=0),this},l.prototype.off=l.prototype.removeListener,l.prototype.addListener=l.prototype.on,l.prefixed=t,l.EventEmitter=l,e.exports=l})(pe);var nt=pe.exports;const st=tt(nt);class ge extends st{on(n,t,s){return super.on(n,t,s)}once(n,t,s){return super.once(n,t,s)}off(n,t,s){return super.off(n,t,s)}emit(n,...t){return super.emit(n,...t)}}class rt{constructor(){g(this,"queue",[]);g(this,"maxSize",100)}enqueue(n,t=3){this.queue.length>=this.maxSize&&this.queue.shift();const s={...n,retryCount:0,maxRetries:t};return this.queue.push(s),n.messageId}dequeue(){return this.queue.shift()}hasMessages(){return this.queue.length>0}getMessageById(n){return this.queue.find(t=>t.messageId===n)}removeMessageById(n){const t=this.queue.findIndex(s=>s.messageId===n);t!==-1&&this.queue.splice(t,1)}clear(){this.queue=[]}}class it{constructor(n,t=!1){this.context=n,this.debug=t}formatMessage(n,...t){return[`[${new Date().toISOString()}] [${this.context}] [${n}]`,...t]}info(...n){console.info(...this.formatMessage("INFO",...n))}debug(...n){this.debug&&console.debug(...this.formatMessage("DEBUG",...n))}warn(...n){console.warn(...this.formatMessage("WARN",...n))}error(...n){console.error(...this.formatMessage("ERROR",...n))}}let at=e=>crypto.getRandomValues(new Uint8Array(e)),ot=(e,n,t)=>{let s=(2<<Math.log2(e.length-1))-1,r=-~(1.6*s*n/e.length);return(p=n)=>{let u="";for(;;){let l=t(r),c=r|0;for(;c--;)if(u+=e[l[c]&s]||"",u.length>=p)return u}}},ct=(e,n=21)=>ot(e,n|0,at);const dt="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",ht=ct(dt,12);class ut extends ge{constructor(t,s={}){super();g(this,"connection",null);g(this,"iframe");g(this,"options");g(this,"messageQueue");g(this,"logger");g(this,"isConnected",!1);g(this,"reconnectAttempts",0);g(this,"maxReconnectAttempts",3);this.iframe=t,this.options={timeout:3e4,debug:!1,retryCount:3,retryDelay:1e3,childOrigin:"*",...s},this.messageQueue=new rt,this.logger=new it("PenpalBridge",this.options.debug)}async connect(t={}){try{this.logger.info("正在建立连接...");const s=new Ze({remoteWindow:this.iframe,allowedOrigins:["http://127.0.0.1:3000"]});this.connection=Ge({messenger:s,methods:{add(r,p){return r+p},emitEvent:(r,p)=>{this.emit(r,p)},...t},timeout:this.options.timeout,log:et("parent")}),await this.connection.promise,this.isConnected=!0,this.reconnectAttempts=0,await this.processQueuedMessages(),this.logger.info("连接建立成功"),this.emit("connected")}catch(s){throw this.logger.error("连接失败:",s),await this.handleReconnect(),s}}async send(t,s){var p;const r={action:t,params:s,timestamp:Date.now(),messageId:ht()};if(!this.isConnected)throw this.messageQueue.enqueue(r),new Error("Connection not ready, message queued");try{if(this.logger.debug("发送消息:",r),!((p=this.connection)!=null&&p.child))throw new Error("连接未就绪");const u=await this.connection.child.handleMessage(r);return this.logger.debug("收到响应:",u),this.validateResponse(u)}catch(u){throw this.logger.error("发送消息失败:",u),this.messageQueue.enqueue(r),u}}async processQueuedMessages(){for(;this.messageQueue.hasMessages();){const t=this.messageQueue.dequeue();if(t)try{await this.send(t.action,t.params)}catch(s){this.logger.warn("队列消息发送失败:",s),this.messageQueue.enqueue(t)}}}async handleReconnect(){if(this.reconnectAttempts>=this.maxReconnectAttempts){this.logger.error("重连次数达到上限"),this.emit("connection-lost");return}this.reconnectAttempts++,this.logger.info(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`),await new Promise(t=>setTimeout(t,this.options.retryDelay*this.reconnectAttempts));try{await this.connect()}catch{await this.handleReconnect()}}validateResponse(t){if(!t||t.success===void 0)throw new Error("Invalid response format");if(!t.success){const s=t.error||{code:"UNKNOWN",message:"Unknown error"};throw new Error(`${s.code}: ${s.message}`)}return t.data}disconnect(){this.connection&&(this.connection.destroy(),this.isConnected=!1,this.emit("disconnected"),this.logger.info("连接已断开"))}getConnectionStatus(){return this.isConnected}}class lt{constructor(n){this.bridge=n}async initialize(n){return this.bridge.send("canvas.initialize",n)}async setData(n){return this.bridge.send("canvas.setData",n)}async getData(){return this.bridge.send("canvas.getData")}async clear(){return this.bridge.send("canvas.clear")}async undo(){return this.bridge.send("canvas.undo")}async redo(){return this.bridge.send("canvas.redo")}async export(n){return this.bridge.send("canvas.export",{format:n})}async save(){return this.bridge.send("canvas.save")}async invoke(n,...t){return this.bridge.send("canvas.invoke",{method:n,args:t})}async setZoom(n){return this.bridge.send("canvas.setZoom",{zoom:n})}async getSnapshot(){return this.bridge.send("canvas.getSnapshot")}}class ft{constructor(n){this.bridge=n}async setAbilities(n){return this.bridge.send("abilities.set",n)}async getAbilities(){return this.bridge.send("abilities.get")}async enableAbility(n){return this.bridge.send("abilities.enable",{name:n})}async disableAbility(n){return this.bridge.send("abilities.disable",{name:n})}}class vt{constructor(n){this.bridge=n}async setTheme(n){return this.bridge.send("theme.set",{theme:n})}async getCurrentTheme(){return this.bridge.send("theme.get")}async updateToken(n){return this.bridge.send("theme.updateToken",n)}}class pt{constructor(n){this.bridge=n}async setLocale(n,t){return this.bridge.send("i18n.setLocale",{locale:n,messages:t})}async getCurrentLocale(){return this.bridge.send("i18n.getLocale")}async updateMessages(n){return this.bridge.send("i18n.updateMessages",n)}}class gt{constructor(n){this.bridge=n}async validateToken(){return this.bridge.send("auth.validateToken")}}const S={READY:"ready",CHANGE:"change",SAVE:"save",ERROR:"error",SELECTION_CHANGED:"selection-changed",CONNECTED:"connected",DISCONNECTED:"disconnected",LOADED:"loaded",BEFORE_UNLOAD:"before-unload",OBJECT_ADDED:"object-added",OBJECT_MODIFIED:"object-modified",OBJECT_REMOVED:"object-removed",MOUSE_DOWN:"mouse-down",MOUSE_UP:"mouse-up",MOUSE_MOVE:"mouse-move",KEY_DOWN:"key-down",KEY_UP:"key-up"};class ye extends ge{constructor(t,s){super();g(this,"bridge");g(this,"canvasAPI");g(this,"abilityAPI");g(this,"themeAPI");g(this,"i18nAPI");g(this,"authAPI");g(this,"config");g(this,"iframe");g(this,"isInitialized",!1);this.validateConfig(s),this.config=s,this.iframe=t,this.bridge=new ut(t,{debug:s.debug||!1,timeout:3e4,childOrigin:this.extractOrigin(t.src)}),this.canvasAPI=new lt(this.bridge),this.abilityAPI=new ft(this.bridge),this.themeAPI=new vt(this.bridge),this.i18nAPI=new pt(this.bridge),this.authAPI=new gt(this.bridge),this.setupEventHandlers()}async init(){if(!this.isInitialized)try{await this.bridge.connect({getConfig:()=>this.config,log:(t,s)=>{console.log(`[Canvas ${t.toUpperCase()}]`,s)}}),await this.canvasAPI.initialize(this.config),this.config.abilities&&await this.abilityAPI.setAbilities(this.config.abilities),this.config.theme&&await this.themeAPI.setTheme(this.config.theme),this.config.locale&&await this.i18nAPI.setLocale(this.config.locale,this.config.messages),this.isInitialized=!0,this.emit(S.READY)}catch(t){throw this.emit(S.ERROR,t),t}}get canvas(){return{setData:t=>this.canvasAPI.setData(t),getData:()=>this.canvasAPI.getData(),clear:()=>this.canvasAPI.clear(),undo:()=>this.canvasAPI.undo(),redo:()=>this.canvasAPI.redo(),export:(t="png")=>this.canvasAPI.export(t),save:()=>this.canvasAPI.save(),setZoom:t=>this.canvasAPI.setZoom(t),getSnapshot:()=>this.canvasAPI.getSnapshot(),invoke:(t,...s)=>this.canvasAPI.invoke(t,...s)}}get abilities(){return{set:t=>this.abilityAPI.setAbilities(t),get:()=>this.abilityAPI.getAbilities(),enable:t=>this.abilityAPI.enableAbility(t),disable:t=>this.abilityAPI.disableAbility(t),updateConfig:(t,s)=>this.abilityAPI.updateAbilityConfig(t,s)}}get theme(){return{set:t=>this.themeAPI.setTheme(t),get:()=>this.themeAPI.getCurrentTheme(),updateToken:t=>this.themeAPI.updateToken(t),reset:()=>this.themeAPI.resetTheme()}}get i18n(){return{setLocale:(t,s)=>this.i18nAPI.setLocale(t,s),getLocale:()=>this.i18nAPI.getCurrentLocale(),updateMessages:t=>this.i18nAPI.updateMessages(t),getMessages:()=>this.i18nAPI.getMessages(),getTranslation:t=>this.i18nAPI.getTranslation(t)}}get auth(){return{validateToken:()=>this.authAPI.validateToken(),refreshToken:t=>this.authAPI.refreshToken(t),getTokenInfo:()=>this.authAPI.getTokenInfo()}}get utils(){return{getConnectionStatus:()=>this.bridge.getConnectionStatus(),disconnect:()=>this.bridge.disconnect(),reconnect:async()=>{this.bridge.disconnect(),this.isInitialized=!1,await this.init()},isInitialized:()=>this.isInitialized}}setupEventHandlers(){this.bridge.on("canvas-change",t=>{this.emit(S.CHANGE,t)}),this.bridge.on("canvas-save",t=>{this.emit(S.SAVE,t)}),this.bridge.on("canvas-error",t=>{this.emit(S.ERROR,t)}),this.bridge.on("canvas-selection-changed",t=>{this.emit(S.SELECTION_CHANGED,t)}),this.bridge.on("connected",()=>{console.log("链接建立成功"),this.emit(S.CONNECTED)}),this.bridge.on("disconnected",()=>{console.log("链接断开"),this.emit(S.DISCONNECTED)})}validateConfig(t){if(!t.token)throw new Error("Token is required");if(t.abilities){const s=["text","image","barcode","multiLayout","shape","qrCode"];Object.keys(t.abilities).forEach(r=>{s.includes(r)||console.warn(`Unknown ability: ${r}`)})}}extractOrigin(t){try{return new URL(t).origin}catch{return"*"}}}function yt(e,n){return new ye(e,n)}exports.CANVAS_EVENTS=S;exports.NiimbotCanvasSDK=ye;exports.createCanvas=yt;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "niimbot-canvas-sdk",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Niimbot Canvas iframe communication SDK",
5
5
  "type": "module",
6
6
  "main": "dist/niimbot-canvas-sdk.umd.js",
@@ -37,15 +37,20 @@
37
37
  "penpal": "^7.0.4"
38
38
  },
39
39
  "devDependencies": {
40
+ "@babel/core": "^7.28.5",
41
+ "@babel/preset-env": "^7.28.5",
40
42
  "@types/node": "^20.0.0",
41
43
  "@typescript-eslint/eslint-plugin": "^6.0.0",
42
44
  "@typescript-eslint/parser": "^6.0.0",
43
45
  "@vitejs/plugin-vue": "^4.0.0",
44
46
  "@vue/test-utils": "^2.0.0",
47
+ "babel-loader": "^10.0.0",
48
+ "babel-plugin-transform-runtime": "^6.23.0",
45
49
  "eslint": "^8.45.0",
46
50
  "eslint-plugin-vue": "^9.0.0",
47
51
  "typescript": "^5.0.0",
48
52
  "vite": "^4.0.0",
53
+ "vite-plugin-babel": "^1.3.2",
49
54
  "vitest": "^0.34.0",
50
55
  "vue": "^3.3.0",
51
56
  "vue-tsc": "^1.8.0"
@@ -1 +0,0 @@
1
- var vt=Object.defineProperty;var gt=(m,E,v)=>E in m?vt(m,E,{enumerable:!0,configurable:!0,writable:!0,value:v}):m[E]=v;var y=(m,E,v)=>(gt(m,typeof E!="symbol"?E+"":E,v),v),Ae=(m,E,v)=>{if(!E.has(m))throw TypeError("Cannot "+v)};var h=(m,E,v)=>(Ae(m,E,"read from private field"),v?v.call(m):E.get(m)),I=(m,E,v)=>{if(E.has(m))throw TypeError("Cannot add the same private member more than once");E instanceof WeakSet?E.add(m):E.set(m,v)},O=(m,E,v,z)=>(Ae(m,E,"write to private field"),z?z.call(m,v):E.set(m,v),v);(function(m,E){typeof exports=="object"&&typeof module<"u"?E(exports):typeof define=="function"&&define.amd?define(["exports"],E):(m=typeof globalThis<"u"?globalThis:m||self,E(m.NiimbotCanvasSDK={}))})(this,function(m){var ee,ge,ye,te,me,R,k,U,$,L,D,S,x,B,j,F,V,q,be;"use strict";var E=class extends Error{constructor(n,t){super(t);y(this,"code");this.name="PenpalError",this.code=n}},v=E,z=e=>({name:e.name,message:e.message,stack:e.stack,penpalCode:e instanceof v?e.code:void 0}),Ee=({name:e,message:n,stack:t,penpalCode:s})=>{const r=s?new v(s,n):new Error(n);return r.name=e,r.stack=t,r},we=Symbol("Reply"),Ie=(ge=class{constructor(e,n){y(this,"value");y(this,"transferables");I(this,ee,we);this.value=e,this.transferables=n==null?void 0:n.transferables}},ee=new WeakMap,ge),Me=Ie,C="penpal",Y=e=>typeof e=="object"&&e!==null,ne=e=>typeof e=="function",Pe=e=>Y(e)&&e.namespace===C,K=e=>e.type==="SYN",J=e=>e.type==="ACK1",Z=e=>e.type==="ACK2",se=e=>e.type==="CALL",re=e=>e.type==="REPLY",Ce=e=>e.type==="DESTROY",ie=(e,n=[])=>{const t=[];for(const s of Object.keys(e)){const r=e[s];ne(r)?t.push([...n,s]):Y(r)&&t.push(...ie(r,[...n,s]))}return t},Se=(e,n)=>{const t=e.reduce((s,r)=>Y(s)?s[r]:void 0,n);return ne(t)?t:void 0},N=e=>e.join("."),ae=(e,n,t)=>({namespace:C,channel:e,type:"REPLY",callId:n,isError:!0,...t instanceof Error?{value:z(t),isSerializedErrorInstance:!0}:{value:t}}),_e=(e,n,t,s)=>{let r=!1;const g=async u=>{if(r||!se(u))return;s==null||s(`Received ${N(u.methodPath)}() call`,u);const{methodPath:l,args:c,id:a}=u;let i,o;try{const f=Se(l,n);if(!f)throw new v("METHOD_NOT_FOUND",`Method \`${N(l)}\` is not found.`);let p=await f(...c);p instanceof Me&&(o=p.transferables,p=await p.value),i={namespace:C,channel:t,type:"REPLY",callId:a,value:p}}catch(f){i=ae(t,a,f)}if(!r)try{s==null||s(`Sending ${N(l)}() reply`,i),e.sendMessage(i,o)}catch(f){throw f.name==="DataCloneError"&&(i=ae(t,a,f),s==null||s(`Sending ${N(l)}() reply`,i),e.sendMessage(i)),f}};return e.addMessageHandler(g),()=>{r=!0,e.removeMessageHandler(g)}},Oe=_e,oe=((ye=crypto.randomUUID)==null?void 0:ye.bind(crypto))??(()=>new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-")),Te=Symbol("CallOptions"),Ne=(me=class{constructor(e){y(this,"transferables");y(this,"timeout");I(this,te,Te);this.transferables=e==null?void 0:e.transferables,this.timeout=e==null?void 0:e.timeout}},te=new WeakMap,me),Re=Ne,De=new Set(["apply","call","bind"]),ce=(e,n,t=[])=>new Proxy(t.length?()=>{}:Object.create(null),{get(s,r){if(r!=="then")return t.length&&De.has(r)?Reflect.get(s,r):ce(e,n,[...t,r])},apply(s,r,g){return e(t,g)}}),de=e=>new v("CONNECTION_DESTROYED",`Method call ${N(e)}() failed due to destroyed connection`),ke=(e,n,t)=>{let s=!1;const r=new Map,g=c=>{if(!re(c))return;const{callId:a,value:i,isError:o,isSerializedErrorInstance:f}=c,p=r.get(a);p&&(r.delete(a),t==null||t(`Received ${N(p.methodPath)}() call`,c),o?p.reject(f?Ee(i):i):p.resolve(i))};return e.addMessageHandler(g),{remoteProxy:ce((c,a)=>{if(s)throw de(c);const i=oe(),o=a[a.length-1],f=o instanceof Re,{timeout:p,transferables:w}=f?o:{},M=f?a.slice(0,-1):a;return new Promise((d,P)=>{const _=p!==void 0?window.setTimeout(()=>{r.delete(i),P(new v("METHOD_CALL_TIMEOUT",`Method call ${N(c)}() timed out after ${p}ms`))},p):void 0;r.set(i,{methodPath:c,resolve:d,reject:P,timeoutId:_});try{const b={namespace:C,channel:n,type:"CALL",id:i,methodPath:c,args:M};t==null||t(`Sending ${N(c)}() call`,b),e.sendMessage(b,w)}catch(b){P(new v("TRANSMISSION_FAILED",b.message))}})},t),destroy:()=>{s=!0,e.removeMessageHandler(g);for(const{methodPath:c,reject:a,timeoutId:i}of r.values())clearTimeout(i),a(de(c));r.clear()}}},Le=ke,xe=()=>{let e,n;return{promise:new Promise((s,r)=>{e=s,n=r}),resolve:e,reject:n}},He=xe,Ue=class extends Error{constructor(e){super(`You've hit a bug in Penpal. Please file an issue with the following information: ${e}`)}},W=Ue,X="deprecated-penpal",$e=e=>Y(e)&&"penpal"in e,je=e=>e.split("."),he=e=>e.join("."),ue=e=>new W(`Unexpected message to translate: ${JSON.stringify(e)}`),qe=e=>{if(e.penpal==="syn")return{namespace:C,channel:void 0,type:"SYN",participantId:X};if(e.penpal==="ack")return{namespace:C,channel:void 0,type:"ACK2"};if(e.penpal==="call")return{namespace:C,channel:void 0,type:"CALL",id:e.id,methodPath:je(e.methodName),args:e.args};if(e.penpal==="reply")return e.resolution==="fulfilled"?{namespace:C,channel:void 0,type:"REPLY",callId:e.id,value:e.returnValue}:{namespace:C,channel:void 0,type:"REPLY",callId:e.id,isError:!0,...e.returnValueIsError?{value:e.returnValue,isSerializedErrorInstance:!0}:{value:e.returnValue}};throw ue(e)},Fe=e=>{if(J(e))return{penpal:"synAck",methodNames:e.methodPaths.map(he)};if(se(e))return{penpal:"call",id:e.id,methodName:he(e.methodPath),args:e.args};if(re(e))return e.isError?{penpal:"reply",id:e.callId,resolution:"rejected",...e.isSerializedErrorInstance?{returnValue:e.value,returnValueIsError:!0}:{returnValue:e.value}}:{penpal:"reply",id:e.callId,resolution:"fulfilled",returnValue:e.value};throw ue(e)},Ve=({messenger:e,methods:n,timeout:t,channel:s,log:r})=>{const g=oe();let u;const l=[];let c=!1;const a=ie(n),{promise:i,resolve:o,reject:f}=He(),p=t!==void 0?setTimeout(()=>{f(new v("CONNECTION_TIMEOUT",`Connection timed out after ${t}ms`))},t):void 0,w=()=>{for(const A of l)A()},M=()=>{if(c)return;l.push(Oe(e,n,s,r));const{remoteProxy:A,destroy:H}=Le(e,s,r);l.push(H),clearTimeout(p),c=!0,o({remoteProxy:A,destroy:w})},d=()=>{const A={namespace:C,type:"SYN",channel:s,participantId:g};r==null||r("Sending handshake SYN",A);try{e.sendMessage(A)}catch(H){f(new v("TRANSMISSION_FAILED",H.message))}},P=A=>{if(r==null||r("Received handshake SYN",A),A.participantId===u&&u!==X||(u=A.participantId,d(),!(g>u||u===X)))return;const G={namespace:C,channel:s,type:"ACK1",methodPaths:a};r==null||r("Sending handshake ACK1",G);try{e.sendMessage(G)}catch(pt){f(new v("TRANSMISSION_FAILED",pt.message));return}},_=A=>{r==null||r("Received handshake ACK1",A);const H={namespace:C,channel:s,type:"ACK2"};r==null||r("Sending handshake ACK2",H);try{e.sendMessage(H)}catch(G){f(new v("TRANSMISSION_FAILED",G.message));return}M()},b=A=>{r==null||r("Received handshake ACK2",A),M()},Q=A=>{K(A)&&P(A),J(A)&&_(A),Z(A)&&b(A)};return e.addMessageHandler(Q),l.push(()=>e.removeMessageHandler(Q)),d(),i},ze=Ve,Ye=e=>{let n=!1,t;return(...s)=>(n||(n=!0,t=e(...s)),t)},Ke=Ye,le=new WeakSet,We=({messenger:e,methods:n={},timeout:t,channel:s,log:r})=>{if(!e)throw new v("INVALID_ARGUMENT","messenger must be defined");if(le.has(e))throw new v("INVALID_ARGUMENT","A messenger can only be used for a single connection");le.add(e);const g=[e.destroy],u=Ke(a=>{if(a){const i={namespace:C,channel:s,type:"DESTROY"};try{e.sendMessage(i)}catch{}}for(const i of g)i();r==null||r("Connection destroyed")}),l=a=>Pe(a)&&a.channel===s;return{promise:(async()=>{try{e.initialize({log:r,validateReceivedMessage:l}),e.addMessageHandler(o=>{Ce(o)&&u(!1)});const{remoteProxy:a,destroy:i}=await ze({messenger:e,methods:n,timeout:t,channel:s,log:r});return g.push(i),a}catch(a){throw u(!0),a}})(),destroy:()=>{u(!0)}}},Be=We,Qe=(be=class{constructor({remoteWindow:e,allowedOrigins:n}){I(this,R,void 0);I(this,k,void 0);I(this,U,void 0);I(this,$,void 0);I(this,L,void 0);I(this,D,new Set);I(this,S,void 0);I(this,x,!1);y(this,"initialize",({log:e,validateReceivedMessage:n})=>{O(this,U,e),O(this,$,n),window.addEventListener("message",h(this,V))});y(this,"sendMessage",(e,n)=>{if(K(e)){const t=h(this,j).call(this,e);h(this,R).postMessage(e,{targetOrigin:t,transfer:n});return}if(J(e)||h(this,x)){const t=h(this,x)?Fe(e):e,s=h(this,j).call(this,e);h(this,R).postMessage(t,{targetOrigin:s,transfer:n});return}if(Z(e)){const{port1:t,port2:s}=new MessageChannel;O(this,S,t),t.addEventListener("message",h(this,q)),t.start();const r=[s,...n||[]],g=h(this,j).call(this,e);h(this,R).postMessage(e,{targetOrigin:g,transfer:r});return}if(h(this,S)){h(this,S).postMessage(e,{transfer:n});return}throw new W("Port is undefined")});y(this,"addMessageHandler",e=>{h(this,D).add(e)});y(this,"removeMessageHandler",e=>{h(this,D).delete(e)});y(this,"destroy",()=>{window.removeEventListener("message",h(this,V)),h(this,F).call(this),h(this,D).clear()});I(this,B,e=>h(this,k).some(n=>n instanceof RegExp?n.test(e):n===e||n==="*"));I(this,j,e=>{if(K(e))return"*";if(!h(this,L))throw new W("Concrete remote origin not set");return h(this,L)==="null"&&h(this,k).includes("*")?"*":h(this,L)});I(this,F,()=>{var e,n;(e=h(this,S))==null||e.removeEventListener("message",h(this,q)),(n=h(this,S))==null||n.close(),O(this,S,void 0)});I(this,V,({source:e,origin:n,ports:t,data:s})=>{var r,g,u;if(e===h(this,R)&&($e(s)&&((r=h(this,U))==null||r.call(this,"Please upgrade the child window to the latest version of Penpal."),O(this,x,!0),s=qe(s)),!!((g=h(this,$))!=null&&g.call(this,s)))){if(!h(this,B).call(this,n)){(u=h(this,U))==null||u.call(this,`Received a message from origin \`${n}\` which did not match allowed origins \`[${h(this,k).join(", ")}]\``);return}if(K(s)&&(h(this,F).call(this),O(this,L,n)),Z(s)&&!h(this,x)){if(O(this,S,t[0]),!h(this,S))throw new W("No port received on ACK2");h(this,S).addEventListener("message",h(this,q)),h(this,S).start()}for(const l of h(this,D))l(s)}});I(this,q,({data:e})=>{var n;if((n=h(this,$))!=null&&n.call(this,e))for(const t of h(this,D))t(e)});if(!e)throw new v("INVALID_ARGUMENT","remoteWindow must be defined");O(this,R,e),O(this,k,n!=null&&n.length?n:[window.origin])}},R=new WeakMap,k=new WeakMap,U=new WeakMap,$=new WeakMap,L=new WeakMap,D=new WeakMap,S=new WeakMap,x=new WeakMap,B=new WeakMap,j=new WeakMap,F=new WeakMap,V=new WeakMap,q=new WeakMap,be),Ge=Qe,Je=e=>(...n)=>{console.log(`✍️ %c${e}%c`,"font-weight: bold;","",...n)},Ze=Je;function Xe(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var fe={exports:{}};(function(e){var n=Object.prototype.hasOwnProperty,t="~";function s(){}Object.create&&(s.prototype=Object.create(null),new s().__proto__||(t=!1));function r(c,a,i){this.fn=c,this.context=a,this.once=i||!1}function g(c,a,i,o,f){if(typeof i!="function")throw new TypeError("The listener must be a function");var p=new r(i,o||c,f),w=t?t+a:a;return c._events[w]?c._events[w].fn?c._events[w]=[c._events[w],p]:c._events[w].push(p):(c._events[w]=p,c._eventsCount++),c}function u(c,a){--c._eventsCount===0?c._events=new s:delete c._events[a]}function l(){this._events=new s,this._eventsCount=0}l.prototype.eventNames=function(){var a=[],i,o;if(this._eventsCount===0)return a;for(o in i=this._events)n.call(i,o)&&a.push(t?o.slice(1):o);return Object.getOwnPropertySymbols?a.concat(Object.getOwnPropertySymbols(i)):a},l.prototype.listeners=function(a){var i=t?t+a:a,o=this._events[i];if(!o)return[];if(o.fn)return[o.fn];for(var f=0,p=o.length,w=new Array(p);f<p;f++)w[f]=o[f].fn;return w},l.prototype.listenerCount=function(a){var i=t?t+a:a,o=this._events[i];return o?o.fn?1:o.length:0},l.prototype.emit=function(a,i,o,f,p,w){var M=t?t+a:a;if(!this._events[M])return!1;var d=this._events[M],P=arguments.length,_,b;if(d.fn){switch(d.once&&this.removeListener(a,d.fn,void 0,!0),P){case 1:return d.fn.call(d.context),!0;case 2:return d.fn.call(d.context,i),!0;case 3:return d.fn.call(d.context,i,o),!0;case 4:return d.fn.call(d.context,i,o,f),!0;case 5:return d.fn.call(d.context,i,o,f,p),!0;case 6:return d.fn.call(d.context,i,o,f,p,w),!0}for(b=1,_=new Array(P-1);b<P;b++)_[b-1]=arguments[b];d.fn.apply(d.context,_)}else{var Q=d.length,A;for(b=0;b<Q;b++)switch(d[b].once&&this.removeListener(a,d[b].fn,void 0,!0),P){case 1:d[b].fn.call(d[b].context);break;case 2:d[b].fn.call(d[b].context,i);break;case 3:d[b].fn.call(d[b].context,i,o);break;case 4:d[b].fn.call(d[b].context,i,o,f);break;default:if(!_)for(A=1,_=new Array(P-1);A<P;A++)_[A-1]=arguments[A];d[b].fn.apply(d[b].context,_)}}return!0},l.prototype.on=function(a,i,o){return g(this,a,i,o,!1)},l.prototype.once=function(a,i,o){return g(this,a,i,o,!0)},l.prototype.removeListener=function(a,i,o,f){var p=t?t+a:a;if(!this._events[p])return this;if(!i)return u(this,p),this;var w=this._events[p];if(w.fn)w.fn===i&&(!f||w.once)&&(!o||w.context===o)&&u(this,p);else{for(var M=0,d=[],P=w.length;M<P;M++)(w[M].fn!==i||f&&!w[M].once||o&&w[M].context!==o)&&d.push(w[M]);d.length?this._events[p]=d.length===1?d[0]:d:u(this,p)}return this},l.prototype.removeAllListeners=function(a){var i;return a?(i=t?t+a:a,this._events[i]&&u(this,i)):(this._events=new s,this._eventsCount=0),this},l.prototype.off=l.prototype.removeListener,l.prototype.addListener=l.prototype.on,l.prefixed=t,l.EventEmitter=l,e.exports=l})(fe);var et=fe.exports;const tt=Xe(et);class pe extends tt{on(n,t,s){return super.on(n,t,s)}once(n,t,s){return super.once(n,t,s)}off(n,t,s){return super.off(n,t,s)}emit(n,...t){return super.emit(n,...t)}}class nt{constructor(){y(this,"queue",[]);y(this,"maxSize",100)}enqueue(n,t=3){this.queue.length>=this.maxSize&&this.queue.shift();const s={...n,retryCount:0,maxRetries:t};return this.queue.push(s),n.messageId}dequeue(){return this.queue.shift()}hasMessages(){return this.queue.length>0}getMessageById(n){return this.queue.find(t=>t.messageId===n)}removeMessageById(n){const t=this.queue.findIndex(s=>s.messageId===n);t!==-1&&this.queue.splice(t,1)}clear(){this.queue=[]}}class st{constructor(n,t=!1){this.context=n,this.debug=t}formatMessage(n,...t){return[`[${new Date().toISOString()}] [${this.context}] [${n}]`,...t]}info(...n){console.info(...this.formatMessage("INFO",...n))}debug(...n){this.debug&&console.debug(...this.formatMessage("DEBUG",...n))}warn(...n){console.warn(...this.formatMessage("WARN",...n))}error(...n){console.error(...this.formatMessage("ERROR",...n))}}let rt=e=>crypto.getRandomValues(new Uint8Array(e)),it=(e,n,t)=>{let s=(2<<Math.log2(e.length-1))-1,r=-~(1.6*s*n/e.length);return(g=n)=>{let u="";for(;;){let l=t(r),c=r|0;for(;c--;)if(u+=e[l[c]&s]||"",u.length>=g)return u}}};const at=((e,n=21)=>it(e,n|0,rt))("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",12);class ot extends pe{constructor(t,s={}){super();y(this,"connection",null);y(this,"iframe");y(this,"options");y(this,"messageQueue");y(this,"logger");y(this,"isConnected",!1);y(this,"reconnectAttempts",0);y(this,"maxReconnectAttempts",3);this.iframe=t,this.options={timeout:3e4,debug:!1,retryCount:3,retryDelay:1e3,childOrigin:"*",...s},this.messageQueue=new nt,this.logger=new st("PenpalBridge",this.options.debug)}async connect(t={}){try{this.logger.info("正在建立连接...");const s=new Ge({remoteWindow:this.iframe,allowedOrigins:["http://127.0.0.1:3000"]});this.connection=Be({messenger:s,methods:{add(r,g){return r+g},emitEvent:(r,g)=>{this.emit(r,g)},...t},timeout:this.options.timeout,log:Ze("parent")}),await this.connection.promise,this.isConnected=!0,this.reconnectAttempts=0,await this.processQueuedMessages(),this.logger.info("连接建立成功"),this.emit("connected")}catch(s){throw this.logger.error("连接失败:",s),await this.handleReconnect(),s}}async send(t,s){var g;const r={action:t,params:s,timestamp:Date.now(),messageId:at()};if(!this.isConnected)throw this.messageQueue.enqueue(r),new Error("Connection not ready, message queued");try{if(this.logger.debug("发送消息:",r),!((g=this.connection)!=null&&g.child))throw new Error("连接未就绪");const u=await this.connection.child.handleMessage(r);return this.logger.debug("收到响应:",u),this.validateResponse(u)}catch(u){throw this.logger.error("发送消息失败:",u),this.messageQueue.enqueue(r),u}}async processQueuedMessages(){for(;this.messageQueue.hasMessages();){const t=this.messageQueue.dequeue();if(t)try{await this.send(t.action,t.params)}catch(s){this.logger.warn("队列消息发送失败:",s),this.messageQueue.enqueue(t)}}}async handleReconnect(){if(this.reconnectAttempts>=this.maxReconnectAttempts){this.logger.error("重连次数达到上限"),this.emit("connection-lost");return}this.reconnectAttempts++,this.logger.info(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`),await new Promise(t=>setTimeout(t,this.options.retryDelay*this.reconnectAttempts));try{await this.connect()}catch{await this.handleReconnect()}}validateResponse(t){if(!t||t.success===void 0)throw new Error("Invalid response format");if(!t.success){const s=t.error||{code:"UNKNOWN",message:"Unknown error"};throw new Error(`${s.code}: ${s.message}`)}return t.data}disconnect(){this.connection&&(this.connection.destroy(),this.isConnected=!1,this.emit("disconnected"),this.logger.info("连接已断开"))}getConnectionStatus(){return this.isConnected}}class ct{constructor(n){this.bridge=n}async initialize(n){return this.bridge.send("canvas.initialize",n)}async setData(n){return this.bridge.send("canvas.setData",n)}async getData(){return this.bridge.send("canvas.getData")}async clear(){return this.bridge.send("canvas.clear")}async undo(){return this.bridge.send("canvas.undo")}async redo(){return this.bridge.send("canvas.redo")}async export(n){return this.bridge.send("canvas.export",{format:n})}async save(){return this.bridge.send("canvas.save")}async invoke(n,...t){return this.bridge.send("canvas.invoke",{method:n,args:t})}async setZoom(n){return this.bridge.send("canvas.setZoom",{zoom:n})}async getSnapshot(){return this.bridge.send("canvas.getSnapshot")}}class dt{constructor(n){this.bridge=n}async setAbilities(n){return this.bridge.send("abilities.set",n)}async getAbilities(){return this.bridge.send("abilities.get")}async enableAbility(n){return this.bridge.send("abilities.enable",{name:n})}async disableAbility(n){return this.bridge.send("abilities.disable",{name:n})}}class ht{constructor(n){this.bridge=n}async setTheme(n){return this.bridge.send("theme.set",{theme:n})}async getCurrentTheme(){return this.bridge.send("theme.get")}async updateToken(n){return this.bridge.send("theme.updateToken",n)}}class ut{constructor(n){this.bridge=n}async setLocale(n,t){return this.bridge.send("i18n.setLocale",{locale:n,messages:t})}async getCurrentLocale(){return this.bridge.send("i18n.getLocale")}async updateMessages(n){return this.bridge.send("i18n.updateMessages",n)}}class lt{constructor(n){this.bridge=n}async validateToken(){return this.bridge.send("auth.validateToken")}}const T={READY:"ready",CHANGE:"change",SAVE:"save",ERROR:"error",SELECTION_CHANGED:"selection-changed",CONNECTED:"connected",DISCONNECTED:"disconnected",LOADED:"loaded",BEFORE_UNLOAD:"before-unload",OBJECT_ADDED:"object-added",OBJECT_MODIFIED:"object-modified",OBJECT_REMOVED:"object-removed",MOUSE_DOWN:"mouse-down",MOUSE_UP:"mouse-up",MOUSE_MOVE:"mouse-move",KEY_DOWN:"key-down",KEY_UP:"key-up"};class ve extends pe{constructor(t,s){super();y(this,"bridge");y(this,"canvasAPI");y(this,"abilityAPI");y(this,"themeAPI");y(this,"i18nAPI");y(this,"authAPI");y(this,"config");y(this,"iframe");y(this,"isInitialized",!1);this.validateConfig(s),this.config=s,this.iframe=t,this.bridge=new ot(t,{debug:s.debug||!1,timeout:3e4,childOrigin:this.extractOrigin(t.src)}),this.canvasAPI=new ct(this.bridge),this.abilityAPI=new dt(this.bridge),this.themeAPI=new ht(this.bridge),this.i18nAPI=new ut(this.bridge),this.authAPI=new lt(this.bridge),this.setupEventHandlers()}async init(){if(!this.isInitialized)try{await this.bridge.connect({getConfig:()=>this.config,log:(t,s)=>{console.log(`[Canvas ${t.toUpperCase()}]`,s)}}),await this.canvasAPI.initialize(this.config),this.config.abilities&&await this.abilityAPI.setAbilities(this.config.abilities),this.config.theme&&await this.themeAPI.setTheme(this.config.theme),this.config.locale&&await this.i18nAPI.setLocale(this.config.locale,this.config.messages),this.isInitialized=!0,this.emit(T.READY)}catch(t){throw this.emit(T.ERROR,t),t}}get canvas(){return{setData:t=>this.canvasAPI.setData(t),getData:()=>this.canvasAPI.getData(),clear:()=>this.canvasAPI.clear(),undo:()=>this.canvasAPI.undo(),redo:()=>this.canvasAPI.redo(),export:(t="png")=>this.canvasAPI.export(t),save:()=>this.canvasAPI.save(),setZoom:t=>this.canvasAPI.setZoom(t),getSnapshot:()=>this.canvasAPI.getSnapshot(),invoke:(t,...s)=>this.canvasAPI.invoke(t,...s)}}get abilities(){return{set:t=>this.abilityAPI.setAbilities(t),get:()=>this.abilityAPI.getAbilities(),enable:t=>this.abilityAPI.enableAbility(t),disable:t=>this.abilityAPI.disableAbility(t),updateConfig:(t,s)=>this.abilityAPI.updateAbilityConfig(t,s)}}get theme(){return{set:t=>this.themeAPI.setTheme(t),get:()=>this.themeAPI.getCurrentTheme(),updateToken:t=>this.themeAPI.updateToken(t),reset:()=>this.themeAPI.resetTheme()}}get i18n(){return{setLocale:(t,s)=>this.i18nAPI.setLocale(t,s),getLocale:()=>this.i18nAPI.getCurrentLocale(),updateMessages:t=>this.i18nAPI.updateMessages(t),getMessages:()=>this.i18nAPI.getMessages(),getTranslation:t=>this.i18nAPI.getTranslation(t)}}get auth(){return{validateToken:()=>this.authAPI.validateToken(),refreshToken:t=>this.authAPI.refreshToken(t),getTokenInfo:()=>this.authAPI.getTokenInfo()}}get utils(){return{getConnectionStatus:()=>this.bridge.getConnectionStatus(),disconnect:()=>this.bridge.disconnect(),reconnect:async()=>{this.bridge.disconnect(),this.isInitialized=!1,await this.init()},isInitialized:()=>this.isInitialized}}setupEventHandlers(){this.bridge.on("canvas-change",t=>{this.emit(T.CHANGE,t)}),this.bridge.on("canvas-save",t=>{this.emit(T.SAVE,t)}),this.bridge.on("canvas-error",t=>{this.emit(T.ERROR,t)}),this.bridge.on("canvas-selection-changed",t=>{this.emit(T.SELECTION_CHANGED,t)}),this.bridge.on("connected",()=>{console.log("链接建立成功"),this.emit(T.CONNECTED)}),this.bridge.on("disconnected",()=>{console.log("链接断开"),this.emit(T.DISCONNECTED)})}validateConfig(t){if(!t.token)throw new Error("Token is required");if(t.abilities){const s=["text","image","barcode","multiLayout","shape","qrCode"];Object.keys(t.abilities).forEach(r=>{s.includes(r)||console.warn(`Unknown ability: ${r}`)})}}extractOrigin(t){try{return new URL(t).origin}catch{return"*"}}}function ft(e,n){return new ve(e,n)}m.CANVAS_EVENTS=T,m.NiimbotCanvasSDK=ve,m.createCanvas=ft,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})});