@willwade/aac-processors 0.1.6 → 0.1.8

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 (54) hide show
  1. package/dist/analytics.d.ts +7 -0
  2. package/dist/analytics.js +23 -0
  3. package/dist/browser/index.browser.js +5 -0
  4. package/dist/browser/metrics.js +17 -0
  5. package/dist/browser/processors/gridset/helpers.js +390 -0
  6. package/dist/browser/processors/snap/helpers.js +252 -0
  7. package/dist/browser/utilities/analytics/history.js +116 -0
  8. package/dist/browser/utilities/analytics/metrics/comparison.js +477 -0
  9. package/dist/browser/utilities/analytics/metrics/core.js +775 -0
  10. package/dist/browser/utilities/analytics/metrics/effort.js +221 -0
  11. package/dist/browser/utilities/analytics/metrics/obl-types.js +6 -0
  12. package/dist/browser/utilities/analytics/metrics/obl.js +282 -0
  13. package/dist/browser/utilities/analytics/metrics/sentence.js +121 -0
  14. package/dist/browser/utilities/analytics/metrics/types.js +6 -0
  15. package/dist/browser/utilities/analytics/metrics/vocabulary.js +138 -0
  16. package/dist/browser/utilities/analytics/reference/browser.js +67 -0
  17. package/dist/browser/utilities/analytics/reference/index.js +129 -0
  18. package/dist/browser/utils/dotnetTicks.js +17 -0
  19. package/dist/browser/utils/io.js +16 -2
  20. package/dist/browser/validation/gridsetValidator.js +7 -27
  21. package/dist/browser/validation/obfValidator.js +9 -4
  22. package/dist/browser/validation/snapValidator.js +6 -9
  23. package/dist/browser/validation/touchChatValidator.js +6 -7
  24. package/dist/index.browser.d.ts +1 -0
  25. package/dist/index.browser.js +18 -1
  26. package/dist/index.node.d.ts +2 -2
  27. package/dist/index.node.js +5 -5
  28. package/dist/metrics.d.ts +17 -0
  29. package/dist/metrics.js +44 -0
  30. package/dist/utilities/analytics/metrics/comparison.d.ts +2 -1
  31. package/dist/utilities/analytics/metrics/comparison.js +3 -3
  32. package/dist/utilities/analytics/metrics/vocabulary.d.ts +2 -2
  33. package/dist/utilities/analytics/reference/browser.d.ts +31 -0
  34. package/dist/utilities/analytics/reference/browser.js +73 -0
  35. package/dist/utilities/analytics/reference/index.d.ts +21 -0
  36. package/dist/utilities/analytics/reference/index.js +22 -46
  37. package/dist/utils/io.d.ts +2 -0
  38. package/dist/utils/io.js +18 -2
  39. package/dist/validation/applePanelsValidator.js +11 -28
  40. package/dist/validation/astericsValidator.js +11 -30
  41. package/dist/validation/dotValidator.js +11 -30
  42. package/dist/validation/excelValidator.js +5 -6
  43. package/dist/validation/gridsetValidator.js +29 -26
  44. package/dist/validation/index.d.ts +2 -1
  45. package/dist/validation/index.js +9 -32
  46. package/dist/validation/obfValidator.js +8 -3
  47. package/dist/validation/obfsetValidator.js +11 -30
  48. package/dist/validation/opmlValidator.js +11 -30
  49. package/dist/validation/snapValidator.js +6 -9
  50. package/dist/validation/touchChatValidator.js +6 -7
  51. package/examples/vitedemo/index.html +49 -0
  52. package/examples/vitedemo/src/main.ts +84 -0
  53. package/examples/vitedemo/vite.config.ts +26 -7
  54. package/package.json +9 -1
@@ -81,6 +81,7 @@ import {
81
81
  AACPage,
82
82
  AACButton
83
83
  } from 'aac-processors';
84
+ import { validateFileOrBuffer, type ValidationResult } from 'aac-processors/validation';
84
85
 
85
86
  import sqlWasmUrl from 'sql.js/dist/sql-wasm.wasm?url';
86
87
 
