sensemaking 0.24.7 → 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.
Files changed (242) hide show
  1. package/README.md +20 -11
  2. package/dist/cjs/cli/build.d.cts +3 -0
  3. package/dist/cjs/cli/build.d.ts +3 -0
  4. package/dist/cjs/cli/build.js +195 -0
  5. package/dist/cjs/cli/build.js.map +1 -0
  6. package/dist/cjs/cli/index.d.cts +7 -6
  7. package/dist/cjs/cli/index.d.ts +7 -6
  8. package/dist/cjs/cli/index.js +12 -6
  9. package/dist/cjs/cli/index.js.map +1 -1
  10. package/dist/cjs/cli/init.js +2 -2
  11. package/dist/cjs/cli/init.js.map +1 -1
  12. package/dist/cjs/cli/map.js +7 -2
  13. package/dist/cjs/cli/map.js.map +1 -1
  14. package/dist/cjs/cli/named.js +63 -21
  15. package/dist/cjs/cli/named.js.map +1 -1
  16. package/dist/cjs/cli/path.js +7 -2
  17. package/dist/cjs/cli/path.js.map +1 -1
  18. package/dist/cjs/cli/peek.js +7 -2
  19. package/dist/cjs/cli/peek.js.map +1 -1
  20. package/dist/cjs/cli/related.js +55 -6
  21. package/dist/cjs/cli/related.js.map +1 -1
  22. package/dist/cjs/cli/search.js +54 -15
  23. package/dist/cjs/cli/search.js.map +1 -1
  24. package/dist/cjs/cli/shared.d.cts +9 -3
  25. package/dist/cjs/cli/shared.d.ts +9 -3
  26. package/dist/cjs/cli/shared.js +109 -74
  27. package/dist/cjs/cli/shared.js.map +1 -1
  28. package/dist/cjs/cli/sql.js +8 -3
  29. package/dist/cjs/cli/sql.js.map +1 -1
  30. package/dist/cjs/cli/status.js +142 -50
  31. package/dist/cjs/cli/status.js.map +1 -1
  32. package/dist/cjs/cli/types.d.cts +4 -2
  33. package/dist/cjs/cli/types.d.ts +4 -2
  34. package/dist/cjs/cli.js +10 -4
  35. package/dist/cjs/cli.js.map +1 -1
  36. package/dist/cjs/commands/map.js +10 -6
  37. package/dist/cjs/commands/map.js.map +1 -1
  38. package/dist/cjs/commands/peek.js +10 -6
  39. package/dist/cjs/commands/peek.js.map +1 -1
  40. package/dist/cjs/commands/related.d.cts +1 -0
  41. package/dist/cjs/commands/related.d.ts +1 -0
  42. package/dist/cjs/commands/related.js +56 -21
  43. package/dist/cjs/commands/related.js.map +1 -1
  44. package/dist/cjs/commands/scope.js +1 -1
  45. package/dist/cjs/commands/scope.js.map +1 -1
  46. package/dist/cjs/commands/search.js +102 -84
  47. package/dist/cjs/commands/search.js.map +1 -1
  48. package/dist/cjs/config/index.d.cts +1 -1
  49. package/dist/cjs/config/index.d.ts +1 -1
  50. package/dist/cjs/config/index.js.map +1 -1
  51. package/dist/cjs/config/load.d.cts +6 -1
  52. package/dist/cjs/config/load.d.ts +6 -1
  53. package/dist/cjs/config/load.js +38 -1
  54. package/dist/cjs/config/load.js.map +1 -1
  55. package/dist/cjs/config/types.d.cts +2 -1
  56. package/dist/cjs/config/types.d.ts +2 -1
  57. package/dist/cjs/config/types.js +1 -1
  58. package/dist/cjs/config/types.js.map +1 -1
  59. package/dist/cjs/config/validate.js +20 -0
  60. package/dist/cjs/config/validate.js.map +1 -1
  61. package/dist/cjs/embed/query.d.cts +2 -1
  62. package/dist/cjs/embed/query.d.ts +2 -1
  63. package/dist/cjs/embed/query.js +186 -109
  64. package/dist/cjs/embed/query.js.map +1 -1
  65. package/dist/cjs/errors.d.cts +1 -1
  66. package/dist/cjs/errors.d.ts +1 -1
  67. package/dist/cjs/errors.js.map +1 -1
  68. package/dist/cjs/features/embed.js.map +1 -1
  69. package/dist/cjs/graph/traverse.js +11 -6
  70. package/dist/cjs/graph/traverse.js.map +1 -1
  71. package/dist/cjs/index.d.cts +3 -3
  72. package/dist/cjs/index.d.ts +3 -3
  73. package/dist/cjs/index.js +3 -0
  74. package/dist/cjs/index.js.map +1 -1
  75. package/dist/cjs/lib/atomic-write.js +20 -6
  76. package/dist/cjs/lib/atomic-write.js.map +1 -1
  77. package/dist/cjs/lib/serial-query.d.cts +1 -0
  78. package/dist/cjs/lib/serial-query.d.ts +1 -0
  79. package/dist/cjs/lib/serial-query.js +22 -0
  80. package/dist/cjs/lib/serial-query.js.map +1 -0
  81. package/dist/cjs/scan/index.d.cts +5 -0
  82. package/dist/cjs/scan/index.d.ts +5 -0
  83. package/dist/cjs/scan/index.js +12 -4
  84. package/dist/cjs/scan/index.js.map +1 -1
  85. package/dist/cjs/scan/pool.d.cts +5 -0
  86. package/dist/cjs/scan/pool.d.ts +5 -0
  87. package/dist/cjs/scan/pool.js +167 -55
  88. package/dist/cjs/scan/pool.js.map +1 -1
  89. package/dist/cjs/store/builder.d.cts +6 -1
  90. package/dist/cjs/store/builder.d.ts +6 -1
  91. package/dist/cjs/store/builder.js +135 -5
  92. package/dist/cjs/store/builder.js.map +1 -1
  93. package/dist/cjs/store/duckdb/lexical.d.cts +2 -0
  94. package/dist/cjs/store/duckdb/lexical.d.ts +2 -0
  95. package/dist/cjs/store/duckdb/lexical.js +139 -7
  96. package/dist/cjs/store/duckdb/lexical.js.map +1 -1
  97. package/dist/cjs/store/duckdb/open.d.cts +3 -3
  98. package/dist/cjs/store/duckdb/open.d.ts +3 -3
  99. package/dist/cjs/store/duckdb/open.js +53 -41
  100. package/dist/cjs/store/duckdb/open.js.map +1 -1
  101. package/dist/cjs/store/duckdb/reconcile.js +2 -2
  102. package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
  103. package/dist/cjs/store/index.d.cts +23 -4
  104. package/dist/cjs/store/index.d.ts +23 -4
  105. package/dist/cjs/store/index.js +224 -15
  106. package/dist/cjs/store/index.js.map +1 -1
  107. package/dist/cjs/store/open.d.cts +9 -1
  108. package/dist/cjs/store/open.d.ts +9 -1
  109. package/dist/cjs/store/open.js +479 -128
  110. package/dist/cjs/store/open.js.map +1 -1
  111. package/dist/cjs/store/reconcile.js +93 -63
  112. package/dist/cjs/store/reconcile.js.map +1 -1
  113. package/dist/cjs/store/sqlite/open.d.cts +3 -3
  114. package/dist/cjs/store/sqlite/open.d.ts +3 -3
  115. package/dist/cjs/store/sqlite/open.js +44 -36
  116. package/dist/cjs/store/sqlite/open.js.map +1 -1
  117. package/dist/cjs/store/turso/open.d.cts +3 -3
  118. package/dist/cjs/store/turso/open.d.ts +3 -3
  119. package/dist/cjs/store/turso/open.js +83 -66
  120. package/dist/cjs/store/turso/open.js.map +1 -1
  121. package/dist/cjs/store/turso/store.d.cts +3 -1
  122. package/dist/cjs/store/turso/store.d.ts +3 -1
  123. package/dist/cjs/store/turso/store.js +46 -31
  124. package/dist/cjs/store/turso/store.js.map +1 -1
  125. package/dist/cjs/store/types.d.cts +12 -3
  126. package/dist/cjs/store/types.d.ts +12 -3
  127. package/dist/cjs/store/types.js.map +1 -1
  128. package/dist/cjs/watch.js +155 -35
  129. package/dist/cjs/watch.js.map +1 -1
  130. package/dist/esm/cli/build.d.ts +3 -0
  131. package/dist/esm/cli/build.js +18 -0
  132. package/dist/esm/cli/build.js.map +1 -0
  133. package/dist/esm/cli/index.d.ts +7 -6
  134. package/dist/esm/cli/index.js +8 -6
  135. package/dist/esm/cli/index.js.map +1 -1
  136. package/dist/esm/cli/init.js +2 -2
  137. package/dist/esm/cli/init.js.map +1 -1
  138. package/dist/esm/cli/map.js +8 -2
  139. package/dist/esm/cli/map.js.map +1 -1
  140. package/dist/esm/cli/named.js +38 -14
  141. package/dist/esm/cli/named.js.map +1 -1
  142. package/dist/esm/cli/path.js +8 -2
  143. package/dist/esm/cli/path.js.map +1 -1
  144. package/dist/esm/cli/peek.js +8 -2
  145. package/dist/esm/cli/peek.js.map +1 -1
  146. package/dist/esm/cli/related.js +21 -3
  147. package/dist/esm/cli/related.js.map +1 -1
  148. package/dist/esm/cli/search.js +28 -7
  149. package/dist/esm/cli/search.js.map +1 -1
  150. package/dist/esm/cli/shared.d.ts +9 -3
  151. package/dist/esm/cli/shared.js +44 -24
  152. package/dist/esm/cli/shared.js.map +1 -1
  153. package/dist/esm/cli/sql.js +8 -2
  154. package/dist/esm/cli/sql.js.map +1 -1
  155. package/dist/esm/cli/status.js +166 -111
  156. package/dist/esm/cli/status.js.map +1 -1
  157. package/dist/esm/cli/types.d.ts +4 -2
  158. package/dist/esm/cli/types.js.map +1 -1
  159. package/dist/esm/cli.js +9 -4
  160. package/dist/esm/cli.js.map +1 -1
  161. package/dist/esm/commands/map.js +5 -1
  162. package/dist/esm/commands/map.js.map +1 -1
  163. package/dist/esm/commands/peek.js +5 -1
  164. package/dist/esm/commands/peek.js.map +1 -1
  165. package/dist/esm/commands/related.d.ts +1 -0
  166. package/dist/esm/commands/related.js +19 -10
  167. package/dist/esm/commands/related.js.map +1 -1
  168. package/dist/esm/commands/scope.js +1 -1
  169. package/dist/esm/commands/scope.js.map +1 -1
  170. package/dist/esm/commands/search.js +11 -10
  171. package/dist/esm/commands/search.js.map +1 -1
  172. package/dist/esm/config/index.d.ts +1 -1
  173. package/dist/esm/config/index.js.map +1 -1
  174. package/dist/esm/config/load.d.ts +6 -1
  175. package/dist/esm/config/load.js +32 -3
  176. package/dist/esm/config/load.js.map +1 -1
  177. package/dist/esm/config/types.d.ts +2 -1
  178. package/dist/esm/config/types.js +1 -1
  179. package/dist/esm/config/types.js.map +1 -1
  180. package/dist/esm/config/validate.js +20 -0
  181. package/dist/esm/config/validate.js.map +1 -1
  182. package/dist/esm/embed/query.d.ts +2 -1
  183. package/dist/esm/embed/query.js +40 -34
  184. package/dist/esm/embed/query.js.map +1 -1
  185. package/dist/esm/errors.d.ts +1 -1
  186. package/dist/esm/errors.js.map +1 -1
  187. package/dist/esm/features/embed.js.map +1 -1
  188. package/dist/esm/graph/traverse.js +5 -1
  189. package/dist/esm/graph/traverse.js.map +1 -1
  190. package/dist/esm/index.d.ts +3 -3
  191. package/dist/esm/index.js +1 -1
  192. package/dist/esm/index.js.map +1 -1
  193. package/dist/esm/lib/atomic-write.js +14 -6
  194. package/dist/esm/lib/atomic-write.js.map +1 -1
  195. package/dist/esm/lib/serial-query.d.ts +1 -0
  196. package/dist/esm/lib/serial-query.js +13 -0
  197. package/dist/esm/lib/serial-query.js.map +1 -0
  198. package/dist/esm/scan/index.d.ts +5 -0
  199. package/dist/esm/scan/index.js +7 -3
  200. package/dist/esm/scan/index.js.map +1 -1
  201. package/dist/esm/scan/pool.d.ts +5 -0
  202. package/dist/esm/scan/pool.js +41 -16
  203. package/dist/esm/scan/pool.js.map +1 -1
  204. package/dist/esm/store/builder.d.ts +6 -1
  205. package/dist/esm/store/builder.js +19 -0
  206. package/dist/esm/store/builder.js.map +1 -1
  207. package/dist/esm/store/duckdb/lexical.d.ts +2 -0
  208. package/dist/esm/store/duckdb/lexical.js +32 -4
  209. package/dist/esm/store/duckdb/lexical.js.map +1 -1
  210. package/dist/esm/store/duckdb/open.d.ts +3 -3
  211. package/dist/esm/store/duckdb/open.js +13 -6
  212. package/dist/esm/store/duckdb/open.js.map +1 -1
  213. package/dist/esm/store/duckdb/reconcile.js +2 -2
  214. package/dist/esm/store/duckdb/reconcile.js.map +1 -1
  215. package/dist/esm/store/index.d.ts +23 -4
  216. package/dist/esm/store/index.js +80 -15
  217. package/dist/esm/store/index.js.map +1 -1
  218. package/dist/esm/store/open.d.ts +9 -1
  219. package/dist/esm/store/open.js +175 -84
  220. package/dist/esm/store/open.js.map +1 -1
  221. package/dist/esm/store/reconcile.js +12 -0
  222. package/dist/esm/store/reconcile.js.map +1 -1
  223. package/dist/esm/store/sqlite/open.d.ts +3 -3
  224. package/dist/esm/store/sqlite/open.js +9 -6
  225. package/dist/esm/store/sqlite/open.js.map +1 -1
  226. package/dist/esm/store/turso/open.d.ts +3 -3
  227. package/dist/esm/store/turso/open.js +14 -10
  228. package/dist/esm/store/turso/open.js.map +1 -1
  229. package/dist/esm/store/turso/store.d.ts +3 -1
  230. package/dist/esm/store/turso/store.js +5 -1
  231. package/dist/esm/store/turso/store.js.map +1 -1
  232. package/dist/esm/store/types.d.ts +12 -3
  233. package/dist/esm/store/types.js.map +1 -1
  234. package/dist/esm/watch.js +57 -19
  235. package/dist/esm/watch.js.map +1 -1
  236. package/package.json +1 -1
  237. package/schema.json +7 -2
  238. package/skills/sense/SKILL.md +3 -3
  239. package/skills/sense-bases/SKILL.md +1 -2
  240. package/skills/sense-setup/SKILL.md +1 -1
  241. package/skills/sense-setup/references/embeddings.md +1 -1
  242. package/skills/sense-setup/references/store-benchmarks.md +6 -6
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/graph/traverse.ts"],"sourcesContent":["// Frontier-by-frontier BFS through a temp visited table, one indexed anti-join per ring: a\n// local question touches a neighborhood, never the whole edge list.\nimport type { Store } from '../store/types.ts';\n\ntype Direction = 'forward' | 'reverse' | 'both';\n\ninterface FindPathOptions {\n directed?: boolean;\n maxDepth?: number;\n allowed?: Set<string>;\n}\n\nasync function resetVisited(store: Store): Promise<void> {\n await store.exec('DROP TABLE IF EXISTS temp.visited');\n await store.exec('CREATE TEMP TABLE visited (path TEXT PRIMARY KEY, depth INTEGER NOT NULL, pred TEXT)');\n}\n\n// Materializes the caller-resolved scope Set into a temp table so it joins like any other\n// indexed column. `extra`, when given, is always in scope -- findPath's `to` endpoint.\nasync function setupAllowed(store: Store, allowed: Set<string>, extra?: string): Promise<void> {\n const all = new Set(allowed);\n if (extra !== undefined) all.add(extra);\n await store.exec('DROP TABLE IF EXISTS temp.allowed_nodes');\n await store.exec('CREATE TEMP TABLE allowed_nodes (path TEXT PRIMARY KEY)');\n await store.runBatch(\n 'INSERT INTO allowed_nodes (path) VALUES (?)',\n [...all].map((p) => [p])\n );\n}\n\n// Only resolved links (dst IS NOT NULL) are followed, in either direction.\nfunction candidateSelect(direction: Direction): string {\n const forward = 'SELECT l.dst AS path, l.src AS pred FROM links l JOIN visited v ON v.path = l.src AND v.depth = ?1 WHERE l.dst IS NOT NULL';\n const reverse = 'SELECT l.src AS path, l.dst AS pred FROM links l JOIN visited v ON v.path = l.dst AND v.depth = ?1 WHERE l.dst IS NOT NULL';\n if (direction === 'forward') return forward;\n if (direction === 'reverse') return reverse;\n return `${forward} UNION ALL ${reverse}`;\n}\n\n// One ring: candidates adjacent to the previous ring's frontier (?1), anti-joined against\n// everything already visited, optionally filtered to the allowed set, inserted at the new depth (?2); RETURNING gives what this ring newly reached.\nfunction ringSql(direction: Direction, hasAllowed: boolean): string {\n return `\nINSERT INTO visited (path, depth, pred)\nSELECT cand.path, ?2, MIN(cand.pred)\nFROM (${candidateSelect(direction)}) cand\nWHERE NOT EXISTS (SELECT 1 FROM visited v2 WHERE v2.path = cand.path)\n${hasAllowed ? 'AND EXISTS (SELECT 1 FROM allowed_nodes a WHERE a.path = cand.path)' : ''}\nGROUP BY cand.path\nORDER BY cand.path\nRETURNING path`;\n}\n\nasync function reconstructPath(store: Store, to: string): Promise<string[]> {\n const lookup = await store.prepare('SELECT pred FROM visited WHERE path = ?');\n const path: string[] = [];\n let cur: string | null = to;\n while (cur !== null) {\n path.push(cur);\n const row = (await lookup.get(cur)) as { pred: string | null } | undefined;\n cur = row ? row.pred : null;\n }\n return path.reverse();\n}\n\n// One BFS from `from`, tracking a predecessor per node. Undirected by default, matching\n// personalizedRank; null when `to` is unreached within `maxDepth`.\nexport async function findPath(store: Store, from: string, to: string, opts: FindPathOptions = {}): Promise<string[] | null> {\n if (from === to) return [from];\n\n const direction: Direction = opts.directed ? 'forward' : 'both';\n const maxDepth = opts.maxDepth ?? Infinity;\n if (maxDepth <= 0) return null;\n\n await resetVisited(store);\n const insertStart = await store.prepare('INSERT INTO visited (path, depth, pred) VALUES (?, 0, NULL)');\n await insertStart.run(from);\n if (opts.allowed) await setupAllowed(store, opts.allowed, to);\n\n const stmt = await store.prepare(ringSql(direction, !!opts.allowed));\n for (let ring = 1; ring <= maxDepth; ring++) {\n const rows = (await stmt.all(ring - 1, ring)) as Array<{ path: string }>;\n if (rows.length === 0) break;\n if (rows.some((row) => row.path === to)) return reconstructPath(store, to);\n }\n return null;\n}\n"],"names":["findPath","resetVisited","store","exec","setupAllowed","allowed","extra","all","Set","undefined","add","runBatch","map","p","candidateSelect","direction","forward","reverse","ringSql","hasAllowed","reconstructPath","to","lookup","path","cur","row","prepare","push","get","pred","from","opts","maxDepth","insertStart","stmt","ring","rows","directed","Infinity","run","length","some"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/graph/traverse.ts"],"sourcesContent":["// Frontier-by-frontier BFS through a temp visited table, one indexed anti-join per ring: a\n// local question touches a neighborhood, never the whole edge list.\n\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { Store } from '../store/types.ts';\n\ntype Direction = 'forward' | 'reverse' | 'both';\n\ninterface FindPathOptions {\n directed?: boolean;\n maxDepth?: number;\n allowed?: Set<string>;\n}\n\nasync function resetVisited(store: Store): Promise<void> {\n await store.exec('DROP TABLE IF EXISTS temp.visited');\n await store.exec('CREATE TEMP TABLE visited (path TEXT PRIMARY KEY, depth INTEGER NOT NULL, pred TEXT)');\n}\n\n// Materializes the caller-resolved scope Set into a temp table so it joins like any other\n// indexed column. `extra`, when given, is always in scope -- findPath's `to` endpoint.\nasync function setupAllowed(store: Store, allowed: Set<string>, extra?: string): Promise<void> {\n const all = new Set(allowed);\n if (extra !== undefined) all.add(extra);\n await store.exec('DROP TABLE IF EXISTS temp.allowed_nodes');\n await store.exec('CREATE TEMP TABLE allowed_nodes (path TEXT PRIMARY KEY)');\n await store.runBatch(\n 'INSERT INTO allowed_nodes (path) VALUES (?)',\n [...all].map((p) => [p])\n );\n}\n\n// Only resolved links (dst IS NOT NULL) are followed, in either direction.\nfunction candidateSelect(direction: Direction): string {\n const forward = 'SELECT l.dst AS path, l.src AS pred FROM links l JOIN visited v ON v.path = l.src AND v.depth = ?1 WHERE l.dst IS NOT NULL';\n const reverse = 'SELECT l.src AS path, l.dst AS pred FROM links l JOIN visited v ON v.path = l.dst AND v.depth = ?1 WHERE l.dst IS NOT NULL';\n if (direction === 'forward') return forward;\n if (direction === 'reverse') return reverse;\n return `${forward} UNION ALL ${reverse}`;\n}\n\n// One ring: candidates adjacent to the previous ring's frontier (?1), anti-joined against\n// everything already visited, optionally filtered to the allowed set, inserted at the new depth (?2); RETURNING gives what this ring newly reached.\nfunction ringSql(direction: Direction, hasAllowed: boolean): string {\n return `\nINSERT INTO visited (path, depth, pred)\nSELECT cand.path, ?2, MIN(cand.pred)\nFROM (${candidateSelect(direction)}) cand\nWHERE NOT EXISTS (SELECT 1 FROM visited v2 WHERE v2.path = cand.path)\n${hasAllowed ? 'AND EXISTS (SELECT 1 FROM allowed_nodes a WHERE a.path = cand.path)' : ''}\nGROUP BY cand.path\nORDER BY cand.path\nRETURNING path`;\n}\n\nasync function reconstructPath(store: Store, to: string): Promise<string[]> {\n const lookup = await store.prepare('SELECT pred FROM visited WHERE path = ?');\n const path: string[] = [];\n let cur: string | null = to;\n while (cur !== null) {\n path.push(cur);\n const row = (await lookup.get(cur)) as { pred: string | null } | undefined;\n cur = row ? row.pred : null;\n }\n return path.reverse();\n}\n\n// One BFS from `from`, tracking a predecessor per node. Undirected by default, matching\n// personalizedRank; null when `to` is unreached within `maxDepth`.\nexport function findPath(store: Store, from: string, to: string, opts: FindPathOptions = {}): Promise<string[] | null> {\n return serialQuery(store, () => findIndexedPath(store, from, to, opts));\n}\n\nasync function findIndexedPath(store: Store, from: string, to: string, opts: FindPathOptions): Promise<string[] | null> {\n if (from === to) return [from];\n\n const direction: Direction = opts.directed ? 'forward' : 'both';\n const maxDepth = opts.maxDepth ?? Infinity;\n if (maxDepth <= 0) return null;\n\n await resetVisited(store);\n const insertStart = await store.prepare('INSERT INTO visited (path, depth, pred) VALUES (?, 0, NULL)');\n await insertStart.run(from);\n if (opts.allowed) await setupAllowed(store, opts.allowed, to);\n\n const stmt = await store.prepare(ringSql(direction, !!opts.allowed));\n for (let ring = 1; ring <= maxDepth; ring++) {\n const rows = (await stmt.all(ring - 1, ring)) as Array<{ path: string }>;\n if (rows.length === 0) break;\n if (rows.some((row) => row.path === to)) return reconstructPath(store, to);\n }\n return null;\n}\n"],"names":["findPath","resetVisited","store","exec","setupAllowed","allowed","extra","all","Set","undefined","add","runBatch","map","p","candidateSelect","direction","forward","reverse","ringSql","hasAllowed","reconstructPath","to","lookup","path","cur","row","prepare","push","get","pred","from","opts","serialQuery","findIndexedPath","maxDepth","insertStart","stmt","ring","rows","directed","Infinity","run","length","some"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
1
  export type { Peek, PresetCoverage, SearchOptions, TreeMap } from './commands/index.js';
