@netless/window-manager 1.0.0-canary.9 → 1.0.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 (132) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +90 -64
  3. package/README.zh-cn.md +224 -0
  4. package/dist/index.d.ts +1133 -40
  5. package/dist/index.js +62 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/{index.es.js → index.mjs} +9480 -6984
  8. package/dist/index.mjs.map +1 -0
  9. package/dist/style.css +1 -1
  10. package/docs/advanced.md +55 -55
  11. package/docs/api.md +124 -113
  12. package/docs/app-context.md +248 -209
  13. package/docs/basic.md +25 -26
  14. package/docs/camera.md +19 -20
  15. package/docs/cn/advanced.md +137 -0
  16. package/docs/cn/api.md +309 -0
  17. package/docs/cn/app-context.md +369 -0
  18. package/docs/cn/basic.md +64 -0
  19. package/docs/cn/camera.md +53 -0
  20. package/docs/cn/concept.md +9 -0
  21. package/docs/cn/custom-max-bar.md +31 -0
  22. package/docs/cn/develop-app.md +94 -0
  23. package/docs/cn/export-pdf.md +48 -0
  24. package/docs/cn/migrate.md +60 -0
  25. package/docs/cn/replay.md +40 -0
  26. package/docs/concept.md +6 -5
  27. package/docs/custom-max-bar.md +31 -0
  28. package/docs/develop-app.md +22 -19
  29. package/docs/export-pdf.md +48 -0
  30. package/docs/migrate.md +25 -27
  31. package/docs/quickstart.md +50 -0
  32. package/docs/replay.md +20 -20
  33. package/package.json +32 -22
  34. package/src/App/AppContext.ts +105 -73
  35. package/src/App/AppPageStateImpl.ts +6 -25
  36. package/src/App/AppProxy.ts +41 -166
  37. package/src/App/MagixEvent/index.ts +38 -38
  38. package/src/App/Storage/StorageEvent.ts +13 -13
  39. package/src/App/Storage/index.ts +269 -245
  40. package/src/App/Storage/typings.ts +4 -2
  41. package/src/App/Storage/utils.ts +3 -3
  42. package/src/App/index.ts +0 -1
  43. package/src/AppListener.ts +8 -8
  44. package/src/AppManager.ts +88 -77
  45. package/src/AttributesDelegate.ts +42 -22
  46. package/src/BoxEmitter.ts +12 -6
  47. package/src/BoxManager.ts +128 -108
  48. package/src/ContainerResizeObserver.ts +75 -0
  49. package/src/Cursor/Cursor.svelte +16 -5
  50. package/src/Cursor/Cursor.svelte.d.ts +21 -0
  51. package/src/Cursor/Cursor.ts +77 -13
  52. package/src/Cursor/icons.ts +6 -0
  53. package/src/Cursor/icons2.ts +66 -0
  54. package/src/Cursor/index.ts +127 -26
  55. package/src/Helper.ts +94 -14
  56. package/src/InternalEmitter.ts +2 -7
  57. package/src/Page/index.ts +1 -1
  58. package/src/PageState.ts +6 -5
  59. package/src/ReconnectRefresher.ts +9 -4
  60. package/src/RedoUndo.ts +3 -3
  61. package/src/Register/index.ts +22 -17
  62. package/src/Register/loader.ts +26 -22
  63. package/src/Register/storage.ts +13 -13
  64. package/src/Utils/Common.ts +18 -14
  65. package/src/Utils/Reactive.ts +26 -25
  66. package/src/Utils/RoomHacker.ts +4 -4
  67. package/src/Utils/error.ts +0 -1
  68. package/src/View/IframeBridge.ts +680 -0
  69. package/src/View/MainView.ts +127 -53
  70. package/src/callback.ts +21 -1
  71. package/src/constants.ts +0 -2
  72. package/src/image/pencil-eraser-1.svg +3 -0
  73. package/src/image/pencil-eraser-2.svg +3 -0
  74. package/src/image/pencil-eraser-3.svg +3 -0
  75. package/src/index.ts +220 -83
  76. package/src/style.css +27 -10
  77. package/src/typings.ts +20 -10
  78. package/.prettierignore +0 -7
  79. package/.prettierrc.json +0 -9
  80. package/CHANGELOG.md +0 -196
  81. package/__mocks__/white-web-sdk.ts +0 -50
  82. package/dist/App/AppContext.d.ts +0 -76
  83. package/dist/App/AppPageStateImpl.d.ts +0 -21
  84. package/dist/App/AppProxy.d.ts +0 -86
  85. package/dist/App/AppViewSync.d.ts +0 -11
  86. package/dist/App/MagixEvent/index.d.ts +0 -29
  87. package/dist/App/Storage/StorageEvent.d.ts +0 -8
  88. package/dist/App/Storage/index.d.ts +0 -39
  89. package/dist/App/Storage/typings.d.ts +0 -22
  90. package/dist/App/Storage/utils.d.ts +0 -5
  91. package/dist/App/WhiteboardView.d.ts +0 -22
  92. package/dist/App/index.d.ts +0 -3
  93. package/dist/AppListener.d.ts +0 -21
  94. package/dist/AppManager.d.ts +0 -107
  95. package/dist/AttributesDelegate.d.ts +0 -80
  96. package/dist/BoxEmitter.d.ts +0 -34
  97. package/dist/BoxManager.d.ts +0 -99
  98. package/dist/BuiltinApps.d.ts +0 -5
  99. package/dist/Cursor/Cursor.d.ts +0 -39
  100. package/dist/Cursor/icons.d.ts +0 -3
  101. package/dist/Cursor/index.d.ts +0 -46
  102. package/dist/Helper.d.ts +0 -17
  103. package/dist/InternalEmitter.d.ts +0 -39
  104. package/dist/Page/PageController.d.ts +0 -21
  105. package/dist/Page/index.d.ts +0 -3
  106. package/dist/PageState.d.ts +0 -9
  107. package/dist/ReconnectRefresher.d.ts +0 -24
  108. package/dist/RedoUndo.d.ts +0 -18
  109. package/dist/Register/index.d.ts +0 -28
  110. package/dist/Register/loader.d.ts +0 -4
  111. package/dist/Register/storage.d.ts +0 -8
  112. package/dist/Utils/AppCreateQueue.d.ts +0 -15
  113. package/dist/Utils/Common.d.ts +0 -23
  114. package/dist/Utils/Reactive.d.ts +0 -6
  115. package/dist/Utils/RoomHacker.d.ts +0 -3
  116. package/dist/Utils/error.d.ts +0 -27
  117. package/dist/Utils/log.d.ts +0 -1
  118. package/dist/View/CameraSynchronizer.d.ts +0 -16
  119. package/dist/View/MainView.d.ts +0 -47
  120. package/dist/View/ViewManager.d.ts +0 -13
  121. package/dist/callback.d.ts +0 -24
  122. package/dist/constants.d.ts +0 -49
  123. package/dist/index.cjs.js +0 -46
  124. package/dist/index.umd.js +0 -46
  125. package/dist/typings.d.ts +0 -82
  126. package/jest.config.js +0 -27
  127. package/pnpm-lock.yaml +0 -6302
  128. package/src/App/AppViewSync.ts +0 -68
  129. package/src/App/WhiteboardView.ts +0 -83
  130. package/src/View/CameraSynchronizer.ts +0 -56
  131. package/vite.config.js +0 -51
  132. /package/docs/{qickstart.md → cn/quickstart.md} +0 -0
