3dviewer-sdk 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -120,7 +120,7 @@ var NodeModule = class {
120
120
 
121
121
  // src/modules/files.module.ts
122
122
  var DEFAULT_API_BASE_URL = "https://dev.3dviewer.anybim.vn";
123
- var DEFAULT_VIEWER_ORIGIN = "https://dev.3dviewer.anybim.vn";
123
+ var DEFAULT_VIEWER_ORIGIN = "http://localhost:3000";
124
124
  var FilesModule = class {
125
125
  constructor(viewer) {
126
126
  this.viewer = viewer;
@@ -168,12 +168,12 @@ var FilesModule = class {
168
168
  });
169
169
  }
170
170
  // Trigger conversion flow and resolve final viewer metadata.
171
- async convert(file) {
171
+ async convert(file, options = {}) {
172
172
  const target = this.resolveFile(file);
173
173
  return this.withOperation({ stage: "converting", message: "Converting file..." }, async () => {
174
174
  this.viewer._emit("files:conversion:start", { fileName: target.name });
175
175
  try {
176
- const prepared = await this.convertInternal(target);
176
+ const prepared = await this.convertInternal(target, options);
177
177
  this.viewer._emit("files:conversion:success", prepared);
178
178
  return prepared;
179
179
  } catch (e) {
@@ -183,14 +183,28 @@ var FilesModule = class {
183
183
  });
184
184
  }
185
185
  // Convenience API: upload first, then convert in one call.
186
- async prepare(file) {
186
+ async prepare(file, options = {}) {
187
187
  const target = this.resolveFile(file);
188
188
  return this.withOperation({ stage: "uploading", message: "Preparing file..." }, async () => {
189
189
  await this.uploadInternal(target);
190
- const prepared = await this.convertInternal(target);
190
+ const prepared = await this.convertInternal(target, options);
191
191
  return prepared;
192
192
  });
193
193
  }
194
+ // Trigger the newer downloadUrl-based conversion flow.
195
+ async convertV2(options) {
196
+ return this.withOperation({ stage: "converting", message: "Converting file..." }, async () => {
197
+ this.viewer._emit("files:conversion:start", { fileName: options.filename });
198
+ try {
199
+ const prepared = await this.convertV2Internal(options);
200
+ this.viewer._emit("files:conversion:success", prepared);
201
+ return prepared;
202
+ } catch (e) {
203
+ this.viewer._emit("files:conversion:error", { fileName: options.filename, error: this.toErrorMessage(e) });
204
+ throw e;
205
+ }
206
+ });
207
+ }
194
208
  // Open iframe with an already prepared viewer URL.
195
209
  open(input) {
196
210
  const url = input.url;
@@ -204,11 +218,11 @@ var FilesModule = class {
204
218
  }
205
219
  }
206
220
  // Full pipeline: upload + convert + open iframe.
207
- async render(file) {
221
+ async render(file, options = {}) {
208
222
  const target = this.resolveFile(file);
209
223
  return this.withOperation({ stage: "uploading", message: "Uploading + converting + opening..." }, async () => {
210
224
  await this.upload(target);
211
- const prepared = await this.convert(target);
225
+ const prepared = await this.convert(target, options);
212
226
  this.updateState({ stage: "rendering", message: "Opening viewer..." });
213
227
  this.open(prepared);
214
228
  this.viewer._emit("files:load:success", prepared);
@@ -301,10 +315,11 @@ var FilesModule = class {
301
315
  }
302
316
  }
303
317
  // Build StreamFile payload compatible with conversion service.
304
- buildCachePayload(file, baseFileId) {
318
+ buildCachePayload(file, baseFileId, options = {}) {
305
319
  const createdDate = (/* @__PURE__ */ new Date()).toISOString();
306
320
  return {
307
321
  filename: file.name,
322
+ ...options.downloadUrl ? { downloadUrl: options.downloadUrl } : {},
308
323
  baseFileId,
309
324
  baseMajorRev: 0,
310
325
  baseMinorRev: 0,
@@ -347,11 +362,31 @@ var FilesModule = class {
347
362
  attemptedConvertTimes: 0
348
363
  };
349
364
  }
365
+ // Build payload for POST /api/StreamFile/convert.
366
+ buildConvertV2Payload(options) {
367
+ var _a, _b;
368
+ const convertOptions = {
369
+ convert3DModel: 1,
370
+ convert2DSheet: 1,
371
+ extractProperties: 1,
372
+ childModels: 0,
373
+ ...options.convertOptions
374
+ };
375
+ return {
376
+ filename: options.filename,
377
+ originalFilePath: options.originalFilePath,
378
+ convertOptions,
379
+ downloadUrl: options.downloadUrl,
380
+ baseFileId: options.baseFileId,
381
+ baseMajorRev: (_a = options.baseMajorRev) != null ? _a : 0,
382
+ baseMinorRev: (_b = options.baseMinorRev) != null ? _b : 0
383
+ };
384
+ }
350
385
  // Submit conversion/caching request and return service response.
351
- async cacheFile(file, baseFileId) {
386
+ async cacheFile(file, baseFileId, options = {}) {
352
387
  const hostConversion = await this.resolveHostConversion();
353
388
  const url = `${hostConversion}/api/StreamFile?overwrite=true&ignore_line_weight=1`;
354
- const payload = this.buildCachePayload(file, baseFileId);
389
+ const payload = this.buildCachePayload(file, baseFileId, options);
355
390
  const response = await fetch(url, {
356
391
  method: "POST",
357
392
  headers: {
@@ -367,17 +402,45 @@ var FilesModule = class {
367
402
  }
368
403
  return await response.json();
369
404
  }
405
+ // Submit conversion request to the newer downloadUrl-based endpoint.
406
+ async cacheFileV2(options) {
407
+ const hostConversion = await this.resolveHostConversion();
408
+ const params = new URLSearchParams();
409
+ if (typeof options.overwrite === "boolean") {
410
+ params.set("overwrite", String(options.overwrite));
411
+ }
412
+ if (options.project) {
413
+ params.set("project", options.project);
414
+ }
415
+ const query = params.toString();
416
+ const url = `${hostConversion}/api/StreamFile/convert${query ? `?${query}` : ""}`;
417
+ const payload = this.buildConvertV2Payload(options);
418
+ const response = await fetch(url, {
419
+ method: "POST",
420
+ headers: {
421
+ "Content-Type": "application/json",
422
+ Accept: "application/json"
423
+ },
424
+ body: JSON.stringify(payload)
425
+ });
426
+ if (!response.ok) {
427
+ throw new Error(
428
+ `Cache/convert v2 failed (${response.status} ${response.statusText})`
429
+ );
430
+ }
431
+ return await response.json();
432
+ }
370
433
  // Convert file and generate final iframe URL with query string.
371
- async convertInternal(file) {
434
+ async convertInternal(file, options = {}) {
372
435
  var _a, _b, _c, _d;
373
436
  this.updateState({ stage: "converting", message: "Converting file..." });
374
437
  const uploadSession = this.getUploadSessionForFile(file) || this.createUploadSession(file);
375
438
  const seedBaseFileId = uploadSession.baseFileId;
376
- const cacheResult = await this.cacheFile(file, seedBaseFileId);
439
+ const cacheResult = await this.cacheFile(file, seedBaseFileId, options);
377
440
  const baseFileId = (_a = cacheResult.baseFileId) != null ? _a : seedBaseFileId;
378
441
  const baseMajorRev = (_b = cacheResult.baseMajorRev) != null ? _b : 0;
379
442
  const baseMinorRev = (_c = cacheResult.baseMinorRev) != null ? _c : 0;
380
- const fileName = cacheResult.filename || file.name;
443
+ const fileName = cacheResult.filename || cacheResult.fileName || file.name;
381
444
  const cacheListItem = { baseFileId, baseMajorRev, baseMinorRev, fileName };
382
445
  if (cacheResult.cacheStatus !== 2) {
383
446
  throw new Error(`Conversion not ready after first request (cacheStatus=${(_d = cacheResult.cacheStatus) != null ? _d : "unknown"})`);
@@ -388,6 +451,24 @@ var FilesModule = class {
388
451
  const url = `${viewerBase}${viewerPath}?${query}`;
389
452
  return { baseFileId, baseMajorRev, baseMinorRev, fileName, query, url };
390
453
  }
454
+ async convertV2Internal(options) {
455
+ var _a, _b, _c, _d, _e;
456
+ this.updateState({ stage: "converting", message: "Converting file..." });
457
+ const cacheResult = await this.cacheFileV2(options);
458
+ const baseFileId = (_a = cacheResult.baseFileId) != null ? _a : options.baseFileId;
459
+ const baseMajorRev = (_c = (_b = cacheResult.baseMajorRev) != null ? _b : options.baseMajorRev) != null ? _c : 0;
460
+ const baseMinorRev = (_e = (_d = cacheResult.baseMinorRev) != null ? _d : options.baseMinorRev) != null ? _e : 0;
461
+ const fileName = cacheResult.filename || cacheResult.fileName || options.filename;
462
+ if (cacheResult.cacheStatus !== void 0 && cacheResult.cacheStatus !== 2) {
463
+ throw new Error(`Conversion not ready after v2 request (cacheStatus=${cacheResult.cacheStatus})`);
464
+ }
465
+ const cacheListItem = { baseFileId, baseMajorRev, baseMinorRev, fileName };
466
+ const query = new URLSearchParams({ fileList: JSON.stringify([cacheListItem]) }).toString();
467
+ const viewerBase = this.resolveViewerOrigin();
468
+ const viewerPath = this.resolveViewerPath();
469
+ const url = `${viewerBase}${viewerPath}?${query}`;
470
+ return { baseFileId, baseMajorRev, baseMinorRev, fileName, query, url };
471
+ }
391
472
  // Update internal loading state and emit state event.
392
473
  updateState(next) {
393
474
  const elapsedMs = this.operationStartTime > 0 ? Date.now() - this.operationStartTime : 0;
@@ -0,0 +1,13 @@
1
+ import { Viewer3D } from "../viewer";
2
+ export declare class CameraModule {
3
+ private viewer;
4
+ on: {
5
+ home: (cb: (payload: {
6
+ timestamp: number;
7
+ }) => void) => () => void;
8
+ };
9
+ constructor(viewer: Viewer3D);
10
+ zoomIn(percent: number): void;
11
+ zoomOut(percent: number): void;
12
+ home(): void;
13
+ }
@@ -0,0 +1,18 @@
1
+ import { ViewerMessageType } from "../contracts/messages";
2
+ export class CameraModule {
3
+ constructor(viewer) {
4
+ this.viewer = viewer;
5
+ this.on = {
6
+ home: (cb) => this.viewer._on("camera:home", cb),
7
+ };
8
+ }
9
+ zoomIn(percent) {
10
+ this.viewer.postToViewer(ViewerMessageType.ZOOM, { action: "in", percent });
11
+ }
12
+ zoomOut(percent) {
13
+ this.viewer.postToViewer(ViewerMessageType.ZOOM, { action: "out", percent });
14
+ }
15
+ home() {
16
+ this.viewer.postToViewer(ViewerMessageType.HOME, {});
17
+ }
18
+ }
@@ -0,0 +1,106 @@
1
+ import type { LoadStatePayload, PreparedViewerData } from "../contracts/events";
2
+ import { Viewer3D } from "../viewer";
3
+ export declare type FilesConfig = {
4
+ baseUrl?: string;
5
+ viewerPath?: string;
6
+ uploadPath?: string;
7
+ };
8
+ export declare type ConvertOptions = {
9
+ downloadUrl?: string;
10
+ };
11
+ export declare type ConvertV2Options = {
12
+ filename: string;
13
+ originalFilePath: string;
14
+ downloadUrl: string;
15
+ baseFileId: string;
16
+ baseMajorRev?: number;
17
+ baseMinorRev?: number;
18
+ overwrite?: boolean;
19
+ project?: string;
20
+ convertOptions?: Partial<StreamConvertOptions>;
21
+ };
22
+ declare type StreamConvertOptions = {
23
+ convert3DModel: number;
24
+ convert2DSheet: number;
25
+ extractProperties: number;
26
+ childModels: number;
27
+ };
28
+ export declare class FilesModule {
29
+ private viewer;
30
+ on: {
31
+ state: (cb: (payload: LoadStatePayload) => void) => () => void;
32
+ uploadStart: (cb: (payload: {
33
+ fileName: string;
34
+ }) => void) => () => void;
35
+ uploadSuccess: (cb: (payload: {
36
+ fileName: string;
37
+ baseFileId: string;
38
+ }) => void) => () => void;
39
+ uploadError: (cb: (payload: {
40
+ fileName: string;
41
+ error: string;
42
+ }) => void) => () => void;
43
+ conversionStart: (cb: (payload: {
44
+ fileName: string;
45
+ }) => void) => () => void;
46
+ conversionSuccess: (cb: (payload: PreparedViewerData) => void) => () => void;
47
+ conversionError: (cb: (payload: {
48
+ fileName: string;
49
+ error: string;
50
+ }) => void) => () => void;
51
+ renderStart: (cb: (payload: {
52
+ url: string;
53
+ }) => void) => () => void;
54
+ renderSuccess: (cb: (payload: {
55
+ url: string;
56
+ }) => void) => () => void;
57
+ renderError: (cb: (payload: {
58
+ url?: string;
59
+ error: string;
60
+ }) => void) => () => void;
61
+ loadSuccess: (cb: (payload: PreparedViewerData) => void) => () => void;
62
+ loadError: (cb: (payload: {
63
+ error: string;
64
+ }) => void) => () => void;
65
+ };
66
+ private config;
67
+ private operationStartTime;
68
+ private state;
69
+ private lastUploadSession;
70
+ constructor(viewer: Viewer3D);
71
+ setConfig(next: FilesConfig): void;
72
+ getState(): LoadStatePayload;
73
+ upload(file?: File): Promise<{
74
+ fileName: string;
75
+ baseFileId: string;
76
+ }>;
77
+ convert(file?: File, options?: ConvertOptions): Promise<PreparedViewerData>;
78
+ prepare(file?: File, options?: ConvertOptions): Promise<PreparedViewerData>;
79
+ convertV2(options: ConvertV2Options): Promise<PreparedViewerData>;
80
+ open(input: PreparedViewerData | {
81
+ url: string;
82
+ }): void;
83
+ render(file?: File, options?: ConvertOptions): Promise<PreparedViewerData>;
84
+ private resolveFile;
85
+ private normalizeBaseUrl;
86
+ private resolveBaseUrl;
87
+ private resolveViewerPath;
88
+ private resolveViewerOrigin;
89
+ private resolveHostConversion;
90
+ private getUploadPath;
91
+ private fileSignature;
92
+ private createBaseFileId;
93
+ private createUploadSession;
94
+ private getUploadSessionForFile;
95
+ private uploadInternal;
96
+ private buildCachePayload;
97
+ private buildConvertV2Payload;
98
+ private cacheFile;
99
+ private cacheFileV2;
100
+ private convertInternal;
101
+ private convertV2Internal;
102
+ private updateState;
103
+ private withOperation;
104
+ private toErrorMessage;
105
+ }
106
+ export {};