2
2
  export { mapTree, peek, presetCoverage, search } from './commands/index.js';
3
- export type { Config, EmbedConfig, FeatureName, InitOverrides, Preset, ResolvedConfig, SavedQuery, SavedSearch, SearchOverrides, SignalName, SignalWeights, StoreName } from './config/index.js';
3
+ export type { Config, EmbedConfig, FeatureName, InitOverrides, LoadConfigOptions, Preset, ResolvedConfig, SavedQuery, SavedSearch, SearchOverrides, SignalName, SignalWeights, StoreName } from './config/index.js';
4
4
  export { CONFIG_FILENAME, initConfig, loadConfig, migrateConfig, SIGNAL_NAMES, STATE_DIR, STORE_NAMES, SUPPORTED_CONFIG_VERSION } from './config/index.js';
5
5
  export type { SenseErrorCode } from './errors.js';
6
6
  export { SenseError } from './errors.js';
7
7
  export type { Format, Row, RowFormat } from './output/output.js';
8
8
  export { printRows } from './output/output.js';
9
- export type { OpenResult, Stages } from './store/index.js';
10
- export { CAPABILITY_NAMES, clearCache, openStore as open } from './store/index.js';
9
+ export type { BuildOptions, BuildResult, OpenOptions, OpenResult, Stages } from './store/index.js';
10
+ export { buildIndex as build, CAPABILITY_NAMES, clearCache, openStore as open } from './store/index.js';
11
11
  export type { Capability, DocumentStore, FieldStat, LexicalHit, LexicalIndex, LexicalQueryOptions, RawStatement, RunResult, SqlSession, Statement, Store, VectorCandidate, VectorSimilar, VectorStore, VectorWriteRow } from './store/types.js';
