@netless/window-manager 0.4.0-canary.6 → 0.4.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.
Files changed (81) hide show
  1. package/.idea/inspectionProfiles/Project_Default.xml +7 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/vcs.xml +6 -0
  4. package/.idea/window-manager.iml +12 -0
  5. package/.vscode/settings.json +1 -0
  6. package/CHANGELOG.md +39 -2
  7. package/README.md +3 -0
  8. package/dist/App/MagixEvent/index.d.ts +29 -0
  9. package/dist/App/Storage/index.d.ts +19 -6
  10. package/dist/App/Storage/typings.d.ts +4 -0
  11. package/dist/AppContext.d.ts +39 -17
  12. package/dist/AppListener.d.ts +2 -1
  13. package/dist/AppManager.d.ts +25 -11
  14. package/dist/AppProxy.d.ts +7 -8
  15. package/dist/AttributesDelegate.d.ts +2 -2
  16. package/dist/BoxManager.d.ts +6 -3
  17. package/dist/BuiltinApps.d.ts +5 -0
  18. package/dist/ContainerResizeObserver.d.ts +10 -0
  19. package/dist/Cursor/Cursor.d.ts +10 -12
  20. package/dist/Cursor/index.d.ts +6 -16
  21. package/dist/Helper.d.ts +7 -0
  22. package/dist/Register/storage.d.ts +5 -1
  23. package/dist/Utils/AppCreateQueue.d.ts +11 -0
  24. package/dist/Utils/Common.d.ts +7 -2
  25. package/dist/Utils/RoomHacker.d.ts +3 -3
  26. package/dist/{MainView.d.ts → View/MainView.d.ts} +5 -6
  27. package/dist/View/ViewManager.d.ts +13 -0
  28. package/dist/constants.d.ts +5 -7
  29. package/dist/index.d.ts +35 -16
  30. package/dist/index.es.js +41 -1
  31. package/dist/index.es.js.map +1 -1
  32. package/dist/index.umd.js +41 -1
  33. package/dist/index.umd.js.map +1 -1
  34. package/dist/style.css +1 -1
  35. package/dist/typings.d.ts +3 -2
  36. package/docs/advanced.md +39 -0
  37. package/docs/api.md +69 -6
  38. package/docs/concept.md +9 -0
  39. package/docs/replay.md +40 -0
  40. package/package.json +7 -6
  41. package/src/App/MagixEvent/index.ts +68 -0
  42. package/src/App/Storage/index.ts +90 -44
  43. package/src/App/Storage/typings.ts +8 -0
  44. package/src/AppContext.ts +61 -25
  45. package/src/AppListener.ts +28 -16
  46. package/src/AppManager.ts +260 -81
  47. package/src/AppProxy.ts +53 -64
  48. package/src/AttributesDelegate.ts +2 -2
  49. package/src/BoxManager.ts +40 -24
  50. package/src/BuiltinApps.ts +23 -0
  51. package/src/ContainerResizeObserver.ts +62 -0
  52. package/src/Cursor/Cursor.svelte +25 -21
  53. package/src/Cursor/Cursor.ts +25 -38
  54. package/src/Cursor/icons.ts +2 -0
  55. package/src/Cursor/index.ts +45 -139
  56. package/src/Helper.ts +41 -0
  57. package/src/Register/index.ts +25 -16
  58. package/src/Register/loader.ts +2 -2
  59. package/src/Register/storage.ts +6 -1
  60. package/src/Utils/AppCreateQueue.ts +54 -0
  61. package/src/Utils/Common.ts +69 -14
  62. package/src/Utils/RoomHacker.ts +44 -14
  63. package/src/{MainView.ts → View/MainView.ts} +25 -36
  64. package/src/View/ViewManager.ts +52 -0
  65. package/src/constants.ts +6 -4
  66. package/src/image/laser-pointer-cursor.svg +17 -0
  67. package/src/index.ts +164 -99
  68. package/src/shim.d.ts +5 -0
  69. package/src/style.css +12 -1
  70. package/src/typings.ts +3 -2
  71. package/vite.config.js +8 -2
  72. package/dist/Base/Context.d.ts +0 -13
  73. package/dist/Base/index.d.ts +0 -7
  74. package/dist/Utils/CameraStore.d.ts +0 -15
  75. package/dist/ViewManager.d.ts +0 -29
  76. package/dist/sdk.d.ts +0 -14
  77. package/src/Base/Context.ts +0 -49
  78. package/src/Base/index.ts +0 -10
  79. package/src/Utils/CameraStore.ts +0 -72
  80. package/src/sdk.ts +0 -39
  81. package/src/viewManager.ts +0 -177
