@virtualdisplay.io/client 4.0.0-alpha.1 → 4.0.0-alpha.3
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/CHANGELOG.md +12 -0
- package/dist/src/attributes/attribute.d.ts +38 -0
- package/dist/src/attributes/attribute.d.ts.map +1 -0
- package/dist/src/attributes/attributes.d.ts +43 -0
- package/dist/src/attributes/attributes.d.ts.map +1 -0
- package/dist/src/attributes/selections.d.ts +16 -0
- package/dist/src/attributes/selections.d.ts.map +1 -0
- package/dist/src/attributes/value.d.ts +13 -0
- package/dist/src/attributes/value.d.ts.map +1 -0
- package/dist/src/camera/camera.d.ts +40 -0
- package/dist/src/camera/camera.d.ts.map +1 -0
- package/dist/src/camera/index.d.ts +4 -0
- package/dist/src/camera/index.d.ts.map +1 -0
- package/dist/src/camera/position.d.ts +43 -0
- package/dist/src/camera/position.d.ts.map +1 -0
- package/dist/src/client/client.d.ts +83 -0
- package/dist/src/client/client.d.ts.map +1 -0
- package/dist/src/client/error.d.ts +26 -0
- package/dist/src/client/error.d.ts.map +1 -0
- package/dist/src/client/iframe-builder.d.ts +25 -0
- package/dist/src/client/iframe-builder.d.ts.map +1 -0
- package/dist/src/client/options.d.ts +17 -0
- package/dist/src/client/options.d.ts.map +1 -0
- package/dist/src/client/ready-state-tracker.d.ts +26 -0
- package/dist/src/client/ready-state-tracker.d.ts.map +1 -0
- package/dist/src/client/types.d.ts +5 -0
- package/dist/src/client/types.d.ts.map +1 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/snapshot/index.d.ts +3 -0
- package/dist/src/snapshot/index.d.ts.map +1 -0
- package/dist/src/snapshot/photo.d.ts +47 -0
- package/dist/src/snapshot/photo.d.ts.map +1 -0
- package/dist/src/snapshot/snapshot.d.ts +30 -0
- package/dist/src/snapshot/snapshot.d.ts.map +1 -0
- package/dist/src/ui/viewer-config.d.ts +63 -0
- package/dist/src/ui/viewer-config.d.ts.map +1 -0
- package/dist/src/utils/logger.d.ts +11 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/virtualdisplay.client.cjs.js +1 -2
- package/dist/virtualdisplay.client.es.js +798 -2
- package/dist/virtualdisplay.client.umd.js +1 -2
- package/package.json +3 -3
- package/dist/index.d.ts +0 -415
- package/dist/virtualdisplay.client.cjs.js.map +0 -1
- package/dist/virtualdisplay.client.es.js.map +0 -1
- package/dist/virtualdisplay.client.umd.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewer-config.d.ts","sourceRoot":"","sources":["../../../src/ui/viewer-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,QAAQ,EAEd,MAAM,8BAA8B,CAAC;AAGtC;;;GAGG;AACH,qBAAa,2BAA2B;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkB;gBAE3B,IAAI,EAAE,eAAe;IAIjC;;;OAGG;IACI,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAStD;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAoBrB;;OAEG;IACH,OAAO,CAAC,eAAe;IAavB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAK3C;;OAEG;IACI,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKnD;;OAEG;IACI,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKzD;;OAEG;IACI,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI;IAQtD;;OAEG;IACI,SAAS,IAAI,IAAI;IASxB;;OAEG;IACI,SAAS,IAAI,IAAI;IASxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB;;OAEG;IACH,OAAO,CAAC,UAAU;CAUnB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type Attrs = Record<string, unknown> | unknown;
|
|
2
|
+
export declare let logger: {
|
|
3
|
+
debug: (msg: string, attrs?: Attrs) => void;
|
|
4
|
+
info: (msg: string, attrs?: Attrs) => void;
|
|
5
|
+
warn: (msg: string, attrs?: Attrs) => void;
|
|
6
|
+
error: (msg: string, attrs?: Attrs) => void;
|
|
7
|
+
};
|
|
8
|
+
export declare function enableDebugMode(): void;
|
|
9
|
+
export declare function isDebugMode(): boolean;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;AA4B/C,eAAO,IAAI,MAAM;iBAbF,MAAM,UAAU,KAAK;gBACtB,MAAM,UAAU,KAAK;gBACrB,MAAM,UAAU,KAAK;iBACpB,MAAM,UAAU,KAAK;CAU4C,CAAC;AAEjF,wBAAgB,eAAe,IAAI,IAAI,CAGtC;AAED,wBAAgB,WAAW,IAAI,OAAO,CAErC"}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e={NO_MAPPING:"NO_MAPPING",ATTRIBUTE_NOT_FOUND:"ATTRIBUTE_NOT_FOUND",VALUE_NOT_FOUND:"VALUE_NOT_FOUND",PARENT_NOT_FOUND:"PARENT_NOT_FOUND",INVALID_PARAMETER:"INVALID_PARAMETER",SNAPSHOT_FAILED:"SNAPSHOT_FAILED"};class t extends Error{code;constructor(e,s){super(e),this.name="VirtualdisplayError",this.code=s,void 0!==Error.captureStackTrace&&Error.captureStackTrace(this,t)}static noMapping(){return new t("No attributes available. Waiting for server metadata.",e.NO_MAPPING)}static attributeNotFound(s){return new t(`Attribute "${s}" not found in mapping`,e.ATTRIBUTE_NOT_FOUND)}static valueNotFound(s,i){return new t(`Value "${i}" not found for attribute "${s}"`,e.VALUE_NOT_FOUND)}static parentNotFound(s){return new t(`Parent element not found: ${s}`,e.PARENT_NOT_FOUND)}static invalidParameter(s){return new t(s,e.INVALID_PARAMETER)}static snapshotFailed(s,i){return new t(`Snapshot failed for "${s}": ${i}`,e.SNAPSHOT_FAILED)}}const s={};class i{defaultServer="https://server.virtualdisplay.io";options;constructor(e){this.options=e}create(){const e=this.createIframe();return this.attachToParent(e),e}createIframe(){const e=document.createElement("iframe");return e.src=this.buildUrl(),Object.assign(e.style,{width:"100%",height:"100%",border:"none"}),e.setAttribute("allow","xr-spatial-tracking; fullscreen"),e}attachToParent(e){this.getParentElement().appendChild(e)}buildUrl(){const e=this.getServerUrl(),t=new URL(e);return t.searchParams.set("license",this.options.license),t.searchParams.set("model",this.options.model),!0===this.options.debug&&t.searchParams.set("debug","true"),void 0!==this.options.language&&t.searchParams.set("language",this.options.language),t.toString()}getServerUrl(){if(void 0===s?.VITE_VIRTUALDISPLAY_SERVER_HOST)return this.defaultServer}getParentElement(){if("string"!=typeof this.options.parent)return this.options.parent;const e=document.querySelector(this.options.parent);if(null===e)throw t.parentNotFound(this.options.parent);return e}}function n(e,t){const s=t?function(e){const t=new Date(e.timestamp).toLocaleTimeString("en-GB",{hour12:!1}),s=e.level.toUpperCase().padEnd(5),i=e.trace_id?.slice(0,8)??"--------",n=e.msg,r=["timestamp","level","msg","service","trace_id","span_id"],a=Object.entries(e).filter(([e])=>!r.includes(e)).map(([e,t])=>`${e}=${JSON.stringify(t)}`).join(" ");return`${t} ${s} [${i}] ${n}${a?" "+a:""}`}(e):function(e){return JSON.stringify(e)}(e);"error"===e.level?console.error(s):"warn"===e.level?console.warn(s):console.log(s)}class r{constructor(e){this.config=e}log(e,t,s={}){const i=this.config.traceProvider?.()??{};var r;n({timestamp:(r=new Date,r.toISOString()),level:e,msg:t,service:this.config.service,...i,...s},this.config.isDev)}debug(e,t){this.config.isDev&&this.log("debug",e,t)}info(e,t){this.log("info",e,t)}warn(e,t){this.log("warn",e,t)}error(e,t){this.log("error",e,t)}with(e){const t=new r(this.config);return t.log=((t,s,i={})=>{this.log(t,s,{...e,...i})}).bind(this),t}}function a(e,t){const s=void 0!==t?.isDev?t.isDev:"undefined"==typeof process||"production"!==process.env.NODE_ENV;return new r({service:e,isDev:s,traceProvider:t?.traceProvider})}function o(e){if(void 0!==e)return"object"!=typeof e||null===e||Array.isArray(e)||e instanceof Error?e instanceof Error?{error:e.message}:{value:e}:e}function l(e){return{debug:(t,s)=>e.debug(t,o(s)),info:(t,s)=>e.info(t,o(s)),warn:(t,s)=>e.warn(t,o(s)),error:(t,s)=>e.error(t,o(s))}}let d=!1;function u(){d=!0,exports.logger=l(a("client",{isDev:!0}))}exports.logger=l(a("client",{isDev:!1}));class h{ready=!1;onReady;constructor(e){this.onReady=e}handleMappingReceived(){this.markReady("Mapping received from server")}handleMutationResult(e){e.isInitial&&this.markReady("Initial mutations processed")}get isReady(){return this.ready}clear(){this.ready=!1}markReady(e){this.ready||(this.ready=!0,exports.logger.info(`${e} - client is now ready`),this.onReady?.())}}class c{constructor(e,t){this.value=e,this.attribute=t}isSelectedValue=!1;get isSelected(){return this.isSelectedValue}setSelected(e){this.isSelectedValue=e}}class g{name;defaultValue;values;onSelect;onChangeCallback;constructor(e){this.name=e.name,this.defaultValue=e.defaultValue,this.onSelect=e.onSelect,this.values=this.createValues(e.values)}select(e){if(!this.values.has(e))throw t.valueNotFound(this.name,e);this.onSelect(this.name,e)}getValues(){return Array.from(this.values.values())}getValue(e){return this.values.get(e)}onChange(e){this.onChangeCallback=e}handleResult(e){let t;for(const s of this.values.values()){const i=s.value===e;s.setSelected(i),i&&(t=s)}void 0!==t&&void 0!==this.onChangeCallback&&this.onChangeCallback(t)}createValues(e){const t=new Map;for(const s of e){const e=new c(s,this.name);s===this.defaultValue&&e.setSelected(!0),t.set(s,e)}return t}}class p{attributes=new Map;constructor(e,t,s){for(const i of e){const e=this.buildOptions(i,t);this.attributes.set(i.name,new g(e))}this.onMutationFailed=s}onMutationFailed;get(e){return this.attributes.get(e)}defaults(){const e=[];for(const t of this.attributes.values())void 0!==t.defaultValue&&e.push({name:t.name,value:t.defaultValue});return e}handleResults(e){for(const t of e)t.success?this.get(t.name)?.handleResult(t.value):this.onMutationFailed?.(t.name,t.value)}buildOptions(e,t){const s={name:e.name,values:e.values,onSelect:(e,s)=>{t([{name:e,value:s}],!1)}};return void 0!==e.defaultValue?{...s,defaultValue:e.defaultValue}:s}}const f={READY:"ready",MUTATION:"mutation",STATE:"state",CONFIG:"config",CAMERA:"camera",SNAPSHOT:"snapshot",MAPPING:"mapping"},m=new Set(Object.values(f));function b(e){return"object"!=typeof e||null===e?null:e}class v{constructor(e){this.processor=e}pending=[];isReady=!1;enqueue(e){this.isReady?this.processor(e):this.pending.push(e)}markReady(){if(this.isReady)return;if(this.isReady=!0,0===this.pending.length)return;const e=[...this.pending];this.pending.length=0;for(const t of e)this.processor(t)}get ready(){return this.isReady}get pendingCount(){return this.pending.length}hasPending(e){return this.pending.some(t=>t.type===e)}clear(){this.pending.length=0}}class y{constructor(e,t){this.getTarget=e,this.sourceId=`vd-${Math.random().toString(36).slice(2,8)}`,this.publisher=new v(e=>this.post(e)),this.consumer=new v(e=>this.routeToHandler(e)),this.shouldBuffer=t?.shouldBuffer??null,!0!==t?.bufferIncoming&&this.consumer.markReady()}handlers=new Map;publisher;consumer;shouldBuffer;listener=null;sourceId;on(e,t){this.handlers.set(e,t)}off(e){this.handlers.delete(e)}send(e){this.publisher.enqueue(e)}markReady(){this.publisher.markReady()}markConsumerReady(){this.consumer.markReady()}consumerHasPending(e){return this.consumer.hasPending(e)}start(){null===this.listener&&(this.listener=e=>{const{data:t}=e;if(!function(e){if("object"!=typeof e||null===e)return!1;const t=e;return"string"!=typeof t.target&&"string"==typeof t.type&&m.has(t.type)}(t))return;if(t._source===this.sourceId)return;const s=t;null===this.shouldBuffer||this.shouldBuffer(s)?this.consumer.enqueue(s):this.routeToHandler(s)},window.addEventListener("message",this.listener))}destroy(){null!==this.listener&&(window.removeEventListener("message",this.listener),this.listener=null),this.publisher.clear(),this.consumer.clear(),this.handlers.clear()}get ready(){return this.publisher.ready}get pendingCount(){return this.publisher.pendingCount}post(e){const t=this.getTarget();null!==t&&t.postMessage({...e,_source:this.sourceId},"*")}routeToHandler(e){const t=this.handlers.get(e.type);if(void 0===t)return;const s=t(e);s instanceof Promise&&s.catch(t=>{const s=t instanceof Error?t.message:String(t);console.error(`Virtualdisplay: error handling ${e.type}: ${s}`)})}}class A{constructor(e,t){this.send=e,this.onMutationFailed=t}registry;pendingCallbacks=[];handleMappingReceived(e){exports.logger.debug("Initializing from server mapping",{attributeCount:e.attributes.length}),this.registry=new p(e.attributes,(e,t)=>this.sendMutation(e,t),this.onMutationFailed);const t=this.registry.defaults();t.length>0&&this.sendMutation(t,!0),this.replayPendingCallbacks()}handleMutationResult(e){this.registry?.handleResults(e.results)}select(e,t){this.sendMutation([{name:e,value:t}],!1)}getValues(e){return this.registry?.get(e)?.getValues()??[]}getValue(e,t){return this.registry?.get(e)?.getValue(t)}onChange(e,t){if(void 0===this.registry)return void this.pendingCallbacks.push({name:e,callback:t});const s=this.registry.get(e);void 0!==s?s.onChange(t):exports.logger.warn(`onChange: attribute "${e}" not found — callback will not fire`)}getAttribute(e){return this.registry?.get(e)}get hasMapping(){return void 0!==this.registry}sendMutation(e,t){const s={type:f.MUTATION,mutations:e,isInitial:t};this.send(s)}replayPendingCallbacks(){for(const{name:e,callback:t}of this.pendingCallbacks){const s=this.registry?.get(e);void 0===s&&exports.logger.warn(`onChange: attribute "${e}" not found — buffered callback will not fire`),s?.onChange(t)}this.pendingCallbacks.length=0}}class E{constructor(e){this.send=e}commands=[];rotate(e){return this.validateFiniteNumber(e,"rotate"),this.commands.push({action:"rotate",value:e}),this}tilt(e){return this.validateFiniteNumber(e,"tilt"),this.commands.push({action:"tilt",value:e}),this}zoom(e){return this.validateFiniteNumber(e,"zoom"),this.commands.push({action:"zoom",value:e}),this}set(){if(0===this.commands.length)throw t.invalidParameter("No camera commands to execute. Call rotate(), tilt(), or zoom() before set().");const e={type:f.CAMERA,commands:this.commands};this.send(e),this.commands=[]}validateFiniteNumber(e,s){if(!Number.isFinite(e))throw t.invalidParameter(`${s}() requires a finite number, got ${String(e)}`)}reset(){const e={type:f.CAMERA,commands:[{action:"reset"}]};this.send(e)}}class C{state;changeCallbacks=[];constructor(){this.state={rotation:0,tilt:0,zoom:0}}get rotation(){return this.state.rotation}get tilt(){return this.state.tilt}get zoom(){return this.state.zoom}onChange(e){this.changeCallbacks.push(e)}handlePositionUpdate(e){this.update(e.transforms)}update(e){let t=!1;for(const s of e)switch(s.type){case"rotation":this.state.rotation=s.value,t=!0;break;case"tilt":this.state.tilt=s.value,t=!0;break;case"zoom":this.state.zoom=s.value,t=!0}if(t){const e={rotation:this.rotation,tilt:this.tilt,zoom:this.zoom};for(const t of this.changeCallbacks)t(e)}}}class I{constructor(e){this.filename=e}developedCallbacks=new Set;errorCallbacks=new Set;developed=!1;failed=!1;photoData=null;onDeveloped(e){return this.developed&&null!==this.photoData?(e(this.photoData),this):(this.developedCallbacks.add(e),this)}onError(e){return this.errorCallbacks.add(e),this}getFilename(){return this.filename}develop(e){this.developed||this.failed||(this.photoData=e,this.developed=!0,this.developedCallbacks.forEach(e=>{e(this.photoData)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}fail(e){this.developed||this.failed||(this.failed=!0,this.errorCallbacks.forEach(t=>{t(e)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}}class w{constructor(e){this.send=e}validExtensions=[".png"];pendingPhotos=new Map;take(e){this.validateFilename(e),exports.logger.debug("Taking snapshot",{filename:e});const t=new I(e);return this.pendingPhotos.set(t.getFilename(),t),this.send({type:f.SNAPSHOT,filename:e}),t}handleSnapshotResult(s){const i=this.pendingPhotos.get(s.filename);void 0!==i?(this.pendingPhotos.delete(s.filename),void 0===s.error?void 0!==s.data&&i.develop({filename:s.filename,data:s.data}):i.fail(new t(s.error,e.SNAPSHOT_FAILED))):exports.logger.warn("No pending photo found for filename",{filename:s.filename,pendingFilenames:Array.from(this.pendingPhotos.keys())})}validateFilename(s){if(""===s||"string"!=typeof s)throw new t("Filename must be a non-empty string",e.INVALID_PARAMETER);if(!this.validExtensions.some(e=>s.toLowerCase().endsWith(e)))throw new t(`Invalid filename: "${s}". Filename must end with one of: ${this.validExtensions.join(", ")}`,e.INVALID_PARAMETER);if(s.includes("..")||s.includes("/")||s.includes("\\"))throw new t('Filename cannot contain path separators or ".."',e.INVALID_PARAMETER)}}class S{send;constructor(e){this.send=e}sendInitialConfig(e){const t=this.buildUIConfig(e),s=this.buildViewerConfig(t,e.camera);void 0!==s&&this.sendConfig(s)}buildUIConfig(e){const t=this.extractUIValues(e);if(Object.values(t).some(e=>void 0!==e))return{...void 0!==t.arEnabled&&{arEnabled:t.arEnabled},...void 0!==t.fullscreenEnabled&&{fullscreenEnabled:t.fullscreenEnabled},...void 0!==t.loadingIndicatorEnabled&&{loadingIndicatorEnabled:t.loadingIndicatorEnabled}}}extractUIValues(e){return{arEnabled:e.arEnabled??e.ui?.arEnabled,fullscreenEnabled:e.fullscreenEnabled??e.ui?.fullscreenEnabled,loadingIndicatorEnabled:e.loadingIndicatorEnabled??e.ui?.loadingIndicatorEnabled}}buildViewerConfig(e,t){if(void 0!==e||void 0!==t)return{...void 0!==e&&{ui:e},...void 0!==t&&{camera:t}}}setArEnabled(e){exports.logger.debug(`Setting AR button enabled: ${e}`),this.updateUIConfig({arEnabled:e})}setFullscreenEnabled(e){exports.logger.debug(`Setting fullscreen button enabled: ${e}`),this.updateUIConfig({fullscreenEnabled:e})}setLoadingIndicatorEnabled(e){exports.logger.debug(`Setting loading indicator enabled: ${e}`),this.updateUIConfig({loadingIndicatorEnabled:e})}updateUIConfig(e){exports.logger.debug("Updating UI configuration",e),Object.keys(e).length>0&&this.sendConfig({ui:e})}hideAllUI(){exports.logger.debug("Hiding all UI elements"),this.sendUIConfig({arEnabled:!1,fullscreenEnabled:!1,loadingIndicatorEnabled:!1})}showAllUI(){exports.logger.debug("Showing all UI elements"),this.sendUIConfig({arEnabled:!0,fullscreenEnabled:!0,loadingIndicatorEnabled:!0})}sendUIConfig(e){this.sendConfig({ui:e})}sendConfig(e){const t={type:f.CONFIG,config:e};exports.logger.debug("Sending config",t),this.send(t)}}exports.Attribute=g,exports.AttributeValue=c,exports.Camera=E,exports.ERROR_CODES=e,exports.Photo=I,exports.Snapshot=w,exports.VirtualdisplayClient=class{attributes;readyStateTracker;messenger;viewerService;cameraApi;cameraPositionApi;snapshotApi;options;iframe;readyCallbacks=[];mutationFailedCallbacks=[];constructor(e){this.options=e,this.initializeLogging(),this.messenger=new y(()=>this.iframe?.contentWindow??null);const t=e=>{this.messenger.send(e)};this.attributes=new A(t,(e,t)=>{for(const s of this.mutationFailedCallbacks)s({attribute:e,value:t})}),this.readyStateTracker=new h(()=>{const e=this.readyCallbacks;this.readyCallbacks=[];for(const t of e)t(this)}),this.viewerService=new S(t),this.cameraApi=new E(t),this.cameraPositionApi=new C,this.snapshotApi=new w(t),this.registerHandlers(),this.messenger.start(),this.createAndConnectIframe()}registerHandlers(){this.messenger.on(f.READY,e=>{(function(e){const t=b(e);return null!==t&&t.type===f.READY})(e)&&(exports.logger.info("Server ready — flushing publisher queue"),this.messenger.markReady(),this.viewerService.sendInitialConfig(this.options))}),this.messenger.on(f.MUTATION,e=>{(function(e){const t=b(e);return null!==t&&t.type===f.MUTATION&&Array.isArray(t.results)})(e)&&(this.attributes.handleMutationResult(e),this.readyStateTracker.handleMutationResult(e))}),this.messenger.on(f.SNAPSHOT,e=>{(function(e){const t=b(e);return null!==t&&t.type===f.SNAPSHOT&&("data"in t||"error"in t)})(e)&&this.snapshotApi.handleSnapshotResult(e)}),this.messenger.on(f.CAMERA,e=>{(function(e){const t=b(e);return null!==t&&t.type===f.CAMERA&&Array.isArray(t.transforms)})(e)&&this.cameraPositionApi.handlePositionUpdate(e)}),this.messenger.on(f.MAPPING,e=>{(function(e){const t=b(e);return null!==t&&t.type===f.MAPPING&&Array.isArray(t.attributes)})(e)&&(this.attributes.handleMappingReceived(e),this.readyStateTracker.handleMappingReceived())})}initializeLogging(){!0===this.options.debug&&u(),exports.logger.info("Initializing Virtualdisplay client",{model:this.options.model,debug:this.options.debug,language:this.options.language})}createAndConnectIframe(){exports.logger.debug("Creating iframe for Virtualdisplay viewer");const e=new i(this.options);this.iframe=e.create(),exports.logger.debug("Iframe created, waiting for server READY")}select(e,t){this.attributes.select(e,t)}getValues(e){return this.attributes.getValues(e)}getValue(e,t){return this.attributes.getValue(e,t)}onChange(e,t){this.attributes.onChange(e,t)}getAttribute(e){return this.attributes.getAttribute(e)}get isReady(){return this.readyStateTracker.isReady}onReady(e){this.readyStateTracker.isReady?e(this):this.readyCallbacks.push(e)}onMutationFailed(e){this.mutationFailedCallbacks.push(e)}get viewer(){return this.viewerService}get camera(){return this.cameraApi}get cameraPosition(){return this.cameraPositionApi}get snapshot(){return this.snapshotApi}destroy(){exports.logger.info("Destroying Virtualdisplay client"),this.readyStateTracker.clear(),this.readyCallbacks=[],this.messenger.destroy(),null!==this.iframe?.parentElement&&void 0!==this.iframe?.parentElement&&this.iframe.parentElement.removeChild(this.iframe),this.iframe=void 0,exports.logger.debug("Virtualdisplay client destroyed")}},exports.VirtualdisplayError=t,exports.VirtualdisplayViewerService=S,exports.enableDebugMode=u,exports.isDebugMode=function(){return d};
|
|
2
|
-
//# sourceMappingURL=virtualdisplay.client.cjs.js.map
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={NO_MAPPING:`NO_MAPPING`,ATTRIBUTE_NOT_FOUND:`ATTRIBUTE_NOT_FOUND`,VALUE_NOT_FOUND:`VALUE_NOT_FOUND`,PARENT_NOT_FOUND:`PARENT_NOT_FOUND`,INVALID_PARAMETER:`INVALID_PARAMETER`,SNAPSHOT_FAILED:`SNAPSHOT_FAILED`},t=class t extends Error{code;constructor(e,n){super(e),this.name=`VirtualdisplayError`,this.code=n,Error.captureStackTrace?.(this,t)}static noMapping(){return new t(`No attributes available. Waiting for server metadata.`,e.NO_MAPPING)}static attributeNotFound(n){return new t(`Attribute "${n}" not found in mapping`,e.ATTRIBUTE_NOT_FOUND)}static valueNotFound(n,r){return new t(`Value "${r}" not found for attribute "${n}"`,e.VALUE_NOT_FOUND)}static parentNotFound(n){return new t(`Parent element not found: ${n}`,e.PARENT_NOT_FOUND)}static invalidParameter(n){return new t(n,e.INVALID_PARAMETER)}static snapshotFailed(n,r){return new t(`Snapshot failed for "${n}": ${r}`,e.SNAPSHOT_FAILED)}},n=class{defaultServer=`https://server.virtualdisplay.io`;options;constructor(e){this.options=e}create(){let e=this.createIframe();return this.attachToParent(e),e}createIframe(){let e=document.createElement(`iframe`);return e.src=this.buildUrl(),Object.assign(e.style,{width:`100%`,height:`100%`,border:`none`}),e.setAttribute(`allow`,`xr-spatial-tracking; fullscreen`),e}attachToParent(e){this.getParentElement().appendChild(e)}buildUrl(){let e=this.getServerUrl(),t=new URL(e);return t.searchParams.set(`license`,this.options.license),t.searchParams.set(`model`,this.options.model),this.options.debug===!0&&t.searchParams.set(`debug`,`true`),this.options.language!==void 0&&t.searchParams.set(`language`,this.options.language),t.toString()}getServerUrl(){return this.defaultServer}getParentElement(){if(typeof this.options.parent!=`string`)return this.options.parent;let e=document.querySelector(this.options.parent);if(e===null)throw t.parentNotFound(this.options.parent);return e}};function r(e){let t=new Date(e.timestamp).toLocaleTimeString(`en-GB`,{hour12:!1}),n=e.level.toUpperCase().padEnd(5),r=e.trace_id?.slice(0,8)??`--------`,i=e.msg,a=[`timestamp`,`level`,`msg`,`service`,`trace_id`,`span_id`],o=Object.entries(e).filter(([e])=>!a.includes(e)).map(([e,t])=>`${e}=${JSON.stringify(t)}`).join(` `);return`${t} ${n} [${r}] ${i}${o?` `+o:``}`}function i(e){return JSON.stringify(e)}function a(e,t){let n=t?r(e):i(e);e.level===`error`?console.error(n):e.level===`warn`?console.warn(n):console.log(n)}function o(){return new Date}function s(e){return e.toISOString()}var c=class e{constructor(e){this.config=e}log(e,t,n={}){let r=this.config.traceProvider?.()??{};a({timestamp:s(o()),level:e,msg:t,service:this.config.service,...r,...n},this.config.isDev)}debug(e,t){this.config.isDev&&this.log(`debug`,e,t)}info(e,t){this.log(`info`,e,t)}warn(e,t){this.log(`warn`,e,t)}error(e,t){this.log(`error`,e,t)}with(t){let n=new e(this.config);return n.log=((e,n,r={})=>{this.log(e,n,{...t,...r})}).bind(this),n}};function l(e,t){return new c({service:e,isDev:t?.isDev===void 0?typeof process<`u`?process.env.NODE_ENV!==`production`:!0:t.isDev,traceProvider:t?.traceProvider})}function u(e){if(e!==void 0)return typeof e==`object`&&e&&!Array.isArray(e)&&!(e instanceof Error)?e:e instanceof Error?{error:e.message}:{value:e}}function d(e){return{debug:(t,n)=>e.debug(t,u(n)),info:(t,n)=>e.info(t,u(n)),warn:(t,n)=>e.warn(t,u(n)),error:(t,n)=>e.error(t,u(n))}}var f=!1,p=d(l(`client`,{isDev:!1}));function m(){f=!0,p=d(l(`client`,{isDev:!0}))}function h(){return f}var g=class{ready=!1;onReady;constructor(e){this.onReady=e}handleMappingReceived(){this.markReady(`Mapping received from server`)}handleMutationResult(e){e.isInitial&&this.markReady(`Initial mutations processed`)}get isReady(){return this.ready}clear(){this.ready=!1}markReady(e){this.ready||(this.ready=!0,p.info(`${e} - client is now ready`),this.onReady?.())}},_=class{isSelectedValue=!1;constructor(e,t){this.value=e,this.attribute=t}get isSelected(){return this.isSelectedValue}setSelected(e){this.isSelectedValue=e}},v=class{name;defaultValue;values;onSelect;onChangeCallback;constructor(e){this.name=e.name,this.defaultValue=e.defaultValue,this.onSelect=e.onSelect,this.values=this.createValues(e.values)}select(e){if(!this.values.has(e))throw t.valueNotFound(this.name,e);this.onSelect(this.name,e)}getValues(){return Array.from(this.values.values())}getValue(e){return this.values.get(e)}onChange(e){this.onChangeCallback=e}handleResult(e){let t;for(let n of this.values.values()){let r=n.value===e;n.setSelected(r),r&&(t=n)}t!==void 0&&this.onChangeCallback!==void 0&&this.onChangeCallback(t)}createValues(e){let t=new Map;for(let n of e){let e=new _(n,this.name);n===this.defaultValue&&e.setSelected(!0),t.set(n,e)}return t}},y=class{attributes=new Map;constructor(e,t,n){for(let n of e){let e=this.buildOptions(n,t);this.attributes.set(n.name,new v(e))}this.onMutationFailed=n}onMutationFailed;get(e){return this.attributes.get(e)}defaults(){let e=[];for(let t of this.attributes.values())t.defaultValue!==void 0&&e.push({name:t.name,value:t.defaultValue});return e}handleResults(e){for(let t of e){if(!t.success){this.onMutationFailed?.(t.name,t.value);continue}this.get(t.name)?.handleResult(t.value)}}buildOptions(e,t){let n={name:e.name,values:e.values,onSelect:(e,n)=>{t([{name:e,value:n}],!1)}};return e.defaultValue===void 0?n:{...n,defaultValue:e.defaultValue}}},b={READY:`ready`,MUTATION:`mutation`,STATE:`state`,CONFIG:`config`,CAMERA:`camera`,SNAPSHOT:`snapshot`,MAPPING:`mapping`},x=new Set(Object.values(b));function S(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.target==`string`?!1:typeof t.type==`string`&&x.has(t.type)}function C(e){let t=O(e);return t!==null&&t.type===b.READY}function w(e){let t=O(e);return t!==null&&t.type===b.MUTATION&&Array.isArray(t.results)}function T(e){let t=O(e);return t!==null&&t.type===b.SNAPSHOT&&(`data`in t||`error`in t)}function E(e){let t=O(e);return t!==null&&t.type===b.CAMERA&&Array.isArray(t.transforms)}function D(e){let t=O(e);return t!==null&&t.type===b.MAPPING&&Array.isArray(t.attributes)}function O(e){return typeof e!=`object`||!e?null:e}var k=class{pending=[];isReady=!1;constructor(e){this.processor=e}enqueue(e){if(this.isReady){this.processor(e);return}this.pending.push(e)}markReady(){if(this.isReady||(this.isReady=!0,this.pending.length===0))return;let e=[...this.pending];this.pending.length=0;for(let t of e)this.processor(t)}get ready(){return this.isReady}get pendingCount(){return this.pending.length}hasPending(e){return this.pending.some(t=>t.type===e)}clear(){this.pending.length=0}},A=class{handlers=new Map;publisher;consumer;shouldBuffer;listener=null;sourceId;constructor(e,t){this.getTarget=e,this.sourceId=`vd-${Math.random().toString(36).slice(2,8)}`,this.publisher=new k(e=>this.post(e)),this.consumer=new k(e=>this.routeToHandler(e)),this.shouldBuffer=t?.shouldBuffer??null,t?.bufferIncoming!==!0&&this.consumer.markReady()}on(e,t){this.handlers.set(e,t)}off(e){this.handlers.delete(e)}send(e){this.publisher.enqueue(e)}markReady(){this.publisher.markReady()}markConsumerReady(){this.consumer.markReady()}consumerHasPending(e){return this.consumer.hasPending(e)}start(){this.listener===null&&(this.listener=e=>{let{data:t}=e;if(!S(t)||t._source===this.sourceId)return;let n=t;if(this.shouldBuffer!==null&&!this.shouldBuffer(n)){this.routeToHandler(n);return}this.consumer.enqueue(n)},window.addEventListener(`message`,this.listener))}destroy(){this.listener!==null&&(window.removeEventListener(`message`,this.listener),this.listener=null),this.publisher.clear(),this.consumer.clear(),this.handlers.clear()}get ready(){return this.publisher.ready}get pendingCount(){return this.publisher.pendingCount}post(e){let t=this.getTarget();t!==null&&t.postMessage({...e,_source:this.sourceId},`*`)}routeToHandler(e){let t=this.handlers.get(e.type);if(t===void 0)return;let n=t(e);n instanceof Promise&&n.catch(t=>{let n=t instanceof Error?t.message:String(t);console.error(`Virtualdisplay: error handling ${e.type}: ${n}`)})}};new Set([b.CAMERA]);var j=class{registry;pendingCallbacks=[];constructor(e,t){this.send=e,this.onMutationFailed=t}handleMappingReceived(e){p.debug(`Initializing from server mapping`,{attributeCount:e.attributes.length}),this.registry=new y(e.attributes,(e,t)=>this.sendMutation(e,t),this.onMutationFailed);let t=this.registry.defaults();t.length>0&&this.sendMutation(t,!0),this.replayPendingCallbacks()}handleMutationResult(e){this.registry?.handleResults(e.results)}select(e,t){this.sendMutation([{name:e,value:t}],!1)}getValues(e){return this.registry?.get(e)?.getValues()??[]}getValue(e,t){return this.registry?.get(e)?.getValue(t)}onChange(e,t){if(this.registry===void 0){this.pendingCallbacks.push({name:e,callback:t});return}let n=this.registry.get(e);if(n===void 0){p.warn(`onChange: attribute "${e}" not found — callback will not fire`);return}n.onChange(t)}getAttribute(e){return this.registry?.get(e)}get hasMapping(){return this.registry!==void 0}sendMutation(e,t){let n={type:b.MUTATION,mutations:e,isInitial:t};this.send(n)}replayPendingCallbacks(){for(let{name:e,callback:t}of this.pendingCallbacks){let n=this.registry?.get(e);n===void 0&&p.warn(`onChange: attribute "${e}" not found — buffered callback will not fire`),n?.onChange(t)}this.pendingCallbacks.length=0}},M=class{commands=[];constructor(e){this.send=e}rotate(e){return this.validateFiniteNumber(e,`rotate`),this.commands.push({action:`rotate`,value:e}),this}tilt(e){return this.validateFiniteNumber(e,`tilt`),this.commands.push({action:`tilt`,value:e}),this}zoom(e){return this.validateFiniteNumber(e,`zoom`),this.commands.push({action:`zoom`,value:e}),this}set(){if(this.commands.length===0)throw t.invalidParameter(`No camera commands to execute. Call rotate(), tilt(), or zoom() before set().`);let e={type:b.CAMERA,commands:this.commands};this.send(e),this.commands=[]}validateFiniteNumber(e,n){if(!Number.isFinite(e))throw t.invalidParameter(`${n}() requires a finite number, got ${String(e)}`)}reset(){let e={type:b.CAMERA,commands:[{action:`reset`}]};this.send(e)}},N=class{state;changeCallbacks=[];constructor(){this.state={rotation:0,tilt:0,zoom:0}}get rotation(){return this.state.rotation}get tilt(){return this.state.tilt}get zoom(){return this.state.zoom}onChange(e){this.changeCallbacks.push(e)}handlePositionUpdate(e){this.update(e.transforms)}update(e){let t=!1;for(let n of e)switch(n.type){case`rotation`:this.state.rotation=n.value,t=!0;break;case`tilt`:this.state.tilt=n.value,t=!0;break;case`zoom`:this.state.zoom=n.value,t=!0;break;default:break}if(t){let e={rotation:this.rotation,tilt:this.tilt,zoom:this.zoom};for(let t of this.changeCallbacks)t(e)}}},P=class{developedCallbacks=new Set;errorCallbacks=new Set;developed=!1;failed=!1;photoData=null;constructor(e){this.filename=e}onDeveloped(e){return this.developed&&this.photoData!==null?(e(this.photoData),this):(this.developedCallbacks.add(e),this)}onError(e){return this.errorCallbacks.add(e),this}getFilename(){return this.filename}develop(e){this.developed||this.failed||(this.photoData=e,this.developed=!0,this.developedCallbacks.forEach(e=>{e(this.photoData)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}fail(e){this.developed||this.failed||(this.failed=!0,this.errorCallbacks.forEach(t=>{t(e)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}},F=class{validExtensions=[`.png`];pendingPhotos=new Map;constructor(e){this.send=e}take(e){this.validateFilename(e),p.debug(`Taking snapshot`,{filename:e});let t=new P(e);return this.pendingPhotos.set(t.getFilename(),t),this.send({type:b.SNAPSHOT,filename:e}),t}handleSnapshotResult(n){let r=this.pendingPhotos.get(n.filename);if(r===void 0){p.warn(`No pending photo found for filename`,{filename:n.filename,pendingFilenames:Array.from(this.pendingPhotos.keys())});return}if(this.pendingPhotos.delete(n.filename),n.error!==void 0){r.fail(new t(n.error,e.SNAPSHOT_FAILED));return}n.data!==void 0&&r.develop({filename:n.filename,data:n.data})}validateFilename(n){if(n===``||typeof n!=`string`)throw new t(`Filename must be a non-empty string`,e.INVALID_PARAMETER);if(!this.validExtensions.some(e=>n.toLowerCase().endsWith(e)))throw new t(`Invalid filename: "${n}". Filename must end with one of: ${this.validExtensions.join(`, `)}`,e.INVALID_PARAMETER);if(n.includes(`..`)||n.includes(`/`)||n.includes(`\\`))throw new t(`Filename cannot contain path separators or ".."`,e.INVALID_PARAMETER)}},I=class{send;constructor(e){this.send=e}sendInitialConfig(e){let t=this.buildUIConfig(e),n=this.buildViewerConfig(t,e.camera);n!==void 0&&this.sendConfig(n)}buildUIConfig(e){let t=this.extractUIValues(e);if(Object.values(t).some(e=>e!==void 0))return{...t.arEnabled!==void 0&&{arEnabled:t.arEnabled},...t.fullscreenEnabled!==void 0&&{fullscreenEnabled:t.fullscreenEnabled},...t.loadingIndicatorEnabled!==void 0&&{loadingIndicatorEnabled:t.loadingIndicatorEnabled}}}extractUIValues(e){return{arEnabled:e.arEnabled??e.ui?.arEnabled,fullscreenEnabled:e.fullscreenEnabled??e.ui?.fullscreenEnabled,loadingIndicatorEnabled:e.loadingIndicatorEnabled??e.ui?.loadingIndicatorEnabled}}buildViewerConfig(e,t){if(!(e===void 0&&t===void 0))return{...e!==void 0&&{ui:e},...t!==void 0&&{camera:t}}}setArEnabled(e){p.debug(`Setting AR button enabled: ${e}`),this.updateUIConfig({arEnabled:e})}setFullscreenEnabled(e){p.debug(`Setting fullscreen button enabled: ${e}`),this.updateUIConfig({fullscreenEnabled:e})}setLoadingIndicatorEnabled(e){p.debug(`Setting loading indicator enabled: ${e}`),this.updateUIConfig({loadingIndicatorEnabled:e})}updateUIConfig(e){p.debug(`Updating UI configuration`,e),Object.keys(e).length>0&&this.sendConfig({ui:e})}hideAllUI(){p.debug(`Hiding all UI elements`),this.sendUIConfig({arEnabled:!1,fullscreenEnabled:!1,loadingIndicatorEnabled:!1})}showAllUI(){p.debug(`Showing all UI elements`),this.sendUIConfig({arEnabled:!0,fullscreenEnabled:!0,loadingIndicatorEnabled:!0})}sendUIConfig(e){this.sendConfig({ui:e})}sendConfig(e){let t={type:b.CONFIG,config:e};p.debug(`Sending config`,t),this.send(t)}},L=class{attributes;readyStateTracker;messenger;viewerService;cameraApi;cameraPositionApi;snapshotApi;options;iframe;readyCallbacks=[];mutationFailedCallbacks=[];constructor(e){this.options=e,this.initializeLogging(),this.messenger=new A(()=>this.iframe?.contentWindow??null);let t=e=>{this.messenger.send(e)};this.attributes=new j(t,(e,t)=>{for(let n of this.mutationFailedCallbacks)n({attribute:e,value:t})}),this.readyStateTracker=new g(()=>{let e=this.readyCallbacks;this.readyCallbacks=[];for(let t of e)t(this)}),this.viewerService=new I(t),this.cameraApi=new M(t),this.cameraPositionApi=new N,this.snapshotApi=new F(t),this.registerHandlers(),this.messenger.start(),this.createAndConnectIframe()}registerHandlers(){this.messenger.on(b.READY,e=>{C(e)&&(p.info(`Server ready — flushing publisher queue`),this.messenger.markReady(),this.viewerService.sendInitialConfig(this.options))}),this.messenger.on(b.MUTATION,e=>{w(e)&&(this.attributes.handleMutationResult(e),this.readyStateTracker.handleMutationResult(e))}),this.messenger.on(b.SNAPSHOT,e=>{T(e)&&this.snapshotApi.handleSnapshotResult(e)}),this.messenger.on(b.CAMERA,e=>{E(e)&&this.cameraPositionApi.handlePositionUpdate(e)}),this.messenger.on(b.MAPPING,e=>{D(e)&&(this.attributes.handleMappingReceived(e),this.readyStateTracker.handleMappingReceived())})}initializeLogging(){this.options.debug===!0&&m(),p.info(`Initializing Virtualdisplay client`,{model:this.options.model,debug:this.options.debug,language:this.options.language})}createAndConnectIframe(){p.debug(`Creating iframe for Virtualdisplay viewer`),this.iframe=new n(this.options).create(),p.debug(`Iframe created, waiting for server READY`)}select(e,t){this.attributes.select(e,t)}getValues(e){return this.attributes.getValues(e)}getValue(e,t){return this.attributes.getValue(e,t)}onChange(e,t){this.attributes.onChange(e,t)}getAttribute(e){return this.attributes.getAttribute(e)}get isReady(){return this.readyStateTracker.isReady}onReady(e){if(this.readyStateTracker.isReady){e(this);return}this.readyCallbacks.push(e)}onMutationFailed(e){this.mutationFailedCallbacks.push(e)}get viewer(){return this.viewerService}get camera(){return this.cameraApi}get cameraPosition(){return this.cameraPositionApi}get snapshot(){return this.snapshotApi}destroy(){p.info(`Destroying Virtualdisplay client`),this.readyStateTracker.clear(),this.readyCallbacks=[],this.messenger.destroy(),this.iframe?.parentElement!==null&&this.iframe?.parentElement!==void 0&&this.iframe.parentElement.removeChild(this.iframe),this.iframe=void 0,p.debug(`Virtualdisplay client destroyed`)}};exports.Attribute=v,exports.AttributeValue=_,exports.Camera=M,exports.ERROR_CODES=e,exports.Photo=P,exports.Snapshot=F,exports.VirtualdisplayClient=L,exports.VirtualdisplayError=t,exports.VirtualdisplayViewerService=I,exports.enableDebugMode=m,exports.isDebugMode=h,Object.defineProperty(exports,`logger`,{enumerable:!0,get:function(){return p}});
|