12
12
  export type { WatchEvent, WatchOptions } from './watch.js';
13
13
  export { runWatch } from './watch.js';
@@ -1,13 +1,13 @@
1
1
  export type { Peek, PresetCoverage, SearchOptions, TreeMap } from './commands/index.js';
2
2
  export { mapTree, peek, presetCoverage, search } from './commands/index.js';
3
- export type { Config, EmbedConfig, FeatureName, InitOverrides, Preset, ResolvedConfig, SavedQuery, SavedSearch, SearchOverrides, SignalName, SignalWeights, StoreName } from './config/index.js';
3
+ export type { Config, EmbedConfig, FeatureName, InitOverrides, LoadConfigOptions, Preset, ResolvedConfig, SavedQuery, SavedSearch, SearchOverrides, SignalName, SignalWeights, StoreName } from './config/index.js';
4
4
  export { CONFIG_FILENAME, initConfig, loadConfig, migrateConfig, SIGNAL_NAMES, STATE_DIR, STORE_NAMES, SUPPORTED_CONFIG_VERSION } from './config/index.js';
5
5
  export type { SenseErrorCode } from './errors.js';
6
6
  export { SenseError } from './errors.js';
7
7
  export type { Format, Row, RowFormat } from './output/output.js';
8
8
  export { printRows } from './output/output.js';
