orcas-angular 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.
Files changed (42) hide show
  1. package/LICENSE +159 -0
  2. package/README.md +17 -0
  3. package/async/README.md +46 -0
  4. package/async/async.ts +16 -0
  5. package/async/cancellation-token.ts +90 -0
  6. package/dev/README.md +41 -0
  7. package/dev/console-hook.ts +25 -0
  8. package/dev/debug.service.ts.example +29 -0
  9. package/framework/README.md +34 -0
  10. package/framework/services-init.ts +25 -0
  11. package/index.ts +21 -0
  12. package/localization/README.md +73 -0
  13. package/localization/localization.interface.ts +18 -0
  14. package/localization/localization.service.ts +131 -0
  15. package/localization/localize.pipe.ts +30 -0
  16. package/log/README.md +275 -0
  17. package/log/echo-provider.ts +27 -0
  18. package/log/echo.ts +635 -0
  19. package/log/index.ts +6 -0
  20. package/log/log-systems.ts +20 -0
  21. package/navigation/README.md +47 -0
  22. package/navigation/back-on-click.directive.ts +19 -0
  23. package/navigation/index.ts +3 -0
  24. package/navigation/navigation-stack.service.ts +33 -0
  25. package/package.json +29 -0
  26. package/storage/README.md +75 -0
  27. package/storage/capacitor-files.service.ts +38 -0
  28. package/storage/file-box.service.ts +112 -0
  29. package/storage/files.ts +42 -0
  30. package/storage/key-signals.ts +49 -0
  31. package/storage/local-storage-files.service.ts +49 -0
  32. package/storage/settings-signals.service.ts +24 -0
  33. package/storage/settings.service.ts +24 -0
  34. package/storage/tauri-files.service.ts +69 -0
  35. package/theme/README.md +44 -0
  36. package/theme/theme.service.ts +33 -0
  37. package/ui/README.md +42 -0
  38. package/ui/context-menu/context-button.component.ts +55 -0
  39. package/ui/context-menu/context-header.component.ts +15 -0
  40. package/ui/context-menu/context-menu-trigger.directive.ts +26 -0
  41. package/ui/context-menu/context-menu.component.ts +95 -0
  42. package/ui/context-menu/index.ts +4 -0
