@theia/filesystem 1.75.0 → 1.76.0-next.4

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.
@@ -12,6 +12,12 @@ export declare class FileTreeDecoratorAdapter implements TreeDecorator {
12
12
  protected readonly onDidChangeDecorationsEmitter: Emitter<(tree: Tree) => Map<string, TreeDecoration.Data>>;
13
13
  protected decorationsByUri: Map<string, TreeDecoration.Data>;
14
14
  protected parentDecorations: Map<string, TreeDecoration.Data>;
15
+ /**
16
+ * Resources already queried from the service since the last decoration change event.
17
+ * Undecorated resources never enter {@link decorationsByUri}, so without this set
18
+ * every render pass would re-query (and re-parse the URI of) every undecorated node.
19
+ */
20
+ protected readonly queriedUris: Set<string>;
15
21
  get onDidChangeDecorations(): Event<(tree: Tree) => Map<string, TreeDecoration.Data>>;
16
22
  protected init(): void;
17
23
  decorations(tree: Tree): MaybePromise<Map<string, TreeDecoration.Data>>;
@@ -1 +1 @@
1
- {"version":3,"file":"file-tree-decorator-adapter.d.ts","sourceRoot":"","sources":["../../../src/browser/file-tree/file-tree-decorator-adapter.ts"],"names":[],"mappings":"AAiBA,OAAO,GAAG,MAAM,4BAA4B,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAO,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAC7F,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,aAAa,EAAE,IAAI,EAAuB,MAAM,yBAAyB,CAAC;AAC7G,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAGvE,qBACa,wBAAyB,YAAW,aAAa;IAC1D,QAAQ,CAAC,EAAE,gDAAgD;IAC3D,SAAS,CAAC,QAAQ,CAAC,aAAa,SAAsD;IAC1D,SAAS,CAAC,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IAC/D,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IAEvE,SAAS,CAAC,QAAQ,CAAC,6BAA6B,iBAAsB,IAAI,KAAK,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,EAAI;IACnH,SAAS,CAAC,gBAAgB,mCAA0C;IACpE,SAAS,CAAC,iBAAiB,mCAA0C;IAErE,IAAI,sBAAsB,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,CAEpF;IAGD,SAAS,CAAC,IAAI,IAAI,IAAI;IAOtB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC;IAIvE,SAAS,CAAC,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC;IAmB1E,SAAS,CAAC,gBAAgB,CAAC,aAAa,CAAC,EAAE,cAAc,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,cAAc,CAAC,IAAI,GAAG,cAAc,CAAC,IAAI,GAAG,SAAS;IAczI,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,IAAI;IAsBvG,SAAS,CAAC,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC,IAAI;IAU7F,SAAS,CAAC,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC,cAAc,CAAC,WAAW;IAOnJ,SAAS,CAAC,yBAAyB,CAAC,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI;IAoBhF;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM;IAIpE,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS;IAI3D,wBAAwB,IAAI,IAAI;CAGnC"}
1
+ {"version":3,"file":"file-tree-decorator-adapter.d.ts","sourceRoot":"","sources":["../../../src/browser/file-tree/file-tree-decorator-adapter.ts"],"names":[],"mappings":"AAiBA,OAAO,GAAG,MAAM,4BAA4B,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAO,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAC7F,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,aAAa,EAAE,IAAI,EAAuB,MAAM,yBAAyB,CAAC;AAC7G,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAGvE,qBACa,wBAAyB,YAAW,aAAa;IAC1D,QAAQ,CAAC,EAAE,gDAAgD;IAC3D,SAAS,CAAC,QAAQ,CAAC,aAAa,SAAsD;IAC1D,SAAS,CAAC,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IAC/D,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IAEvE,SAAS,CAAC,QAAQ,CAAC,6BAA6B,iBAAsB,IAAI,KAAK,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,EAAI;IACnH,SAAS,CAAC,gBAAgB,mCAA0C;IACpE,SAAS,CAAC,iBAAiB,mCAA0C;IACrE;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,WAAW,cAAqB;IAEnD,IAAI,sBAAsB,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,CAEpF;IAGD,SAAS,CAAC,IAAI,IAAI,IAAI;IAQtB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC;IAIvE,SAAS,CAAC,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC;IAmC1E,SAAS,CAAC,gBAAgB,CAAC,aAAa,CAAC,EAAE,cAAc,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE,cAAc,CAAC,IAAI,GAAG,cAAc,CAAC,IAAI,GAAG,SAAS;IAczI,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,IAAI;IAuBvG,SAAS,CAAC,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC,IAAI;IAU7F,SAAS,CAAC,gBAAgB,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC,cAAc,CAAC,WAAW;IAOnJ,SAAS,CAAC,yBAAyB,CAAC,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI;IAoBhF;;OAEG;IACH,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM;IAIpE,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS;IAI3D,wBAAwB,IAAI,IAAI;CAGnC"}
@@ -31,12 +31,19 @@ let FileTreeDecoratorAdapter = class FileTreeDecoratorAdapter {
31
31
  this.onDidChangeDecorationsEmitter = new common_1.Emitter();
32
32
  this.decorationsByUri = new Map();
33
33
  this.parentDecorations = new Map();
34
+ /**
35
+ * Resources already queried from the service since the last decoration change event.
36
+ * Undecorated resources never enter {@link decorationsByUri}, so without this set
37
+ * every render pass would re-query (and re-parse the URI of) every undecorated node.
38
+ */
39
+ this.queriedUris = new Set();
34
40
  }
35
41
  get onDidChangeDecorations() {
36
42
  return this.onDidChangeDecorationsEmitter.event;
37
43
  }
38
44
  init() {
39
45
  this.decorationsService.onDidChangeDecorations(newDecorations => {
46
+ this.queriedUris.clear();
40
47
  this.updateDecorations(this.decorationsByUri.keys(), newDecorations.keys());
41
48
  this.fireDidChangeDecorations();
42
49
  });
@@ -51,6 +58,22 @@ let FileTreeDecoratorAdapter = class FileTreeDecoratorAdapter {
51
58
  const uri = this.getUriForNode(node);
52
59
  if (uri) {
53
60
  const stringified = uri.toString();
61
+ if (!this.decorationsByUri.has(stringified) && !this.queriedUris.has(stringified)) {
62
+ // Query the service once per change event for resources this decorator
63
+ // has not seen, so that decorations dropped from change events (e.g. by
64
+ // the plugin-ext event cap, see #17507) are fetched on demand. The
65
+ // service caches results, including "no decoration": known resources
66
+ // resolve synchronously and undecorated ones are not fetched again.
67
+ // Resolved fetches arrive as a single batched change event handled in
68
+ // updateDecorations.
69
+ this.queriedUris.add(stringified);
70
+ const nodeUri = new uri_1.default(stringified);
71
+ const fetched = this.decorationsService.getDecoration(nodeUri, false);
72
+ if (fetched.length) {
73
+ this.decorationsByUri.set(stringified, this.toTheiaDecoration(fetched, false));
74
+ this.propagateDecorationsByUri(nodeUri, fetched);
75
+ }
76
+ }
54
77
  const ownDecoration = this.decorationsByUri.get(stringified);
55
78
  const bubbledDecoration = this.parentDecorations.get(stringified);
56
79
  const combined = this.mergeDecorations(ownDecoration, bubbledDecoration);
@@ -82,6 +105,7 @@ let FileTreeDecoratorAdapter = class FileTreeDecoratorAdapter {
82
105
  const newDecorations = new Map();
83
106
  const handleUri = (rawUri) => {
84
107
  if (!newDecorations.has(rawUri)) {
108
+ this.queriedUris.add(rawUri);
85
109
  const uri = new uri_1.default(rawUri);
86
110
  const decorations = this.decorationsService.getDecoration(uri, false);
87
111
  if (decorations.length) {
@@ -1 +1 @@
1
- {"version":3,"file":"file-tree-decorator-adapter.js","sourceRoot":"","sources":["../../../src/browser/file-tree/file-tree-decorator-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"file-tree-decorator-adapter.js","sourceRoot":"","sources":["../../../src/browser/file-tree/file-tree-decorator-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=file-tree-decorator-adapter.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-tree-decorator-adapter.spec.d.ts","sourceRoot":"","sources":["../../../src/browser/file-tree/file-tree-decorator-adapter.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2026 Safi Seid-Ahmad, K2view and others.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ const jsdom_1 = require("@theia/core/lib/browser/test/jsdom");
19
+ let disableJSDOM = (0, jsdom_1.enableJSDOM)();
20
+ const color_registry_1 = require("@theia/core/lib/browser/color-registry");
21
+ const decorations_service_1 = require("@theia/core/lib/browser/decorations-service");
22
+ const common_1 = require("@theia/core/lib/common");
23
+ const uri_1 = require("@theia/core/lib/common/uri");
24
+ const inversify_1 = require("@theia/core/shared/inversify");
25
+ const chai_1 = require("chai");
26
+ const file_tree_decorator_adapter_1 = require("./file-tree-decorator-adapter");
27
+ disableJSDOM();
28
+ class TestDecorationsProvider {
29
+ constructor() {
30
+ this.onDidChangeEmitter = new common_1.Emitter();
31
+ this.decorations = new Map();
32
+ this.queried = [];
33
+ }
34
+ get onDidChange() {
35
+ return this.onDidChangeEmitter.event;
36
+ }
37
+ fireDidChange(uris) {
38
+ this.onDidChangeEmitter.fire(uris);
39
+ }
40
+ provideDecorations(uri, token) {
41
+ this.queried.push(uri.toString());
42
+ return Promise.resolve(this.decorations.get(uri.toString()));
43
+ }
44
+ }
45
+ function createTree(uris) {
46
+ const root = {
47
+ id: 'root',
48
+ name: 'root',
49
+ parent: undefined,
50
+ children: []
51
+ };
52
+ const children = uris.map(uri => ({
53
+ id: uri,
54
+ name: new uri_1.default(uri).path.base,
55
+ parent: root,
56
+ fileStat: { resource: new uri_1.default(uri) }
57
+ }));
58
+ children.forEach((child, index) => Object.assign(child, { nextSibling: children[index + 1] }));
59
+ Object.assign(root, { children });
60
+ return { root };
61
+ }
62
+ const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
63
+ describe('FileTreeDecoratorAdapter', () => {
64
+ before(() => {
65
+ disableJSDOM = (0, jsdom_1.enableJSDOM)();
66
+ });
67
+ after(() => {
68
+ disableJSDOM();
69
+ });
70
+ const fileUris = ['file:///project/f1.ts', 'file:///project/f2.ts', 'file:///project/f3.ts'];
71
+ let service;
72
+ let provider;
73
+ let adapter;
74
+ let tree;
75
+ beforeEach(() => {
76
+ service = new decorations_service_1.DecorationsServiceImpl();
77
+ provider = new TestDecorationsProvider();
78
+ service.registerDecorationsProvider(provider);
79
+ const container = new inversify_1.Container();
80
+ container.bind(decorations_service_1.DecorationsService).toConstantValue(service);
81
+ container.bind(color_registry_1.ColorRegistry).toSelf().inSingletonScope();
82
+ container.bind(file_tree_decorator_adapter_1.FileTreeDecoratorAdapter).toSelf().inSingletonScope();
83
+ adapter = container.get(file_tree_decorator_adapter_1.FileTreeDecoratorAdapter);
84
+ tree = createTree(fileUris);
85
+ });
86
+ afterEach(() => {
87
+ service.dispose();
88
+ });
89
+ it('fetches decorations on demand for resources never mentioned in a change event', async () => {
90
+ for (const uri of fileUris) {
91
+ provider.decorations.set(uri, { letter: 'U', bubble: true });
92
+ }
93
+ // simulates a render: nothing decorated yet, but fetches are triggered
94
+ (0, chai_1.expect)(await adapter.decorations(tree)).to.have.lengthOf(0);
95
+ await sleep(20);
96
+ const decorations = await adapter.decorations(tree);
97
+ for (const uri of fileUris) {
98
+ (0, chai_1.expect)(decorations.has(uri), uri).to.equal(true);
99
+ }
100
+ });
101
+ it('does not re-query the provider for undecorated resources on repeated renders', async () => {
102
+ await adapter.decorations(tree);
103
+ await sleep(20);
104
+ const queriesAfterFirstRender = provider.queried.length;
105
+ await adapter.decorations(tree);
106
+ await adapter.decorations(tree);
107
+ await sleep(20);
108
+ (0, chai_1.expect)(provider.queried.length).to.equal(queriesAfterFirstRender);
109
+ });
110
+ it('does not query the decorations service for undecorated resources on repeated renders', async () => {
111
+ const originalGetDecoration = service.getDecoration.bind(service);
112
+ let queries = 0;
113
+ service.getDecoration = (uri, includeChildren) => {
114
+ queries++;
115
+ return originalGetDecoration(uri, includeChildren);
116
+ };
117
+ await adapter.decorations(tree);
118
+ await sleep(20);
119
+ const queriesAfterFirstRender = queries;
120
+ await adapter.decorations(tree);
121
+ await adapter.decorations(tree);
122
+ (0, chai_1.expect)(queries).to.equal(queriesAfterFirstRender);
123
+ });
124
+ it('recovers decorations of resources cached as undecorated after a flush event', async () => {
125
+ // resources are queried before the provider has any data, e.g. before
126
+ // the initial git status is computed
127
+ await adapter.decorations(tree);
128
+ await sleep(20);
129
+ (0, chai_1.expect)(await adapter.decorations(tree)).to.have.lengthOf(0);
130
+ // data becomes available, but the change event exceeds the plugin-ext
131
+ // event cap and arrives as a flush (see #17507)
132
+ for (const uri of fileUris) {
133
+ provider.decorations.set(uri, { letter: 'M' });
134
+ }
135
+ let treeInvalidated = false;
136
+ adapter.onDidChangeDecorations(() => {
137
+ treeInvalidated = true;
138
+ });
139
+ provider.fireDidChange(undefined);
140
+ await sleep(20);
141
+ (0, chai_1.expect)(treeInvalidated, 'flush must invalidate the tree decorations').to.equal(true);
142
+ // the invalidation makes the tree render, which re-fetches on demand ...
143
+ await adapter.decorations(tree);
144
+ await sleep(20);
145
+ // ... and the next render shows every decoration
146
+ const decorations = await adapter.decorations(tree);
147
+ for (const uri of fileUris) {
148
+ (0, chai_1.expect)(decorations.get(uri)?.tailDecorations?.some(tail => 'data' in tail && tail.data === 'M'), uri).to.equal(true);
149
+ }
150
+ });
151
+ });
152
+ //# sourceMappingURL=file-tree-decorator-adapter.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-tree-decorator-adapter.spec.js","sourceRoot":"","sources":["../../../src/browser/file-tree/file-tree-decorator-adapter.spec.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@theia/filesystem",
3
- "version": "1.75.0",
3
+ "version": "1.76.0-next.4+21b9b5342",
4
4
  "description": "Theia - FileSystem Extension",
5
5
  "dependencies": {
6
- "@theia/core": "1.75.0",
6
+ "@theia/core": "1.76.0-next.4+21b9b5342",
7
7
  "@types/body-parser": "^1.19.6",
8
8
  "@types/multer": "^1.4.13",
9
9
  "@types/tar-fs": "^1.16.3",
@@ -82,5 +82,5 @@
82
82
  "nyc": {
83
83
  "extends": "../../configs/nyc.json"
84
84
  },
85
- "gitHead": "6d8e911f05f0fd9a13d76797e79b21ee3f038bc2"
85
+ "gitHead": "21b9b534224c55152fca0b67af7f8a8283dad2bd"
86
86
  }
@@ -0,0 +1,181 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2026 Safi Seid-Ahmad, K2view and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
18
+ let disableJSDOM = enableJSDOM();
19
+
20
+ import { ColorRegistry } from '@theia/core/lib/browser/color-registry';
21
+ import { Decoration, DecorationsProvider, DecorationsService, DecorationsServiceImpl } from '@theia/core/lib/browser/decorations-service';
22
+ import { CompositeTreeNode, Tree } from '@theia/core/lib/browser/tree';
23
+ import { CancellationToken, Emitter, Event } from '@theia/core/lib/common';
24
+ import URI from '@theia/core/lib/common/uri';
25
+ import { Container } from '@theia/core/shared/inversify';
26
+ import { expect } from 'chai';
27
+ import { FileTreeDecoratorAdapter } from './file-tree-decorator-adapter';
28
+
29
+ disableJSDOM();
30
+
31
+ class TestDecorationsProvider implements DecorationsProvider {
32
+
33
+ protected readonly onDidChangeEmitter = new Emitter<URI[] | undefined>();
34
+ readonly decorations = new Map<string, Decoration>();
35
+ readonly queried: string[] = [];
36
+
37
+ get onDidChange(): Event<URI[] | undefined> {
38
+ return this.onDidChangeEmitter.event;
39
+ }
40
+
41
+ fireDidChange(uris?: URI[]): void {
42
+ this.onDidChangeEmitter.fire(uris);
43
+ }
44
+
45
+ provideDecorations(uri: URI, token: CancellationToken): Promise<Decoration | undefined> {
46
+ this.queried.push(uri.toString());
47
+ return Promise.resolve(this.decorations.get(uri.toString()));
48
+ }
49
+ }
50
+
51
+ function createTree(uris: string[]): Tree {
52
+ const root = {
53
+ id: 'root',
54
+ name: 'root',
55
+ parent: undefined,
56
+ children: []
57
+ } as unknown as CompositeTreeNode;
58
+ const children = uris.map(uri => ({
59
+ id: uri,
60
+ name: new URI(uri).path.base,
61
+ parent: root,
62
+ fileStat: { resource: new URI(uri) }
63
+ }));
64
+ children.forEach((child, index) => Object.assign(child, { nextSibling: children[index + 1] }));
65
+ Object.assign(root, { children });
66
+ return { root } as unknown as Tree;
67
+ }
68
+
69
+ const sleep = (ms: number): Promise<void> => new Promise(resolve => setTimeout(resolve, ms));
70
+
71
+ describe('FileTreeDecoratorAdapter', () => {
72
+
73
+ before(() => {
74
+ disableJSDOM = enableJSDOM();
75
+ });
76
+
77
+ after(() => {
78
+ disableJSDOM();
79
+ });
80
+
81
+ const fileUris = ['file:///project/f1.ts', 'file:///project/f2.ts', 'file:///project/f3.ts'];
82
+
83
+ let service: DecorationsServiceImpl;
84
+ let provider: TestDecorationsProvider;
85
+ let adapter: FileTreeDecoratorAdapter;
86
+ let tree: Tree;
87
+
88
+ beforeEach(() => {
89
+ service = new DecorationsServiceImpl();
90
+ provider = new TestDecorationsProvider();
91
+ service.registerDecorationsProvider(provider);
92
+
93
+ const container = new Container();
94
+ container.bind(DecorationsService).toConstantValue(service);
95
+ container.bind(ColorRegistry).toSelf().inSingletonScope();
96
+ container.bind(FileTreeDecoratorAdapter).toSelf().inSingletonScope();
97
+ adapter = container.get(FileTreeDecoratorAdapter);
98
+
99
+ tree = createTree(fileUris);
100
+ });
101
+
102
+ afterEach(() => {
103
+ service.dispose();
104
+ });
105
+
106
+ it('fetches decorations on demand for resources never mentioned in a change event', async () => {
107
+ for (const uri of fileUris) {
108
+ provider.decorations.set(uri, { letter: 'U', bubble: true });
109
+ }
110
+
111
+ // simulates a render: nothing decorated yet, but fetches are triggered
112
+ expect(await adapter.decorations(tree)).to.have.lengthOf(0);
113
+ await sleep(20);
114
+
115
+ const decorations = await adapter.decorations(tree);
116
+ for (const uri of fileUris) {
117
+ expect(decorations.has(uri), uri).to.equal(true);
118
+ }
119
+ });
120
+
121
+ it('does not re-query the provider for undecorated resources on repeated renders', async () => {
122
+ await adapter.decorations(tree);
123
+ await sleep(20);
124
+ const queriesAfterFirstRender = provider.queried.length;
125
+
126
+ await adapter.decorations(tree);
127
+ await adapter.decorations(tree);
128
+ await sleep(20);
129
+
130
+ expect(provider.queried.length).to.equal(queriesAfterFirstRender);
131
+ });
132
+
133
+ it('does not query the decorations service for undecorated resources on repeated renders', async () => {
134
+ const originalGetDecoration = service.getDecoration.bind(service);
135
+ let queries = 0;
136
+ service.getDecoration = (uri, includeChildren) => {
137
+ queries++;
138
+ return originalGetDecoration(uri, includeChildren);
139
+ };
140
+ await adapter.decorations(tree);
141
+ await sleep(20);
142
+ const queriesAfterFirstRender = queries;
143
+
144
+ await adapter.decorations(tree);
145
+ await adapter.decorations(tree);
146
+
147
+ expect(queries).to.equal(queriesAfterFirstRender);
148
+ });
149
+
150
+ it('recovers decorations of resources cached as undecorated after a flush event', async () => {
151
+ // resources are queried before the provider has any data, e.g. before
152
+ // the initial git status is computed
153
+ await adapter.decorations(tree);
154
+ await sleep(20);
155
+ expect(await adapter.decorations(tree)).to.have.lengthOf(0);
156
+
157
+ // data becomes available, but the change event exceeds the plugin-ext
158
+ // event cap and arrives as a flush (see #17507)
159
+ for (const uri of fileUris) {
160
+ provider.decorations.set(uri, { letter: 'M' });
161
+ }
162
+ let treeInvalidated = false;
163
+ adapter.onDidChangeDecorations(() => {
164
+ treeInvalidated = true;
165
+ });
166
+ provider.fireDidChange(undefined);
167
+ await sleep(20);
168
+ expect(treeInvalidated, 'flush must invalidate the tree decorations').to.equal(true);
169
+
170
+ // the invalidation makes the tree render, which re-fetches on demand ...
171
+ await adapter.decorations(tree);
172
+ await sleep(20);
173
+
174
+ // ... and the next render shows every decoration
175
+ const decorations = await adapter.decorations(tree);
176
+ for (const uri of fileUris) {
177
+ expect(decorations.get(uri)?.tailDecorations?.some(tail => 'data' in tail && tail.data === 'M'), uri).to.equal(true);
178
+ }
179
+ });
180
+
181
+ });
@@ -33,6 +33,12 @@ export class FileTreeDecoratorAdapter implements TreeDecorator {
33
33
  protected readonly onDidChangeDecorationsEmitter = new Emitter<(tree: Tree) => Map<string, TreeDecoration.Data>>();
34
34
  protected decorationsByUri = new Map<string, TreeDecoration.Data>();
35
35
  protected parentDecorations = new Map<string, TreeDecoration.Data>();
36
+ /**
37
+ * Resources already queried from the service since the last decoration change event.
38
+ * Undecorated resources never enter {@link decorationsByUri}, so without this set
39
+ * every render pass would re-query (and re-parse the URI of) every undecorated node.
40
+ */
41
+ protected readonly queriedUris = new Set<string>();
36
42
 
37
43
  get onDidChangeDecorations(): Event<(tree: Tree) => Map<string, TreeDecoration.Data>> {
38
44
  return this.onDidChangeDecorationsEmitter.event;
@@ -41,6 +47,7 @@ export class FileTreeDecoratorAdapter implements TreeDecorator {
41
47
  @postConstruct()
42
48
  protected init(): void {
43
49
  this.decorationsService.onDidChangeDecorations(newDecorations => {
50
+ this.queriedUris.clear();
44
51
  this.updateDecorations(this.decorationsByUri.keys(), newDecorations.keys());
45
52
  this.fireDidChangeDecorations();
46
53
  });
@@ -57,6 +64,22 @@ export class FileTreeDecoratorAdapter implements TreeDecorator {
57
64
  const uri = this.getUriForNode(node);
58
65
  if (uri) {
59
66
  const stringified = uri.toString();
67
+ if (!this.decorationsByUri.has(stringified) && !this.queriedUris.has(stringified)) {
68
+ // Query the service once per change event for resources this decorator
69
+ // has not seen, so that decorations dropped from change events (e.g. by
70
+ // the plugin-ext event cap, see #17507) are fetched on demand. The
71
+ // service caches results, including "no decoration": known resources
72
+ // resolve synchronously and undecorated ones are not fetched again.
73
+ // Resolved fetches arrive as a single batched change event handled in
74
+ // updateDecorations.
75
+ this.queriedUris.add(stringified);
76
+ const nodeUri = new URI(stringified);
77
+ const fetched = this.decorationsService.getDecoration(nodeUri, false);
78
+ if (fetched.length) {
79
+ this.decorationsByUri.set(stringified, this.toTheiaDecoration(fetched, false));
80
+ this.propagateDecorationsByUri(nodeUri, fetched);
81
+ }
82
+ }
60
83
  const ownDecoration = this.decorationsByUri.get(stringified);
61
84
  const bubbledDecoration = this.parentDecorations.get(stringified);
62
85
  const combined = this.mergeDecorations(ownDecoration, bubbledDecoration);
@@ -88,6 +111,7 @@ export class FileTreeDecoratorAdapter implements TreeDecorator {
88
111
  const newDecorations = new Map<string, TreeDecoration.Data>();
89
112
  const handleUri = (rawUri: string) => {
90
113
  if (!newDecorations.has(rawUri)) {
114
+ this.queriedUris.add(rawUri);
91
115
  const uri = new URI(rawUri);
92
116
  const decorations = this.decorationsService.getDecoration(uri, false);
93
117
  if (decorations.length) {