@willwade/aac-processors 0.0.7 → 0.0.9

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 CHANGED
@@ -58,6 +58,37 @@ npm run build
58
58
 
59
59
  ---
60
60
 
61
+ ## Using with Electron
62
+
63
+ `better-sqlite3` is a native module and must be rebuilt against Electron's Node.js runtime. If you see a `NODE_MODULE_VERSION` mismatch error, rebuild after installing dependencies:
64
+
65
+ ```bash
66
+ npm install
67
+ npx electron-rebuild
68
+ ```
69
+
70
+ Or add a postinstall hook so the rebuild happens automatically:
71
+
72
+ ```json
73
+ {
74
+ "scripts": {
75
+ "postinstall": "electron-builder install-app-deps"
76
+ }
77
+ }
78
+ ```
79
+
80
+ This step is only required for Electron apps; regular Node.js consumers do not need it.
81
+
82
+ ---
83
+
84
+ ## Windows Data Paths
85
+
86
+ - **Grid 3 history**: `C:\Users\Public\Documents\Smartbox\Grid 3\Users\{username}\{langCode}\Phrases\history.sqlite`
87
+ - **Grid 3 vocabularies**: `C:\Users\Public\Documents\Smartbox\Grid 3\Users\{username}\Grid Sets\`
88
+ - **Snap vocabularies**: `C:\Users\{username}\AppData\Roaming\Tobii Dynavox\Snap Scene\Users\{userId}\` (`.sps`/`.spb`)
89
+
90
+ ---
91
+
61
92
  ## 🔧 Quick Start
62
93
 
63
94
  ### Basic Usage (TypeScript/ES6)
@@ -404,8 +435,8 @@ processor.saveFromTree(tree, "styled-board.spb");
404
435
  | **Grid3** | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Style references |
405
436
  | **Asterics Grid** | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Metadata-based |
406
437
  | **Apple Panels** | ✅ Yes | ✅ Size only | ❌ No | ✅ Display weight |
407
- | **Dot** | ❌No | ❌ Yes | ❌ No | ❌ Basic only |
408
- | **OPML** | ❌No | ❌ Yes | ❌ No | ❌ Basic only |
438
+ | **Dot** | ❌No | ❌ Yes | ❌ No | ❌ Basic only |
439
+ | **OPML** | ❌No | ❌ Yes | ❌ No | ❌ Basic only |
409
440
  | **Excel** | ✅ Yes | ✅ Size only | ❌ No | ✅ Display weight |
410
441
 
411
442
  #### Cross-Format Styling Conversion
@@ -710,7 +741,6 @@ Inspired by the Python AACProcessors project
710
741
  - [ ] **Add Symbol Tools coverage** (currently 0%) - Implement tests for PCS and ARASAAC symbol lookups to reach >70% coverage
711
742
  - [ ] **Fix property-based test failures** - Resolve TypeScript interface compatibility issues in edge case generators
712
743
 
713
-
714
744
  ### Medium Priority
715
745
 
716
746
  - [ ] **Performance optimization** - Optimize memory usage for very large communication boards (1000+ buttons)
@@ -0,0 +1,57 @@
1
+ import { dotNetTicksToDate } from '../utils/dotnetTicks';
2
+ import { Grid3UserPath } from '../processors/gridset/helpers';
3
+ import { SnapUserInfo } from '../processors/snap/helpers';
4
+ export type HistorySource = 'Grid' | 'Snap';
5
+ export interface HistoryOccurrence {
6
+ timestamp: Date;
7
+ latitude?: number | null;
8
+ longitude?: number | null;
9
+ modeling?: boolean;
10
+ accessMethod?: number | null;
11
+ pageId?: string | null;
12
+ }
13
+ export interface HistoryPlatformExtras {
14
+ label?: string;
15
+ message?: string;
16
+ buttonId?: string;
17
+ contentXml?: string;
18
+ }
19
+ export interface HistoryEntry {
20
+ id: string;
21
+ source: HistorySource;
22
+ content: string;
23
+ occurrences: HistoryOccurrence[];
24
+ raw?: unknown;
25
+ platform?: HistoryPlatformExtras;
26
+ }
27
+ export { dotNetTicksToDate };
28
+ /**
29
+ * Read Grid 3 phrase history from a history.sqlite database and tag entries with their source.
30
+ */
31
+ export declare function readGrid3History(historyDbPath: string): HistoryEntry[];
32
+ /**
33
+ * Read Grid 3 history for a specific user/language combination.
34
+ */
35
+ export declare function readGrid3HistoryForUser(userName: string, langCode?: string): HistoryEntry[];
36
+ /**
37
+ * Read every available Grid 3 history database on the machine.
38
+ */
39
+ export declare function readAllGrid3History(): HistoryEntry[];
40
+ /**
41
+ * Read Snap button usage from a pageset database and tag entries with source.
42
+ */
43
+ export declare function readSnapUsage(pagesetPath: string): HistoryEntry[];
44
+ /**
45
+ * Read Snap usage for a specific user across all discovered pagesets.
46
+ */
47
+ export declare function readSnapUsageForUser(userId?: string, packageNamePattern?: string): HistoryEntry[];
48
+ export declare function listSnapUsers(): SnapUserInfo[];
49
+ /**
50
+ * List Grid 3 users on the current machine.
51
+ */
52
+ export declare function listGrid3Users(): Grid3UserPath[];
53
+ /**
54
+ * Convenience helper to gather all available history across Grid 3 and Snap.
55
+ * Returns an empty array if no history files are present.
56
+ */
57
+ export declare function collectUnifiedHistory(): HistoryEntry[];
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dotNetTicksToDate = void 0;
4
+ exports.readGrid3History = readGrid3History;
5
+ exports.readGrid3HistoryForUser = readGrid3HistoryForUser;
6
+ exports.readAllGrid3History = readAllGrid3History;
7
+ exports.readSnapUsage = readSnapUsage;
8
+ exports.readSnapUsageForUser = readSnapUsageForUser;
9
+ exports.listSnapUsers = listSnapUsers;
10
+ exports.listGrid3Users = listGrid3Users;
11
+ exports.collectUnifiedHistory = collectUnifiedHistory;
12
+ const dotnetTicks_1 = require("../utils/dotnetTicks");
13
+ Object.defineProperty(exports, "dotNetTicksToDate", { enumerable: true, get: function () { return dotnetTicks_1.dotNetTicksToDate; } });
14
+ const helpers_1 = require("../processors/gridset/helpers");
15
+ const helpers_2 = require("../processors/snap/helpers");
16
+ /**
17
+ * Read Grid 3 phrase history from a history.sqlite database and tag entries with their source.
18
+ */
19
+ function readGrid3History(historyDbPath) {
20
+ return (0, helpers_1.readGrid3History)(historyDbPath).map((e) => ({
21
+ ...e,
22
+ source: 'Grid',
23
+ }));
24
+ }
25
+ /**
26
+ * Read Grid 3 history for a specific user/language combination.
27
+ */
28
+ function readGrid3HistoryForUser(userName, langCode) {
29
+ return (0, helpers_1.readGrid3HistoryForUser)(userName, langCode).map((e) => ({
30
+ ...e,
31
+ source: 'Grid',
32
+ }));
33
+ }
34
+ /**
35
+ * Read every available Grid 3 history database on the machine.
36
+ */
37
+ function readAllGrid3History() {
38
+ return (0, helpers_1.readAllGrid3History)().map((e) => ({ ...e, source: 'Grid' }));
39
+ }
40
+ /**
41
+ * Read Snap button usage from a pageset database and tag entries with source.
42
+ */
43
+ function readSnapUsage(pagesetPath) {
44
+ return (0, helpers_2.readSnapUsage)(pagesetPath).map((e) => ({ ...e, source: 'Snap' }));
45
+ }
46
+ /**
47
+ * Read Snap usage for a specific user across all discovered pagesets.
48
+ */
49
+ function readSnapUsageForUser(userId, packageNamePattern = 'TobiiDynavox') {
50
+ return (0, helpers_2.readSnapUsageForUser)(userId, packageNamePattern).map((e) => ({
51
+ ...e,
52
+ source: 'Snap',
53
+ }));
54
+ }
55
+ function listSnapUsers() {
56
+ return (0, helpers_2.findSnapUsers)();
57
+ }
58
+ /**
59
+ * List Grid 3 users on the current machine.
60
+ */
61
+ function listGrid3Users() {
62
+ return (0, helpers_1.findGrid3Users)();
63
+ }
64
+ /**
65
+ * Convenience helper to gather all available history across Grid 3 and Snap.
66
+ * Returns an empty array if no history files are present.
67
+ */
68
+ function collectUnifiedHistory() {
69
+ const gridHistory = readAllGrid3History();
70
+ const snapHistory = (0, helpers_2.findSnapUsers)().flatMap((u) => readSnapUsageForUser(u.userId));
71
+ return [...gridHistory, ...snapHistory];
72
+ }
@@ -1,6 +1,16 @@
1
1
  import { AACTree } from './treeStructure';
2
2
  import { BaseProcessor, ProcessorOptions } from './baseProcessor';
3
+ /**
4
+ * Resolve a processor instance by friendly format name or common extension.
5
+ * @param format Format key or extension (e.g., 'snap', 'obf', 'xlsx')
6
+ * @param options Optional processor configuration
7
+ */
3
8
  export declare function getProcessor(format: string, options?: ProcessorOptions): BaseProcessor;
9
+ /**
10
+ * Convenience helper to load a file into an AACTree using the inferred processor.
11
+ * @param file Path to the source file
12
+ * @param format Format key or extension (passed to getProcessor)
13
+ */
4
14
  export declare function analyze(file: string, format: string): {
5
15
  tree: AACTree;
6
16
  };
@@ -11,6 +11,11 @@ const snapProcessor_1 = require("../processors/snapProcessor");
11
11
  const dotProcessor_1 = require("../processors/dotProcessor");
12
12
  const excelProcessor_1 = require("../processors/excelProcessor");
13
13
  const applePanelsProcessor_1 = require("../processors/applePanelsProcessor");
14
+ /**
15
+ * Resolve a processor instance by friendly format name or common extension.
16
+ * @param format Format key or extension (e.g., 'snap', 'obf', 'xlsx')
17
+ * @param options Optional processor configuration
18
+ */
14
19
  function getProcessor(format, options) {
15
20
  const normalizedFormat = (format || '').toLowerCase();
16
21
  switch (normalizedFormat) {
@@ -42,6 +47,11 @@ function getProcessor(format, options) {
42
47
  throw new Error('Unknown format: ' + format);
43
48
  }
44
49
  }
50
+ /**
51
+ * Convenience helper to load a file into an AACTree using the inferred processor.
52
+ * @param file Path to the source file
53
+ * @param format Format key or extension (passed to getProcessor)
54
+ */
45
55
  function analyze(file, format) {
46
56
  const processor = getProcessor(format);
47
57
  const tree = processor.loadIntoTree(file);
@@ -20,6 +20,9 @@ export declare enum StringCasing {
20
20
  * @param text - The text to analyze for casing pattern
21
21
  * @returns StringCasing enum value representing the detected casing
22
22
  */
23
+ /**
24
+ * Infer the dominant casing style of a string (camel, pascal, snake, kebab, title, sentence, upper, lower).
25
+ */
23
26
  export declare function detectCasing(text: string): StringCasing;
24
27
  /**
25
28
  * Converts text to the specified casing
@@ -27,6 +30,11 @@ export declare function detectCasing(text: string): StringCasing;
27
30
  * @param targetCasing - The desired casing format
28
31
  * @returns The text converted to the target casing
29
32
  */
33
+ /**
34
+ * Convert a string into the requested casing style.
35
+ * @param text Input string
36
+ * @param targetCasing Desired casing variant
37
+ */
30
38
  export declare function convertCasing(text: string, targetCasing: StringCasing): string;
31
39
  /**
32
40
  * Utility function to check if text is primarily numeric or empty
@@ -34,4 +42,7 @@ export declare function convertCasing(text: string, targetCasing: StringCasing):
34
42
  * @param text - The text to check
35
43
  * @returns True if the text should be considered non-meaningful
36
44
  */
45
+ /**
46
+ * Check whether a string is empty or represents a numeric value.
47
+ */
37
48
  export declare function isNumericOrEmpty(text: string): boolean;
@@ -27,6 +27,9 @@ var StringCasing;
27
27
  * @param text - The text to analyze for casing pattern
28
28
  * @returns StringCasing enum value representing the detected casing
29
29
  */
30
+ /**
31
+ * Infer the dominant casing style of a string (camel, pascal, snake, kebab, title, sentence, upper, lower).
32
+ */
30
33
  function detectCasing(text) {
31
34
  if (!text || text.length === 0)
32
35
  return StringCasing.LOWER;
@@ -102,6 +105,11 @@ function detectCasing(text) {
102
105
  * @param targetCasing - The desired casing format
103
106
  * @returns The text converted to the target casing
104
107
  */
108
+ /**
109
+ * Convert a string into the requested casing style.
110
+ * @param text Input string
111
+ * @param targetCasing Desired casing variant
112
+ */
105
113
  function convertCasing(text, targetCasing) {
106
114
  if (!text || text.length === 0)
107
115
  return text;
@@ -164,6 +172,9 @@ function convertCasing(text, targetCasing) {
164
172
  * @param text - The text to check
165
173
  * @returns True if the text should be considered non-meaningful
166
174
  */
175
+ /**
176
+ * Check whether a string is empty or represents a numeric value.
177
+ */
167
178
  function isNumericOrEmpty(text) {
168
179
  const trimmed = text.trim();
169
180
  if (trimmed.length <= 1)
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './core/treeStructure';
2
2
  export * from './core/baseProcessor';
3
3
  export * from './core/stringCasing';
4
4
  export * from './processors';
5
+ export { collectUnifiedHistory, listGrid3Users as listHistoryGrid3Users, listSnapUsers as listHistorySnapUsers, } from './analytics/history';
5
6
  import { BaseProcessor } from './core/baseProcessor';
6
7
  /**
7
8
  * Factory function to get the appropriate processor for a file extension
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.listHistorySnapUsers = exports.listHistoryGrid3Users = exports.collectUnifiedHistory = void 0;
17
18
  exports.getProcessor = getProcessor;
18
19
  exports.getSupportedExtensions = getSupportedExtensions;
19
20
  exports.isExtensionSupported = isExtensionSupported;
@@ -22,6 +23,10 @@ __exportStar(require("./core/treeStructure"), exports);
22
23
  __exportStar(require("./core/baseProcessor"), exports);
23
24
  __exportStar(require("./core/stringCasing"), exports);
24
25
  __exportStar(require("./processors"), exports);
26
+ var history_1 = require("./analytics/history");
27
+ Object.defineProperty(exports, "collectUnifiedHistory", { enumerable: true, get: function () { return history_1.collectUnifiedHistory; } });
28
+ Object.defineProperty(exports, "listHistoryGrid3Users", { enumerable: true, get: function () { return history_1.listGrid3Users; } });
29
+ Object.defineProperty(exports, "listHistorySnapUsers", { enumerable: true, get: function () { return history_1.listSnapUsers; } });
25
30
  const dotProcessor_1 = require("./processors/dotProcessor");
26
31
  const excelProcessor_1 = require("./processors/excelProcessor");
27
32
  const opmlProcessor_1 = require("./processors/opmlProcessor");
@@ -1,6 +1,20 @@
1
1
  import { AACTree } from '../../core/treeStructure';
2
+ /**
3
+ * Build a map of button IDs to resolved image entry paths for a specific page.
4
+ * Helpful when rewriting zip entry names or validating images referenced in a grid.
5
+ */
2
6
  export declare function getPageTokenImageMap(tree: AACTree, pageId: string): Map<string, string>;
7
+ /**
8
+ * Collect all image entries referenced across every page in a tree.
9
+ * Returns normalized zip entry paths that should be preserved when pruning images.
10
+ */
3
11
  export declare function getAllowedImageEntries(tree: AACTree): Set<string>;
12
+ /**
13
+ * Read an image entry from a gridset zip by path.
14
+ * @param gridsetBuffer Gridset archive contents
15
+ * @param entryPath Entry name inside the zip
16
+ * @returns Image data buffer or null if not found
17
+ */
4
18
  export declare function openImage(gridsetBuffer: Buffer, entryPath: string): Buffer | null;
5
19
  /**
6
20
  * Generate a random GUID for Grid3 elements
@@ -32,3 +46,86 @@ export declare function createFileMapXml(grids: Array<{
32
46
  path: string;
33
47
  dynamicFiles?: string[];
34
48
  }>): string;
49
+ /**
50
+ * Grid3 user data path information
51
+ */
52
+ export interface Grid3UserPath {
53
+ userName: string;
54
+ langCode: string;
55
+ basePath: string;
56
+ historyDbPath: string;
57
+ }
58
+ export interface Grid3VocabularyPath {
59
+ userName: string;
60
+ gridsetPath: string;
61
+ }
62
+ export interface Grid3HistoryEntry {
63
+ id: string;
64
+ content: string;
65
+ occurrences: Array<{
66
+ timestamp: Date;
67
+ latitude?: number | null;
68
+ longitude?: number | null;
69
+ }>;
70
+ rawXml?: string;
71
+ }
72
+ /**
73
+ * Get the Windows Common Documents folder path from registry
74
+ * Falls back to default path if registry access fails
75
+ * @returns Path to Common Documents folder
76
+ */
77
+ export declare function getCommonDocumentsPath(): string;
78
+ /**
79
+ * Find all Grid3 user data paths
80
+ * Searches for users and language codes in the Grid3 directory structure
81
+ * C:\Users\Public\Documents\Smartbox\Grid 3\Users\{UserName}\{langCode}\Phrases\history.sqlite
82
+ * Grid set/vocabulary archives live alongside users at:
83
+ * C:\Users\Public\Documents\Smartbox\Grid 3\Users\{UserName}\Grid Sets\
84
+ * @returns Array of Grid3 user path information
85
+ */
86
+ export declare function findGrid3UserPaths(): Grid3UserPath[];
87
+ /**
88
+ * Find all Grid3 history database paths
89
+ * Convenience method that returns just the database file paths
90
+ * @returns Array of paths to history.sqlite files
91
+ */
92
+ export declare function findGrid3HistoryDatabases(): string[];
93
+ /**
94
+ * Get Grid 3 users (alias of findGrid3UserPaths for clarity)
95
+ */
96
+ export declare function findGrid3Users(): Grid3UserPath[];
97
+ /**
98
+ * Find Grid 3 gridset/vocabulary files for each user
99
+ * @param userName Optional user filter; matches case-insensitively
100
+ * @returns Array of user/gridset path pairs
101
+ */
102
+ export declare function findGrid3Vocabularies(userName?: string): Grid3VocabularyPath[];
103
+ /**
104
+ * Find a specific user's Grid 3 history database
105
+ * @param userName User name to search for (case-insensitive)
106
+ * @param langCode Optional language code filter (case-insensitive)
107
+ * @returns Path to history.sqlite or null if not found
108
+ */
109
+ export declare function findGrid3UserHistory(userName: string, langCode?: string): string | null;
110
+ /**
111
+ * Check whether Grid 3 appears to be installed (Windows only)
112
+ */
113
+ export declare function isGrid3Installed(): boolean;
114
+ /**
115
+ * Read history events from a Grid 3 history.sqlite database.
116
+ * @param historyDbPath Absolute path to the history database
117
+ * @returns Parsed history entries grouped by phrase
118
+ */
119
+ export declare function readGrid3History(historyDbPath: string): Grid3HistoryEntry[];
120
+ /**
121
+ * Convenience wrapper to load history for a specific Grid 3 user/lang combination.
122
+ * @param userName Grid 3 user name (case-insensitive)
123
+ * @param langCode Optional language code to narrow selection (case-insensitive)
124
+ * @returns History entries for that user/language, or empty array if none
125
+ */
126
+ export declare function readGrid3HistoryForUser(userName: string, langCode?: string): Grid3HistoryEntry[];
127
+ /**
128
+ * Load all available Grid 3 histories on the machine.
129
+ * @returns Combined history entries from every discovered history.sqlite
130
+ */
131
+ export declare function readAllGrid3History(): Grid3HistoryEntry[];