@adecore/editor 0.39.0 → 0.40.1
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/controller.d.ts +1 -0
- package/dist/controller.js +17 -28
- package/dist/engine.js +2 -9
- package/dist/find.js +12 -13
- package/dist/layout.js +7 -2
- package/dist/paint.d.ts +2 -0
- package/dist/paint.js +23 -20
- package/dist/view.d.ts +3 -2
- package/dist/view.js +46 -59
- package/package.json +6 -6
- package/src/attribution.ts +14 -0
- package/src/code-block.ts +25 -0
- package/src/column-selection.ts +10 -0
- package/src/controller.ts +189 -28
- package/src/engine.ts +87 -9
- package/src/fake.ts +79 -0
- package/src/find-search.ts +20 -0
- package/src/find.ts +135 -14
- package/src/geometry-stops.ts +10 -0
- package/src/grammar-preparation.ts +23 -0
- package/src/index.ts +1 -0
- package/src/input.ts +13 -0
- package/src/keymap-table.ts +9 -0
- package/src/keymap.ts +25 -0
- package/src/layout-changes.ts +7 -0
- package/src/layout.ts +219 -3
- package/src/lens.ts +3 -0
- package/src/listeners.ts +1 -0
- package/src/metrics.ts +14 -0
- package/src/modifier-gesture.ts +17 -0
- package/src/native-input.ts +27 -0
- package/src/offsets.ts +10 -0
- package/src/outline.ts +38 -0
- package/src/overview.ts +13 -0
- package/src/paint.ts +140 -20
- package/src/php-html.ts +1 -0
- package/src/pointer.ts +50 -0
- package/src/scroll-animation.ts +10 -0
- package/src/scroll.ts +7 -0
- package/src/search-client.ts +32 -0
- package/src/search-worker.ts +38 -0
- package/src/semantic.ts +12 -0
- package/src/shiki-document.ts +19 -0
- package/src/shiki-worker.ts +68 -0
- package/src/shiki.ts +37 -0
- package/src/testing.ts +17 -0
- package/src/theme-scopes.ts +14 -0
- package/src/tokens.ts +31 -0
- package/src/touch.ts +16 -0
- package/src/tracked-range.ts +5 -0
- package/src/uniform-geometry.ts +10 -0
- package/src/view.ts +481 -75
- package/src/worker-client.ts +54 -0
package/src/worker-client.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
export type WorkerRequestPort = Pick<Worker, 'addEventListener' | 'removeEventListener' | 'postMessage' | 'terminate'>;
|
|
2
2
|
export type WorkerRequestErrorKind = 'timeout' | 'superseded' | 'unavailable' | 'error' | 'disposed';
|
|
3
|
+
|
|
3
4
|
export class WorkerRequestError extends Error {
|
|
4
5
|
readonly kind: WorkerRequestErrorKind;
|
|
6
|
+
|
|
5
7
|
constructor(kind: WorkerRequestErrorKind, message: string) {
|
|
6
8
|
super(message);
|
|
7
9
|
this.kind = kind;
|
|
8
10
|
this.name = 'WorkerRequestError';
|
|
9
11
|
}
|
|
10
12
|
}
|
|
13
|
+
|
|
11
14
|
export interface WorkerRequestOptions<Input extends { id: number }, Output extends { id: number }> {
|
|
12
15
|
readonly workerFactory: () => WorkerRequestPort;
|
|
13
16
|
readonly deadline?: number;
|
|
@@ -17,30 +20,38 @@ export interface WorkerRequestOptions<Input extends { id: number }, Output exten
|
|
|
17
20
|
readonly failure?: (reply: Output) => { error: Error; restart: boolean } | undefined;
|
|
18
21
|
readonly stopped?: () => void;
|
|
19
22
|
}
|
|
23
|
+
|
|
20
24
|
export interface WorkerRequestClient<Input extends { id: number }, Output extends { id: number }> {
|
|
21
25
|
request(input: (id: number) => Input, deadline?: number, validate?: () => void): Promise<Output>;
|
|
22
26
|
cancel(): void;
|
|
23
27
|
release(): void;
|
|
24
28
|
dispose(): void;
|
|
25
29
|
}
|
|
30
|
+
|
|
26
31
|
function scheduleTimer(callback: () => void, delay: number): () => void {
|
|
27
32
|
const timer = setTimeout(callback, delay);
|
|
33
|
+
|
|
28
34
|
return () => clearTimeout(timer);
|
|
29
35
|
}
|
|
36
|
+
|
|
30
37
|
export function createWorkerRequestClient<Input extends { id: number }, Output extends { id: number }>(
|
|
31
38
|
options: WorkerRequestOptions<Input, Output>
|
|
32
39
|
): WorkerRequestClient<Input, Output> {
|
|
33
40
|
const deadline = options.deadline ?? 1500;
|
|
41
|
+
|
|
34
42
|
if (!Number.isFinite(deadline) || deadline <= 0 || deadline > 2147483647) {
|
|
35
43
|
throw new RangeError('The worker deadline must fit a positive browser timer.');
|
|
36
44
|
}
|
|
45
|
+
|
|
37
46
|
const schedule = options.schedule ?? scheduleTimer;
|
|
38
47
|
type Request = { input: Input; deadline: number; resolve: (reply: Output) => void; reject: (error: Error) => void };
|
|
39
48
|
let worker: WorkerRequestPort | undefined, detach: (() => void) | undefined, cancelTimer: (() => void) | undefined;
|
|
40
49
|
let active: Request | undefined, pending: Request | undefined;
|
|
41
50
|
let unavailable: WorkerRequestError | undefined;
|
|
51
|
+
|
|
42
52
|
let disposed = false,
|
|
43
53
|
nextId = 0;
|
|
54
|
+
|
|
44
55
|
const stopWorker = (): void => {
|
|
45
56
|
cancelTimer?.();
|
|
46
57
|
cancelTimer = undefined;
|
|
@@ -51,60 +62,82 @@ export function createWorkerRequestClient<Input extends { id: number }, Output e
|
|
|
51
62
|
options.stopped?.();
|
|
52
63
|
previous?.terminate();
|
|
53
64
|
};
|
|
65
|
+
|
|
54
66
|
const fail = (request: Request, error: Error, restart = true): void => {
|
|
55
67
|
if (active !== request) {
|
|
56
68
|
return;
|
|
57
69
|
}
|
|
70
|
+
|
|
58
71
|
active = undefined;
|
|
72
|
+
|
|
59
73
|
if (restart) {
|
|
60
74
|
stopWorker();
|
|
61
75
|
} else {
|
|
62
76
|
cancelTimer?.();
|
|
63
77
|
cancelTimer = undefined;
|
|
64
78
|
}
|
|
79
|
+
|
|
65
80
|
request.reject(error);
|
|
66
81
|
};
|
|
82
|
+
|
|
67
83
|
const startWorker = (): WorkerRequestPort => {
|
|
68
84
|
if (worker !== undefined) {
|
|
69
85
|
return worker;
|
|
70
86
|
}
|
|
87
|
+
|
|
71
88
|
let created: WorkerRequestPort;
|
|
89
|
+
|
|
72
90
|
try {
|
|
73
91
|
created = options.workerFactory();
|
|
74
92
|
} catch (error) {
|
|
75
93
|
unavailable = new WorkerRequestError('unavailable', error instanceof Error ? error.message : String(error));
|
|
94
|
+
|
|
76
95
|
throw unavailable;
|
|
77
96
|
}
|
|
97
|
+
|
|
78
98
|
worker = created;
|
|
79
99
|
let received = false;
|
|
100
|
+
|
|
80
101
|
const onMessage = (event: Event): void => {
|
|
81
102
|
if (worker !== created) {
|
|
82
103
|
return;
|
|
83
104
|
}
|
|
105
|
+
|
|
84
106
|
const reply = (event as MessageEvent<Output | { type: 'ready' }>).data;
|
|
107
|
+
|
|
85
108
|
if (reply === null || typeof reply !== 'object') {
|
|
86
109
|
if (active !== undefined) {
|
|
87
110
|
fail(active, new WorkerRequestError('error', 'The worker returned an invalid response.'));
|
|
88
111
|
}
|
|
112
|
+
|
|
89
113
|
return;
|
|
90
114
|
}
|
|
115
|
+
|
|
91
116
|
received = true;
|
|
117
|
+
|
|
92
118
|
if ('type' in reply && reply.type === 'ready') {
|
|
93
119
|
return;
|
|
94
120
|
}
|
|
121
|
+
|
|
95
122
|
const request = active;
|
|
123
|
+
|
|
96
124
|
if (request === undefined || !('id' in reply) || reply.id !== request.input.id) {
|
|
97
125
|
return;
|
|
98
126
|
}
|
|
127
|
+
|
|
99
128
|
try {
|
|
100
129
|
if (options.accepts?.(reply, request.input) === false) {
|
|
101
130
|
return;
|
|
102
131
|
}
|
|
132
|
+
|
|
103
133
|
const failure = options.failure?.(reply);
|
|
134
|
+
|
|
104
135
|
if (failure !== undefined) {
|
|
105
136
|
fail(request, failure.error, failure.restart);
|
|
137
|
+
|
|
106
138
|
return;
|
|
107
139
|
}
|
|
140
|
+
|
|
108
141
|
active = undefined;
|
|
109
142
|
cancelTimer?.();
|
|
110
143
|
cancelTimer = undefined;
|
|
@@ -113,47 +146,60 @@ export function createWorkerRequestClient<Input extends { id: number }, Output e
|
|
|
113
146
|
fail(request, new WorkerRequestError('error', error instanceof Error ? error.message : String(error)));
|
|
114
147
|
}
|
|
115
148
|
};
|
|
149
|
+
|
|
116
150
|
const onError = (event: Event): void => {
|
|
117
151
|
if (worker !== created) {
|
|
118
152
|
return;
|
|
119
153
|
}
|
|
154
|
+
|
|
120
155
|
const error = new WorkerRequestError(received ? 'error' : 'unavailable', (event as ErrorEvent).message || 'The worker failed.');
|
|
156
|
+
|
|
121
157
|
if (!received) {
|
|
122
158
|
unavailable = error;
|
|
123
159
|
}
|
|
160
|
+
|
|
124
161
|
if (active !== undefined) {
|
|
125
162
|
fail(active, error);
|
|
126
163
|
} else {
|
|
127
164
|
stopWorker();
|
|
128
165
|
}
|
|
129
166
|
};
|
|
167
|
+
|
|
130
168
|
const onMessageError = (): void => {
|
|
131
169
|
if (worker !== created) {
|
|
132
170
|
return;
|
|
133
171
|
}
|
|
172
|
+
|
|
134
173
|
if (active !== undefined) {
|
|
135
174
|
fail(active, new WorkerRequestError('error', 'The worker response could not be decoded.'));
|
|
136
175
|
} else {
|
|
137
176
|
stopWorker();
|
|
138
177
|
}
|
|
139
178
|
};
|
|
179
|
+
|
|
140
180
|
created.addEventListener('message', onMessage);
|
|
141
181
|
created.addEventListener('error', onError);
|
|
142
182
|
created.addEventListener('messageerror', onMessageError);
|
|
183
|
+
|
|
143
184
|
detach = () => {
|
|
144
185
|
created.removeEventListener('message', onMessage);
|
|
145
186
|
created.removeEventListener('error', onError);
|
|
146
187
|
created.removeEventListener('messageerror', onMessageError);
|
|
147
188
|
};
|
|
189
|
+
|
|
148
190
|
return created;
|
|
149
191
|
};
|
|
192
|
+
|
|
150
193
|
const pump = (): void => {
|
|
151
194
|
const request = pending;
|
|
195
|
+
|
|
152
196
|
if (disposed || request === undefined) {
|
|
153
197
|
return;
|
|
154
198
|
}
|
|
199
|
+
|
|
155
200
|
pending = undefined;
|
|
156
201
|
active = request;
|
|
202
|
+
|
|
157
203
|
try {
|
|
158
204
|
const target = startWorker();
|
|
159
205
|
cancelTimer = schedule(() => fail(request, new WorkerRequestError('timeout', 'The worker exceeded its time limit.')), request.deadline);
|
|
@@ -165,31 +211,39 @@ export function createWorkerRequestClient<Input extends { id: number }, Output e
|
|
|
165
211
|
);
|
|
166
212
|
}
|
|
167
213
|
};
|
|
214
|
+
|
|
168
215
|
const cancel = (kind: 'superseded' | 'disposed'): void => {
|
|
169
216
|
const error = new WorkerRequestError(kind, kind === 'disposed' ? 'The worker client was disposed.' : 'A newer request superseded this request.');
|
|
170
217
|
pending?.reject(error);
|
|
171
218
|
pending = undefined;
|
|
219
|
+
|
|
172
220
|
if (active !== undefined) {
|
|
173
221
|
fail(active, error);
|
|
174
222
|
}
|
|
175
223
|
};
|
|
224
|
+
|
|
176
225
|
return {
|
|
177
226
|
request(input, duration = deadline, validate) {
|
|
178
227
|
if (disposed) {
|
|
179
228
|
return Promise.reject(new WorkerRequestError('disposed', 'The worker client was disposed.'));
|
|
180
229
|
}
|
|
230
|
+
|
|
181
231
|
if (unavailable !== undefined) {
|
|
182
232
|
return Promise.reject(unavailable);
|
|
183
233
|
}
|
|
234
|
+
|
|
184
235
|
cancel('superseded');
|
|
236
|
+
|
|
185
237
|
try {
|
|
186
238
|
validate?.();
|
|
239
|
+
|
|
187
240
|
if (!Number.isFinite(duration) || duration <= 0 || duration > 2147483647) {
|
|
188
241
|
throw new RangeError('The request deadline must fit a positive browser timer.');
|
|
189
242
|
}
|
|
190
243
|
} catch (error) {
|
|
191
244
|
return Promise.reject(error);
|
|
192
245
|
}
|
|
246
|
+
|
|
193
247
|
return new Promise((resolve, reject) => {
|
|
194
248
|
pending = { input: input(++nextId), deadline: duration, resolve, reject };
|
|
195
249
|
// A burst before the microtask posts only its newest request.
|