@netless/appliance-plugin 1.1.40 → 1.1.42-beta.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.
Files changed (44) hide show
  1. package/README.md +31 -0
  2. package/dist/appliance-plugin.js +1 -1
  3. package/dist/appliance-plugin.mjs +17 -16
  4. package/dist/{bridge-b23MKtwT.mjs → bridge-B-QptMEy.mjs} +1 -1
  5. package/dist/{bridge-DLEmhE7Y.js → bridge-hRl_DY0c.js} +1 -1
  6. package/dist/bridge.js +1 -1
  7. package/dist/bridge.mjs +1 -1
  8. package/dist/component/backgroundImageLoadCoordinator.d.ts +61 -0
  9. package/dist/component/svg/base.d.ts +2 -0
  10. package/dist/component/svg/svgElemt.d.ts +3 -1
  11. package/dist/component/svg/types.d.ts +2 -0
  12. package/dist/component/textEditor/types.d.ts +2 -0
  13. package/dist/core/currentSceneGuard.d.ts +6 -0
  14. package/dist/core/initReadyBarrier.d.ts +8 -0
  15. package/dist/core/mainEngine.d.ts +4 -2
  16. package/dist/core/mainThread/base.d.ts +3 -3
  17. package/dist/core/mainThread/snapshotThread.d.ts +3 -3
  18. package/dist/core/mainThread/subLocalThread.d.ts +1 -1
  19. package/dist/core/mainThread/subServiceThread.d.ts +1 -1
  20. package/dist/fullWorker.js +85 -85
  21. package/dist/{index-rhSRO8Tb.mjs → index-1g93HWeU.mjs} +9106 -8749
  22. package/dist/{index-CDDMgpaL.js → index-B0MSTcdT.js} +1 -1
  23. package/dist/index-BpRy_vjc.js +570 -0
  24. package/dist/index-BtNb2M5H.js +1 -0
  25. package/dist/{index-WifS74pI.mjs → index-BwbqPE3q.mjs} +234 -210
  26. package/dist/{index-pyv2KvXa.mjs → index-C3e6mT0j.mjs} +221 -201
  27. package/dist/{index-BSR23bx5.mjs → index-CCO-qEim.mjs} +1 -1
  28. package/dist/{index-CDbcv4B7.js → index-CgEdhx54.js} +1 -1
  29. package/dist/index-CgJv1Exy.js +570 -0
  30. package/dist/{index-GpA_9BZu.mjs → index-DJS3KHjE.mjs} +12695 -12377
  31. package/dist/{index-C3XOupI-.mjs → index-DUVQmCiI.mjs} +1 -1
  32. package/dist/index-vIt18mo2.js +1 -0
  33. package/dist/plugin/applianceMultiPlugin.d.ts +1 -1
  34. package/dist/plugin/applianceSinglePlugin.d.ts +1 -1
  35. package/dist/plugin/backgroundImageQuery.d.ts +4 -0
  36. package/dist/plugin/baseApplianceManager.d.ts +7 -3
  37. package/dist/plugin/renderingCompatibility.d.ts +2 -1
  38. package/dist/plugin/types.d.ts +35 -2
  39. package/dist/subWorker.js +61 -61
  40. package/package.json +9 -4
  41. package/dist/index-DKaa5HSe.js +0 -1
  42. package/dist/index-DoIyQYzA.js +0 -570
  43. package/dist/index-DwW4gzgA.js +0 -1
  44. package/dist/index-RKd-OVPO.js +0 -570
@@ -1,7 +1,7 @@
1
1
  var pe = Object.defineProperty;
