@netless/window-manager 0.4.0-canary.14 → 0.4.0-canary.18

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 (49) hide show
  1. package/.vscode/settings.json +1 -0
  2. package/CHANGELOG.md +29 -1
  3. package/README.md +1 -0
  4. package/dist/AppListener.d.ts +1 -0
  5. package/dist/AppManager.d.ts +10 -7
  6. package/dist/AppProxy.d.ts +3 -2
  7. package/dist/AttributesDelegate.d.ts +2 -2
  8. package/dist/BoxManager.d.ts +5 -3
  9. package/dist/BuiltinApps.d.ts +0 -1
  10. package/dist/Cursor/Cursor.d.ts +8 -11
  11. package/dist/Cursor/index.d.ts +5 -15
  12. package/dist/Register/storage.d.ts +5 -1
  13. package/dist/Utils/Common.d.ts +4 -1
  14. package/dist/Utils/RoomHacker.d.ts +1 -1
  15. package/dist/View/MainView.d.ts +3 -2
  16. package/dist/constants.d.ts +3 -2
  17. package/dist/index.d.ts +16 -2
  18. package/dist/index.es.js +41 -1
  19. package/dist/index.es.js.map +1 -1
  20. package/dist/index.umd.js +41 -1
  21. package/dist/index.umd.js.map +1 -1
  22. package/dist/style.css +1 -1
  23. package/docs/api.md +36 -6
  24. package/docs/concept.md +9 -0
  25. package/package.json +5 -5
  26. package/src/AppContext.ts +1 -4
  27. package/src/AppListener.ts +14 -6
  28. package/src/AppManager.ts +96 -50
  29. package/src/AppProxy.ts +13 -8
  30. package/src/AttributesDelegate.ts +2 -2
  31. package/src/BoxManager.ts +33 -19
  32. package/src/BuiltinApps.ts +0 -1
  33. package/src/Cursor/Cursor.ts +22 -36
  34. package/src/Cursor/index.ts +33 -135
  35. package/src/Register/index.ts +25 -16
  36. package/src/Register/loader.ts +1 -1
  37. package/src/Register/storage.ts +6 -1
  38. package/src/Utils/Common.ts +32 -1
  39. package/src/Utils/RoomHacker.ts +28 -15
  40. package/src/View/MainView.ts +10 -11
  41. package/src/constants.ts +3 -2
  42. package/src/index.ts +61 -2
  43. package/src/shim.d.ts +2 -1
  44. package/src/style.css +1 -1
  45. package/vite.config.js +5 -2
  46. package/dist/Base/Context.d.ts +0 -12
  47. package/dist/Base/index.d.ts +0 -7
  48. package/src/Base/Context.ts +0 -45
  49. package/src/Base/index.ts +0 -10
package/src/BoxManager.ts CHANGED
@@ -1,12 +1,11 @@
1
1
  import { AppAttributes, Events, MIN_HEIGHT, MIN_WIDTH } from "./constants";
2
- import { debounce, maxBy } from "lodash";
2
+ import { debounce } from "lodash";
3
+ import { emitter, WindowManager } from "./index";
3
4
  import {
4
- TELE_BOX_MANAGER_EVENT,
5
5
  TELE_BOX_STATE,
6
6
  TeleBoxCollector,
7
7
  TeleBoxManager,
8
8
  } from "@netless/telebox-insider";
9
- import { emitter, WindowManager } from "./index";
10
9
  import type { AddAppOptions, AppInitState, EmitterType, CallbacksType } from "./index";
