type-registry-effect 0.1.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.
package/index.d.ts ADDED
@@ -0,0 +1,1754 @@
1
+ /**
2
+ * type-registry-effect — platform-agnostic entry point.
3
+ *
4
+ * Provides composable Effect programs for fetching, caching, and resolving
5
+ * TypeScript type definitions from npm packages via the jsDelivr CDN.
6
+ *
7
+ * @remarks
8
+ * This entry point contains only platform-agnostic code. It exports:
9
+ *
10
+ * - **Namespace modules** — {@link TypeRegistry} (composable programs) and
11
+ * {@link VirtualPackage} (synthetic packages from local declarations).
12
+ * - **Schemas** — {@link PackageSpec}, {@link CacheMetadata},
13
+ * {@link ResolvedModule}, {@link PackageJson}, {@link FileTreeResponse}.
14
+ * - **Errors** — {@link CacheError}, {@link NetworkError},
15
+ * {@link PackageNotFoundError}, {@link ParseError},
16
+ * {@link ResolutionError}, {@link TimeoutError}.
17
+ * - **Services** — {@link CacheService}, {@link PackageFetcher},
18
+ * {@link TypeResolver}.
19
+ * - **Layers** — {@link CacheServiceLive}, {@link PackageFetcherLive},
20
+ * {@link TypeResolverLive}, {@link TypeRegistryLive}.
21
+ * - **Events** — {@link LogEventSchema}, {@link LogEvent}.
22
+ *
23
+ * For a Node.js convenience layer and Promise-returning wrappers, import
24
+ * from `type-registry-effect/node` instead.
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * import { Effect } from "effect";
29
+ * import { TypeRegistry, PackageSpec, TypeRegistryLive } from "type-registry-effect";
30
+ * import { NodeFileSystem, NodeHttpClient } from "@effect/platform-node";
31
+ *
32
+ * const program = Effect.gen(function* () {
33
+ * const pkg = new PackageSpec({ name: "zod", version: "3.23.8" });
34
+ * yield* TypeRegistry.fetchAndCache(pkg);
35
+ * return yield* TypeRegistry.getVFS([pkg]);
36
+ * });
37
+ *
38
+ * const vfs = await program.pipe(
39
+ * Effect.provide(TypeRegistryLive),
40
+ * Effect.provide(NodeFileSystem.layer),
41
+ * Effect.provide(NodeHttpClient.layerUndici),
42
+ * Effect.runPromise,
43
+ * );
44
+ * ```
45
+ *
46
+ * @packageDocumentation
47
+ */
48
+
49
+ import { Context } from 'effect';
50
+ import { Effect } from 'effect';
51
+ import { Equals } from 'effect/Types';
52
+ import { FileSystem } from '@effect/platform';
53
+ import { HttpClient } from '@effect/platform';
54
+ import { Layer } from 'effect';
55
+ import { Schema } from 'effect';
56
+ import * as Schema_2 from 'effect/Schema';
57
+ import { YieldableError } from 'effect/Cause';
58
+
59
+ /**
60
+ * Raised when a disk cache operation (read, write, delete, or list) fails.
61
+ *
62
+ * @remarks
63
+ * The `operation` field indicates which cache operation triggered the failure,
64
+ * `path` is the filesystem path involved, and `message` describes the
65
+ * underlying cause (e.g. permission denied, disk full). Use `Effect.catchTag`
66
+ * with the `"CacheError"` tag to handle this error selectively.
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * import { Effect } from "effect";
71
+ * import type { CacheError } from "type-registry-effect";
72
+ * import { TypeRegistry, PackageSpec } from "type-registry-effect";
73
+ * import { NodeLayer } from "type-registry-effect/node";
74
+ *
75
+ * const program = TypeRegistry.fetchAndCache(
76
+ * new PackageSpec({ name: "zod", version: "3.23.8" }),
77
+ * ).pipe(
78
+ * Effect.catchTag("CacheError", (err: CacheError) =>
79
+ * Effect.logWarning(`Cache ${err.operation} failed at ${err.path}: ${err.message}`),
80
+ * ),
81
+ * );
82
+ *
83
+ * await Effect.runPromise(Effect.provide(program, NodeLayer));
84
+ * ```
85
+ *
86
+ * @see {@link CacheService}
87
+ * @public
88
+ */
89
+ export declare class CacheError extends CacheErrorBase<{
90
+ readonly operation: "read" | "write" | "delete" | "list";
91
+ readonly path: string;
92
+ readonly message: string;
93
+ }> {
94
+ }
95
+
96
+ /**
97
+ * @internal
98
+ * Exported for declaration bundling (api-extractor). When `export *` re-exports
99
+ * a class whose `extends` expression is an inline call like
100
+ * `Data.TaggedError(...)`, TypeScript emits an un-nameable `_base` symbol in
101
+ * the declaration file. Splitting the base into a named export gives the
102
+ * bundler a stable reference.
103
+ *
104
+ * @privateRemarks
105
+ * This base constant must remain a named export so that api-extractor can
106
+ * resolve the extends clause of {@link CacheError} to a stable
107
+ * declaration. Without it the bundled `.d.ts` would contain an anonymous
108
+ * `_base` symbol that cannot be referenced by downstream consumers.
109
+ */
110
+ export declare const CacheErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
111
+ readonly _tag: "CacheError";
112
+ } & Readonly<A>;
113
+
114
+ /**
115
+ * Metadata stored alongside cached packages on disk.
116
+ *
117
+ * @remarks
118
+ * Each cached package directory contains a metadata file recording when it was
119
+ * cached and the version that was resolved. The optional `ttl` field (in
120
+ * milliseconds) allows per-package cache expiration policies. When `ttl` is
121
+ * omitted the cache entry never expires automatically.
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * import { CacheMetadata } from "type-registry-effect";
126
+ *
127
+ * // Metadata with an explicit 1-hour TTL
128
+ * const meta: CacheMetadata = {
129
+ * version: "3.23.8",
130
+ * cachedAt: Date.now(),
131
+ * ttl: 60 * 60 * 1000,
132
+ * };
133
+ *
134
+ * // Metadata that never expires
135
+ * const permanent: CacheMetadata = {
136
+ * version: "5.4.2",
137
+ * cachedAt: Date.now(),
138
+ * };
139
+ * ```
140
+ *
141
+ * @see {@link CacheServiceLive}
142
+ * @see {@link TypeRegistry.fetchAndCache}
143
+ * @public
144
+ */
145
+ export declare interface CacheMetadata {
146
+ readonly version: string;
147
+ readonly cachedAt: number;
148
+ readonly ttl?: number | undefined;
149
+ }
150
+
151
+ /**
152
+ * Effect Schema for validating and encoding {@link CacheMetadata}.
153
+ *
154
+ * @see {@link CacheMetadata}
155
+ */
156
+ export declare const CacheMetadata: Schema.Schema<CacheMetadata>;
157
+
158
+ /**
159
+ * Effect service interface for the disk-based type definition cache.
160
+ *
161
+ * @remarks
162
+ * Implementations store type definition files and metadata on disk using a
163
+ * platform-specific {@link @effect/platform#FileSystem | FileSystem} service.
164
+ * Platform dependencies are resolved **within the layer**, so consumers of this
165
+ * interface never interact with the filesystem directly.
166
+ *
167
+ * Use this tag to access cache methods inside an `Effect.gen` block. The live
168
+ * implementation is provided by {@link CacheServiceLive} (or the lower-level
169
+ * {@link makeNodeCacheLayer}).
170
+ *
171
+ * @example
172
+ * ```typescript
173
+ * import { Effect } from "effect";
174
+ * import { CacheService } from "type-registry-effect";
175
+ * import type { PackageSpec } from "type-registry-effect";
176
+ *
177
+ * const program = Effect.gen(function* () {
178
+ * const cache = yield* CacheService;
179
+ * const exists = yield* cache.exists({ name: "lodash", version: "4.17.21" } as PackageSpec);
180
+ * console.log("cached:", exists);
181
+ * });
182
+ * ```
183
+ *
184
+ * @see {@link CacheServiceLive}
185
+ * @see {@link makeNodeCacheLayer}
186
+ *
187
+ * @public
188
+ */
189
+ export declare interface CacheService {
190
+ /** Check whether cached type definitions exist for a package. */
191
+ readonly exists: (pkg: PackageSpec) => Effect.Effect<boolean, CacheError>;
192
+ /** Read a single cached file by relative path within the package cache directory. */
193
+ readonly read: (pkg: PackageSpec, filePath: string) => Effect.Effect<string, CacheError>;
194
+ /** Write a single file into the package cache directory, creating parent directories as needed. */
195
+ readonly write: (pkg: PackageSpec, filePath: string, content: string) => Effect.Effect<void, CacheError>;
196
+ /** List all cached file paths (relative) for a package. */
197
+ readonly listFiles: (pkg: PackageSpec) => Effect.Effect<ReadonlyArray<string>, CacheError>;
198
+ /** Read the `.metadata.json` sidecar for a cached package. */
199
+ readonly readMetadata: (pkg: PackageSpec) => Effect.Effect<CacheMetadata, CacheError>;
200
+ /** Write or overwrite the `.metadata.json` sidecar for a cached package. */
201
+ readonly writeMetadata: (pkg: PackageSpec, metadata: CacheMetadata) => Effect.Effect<void, CacheError>;
202
+ /** Build a {@link VirtualFileSystem} from the cache, suitable for an in-memory TS compiler host. */
203
+ readonly getVFS: (pkg: PackageSpec) => Effect.Effect<VirtualFileSystem, CacheError>;
204
+ /** Remove all cached data for a package, including metadata. */
205
+ readonly remove: (pkg: PackageSpec) => Effect.Effect<void, CacheError>;
206
+ }
207
+
208
+ /**
209
+ * Effect Context tag for the {@link CacheService} service.
210
+ *
211
+ * @see {@link CacheServiceLive}
212
+ * @see {@link makeNodeCacheLayer}
213
+ */
214
+ export declare const CacheService: Context.Tag<CacheService, CacheService>;
215
+
216
+ /**
217
+ * Default {@link CacheService} layer using the XDG cache directory.
218
+ *
219
+ * @remarks
220
+ * This is equivalent to calling {@link makeNodeCacheLayer} with no arguments.
221
+ * Requires a {@link @effect/platform#FileSystem | FileSystem} layer to be
222
+ * provided at composition time.
223
+ *
224
+ * @see {@link makeNodeCacheLayer}
225
+ *
226
+ * @public
227
+ */
228
+ export declare const CacheServiceLive: Layer.Layer<CacheService, never, FileSystem.FileSystem>;
229
+
230
+ /**
231
+ * Remove a package and all of its cached files from the disk cache.
232
+ *
233
+ * @param pkg - The package specification to remove.
234
+ * @returns An Effect that succeeds with `void` once the cache entry is deleted.
235
+ *
236
+ * @example
237
+ * ```typescript
238
+ * import { Effect } from "effect";
239
+ * import { TypeRegistry, PackageSpec } from "type-registry-effect";
240
+ * import { NodeLayer } from "type-registry-effect/node";
241
+ *
242
+ * const program = Effect.gen(function* () {
243
+ * const pkg = new PackageSpec({ name: "zod", version: "3.23.8" });
244
+ * yield* TypeRegistry.clearCache(pkg);
245
+ * console.log("Cache cleared for zod@3.23.8");
246
+ * });
247
+ *
248
+ * await Effect.runPromise(Effect.provide(program, NodeLayer));
249
+ * ```
250
+ *
251
+ * @see {@link hasCached} to check existence before clearing
252
+ * @see {@link fetchAndCache} to repopulate the cache afterward
253
+ *
254
+ * @public
255
+ */
256
+ declare const clearCache: (pkg: PackageSpec) => Effect.Effect<void, CacheError, CacheService>;
257
+
258
+ /**
259
+ * Create a validated {@link LogEvent} from unknown data.
260
+ *
261
+ * @remarks
262
+ * Decodes `event` synchronously through {@link LogEventSchema}. Throws a
263
+ * parse error if the input does not conform to any variant of the schema.
264
+ * This is intended for internal use within the library's logging
265
+ * infrastructure.
266
+ *
267
+ * @param event - Raw, unvalidated event data.
268
+ * @returns A fully validated {@link LogEvent}.
269
+ * @throws `ParseError` when `event` does not match {@link LogEventSchema}.
270
+ *
271
+ * @internal
272
+ */
273
+ export declare function createLogEvent(event: unknown): LogEvent;
274
+
275
+ /**
276
+ * Fetch type definitions for a package from the jsDelivr CDN and write them
277
+ * to the disk cache.
278
+ *
279
+ * @remarks
280
+ * The function downloads the `package.json` and every `.d.ts` file published
281
+ * by the package, then persists them under the {@link CacheService} storage
282
+ * directory. A {@link CacheMetadata} record is written alongside the files so
283
+ * that future cache hits can evaluate freshness.
284
+ *
285
+ * The optional `ttl` (time-to-live) is stored in the metadata and expressed
286
+ * in **milliseconds**. When a subsequent read finds that the cache entry is
287
+ * older than `ttl`, the entry is considered stale and a re-fetch is triggered
288
+ * by higher-level operations such as {@link getPackageVFS}.
289
+ *
290
+ * @param pkg - The package specification to fetch.
291
+ * @param options - Optional configuration. When provided, `options.ttl` sets
292
+ * the time-to-live in milliseconds for the cached entry.
293
+ * @returns An Effect that succeeds with `void` once all files are written.
294
+ *
295
+ * @example
296
+ * ```typescript
297
+ * import { Effect } from "effect";
298
+ * import { TypeRegistry, PackageSpec } from "type-registry-effect";
299
+ * import { NodeLayer } from "type-registry-effect/node";
300
+ *
301
+ * const program = Effect.gen(function* () {
302
+ * const pkg = new PackageSpec({ name: "lodash", version: "4.17.21" });
303
+ * // Cache with a 1-hour TTL
304
+ * yield* TypeRegistry.fetchAndCache(pkg, { ttl: 60 * 60 * 1000 });
305
+ * });
306
+ *
307
+ * await Effect.runPromise(Effect.provide(program, NodeLayer));
308
+ * ```
309
+ *
310
+ * @see {@link hasCached} to check before fetching
311
+ * @see {@link getPackageVFS} for a higher-level API that auto-fetches
312
+ *
313
+ * @public
314
+ */
315
+ declare const fetchAndCache: (pkg: PackageSpec, options?: {
316
+ readonly ttl?: number;
317
+ } | undefined) => Effect.Effect<void, CacheError | NetworkError | ParseError, CacheService | PackageFetcher>;
318
+
319
+ /**
320
+ * Schema for a single file entry in the jsDelivr flat file tree response.
321
+ *
322
+ * @remarks
323
+ * Each entry contains the file `name` (path relative to the package root),
324
+ * a content `hash` for integrity checking, a `time` timestamp string, and
325
+ * the file `size` in bytes. This schema is used to validate raw JSON from
326
+ * the jsDelivr data API before further processing.
327
+ *
328
+ * @example
329
+ * ```typescript
330
+ * import { Schema } from "effect";
331
+ * import { FileTreeEntry } from "type-registry-effect";
332
+ *
333
+ * const decode = Schema.decodeUnknownSync(FileTreeEntry);
334
+ * const entry = decode({
335
+ * name: "/dist/index.d.ts",
336
+ * hash: "abc123",
337
+ * time: "2024-01-15T10:30:00.000Z",
338
+ * size: 4096,
339
+ * });
340
+ * ```
341
+ *
342
+ * @see {@link PackageFetcher.getFileTree}
343
+ * @public
344
+ */
345
+ export declare const FileTreeEntry: Schema.Struct<{
346
+ name: typeof Schema.String;
347
+ hash: typeof Schema.String;
348
+ time: typeof Schema.String;
349
+ size: typeof Schema.Number;
350
+ }>;
351
+
352
+ export declare type FileTreeEntry = Schema.Schema.Type<typeof FileTreeEntry>;
353
+
354
+ /**
355
+ * Schema for the jsDelivr flat file tree API response.
356
+ *
357
+ * @remarks
358
+ * The response includes a `default` field indicating the package's default
359
+ * branch/tag and a `files` array of {@link FileTreeEntry} objects. This
360
+ * corresponds to the `GET /v1/packages/npm/:package@:version/flat` endpoint.
361
+ *
362
+ * @example
363
+ * ```typescript
364
+ * import { Schema } from "effect";
365
+ * import { FileTreeResponse } from "type-registry-effect";
366
+ *
367
+ * const decode = Schema.decodeUnknownSync(FileTreeResponse);
368
+ * const tree = decode({
369
+ * default: "/dist/index.js",
370
+ * files: [
371
+ * { name: "/dist/index.js", hash: "abc123", time: "2024-01-15T10:30:00.000Z", size: 2048 },
372
+ * { name: "/dist/index.d.ts", hash: "def456", time: "2024-01-15T10:30:00.000Z", size: 4096 },
373
+ * ],
374
+ * });
375
+ * ```
376
+ *
377
+ * @see {@link PackageFetcher.getFileTree}
378
+ * @see {@link https://www.jsdelivr.com/docs/data.jsdelivr.com | jsDelivr Data API}
379
+ * @public
380
+ */
381
+ export declare const FileTreeResponse: Schema.Struct<{
382
+ default: typeof Schema.String;
383
+ files: Schema.Array$<Schema.Struct<{
384
+ name: typeof Schema.String;
385
+ hash: typeof Schema.String;
386
+ time: typeof Schema.String;
387
+ size: typeof Schema.Number;
388
+ }>>;
389
+ }>;
390
+
391
+ export declare type FileTreeResponse = Schema.Schema.Type<typeof FileTreeResponse>;
392
+
393
+ /**
394
+ * Return the default cache directory used by `effect-type-registry`.
395
+ *
396
+ * @remarks
397
+ * Resolves to `<XDG_CACHE_HOME>/effect-type-registry`. This is the path
398
+ * used by the built-in Node.js cache layer when no custom directory is
399
+ * provided.
400
+ *
401
+ * @returns Absolute path to the default cache directory
402
+ * (e.g. `~/.cache/effect-type-registry`).
403
+ *
404
+ * @see {@link makeNodeCacheLayer} in `"type-registry-effect/node"` which
405
+ * calls this function when constructing the default layer.
406
+ *
407
+ * @public
408
+ */
409
+ export declare function getDefaultCacheDir(): string;
410
+
411
+ /**
412
+ * Get a {@link VirtualFileSystem} for a single package, optionally fetching
413
+ * it from the CDN first if it is not already cached.
414
+ *
415
+ * @remarks
416
+ * When `autoFetch` is `true` (the default) and the package is not present in
417
+ * the cache, this function transparently calls {@link fetchAndCache} before
418
+ * building the VFS. Set `autoFetch` to `false` to restrict the operation to
419
+ * cached data only; a {@link PackageNotFoundError} is raised if the package
420
+ * is missing.
421
+ *
422
+ * The returned VFS maps file paths (relative to `node_modules/<package>`) to
423
+ * their string contents.
424
+ *
425
+ * @param pkg - The package specification to retrieve.
426
+ * @param options - Optional configuration. When provided, `options.autoFetch`
427
+ * controls whether to fetch from the CDN on a cache miss (default `true`),
428
+ * and `options.ttl` sets the time-to-live in milliseconds forwarded to
429
+ * {@link fetchAndCache}.
430
+ * @returns An Effect that succeeds with the package's {@link VirtualFileSystem}.
431
+ *
432
+ * @example
433
+ * ```typescript
434
+ * import { Effect } from "effect";
435
+ * import type { VirtualFileSystem } from "type-registry-effect";
436
+ * import { TypeRegistry, PackageSpec } from "type-registry-effect";
437
+ * import { NodeLayer } from "type-registry-effect/node";
438
+ *
439
+ * const program = Effect.gen(function* () {
440
+ * const pkg = new PackageSpec({ name: "zod", version: "3.23.8" });
441
+ * // Auto-fetches if not cached
442
+ * const vfs: VirtualFileSystem = yield* TypeRegistry.getPackageVFS(pkg);
443
+ * console.log(`Files: ${[...vfs.keys()].join(", ")}`);
444
+ * return vfs;
445
+ * });
446
+ *
447
+ * const vfs = await Effect.runPromise(Effect.provide(program, NodeLayer));
448
+ * ```
449
+ *
450
+ * @see {@link getVFS} to load multiple packages at once
451
+ * @see {@link fetchAndCache} for the underlying fetch + write logic
452
+ *
453
+ * @public
454
+ */
455
+ declare const getPackageVFS: (pkg: PackageSpec, options?: {
456
+ readonly autoFetch?: boolean;
457
+ readonly ttl?: number;
458
+ } | undefined) => Effect.Effect<VirtualFileSystem, CacheError | NetworkError | PackageNotFoundError | ParseError, CacheService | PackageFetcher>;
459
+
460
+ /**
461
+ * Get all type entry points exported by a cached package.
462
+ *
463
+ * @remarks
464
+ * Reads the cached `package.json` and delegates to {@link TypeResolver} to
465
+ * enumerate every entry point that exposes type definitions (via `exports`,
466
+ * `types`, or `typings` fields). The package must already be in the cache.
467
+ *
468
+ * @param pkg - The cached package to inspect.
469
+ * @returns An Effect that succeeds with a read-only array of {@link ResolvedModule} entries.
470
+ *
471
+ * @example
472
+ * ```typescript
473
+ * import { Effect } from "effect";
474
+ * import type { ResolvedModule } from "type-registry-effect";
475
+ * import { TypeRegistry, PackageSpec } from "type-registry-effect";
476
+ * import { NodeLayer } from "type-registry-effect/node";
477
+ *
478
+ * const program = Effect.gen(function* () {
479
+ * const pkg = new PackageSpec({ name: "effect", version: "3.12.5" });
480
+ * yield* TypeRegistry.fetchAndCache(pkg);
481
+ * const entries: ReadonlyArray<ResolvedModule> = yield* TypeRegistry.getTypeEntries(pkg);
482
+ * for (const entry of entries) {
483
+ * console.log(`${entry.specifier} -> ${entry.resolvedPath}`);
484
+ * }
485
+ * return entries;
486
+ * });
487
+ *
488
+ * const entries = await Effect.runPromise(Effect.provide(program, NodeLayer));
489
+ * ```
490
+ *
491
+ * @see {@link resolveImport} to resolve a single specifier
492
+ * @see {@link TypeResolver} for the underlying resolution service
493
+ *
494
+ * @public
495
+ */
496
+ declare const getTypeEntries: (pkg: PackageSpec) => Effect.Effect<readonly ResolvedModule[], CacheError | ParseError | ResolutionError, CacheService | TypeResolver>;
497
+
498
+ /**
499
+ * Get a combined {@link VirtualFileSystem} for multiple packages with
500
+ * graceful degradation on per-package failures.
501
+ *
502
+ * @remarks
503
+ * Packages are fetched concurrently with a concurrency limit of **5**.
504
+ * Individual package failures are caught and accumulated rather than
505
+ * aborting the entire batch. The operation only fails with a
506
+ * {@link PackageNotFoundError} when **every** requested package fails.
507
+ * When at least one package succeeds, the merged VFS is returned and
508
+ * failing packages are silently skipped.
509
+ *
510
+ * This partial-failure strategy makes the function suitable for
511
+ * best-effort scenarios such as editor integrations where missing type
512
+ * definitions for one dependency should not block the rest.
513
+ *
514
+ * @param packages - Array of package specifications to load.
515
+ * @param options - Optional configuration forwarded to {@link getPackageVFS}.
516
+ * When provided, `options.autoFetch` controls whether to fetch missing
517
+ * packages from the CDN (default `true`), and `options.ttl` sets the
518
+ * time-to-live in milliseconds for newly cached entries.
519
+ * @returns An Effect that succeeds with the merged {@link VirtualFileSystem}.
520
+ *
521
+ * @example
522
+ * ```typescript
523
+ * import { Effect } from "effect";
524
+ * import type { VirtualFileSystem } from "type-registry-effect";
525
+ * import { TypeRegistry, PackageSpec } from "type-registry-effect";
526
+ * import { NodeLayer } from "type-registry-effect/node";
527
+ *
528
+ * const program = Effect.gen(function* () {
529
+ * const packages = [
530
+ * new PackageSpec({ name: "zod", version: "3.23.8" }),
531
+ * new PackageSpec({ name: "effect", version: "3.12.5" }),
532
+ * ];
533
+ * const vfs: VirtualFileSystem = yield* TypeRegistry.getVFS(packages);
534
+ * console.log(`Total VFS entries: ${vfs.size}`);
535
+ * return vfs;
536
+ * });
537
+ *
538
+ * const vfs = await Effect.runPromise(Effect.provide(program, NodeLayer));
539
+ * ```
540
+ *
541
+ * @see {@link getPackageVFS} for loading a single package
542
+ *
543
+ * @public
544
+ */
545
+ declare const getVFS: (packages: readonly PackageSpec[], options?: {
546
+ readonly autoFetch?: boolean;
547
+ readonly ttl?: number;
548
+ } | undefined) => Effect.Effect<VirtualFileSystem, PackageNotFoundError, CacheService | PackageFetcher>;
549
+
550
+ /**
551
+ * Check whether a package already exists in the disk cache.
552
+ *
553
+ * @remarks
554
+ * This performs a lightweight existence check against {@link CacheService} without
555
+ * reading any file contents. Use it to decide whether to fetch before calling
556
+ * {@link fetchAndCache}.
557
+ *
558
+ * @param pkg - The package specification to look up.
559
+ * @returns An Effect that succeeds with `true` when the package is cached, `false` otherwise.
560
+ *
561
+ * @example
562
+ * ```typescript
563
+ * import { Effect } from "effect";
564
+ * import { TypeRegistry, PackageSpec } from "type-registry-effect";
565
+ * import { NodeLayer } from "type-registry-effect/node";
566
+ *
567
+ * const program = Effect.gen(function* () {
568
+ * const pkg = new PackageSpec({ name: "zod", version: "3.23.8" });
569
+ * const exists = yield* TypeRegistry.hasCached(pkg);
570
+ * console.log(`zod@3.23.8 cached: ${exists}`);
571
+ * return exists;
572
+ * });
573
+ *
574
+ * const result = await Effect.runPromise(Effect.provide(program, NodeLayer));
575
+ * ```
576
+ *
577
+ * @public
578
+ */
579
+ declare const hasCached: (pkg: PackageSpec) => Effect.Effect<boolean, CacheError, CacheService>;
580
+
581
+ /**
582
+ * Type-safe log event inferred from {@link LogEventSchema}.
583
+ *
584
+ * @remarks
585
+ * This is a discriminated union — narrow it using the `event` string literal
586
+ * field. Each variant carries a strongly-typed `data` payload.
587
+ *
588
+ * @example
589
+ * ```typescript
590
+ * import type { LogEvent } from "type-registry-effect";
591
+ *
592
+ * function handleEvent(event: LogEvent): void {
593
+ * switch (event.event) {
594
+ * case "cache.hit":
595
+ * console.log(`Cache hit for ${event.data.package}@${event.data.version}`);
596
+ * break;
597
+ * case "cache.miss":
598
+ * console.log(`Cache miss for ${event.data.package}@${event.data.version}`);
599
+ * break;
600
+ * case "package.loaded":
601
+ * console.log(`Loaded ${event.data.files} files from ${event.data.source}`);
602
+ * break;
603
+ * case "packages.batch.complete":
604
+ * console.log(`Batch done: ${event.data.loaded}/${event.data.total} in ${event.data.durationMs}ms`);
605
+ * break;
606
+ * default:
607
+ * console.log(`[${event.level}] ${event.message}`);
608
+ * }
609
+ * }
610
+ * ```
611
+ *
612
+ * @see {@link LogEventSchema} for the runtime schema definition
613
+ *
614
+ * @public
615
+ */
616
+ export declare type LogEvent = Schema_2.Schema.Type<typeof LogEventSchema>;
617
+
618
+ /**
619
+ * Callback function type for receiving validated {@link LogEvent} instances.
620
+ *
621
+ * @remarks
622
+ * Pass an implementation of this type to logging integrations that subscribe
623
+ * to TypeRegistry operations. The handler is invoked synchronously with each
624
+ * event after it has been validated against the {@link LogEventSchema}.
625
+ *
626
+ * @see {@link LogEvent} for the event payload type
627
+ * @see {@link LogEventSchema} for the runtime schema
628
+ *
629
+ * @public
630
+ */
631
+ export declare type LogEventHandler = (event: LogEvent) => void;
632
+
633
+ /**
634
+ * Discriminated union schema for all structured log events emitted by
635
+ * TypeRegistry operations.
636
+ *
637
+ * @remarks
638
+ * The following event types are defined:
639
+ *
640
+ * - `"package.version.resolved"` — a version reference was resolved to a pinned version.
641
+ * - `"cache.hit"` — a package was found in the disk cache and is fresh.
642
+ * - `"cache.stale"` — a cached package exceeded its TTL.
643
+ * - `"cache.miss"` — a package was not found in the cache.
644
+ * - `"package.fetch.start"` — a network fetch has begun for a package.
645
+ * - `"package.loaded"` — a package was successfully loaded (from cache or network).
646
+ * - `"package.load.failed"` — loading a package failed.
647
+ * - `"packages.batch.start"` — a batch operation started for multiple packages.
648
+ * - `"packages.batch.complete"` — a batch operation finished with summary statistics.
649
+ * - `"typescript.cache.created"` — a TypeScript in-memory cache was created from VFS data.
650
+ *
651
+ * Use the `event` field on the decoded value to narrow the type in a
652
+ * `switch`/`case` or `if` block.
653
+ *
654
+ * @see {@link LogEvent} for the inferred TypeScript type
655
+ * @see {@link LogEventHandler} for the callback signature
656
+ *
657
+ * @example
658
+ * ```typescript
659
+ * import type { LogEventHandler } from "type-registry-effect";
660
+ *
661
+ * const handler: LogEventHandler = (event) => {
662
+ * if (event.event === "package.loaded") {
663
+ * console.log(`Loaded ${event.data.package}@${event.data.version}`);
664
+ * }
665
+ * };
666
+ * ```
667
+ *
668
+ * @public
669
+ */
670
+ export declare const LogEventSchema: Schema_2.Union<[Schema_2.Struct<{
671
+ event: Schema_2.Literal<["package.version.resolved"]>;
672
+ level: Schema_2.Literal<["info"]>;
673
+ message: typeof Schema_2.String;
674
+ timestamp: typeof Schema_2.Number;
675
+ fiber: Schema_2.optional<typeof Schema_2.String>;
676
+ data: Schema_2.Struct<{
677
+ package: typeof Schema_2.String;
678
+ requested: typeof Schema_2.String;
679
+ resolved: typeof Schema_2.String;
680
+ }>;
681
+ }>, Schema_2.Struct<{
682
+ event: Schema_2.Literal<["cache.hit"]>;
683
+ level: Schema_2.Literal<["info"]>;
684
+ message: typeof Schema_2.String;
685
+ timestamp: typeof Schema_2.Number;
686
+ fiber: Schema_2.optional<typeof Schema_2.String>;
687
+ data: Schema_2.Struct<{
688
+ package: typeof Schema_2.String;
689
+ version: typeof Schema_2.String;
690
+ ageMinutes: typeof Schema_2.Number;
691
+ }>;
692
+ }>, Schema_2.Struct<{
693
+ event: Schema_2.Literal<["cache.stale"]>;
694
+ level: Schema_2.Literal<["debug"]>;
695
+ message: typeof Schema_2.String;
696
+ timestamp: typeof Schema_2.Number;
697
+ fiber: Schema_2.optional<typeof Schema_2.String>;
698
+ data: Schema_2.Struct<{
699
+ package: typeof Schema_2.String;
700
+ version: typeof Schema_2.String;
701
+ ageMinutes: typeof Schema_2.Number;
702
+ ttlMinutes: typeof Schema_2.Number;
703
+ }>;
704
+ }>, Schema_2.Struct<{
705
+ event: Schema_2.Literal<["cache.miss"]>;
706
+ level: Schema_2.Literal<["debug"]>;
707
+ message: typeof Schema_2.String;
708
+ timestamp: typeof Schema_2.Number;
709
+ fiber: Schema_2.optional<typeof Schema_2.String>;
710
+ data: Schema_2.Struct<{
711
+ package: typeof Schema_2.String;
712
+ version: typeof Schema_2.String;
713
+ }>;
714
+ }>, Schema_2.Struct<{
715
+ event: Schema_2.Literal<["package.fetch.start"]>;
716
+ level: Schema_2.Literal<["debug"]>;
717
+ message: typeof Schema_2.String;
718
+ timestamp: typeof Schema_2.Number;
719
+ fiber: Schema_2.optional<typeof Schema_2.String>;
720
+ data: Schema_2.Struct<{
721
+ package: typeof Schema_2.String;
722
+ version: typeof Schema_2.String;
723
+ }>;
724
+ }>, Schema_2.Struct<{
725
+ event: Schema_2.Literal<["package.loaded"]>;
726
+ level: Schema_2.Literal<["info"]>;
727
+ message: typeof Schema_2.String;
728
+ timestamp: typeof Schema_2.Number;
729
+ fiber: Schema_2.optional<typeof Schema_2.String>;
730
+ data: Schema_2.Struct<{
731
+ package: typeof Schema_2.String;
732
+ version: typeof Schema_2.String;
733
+ files: typeof Schema_2.Number;
734
+ source: Schema_2.Literal<["cache", "network"]>;
735
+ }>;
736
+ }>, Schema_2.Struct<{
737
+ event: Schema_2.Literal<["package.load.failed"]>;
738
+ level: Schema_2.Literal<["warn"]>;
739
+ message: typeof Schema_2.String;
740
+ timestamp: typeof Schema_2.Number;
741
+ fiber: Schema_2.optional<typeof Schema_2.String>;
742
+ data: Schema_2.Struct<{
743
+ package: typeof Schema_2.String;
744
+ version: typeof Schema_2.String;
745
+ error: typeof Schema_2.String;
746
+ }>;
747
+ }>, Schema_2.Struct<{
748
+ event: Schema_2.Literal<["packages.batch.start"]>;
749
+ level: Schema_2.Literal<["debug"]>;
750
+ message: typeof Schema_2.String;
751
+ timestamp: typeof Schema_2.Number;
752
+ fiber: Schema_2.optional<typeof Schema_2.String>;
753
+ data: Schema_2.Struct<{
754
+ total: typeof Schema_2.Number;
755
+ packages: Schema_2.Array$<typeof Schema_2.String>;
756
+ }>;
757
+ }>, Schema_2.Struct<{
758
+ event: Schema_2.Literal<["packages.batch.complete"]>;
759
+ level: Schema_2.Literal<["info"]>;
760
+ message: typeof Schema_2.String;
761
+ timestamp: typeof Schema_2.Number;
762
+ fiber: Schema_2.optional<typeof Schema_2.String>;
763
+ data: Schema_2.Struct<{
764
+ loaded: typeof Schema_2.Number;
765
+ failed: typeof Schema_2.Number;
766
+ total: typeof Schema_2.Number;
767
+ totalFiles: typeof Schema_2.Number;
768
+ durationMs: typeof Schema_2.Number;
769
+ }>;
770
+ }>, Schema_2.Struct<{
771
+ event: Schema_2.Literal<["typescript.cache.created"]>;
772
+ level: Schema_2.Literal<["info"]>;
773
+ message: typeof Schema_2.String;
774
+ timestamp: typeof Schema_2.Number;
775
+ fiber: Schema_2.optional<typeof Schema_2.String>;
776
+ data: Schema_2.Struct<{
777
+ packages: Schema_2.Array$<typeof Schema_2.String>;
778
+ fileCount: typeof Schema_2.Number;
779
+ rootFiles: typeof Schema_2.Number;
780
+ }>;
781
+ }>]>;
782
+
783
+ /**
784
+ * Creates a {@link CacheService} layer backed by the local filesystem.
785
+ *
786
+ * @param baseDir - Optional custom cache directory. When omitted the XDG
787
+ * cache directory is used (see {@link getDefaultCacheDir}).
788
+ * @returns A `Layer` providing {@link CacheService} that requires
789
+ * {@link @effect/platform#FileSystem | FileSystem}.
790
+ *
791
+ * @example
792
+ * ```typescript
793
+ * import { NodeFileSystem } from "@effect/platform-node";
794
+ * import { Effect, Layer } from "effect";
795
+ * import { CacheService, makeNodeCacheLayer } from "type-registry-effect";
796
+ *
797
+ * const CustomCache = makeNodeCacheLayer("/tmp/my-type-cache");
798
+ * const MainLayer = Layer.provide(CustomCache, NodeFileSystem.layer);
799
+ *
800
+ * const program = Effect.gen(function* () {
801
+ * const cache = yield* CacheService;
802
+ * console.log("using custom cache dir");
803
+ * });
804
+ *
805
+ * Effect.runPromise(Effect.provide(program, MainLayer));
806
+ * ```
807
+ *
808
+ * @see {@link CacheService}
809
+ * @see {@link getDefaultCacheDir}
810
+ *
811
+ * @public
812
+ */
813
+ export declare const makeNodeCacheLayer: (baseDir?: string | undefined) => Layer.Layer<CacheService, never, FileSystem.FileSystem>;
814
+
815
+ /**
816
+ * Raised when an HTTP request to the jsDelivr CDN fails.
817
+ *
818
+ * @remarks
819
+ * The `url` field contains the request URL, `status` is the HTTP status code
820
+ * (when available), and `message` describes the failure. Network errors may be
821
+ * transient (e.g. DNS resolution, connection reset) or permanent (e.g. 403
822
+ * Forbidden). Use `Effect.catchTag` with the `"NetworkError"` tag to handle
823
+ * this error selectively.
824
+ *
825
+ * @example
826
+ * ```typescript
827
+ * import { Effect } from "effect";
828
+ * import type { NetworkError } from "type-registry-effect";
829
+ * import { TypeRegistry, PackageSpec } from "type-registry-effect";
830
+ * import { NodeLayer } from "type-registry-effect/node";
831
+ *
832
+ * const program = TypeRegistry.fetchAndCache(
833
+ * new PackageSpec({ name: "zod", version: "3.23.8" }),
834
+ * ).pipe(
835
+ * Effect.catchTag("NetworkError", (err: NetworkError) =>
836
+ * Effect.logError(`Request to ${err.url} failed (${err.status ?? "no status"}): ${err.message}`),
837
+ * ),
838
+ * );
839
+ *
840
+ * await Effect.runPromise(Effect.provide(program, NodeLayer));
841
+ * ```
842
+ *
843
+ * @see {@link PackageFetcher}
844
+ * @public
845
+ */
846
+ export declare class NetworkError extends NetworkErrorBase<{
847
+ readonly url: string;
848
+ readonly status?: number;
849
+ readonly message: string;
850
+ }> {
851
+ }
852
+
853
+ /**
854
+ * @internal
855
+ * Exported for declaration bundling (api-extractor). When `export *` re-exports
856
+ * a class whose `extends` expression is an inline call like
857
+ * `Data.TaggedError(...)`, TypeScript emits an un-nameable `_base` symbol in
858
+ * the declaration file. Splitting the base into a named export gives the
859
+ * bundler a stable reference.
860
+ *
861
+ * @privateRemarks
862
+ * This base constant must remain a named export so that api-extractor can
863
+ * resolve the extends clause of {@link NetworkError} to a stable
864
+ * declaration. Without it the bundled `.d.ts` would contain an anonymous
865
+ * `_base` symbol that cannot be referenced by downstream consumers.
866
+ */
867
+ export declare const NetworkErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
868
+ readonly _tag: "NetworkError";
869
+ } & Readonly<A>;
870
+
871
+ /**
872
+ * Effect service interface for fetching type definitions and package metadata
873
+ * from the jsDelivr CDN.
874
+ *
875
+ * @remarks
876
+ * All network calls are retried up to 3 times with exponential back-off
877
+ * (starting at 100 ms) and are subject to a 30-second timeout. The live
878
+ * implementation is provided by {@link PackageFetcherLive}.
879
+ *
880
+ * @example
881
+ * ```typescript
882
+ * import { Effect } from "effect";
883
+ * import { PackageFetcher } from "type-registry-effect";
884
+ *
885
+ * const program = Effect.gen(function* () {
886
+ * const fetcher = yield* PackageFetcher;
887
+ * const meta = yield* fetcher.getVersions("lodash");
888
+ * console.log("latest:", meta.tags["latest"]);
889
+ * });
890
+ * ```
891
+ *
892
+ * @see {@link PackageFetcherLive}
893
+ *
894
+ * @public
895
+ */
896
+ export declare interface PackageFetcher {
897
+ /** Fetch all published versions and dist-tags for a package. */
898
+ readonly getVersions: (name: string) => Effect.Effect<PackageMetadata, NetworkError | ParseError>;
899
+ /** Resolve a semver range or dist-tag to a concrete version string. */
900
+ readonly resolveVersion: (name: string, ref: string) => Effect.Effect<string, NetworkError | PackageNotFoundError>;
901
+ /** Retrieve the flat file tree listing for a specific package version. */
902
+ readonly getFileTree: (pkg: PackageSpec) => Effect.Effect<FileTreeResponse, NetworkError | ParseError>;
903
+ /** Download a single file from the CDN by path. */
904
+ readonly downloadFile: (pkg: PackageSpec, path: string) => Effect.Effect<string, NetworkError>;
905
+ /** Download and schema-validate the `package.json` for a package version. */
906
+ readonly getPackageJson: (pkg: PackageSpec) => Effect.Effect<PackageJson, NetworkError | ParseError>;
907
+ /** Download all TypeScript declaration files for a package version, returned as a path-to-content map. */
908
+ readonly getTypeFiles: (pkg: PackageSpec) => Effect.Effect<Map<string, string>, NetworkError | ParseError>;
909
+ }
910
+
911
+ /**
912
+ * Effect Context tag for the {@link PackageFetcher} service.
913
+ *
914
+ * @see {@link PackageFetcherLive}
915
+ */
916
+ export declare const PackageFetcher: Context.Tag<PackageFetcher, PackageFetcher>;
917
+
918
+ /**
919
+ * Live {@link PackageFetcher} layer that fetches package metadata and type
920
+ * definitions from the jsDelivr CDN.
921
+ *
922
+ * @remarks
923
+ * All HTTP requests are retried up to **3 times** with exponential back-off
924
+ * (starting at 100 ms) and time out after **30 seconds**. Requires an
925
+ * {@link @effect/platform#HttpClient | HttpClient} layer to be provided at
926
+ * composition time.
927
+ *
928
+ * @see {@link PackageFetcher}
929
+ *
930
+ * @public
931
+ */
932
+ export declare const PackageFetcherLive: Layer.Layer<PackageFetcher, never, HttpClient.HttpClient>;
933
+
934
+ /**
935
+ * Schema for a validated subset of npm `package.json` fields relevant to type resolution.
936
+ *
937
+ * @remarks
938
+ * This schema captures only the fields the type resolver needs to locate
939
+ * declaration files within a published package:
940
+ *
941
+ * - **`name`** and **`version`** -- identity fields (always required).
942
+ * - **`types`** / **`typings`** -- legacy top-level type entry points.
943
+ * - **`main`** / **`module`** -- JavaScript entry points used as fallbacks
944
+ * when no explicit type entry is declared.
945
+ * - **`exports`** -- the modern Node.js conditional exports map; may be a
946
+ * simple string or a nested record of conditions.
947
+ * - **`typesVersions`** -- TypeScript path-mapping overrides keyed by TS
948
+ * version ranges (e.g. `">=4.0"`).
949
+ * - **`dependencies`** / **`peerDependencies`** / **`devDependencies`** --
950
+ * used to discover transitive type packages (e.g. `@types/*`).
951
+ *
952
+ * Fields outside this set are intentionally ignored to keep validation fast
953
+ * and the attack surface small.
954
+ *
955
+ * @example
956
+ * ```typescript
957
+ * import { Schema } from "effect";
958
+ * import { PackageJson } from "type-registry-effect";
959
+ *
960
+ * const decode = Schema.decodeUnknownSync(PackageJson);
961
+ * const pkg = decode({
962
+ * name: "zod",
963
+ * version: "3.23.8",
964
+ * types: "./lib/types.d.ts",
965
+ * main: "./lib/index.js",
966
+ * exports: {
967
+ * ".": { types: "./lib/types.d.ts", import: "./lib/index.mjs" },
968
+ * },
969
+ * });
970
+ * ```
971
+ *
972
+ * @see {@link TypeResolver}
973
+ * @public
974
+ */
975
+ export declare const PackageJson: Schema.Struct<{
976
+ name: typeof Schema.String;
977
+ version: typeof Schema.String;
978
+ types: Schema.optional<typeof Schema.String>;
979
+ typings: Schema.optional<typeof Schema.String>;
980
+ main: Schema.optional<typeof Schema.String>;
981
+ module: Schema.optional<typeof Schema.String>;
982
+ exports: Schema.optional<Schema.Union<[typeof Schema.String, Schema.Record$<typeof Schema.String, typeof Schema.Unknown>]>>;
983
+ typesVersions: Schema.optional<Schema.Record$<typeof Schema.String, Schema.Record$<typeof Schema.String, Schema.Array$<typeof Schema.String>>>>;
984
+ dependencies: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
985
+ peerDependencies: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
986
+ devDependencies: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.String>>;
987
+ }>;
988
+
989
+ export declare type PackageJson = Schema.Schema.Type<typeof PackageJson>;
990
+
991
+ /**
992
+ * Version and tag metadata for an npm package as returned by the jsDelivr API.
993
+ *
994
+ * @remarks
995
+ * The `versions` array contains every published version string. The `tags`
996
+ * record maps dist-tags (e.g. `"latest"`, `"next"`) to their corresponding
997
+ * version strings.
998
+ *
999
+ * @public
1000
+ */
1001
+ export declare interface PackageMetadata {
1002
+ readonly versions: string[];
1003
+ readonly tags: Record<string, string>;
1004
+ }
1005
+
1006
+ /**
1007
+ * Raised when a package or version does not exist on the CDN.
1008
+ *
1009
+ * @remarks
1010
+ * The `name` and `version` fields identify the package that could not be
1011
+ * found, and `message` provides additional context. This typically occurs
1012
+ * when a typo is present in the package name or the requested version has
1013
+ * not been published. Use `Effect.catchTag` with the
1014
+ * `"PackageNotFoundError"` tag to handle this error selectively.
1015
+ *
1016
+ * @example
1017
+ * ```typescript
1018
+ * import { Effect } from "effect";
1019
+ * import type { PackageNotFoundError } from "type-registry-effect";
1020
+ * import { TypeRegistry, PackageSpec } from "type-registry-effect";
1021
+ * import { NodeLayer } from "type-registry-effect/node";
1022
+ *
1023
+ * const program = TypeRegistry.fetchAndCache(
1024
+ * new PackageSpec({ name: "nonexistent-pkg", version: "0.0.0" }),
1025
+ * ).pipe(
1026
+ * Effect.catchTag("PackageNotFoundError", (err: PackageNotFoundError) =>
1027
+ * Effect.logWarning(`Package ${err.name}@${err.version} not found: ${err.message}`),
1028
+ * ),
1029
+ * );
1030
+ *
1031
+ * await Effect.runPromise(Effect.provide(program, NodeLayer));
1032
+ * ```
1033
+ *
1034
+ * @see {@link PackageFetcher.resolveVersion}
1035
+ * @public
1036
+ */
1037
+ export declare class PackageNotFoundError extends PackageNotFoundErrorBase<{
1038
+ readonly name: string;
1039
+ readonly version: string;
1040
+ readonly message: string;
1041
+ }> {
1042
+ }
1043
+
1044
+ /**
1045
+ * @internal
1046
+ * Exported for declaration bundling (api-extractor). When `export *` re-exports
1047
+ * a class whose `extends` expression is an inline call like
1048
+ * `Data.TaggedError(...)`, TypeScript emits an un-nameable `_base` symbol in
1049
+ * the declaration file. Splitting the base into a named export gives the
1050
+ * bundler a stable reference.
1051
+ *
1052
+ * @privateRemarks
1053
+ * This base constant must remain a named export so that api-extractor can
1054
+ * resolve the extends clause of {@link PackageNotFoundError} to a stable
1055
+ * declaration. Without it the bundled `.d.ts` would contain an anonymous
1056
+ * `_base` symbol that cannot be referenced by downstream consumers.
1057
+ */
1058
+ export declare const PackageNotFoundErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
1059
+ readonly _tag: "PackageNotFoundError";
1060
+ } & Readonly<A>;
1061
+
1062
+ /**
1063
+ * Immutable value object identifying a package at a specific version.
1064
+ *
1065
+ * @remarks
1066
+ * `PackageSpec` uses {@link https://effect.website/docs/data-types/data/#taggedclass | Data.TaggedClass}
1067
+ * to provide structural equality out of the box. Two `PackageSpec` instances
1068
+ * with the same `name` and `version` are considered equal via `Equal.equals`.
1069
+ * The optional `registry` field allows targeting alternative registries.
1070
+ *
1071
+ * @example
1072
+ * ```typescript
1073
+ * import { Equal } from "effect";
1074
+ * import type { PackageSpec } from "type-registry-effect";
1075
+ * import { PackageSpec as PackageSpecClass } from "type-registry-effect";
1076
+ *
1077
+ * const pkg = new PackageSpecClass({ name: "zod", version: "3.23.8" });
1078
+ * const same = new PackageSpecClass({ name: "zod", version: "3.23.8" });
1079
+ *
1080
+ * // Structural equality via Data.TaggedClass
1081
+ * console.assert(Equal.equals(pkg, same) === true);
1082
+ *
1083
+ * // String representation: "zod@3.23.8"
1084
+ * console.assert(pkg.toString() === "zod@3.23.8");
1085
+ *
1086
+ * // Optional registry for alternative sources
1087
+ * const custom = new PackageSpecClass({
1088
+ * name: "@myorg/types",
1089
+ * version: "1.0.0",
1090
+ * registry: "https://npm.pkg.github.com",
1091
+ * });
1092
+ * ```
1093
+ *
1094
+ * @see {@link CacheService}
1095
+ * @see {@link TypeRegistry}
1096
+ * @public
1097
+ */
1098
+ export declare class PackageSpec extends PackageSpecBase<{
1099
+ readonly name: string;
1100
+ readonly version: string;
1101
+ readonly registry?: string;
1102
+ }> {
1103
+ toString(): string;
1104
+ }
1105
+
1106
+ /**
1107
+ * @internal
1108
+ * Exported for declaration bundling (api-extractor). When `export *` re-exports
1109
+ * a class whose `extends` expression is an inline call like
1110
+ * `Data.TaggedClass(...)`, TypeScript emits an un-nameable `_base` symbol in
1111
+ * the declaration file. Splitting the base into a named export gives the
1112
+ * bundler a stable reference.
1113
+ *
1114
+ * @privateRemarks
1115
+ * This base constant must remain a named export so that api-extractor can
1116
+ * resolve the extends clause of {@link PackageSpec} to a stable
1117
+ * declaration. Without it the bundled `.d.ts` would contain an anonymous
1118
+ * `_base` symbol that cannot be referenced by downstream consumers.
1119
+ */
1120
+ export declare const PackageSpecBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Readonly<A> & {
1121
+ readonly _tag: "PackageSpec";
1122
+ };
1123
+
1124
+ /**
1125
+ * Raised when a CDN response fails schema validation or JSON parsing.
1126
+ *
1127
+ * @remarks
1128
+ * The `source` field identifies what was being parsed (e.g. `"package.json"`,
1129
+ * `"file-tree"`) and `message` describes the validation failure. This
1130
+ * typically indicates the CDN returned an unexpected response shape or
1131
+ * corrupted data. Use `Effect.catchTag` with the `"ParseError"` tag to
1132
+ * handle this error selectively.
1133
+ *
1134
+ * @example
1135
+ * ```typescript
1136
+ * import { Effect } from "effect";
1137
+ * import type { ParseError } from "type-registry-effect";
1138
+ * import { TypeRegistry, PackageSpec } from "type-registry-effect";
1139
+ * import { NodeLayer } from "type-registry-effect/node";
1140
+ *
1141
+ * const program = TypeRegistry.fetchAndCache(
1142
+ * new PackageSpec({ name: "zod", version: "3.23.8" }),
1143
+ * ).pipe(
1144
+ * Effect.catchTag("ParseError", (err: ParseError) =>
1145
+ * Effect.logError(`Failed to parse ${err.source}: ${err.message}`),
1146
+ * ),
1147
+ * );
1148
+ *
1149
+ * await Effect.runPromise(Effect.provide(program, NodeLayer));
1150
+ * ```
1151
+ *
1152
+ * @see {@link PackageFetcher.getPackageJson}
1153
+ * @public
1154
+ */
1155
+ export declare class ParseError extends ParseErrorBase<{
1156
+ readonly source: string;
1157
+ readonly message: string;
1158
+ }> {
1159
+ }
1160
+
1161
+ /**
1162
+ * @internal
1163
+ * Exported for declaration bundling (api-extractor). When `export *` re-exports
1164
+ * a class whose `extends` expression is an inline call like
1165
+ * `Data.TaggedError(...)`, TypeScript emits an un-nameable `_base` symbol in
1166
+ * the declaration file. Splitting the base into a named export gives the
1167
+ * bundler a stable reference.
1168
+ *
1169
+ * @privateRemarks
1170
+ * This base constant must remain a named export so that api-extractor can
1171
+ * resolve the extends clause of {@link ParseError} to a stable
1172
+ * declaration. Without it the bundled `.d.ts` would contain an anonymous
1173
+ * `_base` symbol that cannot be referenced by downstream consumers.
1174
+ */
1175
+ export declare const ParseErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
1176
+ readonly _tag: "ParseError";
1177
+ } & Readonly<A>;
1178
+
1179
+ /**
1180
+ * Raised when an import specifier cannot be resolved to a module within a package.
1181
+ *
1182
+ * @remarks
1183
+ * The `package` field is the package name, `specifier` is the import path
1184
+ * that could not be resolved, and `message` describes the failure cause.
1185
+ * This occurs when the package's exports map, `typesVersions`, or file tree
1186
+ * do not contain a matching entry for the requested specifier. Use
1187
+ * `Effect.catchTag` with the `"ResolutionError"` tag to handle this error
1188
+ * selectively.
1189
+ *
1190
+ * @example
1191
+ * ```typescript
1192
+ * import { Effect } from "effect";
1193
+ * import type { ResolutionError } from "type-registry-effect";
1194
+ * import { TypeResolver, PackageSpec } from "type-registry-effect";
1195
+ * import { NodeLayer } from "type-registry-effect/node";
1196
+ *
1197
+ * const program = TypeResolver.resolveImport(
1198
+ * new PackageSpec({ name: "zod", version: "3.23.8" }),
1199
+ * "./nonexistent",
1200
+ * ).pipe(
1201
+ * Effect.catchTag("ResolutionError", (err: ResolutionError) =>
1202
+ * Effect.logWarning(`Cannot resolve "${err.specifier}" in ${err.package}: ${err.message}`),
1203
+ * ),
1204
+ * );
1205
+ *
1206
+ * await Effect.runPromise(Effect.provide(program, NodeLayer));
1207
+ * ```
1208
+ *
1209
+ * @see {@link TypeResolver.resolveImport}
1210
+ * @public
1211
+ */
1212
+ export declare class ResolutionError extends ResolutionErrorBase<{
1213
+ readonly package: string;
1214
+ readonly specifier: string;
1215
+ readonly message: string;
1216
+ }> {
1217
+ }
1218
+
1219
+ /**
1220
+ * @internal
1221
+ * Exported for declaration bundling (api-extractor). When `export *` re-exports
1222
+ * a class whose `extends` expression is an inline call like
1223
+ * `Data.TaggedError(...)`, TypeScript emits an un-nameable `_base` symbol in
1224
+ * the declaration file. Splitting the base into a named export gives the
1225
+ * bundler a stable reference.
1226
+ *
1227
+ * @privateRemarks
1228
+ * This base constant must remain a named export so that api-extractor can
1229
+ * resolve the extends clause of {@link ResolutionError} to a stable
1230
+ * declaration. Without it the bundled `.d.ts` would contain an anonymous
1231
+ * `_base` symbol that cannot be referenced by downstream consumers.
1232
+ */
1233
+ export declare const ResolutionErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
1234
+ readonly _tag: "ResolutionError";
1235
+ } & Readonly<A>;
1236
+
1237
+ /**
1238
+ * Represents a resolved module path within a package.
1239
+ *
1240
+ * @remarks
1241
+ * After the {@link TypeResolver} walks a package's exports and file tree, each
1242
+ * resolvable import specifier maps to a `ResolvedModule`. The `filePath` is
1243
+ * relative to the package root, and `isTypeDefinition` indicates whether the
1244
+ * file is a `.d.ts` (or `.d.mts` / `.d.cts`) declaration file. The `package`
1245
+ * field links back to the originating {@link PackageSpec}.
1246
+ *
1247
+ * @example
1248
+ * ```typescript
1249
+ * import type { ResolvedModule, PackageSpec } from "type-registry-effect";
1250
+ * import {
1251
+ * ResolvedModule as ResolvedModuleClass,
1252
+ * PackageSpec as PackageSpecClass,
1253
+ * } from "type-registry-effect";
1254
+ *
1255
+ * const mod = new ResolvedModuleClass({
1256
+ * filePath: "dist/index.d.ts",
1257
+ * isTypeDefinition: true,
1258
+ * package: new PackageSpecClass({ name: "zod", version: "3.23.8" }),
1259
+ * });
1260
+ * ```
1261
+ *
1262
+ * @see {@link TypeResolver.resolveImport}
1263
+ * @see {@link TypeResolver.resolveTypeEntries}
1264
+ * @public
1265
+ */
1266
+ export declare class ResolvedModule extends ResolvedModuleBase<{
1267
+ readonly filePath: string;
1268
+ readonly isTypeDefinition: boolean;
1269
+ readonly package: PackageSpec;
1270
+ }> {
1271
+ }
1272
+
1273
+ /**
1274
+ * @internal
1275
+ * Exported for declaration bundling (api-extractor). When `export *` re-exports
1276
+ * a class whose `extends` expression is an inline call like
1277
+ * `Data.TaggedClass(...)`, TypeScript emits an un-nameable `_base` symbol in
1278
+ * the declaration file. Splitting the base into a named export gives the
1279
+ * bundler a stable reference.
1280
+ *
1281
+ * @privateRemarks
1282
+ * This base constant must remain a named export so that api-extractor can
1283
+ * resolve the extends clause of {@link ResolvedModule} to a stable
1284
+ * declaration. Without it the bundled `.d.ts` would contain an anonymous
1285
+ * `_base` symbol that cannot be referenced by downstream consumers.
1286
+ */
1287
+ export declare const ResolvedModuleBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Readonly<A> & {
1288
+ readonly _tag: "ResolvedModule";
1289
+ };
1290
+
1291
+ /**
1292
+ * Resolve an import specifier (e.g. `"zod"`, `"zod/lib/types"`) against a
1293
+ * cached package's `package.json` exports map.
1294
+ *
1295
+ * @remarks
1296
+ * The package must already be present in the cache. The resolution logic
1297
+ * delegates to {@link TypeResolver} which interprets the `exports`, `types`,
1298
+ * and `typings` fields of the cached `package.json`.
1299
+ *
1300
+ * @param pkg - The cached package to resolve against.
1301
+ * @param specifier - The bare import specifier to resolve (e.g. `"zod"` or `"zod/lib/types"`).
1302
+ * @returns An Effect that succeeds with a {@link ResolvedModule} describing the resolved file.
1303
+ *
1304
+ * @example
1305
+ * ```typescript
1306
+ * import { Effect } from "effect";
1307
+ * import type { ResolvedModule } from "type-registry-effect";
1308
+ * import { TypeRegistry, PackageSpec } from "type-registry-effect";
1309
+ * import { NodeLayer } from "type-registry-effect/node";
1310
+ *
1311
+ * const program = Effect.gen(function* () {
1312
+ * const pkg = new PackageSpec({ name: "zod", version: "3.23.8" });
1313
+ * yield* TypeRegistry.fetchAndCache(pkg);
1314
+ * const resolved: ResolvedModule = yield* TypeRegistry.resolveImport(pkg, "zod");
1315
+ * console.log(`Resolved to: ${resolved.resolvedPath}`);
1316
+ * return resolved;
1317
+ * });
1318
+ *
1319
+ * const resolved = await Effect.runPromise(Effect.provide(program, NodeLayer));
1320
+ * ```
1321
+ *
1322
+ * @see {@link getTypeEntries} to discover all entry points
1323
+ * @see {@link TypeResolver} for the underlying resolution service
1324
+ *
1325
+ * @public
1326
+ */
1327
+ declare const resolveImport: (pkg: PackageSpec, specifier: string) => Effect.Effect<ResolvedModule, CacheError | ParseError | ResolutionError, CacheService | TypeResolver>;
1328
+
1329
+ /**
1330
+ * Resolve a version reference to a concrete, pinned version string.
1331
+ *
1332
+ * @remarks
1333
+ * Accepts any npm-style version reference — `"latest"`, a semver range
1334
+ * like `"^1.0.0"`, or an exact version like `"3.23.8"` — and queries the
1335
+ * {@link PackageFetcher} (backed by the jsDelivr API) to determine the
1336
+ * matching published version.
1337
+ *
1338
+ * @param name - The npm package name (e.g. `"zod"`).
1339
+ * @param ref - A version reference: `"latest"`, a semver range, or an exact version.
1340
+ * @returns An Effect that succeeds with the resolved version string (e.g. `"3.23.8"`).
1341
+ *
1342
+ * @example
1343
+ * ```typescript
1344
+ * import { Effect } from "effect";
1345
+ * import { TypeRegistry } from "type-registry-effect";
1346
+ * import { NodeLayer } from "type-registry-effect/node";
1347
+ *
1348
+ * const program = Effect.gen(function* () {
1349
+ * const version = yield* TypeRegistry.resolveVersion("zod", "latest");
1350
+ * console.log(`Latest zod version: ${version}`);
1351
+ * return version;
1352
+ * });
1353
+ *
1354
+ * const version = await Effect.runPromise(Effect.provide(program, NodeLayer));
1355
+ * ```
1356
+ *
1357
+ * @see {@link PackageFetcher} for the underlying network service
1358
+ *
1359
+ * @public
1360
+ */
1361
+ declare const resolveVersion: (name: string, ref: string) => Effect.Effect<string, NetworkError | PackageNotFoundError, PackageFetcher>;
1362
+
1363
+ /**
1364
+ * Raised when an operation exceeds its configured time limit.
1365
+ *
1366
+ * @remarks
1367
+ * The `operation` field describes what was being performed (e.g.
1368
+ * `"fetchFileTree"`, `"resolveVersion"`), `duration` is the elapsed time in
1369
+ * milliseconds, and `message` provides additional context. Use
1370
+ * `Effect.catchTag` with the `"TimeoutError"` tag to handle this error
1371
+ * selectively.
1372
+ *
1373
+ * @example
1374
+ * ```typescript
1375
+ * import { Effect } from "effect";
1376
+ * import type { TimeoutError } from "type-registry-effect";
1377
+ * import { TypeRegistry, PackageSpec } from "type-registry-effect";
1378
+ * import { NodeLayer } from "type-registry-effect/node";
1379
+ *
1380
+ * const program = TypeRegistry.fetchAndCache(
1381
+ * new PackageSpec({ name: "zod", version: "3.23.8" }),
1382
+ * ).pipe(
1383
+ * Effect.catchTag("TimeoutError", (err: TimeoutError) =>
1384
+ * Effect.logWarning(`${err.operation} timed out after ${err.duration}ms: ${err.message}`),
1385
+ * ),
1386
+ * );
1387
+ *
1388
+ * await Effect.runPromise(Effect.provide(program, NodeLayer));
1389
+ * ```
1390
+ *
1391
+ * @public
1392
+ */
1393
+ export declare class TimeoutError extends TimeoutErrorBase<{
1394
+ readonly operation: string;
1395
+ readonly duration: number;
1396
+ readonly message: string;
1397
+ }> {
1398
+ }
1399
+
1400
+ /**
1401
+ * @internal
1402
+ * Exported for declaration bundling (api-extractor). When `export *` re-exports
1403
+ * a class whose `extends` expression is an inline call like
1404
+ * `Data.TaggedError(...)`, TypeScript emits an un-nameable `_base` symbol in
1405
+ * the declaration file. Splitting the base into a named export gives the
1406
+ * bundler a stable reference.
1407
+ *
1408
+ * @privateRemarks
1409
+ * This base constant must remain a named export so that api-extractor can
1410
+ * resolve the extends clause of {@link TimeoutError} to a stable
1411
+ * declaration. Without it the bundled `.d.ts` would contain an anonymous
1412
+ * `_base` symbol that cannot be referenced by downstream consumers.
1413
+ */
1414
+ export declare const TimeoutErrorBase: new <A extends Record<string, any> = {}>(args: Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => YieldableError & {
1415
+ readonly _tag: "TimeoutError";
1416
+ } & Readonly<A>;
1417
+
1418
+ export declare namespace TypeRegistry {
1419
+ export {
1420
+ hasCached,
1421
+ fetchAndCache,
1422
+ getPackageVFS,
1423
+ getVFS,
1424
+ resolveImport,
1425
+ getTypeEntries,
1426
+ resolveVersion,
1427
+ clearCache
1428
+ }
1429
+ }
1430
+
1431
+ /**
1432
+ * Union of all error types that can be raised by the type-registry-effect package.
1433
+ *
1434
+ * @remarks
1435
+ * `TypeRegistryError` is a discriminated union over the `_tag` field. Each
1436
+ * variant corresponds to a specific failure mode:
1437
+ *
1438
+ * - `"CacheError"` -- disk cache operations
1439
+ * - `"NetworkError"` -- HTTP requests to the CDN
1440
+ * - `"PackageNotFoundError"` -- missing packages or versions
1441
+ * - `"ParseError"` -- schema validation / JSON parsing
1442
+ * - `"ResolutionError"` -- import specifier resolution
1443
+ * - `"TimeoutError"` -- operation time limits
1444
+ *
1445
+ * Use `Effect.catchTags` to exhaustively handle all variants, or
1446
+ * `Effect.catchTag` for selective handling of individual error types.
1447
+ *
1448
+ * @public
1449
+ */
1450
+ export declare type TypeRegistryError = CacheError | NetworkError | PackageNotFoundError | ParseError | ResolutionError | TimeoutError;
1451
+
1452
+ /**
1453
+ * Composed layer providing {@link CacheService}, {@link PackageFetcher}, and
1454
+ * {@link TypeResolver} as a single unified layer.
1455
+ *
1456
+ * @remarks
1457
+ * This layer merges {@link CacheServiceLive}, {@link PackageFetcherLive}, and
1458
+ * {@link TypeResolverLive}. It still requires platform-specific
1459
+ * {@link @effect/platform#FileSystem | FileSystem} and
1460
+ * {@link @effect/platform#HttpClient | HttpClient} layers to be provided.
1461
+ * Use the Node.js platform layers to satisfy these requirements:
1462
+ *
1463
+ * @example
1464
+ * ```typescript
1465
+ * import { NodeFileSystem, NodeHttpClient } from "@effect/platform-node";
1466
+ * import { Effect, Layer } from "effect";
1467
+ * import { TypeRegistryLive } from "type-registry-effect";
1468
+ *
1469
+ * const NodeLayer = Layer.mergeAll(NodeFileSystem.layer, NodeHttpClient.layer);
1470
+ * const MainLayer = Layer.provide(TypeRegistryLive, NodeLayer);
1471
+ *
1472
+ * const program = Effect.gen(function* () {
1473
+ * // All three services are now available
1474
+ * console.log("registry ready");
1475
+ * });
1476
+ *
1477
+ * Effect.runPromise(Effect.provide(program, MainLayer));
1478
+ * ```
1479
+ *
1480
+ * @see {@link CacheServiceLive}
1481
+ * @see {@link PackageFetcherLive}
1482
+ * @see {@link TypeResolverLive}
1483
+ *
1484
+ * @public
1485
+ */
1486
+ export declare const TypeRegistryLive: Layer.Layer<CacheService | PackageFetcher | TypeResolver, never, FileSystem.FileSystem | HttpClient.HttpClient>;
1487
+
1488
+ /**
1489
+ * Effect service interface for import resolution using `package.json` metadata.
1490
+ *
1491
+ * @remarks
1492
+ * Resolution is attempted in the following order:
1493
+ *
1494
+ * 1. **`exports`** -- the `"types"` condition inside the package's exports map.
1495
+ * 2. **`typesVersions`** -- the `"*"` entry of `typesVersions` with wildcard
1496
+ * matching.
1497
+ * 3. **`types` / `typings`** -- top-level fields pointing at the main
1498
+ * declaration file.
1499
+ * 4. **Conventional** -- extension swapping (`.js` to `.d.ts`) and
1500
+ * `index.d.ts` fallback.
1501
+ *
1502
+ * @example
1503
+ * ```typescript
1504
+ * import { Effect } from "effect";
1505
+ * import { TypeResolver } from "type-registry-effect";
1506
+ * import type { PackageJson } from "type-registry-effect";
1507
+ * import type { PackageSpec } from "type-registry-effect";
1508
+ *
1509
+ * const program = Effect.gen(function* () {
1510
+ * const resolver = yield* TypeResolver;
1511
+ * const resolved = yield* resolver.resolveMainEntry(
1512
+ * { name: "lodash", version: "4.17.21" } as unknown as PackageJson,
1513
+ * { name: "lodash", version: "4.17.21" } as PackageSpec,
1514
+ * );
1515
+ * console.log("main types:", resolved.filePath);
1516
+ * });
1517
+ * ```
1518
+ *
1519
+ * @see {@link TypeResolverLive}
1520
+ *
1521
+ * @public
1522
+ */
1523
+ export declare interface TypeResolver {
1524
+ /**
1525
+ * Resolve a bare or deep-import specifier to a type definition path within
1526
+ * the package.
1527
+ */
1528
+ readonly resolveImport: (specifier: string, packageJson: PackageJson, pkg: PackageSpec) => Effect.Effect<ResolvedModule, ResolutionError>;
1529
+ /**
1530
+ * Resolve the main (root `"."`) type entry point for a package.
1531
+ */
1532
+ readonly resolveMainEntry: (packageJson: PackageJson, pkg: PackageSpec) => Effect.Effect<ResolvedModule, ResolutionError>;
1533
+ /**
1534
+ * Collect all type entry points declared by the package, including the main
1535
+ * entry and any additional sub-path exports that expose types.
1536
+ */
1537
+ readonly resolveTypeEntries: (packageJson: PackageJson, pkg: PackageSpec) => Effect.Effect<ReadonlyArray<ResolvedModule>, ResolutionError>;
1538
+ /**
1539
+ * Given a JavaScript file path, derive the corresponding `.d.ts` / `.d.mts`
1540
+ * / `.d.cts` path. Returns `null` when no type definition can be inferred.
1541
+ */
1542
+ readonly findTypeDefinition: (jsFilePath: string, packageJson: PackageJson, pkg: PackageSpec) => Effect.Effect<ResolvedModule | null, ResolutionError>;
1543
+ }
1544
+
1545
+ /**
1546
+ * Effect Context tag for the {@link TypeResolver} service.
1547
+ *
1548
+ * @see {@link TypeResolverLive}
1549
+ */
1550
+ export declare const TypeResolver: Context.Tag<TypeResolver, TypeResolver>;
1551
+
1552
+ /**
1553
+ * Pure {@link TypeResolver} layer with no external dependencies.
1554
+ *
1555
+ * @remarks
1556
+ * Resolution is performed synchronously using only the data present in the
1557
+ * supplied `package.json`. The resolution order is:
1558
+ *
1559
+ * 1. `exports` map (`"types"` condition, then `"import"` / `"default"`)
1560
+ * 2. `typesVersions["*"]` with wildcard pattern matching
1561
+ * 3. Top-level `types` or `typings` fields
1562
+ * 4. Conventional extension swapping (`.js` to `.d.ts`) and `index.d.ts`
1563
+ * fallback
1564
+ *
1565
+ * @see {@link TypeResolver}
1566
+ *
1567
+ * @public
1568
+ */
1569
+ export declare const TypeResolverLive: Layer.Layer<TypeResolver>;
1570
+
1571
+ /**
1572
+ * A `Map<string, string>` that maps virtual file paths to their contents.
1573
+ *
1574
+ * @remarks
1575
+ * Keys are prefixed with `node_modules/` so the map can be fed directly into
1576
+ * an in-memory TypeScript compiler host. Values are the UTF-8 file contents
1577
+ * (typically `.d.ts` declarations).
1578
+ *
1579
+ * @example
1580
+ * ```typescript
1581
+ * import type { VirtualFileSystem } from "type-registry-effect";
1582
+ *
1583
+ * const vfs: VirtualFileSystem = new Map([
1584
+ * ["node_modules/lodash/index.d.ts", "declare module 'lodash' { ... }"],
1585
+ * ]);
1586
+ * ```
1587
+ *
1588
+ * @see {@link CacheService}
1589
+ *
1590
+ * @public
1591
+ */
1592
+ export declare type VirtualFileSystem = Map<string, string>;
1593
+
1594
+ export declare namespace VirtualPackage {
1595
+ export {
1596
+ VirtualPackage_2 as VirtualPackage
1597
+ }
1598
+ }
1599
+
1600
+ /**
1601
+ * Creates virtual npm packages from TypeScript declaration content for
1602
+ * inclusion in a {@link VirtualFileSystem} without fetching from the CDN.
1603
+ *
1604
+ * @remarks
1605
+ * `VirtualPackage` is useful when you have locally-generated `.d.ts` files —
1606
+ * for example, output from API Extractor, hand-written ambient declarations, or
1607
+ * declaration files bundled alongside your own packages — and want to inject
1608
+ * them into the same VFS that TypeRegistry builds from remote packages.
1609
+ *
1610
+ * Instances are **transient**: they are not persisted to the disk cache and
1611
+ * live only as long as the VFS they produce. Call {@link VirtualPackage.generateVfs}
1612
+ * to obtain a VFS that can be merged with other VFS maps.
1613
+ *
1614
+ * @see {@link VirtualFileSystem} for the VFS type consumed by TypeScript tooling
1615
+ *
1616
+ * @public
1617
+ */
1618
+ declare class VirtualPackage_2 {
1619
+ readonly name: string;
1620
+ readonly version: string;
1621
+ private readonly entries;
1622
+ constructor(name: string, version: string, entries: Map<string, string>);
1623
+ /**
1624
+ * Single-entry convenience factory.
1625
+ *
1626
+ * Creates a virtual package whose sole entry point is `index.d.ts`.
1627
+ *
1628
+ * @param name - Package name (e.g. `"@my-org/api-types"`).
1629
+ * @param version - Semver version string (e.g. `"1.0.0"`).
1630
+ * @param declarations - The full TypeScript declaration source for `index.d.ts`.
1631
+ * @returns A new {@link VirtualPackage} instance.
1632
+ *
1633
+ * @example
1634
+ * ```typescript
1635
+ * import type { VirtualFileSystem } from "type-registry-effect";
1636
+ * import { VirtualPackage } from "type-registry-effect";
1637
+ *
1638
+ * const declarations = `
1639
+ * export interface User {
1640
+ * id: string;
1641
+ * name: string;
1642
+ * }
1643
+ * `;
1644
+ *
1645
+ * const pkg = VirtualPackage.create("@my-org/api-types", "1.0.0", declarations);
1646
+ * const vfs: VirtualFileSystem = pkg.generateVfs();
1647
+ * console.log([...vfs.keys()]);
1648
+ * // ["node_modules/@my-org/api-types/package.json",
1649
+ * // "node_modules/@my-org/api-types/index.d.ts"]
1650
+ * ```
1651
+ *
1652
+ * @public
1653
+ */
1654
+ static create(name: string, version: string, declarations: string): VirtualPackage_2;
1655
+ /**
1656
+ * Multi-entry factory.
1657
+ *
1658
+ * Creates a virtual package with multiple `.d.ts` entry point files,
1659
+ * producing a `package.json` that uses the `exports` map.
1660
+ *
1661
+ * @param name - Package name.
1662
+ * @param version - Semver version string.
1663
+ * @param entries - Map of file names (e.g. `"index.d.ts"`, `"testing.d.ts"`)
1664
+ * to their declaration source content.
1665
+ * @returns A new {@link VirtualPackage} instance.
1666
+ *
1667
+ * @example
1668
+ * ```typescript
1669
+ * import type { VirtualFileSystem } from "type-registry-effect";
1670
+ * import { VirtualPackage } from "type-registry-effect";
1671
+ *
1672
+ * const entries = new Map<string, string>([
1673
+ * ["index.d.ts", "export declare function run(): void;"],
1674
+ * ["testing.d.ts", "export declare function mock(): void;"],
1675
+ * ]);
1676
+ *
1677
+ * const pkg = VirtualPackage.createMultiEntry("@my-org/sdk", "2.0.0", entries);
1678
+ * const vfs: VirtualFileSystem = pkg.generateVfs();
1679
+ * console.log([...vfs.keys()]);
1680
+ * // ["node_modules/@my-org/sdk/package.json",
1681
+ * // "node_modules/@my-org/sdk/index.d.ts",
1682
+ * // "node_modules/@my-org/sdk/testing.d.ts"]
1683
+ * ```
1684
+ *
1685
+ * @public
1686
+ */
1687
+ static createMultiEntry(name: string, version: string, entries: Map<string, string>): VirtualPackage_2;
1688
+ /**
1689
+ * Load a single `.d.ts` file from disk and create a virtual package from it.
1690
+ *
1691
+ * @remarks
1692
+ * Reads the file synchronously with `node:fs`. The resulting package has a
1693
+ * single `index.d.ts` entry whose content matches the file on disk.
1694
+ *
1695
+ * @param name - Package name.
1696
+ * @param version - Semver version string.
1697
+ * @param filePath - Absolute or relative path to a `.d.ts` file.
1698
+ * @returns A new {@link VirtualPackage} instance.
1699
+ *
1700
+ * @example
1701
+ * ```typescript
1702
+ * import type { VirtualFileSystem } from "type-registry-effect";
1703
+ * import { VirtualPackage } from "type-registry-effect";
1704
+ *
1705
+ * const pkg = VirtualPackage.fromFile(
1706
+ * "@my-org/api-types",
1707
+ * "1.0.0",
1708
+ * "./dist/api-types.d.ts",
1709
+ * );
1710
+ * const vfs: VirtualFileSystem = pkg.generateVfs();
1711
+ * ```
1712
+ *
1713
+ * @public
1714
+ */
1715
+ static fromFile(name: string, version: string, filePath: string): VirtualPackage_2;
1716
+ /**
1717
+ * Generate the full {@link VirtualFileSystem}: a synthetic `package.json`
1718
+ * plus all entry `.d.ts` files, with every path prefixed by
1719
+ * `node_modules/<name>/`.
1720
+ *
1721
+ * @returns A {@link VirtualFileSystem} map ready to be merged with other VFS maps.
1722
+ *
1723
+ * @example
1724
+ * ```typescript
1725
+ * import type { VirtualFileSystem } from "type-registry-effect";
1726
+ * import { VirtualPackage } from "type-registry-effect";
1727
+ *
1728
+ * const pkg = VirtualPackage.create("my-types", "1.0.0", "export type Foo = string;");
1729
+ * const vfs: VirtualFileSystem = pkg.generateVfs();
1730
+ *
1731
+ * for (const [path, content] of vfs) {
1732
+ * console.log(`${path} (${content.length} chars)`);
1733
+ * }
1734
+ * ```
1735
+ *
1736
+ * @public
1737
+ */
1738
+ generateVfs(): VirtualFileSystem;
1739
+ /**
1740
+ * Generate synthetic `package.json` content for the virtual package.
1741
+ *
1742
+ * @remarks
1743
+ * Uses the `types` field for single-entry packages and the `exports` map
1744
+ * for multi-entry packages so that TypeScript module resolution works
1745
+ * correctly against the generated VFS.
1746
+ *
1747
+ * @returns The `package.json` content as a JSON string.
1748
+ *
1749
+ * @internal
1750
+ */
1751
+ private generatePackageJson;
1752
+ }
1753
+
1754
+ export { }