2
2
  var de = (C, t, e) => t in C ? pe(C, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : C[t] = e;
3
3
  var m = (C, t, e) => de(C, typeof t != "symbol" ? t + "" : t, e);
4
- import { D as K, e as W, c as y, r as q, b as g, g as X, t as V, a as h, f as ie, M as ue, h as D, i as Y, j as fe, C as H, k as P, l as me, m as ye, n as ke, o as Se, p as J, q as _, E as N, s as j, u as $, v as we, w as ae, x as ne, T as ee, y as te, z as ve, A as ce, G as le, B as se, F as Te, H as z, V as oe, S as Ie } from "./index-GpA_9BZu.mjs";
4
+ import { D as K, e as W, c as y, r as q, b as g, g as X, t as V, a as h, f as ie, M as ue, h as D, i as Y, j as fe, C as H, k as P, l as me, m as ye, n as ke, o as Se, p as J, q as _, E as N, s as j, u as $, v as we, w as ae, x as ne, T as ee, y as te, z as ve, A as ce, G as le, B as se, F as Te, H as z, V as oe, S as Ie } from "./index-1g93HWeU.mjs";
5
5
  import { cloneDeep as Z, xor as ge, isNumber as G, isEqual as re } from "lodash";
6
6
  import "clipper-lib";
7
7
  import "lineclip";
@@ -0,0 +1 @@
1
+ "use strict";var P=Object.defineProperty;var b=(n,e,t)=>e in n?P(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var c=(n,e,t)=>b(n,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("./index-CgJv1Exy.js"),f=require("lodash");require("clipper-lib");require("lz-string");require("lineclip");require("xss");require("rbush");require("react-dom");require("react");class N{constructor(){c(this,"threadEngine")}registerBackgroundThread(e){return this.threadEngine=e,this}}class L extends N{constructor(){super(...arguments);c(this,"emitEventType",h.EmitEventType.CopyNode)}async consume(t){const{msgType:s,dataType:r,emitEventType:a}=t;if(s===h.EPostMessageType.FullWork&&r===h.EDataType.Local&&a===this.emitEventType)return this.consumeForLocalWorker(t),!0}async consumeForLocalWorker(t){var r;const{workId:s}=t;s&&await((r=this.threadEngine)==null?void 0:r.consumeFull(t))}}class C{constructor(e){c(this,"builders",new Map);this.builders=new Map(e.map(t=>[t,this.build(t)]))}build(e){switch(e){case h.EmitEventType.CopyNode:return new L}}registerForBackgroundThread(e){return this.builders.forEach(t=>{t&&t.registerBackgroundThread(e)}),this}async consumeForBackgroundThread(e){for(const t of this.builders.values())if(await(t==null?void 0:t.consume(e)))return!0;return!1}}async function W(n){const e=n.querySelectorAll("img"),t=Array.from(e).map(a=>{if(!a.crossOrigin&&a.src&&!a.src.startsWith("data:")&&(a.crossOrigin="anonymous",a.complete)){const o=a.src;a.src="",a.src=o}return a.complete&&a.crossOrigin?Promise.resolve():new Promise(o=>{a.onload=()=>{o(void 0)},a.onerror=()=>{o(void 0)}})});return n.querySelectorAll("svg").forEach(a=>{a.querySelectorAll("image").forEach(i=>{i.href&&!i.href.baseVal.startsWith("data:")&&(i.getAttribute("crossorigin")||i.setAttribute("crossorigin","anonymous"),t.push(new Promise(l=>{const d=new Image;d.crossOrigin="anonymous",d.onload=()=>{l(void 0)},d.onerror=()=>{l(void 0)},d.src=i.href.baseVal})))})}),await Promise.all(t)}async function B(n){const s=Date.now();let r=!1;for(;Date.now()-s<5e3;){const a=n.querySelectorAll("path");if(a.length>0&&(r=Array.from(a).some(o=>{const i=o.getAttribute("d")||"";return i!=="M0,0C0,0,0,0,0,0"&&i.length>10}),r))break;await new Promise(o=>setTimeout(o,50))}}async function F(n){const e=n.querySelectorAll("svg");if(!e.length)return;const t=[];for(let s=0;s<e.length;s++){const r=e[s];t.push(B(r))}await Promise.all(t)}async function I(n){if(n.querySelectorAll("svg[data-type='mermaid']").length>0){const s=Date.now();let r=!1;for(;Date.now()-s<5e3&&!r;){const a=n.querySelectorAll("foreignObject");if(a.length>0){let o=!0;for(const i of Array.from(a)){const l=parseFloat(i.getAttribute("width")||"0"),d=parseFloat(i.getAttribute("height")||"0");if(i.querySelector(".mermaid-container")&&(l<50||d<50)){o=!1;break}}if(o){r=!0;break}}else r=!0;await new Promise(o=>setTimeout(o,50))}}}async function A(n,e={}){const{width:t=n.offsetWidth,height:s=n.offsetHeight}=e,r=n.offsetWidth||t,a=n.offsetHeight||s;try{const{loadSvgToImageLib:o,getSvgToImageLib:i}=await Promise.resolve().then(()=>require("./svgToImageLoader-B3gIDAQo.js"));let l=i();if(!l)try{l=await o()}catch(w){return console.error("[loadSvgToImageLib] error: ",w),null}const d=n.style.width,u=n.style.height,k=n.style.display;n.style.width||(n.style.width=`${r}px`),n.style.height||(n.style.height=`${a}px`),(!n.style.display||n.style.display==="none")&&(n.style.display="block");try{await new Promise(p=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{p()})})});const w=await l.toPng(n,{width:r,height:a,quality:1});return n.style.width=d,n.style.height=u,n.style.display=k,new Promise(p=>{const m=new Image;m.crossOrigin="anonymous",m.onload=()=>{p(m)},m.onerror=()=>{p(null)},m.src=w})}catch(w){return n.style.width=d,n.style.height=u,n.style.display=k,console.error("[divToImageElement] error: ",w),null}}catch(o){return console.error("[divToImageElement] error: ",o),null}}class x{constructor(e){c(this,"toolsType",h.EToolsKey.BackgroundSVG);c(this,"vNodes");c(this,"workOptions");c(this,"workId");c(this,"markmapInstance",null);c(this,"isDestroyed",!1);c(this,"element");c(this,"manager");c(this,"scenePath");c(this,"trackBackgroundImageLoad");c(this,"reloadSourceUrl");const{vNodes:t,workId:s,toolsOpt:r,manager:a,scenePath:o,trackBackgroundImageLoad:i=!0}=e;this.workId=s,this.vNodes=t,this.workOptions=r,this.manager=a,this.scenePath=o,this.trackBackgroundImageLoad=i,this.element=this.createElement(),this.manager.fullLayer.appendChild(this.element),this.vNodes.setInfo(this.workId,{workShape:this})}get fullLayer(){return this.manager.fullLayer}get collector(){return this.manager.master.control.collector}async init(){await this.render()}createElement(){const{type:e}=this.workOptions;let t;return e===h.ESVGType.markmap?(t=document.createElementNS("http://www.w3.org/2000/svg","svg"),t.classList.add("svg")):(t=document.createElement("img"),t.classList.add("img")),t.id=this.workId,t.setAttribute("data-id",this.workId),t}async render(e){this.isDestroyed||!this.element||!this.element.parentNode||(this.updateElementPosition(e),await this.updateSvg(e))}isSameSize(e){const{width:t,height:s}=e,{width:r,height:a}=this.workOptions,o=t*this.manager.camera.scale,i=s*this.manager.camera.scale,l=r*this.manager.camera.scale,d=a*this.manager.camera.scale;return o===l&&i===d}isSamePosition(e){const{centerX:t,centerY:s}=e,{centerX:r,centerY:a}=this.workOptions,o=this.manager.getPagePoint(r,a),i=this.manager.getPagePoint(t,s);return f.isEqual(i,o)}isSameZIndex(e){const{zIndex:t}=e,{zIndex:s}=this.workOptions;return t===s}isSameState(e){const{state:t}=e,{state:s}=this.workOptions;return f.isEqual(t,s)}isSameData(e){const{data:t}=e,{data:s}=this.workOptions;return f.isEqual(t,s)}updateElementPosition(e){if(this.isDestroyed||!this.element||!this.fullLayer)return;const{centerX:t,centerY:s,width:r,height:a,zIndex:o}=this.workOptions,i=this.manager.getPagePoint(t,s),l=r*this.manager.camera.scale,d=a*this.manager.camera.scale;(!e||e&&!this.isSameSize(e))&&(this.element.setAttribute("width",`${l}`),this.element.setAttribute("height",`${d}`),this.element.style.width=`${l}px`,this.element.style.height=`${d}px`),(!e||e&&!this.isSamePosition(e))&&(this.element.style.left=`${i.x}px`,this.element.style.top=`${i.y}px`),(!e||e&&!this.isSameZIndex(e))&&(this.element.style.zIndex=(o||0).toString())}async updateSvg(e){const{type:t,state:s}=this.workOptions;if(t===h.ESVGType.markmap){const r=h.getMarkmapRuntimeOrThrow(),{data:a}=this.workOptions;if(this.markmapInstance||(this.markmapInstance=r.createMarkmap(this.element,this.manager.markmapOptions),this.markmapInstance.handleClick=async(l,d)=>{var w,p,m;(w=this.markmapInstance)==null||w.toggleNode(d);const u=this.serializeData((p=this.markmapInstance)==null?void 0:p.state.data);this.setWorkOptions({...this.workOptions,state:u},!1),r.checkNodeHasMermaid(d)&&await r.renderMermaidAfterDOMUpdate(this.element,this.workId),this.scenePath&&this.collector&&((m=this.collector)==null||m.dispatch({type:h.EPostMessageType.UpdateNode,workId:this.workId,opt:this.workOptions,isSync:!0,viewId:this.manager.viewId,scenePath:this.scenePath}))}),e&&this.isSameState(e)&&this.isSameSize(e)&&this.isSameData(e))return;const o=r.transform(this.workId,a);let{root:i}=o;a&&r.hasMermaidCodeBlock(a)&&(i=r.injectMermaidHtml(i,a,this.workId));try{s&&Array.isArray(s)&&this.transformState(s,i),await this.markmapInstance.setData(i),!this.isDestroyed&&this.element&&this.fullLayer&&this.markmapInstance&&(window.markmapInstance=this.markmapInstance,a&&r.hasMermaidCodeBlock(a)&&await r.renderMermaidAfterDOMUpdate(this.element,this.workId),await this.fit(!e||e&&!this.isSameData(e)))}catch(l){console.error("[updateSvg] error: ",l)}}else{const{src:r,crossOrigin:a}=this.workOptions,o=this.reloadSourceUrl??r;if(this.element.crossOrigin=f.isString(a)?a:"anonymous",!this.trackBackgroundImageLoad){this.element.src=o,await new Promise((i,l)=>{this.element.onload=()=>i(),this.element.onerror=()=>l()});return}await this.manager.master.control.backgroundImageLoadCoordinator.load({viewId:this.manager.viewId,scenePath:this.scenePath,resourceId:this.workId,src:o,image:this.element,isActive:()=>!this.isDestroyed&&this.manager.master.control.viewContainerManager.getCurScenePath(this.manager.viewId)===this.scenePath,onReloadUrl:i=>{this.reloadSourceUrl=i}})}}async fit(e=!0){var t;if(!this.isDestroyed&&this.element&&this.fullLayer&&this.markmapInstance){const s=h.getMarkmapRuntimeOrThrow();e&&this.element&&await s.waitForImagesInForeignObjects(this.element),await((t=this.markmapInstance)==null?void 0:t.fit()),this.element&&s.isSafari()&&s.hasMermaidSvg(this.element)&&(await I(this.element),await s.transformMermaidSvgToMarkmapSvg(this.element))}}serializeData(e){var r;const t=[e],s=[];for(;t.length>0;){const a=t.pop();a&&(a!=null&&a.children&&t.push(...a.children),s.push(((r=a==null?void 0:a.payload)==null?void 0:r.fold)||0))}return s}transformState(e,t){const s=[t];for(;s.length>0;){const r=s.pop();r&&(r!=null&&r.children&&s.push(...r.children),r.payload?r.payload.fold=e.shift():e.shift())}}async updateCamera(){this.updateElementPosition(),await this.fit(!1)}async setWorkOptions(e,t=!0){if(!f.isEqual(this.workOptions,e)){const s=f.clone(this.workOptions),r="src"in this.workOptions?this.workOptions.src:void 0,a="src"in e?e.src:void 0;r!==a&&(this.reloadSourceUrl=void 0),this.workOptions=e,t&&await this.render(s)}}destroy(){this.isDestroyed=!0,this.reloadSourceUrl=void 0,this.trackBackgroundImageLoad&&this.manager.master.control.backgroundImageLoadCoordinator.cancelResource(this.manager.viewId,this.scenePath,this.workId),this.element.remove()}getRectFromLayer(){const e=this.element.getBoundingClientRect();return{x:e.x,y:e.y,w:e.width,h:e.height}}}function M(n){const{toolsType:e,...t}=n;switch(e){case h.EToolsKey.BackgroundSVG:return new x(t);default:return}}class O{constructor(e){c(this,"viewId");c(this,"fullLayer");c(this,"curNodeMap");this.viewId=e,this.curNodeMap=new h.ObserverMap}init(e){this.fullLayer=e}get(e){return this.curNodeMap.get(e)}setInfo(e,t){const s=this.curNodeMap.get(e)||{name:e,workShape:t.workShape};t.workShape&&(s.workShape=t.workShape),this.curNodeMap.set(e,s)}getNodeRectFormShape(e){const t=this.curNodeMap.get(e);if(t&&t.workShape)return t.workShape.getRectFromLayer()}delete(e){const t=this.curNodeMap.get(e);t&&t.workShape.destroy(),this.curNodeMap.delete(e)}clear(){for(const e of this.curNodeMap.values())e.workShape.destroy();this.curNodeMap.clear()}}class q{constructor(e,t){c(this,"opt");c(this,"viewId");c(this,"fullLayer");c(this,"vNodes");c(this,"master");c(this,"cameraOpt");c(this,"methodBuilder");c(this,"updateCamera",f.throttle(async e=>{const{cameraOpt:t}=e;t&&!f.isEqual(this.cameraOpt,t)&&await this.setCameraOpt(t)},100));this.viewId=e,this.opt=t,this.master=t.master,this.fullLayer=t.container,this.methodBuilder=new C([h.EmitEventType.CopyNode]).registerForBackgroundThread(this),this.vNodes=new O(e),this.vNodes.init(this.fullLayer)}get camera(){return this.cameraOpt||{scale:1,centerX:0,centerY:0,width:0,height:0}}get view(){var e;return(e=this.master.control.viewContainerManager.getView(this.viewId))==null?void 0:e.viewData}get markmapOptions(){return this.master.control.pluginOptions.extras.markmap.options}getPagePoint(e,t){const{scale:s,centerX:r,centerY:a,width:o,height:i}=this.camera;return{x:(e-r)*s+o/2,y:(t-a)*s+i/2}}async setCameraOpt(e){this.cameraOpt=e;for(const t of this.vNodes.curNodeMap.values()){const{workShape:s}=t;s&&await s.updateCamera()}}clearAll(){this.vNodes.clear()}canUseFullLayer(e){return e===h.EToolsKey.BackgroundSVG}async consumeFull(e){const{toolsType:t,opt:s,workId:r,scenePath:a}=e;if(r!=null&&r.toString()&&t&&this.canUseFullLayer(t))switch(t){case h.EToolsKey.BackgroundSVG:await this.setFullWork({toolsType:t,opt:s,workId:r,scenePath:a});break}}async setFullWork(e){const{workId:t,opt:s,toolsType:r,scenePath:a}=e;if(t&&s&&r&&a){const o=t.toString();let i;const l=this.vNodes.get(o);return!l||!l.workShape?(i=this.createWorkShapeNode({toolsOpt:s,toolsType:h.EToolsKey.BackgroundSVG,workId:o,scenePath:a}),i&&await i.init()):(i=l.workShape,await i.setWorkOptions(s)),i}}createWorkShapeNode(e){return M({...e,vNodes:this.vNodes,manager:this})}removeWork(e){const{workId:t}=e,s=t==null?void 0:t.toString();s&&this.removeNode(s)}removeNode(e){this.vNodes.delete(e)}async on(e){if(!await this.methodBuilder.consumeForBackgroundThread(e)){const{msgType:t,toolsType:s}=e;switch(t){case h.EPostMessageType.Destroy:{this.destroy();break}case h.EPostMessageType.Clear:{this.clearAll();break}case h.EPostMessageType.UpdateCamera:{this.updateCamera(e);break}case h.EPostMessageType.UpdateTools:{this.toggleFullLayer(s===h.EToolsKey.Clicker);break}case h.EPostMessageType.BackgroundSVGUpdate:case h.EPostMessageType.UpdateNode:case h.EPostMessageType.FullWork:{s&&this.canUseFullLayer(s)&&await this.consumeFull(e);break}case h.EPostMessageType.BackgroundSVGDelete:{this.removeWork(e);break}}}}toggleFullLayer(e){this.fullLayer.classList.toggle("appliance-plugin-background-svg-active",e)}destroy(){this.vNodes.clear()}}class V{constructor(e,t){c(this,"viewId");c(this,"fullLayer");c(this,"master");c(this,"vNodes");c(this,"cameraOpt");c(this,"opt");c(this,"workShapes",new Map);this.viewId=e,this.opt=t,this.master=t.master,this.fullLayer=t.container,this.vNodes=new O(e),this.vNodes.init(this.fullLayer)}get camera(){return this.cameraOpt||{scale:1,centerX:0,centerY:0,width:0,height:0}}get view(){var e;return(e=this.master.control.viewContainerManager.getView(this.viewId))==null?void 0:e.viewData}get markmapOptions(){return this.master.control.pluginOptions.extras.markmap.options}createOffscreenCanvas(e){const{width:t,height:s}=e.canvasOpt,r=new OffscreenCanvas(e.canvasOpt.width,e.canvasOpt.height);r.width=t,r.height=s}async setCameraOpt(e){this.cameraOpt=e;for(const t of this.vNodes.curNodeMap.values()){const{workShape:s}=t;s&&await s.updateCamera()}}getPagePoint(e,t){const{scale:s,centerX:r,centerY:a,width:o,height:i}=this.camera;return{x:(e-r)*s+o/2,y:(t-a)*s+i/2}}async getSnapshot(e){const{scenePath:t,scenes:s,cameraOpt:r}=e;if(t&&s&&r){await this.setCameraOpt(r);for(const[a,o]of Object.entries(s))if(o!=null&&o.type&&(o==null?void 0:o.toolsType)===h.EToolsKey.BackgroundSVG)switch(o==null?void 0:o.type){case h.EPostMessageType.UpdateNode:case h.EPostMessageType.FullWork:{const{opt:i}=o,l={...o,opt:i,workId:a,msgType:h.EPostMessageType.FullWork,dataType:h.EDataType.Service,viewId:this.viewId,scenePath:t};await this.runFullWork(l);break}}try{if(t){await I(this.fullLayer),await W(this.fullLayer),await F(this.fullLayer);const a=await A(this.fullLayer);a&&this.opt.post({sp:[{type:h.EPostMessageType.Snapshot,scenePath:t,imageElement:a,viewId:this.viewId,index:1}]})}}catch(a){const o=a&&a instanceof Error?a.message:a==null?void 0:a.toString();this.opt.post({sp:[{type:h.EPostMessageType.ReportError,reportString:`[SnapshotThreadImpl] getSnapshotRender error: ${o}`}]})}}}createWorkShapeNode(e){return M({...e,vNodes:this.vNodes,manager:this,trackBackgroundImageLoad:!1})}async setFullWork(e){const{workId:t,opt:s,toolsType:r,scenePath:a}=e;if(t&&s&&r&&a){const o=t.toString();let i;const l=this.vNodes.get(o);return!l||!l.workShape?(i=this.createWorkShapeNode({toolsOpt:s,toolsType:h.EToolsKey.BackgroundSVG,workId:o,scenePath:a}),i&&await i.init()):(i=l.workShape,await i.setWorkOptions(s)),i}}async runFullWork(e){const{toolsType:t,opt:s,workId:r,scenePath:a}=e;await this.setFullWork({toolsType:t,opt:s,workId:r,scenePath:a})}destroy(){this.fullLayer.innerHTML="",this.fullLayer.style.width="",this.fullLayer.style.height=""}}class U{constructor(e){c(this,"backgroundThreadMap",new Map);c(this,"snapshotThread");c(this,"master");c(this,"post",e=>{const{sp:t}=e;t&&this.master.collectorSyncData(t)});this.master=e,this.backgroundThreadMap=new Map}createBackgroundThread(e,t){return new q(e,t)}createSnapshotThread(e,t){return new V(e,t)}async consume(e){var t,s,r,a,o,i;for(const l of e.values()){const{msgType:d,viewId:u,layerOpt:k,offscreenCanvasOpt:w,cameraOpt:p,tasksqueue:m}=l;if(d===h.EPostMessageType.Console){console.log(this);continue}if(d===h.EPostMessageType.Init){const g=(t=this.master.control.viewContainerManager.getView(u))==null?void 0:t.displayer,v=(s=g==null?void 0:g.backgroundContainerRef)==null?void 0:s.current;if(g&&v&&k&&w){const y=this.backgroundThreadMap.get(u);y==null||y.destroy();const T=this.createBackgroundThread(u,{displayer:g,container:v,layerOpt:k,master:this.master,canvasOpt:w,post:this.post});this.backgroundThreadMap.set(u,T),T&&p&&await T.setCameraOpt(p)}continue}if(d===h.EPostMessageType.Snapshot){const g=(r=this.master.control.viewContainerManager.getView(u))==null?void 0:r.displayer,y=(o=((a=this.master.control.viewContainerManager.mainView)==null?void 0:a.displayer).backgroundSnapshotContainerRef)==null?void 0:o.current;if(g&&y&&p){(i=this.snapshotThread)==null||i.destroy(),y.style.width=`${p.width}px`,y.style.height=`${p.height}px`;const T={...h.ViewContainerManager.defaultLayerOpt,offscreen:!1,width:p.width,height:p.height},E={...h.ViewContainerManager.defaultScreenCanvasOpt,width:p.width,height:p.height};this.snapshotThread=this.createSnapshotThread(u,{displayer:g,container:y,layerOpt:T,master:this.master,canvasOpt:E,post:this.post}),await this.snapshotThread.getSnapshot(l),this.snapshotThread.destroy(),this.snapshotThread=void 0;continue}}if(d===h.EPostMessageType.TasksQueue&&(m!=null&&m.size)){for(const[g,v]of this.backgroundThreadMap.entries()){const y=m.get(g);y&&await v.on(y)}continue}if(u===h.Storage_ViewId_ALL){for(const g of this.backgroundThreadMap.values())await g.on(l);d===h.EPostMessageType.Destroy&&this.backgroundThreadMap.clear();continue}const S=this.backgroundThreadMap.get(u);S&&(await S.on(l),d===h.EPostMessageType.Destroy&&this.backgroundThreadMap.delete(u))}}async consumeTargetOne(e,t){const s=this.backgroundThreadMap.get(e);s&&await s.on(t)}destroy(){var e;(e=this.snapshotThread)==null||e.destroy(),this.snapshotThread=void 0;for(const t of this.backgroundThreadMap.values())t.destroy();this.backgroundThreadMap.clear()}}exports.BackgroundThreadManagerImpl=U;
@@ -12,7 +12,7 @@ export declare class ApplianceMultiPlugin extends InvisiblePlugin<AppliancePlugi
12
12
  static getInstance(remake: WindowManager, adaptor: ApplianceAdaptor): Promise<AppliancePluginInstance>;
