diff --git a/manifest-beta.json b/manifest-beta.json index 028824d..ba76b84 100644 --- a/manifest-beta.json +++ b/manifest-beta.json @@ -1,7 +1,7 @@ { "id": "obsidian-excalidraw-plugin", "name": "Excalidraw", - "version": "2.8.1", + "version": "2.8.2-beta-1", "minAppVersion": "1.1.6", "description": "An Obsidian plugin to edit and view Excalidraw drawings", "author": "Zsolt Viczian", diff --git a/package.json b/package.json index b3ce8aa..04fc574 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "license": "MIT", "dependencies": { "@popperjs/core": "^2.11.8", - "@zsviczian/excalidraw": "0.17.6-29", + "@zsviczian/excalidraw": "0.17.6-30", "chroma-js": "^2.4.2", "clsx": "^2.0.0", "@zsviczian/colormaster": "^1.2.2", diff --git a/src/shared/Workers/compression-worker.ts b/src/shared/Workers/compression-worker.ts index bcdcf96..4e8c9ce 100644 --- a/src/shared/Workers/compression-worker.ts +++ b/src/shared/Workers/compression-worker.ts @@ -11,7 +11,7 @@ function createWorkerBlob(jsCode:string) { const workerCode = ` var LZString=function(){var r=String.fromCharCode,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$",e={};function t(r,o){if(!e[r]){e[r]={};for(var n=0;n>>8,n[2*e+1]=s%256}return n},decompressFromUint8Array:function(o){if(null==o)return i.decompress(o);for(var n=new Array(o.length/2),e=0,t=n.length;e>=1}else{for(t=1,e=0;e>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[c]}else for(t=s[c],e=0;e>=1;0==--l&&(l=Math.pow(2,h),h++),s[p]=f++,c=String(a)}if(""!==c){if(Object.prototype.hasOwnProperty.call(u,c)){if(c.charCodeAt(0)<256){for(e=0;e>=1}else{for(t=1,e=0;e>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[c]}else for(t=s[c],e=0;e>=1;0==--l&&(l=Math.pow(2,h),h++)}for(t=2,e=0;e>=1;for(;;){if(m<<=1,v==o-1){d.push(n(m));break}v++}return d.join("")},decompress:function(r){return null==r?"":""==r?null:i._decompress(r.length,32768,function(o){return r.charCodeAt(o)})},_decompress:function(o,n,e){var t,i,s,u,a,p,c,l=[],f=4,h=4,d=3,m="",v=[],g={val:e(0),position:n,index:1};for(t=0;t<3;t+=1)l[t]=t;for(s=0,a=Math.pow(2,2),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;switch(s){case 0:for(s=0,a=Math.pow(2,8),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;c=r(s);break;case 1:for(s=0,a=Math.pow(2,16),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;c=r(s);break;case 2:return""}for(l[3]=c,i=c,v.push(c);;){if(g.index>o)return"";for(s=0,a=Math.pow(2,d),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;switch(c=s){case 0:for(s=0,a=Math.pow(2,8),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;l[h++]=r(s),c=h-1,f--;break;case 1:for(s=0,a=Math.pow(2,16),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;l[h++]=r(s),c=h-1,f--;break;case 2:return v.join("")}if(0==f&&(f=Math.pow(2,d),d++),l[c])m=l[c];else{if(c!==h)return null;m=i+i.charAt(0)}v.push(m),l[h++]=i+m.charAt(0),i=m,0==--f&&(f=Math.pow(2,d),d++)}}};return i}();"function"==typeof define&&define.amd?define(function(){return LZString}):"undefined"!=typeof module&&null!=module?module.exports=LZString:"undefined"!=typeof angular&&null!=angular&&angular.module("LZString",[]).factory("LZString",function(){return LZString}); self.onmessage = function(e) { - const { data, action } = e.data; + const { data, action, messageId } = e.data; try { switch (action) { case 'compress': @@ -22,7 +22,7 @@ self.onmessage = function(e) { for (let i = 0; i < compressed.length; i += chunkSize) { result += compressed.slice(i, i + chunkSize) + '\\n\\n'; } - self.postMessage({ compressed: result.trim() }); + self.postMessage({ messageId, compressed: result.trim() }); break; case 'decompress': if (!data) throw new Error("No input string provided for decompression."); @@ -35,14 +35,13 @@ self.onmessage = function(e) { } } const decompressed = LZString.decompressFromBase64(cleanedData); - self.postMessage({ decompressed }); + self.postMessage({ messageId, decompressed }); break; default: throw new Error("Unknown action."); } } catch (error) { - // Post the error message back to the main thread - self.postMessage({ error: error.message }); + self.postMessage({ messageId, error: error.message }); } }; `; @@ -55,27 +54,48 @@ export function initCompressionWorker() { } } -export async function runCompressionWorker(data:string, action: 'compress' | 'decompress'): Promise { +let messageCounter = 0; +const pendingOperations = new Map void, + reject: (reason: Error) => void +}>(); + +export async function runCompressionWorker(data: string, action: 'compress' | 'decompress'): Promise { + const messageId = messageCounter++; + return new Promise((resolve, reject) => { - worker.onmessage = function(e) { - const { compressed, decompressed, error } = e.data; - - if (error) { - reject(new Error(error)); - } else if (compressed || decompressed) { - resolve(compressed || decompressed); - } else { - reject(new Error('Unexpected response from worker')); - } - }; + // Store the promise handlers + pendingOperations.set(messageId, { resolve, reject }); - // Set up the worker's error handler - worker.onerror = function(error) { - reject(new Error(error.message)); - }; + // Set up worker message handler if not already set + if (!worker.onmessage) { + worker.onmessage = function(e) { + const { messageId, compressed, decompressed, error } = e.data; + const handlers = pendingOperations.get(messageId); + + if (handlers) { + if (error) { + handlers.reject(new Error(error)); + } else if (compressed || decompressed) { + handlers.resolve(compressed || decompressed); + } else { + handlers.reject(new Error('Unexpected response from worker')); + } + pendingOperations.delete(messageId); + } + }; - // Post the message to the worker - worker.postMessage({ data, action }); + worker.onerror = function(error) { + // Handle any pending operations in case of worker error + for (const [id, handlers] of pendingOperations) { + handlers.reject(new Error(error.message)); + pendingOperations.delete(id); + } + }; + } + + // Post message with ID + worker.postMessage({ messageId, data, action }); }); }