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/contracts/events.d.ts +97 -0
- package/dist/contracts/events.js +1 -0
- package/dist/contracts/messages.d.ts +153 -0
- package/dist/contracts/messages.js +49 -0
- package/dist/core/emitter.d.ts +7 -0
- package/dist/core/emitter.js +31 -0
- package/dist/index.d.mts +28 -4
- package/dist/index.d.ts +28 -4
- package/dist/index.js +94 -13
- package/dist/index.mjs +94 -13
- package/dist/modules/camera.module.d.ts +13 -0
- package/dist/modules/camera.module.js +18 -0
- package/dist/modules/files.module.d.ts +106 -0
- package/dist/modules/files.module.js +394 -0
- package/dist/modules/interaction.module.d.ts +28 -0
- package/dist/modules/interaction.module.js +63 -0
- package/dist/modules/language.module.d.ts +8 -0
- package/dist/modules/language.module.js +15 -0
- package/dist/modules/markup.module.d.ts +26 -0
- package/dist/modules/markup.module.js +96 -0
- package/dist/modules/model-tree.module.d.ts +12 -0
- package/dist/modules/model-tree.module.js +42 -0
- package/dist/modules/node.module.d.ts +11 -0
- package/dist/modules/node.module.js +6 -0
- package/dist/modules/toolbar.module.d.ts +83 -0
- package/dist/modules/toolbar.module.js +219 -0
- package/dist/viewer.d.ts +51 -0
- package/dist/viewer.js +277 -0
- package/package.json +1 -1
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 = "
|
|
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 {};
|