13
13
  static onCreate(plugin: InvisiblePlugin<AppliancePluginAttributes, any>): void;
14
14
  static createApplianceMultiPlugin(d: Room, kind: string): Promise<ApplianceMultiPlugin>;
15
- static createCurrentManager: (remake: WindowManager, options: RequiredAppliancePluginOptions, plugin: ApplianceMultiPlugin, onInitLoadingChange?: ApplianceAdaptor["onInitLoadingChange"]) => void;
15
+ static createCurrentManager: (remake: WindowManager, options: RequiredAppliancePluginOptions, plugin: ApplianceMultiPlugin, callbacks?: ApplianceAdaptor["callbacks"]) => void;
16
16
  private get isReplay();
17
17
  private get callbackName();
18
18
  init(displayer: Displayer): void;
@@ -12,7 +12,7 @@ export declare class ApplianceSinglePlugin extends InvisiblePlugin<AppliancePlug
12
12
  static getInstance(remake: Player | Room, adaptor: ApplianceAdaptor): Promise<AppliancePluginInstance>;
13
13
  static onCreate(plugin: InvisiblePlugin<AppliancePluginAttributes, any>): void;
14
14
  static createAppliancePlugin(d: Room, kind: string): Promise<ApplianceSinglePlugin>;
15
- static createCurrentManager: (displayer: Displayer, options: RequiredAppliancePluginOptions, plugin?: ApplianceSinglePlugin, onInitLoadingChange?: ApplianceAdaptor["onInitLoadingChange"]) => void;
15
+ static createCurrentManager: (displayer: Displayer, options: RequiredAppliancePluginOptions, plugin?: ApplianceSinglePlugin, callbacks?: ApplianceAdaptor["callbacks"]) => void;
16
16
  /**
17
17
  * 房间实例化时,将当前实例对displayer外部API的添加内部处理逻辑;
18
18
  * @param displayer
@@ -0,0 +1,4 @@
1
+ import type { ISerializableStorageViewData } from "../collector/types";
2
+ import type { HasBackgroundImageParams } from "./types";
3
+ /** Returns whether the appliance provider contains the requested background. */
4
+ export declare function hasApplianceBackgroundImage(storage: ISerializableStorageViewData | undefined, params: HasBackgroundImageParams): boolean;
@@ -1,5 +1,5 @@
1
1
  import EventEmitter2 from "eventemitter2";
