@spyglassmc/core 0.4.34 → 0.4.35

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.
@@ -35,24 +35,6 @@ export class BrowserEventEmitter {
35
35
  return this;
36
36
  }
37
37
  }
38
- class BrowserExternalDownloader {
39
- async get(uri, options = {}) {
40
- const headers = new Headers();
41
- for (const [name, value] of Object.entries(options?.headers ?? {})) {
42
- const values = typeof value === 'string' ? [value] : value;
43
- for (const v of values) {
44
- headers.append(name, v);
45
- }
46
- }
47
- const res = await fetch(uri, { headers, redirect: 'follow' });
48
- if (!res.ok) {
49
- throw new Error(`Status code ${res.status}: ${res.ok}`);
50
- }
51
- else {
52
- return new Uint8Array(await res.arrayBuffer());
53
- }
54
- }
55
- }
56
38
  class BrowserFsWatcher {
57
39
  on(event, listener) {
58
40
  if (event === 'ready') {
@@ -157,7 +139,6 @@ export const BrowserExternals = {
157
139
  return uint8ArrayToHex(new Uint8Array(hash));
158
140
  },
159
141
  },
160
- downloader: new BrowserExternalDownloader(),
161
142
  error: {
162
143
  createKind(kind, message) {
163
144
  return new Error(`${kind}: ${message}`);
@@ -168,6 +149,10 @@ export const BrowserExternals = {
168
149
  },
169
150
  event: { EventEmitter: BrowserEventEmitter },
170
151
  fs: new BrowserFileSystem(),
152
+ web: {
153
+ fetch,
154
+ getCache: () => window.caches.open('spyglassmc'),
155
+ },
171
156
  };
172
157
  function uint8ArrayToHex(array) {
173
158
  let ans = '';
@@ -1,3 +1,116 @@
1
- import type { Externals } from './index.js';
2
- export declare const NodeJsExternals: Externals;
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ import chokidar from 'chokidar';
5
+ import decompress from 'decompress';
6
+ import { Buffer } from 'node:buffer';
7
+ import { EventEmitter } from 'node:events';
8
+ import fs from 'node:fs';
9
+ import type { RootUriString } from '../../index.js';
10
+ import type { FsLocation, FsWatcher } from './index.js';
11
+ export declare function getNodeJsExternals({ cacheRoot }?: {
12
+ cacheRoot?: RootUriString;
13
+ }): Readonly<{
14
+ archive: {
15
+ decompressBall(buffer: Uint8Array, options: {
16
+ stripLevel?: number | undefined;
17
+ } | undefined): Promise<decompress.File[]>;
18
+ gunzip(buffer: Uint8Array): Promise<Buffer>;
19
+ gzip(buffer: Uint8Array): Promise<Buffer>;
20
+ };
21
+ crypto: {
22
+ getSha1(data: string | Uint8Array): Promise<string>;
23
+ };
24
+ error: {
25
+ createKind(kind: import("./index.js").ExternalErrorKind, message: string): Error;
26
+ isKind(e: unknown, kind: import("./index.js").ExternalErrorKind): boolean;
27
+ };
28
+ event: {
29
+ EventEmitter: typeof EventEmitter;
30
+ };
31
+ fs: {
32
+ chmod(location: FsLocation, mode: number): Promise<void>;
33
+ mkdir(location: FsLocation, options: {
34
+ mode?: number | undefined;
35
+ recursive?: boolean | undefined;
36
+ } | undefined): Promise<undefined>;
37
+ readdir(location: FsLocation): Promise<fs.Dirent[]>;
38
+ readFile(location: FsLocation): Promise<Buffer>;
39
+ showFile(location: FsLocation): Promise<void>;
40
+ stat(location: FsLocation): Promise<fs.Stats>;
41
+ unlink(location: FsLocation): Promise<void>;
42
+ watch(locations: FsLocation[], { usePolling }?: {
43
+ usePolling?: boolean | undefined;
44
+ }): ChokidarWatcherWrapper;
45
+ writeFile(location: FsLocation, data: string | Uint8Array, options: {
46
+ mode: number;
47
+ } | undefined): Promise<void>;
48
+ };
49
+ web: {
50
+ fetch: typeof fetch;
51
+ getCache: () => Promise<HttpCache>;
52
+ };
53
+ }>;
54
+ export declare const NodeJsExternals: Readonly<{
55
+ archive: {
56
+ decompressBall(buffer: Uint8Array, options: {
57
+ stripLevel?: number | undefined;
58
+ } | undefined): Promise<decompress.File[]>;
59
+ gunzip(buffer: Uint8Array): Promise<Buffer>;
60
+ gzip(buffer: Uint8Array): Promise<Buffer>;
61
+ };
62
+ crypto: {
63
+ getSha1(data: string | Uint8Array): Promise<string>;
64
+ };
65
+ error: {
66
+ createKind(kind: import("./index.js").ExternalErrorKind, message: string): Error;
67
+ isKind(e: unknown, kind: import("./index.js").ExternalErrorKind): boolean;
68
+ };
69
+ event: {
70
+ EventEmitter: typeof EventEmitter;
71
+ };
72
+ fs: {
73
+ chmod(location: FsLocation, mode: number): Promise<void>;
74
+ mkdir(location: FsLocation, options: {
75
+ mode?: number | undefined;
76
+ recursive?: boolean | undefined;
77
+ } | undefined): Promise<undefined>;
78
+ readdir(location: FsLocation): Promise<fs.Dirent[]>;
79
+ readFile(location: FsLocation): Promise<Buffer>;
80
+ showFile(location: FsLocation): Promise<void>;
81
+ stat(location: FsLocation): Promise<fs.Stats>;
82
+ unlink(location: FsLocation): Promise<void>;
83
+ watch(locations: FsLocation[], { usePolling }?: {
84
+ usePolling?: boolean | undefined;
85
+ }): ChokidarWatcherWrapper;
86
+ writeFile(location: FsLocation, data: string | Uint8Array, options: {
87
+ mode: number;
88
+ } | undefined): Promise<void>;
89
+ };
90
+ web: {
91
+ fetch: typeof fetch;
92
+ getCache: () => Promise<HttpCache>;
93
+ };
94
+ }>;
95
+ declare class ChokidarWatcherWrapper extends EventEmitter implements FsWatcher {
96
+ #private;
97
+ constructor(watcher: chokidar.FSWatcher);
98
+ close(): Promise<void>;
99
+ }
100
+ /**
101
+ * A non-spec-compliant, non-complete implementation of the Cache Web API for use in Spyglass.
102
+ * This class stores the cached response on the file system under the cache root.
103
+ */
104
+ declare class HttpCache implements Cache {
105
+ #private;
106
+ constructor(cacheRoot: RootUriString | undefined);
107
+ match(request: RequestInfo | URL, _options?: CacheQueryOptions | undefined): Promise<Response | undefined>;
108
+ put(request: RequestInfo | URL, response: Response): Promise<void>;
109
+ add(): Promise<void>;
110
+ addAll(): Promise<void>;
111
+ delete(): Promise<boolean>;
112
+ keys(): Promise<readonly Request[]>;
113
+ matchAll(): Promise<readonly Response[]>;
114
+ }
115
+ export {};
3
116
  //# sourceMappingURL=NodeJsExternals.d.ts.map
@@ -1,119 +1,111 @@
1
1
  // https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/60592
2
2
  import chokidar from 'chokidar';
3
3
  import decompress from 'decompress';
4
- import followRedirects from 'follow-redirects';
5
4
  import { Buffer } from 'node:buffer';
6
5
  import cp from 'node:child_process';
7
6
  import crypto from 'node:crypto';
8
7
  import { EventEmitter } from 'node:events';
9
- import { promises as fsp } from 'node:fs';
8
+ import fs, { promises as fsp } from 'node:fs';
9
+ import os from 'node:os';
10
10
  import process from 'node:process';
11
+ import stream from 'node:stream';
11
12
  import url from 'node:url';
12
13
  import { promisify } from 'node:util';
13
14
  import zlib from 'node:zlib';
14
- import { promisifyAsyncIterable, Uri } from '../util.js';
15
- const { http, https } = followRedirects;
15
+ import { Uri } from '../util.js';
16
16
  const gunzip = promisify(zlib.gunzip);
17
17
  const gzip = promisify(zlib.gzip);
18
- class NodeJsExternalDownloader {
19
- get(uri, options = {}) {
20
- const protocol = new Uri(uri).protocol;
21
- return new Promise((resolve, reject) => {
22
- const backend = protocol === 'http:' ? http : https;
23
- backend.get(uri, options, (res) => {
24
- if (res.statusCode !== 200) {
25
- reject(new Error(`Status code ${res.statusCode}: ${res.statusMessage}`));
18
+ export function getNodeJsExternals({ cacheRoot } = {}) {
19
+ return Object.freeze({
20
+ archive: {
21
+ decompressBall(buffer, options) {
22
+ if (!(buffer instanceof Buffer)) {
23
+ buffer = Buffer.from(buffer);
26
24
  }
27
- else {
28
- resolve(promisifyAsyncIterable(res, (chunks) => Buffer.concat(chunks)));
29
- }
30
- }).on('error', (e) => {
31
- reject(e);
32
- });
33
- });
34
- }
35
- }
36
- export const NodeJsExternals = {
37
- archive: {
38
- decompressBall(buffer, options) {
39
- if (buffer instanceof Buffer) {
40
25
  return decompress(buffer, { strip: options?.stripLevel });
41
- }
42
- throw new TypeError(`The 'buffer' argument for 'decompressBall' on Node.js must be an instance of 'Buffer'. Got '${buffer}' instead.`);
43
- },
44
- gunzip(buffer) {
45
- return gunzip(buffer);
46
- },
47
- gzip(buffer) {
48
- return gzip(buffer);
49
- },
50
- },
51
- crypto: {
52
- async getSha1(data) {
53
- const hash = crypto.createHash('sha1');
54
- hash.update(data);
55
- return hash.digest('hex');
56
- },
57
- },
58
- downloader: new NodeJsExternalDownloader(),
59
- error: {
60
- createKind(kind, message) {
61
- const error = new Error(message);
62
- error.code = kind;
63
- return error;
64
- },
65
- isKind(e, kind) {
66
- return e instanceof Error && e.code === kind;
67
- },
68
- },
69
- event: { EventEmitter },
70
- fs: {
71
- chmod(location, mode) {
72
- return fsp.chmod(toFsPathLike(location), mode);
73
- },
74
- async mkdir(location, options) {
75
- return void (await fsp.mkdir(toFsPathLike(location), options));
76
- },
77
- readdir(location) {
78
- return fsp.readdir(toFsPathLike(location), { encoding: 'utf-8', withFileTypes: true });
79
- },
80
- readFile(location) {
81
- return fsp.readFile(toFsPathLike(location));
82
- },
83
- async showFile(location) {
84
- const execFile = promisify(cp.execFile);
85
- let command;
86
- switch (process.platform) {
87
- case 'darwin':
88
- command = 'open';
89
- break;
90
- case 'win32':
91
- command = 'explorer';
92
- break;
93
- default:
94
- command = 'xdg-open';
95
- break;
96
- }
97
- return void (await execFile(command, [toPath(location)]));
26
+ },
27
+ gunzip(buffer) {
28
+ return gunzip(buffer);
29
+ },
30
+ gzip(buffer) {
31
+ return gzip(buffer);
32
+ },
98
33
  },
99
- stat(location) {
100
- return fsp.stat(toFsPathLike(location));
34
+ crypto: {
35
+ async getSha1(data) {
36
+ const hash = crypto.createHash('sha1');
37
+ hash.update(data);
38
+ return hash.digest('hex');
39
+ },
101
40
  },
102
- unlink(location) {
103
- return fsp.unlink(toFsPathLike(location));
41
+ error: {
42
+ createKind(kind, message) {
43
+ const error = new Error(message);
44
+ error.code = kind;
45
+ return error;
46
+ },
47
+ isKind(e, kind) {
48
+ return e instanceof Error && e.code === kind;
49
+ },
104
50
  },
105
- watch(locations, { usePolling = false } = {}) {
106
- return new ChokidarWatcherWrapper(chokidar.watch(locations.map(toPath), {
107
- usePolling,
108
- disableGlobbing: true,
109
- }));
51
+ event: { EventEmitter },
52
+ fs: {
53
+ chmod(location, mode) {
54
+ return fsp.chmod(toFsPathLike(location), mode);
55
+ },
56
+ async mkdir(location, options) {
57
+ return void (await fsp.mkdir(toFsPathLike(location), options));
58
+ },
59
+ readdir(location) {
60
+ return fsp.readdir(toFsPathLike(location), {
61
+ encoding: 'utf-8',
62
+ withFileTypes: true,
63
+ });
64
+ },
65
+ readFile(location) {
66
+ return fsp.readFile(toFsPathLike(location));
67
+ },
68
+ async showFile(location) {
69
+ const execFile = promisify(cp.execFile);
70
+ let command;
71
+ switch (process.platform) {
72
+ case 'darwin':
73
+ command = 'open';
74
+ break;
75
+ case 'win32':
76
+ command = 'explorer';
77
+ break;
78
+ default:
79
+ command = 'xdg-open';
80
+ break;
81
+ }
82
+ return void (await execFile(command, [toPath(location)]));
83
+ },
84
+ stat(location) {
85
+ return fsp.stat(toFsPathLike(location));
86
+ },
87
+ unlink(location) {
88
+ return fsp.unlink(toFsPathLike(location));
89
+ },
90
+ watch(locations, { usePolling = false } = {}) {
91
+ return new ChokidarWatcherWrapper(chokidar.watch(locations.map(toPath), {
92
+ usePolling,
93
+ disableGlobbing: true,
94
+ }));
95
+ },
96
+ writeFile(location, data, options) {
97
+ return fsp.writeFile(toFsPathLike(location), data, options);
98
+ },
110
99
  },
111
- writeFile(location, data, options) {
112
- return fsp.writeFile(toFsPathLike(location), data, options);
100
+ web: {
101
+ fetch,
102
+ getCache: async () => {
103
+ return new HttpCache(cacheRoot);
104
+ },
113
105
  },
114
- },
115
- };
116
- Object.freeze(NodeJsExternals);
106
+ });
107
+ }
108
+ export const NodeJsExternals = getNodeJsExternals();
117
109
  /**
118
110
  * @returns A {@link fs.PathLike}.
119
111
  */
@@ -151,4 +143,70 @@ class ChokidarWatcherWrapper extends EventEmitter {
151
143
  return this.#watcher.close();
152
144
  }
153
145
  }
146
+ /**
147
+ * A non-spec-compliant, non-complete implementation of the Cache Web API for use in Spyglass.
148
+ * This class stores the cached response on the file system under the cache root.
149
+ */
150
+ class HttpCache {
151
+ #cacheRoot;
152
+ constructor(cacheRoot) {
153
+ if (cacheRoot) {
154
+ this.#cacheRoot = `${cacheRoot}http/`;
155
+ }
156
+ }
157
+ async match(request, _options) {
158
+ if (!this.#cacheRoot) {
159
+ return undefined;
160
+ }
161
+ const fileName = this.#getFileName(request);
162
+ try {
163
+ const etag = (await fsp.readFile(new URL(`${fileName}.etag`, this.#cacheRoot), 'utf8'))
164
+ .trim();
165
+ const bodyStream = fs.createReadStream(new URL(`${fileName}.bin`, this.#cacheRoot));
166
+ return new Response(stream.Readable.toWeb(bodyStream),
167
+ // \___/
168
+ // stream Readable -> stream/web ReadableStream
169
+ // \_______________/
170
+ // stream/web ReadableStream -> DOM ReadableStream
171
+ { headers: { etag } });
172
+ }
173
+ catch (e) {
174
+ if (e?.code === 'ENOENT') {
175
+ return undefined;
176
+ }
177
+ throw e;
178
+ }
179
+ }
180
+ async put(request, response) {
181
+ const etag = response.headers.get('etag');
182
+ if (!(this.#cacheRoot && response.body && etag)) {
183
+ return;
184
+ }
185
+ const fileName = this.#getFileName(request);
186
+ await fsp.mkdir(new URL(this.#cacheRoot), { recursive: true });
187
+ await Promise.all([
188
+ fsp.writeFile(new URL(`${fileName}.bin`, this.#cacheRoot), stream.Readable.fromWeb(response.body)),
189
+ fsp.writeFile(new URL(`${fileName}.etag`, this.#cacheRoot), `${etag}${os.EOL}`),
190
+ ]);
191
+ }
192
+ #getFileName(request) {
193
+ const uriString = request instanceof Request ? request.url : request.toString();
194
+ return Buffer.from(uriString, 'utf8').toString('base64url');
195
+ }
196
+ async add() {
197
+ throw new Error('Method not implemented.');
198
+ }
199
+ async addAll() {
200
+ throw new Error('Method not implemented.');
201
+ }
202
+ async delete() {
203
+ throw new Error('Method not implemented.');
204
+ }
205
+ async keys() {
206
+ throw new Error('Method not implemented.');
207
+ }
208
+ async matchAll() {
209
+ throw new Error('Method not implemented.');
210
+ }
211
+ }
154
212
  //# sourceMappingURL=NodeJsExternals.js.map
@@ -1,6 +1,4 @@
1
1
  import type { Uri } from '../util.js';
2
- import type { ExternalDownloader } from './downloader.js';
3
- export * from './downloader.js';
4
2
  export interface Externals {
5
3
  archive: {
6
4
  decompressBall: (buffer: Uint8Array, options?: {
@@ -15,7 +13,6 @@ export interface Externals {
15
13
  */
16
14
  getSha1: (data: string | Uint8Array) => Promise<string>;
17
15
  };
18
- downloader: ExternalDownloader;
19
16
  error: {
20
17
  /**
21
18
  * @returns an error of the specified kind
@@ -30,6 +27,10 @@ export interface Externals {
30
27
  EventEmitter: new () => ExternalEventEmitter;
31
28
  };
32
29
  fs: ExternalFileSystem;
30
+ web: {
31
+ fetch: typeof fetch;
32
+ getCache: () => Promise<Cache>;
33
+ };
33
34
  }
34
35
  export interface DecompressedFile {
35
36
  data: Uint8Array;
@@ -1,2 +1,2 @@
1
- export * from './downloader.js';
1
+ export {};
2
2
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,15 @@
1
1
  export type Dependency = {
2
+ type: 'directory';
2
3
  uri: string;
3
- info?: Record<string, any>;
4
+ } | {
5
+ type: 'tarball-file';
6
+ uri: string;
7
+ stripLevel?: number;
8
+ } | {
9
+ type: 'tarball-ram';
10
+ name: string;
11
+ data: Uint8Array;
12
+ stripLevel?: number;
4
13
  };
5
14
  export type DependencyKey = `@${string}`;
6
15
  export declare namespace DependencyKey {
@@ -137,7 +137,11 @@ export class FileUriSupporter {
137
137
  static async create(dependencies, externals, logger) {
138
138
  const roots = [];
139
139
  const files = new Map();
140
- for (let { uri } of dependencies) {
140
+ for (const dependency of dependencies) {
141
+ if (dependency.type !== 'directory') {
142
+ continue;
143
+ }
144
+ let { uri } = dependency;
141
145
  try {
142
146
  if (fileUtil.isFileUri(uri) && (await externals.fs.stat(uri)).isDirectory()) {
143
147
  uri = fileUtil.ensureEndingSlash(uri);
@@ -232,23 +236,26 @@ export class ArchiveUriSupporter {
232
236
  }
233
237
  static async create(dependencies, externals, logger) {
234
238
  const entries = new Map();
235
- for (const { uri, info } of dependencies) {
239
+ for (const dependency of dependencies) {
240
+ if (dependency.type === 'directory') {
241
+ continue;
242
+ }
243
+ const archiveName = dependency.type === 'tarball-file'
244
+ ? fileUtil.basename(dependency.uri)
245
+ : dependency.name;
236
246
  try {
237
- if (uri.startsWith('file:')
238
- && ArchiveUriSupporter.SupportedArchiveExtnames.some((ext) => uri.endsWith(ext))
239
- && (await externals.fs.stat(uri)).isFile()) {
240
- const archiveName = fileUtil.basename(uri);
241
- if (entries.has(archiveName)) {
242
- throw new Error(`A different URI with ${archiveName} already exists`);
243
- }
244
- const files = await externals.archive.decompressBall(await externals.fs.readFile(uri), { stripLevel: typeof info?.startDepth === 'number' ? info.startDepth : 0 });
245
- /// Debug message for #1609
246
- logger.info(`[ArchiveUriSupporter#create] Extracted ${files.length} files from ${archiveName}`);
247
- entries.set(archiveName, new Map(files.map((f) => [f.path.replace(/\\/g, '/'), f])));
247
+ if (entries.has(archiveName)) {
248
+ throw new Error(`A different archive with ${archiveName} already exists`);
248
249
  }
250
+ const files = await externals.archive.decompressBall(dependency.type === 'tarball-file'
251
+ ? await externals.fs.readFile(dependency.uri)
252
+ : dependency.data, { stripLevel: dependency.stripLevel ?? 0 });
253
+ /// Debug message for #1609
254
+ logger.info(`[ArchiveUriSupporter#create] Extracted ${files.length} files from ${archiveName}`);
255
+ entries.set(archiveName, new Map(files.map((f) => [f.path.replace(/\\/g, '/'), f])));
249
256
  }
250
257
  catch (e) {
251
- logger.error(`[ArchiveUriSupporter#create] Bad dependency ${uri}`, e);
258
+ logger.error(`[ArchiveUriSupporter#create] Bad dependency ${archiveName}`, e);
252
259
  }
253
260
  }
254
261
  return new ArchiveUriSupporter(externals, logger, entries);
@@ -8,19 +8,17 @@ import type { PosRangeLanguageError } from '../source/index.js';
8
8
  import { SymbolUtil } from '../symbol/index.js';
9
9
  import { CacheService } from './CacheService.js';
10
10
  import type { Config } from './Config.js';
11
- import { Downloader } from './Downloader.js';
12
11
  import { FileService } from './FileService.js';
13
12
  import type { RootUriString } from './fileUtil.js';
14
13
  import { MetaRegistry } from './MetaRegistry.js';
15
14
  import { ProfilerFactory } from './Profiler.js';
16
- export type ProjectInitializerContext = Pick<Project, 'cacheRoot' | 'config' | 'downloader' | 'externals' | 'isDebugging' | 'logger' | 'meta' | 'projectRoots'>;
15
+ export type ProjectInitializerContext = Pick<Project, 'cacheRoot' | 'config' | 'externals' | 'isDebugging' | 'logger' | 'meta' | 'projectRoots'>;
17
16
  export type SyncProjectInitializer = (this: void, ctx: ProjectInitializerContext) => Record<string, string> | void;
18
17
  export type AsyncProjectInitializer = (this: void, ctx: ProjectInitializerContext) => PromiseLike<Record<string, string> | void>;
19
18
  export type ProjectInitializer = SyncProjectInitializer | AsyncProjectInitializer;
20
19
  export interface ProjectOptions {
21
20
  cacheRoot: RootUriString;
22
21
  defaultConfig?: Config;
23
- downloader?: Downloader;
24
22
  externals: Externals;
25
23
  fs?: FileService;
26
24
  initializers?: readonly ProjectInitializer[];
@@ -56,7 +54,7 @@ interface SymbolRegistrarEvent {
56
54
  id: string;
57
55
  checksum: string | undefined;
58
56
  }
59
- export type ProjectData = Pick<Project, 'cacheRoot' | 'config' | 'downloader' | 'ensureBindingStarted' | 'externals' | 'fs' | 'isDebugging' | 'logger' | 'meta' | 'profilers' | 'projectRoots' | 'roots' | 'symbols' | 'ctx'>;
57
+ export type ProjectData = Pick<Project, 'cacheRoot' | 'config' | 'ensureBindingStarted' | 'externals' | 'fs' | 'isDebugging' | 'logger' | 'meta' | 'profilers' | 'projectRoots' | 'roots' | 'symbols' | 'ctx'>;
60
58
  /**
61
59
  * Manage all tracked documents and errors.
62
60
  *
@@ -100,7 +98,6 @@ export declare class Project implements ExternalEventEmitter {
100
98
  readonly cacheService: CacheService;
101
99
  get isReady(): boolean;
102
100
  config: Config;
103
- readonly downloader: Downloader;
104
101
  readonly externals: Externals;
105
102
  readonly fs: FileService;
106
103
  readonly isDebugging: boolean;
@@ -156,7 +153,7 @@ export declare class Project implements ExternalEventEmitter {
156
153
  * are not loaded into the memory.
157
154
  */
158
155
  getTrackedFiles(): string[];
159
- constructor({ cacheRoot, defaultConfig, downloader, externals, fs, initializers, isDebugging, logger, profilers, projectRoots, }: ProjectOptions);
156
+ constructor({ cacheRoot, defaultConfig, externals, fs, initializers, isDebugging, logger, profilers, projectRoots, }: ProjectOptions);
160
157
  private setInitPromise;
161
158
  private setReadyPromise;
162
159
  /**