@spyglassmc/core 0.4.45 → 0.4.47

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.
Files changed (36) hide show
  1. package/lib/common/Dev.d.ts +1 -1
  2. package/lib/common/Dev.js +3 -2
  3. package/lib/common/EventDispatcher.d.ts +6 -0
  4. package/lib/common/EventDispatcher.js +15 -0
  5. package/lib/common/ReadonlyProxy.js +2 -2
  6. package/lib/common/StateProxy.js +2 -2
  7. package/lib/common/externals/BrowserExternals.d.ts +1 -9
  8. package/lib/common/externals/BrowserExternals.js +0 -59
  9. package/lib/common/externals/NodeJsExternals.d.ts +0 -19
  10. package/lib/common/externals/NodeJsExternals.js +0 -20
  11. package/lib/common/externals/index.d.ts +0 -17
  12. package/lib/common/index.d.ts +2 -0
  13. package/lib/common/index.js +2 -0
  14. package/lib/common/json.d.ts +34 -0
  15. package/lib/common/json.js +53 -0
  16. package/lib/common/util.d.ts +44 -7
  17. package/lib/common/util.js +94 -18
  18. package/lib/node/StringNode.d.ts +1 -1
  19. package/lib/parser/string.d.ts +2 -2
  20. package/lib/processor/colorizer/Colorizer.d.ts +2 -2
  21. package/lib/service/CacheService.d.ts +1 -1
  22. package/lib/service/CacheService.js +7 -8
  23. package/lib/service/Config.d.ts +6 -10
  24. package/lib/service/Config.js +3 -15
  25. package/lib/service/FileService.js +5 -5
  26. package/lib/service/FileWatcher.d.ts +9 -12
  27. package/lib/service/Project.d.ts +14 -27
  28. package/lib/service/Project.js +6 -18
  29. package/lib/service/fetcher.js +1 -1
  30. package/lib/service/fileUtil.d.ts +2 -2
  31. package/lib/service/fileUtil.js +9 -9
  32. package/lib/symbol/Symbol.d.ts +6 -6
  33. package/lib/symbol/Symbol.js +3 -2
  34. package/lib/symbol/SymbolUtil.d.ts +9 -18
  35. package/lib/symbol/SymbolUtil.js +6 -19
  36. package/package.json +4 -5
@@ -6,11 +6,11 @@ import type { Parser, Result, Returnable } from './Parser.js';
6
6
  export declare function string(options: StringOptions): InfallibleParser<StringNode>;
7
7
  export declare function parseStringValue<T extends Returnable>(parser: Parser<T>, value: string, map: IndexMap, ctx: ParserContext): Result<T>;
8
8
  export declare const BrigadierUnquotableCharacters: readonly ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "_", ".", "+", "-"];
9
- export declare const BrigadierUnquotableCharacterSet: Set<"0" | "k" | "v" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "." | "i" | "p" | "-" | "+" | "e" | "a" | "b" | "c" | "d" | "f" | "g" | "h" | "j" | "l" | "m" | "n" | "o" | "q" | "r" | "s" | "t" | "u" | "w" | "x" | "y" | "z" | "_" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z">;
9
+ export declare const BrigadierUnquotableCharacterSet: Set<"+" | "-" | "." | "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "_" | "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z">;
10
10
  export declare const BrigadierUnquotablePattern: RegExp;
11
11
  export declare const BrigadierUnquotableOption: {
12
12
  allowEmpty: boolean;
13
- allowList: Set<"0" | "k" | "v" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "." | "i" | "p" | "-" | "+" | "e" | "a" | "b" | "c" | "d" | "f" | "g" | "h" | "j" | "l" | "m" | "n" | "o" | "q" | "r" | "s" | "t" | "u" | "w" | "x" | "y" | "z" | "_" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z">;
13
+ allowList: Set<"+" | "-" | "." | "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "_" | "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z">;
14
14
  };
15
15
  export declare const BrigadierStringOptions: StringOptions;
16
16
  export declare const brigadierString: InfallibleParser<StringNode>;
@@ -18,7 +18,7 @@ export declare namespace ColorToken {
18
18
  function fillGap(tokens: readonly ColorToken[], targetRange: Range, type: ColorTokenType, modifiers?: ColorTokenModifier[]): ColorToken[];
19
19
  }
