@codingame/monaco-vscode-files-service-override 25.1.2 → 26.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codingame/monaco-vscode-files-service-override",
3
- "version": "25.1.2",
3
+ "version": "26.0.0",
4
4
  "private": false,
5
5
  "description": "VSCode public API plugged on the monaco editor - files service-override",
6
6
  "keywords": [],
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "type": "module",
17
17
  "dependencies": {
18
- "@codingame/monaco-vscode-api": "25.1.2"
18
+ "@codingame/monaco-vscode-api": "26.0.0"
19
19
  },
20
20
  "main": "index.js",
21
21
  "module": "index.js",
@@ -15,7 +15,7 @@ const ERR_FILE_IS_DIR = createFileSystemProviderError(( localize(1908, "File is
15
15
  const ERR_FILE_NOT_DIR = createFileSystemProviderError(( localize(1909, "File is not a directory")), FileSystemProviderErrorCode.FileNotADirectory);
16
16
  const ERR_DIR_NOT_EMPTY = createFileSystemProviderError(( localize(1910, "Directory is not empty")), FileSystemProviderErrorCode.Unknown);
17
17
  const ERR_FILE_EXCEEDS_STORAGE_QUOTA = createFileSystemProviderError(( localize(1911, "File exceeds available storage quota")), FileSystemProviderErrorCode.FileExceedsStorageQuota);
18
- const ERR_UNKNOWN_INTERNAL = (message) => createFileSystemProviderError(( localize(
18
+ const ERR_UNKNOWN_INTERNAL = message => createFileSystemProviderError(( localize(
19
19
  1912,
20
20
  "Internal error occurred in IndexedDB File System Provider. ({0})",
21
21
  message
@@ -26,14 +26,16 @@ class IndexedDBFileSystemNode {
26
26
  this.type = entry.type;
27
27
  }
28
28
  read(path) {
29
- return this.doRead(path.split('/').filter(p => p.length));
29
+ return this.doRead(path.split("/").filter(p => p.length));
30
30
  }
31
31
  doRead(pathParts) {
32
32
  if (pathParts.length === 0) {
33
33
  return this.entry;
34
34
  }
35
35
  if (this.entry.type !== FileType.Directory) {
36
- throw ERR_UNKNOWN_INTERNAL('Internal error reading from IndexedDBFSNode -- expected directory at ' + this.entry.path);
36
+ throw ERR_UNKNOWN_INTERNAL(
37
+ "Internal error reading from IndexedDBFSNode -- expected directory at " + this.entry.path
38
+ );
37
39
  }
38
40
  const next = this.entry.children.get(pathParts[0]);
39
41
  if (!next) {
@@ -42,90 +44,99 @@ class IndexedDBFileSystemNode {
42
44
  return next.doRead(pathParts.slice(1));
43
45
  }
44
46
  delete(path) {
45
- const toDelete = path.split('/').filter(p => p.length);
47
+ const toDelete = path.split("/").filter(p => p.length);
46
48
  if (toDelete.length === 0) {
47
49
  if (this.entry.type !== FileType.Directory) {
48
- throw ERR_UNKNOWN_INTERNAL(`Internal error deleting from IndexedDBFSNode. Expected root entry to be directory`);
50
+ throw ERR_UNKNOWN_INTERNAL(
51
+ `Internal error deleting from IndexedDBFSNode. Expected root entry to be directory`
52
+ );
49
53
  }
50
54
  this.entry.children.clear();
51
- }
52
- else {
55
+ } else {
53
56
  return this.doDelete(toDelete, path);
54
57
  }
55
58
  }
56
59
  doDelete(pathParts, originalPath) {
57
60
  if (pathParts.length === 0) {
58
- throw ERR_UNKNOWN_INTERNAL(`Internal error deleting from IndexedDBFSNode -- got no deletion path parts (encountered while deleting ${originalPath})`);
59
- }
60
- else if (this.entry.type !== FileType.Directory) {
61
- throw ERR_UNKNOWN_INTERNAL('Internal error deleting from IndexedDBFSNode -- expected directory at ' + this.entry.path);
62
- }
63
- else if (pathParts.length === 1) {
61
+ throw ERR_UNKNOWN_INTERNAL(
62
+ `Internal error deleting from IndexedDBFSNode -- got no deletion path parts (encountered while deleting ${originalPath})`
63
+ );
64
+ } else if (this.entry.type !== FileType.Directory) {
65
+ throw ERR_UNKNOWN_INTERNAL(
66
+ "Internal error deleting from IndexedDBFSNode -- expected directory at " + this.entry.path
67
+ );
68
+ } else if (pathParts.length === 1) {
64
69
  this.entry.children.delete(pathParts[0]);
65
- }
66
- else {
70
+ } else {
67
71
  const next = this.entry.children.get(pathParts[0]);
68
72
  if (!next) {
69
- throw ERR_UNKNOWN_INTERNAL('Internal error deleting from IndexedDBFSNode -- expected entry at ' + this.entry.path + '/' + next);
73
+ throw ERR_UNKNOWN_INTERNAL(
74
+ "Internal error deleting from IndexedDBFSNode -- expected entry at " + this.entry.path + "/" + next
75
+ );
70
76
  }
71
77
  next.doDelete(pathParts.slice(1), originalPath);
72
78
  }
73
79
  }
74
80
  add(path, entry) {
75
- this.doAdd(path.split('/').filter(p => p.length), entry, path);
81
+ this.doAdd(path.split("/").filter(p => p.length), entry, path);
76
82
  }
77
83
  doAdd(pathParts, entry, originalPath) {
78
84
  if (pathParts.length === 0) {
79
- throw ERR_UNKNOWN_INTERNAL(`Internal error creating IndexedDBFSNode -- adding empty path (encountered while adding ${originalPath})`);
80
- }
81
- else if (this.entry.type !== FileType.Directory) {
82
- throw ERR_UNKNOWN_INTERNAL(`Internal error creating IndexedDBFSNode -- parent is not a directory (encountered while adding ${originalPath})`);
83
- }
84
- else if (pathParts.length === 1) {
85
+ throw ERR_UNKNOWN_INTERNAL(
86
+ `Internal error creating IndexedDBFSNode -- adding empty path (encountered while adding ${originalPath})`
87
+ );
88
+ } else if (this.entry.type !== FileType.Directory) {
89
+ throw ERR_UNKNOWN_INTERNAL(
90
+ `Internal error creating IndexedDBFSNode -- parent is not a directory (encountered while adding ${originalPath})`
91
+ );
92
+ } else if (pathParts.length === 1) {
85
93
  const next = pathParts[0];
86
94
  const existing = this.entry.children.get(next);
87
- if (entry.type === 'dir') {
95
+ if (entry.type === "dir") {
88
96
  if (existing?.entry.type === FileType.File) {
89
- throw ERR_UNKNOWN_INTERNAL(`Internal error creating IndexedDBFSNode -- overwriting file with directory: ${this.entry.path}/${next} (encountered while adding ${originalPath})`);
97
+ throw ERR_UNKNOWN_INTERNAL(
98
+ `Internal error creating IndexedDBFSNode -- overwriting file with directory: ${this.entry.path}/${next} (encountered while adding ${originalPath})`
99
+ );
90
100
  }
91
101
  this.entry.children.set(next, existing ?? ( new IndexedDBFileSystemNode({
92
102
  type: FileType.Directory,
93
- path: this.entry.path + '/' + next,
94
- children: ( new Map()),
103
+ path: this.entry.path + "/" + next,
104
+ children: ( new Map())
95
105
  })));
96
- }
97
- else {
106
+ } else {
98
107
  if (existing?.entry.type === FileType.Directory) {
99
- throw ERR_UNKNOWN_INTERNAL(`Internal error creating IndexedDBFSNode -- overwriting directory with file: ${this.entry.path}/${next} (encountered while adding ${originalPath})`);
108
+ throw ERR_UNKNOWN_INTERNAL(
109
+ `Internal error creating IndexedDBFSNode -- overwriting directory with file: ${this.entry.path}/${next} (encountered while adding ${originalPath})`
110
+ );
100
111
  }
101
112
  this.entry.children.set(next, ( new IndexedDBFileSystemNode({
102
113
  type: FileType.File,
103
- path: this.entry.path + '/' + next,
104
- size: entry.size,
114
+ path: this.entry.path + "/" + next,
115
+ size: entry.size
105
116
  })));
106
117
  }
107
- }
108
- else if (pathParts.length > 1) {
118
+ } else if (pathParts.length > 1) {
109
119
  const next = pathParts[0];
110
120
  let childNode = this.entry.children.get(next);
111
121
  if (!childNode) {
112
122
  childNode = ( new IndexedDBFileSystemNode({
113
123
  children: ( new Map()),
114
- path: this.entry.path + '/' + next,
124
+ path: this.entry.path + "/" + next,
115
125
  type: FileType.Directory
116
126
  }));
117
127
  this.entry.children.set(next, childNode);
118
- }
119
- else if (childNode.type === FileType.File) {
120
- throw ERR_UNKNOWN_INTERNAL(`Internal error creating IndexedDBFSNode -- overwriting file entry with directory: ${this.entry.path}/${next} (encountered while adding ${originalPath})`);
128
+ } else if (childNode.type === FileType.File) {
129
+ throw ERR_UNKNOWN_INTERNAL(
130
+ `Internal error creating IndexedDBFSNode -- overwriting file entry with directory: ${this.entry.path}/${next} (encountered while adding ${originalPath})`
131
+ );
121
132
  }
122
133
  childNode.doAdd(pathParts.slice(1), entry, originalPath);
123
134
  }
124
135
  }
125
- print(indentation = '') {
136
+ print(indentation = "") {
126
137
  console.log(indentation + this.entry.path);
127
138
  if (this.entry.type === FileType.Directory) {
128
- this.entry.children.forEach(child => child.print(indentation + ' '));
139
+ this.entry.children.forEach(child => child.print(indentation + " "));
129
140
  }
130
141
  }
131
142
  }
@@ -135,8 +146,7 @@ class IndexedDBFileSystemProvider extends Disposable {
135
146
  this.scheme = scheme;
136
147
  this.indexedDB = indexedDB;
137
148
  this.store = store;
138
- this.capabilities = FileSystemProviderCapabilities.FileReadWrite
139
- | FileSystemProviderCapabilities.PathCaseSensitive;
149
+ this.capabilities = FileSystemProviderCapabilities.FileReadWrite | FileSystemProviderCapabilities.FileAppend | FileSystemProviderCapabilities.PathCaseSensitive;
140
150
  this.onDidChangeCapabilities = Event.None;
141
151
  this.extUri = ( new ExtUri(() => false)) ;
142
152
  this._onDidChangeFile = this._register(( new Emitter()));
@@ -147,7 +157,10 @@ class IndexedDBFileSystemProvider extends Disposable {
147
157
  if (watchCrossWindowChanges) {
148
158
  this.changesBroadcastChannel = this._register(( new BroadcastDataChannel(`vscode.indexedDB.${scheme}.changes`)));
149
159
  this._register(this.changesBroadcastChannel.onDidReceiveData(changes => {
150
- this._onDidChangeFile.fire(( changes.map(c => ({ type: c.type, resource: URI.revive(c.resource) }))));
160
+ this._onDidChangeFile.fire(( changes.map(c => ({
161
+ type: c.type,
162
+ resource: URI.revive(c.resource)
163
+ }))));
151
164
  }));
152
165
  }
153
166
  }
@@ -160,9 +173,10 @@ class IndexedDBFileSystemProvider extends Disposable {
160
173
  if (resourceStat.type === FileType.File) {
161
174
  throw ERR_FILE_NOT_DIR;
162
175
  }
163
- }
164
- catch (error) { }
165
- (await this.getFiletree()).add(resource.path, { type: 'dir' });
176
+ } catch (error) {}
177
+ (await this.getFiletree()).add(resource.path, {
178
+ type: "dir"
179
+ });
166
180
  }
167
181
  async stat(resource) {
168
182
  const entry = (await this.getFiletree()).read(resource.path);
@@ -191,13 +205,12 @@ class IndexedDBFileSystemProvider extends Disposable {
191
205
  }
192
206
  if (entry.type !== FileType.Directory) {
193
207
  throw ERR_FILE_NOT_DIR;
194
- }
195
- else {
208
+ } else {
196
209
  return ( [...entry.children.entries()].map(([name, node]) => [name, node.type]));
197
210
  }
198
211
  }
199
212
  async readFile(resource) {
200
- const result = await this.indexedDB.runInTransaction(this.store, 'readonly', objectStore => objectStore.get(resource.path));
213
+ const result = await this.indexedDB.runInTransaction(this.store, "readonly", objectStore => objectStore.get(resource.path));
201
214
  if (result === undefined) {
202
215
  throw ERR_FILE_NOT_FOUND;
203
216
  }
@@ -206,7 +219,10 @@ class IndexedDBFileSystemProvider extends Disposable {
206
219
  throw ERR_UNKNOWN_INTERNAL(`IndexedDB entry at "${resource.path}" in unexpected format`);
207
220
  }
208
221
  const fileTree = await this.getFiletree();
209
- fileTree.add(resource.path, { type: 'file', size: buffer.byteLength });
222
+ fileTree.add(resource.path, {
223
+ type: "file",
224
+ size: buffer.byteLength
225
+ });
210
226
  return buffer;
211
227
  }
212
228
  async writeFile(resource, content, opts) {
@@ -214,7 +230,15 @@ class IndexedDBFileSystemProvider extends Disposable {
214
230
  if (existing?.type === FileType.Directory) {
215
231
  throw ERR_FILE_IS_DIR;
216
232
  }
217
- await this.bulkWrite([[resource, content]]);
233
+ let finalContent = content;
234
+ if (opts.append && existing) {
235
+ const existingContent = await this.readFile(resource);
236
+ const combined = ( new Uint8Array(existingContent.byteLength + content.byteLength));
237
+ combined.set(existingContent, 0);
238
+ combined.set(content, existingContent.byteLength);
239
+ finalContent = combined;
240
+ }
241
+ await this.bulkWrite([[resource, finalContent]]);
218
242
  }
219
243
  async rename(from, to, opts) {
220
244
  const fileTree = await this.getFiletree();
@@ -225,27 +249,37 @@ class IndexedDBFileSystemProvider extends Disposable {
225
249
  const toEntry = fileTree.read(to.path);
226
250
  if (toEntry) {
227
251
  if (!opts.overwrite) {
228
- throw createFileSystemProviderError('file exists already', FileSystemProviderErrorCode.FileExists);
252
+ throw createFileSystemProviderError("file exists already", FileSystemProviderErrorCode.FileExists);
229
253
  }
230
254
  if (toEntry.type !== fromEntry.type) {
231
- throw createFileSystemProviderError('Cannot rename files with different types', FileSystemProviderErrorCode.Unknown);
255
+ throw createFileSystemProviderError(
256
+ "Cannot rename files with different types",
257
+ FileSystemProviderErrorCode.Unknown
258
+ );
232
259
  }
233
- await this.delete(to, { recursive: true, useTrash: false, atomic: false });
234
- }
235
- const toTargetResource = (path) => this.extUri.joinPath(to, this.extUri.relativePath(from, from.with({ path })) || '');
260
+ await this.delete(to, {
261
+ recursive: true,
262
+ useTrash: false,
263
+ atomic: false
264
+ });
265
+ }
266
+ const toTargetResource = path => this.extUri.joinPath(to, this.extUri.relativePath(from, from.with({
267
+ path
268
+ })) || "");
236
269
  const sourceEntries = await this.tree(from);
237
270
  const sourceFiles = [];
238
271
  for (const sourceEntry of sourceEntries) {
239
272
  if (sourceEntry[1] === FileType.File) {
240
273
  sourceFiles.push(sourceEntry);
241
- }
242
- else if (sourceEntry[1] === FileType.Directory) {
243
- fileTree.add(toTargetResource(sourceEntry[0]).path, { type: 'dir' });
274
+ } else if (sourceEntry[1] === FileType.Directory) {
275
+ fileTree.add(toTargetResource(sourceEntry[0]).path, {
276
+ type: "dir"
277
+ });
244
278
  }
245
279
  }
246
280
  if (sourceFiles.length) {
247
281
  const targetFiles = [];
248
- const sourceFilesContents = await this.indexedDB.runInTransaction(this.store, 'readonly', objectStore => ( sourceFiles.map(([path]) => objectStore.get(path))));
282
+ const sourceFilesContents = await this.indexedDB.runInTransaction(this.store, "readonly", objectStore => ( sourceFiles.map(([path]) => objectStore.get(path))));
249
283
  for (let index = 0; index < sourceFiles.length; index++) {
250
284
  const content = sourceFilesContents[index] instanceof Uint8Array ? sourceFilesContents[index] : isString(sourceFilesContents[index]) ? VSBuffer.fromString(sourceFilesContents[index]).buffer : undefined;
251
285
  if (content) {
@@ -254,14 +288,17 @@ class IndexedDBFileSystemProvider extends Disposable {
254
288
  }
255
289
  await this.bulkWrite(targetFiles);
256
290
  }
257
- await this.delete(from, { recursive: true, useTrash: false, atomic: false });
291
+ await this.delete(from, {
292
+ recursive: true,
293
+ useTrash: false,
294
+ atomic: false
295
+ });
258
296
  }
259
297
  async delete(resource, opts) {
260
298
  let stat;
261
299
  try {
262
300
  stat = await this.stat(resource);
263
- }
264
- catch (e) {
301
+ } catch (e) {
265
302
  if (e.code === FileSystemProviderErrorCode.FileNotFound) {
266
303
  return;
267
304
  }
@@ -271,8 +308,7 @@ class IndexedDBFileSystemProvider extends Disposable {
271
308
  if (opts.recursive) {
272
309
  const tree = await this.tree(resource);
273
310
  toDelete = ( tree.map(([path]) => path));
274
- }
275
- else {
311
+ } else {
276
312
  if (stat.type === FileType.Directory && (await this.readdir(resource)).length) {
277
313
  throw ERR_DIR_NOT_EMPTY;
278
314
  }
@@ -281,9 +317,12 @@ class IndexedDBFileSystemProvider extends Disposable {
281
317
  await this.deleteKeys(toDelete);
282
318
  (await this.getFiletree()).delete(resource.path);
283
319
  toDelete.forEach(key => this.mtimes.delete(key));
284
- this.triggerChanges(( toDelete.map(
285
- path => ({ resource: resource.with({ path }), type: FileChangeType.DELETED })
286
- )));
320
+ this.triggerChanges(( toDelete.map(path => ({
321
+ resource: resource.with({
322
+ path
323
+ }),
324
+ type: FileChangeType.DELETED
325
+ }))));
287
326
  }
288
327
  async tree(resource) {
289
328
  const stat = await this.stat(resource);
@@ -312,37 +351,47 @@ class IndexedDBFileSystemProvider extends Disposable {
312
351
  this.cachedFiletree = (async () => {
313
352
  const rootNode = ( new IndexedDBFileSystemNode({
314
353
  children: ( new Map()),
315
- path: '',
354
+ path: "",
316
355
  type: FileType.Directory
317
356
  }));
318
- const result = await this.indexedDB.runInTransaction(this.store, 'readonly', objectStore => objectStore.getAllKeys());
357
+ const result = await this.indexedDB.runInTransaction(this.store, "readonly", objectStore => objectStore.getAllKeys());
319
358
  const keys = ( result.map(key => ( key.toString())));
320
- keys.forEach(key => rootNode.add(key, { type: 'file' }));
359
+ keys.forEach(key => rootNode.add(key, {
360
+ type: "file"
361
+ }));
321
362
  return rootNode;
322
363
  })();
323
364
  }
324
365
  return this.cachedFiletree;
325
366
  }
326
367
  async bulkWrite(files) {
327
- files.forEach(([resource, content]) => this.fileWriteBatch.push({ content, resource }));
368
+ files.forEach(([resource, content]) => this.fileWriteBatch.push({
369
+ content,
370
+ resource
371
+ }));
328
372
  await this.writeManyThrottler.queue(() => this.writeMany());
329
373
  const fileTree = await this.getFiletree();
330
374
  for (const [resource, content] of files) {
331
- fileTree.add(resource.path, { type: 'file', size: content.byteLength });
375
+ fileTree.add(resource.path, {
376
+ type: "file",
377
+ size: content.byteLength
378
+ });
332
379
  this.mtimes.set(( resource.toString()), Date.now());
333
380
  }
334
- this.triggerChanges(( files.map(([resource]) => ({ resource, type: FileChangeType.UPDATED }))));
381
+ this.triggerChanges(( files.map(([resource]) => ({
382
+ resource,
383
+ type: FileChangeType.UPDATED
384
+ }))));
335
385
  }
336
386
  async writeMany() {
337
387
  if (this.fileWriteBatch.length) {
338
388
  const fileBatch = this.fileWriteBatch.splice(0, this.fileWriteBatch.length);
339
389
  try {
340
- await this.indexedDB.runInTransaction(this.store, 'readwrite', objectStore => ( fileBatch.map(entry => {
390
+ await this.indexedDB.runInTransaction(this.store, "readwrite", objectStore => ( fileBatch.map(entry => {
341
391
  return objectStore.put(entry.content, entry.resource.path);
342
392
  })));
343
- }
344
- catch (ex) {
345
- if (ex instanceof DOMException && ex.name === 'QuotaExceededError') {
393
+ } catch (ex) {
394
+ if (ex instanceof DOMException && ex.name === "QuotaExceededError") {
346
395
  throw ERR_FILE_EXCEEDS_STORAGE_QUOTA;
347
396
  }
348
397
  throw ex;
@@ -351,11 +400,11 @@ class IndexedDBFileSystemProvider extends Disposable {
351
400
  }
352
401
  async deleteKeys(keys) {
353
402
  if (keys.length) {
354
- await this.indexedDB.runInTransaction(this.store, 'readwrite', objectStore => ( keys.map(key => objectStore.delete(key))));
403
+ await this.indexedDB.runInTransaction(this.store, "readwrite", objectStore => ( keys.map(key => objectStore.delete(key))));
355
404
  }
356
405
  }
357
406
  async reset() {
358
- await this.indexedDB.runInTransaction(this.store, 'readwrite', objectStore => objectStore.clear());
407
+ await this.indexedDB.runInTransaction(this.store, "readwrite", objectStore => objectStore.clear());
359
408
  }
360
409
  }
361
410