@scbt-ecom/ui 0.127.1 → 0.128.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.
|
@@ -8,15 +8,57 @@ export interface Variable<Key = string, Value = string> {
|
|
|
8
8
|
}
|
|
9
9
|
export type VariableEntry<Key = string, Value = string> = [Key, Value];
|
|
10
10
|
export interface IVariableContextHolder<Key, Value> {
|
|
11
|
+
/**
|
|
12
|
+
* список переменных, находящихся в имплементации
|
|
13
|
+
*/
|
|
11
14
|
variables: Variable<Key, Value>[];
|
|
15
|
+
/**
|
|
16
|
+
* метод для добавления переменной
|
|
17
|
+
* @param variable
|
|
18
|
+
*/
|
|
12
19
|
append: (variable: Variable<Key, Value>) => void;
|
|
20
|
+
/**
|
|
21
|
+
* метод для удаления переменной
|
|
22
|
+
* @param key
|
|
23
|
+
*/
|
|
13
24
|
remove: (key: Key) => void;
|
|
25
|
+
/**
|
|
26
|
+
* метод для проверки наличия переменной по ключу
|
|
27
|
+
* @param key
|
|
28
|
+
*/
|
|
14
29
|
has: (key: Key) => boolean;
|
|
30
|
+
/**
|
|
31
|
+
* метод для замены всех переменных
|
|
32
|
+
* @param variables
|
|
33
|
+
*/
|
|
15
34
|
replace: (variables: Variable<Key, Value>[]) => void;
|
|
35
|
+
/**
|
|
36
|
+
* метод для очистки переменных
|
|
37
|
+
*/
|
|
16
38
|
clear: () => void;
|
|
39
|
+
/**
|
|
40
|
+
* метод для обновления переменной, по её идентификатору
|
|
41
|
+
* @param id
|
|
42
|
+
* @param variable
|
|
43
|
+
*/
|
|
17
44
|
update: (id: string, variable: Variable<Key, Value>) => void;
|
|
45
|
+
/**
|
|
46
|
+
* получение вхождений переменных по ключам
|
|
47
|
+
* @param keys
|
|
48
|
+
* @returns {VariableEntry<Key, Value>[]} entries `Array<[Key, Value]>`
|
|
49
|
+
*/
|
|
18
50
|
entriesOf: (...keys: Key[]) => VariableEntry<Key, Value>[];
|
|
51
|
+
/**
|
|
52
|
+
* метод для подписки на изменения переменных
|
|
53
|
+
* @param listener
|
|
54
|
+
* @returns функция для отписки
|
|
55
|
+
*/
|
|
19
56
|
observe: (listener: (variables: Variable<Key, Value>[]) => void) => () => void;
|
|
57
|
+
/**
|
|
58
|
+
* получение переменной по ключу
|
|
59
|
+
* @param key
|
|
60
|
+
* @returns `Variable<Key, Value>` если переменная присутствует, `undefined` если переменной не существует
|
|
61
|
+
*/
|
|
20
62
|
get: (key: Key) => Variable<Key, Value> | undefined;
|
|
21
63
|
}
|
|
22
64
|
export interface VariableStore {
|
|
@@ -25,7 +67,90 @@ export interface VariableStore {
|
|
|
25
67
|
clearItems: (...keys: string[]) => void;
|
|
26
68
|
}
|
|
27
69
|
/**
|
|
28
|
-
* Класс для управления
|
|
70
|
+
* Класс для управления переменными.
|
|
71
|
+
* Присутствует возможность использования в среде исполнения NodeJS, при этом будет использоваться in-memory хранилище переменных, что может потреблять дополнительную память приложения
|
|
72
|
+
*
|
|
73
|
+
* @example Базовое использование
|
|
74
|
+
* ```ts
|
|
75
|
+
* // используем статичный метод класса для получения инстанса
|
|
76
|
+
* const holder = VariableContextHolder.getInstance('VARIABLE_STORE')
|
|
77
|
+
*
|
|
78
|
+
* // эмулируем создание переменной
|
|
79
|
+
* const variable: Variable = {
|
|
80
|
+
* _id: Math.random().toString(36).substring(2),
|
|
81
|
+
* // ключ должен быть обёрнут в шаблон переменной
|
|
82
|
+
* // чтобы это сделать, используем статичный метод
|
|
83
|
+
* key: VariableContextHolder.wrap('variable_key'),
|
|
84
|
+
* value: 'variable_value',
|
|
85
|
+
* createdAt: new Date().toISOString(),
|
|
86
|
+
* updatedAt: new Date().toISOString(),
|
|
87
|
+
* description: ''
|
|
88
|
+
* }
|
|
89
|
+
*
|
|
90
|
+
* holder.append(variable)
|
|
91
|
+
*
|
|
92
|
+
* holder.variables.forEach((v) => {
|
|
93
|
+
* // рендерим переменные как в соответствии с требованиями
|
|
94
|
+
* })
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* @example Использование с react
|
|
98
|
+
* ```tsx
|
|
99
|
+
* const Component = () => {
|
|
100
|
+
* // создадим ref с экземпляром класса (это нужно чтобы не изменять ссылку при ре-рендере)
|
|
101
|
+
* const holder = useRef(VariableContextHolder.getInstance('VARIABLE_STORE'))
|
|
102
|
+
* // подключаем и подписываемся на мутацию переменных
|
|
103
|
+
* const variables = useSyncExternalStore(holder.current.observe, () => holder.current.variables)
|
|
104
|
+
*
|
|
105
|
+
* return (
|
|
106
|
+
* <div>
|
|
107
|
+
* {variables.map((variable) => (
|
|
108
|
+
* // рендерим переменные как в соответствии с требованиями
|
|
109
|
+
* ))}
|
|
110
|
+
* </div>
|
|
111
|
+
* )
|
|
112
|
+
* }
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @example Синхронизация с сервером
|
|
116
|
+
* ```ts
|
|
117
|
+
* const holder = VariableContextHolder.getInstance('VARIABLE_STORE')
|
|
118
|
+
*
|
|
119
|
+
* // загружаем переменные с сервера
|
|
120
|
+
* fetch('https://backend.url/variables')
|
|
121
|
+
* .then((response) => response.json())
|
|
122
|
+
* .then((data) => holder.replace(data))
|
|
123
|
+
* ```
|
|
124
|
+
*
|
|
125
|
+
* @example Обход строки для замены переменных на их значения
|
|
126
|
+
* ```ts
|
|
127
|
+
* const holder = VariableContextHolder.getInstance('VARIABLE_STORE')
|
|
128
|
+
*
|
|
129
|
+
* const transformVariable = (value: string): string => {
|
|
130
|
+
* let str = value
|
|
131
|
+
* // находим все переменные в строке
|
|
132
|
+
* let matches = VariableContextHolder.match(str)
|
|
133
|
+
* // получаем вхождения по найденным переменным
|
|
134
|
+
* let variables = holder.entriesOf(...(matches ?? []))
|
|
135
|
+
*
|
|
136
|
+
* // выполняем замену переменных до тех пор, пока в строке содержатся переменные
|
|
137
|
+
* while (!TypeGuards.isArrayEmpty(variables)) {
|
|
138
|
+
* variables.forEach(([key, value]) => {
|
|
139
|
+
* // заменяем каждую переменную на её значение
|
|
140
|
+
* str = str.replace(key, value)
|
|
141
|
+
* })
|
|
142
|
+
* // пробуем снова получить переменные в строке,
|
|
143
|
+
* // так как переменная может содержать другую переменную
|
|
144
|
+
* matches = VariableContextHolder.match(str)
|
|
145
|
+
* variables = holder.entriesOf(...(matches ?? []))
|
|
146
|
+
* }
|
|
147
|
+
*
|
|
148
|
+
* return str
|
|
149
|
+
* }
|
|
150
|
+
*
|
|
151
|
+
* const stringWithVariables = 'Процентная ставка \${percent}% годовых до \${months} месяцев'
|
|
152
|
+
* const processedString = transformVariable(stringWithVariables)
|
|
153
|
+
* ```
|
|
29
154
|
*/
|
|
30
155
|
export declare class VariableContextHolder<Key extends string = string, Value = string> implements IVariableContextHolder<Key, Value> {
|
|
31
156
|
private _store;
|
|
@@ -37,9 +162,27 @@ export declare class VariableContextHolder<Key extends string = string, Value =
|
|
|
37
162
|
private static _VARIABLE_PATTERN;
|
|
38
163
|
private static _instance;
|
|
39
164
|
private constructor();
|
|
165
|
+
/**
|
|
166
|
+
* метод для извлечения ключа переменной из шаблона
|
|
167
|
+
* @param variable
|
|
168
|
+
*/
|
|
40
169
|
static unwrap(variable: string): string;
|
|
170
|
+
/**
|
|
171
|
+
* метод для оборачивания ключа переменной в шаблон
|
|
172
|
+
* @param variable
|
|
173
|
+
*/
|
|
41
174
|
static wrap(variable: string): string;
|
|
175
|
+
/**
|
|
176
|
+
* метод для поиска переменных в строке
|
|
177
|
+
* @param pattern
|
|
178
|
+
* @returns `string[]` если переменные присутствуют в строке, иначе `null`
|
|
179
|
+
*/
|
|
42
180
|
static match(pattern: string): string[] | null;
|
|
181
|
+
/**
|
|
182
|
+
* метод для получения синглтон экземпляра класса по ключу хранилища
|
|
183
|
+
* @param store
|
|
184
|
+
* @returns экземпляр подключенный к in-memory хранилищу если код выполняется в NodeJS, `localStorage` если в браузере
|
|
185
|
+
*/
|
|
43
186
|
static getInstance(store: string): VariableContextHolder;
|
|
44
187
|
get variables(): Variable<Key, Value>[];
|
|
45
188
|
private collect;
|