@netless/window-manager 0.4.24 → 0.4.27-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.
Files changed (46) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/__mocks__/white-web-sdk.ts +41 -0
  3. package/dist/App/AppContext.d.ts +2 -1
  4. package/dist/App/AppProxy.d.ts +7 -3
  5. package/dist/AppListener.d.ts +1 -0
  6. package/dist/AppManager.d.ts +2 -0
  7. package/dist/ContainerResizeObserver.d.ts +2 -1
  8. package/dist/InternalEmitter.d.ts +8 -2
  9. package/dist/Page/PageController.d.ts +5 -0
  10. package/dist/Page/index.d.ts +2 -0
  11. package/dist/Utils/Common.d.ts +2 -1
  12. package/dist/Utils/error.d.ts +3 -0
  13. package/dist/View/MainView.d.ts +4 -1
  14. package/dist/constants.d.ts +1 -0
  15. package/dist/index.cjs.js +12 -12
  16. package/dist/index.cjs.js.map +1 -1
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.es.js +263 -61
  19. package/dist/index.es.js.map +1 -1
  20. package/dist/index.umd.js +12 -12
  21. package/dist/index.umd.js.map +1 -1
  22. package/dist/typings.d.ts +1 -0
  23. package/docs/advanced.md +29 -4
  24. package/docs/api.md +17 -0
  25. package/docs/app-context.md +149 -100
  26. package/package.json +5 -9
  27. package/pnpm-lock.yaml +793 -2690
  28. package/src/App/AppContext.ts +20 -11
  29. package/src/App/AppProxy.ts +61 -5
  30. package/src/App/Storage/index.ts +14 -8
  31. package/src/AppListener.ts +22 -0
  32. package/src/AppManager.ts +57 -24
  33. package/src/ContainerResizeObserver.ts +12 -1
  34. package/src/InternalEmitter.ts +7 -2
  35. package/src/Page/PageController.ts +6 -0
  36. package/src/Page/index.ts +18 -0
  37. package/src/PageState.ts +2 -1
  38. package/src/ReconnectRefresher.ts +4 -1
  39. package/src/Utils/Common.ts +14 -2
  40. package/src/Utils/RoomHacker.ts +2 -2
  41. package/src/Utils/error.ts +4 -0
  42. package/src/View/MainView.ts +37 -8
  43. package/src/constants.ts +1 -0
  44. package/src/index.ts +26 -1
  45. package/src/typings.ts +1 -0
  46. package/vite.config.js +9 -1
package/dist/index.d.ts CHANGED
@@ -144,6 +144,7 @@ export declare class WindowManager extends InvisiblePlugin<WindowMangerAttribute
144
144
  nextPage(): Promise<boolean>;
145
145
  prevPage(): Promise<boolean>;
146
146
  addPage(params?: AddPageParams): Promise<void>;
147
+ removePage(index: number): Promise<boolean>;
147
148
  /**
148
149
  * 返回 mainView 的 ScenePath
149
150
  */
@@ -232,6 +233,7 @@ export declare class WindowManager extends InvisiblePlugin<WindowMangerAttribute
232
233
  refresh(): void;
233
234
  /** @inner */
234
235
  _refresh(): void;
236
+ setContainerSizeRatio(ratio: number): void;
235
237
  private isDynamicPPT;
236
238
  private ensureAttributes;
237
239
  }
