@netless/slide 1.4.55-alpha.4 → 1.4.55-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,33 +1,205 @@
1
+ function assertSyncEventQueuePolicy(policy) {
2
+ if (policy !== "fifo" && policy !== "latest-pending-render") {
3
+ throw new Error("Invalid sync event queue policy: " + policy);
4
+ }
5
+ }
6
+ export function resolveSyncEventQueuePolicy(mode, policy) {
7
+ if (policy === void 0) { policy = "fifo"; }
8
+ assertSyncEventQueuePolicy(policy);
9
+ return mode === "interactive" ? policy : "fifo";
10
+ }
11
+ function isPageScopedEvent(event) {
12
+ switch (event.type) {
13
+ case "renderSlide":
14
+ case "nextStep":
15
+ case "prevStep":
16
+ case "interactiveAnim":
17
+ case "mediaPlay":
18
+ case "mediaPause":
19
+ case "mediaSeek":
20
+ case "mediaFullscreen":
21
+ return true;
22
+ default:
23
+ return false;
24
+ }
25
+ }
1
26
  var SyncTaskManager = /** @class */ (function () {
2
- function SyncTaskManager(fn) {
27
+ function SyncTaskManager(fn, options) {
3
28
  var _this = this;
29
+ if (options === void 0) { options = {}; }
4
30
  this.tasks = [];
5
31
  this.isDestroy = false;
6
32
  this.isScheduling = false;
33
+ this.isTaskRunning = false;
34
+ this.isCatchingUp = false;
35
+ this.compactedTasks = new WeakMap();
36
+ this.finishTask = function () {
37
+ _this.isTaskRunning = false;
38
+ _this.runningTask = undefined;
39
+ if (_this.isDestroy) {
40
+ _this.tasks.length = 0;
41
+ _this.isScheduling = false;
42
+ }
43
+ else if (_this.tasks.length > 0) {
44
+ window.requestAnimationFrame(_this.schedule);
45
+ }
46
+ else {
47
+ _this.isScheduling = false;
48
+ _this.setCatchUpState(false);
49
+ }
50
+ };
7
51
  this.schedule = function () {
52
+ if (_this.isDestroy) {
53
+ _this.tasks.length = 0;
54
+ _this.isScheduling = false;
55
+ return;
56
+ }
8
57
  _this.isScheduling = true;
9
58
  var task = _this.tasks.shift();
10
- if (task && !_this.isDestroy) {
11
- _this.fn(task).finally(function () {
12
- if (_this.tasks.length > 0) {
13
- window.requestAnimationFrame(_this.schedule);
14
- }
15
- else {
16
- _this.isScheduling = false;
59
+ if (!task) {
60
+ _this.isScheduling = false;
61
+ return;
62
+ }
63
+ _this.isTaskRunning = true;
64
+ _this.runningTask = task;
65
+ var compactInfo = _this.compactedTasks.get(task);
66
+ try {
67
+ _this.fn(task).then(function () {
68
+ var _a;
69
+ _this.compactedTasks.delete(task);
70
+ if (compactInfo && !_this.isDestroy) {
71
+ try {
72
+ (_a = _this.onCompactedRenderComplete) === null || _a === void 0 ? void 0 : _a.call(_this, compactInfo, Date.now());
73
+ }
74
+ catch ( /* Observability must not interrupt synchronization. */_b) { /* Observability must not interrupt synchronization. */ }
17
75
  }
76
+ _this.finishTask();
77
+ }, function () {
78
+ _this.compactedTasks.delete(task);
79
+ _this.finishTask();
18
80
  });
19
81
  }
82
+ catch (_a) {
83
+ _this.compactedTasks.delete(task);
84
+ _this.finishTask();
85
+ }
20
86
  };
21
87
  this.fn = fn;
88
+ this.policy = options.policy || "fifo";
89
+ this.onCompact = options.onCompact;
90
+ this.onCompactedRenderComplete = options.onCompactedRenderComplete;
91
+ this.onCatchUpStateChange = options.onCatchUpStateChange;
92
+ this.shouldTrackCatchUpEvent = options.shouldTrackCatchUpEvent;
93
+ assertSyncEventQueuePolicy(this.policy);
22
94
  }
23
95
  SyncTaskManager.prototype.destroy = function () {
24
96
  this.isDestroy = true;
97
+ this.isCatchingUp = false;
98
+ this.runningTask = undefined;
99
+ this.tasks.length = 0;
100
+ };
101
+ SyncTaskManager.prototype.setPolicy = function (policy) {
102
+ assertSyncEventQueuePolicy(policy);
103
+ this.policy = policy;
104
+ };
105
+ SyncTaskManager.prototype.setCatchUpState = function (isCatchingUp) {
106
+ var _a;
107
+ if (this.isCatchingUp === isCatchingUp) {
108
+ return;
109
+ }
110
+ this.isCatchingUp = isCatchingUp;
111
+ try {
112
+ (_a = this.onCatchUpStateChange) === null || _a === void 0 ? void 0 : _a.call(this, isCatchingUp);
113
+ }
114
+ catch ( /* Observability must not interrupt synchronization. */_b) { /* Observability must not interrupt synchronization. */ }
25
115
  };
26
- SyncTaskManager.prototype.addTask = function (evt) {
27
- this.tasks.push(evt);
116
+ SyncTaskManager.prototype.isCatchUpEvent = function (event) {
117
+ var _a, _b;
118
+ try {
119
+ return (_b = (_a = this.shouldTrackCatchUpEvent) === null || _a === void 0 ? void 0 : _a.call(this, event)) !== null && _b !== void 0 ? _b : true;
120
+ }
121
+ catch (_c) {
122
+ return true;
123
+ }
124
+ };
125
+ SyncTaskManager.prototype.compactForRender = function (event) {
126
+ var droppedEventTypes = {};
127
+ var droppedEventCount = 0;
128
+ var droppedRenderCount = 0;
129
+ var droppedStepCount = 0;
130
+ var droppedAnimationCount = 0;
131
+ var droppedMediaCount = 0;
132
+ while (this.tasks.length > 0) {
133
+ var pendingEvent = this.tasks[this.tasks.length - 1];
134
+ if (!isPageScopedEvent(pendingEvent)) {
135
+ break;
136
+ }
137
+ this.tasks.pop();
138
+ this.compactedTasks.delete(pendingEvent);
139
+ droppedEventCount += 1;
140
+ droppedEventTypes[pendingEvent.type] = (droppedEventTypes[pendingEvent.type] || 0) + 1;
141
+ if (pendingEvent.type === "renderSlide") {
142
+ droppedRenderCount += 1;
143
+ }
144
+ else if (pendingEvent.type === "nextStep" || pendingEvent.type === "prevStep") {
145
+ droppedStepCount += 1;
146
+ }
147
+ else if (pendingEvent.type === "interactiveAnim") {
148
+ droppedAnimationCount += 1;
149
+ }
150
+ else {
151
+ droppedMediaCount += 1;
152
+ }
153
+ }
154
+ if (droppedEventCount === 0) {
155
+ return undefined;
156
+ }
157
+ var boundaryEvent = this.tasks[this.tasks.length - 1];
158
+ return {
159
+ policy: "latest-pending-render",
160
+ droppedEventCount: droppedEventCount,
161
+ droppedRenderCount: droppedRenderCount,
162
+ droppedStepCount: droppedStepCount,
163
+ droppedAnimationCount: droppedAnimationCount,
164
+ droppedMediaCount: droppedMediaCount,
165
+ droppedOperationCount: droppedEventCount - droppedRenderCount,
166
+ droppedEventTypes: droppedEventTypes,
167
+ retainedSlideIndex: event.index,
168
+ retainedRenderReceivedAt: Date.now(),
169
+ hasRunningTask: this.isTaskRunning,
170
+ hardBoundaryType: boundaryEvent === null || boundaryEvent === void 0 ? void 0 : boundaryEvent.type,
171
+ };
172
+ };
173
+ SyncTaskManager.prototype.addTask = function (event) {
174
+ var _this = this;
175
+ var _a;
176
+ if (this.isDestroy) {
177
+ return undefined;
178
+ }
179
+ var hasPendingWork = this.isTaskRunning || this.tasks.length > 0;
180
+ var isIncomingCatchUpEvent = this.policy === "latest-pending-render" && this.isCatchUpEvent(event);
181
+ var hasCatchUpEvent = this.policy === "latest-pending-render" && (isIncomingCatchUpEvent ||
182
+ (!!this.runningTask && this.isCatchUpEvent(this.runningTask)) ||
183
+ this.tasks.some(function (pendingEvent) { return _this.isCatchUpEvent(pendingEvent); }));
184
+ var compactInfo = this.policy === "latest-pending-render" && event.type === "renderSlide" ?
185
+ this.compactForRender(event) :
186
+ undefined;
187
+ this.tasks.push(event);
188
+ var shouldStartCatchUp = hasCatchUpEvent && (hasPendingWork || (isIncomingCatchUpEvent && event.type === "renderSlide"));
189
+ if (shouldStartCatchUp) {
190
+ this.setCatchUpState(true);
191
+ }
192
+ if (compactInfo) {
193
+ this.compactedTasks.set(event, compactInfo);
194
+ try {
195
+ (_a = this.onCompact) === null || _a === void 0 ? void 0 : _a.call(this, compactInfo);
196
+ }
197
+ catch ( /* Observability must not interrupt synchronization. */_b) { /* Observability must not interrupt synchronization. */ }
198
+ }
28
199
  if (!this.isScheduling) {
29
200
  this.schedule();
30
201
  }
202
+ return compactInfo;
31
203
  };
32
204
  return SyncTaskManager;
33
205
  }());
@@ -0,0 +1,10 @@
1
+ import { SyncEvent, SyncInteractiveAnimEvent, SyncMediaFullscreenEvent, SyncMediaPauseEvent, SyncMediaPlayEvent, SyncMediaSeekEvent, SyncNextStepEvent, SyncPrevStepEvent, SyncRenderSlideEvent, SyncSetResourceEvent } from "../Slide";
2
+ export declare function isSyncInteractiveAnimEvent(event: SyncEvent): event is SyncInteractiveAnimEvent;
3
+ export declare function isSyncPrevStepEvent(event: SyncEvent): event is SyncPrevStepEvent;
4
+ export declare function isSyncNextStepEvent(event: SyncEvent): event is SyncNextStepEvent;
5
+ export declare function isSyncRenderSlideEvent(event: SyncEvent): event is SyncRenderSlideEvent;
6
+ export declare function isSyncSetResourceEvent(event: SyncEvent): event is SyncSetResourceEvent;
7
+ export declare function isSyncMediaPlayEvent(event: SyncEvent): event is SyncMediaPlayEvent;
8
+ export declare function isSyncMediaPauseEvent(event: SyncEvent): event is SyncMediaPauseEvent;
9
+ export declare function isSyncMediaSeekEvent(event: SyncEvent): event is SyncMediaSeekEvent;
10
+ export declare function isSyncMediaFullscreenEvent(event: SyncEvent): event is SyncMediaFullscreenEvent;
@@ -0,0 +1,27 @@
1
+ export function isSyncInteractiveAnimEvent(event) {
2
+ return event.type === "interactiveAnim";
3
+ }
4
+ export function isSyncPrevStepEvent(event) {
5
+ return event.type === "prevStep";
6
+ }
7
+ export function isSyncNextStepEvent(event) {
8
+ return event.type === "nextStep";
9
+ }
10
+ export function isSyncRenderSlideEvent(event) {
11
+ return event.type === "renderSlide";
12
+ }
13
+ export function isSyncSetResourceEvent(event) {
14
+ return event.type === "setResource";
15
+ }
16
+ export function isSyncMediaPlayEvent(event) {
17
+ return event.type === "mediaPlay";
18
+ }
19
+ export function isSyncMediaPauseEvent(event) {
20
+ return event.type === "mediaPause";
21
+ }
22
+ export function isSyncMediaSeekEvent(event) {
23
+ return event.type === "mediaSeek";
24
+ }
25
+ export function isSyncMediaFullscreenEvent(event) {
26
+ return event.type === "mediaFullscreen";
27
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/slide",
3
- "version": "1.4.55-alpha.4",
3
+ "version": "1.4.55-alpha.6",
4
4
  "description": "> TODO: description",
5
5
  "author": "huaguzheng <huaguzheng2007@126.com>",
6
6
  "homepage": "https://github.com/netless-io/netless-slide-demo",
@@ -16,7 +16,7 @@
16
16
  ],
17
17
  "scripts": {
18
18
  "dev": "tsc",
19
- "test": "node __tests__/FrozenMediaState.test.js",
19
+ "test": "node __tests__/SyncTaskManager.test.js && node __tests__/FrozenMediaState.test.js",
20
20
  "build": "webpack --config webpack.config.js",
21
21
  "watch": "webpack --config webpack.config.js --watch"
22
22
  },
@@ -37,5 +37,5 @@
37
37
  "publishConfig": {
38
38
  "access": "public"
39
39
  },
40
- "gitHead": "3375eb8aa9ca3007dc644274f08850552f51398f"
40
+ "gitHead": "dd66331095e888ff187059ed36e6e3dc4050a6e7"
41
41
  }