20
20
  export declare const ColorTokenTypes: readonly ["comment", "enum", "enumMember", "escape", "function", "keyword", "modifier", "number", "property", "string", "struct", "type", "variable", "error", "literal", "operator", "resourceLocation", "vector"];
21
- export type ColorTokenType = typeof ColorTokenTypes[number];
21
+ export type ColorTokenType = (typeof ColorTokenTypes)[number];
22
22
  export declare const ColorTokenModifiers: readonly ["declaration", "defaultLibrary", "definition", "deprecated", "documentation", "modification", "readonly"];
23
- export type ColorTokenModifier = typeof ColorTokenModifiers[number];
23
+ export type ColorTokenModifier = (typeof ColorTokenModifiers)[number];
24
24
  //# sourceMappingURL=Colorizer.d.ts.map
@@ -7,7 +7,7 @@ import type { Project } from './Project.js';
7
7
  * The format version of the cache. Should be increased when any changes that
8
8
  * could invalidate the cache are introduced to the Spyglass codebase.
9
9
  */
10
- export declare const LatestCacheVersion = 6;
10
+ export declare const LatestCacheVersion = 7;
11
11
  /**
12
12
  * Checksums of cached files or roots.
13
13
  */
@@ -1,4 +1,4 @@
1
- import { Uri } from '../common/index.js';
1
+ import { bigintJsonLosslessReplacer, bigintJsonLosslessReviver, getSha1, Uri, } from '../common/index.js';
2
2
  import { SymbolTable } from '../symbol/index.js';
3
3
  import { ArchiveUriSupporter } from './FileService.js';
4
4
  import { fileUtil } from './fileUtil.js';
@@ -6,7 +6,7 @@ import { fileUtil } from './fileUtil.js';
6
6
  * The format version of the cache. Should be increased when any changes that
7
7
  * could invalidate the cache are introduced to the Spyglass codebase.
8
8
  */
9
- export const LatestCacheVersion = 6;
9
+ export const LatestCacheVersion = 7;
10
10
  var Checksums;
