Skip to content

Commit 3c1352b

Browse files
committed
start of Mutation API on AACPage
1 parent bbd6155 commit 3c1352b

17 files changed

Lines changed: 550 additions & 0 deletions

src/core/baseProcessor.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import { StringCasing, detectCasing, isNumericOrEmpty } from './stringCasing';
4545
import { ValidationResult } from '../validation/validationTypes';
4646
import { BinaryOutput, defaultFileAdapter, FileAdapter, ProcessorInput } from '../utils/io';
4747
import { getZipAdapter, ZipAdapter } from '../utils/zip';
48+
import type { ProcessorCapabilities } from '../types/aac';
4849

4950
// Configuration options for processors
5051
export interface ProcessorConfig {
@@ -122,6 +123,7 @@ export interface SourceString {
122123

123124
abstract class BaseProcessor {
124125
protected options: ProcessorConfig;
126+
abstract readonly capabilities: ProcessorCapabilities;
125127

126128
constructor(options: ProcessorOptions = {}) {
127129
// Default configuration: exclude navigation/system buttons

src/core/treeStructure.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import type {
88
TouchChatMetadata,
99
CellScanningOrder,
1010
ScanningSelectionMethod,
11+
AACWordListItem,
12+
AACPageMutation,
13+
ProcessorCapabilities,
1114
} from '../types/aac';
1215

1316
// Re-export for consumers
@@ -20,6 +23,9 @@ export type {
2023
TouchChatMetadata,
2124
CellScanningOrder,
2225
ScanningSelectionMethod,
26+
AACWordListItem,
27+
AACPageMutation,
28+
ProcessorCapabilities,
2329
};
2430

2531
// Semantic action categories for cross-platform compatibility
@@ -414,6 +420,9 @@ export class AACPage {
414420
scanType?: AACScanType;
415421
scanBlocksConfig?: AACScanBlock[];
416422

423+
// Mutation tracking
424+
private _pendingMutations: AACPageMutation[] = [];
425+
417426
constructor({
418427
id,
419428
name = '',
@@ -474,6 +483,55 @@ export class AACPage {
474483

475484
addButton(button: AACButton): void {
476485
this.buttons.push(button);
486+
// Record the mutation
487+
this._pendingMutations.push({ type: 'addButton', button });
488+
}
489+
490+
/**
491+
* Get the list of pending mutations for this page (read-only)
492+
*/
493+
get pendingMutations(): readonly AACPageMutation[] {
494+
return Object.freeze([...this._pendingMutations]);
495+
}
496+
497+
/**
498+
* Remove a button by ID
499+
* @param buttonId - The ID of the button to remove
500+
*/
501+
removeButton(buttonId: string): void {
502+
this._pendingMutations.push({ type: 'removeButton', buttonId });
503+
}
504+
505+
/**
506+
* Update a button by merging a patch
507+
* @param buttonId - The ID of the button to update
508+
* @param patch - Partial button object with fields to update
509+
*/
510+
updateButton(buttonId: string, patch: Partial<AACButton>): void {
511+
this._pendingMutations.push({ type: 'updateButton', buttonId, patch });
512+
}
513+
514+
/**
515+
* Add an item to the page's WordList (for formats with dynamic content cells)
516+
* @param item - WordList item to add
517+
*/
518+
addWordListItem(item: AACWordListItem): void {
519+
this._pendingMutations.push({ type: 'addWordListItem', item });
520+
}
521+
522+
/**
523+
* Remove items from the page's WordList
524+
* @param textOrPredicate - Text to match or predicate function to filter items
525+
*/
526+
removeWordListItem(textOrPredicate: string | ((item: AACWordListItem) => boolean)): void {
527+
this._pendingMutations.push({ type: 'removeWordListItem', match: textOrPredicate });
528+
}
529+
530+
/**
531+
* Clear all items from the page's WordList
532+
*/
533+
clearWordList(): void {
534+
this._pendingMutations.push({ type: 'clearWordList' });
477535
}
478536
}
479537

src/processors/applePanelsProcessor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ function normalizeActionParameters(input: unknown): ApplePanelsActionParameters
169169
}
170170

171171
class ApplePanelsProcessor extends BaseProcessor {
172+
readonly capabilities = {
173+
wordList: 'none' as const,
174+
preservesAssetsOnSave: false,
175+
newCellCreation: 'allowed' as const,
176+
};
177+
172178
constructor(options?: ProcessorOptions) {
173179
super(options);
174180
}

src/processors/astericsGridProcessor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,12 @@ function mapAstericsVisibility(hidden: boolean | undefined): 'Hidden' | 'Visible
720720
}
721721

722722
class AstericsGridProcessor extends BaseProcessor {
723+
readonly capabilities = {
724+
wordList: 'none' as const,
725+
preservesAssetsOnSave: false,
726+
newCellCreation: 'allowed' as const,
727+
};
728+
723729
private loadAudio: boolean = false;
724730

725731
constructor(options: ProcessorOptions & { loadAudio?: boolean } = {}) {

src/processors/dotProcessor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ interface DotEdge {
2424
}
2525

2626
class DotProcessor extends BaseProcessor {
27+
readonly capabilities = {
28+
wordList: 'none' as const,
29+
preservesAssetsOnSave: false,
30+
newCellCreation: 'allowed' as const,
31+
};
32+
2733
constructor(options?: ProcessorOptions) {
2834
super(options);
2935
}

src/processors/excelProcessor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ import { AACStyle } from '../types/aac';
1515
* Supports visual styling, navigation links, and vocabulary analysis workflows
1616
*/
1717
export class ExcelProcessor extends BaseProcessor {
18+
readonly capabilities = {
19+
wordList: 'none' as const,
20+
preservesAssetsOnSave: false,
21+
newCellCreation: 'allowed' as const,
22+
};
23+
1824
private static readonly NAVIGATION_BUTTONS = ['Home', 'Message Bar', 'Delete', 'Back', 'Clear'];
1925

2026
/**

src/processors/gridsetProcessor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ import { ProcessorInput, decodeText } from '../utils/io';
4848
import { ZipFile } from '../utils/zip';
4949

5050
class GridsetProcessor extends BaseProcessor {
51+
readonly capabilities = {
52+
wordList: 'native' as const,
53+
preservesAssetsOnSave: true,
54+
newCellCreation: 'restricted' as const,
55+
};
56+
5157
constructor(options?: ProcessorOptions) {
5258
super(options);
5359
}

src/processors/obfProcessor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ interface ObfBoard {
102102
}
103103

104104
class ObfProcessor extends BaseProcessor {
105+
readonly capabilities = {
106+
wordList: 'none' as const,
107+
preservesAssetsOnSave: true,
108+
newCellCreation: 'allowed' as const,
109+
};
110+
105111
private zipFile?: ZipAdapter;
106112
private imageCache: Map<string, string> = new Map(); // Cache for data URLs
107113

src/processors/obfsetProcessor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ interface ObfsetBoard {
3737
}
3838

3939
export class ObfsetProcessor extends BaseProcessor {
40+
readonly capabilities = {
41+
wordList: 'none' as const,
42+
preservesAssetsOnSave: false,
43+
newCellCreation: 'allowed' as const,
44+
};
45+
4046
constructor(options: ProcessorOptions = {}) {
4147
super(options);
4248
}

src/processors/opmlProcessor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ interface OpmlDocument {
3232
}
3333

3434
class OpmlProcessor extends BaseProcessor {
35+
readonly capabilities = {
36+
wordList: 'none' as const,
37+
preservesAssetsOnSave: false,
38+
newCellCreation: 'allowed' as const,
39+
};
40+
3541
constructor(options?: ProcessorOptions) {
3642
super(options);
3743
}

0 commit comments

Comments
 (0)