@netless/window-manager 0.3.8-canary.3 → 0.3.10-canary.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/window-manager",
3
- "version": "0.3.8-canary.3",
3
+ "version": "0.3.10-canary.0",
4
4
  "description": "",
5
5
  "main": "dist/index.es.js",
6
6
  "module": "dist/index.es.js",
@@ -24,7 +24,7 @@
24
24
  "@juggle/resize-observer": "^3.3.1",
25
25
  "@netless/app-docs-viewer": "^0.1.21",
26
26
  "@netless/app-media-player": "0.1.0-beta.5",
27
- "@netless/telebox-insider": "0.2.6",
27
+ "@netless/telebox-insider": "0.2.7",
28
28
  "emittery": "^0.9.2",
29
29
  "lodash": "^4.17.21",
30
30
  "p-retry": "^4.6.1",
@@ -56,6 +56,6 @@
56
56
  "typescript": "^4.3.5",
57
57
  "video.js": "^7.14.3",
58
58
  "vite": "^2.5.3",
59
- "white-web-sdk": "^2.15.8"
59
+ "white-web-sdk": "^2.15.12"
60
60
  }
61
61
  }
package/src/AppManager.ts CHANGED
@@ -160,7 +160,7 @@ export class AppManager {
160
160
  const ids = Object.keys(apps);
161
161
  this.appProxies.forEach((appProxy, id) => {
162
162
  if (!ids.includes(id)) {
163
- appProxy.destroy(true, false);
163
+ appProxy.destroy(true, false, true);
164
164
  }
165
165
  });
166
166
  };
