@mediacubeco/base 0.0.1
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/helpers/index.cjs +1 -0
- package/dist/helpers/index.d.ts +513 -0
- package/dist/helpers/index.mjs +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +1243 -0
- package/dist/index.mjs +1 -0
- package/dist/services/index.cjs +1 -0
- package/dist/services/index.d.ts +174 -0
- package/dist/services/index.mjs +1 -0
- package/dist/types/index.cjs +1 -0
- package/dist/types/index.d.ts +195 -0
- package/dist/types/index.mjs +1 -0
- package/dist/utils/index.cjs +1 -0
- package/dist/utils/index.d.ts +587 -0
- package/dist/utils/index.mjs +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const t=t=>t instanceof Error,e=(t,...e)=>{if(t instanceof Function)return t(...e)};class s{isDefaultPrevented=!1;constructor(){this.preventDefault=this.preventDefault.bind(this),this.overrideDefault=this.overrideDefault.bind(this)}preventDefault(){this.isDefaultPrevented=!0}overrideDefault(){this.isDefaultPrevented=!1}}class r{subscriptions={};constructor(){this.emit=this.emit.bind(this),this.on=this.on.bind(this),this.off=this.off.bind(this),this.clear=this.clear.bind(this)}emit(t,s,r){const i=this.subscriptions[t];if(i){const{event:t,listenerList:n}=i;n.forEach(r=>e(r,Object.assign(t,s))),t.isDefaultPrevented||e(r)}else e(r)}on(t,e){const r=this.subscriptions[t];return r?r.listenerList.push(e):this.subscriptions[t]={event:new s,listenerList:[e]},()=>this.off(t,e)}off(t,e){const s=this.subscriptions[t];if(s){const{event:r,listenerList:i}=s;this.subscriptions[t]={event:r,listenerList:i.filter(t=>t!==e)},r.overrideDefault()}}clear(t){delete this.subscriptions[t]}}const i=(t="?",...e)=>{const s=(t&&(r=t,"string"==typeof r)?t:"?").toUpperCase();var r;const i=e.reduce((t,e,s,{length:r})=>{const i=s===r-1?[]:["|"];return t.push(e,...i),t},e.length?["-"]:[]);return[`[${s}]`,...i]};var n,a,o;!function(t){t.StartGroup="group",t.EndGroup="groupEnd",t.Default="log"}(n||(n={})),function(t){t.Info="[36m%s[0m",t.Success="[32m%s[0m",t.Warning="[33m%s[0m",t.Danger="[31m%s[0m"}(a||(a={}));class c{static formatted={info:(...t)=>c.info(...i(...t)),success:(...t)=>c.success(...i(...t)),warning:(...t)=>c.warning(...i(...t)),danger:(...t)=>c.danger(...i(...t))};static#t(t,...e){console[t](...e)}static startGroup(t,e,...s){c.#t(n.StartGroup,...((t,...e)=>["%c%s",t,...e])(`font-size: 16px;${e}`,...i(t,...s)))}static endGroup(){c.#t(n.EndGroup)}static info(...t){c.#t(n.Default,a.Info,...t)}static success(...t){c.#t(n.Default,a.Success,...t)}static warning(...t){c.#t(n.Default,a.Warning,...t)}static danger(...t){c.#t(n.Default,a.Danger,...t)}}exports.ErrorHandlerEventName=void 0,(o=exports.ErrorHandlerEventName||(exports.ErrorHandlerEventName={})).Capture="capture",o.Forward="forward";class u{static eventEmitter=new r;static caseList=[];static log(e,s){const{signal:r,message:i,payload:n,stack:a}=s,o=[i,t(e)?e.message:void 0].filter(Boolean);c.formatted.danger(r,...o,{error:e,payload:n,stack:a})}static get on(){return u.eventEmitter.on}static get off(){return u.eventEmitter.off}static get clear(){return u.eventEmitter.clear}static create(t,e){return new Error(t,{cause:e})}static throw(t,e){throw u.create(t,e)}static capture(t,e){u.log(t,e),u.eventEmitter.emit(exports.ErrorHandlerEventName.Capture,{error:t,config:e})}static forward(t,e){throw u.log(t,e),u.eventEmitter.emit(exports.ErrorHandlerEventName.Capture,{error:t,config:e}),t}static case(t){u.caseList.push(t)}static parse(e){const s={message:"Error!",status:0,errors:{},isExternal:!0};for(const{check:t,parse:r}of u.caseList)if(t(e,s))return r(e,s);return!0===t(e)?{message:e.message,status:s.status,errors:s.errors,isExternal:s.isExternal}:{message:s.message,status:s.status,errors:s.errors,isExternal:s.isExternal}}}exports.ErrorHandler=u,exports.EventEmitter=r,exports.Log=c;
|
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* @description
|
|
4
|
+
* Общие утилитарные типы для проектов на TypeScript.
|
|
5
|
+
* Содержит типы для примитивов (Nullable, NotNullable), структур данных
|
|
6
|
+
* (BaseRecord, Entry, List), функций (Callback, AsyncCallback) и вспомогательные
|
|
7
|
+
* утилиты (KeyOf, ValueOf, Decrement, Increment и др.).
|
|
8
|
+
* Модуль не содержит рантайм-кода — только типы.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* type User = { id: number; name?: string | null }
|
|
13
|
+
*
|
|
14
|
+
* type UserId = ValueOf<Pick<User, 'id'>>
|
|
15
|
+
* type SafeName = NotNullable<User['name']>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
type NullablePrimitive = undefined | null;
|
|
19
|
+
/**
|
|
20
|
+
* Тип, допускающий null или undefined (например для опциональных полей).
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* type MaybeName = Nullable<string> // string | null | undefined
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
type Nullable<Data = undefined> = Data | NullablePrimitive;
|
|
28
|
+
/**
|
|
29
|
+
* Допустимые ключи объекта (как в Record).
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* type Key = BaseKey // string | number | symbol
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
type BaseKey = string | number | symbol;
|
|
37
|
+
/**
|
|
38
|
+
* Массив элементов (базовый тип для списков).
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* type IdList = BaseList<number> // number[]
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
type BaseList<Item = unknown> = Item[];
|
|
46
|
+
/**
|
|
47
|
+
* Объект с ключами Key и значениями Value (обобщение Record).
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* type UserMap = BaseRecord<string, 'name' | 'role'>
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
type BaseRecord<Value = unknown, Key extends BaseKey = BaseKey> = Record<Key, Value>;
|
|
55
|
+
/**
|
|
56
|
+
* Функция без аргументов и возвращаемого значения.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* const noop: Noop = () => {}
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
type Noop = () => void;
|
|
64
|
+
/**
|
|
65
|
+
* Синхронная функция с заданным списком параметров и результатом.
|
|
66
|
+
* @template ParamList - кортеж типов аргументов
|
|
67
|
+
* @template Result - тип возвращаемого значения
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* type Sum = Callback<[number, number], number>
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
type Callback<ParamList extends BaseList = BaseList, Result = void> = (...paramList: ParamList) => Result;
|
|
75
|
+
|
|
76
|
+
declare class Event {
|
|
77
|
+
isDefaultPrevented: boolean;
|
|
78
|
+
constructor();
|
|
79
|
+
preventDefault(): void;
|
|
80
|
+
overrideDefault(): void;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
type EventEmitterDefaultAction = Noop;
|
|
84
|
+
type EventEmitterListener<Params> = Callback<[Event & Params]>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Имена событий, которые генерирует `ErrorHandler`.
|
|
88
|
+
*/
|
|
89
|
+
declare enum ErrorHandlerEventName {
|
|
90
|
+
/** Ошибка была залогирована и передана подписчикам без выбрасывания. */
|
|
91
|
+
Capture = "capture",
|
|
92
|
+
/** Зарезервированное имя события для проброса ошибки дальше по цепочке. */
|
|
93
|
+
Forward = "forward"
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Сообщение об ошибке для пользователя или лога.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* const message: ErrorHandlerMessage = 'Request failed'
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
type ErrorHandlerMessage = string;
|
|
105
|
+
/**
|
|
106
|
+
* Любое значение, которое может быть перехвачено как ошибка (Error или unknown).
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const error: ErrorHandlerError = new Error('Timeout')
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
type ErrorHandlerError = unknown;
|
|
114
|
+
/**
|
|
115
|
+
* Словарь ошибок валидации (например поле → сообщение или список сообщений).
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const errors: ErrorHandlerErrors<'email'> = { email: 'Invalid email' }
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
type ErrorHandlerErrors<Key extends BaseKey = BaseKey, Value = Nullable<string | string[]>> = BaseRecord<Value, Key>;
|
|
123
|
+
/**
|
|
124
|
+
* Результат разбора ошибки через ErrorHandler.parse.
|
|
125
|
+
* Используется для единообразного представления ошибок API (message, status, errors, isExternal).
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const result: ErrorHandlerParseResult<'email'> = {
|
|
130
|
+
* message: 'Validation failed',
|
|
131
|
+
* status: 422,
|
|
132
|
+
* errors: { email: 'Invalid email' },
|
|
133
|
+
* isExternal: true
|
|
134
|
+
* }
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
type ErrorHandlerParseResult<Key extends BaseKey> = {
|
|
138
|
+
message: string;
|
|
139
|
+
status: number;
|
|
140
|
+
errors: ErrorHandlerErrors<Key>;
|
|
141
|
+
isExternal: boolean;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Конфиг одного «кейса» для ErrorHandler.parse: проверка типа ошибки и функция разбора.
|
|
145
|
+
* Регистрируется через ErrorHandler.case().
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const config: ErrorHandlerCaseConfig<Response> = {
|
|
150
|
+
* check: (error): error is Response => error instanceof Response,
|
|
151
|
+
* parse: (error, defaultResult) => ({ ...defaultResult, status: error.status })
|
|
152
|
+
* }
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
type ErrorHandlerCaseConfig<ErrorHandlerCaseError = any> = {
|
|
156
|
+
check: <Key extends BaseKey>(error: ErrorHandlerError, defaultResult: ErrorHandlerParseResult<Key>) => error is ErrorHandlerCaseError;
|
|
157
|
+
parse: <Key extends BaseKey>(error: ErrorHandlerCaseError, defaultResult: ErrorHandlerParseResult<Key>) => ErrorHandlerParseResult<Key>;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Конфигурация при логировании/пробросе ошибки (signal, опциональные message, payload, stack).
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* const config: ErrorHandlerConfig = {
|
|
165
|
+
* signal: 'api',
|
|
166
|
+
* message: 'Cannot load profile'
|
|
167
|
+
* }
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
type ErrorHandlerConfig = {
|
|
171
|
+
signal: string;
|
|
172
|
+
message?: ErrorHandlerMessage;
|
|
173
|
+
payload?: BaseRecord<unknown>;
|
|
174
|
+
stack?: string[];
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* Параметры события capture/forward: ошибка и конфиг.
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* const params: ErrorHandlerEventParams = {
|
|
182
|
+
* error: new Error('Timeout'),
|
|
183
|
+
* config: { signal: 'api' }
|
|
184
|
+
* }
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
type ErrorHandlerEventParams = {
|
|
188
|
+
error: ErrorHandlerError;
|
|
189
|
+
config: ErrorHandlerConfig;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Централизованная обработка ошибок: логирование, подписка на события, разбор ошибок по кейсам.
|
|
194
|
+
* Статический класс; подписка через on('capture', …), регистрация кейсов через case().
|
|
195
|
+
* capture — залогировать и вызвать событие, не бросать; forward — залогировать, вызвать событие и пробросить.
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```typescript
|
|
199
|
+
* ErrorHandler.on(ErrorHandlerEventName.Capture, ({ error }) => {
|
|
200
|
+
* console.error(error)
|
|
201
|
+
* })
|
|
202
|
+
*
|
|
203
|
+
* ErrorHandler.capture(new Error('Request failed'), { signal: 'api' })
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
declare class ErrorHandler {
|
|
207
|
+
private static eventEmitter;
|
|
208
|
+
private static caseList;
|
|
209
|
+
private static log;
|
|
210
|
+
/**
|
|
211
|
+
* Доступ к подписке на события обработчика ошибок.
|
|
212
|
+
* Обычно используется как `ErrorHandler.on(ErrorHandlerEventName.Capture, listener)`.
|
|
213
|
+
*
|
|
214
|
+
* @returns Метод подписки `EventEmitter.on`
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```typescript
|
|
218
|
+
* ErrorHandler.on(ErrorHandlerEventName.Capture, ({ config }) => {
|
|
219
|
+
* console.log(config.signal)
|
|
220
|
+
* })
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
static get on(): (name: ErrorHandlerEventName, listener: EventEmitterListener<ErrorHandlerEventParams>) => () => void;
|
|
224
|
+
/**
|
|
225
|
+
* Доступ к удалению конкретного подписчика обработчика ошибок.
|
|
226
|
+
*
|
|
227
|
+
* @returns Метод отписки `EventEmitter.off`
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```typescript
|
|
231
|
+
* ErrorHandler.off(ErrorHandlerEventName.Capture, listener)
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
static get off(): (name: ErrorHandlerEventName, listener: EventEmitterListener<ErrorHandlerEventParams>) => void;
|
|
235
|
+
/**
|
|
236
|
+
* Доступ к очистке подписок по имени события.
|
|
237
|
+
*
|
|
238
|
+
* @returns Метод очистки `EventEmitter.clear`
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* ErrorHandler.clear(ErrorHandlerEventName.Capture)
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
static get clear(): (name: ErrorHandlerEventName) => void;
|
|
246
|
+
/**
|
|
247
|
+
* Создаёт экземпляр Error с сообщением и опциональной причиной (cause).
|
|
248
|
+
*
|
|
249
|
+
* @param message - Текст ошибки
|
|
250
|
+
* @param error - Исходная ошибка или причина
|
|
251
|
+
* @returns Новый объект Error (не бросается)
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```typescript
|
|
255
|
+
* const error = ErrorHandler.create('Request failed', new Error('Timeout'))
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
static create(message: ErrorHandlerMessage, error?: ErrorHandlerError): Error;
|
|
259
|
+
/**
|
|
260
|
+
* Создаёт ошибку и немедленно бросает её (never).
|
|
261
|
+
* Используется для заглушек (например «Not implemented»).
|
|
262
|
+
*
|
|
263
|
+
* @param message - Текст ошибки
|
|
264
|
+
* @param error - Исходная ошибка или причина
|
|
265
|
+
* @returns Управление не возвращается, так как метод выбрасывает исключение
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* ```typescript
|
|
269
|
+
* ErrorHandler.throw('Not implemented')
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
static throw(message: ErrorHandlerMessage, error?: ErrorHandlerError): never;
|
|
273
|
+
/**
|
|
274
|
+
* Логирует ошибку и эмитит событие 'capture'. Ошибку не бросает.
|
|
275
|
+
* Подписчики могут отправить данные в мониторинг и т.д.
|
|
276
|
+
*
|
|
277
|
+
* @param error - Ошибка или любое перехваченное значение
|
|
278
|
+
* @param config - Конфигурация логирования и сопровождающих данных
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* ```typescript
|
|
282
|
+
* ErrorHandler.capture(new Error('Request failed'), {
|
|
283
|
+
* signal: 'api',
|
|
284
|
+
* message: 'Cannot load profile'
|
|
285
|
+
* })
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
static capture(error: ErrorHandlerError, config: ErrorHandlerConfig): void;
|
|
289
|
+
/**
|
|
290
|
+
* Логирует ошибку, эмитит 'capture' и пробрасывает ошибку дальше (never).
|
|
291
|
+
*
|
|
292
|
+
* @param error - Ошибка или любое перехваченное значение
|
|
293
|
+
* @param config - Конфигурация логирования и сопровождающих данных
|
|
294
|
+
* @returns Управление не возвращается, так как метод выбрасывает ошибку дальше
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* ```typescript
|
|
298
|
+
* ErrorHandler.forward(new Error('Forbidden'), {
|
|
299
|
+
* signal: 'auth'
|
|
300
|
+
* })
|
|
301
|
+
* ```
|
|
302
|
+
*/
|
|
303
|
+
static forward(error: ErrorHandlerError, config: ErrorHandlerConfig): never;
|
|
304
|
+
/**
|
|
305
|
+
* Регистрирует кейс для parse: при совпадении check() будет вызван parse().
|
|
306
|
+
* Порядок регистрации важен — используется первый подходящий кейс.
|
|
307
|
+
*
|
|
308
|
+
* @param config - Пара функций `check` и `parse` для пользовательского разбора ошибок
|
|
309
|
+
*
|
|
310
|
+
* @example
|
|
311
|
+
* ```typescript
|
|
312
|
+
* ErrorHandler.case({
|
|
313
|
+
* check: (error): error is Response => error instanceof Response,
|
|
314
|
+
* parse: (error, defaultResult) => ({
|
|
315
|
+
* ...defaultResult,
|
|
316
|
+
* status: error.status
|
|
317
|
+
* })
|
|
318
|
+
* })
|
|
319
|
+
* ```
|
|
320
|
+
*/
|
|
321
|
+
static case<ErrorHandlerCaseError>(config: ErrorHandlerCaseConfig<ErrorHandlerCaseError>): void;
|
|
322
|
+
/**
|
|
323
|
+
* Разбирает ошибку в единый формат (message, status, errors, isExternal).
|
|
324
|
+
* Сначала проверяются зарегистрированные кейсы; если ни один не подошёл — базовый разбор (Error.message или default).
|
|
325
|
+
*
|
|
326
|
+
* @param error - Ошибка или любое неизвестное значение
|
|
327
|
+
* @returns Унифицированный результат разбора ошибки
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```typescript
|
|
331
|
+
* const parsed = ErrorHandler.parse(new Error('Request failed'))
|
|
332
|
+
* console.log(parsed.message)
|
|
333
|
+
* ```
|
|
334
|
+
*/
|
|
335
|
+
static parse<Key extends BaseKey>(error: ErrorHandlerError): ErrorHandlerParseResult<Key>;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Лёгкий EventEmitter с поддержкой подписок, отписок и `defaultAction`.
|
|
340
|
+
* Слушатель получает объект события, объединённый с переданными параметрами emit.
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* ```typescript
|
|
344
|
+
* const emitter = new EventEmitter<'save', { id: number }>()
|
|
345
|
+
*
|
|
346
|
+
* emitter.on('save', (event) => {
|
|
347
|
+
* console.log(event.id)
|
|
348
|
+
* })
|
|
349
|
+
*
|
|
350
|
+
* emitter.emit('save', { id: 1 })
|
|
351
|
+
* ```
|
|
352
|
+
*/
|
|
353
|
+
declare class EventEmitter<EventName extends string = string, EventParams extends Nullable<object> = undefined> {
|
|
354
|
+
private subscriptions;
|
|
355
|
+
constructor();
|
|
356
|
+
/**
|
|
357
|
+
* Вызывает событие и передаёт параметры всем подписчикам.
|
|
358
|
+
* Если ни один слушатель не отменил стандартное действие, дополнительно вызывается `defaultAction`.
|
|
359
|
+
*
|
|
360
|
+
* @param name - Имя события
|
|
361
|
+
* @param params - Дополнительные параметры события
|
|
362
|
+
* @param defaultAction - Функция, которая выполнится после слушателей, если действие не отменено
|
|
363
|
+
*
|
|
364
|
+
* @example
|
|
365
|
+
* ```typescript
|
|
366
|
+
* emitter.emit('save', { id: 1 }, () => {
|
|
367
|
+
* console.log('saved')
|
|
368
|
+
* })
|
|
369
|
+
* ```
|
|
370
|
+
*/
|
|
371
|
+
emit(name: EventName, params?: EventParams, defaultAction?: EventEmitterDefaultAction): void;
|
|
372
|
+
/**
|
|
373
|
+
* Подписывает слушатель на событие.
|
|
374
|
+
*
|
|
375
|
+
* @param name - Имя события
|
|
376
|
+
* @param listener - Обработчик события
|
|
377
|
+
* @returns Функция для отписки от события
|
|
378
|
+
*
|
|
379
|
+
* @example
|
|
380
|
+
* ```typescript
|
|
381
|
+
* const unsubscribe = emitter.on('save', (event) => {
|
|
382
|
+
* console.log(event.id)
|
|
383
|
+
* })
|
|
384
|
+
*
|
|
385
|
+
* unsubscribe()
|
|
386
|
+
* ```
|
|
387
|
+
*/
|
|
388
|
+
on(name: EventName, listener: EventEmitterListener<EventParams>): () => void;
|
|
389
|
+
/**
|
|
390
|
+
* Удаляет конкретный слушатель из подписки на событие.
|
|
391
|
+
*
|
|
392
|
+
* @param name - Имя события
|
|
393
|
+
* @param listener - Слушатель, которого нужно удалить
|
|
394
|
+
*
|
|
395
|
+
* @example
|
|
396
|
+
* ```typescript
|
|
397
|
+
* emitter.off('save', listener)
|
|
398
|
+
* ```
|
|
399
|
+
*/
|
|
400
|
+
off(name: EventName, listener: EventEmitterListener<EventParams>): void;
|
|
401
|
+
/**
|
|
402
|
+
* Полностью очищает подписку на указанное событие.
|
|
403
|
+
*
|
|
404
|
+
* @param name - Имя события
|
|
405
|
+
*
|
|
406
|
+
* @example
|
|
407
|
+
* ```typescript
|
|
408
|
+
* emitter.clear('save')
|
|
409
|
+
* ```
|
|
410
|
+
*/
|
|
411
|
+
clear(name: EventName): void;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
type LogSignal = string;
|
|
415
|
+
type LogParamList = any[];
|
|
416
|
+
type LogStyles = string;
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Статический helper для форматированного вывода сообщений в консоль.
|
|
420
|
+
* Поддерживает обычные сообщения, стилизованные группы и набор `formatted`-методов с signal.
|
|
421
|
+
*
|
|
422
|
+
* @example
|
|
423
|
+
* ```typescript
|
|
424
|
+
* Log.info('App started')
|
|
425
|
+
* Log.formatted.success('auth', 'Signed in')
|
|
426
|
+
* ```
|
|
427
|
+
*/
|
|
428
|
+
declare class Log {
|
|
429
|
+
#private;
|
|
430
|
+
/**
|
|
431
|
+
* Набор методов для логирования с предварительным форматированием по signal.
|
|
432
|
+
*
|
|
433
|
+
* @example
|
|
434
|
+
* ```typescript
|
|
435
|
+
* Log.formatted.warning('api', 'Slow response')
|
|
436
|
+
* ```
|
|
437
|
+
*/
|
|
438
|
+
static readonly formatted: {
|
|
439
|
+
info: (paramList_0: string, ...paramList: any[]) => void;
|
|
440
|
+
success: (paramList_0: string, ...paramList: any[]) => void;
|
|
441
|
+
warning: (paramList_0: string, ...paramList: any[]) => void;
|
|
442
|
+
danger: (paramList_0: string, ...paramList: any[]) => void;
|
|
443
|
+
};
|
|
444
|
+
/**
|
|
445
|
+
* Открывает группу логов в консоли и выводит её заголовок.
|
|
446
|
+
*
|
|
447
|
+
* @param signal - Короткий идентификатор группы
|
|
448
|
+
* @param styles - Дополнительные CSS-стили для заголовка
|
|
449
|
+
* @param paramList - Дополнительные данные, которые будут выведены вместе с signal
|
|
450
|
+
*
|
|
451
|
+
* @example
|
|
452
|
+
* ```typescript
|
|
453
|
+
* Log.startGroup('profile', 'color: purple;', { id: 1 })
|
|
454
|
+
* ```
|
|
455
|
+
*/
|
|
456
|
+
static startGroup(signal: LogSignal, styles?: LogStyles, ...paramList: LogParamList): void;
|
|
457
|
+
/**
|
|
458
|
+
* Закрывает текущую группу логов в консоли.
|
|
459
|
+
*
|
|
460
|
+
* @example
|
|
461
|
+
* ```typescript
|
|
462
|
+
* Log.endGroup()
|
|
463
|
+
* ```
|
|
464
|
+
*/
|
|
465
|
+
static endGroup(): void;
|
|
466
|
+
/**
|
|
467
|
+
* Выводит информационное сообщение.
|
|
468
|
+
*
|
|
469
|
+
* @param paramList - Параметры для вывода в консоль
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
* ```typescript
|
|
473
|
+
* Log.info('Profile loaded', user)
|
|
474
|
+
* ```
|
|
475
|
+
*/
|
|
476
|
+
static info(...paramList: LogParamList): void;
|
|
477
|
+
/**
|
|
478
|
+
* Выводит сообщение об успешном результате.
|
|
479
|
+
*
|
|
480
|
+
* @param paramList - Параметры для вывода в консоль
|
|
481
|
+
*
|
|
482
|
+
* @example
|
|
483
|
+
* ```typescript
|
|
484
|
+
* Log.success('Profile saved')
|
|
485
|
+
* ```
|
|
486
|
+
*/
|
|
487
|
+
static success(...paramList: LogParamList): void;
|
|
488
|
+
/**
|
|
489
|
+
* Выводит предупреждение.
|
|
490
|
+
*
|
|
491
|
+
* @param paramList - Параметры для вывода в консоль
|
|
492
|
+
*
|
|
493
|
+
* @example
|
|
494
|
+
* ```typescript
|
|
495
|
+
* Log.warning('Retry in progress')
|
|
496
|
+
* ```
|
|
497
|
+
*/
|
|
498
|
+
static warning(...paramList: LogParamList): void;
|
|
499
|
+
/**
|
|
500
|
+
* Выводит сообщение об ошибке.
|
|
501
|
+
*
|
|
502
|
+
* @param paramList - Параметры для вывода в консоль
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* ```typescript
|
|
506
|
+
* Log.danger('Request failed', error)
|
|
507
|
+
* ```
|
|
508
|
+
*/
|
|
509
|
+
static danger(...paramList: LogParamList): void;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
export { ErrorHandler, ErrorHandlerEventName, EventEmitter, Log };
|
|
513
|
+
export type { ErrorHandlerCaseConfig, ErrorHandlerConfig, ErrorHandlerError, ErrorHandlerErrors, ErrorHandlerEventParams, ErrorHandlerMessage, ErrorHandlerParseResult };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t=t=>t instanceof Error,e=(t,...e)=>{if(t instanceof Function)return t(...e)};class s{isDefaultPrevented=!1;constructor(){this.preventDefault=this.preventDefault.bind(this),this.overrideDefault=this.overrideDefault.bind(this)}preventDefault(){this.isDefaultPrevented=!0}overrideDefault(){this.isDefaultPrevented=!1}}class r{subscriptions={};constructor(){this.emit=this.emit.bind(this),this.on=this.on.bind(this),this.off=this.off.bind(this),this.clear=this.clear.bind(this)}emit(t,s,r){const i=this.subscriptions[t];if(i){const{event:t,listenerList:n}=i;n.forEach(r=>e(r,Object.assign(t,s))),t.isDefaultPrevented||e(r)}else e(r)}on(t,e){const r=this.subscriptions[t];return r?r.listenerList.push(e):this.subscriptions[t]={event:new s,listenerList:[e]},()=>this.off(t,e)}off(t,e){const s=this.subscriptions[t];if(s){const{event:r,listenerList:i}=s;this.subscriptions[t]={event:r,listenerList:i.filter(t=>t!==e)},r.overrideDefault()}}clear(t){delete this.subscriptions[t]}}const i=(t="?",...e)=>{const s=(t&&(r=t,"string"==typeof r)?t:"?").toUpperCase();var r;const i=e.reduce((t,e,s,{length:r})=>{const i=s===r-1?[]:["|"];return t.push(e,...i),t},e.length?["-"]:[]);return[`[${s}]`,...i]};var n,a,o;!function(t){t.StartGroup="group",t.EndGroup="groupEnd",t.Default="log"}(n||(n={})),function(t){t.Info="[36m%s[0m",t.Success="[32m%s[0m",t.Warning="[33m%s[0m",t.Danger="[31m%s[0m"}(a||(a={}));class c{static formatted={info:(...t)=>c.info(...i(...t)),success:(...t)=>c.success(...i(...t)),warning:(...t)=>c.warning(...i(...t)),danger:(...t)=>c.danger(...i(...t))};static#t(t,...e){console[t](...e)}static startGroup(t,e,...s){c.#t(n.StartGroup,...((t,...e)=>["%c%s",t,...e])(`font-size: 16px;${e}`,...i(t,...s)))}static endGroup(){c.#t(n.EndGroup)}static info(...t){c.#t(n.Default,a.Info,...t)}static success(...t){c.#t(n.Default,a.Success,...t)}static warning(...t){c.#t(n.Default,a.Warning,...t)}static danger(...t){c.#t(n.Default,a.Danger,...t)}}!function(t){t.Capture="capture",t.Forward="forward"}(o||(o={}));class u{static eventEmitter=new r;static caseList=[];static log(e,s){const{signal:r,message:i,payload:n,stack:a}=s,o=[i,t(e)?e.message:void 0].filter(Boolean);c.formatted.danger(r,...o,{error:e,payload:n,stack:a})}static get on(){return u.eventEmitter.on}static get off(){return u.eventEmitter.off}static get clear(){return u.eventEmitter.clear}static create(t,e){return new Error(t,{cause:e})}static throw(t,e){throw u.create(t,e)}static capture(t,e){u.log(t,e),u.eventEmitter.emit(o.Capture,{error:t,config:e})}static forward(t,e){throw u.log(t,e),u.eventEmitter.emit(o.Capture,{error:t,config:e}),t}static case(t){u.caseList.push(t)}static parse(e){const s={message:"Error!",status:0,errors:{},isExternal:!0};for(const{check:t,parse:r}of u.caseList)if(t(e,s))return r(e,s);return!0===t(e)?{message:e.message,status:s.status,errors:s.errors,isExternal:s.isExternal}:{message:s.message,status:s.status,errors:s.errors,isExternal:s.isExternal}}}export{u as ErrorHandler,o as ErrorHandlerEventName,r as EventEmitter,c as Log};
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const t=t=>void 0===t,e=t=>null===t,s=s=>t(s)||e(s),r=t=>"string"==typeof t,i=t=>"object"==typeof t,o=t=>{const e=[n,a,c,u,l,f,p,h,g,m,d].some(e=>e(t));return!!t&&"object"==typeof t&&!e},n=t=>Array.isArray(t),a=t=>t instanceof ArrayBuffer,c=t=>t instanceof Map,u=t=>t instanceof Set,l=t=>t instanceof Map,f=t=>t instanceof Set,p=t=>t instanceof Date,h=t=>t instanceof Error,g=t=>t instanceof RegExp,m=t=>t instanceof Promise,d=t=>t instanceof Function;const x=(t,...e)=>{if(d(t))return t(...e)};function y(t,e){return!(!i(e)||!(t in e))}function b(t,e){return t.filter(t=>e.includes(t))}class E{isDefaultPrevented=!1;constructor(){this.preventDefault=this.preventDefault.bind(this),this.overrideDefault=this.overrideDefault.bind(this)}preventDefault(){this.isDefaultPrevented=!0}overrideDefault(){this.isDefaultPrevented=!1}}class v{subscriptions={};constructor(){this.emit=this.emit.bind(this),this.on=this.on.bind(this),this.off=this.off.bind(this),this.clear=this.clear.bind(this)}emit(t,e,s){const r=this.subscriptions[t];if(r){const{event:t,listenerList:i}=r;i.forEach(s=>x(s,Object.assign(t,e))),t.isDefaultPrevented||x(s)}else x(s)}on(t,e){const s=this.subscriptions[t];return s?s.listenerList.push(e):this.subscriptions[t]={event:new E,listenerList:[e]},()=>this.off(t,e)}off(t,e){const s=this.subscriptions[t];if(s){const{event:r,listenerList:i}=s;this.subscriptions[t]={event:r,listenerList:i.filter(t=>t!==e)},r.overrideDefault()}}clear(t){delete this.subscriptions[t]}}const w=(t="?",...e)=>[`[${(t&&r(t)?t:"?").toUpperCase()}]`,...e.reduce((t,e,s,{length:r})=>{const i=s===r-1?[]:["|"];return t.push(e,...i),t},e.length?["-"]:[])];var D,N,k;!function(t){t.StartGroup="group",t.EndGroup="groupEnd",t.Default="log"}(D||(D={})),function(t){t.Info="[36m%s[0m",t.Success="[32m%s[0m",t.Warning="[33m%s[0m",t.Danger="[31m%s[0m"}(N||(N={}));class S{static formatted={info:(...t)=>S.info(...w(...t)),success:(...t)=>S.success(...w(...t)),warning:(...t)=>S.warning(...w(...t)),danger:(...t)=>S.danger(...w(...t))};static#t(t,...e){console[t](...e)}static startGroup(t,e,...s){S.#t(D.StartGroup,...((t,...e)=>["%c%s",t,...e])(`font-size: 16px;${e}`,...w(t,...s)))}static endGroup(){S.#t(D.EndGroup)}static info(...t){S.#t(D.Default,N.Info,...t)}static success(...t){S.#t(D.Default,N.Success,...t)}static warning(...t){S.#t(D.Default,N.Warning,...t)}static danger(...t){S.#t(D.Default,N.Danger,...t)}}exports.ErrorHandlerEventName=void 0,(k=exports.ErrorHandlerEventName||(exports.ErrorHandlerEventName={})).Capture="capture",k.Forward="forward";class L{static eventEmitter=new v;static caseList=[];static log(t,e){const{signal:s,message:r,payload:i,stack:o}=e,n=[r,h(t)?t.message:void 0].filter(Boolean);S.formatted.danger(s,...n,{error:t,payload:i,stack:o})}static get on(){return L.eventEmitter.on}static get off(){return L.eventEmitter.off}static get clear(){return L.eventEmitter.clear}static create(t,e){return new Error(t,{cause:e})}static throw(t,e){throw L.create(t,e)}static capture(t,e){L.log(t,e),L.eventEmitter.emit(exports.ErrorHandlerEventName.Capture,{error:t,config:e})}static forward(t,e){throw L.log(t,e),L.eventEmitter.emit(exports.ErrorHandlerEventName.Capture,{error:t,config:e}),t}static case(t){L.caseList.push(t)}static parse(t){const e={message:"Error!",status:0,errors:{},isExternal:!0};for(const{check:s,parse:r}of L.caseList)if(s(t,e))return r(t,e);return!0===h(t)?{message:t.message,status:e.status,errors:e.errors,isExternal:e.isExternal}:{message:e.message,status:e.status,errors:e.errors,isExternal:e.isExternal}}}class j{key;model;config;constructor(t,e,s){this.key=t,this.model=e,this.config=s}async get(t){const{defaultValue:e,withDebug:s}={...this.config,...t},r=await this.model.get(this.key),i=r&&JSON.parse(r)||e;return s&&S.formatted.info("get",this.key,i),i}async set(t,e){const{withDebug:s}={...this.config,...e};await this.model.set(this.key,JSON.stringify(t)),s&&S.formatted.info("set",this.key,t)}async delete(t){const{withDebug:e}={...this.config,...t},s=await this.get({...t,withDebug:!1});await this.model.delete(this.key),e&&S.formatted.info("delete",this.key,s)}async has(t){const{withDebug:e}={...this.config,...t},s=await this.get({...t,withDebug:!1});return e&&S.formatted.info("has",this.key,s),!!s}}exports.ErrorHandler=L,exports.EventEmitter=v,exports.Log=S,exports.Storage=class{model;config;constructor(t,e){this.model=t,this.config=e}async all(){L.throw("Not implemented")}async clear(){L.throw("Not implemented")}create(t){const e={[t]:new j(t,this.model,this.config)};return Object.assign(this,e)}},exports.chunkList=function(t,e){const s=[];for(let r=0;r<t.length;r+=e)s.push(t.slice(r,r+e));return s},exports.compose=function(t,e,r){const i=!o(t);return!s(r)&&{...e,...i?{[r]:t}:t}||!s(e)&&{...e,...t}||{...t}},exports.debounce=(t,e)=>{let s;return(...r)=>{s&&clearTimeout(s),s=setTimeout(()=>x(t,...r),e)}},exports.filterByKey=function(t,e="isVisible"){return t.filter(t=>!y(e,t)||t[e])},exports.filterDuplicateByKey=function(t,e){return t.reduce((t,s)=>t.some(t=>t[e]===s[e])?t:[...t,s],[])},exports.filterEqualValues=b,exports.filterNullableValues=function(t){return t.filter(t=>!s(t))},exports.forceList=function(t){return n(t)?t:[t]},exports.getValueByKey=function(t,e,r){return s(t)?r:2===arguments.length?e[t]:e[t]??r},exports.hasEqualValues=function(t,e){return!!b(t,e).length},exports.hasKey=y,exports.isAnyObject=i,exports.isArray=n,exports.isArrayBuffer=a,exports.isArrayEmpty=function(t){return 0===t.length},exports.isBigint=t=>"bigint"==typeof t,exports.isBoolean=t=>"boolean"==typeof t,exports.isDate=p,exports.isError=h,exports.isFunction=d,exports.isMap=c,exports.isNaN=t=>Number.isNaN(t),exports.isNull=e,exports.isNullable=s,exports.isNumber=t=>"number"==typeof t,exports.isObject=o,exports.isObjectEmpty=function(t){for(const e in t)return!1;return!0},exports.isPromise=m,exports.isProxy=t=>t instanceof Proxy,exports.isRegExp=g,exports.isSet=u,exports.isString=r,exports.isSymbol=t=>"symbol"==typeof t,exports.isUndefined=t,exports.isWeakMap=l,exports.isWeakSet=f,exports.mapRecord=(t,e)=>{const s=Object.entries(t);return Object.fromEntries(s.map(([t,s],r,i)=>[t,e(t,s,r,i)]))},exports.runCallback=x,exports.throttle=(t,e)=>{let s=!0;return(...r)=>{s&&(x(t,...r),s=!1),setTimeout(()=>s=!0,e)}},exports.wait=t=>new Promise(e=>setTimeout(e,t));
|