the-best-sort 1.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/LICENCE ADDED
@@ -0,0 +1,12 @@
1
+ ОБЩЕСТВЕННАЯ ЛИЦЕНЗИЯ "УДАЧИ С ЭТИМ"
2
+ УСЛОВИЯ И ПОЛОЖЕНИЯ ДЛЯ КОПИРОВАНИЯ, РАСПРОСТРАНЕНИЯ И ИЗМЕНЕНИЯ
3
+
4
+ 0. Вы можете ДЕЛАТЬ ВСЁ, ЧТО ЗАХОТИТЕ до тех пор, пока ВЫ НЕ ОСТАВЛЯЕТЕ УЛИК
5
+ ДЛЯ НАХОЖДЕНИЯ АВТОРА оригинального продукта, чтобы обвинить его или заставить
6
+ взять на себя ответственность.
7
+
8
+ НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ АВТОРЫ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ЗА ПРЕТЕНЗИИ,
9
+ УБЫТКИ ИЛИ ДРУГИЕ ОТВЕТСТВЕННОСТИ, ПОДНЯТЫЕ ВО ВРЕМЯ КОНТРАКТА И ВЫЗВАННЫЕ
10
+ ПРЯМОЙ ИЛИ КОСВЕННОЙ СВЯЗЬЮ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
11
+
12
+ Удачи, и храни тебя Господь.
package/README.md ADDED
@@ -0,0 +1,203 @@
1
+ # The Best Sort
2
+
3
+ A comprehensive TypeScript library for array visualization and asynchronous processing using powerful strategy with advanced object-oriented programming patterns and design principles.
4
+
5
+ ## Overview
6
+
7
+ The Best Sort is a production ready framework that demonstrates the application of multiple OOP design patterns, architectural principles, and advanced TypeScript features to visualize array element processing. The library implements a most powerful sort strategy.
8
+
9
+ ## Installation
10
+
11
+ ### Prerequisites
12
+
13
+ - Node.js 18.0.0 or higher
14
+ - npm or yarn
15
+
16
+ ### Setup
17
+
18
+ Clone the repository and install dependencies:
19
+
20
+ ```sh
21
+ npm install -D typescript @types/node
22
+ ```
23
+
24
+ ## Running the Library
25
+
26
+ ```sh
27
+ npm install -D tsx
28
+ npx tsx src/index.ts
29
+ ```
30
+
31
+ ### Manual Compilation
32
+
33
+ ```sh
34
+ npx tsc src/index.ts --experimentalDecorators --emitDecoratorMetadata
35
+ node the-best-sort.js
36
+ ```
37
+
38
+ ## Design Patterns
39
+
40
+ The Best Sort implements multiple design patterns to create a robust and extensible framework, including singleton, factory, builder, facade, decorators, strategy, observer, command invoker and runner.
41
+
42
+
43
+ ## Core Components
44
+
45
+ ### VisualizableNumber
46
+
47
+ A comparable number wrapper implementing the `IVisualizable` interface:
48
+
49
+ ```typescript
50
+ const nums =.map(n => new VisualizableNumber(n));
51
+ ```
52
+
53
+
54
+ ### VisualizationContext
55
+
56
+ Manages state and event notifications during visualization:
57
+
58
+ ```typescript
59
+ const context = new VisualizationContext<VisualizableNumber>("Strategy Name");
60
+ context.attach(observer);
61
+ context.emitElementDisplayed(element, index, delay);
62
+ ```
63
+
64
+
65
+ ### Observers
66
+
67
+ Track visualization events and collect metrics:
68
+
69
+ ```typescript
70
+ const statsObserver = new StatisticsObserver<VisualizableNumber>();
71
+ visualizer.addObserver(statsObserver);
72
+ ```
73
+
74
+
75
+ ### Configuration Management
76
+
77
+ Control visualization behavior globally:
78
+
79
+ ```typescript
80
+ ConfigurationManager.getInstance().updateConfig({
81
+ baseDelayMs: 100,
82
+ enableLogging: true,
83
+ showTimestamps: true,
84
+ colorize: true
85
+ });
86
+ ```
87
+
88
+
89
+ ## Event Types
90
+
91
+ The library emits the following event types during visualization:
92
+
93
+ - `STARTED` - Visualization has started
94
+ - `ELEMENT_DISPLAYED` - An array element was displayed
95
+ - `COMPLETED` - Visualization has completed
96
+ - `ERROR` - An error occurred during visualization
97
+
98
+ ## Performance Metrics
99
+
100
+ `StatisticsObserver` collects the following metrics:
101
+
102
+ ```typescript
103
+ interface VisualizationStatistics {
104
+ duration: number; // Total duration in milliseconds
105
+ displayedElements: number; // Number of elements displayed
106
+ totalDelay: number; // Sum of all delays
107
+ averageDelay: number; // Average delay per element
108
+ eventCounts: Map<EventType, number>; // Event counts by type
109
+ }
110
+ ```
111
+
112
+
113
+ ## Architecture
114
+
115
+ The library follows a layered architecture:
116
+
117
+ 1. **Core Domain** - `VisualizableNumber`, event types, configuration
118
+ 2. **Patterns Layer** - Decorators, strategies, factory implementations
119
+ 3. **Context Layer** - `VisualizationContext` managing state and notifications
120
+ 4. **Observer Layer** - Multiple observer implementations
121
+ 5. **Application Layer** - `ArrayVisualizer`, `CommandInvoker`, runners
122
+ 6. **Factory Layer** - Strategy and builder creation
123
+
124
+ ## TypeScript Features Used
125
+
126
+ - Generics for type-safe implementations
127
+ - Decorators for cross-cutting concerns
128
+ - Abstract classes and interfaces for contracts
129
+ - Union types and enums for type safety
130
+ - Method decorators with property descriptors
131
+ - Readonly types for immutability
132
+ - Object destructuring and spreading
133
+
134
+ ## Extending the Library
135
+
136
+ ### Creating Custom Observers
137
+
138
+ ```typescript
139
+ class CustomObserver<T extends IVisualizable> implements IObserver<T> {
140
+ update(event: VisualizationEvent<T>): void {
141
+ // Custom logic here
142
+ }
143
+ }
144
+
145
+ visualizer.addObserver(new CustomObserver());
146
+ ```
147
+
148
+
149
+ ### Creating Custom Commands
150
+
151
+ ```typescript
152
+ class CustomCommand implements ICommand {
153
+ execute(): void {
154
+ // Custom command logic
155
+ }
156
+
157
+ getDescription(): string {
158
+ return "Custom command description";
159
+ }
160
+ }
161
+
162
+ invoker.enqueueCommand(new CustomCommand());
163
+ ```
164
+
165
+
166
+ ### Creating Custom Runners
167
+
168
+ ```typescript
169
+ class CustomRunner<T extends IVisualizable>
170
+ extends AbstractVisualizationRunner<T> {
171
+
172
+ protected beforeRun(): void {
173
+ console.log("Before run");
174
+ }
175
+
176
+ protected afterRun(): void {
177
+ console.log("After run");
178
+ }
179
+ }
180
+
181
+ const runner = new CustomRunner<VisualizableNumber>();
182
+ runner.run(array, StrategyType.TIMEOUT_FOREACH);
183
+ ```
184
+
185
+ ## Requirements
186
+
187
+ - TypeScript 4.7 or higher
188
+ - Node.js 18.0.0 or higher
189
+ - Decorator support enabled in `tsconfig.json`
190
+
191
+ ## Limitations
192
+
193
+ - All timing is based on setTimeout, which may be affected by event loop congestion
194
+ - Very large arrays (10,000+) may cause performance degradation
195
+ - setTimeout precision is not guaranteed to be exact at sub-millisecond scales
196
+
197
+ ## Contributing
198
+
199
+ Contributions are welcome. Please ensure all code follows the established patterns and includes appropriate type annotations.
200
+
201
+ ## Support
202
+
203
+ For issues, questions, or feature requests, please open an issue in the repository.
@@ -0,0 +1,199 @@
1
+ interface IVisualizable {
2
+ getValue(): number;
3
+ toString(): string;
4
+ }
5
+ interface IObserver<T> {
6
+ update(event: VisualizationEvent<T>): void;
7
+ }
8
+ interface ISubject<T> {
9
+ attach(observer: IObserver<T>): void;
10
+ detach(observer: IObserver<T>): void;
11
+ notify(event: VisualizationEvent<T>): void;
12
+ }
13
+ declare enum EventType {
14
+ STARTED = "STARTED",
15
+ ELEMENT_DISPLAYED = "ELEMENT_DISPLAYED",
16
+ COMPLETED = "COMPLETED",
17
+ ERROR = "ERROR"
18
+ }
19
+ interface VisualizationEvent<T> {
20
+ type: EventType;
21
+ element?: T;
22
+ index?: number;
23
+ timestamp: number;
24
+ delay?: number;
25
+ metadata?: Record<string, any>;
26
+ }
27
+ interface IVisualizationStrategy<T extends IVisualizable> {
28
+ visualize(array: T[], context: VisualizationContext<T>): void;
29
+ getName(): string;
30
+ getDescription(): string;
31
+ }
32
+ interface IVisualizationStrategyFactory<T extends IVisualizable> {
33
+ createStrategy(type: StrategyType): IVisualizationStrategy<T>;
34
+ registerStrategy(type: StrategyType, strategy: IVisualizationStrategy<T>): void;
35
+ listAvailableStrategies(): string[];
36
+ }
37
+ declare enum StrategyType {
38
+ TIMEOUT_FOREACH = "TIMEOUT_FOREACH"
39
+ }
40
+ interface VisualizationConfig {
41
+ baseDelayMs: number;
42
+ enableLogging: boolean;
43
+ logPrefix: string;
44
+ showTimestamps: boolean;
45
+ colorize: boolean;
46
+ }
47
+ declare class VisualizableNumber implements IVisualizable {
48
+ private readonly value;
49
+ constructor(value: number);
50
+ getValue(): number;
51
+ toString(): string;
52
+ toDetailedString(): string;
53
+ }
54
+ declare class ConfigurationManager {
55
+ private static instance;
56
+ private config;
57
+ private constructor();
58
+ static getInstance(): ConfigurationManager;
59
+ getConfig(): Readonly<VisualizationConfig>;
60
+ updateConfig(partial: Partial<VisualizationConfig>): void;
61
+ resetToDefaults(): void;
62
+ }
63
+ declare function Measure(target: any, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor;
64
+ declare function Log(target: any, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor;
65
+ declare function ValidateArray(target: any, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor;
66
+ declare class VisualizationContext<T extends IVisualizable> implements ISubject<T> {
67
+ private strategyName;
68
+ private observers;
69
+ private eventHistory;
70
+ private elementCount;
71
+ constructor(strategyName: string);
72
+ attach(observer: IObserver<T>): void;
73
+ detach(observer: IObserver<T>): void;
74
+ notify(event: VisualizationEvent<T>): void;
75
+ emitStarted(): void;
76
+ emitElementDisplayed(element: T, index: number, delay: number): void;
77
+ emitCompleted(): void;
78
+ emitError(error: Error): void;
79
+ getEventHistory(): VisualizationEvent<T>[];
80
+ getElementCount(): number;
81
+ getStrategyName(): string;
82
+ }
83
+ declare class ConsoleLoggingObserver<T extends IVisualizable> implements IObserver<T> {
84
+ private config;
85
+ update(event: VisualizationEvent<T>): void;
86
+ }
87
+ declare class StatisticsObserver<T extends IVisualizable> implements IObserver<T> {
88
+ private startTime;
89
+ private endTime;
90
+ private displayedElements;
91
+ private totalDelay;
92
+ private events;
93
+ update(event: VisualizationEvent<T>): void;
94
+ getStatistics(): VisualizationStatistics;
95
+ printStatistics(): void;
96
+ reset(): void;
97
+ }
98
+ interface VisualizationStatistics {
99
+ duration: number;
100
+ displayedElements: number;
101
+ totalDelay: number;
102
+ averageDelay: number;
103
+ eventCounts: Map<EventType, number>;
104
+ }
105
+ declare class HistoryObserver<T extends IVisualizable> implements IObserver<T> {
106
+ private history;
107
+ update(event: VisualizationEvent<T>): void;
108
+ getHistory(): Array<{
109
+ event: VisualizationEvent<T>;
110
+ formattedTime: string;
111
+ }>;
112
+ printHistory(): void;
113
+ clear(): void;
114
+ }
115
+ declare abstract class AbstractVisualizationStrategy<T extends IVisualizable> implements IVisualizationStrategy<T> {
116
+ abstract visualize(array: T[], context: VisualizationContext<T>): void;
117
+ abstract getName(): string;
118
+ abstract getDescription(): string;
119
+ protected getConfig(): Readonly<VisualizationConfig>;
120
+ }
121
+ declare class TimeoutForEachStrategy<T extends IVisualizable> extends AbstractVisualizationStrategy<T> {
122
+ visualize(array: T[], context: VisualizationContext<T>): void;
123
+ getName(): string;
124
+ getDescription(): string;
125
+ }
126
+ declare class ConcreteVisualizationStrategyFactory<T extends IVisualizable> implements IVisualizationStrategyFactory<T> {
127
+ private strategies;
128
+ constructor();
129
+ createStrategy(type: StrategyType): IVisualizationStrategy<T>;
130
+ registerStrategy(type: StrategyType, strategy: IVisualizationStrategy<T>): void;
131
+ listAvailableStrategies(): string[];
132
+ hasStrategy(type: StrategyType): boolean;
133
+ }
134
+ declare class VisualizerBuilder<T extends IVisualizable> {
135
+ private array?;
136
+ private strategy?;
137
+ private observers;
138
+ private config?;
139
+ private enableDefaultObservers;
140
+ setArray(array: T[]): this;
141
+ setStrategy(strategy: IVisualizationStrategy<T>): this;
142
+ addObserver(observer: IObserver<T>): this;
143
+ setConfig(config: Partial<VisualizationConfig>): this;
144
+ disableDefaultObservers(): this;
145
+ build(): ArrayVisualizer<T>;
146
+ reset(): this;
147
+ }
148
+ declare class ArrayVisualizer<T extends IVisualizable> {
149
+ private array;
150
+ private strategy;
151
+ private context;
152
+ constructor(array: T[], strategy: IVisualizationStrategy<T>);
153
+ addObserver(observer: IObserver<T>): void;
154
+ removeObserver(observer: IObserver<T>): void;
155
+ execute(): void;
156
+ getContext(): VisualizationContext<T>;
157
+ getEventHistory(): VisualizationEvent<T>[];
158
+ }
159
+ interface ICommand {
160
+ execute(): void;
161
+ getDescription(): string;
162
+ }
163
+ declare class ExecuteVisualizationCommand<T extends IVisualizable> implements ICommand {
164
+ private visualizer;
165
+ constructor(visualizer: ArrayVisualizer<T>);
166
+ execute(): void;
167
+ getDescription(): string;
168
+ }
169
+ declare class UpdateConfigCommand implements ICommand {
170
+ private config;
171
+ constructor(config: Partial<VisualizationConfig>);
172
+ execute(): void;
173
+ getDescription(): string;
174
+ }
175
+ declare class CommandInvoker {
176
+ private commandQueue;
177
+ private executedCommands;
178
+ enqueueCommand(command: ICommand): void;
179
+ executeNext(): void;
180
+ executeAll(): void;
181
+ getQueueSize(): number;
182
+ clearQueue(): void;
183
+ getExecutedCommands(): ICommand[];
184
+ }
185
+ declare abstract class AbstractVisualizationRunner<T extends IVisualizable> {
186
+ run(array: T[], strategyType: StrategyType): void;
187
+ protected abstract beforeRun(): void;
188
+ protected abstract afterRun(): void;
189
+ protected buildVisualizer(builder: VisualizerBuilder<T>, array: T[], strategy: IVisualizationStrategy<T>): ArrayVisualizer<T>;
190
+ protected executeVisualization(visualizer: ArrayVisualizer<T>): void;
191
+ }
192
+ declare class LoggingVisualizationRunner<T extends IVisualizable> extends AbstractVisualizationRunner<T> {
193
+ protected beforeRun(): void;
194
+ protected afterRun(): void;
195
+ }
196
+ declare function demonstrateVisualization(): void;
197
+ declare function demonstrateWithTemplateMethod(): void;
198
+ declare function demonstrateWithCustomConfig(): void;
199
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,577 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var EventType;
12
+ (function (EventType) {
13
+ EventType["STARTED"] = "STARTED";
14
+ EventType["ELEMENT_DISPLAYED"] = "ELEMENT_DISPLAYED";
15
+ EventType["COMPLETED"] = "COMPLETED";
16
+ EventType["ERROR"] = "ERROR";
17
+ })(EventType || (EventType = {}));
18
+ var StrategyType;
19
+ (function (StrategyType) {
20
+ StrategyType["TIMEOUT_FOREACH"] = "TIMEOUT_FOREACH";
21
+ })(StrategyType || (StrategyType = {}));
22
+ class VisualizableNumber {
23
+ constructor(value) {
24
+ this.value = value;
25
+ }
26
+ getValue() {
27
+ return this.value;
28
+ }
29
+ toString() {
30
+ return `${this.value}`;
31
+ }
32
+ toDetailedString() {
33
+ return `VisualizableNumber(${this.value})`;
34
+ }
35
+ }
36
+ class ConfigurationManager {
37
+ constructor() {
38
+ this.config = {
39
+ baseDelayMs: 1000,
40
+ enableLogging: true,
41
+ logPrefix: '',
42
+ showTimestamps: false,
43
+ colorize: true
44
+ };
45
+ }
46
+ static getInstance() {
47
+ if (!ConfigurationManager.instance) {
48
+ ConfigurationManager.instance = new ConfigurationManager();
49
+ }
50
+ return ConfigurationManager.instance;
51
+ }
52
+ getConfig() {
53
+ return Object.freeze({ ...this.config });
54
+ }
55
+ updateConfig(partial) {
56
+ this.config = { ...this.config, ...partial };
57
+ }
58
+ resetToDefaults() {
59
+ this.config = {
60
+ baseDelayMs: 1000,
61
+ enableLogging: true,
62
+ logPrefix: '🎯',
63
+ showTimestamps: false,
64
+ colorize: true
65
+ };
66
+ }
67
+ }
68
+ function Measure(target, propertyKey, descriptor) {
69
+ const originalMethod = descriptor.value;
70
+ descriptor.value = function (...args) {
71
+ const start = performance.now();
72
+ const result = originalMethod.apply(this, args);
73
+ if (result && typeof result.then === 'function') {
74
+ return result.then((res) => {
75
+ const end = performance.now();
76
+ console.log(`${propertyKey} completed in ${(end - start).toFixed(2)}ms`);
77
+ return res;
78
+ });
79
+ }
80
+ const end = performance.now();
81
+ console.log(`${propertyKey} executed in ${(end - start).toFixed(2)}ms`);
82
+ return result;
83
+ };
84
+ return descriptor;
85
+ }
86
+ function Log(target, propertyKey, descriptor) {
87
+ const originalMethod = descriptor.value;
88
+ descriptor.value = function (...args) {
89
+ const config = ConfigurationManager.getInstance().getConfig();
90
+ if (config.enableLogging) {
91
+ console.log(`Calling ${propertyKey} with ${args.length} argument(s)`);
92
+ }
93
+ return originalMethod.apply(this, args);
94
+ };
95
+ return descriptor;
96
+ }
97
+ function ValidateArray(target, propertyKey, descriptor) {
98
+ const originalMethod = descriptor.value;
99
+ descriptor.value = function (...args) {
100
+ const array = args[0];
101
+ if (!Array.isArray(array)) {
102
+ throw new TypeError(`${propertyKey} expects an array as first argument`);
103
+ }
104
+ if (array.length === 0) {
105
+ throw new Error(`${propertyKey} cannot work with empty array`);
106
+ }
107
+ return originalMethod.apply(this, args);
108
+ };
109
+ return descriptor;
110
+ }
111
+ class VisualizationContext {
112
+ constructor(strategyName) {
113
+ this.strategyName = strategyName;
114
+ this.observers = new Set();
115
+ this.eventHistory = [];
116
+ this.elementCount = 0;
117
+ }
118
+ attach(observer) {
119
+ this.observers.add(observer);
120
+ }
121
+ detach(observer) {
122
+ this.observers.delete(observer);
123
+ }
124
+ notify(event) {
125
+ this.eventHistory.push(event);
126
+ this.observers.forEach(observer => observer.update(event));
127
+ }
128
+ emitStarted() {
129
+ const event = {
130
+ type: EventType.STARTED,
131
+ timestamp: Date.now(),
132
+ metadata: { strategy: this.strategyName }
133
+ };
134
+ this.notify(event);
135
+ }
136
+ emitElementDisplayed(element, index, delay) {
137
+ this.elementCount++;
138
+ const event = {
139
+ type: EventType.ELEMENT_DISPLAYED,
140
+ element,
141
+ index,
142
+ timestamp: Date.now(),
143
+ delay,
144
+ metadata: { totalDisplayed: this.elementCount }
145
+ };
146
+ this.notify(event);
147
+ }
148
+ emitCompleted() {
149
+ const event = {
150
+ type: EventType.COMPLETED,
151
+ timestamp: Date.now(),
152
+ metadata: {
153
+ strategy: this.strategyName,
154
+ totalElements: this.elementCount
155
+ }
156
+ };
157
+ this.notify(event);
158
+ }
159
+ emitError(error) {
160
+ const event = {
161
+ type: EventType.ERROR,
162
+ timestamp: Date.now(),
163
+ metadata: { error: error.message }
164
+ };
165
+ this.notify(event);
166
+ }
167
+ getEventHistory() {
168
+ return [...this.eventHistory];
169
+ }
170
+ getElementCount() {
171
+ return this.elementCount;
172
+ }
173
+ getStrategyName() {
174
+ return this.strategyName;
175
+ }
176
+ }
177
+ class ConsoleLoggingObserver {
178
+ constructor() {
179
+ this.config = ConfigurationManager.getInstance().getConfig();
180
+ }
181
+ update(event) {
182
+ if (!this.config.enableLogging)
183
+ return;
184
+ const timestamp = this.config.showTimestamps
185
+ ? `[${new Date(event.timestamp).toISOString()}] `
186
+ : '';
187
+ switch (event.type) {
188
+ case EventType.STARTED:
189
+ console.log(`\n${this.config.logPrefix} ${timestamp}Visualization started: ${event.metadata?.strategy}`);
190
+ break;
191
+ case EventType.ELEMENT_DISPLAYED:
192
+ const delayInfo = event.delay ? ` (delay: ${event.delay}ms)` : '';
193
+ console.log(`${this.config.logPrefix} ${timestamp}Element ${event.element?.getValue()} displayed${delayInfo}`);
194
+ break;
195
+ case EventType.COMPLETED:
196
+ console.log(`${this.config.logPrefix} ${timestamp}Visualization completed: ${event.metadata?.totalElements} elements\n`);
197
+ break;
198
+ case EventType.ERROR:
199
+ console.error(`${this.config.logPrefix} ${timestamp}Error: ${event.metadata?.error}`);
200
+ break;
201
+ }
202
+ }
203
+ }
204
+ class StatisticsObserver {
205
+ constructor() {
206
+ this.startTime = 0;
207
+ this.endTime = 0;
208
+ this.displayedElements = 0;
209
+ this.totalDelay = 0;
210
+ this.events = new Map();
211
+ }
212
+ update(event) {
213
+ const currentCount = this.events.get(event.type) || 0;
214
+ this.events.set(event.type, currentCount + 1);
215
+ switch (event.type) {
216
+ case EventType.STARTED:
217
+ this.startTime = event.timestamp;
218
+ break;
219
+ case EventType.ELEMENT_DISPLAYED:
220
+ this.displayedElements++;
221
+ if (event.delay) {
222
+ this.totalDelay += event.delay;
223
+ }
224
+ break;
225
+ case EventType.COMPLETED:
226
+ this.endTime = event.timestamp;
227
+ break;
228
+ }
229
+ }
230
+ getStatistics() {
231
+ return {
232
+ duration: this.endTime - this.startTime,
233
+ displayedElements: this.displayedElements,
234
+ totalDelay: this.totalDelay,
235
+ averageDelay: this.displayedElements > 0 ? this.totalDelay / this.displayedElements : 0,
236
+ eventCounts: new Map(this.events)
237
+ };
238
+ }
239
+ printStatistics() {
240
+ const stats = this.getStatistics();
241
+ console.log('\n Visualization Statistics:');
242
+ console.log(` Duration: ${stats.duration.toFixed(2)}ms`);
243
+ console.log(` Elements Displayed: ${stats.displayedElements}`);
244
+ console.log(` Total Delay: ${stats.totalDelay}ms`);
245
+ console.log(` Average Delay: ${stats.averageDelay.toFixed(2)}ms`);
246
+ console.log(' Event Counts:');
247
+ stats.eventCounts.forEach((count, type) => {
248
+ console.log(` ${type}: ${count}`);
249
+ });
250
+ }
251
+ reset() {
252
+ this.startTime = 0;
253
+ this.endTime = 0;
254
+ this.displayedElements = 0;
255
+ this.totalDelay = 0;
256
+ this.events.clear();
257
+ }
258
+ }
259
+ class HistoryObserver {
260
+ constructor() {
261
+ this.history = [];
262
+ }
263
+ update(event) {
264
+ this.history.push({
265
+ event,
266
+ formattedTime: new Date(event.timestamp).toLocaleTimeString()
267
+ });
268
+ }
269
+ getHistory() {
270
+ return [...this.history];
271
+ }
272
+ printHistory() {
273
+ console.log('\n Visualization History:');
274
+ this.history.forEach(({ event, formattedTime }, index) => {
275
+ console.log(` ${index + 1}. [${formattedTime}] ${event.type}${event.element ? ` - ${event.element.getValue()}` : ''}`);
276
+ });
277
+ }
278
+ clear() {
279
+ this.history = [];
280
+ }
281
+ }
282
+ class AbstractVisualizationStrategy {
283
+ getConfig() {
284
+ return ConfigurationManager.getInstance().getConfig();
285
+ }
286
+ }
287
+ class TimeoutForEachStrategy extends AbstractVisualizationStrategy {
288
+ visualize(array, context) {
289
+ context.emitStarted();
290
+ try {
291
+ array.forEach((element, index) => {
292
+ const delayMs = element.getValue();
293
+ setTimeout(() => {
294
+ console.log(element.getValue());
295
+ context.emitElementDisplayed(element, index, delayMs);
296
+ if (index === array.length - 1) {
297
+ setTimeout(() => {
298
+ context.emitCompleted();
299
+ }, 10);
300
+ }
301
+ }, delayMs);
302
+ });
303
+ }
304
+ catch (error) {
305
+ context.emitError(error);
306
+ throw error;
307
+ }
308
+ }
309
+ getName() {
310
+ return 'setTimeout + forEach Strategy';
311
+ }
312
+ getDescription() {
313
+ return 'Visualizes array elements using setTimeout with delay equal to element value: arr.forEach((t) => setTimeout(() => console.log(t), t))';
314
+ }
315
+ }
316
+ __decorate([
317
+ Log,
318
+ ValidateArray,
319
+ Measure,
320
+ __metadata("design:type", Function),
321
+ __metadata("design:paramtypes", [Array, VisualizationContext]),
322
+ __metadata("design:returntype", void 0)
323
+ ], TimeoutForEachStrategy.prototype, "visualize", null);
324
+ class ConcreteVisualizationStrategyFactory {
325
+ constructor() {
326
+ this.strategies = new Map();
327
+ this.registerStrategy(StrategyType.TIMEOUT_FOREACH, new TimeoutForEachStrategy());
328
+ }
329
+ createStrategy(type) {
330
+ const strategy = this.strategies.get(type);
331
+ if (!strategy) {
332
+ throw new Error(`Strategy type '${type}' not found. Available: ${this.listAvailableStrategies().join(', ')}`);
333
+ }
334
+ return strategy;
335
+ }
336
+ registerStrategy(type, strategy) {
337
+ this.strategies.set(type, strategy);
338
+ }
339
+ listAvailableStrategies() {
340
+ return Array.from(this.strategies.keys());
341
+ }
342
+ hasStrategy(type) {
343
+ return this.strategies.has(type);
344
+ }
345
+ }
346
+ class VisualizerBuilder {
347
+ constructor() {
348
+ this.observers = [];
349
+ this.enableDefaultObservers = true;
350
+ }
351
+ setArray(array) {
352
+ this.array = array;
353
+ return this;
354
+ }
355
+ setStrategy(strategy) {
356
+ this.strategy = strategy;
357
+ return this;
358
+ }
359
+ addObserver(observer) {
360
+ this.observers.push(observer);
361
+ return this;
362
+ }
363
+ setConfig(config) {
364
+ this.config = config;
365
+ return this;
366
+ }
367
+ disableDefaultObservers() {
368
+ this.enableDefaultObservers = false;
369
+ return this;
370
+ }
371
+ build() {
372
+ if (!this.array) {
373
+ throw new Error('Array is required to build visualizer');
374
+ }
375
+ if (!this.strategy) {
376
+ throw new Error('Strategy is required to build visualizer');
377
+ }
378
+ if (this.config) {
379
+ ConfigurationManager.getInstance().updateConfig(this.config);
380
+ }
381
+ const visualizer = new ArrayVisualizer(this.array, this.strategy);
382
+ if (this.enableDefaultObservers) {
383
+ visualizer.addObserver(new ConsoleLoggingObserver());
384
+ }
385
+ this.observers.forEach(observer => visualizer.addObserver(observer));
386
+ return visualizer;
387
+ }
388
+ reset() {
389
+ this.array = undefined;
390
+ this.strategy = undefined;
391
+ this.observers = [];
392
+ this.config = undefined;
393
+ this.enableDefaultObservers = true;
394
+ return this;
395
+ }
396
+ }
397
+ class ArrayVisualizer {
398
+ constructor(array, strategy) {
399
+ this.array = array;
400
+ this.strategy = strategy;
401
+ this.context = new VisualizationContext(strategy.getName());
402
+ }
403
+ addObserver(observer) {
404
+ this.context.attach(observer);
405
+ }
406
+ removeObserver(observer) {
407
+ this.context.detach(observer);
408
+ }
409
+ execute() {
410
+ console.log('\n' + '='.repeat(70));
411
+ console.log(` ${this.strategy.getName()}`);
412
+ console.log('='.repeat(70));
413
+ console.log(` ${this.strategy.getDescription()}`);
414
+ console.log(` Array: [${this.array.map(x => x.getValue()).join(', ')}]`);
415
+ console.log('='.repeat(70));
416
+ this.strategy.visualize([...this.array], this.context);
417
+ }
418
+ getContext() {
419
+ return this.context;
420
+ }
421
+ getEventHistory() {
422
+ return this.context.getEventHistory();
423
+ }
424
+ }
425
+ __decorate([
426
+ Measure,
427
+ __metadata("design:type", Function),
428
+ __metadata("design:paramtypes", []),
429
+ __metadata("design:returntype", void 0)
430
+ ], ArrayVisualizer.prototype, "execute", null);
431
+ class ExecuteVisualizationCommand {
432
+ constructor(visualizer) {
433
+ this.visualizer = visualizer;
434
+ }
435
+ execute() {
436
+ this.visualizer.execute();
437
+ }
438
+ getDescription() {
439
+ return 'Execute array visualization';
440
+ }
441
+ }
442
+ class UpdateConfigCommand {
443
+ constructor(config) {
444
+ this.config = config;
445
+ }
446
+ execute() {
447
+ ConfigurationManager.getInstance().updateConfig(this.config);
448
+ console.log('Configuration updated');
449
+ }
450
+ getDescription() {
451
+ return 'Update visualization configuration';
452
+ }
453
+ }
454
+ class CommandInvoker {
455
+ constructor() {
456
+ this.commandQueue = [];
457
+ this.executedCommands = [];
458
+ }
459
+ enqueueCommand(command) {
460
+ this.commandQueue.push(command);
461
+ }
462
+ executeNext() {
463
+ const command = this.commandQueue.shift();
464
+ if (command) {
465
+ console.log(`\n🔧 Executing: ${command.getDescription()}`);
466
+ command.execute();
467
+ this.executedCommands.push(command);
468
+ }
469
+ }
470
+ executeAll() {
471
+ while (this.commandQueue.length > 0) {
472
+ this.executeNext();
473
+ }
474
+ }
475
+ getQueueSize() {
476
+ return this.commandQueue.length;
477
+ }
478
+ clearQueue() {
479
+ this.commandQueue = [];
480
+ }
481
+ getExecutedCommands() {
482
+ return [...this.executedCommands];
483
+ }
484
+ }
485
+ class AbstractVisualizationRunner {
486
+ run(array, strategyType) {
487
+ this.beforeRun();
488
+ const factory = new ConcreteVisualizationStrategyFactory();
489
+ const strategy = factory.createStrategy(strategyType);
490
+ const builder = new VisualizerBuilder();
491
+ const visualizer = this.buildVisualizer(builder, array, strategy);
492
+ this.executeVisualization(visualizer);
493
+ this.afterRun();
494
+ }
495
+ buildVisualizer(builder, array, strategy) {
496
+ return builder
497
+ .setArray(array)
498
+ .setStrategy(strategy)
499
+ .build();
500
+ }
501
+ executeVisualization(visualizer) {
502
+ visualizer.execute();
503
+ }
504
+ }
505
+ class LoggingVisualizationRunner extends AbstractVisualizationRunner {
506
+ beforeRun() {
507
+ console.log('\n Starting visualization process...');
508
+ }
509
+ afterRun() {
510
+ console.log('\n Visualization process completed.');
511
+ }
512
+ }
513
+ function demonstrateVisualization() {
514
+ ConfigurationManager.getInstance().updateConfig({
515
+ enableLogging: true,
516
+ logPrefix: '>',
517
+ showTimestamps: false
518
+ });
519
+ console.log('\n' + '='.repeat(70));
520
+ console.log('ARRAY VISUALIZATION FRAMEWORK');
521
+ console.log(' Using setTimeout + forEach Strategy');
522
+ console.log('='.repeat(70));
523
+ const numbers = [1, 2, 3];
524
+ const visualizableArray = numbers.map(n => new VisualizableNumber(n));
525
+ console.log(`\n Input array: [${numbers.join(', ')}]`);
526
+ console.log(' Each element will be displayed after a delay equal to its value (in milliseconds)\n');
527
+ const factory = new ConcreteVisualizationStrategyFactory();
528
+ const strategy = factory.createStrategy(StrategyType.TIMEOUT_FOREACH);
529
+ const statisticsObserver = new StatisticsObserver();
530
+ const historyObserver = new HistoryObserver();
531
+ const builder = new VisualizerBuilder();
532
+ const visualizer = builder
533
+ .setArray(visualizableArray)
534
+ .setStrategy(strategy)
535
+ .addObserver(statisticsObserver)
536
+ .addObserver(historyObserver)
537
+ .build();
538
+ const invoker = new CommandInvoker();
539
+ const visualizationCommand = new ExecuteVisualizationCommand(visualizer);
540
+ invoker.enqueueCommand(visualizationCommand);
541
+ invoker.executeAll();
542
+ setTimeout(() => {
543
+ console.log('\n' + '─'.repeat(70));
544
+ statisticsObserver.printStatistics();
545
+ historyObserver.printHistory();
546
+ console.log('\n' + '='.repeat(70));
547
+ console.log('DEMONSTRATION COMPLETED');
548
+ console.log('='.repeat(70) + '\n');
549
+ }, 5000);
550
+ }
551
+ function demonstrateWithTemplateMethod() {
552
+ const numbers = [1, 2, 3];
553
+ const visualizableArray = numbers.map(n => new VisualizableNumber(n));
554
+ const runner = new LoggingVisualizationRunner();
555
+ runner.run(visualizableArray, StrategyType.TIMEOUT_FOREACH);
556
+ }
557
+ function demonstrateWithCustomConfig() {
558
+ const numbers = [100, 200, 300];
559
+ const visualizableArray = numbers.map(n => new VisualizableNumber(n));
560
+ const invoker = new CommandInvoker();
561
+ const configCommand = new UpdateConfigCommand({
562
+ logPrefix: '[TIMEOUT_FOREACH FRAMEWORK] ',
563
+ showTimestamps: true
564
+ });
565
+ invoker.enqueueCommand(configCommand);
566
+ const factory = new ConcreteVisualizationStrategyFactory();
567
+ const strategy = factory.createStrategy(StrategyType.TIMEOUT_FOREACH);
568
+ const visualizer = new VisualizerBuilder()
569
+ .setArray(visualizableArray)
570
+ .setStrategy(strategy)
571
+ .build();
572
+ const visualizationCommand = new ExecuteVisualizationCommand(visualizer);
573
+ invoker.enqueueCommand(visualizationCommand);
574
+ invoker.executeAll();
575
+ }
576
+ console.log('\n Starting demonstration...\n');
577
+ demonstrateVisualization();
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "the-best-sort",
3
+ "version": "1.0.0",
4
+ "description": "Sorting framework basid on best design patterns with the most powerful sort strategies in TypeScript",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "LICENSE",
10
+ "README.md",
11
+ "CHANGELOG.md"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc --project tsconfig.build.json",
15
+ "clean": "rm -rf dist",
16
+ "prebuild": "npm run clean",
17
+ "prepare": "npm run build",
18
+ "prepublishOnly": "npm run build",
19
+ "type-check": "tsc --noEmit"
20
+ },
21
+ "keywords": [
22
+ "typescript",
23
+ "sort",
24
+ "design-patterns",
25
+ "visualization",
26
+ "observer-pattern",
27
+ "strategy-pattern",
28
+ "factory-pattern",
29
+ "builder-pattern",
30
+ "async",
31
+ "async-visualization"
32
+ ],
33
+ "author": "Danila Grigoriev <danila.sar@yandex.ru> (http://danilasar.ru)",
34
+ "license": "GLWT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/danilasar/the-best-sort.git"
38
+ },
39
+ "bugs": {
40
+ "url": "https://github.com/danilasar/the-best-sort/issues"
41
+ },
42
+ "homepage": "https://github.com/danilasar/the-best-sort#readme",
43
+ "engines": {
44
+ "node": ">=18.0.0"
45
+ },
46
+ "devDependencies": {
47
+ "@types/node": "^20.10.0",
48
+ "typescript": "^5.3.0",
49
+ "tsx": "^4.20.6"
50
+ }
51
+ }