package/dist/index.es.js CHANGED
@@ -19,7 +19,7 @@ var __spreadValues = (a2, b2) => {
19
19
  var __spreadProps = (a2, b2) => __defProps(a2, __getOwnPropDescs(b2));
20
20
  import pRetry from "p-retry";
21
21
  import Emittery from "emittery";
22
- import { debounce, isEqual, omit, isObject, has, get, size as size$1, mapValues, noop as noop$1, pick, isEmpty, isInteger, orderBy, throttle, isFunction, isNull } from "lodash";
22
+ import { debounce, isEqual, omit, isObject, has, get, size as size$1, mapValues, noop as noop$1, pick, isEmpty, isInteger, orderBy, isFunction, throttle, isNumber, isNull } from "lodash";
23
23
  import { ScenePathType, UpdateEventKind, listenUpdated, unlistenUpdated, reaction, autorun, toJS, listenDisposed, unlistenDisposed, AnimationMode, isPlayer, isRoom, WhiteVersion, ApplianceNames, RoomPhase, InvisiblePlugin, ViewMode } from "white-web-sdk";
24
24
  import { v4 } from "uuid";
25
25
  import { genUID, SideEffectManager } from "side-effect-manager";
@@ -36,6 +36,7 @@ var Events = /* @__PURE__ */ ((Events2) => {
36
36
  Events2["WindowCreated"] = "WindowCreated";
37
37
  Events2["SetMainViewScenePath"] = "SetMainViewScenePath";
38
38
  Events2["SetMainViewSceneIndex"] = "SetMainViewSceneIndex";
39
+ Events2["SetAppFocusIndex"] = "SetAppFocusIndex";
39
40
  Events2["SwitchViewsToFreedom"] = "SwitchViewsToFreedom";
40
41
  Events2["MoveCamera"] = "MoveCamera";
41
42
  Events2["MoveCameraToContain"] = "MoveCameraToContain";
@@ -369,11 +370,11 @@ const getScenePath = (room, dir, index) => {
369
370
  }
370
371
  }
371
372
  };
372
- const removeScenes = (room, scenePath) => {
373
+ const removeScenes = (room, scenePath, index) => {
373
374
  if (room) {
374
375
  const type = room.scenePathType(scenePath);
375
376
  if (type !== ScenePathType.None) {
376
- room.removeScenes(scenePath);
377
+ room.removeScenes(scenePath, index);
377
378
  }
378
379
  }
379
380
  };
@@ -427,6 +428,15 @@ const getVersionNumber = (version) => {
427
428
  return parseInt(versionString);
428
429
  };
429
430
  const wait = (time2) => new Promise((resolve) => setTimeout(resolve, time2));
431
+ const isRootDirPage = (scenePath) => {
432
+ const delimiterCount = scenePath.split("").reduce((prev, cur) => {
433
+ if (cur === ROOT_DIR) {
434
+ prev += 1;
435
+ }
436
+ return prev;
437
+ }, 0);
438
+ return delimiterCount === 1;
439
+ };
430
440
  class AppListeners {
431
441
  constructor(manager) {
432
442
  this.manager = manager;
@@ -475,6 +485,10 @@ class AppListeners {
475
485
  this.initMainViewCameraHandler();
476
486
  break;
477
487
  }
488
+ case Events.SetAppFocusIndex: {
489
+ this.setAppFocusViewIndexHandler(data.payload);
490
+ break;
491
+ }
478
492
  }
479
493
  }
480
494
  };
@@ -516,6 +530,16 @@ class AppListeners {
516
530
  this.initMainViewCameraHandler = () => {
517
531
  this.manager.mainViewProxy.addCameraReaction();
518
532
  };
533
+ this.setAppFocusViewIndexHandler = (payload) => {
534
+ if (payload.type === "main") {
535
+ this.manager.setSceneIndexWithoutSync(payload.index);
536
+ } else if (payload.type === "app" && payload.appID) {
537
+ const app = this.manager.appProxies.get(payload.appID);
538
+ if (app) {
539
+ app.setSceneIndexWithoutSync(payload.index);
540
+ }
541
+ }
542
+ };
519
543
  }
520
544
  get boxManager() {
521
545
  return this.manager.boxManager;
@@ -533,6 +557,11 @@ class AppCreateError extends Error {
533
557
  this.message = "[WindowManager]: app duplicate exists and cannot be created again";
534
558
  }
535
559
  }
560
+ class AppNotRegisterError extends Error {
561
+ constructor(kind2) {
562
+ super(`[WindowManager]: app ${kind2} need register or provide src`);
563
+ }
564
+ }
536
565
  class AppManagerNotInitError extends Error {
537
566
  constructor() {
538
567
  super(...arguments);
@@ -568,6 +597,12 @@ class BoxManagerNotFoundError extends Error {
568
597
  this.message = "[WindowManager]: boxManager not found";
569
598
  }
570
599
  }
600
+ class BindContainerRoomPhaseInvalidError extends Error {
601
+ constructor() {
602
+ super(...arguments);
603
+ this.message = "[WindowManager]: room phase only Connected can be bindContainer";
604
+ }
605
+ }
571
606
  const onObjectByEvent = (event) => {
572
607
  return (object, func) => {
573
608
  if (object === void 0)
@@ -652,15 +687,21 @@ class Storage {
652
687
  this.id = id2 || null;
653
688
  this._state = {};
654
689
  const rawState = this._getRawState(this._state);
655
- if (this.id !== null && this._context.getIsWritable()) {
656
- if (rawState === this._state || !isObject(rawState)) {
657
- if (!get(this._context.getAttributes(), [STORAGE_NS])) {
658
- this._context.updateAttributes([STORAGE_NS], {});
690
+ if (this._context.getIsWritable()) {
691
+ if (this.id === null) {
692
+ if (context.isAddApp && defaultState) {
693
+ this.setState(defaultState);
694
+ }
695
+ } else {
696
+ if (rawState === this._state || !isObject(rawState)) {
697
+ if (!get(this._context.getAttributes(), [STORAGE_NS])) {
698
+ this._context.updateAttributes([STORAGE_NS], {});
699
+ }
700
+ this._context.updateAttributes([STORAGE_NS, this.id], this._state);
701
+ if (defaultState) {
702
+ this.setState(defaultState);
703
+ }
659
704
  }
660
- this._context.updateAttributes([STORAGE_NS, this.id], this._state);
661
- }
662
- if (defaultState) {
663
- this.setState(defaultState);
664
705
  }
665
706
  }
666
707
  plainObjectKeys(rawState).forEach((key) => {
@@ -885,6 +926,16 @@ class AppContext {
885
926
  this.getView = () => {
886
927
  return this.appProxy.view;
887
928
  };
929
+ this.mountView = (dom) => {
930
+ const view = this.getView();
931
+ if (view) {
932
+ view.divElement = dom;
933
+ setTimeout(() => {
934
+ var _a;
935
+ (_a = this.getRoom()) == null ? void 0 : _a.refreshViewSize();
936
+ }, 1e3);
937
+ }
938
+ };
888
939
  this.getInitScenePath = () => {
889
940
  return this.manager.getAppInitPath(this.appId);
890
941
  };
@@ -917,16 +968,6 @@ class AppContext {
917
968
  this.appProxy.setFullPath(scenePath);
918
969
  (_a = this.getRoom()) == null ? void 0 : _a.setScenePath(scenePath);
919
970
  };
920
- this.mountView = (dom) => {
921
- const view = this.getView();
922
- if (view) {
923
- view.divElement = dom;
924
- setTimeout(() => {
925
- var _a;
926
- (_a = this.getRoom()) == null ? void 0 : _a.refreshViewSize();
927
- }, 1e3);
928
- }
929
- };
930
971
  this.getAppOptions = () => {
931
972
  return typeof this.appOptions === "function" ? this.appOptions() : this.appOptions;
932
973
  };
@@ -979,6 +1020,14 @@ class AppContext {
979
1020
  putScenes(this.manager.room, scenePath, [scene || {}]);
980
1021
  }
981
1022
  };
1023
+ this.removePage = async (index) => {
1024
+ if (index < 0 || index >= this.pageState.length) {
1025
+ console.warn(`[WindowManager]: page index ${index} out of range`);
1026
+ return false;
1027
+ }
1028
+ this.appProxy.removeSceneByIndex(index);
1029
+ return true;
1030
+ };
982
1031
  this.emitter = appProxy.appEmitter;
983
1032
  this.isAddApp = appProxy.isAddApp;
984
1033
  }
@@ -1203,6 +1252,21 @@ const log = (...args) => {
1203
1252
  console.log(`[WindowManager]:`, ...args);
1204
1253
  }
1205
1254
  };
1255
+ const calculateNextIndex = (index, pageState) => {
1256
+ let nextIndex = 0;
1257
+ if (index === 0) {
1258
+ return index + 1;
1259
+ }
1260
+ if (pageState.index !== 0 && index !== 0) {
1261
+ const maxIndex = pageState.length - 1;
1262
+ if (index === maxIndex) {
1263
+ nextIndex = maxIndex - 1;
1264
+ } else if (index > 0 && index < maxIndex) {
1265
+ nextIndex = index + 1;
1266
+ }
1267
+ }
1268
+ return nextIndex;
1269
+ };
1206
1270
  class AppProxy {
1207
1271
  constructor(params, manager, appId, isAddApp) {
1208
1272
  var _a;
@@ -1264,7 +1328,10 @@ class AppProxy {
1264
1328
  var _a3;
1265
1329
  const fullPath = (_a3 = this.appAttributes) == null ? void 0 : _a3.fullPath;
1266
1330
  this.setFocusScenePathHandler(fullPath);
1267
- this.notifyPageStateChange();
1331
+ if (this._prevFullPath !== fullPath) {
1332
+ this.notifyPageStateChange();
1333
+ this._prevFullPath = fullPath;
1334
+ }
1268
1335
  });
1269
1336
  });
1270
1337
  };
@@ -1274,9 +1341,9 @@ class AppProxy {
1274
1341
  setViewFocusScenePath(this.view, fullPath);
1275
1342
  }
1276
1343
  }, 50);
1277
- this.notifyPageStateChange = () => {
1344
+ this.notifyPageStateChange = debounce(() => {
1278
1345
  this.appEmitter.emit("pageStateChange", this.pageState);
1279
- };
1346
+ }, 50);
1280
1347
  this.kind = params.kind;
1281
1348
  this.id = appId;
1282
1349
  this.stateKey = `${this.id}_state`;
@@ -1444,6 +1511,23 @@ class AppProxy {
1444
1511
  await appProxy.baseInsertApp(true);
1445
1512
  (_a = this.boxManager) == null ? void 0 : _a.updateBoxState(currentAppState);
1446
1513
  }
1514
+ async onRemoveScene(scenePath) {
1515
+ if (this.scenePath && scenePath.startsWith(this.scenePath + "/")) {
1516
+ let nextIndex = this.pageState.index;
1517
+ let fullPath = this._pageState.getFullPath(nextIndex);
1518
+ if (!fullPath) {
1519
+ nextIndex = 0;
1520
+ fullPath = this._pageState.getFullPath(nextIndex);
1521
+ }
1522
+ if (fullPath) {
1523
+ this.setFullPath(fullPath);
1524
+ }
1525
+ this.setViewFocusScenePath();
1526
+ if (this.view) {
1527
+ this.view.focusSceneIndex = nextIndex;
1528
+ }
1529
+ }
1530
+ }
1447
1531
  emitAppSceneStateChange(sceneState) {
1448
1532
  this.appEmitter.emit("sceneStateChange", sceneState);
1449
1533
  }
@@ -1517,6 +1601,32 @@ class AppProxy {
1517
1601
  get pageState() {
1518
1602
  return this._pageState.toObject();
1519
1603
  }
1604
+ async removeSceneByIndex(index) {
1605
+ const scenePath = this._pageState.getFullPath(index);
1606
+ if (scenePath) {
1607
+ if (this.pageState.length <= 1) {
1608
+ return false;
1609
+ }
1610
+ const nextIndex = calculateNextIndex(index, this.pageState);
1611
+ this.setSceneIndexWithoutSync(nextIndex);
1612
+ this.manager.dispatchInternalEvent(Events.SetAppFocusIndex, {
1613
+ type: "app",
1614
+ appID: this.id,
1615
+ index: nextIndex
1616
+ });
1617
+ setTimeout(() => {
1618
+ removeScenes(this.manager.room, scenePath, index);
1619
+ }, 100);
1620
+ return true;
1621
+ } else {
1622
+ return false;
1623
+ }
1624
+ }
1625
+ setSceneIndexWithoutSync(index) {
1626
+ if (this.view) {
1627
+ this.view.focusSceneIndex = index;
1628
+ }
1629
+ }
1520
1630
  setSceneIndex(index) {
1521
1631
  if (this.view) {
1522
1632
  this.view.focusSceneIndex = index;
@@ -1555,6 +1665,7 @@ class AppProxy {
1555
1665
  (_b = this.manager.refresher) == null ? void 0 : _b.remove(this.id);
1556
1666
  (_c = this.manager.refresher) == null ? void 0 : _c.remove(this.stateKey);
1557
1667
  (_d = this.manager.refresher) == null ? void 0 : _d.remove(`${this.id}-fullPath`);
1668
+ this._prevFullPath = void 0;
1558
1669
  }
1559
1670
  close() {
1560
1671
  return this.destroy(true, true, false);
@@ -1644,6 +1755,13 @@ class MainViewProxy {
1644
1755
  this.moveCamera(this.mainViewCamera);
1645
1756
  }
1646
1757
  }, 30);
1758
+ this.onUpdateContainerSizeRatio = () => {
1759
+ const size2 = this.store.getMainViewSize();
1760
+ this.sizeChangeHandler(size2);
1761
+ if (size2.id === this.manager.uid) {
1762
+ this.setCameraAndSize();
1763
+ }
1764
+ };
1647
1765
  this.onCameraUpdatedByDevice = (camera) => {
1648
1766
  this.store.setMainViewCamera(__spreadProps(__spreadValues({}, camera), { id: this.manager.uid }));
1649
1767
  if (!isEqual(this.mainViewSize, __spreadProps(__spreadValues({}, this.mainView.size), { id: this.manager.uid }))) {
@@ -1671,8 +1789,15 @@ class MainViewProxy {
1671
1789
  this.sizeChangeHandler(this.mainViewSize);
1672
1790
  };
1673
1791
  this.sideEffectManager.add(() => {
1674
- emitter.on("playgroundSizeChange", playgroundSizeChangeListener);
1675
- return () => emitter.off("playgroundSizeChange", playgroundSizeChangeListener);
1792
+ return emitter.on("playgroundSizeChange", playgroundSizeChangeListener);
1793
+ });
1794
+ this.sideEffectManager.add(() => {
1795
+ return emitter.on("containerSizeRatioUpdate", this.onUpdateContainerSizeRatio);
1796
+ });
1797
+ this.sideEffectManager.add(() => {
1798
+ return emitter.on("startReconnect", () => {
1799
+ this.mainView.release();
1800
+ });
1676
1801
  });
1677
1802
  }
1678
1803
  ensureCameraAndSize() {
@@ -1687,6 +1812,9 @@ class MainViewProxy {
1687
1812
  get mainViewSize() {
1688
1813
  return this.store.getMainViewSize();
1689
1814
  }
1815
+ get didRelease() {
1816
+ return get(this.view, ["didRelease"]);
1817
+ }
1690
1818
  moveCameraSizeByAttributes() {
1691
1819
  this.moveCameraToContian(this.mainViewSize);
1692
1820
  this.moveCamera(this.mainViewCamera);
@@ -1719,16 +1847,25 @@ class MainViewProxy {
1719
1847
  return mainView;
1720
1848
  }
1721
1849
  onReconnect() {
1722
- const mainViewScenePath = this.store.getMainViewScenePath();
1723
- if (mainViewScenePath) {
1724
- setViewFocusScenePath(this.view, mainViewScenePath);
1850
+ if (this.didRelease) {
1851
+ this.rebind();
1852
+ } else {
1853
+ const mainViewScenePath = this.store.getMainViewScenePath();
1854
+ this.setFocusScenePath(mainViewScenePath);
1855
+ }
1856
+ }
1857
+ setFocusScenePath(path) {
1858
+ if (path) {
1859
+ return setViewFocusScenePath(this.view, path);
1725
1860
  }
1726
1861
  }
1727
1862
  rebind() {
1728
1863
  const divElement = this.mainView.divElement;
1729
1864
  const disableCameraTransform = this.mainView.disableCameraTransform;
1730
1865
  this.stop();
1731
- this.mainView.release();
1866
+ if (!this.didRelease) {
1867
+ this.mainView.release();
1868
+ }
1732
1869
  this.removeMainViewListener();
1733
1870
  this.mainView = this.createMainView();
1734
1871
  this.mainView.disableCameraTransform = disableCameraTransform;
@@ -1880,19 +2017,29 @@ class AppManager {
1880
2017
  this.sideEffectManager = new SideEffectManager();
1881
2018
  this.sceneState = null;
1882
2019
  this.rootDirRemoving = false;
1883
- this.onRemoveScenes = async (scenePath) => {
1884
- var _a;
2020
+ this.onRemoveScenes = async (params) => {
2021
+ var _a, _b;
2022
+ const { scenePath } = params;
1885
2023
  if (scenePath === ROOT_DIR) {
1886
2024
  await this.onRootDirRemoved();
1887
2025
  this.dispatchInternalEvent(Events.RootDirRemoved);
1888
2026
  return;
1889
2027
  }
1890
- const mainViewScenePath = this.store.getMainViewScenePath();
1891
- if (this.room && mainViewScenePath) {
1892
- if (mainViewScenePath === scenePath) {
1893
- const nextPath = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[this.store.getMainViewSceneIndex()];
1894
- this.setMainViewScenePath(`/${nextPath}` || INIT_DIR);
2028
+ if (isRootDirPage(scenePath)) {
2029
+ let nextIndex = this.mainView.focusSceneIndex || 0;
2030
+ let sceneName = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[nextIndex];
2031
+ if (!sceneName) {
2032
+ nextIndex = 0;
2033
+ sceneName = (_b = this.callbacksNode) == null ? void 0 : _b.scenes[nextIndex];
2034
+ }
2035
+ if (sceneName) {
2036
+ this.setMainViewScenePath(`${ROOT_DIR}${sceneName}`);
1895
2037
  }
2038
+ await this.setMainViewSceneIndex(nextIndex);
2039
+ } else {
2040
+ this.appProxies.forEach((app) => {
2041
+ app.onRemoveScene(scenePath);
2042
+ });
1896
2043
  }
1897
2044
  };
1898
2045
  this.onReadonlyChanged = () => {
@@ -1927,6 +2074,26 @@ class AppManager {
1927
2074
  }
1928
2075
  }
1929
2076
  };
2077
+ this.removeSceneByIndex = async (index) => {
2078
+ const nextIndex = calculateNextIndex(index, this.windowManger.pageState);
2079
+ this.setSceneIndexWithoutSync(nextIndex);
2080
+ this.dispatchInternalEvent(Events.SetAppFocusIndex, { type: "main", index: nextIndex });
2081
+ setTimeout(() => {
2082
+ var _a;
2083
+ const scene = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[index];
2084
+ if (scene) {
2085
+ removeScenes(this.room, `${ROOT_DIR}${scene}`, index);
2086
+ }
2087
+ }, 100);
2088
+ return true;
2089
+ };
2090
+ this.setSceneIndexWithoutSync = (index) => {
2091
+ var _a;
2092
+ const sceneName = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[index];
2093
+ if (sceneName) {
2094
+ this.mainViewProxy.setFocusScenePath(`${ROOT_DIR}${sceneName}`);
2095
+ }
2096
+ };
1930
2097
  this.onSceneChange = (node) => {
1931
2098
  this.mainViewScenesLength = node.scenes.length;
1932
2099
  this.updateSceneState(node);
@@ -1938,7 +2105,10 @@ class AppManager {
1938
2105
  };
1939
2106
  this.updateSceneState = (node) => {
1940
2107
  const currentIndex = this.store.getMainViewSceneIndex() || 0;
1941
- const sceneName = node.scenes[currentIndex];
2108
+ let sceneName = node.scenes[currentIndex];
2109
+ if (!sceneName) {
2110
+ sceneName = node.scenes[this.mainView.focusSceneIndex || 0];
2111
+ }
1942
2112
  this.sceneState = {
1943
2113
  scenePath: `${ROOT_DIR}${sceneName}`,
1944
2114
  contextPath: node.path,
@@ -2322,10 +2492,11 @@ class AppManager {
2322
2492
  emitter.emit("mainViewMounted");
2323
2493
  }
2324
2494
  setMainViewFocusPath(scenePath) {
2495
+ var _a;
2325
2496
  const focusScenePath = scenePath || this.store.getMainViewScenePath();
2326
2497
  if (focusScenePath) {
2327
- const view = setViewFocusScenePath(this.mainView, focusScenePath);
2328
- return (view == null ? void 0 : view.focusScenePath) === focusScenePath;
2498
+ setViewFocusScenePath(this.mainView, focusScenePath);
2499
+ return ((_a = this.mainView) == null ? void 0 : _a.focusScenePath) === focusScenePath;
2329
2500
  }
2330
2501
  }
2331
2502
  resetScenePath(scenePath) {
@@ -2425,23 +2596,21 @@ class AppManager {
2425
2596
  }
2426
2597
  }
2427
2598
  async setMainViewSceneIndex(index) {
2599
+ var _a;
2428
2600
  if (this.room) {
2429
2601
  if (this.store.getMainViewSceneIndex() === index)
2430
2602
  return;
2431
- const mainViewScenePath = this.store.getMainViewScenePath();
2432
- if (mainViewScenePath) {
2433
- const sceneDir = parseSceneDir(mainViewScenePath);
2434
- const scenePath = makeValidScenePath(this.displayer, sceneDir, index);
2435
- if (scenePath) {
2436
- const success = this.setMainViewFocusPath(scenePath);
2437
- if (success) {
2438
- this.store.setMainViewScenePath(scenePath);
2439
- this.safeSetAttributes({ _mainSceneIndex: index });
2440
- this.dispatchSetMainViewScenePath(scenePath);
2441
- }
2442
- } else {
2443
- throw new Error(`[WindowManager]: ${sceneDir}: ${index} not valid index`);
2603
+ const sceneName = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[index];
2604
+ const scenePath = `${ROOT_DIR}${sceneName}`;
2605
+ if (sceneName) {
2606
+ const success = this.setMainViewFocusPath(scenePath);
2607
+ if (success) {
2608
+ this.store.setMainViewScenePath(scenePath);
2609
+ this.safeSetAttributes({ _mainSceneIndex: index });
2610
+ this.dispatchSetMainViewScenePath(scenePath);
2444
2611
  }
2612
+ } else {
2613
+ throw new Error(`[WindowManager]: ${index} not valid index`);
2445
2614
  }
2446
2615
  }
2447
2616
  }
@@ -2555,6 +2724,9 @@ class ContainerResizeObserver {
2555
2724
  this.emitter.emit("playgroundSizeChange", containerRect);
2556
2725
  }
2557
2726
  });
2727
+ this.disposer = this.emitter.on("containerSizeRatioUpdate", () => {
2728
+ this.updateSizer(container.getBoundingClientRect(), sizer, wrapper);
2729
+ });
2558
2730
  this.containerResizeObserver.observe(container);
2559
2731
  }
2560
2732
  updateSizer({ width, height }, sizer, wrapper) {
@@ -2573,6 +2745,10 @@ class ContainerResizeObserver {
2573
2745
  disconnect() {
2574
2746
  var _a;
2575
2747
  (_a = this.containerResizeObserver) == null ? void 0 : _a.disconnect();
2748
+ if (isFunction(this.disposer)) {
2749
+ this.disposer();
2750
+ this.disposer = void 0;
2751
+ }
2576
2752
  }
2577
2753
  }
2578
2754
  var react = { exports: {} };
@@ -5545,8 +5721,9 @@ class PageStateImpl {
5545
5721
  return ((_a = this.manager) == null ? void 0 : _a.mainViewScenesLength) || 0;
5546
5722
  }
5547
5723
  toObject() {
5724
+ const index = this.index >= this.length ? this.length - 1 : this.index;
5548
5725
  return {
5549
- index: this.index,
5726
+ index,
5550
5727
  length: this.length
5551
5728
  };
5552
5729
  }
@@ -5557,6 +5734,9 @@ class ReconnectRefresher {
5557
5734
  this.reactors = /* @__PURE__ */ new Map();
5558
5735
  this.disposers = /* @__PURE__ */ new Map();
5559
5736
  this.onPhaseChanged = (phase) => {
5737
+ if (phase === RoomPhase.Reconnecting) {
5738
+ this.ctx.emitter.emit("startReconnect");
5739
+ }
5560
5740
  if (phase === RoomPhase.Connected && this.phase === RoomPhase.Reconnecting) {
5561
5741
  this.onReconnected();
5562
5742
  }
@@ -5573,7 +5753,7 @@ class ReconnectRefresher {
5573
5753
  this.disposers.set(id2, func());
5574
5754
  }
5575
5755
  });
5576
- this.ctx.emitter.emit("onReconnected", void 0);
5756
+ this.ctx.emitter.emit("onReconnected");
5577
5757
  };
5578
5758
  }
5579
5759
  setRoom(room) {
@@ -5679,13 +5859,13 @@ const replaceRoomFunction = (room, manager) => {
5679
5859
  };
5680
5860
  const delegateRemoveScenes = (room, manager) => {
5681
5861
  const originRemoveScenes = room.removeScenes;
5682
- room.removeScenes = (scenePath) => {
5862
+ room.removeScenes = (scenePath, index) => {
5683
5863
  var _a;
5684
5864
  if (scenePath === ROOT_DIR) {
5685
5865
  (_a = manager.appManager) == null ? void 0 : _a.updateRootDirRemoving(true);
5686
5866
  }
5687
5867
  const result = originRemoveScenes.call(room, scenePath);
5688
- emitter.emit("removeScenes", scenePath);
5868
+ emitter.emit("removeScenes", { scenePath, index });
5689
5869
  return result;
5690
5870
  };
5691
5871
  };
@@ -14868,14 +15048,14 @@ const reconnectRefresher = new ReconnectRefresher({ emitter });
14868
15048
  const _WindowManager = class extends InvisiblePlugin {
14869
15049
  constructor(context) {
14870
15050
  super(context);
14871
- this.version = "0.4.24";
14872
- this.dependencies = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "0.2.26", "emittery": "^0.9.2", "lodash": "^4.17.21", "p-retry": "^4.6.1", "side-effect-manager": "^0.1.5", "uuid": "^7.0.3", "video.js": ">=7" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.2.9", "@netless/app-media-player": "0.1.0-beta.5", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.22", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/jest": "^27.4.1", "@types/lodash-es": "^4.17.4", "@types/uuid": "^8.3.1", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jest": "^27.5.1", "jest-canvas-mock": "^2.3.1", "jest-fetch-mock": "^3.0.3", "jest-transform-stub": "^2.0.0", "less": "^4.1.1", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "svelte-jester": "^2.3.2", "ts-jest": "^27.1.4", "typescript": "^4.5.5", "vite": "^2.5.3", "white-web-sdk": "2.16.10" } };
15051
+ this.version = "0.4.27-canary.0";
15052
+ this.dependencies = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "0.2.26", "emittery": "^0.9.2", "lodash": "^4.17.21", "p-retry": "^4.6.1", "side-effect-manager": "^0.1.5", "uuid": "^7.0.3", "video.js": ">=7" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.2.9", "@netless/app-media-player": "0.1.0-beta.5", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.22", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.4", "@types/uuid": "^8.3.1", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jsdom": "^19.0.0", "less": "^4.1.1", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "typescript": "^4.5.5", "vite": "^2.5.3", "vitest": "^0.12.4", "white-web-sdk": "2.16.10" } };
14873
15053
  this.emitter = callbacks$1;
14874
15054
  this.viewMode = ViewMode.Broadcaster;
14875
15055
  this.isReplay = isPlayer(this.displayer);
14876
15056
  this.containerSizeRatio = _WindowManager.containerSizeRatio;
14877
15057
  _WindowManager.displayer = context.displayer;
14878
- window.NETLESS_DEPS = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "0.2.26", "emittery": "^0.9.2", "lodash": "^4.17.21", "p-retry": "^4.6.1", "side-effect-manager": "^0.1.5", "uuid": "^7.0.3", "video.js": ">=7" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.2.9", "@netless/app-media-player": "0.1.0-beta.5", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.22", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/jest": "^27.4.1", "@types/lodash-es": "^4.17.4", "@types/uuid": "^8.3.1", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jest": "^27.5.1", "jest-canvas-mock": "^2.3.1", "jest-fetch-mock": "^3.0.3", "jest-transform-stub": "^2.0.0", "less": "^4.1.1", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "svelte-jester": "^2.3.2", "ts-jest": "^27.1.4", "typescript": "^4.5.5", "vite": "^2.5.3", "white-web-sdk": "2.16.10" } };
15058
+ window.NETLESS_DEPS = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "0.2.26", "emittery": "^0.9.2", "lodash": "^4.17.21", "p-retry": "^4.6.1", "side-effect-manager": "^0.1.5", "uuid": "^7.0.3", "video.js": ">=7" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.2.9", "@netless/app-media-player": "0.1.0-beta.5", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.22", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.4", "@types/uuid": "^8.3.1", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jsdom": "^19.0.0", "less": "^4.1.1", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "typescript": "^4.5.5", "vite": "^2.5.3", "vitest": "^0.12.4", "white-web-sdk": "2.16.10" } };
14879
15059
  }
14880
15060
  static async mount(params) {
14881
15061
  const room = params.room;
@@ -14985,6 +15165,9 @@ const _WindowManager = class extends InvisiblePlugin {
14985
15165
  }
14986
15166
  bindContainer(container) {
14987
15167
  var _a, _b, _c, _d, _e2, _f;
15168
+ if (this.room.phase !== RoomPhase.Connected) {
15169
+ throw new BindContainerRoomPhaseInvalidError();
15170
+ }
14988
15171
  if (_WindowManager.isCreated && _WindowManager.container) {
14989
15172
  if (_WindowManager.container.firstChild) {
14990
15173
  container.appendChild(_WindowManager.container.firstChild);
@@ -15165,6 +15348,17 @@ const _WindowManager = class extends InvisiblePlugin {
15165
15348
  }
15166
15349
  }
15167
15350
  }
15351
+ async removePage(index) {
15352
+ if (this.appManager) {
15353
+ if (index < 0 || index >= this.pageState.length) {
15354
+ console.warn(`[WindowManager]: index ${index} out of range`);
15355
+ return false;
15356
+ }
15357
+ return this.appManager.removeSceneByIndex(index);
15358
+ } else {
15359
+ return false;
15360
+ }
15361
+ }
15168
15362
  getMainViewScenePath() {
15169
15363
  var _a;
15170
15364
  return (_a = this.appManager) == null ? void 0 : _a.store.getMainViewScenePath();
@@ -15474,6 +15668,14 @@ const _WindowManager = class extends InvisiblePlugin {
15474
15668
  }
15475
15669
  (_c = (_b = this.appManager) == null ? void 0 : _b.refresher) == null ? void 0 : _c.refresh();
15476
15670
  }
15671
+ setContainerSizeRatio(ratio) {
15672
+ if (!isNumber(ratio)) {
15673
+ throw new Error(`[WindowManager]: updateContainerSizeRatio error, ratio must be a number. but got ${ratio}`);
15674
+ }
15675
+ _WindowManager.containerSizeRatio = ratio;
15676
+ this.containerSizeRatio = ratio;
15677
+ emitter.emit("containerSizeRatioUpdate", ratio);
15678
+ }
15477
15679
  isDynamicPPT(scenes) {
15478
15680
  var _a, _b;
15479
15681
  const sceneSrc = (_b = (_a = scenes[0]) == null ? void 0 : _a.ppt) == null ? void 0 : _b.src;
@@ -15508,5 +15710,5 @@ WindowManager.debug = false;
15508
15710
  WindowManager.containerSizeRatio = DEFAULT_CONTAINER_RATIO;
15509
15711
  WindowManager.isCreated = false;
15510
15712
  setupBuiltin();
15511
- export { BuiltinApps, WindowManager, reconnectRefresher };
15713
+ export { AppCreateError, AppManagerNotInitError, AppNotRegisterError, BindContainerRoomPhaseInvalidError, BoxManagerNotFoundError, BoxNotCreatedError, BuiltinApps, InvalidScenePath, ParamsInvalidError, WhiteWebSDKInvalidError, WindowManager, calculateNextIndex, reconnectRefresher };
15512
15714
  //# sourceMappingURL=index.es.js.map