@netless/fastboard-core 0.2.12 → 0.3.0-canary.1

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.
@@ -1,21 +0,0 @@
1
- export type FastboardListener<T> = (event: T) => void;
2
-
3
- export class FastboardEmitter<T> {
4
- listeners = new Set<FastboardListener<T>>();
5
-
6
- get length(): number {
7
- return this.listeners.size;
8
- }
9
-
10
- dispatch(message: T) {
11
- this.listeners.forEach(callback => callback(message));
12
- }
13
-
14
- addListener(listener: FastboardListener<T>) {
15
- this.listeners.add(listener);
16
- }
17
-
18
- removeListener(listener: FastboardListener<T>) {
19
- this.listeners.delete(listener);
20
- }
21
- }
@@ -1,78 +0,0 @@
1
- import type { ConvertedFile, JoinRoomParams, ReplayRoomParams, SceneDefinition, Size } from "white-web-sdk";
2
- import { WindowManager } from "@netless/window-manager";
3
-
4
- export function noop() {
5
- /* noop */
6
- }
7
-
8
- export function safe_not_equal(a: unknown, b: unknown) {
9
- return a != a ? b == b : a !== b || (a && typeof a === "object") || typeof a === "function";
10
- }
11
-
12
- export function getImageSize(url: string, fallback: Size) {
13
- return new Promise<Size>(resolve => {
14
- const img = new Image();
15
- img.onload = () => resolve(img);
16
- img.onerror = () => resolve(fallback);
17
- img.src = url;
18
- });
19
- }
20
-
21
- export function makeSlideParams(scenes: SceneDefinition[]) {
22
- const emptyScenes: SceneDefinition[] = [];
23
- let taskId = "";
24
- let url = "";
25
-
26
- // e.g. "ppt(x)://cdn/prefix/dynamicConvert/{taskId}/1.slide"
27
- const pptSrcRE = /^pptx?(?<prefix>:\/\/\S+?dynamicConvert)\/(?<taskId>\w+)\//;
28
-
29
- for (const { name, ppt } of scenes) {
30
- // make sure scenesWithoutPPT.length === scenes.length
31
- emptyScenes.push({ name });
32
-
33
- if (!ppt || !ppt.src.startsWith("ppt")) {
34
- continue;
35
- }
36
- const match = pptSrcRE.exec(ppt.src);
37
- if (!match || !match.groups) {
38
- continue;
39
- }
40
- taskId = match.groups.taskId;
41
- url = "https" + match.groups.prefix;
42
- break;
43
- }
44
-
45
- return { emptyScenes, taskId, url };
46
- }
47
-
48
- export function convertedFileToScene(f: ConvertedFile, i: number) {
49
- return {
50
- name: String(i + 1),
51
- ppt: {
52
- src: f.conversionFileUrl,
53
- width: f.width,
54
- height: f.height,
55
- previewURL: f.preview,
56
- },
57
- };
58
- }
59
-
60
- export function ensureWindowManager<T extends JoinRoomParams | ReplayRoomParams>(joinRoom: T): T {
61
- if (!joinRoom.invisiblePlugins || !joinRoom.invisiblePlugins.includes(WindowManager)) {
62
- joinRoom.invisiblePlugins = [...(joinRoom.invisiblePlugins || []), WindowManager];
63
- }
64
- return joinRoom;
65
- }
66
-
67
- // Copy from https://github.com/crimx/side-effect-manager/blob/main/src/gen-uid.ts
68
- const SOUP = "!#%()*+,-./:;=?@[]^_`{|}~" + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
69
- const SOUP_LEN = SOUP.length;
70
- const ID_LEN = 20;
71
- const reusedIdCarrier = /* @__PURE__ */ Array(ID_LEN);
72
-
73
- export function genUID() {
74
- for (let i = 0; i < ID_LEN; i++) {
75
- reusedIdCarrier[i] = SOUP.charAt(Math.random() * SOUP_LEN);
76
- }
77
- return reusedIdCarrier.join("");
78
- }
@@ -1,84 +0,0 @@
1
- import { FastboardEmitter } from "./emitter";
2
- import { noop, safe_not_equal } from "./utils";
3
-
4
- export type FastboardDisposer = () => void;
5
-
6
- export interface FastboardReadable<T> {
7
- readonly value: T;
8
- subscribe(callback: (value: T) => void): FastboardDisposer;
9
- reaction(callback: (value: T) => void): FastboardDisposer;
10
- }
11
-
12
- export interface FastboardWritable<T, SetFn = (value: T) => void> extends FastboardReadable<T> {
13
- setValue: SetFn;
14
- }
15
-
16
- export interface FastboardInternalValue<T> extends FastboardWritable<T> {
17
- dispose: FastboardDisposer;
18
- }
19
-
20
- /**
21
- * Create a readonly, reactive value.
22
- * @example
23
- * createValue(manager.getMainViewSceneIndex(), (set) => {
24
- * manager.emitter.on("mainViewSceneIndexChanged", set)
25
- * return () => manager.emitter.off("mainViewSceneIndexChanged", set)
26
- * })
27
- */
28
- export function createValue<T>(
29
- value: T,
30
- effect: (set: (value: T) => void) => FastboardDisposer | void
31
- ): FastboardReadable<T>;
32
-
33
- /**
34
- * Create a writable, reactive value.
35
- * @example
36
- * createValue(manager.getMainViewSceneIndex(), (set) => {
37
- * manager.emitter.on("mainViewSceneIndexChanged", set)
38
- * return () => manager.emitter.off("mainViewSceneIndexChanged", set)
39
- * }, (newValue) => {
40
- * manager.setMainViewSceneIndex(newValue)
41
- * })
42
- */
43
- export function createValue<T, SetFn = (value: T) => void>(
44
- value: T,
45
- effect: (set: (value: T) => void) => FastboardDisposer | void,
46
- set: (value: T) => void
47
- ): FastboardWritable<T, SetFn>;
48
-
49
- export function createValue<T>(
50
- value: T,
51
- effect: (set: (value: T) => void) => FastboardDisposer | void,
52
- setValue: (value: T) => void = noop
53
- ): FastboardInternalValue<T> {
54
- const emitter = new FastboardEmitter<T>();
55
-
56
- function set(newValue: T) {
57
- if (safe_not_equal(value, newValue)) {
58
- emitter.dispatch((value = newValue));
59
- }
60
- }
61
-
62
- const dispose = effect(set) || noop;
63
-
64
- function subscribe(callback: (value: T) => void) {
65
- emitter.addListener(callback);
66
- callback(value);
67
- return () => emitter.removeListener(callback);
68
- }
69
-
70
- function reaction(callback: (value: T) => void) {
71
- emitter.addListener(callback);
72
- return () => emitter.removeListener(callback);
73
- }
74
-
75
- return {
76
- get value() {
77
- return value;
78
- },
79
- subscribe,
80
- reaction,
81
- setValue,
82
- dispose,
83
- };
84
- }
@@ -1,122 +0,0 @@
1
- import type { Player, PlayerCallbacks, PlayerState, ViewCallbacks, WhiteWebSdk } from "white-web-sdk";
2
- import type { PublicEvent, WindowManager } from "@netless/window-manager";
3
- import type { FastboardDisposer, FastboardInternalValue } from "../helpers/value";
4
-
5
- import { createValue } from "../helpers/value";
6
-
7
- class FastboardPlayerBase {
8
- public constructor(readonly sdk: WhiteWebSdk, readonly player: Player, readonly manager: WindowManager) {}
9
-
10
- protected readonly _disposers: FastboardDisposer[] = [];
11
- protected _destroyed = false;
12
- protected _assertNotDestroyed() {
13
- if (this._destroyed) {
14
- throw new Error("[FastboardPlayer] Can not call any method on destroyed FastboardPlayer.");
15
- }
16
- }
17
-
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- protected createValue: typeof createValue = (...args: [any, any]): any => {
20
- const value = createValue(...args);
21
- this._disposers.push((value as FastboardInternalValue<unknown>).dispose);
22
- return value;
23
- };
24
-
25
- protected _addPlayerListener<K extends keyof PlayerCallbacks, T = PlayerCallbacks[K]>(
26
- name: K,
27
- listener: T
28
- ) {
29
- this._assertNotDestroyed();
30
- this.player.callbacks.on(name, listener);
31
- return () => this.player.callbacks.off(name, listener);
32
- }
33
-
34
- protected _addManagerListener<K extends keyof PublicEvent>(name: K, set: (value: PublicEvent[K]) => void) {
35
- this._assertNotDestroyed();
36
- this.manager.emitter.on(name, set);
37
- return () => this.manager.emitter.off(name, set);
38
- }
39
-
40
- protected _addMainViewListener<K extends keyof ViewCallbacks, T = ViewCallbacks[K]>(name: K, listener: T) {
41
- this._assertNotDestroyed();
42
- this.manager.mainView.callbacks.on(name, listener);
43
- return () => this.manager.mainView.callbacks.off(name, listener);
44
- }
45
-
46
- public destroy() {
47
- this._disposers.forEach(dispose => dispose());
48
- this._disposers.length = 0;
49
- this._destroyed = true;
50
- this.manager.destroy();
51
- this.player.callbacks.off();
52
- }
53
- }
54
-
55
- export class FastboardPlayer extends FastboardPlayerBase {
56
- /**
57
- * Render this player to some DOM.
58
- */
59
- bindContainer(container: HTMLElement) {
60
- this._assertNotDestroyed();
61
- this.manager.bindContainer(container);
62
- }
63
-
64
- /**
65
- * Move window-manager's collector to some place.
66
- */
67
- bindCollector(container: HTMLElement) {
68
- this._assertNotDestroyed();
69
- this.manager.bindCollectorContainer(container);
70
- }
71
-
72
- readonly currentTime = this.createValue(
73
- this.player.progressTime,
74
- set => this._addPlayerListener("onProgressTimeChanged", set),
75
- this.player.seekToProgressTime.bind(this.player)
76
- );
77
-
78
- readonly phase = this.createValue(this.player.phase, set => this._addPlayerListener("onPhaseChanged", set));
79
-
80
- readonly canplay = this.createValue(this.player.isPlayable, set =>
81
- this._addPlayerListener("onIsPlayableChanged", set)
82
- );
83
-
84
- private _setSpeed!: (value: number) => void;
85
- readonly speed = this.createValue(
86
- this.player.playbackSpeed,
87
- set => {
88
- this._setSpeed = set;
89
- },
90
- value => {
91
- this.player.playbackSpeed = value;
92
- this._setSpeed(value);
93
- }
94
- );
95
-
96
- readonly state = this.createValue<PlayerState | null>(null, set => {
97
- const update = () => set(this.player.state);
98
- const dispose1 = this._addPlayerListener("onLoadFirstFrame", update);
99
- const dispose2 = this._addPlayerListener("onPlayerStateChanged", update);
100
- return () => (dispose1(), dispose2());
101
- });
102
-
103
- seek(timestamp: number) {
104
- this._assertNotDestroyed();
105
- return this.player.seekToProgressTime(timestamp);
106
- }
107
-
108
- play() {
109
- this._assertNotDestroyed();
110
- this.player.play();
111
- }
112
-
113
- pause() {
114
- this._assertNotDestroyed();
115
- this.player.pause();
116
- }
117
-
118
- stop() {
119
- this._assertNotDestroyed();
120
- this.player.stop();
121
- }
122
- }
package/src/minimal.ts DELETED
@@ -1,153 +0,0 @@
1
- import type {
2
- Displayer,
3
- HotKeys,
4
- JoinRoomParams,
5
- PlayerCallbacks,
6
- ReplayRoomParams,
7
- Room,
8
- RoomCallbacks,
9
- WhiteWebSdkConfiguration,
10
- } from "white-web-sdk";
11
- import type { MountParams } from "@netless/window-manager";
12
-
13
- import { contentModeScale, DefaultHotKeys, WhiteWebSdk } from "white-web-sdk";
14
- import { WindowManager } from "@netless/window-manager";
15
-
16
- import { ensureWindowManager } from "./helpers/utils";
17
- import { FastboardApp } from "./impl/app";
18
- import { FastboardPlayer } from "./impl/player";
19
-
20
- export type { FastboardReadable, FastboardWritable } from "./helpers/value";
21
-
22
- export type { AppsStatus, InsertDocsDynamic, InsertDocsParams, InsertDocsStatic } from "./impl/app";
23
-
24
- export type { FastboardApp, FastboardPlayer };
25
-
26
- export interface FastboardOptions {
27
- sdkConfig: Omit<WhiteWebSdkConfiguration, "useMobXState"> & { region: string };
28
- joinRoom: Omit<JoinRoomParams, "useMultiViews" | "disableNewPencil" | "disableMagixEventDispatchLimit"> & {
29
- callbacks?: Partial<RoomCallbacks>;
30
- };
31
- managerConfig?: Omit<MountParams, "room">;
32
- }
33
-
34
- /**
35
- * Create a FastboardApp instance.
36
- * @example
37
- * let app = await createFastboard({
38
- * sdkConfig: {
39
- * appIdentifier: import.meta.env.VITE_APPID,
40
- * region: "cn-hz",
41
- * },
42
- * joinRoom: {
43
- * uid: unique_id,
44
- * uuid: import.meta.env.VITE_ROOM_UUID,
45
- * roomToken: import.meta.env.VITE_ROOM_TOKEN,
46
- * },
47
- * })
48
- */
49
- export async function createFastboard({
50
- sdkConfig,
51
- joinRoom: { callbacks, ...joinRoomParams },
52
- managerConfig,
53
- }: FastboardOptions) {
54
- const sdk = new WhiteWebSdk({
55
- ...sdkConfig,
56
- useMobXState: true,
57
- });
58
-
59
- const hotKeys: Partial<HotKeys> = {
60
- ...DefaultHotKeys,
61
- changeToSelector: "s",
62
- changeToLaserPointer: "z",
63
- changeToPencil: "p",
64
- changeToRectangle: "r",
65
- changeToEllipse: "c",
66
- changeToEraser: "e",
67
- changeToText: "t",
68
- changeToStraight: "l",
69
- changeToArrow: "a",
70
- changeToHand: "h",
71
- };
72
-
73
- const room = await sdk.joinRoom(
74
- {
75
- floatBar: true,
76
- hotKeys,
77
- ...ensureWindowManager(joinRoomParams),
78
- useMultiViews: true,
79
- disableNewPencil: false,
80
- disableMagixEventDispatchLimit: true,
81
- },
82
- callbacks
83
- );
84
-
85
- const manager = await WindowManager.mount({
86
- cursor: true,
87
- ...managerConfig,
88
- room,
89
- });
90
-
91
- manager.mainView.setCameraBound({
92
- minContentMode: contentModeScale(0.3),
93
- maxContentMode: contentModeScale(3),
94
- });
95
-
96
- return new FastboardApp(sdk, room, manager, hotKeys);
97
- }
98
-
99
- export interface FastboardReplayOptions {
100
- sdkConfig: Omit<WhiteWebSdkConfiguration, "useMobXState"> & { region: string };
101
- replayRoom: Omit<ReplayRoomParams, "useMultiViews"> & {
102
- callbacks?: Partial<PlayerCallbacks>;
103
- };
104
- managerConfig?: Omit<MountParams, "room">;
105
- }
106
-
107
- /**
108
- * Create a FastboardPlayer instance.
109
- * @example
110
- * let app = await replayFastboard({
111
- * sdkConfig: {
112
- * appIdentifier: import.meta.env.VITE_APPID,
113
- * region: "cn-hz",
114
- * },
115
- * replayRoom: {
116
- * uid: unique_id,
117
- * uuid: import.meta.env.VITE_ROOM_UUID,
118
- * roomToken: import.meta.env.VITE_ROOM_TOKEN,
119
- * },
120
- * })
121
- */
122
- export async function replayFastboard({
123
- sdkConfig,
124
- replayRoom: { callbacks, ...replayRoomParams },
125
- managerConfig,
126
- }: FastboardReplayOptions) {
127
- const sdk = new WhiteWebSdk({
128
- ...sdkConfig,
129
- useMobXState: true,
130
- });
131
-
132
- const player = await sdk.replayRoom(
133
- {
134
- ...ensureWindowManager(replayRoomParams),
135
- useMultiViews: true,
136
- },
137
- callbacks
138
- );
139
-
140
- const managerPromise = WindowManager.mount({
141
- cursor: true,
142
- ...managerConfig,
143
- room: player as Displayer as Room,
144
- });
145
-
146
- player.play();
147
- const manager = await managerPromise;
148
- player.pause();
149
-
150
- return new FastboardPlayer(sdk, player, manager);
151
- }
152
-
153
- import "./behaviors/register-apps";