@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.
Files changed (53) hide show
  1. package/dist/controller.d.ts +1 -0
  2. package/dist/controller.js +17 -28
  3. package/dist/engine.js +2 -9
  4. package/dist/find.js +12 -13
  5. package/dist/layout.js +7 -2
  6. package/dist/paint.d.ts +2 -0
  7. package/dist/paint.js +23 -20
  8. package/dist/view.d.ts +3 -2
  9. package/dist/view.js +46 -59
  10. package/package.json +6 -6
  11. package/src/attribution.ts +14 -0
  12. package/src/code-block.ts +25 -0
  13. package/src/column-selection.ts +10 -0
  14. package/src/controller.ts +189 -28
  15. package/src/engine.ts +87 -9
  16. package/src/fake.ts +79 -0
  17. package/src/find-search.ts +20 -0
  18. package/src/find.ts +135 -14
  19. package/src/geometry-stops.ts +10 -0
  20. package/src/grammar-preparation.ts +23 -0
  21. package/src/index.ts +1 -0
  22. package/src/input.ts +13 -0
  23. package/src/keymap-table.ts +9 -0
  24. package/src/keymap.ts +25 -0
  25. package/src/layout-changes.ts +7 -0
  26. package/src/layout.ts +219 -3
  27. package/src/lens.ts +3 -0
  28. package/src/listeners.ts +1 -0
  29. package/src/metrics.ts +14 -0
  30. package/src/modifier-gesture.ts +17 -0
  31. package/src/native-input.ts +27 -0
  32. package/src/offsets.ts +10 -0
  33. package/src/outline.ts +38 -0
  34. package/src/overview.ts +13 -0
  35. package/src/paint.ts +140 -20
  36. package/src/php-html.ts +1 -0
  37. package/src/pointer.ts +50 -0
  38. package/src/scroll-animation.ts +10 -0
  39. package/src/scroll.ts +7 -0
  40. package/src/search-client.ts +32 -0
  41. package/src/search-worker.ts +38 -0
  42. package/src/semantic.ts +12 -0
  43. package/src/shiki-document.ts +19 -0
  44. package/src/shiki-worker.ts +68 -0
  45. package/src/shiki.ts +37 -0
  46. package/src/testing.ts +17 -0
  47. package/src/theme-scopes.ts +14 -0
  48. package/src/tokens.ts +31 -0
  49. package/src/touch.ts +16 -0
  50. package/src/tracked-range.ts +5 -0
  51. package/src/uniform-geometry.ts +10 -0
  52. package/src/view.ts +481 -75
  53. package/src/worker-client.ts +54 -0
@@ -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.