@@ -28,39 +28,43 @@ export const executeScript = (text: string, appName: string): NetlessApp => {
28
28
  return result;
29
29
  };
30
30
 
31
- export const loadApp = async (
32
- url: string,
33
- key: string,
34
- name?: string
35
- ): Promise<NetlessApp | undefined> => {
31
+ export const loadApp = async (url: string, key: string, name?: string): Promise<NetlessApp> => {
36
32
  const appName = name || Prefix + key;
37
33
  callbacks.emit("loadApp", { kind: key, status: "start" });
34
+
35
+ let text: string;
38
36
  try {
39
- const text = await getScript(url);
37
+ text = await getScript(url);
40
38
  if (!text || text.length === 0) {
41
39
  callbacks.emit("loadApp", { kind: key, status: "failed", reason: "script is empty." });
42
- return;
40
+ throw new Error("[WindowManager]: script is empty.");
43
41
  }
44
- try {
42
+ } catch (error) {
43
+ callbacks.emit("loadApp", { kind: key, status: "failed", reason: error.message });
44
+ throw error;
45
+ }
46
+ return getResult(text, appName, key);
47
+ };
48
+
49
+ const getResult = (text: string, appName: string, key: string): NetlessApp => {
50
+ try {
51
+ const result = executeScript(text, appName);
52
+ callbacks.emit("loadApp", { kind: key, status: "success" });
53
+ return result;
54
+ } catch (error: any) {
55
+ if (error.message.includes("Can only have one anonymous define call per script file")) {
56
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
57
+ // @ts-ignore
58
+ const define = window.define;
59
+ if ("function" == typeof define && define.amd) {
60
+ delete define.amd;
61
+ }
45
62
  const result = executeScript(text, appName);
46
63
  callbacks.emit("loadApp", { kind: key, status: "success" });
47
64
  return result;
48
- } catch (error: any) {
49
- if (error.message.includes("Can only have one anonymous define call per script file")) {
50
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
51
- // @ts-ignore
52
- const define = window.define;
53
- if ("function" == typeof define && define.amd) {
54
- delete define.amd;
55
- }
56
- const result = executeScript(text, appName);
57
- callbacks.emit("loadApp", { kind: key, status: "success" });
58
- return result;
59
- }
60
- callbacks.emit("loadApp", { kind: key, status: "failed", reason: error.message });
61
65
  }
62
- } catch (error: any) {
63
66
  callbacks.emit("loadApp", { kind: key, status: "failed", reason: error.message });
67
+ throw error;
64
68
  }
65
69
  };
66
70
 
@@ -6,15 +6,15 @@ let store: IDBObjectStore;
6
6
  export type Item = {
7
7
  kind: string;
8
8
  sourceCode: string;
9
- }
9
+ };
10
10
 
11
11
  export const initDb = async () => {
12
12
  db = await createDb();
13
- }
13
+ };
14
14
 