2
- import { EStrokeType, MemberState, AppliancePluginLike, ApplianceInitLoadingChangeInfo, ApplianceFontFaceLoadState, ApplianceFontFaceRenderState, ApplianceRefreshRenderState } from "./types";
2
+ import { EStrokeType, MemberState, AppliancePluginLike, ApplianceInitLoadingChangeInfo, ApplianceFontFaceLoadState, ApplianceFontFaceRenderState, ApplianceRefreshRenderState, CallbacksFun } from "./types";
3
3
  import { Collector, ViewId } from "../collector";
4
4
  import { RoomMemberManager } from "../members";
5
5
  import { TextEditorManager } from "../component/textEditor";
@@ -17,14 +17,17 @@ import { RenderCotrolImple } from "../core/renderCotrol";
17
17
  import { MiniMapManagerImpl } from "../component/miniMap/manager";
18
18
  import { PluginManager, Plugin } from "../core/plugin";
19
19
  import { SelectorApiManager } from "./selectorApi";
20
+ import { BackgroundImageLoadCoordinator } from "../component/backgroundImageLoadCoordinator";
21
+ import type { ReloadBackgroundImageParams, ReloadBackgroundImageResult } from "../component/backgroundImageLoadCoordinator";
20
22
  export interface BaseApplianceManagerProps {
21
23
  displayer: Displayer<DisplayerCallbacks>;
22
24
  plugin?: AppliancePluginLike;
23
25
  options: RequiredAppliancePluginOptions;
24
- onInitLoadingChange?: (info: ApplianceInitLoadingChangeInfo) => void;
26
+ callbacks?: CallbacksFun;
25
27
  }
