flappa-doormal 2.11.4 → 2.11.6
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/AGENTS.md +56 -5
- package/README.md +2 -0
- package/dist/index.d.mts +10 -76
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +447 -647
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/AGENTS.md
CHANGED
|
@@ -118,7 +118,7 @@ src/
|
|
|
118
118
|
- `findNextPagePosition()` - Find next page content position
|
|
119
119
|
- `findPatternBreakPosition()` - Find pattern match by preference
|
|
120
120
|
- `findSafeBreakPosition()` - Search backward for a safe linguistic split point (whitespace/punctuation)
|
|
121
|
-
- `
|
|
121
|
+
- `adjustForUnicodeBoundary()` - Ensure split position doesn't corrupt surrogate pairs, combining marks, ZWJ/ZWNJ, or variation selectors
|
|
122
122
|
|
|
123
123
|
10. **`types.ts`** - Type definitions
|
|
124
124
|
- `Logger` interface - Optional logging for debugging
|
|
@@ -269,7 +269,7 @@ When using `maxContentLength`, the segmenter prevents text corruption through se
|
|
|
269
269
|
**Algorithm:**
|
|
270
270
|
1. **Windowed Pattern Match**: Attempt to find a user-provided `breakpoint` pattern within the character window.
|
|
271
271
|
2. **Safe Fallback (Linguistic)**: If no pattern matches, use `findSafeBreakPosition()` to search backward (100 chars) for whitespace or punctuation `[\s\n.,;!?؛،۔]`.
|
|
272
|
-
3. **Safe Fallback (Technical)**: If still no safe break found, use `
|
|
272
|
+
3. **Safe Fallback (Technical)**: If still no safe break found, use `adjustForUnicodeBoundary()` to ensure the split doesn't corrupt surrogate pairs, combining marks, ZWJ/ZWNJ, or variation selectors.
|
|
273
273
|
4. **Hard Split**: Only as a final resort is a character-exact split performed.
|
|
274
274
|
|
|
275
275
|
**Progress Guarantee**:
|
|
@@ -333,6 +333,7 @@ The original `segmentPages` had complexity 37 (max: 15). Extraction:
|
|
|
333
333
|
- **Unit tests**: Each utility function has dedicated tests
|
|
334
334
|
- **Integration tests**: Full pipeline tests in `segmenter.test.ts`
|
|
335
335
|
- **Real-world tests**: `segmenter.bukhari.test.ts` uses actual hadith data
|
|
336
|
+
- **Style convention**: Prefer `it('should ...', () => { ... })` (Bun) for consistency across the suite
|
|
336
337
|
- Run: `bun test`
|
|
337
338
|
|
|
338
339
|
## Code Quality Standards
|
|
@@ -433,18 +434,68 @@ bunx biome lint .
|
|
|
433
434
|
|
|
434
435
|
11. **Safety Fallback (Search-back)**: When forced to split at a hard character limit, searching backward for whitespace/punctuation (`[\s\n.,;!?؛،۔]`) prevents word-chopping and improves readability significantly.
|
|
435
436
|
|
|
436
|
-
12. **Unicode
|
|
437
|
+
12. **Unicode Boundary Safety (Surrogates + Graphemes)**: Multi-byte characters (like emojis) can be corrupted if split in the middle of a surrogate pair. Similarly, Arabic diacritics (combining marks), ZWJ/ZWNJ, and variation selectors can be orphaned if a hard split lands in the middle of a grapheme cluster. Use `adjustForUnicodeBoundary` when forced to hard-split near a limit.
|
|
437
438
|
|
|
438
439
|
13. **Recursion/Iteration Safety**: Using a progress-based guard (comparing `cursorPos` before and after loop iteration) is safer than fixed iteration limits for supporting arbitrary-sized content without truncation risks.
|
|
439
440
|
|
|
440
441
|
14. **Accidental File Overwrites**: Be extremely careful when using tools like `replace_file_content` with large ranges. Verify file integrity frequently (e.g., `git diff`) to catch accidental deletions of existing code or tests. Merging new tests into existing files is a high-risk operation for AI agents.
|
|
441
442
|
|
|
442
|
-
15. **Invisible Unicode Marks Break Regex Anchors**: Arabic text often contains invisible
|
|
443
|
+
15. **Invisible Unicode Marks Break Regex Anchors**: Arabic text often contains invisible formatting marks like Left-to-Right Mark (`U+200E`), Right-to-Left Mark (`U+200F`), Arabic Letter Mark (`U+061C`), Zero-Width Space (`U+200B`), Zero-Width Non-Joiner (`U+200C`), Zero-Width Joiner (`U+200D`), or BOM (`U+FEFF`). These can appear at line starts after `\n` but before visible characters, breaking `^` anchored patterns. Solution: include an optional zero-width character class prefix in line-start patterns: `^[\u200E\u200F\u061C\u200B\u200C\u200D\uFEFF]*(?:pattern)`. The library now handles this automatically in `buildLineStartsWithRegexSource` and `buildLineStartsAfterRegexSource`.
|
|
443
444
|
|
|
444
|
-
16. **Large Segment Performance & Debugging Strategy**: When processing large books (1000+ pages), avoid O(n²) algorithms. The library uses a fast-path threshold (1000 pages) to switch from accurate string-search boundary detection to cumulative-offset-based slicing. To diagnose performance bottlenecks: (1) Look for logs with "Using iterative path" or "Using accurate string-search path" with large `pageCount` values, (2) Check `iterations` count in completion logs, (3) Strategic logs are placed at operation boundaries (start/end) NOT inside tight loops to avoid log-induced performance regression.
|
|
445
|
+
16. **Large Segment Performance & Debugging Strategy**: When processing large books (1000+ pages), avoid O(n²) algorithms. The library uses a fast-path threshold (1000 pages) to switch from accurate string-search boundary detection to cumulative-offset-based slicing. Even on the iterative path (e.g. debug mode), we **slice only the active window (+padding)** per iteration (never `fullContent.slice(cursorPos)`), to avoid quadratic allocation/GC churn. To diagnose performance bottlenecks: (1) Look for logs with "Using iterative path" or "Using accurate string-search path" with large `pageCount` values, (2) Check `iterations` count in completion logs, (3) Strategic logs are placed at operation boundaries (start/end) NOT inside tight loops to avoid log-induced performance regression.
|
|
446
|
+
|
|
447
|
+
17. **`maxPages=0` is a hard invariant**: When `maxPages=0`, breakpoint windows must never scan beyond the current page boundary. Relying purely on boundary detection (string search) can fail near page ends for long Arabic text + space joiners, letting the window “see” into the next page and creating multi-page segments. The safe fix is to clamp the breakpoint window to the current page’s end using `boundaryPositions` in breakpoint processing.
|
|
448
|
+
|
|
449
|
+
18. **`''` breakpoint semantics depend on whether the window is page-bounded vs length-bounded**: `''` means “page boundary fallback”, but it’s intentionally **mode-dependent**:
|
|
450
|
+
|
|
451
|
+
- **Page-bounded window (maxPages-driven)**: `''` should “swallow the remainder of the current page” (i.e. break at the **next page boundary**, not at an arbitrary character limit). This prevents accidentally consuming part of the next page when no other breakpoint patterns match.
|
|
452
|
+
- **Length-bounded window (maxContentLength-driven)**: `''` should **not** force an early page-boundary break. In this mode we want the best split *near the length limit* (safe-break fallback → Unicode-safe hard split) even if that means a piece can cross a page boundary.
|
|
453
|
+
|
|
454
|
+
Concrete branching (simplified):
|
|
455
|
+
|
|
456
|
+
```ts
|
|
457
|
+
if (breakpoint.pattern === '') {
|
|
458
|
+
if (!isLengthBounded /* i.e. maxContentLength is not the active limiter */) {
|
|
459
|
+
return nextPageBoundaryWithinWindow ?? windowEndPosition; // end-of-page semantics
|
|
460
|
+
}
|
|
461
|
+
return safeBreakNear(windowEndPosition) ?? unicodeSafeHardSplit(windowEndPosition);
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
19. **Beware `.only` in test files**: A single `it.only(...)` can mask unrelated failing fixtures for a long time. When debugging, remove `.only` as soon as you have a focused reproduction, and re-run the full suite to catch latent failures.
|
|
466
|
+
|
|
467
|
+
20. **Tooling gotcha: IDE diagnostics vs actual parser**: If the editor shows parse errors but `bun test` and `bunx biome check` pass, suspect unsaved local edits or stale diagnostics rather than codebase syntax. Always validate with a direct `bunx biome check <file>` before making sweeping “syntax fix” edits.
|
|
468
|
+
|
|
469
|
+
21. **Content-based page detection fails with overlapping content**: The `computeNextFromIdx` function uses prefix matching to detect page transitions. When page 0 ends with text identical to page 1's prefix, it incorrectly advances `currentFromIdx`. **Fix**: When `maxPages=0`, override content-based detection with position-based detection via `findPageIndexForPosition(cursorPos, boundaryPositions, fromIdx)`. Always trust cumulative offsets over content heuristics for strict page isolation.
|
|
470
|
+
|
|
471
|
+
22. **Test edge cases with data that TRIGGERS the bug path**: Simple test data often bypasses problematic code paths. Ensure tests: (a) use `maxContentLength` to force sub-page splitting, (b) include enough content to exceed window sizes, (c) create overlapping/duplicate text at page boundaries, (d) verify that segments are actually split (not just checking no crashes).
|
|
472
|
+
|
|
473
|
+
23. **Debug breakpoint processing with the logger**: Pass a `logger` object with `debug` and `trace` methods to `segmentPages()`. Key logs: `boundaryPositions built` (page boundary byte offsets), `iteration=N` (shows `currentFromIdx`, `cursorPos`, `windowEndPosition` per loop), `Complete` (final segment count).
|
|
474
|
+
|
|
475
|
+
24. **Navigating `breakpoint-processor.ts`**: Key functions in (approximate) execution order:
|
|
476
|
+
|
|
477
|
+
- `applyBreakpoints()` (entry point)
|
|
478
|
+
- `processOversizedSegment()` (main loop)
|
|
479
|
+
- `buildBoundaryPositions()` (precompute page boundary positions)
|
|
480
|
+
- loop iteration:
|
|
481
|
+
- `computeWindowEndIdx()` (page-window end by `maxPages`)
|
|
482
|
+
- `getWindowEndPosition()` / maxPages=0 clamp (compute window end in content-space)
|
|
483
|
+
- `findBreakOffsetForWindow()` → `findBreakPosition()` → `handlePageBoundaryBreak()` / `findPatternBreakPosition()` (select split point)
|
|
484
|
+
- `advanceCursorAndIndex()` (progress)
|
|
485
|
+
- `computeNextFromIdx()` (heuristic) **or** position-based override when `maxPages=0` (see #21)
|
|
486
|
+
|
|
487
|
+
25. **Page attribution can drift in large-document breakpoint processing**: For ≥`FAST_PATH_THRESHOLD` segments, boundary positions may be derived from cumulative offsets (fast path). If upstream content is modified (e.g. marker stripping or accidental leading-trim), binary-search attribution can classify a piece as starting **before** `currentFromIdx`, inflating `(to - from)` and violating `maxPages`. **Fix**: clamp `actualStartIdx >= currentFromIdx` and re-apply the `maxPages` window using the same ID-span logic as `computeWindowEndIdx(...)` before creating the piece segment.
|
|
488
|
+
|
|
489
|
+
26. **Offset fast path must respect page-ID span semantics**: `maxPages` in this library is enforced as an **ID span** invariant (`(to ?? from) - from <= maxPages`). For large segments, the offset-based fast path must choose `segEnd` using the same ID-window logic as `computeWindowEndIdx(...)` (not “N pages by index”), otherwise gaps (e.g. `2216 → 2218`) produce illegal spans.
|
|
490
|
+
|
|
491
|
+
27. **Never `trimStart()` huge fallback content**: `ensureFallbackSegment()` constructs “all pages as one segment” when there are no structural split rules. If this giant content is `trimStart()`’d, cumulative offsets and derived boundary positions become inconsistent, which can lead to incorrect `from/to` attribution and `maxPages` violations that only appear on very large books.
|
|
492
|
+
|
|
493
|
+
28. **Always test both sides of the fast-path threshold**: Several breakpoint bugs only reproduce at or above `FAST_PATH_THRESHOLD` (1000). Add regressions at `threshold-1` and `threshold` to avoid “works in small unit tests, fails on full books” surprises.
|
|
445
494
|
|
|
446
495
|
### Process Template (Multi-agent design review, TDD-first)
|
|
447
496
|
|
|
497
|
+
|
|
498
|
+
|
|
448
499
|
If you want to repeat the “write a plan → get multiple AI critiques → synthesize → update plan → implement TDD-first” workflow, use:
|
|
449
500
|
|
|
450
501
|
- `docs/ai-multi-agent-tdd-template.md`
|
package/README.md
CHANGED
|
@@ -324,6 +324,8 @@ When a segment exceeds `maxPages` or `maxContentLength`, breakpoints split it at
|
|
|
324
324
|
}
|
|
325
325
|
```
|
|
326
326
|
|
|
327
|
+
**Security note (ReDoS)**: Breakpoints (and raw `regex` rules) compile user-provided regular expressions. **Do not accept untrusted patterns** (e.g. from end users) without validation/sandboxing; some regexes can trigger catastrophic backtracking and hang the process.
|
|
328
|
+
|
|
327
329
|
### 12. Occurrence Filtering
|
|
328
330
|
|
|
329
331
|
Control which matches to use:
|
package/dist/index.d.mts
CHANGED
|
@@ -28,41 +28,6 @@
|
|
|
28
28
|
* escapeRegex('a+b*c?') // → 'a\\+b\\*c\\?'
|
|
29
29
|
*/
|
|
30
30
|
declare const escapeRegex: (s: string) => string;
|
|
31
|
-
/**
|
|
32
|
-
* Creates a diacritic-insensitive regex pattern for Arabic text matching.
|
|
33
|
-
*
|
|
34
|
-
* Transforms input text into a regex pattern that matches the text regardless
|
|
35
|
-
* of diacritical marks (harakat) and character variations. Each character in
|
|
36
|
-
* the input is:
|
|
37
|
-
* 1. Expanded to its equivalence class (if applicable)
|
|
38
|
-
* 2. Followed by an optional diacritics matcher
|
|
39
|
-
*
|
|
40
|
-
* This allows matching:
|
|
41
|
-
* - `حدثنا` with `حَدَّثَنَا` (with full diacritics)
|
|
42
|
-
* - `الإيمان` with `الايمان` (alef variants)
|
|
43
|
-
* - `صلاة` with `صلاه` (ta marbuta ↔ ha)
|
|
44
|
-
*
|
|
45
|
-
* @param text - Input Arabic text to make diacritic-insensitive
|
|
46
|
-
* @returns Regex pattern string that matches the text with or without diacritics
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* const pattern = makeDiacriticInsensitive('حدثنا');
|
|
50
|
-
* // Each char gets equivalence class + optional diacritics
|
|
51
|
-
* // Result matches: حدثنا, حَدَّثَنَا, حَدَثَنَا, etc.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* const pattern = makeDiacriticInsensitive('باب');
|
|
55
|
-
* new RegExp(pattern, 'u').test('بَابٌ') // → true
|
|
56
|
-
* new RegExp(pattern, 'u').test('باب') // → true
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* // Using with split rules
|
|
60
|
-
* {
|
|
61
|
-
* lineStartsWith: ['باب'],
|
|
62
|
-
* split: 'at',
|
|
63
|
-
* fuzzy: true // Applies makeDiacriticInsensitive internally
|
|
64
|
-
* }
|
|
65
|
-
*/
|
|
66
31
|
declare const makeDiacriticInsensitive: (text: string) => string;
|
|
67
32
|
//#endregion
|
|
68
33
|
//#region src/segmentation/types.d.ts
|
|
@@ -789,35 +754,10 @@ type OptimizeResult = {
|
|
|
789
754
|
/** Number of rules that were merged into existing rules */
|
|
790
755
|
mergedCount: number;
|
|
791
756
|
};
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
* 1. **Merges compatible rules**: Rules with the same pattern type and identical
|
|
797
|
-
* options (meta, fuzzy, min/max, etc.) have their pattern arrays combined
|
|
798
|
-
* 2. **Deduplicates patterns**: Removes duplicate patterns within each rule
|
|
799
|
-
* 3. **Sorts by specificity**: Rules with longer patterns come first
|
|
800
|
-
*
|
|
801
|
-
* Only array-based pattern types (`lineStartsWith`, `lineStartsAfter`, `lineEndsWith`)
|
|
802
|
-
* can be merged. `template` and `regex` rules are kept separate.
|
|
803
|
-
*
|
|
804
|
-
* @param rules - Array of split rules to optimize
|
|
805
|
-
* @returns Optimized rules and count of merged rules
|
|
806
|
-
*
|
|
807
|
-
* @example
|
|
808
|
-
* import { optimizeRules } from 'flappa-doormal';
|
|
809
|
-
*
|
|
810
|
-
* const { rules, mergedCount } = optimizeRules([
|
|
811
|
-
* { lineStartsWith: ['{{kitab}}'], fuzzy: true, meta: { type: 'header' } },
|
|
812
|
-
* { lineStartsWith: ['{{bab}}'], fuzzy: true, meta: { type: 'header' } },
|
|
813
|
-
* { lineStartsAfter: ['{{numbered}}'], meta: { type: 'entry' } },
|
|
814
|
-
* ]);
|
|
815
|
-
*
|
|
816
|
-
* // rules[0] = { lineStartsWith: ['{{kitab}}', '{{bab}}'], fuzzy: true, meta: { type: 'header' } }
|
|
817
|
-
* // rules[1] = { lineStartsAfter: ['{{numbered}}'], meta: { type: 'entry' } }
|
|
818
|
-
* // mergedCount = 1
|
|
819
|
-
*/
|
|
820
|
-
declare const optimizeRules: (rules: SplitRule[]) => OptimizeResult;
|
|
757
|
+
declare const optimizeRules: (rules: SplitRule[]) => {
|
|
758
|
+
mergedCount: number;
|
|
759
|
+
rules: SplitRule[];
|
|
760
|
+
};
|
|
821
761
|
//#endregion
|
|
822
762
|
//#region src/segmentation/pattern-validator.d.ts
|
|
823
763
|
/**
|
|
@@ -893,16 +833,6 @@ declare const formatValidationReport: (results: (RuleValidationResult | undefine
|
|
|
893
833
|
* - If `pageIds` is `[]`, the rule applies to no pages (rule is skipped).
|
|
894
834
|
*/
|
|
895
835
|
type ReplaceRule = NonNullable<SegmentationOptions['replace']>[number];
|
|
896
|
-
/**
|
|
897
|
-
* Applies ordered regex replacements to page content (per page).
|
|
898
|
-
*
|
|
899
|
-
* - Replacement rules are applied in array order.
|
|
900
|
-
* - Each rule is applied globally (flag `g` enforced) with unicode mode (flag `u` enforced).
|
|
901
|
-
* - `pageIds` can scope a rule to specific pages. `pageIds: []` skips the rule entirely.
|
|
902
|
-
*
|
|
903
|
-
* This function is intentionally **pure**:
|
|
904
|
-
* it returns a new pages array only when changes are needed, otherwise it returns the original pages.
|
|
905
|
-
*/
|
|
906
836
|
declare const applyReplacements: (pages: Page[], rules?: ReplaceRule[]) => Page[];
|
|
907
837
|
//#endregion
|
|
908
838
|
//#region src/segmentation/segmenter.d.ts
|
|
@@ -1134,7 +1064,11 @@ type ExpandResult = {
|
|
|
1134
1064
|
* expandTokensWithCaptures('{{bab}}', makeDiacriticInsensitive)
|
|
1135
1065
|
* // → { pattern: 'بَ?ا?بٌ?', captureNames: [], hasCaptures: false }
|
|
1136
1066
|
*/
|
|
1137
|
-
declare const expandTokensWithCaptures: (query: string, fuzzyTransform?: (pattern: string) => string, capturePrefix?: string) =>
|
|
1067
|
+
declare const expandTokensWithCaptures: (query: string, fuzzyTransform?: (pattern: string) => string, capturePrefix?: string) => {
|
|
1068
|
+
captureNames: string[];
|
|
1069
|
+
hasCaptures: boolean;
|
|
1070
|
+
pattern: string;
|
|
1071
|
+
};
|
|
1138
1072
|
/**
|
|
1139
1073
|
* Expands template tokens in a query string to their regex equivalents.
|
|
1140
1074
|
*
|
|
@@ -1204,7 +1138,7 @@ declare const getAvailableTokens: () => string[];
|
|
|
1204
1138
|
* getTokenPattern('dash') // → '[-–—ـ]'
|
|
1205
1139
|
* getTokenPattern('unknown') // → undefined
|
|
1206
1140
|
*/
|
|
1207
|
-
declare const getTokenPattern: (tokenName: string) => string
|
|
1141
|
+
declare const getTokenPattern: (tokenName: string) => string;
|
|
1208
1142
|
/**
|
|
1209
1143
|
* Checks if a pattern (or array of patterns) contains tokens that should
|
|
1210
1144
|
* default to fuzzy matching.
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/segmentation/fuzzy.ts","../src/segmentation/types.ts","../src/segmentation/optimize-rules.ts","../src/segmentation/pattern-validator.ts","../src/segmentation/replace.ts","../src/segmentation/segmenter.ts","../src/segmentation/tokens.ts","../src/analysis/line-starts.ts","../src/analysis/repeating-sequences.ts","../src/detection.ts","../src/recovery.ts"],"sourcesContent":[],"mappings":";;AAkEA;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/segmentation/fuzzy.ts","../src/segmentation/types.ts","../src/segmentation/optimize-rules.ts","../src/segmentation/pattern-validator.ts","../src/segmentation/replace.ts","../src/segmentation/segmenter.ts","../src/segmentation/tokens.ts","../src/analysis/line-starts.ts","../src/analysis/repeating-sequences.ts","../src/detection.ts","../src/recovery.ts"],"sourcesContent":[],"mappings":"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"}
|