@willwade/aac-processors 0.1.20 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/browser/core/baseProcessor.js +4 -0
  2. package/dist/browser/processors/applePanelsProcessor.js +33 -40
  3. package/dist/browser/processors/astericsGridProcessor.js +31 -26
  4. package/dist/browser/processors/dotProcessor.js +11 -12
  5. package/dist/browser/processors/gridset/colorUtils.js +354 -0
  6. package/dist/browser/processors/gridset/helpers.js +60 -53
  7. package/dist/browser/processors/gridset/index.js +61 -0
  8. package/dist/browser/processors/gridset/styleHelpers.js +205 -0
  9. package/dist/browser/processors/gridset/symbolExtractor.js +331 -0
  10. package/dist/browser/processors/gridset/symbolSearch.js +248 -0
  11. package/dist/browser/processors/gridset/symbols.js +39 -72
  12. package/dist/browser/processors/gridsetProcessor.js +39 -48
  13. package/dist/browser/processors/obfProcessor.js +39 -53
  14. package/dist/browser/processors/opmlProcessor.js +11 -12
  15. package/dist/browser/processors/snap/helpers.js +57 -49
  16. package/dist/browser/processors/snapProcessor.js +48 -51
  17. package/dist/browser/processors/touchchatProcessor.js +60 -52
  18. package/dist/browser/utilities/analytics/history.js +24 -18
  19. package/dist/browser/utilities/analytics/metrics/comparison.js +16 -16
  20. package/dist/browser/utilities/analytics/metrics/vocabulary.js +2 -2
  21. package/dist/browser/utilities/analytics/reference/browser.js +16 -16
  22. package/dist/browser/utilities/analytics/reference/index.js +44 -35
  23. package/dist/browser/utils/io.js +78 -21
  24. package/dist/browser/utils/sqlite.js +8 -10
  25. package/dist/browser/utils/zip.js +43 -43
  26. package/dist/browser/validation/baseValidator.js +5 -0
  27. package/dist/browser/validation/gridsetValidator.js +12 -20
  28. package/dist/browser/validation/obfValidator.js +6 -5
  29. package/dist/browser/validation/snapValidator.js +11 -7
  30. package/dist/browser/validation/touchChatValidator.js +23 -13
  31. package/dist/cli/index.js +22 -24
  32. package/dist/core/baseProcessor.d.ts +7 -7
  33. package/dist/core/baseProcessor.js +4 -0
  34. package/dist/processors/applePanelsProcessor.js +32 -39
  35. package/dist/processors/astericsGridProcessor.d.ts +4 -4
  36. package/dist/processors/astericsGridProcessor.js +30 -25
  37. package/dist/processors/dotProcessor.js +10 -11
  38. package/dist/processors/excelProcessor.d.ts +3 -3
  39. package/dist/processors/excelProcessor.js +14 -20
  40. package/dist/processors/gridset/helpers.d.ts +12 -14
  41. package/dist/processors/gridset/helpers.js +60 -79
  42. package/dist/processors/gridset/imageDebug.d.ts +3 -5
  43. package/dist/processors/gridset/imageDebug.js +4 -4
  44. package/dist/processors/gridset/password.d.ts +1 -1
  45. package/dist/processors/gridset/symbolExtractor.d.ts +5 -3
  46. package/dist/processors/gridset/symbolExtractor.js +15 -38
  47. package/dist/processors/gridset/symbolSearch.d.ts +11 -10
  48. package/dist/processors/gridset/symbolSearch.js +29 -51
  49. package/dist/processors/gridset/symbols.d.ts +8 -6
  50. package/dist/processors/gridset/symbols.js +38 -71
  51. package/dist/processors/gridset/wordlistHelpers.d.ts +4 -6
  52. package/dist/processors/gridset/wordlistHelpers.js +15 -74
  53. package/dist/processors/gridsetProcessor.d.ts +2 -2
  54. package/dist/processors/gridsetProcessor.js +38 -70
  55. package/dist/processors/obfProcessor.d.ts +2 -2
  56. package/dist/processors/obfProcessor.js +38 -75
  57. package/dist/processors/obfsetProcessor.js +2 -3
  58. package/dist/processors/opmlProcessor.js +10 -11
  59. package/dist/processors/snap/helpers.d.ts +9 -9
  60. package/dist/processors/snap/helpers.js +58 -76
  61. package/dist/processors/snapProcessor.d.ts +2 -2
  62. package/dist/processors/snapProcessor.js +47 -50
  63. package/dist/processors/touchchatProcessor.d.ts +2 -2
  64. package/dist/processors/touchchatProcessor.js +59 -51
  65. package/dist/types/aac.d.ts +2 -2
  66. package/dist/utilities/analytics/history.d.ts +8 -8
  67. package/dist/utilities/analytics/history.js +24 -18
  68. package/dist/utilities/analytics/index.d.ts +3 -2
  69. package/dist/utilities/analytics/index.js +9 -10
  70. package/dist/utilities/analytics/metrics/comparison.d.ts +1 -1
  71. package/dist/utilities/analytics/metrics/comparison.js +16 -16
  72. package/dist/utilities/analytics/metrics/vocabulary.d.ts +1 -1
  73. package/dist/utilities/analytics/metrics/vocabulary.js +2 -2
  74. package/dist/utilities/analytics/reference/browser.d.ts +9 -9
  75. package/dist/utilities/analytics/reference/browser.js +16 -16
  76. package/dist/utilities/analytics/reference/index.d.ts +25 -23
  77. package/dist/utilities/analytics/reference/index.js +43 -34
  78. package/dist/utilities/symbolTools.d.ts +8 -6
  79. package/dist/utilities/symbolTools.js +21 -18
  80. package/dist/utils/io.d.ts +24 -6
  81. package/dist/utils/io.js +79 -25
  82. package/dist/utils/sqlite.d.ts +3 -1
  83. package/dist/utils/sqlite.js +7 -9
  84. package/dist/utils/zip.d.ts +7 -3
  85. package/dist/utils/zip.js +43 -43
  86. package/dist/validation/applePanelsValidator.d.ts +2 -1
  87. package/dist/validation/applePanelsValidator.js +10 -11
  88. package/dist/validation/astericsValidator.d.ts +2 -1
  89. package/dist/validation/astericsValidator.js +5 -4
  90. package/dist/validation/baseValidator.d.ts +2 -2
  91. package/dist/validation/baseValidator.js +5 -0
  92. package/dist/validation/dotValidator.d.ts +2 -1
  93. package/dist/validation/dotValidator.js +5 -4
  94. package/dist/validation/excelValidator.d.ts +2 -1
  95. package/dist/validation/excelValidator.js +5 -4
  96. package/dist/validation/gridsetValidator.d.ts +2 -1
  97. package/dist/validation/gridsetValidator.js +11 -22
  98. package/dist/validation/index.d.ts +2 -2
  99. package/dist/validation/index.js +5 -4
  100. package/dist/validation/obfValidator.d.ts +2 -1
  101. package/dist/validation/obfValidator.js +5 -4
  102. package/dist/validation/obfsetValidator.d.ts +2 -1
  103. package/dist/validation/obfsetValidator.js +5 -4
  104. package/dist/validation/opmlValidator.d.ts +2 -1
  105. package/dist/validation/opmlValidator.js +5 -4
  106. package/dist/validation/snapValidator.d.ts +2 -1
  107. package/dist/validation/snapValidator.js +10 -6
  108. package/dist/validation/touchChatValidator.d.ts +4 -6
  109. package/dist/validation/touchChatValidator.js +22 -12
  110. package/dist/validation/validationTypes.d.ts +8 -1
  111. package/package.json +1 -1
  112. package/dist/core/fileProcessor.d.ts +0 -7
  113. package/dist/core/fileProcessor.js +0 -57