26
28
  /** 插件管理器 */
27
29
  export declare abstract class BaseApplianceManager {
30
+ readonly backgroundImageLoadCoordinator: BackgroundImageLoadCoordinator;
28
31
  private toolChangePending;
29
32
  private toolChangePendingTimer?;
30
33
  private pendingSceneChecks;
@@ -64,7 +67,7 @@ export declare abstract class BaseApplianceManager {
64
67
  readonly renderControl: RenderCotrolImple;
65
68
  readonly miniMapManager?: MiniMapManagerImpl;
66
69
  readonly pluginManager?: PluginManager;
67
- readonly onInitLoadingChange?: (info: ApplianceInitLoadingChangeInfo) => void;
70
+ readonly callbacks?: CallbacksFun;
68
71
  /** WB-429: selector 公开 API / 事件实现入口 */
69
72
  selectorApi?: SelectorApiManager;
70
73
  /** WB-429: selector API 事件派发用,指向 BaseApplianceManager.PublicMsgEmitter */
@@ -198,6 +201,7 @@ export declare abstract class BaseApplianceManager {
198
201
  destroyMiniMap(viewId: string): Promise<void>;
199
202
  insertIconify(viewId: string, iconifyInfo: IconifyInformation): void;
200
203
  insertBackgroundSVG(viewId: string, svgInfo: ISVGUrlInformation): void;
204
+ reloadBackgroundImage(params: ReloadBackgroundImageParams): ReloadBackgroundImageResult;
201
205
  insertBackgroundMarkMap(viewId: string, svgInfo: ISVGMarkmapInformation): Promise<MarkmapId | undefined>;
202
206
  updateBackgroundMarkMap(viewId: string, markmapId: string, svgInfo: ISVGMarkmapInformation): void;
203
207
  usePlugin(plugin: Plugin): void | undefined;
@@ -32,12 +32,13 @@ export type RenderingCompatibilityDecision = {
32
32
  effectiveImageBitmapFeatureLevel?: WorkerImageBitmapFeatureBlacklistLevel;
33
33
  issues: string[];
34
34
  };
35
- type BlacklistKind = "renderMode" | "canvasContext" | "maskTextureFormat" | "maskTextureUpload" | "imageBitmapFeature";
35
+ type BlacklistKind = "renderMode" | "canvasContext" | "maskTextureFormat" | "maskTextureUpload" | "imageBitmapFeature" | "fontFaceFallback";
36
36
  export declare function normalizeVersion(value: string): string | undefined;
37
37
  export declare function compareVersions(left: string, right: string): number;
38
38
  export declare function detectRenderingRuntime(userAgent?: string): RenderingRuntime | undefined;
39
39
  export declare function resolveVersionBlacklistLevel(currentVersion: string, rules: VersionWorkerBlacklist | undefined, kind: BlacklistKind, issues?: string[]): number | undefined;
40
40
  export declare function mergeWorkerBlacklists(builtin: WorkerBlacklistByRuntime | undefined, injected: WorkerBlacklistByRuntime | undefined, kind: BlacklistKind): WorkerBlacklistByRuntime;
41
+ export declare function isFontFaceFallbackBlacklisted(blacklist: WorkerBlacklistByRuntime | undefined, userAgent?: string): boolean;
41
42
  export declare function detectRenderCapabilities(workerUrl?: boolean): RenderCapabilities;
42
43
  export declare function resolveRenderingCompatibility(input: {
43
44
  useWorker: "auto" | "mainThread";
@@ -15,6 +15,19 @@ import type { TextEditorInfo, FontWeightType, FontStyleType, TextAlignType, Vert
15
15
  import type { IMarkmapOptions } from "../component/svg/markmap-runtime";
16
16
  import type { AutoShapeKind, AutoShapeMetrics } from "../core/autoShape/types";
17
17
  import type { ShapeOptType } from "../displayer/types";
18
+ import type { BackgroundImageLoadEvent, BackgroundImageLoadOptions, BackgroundImageSource, ReloadBackgroundImageParams, ReloadBackgroundImageResult } from "../component/backgroundImageLoadCoordinator";
19
+ export type { BackgroundImageLoadEvent, BackgroundImageLoadOptions, BackgroundImageSource, ReloadBackgroundImageParams, ReloadBackgroundImageResult, };
20
+ export type BackgroundImageQuerySource = "appliance" | "whiteSdk";
21
+ export interface HasBackgroundImageParams {
22
+ /** Whiteboard view containing the scene. */
23
+ viewId: string;
24
+ /** Exact scene path to query. */
25
+ scenePath: string;
26
+ /** Exact background image URL to match. */
27
+ imageUrl: string;
28
+ /** Providers included in the aggregate query. */
29
+ sources: readonly BackgroundImageQuerySource[];
30
+ }
18
31
  export type { Room, ImageInformation, Point, Size, Rectangle, RoomMember, RoomState, Player, HotKeys, Camera, Displayer, DisplayerCallbacks, CameraState, View, Cursor, CursorAdapter, RenderEngine, _MemberState, };
19
32
  export declare enum ApplianceNames {
20
33
  /**
@@ -146,13 +159,18 @@ export type ApplianceFontFaceRenderState = {
146
159
  export type ApplianceRefreshRenderState = {
147
160
  status: "success" | "error";
148
161
  };
162
+ /** Runtime callbacks. These are deliberately outside options/extras so options remain JSON-serializable. */
163
+ export type CallbacksFun = {
164
+ onInitLoadingChange?: (info: ApplianceInitLoadingChangeInfo) => void;
165
+ onBackgroundImageLoadEvent?: (event: BackgroundImageLoadEvent) => void;
166
+ };
149
167
  export type ApplianceAdaptor = {
150
168
  options: AppliancePluginOptions;
151
169
  logger?: Logger;
152
170
  cursorAdapter?: CursorAdapter;
153
- onInitLoadingChange?: (info: ApplianceInitLoadingChangeInfo) => void;
171
+ callbacks?: CallbacksFun;
154
172
  };
155
- export type canBindMethodType = keyof Omit<AppliancePluginInstance, "displayer" | "windowManager" | "disableDeviceInputs" | "disableEraseImage" | "disableCameraTransform" | "injectMethodToObject" | "callbacksOn" | "callbacksOnce" | "callbacksOff" | "_injectTargetObject" | "createMiniMap" | "destroyMiniMap" | "filterRenderByUid" | "cancelFilterRender" | "addListener" | "removeListener" | "usePlugin" | "stopDraw" | "setViewLocalScenePathChange" | "getElements" | "hasElements" | "blurText" | "insertMarkmap" | "updateMarkmap" | "insertBackgroundImage" | "getSelectedElements" | "updateSelectedElements" | "copySelectedElements" | "deleteSelectedElements" | "getFloatbarContainer" | "getViewOffsetToContainer">;
173
+ export type canBindMethodType = keyof Omit<AppliancePluginInstance, "displayer" | "windowManager" | "disableDeviceInputs" | "disableEraseImage" | "disableCameraTransform" | "injectMethodToObject" | "callbacksOn" | "callbacksOnce" | "callbacksOff" | "_injectTargetObject" | "createMiniMap" | "destroyMiniMap" | "filterRenderByUid" | "cancelFilterRender" | "addListener" | "removeListener" | "usePlugin" | "stopDraw" | "setViewLocalScenePathChange" | "getElements" | "hasElements" | "hasBackgroundImage" | "blurText" | "insertMarkmap" | "updateMarkmap" | "insertBackgroundImage" | "getSelectedElements" | "updateSelectedElements" | "copySelectedElements" | "deleteSelectedElements" | "getFloatbarContainer" | "getViewOffsetToContainer">;
156
174
  export interface AppliancePluginInstance {
157
175
  readonly displayer: Displayer;
158
176
  readonly currentManager?: ApplianceManagerLike;
@@ -308,6 +326,11 @@ export interface AppliancePluginInstance {
308
326
  * @returns 所有元素
309
327
  */
310
328
  getElements(scenePath?: string, filter?: (toolsType: EToolsKey) => boolean): BaseCollectorReducerAction[];
329
+ /**
330
+ * 判断指定 view 和场景中是否存在 URL 完全匹配的背景图。
331
+ * appliance 实现只在 sources 包含 `appliance` 时参与查询。
332
+ */
333
+ hasBackgroundImage(params: HasBackgroundImageParams): boolean;
311
334
  /** 停止Draw事件 */
312
335
  stopDraw(viewId: string): Promise<void>;
313
336
  /** 加载自定义字体,不阻塞插件初始化 */
@@ -328,6 +351,7 @@ export interface AppliancePluginInstance {
328
351
  updateMarkmap(viewId: string, markmapId: MarkmapId, markdownInfo: ISVGMarkmapInformation): Promise<void>;
329
352
  /** 插入背景图片 */
330
353
  insertBackgroundImage(viewId: string, imageInfo: ISVGUrlInformation): void;
354
+ reloadBackgroundImage(params: ReloadBackgroundImageParams): Promise<ReloadBackgroundImageResult>;
331
355
  /**
332
356
  * 获取当前 selector 选中元素的快照。
333
357
  * @param viewId 多白板下白板ID, 主白板ID为 `mainView`, 其他白板ID为 addApp() return 的 appID。省略时取当前 focuedView / mainView。
@@ -402,6 +426,9 @@ export declare enum WorkerMaskTextureUploadBlacklistLevel {
402
426
  export declare enum WorkerImageBitmapFeatureBlacklistLevel {
403
427
  DirtyRect = 1
404
428
  }
429
+ export declare enum FontFaceFallbackBlacklistLevel {
430
+ RefreshTextRender = 1
431
+ }
405
432
  export type VersionWorkerBlacklist = Record<string, number>;
406
433
  export type WorkerBlacklistByRuntime = {
407
434
  androidWebView?: VersionWorkerBlacklist;
@@ -432,6 +459,8 @@ export type ExtrasOptions = {
432
459
  workerMaskTextureUploadBlacklist?: WorkerBlacklistByRuntime;
433
460
  /** API 可用但 ImageBitmap crop 行为异常的运行时版本 */
434
461
  workerImageBitmapFeatureBlacklist?: WorkerBlacklistByRuntime;
462
+ /** 按运行时版本启用字体加载失败后的文本补绘兜底 */
463
+ fontFaceFallbackBlacklist?: WorkerBlacklistByRuntime;
435
464
  /** 是否使用背景Svg功能, 默认值为 ``false`` */
436
465
  useBackgroundThread?: boolean;
437
466
  /** 同步数据配置项 */
@@ -464,6 +493,8 @@ export type ExtrasOptions = {
464
493
  markmap?: MarkmapOpt;
465
494
  /** 覆盖 selector DOM 的内联样式 */
466
495
  overwriteSelectorStyles?: SelectorStyleOverrides;
496
+ /** 可见背景图片的超时与重试策略。 */
497
+ backgroundImageLoadOptions?: BackgroundImageLoadOptions;
467
498
  };
468
499
  export type SelectorStyleOverrides = {
469
500
  /** `.appliance-plugin-highlight-box` 外框样式 */
@@ -542,6 +573,7 @@ export type RequiredExtrasOptions = {
542
573
  workerMaskTextureFormatBlacklist: WorkerBlacklistByRuntime;
543
574
  workerMaskTextureUploadBlacklist: WorkerBlacklistByRuntime;
544
575
  workerImageBitmapFeatureBlacklist: WorkerBlacklistByRuntime;
576
+ fontFaceFallbackBlacklist: WorkerBlacklistByRuntime;
545
577
  useBackgroundThread: Required<boolean>;
546
578
  syncOpt: Required<SyncOpt>;
547
579
  syncLogger: Required<SyncLoggerOpt>;
@@ -558,6 +590,7 @@ export type RequiredExtrasOptions = {
558
590
  undoRedo: Required<UndoRedoOpt>;
559
591
  markmap: Required<MarkmapOpt>;
560
592
  overwriteSelectorStyles: SelectorStyleOverrides;
593
+ backgroundImageLoadOptions: Required<BackgroundImageLoadOptions>;
561
594
  };
562
595
  export type RequiredAppliancePluginOptions = {
563
596
  cdn: CdnOpt;