@@ -0,0 +1,131 @@
1
+ import { computed, inject, Injectable, signal } from '@angular/core';
2
+ import { HttpClient } from '@angular/common/http';
3
+ import { ILocalizationService } from './localization.interface';
4
+
5
+ @Injectable({
6
+ providedIn: 'root'
7
+ })
8
+ export class LocalizationService implements ILocalizationService {
9
+ private defaultLanguage = 'en';
10
+ private storageKey = 'orcas-language';
11
+
12
+ private translations: any = {};
13
+ private loaded = false;
14
+
15
+ private $language: ReturnType<typeof signal<string>>;
16
+ public $currentLang = computed(() => this.$language());
17
+
18
+ private http = inject(HttpClient);
19
+
20
+ constructor() {
21
+ this.$language = signal(this.getStoredLanguage());
22
+ }
23
+
24
+ public async init(
25
+ jsonPath: string = 'assets/translations.json',
26
+ defaultLanguage: string = 'en',
27
+ storageKey: string = 'orcas-language'
28
+ ): Promise<void> {
29
+ this.defaultLanguage = defaultLanguage;
30
+ this.storageKey = storageKey;
31
+ this.$language.set(this.getStoredLanguage());
32
+
33
+ try {
34
+ this.translations = await this.http.get(jsonPath).toPromise();
35
+ this.loaded = true;
36
+ }
37
+ catch (err) {
38
+ console.error('Failed to load translations:', err);
39
+ }
40
+ }
41
+
42
+ getLanguage(): string {
43
+ return this.$language();
44
+ }
45
+
46
+ getDefaultLanguage(): string {
47
+ return this.defaultLanguage;
48
+ }
49
+
50
+ setActiveLanguage(lang: string): void {
51
+ if (lang !== this.$language()) {
52
+ localStorage.setItem(this.storageKey, lang);
53
+ this.$language.set(lang);
54
+ }
55
+ }
56
+
57
+ translate(key: string, params?: any, language?: string): string {
58
+ const lang = language || this.getLanguage();
59
+
60
+ if (!this.loaded) {
61
+ console.error('Localization: Translations not loaded yet!');
62
+ return key;
63
+ }
64
+
65
+ let translation = null;
66
+
67
+ // Handle pluralization: try singular suffix __1 first if count is 1
68
+ if (params && params.count === 1)
69
+ translation = this.resolveKey(`${key}__1`);
70
+
71
+ if (!translation)
72
+ translation = this.resolveKey(key);
73
+
74
+ if (!translation) {
75
+ console.warn(`Localization: Key not found for "${key}".`);
76
+ return key;
77
+ }
78
+
79
+ let translatedText = translation[lang];
80
+
81
+ if (!translatedText) {
82
+ console.warn(`Localization: Key "${key}" not found for language "${lang}". Falling back to default language.`);
83
+ translatedText = translation[this.defaultLanguage];
84
+ }
85
+
86
+ if (!translatedText) {
87
+ console.error(`Localization: Key "${key}" not found for default language "${this.defaultLanguage}".`);
88
+ return key;
89
+ }
90
+
91
+ if (params) {
92
+ if (Array.isArray(params))
93
+ return this.replaceArrayParams(translatedText, params);
94
+ else
95
+ return this.replaceObjectParams(translatedText, params);
96
+ }
97
+
98
+ return translatedText;
99
+ }
100
+
101
+ private resolveKey(key: string): any {
102
+ const keys = key.split('.');
103
+ let translation = this.translations;
104
+ for (const k of keys) {
105
+ if (!translation[k])
106
+ return null;
107
+ translation = translation[k];
108
+ }
109
+ return translation;
110
+ }
111
+
112
+ private getStoredLanguage(): string {
113
+ return localStorage.getItem(this.storageKey) || this.defaultLanguage;
114
+ }
115
+
116
+ private replaceArrayParams(text: string, params: any[]): string {
117
+ let result = text;
118
+ params.forEach((param, index) => {
119
+ result = result.replace(new RegExp(`\\{\\{${index}\\}\\}`, 'g'), param.toString());
120
+ });
121
+ return result;
122
+ }
123
+
124
+ private replaceObjectParams(text: string, params: any): string {
125
+ let result = text;
126
+ Object.keys(params).forEach(key => {
127
+ result = result.replace(new RegExp(`\\{\\{${key}\\}\\}`, 'g'), params[key].toString());
128
+ });
129
+ return result;
130
+ }
131
+ }
@@ -0,0 +1,30 @@
1
+ import {Pipe, PipeTransform} from '@angular/core';
2
+ import {LocalizationService} from './localization.service';
3
+
4
+ @Pipe({
5
+ name: 'localize',
6
+ standalone: true,
7
+ pure: false
8
+ })
9
+ export class LocalizePipe implements PipeTransform {
10
+ private lastLanguage: string = '';
11
+ private lastKey: string = '';
12
+ private lastParams: any;
13
+ private lastResult: string = '';
14
+
15
+ constructor(private localizationService: LocalizationService) {
16
+ }
17
+
18
+ transform(key: string, params?: any): string {
19
+ if (this.localizationService.$currentLang() !== this.lastLanguage
20
+ || key !== this.lastKey
21
+ || params !== this.lastParams) {
22
+ this.lastLanguage = this.localizationService.$currentLang();
23
+ this.lastKey = key;
24
+ this.lastParams = params;
25
+ this.lastResult = this.localizationService.translate(key, params);
26
+ }
27
+
28
+ return this.lastResult;
29
+ }
30
+ }
package/log/README.md ADDED
@@ -0,0 +1,275 @@
1
+ # Echo TypeScript
2
+
3
+ TypeScript port of the Echo.cs logging library. This is a flexible and powerful logging library with support for log levels, system-based organization, and custom log writers.
4
+
5
+ ## Features
6
+
7
+ - Structured logging with system tags
8
+ - Customizable log levels (per system or global)
9
+ - String formatting with parameters (only formatted when log will be written)
10
+ - Log-once functionality to prevent duplicate messages
11
+ - Extensible with custom log writers
12
+ - Console log writer with colors and timestamps included
13
+ - TypeScript type safety
14
+ - Performance optimized - no allocations when logs are filtered out
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ # Install dependencies
20
+ npm install
21
+
22
+ # Build the library
23
+ npm run build
24
+ ```
25
+
26
+ The compiled JavaScript and type definitions will be in the `dist/` folder.
27
+
28
+ ## Quick Start
29
+
30
+ ```typescript
31
+ import { EchoConsole, LogLevel } from './dist/echo';
32
+
33
+ // Create an Echo instance with default console writer
34
+ const echo = EchoConsole.new();
35
+
36
+ // Get a logger
37
+ const logger = echo.getLogger();
38
+
39
+ // Log messages
40
+ logger.debug("System", "Debug message");
41
+ logger.info("System", "Info message");
42
+ logger.warn("System", "Warning message");
43
+ logger.error("System", "Error message");
44
+ ```
45
+
46
+ ## Usage Examples
47
+
48
+ ### Basic Logging
49
+
50
+ ```typescript
51
+ import { EchoConsole } from './echo';
52
+
53
+ const echo = EchoConsole.new();
54
+ const logger = echo.getLogger();
55
+
56
+ // Log with different levels
57
+ logger.debug("GUI", "This is a debug message from the GUI system.");
58
+ logger.info("Physics", "This is an info message from the Physics system.");
59
+ logger.warn("AI", "This is a warning message from the AI system.");
60
+ logger.error("Rendering", "This is an error message from the Rendering system.");
61
+ ```
62
+
63
+ ### System Logger
64
+
65
+ ```typescript
66
+ // Get a system-specific logger (cached per system)
67
+ const animationLogger = echo.getSystemLogger("Animation");
68
+
69
+ // No need to specify system in subsequent calls
70
+ animationLogger.debug("This is a debug message from the Animation system.");
71
+ animationLogger.info("This is an info message from the Animation system.");
72
+ animationLogger.warn("This is a warning message from the Animation system.");
73
+ animationLogger.error("This is an error message from the Animation system.");
74
+ ```
75
+
76
+ ### String Formatting
77
+
78
+ ```typescript
79
+ // Use formatted strings with parameters
80
+ // Formatting is only done IF the log will be written (performance optimization)
81
+ const playerName = "John";
82
+ const playerHealth = 100;
83
+ logger.info("General", "Player {0} has {1} health.", playerName, playerHealth);
84
+ // Output: Player John has 100 health.
85
+ ```
86
+
87
+ ### Log Level Management
88
+
89
+ ```typescript
90
+ import { LogLevel } from './echo';
91
+
92
+ // Set default log level (applies to all systems)
93
+ echo.settings.setDefaultLevel(LogLevel.Warn); // Only Warn and Error will be logged
94
+
95
+ // Set system-specific log level
96
+ echo.settings.setSystemLevel("Physics", LogLevel.Debug); // Physics logs everything
97
+
98
+ // Get current log level for a system
99
+ const level = echo.settings.getSystemLevel("Physics");
100
+
101
+ // Clear a system-specific level (reverts to default)
102
+ echo.settings.clearSystemLevel("Physics");
103
+
104
+ // Clear all system-specific levels
105
+ echo.settings.clearSystemLevels();
106
+ ```
107
+
108
+ ### Log Once
109
+
110
+ ```typescript
111
+ // Log a message only once, even if called multiple times
112
+ logger.debug1("System", "This will only appear once");
113
+ logger.debug1("System", "This will only appear once"); // Won't be logged
114
+ logger.debug1("System", "This will only appear once"); // Won't be logged
115
+
116
+ // Also works with other log levels
117
+ logger.info1("System", "Info once");
118
+ logger.warn1("System", "Warn once");
119
+ logger.error1("System", "Error once");
120
+ ```
121
+
122
+ ### Custom Configuration
123
+
124
+ ```typescript
125
+ import { LogWriterConfig, SystemColor } from './echo';
126
+
127
+ const config = new LogWriterConfig();
128
+ config.timestamp = true; // Include timestamps (default: true)
129
+ config.levelLabels = true; // Include log level labels (default: true)
130
+ config.levelColors = true; // Use colors for log levels (default: true)
131
+ config.systemColor = SystemColor.LabelAndMessage; // Color both label and message
132
+
133
+ const echo = EchoConsole.new(config);
134
+ ```
135
+
136
+ ### Custom Log Writer
137
+
138
+ ```typescript
139
+ import { Echo, EchoLogWriter, LogLevel } from './echo';
140
+
141
+ class CustomLogWriter implements EchoLogWriter {
142
+ writeLog(level: LogLevel, system: string, message: string): void {
143
+ // Custom log writing logic here
144
+ const timestamp = new Date().toISOString();
145
+ console.log(`${timestamp} | ${level} | [${system}] ${message}`);
146
+ }
147
+ }
148
+
149
+ // Use custom writer
150
+ const customWriter = new CustomLogWriter();
151
+ const echo = new Echo(customWriter);
152
+ ```
153
+
154
+ ## API Reference
155
+
156
+ ### Echo Class
157
+
158
+ Main entry point for the library.
159
+
160
+ ```typescript
161
+ constructor(writer: EchoLogWriter)
162
+ ```
163
+
164
+ - **getLogger()**: Returns the main logger instance (cached)
165
+ - **getSystemLogger(system: string)**: Returns a system-specific logger (cached per system)
166
+ - **settings**: Access to EchoSettings for configuration
167
+
168
+ ### EchoLogger Class
169
+
170
+ Main logger with system parameter required.
171
+
172
+ **Methods** (all have the same signature pattern):
173
+ - **debug(system: string, message: string, ...params: any[])**
174
+ - **info(system: string, message: string, ...params: any[])**
175
+ - **warn(system: string, message: string, ...params: any[])**
176
+ - **error(system: string, message: string, ...params: any[])**
177
+
178
+ **Log-once variants** (append `1` to method name):
179
+ - **debug1, info1, warn1, error1** - Same signatures as above
180
+
181
+ ### EchoSystemLogger Class
182
+
183
+ System-specific logger (system is set at creation).
184
+
185
+ **Methods** (no system parameter needed):
186
+ - **debug(message: string, ...params: any[])**
187
+ - **info(message: string, ...params: any[])**
188
+ - **warn(message: string, ...params: any[])**
189
+ - **error(message: string, ...params: any[])**
190
+
191
+ **Log-once variants**:
192
+ - **debug1, info1, warn1, error1** - Same signatures as above
193
+
194
+ ### EchoSettings Class
195
+
196
+ Configuration for log levels.
197
+
198
+ - **defaultLevel**: Get/set the default log level
199
+ - **setDefaultLevel(level: LogLevel)**: Set default log level for all systems
200
+ - **setSystemLevel(system: string, level: LogLevel)**: Set log level for specific system
201
+ - **getSystemLevel(system: string)**: Get log level for specific system
202
+ - **clearSystemLevel(system: string)**: Remove system-specific level
203
+ - **clearSystemLevels()**: Remove all system-specific levels
204
+ - **getAllSystemLevels()**: Get all system-specific levels
205
+ - **onUpdated(callback: () => void)**: Register callback for settings updates
206
+
207
+ ### LogLevel Enum
208
+
209
+ ```typescript
210
+ enum LogLevel {
211
+ None = 0, // No logging
212
+ Error = 1, // Errors only
213
+ Warn = 2, // Warnings and errors
214
+ Info = 3, // Info, warnings, and errors
215
+ Debug = 4 // All logs (most verbose)
216
+ }
217
+ ```
218
+
219
+ ### LogWriterConfig Class
220
+
221
+ Configuration for the console log writer.
222
+
223
+ - **timestamp**: Include timestamps (default: true)
224
+ - **levelLabels**: Include log level labels (default: true)
225
+ - **levelColors**: Use colors for log levels (default: true)
226
+ - **systemColor**: Control system color usage (default: SystemColor.LabelOnly)
227
+
228
+ ### SystemColor Enum
229
+
230
+ ```typescript
231
+ enum SystemColor {
232
+ None, // No color
233
+ LabelOnly, // Color only the system label
234
+ LabelAndMessage // Color both label and message
235
+ }
236
+ ```
237
+
238
+ ### EchoConsole Helper
239
+
240
+ Factory for creating Echo instances with console writer.
241
+
242
+ ```typescript
243
+ EchoConsole.new(config?: LogWriterConfig): Echo
244
+ ```
245
+
246
+ ## Differences from C# Version
247
+
248
+ The TypeScript port maintains the same API signatures as the C# version with these differences:
249
+
250
+ 1. **Case Convention**: TypeScript methods use camelCase (e.g., `getLogger()`) instead of PascalCase
251
+ 2. **Generic Overloads**: Instead of C# generic type parameters, TypeScript uses rest parameters (`...params: any[]`)
252
+ 3. **Events**: Instead of C# events, use `onUpdated(callback)` method to register callbacks
253
+ 4. **Properties**: C# properties become TypeScript getters/setters
254
+ 5. **No Unity**: This port excludes all Unity-specific features
255
+
256
+ ## Running the Demo
257
+
258
+ ```bash
259
+ # Compile
260
+ tsc echo.demo.ts
261
+
262
+ # Run
263
+ node echo.demo.js
264
+ ```
265
+
266
+ ## Running Tests
267
+
268
+ ```bash
269
+ # Compile and run tests
270
+ tsc && node echo.test.js
271
+ ```
272
+
273
+ ## License
274
+
275
+ Copyright © 2025 Racso
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Echo provider for Angular dependency injection.
3
+ * Provides a singleton Echo instance with console writer.
4
+ */
5
+ import { InjectionToken, Provider } from '@angular/core';
6
+ import { Echo, EchoConsole } from './echo';
7
+
8
+ /**
9
+ * Injection token for Echo logger instance
10
+ */
11
+ export const ECHO = new InjectionToken<Echo>('Echo Logger Instance');
12
+
13
+ /**
14
+ * Factory function to create Echo instance
15
+ */
16
+ export function echoFactory(): Echo {
17
+ return EchoConsole.new();
18
+ }
19
+
20
+ /**
21
+ * Provider for Echo logger
22
+ * Use this in your module providers or inject it in services
23
+ */
24
+ export const ECHO_PROVIDER: Provider = {
25
+ provide: ECHO,
26
+ useFactory: echoFactory
27
+ };