@tolgee/core 5.33.2 → 5.33.3-prerelease.2efc0e6b.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 +227 -186
- 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.js +227 -186
- package/dist/tolgee.esm.js.map +1 -1
- package/dist/tolgee.esm.min.js +1 -1
- package/dist/tolgee.esm.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 +227 -186
- package/dist/tolgee.esm.mjs.map +1 -1
- package/dist/tolgee.umd.js +227 -186
- 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 +8 -12
- package/lib/Controller/Cache/helpers.d.ts +3 -2
- package/lib/Controller/Controller.d.ts +57 -26
- package/lib/Controller/Events/EventEmitter.d.ts +5 -5
- package/lib/Controller/Events/EventEmitterCombined.d.ts +6 -0
- package/lib/Controller/Events/Events.d.ts +39 -12
- package/lib/Controller/State/State.d.ts +10 -4
- package/lib/Controller/State/initState.d.ts +29 -7
- package/lib/TolgeeCore.d.ts +25 -28
- package/lib/helpers.d.ts +2 -2
- package/lib/types/cache.d.ts +19 -1
- package/lib/types/events.d.ts +24 -23
- package/lib/types/index.d.ts +1 -1
- package/package.json +2 -2
- package/src/Controller/Cache/Cache.test.ts +189 -0
- package/src/Controller/Cache/Cache.ts +118 -57
- package/src/Controller/Cache/helpers.ts +12 -3
- package/src/Controller/Controller.ts +81 -27
- package/src/Controller/Events/EventEmitter.ts +23 -15
- package/src/Controller/Events/EventEmitterCombined.ts +55 -0
- package/src/Controller/Events/Events.ts +31 -23
- package/src/Controller/Plugins/Plugins.ts +5 -0
- package/src/Controller/State/State.ts +26 -6
- package/src/Controller/State/initState.ts +35 -7
- package/src/TolgeeCore.ts +14 -17
- package/src/__test/cache.test.ts +2 -26
- package/src/__test/client.test.ts +3 -3
- package/src/__test/events.test.ts +40 -13
- package/src/__test/load.matrix.test.ts +123 -0
- package/src/__test/load.required.test.ts +71 -0
- package/src/__test/namespaces.required.test.ts +52 -0
- package/src/__test/options.test.ts +1 -1
- package/src/__test/testTools.ts +39 -0
- package/src/helpers.ts +2 -1
- package/src/types/cache.ts +24 -1
- package/src/types/events.ts +33 -24
- package/src/types/index.ts +1 -0
- package/lib/Controller/Events/EventEmitterSelective.d.ts +0 -7
- package/src/Controller/Events/EventEmitterSelective.test.ts +0 -110
- package/src/Controller/Events/EventEmitterSelective.ts +0 -133
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Controller } from '../Controller/Controller';
|
|
2
|
+
|
|
3
|
+
describe('required namespaces', () => {
|
|
4
|
+
it('<default>', () => {
|
|
5
|
+
const controller = Controller({
|
|
6
|
+
options: {},
|
|
7
|
+
});
|
|
8
|
+
expect(controller.getDefaultNs()).toEqual('');
|
|
9
|
+
expect(controller.getRequiredNamespaces()).toEqual(['']);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('ns:[common]', () => {
|
|
13
|
+
const controller = Controller({
|
|
14
|
+
options: { ns: ['common'] },
|
|
15
|
+
});
|
|
16
|
+
expect(controller.getRequiredNamespaces()).toEqual(['common']);
|
|
17
|
+
expect(controller.getDefaultNs()).toEqual('common');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('defaultNs: test', () => {
|
|
21
|
+
const controller = Controller({
|
|
22
|
+
options: { defaultNs: 'test' },
|
|
23
|
+
});
|
|
24
|
+
expect(controller.getRequiredNamespaces()).toEqual(['test']);
|
|
25
|
+
expect(controller.getDefaultNs()).toEqual('test');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('defaultNs: test, ns:[common]', () => {
|
|
29
|
+
const controller = Controller({
|
|
30
|
+
options: { defaultNs: 'test', ns: ['common'] },
|
|
31
|
+
});
|
|
32
|
+
expect(controller.getRequiredNamespaces()).toEqual(['test', 'common']);
|
|
33
|
+
expect(controller.getDefaultNs()).toEqual('test');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('defaultNs, ns, fallbackNs', () => {
|
|
37
|
+
const controller = Controller({
|
|
38
|
+
options: {
|
|
39
|
+
defaultNs: 'test',
|
|
40
|
+
ns: ['common', 'test2'],
|
|
41
|
+
fallbackNs: ['fallback', 'fallback2'],
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
expect(controller.getRequiredNamespaces()).toEqual([
|
|
45
|
+
'test',
|
|
46
|
+
'common',
|
|
47
|
+
'test2',
|
|
48
|
+
'fallback',
|
|
49
|
+
'fallback2',
|
|
50
|
+
]);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -41,7 +41,7 @@ describe('initial options', () => {
|
|
|
41
41
|
expect(restrictedElements).toEqual(['a']);
|
|
42
42
|
expect(highlightColor).toEqual('red');
|
|
43
43
|
expect(inputPrefix).toEqual('%-%tolgee:');
|
|
44
|
-
expect(defaultNs).toEqual(
|
|
44
|
+
expect(defaultNs).toEqual(undefined);
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
it('sanitizes url', () => {
|
package/src/__test/testTools.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { TolgeePlugin } from '../types';
|
|
2
|
+
|
|
1
3
|
export const resolvablePromise = <T = any>() => {
|
|
2
4
|
let resolve: (value: T) => void;
|
|
3
5
|
const promise = new Promise<T>((innerResolve) => {
|
|
@@ -5,3 +7,40 @@ export const resolvablePromise = <T = any>() => {
|
|
|
5
7
|
});
|
|
6
8
|
return [promise, resolve!] as const;
|
|
7
9
|
};
|
|
10
|
+
|
|
11
|
+
export const DevToolsPlugin =
|
|
12
|
+
(postfix = ''): TolgeePlugin =>
|
|
13
|
+
(tolgee, tools) => {
|
|
14
|
+
tolgee.updateOptions({ apiKey: 'test', apiUrl: 'test' });
|
|
15
|
+
tools.setDevBackend({
|
|
16
|
+
getRecord({ language, namespace }) {
|
|
17
|
+
return Promise.resolve({
|
|
18
|
+
test: { sub: `${language}.${namespace || 'default'}${postfix}` },
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
return tolgee;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const BackendPlugin =
|
|
26
|
+
(postfix = ''): TolgeePlugin =>
|
|
27
|
+
(tolgee, tools) => {
|
|
28
|
+
tools.addBackend({
|
|
29
|
+
getRecord({ language, namespace }) {
|
|
30
|
+
return Promise.resolve({
|
|
31
|
+
test: { sub: `${language}.${namespace || 'default'}${postfix}` },
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
return tolgee;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const DevToolsThrow = (): TolgeePlugin => (tolgee, tools) => {
|
|
39
|
+
tolgee.updateOptions({ apiKey: 'test', apiUrl: 'test' });
|
|
40
|
+
tools.setDevBackend({
|
|
41
|
+
getRecord() {
|
|
42
|
+
return Promise.reject();
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
return tolgee;
|
|
46
|
+
};
|
package/src/helpers.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
FallbackLanguageOption,
|
|
5
5
|
FetchFn,
|
|
6
6
|
TolgeeError,
|
|
7
|
+
ErrorEvent,
|
|
7
8
|
} from './types';
|
|
8
9
|
import { EventEmitterInstance } from './Controller/Events/EventEmitter';
|
|
9
10
|
|
|
@@ -25,7 +26,7 @@ export function valueOrPromise<T, R>(
|
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
export function handleRegularOrAsyncErr<T>(
|
|
28
|
-
onError: EventEmitterInstance<
|
|
29
|
+
onError: EventEmitterInstance<ErrorEvent>,
|
|
29
30
|
createError: (e: any) => TolgeeError,
|
|
30
31
|
callback: () => Promise<T> | T
|
|
31
32
|
): Promise<T> | T {
|
package/src/types/cache.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type TranslationValue = string | undefined | null;
|
|
2
2
|
|
|
3
|
-
export type TranslationsFlat =
|
|
3
|
+
export type TranslationsFlat = Record<string, TranslationValue>;
|
|
4
4
|
|
|
5
5
|
export type TreeTranslationsData = {
|
|
6
6
|
[key: string]: TranslationValue | TreeTranslationsData;
|
|
@@ -35,3 +35,26 @@ export type CachePublicRecord = {
|
|
|
35
35
|
language: string;
|
|
36
36
|
namespace: string;
|
|
37
37
|
};
|
|
38
|
+
|
|
39
|
+
export type CacheInternalRecord = {
|
|
40
|
+
data: TranslationsFlat;
|
|
41
|
+
language: string;
|
|
42
|
+
namespace: string;
|
|
43
|
+
cacheKey: string;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export type LoadOptions = {
|
|
47
|
+
noDev?: boolean;
|
|
48
|
+
useCache?: boolean;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type LoadRequiredOptions = LoadOptions & {
|
|
52
|
+
language?: string;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export type MatrixOptions = {
|
|
56
|
+
languages: string[] | 'all';
|
|
57
|
+
namespaces: string[] | 'all';
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export type LoadMatrixOptions = LoadOptions & MatrixOptions;
|
package/src/types/events.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { NsFallback } from './general';
|
|
2
1
|
import type { CacheDescriptorWithKey } from './cache';
|
|
3
2
|
import { TolgeeError } from './errors';
|
|
4
3
|
|
|
@@ -6,19 +5,26 @@ export type Subscription = {
|
|
|
6
5
|
unsubscribe: () => void;
|
|
7
6
|
};
|
|
8
7
|
|
|
9
|
-
export type
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export type
|
|
21
|
-
export type
|
|
8
|
+
export type ListenerEvent<E extends string, T> = { type: E; value: T };
|
|
9
|
+
export type Handler<E extends ListenerEvent<string, any>> = (e: E) => void;
|
|
10
|
+
export type CombinedHandler<E extends ListenerEvent<string, any>> = (
|
|
11
|
+
e: E[]
|
|
12
|
+
) => void;
|
|
13
|
+
|
|
14
|
+
export type LanguageEvent = ListenerEvent<'language', string>;
|
|
15
|
+
export type PendingLanguageEvent = ListenerEvent<'pendingLanguage', string>;
|
|
16
|
+
export type LoadingEvent = ListenerEvent<'loading', boolean>;
|
|
17
|
+
export type FetchingEvent = ListenerEvent<'fetching', boolean>;
|
|
18
|
+
export type InitialLoadEvent = ListenerEvent<'initialLoad', void>;
|
|
19
|
+
export type RunningEvent = ListenerEvent<'running', boolean>;
|
|
20
|
+
export type CacheEvent = ListenerEvent<'cache', CacheDescriptorWithKey>;
|
|
21
|
+
export type ErrorEvent = ListenerEvent<'error', TolgeeError>;
|
|
22
|
+
export type PermanentChangeEvent = ListenerEvent<
|
|
23
|
+
'permanentChange',
|
|
24
|
+
TranslationDescriptor
|
|
25
|
+
>;
|
|
26
|
+
|
|
27
|
+
export type UpdateEvent = LanguageEvent | CacheEvent | InitialLoadEvent;
|
|
22
28
|
|
|
23
29
|
export type TolgeeEvent =
|
|
24
30
|
| 'language'
|
|
@@ -49,54 +55,57 @@ export type TolgeeOn<E extends keyof EventType = keyof EventType> = {
|
|
|
49
55
|
* Emitted when any key needs (or might need) to be re-rendered.
|
|
50
56
|
* Similar to tolgee.onNsUpdate, except for all namespaces.
|
|
51
57
|
*/
|
|
52
|
-
(event: 'update', handler:
|
|
58
|
+
(event: 'update', handler: CombinedHandler<UpdateEvent>): Subscription;
|
|
53
59
|
|
|
54
60
|
/**
|
|
55
61
|
* Emitted on language change.
|
|
56
62
|
*/
|
|
57
|
-
(event: 'language', handler:
|
|
63
|
+
(event: 'language', handler: Handler<LanguageEvent>): Subscription;
|
|
58
64
|
|
|
59
65
|
/**
|
|
60
66
|
* Emitted on pendingLanguage change.
|
|
61
67
|
*/
|
|
62
|
-
(
|
|
68
|
+
(
|
|
69
|
+
event: 'pendingLanguage',
|
|
70
|
+
handler: Handler<PendingLanguageEvent>
|
|
71
|
+
): Subscription;
|
|
63
72
|
|
|
64
73
|
/**
|
|
65
74
|
* Emitted on loading change. Changes when tolgee is loading some data for the first time.
|
|
66
75
|
*/
|
|
67
|
-
(event: 'loading', handler:
|
|
76
|
+
(event: 'loading', handler: Handler<LoadingEvent>): Subscription;
|
|
68
77
|
|
|
69
78
|
/**
|
|
70
79
|
* Emitted on fetching change. Changes when tolgee is fetching any data.
|
|
71
80
|
*/
|
|
72
|
-
(event: 'fetching', handler:
|
|
81
|
+
(event: 'fetching', handler: Handler<FetchingEvent>): Subscription;
|
|
73
82
|
|
|
74
83
|
/**
|
|
75
84
|
* Emitted when `tolgee.run` method finishes.
|
|
76
85
|
*/
|
|
77
|
-
(event: 'initialLoad', handler:
|
|
86
|
+
(event: 'initialLoad', handler: Handler<InitialLoadEvent>): Subscription;
|
|
78
87
|
|
|
79
88
|
/**
|
|
80
89
|
* Emitted when internal `running` state changes.
|
|
81
90
|
*/
|
|
82
|
-
(event: 'running', handler:
|
|
91
|
+
(event: 'running', handler: Handler<RunningEvent>): Subscription;
|
|
83
92
|
|
|
84
93
|
/**
|
|
85
94
|
* Emitted when cache changes.
|
|
86
95
|
*/
|
|
87
|
-
(event: 'cache', handler:
|
|
96
|
+
(event: 'cache', handler: Handler<CacheEvent>): Subscription;
|
|
88
97
|
|
|
89
98
|
/**
|
|
90
99
|
* Emitted on errors
|
|
91
100
|
*/
|
|
92
|
-
(event: 'error', handler:
|
|
101
|
+
(event: 'error', handler: Handler<ErrorEvent>): Subscription;
|
|
93
102
|
|
|
94
103
|
/**
|
|
95
104
|
* Translation was changed or created via dev tools
|
|
96
105
|
*/
|
|
97
106
|
(
|
|
98
107
|
event: 'permanentChange',
|
|
99
|
-
handler:
|
|
108
|
+
handler: Handler<PermanentChangeEvent>
|
|
100
109
|
): Subscription;
|
|
101
110
|
|
|
102
111
|
(event: E, handler: unknown): Subscription;
|
package/src/types/index.ts
CHANGED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { Subscription, Listener, SubscriptionSelective } from '../../types';
|
|
2
|
-
export declare function EventEmitterSelective(isActive: () => boolean, getFallbackNs: () => string[], getDefaultNs: () => string): EventEmitterSelectiveInstance;
|
|
3
|
-
export type EventEmitterSelectiveInstance = {
|
|
4
|
-
readonly listenSome: (handler: Listener<undefined>) => SubscriptionSelective;
|
|
5
|
-
readonly listen: (handler: Listener<undefined>) => Subscription;
|
|
6
|
-
readonly emit: (ns?: string[], delayed?: boolean) => void;
|
|
7
|
-
};
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { EventEmitterSelective } from './EventEmitterSelective';
|
|
2
|
-
|
|
3
|
-
describe('event emitter selective', () => {
|
|
4
|
-
it('handles correctly default namespace', () => {
|
|
5
|
-
const emitter = EventEmitterSelective(
|
|
6
|
-
() => true,
|
|
7
|
-
() => [],
|
|
8
|
-
() => 'default'
|
|
9
|
-
);
|
|
10
|
-
const handler = jest.fn();
|
|
11
|
-
const listener = emitter.listenSome(handler);
|
|
12
|
-
|
|
13
|
-
// subscribe to default ns
|
|
14
|
-
listener.subscribeNs();
|
|
15
|
-
|
|
16
|
-
// emmit
|
|
17
|
-
emitter.emit(['default']);
|
|
18
|
-
// should be ignored
|
|
19
|
-
emitter.emit(['c']);
|
|
20
|
-
|
|
21
|
-
expect(handler).toBeCalledTimes(1);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('unsubscribes', () => {
|
|
25
|
-
const emitter = EventEmitterSelective(
|
|
26
|
-
() => true,
|
|
27
|
-
() => [],
|
|
28
|
-
() => ''
|
|
29
|
-
);
|
|
30
|
-
const handler = jest.fn();
|
|
31
|
-
const listener = emitter.listen(handler);
|
|
32
|
-
|
|
33
|
-
emitter.emit();
|
|
34
|
-
|
|
35
|
-
listener.unsubscribe();
|
|
36
|
-
emitter.emit();
|
|
37
|
-
expect(handler).toBeCalledTimes(1);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('groups events correctly', async () => {
|
|
41
|
-
const emitter = EventEmitterSelective(
|
|
42
|
-
() => true,
|
|
43
|
-
() => ['test', 'opqrst'],
|
|
44
|
-
() => ''
|
|
45
|
-
);
|
|
46
|
-
const handler = jest.fn();
|
|
47
|
-
const hanlderAll = jest.fn();
|
|
48
|
-
const listener = emitter.listenSome(handler);
|
|
49
|
-
const listenerAll = emitter.listen(hanlderAll);
|
|
50
|
-
|
|
51
|
-
listener.subscribeNs('test');
|
|
52
|
-
|
|
53
|
-
// is fallback should always call handler
|
|
54
|
-
emitter.emit(['opqrst'], true);
|
|
55
|
-
|
|
56
|
-
await new Promise((resolve) => setTimeout(resolve));
|
|
57
|
-
|
|
58
|
-
expect(hanlderAll).toBeCalledTimes(1);
|
|
59
|
-
expect(handler).toBeCalledTimes(1);
|
|
60
|
-
|
|
61
|
-
// these should be merged together
|
|
62
|
-
emitter.emit(['abcd'], true);
|
|
63
|
-
emitter.emit(['abcd']);
|
|
64
|
-
|
|
65
|
-
expect(hanlderAll).toBeCalledTimes(2);
|
|
66
|
-
expect(handler).toBeCalledTimes(1);
|
|
67
|
-
|
|
68
|
-
listener.unsubscribe();
|
|
69
|
-
listenerAll.unsubscribe();
|
|
70
|
-
emitter.emit();
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('always subscribes to fallback ns', async () => {
|
|
74
|
-
const emitter = EventEmitterSelective(
|
|
75
|
-
() => true,
|
|
76
|
-
() => ['fallback1', 'fallback2'],
|
|
77
|
-
() => ''
|
|
78
|
-
);
|
|
79
|
-
const handler = jest.fn();
|
|
80
|
-
emitter.listenSome(handler);
|
|
81
|
-
|
|
82
|
-
emitter.emit(['fallback1']);
|
|
83
|
-
expect(handler).toBeCalledTimes(1);
|
|
84
|
-
|
|
85
|
-
emitter.emit(['fallback2']);
|
|
86
|
-
expect(handler).toBeCalledTimes(2);
|
|
87
|
-
|
|
88
|
-
emitter.emit(['test']);
|
|
89
|
-
expect(handler).toBeCalledTimes(2);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('switches off emitting', () => {
|
|
93
|
-
const emitter = EventEmitterSelective(
|
|
94
|
-
() => false,
|
|
95
|
-
() => ['fallback1', 'fallback2'],
|
|
96
|
-
() => ''
|
|
97
|
-
);
|
|
98
|
-
const handler = jest.fn();
|
|
99
|
-
emitter.listenSome(handler);
|
|
100
|
-
|
|
101
|
-
emitter.emit(['fallback1']);
|
|
102
|
-
expect(handler).toBeCalledTimes(0);
|
|
103
|
-
|
|
104
|
-
emitter.emit(['fallback2']);
|
|
105
|
-
expect(handler).toBeCalledTimes(0);
|
|
106
|
-
|
|
107
|
-
emitter.emit(['']);
|
|
108
|
-
expect(handler).toBeCalledTimes(0);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { getFallbackArray } from '../../helpers';
|
|
2
|
-
import {
|
|
3
|
-
NsFallback,
|
|
4
|
-
Subscription,
|
|
5
|
-
Listener,
|
|
6
|
-
ListenerEvent,
|
|
7
|
-
SubscriptionSelective,
|
|
8
|
-
NsType,
|
|
9
|
-
} from '../../types';
|
|
10
|
-
|
|
11
|
-
type NsListType = string;
|
|
12
|
-
|
|
13
|
-
type HandlerWrapperType = {
|
|
14
|
-
fn: Listener<undefined>;
|
|
15
|
-
namespaces: Set<string>;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export function EventEmitterSelective(
|
|
19
|
-
isActive: () => boolean,
|
|
20
|
-
getFallbackNs: () => string[],
|
|
21
|
-
getDefaultNs: () => string
|
|
22
|
-
): EventEmitterSelectiveInstance {
|
|
23
|
-
const listeners: Set<Listener<undefined>> = new Set();
|
|
24
|
-
const partialListeners: Set<HandlerWrapperType> = new Set();
|
|
25
|
-
|
|
26
|
-
function callHandlers(ns: Array<string> | undefined) {
|
|
27
|
-
// everything is implicitly subscribed to fallbacks
|
|
28
|
-
// as it can always fall through to it
|
|
29
|
-
const fallbackNamespaces = new Set(getFallbackNs());
|
|
30
|
-
|
|
31
|
-
partialListeners.forEach((handler) => {
|
|
32
|
-
const nsMatches =
|
|
33
|
-
ns === undefined ||
|
|
34
|
-
ns?.findIndex(
|
|
35
|
-
(ns) => fallbackNamespaces.has(ns) || handler.namespaces.has(ns!)
|
|
36
|
-
) !== -1;
|
|
37
|
-
|
|
38
|
-
if (nsMatches) {
|
|
39
|
-
handler.fn({ value: undefined as any });
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
let queue: (string[] | undefined)[] = [];
|
|
45
|
-
|
|
46
|
-
// merge events in queue into one event
|
|
47
|
-
function solveQueue() {
|
|
48
|
-
if (queue.length === 0) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
const queueCopy = queue;
|
|
52
|
-
queue = [];
|
|
53
|
-
|
|
54
|
-
listeners.forEach((handler) => {
|
|
55
|
-
handler({ value: undefined as any });
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
let namespaces: Set<NsType> | undefined = new Set<NsType>();
|
|
59
|
-
|
|
60
|
-
queueCopy.forEach((ns) => {
|
|
61
|
-
if (ns === undefined) {
|
|
62
|
-
// when no ns specified, it affects all namespaces
|
|
63
|
-
namespaces = undefined;
|
|
64
|
-
} else if (namespaces !== undefined) {
|
|
65
|
-
ns.forEach((ns) => namespaces!.add(ns));
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
const namespacesArray = namespaces
|
|
70
|
-
? Array.from(namespaces.keys())
|
|
71
|
-
: undefined;
|
|
72
|
-
|
|
73
|
-
callHandlers(namespacesArray);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return Object.freeze({
|
|
77
|
-
emit(ns?: string[], delayed?: boolean) {
|
|
78
|
-
if (isActive()) {
|
|
79
|
-
queue.push(ns);
|
|
80
|
-
if (!delayed) {
|
|
81
|
-
solveQueue();
|
|
82
|
-
} else {
|
|
83
|
-
setTimeout(solveQueue, 0);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
listen(handler: Listener<undefined>) {
|
|
89
|
-
listeners.add(handler);
|
|
90
|
-
const result = {
|
|
91
|
-
unsubscribe: () => {
|
|
92
|
-
listeners.delete(handler);
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
return result;
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
listenSome(handler: Listener<undefined>) {
|
|
99
|
-
const handlerWrapper = {
|
|
100
|
-
fn: (e: ListenerEvent<undefined>) => {
|
|
101
|
-
handler(e);
|
|
102
|
-
},
|
|
103
|
-
namespaces: new Set<NsListType>(),
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
partialListeners.add(handlerWrapper);
|
|
107
|
-
|
|
108
|
-
const result = {
|
|
109
|
-
unsubscribe: () => {
|
|
110
|
-
partialListeners.delete(handlerWrapper);
|
|
111
|
-
},
|
|
112
|
-
subscribeNs: (ns: NsFallback) => {
|
|
113
|
-
getFallbackArray(ns).forEach((val) =>
|
|
114
|
-
handlerWrapper.namespaces.add(val)
|
|
115
|
-
);
|
|
116
|
-
if (ns === undefined) {
|
|
117
|
-
// subscribing to default ns
|
|
118
|
-
handlerWrapper.namespaces.add(getDefaultNs());
|
|
119
|
-
}
|
|
120
|
-
return result;
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
return result;
|
|
125
|
-
},
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export type EventEmitterSelectiveInstance = {
|
|
130
|
-
readonly listenSome: (handler: Listener<undefined>) => SubscriptionSelective;
|
|
131
|
-
readonly listen: (handler: Listener<undefined>) => Subscription;
|
|
132
|
-
readonly emit: (ns?: string[], delayed?: boolean) => void;
|
|
133
|
-
};
|