@adeu/core 1.27.0 → 1.29.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.
package/dist/index.d.cts CHANGED
@@ -128,6 +128,23 @@ declare class DocumentMapper {
128
128
  * characters are excluded.
129
129
  */
130
130
  private _find_plain_projection_matches;
131
+ /**
132
+ * True when no run-backed span overlaps [start, start+length): the range
133
+ * covers only virtual projection text — meta bubbles (change/comment
134
+ * headers, timestamps), style markers, list prefixes. Such text does not
135
+ * exist in the document, so it can neither satisfy a match nor count
136
+ * toward ambiguity (QA 2026-07-19 ADEU-QA-002 C): an edit targeting "4"
137
+ * used to be rejected as "appears 8 times" because a comment bubble's
138
+ * timestamp matched.
139
+ *
140
+ * Anchor tokens ({#Bookmark}, {#cell:paraId}) are the exception: they are
141
+ * deliberate virtual TARGETING surfaces (empty-cell writes, bookmark
142
+ * anchors) and must stay matchable.
143
+ */
144
+ range_is_virtual_only(start: number, length: number): boolean;
145
+ /** Filters find_all_match_indices output down to matches that touch at
146
+ * least one run-backed span. See range_is_virtual_only. */
147
+ drop_virtual_only_matches(matches: [number, number][]): [number, number][];
131
148
  find_match_index(target_text: string, is_regex?: boolean): [number, number];
132
149
  find_all_match_indices(target_text: string, is_regex?: boolean): [number, number][];
133
150
  find_target_runs(target_text: string): Run[];
@@ -291,7 +308,12 @@ declare class RedlineEngine {
291
308
  private _build_edit_context_previews;
292
309
  private _scan_existing_ids;
293
310
  private _get_heading_path_and_page;
294
- accept_all_revisions(): void;
311
+ accept_all_revisions(): {
312
+ accepted_insertions: number;
313
+ accepted_deletions: number;
314
+ accepted_formatting: number;
315
+ removed_comments: number;
316
+ };
295
317
  /**
296
318
  * Revert every tracked change, returning the document to the state it had
297
319
  * before any revision was proposed. The exact inverse of
@@ -386,6 +408,7 @@ declare class RedlineEngine {
386
408
  *
387
409
  * Does NOT attach comments; callers handle that.
388
410
  */
411
+ private _clone_pPr_scrubbing_headings;
389
412
  private _track_insert_multiline;
390
413
  /**
391
414
  * Builds a single tracked-insert wrapper (<w:ins>) containing one or more
@@ -431,7 +454,10 @@ declare class RedlineEngine {
431
454
  * actions, so it can be stale mid-batch. Returns null if not found.
432
455
  */
433
456
  private _get_comment_author;
457
+ /** Returns how many comment BODIES were actually deleted (see below: only
458
+ * our own are; foreign ones keep their body and lose only the anchor). */
434
459
  private _clean_wrapping_comments;
460
+ /** Returns how many comment bodies were deleted. */
435
461
  private _delete_comments_in_element;
436
462
  validate_edits(edits: any[], index_offset?: number): string[];
437
463
  /**
@@ -451,7 +477,42 @@ declare class RedlineEngine {
451
477
  process_batch(changes: DocumentChange[], dry_run?: boolean): any;
452
478
  private _process_batch_internal;
453
479
  apply_edits(edits: any[], page_offsets?: number[]): [number, number];
454
- apply_review_actions(actions: any[]): [number, number];
480
+ /**
481
+ * True when the paragraph still carries visible content (w:t text, w:tab,
482
+ * w:br) that is NOT wrapped in a tracked deletion — i.e. the paragraph
483
+ * would render non-empty in the accepted document.
484
+ */
485
+ private _paragraph_has_visible_content;
486
+ /**
487
+ * All contiguous same-author w:ins/w:del siblings that form one logical
488
+ * modification block with `node` (a replacement's del+ins pair). Mirrors
489
+ * the Python engine's _get_paired_nodes: comment range markers and
490
+ * rPr/pPr are transparent; a different author or any other element breaks
491
+ * the group.
492
+ */
493
+ private _get_paired_nodes;
494
+ /**
495
+ * All revision ids that resolve as ONE unit with `target_id`: the ids of
496
+ * every contiguous same-author w:ins/w:del sibling of its elements (a
497
+ * replacement's del+ins pair), plus the id itself.
498
+ */
499
+ private _resolution_group_ids;
500
+ /**
501
+ * Document-aware validation (QA 2026-07-19 ADEU-QA-004): a replacement's
502
+ * del+ins pair carries two distinct ids but resolves as one unit, so a
503
+ * batch that accepts one side and rejects the other is contradictory.
504
+ * Rejecting it up front — before any action mutates the document — keeps
505
+ * the batch transactional.
506
+ */
507
+ validate_action_pairing(actions: any[]): string[];
508
+ /**
509
+ * Returns [applied, skipped, already_resolved]. `applied` counts actions
510
+ * that caused an observable state transition; an action naming an id an
511
+ * earlier action of this batch already resolved (via its replacement pair)
512
+ * is counted in `already_resolved` instead — never as applied
513
+ * (QA 2026-07-19 ADEU-QA-004).
514
+ */
515
+ apply_review_actions(actions: any[]): [number, number, number];
455
516
  private _apply_table_edit;
456
517
  private _pre_resolve_heuristic_edit;
457
518
  /**
package/dist/index.d.ts CHANGED
@@ -128,6 +128,23 @@ declare class DocumentMapper {
128
128
  * characters are excluded.
129
129
  */
130
130
  private _find_plain_projection_matches;
131
+ /**
132
+ * True when no run-backed span overlaps [start, start+length): the range
133
+ * covers only virtual projection text — meta bubbles (change/comment
134
+ * headers, timestamps), style markers, list prefixes. Such text does not
135
+ * exist in the document, so it can neither satisfy a match nor count
136
+ * toward ambiguity (QA 2026-07-19 ADEU-QA-002 C): an edit targeting "4"
137
+ * used to be rejected as "appears 8 times" because a comment bubble's
138
+ * timestamp matched.
139
+ *
140
+ * Anchor tokens ({#Bookmark}, {#cell:paraId}) are the exception: they are
141
+ * deliberate virtual TARGETING surfaces (empty-cell writes, bookmark
142
+ * anchors) and must stay matchable.
143
+ */
144
+ range_is_virtual_only(start: number, length: number): boolean;
145
+ /** Filters find_all_match_indices output down to matches that touch at
146
+ * least one run-backed span. See range_is_virtual_only. */
147
+ drop_virtual_only_matches(matches: [number, number][]): [number, number][];
131
148
  find_match_index(target_text: string, is_regex?: boolean): [number, number];
132
149
  find_all_match_indices(target_text: string, is_regex?: boolean): [number, number][];
133
150
  find_target_runs(target_text: string): Run[];
@@ -291,7 +308,12 @@ declare class RedlineEngine {
291
308
  private _build_edit_context_previews;
292
309
  private _scan_existing_ids;
293
310
  private _get_heading_path_and_page;
294
- accept_all_revisions(): void;
311
+ accept_all_revisions(): {
312
+ accepted_insertions: number;
313
+ accepted_deletions: number;
314
+ accepted_formatting: number;
315
+ removed_comments: number;
316
+ };
295
317
  /**
296
318
  * Revert every tracked change, returning the document to the state it had
297
319
  * before any revision was proposed. The exact inverse of
@@ -386,6 +408,7 @@ declare class RedlineEngine {
386
408
  *
387
409
  * Does NOT attach comments; callers handle that.
388
410
  */
411
+ private _clone_pPr_scrubbing_headings;
389
412
  private _track_insert_multiline;
390
413
  /**
391
414
  * Builds a single tracked-insert wrapper (<w:ins>) containing one or more
@@ -431,7 +454,10 @@ declare class RedlineEngine {
431
454
  * actions, so it can be stale mid-batch. Returns null if not found.
432
455
  */
433
456
  private _get_comment_author;
457
+ /** Returns how many comment BODIES were actually deleted (see below: only
458
+ * our own are; foreign ones keep their body and lose only the anchor). */
434
459
  private _clean_wrapping_comments;
460
+ /** Returns how many comment bodies were deleted. */
435
461
  private _delete_comments_in_element;
436
462
  validate_edits(edits: any[], index_offset?: number): string[];
437
463
  /**
@@ -451,7 +477,42 @@ declare class RedlineEngine {
451
477
  process_batch(changes: DocumentChange[], dry_run?: boolean): any;
452
478
  private _process_batch_internal;
453
479
  apply_edits(edits: any[], page_offsets?: number[]): [number, number];
454
- apply_review_actions(actions: any[]): [number, number];
480
+ /**
481
+ * True when the paragraph still carries visible content (w:t text, w:tab,
482
+ * w:br) that is NOT wrapped in a tracked deletion — i.e. the paragraph
483
+ * would render non-empty in the accepted document.
484
+ */
485
+ private _paragraph_has_visible_content;
486
+ /**
487
+ * All contiguous same-author w:ins/w:del siblings that form one logical
488
+ * modification block with `node` (a replacement's del+ins pair). Mirrors
489
+ * the Python engine's _get_paired_nodes: comment range markers and
490
+ * rPr/pPr are transparent; a different author or any other element breaks
491
+ * the group.
492
+ */
493
+ private _get_paired_nodes;
494
+ /**
495
+ * All revision ids that resolve as ONE unit with `target_id`: the ids of
496
+ * every contiguous same-author w:ins/w:del sibling of its elements (a
497
+ * replacement's del+ins pair), plus the id itself.
498
+ */
499
+ private _resolution_group_ids;
500
+ /**
501
+ * Document-aware validation (QA 2026-07-19 ADEU-QA-004): a replacement's
502
+ * del+ins pair carries two distinct ids but resolves as one unit, so a
503
+ * batch that accepts one side and rejects the other is contradictory.
504
+ * Rejecting it up front — before any action mutates the document — keeps
505
+ * the batch transactional.
506
+ */
507
+ validate_action_pairing(actions: any[]): string[];
508
+ /**
509
+ * Returns [applied, skipped, already_resolved]. `applied` counts actions
510
+ * that caused an observable state transition; an action naming an id an
511
+ * earlier action of this batch already resolved (via its replacement pair)
512
+ * is counted in `already_resolved` instead — never as applied
513
+ * (QA 2026-07-19 ADEU-QA-004).
514
+ */
515
+ apply_review_actions(actions: any[]): [number, number, number];
455
516
  private _apply_table_edit;
456
517
  private _pre_resolve_heuristic_edit;
457
518
  /**