@@ -92,6 +93,7 @@ configureSqlJs({
92
93
  const dropArea = document.getElementById('dropArea') as HTMLElement;
93
94
  const fileInput = document.getElementById('fileInput') as HTMLInputElement;
94
95
  const processBtn = document.getElementById('processBtn') as HTMLButtonElement;
96
+ const validateBtn = document.getElementById('validateBtn') as HTMLButtonElement;
95
97
  const runTestsBtn = document.getElementById('runTestsBtn') as HTMLButtonElement;
96
98
  const clearBtn = document.getElementById('clearBtn') as HTMLButtonElement;
97
99
  const fileInfo = document.getElementById('fileInfo') as HTMLElement;
@@ -102,6 +104,9 @@ const results = document.getElementById('results') as HTMLElement;
102
104
  const logPanel = document.getElementById('logPanel') as HTMLElement;
103
105
  const testResults = document.getElementById('testResults') as HTMLElement;
104
106
  const testList = document.getElementById('testList') as HTMLElement;
107
+ const validationPanel = document.getElementById('validationPanel') as HTMLElement;
108
+ const validationSummary = document.getElementById('validationSummary') as HTMLElement;
109
+ const validationList = document.getElementById('validationList') as HTMLElement;
105
110
  const tabButtons = document.querySelectorAll('.tab-btn') as NodeListOf<HTMLButtonElement>;
106
111
  const inspectTab = document.getElementById('inspectTab') as HTMLElement;
107
112
  const pagesetTab = document.getElementById('pagesetTab') as HTMLElement;
@@ -218,6 +223,7 @@ function handleFile(file: File) {
218
223
  fileDetails.textContent = extension;
219
224
  fileInfo.style.display = 'block';
220
225
  processBtn.disabled = true;
226
+ validateBtn.disabled = true;
221
227
  return;
222
228
  }
223
229
 
@@ -228,12 +234,14 @@ function handleFile(file: File) {
228
234
  fileDetails.textContent = `${file.name} • ${formatFileSize(file.size)}`;
229
235
  fileInfo.style.display = 'block';
230
236
  processBtn.disabled = false;
237
+ validateBtn.disabled = false;
231
238
  currentSourceLabel = file.name;
232
239
 
233
240
  log(`Using processor: ${currentProcessor.constructor.name}`, 'success');
234
241
  } catch (error) {
235
242
  log(`Error getting processor: ${(error as Error).message}`, 'error');
236
243
  processBtn.disabled = true;
244
+ validateBtn.disabled = true;
237
245
  }
238
246
  }
239
247
 
@@ -314,6 +322,79 @@ processBtn.addEventListener('click', async () => {
314
322
  }
315
323
  });
316
324
 
325
+ function collectValidationMessages(
326
+ result: ValidationResult,
327
+ prefix = ''
328
+ ): Array<{ type: 'error' | 'warn'; message: string }> {
329
+ const messages: Array<{ type: 'error' | 'warn'; message: string }> = [];
330
+ const label = prefix ? `${prefix}: ` : '';
331
+ result.results.forEach((check) => {
332
+ if (!check.valid && check.error) {
333
+ messages.push({ type: 'error', message: `${label}${check.description}: ${check.error}` });
334
+ }
335
+ if (check.warnings?.length) {
336
+ check.warnings.forEach((warning) => {
337
+ messages.push({ type: 'warn', message: `${label}${check.description}: ${warning}` });
338
+ });
339
+ }
340
+ });
341
+ result.sub_results?.forEach((sub) => {
342
+ const nextPrefix = `${label}${sub.filename || sub.format}`;
343
+ messages.push(...collectValidationMessages(sub, nextPrefix));
344
+ });
345
+ return messages;
346
+ }
347
+
348
+ function renderValidationResult(result: ValidationResult) {
349
+ validationPanel.style.display = 'block';
350
+ validationSummary.classList.remove('success', 'error');
351
+ validationSummary.classList.add(result.valid ? 'success' : 'error');
352
+ validationSummary.textContent = `${result.valid ? '✅ Valid' : '❌ Invalid'} • ${result.format.toUpperCase()} • ${result.errors} errors, ${result.warnings} warnings`;
353
+
354
+ validationList.innerHTML = '';
355
+ const messages = collectValidationMessages(result).slice(0, 30);
356
+ if (messages.length === 0) {
357
+ const empty = document.createElement('div');
358
+ empty.className = 'validation-item';
359
+ empty.textContent = 'No issues reported.';
360
+ validationList.appendChild(empty);
361
+ return;
362
+ }
363
+
364
+ messages.forEach((entry) => {
365
+ const item = document.createElement('div');
366
+ item.className = `validation-item ${entry.type}`;
367
+ item.textContent = entry.message;
368
+ validationList.appendChild(item);
369
+ });
370
+ }
371
+
372
+ validateBtn.addEventListener('click', async () => {
373
+ if (!currentFile) return;
374
+ log('Validating file...', 'info');
375
+
376
+ try {
377
+ validateBtn.disabled = true;
378
+ const arrayBuffer = await currentFile.arrayBuffer();
379
+ const result = await validateFileOrBuffer(new Uint8Array(arrayBuffer), currentFile.name);
380
+ renderValidationResult(result);
381
+ log(
382
+ `${result.valid ? '✅' : '❌'} Validation complete: ${result.errors} errors, ${result.warnings} warnings`,
383
+ result.valid ? 'success' : 'warn'
384
+ );
385
+ } catch (error) {
386
+ const errorMsg = (error as Error).message;
387
+ validationPanel.style.display = 'block';
388
+ validationSummary.classList.remove('success');
389
+ validationSummary.classList.add('error');
390
+ validationSummary.textContent = `❌ Validation failed: ${errorMsg}`;
391
+ validationList.innerHTML = '';
392
+ log(`❌ Validation failed: ${errorMsg}`, 'error');
393
+ } finally {
394
+ validateBtn.disabled = !currentFile;
395
+ }
396
+ });
397
+
317
398
  // Display results