@@ -41,6 +41,8 @@
41
41
  */
42
42
  import { AACSemanticCategory } from './treeStructure';
43
43
  import { detectCasing, isNumericOrEmpty } from './stringCasing';
44
+ import { defaultFileAdapter } from '../utils/io';
45
+ import { getZipAdapter } from '../utils/zip';
44
46
  class BaseProcessor {
45
47
  constructor(options = {}) {
46
48
  // Default configuration: exclude navigation/system buttons
@@ -48,6 +50,8 @@ class BaseProcessor {
48
50
  excludeNavigationButtons: true,
49
51
  excludeSystemButtons: true,
50
52
  preserveAllButtons: false,
53
+ fileAdapter: defaultFileAdapter,
54
+ zipAdapter: getZipAdapter,
51
55
  ...options,
52
56
  };
53
57
  }
@@ -1,9 +1,8 @@
1
1
  import { BaseProcessor, } from '../core/baseProcessor';
2
2
  import { AACTree, AACPage, AACButton, AACSemanticCategory, AACSemanticIntent, } from '../core/treeStructure';
3
- // Removed unused import: FileProcessor
4
3
  import plist from 'plist';
5
4
  import { ValidationFailureError, buildValidationResultFromMessage, } from '../validation/validationTypes';
6
- import { getBasename, getFs, getPath, readBinaryFromInput, readTextFromInput, writeTextToPath, } from '../utils/io';
5
+ import { getBasename } from '../utils/io';
7
6
  function isNormalizedPanel(panel) {
8
7
  return typeof panel.id === 'string';
9
8
  }
@@ -86,17 +85,15 @@ class ApplePanelsProcessor extends BaseProcessor {
86
85
  return texts;
87
86
  }
88
87
  async loadIntoTree(filePathOrBuffer) {
89
- await Promise.resolve();
88
+ const { readBinaryFromInput, readTextFromInput, pathExists, getFileSize, join } = this.options.fileAdapter;
90
89
  const filename = typeof filePathOrBuffer === 'string' ? getBasename(filePathOrBuffer) : 'upload.plist';
91
90
  let buffer;
92
91
  try {
93
92
  if (typeof filePathOrBuffer === 'string') {
94
- const fs = getFs();
95
- const path = getPath();
96
93
  if (filePathOrBuffer.endsWith('.ascconfig')) {
97
- const panelDefsPath = path.join(filePathOrBuffer, 'Contents', 'Resources', 'PanelDefinitions.plist');
98
- if (fs.existsSync(panelDefsPath)) {
99
- buffer = fs.readFileSync(panelDefsPath);
94
+ const panelDefsPath = join(filePathOrBuffer, 'Contents', 'Resources', 'PanelDefinitions.plist');
95
+ if (await pathExists(panelDefsPath)) {
96
+ buffer = await readBinaryFromInput(panelDefsPath);
100
97
  }
101
98
  else {
102
99
  const validation = buildValidationResultFromMessage({
@@ -111,13 +108,13 @@ class ApplePanelsProcessor extends BaseProcessor {
111
108
  }
112
109
  }
113
110
  else {
114
- buffer = fs.readFileSync(filePathOrBuffer);
111
+ buffer = await readBinaryFromInput(filePathOrBuffer);
115
112
  }
116
113
  }
117
114
  else {
118
- buffer = readBinaryFromInput(filePathOrBuffer);
115
+ buffer = await readBinaryFromInput(filePathOrBuffer);
119
116
  }
120
- const content = readTextFromInput(buffer);
117
+ const content = await readTextFromInput(buffer);
121
118
  const parsedData = plist.parse(content);
122
119
  let panelsData = [];
123
120
  if (Array.isArray(parsedData.panels)) {
@@ -246,11 +243,12 @@ class ApplePanelsProcessor extends BaseProcessor {
246
243
  const validation = buildValidationResultFromMessage({
247
244
  filename,
248
245
  filesize: typeof filePathOrBuffer === 'string'
249
- ? (() => {
250
- const fs = getFs();
251
- return fs.existsSync(filePathOrBuffer) ? fs.statSync(filePathOrBuffer).size : 0;
246
+ ? await (async () => {
247
+ return (await pathExists(filePathOrBuffer))
248
+ ? await getFileSize(filePathOrBuffer)
249
+ : 0;
252
250
  })()
253
- : readBinaryFromInput(filePathOrBuffer).byteLength,
251
+ : (await readBinaryFromInput(filePathOrBuffer)).byteLength,
254
252
  format: 'applepanels',
255
253
  message: err?.message || 'Failed to parse Apple Panels file',
256
254
  type: 'parse',
@@ -260,6 +258,7 @@ class ApplePanelsProcessor extends BaseProcessor {
260
258
  }
261
259
  }
262
260
  async processTexts(filePathOrBuffer, translations, outputPath) {
261
+ const { readBinaryFromInput, join } = this.options.fileAdapter;
263
262
  // Load the tree, apply translations, and save to new file
264
263
  const tree = await this.loadIntoTree(filePathOrBuffer);
265
264
  // Apply translations to all text content
@@ -309,15 +308,14 @@ class ApplePanelsProcessor extends BaseProcessor {
309
308
  // Save the translated tree to the requested location and return its content
310
309
  await this.saveFromTree(tree, outputPath);
311
310
  if (outputPath.endsWith('.plist')) {
312
- return readBinaryFromInput(outputPath);
311
+ return await readBinaryFromInput(outputPath);
313
312
  }
314
- const path = getPath();
315
313
  const configPath = outputPath.endsWith('.ascconfig') ? outputPath : `${outputPath}.ascconfig`;
316
- const panelDefsPath = path.join(configPath, 'Contents', 'Resources', 'PanelDefinitions.plist');
317
- return readBinaryFromInput(panelDefsPath);
314
+ const panelDefsPath = join(configPath, 'Contents', 'Resources', 'PanelDefinitions.plist');
315
+ return await readBinaryFromInput(panelDefsPath);
318
316
  }
319
317
  async saveFromTree(tree, outputPath) {
320
- await Promise.resolve();
318
+ const { writeTextToPath, pathExists, mkDir, join, dirname } = this.options.fileAdapter;
321
319
  // Support two output modes:
322
320
  // 1) Single-file .plist (PanelDefinitions.plist content written directly)
323
321
  // 2) Apple Panels bundle folder (*.ascconfig) with Contents/Resources structure
@@ -327,17 +325,15 @@ class ApplePanelsProcessor extends BaseProcessor {
327
325
  let contentsPath = '';
328
326
  let resourcesPath = '';
329
327
  if (!isSinglePlist) {
330
- const fs = getFs();
331
- const path = getPath();
332
328
  configPath = outputPath.endsWith('.ascconfig') ? outputPath : `${outputPath}.ascconfig`;
333
- contentsPath = path.join(configPath, 'Contents');
334
- resourcesPath = path.join(contentsPath, 'Resources');
335
- if (!fs.existsSync(configPath))
336
- fs.mkdirSync(configPath, { recursive: true });
337
- if (!fs.existsSync(contentsPath))
338
- fs.mkdirSync(contentsPath, { recursive: true });
339
- if (!fs.existsSync(resourcesPath))
340
- fs.mkdirSync(resourcesPath, { recursive: true });
329
+ contentsPath = join(configPath, 'Contents');
330
+ resourcesPath = join(contentsPath, 'Resources');
331
+ if (!(await pathExists(configPath)))
332
+ await mkDir(configPath, { recursive: true });
333
+ if (!(await pathExists(contentsPath)))
334
+ await mkDir(contentsPath, { recursive: true });
335
+ if (!(await pathExists(resourcesPath)))
336
+ await mkDir(resourcesPath, { recursive: true });
341
337
  // Create Info.plist (bundle mode only)
342
338
  const infoPlist = {
343
339
  ASCConfigurationDisplayName: tree.metadata?.name || 'AAC Processors Export',
@@ -353,10 +349,10 @@ class ApplePanelsProcessor extends BaseProcessor {
353
349
  `Generated by AAC Processors${tree.metadata?.author ? ` - Author: ${tree.metadata.author}` : ''}`,
354
350
  };
355
351
  const infoPlistContent = plist.build(infoPlist);
356
- writeTextToPath(path.join(contentsPath, 'Info.plist'), infoPlistContent);
352
+ await writeTextToPath(join(contentsPath, 'Info.plist'), infoPlistContent);
357
353
  // Create AssetIndex.plist (empty)
358
354
  const assetIndexContent = plist.build({});
359
- writeTextToPath(path.join(resourcesPath, 'AssetIndex.plist'), assetIndexContent);
355
+ await writeTextToPath(join(resourcesPath, 'AssetIndex.plist'), assetIndexContent);
360
356
  }
361
357
  // Build PanelDefinitions content from tree
362
358
  const panelsDict = {};
@@ -482,17 +478,14 @@ class ApplePanelsProcessor extends BaseProcessor {
482
478
  const panelDefsContent = plist.build(panelDefinitions);
483
479
  if (isSinglePlist) {
484
480
  // Write single PanelDefinitions.plist file directly
485
- const fs = getFs();
486
- const path = getPath();
487
- const dir = path.dirname(outputPath);
488
- if (!fs.existsSync(dir))
489
- fs.mkdirSync(dir, { recursive: true });
490
- writeTextToPath(outputPath, panelDefsContent);
481
+ const dir = dirname(outputPath);
482
+ if (!(await pathExists(dir)))
483
+ await mkDir(dir, { recursive: true });
484
+ await writeTextToPath(outputPath, panelDefsContent);
491
485
  }
492
486
  else {
493
487
  // Write into bundle structure
494
- const path = getPath();
495
- writeTextToPath(path.join(resourcesPath, 'PanelDefinitions.plist'), panelDefsContent);
488
+ await writeTextToPath(join(resourcesPath, 'PanelDefinitions.plist'), panelDefsContent);
496
489
  }
497
490
  }
498
491
  createApplePanelsAction(button) {
@@ -1,7 +1,7 @@
1
1
  import { BaseProcessor, } from '../core/baseProcessor';
2
2
  import { AACTree, AACPage, AACButton, AACSemanticCategory, AACSemanticIntent, } from '../core/treeStructure';
3
3
  import { ValidationFailureError, buildValidationResultFromMessage, } from '../validation/validationTypes';
4
- import { getBasename, getFs, readBinaryFromInput, readTextFromInput, writeTextToPath, encodeBase64, } from '../utils/io';
4
+ import { getBasename, encodeBase64 } from '../utils/io';
5
5
  const DEFAULT_COLOR_SCHEME_DEFINITIONS = [
6
6
  {
7
7
  name: 'CS_MODIFIED_FITZGERALD_KEY_VERY_LIGHT',
@@ -562,7 +562,7 @@ class AstericsGridProcessor extends BaseProcessor {
562
562
  });
563
563
  }
564
564
  // Also extract texts from the raw file for comprehensive coverage
565
- const rawTexts = this.extractRawTexts(filePathOrBuffer);
565
+ const rawTexts = await this.extractRawTexts(filePathOrBuffer);
566
566
  rawTexts.forEach((text) => {
567
567
  if (text && !texts.includes(text)) {
568
568
  texts.push(text);
@@ -570,8 +570,9 @@ class AstericsGridProcessor extends BaseProcessor {
570
570
  });
571
571
  return texts;
572
572
  }
573
- extractRawTexts(filePathOrBuffer) {
574
- let content = readTextFromInput(filePathOrBuffer);
573
+ async extractRawTexts(filePathOrBuffer) {
574
+ const { readTextFromInput } = this.options.fileAdapter;
575
+ let content = await readTextFromInput(filePathOrBuffer);
575
576
  // Remove BOM if present
576
577
  if (content.charCodeAt(0) === 0xfeff) {
577
578
  content = content.slice(1);
@@ -651,12 +652,12 @@ class AstericsGridProcessor extends BaseProcessor {
651
652
  }
652
653
  }
653
654
  async loadIntoTree(filePathOrBuffer) {
654
- await Promise.resolve();
655
+ const { readBinaryFromInput, readTextFromInput } = this.options.fileAdapter;
655
656
  const tree = new AACTree();
656
657
  const filename = typeof filePathOrBuffer === 'string' ? getBasename(filePathOrBuffer) : 'upload.grd';
657
- const buffer = readBinaryFromInput(filePathOrBuffer);
658
+ const buffer = await readBinaryFromInput(filePathOrBuffer);
658
659
  try {
659
- let content = readTextFromInput(buffer);
660
+ let content = await readTextFromInput(buffer);
660
661
  // Remove BOM if present
661
662
  if (content.charCodeAt(0) === 0xfeff) {
662
663
  content = content.slice(1);
@@ -1049,8 +1050,8 @@ class AstericsGridProcessor extends BaseProcessor {
1049
1050
  });
1050
1051
  }
1051
1052
  async processTexts(filePathOrBuffer, translations, outputPath) {
1052
- await Promise.resolve();
1053
- let content = readTextFromInput(filePathOrBuffer);
1053
+ const { readTextFromInput, readBinaryFromInput, writeTextToPath } = this.options.fileAdapter;
1054
+ let content = await readTextFromInput(filePathOrBuffer);
1054
1055
  // Remove BOM if present
1055
1056
  if (content.charCodeAt(0) === 0xfeff) {
1056
1057
  content = content.slice(1);
@@ -1059,8 +1060,8 @@ class AstericsGridProcessor extends BaseProcessor {
1059
1060
  // Apply translations directly to the JSON structure for comprehensive coverage
1060
1061
  this.applyTranslationsToGridFile(grdFile, translations);
1061
1062
  // Write the translated file
1062
- writeTextToPath(outputPath, JSON.stringify(grdFile, null, 2));
1063
- return readBinaryFromInput(outputPath);
1063
+ await writeTextToPath(outputPath, JSON.stringify(grdFile, null, 2));
1064
+ return await readBinaryFromInput(outputPath);
1064
1065
  }
1065
1066
  applyTranslationsToGridFile(grdFile, translations) {
1066
1067
  grdFile.grids.forEach((grid) => {
@@ -1172,7 +1173,7 @@ class AstericsGridProcessor extends BaseProcessor {
1172
1173
  }
1173
1174
  }
1174
1175
  async saveFromTree(tree, outputPath) {
1175
- await Promise.resolve();
1176
+ const { writeTextToPath } = this.options.fileAdapter;
1176
1177
  // Use default Asterics Grid styling instead of taking from first page
1177
1178
  // This prevents issues where the first page has unusual colors (like purple)
1178
1179
  const defaultPageStyle = {
@@ -1375,13 +1376,14 @@ class AstericsGridProcessor extends BaseProcessor {
1375
1376
  },
1376
1377
  },
1377
1378
  };
1378
- writeTextToPath(outputPath, JSON.stringify(grdFile, null, 2));
1379
+ await writeTextToPath(outputPath, JSON.stringify(grdFile, null, 2));
1379
1380
  }
1380
1381
  /**
1381
1382
  * Add audio recording to a specific grid element
1382
1383
  */
1383
- addAudioToElement(filePath, elementId, audioData, metadata) {
1384
- let content = readTextFromInput(filePath);
1384
+ async addAudioToElement(filePath, elementId, audioData, metadata) {
1385
+ const { readTextFromInput, writeTextToPath } = this.options.fileAdapter;
1386
+ let content = await readTextFromInput(filePath);
1385
1387
  // Remove BOM if present
1386
1388
  if (content.charCodeAt(0) === 0xfeff) {
1387
1389
  content = content.slice(1);
@@ -1424,31 +1426,33 @@ class AstericsGridProcessor extends BaseProcessor {
1424
1426
  throw new Error(`Element with ID ${elementId} not found`);
1425
1427
  }
1426
1428
  // Write back to file
1427
- writeTextToPath(filePath, JSON.stringify(grdFile, null, 2));
1429
+ await writeTextToPath(filePath, JSON.stringify(grdFile, null, 2));
1428
1430
  }
1429
1431
  /**
1430
1432
  * Create a copy of the grid file with audio recordings added
1431
1433
  */
1432
- createAudioEnhancedGridFile(sourceFilePath, targetFilePath, audioMappings) {
1434
+ async createAudioEnhancedGridFile(sourceFilePath, targetFilePath, audioMappings) {
1435
+ const { writeBinaryToPath, readBinaryFromInput } = this.options.fileAdapter;
1433
1436
  // Copy the source file to target
1434
- const fs = getFs();
1435
- fs.copyFileSync(sourceFilePath, targetFilePath);
1437
+ await writeBinaryToPath(targetFilePath, await readBinaryFromInput(sourceFilePath));
1436
1438
  // Add audio recordings to the copy
1437
- audioMappings.forEach((audioInfo, elementId) => {
1439
+ await Promise.all(Object.entries(audioMappings).map(async (item) => {
1440
+ const [elementId, audioInfo] = item;
1438
1441
  try {
1439
- this.addAudioToElement(targetFilePath, elementId, audioInfo.audioData, audioInfo.metadata);
1442
+ await this.addAudioToElement(targetFilePath, elementId, audioInfo.audioData, audioInfo.metadata);
1440
1443
  }
1441
1444
  catch (error) {
1442
1445
  // Failed to add audio to element - continue with others
1443
1446
  console.warn(`Failed to add audio to element ${elementId}:`, error);
1444
1447
  }
1445
- });
1448
+ }));
1446
1449
  }
1447
1450
  /**
1448
1451
  * Extract all element IDs from the grid file for audio mapping
1449
1452
  */
1450
- getElementIds(filePathOrBuffer) {
1451
- let content = readTextFromInput(filePathOrBuffer);
1453
+ async getElementIds(filePathOrBuffer) {
1454
+ const { readTextFromInput } = this.options.fileAdapter;
1455
+ let content = await readTextFromInput(filePathOrBuffer);
1452
1456
  // Remove BOM if present
1453
1457
  if (content.charCodeAt(0) === 0xfeff) {
1454
1458
  content = content.slice(1);
@@ -1470,8 +1474,9 @@ class AstericsGridProcessor extends BaseProcessor {
1470
1474
  /**
1471
1475
  * Check if an element has audio recording
1472
1476
  */
1473
- hasAudioRecording(filePathOrBuffer, elementId) {
1474
- let content = readTextFromInput(filePathOrBuffer);
1477
+ async hasAudioRecording(filePathOrBuffer, elementId) {
1478
+ const { readTextFromInput } = this.options.fileAdapter;
1479
+ let content = await readTextFromInput(filePathOrBuffer);
1475
1480
  // Remove BOM if present
1476
1481
  if (content.charCodeAt(0) === 0xfeff) {
1477
1482
  content = content.slice(1);
@@ -1,8 +1,7 @@
1
1
  import { BaseProcessor, } from '../core/baseProcessor';
2
2
  import { AACTree, AACPage, AACButton, AACSemanticIntent } from '../core/treeStructure';
3
- // Removed unused import: FileProcessor
4
3
  import { ValidationFailureError, buildValidationResultFromMessage, } from '../validation/validationTypes';
5
- import { getBasename, readBinaryFromInput, readTextFromInput, writeBinaryToPath, writeTextToPath, encodeText, } from '../utils/io';
4
+ import { getBasename, encodeText } from '../utils/io';
6
5
  class DotProcessor extends BaseProcessor {
7
6
  constructor(options) {
8
7
  super(options);
@@ -49,8 +48,8 @@ class DotProcessor extends BaseProcessor {
49
48
  return { nodes: Array.from(nodes.values()), edges };
50
49
  }
51
50
  async extractTexts(filePathOrBuffer) {
52
- await Promise.resolve();
53
- const content = readTextFromInput(filePathOrBuffer);
51
+ const { readTextFromInput } = this.options.fileAdapter;
52
+ const content = await readTextFromInput(filePathOrBuffer);
54
53
  const { nodes, edges } = this.parseDotFile(content);
55
54
  const texts = [];
56
55
  // Collect node labels
@@ -66,12 +65,12 @@ class DotProcessor extends BaseProcessor {
66
65
  return texts;
67
66
  }
68
67
  async loadIntoTree(filePathOrBuffer) {
69
- await Promise.resolve();
68
+ const { readBinaryFromInput, readTextFromInput } = this.options.fileAdapter;
70
69
  const filename = typeof filePathOrBuffer === 'string' ? getBasename(filePathOrBuffer) : 'upload.dot';
71
- const buffer = readBinaryFromInput(filePathOrBuffer);
70
+ const buffer = await readBinaryFromInput(filePathOrBuffer);
72
71
  const filesize = buffer.byteLength;
73
72
  try {
74
- const content = readTextFromInput(buffer);
73
+ const content = await readTextFromInput(buffer);
75
74
  if (!content || content.trim().length === 0) {
76
75
  const validation = buildValidationResultFromMessage({
77
76
  filename,
@@ -155,8 +154,8 @@ class DotProcessor extends BaseProcessor {
155
154
  }
156
155
  }
157
156
  async processTexts(filePathOrBuffer, translations, outputPath) {
158
- await Promise.resolve();
159
- const content = readTextFromInput(filePathOrBuffer);
157
+ const { readTextFromInput, writeBinaryToPath } = this.options.fileAdapter;
158
+ const content = await readTextFromInput(filePathOrBuffer);
160
159
  let translatedContent = content;
161
160
  translations.forEach((translation, text) => {
162
161
  if (typeof text === 'string' && typeof translation === 'string') {
@@ -167,11 +166,11 @@ class DotProcessor extends BaseProcessor {
167
166
  }
168
167
  });
169
168
  const resultBuffer = encodeText(translatedContent || '');
170
- writeBinaryToPath(outputPath, resultBuffer);
169
+ await writeBinaryToPath(outputPath, resultBuffer);
171
170
  return resultBuffer;
172
171
  }
173
172
  async saveFromTree(tree, _outputPath) {
174
- await Promise.resolve();
173
+ const { writeTextToPath } = this.options.fileAdapter;
175
174
  let dotContent = `digraph "${tree.metadata?.name || 'AACBoard'}" {\n`;
176
175
  // Helper to escape DOT string
177
176
  const escapeDotString = (str) => {
@@ -201,7 +200,7 @@ class DotProcessor extends BaseProcessor {
201
200
  });
202
201
  }
203
202
  dotContent += '}\n';
204
- writeTextToPath(_outputPath, dotContent);
203
+ await writeTextToPath(_outputPath, dotContent);
205
204
  }
206
205
  /**
207
206
  * Extract strings with metadata for aac-tools-platform compatibility