15
15
  export const setItem = (key: string, val: any) => {
16
16
  if (!db) return;
17
- return addRecord(db, { kind: key, sourceCode: val })
17
+ return addRecord(db, { kind: key, sourceCode: val });
18
18
  };
19
19
 
20
20
  export const getItem = async (key: string): Promise<Item | null> => {
@@ -30,9 +30,9 @@ export const removeItem = (key: string) => {
30
30
  function createDb(): Promise<IDBDatabase> {
31
31
  return new Promise((resolve, reject) => {
32
32
  const request = indexedDB.open(DatabaseName, 2);
33
- request.onerror = (e) => {
33
+ request.onerror = e => {
34
34
  reject(e);
35
- }
35
+ };
36
36
 
37
37
  request.onupgradeneeded = (event: any) => {
38
38
  const db = event.target.result as IDBDatabase;
@@ -40,28 +40,28 @@ function createDb(): Promise<IDBDatabase> {
40
40
  store = db.createObjectStore("apps", { keyPath: "kind" });
41
41
  store.createIndex("kind", "kind", { unique: true });
42
42
  }
43
- }
43
+ };
44
44
 
45
45
  request.onsuccess = () => {
46
46
  const db = request.result;
47
47
  resolve(db);
48
- }
49
- })
48
+ };
49
+ });
50
50
  }
51
51
 
52
52
  function query<T>(db: IDBDatabase, val: string): Promise<T | null> {
53
53
  return new Promise((resolve, reject) => {
54
54
  const index = db.transaction(["apps"]).objectStore("apps").index("kind");
55
55
  const request = index.get(val);
56
- request.onerror = (e) => reject(e);
56
+ request.onerror = e => reject(e);
57
57
  request.onsuccess = () => {
58
58
  if (request.result) {
59
59
  resolve(request.result);
60
60
  } else {
61
61
  resolve(null);
62
62
  }
63
- }
64
- })
63
+ };
64
+ });
65
65
  }
66
66
 
