sensemaking 0.19.2 → 0.20.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 (140) hide show
  1. package/dist/cjs/chunk/extract.d.cts +1 -0
  2. package/dist/cjs/chunk/extract.d.ts +1 -0
  3. package/dist/cjs/chunk/extract.js +23 -5
  4. package/dist/cjs/chunk/extract.js.map +1 -1
  5. package/dist/cjs/chunk/index.d.cts +1 -1
  6. package/dist/cjs/chunk/index.d.ts +1 -1
  7. package/dist/cjs/chunk/index.js +3 -0
  8. package/dist/cjs/chunk/index.js.map +1 -1
  9. package/dist/cjs/scan/pool.d.cts +15 -0
  10. package/dist/cjs/scan/pool.d.ts +15 -0
  11. package/dist/cjs/scan/pool.js +263 -0
  12. package/dist/cjs/scan/pool.js.map +1 -0
  13. package/dist/cjs/scan/reparse.d.cts +2 -0
  14. package/dist/cjs/scan/reparse.d.ts +2 -0
  15. package/dist/cjs/scan/reparse.js +15 -76
  16. package/dist/cjs/scan/reparse.js.map +1 -1
  17. package/dist/cjs/store/builder.d.cts +11 -0
  18. package/dist/cjs/store/builder.d.ts +11 -0
  19. package/dist/cjs/store/builder.js +27 -0
  20. package/dist/cjs/store/builder.js.map +1 -0
  21. package/dist/cjs/store/duckdb/lexical.d.cts +1 -0
  22. package/dist/cjs/store/duckdb/lexical.d.ts +1 -0
  23. package/dist/cjs/store/duckdb/lexical.js +21 -5
  24. package/dist/cjs/store/duckdb/lexical.js.map +1 -1
  25. package/dist/cjs/store/duckdb/open.d.cts +9 -8
  26. package/dist/cjs/store/duckdb/open.d.ts +9 -8
  27. package/dist/cjs/store/duckdb/open.js +70 -122
  28. package/dist/cjs/store/duckdb/open.js.map +1 -1
  29. package/dist/cjs/store/duckdb/reconcile.js +4 -0
  30. package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
  31. package/dist/cjs/store/duckdb/store.d.cts +1 -2
  32. package/dist/cjs/store/duckdb/store.d.ts +1 -2
  33. package/dist/cjs/store/duckdb/store.js +1 -26
  34. package/dist/cjs/store/duckdb/store.js.map +1 -1
  35. package/dist/cjs/store/index.d.cts +8 -3
  36. package/dist/cjs/store/index.d.ts +8 -3
  37. package/dist/cjs/store/index.js +36 -7
  38. package/dist/cjs/store/index.js.map +1 -1
  39. package/dist/cjs/store/open.d.cts +15 -0
  40. package/dist/cjs/store/open.d.ts +15 -0
  41. package/dist/cjs/store/open.js +516 -0
  42. package/dist/cjs/store/open.js.map +1 -0
  43. package/dist/cjs/store/reconcile.d.cts +2 -1
  44. package/dist/cjs/store/reconcile.d.ts +2 -1
  45. package/dist/cjs/store/reconcile.js +4 -2
  46. package/dist/cjs/store/reconcile.js.map +1 -1
  47. package/dist/cjs/store/{sqlite/signature.d.cts → signature.d.cts} +0 -3
  48. package/dist/cjs/store/{sqlite/signature.d.ts → signature.d.ts} +0 -3
  49. package/dist/cjs/store/signature.js +162 -0
  50. package/dist/cjs/store/signature.js.map +1 -0
  51. package/dist/cjs/store/sqlite/open.d.cts +9 -9
  52. package/dist/cjs/store/sqlite/open.d.ts +9 -9
  53. package/dist/cjs/store/sqlite/open.js +189 -201
  54. package/dist/cjs/store/sqlite/open.js.map +1 -1
  55. package/dist/cjs/store/sqlite/store.d.cts +1 -1
  56. package/dist/cjs/store/sqlite/store.d.ts +1 -1
  57. package/dist/cjs/store/sqlite/store.js +1 -13
  58. package/dist/cjs/store/sqlite/store.js.map +1 -1
  59. package/dist/cjs/store/turso/open.d.cts +6 -11
  60. package/dist/cjs/store/turso/open.d.ts +6 -11
  61. package/dist/cjs/store/turso/open.js +79 -171
  62. package/dist/cjs/store/turso/open.js.map +1 -1
  63. package/dist/cjs/store/turso/reconcile.d.cts +2 -0
  64. package/dist/cjs/store/turso/reconcile.d.ts +2 -0
  65. package/dist/cjs/store/turso/reconcile.js +16 -5
  66. package/dist/cjs/store/turso/reconcile.js.map +1 -1
  67. package/dist/cjs/store/turso/store.d.cts +1 -2
  68. package/dist/cjs/store/turso/store.d.ts +1 -2
  69. package/dist/cjs/store/turso/store.js +1 -13
  70. package/dist/cjs/store/turso/store.js.map +1 -1
  71. package/dist/cjs/store/types.d.cts +17 -5
  72. package/dist/cjs/store/types.d.ts +17 -5
  73. package/dist/cjs/store/types.js.map +1 -1
  74. package/dist/cjs/text/strip.js +3 -6
  75. package/dist/cjs/text/strip.js.map +1 -1
  76. package/dist/cjs/watch.js +28 -16
  77. package/dist/cjs/watch.js.map +1 -1
  78. package/dist/esm/chunk/extract.d.ts +1 -0
  79. package/dist/esm/chunk/extract.js +10 -2
  80. package/dist/esm/chunk/extract.js.map +1 -1
  81. package/dist/esm/chunk/index.d.ts +1 -1
  82. package/dist/esm/chunk/index.js +1 -1
  83. package/dist/esm/chunk/index.js.map +1 -1
  84. package/dist/esm/scan/pool.d.ts +15 -0
  85. package/dist/esm/scan/pool.js +77 -0
  86. package/dist/esm/scan/pool.js.map +1 -0
  87. package/dist/esm/scan/reparse.d.ts +2 -0
  88. package/dist/esm/scan/reparse.js +11 -58
  89. package/dist/esm/scan/reparse.js.map +1 -1
  90. package/dist/esm/store/builder.d.ts +11 -0
  91. package/dist/esm/store/builder.js +14 -0
  92. package/dist/esm/store/builder.js.map +1 -0
  93. package/dist/esm/store/duckdb/lexical.d.ts +1 -0
  94. package/dist/esm/store/duckdb/lexical.js +22 -9
  95. package/dist/esm/store/duckdb/lexical.js.map +1 -1
  96. package/dist/esm/store/duckdb/open.d.ts +9 -8
  97. package/dist/esm/store/duckdb/open.js +31 -57
  98. package/dist/esm/store/duckdb/open.js.map +1 -1
  99. package/dist/esm/store/duckdb/reconcile.js +4 -0
  100. package/dist/esm/store/duckdb/reconcile.js.map +1 -1
  101. package/dist/esm/store/duckdb/store.d.ts +1 -2
  102. package/dist/esm/store/duckdb/store.js +2 -11
  103. package/dist/esm/store/duckdb/store.js.map +1 -1
  104. package/dist/esm/store/index.d.ts +8 -3
  105. package/dist/esm/store/index.js +22 -7
  106. package/dist/esm/store/index.js.map +1 -1
  107. package/dist/esm/store/open.d.ts +15 -0
  108. package/dist/esm/store/open.js +137 -0
  109. package/dist/esm/store/open.js.map +1 -0
  110. package/dist/esm/store/reconcile.d.ts +2 -1
  111. package/dist/esm/store/reconcile.js +4 -2
  112. package/dist/esm/store/reconcile.js.map +1 -1
  113. package/dist/esm/store/{sqlite/signature.d.ts → signature.d.ts} +0 -3
  114. package/dist/esm/store/{sqlite/signature.js → signature.js} +3 -26
  115. package/dist/esm/store/signature.js.map +1 -0
  116. package/dist/esm/store/sqlite/open.d.ts +9 -9
  117. package/dist/esm/store/sqlite/open.js +81 -113
  118. package/dist/esm/store/sqlite/open.js.map +1 -1
  119. package/dist/esm/store/sqlite/store.d.ts +1 -1
  120. package/dist/esm/store/sqlite/store.js +2 -7
  121. package/dist/esm/store/sqlite/store.js.map +1 -1
  122. package/dist/esm/store/turso/open.d.ts +6 -11
  123. package/dist/esm/store/turso/open.js +30 -78
  124. package/dist/esm/store/turso/open.js.map +1 -1
  125. package/dist/esm/store/turso/reconcile.d.ts +2 -0
  126. package/dist/esm/store/turso/reconcile.js +12 -1
  127. package/dist/esm/store/turso/reconcile.js.map +1 -1
  128. package/dist/esm/store/turso/store.d.ts +1 -2
  129. package/dist/esm/store/turso/store.js +2 -7
  130. package/dist/esm/store/turso/store.js.map +1 -1
  131. package/dist/esm/store/types.d.ts +17 -5
  132. package/dist/esm/store/types.js.map +1 -1
  133. package/dist/esm/text/strip.js +3 -4
  134. package/dist/esm/text/strip.js.map +1 -1
  135. package/dist/esm/watch.js +5 -3
  136. package/dist/esm/watch.js.map +1 -1
  137. package/package.json +2 -2
  138. package/dist/cjs/store/sqlite/signature.js +0 -380
  139. package/dist/cjs/store/sqlite/signature.js.map +0 -1
  140. package/dist/esm/store/sqlite/signature.js.map +0 -1
