UNPKG

12.3 kBJavaScriptView Raw
1"use strict";
2// *****************************************************************************
3// Copyright (C) 2017 TypeFox 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// *****************************************************************************
17Object.defineProperty(exports, "__esModule", { value: true });
18exports.createUntitledURI = exports.UntitledResource = exports.UntitledResourceResolver = exports.UNTITLED_SCHEME = exports.InMemoryTextResourceResolver = exports.InMemoryTextResource = exports.MEMORY_TEXT = exports.InMemoryResources = exports.ReferenceMutableResource = exports.MutableResource = exports.DefaultResourceProvider = exports.ResourceProvider = exports.ResourceResolver = exports.ResourceError = exports.Resource = void 0;
19const tslib_1 = require("tslib");
20const inversify_1 = require("inversify");
21const uri_1 = require("../common/uri");
22const contribution_provider_1 = require("./contribution-provider");
23const event_1 = require("./event");
24const application_error_1 = require("./application-error");
25const stream_1 = require("./stream");
26const reference_1 = require("./reference");
27var Resource;
28(function (Resource) {
29 async function save(resource, context, token) {
30 if (!resource.saveContents) {
31 return;
32 }
33 if (await trySaveContentChanges(resource, context)) {
34 return;
35 }
36 if (token && token.isCancellationRequested) {
37 return;
38 }
39 if (typeof context.content !== 'string' && resource.saveStream) {
40 await resource.saveStream(context.content, context.options);
41 }
42 else {
43 const content = typeof context.content === 'string' ? context.content : stream_1.Readable.toString(context.content);
44 await resource.saveContents(content, context.options);
45 }
46 }
47 Resource.save = save;
48 async function trySaveContentChanges(resource, context) {
49 if (!context.changes || !resource.saveContentChanges || shouldSaveContent(resource, context)) {
50 return false;
51 }
52 try {
53 await resource.saveContentChanges(context.changes, context.options);
54 return true;
55 }
56 catch (e) {
57 if (!ResourceError.NotFound.is(e) && !ResourceError.OutOfSync.is(e)) {
58 console.error(`Failed to apply incremental changes to '${resource.uri.toString()}':`, e);
59 }
60 return false;
61 }
62 }
63 Resource.trySaveContentChanges = trySaveContentChanges;
64 function shouldSaveContent(resource, { contentLength, changes }) {
65 if (!changes || (resource.saveStream && contentLength > 32 * 1024 * 1024)) {
66 return true;
67 }
68 let contentChangesLength = 0;
69 for (const change of changes) {
70 contentChangesLength += JSON.stringify(change).length;
71 if (contentChangesLength > contentLength) {
72 return true;
73 }
74 }
75 return contentChangesLength > contentLength;
76 }
77 Resource.shouldSaveContent = shouldSaveContent;
78})(Resource = exports.Resource || (exports.Resource = {}));
79var ResourceError;
80(function (ResourceError) {
81 ResourceError.NotFound = application_error_1.ApplicationError.declare(-40000, (raw) => raw);
82 ResourceError.OutOfSync = application_error_1.ApplicationError.declare(-40001, (raw) => raw);
83})(ResourceError = exports.ResourceError || (exports.ResourceError = {}));
84exports.ResourceResolver = Symbol('ResourceResolver');
85exports.ResourceProvider = Symbol('ResourceProvider');
86let DefaultResourceProvider = class DefaultResourceProvider {
87 constructor(resolversProvider) {
88 this.resolversProvider = resolversProvider;
89 }
90 /**
91 * Reject if a resource cannot be provided.
92 */
93 async get(uri) {
94 const resolvers = this.resolversProvider.getContributions();
95 for (const resolver of resolvers) {
96 try {
97 return await resolver.resolve(uri);
98 }
99 catch (err) {
100 // no-op
101 }
102 }
103 return Promise.reject(new Error(`A resource provider for '${uri.toString()}' is not registered.`));
104 }
105};
106DefaultResourceProvider = (0, tslib_1.__decorate)([
107 (0, inversify_1.injectable)(),
108 (0, tslib_1.__param)(0, (0, inversify_1.inject)(contribution_provider_1.ContributionProvider)),
109 (0, tslib_1.__param)(0, (0, inversify_1.named)(exports.ResourceResolver)),
110 (0, tslib_1.__metadata)("design:paramtypes", [Object])
111], DefaultResourceProvider);
112exports.DefaultResourceProvider = DefaultResourceProvider;
113class MutableResource {
114 constructor(uri) {
115 this.uri = uri;
116 this.contents = '';
117 this.onDidChangeContentsEmitter = new event_1.Emitter();
118 this.onDidChangeContents = this.onDidChangeContentsEmitter.event;
119 }
120 dispose() { }
121 async readContents() {
122 return this.contents;
123 }
124 async saveContents(contents) {
125 this.contents = contents;
126 this.fireDidChangeContents();
127 }
128 fireDidChangeContents() {
129 this.onDidChangeContentsEmitter.fire(undefined);
130 }
131}
132exports.MutableResource = MutableResource;
133class ReferenceMutableResource {
134 constructor(reference) {
135 this.reference = reference;
136 }
137 get uri() {
138 return this.reference.object.uri;
139 }
140 get onDidChangeContents() {
141 return this.reference.object.onDidChangeContents;
142 }
143 dispose() {
144 this.reference.dispose();
145 }
146 readContents() {
147 return this.reference.object.readContents();
148 }
149 saveContents(contents) {
150 return this.reference.object.saveContents(contents);
151 }
152}
153exports.ReferenceMutableResource = ReferenceMutableResource;
154let InMemoryResources = class InMemoryResources {
155 constructor() {
156 this.resources = new reference_1.SyncReferenceCollection(uri => new MutableResource(new uri_1.default(uri)));
157 }
158 add(uri, contents) {
159 const resourceUri = uri.toString();
160 if (this.resources.has(resourceUri)) {
161 throw new Error(`Cannot add already existing in-memory resource '${resourceUri}'`);
162 }
163 const resource = this.acquire(resourceUri);
164 resource.saveContents(contents);
165 return resource;
166 }
167 update(uri, contents) {
168 const resourceUri = uri.toString();
169 const resource = this.resources.get(resourceUri);
170 if (!resource) {
171 throw new Error(`Cannot update non-existed in-memory resource '${resourceUri}'`);
172 }
173 resource.saveContents(contents);
174 return resource;
175 }
176 resolve(uri) {
177 const uriString = uri.toString();
178 if (!this.resources.has(uriString)) {
179 throw new Error(`In memory '${uriString}' resource does not exist.`);
180 }
181 return this.acquire(uriString);
182 }
183 acquire(uri) {
184 const reference = this.resources.acquire(uri);
185 return new ReferenceMutableResource(reference);
186 }
187};
188InMemoryResources = (0, tslib_1.__decorate)([
189 (0, inversify_1.injectable)()
190], InMemoryResources);
191exports.InMemoryResources = InMemoryResources;
192exports.MEMORY_TEXT = 'mem-txt';
193/**
194 * Resource implementation for 'mem-txt' URI scheme where content is saved in URI query.
195 */
196class InMemoryTextResource {
197 constructor(uri) {
198 this.uri = uri;
199 }
200 async readContents(options) {
201 return this.uri.query;
202 }
203 dispose() { }
204}
205exports.InMemoryTextResource = InMemoryTextResource;
206/**
207 * ResourceResolver implementation for 'mem-txt' URI scheme.
208 */
209let InMemoryTextResourceResolver = class InMemoryTextResourceResolver {
210 resolve(uri) {
211 if (uri.scheme !== exports.MEMORY_TEXT) {
212 throw new Error(`Expected a URI with ${exports.MEMORY_TEXT} scheme. Was: ${uri}.`);
213 }
214 return new InMemoryTextResource(uri);
215 }
216};
217InMemoryTextResourceResolver = (0, tslib_1.__decorate)([
218 (0, inversify_1.injectable)()
219], InMemoryTextResourceResolver);
220exports.InMemoryTextResourceResolver = InMemoryTextResourceResolver;
221exports.UNTITLED_SCHEME = 'untitled';
222let untitledResourceSequenceIndex = 0;
223let UntitledResourceResolver = class UntitledResourceResolver {
224 constructor() {
225 this.resources = new Map();
226 }
227 has(uri) {
228 if (uri.scheme !== exports.UNTITLED_SCHEME) {
229 throw new Error('The given uri is not untitled file uri: ' + uri);
230 }
231 else {
232 return this.resources.has(uri.toString());
233 }
234 }
235 async resolve(uri) {
236 if (uri.scheme !== exports.UNTITLED_SCHEME) {
237 throw new Error('The given uri is not untitled file uri: ' + uri);
238 }
239 else {
240 const untitledResource = this.resources.get(uri.toString());
241 if (!untitledResource) {
242 return this.createUntitledResource('', '', uri);
243 }
244 else {
245 return untitledResource;
246 }
247 }
248 }
249 async createUntitledResource(content, extension, uri) {
250 if (!uri) {
251 uri = this.createUntitledURI(extension);
252 }
253 return new UntitledResource(this.resources, uri, content);
254 }
255 createUntitledURI(extension, parent) {
256 let counter = 1; // vscode starts at 1
257 let untitledUri;
258 do {
259 const name = `Untitled-${counter}${extension !== null && extension !== void 0 ? extension : ''}`;
260 if (parent) {
261 untitledUri = parent.resolve(name).withScheme(exports.UNTITLED_SCHEME);
262 }
263 untitledUri = new uri_1.default().resolve(name).withScheme(exports.UNTITLED_SCHEME);
264 counter++;
265 } while (this.has(untitledUri));
266 return untitledUri;
267 }
268};
269UntitledResourceResolver = (0, tslib_1.__decorate)([
270 (0, inversify_1.injectable)()
271], UntitledResourceResolver);
272exports.UntitledResourceResolver = UntitledResourceResolver;
273class UntitledResource {
274 constructor(resources, uri, content) {
275 this.resources = resources;
276 this.uri = uri;
277 this.content = content;
278 this.onDidChangeContentsEmitter = new event_1.Emitter();
279 this.resources.set(this.uri.toString(), this);
280 }
281 get onDidChangeContents() {
282 return this.onDidChangeContentsEmitter.event;
283 }
284 dispose() {
285 this.resources.delete(this.uri.toString());
286 this.onDidChangeContentsEmitter.dispose();
287 }
288 async readContents(options) {
289 if (this.content) {
290 return this.content;
291 }
292 else {
293 return '';
294 }
295 }
296 async saveContents(content, options) {
297 // This function must exist to ensure readOnly is false for the Monaco editor.
298 // However it should not be called because saving 'untitled' is always processed as 'Save As'.
299 throw Error('Untitled resources cannot be saved.');
300 }
301 fireDidChangeContents() {
302 this.onDidChangeContentsEmitter.fire(undefined);
303 }
304 get version() {
305 return undefined;
306 }
307 get encoding() {
308 return undefined;
309 }
310}
311exports.UntitledResource = UntitledResource;
312/**
313 * @deprecated Since 1.27.0. Please use `UntitledResourceResolver.createUntitledURI` instead.
314 */
315function createUntitledURI(extension, parent) {
316 const name = `Untitled-${untitledResourceSequenceIndex++}${extension !== null && extension !== void 0 ? extension : ''}`;
317 if (parent) {
318 return parent.resolve(name).withScheme(exports.UNTITLED_SCHEME);
319 }
320 return new uri_1.default().resolve(name).withScheme(exports.UNTITLED_SCHEME);
321}
322exports.createUntitledURI = createUntitledURI;
323//# sourceMappingURL=resource.js.map
\No newline at end of file