@netless/window-manager 1.0.14 → 1.0.16
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.
- package/dist/app-docs-viewer.js +4 -0
- package/dist/app-docs-viewer.js.map +1 -0
- package/dist/app-docs-viewer.mjs +2892 -0
- package/dist/app-docs-viewer.mjs.map +1 -0
- package/dist/app-media-player.js +31 -0
- package/dist/app-media-player.js.map +1 -0
- package/dist/app-media-player.mjs +7056 -0
- package/dist/app-media-player.mjs.map +1 -0
- package/dist/app-presentation.js +21 -0
- package/dist/app-presentation.js.map +1 -0
- package/dist/app-presentation.mjs +7538 -0
- package/dist/app-presentation.mjs.map +1 -0
- package/dist/index.d.ts +87 -9
- package/dist/index.js +5 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1225 -10943
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
- package/src/App/AppProxy.ts +13 -4
- package/src/AppManager.ts +16 -11
- package/src/BuiltinApps.ts +29 -6
- package/src/ContainerResizeObserver.ts +14 -5
- package/src/Utils/RoomHacker.ts +3 -1
- package/src/Utils/attributesLogStringify.ts +13 -8
- package/src/Utils/log.ts +13 -9
- package/src/Utils/resolveAppOptions.ts +12 -0
- package/src/View/MainView.ts +50 -24
- package/src/css.d.ts +1 -0
- package/src/index.ts +273 -18
package/src/index.ts
CHANGED
|
@@ -16,7 +16,8 @@ import { ArgusLog, log } from "./Utils/log";
|
|
|
16
16
|
import { PageStateImpl } from "./PageState";
|
|
17
17
|
import { ReconnectRefresher } from "./ReconnectRefresher";
|
|
18
18
|
import { replaceRoomFunction } from "./Utils/RoomHacker";
|
|
19
|
-
import { setupBuiltin } from "./BuiltinApps";
|
|
19
|
+
import { BuiltinApps, setupBuiltin } from "./BuiltinApps";
|
|
20
|
+
import type { BuiltinAppOptions } from "./BuiltinApps";
|
|
20
21
|
import "video.js/dist/video-js.css";
|
|
21
22
|
import "./style.css";
|
|
22
23
|
import "@netless/telebox-insider/dist/style.css";
|
|
@@ -62,11 +63,11 @@ import type Emittery from "emittery";
|
|
|
62
63
|
import type { PageController, AddPageParams, PageState } from "./Page";
|
|
63
64
|
import { boxEmitter } from "./BoxEmitter";
|
|
64
65
|
import { IframeBridge } from "./View/IframeBridge";
|
|
65
|
-
import { setOptions } from "@netless/app-media-player";
|
|
66
66
|
import type { ExtendPluginInstance } from "./ExtendPluginManager";
|
|
67
67
|
import { ExtendPluginManager } from "./ExtendPluginManager";
|
|
68
68
|
import { getExtendClass } from "./Utils/extendClass";
|
|
69
69
|
import type { ExtendClass } from "./Utils/extendClass";
|
|
70
|
+
import { resolveAppOptions as mergeAppOptions } from "./Utils/resolveAppOptions";
|
|
70
71
|
|
|
71
72
|
export * from "./utils/extendClass";
|
|
72
73
|
|
|
@@ -90,6 +91,54 @@ export type AddAppOptions = {
|
|
|
90
91
|
|
|
91
92
|
export type setAppOptions = AddAppOptions & { appOptions?: any };
|
|
92
93
|
|
|
94
|
+
export type DocsEvent =
|
|
95
|
+
| "prevPage"
|
|
96
|
+
| "nextPage"
|
|
97
|
+
| "prevStep"
|
|
98
|
+
| "nextStep"
|
|
99
|
+
| "jumpToPage"
|
|
100
|
+
| "scalePage";
|
|
101
|
+
|
|
102
|
+
export type DocsEventOptions = {
|
|
103
|
+
/** If provided, will dispatch to the specific app. Default to the focused app. */
|
|
104
|
+
appId?: string;
|
|
105
|
+
/** Used by `jumpToPage` event, range from 1 to total pages count. */
|
|
106
|
+
page?: number;
|
|
107
|
+
/** Used by `scalePage` event. Range from 1 to 4, decimals allowed. `1` means default fitted size. */
|
|
108
|
+
scale?: number;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
type SlideDocsAppResult = {
|
|
112
|
+
prevPage: () => boolean;
|
|
113
|
+
nextPage: () => boolean;
|
|
114
|
+
prevStep: () => boolean;
|
|
115
|
+
nextStep: () => boolean;
|
|
116
|
+
jumpToPage: (page: number) => boolean;
|
|
117
|
+
scaleView: (scale: number) => void;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
type PresentationDocsAppResult = {
|
|
121
|
+
prevPage: () => boolean;
|
|
122
|
+
nextPage: () => boolean;
|
|
123
|
+
jumpPage: (index: number) => boolean;
|
|
124
|
+
moveCamera: (camera: { centerX: number; centerY: number; scale: number }) => void;
|
|
125
|
+
getOriginScale: () => number;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const SlideAppKind = "Slide";
|
|
129
|
+
const PresentationAppKind = BuiltinApps.Presentation;
|
|
130
|
+
const MinDocsPageScale = 1;
|
|
131
|
+
const MaxDocsPageScale = 4;
|
|
132
|
+
|
|
133
|
+
function isValidDocsPageScale(scale: unknown): scale is number {
|
|
134
|
+
return (
|
|
135
|
+
typeof scale === "number" &&
|
|
136
|
+
Number.isFinite(scale) &&
|
|
137
|
+
scale >= MinDocsPageScale &&
|
|
138
|
+
scale <= MaxDocsPageScale
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
93
142
|
export type AddAppParams<TAttributes = any> = {
|
|
94
143
|
kind: string;
|
|
95
144
|
// app 地址(本地 app 不需要传)
|
|
@@ -197,6 +246,8 @@ export type MountParams = {
|
|
|
197
246
|
supportAppliancePlugin?: boolean;
|
|
198
247
|
/** 是否使用 boxesStatus 状态管理窗口 */
|
|
199
248
|
useBoxesStatus?: boolean;
|
|
249
|
+
/** Local Presentation options applied before restoring apps. Not synchronized. */
|
|
250
|
+
builtinAppOptions?: BuiltinAppOptions;
|
|
200
251
|
};
|
|
201
252
|
|
|
202
253
|
export const reconnectRefresher = new ReconnectRefresher({ emitter: internalEmitter });
|
|
@@ -234,6 +285,8 @@ export class WindowManager
|
|
|
234
285
|
|
|
235
286
|
public _appliancePlugin?: any;
|
|
236
287
|
|
|
288
|
+
public builtinAppOptions?: BuiltinAppOptions;
|
|
289
|
+
|
|
237
290
|
private boxManager?: BoxManager;
|
|
238
291
|
private static params?: MountParams;
|
|
239
292
|
static extendClass?: ExtendClass;
|
|
@@ -255,7 +308,7 @@ export class WindowManager
|
|
|
255
308
|
super(context);
|
|
256
309
|
WindowManager.displayer = context.displayer;
|
|
257
310
|
(window as any).NETLESS_DEPS = __APP_DEPENDENCIES__;
|
|
258
|
-
this.emitter.on(
|
|
311
|
+
this.emitter.on("mainViewScenePathChange", this.onMainViewScenePathChangeHandler);
|
|
259
312
|
}
|
|
260
313
|
|
|
261
314
|
public static onCreate(manager: WindowManager) {
|
|
@@ -289,7 +342,11 @@ export class WindowManager
|
|
|
289
342
|
manager = await this.initManager(room);
|
|
290
343
|
if (manager) {
|
|
291
344
|
manager._roomLogger = (room as unknown as { logger: Logger }).logger;
|
|
292
|
-
manager.attributesDeboundceLog = new ArgusLog(
|
|
345
|
+
manager.attributesDeboundceLog = new ArgusLog(
|
|
346
|
+
manager._roomLogger,
|
|
347
|
+
"attributes",
|
|
348
|
+
300
|
|
349
|
+
);
|
|
293
350
|
if (WindowManager.registered.size > 0) {
|
|
294
351
|
manager._roomLogger.info(
|
|
295
352
|
`[WindowManager] registered apps: ${JSON.stringify(
|
|
@@ -304,9 +361,6 @@ export class WindowManager
|
|
|
304
361
|
}
|
|
305
362
|
|
|
306
363
|
this.debug = Boolean(debug);
|
|
307
|
-
if (this.debug) {
|
|
308
|
-
setOptions({ verbose: true });
|
|
309
|
-
}
|
|
310
364
|
if (manager?._roomLogger) {
|
|
311
365
|
manager._roomLogger.info(
|
|
312
366
|
`[WindowManager] Already insert room version: ${manager.version}`
|
|
@@ -337,6 +391,8 @@ export class WindowManager
|
|
|
337
391
|
throw new Error("[WindowManager]: create manager failed");
|
|
338
392
|
}
|
|
339
393
|
|
|
394
|
+
manager.builtinAppOptions = params.builtinAppOptions;
|
|
395
|
+
|
|
340
396
|
if (containerSizeRatio) {
|
|
341
397
|
WindowManager.containerSizeRatio = containerSizeRatio;
|
|
342
398
|
}
|
|
@@ -390,27 +446,43 @@ export class WindowManager
|
|
|
390
446
|
console.warn("[WindowManager]: indexedDB open failed");
|
|
391
447
|
console.log(error);
|
|
392
448
|
}
|
|
393
|
-
manager.emitter.on(
|
|
449
|
+
manager.emitter.on("mainViewScenePathChange", manager.onMainViewScenePathChangeHandler);
|
|
394
450
|
return manager;
|
|
395
451
|
}
|
|
396
452
|
|
|
397
453
|
public onMainViewScenePathChangeHandler = (scenePath: string) => {
|
|
398
454
|
const mainViewElement = this.mainView.divElement;
|
|
399
455
|
if (mainViewElement) {
|
|
400
|
-
const backgroundImage = mainViewElement.querySelector(
|
|
456
|
+
const backgroundImage = mainViewElement.querySelector(".background img");
|
|
401
457
|
if (backgroundImage) {
|
|
402
458
|
const backgroundImageRect = backgroundImage?.getBoundingClientRect();
|
|
403
459
|
const backgroundImageCSS = window.getComputedStyle(backgroundImage);
|
|
404
|
-
const backgroundImageVisible =
|
|
460
|
+
const backgroundImageVisible =
|
|
461
|
+
backgroundImageRect?.width > 0 &&
|
|
462
|
+
backgroundImageRect?.height > 0 &&
|
|
463
|
+
backgroundImageCSS.display !== "none";
|
|
405
464
|
const camera = this.mainView.camera;
|
|
406
|
-
console.log(
|
|
465
|
+
console.log(
|
|
466
|
+
"[window-manager] backgroundImageVisible:" +
|
|
467
|
+
backgroundImageVisible +
|
|
468
|
+
" camera:" +
|
|
469
|
+
JSON.stringify(camera)
|
|
470
|
+
);
|
|
407
471
|
return;
|
|
408
472
|
}
|
|
409
|
-
console.log(
|
|
473
|
+
console.log(
|
|
474
|
+
"[window-manager] onMainViewScenePathChange scenePath:" +
|
|
475
|
+
scenePath +
|
|
476
|
+
" backgroundImageVisible is not found"
|
|
477
|
+
);
|
|
410
478
|
return;
|
|
411
479
|
}
|
|
412
|
-
console.log(
|
|
413
|
-
|
|
480
|
+
console.log(
|
|
481
|
+
"[window-manager] onMainViewScenePathChange scenePath:" +
|
|
482
|
+
scenePath +
|
|
483
|
+
" mainViewElement is not found"
|
|
484
|
+
);
|
|
485
|
+
};
|
|
414
486
|
|
|
415
487
|
private static initManager(room: Room): Promise<WindowManager | undefined> {
|
|
416
488
|
return createInvisiblePlugin(room);
|
|
@@ -522,6 +594,15 @@ export class WindowManager
|
|
|
522
594
|
return appRegister.unregister(kind);
|
|
523
595
|
}
|
|
524
596
|
|
|
597
|
+
public resolveAppOptions(
|
|
598
|
+
kind: string,
|
|
599
|
+
registeredOptions?: any | (() => any)
|
|
600
|
+
): any | (() => any) {
|
|
601
|
+
const override =
|
|
602
|
+
kind === BuiltinApps.Presentation ? this.builtinAppOptions?.Presentation : undefined;
|
|
603
|
+
return mergeAppOptions(registeredOptions, override);
|
|
604
|
+
}
|
|
605
|
+
|
|
525
606
|
/**
|
|
526
607
|
* 创建一个 app 至白板
|
|
527
608
|
*/
|
|
@@ -1007,6 +1088,172 @@ export class WindowManager
|
|
|
1007
1088
|
return this.appManager?.appProxies.get(appId);
|
|
1008
1089
|
}
|
|
1009
1090
|
|
|
1091
|
+
/**
|
|
1092
|
+
* Send specific command to DocsViewer / Presentation / Slide app.
|
|
1093
|
+
*
|
|
1094
|
+
* Static docs and Presentation do not have animation steps, so `prevStep` / `nextStep`
|
|
1095
|
+
* are treated as `prevPage` / `nextPage`.
|
|
1096
|
+
*/
|
|
1097
|
+
public dispatchDocsEvent(event: DocsEvent, options: DocsEventOptions = {}): boolean {
|
|
1098
|
+
const appId = options.appId || this.focused;
|
|
1099
|
+
if (!appId) {
|
|
1100
|
+
console.warn("not found " + (options.appId || "focused app"));
|
|
1101
|
+
return false;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
const app = this.queryOne(appId);
|
|
1105
|
+
if (!app) {
|
|
1106
|
+
console.warn("not found app with id " + appId);
|
|
1107
|
+
return false;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
const isDocsViewerApp =
|
|
1111
|
+
appId.startsWith(`${BuiltinApps.DocsViewer}-`) || app.kind === BuiltinApps.DocsViewer;
|
|
1112
|
+
const isPresentationApp =
|
|
1113
|
+
appId.startsWith(`${PresentationAppKind}-`) || app.kind === PresentationAppKind;
|
|
1114
|
+
const isSlideApp = appId.startsWith(`${SlideAppKind}-`) || app.kind === SlideAppKind;
|
|
1115
|
+
let appKind = app.kind;
|
|
1116
|
+
if (isDocsViewerApp) {
|
|
1117
|
+
appKind = BuiltinApps.DocsViewer;
|
|
1118
|
+
} else if (isPresentationApp) {
|
|
1119
|
+
appKind = PresentationAppKind;
|
|
1120
|
+
} else if (isSlideApp) {
|
|
1121
|
+
appKind = SlideAppKind;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
if (!WindowManager.registered.has(appKind)) {
|
|
1125
|
+
console.warn("not registered app kind " + appKind);
|
|
1126
|
+
return false;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
let page: number | undefined, input: HTMLInputElement | null, scale: number | undefined;
|
|
1130
|
+
|
|
1131
|
+
if (isDocsViewerApp) {
|
|
1132
|
+
const dom = app.box?.$footer;
|
|
1133
|
+
if (!dom) {
|
|
1134
|
+
console.warn("not found app with id " + appId);
|
|
1135
|
+
return false;
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
const click = (el: Element | null) => {
|
|
1139
|
+
el && el.dispatchEvent(new MouseEvent("click"));
|
|
1140
|
+
};
|
|
1141
|
+
|
|
1142
|
+
switch (event) {
|
|
1143
|
+
case "prevPage":
|
|
1144
|
+
case "prevStep":
|
|
1145
|
+
click(dom.querySelector('button[class$="btn-page-back"]'));
|
|
1146
|
+
break;
|
|
1147
|
+
case "nextPage":
|
|
1148
|
+
case "nextStep":
|
|
1149
|
+
click(dom.querySelector('button[class$="btn-page-next"]'));
|
|
1150
|
+
break;
|
|
1151
|
+
case "jumpToPage":
|
|
1152
|
+
page = options.page;
|
|
1153
|
+
input = dom.querySelector('input[class$="page-number-input"]');
|
|
1154
|
+
if (!input || typeof page !== "number") {
|
|
1155
|
+
console.warn("failed to jump" + (page ? " to page " + page : ""));
|
|
1156
|
+
return false;
|
|
1157
|
+
}
|
|
1158
|
+
input.value = "" + page;
|
|
1159
|
+
input.dispatchEvent(new InputEvent("change"));
|
|
1160
|
+
break;
|
|
1161
|
+
case "scalePage":
|
|
1162
|
+
console.warn("not supported event " + event + " for app kind " + appKind);
|
|
1163
|
+
return false;
|
|
1164
|
+
default:
|
|
1165
|
+
console.warn("unknown event " + event);
|
|
1166
|
+
return false;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
return true;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
if (isPresentationApp) {
|
|
1173
|
+
const controller = app.appResult as PresentationDocsAppResult | undefined;
|
|
1174
|
+
if (!controller) {
|
|
1175
|
+
console.warn("not found app with id " + appId);
|
|
1176
|
+
return false;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
switch (event) {
|
|
1180
|
+
case "prevPage":
|
|
1181
|
+
case "prevStep":
|
|
1182
|
+
return controller.prevPage();
|
|
1183
|
+
case "nextPage":
|
|
1184
|
+
case "nextStep":
|
|
1185
|
+
return controller.nextPage();
|
|
1186
|
+
case "jumpToPage":
|
|
1187
|
+
page = options.page;
|
|
1188
|
+
if (typeof page !== "number") {
|
|
1189
|
+
console.warn("failed to jump" + (page ? " to page " + page : ""));
|
|
1190
|
+
return false;
|
|
1191
|
+
}
|
|
1192
|
+
return controller.jumpPage(page - 1);
|
|
1193
|
+
case "scalePage":
|
|
1194
|
+
scale = options.scale;
|
|
1195
|
+
if (!isValidDocsPageScale(scale)) {
|
|
1196
|
+
console.warn("failed to scale, scale should be a number from 1 to 4");
|
|
1197
|
+
return false;
|
|
1198
|
+
}
|
|
1199
|
+
try {
|
|
1200
|
+
controller.moveCamera({
|
|
1201
|
+
centerX: 0,
|
|
1202
|
+
centerY: 0,
|
|
1203
|
+
scale: controller.getOriginScale() * scale,
|
|
1204
|
+
});
|
|
1205
|
+
return true;
|
|
1206
|
+
} catch (error) {
|
|
1207
|
+
console.warn(error);
|
|
1208
|
+
return false;
|
|
1209
|
+
}
|
|
1210
|
+
default:
|
|
1211
|
+
console.warn("unknown event " + event);
|
|
1212
|
+
return false;
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
if (isSlideApp) {
|
|
1217
|
+
const controller = app.appResult as SlideDocsAppResult | undefined;
|
|
1218
|
+
if (!controller) {
|
|
1219
|
+
console.warn("not found app with id " + appId);
|
|
1220
|
+
return false;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
switch (event) {
|
|
1224
|
+
case "prevPage":
|
|
1225
|
+
return controller.prevPage();
|
|
1226
|
+
case "nextPage":
|
|
1227
|
+
return controller.nextPage();
|
|
1228
|
+
case "prevStep":
|
|
1229
|
+
return controller.prevStep();
|
|
1230
|
+
case "nextStep":
|
|
1231
|
+
return controller.nextStep();
|
|
1232
|
+
case "jumpToPage":
|
|
1233
|
+
page = options.page;
|
|
1234
|
+
if (typeof page !== "number") {
|
|
1235
|
+
console.warn("failed to jump" + (page ? " to page " + page : ""));
|
|
1236
|
+
return false;
|
|
1237
|
+
}
|
|
1238
|
+
return controller.jumpToPage(page);
|
|
1239
|
+
case "scalePage":
|
|
1240
|
+
scale = options.scale;
|
|
1241
|
+
if (!isValidDocsPageScale(scale)) {
|
|
1242
|
+
console.warn("failed to scale, scale should be a number from 1 to 4");
|
|
1243
|
+
return false;
|
|
1244
|
+
}
|
|
1245
|
+
controller.scaleView(scale);
|
|
1246
|
+
return true;
|
|
1247
|
+
default:
|
|
1248
|
+
console.warn("unknown event " + event);
|
|
1249
|
+
return false;
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
console.warn("not supported app kind " + app.kind);
|
|
1254
|
+
return false;
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1010
1257
|
/**
|
|
1011
1258
|
* 关闭 APP
|
|
1012
1259
|
*/
|
|
@@ -1081,7 +1328,7 @@ export class WindowManager
|
|
|
1081
1328
|
WindowManager.playground.parentNode?.removeChild(WindowManager.playground);
|
|
1082
1329
|
}
|
|
1083
1330
|
WindowManager.params = undefined;
|
|
1084
|
-
this.emitter.off(
|
|
1331
|
+
this.emitter.off("mainViewScenePathChange", this.onMainViewScenePathChangeHandler);
|
|
1085
1332
|
this._iframeBridge?.destroy();
|
|
1086
1333
|
this._iframeBridge = undefined;
|
|
1087
1334
|
log("Destroyed");
|
|
@@ -1113,7 +1360,10 @@ export class WindowManager
|
|
|
1113
1360
|
if (this.canOperate) {
|
|
1114
1361
|
this.setAttributes(attributes);
|
|
1115
1362
|
if (this.attributesDeboundceLog) {
|
|
1116
|
-
this.attributesDeboundceLog.logDebouncedShallowMerge(
|
|
1363
|
+
this.attributesDeboundceLog.logDebouncedShallowMerge(
|
|
1364
|
+
"safeSetAttributes",
|
|
1365
|
+
attributes
|
|
1366
|
+
);
|
|
1117
1367
|
}
|
|
1118
1368
|
}
|
|
1119
1369
|
}
|
|
@@ -1134,7 +1384,10 @@ export class WindowManager
|
|
|
1134
1384
|
public cleanCurrentScene(): void {
|
|
1135
1385
|
log("clean current scene");
|
|
1136
1386
|
this.focusedView?.cleanCurrentScene();
|
|
1137
|
-
this.Logger &&
|
|
1387
|
+
this.Logger &&
|
|
1388
|
+
this.Logger.info(
|
|
1389
|
+
`[WindowManager]: cleanCurrentScene ${this.focusedView?.focusScenePath}`
|
|
1390
|
+
);
|
|
1138
1391
|
}
|
|
1139
1392
|
|
|
1140
1393
|
public redo(): number {
|
|
@@ -1147,7 +1400,8 @@ export class WindowManager
|
|
|
1147
1400
|
|
|
1148
1401
|
public delete(): void {
|
|
1149
1402
|
this.focusedView?.delete();
|
|
1150
|
-
this.Logger &&
|
|
1403
|
+
this.Logger &&
|
|
1404
|
+
this.Logger.info(`[WindowManager]: delete ${this.focusedView?.focusScenePath}`);
|
|
1151
1405
|
}
|
|
1152
1406
|
|
|
1153
1407
|
public copy(): void {
|
|
@@ -1257,6 +1511,7 @@ setupBuiltin();
|
|
|
1257
1511
|
export * from "./typings";
|
|
1258
1512
|
|
|
1259
1513
|
export { BuiltinApps } from "./BuiltinApps";
|
|
1514
|
+
export type { BuiltinAppOptions } from "./BuiltinApps";
|
|
1260
1515
|
export type { PublicEvent } from "./callback";
|
|
1261
1516
|
|
|
1262
1517
|
export * from "./ExtendPluginManager";
|