jtcsv 2.2.7 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -1
- package/bin/jtcsv.js +891 -821
- package/bin/jtcsv.ts +2534 -0
- package/csv-to-json.js +168 -145
- package/dist/jtcsv-core.cjs.js +1407 -0
- package/dist/jtcsv-core.cjs.js.map +1 -0
- package/dist/jtcsv-core.esm.js +1379 -0
- package/dist/jtcsv-core.esm.js.map +1 -0
- package/dist/jtcsv-core.umd.js +1413 -0
- package/dist/jtcsv-core.umd.js.map +1 -0
- package/dist/jtcsv-full.cjs.js +1912 -0
- package/dist/jtcsv-full.cjs.js.map +1 -0
- package/dist/jtcsv-full.esm.js +1880 -0
- package/dist/jtcsv-full.esm.js.map +1 -0
- package/dist/jtcsv-full.umd.js +1918 -0
- package/dist/jtcsv-full.umd.js.map +1 -0
- package/dist/jtcsv-workers.esm.js +759 -0
- package/dist/jtcsv-workers.esm.js.map +1 -0
- package/dist/jtcsv-workers.umd.js +773 -0
- package/dist/jtcsv-workers.umd.js.map +1 -0
- package/dist/jtcsv.cjs.js +61 -19
- package/dist/jtcsv.cjs.js.map +1 -1
- package/dist/jtcsv.esm.js +61 -19
- package/dist/jtcsv.esm.js.map +1 -1
- package/dist/jtcsv.umd.js +61 -19
- package/dist/jtcsv.umd.js.map +1 -1
- package/errors.js +188 -2
- package/examples/advanced/conditional-transformations.js +446 -0
- package/examples/advanced/conditional-transformations.ts +446 -0
- package/examples/advanced/csv-parser.worker.js +89 -0
- package/examples/advanced/csv-parser.worker.ts +89 -0
- package/examples/advanced/nested-objects-example.js +306 -0
- package/examples/advanced/nested-objects-example.ts +306 -0
- package/examples/advanced/performance-optimization.js +504 -0
- package/examples/advanced/performance-optimization.ts +504 -0
- package/examples/advanced/run-demo-server.js +116 -0
- package/examples/advanced/run-demo-server.ts +116 -0
- package/examples/advanced/web-worker-usage.html +874 -0
- package/examples/async-multithreaded-example.ts +335 -0
- package/examples/cli-advanced-usage.md +288 -0
- package/examples/cli-batch-processing.ts +38 -0
- package/examples/cli-tool.js +0 -3
- package/examples/cli-tool.ts +183 -0
- package/examples/error-handling.js +21 -7
- package/examples/error-handling.ts +356 -0
- package/examples/express-api.js +0 -3
- package/examples/express-api.ts +164 -0
- package/examples/large-dataset-example.js +0 -3
- package/examples/large-dataset-example.ts +204 -0
- package/examples/ndjson-processing.js +1 -1
- package/examples/ndjson-processing.ts +456 -0
- package/examples/plugin-excel-exporter.js +3 -4
- package/examples/plugin-excel-exporter.ts +406 -0
- package/examples/react-integration.tsx +637 -0
- package/examples/schema-validation.ts +640 -0
- package/examples/simple-usage.js +254 -254
- package/examples/simple-usage.ts +194 -0
- package/examples/streaming-example.js +4 -5
- package/examples/streaming-example.ts +419 -0
- package/examples/web-workers-advanced.ts +28 -0
- package/index.d.ts +1 -3
- package/index.js +15 -1
- package/json-save.js +9 -3
- package/json-to-csv.js +168 -21
- package/package.json +69 -10
- package/plugins/express-middleware/README.md +21 -2
- package/plugins/express-middleware/example.js +3 -4
- package/plugins/express-middleware/example.ts +135 -0
- package/plugins/express-middleware/index.d.ts +1 -1
- package/plugins/express-middleware/index.js +270 -118
- package/plugins/express-middleware/index.ts +557 -0
- package/plugins/fastify-plugin/index.js +2 -4
- package/plugins/fastify-plugin/index.ts +443 -0
- package/plugins/hono/index.ts +226 -0
- package/plugins/nestjs/index.ts +201 -0
- package/plugins/nextjs-api/examples/ConverterComponent.tsx +386 -0
- package/plugins/nextjs-api/examples/api-convert.js +0 -2
- package/plugins/nextjs-api/examples/api-convert.ts +67 -0
- package/plugins/nextjs-api/index.tsx +339 -0
- package/plugins/nextjs-api/route.js +2 -3
- package/plugins/nextjs-api/route.ts +370 -0
- package/plugins/nuxt/index.ts +94 -0
- package/plugins/nuxt/runtime/composables/useJtcsv.ts +100 -0
- package/plugins/nuxt/runtime/plugin.ts +71 -0
- package/plugins/remix/index.js +1 -1
- package/plugins/remix/index.ts +260 -0
- package/plugins/sveltekit/index.js +1 -1
- package/plugins/sveltekit/index.ts +301 -0
- package/plugins/trpc/index.ts +267 -0
- package/src/browser/browser-functions.ts +402 -0
- package/src/browser/core.js +92 -0
- package/src/browser/core.ts +152 -0
- package/src/browser/csv-to-json-browser.d.ts +3 -0
- package/src/browser/csv-to-json-browser.js +36 -14
- package/src/browser/csv-to-json-browser.ts +264 -0
- package/src/browser/errors-browser.ts +303 -0
- package/src/browser/extensions/plugins.js +92 -0
- package/src/browser/extensions/plugins.ts +93 -0
- package/src/browser/extensions/workers.js +39 -0
- package/src/browser/extensions/workers.ts +39 -0
- package/src/browser/globals.d.ts +5 -0
- package/src/browser/index.ts +192 -0
- package/src/browser/json-to-csv-browser.d.ts +3 -0
- package/src/browser/json-to-csv-browser.js +13 -3
- package/src/browser/json-to-csv-browser.ts +262 -0
- package/src/browser/streams.js +12 -2
- package/src/browser/streams.ts +336 -0
- package/src/browser/workers/csv-parser.worker.ts +377 -0
- package/src/browser/workers/worker-pool.ts +548 -0
- package/src/core/delimiter-cache.js +22 -8
- package/src/core/delimiter-cache.ts +310 -0
- package/src/core/node-optimizations.ts +449 -0
- package/src/core/plugin-system.js +29 -11
- package/src/core/plugin-system.ts +400 -0
- package/src/core/transform-hooks.ts +558 -0
- package/src/engines/fast-path-engine-new.ts +347 -0
- package/src/engines/fast-path-engine.ts +854 -0
- package/src/errors.ts +72 -0
- package/src/formats/ndjson-parser.ts +469 -0
- package/src/formats/tsv-parser.ts +334 -0
- package/src/index-with-plugins.js +16 -9
- package/src/index-with-plugins.ts +395 -0
- package/src/types/index.ts +255 -0
- package/src/utils/bom-utils.js +259 -0
- package/src/utils/bom-utils.ts +373 -0
- package/src/utils/encoding-support.js +124 -0
- package/src/utils/encoding-support.ts +155 -0
- package/src/utils/schema-validator.js +19 -19
- package/src/utils/schema-validator.ts +819 -0
- package/src/utils/transform-loader.js +1 -1
- package/src/utils/transform-loader.ts +389 -0
- package/src/utils/zod-adapter.js +170 -0
- package/src/utils/zod-adapter.ts +280 -0
- package/src/web-server/index.js +10 -10
- package/src/web-server/index.ts +683 -0
- package/src/workers/csv-multithreaded.ts +310 -0
- package/src/workers/csv-parser.worker.ts +227 -0
- package/src/workers/worker-pool.ts +409 -0
- package/stream-csv-to-json.js +26 -8
- package/stream-json-to-csv.js +1 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin System для JTCSV
|
|
3
|
+
* Middleware-like архитектура с поддержкой hooks и плагинов
|
|
4
|
+
*
|
|
5
|
+
* @version 1.0.0
|
|
6
|
+
* @date 2026-01-22
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
interface PluginStats {
|
|
10
|
+
pluginLoads: number;
|
|
11
|
+
hookExecutions: number;
|
|
12
|
+
middlewareExecutions: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface Plugin {
|
|
16
|
+
name: string;
|
|
17
|
+
version?: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
hooks?: Record<string, Function>;
|
|
20
|
+
middlewares?: Function[];
|
|
21
|
+
init?: (manager: PluginManager) => void;
|
|
22
|
+
destroy?: () => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type HookName =
|
|
26
|
+
| 'before:csvToJson'
|
|
27
|
+
| 'after:csvToJson'
|
|
28
|
+
| 'before:jsonToCsv'
|
|
29
|
+
| 'after:jsonToCsv'
|
|
30
|
+
| 'before:parse'
|
|
31
|
+
| 'after:parse'
|
|
32
|
+
| 'before:serialize'
|
|
33
|
+
| 'after:serialize'
|
|
34
|
+
| 'error'
|
|
35
|
+
| 'validation'
|
|
36
|
+
| 'transformation'
|
|
37
|
+
| string;
|
|
38
|
+
|
|
39
|
+
export class PluginManager {
|
|
40
|
+
private plugins: Map<string, Plugin>;
|
|
41
|
+
private hooks: Map<HookName, Function[]>;
|
|
42
|
+
private middlewares: Function[];
|
|
43
|
+
private context: Record<string, any>;
|
|
44
|
+
private stats: PluginStats;
|
|
45
|
+
|
|
46
|
+
constructor() {
|
|
47
|
+
this.plugins = new Map();
|
|
48
|
+
this.hooks = new Map();
|
|
49
|
+
this.middlewares = [];
|
|
50
|
+
this.context = {};
|
|
51
|
+
this.stats = {
|
|
52
|
+
pluginLoads: 0,
|
|
53
|
+
hookExecutions: 0,
|
|
54
|
+
middlewareExecutions: 0
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Регистрируем стандартные hooks
|
|
58
|
+
this._registerDefaultHooks();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Backwards-compatible alias for registerPlugin.
|
|
63
|
+
*/
|
|
64
|
+
use(name: string, plugin: Plugin): void {
|
|
65
|
+
this.registerPlugin(name, plugin);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Регистрирует стандартные hooks
|
|
70
|
+
*/
|
|
71
|
+
private _registerDefaultHooks(): void {
|
|
72
|
+
const defaultHooks: HookName[] = [
|
|
73
|
+
'before:csvToJson',
|
|
74
|
+
'after:csvToJson',
|
|
75
|
+
'before:jsonToCsv',
|
|
76
|
+
'after:jsonToCsv',
|
|
77
|
+
'before:parse',
|
|
78
|
+
'after:parse',
|
|
79
|
+
'before:serialize',
|
|
80
|
+
'after:serialize',
|
|
81
|
+
'error',
|
|
82
|
+
'validation',
|
|
83
|
+
'transformation'
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
defaultHooks.forEach(hook => {
|
|
87
|
+
this.hooks.set(hook, []);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Регистрирует плагин
|
|
93
|
+
* @param name - Уникальное имя плагина
|
|
94
|
+
* @param plugin - Объект плагина
|
|
95
|
+
*/
|
|
96
|
+
registerPlugin(name: string, plugin: Plugin): void {
|
|
97
|
+
if (this.plugins.has(name)) {
|
|
98
|
+
throw new Error(`Plugin "${name}" already registered`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Добавляем плагин
|
|
102
|
+
this.plugins.set(name, plugin);
|
|
103
|
+
this.stats.pluginLoads++;
|
|
104
|
+
|
|
105
|
+
// Регистрируем hooks плагина
|
|
106
|
+
if (plugin.hooks) {
|
|
107
|
+
Object.entries(plugin.hooks).forEach(([hookName, handler]) => {
|
|
108
|
+
this.registerHook(hookName as HookName, handler);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Регистрируем middleware плагина
|
|
113
|
+
if (plugin.middlewares) {
|
|
114
|
+
plugin.middlewares.forEach(middleware => {
|
|
115
|
+
this.registerMiddleware(middleware);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Вызываем init если есть
|
|
120
|
+
if (plugin.init) {
|
|
121
|
+
plugin.init(this);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
console.log(`✅ Plugin "${name}" registered successfully`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Регистрирует hook
|
|
129
|
+
* @param hookName - Имя hook
|
|
130
|
+
* @param handler - Функция обработчик
|
|
131
|
+
*/
|
|
132
|
+
registerHook(hookName: HookName, handler: Function): void {
|
|
133
|
+
if (!this.hooks.has(hookName)) {
|
|
134
|
+
this.hooks.set(hookName, []);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const handlers = this.hooks.get(hookName)!;
|
|
138
|
+
handlers.push(handler);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Регистрирует middleware
|
|
143
|
+
* @param middleware - Функция middleware
|
|
144
|
+
*/
|
|
145
|
+
registerMiddleware(middleware: Function): void {
|
|
146
|
+
this.middlewares.push(middleware);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Выполняет hook
|
|
151
|
+
* @param hookName - Имя hook
|
|
152
|
+
* @param data - Данные для обработки
|
|
153
|
+
* @param context - Контекст выполнения
|
|
154
|
+
*/
|
|
155
|
+
async executeHook(hookName: HookName, data: any, context: any = {}): Promise<any> {
|
|
156
|
+
const handlers = this.hooks.get(hookName);
|
|
157
|
+
|
|
158
|
+
if (!handlers || handlers.length === 0) {
|
|
159
|
+
return data;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
this.stats.hookExecutions++;
|
|
163
|
+
let result = data;
|
|
164
|
+
|
|
165
|
+
// Выполняем все handlers последовательно
|
|
166
|
+
for (const handler of handlers) {
|
|
167
|
+
try {
|
|
168
|
+
result = await handler(result, { ...this.context, ...context, hookName });
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.error(`Error in hook "${hookName}":`, error);
|
|
171
|
+
|
|
172
|
+
// Выполняем error hook если есть
|
|
173
|
+
const errorHandlers = this.hooks.get('error');
|
|
174
|
+
if (errorHandlers && errorHandlers.length > 0) {
|
|
175
|
+
for (const errorHandler of errorHandlers) {
|
|
176
|
+
try {
|
|
177
|
+
errorHandler(error, { ...this.context, ...context, hookName, data: result });
|
|
178
|
+
} catch {
|
|
179
|
+
// Игнорируем ошибки в error handlers
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return result;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Backwards-compatible alias for executeHook.
|
|
191
|
+
*/
|
|
192
|
+
async executeHooks(hookName: HookName, data: any, context: any = {}): Promise<any> {
|
|
193
|
+
return this.executeHook(hookName, data, context);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Executes an operation with before/after hooks and middleware.
|
|
198
|
+
*/
|
|
199
|
+
async executeWithPlugins(
|
|
200
|
+
operation: string,
|
|
201
|
+
input: any,
|
|
202
|
+
options: any,
|
|
203
|
+
handler: (input: any, options: any) => any | Promise<any>
|
|
204
|
+
): Promise<any> {
|
|
205
|
+
const context = { operation, options, metadata: {} as Record<string, any> };
|
|
206
|
+
const beforeHook = `before:${operation}` as HookName;
|
|
207
|
+
const afterHook = `after:${operation}` as HookName;
|
|
208
|
+
|
|
209
|
+
const beforeInput = await this.executeHook(beforeHook, input, context);
|
|
210
|
+
const middlewareInput = { input: beforeInput, options, operation, metadata: context.metadata };
|
|
211
|
+
const middlewareResult = await this.executeMiddleware(middlewareInput, context);
|
|
212
|
+
const result = await handler(middlewareResult.input ?? beforeInput, options);
|
|
213
|
+
return this.executeHook(afterHook, result, context);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Returns registered plugin names.
|
|
218
|
+
*/
|
|
219
|
+
listPlugins(): string[] {
|
|
220
|
+
return Array.from(this.plugins.keys());
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Выполняет цепочку middleware
|
|
225
|
+
* @param input - Входные данные
|
|
226
|
+
* @param context - Контекст выполнения
|
|
227
|
+
*/
|
|
228
|
+
async executeMiddleware(input: any, context: any = {}): Promise<any> {
|
|
229
|
+
if (this.middlewares.length === 0) {
|
|
230
|
+
return input;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
this.stats.middlewareExecutions++;
|
|
234
|
+
let result = input;
|
|
235
|
+
|
|
236
|
+
// Выполняем middleware последовательно
|
|
237
|
+
for (const middleware of this.middlewares) {
|
|
238
|
+
try {
|
|
239
|
+
result = await middleware(result, { ...this.context, ...context });
|
|
240
|
+
} catch (error) {
|
|
241
|
+
console.error('Error in middleware:', error);
|
|
242
|
+
|
|
243
|
+
// Выполняем error hook если есть
|
|
244
|
+
const errorHandlers = this.hooks.get('error');
|
|
245
|
+
if (errorHandlers && errorHandlers.length > 0) {
|
|
246
|
+
for (const errorHandler of errorHandlers) {
|
|
247
|
+
try {
|
|
248
|
+
errorHandler(error, { ...this.context, ...context, data: result });
|
|
249
|
+
} catch {
|
|
250
|
+
// Игнорируем ошибки в error handlers
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
throw error;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Устанавливает контекст
|
|
264
|
+
* @param key - Ключ контекста
|
|
265
|
+
* @param value - Значение
|
|
266
|
+
*/
|
|
267
|
+
setContext(key: string, value: any): void {
|
|
268
|
+
this.context[key] = value;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Получает контекст
|
|
273
|
+
* @param key - Ключ контекста (опционально)
|
|
274
|
+
*/
|
|
275
|
+
getContext(key?: string): any {
|
|
276
|
+
if (key) {
|
|
277
|
+
return this.context[key];
|
|
278
|
+
}
|
|
279
|
+
return { ...this.context };
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Возвращает статистику
|
|
284
|
+
*/
|
|
285
|
+
getStats(): PluginStats {
|
|
286
|
+
return { ...this.stats };
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Возвращает список зарегистрированных плагинов
|
|
291
|
+
*/
|
|
292
|
+
getPlugins(): string[] {
|
|
293
|
+
return Array.from(this.plugins.keys());
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Возвращает список зарегистрированных hooks
|
|
298
|
+
*/
|
|
299
|
+
getHooks(): HookName[] {
|
|
300
|
+
return Array.from(this.hooks.keys());
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Удаляет плагин
|
|
305
|
+
* @param name - Имя плагина
|
|
306
|
+
*/
|
|
307
|
+
unregisterPlugin(name: string): boolean {
|
|
308
|
+
const plugin = this.plugins.get(name);
|
|
309
|
+
|
|
310
|
+
if (!plugin) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Вызываем destroy если есть
|
|
315
|
+
if (plugin.destroy) {
|
|
316
|
+
try {
|
|
317
|
+
plugin.destroy();
|
|
318
|
+
} catch (error) {
|
|
319
|
+
console.error(`Error destroying plugin "${name}":`, error);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Удаляем плагин
|
|
324
|
+
this.plugins.delete(name);
|
|
325
|
+
|
|
326
|
+
// TODO: Удалить связанные hooks и middleware
|
|
327
|
+
|
|
328
|
+
console.log(`🗑️ Plugin "${name}" unregistered`);
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Очищает все плагины и hooks
|
|
334
|
+
*/
|
|
335
|
+
clear(): void {
|
|
336
|
+
// Вызываем destroy для всех плагинов
|
|
337
|
+
this.plugins.forEach((plugin, name) => {
|
|
338
|
+
if (plugin.destroy) {
|
|
339
|
+
try {
|
|
340
|
+
plugin.destroy();
|
|
341
|
+
} catch (error) {
|
|
342
|
+
console.error(`Error destroying plugin "${name}":`, error);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
this.plugins.clear();
|
|
348
|
+
this.hooks.clear();
|
|
349
|
+
this.middlewares = [];
|
|
350
|
+
this.context = {};
|
|
351
|
+
|
|
352
|
+
// Регистрируем стандартные hooks заново
|
|
353
|
+
this._registerDefaultHooks();
|
|
354
|
+
|
|
355
|
+
console.log('🧹 Plugin system cleared');
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Асинхронная версия executeHook
|
|
360
|
+
*/
|
|
361
|
+
async executeHookAsync(hookName: HookName, data: any, context: any = {}): Promise<any> {
|
|
362
|
+
return this.executeHook(hookName, data, context);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Асинхронная версия executeMiddleware
|
|
367
|
+
*/
|
|
368
|
+
async executeMiddlewareAsync(input: any, context: any = {}): Promise<any> {
|
|
369
|
+
return this.executeMiddleware(input, context);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Создание глобального экземпляра PluginManager
|
|
374
|
+
let globalPluginManager: PluginManager | null = null;
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Возвращает глобальный экземпляр PluginManager
|
|
378
|
+
*/
|
|
379
|
+
export function getGlobalPluginManager(): PluginManager {
|
|
380
|
+
if (!globalPluginManager) {
|
|
381
|
+
globalPluginManager = new PluginManager();
|
|
382
|
+
}
|
|
383
|
+
return globalPluginManager;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Асинхронная версия getGlobalPluginManager
|
|
388
|
+
*/
|
|
389
|
+
export async function getGlobalPluginManagerAsync(): Promise<PluginManager> {
|
|
390
|
+
return getGlobalPluginManager();
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Экспорт для CommonJS
|
|
394
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
395
|
+
module.exports = {
|
|
396
|
+
PluginManager,
|
|
397
|
+
getGlobalPluginManager,
|
|
398
|
+
getGlobalPluginManagerAsync
|
|
399
|
+
};
|
|
400
|
+
}
|