@willwade/aac-processors 0.1.5 → 0.1.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.
Files changed (40) hide show
  1. package/README.md +14 -0
  2. package/dist/browser/index.browser.js +15 -1
  3. package/dist/browser/processors/gridset/password.js +11 -0
  4. package/dist/browser/processors/gridsetProcessor.js +42 -46
  5. package/dist/browser/processors/obfProcessor.js +47 -63
  6. package/dist/browser/processors/snapProcessor.js +1031 -0
  7. package/dist/browser/processors/touchchatProcessor.js +1004 -0
  8. package/dist/browser/utils/io.js +20 -0
  9. package/dist/browser/utils/sqlite.js +109 -0
  10. package/dist/browser/utils/zip.js +54 -0
  11. package/dist/browser/validation/snapValidator.js +200 -0
  12. package/dist/browser/validation/touchChatValidator.js +202 -0
  13. package/dist/index.browser.d.ts +7 -0
  14. package/dist/index.browser.js +19 -2
  15. package/dist/processors/gridset/helpers.js +3 -4
  16. package/dist/processors/gridset/index.d.ts +1 -1
  17. package/dist/processors/gridset/index.js +3 -2
  18. package/dist/processors/gridset/password.d.ts +3 -2
  19. package/dist/processors/gridset/password.js +12 -0
  20. package/dist/processors/gridset/wordlistHelpers.js +107 -51
  21. package/dist/processors/gridsetProcessor.js +40 -44
  22. package/dist/processors/obfProcessor.js +46 -62
  23. package/dist/processors/snapProcessor.js +60 -54
  24. package/dist/processors/touchchatProcessor.js +38 -36
  25. package/dist/utils/io.d.ts +2 -0
  26. package/dist/utils/io.js +22 -0
  27. package/dist/utils/sqlite.d.ts +21 -0
  28. package/dist/utils/sqlite.js +137 -0
  29. package/dist/utils/zip.d.ts +7 -0
  30. package/dist/utils/zip.js +80 -0
  31. package/docs/BROWSER_USAGE.md +2 -10
  32. package/examples/README.md +3 -75
  33. package/examples/vitedemo/README.md +13 -7
  34. package/examples/vitedemo/index.html +2 -2
  35. package/examples/vitedemo/package-lock.json +9 -0
  36. package/examples/vitedemo/package.json +1 -0
  37. package/examples/vitedemo/src/main.ts +48 -2
  38. package/examples/vitedemo/src/vite-env.d.ts +1 -0
  39. package/package.json +3 -1
  40. package/examples/browser-test-server.js +0 -81
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.configureSqlJs = configureSqlJs;
27
+ exports.requireBetterSqlite3 = requireBetterSqlite3;
28
+ exports.openSqliteDatabase = openSqliteDatabase;
29
+ const io_1 = require("./io");
30
+ let sqlJsConfig = null;
31
+ let sqlJsPromise = null;
32
+ function configureSqlJs(config) {
33
+ sqlJsConfig = { ...(sqlJsConfig ?? {}), ...config };
34
+ }
35
+ async function getSqlJs() {
36
+ if (!sqlJsPromise) {
37
+ sqlJsPromise = Promise.resolve().then(() => __importStar(require('sql.js'))).then((module) => {
38
+ const initSqlJs = module.default || module;
39
+ return initSqlJs(sqlJsConfig ?? {});
40
+ });
41
+ }
42
+ return sqlJsPromise;
43
+ }
44
+ function createSqlJsAdapter(db) {
45
+ return {
46
+ prepare(sql) {
47
+ return {
48
+ all(...params) {
49
+ const stmt = db.prepare(sql);
50
+ if (params.length > 0) {
51
+ stmt.bind(params);
52
+ }
53
+ const rows = [];
54
+ while (stmt.step()) {
55
+ rows.push(stmt.getAsObject());
56
+ }
57
+ stmt.free();
58
+ return rows;
59
+ },
60
+ get(...params) {
61
+ const stmt = db.prepare(sql);
62
+ if (params.length > 0) {
63
+ stmt.bind(params);
64
+ }
65
+ const row = stmt.step() ? stmt.getAsObject() : undefined;
66
+ stmt.free();
67
+ return row;
68
+ },
69
+ run(...params) {
70
+ const stmt = db.prepare(sql);
71
+ if (params.length > 0) {
72
+ stmt.bind(params);
73
+ }
74
+ stmt.step();
75
+ stmt.free();
76
+ return undefined;
77
+ },
78
+ };
79
+ },
80
+ exec(sql) {
81
+ db.exec(sql);
82
+ },
83
+ close() {
84
+ db.close();
85
+ },
86
+ };
87
+ }
88
+ function getBetterSqlite3() {
89
+ try {
90
+ const nodeRequire = (0, io_1.getNodeRequire)();
91
+ return nodeRequire('better-sqlite3');
92
+ }
93
+ catch {
94
+ throw new Error('better-sqlite3 is not available in this environment.');
95
+ }
96
+ }
97
+ function requireBetterSqlite3() {
98
+ return getBetterSqlite3();
99
+ }
100
+ async function openSqliteDatabase(input, options = {}) {
101
+ if (typeof input === 'string') {
102
+ if (!(0, io_1.isNodeRuntime)()) {
103
+ throw new Error('SQLite file paths are not supported in browser environments.');
104
+ }
105
+ const Database = getBetterSqlite3();
106
+ const db = new Database(input, { readonly: options.readonly ?? true });
107
+ return { db };
108
+ }
109
+ const data = (0, io_1.readBinaryFromInput)(input);
110
+ if (!(0, io_1.isNodeRuntime)()) {
111
+ const SQL = await getSqlJs();
112
+ const db = new SQL.Database(data);
113
+ return { db: createSqlJsAdapter(db) };
114
+ }
115
+ const fs = (0, io_1.getFs)();
116
+ const path = (0, io_1.getPath)();
117
+ const os = (0, io_1.getOs)();
118
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'aac-sqlite-'));
119
+ const dbPath = path.join(tempDir, 'input.sqlite');
120
+ fs.writeFileSync(dbPath, data);
121
+ const Database = getBetterSqlite3();
122
+ const db = new Database(dbPath, { readonly: options.readonly ?? true });
123
+ const cleanup = () => {
124
+ try {
125
+ db.close();
126
+ }
127
+ finally {
128
+ try {
129
+ fs.rmSync(tempDir, { recursive: true, force: true });
130
+ }
131
+ catch (error) {
132
+ console.warn('Failed to clean up temporary SQLite files:', error);
133
+ }
134
+ }
135
+ };
136
+ return { db, cleanup };
137
+ }
@@ -0,0 +1,7 @@
1
+ export interface ZipAdapter {
2
+ listFiles(): string[];
3
+ readFile(name: string): Promise<Uint8Array>;
4
+ }
5
+ export declare function openZipFromInput(input: string | Uint8Array | ArrayBuffer | Buffer): Promise<{
6
+ zip: ZipAdapter;
7
+ }>;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.openZipFromInput = openZipFromInput;
27
+ const io_1 = require("./io");
28
+ async function openZipFromInput(input) {
29
+ if (typeof input === 'string') {
30
+ if (!(0, io_1.isNodeRuntime)()) {
31
+ throw new Error('Zip file paths are not supported in browser environments.');
32
+ }
33
+ const AdmZip = (0, io_1.getNodeRequire)()('adm-zip');
34
+ const admZip = new AdmZip(input);
35
+ return {
36
+ zip: {
37
+ listFiles: () => admZip.getEntries().map((entry) => entry.entryName),
38
+ readFile: (name) => {
39
+ const entry = admZip.getEntry(name);
40
+ if (!entry) {
41
+ throw new Error(`Zip entry not found: ${name}`);
42
+ }
43
+ return Promise.resolve(entry.getData());
44
+ },
45
+ },
46
+ };
47
+ }
48
+ const data = (0, io_1.readBinaryFromInput)(input);
49
+ if ((0, io_1.isNodeRuntime)()) {
50
+ const AdmZip = (0, io_1.getNodeRequire)()('adm-zip');
51
+ const admZip = new AdmZip(Buffer.from(data));
52
+ return {
53
+ zip: {
54
+ listFiles: () => admZip.getEntries().map((entry) => entry.entryName),
55
+ readFile: (name) => {
56
+ const entry = admZip.getEntry(name);
57
+ if (!entry) {
58
+ throw new Error(`Zip entry not found: ${name}`);
59
+ }
60
+ return Promise.resolve(entry.getData());
61
+ },
62
+ },
63
+ };
64
+ }
65
+ const module = await Promise.resolve().then(() => __importStar(require('jszip')));
66
+ const init = module.default || module;
67
+ const zip = await init.loadAsync(data);
68
+ return {
69
+ zip: {
70
+ listFiles: () => Object.keys(zip.files),
71
+ readFile: async (name) => {
72
+ const file = zip.file(name);
73
+ if (!file) {
74
+ throw new Error(`Zip entry not found: ${name}`);
75
+ }
76
+ return file.async('uint8array');
77
+ },
78
+ },
79
+ };
80
+ }
@@ -565,14 +565,7 @@ async function safeLoadFile(file) {
565
565
 
566
566
  ## Testing
567
567
 
568
- See [Browser Test Page](../examples/browser-test.html) for interactive testing.
569
-
570
- To run the test server:
571
- ```bash
572
- node examples/browser-test-server.js
573
- ```
574
-
575
- Then open: http://localhost:8080/examples/browser-test.html
568
+ Use the Vite demo in `examples/vitedemo` for interactive browser testing.
576
569
 
577
570
  ## Troubleshooting
578
571
 
@@ -614,5 +607,4 @@ await processor.loadIntoTree(uint8Array);
614
607
 
615
608
  - [API Documentation](./API.md)
616
609
  - [Examples](../examples/)
617
- - [Browser Test Page](../examples/browser-test.html)
618
- - [Test Server](../examples/browser-test-server.js)
610
+ - [Vite Browser Demo](../examples/vitedemo)
@@ -49,79 +49,7 @@ These pagesets are used by:
49
49
 
50
50
  To run demo scripts that use these pagesets, see the [scripts/README.md](../scripts/README.md).
51
51
 
52
- ## Browser Testing
52
+ ## Browser Demo (Vite)
53
53
 
54
- ### ⚠️ Important Note
55
-
56
- AACProcessors is built with TypeScript and outputs CommonJS modules. To use it in a browser, you **must use a bundler** (Vite, Webpack, Rollup, etc.). The browser test page below only validates the library structure - it cannot run actual processors without a bundler.
57
-
58
- ### Browser Test Page
59
-
60
- A dedicated browser test page is available for validating the library structure:
61
-
62
- **Start the test server:**
63
- ```bash
64
- node examples/browser-test-server.js
65
- ```
66
-
67
- **Open in your browser:**
68
- ```
69
- http://localhost:8080/examples/browser-test.html
70
- ```
71
-
72
- **What it tests:**
73
- - ✅ Browser build files exist and are accessible
74
- - ✅ Type definitions are present
75
- - ✅ Processor exports are available
76
- - ❌ **Does NOT run actual processors** (requires bundler)
77
-
78
- ### What Gets Tested
79
-
80
- The browser test page (`browser-test.html`) verifies:
81
-
82
- 1. **Module Loading** - Can the browser load the ES modules?
83
- 2. **Factory Functions** - Do `getProcessor()` and `getSupportedExtensions()` work?
84
- 3. **Processor Instantiation** - Can processors be created?
85
- 4. **File Loading** - Can files be loaded from `<input type="file">`?
86
- 5. **Buffer Handling** - Do ArrayBuffers/Uint8Arrays work correctly?
87
- 6. **Tree Structure** - Can AACTree be created from files?
88
- 7. **Text Extraction** - Can texts be extracted from files?
89
-
90
- ### Supported File Types in Browser
91
-
92
- The browser test page supports all browser-compatible processors:
93
-
94
- - **DotProcessor** (.dot) - OpenSymbols Board files
95
- - **OpmlProcessor** (.opml) - OPML outline files
96
- - **ObfProcessor** (.obf/.obz) - Open Board Format files
97
- - **GridsetProcessor** (.gridset) - Grid 3 gridset files (not .gridsetx)
98
- - **ApplePanelsProcessor** (.plist) - Apple Panels files
99
- - **AstericsGridProcessor** (.grd) - Asterics Grid files
100
-
101
- ### Manual Testing
102
-
103
- 1. Open the browser console (F12 or Cmd+Option+I)
104
- 2. Click "Select a file to test" to upload an AAC file
105
- 3. Click "Test File" to process it
106
- 4. Check the results panel for page count, button count, and extracted texts
107
-
108
- ### Automated Tests
109
-
110
- Click "Run All Browser Tests" to run automated checks:
111
- - Factory function tests
112
- - Extension support tests
113
- - Processor instantiation tests
114
- - Buffer handling tests
115
-
116
- ### Node-Only Processors
117
-
118
- The following processors are **not available** in the browser:
119
- - **SnapProcessor** (.spb/.sps) - Requires SQLite
120
- - **TouchChatProcessor** (.ce) - Requires SQLite
121
- - **ExcelProcessor** (.xlsx) - Uses fs at top level
122
-
123
- ### Notes
124
-
125
- - Gridset `.gridsetx` files (encrypted) are not supported in browser
126
- - All processors work with Buffer, Uint8Array, and ArrayBuffer inputs
127
- - File paths are not supported in browser (use file inputs or fetch)
54
+ For browser testing, use the Vite demo in `examples/vitedemo`. It bundles the
55
+ library and exercises real processors in a browser environment.
@@ -5,7 +5,7 @@ A real browser demo that uses Vite to bundle AACProcessors for browser use.
5
5
  ## Features
6
6
 
7
7
  - ✅ **Real file processing** - Upload and process actual AAC files
8
- - ✅ **All browser-compatible processors** - Tests Dot, OPML, OBF/OBZ, Gridset, ApplePanels, AstericsGrid
8
+ - ✅ **All browser-compatible processors** - Tests Dot, OPML, OBF/OBZ, Gridset, Snap, TouchChat, ApplePanels, AstericsGrid
9
9
  - ✅ **Interactive UI** - Drag & drop files, view pages and buttons
10
10
  - ✅ **Text-to-speech** - Click SPEAK buttons to hear messages (browser speech API)
11
11
  - ✅ **Navigation** - Click NAVIGATE buttons to jump between pages
@@ -35,15 +35,14 @@ The demo will open automatically at: http://localhost:3000
35
35
  This demo is intended for `npm run dev` only. The production build currently fails because the
36
36
  demo source includes strict TypeScript issues, so it will not work "out of the box."
37
37
 
38
- If you need a no-build browser check, use the browser test page served by:
39
- `node examples/browser-test-server.js`
38
+ This demo is the recommended browser test environment.
40
39
 
41
40
  ## How to Use
42
41
 
43
42
  1. **Upload a file**
44
43
  - Drag & drop an AAC file onto the upload area
45
44
  - Or click to open file picker
46
- - Supported formats: .dot, .opml, .obf, .obz, .gridset, .plist, .grd
45
+ - Supported formats: .dot, .opml, .obf, .obz, .gridset, .sps, .spb, .ce, .plist, .grd
47
46
 
48
47
  2. **Process the file**
49
48
  - Click "Process File" button
@@ -57,7 +56,7 @@ If you need a no-build browser check, use the browser test page served by:
57
56
  4. **Run compatibility tests**
58
57
  - Click "Run Compatibility Tests"
59
58
  - See test results in the left panel
60
- - Tests all 6 browser-compatible processors
59
+ - Tests all browser-compatible processors
61
60
 
62
61
  ## Supported File Types
63
62
 
@@ -67,6 +66,8 @@ If you need a no-build browser check, use the browser test page served by:
67
66
  | OPML | .opml | OpmlProcessor |
68
67
  | OBF/OBZ | .obf, .obz | ObfProcessor |
69
68
  | Gridset | .gridset | GridsetProcessor |
69
+ | Snap | .sps, .spb | SnapProcessor |
70
+ | TouchChat| .ce | TouchChatProcessor |
70
71
  | Apple | .plist | ApplePanelsProcessor |
71
72
  | Asterics | .grd | AstericsGridProcessor |
72
73
 
@@ -102,10 +103,15 @@ export default defineConfig({
102
103
 
103
104
  This allows direct TypeScript import without pre-building.
104
105
 
105
- ### Import Example
106
+ ### Import Example (with SQLite WASM)
106
107
 
107
108
  ```typescript
108
- import { getProcessor } from 'aac-processors';
109
+ import { configureSqlJs, getProcessor } from 'aac-processors';
110
+ import sqlWasmUrl from 'sql.js/dist/sql-wasm.wasm?url';
111
+
112
+ configureSqlJs({
113
+ locateFile: () => sqlWasmUrl
114
+ });
109
115
 
110
116
  // Get processor for file type
111
117
  const processor = getProcessor('.obf');
@@ -423,11 +423,11 @@
423
423
  <div class="upload-icon">📤</div>
424
424
  <p><strong>Drop file here</strong> or click to upload</p>
425
425
  <p style="font-size: 12px; color: #999; margin-top: 5px;">
426
- Supports: .dot, .opml, .obf, .obz, .gridset, .plist, .grd
426
+ Supports: .dot, .opml, .obf, .obz, .gridset, .sps, .spb, .ce, .plist, .grd
427
427
  </p>
428
428
  </div>
429
429
 
430
- <input type="file" id="fileInput" accept=".dot,.opml,.obf,.obz,.gridset,.plist,.grd">
430
+ <input type="file" id="fileInput" accept=".dot,.opml,.obf,.obz,.gridset,.sps,.spb,.ce,.plist,.grd">
431
431
 
432
432
  <div id="fileInfo" style="display: none;">
433
433
  <div class="processor-info">
@@ -11,6 +11,7 @@
11
11
  "@willwade/aac-processors": "file:../..",
12
12
  "events": "^3.3.0",
13
13
  "jszip": "^3.10.1",
14
+ "sql.js": "^1.13.0",
14
15
  "stream-browserify": "^3.0.0",
15
16
  "timers-browserify": "^2.0.12",
16
17
  "util": "^0.12.5"
@@ -34,6 +35,7 @@
34
35
  "fast-xml-parser": "^5.2.0",
35
36
  "jszip": "^3.10.1",
36
37
  "plist": "^3.1.0",
38
+ "sql.js": "^1.13.0",
37
39
  "xml2js": "^0.6.2",
38
40
  "yauzl": "^3.2.0"
39
41
  },
@@ -47,6 +49,7 @@
47
49
  "@types/jest": "^29.5.12",
48
50
  "@types/node": "^20.11.24",
49
51
  "@types/plist": "^3.0.5",
52
+ "@types/sql.js": "^1.4.9",
50
53
  "@typescript-eslint/eslint-plugin": "^7.1.0",
51
54
  "@typescript-eslint/parser": "^7.1.0",
52
55
  "eslint": "^8.56.0",
@@ -1547,6 +1550,12 @@
1547
1550
  "node": ">=0.10.0"
1548
1551
  }
1549
1552
  },
1553
+ "node_modules/sql.js": {
1554
+ "version": "1.13.0",
1555
+ "resolved": "https://registry.npmjs.org/sql.js/-/sql.js-1.13.0.tgz",
1556
+ "integrity": "sha512-RJbVP1HRDlUUXahJ7VMTcu9Rm1Nzw+EBpoPr94vnbD4LwR715F3CcxE2G2k45PewcaZ57pjetYa+LoSJLAASgA==",
1557
+ "license": "MIT"
1558
+ },
1550
1559
  "node_modules/stream-browserify": {
1551
1560
  "version": "3.0.0",
1552
1561
  "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
@@ -16,6 +16,7 @@
16
16
  "@willwade/aac-processors": "file:../..",
17
17
  "events": "^3.3.0",
18
18
  "jszip": "^3.10.1",
19
+ "sql.js": "^1.13.0",
19
20
  "stream-browserify": "^3.0.0",
20
21
  "timers-browserify": "^2.0.12",
21
22
  "util": "^0.12.5"
@@ -66,12 +66,15 @@ if (typeof (window as any).Buffer === 'undefined') {
66
66
  }
67
67
 
68
68
  import {
69
+ configureSqlJs,
69
70
  getProcessor,
70
71
  getSupportedExtensions,
71
72
  DotProcessor,
72
73
  OpmlProcessor,
73
74
  ObfProcessor,
74
75
  GridsetProcessor,
76
+ SnapProcessor,
77
+ TouchChatProcessor,
75
78
  ApplePanelsProcessor,
76
79
  AstericsGridProcessor,
77
80
  AACTree,
@@ -79,6 +82,12 @@ import {
79
82
  AACButton
80
83
  } from 'aac-processors';
81
84
 
85
+ import sqlWasmUrl from 'sql.js/dist/sql-wasm.wasm?url';
86
+
87
+ configureSqlJs({
88
+ locateFile: () => sqlWasmUrl
89
+ });
90
+
82
91
  // UI Elements
83
92
  const dropArea = document.getElementById('dropArea') as HTMLElement;
84
93
  const fileInput = document.getElementById('fileInput') as HTMLInputElement;
@@ -717,11 +726,15 @@ runTestsBtn.addEventListener('click', async () => {
717
726
  const opmlProc = getProcessor('.opml');
718
727
  const obfProc = getProcessor('.obf');
719
728
  const gridsetProc = getProcessor('.gridset');
729
+ const snapProc = getProcessor('.sps');
730
+ const touchChatProc = getProcessor('.ce');
720
731
  return (
721
732
  dotProc instanceof DotProcessor &&
722
733
  opmlProc instanceof OpmlProcessor &&
723
734
  obfProc instanceof ObfProcessor &&
724
- gridsetProc instanceof GridsetProcessor
735
+ gridsetProc instanceof GridsetProcessor &&
736
+ snapProc instanceof SnapProcessor &&
737
+ touchChatProc instanceof TouchChatProcessor
725
738
  );
726
739
  }
727
740
  },
@@ -729,7 +742,18 @@ runTestsBtn.addEventListener('click', async () => {
729
742
  name: 'getSupportedExtensions() returns all extensions',
730
743
  fn: async () => {
731
744
  const extensions = getSupportedExtensions();
732
- const expected = ['.dot', '.opml', '.obf', '.obz', '.gridset', '.plist', '.grd'];
745
+ const expected = [
746
+ '.dot',
747
+ '.opml',
748
+ '.obf',
749
+ '.obz',
750
+ '.gridset',
751
+ '.spb',
752
+ '.sps',
753
+ '.ce',
754
+ '.plist',
755
+ '.grd'
756
+ ];
733
757
  return expected.every((ext) => extensions.includes(ext));
734
758
  }
735
759
  },
@@ -777,6 +801,28 @@ runTestsBtn.addEventListener('click', async () => {
777
801
  }
778
802
  }
779
803
  },
804
+ {
805
+ name: 'SnapProcessor instantiation',
806
+ fn: async () => {
807
+ try {
808
+ new SnapProcessor();
809
+ return true;
810
+ } catch {
811
+ return false;
812
+ }
813
+ }
814
+ },
815
+ {
816
+ name: 'TouchChatProcessor instantiation',
817
+ fn: async () => {
818
+ try {
819
+ new TouchChatProcessor();
820
+ return true;
821
+ } catch {
822
+ return false;
823
+ }
824
+ }
825
+ },
780
826
  {
781
827
  name: 'ApplePanelsProcessor instantiation',
782
828
  fn: async () => {
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willwade/aac-processors",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
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",
@@ -151,6 +151,7 @@
151
151
  "@types/jest": "^29.5.12",
152
152
  "@types/node": "^20.11.24",
153
153
  "@types/plist": "^3.0.5",
154
+ "@types/sql.js": "^1.4.9",
154
155
  "@typescript-eslint/eslint-plugin": "^7.1.0",
155
156
  "@typescript-eslint/parser": "^7.1.0",
156
157
  "eslint": "^8.56.0",
@@ -174,6 +175,7 @@
174
175
  "fast-xml-parser": "^5.2.0",
175
176
  "jszip": "^3.10.1",
176
177
  "plist": "^3.1.0",
178
+ "sql.js": "^1.13.0",
177
179
  "xml2js": "^0.6.2",
178
180
  "yauzl": "^3.2.0"
179
181
  },
@@ -1,81 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Simple HTTP server for testing AACProcessors in a browser
5
- *
6
- * Usage:
7
- * node examples/browser-test-server.js
8
- *
9
- * Then open: http://localhost:8080/examples/browser-test.html
10
- */
11
-
12
- const http = require('http');
13
- const fs = require('fs');
14
- const path = require('path');
15
-
16
- const PORT = 8080;
17
- const MIME_TYPES = {
18
- '.html': 'text/html',
19
- '.js': 'text/javascript',
20
- '.css': 'text/css',
21
- '.json': 'application/json',
22
- '.png': 'image/png',
23
- '.jpg': 'image/jpg',
24
- '.gif': 'image/gif',
25
- '.svg': 'image/svg+xml',
26
- '.ico': 'image/x-icon',
27
- };
28
-
29
- const server = http.createServer((req, res) => {
30
- // Enable CORS
31
- res.setHeader('Access-Control-Allow-Origin', '*');
32
- res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
33
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
34
-
35
- if (req.method === 'OPTIONS') {
36
- res.writeHead(200);
37
- res.end();
38
- return;
39
- }
40
-
41
- // Parse URL
42
- let filePath = '.' + req.url;
43
- if (filePath === './') {
44
- filePath = './examples/browser-test.html';
45
- }
46
-
47
- // Get file extension
48
- const extname = String(path.extname(filePath)).toLowerCase();
49
- const contentType = MIME_TYPES[extname] || 'application/octet-stream';
50
-
51
- // Read and serve file
52
- fs.readFile(filePath, (error, content) => {
53
- if (error) {
54
- if (error.code === 'ENOENT') {
55
- res.writeHead(404, { 'Content-Type': 'text/html' });
56
- res.end('<h1>404 Not Found</h1>', 'utf-8');
57
- } else {
58
- res.writeHead(500);
59
- res.end(`Server Error: ${error.code}`, 'utf-8');
60
- }
61
- } else {
62
- res.writeHead(200, { 'Content-Type': contentType });
63
- res.end(content, 'utf-8');
64
- }
65
- });
66
- });
67
-
68
- server.listen(PORT, () => {
69
- console.log(`
70
- ╔════════════════════════════════════════════════════════════╗
71
- ║ AACProcessors Browser Test Server ║
72
- ╠════════════════════════════════════════════════════════════╣
73
- ║ ║
74
- ║ Server running at: ║
75
- ║ 🌐 http://localhost:${PORT}/examples/browser-test.html ║
76
- ║ ║
77
- ║ Press Ctrl+C to stop ║
78
- ║ ║
79
- ╚════════════════════════════════════════════════════════════╝
80
- `);
81
- });