UNPKG

2.43 kBPlain TextView Raw
1/**
2 * Represents source text that can be missing.
3 */
4export type NullableSourceText = string | null;
5
6export interface SourceStore {
7 /**
8 * Registers a `url`, optionally with its source text.
9 *
10 * @param url URL of the source text.
11 * @param sourceText Source text corresponding to the provided URL, or `null`.
12 * @returns Boolean indicating if the source store was updated.
13 */
14 set(url: string, sourceText: NullableSourceText): boolean;
15
16 // TODO: Find out why TSLint complains about whitespace
17 // tslint:disable:whitespace
18 /**
19 * Returns the current source text for the provided `url`.
20 *
21 * - If the `url` is unknown, returns `undefined`.
22 * - If the `url` is known but does not have any associated source text,
23 * returns `null`.
24 * - If the `url` is known and the store has its source text, returns the
25 * source text (a `string`).
26 *
27 * @param url URL of the source text.
28 */
29 get(url: string): NullableSourceText | undefined;
30
31 // tslint:enable
32
33 [Symbol.iterator](): Iterator<[string, NullableSourceText]>;
34}
35
36/**
37 * This is basically a `Map` with a setter checking for changes instead
38 * of returning `this`.
39 */
40export class MemorySourceStore implements SourceStore {
41 private readonly urlToSourceText: Map<string, NullableSourceText>;
42
43 constructor(initialData?: Iterable<[string, NullableSourceText]>) {
44 this.urlToSourceText = initialData === undefined ? new Map() : new Map(initialData);
45 }
46
47 /**
48 * Registers a `url`, optionally with its source text.
49 *
50 * Throws an error if the URL is already set and the value differs.
51 *
52 * @param url URL to set.
53 * @param sourceText Source text corresponding to the provided URL.
54 * @returns Boolean indicating if the source store was updated.
55 */
56 set(url: string, sourceText: NullableSourceText): boolean {
57 const old: NullableSourceText | undefined = this.urlToSourceText.get(url);
58 if (old === undefined || old === null) {
59 this.urlToSourceText.set(url, sourceText);
60 } else if (sourceText !== null && sourceText !== old) {
61 throw new Error(`Incompatible sources for URL: ${url}\nold: ${old}\nnew: ${sourceText}`);
62 }
63 return sourceText !== old;
64 }
65
66 get(url: string): NullableSourceText | undefined {
67 return this.urlToSourceText.get(url);
68 }
69
70 [Symbol.iterator](): Iterator<[string, NullableSourceText]> {
71 return this.urlToSourceText[Symbol.iterator]();
72 }
73}