@@ -1,2 +1,3 @@
1
1
  import type { Nodes } from 'mdast';
2
2
  export declare function extractText(node: Nodes): string;
3
+ export declare function extractTexts(nodes: Nodes[]): string;
@@ -1,2 +1,3 @@
1
1
  import type { Nodes } from 'mdast';
2
2
  export declare function extractText(node: Nodes): string;
3
+ export declare function extractTexts(nodes: Nodes[]): string;
@@ -2,10 +2,18 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "extractText", {
6
- enumerable: true,
7
- get: function() {
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get extractText () {
8
13
  return extractText;
14
+ },
15
+ get extractTexts () {
16
+ return extractTexts;
9
17
  }
10
18
  });
11
19
  // mdast has no wikilink, embed, or %%comment%% node -- literal text resolved by regex passes
@@ -46,7 +54,7 @@ function embedText(inner) {
46
54
  return anchorText(pipeIdx === -1 ? inner : inner.slice(0, pipeIdx));
47
55
  }
48
56
  function resolveFlavor(text) {
49
- return text.replace(COMMENT_PAIR, '').replace(EMBED, function(_, inner) {
57
+ return text.replace(HTML_COMMENT, '').replace(COMMENT_PAIR, '').replace(EMBED, function(_, inner) {
50
58
  return embedText(inner);
51
59
  }).replace(WIKILINK, function(_, inner) {
52
60
  return wikilinkText(inner);
@@ -130,8 +138,18 @@ function extractNode(node, code) {
130
138
  }
131
139
  var CODE_PLACEHOLDER = /\uE000(\d+)\uE000/g;
132
140
  function extractText(node) {
141
+ return extractTexts([
142
+ node
143
+ ]);
144
+ }
145
+ function extractTexts(nodes) {
133
146
  var code = [];
134
- var resolved = resolveFlavor(extractNode(node, code));
147
+ var joined = nodes.map(function(n) {
148
+ return extractNode(n, code);
149
+ }).filter(function(s) {
150
+ return s.length > 0;
151
+ }).join('\n');
152
+ var resolved = resolveFlavor(joined);
135
153
  return code.length === 0 ? resolved : resolved.replace(CODE_PLACEHOLDER, function(_, i) {
136
154
  return code[Number(i)];
137
155
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/extract.ts"],"sourcesContent":["import type { Nodes } from 'mdast';\n\n// mdast has no wikilink, embed, or %%comment%% node -- literal text resolved by regex passes\n// over non-code text (code/inlineCode is placeholder-held and spliced back verbatim, below).\nconst COMMENT_PAIR = /%%[\\s\\S]*?%%/g;\n// An embed always yields its target, whatever follows a pipe (a resize suffix, never an alias);\n// must run before the wikilink regex below, bang included, or that regex matches first.\nconst EMBED = /!\\[\\[([^\\]]+)\\]\\]/g;\nconst WIKILINK = /\\[\\[([^\\]]+)\\]\\]/g;\n// A trailing \" ^id\" is an Obsidian block anchor, valid only at a line's end; a caret elsewhere\n// (mid-line) is ordinary text and is left alone.\nconst BLOCK_ID = / \\^[A-Za-z0-9-]+$/gm;\n// A callout marker is only ever the first thing in a blockquote's text (Obsidian's grammar),\n// so this anchors to blockquote output alone -- never applied to prose in general.\nconst CALLOUT_MARKER = /^\\[!\\w[\\w-]*\\][+-]?[ \\t]?/;\n// An html node's value is raw HTML, block or inline: a full <!-- --> comment is dropped, any\n// remaining tags are stripped, and the text a browser would still render survives.\nconst HTML_COMMENT = /<!--[\\s\\S]*?-->/g;\nconst HTML_TAG = /<[^>]+>/g;\n\nfunction stripHtml(value: string): string {\n return value.replace(HTML_COMMENT, '').replace(HTML_TAG, '');\n}\n\n// A `#anchor` keeps its text (hash dropped), unlike links.ts's parseWikilinkInner (the resolver\n// authority), which discards it entirely -- replicated here since that return value doesn't fit.\nfunction anchorText(base: string): string {\n const hashIdx = base.indexOf('#');\n if (hashIdx === -1) return base.trim();\n const target = base.slice(0, hashIdx).trim();\n const anchor = base.slice(hashIdx + 1).trim();\n return target ? `${target} ${anchor}` : anchor;\n}\n\nfunction wikilinkText(inner: string): string {\n const pipeIdx = inner.indexOf('|');\n return pipeIdx === -1 ? anchorText(inner) : inner.slice(pipeIdx + 1).trim();\n}\n\nfunction embedText(inner: string): string {\n const pipeIdx = inner.indexOf('|');\n return anchorText(pipeIdx === -1 ? inner : inner.slice(0, pipeIdx));\n}\n\nfunction resolveFlavor(text: string): string {\n return text\n .replace(COMMENT_PAIR, '')\n .replace(EMBED, (_, inner: string) => embedText(inner))\n .replace(WIKILINK, (_, inner: string) => wikilinkText(inner))\n .replace(BLOCK_ID, '');\n}\n\n// Sibling blocks (list items, blockquote content, footnote bodies) joined one per line;\n// empties dropped so a blank child never widens the gap between its neighbors.\nfunction joinBlocks(nodes: Nodes[], code: string[]): string {\n return nodes\n .map((n) => extractNode(n, code))\n .filter((s) => s.length > 0)\n .join('\\n');\n}\n\n// Inline content (headings, paragraphs, emphasis, links) concatenated with no separator: the\n// source text nodes already carry whatever spacing separates them.\nfunction joinInline(nodes: Nodes[], code: string[]): string {\n return nodes.map((n) => extractNode(n, code)).join('');\n}\n\n// U+E000 (Private Use Area) never appears in real markdown text, so it is a collision-free\n// placeholder delimiter, spliced back to the literal code value after flavor resolution.\nfunction codePlaceholder(value: string, code: string[]): string {\n const idx = code.push(value) - 1;\n return `\\uE000${idx}\\uE000`;\n}\n\n// A GFM autolink's display text is its own target, missing only the scheme\n// mdast-util-gfm-autolink-literal fills into node.url (http:// for www., mailto: for an email).\nconst SCHEME_PREFIX = /^[a-z][a-z0-9+.-]*:\\/{0,2}/i;\nfunction isAutolink(url: string, text: string): boolean {\n return url === text || url.replace(SCHEME_PREFIX, '') === text;\n}\n\nfunction extractNode(node: Nodes, code: string[]): string {\n switch (node.type) {\n case 'root':\n case 'list':\n case 'listItem':\n case 'footnoteDefinition':\n return joinBlocks(node.children, code);\n case 'blockquote':\n return joinBlocks(node.children, code).replace(CALLOUT_MARKER, '');\n case 'link': {\n const text = joinInline(node.children, code);\n return isAutolink(node.url, text) ? '' : text;\n }\n case 'heading':\n case 'paragraph':\n case 'linkReference':\n case 'emphasis':\n case 'strong':\n case 'delete':\n return joinInline(node.children, code);\n case 'table':\n return node.children.map((n) => extractNode(n, code)).join('\\n');\n case 'tableRow':\n return node.children.map((n) => extractNode(n, code)).join(' ');\n case 'tableCell':\n return joinInline(node.children, code);\n case 'image':\n case 'imageReference':\n return node.alt ?? '';\n case 'text':\n return node.value;\n case 'inlineCode':\n case 'code':\n return codePlaceholder(node.value, code);\n case 'html':\n return stripHtml(node.value);\n case 'break':\n return ' ';\n default:\n return '';\n }\n}\n\nconst CODE_PLACEHOLDER = /\\uE000(\\d+)\\uE000/g;\n\n// Plain text of one mdast node (or a whole tree): heading/list/table structure is kept as text,\n// markup (emphasis, link targets, task and callout markers) is dropped. Pure, synchronous.\nexport function extractText(node: Nodes): string {\n const code: string[] = [];\n const resolved = resolveFlavor(extractNode(node, code));\n return code.length === 0 ? resolved : resolved.replace(CODE_PLACEHOLDER, (_, i: string) => code[Number(i)]);\n}\n"],"names":["extractText","COMMENT_PAIR","EMBED","WIKILINK","BLOCK_ID","CALLOUT_MARKER","HTML_COMMENT","HTML_TAG","stripHtml","value","replace","anchorText","base","hashIdx","indexOf","trim","target","slice","anchor","wikilinkText","inner","pipeIdx","embedText","resolveFlavor","text","_","joinBlocks","nodes","code","map","n","extractNode","filter","s","length","join","joinInline","codePlaceholder","idx","push","SCHEME_PREFIX","isAutolink","url","node","type","children","alt","CODE_PLACEHOLDER","resolved","i","Number"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/extract.ts"],"sourcesContent":["import type { Nodes } from 'mdast';\n\n// mdast has no wikilink, embed, or %%comment%% node -- literal text resolved by regex passes\n// over non-code text (code/inlineCode is placeholder-held and spliced back verbatim, below).\nconst COMMENT_PAIR = /%%[\\s\\S]*?%%/g;\n// An embed always yields its target, whatever follows a pipe (a resize suffix, never an alias);\n// must run before the wikilink regex below, bang included, or that regex matches first.\nconst EMBED = /!\\[\\[([^\\]]+)\\]\\]/g;\nconst WIKILINK = /\\[\\[([^\\]]+)\\]\\]/g;\n// A trailing \" ^id\" is an Obsidian block anchor, valid only at a line's end; a caret elsewhere\n// (mid-line) is ordinary text and is left alone.\nconst BLOCK_ID = / \\^[A-Za-z0-9-]+$/gm;\n// A callout marker is only ever the first thing in a blockquote's text (Obsidian's grammar),\n// so this anchors to blockquote output alone -- never applied to prose in general.\nconst CALLOUT_MARKER = /^\\[!\\w[\\w-]*\\][+-]?[ \\t]?/;\n// An html node's value is raw HTML, block or inline: a full <!-- --> comment is dropped, any\n// remaining tags are stripped, and the text a browser would still render survives.\nconst HTML_COMMENT = /<!--[\\s\\S]*?-->/g;\nconst HTML_TAG = /<[^>]+>/g;\n\nfunction stripHtml(value: string): string {\n return value.replace(HTML_COMMENT, '').replace(HTML_TAG, '');\n}\n\n// A `#anchor` keeps its text (hash dropped), unlike links.ts's parseWikilinkInner (the resolver\n// authority), which discards it entirely -- replicated here since that return value doesn't fit.\nfunction anchorText(base: string): string {\n const hashIdx = base.indexOf('#');\n if (hashIdx === -1) return base.trim();\n const target = base.slice(0, hashIdx).trim();\n const anchor = base.slice(hashIdx + 1).trim();\n return target ? `${target} ${anchor}` : anchor;\n}\n\nfunction wikilinkText(inner: string): string {\n const pipeIdx = inner.indexOf('|');\n return pipeIdx === -1 ? anchorText(inner) : inner.slice(pipeIdx + 1).trim();\n}\n\nfunction embedText(inner: string): string {\n const pipeIdx = inner.indexOf('|');\n return anchorText(pipeIdx === -1 ? inner : inner.slice(0, pipeIdx));\n}\n\nfunction resolveFlavor(text: string): string {\n return text\n .replace(HTML_COMMENT, '')\n .replace(COMMENT_PAIR, '')\n .replace(EMBED, (_, inner: string) => embedText(inner))\n .replace(WIKILINK, (_, inner: string) => wikilinkText(inner))\n .replace(BLOCK_ID, '');\n}\n\n// Sibling blocks (list items, blockquote content, footnote bodies) joined one per line;\n// empties dropped so a blank child never widens the gap between its neighbors.\nfunction joinBlocks(nodes: Nodes[], code: string[]): string {\n return nodes\n .map((n) => extractNode(n, code))\n .filter((s) => s.length > 0)\n .join('\\n');\n}\n\n// Inline content (headings, paragraphs, emphasis, links) concatenated with no separator: the\n// source text nodes already carry whatever spacing separates them.\nfunction joinInline(nodes: Nodes[], code: string[]): string {\n return nodes.map((n) => extractNode(n, code)).join('');\n}\n\n// U+E000 (Private Use Area) never appears in real markdown text, so it is a collision-free\n// placeholder delimiter, spliced back to the literal code value after flavor resolution.\nfunction codePlaceholder(value: string, code: string[]): string {\n const idx = code.push(value) - 1;\n return `\\uE000${idx}\\uE000`;\n}\n\n// A GFM autolink's display text is its own target, missing only the scheme\n// mdast-util-gfm-autolink-literal fills into node.url (http:// for www., mailto: for an email).\nconst SCHEME_PREFIX = /^[a-z][a-z0-9+.-]*:\\/{0,2}/i;\nfunction isAutolink(url: string, text: string): boolean {\n return url === text || url.replace(SCHEME_PREFIX, '') === text;\n}\n\nfunction extractNode(node: Nodes, code: string[]): string {\n switch (node.type) {\n case 'root':\n case 'list':\n case 'listItem':\n case 'footnoteDefinition':\n return joinBlocks(node.children, code);\n case 'blockquote':\n return joinBlocks(node.children, code).replace(CALLOUT_MARKER, '');\n case 'link': {\n const text = joinInline(node.children, code);\n return isAutolink(node.url, text) ? '' : text;\n }\n case 'heading':\n case 'paragraph':\n case 'linkReference':\n case 'emphasis':\n case 'strong':\n case 'delete':\n return joinInline(node.children, code);\n case 'table':\n return node.children.map((n) => extractNode(n, code)).join('\\n');\n case 'tableRow':\n return node.children.map((n) => extractNode(n, code)).join(' ');\n case 'tableCell':\n return joinInline(node.children, code);\n case 'image':\n case 'imageReference':\n return node.alt ?? '';\n case 'text':\n return node.value;\n case 'inlineCode':\n case 'code':\n return codePlaceholder(node.value, code);\n case 'html':\n return stripHtml(node.value);\n case 'break':\n return ' ';\n default:\n return '';\n }\n}\n\nconst CODE_PLACEHOLDER = /\\uE000(\\d+)\\uE000/g;\n\n// Plain text of one mdast node (or a whole tree): heading/list/table structure is kept as text,\n// markup (emphasis, link targets, task and callout markers) is dropped. Pure, synchronous.\nexport function extractText(node: Nodes): string {\n return extractTexts([node]);\n}\n\n// Blocks resolved together: a blank line inside %%...%% splits it across blocks, and a per-block\n// strip then never sees the closing %%. Code stays placeholder-held across all of them.\nexport function extractTexts(nodes: Nodes[]): string {\n const code: string[] = [];\n const joined = nodes\n .map((n) => extractNode(n, code))\n .filter((s) => s.length > 0)\n .join('\\n');\n const resolved = resolveFlavor(joined);\n return code.length === 0 ? resolved : resolved.replace(CODE_PLACEHOLDER, (_, i: string) => code[Number(i)]);\n}\n"],"names":["extractText","extractTexts","COMMENT_PAIR","EMBED","WIKILINK","BLOCK_ID","CALLOUT_MARKER","HTML_COMMENT","HTML_TAG","stripHtml","value","replace","anchorText","base","hashIdx","indexOf","trim","target","slice","anchor","wikilinkText","inner","pipeIdx","embedText","resolveFlavor","text","_","joinBlocks","nodes","code","map","n","extractNode","filter","s","length","join","joinInline","codePlaceholder","idx","push","SCHEME_PREFIX","isAutolink","url","node","type","children","alt","CODE_PLACEHOLDER","joined","resolved","i","Number"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import type { Block, Chunk, ChunkOptions } from './types.js';
2
2
  export declare function chunkFromBlocks(blocks: Block[], body: string, opts?: ChunkOptions): Chunk[];
3
3
  export declare function chunk(body: string, opts?: ChunkOptions): Chunk[];
4
- export { extractText } from './extract.js';
4
+ export { extractText, extractTexts } from './extract.js';
5
5
  export { DEFAULT_TARGET_TOKENS, estimateTokens } from './group.js';
6
6
  export { parse } from './parse.js';
7
7
  export type { Block, BlockType, Chunk, ChunkOptions } from './types.js';
@@ -1,7 +1,7 @@
1
1
  import type { Block, Chunk, ChunkOptions } from './types.js';
2
2
  export declare function chunkFromBlocks(blocks: Block[], body: string, opts?: ChunkOptions): Chunk[];
3
3
  export declare function chunk(body: string, opts?: ChunkOptions): Chunk[];
4
- export { extractText } from './extract.js';
4
+ export { extractText, extractTexts } from './extract.js';
5
5
  export { DEFAULT_TARGET_TOKENS, estimateTokens } from './group.js';
6
6
  export { parse } from './parse.js';
7
7
  export type { Block, BlockType, Chunk, ChunkOptions } from './types.js';
@@ -27,6 +27,9 @@ _export(exports, {
27
27
  get extractText () {
28
28
  return _extractts.extractText;
29
29
  },
30
+ get extractTexts () {
31
+ return _extractts.extractTexts;
32
+ },
30
33
  get parse () {
31
34
  return _parsets.parse;
32
35
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/index.ts"],"sourcesContent":["import { group } from './group.ts';\nimport { parse } from './parse.ts';\nimport type { Block, Chunk, ChunkOptions } from './types.ts';\n\n// Groups blocks a caller already parsed (e.g. scan/index.ts, sharing one parse with the FTS\n// text path) against the same body they came from, per opts (D1/D3).\nexport function chunkFromBlocks(blocks: Block[], body: string, opts?: ChunkOptions): Chunk[] {\n return group(blocks, body, opts);\n}\n\n// Pure, deterministic function of file content; chunk semantics are version-stamped via\n// CHUNK_VERSION (./version.ts). Algorithm and evidence: BENCHMARKING.md, \"The chunking algorithm\".\nexport function chunk(body: string, opts?: ChunkOptions): Chunk[] {\n return chunkFromBlocks(parse(body), body, opts);\n}\n\nexport { extractText } from './extract.ts';\nexport { DEFAULT_TARGET_TOKENS, estimateTokens } from './group.ts';\nexport { parse } from './parse.ts';\nexport type { Block, BlockType, Chunk, ChunkOptions } from './types.ts';\nexport { CHUNK_VERSION } from './version.ts';\n"],"names":["CHUNK_VERSION","DEFAULT_TARGET_TOKENS","chunk","chunkFromBlocks","estimateTokens","extractText","parse","blocks","body","opts","group"],"mappings":";;;;;;;;;;;QAoBSA;eAAAA,wBAAa;;QAHbC;eAAAA,8BAAqB;;QALdC;eAAAA;;QANAC;eAAAA;;QAWgBC;eAAAA,uBAAc;;QADrCC;eAAAA,sBAAW;;QAEXC;eAAAA,cAAK;;;uBAlBQ;uBACA;yBAeM;yBAIE;AAdvB,SAASH,gBAAgBI,MAAe,EAAEC,IAAY,EAAEC,IAAmB;IAChF,OAAOC,IAAAA,cAAK,EAACH,QAAQC,MAAMC;AAC7B;AAIO,SAASP,MAAMM,IAAY,EAAEC,IAAmB;IACrD,OAAON,gBAAgBG,IAAAA,cAAK,EAACE,OAAOA,MAAMC;AAC5C"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/index.ts"],"sourcesContent":["import { group } from './group.ts';\nimport { parse } from './parse.ts';\nimport type { Block, Chunk, ChunkOptions } from './types.ts';\n\n// Groups blocks a caller already parsed (e.g. scan/index.ts, sharing one parse with the FTS\n// text path) against the same body they came from, per opts (D1/D3).\nexport function chunkFromBlocks(blocks: Block[], body: string, opts?: ChunkOptions): Chunk[] {\n return group(blocks, body, opts);\n}\n\n// Pure, deterministic function of file content; chunk semantics are version-stamped via\n// CHUNK_VERSION (./version.ts). Algorithm and evidence: BENCHMARKING.md, \"The chunking algorithm\".\nexport function chunk(body: string, opts?: ChunkOptions): Chunk[] {\n return chunkFromBlocks(parse(body), body, opts);\n}\n\nexport { extractText, extractTexts } from './extract.ts';\nexport { DEFAULT_TARGET_TOKENS, estimateTokens } from './group.ts';\nexport { parse } from './parse.ts';\nexport type { Block, BlockType, Chunk, ChunkOptions } from './types.ts';\nexport { CHUNK_VERSION } from './version.ts';\n"],"names":["CHUNK_VERSION","DEFAULT_TARGET_TOKENS","chunk","chunkFromBlocks","estimateTokens","extractText","extractTexts","parse","blocks","body","opts","group"],"mappings":";;;;;;;;;;;QAoBSA;eAAAA,wBAAa;;QAHbC;eAAAA,8BAAqB;;QALdC;eAAAA;;QANAC;eAAAA;;QAWgBC;eAAAA,uBAAc;;QADrCC;eAAAA,sBAAW;;QAAEC;eAAAA,uBAAY;;QAEzBC;eAAAA,cAAK;;;uBAlBQ;uBACA;yBAeoB;yBAIZ;AAdvB,SAASJ,gBAAgBK,MAAe,EAAEC,IAAY,EAAEC,IAAmB;IAChF,OAAOC,IAAAA,cAAK,EAACH,QAAQC,MAAMC;AAC7B;AAIO,SAASR,MAAMO,IAAY,EAAEC,IAAmB;IACrD,OAAOP,gBAAgBI,IAAAA,cAAK,EAACE,OAAOA,MAAMC;AAC5C"}
@@ -0,0 +1,15 @@
1
+ import type { Config } from '../config/index.js';
2
+ import type { Feature } from '../features/types.js';
3
+ import type { ParsedDoc } from '../scan/index.js';
4
+ import type { FileStat } from './list.js';
5
+ export type FileResult = {
6
+ doc: ParsedDoc;
7
+ warnings: string[];
8
+ };
9
+ export declare class ParsePool {
10
+ private pool;
11
+ poolsCreated: number;
12
+ private ensure;
13
+ run(files: FileStat[], features: Feature[], cfg: Config, onParsed: ((done: number) => void) | undefined, maxWorkers: number): Promise<FileResult[]>;
14
+ close(): Promise<void>;
15
+ }
@@ -0,0 +1,15 @@
1
+ import type { Config } from '../config/index.js';
2
+ import type { Feature } from '../features/types.js';
3
+ import type { ParsedDoc } from '../scan/index.js';
4
+ import type { FileStat } from './list.js';
5
+ export type FileResult = {
6
+ doc: ParsedDoc;
7
+ warnings: string[];
8
+ };
9
+ export declare class ParsePool {
10
+ private pool;
11
+ poolsCreated: number;
12
+ private ensure;
13
+ run(files: FileStat[], features: Feature[], cfg: Config, onParsed: ((done: number) => void) | undefined, maxWorkers: number): Promise<FileResult[]>;
14
+ close(): Promise<void>;
15
+ }
@@ -0,0 +1,263 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "ParsePool", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return ParsePool;
9
+ }
10
+ });
11
+ var _nodemodule = require("node:module");
12
+ var _nodepath = require("node:path");
13
+ var _workererrorts = require("./worker-error.js");
14
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
15
+ try {
16
+ var info = gen[key](arg);
17
+ var value = info.value;
18
+ } catch (error) {
19
+ reject(error);
20
+ return;
21
+ }
22
+ if (info.done) resolve(value);
23
+ else Promise.resolve(value).then(_next, _throw);
24
+ }
25
+ function _async_to_generator(fn) {
26
+ return function() {
27
+ var self = this, args = arguments;
28
+ return new Promise(function(resolve, reject) {
29
+ var gen = fn.apply(self, args);
30
+ function _next(value) {
31
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
32
+ }
33
+ function _throw(err) {
34
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
35
+ }
36
+ _next(undefined);
37
+ });
38
+ };
39
+ }
40
+ function _class_call_check(instance, Constructor) {
41
+ if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
42
+ }
43
+ function _ts_generator(thisArg, body) {
44
+ var f, y, t, _ = {
45
+ label: 0,
46
+ sent: function() {
47
+ if (t[0] & 1) throw t[1];
48
+ return t[1];
49
+ },
50
+ trys: [],
51
+ ops: []
52
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
53
+ return d(g, "next", {
54
+ value: verb(0)
55
+ }), d(g, "throw", {
56
+ value: verb(1)
57
+ }), d(g, "return", {
58
+ value: verb(2)
59
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
60
+ value: function() {
61
+ return this;
62
+ }
63
+ }), g;
64
+ function verb(n) {
65
+ return function(v) {
66
+ return step([
67
+ n,
68
+ v
69
+ ]);
70
+ };
71
+ }
72
+ function step(op) {
73
+ if (f) throw new TypeError("Generator is already executing.");
74
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
75
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
76
+ if (y = 0, t) op = [
77
+ op[0] & 2,
78
+ t.value
79
+ ];
80
+ switch(op[0]){
81
+ case 0:
82
+ case 1:
83
+ t = op;
84
+ break;
85
+ case 4:
86
+ _.label++;
87
+ return {
88
+ value: op[1],
89
+ done: false
90
+ };
91
+ case 5:
92
+ _.label++;
93
+ y = op[1];
94
+ op = [
95
+ 0
96
+ ];
97
+ continue;
98
+ case 7:
99
+ op = _.ops.pop();
100
+ _.trys.pop();
101
+ continue;
102
+ default:
103
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
104
+ _ = 0;
105
+ continue;
106
+ }
107
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
108
+ _.label = op[1];
109
+ break;
110
+ }
111
+ if (op[0] === 6 && _.label < t[1]) {
112
+ _.label = t[1];
113
+ t = op;
114
+ break;
115
+ }
116
+ if (t && _.label < t[2]) {
117
+ _.label = t[2];
118
+ _.ops.push(op);
119
+ break;
120
+ }
121
+ if (t[2]) _.ops.pop();
122
+ _.trys.pop();
123
+ continue;
124
+ }
125
+ op = body.call(thisArg, _);
126
+ } catch (e) {
127
+ op = [
128
+ 6,
129
+ e
130
+ ];
131
+ y = 0;
132
+ } finally{
133
+ f = t = 0;
134
+ }
135
+ if (op[0] & 5) throw op[1];
136
+ return {
137
+ value: op[0] ? op[1] : void 0,
138
+ done: true
139
+ };
140
+ }
141
+ }
142
+ // Tinypool is ESM-only; our floor (>=22.20) has native require(esm), so the tier-2 house deferral reaches it.
143
+ var _require = typeof require === 'undefined' ? (0, _nodemodule.createRequire)(require("url").pathToFileURL(__filename).toString()) : require;
144
+ // Worker MUST load from dist/cjs/: a worker_threads thread is a fresh realm with no inherited
145
+ // TS loader hook, so a source path cannot work. Resolved on first pooled dispatch, not at import.
146
+ var workerFile;
147
+ function resolveWorkerFile() {
148
+ if (workerFile) return workerFile;
149
+ var load = (0, _nodemodule.createRequire)(require("url").pathToFileURL(__filename).toString());
150
+ for(var _i = 0, _iter = [
151
+ '..',
152
+ '../..',
153
+ '../../..'
154
+ ]; _i < _iter.length; _i++){
155
+ var rel = _iter[_i];
156
+ try {
157
+ if (load("".concat(rel, "/package.json")).name === 'sensemaking') {
158
+ workerFile = (0, _nodepath.join)((0, _nodepath.dirname)(load.resolve("".concat(rel, "/package.json"))), 'dist', 'cjs', 'workers', 'parse.js');
159
+ return workerFile;
160
+ }
161
+ } catch (unused) {}
162
+ }
163
+ throw new Error('cannot locate the sensemaking package root, so the parse worker cannot be found; run npm run build');
164
+ }
165
+ var ParsePool = /*#__PURE__*/ function() {
166
+ "use strict";
167
+ function ParsePool() {
168
+ _class_call_check(this, ParsePool);
169
+ // Tinypools this instance has constructed. One dispatch or a hundred should leave it at 1;
170
+ // it is how a caller, and the specs, observe that a lifetime reuses its pool rather than churning one.
171
+ this.poolsCreated = 0;
172
+ }
173
+ var _proto = ParsePool.prototype;
174
+ _proto.ensure = function ensure(workerData, maxWorkers) {
175
+ if (!this.pool) {
176
+ var Tinypool = _require('tinypool').Tinypool;
177
+ this.pool = new Tinypool({
178
+ filename: resolveWorkerFile(),
179
+ minThreads: maxWorkers,
180
+ maxThreads: maxWorkers,
181
+ workerData: workerData
182
+ });
183
+ this.poolsCreated++;
184
+ }
185
+ return this.pool;
186
+ };
187
+ // Never the tree: a worker task carries one FileStat and returns only what parseFile returns --
188
+ // extracted text and feature values, never the mdast tree.
189
+ _proto.run = function run(files, features, cfg, onParsed, maxWorkers) {
190
+ return _async_to_generator(function() {
191
+ var workerData, pool, done;
192
+ return _ts_generator(this, function(_state) {
193
+ // cfg and the feature selection are constant for the dispatch, so they cross once per worker
194
+ // as workerData. Features carry closures and cannot cross at all; only their names do.
195
+ workerData = {
196
+ cfg: cfg,
197
+ featureNames: features.map(function(feature) {
198
+ return feature.name;
199
+ })
200
+ };
201
+ pool = this.ensure(workerData, maxWorkers);
202
+ done = 0;
203
+ // Promise.all over a mapped array is load-bearing: the resolved array keeps `files` order
204
+ // regardless of task completion order, which first-seen column order depends on downstream.
205
+ return [
206
+ 2,
207
+ Promise.all(files.map(function(file) {
208
+ return _async_to_generator(function() {
209
+ var result;
210
+ return _ts_generator(this, function(_state) {
211
+ switch(_state.label){
212
+ case 0:
213
+ return [
214
+ 4,
215
+ pool.run(file)
216
+ ];
217
+ case 1:
218
+ result = _state.sent();
219
+ if (!result.ok) throw (0, _workererrorts.reviveError)(result.error);
220
+ onParsed === null || onParsed === void 0 ? void 0 : onParsed(++done);
221
+ return [
222
+ 2,
223
+ {
224
+ doc: result.doc,
225
+ warnings: result.warnings
226
+ }
227
+ ];
228
+ }
229
+ });
230
+ })();
231
+ }))
232
+ ];
233
+ });
234
+ }).call(this);
235
+ };
236
+ // A pool never created costs nothing to destroy.
237
+ _proto.close = function close() {
238
+ return _async_to_generator(function() {
239
+ var pool;
240
+ return _ts_generator(this, function(_state) {
241
+ switch(_state.label){
242
+ case 0:
243
+ if (!this.pool) return [
244
+ 2
245
+ ];
246
+ pool = this.pool;
247
+ this.pool = undefined;
248
+ return [
249
+ 4,
250
+ pool.destroy()
251
+ ];
252
+ case 1:
253
+ _state.sent();
254
+ return [
255
+ 2
256
+ ];
257
+ }
258
+ });
259
+ }).call(this);
260
+ };
261
+ return ParsePool;
262
+ }();
263
+ /* 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/scan/pool.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\n// Type-only: erased at build, but keeps depcheck's usage check satisfied for the tier-2\n// `_require` below (see coding-standards' deferral tiers).\nimport type * as TinypoolNS from 'tinypool';\nimport type { Config } from '../config/index.ts';\nimport type { Feature } from '../features/types.ts';\nimport type { ParsedDoc } from '../scan/index.ts';\nimport type { ParseTask, ParseTaskResult, ParseWorkerData } from '../workers/parse.ts';\nimport type { FileStat } from './list.ts';\nimport { reviveError } from './worker-error.ts';\n\n// Tinypool is ESM-only; our floor (>=22.20) has native require(esm), so the tier-2 house deferral reaches it.\nconst _require = typeof require === 'undefined' ? createRequire(import.meta.url) : require;\n\n// Worker MUST load from dist/cjs/: a worker_threads thread is a fresh realm with no inherited\n// TS loader hook, so a source path cannot work. Resolved on first pooled dispatch, not at import.\nlet workerFile: string | undefined;\nfunction resolveWorkerFile(): string {\n if (workerFile) return workerFile;\n const load = createRequire(import.meta.url);\n for (const rel of ['..', '../..', '../../..']) {\n try {\n if ((load(`${rel}/package.json`) as { name?: string }).name === 'sensemaking') {\n workerFile = join(dirname(load.resolve(`${rel}/package.json`)), 'dist', 'cjs', 'workers', 'parse.js');\n return workerFile;\n }\n } catch {}\n }\n throw new Error('cannot locate the sensemaking package root, so the parse worker cannot be found; run npm run build');\n}\n\nexport type FileResult = { doc: ParsedDoc; warnings: string[] };\n\n// One Tinypool per instance, created lazily on first dispatch and reused by every later call:\n// a builder owns one of these for its whole lifetime instead of paying pool startup per reconcile.\nexport class ParsePool {\n private pool: TinypoolNS.Tinypool | undefined;\n // Tinypools this instance has constructed. One dispatch or a hundred should leave it at 1;\n // it is how a caller, and the specs, observe that a lifetime reuses its pool rather than churning one.\n poolsCreated = 0;\n\n private ensure(workerData: ParseWorkerData, maxWorkers: number): TinypoolNS.Tinypool {\n if (!this.pool) {\n const { Tinypool } = _require('tinypool') as typeof TinypoolNS;\n this.pool = new Tinypool({ filename: resolveWorkerFile(), minThreads: maxWorkers, maxThreads: maxWorkers, workerData });\n this.poolsCreated++;\n }\n return this.pool;\n }\n\n // Never the tree: a worker task carries one FileStat and returns only what parseFile returns --\n // extracted text and feature values, never the mdast tree.\n async run(files: FileStat[], features: Feature[], cfg: Config, onParsed: ((done: number) => void) | undefined, maxWorkers: number): Promise<FileResult[]> {\n // cfg and the feature selection are constant for the dispatch, so they cross once per worker\n // as workerData. Features carry closures and cannot cross at all; only their names do.\n const workerData: ParseWorkerData = { cfg, featureNames: features.map((feature) => feature.name) };\n const pool = this.ensure(workerData, maxWorkers);\n let done = 0;\n // Promise.all over a mapped array is load-bearing: the resolved array keeps `files` order\n // regardless of task completion order, which first-seen column order depends on downstream.\n return Promise.all(\n files.map(async (file): Promise<FileResult> => {\n const result = (await pool.run(file as ParseTask)) as ParseTaskResult;\n if (!result.ok) throw reviveError(result.error);\n onParsed?.(++done);\n return { doc: result.doc, warnings: result.warnings };\n })\n );\n }\n\n // A pool never created costs nothing to destroy.\n async close(): Promise<void> {\n if (!this.pool) return;\n const pool = this.pool;\n this.pool = undefined;\n await pool.destroy();\n }\n}\n"],"names":["ParsePool","_require","require","createRequire","workerFile","resolveWorkerFile","load","rel","name","join","dirname","resolve","Error","poolsCreated","ensure","workerData","maxWorkers","pool","Tinypool","filename","minThreads","maxThreads","run","files","features","cfg","onParsed","done","featureNames","map","feature","Promise","all","file","result","ok","reviveError","error","doc","warnings","close","undefined","destroy"],"mappings":";;;;+BAoCaA;;;eAAAA;;;0BApCiB;wBACA;6BASF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE5B,8GAA8G;AAC9G,IAAMC,WAAW,OAAOC,YAAY,cAAcC,IAAAA,yBAAa,EAAC,uDAAmBD;AAEnF,8FAA8F;AAC9F,kGAAkG;AAClG,IAAIE;AACJ,SAASC;IACP,IAAID,YAAY,OAAOA;IACvB,IAAME,OAAOH,IAAAA,yBAAa,EAAC;IAC3B,gBAAkB,QAAA;QAAC;QAAM;QAAS;KAAW,OAA3B,mBAA6B;YAApCI,MAAO;QAChB,IAAI;YACF,IAAI,AAACD,KAAK,AAAC,GAAM,OAAJC,KAAI,kBAAsCC,IAAI,KAAK,eAAe;gBAC7EJ,aAAaK,IAAAA,cAAI,EAACC,IAAAA,iBAAO,EAACJ,KAAKK,OAAO,CAAC,AAAC,GAAM,OAAJJ,KAAI,oBAAkB,QAAQ,OAAO,WAAW;gBAC1F,OAAOH;YACT;QACF,EAAE,eAAM,CAAC;IACX;IACA,MAAM,IAAIQ,MAAM;AAClB;AAMO,IAAA,AAAMZ,0BAAN;;aAAMA;gCAAAA;QAEX,2FAA2F;QAC3F,uGAAuG;aACvGa,eAAe;;iBAJJb;IAMX,OAAQc,MAOP,GAPD,SAAQA,OAAOC,UAA2B,EAAEC,UAAkB;QAC5D,IAAI,CAAC,IAAI,CAACC,IAAI,EAAE;YACd,IAAM,AAAEC,WAAajB,SAAS,YAAtBiB;YACR,IAAI,CAACD,IAAI,GAAG,IAAIC,SAAS;gBAAEC,UAAUd;gBAAqBe,YAAYJ;gBAAYK,YAAYL;gBAAYD,YAAAA;YAAW;YACrH,IAAI,CAACF,YAAY;QACnB;QACA,OAAO,IAAI,CAACI,IAAI;IAClB;IAEA,gGAAgG;IAChG,2DAA2D;IAC3D,OAAMK,GAgBL,GAhBD,SAAMA,IAAIC,KAAiB,EAAEC,QAAmB,EAAEC,GAAW,EAAEC,QAA8C,EAAEV,UAAkB;;gBAGzHD,YACAE,MACFU;;gBAJJ,6FAA6F;gBAC7F,uFAAuF;gBACjFZ,aAA8B;oBAAEU,KAAAA;oBAAKG,cAAcJ,SAASK,GAAG,CAAC,SAACC;+BAAYA,QAAQtB,IAAI;;gBAAE;gBAC3FS,OAAO,IAAI,CAACH,MAAM,CAACC,YAAYC;gBACjCW,OAAO;gBACX,0FAA0F;gBAC1F,4FAA4F;gBAC5F;;oBAAOI,QAAQC,GAAG,CAChBT,MAAMM,GAAG,CAAC,SAAOI;;gCACTC;;;;wCAAU;;4CAAMjB,KAAKK,GAAG,CAACW;;;wCAAzBC,SAAU;wCAChB,IAAI,CAACA,OAAOC,EAAE,EAAE,MAAMC,IAAAA,0BAAW,EAACF,OAAOG,KAAK;wCAC9CX,qBAAAA,+BAAAA,SAAW,EAAEC;wCACb;;4CAAO;gDAAEW,KAAKJ,OAAOI,GAAG;gDAAEC,UAAUL,OAAOK,QAAQ;4CAAC;;;;wBACtD;;;;QAEJ;;IAEA,iDAAiD;IACjD,OAAMC,KAKL,GALD,SAAMA;;gBAEEvB;;;;wBADN,IAAI,CAAC,IAAI,CAACA,IAAI,EAAE;;;wBACVA,OAAO,IAAI,CAACA,IAAI;wBACtB,IAAI,CAACA,IAAI,GAAGwB;wBACZ;;4BAAMxB,KAAKyB,OAAO;;;wBAAlB;;;;;;QACF;;WAzCW1C"}
@@ -2,6 +2,7 @@ import type { Config } from '../config/index.js';
2
2
  import type { Feature } from '../features/types.js';
3
3
  import type { ParsedDoc } from './index.js';
4
4
  import type { FileStat } from './list.js';
5
+ import { ParsePool } from './pool.js';
5
6
  export interface ReparseResult {
6
7
  docs: ParsedDoc[];
7
8
  warnings: string[];
@@ -10,6 +11,7 @@ export interface ReparseResult {
10
11
  export interface ReparseOptions {
11
12
  threshold?: number;
12
13
  maxWorkers?: number;
14
+ pool?: ParsePool;
13
15
  }
14
16
  export declare function featuresForFile(features: Feature[], cfg: Config, file: FileStat): Feature[];
15
17
  export declare function reparseFiles(files: FileStat[], features: Feature[], cfg: Config, knownColumns: ReadonlySet<string>, onParsed?: (done: number) => void, options?: ReparseOptions): Promise<ReparseResult>;
@@ -2,6 +2,7 @@ import type { Config } from '../config/index.js';
2
2
  import type { Feature } from '../features/types.js';
3
3
  import type { ParsedDoc } from './index.js';
4
4
  import type { FileStat } from './list.js';
5
+ import { ParsePool } from './pool.js';
5
6
  export interface ReparseResult {
6
7
  docs: ParsedDoc[];
7
8
  warnings: string[];
@@ -10,6 +11,7 @@ export interface ReparseResult {
10
11
  export interface ReparseOptions {
11
12
  threshold?: number;
12
13
  maxWorkers?: number;
14
+ pool?: ParsePool;
13
15
  }
14
16
  export declare function featuresForFile(features: Feature[], cfg: Config, file: FileStat): Feature[];
15
17
  export declare function reparseFiles(files: FileStat[], features: Feature[], cfg: Config, knownColumns: ReadonlySet<string>, onParsed?: (done: number) => void, options?: ReparseOptions): Promise<ReparseResult>;
@@ -16,11 +16,9 @@ _export(exports, {
16
16
  return reparseFiles;
17
17
  }
18
18
  });
19
- var _nodemodule = require("node:module");
20
19
  var _nodeos = require("node:os");
21
- var _nodepath = require("node:path");
22
20
  var _indexts = require("./index.js");
23
- var _workererrorts = require("./worker-error.js");
21
+ var _poolts = require("./pool.js");
24
22
  function _array_like_to_array(arr, len) {
25
23
  if (len == null || len > arr.length) len = arr.length;
26
24
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
@@ -173,34 +171,10 @@ function _unsupported_iterable_to_array(o, minLen) {
173
171
  if (n === "Map" || n === "Set") return Array.from(n);
174
172
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
175
173
  }
176
- // Tinypool is ESM-only; our floor (>=22.20) has native require(esm), so the tier-2 house deferral reaches it.
177
- // Deferred (not top-level) because most reconciles stay below DEFAULT_THRESHOLD and shouldn't pay for pool machinery they never use.
178
- var _require = typeof require === 'undefined' ? (0, _nodemodule.createRequire)(require("url").pathToFileURL(__filename).toString()) : require;
179
174
  // Measured 2026-08-29 on a 14-core Apple M4 Pro: serial and pooled cross between 160-180 files
180
175
  // (pool fixed cost ~85-100ms), so 200 keeps margin. 8 workers ties 10 in a 6,566-file sweep; 12+ trends worse.
181
176
  var DEFAULT_THRESHOLD = 200;
182
177
  var DEFAULT_MAX_WORKERS = 8;
183
- // Worker MUST load from dist/cjs/: a worker_threads thread is a fresh realm with no inherited
184
- // TS loader hook, so a source path cannot work. Resolved on first pooled dispatch, not at import.
185
- var workerFile;
186
- function resolveWorkerFile() {
187
- if (workerFile) return workerFile;
188
- var load = (0, _nodemodule.createRequire)(require("url").pathToFileURL(__filename).toString());
189
- for(var _i = 0, _iter = [
190
- '..',
191
- '../..',
192
- '../../..'
193
- ]; _i < _iter.length; _i++){
194
- var rel = _iter[_i];
195
- try {
196
- if (load("".concat(rel, "/package.json")).name === 'sensemaking') {
197
- workerFile = (0, _nodepath.join)((0, _nodepath.dirname)(load.resolve("".concat(rel, "/package.json"))), 'dist', 'cjs', 'workers', 'parse.js');
198
- return workerFile;
199
- }
200
- } catch (unused) {}
201
- }
202
- throw new Error('cannot locate the sensemaking package root, so the parse worker cannot be found; run npm run build');
203
- }
204
178
  function featuresForFile(features, cfg, file) {
205
179
  return features.filter(function(feature) {
206
180
  return !feature.enabledForFile || feature.enabledForFile(cfg, file);
@@ -233,30 +207,19 @@ function reparseSerial(files, features, cfg, onParsed) {
233
207
  }
234
208
  return results;
235
209
  }
236
- // Never the tree: a worker task carries one FileStat and returns only what parseFile returns --
237
- // extracted text and feature values. Pool created once here, destroyed once dispatch finishes.
238
- function reparsePooled(files, features, cfg, onParsed, maxWorkers) {
210
+ // Dispatches through `pool` when the caller owns one (a builder, kept alive across calls); with
211
+ // none given, opens an ephemeral ParsePool for this call alone and always closes it.
212
+ function reparsePooled(files, features, cfg, onParsed, maxWorkers, pool) {
239
213
  return _async_to_generator(function() {
240
- var Tinypool, workerData, pool, done, results, err;
214
+ var ephemeral, results, err;
241
215
  return _ts_generator(this, function(_state) {
242
216
  switch(_state.label){
243
217
  case 0:
244
- Tinypool = _require('tinypool').Tinypool;
245
- // cfg and the feature selection are constant for the dispatch, so they cross once per worker
246
- // as workerData. Features carry closures and cannot cross at all; only their names do.
247
- workerData = {
248
- cfg: cfg,
249
- featureNames: features.map(function(feature) {
250
- return feature.name;
251
- })
252
- };
253
- pool = new Tinypool({
254
- filename: resolveWorkerFile(),
255
- minThreads: maxWorkers,
256
- maxThreads: maxWorkers,
257
- workerData: workerData
258
- });
259
- done = 0;
218
+ if (pool) return [
219
+ 2,
220
+ pool.run(files, features, cfg, onParsed, maxWorkers)
221
+ ];
222
+ ephemeral = new _poolts.ParsePool();
260
223
  _state.label = 1;
261
224
  case 1:
262
225
  _state.trys.push([
@@ -267,37 +230,13 @@ function reparsePooled(files, features, cfg, onParsed, maxWorkers) {
267
230
  ]);
268
231
  return [
269
232
  4,
270
- Promise.all(files.map(function(file) {
271
- return _async_to_generator(function() {
272
- var result;
273
- return _ts_generator(this, function(_state) {
274
- switch(_state.label){
275
- case 0:
276
- return [
277
- 4,
278
- pool.run(file)
279
- ];
280
- case 1:
281
- result = _state.sent();
282
- if (!result.ok) throw (0, _workererrorts.reviveError)(result.error);
283
- onParsed === null || onParsed === void 0 ? void 0 : onParsed(++done);
284
- return [
285
- 2,
286
- {
287
- doc: result.doc,
288
- warnings: result.warnings
289
- }
290
- ];
291
- }
292
- });
293
- })();
294
- }))
233
+ ephemeral.run(files, features, cfg, onParsed, maxWorkers)
295
234
  ];
296
235
  case 2:
297
236
  results = _state.sent();
298
237
  return [
299
238
  4,
300
- pool.destroy()
239
+ ephemeral.close()
301
240
  ];
302
241
  case 3:
303
242
  _state.sent();
@@ -307,11 +246,11 @@ function reparsePooled(files, features, cfg, onParsed, maxWorkers) {
307
246
  ];
308
247
  case 4:
309
248
  err = _state.sent();
310
- // Tear the pool down before rethrowing, but a destroy failure must not mask the parse
249
+ // Tear the pool down before rethrowing, but a close failure must not mask the parse
311
250
  // failure that caused it -- not a `finally`, for that reason.
312
251
  return [
313
252
  4,
314
- pool.destroy().catch(function() {})
253
+ ephemeral.close().catch(function() {})
315
254
  ];
316
255
  case 5:
317
256
  _state.sent();
@@ -340,7 +279,7 @@ function reparseFiles(_0, _1, _2, _3, _4) {
340
279
  ];
341
280
  return [
342
281
  4,
343
- reparsePooled(files, features, cfg, onParsed, maxWorkers)
282
+ reparsePooled(files, features, cfg, onParsed, maxWorkers, options.pool)
344
283
  ];
345
284
  case 1:
346
285
  _tmp = _state.sent();