@openpkg-ts/extract 0.24.0 → 0.25.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/dist/bin/tspec.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  detectTsRuntime,
4
4
  extract,
5
5
  resolveCompiledPath
6
- } from "../shared/chunk-bh378f7b.js";
6
+ } from "../shared/chunk-2zvzqxtn.js";
7
7
 
8
8
  // src/cli/spec.ts
9
9
  import * as fs from "node:fs";
@@ -1722,13 +1722,14 @@ function getInheritedMembers(classType, ownMemberNames, ctx, isStatic = false) {
1722
1722
  const { typeChecker: checker } = ctx;
1723
1723
  const inherited = [];
1724
1724
  const visited = new Set;
1725
+ const inheritedNames = new Set;
1725
1726
  const typeToWalk = isStatic ? classType.getSymbol()?.valueDeclaration && checker.getTypeOfSymbolAtLocation(classType.getSymbol(), classType.getSymbol().valueDeclaration) : classType;
1726
1727
  if (!typeToWalk)
1727
1728
  return inherited;
1728
- walkBaseTypes(typeToWalk, ownMemberNames, inherited, visited, ctx, isStatic);
1729
+ walkBaseTypes(typeToWalk, ownMemberNames, inherited, inheritedNames, visited, ctx, isStatic);
1729
1730
  return inherited;
1730
1731
  }
1731
- function walkBaseTypes(type, ownMemberNames, inherited, visited, ctx, isStatic) {
1732
+ function walkBaseTypes(type, ownMemberNames, inherited, inheritedNames, visited, ctx, isStatic) {
1732
1733
  if (visited.has(type))
1733
1734
  return;
1734
1735
  visited.add(type);
@@ -1742,16 +1743,17 @@ function walkBaseTypes(type, ownMemberNames, inherited, visited, ctx, isStatic)
1742
1743
  const propName = prop.getName();
1743
1744
  if (ownMemberNames.has(propName))
1744
1745
  continue;
1745
- if (inherited.some((m) => m.name === propName))
1746
+ if (inheritedNames.has(propName))
1746
1747
  continue;
1747
1748
  if (propName.startsWith("#") || propName.startsWith("__"))
1748
1749
  continue;
1749
1750
  const member = serializeInheritedMember(prop, baseName, ctx, isStatic);
1750
1751
  if (member) {
1751
1752
  inherited.push(member);
1753
+ inheritedNames.add(propName);
1752
1754
  }
1753
1755
  }
1754
- walkBaseTypes(baseType, ownMemberNames, inherited, visited, ctx, isStatic);
1756
+ walkBaseTypes(baseType, ownMemberNames, inherited, inheritedNames, visited, ctx, isStatic);
1755
1757
  }
1756
1758
  }