@@ -202,10 +202,11 @@ export class AppManager {
202
202
 
203
203
  private afterAddApp(appProxy: AppProxy | undefined) {
204
204
  if (appProxy && appProxy.box) {
205
+ const box = appProxy.box;
205
206
  emitter.emit("move", {
206
207
  appId: appProxy.id,
207
- x: appProxy.box?.x,
208
- y: appProxy.box?.y,
208
+ x: box?.intrinsicX,
209
+ y: box?.intrinsicY,
209
210
  });
210
211
  }
211
212
  if (this.boxManager.minimized) {
@@ -216,7 +217,7 @@ export class AppManager {
216
217
  public async closeApp(appId: string) {
217
218
  const appProxy = this.appProxies.get(appId);
218
219
  if (appProxy) {
219
- appProxy.destroy(true, true);
220
+ appProxy.destroy(true, true, false);
220
221
  }
221
222
  }
222
223
 
@@ -414,10 +415,12 @@ export class AppManager {
414
415
  }
415
416
  }
416
417
 
417
- public notifyReconnected() {
418
- this.appProxies.forEach(appProxy => {
419
- appProxy.onReconnected();
418
+ public async notifyReconnected() {
419
+ const appProxies = Array.from(this.appProxies.values());
420
+ const reconnected = appProxies.map(appProxy => {
421
+ return appProxy.onReconnected();
420
422
  });
423
+ await Promise.all(reconnected);
421
424
  }
422
425
 
423
426
  public notifyContainerRectUpdate(rect: TeleBoxRect) {
@@ -441,7 +444,7 @@ export class AppManager {
441
444
  emitter.clearListeners();
442
445
  if (this.appProxies.size) {
443
446
  this.appProxies.forEach(appProxy => {
444
- appProxy.destroy(true, false);
447
+ appProxy.destroy(true, false, true);
445
448
  });
446
449
  }
447
450
  this.viewManager.destroy();
package/src/AppProxy.ts CHANGED
@@ -101,7 +101,10 @@ export class AppProxy extends Base {
101
101
  this.manager.safeUpdateAttributes(["apps", this.id, Fields.FullPath], path);
102
102
  }
103
103
 
104
- public async baseInsertApp(focus?: boolean): Promise<{ appId: string; app: NetlessApp }> {
104
+ public async baseInsertApp(
105
+ skipUpdate = false,
106
+ focus?: boolean
107
+ ): Promise<{ appId: string; app: NetlessApp }> {
105
108
  const params = this.params;
106
109
  if (!params.kind) {
107
110
  throw new Error("[WindowManager]: kind require");
@@ -109,7 +112,7 @@ export class AppProxy extends Base {
109
112
  const appImpl = await appRegister.appClasses.get(params.kind)?.();
110
113
  const appParams = appRegister.registered.get(params.kind);
111
114
  if (appImpl) {
112
- await this.setupApp(this.id, appImpl, params.options, appParams?.appOptions);
115
+ await this.setupApp(this.id, skipUpdate, appImpl, params.options, appParams?.appOptions);
113
116
  } else {
114
117
  throw new Error(`[WindowManager]: app load failed ${params.kind} ${params.src}`);
115
118
  }
@@ -139,6 +142,7 @@ export class AppProxy extends Base {
139
142
 
140
143
  private async setupApp(
141
144
  appId: string,
145
+ skipUpdate: boolean,
142
146
  app: NetlessApp,
143
147
  options?: setAppOptions,
144
148
  appOptions?: any
@@ -147,8 +151,11 @@ export class AppProxy extends Base {
147
151
  const context = new AppContext(this.manager, appId, this, appOptions);
148
152
  try {
149
153
  emitter.once(`${appId}${Events.WindowCreated}` as any).then(async () => {
150
- const boxInitState = this.getAppInitState(appId);
151
- this.boxManager.updateBoxState(boxInitState);
154
+ let boxInitState: AppInitState | undefined;
155
+ if (!skipUpdate) {
156
+ boxInitState = this.getAppInitState(appId);
157
+ this.boxManager.updateBoxState(boxInitState);
158
+ }
152
159
  this.appEmitter.onAny(this.appListener);
153
160
  this.appAttributesUpdateListener(appId);
154
161
  this.setViewFocusScenePath();
@@ -204,10 +211,12 @@ export class AppProxy extends Base {
204
211
 
205
212
  public async onReconnected() {
206
213
  this.appEmitter.emit("reconnected", undefined);
207
- await this.destroy(true, false);
214
+ const currentAppState = this.getAppInitState(this.id);
215
+ await this.destroy(true, false, true);
208
216
  const params = this.params;
209
217
  const appProxy = new AppProxy(params, this.manager, this.id, this.isAddApp);
210
- await appProxy.baseInsertApp(this.store.focus === this.id);
218
+ await appProxy.baseInsertApp(true, this.store.focus === this.id);
219
+ this.boxManager.updateBoxState(currentAppState);
211
220
  }
212
221
 
213
222
  public switchToWritable() {
@@ -236,8 +245,8 @@ export class AppProxy extends Base {
236
245
  const focus = this.store.focus;
237
246
  const size = attrs?.[AppAttributes.Size];
238
247
  const sceneIndex = attrs?.[AppAttributes.SceneIndex];
239
- const maximized = this.manager.attributes?.["maximized"];
240
- const minimized = this.manager.attributes?.["minimized"];
248
+ const maximized = this.attributes?.["maximized"];
249
+ const minimized = this.attributes?.["minimized"];
241
250
  let payload = { maximized, minimized } as AppInitState;
242
251
  if (position) {
243
252
  payload = { ...payload, id: id, x: position.x, y: position.y };
@@ -289,7 +298,7 @@ export class AppProxy extends Base {
289
298
  }
290
299
  case AppEvents.destroy: {
291
300
  if (this.status === "destroyed") return;
292
- this.destroy(true, data?.error);
301
+ this.destroy(true, false, true, data?.error);
293
302
  if (data?.error) {
294
303
  console.error(data?.error);
295
304
  }
@@ -340,7 +349,12 @@ export class AppProxy extends Base {
340
349
  return view;
341
350
  }
342
351
 
343
- public async destroy(needCloseBox: boolean, cleanAttrs: boolean, error?: Error) {
352
+ public async destroy(
353
+ needCloseBox: boolean,
354
+ cleanAttrs: boolean,
355
+ skipUpdate: boolean,
356
+ error?: Error
357
+ ) {
344
358
  if (this.status === "destroyed") return;
345
359
  this.status = "destroyed";
346
360
  await appRegister.notifyApp(this.kind, "destroy", { appId: this.id });
@@ -348,7 +362,7 @@ export class AppProxy extends Base {
348
362
  this.appEmitter.clearListeners();
349
363
  emitter.emit(`destroy-${this.id}` as any, { error });
350
364
  if (needCloseBox) {
351
- this.boxManager.closeBox(this.id);
365
+ this.boxManager.closeBox(this.id, skipUpdate);
352
366
  }
353
367
  if (cleanAttrs) {
354
368
  this.store.cleanAppAttributes(this.id);
@@ -362,6 +376,6 @@ export class AppProxy extends Base {
362
376
  }
363
377
 
364
378
  public close(): Promise<void> {
365
- return this.destroy(true, true);
379
+ return this.destroy(true, true, false);
366
380
  }
367
381
  }
package/src/BoxManager.ts CHANGED
@@ -188,8 +188,8 @@ export class BoxManager {
188
188
  return this.teleBoxManager.queryOne({ id: appId });
189
189
  }
190
190
 
191
- public closeBox(appId: string): ReadonlyTeleBox | undefined {
192
- return this.teleBoxManager.remove(appId);
191
+ public closeBox(appId: string, skipUpdate = false): ReadonlyTeleBox | undefined {
192
+ return this.teleBoxManager.remove(appId, skipUpdate);
193
193
  }
194
194
 
195
195
  public boxIsFocus(appId: string): boolean | undefined {
package/src/MainView.ts CHANGED
@@ -1,9 +1,10 @@
1
- import { AnimationMode, reaction, ViewVisionMode } from 'white-web-sdk';
2
- import { Base } from './Base';
3
- import { callbacks, emitter } from './index';
4
- import { debounce, isEmpty, isEqual } from 'lodash';
5
- import { Fields } from './AttributesDelegate';
6
- import { notifyMainViewModeChange, setViewFocusScenePath, setViewMode } from './Utils/Common';
1
+ import { AnimationMode, reaction, ViewVisionMode } from "white-web-sdk";
2
+ import { Base } from "./Base";
3
+ import { callbacks, emitter } from "./index";
4
+ import { createView } from "./ViewManager";
5
+ import { debounce, isEmpty, isEqual } from "lodash";
6
+ import { Fields } from "./AttributesDelegate";
7
+ import { notifyMainViewModeChange, setViewFocusScenePath, setViewMode } from "./Utils/Common";
7
8
  import type { Camera, Size, View } from "white-web-sdk";
8
9
  import type { AppManager } from "./AppManager";
9
10
 
@@ -24,7 +25,7 @@ export class MainViewProxy extends Base {
24
25
  setTimeout(() => {
25
26
  this.start();
26
27
  }, 200); // 等待 mainView 挂载完毕再进行监听,否则会触发不必要的 onSizeUpdated
27
- })
28
+ });
28
29
  }
29
30
 
30
31
  private get mainViewCamera() {
@@ -50,7 +51,7 @@ export class MainViewProxy extends Base {
50
51
  }
51
52
 
52
53
  public setCameraAndSize(): void {
53
- this.store.setMainViewCamera({ ...this.mainView.camera, id: this.context.uid });
54
+ this.store.setMainViewCamera({ ...this.mainView.camera, id: this.context.uid });
54
55
  this.store.setMainViewSize({ ...this.mainView.size, id: this.context.uid });
55
56
  }
56
57
 
@@ -65,8 +66,8 @@ export class MainViewProxy extends Base {
65
66
  {
66
67
  fireImmediately: true,
67
68
  }
68
- )
69
- }
69
+ );
70
+ };
70
71
 
71
72
  private sizeReaction = () => {
72
73
  return reaction(
@@ -80,15 +81,15 @@ export class MainViewProxy extends Base {
80
81
  {
81
82
  fireImmediately: true,
82
83
  }
83
- )
84
- }
84
+ );
85
+ };
85
86
 
86
87
  public get view(): View {
87
88
  return this.mainView;
88
89
  }
89
90
 
90
91
  public createMainView(): View {
91
- const mainView = this.manager.displayer.views.createView();
92
+ const mainView = createView(this.manager.displayer);
92
93
  mainView.callbacks.on("onSizeUpdated", () => {
93
94
  this.context.updateManagerRect();
94
95
  });
@@ -103,11 +104,11 @@ export class MainViewProxy extends Base {
103
104
  }
104
105
 
105
106
  private cameraListener = (camera: Camera) => {
106
- this.store.setMainViewCamera({ ...camera, id: this.context.uid});
107
+ this.store.setMainViewCamera({ ...camera, id: this.context.uid });
107
108
  if (this.store.getMainViewSize()?.id !== this.context.uid) {
108
109
  this.setMainViewSize(this.view.size);
109
110
  }
110
- }
111
+ };
111
112
 
112
113
  public addMainViewListener(): void {
113
114
  if (this.mainViewIsAddListener) return;
@@ -138,7 +139,7 @@ export class MainViewProxy extends Base {
138
139
 
139
140
  private sizeListener = (size: Size) => {
140
141
  this.setMainViewSize(size);
141
- }
142
+ };
142
143
 
143
144
  public setMainViewSize = debounce(size => {
144
145
  this.store.setMainViewSize({ ...size, id: this.context.uid });
package/src/index.ts CHANGED
@@ -1,28 +1,28 @@
1
- import AppDocsViewer from '@netless/app-docs-viewer';
2
- import AppMediaPlayer, { setOptions } from '@netless/app-media-player';
3
- import Emittery from 'emittery';
4
- import pRetry from 'p-retry';
1
+ import AppDocsViewer from "@netless/app-docs-viewer";
2
+ import AppMediaPlayer, { setOptions } from "@netless/app-media-player";
3
+ import Emittery from "emittery";
4
+ import pRetry from "p-retry";
5
+ import { AppManager } from "./AppManager";
6
+ import { appRegister } from "./Register";
7
+ import { CursorManager } from "./Cursor";
8
+ import { DEFAULT_CONTAINER_RATIO, REQUIRE_VERSION } from "./constants";
9
+ import { Fields } from "./AttributesDelegate";
10
+ import { initDb } from "./Register/storage";
11
+ import { isNull, isObject } from "lodash";
12
+ import { log } from "./Utils/log";
13
+ import { replaceRoomFunction } from "./Utils/RoomHacker";
14
+ import { ResizeObserver as ResizeObserverPolyfill } from "@juggle/resize-observer";
15
+ import { setupWrapper } from "./ViewManager";
16
+ import "./style.css";
17
+ import "@netless/telebox-insider/dist/style.css";
5
18
  import {
6
19
  addEmitterOnceListener,
7
20
  ensureValidScenePath,
8
21
  getVersionNumber,
9
22
  isValidScenePath,
10
- wait
11
- } from './Utils/Common';
12
- import { AppManager } from './AppManager';
13
- import { appRegister } from './Register';
14
- import { CursorManager } from './Cursor';
15
- import { DEFAULT_CONTAINER_RATIO, REQUIRE_VERSION } from './constants';
16
- import { Fields } from './AttributesDelegate';
17
- import { initDb } from './Register/storage';
18
- import { isNull, isObject } from 'lodash';
19
- import { log } from './Utils/log';
20
- import { replaceRoomFunction } from './Utils/RoomHacker';
21
- import { ResizeObserver as ResizeObserverPolyfill } from '@juggle/resize-observer';
22
- import { setupWrapper } from './ViewManager';
23
- import './style.css';
24
- import '@netless/telebox-insider/dist/style.css';
25
- import type { TELE_BOX_STATE } from './BoxManager';
23
+ wait,
24
+ } from "./Utils/Common";
25
+ import type { TELE_BOX_STATE } from "./BoxManager";
26
26
  import {
27
27
  AppCreateError,
28
28
  AppManagerNotInitError,
@@ -50,7 +50,8 @@ import type {
50
50
  CameraBound,
51
51
  Point,
52
52
  Rectangle,
53
- ViewVisionMode} from "white-web-sdk";
53
+ ViewVisionMode,
54
+ } from "white-web-sdk";
54
55
  import type { AppListeners } from "./AppListener";
55
56
  import type { NetlessApp, RegisterParams } from "./typings";
56
57
  import type { TeleBoxState } from "@netless/telebox-insider";
@@ -122,18 +123,18 @@ export type AppInitState = {
122
123
  };
123
124
 
124
125
  export type EmitterEvent = {
125
- onCreated: undefined,
126
- InitReplay: AppInitState,
127
- move: { appId: string, x: number, y: number },
128
- focus: { appId: string },
129
- close: { appId: string },
130
- resize: { appId: string, width: number, height: number, x?: number, y?: number },
131
- error: Error,
132
- seek: number,
133
- mainViewMounted: undefined,
126
+ onCreated: undefined;
127
+ InitReplay: AppInitState;
128
+ move: { appId: string; x: number; y: number };
129
+ focus: { appId: string };
130
+ close: { appId: string };
131
+ resize: { appId: string; width: number; height: number; x?: number; y?: number };
132
+ error: Error;
133
+ seek: number;
134
+ mainViewMounted: undefined;
134
135
  observerIdChange: number;
135
136
  boxStateChange: string;
136
- }
137
+ };
137
138
 
138
139
  export const emitter: Emittery<EmitterEvent> = new Emittery();
139
140
 
@@ -169,7 +170,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
169
170
  public static containerSizeRatio = DEFAULT_CONTAINER_RATIO;
170
171
  private static isCreated = false;
171
172
 
172
- public version = "0.3.8-canary.3";
173
+ public version = "0.3.10-canary.0";
173
174
 
174
175
  public appListeners?: AppListeners;
175
176
 
@@ -272,13 +273,16 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
272
273
  throw new Error("[WindowManager]: init InvisiblePlugin failed");
273
274
  }
274
275
  } else {
275
- await pRetry(async (count) => {
276
- manager = await this.initManager(room);
277
- if (!manager) {
278
- log(`manager is empty. retrying ${count}`)
279
- throw new Error();
280
- }
281
- }, { retries: 10 });
276
+ await pRetry(
277
+ async count => {
278
+ manager = await this.initManager(room);
279
+ if (!manager) {
280
+ log(`manager is empty. retrying ${count}`);
281
+ throw new Error();
282
+ }
283
+ },
284
+ { retries: 10 }
285
+ );
282
286
  }
283
287
 
284
288
  if (containerSizeRatio) {
@@ -327,12 +331,18 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
327
331
  } catch (error) {
328
332
  throw new Error("[WindowManger]: room must be switched to be writable");
329
333
  }
330
- manager = (await room.createInvisiblePlugin(WindowManager, {})) as WindowManager;
334
+ manager = (await room.createInvisiblePlugin(
335
+ WindowManager,
336
+ {}
337
+ )) as WindowManager;
331
338
  manager.ensureAttributes();
332
339
  await wait(500);
333
340
  await room.setWritable(false);
334
341
  } else {
335
- manager = (await room.createInvisiblePlugin(WindowManager, {})) as WindowManager;
342
+ manager = (await room.createInvisiblePlugin(
343
+ WindowManager,
344
+ {}
345
+ )) as WindowManager;
336
346
  }
337
347
  }
338
348
  }
@@ -342,7 +352,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
342
352
  /**
343
353
  * 注册插件
344
354
  */
345
- public static register<AppOptions = any, SetupResult = any, Attributes = any>(
355
+ public static register<AppOptions = any, SetupResult = any, Attributes = any>(
346
356
  params: RegisterParams<AppOptions, SetupResult, Attributes>
347
357
  ): Promise<void> {
348
358
  return appRegister.register(params);
@@ -406,7 +416,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
406
416
  }
407
417
  }
408
418
  if (scenePath && scenes === undefined) {
409
- this.room?.putScenes(scenePath, [{}])
419
+ this.room?.putScenes(scenePath, [{}]);
410
420
  }
411
421
  }
412
422
  return isDynamicPPT;
@@ -532,13 +542,18 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
532
542
  return this.appManager?.closeApp(appId);
533
543
  }
534
544
 
535
- public moveCamera(camera: Partial<Camera> & { animationMode?: AnimationMode | undefined }): void {
545
+ public moveCamera(
546
+ camera: Partial<Camera> & { animationMode?: AnimationMode | undefined }
547
+ ): void {
536
548
  this.mainView.moveCamera(camera);
537
549
  }
538
550
 
539
- public moveCameraToContain(rectangle: Rectangle & Readonly<{
540
- animationMode?: AnimationMode;
541
- }>): void {
551
+ public moveCameraToContain(
552
+ rectangle: Rectangle &
553
+ Readonly<{
554
+ animationMode?: AnimationMode;
555
+ }>
556
+ ): void {
542
557
  this.mainView.moveCameraToContain(rectangle);
543
558
  }
544
559
 
@@ -3,7 +3,7 @@ import { callbacks, WindowManager } from "./index";
3
3
  import { reaction, ViewVisionMode } from "white-web-sdk";
4
4
  import { SET_SCENEPATH_DELAY } from "./constants";
5
5
  import { notifyMainViewModeChange, setScenePath, setViewMode } from "./Utils/Common";
6
- import type { View } from "white-web-sdk";
6
+ import type { View, Displayer } from "white-web-sdk";
7
7
  import type { AppManager } from "./AppManager";
8
8
 
9
9
  export class ViewManager extends Base {
@@ -44,7 +44,7 @@ export class ViewManager extends Base {
44
44
  }
45
45
 
46
46
  public createView(appId: string): View {
47
- const view = this.displayer.views.createView();
47
+ const view = createView(this.displayer);
48
48
  setViewMode(view, ViewVisionMode.Freedom);
49
49
  this.views.set(appId, view);
50
50
  return view;
@@ -134,6 +134,19 @@ export class ViewManager extends Base {
134
134
  }
135
135
  }
136
136
 
137
+ export const createView = (displayer: Displayer): View => {
138
+ const view = displayer.views.createView();
139
+ setDefaultCameraBound(view);
140
+ return view;
141
+ };
142
+
143
+ export const setDefaultCameraBound = (view: View) => {
144
+ view.setCameraBound({
145
+ maxContentMode: () => 10,
146
+ minContentMode: () => 0.1,
147
+ });
148
+ };
149
+
137
150
  export const setupWrapper = (
138
151
  root: HTMLElement
139
152
  ): {