package/src/AppContext.ts CHANGED
@@ -6,9 +6,9 @@ import {
6
6
  unlistenDisposed,
7
7
  unlistenUpdated,
8
8
  toJS
9
- } from 'white-web-sdk';
9
+ } from 'white-web-sdk';
10
10
  import { BoxNotCreatedError } from './Utils/error';
11
- import type { Room, SceneDefinition, View } from "white-web-sdk";
11
+ import type { Room, SceneDefinition, View, EventListener as WhiteEventListener } from "white-web-sdk";
12
12
  import type { ReadonlyTeleBox } from "@netless/telebox-insider";
13
13
  import type Emittery from "emittery";
14
14
  import type { BoxManager } from "./BoxManager";
@@ -16,9 +16,10 @@ import type { AppEmitterEvent } from "./index";
16
16
  import type { AppManager } from "./AppManager";
17
17
  import type { AppProxy } from "./AppProxy";
18
18
  import { Storage } from './App/Storage';
19
+ import type { MagixEventAddListener, MagixEventDispatcher, MagixEventRemoveListener } from './App/MagixEvent';
19
20
 
20
- export class AppContext<TAttrs extends Record<string, any>, AppOptions = any> {
21
- public readonly emitter: Emittery<AppEmitterEvent<TAttrs>>;
21
+ export class AppContext<TAttributes = any, TMagixEventPayloads = any, TAppOptions = any> {
22
+ public readonly emitter: Emittery<AppEmitterEvent<TAttributes>>;
22
23
  public readonly mobxUtils = {
23
24
  autorun,
24
25
  reaction,
@@ -40,45 +41,45 @@ export class AppContext<TAttrs extends Record<string, any>, AppOptions = any> {
40
41
  private boxManager: BoxManager,
41
42
  public appId: string,
42
43
  private appProxy: AppProxy,
43
- private appOptions?: AppOptions | (() => AppOptions),
44
+ private appOptions?: TAppOptions | (() => TAppOptions),
44
45
  ) {
45
46
  this.emitter = appProxy.appEmitter;
46
47
  this.isAddApp = appProxy.isAddApp;
47
48
  }
48
49
 
49
- public getDisplayer() {
50
+ public getDisplayer = () => {
50
51
  return this.manager.displayer;
51
52
  }
52
53
 
53
- public getAttributes(): TAttrs | undefined {
54
+ /** @deprecated Use context.storage.state instead. */
55
+ public getAttributes = (): TAttributes | undefined => {
54
56
  return this.appProxy.attributes;
55
57
  }
56
58
 
57
- public getScenes(): SceneDefinition[] | undefined {
59
+ public getScenes = (): SceneDefinition[] | undefined => {
58
60
  const appAttr = this.store.getAppAttributes(this.appId);
59
61
  if (appAttr?.isDynamicPPT) {
60
- const appProxy = this.manager.appProxies.get(this.appId);
61
- if (appProxy) {
62
- return appProxy.scenes;
63
- }
62
+ return this.appProxy.scenes;
64
63
  } else {
65
64
  return appAttr?.options["scenes"];
66
65
  }
67
66
  }
68
67
 
69
- public getView(): View | undefined {
68
+ public getView = (): View | undefined => {
70
69
  return this.appProxy.view;
71
70
  }
72
71
 
73
- public getInitScenePath() {
72
+ public getInitScenePath = () => {
74
73
  return this.manager.getAppInitPath(this.appId);
75
74
  }
76
75
 
77
- public getIsWritable(): boolean {
76
+ /** Get App writable status. */
77
+ public getIsWritable = (): boolean => {
78
78
  return this.manager.canOperate;
79
79
  }
80
80
 
81
- public getBox(): ReadonlyTeleBox {
81
+ /** Get the App Window UI box. */
82
+ public getBox = (): ReadonlyTeleBox => {
82
83
  const box = this.boxManager.getBox(this.appId);
83
84
  if (box) {
84
85
  return box;
@@ -87,27 +88,30 @@ export class AppContext<TAttrs extends Record<string, any>, AppOptions = any> {
87
88
  }
88
89
  }
89
90
 
90
- public getRoom(): Room | undefined {
91
+ public getRoom = (): Room | undefined => {
91
92
  return this.manager.room;
92
93
  }
93
94
 
94
- public setAttributes(attributes: TAttrs) {
95
+ /** @deprecated Use context.storage.setState instead. */
96
+ public setAttributes = (attributes: TAttributes) => {
95
97
  this.manager.safeSetAttributes({ [this.appId]: attributes });
96
98
  }
97
99
 
98
- public updateAttributes(keys: string[], value: any) {
100
+ /** @deprecated Use context.storage.setState instead. */
101
+ public updateAttributes = (keys: string[], value: any) => {
99
102
  if (this.manager.attributes[this.appId]) {
100
103
  this.manager.safeUpdateAttributes([this.appId, ...keys], value);
101
104
  }
102
105
  }
103
106
 
104
- public async setScenePath(scenePath: string): Promise<void> {
107
+ public setScenePath = async (scenePath: string): Promise<void> => {
105
108
  if (!this.appProxy.box) return;
106
109
  this.appProxy.setFullPath(scenePath);
107
- this.appProxy.context.switchAppToWriter(this.appId);
110
+ // 兼容 15 版本 SDK 的切页
111
+ this.getRoom()?.setScenePath(scenePath);
108
112
  }
109
113
 
110
- public mountView(dom: HTMLDivElement): void {
114
+ public mountView = (dom: HTMLDivElement): void => {
111
115
  const view = this.getView();
112
116
  if (view) {
113
117
  view.divElement = dom;
@@ -118,15 +122,47 @@ export class AppContext<TAttrs extends Record<string, any>, AppOptions = any> {
118
122
  }
119
123
  }
120
124
 
121
- public getAppOptions(): AppOptions | undefined {
122
- return typeof this.appOptions === 'function' ? (this.appOptions as () => AppOptions)() : this.appOptions
125
+ /** Get the local App options. */
126
+ public getAppOptions = (): TAppOptions | undefined => {
127
+ return typeof this.appOptions === 'function' ? (this.appOptions as () => TAppOptions)() : this.appOptions
123
128
  }
124
129
 
125
- public createStorage<TState>(storeId: string, defaultState?: TState): Storage<TState> {
130
+ private _storage?: Storage<TAttributes>
131
+
132
+ /** Main Storage for attributes. */
133
+ public get storage(): Storage<TAttributes> {
134
+ if (!this._storage) {
135
+ this._storage = new Storage(this);
136
+ }
137
+ return this._storage;
138
+ }
139
+
140
+ /**
141
+ * Create separated storages for flexible state management.
142
+ * @param storeId Namespace for the storage. Storages of the same namespace share the same data.
143
+ * @param defaultState Default state for initial storage creation.
144
+ * @returns
145
+ */
146
+ public createStorage = <TState>(storeId: string, defaultState?: TState): Storage<TState> => {
126
147
  const storage = new Storage(this, storeId, defaultState);
127
148
  this.emitter.on("destroy", () => {
128
149
  storage.destroy();
129
150
  });
130
151
  return storage;
131
152
  }
153
+
154
+ /** Dispatch events to other clients (and self). */
155
+ public dispatchMagixEvent: MagixEventDispatcher<TMagixEventPayloads> = (...args) => {
156
+ // can't dispatch events on replay mode
157
+ return this.manager.room?.dispatchMagixEvent(...args);
158
+ }
159
+
160
+ /** Listen to events from others clients (and self messages). */
161
+ public addMagixEventListener: MagixEventAddListener<TMagixEventPayloads> = (event, handler, options) => {
162
+ this.manager.displayer.addMagixEventListener(event, handler as WhiteEventListener, options);
163
+ return () => this.manager.displayer.removeMagixEventListener(event, handler as WhiteEventListener);
164
+ }
165
+
166
+ /** Remove a Magix event listener. */
167
+ public removeMagixEventListener = this.manager.displayer.removeMagixEventListener.bind(this.manager.displayer) as MagixEventRemoveListener<TMagixEventPayloads>
132
168
  }
@@ -1,10 +1,10 @@
1
- import { callbacks } from './index';
2
- import { Events, MagixEventName } from './constants';
3
- import type { Event } from "white-web-sdk";
1
+ import { callbacks, emitter } from "./index";
2
+ import { Events, MagixEventName } from "./constants";
3
+ import { isEqual, omit } from "lodash";
4
+ import { setViewFocusScenePath } from "./Utils/Common";
5
+ import type { AnimationMode, Camera, Event } from "white-web-sdk";
4
6
  import type { AppManager } from "./AppManager";
5
7
  import type { TeleBoxState } from "@netless/telebox-insider";
6
- import { setViewFocusScenePath } from './Utils/Common';
7
-
8
8
  export class AppListeners {
9
9
  private displayer = this.manager.displayer;
10
10
 
@@ -34,10 +34,6 @@ export class AppListeners {
34
34
  this.appResizeHandler(data.payload);
35
35
  break;
36
36
  }
37
- case Events.SwitchViewsToFreedom: {
38
- this.switchViewsToFreedomHandler();
39
- break;
40
- }
41
37
  case Events.AppBoxStateChange: {
42
38
  this.boxStateChangeHandler(data.payload);
43
39
  break;
@@ -46,10 +42,18 @@ export class AppListeners {
46
42
  this.setMainViewScenePathHandler(data.payload);
47
43
  break;
48
44
  }
45
+ case Events.MoveCamera: {
46
+ this.moveCameraHandler(data.payload);
47
+ break;
48
+ }
49
49
  case Events.MoveCameraToContain: {
50
50
  this.moveCameraToContainHandler(data.payload);
51
51
  break;
52
52
  }
53
+ case Events.CursorMove: {
54
+ this.cursorMoveHandler(data.payload);
55
+ break;
56
+ }
53
57
  default:
54
58
  break;
55
59
  }
@@ -65,19 +69,27 @@ export class AppListeners {
65
69
  this.manager.room?.refreshViewSize();
66
70
  };
67
71
 
68
- private switchViewsToFreedomHandler = () => {
69
- this.manager.viewManager.freedomAllViews();
70
- };
71
-
72
72
  private boxStateChangeHandler = (state: TeleBoxState) => {
73
73
  callbacks.emit("boxStateChange", state);
74
- }
74
+ };
75
75
 
76
76
  private setMainViewScenePathHandler = ({ nextScenePath }: { nextScenePath: string }) => {
77
77
  setViewFocusScenePath(this.manager.mainView, nextScenePath);
78
- }
78
+ callbacks.emit("mainViewScenePathChange", nextScenePath);
79
+ };
80
+
81
+ private moveCameraHandler = (
82
+ payload: Camera & { animationMode?: AnimationMode | undefined }
83
+ ) => {
84
+ if (isEqual(omit(payload, ["animationMode"]), { ...this.manager.mainView.camera })) return;
85
+ this.manager.mainView.moveCamera(payload);
86
+ };
79
87
 
80
88
  private moveCameraToContainHandler = (payload: any) => {
81
89
  this.manager.mainView.moveCameraToContain(payload);
82
- }
90
+ };
91
+
92
+ private cursorMoveHandler = (payload: any) => {
93
+ emitter.emit("cursorMove", payload);
94
+ };
83
95
  }