@defensestation/yjs-local-translator 0.3.0-dev.2.d2befbc

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 (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +519 -0
  3. package/dist/blocknote.d.ts +62 -0
  4. package/dist/blocknote.d.ts.map +1 -0
  5. package/dist/blocknote.js +379 -0
  6. package/dist/blocknote.js.map +1 -0
  7. package/dist/browser-translator.d.ts +81 -0
  8. package/dist/browser-translator.d.ts.map +1 -0
  9. package/dist/browser-translator.js +452 -0
  10. package/dist/browser-translator.js.map +1 -0
  11. package/dist/chunking.d.ts +16 -0
  12. package/dist/chunking.d.ts.map +1 -0
  13. package/dist/chunking.js +95 -0
  14. package/dist/chunking.js.map +1 -0
  15. package/dist/index.d.ts +7 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +7 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/metadata.d.ts +26 -0
  20. package/dist/metadata.d.ts.map +1 -0
  21. package/dist/metadata.js +41 -0
  22. package/dist/metadata.js.map +1 -0
  23. package/dist/model-catalog.d.ts +14 -0
  24. package/dist/model-catalog.d.ts.map +1 -0
  25. package/dist/model-catalog.js +41 -0
  26. package/dist/model-catalog.js.map +1 -0
  27. package/dist/native-translation.d.ts +37 -0
  28. package/dist/native-translation.d.ts.map +1 -0
  29. package/dist/native-translation.js +80 -0
  30. package/dist/native-translation.js.map +1 -0
  31. package/dist/protocol.d.ts +59 -0
  32. package/dist/protocol.d.ts.map +1 -0
  33. package/dist/protocol.js +2 -0
  34. package/dist/protocol.js.map +1 -0
  35. package/dist/translation-memory.d.ts +50 -0
  36. package/dist/translation-memory.d.ts.map +1 -0
  37. package/dist/translation-memory.js +117 -0
  38. package/dist/translation-memory.js.map +1 -0
  39. package/dist/translator.worker.d.ts +2 -0
  40. package/dist/translator.worker.d.ts.map +1 -0
  41. package/dist/translator.worker.js +304 -0
  42. package/dist/translator.worker.js.map +1 -0
  43. package/dist/yjs.d.ts +98 -0
  44. package/dist/yjs.d.ts.map +1 -0
  45. package/dist/yjs.js +291 -0
  46. package/dist/yjs.js.map +1 -0
  47. package/package.json +78 -0
@@ -0,0 +1,304 @@
1
+ /// <reference lib="webworker" />
2
+ import { DEFAULT_MAX_CHUNK_LENGTH, splitTextIntoChunks } from "./chunking.js";
3
+ import { getTranslationRoute } from "./model-catalog.js";
4
+ const DEFAULT_CONFIGURATION = {
5
+ transformersUrl: "https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.2.0/dist/transformers.min.js",
6
+ dtype: "int8",
7
+ device: "wasm",
8
+ graphOptimizationLevel: "disabled",
9
+ modelCatalog: {}
10
+ };
11
+ let configuration = DEFAULT_CONFIGURATION;
12
+ let transformersPromise;
13
+ let workQueue = Promise.resolve();
14
+ const activePipelines = new Map();
15
+ const loadingPipelines = new Map();
16
+ const cancelledRequests = new Set();
17
+ const activeStoppingCriteria = new Map();
18
+ function post(message) {
19
+ self.postMessage(message);
20
+ }
21
+ async function getTransformers() {
22
+ if (!transformersPromise) {
23
+ transformersPromise = import(
24
+ /* @vite-ignore */ configuration.transformersUrl);
25
+ }
26
+ const module = await transformersPromise;
27
+ module.env.allowLocalModels = false;
28
+ module.env.allowRemoteModels = true;
29
+ module.env.useBrowserCache = true;
30
+ return module;
31
+ }
32
+ function describeRoute(route) {
33
+ if (route.length === 0) {
34
+ return "The source and target languages are the same.";
35
+ }
36
+ if (route.length === 1) {
37
+ return `Using ${route[0]?.label ?? "the selected model"}.`;
38
+ }
39
+ return `Using ${route.map((step) => step.label).join(", then ")}.`;
40
+ }
41
+ async function unloadUnusedPipelines(requiredModelIds) {
42
+ const tasks = [];
43
+ for (const [modelId, translator] of activePipelines.entries()) {
44
+ if (requiredModelIds.has(modelId)) {
45
+ continue;
46
+ }
47
+ activePipelines.delete(modelId);
48
+ tasks.push(Promise.resolve(translator.dispose?.()).catch((error) => {
49
+ console.warn(`Could not dispose ${modelId}:`, error);
50
+ }));
51
+ }
52
+ await Promise.all(tasks);
53
+ }
54
+ async function unloadAllPipelines() {
55
+ await unloadUnusedPipelines(new Set());
56
+ }
57
+ async function loadPipeline(modelInfo, requestId) {
58
+ const active = activePipelines.get(modelInfo.id);
59
+ if (active) {
60
+ return active;
61
+ }
62
+ const loading = loadingPipelines.get(modelInfo.id);
63
+ if (loading) {
64
+ return loading;
65
+ }
66
+ post({
67
+ status: "loading",
68
+ requestId,
69
+ modelId: modelInfo.id,
70
+ message: `Loading ${modelInfo.label} model...`
71
+ });
72
+ const module = await getTransformers();
73
+ const lastProgressUpdateByFile = new Map();
74
+ const promise = module
75
+ .pipeline("translation", modelInfo.id, {
76
+ dtype: configuration.dtype,
77
+ device: configuration.device,
78
+ session_options: {
79
+ graphOptimizationLevel: configuration.graphOptimizationLevel
80
+ },
81
+ progress_callback: (progressInfo) => {
82
+ if (progressInfo.status !== "progress") {
83
+ return;
84
+ }
85
+ const file = typeof progressInfo.file === "string" ? progressInfo.file : "";
86
+ const now = Date.now();
87
+ const progress = Number(progressInfo.progress);
88
+ const isComplete = Number.isFinite(progress) && progress >= 100;
89
+ const lastUpdate = lastProgressUpdateByFile.get(file) ?? 0;
90
+ if (!isComplete && now - lastUpdate < 120) {
91
+ return;
92
+ }
93
+ lastProgressUpdateByFile.set(file, now);
94
+ post({
95
+ status: "progress",
96
+ requestId,
97
+ modelId: modelInfo.id,
98
+ message: `Downloading ${modelInfo.label} model...`,
99
+ ...(file ? { file } : {}),
100
+ ...(Number.isFinite(progress) ? { progress } : {}),
101
+ ...(typeof progressInfo.loaded === "number"
102
+ ? { loaded: progressInfo.loaded }
103
+ : {}),
104
+ ...(typeof progressInfo.total === "number"
105
+ ? { total: progressInfo.total }
106
+ : {})
107
+ });
108
+ }
109
+ })
110
+ .then((translator) => {
111
+ activePipelines.set(modelInfo.id, translator);
112
+ post({
113
+ status: "model-ready",
114
+ requestId,
115
+ modelId: modelInfo.id,
116
+ message: `${modelInfo.label} model is ready.`
117
+ });
118
+ return translator;
119
+ })
120
+ .finally(() => {
121
+ loadingPipelines.delete(modelInfo.id);
122
+ });
123
+ loadingPipelines.set(modelInfo.id, promise);
124
+ return promise;
125
+ }
126
+ function extractSingleTranslation(output) {
127
+ const first = Array.isArray(output) ? output[0] : output;
128
+ if (typeof first === "string") {
129
+ return first;
130
+ }
131
+ if (first &&
132
+ typeof first === "object" &&
133
+ "translation_text" in first &&
134
+ typeof first.translation_text === "string") {
135
+ return first.translation_text;
136
+ }
137
+ if (first &&
138
+ typeof first === "object" &&
139
+ "generated_text" in first &&
140
+ typeof first.generated_text === "string") {
141
+ return first.generated_text;
142
+ }
143
+ throw new Error("The translation model returned an unexpected response.");
144
+ }
145
+ async function translateOnce(translator, text, requestId, stream, stoppingCriteria) {
146
+ const module = await getTransformers();
147
+ let streamer;
148
+ if (stream) {
149
+ streamer = new module.TextStreamer(translator.tokenizer, {
150
+ skip_prompt: true,
151
+ skip_special_tokens: true,
152
+ callback_function(delta) {
153
+ if (!delta || cancelledRequests.has(requestId)) {
154
+ return;
155
+ }
156
+ post({ status: "partial", requestId, delta });
157
+ }
158
+ });
159
+ }
160
+ const generationOptions = {
161
+ ...(streamer ? { streamer } : {}),
162
+ ...(stoppingCriteria ? { stopping_criteria: stoppingCriteria } : {}),
163
+ ...(configuration.maxNewTokens === undefined
164
+ ? {}
165
+ : { max_new_tokens: configuration.maxNewTokens })
166
+ };
167
+ const output = await translator(text, generationOptions);
168
+ return extractSingleTranslation(output);
169
+ }
170
+ async function handleTranslation(message) {
171
+ const { requestId, text, sourceLanguage, targetLanguage } = message;
172
+ if (cancelledRequests.has(requestId)) {
173
+ return;
174
+ }
175
+ if (!text.trim()) {
176
+ throw new Error("Translation text must not be empty.");
177
+ }
178
+ const route = getTranslationRoute(sourceLanguage, targetLanguage, configuration.modelCatalog);
179
+ const modelIds = route.map((step) => step.id);
180
+ post({
181
+ status: "route",
182
+ requestId,
183
+ models: modelIds,
184
+ message: describeRoute(route)
185
+ });
186
+ if (route.length === 0) {
187
+ await unloadAllPipelines();
188
+ post({
189
+ status: "success",
190
+ requestId,
191
+ translation: text,
192
+ models: []
193
+ });
194
+ return;
195
+ }
196
+ await unloadUnusedPipelines(new Set(modelIds));
197
+ const loaded = [];
198
+ for (const modelInfo of route) {
199
+ loaded.push({
200
+ modelInfo,
201
+ translator: await loadPipeline(modelInfo, requestId)
202
+ });
203
+ }
204
+ const module = await getTransformers();
205
+ const stoppingCriteria = module.InterruptableStoppingCriteria
206
+ ? new module.InterruptableStoppingCriteria()
207
+ : undefined;
208
+ if (stoppingCriteria) {
209
+ activeStoppingCriteria.set(requestId, stoppingCriteria);
210
+ }
211
+ try {
212
+ const chunks = splitTextIntoChunks(text, configuration.maxChunkLength ?? DEFAULT_MAX_CHUNK_LENGTH);
213
+ const outputs = [];
214
+ for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex += 1) {
215
+ if (cancelledRequests.has(requestId)) {
216
+ return;
217
+ }
218
+ const chunk = chunks[chunkIndex];
219
+ if (!chunk) {
220
+ continue;
221
+ }
222
+ if (chunks.length > 1) {
223
+ post({
224
+ status: "processing",
225
+ requestId,
226
+ message: `Translating part ${chunkIndex + 1} of ${chunks.length}...`
227
+ });
228
+ }
229
+ let currentText = chunk.text;
230
+ for (let stepIndex = 0; stepIndex < loaded.length; stepIndex += 1) {
231
+ if (cancelledRequests.has(requestId)) {
232
+ return;
233
+ }
234
+ const step = loaded[stepIndex];
235
+ if (!step) {
236
+ continue;
237
+ }
238
+ const isFinalStep = stepIndex === loaded.length - 1;
239
+ if (chunks.length === 1) {
240
+ post({
241
+ status: "processing",
242
+ requestId,
243
+ modelId: step.modelInfo.id,
244
+ message: loaded.length === 1
245
+ ? "Translating..."
246
+ : `Translation step ${stepIndex + 1} of ${loaded.length}: ${step.modelInfo.label}...`
247
+ });
248
+ }
249
+ currentText = await translateOnce(step.translator, currentText, requestId, isFinalStep, stoppingCriteria);
250
+ }
251
+ if (cancelledRequests.has(requestId)) {
252
+ return;
253
+ }
254
+ outputs.push(currentText + chunk.separator);
255
+ if (chunk.separator) {
256
+ post({ status: "partial", requestId, delta: chunk.separator });
257
+ }
258
+ }
259
+ post({
260
+ status: "success",
261
+ requestId,
262
+ translation: outputs.join(""),
263
+ models: modelIds
264
+ });
265
+ }
266
+ finally {
267
+ activeStoppingCriteria.delete(requestId);
268
+ }
269
+ }
270
+ self.addEventListener("message", (event) => {
271
+ const message = event.data;
272
+ if (message.type === "configure") {
273
+ configuration = message.configuration;
274
+ return;
275
+ }
276
+ if (message.type === "cancel") {
277
+ cancelledRequests.add(message.requestId);
278
+ activeStoppingCriteria.get(message.requestId)?.interrupt();
279
+ // The matching translate job (if any) is already in the queue, so the
280
+ // flag can be swept once the queue drains past it.
281
+ workQueue = workQueue.then(() => {
282
+ cancelledRequests.delete(message.requestId);
283
+ });
284
+ return;
285
+ }
286
+ if (message.type === "unload-models") {
287
+ workQueue = workQueue.then(unloadAllPipelines);
288
+ return;
289
+ }
290
+ if (message.type !== "translate") {
291
+ return;
292
+ }
293
+ workQueue = workQueue
294
+ .then(() => handleTranslation(message))
295
+ .catch((error) => {
296
+ cancelledRequests.delete(message.requestId);
297
+ post({
298
+ status: "error",
299
+ requestId: message.requestId,
300
+ error: error instanceof Error ? error.message : String(error)
301
+ });
302
+ });
303
+ });
304
+ //# sourceMappingURL=translator.worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translator.worker.js","sourceRoot":"","sources":["../src/translator.worker.ts"],"names":[],"mappings":"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"}
package/dist/yjs.d.ts ADDED
@@ -0,0 +1,98 @@
1
+ import type { Map as YMap, Text as YText } from "yjs";
2
+ import type { BrowserTranslator, TranslateOptions, TranslationResult } from "./index.js";
3
+ export declare const YJS_TRANSLATION_ORIGIN: unique symbol;
4
+ export type ConflictPolicy = "abort" | "overwrite";
5
+ export declare class TranslationConflictError extends Error {
6
+ constructor(message?: string);
7
+ }
8
+ export interface TranslateYTextOptions extends TranslateOptions {
9
+ target?: YText;
10
+ conflictPolicy?: ConflictPolicy;
11
+ transactionOrigin?: unknown;
12
+ /**
13
+ * When metadataMap and metadataKey are both set, a TranslationMetadata
14
+ * record is written there in the same transaction as the translation, so
15
+ * staleness can be checked later with isTranslationStale.
16
+ */
17
+ metadataMap?: YMap<unknown>;
18
+ metadataKey?: string;
19
+ }
20
+ export interface TranslateYMapStringOptions extends TranslateOptions {
21
+ targetMap?: YMap<unknown>;
22
+ targetKey?: string;
23
+ conflictPolicy?: ConflictPolicy;
24
+ transactionOrigin?: unknown;
25
+ /**
26
+ * Whether to write a TranslationMetadata record next to the translation.
27
+ * Defaults to true when the translation is stored beside the source
28
+ * (different key or map) and false when the source is replaced in place,
29
+ * because an overwritten source leaves nothing to compare against.
30
+ */
31
+ storeMetadata?: boolean;
32
+ /** Key for the metadata record. Defaults to "<targetKey>:meta". */
33
+ metadataKey?: string;
34
+ }
35
+ /**
36
+ * Replaces the content of a Y.Text with a minimal edit: the longest common
37
+ * prefix and suffix are left untouched, so collaborator cursors and relative
38
+ * positions outside the changed region survive the update.
39
+ */
40
+ export declare function applyMinimalYTextEdit(target: YText, nextValue: string): void;
41
+ /**
42
+ * Translates a complete Y.Text value. Streamed deltas are delivered only to
43
+ * callbacks; the shared type is updated once, after the final output exists.
44
+ */
45
+ export declare function translateYText(translator: BrowserTranslator, source: YText, options: TranslateYTextOptions): Promise<TranslationResult>;
46
+ /**
47
+ * Translates a string stored in a Y.Map and writes the finished translation
48
+ * in one transaction. Use targetKey to keep the source and translation side
49
+ * by side instead of replacing the source value. When stored side by side, a
50
+ * metadata record is written under "<targetKey>:meta" so staleness can be
51
+ * detected after the source changes.
52
+ */
53
+ export declare function translateYMapString(translator: BrowserTranslator, sourceMap: YMap<unknown>, sourceKey: string, options: TranslateYMapStringOptions): Promise<TranslationResult>;
54
+ /**
55
+ * Returns true when the translation stored beside a Y.Map source value is
56
+ * missing or was produced from a different source text. Returns false when
57
+ * there is no source string to translate.
58
+ */
59
+ export declare function isYMapTranslationStale(map: YMap<unknown>, sourceKey: string, targetKey: string, metadataKey?: string): boolean;
60
+ export interface WatchOptions {
61
+ /** Idle time after the last source change before reacting. Default 1500. */
62
+ debounceMs?: number;
63
+ /** Retranslate automatically after the debounce. Default true. */
64
+ autoTranslate?: boolean;
65
+ /**
66
+ * React only to transactions made by this client. Default true, so in a
67
+ * collaborative document exactly one client (the author of the edit)
68
+ * retranslates instead of every connected client racing.
69
+ */
70
+ localOnly?: boolean;
71
+ /** Run once immediately after the watcher starts. Default false. */
72
+ immediate?: boolean;
73
+ onStale?: (sourceText: string) => void;
74
+ onTranslated?: (result: TranslationResult) => void;
75
+ onError?: (error: Error) => void;
76
+ }
77
+ export interface WatchYTextOptions extends Omit<TranslateYTextOptions, "signal" | "target">, WatchOptions {
78
+ /** Where the translation is written. Must differ from the source. */
79
+ target: YText;
80
+ }
81
+ export interface WatchYMapStringOptions extends Omit<TranslateYMapStringOptions, "signal" | "targetKey">, WatchOptions {
82
+ /** Key the translation is written to. Must differ from the source key. */
83
+ targetKey: string;
84
+ }
85
+ /**
86
+ * Observes a source Y.Text and keeps a target Y.Text translated. Changes are
87
+ * debounced, transactions written by the watcher itself are ignored, and by
88
+ * default only local edits trigger retranslation so a single client in a
89
+ * collaborative session does the work. Returns a stop function.
90
+ */
91
+ export declare function watchYText(translator: BrowserTranslator, source: YText, options: WatchYTextOptions): () => void;
92
+ /**
93
+ * Observes one string value in a Y.Map and keeps a translated value beside
94
+ * it. Same debounce, origin, and locality rules as watchYText. Returns a
95
+ * stop function.
96
+ */
97
+ export declare function watchYMapString(translator: BrowserTranslator, sourceMap: YMap<unknown>, sourceKey: string, options: WatchYMapStringOptions): () => void;
98
+ //# sourceMappingURL=yjs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yjs.d.ts","sourceRoot":"","sources":["../src/yjs.ts"],"names":[],"mappings":"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"}