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/821.js ADDED
@@ -0,0 +1,628 @@
1
+ import { __webpack_require__ } from "./rslib-runtime.js";
2
+ import { Context, Data, Duration, Effect, Layer, Schedule, Schema } from "effect";
3
+ import { dirname, isAbsolute, join, relative } from "node:path";
4
+ import { FileSystem, HttpClient } from "@effect/platform";
5
+ import { homedir as external_node_os_homedir } from "node:os";
6
+ var TypeRegistry_namespaceObject = {};
7
+ __webpack_require__.r(TypeRegistry_namespaceObject);
8
+ __webpack_require__.d(TypeRegistry_namespaceObject, {
9
+ clearCache: ()=>clearCache,
10
+ fetchAndCache: ()=>fetchAndCache,
11
+ getPackageVFS: ()=>getPackageVFS,
12
+ getTypeEntries: ()=>getTypeEntries,
13
+ getVFS: ()=>getVFS,
14
+ hasCached: ()=>hasCached,
15
+ resolveImport: ()=>resolveImport,
16
+ resolveVersion: ()=>resolveVersion
17
+ });
18
+ const PackageNotFoundErrorBase = Data.TaggedError("PackageNotFoundError");
19
+ class PackageNotFoundError extends PackageNotFoundErrorBase {
20
+ }
21
+ const ParseErrorBase = Data.TaggedError("ParseError");
22
+ class ParseError extends ParseErrorBase {
23
+ }
24
+ const CacheService = Context.GenericTag("type-registry-effect/CacheService");
25
+ const PackageFetcher = Context.GenericTag("type-registry-effect/PackageFetcher");
26
+ const JSDELIVR_DATA_API = "https://data.jsdelivr.com/v1";
27
+ const JSDELIVR_CDN = "https://cdn.jsdelivr.net";
28
+ const TYPE_FILE_PATTERN = /\.d\.([^.]+\.)?[cm]?ts$/i;
29
+ new Set([
30
+ "assert",
31
+ "async_hooks",
32
+ "buffer",
33
+ "child_process",
34
+ "cluster",
35
+ "console",
36
+ "constants",
37
+ "crypto",
38
+ "dgram",
39
+ "diagnostics_channel",
40
+ "dns",
41
+ "domain",
42
+ "events",
43
+ "fs",
44
+ "http",
45
+ "http2",
46
+ "https",
47
+ "inspector",
48
+ "module",
49
+ "net",
50
+ "os",
51
+ "path",
52
+ "perf_hooks",
53
+ "process",
54
+ "punycode",
55
+ "querystring",
56
+ "readline",
57
+ "repl",
58
+ "stream",
59
+ "string_decoder",
60
+ "timers",
61
+ "tls",
62
+ "trace_events",
63
+ "tty",
64
+ "url",
65
+ "util",
66
+ "v8",
67
+ "vm",
68
+ "wasi",
69
+ "worker_threads",
70
+ "zlib",
71
+ "fs/promises",
72
+ "stream/web",
73
+ "stream/consumers",
74
+ "timers/promises",
75
+ "dns/promises"
76
+ ]);
77
+ const TypeResolver = Context.GenericTag("type-registry-effect/TypeResolver");
78
+ const hasCached = (pkg)=>Effect.gen(function*() {
79
+ const cache = yield* CacheService;
80
+ return yield* cache.exists(pkg);
81
+ });
82
+ const fetchAndCache = (pkg, options)=>Effect.gen(function*() {
83
+ const cache = yield* CacheService;
84
+ const fetcher = yield* PackageFetcher;
85
+ const packageJson = yield* fetcher.getPackageJson(pkg);
86
+ const typeFiles = yield* fetcher.getTypeFiles(pkg);
87
+ yield* cache.write(pkg, "package.json", JSON.stringify(packageJson, null, 2));
88
+ for (const [filePath, content] of typeFiles){
89
+ const normalizedPath = filePath.replace(/^\//, "");
90
+ if ("package.json" !== normalizedPath) yield* cache.write(pkg, normalizedPath, content);
91
+ }
92
+ const metadata = {
93
+ cachedAt: Date.now(),
94
+ version: pkg.version,
95
+ ...options?.ttl !== void 0 ? {
96
+ ttl: options.ttl
97
+ } : {}
98
+ };
99
+ yield* cache.writeMetadata(pkg, metadata);
100
+ });
101
+ const getPackageVFS = (pkg, options)=>Effect.gen(function*() {
102
+ const cache = yield* CacheService;
103
+ const autoFetch = options?.autoFetch ?? true;
104
+ const exists = yield* cache.exists(pkg);
105
+ if (!exists && autoFetch) yield* fetchAndCache(pkg, options);
106
+ else if (exists || autoFetch) {
107
+ if (exists && autoFetch) {
108
+ const isStale = yield* cache.readMetadata(pkg).pipe(Effect.map((meta)=>{
109
+ if (void 0 === meta.ttl) return false;
110
+ return meta.cachedAt + meta.ttl < Date.now();
111
+ }), Effect.catchAll(()=>Effect.succeed(false)));
112
+ if (isStale) yield* fetchAndCache(pkg, options);
113
+ }
114
+ } else yield* Effect.fail(new PackageNotFoundError({
115
+ name: pkg.name,
116
+ version: pkg.version,
117
+ message: `Package ${pkg.toString()} is not cached and autoFetch is disabled`
118
+ }));
119
+ return yield* cache.getVFS(pkg);
120
+ });
121
+ const getVFS = (packages, options)=>Effect.gen(function*() {
122
+ const results = yield* Effect.forEach(packages, (pkg)=>getPackageVFS(pkg, options).pipe(Effect.map((vfs)=>({
123
+ _tag: "ok",
124
+ vfs
125
+ })), Effect.catchAll((error)=>Effect.succeed({
126
+ _tag: "err",
127
+ pkg,
128
+ error
129
+ }))), {
130
+ concurrency: 5
131
+ });
132
+ const merged = new Map();
133
+ const errors = [];
134
+ for (const result of results)if ("ok" === result._tag) for (const [path, content] of result.vfs)merged.set(path, content);
135
+ else errors.push({
136
+ pkg: result.pkg,
137
+ error: result.error
138
+ });
139
+ if (errors.length === packages.length && packages.length > 0) yield* Effect.fail(new PackageNotFoundError({
140
+ name: errors.map((e)=>e.pkg.name).join(", "),
141
+ version: "",
142
+ message: `Failed to fetch VFS for all packages:\n${errors.map((e)=>`- ${e.pkg.toString()}: ${String(e.error)}`).join("\n")}`
143
+ }));
144
+ return merged;
145
+ });
146
+ const resolveImport = (pkg, specifier)=>Effect.gen(function*() {
147
+ const cache = yield* CacheService;
148
+ const resolver = yield* TypeResolver;
149
+ const packageJsonContent = yield* cache.read(pkg, "package.json");
150
+ const packageJson = yield* Effect["try"]({
151
+ try: ()=>JSON.parse(packageJsonContent),
152
+ catch: (error)=>new ParseError({
153
+ source: "package.json",
154
+ message: String(error)
155
+ })
156
+ });
157
+ return yield* resolver.resolveImport(specifier, packageJson, pkg);
158
+ });
159
+ const getTypeEntries = (pkg)=>Effect.gen(function*() {
160
+ const cache = yield* CacheService;
161
+ const resolver = yield* TypeResolver;
162
+ const packageJsonContent = yield* cache.read(pkg, "package.json");
163
+ const packageJson = yield* Effect["try"]({
164
+ try: ()=>JSON.parse(packageJsonContent),
165
+ catch: (error)=>new ParseError({
166
+ source: "package.json",
167
+ message: String(error)
168
+ })
169
+ });
170
+ return yield* resolver.resolveTypeEntries(packageJson, pkg);
171
+ });
172
+ const resolveVersion = (name, ref)=>Effect.gen(function*() {
173
+ const fetcher = yield* PackageFetcher;
174
+ return yield* fetcher.resolveVersion(name, ref);
175
+ });
176
+ const clearCache = (pkg)=>Effect.gen(function*() {
177
+ const cache = yield* CacheService;
178
+ yield* cache.remove(pkg);
179
+ });
180
+ const CacheMetadata = Schema.Struct({
181
+ version: Schema.String,
182
+ cachedAt: Schema.Number,
183
+ ttl: Schema.optional(Schema.Number)
184
+ });
185
+ const FileTreeEntry = Schema.Struct({
186
+ name: Schema.String,
187
+ hash: Schema.String,
188
+ time: Schema.String,
189
+ size: Schema.Number
190
+ });
191
+ const FileTreeResponse = Schema.Struct({
192
+ default: Schema.String,
193
+ files: Schema.Array(FileTreeEntry)
194
+ });
195
+ const PackageJson = Schema.Struct({
196
+ name: Schema.String,
197
+ version: Schema.String,
198
+ types: Schema.optional(Schema.String),
199
+ typings: Schema.optional(Schema.String),
200
+ main: Schema.optional(Schema.String),
201
+ module: Schema.optional(Schema.String),
202
+ exports: Schema.optional(Schema.Union(Schema.String, Schema.Record({
203
+ key: Schema.String,
204
+ value: Schema.Unknown
205
+ }))),
206
+ typesVersions: Schema.optional(Schema.Record({
207
+ key: Schema.String,
208
+ value: Schema.Record({
209
+ key: Schema.String,
210
+ value: Schema.Array(Schema.String)
211
+ })
212
+ })),
213
+ dependencies: Schema.optional(Schema.Record({
214
+ key: Schema.String,
215
+ value: Schema.String
216
+ })),
217
+ peerDependencies: Schema.optional(Schema.Record({
218
+ key: Schema.String,
219
+ value: Schema.String
220
+ })),
221
+ devDependencies: Schema.optional(Schema.Record({
222
+ key: Schema.String,
223
+ value: Schema.String
224
+ }))
225
+ });
226
+ var _computedKey;
227
+ const PackageSpecBase = Data.TaggedClass("PackageSpec");
228
+ _computedKey = Symbol.for("nodejs.util.inspect.custom");
229
+ class PackageSpec extends PackageSpecBase {
230
+ toString() {
231
+ return `${this.name}@${this.version}`;
232
+ }
233
+ [_computedKey]() {
234
+ return this.toString();
235
+ }
236
+ }
237
+ const ResolvedModuleBase = Data.TaggedClass("ResolvedModule");
238
+ class ResolvedModule extends ResolvedModuleBase {
239
+ }
240
+ const CacheErrorBase = Data.TaggedError("CacheError");
241
+ class CacheError extends CacheErrorBase {
242
+ }
243
+ const NetworkErrorBase = Data.TaggedError("NetworkError");
244
+ class NetworkError extends NetworkErrorBase {
245
+ }
246
+ const ResolutionErrorBase = Data.TaggedError("ResolutionError");
247
+ class ResolutionError extends ResolutionErrorBase {
248
+ }
249
+ const TimeoutErrorBase = Data.TaggedError("TimeoutError");
250
+ class TimeoutError extends TimeoutErrorBase {
251
+ }
252
+ function getXdgCacheHome() {
253
+ const xdgCacheHome = process.env.XDG_CACHE_HOME;
254
+ if (xdgCacheHome && isAbsolute(xdgCacheHome)) return xdgCacheHome;
255
+ return join(external_node_os_homedir(), ".cache");
256
+ }
257
+ function getDefaultCacheDir() {
258
+ return join(getXdgCacheHome(), "effect-type-registry");
259
+ }
260
+ const pkgDir = (baseDir, pkg)=>join(baseDir, pkg.toString());
261
+ const mapToCacheError = (operation, path)=>(error)=>new CacheError({
262
+ operation,
263
+ path,
264
+ message: String(error)
265
+ });
266
+ const makeNodeCacheLayer = (baseDir)=>Layer.effect(CacheService, Effect.gen(function*() {
267
+ const fs = yield* FileSystem.FileSystem;
268
+ const cacheDir = baseDir ?? getDefaultCacheDir();
269
+ const listRecursive = (dir, relativeTo)=>Effect.gen(function*() {
270
+ const entries = yield* fs.readDirectory(dir).pipe(Effect.mapError(mapToCacheError("list", dir)));
271
+ const files = [];
272
+ for (const entry of entries){
273
+ const fullPath = join(dir, entry);
274
+ const stat = yield* fs.stat(fullPath).pipe(Effect.mapError(mapToCacheError("list", fullPath)));
275
+ if ("Directory" === stat.type) files.push(...yield* listRecursive(fullPath, relativeTo));
276
+ else files.push(relative(relativeTo, fullPath));
277
+ }
278
+ return files;
279
+ });
280
+ return {
281
+ exists: (pkg)=>fs.exists(pkgDir(cacheDir, pkg)).pipe(Effect.catchAll(()=>Effect.succeed(false))),
282
+ read: (pkg, filePath)=>{
283
+ const fullPath = join(pkgDir(cacheDir, pkg), filePath);
284
+ return fs.readFileString(fullPath).pipe(Effect.mapError(mapToCacheError("read", fullPath)));
285
+ },
286
+ write: (pkg, filePath, content)=>{
287
+ const fullPath = join(pkgDir(cacheDir, pkg), filePath);
288
+ const dirPath = dirname(fullPath);
289
+ return Effect.gen(function*() {
290
+ yield* fs.makeDirectory(dirPath, {
291
+ recursive: true
292
+ }).pipe(Effect.mapError(mapToCacheError("write", dirPath)));
293
+ yield* fs.writeFileString(fullPath, content).pipe(Effect.mapError(mapToCacheError("write", fullPath)));
294
+ });
295
+ },
296
+ listFiles: (pkg)=>{
297
+ const cachePath = pkgDir(cacheDir, pkg);
298
+ return listRecursive(cachePath, cachePath);
299
+ },
300
+ readMetadata: (pkg)=>{
301
+ const metaPath = join(pkgDir(cacheDir, pkg), ".metadata.json");
302
+ return fs.readFileString(metaPath).pipe(Effect.mapError(mapToCacheError("read", metaPath)), Effect.flatMap((content)=>Effect["try"]({
303
+ try: ()=>JSON.parse(content),
304
+ catch: mapToCacheError("read", metaPath)
305
+ })), Effect.flatMap((parsed)=>Schema.decodeUnknown(CacheMetadata)(parsed).pipe(Effect.mapError(mapToCacheError("read", metaPath)))));
306
+ },
307
+ writeMetadata: (pkg, metadata)=>{
308
+ const metaPath = join(pkgDir(cacheDir, pkg), ".metadata.json");
309
+ const dirPath = dirname(metaPath);
310
+ return Effect.gen(function*() {
311
+ yield* fs.makeDirectory(dirPath, {
312
+ recursive: true
313
+ }).pipe(Effect.mapError(mapToCacheError("write", dirPath)));
314
+ const encoded = Schema.encodeSync(CacheMetadata)(metadata);
315
+ yield* fs.writeFileString(metaPath, JSON.stringify(encoded, null, 2)).pipe(Effect.mapError(mapToCacheError("write", metaPath)));
316
+ });
317
+ },
318
+ getVFS: (pkg)=>Effect.gen(function*() {
319
+ const cachePath = pkgDir(cacheDir, pkg);
320
+ const files = yield* listRecursive(cachePath, cachePath);
321
+ const vfs = new Map();
322
+ for (const file of files){
323
+ if (".metadata.json" === file) continue;
324
+ const fullPath = join(cachePath, file);
325
+ const content = yield* fs.readFileString(fullPath).pipe(Effect.mapError(mapToCacheError("read", fullPath)));
326
+ const vfsPath = `node_modules/${pkg.name}/${file.replace(/\\/g, "/")}`;
327
+ vfs.set(vfsPath, content);
328
+ }
329
+ return vfs;
330
+ }),
331
+ remove: (pkg)=>{
332
+ const cachePath = pkgDir(cacheDir, pkg);
333
+ return fs.remove(cachePath, {
334
+ recursive: true
335
+ }).pipe(Effect.mapError(mapToCacheError("delete", cachePath)));
336
+ }
337
+ };
338
+ }));
339
+ const CacheServiceLive = makeNodeCacheLayer();
340
+ const PackageMetadataSchema = Schema.Struct({
341
+ versions: Schema.mutable(Schema.Array(Schema.String)),
342
+ tags: Schema.mutable(Schema.Record({
343
+ key: Schema.String,
344
+ value: Schema.String
345
+ }))
346
+ });
347
+ const ResolveResponseSchema = Schema.Struct({
348
+ version: Schema.String
349
+ });
350
+ const retrySchedule = Schedule.exponential(Duration.millis(100)).pipe(Schedule.compose(Schedule.recurs(3)));
351
+ const defaultTimeout = Duration.seconds(30);
352
+ const PackageFetcherLive = Layer.effect(PackageFetcher, Effect.gen(function*() {
353
+ const http = yield* HttpClient.HttpClient;
354
+ const fetchJson = (url)=>http.get(url).pipe(Effect.flatMap((res)=>res.json), Effect.timeout(defaultTimeout), Effect.retry(retrySchedule), Effect.mapError((error)=>new NetworkError({
355
+ url,
356
+ message: String(error)
357
+ })));
358
+ const fetchText = (url)=>http.get(url).pipe(Effect.flatMap((res)=>res.text), Effect.timeout(defaultTimeout), Effect.retry(retrySchedule), Effect.mapError((error)=>new NetworkError({
359
+ url,
360
+ message: String(error)
361
+ })));
362
+ const getFileTree = (pkg)=>fetchJson(`${JSDELIVR_DATA_API}/package/npm/${pkg.name}@${pkg.version}/flat`).pipe(Effect.flatMap((data)=>Schema.decodeUnknown(FileTreeResponse)(data).pipe(Effect.mapError((e)=>new ParseError({
363
+ source: `${pkg.name}@${pkg.version}/flat`,
364
+ message: `Schema validation failed: ${String(e)}`
365
+ })))));
366
+ return {
367
+ getVersions: (name)=>fetchJson(`${JSDELIVR_DATA_API}/package/npm/${name}`).pipe(Effect.flatMap((data)=>Schema.decodeUnknown(PackageMetadataSchema)(data).pipe(Effect.mapError((e)=>new ParseError({
368
+ source: `${name}/versions`,
369
+ message: `Schema validation failed: ${String(e)}`
370
+ }))))),
371
+ resolveVersion: (name, ref)=>fetchJson(`${JSDELIVR_DATA_API}/package/resolve/npm/${name}@${ref}`).pipe(Effect.flatMap((data)=>Schema.decodeUnknown(ResolveResponseSchema)(data).pipe(Effect.mapError((e)=>new ParseError({
372
+ source: `resolve/${name}@${ref}`,
373
+ message: `Invalid response: ${String(e)}`
374
+ })))), Effect.map((data)=>data.version), Effect.catchTags({
375
+ ParseError: (e)=>Effect.fail(new PackageNotFoundError({
376
+ name,
377
+ version: ref,
378
+ message: e.message
379
+ })),
380
+ NetworkError: (e)=>e.message.includes("404") ? Effect.fail(new PackageNotFoundError({
381
+ name,
382
+ version: ref,
383
+ message: e.message
384
+ })) : Effect.fail(e)
385
+ })),
386
+ getFileTree,
387
+ downloadFile: (pkg, filePath)=>{
388
+ const normalizedPath = filePath.startsWith("/") ? filePath : `/${filePath}`;
389
+ return fetchText(`${JSDELIVR_CDN}/npm/${pkg.name}@${pkg.version}${normalizedPath}`);
390
+ },
391
+ getPackageJson: (pkg)=>fetchText(`${JSDELIVR_CDN}/npm/${pkg.name}@${pkg.version}/package.json`).pipe(Effect.flatMap((content)=>Effect["try"]({
392
+ try: ()=>JSON.parse(content),
393
+ catch: (e)=>new ParseError({
394
+ source: `${pkg.name}@${pkg.version}/package.json`,
395
+ message: `JSON parse failed: ${String(e)}`
396
+ })
397
+ })), Effect.flatMap((parsed)=>Schema.decodeUnknown(PackageJson)(parsed).pipe(Effect.mapError((e)=>new ParseError({
398
+ source: `${pkg.name}@${pkg.version}/package.json`,
399
+ message: `Schema validation failed: ${String(e)}`
400
+ }))))),
401
+ getTypeFiles: (pkg)=>Effect.gen(function*() {
402
+ const fileTree = yield* getFileTree(pkg);
403
+ const typeFiles = fileTree.files.filter((f)=>TYPE_FILE_PATTERN.test(f.name));
404
+ const entries = yield* Effect.forEach(typeFiles, (file)=>{
405
+ const normalizedPath = file.name.startsWith("/") ? file.name : `/${file.name}`;
406
+ return fetchText(`${JSDELIVR_CDN}/npm/${pkg.name}@${pkg.version}${normalizedPath}`).pipe(Effect.map((content)=>[
407
+ file.name,
408
+ content
409
+ ]));
410
+ }, {
411
+ concurrency: 10
412
+ });
413
+ const vfs = new Map(entries);
414
+ const hasPackageJson = fileTree.files.some((f)=>"/package.json" === f.name);
415
+ if (!hasPackageJson) {
416
+ const pkgContent = yield* fetchText(`${JSDELIVR_CDN}/npm/${pkg.name}@${pkg.version}/package.json`);
417
+ vfs.set("/package.json", pkgContent);
418
+ }
419
+ return vfs;
420
+ })
421
+ };
422
+ }));
423
+ function isTypeDefinition(filePath) {
424
+ return filePath.endsWith(".d.ts") || filePath.endsWith(".d.mts") || filePath.endsWith(".d.cts");
425
+ }
426
+ function normalizePath(path) {
427
+ return path.replace(/\\/g, "/");
428
+ }
429
+ function escapeRegex(str) {
430
+ return str.replace(/[.+^${}()|[\]\\]/g, "\\$&");
431
+ }
432
+ function substituteWildcard(value, captured) {
433
+ if ("string" == typeof value) return value.replace(/\*/g, captured);
434
+ if ("object" == typeof value && null !== value) {
435
+ const result = {};
436
+ for (const [k, v] of Object.entries(value))if ("string" == typeof v) result[k] = v.replace(/\*/g, captured);
437
+ else if ("object" == typeof v && null !== v) result[k] = substituteWildcard(v, captured);
438
+ else result[k] = v;
439
+ return result;
440
+ }
441
+ return value;
442
+ }
443
+ function tryExtensions(basePath) {
444
+ return [
445
+ basePath,
446
+ `${basePath}.d.ts`,
447
+ `${basePath}.d.mts`,
448
+ `${basePath}.d.cts`,
449
+ `${basePath}.ts`,
450
+ `${basePath}.mts`,
451
+ `${basePath}.cts`,
452
+ `${basePath}.js`,
453
+ `${basePath}.mjs`,
454
+ `${basePath}.cjs`,
455
+ `${basePath}/index.d.ts`,
456
+ `${basePath}/index.d.mts`,
457
+ `${basePath}/index.d.cts`,
458
+ `${basePath}/index.ts`,
459
+ `${basePath}/index.js`
460
+ ].map(normalizePath);
461
+ }
462
+ function getExportValue(exports, subpath) {
463
+ if (!exports) return null;
464
+ if ("string" == typeof exports) return "." === subpath ? exports : null;
465
+ if ("object" == typeof exports && null !== exports) {
466
+ const exportsObj = exports;
467
+ const value = exportsObj[subpath];
468
+ if (void 0 !== value) return value;
469
+ const withoutDot = subpath.replace(/^\.\//, "");
470
+ const alt = exportsObj[withoutDot];
471
+ if (void 0 !== alt) return alt;
472
+ for (const [pattern, val] of Object.entries(exportsObj))if (pattern.includes("*")) {
473
+ const escaped = escapeRegex(pattern).replace(/\*/g, "(.*)");
474
+ const regex = new RegExp(`^${escaped}$`);
475
+ const match = regex.exec(subpath) || regex.exec(withoutDot);
476
+ if (match) {
477
+ const captured = match[1] || "";
478
+ return substituteWildcard(val, captured);
479
+ }
480
+ }
481
+ }
482
+ return null;
483
+ }
484
+ function findMainTypePath(packageJson) {
485
+ if (packageJson.types) return packageJson.types;
486
+ if (packageJson.typings) return packageJson.typings;
487
+ if (packageJson.exports) {
488
+ const rootExport = getExportValue(packageJson.exports, ".");
489
+ if (rootExport) {
490
+ const typesPath = extractTypesFromExport(rootExport);
491
+ if (typesPath) return typesPath;
492
+ }
493
+ }
494
+ if (packageJson.main) {
495
+ const mainWithoutExt = packageJson.main.replace(/\.(m?[jt]s|cjs)$/, "");
496
+ const candidates = tryExtensions(mainWithoutExt);
497
+ const found = candidates.find((c)=>isTypeDefinition(c));
498
+ if (found) return found;
499
+ return packageJson.main;
500
+ }
501
+ return "index.d.ts";
502
+ }
503
+ function extractTypesFromExport(exportValue) {
504
+ if (!exportValue) return null;
505
+ if ("string" == typeof exportValue) return exportValue;
506
+ if ("object" == typeof exportValue && null !== exportValue) {
507
+ const obj = exportValue;
508
+ if ("string" == typeof obj.types) return obj.types;
509
+ if ("string" == typeof obj.import) return obj.import;
510
+ if ("string" == typeof obj.default) return obj.default;
511
+ if ("object" == typeof obj.import) return extractTypesFromExport(obj.import);
512
+ if ("object" == typeof obj.default) return extractTypesFromExport(obj.default);
513
+ }
514
+ return null;
515
+ }
516
+ const TypeResolverLive = Layer.succeed(TypeResolver, {
517
+ resolveImport: (specifier, packageJson, pkg)=>Effect.sync(()=>{
518
+ let subpath = specifier;
519
+ if (specifier.startsWith(pkg.name)) subpath = specifier.slice(pkg.name.length);
520
+ subpath = subpath.replace(/^\//, "");
521
+ if (!subpath.startsWith(".")) subpath = `./${subpath}`;
522
+ if (packageJson.exports) {
523
+ const lookupPath = subpath.startsWith("./") ? subpath : `./${subpath}`;
524
+ const exportValue = getExportValue(packageJson.exports, lookupPath);
525
+ if (exportValue) {
526
+ const typesPath = extractTypesFromExport(exportValue);
527
+ if (typesPath) return new ResolvedModule({
528
+ filePath: normalizePath(typesPath.replace(/^\.\//, "")),
529
+ isTypeDefinition: isTypeDefinition(typesPath),
530
+ package: pkg
531
+ });
532
+ }
533
+ }
534
+ if (packageJson.typesVersions) {
535
+ const versionMap = packageJson.typesVersions["*"];
536
+ if (versionMap) {
537
+ const lookupPath = subpath.replace(/^\.\//, "");
538
+ if (versionMap[lookupPath]) {
539
+ const resolved = versionMap[lookupPath];
540
+ const path = Array.isArray(resolved) ? resolved[0] : resolved;
541
+ if (path) return new ResolvedModule({
542
+ filePath: normalizePath(path.replace(/^\.\//, "")),
543
+ isTypeDefinition: isTypeDefinition(path),
544
+ package: pkg
545
+ });
546
+ }
547
+ for (const [pattern, paths] of Object.entries(versionMap))if (pattern.includes("*")) {
548
+ const escaped = escapeRegex(pattern).replace(/\*/g, "(.*)");
549
+ const regex = new RegExp(`^${escaped}$`);
550
+ if (regex.test(lookupPath)) {
551
+ const resolved = Array.isArray(paths) ? paths[0] : paths;
552
+ if (resolved) {
553
+ const captured = lookupPath.replace(regex, "$1");
554
+ const finalPath = resolved.replace("*", captured);
555
+ return new ResolvedModule({
556
+ filePath: normalizePath(finalPath.replace(/^\.\//, "")),
557
+ isTypeDefinition: isTypeDefinition(finalPath),
558
+ package: pkg
559
+ });
560
+ }
561
+ }
562
+ }
563
+ }
564
+ }
565
+ const candidates = tryExtensions(subpath.replace(/^\.\//, ""));
566
+ for (const candidate of candidates)if (isTypeDefinition(candidate)) return new ResolvedModule({
567
+ filePath: normalizePath(candidate),
568
+ isTypeDefinition: true,
569
+ package: pkg
570
+ });
571
+ const fallback = normalizePath(candidates[0] || subpath);
572
+ return new ResolvedModule({
573
+ filePath: fallback,
574
+ isTypeDefinition: isTypeDefinition(candidates[0] || subpath),
575
+ package: pkg
576
+ });
577
+ }),
578
+ resolveMainEntry: (packageJson, pkg)=>Effect.sync(()=>{
579
+ const mainPath = findMainTypePath(packageJson);
580
+ const normalizedPath = normalizePath(mainPath.replace(/^\.\//, ""));
581
+ return new ResolvedModule({
582
+ filePath: normalizedPath,
583
+ isTypeDefinition: isTypeDefinition(normalizedPath),
584
+ package: pkg
585
+ });
586
+ }),
587
+ resolveTypeEntries: (packageJson, pkg)=>Effect.sync(()=>{
588
+ const entries = [];
589
+ const mainPath = findMainTypePath(packageJson);
590
+ entries.push(new ResolvedModule({
591
+ filePath: normalizePath(mainPath.replace(/^\.\//, "")),
592
+ isTypeDefinition: isTypeDefinition(mainPath),
593
+ package: pkg
594
+ }));
595
+ if (packageJson.exports && "object" == typeof packageJson.exports) for (const [key, value] of Object.entries(packageJson.exports)){
596
+ if (!key.startsWith(".") && "*" !== key) continue;
597
+ const typesPath = extractTypesFromExport(value);
598
+ if (typesPath) entries.push(new ResolvedModule({
599
+ filePath: normalizePath(typesPath.replace(/^\.\//, "")),
600
+ isTypeDefinition: isTypeDefinition(typesPath),
601
+ package: pkg
602
+ }));
603
+ }
604
+ const seen = new Set();
605
+ return entries.filter((e)=>{
606
+ if (seen.has(e.filePath)) return false;
607
+ seen.add(e.filePath);
608
+ return true;
609
+ });
610
+ }),
611
+ findTypeDefinition: (jsFilePath, _packageJson, pkg)=>Effect.sync(()=>{
612
+ let typePath;
613
+ if (jsFilePath.endsWith(".mjs")) typePath = jsFilePath.replace(/\.mjs$/, ".d.mts");
614
+ else if (jsFilePath.endsWith(".cjs")) typePath = jsFilePath.replace(/\.cjs$/, ".d.cts");
615
+ else if (jsFilePath.endsWith(".js")) typePath = jsFilePath.replace(/\.js$/, ".d.ts");
616
+ else {
617
+ const withoutExt = jsFilePath.replace(/\.(m?js|cjs)$/, "");
618
+ typePath = `${withoutExt}.d.ts`;
619
+ }
620
+ return new ResolvedModule({
621
+ filePath: normalizePath(typePath),
622
+ isTypeDefinition: true,
623
+ package: pkg
624
+ });
625
+ })
626
+ });
627
+ const TypeRegistryLive = Layer.mergeAll(CacheServiceLive, PackageFetcherLive, TypeResolverLive);
628
+ export { CacheError, CacheErrorBase, CacheMetadata, CacheService, CacheServiceLive, Effect, FileTreeEntry, FileTreeResponse, Layer, NetworkError, NetworkErrorBase, PackageFetcher, PackageFetcherLive, PackageJson, PackageNotFoundError, PackageNotFoundErrorBase, PackageSpec, PackageSpecBase, ParseError, ParseErrorBase, ResolutionError, ResolutionErrorBase, ResolvedModule, ResolvedModuleBase, TimeoutError, TimeoutErrorBase, TypeRegistryLive, TypeRegistry_namespaceObject as TypeRegistry, TypeResolver, TypeResolverLive, fetchAndCache, getDefaultCacheDir, getVFS, hasCached, makeNodeCacheLayer, resolveVersion };
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 C. Spencer Beggs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.