sensemaking 0.21.0 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/chunk/group.d.cts +0 -2
- package/dist/cjs/chunk/group.d.ts +0 -2
- package/dist/cjs/chunk/group.js +12 -53
- package/dist/cjs/chunk/group.js.map +1 -1
- package/dist/cjs/chunk/index.d.cts +1 -1
- package/dist/cjs/chunk/index.d.ts +1 -1
- package/dist/cjs/chunk/index.js +3 -2
- package/dist/cjs/chunk/index.js.map +1 -1
- package/dist/cjs/chunk/parse.js +46 -29
- package/dist/cjs/chunk/parse.js.map +1 -1
- package/dist/cjs/chunk/tokens.d.cts +2 -0
- package/dist/cjs/chunk/tokens.d.ts +2 -0
- package/dist/cjs/chunk/tokens.js +50 -0
- package/dist/cjs/chunk/tokens.js.map +1 -0
- package/dist/cjs/config/validate.js.map +1 -1
- package/dist/cjs/store/duckdb/connection.d.cts +4 -1
- package/dist/cjs/store/duckdb/connection.d.ts +4 -1
- package/dist/cjs/store/duckdb/connection.js +1 -0
- package/dist/cjs/store/duckdb/connection.js.map +1 -1
- package/dist/cjs/store/duckdb/reconcile.js +105 -1
- package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
- package/dist/cjs/store/reconcile.d.cts +1 -0
- package/dist/cjs/store/reconcile.d.ts +1 -0
- package/dist/cjs/store/reconcile.js +122 -82
- package/dist/cjs/store/reconcile.js.map +1 -1
- package/dist/cjs/store/types.d.cts +1 -0
- package/dist/cjs/store/types.d.ts +1 -0
- package/dist/cjs/store/types.js.map +1 -1
- package/dist/esm/chunk/group.d.ts +0 -2
- package/dist/esm/chunk/group.js +1 -15
- package/dist/esm/chunk/group.js.map +1 -1
- package/dist/esm/chunk/index.d.ts +1 -1
- package/dist/esm/chunk/index.js +1 -1
- package/dist/esm/chunk/index.js.map +1 -1
- package/dist/esm/chunk/parse.js +41 -29
- package/dist/esm/chunk/parse.js.map +1 -1
- package/dist/esm/chunk/tokens.d.ts +2 -0
- package/dist/esm/chunk/tokens.js +15 -0
- package/dist/esm/chunk/tokens.js.map +1 -0
- package/dist/esm/config/validate.js +2 -2
- package/dist/esm/config/validate.js.map +1 -1
- package/dist/esm/store/duckdb/connection.d.ts +4 -1
- package/dist/esm/store/duckdb/connection.js +1 -0
- package/dist/esm/store/duckdb/connection.js.map +1 -1
- package/dist/esm/store/duckdb/reconcile.js +34 -1
- package/dist/esm/store/duckdb/reconcile.js.map +1 -1
- package/dist/esm/store/reconcile.d.ts +1 -0
- package/dist/esm/store/reconcile.js +13 -4
- package/dist/esm/store/reconcile.js.map +1 -1
- package/dist/esm/store/types.d.ts +1 -0
- package/dist/esm/store/types.js.map +1 -1
- package/package.json +3 -3
package/dist/cjs/chunk/group.js
CHANGED
|
@@ -2,26 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", {
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
_export(exports, {
|
|
12
|
-
get DEFAULT_TARGET_TOKENS () {
|
|
13
|
-
return DEFAULT_TARGET_TOKENS;
|
|
14
|
-
},
|
|
15
|
-
get estimateTokens () {
|
|
16
|
-
return estimateTokens;
|
|
17
|
-
},
|
|
18
|
-
get group () {
|
|
5
|
+
Object.defineProperty(exports, "group", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
19
8
|
return group;
|
|
20
9
|
}
|
|
21
10
|
});
|
|
22
|
-
var _segmentts = require("../text/segment.js");
|
|
23
11
|
var _extractts = require("./extract.js");
|
|
24
12
|
var _parsets = require("./parse.js");
|
|
13
|
+
var _tokensts = require("./tokens.js");
|
|
25
14
|
function _array_like_to_array(arr, len) {
|
|
26
15
|
if (len == null || len > arr.length) len = arr.length;
|
|
27
16
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
@@ -98,42 +87,12 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
98
87
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
99
88
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
100
89
|
}
|
|
101
|
-
var DEFAULT_TARGET_TOKENS = 500;
|
|
102
90
|
var PGC_GROUP_SIZE = 2;
|
|
103
91
|
var OVERSIZE_TRIGGER_MULTIPLE = 2;
|
|
104
|
-
// D5: segment.ts's unspaced-script set packs close to one token per character; Hangul is
|
|
105
|
-
// spaced but still token-dense and sits in this set as a conservative bound (one Unicode set, one home).
|
|
106
|
-
var DENSE_SCRIPT = new RegExp("[".concat(_segmentts.UNSPACED_SCRIPTS, "\\p{scx=Hangul}]"), 'u');
|
|
107
|
-
function estimateTokens(text) {
|
|
108
|
-
var dense = 0;
|
|
109
|
-
var other = 0;
|
|
110
|
-
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
111
|
-
try {
|
|
112
|
-
for(var _iterator = text[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
113
|
-
var ch = _step.value;
|
|
114
|
-
if (DENSE_SCRIPT.test(ch)) dense++;
|
|
115
|
-
else other++;
|
|
116
|
-
}
|
|
117
|
-
} catch (err) {
|
|
118
|
-
_didIteratorError = true;
|
|
119
|
-
_iteratorError = err;
|
|
120
|
-
} finally{
|
|
121
|
-
try {
|
|
122
|
-
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
123
|
-
_iterator.return();
|
|
124
|
-
}
|
|
125
|
-
} finally{
|
|
126
|
-
if (_didIteratorError) {
|
|
127
|
-
throw _iteratorError;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return dense + other / 4;
|
|
132
|
-
}
|
|
133
92
|
function resolveOptions(opts) {
|
|
134
93
|
var _ref, _ref1;
|
|
135
94
|
return {
|
|
136
|
-
targetTokens: (_ref = opts === null || opts === void 0 ? void 0 : opts.targetTokens) !== null && _ref !== void 0 ? _ref : DEFAULT_TARGET_TOKENS,
|
|
95
|
+
targetTokens: (_ref = opts === null || opts === void 0 ? void 0 : opts.targetTokens) !== null && _ref !== void 0 ? _ref : _tokensts.DEFAULT_TARGET_TOKENS,
|
|
137
96
|
text: (_ref1 = opts === null || opts === void 0 ? void 0 : opts.text) !== null && _ref1 !== void 0 ? _ref1 : 'raw'
|
|
138
97
|
};
|
|
139
98
|
}
|
|
@@ -184,7 +143,7 @@ function finalize(parts) {
|
|
|
184
143
|
})
|
|
185
144
|
};
|
|
186
145
|
}
|
|
187
|
-
var NEWLINE_TOKENS = estimateTokens('\n');
|
|
146
|
+
var NEWLINE_TOKENS = (0, _tokensts.estimateTokens)('\n');
|
|
188
147
|
var SENTENCE_SEGMENTER = new Intl.Segmenter(undefined, {
|
|
189
148
|
granularity: 'sentence'
|
|
190
149
|
});
|
|
@@ -206,7 +165,7 @@ function pack(segments, working) {
|
|
|
206
165
|
try {
|
|
207
166
|
for(var _iterator = segments[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
208
167
|
var segment = _step.value;
|
|
209
|
-
var segmentTokens = estimateTokens(segment);
|
|
168
|
+
var segmentTokens = (0, _tokensts.estimateTokens)(segment);
|
|
210
169
|
if (current.length > 0 && tokens + segmentTokens > working) {
|
|
211
170
|
groups.push(current);
|
|
212
171
|
current = '';
|
|
@@ -250,7 +209,7 @@ function splitLineText(text, working) {
|
|
|
250
209
|
try {
|
|
251
210
|
for(var _iterator = sentences[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
252
211
|
var sentence = _step.value;
|
|
253
|
-
var sentenceTokens = estimateTokens(sentence);
|
|
212
|
+
var sentenceTokens = (0, _tokensts.estimateTokens)(sentence);
|
|
254
213
|
if (sentenceTokens > working) {
|
|
255
214
|
var _out;
|
|
256
215
|
flush();
|
|
@@ -299,7 +258,7 @@ function piece(pieceLines, startLine, endLine, blockType, textMode) {
|
|
|
299
258
|
// splits at sentence/word boundaries instead; `final` stops group() re-deriving its text by extent (F5).
|
|
300
259
|
function finalizePiece(pieceLines, startLine, endLine, working, blockType, textMode) {
|
|
301
260
|
var p = piece(pieceLines, startLine, endLine, blockType, textMode);
|
|
302
|
-
if (pieceLines.length === 1 && estimateTokens(p.text) > working) {
|
|
261
|
+
if (pieceLines.length === 1 && (0, _tokensts.estimateTokens)(p.text) > working) {
|
|
303
262
|
return splitLineText(p.text, working).map(function(text) {
|
|
304
263
|
return {
|
|
305
264
|
startLine: startLine,
|
|
@@ -325,7 +284,7 @@ function splitOversizeBlock(lines, startLine, endLine, working, blockType, textM
|
|
|
325
284
|
for(var line = startLine; line <= endLine; line++){
|
|
326
285
|
var lineText = lines[line - 1];
|
|
327
286
|
var sep = pieceLines.length > 0 || tokens > 0 ? NEWLINE_TOKENS : 0;
|
|
328
|
-
var lineTokens = estimateTokens(lineText);
|
|
287
|
+
var lineTokens = (0, _tokensts.estimateTokens)(lineText);
|
|
329
288
|
if (pieceLines.length > 0 && tokens + sep + lineTokens > working) {
|
|
330
289
|
var _pieces1;
|
|
331
290
|
(_pieces1 = pieces).push.apply(_pieces1, _to_consumable_array(finalizePiece(pieceLines, pieceStart, line - 1, working, blockType, textMode)));
|
|
@@ -361,7 +320,7 @@ function groupScope(scopeBlocks, lines, resolved) {
|
|
|
361
320
|
// tokens tracks the active text mode's own estimate (a newline between parts costs
|
|
362
321
|
// NEWLINE_TOKENS too), so packing decisions size the text the chunk will actually ship as.
|
|
363
322
|
function addPart(text, sizeText, startLine, endLine) {
|
|
364
|
-
tokens += (parts.length > 0 ? NEWLINE_TOKENS : 0) + estimateTokens(sizeText);
|
|
323
|
+
tokens += (parts.length > 0 ? NEWLINE_TOKENS : 0) + (0, _tokensts.estimateTokens)(sizeText);
|
|
365
324
|
parts.push({
|
|
366
325
|
startLine: startLine,
|
|
367
326
|
endLine: endLine,
|
|
@@ -373,7 +332,7 @@ function groupScope(scopeBlocks, lines, resolved) {
|
|
|
373
332
|
for(var _iterator = scopeBlocks[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
374
333
|
var block = _step.value;
|
|
375
334
|
var raw = lines.slice(block.startLine - 1, block.endLine).join('\n');
|
|
376
|
-
var blockTokens = estimateTokens(raw);
|
|
335
|
+
var blockTokens = (0, _tokensts.estimateTokens)(raw);
|
|
377
336
|
if (blockTokens > trigger) {
|
|
378
337
|
var seed = parts.length > 0 ? tokens : 0;
|
|
379
338
|
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/group.ts"],"sourcesContent":["import { UNSPACED_SCRIPTS } from '../text/segment.ts';\nimport { extractText } from './extract.ts';\nimport { parse } from './parse.ts';\nimport type { Block, BlockType, Chunk, ChunkOptions } from './types.ts';\n\nexport const DEFAULT_TARGET_TOKENS = 500;\nconst PGC_GROUP_SIZE = 2;\nconst OVERSIZE_TRIGGER_MULTIPLE = 2;\n\n// D5: segment.ts's unspaced-script set packs close to one token per character; Hangul is\n// spaced but still token-dense and sits in this set as a conservative bound (one Unicode set, one home).\nconst DENSE_SCRIPT = new RegExp(`[${UNSPACED_SCRIPTS}\\\\p{scx=Hangul}]`, 'u');\n\n// D5's size estimate: dense-script graphemes 1:1, everything else at 4 chars/token.\nexport function estimateTokens(text: string): number {\n let dense = 0;\n let other = 0;\n for (const ch of text) {\n if (DENSE_SCRIPT.test(ch)) dense++;\n else other++;\n }\n return dense + other / 4;\n}\n\ninterface ResolvedOptions {\n targetTokens: number;\n text: 'extracted' | 'raw';\n}\n\nfunction resolveOptions(opts?: ChunkOptions): ResolvedOptions {\n return {\n targetTokens: opts?.targetTokens ?? DEFAULT_TARGET_TOKENS,\n text: opts?.text ?? 'raw',\n };\n}\n\n// A heading of any depth ends the current scope and starts a new one (D1); the heading block\n// itself is carried into the new scope, where it joins that scope's first group (F7/F10).\nfunction splitScopes(blocks: Block[]): Block[][] {\n const scopes: Block[][] = [];\n let current: Block[] = [];\n for (const block of blocks) {\n if (block.type === 'heading' && current.length > 0) {\n scopes.push(current);\n current = [];\n }\n current.push(block);\n }\n if (current.length > 0) scopes.push(current);\n return scopes;\n}\n\ninterface Part {\n startLine: number;\n endLine: number;\n text: string;\n // True for a sub-line split piece: its text is already the final slice, not the whole line --\n // group()'s extent-based raw re-slice must not touch it (siblings share startLine === endLine).\n final?: boolean;\n}\n\nfunction finalize(parts: Part[]): (Chunk & { final?: boolean }) | undefined {\n if (parts.length === 0) return undefined;\n const first = parts[0];\n const last = parts[parts.length - 1];\n return { startLine: first.startLine, endLine: last.endLine, text: parts.map((p) => p.text).join('\\n'), final: parts.some((p) => p.final) };\n}\n\nconst NEWLINE_TOKENS = estimateTokens('\\n');\nconst SENTENCE_SEGMENTER = new Intl.Segmenter(undefined, { granularity: 'sentence' });\nconst WORD_SEGMENTER = new Intl.Segmenter(undefined, { granularity: 'word' });\n\nfunction segmentsOf(text: string, segmenter: Intl.Segmenter): string[] {\n return Array.from(segmenter.segment(text), (s) => s.segment);\n}\n\n// Greedily packs segments (already contiguous, tiling the source text with no gaps) into groups\n// of at most `working` estimated tokens; a lone segment over `working` still stands alone.\nfunction pack(segments: string[], working: number): string[] {\n const groups: string[] = [];\n let current = '';\n let tokens = 0;\n for (const segment of segments) {\n const segmentTokens = estimateTokens(segment);\n if (current.length > 0 && tokens + segmentTokens > working) {\n groups.push(current);\n current = '';\n tokens = 0;\n }\n current += segment;\n tokens += segmentTokens;\n }\n if (current.length > 0) groups.push(current);\n return groups;\n}\n\n// Line-split alone can't shrink a lone dense line (the CJK case): falls back to sentence then\n// word boundaries (Intl.Segmenter, the same grapheme-safe engine as segment.ts), mode-agnostic on `text`.\nfunction splitLineText(text: string, working: number): string[] {\n const sentences = segmentsOf(text, SENTENCE_SEGMENTER);\n const out: string[] = [];\n let current = '';\n let tokens = 0;\n const flush = () => {\n if (current.length > 0) {\n out.push(current);\n current = '';\n tokens = 0;\n }\n };\n for (const sentence of sentences) {\n const sentenceTokens = estimateTokens(sentence);\n if (sentenceTokens > working) {\n flush();\n out.push(...pack(segmentsOf(sentence, WORD_SEGMENTER), working));\n continue;\n }\n if (current.length > 0 && tokens + sentenceTokens > working) flush();\n current += sentence;\n tokens += sentenceTokens;\n }\n flush();\n return out;\n}\n\nconst ATOMIC_TYPES: ReadonlySet<BlockType> = new Set(['code', 'table', 'list']);\n\n// Atomic (code/table/list) pieces are always a raw line slice: re-parsing a table's later pieces\n// without their header/delimiter rows would demote them to paragraph text.\nfunction piece(pieceLines: string[], startLine: number, endLine: number, blockType: BlockType, textMode: 'extracted' | 'raw'): Part {\n const text =\n ATOMIC_TYPES.has(blockType) || textMode === 'raw'\n ? pieceLines.join('\\n')\n : parse(pieceLines.join('\\n'))\n .map((b) => extractText(b.node))\n .join('\\n');\n return { startLine, endLine, text };\n}\n\n// A one-line piece over working can't shrink via another line-boundary pass (rule 5's gap), so it\n// splits at sentence/word boundaries instead; `final` stops group() re-deriving its text by extent (F5).\nfunction finalizePiece(pieceLines: string[], startLine: number, endLine: number, working: number, blockType: BlockType, textMode: 'extracted' | 'raw'): Part[] {\n const p = piece(pieceLines, startLine, endLine, blockType, textMode);\n if (pieceLines.length === 1 && estimateTokens(p.text) > working) {\n return splitLineText(p.text, working).map((text) => ({ startLine, endLine, text, final: true }));\n }\n return [p];\n}\n\n// A block over 2x working size splits at line boundaries into pieces each <= working size, never\n// mid-line. `seed`: pending tokens (e.g. a heading) the first piece must join, checked against the limit.\nfunction splitOversizeBlock(lines: string[], startLine: number, endLine: number, working: number, blockType: BlockType, textMode: 'extracted' | 'raw', seed = 0): Part[] {\n const pieces: Part[] = [];\n let pieceLines: string[] = [];\n let pieceStart = startLine;\n let tokens = seed;\n for (let line = startLine; line <= endLine; line++) {\n const lineText = lines[line - 1];\n const sep = pieceLines.length > 0 || tokens > 0 ? NEWLINE_TOKENS : 0;\n const lineTokens = estimateTokens(lineText);\n if (pieceLines.length > 0 && tokens + sep + lineTokens > working) {\n pieces.push(...finalizePiece(pieceLines, pieceStart, line - 1, working, blockType, textMode));\n pieceLines = [];\n tokens = 0;\n pieceStart = line;\n pieceLines.push(lineText);\n tokens += lineTokens;\n continue;\n }\n pieceLines.push(lineText);\n tokens += sep + lineTokens;\n }\n if (pieceLines.length > 0) pieces.push(...finalizePiece(pieceLines, pieceStart, endLine, working, blockType, textMode));\n return pieces;\n}\n\n// One heading scope's groups (D1): a heading opens the first group, and an oversize block\n// (rule 5, including an oversize heading) splits into pieces that each close their own group.\nfunction groupScope(scopeBlocks: Block[], lines: string[], resolved: ResolvedOptions): (Chunk & { final?: boolean })[] {\n const working = resolved.targetTokens;\n const trigger = working * OVERSIZE_TRIGGER_MULTIPLE;\n const finished: (Chunk & { final?: boolean })[] = [];\n let parts: Part[] = [];\n let paragraphCount = 0;\n let tokens = 0;\n\n function close(): void {\n const group = finalize(parts);\n if (group) finished.push(group);\n parts = [];\n paragraphCount = 0;\n tokens = 0;\n }\n\n // tokens tracks the active text mode's own estimate (a newline between parts costs\n // NEWLINE_TOKENS too), so packing decisions size the text the chunk will actually ship as.\n function addPart(text: string, sizeText: string, startLine: number, endLine: number): void {\n tokens += (parts.length > 0 ? NEWLINE_TOKENS : 0) + estimateTokens(sizeText);\n parts.push({ startLine, endLine, text });\n }\n\n for (const block of scopeBlocks) {\n const raw = lines.slice(block.startLine - 1, block.endLine).join('\\n');\n const blockTokens = estimateTokens(raw);\n\n if (blockTokens > trigger) {\n const seed = parts.length > 0 ? tokens : 0;\n for (const p of splitOversizeBlock(lines, block.startLine, block.endLine, working, block.type, resolved.text, seed)) {\n parts.push(p);\n close();\n }\n continue;\n }\n\n const extracted = extractText(block.node);\n const sizeText = resolved.text === 'raw' ? raw : extracted;\n\n if (block.type === 'heading') {\n addPart(extracted, sizeText, block.startLine, block.endLine);\n continue;\n }\n\n // The 2x-working invariant holds even under pgc's paper-faithful 2-paragraph pairing --\n // close first if the pair about to form would cross it.\n const pairOversize = parts.length > 0 && tokens + NEWLINE_TOKENS + blockTokens > trigger;\n if (pairOversize) close();\n\n addPart(extracted, sizeText, block.startLine, block.endLine);\n paragraphCount++;\n\n if (paragraphCount >= PGC_GROUP_SIZE) close();\n }\n close();\n\n return finished;\n}\n\n// Groups already-parsed blocks per opts (D1/D3), against the same body the blocks were parsed\n// from (line lookups for oversize splitting).\nexport function group(blocks: Block[], body: string, opts?: ChunkOptions): Chunk[] {\n const resolved = resolveOptions(opts);\n const lines = body.split('\\n');\n const chunks: (Chunk & { final?: boolean })[] = [];\n for (const scope of splitScopes(blocks)) chunks.push(...groupScope(scope, lines, resolved));\n // 'raw': the chunk's own source lines verbatim, replacing the flavor-resolved join above (D9).\n // A `final` chunk already carries its own slice's raw text; re-slicing by extent would return the whole shared line.\n const texted =\n resolved.text === 'raw'\n ? chunks.map((c) =>\n c.final\n ? c\n : {\n ...c,\n text: lines\n .slice(c.startLine - 1, c.endLine)\n .join('\\n')\n .trim(),\n }\n )\n : chunks;\n // A group can be all-blank (flavor-stripped to nothing, or a raw slice of pure syntax); it never produces a chunk.\n return texted.filter((c) => c.text.trim().length > 0).map((c) => ({ startLine: c.startLine, endLine: c.endLine, text: c.text }));\n}\n"],"names":["DEFAULT_TARGET_TOKENS","estimateTokens","group","PGC_GROUP_SIZE","OVERSIZE_TRIGGER_MULTIPLE","DENSE_SCRIPT","RegExp","UNSPACED_SCRIPTS","text","dense","other","ch","test","resolveOptions","opts","targetTokens","splitScopes","blocks","scopes","current","block","type","length","push","finalize","parts","undefined","first","last","startLine","endLine","map","p","join","final","some","NEWLINE_TOKENS","SENTENCE_SEGMENTER","Intl","Segmenter","granularity","WORD_SEGMENTER","segmentsOf","segmenter","Array","from","segment","s","pack","segments","working","groups","tokens","segmentTokens","splitLineText","sentences","out","flush","sentence","sentenceTokens","ATOMIC_TYPES","Set","piece","pieceLines","blockType","textMode","has","parse","b","extractText","node","finalizePiece","splitOversizeBlock","lines","seed","pieces","pieceStart","line","lineText","sep","lineTokens","groupScope","scopeBlocks","resolved","trigger","finished","paragraphCount","close","addPart","sizeText","raw","slice","blockTokens","extracted","pairOversize","body","chunks","split","scope","texted","c","trim","filter"],"mappings":";;;;;;;;;;;QAKaA;eAAAA;;QASGC;eAAAA;;QAiOAC;eAAAA;;;yBA/OiB;yBACL;uBACN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGf,IAAMF,wBAAwB;AACrC,IAAMG,iBAAiB;AACvB,IAAMC,4BAA4B;AAElC,yFAAyF;AACzF,yGAAyG;AACzG,IAAMC,eAAe,IAAIC,OAAO,AAAC,IAAoB,OAAjBC,2BAAgB,EAAC,qBAAmB;AAGjE,SAASN,eAAeO,IAAY;IACzC,IAAIC,QAAQ;IACZ,IAAIC,QAAQ;QACP,kCAAA,2BAAA;;QAAL,QAAK,YAAYF,yBAAZ,SAAA,6BAAA,QAAA,yBAAA,iCAAkB;YAAlB,IAAMG,KAAN;YACH,IAAIN,aAAaO,IAAI,CAACD,KAAKF;iBACtBC;QACP;;QAHK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAIL,OAAOD,QAAQC,QAAQ;AACzB;AAOA,SAASG,eAAeC,IAAmB;;IACzC,OAAO;QACLC,YAAY,UAAED,iBAAAA,2BAAAA,KAAMC,YAAY,uCAAIf;QACpCQ,IAAI,WAAEM,iBAAAA,2BAAAA,KAAMN,IAAI,yCAAI;IACtB;AACF;AAEA,6FAA6F;AAC7F,0FAA0F;AAC1F,SAASQ,YAAYC,MAAe;IAClC,IAAMC,SAAoB,EAAE;IAC5B,IAAIC,UAAmB,EAAE;QACpB,kCAAA,2BAAA;;QAAL,QAAK,YAAeF,2BAAf,SAAA,6BAAA,QAAA,yBAAA,iCAAuB;YAAvB,IAAMG,QAAN;YACH,IAAIA,MAAMC,IAAI,KAAK,aAAaF,QAAQG,MAAM,GAAG,GAAG;gBAClDJ,OAAOK,IAAI,CAACJ;gBACZA,UAAU,EAAE;YACd;YACAA,QAAQI,IAAI,CAACH;QACf;;QANK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAOL,IAAID,QAAQG,MAAM,GAAG,GAAGJ,OAAOK,IAAI,CAACJ;IACpC,OAAOD;AACT;AAWA,SAASM,SAASC,KAAa;IAC7B,IAAIA,MAAMH,MAAM,KAAK,GAAG,OAAOI;IAC/B,IAAMC,QAAQF,KAAK,CAAC,EAAE;IACtB,IAAMG,OAAOH,KAAK,CAACA,MAAMH,MAAM,GAAG,EAAE;IACpC,OAAO;QAAEO,WAAWF,MAAME,SAAS;QAAEC,SAASF,KAAKE,OAAO;QAAEtB,MAAMiB,MAAMM,GAAG,CAAC,SAACC;mBAAMA,EAAExB,IAAI;WAAEyB,IAAI,CAAC;QAAOC,OAAOT,MAAMU,IAAI,CAAC,SAACH;mBAAMA,EAAEE,KAAK;;IAAE;AAC3I;AAEA,IAAME,iBAAiBnC,eAAe;AACtC,IAAMoC,qBAAqB,IAAIC,KAAKC,SAAS,CAACb,WAAW;IAAEc,aAAa;AAAW;AACnF,IAAMC,iBAAiB,IAAIH,KAAKC,SAAS,CAACb,WAAW;IAAEc,aAAa;AAAO;AAE3E,SAASE,WAAWlC,IAAY,EAAEmC,SAAyB;IACzD,OAAOC,MAAMC,IAAI,CAACF,UAAUG,OAAO,CAACtC,OAAO,SAACuC;eAAMA,EAAED,OAAO;;AAC7D;AAEA,gGAAgG;AAChG,2FAA2F;AAC3F,SAASE,KAAKC,QAAkB,EAAEC,OAAe;IAC/C,IAAMC,SAAmB,EAAE;IAC3B,IAAIhC,UAAU;IACd,IAAIiC,SAAS;QACR,kCAAA,2BAAA;;QAAL,QAAK,YAAiBH,6BAAjB,SAAA,6BAAA,QAAA,yBAAA,iCAA2B;YAA3B,IAAMH,UAAN;YACH,IAAMO,gBAAgBpD,eAAe6C;YACrC,IAAI3B,QAAQG,MAAM,GAAG,KAAK8B,SAASC,gBAAgBH,SAAS;gBAC1DC,OAAO5B,IAAI,CAACJ;gBACZA,UAAU;gBACViC,SAAS;YACX;YACAjC,WAAW2B;YACXM,UAAUC;QACZ;;QATK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAUL,IAAIlC,QAAQG,MAAM,GAAG,GAAG6B,OAAO5B,IAAI,CAACJ;IACpC,OAAOgC;AACT;AAEA,8FAA8F;AAC9F,0GAA0G;AAC1G,SAASG,cAAc9C,IAAY,EAAE0C,OAAe;IAClD,IAAMK,YAAYb,WAAWlC,MAAM6B;IACnC,IAAMmB,MAAgB,EAAE;IACxB,IAAIrC,UAAU;IACd,IAAIiC,SAAS;IACb,IAAMK,QAAQ;QACZ,IAAItC,QAAQG,MAAM,GAAG,GAAG;YACtBkC,IAAIjC,IAAI,CAACJ;YACTA,UAAU;YACViC,SAAS;QACX;IACF;QACK,kCAAA,2BAAA;;QAAL,QAAK,YAAkBG,8BAAlB,SAAA,6BAAA,QAAA,yBAAA,iCAA6B;YAA7B,IAAMG,WAAN;YACH,IAAMC,iBAAiB1D,eAAeyD;YACtC,IAAIC,iBAAiBT,SAAS;oBAE5BM;gBADAC;gBACAD,CAAAA,OAAAA,KAAIjC,IAAI,OAARiC,MAAS,qBAAGR,KAAKN,WAAWgB,UAAUjB,iBAAiBS;gBACvD;YACF;YACA,IAAI/B,QAAQG,MAAM,GAAG,KAAK8B,SAASO,iBAAiBT,SAASO;YAC7DtC,WAAWuC;YACXN,UAAUO;QACZ;;QAVK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAWLF;IACA,OAAOD;AACT;AAEA,IAAMI,eAAuC,IAAIC,IAAI;IAAC;IAAQ;IAAS;CAAO;AAE9E,iGAAiG;AACjG,2EAA2E;AAC3E,SAASC,MAAMC,UAAoB,EAAElC,SAAiB,EAAEC,OAAe,EAAEkC,SAAoB,EAAEC,QAA6B;IAC1H,IAAMzD,OACJoD,aAAaM,GAAG,CAACF,cAAcC,aAAa,QACxCF,WAAW9B,IAAI,CAAC,QAChBkC,IAAAA,cAAK,EAACJ,WAAW9B,IAAI,CAAC,OACnBF,GAAG,CAAC,SAACqC;eAAMC,IAAAA,sBAAW,EAACD,EAAEE,IAAI;OAC7BrC,IAAI,CAAC;IACd,OAAO;QAAEJ,WAAAA;QAAWC,SAAAA;QAAStB,MAAAA;IAAK;AACpC;AAEA,kGAAkG;AAClG,yGAAyG;AACzG,SAAS+D,cAAcR,UAAoB,EAAElC,SAAiB,EAAEC,OAAe,EAAEoB,OAAe,EAAEc,SAAoB,EAAEC,QAA6B;IACnJ,IAAMjC,IAAI8B,MAAMC,YAAYlC,WAAWC,SAASkC,WAAWC;IAC3D,IAAIF,WAAWzC,MAAM,KAAK,KAAKrB,eAAe+B,EAAExB,IAAI,IAAI0C,SAAS;QAC/D,OAAOI,cAActB,EAAExB,IAAI,EAAE0C,SAASnB,GAAG,CAAC,SAACvB;mBAAU;gBAAEqB,WAAAA;gBAAWC,SAAAA;gBAAStB,MAAAA;gBAAM0B,OAAO;YAAK;;IAC/F;IACA,OAAO;QAACF;KAAE;AACZ;AAEA,iGAAiG;AACjG,0GAA0G;AAC1G,SAASwC,mBAAmBC,KAAe,EAAE5C,SAAiB,EAAEC,OAAe,EAAEoB,OAAe,EAAEc,SAAoB,EAAEC,QAA6B;QAAES,OAAAA,iEAAO;QAqBjIC;IApB3B,IAAMA,SAAiB,EAAE;IACzB,IAAIZ,aAAuB,EAAE;IAC7B,IAAIa,aAAa/C;IACjB,IAAIuB,SAASsB;IACb,IAAK,IAAIG,OAAOhD,WAAWgD,QAAQ/C,SAAS+C,OAAQ;QAClD,IAAMC,WAAWL,KAAK,CAACI,OAAO,EAAE;QAChC,IAAME,MAAMhB,WAAWzC,MAAM,GAAG,KAAK8B,SAAS,IAAIhB,iBAAiB;QACnE,IAAM4C,aAAa/E,eAAe6E;QAClC,IAAIf,WAAWzC,MAAM,GAAG,KAAK8B,SAAS2B,MAAMC,aAAa9B,SAAS;gBAChEyB;YAAAA,CAAAA,WAAAA,QAAOpD,IAAI,OAAXoD,UAAY,qBAAGJ,cAAcR,YAAYa,YAAYC,OAAO,GAAG3B,SAASc,WAAWC;YACnFF,aAAa,EAAE;YACfX,SAAS;YACTwB,aAAaC;YACbd,WAAWxC,IAAI,CAACuD;YAChB1B,UAAU4B;YACV;QACF;QACAjB,WAAWxC,IAAI,CAACuD;QAChB1B,UAAU2B,MAAMC;IAClB;IACA,IAAIjB,WAAWzC,MAAM,GAAG,GAAGqD,CAAAA,UAAAA,QAAOpD,IAAI,OAAXoD,SAAY,qBAAGJ,cAAcR,YAAYa,YAAY9C,SAASoB,SAASc,WAAWC;IAC7G,OAAOU;AACT;AAEA,0FAA0F;AAC1F,8FAA8F;AAC9F,SAASM,WAAWC,WAAoB,EAAET,KAAe,EAAEU,QAAyB;IAClF,IAAMjC,UAAUiC,SAASpE,YAAY;IACrC,IAAMqE,UAAUlC,UAAU9C;IAC1B,IAAMiF,WAA4C,EAAE;IACpD,IAAI5D,QAAgB,EAAE;IACtB,IAAI6D,iBAAiB;IACrB,IAAIlC,SAAS;IAEb,SAASmC;QACP,IAAMrF,QAAQsB,SAASC;QACvB,IAAIvB,OAAOmF,SAAS9D,IAAI,CAACrB;QACzBuB,QAAQ,EAAE;QACV6D,iBAAiB;QACjBlC,SAAS;IACX;IAEA,mFAAmF;IACnF,2FAA2F;IAC3F,SAASoC,QAAQhF,IAAY,EAAEiF,QAAgB,EAAE5D,SAAiB,EAAEC,OAAe;QACjFsB,UAAU,AAAC3B,CAAAA,MAAMH,MAAM,GAAG,IAAIc,iBAAiB,CAAA,IAAKnC,eAAewF;QACnEhE,MAAMF,IAAI,CAAC;YAAEM,WAAAA;YAAWC,SAAAA;YAAStB,MAAAA;QAAK;IACxC;QAEK,kCAAA,2BAAA;;QAAL,QAAK,YAAe0E,gCAAf,SAAA,6BAAA,QAAA,yBAAA,iCAA4B;YAA5B,IAAM9D,QAAN;YACH,IAAMsE,MAAMjB,MAAMkB,KAAK,CAACvE,MAAMS,SAAS,GAAG,GAAGT,MAAMU,OAAO,EAAEG,IAAI,CAAC;YACjE,IAAM2D,cAAc3F,eAAeyF;YAEnC,IAAIE,cAAcR,SAAS;gBACzB,IAAMV,OAAOjD,MAAMH,MAAM,GAAG,IAAI8B,SAAS;oBACpC,mCAAA,4BAAA;;oBAAL,QAAK,aAAWoB,mBAAmBC,OAAOrD,MAAMS,SAAS,EAAET,MAAMU,OAAO,EAAEoB,SAAS9B,MAAMC,IAAI,EAAE8D,SAAS3E,IAAI,EAAEkE,0BAAzG,UAAA,8BAAA,SAAA,0BAAA,kCAAgH;wBAAhH,IAAM1C,IAAN;wBACHP,MAAMF,IAAI,CAACS;wBACXuD;oBACF;;oBAHK;oBAAA;;;6BAAA,8BAAA;4BAAA;;;4BAAA;kCAAA;;;;gBAIL;YACF;YAEA,IAAMM,YAAYxB,IAAAA,sBAAW,EAACjD,MAAMkD,IAAI;YACxC,IAAMmB,WAAWN,SAAS3E,IAAI,KAAK,QAAQkF,MAAMG;YAEjD,IAAIzE,MAAMC,IAAI,KAAK,WAAW;gBAC5BmE,QAAQK,WAAWJ,UAAUrE,MAAMS,SAAS,EAAET,MAAMU,OAAO;gBAC3D;YACF;YAEA,wFAAwF;YACxF,wDAAwD;YACxD,IAAMgE,eAAerE,MAAMH,MAAM,GAAG,KAAK8B,SAAShB,iBAAiBwD,cAAcR;YACjF,IAAIU,cAAcP;YAElBC,QAAQK,WAAWJ,UAAUrE,MAAMS,SAAS,EAAET,MAAMU,OAAO;YAC3DwD;YAEA,IAAIA,kBAAkBnF,gBAAgBoF;QACxC;;QA9BK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IA+BLA;IAEA,OAAOF;AACT;AAIO,SAASnF,MAAMe,MAAe,EAAE8E,IAAY,EAAEjF,IAAmB;QAI7BkF;IAHzC,IAAMb,WAAWtE,eAAeC;IAChC,IAAM2D,QAAQsB,KAAKE,KAAK,CAAC;IACzB,IAAMD,SAA0C,EAAE;QAC7C,kCAAA,2BAAA;;QAAL,QAAK,YAAehF,YAAYC,4BAA3B,SAAA,6BAAA,QAAA,yBAAA;YAAA,IAAMiF,QAAN;YAAoCF,CAAAA,UAAAA,QAAOzE,IAAI,OAAXyE,SAAY,qBAAGf,WAAWiB,OAAOzB,OAAOU;;;QAA5E;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IACL,+FAA+F;IAC/F,qHAAqH;IACrH,IAAMgB,SACJhB,SAAS3E,IAAI,KAAK,QACdwF,OAAOjE,GAAG,CAAC,SAACqE;eACVA,EAAElE,KAAK,GACHkE,IACA,wCACKA;YACH5F,MAAMiE,MACHkB,KAAK,CAACS,EAAEvE,SAAS,GAAG,GAAGuE,EAAEtE,OAAO,EAChCG,IAAI,CAAC,MACLoE,IAAI;;SAGfL;IACN,mHAAmH;IACnH,OAAOG,OAAOG,MAAM,CAAC,SAACF;eAAMA,EAAE5F,IAAI,CAAC6F,IAAI,GAAG/E,MAAM,GAAG;OAAGS,GAAG,CAAC,SAACqE;eAAO;YAAEvE,WAAWuE,EAAEvE,SAAS;YAAEC,SAASsE,EAAEtE,OAAO;YAAEtB,MAAM4F,EAAE5F,IAAI;QAAC;;AAC/H"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/group.ts"],"sourcesContent":["import { extractText } from './extract.ts';\nimport { parse } from './parse.ts';\nimport { DEFAULT_TARGET_TOKENS, estimateTokens } from './tokens.ts';\nimport type { Block, BlockType, Chunk, ChunkOptions } from './types.ts';\n\nconst PGC_GROUP_SIZE = 2;\nconst OVERSIZE_TRIGGER_MULTIPLE = 2;\n\ninterface ResolvedOptions {\n targetTokens: number;\n text: 'extracted' | 'raw';\n}\n\nfunction resolveOptions(opts?: ChunkOptions): ResolvedOptions {\n return {\n targetTokens: opts?.targetTokens ?? DEFAULT_TARGET_TOKENS,\n text: opts?.text ?? 'raw',\n };\n}\n\n// A heading of any depth ends the current scope and starts a new one (D1); the heading block\n// itself is carried into the new scope, where it joins that scope's first group (F7/F10).\nfunction splitScopes(blocks: Block[]): Block[][] {\n const scopes: Block[][] = [];\n let current: Block[] = [];\n for (const block of blocks) {\n if (block.type === 'heading' && current.length > 0) {\n scopes.push(current);\n current = [];\n }\n current.push(block);\n }\n if (current.length > 0) scopes.push(current);\n return scopes;\n}\n\ninterface Part {\n startLine: number;\n endLine: number;\n text: string;\n // True for a sub-line split piece: its text is already the final slice, not the whole line --\n // group()'s extent-based raw re-slice must not touch it (siblings share startLine === endLine).\n final?: boolean;\n}\n\nfunction finalize(parts: Part[]): (Chunk & { final?: boolean }) | undefined {\n if (parts.length === 0) return undefined;\n const first = parts[0];\n const last = parts[parts.length - 1];\n return { startLine: first.startLine, endLine: last.endLine, text: parts.map((p) => p.text).join('\\n'), final: parts.some((p) => p.final) };\n}\n\nconst NEWLINE_TOKENS = estimateTokens('\\n');\nconst SENTENCE_SEGMENTER = new Intl.Segmenter(undefined, { granularity: 'sentence' });\nconst WORD_SEGMENTER = new Intl.Segmenter(undefined, { granularity: 'word' });\n\nfunction segmentsOf(text: string, segmenter: Intl.Segmenter): string[] {\n return Array.from(segmenter.segment(text), (s) => s.segment);\n}\n\n// Greedily packs segments (already contiguous, tiling the source text with no gaps) into groups\n// of at most `working` estimated tokens; a lone segment over `working` still stands alone.\nfunction pack(segments: string[], working: number): string[] {\n const groups: string[] = [];\n let current = '';\n let tokens = 0;\n for (const segment of segments) {\n const segmentTokens = estimateTokens(segment);\n if (current.length > 0 && tokens + segmentTokens > working) {\n groups.push(current);\n current = '';\n tokens = 0;\n }\n current += segment;\n tokens += segmentTokens;\n }\n if (current.length > 0) groups.push(current);\n return groups;\n}\n\n// Line-split alone can't shrink a lone dense line (the CJK case): falls back to sentence then\n// word boundaries (Intl.Segmenter, the same grapheme-safe engine as segment.ts), mode-agnostic on `text`.\nfunction splitLineText(text: string, working: number): string[] {\n const sentences = segmentsOf(text, SENTENCE_SEGMENTER);\n const out: string[] = [];\n let current = '';\n let tokens = 0;\n const flush = () => {\n if (current.length > 0) {\n out.push(current);\n current = '';\n tokens = 0;\n }\n };\n for (const sentence of sentences) {\n const sentenceTokens = estimateTokens(sentence);\n if (sentenceTokens > working) {\n flush();\n out.push(...pack(segmentsOf(sentence, WORD_SEGMENTER), working));\n continue;\n }\n if (current.length > 0 && tokens + sentenceTokens > working) flush();\n current += sentence;\n tokens += sentenceTokens;\n }\n flush();\n return out;\n}\n\nconst ATOMIC_TYPES: ReadonlySet<BlockType> = new Set(['code', 'table', 'list']);\n\n// Atomic (code/table/list) pieces are always a raw line slice: re-parsing a table's later pieces\n// without their header/delimiter rows would demote them to paragraph text.\nfunction piece(pieceLines: string[], startLine: number, endLine: number, blockType: BlockType, textMode: 'extracted' | 'raw'): Part {\n const text =\n ATOMIC_TYPES.has(blockType) || textMode === 'raw'\n ? pieceLines.join('\\n')\n : parse(pieceLines.join('\\n'))\n .map((b) => extractText(b.node))\n .join('\\n');\n return { startLine, endLine, text };\n}\n\n// A one-line piece over working can't shrink via another line-boundary pass (rule 5's gap), so it\n// splits at sentence/word boundaries instead; `final` stops group() re-deriving its text by extent (F5).\nfunction finalizePiece(pieceLines: string[], startLine: number, endLine: number, working: number, blockType: BlockType, textMode: 'extracted' | 'raw'): Part[] {\n const p = piece(pieceLines, startLine, endLine, blockType, textMode);\n if (pieceLines.length === 1 && estimateTokens(p.text) > working) {\n return splitLineText(p.text, working).map((text) => ({ startLine, endLine, text, final: true }));\n }\n return [p];\n}\n\n// A block over 2x working size splits at line boundaries into pieces each <= working size, never\n// mid-line. `seed`: pending tokens (e.g. a heading) the first piece must join, checked against the limit.\nfunction splitOversizeBlock(lines: string[], startLine: number, endLine: number, working: number, blockType: BlockType, textMode: 'extracted' | 'raw', seed = 0): Part[] {\n const pieces: Part[] = [];\n let pieceLines: string[] = [];\n let pieceStart = startLine;\n let tokens = seed;\n for (let line = startLine; line <= endLine; line++) {\n const lineText = lines[line - 1];\n const sep = pieceLines.length > 0 || tokens > 0 ? NEWLINE_TOKENS : 0;\n const lineTokens = estimateTokens(lineText);\n if (pieceLines.length > 0 && tokens + sep + lineTokens > working) {\n pieces.push(...finalizePiece(pieceLines, pieceStart, line - 1, working, blockType, textMode));\n pieceLines = [];\n tokens = 0;\n pieceStart = line;\n pieceLines.push(lineText);\n tokens += lineTokens;\n continue;\n }\n pieceLines.push(lineText);\n tokens += sep + lineTokens;\n }\n if (pieceLines.length > 0) pieces.push(...finalizePiece(pieceLines, pieceStart, endLine, working, blockType, textMode));\n return pieces;\n}\n\n// One heading scope's groups (D1): a heading opens the first group, and an oversize block\n// (rule 5, including an oversize heading) splits into pieces that each close their own group.\nfunction groupScope(scopeBlocks: Block[], lines: string[], resolved: ResolvedOptions): (Chunk & { final?: boolean })[] {\n const working = resolved.targetTokens;\n const trigger = working * OVERSIZE_TRIGGER_MULTIPLE;\n const finished: (Chunk & { final?: boolean })[] = [];\n let parts: Part[] = [];\n let paragraphCount = 0;\n let tokens = 0;\n\n function close(): void {\n const group = finalize(parts);\n if (group) finished.push(group);\n parts = [];\n paragraphCount = 0;\n tokens = 0;\n }\n\n // tokens tracks the active text mode's own estimate (a newline between parts costs\n // NEWLINE_TOKENS too), so packing decisions size the text the chunk will actually ship as.\n function addPart(text: string, sizeText: string, startLine: number, endLine: number): void {\n tokens += (parts.length > 0 ? NEWLINE_TOKENS : 0) + estimateTokens(sizeText);\n parts.push({ startLine, endLine, text });\n }\n\n for (const block of scopeBlocks) {\n const raw = lines.slice(block.startLine - 1, block.endLine).join('\\n');\n const blockTokens = estimateTokens(raw);\n\n if (blockTokens > trigger) {\n const seed = parts.length > 0 ? tokens : 0;\n for (const p of splitOversizeBlock(lines, block.startLine, block.endLine, working, block.type, resolved.text, seed)) {\n parts.push(p);\n close();\n }\n continue;\n }\n\n const extracted = extractText(block.node);\n const sizeText = resolved.text === 'raw' ? raw : extracted;\n\n if (block.type === 'heading') {\n addPart(extracted, sizeText, block.startLine, block.endLine);\n continue;\n }\n\n // The 2x-working invariant holds even under pgc's paper-faithful 2-paragraph pairing --\n // close first if the pair about to form would cross it.\n const pairOversize = parts.length > 0 && tokens + NEWLINE_TOKENS + blockTokens > trigger;\n if (pairOversize) close();\n\n addPart(extracted, sizeText, block.startLine, block.endLine);\n paragraphCount++;\n\n if (paragraphCount >= PGC_GROUP_SIZE) close();\n }\n close();\n\n return finished;\n}\n\n// Groups already-parsed blocks per opts (D1/D3), against the same body the blocks were parsed\n// from (line lookups for oversize splitting).\nexport function group(blocks: Block[], body: string, opts?: ChunkOptions): Chunk[] {\n const resolved = resolveOptions(opts);\n const lines = body.split('\\n');\n const chunks: (Chunk & { final?: boolean })[] = [];\n for (const scope of splitScopes(blocks)) chunks.push(...groupScope(scope, lines, resolved));\n // 'raw': the chunk's own source lines verbatim, replacing the flavor-resolved join above (D9).\n // A `final` chunk already carries its own slice's raw text; re-slicing by extent would return the whole shared line.\n const texted =\n resolved.text === 'raw'\n ? chunks.map((c) =>\n c.final\n ? c\n : {\n ...c,\n text: lines\n .slice(c.startLine - 1, c.endLine)\n .join('\\n')\n .trim(),\n }\n )\n : chunks;\n // A group can be all-blank (flavor-stripped to nothing, or a raw slice of pure syntax); it never produces a chunk.\n return texted.filter((c) => c.text.trim().length > 0).map((c) => ({ startLine: c.startLine, endLine: c.endLine, text: c.text }));\n}\n"],"names":["group","PGC_GROUP_SIZE","OVERSIZE_TRIGGER_MULTIPLE","resolveOptions","opts","targetTokens","DEFAULT_TARGET_TOKENS","text","splitScopes","blocks","scopes","current","block","type","length","push","finalize","parts","undefined","first","last","startLine","endLine","map","p","join","final","some","NEWLINE_TOKENS","estimateTokens","SENTENCE_SEGMENTER","Intl","Segmenter","granularity","WORD_SEGMENTER","segmentsOf","segmenter","Array","from","segment","s","pack","segments","working","groups","tokens","segmentTokens","splitLineText","sentences","out","flush","sentence","sentenceTokens","ATOMIC_TYPES","Set","piece","pieceLines","blockType","textMode","has","parse","b","extractText","node","finalizePiece","splitOversizeBlock","lines","seed","pieces","pieceStart","line","lineText","sep","lineTokens","groupScope","scopeBlocks","resolved","trigger","finished","paragraphCount","close","addPart","sizeText","raw","slice","blockTokens","extracted","pairOversize","body","chunks","split","scope","texted","c","trim","filter"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ 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
4
|
export { extractText, extractTexts } from './extract.js';
|
|
5
|
-
export { DEFAULT_TARGET_TOKENS, estimateTokens } from './group.js';
|
|
6
5
|
export { parse } from './parse.js';
|
|
6
|
+
export { DEFAULT_TARGET_TOKENS, estimateTokens } from './tokens.js';
|
|
7
7
|
export type { Block, BlockType, Chunk, ChunkOptions } from './types.js';
|
|
8
8
|
export { CHUNK_VERSION } from './version.js';
|
|
@@ -2,7 +2,7 @@ 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
4
|
export { extractText, extractTexts } from './extract.js';
|
|
5
|
-
export { DEFAULT_TARGET_TOKENS, estimateTokens } from './group.js';
|
|
6
5
|
export { parse } from './parse.js';
|
|
6
|
+
export { DEFAULT_TARGET_TOKENS, estimateTokens } from './tokens.js';
|
|
7
7
|
export type { Block, BlockType, Chunk, ChunkOptions } from './types.js';
|
|
8
8
|
export { CHUNK_VERSION } from './version.js';
|
package/dist/cjs/chunk/index.js
CHANGED
|
@@ -13,7 +13,7 @@ _export(exports, {
|
|
|
13
13
|
return _versionts.CHUNK_VERSION;
|
|
14
14
|
},
|
|
15
15
|
get DEFAULT_TARGET_TOKENS () {
|
|
16
|
-
return
|
|
16
|
+
return _tokensts.DEFAULT_TARGET_TOKENS;
|
|
17
17
|
},
|
|
18
18
|
get chunk () {
|
|
19
19
|
return chunk;
|
|
@@ -22,7 +22,7 @@ _export(exports, {
|
|
|
22
22
|
return chunkFromBlocks;
|
|
23
23
|
},
|
|
24
24
|
get estimateTokens () {
|
|
25
|
-
return
|
|
25
|
+
return _tokensts.estimateTokens;
|
|
26
26
|
},
|
|
27
27
|
get extractText () {
|
|
28
28
|
return _extractts.extractText;
|
|
@@ -37,6 +37,7 @@ _export(exports, {
|
|
|
37
37
|
var _groupts = require("./group.js");
|
|
38
38
|
var _parsets = require("./parse.js");
|
|
39
39
|
var _extractts = require("./extract.js");
|
|
40
|
+
var _tokensts = require("./tokens.js");
|
|
40
41
|
var _versionts = require("./version.js");
|
|
41
42
|
function chunkFromBlocks(blocks, body, opts) {
|
|
42
43
|
return (0, _groupts.group)(blocks, body, opts);
|
|
@@ -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, extractTexts } from './extract.ts';\nexport {
|
|
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 { parse } from './parse.ts';\nexport { DEFAULT_TARGET_TOKENS, estimateTokens } from './tokens.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;;QAFbC;eAAAA,+BAAqB;;QANdC;eAAAA;;QANAC;eAAAA;;QAYgBC;eAAAA,wBAAc;;QAFrCC;eAAAA,sBAAW;;QAAEC;eAAAA,uBAAY;;QACzBC;eAAAA,cAAK;;;uBAjBQ;uBACA;yBAeoB;wBAEY;yBAExB;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"}
|
package/dist/cjs/chunk/parse.js
CHANGED
|
@@ -8,18 +8,16 @@ Object.defineProperty(exports, "parse", {
|
|
|
8
8
|
return parse;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
var
|
|
12
|
-
var _mdastutilgfmautolinkliteral = require("mdast-util-gfm-autolink-literal");
|
|
13
|
-
var _mdastutilgfmfootnote = require("mdast-util-gfm-footnote");
|
|
14
|
-
var _mdastutilgfmstrikethrough = require("mdast-util-gfm-strikethrough");
|
|
15
|
-
var _mdastutilgfmtable = require("mdast-util-gfm-table");
|
|
16
|
-
var _mdastutilgfmtasklistitem = require("mdast-util-gfm-task-list-item");
|
|
17
|
-
var _micromarkextensiongfmautolinkliteral = require("micromark-extension-gfm-autolink-literal");
|
|
18
|
-
var _micromarkextensiongfmfootnote = require("micromark-extension-gfm-footnote");
|
|
19
|
-
var _micromarkextensiongfmstrikethrough = require("micromark-extension-gfm-strikethrough");
|
|
20
|
-
var _micromarkextensiongfmtable = require("micromark-extension-gfm-table");
|
|
21
|
-
var _micromarkextensiongfmtasklistitem = require("micromark-extension-gfm-task-list-item");
|
|
11
|
+
var _nodemodule = /*#__PURE__*/ _interop_require_default(require("node:module"));
|
|
22
12
|
var _extractts = require("./extract.js");
|
|
13
|
+
function _interop_require_default(obj) {
|
|
14
|
+
return obj && obj.__esModule ? obj : {
|
|
15
|
+
default: obj
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
// Tier-2, as embed/static.ts: the parser's packages cost ~19 ms to load and a warm tree never
|
|
19
|
+
// parses, so every store-opening command paid for them until a file actually changed.
|
|
20
|
+
var _require = typeof require === 'undefined' ? _nodemodule.default.createRequire(require("url").pathToFileURL(__filename).toString()) : require;
|
|
23
21
|
var BLOCK_TYPES = {
|
|
24
22
|
heading: 'heading',
|
|
25
23
|
paragraph: 'paragraph',
|
|
@@ -28,27 +26,46 @@ var BLOCK_TYPES = {
|
|
|
28
26
|
list: 'list',
|
|
29
27
|
blockquote: 'blockquote'
|
|
30
28
|
};
|
|
29
|
+
var cached;
|
|
31
30
|
// Imported individually, not via micromark-extension-gfm/mdast-util-gfm: those bundles also pull
|
|
32
31
|
// in gfm-tagfilter, an HTML sanitizer this library never uses (no htmlExtensions call anywhere).
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
var
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
32
|
+
function parser() {
|
|
33
|
+
if (cached) return cached;
|
|
34
|
+
var fromMarkdown = _require('mdast-util-from-markdown').fromMarkdown;
|
|
35
|
+
var gfmAutolinkLiteralFromMarkdown = _require('mdast-util-gfm-autolink-literal').gfmAutolinkLiteralFromMarkdown;
|
|
36
|
+
var gfmFootnoteFromMarkdown = _require('mdast-util-gfm-footnote').gfmFootnoteFromMarkdown;
|
|
37
|
+
var gfmStrikethroughFromMarkdown = _require('mdast-util-gfm-strikethrough').gfmStrikethroughFromMarkdown;
|
|
38
|
+
var gfmTableFromMarkdown = _require('mdast-util-gfm-table').gfmTableFromMarkdown;
|
|
39
|
+
var gfmTaskListItemFromMarkdown = _require('mdast-util-gfm-task-list-item').gfmTaskListItemFromMarkdown;
|
|
40
|
+
var gfmAutolinkLiteral = _require('micromark-extension-gfm-autolink-literal').gfmAutolinkLiteral;
|
|
41
|
+
var gfmFootnote = _require('micromark-extension-gfm-footnote').gfmFootnote;
|
|
42
|
+
var gfmStrikethrough = _require('micromark-extension-gfm-strikethrough').gfmStrikethrough;
|
|
43
|
+
var gfmTable = _require('micromark-extension-gfm-table').gfmTable;
|
|
44
|
+
var gfmTaskListItem = _require('micromark-extension-gfm-task-list-item').gfmTaskListItem;
|
|
45
|
+
cached = {
|
|
46
|
+
fromMarkdown: fromMarkdown,
|
|
47
|
+
options: {
|
|
48
|
+
extensions: [
|
|
49
|
+
gfmAutolinkLiteral(),
|
|
50
|
+
gfmFootnote(),
|
|
51
|
+
gfmStrikethrough(),
|
|
52
|
+
gfmTable(),
|
|
53
|
+
gfmTaskListItem()
|
|
54
|
+
],
|
|
55
|
+
mdastExtensions: [
|
|
56
|
+
gfmAutolinkLiteralFromMarkdown(),
|
|
57
|
+
gfmFootnoteFromMarkdown(),
|
|
58
|
+
gfmStrikethroughFromMarkdown(),
|
|
59
|
+
gfmTableFromMarkdown(),
|
|
60
|
+
gfmTaskListItemFromMarkdown()
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
return cached;
|
|
65
|
+
}
|
|
47
66
|
function parse(body) {
|
|
48
|
-
var
|
|
49
|
-
|
|
50
|
-
mdastExtensions: MDAST_EXTENSIONS
|
|
51
|
-
});
|
|
67
|
+
var _parser = parser(), fromMarkdown = _parser.fromMarkdown, options = _parser.options;
|
|
68
|
+
var tree = fromMarkdown(body, options);
|
|
52
69
|
return tree.children.map(function(node) {
|
|
53
70
|
var _BLOCK_TYPES_node_type;
|
|
54
71
|
var position = node.position;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/parse.ts"],"sourcesContent":["import type { RootContent } from 'mdast';\nimport { fromMarkdown } from 'mdast-util-from-markdown';\
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/chunk/parse.ts"],"sourcesContent":["import Module from 'node:module';\nimport type { RootContent } from 'mdast';\nimport { extractText } from './extract.ts';\nimport type { Block, BlockType } from './types.ts';\n\n// Tier-2, as embed/static.ts: the parser's packages cost ~19 ms to load and a warm tree never\n// parses, so every store-opening command paid for them until a file actually changed.\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\n\nconst BLOCK_TYPES: Partial<Record<RootContent['type'], BlockType>> = {\n heading: 'heading',\n paragraph: 'paragraph',\n code: 'code',\n table: 'table',\n list: 'list',\n blockquote: 'blockquote',\n};\n\ntype FromMarkdown = typeof import('mdast-util-from-markdown').fromMarkdown;\ntype Parser = { fromMarkdown: FromMarkdown; options: NonNullable<Parameters<FromMarkdown>[1]> };\nlet cached: Parser | undefined;\n\n// Imported individually, not via micromark-extension-gfm/mdast-util-gfm: those bundles also pull\n// in gfm-tagfilter, an HTML sanitizer this library never uses (no htmlExtensions call anywhere).\nfunction parser(): Parser {\n if (cached) return cached;\n const { fromMarkdown } = _require('mdast-util-from-markdown') as typeof import('mdast-util-from-markdown');\n const { gfmAutolinkLiteralFromMarkdown } = _require('mdast-util-gfm-autolink-literal') as typeof import('mdast-util-gfm-autolink-literal');\n const { gfmFootnoteFromMarkdown } = _require('mdast-util-gfm-footnote') as typeof import('mdast-util-gfm-footnote');\n const { gfmStrikethroughFromMarkdown } = _require('mdast-util-gfm-strikethrough') as typeof import('mdast-util-gfm-strikethrough');\n const { gfmTableFromMarkdown } = _require('mdast-util-gfm-table') as typeof import('mdast-util-gfm-table');\n const { gfmTaskListItemFromMarkdown } = _require('mdast-util-gfm-task-list-item') as typeof import('mdast-util-gfm-task-list-item');\n const { gfmAutolinkLiteral } = _require('micromark-extension-gfm-autolink-literal') as typeof import('micromark-extension-gfm-autolink-literal');\n const { gfmFootnote } = _require('micromark-extension-gfm-footnote') as typeof import('micromark-extension-gfm-footnote');\n const { gfmStrikethrough } = _require('micromark-extension-gfm-strikethrough') as typeof import('micromark-extension-gfm-strikethrough');\n const { gfmTable } = _require('micromark-extension-gfm-table') as typeof import('micromark-extension-gfm-table');\n const { gfmTaskListItem } = _require('micromark-extension-gfm-task-list-item') as typeof import('micromark-extension-gfm-task-list-item');\n cached = {\n fromMarkdown,\n options: {\n extensions: [gfmAutolinkLiteral(), gfmFootnote(), gfmStrikethrough(), gfmTable(), gfmTaskListItem()],\n mdastExtensions: [gfmAutolinkLiteralFromMarkdown(), gfmFootnoteFromMarkdown(), gfmStrikethroughFromMarkdown(), gfmTableFromMarkdown(), gfmTaskListItemFromMarkdown()],\n },\n };\n return cached;\n}\n\n// Top-level blocks of a markdown body, typed and line-extent bounded from mdast's own\n// node.position (never a regex guess). GFM extensions add tables, task lists, footnotes, strikethrough.\nexport function parse(body: string): Block[] {\n const { fromMarkdown, options } = parser();\n const tree = fromMarkdown(body, options);\n return tree.children.map((node) => {\n const position = node.position;\n const block: Block = {\n type: BLOCK_TYPES[node.type] ?? 'other',\n startLine: position ? position.start.line : 1,\n endLine: position ? position.end.line : 1,\n node,\n };\n if (node.type === 'heading') {\n block.depth = node.depth;\n block.text = extractText(node);\n }\n return block;\n });\n}\n"],"names":["parse","_require","require","Module","createRequire","BLOCK_TYPES","heading","paragraph","code","table","list","blockquote","cached","parser","fromMarkdown","gfmAutolinkLiteralFromMarkdown","gfmFootnoteFromMarkdown","gfmStrikethroughFromMarkdown","gfmTableFromMarkdown","gfmTaskListItemFromMarkdown","gfmAutolinkLiteral","gfmFootnote","gfmStrikethrough","gfmTable","gfmTaskListItem","options","extensions","mdastExtensions","body","tree","children","map","node","position","block","type","startLine","start","line","endLine","end","depth","text","extractText"],"mappings":";;;;+BAiDgBA;;;eAAAA;;;iEAjDG;yBAES;;;;;;AAG5B,8FAA8F;AAC9F,sFAAsF;AACtF,IAAMC,WAAW,OAAOC,YAAY,cAAcC,mBAAM,CAACC,aAAa,CAAC,uDAAmBF;AAE1F,IAAMG,cAA+D;IACnEC,SAAS;IACTC,WAAW;IACXC,MAAM;IACNC,OAAO;IACPC,MAAM;IACNC,YAAY;AACd;AAIA,IAAIC;AAEJ,iGAAiG;AACjG,iGAAiG;AACjG,SAASC;IACP,IAAID,QAAQ,OAAOA;IACnB,IAAM,AAAEE,eAAiBb,SAAS,4BAA1Ba;IACR,IAAM,AAAEC,iCAAmCd,SAAS,mCAA5Cc;IACR,IAAM,AAAEC,0BAA4Bf,SAAS,2BAArCe;IACR,IAAM,AAAEC,+BAAiChB,SAAS,gCAA1CgB;IACR,IAAM,AAAEC,uBAAyBjB,SAAS,wBAAlCiB;IACR,IAAM,AAAEC,8BAAgClB,SAAS,iCAAzCkB;IACR,IAAM,AAAEC,qBAAuBnB,SAAS,4CAAhCmB;IACR,IAAM,AAAEC,cAAgBpB,SAAS,oCAAzBoB;IACR,IAAM,AAAEC,mBAAqBrB,SAAS,yCAA9BqB;IACR,IAAM,AAAEC,WAAatB,SAAS,iCAAtBsB;IACR,IAAM,AAAEC,kBAAoBvB,SAAS,0CAA7BuB;IACRZ,SAAS;QACPE,cAAAA;QACAW,SAAS;YACPC,YAAY;gBAACN;gBAAsBC;gBAAeC;gBAAoBC;gBAAYC;aAAkB;YACpGG,iBAAiB;gBAACZ;gBAAkCC;gBAA2BC;gBAAgCC;gBAAwBC;aAA8B;QACvK;IACF;IACA,OAAOP;AACT;AAIO,SAASZ,MAAM4B,IAAY;IAChC,IAAkCf,UAAAA,UAA1BC,eAA0BD,QAA1BC,cAAcW,UAAYZ,QAAZY;IACtB,IAAMI,OAAOf,aAAac,MAAMH;IAChC,OAAOI,KAAKC,QAAQ,CAACC,GAAG,CAAC,SAACC;YAGhB3B;QAFR,IAAM4B,WAAWD,KAAKC,QAAQ;QAC9B,IAAMC,QAAe;YACnBC,IAAI,GAAE9B,yBAAAA,WAAW,CAAC2B,KAAKG,IAAI,CAAC,cAAtB9B,oCAAAA,yBAA0B;YAChC+B,WAAWH,WAAWA,SAASI,KAAK,CAACC,IAAI,GAAG;YAC5CC,SAASN,WAAWA,SAASO,GAAG,CAACF,IAAI,GAAG;YACxCN,MAAAA;QACF;QACA,IAAIA,KAAKG,IAAI,KAAK,WAAW;YAC3BD,MAAMO,KAAK,GAAGT,KAAKS,KAAK;YACxBP,MAAMQ,IAAI,GAAGC,IAAAA,sBAAW,EAACX;QAC3B;QACA,OAAOE;IACT;AACF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
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 DEFAULT_TARGET_TOKENS () {
|
|
13
|
+
return DEFAULT_TARGET_TOKENS;
|
|
14
|
+
},
|
|
15
|
+
get estimateTokens () {
|
|
16
|
+
return estimateTokens;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
var _segmentts = require("../text/segment.js");
|
|
20
|
+
var DEFAULT_TARGET_TOKENS = 500;
|
|
21
|
+
// D5: segment.ts's unspaced-script set packs close to one token per character; Hangul is
|
|
22
|
+
// spaced but still token-dense and sits in this set as a conservative bound (one Unicode set, one home).
|
|
23
|
+
var DENSE_SCRIPT = new RegExp("[".concat(_segmentts.UNSPACED_SCRIPTS, "\\p{scx=Hangul}]"), 'u');
|
|
24
|
+
function estimateTokens(text) {
|
|
25
|
+
var dense = 0;
|
|
26
|
+
var other = 0;
|
|
27
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
28
|
+
try {
|
|
29
|
+
for(var _iterator = text[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
30
|
+
var ch = _step.value;
|
|
31
|
+
if (DENSE_SCRIPT.test(ch)) dense++;
|
|
32
|
+
else other++;
|
|
33
|
+
}
|
|
34
|
+
} catch (err) {
|
|
35
|
+
_didIteratorError = true;
|
|
36
|
+
_iteratorError = err;
|
|
37
|
+
} finally{
|
|
38
|
+
try {
|
|
39
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
40
|
+
_iterator.return();
|
|
41
|
+
}
|
|
42
|
+
} finally{
|
|
43
|
+
if (_didIteratorError) {
|
|
44
|
+
throw _iteratorError;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return dense + other / 4;
|
|
49
|
+
}
|
|
50
|
+
/* 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/chunk/tokens.ts"],"sourcesContent":["import { UNSPACED_SCRIPTS } from '../text/segment.ts';\n\nexport const DEFAULT_TARGET_TOKENS = 500;\n\n// D5: segment.ts's unspaced-script set packs close to one token per character; Hangul is\n// spaced but still token-dense and sits in this set as a conservative bound (one Unicode set, one home).\nconst DENSE_SCRIPT = new RegExp(`[${UNSPACED_SCRIPTS}\\\\p{scx=Hangul}]`, 'u');\n\n// D5's size estimate: dense-script graphemes 1:1, everything else at 4 chars/token.\nexport function estimateTokens(text: string): number {\n let dense = 0;\n let other = 0;\n for (const ch of text) {\n if (DENSE_SCRIPT.test(ch)) dense++;\n else other++;\n }\n return dense + other / 4;\n}\n"],"names":["DEFAULT_TARGET_TOKENS","estimateTokens","DENSE_SCRIPT","RegExp","UNSPACED_SCRIPTS","text","dense","other","ch","test"],"mappings":";;;;;;;;;;;QAEaA;eAAAA;;QAOGC;eAAAA;;;yBATiB;AAE1B,IAAMD,wBAAwB;AAErC,yFAAyF;AACzF,yGAAyG;AACzG,IAAME,eAAe,IAAIC,OAAO,AAAC,IAAoB,OAAjBC,2BAAgB,EAAC,qBAAmB;AAGjE,SAASH,eAAeI,IAAY;IACzC,IAAIC,QAAQ;IACZ,IAAIC,QAAQ;QACP,kCAAA,2BAAA;;QAAL,QAAK,YAAYF,yBAAZ,SAAA,6BAAA,QAAA,yBAAA,iCAAkB;YAAlB,IAAMG,KAAN;YACH,IAAIN,aAAaO,IAAI,CAACD,KAAKF;iBACtBC;QACP;;QAHK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAIL,OAAOD,QAAQC,QAAQ;AACzB"}
|