11
10
  import type {
12
11
  TeleBoxManagerUpdateConfig,
@@ -15,6 +14,7 @@ import type {
15
14
  TeleBoxManagerConfig,
16
15
  TeleBoxColorScheme,
17
16
  TeleBoxRect,
17
+ TeleBoxConfig,
18
18
  } from "@netless/telebox-insider";
19
19
  import type Emittery from "emittery";
20
20
  import type { NetlessApp } from "./typings";
@@ -57,6 +57,7 @@ export type BoxManagerContext = {
57
57
  canOperate: () => boolean;
58
58
  notifyContainerRectUpdate: (rect: TeleBoxRect) => void;
59
59
  cleanFocus: () => void;
60
+ setAppFocus: (appId: string) => void;
60
61
  };
61
62
 
62
63
  export const createBoxManager = (
@@ -74,6 +75,7 @@ export const createBoxManager = (
74
75
  notifyContainerRectUpdate: (rect: TeleBoxRect) =>
75
76
  manager.appManager?.notifyContainerRectUpdate(rect),
76
77
  cleanFocus: () => manager.appManager?.store.cleanFocus(),
78
+ setAppFocus: (appId: string) => manager.appManager?.store.setAppFocus(appId, true),
77
79
  callbacks,
78
80
  emitter,
79
81
  },
@@ -90,17 +92,32 @@ export class BoxManager {
90
92
  ) {
91
93
  const { emitter, callbacks } = context;
92
94
  this.teleBoxManager = this.setupBoxManager(createTeleBoxManagerConfig);
93
- this.teleBoxManager.events.on(TELE_BOX_MANAGER_EVENT.State, state => {
94
- if (state) {
95
- this.context.callbacks.emit("boxStateChange", state);
96
- this.context.emitter.emit("boxStateChange", state);
97
- }
95
+
96
+ // 使用 _xxx$.reaction 订阅修改的值, 不管有没有 skipUpdate, 修改值都会触发回调
97
+ this.teleBoxManager._state$.reaction(state => {
98
+ callbacks.emit("boxStateChange", state);
99
+ emitter.emit("boxStateChange", state);
100
+ });
101
+
102
+ this.teleBoxManager._darkMode$.reaction(darkMode => {
103
+ callbacks.emit("darkModeChange", darkMode);
98
104
  });
105
+ this.teleBoxManager._prefersColorScheme$.reaction(colorScheme => {
106
+ callbacks.emit("prefersColorSchemeChange", colorScheme);
107
+ });
108
+
109
+ // events.on 的值则会根据 skipUpdate 来决定是否触发回调
99
110
  this.teleBoxManager.events.on("minimized", minimized => {
100
111
  this.context.safeSetAttributes({ minimized });
101
112
  if (minimized) {
102
113
  this.context.cleanFocus();
103
114
  this.blurAllBox();
115
+ } else {
116
+ const topBox = this.getTopBox();
117
+ if (topBox) {
118
+ this.context.setAppFocus(topBox.id);
119
+ this.focusBox({ appId: topBox.id }, false);
120
+ }
104
121
  }
105
122
  });
106
123
  this.teleBoxManager.events.on("maximized", maximized => {
@@ -136,12 +153,6 @@ export class BoxManager {
136
153
  }
137
154
  }
138
155
  });
139
- this.teleBoxManager.events.on("dark_mode", darkMode => {
140
- callbacks.emit("darkModeChange", darkMode);
141
- });
142
- this.teleBoxManager.events.on("prefers_color_scheme", colorScheme => {
143
- callbacks.emit("prefersColorSchemeChange", colorScheme);
144
- });
145
156
  this.teleBoxManager.events.on("z_index", box => {
146
157
  this.context.updateAppState(box.id, AppAttributes.ZIndex, box.zIndex);
147
158
  });
@@ -150,7 +161,7 @@ export class BoxManager {
150
161
 
151
162
  private playgroundSizeChangeListener = () => {
152
163
  this.updateManagerRect();
153
- }
164
+ };
154
165
 
155
166
  private get mainView() {
156
167
  return this.context.getMainView();
@@ -281,8 +292,7 @@ export class BoxManager {
281
292
  }
282
293
 
283
294
  public getTopBox(): ReadonlyTeleBox | undefined {
284
- const boxes = this.teleBoxManager.query();
285
- return maxBy(boxes, "zIndex");
295
+ return this.teleBoxManager.topBox;
286
296
  }
287
297
 
288
298
  public updateBoxState(state?: AppInitState): void {
@@ -359,9 +369,9 @@ export class BoxManager {
359
369
  this.teleBoxManager.updateAll(config);
360
370
  }
361
371
 
362
- public setMaximized(maximized: boolean) {
372
+ public setMaximized(maximized: boolean, skipUpdate = true): void {
363
373
  if (maximized !== this.maximized) {
364
- this.teleBoxManager.setMaximized(maximized, true);
374
+ this.teleBoxManager.setMaximized(maximized, skipUpdate);
365
375
  }
366
376
  }
367
377
 
@@ -379,6 +389,10 @@ export class BoxManager {
379
389
  }
380
390
  }
381
391
 
392
+ public updateBox(id: string, payload: TeleBoxConfig, skipUpdate = true): void {
393
+ this.teleBoxManager.update(id, payload, skipUpdate);
394
+ }
395
+
382
396
  public setReadonly(readonly: boolean) {
383
397
  this.teleBoxManager.setReadonly(readonly);
384
398
  }
@@ -1,7 +1,6 @@
1
1
  import AppDocsViewer from "@netless/app-docs-viewer";
2
2
  import AppMediaPlayer, { setOptions } from "@netless/app-media-player";
3
3
  import { WindowManager } from "./index";
4
- import "@netless/app-docs-viewer/dist/style.css";
5
4
 
6
5
  export const setupBuiltin = () => {
7
6
  if (WindowManager.debug) {
@@ -1,42 +1,34 @@
1
- import App from './Cursor.svelte';
2
- import { ApplianceMap } from './icons';
3
- import { ApplianceNames } from 'white-web-sdk';
4
- import { CursorState } from '../constants';
5
- import { Fields } from '../AttributesDelegate';
6
- import { get, omit } from 'lodash';
7
- import type { Position } from '../AttributesDelegate';
1
+ import App from "./Cursor.svelte";
2
+ import { ApplianceMap } from "./icons";
3
+ import { ApplianceNames } from "white-web-sdk";
4
+ import { omit } from "lodash";
5
+ import type { Position } from "../AttributesDelegate";
8
6
  import type { RoomMember } from "white-web-sdk";
9
7
  import type { CursorManager } from "./index";
10
8
  import type { SvelteComponent } from "svelte";
11
- import { Base } from '../Base';
12
- import type { AppManager } from '../AppManager';
9
+ import type { AppManager } from "../AppManager";
13
10
 
14
11
  export type Payload = {
15
- [key: string]: any
16
- }
17
-
12
+ [key: string]: any;
13
+ };
18
14
 
19
- export class Cursor extends Base {
15
+ export class Cursor {
20
16
  private member?: RoomMember;
21
17
  private timer?: number;
22
18
  private component?: SvelteComponent;
23
19
 
24
20
  constructor(
25
- manager: AppManager,
26
- addCursorChangeListener: (uid: string, callback: (position: Position, state: CursorState) => void) => void,
27
- private cursors: any,
21
+ private manager: AppManager,
28
22
  private memberId: string,
29
23
  private cursorManager: CursorManager,
30
- private wrapper?: HTMLElement,
24
+ private wrapper?: HTMLElement
31
25
  ) {
32
- super(manager);
33
26
  this.setMember();
34
27
  this.createCursor();
35
- addCursorChangeListener(this.memberId, this.onCursorChange);
36
28
  this.autoHidden();
37
29
  }
38
30
 
39
- private onCursorChange = (position: Position, state: CursorState) => {
31
+ public move = (position: Position) => {
40
32
  if (position.type === "main") {
41
33
  const rect = this.cursorManager.wrapperRect;
42
34
  if (this.component && rect) {
@@ -45,7 +37,6 @@ export class Cursor extends Base {
45
37
  }
46
38
  } else {
47
39
  const focusView = this.cursorManager.focusView;
48
- // TODO 可以存一个当前 focusView 的 Rect 这样只有 focus 切换的时候才调用 getBoundingClientRect
49
40
  const viewRect = focusView?.divElement?.getBoundingClientRect();
50
41
  const viewCamera = focusView?.camera;
51
42
  if (focusView && viewRect && viewCamera && this.component) {
@@ -53,10 +44,11 @@ export class Cursor extends Base {
53
44
  this.moveCursor(position, viewRect, focusView);
54
45
  }
55
46
  }
56
- if (state && state === CursorState.Leave) {
57
- this.hide();
58
- }
59
- }
47
+ };
48
+
49
+ public leave = () => {
50
+ this.hide();
51
+ };
60
52
 
61
53
  private moveCursor(cursor: Position, rect: DOMRect, view: any) {
62
54
  const { x, y, type } = cursor;
@@ -124,21 +116,12 @@ export class Cursor extends Base {
124
116
  }
125
117
  }
126
118
 
127
- public get cursorState(): CursorState | undefined {
128
- return get(this.cursors, [this.memberId, Fields.CursorState]);
129
- }
130
-
131
- public get cursorPosition(): Position | undefined {
132
- return get(this.cursors, [this.memberId, Fields.Position]);
133
- }
134
-
135
119
  private autoHidden() {
136
120
  if (this.timer) {
137
121
  clearTimeout(this.timer);
138
122
  }
139
123
  this.timer = window.setTimeout(() => {
140
124
  this.hide();
141
- this.store.updateCursorState(this.memberId, CursorState.Leave);
142
125
  }, 1000 * 10); // 10 秒钟自动隐藏
143
126
  }
144
127
 
@@ -176,7 +159,7 @@ export class Cursor extends Base {
176
159
  }
177
160
 
178
161
  public setMember() {
179
- this.member = this.context.findMemberByUid(this.memberId);
162
+ this.member = this.manager.findMemberByUid(this.memberId);
180
163
  this.updateComponent();
181
164
  }
182
165
 
@@ -188,13 +171,16 @@ export class Cursor extends Base {
188
171
  if (this.component) {
189
172
  this.component.$destroy();
190
173
  }
191
- this.manager.refresher?.remove(this.memberId);
192
174
  this.cursorManager.cursorInstances.delete(this.memberId);
175
+ if (this.timer) {
176
+ clearTimeout(this.timer);
177
+ }
193
178
  }
194
179
 
195
180
  public hide() {
196
181
  if (this.component) {
197
182
  this.component.$set({ visible: false });
183
+ this.destroy();
198
184
  }
199
185
  }
200
186
  }
@@ -1,13 +1,10 @@
1
- import { autorun } from "white-web-sdk";
2
- import { Base } from "../Base";
3
- import { compact, debounce, get, uniq } from "lodash";
1
+ import { compact, throttle, uniq } from "lodash";
4
2
  import { Cursor } from "./Cursor";
5
- import { CursorState } from "../constants";
3
+ import { CursorState, Events } from "../constants";
6
4
  import { emitter, WindowManager } from "../index";
7
- import { Fields } from "../AttributesDelegate";
8
- import { onObjectInserted } from "../Utils/Reactive";
9
5
  import { SideEffectManager } from "side-effect-manager";
10
- import type { PositionType, Position } from "../AttributesDelegate";
6
+ import type { CursorMovePayload } from "../index";
7
+ import type { PositionType } from "../AttributesDelegate";
11
8
  import type { Point, RoomMember, View } from "white-web-sdk";
12
9
  import type { AppManager } from "../AppManager";
13
10
 
@@ -21,30 +18,36 @@ export type MoveCursorParams = {
21
18
  x: number;
22
19
  y: number;
23
20
  };
24
- export class CursorManager extends Base {
21
+ export class CursorManager {
25
22
  public containerRect?: DOMRect;
26
23
  public wrapperRect?: DOMRect;
27
24
  public cursorInstances: Map<string, Cursor> = new Map();
28
25
  public roomMembers?: readonly RoomMember[];
29
26
  private mainViewElement?: HTMLDivElement;
30
27
  private sideEffectManager = new SideEffectManager();
28
+ private store = this.manager.store;
31
29
 
32
- constructor(private appManager: AppManager) {
33
- super(appManager);
34
- this.roomMembers = this.appManager.room?.state.roomMembers;
30
+ constructor(private manager: AppManager) {
31
+ this.roomMembers = this.manager.room?.state.roomMembers;
35
32
  const wrapper = WindowManager.wrapper;
36
33
  if (wrapper) {
37
34
  this.setupWrapper(wrapper);
38
35
  }
39
- emitter.on("onReconnected", () => {
40
- this.onReconnect();
36
+ emitter.on("cursorMove", payload => {
37
+ let cursorInstance = this.cursorInstances.get(payload.uid);
38
+ if (!cursorInstance) {
39
+ cursorInstance = new Cursor(this.manager, payload.uid, this, WindowManager.wrapper);
40
+ this.cursorInstances.set(payload.uid, cursorInstance);
41
+ }
42
+ if (payload.state === CursorState.Leave) {
43
+ cursorInstance.leave();
44
+ } else {
45
+ cursorInstance.move(payload.position);
46
+ }
41
47
  });
42
48
  }
43
49
 
44
50
  public setupWrapper(wrapper: HTMLElement) {
45
- if (this.manager.refresher?.hasReactor("cursors")) {
46
- this.destroy();
47
- }
48
51
  this.sideEffectManager.add(() => {
49
52
  wrapper.addEventListener("pointerenter", this.mouseMoveListener);
50
53
  wrapper.addEventListener("pointermove", this.mouseMoveListener);
@@ -56,77 +59,42 @@ export class CursorManager extends Base {
56
59
  };
57
60
  });
58
61
 
59
- this.initCursorAttributes();
60
62
  this.wrapperRect = wrapper.getBoundingClientRect();
61
- this.startReaction(wrapper);
62
63
  }
63
64
 
64
65
  public setMainViewDivElement(div: HTMLDivElement) {
65
66
  this.mainViewElement = div;
66
67
  }
67
68
 
68
- private startReaction(wrapper: HTMLElement) {
69
- this.manager.refresher?.add("cursors", () => {
70
- return onObjectInserted(this.cursors, () => {
71
- this.handleRoomMembersChange(wrapper);
72
- });
73
- });
74
- }
75
-
76
69
  private getUids = (members: readonly RoomMember[] | undefined) => {
77
70
  return compact(uniq(members?.map(member => member.payload?.uid)));
78
71
  };
79
72
 
80
- private handleRoomMembersChange = debounce((wrapper: HTMLElement) => {
81
- const uids = this.getUids(this.roomMembers);
82
- const cursors = Object.keys(this.cursors);
83
- if (uids?.length) {
84
- cursors.map(uid => {
85
- if (uids.includes(uid) && !this.cursorInstances.has(uid)) {
86
- if (uid === this.context.uid) {
87
- return;
88
- }
89
- const component = new Cursor(
90
- this.appManager,
91
- this.addCursorChangeListener,
92
- this.cursors,
93
- uid,
94
- this,
95
- wrapper
96
- );
97
- this.cursorInstances.set(uid, component);
98
- }
99
- });
100
- }
101
- }, 100);
102
-
103
- public get cursors() {
104
- return this.manager.attributes?.[Fields.Cursors];
105
- }
106
-
107
73
  public get boxState() {
108
74
  return this.store.getBoxState();
109
75
  }
110
76
 
111
77
  public get focusView() {
112
- return this.appManager.focusApp?.view;
78
+ return this.manager.focusApp?.view;
113
79
  }
114
80
 
115
- private mouseMoveListener = debounce((event: MouseEvent) => {
81
+ private mouseMoveListener = throttle((event: MouseEvent) => {
116
82
  this.updateCursor(this.getType(event), event.clientX, event.clientY);
117
- }, 5);
83
+ }, 16);
118
84
 
119
85
  private updateCursor(event: EventType, clientX: number, clientY: number) {
120
86
  if (this.wrapperRect && this.manager.canOperate) {
121
- const view = event.type === "main" ? this.appManager.mainView : this.focusView;
87
+ const view = event.type === "main" ? this.manager.mainView : this.focusView;
122
88
  const point = this.getPoint(view, clientX, clientY);
123
89
  if (point) {
124
- this.setNormalCursorState();
125
- this.store.updateCursor(this.context.uid, {
126
- x: point.x,
127
- y: point.y,
128
- ...event,
129
- });
90
+ this.manager.dispatchInternalEvent(Events.CursorMove, {
91
+ uid: this.manager.uid,
92
+ position: {
93
+ x: point.x,
94
+ y: point.y,
95
+ type: event.type,
96
+ },
97
+ } as CursorMovePayload);
130
98
  }
131
99
  }
132
100
  }
@@ -151,7 +119,7 @@ export class CursorManager extends Base {
151
119
  */
152
120
  private getType = (event: MouseEvent | Touch): EventType => {
153
121
  const target = event.target as HTMLElement;
154
- const focusApp = this.appManager.focusApp;
122
+ const focusApp = this.manager.focusApp;
155
123
  switch (target.parentElement) {
156
124
  case this.mainViewElement: {
157
125
  return { type: "main" };
@@ -165,25 +133,8 @@ export class CursorManager extends Base {
165
133
  }
166
134
  };
167
135
 
168
- private initCursorAttributes() {
169
- this.store.updateCursor(this.context.uid, {
170
- x: 0,
171
- y: 0,
172
- type: "main",
173
- });
174
- this.store.updateCursorState(this.context.uid, CursorState.Leave);
175
- }
176
-
177
- private setNormalCursorState() {
178
- const cursorState = this.store.getCursorState(this.context.uid);
179
- if (cursorState !== CursorState.Normal) {
180
- this.store.updateCursorState(this.context.uid, CursorState.Normal);
181
- }
182
- }
183
-
184
136
  private mouseLeaveListener = () => {
185
- this.hideCursor(this.context.uid);
186
- this.store.updateCursorState(this.context.uid, CursorState.Leave);
137
+ this.hideCursor(this.manager.uid);
187
138
  };
188
139
 
189
140
  public updateContainerRect() {
@@ -191,16 +142,6 @@ export class CursorManager extends Base {
191
142
  this.wrapperRect = WindowManager.wrapper?.getBoundingClientRect();
192
143
  }
193
144
 
194
- public setRoomMembers(members: readonly RoomMember[]) {
195
- this.roomMembers = members;
196
- this.cursorInstances.forEach(cursor => {
197
- cursor.setMember();
198
- });
199
- if (WindowManager.wrapper) {
200
- this.handleRoomMembersChange(WindowManager.wrapper);
201
- }
202
- }
203
-
204
145
  public deleteCursor(uid: string) {
205
146
  this.store.cleanCursor(uid);
206
147
  const cursor = this.cursorInstances.get(uid);
@@ -216,48 +157,6 @@ export class CursorManager extends Base {
216
157
  }
217
158
  }
218
159
 
219
- public cleanMemberAttributes(members: readonly RoomMember[]) {
220
- const uids = this.getUids(members);
221
- const needDeleteIds: string[] = [];
222
- const cursors = Object.keys(this.cursors);
223
- cursors.map(cursorId => {
224
- const index = uids.findIndex(id => id === cursorId);
225
- if (index === -1) {
226
- needDeleteIds.push(cursorId);
227
- }
228
- });
229
- needDeleteIds.forEach(uid => {
230
- this.deleteCursor(uid);
231
- });
232
- }
233
-
234
- public onReconnect() {
235
- if (this.cursorInstances.size) {
236
- this.cursorInstances.forEach(cursor => cursor.destroy());
237
- this.cursorInstances.clear();
238
- }
239
- this.roomMembers = this.appManager.room?.state.roomMembers;
240
- if (WindowManager.wrapper) {
241
- this.handleRoomMembersChange(WindowManager.wrapper);
242
- }
243
- }
244
-
245
- public addCursorChangeListener = (
246
- uid: string,
247
- callback: (position: Position, state: CursorState) => void
248
- ) => {
249
- this.manager.refresher?.add(uid, () => {
250
- const disposer = autorun(() => {
251
- const position = get(this.cursors, [uid, Fields.Position]);
252
- const state = get(this.cursors, [uid, Fields.CursorState]);
253
- if (position) {
254
- callback(position, state);
255
- }
256
- });
257
- return disposer;
258
- });
259
- };
260
-
261
160
  public destroy() {
262
161
  this.sideEffectManager.flushAll();
263
162
  if (this.cursorInstances.size) {
@@ -266,6 +165,5 @@ export class CursorManager extends Base {
266
165
  });
267
166
  this.cursorInstances.clear();
268
167
  }
269
- this.manager.refresher?.remove("cursors");
270
168
  }
271
169
  }
@@ -10,34 +10,39 @@ class AppRegister {
10
10
 
11
11
  public async register(params: RegisterParams): Promise<void> {
12
12
  this.registered.set(params.kind, params);
13
-
14
- const srcOrAppOrFunction = params.src
15
- let downloadApp: () => Promise<NetlessApp>
16
-
13
+
14
+ const srcOrAppOrFunction = params.src;
15
+ let downloadApp: () => Promise<NetlessApp>;
16
+
17
17
  if (typeof srcOrAppOrFunction === "string") {
18
18
  downloadApp = async () => {
19
- const appClass = await loadApp(srcOrAppOrFunction, params.kind);
19
+ let appClass = (await loadApp(srcOrAppOrFunction, params.kind)) as any;
20
20
  if (appClass) {
21
- return appClass
21
+ if (appClass.__esModule) {
22
+ appClass = appClass.default;
23
+ }
24
+ return appClass;
22
25
  } else {
23
- throw new Error(`[WindowManager]: load remote script failed, ${srcOrAppOrFunction}`);
26
+ throw new Error(
27
+ `[WindowManager]: load remote script failed, ${srcOrAppOrFunction}`
28
+ );
24
29
  }
25
- }
30
+ };
26
31
  } else if (typeof srcOrAppOrFunction === "function") {
27
- downloadApp = srcOrAppOrFunction
32
+ downloadApp = srcOrAppOrFunction;
28
33
  } else {
29
- downloadApp = async () => srcOrAppOrFunction
34
+ downloadApp = async () => srcOrAppOrFunction;
30
35
  }
31
36
 
32
37
  this.appClasses.set(params.kind, async () => {
33
- let app = this.appClassesCache.get(params.kind)
38
+ let app = this.appClassesCache.get(params.kind);
34
39
  if (!app) {
35
- app = downloadApp()
36
- this.appClassesCache.set(params.kind, app)
40
+ app = downloadApp();
41
+ this.appClassesCache.set(params.kind, app);
37
42
  }
38
- return app
43
+ return app;
39
44
  });
40
-
45
+
41
46
  if (params.addHooks) {
42
47
  const emitter = this.createKindEmitter(params.kind);
43
48
  if (emitter) {
@@ -46,7 +51,11 @@ class AppRegister {
46
51
  }
47
52
  }
48
53
 
49
- public async notifyApp<T extends keyof RegisterEvents>(kind: string, event: T, payload: RegisterEvents[T]) {
54
+ public async notifyApp<T extends keyof RegisterEvents>(
55
+ kind: string,
56
+ event: T,
57
+ payload: RegisterEvents[T]
58
+ ) {
50
59
  const emitter = this.kindEmitters.get(kind);
51
60
  await emitter?.emit(event, payload);
52
61
  }
@@ -8,7 +8,7 @@ const TIMEOUT = 10000; // 10 秒超时
8
8
  export const getScript = async (url: string): Promise<string> => {
9
9
  const item = await getItem(url);
10
10
  if (item) {
11
- return item;
11
+ return item.sourceCode;
12
12
  } else {
13
13
  const result = await fetchWithTimeout(url, { timeout: TIMEOUT });
14
14
  const text = await result.text();
@@ -3,6 +3,11 @@ const DatabaseName = "__WindowManagerAppCache";
3
3
  let db: IDBDatabase;
4
4
  let store: IDBObjectStore;
5
5
 
6
+ export type Item = {
7
+ kind: string;
8
+ sourceCode: string;
9
+ }
10
+
6
11
  export const initDb = async () => {
7
12
  db = await createDb();
8
13
  }
@@ -12,7 +17,7 @@ export const setItem = (key: string, val: any) => {
12
17
  return addRecord(db, { kind: key, sourceCode: val })
13
18
  };
14
19
 
15
- export const getItem = async (key: string): Promise<string | null> => {
20
+ export const getItem = async (key: string): Promise<Item | null> => {
16
21
  if (!db) return null;
17
22
  return await query(db, key);
18
23
  };