@inweb/viewer-visualize 26.7.0 → 26.7.1

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.
@@ -3854,28 +3854,134 @@
3854
3854
  // By use of this software, its documentation or related materials, you
3855
3855
  // acknowledge and accept the above terms.
3856
3856
  ///////////////////////////////////////////////////////////////////////////////
3857
- class VSFBufferLoader extends Loader {
3857
+ class FileLoader {
3858
+ constructor() {
3859
+ this.requestHeader = {};
3860
+ this.withCredentials = false;
3861
+ this.abortSignal = undefined;
3862
+ }
3863
+ setRequestHeader(requestHeader) {
3864
+ this.requestHeader = requestHeader;
3865
+ }
3866
+ setWithCredentials(withCredentials) {
3867
+ this.withCredentials = withCredentials;
3868
+ }
3869
+ setAbortSignal(abortSignal) {
3870
+ this.abortSignal = abortSignal;
3871
+ }
3872
+ load(file, onProgress) {
3873
+ if (typeof file === "string") {
3874
+ const request = new Request(file, {
3875
+ headers: new Headers(this.requestHeader),
3876
+ credentials: this.withCredentials ? "include" : "same-origin",
3877
+ signal: this.abortSignal,
3878
+ });
3879
+ return fetch(request)
3880
+ .then((response) => {
3881
+ if (!response.ok)
3882
+ throw new Error(`Failed to fetch "${response.url}", status ${response.status}`);
3883
+ const contentLength = response.headers.get("X-File-Size") || response.headers.get("Content-Length");
3884
+ const total = parseInt(contentLength || "", 10) || 0;
3885
+ const lengthComputable = total > 0;
3886
+ const stream = new ReadableStream({
3887
+ async start(controller) {
3888
+ const reader = response.body.getReader();
3889
+ let loaded = 0;
3890
+ try {
3891
+ while (true) {
3892
+ const { done, value } = await reader.read();
3893
+ if (done)
3894
+ break;
3895
+ if (onProgress) {
3896
+ loaded += value.byteLength;
3897
+ onProgress(new ProgressEvent("progress", { lengthComputable, loaded, total }));
3898
+ }
3899
+ controller.enqueue(value);
3900
+ }
3901
+ controller.close();
3902
+ }
3903
+ catch (e) {
3904
+ controller.error(e);
3905
+ }
3906
+ },
3907
+ });
3908
+ return new Response(stream);
3909
+ })
3910
+ .then((response) => response.arrayBuffer());
3911
+ }
3912
+ if (file instanceof globalThis.File) {
3913
+ return new Promise((resolve, reject) => {
3914
+ const reader = new FileReader();
3915
+ reader.onload = () => resolve(reader.result);
3916
+ reader.onerror = () => reject(reader.error);
3917
+ reader.onprogress = onProgress;
3918
+ reader.readAsArrayBuffer(new Blob([file]));
3919
+ });
3920
+ }
3921
+ if (onProgress) {
3922
+ const total = file.byteLength;
3923
+ const lengthComputable = total > 0;
3924
+ const loaded = total;
3925
+ onProgress(new ProgressEvent("progress", { lengthComputable, loaded, total }));
3926
+ }
3927
+ return Promise.resolve(file);
3928
+ }
3929
+ }
3930
+
3931
+ ///////////////////////////////////////////////////////////////////////////////
3932
+ // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
3933
+ // All rights reserved.
3934
+ //
3935
+ // This software and its documentation and related materials are owned by
3936
+ // the Alliance. The software may only be incorporated into application
3937
+ // programs owned by members of the Alliance, subject to a signed
3938
+ // Membership Agreement and Supplemental Software License Agreement with the
3939
+ // Alliance. The structure and organization of this software are the valuable
3940
+ // trade secrets of the Alliance and its suppliers. The software is also
3941
+ // protected by copyright law and international treaty provisions. Application
3942
+ // programs incorporating this software must include the following statement
3943
+ // with their copyright notices:
3944
+ //
3945
+ // This application incorporates Open Design Alliance software pursuant to a
3946
+ // license agreement with Open Design Alliance.
3947
+ // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
3948
+ // All rights reserved.
3949
+ //
3950
+ // By use of this software, its documentation or related materials, you
3951
+ // acknowledge and accept the above terms.
3952
+ ///////////////////////////////////////////////////////////////////////////////
3953
+ class VSFFileLoader extends Loader {
3858
3954
  constructor(viewer) {
3859
3955
  super();
3860
3956
  this.viewer = viewer;
3861
3957
  }
3862
3958
  isSupport(file, format) {
3863
- return file instanceof ArrayBuffer && /vsf$/i.test(format);
3959
+ return ((typeof file === "string" || file instanceof globalThis.File || file instanceof ArrayBuffer) &&
3960
+ /vsf$/i.test(format));
3864
3961
  }
3865
- load(buffer, format) {
3962
+ async load(file, format, params) {
3866
3963
  if (!this.viewer.visualizeJs)
3867
- return Promise.resolve(this);
3964
+ return this;
3965
+ const progress = (event) => {
3966
+ const { lengthComputable, loaded, total } = event;
3967
+ const progress = lengthComputable ? loaded / total : 1;
3968
+ this.viewer.emitEvent({ type: "geometryprogress", data: progress, file });
3969
+ };
3970
+ const loader = new FileLoader();
3971
+ loader.setRequestHeader(params.requestHeader);
3972
+ loader.setWithCredentials(params.withCredentials);
3973
+ loader.setAbortSignal(this.abortController.signal);
3974
+ const buffer = await loader.load(file, progress);
3975
+ const data = new Uint8Array(buffer);
3868
3976
  const visLib = this.viewer.visLib();
3869
3977
  const visViewer = visLib.getViewer();
3870
- const data = new Uint8Array(buffer);
3871
3978
  visViewer.parseFile(data);
3872
3979
  this.viewer.syncOpenCloudVisualStyle(false);
3873
3980
  this.viewer.syncOptions();
3874
3981
  this.viewer.syncOverlay();
3875
3982
  this.viewer.resize();
3876
- this.viewer.emitEvent({ type: "geometryprogress", data: 1, file: buffer });
3877
- this.viewer.emitEvent({ type: "databasechunk", data, file: buffer });
3878
- return Promise.resolve(this);
3983
+ this.viewer.emitEvent({ type: "databasechunk", data, file });
3984
+ return this;
3879
3985
  }
3880
3986
  }
3881
3987
 
@@ -3970,28 +4076,38 @@
3970
4076
  // By use of this software, its documentation or related materials, you
3971
4077
  // acknowledge and accept the above terms.
3972
4078
  ///////////////////////////////////////////////////////////////////////////////
3973
- class VSFXBufferLoader extends Loader {
4079
+ class VSFXFileLoader extends Loader {
3974
4080
  constructor(viewer) {
3975
4081
  super();
3976
4082
  this.viewer = viewer;
3977
4083
  }
3978
4084
  isSupport(file, format) {
3979
- return file instanceof ArrayBuffer && /vsfx$/i.test(format);
4085
+ return ((typeof file === "string" || file instanceof globalThis.File || file instanceof ArrayBuffer) &&
4086
+ /vsfx$/i.test(format));
3980
4087
  }
3981
- load(buffer, format) {
4088
+ async load(file, format, params) {
3982
4089
  if (!this.viewer.visualizeJs)
3983
- return Promise.resolve(this);
4090
+ return this;
4091
+ const progress = (event) => {
4092
+ const { lengthComputable, loaded, total } = event;
4093
+ const progress = lengthComputable ? loaded / total : 1;
4094
+ this.viewer.emitEvent({ type: "geometryprogress", data: progress, file });
4095
+ };
4096
+ const loader = new FileLoader();
4097
+ loader.setRequestHeader(params.requestHeader);
4098
+ loader.setWithCredentials(params.withCredentials);
4099
+ loader.setAbortSignal(this.abortController.signal);
4100
+ const buffer = await loader.load(file, progress);
4101
+ const data = new Uint8Array(buffer);
3984
4102
  const visLib = this.viewer.visLib();
3985
4103
  const visViewer = visLib.getViewer();
3986
- const data = new Uint8Array(buffer);
3987
4104
  visViewer.parseVsfx(data);
3988
4105
  this.viewer.syncOpenCloudVisualStyle(false);
3989
4106
  this.viewer.syncOptions();
3990
4107
  this.viewer.syncOverlay();
3991
4108
  this.viewer.resize();
3992
- this.viewer.emitEvent({ type: "geometryprogress", data: 1, file: buffer });
3993
- this.viewer.emitEvent({ type: "databasechunk", data, file: buffer });
3994
- return Promise.resolve(this);
4109
+ this.viewer.emitEvent({ type: "databasechunk", data, file });
4110
+ return this;
3995
4111
  }
3996
4112
  }
3997
4113
 
@@ -4431,8 +4547,7 @@
4431
4547
  * @example Implementing a custom loader.
4432
4548
  *
4433
4549
  * ```javascript
4434
- * import { Loader } from "@inweb/viewer-core";
4435
- * import { loaders, Viewer } from "@inweb/viewer-visualize";
4550
+ * import { Loader, loaders, Viewer } from "@inweb/viewer-visualize";
4436
4551
  *
4437
4552
  * class MyLoader extends Loader {
4438
4553
  * public viewer: Viewer;
@@ -4459,7 +4574,7 @@
4459
4574
  * this.viewer.syncOverlay();
4460
4575
  * this.viewer.resize();
4461
4576
  *
4462
- * this.viewer.emitEvent({ type: "databasechunk", data: model, file });
4577
+ * this.viewer.emitEvent({ type: "databasechunk", data, file });
4463
4578
  *
4464
4579
  * return Promise.resove(this);
4465
4580
  * };
@@ -4470,9 +4585,9 @@
4470
4585
  */
4471
4586
  const loaders = loadersRegistry("visualizejs");
4472
4587
  // build-in loaders
4473
- loaders.registerLoader("vsf-buffer", (viewer) => new VSFBufferLoader(viewer));
4588
+ loaders.registerLoader("vsf-file", (viewer) => new VSFFileLoader(viewer));
4474
4589
  loaders.registerLoader("vsf-cloud", (viewer) => new VSFCloudLoader(viewer));
4475
- loaders.registerLoader("vsfx-buffer", (viewer) => new VSFXBufferLoader(viewer));
4590
+ loaders.registerLoader("vsfx-file", (viewer) => new VSFXFileLoader(viewer));
4476
4591
  loaders.registerLoader("vsfx-cloud", (viewer) => new VSFXCloudLoader(viewer));
4477
4592
  loaders.registerLoader("vsfx-cloud-streaming", (viewer) => new VSFXCloudStreamingLoader(viewer));
4478
4593
  loaders.registerLoader("vsfx-cloud-partial", (viewer) => new VSFXCloudPartialLoader(viewer));
@@ -19960,6 +20075,68 @@
19960
20075
  device.delete();
19961
20076
  this.update();
19962
20077
  }
20078
+ /**
20079
+ * Loads a file into the viewer.
20080
+ *
20081
+ * The viewer must be {@link initialize | initialized} before opening the file. Otherwise, `open()` does
20082
+ * nothing.
20083
+ *
20084
+ * This method requires a `Client` instance to be specified to load file from the Open Cloud Server.
20085
+ * The file geometry data on the Open Cloud Server must be converted into a `vsfx` format, otherwise an
20086
+ * exception will be thrown.
20087
+ *
20088
+ * For files from Open Cloud Server, the default model will be loaded. If there is no default model,
20089
+ * first availiable model will be loaded. If no models are found in the file, an exception will be
20090
+ * thrown.
20091
+ *
20092
+ * For URLs, the file extension is used to determine the file format. For a `ArrayBuffer` and `Data
20093
+ * URL`, a file format must be specified using `params.format` parameter (see below). If no appropriate
20094
+ * loader is found for the specified format, an exception will be thrown.
20095
+ *
20096
+ * If there was an active dragger before opening the file, it will be deactivated. After opening the
20097
+ * file, you must manually activate the required dragger.
20098
+ *
20099
+ * To open a large files, enable {@link IOptions.enablePartialMode | partial streaming} mode before
20100
+ * opening. Partial streaming is only supported when opening files from an Open Cloud Server, but not
20101
+ * local files and URLs. Example:
20102
+ *
20103
+ * ```javascript
20104
+ * viewer.options.enableStreamingMode = true;
20105
+ * viewer.options.enablePartialMode = true;
20106
+ * await viewer.open(file);
20107
+ * ```
20108
+ *
20109
+ * Fires:
20110
+ *
20111
+ * - {@link OpenEvent | open}
20112
+ * - {@link GeometryStartEvent | geometrystart}
20113
+ * - {@link GeometryProgressEvent | geometryprogress}
20114
+ * - {@link DatabaseChunkEvent | databasechunk}
20115
+ * - {@link GeometryChunkEvent | geometrychunk}
20116
+ * - {@link GeometryEndEvent | geometryend}
20117
+ * - {@link GeometryErrorEvent | geometryerror}
20118
+ *
20119
+ * @param file - File to load. Can be one of:
20120
+ *
20121
+ * - `File`, `Assembly` or `Model` instance from the Open Cloud Server
20122
+ * - File `URL` string
20123
+ * - {@link https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/Data_URIs | Data URL} string
20124
+ * - {@link https://developer.mozilla.org/docs/Web/API/File | Web API File} object
20125
+ * - {@link https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer | ArrayBuffer}
20126
+ * object
20127
+ *
20128
+ * @param params - Loading parameters.
20129
+ * @param params.format - File format string. Required when loading a file as `ArrayBuffer` or `Data
20130
+ * URL`.
20131
+ * @param params.mode - Reserved for future use.
20132
+ * @param params.requestHeader - The
20133
+ * {@link https://developer.mozilla.org/docs/Glossary/Request_header | request header} used in HTTP
20134
+ * request.
20135
+ * @param params.withCredentials - Whether the HTTP request uses credentials such as cookies,
20136
+ * authorization headers or TLS client certificates. See
20137
+ * {@link https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/withCredentials | XMLHttpRequest.withCredentials}
20138
+ * for more details.
20139
+ */
19963
20140
  async open(file, params = {}) {
19964
20141
  if (!this.visualizeJs)
19965
20142
  return this;
@@ -20002,8 +20179,11 @@
20002
20179
  }
20003
20180
  /**
20004
20181
  * Deprecated since `26.4`. Use {@link open | open()} instead.
20182
+ *
20183
+ * @deprecated
20005
20184
  */
20006
20185
  openVsfFile(buffer) {
20186
+ console.warn("Viewer.openVsfFile() has been deprecated since 26.4 and will be removed in a future release, use Viewer.open() instead.");
20007
20187
  if (!this.visualizeJs)
20008
20188
  return this;
20009
20189
  this.cancel();
@@ -20030,26 +20210,12 @@
20030
20210
  return this;
20031
20211
  }
20032
20212
  /**
20033
- * Loads a `VSFX` file into the viewer.
20034
- *
20035
- * This method does not support {@link IOptions.enableStreamingMode | streaming} or
20036
- * {@link IOptions.enablePartialMode | partial streaming} mode.
20037
- *
20038
- * If there was an active dragger before opening the file, it will be deactivated. After opening the
20039
- * file, you must manually activate the required dragger.
20040
- *
20041
- * Fires:
20042
- *
20043
- * - {@link OpenEvent | open}
20044
- * - {@link GeometryStartEvent | geometrystart}
20045
- * - {@link GeometryProgressEvent | geometryprogress}
20046
- * - {@link DatabaseChunkEvent | databasechunk}
20047
- * - {@link GeometryEndEvent | geometryend}
20048
- * - {@link GeometryErrorEvent | geometryerror}
20213
+ * Deprecated since `26.4`. Use {@link open | open()} instead.
20049
20214
  *
20050
- * @param buffer - Binary data buffer to load.
20215
+ * @deprecated
20051
20216
  */
20052
20217
  openVsfxFile(buffer) {
20218
+ console.warn("Viewer.openVsfxFile() has been deprecated since 26.4 and will be removed in a future release, use Viewer.open() instead.");
20053
20219
  if (!this.visualizeJs)
20054
20220
  return this;
20055
20221
  this.cancel();
@@ -20293,6 +20459,7 @@
20293
20459
  exports.CanvasEvents = CanvasEvents;
20294
20460
  exports.Component = Component;
20295
20461
  exports.Dragger = Dragger;
20462
+ exports.FileLoader = FileLoader;
20296
20463
  exports.Loader = Loader;
20297
20464
  exports.Markup = KonvaMarkup;
20298
20465
  exports.OdBaseDragger = OdBaseDragger;