1757
1759
  function getStaticMembers(classType, checker) {
@@ -3092,6 +3094,25 @@ function mergeRuntimeSchemas(staticExports, runtimeSchemas) {
3092
3094
  }
3093
3095
 
3094
3096
  // src/builder/spec-builder.ts
3097
+ var typeDefinitionCache = null;
3098
+ function getTypeDefinitionCache() {
3099
+ if (!typeDefinitionCache) {
3100
+ typeDefinitionCache = new Map;
3101
+ }
3102
+ return typeDefinitionCache;
3103
+ }
3104
+ var internalTagCache = null;
3105
+ function getInternalTagCache() {
3106
+ if (!internalTagCache) {
3107
+ internalTagCache = new Map;
3108
+ }
3109
+ return internalTagCache;
3110
+ }
3111
+ function clearTypeDefinitionCache() {
3112
+ typeDefinitionCache = null;
3113
+ internalTagCache = null;
3114
+ }
3115
+ var YIELD_BATCH_SIZE = 5;
3095
3116
  var BUILTIN_TYPES2 = new Set([
3096
3117
  "Array",
3097
3118
  "ArrayBuffer",
@@ -3176,6 +3197,7 @@ function shouldSkipDanglingRef(name) {
3176
3197
  return false;
3177
3198
  }
3178
3199
  async function extract(options) {
3200
+ clearTypeDefinitionCache();
3179
3201
  const {
3180
3202
  entryFile,
3181
3203
  baseDir,
@@ -3185,7 +3207,8 @@ async function extract(options) {
3185
3207
  resolveExternalTypes,
3186
3208
  includeSchema,
3187
3209
  only,
3188
- ignore
3210
+ ignore,
3211
+ onProgress
3189
3212
  } = options;
3190
3213
  const diagnostics = [];
3191
3214
  let exports = [];
@@ -3216,10 +3239,15 @@ async function extract(options) {
3216
3239
  resolveExternalTypes
3217
3240
  });
3218
3241
  ctx.exportedIds = exportedIds;
3219
- for (const symbol of exportedSymbols) {
3242
+ const filteredSymbols = exportedSymbols.filter((s) => shouldIncludeExport(s.getName(), only, ignore));
3243
+ const total = filteredSymbols.length;
3244
+ for (let i = 0;i < filteredSymbols.length; i++) {
3245
+ const symbol = filteredSymbols[i];
3220
3246
  const exportName = symbol.getName();
3221
- if (!shouldIncludeExport(exportName, only, ignore))
3222
- continue;
3247
+ onProgress?.(i + 1, total, exportName);
3248
+ if (i > 0 && i % YIELD_BATCH_SIZE === 0) {
3249
+ await new Promise((r) => setImmediate(r));
3250
+ }
3223
3251
  try {
3224
3252
  const { declaration, targetSymbol } = resolveExportTarget(symbol, typeChecker);
3225
3253
  if (!declaration)
@@ -3237,7 +3265,8 @@ async function extract(options) {
3237
3265
  const meta = await getPackageMeta(entryFile, baseDir);
3238
3266
  const types = ctx.typeRegistry.getAll();
3239
3267
  const projectBaseDir = baseDir ?? path3.dirname(entryFile);
3240
- const forgottenExports = collectForgottenExports(exports, types, program, sourceFile, exportedIds, projectBaseDir);
3268
+ const definedTypes = new Set(types.map((t) => t.id));
3269
+ const forgottenExports = collectForgottenExports(exports, types, program, sourceFile, exportedIds, projectBaseDir, definedTypes);
3241
3270
  for (const forgotten of forgottenExports) {
3242
3271
  const refSummary = forgotten.referencedBy.slice(0, 3).map((r) => `${r.exportName} (${r.location})`).join(", ");
3243
3272
  const moreRefs = forgotten.referencedBy.length > 3 ? ` +${forgotten.referencedBy.length - 3} more` : "";
@@ -3320,10 +3349,9 @@ function collectAllRefsWithContext(obj, refs, state) {
3320
3349
  return;
3321
3350
  if (Array.isArray(obj)) {
3322
3351
  for (let i = 0;i < obj.length; i++) {
3323
- collectAllRefsWithContext(obj[i], refs, {
3324
- ...state,
3325
- path: [...state.path, `[${i}]`]
3326
- });
3352
+ state.path.push(`[${i}]`);
3353
+ collectAllRefsWithContext(obj[i], refs, state);
3354
+ state.path.pop();
3327
3355
  }
3328
3356
  return;
3329
3357
  }
@@ -3336,31 +3364,34 @@ function collectAllRefsWithContext(obj, refs, state) {
3336
3364
  typeName,
3337
3365
  exportName: state.exportName,
3338
3366
  location: state.location,
3339
- path: state.path.join(".") || undefined
3367
+ path: state.path.length > 0 ? state.path.join(".") : undefined
3340
3368
  });
3341
3369
  refs.set(typeName, existing);
3342
3370
  }
3371
+ const prevLocation = state.location;
3343
3372
  for (const [key, value] of Object.entries(record)) {
3344
- let newLocation = state.location;
3345
3373
  if (key === "returnType" || key === "returns")
3346
- newLocation = "return";
3374
+ state.location = "return";
3347
3375
  else if (key === "parameters" || key === "params")
3348
- newLocation = "parameter";
3376
+ state.location = "parameter";
3349
3377
  else if (key === "properties" || key === "members")
3350
- newLocation = "property";
3378
+ state.location = "property";
3351
3379
  else if (key === "extends" || key === "implements")
3352
- newLocation = "extends";
3380
+ state.location = "extends";
3353
3381
  else if (key === "typeParameters" || key === "typeParams")
3354
- newLocation = "type-parameter";
3355
- collectAllRefsWithContext(value, refs, {
3356
- ...state,
3357
- location: newLocation,
3358
- path: [...state.path, key]
3359
- });
3382
+ state.location = "type-parameter";
3383
+ state.path.push(key);
3384
+ collectAllRefsWithContext(value, refs, state);
3385
+ state.path.pop();
3386
+ state.location = prevLocation;
3360
3387
  }
3361
3388
  }
3362
3389
  }
3363
3390
  function findTypeDefinition(typeName, program, sourceFile) {
3391
+ const cache = getTypeDefinitionCache();
3392
+ if (cache.has(typeName)) {
3393
+ return cache.get(typeName);
3394
+ }
3364
3395
  const checker = program.getTypeChecker();
3365
3396
  const findInNode = (node) => {
3366
3397
  if ((ts11.isInterfaceDeclaration(node) || ts11.isTypeAliasDeclaration(node) || ts11.isClassDeclaration(node) || ts11.isEnumDeclaration(node)) && node.name?.text === typeName) {
@@ -3370,19 +3401,26 @@ function findTypeDefinition(typeName, program, sourceFile) {
3370
3401
  return ts11.forEachChild(node, findInNode);
3371
3402
  };
3372
3403
  const entryResult = findInNode(sourceFile);
3373
- if (entryResult)
3404
+ if (entryResult) {
3405
+ cache.set(typeName, entryResult);
3374
3406
  return entryResult;
3407
+ }
3375
3408
  for (const sf of program.getSourceFiles()) {
3376
3409
  if (sf.isDeclarationFile && !sf.fileName.includes("node_modules")) {
3377
3410
  const result = findInNode(sf);
3378
- if (result)
3411
+ if (result) {
3412
+ cache.set(typeName, result);
3379
3413
  return result;
3414
+ }
3380
3415
  }
3381
3416
  }
3382
3417
  const symbol = checker.resolveName(typeName, sourceFile, ts11.SymbolFlags.Type, false);
3383
3418
  if (symbol?.declarations?.[0]) {
3384
- return symbol.declarations[0].getSourceFile().fileName;
3419
+ const result = symbol.declarations[0].getSourceFile().fileName;
3420
+ cache.set(typeName, result);
3421
+ return result;
3385
3422
  }
3423
+ cache.set(typeName, undefined);
3386
3424
  return;
3387
3425
  }
3388
3426
  function isExternalType2(definedIn, baseDir) {
@@ -3395,15 +3433,23 @@ function isExternalType2(definedIn, baseDir) {
3395
3433
  return !normalizedDefined.startsWith(normalizedBase);
3396
3434
  }
3397
3435
  function hasInternalTag(typeName, program, sourceFile) {
3436
+ const cache = getInternalTagCache();
3437
+ const cached = cache.get(typeName);
3438
+ if (cached !== undefined) {
3439
+ return cached;
3440
+ }
3398
3441
  const checker = program.getTypeChecker();
3399
3442
  const symbol = checker.resolveName(typeName, sourceFile, ts11.SymbolFlags.Type, false);
3400
- if (!symbol)
3443
+ if (!symbol) {
3444
+ cache.set(typeName, false);
3401
3445
  return false;
3446
+ }
3402
3447
  const jsTags = symbol.getJsDocTags();
3403
- return jsTags.some((tag) => tag.name === "internal");
3448
+ const isInternal = jsTags.some((tag) => tag.name === "internal");
3449
+ cache.set(typeName, isInternal);
3450
+ return isInternal;
3404
3451
  }
3405
- function collectForgottenExports(exports, types, program, sourceFile, exportedIds, baseDir) {
3406
- const definedTypes = new Set(types.map((t) => t.id));
3452
+ function collectForgottenExports(exports, types, program, sourceFile, exportedIds, baseDir, definedTypes) {
3407
3453
  const referencedTypes = new Map;
3408
3454
  for (const exp of exports) {
3409
3455
  collectAllRefsWithContext(exp, referencedTypes, {
@@ -237,6 +237,8 @@ interface ExtractOptions {
237
237
  only?: string[];
238
238
  /** Ignore these exports (supports * wildcards) */
239
239
  ignore?: string[];
240
+ /** Progress callback for tracking extraction progress */
241
+ onProgress?: (current: number, total: number, item: string) => void;
240
242
  }
241
243
  interface ExtractResult {
242
244
  spec: OpenPkg;
package/dist/src/index.js CHANGED
@@ -48,7 +48,7 @@ import {
48
48
  valibotAdapter,
49
49
  withDescription,
50
50
  zodAdapter
51
- } from "../shared/chunk-bh378f7b.js";
51
+ } from "../shared/chunk-2zvzqxtn.js";
52
52
  // src/types/utils.ts
53
53
  function isExported(node) {
54
54
  const modifiers = node.modifiers;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpkg-ts/extract",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "TypeScript export extraction to OpenPkg spec",
5
5
  "keywords": [
6
6
  "openpkg",