@netless/slide 1.4.36 → 1.4.38

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/README.md CHANGED
@@ -4,6 +4,9 @@
4
4
 
5
5
  ## changelog
6
6
 
7
+ ### 1.4.37 (2025-7-16)
8
+ * 添加 `setStageCountLimit` 静态方法, 用于设置强行清除最大限制, 需设置 `window.__nativeTags.platform`
9
+
7
10
  ### 1.4.36 (2025-6-26)
8
11
  * 修复`safari`无法在播放前调整进度问题
9
12
 
@@ -4,11 +4,22 @@ export declare class AliTrackLogger {
4
4
  private config;
5
5
  private retryTimes;
6
6
  private enable;
7
+ private db;
8
+ private useIndexedDB;
9
+ private readonly DB_NAME;
10
+ private readonly STORE_NAME;
11
+ private readonly BATCH_SIZE;
7
12
  constructor();
13
+ private initIndexedDB;
14
+ private storeLogInIndexedDB;
15
+ private getLogsFromIndexedDB;
16
+ private deleteLogsFromIndexedDB;
8
17
  private uploadLoggerGlobalEvent;
9
18
  start(): Promise<void>;
10
19
  pause(): void;
11
- addLog(message: string, level: Level, taskId: string, randomId: string): void;
20
+ addLog(message: string, level: Level, taskId: string, randomId: string): Promise<void>;
21
+ private isDatabaseHealthy;
22
+ private recreateDatabase;
12
23
  destroy(): void;
13
24
  uploadLog(focus?: boolean): Promise<void>;
14
25
  setEnable(enable: boolean): void;
@@ -1,3 +1,14 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
1
12
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
13
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
14
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -41,18 +52,270 @@ var AliTrackLogger = /** @class */ (function () {
41
52
  this.checkTimer = null;
42
53
  this.retryTimes = 0;
43
54
  this.enable = false;
55
+ this.db = null;
56
+ this.useIndexedDB = false;
57
+ this.DB_NAME = "__slide_logs_report__";
58
+ this.STORE_NAME = "logs";
59
+ this.BATCH_SIZE = 1000;
44
60
  this.uploadLoggerGlobalEvent = function (event) {
45
61
  if (event.data.type === "@slide/_upload_log_") {
46
62
  _this.start();
47
63
  }
48
64
  };
49
65
  this.config = {
50
- checkTime: 3000,
66
+ checkTime: 5000,
51
67
  buffer: 300,
52
68
  };
53
69
  window.addEventListener("message", this.uploadLoggerGlobalEvent);
54
- this.start();
70
+ this.initIndexedDB();
55
71
  }
72
+ AliTrackLogger.prototype.initIndexedDB = function () {
73
+ return __awaiter(this, void 0, void 0, function () {
74
+ var request_1;
75
+ var _this = this;
76
+ return __generator(this, function (_a) {
77
+ if (!('indexedDB' in window)) {
78
+ this.useIndexedDB = false;
79
+ this.start();
80
+ return [2 /*return*/];
81
+ }
82
+ try {
83
+ request_1 = indexedDB.open(this.DB_NAME, 1);
84
+ request_1.onerror = function () {
85
+ _this.useIndexedDB = false;
86
+ };
87
+ request_1.onsuccess = function () {
88
+ _this.start();
89
+ _this.db = request_1.result;
90
+ _this.useIndexedDB = true;
91
+ };
92
+ request_1.onupgradeneeded = function (event) {
93
+ var db = event.target.result;
94
+ if (!db.objectStoreNames.contains(_this.STORE_NAME)) {
95
+ var store = db.createObjectStore(_this.STORE_NAME, { keyPath: 'id', autoIncrement: true });
96
+ store.createIndex('timestamp', 'timestamp');
97
+ }
98
+ };
99
+ }
100
+ catch (error) {
101
+ this.useIndexedDB = false;
102
+ }
103
+ return [2 /*return*/];
104
+ });
105
+ });
106
+ };
107
+ AliTrackLogger.prototype.storeLogInIndexedDB = function (log) {
108
+ return __awaiter(this, void 0, void 0, function () {
109
+ var error_1;
110
+ var _this = this;
111
+ return __generator(this, function (_a) {
112
+ switch (_a.label) {
113
+ case 0:
114
+ if (!this.useIndexedDB)
115
+ return [2 /*return*/];
116
+ _a.label = 1;
117
+ case 1:
118
+ _a.trys.push([1, 4, , 5]);
119
+ if (!(!this.db || !this.isDatabaseHealthy())) return [3 /*break*/, 3];
120
+ return [4 /*yield*/, this.recreateDatabase()];
121
+ case 2:
122
+ _a.sent();
123
+ if (!this.db || !this.useIndexedDB) {
124
+ throw new Error('Database not available after recreation attempt');
125
+ }
126
+ _a.label = 3;
127
+ case 3: return [2 /*return*/, new Promise(function (resolve, reject) {
128
+ var transaction = _this.db.transaction([_this.STORE_NAME], 'readwrite');
129
+ var store = transaction.objectStore(_this.STORE_NAME);
130
+ var request = store.add(log);
131
+ transaction.onerror = function () {
132
+ // If transaction fails due to database being deleted, try to recreate
133
+ _this.recreateDatabase().then(function () {
134
+ if (!_this.db || !_this.useIndexedDB) {
135
+ reject(new Error('Database recreation failed'));
136
+ }
137
+ else {
138
+ // Retry the operation after recreation
139
+ var retryTransaction = _this.db.transaction([_this.STORE_NAME], 'readwrite');
140
+ var retryStore = retryTransaction.objectStore(_this.STORE_NAME);
141
+ var retryRequest_1 = retryStore.add(log);
142
+ retryRequest_1.onsuccess = function () { return resolve(); };
143
+ retryRequest_1.onerror = function () { return reject(retryRequest_1.error); };
144
+ }
145
+ }).catch(function (error) {
146
+ console.warn('Database recreation failed:', error);
147
+ // Fall back to memory storage and reject
148
+ _this.useIndexedDB = false;
149
+ reject(error);
150
+ });
151
+ };
152
+ request.onsuccess = function () { return resolve(); };
153
+ request.onerror = function () {
154
+ var _a, _b;
155
+ if (((_a = request.error) === null || _a === void 0 ? void 0 : _a.name) === 'UnknownError' || ((_b = request.error) === null || _b === void 0 ? void 0 : _b.name) === 'NotFoundError') {
156
+ // Database might have been deleted, try to recreate
157
+ _this.recreateDatabase().catch(function (error) {
158
+ console.warn('Database recreation failed:', error);
159
+ _this.useIndexedDB = false;
160
+ }).finally(function () { return reject(request.error); });
161
+ }
162
+ else {
163
+ reject(request.error);
164
+ }
165
+ };
166
+ })];
167
+ case 4:
168
+ error_1 = _a.sent();
169
+ this.useIndexedDB = false;
170
+ throw error_1;
171
+ case 5: return [2 /*return*/];
172
+ }
173
+ });
174
+ });
175
+ };
176
+ AliTrackLogger.prototype.getLogsFromIndexedDB = function (limit) {
177
+ return __awaiter(this, void 0, void 0, function () {
178
+ var error_2;
179
+ var _this = this;
180
+ return __generator(this, function (_a) {
181
+ switch (_a.label) {
182
+ case 0:
183
+ if (!this.useIndexedDB)
184
+ return [2 /*return*/, []];
185
+ _a.label = 1;
186
+ case 1:
187
+ _a.trys.push([1, 4, , 5]);
188
+ if (!(!this.db || !this.isDatabaseHealthy())) return [3 /*break*/, 3];
189
+ return [4 /*yield*/, this.recreateDatabase()];
190
+ case 2:
191
+ _a.sent();
192
+ if (!this.db || !this.useIndexedDB) {
193
+ return [2 /*return*/, []];
194
+ }
195
+ _a.label = 3;
196
+ case 3: return [2 /*return*/, new Promise(function (resolve, reject) {
197
+ var transaction = _this.db.transaction([_this.STORE_NAME], 'readonly');
198
+ var store = transaction.objectStore(_this.STORE_NAME);
199
+ var index = store.index('timestamp');
200
+ var request = index.openCursor(null, 'next');
201
+ var logs = [];
202
+ transaction.onerror = function () {
203
+ var _a, _b;
204
+ if (((_a = transaction.error) === null || _a === void 0 ? void 0 : _a.name) === 'UnknownError' || ((_b = transaction.error) === null || _b === void 0 ? void 0 : _b.name) === 'NotFoundError') {
205
+ _this.recreateDatabase().catch(function (error) {
206
+ console.warn('Database recreation failed:', error);
207
+ _this.useIndexedDB = false;
208
+ }).finally(function () { return resolve([]); });
209
+ }
210
+ else {
211
+ reject(transaction.error);
212
+ }
213
+ };
214
+ request.onsuccess = function (event) {
215
+ var cursor = event.target.result;
216
+ if (cursor && logs.length < limit) {
217
+ logs.push(cursor.value);
218
+ cursor.continue();
219
+ }
220
+ else {
221
+ resolve(logs.map(function (item) {
222
+ var _a;
223
+ return __assign(__assign({}, item), { id: (_a = item.id) === null || _a === void 0 ? void 0 : _a.toString() });
224
+ }));
225
+ }
226
+ };
227
+ request.onerror = function () {
228
+ var _a, _b;
229
+ if (((_a = request.error) === null || _a === void 0 ? void 0 : _a.name) === 'UnknownError' || ((_b = request.error) === null || _b === void 0 ? void 0 : _b.name) === 'NotFoundError') {
230
+ _this.recreateDatabase().catch(function (error) {
231
+ console.warn('Database recreation failed:', error);
232
+ _this.useIndexedDB = false;
233
+ }).finally(function () { return resolve([]); });
234
+ }
235
+ else {
236
+ reject(request.error);
237
+ }
238
+ };
239
+ })];
240
+ case 4:
241
+ error_2 = _a.sent();
242
+ this.useIndexedDB = false;
243
+ return [2 /*return*/, []];
244
+ case 5: return [2 /*return*/];
245
+ }
246
+ });
247
+ });
248
+ };
249
+ AliTrackLogger.prototype.deleteLogsFromIndexedDB = function (logsToDelete) {
250
+ return __awaiter(this, void 0, void 0, function () {
251
+ var error_3;
252
+ var _this = this;
253
+ return __generator(this, function (_a) {
254
+ switch (_a.label) {
255
+ case 0:
256
+ if (!this.useIndexedDB || logsToDelete.length === 0)
257
+ return [2 /*return*/];
258
+ _a.label = 1;
259
+ case 1:
260
+ _a.trys.push([1, 4, , 5]);
261
+ if (!(!this.db || !this.isDatabaseHealthy())) return [3 /*break*/, 3];
262
+ return [4 /*yield*/, this.recreateDatabase()];
263
+ case 2:
264
+ _a.sent();
265
+ if (!this.db || !this.useIndexedDB) {
266
+ return [2 /*return*/];
267
+ }
268
+ _a.label = 3;
269
+ case 3: return [2 /*return*/, new Promise(function (resolve, reject) {
270
+ var transaction = _this.db.transaction([_this.STORE_NAME], 'readwrite');
271
+ var store = transaction.objectStore(_this.STORE_NAME);
272
+ var deletePromises = logsToDelete.map(function (log) {
273
+ return new Promise(function (resolveDelete, rejectDelete) {
274
+ var logId = Number(log.id);
275
+ if (logId) {
276
+ var request_2 = store.delete(logId);
277
+ request_2.onsuccess = function () { return resolveDelete(); };
278
+ request_2.onerror = function () {
279
+ var _a, _b;
280
+ if (((_a = request_2.error) === null || _a === void 0 ? void 0 : _a.name) === 'UnknownError' || ((_b = request_2.error) === null || _b === void 0 ? void 0 : _b.name) === 'NotFoundError') {
281
+ // Database might have been deleted, ignore deletion errors
282
+ resolveDelete();
283
+ }
284
+ else {
285
+ rejectDelete(request_2.error);
286
+ }
287
+ };
288
+ }
289
+ else {
290
+ resolveDelete();
291
+ }
292
+ });
293
+ });
294
+ transaction.onerror = function () {
295
+ var _a, _b;
296
+ if (((_a = transaction.error) === null || _a === void 0 ? void 0 : _a.name) === 'UnknownError' || ((_b = transaction.error) === null || _b === void 0 ? void 0 : _b.name) === 'NotFoundError') {
297
+ _this.recreateDatabase().catch(function (error) {
298
+ console.warn('Database recreation failed:', error);
299
+ _this.useIndexedDB = false;
300
+ }).finally(function () { return resolve(); });
301
+ }
302
+ else {
303
+ reject(transaction.error);
304
+ }
305
+ };
306
+ Promise.all(deletePromises)
307
+ .then(function () { return resolve(); })
308
+ .catch(reject);
309
+ })];
310
+ case 4:
311
+ error_3 = _a.sent();
312
+ this.useIndexedDB = false;
313
+ return [3 /*break*/, 5];
314
+ case 5: return [2 /*return*/];
315
+ }
316
+ });
317
+ });
318
+ };
56
319
  AliTrackLogger.prototype.start = function () {
57
320
  return __awaiter(this, void 0, void 0, function () {
58
321
  var _this = this;
@@ -76,11 +339,93 @@ var AliTrackLogger = /** @class */ (function () {
76
339
  clearInterval(this.checkTimer);
77
340
  };
78
341
  AliTrackLogger.prototype.addLog = function (message, level, taskId, randomId) {
79
- this.logList.push({ level: level, taskId: taskId, message: message, randomId: randomId });
342
+ return __awaiter(this, void 0, void 0, function () {
343
+ var log, error_4;
344
+ return __generator(this, function (_a) {
345
+ switch (_a.label) {
346
+ case 0:
347
+ log = { level: level, taskId: taskId, message: message, randomId: randomId, timestamp: Date.now().toString() };
348
+ if (!this.useIndexedDB) return [3 /*break*/, 5];
349
+ _a.label = 1;
350
+ case 1:
351
+ _a.trys.push([1, 3, , 4]);
352
+ return [4 /*yield*/, this.storeLogInIndexedDB(log)];
353
+ case 2:
354
+ _a.sent();
355
+ return [3 /*break*/, 4];
356
+ case 3:
357
+ error_4 = _a.sent();
358
+ this.logList.push(log);
359
+ return [3 /*break*/, 4];
360
+ case 4: return [3 /*break*/, 6];
361
+ case 5:
362
+ this.logList.push(log);
363
+ _a.label = 6;
364
+ case 6: return [2 /*return*/];
365
+ }
366
+ });
367
+ });
368
+ };
369
+ AliTrackLogger.prototype.isDatabaseHealthy = function () {
370
+ if (!this.db)
371
+ return false;
372
+ try {
373
+ // Check if the database connection is still valid and object store exists
374
+ var transaction = this.db.transaction([this.STORE_NAME], 'readonly');
375
+ var store = transaction.objectStore(this.STORE_NAME);
376
+ // Actually try to access the store to validate it exists and works
377
+ var index = store.index('timestamp');
378
+ return true;
379
+ }
380
+ catch (error) {
381
+ console.warn('Database health check failed:', error);
382
+ return false;
383
+ }
384
+ };
385
+ AliTrackLogger.prototype.recreateDatabase = function () {
386
+ return __awaiter(this, void 0, void 0, function () {
387
+ var _this = this;
388
+ return __generator(this, function (_a) {
389
+ return [2 /*return*/, new Promise(function (resolve, reject) {
390
+ try {
391
+ // Close existing connection if any
392
+ if (_this.db) {
393
+ _this.db.close();
394
+ _this.db = null;
395
+ }
396
+ var request_3 = indexedDB.open(_this.DB_NAME, 1);
397
+ request_3.onerror = function () {
398
+ _this.useIndexedDB = false;
399
+ reject(request_3.error);
400
+ };
401
+ request_3.onsuccess = function () {
402
+ _this.db = request_3.result;
403
+ _this.useIndexedDB = true;
404
+ resolve();
405
+ };
406
+ request_3.onupgradeneeded = function (event) {
407
+ var db = event.target.result;
408
+ if (!db.objectStoreNames.contains(_this.STORE_NAME)) {
409
+ var store = db.createObjectStore(_this.STORE_NAME, { keyPath: 'id', autoIncrement: true });
410
+ store.createIndex('timestamp', 'timestamp');
411
+ }
412
+ };
413
+ }
414
+ catch (error) {
415
+ _this.useIndexedDB = false;
416
+ reject(error);
417
+ }
418
+ })];
419
+ });
420
+ });
80
421
  };
81
422
  AliTrackLogger.prototype.destroy = function () {
82
423
  clearInterval(this.checkTimer);
83
424
  window.removeEventListener("message", this.uploadLoggerGlobalEvent);
425
+ if (this.db) {
426
+ this.db.close();
427
+ this.db = null;
428
+ }
84
429
  };
85
430
  AliTrackLogger.prototype.uploadLog = function (focus) {
86
431
  if (focus === void 0) { focus = false; }
@@ -90,20 +435,34 @@ var AliTrackLogger = /** @class */ (function () {
90
435
  return __generator(this, function (_a) {
91
436
  switch (_a.label) {
92
437
  case 0:
438
+ uploadLog = [];
439
+ if (!this.useIndexedDB) return [3 /*break*/, 2];
440
+ return [4 /*yield*/, this.getLogsFromIndexedDB(this.BATCH_SIZE)];
441
+ case 1:
442
+ uploadLog = _a.sent();
443
+ if (uploadLog.length === 0) {
444
+ return [2 /*return*/];
445
+ }
446
+ return [3 /*break*/, 3];
447
+ case 2:
93
448
  if (!(this.logList.length >= this.config.buffer || focus)) {
94
449
  return [2 /*return*/];
95
450
  }
96
451
  uploadLog = this.logList.splice(0);
452
+ _a.label = 3;
453
+ case 3:
97
454
  errHandle = function () {
98
- _this.logList = uploadLog.concat(_this.logList);
455
+ if (!_this.useIndexedDB) {
456
+ _this.logList = uploadLog.concat(_this.logList);
457
+ }
99
458
  if (_this.retryTimes > 3) {
100
459
  _this.pause();
101
460
  }
102
461
  _this.retryTimes += 1;
103
462
  };
104
- _a.label = 1;
105
- case 1:
106
- _a.trys.push([1, 3, , 4]);
463
+ _a.label = 4;
464
+ case 4:
465
+ _a.trys.push([4, 10, , 11]);
107
466
  return [4 /*yield*/, fetch("https://netless-ppt-plugin-dev.cn-hangzhou.log.aliyuncs.com/logstores/netless-ppt-plugin-dev/track", {
108
467
  method: "POST",
109
468
  headers: {
@@ -117,21 +476,26 @@ var AliTrackLogger = /** @class */ (function () {
117
476
  __logs__: uploadLog,
118
477
  })
119
478
  })];
120
- case 2:
479
+ case 5:
121
480
  res = _a.sent();
122
- if (res.ok) {
123
- this.retryTimes = 0;
124
- }
125
- else {
126
- errHandle();
127
- }
128
- return [3 /*break*/, 4];
129
- case 3:
481
+ if (!res.ok) return [3 /*break*/, 8];
482
+ this.retryTimes = 0;
483
+ if (!this.useIndexedDB) return [3 /*break*/, 7];
484
+ return [4 /*yield*/, this.deleteLogsFromIndexedDB(uploadLog)];
485
+ case 6:
486
+ _a.sent();
487
+ _a.label = 7;
488
+ case 7: return [3 /*break*/, 9];
489
+ case 8:
490
+ errHandle();
491
+ _a.label = 9;
492
+ case 9: return [3 /*break*/, 11];
493
+ case 10:
130
494
  e_1 = _a.sent();
131
495
  console.warn(e_1);
132
496
  errHandle();
133
- return [3 /*break*/, 4];
134
- case 4: return [2 /*return*/];
497
+ return [3 /*break*/, 11];
498
+ case 11: return [2 /*return*/];
135
499
  }
136
500
  });
137
501
  });
@@ -11,14 +11,14 @@ var FrozenTaskManager = /** @class */ (function () {
11
11
  task.status = "running";
12
12
  task.fn.apply(null).then(function () {
13
13
  if (_this.tasks.length > 0) {
14
- window.requestAnimationFrame(_this.schedule);
14
+ setTimeout(_this.schedule);
15
15
  }
16
16
  else {
17
17
  _this.isScheduling = false;
18
18
  }
19
19
  }).catch(function () {
20
20
  if (_this.tasks.length > 0) {
21
- window.requestAnimationFrame(_this.schedule);
21
+ setTimeout(_this.schedule);
22
22
  }
23
23
  else {
24
24
  _this.isScheduling = false;
@@ -97,6 +97,16 @@ var PlayerConfig = /** @class */ (function () {
97
97
  enumerable: false,
98
98
  configurable: true
99
99
  });
100
+ Object.defineProperty(PlayerConfig.prototype, "maxResolutionLevel", {
101
+ get: function () {
102
+ return this.player.config.maxResolutionLevel;
103
+ },
104
+ set: function (value) {
105
+ this.player.updateConfig({ maxResolutionLevel: value });
106
+ },
107
+ enumerable: false,
108
+ configurable: true
109
+ });
100
110
  return PlayerConfig;
101
111
  }());
102
112
  export { PlayerConfig };
@@ -145,6 +155,7 @@ var PlayerController = /** @class */ (function () {
145
155
  resolution: gui.add(this.config, "resolution", 0.5, 8, 0.5),
146
156
  autoResolution: gui.add(this.config, "autoResolution"),
147
157
  autoFps: gui.add(this.config, "autoFPS"),
158
+ maxResolutionLevel: gui.add(this.config, "maxResolutionLevel", 0, 4, 1),
148
159
  transactionBgColor: gui.addColor(this.config, "backgroundColor"),
149
160
  };
150
161
  return [gui, controller];
@@ -104,6 +104,7 @@ var RenderingTaskManager = /** @class */ (function () {
104
104
  _this.tasks.splice(selfIndex, 1);
105
105
  _this.replaceIdleTask();
106
106
  }
107
+ _this.eventHub.emit("task-error-".concat(task.id));
107
108
  });
108
109
  }
109
110
  RenderingTaskManager.prototype.replaceIdleTask = function () {
package/lib/Slide.d.ts CHANGED
@@ -420,6 +420,8 @@ export declare class Slide extends Slide_base {
420
420
  * 设置全局音量, 对所有 Slide 实例都生效
421
421
  */
422
422
  static volumeAdjuster: VolumeAdjuster;
423
+ static __stageCountLimit: number;
424
+ static setStageCountLimit(limit: number): void;
423
425
  private iosResetCache;
424
426
  private iosNewPlayer?;
425
427
  private version?;
@@ -485,6 +487,7 @@ export declare class Slide extends Slide_base {
485
487
  private handleViewTouchEnd;
486
488
  private createController;
487
489
  private handleSlideRef;
490
+ private updateStageCountLimit;
488
491
  private setMedianControllerAttribute;
489
492
  private frameResizeHandler;
490
493
  /**