9
- export type { OpenResult, Stages } from './store/index.js';
10
- export { CAPABILITY_NAMES, clearCache, openStore as open } from './store/index.js';
9
+ export type { BuildOptions, BuildResult, OpenOptions, OpenResult, Stages } from './store/index.js';
10
+ export { buildIndex as build, CAPABILITY_NAMES, clearCache, openStore as open } from './store/index.js';
11
11
  export type { Capability, DocumentStore, FieldStat, LexicalHit, LexicalIndex, LexicalQueryOptions, RawStatement, RunResult, SqlSession, Statement, Store, VectorCandidate, VectorSimilar, VectorStore, VectorWriteRow } from './store/types.js';
12
12
  export type { WatchEvent, WatchOptions } from './watch.js';
13
13
  export { runWatch } from './watch.js';
package/dist/cjs/index.js CHANGED
@@ -32,6 +32,9 @@ _export(exports, {
32
32
  get SenseError () {
33
33
  return _errorsts.SenseError;
34
34
  },
35
+ get build () {
36
+ return _indexts2.buildIndex;
37
+ },
35
38
  get clearCache () {
36
39
  return _indexts2.clearCache;
37
40
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/index.ts"],"sourcesContent":["// Public library API. Deliberately small: every export is a stability promise;\n// internals (feature registry, graph, scan, meta) stay module-private.\n\nexport type { Peek, PresetCoverage, SearchOptions, TreeMap } from './commands/index.ts';\nexport { mapTree, peek, presetCoverage, search } from './commands/index.ts';\nexport type { Config, EmbedConfig, FeatureName, InitOverrides, Preset, ResolvedConfig, SavedQuery, SavedSearch, SearchOverrides, SignalName, SignalWeights, StoreName } from './config/index.ts';\nexport { CONFIG_FILENAME, initConfig, loadConfig, migrateConfig, SIGNAL_NAMES, STATE_DIR, STORE_NAMES, SUPPORTED_CONFIG_VERSION } from './config/index.ts';\nexport type { SenseErrorCode } from './errors.ts';\nexport { SenseError } from './errors.ts';\nexport type { Format, Row, RowFormat } from './output/output.ts';\nexport { printRows } from './output/output.ts';\nexport type { OpenResult, Stages } from './store/index.ts';\nexport { CAPABILITY_NAMES, clearCache, openStore as open } from './store/index.ts';\nexport type { Capability, DocumentStore, FieldStat, LexicalHit, LexicalIndex, LexicalQueryOptions, RawStatement, RunResult, SqlSession, Statement, Store, VectorCandidate, VectorSimilar, VectorStore, VectorWriteRow } from './store/types.ts';\n\nexport type { WatchEvent, WatchOptions } from './watch.ts';\nexport { runWatch } from './watch.ts';\n"],"names":["CAPABILITY_NAMES","CONFIG_FILENAME","SIGNAL_NAMES","STATE_DIR","STORE_NAMES","SUPPORTED_CONFIG_VERSION","SenseError","clearCache","initConfig","loadConfig","mapTree","migrateConfig","open","openStore","peek","presetCoverage","printRows","runWatch","search"],"mappings":"AAAA,+EAA+E;AAC/E,uEAAuE;;;;;;;;;;;;QAW9DA;eAAAA,0BAAgB;;QANhBC;eAAAA,yBAAe;;QAAyCC;eAAAA,sBAAY;;QAAEC;eAAAA,mBAAS;;QAAEC;eAAAA,qBAAW;;QAAEC;eAAAA,kCAAwB;;QAEtHC;eAAAA,oBAAU;;QAIQC;eAAAA,oBAAU;;QANXC;eAAAA,oBAAU;;QAAEC;eAAAA,oBAAU;;QAFvCC;eAAAA,gBAAO;;QAEkCC;eAAAA,uBAAa;;QAMXC;eAAbC,mBAAS;;QAR9BC;eAAAA,aAAI;;QAAEC;eAAAA,uBAAc;;QAM7BC;eAAAA,mBAAS;;QAMTC;eAAAA,iBAAQ;;QAZuBC;eAAAA,eAAM;;;uBAAQ;wBAEiF;wBAE5G;wBAED;wBAEsC;uBAIvC"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/index.ts"],"sourcesContent":["// Public library API. Deliberately small: every export is a stability promise;\n// internals (feature registry, graph, scan, meta) stay module-private.\n\nexport type { Peek, PresetCoverage, SearchOptions, TreeMap } from './commands/index.ts';\nexport { mapTree, peek, presetCoverage, search } from './commands/index.ts';\nexport type { Config, EmbedConfig, FeatureName, InitOverrides, LoadConfigOptions, Preset, ResolvedConfig, SavedQuery, SavedSearch, SearchOverrides, SignalName, SignalWeights, StoreName } from './config/index.ts';\nexport { CONFIG_FILENAME, initConfig, loadConfig, migrateConfig, SIGNAL_NAMES, STATE_DIR, STORE_NAMES, SUPPORTED_CONFIG_VERSION } from './config/index.ts';\nexport type { SenseErrorCode } from './errors.ts';\nexport { SenseError } from './errors.ts';\nexport type { Format, Row, RowFormat } from './output/output.ts';\nexport { printRows } from './output/output.ts';\nexport type { BuildOptions, BuildResult, OpenOptions, OpenResult, Stages } from './store/index.ts';\nexport { buildIndex as build, CAPABILITY_NAMES, clearCache, openStore as open } from './store/index.ts';\nexport type { Capability, DocumentStore, FieldStat, LexicalHit, LexicalIndex, LexicalQueryOptions, RawStatement, RunResult, SqlSession, Statement, Store, VectorCandidate, VectorSimilar, VectorStore, VectorWriteRow } from './store/types.ts';\n\nexport type { WatchEvent, WatchOptions } from './watch.ts';\nexport { runWatch } from './watch.ts';\n"],"names":["CAPABILITY_NAMES","CONFIG_FILENAME","SIGNAL_NAMES","STATE_DIR","STORE_NAMES","SUPPORTED_CONFIG_VERSION","SenseError","build","buildIndex","clearCache","initConfig","loadConfig","mapTree","migrateConfig","open","openStore","peek","presetCoverage","printRows","runWatch","search"],"mappings":"AAAA,+EAA+E;AAC/E,uEAAuE;;;;;;;;;;;;QAWzCA;eAAAA,0BAAgB;;QANrCC;eAAAA,yBAAe;;QAAyCC;eAAAA,sBAAY;;QAAEC;eAAAA,mBAAS;;QAAEC;eAAAA,qBAAW;;QAAEC;eAAAA,kCAAwB;;QAEtHC;eAAAA,oBAAU;;QAIIC;eAAdC,oBAAU;;QAA6BC;eAAAA,oBAAU;;QANhCC;eAAAA,oBAAU;;QAAEC;eAAAA,oBAAU;;QAFvCC;eAAAA,gBAAO;;QAEkCC;eAAAA,uBAAa;;QAMUC;eAAbC,mBAAS;;QARnDC;eAAAA,aAAI;;QAAEC;eAAAA,uBAAc;;QAM7BC;eAAAA,mBAAS;;QAMTC;eAAAA,iBAAQ;;QAZuBC;eAAAA,eAAM;;;uBAAQ;wBAEiF;wBAE5G;wBAED;wBAE2D;uBAI5D"}
@@ -8,17 +8,31 @@ Object.defineProperty(exports, "writeFileAtomic", {
8
8
  return writeFileAtomic;
9
9
  }
10
10
  });
11
+ var _nodecrypto = require("node:crypto");
11
12
  var _nodefs = require("node:fs");
13
+ function _instanceof(left, right) {
14
+ "@swc/helpers - instanceof";
15
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
16
+ return !!right[Symbol.hasInstance](left);
17
+ } else return left instanceof right;
18
+ }
12
19
  function writeFileAtomic(path, data) {
13
- var tmp = "".concat(path, ".part");
14
- (0, _nodefs.writeFileSync)(tmp, data);
20
+ var tmp = "".concat(path, ".").concat((0, _nodecrypto.randomUUID)(), ".part");
21
+ var staged = false;
15
22
  try {
23
+ (0, _nodefs.writeFileSync)(tmp, data, {
24
+ flag: 'wx'
25
+ });
26
+ staged = true;
16
27
  (0, _nodefs.renameSync)(tmp, path);
17
28
  } catch (err) {
18
- try {
19
- (0, _nodefs.unlinkSync)(tmp);
20
- } catch (unused) {
21
- // best-effort cleanup; the rename error below is what matters
29
+ // An exclusive-create collision belongs to another writer; never remove its staging file.
30
+ if (staged || !(_instanceof(err, Error) && 'code' in err && err.code === 'EEXIST')) {
31
+ try {
32
+ (0, _nodefs.unlinkSync)(tmp);
33
+ } catch (unused) {
34
+ // best-effort cleanup; the original error below is what matters
35
+ }
22
36
  }
23
37
  throw err;
24
38
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/lib/atomic-write.ts"],"sourcesContent":["import { renameSync, unlinkSync, writeFileSync } from 'node:fs';\n\n// Stage-then-swap: write beside the target, then rename over it. A crash or full disk mid-write\n// leaves the target untouched instead of truncated. Matches embed/store.ts's model-download idiom.\nexport function writeFileAtomic(path: string, data: string | Buffer): void {\n const tmp = `${path}.part`;\n writeFileSync(tmp, data);\n try {\n renameSync(tmp, path);\n } catch (err) {\n try {\n unlinkSync(tmp);\n } catch {\n // best-effort cleanup; the rename error below is what matters\n }\n throw err;\n }\n}\n"],"names":["writeFileAtomic","path","data","tmp","writeFileSync","renameSync","err","unlinkSync"],"mappings":";;;;+BAIgBA;;;eAAAA;;;sBAJsC;AAI/C,SAASA,gBAAgBC,IAAY,EAAEC,IAAqB;IACjE,IAAMC,MAAM,AAAC,GAAO,OAALF,MAAK;IACpBG,IAAAA,qBAAa,EAACD,KAAKD;IACnB,IAAI;QACFG,IAAAA,kBAAU,EAACF,KAAKF;IAClB,EAAE,OAAOK,KAAK;QACZ,IAAI;YACFC,IAAAA,kBAAU,EAACJ;QACb,EAAE,eAAM;QACN,8DAA8D;QAChE;QACA,MAAMG;IACR;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/lib/atomic-write.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { renameSync, unlinkSync, writeFileSync } from 'node:fs';\n\n// Stage-then-swap: write beside the target, then rename over it. A crash or full disk mid-write\n// leaves the target untouched instead of truncated. Matches embed/store.ts's model-download idiom.\nexport function writeFileAtomic(path: string, data: string | Buffer): void {\n const tmp = `${path}.${randomUUID()}.part`;\n let staged = false;\n try {\n writeFileSync(tmp, data, { flag: 'wx' });\n staged = true;\n renameSync(tmp, path);\n } catch (err) {\n // An exclusive-create collision belongs to another writer; never remove its staging file.\n if (staged || !(err instanceof Error && 'code' in err && err.code === 'EEXIST')) {\n try {\n unlinkSync(tmp);\n } catch {\n // best-effort cleanup; the original error below is what matters\n }\n }\n throw err;\n }\n}\n"],"names":["writeFileAtomic","path","data","tmp","randomUUID","staged","writeFileSync","flag","renameSync","err","Error","code","unlinkSync"],"mappings":";;;;+BAKgBA;;;eAAAA;;;0BALW;sBAC2B;;;;;;;AAI/C,SAASA,gBAAgBC,IAAY,EAAEC,IAAqB;IACjE,IAAMC,MAAM,AAAC,GAAUC,OAARH,MAAK,KAAgB,OAAbG,IAAAA,sBAAU,KAAG;IACpC,IAAIC,SAAS;IACb,IAAI;QACFC,IAAAA,qBAAa,EAACH,KAAKD,MAAM;YAAEK,MAAM;QAAK;QACtCF,SAAS;QACTG,IAAAA,kBAAU,EAACL,KAAKF;IAClB,EAAE,OAAOQ,KAAK;QACZ,0FAA0F;QAC1F,IAAIJ,UAAU,CAAEI,CAAAA,AAAG,YAAHA,KAAeC,UAAS,UAAUD,OAAOA,IAAIE,IAAI,KAAK,QAAO,GAAI;YAC/E,IAAI;gBACFC,IAAAA,kBAAU,EAACT;YACb,EAAE,eAAM;YACN,gEAAgE;YAClE;QACF;QACA,MAAMM;IACR;AACF"}
@@ -0,0 +1 @@
1
+ export declare function serialQuery<T>(handle: object, query: () => Promise<T>): Promise<T>;
@@ -0,0 +1 @@
1
+ export declare function serialQuery<T>(handle: object, query: () => Promise<T>): Promise<T>;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "serialQuery", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return serialQuery;
9
+ }
10
+ });
11
+ var pending = new WeakMap();
12
+ function serialQuery(handle, query) {
13
+ var _pending_get;
14
+ var result = ((_pending_get = pending.get(handle)) !== null && _pending_get !== void 0 ? _pending_get : Promise.resolve()).then(query);
15
+ var settled = result.then(function() {}, function() {});
16
+ pending.set(handle, settled);
17
+ void settled.then(function() {
18
+ if (pending.get(handle) === settled) pending.delete(handle);
19
+ });
20
+ return result;
21
+ }
22
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/lib/serial-query.ts"],"sourcesContent":["const pending = new WeakMap<object, Promise<void>>();\n\n// High-level queries share temporary tables and transaction state on a handle.\n// Raw SQL and handle closure remain caller-owned and must await these queries.\nexport function serialQuery<T>(handle: object, query: () => Promise<T>): Promise<T> {\n const result = (pending.get(handle) ?? Promise.resolve()).then(query);\n const settled = result.then(\n () => {},\n () => {}\n );\n pending.set(handle, settled);\n void settled.then(() => {\n if (pending.get(handle) === settled) pending.delete(handle);\n });\n return result;\n}\n"],"names":["serialQuery","pending","WeakMap","handle","query","result","get","Promise","resolve","then","settled","set","delete"],"mappings":";;;;+BAIgBA;;;eAAAA;;;AAJhB,IAAMC,UAAU,IAAIC;AAIb,SAASF,YAAeG,MAAc,EAAEC,KAAuB;QACpDH;IAAhB,IAAMI,SAAS,EAACJ,eAAAA,QAAQK,GAAG,CAACH,qBAAZF,0BAAAA,eAAuBM,QAAQC,OAAO,IAAIC,IAAI,CAACL;IAC/D,IAAMM,UAAUL,OAAOI,IAAI,CACzB,YAAO,GACP,YAAO;IAETR,QAAQU,GAAG,CAACR,QAAQO;IACpB,KAAKA,QAAQD,IAAI,CAAC;QAChB,IAAIR,QAAQK,GAAG,CAACH,YAAYO,SAAST,QAAQW,MAAM,CAACT;IACtD;IACA,OAAOE;AACT"}
@@ -12,6 +12,7 @@ export interface ParsedDoc {
12
12
  presets: string[];
13
13
  data: Record<string, string | number | bigint | null>;
14
14
  parseError: string | null;
15
+ source: string;
15
16
  search: {
16
17
  title: string;
17
18
  summary: string;
@@ -19,6 +20,10 @@ export interface ParsedDoc {
19
20
  };
20
21
  extracted: Record<string, unknown>;
21
22
  }
23
+ export declare function parseSource(file: FileStat, raw: string, extractors?: Feature[], cfg?: Config): {
24
+ doc: ParsedDoc;
25
+ warnings: string[];
26
+ };
22
27
  export declare function parseFile(file: FileStat, extractors?: Feature[], cfg?: Config): {
23
28
  doc: ParsedDoc;
24
29
  warnings: string[];
@@ -12,6 +12,7 @@ export interface ParsedDoc {
12
12
  presets: string[];
13
13
  data: Record<string, string | number | bigint | null>;
14
14
  parseError: string | null;
15
+ source: string;
15
16
  search: {
16
17
  title: string;
17
18
  summary: string;
@@ -19,6 +20,10 @@ export interface ParsedDoc {
19
20
  };
20
21
  extracted: Record<string, unknown>;
21
22
  }
23
+ export declare function parseSource(file: FileStat, raw: string, extractors?: Feature[], cfg?: Config): {
24
+ doc: ParsedDoc;
25
+ warnings: string[];
26
+ };
22
27
  export declare function parseFile(file: FileStat, extractors?: Feature[], cfg?: Config): {
23
28
  doc: ParsedDoc;
24
29
  warnings: string[];
@@ -24,6 +24,9 @@ _export(exports, {
24
24
  get parseFile () {
25
25
  return parseFile;
26
26
  },
27
+ get parseSource () {
28
+ return parseSource;
29
+ },
27
30
  get toPosixPath () {
28
31
  return _listts.toPosixPath;
29
32
  }
@@ -33,10 +36,8 @@ var _indexts = require("../chunk/index.js");
33
36
  var _stripts = require("../text/strip.js");
34
37
  var _frontmatterts = require("./frontmatter.js");
35
38
  var _listts = require("./list.js");
36
- function parseFile(file) {
37
- var extractors = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : [], cfg = arguments.length > 2 ? arguments[2] : void 0;
38
- // Preserve the authored bytes: feature extractors and section offsets use the raw document.
39
- var raw = (0, _nodefs.readFileSync)(file.absPath, 'utf8');
39
+ function parseSource(file, raw) {
40
+ var extractors = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : [], cfg = arguments.length > 3 ? arguments[3] : void 0;
40
41
  var warnings = [];
41
42
  var _splitFrontmatter = (0, _frontmatterts.splitFrontmatter)(raw), fm = _splitFrontmatter.fm, content = _splitFrontmatter.body;
42
43
  var _ref = fm === null ? {
@@ -91,6 +92,7 @@ function parseFile(file) {
91
92
  presets: file.presets,
92
93
  data: mapped,
93
94
  parseError: parseError,
95
+ source: raw,
94
96
  search: search,
95
97
  extracted: Object.fromEntries(extractors.filter(function(f) {
96
98
  return f.extract;
@@ -105,4 +107,10 @@ function parseFile(file) {
105
107
  warnings: warnings
106
108
  };
107
109
  }
110
+ function parseFile(file) {
111
+ var extractors = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : [], cfg = arguments.length > 2 ? arguments[2] : void 0;
112
+ // Preserve the authored bytes: feature extractors, indexed snippets, and section offsets use
113
+ // the same decoded string from this one read.
114
+ return parseSource(file, (0, _nodefs.readFileSync)(file.absPath, 'utf8'), extractors, cfg);
115
+ }
108
116
  /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/scan/index.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { parse } from '../chunk/index.ts';\nimport type { Config } from '../config/index.ts';\nimport type { Feature } from '../features/types.ts';\nimport { textFromBlocks } from '../text/strip.ts';\nimport { looksLikeDatetime, mapValue, normalizeText, parseFrontmatter, RESERVED_COLUMNS, splitFrontmatter } from './frontmatter.ts';\nimport type { FileStat } from './list.ts';\n\n// Filesystem -> rows. Pure data in, data + warnings out; store/sqlite/reconcile.ts does the SQL.\n\nexport { looksLikeDatetime, normalizeDate, RESERVED_COLUMNS } from './frontmatter.ts';\nexport type { FileStat } from './list.ts';\nexport { listFiles, toPosixPath } from './list.ts';\n\nexport interface ParsedDoc {\n relPath: string;\n mtimeMs: number;\n ctimeMs: number;\n size: number;\n presets: string[];\n data: Record<string, string | number | bigint | null>;\n // NULL when the frontmatter parsed, the first YAML message otherwise. In the row rather than\n // a side table so `SELECT *` and any `IS NULL` investigation trip over it without being asked.\n parseError: string | null;\n // title/summary are duplicated from frontmatter so bm25() can weight them above the body text.\n search: { title: string; summary: string; text: string };\n // Per-feature extraction results, keyed by feature name; features store them at reconcile.\n extracted: Record<string, unknown>;\n}\n\nexport function parseFile(file: FileStat, extractors: Feature[] = [], cfg?: Config): { doc: ParsedDoc; warnings: string[] } {\n // Preserve the authored bytes: feature extractors and section offsets use the raw document.\n const raw = readFileSync(file.absPath, 'utf8');\n const warnings: string[] = [];\n\n const { fm, body: content } = splitFrontmatter(raw);\n const { data, parseError } = fm === null ? { data: {} as Record<string, unknown>, parseError: null } : parseFrontmatter(file.relPath, fm, warnings);\n const mapped: Record<string, string | number | bigint | null> = {};\n\n for (const key of Object.keys(data)) {\n if (RESERVED_COLUMNS.has(key)) {\n warnings.push(`warning: ${file.relPath} has a frontmatter key named \"${key}\", which is reserved; ignoring it`);\n continue;\n }\n const value = mapValue(data[key]);\n if (typeof value === 'string' && looksLikeDatetime(value) && Number.isNaN(Date.parse(value))) {\n warnings.push(`warning: ${file.relPath}: ${key} is not a valid date (${value}), so it is invisible to every date comparison`);\n }\n mapped[key] = value;\n }\n\n // Parsed once and shared: the FTS text path (textFromBlocks, ~ strip.ts) and any feature\n // that needs a parse tree (embed's chunker) both read this same block list.\n const blocks = parse(content);\n\n // title/summary are plain YAML strings -- whitespace-collapse only;\n // the prose gets the full markdown strip.\n const search = { title: normalizeText(data.title), summary: normalizeText(data.summary), text: textFromBlocks(blocks) };\n\n return {\n doc: {\n relPath: file.relPath,\n mtimeMs: file.mtimeMs,\n ctimeMs: file.ctimeMs,\n size: file.size,\n presets: file.presets,\n data: mapped,\n parseError,\n search,\n extracted: Object.fromEntries(extractors.filter((f) => f.extract).map((f) => [f.name, f.extract?.(raw, content, search, data, cfg, blocks)])),\n },\n warnings,\n };\n}\n"],"names":["RESERVED_COLUMNS","listFiles","looksLikeDatetime","normalizeDate","parseFile","toPosixPath","file","extractors","cfg","raw","readFileSync","absPath","warnings","splitFrontmatter","fm","body","content","data","parseError","parseFrontmatter","relPath","mapped","Object","keys","key","has","push","value","mapValue","Number","isNaN","Date","parse","blocks","search","title","normalizeText","summary","text","textFromBlocks","doc","mtimeMs","ctimeMs","size","presets","extracted","fromEntries","filter","f","extract","map","name"],"mappings":";;;;;;;;;;;QAU2CA;eAAAA,+BAAgB;;QAElDC;eAAAA,iBAAS;;QAFTC;eAAAA,gCAAiB;;QAAEC;eAAAA,4BAAa;;QAoBzBC;eAAAA;;QAlBIC;eAAAA,mBAAW;;;sBAZF;uBACP;uBAGS;6BACkF;sBAO1E;AAkBhC,SAASD,UAAUE,IAAc;QAAEC,aAAAA,iEAAwB,EAAE,EAAEC;IACpE,4FAA4F;IAC5F,IAAMC,MAAMC,IAAAA,oBAAY,EAACJ,KAAKK,OAAO,EAAE;IACvC,IAAMC,WAAqB,EAAE;IAE7B,IAA8BC,oBAAAA,IAAAA,+BAAgB,EAACJ,MAAvCK,KAAsBD,kBAAtBC,IAAIC,AAAMC,UAAYH,kBAAlBE;IACZ,IAA6BD,OAAAA,OAAO,OAAO;QAAEG,MAAM,CAAC;QAA8BC,YAAY;IAAK,IAAIC,IAAAA,+BAAgB,EAACb,KAAKc,OAAO,EAAEN,IAAIF,WAAlIK,OAAqBH,KAArBG,MAAMC,aAAeJ,KAAfI;IACd,IAAMG,SAA0D,CAAC;QAE5D,kCAAA,2BAAA;;QAAL,QAAK,YAAaC,OAAOC,IAAI,CAACN,0BAAzB,SAAA,6BAAA,QAAA,yBAAA,iCAAgC;YAAhC,IAAMO,MAAN;YACH,IAAIxB,+BAAgB,CAACyB,GAAG,CAACD,MAAM;gBAC7BZ,SAASc,IAAI,CAAC,AAAC,YAAwDF,OAA7ClB,KAAKc,OAAO,EAAC,kCAAoC,OAAJI,KAAI;gBAC3E;YACF;YACA,IAAMG,QAAQC,IAAAA,uBAAQ,EAACX,IAAI,CAACO,IAAI;YAChC,IAAI,OAAOG,UAAU,YAAYzB,IAAAA,gCAAiB,EAACyB,UAAUE,OAAOC,KAAK,CAACC,KAAKC,KAAK,CAACL,SAAS;gBAC5Ff,SAASc,IAAI,CAAC,AAAC,YAA4BF,OAAjBlB,KAAKc,OAAO,EAAC,MAAgCO,OAA5BH,KAAI,0BAA8B,OAANG,OAAM;YAC/E;YACAN,MAAM,CAACG,IAAI,GAAGG;QAChB;;QAVK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAYL,yFAAyF;IACzF,4EAA4E;IAC5E,IAAMM,SAASD,IAAAA,cAAK,EAAChB;IAErB,oEAAoE;IACpE,0CAA0C;IAC1C,IAAMkB,SAAS;QAAEC,OAAOC,IAAAA,4BAAa,EAACnB,KAAKkB,KAAK;QAAGE,SAASD,IAAAA,4BAAa,EAACnB,KAAKoB,OAAO;QAAGC,MAAMC,IAAAA,uBAAc,EAACN;IAAQ;IAEtH,OAAO;QACLO,KAAK;YACHpB,SAASd,KAAKc,OAAO;YACrBqB,SAASnC,KAAKmC,OAAO;YACrBC,SAASpC,KAAKoC,OAAO;YACrBC,MAAMrC,KAAKqC,IAAI;YACfC,SAAStC,KAAKsC,OAAO;YACrB3B,MAAMI;YACNH,YAAAA;YACAgB,QAAAA;YACAW,WAAWvB,OAAOwB,WAAW,CAACvC,WAAWwC,MAAM,CAAC,SAACC;uBAAMA,EAAEC,OAAO;eAAEC,GAAG,CAAC,SAACF;oBAAeA;uBAAT;oBAACA,EAAEG,IAAI;qBAAEH,aAAAA,EAAEC,OAAO,cAATD,iCAAAA,gBAAAA,GAAYvC,KAAKO,SAASkB,QAAQjB,MAAMT,KAAKyB;iBAAQ;;QAC7I;QACArB,UAAAA;IACF;AACF"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/scan/index.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { parse } from '../chunk/index.ts';\nimport type { Config } from '../config/index.ts';\nimport type { Feature } from '../features/types.ts';\nimport { textFromBlocks } from '../text/strip.ts';\nimport { looksLikeDatetime, mapValue, normalizeText, parseFrontmatter, RESERVED_COLUMNS, splitFrontmatter } from './frontmatter.ts';\nimport type { FileStat } from './list.ts';\n\n// Filesystem -> rows. Pure data in, data + warnings out; store/sqlite/reconcile.ts does the SQL.\n\nexport { looksLikeDatetime, normalizeDate, RESERVED_COLUMNS } from './frontmatter.ts';\nexport type { FileStat } from './list.ts';\nexport { listFiles, toPosixPath } from './list.ts';\n\nexport interface ParsedDoc {\n relPath: string;\n mtimeMs: number;\n ctimeMs: number;\n size: number;\n presets: string[];\n data: Record<string, string | number | bigint | null>;\n // NULL when the frontmatter parsed, the first YAML message otherwise. In the row rather than\n // a side table so `SELECT *` and any `IS NULL` investigation trip over it without being asked.\n parseError: string | null;\n // Exact decoded source bytes read for this parse generation. Stored outside the FTS table so\n // snippets and delayed embedding never consult a newer filesystem generation.\n source: string;\n // title/summary are duplicated from frontmatter so bm25() can weight them above the body text.\n search: { title: string; summary: string; text: string };\n // Per-feature extraction results, keyed by feature name; features store them at reconcile.\n extracted: Record<string, unknown>;\n}\n\nexport function parseSource(file: FileStat, raw: string, extractors: Feature[] = [], cfg?: Config): { doc: ParsedDoc; warnings: string[] } {\n const warnings: string[] = [];\n\n const { fm, body: content } = splitFrontmatter(raw);\n const { data, parseError } = fm === null ? { data: {} as Record<string, unknown>, parseError: null } : parseFrontmatter(file.relPath, fm, warnings);\n const mapped: Record<string, string | number | bigint | null> = {};\n\n for (const key of Object.keys(data)) {\n if (RESERVED_COLUMNS.has(key)) {\n warnings.push(`warning: ${file.relPath} has a frontmatter key named \"${key}\", which is reserved; ignoring it`);\n continue;\n }\n const value = mapValue(data[key]);\n if (typeof value === 'string' && looksLikeDatetime(value) && Number.isNaN(Date.parse(value))) {\n warnings.push(`warning: ${file.relPath}: ${key} is not a valid date (${value}), so it is invisible to every date comparison`);\n }\n mapped[key] = value;\n }\n\n // Parsed once and shared: the FTS text path (textFromBlocks, ~ strip.ts) and any feature\n // that needs a parse tree (embed's chunker) both read this same block list.\n const blocks = parse(content);\n\n // title/summary are plain YAML strings -- whitespace-collapse only;\n // the prose gets the full markdown strip.\n const search = { title: normalizeText(data.title), summary: normalizeText(data.summary), text: textFromBlocks(blocks) };\n\n return {\n doc: {\n relPath: file.relPath,\n mtimeMs: file.mtimeMs,\n ctimeMs: file.ctimeMs,\n size: file.size,\n presets: file.presets,\n data: mapped,\n parseError,\n source: raw,\n search,\n extracted: Object.fromEntries(extractors.filter((f) => f.extract).map((f) => [f.name, f.extract?.(raw, content, search, data, cfg, blocks)])),\n },\n warnings,\n };\n}\n\nexport function parseFile(file: FileStat, extractors: Feature[] = [], cfg?: Config): { doc: ParsedDoc; warnings: string[] } {\n // Preserve the authored bytes: feature extractors, indexed snippets, and section offsets use\n // the same decoded string from this one read.\n return parseSource(file, readFileSync(file.absPath, 'utf8'), extractors, cfg);\n}\n"],"names":["RESERVED_COLUMNS","listFiles","looksLikeDatetime","normalizeDate","parseFile","parseSource","toPosixPath","file","raw","extractors","cfg","warnings","splitFrontmatter","fm","body","content","data","parseError","parseFrontmatter","relPath","mapped","Object","keys","key","has","push","value","mapValue","Number","isNaN","Date","parse","blocks","search","title","normalizeText","summary","text","textFromBlocks","doc","mtimeMs","ctimeMs","size","presets","source","extracted","fromEntries","filter","f","extract","map","name","readFileSync","absPath"],"mappings":";;;;;;;;;;;QAU2CA;eAAAA,+BAAgB;;QAElDC;eAAAA,iBAAS;;QAFTC;eAAAA,gCAAiB;;QAAEC;eAAAA,4BAAa;;QAmEzBC;eAAAA;;QA5CAC;eAAAA;;QArBIC;eAAAA,mBAAW;;;sBAZF;uBACP;uBAGS;6BACkF;sBAO1E;AAqBhC,SAASD,YAAYE,IAAc,EAAEC,GAAW;QAAEC,aAAAA,iEAAwB,EAAE,EAAEC;IACnF,IAAMC,WAAqB,EAAE;IAE7B,IAA8BC,oBAAAA,IAAAA,+BAAgB,EAACJ,MAAvCK,KAAsBD,kBAAtBC,IAAIC,AAAMC,UAAYH,kBAAlBE;IACZ,IAA6BD,OAAAA,OAAO,OAAO;QAAEG,MAAM,CAAC;QAA8BC,YAAY;IAAK,IAAIC,IAAAA,+BAAgB,EAACX,KAAKY,OAAO,EAAEN,IAAIF,WAAlIK,OAAqBH,KAArBG,MAAMC,aAAeJ,KAAfI;IACd,IAAMG,SAA0D,CAAC;QAE5D,kCAAA,2BAAA;;QAAL,QAAK,YAAaC,OAAOC,IAAI,CAACN,0BAAzB,SAAA,6BAAA,QAAA,yBAAA,iCAAgC;YAAhC,IAAMO,MAAN;YACH,IAAIvB,+BAAgB,CAACwB,GAAG,CAACD,MAAM;gBAC7BZ,SAASc,IAAI,CAAC,AAAC,YAAwDF,OAA7ChB,KAAKY,OAAO,EAAC,kCAAoC,OAAJI,KAAI;gBAC3E;YACF;YACA,IAAMG,QAAQC,IAAAA,uBAAQ,EAACX,IAAI,CAACO,IAAI;YAChC,IAAI,OAAOG,UAAU,YAAYxB,IAAAA,gCAAiB,EAACwB,UAAUE,OAAOC,KAAK,CAACC,KAAKC,KAAK,CAACL,SAAS;gBAC5Ff,SAASc,IAAI,CAAC,AAAC,YAA4BF,OAAjBhB,KAAKY,OAAO,EAAC,MAAgCO,OAA5BH,KAAI,0BAA8B,OAANG,OAAM;YAC/E;YACAN,MAAM,CAACG,IAAI,GAAGG;QAChB;;QAVK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAYL,yFAAyF;IACzF,4EAA4E;IAC5E,IAAMM,SAASD,IAAAA,cAAK,EAAChB;IAErB,oEAAoE;IACpE,0CAA0C;IAC1C,IAAMkB,SAAS;QAAEC,OAAOC,IAAAA,4BAAa,EAACnB,KAAKkB,KAAK;QAAGE,SAASD,IAAAA,4BAAa,EAACnB,KAAKoB,OAAO;QAAGC,MAAMC,IAAAA,uBAAc,EAACN;IAAQ;IAEtH,OAAO;QACLO,KAAK;YACHpB,SAASZ,KAAKY,OAAO;YACrBqB,SAASjC,KAAKiC,OAAO;YACrBC,SAASlC,KAAKkC,OAAO;YACrBC,MAAMnC,KAAKmC,IAAI;YACfC,SAASpC,KAAKoC,OAAO;YACrB3B,MAAMI;YACNH,YAAAA;YACA2B,QAAQpC;YACRyB,QAAAA;YACAY,WAAWxB,OAAOyB,WAAW,CAACrC,WAAWsC,MAAM,CAAC,SAACC;uBAAMA,EAAEC,OAAO;eAAEC,GAAG,CAAC,SAACF;oBAAeA;uBAAT;oBAACA,EAAEG,IAAI;qBAAEH,aAAAA,EAAEC,OAAO,cAATD,iCAAAA,gBAAAA,GAAYxC,KAAKO,SAASkB,QAAQjB,MAAMN,KAAKsB;iBAAQ;;QAC7I;QACArB,UAAAA;IACF;AACF;AAEO,SAASP,UAAUG,IAAc;QAAEE,aAAAA,iEAAwB,EAAE,EAAEC;IACpE,6FAA6F;IAC7F,8CAA8C;IAC9C,OAAOL,YAAYE,MAAM6C,IAAAA,oBAAY,EAAC7C,KAAK8C,OAAO,EAAE,SAAS5C,YAAYC;AAC3E"}
@@ -9,8 +9,13 @@ export type FileResult = {
9
9
  };
10
10
  export declare class ParsePool {
11
11
  private pool;
12
+ private workerData;
13
+ private operation;
12
14
  poolsCreated: number;
15
+ private enqueue;
13
16
  private ensure;
14
17
  run(files: FileStat[], features: Feature[], cfg: Config, onParsed: ((done: number) => void) | undefined, maxWorkers: number): Promise<FileResult[]>;
18
+ private dispatch;
19
+ private destroy;
15
20
  close(): Promise<void>;
16
21
  }
@@ -9,8 +9,13 @@ export type FileResult = {
9
9
  };
10
10
  export declare class ParsePool {
11
11
  private pool;
12
+ private workerData;
13
+ private operation;
12
14
  poolsCreated: number;
15
+ private enqueue;
13
16
  private ensure;
14
17
  run(files: FileStat[], features: Feature[], cfg: Config, onParsed: ((done: number) => void) | undefined, maxWorkers: number): Promise<FileResult[]>;
18
+ private dispatch;
19
+ private destroy;
15
20
  close(): Promise<void>;
16
21
  }
@@ -9,8 +9,17 @@ Object.defineProperty(exports, "ParsePool", {
9
9
  }
10
10
  });
11
11
  var _nodemodule = require("node:module");
12
+ var _nodeutil = require("node:util");
12
13
  var _workerfilets = require("../lib/worker-file.js");
13
14
  var _workererrorts = require("./worker-error.js");
15
+ function _array_like_to_array(arr, len) {
16
+ if (len == null || len > arr.length) len = arr.length;
17
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
18
+ return arr2;
19
+ }
20
+ function _array_without_holes(arr) {
21
+ if (Array.isArray(arr)) return _array_like_to_array(arr);
22
+ }
14
23
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
15
24
  try {
16
25
  var info = gen[key](arg);
@@ -40,6 +49,17 @@ function _async_to_generator(fn) {
40
49
  function _class_call_check(instance, Constructor) {
41
50
  if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
42
51
  }
52
+ function _iterable_to_array(iter) {
53
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) {
54
+ return Array.from(iter);
55
+ }
56
+ }
57
+ function _non_iterable_spread() {
58
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
59
+ }
60
+ function _to_consumable_array(arr) {
61
+ return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
62
+ }
43
63
  function _ts_generator(thisArg, body) {
44
64
  var f, y, t, _ = {
45
65
  label: 0,
@@ -139,82 +159,166 @@ function _ts_generator(thisArg, body) {
139
159
  };
140
160
  }
141
161
  }
162
+ function _unsupported_iterable_to_array(o, minLen) {
163
+ if (!o) return;
164
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
165
+ var n = Object.prototype.toString.call(o).slice(8, -1);
166
+ if (n === "Object" && o.constructor) n = o.constructor.name;
167
+ if (n === "Map" || n === "Set") return Array.from(n);
168
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
169
+ }
142
170
  // Tinypool is ESM-only; our floor (>=22.20) has native require(esm), so the tier-2 house deferral reaches it.
143
171
  var _require = typeof require === 'undefined' ? (0, _nodemodule.createRequire)(require("url").pathToFileURL(__filename).toString()) : require;
144
172
  var ParsePool = /*#__PURE__*/ function() {
145
173
  "use strict";
146
174
  function ParsePool() {
147
175
  _class_call_check(this, ParsePool);
148
- // Tinypools this instance has constructed. One dispatch or a hundred should leave it at 1;
149
- // it is how a caller, and the specs, observe that a lifetime reuses its pool rather than churning one.
176
+ this.operation = Promise.resolve();
177
+ // Tinypools this instance has constructed. Repeated equivalent dispatches leave this unchanged;
178
+ // a context change or close followed by run constructs another pool.
150
179
  this.poolsCreated = 0;
151
180
  }
152
181
  var _proto = ParsePool.prototype;
182
+ _proto.enqueue = function enqueue(operation) {
183
+ var result = this.operation.then(operation);
184
+ this.operation = result.then(function() {
185
+ return undefined;
186
+ }, function() {
187
+ return undefined;
188
+ });
189
+ return result;
190
+ };
153
191
  _proto.ensure = function ensure(workerData, maxWorkers) {
154
- if (!this.pool) {
155
- var Tinypool = _require('tinypool').Tinypool;
156
- this.pool = new Tinypool({
157
- filename: (0, _workerfilets.resolveWorkerFile)('parse'),
158
- minThreads: maxWorkers,
159
- maxThreads: maxWorkers,
160
- workerData: workerData
192
+ return _async_to_generator(function() {
193
+ var Tinypool;
194
+ return _ts_generator(this, function(_state) {
195
+ switch(_state.label){
196
+ case 0:
197
+ if (!(this.pool && !(0, _nodeutil.isDeepStrictEqual)(this.workerData, workerData))) return [
198
+ 3,
199
+ 2
200
+ ];
201
+ return [
202
+ 4,
203
+ this.destroy()
204
+ ];
205
+ case 1:
206
+ _state.sent();
207
+ _state.label = 2;
208
+ case 2:
209
+ if (!this.pool) {
210
+ Tinypool = _require('tinypool').Tinypool;
211
+ this.pool = new Tinypool({
212
+ filename: (0, _workerfilets.resolveWorkerFile)('parse'),
213
+ minThreads: maxWorkers,
214
+ maxThreads: maxWorkers,
215
+ workerData: workerData
216
+ });
217
+ this.workerData = workerData;
218
+ this.poolsCreated++;
219
+ }
220
+ return [
221
+ 2,
222
+ this.pool
223
+ ];
224
+ }
161
225
  });
162
- this.poolsCreated++;
163
- }
164
- return this.pool;
226
+ }).call(this);
165
227
  };
166
228
  // Never the tree: a worker task carries one FileStat and returns only what parseFile returns --
167
229
  // extracted text and feature values, never the token tree.
168
230
  _proto.run = function run(files, features, cfg, onParsed, maxWorkers) {
231
+ var _this = this;
232
+ // Snapshot at invocation so caller mutation cannot change queued work or its reuse baseline.
233
+ var workerData = {
234
+ cfg: structuredClone(cfg),
235
+ featureNames: _to_consumable_array(new Set(features.map(function(feature) {
236
+ return feature.name;
237
+ }))).sort()
238
+ };
239
+ return this.enqueue(function() {
240
+ return _this.dispatch(files, workerData, onParsed, maxWorkers);
241
+ });
242
+ };
243
+ _proto.dispatch = function dispatch(files, workerData, onParsed, maxWorkers) {
169
244
  return _async_to_generator(function() {
170
- var workerData, pool, done;
245
+ var pool, done, settled, results, failures, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, result;
171
246
  return _ts_generator(this, function(_state) {
172
- // cfg and the feature selection are constant for the dispatch, so they cross once per worker
173
- // as workerData. Features carry closures and cannot cross at all; only their names do.
174
- workerData = {
175
- cfg: cfg,
176
- featureNames: features.map(function(feature) {
177
- return feature.name;
178
- })
179
- };
180
- pool = this.ensure(workerData, maxWorkers);
181
- done = 0;
182
- // Promise.all over a mapped array is load-bearing: the resolved array keeps `files` order
183
- // regardless of task completion order, which first-seen column order depends on downstream.
184
- return [
185
- 2,
186
- Promise.all(files.map(function(file) {
187
- return _async_to_generator(function() {
188
- var result;
189
- return _ts_generator(this, function(_state) {
190
- switch(_state.label){
191
- case 0:
192
- return [
193
- 4,
194
- pool.run(file)
195
- ];
196
- case 1:
197
- result = _state.sent();
198
- if (!result.ok) throw (0, _workererrorts.reviveError)(result.error);
199
- onParsed === null || onParsed === void 0 ? void 0 : onParsed(++done);
200
- return [
201
- 2,
202
- {
203
- doc: result.doc,
204
- warnings: result.warnings,
205
- parseMs: result.parseMs
206
- }
207
- ];
247
+ switch(_state.label){
248
+ case 0:
249
+ return [
250
+ 4,
251
+ this.ensure(workerData, maxWorkers)
252
+ ];
253
+ case 1:
254
+ pool = _state.sent();
255
+ done = 0;
256
+ return [
257
+ 4,
258
+ Promise.allSettled(files.map(function(file) {
259
+ return _async_to_generator(function() {
260
+ var result;
261
+ return _ts_generator(this, function(_state) {
262
+ switch(_state.label){
263
+ case 0:
264
+ return [
265
+ 4,
266
+ pool.run(file)
267
+ ];
268
+ case 1:
269
+ result = _state.sent();
270
+ if (!result.ok) throw (0, _workererrorts.reviveError)(result.error);
271
+ onParsed === null || onParsed === void 0 ? void 0 : onParsed(++done);
272
+ return [
273
+ 2,
274
+ {
275
+ doc: result.doc,
276
+ warnings: result.warnings,
277
+ parseMs: result.parseMs
278
+ }
279
+ ];
280
+ }
281
+ });
282
+ })();
283
+ }))
284
+ ];
285
+ case 2:
286
+ settled = _state.sent();
287
+ results = [];
288
+ failures = [];
289
+ _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
290
+ try {
291
+ for(_iterator = settled[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
292
+ result = _step.value;
293
+ if (result.status === 'fulfilled') results.push(result.value);
294
+ else failures.push(result.reason);
295
+ }
296
+ } catch (err) {
297
+ _didIteratorError = true;
298
+ _iteratorError = err;
299
+ } finally{
300
+ try {
301
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
302
+ _iterator.return();
208
303
  }
209
- });
210
- })();
211
- }))
212
- ];
304
+ } finally{
305
+ if (_didIteratorError) {
306
+ throw _iteratorError;
307
+ }
308
+ }
309
+ }
310
+ if (failures.length === 1) throw failures[0];
311
+ if (failures.length > 1) throw new AggregateError(failures, "".concat(failures.length, " parse tasks failed"));
312
+ // allSettled preserves input order, which downstream first-seen column order depends on.
313
+ return [
314
+ 2,
315
+ results
316
+ ];
317
+ }
213
318
  });
214
319
  }).call(this);
215
320
  };
216
- // A pool never created costs nothing to destroy.
217
- _proto.close = function close() {
321
+ _proto.destroy = function destroy() {
218
322
  return _async_to_generator(function() {
219
323
  var pool;
220
324
  return _ts_generator(this, function(_state) {
@@ -225,6 +329,7 @@ var ParsePool = /*#__PURE__*/ function() {
225
329
  ];
226
330
  pool = this.pool;
227
331
  this.pool = undefined;
332
+ this.workerData = undefined;
228
333
  return [
229
334
  4,
230
335
  pool.destroy()
@@ -238,6 +343,13 @@ var ParsePool = /*#__PURE__*/ function() {
238
343
  });
239
344
  }).call(this);
240
345
  };
346
+ // A pool never created costs nothing to destroy. Queuing lets active dispatches drain first.
347
+ _proto.close = function close() {
348
+ var _this = this;
349
+ return this.enqueue(function() {
350
+ return _this.destroy();
351
+ });
352
+ };
241
353
  return ParsePool;
242
354
  }();
243
355
  /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }