@netless/window-manager 1.0.0-canary.48 → 1.0.0-canary.50

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 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 = (key, val) => {
181
+ const setItem = (kind, url, val) => {
178
182
  if (!db)
179
183
  return;
180
- return addRecord(db, { kind: key, sourceCode: val });
184
+ return addRecord(db, { kind, url, sourceCode: val });
181
185
  };
182
- const getItem = async (key) => {
186
+ const getItem = async (kind) => {
183
187
  if (!db)
184
188
  return null;
185
- return await query(db, key);
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(url);
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
- callbacks.emit("loadApp", { kind: key, status: "failed", reason: "script is empty." });
285
+ emitFailed(key, "script is empty");
255
286
  return;
256
287
  }
257
288
  try {
258
289
  const result = executeScript(text2, appName);
259
- callbacks.emit("loadApp", { kind: key, status: "success" });
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
- callbacks.emit("loadApp", { kind: key, status: "success" });
299
+ emitSuccess(key, url);
269
300
  return result;
270
301
  }
271
- callbacks.emit("loadApp", { kind: key, status: "failed", reason: error.message });
302
+ emitFailed(key, error.message);
272
303
  }
273
304
  } catch (error) {
274
- callbacks.emit("loadApp", { kind: key, status: "failed", reason: error.message });
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 srcOrAppOrFunction = params.src;
339
+ const paramSrc = params.src;
308
340
  let downloadApp;
309
- if (typeof srcOrAppOrFunction === "string") {
341
+ if (typeof paramSrc === "string") {
310
342
  downloadApp = async () => {
311
- let appClass = await loadApp(srcOrAppOrFunction, params.kind, params.name);
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") {
354
+ downloadApp = async () => {
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, ${srcOrAppOrFunction}`);
362
+ throw new Error(`[WindowManager]: load remote script failed, ${paramSrc}`);
319
363
  }
320
364
  };
321
- if (this.syncRegisterApp) {
322
- this.syncRegisterApp({ kind: params.kind, src: srcOrAppOrFunction, name: params.name });
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();
@@ -5164,10 +5215,12 @@ class MaxTitleBar extends DefaultTitleBar {
5164
5215
  this.$titles = document.createElement("div");
5165
5216
  this.$titles.className = this.wrapClassName("titles");
5166
5217
  this.sideEffect.addEventListener(this.$titles, "wheel", (ev) => {
5167
- ev.currentTarget.scrollBy({
5168
- left: ev.deltaY > 0 ? 250 : -250,
5169
- behavior: "smooth"
5170
- });
5218
+ if (!ev.deltaX) {
5219
+ ev.currentTarget.scrollBy({
5220
+ left: ev.deltaY > 0 ? 250 : -250,
5221
+ behavior: "smooth"
5222
+ });
5223
+ }
5171
5224
  }, { passive: false }, "max-render-wheel-titles");
5172
5225
  const $content = document.createElement("div");
5173
5226
  $content.className = this.wrapClassName("titles-content");
@@ -11635,8 +11688,8 @@ const reconnectRefresher = new ReconnectRefresher({ emitter });
11635
11688
  const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11636
11689
  constructor(context) {
11637
11690
  super(context);
11638
- this.version = "1.0.0-canary.48";
11639
- this.dependencies = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.36", "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" } };
11691
+ this.version = "1.0.0-canary.50";
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" } };
11640
11693
  this.emitter = callbacks;
11641
11694
  this.viewMode = whiteWebSdk.ViewMode.Broadcaster;
11642
11695
  this.viewMode$ = new valueEnhancer.Val(whiteWebSdk.ViewMode.Broadcaster);
@@ -11676,7 +11729,7 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11676
11729
  this.cameraUpdating = 0;
11677
11730
  this.mainView.callbacks.on("onCameraUpdated", this.onCameraUpdated);
11678
11731
  if (nextScale) {
11679
- this.nextCamera = __spreadProps(__spreadValues({}, nextCamera), { scale: nextScale });
11732
+ this.nextCamera = nextCamera;
11680
11733
  }
11681
11734
  }
11682
11735
  };
@@ -11698,7 +11751,7 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11698
11751
  }, 50);
11699
11752
  };
11700
11753
  _WindowManager.displayer = context.displayer;
11701
- window.NETLESS_DEPS = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.36", "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" } };
11754
+ window.NETLESS_DEPS = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.1.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jsdom": "^19.0.0", "less": "^4.1.3", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "typescript": "^4.5.5", "vite": "^2.5.3", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "2.16.26" } };
11702
11755
  }
11703
11756
  static async mount(params) {
11704
11757
  var _a;
@@ -11708,8 +11761,8 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11708
11761
  const cursor = params.cursor;
11709
11762
  _WindowManager.params = params;
11710
11763
  _WindowManager.displayer = params.room;
11711
- checkVersion();
11712
11764
  let manager = void 0;
11765
+ checkVersion();
11713
11766
  if (whiteWebSdk.isRoom(room)) {
11714
11767
  if (room.phase !== whiteWebSdk.RoomPhase.Connected) {
11715
11768
  throw new Error("[WindowManager]: Room only Connected can be mount");
@@ -11766,7 +11819,7 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11766
11819
  emitter.emit("onCreated");
11767
11820
  _WindowManager.isCreated = true;
11768
11821
  try {
11769
- await initDb();
11822
+ await initDb(appRegister);
11770
11823
  } catch (error) {
11771
11824
  console.warn("[WindowManager]: indexedDB open failed");
11772
11825
  console.log(error);
@@ -12418,6 +12471,7 @@ WindowManager.kind = "WindowManager";
12418
12471
  WindowManager.debug = false;
12419
12472
  WindowManager.containerSizeRatio = DEFAULT_CONTAINER_RATIO;
12420
12473
  WindowManager.isCreated = false;
12474
+ WindowManager.registry = appRegister;
12421
12475
  setupBuiltin();
12422
12476
  exports.AppCreateError = AppCreateError;
12423
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 = (key, val) => {
174
+ const setItem = (kind, url, val) => {
171
175
  if (!db)
172
176
  return;
173
- return addRecord(db, { kind: key, sourceCode: val });
177
+ return addRecord(db, { kind, url, sourceCode: val });
174
178
  };
175
- const getItem = async (key) => {
179
+ const getItem = async (kind) => {
176
180
  if (!db)
177
181
  return null;
178
- return await query(db, key);
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(url);
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
- callbacks.emit("loadApp", { kind: key, status: "failed", reason: "script is empty." });
278
+ emitFailed(key, "script is empty");
248
279
  return;
249
280
  }
250
281
  try {
251
282
  const result = executeScript(text2, appName);
252
- callbacks.emit("loadApp", { kind: key, status: "success" });
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
- callbacks.emit("loadApp", { kind: key, status: "success" });
292
+ emitSuccess(key, url);
262
293
  return result;
263
294
  }
264
- callbacks.emit("loadApp", { kind: key, status: "failed", reason: error.message });
295
+ emitFailed(key, error.message);
265
296
  }
266
297
  } catch (error) {
267
- callbacks.emit("loadApp", { kind: key, status: "failed", reason: error.message });
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 srcOrAppOrFunction = params.src;
332
+ const paramSrc = params.src;
301
333
  let downloadApp;
302
- if (typeof srcOrAppOrFunction === "string") {
334
+ if (typeof paramSrc === "string") {
303
335
  downloadApp = async () => {
304
- let appClass = await loadApp(srcOrAppOrFunction, params.kind, params.name);
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") {
347
+ downloadApp = async () => {
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, ${srcOrAppOrFunction}`);
355
+ throw new Error(`[WindowManager]: load remote script failed, ${paramSrc}`);
312
356
  }
313
357
  };
314
- if (this.syncRegisterApp) {
315
- this.syncRegisterApp({ kind: params.kind, src: srcOrAppOrFunction, name: params.name });
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();
@@ -5157,10 +5208,12 @@ class MaxTitleBar extends DefaultTitleBar {
5157
5208
  this.$titles = document.createElement("div");
5158
5209
  this.$titles.className = this.wrapClassName("titles");
5159
5210
  this.sideEffect.addEventListener(this.$titles, "wheel", (ev) => {
5160
- ev.currentTarget.scrollBy({
5161
- left: ev.deltaY > 0 ? 250 : -250,
5162
- behavior: "smooth"
5163
- });
5211
+ if (!ev.deltaX) {
5212
+ ev.currentTarget.scrollBy({
5213
+ left: ev.deltaY > 0 ? 250 : -250,
5214
+ behavior: "smooth"
5215
+ });
5216
+ }
5164
5217
  }, { passive: false }, "max-render-wheel-titles");
5165
5218
  const $content = document.createElement("div");
5166
5219
  $content.className = this.wrapClassName("titles-content");
@@ -11628,8 +11681,8 @@ const reconnectRefresher = new ReconnectRefresher({ emitter });
11628
11681
  const _WindowManager = class extends InvisiblePlugin {
11629
11682
  constructor(context) {
11630
11683
  super(context);
11631
- this.version = "1.0.0-canary.48";
11632
- this.dependencies = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.36", "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" } };
11684
+ this.version = "1.0.0-canary.50";
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" } };
11633
11686
  this.emitter = callbacks;
11634
11687
  this.viewMode = ViewMode.Broadcaster;
11635
11688
  this.viewMode$ = new Val(ViewMode.Broadcaster);
@@ -11669,7 +11722,7 @@ const _WindowManager = class extends InvisiblePlugin {
11669
11722
  this.cameraUpdating = 0;
11670
11723
  this.mainView.callbacks.on("onCameraUpdated", this.onCameraUpdated);
11671
11724
  if (nextScale) {
11672
- this.nextCamera = __spreadProps(__spreadValues({}, nextCamera), { scale: nextScale });
11725
+ this.nextCamera = nextCamera;
11673
11726
  }
11674
11727
  }
11675
11728
  };
@@ -11691,7 +11744,7 @@ const _WindowManager = class extends InvisiblePlugin {
11691
11744
  }, 50);
11692
11745
  };
11693
11746
  _WindowManager.displayer = context.displayer;
11694
- window.NETLESS_DEPS = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.36", "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" } };
11747
+ window.NETLESS_DEPS = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.1.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jsdom": "^19.0.0", "less": "^4.1.3", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "typescript": "^4.5.5", "vite": "^2.5.3", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "2.16.26" } };
11695
11748
  }
11696
11749
  static async mount(params) {
11697
11750
  var _a;
@@ -11701,8 +11754,8 @@ const _WindowManager = class extends InvisiblePlugin {
11701
11754
  const cursor = params.cursor;
11702
11755
  _WindowManager.params = params;
11703
11756
  _WindowManager.displayer = params.room;
11704
- checkVersion();
11705
11757
  let manager = void 0;
11758
+ checkVersion();
11706
11759
  if (isRoom(room)) {
11707
11760
  if (room.phase !== RoomPhase.Connected) {
11708
11761
  throw new Error("[WindowManager]: Room only Connected can be mount");
@@ -11759,7 +11812,7 @@ const _WindowManager = class extends InvisiblePlugin {
11759
11812
  emitter.emit("onCreated");
11760
11813
  _WindowManager.isCreated = true;
11761
11814
  try {
11762
- await initDb();
11815
+ await initDb(appRegister);
11763
11816
  } catch (error) {
11764
11817
  console.warn("[WindowManager]: indexedDB open failed");
11765
11818
  console.log(error);
@@ -12411,5 +12464,6 @@ WindowManager.kind = "WindowManager";
12411
12464
  WindowManager.debug = false;
12412
12465
  WindowManager.containerSizeRatio = DEFAULT_CONTAINER_RATIO;
12413
12466
  WindowManager.isCreated = false;
12467
+ WindowManager.registry = appRegister;
12414
12468
  setupBuiltin();
12415
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 = (key, val) => {
175
+ const setItem = (kind, url, val) => {
172
176
  if (!db)
173
177
  return;
174
- return addRecord(db, { kind: key, sourceCode: val });
178
+ return addRecord(db, { kind, url, sourceCode: val });
175
179
  };
176
- const getItem = async (key) => {
180
+ const getItem = async (kind) => {
177
181
  if (!db)
178
182
  return null;
179
- return await query(db, key);
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(url);
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
- callbacks.emit("loadApp", { kind: key, status: "failed", reason: "script is empty." });
279
+ emitFailed(key, "script is empty");
249
280
  return;
250
281
  }
251
282
  try {
252
283
  const result = executeScript(text2, appName);
253
- callbacks.emit("loadApp", { kind: key, status: "success" });
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
- callbacks.emit("loadApp", { kind: key, status: "success" });
293
+ emitSuccess(key, url);
263
294
  return result;
264
295
  }
265
- callbacks.emit("loadApp", { kind: key, status: "failed", reason: error.message });
296
+ emitFailed(key, error.message);
266
297
  }
267
298
  } catch (error) {
268
- callbacks.emit("loadApp", { kind: key, status: "failed", reason: error.message });
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 srcOrAppOrFunction = params.src;
333
+ const paramSrc = params.src;
302
334
  let downloadApp;
303
- if (typeof srcOrAppOrFunction === "string") {
335
+ if (typeof paramSrc === "string") {
304
336
  downloadApp = async () => {
305
- let appClass = await loadApp(srcOrAppOrFunction, params.kind, params.name);
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") {
348
+ downloadApp = async () => {
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, ${srcOrAppOrFunction}`);
356
+ throw new Error(`[WindowManager]: load remote script failed, ${paramSrc}`);
313
357
  }
314
358
  };
315
- if (this.syncRegisterApp) {
316
- this.syncRegisterApp({ kind: params.kind, src: srcOrAppOrFunction, name: params.name });
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();
@@ -5158,10 +5209,12 @@ var __objRest = (source, exclude) => {
5158
5209
  this.$titles = document.createElement("div");
5159
5210
  this.$titles.className = this.wrapClassName("titles");
5160
5211
  this.sideEffect.addEventListener(this.$titles, "wheel", (ev) => {
5161
- ev.currentTarget.scrollBy({
5162
- left: ev.deltaY > 0 ? 250 : -250,
5163
- behavior: "smooth"
5164
- });
5212
+ if (!ev.deltaX) {
5213
+ ev.currentTarget.scrollBy({
5214
+ left: ev.deltaY > 0 ? 250 : -250,
5215
+ behavior: "smooth"
5216
+ });
5217
+ }
5165
5218
  }, { passive: false }, "max-render-wheel-titles");
5166
5219
  const $content = document.createElement("div");
5167
5220
  $content.className = this.wrapClassName("titles-content");
@@ -11629,8 +11682,8 @@ var __objRest = (source, exclude) => {
11629
11682
  const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11630
11683
  constructor(context) {
11631
11684
  super(context);
11632
- this.version = "1.0.0-canary.48";
11633
- this.dependencies = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.36", "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" } };
11685
+ this.version = "1.0.0-canary.50";
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" } };
11634
11687
  this.emitter = callbacks;
11635
11688
  this.viewMode = whiteWebSdk.ViewMode.Broadcaster;
11636
11689
  this.viewMode$ = new valueEnhancer.Val(whiteWebSdk.ViewMode.Broadcaster);
@@ -11670,7 +11723,7 @@ var __objRest = (source, exclude) => {
11670
11723
  this.cameraUpdating = 0;
11671
11724
  this.mainView.callbacks.on("onCameraUpdated", this.onCameraUpdated);
11672
11725
  if (nextScale) {
11673
- this.nextCamera = __spreadProps(__spreadValues({}, nextCamera), { scale: nextScale });
11726
+ this.nextCamera = nextCamera;
11674
11727
  }
11675
11728
  }
11676
11729
  };
@@ -11692,7 +11745,7 @@ var __objRest = (source, exclude) => {
11692
11745
  }, 50);
11693
11746
  };
11694
11747
  _WindowManager.displayer = context.displayer;
11695
- window.NETLESS_DEPS = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.36", "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" } };
11748
+ window.NETLESS_DEPS = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.1.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jsdom": "^19.0.0", "less": "^4.1.3", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "typescript": "^4.5.5", "vite": "^2.5.3", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "2.16.26" } };
11696
11749
  }
11697
11750
  static async mount(params) {
11698
11751
  var _a;
@@ -11702,8 +11755,8 @@ var __objRest = (source, exclude) => {
11702
11755
  const cursor = params.cursor;
11703
11756
  _WindowManager.params = params;
11704
11757
  _WindowManager.displayer = params.room;
11705
- checkVersion();
11706
11758
  let manager = void 0;
11759
+ checkVersion();
11707
11760
  if (whiteWebSdk.isRoom(room)) {
11708
11761
  if (room.phase !== whiteWebSdk.RoomPhase.Connected) {
11709
11762
  throw new Error("[WindowManager]: Room only Connected can be mount");
@@ -11760,7 +11813,7 @@ var __objRest = (source, exclude) => {
11760
11813
  emitter.emit("onCreated");
11761
11814
  _WindowManager.isCreated = true;
11762
11815
  try {
11763
- await initDb();
11816
+ await initDb(appRegister);
11764
11817
  } catch (error) {
11765
11818
  console.warn("[WindowManager]: indexedDB open failed");
11766
11819
  console.log(error);
@@ -12412,6 +12465,7 @@ var __objRest = (source, exclude) => {
12412
12465
  WindowManager.debug = false;
12413
12466
  WindowManager.containerSizeRatio = DEFAULT_CONTAINER_RATIO;
12414
12467
  WindowManager.isCreated = false;
12468
+ WindowManager.registry = appRegister;
12415
12469
  setupBuiltin();
12416
12470
  exports2.AppCreateError = AppCreateError;
12417
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: (key: string, val: any) => Promise<void> | undefined;
7
- export declare const getItem: (key: string) => Promise<Item | null>;
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;
@@ -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;
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/window-manager",
3
- "version": "1.0.0-canary.48",
3
+ "version": "1.0.0-canary.50",
4
4
  "description": "",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@juggle/resize-observer": "^3.3.1",
28
- "@netless/telebox-insider": "1.0.0-alpha.36",
28
+ "@netless/telebox-insider": "1.0.0-alpha.37",
29
29
  "emittery": "^0.11.0",
30
30
  "lodash": "^4.17.21",
31
31
  "p-retry": "^4.6.2",
package/pnpm-lock.yaml CHANGED
@@ -4,7 +4,7 @@ specifiers:
4
4
  '@juggle/resize-observer': ^3.3.1
5
5
  '@netless/app-docs-viewer': ^0.3.3
6
6
  '@netless/app-plyr': 0.2.2
7
- '@netless/telebox-insider': 1.0.0-alpha.36
7
+ '@netless/telebox-insider': 1.0.0-alpha.37
8
8
  '@playwright/test': ^1.23.2
9
9
  '@rollup/plugin-commonjs': ^20.0.0
10
10
  '@rollup/plugin-node-resolve': ^13.0.4
@@ -45,7 +45,7 @@ specifiers:
45
45
 
46
46
  dependencies:
47
47
  '@juggle/resize-observer': 3.3.1
48
- '@netless/telebox-insider': 1.0.0-alpha.36
48
+ '@netless/telebox-insider': 1.0.0-alpha.37
49
49
  emittery: 0.11.0
50
50
  lodash: 4.17.21
51
51
  p-retry: 4.6.2
@@ -247,8 +247,8 @@ packages:
247
247
  resolution: {integrity: sha512-7NzsJrba0R/mq/l10SkIZQwbrNVJyPxZYrjK6xL3Ts732iWAVuS2UB0u3s6iGeUVcqV39A679yva8APWRl4M0A==}
248
248
  dev: true
249
249
 
250
- /@netless/telebox-insider/1.0.0-alpha.36:
251
- resolution: {integrity: sha512-wW0/pmagLt1pzV7PfCWJAAsOm4+RED6GEh2mOSTGS/q6lIOV8Qjoe0MizaR3ild7d6rg/kIFj2II3IYF0d+OiA==}
250
+ /@netless/telebox-insider/1.0.0-alpha.37:
251
+ resolution: {integrity: sha512-Fazjl/sLaqXPASEvc3ZC+uQSzaCmlmOIpcTwokP//Hn9u4f6C1HvU1veIF1An+s6s44gSYkS9IegYZrGt5cOsg==}
252
252
  dependencies:
253
253
  '@juggle/resize-observer': 3.3.1
254
254
  '@types/shallowequal': 1.1.1
@@ -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 srcOrAppOrFunction = params.src;
36
+ const paramSrc = params.src;
35
37
  let downloadApp: () => Promise<NetlessApp>;
36
38
 
37
- if (typeof srcOrAppOrFunction === "string") {
39
+ if (typeof paramSrc === "string") {
38
40
  downloadApp = async () => {
39
- let appClass = (await loadApp(srcOrAppOrFunction, params.kind, params.name)) as any;
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, ${srcOrAppOrFunction}`
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();
@@ -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(url);
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
- callbacks.emit("loadApp", { kind: key, status: "failed", reason: "script is empty." });
51
+ emitFailed(key, "script is empty");
42
52
  return;
43
53
  }
44
54
  try {
45
55
  const result = executeScript(text, appName);
46
- callbacks.emit("loadApp", { kind: key, status: "success" });
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
- callbacks.emit("loadApp", { kind: key, status: "success" });
67
+ emitSuccess(key, url);
58
68
  return result;
59
69
  }
60
- callbacks.emit("loadApp", { kind: key, status: "failed", reason: error.message });
70
+ emitFailed(key, error.message);
61
71
  }
62
72
  } catch (error: any) {
63
- callbacks.emit("loadApp", { kind: key, status: "failed", reason: error.message });
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
 
@@ -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 = (key: string, val: any) => {
22
+ export const setItem = (kind: string, url: string, val: any) => {
16
23
  if (!db) return;
17
- return addRecord(db, { kind: key, sourceCode: val })
24
+ return addRecord(db, { kind, url, sourceCode: val })
18
25
  };
19
26
 
20
- export const getItem = async (key: string): Promise<Item | null> => {
27
+ export const getItem = async (kind: string): Promise<Item | null> => {
21
28
  if (!db) return null;
22
- return await query(db, key);
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/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);
@@ -841,7 +841,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> imple
841
841
  this.cameraUpdating = 0;
842
842
  this.mainView.callbacks.on("onCameraUpdated", this.onCameraUpdated);
843
843
  if (nextScale) {
844
- this.nextCamera = { ...nextCamera, scale: nextScale };
844
+ this.nextCamera = nextCamera;
845
845
  }
846
846
  }
847
847
  };
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: NetlessApp<Attributes, SetupResult> | string | (() => Promise<NetlessApp<Attributes, SetupResult>>);
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 */