11
11
  (function (Checksums) {
12
12
  function create() {
@@ -36,7 +36,7 @@ export class CacheService {
36
36
  }
37
37
  try {
38
38
  // TODO: Don't update this for every single change.
39
- this.checksums.files[doc.uri] = await this.project.externals.crypto.getSha1(doc.getText());
39
+ this.checksums.files[doc.uri] = await getSha1(doc.getText());
40
40
  }
41
41
  catch (e) {
42
42
  if (!this.project.externals.error.isKind(e, 'EISDIR')) {
@@ -72,7 +72,7 @@ export class CacheService {
72
72
  async getCacheFileUri() {
73
73
  if (!this.#cacheFilePath) {
74
74
  const sortedRoots = [...this.project.projectRoots].sort();
75
- const hash = await this.project.externals.crypto.getSha1(sortedRoots.join(':'));
75
+ const hash = await getSha1(sortedRoots.join(':'));
76
76
  this.#cacheFilePath = new Uri(`symbols/${hash}.json.gz`, this.cacheRoot).toString();
77
77
  }
78
78
  return this.#cacheFilePath;
@@ -87,7 +87,7 @@ export class CacheService {
87
87
  try {
88
88
  filePath = await this.getCacheFileUri();
89
89
  this.project.logger.info(`[CacheService#load] symbolCachePath = ${filePath}`);
90
- const cache = (await fileUtil.readGzippedJson(this.project.externals, filePath));
90
+ const cache = (await fileUtil.readGzippedJson(this.project.externals, filePath, bigintJsonLosslessReviver));
91
91
  __profiler.task('Read File');
92
92
  if (cache.version === LatestCacheVersion) {
93
93
  this.checksums = cache.checksums;
@@ -186,7 +186,7 @@ export class CacheService {
186
186
  errors: this.errors,
187
187
  };
188
188
  __profiler.task('Unlink Symbols');
189
- await fileUtil.writeGzippedJson(this.project.externals, filePath, cache);
189
+ await fileUtil.writeGzippedJson(this.project.externals, filePath, cache, bigintJsonLosslessReplacer);
190
190
  __profiler.task('Write File').finalize();
191
191
  return true;
192
192
  }
@@ -196,8 +196,7 @@ export class CacheService {
196
196
  return false;
197
197
  }
198
198
  async hasFileChangedSinceCache(doc) {
199
- return (this.checksums.files[doc.uri]
200
- !== (await this.project.externals.crypto.getSha1(doc.getText())));
199
+ return (this.checksums.files[doc.uri] !== (await getSha1(doc.getText())));
201
200
  }
202
201
  reset() {
203
202
  this.#hasValidatedFiles = false;
@@ -1,5 +1,5 @@
1
- import type { DeepPartial, ExternalEventEmitter } from '../common/index.js';
2
- import { Arrayable } from '../common/index.js';
1
+ import type { DeepPartial } from '../common/index.js';
2
+ import { Arrayable, EventDispatcher } from '../common/index.js';
3
3
  import { ErrorSeverity } from '../source/index.js';
4
4
  import type { Project } from './Project.js';
5
5
  export interface Config {
@@ -239,19 +239,15 @@ type ErrorEvent = {
239
239
  error: unknown;
240
240
  uri: string;
241
241
  };
242
- export declare class ConfigService implements ExternalEventEmitter {
243
- #private;
242
+ export declare class ConfigService extends EventDispatcher<{
243
+ changed: ConfigEvent;
244
+ error: ErrorEvent;
245
+ }> {
244
246
  private readonly project;
245
247
  private readonly defaultConfig;
246
248
  static readonly ConfigFileNames: readonly ["spyglass.json", ".spyglassrc", ".spyglassrc.json"];
247
249
  private currentEditorConfiguration;
248
250
  constructor(project: Project, defaultConfig?: Config);
249
- on(event: 'changed', callbackFn: (data: ConfigEvent) => void): this;
250
- on(event: 'error', callbackFn: (data: ErrorEvent) => void): this;
251
- once(event: 'changed', callbackFn: (data: ConfigEvent) => void): this;
252
- once(event: 'error', callbackFn: (data: ErrorEvent) => void): this;
253
- emit(event: 'changed', data: ConfigEvent): boolean;
254
- emit(event: 'error', data: ErrorEvent): boolean;
255
251
  onEditorConfigurationUpdate(editorConfiguration: PartialConfig): Promise<void>;
256
252
  load(): Promise<Config>;
257
253
  static isConfigFile(this: void, uri: string): boolean;
@@ -1,5 +1,5 @@
1
1
  import rfdc from 'rfdc';
2
- import { Arrayable, bufferToString, merge, TypePredicates } from '../common/index.js';
2
+ import { Arrayable, bufferToString, EventDispatcher, merge, TypePredicates, } from '../common/index.js';
3
3
  import { ErrorSeverity } from '../source/index.js';
4
4
  import { DataFileCategories, RegistryCategories } from '../symbol/index.js';
5
5
  export var LinterSeverity;
@@ -296,16 +296,15 @@ export var PartialConfig;
296
296
  }
297
297
  PartialConfig.buildConfigFromEditorSettingsSafe = buildConfigFromEditorSettingsSafe;
298
298
  })(PartialConfig || (PartialConfig = {}));
299
- export class ConfigService {
299
+ export class ConfigService extends EventDispatcher {
300
300
  project;
301
301
  defaultConfig;
302
302
  static ConfigFileNames = Object.freeze(['spyglass.json', '.spyglassrc', '.spyglassrc.json']);
303
- #eventEmitter;
304
303
  currentEditorConfiguration = {};
305
304
  constructor(project, defaultConfig = VanillaConfig) {
305
+ super();
306
306
  this.project = project;
307
307
  this.defaultConfig = defaultConfig;
308
- this.#eventEmitter = new project.externals.event.EventEmitter();
309
308
  const handler = async ({ uri }) => {
310
309
  if (ConfigService.isConfigFile(uri)) {
311
310
  this.emit('changed', { config: await this.load() });
@@ -315,17 +314,6 @@ export class ConfigService {
315
314
  project.on('fileModified', handler);
316
315
  project.on('fileDeleted', handler);
317
316
  }
318
- on(event, callbackFn) {
319
- this.#eventEmitter.on(event, callbackFn);
320
- return this;
321
- }
322
- once(event, callbackFn) {
323
- this.#eventEmitter.once(event, callbackFn);
324
- return this;
325
- }
326
- emit(event, ...args) {
327
- return this.#eventEmitter.emit(event, ...args);
328
- }
329
317
  async onEditorConfigurationUpdate(editorConfiguration) {
330
318
  this.currentEditorConfiguration = editorConfiguration;
331
319
  this.emit('changed', { config: await this.load() });
@@ -1,5 +1,5 @@
1
1
  /* istanbul ignore file */
2
- import { Uri } from '../common/index.js';
2
+ import { getSha1, Uri } from '../common/index.js';
3
3
  import { TwoWayMap } from '../common/TwoWayMap.js';
4
4
  import { fileUtil } from './fileUtil.js';
5
5
  export var FileService;
@@ -77,7 +77,7 @@ export class FileServiceImpl {
77
77
  try {
78
78
  let mappedUri = this.map.getKey(virtualUri);
79
79
  if (mappedUri === undefined) {
80
- mappedUri = `${this.virtualUrisRoot}${await this.externals.crypto.getSha1(virtualUri)}/${fileUtil.basename(virtualUri)}`;
80
+ mappedUri = `${this.virtualUrisRoot}${await getSha1(virtualUri)}/${fileUtil.basename(virtualUri)}`;
81
81
  // Delete old mapped file if it exists. This makes sure the
82
82
  // readonly permission on the file is not removed by it being
83
83
  // overwritten.
@@ -183,7 +183,7 @@ export class ArchiveUriSupporter {
183
183
  }
184
184
  else {
185
185
  // Hash the corresponding file.
186
- return this.externals.crypto.getSha1(this.getDataInArchive(archiveName, pathInArchive));
186
+ return getSha1(this.getDataInArchive(archiveName, pathInArchive));
187
187
  }
188
188
  }
189
189
  async readFile(uri) {
@@ -258,7 +258,7 @@ export class ArchiveUriSupporter {
258
258
  const files = await externals.archive.decompressBall(bytes, { stripLevel: dependency.stripLevel ?? 0 });
259
259
  /// Debug message for #1609
260
260
  logger.info(`[ArchiveUriSupporter#create] Extracted ${files.length} files from ${archiveName}`);
261
- const hash = await externals.crypto.getSha1(bytes);
261
+ const hash = await getSha1(bytes);
262
262
  archiveHashes.set(archiveName, hash);
263
263
  entries.set(archiveName, new Map(files.map((f) => [f.path.replace(/\\/g, '/'), f])));
264
264
  }
@@ -270,6 +270,6 @@ export class ArchiveUriSupporter {
270
270
  }
271
271
  }
272
272
  async function hashFile(externals, uri) {
273
- return externals.crypto.getSha1(await externals.fs.readFile(uri));
273
+ return getSha1(await externals.fs.readFile(uri));
274
274
  }
275
275
  //# sourceMappingURL=FileService.js.map
@@ -1,21 +1,18 @@
1
- import type { UriStore } from '../common/index.js';
1
+ import type { EventDispatcher, UriStore } from '../common/index.js';
2
+ export type FileWatcherEventMap = {
3
+ ready: void;
4
+ add: string;
5
+ change: string;
6
+ unlink: string;
7
+ error: Error;
8
+ };
2
9
  /**
3
10
  * A file watcher that reports additions, changes, and deletions of files.
4
11
  * Changes to directories should not be reported.
5
12
  */
6
- export interface FileWatcher {
13
+ export interface FileWatcher extends EventDispatcher<FileWatcherEventMap> {
7
14
  get watchedFiles(): UriStore;
8
15
  ready(): Promise<void>;
9
- on(eventName: 'ready', listener: () => unknown): this;
10
- once(eventName: 'ready', listener: () => unknown): this;
11
- on(eventName: 'add', listener: (uri: string) => unknown): this;
12
- once(eventName: 'add', listener: (uri: string) => unknown): this;
13
- on(eventName: 'change', listener: (uri: string) => unknown): this;
14
- once(eventName: 'change', listener: (uri: string) => unknown): this;
15
- on(eventName: 'unlink', listener: (uri: string) => unknown): this;
16
- once(eventName: 'unlink', listener: (uri: string) => unknown): this;
17
- on(eventName: 'error', listener: (error: Error) => unknown): this;
18
- once(eventName: 'error', listener: (error: Error) => unknown): this;
19
16
  close(): Promise<void>;
20
17
  }
21
18
  //# sourceMappingURL=FileWatcher.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import type { TextDocumentContentChangeEvent } from 'vscode-languageserver-textdocument';
2
2
  import { TextDocument } from 'vscode-languageserver-textdocument';
3
- import type { ExternalEventEmitter, Externals } from '../common/index.js';
4
- import { Logger, UriStore } from '../common/index.js';
3
+ import type { Externals } from '../common/index.js';
4
+ import { EventDispatcher, Logger, UriStore } from '../common/index.js';
5
5
  import type { AstNode } from '../node/index.js';
6
6
  import { FileNode } from '../node/index.js';
7
7
  import type { PosRangeLanguageError } from '../source/index.js';
@@ -100,7 +100,18 @@ export type ProjectData = Pick<Project, 'cacheRoot' | 'config' | 'ensureBindingS
100
100
  *
101
101
  * After the READY process is complete, editing text documents as signaled by the client or the file watcher results in the file being re-processed.
102
102
  */
103
- export declare class Project implements ExternalEventEmitter {
103
+ export declare class Project extends EventDispatcher<{
104
+ documentErrored: DocumentErrorEvent;
105
+ documentUpdated: DocumentEvent;
106
+ documentRemoved: FileEvent;
107
+ fileCreated: FileEvent;
108
+ fileModified: FileEvent;
109
+ fileDeleted: FileEvent;
110
+ ready: EmptyEvent;
111
+ rootsUpdated: RootsEvent;
112
+ symbolRegistrarExecuted: SymbolRegistrarEvent;
113
+ configChanged: ConfigChangeEvent;
114
+ }> {
104
115
  #private;
105
116
  private static readonly RootSuffix;
106
117
  readonly cacheService: CacheService;
@@ -134,30 +145,6 @@ export declare class Project implements ExternalEventEmitter {
134
145
  */
135
146
  get cacheRoot(): RootUriString;
136
147
  private updateRoots;
137
- on(event: 'documentErrored', callbackFn: (data: DocumentErrorEvent) => void): this;
138
- on(event: 'documentUpdated', callbackFn: (data: DocumentEvent) => void): this;
139
- on(event: 'documentRemoved', callbackFn: (data: FileEvent) => void): this;
140
- on(event: `file${'Created' | 'Modified' | 'Deleted'}`, callbackFn: (data: FileEvent) => void): this;
141
- on(event: 'ready', callbackFn: (data: EmptyEvent) => void): this;
142
- on(event: 'rootsUpdated', callbackFn: (data: RootsEvent) => void): this;
143
- on(event: 'symbolRegistrarExecuted', callbackFn: (data: SymbolRegistrarEvent) => void): this;
144
- on(event: 'configChanged', callbackFn: (data: ConfigChangeEvent) => void): this;
145
- once(event: 'documentErrored', callbackFn: (data: DocumentErrorEvent) => void): this;
146
- once(event: 'documentUpdated', callbackFn: (data: DocumentEvent) => void): this;
147
- once(event: 'documentRemoved', callbackFn: (data: FileEvent) => void): this;
148
- once(event: `file${'Created' | 'Modified' | 'Deleted'}`, callbackFn: (data: FileEvent) => void): this;
149
- once(event: 'ready', callbackFn: (data: EmptyEvent) => void): this;
150
- once(event: 'rootsUpdated', callbackFn: (data: RootsEvent) => void): this;
151
- once(event: 'symbolRegistrarExecuted', callbackFn: (data: SymbolRegistrarEvent) => void): this;
152
- once(event: 'configChanged', callbackFn: (data: ConfigChangeEvent) => void): this;
153
- emit(event: 'documentErrored', data: DocumentErrorEvent): boolean;
154
- emit(event: 'documentUpdated', data: DocumentEvent): boolean;
155
- emit(event: 'documentRemoved', data: FileEvent): boolean;
156
- emit(event: `file${'Created' | 'Modified' | 'Deleted'}`, data: FileEvent): boolean;
157
- emit(event: 'ready', data: EmptyEvent): boolean;
158
- emit(event: 'rootsUpdated', data: RootsEvent): boolean;
159
- emit(event: 'symbolRegistrarExecuted', data: SymbolRegistrarEvent): boolean;
160
- emit(event: 'configChanged', data: ConfigChangeEvent): boolean;
161
148
  /**
162
149
  * Get all files that are tracked and supported.
163
150
  *
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import picomatch from 'picomatch';
8
8
  import { TextDocument } from 'vscode-languageserver-textdocument';
9
- import { bufferToString, Logger, normalizeUri, SingletonPromise, StateProxy, UriStore, } from '../common/index.js';
9
+ import { bufferToString, EventDispatcher, Logger, normalizeUri, SingletonPromise, StateProxy, UriStore, } from '../common/index.js';
10
10
  import { FileNode } from '../node/index.js';
11
11
  import { file } from '../parser/index.js';
12
12
  import { traversePreOrder } from '../processor/index.js';
@@ -60,7 +60,7 @@ const CacheAutoSaveInterval = 600_000; // 10 Minutes.
60
60
  *
61
61
  * After the READY process is complete, editing text documents as signaled by the client or the file watcher results in the file being re-processed.
62
62
  */
63
- export class Project {
63
+ export class Project extends EventDispatcher {
64
64
  static RootSuffix = '/pack.mcmeta';
65
65
  /** Prevent circular binding. */
66
66
  #bindingInProgressUris = new Set();
@@ -71,7 +71,6 @@ export class Project {
71
71
  #clientManagedDocAndNodes = new Map();
72
72
  #configService;
73
73
  #symbolUpToDateUris = new Set();
74
- #eventEmitter;
75
74
  #initializers;
76
75
  #watcher;
77
76
  get watchedFiles() {
@@ -134,17 +133,6 @@ export class Project {
134
133
  this.#roots = [...ans].sort((a, b) => b.length - a.length);
135
134
  this.emit('rootsUpdated', { roots: this.#roots });
136
135
  }
137
- on(event, callbackFn) {
138
- this.#eventEmitter.on(event, callbackFn);
139
- return this;
140
- }
141
- once(event, callbackFn) {
142
- this.#eventEmitter.once(event, callbackFn);
143
- return this;
144
- }
145
- emit(event, ...args) {
146
- return this.#eventEmitter.emit(event, ...args);
147
- }
148
136
  /**
149
137
  * Get all files that are tracked and supported.
150
138
  *
@@ -157,8 +145,8 @@ export class Project {
157
145
  return supportedFiles;
158
146
  }
159
147
  constructor({ cacheRoot, defaultConfig, externals, fs = FileService.create(externals, cacheRoot), initializers = [], isDebugging = false, logger = Logger.create(), profilers = ProfilerFactory.noop(), projectRoots, }) {
148
+ super();
160
149
  this.#cacheRoot = cacheRoot;
161
- this.#eventEmitter = new externals.event.EventEmitter();
162
150
  this.externals = externals;
163
151
  this.fs = fs;
164
152
  this.#initializers = initializers;
@@ -168,7 +156,7 @@ export class Project {
168
156
  this.projectRoots = projectRoots;
169
157
  this.cacheService = new CacheService(cacheRoot, this);
170
158
  this.#configService = new ConfigService(this, defaultConfig);
171
- this.symbols = new SymbolUtil({}, externals.event.EventEmitter);
159
+ this.symbols = new SymbolUtil({});
172
160
  this.#ctx = {};
173
161
  this.logger.info(`[Project] [init] cacheRoot = ${cacheRoot}`);
174
162
  this.logger.info(`[Project] [init] projectRoots = ${projectRoots.join(' ')}`);
@@ -250,7 +238,7 @@ export class Project {
250
238
  };
251
239
  const __profiler = this.profilers.get('project#init');
252
240
  const { symbols } = await this.cacheService.load();
253
- this.symbols = new SymbolUtil(symbols, this.externals.event.EventEmitter);
241
+ this.symbols = new SymbolUtil(symbols);
254
242
  this.symbols.buildCache();
255
243
  __profiler.task('Load Cache');
256
244
  this.config = await this.#configService.load();
@@ -425,7 +413,7 @@ export class Project {
425
413
  }
426
414
  // Reset cache.
427
415
  const { symbols } = this.cacheService.reset();
428
- this.symbols = new SymbolUtil(symbols, this.externals.event.EventEmitter);
416
+ this.symbols = new SymbolUtil(symbols);
429
417
  this.symbols.buildCache();
430
418
  return this.restart();
431
419
  }
@@ -10,7 +10,7 @@ export async function fetchWithCache({ web }, logger, input, init) {
10
10
  }
11
11
  request.headers.set('User-Agent', 'SpyglassMC (+https://spyglassmc.com)');
12
12
  try {
13
- const response = await web.fetch(request, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });
13
+ const response = await fetch(request, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });
14
14
  if (response.status === 304) {
15
15
  Dev.assertDefined(cachedResponse);
16
16
  logger.info(`[fetchWithCache] reusing cache for ${request.url}`);
@@ -109,10 +109,10 @@ export declare namespace fileUtil {
109
109
  /**
110
110
  * @throws
111
111
  */
112
- function readGzippedJson(externals: Externals, path: FsLocation): Promise<unknown>;
112
+ function readGzippedJson(externals: Externals, path: FsLocation, reviver?: (this: any, key: string, value: any) => any): Promise<unknown>;
113
113
  /**
114
114
  * @throws
115
115
  */
116
- function writeGzippedJson(externals: Externals, path: FsLocation, data: any): Promise<void>;
116
+ function writeGzippedJson(externals: Externals, path: FsLocation, data: any, replacer?: (this: any, key: string, value: any) => any): Promise<void>;
117
117
  }
118
118
  //# sourceMappingURL=fileUtil.d.ts.map
@@ -1,4 +1,4 @@
1
- import { bufferToString, Uri } from '../common/index.js';
1
+ import { bigintJsonNumberReplacer, bigintJsonNumberReviver, bufferToString, compressBytes, decompressBytes, Uri, } from '../common/index.js';
2
2
  export var fileUtil;
3
3
  (function (fileUtil) {
4
4
  /**
@@ -228,7 +228,7 @@ export var fileUtil;
228
228
  * @throws
229
229
  */
230
230
  async function readJson(externals, path) {
231
- return JSON.parse(bufferToString(await readFile(externals, path)));
231
+ return JSON.parse(bufferToString(await readFile(externals, path)), bigintJsonNumberReviver);
232
232
  }
233
233
  fileUtil.readJson = readJson;
234
234
  /* istanbul ignore next */
@@ -238,14 +238,14 @@ export var fileUtil;
238
238
  * @see {@link writeFile}
239
239
  */
240
240
  async function writeJson(externals, path, data) {
241
- return writeFile(externals, path, JSON.stringify(data));
241
+ return writeFile(externals, path, JSON.stringify(data, bigintJsonNumberReplacer));
242
242
  }
243
243
  fileUtil.writeJson = writeJson;
244
244
  /**
245
245
  * @throws
246
246
  */
247
247
  async function readGzippedFile(externals, path) {
248
- return externals.archive.gunzip(await readFile(externals, path));
248
+ return decompressBytes(await readFile(externals, path), 'gzip');
249
249
  }
250
250
  fileUtil.readGzippedFile = readGzippedFile;
251
251
  /**
@@ -255,21 +255,21 @@ export var fileUtil;
255
255
  if (typeof buffer === 'string') {
256
256
  buffer = new TextEncoder().encode(buffer);
257
257
  }
258
- return writeFile(externals, path, await externals.archive.gzip(buffer));
258
+ return writeFile(externals, path, await compressBytes(buffer, 'gzip'));
259
259
  }
260
260
  fileUtil.writeGzippedFile = writeGzippedFile;
261
261
  /**
262
262
  * @throws
263
263
  */
264
- async function readGzippedJson(externals, path) {
265
- return JSON.parse(bufferToString(await readGzippedFile(externals, path)));
264
+ async function readGzippedJson(externals, path, reviver) {
265
+ return JSON.parse(bufferToString(await readGzippedFile(externals, path)), reviver ?? bigintJsonNumberReviver);
266
266
  }
267
267
  fileUtil.readGzippedJson = readGzippedJson;
268
268
  /**
269
269
  * @throws
270
270
  */
271
- async function writeGzippedJson(externals, path, data) {
272
- return writeGzippedFile(externals, path, JSON.stringify(data));
271
+ async function writeGzippedJson(externals, path, data, replacer) {
272
+ return writeGzippedFile(externals, path, JSON.stringify(data, replacer ?? bigintJsonNumberReplacer));
273
273
  }
274
274
  fileUtil.writeGzippedJson = writeGzippedJson;
275
275
  })(fileUtil || (fileUtil = {}));