67
67
  function addRecord(db: IDBDatabase, payload: any): Promise<void> {
@@ -69,7 +69,7 @@ function addRecord(db: IDBDatabase, payload: any): Promise<void> {
69
69
  const request = db.transaction(["apps"], "readwrite").objectStore("apps").add(payload);
70
70
  request.onsuccess = () => resolve();
71
71
  request.onerror = () => reject();
72
- })
72
+ });
73
73
  }
74
74
 
75
75
  function deleteRecord(db: IDBDatabase, key: string): Promise<void> {
@@ -77,5 +77,5 @@ function deleteRecord(db: IDBDatabase, key: string): Promise<void> {
77
77
  const request = db.transaction(["apps"], "readwrite").objectStore("apps").delete(key);
78
78
  request.onsuccess = () => resolve();
79
79
  request.onerror = () => reject();
80
- })
80
+ });
81
81
  }
@@ -1,11 +1,11 @@
1
1
  import { appRegister } from "../Register";
2
2
  import { debounce } from "lodash";
3
- import { emitter } from "../InternalEmitter";
3
+ import { internalEmitter } from "../InternalEmitter";
4
4
  import { ROOT_DIR } from "../constants";
5
5
  import { ScenePathType } from "white-web-sdk";
6
6
  import { v4 } from "uuid";
7
7
  import type { PublicEvent } from "../callback";
8
- import type { Displayer, ViewVisionMode, Room, View , SceneDefinition} from "white-web-sdk";
8
+ import type { Displayer, ViewVisionMode, Room, View, SceneDefinition } from "white-web-sdk";
9
9
  import type Emittery from "emittery";
10
10
 
11
11
  export const genAppId = async (kind: string) => {
@@ -30,12 +30,6 @@ export const setViewSceneIndex = (view: View, index: number) => {
30
30
  }
31
31
  };
32
32
 
33
- export const releaseView = (view: View) => {
34
- if (!(view as any).didRelease) {
35
- view.release();
36
- }
37
- }
38
-
39
33
  export const setScenePath = (room: Room | undefined, scenePath: string) => {
40
34
  if (room && room.isWritable) {
41
35
  if (room.state.sceneState.scenePath !== scenePath) {
@@ -75,15 +69,15 @@ export const setViewMode = (view: View, mode: ViewVisionMode) => {
75
69
  };
76
70
 
77
71
  export const emitError = (error: Error) => {
78
- if (emitter.listenerCount("error") > 0) {
79
- emitter.emit("error", error);
72
+ if (internalEmitter.listenerCount("error") > 0) {
73
+ internalEmitter.emit("error", error);
80
74
  } else {
81
75
  console.log("[WindowManager]:", error);
82
76
  }
83
77
  };
84
78
 
85
79
  export const addEmitterOnceListener = (event: any, listener: any) => {
86
- emitter.once(event).then(listener);
80
+ internalEmitter.once(event).then(listener);
87
81
  };
88
82
 
89
83
  export const notifyMainViewModeChange = debounce(
@@ -110,9 +104,19 @@ export const entireScenes = (displayer: Displayer) => {
110
104
  return displayer.entireScenes();
111
105
  };
112
106
 
113
- export const putScenes = (room: Room | undefined, path: string, scenes: SceneDefinition[], index?: number) => {
107
+ export const putScenes = (
108
+ room: Room | undefined,
109
+ path: string,
110
+ scenes: SceneDefinition[],
111
+ index?: number
112
+ ) => {
113
+ for (let i = 0; i < scenes.length; ++i) {
114
+ if (scenes[i].name?.includes("/")) {
115
+ throw new Error("scenes name can not have '/'");
116
+ }
117
+ }
114
118
  return room?.putScenes(path, scenes, index);
115
- }
119
+ };
116
120
 
117
121
  export const isValidScenePath = (scenePath: string) => {
118
122
  return scenePath.startsWith("/");
@@ -157,4 +161,4 @@ export const isRootDirPage = (scenePath: string) => {
157
161
  return prev;
158
162
  }, 0);
159
163
  return delimiterCount === 1;
160
- }
164
+ };
@@ -1,5 +1,5 @@
1
1
  import { listenUpdated, unlistenUpdated, reaction, UpdateEventKind } from "white-web-sdk";
2
- import type { AkkoObjectUpdatedProperty , AkkoObjectUpdatedListener } from "white-web-sdk";
2
+ import type { AkkoObjectUpdatedProperty, AkkoObjectUpdatedListener } from "white-web-sdk";
3
3
  import { isObject } from "lodash";
4
4
 
5
5
  // 兼容 13 和 14 版本 SDK
@@ -12,7 +12,7 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
12
12
  if (kinds.includes(event)) {
13
13
  func();
14
14
  }
15
- }
15
+ };
16
16
  listenUpdated(object, listener);
17
17
  func();
18
18
  return () => unlistenUpdated(object, listener);
@@ -21,43 +21,44 @@ export const onObjectByEvent = (event: UpdateEventKind) => {
21
21
  () => object,
22
22
  () => {
23
23
  func();
24
- }, {
24
+ },
25
+ {
25
26
  fireImmediately: true,
26
27
  }
27
- )
28
+ );
28
29
  }
