@lionrapid/core 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.
- package/README.md +106 -0
- package/dist/base/event-emitter.d.ts +91 -0
- package/dist/base/event-emitter.d.ts.map +1 -0
- package/dist/base/event-emitter.js +330 -0
- package/dist/base/event-emitter.js.map +1 -0
- package/dist/base/index.d.ts +5 -0
- package/dist/base/index.d.ts.map +1 -0
- package/dist/base/index.js +5 -0
- package/dist/base/index.js.map +1 -0
- package/dist/browser/auto-init.d.ts +57 -0
- package/dist/browser/auto-init.d.ts.map +1 -0
- package/dist/browser/auto-init.js +304 -0
- package/dist/browser/auto-init.js.map +1 -0
- package/dist/browser/auto-translator.d.ts +98 -0
- package/dist/browser/auto-translator.d.ts.map +1 -0
- package/dist/browser/auto-translator.js +218 -0
- package/dist/browser/auto-translator.js.map +1 -0
- package/dist/browser/block-extractor.d.ts +26 -0
- package/dist/browser/block-extractor.d.ts.map +1 -0
- package/dist/browser/block-extractor.js +143 -0
- package/dist/browser/block-extractor.js.map +1 -0
- package/dist/browser/dom-observer.d.ts +42 -0
- package/dist/browser/dom-observer.d.ts.map +1 -0
- package/dist/browser/dom-observer.js +109 -0
- package/dist/browser/dom-observer.js.map +1 -0
- package/dist/browser/editor/editor-api.d.ts +67 -0
- package/dist/browser/editor/editor-api.d.ts.map +1 -0
- package/dist/browser/editor/editor-api.js +233 -0
- package/dist/browser/editor/editor-api.js.map +1 -0
- package/dist/browser/editor/editor-init.d.ts +11 -0
- package/dist/browser/editor/editor-init.d.ts.map +1 -0
- package/dist/browser/editor/editor-init.js +181 -0
- package/dist/browser/editor/editor-init.js.map +1 -0
- package/dist/browser/editor/editor-styles.d.ts +6 -0
- package/dist/browser/editor/editor-styles.d.ts.map +1 -0
- package/dist/browser/editor/editor-styles.js +419 -0
- package/dist/browser/editor/editor-styles.js.map +1 -0
- package/dist/browser/editor/inspector.d.ts +22 -0
- package/dist/browser/editor/inspector.d.ts.map +1 -0
- package/dist/browser/editor/inspector.js +125 -0
- package/dist/browser/editor/inspector.js.map +1 -0
- package/dist/browser/editor/key-resolver.d.ts +19 -0
- package/dist/browser/editor/key-resolver.d.ts.map +1 -0
- package/dist/browser/editor/key-resolver.js +49 -0
- package/dist/browser/editor/key-resolver.js.map +1 -0
- package/dist/browser/editor/live-preview.d.ts +10 -0
- package/dist/browser/editor/live-preview.d.ts.map +1 -0
- package/dist/browser/editor/live-preview.js +57 -0
- package/dist/browser/editor/live-preview.js.map +1 -0
- package/dist/browser/editor/sidebar.d.ts +50 -0
- package/dist/browser/editor/sidebar.d.ts.map +1 -0
- package/dist/browser/editor/sidebar.js +353 -0
- package/dist/browser/editor/sidebar.js.map +1 -0
- package/dist/browser/editor/toolbar.d.ts +29 -0
- package/dist/browser/editor/toolbar.d.ts.map +1 -0
- package/dist/browser/editor/toolbar.js +131 -0
- package/dist/browser/editor/toolbar.js.map +1 -0
- package/dist/browser/exclude-filter.d.ts +21 -0
- package/dist/browser/exclude-filter.d.ts.map +1 -0
- package/dist/browser/exclude-filter.js +51 -0
- package/dist/browser/exclude-filter.js.map +1 -0
- package/dist/browser/index.d.ts +32 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +28 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/language-switcher.d.ts +70 -0
- package/dist/browser/language-switcher.d.ts.map +1 -0
- package/dist/browser/language-switcher.js +339 -0
- package/dist/browser/language-switcher.js.map +1 -0
- package/dist/browser/lionrapid.auto.dev.js +5757 -0
- package/dist/browser/lionrapid.auto.dev.js.map +7 -0
- package/dist/browser/lionrapid.auto.js +5757 -0
- package/dist/browser/lionrapid.auto.js.map +7 -0
- package/dist/browser/lionrapid.auto.min.js +80 -0
- package/dist/browser/lionrapid.auto.min.js.map +7 -0
- package/dist/browser/lionrapid.editor.js +1869 -0
- package/dist/browser/lionrapid.editor.js.map +7 -0
- package/dist/browser/lionrapid.editor.min.js +415 -0
- package/dist/browser/lionrapid.editor.min.js.map +7 -0
- package/dist/browser/lionrapid.esm.js +4786 -0
- package/dist/browser/lionrapid.esm.js.map +7 -0
- package/dist/browser/lionrapid.esm.min.js +3 -0
- package/dist/browser/lionrapid.esm.min.js.map +7 -0
- package/dist/browser/lionrapid.iife.dev.js +4809 -0
- package/dist/browser/lionrapid.iife.dev.js.map +7 -0
- package/dist/browser/lionrapid.iife.js +4809 -0
- package/dist/browser/lionrapid.iife.js.map +7 -0
- package/dist/browser/lionrapid.iife.min.js +3 -0
- package/dist/browser/lionrapid.iife.min.js.map +7 -0
- package/dist/browser/lionrapid.umd.js +4822 -0
- package/dist/browser/lionrapid.umd.js.map +7 -0
- package/dist/browser/lionrapid.umd.min.js +18 -0
- package/dist/browser/lionrapid.umd.min.js.map +7 -0
- package/dist/browser/markup-parser.d.ts +13 -0
- package/dist/browser/markup-parser.d.ts.map +1 -0
- package/dist/browser/markup-parser.js +56 -0
- package/dist/browser/markup-parser.js.map +1 -0
- package/dist/browser/md5.d.ts +16 -0
- package/dist/browser/md5.d.ts.map +1 -0
- package/dist/browser/md5.js +145 -0
- package/dist/browser/md5.js.map +1 -0
- package/dist/browser/storage/cache-storage-repository.d.ts +44 -0
- package/dist/browser/storage/cache-storage-repository.d.ts.map +1 -0
- package/dist/browser/storage/cache-storage-repository.js +186 -0
- package/dist/browser/storage/cache-storage-repository.js.map +1 -0
- package/dist/browser/storage/localstorage-repository.d.ts +51 -0
- package/dist/browser/storage/localstorage-repository.d.ts.map +1 -0
- package/dist/browser/storage/localstorage-repository.js +270 -0
- package/dist/browser/storage/localstorage-repository.js.map +1 -0
- package/dist/builder.d.ts +24 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +169 -0
- package/dist/builder.js.map +1 -0
- package/dist/cache/CacheManager.d.ts +132 -0
- package/dist/cache/CacheManager.d.ts.map +1 -0
- package/dist/cache/CacheManager.js +277 -0
- package/dist/cache/CacheManager.js.map +1 -0
- package/dist/cache/index.d.ts +6 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +5 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +6 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/lionrapid.config.d.ts +12 -0
- package/dist/config/lionrapid.config.d.ts.map +1 -0
- package/dist/config/lionrapid.config.js +2 -0
- package/dist/config/lionrapid.config.js.map +1 -0
- package/dist/config/logger.config.d.ts +19 -0
- package/dist/config/logger.config.d.ts.map +1 -0
- package/dist/config/logger.config.js +9 -0
- package/dist/config/logger.config.js.map +1 -0
- package/dist/config/repository.config.d.ts +87 -0
- package/dist/config/repository.config.d.ts.map +1 -0
- package/dist/config/repository.config.js +5 -0
- package/dist/config/repository.config.js.map +1 -0
- package/dist/content/index.d.ts +20 -0
- package/dist/content/index.d.ts.map +1 -0
- package/dist/content/index.js +13 -0
- package/dist/content/index.js.map +1 -0
- package/dist/content/parser/IParser.d.ts +33 -0
- package/dist/content/parser/IParser.d.ts.map +1 -0
- package/dist/content/parser/IParser.js +6 -0
- package/dist/content/parser/IParser.js.map +1 -0
- package/dist/content/parser/MarkupParser.d.ts +67 -0
- package/dist/content/parser/MarkupParser.d.ts.map +1 -0
- package/dist/content/parser/MarkupParser.js +231 -0
- package/dist/content/parser/MarkupParser.js.map +1 -0
- package/dist/content/serializer/HTMLSerializer.d.ts +61 -0
- package/dist/content/serializer/HTMLSerializer.d.ts.map +1 -0
- package/dist/content/serializer/HTMLSerializer.js +100 -0
- package/dist/content/serializer/HTMLSerializer.js.map +1 -0
- package/dist/content/serializer/ISerializer.d.ts +33 -0
- package/dist/content/serializer/ISerializer.d.ts.map +1 -0
- package/dist/content/serializer/ISerializer.js +6 -0
- package/dist/content/serializer/ISerializer.js.map +1 -0
- package/dist/content/style-mapper/DefaultStyleMapper.d.ts +59 -0
- package/dist/content/style-mapper/DefaultStyleMapper.d.ts.map +1 -0
- package/dist/content/style-mapper/DefaultStyleMapper.js +128 -0
- package/dist/content/style-mapper/DefaultStyleMapper.js.map +1 -0
- package/dist/content/style-mapper/IStyleMapper.d.ts +50 -0
- package/dist/content/style-mapper/IStyleMapper.d.ts.map +1 -0
- package/dist/content/style-mapper/IStyleMapper.js +6 -0
- package/dist/content/style-mapper/IStyleMapper.js.map +1 -0
- package/dist/content/types.d.ts +39 -0
- package/dist/content/types.d.ts.map +1 -0
- package/dist/content/types.js +6 -0
- package/dist/content/types.js.map +1 -0
- package/dist/content/validator/ContentValidator.d.ts +57 -0
- package/dist/content/validator/ContentValidator.d.ts.map +1 -0
- package/dist/content/validator/ContentValidator.js +215 -0
- package/dist/content/validator/ContentValidator.js.map +1 -0
- package/dist/content/validator/IValidator.d.ts +82 -0
- package/dist/content/validator/IValidator.d.ts.map +1 -0
- package/dist/content/validator/IValidator.js +6 -0
- package/dist/content/validator/IValidator.js.map +1 -0
- package/dist/errors/translation-errors.d.ts +55 -0
- package/dist/errors/translation-errors.d.ts.map +1 -0
- package/dist/errors/translation-errors.js +85 -0
- package/dist/errors/translation-errors.js.map +1 -0
- package/dist/handlers/async-storage-handler.d.ts +77 -0
- package/dist/handlers/async-storage-handler.d.ts.map +1 -0
- package/dist/handlers/async-storage-handler.js +239 -0
- package/dist/handlers/async-storage-handler.js.map +1 -0
- package/dist/handlers/handler-chain.d.ts +79 -0
- package/dist/handlers/handler-chain.d.ts.map +1 -0
- package/dist/handlers/handler-chain.js +366 -0
- package/dist/handlers/handler-chain.js.map +1 -0
- package/dist/handlers/index.d.ts +7 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +7 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/network-handler.d.ts +90 -0
- package/dist/handlers/network-handler.d.ts.map +1 -0
- package/dist/handlers/network-handler.js +283 -0
- package/dist/handlers/network-handler.js.map +1 -0
- package/dist/handlers/sync-storage-handler.d.ts +88 -0
- package/dist/handlers/sync-storage-handler.d.ts.map +1 -0
- package/dist/handlers/sync-storage-handler.js +270 -0
- package/dist/handlers/sync-storage-handler.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/emitter.interface.d.ts +33 -0
- package/dist/interfaces/emitter.interface.d.ts.map +1 -0
- package/dist/interfaces/emitter.interface.js +2 -0
- package/dist/interfaces/emitter.interface.js.map +1 -0
- package/dist/interfaces/handler.interface.d.ts +50 -0
- package/dist/interfaces/handler.interface.d.ts.map +1 -0
- package/dist/interfaces/handler.interface.js +5 -0
- package/dist/interfaces/handler.interface.js.map +1 -0
- package/dist/interfaces/index.d.ts +8 -0
- package/dist/interfaces/index.d.ts.map +1 -0
- package/dist/interfaces/index.js +8 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/plugin.interface.d.ts +49 -0
- package/dist/interfaces/plugin.interface.d.ts.map +1 -0
- package/dist/interfaces/plugin.interface.js +6 -0
- package/dist/interfaces/plugin.interface.js.map +1 -0
- package/dist/interfaces/repository.interface.d.ts +56 -0
- package/dist/interfaces/repository.interface.d.ts.map +1 -0
- package/dist/interfaces/repository.interface.js +2 -0
- package/dist/interfaces/repository.interface.js.map +1 -0
- package/dist/lionRapid.d.ts +225 -0
- package/dist/lionRapid.d.ts.map +1 -0
- package/dist/lionRapid.js +596 -0
- package/dist/lionRapid.js.map +1 -0
- package/dist/repositories/index.d.ts +3 -0
- package/dist/repositories/index.d.ts.map +1 -0
- package/dist/repositories/index.js +3 -0
- package/dist/repositories/index.js.map +1 -0
- package/dist/repositories/memory-repository.d.ts +30 -0
- package/dist/repositories/memory-repository.d.ts.map +1 -0
- package/dist/repositories/memory-repository.js +100 -0
- package/dist/repositories/memory-repository.js.map +1 -0
- package/dist/repositories/network-repository.d.ts +138 -0
- package/dist/repositories/network-repository.d.ts.map +1 -0
- package/dist/repositories/network-repository.js +516 -0
- package/dist/repositories/network-repository.js.map +1 -0
- package/dist/sync/missing-translation-queue.d.ts +64 -0
- package/dist/sync/missing-translation-queue.d.ts.map +1 -0
- package/dist/sync/missing-translation-queue.js +184 -0
- package/dist/sync/missing-translation-queue.js.map +1 -0
- package/dist/types/cache.types.d.ts +62 -0
- package/dist/types/cache.types.d.ts.map +1 -0
- package/dist/types/cache.types.js +6 -0
- package/dist/types/cache.types.js.map +1 -0
- package/dist/types/event-payloads.types.d.ts +46 -0
- package/dist/types/event-payloads.types.d.ts.map +1 -0
- package/dist/types/event-payloads.types.js +6 -0
- package/dist/types/event-payloads.types.js.map +1 -0
- package/dist/types/generated.types.d.ts +31 -0
- package/dist/types/generated.types.d.ts.map +1 -0
- package/dist/types/generated.types.js +6 -0
- package/dist/types/generated.types.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/lionRapid.types.d.ts +169 -0
- package/dist/types/lionRapid.types.d.ts.map +1 -0
- package/dist/types/lionRapid.types.js +8 -0
- package/dist/types/lionRapid.types.js.map +1 -0
- package/dist/types/parameters.types.d.ts +36 -0
- package/dist/types/parameters.types.d.ts.map +1 -0
- package/dist/types/parameters.types.js +6 -0
- package/dist/types/parameters.types.js.map +1 -0
- package/dist/types/translation-data.types.d.ts +54 -0
- package/dist/types/translation-data.types.d.ts.map +1 -0
- package/dist/types/translation-data.types.js +6 -0
- package/dist/types/translation-data.types.js.map +1 -0
- package/dist/types/translation.types.d.ts +94 -0
- package/dist/types/translation.types.d.ts.map +1 -0
- package/dist/types/translation.types.js +5 -0
- package/dist/types/translation.types.js.map +1 -0
- package/dist/utils/context-utils.d.ts +23 -0
- package/dist/utils/context-utils.d.ts.map +1 -0
- package/dist/utils/context-utils.js +36 -0
- package/dist/utils/context-utils.js.map +1 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +19 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +229 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +345 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/namespace-utils.d.ts +30 -0
- package/dist/utils/namespace-utils.d.ts.map +1 -0
- package/dist/utils/namespace-utils.js +56 -0
- package/dist/utils/namespace-utils.js.map +1 -0
- package/dist/utils/translation-flow.d.ts +18 -0
- package/dist/utils/translation-flow.d.ts.map +1 -0
- package/dist/utils/translation-flow.js +74 -0
- package/dist/utils/translation-flow.js.map +1 -0
- package/dist/utils/translation-value-utils.d.ts +57 -0
- package/dist/utils/translation-value-utils.d.ts.map +1 -0
- package/dist/utils/translation-value-utils.js +194 -0
- package/dist/utils/translation-value-utils.js.map +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API repository - Simple HTTP data access layer
|
|
3
|
+
* No business logic - just GET/POST operations
|
|
4
|
+
*
|
|
5
|
+
* Server always returns ContentUnit format: { text, styles }
|
|
6
|
+
*/
|
|
7
|
+
import { NetworkError, ServerError, TranslationLockedError, TranslationNotFoundError, } from '../errors/translation-errors.js';
|
|
8
|
+
import { logger } from '../utils/logger.js';
|
|
9
|
+
/**
|
|
10
|
+
* API repository implementation
|
|
11
|
+
* Pure data access - no caching, no business logic
|
|
12
|
+
*/
|
|
13
|
+
export class NetworkRepository {
|
|
14
|
+
name = 'NetworkRepository';
|
|
15
|
+
type = 'network';
|
|
16
|
+
config = {};
|
|
17
|
+
/** Cached version (opaque string from server) per namespace key "locale:namespace" */
|
|
18
|
+
namespaceVersions = new Map();
|
|
19
|
+
/** localStorage key prefix for persisted versions */
|
|
20
|
+
static VERSION_PREFIX = 'lionrapid:v:';
|
|
21
|
+
/**
|
|
22
|
+
* Default endpoint templates with placeholder support
|
|
23
|
+
* Placeholders: :key, :locale, :namespace
|
|
24
|
+
*/
|
|
25
|
+
DEFAULT_ENDPOINTS = {
|
|
26
|
+
getTranslation: '/api/integrations/translations/:key',
|
|
27
|
+
getNamespace: '/api/integrations/translations/:locale/:namespace',
|
|
28
|
+
setTranslation: '/api/integrations/sync/:key',
|
|
29
|
+
setNamespace: '/api/integrations/sync/:locale/:namespace',
|
|
30
|
+
setBatch: '/api/integrations/sync/batch',
|
|
31
|
+
removeTranslation: '/api/integrations/sync/:key',
|
|
32
|
+
clearTranslations: '/translations',
|
|
33
|
+
};
|
|
34
|
+
constructor(config = {}) {
|
|
35
|
+
this.config = {
|
|
36
|
+
options: {
|
|
37
|
+
timeout: config.options?.timeout ?? 5000,
|
|
38
|
+
baseUrl: config.options?.baseUrl ?? '',
|
|
39
|
+
headers: config.options?.headers ?? {},
|
|
40
|
+
},
|
|
41
|
+
...config,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get single translation from API
|
|
46
|
+
* Uses platform-specific integration endpoint
|
|
47
|
+
* @throws {TranslationNotFoundError} When translation doesn't exist (404)
|
|
48
|
+
* @throws {TranslationLockedError} When translation is locked/not ready (423)
|
|
49
|
+
* @throws {ServerError} When server returns 5xx error
|
|
50
|
+
* @throws {NetworkError} When network request fails
|
|
51
|
+
*/
|
|
52
|
+
async get(key) {
|
|
53
|
+
if (!this.config?.options?.baseUrl) {
|
|
54
|
+
logger.debug('API base URL is not set');
|
|
55
|
+
throw new NetworkError('API base URL is not set');
|
|
56
|
+
}
|
|
57
|
+
const url = this.buildUrl('getTranslation', { key });
|
|
58
|
+
logger.debug(`API GET: ${url}`);
|
|
59
|
+
try {
|
|
60
|
+
const response = await this.makeRequest(url, 'GET');
|
|
61
|
+
if (!response.ok) {
|
|
62
|
+
this.handleHttpError(response, key);
|
|
63
|
+
}
|
|
64
|
+
const data = await response.json();
|
|
65
|
+
logger.debug('API response data:', data);
|
|
66
|
+
// Try multiple key formats: meta.key, original key, or first translation
|
|
67
|
+
const translation = data.translations[data.meta?.key]
|
|
68
|
+
|| data.translations[key]
|
|
69
|
+
|| Object.values(data.translations)[0];
|
|
70
|
+
logger.debug(`Fetched translation for key "${key}":`, translation);
|
|
71
|
+
if (!translation) {
|
|
72
|
+
throw new TranslationNotFoundError(key);
|
|
73
|
+
}
|
|
74
|
+
// Handle both ContentUnit format and plain string
|
|
75
|
+
if (typeof translation === 'object' && 'text' in translation) {
|
|
76
|
+
logger.debug(`ContentUnit text: "${translation.text}"`);
|
|
77
|
+
return translation.text;
|
|
78
|
+
}
|
|
79
|
+
return String(translation);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
this.handleCaughtError(error);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get single translation as full ContentUnit (with styles)
|
|
87
|
+
* Used by NetworkHandler for individual key lookups that need styles
|
|
88
|
+
* @throws {TranslationNotFoundError} When translation doesn't exist (404)
|
|
89
|
+
* @throws {TranslationLockedError} When translation is locked/not ready (423)
|
|
90
|
+
* @throws {ServerError} When server returns 5xx error
|
|
91
|
+
* @throws {NetworkError} When network request fails
|
|
92
|
+
*/
|
|
93
|
+
async getContentUnit(key) {
|
|
94
|
+
if (!this.config?.options?.baseUrl) {
|
|
95
|
+
logger.debug('API base URL is not set');
|
|
96
|
+
throw new NetworkError('API base URL is not set');
|
|
97
|
+
}
|
|
98
|
+
const url = this.buildUrl('getTranslation', { key });
|
|
99
|
+
logger.debug(`API GET ContentUnit: ${url}`);
|
|
100
|
+
try {
|
|
101
|
+
const response = await this.makeRequest(url, 'GET');
|
|
102
|
+
if (!response.ok) {
|
|
103
|
+
this.handleHttpError(response, key);
|
|
104
|
+
}
|
|
105
|
+
const data = await response.json();
|
|
106
|
+
logger.debug('API response data:', data);
|
|
107
|
+
// Try multiple key formats: meta.key, original key, or first translation
|
|
108
|
+
const translation = data.translations[data.meta?.key]
|
|
109
|
+
|| data.translations[key]
|
|
110
|
+
|| Object.values(data.translations)[0];
|
|
111
|
+
if (!translation) {
|
|
112
|
+
throw new TranslationNotFoundError(key);
|
|
113
|
+
}
|
|
114
|
+
// Handle both ContentUnit format and plain string
|
|
115
|
+
if (typeof translation === 'object' && 'text' in translation) {
|
|
116
|
+
// Server returned ContentUnit format
|
|
117
|
+
logger.debug(`ContentUnit for "${key}": text="${translation.text}", styles=`, translation.styles);
|
|
118
|
+
return {
|
|
119
|
+
text: translation.text,
|
|
120
|
+
styles: translation.styles || {},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
// Server returned plain string - wrap in ContentUnit
|
|
124
|
+
logger.debug(`Plain string for "${key}": "${translation}" (no styles)`);
|
|
125
|
+
return {
|
|
126
|
+
text: String(translation),
|
|
127
|
+
styles: {},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
this.handleCaughtError(error);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Get namespace with all translations
|
|
136
|
+
* @throws {TranslationNotFoundError} When namespace doesn't exist (404)
|
|
137
|
+
* @throws {TranslationLockedError} When namespace is locked/not ready (423)
|
|
138
|
+
* @throws {ServerError} When server returns 5xx error
|
|
139
|
+
* @throws {NetworkError} When network request fails
|
|
140
|
+
*/
|
|
141
|
+
async getNamespace(locale, namespace) {
|
|
142
|
+
if (!this.config?.options?.baseUrl) {
|
|
143
|
+
logger.debug('API base URL is not set');
|
|
144
|
+
throw new NetworkError('API base URL is not set');
|
|
145
|
+
}
|
|
146
|
+
const url = this.buildUrl('getNamespace', { locale, namespace });
|
|
147
|
+
logger.debug(`API GET Namespace: ${url}`);
|
|
148
|
+
const namespaceKey = `${locale}:${namespace}`;
|
|
149
|
+
try {
|
|
150
|
+
// Send If-None-Match for conditional request
|
|
151
|
+
const extraHeaders = {};
|
|
152
|
+
const cachedVersion = this.getVersion(namespaceKey);
|
|
153
|
+
if (cachedVersion) {
|
|
154
|
+
extraHeaders['If-None-Match'] = `W/"${cachedVersion}"`;
|
|
155
|
+
}
|
|
156
|
+
const response = await this.makeRequest(url, 'GET', undefined, extraHeaders);
|
|
157
|
+
// 304 Not Modified — cached translations are still fresh
|
|
158
|
+
if (response.status === 304) {
|
|
159
|
+
logger.debug(`Namespace ${namespaceKey}: 304 Not Modified`);
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
if (!response.ok) {
|
|
163
|
+
this.handleHttpError(response, namespaceKey);
|
|
164
|
+
}
|
|
165
|
+
const data = await response.json();
|
|
166
|
+
logger.debug('API response data:', data);
|
|
167
|
+
if (!data.translations) {
|
|
168
|
+
throw new TranslationNotFoundError(namespaceKey);
|
|
169
|
+
}
|
|
170
|
+
// Track version for future conditional requests (memory + localStorage)
|
|
171
|
+
const version = data.meta?.version != null ? String(data.meta.version) : null;
|
|
172
|
+
if (version) {
|
|
173
|
+
this.setVersion(namespaceKey, version);
|
|
174
|
+
}
|
|
175
|
+
return data.translations;
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
this.handleCaughtError(error);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Save translation to API (if supported)
|
|
183
|
+
*/
|
|
184
|
+
async set(key, value) {
|
|
185
|
+
if (!this.config?.options?.baseUrl) {
|
|
186
|
+
logger.debug('API base URL is not set');
|
|
187
|
+
return Promise.reject(new Error('API base URL is not set'));
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
const url = this.buildUrl('setTranslation', { key });
|
|
191
|
+
const response = await this.makeRequest(url, 'PUT', {
|
|
192
|
+
translation: value,
|
|
193
|
+
});
|
|
194
|
+
if (!response.ok) {
|
|
195
|
+
throw new Error(`Failed to save translation: ${response.status}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
logger.debug(`API set failed for key "${key}":`, error);
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async setNamespace(locale, namespace, translations) {
|
|
204
|
+
if (!this.config?.options?.baseUrl) {
|
|
205
|
+
logger.debug('API base URL is not set');
|
|
206
|
+
return Promise.reject(new Error('API base URL is not set'));
|
|
207
|
+
}
|
|
208
|
+
try {
|
|
209
|
+
const url = this.buildUrl('setNamespace', { locale, namespace });
|
|
210
|
+
const response = await this.makeRequest(url, 'PUT', {
|
|
211
|
+
translations,
|
|
212
|
+
});
|
|
213
|
+
if (!response.ok) {
|
|
214
|
+
throw new Error(`Failed to save namespace: ${response.status}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
logger.debug(`API setNamespace failed for ${locale}:${namespace}:`, error);
|
|
219
|
+
throw error;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Batch sync multiple missing translations
|
|
224
|
+
* Uses new batch endpoint for efficiency
|
|
225
|
+
*/
|
|
226
|
+
async setBatch(items) {
|
|
227
|
+
if (!this.config?.options?.baseUrl) {
|
|
228
|
+
logger.debug('API base URL is not set');
|
|
229
|
+
return Promise.reject(new Error('API base URL is not set'));
|
|
230
|
+
}
|
|
231
|
+
try {
|
|
232
|
+
const url = this.buildUrl('setBatch');
|
|
233
|
+
logger.debug(`API POST Batch: ${url} (${items.length} items)`);
|
|
234
|
+
const response = await this.makeRequest(url, 'POST', {
|
|
235
|
+
translations: items,
|
|
236
|
+
});
|
|
237
|
+
if (!response.ok) {
|
|
238
|
+
throw new Error(`Failed to sync batch: ${response.status}`);
|
|
239
|
+
}
|
|
240
|
+
logger.debug(`Batch sync successful: ${items.length} items`);
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
logger.debug(`API setBatch failed for ${items.length} items:`, error);
|
|
244
|
+
throw error;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
248
|
+
// ContentUnit API Methods
|
|
249
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
250
|
+
/**
|
|
251
|
+
* Get namespace with all translations as ContentUnit data
|
|
252
|
+
*
|
|
253
|
+
* @returns ContentUnitData (Record<string, ContentUnit>)
|
|
254
|
+
* @throws {TranslationNotFoundError} When namespace doesn't exist (404)
|
|
255
|
+
* @throws {TranslationLockedError} When namespace is locked/not ready (423)
|
|
256
|
+
* @throws {ServerError} When server returns 5xx error
|
|
257
|
+
* @throws {NetworkError} When network request fails
|
|
258
|
+
*/
|
|
259
|
+
async getNamespaceContentUnits(locale, namespace) {
|
|
260
|
+
if (!this.config?.options?.baseUrl) {
|
|
261
|
+
logger.debug('API base URL is not set');
|
|
262
|
+
throw new NetworkError('API base URL is not set');
|
|
263
|
+
}
|
|
264
|
+
const url = this.buildUrl('getNamespace', { locale, namespace });
|
|
265
|
+
logger.debug(`API GET Namespace ContentUnits: ${url}`);
|
|
266
|
+
const namespaceKey = `${locale}:${namespace}`;
|
|
267
|
+
try {
|
|
268
|
+
// Send If-None-Match for conditional request
|
|
269
|
+
const extraHeaders = {};
|
|
270
|
+
const cachedVersion = this.getVersion(namespaceKey);
|
|
271
|
+
if (cachedVersion) {
|
|
272
|
+
extraHeaders['If-None-Match'] = `W/"${cachedVersion}"`;
|
|
273
|
+
}
|
|
274
|
+
const response = await this.makeRequest(url, 'GET', undefined, extraHeaders);
|
|
275
|
+
// 304 Not Modified — cached translations are still fresh
|
|
276
|
+
if (response.status === 304) {
|
|
277
|
+
logger.debug(`Namespace ContentUnits ${namespaceKey}: 304 Not Modified`);
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
if (!response.ok) {
|
|
281
|
+
this.handleHttpError(response, namespaceKey);
|
|
282
|
+
}
|
|
283
|
+
const data = await response.json();
|
|
284
|
+
logger.debug('API response data:', data);
|
|
285
|
+
if (!data.translations) {
|
|
286
|
+
throw new TranslationNotFoundError(namespaceKey);
|
|
287
|
+
}
|
|
288
|
+
// Track version for future conditional requests (memory + localStorage)
|
|
289
|
+
const version = data.meta?.version != null ? String(data.meta.version) : null;
|
|
290
|
+
if (version) {
|
|
291
|
+
this.setVersion(namespaceKey, version);
|
|
292
|
+
}
|
|
293
|
+
// Server always returns ContentUnit format
|
|
294
|
+
return data.translations;
|
|
295
|
+
}
|
|
296
|
+
catch (error) {
|
|
297
|
+
this.handleCaughtError(error);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Save ContentUnit to API
|
|
302
|
+
*
|
|
303
|
+
* Sends the ContentUnit format to server for storage.
|
|
304
|
+
* Server should store in ContentUnit format for efficient retrieval.
|
|
305
|
+
*
|
|
306
|
+
* @param key - Translation key
|
|
307
|
+
* @param unit - ContentUnit to save
|
|
308
|
+
*/
|
|
309
|
+
async setContentUnit(key, unit) {
|
|
310
|
+
if (!this.config?.options?.baseUrl) {
|
|
311
|
+
logger.debug('API base URL is not set');
|
|
312
|
+
return Promise.reject(new Error('API base URL is not set'));
|
|
313
|
+
}
|
|
314
|
+
try {
|
|
315
|
+
const url = this.buildUrl('setTranslation', { key });
|
|
316
|
+
const response = await this.makeRequest(url, 'PUT', {
|
|
317
|
+
translation: unit,
|
|
318
|
+
format: 'contentunit', // Signal to server that this is ContentUnit format
|
|
319
|
+
});
|
|
320
|
+
if (!response.ok) {
|
|
321
|
+
throw new Error(`Failed to save ContentUnit: ${response.status}`);
|
|
322
|
+
}
|
|
323
|
+
logger.debug(`Saved ContentUnit for key "${key}"`);
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
logger.debug(`API setContentUnit failed for key "${key}":`, error);
|
|
327
|
+
throw error;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Batch sync multiple ContentUnits
|
|
332
|
+
*
|
|
333
|
+
* Sends ContentUnit format to server for batch storage.
|
|
334
|
+
*
|
|
335
|
+
* @param items - Array of key-ContentUnit pairs
|
|
336
|
+
*/
|
|
337
|
+
async setBatchContentUnits(items) {
|
|
338
|
+
if (!this.config?.options?.baseUrl) {
|
|
339
|
+
logger.debug('API base URL is not set');
|
|
340
|
+
return Promise.reject(new Error('API base URL is not set'));
|
|
341
|
+
}
|
|
342
|
+
try {
|
|
343
|
+
const url = this.buildUrl('setBatch');
|
|
344
|
+
logger.debug(`API POST Batch ContentUnits: ${url} (${items.length} items)`);
|
|
345
|
+
const response = await this.makeRequest(url, 'POST', {
|
|
346
|
+
translations: items,
|
|
347
|
+
format: 'contentunit', // Signal to server that this is ContentUnit format
|
|
348
|
+
});
|
|
349
|
+
if (!response.ok) {
|
|
350
|
+
throw new Error(`Failed to sync batch ContentUnits: ${response.status}`);
|
|
351
|
+
}
|
|
352
|
+
logger.debug(`Batch ContentUnit sync successful: ${items.length} items`);
|
|
353
|
+
}
|
|
354
|
+
catch (error) {
|
|
355
|
+
logger.debug(`API setBatchContentUnits failed for ${items.length} items:`, error);
|
|
356
|
+
throw error;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Remove translation from API (if supported)
|
|
361
|
+
*/
|
|
362
|
+
async remove(key) {
|
|
363
|
+
if (!this.config?.options?.baseUrl) {
|
|
364
|
+
logger.debug('API base URL is not set');
|
|
365
|
+
return Promise.reject(new Error('API base URL is not set'));
|
|
366
|
+
}
|
|
367
|
+
try {
|
|
368
|
+
const url = this.buildUrl('removeTranslation', { key });
|
|
369
|
+
const response = await this.makeRequest(url, 'DELETE');
|
|
370
|
+
if (!response.ok) {
|
|
371
|
+
throw new Error(`Failed to remove translation: ${response.status}`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
catch (error) {
|
|
375
|
+
logger.debug(`API remove failed for key "${key}":`, error);
|
|
376
|
+
throw error;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Clear all translations (if supported)
|
|
381
|
+
*/
|
|
382
|
+
async clear() {
|
|
383
|
+
if (!this.config?.options?.baseUrl) {
|
|
384
|
+
logger.debug('API base URL is not set');
|
|
385
|
+
return Promise.reject(new Error('API base URL is not set'));
|
|
386
|
+
}
|
|
387
|
+
try {
|
|
388
|
+
const url = this.buildUrl('clearTranslations');
|
|
389
|
+
const response = await this.makeRequest(url, 'DELETE');
|
|
390
|
+
if (!response.ok) {
|
|
391
|
+
throw new Error(`Failed to clear translations: ${response.status}`);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
catch (error) {
|
|
395
|
+
logger.debug('API clear failed:', error);
|
|
396
|
+
throw error;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
getConfig() {
|
|
400
|
+
return this.config;
|
|
401
|
+
}
|
|
402
|
+
/** Read persisted version from localStorage, falling back to in-memory map */
|
|
403
|
+
getVersion(namespaceKey) {
|
|
404
|
+
const mem = this.namespaceVersions.get(namespaceKey);
|
|
405
|
+
if (mem)
|
|
406
|
+
return mem;
|
|
407
|
+
try {
|
|
408
|
+
const stored = localStorage.getItem(NetworkRepository.VERSION_PREFIX + namespaceKey);
|
|
409
|
+
if (stored) {
|
|
410
|
+
this.namespaceVersions.set(namespaceKey, stored);
|
|
411
|
+
return stored;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
catch { /* SSR or localStorage unavailable */ }
|
|
415
|
+
return undefined;
|
|
416
|
+
}
|
|
417
|
+
/** Persist version to both in-memory map and localStorage */
|
|
418
|
+
setVersion(namespaceKey, version) {
|
|
419
|
+
this.namespaceVersions.set(namespaceKey, version);
|
|
420
|
+
try {
|
|
421
|
+
localStorage.setItem(NetworkRepository.VERSION_PREFIX + namespaceKey, version);
|
|
422
|
+
}
|
|
423
|
+
catch { /* quota exceeded or unavailable */ }
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Handle HTTP error responses by mapping to domain errors
|
|
427
|
+
* @throws {TranslationNotFoundError} When status is 404
|
|
428
|
+
* @throws {TranslationLockedError} When status is 423
|
|
429
|
+
* @throws {ServerError} When status is 5xx
|
|
430
|
+
* @throws {NetworkError} For other client errors
|
|
431
|
+
*/
|
|
432
|
+
handleHttpError(response, key) {
|
|
433
|
+
logger.debug(`API response: ${response.status} ${response.statusText}`);
|
|
434
|
+
if (response.status === 404) {
|
|
435
|
+
throw new TranslationNotFoundError(key);
|
|
436
|
+
}
|
|
437
|
+
if (response.status === 423) {
|
|
438
|
+
const retryAfter = response.headers.get('Retry-After');
|
|
439
|
+
throw new TranslationLockedError(key, retryAfter ? parseInt(retryAfter, 10) * 1000 : undefined);
|
|
440
|
+
}
|
|
441
|
+
if (response.status >= 500 && response.status < 600) {
|
|
442
|
+
throw new ServerError(key, response.status);
|
|
443
|
+
}
|
|
444
|
+
// Other client errors (400, 401, 403, etc.)
|
|
445
|
+
throw new NetworkError(`HTTP ${response.status}: ${response.statusText}`);
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Handle caught errors by wrapping non-domain errors
|
|
449
|
+
* @throws {TranslationError} Always throws - propagates domain errors or wraps unexpected ones
|
|
450
|
+
*/
|
|
451
|
+
handleCaughtError(error) {
|
|
452
|
+
// Custom errors propagate automatically, wrap everything else
|
|
453
|
+
if (error instanceof TranslationNotFoundError ||
|
|
454
|
+
error instanceof TranslationLockedError ||
|
|
455
|
+
error instanceof ServerError ||
|
|
456
|
+
error instanceof NetworkError) {
|
|
457
|
+
throw error;
|
|
458
|
+
}
|
|
459
|
+
// Wrap unexpected errors (fetch abort, JSON parse, etc.)
|
|
460
|
+
throw new NetworkError('Network request failed', error);
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Build URL from endpoint template and parameters
|
|
464
|
+
* Supports placeholders: :key, :locale, :namespace
|
|
465
|
+
* @param endpoint - Endpoint key from DEFAULT_ENDPOINTS
|
|
466
|
+
* @param params - Parameters to replace placeholders with
|
|
467
|
+
* @returns Complete URL with baseUrl + endpoint path
|
|
468
|
+
*/
|
|
469
|
+
buildUrl(endpoint, params = {}) {
|
|
470
|
+
const baseUrl = this.config.options?.baseUrl || '';
|
|
471
|
+
// Get endpoint template from config or use default
|
|
472
|
+
let endpointTemplate = this.config.options?.endpoints?.[endpoint] ||
|
|
473
|
+
this.DEFAULT_ENDPOINTS[endpoint];
|
|
474
|
+
// Ensure endpoint starts with / for consistent URL building
|
|
475
|
+
if (!endpointTemplate.startsWith('/')) {
|
|
476
|
+
endpointTemplate = `/${endpointTemplate}`;
|
|
477
|
+
}
|
|
478
|
+
// Replace all placeholders with actual values (encoded)
|
|
479
|
+
// Use global replace to handle multiple occurrences
|
|
480
|
+
let path = endpointTemplate;
|
|
481
|
+
for (const [key, value] of Object.entries(params)) {
|
|
482
|
+
const placeholder = new RegExp(`:${key}`, 'g');
|
|
483
|
+
path = path.replace(placeholder, encodeURIComponent(value));
|
|
484
|
+
}
|
|
485
|
+
return `${baseUrl}${path}`;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Make HTTP request with timeout and headers
|
|
489
|
+
*/
|
|
490
|
+
async makeRequest(url, method, body, extraHeaders) {
|
|
491
|
+
const controller = new AbortController();
|
|
492
|
+
const timeout = this.config.options?.timeout ?? 10000;
|
|
493
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
494
|
+
try {
|
|
495
|
+
const headers = {
|
|
496
|
+
'Content-Type': 'application/json',
|
|
497
|
+
...this.config.options?.headers,
|
|
498
|
+
...extraHeaders,
|
|
499
|
+
};
|
|
500
|
+
if (this.config.options?.apiKey) {
|
|
501
|
+
headers['Authorization'] = `Bearer ${this.config.options.apiKey}`;
|
|
502
|
+
}
|
|
503
|
+
const response = await fetch(url, {
|
|
504
|
+
method,
|
|
505
|
+
headers,
|
|
506
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
507
|
+
signal: controller.signal,
|
|
508
|
+
});
|
|
509
|
+
return response;
|
|
510
|
+
}
|
|
511
|
+
finally {
|
|
512
|
+
clearTimeout(timeoutId);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
//# sourceMappingURL=network-repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-repository.js","sourceRoot":"","sources":["../../src/repositories/network-repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue for batching and syncing missing translations to the backend
|
|
3
|
+
* Uses debouncing (500ms default) and batching (50 items default)
|
|
4
|
+
*/
|
|
5
|
+
import type { EventEmitter } from '../base/event-emitter.js';
|
|
6
|
+
import type { IAsyncRepository } from '../interfaces/repository.interface.js';
|
|
7
|
+
export interface MissingTranslationItem {
|
|
8
|
+
key: string;
|
|
9
|
+
fallbackValue: string;
|
|
10
|
+
styles?: Record<string, string[]>;
|
|
11
|
+
locale: string;
|
|
12
|
+
namespace: string;
|
|
13
|
+
}
|
|
14
|
+
export interface MissingTranslationQueueConfig {
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
debounceMs: number;
|
|
17
|
+
batchSize: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class MissingTranslationQueue {
|
|
20
|
+
private queue;
|
|
21
|
+
private debounceTimer;
|
|
22
|
+
private repository;
|
|
23
|
+
private config;
|
|
24
|
+
private eventEmitter;
|
|
25
|
+
private recentlySynced;
|
|
26
|
+
constructor(repository: IAsyncRepository, config: MissingTranslationQueueConfig, eventEmitter?: EventEmitter);
|
|
27
|
+
/**
|
|
28
|
+
* Add a missing translation to the queue
|
|
29
|
+
* Triggers debounce timer or immediate flush if batch size reached
|
|
30
|
+
*/
|
|
31
|
+
add(item: MissingTranslationItem): void;
|
|
32
|
+
/**
|
|
33
|
+
* Flush the queue - send all queued items to the backend
|
|
34
|
+
* Fire-and-forget pattern (async but not awaited)
|
|
35
|
+
*/
|
|
36
|
+
flush(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Send batch to backend via repository
|
|
39
|
+
* Uses repository's retry logic from makeRequest()
|
|
40
|
+
*/
|
|
41
|
+
private syncBatch;
|
|
42
|
+
/**
|
|
43
|
+
* Fallback: sync items individually in parallel
|
|
44
|
+
*/
|
|
45
|
+
private syncIndividually;
|
|
46
|
+
/**
|
|
47
|
+
* Get current queue size (for debugging)
|
|
48
|
+
*/
|
|
49
|
+
getQueueSize(): number;
|
|
50
|
+
/**
|
|
51
|
+
* Get queue stats (for debugging)
|
|
52
|
+
*/
|
|
53
|
+
getStats(): {
|
|
54
|
+
queueSize: number;
|
|
55
|
+
enabled: boolean;
|
|
56
|
+
debounceMs: number;
|
|
57
|
+
batchSize: number;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Cleanup - clear timer and queue
|
|
61
|
+
*/
|
|
62
|
+
destroy(): void;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=missing-translation-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"missing-translation-queue.d.ts","sourceRoot":"","sources":["../../src/sync/missing-translation-queue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAG9E,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,qBAAa,uBAAuB;IAClC,OAAO,CAAC,KAAK,CAAkD;IAC/D,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,cAAc,CAAkC;gBAGtD,UAAU,EAAE,gBAAgB,EAC5B,MAAM,EAAE,6BAA6B,EACrC,YAAY,CAAC,EAAE,YAAY;IAe7B;;;OAGG;IACH,GAAG,CAAC,IAAI,EAAE,sBAAsB,GAAG,IAAI;IAuCvC;;;OAGG;IACH,KAAK,IAAI,IAAI;IAmCb;;;OAGG;YACW,SAAS;IA0DvB;;OAEG;YACW,gBAAgB;IAe9B;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,QAAQ,IAAI;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB;IASD;;OAEG;IACH,OAAO,IAAI,IAAI;CAYhB"}
|