@tolgee/core 4.9.2 → 4.9.3-rc.ad9d2a4.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/dist/tolgee.cjs.js +1127 -7028
- package/dist/tolgee.cjs.js.map +1 -1
- package/dist/tolgee.cjs.min.js +1 -1
- package/dist/tolgee.cjs.min.js.map +1 -1
- package/dist/tolgee.esm.min.mjs +1 -1
- package/dist/tolgee.esm.min.mjs.map +1 -1
- package/dist/tolgee.esm.mjs +1125 -7023
- package/dist/tolgee.esm.mjs.map +1 -1
- package/dist/tolgee.umd.js +1127 -7028
- package/dist/tolgee.umd.js.map +1 -1
- package/dist/tolgee.umd.min.js +1 -1
- package/dist/tolgee.umd.min.js.map +1 -1
- package/lib/Controller/Cache/Cache.d.ts +22 -0
- package/lib/Controller/Cache/helpers.d.ts +4 -0
- package/lib/Controller/Controller.d.ts +110 -0
- package/lib/Controller/Events/EventEmitter.d.ts +6 -0
- package/lib/Controller/Events/EventEmitterSelective.d.ts +7 -0
- package/lib/Controller/Events/Events.d.ts +14 -0
- package/lib/Controller/Plugins/Plugins.d.ts +36 -0
- package/lib/Controller/State/State.d.ts +39 -0
- package/lib/Controller/State/helpers.d.ts +6 -0
- package/lib/Controller/State/initObserverOptions.d.ts +13 -0
- package/lib/Controller/State/initState.d.ts +47 -0
- package/lib/Controller/ValueObserver.d.ts +5 -0
- package/lib/Tolgee.d.ts +2 -68
- package/lib/TranslateParams.d.ts +2 -0
- package/lib/{Constants/Global.d.ts → constants.d.ts} +1 -2
- package/lib/helpers.d.ts +3 -0
- package/lib/index.d.ts +3 -8
- package/lib/types.d.ts +244 -84
- package/package.json +20 -29
- package/src/Controller/Cache/Cache.ts +293 -0
- package/src/Controller/Cache/helpers.ts +37 -0
- package/src/Controller/Controller.ts +310 -0
- package/src/Controller/Events/EventEmitter.ts +30 -0
- package/src/Controller/Events/EventEmitterSelective.test.ts +125 -0
- package/src/Controller/Events/EventEmitterSelective.ts +188 -0
- package/src/Controller/Events/Events.ts +66 -0
- package/src/Controller/Plugins/Plugins.ts +315 -0
- package/src/Controller/State/State.ts +175 -0
- package/src/Controller/State/helpers.ts +41 -0
- package/src/Controller/State/initObserverOptions.ts +38 -0
- package/src/Controller/State/initState.ts +81 -0
- package/src/Controller/ValueObserver.ts +26 -0
- package/src/Tolgee.ts +79 -330
- package/src/TranslateParams.test.ts +41 -0
- package/src/TranslateParams.ts +51 -0
- package/src/__test/backend.test.ts +48 -0
- package/src/__test/cache.test.ts +148 -0
- package/src/__test/client.test.ts +48 -0
- package/src/__test/events.test.ts +33 -0
- package/src/__test/initialization.test.ts +85 -0
- package/src/__test/jest-setup.ts +2 -0
- package/src/__test/languageDetection.test.ts +129 -0
- package/src/__test/languageStorage.test.ts +145 -0
- package/src/__test/languages.test.ts +112 -0
- package/src/__test/loading.test.ts +39 -0
- package/src/__test/namespaces.test.ts +99 -0
- package/src/__test/namespacesFallback.test.ts +74 -0
- package/src/__test/plugins.test.ts +136 -0
- package/src/__test/testTools.ts +7 -0
- package/src/{Constants/Global.ts → constants.ts} +1 -3
- package/src/helpers.ts +17 -0
- package/src/index.ts +9 -8
- package/src/types.ts +338 -90
- package/README.md +0 -45
- package/dist/Constants/Global.d.ts +0 -6
- package/dist/Constants/ModifierKey.d.ts +0 -6
- package/dist/Errors/ApiHttpError.d.ts +0 -5
- package/dist/Observer.d.ts +0 -14
- package/dist/Observer.test.d.ts +0 -2
- package/dist/Properties.d.ts +0 -17
- package/dist/Properties.test.d.ts +0 -1
- package/dist/Tolgee.d.ts +0 -68
- package/dist/Tolgee.test.d.ts +0 -1
- package/dist/TolgeeConfig.d.ts +0 -69
- package/dist/TolgeeConfig.test.d.ts +0 -1
- package/dist/__integration/FormatterIcu.test.d.ts +0 -1
- package/dist/__integration/FormatterMissing.d.ts +0 -1
- package/dist/__integration/Tolgee.test.d.ts +0 -1
- package/dist/__integration/TolgeeInvisible.test.d.ts +0 -1
- package/dist/__integration/mockTranslations.d.ts +0 -7
- package/dist/__integration/testConfig.d.ts +0 -9
- package/dist/__testFixtures/classMock.d.ts +0 -3
- package/dist/__testFixtures/createElement.d.ts +0 -2
- package/dist/__testFixtures/createTestDom.d.ts +0 -9
- package/dist/__testFixtures/mocked.d.ts +0 -20
- package/dist/__testFixtures/setupAfterEnv.d.ts +0 -8
- package/dist/helpers/NodeHelper.d.ts +0 -14
- package/dist/helpers/TextHelper.d.ts +0 -5
- package/dist/helpers/TextHelper.test.d.ts +0 -1
- package/dist/helpers/commonTypes.d.ts +0 -2
- package/dist/helpers/encoderPolyfill.d.ts +0 -8
- package/dist/helpers/secret.d.ts +0 -6
- package/dist/helpers/secret.test.d.ts +0 -1
- package/dist/helpers/sleep.d.ts +0 -1
- package/dist/highlighter/HighlightFunctionsInitializer.d.ts +0 -10
- package/dist/highlighter/HighlightFunctionsInitializer.test.d.ts +0 -1
- package/dist/highlighter/MouseEventHandler.d.ts +0 -29
- package/dist/highlighter/MouseEventHandler.test.d.ts +0 -1
- package/dist/highlighter/TranslationHighlighter.d.ts +0 -14
- package/dist/highlighter/TranslationHighlighter.test.d.ts +0 -1
- package/dist/index.d.ts +0 -10
- package/dist/internal.d.ts +0 -2
- package/dist/modules/IcuFormatter.d.ts +0 -2
- package/dist/modules/IcuFormatter.test.d.ts +0 -1
- package/dist/modules/index.d.ts +0 -1
- package/dist/services/ApiHttpService.d.ts +0 -15
- package/dist/services/CoreService.d.ts +0 -18
- package/dist/services/CoreService.test.d.ts +0 -1
- package/dist/services/DependencyService.d.ts +0 -39
- package/dist/services/DependencyService.test.d.ts +0 -1
- package/dist/services/ElementRegistrar.d.ts +0 -19
- package/dist/services/ElementRegistrar.test.d.ts +0 -1
- package/dist/services/EventEmitter.d.ts +0 -13
- package/dist/services/EventService.d.ts +0 -9
- package/dist/services/ModuleService.d.ts +0 -5
- package/dist/services/ScreenshotService.d.ts +0 -15
- package/dist/services/Subscription.d.ts +0 -5
- package/dist/services/TextService.d.ts +0 -14
- package/dist/services/TextService.test.d.ts +0 -1
- package/dist/services/TranslationService.d.ts +0 -75
- package/dist/services/TranslationService.test.d.ts +0 -1
- package/dist/services/__mocks__/CoreService.d.ts +0 -2
- package/dist/toolsManager/Messages.d.ts +0 -8
- package/dist/toolsManager/Messages.test.d.ts +0 -1
- package/dist/toolsManager/PluginManager.d.ts +0 -21
- package/dist/toolsManager/PluginManager.test.d.ts +0 -1
- package/dist/types/DTOs.d.ts +0 -20
- package/dist/types/apiSchema.generated.d.ts +0 -6185
- package/dist/types.d.ts +0 -123
- package/dist/wrappers/AbstractWrapper.d.ts +0 -8
- package/dist/wrappers/NodeHandler.d.ts +0 -18
- package/dist/wrappers/WrappedHandler.d.ts +0 -8
- package/dist/wrappers/invisible/AttributeHandler.d.ts +0 -8
- package/dist/wrappers/invisible/Coder.d.ts +0 -7
- package/dist/wrappers/invisible/ContentHandler.d.ts +0 -6
- package/dist/wrappers/invisible/CoreHandler.d.ts +0 -10
- package/dist/wrappers/invisible/InvisibleWrapper.d.ts +0 -18
- package/dist/wrappers/invisible/ValueMemory.d.ts +0 -5
- package/dist/wrappers/invisible/ValueMemory.test.d.ts +0 -1
- package/dist/wrappers/text/AttributeHandler.d.ts +0 -8
- package/dist/wrappers/text/AttributeHandler.test.d.ts +0 -1
- package/dist/wrappers/text/Coder.d.ts +0 -15
- package/dist/wrappers/text/Coder.test.d.ts +0 -1
- package/dist/wrappers/text/ContentHandler.d.ts +0 -8
- package/dist/wrappers/text/ContentHandler.test.d.ts +0 -1
- package/dist/wrappers/text/CoreHandler.d.ts +0 -17
- package/dist/wrappers/text/CoreHandler.test.d.ts +0 -1
- package/dist/wrappers/text/TextWrapper.d.ts +0 -20
- package/index.js +0 -7
- package/lib/Constants/ModifierKey.d.ts +0 -6
- package/lib/Errors/ApiHttpError.d.ts +0 -5
- package/lib/Observer.d.ts +0 -14
- package/lib/Properties.d.ts +0 -17
- package/lib/TolgeeConfig.d.ts +0 -69
- package/lib/helpers/NodeHelper.d.ts +0 -14
- package/lib/helpers/TextHelper.d.ts +0 -5
- package/lib/helpers/commonTypes.d.ts +0 -2
- package/lib/helpers/encoderPolyfill.d.ts +0 -8
- package/lib/helpers/secret.d.ts +0 -6
- package/lib/helpers/sleep.d.ts +0 -1
- package/lib/highlighter/HighlightFunctionsInitializer.d.ts +0 -10
- package/lib/highlighter/MouseEventHandler.d.ts +0 -29
- package/lib/highlighter/TranslationHighlighter.d.ts +0 -14
- package/lib/modules/IcuFormatter.d.ts +0 -2
- package/lib/modules/index.d.ts +0 -1
- package/lib/services/ApiHttpService.d.ts +0 -15
- package/lib/services/CoreService.d.ts +0 -18
- package/lib/services/DependencyService.d.ts +0 -39
- package/lib/services/ElementRegistrar.d.ts +0 -19
- package/lib/services/EventEmitter.d.ts +0 -13
- package/lib/services/EventService.d.ts +0 -9
- package/lib/services/ModuleService.d.ts +0 -5
- package/lib/services/ScreenshotService.d.ts +0 -15
- package/lib/services/Subscription.d.ts +0 -5
- package/lib/services/TextService.d.ts +0 -14
- package/lib/services/TranslationService.d.ts +0 -75
- package/lib/toolsManager/Messages.d.ts +0 -8
- package/lib/toolsManager/PluginManager.d.ts +0 -21
- package/lib/types/DTOs.d.ts +0 -20
- package/lib/types/apiSchema.generated.d.ts +0 -6185
- package/lib/wrappers/AbstractWrapper.d.ts +0 -8
- package/lib/wrappers/NodeHandler.d.ts +0 -18
- package/lib/wrappers/WrappedHandler.d.ts +0 -8
- package/lib/wrappers/invisible/AttributeHandler.d.ts +0 -8
- package/lib/wrappers/invisible/Coder.d.ts +0 -7
- package/lib/wrappers/invisible/ContentHandler.d.ts +0 -6
- package/lib/wrappers/invisible/CoreHandler.d.ts +0 -10
- package/lib/wrappers/invisible/InvisibleWrapper.d.ts +0 -18
- package/lib/wrappers/invisible/ValueMemory.d.ts +0 -5
- package/lib/wrappers/text/AttributeHandler.d.ts +0 -8
- package/lib/wrappers/text/Coder.d.ts +0 -15
- package/lib/wrappers/text/ContentHandler.d.ts +0 -8
- package/lib/wrappers/text/CoreHandler.d.ts +0 -17
- package/lib/wrappers/text/TextWrapper.d.ts +0 -20
- package/src/Constants/ModifierKey.ts +0 -6
- package/src/Errors/ApiHttpError.ts +0 -8
- package/src/Observer.test.ts +0 -119
- package/src/Observer.ts +0 -68
- package/src/Properties.test.ts +0 -150
- package/src/Properties.ts +0 -112
- package/src/Tolgee.test.ts +0 -473
- package/src/TolgeeConfig.test.ts +0 -21
- package/src/TolgeeConfig.ts +0 -134
- package/src/__integration/FormatterIcu.test.ts +0 -80
- package/src/__integration/FormatterMissing.ts +0 -54
- package/src/__integration/Tolgee.test.ts +0 -90
- package/src/__integration/TolgeeInvisible.test.ts +0 -145
- package/src/__integration/mockTranslations.ts +0 -6
- package/src/__integration/testConfig.ts +0 -16
- package/src/__testFixtures/classMock.ts +0 -11
- package/src/__testFixtures/createElement.ts +0 -43
- package/src/__testFixtures/createTestDom.ts +0 -26
- package/src/__testFixtures/mocked.ts +0 -25
- package/src/__testFixtures/setupAfterEnv.ts +0 -34
- package/src/helpers/NodeHelper.ts +0 -90
- package/src/helpers/TextHelper.test.ts +0 -62
- package/src/helpers/TextHelper.ts +0 -58
- package/src/helpers/commonTypes.ts +0 -8
- package/src/helpers/encoderPolyfill.ts +0 -96
- package/src/helpers/secret.test.ts +0 -61
- package/src/helpers/secret.ts +0 -68
- package/src/helpers/sleep.ts +0 -2
- package/src/highlighter/HighlightFunctionsInitializer.test.ts +0 -40
- package/src/highlighter/HighlightFunctionsInitializer.ts +0 -61
- package/src/highlighter/MouseEventHandler.test.ts +0 -151
- package/src/highlighter/MouseEventHandler.ts +0 -191
- package/src/highlighter/TranslationHighlighter.test.ts +0 -177
- package/src/highlighter/TranslationHighlighter.ts +0 -113
- package/src/internal.ts +0 -2
- package/src/modules/IcuFormatter.test.ts +0 -21
- package/src/modules/IcuFormatter.ts +0 -39
- package/src/modules/index.ts +0 -1
- package/src/services/ApiHttpService.ts +0 -85
- package/src/services/CoreService.test.ts +0 -141
- package/src/services/CoreService.ts +0 -76
- package/src/services/DependencyService.test.ts +0 -51
- package/src/services/DependencyService.ts +0 -116
- package/src/services/ElementRegistrar.test.ts +0 -131
- package/src/services/ElementRegistrar.ts +0 -108
- package/src/services/EventEmitter.ts +0 -52
- package/src/services/EventService.ts +0 -14
- package/src/services/ModuleService.ts +0 -14
- package/src/services/ScreenshotService.ts +0 -31
- package/src/services/Subscription.ts +0 -7
- package/src/services/TextService.test.ts +0 -88
- package/src/services/TextService.ts +0 -82
- package/src/services/TranslationService.test.ts +0 -358
- package/src/services/TranslationService.ts +0 -417
- package/src/services/__mocks__/CoreService.ts +0 -17
- package/src/toolsManager/Messages.test.ts +0 -79
- package/src/toolsManager/Messages.ts +0 -60
- package/src/toolsManager/PluginManager.test.ts +0 -108
- package/src/toolsManager/PluginManager.ts +0 -129
- package/src/types/DTOs.ts +0 -25
- package/src/types/apiSchema.generated.ts +0 -6208
- package/src/wrappers/AbstractWrapper.ts +0 -14
- package/src/wrappers/NodeHandler.ts +0 -143
- package/src/wrappers/WrappedHandler.ts +0 -28
- package/src/wrappers/invisible/AttributeHandler.ts +0 -23
- package/src/wrappers/invisible/Coder.ts +0 -65
- package/src/wrappers/invisible/ContentHandler.ts +0 -15
- package/src/wrappers/invisible/CoreHandler.ts +0 -17
- package/src/wrappers/invisible/InvisibleWrapper.ts +0 -59
- package/src/wrappers/invisible/ValueMemory.test.ts +0 -25
- package/src/wrappers/invisible/ValueMemory.ts +0 -16
- package/src/wrappers/text/AttributeHandler.test.ts +0 -118
- package/src/wrappers/text/AttributeHandler.ts +0 -25
- package/src/wrappers/text/Coder.test.ts +0 -298
- package/src/wrappers/text/Coder.ts +0 -202
- package/src/wrappers/text/ContentHandler.test.ts +0 -185
- package/src/wrappers/text/ContentHandler.ts +0 -21
- package/src/wrappers/text/CoreHandler.test.ts +0 -106
- package/src/wrappers/text/CoreHandler.ts +0 -45
- package/src/wrappers/text/TextWrapper.ts +0 -69
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { EventEmitterSelective } from './EventEmitterSelective';
|
|
2
|
+
|
|
3
|
+
describe('event emitter selective', () => {
|
|
4
|
+
it('handles correctly fallback namespaces', () => {
|
|
5
|
+
const emitter = EventEmitterSelective(() => ['a', 'b']);
|
|
6
|
+
const handler = jest.fn();
|
|
7
|
+
const listener = emitter.listenSome(handler);
|
|
8
|
+
|
|
9
|
+
// subscribe to fallback namespaces
|
|
10
|
+
listener.subscribeKey({ key: 'test' });
|
|
11
|
+
|
|
12
|
+
// emmit
|
|
13
|
+
emitter.emit({ key: 'test' });
|
|
14
|
+
emitter.emit({ ns: ['a'] });
|
|
15
|
+
// should be ignored
|
|
16
|
+
emitter.emit({ ns: ['c'] });
|
|
17
|
+
|
|
18
|
+
expect(handler).toBeCalledTimes(2);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('subscribes to key', () => {
|
|
22
|
+
const emitter = EventEmitterSelective(() => ['']);
|
|
23
|
+
const handler = jest.fn();
|
|
24
|
+
const listener = emitter.listenSome(handler);
|
|
25
|
+
listener.subscribeKey({ key: 'test' });
|
|
26
|
+
listener.subscribeKey({ key: 'abcd' });
|
|
27
|
+
|
|
28
|
+
emitter.emit({ key: 'test' });
|
|
29
|
+
emitter.emit({ key: 'youda' });
|
|
30
|
+
expect(handler).toBeCalledTimes(1);
|
|
31
|
+
listener.unsubscribe();
|
|
32
|
+
emitter.emit();
|
|
33
|
+
expect(handler).toBeCalledTimes(1);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('subscribes to key with namespaces', () => {
|
|
37
|
+
const emitter = EventEmitterSelective(() => []);
|
|
38
|
+
const handler = jest.fn();
|
|
39
|
+
const listener = emitter.listenSome(handler);
|
|
40
|
+
|
|
41
|
+
listener.subscribeKey({ key: 'test', ns: 'common' });
|
|
42
|
+
listener.subscribeKey({ key: 'abcd', ns: ['test', 'abcd'] });
|
|
43
|
+
|
|
44
|
+
emitter.emit({ key: 'youda', ns: ['common'] });
|
|
45
|
+
emitter.emit({ key: 'test', ns: ['youda'] });
|
|
46
|
+
expect(handler).toBeCalledTimes(0);
|
|
47
|
+
emitter.emit({ key: 'abcd', ns: ['abcd'] });
|
|
48
|
+
emitter.emit({ ns: ['test'] });
|
|
49
|
+
expect(handler).toBeCalledTimes(2);
|
|
50
|
+
listener.unsubscribe();
|
|
51
|
+
emitter.emit();
|
|
52
|
+
expect(handler).toBeCalledTimes(2);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('unsubscribes', () => {
|
|
56
|
+
const emitter = EventEmitterSelective(() => []);
|
|
57
|
+
const handler = jest.fn();
|
|
58
|
+
const listener = emitter.listenSome(handler);
|
|
59
|
+
|
|
60
|
+
listener.subscribeKey({ key: 'test', ns: 'common' });
|
|
61
|
+
listener.subscribeKey({ key: 'abcd', ns: ['test', 'abcd'] });
|
|
62
|
+
|
|
63
|
+
emitter.emit({ key: 'youda', ns: ['common'] });
|
|
64
|
+
emitter.emit({ key: 'test', ns: ['youda'] });
|
|
65
|
+
expect(handler).toBeCalledTimes(0);
|
|
66
|
+
emitter.emit({ key: 'abcd', ns: ['abcd'] });
|
|
67
|
+
emitter.emit({ ns: ['test'] });
|
|
68
|
+
expect(handler).toBeCalledTimes(2);
|
|
69
|
+
|
|
70
|
+
listener.unsubscribeKey({ key: 'abcd', ns: ['test', 'abcd'] });
|
|
71
|
+
emitter.emit({ key: 'abcd' });
|
|
72
|
+
emitter.emit({ ns: ['test'] });
|
|
73
|
+
|
|
74
|
+
listener.unsubscribe();
|
|
75
|
+
emitter.emit();
|
|
76
|
+
expect(handler).toBeCalledTimes(2);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('groups events correctly', async () => {
|
|
80
|
+
const emitter = EventEmitterSelective(() => ['test', 'opqrst']);
|
|
81
|
+
const handler = jest.fn();
|
|
82
|
+
const hanlderAll = jest.fn();
|
|
83
|
+
const listener = emitter.listenSome(handler);
|
|
84
|
+
const listenerAll = emitter.listen(hanlderAll);
|
|
85
|
+
|
|
86
|
+
listener.subscribeKey({ key: 'abcd', ns: ['test'] });
|
|
87
|
+
|
|
88
|
+
emitter.emit({ key: 'abcd' }, true);
|
|
89
|
+
emitter.emit({ ns: ['opqrst'] }, true);
|
|
90
|
+
|
|
91
|
+
await Promise.resolve();
|
|
92
|
+
|
|
93
|
+
expect(hanlderAll).toBeCalledTimes(1);
|
|
94
|
+
expect(handler).toBeCalledTimes(1);
|
|
95
|
+
|
|
96
|
+
emitter.emit({ key: 'youda', ns: ['test'] }, true);
|
|
97
|
+
emitter.emit({ key: 'filda', ns: ['test'] });
|
|
98
|
+
|
|
99
|
+
expect(hanlderAll).toBeCalledTimes(2);
|
|
100
|
+
expect(handler).toBeCalledTimes(1);
|
|
101
|
+
|
|
102
|
+
listener.unsubscribe();
|
|
103
|
+
listenerAll.unsubscribe();
|
|
104
|
+
emitter.emit();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('subscribes to ns only', async () => {
|
|
108
|
+
const emitter = EventEmitterSelective(() => ['test', 'youda']);
|
|
109
|
+
const handler = jest.fn();
|
|
110
|
+
const listener = emitter.listenSome(handler);
|
|
111
|
+
listener.subscribeNs(['test']);
|
|
112
|
+
|
|
113
|
+
emitter.emit({ key: 'youda' });
|
|
114
|
+
expect(handler).toBeCalledTimes(1);
|
|
115
|
+
|
|
116
|
+
emitter.emit({ ns: ['test'] });
|
|
117
|
+
expect(handler).toBeCalledTimes(2);
|
|
118
|
+
|
|
119
|
+
emitter.emit({ ns: ['youda'] });
|
|
120
|
+
expect(handler).toBeCalledTimes(2);
|
|
121
|
+
|
|
122
|
+
emitter.emit({ key: 'youda', ns: ['youda'] });
|
|
123
|
+
expect(handler).toBeCalledTimes(2);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { getFallbackArray } from '../State/helpers';
|
|
2
|
+
import {
|
|
3
|
+
FallbackNSTranslation,
|
|
4
|
+
KeyDescriptor,
|
|
5
|
+
KeyDescriptorInternal,
|
|
6
|
+
Listener,
|
|
7
|
+
ListenerHandler,
|
|
8
|
+
ListenerHandlerEvent,
|
|
9
|
+
ListenerSelective,
|
|
10
|
+
} from '../../types';
|
|
11
|
+
|
|
12
|
+
type HandlerWrapperType = {
|
|
13
|
+
fn: ListenerHandler<undefined>;
|
|
14
|
+
keys: Map<string, number>;
|
|
15
|
+
namespaces: Map<string | undefined, number>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function incrementInMap(map: Map<any, number>, value: any) {
|
|
19
|
+
const currNum = map.get(value) || 0;
|
|
20
|
+
map.set(value, currNum + 1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function decrementInMap(map: Map<any, number>, value: any) {
|
|
24
|
+
let currNum = map.get(value) || 1;
|
|
25
|
+
currNum -= 1;
|
|
26
|
+
if (currNum <= 0) {
|
|
27
|
+
map.delete(value);
|
|
28
|
+
} else {
|
|
29
|
+
map.set(value, currNum);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const EventEmitterSelective = (
|
|
34
|
+
getFallbackNamespaces: () => string[]
|
|
35
|
+
): EventEmitterSelectiveInstance => {
|
|
36
|
+
const listeners: Set<ListenerHandler<undefined>> = new Set();
|
|
37
|
+
const partialListeners: Set<HandlerWrapperType> = new Set();
|
|
38
|
+
|
|
39
|
+
const listen = (handler: ListenerHandler<undefined>) => {
|
|
40
|
+
listeners.add(handler);
|
|
41
|
+
const result = {
|
|
42
|
+
unsubscribe: () => {
|
|
43
|
+
listeners.delete(handler);
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const listenSome = (handler: ListenerHandler<undefined>) => {
|
|
50
|
+
const handlerWrapper = {
|
|
51
|
+
fn: (e: ListenerHandlerEvent<undefined>) => {
|
|
52
|
+
handler(e);
|
|
53
|
+
},
|
|
54
|
+
keys: new Map<string, number>(),
|
|
55
|
+
namespaces: new Map<string | undefined, number>(),
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
partialListeners.add(handlerWrapper);
|
|
59
|
+
|
|
60
|
+
const result = {
|
|
61
|
+
unsubscribe: () => {
|
|
62
|
+
partialListeners.delete(handlerWrapper);
|
|
63
|
+
},
|
|
64
|
+
subscribeNs: (ns: FallbackNSTranslation) => {
|
|
65
|
+
getFallbackArray(ns).forEach((val) =>
|
|
66
|
+
incrementInMap(handlerWrapper.namespaces, val)
|
|
67
|
+
);
|
|
68
|
+
return result;
|
|
69
|
+
},
|
|
70
|
+
unsubscribeNs: (ns: FallbackNSTranslation) => {
|
|
71
|
+
getFallbackArray(ns).forEach((val) =>
|
|
72
|
+
decrementInMap(handlerWrapper.namespaces, val)
|
|
73
|
+
);
|
|
74
|
+
return result;
|
|
75
|
+
},
|
|
76
|
+
subscribeKey: (descriptor: KeyDescriptor) => {
|
|
77
|
+
const { key, ns } = descriptor;
|
|
78
|
+
incrementInMap(handlerWrapper.keys, key);
|
|
79
|
+
getFallbackArray(ns).forEach((val) =>
|
|
80
|
+
incrementInMap(handlerWrapper.namespaces, val)
|
|
81
|
+
);
|
|
82
|
+
if (ns === undefined) {
|
|
83
|
+
// subscribing to all namespaces
|
|
84
|
+
incrementInMap(handlerWrapper.namespaces, undefined);
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
},
|
|
88
|
+
unsubscribeKey: (descriptor: KeyDescriptor) => {
|
|
89
|
+
const { key, ns } = descriptor;
|
|
90
|
+
decrementInMap(handlerWrapper.keys, key);
|
|
91
|
+
getFallbackArray(ns).forEach((val) =>
|
|
92
|
+
decrementInMap(handlerWrapper.namespaces, val)
|
|
93
|
+
);
|
|
94
|
+
if (ns === undefined) {
|
|
95
|
+
// subscribing to all namespaces
|
|
96
|
+
decrementInMap(handlerWrapper.namespaces, undefined);
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
return result;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const namespacesWithFallbacks = (
|
|
106
|
+
namespaces: Map<string | undefined, number> | Set<string | undefined>
|
|
107
|
+
) => {
|
|
108
|
+
if (namespaces.has(undefined)) {
|
|
109
|
+
const result = new Set(namespaces.keys());
|
|
110
|
+
result.delete(undefined);
|
|
111
|
+
getFallbackNamespaces().forEach((ns) => result.add(ns));
|
|
112
|
+
return result as Set<string>;
|
|
113
|
+
}
|
|
114
|
+
return namespaces as Map<string, number>;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const callHandlers = (key: string | undefined, ns: string[] | undefined) => {
|
|
118
|
+
partialListeners.forEach((handler) => {
|
|
119
|
+
const handlerNamespaces = namespacesWithFallbacks(handler.namespaces);
|
|
120
|
+
const nsMatches =
|
|
121
|
+
ns === undefined ||
|
|
122
|
+
ns?.findIndex((ns) => handlerNamespaces.has(ns)) !== -1;
|
|
123
|
+
const keyMatches =
|
|
124
|
+
key === undefined || handler.keys.has(key) || handler.keys.size === 0;
|
|
125
|
+
if (nsMatches && keyMatches) {
|
|
126
|
+
handler.fn({ value: undefined as any });
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
let queue: (KeyDescriptorInternal | undefined)[] = [];
|
|
132
|
+
// merge events in queue into one event
|
|
133
|
+
const solveQueue = () => {
|
|
134
|
+
if (queue.length === 0) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
listeners.forEach((handler) => {
|
|
138
|
+
handler({ value: undefined as any });
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const namespaces = new Set<string | undefined>();
|
|
142
|
+
let keys: Set<string> | undefined = new Set<string>();
|
|
143
|
+
queue.forEach((descriptor) => {
|
|
144
|
+
if (descriptor?.ns === undefined) {
|
|
145
|
+
// when no ns specified, it affets all fallback namespaces
|
|
146
|
+
namespaces.add(undefined);
|
|
147
|
+
} else {
|
|
148
|
+
descriptor.ns.forEach((ns) => namespaces.add(ns));
|
|
149
|
+
}
|
|
150
|
+
if (descriptor?.key === undefined) {
|
|
151
|
+
// when no key specified, it affects all keys
|
|
152
|
+
keys = undefined;
|
|
153
|
+
} else if (keys !== undefined) {
|
|
154
|
+
keys.add(descriptor.key);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
const namespacesArray = Array.from(
|
|
158
|
+
namespacesWithFallbacks(namespaces).keys()
|
|
159
|
+
);
|
|
160
|
+
(keys || [undefined]).forEach((key) => {
|
|
161
|
+
callHandlers(key, namespacesArray);
|
|
162
|
+
});
|
|
163
|
+
queue = [];
|
|
164
|
+
};
|
|
165
|
+
const emit = (descriptor?: KeyDescriptorInternal, delayed?: boolean) => {
|
|
166
|
+
queue.push(descriptor);
|
|
167
|
+
if (!delayed) {
|
|
168
|
+
solveQueue();
|
|
169
|
+
} else {
|
|
170
|
+
Promise.resolve().then(() => {
|
|
171
|
+
solveQueue();
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
return Object.freeze({ listenSome, listen, emit });
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export type EventEmitterSelectiveInstance = {
|
|
180
|
+
readonly listenSome: (
|
|
181
|
+
handler: ListenerHandler<undefined>
|
|
182
|
+
) => ListenerSelective;
|
|
183
|
+
readonly listen: (handler: ListenerHandler<undefined>) => Listener;
|
|
184
|
+
readonly emit: (
|
|
185
|
+
descriptor?: KeyDescriptorInternal,
|
|
186
|
+
delayed?: boolean
|
|
187
|
+
) => void;
|
|
188
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { EventEmitter } from './EventEmitter';
|
|
2
|
+
import { EventEmitterSelective } from './EventEmitterSelective';
|
|
3
|
+
import {
|
|
4
|
+
CacheDescriptorWithKey,
|
|
5
|
+
KeyDescriptorInternal,
|
|
6
|
+
ListenerHandler,
|
|
7
|
+
TolgeeOn,
|
|
8
|
+
} from '../../types';
|
|
9
|
+
|
|
10
|
+
export const Events = (getFallbackNamespaces: () => string[]) => {
|
|
11
|
+
const onPendingLanguageChange = EventEmitter<string>();
|
|
12
|
+
const onLanguageChange = EventEmitter<string>();
|
|
13
|
+
const onKeyChange = EventEmitter<KeyDescriptorInternal>();
|
|
14
|
+
const onLoadingChange = EventEmitter<boolean>();
|
|
15
|
+
const onFetchingChange = EventEmitter<boolean>();
|
|
16
|
+
const onInitialLoaded = EventEmitter<void>();
|
|
17
|
+
const onKeyUpdate = EventEmitterSelective(getFallbackNamespaces);
|
|
18
|
+
const onCacheChange = EventEmitter<CacheDescriptorWithKey>();
|
|
19
|
+
const onRunningChange = EventEmitter<boolean>();
|
|
20
|
+
|
|
21
|
+
onInitialLoaded.listen(() => onKeyUpdate.emit());
|
|
22
|
+
onLanguageChange.listen(() => onKeyUpdate.emit());
|
|
23
|
+
onCacheChange.listen(({ value }) => {
|
|
24
|
+
onKeyUpdate.emit({ ns: [value.namespace], key: value.key }, true);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const on: TolgeeOn = (event, handler): any => {
|
|
28
|
+
switch (event) {
|
|
29
|
+
case 'pendingLanguage':
|
|
30
|
+
return onPendingLanguageChange.listen(
|
|
31
|
+
handler as ListenerHandler<string>
|
|
32
|
+
);
|
|
33
|
+
case 'language':
|
|
34
|
+
return onLanguageChange.listen(handler as ListenerHandler<string>);
|
|
35
|
+
case 'loading':
|
|
36
|
+
return onLoadingChange.listen(handler as ListenerHandler<boolean>);
|
|
37
|
+
case 'fetching':
|
|
38
|
+
return onFetchingChange.listen(handler as ListenerHandler<boolean>);
|
|
39
|
+
case 'initialLoad':
|
|
40
|
+
return onInitialLoaded.listen(handler as ListenerHandler<void>);
|
|
41
|
+
case 'running':
|
|
42
|
+
return onRunningChange.listen(handler as ListenerHandler<boolean>);
|
|
43
|
+
case 'cache':
|
|
44
|
+
return onCacheChange.listen(
|
|
45
|
+
handler as ListenerHandler<CacheDescriptorWithKey>
|
|
46
|
+
);
|
|
47
|
+
case 'keyUpdate':
|
|
48
|
+
return onKeyUpdate.listen(handler as ListenerHandler<void>);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
return Object.freeze({
|
|
53
|
+
onPendingLanguageChange,
|
|
54
|
+
onLanguageChange,
|
|
55
|
+
onKeyChange,
|
|
56
|
+
onKeyUpdate,
|
|
57
|
+
onLoadingChange,
|
|
58
|
+
onFetchingChange,
|
|
59
|
+
onInitialLoaded,
|
|
60
|
+
onRunningChange,
|
|
61
|
+
onCacheChange,
|
|
62
|
+
on,
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export type EventServiceType = ReturnType<typeof Events>;
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { isPromise, valueOrPromise } from '../../helpers';
|
|
2
|
+
import {
|
|
3
|
+
BackendDevInterface,
|
|
4
|
+
BackendGetRecord,
|
|
5
|
+
BackendInterface,
|
|
6
|
+
FormatterInterface,
|
|
7
|
+
ObserverInterface,
|
|
8
|
+
TranslatePropsInternal,
|
|
9
|
+
TranslationOnClick,
|
|
10
|
+
UiInterface,
|
|
11
|
+
UiLibInterface,
|
|
12
|
+
UiType,
|
|
13
|
+
FinalFormatterInterface,
|
|
14
|
+
HighlightInterface,
|
|
15
|
+
UiConstructor,
|
|
16
|
+
UiKeyOption,
|
|
17
|
+
LanguageDetectorInterface,
|
|
18
|
+
LanguageStorageInterface,
|
|
19
|
+
Options,
|
|
20
|
+
ChangeTranslationInterface,
|
|
21
|
+
WrapperWrapProps,
|
|
22
|
+
Unwrapped,
|
|
23
|
+
} from '../../types';
|
|
24
|
+
import { getFallbackArray } from '../State/helpers';
|
|
25
|
+
import { ObserverOptions } from '../State/initObserverOptions';
|
|
26
|
+
|
|
27
|
+
export const PluginService = (
|
|
28
|
+
getLanguage: () => string | undefined,
|
|
29
|
+
getInitialOptions: () => Options,
|
|
30
|
+
getObserverOptions: () => ObserverOptions,
|
|
31
|
+
getAvailableLanguages: () => string[] | undefined,
|
|
32
|
+
getTranslationNs: (props: TranslatePropsInternal) => string[] | string,
|
|
33
|
+
getTranslation: (props: TranslatePropsInternal) => string | undefined,
|
|
34
|
+
changeTranslation: ChangeTranslationInterface
|
|
35
|
+
) => {
|
|
36
|
+
const plugins = {
|
|
37
|
+
ui: undefined as UiConstructor | undefined,
|
|
38
|
+
observer: undefined as ObserverInterface | undefined,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const instances = {
|
|
42
|
+
formatters: [] as FormatterInterface[],
|
|
43
|
+
finalFormatter: undefined as FinalFormatterInterface | undefined,
|
|
44
|
+
observer: undefined as ReturnType<ObserverInterface> | undefined,
|
|
45
|
+
devBackend: undefined as BackendDevInterface | undefined,
|
|
46
|
+
backends: [] as BackendInterface[],
|
|
47
|
+
ui: undefined as UiInterface | undefined,
|
|
48
|
+
languageDetector: undefined as LanguageDetectorInterface | undefined,
|
|
49
|
+
languageStorage: undefined as LanguageStorageInterface | undefined,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const onClick: TranslationOnClick = async (event, { keysAndDefaults }) => {
|
|
53
|
+
const withNs: UiKeyOption[] = keysAndDefaults.map(
|
|
54
|
+
({ key, ns, defaultValue }) => ({
|
|
55
|
+
key,
|
|
56
|
+
defaultValue,
|
|
57
|
+
ns: getFallbackArray(getTranslationNs({ key, ns, defaultValue })),
|
|
58
|
+
translation: getTranslation({
|
|
59
|
+
key,
|
|
60
|
+
ns,
|
|
61
|
+
}),
|
|
62
|
+
})
|
|
63
|
+
);
|
|
64
|
+
instances.ui?.handleElementClick(event, withNs);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const run = (isDev: boolean) => {
|
|
68
|
+
if (!instances.ui && plugins.ui) {
|
|
69
|
+
instances.ui = new plugins.ui({
|
|
70
|
+
apiKey: getInitialOptions().apiKey!,
|
|
71
|
+
apiUrl: getInitialOptions().apiUrl!,
|
|
72
|
+
highlight,
|
|
73
|
+
changeTranslation,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (!instances.observer) {
|
|
77
|
+
instances.observer = plugins.observer?.({
|
|
78
|
+
translate,
|
|
79
|
+
onClick,
|
|
80
|
+
options: getObserverOptions(),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
instances.observer?.run({ mouseHighlight: isDev });
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const stop = () => {
|
|
87
|
+
instances.ui = undefined;
|
|
88
|
+
instances.observer?.stop();
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const highlight: HighlightInterface = (key, ns) => {
|
|
92
|
+
return instances.observer?.highlight?.(key, ns) || { unhighlight() {} };
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const translate = (props: TranslatePropsInternal) => {
|
|
96
|
+
const translation = getTranslation(props);
|
|
97
|
+
return formatTranslation({ ...props, translation, formatEnabled: true });
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const setObserver = (observer: ObserverInterface | undefined) => {
|
|
101
|
+
plugins.observer = observer;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const hasObserver = () => {
|
|
105
|
+
return Boolean(plugins.observer);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const addFormatter = (formatter: FormatterInterface | undefined) => {
|
|
109
|
+
if (formatter) {
|
|
110
|
+
instances.formatters.push(formatter);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const setFinalFormatter = (
|
|
115
|
+
formatter: FinalFormatterInterface | undefined
|
|
116
|
+
) => {
|
|
117
|
+
instances.finalFormatter = formatter;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const setUi = (ui: UiType | undefined) => {
|
|
121
|
+
plugins.ui = (ui as UiLibInterface)?.UI || ui;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const hasUi = () => {
|
|
125
|
+
return Boolean(plugins.ui);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const setLanguageStorage = (
|
|
129
|
+
storage: LanguageStorageInterface | undefined
|
|
130
|
+
) => {
|
|
131
|
+
instances.languageStorage = storage;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const getLanguageStorage = () => {
|
|
135
|
+
return instances.languageStorage;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const setStoredLanguage = (language: string) => {
|
|
139
|
+
instances.languageStorage?.setLanguage(language);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const setLanguageDetector = (
|
|
143
|
+
detector: LanguageDetectorInterface | undefined
|
|
144
|
+
) => {
|
|
145
|
+
instances.languageDetector = detector;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const getLanguageDetector = () => {
|
|
149
|
+
return instances.languageDetector;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const detectLanguage = () => {
|
|
153
|
+
if (!instances.languageDetector) {
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const availableLanguages = getAvailableLanguages()!;
|
|
158
|
+
|
|
159
|
+
return instances.languageDetector.getLanguage({
|
|
160
|
+
availableLanguages,
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const getInitialLanguage = () => {
|
|
165
|
+
const availableLanguages = getAvailableLanguages();
|
|
166
|
+
const languageOrPromise = instances.languageStorage?.getLanguage();
|
|
167
|
+
|
|
168
|
+
return valueOrPromise(languageOrPromise, (language) => {
|
|
169
|
+
if (
|
|
170
|
+
(!availableLanguages || availableLanguages.includes(language!)) &&
|
|
171
|
+
language
|
|
172
|
+
) {
|
|
173
|
+
return language;
|
|
174
|
+
}
|
|
175
|
+
return detectLanguage();
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const addBackend = (backend: BackendInterface | undefined) => {
|
|
180
|
+
if (backend) {
|
|
181
|
+
instances.backends.push(backend);
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const setDevBackend = (backend: BackendDevInterface | undefined) => {
|
|
186
|
+
instances.devBackend = backend;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const getDevBackend = () => {
|
|
190
|
+
return instances.devBackend;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const getBackendDevRecord: BackendGetRecord = ({ language, namespace }) => {
|
|
194
|
+
return instances.devBackend?.getRecord({
|
|
195
|
+
apiKey: getInitialOptions().apiKey,
|
|
196
|
+
apiUrl: getInitialOptions().apiUrl,
|
|
197
|
+
language,
|
|
198
|
+
namespace,
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const getBackendRecord: BackendGetRecord = ({ language, namespace }) => {
|
|
203
|
+
for (const backend of instances.backends) {
|
|
204
|
+
const data = backend.getRecord({ language, namespace });
|
|
205
|
+
if (isPromise(data)) {
|
|
206
|
+
return data?.catch((e) => {
|
|
207
|
+
// eslint-disable-next-line no-console
|
|
208
|
+
console.error(e);
|
|
209
|
+
return {};
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
if (data !== undefined) {
|
|
213
|
+
return data;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return undefined;
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const formatTranslation = ({
|
|
220
|
+
key,
|
|
221
|
+
translation,
|
|
222
|
+
defaultValue,
|
|
223
|
+
noWrap,
|
|
224
|
+
params,
|
|
225
|
+
orEmpty,
|
|
226
|
+
ns,
|
|
227
|
+
formatEnabled,
|
|
228
|
+
}: TranslatePropsInternal & { formatEnabled?: boolean }) => {
|
|
229
|
+
const formattableTranslation = translation || defaultValue;
|
|
230
|
+
let result = formattableTranslation || (orEmpty ? '' : key);
|
|
231
|
+
if (instances.observer && !noWrap) {
|
|
232
|
+
result = instances.observer.wrap({
|
|
233
|
+
key,
|
|
234
|
+
translation: result,
|
|
235
|
+
defaultValue,
|
|
236
|
+
params,
|
|
237
|
+
ns,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const language = getLanguage();
|
|
242
|
+
const isFormatEnabled =
|
|
243
|
+
formatEnabled || !instances.observer?.outputNotFormattable;
|
|
244
|
+
if (formattableTranslation && language && isFormatEnabled) {
|
|
245
|
+
for (const formatter of instances.formatters) {
|
|
246
|
+
result = formatter.format({
|
|
247
|
+
translation: result,
|
|
248
|
+
language,
|
|
249
|
+
params,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (
|
|
255
|
+
instances.finalFormatter &&
|
|
256
|
+
formattableTranslation &&
|
|
257
|
+
language &&
|
|
258
|
+
isFormatEnabled
|
|
259
|
+
) {
|
|
260
|
+
result = instances.finalFormatter.format({
|
|
261
|
+
translation: result,
|
|
262
|
+
language,
|
|
263
|
+
params,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
return result;
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
const wrap = (params: WrapperWrapProps) => {
|
|
270
|
+
if (instances.observer) {
|
|
271
|
+
return instances.observer?.wrap(params);
|
|
272
|
+
}
|
|
273
|
+
return params.translation;
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const unwrap = (text: string): Unwrapped => {
|
|
277
|
+
if (instances.observer) {
|
|
278
|
+
return instances.observer?.unwrap(text);
|
|
279
|
+
}
|
|
280
|
+
return { text, keys: [] };
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
const retranslate = () => {
|
|
284
|
+
instances.observer?.retranslate();
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
return Object.freeze({
|
|
288
|
+
setFinalFormatter,
|
|
289
|
+
addFormatter,
|
|
290
|
+
formatTranslation,
|
|
291
|
+
setObserver,
|
|
292
|
+
hasObserver,
|
|
293
|
+
setUi,
|
|
294
|
+
hasUi,
|
|
295
|
+
addBackend,
|
|
296
|
+
setDevBackend,
|
|
297
|
+
getDevBackend,
|
|
298
|
+
getBackendRecord,
|
|
299
|
+
getBackendDevRecord,
|
|
300
|
+
setLanguageDetector,
|
|
301
|
+
getLanguageDetector,
|
|
302
|
+
setLanguageStorage,
|
|
303
|
+
getLanguageStorage,
|
|
304
|
+
getInitialLanguage,
|
|
305
|
+
setStoredLanguage,
|
|
306
|
+
run,
|
|
307
|
+
stop,
|
|
308
|
+
retranslate,
|
|
309
|
+
highlight,
|
|
310
|
+
wrap,
|
|
311
|
+
unwrap,
|
|
312
|
+
});
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
export type PluginServiceType = ReturnType<typeof PluginService>;
|