3dviewer-sdk 1.0.1 → 1.0.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/dist/viewer.js ADDED
@@ -0,0 +1,277 @@
1
+ // sdk/src/viewer.ts
2
+ import { Emitter } from "./core/emitter";
3
+ import { CameraModule } from "./modules/camera.module";
4
+ import { InteractionModule } from "./modules/interaction.module";
5
+ import { NodeModule } from "./modules/node.module";
6
+ import { FilesModule } from "./modules/files.module";
7
+ import { ToolbarModule } from "./modules/toolbar.module";
8
+ import { ModelTreeModule } from "./modules/model-tree.module";
9
+ import { MarkupModule } from "./modules/markup.module";
10
+ import { LanguageModule } from "./modules/language.module";
11
+ import { ViewerMessageType, ViewerMessageSource, } from "./contracts/messages";
12
+ export class Viewer3D {
13
+ constructor(options) {
14
+ this.options = options;
15
+ this.containerEl = null;
16
+ this.iframeEl = null;
17
+ this.initialized = false;
18
+ this.emitter = new Emitter();
19
+ this.handleMessage = (event) => {
20
+ var _a, _b, _c, _d;
21
+ const data = event.data;
22
+ if (!data || typeof data !== "object")
23
+ return;
24
+ switch (data.type) {
25
+ case ViewerMessageType.HOME_CLICK:
26
+ this._emit("camera:home", { timestamp: Date.now() });
27
+ break;
28
+ case ViewerMessageType.NODE_SELECT:
29
+ this._emit("node:select", { nodeId: String((_b = (_a = data.payload) === null || _a === void 0 ? void 0 : _a.nodeId) !== null && _b !== void 0 ? _b : ""), timestamp: Date.now() });
30
+ break;
31
+ case ViewerMessageType.PAN_CHANGE:
32
+ this._emit("interaction:pan-change", { enabled: Boolean((_c = data.payload) === null || _c === void 0 ? void 0 : _c.enabled) });
33
+ break;
34
+ case ViewerMessageType.PDF_PLAN_MODE: {
35
+ const payload = data.payload;
36
+ this._emit("toolbar:pdf-plan-mode", {
37
+ mode: "plan",
38
+ timestamp: Number(payload === null || payload === void 0 ? void 0 : payload.timestamp) || Date.now(),
39
+ });
40
+ break;
41
+ }
42
+ case ViewerMessageType.PDF_DOCUMENT_MODE: {
43
+ const payload = data.payload;
44
+ this._emit("toolbar:pdf-document-mode", {
45
+ mode: "document",
46
+ timestamp: Number(payload === null || payload === void 0 ? void 0 : payload.timestamp) || Date.now(),
47
+ });
48
+ break;
49
+ }
50
+ case ViewerMessageType.PDF_FIRST_PAGE: {
51
+ const payload = data.payload;
52
+ this._emit("toolbar:pdf-first-page", {
53
+ timestamp: Number(payload === null || payload === void 0 ? void 0 : payload.timestamp) || Date.now(),
54
+ });
55
+ break;
56
+ }
57
+ case ViewerMessageType.PDF_PREVIOUS_PAGE: {
58
+ const payload = data.payload;
59
+ this._emit("toolbar:pdf-previous-page", {
60
+ timestamp: Number(payload === null || payload === void 0 ? void 0 : payload.timestamp) || Date.now(),
61
+ });
62
+ break;
63
+ }
64
+ case ViewerMessageType.PDF_NEXT_PAGE: {
65
+ const payload = data.payload;
66
+ this._emit("toolbar:pdf-next-page", {
67
+ timestamp: Number(payload === null || payload === void 0 ? void 0 : payload.timestamp) || Date.now(),
68
+ });
69
+ break;
70
+ }
71
+ case ViewerMessageType.PDF_LAST_PAGE: {
72
+ const payload = data.payload;
73
+ this._emit("toolbar:pdf-last-page", {
74
+ timestamp: Number(payload === null || payload === void 0 ? void 0 : payload.timestamp) || Date.now(),
75
+ });
76
+ break;
77
+ }
78
+ case ViewerMessageType.PDF_CURRENT_PAGE: {
79
+ const payload = data.payload;
80
+ if (!payload)
81
+ break;
82
+ this._emit("toolbar:pdf-current-page", {
83
+ pageIndex: Number(payload.pageIndex) || 0,
84
+ pageNumber: Number(payload.pageNumber) || 1,
85
+ timestamp: Number(payload.timestamp) || Date.now(),
86
+ });
87
+ break;
88
+ }
89
+ case ViewerMessageType.TREE_NODE_IDS: {
90
+ const payload = data.payload;
91
+ if (!payload || !payload.requestId || !Array.isArray(payload.nodeIds))
92
+ break;
93
+ this._emit("modelTree:node-ids", {
94
+ requestId: String(payload.requestId),
95
+ nodeIds: payload.nodeIds.map(String),
96
+ timestamp: Number(payload.timestamp) || Date.now(),
97
+ });
98
+ break;
99
+ }
100
+ case ViewerMessageType.SHEETS_LIST: {
101
+ const payload = data.payload;
102
+ if (!payload || !payload.requestId || !Array.isArray(payload.sheets))
103
+ break;
104
+ this._emit("sheets:list", {
105
+ requestId: String(payload.requestId),
106
+ sheets: payload.sheets.map((sheet) => {
107
+ var _a;
108
+ return ({
109
+ id: sheet.id,
110
+ name: String((_a = sheet.name) !== null && _a !== void 0 ? _a : ""),
111
+ is3D: Boolean(sheet.is3D),
112
+ viewId: sheet.viewId ? String(sheet.viewId) : undefined,
113
+ });
114
+ }),
115
+ activeSheetId: (_d = payload.activeSheetId) !== null && _d !== void 0 ? _d : null,
116
+ timestamp: Number(payload.timestamp) || Date.now(),
117
+ });
118
+ break;
119
+ }
120
+ case ViewerMessageType.MARKUP_LIST: {
121
+ const payload = data.payload;
122
+ if (!payload || !payload.requestId || !Array.isArray(payload.markups))
123
+ break;
124
+ this._emit("markup:list", {
125
+ requestId: String(payload.requestId),
126
+ markups: payload.markups.map((markup) => {
127
+ var _a, _b;
128
+ return ({
129
+ id: String(markup.id),
130
+ viewId: String(markup.viewId),
131
+ viewName: markup.viewName ? String(markup.viewName) : undefined,
132
+ title: String((_a = markup.title) !== null && _a !== void 0 ? _a : ""),
133
+ type: String((_b = markup.type) !== null && _b !== void 0 ? _b : ""),
134
+ shapeName: markup.shapeName ? String(markup.shapeName) : undefined,
135
+ createdDate: markup.createdDate ? String(markup.createdDate) : undefined,
136
+ modifiedDate: markup.modifiedDate ? String(markup.modifiedDate) : undefined,
137
+ createdBy: markup.createdBy ? String(markup.createdBy) : undefined,
138
+ lastModifiedBy: markup.lastModifiedBy ? String(markup.lastModifiedBy) : undefined,
139
+ });
140
+ }),
141
+ timestamp: Number(payload.timestamp) || Date.now(),
142
+ });
143
+ break;
144
+ }
145
+ case ViewerMessageType.MARKUP_SAVE_RESULT: {
146
+ const payload = data.payload;
147
+ if (!payload || !payload.requestId)
148
+ break;
149
+ this._emit("markup:save", {
150
+ requestId: String(payload.requestId),
151
+ success: Boolean(payload.success),
152
+ error: payload.error ? String(payload.error) : undefined,
153
+ timestamp: Number(payload.timestamp) || Date.now(),
154
+ });
155
+ break;
156
+ }
157
+ case ViewerMessageType.MARKUP_CANCEL_RESULT: {
158
+ const payload = data.payload;
159
+ if (!payload || !payload.requestId)
160
+ break;
161
+ this._emit("markup:cancel", {
162
+ requestId: String(payload.requestId),
163
+ success: Boolean(payload.success),
164
+ error: payload.error ? String(payload.error) : undefined,
165
+ timestamp: Number(payload.timestamp) || Date.now(),
166
+ });
167
+ break;
168
+ }
169
+ default:
170
+ break;
171
+ }
172
+ };
173
+ this.camera = new CameraModule(this);
174
+ this.interaction = new InteractionModule(this);
175
+ this.node = new NodeModule(this);
176
+ this.files = new FilesModule(this);
177
+ this.toolbar = new ToolbarModule(this);
178
+ this.modelTree = new ModelTreeModule(this);
179
+ this.markup = new MarkupModule(this);
180
+ this.language = new LanguageModule(this);
181
+ }
182
+ // ===== options helpers =====
183
+ getOptions() {
184
+ return this.options;
185
+ }
186
+ patchOptions(next) {
187
+ this.options = { ...this.options, ...next };
188
+ }
189
+ getUrl() {
190
+ var _a;
191
+ return (_a = this.options.url) !== null && _a !== void 0 ? _a : null;
192
+ }
193
+ // ===== lifecycle =====
194
+ init() {
195
+ if (this.initialized)
196
+ return;
197
+ this.containerEl =
198
+ typeof this.options.container === "string"
199
+ ? document.querySelector(this.options.container)
200
+ : this.options.container;
201
+ if (!this.containerEl)
202
+ throw new Error("Container element not found");
203
+ window.addEventListener("message", this.handleMessage);
204
+ this.initialized = true;
205
+ }
206
+ async render(file) {
207
+ this.ensureInit();
208
+ if (this.iframeEl)
209
+ return;
210
+ // If URL is missing, render falls back to files pipeline.
211
+ if (!this.options.url)
212
+ return this.files.render(file);
213
+ const iframe = document.createElement("iframe");
214
+ iframe.src = this.options.url;
215
+ iframe.style.border = "none";
216
+ iframe.style.width = this.options.width || "100%";
217
+ iframe.style.height = this.options.height || "100%";
218
+ iframe.width = this.options.width || "100%";
219
+ iframe.height = this.options.height || "100%";
220
+ if (this.options.sandbox)
221
+ iframe.setAttribute("sandbox", this.options.sandbox);
222
+ this.containerEl.appendChild(iframe);
223
+ this.iframeEl = iframe;
224
+ }
225
+ open(url) {
226
+ this.ensureInit();
227
+ this.options.url = url;
228
+ if (!this.iframeEl) {
229
+ this.render();
230
+ return;
231
+ }
232
+ this.iframeEl.src = url;
233
+ }
234
+ destroy() {
235
+ // remove listener using the same function reference
236
+ window.removeEventListener("message", this.handleMessage);
237
+ // remove iframe
238
+ if (this.iframeEl && this.containerEl) {
239
+ try {
240
+ this.containerEl.removeChild(this.iframeEl);
241
+ }
242
+ catch {
243
+ // ignore
244
+ }
245
+ }
246
+ this.iframeEl = null;
247
+ this.containerEl = null;
248
+ this.initialized = false;
249
+ }
250
+ ensureInit() {
251
+ if (!this.initialized)
252
+ throw new Error("Call viewer.init() before using viewer");
253
+ }
254
+ // ===== typed internal events used by modules =====
255
+ _on(event, cb) {
256
+ return this.emitter.on(event, cb);
257
+ }
258
+ _off(event, cb) {
259
+ this.emitter.off(event, cb);
260
+ }
261
+ _emit(event, payload) {
262
+ this.emitter.emit(event, payload);
263
+ }
264
+ // ===== postMessage bridge =====
265
+ postToViewer(type, payload) {
266
+ var _a;
267
+ if (!((_a = this.iframeEl) === null || _a === void 0 ? void 0 : _a.contentWindow))
268
+ return;
269
+ const message = {
270
+ source: ViewerMessageSource.SDK,
271
+ type,
272
+ payload,
273
+ };
274
+ const targetOrigin = this.options.allowedOrigin || "*";
275
+ this.iframeEl.contentWindow.postMessage(message, targetOrigin);
276
+ }
277
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "3dviewer-sdk",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [