@netless/fastboard-core 0.2.6 → 0.2.9

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.
@@ -36,26 +36,43 @@ import { WindowManager as WindowManager3 } from "@netless/window-manager";
36
36
 
37
37
  // src/behaviors/register-apps.ts
38
38
  import { WindowManager } from "@netless/window-manager";
39
- WindowManager.register({
40
- kind: "Monaco",
41
- src: "https://cdn.jsdelivr.net/npm/@netless/app-monaco@latest/dist/main.iife.js"
42
- });
43
- WindowManager.register({
44
- kind: "Countdown",
45
- src: "https://cdn.jsdelivr.net/npm/@netless/app-countdown@latest/dist/main.iife.js"
46
- });
47
- WindowManager.register({
48
- kind: "GeoGebra",
49
- src: "https://cdn.jsdelivr.net/npm/@netless/app-geogebra@latest/dist/main.iife.js",
50
- appOptions: {
51
- HTML5Codebase: "https://flat-storage-cn-hz.whiteboard.agora.io/GeoGebra/HTML5/5.0/web3d"
52
- }
53
- });
39
+ var DefaultApps = {
40
+ Monaco: {
41
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-monaco/0.1.12/dist/main.iife.js"
42
+ },
43
+ Countdown: {
44
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-countdown/0.0.2/dist/main.iife.js"
45
+ },
46
+ GeoGebra: {
47
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-geogebra/0.0.4/dist/main.iife.js",
48
+ appOptions: {
49
+ HTML5Codebase: "https://flat-storage-cn-hz.whiteboard.agora.io/GeoGebra/HTML5/5.0/web3d"
50
+ }
51
+ },
52
+ EmbeddedPage: {
53
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-embedded-page/0.1.1/dist/main.iife.js"
54
+ },
55
+ Player: {
56
+ name: "NetlessAppMediaPlayer",
57
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-media-player/0.1.1/dist/main.iife.js"
58
+ }
59
+ };
60
+ function registerApps(config) {
61
+ for (const kind in config) {
62
+ if (Object.prototype.hasOwnProperty.call(config, kind)) {
63
+ const options = config[kind];
64
+ WindowManager.register(__spreadValues({ kind }, options));
65
+ }
66
+ }
67
+ }
54
68
 
55
69
  // src/helpers/utils.ts
56
70
  import { WindowManager as WindowManager2 } from "@netless/window-manager";
57
71
  function noop() {
58
72
  }
73
+ function safe_not_equal(a, b) {
74
+ return a != a ? b == b : a !== b || a && typeof a === "object" || typeof a === "function";
75
+ }
59
76
  function getImageSize(url, fallback) {
60
77
  return new Promise((resolve) => {
61
78
  const img = new Image();
@@ -138,7 +155,9 @@ var FastboardEmitter = class {
138
155
  function createValue(value, effect, setValue = noop) {
139
156
  const emitter = new FastboardEmitter();
140
157
  function set(newValue) {
141
- emitter.dispatch(value = newValue);
158
+ if (safe_not_equal(value, newValue)) {
159
+ emitter.dispatch(value = newValue);
160
+ }
142
161
  }
143
162
  const dispose = effect(set) || noop;
144
163
  function subscribe(callback) {
@@ -150,7 +169,15 @@ function createValue(value, effect, setValue = noop) {
150
169
  emitter.addListener(callback);
151
170
  return () => emitter.removeListener(callback);
152
171
  }
153
- return { value, subscribe, reaction, setValue, dispose };
172
+ return {
173
+ get value() {
174
+ return value;
175
+ },
176
+ subscribe,
177
+ reaction,
178
+ setValue,
179
+ dispose
180
+ };
154
181
  }
155
182
 
156
183
  // src/impl/app.ts
@@ -208,6 +235,14 @@ var FastboardApp = class extends FastboardAppBase {
208
235
  this.memberState = this.createValue(this.room.state.memberState, (set) => this._addRoomListener("onRoomStateChanged", ({ memberState: m }) => m && set(m)));
209
236
  this.sceneIndex = this.createValue(this.manager.mainViewSceneIndex, (set) => this._addManagerListener("mainViewSceneIndexChange", set), this.manager.setMainViewSceneIndex.bind(this.manager));
210
237
  this.sceneLength = this.createValue(this.manager.mainViewScenesLength, (set) => this._addManagerListener("mainViewScenesLengthChange", set));
238
+ this._appsStatus = {};
239
+ this.appsStatus = this.createValue({}, (set) => this._addManagerListener("loadApp", ({ kind, status, reason }) => {
240
+ this._appsStatus[kind] = {
241
+ status: status === "start" ? "loading" : status === "failed" ? "failed" : "idle",
242
+ reason
243
+ };
244
+ set(this._appsStatus);
245
+ }));
211
246
  }
212
247
  bindContainer(container) {
213
248
  this._assertNotDestroyed();
@@ -294,7 +329,6 @@ var FastboardApp = class extends FastboardAppBase {
294
329
  this._assertNotDestroyed();
295
330
  switch (fileType) {
296
331
  case "pdf":
297
- case "ppt":
298
332
  return this.manager.addApp({
299
333
  kind: "DocsViewer",
300
334
  options: { scenePath, title, scenes }
@@ -431,8 +465,10 @@ async function createFastboard(_a) {
431
465
  sdkConfig,
432
466
  joinRoom: _c
433
467
  } = _b, _d = _c, { callbacks } = _d, joinRoomParams = __objRest(_d, ["callbacks"]), {
434
- managerConfig
468
+ managerConfig,
469
+ appsConfig = DefaultApps
435
470
  } = _b;
471
+ registerApps(appsConfig);
436
472
  const sdk = new WhiteWebSdk(__spreadProps(__spreadValues({}, sdkConfig), {
437
473
  useMobXState: true
438
474
  }));
@@ -472,24 +508,31 @@ async function replayFastboard(_a) {
472
508
  sdkConfig,
473
509
  replayRoom: _c
474
510
  } = _b, _d = _c, { callbacks } = _d, replayRoomParams = __objRest(_d, ["callbacks"]), {
475
- managerConfig
511
+ managerConfig,
512
+ appsConfig = DefaultApps
476
513
  } = _b;
514
+ registerApps(appsConfig);
477
515
  const sdk = new WhiteWebSdk(__spreadProps(__spreadValues({}, sdkConfig), {
478
516
  useMobXState: true
479
517
  }));
480
518
  const player = await sdk.replayRoom(__spreadProps(__spreadValues({}, ensureWindowManager(replayRoomParams)), {
481
519
  useMultiViews: true
482
520
  }), callbacks);
483
- const manager = await WindowManager3.mount(__spreadProps(__spreadValues({
521
+ const managerPromise = WindowManager3.mount(__spreadProps(__spreadValues({
484
522
  cursor: true
485
523
  }, managerConfig), {
486
524
  room: player
487
525
  }));
526
+ player.play();
527
+ const manager = await managerPromise;
528
+ player.pause();
488
529
  return new FastboardPlayer(sdk, player, manager);
489
530
  }
490
531
 
491
532
  export {
533
+ DefaultApps,
534
+ registerApps,
492
535
  createFastboard,
493
536
  replayFastboard
494
537
  };
495
- //# sourceMappingURL=chunk-CS5DXHML.mjs.map
538
+ //# sourceMappingURL=chunk-Z66W5SHZ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/minimal.ts","../src/behaviors/register-apps.ts","../src/helpers/utils.ts","../src/impl/app.ts","../src/helpers/emitter.ts","../src/helpers/value.ts","../src/impl/player.ts"],"sourcesContent":["import type {\n Displayer,\n HotKeys,\n JoinRoomParams,\n PlayerCallbacks,\n ReplayRoomParams,\n Room,\n RoomCallbacks,\n WhiteWebSdkConfiguration,\n} from \"white-web-sdk\";\nimport type { MountParams } from \"@netless/window-manager\";\n\nimport { contentModeScale, DefaultHotKeys, WhiteWebSdk } from \"white-web-sdk\";\nimport { WindowManager } from \"@netless/window-manager\";\n\nimport type { AppsConfig } from \"./behaviors/register-apps\";\n\nimport { DefaultApps, registerApps } from \"./behaviors/register-apps\";\nimport { ensureWindowManager } from \"./helpers/utils\";\nimport { FastboardApp } from \"./impl/app\";\nimport { FastboardPlayer } from \"./impl/player\";\n\nexport type { FastboardReadable, FastboardWritable } from \"./helpers/value\";\n\nexport type { AppsStatus, InsertDocsDynamic, InsertDocsParams, InsertDocsStatic } from \"./impl/app\";\n\nexport type { AppsConfig, FastboardApp, FastboardPlayer };\nexport { DefaultApps, registerApps };\n\nexport interface FastboardOptions {\n sdkConfig: Omit<WhiteWebSdkConfiguration, \"useMobXState\"> & { region: string };\n joinRoom: Omit<JoinRoomParams, \"useMultiViews\" | \"disableNewPencil\" | \"disableMagixEventDispatchLimit\"> & {\n callbacks?: Partial<RoomCallbacks>;\n };\n managerConfig?: Omit<MountParams, \"room\">;\n appsConfig?: AppsConfig;\n}\n\n/**\n * Create a FastboardApp instance.\n * @example\n * let app = await createFastboard({\n * sdkConfig: {\n * appIdentifier: import.meta.env.VITE_APPID,\n * region: \"ch-hz\",\n * },\n * joinRoom: {\n * uid: unique_id,\n * uuid: import.meta.env.VITE_ROOM_UUID,\n * roomToken: import.meta.env.VITE_ROOM_TOKEN,\n * },\n * })\n */\nexport async function createFastboard({\n sdkConfig,\n joinRoom: { callbacks, ...joinRoomParams },\n managerConfig,\n appsConfig = DefaultApps,\n}: FastboardOptions) {\n registerApps(appsConfig);\n\n const sdk = new WhiteWebSdk({\n ...sdkConfig,\n useMobXState: true,\n });\n\n const hotKeys: Partial<HotKeys> = {\n ...DefaultHotKeys,\n changeToSelector: \"s\",\n changeToLaserPointer: \"z\",\n changeToPencil: \"p\",\n changeToRectangle: \"r\",\n changeToEllipse: \"c\",\n changeToEraser: \"e\",\n changeToText: \"t\",\n changeToStraight: \"l\",\n changeToArrow: \"a\",\n changeToHand: \"h\",\n };\n\n const room = await sdk.joinRoom(\n {\n floatBar: true,\n hotKeys,\n ...ensureWindowManager(joinRoomParams),\n useMultiViews: true,\n disableNewPencil: false,\n disableMagixEventDispatchLimit: true,\n },\n callbacks\n );\n\n const manager = await WindowManager.mount({\n cursor: true,\n ...managerConfig,\n room,\n });\n\n manager.mainView.setCameraBound({\n minContentMode: contentModeScale(0.3),\n maxContentMode: contentModeScale(3),\n });\n\n return new FastboardApp(sdk, room, manager, hotKeys);\n}\n\nexport interface FastboardReplayOptions {\n sdkConfig: Omit<WhiteWebSdkConfiguration, \"useMobXState\"> & { region: string };\n replayRoom: Omit<ReplayRoomParams, \"useMultiViews\"> & {\n callbacks?: Partial<PlayerCallbacks>;\n };\n managerConfig?: Omit<MountParams, \"room\">;\n appsConfig?: AppsConfig;\n}\n\n/**\n * Create a FastboardPlayer instance.\n * @example\n * let app = await replayFastboard({\n * sdkConfig: {\n * appIdentifier: import.meta.env.VITE_APPID,\n * region: \"ch-hz\",\n * },\n * replayRoom: {\n * uid: unique_id,\n * uuid: import.meta.env.VITE_ROOM_UUID,\n * roomToken: import.meta.env.VITE_ROOM_TOKEN,\n * },\n * })\n */\nexport async function replayFastboard({\n sdkConfig,\n replayRoom: { callbacks, ...replayRoomParams },\n managerConfig,\n appsConfig = DefaultApps,\n}: FastboardReplayOptions) {\n registerApps(appsConfig);\n\n const sdk = new WhiteWebSdk({\n ...sdkConfig,\n useMobXState: true,\n });\n\n const player = await sdk.replayRoom(\n {\n ...ensureWindowManager(replayRoomParams),\n useMultiViews: true,\n },\n callbacks\n );\n\n const managerPromise = WindowManager.mount({\n cursor: true,\n ...managerConfig,\n room: player as Displayer as Room,\n });\n\n player.play();\n const manager = await managerPromise;\n player.pause();\n\n return new FastboardPlayer(sdk, player, manager);\n}\n","import type { RegisterParams } from \"@netless/window-manager\";\nimport { WindowManager } from \"@netless/window-manager\";\n\nexport interface AppsConfig {\n [kind: string]: Omit<RegisterParams, \"kind\">;\n}\n\nexport const DefaultApps: AppsConfig = {\n Monaco: {\n src: \"https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-monaco/0.1.12/dist/main.iife.js\",\n },\n Countdown: {\n src: \"https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-countdown/0.0.2/dist/main.iife.js\",\n },\n GeoGebra: {\n src: \"https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-geogebra/0.0.4/dist/main.iife.js\",\n appOptions: {\n HTML5Codebase: \"https://flat-storage-cn-hz.whiteboard.agora.io/GeoGebra/HTML5/5.0/web3d\",\n },\n },\n EmbeddedPage: {\n src: \"https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-embedded-page/0.1.1/dist/main.iife.js\",\n },\n Player: {\n name: \"NetlessAppMediaPlayer\",\n src: \"https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-media-player/0.1.1/dist/main.iife.js\",\n },\n};\n\nexport function registerApps(config: AppsConfig) {\n for (const kind in config) {\n if (Object.prototype.hasOwnProperty.call(config, kind)) {\n const options = config[kind];\n WindowManager.register({ kind, ...options });\n }\n }\n}\n","import type { ConvertedFile, JoinRoomParams, ReplayRoomParams, SceneDefinition, Size } from \"white-web-sdk\";\nimport { WindowManager } from \"@netless/window-manager\";\n\nexport function noop() {\n /* noop */\n}\n\nexport function safe_not_equal(a: unknown, b: unknown) {\n return a != a ? b == b : a !== b || (a && typeof a === \"object\") || typeof a === \"function\";\n}\n\nexport function getImageSize(url: string, fallback: Size) {\n return new Promise<Size>(resolve => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => resolve(fallback);\n img.src = url;\n });\n}\n\nexport function makeSlideParams(scenes: SceneDefinition[]) {\n const emptyScenes: SceneDefinition[] = [];\n let taskId = \"\";\n let url = \"\";\n\n // e.g. \"ppt(x)://cdn/prefix/dynamicConvert/{taskId}/1.slide\"\n const pptSrcRE = /^pptx?(?<prefix>:\\/\\/\\S+?dynamicConvert)\\/(?<taskId>\\w+)\\//;\n\n for (const { name, ppt } of scenes) {\n // make sure scenesWithoutPPT.length === scenes.length\n emptyScenes.push({ name });\n\n if (!ppt || !ppt.src.startsWith(\"ppt\")) {\n continue;\n }\n const match = pptSrcRE.exec(ppt.src);\n if (!match || !match.groups) {\n continue;\n }\n taskId = match.groups.taskId;\n url = \"https\" + match.groups.prefix;\n break;\n }\n\n return { emptyScenes, taskId, url };\n}\n\nexport function convertedFileToScene(f: ConvertedFile, i: number) {\n return {\n name: String(i + 1),\n ppt: {\n src: f.conversionFileUrl,\n width: f.width,\n height: f.height,\n previewURL: f.preview,\n },\n };\n}\n\nexport function ensureWindowManager<T extends JoinRoomParams | ReplayRoomParams>(joinRoom: T): T {\n if (!joinRoom.invisiblePlugins || !joinRoom.invisiblePlugins.includes(WindowManager)) {\n joinRoom.invisiblePlugins = [...(joinRoom.invisiblePlugins || []), WindowManager];\n }\n return joinRoom;\n}\n\n// Copy from https://github.com/crimx/side-effect-manager/blob/main/src/gen-uid.ts\nconst SOUP = \"!#%()*+,-./:;=?@[]^_`{|}~\" + \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\nconst SOUP_LEN = SOUP.length;\nconst ID_LEN = 20;\nconst reusedIdCarrier = /* @__PURE__ */ Array(ID_LEN);\n\nexport function genUID() {\n for (let i = 0; i < ID_LEN; i++) {\n reusedIdCarrier[i] = SOUP.charAt(Math.random() * SOUP_LEN);\n }\n return reusedIdCarrier.join(\"\");\n}\n","import type { PublicEvent, WindowManager } from \"@netless/window-manager\";\nimport type {\n AnimationMode,\n ApplianceNames,\n Camera,\n Color,\n ConversionResponse,\n HotKeys,\n MemberState,\n Rectangle,\n Room,\n RoomCallbacks,\n RoomState,\n SceneDefinition,\n ShapeType,\n ViewCallbacks,\n WhiteWebSdk,\n} from \"white-web-sdk\";\nimport type { FastboardDisposer, FastboardInternalValue } from \"../helpers/value\";\n\nimport { BuiltinApps } from \"@netless/window-manager\";\nimport { convertedFileToScene, genUID, getImageSize, makeSlideParams } from \"../helpers/utils\";\nimport { createValue } from \"../helpers/value\";\n\nclass FastboardAppBase {\n public constructor(\n readonly sdk: WhiteWebSdk,\n readonly room: Room,\n readonly manager: WindowManager,\n readonly hotKeys: Partial<HotKeys>\n ) {}\n\n protected readonly _disposers: FastboardDisposer[] = [];\n protected _destroyed = false;\n protected _assertNotDestroyed() {\n if (this._destroyed) {\n throw new Error(\"[FastboardApp] Can not call any method on destroyed FastboardApp.\");\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected createValue: typeof createValue = (...args: [any, any]): any => {\n const value = createValue(...args);\n this._disposers.push((value as FastboardInternalValue<unknown>).dispose);\n return value;\n };\n\n protected _addRoomListener<K extends keyof RoomCallbacks, T = RoomCallbacks[K]>(name: K, listener: T) {\n this._assertNotDestroyed();\n this.room.callbacks.on(name, listener);\n return () => this.room.callbacks.off(name, listener);\n }\n\n protected _addManagerListener<K extends keyof PublicEvent>(name: K, set: (value: PublicEvent[K]) => void) {\n this._assertNotDestroyed();\n this.manager.emitter.on(name, set);\n return () => this.manager.emitter.off(name, set);\n }\n\n protected _addMainViewListener<K extends keyof ViewCallbacks, T = ViewCallbacks[K]>(name: K, listener: T) {\n this._assertNotDestroyed();\n this.manager.mainView.callbacks.on(name, listener);\n return () => this.manager.mainView.callbacks.off(name, listener);\n }\n\n public destroy() {\n this._disposers.forEach(dispose => dispose());\n this._disposers.length = 0;\n this._destroyed = true;\n this.manager.destroy();\n return this.room.disconnect();\n }\n}\n\nexport interface InsertDocsStatic {\n readonly fileType: \"pdf\";\n readonly scenePath: string;\n readonly scenes: SceneDefinition[];\n readonly title?: string;\n}\n\nexport interface InsertDocsDynamic {\n readonly fileType: \"pptx\";\n readonly scenePath: string;\n readonly taskId: string;\n readonly title?: string;\n readonly url?: string;\n /** @example [{ name: '1' }, { name: '2' }, { name: '3' }] */\n readonly scenes?: SceneDefinition[];\n}\n\nexport type InsertDocsParams = InsertDocsStatic | InsertDocsDynamic;\n\nexport type SetMemberStateFn = (partialMemberState: Partial<MemberState>) => void;\n\nexport type RoomStateChanged = (diff: Partial<RoomState>) => void;\n\nexport interface AppsStatus {\n [kind: string]: {\n status: \"idle\" | \"loading\" | \"failed\";\n reason?: string;\n };\n}\n\nexport class FastboardApp extends FastboardAppBase {\n /**\n * Render this app to some DOM.\n */\n bindContainer(container: HTMLElement) {\n this._assertNotDestroyed();\n this.manager.bindContainer(container);\n }\n\n /**\n * Move window-manager's collector to some place.\n */\n bindCollector(container: HTMLElement) {\n this._assertNotDestroyed();\n this.manager.bindCollectorContainer(container);\n }\n\n /**\n * Is current room writable?\n */\n readonly writable = this.createValue(\n this.room.isWritable,\n set => this._addRoomListener(\"onEnableWriteNowChanged\", () => set(this.room.isWritable)),\n this.room.setWritable.bind(this.room)\n );\n\n /**\n * Current window-manager's windows' state (is it maximized?).\n */\n readonly boxState = this.createValue(this.manager.boxState, set =>\n this._addManagerListener(\"boxStateChange\", set)\n );\n\n /**\n * Current window-manager's focused app's id.\n * @example \"HelloWorld-1A2b3C4d\"\n */\n readonly focusedApp = this.createValue(this.manager.focused, set =>\n this._addManagerListener(\"focusedChange\", set)\n );\n\n /**\n * How many times can I call `app.redo()`?\n */\n readonly canRedoSteps = this.createValue(this.manager.canRedoSteps, set =>\n this._addManagerListener(\"canRedoStepsChange\", set)\n );\n\n /**\n * How many times can I call `app.undo()`?\n */\n readonly canUndoSteps = this.createValue(this.manager.canUndoSteps, set =>\n this._addManagerListener(\"canUndoStepsChange\", set)\n );\n\n /**\n * Current camera information of main view.\n */\n readonly camera = this.createValue(this.manager.mainView.camera, set =>\n this._addMainViewListener(\"onCameraUpdated\", set)\n );\n\n /**\n * Current tool's info, like \"is using pencil?\", \"what color?\".\n */\n readonly memberState = this.createValue(this.room.state.memberState, set =>\n this._addRoomListener(\"onRoomStateChanged\", ({ memberState: m }) => m && set(m))\n );\n\n /**\n * 0..n-1, current index of main view scenes.\n */\n readonly sceneIndex = this.createValue(\n this.manager.mainViewSceneIndex,\n set => this._addManagerListener(\"mainViewSceneIndexChange\", set),\n this.manager.setMainViewSceneIndex.bind(this.manager)\n );\n\n /**\n * How many pages are in the main view?\n */\n readonly sceneLength = this.createValue(this.manager.mainViewScenesLength, set =>\n this._addManagerListener(\"mainViewScenesLengthChange\", set)\n );\n\n private _appsStatus: AppsStatus = {};\n /**\n * Apps status.\n */\n readonly appsStatus = this.createValue<AppsStatus>({}, set =>\n this._addManagerListener(\"loadApp\", ({ kind, status, reason }) => {\n this._appsStatus[kind] = {\n status: status === \"start\" ? \"loading\" : status === \"failed\" ? \"failed\" : \"idle\",\n reason,\n };\n set(this._appsStatus);\n })\n );\n\n /**\n * Undo a step on main view.\n */\n undo() {\n this._assertNotDestroyed();\n this.manager.mainView.undo();\n }\n\n /**\n * Redo a step on main view.\n */\n redo() {\n this._assertNotDestroyed();\n this.manager.mainView.redo();\n }\n\n /**\n * Move current main view's camera position.\n */\n moveCamera(camera: Partial<Camera> & { animationMode?: AnimationMode | undefined }) {\n this._assertNotDestroyed();\n this.manager.moveCamera(camera);\n }\n\n /**\n * Move current main view's camera to include a rectangle.\n */\n moveCameraToContain(rectangle: Rectangle & { animationMode?: AnimationMode }) {\n this._assertNotDestroyed();\n this.manager.moveCameraToContain(rectangle);\n }\n\n /**\n * Delete all things on the main view.\n */\n cleanCurrentScene() {\n this._assertNotDestroyed();\n this.manager.cleanCurrentScene();\n }\n\n /**\n * Set current tool, like \"pencil\".\n */\n setAppliance(appliance: ApplianceNames, shape?: ShapeType) {\n this._assertNotDestroyed();\n this.manager.mainView.setMemberState({ currentApplianceName: appliance, shapeType: shape });\n }\n\n setStrokeWidth(strokeWidth: number) {\n this._assertNotDestroyed();\n this.manager.mainView.setMemberState({ strokeWidth });\n }\n\n setStrokeColor(strokeColor: Color) {\n this._assertNotDestroyed();\n this.manager.mainView.setMemberState({ strokeColor });\n }\n\n /**\n * Insert an image to the main view.\n */\n async insertImage(url: string) {\n this._assertNotDestroyed();\n await this.manager.switchMainViewToWriter();\n\n const { divElement } = this.manager.mainView;\n const containerSize = {\n width: divElement?.scrollWidth || window.innerWidth,\n height: divElement?.scrollHeight || window.innerHeight,\n };\n\n // 1. shrink the image a little to fit container **width**\n const maxWidth = containerSize.width * 0.8;\n let { width, height } = await getImageSize(url, containerSize);\n const scale = Math.min(maxWidth / width, 1);\n const uuid = genUID();\n const { centerX, centerY } = this.manager.camera;\n width *= scale;\n height *= scale;\n this.manager.mainView.insertImage({ uuid, centerX, centerY, width, height, locked: false });\n this.manager.mainView.completeImageUpload(uuid, url);\n\n // 2. move camera to fit image **height**\n width /= 0.8;\n height /= 0.8;\n const originX = centerX - width / 2;\n const originY = centerY - height / 2;\n this.manager.moveCameraToContain({ originX, originY, width, height });\n }\n\n /**\n * Insert PDF/PPTX from conversion result.\n * @param status https://developer.netless.link/server-en/home/server-conversion#get-query-task-conversion-progress\n */\n insertDocs(filename: string, status: ConversionResponse): Promise<string | undefined>;\n\n /**\n * Manual way.\n * @example\n * app.insertDocs({\n * fileType: 'pptx',\n * scenePath: `/pptx/${conversion.taskId}`,\n * taskId: conversion.taskId,\n * title: 'Title',\n * })\n */\n insertDocs(params: InsertDocsParams): Promise<string | undefined>;\n\n insertDocs(arg1: string | InsertDocsParams, arg2?: ConversionResponse) {\n if (typeof arg1 === \"object\" && \"fileType\" in arg1) {\n return this._insertDocsImpl(arg1);\n } else if (arg2 && arg2.status !== \"Finished\") {\n throw new Error(\"[FastboardApp] Can not insert a converting doc.\");\n } else if (arg2 && arg2.progress) {\n const scenes: SceneDefinition[] = arg2.progress.convertedFileList.map(convertedFileToScene);\n const scenePath = `/${arg2.uuid}/${genUID()}`;\n const { emptyScenes, taskId, url } = makeSlideParams(scenes);\n if (taskId && url) {\n const title = arg1;\n return this._insertDocsImpl({ fileType: \"pptx\", scenePath, taskId, title, url, scenes: emptyScenes });\n } else {\n return this._insertDocsImpl({ fileType: \"pdf\", scenePath, scenes, title: arg1 });\n }\n }\n }\n\n private _insertDocsImpl({ fileType, scenePath, title, scenes, ...attributes }: InsertDocsParams) {\n this._assertNotDestroyed();\n switch (fileType) {\n case \"pdf\":\n return this.manager.addApp({\n kind: \"DocsViewer\",\n options: { scenePath, title, scenes },\n });\n case \"pptx\":\n return this.manager.addApp({\n kind: \"Slide\",\n options: { scenePath, title, scenes },\n attributes,\n });\n }\n }\n\n /**\n * Insert the Monaco Code Editor app.\n */\n insertCodeEditor() {\n this._assertNotDestroyed();\n return this.manager.addApp({\n kind: \"Monaco\",\n options: { title: \"Code Editor\" },\n });\n }\n\n /**\n * Insert the Countdown app.\n */\n insertCountdown() {\n this._assertNotDestroyed();\n return this.manager.addApp({\n kind: \"Countdown\",\n options: { title: \"Countdown\" },\n });\n }\n\n /**\n * Insert the Media Player app.\n */\n insertMedia(title: string, src: string) {\n this._assertNotDestroyed();\n return this.manager.addApp({\n kind: BuiltinApps.MediaPlayer,\n options: { title },\n attributes: { src },\n });\n }\n\n /**\n * Insert the GeoGebra app.\n */\n insertGeoGebra() {\n this._assertNotDestroyed();\n return this.manager.addApp({\n kind: \"GeoGebra\",\n options: { title: \"GeoGebra\" },\n });\n }\n}\n","export type FastboardListener<T> = (event: T) => void;\n\nexport class FastboardEmitter<T> {\n listeners = new Set<FastboardListener<T>>();\n\n get length(): number {\n return this.listeners.size;\n }\n\n dispatch(message: T) {\n this.listeners.forEach(callback => callback(message));\n }\n\n addListener(listener: FastboardListener<T>) {\n this.listeners.add(listener);\n }\n\n removeListener(listener: FastboardListener<T>) {\n this.listeners.delete(listener);\n }\n}\n","import { FastboardEmitter } from \"./emitter\";\nimport { noop, safe_not_equal } from \"./utils\";\n\nexport type FastboardDisposer = () => void;\n\nexport interface FastboardReadable<T> {\n readonly value: T;\n subscribe(callback: (value: T) => void): FastboardDisposer;\n reaction(callback: (value: T) => void): FastboardDisposer;\n}\n\nexport interface FastboardWritable<T, SetFn = (value: T) => void> extends FastboardReadable<T> {\n setValue: SetFn;\n}\n\nexport interface FastboardInternalValue<T> extends FastboardWritable<T> {\n dispose: FastboardDisposer;\n}\n\n/**\n * Create a readonly, reactive value.\n * @example\n * createValue(manager.getMainViewSceneIndex(), (set) => {\n * manager.emitter.on(\"mainViewSceneIndexChanged\", set)\n * return () => manager.emitter.off(\"mainViewSceneIndexChanged\", set)\n * })\n */\nexport function createValue<T>(\n value: T,\n effect: (set: (value: T) => void) => FastboardDisposer | void\n): FastboardReadable<T>;\n\n/**\n * Create a writable, reactive value.\n * @example\n * createValue(manager.getMainViewSceneIndex(), (set) => {\n * manager.emitter.on(\"mainViewSceneIndexChanged\", set)\n * return () => manager.emitter.off(\"mainViewSceneIndexChanged\", set)\n * }, (newValue) => {\n * manager.setMainViewSceneIndex(newValue)\n * })\n */\nexport function createValue<T, SetFn = (value: T) => void>(\n value: T,\n effect: (set: (value: T) => void) => FastboardDisposer | void,\n set: (value: T) => void\n): FastboardWritable<T, SetFn>;\n\nexport function createValue<T>(\n value: T,\n effect: (set: (value: T) => void) => FastboardDisposer | void,\n setValue: (value: T) => void = noop\n): FastboardInternalValue<T> {\n const emitter = new FastboardEmitter<T>();\n\n function set(newValue: T) {\n if (safe_not_equal(value, newValue)) {\n emitter.dispatch((value = newValue));\n }\n }\n\n const dispose = effect(set) || noop;\n\n function subscribe(callback: (value: T) => void) {\n emitter.addListener(callback);\n callback(value);\n return () => emitter.removeListener(callback);\n }\n\n function reaction(callback: (value: T) => void) {\n emitter.addListener(callback);\n return () => emitter.removeListener(callback);\n }\n\n return {\n get value() {\n return value;\n },\n subscribe,\n reaction,\n setValue,\n dispose,\n };\n}\n","import type { Player, PlayerCallbacks, PlayerState, ViewCallbacks, WhiteWebSdk } from \"white-web-sdk\";\nimport type { PublicEvent, WindowManager } from \"@netless/window-manager\";\nimport type { FastboardDisposer, FastboardInternalValue } from \"../helpers/value\";\n\nimport { createValue } from \"../helpers/value\";\n\nclass FastboardPlayerBase {\n public constructor(readonly sdk: WhiteWebSdk, readonly player: Player, readonly manager: WindowManager) {}\n\n protected readonly _disposers: FastboardDisposer[] = [];\n protected _destroyed = false;\n protected _assertNotDestroyed() {\n if (this._destroyed) {\n throw new Error(\"[FastboardPlayer] Can not call any method on destroyed FastboardPlayer.\");\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected createValue: typeof createValue = (...args: [any, any]): any => {\n const value = createValue(...args);\n this._disposers.push((value as FastboardInternalValue<unknown>).dispose);\n return value;\n };\n\n protected _addPlayerListener<K extends keyof PlayerCallbacks, T = PlayerCallbacks[K]>(\n name: K,\n listener: T\n ) {\n this._assertNotDestroyed();\n this.player.callbacks.on(name, listener);\n return () => this.player.callbacks.off(name, listener);\n }\n\n protected _addManagerListener<K extends keyof PublicEvent>(name: K, set: (value: PublicEvent[K]) => void) {\n this._assertNotDestroyed();\n this.manager.emitter.on(name, set);\n return () => this.manager.emitter.off(name, set);\n }\n\n protected _addMainViewListener<K extends keyof ViewCallbacks, T = ViewCallbacks[K]>(name: K, listener: T) {\n this._assertNotDestroyed();\n this.manager.mainView.callbacks.on(name, listener);\n return () => this.manager.mainView.callbacks.off(name, listener);\n }\n\n public destroy() {\n this._disposers.forEach(dispose => dispose());\n this._disposers.length = 0;\n this._destroyed = true;\n this.manager.destroy();\n this.player.callbacks.off();\n }\n}\n\nexport class FastboardPlayer extends FastboardPlayerBase {\n /**\n * Render this player to some DOM.\n */\n bindContainer(container: HTMLElement) {\n this._assertNotDestroyed();\n this.manager.bindContainer(container);\n }\n\n /**\n * Move window-manager's collector to some place.\n */\n bindCollector(container: HTMLElement) {\n this._assertNotDestroyed();\n this.manager.bindCollectorContainer(container);\n }\n\n readonly currentTime = this.createValue(\n this.player.progressTime,\n set => this._addPlayerListener(\"onProgressTimeChanged\", set),\n this.player.seekToProgressTime.bind(this.player)\n );\n\n readonly phase = this.createValue(this.player.phase, set => this._addPlayerListener(\"onPhaseChanged\", set));\n\n readonly canplay = this.createValue(this.player.isPlayable, set =>\n this._addPlayerListener(\"onIsPlayableChanged\", set)\n );\n\n private _setSpeed!: (value: number) => void;\n readonly speed = this.createValue(\n this.player.playbackSpeed,\n set => {\n this._setSpeed = set;\n },\n value => {\n this.player.playbackSpeed = value;\n this._setSpeed(value);\n }\n );\n\n readonly state = this.createValue<PlayerState | null>(null, set => {\n const update = () => set(this.player.state);\n const dispose1 = this._addPlayerListener(\"onLoadFirstFrame\", update);\n const dispose2 = this._addPlayerListener(\"onPlayerStateChanged\", update);\n return () => (dispose1(), dispose2());\n });\n\n seek(timestamp: number) {\n this._assertNotDestroyed();\n return this.player.seekToProgressTime(timestamp);\n }\n\n play() {\n this._assertNotDestroyed();\n this.player.play();\n }\n\n pause() {\n this._assertNotDestroyed();\n this.player.pause();\n }\n\n stop() {\n this._assertNotDestroyed();\n this.player.stop();\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -58,7 +58,9 @@ var __toCommonJS = /* @__PURE__ */ ((cache) => {
58
58
  // src/index.ts
59
59
  var src_exports = {};
60
60
  __export(src_exports, {
61
+ DefaultApps: () => DefaultApps,
61
62
  createFastboard: () => createFastboard,
63
+ registerApps: () => registerApps,
62
64
  replayFastboard: () => replayFastboard
63
65
  });
64
66
 
@@ -79,26 +81,43 @@ var import_window_manager5 = require("@netless/window-manager");
79
81
 
80
82
  // src/behaviors/register-apps.ts
81
83
  var import_window_manager2 = require("@netless/window-manager");
82
- import_window_manager2.WindowManager.register({
83
- kind: "Monaco",
84
- src: "https://cdn.jsdelivr.net/npm/@netless/app-monaco@latest/dist/main.iife.js"
85
- });
86
- import_window_manager2.WindowManager.register({
87
- kind: "Countdown",
88
- src: "https://cdn.jsdelivr.net/npm/@netless/app-countdown@latest/dist/main.iife.js"
89
- });
90
- import_window_manager2.WindowManager.register({
91
- kind: "GeoGebra",
92
- src: "https://cdn.jsdelivr.net/npm/@netless/app-geogebra@latest/dist/main.iife.js",
93
- appOptions: {
94
- HTML5Codebase: "https://flat-storage-cn-hz.whiteboard.agora.io/GeoGebra/HTML5/5.0/web3d"
84
+ var DefaultApps = {
85
+ Monaco: {
86
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-monaco/0.1.12/dist/main.iife.js"
87
+ },
88
+ Countdown: {
89
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-countdown/0.0.2/dist/main.iife.js"
90
+ },
91
+ GeoGebra: {
92
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-geogebra/0.0.4/dist/main.iife.js",
93
+ appOptions: {
94
+ HTML5Codebase: "https://flat-storage-cn-hz.whiteboard.agora.io/GeoGebra/HTML5/5.0/web3d"
95
+ }
96
+ },
97
+ EmbeddedPage: {
98
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-embedded-page/0.1.1/dist/main.iife.js"
99
+ },
100
+ Player: {
101
+ name: "NetlessAppMediaPlayer",
102
+ src: "https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-media-player/0.1.1/dist/main.iife.js"
95
103
  }
96
- });
104
+ };
105
+ function registerApps(config) {
106
+ for (const kind in config) {
107
+ if (Object.prototype.hasOwnProperty.call(config, kind)) {
108
+ const options = config[kind];
109
+ import_window_manager2.WindowManager.register(__spreadValues({ kind }, options));
110
+ }
111
+ }
112
+ }
97
113
 
98
114
  // src/helpers/utils.ts
99
115
  var import_window_manager3 = require("@netless/window-manager");
100
116
  function noop() {
101
117
  }
118
+ function safe_not_equal(a, b) {
119
+ return a != a ? b == b : a !== b || a && typeof a === "object" || typeof a === "function";
120
+ }
102
121
  function getImageSize(url, fallback) {
103
122
  return new Promise((resolve) => {
104
123
  const img = new Image();
@@ -181,7 +200,9 @@ var FastboardEmitter = class {
181
200
  function createValue(value, effect, setValue = noop) {
182
201
  const emitter = new FastboardEmitter();
183
202
  function set(newValue) {
184
- emitter.dispatch(value = newValue);
203
+ if (safe_not_equal(value, newValue)) {
204
+ emitter.dispatch(value = newValue);
205
+ }
185
206
  }
186
207
  const dispose = effect(set) || noop;
187
208
  function subscribe(callback) {
@@ -193,7 +214,15 @@ function createValue(value, effect, setValue = noop) {
193
214
  emitter.addListener(callback);
194
215
  return () => emitter.removeListener(callback);
195
216
  }
196
- return { value, subscribe, reaction, setValue, dispose };
217
+ return {
218
+ get value() {
219
+ return value;
220
+ },
221
+ subscribe,
222
+ reaction,
223
+ setValue,
224
+ dispose
225
+ };
197
226
  }
198
227
 
199
228
  // src/impl/app.ts
@@ -251,6 +280,14 @@ var FastboardApp = class extends FastboardAppBase {
251
280
  this.memberState = this.createValue(this.room.state.memberState, (set) => this._addRoomListener("onRoomStateChanged", ({ memberState: m }) => m && set(m)));
252
281
  this.sceneIndex = this.createValue(this.manager.mainViewSceneIndex, (set) => this._addManagerListener("mainViewSceneIndexChange", set), this.manager.setMainViewSceneIndex.bind(this.manager));
253
282
  this.sceneLength = this.createValue(this.manager.mainViewScenesLength, (set) => this._addManagerListener("mainViewScenesLengthChange", set));
283
+ this._appsStatus = {};
284
+ this.appsStatus = this.createValue({}, (set) => this._addManagerListener("loadApp", ({ kind, status, reason }) => {
285
+ this._appsStatus[kind] = {
286
+ status: status === "start" ? "loading" : status === "failed" ? "failed" : "idle",
287
+ reason
288
+ };
289
+ set(this._appsStatus);
290
+ }));
254
291
  }
255
292
  bindContainer(container) {
256
293
  this._assertNotDestroyed();
@@ -337,7 +374,6 @@ var FastboardApp = class extends FastboardAppBase {
337
374
  this._assertNotDestroyed();
338
375
  switch (fileType) {
339
376
  case "pdf":
340
- case "ppt":
341
377
  return this.manager.addApp({
342
378
  kind: "DocsViewer",
343
379
  options: { scenePath, title, scenes }
@@ -474,8 +510,10 @@ async function createFastboard(_a) {
474
510
  sdkConfig,
475
511
  joinRoom: _c
476
512
  } = _b, _d = _c, { callbacks } = _d, joinRoomParams = __objRest(_d, ["callbacks"]), {
477
- managerConfig
513
+ managerConfig,
514
+ appsConfig = DefaultApps
478
515
  } = _b;
516
+ registerApps(appsConfig);
479
517
  const sdk = new import_white_web_sdk.WhiteWebSdk(__spreadProps(__spreadValues({}, sdkConfig), {
480
518
  useMobXState: true
481
519
  }));
@@ -515,19 +553,24 @@ async function replayFastboard(_a) {
515
553
  sdkConfig,
516
554
  replayRoom: _c
517
555
  } = _b, _d = _c, { callbacks } = _d, replayRoomParams = __objRest(_d, ["callbacks"]), {
518
- managerConfig
556
+ managerConfig,
557
+ appsConfig = DefaultApps
519
558
  } = _b;
559
+ registerApps(appsConfig);
520
560
  const sdk = new import_white_web_sdk.WhiteWebSdk(__spreadProps(__spreadValues({}, sdkConfig), {
521
561
  useMobXState: true
522
562
  }));
523
563
  const player = await sdk.replayRoom(__spreadProps(__spreadValues({}, ensureWindowManager(replayRoomParams)), {
524
564
  useMultiViews: true
525
565
  }), callbacks);
526
- const manager = await import_window_manager5.WindowManager.mount(__spreadProps(__spreadValues({
566
+ const managerPromise = import_window_manager5.WindowManager.mount(__spreadProps(__spreadValues({
527
567
  cursor: true
528
568
  }, managerConfig), {
529
569
  room: player
530
570
  }));
571
+ player.play();
572
+ const manager = await managerPromise;
573
+ player.pause();
531
574
  return new FastboardPlayer(sdk, player, manager);
532
575
  }
533
576
  module.exports = __toCommonJS(src_exports);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/behaviors/register-slide.ts","../src/minimal.ts","../src/behaviors/register-apps.ts","../src/helpers/utils.ts","../src/impl/app.ts","../src/helpers/emitter.ts","../src/helpers/value.ts","../src/impl/player.ts"],"sourcesContent":["import \"./behaviors/register-slide\";\n\nexport * from \"./minimal\";\n","import { WindowManager } from \"@netless/window-manager\";\nimport AppSlide from \"@netless/app-slide\";\n\nWindowManager.register({\n kind: \"Slide\",\n appOptions: {\n // turn on to show debug controller\n debug: false,\n },\n src: AppSlide,\n});\n","import type {\n Displayer,\n HotKeys,\n JoinRoomParams,\n PlayerCallbacks,\n ReplayRoomParams,\n Room,\n RoomCallbacks,\n WhiteWebSdkConfiguration,\n} from \"white-web-sdk\";\nimport type { MountParams } from \"@netless/window-manager\";\n\nimport { contentModeScale, DefaultHotKeys, WhiteWebSdk } from \"white-web-sdk\";\nimport { WindowManager } from \"@netless/window-manager\";\n\nimport \"./behaviors/register-apps\";\nimport { ensureWindowManager } from \"./helpers/utils\";\nimport { FastboardApp } from \"./impl/app\";\nimport { FastboardPlayer } from \"./impl/player\";\n\nexport type { FastboardReadable, FastboardWritable } from \"./helpers/value\";\n\nexport type { FastboardApp };\n\nexport interface FastboardOptions {\n sdkConfig: Omit<WhiteWebSdkConfiguration, \"useMobXState\">;\n joinRoom: Omit<JoinRoomParams, \"useMultiViews\" | \"disableNewPencil\" | \"disableMagixEventDispatchLimit\"> & {\n callbacks?: Partial<RoomCallbacks>;\n };\n managerConfig?: Omit<MountParams, \"room\">;\n}\n\n/**\n * Create a FastboardApp instance.\n * @example\n * let app = await createFastboard({\n * sdkConfig: {\n * appIdentifier: import.meta.env.VITE_APPID,\n * },\n * joinRoom: {\n * uid: unique_id,\n * uuid: import.meta.env.VITE_ROOM_UUID,\n * roomToken: import.meta.env.VITE_ROOM_TOKEN,\n * },\n * })\n */\nexport async function createFastboard({\n sdkConfig,\n joinRoom: { callbacks, ...joinRoomParams },\n managerConfig,\n}: FastboardOptions) {\n const sdk = new WhiteWebSdk({\n ...sdkConfig,\n useMobXState: true,\n });\n\n const hotKeys: Partial<HotKeys> = {\n ...DefaultHotKeys,\n changeToSelector: \"s\",\n changeToLaserPointer: \"z\",\n changeToPencil: \"p\",\n changeToRectangle: \"r\",\n changeToEllipse: \"c\",\n changeToEraser: \"e\",\n changeToText: \"t\",\n changeToStraight: \"l\",\n changeToArrow: \"a\",\n changeToHand: \"h\",\n };\n\n const room = await sdk.joinRoom(\n {\n floatBar: true,\n hotKeys,\n ...ensureWindowManager(joinRoomParams),\n useMultiViews: true,\n disableNewPencil: false,\n disableMagixEventDispatchLimit: true,\n },\n callbacks\n );\n\n const manager = await WindowManager.mount({\n cursor: true,\n ...managerConfig,\n room,\n });\n\n manager.mainView.setCameraBound({\n minContentMode: contentModeScale(0.3),\n maxContentMode: contentModeScale(3),\n });\n\n return new FastboardApp(sdk, room, manager, hotKeys);\n}\n\nexport interface FastboardReplayOptions {\n sdkConfig: Omit<WhiteWebSdkConfiguration, \"useMobXState\">;\n replayRoom: Omit<ReplayRoomParams, \"useMultiViews\"> & {\n callbacks?: Partial<PlayerCallbacks>;\n };\n managerConfig?: Omit<MountParams, \"room\">;\n}\n\n/**\n * Create a FastboardPlayer instance.\n * @example\n * let app = await replayFastboard({\n * sdkConfig: {\n * appIdentifier: import.meta.env.VITE_APPID,\n * },\n * replayRoom: {\n * uid: unique_id,\n * uuid: import.meta.env.VITE_ROOM_UUID,\n * roomToken: import.meta.env.VITE_ROOM_TOKEN,\n * },\n * })\n */\nexport async function replayFastboard({\n sdkConfig,\n replayRoom: { callbacks, ...replayRoomParams },\n managerConfig,\n}: FastboardReplayOptions) {\n const sdk = new WhiteWebSdk({\n ...sdkConfig,\n useMobXState: true,\n });\n\n const player = await sdk.replayRoom(\n {\n ...ensureWindowManager(replayRoomParams),\n useMultiViews: true,\n },\n callbacks\n );\n\n const manager = await WindowManager.mount({\n cursor: true,\n ...managerConfig,\n room: player as Displayer as Room,\n });\n\n return new FastboardPlayer(sdk, player, manager);\n}\n","import { WindowManager } from \"@netless/window-manager\";\n\nWindowManager.register({\n kind: \"Monaco\",\n src: \"https://cdn.jsdelivr.net/npm/@netless/app-monaco@latest/dist/main.iife.js\",\n});\n\nWindowManager.register({\n kind: \"Countdown\",\n src: \"https://cdn.jsdelivr.net/npm/@netless/app-countdown@latest/dist/main.iife.js\",\n});\n\nWindowManager.register({\n kind: \"GeoGebra\",\n src: \"https://cdn.jsdelivr.net/npm/@netless/app-geogebra@latest/dist/main.iife.js\",\n appOptions: {\n HTML5Codebase: \"https://flat-storage-cn-hz.whiteboard.agora.io/GeoGebra/HTML5/5.0/web3d\",\n },\n});\n","import type { ConvertedFile, JoinRoomParams, ReplayRoomParams, SceneDefinition, Size } from \"white-web-sdk\";\nimport { WindowManager } from \"@netless/window-manager\";\n\nexport function noop() {\n /* noop */\n}\n\nexport function getImageSize(url: string, fallback: Size) {\n return new Promise<Size>(resolve => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => resolve(fallback);\n img.src = url;\n });\n}\n\nexport function makeSlideParams(scenes: SceneDefinition[]) {\n const emptyScenes: SceneDefinition[] = [];\n let taskId = \"\";\n let url = \"\";\n\n // e.g. \"ppt(x)://cdn/prefix/dynamicConvert/{taskId}/1.slide\"\n const pptSrcRE = /^pptx?(?<prefix>:\\/\\/\\S+?dynamicConvert)\\/(?<taskId>\\w+)\\//;\n\n for (const { name, ppt } of scenes) {\n // make sure scenesWithoutPPT.length === scenes.length\n emptyScenes.push({ name });\n\n if (!ppt || !ppt.src.startsWith(\"ppt\")) {\n continue;\n }\n const match = pptSrcRE.exec(ppt.src);\n if (!match || !match.groups) {\n continue;\n }\n taskId = match.groups.taskId;\n url = \"https\" + match.groups.prefix;\n break;\n }\n\n return { emptyScenes, taskId, url };\n}\n\nexport function convertedFileToScene(f: ConvertedFile, i: number) {\n return {\n name: String(i + 1),\n ppt: {\n src: f.conversionFileUrl,\n width: f.width,\n height: f.height,\n previewURL: f.preview,\n },\n };\n}\n\nexport function ensureWindowManager<T extends JoinRoomParams | ReplayRoomParams>(joinRoom: T): T {\n if (!joinRoom.invisiblePlugins || !joinRoom.invisiblePlugins.includes(WindowManager)) {\n joinRoom.invisiblePlugins = [...(joinRoom.invisiblePlugins || []), WindowManager];\n }\n return joinRoom;\n}\n\n// Copy from https://github.com/crimx/side-effect-manager/blob/main/src/gen-uid.ts\nconst SOUP = \"!#%()*+,-./:;=?@[]^_`{|}~\" + \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\nconst SOUP_LEN = SOUP.length;\nconst ID_LEN = 20;\nconst reusedIdCarrier = /* @__PURE__ */ Array(ID_LEN);\n\nexport function genUID() {\n for (let i = 0; i < ID_LEN; i++) {\n reusedIdCarrier[i] = SOUP.charAt(Math.random() * SOUP_LEN);\n }\n return reusedIdCarrier.join(\"\");\n}\n","import type { PublicEvent, WindowManager } from \"@netless/window-manager\";\nimport type {\n AnimationMode,\n ApplianceNames,\n Camera,\n Color,\n ConversionResponse,\n HotKeys,\n MemberState,\n Rectangle,\n Room,\n RoomCallbacks,\n RoomState,\n SceneDefinition,\n ShapeType,\n ViewCallbacks,\n WhiteWebSdk,\n} from \"white-web-sdk\";\nimport type { FastboardDisposer, FastboardInternalValue } from \"../helpers/value\";\n\nimport { BuiltinApps } from \"@netless/window-manager\";\nimport { convertedFileToScene, genUID, getImageSize, makeSlideParams } from \"../helpers/utils\";\nimport { createValue } from \"../helpers/value\";\n\nclass FastboardAppBase {\n public constructor(\n readonly sdk: WhiteWebSdk,\n readonly room: Room,\n readonly manager: WindowManager,\n readonly hotKeys: Partial<HotKeys>\n ) {}\n\n protected readonly _disposers: FastboardDisposer[] = [];\n protected _destroyed = false;\n protected _assertNotDestroyed() {\n if (this._destroyed) {\n throw new Error(\"[FastboardApp] Can not call any method on destroyed FastboardApp.\");\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected createValue: typeof createValue = (...args: [any, any]): any => {\n const value = createValue(...args);\n this._disposers.push((value as FastboardInternalValue<unknown>).dispose);\n return value;\n };\n\n protected _addRoomListener<K extends keyof RoomCallbacks, T = RoomCallbacks[K]>(name: K, listener: T) {\n this._assertNotDestroyed();\n this.room.callbacks.on(name, listener);\n return () => this.room.callbacks.off(name, listener);\n }\n\n protected _addManagerListener<K extends keyof PublicEvent>(name: K, set: (value: PublicEvent[K]) => void) {\n this._assertNotDestroyed();\n this.manager.emitter.on(name, set);\n return () => this.manager.emitter.off(name, set);\n }\n\n protected _addMainViewListener<K extends keyof ViewCallbacks, T = ViewCallbacks[K]>(name: K, listener: T) {\n this._assertNotDestroyed();\n this.manager.mainView.callbacks.on(name, listener);\n return () => this.manager.mainView.callbacks.off(name, listener);\n }\n\n public destroy() {\n this._disposers.forEach(dispose => dispose());\n this._disposers.length = 0;\n this._destroyed = true;\n this.manager.destroy();\n return this.room.disconnect();\n }\n}\n\nexport interface InsertDocsStatic {\n readonly fileType: \"pdf\" | \"ppt\";\n readonly scenePath: string;\n readonly scenes: SceneDefinition[];\n readonly title?: string;\n}\n\nexport interface InsertDocsDynamic {\n readonly fileType: \"pptx\";\n readonly scenePath: string;\n readonly taskId: string;\n readonly title?: string;\n readonly url?: string;\n /** @example [{ name: '1' }, { name: '2' }, { name: '3' }] */\n readonly scenes?: SceneDefinition[];\n}\n\nexport type InsertDocsParams = InsertDocsStatic | InsertDocsDynamic;\n\nexport type SetMemberStateFn = (partialMemberState: Partial<MemberState>) => void;\n\nexport type RoomStateChanged = (diff: Partial<RoomState>) => void;\n\nexport class FastboardApp extends FastboardAppBase {\n /**\n * Render this app to some DOM.\n */\n bindContainer(container: HTMLElement) {\n this._assertNotDestroyed();\n this.manager.bindContainer(container);\n }\n\n /**\n * Move window-manager's collector to some place.\n */\n bindCollector(container: HTMLElement) {\n this._assertNotDestroyed();\n this.manager.bindCollectorContainer(container);\n }\n\n /**\n * Is current room writable?\n */\n readonly writable = this.createValue(\n this.room.isWritable,\n set => this._addRoomListener(\"onEnableWriteNowChanged\", () => set(this.room.isWritable)),\n this.room.setWritable.bind(this.room)\n );\n\n /**\n * Current window-manager's windows' state (is it maximized?).\n */\n readonly boxState = this.createValue(this.manager.boxState, set =>\n this._addManagerListener(\"boxStateChange\", set)\n );\n\n /**\n * Current window-manager's focused app's id.\n * @example \"HelloWorld-1A2b3C4d\"\n */\n readonly focusedApp = this.createValue(this.manager.focused, set =>\n this._addManagerListener(\"focusedChange\", set)\n );\n\n /**\n * How many times can I call `app.redo()`?\n */\n readonly canRedoSteps = this.createValue(this.manager.canRedoSteps, set =>\n this._addManagerListener(\"canRedoStepsChange\", set)\n );\n\n /**\n * How many times can I call `app.undo()`?\n */\n readonly canUndoSteps = this.createValue(this.manager.canUndoSteps, set =>\n this._addManagerListener(\"canUndoStepsChange\", set)\n );\n\n /**\n * Current camera information of main view.\n */\n readonly camera = this.createValue(this.manager.mainView.camera, set =>\n this._addMainViewListener(\"onCameraUpdated\", set)\n );\n\n /**\n * Current tool's info, like \"is using pencil?\", \"what color?\".\n */\n readonly memberState = this.createValue(this.room.state.memberState, set =>\n this._addRoomListener(\"onRoomStateChanged\", ({ memberState: m }) => m && set(m))\n );\n\n /**\n * 0..n-1, current index of main view scenes.\n */\n readonly sceneIndex = this.createValue(\n this.manager.mainViewSceneIndex,\n set => this._addManagerListener(\"mainViewSceneIndexChange\", set),\n this.manager.setMainViewSceneIndex.bind(this.manager)\n );\n\n /**\n * How many pages are in the main view?\n */\n readonly sceneLength = this.createValue(this.manager.mainViewScenesLength, set =>\n this._addManagerListener(\"mainViewScenesLengthChange\", set)\n );\n\n /**\n * Undo a step on main view.\n */\n undo() {\n this._assertNotDestroyed();\n this.manager.mainView.undo();\n }\n\n /**\n * Redo a step on main view.\n */\n redo() {\n this._assertNotDestroyed();\n this.manager.mainView.redo();\n }\n\n /**\n * Move current main view's camera position.\n */\n moveCamera(camera: Partial<Camera> & { animationMode?: AnimationMode | undefined }) {\n this._assertNotDestroyed();\n this.manager.moveCamera(camera);\n }\n\n /**\n * Move current main view's camera to include a rectangle.\n */\n moveCameraToContain(rectangle: Rectangle & { animationMode?: AnimationMode }) {\n this._assertNotDestroyed();\n this.manager.moveCameraToContain(rectangle);\n }\n\n /**\n * Delete all things on the main view.\n */\n cleanCurrentScene() {\n this._assertNotDestroyed();\n this.manager.cleanCurrentScene();\n }\n\n /**\n * Set current tool, like \"pencil\".\n */\n setAppliance(appliance: ApplianceNames, shape?: ShapeType) {\n this._assertNotDestroyed();\n this.manager.mainView.setMemberState({ currentApplianceName: appliance, shapeType: shape });\n }\n\n setStrokeWidth(strokeWidth: number) {\n this._assertNotDestroyed();\n this.manager.mainView.setMemberState({ strokeWidth });\n }\n\n setStrokeColor(strokeColor: Color) {\n this._assertNotDestroyed();\n this.manager.mainView.setMemberState({ strokeColor });\n }\n\n /**\n * Insert an image to the main view.\n */\n async insertImage(url: string) {\n this._assertNotDestroyed();\n await this.manager.switchMainViewToWriter();\n\n const { divElement } = this.manager.mainView;\n const containerSize = {\n width: divElement?.scrollWidth || window.innerWidth,\n height: divElement?.scrollHeight || window.innerHeight,\n };\n\n // 1. shrink the image a little to fit container **width**\n const maxWidth = containerSize.width * 0.8;\n let { width, height } = await getImageSize(url, containerSize);\n const scale = Math.min(maxWidth / width, 1);\n const uuid = genUID();\n const { centerX, centerY } = this.manager.camera;\n width *= scale;\n height *= scale;\n this.manager.mainView.insertImage({ uuid, centerX, centerY, width, height, locked: false });\n this.manager.mainView.completeImageUpload(uuid, url);\n\n // 2. move camera to fit image **height**\n width /= 0.8;\n height /= 0.8;\n const originX = centerX - width / 2;\n const originY = centerY - height / 2;\n this.manager.moveCameraToContain({ originX, originY, width, height });\n }\n\n /**\n * Insert PDF/PPTX from conversion result.\n * @param status https://developer.netless.link/server-en/home/server-conversion#get-query-task-conversion-progress\n */\n insertDocs(filename: string, status: ConversionResponse): Promise<string | undefined>;\n\n /**\n * Manual way.\n * @example\n * app.insertDocs({\n * fileType: 'pptx',\n * scenePath: `/pptx/${conversion.taskId}`,\n * taskId: conversion.taskId,\n * title: 'Title',\n * })\n */\n insertDocs(params: InsertDocsParams): Promise<string | undefined>;\n\n insertDocs(arg1: string | InsertDocsParams, arg2?: ConversionResponse) {\n if (typeof arg1 === \"object\" && \"fileType\" in arg1) {\n return this._insertDocsImpl(arg1);\n } else if (arg2 && arg2.status !== \"Finished\") {\n throw new Error(\"[FastboardApp] Can not insert a converting doc.\");\n } else if (arg2 && arg2.progress) {\n const scenes: SceneDefinition[] = arg2.progress.convertedFileList.map(convertedFileToScene);\n const scenePath = `/${arg2.uuid}/${genUID()}`;\n const { emptyScenes, taskId, url } = makeSlideParams(scenes);\n if (taskId && url) {\n const title = arg1;\n return this._insertDocsImpl({ fileType: \"pptx\", scenePath, taskId, title, url, scenes: emptyScenes });\n } else {\n return this._insertDocsImpl({ fileType: \"pdf\", scenePath, scenes, title: arg1 });\n }\n }\n }\n\n private _insertDocsImpl({ fileType, scenePath, title, scenes, ...attributes }: InsertDocsParams) {\n this._assertNotDestroyed();\n switch (fileType) {\n case \"pdf\":\n case \"ppt\":\n return this.manager.addApp({\n kind: \"DocsViewer\",\n options: { scenePath, title, scenes },\n });\n case \"pptx\":\n return this.manager.addApp({\n kind: \"Slide\",\n options: { scenePath, title, scenes },\n attributes,\n });\n }\n }\n\n /**\n * Insert the Monaco Code Editor app.\n */\n insertCodeEditor() {\n this._assertNotDestroyed();\n return this.manager.addApp({\n kind: \"Monaco\",\n options: { title: \"Code Editor\" },\n });\n }\n\n /**\n * Insert the Countdown app.\n */\n insertCountdown() {\n this._assertNotDestroyed();\n return this.manager.addApp({\n kind: \"Countdown\",\n options: { title: \"Countdown\" },\n });\n }\n\n /**\n * Insert the Media Player app.\n */\n insertMedia(title: string, src: string) {\n this._assertNotDestroyed();\n return this.manager.addApp({\n kind: BuiltinApps.MediaPlayer,\n options: { title },\n attributes: { src },\n });\n }\n\n /**\n * Insert the GeoGebra app.\n */\n insertGeoGebra() {\n this._assertNotDestroyed();\n return this.manager.addApp({\n kind: \"GeoGebra\",\n options: { title: \"GeoGebra\" },\n });\n }\n}\n","export type FastboardListener<T> = (event: T) => void;\n\nexport class FastboardEmitter<T> {\n listeners = new Set<FastboardListener<T>>();\n\n get length(): number {\n return this.listeners.size;\n }\n\n dispatch(message: T) {\n this.listeners.forEach(callback => callback(message));\n }\n\n addListener(listener: FastboardListener<T>) {\n this.listeners.add(listener);\n }\n\n removeListener(listener: FastboardListener<T>) {\n this.listeners.delete(listener);\n }\n}\n","import { FastboardEmitter } from \"./emitter\";\nimport { noop } from \"./utils\";\n\nexport type FastboardDisposer = () => void;\n\nexport interface FastboardReadable<T> {\n readonly value: T;\n subscribe(callback: (value: T) => void): FastboardDisposer;\n reaction(callback: (value: T) => void): FastboardDisposer;\n}\n\nexport interface FastboardWritable<T, SetFn = (value: T) => void> extends FastboardReadable<T> {\n setValue: SetFn;\n}\n\nexport interface FastboardInternalValue<T> extends FastboardWritable<T> {\n dispose: FastboardDisposer;\n}\n\n/**\n * Create a readonly, reactive value.\n * @example\n * createValue(manager.getMainViewSceneIndex(), (set) => {\n * manager.emitter.on(\"mainViewSceneIndexChanged\", set)\n * return () => manager.emitter.off(\"mainViewSceneIndexChanged\", set)\n * })\n */\nexport function createValue<T>(\n value: T,\n effect: (set: (value: T) => void) => FastboardDisposer | void\n): FastboardReadable<T>;\n\n/**\n * Create a writable, reactive value.\n * @example\n * createValue(manager.getMainViewSceneIndex(), (set) => {\n * manager.emitter.on(\"mainViewSceneIndexChanged\", set)\n * return () => manager.emitter.off(\"mainViewSceneIndexChanged\", set)\n * }, (newValue) => {\n * manager.setMainViewSceneIndex(newValue)\n * })\n */\nexport function createValue<T, SetFn = (value: T) => void>(\n value: T,\n effect: (set: (value: T) => void) => FastboardDisposer | void,\n set: (value: T) => void\n): FastboardWritable<T, SetFn>;\n\nexport function createValue<T>(\n value: T,\n effect: (set: (value: T) => void) => FastboardDisposer | void,\n setValue: (value: T) => void = noop\n): FastboardInternalValue<T> {\n const emitter = new FastboardEmitter<T>();\n\n function set(newValue: T) {\n emitter.dispatch((value = newValue));\n }\n\n const dispose = effect(set) || noop;\n\n function subscribe(callback: (value: T) => void) {\n emitter.addListener(callback);\n callback(value);\n return () => emitter.removeListener(callback);\n }\n\n function reaction(callback: (value: T) => void) {\n emitter.addListener(callback);\n return () => emitter.removeListener(callback);\n }\n\n return { value, subscribe, reaction, setValue, dispose };\n}\n","import type { Player, PlayerCallbacks, PlayerState, ViewCallbacks, WhiteWebSdk } from \"white-web-sdk\";\nimport type { PublicEvent, WindowManager } from \"@netless/window-manager\";\nimport type { FastboardDisposer, FastboardInternalValue } from \"../helpers/value\";\n\nimport { createValue } from \"../helpers/value\";\n\nclass FastboardPlayerBase {\n public constructor(readonly sdk: WhiteWebSdk, readonly player: Player, readonly manager: WindowManager) {}\n\n protected readonly _disposers: FastboardDisposer[] = [];\n protected _destroyed = false;\n protected _assertNotDestroyed() {\n if (this._destroyed) {\n throw new Error(\"[FastboardPlayer] Can not call any method on destroyed FastboardPlayer.\");\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected createValue: typeof createValue = (...args: [any, any]): any => {\n const value = createValue(...args);\n this._disposers.push((value as FastboardInternalValue<unknown>).dispose);\n return value;\n };\n\n protected _addPlayerListener<K extends keyof PlayerCallbacks, T = PlayerCallbacks[K]>(\n name: K,\n listener: T\n ) {\n this._assertNotDestroyed();\n this.player.callbacks.on(name, listener);\n return () => this.player.callbacks.off(name, listener);\n }\n\n protected _addManagerListener<K extends keyof PublicEvent>(name: K, set: (value: PublicEvent[K]) => void) {\n this._assertNotDestroyed();\n this.manager.emitter.on(name, set);\n return () => this.manager.emitter.off(name, set);\n }\n\n protected _addMainViewListener<K extends keyof ViewCallbacks, T = ViewCallbacks[K]>(name: K, listener: T) {\n this._assertNotDestroyed();\n this.manager.mainView.callbacks.on(name, listener);\n return () => this.manager.mainView.callbacks.off(name, listener);\n }\n\n public destroy() {\n this._disposers.forEach(dispose => dispose());\n this._disposers.length = 0;\n this._destroyed = true;\n this.manager.destroy();\n this.player.callbacks.off();\n }\n}\n\nexport class FastboardPlayer extends FastboardPlayerBase {\n /**\n * Render this player to some DOM.\n */\n bindContainer(container: HTMLElement) {\n this._assertNotDestroyed();\n this.manager.bindContainer(container);\n }\n\n /**\n * Move window-manager's collector to some place.\n */\n bindCollector(container: HTMLElement) {\n this._assertNotDestroyed();\n this.manager.bindCollectorContainer(container);\n }\n\n readonly currentTime = this.createValue(\n this.player.progressTime,\n set => this._addPlayerListener(\"onProgressTimeChanged\", set),\n this.player.seekToProgressTime.bind(this.player)\n );\n\n readonly phase = this.createValue(this.player.phase, set => this._addPlayerListener(\"onPhaseChanged\", set));\n\n readonly canplay = this.createValue(this.player.isPlayable, set =>\n this._addPlayerListener(\"onIsPlayableChanged\", set)\n );\n\n private _setSpeed!: (value: number) => void;\n readonly speed = this.createValue(\n this.player.playbackSpeed,\n set => {\n this._setSpeed = set;\n },\n value => {\n this.player.playbackSpeed = value;\n this._setSpeed(value);\n }\n );\n\n readonly state = this.createValue<PlayerState | null>(null, set => {\n const update = () => set(this.player.state);\n const dispose1 = this._addPlayerListener(\"onLoadFirstFrame\", update);\n const dispose2 = this._addPlayerListener(\"onPlayerStateChanged\", update);\n return () => (dispose1(), dispose2());\n });\n\n seek(timestamp: number) {\n this._assertNotDestroyed();\n return this.player.seekToProgressTime(timestamp);\n }\n\n play() {\n this._assertNotDestroyed();\n this.player.play();\n }\n\n pause() {\n this._assertNotDestroyed();\n this.player.pause();\n }\n\n stop() {\n this._assertNotDestroyed();\n this.player.stop();\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/behaviors/register-slide.ts","../src/minimal.ts","../src/behaviors/register-apps.ts","../src/helpers/utils.ts","../src/impl/app.ts","../src/helpers/emitter.ts","../src/helpers/value.ts","../src/impl/player.ts"],"sourcesContent":["import \"./behaviors/register-slide\";\n\nexport * from \"./minimal\";\n","import { WindowManager } from \"@netless/window-manager\";\nimport AppSlide from \"@netless/app-slide\";\n\nWindowManager.register({\n kind: \"Slide\",\n appOptions: {\n // turn on to show debug controller\n debug: false,\n },\n src: AppSlide,\n});\n","import type {\n Displayer,\n HotKeys,\n JoinRoomParams,\n PlayerCallbacks,\n ReplayRoomParams,\n Room,\n RoomCallbacks,\n WhiteWebSdkConfiguration,\n} from \"white-web-sdk\";\nimport type { MountParams } from \"@netless/window-manager\";\n\nimport { contentModeScale, DefaultHotKeys, WhiteWebSdk } from \"white-web-sdk\";\nimport { WindowManager } from \"@netless/window-manager\";\n\nimport type { AppsConfig } from \"./behaviors/register-apps\";\n\nimport { DefaultApps, registerApps } from \"./behaviors/register-apps\";\nimport { ensureWindowManager } from \"./helpers/utils\";\nimport { FastboardApp } from \"./impl/app\";\nimport { FastboardPlayer } from \"./impl/player\";\n\nexport type { FastboardReadable, FastboardWritable } from \"./helpers/value\";\n\nexport type { AppsStatus, InsertDocsDynamic, InsertDocsParams, InsertDocsStatic } from \"./impl/app\";\n\nexport type { AppsConfig, FastboardApp, FastboardPlayer };\nexport { DefaultApps, registerApps };\n\nexport interface FastboardOptions {\n sdkConfig: Omit<WhiteWebSdkConfiguration, \"useMobXState\"> & { region: string };\n joinRoom: Omit<JoinRoomParams, \"useMultiViews\" | \"disableNewPencil\" | \"disableMagixEventDispatchLimit\"> & {\n callbacks?: Partial<RoomCallbacks>;\n };\n managerConfig?: Omit<MountParams, \"room\">;\n appsConfig?: AppsConfig;\n}\n\n/**\n * Create a FastboardApp instance.\n * @example\n * let app = await createFastboard({\n * sdkConfig: {\n * appIdentifier: import.meta.env.VITE_APPID,\n * region: \"ch-hz\",\n * },\n * joinRoom: {\n * uid: unique_id,\n * uuid: import.meta.env.VITE_ROOM_UUID,\n * roomToken: import.meta.env.VITE_ROOM_TOKEN,\n * },\n * })\n */\nexport async function createFastboard({\n sdkConfig,\n joinRoom: { callbacks, ...joinRoomParams },\n managerConfig,\n appsConfig = DefaultApps,\n}: FastboardOptions) {\n registerApps(appsConfig);\n\n const sdk = new WhiteWebSdk({\n ...sdkConfig,\n useMobXState: true,\n });\n\n const hotKeys: Partial<HotKeys> = {\n ...DefaultHotKeys,\n changeToSelector: \"s\",\n changeToLaserPointer: \"z\",\n changeToPencil: \"p\",\n changeToRectangle: \"r\",\n changeToEllipse: \"c\",\n changeToEraser: \"e\",\n changeToText: \"t\",\n changeToStraight: \"l\",\n changeToArrow: \"a\",\n changeToHand: \"h\",\n };\n\n const room = await sdk.joinRoom(\n {\n floatBar: true,\n hotKeys,\n ...ensureWindowManager(joinRoomParams),\n useMultiViews: true,\n disableNewPencil: false,\n disableMagixEventDispatchLimit: true,\n },\n callbacks\n );\n\n const manager = await WindowManager.mount({\n cursor: true,\n ...managerConfig,\n room,\n });\n\n manager.mainView.setCameraBound({\n minContentMode: contentModeScale(0.3),\n maxContentMode: contentModeScale(3),\n });\n\n return new FastboardApp(sdk, room, manager, hotKeys);\n}\n\nexport interface FastboardReplayOptions {\n sdkConfig: Omit<WhiteWebSdkConfiguration, \"useMobXState\"> & { region: string };\n replayRoom: Omit<ReplayRoomParams, \"useMultiViews\"> & {\n callbacks?: Partial<PlayerCallbacks>;\n };\n managerConfig?: Omit<MountParams, \"room\">;\n appsConfig?: AppsConfig;\n}\n\n/**\n * Create a FastboardPlayer instance.\n * @example\n * let app = await replayFastboard({\n * sdkConfig: {\n * appIdentifier: import.meta.env.VITE_APPID,\n * region: \"ch-hz\",\n * },\n * replayRoom: {\n * uid: unique_id,\n * uuid: import.meta.env.VITE_ROOM_UUID,\n * roomToken: import.meta.env.VITE_ROOM_TOKEN,\n * },\n * })\n */\nexport async function replayFastboard({\n sdkConfig,\n replayRoom: { callbacks, ...replayRoomParams },\n managerConfig,\n appsConfig = DefaultApps,\n}: FastboardReplayOptions) {\n registerApps(appsConfig);\n\n const sdk = new WhiteWebSdk({\n ...sdkConfig,\n useMobXState: true,\n });\n\n const player = await sdk.replayRoom(\n {\n ...ensureWindowManager(replayRoomParams),\n useMultiViews: true,\n },\n callbacks\n );\n\n const managerPromise = WindowManager.mount({\n cursor: true,\n ...managerConfig,\n room: player as Displayer as Room,\n });\n\n player.play();\n const manager = await managerPromise;\n player.pause();\n\n return new FastboardPlayer(sdk, player, manager);\n}\n","import type { RegisterParams } from \"@netless/window-manager\";\nimport { WindowManager } from \"@netless/window-manager\";\n\nexport interface AppsConfig {\n [kind: string]: Omit<RegisterParams, \"kind\">;\n}\n\nexport const DefaultApps: AppsConfig = {\n Monaco: {\n src: \"https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-monaco/0.1.12/dist/main.iife.js\",\n },\n Countdown: {\n src: \"https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-countdown/0.0.2/dist/main.iife.js\",\n },\n GeoGebra: {\n src: \"https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-geogebra/0.0.4/dist/main.iife.js\",\n appOptions: {\n HTML5Codebase: \"https://flat-storage-cn-hz.whiteboard.agora.io/GeoGebra/HTML5/5.0/web3d\",\n },\n },\n EmbeddedPage: {\n src: \"https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-embedded-page/0.1.1/dist/main.iife.js\",\n },\n Player: {\n name: \"NetlessAppMediaPlayer\",\n src: \"https://netless-app.oss-cn-hangzhou.aliyuncs.com/@netless/app-media-player/0.1.1/dist/main.iife.js\",\n },\n};\n\nexport function registerApps(config: AppsConfig) {\n for (const kind in config) {\n if (Object.prototype.hasOwnProperty.call(config, kind)) {\n const options = config[kind];\n WindowManager.register({ kind, ...options });\n }\n }\n}\n","import type { ConvertedFile, JoinRoomParams, ReplayRoomParams, SceneDefinition, Size } from \"white-web-sdk\";\nimport { WindowManager } from \"@netless/window-manager\";\n\nexport function noop() {\n /* noop */\n}\n\nexport function safe_not_equal(a: unknown, b: unknown) {\n return a != a ? b == b : a !== b || (a && typeof a === \"object\") || typeof a === \"function\";\n}\n\nexport function getImageSize(url: string, fallback: Size) {\n return new Promise<Size>(resolve => {\n const img = new Image();\n img.onload = () => resolve(img);\n img.onerror = () => resolve(fallback);\n img.src = url;\n });\n}\n\nexport function makeSlideParams(scenes: SceneDefinition[]) {\n const emptyScenes: SceneDefinition[] = [];\n let taskId = \"\";\n let url = \"\";\n\n // e.g. \"ppt(x)://cdn/prefix/dynamicConvert/{taskId}/1.slide\"\n const pptSrcRE = /^pptx?(?<prefix>:\\/\\/\\S+?dynamicConvert)\\/(?<taskId>\\w+)\\//;\n\n for (const { name, ppt } of scenes) {\n // make sure scenesWithoutPPT.length === scenes.length\n emptyScenes.push({ name });\n\n if (!ppt || !ppt.src.startsWith(\"ppt\")) {\n continue;\n }\n const match = pptSrcRE.exec(ppt.src);\n if (!match || !match.groups) {\n continue;\n }\n taskId = match.groups.taskId;\n url = \"https\" + match.groups.prefix;\n break;\n }\n\n return { emptyScenes, taskId, url };\n}\n\nexport function convertedFileToScene(f: ConvertedFile, i: number) {\n return {\n name: String(i + 1),\n ppt: {\n src: f.conversionFileUrl,\n width: f.width,\n height: f.height,\n previewURL: f.preview,\n },\n };\n}\n\nexport function ensureWindowManager<T extends JoinRoomParams | ReplayRoomParams>(joinRoom: T): T {\n if (!joinRoom.invisiblePlugins || !joinRoom.invisiblePlugins.includes(WindowManager)) {\n joinRoom.invisiblePlugins = [...(joinRoom.invisiblePlugins || []), WindowManager];\n }\n return joinRoom;\n}\n\n// Copy from https://github.com/crimx/side-effect-manager/blob/main/src/gen-uid.ts\nconst SOUP = \"!#%()*+,-./:;=?@[]^_`{|}~\" + \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\nconst SOUP_LEN = SOUP.length;\nconst ID_LEN = 20;\nconst reusedIdCarrier = /* @__PURE__ */ Array(ID_LEN);\n\nexport function genUID() {\n for (let i = 0; i < ID_LEN; i++) {\n reusedIdCarrier[i] = SOUP.charAt(Math.random() * SOUP_LEN);\n }\n return reusedIdCarrier.join(\"\");\n}\n","import type { PublicEvent, WindowManager } from \"@netless/window-manager\";\nimport type {\n AnimationMode,\n ApplianceNames,\n Camera,\n Color,\n ConversionResponse,\n HotKeys,\n MemberState,\n Rectangle,\n Room,\n RoomCallbacks,\n RoomState,\n SceneDefinition,\n ShapeType,\n ViewCallbacks,\n WhiteWebSdk,\n} from \"white-web-sdk\";\nimport type { FastboardDisposer, FastboardInternalValue } from \"../helpers/value\";\n\nimport { BuiltinApps } from \"@netless/window-manager\";\nimport { convertedFileToScene, genUID, getImageSize, makeSlideParams } from \"../helpers/utils\";\nimport { createValue } from \"../helpers/value\";\n\nclass FastboardAppBase {\n public constructor(\n readonly sdk: WhiteWebSdk,\n readonly room: Room,\n readonly manager: WindowManager,\n readonly hotKeys: Partial<HotKeys>\n ) {}\n\n protected readonly _disposers: FastboardDisposer[] = [];\n protected _destroyed = false;\n protected _assertNotDestroyed() {\n if (this._destroyed) {\n throw new Error(\"[FastboardApp] Can not call any method on destroyed FastboardApp.\");\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected createValue: typeof createValue = (...args: [any, any]): any => {\n const value = createValue(...args);\n this._disposers.push((value as FastboardInternalValue<unknown>).dispose);\n return value;\n };\n\n protected _addRoomListener<K extends keyof RoomCallbacks, T = RoomCallbacks[K]>(name: K, listener: T) {\n this._assertNotDestroyed();\n this.room.callbacks.on(name, listener);\n return () => this.room.callbacks.off(name, listener);\n }\n\n protected _addManagerListener<K extends keyof PublicEvent>(name: K, set: (value: PublicEvent[K]) => void) {\n this._assertNotDestroyed();\n this.manager.emitter.on(name, set);\n return () => this.manager.emitter.off(name, set);\n }\n\n protected _addMainViewListener<K extends keyof ViewCallbacks, T = ViewCallbacks[K]>(name: K, listener: T) {\n this._assertNotDestroyed();\n this.manager.mainView.callbacks.on(name, listener);\n return () => this.manager.mainView.callbacks.off(name, listener);\n }\n\n public destroy() {\n this._disposers.forEach(dispose => dispose());\n this._disposers.length = 0;\n this._destroyed = true;\n this.manager.destroy();\n return this.room.disconnect();\n }\n}\n\nexport interface InsertDocsStatic {\n readonly fileType: \"pdf\";\n readonly scenePath: string;\n readonly scenes: SceneDefinition[];\n readonly title?: string;\n}\n\nexport interface InsertDocsDynamic {\n readonly fileType: \"pptx\";\n readonly scenePath: string;\n readonly taskId: string;\n readonly title?: string;\n readonly url?: string;\n /** @example [{ name: '1' }, { name: '2' }, { name: '3' }] */\n readonly scenes?: SceneDefinition[];\n}\n\nexport type InsertDocsParams = InsertDocsStatic | InsertDocsDynamic;\n\nexport type SetMemberStateFn = (partialMemberState: Partial<MemberState>) => void;\n\nexport type RoomStateChanged = (diff: Partial<RoomState>) => void;\n\nexport interface AppsStatus {\n [kind: string]: {\n status: \"idle\" | \"loading\" | \"failed\";\n reason?: string;\n };\n}\n\nexport class FastboardApp extends FastboardAppBase {\n /**\n * Render this app to some DOM.\n */\n bindContainer(container: HTMLElement) {\n this._assertNotDestroyed();\n this.manager.bindContainer(container);\n }\n\n /**\n * Move window-manager's collector to some place.\n */\n bindCollector(container: HTMLElement) {\n this._assertNotDestroyed();\n this.manager.bindCollectorContainer(container);\n }\n\n /**\n * Is current room writable?\n */\n readonly writable = this.createValue(\n this.room.isWritable,\n set => this._addRoomListener(\"onEnableWriteNowChanged\", () => set(this.room.isWritable)),\n this.room.setWritable.bind(this.room)\n );\n\n /**\n * Current window-manager's windows' state (is it maximized?).\n */\n readonly boxState = this.createValue(this.manager.boxState, set =>\n this._addManagerListener(\"boxStateChange\", set)\n );\n\n /**\n * Current window-manager's focused app's id.\n * @example \"HelloWorld-1A2b3C4d\"\n */\n readonly focusedApp = this.createValue(this.manager.focused, set =>\n this._addManagerListener(\"focusedChange\", set)\n );\n\n /**\n * How many times can I call `app.redo()`?\n */\n readonly canRedoSteps = this.createValue(this.manager.canRedoSteps, set =>\n this._addManagerListener(\"canRedoStepsChange\", set)\n );\n\n /**\n * How many times can I call `app.undo()`?\n */\n readonly canUndoSteps = this.createValue(this.manager.canUndoSteps, set =>\n this._addManagerListener(\"canUndoStepsChange\", set)\n );\n\n /**\n * Current camera information of main view.\n */\n readonly camera = this.createValue(this.manager.mainView.camera, set =>\n this._addMainViewListener(\"onCameraUpdated\", set)\n );\n\n /**\n * Current tool's info, like \"is using pencil?\", \"what color?\".\n */\n readonly memberState = this.createValue(this.room.state.memberState, set =>\n this._addRoomListener(\"onRoomStateChanged\", ({ memberState: m }) => m && set(m))\n );\n\n /**\n * 0..n-1, current index of main view scenes.\n */\n readonly sceneIndex = this.createValue(\n this.manager.mainViewSceneIndex,\n set => this._addManagerListener(\"mainViewSceneIndexChange\", set),\n this.manager.setMainViewSceneIndex.bind(this.manager)\n );\n\n /**\n * How many pages are in the main view?\n */\n readonly sceneLength = this.createValue(this.manager.mainViewScenesLength, set =>\n this._addManagerListener(\"mainViewScenesLengthChange\", set)\n );\n\n private _appsStatus: AppsStatus = {};\n /**\n * Apps status.\n */\n readonly appsStatus = this.createValue<AppsStatus>({}, set =>\n this._addManagerListener(\"loadApp\", ({ kind, status, reason }) => {\n this._appsStatus[kind] = {\n status: status === \"start\" ? \"loading\" : status === \"failed\" ? \"failed\" : \"idle\",\n reason,\n };\n set(this._appsStatus);\n })\n );\n\n /**\n * Undo a step on main view.\n */\n undo() {\n this._assertNotDestroyed();\n this.manager.mainView.undo();\n }\n\n /**\n * Redo a step on main view.\n */\n redo() {\n this._assertNotDestroyed();\n this.manager.mainView.redo();\n }\n\n /**\n * Move current main view's camera position.\n */\n moveCamera(camera: Partial<Camera> & { animationMode?: AnimationMode | undefined }) {\n this._assertNotDestroyed();\n this.manager.moveCamera(camera);\n }\n\n /**\n * Move current main view's camera to include a rectangle.\n */\n moveCameraToContain(rectangle: Rectangle & { animationMode?: AnimationMode }) {\n this._assertNotDestroyed();\n this.manager.moveCameraToContain(rectangle);\n }\n\n /**\n * Delete all things on the main view.\n */\n cleanCurrentScene() {\n this._assertNotDestroyed();\n this.manager.cleanCurrentScene();\n }\n\n /**\n * Set current tool, like \"pencil\".\n */\n setAppliance(appliance: ApplianceNames, shape?: ShapeType) {\n this._assertNotDestroyed();\n this.manager.mainView.setMemberState({ currentApplianceName: appliance, shapeType: shape });\n }\n\n setStrokeWidth(strokeWidth: number) {\n this._assertNotDestroyed();\n this.manager.mainView.setMemberState({ strokeWidth });\n }\n\n setStrokeColor(strokeColor: Color) {\n this._assertNotDestroyed();\n this.manager.mainView.setMemberState({ strokeColor });\n }\n\n /**\n * Insert an image to the main view.\n */\n async insertImage(url: string) {\n this._assertNotDestroyed();\n await this.manager.switchMainViewToWriter();\n\n const { divElement } = this.manager.mainView;\n const containerSize = {\n width: divElement?.scrollWidth || window.innerWidth,\n height: divElement?.scrollHeight || window.innerHeight,\n };\n\n // 1. shrink the image a little to fit container **width**\n const maxWidth = containerSize.width * 0.8;\n let { width, height } = await getImageSize(url, containerSize);\n const scale = Math.min(maxWidth / width, 1);\n const uuid = genUID();\n const { centerX, centerY } = this.manager.camera;\n width *= scale;\n height *= scale;\n this.manager.mainView.insertImage({ uuid, centerX, centerY, width, height, locked: false });\n this.manager.mainView.completeImageUpload(uuid, url);\n\n // 2. move camera to fit image **height**\n width /= 0.8;\n height /= 0.8;\n const originX = centerX - width / 2;\n const originY = centerY - height / 2;\n this.manager.moveCameraToContain({ originX, originY, width, height });\n }\n\n /**\n * Insert PDF/PPTX from conversion result.\n * @param status https://developer.netless.link/server-en/home/server-conversion#get-query-task-conversion-progress\n */\n insertDocs(filename: string, status: ConversionResponse): Promise<string | undefined>;\n\n /**\n * Manual way.\n * @example\n * app.insertDocs({\n * fileType: 'pptx',\n * scenePath: `/pptx/${conversion.taskId}`,\n * taskId: conversion.taskId,\n * title: 'Title',\n * })\n */\n insertDocs(params: InsertDocsParams): Promise<string | undefined>;\n\n insertDocs(arg1: string | InsertDocsParams, arg2?: ConversionResponse) {\n if (typeof arg1 === \"object\" && \"fileType\" in arg1) {\n return this._insertDocsImpl(arg1);\n } else if (arg2 && arg2.status !== \"Finished\") {\n throw new Error(\"[FastboardApp] Can not insert a converting doc.\");\n } else if (arg2 && arg2.progress) {\n const scenes: SceneDefinition[] = arg2.progress.convertedFileList.map(convertedFileToScene);\n const scenePath = `/${arg2.uuid}/${genUID()}`;\n const { emptyScenes, taskId, url } = makeSlideParams(scenes);\n if (taskId && url) {\n const title = arg1;\n return this._insertDocsImpl({ fileType: \"pptx\", scenePath, taskId, title, url, scenes: emptyScenes });\n } else {\n return this._insertDocsImpl({ fileType: \"pdf\", scenePath, scenes, title: arg1 });\n }\n }\n }\n\n private _insertDocsImpl({ fileType, scenePath, title, scenes, ...attributes }: InsertDocsParams) {\n this._assertNotDestroyed();\n switch (fileType) {\n case \"pdf\":\n return this.manager.addApp({\n kind: \"DocsViewer\",\n options: { scenePath, title, scenes },\n });\n case \"pptx\":\n return this.manager.addApp({\n kind: \"Slide\",\n options: { scenePath, title, scenes },\n attributes,\n });\n }\n }\n\n /**\n * Insert the Monaco Code Editor app.\n */\n insertCodeEditor() {\n this._assertNotDestroyed();\n return this.manager.addApp({\n kind: \"Monaco\",\n options: { title: \"Code Editor\" },\n });\n }\n\n /**\n * Insert the Countdown app.\n */\n insertCountdown() {\n this._assertNotDestroyed();\n return this.manager.addApp({\n kind: \"Countdown\",\n options: { title: \"Countdown\" },\n });\n }\n\n /**\n * Insert the Media Player app.\n */\n insertMedia(title: string, src: string) {\n this._assertNotDestroyed();\n return this.manager.addApp({\n kind: BuiltinApps.MediaPlayer,\n options: { title },\n attributes: { src },\n });\n }\n\n /**\n * Insert the GeoGebra app.\n */\n insertGeoGebra() {\n this._assertNotDestroyed();\n return this.manager.addApp({\n kind: \"GeoGebra\",\n options: { title: \"GeoGebra\" },\n });\n }\n}\n","export type FastboardListener<T> = (event: T) => void;\n\nexport class FastboardEmitter<T> {\n listeners = new Set<FastboardListener<T>>();\n\n get length(): number {\n return this.listeners.size;\n }\n\n dispatch(message: T) {\n this.listeners.forEach(callback => callback(message));\n }\n\n addListener(listener: FastboardListener<T>) {\n this.listeners.add(listener);\n }\n\n removeListener(listener: FastboardListener<T>) {\n this.listeners.delete(listener);\n }\n}\n","import { FastboardEmitter } from \"./emitter\";\nimport { noop, safe_not_equal } from \"./utils\";\n\nexport type FastboardDisposer = () => void;\n\nexport interface FastboardReadable<T> {\n readonly value: T;\n subscribe(callback: (value: T) => void): FastboardDisposer;\n reaction(callback: (value: T) => void): FastboardDisposer;\n}\n\nexport interface FastboardWritable<T, SetFn = (value: T) => void> extends FastboardReadable<T> {\n setValue: SetFn;\n}\n\nexport interface FastboardInternalValue<T> extends FastboardWritable<T> {\n dispose: FastboardDisposer;\n}\n\n/**\n * Create a readonly, reactive value.\n * @example\n * createValue(manager.getMainViewSceneIndex(), (set) => {\n * manager.emitter.on(\"mainViewSceneIndexChanged\", set)\n * return () => manager.emitter.off(\"mainViewSceneIndexChanged\", set)\n * })\n */\nexport function createValue<T>(\n value: T,\n effect: (set: (value: T) => void) => FastboardDisposer | void\n): FastboardReadable<T>;\n\n/**\n * Create a writable, reactive value.\n * @example\n * createValue(manager.getMainViewSceneIndex(), (set) => {\n * manager.emitter.on(\"mainViewSceneIndexChanged\", set)\n * return () => manager.emitter.off(\"mainViewSceneIndexChanged\", set)\n * }, (newValue) => {\n * manager.setMainViewSceneIndex(newValue)\n * })\n */\nexport function createValue<T, SetFn = (value: T) => void>(\n value: T,\n effect: (set: (value: T) => void) => FastboardDisposer | void,\n set: (value: T) => void\n): FastboardWritable<T, SetFn>;\n\nexport function createValue<T>(\n value: T,\n effect: (set: (value: T) => void) => FastboardDisposer | void,\n setValue: (value: T) => void = noop\n): FastboardInternalValue<T> {\n const emitter = new FastboardEmitter<T>();\n\n function set(newValue: T) {\n if (safe_not_equal(value, newValue)) {\n emitter.dispatch((value = newValue));\n }\n }\n\n const dispose = effect(set) || noop;\n\n function subscribe(callback: (value: T) => void) {\n emitter.addListener(callback);\n callback(value);\n return () => emitter.removeListener(callback);\n }\n\n function reaction(callback: (value: T) => void) {\n emitter.addListener(callback);\n return () => emitter.removeListener(callback);\n }\n\n return {\n get value() {\n return value;\n },\n subscribe,\n reaction,\n setValue,\n dispose,\n };\n}\n","import type { Player, PlayerCallbacks, PlayerState, ViewCallbacks, WhiteWebSdk } from \"white-web-sdk\";\nimport type { PublicEvent, WindowManager } from \"@netless/window-manager\";\nimport type { FastboardDisposer, FastboardInternalValue } from \"../helpers/value\";\n\nimport { createValue } from \"../helpers/value\";\n\nclass FastboardPlayerBase {\n public constructor(readonly sdk: WhiteWebSdk, readonly player: Player, readonly manager: WindowManager) {}\n\n protected readonly _disposers: FastboardDisposer[] = [];\n protected _destroyed = false;\n protected _assertNotDestroyed() {\n if (this._destroyed) {\n throw new Error(\"[FastboardPlayer] Can not call any method on destroyed FastboardPlayer.\");\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected createValue: typeof createValue = (...args: [any, any]): any => {\n const value = createValue(...args);\n this._disposers.push((value as FastboardInternalValue<unknown>).dispose);\n return value;\n };\n\n protected _addPlayerListener<K extends keyof PlayerCallbacks, T = PlayerCallbacks[K]>(\n name: K,\n listener: T\n ) {\n this._assertNotDestroyed();\n this.player.callbacks.on(name, listener);\n return () => this.player.callbacks.off(name, listener);\n }\n\n protected _addManagerListener<K extends keyof PublicEvent>(name: K, set: (value: PublicEvent[K]) => void) {\n this._assertNotDestroyed();\n this.manager.emitter.on(name, set);\n return () => this.manager.emitter.off(name, set);\n }\n\n protected _addMainViewListener<K extends keyof ViewCallbacks, T = ViewCallbacks[K]>(name: K, listener: T) {\n this._assertNotDestroyed();\n this.manager.mainView.callbacks.on(name, listener);\n return () => this.manager.mainView.callbacks.off(name, listener);\n }\n\n public destroy() {\n this._disposers.forEach(dispose => dispose());\n this._disposers.length = 0;\n this._destroyed = true;\n this.manager.destroy();\n this.player.callbacks.off();\n }\n}\n\nexport class FastboardPlayer extends FastboardPlayerBase {\n /**\n * Render this player to some DOM.\n */\n bindContainer(container: HTMLElement) {\n this._assertNotDestroyed();\n this.manager.bindContainer(container);\n }\n\n /**\n * Move window-manager's collector to some place.\n */\n bindCollector(container: HTMLElement) {\n this._assertNotDestroyed();\n this.manager.bindCollectorContainer(container);\n }\n\n readonly currentTime = this.createValue(\n this.player.progressTime,\n set => this._addPlayerListener(\"onProgressTimeChanged\", set),\n this.player.seekToProgressTime.bind(this.player)\n );\n\n readonly phase = this.createValue(this.player.phase, set => this._addPlayerListener(\"onPhaseChanged\", set));\n\n readonly canplay = this.createValue(this.player.isPlayable, set =>\n this._addPlayerListener(\"onIsPlayableChanged\", set)\n );\n\n private _setSpeed!: (value: number) => void;\n readonly speed = this.createValue(\n this.player.playbackSpeed,\n set => {\n this._setSpeed = set;\n },\n value => {\n this.player.playbackSpeed = value;\n this._setSpeed(value);\n }\n );\n\n readonly state = this.createValue<PlayerState | null>(null, set => {\n const update = () => set(this.player.state);\n const dispose1 = this._addPlayerListener(\"onLoadFirstFrame\", update);\n const dispose2 = this._addPlayerListener(\"onPlayerStateChanged\", update);\n return () => (dispose1(), dispose2());\n });\n\n seek(timestamp: number) {\n this._assertNotDestroyed();\n return this.player.seekToProgressTime(timestamp);\n }\n\n play() {\n this._assertNotDestroyed();\n this.player.play();\n }\n\n pause() {\n this._assertNotDestroyed();\n this.player.pause();\n }\n\n stop() {\n this._assertNotDestroyed();\n this.player.stop();\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -1,7 +1,9 @@
1
1
  import {
2
+ DefaultApps,
2
3
  createFastboard,
4
+ registerApps,
3
5
  replayFastboard
4
- } from "./chunk-CS5DXHML.mjs";
6
+ } from "./chunk-Z66W5SHZ.mjs";
5
7
 
6
8
  // src/behaviors/register-slide.ts
7
9
  import { WindowManager } from "@netless/window-manager";
@@ -14,7 +16,9 @@ WindowManager.register({
14
16
  src: AppSlide
15
17
  });
16
18
  export {
19
+ DefaultApps,
17
20
  createFastboard,
21
+ registerApps,
18
22
  replayFastboard
19
23
  };
20
24
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/behaviors/register-slide.ts"],"sourcesContent":["import { WindowManager } from \"@netless/window-manager\";\nimport AppSlide from \"@netless/app-slide\";\n\nWindowManager.register({\n kind: \"Slide\",\n appOptions: {\n // turn on to show debug controller\n debug: false,\n },\n src: AppSlide,\n});\n"],"mappings":";;;;;;AAAA;AACA;AAEA,cAAc,SAAS;AAAA,EACrB,MAAM;AAAA,EACN,YAAY;AAAA,IAEV,OAAO;AAAA;AAAA,EAET,KAAK;AAAA;","names":[]}
1
+ {"version":3,"sources":["../src/behaviors/register-slide.ts"],"sourcesContent":["import { WindowManager } from \"@netless/window-manager\";\nimport AppSlide from \"@netless/app-slide\";\n\nWindowManager.register({\n kind: \"Slide\",\n appOptions: {\n // turn on to show debug controller\n debug: false,\n },\n src: AppSlide,\n});\n"],"mappings":";;;;;;;;AAAA;AACA;AAEA,cAAc,SAAS;AAAA,EACrB,MAAM;AAAA,EACN,YAAY;AAAA,IAEV,OAAO;AAAA;AAAA,EAET,KAAK;AAAA;","names":[]}