@webneat/codewiki 0.0.2 → 0.0.5

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.
@@ -5,15 +5,21 @@ var __export = (target, all3) => {
5
5
  __defProp(target, name, { get: all3[name], enumerable: true });
6
6
  };
7
7
 
8
+ // ../../node_modules/.pnpm/tsup@8.5.0_postcss@8.5.6_tsx@4.20.6_typescript@5.9.3_yaml@2.8.1/node_modules/tsup/assets/esm_shims.js
9
+ import path from "path";
10
+ import { fileURLToPath } from "url";
11
+ var getFilename = () => fileURLToPath(import.meta.url);
12
+ var getDirname = () => path.dirname(getFilename());
13
+ var __dirname = /* @__PURE__ */ getDirname();
14
+
8
15
  // src/cli/env.ts
9
16
  import { existsSync } from "fs";
10
17
 
11
18
  // src/internals/context.ts
12
19
  import ts from "typescript";
13
- import { fileURLToPath } from "url";
14
20
  import Database from "better-sqlite3";
15
21
  import { readFile as readFile2 } from "fs/promises";
16
- import path, { dirname, join as join2 } from "path";
22
+ import path2, { join as join2 } from "path";
17
23
  import { drizzle } from "drizzle-orm/better-sqlite3";
18
24
 
19
25
  // ../errors/dist/index.js