318
399
  function displayResults(tree: AACTree) {
319
400
  results.innerHTML = '';
@@ -423,6 +504,9 @@ clearBtn.addEventListener('click', () => {
423
504
  stats.style.display = 'none';
424
505
  results.innerHTML = '<p style="color: #999; text-align: center; padding: 40px;">Load a file to see its contents here</p>';
425
506
  testResults.style.display = 'none';
507
+ validationPanel.style.display = 'none';
508
+ validationSummary.textContent = '';
509
+ validationList.innerHTML = '';
426
510
  logPanel.innerHTML = '<div class="log-entry log-info">Cleared. Ready to process files...</div>';
427
511
  pagesetOutput.textContent = 'Generate or convert a pageset to preview the output JSON.';
428
512
  updateConvertButtons();
@@ -3,13 +3,32 @@ import path from 'path';
3
3
 
4
4
  export default defineConfig({
5
5
  resolve: {
6
- alias: {
7
- 'aac-processors': path.resolve(__dirname, '../../src/index.browser.ts'),
8
- stream: path.resolve(__dirname, 'node_modules/stream-browserify'),
9
- events: path.resolve(__dirname, 'node_modules/events'),
10
- timers: path.resolve(__dirname, 'node_modules/timers-browserify'),
11
- util: path.resolve(__dirname, 'node_modules/util')
12
- }
6
+ alias: [
7
+ {
8
+ find: /^aac-processors\/validation$/,
9
+ replacement: path.resolve(__dirname, '../../src/validation.ts'),
10
+ },
11
+ {
12
+ find: /^aac-processors$/,
13
+ replacement: path.resolve(__dirname, '../../src/index.browser.ts'),
14
+ },
15
+ {
16
+ find: /^stream$/,
17
+ replacement: path.resolve(__dirname, 'node_modules/stream-browserify'),
18
+ },
19
+ {
20
+ find: /^events$/,
21
+ replacement: path.resolve(__dirname, 'node_modules/events'),
22
+ },
23
+ {
24
+ find: /^timers$/,
25
+ replacement: path.resolve(__dirname, 'node_modules/timers-browserify'),
26
+ },
27
+ {
28
+ find: /^util$/,
29
+ replacement: path.resolve(__dirname, 'node_modules/util'),
30
+ },
31
+ ],
13
32
  },
14
33
  optimizeDeps: {
15
34
  exclude: ['aac-processors'],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willwade/aac-processors",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "A comprehensive TypeScript library for processing AAC (Augmentative and Alternative Communication) file formats with translation support",
5
5
  "main": "dist/index.js",
6
6
  "browser": "dist/browser/index.browser.js",
@@ -67,6 +67,14 @@
67
67
  "./validation": {
68
68
  "types": "./dist/validation.d.ts",
69
69
  "default": "./dist/validation.js"
70
+ },
71
+ "./metrics": {
72
+ "types": "./dist/metrics.d.ts",
73
+ "default": "./dist/metrics.js"
74
+ },
75
+ "./analytics": {
76
+ "types": "./dist/analytics.d.ts",
77
+ "default": "./dist/analytics.js"
70
78
  }
71
79
  },
72
80
  "files": [