29
- }
30
- }
30
+ };
31
+ };
31
32
 
32
33
  export const safeListenPropsUpdated = <T>(
33
34
  getProps: () => T,
34
35
  callback: AkkoObjectUpdatedListener<T>,
35
36
  onDestroyed?: (props: unknown) => void
36
- ) => {
37
+ ) => {
37
38
  let disposeListenUpdated: (() => void) | null = null;
38
39
  const disposeReaction = reaction(
39
- getProps,
40
- () => {
41
- if (disposeListenUpdated) {
42
- disposeListenUpdated();
43
- disposeListenUpdated = null;
44
- }
45
- const props = getProps();
46
- if (isObject(props)) {
47
- disposeListenUpdated = () => unlistenUpdated(props, callback);
48
- listenUpdated(props, callback);
49
- } else {
50
- onDestroyed?.(props);
51
- }
52
- },
53
- { fireImmediately: true }
40
+ getProps,
41
+ () => {
42
+ if (disposeListenUpdated) {
43
+ disposeListenUpdated();
44
+ disposeListenUpdated = null;
45
+ }
46
+ const props = getProps();
47
+ if (isObject(props)) {
48
+ disposeListenUpdated = () => unlistenUpdated(props, callback);
49
+ listenUpdated(props, callback);
50
+ } else {
51
+ onDestroyed?.(props);
52
+ }
53
+ },
54
+ { fireImmediately: true }
54
55
  );
55
56
 
56
57
  return () => {
57
- disposeListenUpdated?.();
58
- disposeReaction();
58
+ disposeListenUpdated?.();
59
+ disposeReaction();
59
60
  };
60
- }
61
+ };
61
62
 
62
63
  export const onObjectRemoved = onObjectByEvent(UpdateEventKind.Removed);
63
64
  export const onObjectInserted = onObjectByEvent(UpdateEventKind.Inserted);
@@ -1,4 +1,4 @@
1
- import { emitter } from "../InternalEmitter";
1
+ import { internalEmitter } 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";
@@ -66,7 +66,7 @@ const delegateRemoveScenes = (room: Room, manager: WindowManager) => {
66
66
  manager.appManager?.updateRootDirRemoving(true);
67
67
  }
68
68
  const result = originRemoveScenes.call(room, scenePath);
69
- emitter.emit("removeScenes", { scenePath, index });
69
+ internalEmitter.emit("removeScenes", { scenePath, index });
70
70
  return result;
71
71
  };
72
72
  };
@@ -76,9 +76,9 @@ const delegateSeekToProgressTime = (player: Player) => {
76
76
  // eslint-disable-next-line no-inner-declarations
77
77
  async function newSeek(time: number): Promise<PlayerSeekingResult> {
78
78
  // seek 时需要先关闭所有的 app 防止内部使用的 mobx 出现错误
79
- await emitter.emit("seekStart");
79
+ await internalEmitter.emit("seekStart");
80
80
  const seekResult = await originSeek.call(player, time);
81
- emitter.emit("seek", time);
81
+ internalEmitter.emit("seek", time);
82
82
  return seekResult;
83
83
  }
84
84
  player.seekToProgressTime = newSeek;
@@ -1,4 +1,3 @@
1
-
2
1
  export class AppCreateError extends Error {
3
2
  override message = "[WindowManager]: app duplicate exists and cannot be created again";
4
3
  }