@netless/window-manager 1.0.0-canary.49 → 1.0.0-canary.51
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/index.cjs.js +82 -30
- package/dist/index.es.js +82 -30
- package/dist/index.umd.js +82 -30
- package/dist/src/Register/index.d.ts +4 -2
- package/dist/src/Register/loader.d.ts +1 -1
- package/dist/src/Register/storage.d.ts +6 -3
- package/dist/src/index.d.ts +1 -0
- package/dist/src/typings.d.ts +3 -1
- package/package.json +1 -1
- package/src/Register/index.ts +36 -14
- package/src/Register/loader.ts +20 -9
- package/src/Register/storage.ts +26 -5
- package/src/View/MainView.ts +1 -1
- package/src/index.ts +4 -4
- package/src/typings.ts +5 -1
package/dist/index.cjs.js
CHANGED
@@ -171,18 +171,27 @@ const emitter = new Emittery__default["default"]();
|
|
171
171
|
const DatabaseName = "__WindowManagerAppCache";
|
172
172
|
let db;
|
173
173
|
let store$1;
|
174
|
-
const initDb = async () => {
|
174
|
+
const initDb = async (appRegister2) => {
|
175
175
|
db = await createDb();
|
176
|
+
const items = await queryAll(db);
|
177
|
+
items.forEach((item) => {
|
178
|
+
appRegister2.downloaded.set(item.kind, item.url);
|
179
|
+
});
|
176
180
|
};
|
177
|
-
const setItem = (
|
181
|
+
const setItem = (kind, url, val) => {
|
178
182
|
if (!db)
|
179
183
|
return;
|
180
|
-
return addRecord(db, { kind
|
184
|
+
return addRecord(db, { kind, url, sourceCode: val });
|
181
185
|
};
|
182
|
-
const getItem = async (
|
186
|
+
const getItem = async (kind) => {
|
183
187
|
if (!db)
|
184
188
|
return null;
|
185
|
-
return await query(db,
|
189
|
+
return await query(db, kind);
|
190
|
+
};
|
191
|
+
const removeItem = (key) => {
|
192
|
+
if (!db)
|
193
|
+
return;
|
194
|
+
return deleteRecord(db, key);
|
186
195
|
};
|
187
196
|
function createDb() {
|
188
197
|
return new Promise((resolve, reject) => {
|
@@ -217,6 +226,14 @@ function query(db2, val) {
|
|
217
226
|
};
|
218
227
|
});
|
219
228
|
}
|
229
|
+
function queryAll(db2) {
|
230
|
+
return new Promise((resolve, reject) => {
|
231
|
+
const index2 = db2.transaction(["apps"]).objectStore("apps").index("kind");
|
232
|
+
const request = index2.getAll();
|
233
|
+
request.onerror = (e) => reject(e);
|
234
|
+
request.onsuccess = () => resolve(request.result);
|
235
|
+
});
|
236
|
+
}
|
220
237
|
function addRecord(db2, payload) {
|
221
238
|
return new Promise((resolve, reject) => {
|
222
239
|
const request = db2.transaction(["apps"], "readwrite").objectStore("apps").add(payload);
|
@@ -224,16 +241,23 @@ function addRecord(db2, payload) {
|
|
224
241
|
request.onerror = () => reject();
|
225
242
|
});
|
226
243
|
}
|
244
|
+
function deleteRecord(db2, key) {
|
245
|
+
return new Promise((resolve, reject) => {
|
246
|
+
const request = db2.transaction(["apps"], "readwrite").objectStore("apps").delete(key);
|
247
|
+
request.onsuccess = () => resolve();
|
248
|
+
request.onerror = () => reject();
|
249
|
+
});
|
250
|
+
}
|
227
251
|
const Prefix = "NetlessApp";
|
228
252
|
const TIMEOUT = 1e4;
|
229
|
-
const getScript = async (url) => {
|
230
|
-
const item = await getItem(
|
253
|
+
const getScript = async (kind, url) => {
|
254
|
+
const item = await getItem(kind);
|
231
255
|
if (item) {
|
232
256
|
return item.sourceCode;
|
233
257
|
} else {
|
234
258
|
const result = await fetchWithTimeout(url, { timeout: TIMEOUT });
|
235
259
|
const text2 = await result.text();
|
236
|
-
await setItem(url, text2);
|
260
|
+
await setItem(kind, url, text2);
|
237
261
|
return text2;
|
238
262
|
}
|
239
263
|
};
|
@@ -245,18 +269,25 @@ const executeScript = (text2, appName) => {
|
|
245
269
|
}
|
246
270
|
return result;
|
247
271
|
};
|
272
|
+
const emitSuccess = (kind, url) => {
|
273
|
+
callbacks.emit("loadApp", { kind, status: "success" });
|
274
|
+
appRegister.downloaded.set(kind, url);
|
275
|
+
};
|
276
|
+
const emitFailed = (kind, reason) => {
|
277
|
+
callbacks.emit("loadApp", { kind, status: "failed", reason });
|
278
|
+
};
|
248
279
|
const loadApp = async (url, key, name) => {
|
249
280
|
const appName = name || Prefix + key;
|
250
281
|
callbacks.emit("loadApp", { kind: key, status: "start" });
|
251
282
|
try {
|
252
|
-
const text2 = await getScript(url);
|
283
|
+
const text2 = await getScript(key, url);
|
253
284
|
if (!text2 || text2.length === 0) {
|
254
|
-
|
285
|
+
emitFailed(key, "script is empty");
|
255
286
|
return;
|
256
287
|
}
|
257
288
|
try {
|
258
289
|
const result = executeScript(text2, appName);
|
259
|
-
|
290
|
+
emitSuccess(key, url);
|
260
291
|
return result;
|
261
292
|
} catch (error) {
|
262
293
|
if (error.message.includes("Can only have one anonymous define call per script file")) {
|
@@ -265,13 +296,13 @@ const loadApp = async (url, key, name) => {
|
|
265
296
|
delete define.amd;
|
266
297
|
}
|
267
298
|
const result = executeScript(text2, appName);
|
268
|
-
|
299
|
+
emitSuccess(key, url);
|
269
300
|
return result;
|
270
301
|
}
|
271
|
-
|
302
|
+
emitFailed(key, error.message);
|
272
303
|
}
|
273
304
|
} catch (error) {
|
274
|
-
|
305
|
+
emitFailed(key, error.message);
|
275
306
|
}
|
276
307
|
};
|
277
308
|
async function fetchWithTimeout(resource, options) {
|
@@ -293,6 +324,7 @@ class AppRegister {
|
|
293
324
|
this.registered = /* @__PURE__ */ new Map();
|
294
325
|
this.appClassesCache = /* @__PURE__ */ new Map();
|
295
326
|
this.appClasses = /* @__PURE__ */ new Map();
|
327
|
+
this.downloaded = /* @__PURE__ */ new Map();
|
296
328
|
this.syncRegisterApp = null;
|
297
329
|
this.onSyncRegisterAppChange = (payload) => {
|
298
330
|
this.register({ kind: payload.kind, src: payload.src });
|
@@ -304,27 +336,35 @@ class AppRegister {
|
|
304
336
|
async register(params) {
|
305
337
|
this.appClassesCache.delete(params.kind);
|
306
338
|
this.registered.set(params.kind, params);
|
307
|
-
const
|
339
|
+
const paramSrc = params.src;
|
308
340
|
let downloadApp;
|
309
|
-
if (typeof
|
341
|
+
if (typeof paramSrc === "string") {
|
342
|
+
downloadApp = async () => {
|
343
|
+
const result = await loadApp(paramSrc, params.kind, params.name);
|
344
|
+
if (result.__esModule) {
|
345
|
+
return result.default;
|
346
|
+
}
|
347
|
+
return result;
|
348
|
+
};
|
349
|
+
if (this.syncRegisterApp) {
|
350
|
+
this.syncRegisterApp({ kind: params.kind, src: paramSrc, name: params.name });
|
351
|
+
}
|
352
|
+
}
|
353
|
+
if (typeof paramSrc === "function") {
|
310
354
|
downloadApp = async () => {
|
311
|
-
let appClass = await
|
355
|
+
let appClass = await paramSrc();
|
312
356
|
if (appClass) {
|
313
|
-
if (appClass.__esModule) {
|
357
|
+
if (appClass.__esModule || appClass.default) {
|
314
358
|
appClass = appClass.default;
|
315
359
|
}
|
316
360
|
return appClass;
|
317
361
|
} else {
|
318
|
-
throw new Error(`[WindowManager]: load remote script failed, ${
|
362
|
+
throw new Error(`[WindowManager]: load remote script failed, ${paramSrc}`);
|
319
363
|
}
|
320
364
|
};
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
} else if (typeof srcOrAppOrFunction === "function") {
|
325
|
-
downloadApp = srcOrAppOrFunction;
|
326
|
-
} else {
|
327
|
-
downloadApp = async () => srcOrAppOrFunction;
|
365
|
+
}
|
366
|
+
if (typeof paramSrc === "object") {
|
367
|
+
downloadApp = async () => paramSrc;
|
328
368
|
}
|
329
369
|
this.appClasses.set(params.kind, async () => {
|
330
370
|
let app = this.appClassesCache.get(params.kind);
|
@@ -341,10 +381,21 @@ class AppRegister {
|
|
341
381
|
}
|
342
382
|
}
|
343
383
|
}
|
384
|
+
downloadApp(kind) {
|
385
|
+
const src = this.registered.get(kind);
|
386
|
+
if (src && typeof src.src === "string") {
|
387
|
+
return loadApp(src.src, src.kind, src.name);
|
388
|
+
}
|
389
|
+
}
|
390
|
+
async removeDownloaded(kind) {
|
391
|
+
await removeItem(kind);
|
392
|
+
this.downloaded.delete(kind);
|
393
|
+
}
|
344
394
|
unregister(kind) {
|
345
395
|
this.appClasses.delete(kind);
|
346
396
|
this.appClassesCache.delete(kind);
|
347
397
|
this.registered.delete(kind);
|
398
|
+
this.removeDownloaded(kind);
|
348
399
|
const kindEmitter = this.kindEmitters.get(kind);
|
349
400
|
if (kindEmitter) {
|
350
401
|
kindEmitter.clearListeners();
|
@@ -2416,6 +2467,7 @@ class MainViewProxy {
|
|
2416
2467
|
start() {
|
2417
2468
|
if (this.started)
|
2418
2469
|
return;
|
2470
|
+
this.removeCameraListener();
|
2419
2471
|
this.addCameraListener();
|
2420
2472
|
this.addCameraReaction();
|
2421
2473
|
this.started = true;
|
@@ -2494,7 +2546,6 @@ class MainViewProxy {
|
|
2494
2546
|
this.view.callbacks.off("onSizeUpdated", this.onCameraOrSizeUpdated);
|
2495
2547
|
}
|
2496
2548
|
stop() {
|
2497
|
-
this.removeCameraListener();
|
2498
2549
|
this.manager.refresher.remove(Fields.MainViewCamera);
|
2499
2550
|
this.manager.refresher.remove(Fields.MainViewSize);
|
2500
2551
|
this.started = false;
|
@@ -11637,7 +11688,7 @@ const reconnectRefresher = new ReconnectRefresher({ emitter });
|
|
11637
11688
|
const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
|
11638
11689
|
constructor(context) {
|
11639
11690
|
super(context);
|
11640
|
-
this.version = "1.0.0-canary.
|
11691
|
+
this.version = "1.0.0-canary.51";
|
11641
11692
|
this.dependencies = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.1.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jsdom": "^19.0.0", "less": "^4.1.3", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "typescript": "^4.5.5", "vite": "^2.5.3", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "2.16.26" } };
|
11642
11693
|
this.emitter = callbacks;
|
11643
11694
|
this.viewMode = whiteWebSdk.ViewMode.Broadcaster;
|
@@ -11710,8 +11761,8 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
|
|
11710
11761
|
const cursor = params.cursor;
|
11711
11762
|
_WindowManager.params = params;
|
11712
11763
|
_WindowManager.displayer = params.room;
|
11713
|
-
checkVersion();
|
11714
11764
|
let manager = void 0;
|
11765
|
+
checkVersion();
|
11715
11766
|
if (whiteWebSdk.isRoom(room)) {
|
11716
11767
|
if (room.phase !== whiteWebSdk.RoomPhase.Connected) {
|
11717
11768
|
throw new Error("[WindowManager]: Room only Connected can be mount");
|
@@ -11768,7 +11819,7 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
|
|
11768
11819
|
emitter.emit("onCreated");
|
11769
11820
|
_WindowManager.isCreated = true;
|
11770
11821
|
try {
|
11771
|
-
await initDb();
|
11822
|
+
await initDb(appRegister);
|
11772
11823
|
} catch (error) {
|
11773
11824
|
console.warn("[WindowManager]: indexedDB open failed");
|
11774
11825
|
console.log(error);
|
@@ -12420,6 +12471,7 @@ WindowManager.kind = "WindowManager";
|
|
12420
12471
|
WindowManager.debug = false;
|
12421
12472
|
WindowManager.containerSizeRatio = DEFAULT_CONTAINER_RATIO;
|
12422
12473
|
WindowManager.isCreated = false;
|
12474
|
+
WindowManager.registry = appRegister;
|
12423
12475
|
setupBuiltin();
|
12424
12476
|
exports.AppCreateError = AppCreateError;
|
12425
12477
|
exports.AppManagerNotInitError = AppManagerNotInitError;
|
package/dist/index.es.js
CHANGED
@@ -164,18 +164,27 @@ const emitter = new Emittery();
|
|
164
164
|
const DatabaseName = "__WindowManagerAppCache";
|
165
165
|
let db;
|
166
166
|
let store$1;
|
167
|
-
const initDb = async () => {
|
167
|
+
const initDb = async (appRegister2) => {
|
168
168
|
db = await createDb();
|
169
|
+
const items = await queryAll(db);
|
170
|
+
items.forEach((item) => {
|
171
|
+
appRegister2.downloaded.set(item.kind, item.url);
|
172
|
+
});
|
169
173
|
};
|
170
|
-
const setItem = (
|
174
|
+
const setItem = (kind, url, val) => {
|
171
175
|
if (!db)
|
172
176
|
return;
|
173
|
-
return addRecord(db, { kind
|
177
|
+
return addRecord(db, { kind, url, sourceCode: val });
|
174
178
|
};
|
175
|
-
const getItem = async (
|
179
|
+
const getItem = async (kind) => {
|
176
180
|
if (!db)
|
177
181
|
return null;
|
178
|
-
return await query(db,
|
182
|
+
return await query(db, kind);
|
183
|
+
};
|
184
|
+
const removeItem = (key) => {
|
185
|
+
if (!db)
|
186
|
+
return;
|
187
|
+
return deleteRecord(db, key);
|
179
188
|
};
|
180
189
|
function createDb() {
|
181
190
|
return new Promise((resolve, reject) => {
|
@@ -210,6 +219,14 @@ function query(db2, val) {
|
|
210
219
|
};
|
211
220
|
});
|
212
221
|
}
|
222
|
+
function queryAll(db2) {
|
223
|
+
return new Promise((resolve, reject) => {
|
224
|
+
const index2 = db2.transaction(["apps"]).objectStore("apps").index("kind");
|
225
|
+
const request = index2.getAll();
|
226
|
+
request.onerror = (e) => reject(e);
|
227
|
+
request.onsuccess = () => resolve(request.result);
|
228
|
+
});
|
229
|
+
}
|
213
230
|
function addRecord(db2, payload) {
|
214
231
|
return new Promise((resolve, reject) => {
|
215
232
|
const request = db2.transaction(["apps"], "readwrite").objectStore("apps").add(payload);
|
@@ -217,16 +234,23 @@ function addRecord(db2, payload) {
|
|
217
234
|
request.onerror = () => reject();
|
218
235
|
});
|
219
236
|
}
|
237
|
+
function deleteRecord(db2, key) {
|
238
|
+
return new Promise((resolve, reject) => {
|
239
|
+
const request = db2.transaction(["apps"], "readwrite").objectStore("apps").delete(key);
|
240
|
+
request.onsuccess = () => resolve();
|
241
|
+
request.onerror = () => reject();
|
242
|
+
});
|
243
|
+
}
|
220
244
|
const Prefix = "NetlessApp";
|
221
245
|
const TIMEOUT = 1e4;
|
222
|
-
const getScript = async (url) => {
|
223
|
-
const item = await getItem(
|
246
|
+
const getScript = async (kind, url) => {
|
247
|
+
const item = await getItem(kind);
|
224
248
|
if (item) {
|
225
249
|
return item.sourceCode;
|
226
250
|
} else {
|
227
251
|
const result = await fetchWithTimeout(url, { timeout: TIMEOUT });
|
228
252
|
const text2 = await result.text();
|
229
|
-
await setItem(url, text2);
|
253
|
+
await setItem(kind, url, text2);
|
230
254
|
return text2;
|
231
255
|
}
|
232
256
|
};
|
@@ -238,18 +262,25 @@ const executeScript = (text2, appName) => {
|
|
238
262
|
}
|
239
263
|
return result;
|
240
264
|
};
|
265
|
+
const emitSuccess = (kind, url) => {
|
266
|
+
callbacks.emit("loadApp", { kind, status: "success" });
|
267
|
+
appRegister.downloaded.set(kind, url);
|
268
|
+
};
|
269
|
+
const emitFailed = (kind, reason) => {
|
270
|
+
callbacks.emit("loadApp", { kind, status: "failed", reason });
|
271
|
+
};
|
241
272
|
const loadApp = async (url, key, name) => {
|
242
273
|
const appName = name || Prefix + key;
|
243
274
|
callbacks.emit("loadApp", { kind: key, status: "start" });
|
244
275
|
try {
|
245
|
-
const text2 = await getScript(url);
|
276
|
+
const text2 = await getScript(key, url);
|
246
277
|
if (!text2 || text2.length === 0) {
|
247
|
-
|
278
|
+
emitFailed(key, "script is empty");
|
248
279
|
return;
|
249
280
|
}
|
250
281
|
try {
|
251
282
|
const result = executeScript(text2, appName);
|
252
|
-
|
283
|
+
emitSuccess(key, url);
|
253
284
|
return result;
|
254
285
|
} catch (error) {
|
255
286
|
if (error.message.includes("Can only have one anonymous define call per script file")) {
|
@@ -258,13 +289,13 @@ const loadApp = async (url, key, name) => {
|
|
258
289
|
delete define.amd;
|
259
290
|
}
|
260
291
|
const result = executeScript(text2, appName);
|
261
|
-
|
292
|
+
emitSuccess(key, url);
|
262
293
|
return result;
|
263
294
|
}
|
264
|
-
|
295
|
+
emitFailed(key, error.message);
|
265
296
|
}
|
266
297
|
} catch (error) {
|
267
|
-
|
298
|
+
emitFailed(key, error.message);
|
268
299
|
}
|
269
300
|
};
|
270
301
|
async function fetchWithTimeout(resource, options) {
|
@@ -286,6 +317,7 @@ class AppRegister {
|
|
286
317
|
this.registered = /* @__PURE__ */ new Map();
|
287
318
|
this.appClassesCache = /* @__PURE__ */ new Map();
|
288
319
|
this.appClasses = /* @__PURE__ */ new Map();
|
320
|
+
this.downloaded = /* @__PURE__ */ new Map();
|
289
321
|
this.syncRegisterApp = null;
|
290
322
|
this.onSyncRegisterAppChange = (payload) => {
|
291
323
|
this.register({ kind: payload.kind, src: payload.src });
|
@@ -297,27 +329,35 @@ class AppRegister {
|
|
297
329
|
async register(params) {
|
298
330
|
this.appClassesCache.delete(params.kind);
|
299
331
|
this.registered.set(params.kind, params);
|
300
|
-
const
|
332
|
+
const paramSrc = params.src;
|
301
333
|
let downloadApp;
|
302
|
-
if (typeof
|
334
|
+
if (typeof paramSrc === "string") {
|
335
|
+
downloadApp = async () => {
|
336
|
+
const result = await loadApp(paramSrc, params.kind, params.name);
|
337
|
+
if (result.__esModule) {
|
338
|
+
return result.default;
|
339
|
+
}
|
340
|
+
return result;
|
341
|
+
};
|
342
|
+
if (this.syncRegisterApp) {
|
343
|
+
this.syncRegisterApp({ kind: params.kind, src: paramSrc, name: params.name });
|
344
|
+
}
|
345
|
+
}
|
346
|
+
if (typeof paramSrc === "function") {
|
303
347
|
downloadApp = async () => {
|
304
|
-
let appClass = await
|
348
|
+
let appClass = await paramSrc();
|
305
349
|
if (appClass) {
|
306
|
-
if (appClass.__esModule) {
|
350
|
+
if (appClass.__esModule || appClass.default) {
|
307
351
|
appClass = appClass.default;
|
308
352
|
}
|
309
353
|
return appClass;
|
310
354
|
} else {
|
311
|
-
throw new Error(`[WindowManager]: load remote script failed, ${
|
355
|
+
throw new Error(`[WindowManager]: load remote script failed, ${paramSrc}`);
|
312
356
|
}
|
313
357
|
};
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
} else if (typeof srcOrAppOrFunction === "function") {
|
318
|
-
downloadApp = srcOrAppOrFunction;
|
319
|
-
} else {
|
320
|
-
downloadApp = async () => srcOrAppOrFunction;
|
358
|
+
}
|
359
|
+
if (typeof paramSrc === "object") {
|
360
|
+
downloadApp = async () => paramSrc;
|
321
361
|
}
|
322
362
|
this.appClasses.set(params.kind, async () => {
|
323
363
|
let app = this.appClassesCache.get(params.kind);
|
@@ -334,10 +374,21 @@ class AppRegister {
|
|
334
374
|
}
|
335
375
|
}
|
336
376
|
}
|
377
|
+
downloadApp(kind) {
|
378
|
+
const src = this.registered.get(kind);
|
379
|
+
if (src && typeof src.src === "string") {
|
380
|
+
return loadApp(src.src, src.kind, src.name);
|
381
|
+
}
|
382
|
+
}
|
383
|
+
async removeDownloaded(kind) {
|
384
|
+
await removeItem(kind);
|
385
|
+
this.downloaded.delete(kind);
|
386
|
+
}
|
337
387
|
unregister(kind) {
|
338
388
|
this.appClasses.delete(kind);
|
339
389
|
this.appClassesCache.delete(kind);
|
340
390
|
this.registered.delete(kind);
|
391
|
+
this.removeDownloaded(kind);
|
341
392
|
const kindEmitter = this.kindEmitters.get(kind);
|
342
393
|
if (kindEmitter) {
|
343
394
|
kindEmitter.clearListeners();
|
@@ -2409,6 +2460,7 @@ class MainViewProxy {
|
|
2409
2460
|
start() {
|
2410
2461
|
if (this.started)
|
2411
2462
|
return;
|
2463
|
+
this.removeCameraListener();
|
2412
2464
|
this.addCameraListener();
|
2413
2465
|
this.addCameraReaction();
|
2414
2466
|
this.started = true;
|
@@ -2487,7 +2539,6 @@ class MainViewProxy {
|
|
2487
2539
|
this.view.callbacks.off("onSizeUpdated", this.onCameraOrSizeUpdated);
|
2488
2540
|
}
|
2489
2541
|
stop() {
|
2490
|
-
this.removeCameraListener();
|
2491
2542
|
this.manager.refresher.remove(Fields.MainViewCamera);
|
2492
2543
|
this.manager.refresher.remove(Fields.MainViewSize);
|
2493
2544
|
this.started = false;
|
@@ -11630,7 +11681,7 @@ const reconnectRefresher = new ReconnectRefresher({ emitter });
|
|
11630
11681
|
const _WindowManager = class extends InvisiblePlugin {
|
11631
11682
|
constructor(context) {
|
11632
11683
|
super(context);
|
11633
|
-
this.version = "1.0.0-canary.
|
11684
|
+
this.version = "1.0.0-canary.51";
|
11634
11685
|
this.dependencies = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.1.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jsdom": "^19.0.0", "less": "^4.1.3", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "typescript": "^4.5.5", "vite": "^2.5.3", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "2.16.26" } };
|
11635
11686
|
this.emitter = callbacks;
|
11636
11687
|
this.viewMode = ViewMode.Broadcaster;
|
@@ -11703,8 +11754,8 @@ const _WindowManager = class extends InvisiblePlugin {
|
|
11703
11754
|
const cursor = params.cursor;
|
11704
11755
|
_WindowManager.params = params;
|
11705
11756
|
_WindowManager.displayer = params.room;
|
11706
|
-
checkVersion();
|
11707
11757
|
let manager = void 0;
|
11758
|
+
checkVersion();
|
11708
11759
|
if (isRoom(room)) {
|
11709
11760
|
if (room.phase !== RoomPhase.Connected) {
|
11710
11761
|
throw new Error("[WindowManager]: Room only Connected can be mount");
|
@@ -11761,7 +11812,7 @@ const _WindowManager = class extends InvisiblePlugin {
|
|
11761
11812
|
emitter.emit("onCreated");
|
11762
11813
|
_WindowManager.isCreated = true;
|
11763
11814
|
try {
|
11764
|
-
await initDb();
|
11815
|
+
await initDb(appRegister);
|
11765
11816
|
} catch (error) {
|
11766
11817
|
console.warn("[WindowManager]: indexedDB open failed");
|
11767
11818
|
console.log(error);
|
@@ -12413,5 +12464,6 @@ WindowManager.kind = "WindowManager";
|
|
12413
12464
|
WindowManager.debug = false;
|
12414
12465
|
WindowManager.containerSizeRatio = DEFAULT_CONTAINER_RATIO;
|
12415
12466
|
WindowManager.isCreated = false;
|
12467
|
+
WindowManager.registry = appRegister;
|
12416
12468
|
setupBuiltin();
|
12417
12469
|
export { AppCreateError, AppManagerNotInitError, AppNotRegisterError, BindContainerRoomPhaseInvalidError, BoxManagerNotInitializeError, BoxNotCreatedError, BuiltinApps, BuiltinAppsMap, InvalidScenePath, ParamsInvalidError, WhiteWebSDKInvalidError, WindowManager, calculateNextIndex, reconnectRefresher };
|
package/dist/index.umd.js
CHANGED
@@ -165,18 +165,27 @@ var __objRest = (source, exclude) => {
|
|
165
165
|
const DatabaseName = "__WindowManagerAppCache";
|
166
166
|
let db;
|
167
167
|
let store$1;
|
168
|
-
const initDb = async () => {
|
168
|
+
const initDb = async (appRegister2) => {
|
169
169
|
db = await createDb();
|
170
|
+
const items = await queryAll(db);
|
171
|
+
items.forEach((item) => {
|
172
|
+
appRegister2.downloaded.set(item.kind, item.url);
|
173
|
+
});
|
170
174
|
};
|
171
|
-
const setItem = (
|
175
|
+
const setItem = (kind, url, val) => {
|
172
176
|
if (!db)
|
173
177
|
return;
|
174
|
-
return addRecord(db, { kind
|
178
|
+
return addRecord(db, { kind, url, sourceCode: val });
|
175
179
|
};
|
176
|
-
const getItem = async (
|
180
|
+
const getItem = async (kind) => {
|
177
181
|
if (!db)
|
178
182
|
return null;
|
179
|
-
return await query(db,
|
183
|
+
return await query(db, kind);
|
184
|
+
};
|
185
|
+
const removeItem = (key) => {
|
186
|
+
if (!db)
|
187
|
+
return;
|
188
|
+
return deleteRecord(db, key);
|
180
189
|
};
|
181
190
|
function createDb() {
|
182
191
|
return new Promise((resolve, reject) => {
|
@@ -211,6 +220,14 @@ var __objRest = (source, exclude) => {
|
|
211
220
|
};
|
212
221
|
});
|
213
222
|
}
|
223
|
+
function queryAll(db2) {
|
224
|
+
return new Promise((resolve, reject) => {
|
225
|
+
const index2 = db2.transaction(["apps"]).objectStore("apps").index("kind");
|
226
|
+
const request = index2.getAll();
|
227
|
+
request.onerror = (e) => reject(e);
|
228
|
+
request.onsuccess = () => resolve(request.result);
|
229
|
+
});
|
230
|
+
}
|
214
231
|
function addRecord(db2, payload) {
|
215
232
|
return new Promise((resolve, reject) => {
|
216
233
|
const request = db2.transaction(["apps"], "readwrite").objectStore("apps").add(payload);
|
@@ -218,16 +235,23 @@ var __objRest = (source, exclude) => {
|
|
218
235
|
request.onerror = () => reject();
|
219
236
|
});
|
220
237
|
}
|
238
|
+
function deleteRecord(db2, key) {
|
239
|
+
return new Promise((resolve, reject) => {
|
240
|
+
const request = db2.transaction(["apps"], "readwrite").objectStore("apps").delete(key);
|
241
|
+
request.onsuccess = () => resolve();
|
242
|
+
request.onerror = () => reject();
|
243
|
+
});
|
244
|
+
}
|
221
245
|
const Prefix = "NetlessApp";
|
222
246
|
const TIMEOUT = 1e4;
|
223
|
-
const getScript = async (url) => {
|
224
|
-
const item = await getItem(
|
247
|
+
const getScript = async (kind, url) => {
|
248
|
+
const item = await getItem(kind);
|
225
249
|
if (item) {
|
226
250
|
return item.sourceCode;
|
227
251
|
} else {
|
228
252
|
const result = await fetchWithTimeout(url, { timeout: TIMEOUT });
|
229
253
|
const text2 = await result.text();
|
230
|
-
await setItem(url, text2);
|
254
|
+
await setItem(kind, url, text2);
|
231
255
|
return text2;
|
232
256
|
}
|
233
257
|
};
|
@@ -239,18 +263,25 @@ var __objRest = (source, exclude) => {
|
|
239
263
|
}
|
240
264
|
return result;
|
241
265
|
};
|
266
|
+
const emitSuccess = (kind, url) => {
|
267
|
+
callbacks.emit("loadApp", { kind, status: "success" });
|
268
|
+
appRegister.downloaded.set(kind, url);
|
269
|
+
};
|
270
|
+
const emitFailed = (kind, reason) => {
|
271
|
+
callbacks.emit("loadApp", { kind, status: "failed", reason });
|
272
|
+
};
|
242
273
|
const loadApp = async (url, key, name) => {
|
243
274
|
const appName = name || Prefix + key;
|
244
275
|
callbacks.emit("loadApp", { kind: key, status: "start" });
|
245
276
|
try {
|
246
|
-
const text2 = await getScript(url);
|
277
|
+
const text2 = await getScript(key, url);
|
247
278
|
if (!text2 || text2.length === 0) {
|
248
|
-
|
279
|
+
emitFailed(key, "script is empty");
|
249
280
|
return;
|
250
281
|
}
|
251
282
|
try {
|
252
283
|
const result = executeScript(text2, appName);
|
253
|
-
|
284
|
+
emitSuccess(key, url);
|
254
285
|
return result;
|
255
286
|
} catch (error) {
|
256
287
|
if (error.message.includes("Can only have one anonymous define call per script file")) {
|
@@ -259,13 +290,13 @@ var __objRest = (source, exclude) => {
|
|
259
290
|
delete define2.amd;
|
260
291
|
}
|
261
292
|
const result = executeScript(text2, appName);
|
262
|
-
|
293
|
+
emitSuccess(key, url);
|
263
294
|
return result;
|
264
295
|
}
|
265
|
-
|
296
|
+
emitFailed(key, error.message);
|
266
297
|
}
|
267
298
|
} catch (error) {
|
268
|
-
|
299
|
+
emitFailed(key, error.message);
|
269
300
|
}
|
270
301
|
};
|
271
302
|
async function fetchWithTimeout(resource, options) {
|
@@ -287,6 +318,7 @@ var __objRest = (source, exclude) => {
|
|
287
318
|
this.registered = /* @__PURE__ */ new Map();
|
288
319
|
this.appClassesCache = /* @__PURE__ */ new Map();
|
289
320
|
this.appClasses = /* @__PURE__ */ new Map();
|
321
|
+
this.downloaded = /* @__PURE__ */ new Map();
|
290
322
|
this.syncRegisterApp = null;
|
291
323
|
this.onSyncRegisterAppChange = (payload) => {
|
292
324
|
this.register({ kind: payload.kind, src: payload.src });
|
@@ -298,27 +330,35 @@ var __objRest = (source, exclude) => {
|
|
298
330
|
async register(params) {
|
299
331
|
this.appClassesCache.delete(params.kind);
|
300
332
|
this.registered.set(params.kind, params);
|
301
|
-
const
|
333
|
+
const paramSrc = params.src;
|
302
334
|
let downloadApp;
|
303
|
-
if (typeof
|
335
|
+
if (typeof paramSrc === "string") {
|
336
|
+
downloadApp = async () => {
|
337
|
+
const result = await loadApp(paramSrc, params.kind, params.name);
|
338
|
+
if (result.__esModule) {
|
339
|
+
return result.default;
|
340
|
+
}
|
341
|
+
return result;
|
342
|
+
};
|
343
|
+
if (this.syncRegisterApp) {
|
344
|
+
this.syncRegisterApp({ kind: params.kind, src: paramSrc, name: params.name });
|
345
|
+
}
|
346
|
+
}
|
347
|
+
if (typeof paramSrc === "function") {
|
304
348
|
downloadApp = async () => {
|
305
|
-
let appClass = await
|
349
|
+
let appClass = await paramSrc();
|
306
350
|
if (appClass) {
|
307
|
-
if (appClass.__esModule) {
|
351
|
+
if (appClass.__esModule || appClass.default) {
|
308
352
|
appClass = appClass.default;
|
309
353
|
}
|
310
354
|
return appClass;
|
311
355
|
} else {
|
312
|
-
throw new Error(`[WindowManager]: load remote script failed, ${
|
356
|
+
throw new Error(`[WindowManager]: load remote script failed, ${paramSrc}`);
|
313
357
|
}
|
314
358
|
};
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
} else if (typeof srcOrAppOrFunction === "function") {
|
319
|
-
downloadApp = srcOrAppOrFunction;
|
320
|
-
} else {
|
321
|
-
downloadApp = async () => srcOrAppOrFunction;
|
359
|
+
}
|
360
|
+
if (typeof paramSrc === "object") {
|
361
|
+
downloadApp = async () => paramSrc;
|
322
362
|
}
|
323
363
|
this.appClasses.set(params.kind, async () => {
|
324
364
|
let app = this.appClassesCache.get(params.kind);
|
@@ -335,10 +375,21 @@ var __objRest = (source, exclude) => {
|
|
335
375
|
}
|
336
376
|
}
|
337
377
|
}
|
378
|
+
downloadApp(kind) {
|
379
|
+
const src = this.registered.get(kind);
|
380
|
+
if (src && typeof src.src === "string") {
|
381
|
+
return loadApp(src.src, src.kind, src.name);
|
382
|
+
}
|
383
|
+
}
|
384
|
+
async removeDownloaded(kind) {
|
385
|
+
await removeItem(kind);
|
386
|
+
this.downloaded.delete(kind);
|
387
|
+
}
|
338
388
|
unregister(kind) {
|
339
389
|
this.appClasses.delete(kind);
|
340
390
|
this.appClassesCache.delete(kind);
|
341
391
|
this.registered.delete(kind);
|
392
|
+
this.removeDownloaded(kind);
|
342
393
|
const kindEmitter = this.kindEmitters.get(kind);
|
343
394
|
if (kindEmitter) {
|
344
395
|
kindEmitter.clearListeners();
|
@@ -2410,6 +2461,7 @@ var __objRest = (source, exclude) => {
|
|
2410
2461
|
start() {
|
2411
2462
|
if (this.started)
|
2412
2463
|
return;
|
2464
|
+
this.removeCameraListener();
|
2413
2465
|
this.addCameraListener();
|
2414
2466
|
this.addCameraReaction();
|
2415
2467
|
this.started = true;
|
@@ -2488,7 +2540,6 @@ var __objRest = (source, exclude) => {
|
|
2488
2540
|
this.view.callbacks.off("onSizeUpdated", this.onCameraOrSizeUpdated);
|
2489
2541
|
}
|
2490
2542
|
stop() {
|
2491
|
-
this.removeCameraListener();
|
2492
2543
|
this.manager.refresher.remove(Fields.MainViewCamera);
|
2493
2544
|
this.manager.refresher.remove(Fields.MainViewSize);
|
2494
2545
|
this.started = false;
|
@@ -11631,7 +11682,7 @@ var __objRest = (source, exclude) => {
|
|
11631
11682
|
const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
|
11632
11683
|
constructor(context) {
|
11633
11684
|
super(context);
|
11634
|
-
this.version = "1.0.0-canary.
|
11685
|
+
this.version = "1.0.0-canary.51";
|
11635
11686
|
this.dependencies = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.1.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jsdom": "^19.0.0", "less": "^4.1.3", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "typescript": "^4.5.5", "vite": "^2.5.3", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "2.16.26" } };
|
11636
11687
|
this.emitter = callbacks;
|
11637
11688
|
this.viewMode = whiteWebSdk.ViewMode.Broadcaster;
|
@@ -11704,8 +11755,8 @@ var __objRest = (source, exclude) => {
|
|
11704
11755
|
const cursor = params.cursor;
|
11705
11756
|
_WindowManager.params = params;
|
11706
11757
|
_WindowManager.displayer = params.room;
|
11707
|
-
checkVersion();
|
11708
11758
|
let manager = void 0;
|
11759
|
+
checkVersion();
|
11709
11760
|
if (whiteWebSdk.isRoom(room)) {
|
11710
11761
|
if (room.phase !== whiteWebSdk.RoomPhase.Connected) {
|
11711
11762
|
throw new Error("[WindowManager]: Room only Connected can be mount");
|
@@ -11762,7 +11813,7 @@ var __objRest = (source, exclude) => {
|
|
11762
11813
|
emitter.emit("onCreated");
|
11763
11814
|
_WindowManager.isCreated = true;
|
11764
11815
|
try {
|
11765
|
-
await initDb();
|
11816
|
+
await initDb(appRegister);
|
11766
11817
|
} catch (error) {
|
11767
11818
|
console.warn("[WindowManager]: indexedDB open failed");
|
11768
11819
|
console.log(error);
|
@@ -12414,6 +12465,7 @@ var __objRest = (source, exclude) => {
|
|
12414
12465
|
WindowManager.debug = false;
|
12415
12466
|
WindowManager.containerSizeRatio = DEFAULT_CONTAINER_RATIO;
|
12416
12467
|
WindowManager.isCreated = false;
|
12468
|
+
WindowManager.registry = appRegister;
|
12417
12469
|
setupBuiltin();
|
12418
12470
|
exports2.AppCreateError = AppCreateError;
|
12419
12471
|
exports2.AppManagerNotInitError = AppManagerNotInitError;
|
@@ -11,18 +11,20 @@ export declare type SyncRegisterAppPayload = {
|
|
11
11
|
name: string | undefined;
|
12
12
|
};
|
13
13
|
export declare type SyncRegisterApp = (payload: SyncRegisterAppPayload) => void;
|
14
|
-
declare class AppRegister {
|
14
|
+
export declare class AppRegister {
|
15
15
|
kindEmitters: Map<string, Emittery<RegisterEvents>>;
|
16
16
|
registered: Map<string, RegisterParams>;
|
17
17
|
appClassesCache: Map<string, Promise<NetlessApp>>;
|
18
18
|
appClasses: Map<string, () => Promise<NetlessApp>>;
|
19
|
+
downloaded: Map<string, string>;
|
19
20
|
private syncRegisterApp;
|
20
21
|
setSyncRegisterApp(fn: SyncRegisterApp): void;
|
21
22
|
onSyncRegisterAppChange: (payload: SyncRegisterAppPayload) => void;
|
22
23
|
register(params: RegisterParams): Promise<void>;
|
24
|
+
downloadApp(kind: string): Promise<NetlessApp<any, any, any, any> | undefined> | undefined;
|
25
|
+
removeDownloaded(kind: string): Promise<void>;
|
23
26
|
unregister(kind: string): void;
|
24
27
|
notifyApp<T extends keyof RegisterEvents>(kind: string, event: T, payload: RegisterEvents[T]): Promise<void>;
|
25
28
|
private createKindEmitter;
|
26
29
|
}
|
27
30
|
export declare const appRegister: AppRegister;
|
28
|
-
export {};
|
@@ -1,4 +1,4 @@
|
|
1
1
|
import type { NetlessApp } from "../typings";
|
2
|
-
export declare const getScript: (url: string) => Promise<string>;
|
2
|
+
export declare const getScript: (kind: string, url: string) => Promise<string>;
|
3
3
|
export declare const executeScript: (text: string, appName: string) => NetlessApp;
|
4
4
|
export declare const loadApp: (url: string, key: string, name?: string | undefined) => Promise<NetlessApp | undefined>;
|
@@ -1,8 +1,11 @@
|
|
1
|
+
import type { AppRegister } from "./index";
|
1
2
|
export declare type Item = {
|
2
3
|
kind: string;
|
4
|
+
url: string;
|
3
5
|
sourceCode: string;
|
4
6
|
};
|
5
|
-
export declare const initDb: () => Promise<void>;
|
6
|
-
export declare const setItem: (
|
7
|
-
export declare const getItem: (
|
7
|
+
export declare const initDb: (appRegister: AppRegister) => Promise<void>;
|
8
|
+
export declare const setItem: (kind: string, url: string, val: any) => Promise<void> | undefined;
|
9
|
+
export declare const getItem: (kind: string) => Promise<Item | null>;
|
8
10
|
export declare const removeItem: (key: string) => Promise<void> | undefined;
|
11
|
+
export declare const getAll: () => Promise<Item[]> | undefined;
|
package/dist/src/index.d.ts
CHANGED
@@ -113,6 +113,7 @@ export declare class WindowManager extends InvisiblePlugin<WindowMangerAttribute
|
|
113
113
|
static debug: boolean;
|
114
114
|
static containerSizeRatio: number;
|
115
115
|
private static isCreated;
|
116
|
+
static registry: import("./Register").AppRegister;
|
116
117
|
version: string;
|
117
118
|
dependencies: Record<string, string>;
|
118
119
|
appListeners?: AppListeners;
|
package/dist/src/typings.d.ts
CHANGED
@@ -66,7 +66,9 @@ export declare type RegisterEvents<SetupResult = any> = {
|
|
66
66
|
};
|
67
67
|
export declare type RegisterParams<AppOptions = any, SetupResult = any, Attributes = any> = {
|
68
68
|
kind: string;
|
69
|
-
src: NetlessApp<Attributes, SetupResult> | string | (() => Promise<NetlessApp<Attributes, SetupResult>>)
|
69
|
+
src: NetlessApp<Attributes, SetupResult> | string | (() => Promise<NetlessApp<Attributes, SetupResult>>) | (() => Promise<{
|
70
|
+
default: NetlessApp<Attributes, SetupResult>;
|
71
|
+
}>);
|
70
72
|
appOptions?: AppOptions | (() => AppOptions);
|
71
73
|
addHooks?: (emitter: Emittery<RegisterEvents<SetupResult>>) => void;
|
72
74
|
/** dynamic load app package name */
|
package/package.json
CHANGED
package/src/Register/index.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import Emittery from "emittery";
|
2
2
|
import { loadApp } from "./loader";
|
3
3
|
import type { NetlessApp, RegisterEvents, RegisterParams } from "../typings";
|
4
|
+
import { removeItem } from "./storage";
|
4
5
|
|
5
6
|
export type LoadAppEvent = {
|
6
7
|
kind: string;
|
@@ -11,11 +12,12 @@ export type LoadAppEvent = {
|
|
11
12
|
export type SyncRegisterAppPayload = { kind: string, src: string, name: string | undefined };
|
12
13
|
export type SyncRegisterApp = (payload: SyncRegisterAppPayload) => void;
|
13
14
|
|
14
|
-
class AppRegister {
|
15
|
+
export class AppRegister {
|
15
16
|
public kindEmitters: Map<string, Emittery<RegisterEvents>> = new Map();
|
16
17
|
public registered: Map<string, RegisterParams> = new Map();
|
17
18
|
public appClassesCache: Map<string, Promise<NetlessApp>> = new Map();
|
18
19
|
public appClasses: Map<string, () => Promise<NetlessApp>> = new Map();
|
20
|
+
public downloaded: Map<string, string> = new Map();
|
19
21
|
|
20
22
|
private syncRegisterApp: SyncRegisterApp | null = null;
|
21
23
|
|
@@ -31,32 +33,39 @@ class AppRegister {
|
|
31
33
|
this.appClassesCache.delete(params.kind);
|
32
34
|
this.registered.set(params.kind, params);
|
33
35
|
|
34
|
-
const
|
36
|
+
const paramSrc = params.src;
|
35
37
|
let downloadApp: () => Promise<NetlessApp>;
|
36
38
|
|
37
|
-
if (typeof
|
39
|
+
if (typeof paramSrc === "string") {
|
38
40
|
downloadApp = async () => {
|
39
|
-
|
41
|
+
const result = await loadApp(paramSrc, params.kind, params.name) as any;
|
42
|
+
if (result.__esModule) {
|
43
|
+
return result.default;
|
44
|
+
}
|
45
|
+
return result;
|
46
|
+
};
|
47
|
+
if (this.syncRegisterApp) {
|
48
|
+
this.syncRegisterApp({ kind: params.kind, src: paramSrc, name: params.name });
|
49
|
+
}
|
50
|
+
}
|
51
|
+
if (typeof paramSrc === "function") {
|
52
|
+
downloadApp = async () => {
|
53
|
+
let appClass = await paramSrc() as any;
|
40
54
|
if (appClass) {
|
41
|
-
if (appClass.__esModule) {
|
55
|
+
if (appClass.__esModule || appClass.default) {
|
42
56
|
appClass = appClass.default;
|
43
57
|
}
|
44
58
|
return appClass;
|
45
59
|
} else {
|
46
60
|
throw new Error(
|
47
|
-
`[WindowManager]: load remote script failed, ${
|
61
|
+
`[WindowManager]: load remote script failed, ${paramSrc}`
|
48
62
|
);
|
49
63
|
}
|
50
64
|
};
|
51
|
-
if (this.syncRegisterApp) {
|
52
|
-
this.syncRegisterApp({ kind: params.kind, src: srcOrAppOrFunction, name: params.name });
|
53
|
-
}
|
54
|
-
} else if (typeof srcOrAppOrFunction === "function") {
|
55
|
-
downloadApp = srcOrAppOrFunction;
|
56
|
-
} else {
|
57
|
-
downloadApp = async () => srcOrAppOrFunction;
|
58
65
|
}
|
59
|
-
|
66
|
+
if (typeof paramSrc === "object") {
|
67
|
+
downloadApp = async () => paramSrc;
|
68
|
+
}
|
60
69
|
this.appClasses.set(params.kind, async () => {
|
61
70
|
let app = this.appClassesCache.get(params.kind);
|
62
71
|
if (!app) {
|
@@ -74,10 +83,23 @@ class AppRegister {
|
|
74
83
|
}
|
75
84
|
}
|
76
85
|
|
86
|
+
public downloadApp(kind: string) {
|
87
|
+
const src = this.registered.get(kind);
|
88
|
+
if (src && typeof src.src === "string") {
|
89
|
+
return loadApp(src.src, src.kind, src.name)
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
public async removeDownloaded(kind: string) {
|
94
|
+
await removeItem(kind);
|
95
|
+
this.downloaded.delete(kind);
|
96
|
+
}
|
97
|
+
|
77
98
|
public unregister(kind: string) {
|
78
99
|
this.appClasses.delete(kind);
|
79
100
|
this.appClassesCache.delete(kind);
|
80
101
|
this.registered.delete(kind);
|
102
|
+
this.removeDownloaded(kind);
|
81
103
|
const kindEmitter = this.kindEmitters.get(kind);
|
82
104
|
if (kindEmitter) {
|
83
105
|
kindEmitter.clearListeners();
|
package/src/Register/loader.ts
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
import { callbacks } from "../callback";
|
2
2
|
import { getItem, setItem } from "./storage";
|
3
3
|
import type { NetlessApp } from "../typings";
|
4
|
+
import { appRegister } from ".";
|
4
5
|
|
5
6
|
const Prefix = "NetlessApp";
|
6
7
|
|
7
8
|
const TIMEOUT = 10000; // 下载 script 10 秒超时
|
8
9
|
|
9
|
-
export const getScript = async (url: string): Promise<string> => {
|
10
|
-
const item = await getItem(
|
10
|
+
export const getScript = async (kind: string, url: string): Promise<string> => {
|
11
|
+
const item = await getItem(kind);
|
11
12
|
if (item) {
|
12
13
|
return item.sourceCode;
|
13
14
|
} else {
|
14
15
|
const result = await fetchWithTimeout(url, { timeout: TIMEOUT });
|
15
16
|
const text = await result.text();
|
16
|
-
await setItem(url, text);
|
17
|
+
await setItem(kind, url, text);
|
17
18
|
return text;
|
18
19
|
}
|
19
20
|
};
|
@@ -28,6 +29,15 @@ export const executeScript = (text: string, appName: string): NetlessApp => {
|
|
28
29
|
return result;
|
29
30
|
};
|
30
31
|
|
32
|
+
const emitSuccess = (kind: string, url: string) => {
|
33
|
+
callbacks.emit("loadApp", { kind, status: "success" });
|
34
|
+
appRegister.downloaded.set(kind, url);
|
35
|
+
};
|
36
|
+
|
37
|
+
const emitFailed = (kind: string, reason: string) => {
|
38
|
+
callbacks.emit("loadApp", { kind, status: "failed", reason, });
|
39
|
+
};
|
40
|
+
|
31
41
|
export const loadApp = async (
|
32
42
|
url: string,
|
33
43
|
key: string,
|
@@ -36,14 +46,14 @@ export const loadApp = async (
|
|
36
46
|
const appName = name || Prefix + key;
|
37
47
|
callbacks.emit("loadApp", { kind: key, status: "start" });
|
38
48
|
try {
|
39
|
-
const text = await getScript(url);
|
49
|
+
const text = await getScript(key, url);
|
40
50
|
if (!text || text.length === 0) {
|
41
|
-
|
51
|
+
emitFailed(key, "script is empty");
|
42
52
|
return;
|
43
53
|
}
|
44
54
|
try {
|
45
55
|
const result = executeScript(text, appName);
|
46
|
-
|
56
|
+
emitSuccess(key, url);
|
47
57
|
return result;
|
48
58
|
} catch (error: any) {
|
49
59
|
if (error.message.includes("Can only have one anonymous define call per script file")) {
|
@@ -54,16 +64,17 @@ export const loadApp = async (
|
|
54
64
|
delete define.amd;
|
55
65
|
}
|
56
66
|
const result = executeScript(text, appName);
|
57
|
-
|
67
|
+
emitSuccess(key, url);
|
58
68
|
return result;
|
59
69
|
}
|
60
|
-
|
70
|
+
emitFailed(key, error.message);
|
61
71
|
}
|
62
72
|
} catch (error: any) {
|
63
|
-
|
73
|
+
emitFailed(key, error.message);
|
64
74
|
}
|
65
75
|
};
|
66
76
|
|
77
|
+
|
67
78
|
async function fetchWithTimeout(resource: string, options: RequestInit & { timeout: number }) {
|
68
79
|
const { timeout = 10000 } = options;
|
69
80
|
|
package/src/Register/storage.ts
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
import type { AppRegister } from "./index";
|
2
|
+
|
1
3
|
const DatabaseName = "__WindowManagerAppCache";
|
2
4
|
|
3
5
|
let db: IDBDatabase;
|
@@ -5,21 +7,26 @@ let store: IDBObjectStore;
|
|
5
7
|
|
6
8
|
export type Item = {
|
7
9
|
kind: string;
|
10
|
+
url: string;
|
8
11
|
sourceCode: string;
|
9
12
|
}
|
10
13
|
|
11
|
-
export const initDb = async () => {
|
14
|
+
export const initDb = async (appRegister: AppRegister) => {
|
12
15
|
db = await createDb();
|
16
|
+
const items = await queryAll(db);
|
17
|
+
items.forEach(item => {
|
18
|
+
appRegister.downloaded.set(item.kind, item.url);
|
19
|
+
});
|
13
20
|
}
|
14
21
|
|
15
|
-
export const setItem = (
|
22
|
+
export const setItem = (kind: string, url: string, val: any) => {
|
16
23
|
if (!db) return;
|
17
|
-
return addRecord(db, { kind
|
24
|
+
return addRecord(db, { kind, url, sourceCode: val })
|
18
25
|
};
|
19
26
|
|
20
|
-
export const getItem = async (
|
27
|
+
export const getItem = async (kind: string): Promise<Item | null> => {
|
21
28
|
if (!db) return null;
|
22
|
-
return await query(db,
|
29
|
+
return await query(db, kind);
|
23
30
|
};
|
24
31
|
|
25
32
|
export const removeItem = (key: string) => {
|
@@ -27,6 +34,11 @@ export const removeItem = (key: string) => {
|
|
27
34
|
return deleteRecord(db, key);
|
28
35
|
};
|
29
36
|
|
37
|
+
export const getAll = () => {
|
38
|
+
if (!db) return;
|
39
|
+
return queryAll(db);
|
40
|
+
}
|
41
|
+
|
30
42
|
function createDb(): Promise<IDBDatabase> {
|
31
43
|
return new Promise((resolve, reject) => {
|
32
44
|
const request = indexedDB.open(DatabaseName, 2);
|
@@ -64,6 +76,15 @@ function query<T>(db: IDBDatabase, val: string): Promise<T | null> {
|
|
64
76
|
})
|
65
77
|
}
|
66
78
|
|
79
|
+
function queryAll(db: IDBDatabase): Promise<Item[]> {
|
80
|
+
return new Promise((resolve, reject) => {
|
81
|
+
const index = db.transaction(["apps"]).objectStore("apps").index("kind");
|
82
|
+
const request = index.getAll();
|
83
|
+
request.onerror = e => reject(e);
|
84
|
+
request.onsuccess = () => resolve(request.result);
|
85
|
+
});
|
86
|
+
}
|
87
|
+
|
67
88
|
function addRecord(db: IDBDatabase, payload: any): Promise<void> {
|
68
89
|
return new Promise((resolve, reject) => {
|
69
90
|
const request = db.transaction(["apps"], "readwrite").objectStore("apps").add(payload);
|
package/src/View/MainView.ts
CHANGED
@@ -118,6 +118,7 @@ export class MainViewProxy {
|
|
118
118
|
|
119
119
|
public start() {
|
120
120
|
if (this.started) return;
|
121
|
+
this.removeCameraListener();
|
121
122
|
this.addCameraListener();
|
122
123
|
this.addCameraReaction();
|
123
124
|
this.started = true;
|
@@ -279,7 +280,6 @@ export class MainViewProxy {
|
|
279
280
|
};
|
280
281
|
|
281
282
|
public stop() {
|
282
|
-
this.removeCameraListener();
|
283
283
|
this.manager.refresher.remove(Fields.MainViewCamera);
|
284
284
|
this.manager.refresher.remove(Fields.MainViewSize);
|
285
285
|
this.started = false;
|
package/src/index.ts
CHANGED
@@ -166,6 +166,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
166
166
|
public static debug = false;
|
167
167
|
public static containerSizeRatio = DEFAULT_CONTAINER_RATIO;
|
168
168
|
private static isCreated = false;
|
169
|
+
public static registry = appRegister;
|
169
170
|
|
170
171
|
public version = __APP_VERSION__;
|
171
172
|
public dependencies = __APP_DEPENDENCIES__;
|
@@ -198,14 +199,13 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
198
199
|
public static async mount(params: MountParams): Promise<WindowManager> {
|
199
200
|
const room = params.room;
|
200
201
|
WindowManager.container = params.container;
|
201
|
-
|
202
202
|
const debug = params.debug;
|
203
|
-
|
204
203
|
const cursor = params.cursor;
|
205
204
|
WindowManager.params = params;
|
206
205
|
WindowManager.displayer = params.room;
|
207
|
-
checkVersion();
|
208
206
|
let manager: WindowManager | undefined = undefined;
|
207
|
+
|
208
|
+
checkVersion();
|
209
209
|
if (isRoom(room)) {
|
210
210
|
if (room.phase !== RoomPhase.Connected) {
|
211
211
|
throw new Error("[WindowManager]: Room only Connected can be mount");
|
@@ -273,7 +273,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
|
|
273
273
|
emitter.emit("onCreated");
|
274
274
|
WindowManager.isCreated = true;
|
275
275
|
try {
|
276
|
-
await initDb();
|
276
|
+
await initDb(appRegister);
|
277
277
|
} catch (error) {
|
278
278
|
console.warn("[WindowManager]: indexedDB open failed");
|
279
279
|
console.log(error);
|
package/src/typings.ts
CHANGED
@@ -72,7 +72,11 @@ export type RegisterEvents<SetupResult = any> = {
|
|
72
72
|
|
73
73
|
export type RegisterParams<AppOptions = any, SetupResult = any, Attributes = any> = {
|
74
74
|
kind: string;
|
75
|
-
src:
|
75
|
+
src:
|
76
|
+
| NetlessApp<Attributes, SetupResult>
|
77
|
+
| string
|
78
|
+
| (() => Promise<NetlessApp<Attributes, SetupResult>>)
|
79
|
+
| (() => Promise<{ default: NetlessApp<Attributes, SetupResult> }>);
|
76
80
|
appOptions?: AppOptions | (() => AppOptions);
|
77
81
|
addHooks?: (emitter: Emittery<RegisterEvents<SetupResult>>) => void;
|
78
82
|
/** dynamic load app package name */
|