@willwade/aac-processors 0.1.4 → 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.
- package/README.md +14 -0
- package/dist/browser/index.browser.js +15 -1
- package/dist/browser/processors/gridset/password.js +11 -0
- package/dist/browser/processors/gridset/symbols.js +3 -2
- package/dist/browser/processors/gridsetProcessor.js +42 -46
- package/dist/browser/processors/obfProcessor.js +47 -63
- package/dist/browser/processors/snapProcessor.js +1031 -0
- package/dist/browser/processors/touchchatProcessor.js +1004 -0
- package/dist/browser/utils/io.js +21 -1
- package/dist/browser/utils/sqlite.js +109 -0
- package/dist/browser/utils/zip.js +54 -0
- package/dist/browser/validation/gridsetValidator.js +21 -2
- package/dist/browser/validation/obfValidator.js +4 -5
- package/dist/browser/validation/snapValidator.js +200 -0
- package/dist/browser/validation/touchChatValidator.js +202 -0
- package/dist/index.browser.d.ts +7 -0
- package/dist/index.browser.js +19 -2
- package/dist/processors/gridset/helpers.js +3 -4
- package/dist/processors/gridset/index.d.ts +1 -1
- package/dist/processors/gridset/index.js +3 -2
- package/dist/processors/gridset/password.d.ts +3 -2
- package/dist/processors/gridset/password.js +12 -0
- package/dist/processors/gridset/symbols.js +2 -1
- package/dist/processors/gridset/wordlistHelpers.js +107 -51
- package/dist/processors/gridsetProcessor.js +40 -44
- package/dist/processors/obfProcessor.js +46 -62
- package/dist/processors/snapProcessor.js +60 -54
- package/dist/processors/touchchatProcessor.js +38 -36
- package/dist/utils/io.d.ts +5 -0
- package/dist/utils/io.js +23 -0
- package/dist/utils/sqlite.d.ts +21 -0
- package/dist/utils/sqlite.js +137 -0
- package/dist/utils/zip.d.ts +7 -0
- package/dist/utils/zip.js +80 -0
- package/dist/validation/gridsetValidator.js +20 -24
- package/dist/validation/obfValidator.js +4 -28
- package/docs/BROWSER_USAGE.md +2 -10
- package/examples/README.md +3 -75
- package/examples/vitedemo/README.md +17 -10
- package/examples/vitedemo/index.html +2 -2
- package/examples/vitedemo/package-lock.json +531 -1
- package/examples/vitedemo/package.json +7 -1
- package/examples/vitedemo/src/main.ts +48 -2
- package/examples/vitedemo/src/vite-env.d.ts +1 -0
- package/package.json +3 -1
- package/examples/browser-test-server.js +0 -81
- package/examples/vitedemo/QUICKSTART.md +0 -75
|
@@ -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,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
|
+
}
|
|
@@ -1,27 +1,4 @@
|
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
4
|
};
|
|
@@ -30,10 +7,25 @@ exports.GridsetValidator = void 0;
|
|
|
30
7
|
/* eslint-disable @typescript-eslint/require-await */
|
|
31
8
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
32
9
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
33
|
-
const xml2js = __importStar(require("xml2js"));
|
|
34
10
|
const jszip_1 = __importDefault(require("jszip"));
|
|
35
11
|
const baseValidator_1 = require("./baseValidator");
|
|
36
12
|
const io_1 = require("../utils/io");
|
|
13
|
+
let cachedXml2js = null;
|
|
14
|
+
function getXml2js() {
|
|
15
|
+
if (cachedXml2js)
|
|
16
|
+
return cachedXml2js;
|
|
17
|
+
try {
|
|
18
|
+
const nodeRequire = (0, io_1.getNodeRequire)();
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
20
|
+
const module = nodeRequire('xml2js');
|
|
21
|
+
const resolved = module.default || module;
|
|
22
|
+
cachedXml2js = resolved;
|
|
23
|
+
return resolved;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
throw new Error('Validator requires Xml2js in this environment.');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
37
29
|
/**
|
|
38
30
|
* Validator for Grid3/Smartbox Gridset files (.gridset, .gridsetx)
|
|
39
31
|
*/
|
|
@@ -63,6 +55,7 @@ class GridsetValidator extends baseValidator_1.BaseValidator {
|
|
|
63
55
|
// Try to parse as XML and check for gridset structure
|
|
64
56
|
try {
|
|
65
57
|
const contentStr = Buffer.isBuffer(content) ? content.toString('utf-8') : content;
|
|
58
|
+
const xml2js = getXml2js();
|
|
66
59
|
const parser = new xml2js.Parser();
|
|
67
60
|
const result = await parser.parseStringPromise(contentStr);
|
|
68
61
|
return result && (result.gridset || result.Gridset);
|
|
@@ -115,6 +108,7 @@ class GridsetValidator extends baseValidator_1.BaseValidator {
|
|
|
115
108
|
let xmlObj = null;
|
|
116
109
|
await this.add_check('xml_parse', 'valid XML', async () => {
|
|
117
110
|
try {
|
|
111
|
+
const xml2js = getXml2js();
|
|
118
112
|
const parser = new xml2js.Parser();
|
|
119
113
|
const contentStr = content.toString('utf-8');
|
|
120
114
|
xmlObj = await parser.parseStringPromise(contentStr);
|
|
@@ -157,6 +151,7 @@ class GridsetValidator extends baseValidator_1.BaseValidator {
|
|
|
157
151
|
else {
|
|
158
152
|
try {
|
|
159
153
|
const gridsetXml = await gridsetEntry.async('string');
|
|
154
|
+
const xml2js = getXml2js();
|
|
160
155
|
const parser = new xml2js.Parser();
|
|
161
156
|
const xmlObj = await parser.parseStringPromise(gridsetXml);
|
|
162
157
|
const gridset = xmlObj.gridset || xmlObj.Gridset;
|
|
@@ -181,6 +176,7 @@ class GridsetValidator extends baseValidator_1.BaseValidator {
|
|
|
181
176
|
else {
|
|
182
177
|
try {
|
|
183
178
|
const settingsXml = await settingsEntry.async('string');
|
|
179
|
+
const xml2js = getXml2js();
|
|
184
180
|
const parser = new xml2js.Parser();
|
|
185
181
|
const xmlObj = await parser.parseStringPromise(settingsXml);
|
|
186
182
|
const settings = xmlObj.GridSetSettings || xmlObj.gridSetSettings || xmlObj.GridsetSettings;
|
|
@@ -1,27 +1,4 @@
|
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
4
|
};
|
|
@@ -34,8 +11,7 @@ exports.ObfValidator = void 0;
|
|
|
34
11
|
/* eslint-disable @typescript-eslint/restrict-template-expressions */
|
|
35
12
|
const jszip_1 = __importDefault(require("jszip"));
|
|
36
13
|
const baseValidator_1 = require("./baseValidator");
|
|
37
|
-
const
|
|
38
|
-
const path = __importStar(require("path"));
|
|
14
|
+
const io_1 = require("../utils/io");
|
|
39
15
|
const OBF_FORMAT = 'open-board-0.1';
|
|
40
16
|
const OBF_FORMAT_CURRENT_VERSION = 0.1;
|
|
41
17
|
/**
|
|
@@ -50,9 +26,9 @@ class ObfValidator extends baseValidator_1.BaseValidator {
|
|
|
50
26
|
*/
|
|
51
27
|
static async validateFile(filePath) {
|
|
52
28
|
const validator = new ObfValidator();
|
|
53
|
-
const content =
|
|
54
|
-
const stats =
|
|
55
|
-
return validator.validate(content,
|
|
29
|
+
const content = (0, io_1.readBinaryFromInput)(filePath);
|
|
30
|
+
const stats = (0, io_1.getFs)().statSync(filePath);
|
|
31
|
+
return validator.validate(content, (0, io_1.getPath)().basename(filePath), stats.size);
|
|
56
32
|
}
|
|
57
33
|
/**
|
|
58
34
|
* Check if content is OBF format
|
package/docs/BROWSER_USAGE.md
CHANGED
|
@@ -565,14 +565,7 @@ async function safeLoadFile(file) {
|
|
|
565
565
|
|
|
566
566
|
## Testing
|
|
567
567
|
|
|
568
|
-
|
|
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
|
|
618
|
-
- [Test Server](../examples/browser-test-server.js)
|
|
610
|
+
- [Vite Browser Demo](../examples/vitedemo)
|
package/examples/README.md
CHANGED
|
@@ -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
|
|
52
|
+
## Browser Demo (Vite)
|
|
53
53
|
|
|
54
|
-
|
|
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
|
|
@@ -30,19 +30,19 @@ npm run dev
|
|
|
30
30
|
|
|
31
31
|
The demo will open automatically at: http://localhost:3000
|
|
32
32
|
|
|
33
|
-
### 3. Build for Production
|
|
33
|
+
### 3. Build for Production (Not Supported Yet)
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
This demo is intended for `npm run dev` only. The production build currently fails because the
|
|
36
|
+
demo source includes strict TypeScript issues, so it will not work "out of the box."
|
|
37
|
+
|
|
38
|
+
This demo is the recommended browser test environment.
|
|
39
39
|
|
|
40
40
|
## How to Use
|
|
41
41
|
|
|
42
42
|
1. **Upload a file**
|
|
43
43
|
- Drag & drop an AAC file onto the upload area
|
|
44
44
|
- Or click to open file picker
|
|
45
|
-
- Supported formats: .dot, .opml, .obf, .obz, .gridset, .plist, .grd
|
|
45
|
+
- Supported formats: .dot, .opml, .obf, .obz, .gridset, .sps, .spb, .ce, .plist, .grd
|
|
46
46
|
|
|
47
47
|
2. **Process the file**
|
|
48
48
|
- Click "Process File" button
|
|
@@ -56,7 +56,7 @@ npm run preview
|
|
|
56
56
|
4. **Run compatibility tests**
|
|
57
57
|
- Click "Run Compatibility Tests"
|
|
58
58
|
- See test results in the left panel
|
|
59
|
-
- Tests all
|
|
59
|
+
- Tests all browser-compatible processors
|
|
60
60
|
|
|
61
61
|
## Supported File Types
|
|
62
62
|
|
|
@@ -66,6 +66,8 @@ npm run preview
|
|
|
66
66
|
| OPML | .opml | OpmlProcessor |
|
|
67
67
|
| OBF/OBZ | .obf, .obz | ObfProcessor |
|
|
68
68
|
| Gridset | .gridset | GridsetProcessor |
|
|
69
|
+
| Snap | .sps, .spb | SnapProcessor |
|
|
70
|
+
| TouchChat| .ce | TouchChatProcessor |
|
|
69
71
|
| Apple | .plist | ApplePanelsProcessor |
|
|
70
72
|
| Asterics | .grd | AstericsGridProcessor |
|
|
71
73
|
|
|
@@ -101,10 +103,15 @@ export default defineConfig({
|
|
|
101
103
|
|
|
102
104
|
This allows direct TypeScript import without pre-building.
|
|
103
105
|
|
|
104
|
-
### Import Example
|
|
106
|
+
### Import Example (with SQLite WASM)
|
|
105
107
|
|
|
106
108
|
```typescript
|
|
107
|
-
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
|
+
});
|
|
108
115
|
|
|
109
116
|
// Get processor for file type
|
|
110
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">
|