@netless/window-manager 1.0.0-canary.53 → 1.0.0-canary.55

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 (44) hide show
  1. package/dist/index.cjs.js +375 -444
  2. package/dist/index.es.js +421 -490
  3. package/dist/index.umd.js +375 -445
  4. package/dist/src/App/AppContext.d.ts +8 -8
  5. package/dist/src/AppManager.d.ts +5 -1
  6. package/dist/src/Cursor/index.d.ts +1 -0
  7. package/dist/src/Utils/Reactive.d.ts +1 -1
  8. package/dist/src/View/CameraSynchronizer.d.ts +3 -2
  9. package/dist/src/View/ScrollMode.d.ts +32 -0
  10. package/dist/src/View/ViewSync.d.ts +3 -2
  11. package/dist/src/callback.d.ts +3 -0
  12. package/dist/src/constants.d.ts +2 -0
  13. package/dist/src/index.d.ts +21 -11
  14. package/dist/src/storage.d.ts +7 -0
  15. package/dist/src/typings.d.ts +5 -4
  16. package/dist/style.css +2 -1
  17. package/docs/api.md +10 -0
  18. package/package.json +4 -3
  19. package/pnpm-lock.yaml +28 -73
  20. package/src/App/AppContext.ts +19 -8
  21. package/src/App/WhiteboardView.ts +4 -2
  22. package/src/AppListener.ts +1 -10
  23. package/src/AppManager.ts +18 -1
  24. package/src/Cursor/index.ts +6 -2
  25. package/src/Utils/Reactive.ts +2 -1
  26. package/src/View/CameraSynchronizer.ts +33 -22
  27. package/src/View/MainView.ts +1 -0
  28. package/src/View/ScrollMode.ts +219 -0
  29. package/src/View/ViewSync.ts +24 -16
  30. package/src/callback.ts +3 -0
  31. package/src/constants.ts +3 -0
  32. package/src/index.ts +56 -63
  33. package/src/storage.ts +15 -0
  34. package/src/style.css +1 -1
  35. package/src/typings.ts +6 -3
  36. package/vite.config.js +1 -1
  37. package/dist/src/App/Storage/StorageEvent.d.ts +0 -8
  38. package/dist/src/App/Storage/index.d.ts +0 -39
  39. package/dist/src/App/Storage/typings.d.ts +0 -22
  40. package/dist/src/App/Storage/utils.d.ts +0 -5
  41. package/src/App/Storage/StorageEvent.ts +0 -21
  42. package/src/App/Storage/index.ts +0 -295
  43. package/src/App/Storage/typings.ts +0 -23
  44. package/src/App/Storage/utils.ts +0 -17
package/dist/index.cjs.js CHANGED
@@ -36,8 +36,9 @@ var Emittery = require("emittery");
36
36
  var lodash = require("lodash");
37
37
  var whiteWebSdk = require("white-web-sdk");
38
38
  var uuid = require("uuid");
39
- var sideEffectManager = require("side-effect-manager");
39
+ var syncedStore = require("@netless/synced-store");
40
40
  var valueEnhancer = require("value-enhancer");
41
+ var sideEffectManager = require("side-effect-manager");
41
42
  var resizeObserver = require("@juggle/resize-observer");