@@ -77,6 +83,7 @@ var index_default = errors;
77
83
  var err = index_default({
78
84
  file_outside_project_path: (data) => `File "${data.file_path}" is outside project path "${data.project_path}"`,
79
85
  file_not_found: (data) => `File not found: ${data.path}`,
86
+ file_stat_error: (data) => `Could not get file stats for ${data.path}: ${data.reason}`,
80
87
  db_error: (data) => `Database error in ${data.operation}: ${data.reason}`,
81
88
  symbol_meta_parse_error: (data) => `Failed to parse symbol metadata for symbol ${data.symbol_id}: ${data.reason}`,
82
89
  exported_symbol_not_found: (data) => `Exported symbol "${data.name}" not found in file with id ${data.file_id}`,
@@ -89,6 +96,8 @@ var err = index_default({
89
96
  symbol_node_not_found: (data) => `Symbol node not found for ${data.name} in ${data.file_path}`,
90
97
  symbol_not_found: (data) => `Symbol "${data.name}" not found in file "${data.path}"`,
91
98
  describe_dependency_failed: (data) => `Failed to describe ${data.package}#${data.name}: ${data.reason}`,
99
+ could_not_describe_files_due_to_pending_symbols: (data) => `Cannot start describing files before describing all symbols; ${data.count} symbols are still pending`,
100
+ could_not_describe_directories_due_to_pending_files: (data) => `Cannot start describing directories before describing all files; ${data.count} files are still pending`,
92
101
  // CLI errors
93
102
  could_not_read_file: (data) => `Could not read file ${data.path}: ${data.reason}`,
94
103
  invalid_json: (data) => `Invalid JSON: ${data.reason}`,
@@ -441,7 +450,7 @@ __export(configs_exports, {
441
450
  import { eq as eq2, sql as sql3 } from "drizzle-orm";
442
451
 
443
452
  // src/db/common.ts
444
- import { eq, like, or, and, asc, desc } from "drizzle-orm";
453
+ import { eq, like, or, and, asc, desc, count } from "drizzle-orm";
445
454
  function safe_query(operation, fn) {
446
455
  return err.safe(fn, (reason, ...args) => err.new("db_error", { operation, args: args.slice(1), reason }));
447
456
  }
@@ -449,6 +458,9 @@ function do_search(db6, table, options) {
449
458
  if (!options.select.includes("id")) options.select.push("id");
450
459
  return db6.select(fields(table, options.select)).from(table).where(conditions(table, options.where)).orderBy(order(table, options.order_by)).offset(options.offset).limit(options.limit).all();
451
460
  }
461
+ function do_count(db6, table, options) {
462
+ return db6.select({ count: count() }).from(table).where(conditions(table, options)).get()?.count ?? 0;
463
+ }
452
464
  function fields(table, fields2) {
453
465
  const res = {};
454
466
  for (const field of fields2) res[field] = table[field];
@@ -500,8 +512,10 @@ __export(files_exports, {
500
512
  by_directory_path: () => by_directory_path,
501
513
  by_id: () => by_id,
502
514
  by_id_and_state: () => by_id_and_state,
515
+ by_ids: () => by_ids,
503
516
  by_path: () => by_path,
504
517
  by_state: () => by_state,
518
+ count: () => count2,
505
519
  del: () => del,
506
520
  del_by_dir: () => del_by_dir,
507
521
  get_directory_ids: () => get_directory_ids,
@@ -515,48 +529,6 @@ __export(files_exports, {
515
529
  });
516
530
  import { eq as eq3, and as and2, inArray, or as or2, like as like2 } from "drizzle-orm";
517
531
 
518
- // src/internals/utils.ts
519
- import { readFileSync } from "fs";
520
- var parse_json = err.safe(JSON.parse, (reason, text2) => err.new("invalid_json", { reason, text: text2 }));
521
- var read_file = err.safe(
522
- (path6) => readFileSync(path6, "utf-8"),
523
- (reason, path6) => err.new("could_not_read_file", { path: path6, reason })
524
- );
525
- function group_by_unique(items, key) {
526
- const groups = {};
527
- for (const item of items) {
528
- groups[key(item)] = item;
529
- }
530
- return groups;
531
- }
532
- function expand({ items, get_children, get_key }) {
533
- const visited = /* @__PURE__ */ new Set();
534
- const result = [];
535
- const queue = [...items];
536
- while (queue.length > 0) {
537
- const item = queue.shift();
538
- const key = get_key(item);
539
- if (err.any(key)) return key;
540
- if (visited.has(key)) continue;
541
- visited.add(key);
542
- result.push(item);
543
- const children3 = get_children(item);
544
- if (err.any(children3)) return children3;
545
- queue.push(...children3);
546
- }
547
- return result;
548
- }
549
- function uniq(items) {
550
- return [...new Set(items)];
551
- }
552
- function merge(a, b) {
553
- const res = { ...a };
554
- for (const key of Object.keys(b)) {
555
- if (b[key] !== void 0) res[key] = b[key];
556
- }
557
- return res;
558
- }
559
-
560
532
  // src/db/defaults.ts
561
533
  var files2 = {
562
534
  select: ["id", "directory_id", "path", "state", "error"],
@@ -586,6 +558,34 @@ var external_dependencies2 = {
586
558
  offset: 0,
587
559
  where: {}
588
560
  };
561
+ var imports2 = {
562
+ select: ["id", "exporter_file_id", "importer_file_id", "symbol_id", "name", "alias", "is_dynamic", "state", "error"],
563
+ order_by: ["id", "asc"],
564
+ limit: 20,
565
+ offset: 0,
566
+ where: {}
567
+ };
568
+ var external_imports2 = {
569
+ select: ["id", "file_id", "external_dependency_id", "alias", "is_dynamic"],
570
+ order_by: ["id", "asc"],
571
+ limit: 20,
572
+ offset: 0,
573
+ where: {}
574
+ };
575
+ var symbol_internal_links2 = {
576
+ select: ["id", "from_file_id", "to_file_id", "from_symbol_id", "to_symbol_id", "state", "error"],
577
+ order_by: ["id", "asc"],
578
+ limit: 20,
579
+ offset: 0,
580
+ where: {}
581
+ };
582
+ var symbol_external_links2 = {
583
+ select: ["id", "symbol_id", "external_import_id"],
584
+ order_by: ["id", "asc"],
585
+ limit: 20,
586
+ offset: 0,
587
+ where: {}
588
+ };
589
589
 
590
590
  // src/db/files.ts
591
591
  var default_select_fields = ["id", "directory_id", "path", "state", "error"];
@@ -593,15 +593,23 @@ var all = safe_query("files.all", (ctx) => ctx.db.select().from(files).all());
593
593
  var search = safe_query("files.search", (ctx, options = {}) => {
594
594
  return do_search(ctx.db, files, merge(files2, options));
595
595
  });
596
+ var count2 = safe_query("files.count", (ctx, where = {}) => {
597
+ return do_count(ctx.db, files, where);
598
+ });
596
599
  var by_id = safe_query("files.by_id", (ctx, id) => ctx.db.select().from(files).where(eq3(files.id, id)).get());
600
+ var by_ids = safe_query(
601
+ "files.by_ids",
602
+ (ctx, ids) => ctx.db.select().from(files).where(inArray(files.id, ids)).all()
603
+ );
597
604
  var by_path = safe_query(
598
605
  "files.by_path",
599
- (ctx, path6) => ctx.db.select().from(files).where(eq3(files.path, path6)).get()
600
- );
601
- var by_state = safe_query(
602
- "files.by_state",
603
- (ctx, state) => ctx.db.select().from(files).where(eq3(files.state, state)).all()
606
+ (ctx, path7) => ctx.db.select().from(files).where(eq3(files.path, path7)).get()
604
607
  );
608
+ var by_state = safe_query("files.by_state", (ctx, state, limit) => {
609
+ let query = ctx.db.select().from(files).where(eq3(files.state, state));
610
+ if (limit) query = query.limit(limit);
611
+ return query.all();
612
+ });
605
613
  var insert = safe_query("files.insert", (ctx, values) => ctx.db.insert(files).values(values).run());
606
614
  var update = safe_query(
607
615
  "files.update",
@@ -643,8 +651,8 @@ var using_dependency = safe_query(
643
651
  "files.using_dependency",
644
652
  (ctx, external_dependency_id, fields_to_select = default_select_fields) => {
645
653
  if (!fields_to_select.includes("id")) fields_to_select.push("id");
646
- const imports2 = ctx.db.select({ file_id: external_imports.file_id }).from(external_imports).where(eq3(external_imports.external_dependency_id, external_dependency_id)).all();
647
- const file_ids = uniq(imports2.map((i) => i.file_id));
654
+ const imports4 = ctx.db.select({ file_id: external_imports.file_id }).from(external_imports).where(eq3(external_imports.external_dependency_id, external_dependency_id)).all();
655
+ const file_ids = uniq(imports4.map((i) => i.file_id));
648
656
  if (file_ids.length === 0) return [];
649
657
  return ctx.db.select(fields(files, fields_to_select)).from(files).where(inArray(files.id, file_ids)).all();
650
658
  }
@@ -675,8 +683,10 @@ var directories_exports = {};
675
683
  __export(directories_exports, {
676
684
  by_id: () => by_id2,
677
685
  by_id_and_state: () => by_id_and_state2,
686
+ by_ids: () => by_ids2,
678
687
  by_path: () => by_path2,
679
688
  by_state: () => by_state2,
689
+ count: () => count3,
680
690
  insert: () => insert2,
681
691
  search: () => search2,
682
692
  update: () => update2,
@@ -687,9 +697,13 @@ var by_id2 = safe_query(
687
697
  "directories.by_id",
688
698
  (ctx, id) => ctx.db.select().from(directories).where(eq4(directories.id, id)).get()
689
699
  );
700
+ var by_ids2 = safe_query(
701
+ "directories.by_ids",
702
+ (ctx, ids) => ctx.db.select().from(directories).where(inArray2(directories.id, ids)).all()
703
+ );
690
704
  var by_path2 = safe_query(
691
705
  "directories.by_path",
692
- (ctx, path6) => ctx.db.select().from(directories).where(eq4(directories.path, path6)).get()
706
+ (ctx, path7) => ctx.db.select().from(directories).where(eq4(directories.path, path7)).get()
693
707
  );
694
708
  var by_state2 = safe_query(
695
709
  "directories.by_state",
@@ -714,6 +728,9 @@ var by_id_and_state2 = safe_query(
714
728
  var search2 = safe_query("directories.search", (ctx, options = {}) => {
715
729
  return do_search(ctx.db, directories, merge(directories2, options));
716
730
  });
731
+ var count3 = safe_query("directories.count", (ctx, where = {}) => {
732
+ return do_count(ctx.db, directories, where);
733
+ });
717
734
 
718
735
  // src/db/imports.ts
719
736
  var imports_exports = {};
@@ -721,11 +738,23 @@ __export(imports_exports, {
721
738
  by_exporter_file: () => by_exporter_file,
722
739
  by_importer_file: () => by_importer_file,
723
740
  by_state: () => by_state3,
741
+ count: () => count4,
742
+ count_pending_symbols: () => count_pending_symbols,
724
743
  del_by_importer_file: () => del_by_importer_file,
725
744
  insert_many: () => insert_many,
745
+ search: () => search3,
726
746
  update: () => update3
727
747
  });
728
- import { eq as eq5 } from "drizzle-orm";
748
+ import { eq as eq5, ne, and as and4, count as countFn } from "drizzle-orm";
749
+ var search3 = safe_query("imports.search", (ctx, options = {}) => {
750
+ return do_search(ctx.db, imports, merge(imports2, options));
751
+ });
752
+ var count4 = safe_query("imports.count", (ctx, where = {}) => {
753
+ return do_count(ctx.db, imports, where);
754
+ });
755
+ var count_pending_symbols = safe_query("imports.count_pending_symbols", (ctx, file_id) => {
756
+ return ctx.db.select({ count: countFn() }).from(imports).innerJoin(symbols, eq5(imports.symbol_id, symbols.id)).where(and4(eq5(imports.importer_file_id, file_id), ne(symbols.state, "ready"))).get()?.count ?? 0;
757
+ });
729
758
  var by_exporter_file = safe_query(
730
759
  "imports.by_exporter_file",
731
760
  (ctx, exporter_file_id) => ctx.db.select().from(imports).where(eq5(imports.exporter_file_id, exporter_file_id)).all()
@@ -755,17 +784,67 @@ __export(symbols_exports, {
755
784
  by_file_and_name: () => by_file_and_name,
756
785
  by_id: () => by_id3,
757
786
  by_id_and_state: () => by_id_and_state3,
787
+ by_ids: () => by_ids3,
758
788
  by_state: () => by_state4,
789
+ count: () => count5,
759
790
  del_by_file: () => del_by_file,
760
791
  insert_many: () => insert_many2,
761
792
  meta: () => meta,
762
793
  referenced_by: () => referenced_by,
763
794
  referencing: () => referencing,
764
- search: () => search3,
795
+ search: () => search4,
765
796
  update: () => update4,
766
797
  using_dependency: () => using_dependency2
767
798
  });
768
- import { eq as eq6, and as and4, inArray as inArray3 } from "drizzle-orm";
799
+ import { eq as eq6, and as and5, inArray as inArray3 } from "drizzle-orm";
800
+
801
+ // src/internals/utils.ts
802
+ import { readFileSync, statSync } from "fs";
803
+ var parse_json = err.safe(JSON.parse, (reason, text2) => err.new("invalid_json", { reason, text: text2 }));
804
+ var read_file = err.safe(
805
+ (path7) => readFileSync(path7, "utf-8"),
806
+ (reason, path7) => err.new("could_not_read_file", { path: path7, reason })
807
+ );
808
+ var file_stat = err.safe(
809
+ (path7) => statSync(path7),
810
+ (reason, path7) => err.new("file_stat_error", { path: path7, reason })
811
+ );
812
+ function group_by_unique(items, key) {
813
+ const groups = {};
814
+ for (const item of items) {
815
+ groups[key(item)] = item;
816
+ }
817
+ return groups;
818
+ }
819
+ function expand({ items, get_children, get_key }) {
820
+ const visited = /* @__PURE__ */ new Set();
821
+ const result = [];
822
+ const queue = [...items];
823
+ while (queue.length > 0) {
824
+ const item = queue.shift();
825
+ const key = get_key(item);
826
+ if (err.any(key)) return key;
827
+ if (visited.has(key)) continue;
828
+ visited.add(key);
829
+ result.push(item);
830
+ const children3 = get_children(item);
831
+ if (err.any(children3)) return children3;
832
+ queue.push(...children3);
833
+ }
834
+ return result;
835
+ }
836
+ function uniq(items) {
837
+ return [...new Set(items)];
838
+ }
839
+ function merge(a, b) {
840
+ const res = { ...a };
841
+ for (const key of Object.keys(b)) {
842
+ if (b[key] !== void 0) res[key] = b[key];
843
+ }
844
+ return res;
845
+ }
846
+
847
+ // src/db/symbols.ts
769
848
  var insert_many2 = safe_query("symbols.insert_many", (ctx, values) => ctx.db.insert(symbols).values(values).run());
770
849
  var del_by_file = safe_query(
771
850
  "symbols.delete_by_file",
@@ -773,7 +852,7 @@ var del_by_file = safe_query(
773
852
  );
774
853
  var by_file_and_name = safe_query(
775
854
  "symbols.by_file_and_name",
776
- (ctx, params) => ctx.db.select().from(symbols).where(and4(eq6(symbols.file_id, params.file_id), eq6(symbols.name, params.name), eq6(symbols.is_exported, params.is_exported))).get()
855
+ (ctx, params) => ctx.db.select().from(symbols).where(and5(eq6(symbols.file_id, params.file_id), eq6(symbols.name, params.name), eq6(symbols.is_exported, params.is_exported))).get()
777
856
  );
778
857
  var by_state4 = safe_query(
779
858
  "symbols.by_state",
@@ -788,9 +867,13 @@ var update4 = safe_query(
788
867
  (ctx, id, data) => ctx.db.update(symbols).set(data).where(eq6(symbols.id, id)).run()
789
868
  );
790
869
  var by_id3 = safe_query("symbols.by_id", (ctx, id) => ctx.db.select().from(symbols).where(eq6(symbols.id, id)).get());
870
+ var by_ids3 = safe_query(
871
+ "symbols.by_ids",
872
+ (ctx, ids) => ctx.db.select().from(symbols).where(inArray3(symbols.id, ids)).all()
873
+ );
791
874
  var by_id_and_state3 = safe_query(
792
875
  "symbols.by_id_and_state",
793
- (ctx, params) => ctx.db.select().from(symbols).where(and4(eq6(symbols.id, params.id), eq6(symbols.state, params.state))).get()
876
+ (ctx, params) => ctx.db.select().from(symbols).where(and5(eq6(symbols.id, params.id), eq6(symbols.state, params.state))).get()
794
877
  );
795
878
  function meta(symbol) {
796
879
  return err.catch(
@@ -798,8 +881,12 @@ function meta(symbol) {
798
881
  (reason) => err.new("symbol_meta_parse_error", { reason, symbol_id: symbol.id, meta: symbol.meta })
799
882
  );
800
883
  }
801
- var search3 = safe_query("symbols.search", (ctx, options = {}) => {
802
- return do_search(ctx.db, symbols, merge(symbols2, options));
884
+ var search4 = safe_query(
885
+ "symbols.search",
886
+ (ctx, options = {}) => do_search(ctx.db, symbols, merge(symbols2, options))
887
+ );
888
+ var count5 = safe_query("symbols.count", (ctx, where = {}) => {
889
+ return do_count(ctx.db, symbols, where);
803
890
  });
804
891
  var referenced_by = safe_query(
805
892
  "symbols.referenced_by",
@@ -837,20 +924,26 @@ var external_dependencies_exports = {};
837
924
  __export(external_dependencies_exports, {
838
925
  all: () => all2,
839
926
  by_id: () => by_id4,
927
+ by_ids: () => by_ids4,
840
928
  by_package_subpath_and_name: () => by_package_subpath_and_name,
841
929
  by_state: () => by_state5,
930
+ count: () => count6,
842
931
  get_or_create: () => get_or_create,
843
932
  insert: () => insert3,
844
- search: () => search4,
933
+ search: () => search5,
845
934
  update: () => update5,
846
935
  used_by_file: () => used_by_file,
847
936
  used_by_symbol: () => used_by_symbol
848
937
  });
849
- import { eq as eq7, and as and5, sql as sql4, inArray as inArray4 } from "drizzle-orm";
938
+ import { eq as eq7, and as and6, sql as sql4, inArray as inArray4 } from "drizzle-orm";
850
939
  var by_id4 = safe_query(
851
940
  "external_dependencies.by_id",
852
941
  (ctx, id) => ctx.db.select().from(external_dependencies).where(eq7(external_dependencies.id, id)).get()
853
942
  );
943
+ var by_ids4 = safe_query(
944
+ "external_dependencies.by_ids",
945
+ (ctx, ids) => ctx.db.select().from(external_dependencies).where(inArray4(external_dependencies.id, ids)).all()
946
+ );
854
947
  var by_state5 = safe_query(
855
948
  "external_dependencies.by_state",
856
949
  (ctx, state) => ctx.db.select().from(external_dependencies).where(eq7(external_dependencies.state, state)).all()
@@ -858,7 +951,7 @@ var by_state5 = safe_query(
858
951
  var by_package_subpath_and_name = safe_query(
859
952
  "external_dependencies.by_package_subpath_and_name",
860
953
  (ctx, params) => ctx.db.select().from(external_dependencies).where(
861
- and5(
954
+ and6(
862
955
  eq7(external_dependencies.package, params.package),
863
956
  params.subpath === null ? sql4`${external_dependencies.subpath} IS NULL` : eq7(external_dependencies.subpath, params.subpath),
864
957
  params.name === null ? sql4`${external_dependencies.name} IS NULL` : eq7(external_dependencies.name, params.name)
@@ -880,11 +973,13 @@ function get_or_create(ctx, value) {
880
973
  (existing) => existing || insert3(ctx, value)
881
974
  );
882
975
  }
883
- var search4 = safe_query(
976
+ var search5 = safe_query(
884
977
  "external_dependencies.search",
885
- (ctx, options = {}) => {
886
- return do_search(ctx.db, external_dependencies, merge(external_dependencies2, options));
887
- }
978
+ (ctx, options = {}) => do_search(ctx.db, external_dependencies, merge(external_dependencies2, options))
979
+ );
980
+ var count6 = safe_query(
981
+ "external_dependencies.count",
982
+ (ctx, where = {}) => do_count(ctx.db, external_dependencies, where)
888
983
  );
889
984
  var used_by_file = safe_query(
890
985
  "external_dependencies.used_by_file",
@@ -916,10 +1011,22 @@ __export(external_imports_exports, {
916
1011
  by_external_dependency: () => by_external_dependency,
917
1012
  by_file: () => by_file2,
918
1013
  by_symbol: () => by_symbol,
1014
+ count: () => count7,
1015
+ count_pending_dependencies: () => count_pending_dependencies,
919
1016
  del_by_file: () => del_by_file2,
920
- insert_many: () => insert_many3
1017
+ insert_many: () => insert_many3,
1018
+ search: () => search6
1019
+ });
1020
+ import { eq as eq8, ne as ne2, and as and7, count as countFn2 } from "drizzle-orm";
1021
+ var search6 = safe_query("external_imports.search", (ctx, options = {}) => {
1022
+ return do_search(ctx.db, external_imports, merge(external_imports2, options));
1023
+ });
1024
+ var count7 = safe_query("external_imports.count", (ctx, where = {}) => {
1025
+ return do_count(ctx.db, external_imports, where);
1026
+ });
1027
+ var count_pending_dependencies = safe_query("external_imports.count_pending_dependencies", (ctx, file_id) => {
1028
+ return ctx.db.select({ count: countFn2() }).from(external_imports).innerJoin(external_dependencies, eq8(external_imports.external_dependency_id, external_dependencies.id)).where(and7(eq8(external_imports.file_id, file_id), ne2(external_dependencies.state, "ready"))).get()?.count ?? 0;
921
1029
  });
922
- import { eq as eq8 } from "drizzle-orm";
923
1030
  var insert_many3 = safe_query(
924
1031
  "external_imports.insert_many",
925
1032
  (ctx, values) => ctx.db.insert(external_imports).values(values).run()
@@ -954,11 +1061,20 @@ var by_symbol = safe_query(
954
1061
  var symbol_internal_links_exports = {};
955
1062
  __export(symbol_internal_links_exports, {
956
1063
  by_from_symbol: () => by_from_symbol,
1064
+ count: () => count8,
957
1065
  del_by_from_symbol: () => del_by_from_symbol,
958
1066
  exists: () => exists,
959
- insert: () => insert4
1067
+ insert: () => insert4,
1068
+ search: () => search7,
1069
+ update_state_by_to_symbol: () => update_state_by_to_symbol
1070
+ });
1071
+ import { and as and8, eq as eq9 } from "drizzle-orm";
1072
+ var search7 = safe_query("symbol_internal_links.search", (ctx, options = {}) => {
1073
+ return do_search(ctx.db, symbol_internal_links, merge(symbol_internal_links2, options));
1074
+ });
1075
+ var count8 = safe_query("symbol_internal_links.count", (ctx, where = {}) => {
1076
+ return do_count(ctx.db, symbol_internal_links, where);
960
1077
  });
961
- import { and as and6, eq as eq9 } from "drizzle-orm";
962
1078
  var by_from_symbol = safe_query(
963
1079
  "symbol_internal_links.by_from_symbol",
964
1080
  (ctx, from_symbol_id) => ctx.db.query.symbol_internal_links.findMany({
@@ -978,23 +1094,43 @@ var insert4 = safe_query(
978
1094
  );
979
1095
  var exists = safe_query(
980
1096
  "symbol_internal_links.exists",
981
- (ctx, params) => ctx.db.select({ id: symbol_internal_links.id }).from(symbol_internal_links).where(and6(eq9(symbol_internal_links.from_symbol_id, params.from_symbol_id), eq9(symbol_internal_links.to_symbol_id, params.to_symbol_id))).get()
1097
+ (ctx, params) => ctx.db.select({ id: symbol_internal_links.id }).from(symbol_internal_links).where(and8(eq9(symbol_internal_links.from_symbol_id, params.from_symbol_id), eq9(symbol_internal_links.to_symbol_id, params.to_symbol_id))).get()
982
1098
  );
983
1099
  var del_by_from_symbol = safe_query(
984
1100
  "symbol_internal_links.del_by_from_symbol",
985
1101
  (ctx, from_symbol_id) => ctx.db.delete(symbol_internal_links).where(eq9(symbol_internal_links.from_symbol_id, from_symbol_id)).run()
986
1102
  );
1103
+ var update_state_by_to_symbol = safe_query(
1104
+ "symbol_internal_links.update_state_by_to_symbol",
1105
+ (ctx, to_symbol_id, state) => ctx.db.update(symbol_internal_links).set({ state }).where(eq9(symbol_internal_links.to_symbol_id, to_symbol_id)).run()
1106
+ );
987
1107
 
988
1108
  // src/db/symbol_external_links.ts
989
1109
  var symbol_external_links_exports = {};
990
1110
  __export(symbol_external_links_exports, {
991
1111
  by_external_import: () => by_external_import,
992
1112
  by_symbol: () => by_symbol2,
1113
+ count: () => count9,
1114
+ count_by_dependency: () => count_by_dependency,
1115
+ count_pending_deps: () => count_pending_deps,
993
1116
  del_by_symbol: () => del_by_symbol,
994
1117
  exists: () => exists2,
995
- insert: () => insert5
1118
+ insert: () => insert5,
1119
+ search: () => search8
1120
+ });
1121
+ import { and as and9, eq as eq10, ne as ne3, count as countFn3 } from "drizzle-orm";
1122
+ var search8 = safe_query("symbol_external_links.search", (ctx, options = {}) => {
1123
+ return do_search(ctx.db, symbol_external_links, merge(symbol_external_links2, options));
1124
+ });
1125
+ var count9 = safe_query("symbol_external_links.count", (ctx, where = {}) => {
1126
+ return do_count(ctx.db, symbol_external_links, where);
1127
+ });
1128
+ var count_by_dependency = safe_query("symbol_external_links.count_by_dependency", (ctx, dependency_id) => {
1129
+ return ctx.db.select({ count: countFn3() }).from(symbol_external_links).innerJoin(external_imports, eq10(symbol_external_links.external_import_id, external_imports.id)).where(eq10(external_imports.external_dependency_id, dependency_id)).get()?.count ?? 0;
1130
+ });
1131
+ var count_pending_deps = safe_query("symbol_external_links.count_pending_deps", (ctx, symbol_id) => {
1132
+ return ctx.db.select({ count: countFn3() }).from(symbol_external_links).innerJoin(external_imports, eq10(symbol_external_links.external_import_id, external_imports.id)).innerJoin(external_dependencies, eq10(external_imports.external_dependency_id, external_dependencies.id)).where(and9(eq10(symbol_external_links.symbol_id, symbol_id), ne3(external_dependencies.state, "ready"))).get()?.count ?? 0;
996
1133
  });
997
- import { and as and7, eq as eq10 } from "drizzle-orm";
998
1134
  var by_symbol2 = safe_query(
999
1135
  "symbol_external_links.by_symbol",
1000
1136
  (ctx, symbol_id) => ctx.db.select().from(symbol_external_links).where(eq10(symbol_external_links.symbol_id, symbol_id)).all()
@@ -1009,7 +1145,7 @@ var by_external_import = safe_query(
1009
1145
  );
1010
1146
  var exists2 = safe_query(
1011
1147
  "symbol_external_links.exists",
1012
- (ctx, params) => ctx.db.select({ id: symbol_external_links.id }).from(symbol_external_links).where(and7(eq10(symbol_external_links.symbol_id, params.symbol_id), eq10(symbol_external_links.external_import_id, params.external_import_id))).get()
1148
+ (ctx, params) => ctx.db.select({ id: symbol_external_links.id }).from(symbol_external_links).where(and9(eq10(symbol_external_links.symbol_id, params.symbol_id), eq10(symbol_external_links.external_import_id, params.external_import_id))).get()
1013
1149
  );
1014
1150
  var del_by_symbol = safe_query(
1015
1151
  "symbol_external_links.del_by_symbol",
@@ -1018,8 +1154,8 @@ var del_by_symbol = safe_query(
1018
1154
 
1019
1155
  // src/internals/context.ts
1020
1156
  async function create_context(sqlite, db6, config) {
1021
- const project_path = path.resolve(config.project_path);
1022
- const currentDir = dirname(fileURLToPath(import.meta.url));
1157
+ const project_path = path2.resolve(config.project_path);
1158
+ const currentDir = __dirname;
1023
1159
  const migrations_path = currentDir.includes("/dist") ? join2(currentDir, "../migrations") : join2(currentDir, "../../migrations");
1024
1160
  const tsconfig_path = join2(project_path, "tsconfig.json");
1025
1161
  if (!ts.sys.fileExists(tsconfig_path)) {
@@ -1027,8 +1163,8 @@ async function create_context(sqlite, db6, config) {
1027
1163
  }
1028
1164
  const tsconfig = ts.parseJsonConfigFileContent(ts.readConfigFile(tsconfig_path, ts.sys.readFile).config, ts.sys, project_path);
1029
1165
  const program = ts.createProgram({ rootNames: tsconfig.fileNames, options: tsconfig.options });
1030
- const package_json_path = config.package_json_path ?? path.join(project_path, "package.json");
1031
- const node_modules_paths = config.node_modules_paths ?? [path.join(project_path, "node_modules")];
1166
+ const package_json_path = config.package_json_path ?? path2.join(project_path, "package.json");
1167
+ const node_modules_paths = config.node_modules_paths ?? [path2.join(project_path, "node_modules")];
1032
1168
  const dependencies2 = await get_dependencies(package_json_path, node_modules_paths);
1033
1169
  const ctx = { db: db6, sqlite, migrations_path, project_path, program, dependencies: dependencies2 };
1034
1170
  await migrate(ctx);
@@ -1087,7 +1223,7 @@ async function get_dependencies(package_json_path, node_modules_paths) {
1087
1223
  async function get_github_repo(node_modules_paths, package_name) {
1088
1224
  for (const node_modules_path of node_modules_paths) {
1089
1225
  try {
1090
- const package_json_path = path.join(node_modules_path, package_name, "package.json");
1226
+ const package_json_path = path2.join(node_modules_path, package_name, "package.json");
1091
1227
  const package_json = JSON.parse(await readFile2(package_json_path, "utf-8"));
1092
1228
  const url = package_json.repository?.url || package_json.repository;
1093
1229
  if (typeof url === "string") {
@@ -1104,7 +1240,7 @@ async function get_github_repo(node_modules_paths, package_name) {
1104
1240
  // src/cli/env.ts
1105
1241
  var env = {
1106
1242
  read_file,
1107
- file_exists: (path6) => existsSync(path6),
1243
+ file_exists: (path7) => existsSync(path7),
1108
1244
  argv: () => process.argv,
1109
1245
  log: (...args) => console.log(...args),
1110
1246
  error: (...args) => console.error(...args),
@@ -1234,7 +1370,7 @@ var DependencySelectOptions = z.object({
1234
1370
  });
1235
1371
 
1236
1372
  // src/update/track_changes.ts
1237
- import path2 from "path";
1373
+ import path3 from "path";
1238
1374
  import "typescript";
1239
1375
  import { stat } from "fs/promises";
1240
1376
 
@@ -1245,9 +1381,9 @@ function file_updated(ctx, file_id) {
1245
1381
  items: [file_id],
1246
1382
  get_key: (id) => id,
1247
1383
  get_children: (id) => {
1248
- const imports2 = imports_exports.by_exporter_file(ctx, id);
1249
- if (err.any(imports2)) return imports2;
1250
- return imports2.map((x) => x.importer_file_id);
1384
+ const imports4 = imports_exports.by_exporter_file(ctx, id);
1385
+ if (err.any(imports4)) return imports4;
1386
+ return imports4.map((x) => x.importer_file_id);
1251
1387
  }
1252
1388
  })
1253
1389
  );
@@ -1280,7 +1416,7 @@ function get_source_files(ctx) {
1280
1416
  for (const file of ctx.program.getSourceFiles()) {
1281
1417
  if (ctx.program.isSourceFileDefaultLibrary(file)) continue;
1282
1418
  if (ctx.program.isSourceFileFromExternalLibrary(file)) continue;
1283
- if (!path2.resolve(file.fileName).startsWith(ctx.project_path)) continue;
1419
+ if (!path3.resolve(file.fileName).startsWith(ctx.project_path)) continue;
1284
1420
  src_files.push(file);
1285
1421
  }
1286
1422
  return src_files;
@@ -1328,7 +1464,7 @@ async function changes(ctx, source_files, db_files) {
1328
1464
  return { created, updated, deleted };
1329
1465
  }
1330
1466
  function get_file_path(ctx, file) {
1331
- const absolute_path = path2.resolve(file.fileName);
1467
+ const absolute_path = path3.resolve(file.fileName);
1332
1468
  if (absolute_path.startsWith(ctx.project_path)) return absolute_path.slice(ctx.project_path.length);
1333
1469
  return err.new("file_outside_project_path", { file_path: absolute_path, project_path: ctx.project_path });
1334
1470
  }
@@ -1336,10 +1472,10 @@ function get_parents_paths(ctx, file) {
1336
1472
  const file_path = get_file_path(ctx, file);
1337
1473
  if (err.any(file_path)) return file_path;
1338
1474
  const dirs = [];
1339
- let current = path2.dirname(file_path);
1340
- while (current !== path2.sep) {
1475
+ let current = path3.dirname(file_path);
1476
+ while (current !== path3.sep) {
1341
1477
  dirs.push(current);
1342
- current = path2.dirname(current);
1478
+ current = path3.dirname(current);
1343
1479
  }
1344
1480
  dirs.push(current);
1345
1481
  return dirs.reverse();
@@ -1373,19 +1509,19 @@ async function sync_external_dependencies(ctx) {
1373
1509
  }
1374
1510
 
1375
1511
  // src/update/scan_files/scan_files.ts
1376
- import path4 from "path";
1512
+ import path5 from "path";
1377
1513
  import ts10 from "typescript";
1378
1514
 
1379
1515
  // src/update/scan_files/imports.ts
1380
1516
  import ts4 from "typescript";
1381
1517
 
1382
1518
  // src/update/scan_files/common.ts
1383
- import path3 from "path";
1519
+ import path4 from "path";
1384
1520
  import ts3 from "typescript";
1385
1521
  function is_external_module(ctx, source_file, module_path) {
1386
1522
  const resolved = ts3.resolveModuleName(module_path, source_file.fileName, ctx.program.getCompilerOptions(), ts3.sys);
1387
1523
  if (!resolved.resolvedModule) return true;
1388
- const resolved_path = path3.resolve(resolved.resolvedModule.resolvedFileName);
1524
+ const resolved_path = path4.resolve(resolved.resolvedModule.resolvedFileName);
1389
1525
  return !resolved_path.startsWith(ctx.project_path);
1390
1526
  }
1391
1527
  function has_export_modifier(node) {
@@ -1494,13 +1630,13 @@ function is_import(ctx, source_file, node) {
1494
1630
  return !is_external_module(ctx, source_file, node.moduleSpecifier.text);
1495
1631
  }
1496
1632
  function extract_import(ctx, source_file, node, file_id) {
1497
- const imports2 = [];
1633
+ const imports4 = [];
1498
1634
  const clause = node.importClause;
1499
- if (!clause || !node.moduleSpecifier || !ts4.isStringLiteral(node.moduleSpecifier)) return imports2;
1635
+ if (!clause || !node.moduleSpecifier || !ts4.isStringLiteral(node.moduleSpecifier)) return imports4;
1500
1636
  const exporter_file_id = resolve_exporter_file(ctx, source_file, node.moduleSpecifier.text);
1501
- if (err.any(exporter_file_id)) return imports2;
1637
+ if (err.any(exporter_file_id)) return imports4;
1502
1638
  if (clause.name) {
1503
- imports2.push({
1639
+ imports4.push({
1504
1640
  importer_file_id: file_id,
1505
1641
  exporter_file_id,
1506
1642
  name: "default",
@@ -1510,7 +1646,7 @@ function extract_import(ctx, source_file, node, file_id) {
1510
1646
  }
1511
1647
  if (clause.namedBindings && ts4.isNamedImports(clause.namedBindings)) {
1512
1648
  for (const element of clause.namedBindings.elements) {
1513
- imports2.push({
1649
+ imports4.push({
1514
1650
  importer_file_id: file_id,
1515
1651
  exporter_file_id,
1516
1652
  name: (element.propertyName || element.name).text,
@@ -1520,7 +1656,7 @@ function extract_import(ctx, source_file, node, file_id) {
1520
1656
  }
1521
1657
  }
1522
1658
  if (clause.namedBindings && ts4.isNamespaceImport(clause.namedBindings)) {
1523
- imports2.push({
1659
+ imports4.push({
1524
1660
  importer_file_id: file_id,
1525
1661
  exporter_file_id,
1526
1662
  name: "*",
@@ -1528,7 +1664,7 @@ function extract_import(ctx, source_file, node, file_id) {
1528
1664
  state: "to_link"
1529
1665
  });
1530
1666
  }
1531
- return imports2;
1667
+ return imports4;
1532
1668
  }
1533
1669
  function extract_dynamic_import(ctx, source_file, node, file_id) {
1534
1670
  const arg = node.arguments[0];
@@ -1640,7 +1776,7 @@ function extract_external_import_info(node) {
1640
1776
  }
1641
1777
  function extract_external_import(ctx, node, file_id) {
1642
1778
  const infos = extract_external_import_info(node);
1643
- const external_imports2 = [];
1779
+ const external_imports3 = [];
1644
1780
  for (const info of infos) {
1645
1781
  const dep_meta = Object.values(ctx.dependencies).find((dep) => info.package.startsWith(dep.name));
1646
1782
  const dependency = external_dependencies_exports.get_or_create(ctx, {
@@ -1653,9 +1789,9 @@ function extract_external_import(ctx, node, file_id) {
1653
1789
  state: "to_describe"
1654
1790
  });
1655
1791
  if (err.any(dependency)) return dependency;
1656
- external_imports2.push({ file_id, external_dependency_id: dependency.id, alias: info.alias, is_dynamic: false });
1792
+ external_imports3.push({ file_id, external_dependency_id: dependency.id, alias: info.alias, is_dynamic: false });
1657
1793
  }
1658
- return external_imports2;
1794
+ return external_imports3;
1659
1795
  }
1660
1796
  function extract_external_dynamic_import(ctx, node, file_id) {
1661
1797
  const arg = node.arguments[0];
@@ -1960,32 +2096,32 @@ function scan_file(ctx, file) {
1960
2096
  () => external_imports_exports.del_by_file(ctx, file.id),
1961
2097
  () => get_source_file(ctx, file.path),
1962
2098
  (source_file) => parse_file(ctx, source_file, file.id),
1963
- ({ imports: imports2, symbols: symbols4, external_imports: external_imports2 }) => err.pipe(
1964
- () => external_imports2.length && external_imports_exports.insert_many(ctx, external_imports2),
1965
- () => imports2.length && imports_exports.insert_many(ctx, imports2),
2099
+ ({ imports: imports4, symbols: symbols4, external_imports: external_imports3 }) => err.pipe(
2100
+ () => external_imports3.length && external_imports_exports.insert_many(ctx, external_imports3),
2101
+ () => imports4.length && imports_exports.insert_many(ctx, imports4),
1966
2102
  () => symbols4.length && symbols_exports.insert_many(ctx, symbols4)
1967
2103
  )
1968
2104
  );
1969
2105
  }
1970
2106
  function get_source_file(ctx, file_path) {
1971
- const source_file = ctx.program.getSourceFile(path4.join(ctx.project_path, file_path));
2107
+ const source_file = ctx.program.getSourceFile(path5.join(ctx.project_path, file_path));
1972
2108
  if (!source_file) return err.new("file_not_found", { path: file_path });
1973
2109
  return source_file;
1974
2110
  }
1975
2111
  function parse_file(ctx, source_file, file_id) {
1976
- const imports2 = [];
2112
+ const imports4 = [];
1977
2113
  const symbols4 = [];
1978
- const external_imports2 = [];
2114
+ const external_imports3 = [];
1979
2115
  function find_dynamic_imports(node) {
1980
2116
  if (is_dynamic_import(node)) {
1981
2117
  const arg = node.arguments[0];
1982
2118
  if (is_external_module(ctx, source_file, arg.text)) {
1983
2119
  const result = extract_external_dynamic_import(ctx, node, file_id);
1984
2120
  if (err.any(result)) return result;
1985
- external_imports2.push(result);
2121
+ external_imports3.push(result);
1986
2122
  } else {
1987
2123
  const result = extract_dynamic_import(ctx, source_file, node, file_id);
1988
- if (result) imports2.push(result);
2124
+ if (result) imports4.push(result);
1989
2125
  }
1990
2126
  }
1991
2127
  ts10.forEachChild(node, find_dynamic_imports);
@@ -1998,24 +2134,24 @@ function parse_file(ctx, source_file, file_id) {
1998
2134
  error = res;
1999
2135
  return;
2000
2136
  }
2001
- imports2.push(...res.imports);
2137
+ imports4.push(...res.imports);
2002
2138
  symbols4.push(...res.symbols);
2003
- external_imports2.push(...res.external_imports);
2139
+ external_imports3.push(...res.external_imports);
2004
2140
  error = find_dynamic_imports(statement);
2005
2141
  });
2006
2142
  if (error) return error;
2007
- return { imports: imports2, symbols: symbols4, external_imports: external_imports2 };
2143
+ return { imports: imports4, symbols: symbols4, external_imports: external_imports3 };
2008
2144
  }
2009
2145
  function parse_node(ctx, source_file, node, file_id) {
2010
- const imports2 = [];
2146
+ const imports4 = [];
2011
2147
  const symbols4 = [];
2012
- const external_imports2 = [];
2148
+ const external_imports3 = [];
2013
2149
  if (is_external_import(ctx, source_file, node)) {
2014
2150
  const result = extract_external_import(ctx, node, file_id);
2015
2151
  if (err.any(result)) return result;
2016
- external_imports2.push(...result);
2152
+ external_imports3.push(...result);
2017
2153
  } else if (is_import(ctx, source_file, node)) {
2018
- imports2.push(...extract_import(ctx, source_file, node, file_id));
2154
+ imports4.push(...extract_import(ctx, source_file, node, file_id));
2019
2155
  } else if (ts10.isExportAssignment(node) && !node.isExportEquals) {
2020
2156
  symbols4.push({
2021
2157
  file_id,
@@ -2057,14 +2193,14 @@ function parse_node(ctx, source_file, node, file_id) {
2057
2193
  symbols4.push(extract_class_symbol(node, file_id, source_file));
2058
2194
  symbols4.push(...extract_class_fields(node, file_id, source_file));
2059
2195
  }
2060
- return { imports: imports2, symbols: symbols4, external_imports: external_imports2 };
2196
+ return { imports: imports4, symbols: symbols4, external_imports: external_imports3 };
2061
2197
  }
2062
2198
 
2063
2199
  // src/update/link_imports.ts
2064
2200
  async function link_imports(ctx) {
2065
- const imports2 = err.or_throw(imports_exports.by_state(ctx, "to_link"));
2201
+ const imports4 = err.or_throw(imports_exports.by_state(ctx, "to_link"));
2066
2202
  let i = 0;
2067
- for (const import_ of imports2) {
2203
+ for (const import_ of imports4) {
2068
2204
  const res = link_import(ctx, import_);
2069
2205
  if (err.any(res)) err.or_throw(imports_exports.update(ctx, import_.id, { error: String(res) }));
2070
2206
  }
@@ -2080,7 +2216,7 @@ function link_import(ctx, import_) {
2080
2216
  }
2081
2217
 
2082
2218
  // src/update/link_symbols.ts
2083
- import path5 from "path";
2219
+ import path6 from "path";
2084
2220
  import ts11 from "typescript";
2085
2221
  async function link_symbols(ctx) {
2086
2222
  const symbols4 = err.or_throw(symbols_exports.by_state(ctx, "to_link"));
@@ -2106,7 +2242,7 @@ function find_symbol_references(ctx, symbol) {
2106
2242
  const file = files_exports.by_id(ctx, symbol.file_id);
2107
2243
  if (err.any(file)) return file;
2108
2244
  if (!file) return err.new("file_not_found", { path: `file_id=${symbol.file_id}` });
2109
- const file_path = path5.join(ctx.project_path, file.path);
2245
+ const file_path = path6.join(ctx.project_path, file.path);
2110
2246
  const source_file = ctx.program.getSourceFile(file_path);
2111
2247
  if (!source_file) return err.new("file_not_found", { path: file_path });
2112
2248
  const symbol_node = find_symbol_node(source_file, symbol);
@@ -2330,19 +2466,19 @@ async function update6(ctx) {
2330
2466
  }
2331
2467
 
2332
2468
  // src/counts.ts
2333
- import { count } from "drizzle-orm";
2334
- var counts = safe_query("counts", (ctx) => {
2335
- const symbol_counts = ctx.db.select({ state: symbols.state, count: count() }).from(symbols).groupBy(symbols.state).all();
2336
- const file_counts = ctx.db.select({ state: files.state, count: count() }).from(files).groupBy(files.state).all();
2337
- const dir_counts = ctx.db.select({ state: directories.state, count: count() }).from(directories).groupBy(directories.state).all();
2338
- const dep_counts = ctx.db.select({ state: external_dependencies.state, count: count() }).from(external_dependencies).groupBy(external_dependencies.state).all();
2469
+ import { count as count10 } from "drizzle-orm";
2470
+ function counts(ctx) {
2471
+ const symbol_counts = ctx.db.select({ state: symbols.state, count: count10() }).from(symbols).groupBy(symbols.state).all();
2472
+ const file_counts = ctx.db.select({ state: files.state, count: count10() }).from(files).groupBy(files.state).all();
2473
+ const dir_counts = ctx.db.select({ state: directories.state, count: count10() }).from(directories).groupBy(directories.state).all();
2474
+ const dep_counts = ctx.db.select({ state: external_dependencies.state, count: count10() }).from(external_dependencies).groupBy(external_dependencies.state).all();
2339
2475
  return {
2340
2476
  symbols: get_groups(symbol_counts, ["to_link", "to_describe", "ready"]),
2341
2477
  files: get_groups(file_counts, ["to_scan", "to_describe", "ready"]),
2342
2478
  directories: get_groups(dir_counts, ["to_describe", "ready"]),
2343
2479
  dependencies: get_groups(dep_counts, ["to_describe", "ready"])
2344
2480
  };
2345
- });
2481
+ }
2346
2482
  function get_groups(items, states) {
2347
2483
  const groups = { total: 0 };
2348
2484
  for (const state of states) groups[state] = 0;
@@ -2358,7 +2494,7 @@ function get_groups(items, states) {
2358
2494
  function files_wiki(ctx) {
2359
2495
  return {
2360
2496
  get: (id) => get2(ctx, id),
2361
- search: (options) => search5(ctx, options),
2497
+ search: (options) => search9(ctx, options),
2362
2498
  set_description: (id, description) => set_description(ctx, id, description),
2363
2499
  imported_by_file: (file_id, options) => imported_by_file(ctx, file_id, options),
2364
2500
  importing_file: (file_id, options) => importing_file(ctx, file_id, options),
@@ -2368,11 +2504,11 @@ function files_wiki(ctx) {
2368
2504
  function get2(ctx, id) {
2369
2505
  return err.or_throw(files_exports.by_id(ctx, id)) ?? null;
2370
2506
  }
2371
- function search5(ctx, options) {
2507
+ function search9(ctx, options) {
2372
2508
  return err.or_throw(files_exports.search(ctx, options));
2373
2509
  }
2374
2510
  function set_description(ctx, id, description) {
2375
- err.or_throw(files_exports.update(ctx, id, { description }));
2511
+ err.or_throw(files_exports.update(ctx, id, { description, state: "ready", error: null }));
2376
2512
  }
2377
2513
  function imported_by_file(ctx, file_id, options = {}) {
2378
2514
  let imported_files = err.or_throw(files_exports.imported_by(ctx, file_id, options.select));
@@ -2424,7 +2560,7 @@ function importing_dependency(ctx, dependency_id, options = {}) {
2424
2560
  function symbols_wiki(ctx) {
2425
2561
  return {
2426
2562
  get: (id) => get3(ctx, id),
2427
- search: (options) => search6(ctx, options),
2563
+ search: (options) => search10(ctx, options),
2428
2564
  set_description: (id, description) => set_description2(ctx, id, description),
2429
2565
  referencing_symbol: (symbol_id, options) => referencing_symbol(ctx, symbol_id, options),
2430
2566
  referenced_by_symbol: (symbol_id, options) => referenced_by_symbol(ctx, symbol_id, options),
@@ -2434,11 +2570,12 @@ function symbols_wiki(ctx) {
2434
2570
  function get3(ctx, id) {
2435
2571
  return err.or_throw(symbols_exports.by_id(ctx, id)) ?? null;
2436
2572
  }
2437
- function search6(ctx, options) {
2573
+ function search10(ctx, options) {
2438
2574
  return err.or_throw(symbols_exports.search(ctx, options));
2439
2575
  }
2440
2576
  function set_description2(ctx, id, description) {
2441
- err.or_throw(symbols_exports.update(ctx, id, { description }));
2577
+ err.or_throw(symbols_exports.update(ctx, id, { description, state: "ready", error: null }));
2578
+ err.or_throw(symbol_internal_links_exports.update_state_by_to_symbol(ctx, id, "ready"));
2442
2579
  }
2443
2580
  function referenced_by_symbol(ctx, symbol_id, options = {}) {
2444
2581
  let referenced_symbols = err.or_throw(symbols_exports.referenced_by(ctx, symbol_id, options.select));
@@ -2490,7 +2627,7 @@ function using_dependency3(ctx, dependency_id, options = {}) {
2490
2627
  function directories_wiki(ctx) {
2491
2628
  return {
2492
2629
  get: (id) => get4(ctx, id),
2493
- search: (options) => search7(ctx, options),
2630
+ search: (options) => search11(ctx, options),
2494
2631
  set_description: (id, description) => set_description3(ctx, id, description),
2495
2632
  children: (parent_id, options) => children(ctx, parent_id, options),
2496
2633
  files: (directory_id, options) => directory_files(ctx, directory_id, options)
@@ -2499,11 +2636,11 @@ function directories_wiki(ctx) {
2499
2636
  function get4(ctx, id) {
2500
2637
  return err.or_throw(directories_exports.by_id(ctx, id)) ?? null;
2501
2638
  }
2502
- function search7(ctx, options) {
2639
+ function search11(ctx, options) {
2503
2640
  return err.or_throw(directories_exports.search(ctx, options));
2504
2641
  }
2505
2642
  function set_description3(ctx, id, description) {
2506
- err.or_throw(directories_exports.update(ctx, id, { description }));
2643
+ err.or_throw(directories_exports.update(ctx, id, { description, state: "ready", error: null }));
2507
2644
  }
2508
2645
  function children(ctx, parent_id, options = {}) {
2509
2646
  let child_directories = err.or_throw(directories_exports.search(ctx, { select: options.select, where: { parent_id }, limit: 1e4 }));
@@ -2546,7 +2683,7 @@ function directory_files(ctx, directory_id, options = {}) {
2546
2683
  function dependencies_wiki(ctx) {
2547
2684
  return {
2548
2685
  get: (id) => get5(ctx, id),
2549
- search: (options) => search8(ctx, options),
2686
+ search: (options) => search12(ctx, options),
2550
2687
  set_description: (id, description) => set_description4(ctx, id, description),
2551
2688
  used_by_file: (file_id, options) => used_by_file2(ctx, file_id, options),
2552
2689
  used_by_symbol: (symbol_id, options) => used_by_symbol2(ctx, symbol_id, options)
@@ -2555,7 +2692,7 @@ function dependencies_wiki(ctx) {
2555
2692
  function get5(ctx, id) {
2556
2693
  return err.or_throw(external_dependencies_exports.by_id(ctx, id)) ?? null;
2557
2694
  }
2558
- function search8(ctx, options) {
2695
+ function search12(ctx, options) {
2559
2696
  return err.or_throw(external_dependencies_exports.search(ctx, options));
2560
2697
  }
2561
2698
  function set_description4(ctx, id, description) {
@@ -2568,13 +2705,88 @@ function used_by_symbol2(ctx, symbol_id, options) {
2568
2705
  return err.or_throw(external_dependencies_exports.used_by_symbol(ctx, symbol_id, options?.select));
2569
2706
  }
2570
2707
 
2708
+ // src/to_describe.ts
2709
+ function to_describe(ctx, limit) {
2710
+ const dependencies_count = err.or_throw(external_dependencies_exports.count(ctx, { state: "to_describe" }));
2711
+ if (dependencies_count > 0) return { type: "dependencies", items: dependencies_to_describe(ctx, limit) };
2712
+ const symbols_count = err.or_throw(symbols_exports.count(ctx, { state: "to_describe" }));
2713
+ if (symbols_count > 0) return { type: "symbols", items: symbols_to_describe(ctx, limit) };
2714
+ const pending_symbols_count = err.or_throw(symbols_exports.count(ctx, { state: "to_link" }));
2715
+ if (pending_symbols_count > 0) throw err.new("could_not_describe_files_due_to_pending_symbols", { count: pending_symbols_count });
2716
+ const files_count = err.or_throw(files_exports.count(ctx, { state: "to_describe" }));
2717
+ if (files_count > 0) return { type: "files", items: files_to_describe(ctx, limit) };
2718
+ const pending_files_count = err.or_throw(files_exports.count(ctx, { state: "to_scan" }));
2719
+ if (pending_files_count > 0) throw err.new("could_not_describe_directories_due_to_pending_files", { count: pending_files_count });
2720
+ const directories_count = err.or_throw(directories_exports.count(ctx, { state: "to_describe" }));
2721
+ if (directories_count > 0) return { type: "directories", items: directories_to_describe(ctx, limit) };
2722
+ return { type: "none" };
2723
+ }
2724
+ function dependencies_to_describe(ctx, limit) {
2725
+ const candidates = err.or_throw(
2726
+ external_dependencies_exports.search(ctx, {
2727
+ where: { state: "to_describe" },
2728
+ select: ["id", "package", "name"],
2729
+ limit: 1e5
2730
+ })
2731
+ );
2732
+ candidates.sort((a, b) => {
2733
+ if (a.package !== b.package) return a.package.localeCompare(b.package);
2734
+ return (a.name || "").localeCompare(b.name || "");
2735
+ });
2736
+ const ids = candidates.slice(0, limit).map((dep) => dep.id);
2737
+ const items = err.or_throw(external_dependencies_exports.by_ids(ctx, ids));
2738
+ const by_id5 = new Map(items.map((item) => [item.id, item]));
2739
+ return ids.map((id) => by_id5.get(id)).filter((item) => !!item);
2740
+ }
2741
+ function symbols_to_describe(ctx, limit) {
2742
+ const candidates = err.or_throw(symbols_exports.search(ctx, { where: { state: "to_describe" }, select: ["id", "text"], limit: 1e5 }));
2743
+ const counts2 = {};
2744
+ for (const symbol of candidates) {
2745
+ counts2[symbol.id] = {
2746
+ length: symbol.text?.length ?? 0,
2747
+ missing_external: err.or_throw(symbol_external_links_exports.count_pending_deps(ctx, symbol.id)),
2748
+ missing_internal: err.or_throw(symbol_internal_links_exports.count(ctx, { from_symbol_id: symbol.id, state: "pending" }))
2749
+ };
2750
+ }
2751
+ candidates.sort((x, y) => {
2752
+ const a = counts2[x.id];
2753
+ const b = counts2[y.id];
2754
+ if (!a || !b) return 0;
2755
+ if (a.missing_internal !== b.missing_internal) return a.missing_internal - b.missing_internal;
2756
+ if (a.missing_external !== b.missing_external) return a.missing_external - b.missing_external;
2757
+ return a.length - b.length;
2758
+ });
2759
+ const ids = candidates.slice(0, limit).map((symbol) => symbol.id);
2760
+ const items = err.or_throw(symbols_exports.by_ids(ctx, ids));
2761
+ const by_id5 = new Map(items.map((item) => [item.id, item]));
2762
+ return ids.map((id) => by_id5.get(id)).filter((item) => !!item);
2763
+ }
2764
+ function files_to_describe(ctx, limit) {
2765
+ return err.or_throw(files_exports.by_state(ctx, "to_describe", limit));
2766
+ }
2767
+ function directories_to_describe(ctx, limit) {
2768
+ const candidates = err.or_throw(
2769
+ directories_exports.search(ctx, {
2770
+ where: { state: "to_describe" },
2771
+ select: ["id", "path"],
2772
+ limit: 1e5
2773
+ })
2774
+ );
2775
+ candidates.sort((a, b) => b.path.split("/").length - a.path.split("/").length);
2776
+ const ids = candidates.slice(0, limit).map((dir) => dir.id);
2777
+ const items = err.or_throw(directories_exports.by_ids(ctx, ids));
2778
+ const by_id5 = new Map(items.map((item) => [item.id, item]));
2779
+ return ids.map((id) => by_id5.get(id)).filter((item) => !!item);
2780
+ }
2781
+
2571
2782
  // src/index.ts
2572
2783
  async function create(config) {
2573
2784
  const ctx = await context_from_config(config);
2574
2785
  return {
2575
2786
  config,
2576
2787
  update: () => update6(ctx),
2577
- counts: () => err.or_throw(counts(ctx)),
2788
+ counts: () => counts(ctx),
2789
+ to_describe: (limit) => to_describe(ctx, limit),
2578
2790
  files: files_wiki(ctx),
2579
2791
  symbols: symbols_wiki(ctx),
2580
2792
  directories: directories_wiki(ctx),
@@ -2594,7 +2806,8 @@ async function load(db_path) {
2594
2806
  return {
2595
2807
  config,
2596
2808
  update: () => update6(ctx),
2597
- counts: () => err.or_throw(counts(ctx)),
2809
+ counts: () => counts(ctx),
2810
+ to_describe: (limit) => to_describe(ctx, limit),
2598
2811
  files: files_wiki(ctx),
2599
2812
  symbols: symbols_wiki(ctx),
2600
2813
  directories: directories_wiki(ctx),
@@ -2643,8 +2856,8 @@ function parse_options(options_json, schema, context) {
2643
2856
  env.log(`Error: Invalid options format in ${context}`);
2644
2857
  env.log("");
2645
2858
  for (const issue of validation_result.error.issues) {
2646
- const path6 = issue.path.length > 0 ? issue.path.join(".") : "root";
2647
- env.log(` \u2022 ${path6}: ${issue.message}`);
2859
+ const path7 = issue.path.length > 0 ? issue.path.join(".") : "root";
2860
+ env.log(` \u2022 ${path7}: ${issue.message}`);
2648
2861
  }
2649
2862
  env.log("");
2650
2863
  env.log(`Run 'codewiki ${context.split(" ")[0]} --help' for usage information`);
@@ -2774,10 +2987,10 @@ get6.action(async (id) => {
2774
2987
 
2775
2988
  // src/cli/commands/files/search.ts
2776
2989
  import { Command as Command5 } from "commander";
2777
- var search9 = new Command5("search");
2778
- search9.description("Search files with JSON options");
2779
- search9.argument("<options>", "JSON options for search");
2780
- search9.action(async (options_json) => {
2990
+ var search13 = new Command5("search");
2991
+ search13.description("Search files with JSON options");
2992
+ search13.argument("<options>", "JSON options for search");
2993
+ search13.action(async (options_json) => {
2781
2994
  const wiki = await load_wiki();
2782
2995
  const options = parse_options(options_json, FileSearchOptions, "files search");
2783
2996
  const results = wiki.files.search(options);
@@ -2846,7 +3059,7 @@ importing_dependency2.action(async (dep_id, options_json) => {
2846
3059
  var files3 = new Command10("files");
2847
3060
  files3.description("Explore files");
2848
3061
  files3.addCommand(get6);
2849
- files3.addCommand(search9);
3062
+ files3.addCommand(search13);
2850
3063
  files3.addCommand(set_description5);
2851
3064
  files3.addCommand(imported_by_file2);
2852
3065
  files3.addCommand(importing_file2);
@@ -2897,10 +3110,10 @@ get7.action(async (id) => {
2897
3110
 
2898
3111
  // src/cli/commands/symbols/search.ts
2899
3112
  import { Command as Command12 } from "commander";
2900
- var search10 = new Command12("search");
2901
- search10.description("Search symbols with JSON options");
2902
- search10.argument("<options>", "JSON options");
2903
- search10.action(async (options_json) => {
3113
+ var search14 = new Command12("search");
3114
+ search14.description("Search symbols with JSON options");
3115
+ search14.argument("<options>", "JSON options");
3116
+ search14.action(async (options_json) => {
2904
3117
  const wiki = await load_wiki();
2905
3118
  const options = parse_options(options_json, SymbolSearchOptions, "symbols search");
2906
3119
  const results = wiki.symbols.search(options);
@@ -2969,7 +3182,7 @@ using_dependency4.action(async (dep_id, options_json) => {
2969
3182
  var symbols3 = new Command17("symbols");
2970
3183
  symbols3.description("Explore symbols");
2971
3184
  symbols3.addCommand(get7);
2972
- symbols3.addCommand(search10);
3185
+ symbols3.addCommand(search14);
2973
3186
  symbols3.addCommand(set_description6);
2974
3187
  symbols3.addCommand(referencing_symbol2);
2975
3188
  symbols3.addCommand(referenced_by_symbol2);
@@ -3020,10 +3233,10 @@ get8.action(async (id) => {
3020
3233
 
3021
3234
  // src/cli/commands/directories/search.ts
3022
3235
  import { Command as Command19 } from "commander";
3023
- var search11 = new Command19("search");
3024
- search11.description("Search directories with JSON options");
3025
- search11.argument("<options>", "JSON options");
3026
- search11.action(async (options_json) => {
3236
+ var search15 = new Command19("search");
3237
+ search15.description("Search directories with JSON options");
3238
+ search15.argument("<options>", "JSON options");
3239
+ search15.action(async (options_json) => {
3027
3240
  const wiki = await load_wiki();
3028
3241
  const options = parse_options(options_json, DirectorySearchOptions, "directories search");
3029
3242
  const results = wiki.directories.search(options);
@@ -3079,7 +3292,7 @@ files4.action(async (directory_id, options_json) => {
3079
3292
  var directories3 = new Command23("directories");
3080
3293
  directories3.description("Explore directories");
3081
3294
  directories3.addCommand(get8);
3082
- directories3.addCommand(search11);
3295
+ directories3.addCommand(search15);
3083
3296
  directories3.addCommand(set_description7);
3084
3297
  directories3.addCommand(children2);
3085
3298
  directories3.addCommand(files4);
@@ -3129,10 +3342,10 @@ get9.action(async (id) => {
3129
3342
 
3130
3343
  // src/cli/commands/dependencies/search.ts
3131
3344
  import { Command as Command25 } from "commander";
3132
- var search12 = new Command25("search");
3133
- search12.description("Search dependencies with JSON options");
3134
- search12.argument("<options>", "JSON options");
3135
- search12.action(async (options_json) => {
3345
+ var search16 = new Command25("search");
3346
+ search16.description("Search dependencies with JSON options");
3347
+ search16.argument("<options>", "JSON options");
3348
+ search16.action(async (options_json) => {
3136
3349
  const wiki = await load_wiki();
3137
3350
  const options = parse_options(options_json, DependencySearchOptions, "dependencies search");
3138
3351
  const results = wiki.dependencies.search(options);
@@ -3188,7 +3401,7 @@ used_by_symbol3.action(async (symbol_id, options_json) => {
3188
3401
  var dependencies = new Command29("dependencies");
3189
3402
  dependencies.description("Explore dependencies");
3190
3403
  dependencies.addCommand(get9);
3191
- dependencies.addCommand(search12);
3404
+ dependencies.addCommand(search16);
3192
3405
  dependencies.addCommand(set_description8);
3193
3406
  dependencies.addCommand(used_by_file3);
3194
3407
  dependencies.addCommand(used_by_symbol3);