@fuzdev/fuz_ui 0.186.0 → 0.187.0

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.
@@ -37,10 +37,15 @@
37
37
  );
38
38
 
39
39
  // find the module using the lookup helper
40
- const module = $derived(library.lookup_module(module_path));
40
+ const module = $derived(library.module_by_path.get(module_path));
41
+
42
+ // check if this is a directory prefix containing child modules
43
+ const directory_modules = $derived(module ? null : library.lookup_directory_modules(module_path));
41
44
 
42
45
  // fallback for 404
43
- const module_name = $derived(module?.path || '[missing module]');
46
+ const module_name = $derived(
47
+ module?.path || (directory_modules ? module_path : '[missing module]'),
48
+ );
44
49
 
45
50
  const search = $derived(create_module_declaration_search(module?.declarations ?? []));
46
51
 
@@ -57,7 +62,18 @@
57
62
  <h1 class="mt_xl4">{module_name}</h1>
58
63
  {/snippet}
59
64
 
60
- {#if !module}
65
+ {#if !module && directory_modules}
66
+ <section>
67
+ <p>{directory_modules.length} module{directory_modules.length === 1 ? '' : 's'}</p>
68
+ <ul>
69
+ {#each directory_modules as child_module (child_module.path)}
70
+ <li>
71
+ <ModuleLink module_path={child_module.path} />
72
+ </li>
73
+ {/each}
74
+ </ul>
75
+ </section>
76
+ {:else if !module}
61
77
  <section>
62
78
  <p>Module not found: {module_path}</p>
63
79
  </section>
@@ -67,7 +83,7 @@
67
83
  <Mdz content={module.module_comment} />
68
84
  </section>
69
85
  {/if}
70
- <!-- Declarations Section -->
86
+ <!-- Declarations section -->
71
87
  <TomeSection>
72
88
  <TomeSectionHeader text="Declarations" />
73
89
 
@@ -92,7 +108,7 @@
92
108
  <ApiDeclarationList declarations={search.filtered} search_query={search.query} />
93
109
  </TomeSection>
94
110
 
95
- <!-- Depends on Section -->
111
+ <!-- Depends on section -->
96
112
  {#if module.dependencies}
97
113
  <TomeSection>
98
114
  <TomeSectionHeader text="Depends on" />
@@ -106,7 +122,7 @@
106
122
  </TomeSection>
107
123
  {/if}
108
124
 
109
- <!-- Imported by Section -->
125
+ <!-- Imported by section -->
110
126
  {#if module.dependents}
111
127
  <TomeSection>
112
128
  <TomeSectionHeader text="Imported by" />
@@ -1 +1 @@
1
- {"version":3,"file":"ApiModule.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/ApiModule.svelte"],"names":[],"mappings":"AAGA,OAAO,EAAkB,KAAK,OAAO,EAAC,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAmB,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AAUrD,KAAK,gBAAgB,GAAI;IACxB;;OAEG;IACH,WAAW,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;CACZ,CAAC;AA2GH,QAAA,MAAM,SAAS,sDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"ApiModule.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/ApiModule.svelte"],"names":[],"mappings":"AAGA,OAAO,EAAkB,KAAK,OAAO,EAAC,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAmB,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AAUrD,KAAK,gBAAgB,GAAI;IACxB;;OAEG;IACH,WAAW,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;CACZ,CAAC;AA2HH,QAAA,MAAM,SAAS,sDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
@@ -20,7 +20,7 @@
20
20
 
21
21
  const library = library_context.get();
22
22
 
23
- const declaration = $derived(library.lookup_declaration(name));
23
+ const declaration = $derived(library.declaration_by_name.get(name));
24
24
 
25
25
  const contextmenu_entries = $derived(
26
26
  declaration ? create_declaration_contextmenu(declaration) : undefined,
@@ -22,8 +22,8 @@
22
22
  const library = library_context.get();
23
23
 
24
24
  // Try to find as declaration first, then module
25
- const declaration = $derived(library.lookup_declaration(reference));
26
- const module = $derived(declaration ? declaration.module : library.lookup_module(reference));
25
+ const declaration = $derived(library.declaration_by_name.get(reference));
26
+ const module = $derived(declaration ? declaration.module : library.module_by_path.get(reference));
27
27
  </script>
28
28
 
29
29
  {#if declaration}
@@ -33,13 +33,13 @@
33
33
 
34
34
  const modules_related_to_selected = $derived(
35
35
  selected_tome?.related_modules
36
- .map((path) => library.lookup_module(path))
36
+ .map((path) => library.module_by_path.get(path))
37
37
  .filter((m) => m !== undefined) ?? [],
38
38
  );
39
39
 
40
40
  const declarations_related_to_selected = $derived(
41
41
  selected_tome?.related_declarations
42
- .map((name) => library.lookup_declaration(name))
42
+ .map((name) => library.declaration_by_name.get(name))
43
43
  .filter((d) => d !== undefined) ?? [],
44
44
  );
45
45
 
@@ -20,7 +20,7 @@
20
20
 
21
21
  const library = library_context.get();
22
22
 
23
- const module = $derived(library.lookup_module(module_path));
23
+ const module = $derived(library.module_by_path.get(module_path));
24
24
 
25
25
  const color_class = $derived(module_path.endsWith('.svelte') ? 'color_h' : '');
26
26
 
@@ -19,7 +19,7 @@
19
19
  // TODO maybe better name?
20
20
  </script>
21
21
 
22
- {#if library.lookup_declaration(type)}
22
+ {#if library.declaration_by_name.has(type)}
23
23
  <DeclarationLink name={type} {hash} />
24
24
  {:else}
25
25
  <Code lang="ts" content={type} inline />
@@ -22,7 +22,7 @@ export declare class Library {
22
22
  * Default `''` preserves single-package behavior.
23
23
  */
24
24
  readonly url_prefix: string;
25
- package_json: {
25
+ readonly package_json: {
26
26
  [x: string]: unknown;
27
27
  name: string;
28
28
  version: string;
@@ -86,7 +86,7 @@ export declare class Library {
86
86
  main?: string | undefined;
87
87
  exports?: string | Record<string, unknown> | null | undefined;
88
88
  };
89
- source_json: {
89
+ readonly source_json: {
90
90
  [x: string]: unknown;
91
91
  name: string;
92
92
  version: string;
@@ -162,49 +162,46 @@ export declare class Library {
162
162
  star_exports?: string[] | undefined;
163
163
  }[] | undefined;
164
164
  };
165
- name: string;
166
- repo_name: string;
167
- repo_url: import("@fuzdev/fuz_util/url.js").Url;
168
- owner_name: string | null;
169
- homepage_url: import("@fuzdev/fuz_util/url.js").Url | null;
170
- logo_url: import("@fuzdev/fuz_util/url.js").Url | null;
171
- logo_alt: string;
172
- npm_url: import("@fuzdev/fuz_util/url.js").Url | null;
173
- changelog_url: import("@fuzdev/fuz_util/url.js").Url | null;
174
- published: boolean;
165
+ readonly name: string;
166
+ readonly repo_name: string;
167
+ readonly repo_url: import("@fuzdev/fuz_util/url.js").Url;
168
+ readonly owner_name: string | null;
169
+ readonly homepage_url: import("@fuzdev/fuz_util/url.js").Url | null;
170
+ readonly logo_url: import("@fuzdev/fuz_util/url.js").Url | null;
171
+ readonly logo_alt: string;
172
+ readonly npm_url: import("@fuzdev/fuz_util/url.js").Url | null;
173
+ readonly changelog_url: import("@fuzdev/fuz_util/url.js").Url | null;
174
+ readonly published: boolean;
175
175
  /**
176
176
  * Organization URL (e.g., 'https://github.com/ryanatkn').
177
177
  */
178
- org_url: string | null;
178
+ readonly org_url: string | null;
179
179
  /**
180
180
  * All modules as rich Module instances.
181
181
  */
182
- modules: Module[];
182
+ readonly modules: Module[];
183
183
  /**
184
184
  * All modules sorted alphabetically by path.
185
185
  */
186
- modules_sorted: Module[];
186
+ readonly modules_sorted: Module[];
187
187
  /**
188
188
  * All declarations across all modules as a flat array.
189
189
  */
190
- declarations: Declaration[];
190
+ readonly declarations: Declaration[];
191
191
  /**
192
- * Declaration lookup map by name. Provides O(1) lookup.
193
- */
194
- declaration_map: Map<string, Declaration>;
195
- constructor(library_json: LibraryJson, url_prefix?: string);
196
- /**
197
- * Look up a declaration by name.
192
+ * Module lookup map by path. Provides O(1) lookup.
198
193
  */
199
- lookup_declaration(name: string): Declaration | undefined;
194
+ readonly module_by_path: Map<string, Module>;
200
195
  /**
201
- * Check if a declaration exists.
196
+ * Declaration lookup map by name. Provides O(1) lookup.
202
197
  */
203
- has_declaration(name: string): boolean;
198
+ readonly declaration_by_name: Map<string, Declaration>;
199
+ constructor(library_json: LibraryJson, url_prefix?: string);
204
200
  /**
205
- * Look up a module by its canonical path.
201
+ * Look up modules within a directory prefix.
202
+ * Returns modules whose paths start with `path + "/"`, or `null` if none match.
206
203
  */
207
- lookup_module(path: string): Module | undefined;
204
+ lookup_directory_modules(path: string): Array<Module> | null;
208
205
  /**
209
206
  * Search declarations by query string with multi-term AND logic.
210
207
  */
@@ -1 +1 @@
1
- {"version":3,"file":"library.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/library.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,kCAAkC,CAAC;AAIlE,OAAO,EAAC,WAAW,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,wBAAwB,GAAI,OAAO,OAAO,KAAG,MAGzD,CAAC;AAEF;;;;;;;;GAQG;AACH,qBAAa,OAAO;IACnB,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAiB;IAEnD;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAA4C;IACxD,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAA2C;IAEtD,IAAI,SAAoC;IACxC,SAAS,SAAyC;IAClD,QAAQ,wCAAwC;IAChD,UAAU,gBAA0C;IACpD,YAAY,+CAA4C;IACxD,QAAQ,+CAAwC;IAChD,QAAQ,SAAwC;IAChD,OAAO,+CAAuC;IAC9C,aAAa,+CAA6C;IAC1D,SAAS,UAAyC;IAElD;;OAEG;IACH,OAAO,gBAML;IAEF;;OAEG;IACH,OAAO,WAIL;IAEF;;OAEG;IACH,cAAc,WAA4E;IAE1F;;OAEG;IACH,YAAY,gBAAmE;IAE/E;;OAEG;IACH,eAAe,2BAAgE;gBAEnE,YAAY,EAAE,WAAW,EAAE,UAAU,SAAK;IAKtD;;OAEG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIzD;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAItC;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI/C;;OAEG;IACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC;CAGtD;AAED,eAAO,MAAM,eAAe;;;;CAA4B,CAAC"}
1
+ {"version":3,"file":"library.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/library.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,kCAAkC,CAAC;AAIlE,OAAO,EAAC,WAAW,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,wBAAwB,GAAI,OAAO,OAAO,KAAG,MAGzD,CAAC;AAEF;;;;;;;;GAQG;AACH,qBAAa,OAAO;IACnB,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAiB;IAEnD;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,QAAQ,CAAC,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAA4C;IACjE,QAAQ,CAAC,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAA2C;IAE/D,QAAQ,CAAC,IAAI,SAAoC;IACjD,QAAQ,CAAC,SAAS,SAAyC;IAC3D,QAAQ,CAAC,QAAQ,wCAAwC;IACzD,QAAQ,CAAC,UAAU,gBAA0C;IAC7D,QAAQ,CAAC,YAAY,+CAA4C;IACjE,QAAQ,CAAC,QAAQ,+CAAwC;IACzD,QAAQ,CAAC,QAAQ,SAAwC;IACzD,QAAQ,CAAC,OAAO,+CAAuC;IACvD,QAAQ,CAAC,aAAa,+CAA6C;IACnE,QAAQ,CAAC,SAAS,UAAyC;IAE3D;;OAEG;IACH,QAAQ,CAAC,OAAO,gBAMd;IAEF;;OAEG;IACH,QAAQ,CAAC,OAAO,WAId;IAEF;;OAEG;IACH,QAAQ,CAAC,cAAc,WAErB;IAEF;;OAEG;IACH,QAAQ,CAAC,YAAY,gBAAmE;IAExF;;OAEG;IACH,QAAQ,CAAC,cAAc,sBAA2D;IAElF;;OAEG;IACH,QAAQ,CAAC,mBAAmB,2BAAgE;gBAEhF,YAAY,EAAE,WAAW,EAAE,UAAU,SAAK;IAKtD;;;OAGG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI;IAW5D;;OAEG;IACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC;CAGtD;AAED,eAAO,MAAM,eAAe;;;;CAA4B,CAAC"}
@@ -61,31 +61,31 @@ export class Library {
61
61
  * All declarations across all modules as a flat array.
62
62
  */
63
63
  declarations = $derived(this.modules.flatMap((module) => module.declarations));
64
+ /**
65
+ * Module lookup map by path. Provides O(1) lookup.
66
+ */
67
+ module_by_path = $derived(new Map(this.modules.map((m) => [m.path, m])));
64
68
  /**
65
69
  * Declaration lookup map by name. Provides O(1) lookup.
66
70
  */
67
- declaration_map = $derived(new Map(this.declarations.map((d) => [d.name, d])));
71
+ declaration_by_name = $derived(new Map(this.declarations.map((d) => [d.name, d])));
68
72
  constructor(library_json, url_prefix = '') {
69
73
  this.library_json = library_json;
70
74
  this.url_prefix = parse_library_url_prefix(url_prefix);
71
75
  }
72
76
  /**
73
- * Look up a declaration by name.
74
- */
75
- lookup_declaration(name) {
76
- return this.declaration_map.get(name);
77
- }
78
- /**
79
- * Check if a declaration exists.
77
+ * Look up modules within a directory prefix.
78
+ * Returns modules whose paths start with `path + "/"`, or `null` if none match.
80
79
  */
81
- has_declaration(name) {
82
- return this.declaration_map.has(name);
83
- }
84
- /**
85
- * Look up a module by its canonical path.
86
- */
87
- lookup_module(path) {
88
- return this.modules.find((m) => m.path === path);
80
+ lookup_directory_modules(path) {
81
+ const prefix = path + '/';
82
+ let result = null;
83
+ for (const m of this.modules_sorted) {
84
+ if (m.path.startsWith(prefix)) {
85
+ (result ??= []).push(m);
86
+ }
87
+ }
88
+ return result;
89
89
  }
90
90
  /**
91
91
  * Search declarations by query string with multi-term AND logic.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuzdev/fuz_ui",
3
- "version": "0.186.0",
3
+ "version": "0.187.0",
4
4
  "description": "Svelte UI library",
5
5
  "motto": "friendly user zystem",
6
6
  "glyph": "🧶",
@@ -76,13 +76,13 @@
76
76
  "devDependencies": {
77
77
  "@changesets/changelog-git": "^0.2.1",
78
78
  "@fuzdev/fuz_code": "^0.45.1",
79
- "@fuzdev/fuz_css": "^0.53.0",
80
- "@fuzdev/fuz_util": "^0.52.0",
81
- "@fuzdev/gro": "^0.195.0",
79
+ "@fuzdev/fuz_css": "^0.55.0",
80
+ "@fuzdev/fuz_util": "^0.53.4",
81
+ "@fuzdev/gro": "^0.197.0",
82
82
  "@jridgewell/trace-mapping": "^0.3.31",
83
- "@ryanatkn/eslint-config": "^0.9.0",
83
+ "@ryanatkn/eslint-config": "^0.10.1",
84
84
  "@sveltejs/adapter-static": "^3.0.10",
85
- "@sveltejs/kit": "^2.50.1",
85
+ "@sveltejs/kit": "^2.53.4",
86
86
  "@sveltejs/package": "^2.5.7",
87
87
  "@sveltejs/vite-plugin-svelte": "^6.2.4",
88
88
  "@types/estree": "^1.0.8",
@@ -95,8 +95,8 @@
95
95
  "magic-string": "^0.30.21",
96
96
  "prettier": "^3.7.4",
97
97
  "prettier-plugin-svelte": "^3.4.1",
98
- "svelte": "^5.49.1",
99
- "svelte-check": "^4.3.6",
98
+ "svelte": "^5.53.7",
99
+ "svelte-check": "^4.4.5",
100
100
  "svelte2tsx": "^0.7.47",
101
101
  "tslib": "^2.8.1",
102
102
  "typescript": "^5.9.3",
@@ -32,24 +32,24 @@ export class Library {
32
32
  */
33
33
  readonly url_prefix: string;
34
34
 
35
- package_json = $derived(this.library_json.package_json);
36
- source_json = $derived(this.library_json.source_json);
37
-
38
- name = $derived(this.library_json.name);
39
- repo_name = $derived(this.library_json.repo_name);
40
- repo_url = $derived(this.library_json.repo_url);
41
- owner_name = $derived(this.library_json.owner_name);
42
- homepage_url = $derived(this.library_json.homepage_url);
43
- logo_url = $derived(this.library_json.logo_url);
44
- logo_alt = $derived(this.library_json.logo_alt);
45
- npm_url = $derived(this.library_json.npm_url);
46
- changelog_url = $derived(this.library_json.changelog_url);
47
- published = $derived(this.library_json.published);
35
+ readonly package_json = $derived(this.library_json.package_json);
36
+ readonly source_json = $derived(this.library_json.source_json);
37
+
38
+ readonly name = $derived(this.library_json.name);
39
+ readonly repo_name = $derived(this.library_json.repo_name);
40
+ readonly repo_url = $derived(this.library_json.repo_url);
41
+ readonly owner_name = $derived(this.library_json.owner_name);
42
+ readonly homepage_url = $derived(this.library_json.homepage_url);
43
+ readonly logo_url = $derived(this.library_json.logo_url);
44
+ readonly logo_alt = $derived(this.library_json.logo_alt);
45
+ readonly npm_url = $derived(this.library_json.npm_url);
46
+ readonly changelog_url = $derived(this.library_json.changelog_url);
47
+ readonly published = $derived(this.library_json.published);
48
48
 
49
49
  /**
50
50
  * Organization URL (e.g., 'https://github.com/ryanatkn').
51
51
  */
52
- org_url = $derived(
52
+ readonly org_url = $derived(
53
53
  this.repo_url && this.repo_name
54
54
  ? this.repo_url.endsWith('/' + this.repo_name)
55
55
  ? this.repo_url.slice(0, -this.repo_name.length - 1)
@@ -60,7 +60,7 @@ export class Library {
60
60
  /**
61
61
  * All modules as rich Module instances.
62
62
  */
63
- modules = $derived(
63
+ readonly modules = $derived(
64
64
  this.source_json.modules
65
65
  ? this.source_json.modules.map((module_json) => new Module(this, module_json))
66
66
  : [],
@@ -69,17 +69,24 @@ export class Library {
69
69
  /**
70
70
  * All modules sorted alphabetically by path.
71
71
  */
72
- modules_sorted = $derived([...this.modules].sort((a, b) => a.path.localeCompare(b.path)));
72
+ readonly modules_sorted = $derived(
73
+ [...this.modules].sort((a, b) => a.path.localeCompare(b.path)),
74
+ );
73
75
 
74
76
  /**
75
77
  * All declarations across all modules as a flat array.
76
78
  */
77
- declarations = $derived(this.modules.flatMap((module) => module.declarations));
79
+ readonly declarations = $derived(this.modules.flatMap((module) => module.declarations));
80
+
81
+ /**
82
+ * Module lookup map by path. Provides O(1) lookup.
83
+ */
84
+ readonly module_by_path = $derived(new Map(this.modules.map((m) => [m.path, m])));
78
85
 
79
86
  /**
80
87
  * Declaration lookup map by name. Provides O(1) lookup.
81
88
  */
82
- declaration_map = $derived(new Map(this.declarations.map((d) => [d.name, d])));
89
+ readonly declaration_by_name = $derived(new Map(this.declarations.map((d) => [d.name, d])));
83
90
 
84
91
  constructor(library_json: LibraryJson, url_prefix = '') {
85
92
  this.library_json = library_json;
@@ -87,24 +94,18 @@ export class Library {
87
94
  }
88
95
 
89
96
  /**
90
- * Look up a declaration by name.
91
- */
92
- lookup_declaration(name: string): Declaration | undefined {
93
- return this.declaration_map.get(name);
94
- }
95
-
96
- /**
97
- * Check if a declaration exists.
97
+ * Look up modules within a directory prefix.
98
+ * Returns modules whose paths start with `path + "/"`, or `null` if none match.
98
99
  */
99
- has_declaration(name: string): boolean {
100
- return this.declaration_map.has(name);
101
- }
102
-
103
- /**
104
- * Look up a module by its canonical path.
105
- */
106
- lookup_module(path: string): Module | undefined {
107
- return this.modules.find((m) => m.path === path);
100
+ lookup_directory_modules(path: string): Array<Module> | null {
101
+ const prefix = path + '/';
102
+ let result: Array<Module> | null = null;
103
+ for (const m of this.modules_sorted) {
104
+ if (m.path.startsWith(prefix)) {
105
+ (result ??= []).push(m);
106
+ }
107
+ }
108
+ return result;
108
109
  }
109
110
 
110
111
  /**