@lvce-editor/status-bar-worker 3.24.0 → 3.25.0

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.
@@ -3,29 +3,100 @@ const toCommandId = key => {
3
3
  return key.slice(dotIndex + 1);
4
4
  };
5
5
  const create$8 = () => {
6
+ const commandQueues = new Map();
7
+ const generations = Object.create(null);
6
8
  const states = Object.create(null);
7
- const commandMapRef = {};
9
+ const commandMapRef = Object.create(null);
10
+ const commandsById = Object.create(null);
11
+ const getGeneration = uid => generations[uid] || 0;
12
+ const isCurrentGeneration = (uid, generation) => {
13
+ return states[uid] !== undefined && getGeneration(uid) === generation;
14
+ };
15
+ const updateState = (uid, generation, fallbackState, updater) => {
16
+ if (!isCurrentGeneration(uid, generation)) {
17
+ return Promise.resolve(fallbackState);
18
+ }
19
+ const current = states[uid];
20
+ const updatedState = updater(current.newState);
21
+ if (updatedState !== current.newState) {
22
+ states[uid] = {
23
+ newState: updatedState,
24
+ oldState: current.oldState,
25
+ scheduledState: updatedState
26
+ };
27
+ }
28
+ return Promise.resolve(updatedState);
29
+ };
30
+ const createAsyncCommandContext = (uid, generation) => {
31
+ let latestState = states[uid].newState;
32
+ return {
33
+ getState: () => {
34
+ if (isCurrentGeneration(uid, generation)) {
35
+ latestState = states[uid].newState;
36
+ }
37
+ return latestState;
38
+ },
39
+ updateState: async updater => {
40
+ latestState = await updateState(uid, generation, latestState, updater);
41
+ return latestState;
42
+ }
43
+ };
44
+ };
45
+ const enqueueCommand = async (uid, command) => {
46
+ const previous = commandQueues.get(uid) || Promise.resolve();
47
+ const run = async () => {
48
+ try {
49
+ await previous;
50
+ } catch {
51
+ // The previous caller receives its error; later commands must still run.
52
+ }
53
+ await command();
54
+ };
55
+ const current = run();
56
+ commandQueues.set(uid, current);
57
+ try {
58
+ await current;
59
+ } finally {
60
+ if (commandQueues.get(uid) === current) {
61
+ commandQueues.delete(uid);
62
+ }
63
+ }
64
+ };
8
65
  return {
9
66
  clear() {
67
+ commandQueues.clear();
10
68
  for (const key of Object.keys(states)) {
11
69
  delete states[key];
12
70
  }
13
71
  },
72
+ createDirectEventCommandMap(requestRender) {
73
+ return {
74
+ async 'Viewlet.executeViewletCommand'(uid, command, ...args) {
75
+ const fn = commandsById[command];
76
+ if (!fn) {
77
+ throw new Error(`Viewlet command not found: ${command}`);
78
+ }
79
+ await fn(uid, ...args);
80
+ await requestRender(uid);
81
+ }
82
+ };
83
+ },
14
84
  diff(uid, modules, numbers) {
15
85
  const {
16
- newState,
17
- oldState
86
+ oldState,
87
+ scheduledState
18
88
  } = states[uid];
19
89
  const diffResult = [];
20
90
  for (let i = 0; i < modules.length; i++) {
21
91
  const fn = modules[i];
22
- if (!fn(oldState, newState)) {
92
+ if (!fn(oldState, scheduledState)) {
23
93
  diffResult.push(numbers[i]);
24
94
  }
25
95
  }
26
96
  return diffResult;
27
97
  },
28
98
  dispose(uid) {
99
+ commandQueues.delete(uid);
29
100
  delete states[uid];
30
101
  },
31
102
  get(uid) {
@@ -37,21 +108,36 @@ const create$8 = () => {
37
108
  return ids;
38
109
  },
39
110
  getKeys() {
40
- return Object.keys(states).map(key => {
41
- return Number.parseFloat(key);
42
- });
111
+ return Object.keys(states).map(Number);
43
112
  },
44
113
  registerCommands(commandMap) {
45
114
  Object.assign(commandMapRef, commandMap);
115
+ for (const [key, fn] of Object.entries(commandMap)) {
116
+ commandsById[toCommandId(key)] = fn;
117
+ }
46
118
  },
47
- set(uid, oldState, newState) {
119
+ set(uid, oldState, newState, scheduledState) {
120
+ const current = states[uid];
121
+ if (!current || oldState === newState && newState !== current.newState) {
122
+ generations[uid] = getGeneration(uid) + 1;
123
+ }
48
124
  states[uid] = {
49
125
  newState,
50
- oldState
126
+ oldState,
127
+ scheduledState: scheduledState ?? newState
128
+ };
129
+ },
130
+ wrapAsyncCommand(fn) {
131
+ const wrapped = async (uid, ...args) => {
132
+ const generation = getGeneration(uid);
133
+ const context = createAsyncCommandContext(uid, generation);
134
+ await fn(context, ...args);
51
135
  };
136
+ return wrapped;
52
137
  },
53
138
  wrapCommand(fn) {
54
139
  const wrapped = async (uid, ...args) => {
140
+ const generation = getGeneration(uid);
55
141
  const {
56
142
  newState,
57
143
  oldState
@@ -60,6 +146,9 @@ const create$8 = () => {
60
146
  if (oldState === newerState || newState === newerState) {
61
147
  return;
62
148
  }
149
+ if (!isCurrentGeneration(uid, generation)) {
150
+ return;
151
+ }
63
152
  const latestOld = states[uid];
64
153
  const latestNew = {
65
154
  ...latestOld.newState,
@@ -67,7 +156,8 @@ const create$8 = () => {
67
156
  };
68
157
  states[uid] = {
69
158
  newState: latestNew,
70
- oldState: latestOld.oldState
159
+ oldState: latestOld.oldState,
160
+ scheduledState: latestNew
71
161
  };
72
162
  };
73
163
  return wrapped;
@@ -83,6 +173,7 @@ const create$8 = () => {
83
173
  },
84
174
  wrapLoadContent(fn) {
85
175
  const wrapped = async (uid, ...args) => {
176
+ const generation = getGeneration(uid);
86
177
  const {
87
178
  newState,
88
179
  oldState
@@ -97,6 +188,11 @@ const create$8 = () => {
97
188
  error
98
189
  };
99
190
  }
191
+ if (!isCurrentGeneration(uid, generation)) {
192
+ return {
193
+ error
194
+ };
195
+ }
100
196
  const latestOld = states[uid];
101
197
  const latestNew = {
102
198
  ...latestOld.newState,
@@ -104,13 +200,59 @@ const create$8 = () => {
104
200
  };
105
201
  states[uid] = {
106
202
  newState: latestNew,
107
- oldState: latestOld.oldState
203
+ oldState: latestOld.oldState,
204
+ scheduledState: latestNew
108
205
  };
109
206
  return {
110
207
  error
111
208
  };
112
209
  };
113
210
  return wrapped;
211
+ },
212
+ wrapSerialAsyncCommand(fn) {
213
+ const wrapped = async (uid, ...args) => {
214
+ await enqueueCommand(uid, async () => {
215
+ if (!states[uid]) {
216
+ return;
217
+ }
218
+ const generation = getGeneration(uid);
219
+ const context = createAsyncCommandContext(uid, generation);
220
+ await fn(context, ...args);
221
+ });
222
+ };
223
+ return wrapped;
224
+ },
225
+ wrapSerialCommand(fn) {
226
+ const wrapped = async (uid, ...args) => {
227
+ await enqueueCommand(uid, async () => {
228
+ if (!states[uid]) {
229
+ return;
230
+ }
231
+ const generation = getGeneration(uid);
232
+ const {
233
+ newState,
234
+ oldState
235
+ } = states[uid];
236
+ const newerState = await fn(newState, ...args);
237
+ if (oldState === newerState || newState === newerState) {
238
+ return;
239
+ }
240
+ if (!isCurrentGeneration(uid, generation)) {
241
+ return;
242
+ }
243
+ const latestOld = states[uid];
244
+ const latestNew = {
245
+ ...latestOld.newState,
246
+ ...newerState
247
+ };
248
+ states[uid] = {
249
+ newState: latestNew,
250
+ oldState: latestOld.oldState,
251
+ scheduledState: latestNew
252
+ };
253
+ });
254
+ };
255
+ return wrapped;
114
256
  }
115
257
  };
116
258
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/status-bar-worker",
3
- "version": "3.24.0",
3
+ "version": "3.25.0",
4
4
  "description": "Status Bar Worker",
5
5
  "repository": {
6
6
  "type": "git",