@procore/ai-translations 0.1.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.
@@ -0,0 +1,367 @@
1
+ interface AITranslationContextValue {
2
+ ait: (text: string) => string;
3
+ isShowingTranslations: boolean;
4
+ toggleTranslations: () => void;
5
+ locale: string;
6
+ isTranslating: boolean;
7
+ renderVersion?: number;
8
+ initializeTranslators: (targetLanguages?: string[], sourceLanguages?: string[]) => Promise<void>;
9
+ isInitialized: boolean;
10
+ }
11
+
12
+ /**
13
+ * useAITranslation Hook
14
+ *
15
+ * Custom React hook to access the AI translation context and manage translation state.
16
+ * This hook provides access to translation functions, state, and utilities for
17
+ * managing translations in your React components.
18
+ *
19
+ * Key Features:
20
+ * - Access to `ait()` function for registering translatable strings
21
+ * - Toggle translations on/off
22
+ * - Check translation state (isShowingTranslations, isTranslating)
23
+ * - Initialize translators (required for first use)
24
+ * - Automatic re-rendering when translations update
25
+ *
26
+ * Usage:
27
+ * ```typescript
28
+ * function MyComponent() {
29
+ * const { ait, isShowingTranslations, toggleTranslations } = useAITranslation();
30
+ *
31
+ * return (
32
+ * <div>
33
+ * <h1>{ait("Welcome to our app")}</h1>
34
+ * <button onClick={toggleTranslations}>
35
+ * {isShowingTranslations ? 'Show Original' : 'Translate'}
36
+ * </button>
37
+ * </div>
38
+ * );
39
+ * }
40
+ * ```
41
+ *
42
+ * Initialization Example:
43
+ * ```typescript
44
+ * function TranslateButton() {
45
+ * const { initializeTranslators, isInitialized } = useAITranslation();
46
+ *
47
+ * const handleClick = async () => {
48
+ * if (!isInitialized) {
49
+ * await initializeTranslators(['es', 'fr'], ['en']);
50
+ * }
51
+ * };
52
+ *
53
+ * return <button onClick={handleClick}>Enable Translation</button>;
54
+ * }
55
+ * ```
56
+ *
57
+ * @throws {Error} If used outside of AITranslationProvider
58
+ * @returns {AITranslationContextValue} The translation context value with reactive render version
59
+ */
60
+ declare function useAITranslation(): AITranslationContextValue;
61
+
62
+ /**
63
+ * DataTable Translation Hook
64
+ *
65
+ * @module useDataTableAITranslation
66
+ * @description
67
+ * Specialized React hook for translating table data (AG Grid) with Chrome AI.
68
+ * Handles the complexity of translating dynamic table content, managing pagination,
69
+ * data changes, and field-level exclusions while maintaining optimal performance.
70
+ *
71
+ * ## Problem Solved
72
+ *
73
+ * Tables present unique translation challenges:
74
+ * - Data loads asynchronously (pagination, sorting, filtering)
75
+ * - New content appears without component remounts
76
+ * - Some fields shouldn't be translated (dates, IDs, technical fields)
77
+ * - Translation must not break table rendering or performance
78
+ * - Memory leaks from event listeners must be prevented
79
+ *
80
+ * This hook solves all these challenges with an intelligent translation system
81
+ * that automatically detects, translates, and applies translations to table data.
82
+ *
83
+ * ## Key Features
84
+ *
85
+ * 1. **Automatic String Registration**: All table cell text is registered for translation
86
+ * 2. **Field Exclusion**: Skip translation for datetime, ID, or custom fields
87
+ * 3. **Pagination Support**: Automatically translates new pages as they load
88
+ * 4. **Data Source Integration**: Listens to data events (loaded, changed)
89
+ * 5. **Progress Reporting**: Access global translation progress directly from the hook
90
+ * 6. **Memory Safe**: Prevents leaks with proper cleanup on unmount
91
+ * 7. **AG Grid Integration**: Direct integration with AG Grid's API
92
+ * 8. **Batch Translation**: Parallel translation for optimal performance
93
+ * 9. **Microtask Batching**: Catches late-loading rows with RAF timing
94
+ *
95
+ * ## Architecture
96
+ *
97
+ * The hook operates in phases:
98
+ *
99
+ * ### Registration Phase (Always Active)
100
+ * - As table renders, `ait()` is called on each cell value
101
+ * - Strings are registered in the string registry
102
+ * - Original values are preserved in `_originalLabel` properties
103
+ *
104
+ * ### Translation Phase (When Toggled ON)
105
+ * 1. Detect source language for each registered string
106
+ * 2. Filter out strings already in target language
107
+ * 3. Translate all strings in parallel batches
108
+ * 4. Update string registry with translations
109
+ * 5. Force table refresh to display translated content
110
+ *
111
+ * ### Update Phase (During Pagination/Data Changes)
112
+ * - New data triggers registration of new strings
113
+ * - If translations are active, automatically translates new strings
114
+ * - Applies translations and refreshes only affected cells
115
+ *
116
+ * ## Usage
117
+ *
118
+ * ### Basic Usage
119
+ * ```tsx
120
+ * import { useTableTranslation } from './ai-translations-package';
121
+ *
122
+ * function MyTable() {
123
+ * const tableApi = useTableApi();
124
+ * const fields = useFields();
125
+ *
126
+ * const {
127
+ * isShowingTranslations,
128
+ * toggleTranslations,
129
+ * isTranslating,
130
+ * translationProgress
131
+ * } = useTableTranslation({
132
+ * tableApi,
133
+ * fieldsIndex: fields,
134
+ * });
135
+ *
136
+ * return (
137
+ * <>
138
+ * <Button onClick={toggleTranslations} loading={isTranslating}>
139
+ * {isShowingTranslations ? 'Show Original' : 'Translate'}
140
+ * </Button>
141
+ * {translationProgress && (
142
+ * <span>Progress: {translationProgress.progress}%</span>
143
+ * )}
144
+ * <Table api={tableApi} />
145
+ * </>
146
+ * );
147
+ * }
148
+ * ```
149
+ *
150
+ * ### With Field Exclusions
151
+ * ```tsx
152
+ * const { toggleTranslations } = useTableTranslation({
153
+ * tableApi,
154
+ * fieldsIndex: fields,
155
+ * excludeFields: ['created_at', 'updated_at', 'id', 'code'],
156
+ * shouldExcludeField: (field) => field.type === 'datetime' || field.technical
157
+ * });
158
+ * ```
159
+ *
160
+ * ### With Progress Reporting
161
+ * ```tsx
162
+ * const {
163
+ * toggleTranslations,
164
+ * translationProgress
165
+ * } = useTableTranslation({
166
+ * tableApi,
167
+ * fieldsIndex: fields,
168
+ * });
169
+ *
170
+ * // Display global progress (no need to call useAITranslation separately!)
171
+ * {translationProgress && (
172
+ * <ProgressBar
173
+ * progress={translationProgress.progress}
174
+ * current={translationProgress.current}
175
+ * total={translationProgress.total}
176
+ * />
177
+ * )}
178
+ * ```
179
+ *
180
+ * ### With Data Source Integration
181
+ * ```tsx
182
+ * const dataSource = useDataSource();
183
+ *
184
+ * const { toggleTranslations } = useTableTranslation({
185
+ * tableApi,
186
+ * fieldsIndex: fields,
187
+ * dataSource, // Automatically handles pagination and view changes
188
+ * });
189
+ * ```
190
+ *
191
+ * ### Manual Data Loading
192
+ * ```tsx
193
+ * const { applyTranslationsToNewData } = useTableTranslation({
194
+ * tableApi,
195
+ * fieldsIndex: fields,
196
+ * });
197
+ *
198
+ * // Call when new data loads
199
+ * const handleDataLoaded = async () => {
200
+ * await applyTranslationsToNewData();
201
+ * };
202
+ * ```
203
+ *
204
+ * ## Field Exclusion
205
+ *
206
+ * By default, these fields are excluded from translation:
207
+ * - `created_at`, `updated_at`, `deleted_at`
208
+ * - `workflow_completion_date`, `workflow_step_due_date`
209
+ * - `received_date`, `date_required`, `private_at`
210
+ *
211
+ * ## Performance Considerations
212
+ *
213
+ * - **Parallel Translation**: All strings translate simultaneously
214
+ * - **Smart Caching**: Translations are cached in the string registry
215
+ * - **Incremental Updates**: Only new strings are translated on pagination
216
+ * - **Microtask Batching**: Multiple refreshes batched with RAF timing
217
+ * - **Memory Safe**: Cleanup prevents leaks from event listeners
218
+ *
219
+ * ## Integration with AG Grid
220
+ *
221
+ * The hook integrates directly with AG Grid's API:
222
+ * - `getRowData()`: Reads current row data for translation
223
+ * - `refreshCells()`: Forces cell updates after translation
224
+ * - `modelUpdated` event: Catches pagination/sorting/filtering
225
+ *
226
+ * It modifies row data in-place by:
227
+ * 1. Storing original values in `_originalLabel` properties
228
+ * 2. Updating `label` properties with translated text
229
+ * 3. Updating both `field.values` and `row[fieldId]` arrays
230
+ *
231
+ * ## Requirements
232
+ *
233
+ * - AG Grid table with `innerTableApi` property
234
+ * - Fields index with `byId` Map structure
235
+ * - Chrome browser with AI translation support
236
+ * - User gesture required for first translation
237
+ *
238
+ * @example
239
+ * // Complete example with all features
240
+ * const {
241
+ * isShowingTranslations,
242
+ * isTranslating,
243
+ * toggleTranslations,
244
+ * applyTranslationsToNewData,
245
+ * translationProgress
246
+ * } = useTableTranslation({
247
+ * tableApi,
248
+ * fieldsIndex: fields,
249
+ * excludeFields: ['created_at', 'id'],
250
+ * shouldExcludeField: (field) => field.type === 'datetime',
251
+ * dataSource: myDataSource,
252
+ * });
253
+ *
254
+ * // Display global translation progress directly from the hook
255
+ * {translationProgress && (
256
+ * <div>
257
+ * Progress: {translationProgress.progress}%
258
+ * ({translationProgress.current}/{translationProgress.total})
259
+ * </div>
260
+ * )}
261
+ */
262
+ declare function useDataTableAITranslation(): void;
263
+
264
+ /**
265
+ * AI Translation Provider
266
+ *
267
+ * @module AITranslationProvider
268
+ * @description
269
+ * Core provider component for Chrome AI-powered translations in React applications.
270
+ * Manages translation state, string registration, language detection, and translation execution.
271
+ *
272
+ * ## Architecture Overview
273
+ *
274
+ * This provider orchestrates several key components:
275
+ * - **String Registry**: Tracks all translatable strings and their states
276
+ * - **Chrome AI Client**: Interfaces with Chrome's built-in AI translation API
277
+ * - **Translation Service**: Handles translation requests with batching and caching
278
+ * - **Render Version Manager**: Forces component re-renders when translations update
279
+ *
280
+ * ## Key Features
281
+ *
282
+ * 1. **Automatic String Registration**: All strings passed through `ait()` are registered
283
+ * 2. **Language Detection**: Automatically detects source language using Chrome AI
284
+ * 3. **Batched Translation**: Efficiently translates multiple strings in parallel
285
+ * 4. **Toggle Mechanism**: Switch between original and translated content on-demand
286
+ * 5. **User Gesture Required**: Chrome AI initialization requires user interaction
287
+ * 6. **Pagination Support**: New content is automatically registered and translated
288
+ *
289
+ * ## Usage
290
+ *
291
+ * ```tsx
292
+ * import { AITranslationProvider } from './ai-translations-package';
293
+ *
294
+ * function App() {
295
+ * const handleProgress = (progress, current, total) => {
296
+ * console.log(`Translation progress: ${progress}% (${current}/${total})`);
297
+ * };
298
+ *
299
+ * return (
300
+ * <AITranslationProvider locale="es" onProgressChange={handleProgress}>
301
+ * <YourApp />
302
+ * </AITranslationProvider>
303
+ * );
304
+ * }
305
+ * ```
306
+ *
307
+ * ## Translation Workflow
308
+ *
309
+ * 1. **Registration Phase**: Strings are registered via `ait(text)` calls
310
+ * 2. **Initialization**: User clicks toggle (user gesture required for Chrome AI)
311
+ * 3. **Detection Phase**: Source languages are detected for all registered strings
312
+ * 4. **Translation Phase**: Strings are translated to target locale
313
+ * 5. **Display Phase**: Translations are displayed, original text on toggle off
314
+ *
315
+ * ## Context Value
316
+ *
317
+ * The provider exposes:
318
+ * - `ait`: Translation function - wrap strings with this
319
+ * - `isShowingTranslations`: Current display state
320
+ * - `toggleTranslations`: Toggle between original and translated content
321
+ * - `isTranslating`: Whether translations are in progress
322
+ * - `initializeTranslators`: Manual initialization for specific languages
323
+ * - `isInitialized`: Whether Chrome AI translators are ready
324
+ * - `locale`: Current target language
325
+ * - `translationProgress`: Global translation progress (progress %, current count, total count)
326
+ *
327
+ * ## Requirements
328
+ *
329
+ * - Chrome browser with AI translation API support
330
+ * - User gesture required for initial translator creation
331
+ * - Network connection for AI model downloads (first use)
332
+ *
333
+ * @example
334
+ * // Using the ait function in a component
335
+ * const { ait } = useAITranslation();
336
+ * return <h1>{ait('Hello World')}</h1>;
337
+ *
338
+ * @example
339
+ * // Displaying global translation progress
340
+ * const { translationProgress, toggleTranslations } = useAITranslation();
341
+ *
342
+ * return (
343
+ * <div>
344
+ * <button onClick={toggleTranslations}>Translate</button>
345
+ * {translationProgress && (
346
+ * <div>
347
+ * Translating: {translationProgress.current}/{translationProgress.total}
348
+ * ({translationProgress.progress}%)
349
+ * </div>
350
+ * )}
351
+ * </div>
352
+ * );
353
+ *
354
+ * @example
355
+ * // Manual initialization with specific languages
356
+ * const { initializeTranslators, toggleTranslations } = useAITranslation();
357
+ *
358
+ * <button onClick={async () => {
359
+ * await initializeTranslators(['es', 'fr'], ['en', 'de']);
360
+ * await toggleTranslations();
361
+ * }}>
362
+ * Translate to Spanish/French
363
+ * </button>
364
+ */
365
+ declare function AITranslationProvider(): void;
366
+
367
+ export { AITranslationProvider, useAITranslation, useDataTableAITranslation };
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AITranslationProvider: () => AITranslationProvider,
24
+ useAITranslation: () => useAITranslation,
25
+ useDataTableAITranslation: () => useDataTableAITranslation
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+
29
+ // src/hooks/useAiTranslation.tsx
30
+ function useAITranslation() {
31
+ return {
32
+ ait: () => "",
33
+ isShowingTranslations: false,
34
+ toggleTranslations: () => {
35
+ },
36
+ locale: "",
37
+ isTranslating: false,
38
+ renderVersion: void 0,
39
+ initializeTranslators: async () => {
40
+ },
41
+ isInitialized: false
42
+ };
43
+ }
44
+
45
+ // src/hooks/useDataTableAITranslation.tsx
46
+ function useDataTableAITranslation() {
47
+ }
48
+
49
+ // src/Provider.tsx
50
+ function AITranslationProvider() {
51
+ }
52
+ // Annotate the CommonJS export names for ESM import in node:
53
+ 0 && (module.exports = {
54
+ AITranslationProvider,
55
+ useAITranslation,
56
+ useDataTableAITranslation
57
+ });
@@ -0,0 +1,28 @@
1
+ // src/hooks/useAiTranslation.tsx
2
+ function useAITranslation() {
3
+ return {
4
+ ait: () => "",
5
+ isShowingTranslations: false,
6
+ toggleTranslations: () => {
7
+ },
8
+ locale: "",
9
+ isTranslating: false,
10
+ renderVersion: void 0,
11
+ initializeTranslators: async () => {
12
+ },
13
+ isInitialized: false
14
+ };
15
+ }
16
+
17
+ // src/hooks/useDataTableAITranslation.tsx
18
+ function useDataTableAITranslation() {
19
+ }
20
+
21
+ // src/Provider.tsx
22
+ function AITranslationProvider() {
23
+ }
24
+ export {
25
+ AITranslationProvider,
26
+ useAITranslation,
27
+ useDataTableAITranslation
28
+ };