@netless/window-manager 0.4.8 → 0.4.9-canary.2

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/docs/advanced.md CHANGED
@@ -3,6 +3,7 @@
3
3
  - 目录
4
4
  - [撤销重做](#redo-undo)
5
5
  - [清屏](#clean-current-scene)
6
+ - [判断是否打开某种 APP](#has-kind)
6
7
 
7
8
 
8
9
  <h3 id="redo-undo">撤销重做</h3>
@@ -51,3 +52,15 @@ manager.cleanCurrentScene()
51
52
  ```ts
52
53
  manager.mainView.cleanCurrentScene()
53
54
  ```
55
+
56
+
57
+ <br>
58
+
59
+ <h3 id="has-kind">判断是否打开某种 APP</h3>
60
+
61
+ ```ts
62
+ manager.emitter.on("ready", () => { // ready 事件在所有 app 创建完成后触发
63
+ const apps = manager.queryAll(); // 获取所有已经打开的 App
64
+ const hasSlide = apps.some(app => app.kind === "Slide"); // 判断已经打开的 APP 中是否有 Slide
65
+ });
66
+ ```
package/docs/api.md CHANGED
@@ -4,6 +4,7 @@
4
4
  - [静态方法](#static-methods)
5
5
  - [`mount`](#mount)
6
6
  - [`register`](#register)
7
+ - [`registered`](#registered)
7
8
  - [`setContainer`](#set-container)
8
9
  - [`setCollectorContainer`](#set-collector-container)
9
10
  - [实例方法](#instance-methods)
@@ -85,6 +86,18 @@ WindowManager.register({
85
86
  })
86
87
  ```
87
88
 
89
+ <br>
90
+
91
+ <h3 id="registered">WindowManager.registered</h3>
92
+
93
+ > 获取已经注册过的 `App`
94
+
95
+ ```ts
96
+ WindowManager.registered
97
+ ```
98
+
99
+ <br>
100
+
88
101
  <h3 id="set-container">setContainer</h3>
89
102
 
90
103
  > 设置白板挂载容器
@@ -215,6 +228,7 @@ manager.addPage({ scene: { name: "page2" } }) // 传入 page 信息
215
228
  | focused | string | | focus 的 app |
216
229
  | canRedoSteps | number | | 当前 focus 的 view 可以重做的步数 |
217
230
  | canRedoSteps | number | | 当前 focus 的 view 可以撤销的步数 |
231
+ | sceneState | SceneState | | 兼容原本 SDK 的 sceneState 属性, 只对 mainView 生效 |
218
232
 
219
233
  <br>
220
234
 
@@ -237,7 +251,8 @@ manager.callbacks.on(events, listener)
237
251
  | canRedoStepsChange | number | | 当前 focus 的 view 可重做步数改变 |
238
252
  | canUndoStepsChange | number | | 当前 focus 的 view 可撤销步数改变 |
239
253
  | loadApp | LoadAppEvent | | 加载远程APP 事件 |
240
-
254
+ | ready | undefined | | 当所有 APP 创建完毕时触发 |
255
+ | sceneStateChange | SceneState | | 当 sceneState 修改时触发 |
241
256
 
242
257
  ```ts
243
258
  type LoadAppEvent = {
@@ -0,0 +1,50 @@
1
+ # 开发自定义 APP
2
+
3
+ ## official apps https://github.com/netless-io/netless-app
4
+
5
+ <br>
6
+
7
+ ```ts
8
+ import type { NetlessApp, AppContext } from "@netless/window-manager";
9
+
10
+ const HelloWorld: NetlessApp = {
11
+ kind: "HelloWorld",
12
+ setup: (context: AppContext) => {
13
+ context.mountView(context.getBox().$content); // 可选: 挂载 View 到 box 上
14
+
15
+ const storage = context.createStorage<{ a: number }>("HelloWorld", { a: 1 });
16
+ console.log(storage.state === { a: 1 });
17
+
18
+ storage.addStateChangedListener(diff => {
19
+ if (diff.a) {
20
+ console.log(diff.a.oldValue === 1);
21
+ console.log(diff.a.newValue === 2);
22
+ }
23
+ });
24
+
25
+ if (context.getIsWritable()) {
26
+ // 只有在可写状态才可以调用 setState
27
+ storage.setState({ a: 2 });
28
+ }
29
+
30
+ // magixEvent 事件是房间内范围的, 建议 app 内使用需要添加自己的 prefix
31
+ context.addMagixEventListener(`${context.appId}_event1`, message => {
32
+ console.log("MagixEvent", message);
33
+ });
34
+
35
+ context.dispatchMagixEvent(`${context.appId}_event1`, { count: 1 });
36
+ },
37
+ };
38
+
39
+ WindowManager.register({
40
+ kind: HelloWorld.kind,
41
+ src: HelloWorld,
42
+ });
43
+
44
+ manager.addApp({
45
+ kind: "HelloWorld",
46
+ options: {
47
+ scenePath: "/hello-world", // 如果需要在 App 中使用白板则必须声明 scenePath
48
+ },
49
+ });
50
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/window-manager",
3
- "version": "0.4.8",
3
+ "version": "0.4.9-canary.2",
4
4
  "description": "",
5
5
  "main": "dist/index.es.js",
6
6
  "module": "dist/index.es.js",
package/src/AppContext.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { BoxNotCreatedError } from "./Utils/error";
2
+ import { Storage } from "./App/Storage";
1
3
  import {
2
4
  autorun,
3
5
  listenDisposed,
@@ -5,31 +7,38 @@ import {
5
7
  reaction,
6
8
  unlistenDisposed,
7
9
  unlistenUpdated,
8
- toJS
9
- } from 'white-web-sdk';
10
- import { BoxNotCreatedError } from './Utils/error';
11
- import type { Room, SceneDefinition, View, EventListener as WhiteEventListener } from "white-web-sdk";
10
+ toJS,
11
+ } from "white-web-sdk";
12
+ import type {
13
+ Room,
14
+ SceneDefinition,
15
+ View,
16
+ EventListener as WhiteEventListener,
17
+ } from "white-web-sdk";
12
18
  import type { ReadonlyTeleBox } from "@netless/telebox-insider";
13
19
  import type Emittery from "emittery";
14
20
  import type { BoxManager } from "./BoxManager";
15
21
  import type { AppEmitterEvent } from "./index";
16
22
  import type { AppManager } from "./AppManager";
17
23
  import type { AppProxy } from "./AppProxy";
18
- import { Storage } from './App/Storage';
19
- import type { MagixEventAddListener, MagixEventDispatcher, MagixEventRemoveListener } from './App/MagixEvent';
24
+ import type {
25
+ MagixEventAddListener,
26
+ MagixEventDispatcher,
27
+ MagixEventRemoveListener,
28
+ } from "./App/MagixEvent";
20
29
 
21
30
  export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOptions = any> {
22
31
  public readonly emitter: Emittery<AppEmitterEvent<TAttributes>>;
23
32
  public readonly mobxUtils = {
24
33
  autorun,
25
34
  reaction,
26
- toJS
35
+ toJS,
27
36
  };
28
37
  public readonly objectUtils = {
29
38
  listenUpdated,
30
39
  unlistenUpdated,
31
40
  listenDisposed,
32
- unlistenDisposed
41
+ unlistenDisposed,
33
42
  };
34
43
 
35
44
  private store = this.manager.store;
@@ -41,7 +50,7 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
41
50
  private boxManager: BoxManager,
42
51
  public appId: string,
43
52
  private appProxy: AppProxy,
44
- private appOptions?: TAppOptions | (() => TAppOptions),
53
+ private appOptions?: TAppOptions | (() => TAppOptions)
45
54
  ) {
46
55
  this.emitter = appProxy.appEmitter;
47
56
  this.isAddApp = appProxy.isAddApp;
@@ -49,12 +58,12 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
49
58
 
50
59
  public getDisplayer = () => {
51
60
  return this.manager.displayer;
52
- }
61
+ };
53
62
 
54
63
  /** @deprecated Use context.storage.state instead. */
55
64
  public getAttributes = (): TAttributes | undefined => {
56
65
  return this.appProxy.attributes;
57
- }
66
+ };
58
67
 
59
68
  public getScenes = (): SceneDefinition[] | undefined => {
60
69
  const appAttr = this.store.getAppAttributes(this.appId);
@@ -63,20 +72,20 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
63
72
  } else {
64
73
  return appAttr?.options["scenes"];
65
74
  }
66
- }
75
+ };
67
76
 
68
77
  public getView = (): View | undefined => {
69
78
  return this.appProxy.view;
70
- }
79
+ };
71
80
 
72
81
  public getInitScenePath = () => {
73
82
  return this.manager.getAppInitPath(this.appId);
74
- }
83
+ };
75
84
 
76
85
  /** Get App writable status. */
77
86
  public getIsWritable = (): boolean => {
78
87
  return this.manager.canOperate;
79
- }
88
+ };
80
89
 
81
90
  /** Get the App Window UI box. */
82
91
  public getBox = (): ReadonlyTeleBox => {
@@ -86,48 +95,50 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
86
95
  } else {
87
96
  throw new BoxNotCreatedError();
88
97
  }
89
- }
98
+ };
90
99
 
91
100
  public getRoom = (): Room | undefined => {
92
101
  return this.manager.room;
93
- }
102
+ };
94
103
 
95
104
  /** @deprecated Use context.storage.setState instead. */
96
105
  public setAttributes = (attributes: TAttributes) => {
97
106
  this.manager.safeSetAttributes({ [this.appId]: attributes });
98
- }
107
+ };
99
108
 
100
109
  /** @deprecated Use context.storage.setState instead. */
101
110
  public updateAttributes = (keys: string[], value: any) => {
102
111
  if (this.manager.attributes[this.appId]) {
103
112
  this.manager.safeUpdateAttributes([this.appId, ...keys], value);
104
113
  }
105
- }
114
+ };
106
115
 
107
116
  public setScenePath = async (scenePath: string): Promise<void> => {
108
117
  if (!this.appProxy.box) return;
109
118
  this.appProxy.setFullPath(scenePath);
110
119
  // 兼容 15 版本 SDK 的切页
111
120
  this.getRoom()?.setScenePath(scenePath);
112
- }
121
+ };
113
122
 
114
- public mountView = (dom: HTMLDivElement): void => {
123
+ public mountView = (dom: HTMLElement): void => {
115
124
  const view = this.getView();
116
125
  if (view) {
117
- view.divElement = dom;
126
+ view.divElement = dom as HTMLDivElement;
118
127
  setTimeout(() => {
119
128
  // 渲染需要时间,延迟 refresh
120
129
  this.getRoom()?.refreshViewSize();
121
130
  }, 1000);
122
131
  }
123
- }
132
+ };
124
133
 
125
134
  /** Get the local App options. */
126
135
  public getAppOptions = (): TAppOptions | undefined => {
127
- return typeof this.appOptions === 'function' ? (this.appOptions as () => TAppOptions)() : this.appOptions
128
- }
136
+ return typeof this.appOptions === "function"
137
+ ? (this.appOptions as () => TAppOptions)()
138
+ : this.appOptions;
139
+ };
129
140
 
130
- private _storage?: Storage<TAttributes>
141
+ private _storage?: Storage<TAttributes>;
131
142
 
132
143
  /** Main Storage for attributes. */
133
144
  public get storage(): Storage<TAttributes> {
@@ -141,7 +152,7 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
141
152
  * Create separated storages for flexible state management.
142
153
  * @param storeId Namespace for the storage. Storages of the same namespace share the same data.
143
154
  * @param defaultState Default state for initial storage creation.
144
- * @returns
155
+ * @returns
145
156
  */
146
157
  public createStorage = <TState>(storeId: string, defaultState?: TState): Storage<TState> => {
147
158
  const storage = new Storage(this, storeId, defaultState);
@@ -149,20 +160,27 @@ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOption
149
160
  storage.destroy();
150
161
  });
151
162
  return storage;
152
- }
163
+ };
153
164
 
154
165
  /** Dispatch events to other clients (and self). */
155
166
  public dispatchMagixEvent: MagixEventDispatcher<TMagixEventPayloads> = (...args) => {
156
167
  // can't dispatch events on replay mode
157
168
  return this.manager.room?.dispatchMagixEvent(...args);
158
- }
169
+ };
159
170
 
160
171
  /** Listen to events from others clients (and self messages). */
161
- public addMagixEventListener: MagixEventAddListener<TMagixEventPayloads> = (event, handler, options) => {
172
+ public addMagixEventListener: MagixEventAddListener<TMagixEventPayloads> = (
173
+ event,
174
+ handler,
175
+ options
176
+ ) => {
162
177
  this.manager.displayer.addMagixEventListener(event, handler as WhiteEventListener, options);
163
- return () => this.manager.displayer.removeMagixEventListener(event, handler as WhiteEventListener);
164
- }
178
+ return () =>
179
+ this.manager.displayer.removeMagixEventListener(event, handler as WhiteEventListener);
180
+ };
165
181
 
166
182
  /** Remove a Magix event listener. */
167
- public removeMagixEventListener = this.manager.displayer.removeMagixEventListener.bind(this.manager.displayer) as MagixEventRemoveListener<TMagixEventPayloads>
183
+ public removeMagixEventListener = this.manager.displayer.removeMagixEventListener.bind(
184
+ this.manager.displayer
185
+ ) as MagixEventRemoveListener<TMagixEventPayloads>;
168
186
  }
@@ -1,4 +1,5 @@
1
- import { callbacks, emitter } from "./index";
1
+ import { callbacks } from "./callback";
2
+ import { emitter } from "./InternalEmitter";
2
3
  import { Events, MagixEventName } from "./constants";
3
4
  import { isEqual, omit } from "lodash";
4
5
  import { setViewFocusScenePath } from "./Utils/Common";
package/src/AppManager.ts CHANGED
@@ -4,15 +4,18 @@ import { AppListeners } from "./AppListener";
4
4
  import { AppProxy } from "./AppProxy";
5
5
  import { appRegister } from "./Register";
6
6
  import { autorun, isPlayer, isRoom, ScenePathType } from "white-web-sdk";
7
- import { callbacks, emitter, reconnectRefresher, WindowManager } from "./index";
7
+ import { callbacks } from "./callback";
8
+ import { emitter } from "./InternalEmitter";
8
9
  import { get, isInteger, orderBy } from "lodash";
9
10
  import { log } from "./Utils/log";
10
11
  import { MainViewProxy } from "./View/MainView";
11
12
  import { onObjectRemoved, safeListenPropsUpdated } from "./Utils/Reactive";
13
+ import { reconnectRefresher, WindowManager } from "./index";
12
14
  import { RedoUndo } from "./RedoUndo";
13
15
  import { SideEffectManager } from "side-effect-manager";
14
16
  import { store } from "./AttributesDelegate";
15
17
  import { ViewManager } from "./View/ViewManager";
18
+ import type { EmitterEvent } from "./InternalEmitter";
16
19
  import {
17
20
  entireScenes,
18
21
  genAppId,
@@ -23,9 +26,14 @@ import {
23
26
  } from "./Utils/Common";
24
27
  import type { ReconnectRefresher } from "./ReconnectRefresher";
25
28
  import type { BoxManager } from "./BoxManager";
26
- import type { Displayer, DisplayerState, Room, ScenesCallbacksNode } from "white-web-sdk";
27
- import type { AddAppParams, BaseInsertParams, TeleBoxRect, EmitterEvent } from "./index";
28
-
29
+ import type {
30
+ Displayer,
31
+ DisplayerState,
32
+ Room,
33
+ ScenesCallbacksNode,
34
+ SceneState,
35
+ } from "white-web-sdk";
36
+ import type { AddAppParams, BaseInsertParams, TeleBoxRect } from "./index";
29
37
  export class AppManager {
30
38
  public displayer: Displayer;
31
39
  public viewManager: ViewManager;
@@ -47,6 +55,8 @@ export class AppManager {
47
55
 
48
56
  private sideEffectManager = new SideEffectManager();
49
57
 
58
+ public sceneState: SceneState | null = null;
59
+
50
60
  constructor(public windowManger: WindowManager) {
51
61
  this.displayer = windowManger.displayer;
52
62
  this.store.setContext({
@@ -126,16 +136,11 @@ export class AppManager {
126
136
  isRecreate = true;
127
137
  }
128
138
  this.callbacksNode = this.displayer.createScenesCallback(ROOT_DIR, {
129
- onAddScene: scenesCallback => {
130
- this.mainViewScenesLength = scenesCallback.scenes.length;
131
- callbacks.emit("mainViewScenesLengthChange", this.mainViewScenesLength);
132
- },
133
- onRemoveScene: scenesCallback => {
134
- this.mainViewScenesLength = scenesCallback.scenes.length;
135
- callbacks.emit("mainViewScenesLengthChange", this.mainViewScenesLength);
136
- },
139
+ onAddScene: this.onSceneChange,
140
+ onRemoveScene: this.onSceneChange,
137
141
  });
138
142
  if (this.callbacksNode) {
143
+ this.updateSceneState(this.callbacksNode);
139
144
  this.mainViewScenesLength = this.callbacksNode.scenes.length;
140
145
  if (isRecreate) {
141
146
  callbacks.emit("mainViewScenesLengthChange", this.callbacksNode.scenes.length);
@@ -143,6 +148,29 @@ export class AppManager {
143
148
  }
144
149
  };
145
150
 
151
+ private onSceneChange = (node: ScenesCallbacksNode) => {
152
+ this.mainViewScenesLength = node.scenes.length;
153
+ this.updateSceneState(node);
154
+ callbacks.emit("mainViewScenesLengthChange", this.mainViewScenesLength);
155
+ };
156
+
157
+ private updateSceneState = (node: ScenesCallbacksNode) => {
158
+ const currentIndex = this.store.getMainViewSceneIndex() || 0;
159
+ const sceneName = node.scenes[currentIndex];
160
+ this.sceneState = {
161
+ scenePath: `${ROOT_DIR}${sceneName}`,
162
+ contextPath: node.path,
163
+ index: currentIndex,
164
+ scenes: node.scenes.map(scene => {
165
+ return {
166
+ name: scene,
167
+ };
168
+ }),
169
+ sceneName: sceneName,
170
+ };
171
+ callbacks.emit("sceneStateChange", this.sceneState);
172
+ };
173
+
146
174
  private get eventName() {
147
175
  return isRoom(this.displayer) ? "onRoomStateChanged" : "onPlayerStateChanged";
148
176
  }
@@ -223,6 +251,9 @@ export class AppManager {
223
251
  const mainSceneIndex = get(this.attributes, "_mainSceneIndex");
224
252
  if (mainSceneIndex !== undefined && this._prevSceneIndex !== mainSceneIndex) {
225
253
  callbacks.emit("mainViewSceneIndexChange", mainSceneIndex);
254
+ if (this.callbacksNode) {
255
+ this.updateSceneState(this.callbacksNode);
256
+ }
226
257
  this._prevSceneIndex = mainSceneIndex;
227
258
  }
228
259
  });
@@ -278,6 +309,9 @@ export class AppManager {
278
309
  public async attributesUpdateCallback(apps: any) {
279
310
  if (apps && WindowManager.container) {
280
311
  const appIds = Object.keys(apps);
312
+ if (appIds.length === 0) {
313
+ this.appCreateQueue.emitReady();
314
+ }
281
315
  const appsWithCreatedAt = appIds.map(appId => {
282
316
  return {
283
317
  id: appId,
package/src/AppProxy.ts CHANGED
@@ -5,7 +5,7 @@ import { appRegister } from "./Register";
5
5
  import { autorun } from "white-web-sdk";
6
6
  import { BoxManagerNotFoundError } from "./Utils/error";
7
7
  import { debounce, get } from "lodash";
8
- import { emitter } from "./index";
8
+ import { emitter } from "./InternalEmitter";
9
9
  import { Fields } from "./AttributesDelegate";
10
10
  import { entireScenes, getScenePath, removeScenes, setScenePath, setViewFocusScenePath } from "./Utils/Common";
11
11
  import { log } from "./Utils/log";
package/src/BoxManager.ts CHANGED
@@ -2,7 +2,7 @@ import { AppAttributes, Events, MIN_HEIGHT, MIN_WIDTH } from "./constants";
2
2
  import { debounce } from "lodash";
3
3
  import { TELE_BOX_STATE, TeleBoxCollector, TeleBoxManager } from "@netless/telebox-insider";
4
4
  import { WindowManager } from "./index";
5
- import type { AddAppOptions, AppInitState, EmitterType, CallbacksType } from "./index";
5
+ import type { AddAppOptions, AppInitState } from "./index";
6
6
  import type {
7
7
  TeleBoxManagerUpdateConfig,
8
8
  TeleBoxManagerCreateConfig,
@@ -15,6 +15,8 @@ import type {
15
15
  import type Emittery from "emittery";
16
16
  import type { NetlessApp } from "./typings";
17
17
  import type { View } from "white-web-sdk";
18
+ import type { CallbacksType } from "./callback";
19
+ import type { EmitterType } from "./InternalEmitter";
18
20
 
19
21
  export { TELE_BOX_STATE };
20
22
 
@@ -1,6 +1,6 @@
1
1
  import { ResizeObserver as ResizeObserverPolyfill } from "@juggle/resize-observer";
2
2
  import { WindowManager } from "./index";
3
- import type { EmitterType } from "./index";
3
+ import type { EmitterType } from "./InternalEmitter";
4
4
 
5
5
  const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
6
6
 
@@ -1,9 +1,10 @@
1
1
  import { ApplianceNames } from "white-web-sdk";
2
2
  import { Cursor } from "./Cursor";
3
3
  import { CursorState, Events } from "../constants";
4
- import { emitter, WindowManager } from "../index";
4
+ import { emitter } from "../InternalEmitter";
5
5
  import { SideEffectManager } from "side-effect-manager";
6
6
  import { throttle } from "lodash";
7
+ import { WindowManager } from "../index";
7
8
  import type { CursorMovePayload } from "../index";
8
9
  import type { PositionType } from "../AttributesDelegate";
9
10
  import type { Point, RoomMember, View } from "white-web-sdk";
@@ -65,7 +66,8 @@ export class CursorManager {
65
66
  };
66
67
 
67
68
  private canMoveCursor(member: RoomMember | undefined) {
68
- const isLaserPointer = member?.memberState.currentApplianceName === ApplianceNames.laserPointer;
69
+ const isLaserPointer =
70
+ member?.memberState.currentApplianceName === ApplianceNames.laserPointer;
69
71
  // 激光笔教具在不开启光标的情况下也要显示
70
72
  return this.enableCursor || isLaserPointer;
71
73
  }
@@ -0,0 +1,27 @@
1
+ import Emittery from "emittery";
2
+ import type { AppInitState, CursorMovePayload } from "./index";
3
+
4
+
5
+ export type EmitterEvent = {
6
+ onCreated: undefined;
7
+ InitReplay: AppInitState;
8
+ move: { appId: string; x: number; y: number };
9
+ focus: { appId: string };
10
+ close: { appId: string };
11
+ resize: { appId: string; width: number; height: number; x?: number; y?: number };
12
+ error: Error;
13
+ seek: number;
14
+ mainViewMounted: undefined;
15
+ observerIdChange: number;
16
+ boxStateChange: string;
17
+ playgroundSizeChange: DOMRect;
18
+ onReconnected: void;
19
+ removeScenes: string;
20
+ cursorMove: CursorMovePayload;
21
+ updateManagerRect: undefined;
22
+ focusedChange: { focused: string | undefined; prev: string | undefined };
23
+ rootDirRemoved: undefined;
24
+ };
25
+
26
+ export type EmitterType = Emittery<EmitterEvent>;
27
+ export const emitter: EmitterType = new Emittery();
@@ -2,7 +2,7 @@ import { debounce, isFunction } from "lodash";
2
2
  import { log } from "./Utils/log";
3
3
  import { RoomPhase } from "white-web-sdk";
4
4
  import type { Room } from "white-web-sdk";
5
- import type { EmitterType } from "./index";
5
+ import type { EmitterType } from "./InternalEmitter";
6
6
 
7
7
  export type ReconnectRefresherContext = {
8
8
  emitter: EmitterType;
package/src/RedoUndo.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { callbacks, emitter } from "./index";
1
+ import { callbacks } from "./callback";
2
+ import { emitter } from "./InternalEmitter";
2
3
  import type { View } from "white-web-sdk";
3
4
  import type { AppProxy } from "./AppProxy";
4
5
 
@@ -1,4 +1,4 @@
1
- import { callbacks } from "../index";
1
+ import { callbacks } from "../callback";
2
2
  import { getItem, setItem } from "./storage";
3
3
  import type { NetlessApp } from "../typings";
4
4
 
@@ -1,3 +1,4 @@
1
+ import { callbacks } from "../callback";
1
2
  import type { AppProxy } from "../AppProxy";
2
3
 
3
4
  export type Invoker = () => Promise<AppProxy | undefined>;
@@ -6,6 +7,7 @@ export class AppCreateQueue {
6
7
  private list: Invoker[] = [];
7
8
  private currentInvoker: Invoker | undefined;
8
9
  private timer: number | undefined;
10
+ public isEmit = false;
9
11
 
10
12
  private initInterval() {
11
13
  return setInterval(() => {
@@ -37,6 +39,7 @@ export class AppCreateQueue {
37
39
  this.currentInvoker = undefined;
38
40
  if (this.list.length === 0) {
39
41
  clearInterval(this.timer);
42
+ this.emitReady();
40
43
  }
41
44
  })
42
45
  .catch(error => {
@@ -46,6 +49,13 @@ export class AppCreateQueue {
46
49
  }
47
50
  }
48
51
 
52
+ public emitReady() {
53
+ if (!this.isEmit) {
54
+ callbacks.emit("ready");
55
+ }
56
+ this.isEmit = true;
57
+ }
58
+
49
59
  public destroy() {
50
60
  if (this.timer) {
51
61
  clearInterval(this.timer);
@@ -1,9 +1,9 @@
1
1
  import { appRegister } from "../Register";
2
2
  import { debounce } from "lodash";
3
- import { emitter } from "../index";
3
+ import { emitter } from "../InternalEmitter";
4
4
  import { ScenePathType } from "white-web-sdk";
5
5
  import { v4 } from "uuid";
6
- import type { PublicEvent } from "../index";
6
+ import type { PublicEvent } from "../callback";
7
7
  import type { Displayer, ViewVisionMode, Room, View } from "white-web-sdk";
8
8
  import type Emittery from "emittery";
9
9
  import { ROOT_DIR } from "../constants";
@@ -1,4 +1,4 @@
1
- import { emitter } from "../index";
1
+ import { emitter } from "../InternalEmitter";
2
2
  import { isPlayer } from "white-web-sdk";
3
3
  import type { WindowManager } from "../index";
4
4
  import type { Camera, Room, Player, PlayerSeekingResult } from "white-web-sdk";
@@ -23,13 +23,13 @@ export const replaceRoomFunction = (room: Room | Player, manager: WindowManager)
23
23
 
24
24
  Object.defineProperty(room, "canUndoSteps", {
25
25
  get() {
26
- return manager.mainView.canUndoSteps;
26
+ return manager.canUndoSteps;
27
27
  },
28
28
  });
29
29
 
30
30
  Object.defineProperty(room, "canRedoSteps", {
31
31
  get() {
32
- return manager.mainView.canRedoSteps;
32
+ return manager.canRedoSteps;
33
33
  },
34
34
  });
35
35
 
@@ -1,7 +1,8 @@
1
1
  import { AnimationMode, reaction } from "white-web-sdk";
2
- import { callbacks, emitter } from "../index";
2
+ import { callbacks } from "../callback";
3
3
  import { createView } from "./ViewManager";
4
4
  import { debounce, isEmpty, isEqual } from "lodash";
5
+ import { emitter } from "../InternalEmitter";
5
6
  import { Fields } from "../AttributesDelegate";
6
7
  import { setViewFocusScenePath } from "../Utils/Common";
7
8
  import { SideEffectManager } from "side-effect-manager";