42
43
  function _interopDefaultLegacy(e) {
43
44
  return e && typeof e === "object" && "default" in e ? e : { "default": e };
@@ -102,6 +103,8 @@ const ROOT_DIR = "/";
102
103
  const INIT_DIR = "/init";
103
104
  const SETUP_APP_DELAY = 50;
104
105
  const MAX_PAGE_SIZE = 500;
106
+ const SCROLL_MODE_BASE_WIDTH = 1600;
107
+ const SCROLL_MODE_BASE_HEIGHT = SCROLL_MODE_BASE_WIDTH * 3;
105
108
  const callbacks = new Emittery__default["default"]();
106
109
  class AppCreateQueue {
107
110
  constructor() {
@@ -522,67 +525,6 @@ const isRootDirPage = (scenePath) => {
522
525
  }, 0);
523
526
  return delimiterCount === 1;
524
527
  };
525
- class CameraSynchronizer {
526
- constructor(saveCamera) {
527
- this.saveCamera = saveCamera;
528
- this.setRect = (rect, updateCamera = true) => {
529
- this.rect = rect;
530
- if (this.remoteCamera && this.remoteSize && updateCamera) {
531
- this.onRemoteUpdate(this.remoteCamera, this.remoteSize);
532
- }
533
- };
534
- this.onRemoteUpdate = lodash.throttle((camera, size) => {
535
- this.remoteCamera = camera;
536
- this.remoteSize = size;
537
- if (this.remoteSize && this.rect) {
538
- const nextScale = camera.scale * computedMinScale(size, this.rect);
539
- const config = {
540
- scale: nextScale
541
- };
542
- if (camera.centerX !== null) {
543
- config.centerX = camera.centerX;
544
- }
545
- if (camera.centerY !== null) {
546
- config.centerY = camera.centerY;
547
- }
548
- console.trace("moveCamera");
549
- this.moveCamera(config);
550
- }
551
- }, 10);
552
- }
553
- setView(view) {
554
- this.view = view;
555
- }
556
- onRemoteSizeUpdate(size) {
557
- var _a;
558
- this.remoteSize = size;
559
- const needMoveCamera = !lodash.isEqual(lodash.pick(this.rect, ["width", "height"]), lodash.pick(size, ["width", "height"]));
560
- if (this.rect && this.remoteCamera && needMoveCamera) {
561
- if (!this.view)
562
- return;
563
- const currentCamera = this.view.camera;
564
- (_a = this.view) == null ? void 0 : _a.moveCameraToContain({
565
- width: size.width,
566
- height: size.height,
567
- originX: currentCamera.centerX - size.width / 2,
568
- originY: currentCamera.centerY - size.height / 2
569
- });
570
- }
571
- }
572
- onLocalCameraUpdate(camera) {
573
- this.saveCamera(camera);
574
- this.remoteCamera = camera;
575
- }
576
- moveCamera(camera) {
577
- var _a;
578
- (_a = this.view) == null ? void 0 : _a.moveCamera(__spreadProps(__spreadValues({}, camera), { animationMode: whiteWebSdk.AnimationMode.Immediately }));
579
- }
580
- }
581
- const computedMinScale = (remoteSize, currentSize) => {
582
- const wScale = currentSize.width / remoteSize.width;
583
- const hScale = currentSize.height / remoteSize.height;
584
- return Math.min(wScale, hScale);
585
- };
586
528
  class AppListeners {
587
529
  constructor(manager) {
588
530
  this.manager = manager;
@@ -683,16 +625,7 @@ class AppListeners {
683
625
  }
684
626
  };
685
627
  this.moveCameraHandler = (payload) => {
686
- var _a;
687
- const cameraPayload = payload;
688
- if (payload.scale) {
689
- const remoteSize = this.manager.mainViewProxy.size$.value;
690
- const currentSize = (_a = this.manager.boxManager) == null ? void 0 : _a.stageRect;
691
- if (remoteSize && currentSize) {
692
- cameraPayload.scale = payload.scale * computedMinScale(remoteSize, currentSize);
693
- }
694
- }
695
- this.manager.mainView.moveCamera(cameraPayload);
628
+ this.manager.mainView.moveCamera(payload);
696
629
  };
697
630
  this.moveCameraToContainHandler = (payload) => {
698
631
  this.manager.mainView.moveCameraToContain(payload);
@@ -760,292 +693,6 @@ class BindContainerRoomPhaseInvalidError extends Error {
760
693
  this.message = "[WindowManager]: room phase only Connected can be bindContainer";
761
694
  }
762
695
  }
763
- const onObjectByEvent = (event) => {
764
- return (object, func) => {
765
- if (object === void 0)
766
- return;
767
- if (whiteWebSdk.listenUpdated) {
768
- const listener = (events) => {
769
- const kinds = events.map((e) => e.kind);
770
- if (kinds.includes(event)) {
771
- func();
772
- }
773
- };
774
- whiteWebSdk.listenUpdated(object, listener);
775
- func();
776
- return () => whiteWebSdk.unlistenUpdated(object, listener);
777
- } else {
778
- return whiteWebSdk.reaction(() => object, () => {
779
- func();
780
- }, {
781
- fireImmediately: true
782
- });
783
- }
784
- };
785
- };
786
- const safeListenPropsUpdated = (getProps, callback, onDestroyed) => {
787
- let disposeListenUpdated = null;
788
- const disposeReaction = whiteWebSdk.reaction(getProps, () => {
789
- if (disposeListenUpdated) {
790
- disposeListenUpdated();
791
- disposeListenUpdated = null;
792
- }
793
- const props = getProps();
794
- if (lodash.isObject(props)) {
795
- disposeListenUpdated = () => whiteWebSdk.unlistenUpdated(props, callback);
796
- whiteWebSdk.listenUpdated(props, callback);
797
- } else {
798
- onDestroyed == null ? void 0 : onDestroyed(props);
799
- }
800
- }, { fireImmediately: true });
801
- return () => {
802
- disposeListenUpdated == null ? void 0 : disposeListenUpdated();
803
- disposeReaction();
804
- };
805
- };
806
- const onObjectRemoved = onObjectByEvent(whiteWebSdk.UpdateEventKind.Removed);
807
- onObjectByEvent(whiteWebSdk.UpdateEventKind.Inserted);
808
- const plainObjectKeys = Object.keys;
809
- function isRef(e) {
810
- return Boolean(lodash.has(e, "__isRef"));
811
- }
812
- function makeRef(v) {
813
- return { k: sideEffectManager.genUID(), v, __isRef: true };
814
- }
815
- class StorageEvent {
816
- constructor() {
817
- this.listeners = /* @__PURE__ */ new Set();
818
- }
819
- get length() {
820
- return this.listeners.size;
821
- }
822
- dispatch(message) {
823
- this.listeners.forEach((callback) => callback(message));
824
- }
825
- addListener(listener) {
826
- this.listeners.add(listener);
827
- }
828
- removeListener(listener) {
829
- this.listeners.delete(listener);
830
- }
831
- }
832
- const STORAGE_NS = "_WM-STORAGE_";
833
- class Storage {
834
- constructor(context, id, defaultState) {
835
- this._sideEffect = new sideEffectManager.SideEffectManager();
836
- this._destroyed = false;
837
- this._refMap = /* @__PURE__ */ new WeakMap();
838
- this._lastValue = /* @__PURE__ */ new Map();
839
- this.onStateChanged = new StorageEvent();
840
- if (defaultState && !lodash.isObject(defaultState)) {
841
- throw new Error(`Default state for Storage ${id} is not an object.`);
842
- }
843
- this._context = context;
844
- this.id = id || null;
845
- this._state = {};
846
- const rawState = this._getRawState(this._state);
847
- if (this._context.isWritable) {
848
- if (this.id === null) {
849
- if (context.isAddApp && defaultState) {
850
- this.setState(defaultState);
851
- }
852
- } else {
853
- if (rawState === this._state || !lodash.isObject(rawState)) {
854
- if (!lodash.get(this._context.getAttributes(), [STORAGE_NS])) {
855
- this._context.updateAttributes([STORAGE_NS], {});
856
- }
857
- this._context.updateAttributes([STORAGE_NS, this.id], this._state);
858
- if (defaultState) {
859
- this.setState(defaultState);
860
- }
861
- }
862
- }
863
- }
864
- plainObjectKeys(rawState).forEach((key) => {
865
- if (this.id === null && key === STORAGE_NS) {
866
- return;
867
- }
868
- try {
869
- const rawValue = lodash.isObject(rawState[key]) ? JSON.parse(JSON.stringify(rawState[key])) : rawState[key];
870
- if (isRef(rawValue)) {
871
- this._state[key] = rawValue.v;
872
- if (lodash.isObject(rawValue.v)) {
873
- this._refMap.set(rawValue.v, rawValue);
874
- }
875
- } else {
876
- this._state[key] = rawValue;
877
- }
878
- } catch (e) {
879
- console.error(e);
880
- }
881
- });
882
- this._sideEffect.addDisposer(safeListenPropsUpdated(() => this.id === null ? context.getAttributes() : lodash.get(context.getAttributes(), [STORAGE_NS, this.id]), this._updateProperties.bind(this), this.destroy.bind(this)));
883
- }
884
- get state() {
885
- if (this._destroyed) {
886
- console.warn(`Accessing state on destroyed Storage "${this.id}"`);
887
- }
888
- return this._state;
889
- }
890
- addStateChangedListener(handler) {
891
- this.onStateChanged.addListener(handler);
892
- return () => this.onStateChanged.removeListener(handler);
893
- }
894
- ensureState(state) {
895
- return this.setState(plainObjectKeys(state).reduce((payload, key) => {
896
- if (!lodash.has(this._state, key)) {
897
- payload[key] = state[key];
898
- }
899
- return payload;
900
- }, {}));
901
- }
902
- setState(state) {
903
- if (this._destroyed) {
904
- console.error(new Error(`Cannot call setState on destroyed Storage "${this.id}".`));
905
- return;
906
- }
907
- if (!this._context.isWritable) {
908
- console.error(new Error(`Cannot setState on Storage "${this.id}" without writable access`), state);
909
- return;
910
- }
911
- const keys = plainObjectKeys(state);
912
- if (keys.length > 0) {
913
- keys.forEach((key) => {
914
- const value = state[key];
915
- if (value === this._state[key]) {
916
- return;
917
- }
918
- if (value === void 0) {
919
- this._lastValue.set(key, this._state[key]);
920
- delete this._state[key];
921
- this._setRawState(key, value);
922
- } else {
923
- this._lastValue.set(key, this._state[key]);
924
- this._state[key] = value;
925
- let payload = value;
926
- if (lodash.isObject(value)) {
927
- let refValue = this._refMap.get(value);
928
- if (!refValue) {
929
- refValue = makeRef(value);
930
- this._refMap.set(value, refValue);
931
- }
932
- payload = refValue;
933
- }
934
- this._setRawState(key, payload);
935
- }
936
- });
937
- }
938
- }
939
- emptyStorage() {
940
- if (lodash.size(this._state) <= 0) {
941
- return;
942
- }
943
- if (this._destroyed) {
944
- console.error(new Error(`Cannot empty destroyed Storage "${this.id}".`));
945
- return;
946
- }
947
- if (!this._context.isWritable) {
948
- console.error(new Error(`Cannot empty Storage "${this.id}" without writable access.`));
949
- return;
950
- }
951
- this.setState(lodash.mapValues(this._state, lodash.noop));
952
- }
953
- deleteStorage() {
954
- if (this.id === null) {
955
- throw new Error(`Cannot delete main Storage`);
956
- }
957
- if (!this._context.isWritable) {
958
- console.error(new Error(`Cannot delete Storage "${this.id}" without writable access.`));
959
- return;
960
- }
961
- this.destroy();
962
- this._context.updateAttributes([STORAGE_NS, this.id], void 0);
963
- }
964
- get destroyed() {
965
- return this._destroyed;
966
- }
967
- destroy() {
968
- this._destroyed = true;
969
- this._sideEffect.flushAll();
970
- }
971
- _getRawState(defaultValue) {
972
- var _a;
973
- if (this.id === null) {
974
- return (_a = this._context.getAttributes()) != null ? _a : defaultValue;
975
- } else {
976
- return lodash.get(this._context.getAttributes(), [STORAGE_NS, this.id], defaultValue);
977
- }
978
- }
979
- _setRawState(key, value) {
980
- if (this.id === null) {
981
- if (key === STORAGE_NS) {
982
- throw new Error(`Cannot set attribute internal filed "${STORAGE_NS}"`);
983
- }
984
- return this._context.updateAttributes([key], value);
985
- } else {
986
- return this._context.updateAttributes([STORAGE_NS, this.id, key], value);
987
- }
988
- }
989
- _updateProperties(actions) {
990
- var _a;
991
- if (this._destroyed) {
992
- console.error(new Error(`Cannot call _updateProperties on destroyed Storage "${this.id}".`));
993
- return;
994
- }
995
- if (actions.length > 0) {
996
- const diffs = {};
997
- for (let i = 0; i < actions.length; i++) {
998
- try {
999
- const action = actions[i];
1000
- const key = action.key;
1001
- if (this.id === null && key === STORAGE_NS) {
1002
- continue;
1003
- }
1004
- const value = lodash.isObject(action.value) ? JSON.parse(JSON.stringify(action.value)) : action.value;
1005
- let oldValue;
1006
- if (this._lastValue.has(key)) {
1007
- oldValue = this._lastValue.get(key);
1008
- this._lastValue.delete(key);
1009
- }
1010
- switch (action.kind) {
1011
- case 2: {
1012
- if (lodash.has(this._state, key)) {
1013
- oldValue = this._state[key];
1014
- delete this._state[key];
1015
- }
1016
- diffs[key] = { oldValue };
1017
- break;
1018
- }
1019
- default: {
1020
- let newValue = value;
1021
- if (isRef(value)) {
1022
- const { k: k2, v } = value;
1023
- const curValue = this._state[key];
1024
- if (lodash.isObject(curValue) && ((_a = this._refMap.get(curValue)) == null ? void 0 : _a.k) === k2) {
1025
- newValue = curValue;
1026
- } else {
1027
- newValue = v;
1028
- if (lodash.isObject(v)) {
1029
- this._refMap.set(v, value);
1030
- }
1031
- }
1032
- }
1033
- if (newValue !== this._state[key]) {
1034
- oldValue = this._state[key];
1035
- this._state[key] = newValue;
1036
- }
1037
- diffs[key] = { newValue, oldValue };
1038
- break;
1039
- }
1040
- }
1041
- } catch (e) {
1042
- console.error(e);
1043
- }
1044
- }
1045
- this.onStateChanged.dispatch(diffs);
1046
- }
1047
- }
1048
- }
1049
696
  class WhiteBoardView {
1050
697
  constructor(view, appContext, appProxy, ensureSize) {
1051
698
  this.view = view;
@@ -1074,11 +721,12 @@ class WhiteBoardView {
1074
721
  const scenePath = this.appProxy.scenePath;
1075
722
  if (!scenePath)
1076
723
  return;
724
+ const scenes = Array.isArray(scene) ? scene : [scene || {}];
1077
725
  if (after) {
1078
726
  const nextIndex = this.pageState.index + 1;
1079
- putScenes(this.appContext.room, scenePath, [scene || {}], nextIndex);
727
+ putScenes(this.appContext.room, scenePath, scenes, nextIndex);
1080
728
  } else {
1081
- putScenes(this.appContext.room, scenePath, [scene || {}]);
729
+ putScenes(this.appContext.room, scenePath, scenes);
1082
730
  }
1083
731
  };
1084
732
  this.removePage = async (index2) => {
@@ -1278,10 +926,20 @@ class AppContext {
1278
926
  this.getAppOptions = () => {
1279
927
  return typeof this.appOptions === "function" ? this.appOptions() : this.appOptions;
1280
928
  };
1281
- this.createStorage = (storeId, defaultState) => {
1282
- const storage = new Storage(this, storeId, defaultState);
929
+ this.createStorage = (namespace, defaultState) => {
930
+ const isWritable$ = new valueEnhancer.Val(this.isWritable);
931
+ const plugin$ = new valueEnhancer.Val(this.manager.windowManger);
932
+ const storage = new syncedStore.Storage({
933
+ plugin$,
934
+ isWritable$,
935
+ namespace,
936
+ defaultState
937
+ });
938
+ this.emitter.on("writableChange", (writable) => {
939
+ isWritable$.setValue(writable);
940
+ });
1283
941
  this.emitter.on("destroy", () => {
1284
- storage.destroy();
942
+ storage.disconnect();
1285
943
  });
1286
944
  return storage;
1287
945
  };
@@ -1344,7 +1002,7 @@ class AppContext {
1344
1002
  }
1345
1003
  get storage() {
1346
1004
  if (!this._storage) {
1347
- this._storage = new Storage(this);
1005
+ this._storage = this.createStorage(this.appId, this.getAttributes());
1348
1006
  }
1349
1007
  return this._storage;
1350
1008
  }
@@ -1402,6 +1060,77 @@ class AppPageStateImpl {
1402
1060
  (_a = this.sceneNode) == null ? void 0 : _a.dispose();
1403
1061
  }
1404
1062
  }
1063
+ class CameraSynchronizer {
1064
+ constructor(saveCamera) {
1065
+ this.saveCamera = saveCamera;
1066
+ this.scale = 1;
1067
+ this.setRect = (rect, updateCamera = true) => {
1068
+ this.rect = rect;
1069
+ if (this.remoteCamera && this.remoteSize && updateCamera) {
1070
+ this.onRemoteUpdate(this.remoteCamera, this.remoteSize);
1071
+ }
1072
+ };
1073
+ this.onRemoteUpdate = lodash.throttle((camera, size) => {
1074
+ this.remoteCamera = camera;
1075
+ this.remoteSize = size;
1076
+ if (this.remoteSize && this.rect) {
1077
+ requestAnimationFrame(() => {
1078
+ this.moveCameraToContian(size);
1079
+ this.moveCamera(camera);
1080
+ });
1081
+ }
1082
+ }, 32);
1083
+ }
1084
+ setView(view) {
1085
+ this.view = view;
1086
+ }
1087
+ onRemoteSizeUpdate(size) {
1088
+ var _a;
1089
+ this.remoteSize = size;
1090
+ const needMoveCamera = !lodash.isEqual(lodash.pick(this.rect, ["width", "height"]), lodash.pick(size, ["width", "height"]));
1091
+ if (this.rect && this.remoteCamera && needMoveCamera) {
1092
+ if (!this.view)
1093
+ return;
1094
+ const currentCamera = this.view.camera;
1095
+ (_a = this.view) == null ? void 0 : _a.moveCameraToContain({
1096
+ width: size.width,
1097
+ height: size.height,
1098
+ originX: currentCamera.centerX - size.width / 2,
1099
+ originY: currentCamera.centerY - size.height / 2
1100
+ });
1101
+ }
1102
+ }
1103
+ onLocalCameraUpdate(camera) {
1104
+ this.saveCamera(camera);
1105
+ this.remoteCamera = camera;
1106
+ }
1107
+ moveCameraToContian(size) {
1108
+ if (!lodash.isEmpty(size) && this.view) {
1109
+ this.view.moveCameraToContain({
1110
+ width: size.width,
1111
+ height: size.height,
1112
+ originX: -size.width / 2,
1113
+ originY: -size.height / 2,
1114
+ animationMode: whiteWebSdk.AnimationMode.Immediately
1115
+ });
1116
+ this.scale = this.view.camera.scale;
1117
+ }
1118
+ }
1119
+ moveCamera(camera) {
1120
+ if (!lodash.isEmpty(camera) && this.view && camera.centerX && camera.centerY) {
1121
+ if (lodash.isEqual(camera, this.view.camera))
1122
+ return;
1123
+ const { centerX, centerY, scale: scale2 } = camera;
1124
+ const needScale = scale2 * (this.scale || 1);
1125
+ this.view.moveCamera({
1126
+ centerX,
1127
+ centerY,
1128
+ scale: needScale,
1129
+ animationMode: whiteWebSdk.AnimationMode.Immediately
1130
+ });
1131
+ }
1132
+ }
1133
+ }
1405
1134
  class ViewSync {
1406
1135
  constructor(context) {
1407
1136
  this.context = context;
@@ -1419,8 +1148,9 @@ class ViewSync {
1419
1148
  };
1420
1149
  this.subscribeView = () => {
1421
1150
  return this.context.view$.subscribe((view) => {
1151
+ var _a;
1422
1152
  const currentCamera = this.context.camera$.value;
1423
- if (currentCamera && this.context.size$.value) {
1153
+ if (currentCamera && this.context.size$.value && ((_a = this.needRecoverCamera$) == null ? void 0 : _a.value)) {
1424
1154
  view == null ? void 0 : view.moveCamera({
1425
1155
  scale: 1,
1426
1156
  animationMode: whiteWebSdk.AnimationMode.Immediately
@@ -1469,10 +1199,13 @@ class ViewSync {
1469
1199
  return;
1470
1200
  if (!this.isBroadcastMode)
1471
1201
  return;
1472
- if (this.context.size$.value && this.context.stageRect$.value) {
1473
- const diffScale = computedMinScale(this.context.size$.value, this.context.stageRect$.value);
1474
- const remoteScale = camera.scale / diffScale;
1475
- this.synchronizer.onLocalCameraUpdate(__spreadProps(__spreadValues({}, camera), { scale: remoteScale, id: this.context.uid }));
1202
+ const { size$, stageRect$, view$ } = this.context;
1203
+ if (size$.value && stageRect$.value && view$.value) {
1204
+ this.synchronizer.onLocalCameraUpdate(__spreadProps(__spreadValues({}, camera), { id: this.context.uid }));
1205
+ const newSize = __spreadProps(__spreadValues({}, view$.value.size), { id: this.context.uid });
1206
+ if (!lodash.isEqual(size$.value, newSize)) {
1207
+ this.context.storeSize(newSize);
1208
+ }
1476
1209
  }
1477
1210
  };
1478
1211
  this.synchronizer = this.createSynchronizer();
@@ -1483,9 +1216,13 @@ class ViewSync {
1483
1216
  this.subscribeSize(),
1484
1217
  this.subscribeStageRect()
1485
1218
  ]);
1219
+ if (context.viewMode$) {
1220
+ this.needRecoverCamera$ = valueEnhancer.derive(context.viewMode$, (mode) => mode !== "scroll");
1221
+ }
1486
1222
  const camera$size$ = valueEnhancer.combine([this.context.camera$, this.context.size$]);
1487
1223
  camera$size$.reaction(([camera, size]) => {
1488
- if (camera && size) {
1224
+ var _a;
1225
+ if (camera && size && ((_a = this.needRecoverCamera$) == null ? void 0 : _a.value)) {
1489
1226
  this.synchronizer.onRemoteUpdate(camera, size);
1490
1227
  camera$size$.destroy();
1491
1228
  }
@@ -2566,6 +2303,51 @@ class MainViewProxy {
2566
2303
  this.sideEffectManager.flushAll();
2567
2304
  }
2568
2305
  }
2306
+ const onObjectByEvent = (event) => {
2307
+ return (object, func) => {
2308
+ if (object === void 0)
2309
+ return;
2310
+ if (whiteWebSdk.listenUpdated) {
2311
+ const listener = (events) => {
2312
+ const kinds = events.map((e) => e.kind);
2313
+ if (kinds.includes(event)) {
2314
+ func();
2315
+ }
2316
+ };
2317
+ whiteWebSdk.listenUpdated(object, listener);
2318
+ func();
2319
+ return () => whiteWebSdk.unlistenUpdated(object, listener);
2320
+ } else {
2321
+ return whiteWebSdk.reaction(() => object, () => {
2322
+ func();
2323
+ }, {
2324
+ fireImmediately: true
2325
+ });
2326
+ }
2327
+ };
2328
+ };
2329
+ const safeListenPropsUpdated = (getProps, callback, onDestroyed) => {
2330
+ let disposeListenUpdated = null;
2331
+ const disposeReaction = whiteWebSdk.reaction(getProps, () => {
2332
+ if (disposeListenUpdated) {
2333
+ disposeListenUpdated();
2334
+ disposeListenUpdated = null;
2335
+ }
2336
+ const props = getProps();
2337
+ if (lodash.isObject(props)) {
2338
+ disposeListenUpdated = () => whiteWebSdk.unlistenUpdated(props, callback);
2339
+ whiteWebSdk.listenUpdated(props, callback);
2340
+ } else {
2341
+ onDestroyed == null ? void 0 : onDestroyed(props);
2342
+ }
2343
+ }, { fireImmediately: true });
2344
+ return () => {
2345
+ disposeListenUpdated == null ? void 0 : disposeListenUpdated();
2346
+ disposeReaction();
2347
+ };
2348
+ };
2349
+ const onObjectRemoved = onObjectByEvent(whiteWebSdk.UpdateEventKind.Removed);
2350
+ onObjectByEvent(whiteWebSdk.UpdateEventKind.Inserted);
2569
2351
  class RedoUndo {
2570
2352
  constructor(context) {
2571
2353
  this.context = context;
@@ -2625,24 +2407,176 @@ class RedoUndo {
2625
2407
  this.disposePrevFocusViewRedoUndoListeners(this.context.focus());
2626
2408
  }
2627
2409
  }
2410
+ const createScrollStorage = (manager) => {
2411
+ return new syncedStore.Storage({
2412
+ plugin$: new valueEnhancer.Val(manager.windowManger),
2413
+ isWritable$: manager.isWritable$,
2414
+ namespace: "scrollStorage",
2415
+ defaultState: { scrollTop: 0 }
2416
+ });
2417
+ };
2418
+ function clamp$2(x2, min, max) {
2419
+ return x2 < min ? min : x2 > max ? max : x2;
2420
+ }
2421
+ class ScrollMode {
2422
+ constructor(manager) {
2423
+ var _a;
2424
+ this.manager = manager;
2425
+ this.sideEffect = new sideEffectManager.SideEffectManager();
2426
+ this.baseWidth = SCROLL_MODE_BASE_WIDTH;
2427
+ this.baseHeight = SCROLL_MODE_BASE_HEIGHT;
2428
+ this.initScroll = () => {
2429
+ const halfWbHeight = this._size$.value.height / 2 / this._scale$.value;
2430
+ const scrollTop = this._scrollTop$.value;
2431
+ this._scrollTop$.setValue(clamp$2(scrollTop, halfWbHeight, this.baseHeight - halfWbHeight) - 0.01);
2432
+ };
2433
+ this.getWhiteboardElement = (root) => {
2434
+ const className = ".netless-window-manager-main-view";
2435
+ return root && root.querySelector(className);
2436
+ };
2437
+ this.onWheel = (ev) => {
2438
+ var _a2;
2439
+ const target = ev.target;
2440
+ if (this.manager.canOperate && ((_a2 = this._whiteboard$.value) == null ? void 0 : _a2.contains(target))) {
2441
+ ev.preventDefault();
2442
+ ev.stopPropagation();
2443
+ const dy = ev.deltaY || 0;
2444
+ const { width } = this._size$.value;
2445
+ if (dy && width > 0) {
2446
+ const halfWbHeight = this._size$.value.height / 2 / this._scale$.value;
2447
+ const scrollTop = this._scrollTop$.value + dy / this._scale$.value;
2448
+ this.scrollStorage.setState({
2449
+ scrollTop: clamp$2(scrollTop, halfWbHeight, this.baseHeight - halfWbHeight)
2450
+ });
2451
+ callbacks.emit("userScroll");
2452
+ }
2453
+ }
2454
+ };
2455
+ this._root$ = new valueEnhancer.Val(null);
2456
+ this._mainView$ = new valueEnhancer.Val(this.manager.mainView);
2457
+ this._mainView$.value.disableCameraTransform = true;
2458
+ if ((_a = manager.scrollBaseSize$) == null ? void 0 : _a.value) {
2459
+ this.baseWidth = manager.scrollBaseSize$.value.width;
2460
+ this.baseHeight = manager.scrollBaseSize$.value.height;
2461
+ }
2462
+ this.scrollStorage = createScrollStorage(manager);
2463
+ const scrollTop$ = new valueEnhancer.Val(this.scrollStorage.state.scrollTop);
2464
+ this._scrollTop$ = scrollTop$;
2465
+ this.sideEffect.push(this.scrollStorage.on("stateChanged", () => {
2466
+ this._scrollTop$.setValue(this.scrollStorage.state.scrollTop);
2467
+ }));
2468
+ const size$ = new valueEnhancer.Val({ width: 0, height: 0 }, { compare: (a, b2) => a.width === b2.width && a.height === b2.height });
2469
+ this._size$ = size$;
2470
+ this.sideEffect.add(() => {
2471
+ const onSizeUpdated = size$.setValue.bind(size$);
2472
+ onSizeUpdated(this._mainView$.value.size);
2473
+ this._mainView$.value.callbacks.on("onSizeUpdated", onSizeUpdated);
2474
+ return () => this._mainView$.value.callbacks.off("onSizeUpdated", onSizeUpdated);
2475
+ });
2476
+ this.sideEffect.add(() => {
2477
+ const onCameraUpdated = (camera) => {
2478
+ const halfWbHeight = size$.value.height / 2 / scale$.value;
2479
+ const scrollTop = camera.centerY;
2480
+ this.scrollStorage.setState({
2481
+ scrollTop: clamp$2(scrollTop, halfWbHeight, this.baseHeight - halfWbHeight)
2482
+ });
2483
+ callbacks.emit("userScroll");
2484
+ };
2485
+ this._mainView$.value.callbacks.on("onCameraUpdatedByDevice", onCameraUpdated);
2486
+ return () => this._mainView$.value.callbacks.off("onCameraUpdatedByDevice", onCameraUpdated);
2487
+ });
2488
+ const scale$ = valueEnhancer.derive(size$, (size) => size.width / this.baseWidth);
2489
+ this._scale$ = scale$;
2490
+ const page$ = new valueEnhancer.Val(0);
2491
+ this.sideEffect.push(valueEnhancer.combine([scrollTop$, size$, scale$]).subscribe(([scrollTop, size, scale2]) => {
2492
+ if (scale2 > 0) {
2493
+ const wbHeight = size.height / scale2;
2494
+ page$.setValue(Math.max(scrollTop / wbHeight - 0.5, 0));
2495
+ }
2496
+ }));
2497
+ this._page$ = page$;
2498
+ this.sideEffect.push(valueEnhancer.combine([scrollTop$, scale$]).subscribe(([scrollTop, scale2]) => {
2499
+ this.updateBound(scrollTop, size$.value, scale2);
2500
+ }));
2501
+ this.sideEffect.push(size$.reaction(() => {
2502
+ this.updateScroll(scrollTop$.value);
2503
+ }));
2504
+ const whiteboard$ = valueEnhancer.derive(this._root$, this.getWhiteboardElement);
2505
+ this._whiteboard$ = whiteboard$;
2506
+ this.sideEffect.push(whiteboard$.reaction((el) => {
2507
+ if (el == null ? void 0 : el.parentElement) {
2508
+ this.sideEffect.addEventListener(el.parentElement, "wheel", this.onWheel, { capture: true, passive: false }, "wheel");
2509
+ }
2510
+ }));
2511
+ const maxScrollPage$ = valueEnhancer.combine([this._size$, this._scale$], ([size, scale2]) => {
2512
+ const halfWbHeight = size.height / 2 / scale2;
2513
+ return (this.baseHeight - halfWbHeight) / halfWbHeight / 2 - 0.51;
2514
+ });
2515
+ this.scrollState$ = valueEnhancer.combine([this._scrollTop$, this._page$, maxScrollPage$], ([scrollTop, page, maxScrollPage]) => {
2516
+ return {
2517
+ scrollTop,
2518
+ page,
2519
+ maxScrollPage
2520
+ };
2521
+ });
2522
+ this.updateScroll(scrollTop$.value);
2523
+ this.sideEffect.push(this.scrollState$.subscribe((state) => callbacks.emit("scrollStateChange", state)));
2524
+ this.initScroll();
2525
+ }
2526
+ setRoot(root) {
2527
+ this._root$.setValue(root);
2528
+ }
2529
+ updateScroll(scrollTop) {
2530
+ this._mainView$.value.moveCamera({
2531
+ centerY: scrollTop,
2532
+ animationMode: whiteWebSdk.AnimationMode.Immediately
2533
+ });
2534
+ }
2535
+ updateBound(scrollTop, { height }, scale2) {
2536
+ if (scale2 > 0) {
2537
+ this._mainView$.value.moveCameraToContain({
2538
+ originX: 0,
2539
+ originY: scrollTop - height / scale2 / 2,
2540
+ width: this.baseWidth,
2541
+ height: height / scale2,
2542
+ animationMode: whiteWebSdk.AnimationMode.Immediately
2543
+ });
2544
+ this._mainView$.value.setCameraBound({
2545
+ damping: 1,
2546
+ maxContentMode: () => scale2,
2547
+ minContentMode: () => scale2,
2548
+ centerX: this.baseWidth / 2,
2549
+ centerY: this.baseHeight / 2,
2550
+ width: this.baseWidth,
2551
+ height: this.baseHeight
2552
+ });
2553
+ }
2554
+ }
2555
+ dispose() {
2556
+ this.sideEffect.flushAll();
2557
+ }
2558
+ }
2628
2559
  class AppManager {
2629
2560
  constructor(windowManger) {
2561
+ var _a;
2630
2562
  this.windowManger = windowManger;
2631
2563
  this.appProxies = /* @__PURE__ */ new Map();
2632
2564
  this.appStatus = /* @__PURE__ */ new Map();
2633
2565
  this.store = store;
2634
2566
  this.isReplay = this.windowManger.isReplay;
2635
2567
  this.mainViewScenesLength = 0;
2568
+ this.scrollBaseSize$ = new valueEnhancer.Val(null);
2636
2569
  this.callbacksNode = null;
2637
2570
  this.appCreateQueue = new AppCreateQueue();
2638
2571
  this.sceneIndex$ = new valueEnhancer.Val(void 0);
2639
2572
  this.focused$ = new valueEnhancer.Val(void 0);
2640
2573
  this.members$ = new valueEnhancer.Val([]);
2574
+ this.isWritable$ = new valueEnhancer.Val(Boolean((_a = this.room) == null ? void 0 : _a.isWritable));
2641
2575
  this.sideEffectManager = new sideEffectManager.SideEffectManager();
2642
2576
  this.sceneState = null;
2643
2577
  this.rootDirRemoving = false;
2644
2578
  this.onRemoveScenes = async (params) => {
2645
- var _a, _b;
2579
+ var _a2, _b;
2646
2580
  const { scenePath } = params;
2647
2581
  if (scenePath === ROOT_DIR) {
2648
2582
  await this.onRootDirRemoved();
@@ -2651,7 +2585,7 @@ class AppManager {
2651
2585
  }
2652
2586
  if (isRootDirPage(scenePath)) {
2653
2587
  let nextIndex = this.mainView.focusSceneIndex || 0;
2654
- let sceneName = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[nextIndex];
2588
+ let sceneName = (_a2 = this.callbacksNode) == null ? void 0 : _a2.scenes[nextIndex];
2655
2589
  if (!sceneName) {
2656
2590
  nextIndex = 0;
2657
2591
  sceneName = (_b = this.callbacksNode) == null ? void 0 : _b.scenes[nextIndex];
@@ -2702,11 +2636,11 @@ class AppManager {
2702
2636
  }
2703
2637
  };
2704
2638
  this.removeSceneByIndex = async (index2) => {
2705
- var _a;
2639
+ var _a2;
2706
2640
  const nextIndex = calculateNextIndex(index2, this.windowManger.pageState);
2707
2641
  this.setSceneIndexWithoutSync(nextIndex);
2708
2642
  this.dispatchInternalEvent(Events.SetAppFocusIndex, { type: "main", index: nextIndex });
2709
- const scene = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[index2];
2643
+ const scene = (_a2 = this.callbacksNode) == null ? void 0 : _a2.scenes[index2];
2710
2644
  setTimeout(() => {
2711
2645
  if (scene) {
2712
2646
  removeScenes(this.room, `${ROOT_DIR}${scene}`, index2);
@@ -2724,8 +2658,8 @@ class AppManager {
2724
2658
  });
2725
2659
  };
2726
2660
  this.setSceneIndexWithoutSync = (index2) => {
2727
- var _a;
2728
- const sceneName = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[index2];
2661
+ var _a2;
2662
+ const sceneName = (_a2 = this.callbacksNode) == null ? void 0 : _a2.scenes[index2];
2729
2663
  if (sceneName) {
2730
2664
  this.mainViewProxy.setFocusScenePath(`${ROOT_DIR}${sceneName}`);
2731
2665
  }
@@ -2796,8 +2730,8 @@ class AppManager {
2796
2730
  });
2797
2731
  };
2798
2732
  this.addAppCloseListener = () => {
2799
- var _a;
2800
- (_a = this.refresher) == null ? void 0 : _a.add("appsClose", () => {
2733
+ var _a2;
2734
+ (_a2 = this.refresher) == null ? void 0 : _a2.add("appsClose", () => {
2801
2735
  return onObjectRemoved(this.attributes.apps, () => {
2802
2736
  this.onAppDelete(this.attributes.apps);
2803
2737
  });
@@ -2814,13 +2748,13 @@ class AppManager {
2814
2748
  }
2815
2749
  };
2816
2750
  this.onFocusChange = (focused) => {
2817
- var _a;
2751
+ var _a2;
2818
2752
  if (this.focused$.value !== focused) {
2819
2753
  callbacks.emit("focusedChange", focused);
2820
2754
  emitter.emit("focusedChange", { focused, prev: this.focused$.value });
2821
2755
  this.focused$.setValue(focused);
2822
2756
  if (focused !== void 0) {
2823
- (_a = this.boxManager) == null ? void 0 : _a.focusBox({ appId: focused });
2757
+ (_a2 = this.boxManager) == null ? void 0 : _a2.focusBox({ appId: focused });
2824
2758
  setTimeout(() => {
2825
2759
  const appProxy = this.appProxies.get(focused);
2826
2760
  if (appProxy) {
@@ -2846,14 +2780,14 @@ class AppManager {
2846
2780
  });
2847
2781
  };
2848
2782
  this.onMinimized = (minimized) => {
2849
- var _a, _b;
2850
- if (((_a = this.boxManager) == null ? void 0 : _a.minimized) !== minimized) {
2783
+ var _a2, _b;
2784
+ if (((_a2 = this.boxManager) == null ? void 0 : _a2.minimized) !== minimized) {
2851
2785
  if (minimized === true) {
2852
2786
  (_b = this.boxManager) == null ? void 0 : _b.blurAllBox();
2853
2787
  }
2854
2788
  setTimeout(() => {
2855
- var _a2;
2856
- (_a2 = this.boxManager) == null ? void 0 : _a2.setMinimized(Boolean(minimized));
2789
+ var _a3;
2790
+ (_a3 = this.boxManager) == null ? void 0 : _a3.setMinimized(Boolean(minimized));
2857
2791
  }, 0);
2858
2792
  }
2859
2793
  };
@@ -2893,11 +2827,11 @@ class AppManager {
2893
2827
  }
2894
2828
  };
2895
2829
  this.displayerWritableListener = (isReadonly) => {
2896
- var _a, _b;
2830
+ var _a2, _b;
2897
2831
  const isWritable = !isReadonly;
2898
2832
  const isManualWritable = this.windowManger.readonly === void 0 || !this.windowManger.readonly;
2899
2833
  if (this.windowManger.readonly === void 0) {
2900
- (_a = this.boxManager) == null ? void 0 : _a.setReadonly(isReadonly);
2834
+ (_a2 = this.boxManager) == null ? void 0 : _a2.setReadonly(isReadonly);
2901
2835
  } else {
2902
2836
  (_b = this.boxManager) == null ? void 0 : _b.setReadonly(!(isWritable && isManualWritable));
2903
2837
  }
@@ -2910,6 +2844,7 @@ class AppManager {
2910
2844
  }
2911
2845
  }
2912
2846
  emitter.emit("writableChange", isWritable);
2847
+ this.isWritable$.setValue(isWritable);
2913
2848
  };
2914
2849
  this.updateSceneIndex = () => {
2915
2850
  const scenePath = this.store.getMainViewScenePath();
@@ -2942,10 +2877,10 @@ class AppManager {
2942
2877
  this.refresher.setContext({ emitter });
2943
2878
  this.sideEffectManager.add(() => {
2944
2879
  return () => {
2945
- var _a, _b, _c;
2880
+ var _a2, _b, _c;
2946
2881
  this.appCreateQueue.destroy();
2947
2882
  this.mainViewProxy.destroy();
2948
- (_a = this.refresher) == null ? void 0 : _a.destroy();
2883
+ (_a2 = this.refresher) == null ? void 0 : _a2.destroy();
2949
2884
  this.viewManager.destroy();
2950
2885
  (_b = this.boxManager) == null ? void 0 : _b.destroy();
2951
2886
  (_c = this.callbacksNode) == null ? void 0 : _c.dispose();
@@ -2964,6 +2899,16 @@ class AppManager {
2964
2899
  this.safeUpdateAttributes([Fields.Registered, payload.kind], payload);
2965
2900
  });
2966
2901
  this.members$.setValue(serializeRoomMembers(this.displayer.state.roomMembers));
2902
+ emitter.on("mainViewMounted", () => {
2903
+ this.windowManger.viewMode$.subscribe((viewMode) => {
2904
+ const playground = this.windowManger.playground$.value;
2905
+ if (viewMode === "scroll" && playground) {
2906
+ const scrollMode = new ScrollMode(this);
2907
+ this.scrollMode = scrollMode;
2908
+ scrollMode.setRoot(playground);
2909
+ }
2910
+ });
2911
+ });
2967
2912
  }
2968
2913
  async onRootDirRemoved(needClose = true) {
2969
2914
  await this.setMainViewScenePath(INIT_DIR);
@@ -6901,7 +6846,7 @@ class CursorManager {
6901
6846
  this.initCursorInstance = (uid) => {
6902
6847
  let cursorInstance = this.cursorInstances.get(uid);
6903
6848
  if (!cursorInstance) {
6904
- cursorInstance = new Cursor(this.manager, uid, this, WindowManager.playground);
6849
+ cursorInstance = new Cursor(this.manager, uid, this, this.playground$.value);
6905
6850
  this.cursorInstances.set(uid, cursorInstance);
6906
6851
  }
6907
6852
  return cursorInstance;
@@ -6944,7 +6889,7 @@ class CursorManager {
6944
6889
  this.hideCursor(this.manager.uid);
6945
6890
  };
6946
6891
  this.roomMembers = (_a = this.manager.room) == null ? void 0 : _a.state.roomMembers;
6947
- const playground = WindowManager.playground;
6892
+ const playground = this.playground$.value;
6948
6893
  if (playground) {
6949
6894
  this.setupWrapper(playground);
6950
6895
  }
@@ -6958,6 +6903,9 @@ class CursorManager {
6958
6903
  this.applianceIcons = __spreadValues(__spreadValues({}, ApplianceMap), applianceIcons);
6959
6904
  }
6960
6905
  }
6906
+ get playground$() {
6907
+ return this.manager.windowManger.playground$;
6908
+ }
6961
6909
  canMoveCursor(member) {
6962
6910
  const isLaserPointer = (member == null ? void 0 : member.memberState.currentApplianceName) === whiteWebSdk.ApplianceNames.laserPointer;
6963
6911
  return this.enableCursor || isLaserPointer;
@@ -11695,70 +11643,35 @@ const reconnectRefresher = new ReconnectRefresher({ emitter });
11695
11643
  const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11696
11644
  constructor(context) {
11697
11645
  super(context);
11698
- this.version = "1.0.0-canary.53";
11699
- this.dependencies = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.1.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@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.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "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.3", "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", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "2.16.26" } };
11646
+ this.version = "1.0.0-canary.54";
11647
+ this.dependencies = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/synced-store": "^2.0.7", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.2.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@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.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "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.3", "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", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "^2.16.35" } };
11700
11648
  this.emitter = callbacks;
11701
11649
  this.viewMode = whiteWebSdk.ViewMode.Broadcaster;
11702
11650
  this.viewMode$ = new valueEnhancer.Val(whiteWebSdk.ViewMode.Broadcaster);
11651
+ this.playground$ = new valueEnhancer.Val(void 0);
11703
11652
  this.isReplay = whiteWebSdk.isPlayer(this.displayer);
11704
- this.cameraUpdating = 0;
11705
- this.nextCamera = null;
11706
11653
  this.containerSizeRatio = _WindowManager.containerSizeRatio;
11707
11654
  this.moveCamera = (camera) => {
11708
11655
  var _a;
11656
+ const pureCamera = lodash.omit(camera, ["animationMode"]);
11709
11657
  const mainViewCamera = __spreadValues({}, this.mainView.camera);
11710
- const nextCamera = __spreadValues(__spreadValues({}, mainViewCamera), camera);
11711
- if (lodash.isEqual(nextCamera, mainViewCamera))
11658
+ if (lodash.isEqual(__spreadValues(__spreadValues({}, mainViewCamera), pureCamera), mainViewCamera))
11712
11659
  return;
11713
- if (!this.appManager)
11714
- return;
11715
- if (camera.animationMode === whiteWebSdk.AnimationMode.Immediately) {
11716
- this.appManager.mainViewProxy.storeCamera(__spreadValues({
11717
- id: this.appManager.uid
11718
- }, nextCamera));
11719
- } else {
11720
- const remoteCamera = this.appManager.mainViewProxy.size$.value;
11721
- const currentSize = (_a = this.boxManager) == null ? void 0 : _a.stageRect;
11722
- let nextScale;
11723
- if (camera.scale && remoteCamera && currentSize) {
11724
- nextScale = camera.scale * computedMinScale(remoteCamera, currentSize);
11725
- }
11726
- if (nextScale) {
11727
- this.mainView.moveCamera(__spreadProps(__spreadValues({}, camera), {
11728
- scale: nextScale
11729
- }));
11730
- } else {
11731
- this.mainView.moveCamera(camera);
11732
- }
11733
- this.appManager.dispatchInternalEvent(Events.MoveCamera, camera);
11734
- this.mainView.callbacks.off("onCameraUpdated", this.onCameraUpdated);
11735
- clearTimeout(this.cameraUpdating);
11736
- this.cameraUpdating = 0;
11737
- this.mainView.callbacks.on("onCameraUpdated", this.onCameraUpdated);
11738
- if (nextScale) {
11739
- this.nextCamera = nextCamera;
11740
- }
11741
- }
11742
- };
11743
- this.onCameraUpdated = () => {
11744
- if (this.cameraUpdating) {
11745
- clearTimeout(this.cameraUpdating);
11746
- this.cameraUpdating = 0;
11747
- }
11748
- this.cameraUpdating = setTimeout(() => {
11749
- this.mainView.callbacks.off("onCameraUpdated", this.onCameraUpdated);
11750
- clearTimeout(this.cameraUpdating);
11751
- this.cameraUpdating = 0;
11752
- if (!this.appManager || !this.nextCamera)
11753
- return;
11754
- this.appManager.mainViewProxy.storeCamera(__spreadValues({
11755
- id: this.appManager.uid
11756
- }, this.nextCamera));
11757
- this.nextCamera = null;
11758
- }, 50);
11660
+ this.debouncedStoreCamera();
11661
+ this.mainView.moveCamera(camera);
11662
+ (_a = this.appManager) == null ? void 0 : _a.dispatchInternalEvent(Events.MoveCamera, camera);
11663
+ };
11664
+ this.debouncedStoreCamera = () => {
11665
+ const storeCamera = lodash.debounce(() => {
11666
+ var _a, _b;
11667
+ (_a = this.appManager) == null ? void 0 : _a.mainViewProxy.storeCurrentCamera();
11668
+ (_b = this.appManager) == null ? void 0 : _b.mainViewProxy.storeCurrentSize();
11669
+ this.mainView.callbacks.off("onCameraUpdated", storeCamera);
11670
+ }, 200);
11671
+ this.mainView.callbacks.on("onCameraUpdated", storeCamera);
11759
11672
  };
11760
11673
  _WindowManager.displayer = context.displayer;
11761
- window.NETLESS_DEPS = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.1.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@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.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "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.3", "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", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "2.16.26" } };
11674
+ window.NETLESS_DEPS = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/synced-store": "^2.0.7", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.2.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@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.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "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.3", "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", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "^2.16.35" } };
11762
11675
  }
11763
11676
  static async mount(params) {
11764
11677
  var _a;
@@ -11805,6 +11718,9 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11805
11718
  }
11806
11719
  manager.containerSizeRatio = _WindowManager.containerSizeRatio;
11807
11720
  await manager.ensureAttributes();
11721
+ if (params.viewMode) {
11722
+ manager.viewMode$.setValue(params.viewMode);
11723
+ }
11808
11724
  manager.appManager = new AppManager(manager);
11809
11725
  manager._pageState = new PageStateImpl(manager.appManager);
11810
11726
  manager.cursorManager = new CursorManager(manager.appManager, Boolean(cursor), params.applianceIcons);
@@ -11822,6 +11738,9 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11822
11738
  if (params.container) {
11823
11739
  manager.bindContainer(params.container);
11824
11740
  }
11741
+ if (params.scrollModeWidth && params.scrollModeHeight) {
11742
+ manager.appManager.scrollBaseSize$.setValue({ width: params.scrollModeWidth, height: params.scrollModeHeight });
11743
+ }
11825
11744
  replaceRoomFunction(room, manager);
11826
11745
  emitter.emit("onCreated");
11827
11746
  _WindowManager.isCreated = true;
@@ -11890,6 +11809,7 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11890
11809
  this.bindMainView(mainViewElement, params.disableCameraTransform);
11891
11810
  if (_WindowManager.playground) {
11892
11811
  (_b = this.cursorManager) == null ? void 0 : _b.setupWrapper(_WindowManager.playground);
11812
+ this.playground$.setValue(_WindowManager.playground);
11893
11813
  }
11894
11814
  }
11895
11815
  }
@@ -12105,10 +12025,11 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
12105
12025
  if (mode === whiteWebSdk.ViewMode.Broadcaster) {
12106
12026
  if (this.canOperate) {
12107
12027
  mainViewProxy == null ? void 0 : mainViewProxy.storeCurrentCamera();
12028
+ mainViewProxy == null ? void 0 : mainViewProxy.storeCurrentSize();
12108
12029
  }
12109
12030
  mainViewProxy == null ? void 0 : mainViewProxy.start();
12110
12031
  }
12111
- if (mode === whiteWebSdk.ViewMode.Freedom) {
12032
+ if (mode === whiteWebSdk.ViewMode.Freedom || mode === "scroll") {
12112
12033
  mainViewProxy == null ? void 0 : mainViewProxy.stop();
12113
12034
  }
12114
12035
  this.viewMode = mode;
@@ -12259,6 +12180,10 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
12259
12180
  throw new AppManagerNotInitError();
12260
12181
  }
12261
12182
  }
12183
+ get scrollState() {
12184
+ var _a, _b;
12185
+ return (_b = (_a = this.appManager) == null ? void 0 : _a.scrollMode) == null ? void 0 : _b.scrollState$.value;
12186
+ }
12262
12187
  get teleboxManager() {
12263
12188
  if (!this.boxManager) {
12264
12189
  throw new BoxManagerNotInitializeError();
@@ -12277,6 +12202,12 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
12277
12202
  var _a;
12278
12203
  return (_a = this.appManager) == null ? void 0 : _a.closeApp(appId);
12279
12204
  }
12205
+ moveCameraToContain(rectangle) {
12206
+ var _a;
12207
+ this.debouncedStoreCamera();
12208
+ this.mainView.moveCameraToContain(rectangle);
12209
+ (_a = this.appManager) == null ? void 0 : _a.dispatchInternalEvent(Events.MoveCameraToContain, rectangle);
12210
+ }
12280
12211
  convertToPointInWorld(point) {
12281
12212
  return this.mainView.convertToPointInWorld(point);
12282
12213
  }