@sylphx/flow 1.7.0 → 1.8.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.
Files changed (131) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/assets/agents/coder.md +72 -119
  3. package/assets/agents/orchestrator.md +26 -90
  4. package/assets/agents/reviewer.md +76 -47
  5. package/assets/agents/writer.md +82 -63
  6. package/assets/output-styles/silent.md +141 -8
  7. package/assets/rules/code-standards.md +9 -33
  8. package/assets/rules/core.md +67 -59
  9. package/package.json +2 -12
  10. package/src/commands/flow/execute.ts +470 -0
  11. package/src/commands/flow/index.ts +11 -0
  12. package/src/commands/flow/prompt.ts +35 -0
  13. package/src/commands/flow/setup.ts +312 -0
  14. package/src/commands/flow/targets.ts +18 -0
  15. package/src/commands/flow/types.ts +47 -0
  16. package/src/commands/flow-command.ts +18 -967
  17. package/src/commands/flow-orchestrator.ts +14 -5
  18. package/src/commands/hook-command.ts +1 -1
  19. package/src/commands/init-core.ts +12 -3
  20. package/src/commands/run-command.ts +1 -1
  21. package/src/config/rules.ts +1 -1
  22. package/src/core/error-handling.ts +1 -1
  23. package/src/core/loop-controller.ts +1 -1
  24. package/src/core/state-detector.ts +1 -1
  25. package/src/core/target-manager.ts +1 -1
  26. package/src/index.ts +1 -1
  27. package/src/shared/files/index.ts +1 -1
  28. package/src/shared/processing/index.ts +1 -1
  29. package/src/targets/claude-code.ts +3 -3
  30. package/src/targets/opencode.ts +3 -3
  31. package/src/utils/agent-enhancer.ts +2 -2
  32. package/src/utils/{mcp-config.ts → config/mcp-config.ts} +4 -4
  33. package/src/utils/{paths.ts → config/paths.ts} +1 -1
  34. package/src/utils/{settings.ts → config/settings.ts} +1 -1
  35. package/src/utils/{target-config.ts → config/target-config.ts} +5 -5
  36. package/src/utils/{target-utils.ts → config/target-utils.ts} +3 -3
  37. package/src/utils/display/banner.ts +25 -0
  38. package/src/utils/display/status.ts +55 -0
  39. package/src/utils/{file-operations.ts → files/file-operations.ts} +2 -2
  40. package/src/utils/files/jsonc.ts +36 -0
  41. package/src/utils/{sync-utils.ts → files/sync-utils.ts} +3 -3
  42. package/src/utils/index.ts +42 -61
  43. package/src/utils/version.ts +47 -0
  44. package/src/components/benchmark-monitor.tsx +0 -331
  45. package/src/components/reindex-progress.tsx +0 -261
  46. package/src/composables/functional/index.ts +0 -14
  47. package/src/composables/functional/useEnvironment.ts +0 -171
  48. package/src/composables/functional/useFileSystem.ts +0 -139
  49. package/src/composables/index.ts +0 -4
  50. package/src/composables/useEnv.ts +0 -13
  51. package/src/composables/useRuntimeConfig.ts +0 -27
  52. package/src/core/ai-sdk.ts +0 -603
  53. package/src/core/app-factory.ts +0 -381
  54. package/src/core/builtin-agents.ts +0 -9
  55. package/src/core/command-system.ts +0 -550
  56. package/src/core/config-system.ts +0 -550
  57. package/src/core/connection-pool.ts +0 -390
  58. package/src/core/di-container.ts +0 -155
  59. package/src/core/headless-display.ts +0 -96
  60. package/src/core/interfaces/index.ts +0 -22
  61. package/src/core/interfaces/repository.interface.ts +0 -91
  62. package/src/core/interfaces/service.interface.ts +0 -133
  63. package/src/core/interfaces.ts +0 -96
  64. package/src/core/result.ts +0 -351
  65. package/src/core/service-config.ts +0 -252
  66. package/src/core/session-service.ts +0 -121
  67. package/src/core/storage-factory.ts +0 -115
  68. package/src/core/stream-handler.ts +0 -288
  69. package/src/core/type-utils.ts +0 -427
  70. package/src/core/unified-storage.ts +0 -456
  71. package/src/core/validation/limit.ts +0 -46
  72. package/src/core/validation/query.ts +0 -20
  73. package/src/db/auto-migrate.ts +0 -322
  74. package/src/db/base-database-client.ts +0 -144
  75. package/src/db/cache-db.ts +0 -218
  76. package/src/db/cache-schema.ts +0 -75
  77. package/src/db/database.ts +0 -70
  78. package/src/db/index.ts +0 -252
  79. package/src/db/memory-db.ts +0 -153
  80. package/src/db/memory-schema.ts +0 -29
  81. package/src/db/schema.ts +0 -289
  82. package/src/db/session-repository.ts +0 -733
  83. package/src/domains/index.ts +0 -6
  84. package/src/domains/utilities/index.ts +0 -6
  85. package/src/domains/utilities/time/index.ts +0 -5
  86. package/src/domains/utilities/time/tools.ts +0 -291
  87. package/src/services/agent-service.ts +0 -273
  88. package/src/services/evaluation-service.ts +0 -271
  89. package/src/services/functional/evaluation-logic.ts +0 -296
  90. package/src/services/functional/file-processor.ts +0 -273
  91. package/src/services/functional/index.ts +0 -12
  92. package/src/services/memory.service.ts +0 -476
  93. package/src/types/api/batch.ts +0 -108
  94. package/src/types/api/errors.ts +0 -118
  95. package/src/types/api/index.ts +0 -55
  96. package/src/types/api/requests.ts +0 -76
  97. package/src/types/api/responses.ts +0 -180
  98. package/src/types/api/websockets.ts +0 -85
  99. package/src/types/benchmark.ts +0 -49
  100. package/src/types/database.types.ts +0 -510
  101. package/src/types/memory-types.ts +0 -63
  102. package/src/utils/advanced-tokenizer.ts +0 -191
  103. package/src/utils/ai-model-fetcher.ts +0 -19
  104. package/src/utils/async-file-operations.ts +0 -516
  105. package/src/utils/audio-player.ts +0 -345
  106. package/src/utils/codebase-helpers.ts +0 -211
  107. package/src/utils/console-ui.ts +0 -79
  108. package/src/utils/database-errors.ts +0 -140
  109. package/src/utils/debug-logger.ts +0 -49
  110. package/src/utils/file-scanner.ts +0 -259
  111. package/src/utils/help.ts +0 -20
  112. package/src/utils/immutable-cache.ts +0 -106
  113. package/src/utils/jsonc.ts +0 -158
  114. package/src/utils/memory-tui.ts +0 -414
  115. package/src/utils/models-dev.ts +0 -91
  116. package/src/utils/parallel-operations.ts +0 -487
  117. package/src/utils/process-manager.ts +0 -155
  118. package/src/utils/prompts.ts +0 -120
  119. package/src/utils/search-tool-builder.ts +0 -214
  120. package/src/utils/session-manager.ts +0 -168
  121. package/src/utils/session-title.ts +0 -87
  122. package/src/utils/simplified-errors.ts +0 -410
  123. package/src/utils/template-engine.ts +0 -94
  124. package/src/utils/test-audio.ts +0 -71
  125. package/src/utils/todo-context.ts +0 -46
  126. package/src/utils/token-counter.ts +0 -288
  127. /package/src/utils/{cli-output.ts → display/cli-output.ts} +0 -0
  128. /package/src/utils/{logger.ts → display/logger.ts} +0 -0
  129. /package/src/utils/{notifications.ts → display/notifications.ts} +0 -0
  130. /package/src/utils/{secret-utils.ts → security/secret-utils.ts} +0 -0
  131. /package/src/utils/{security.ts → security/security.ts} +0 -0
@@ -1,91 +0,0 @@
1
- /**
2
- * Repository interface for dependency inversion
3
- * Abstracts data access implementation
4
- *
5
- * DESIGN RATIONALE:
6
- * - Depend on abstractions, not concrete implementations
7
- * - Enables testing with in-memory implementations
8
- * - Separates interface from implementation
9
- * - Clear contract for data access
10
- */
11
-
12
- import type { DatabaseError } from '../functional/error-types.js';
13
- import type { Result } from '../functional/result.js';
14
-
15
- /**
16
- * Query options for filtering, sorting, pagination
17
- */
18
- export interface QueryOptions {
19
- limit?: number;
20
- offset?: number;
21
- orderBy?: string;
22
- orderDirection?: 'ASC' | 'DESC';
23
- where?: Record<string, any>;
24
- }
25
-
26
- /**
27
- * Paginated result wrapper
28
- */
29
- export interface PaginatedResult<T> {
30
- items: T[];
31
- total: number;
32
- page: number;
33
- pageSize: number;
34
- hasNext: boolean;
35
- hasPrevious: boolean;
36
- }
37
-
38
- /**
39
- * Generic repository interface
40
- * All operations return Result for explicit error handling
41
- */
42
- export interface IRepository<T, ID = string | number> {
43
- /**
44
- * Find entity by ID
45
- */
46
- findById(id: ID): Promise<Result<T | null, DatabaseError>>;
47
-
48
- /**
49
- * Find multiple entities with filtering and sorting
50
- */
51
- findMany(options?: QueryOptions): Promise<Result<T[], DatabaseError>>;
52
-
53
- /**
54
- * Find entities with pagination
55
- */
56
- findPaginated(
57
- page: number,
58
- pageSize: number,
59
- options?: Omit<QueryOptions, 'limit' | 'offset'>
60
- ): Promise<Result<PaginatedResult<T>, DatabaseError>>;
61
-
62
- /**
63
- * Create a new entity
64
- */
65
- create(data: Partial<T>): Promise<Result<T, DatabaseError>>;
66
-
67
- /**
68
- * Update an existing entity
69
- */
70
- update(id: ID, data: Partial<T>): Promise<Result<T | null, DatabaseError>>;
71
-
72
- /**
73
- * Delete an entity
74
- */
75
- delete(id: ID): Promise<Result<boolean, DatabaseError>>;
76
-
77
- /**
78
- * Count entities matching criteria
79
- */
80
- count(options?: { where?: Record<string, any> }): Promise<Result<number, DatabaseError>>;
81
-
82
- /**
83
- * Check if entity exists
84
- */
85
- exists(id: ID): Promise<Result<boolean, DatabaseError>>;
86
- }
87
-
88
- /**
89
- * Factory function type for creating repositories
90
- */
91
- export type RepositoryFactory<T, ID = string | number> = (tableName: string) => IRepository<T, ID>;
@@ -1,133 +0,0 @@
1
- /**
2
- * Service interfaces for dependency inversion
3
- * Core service contracts
4
- *
5
- * DESIGN RATIONALE:
6
- * - Depend on abstractions, not implementations
7
- * - Clear contracts for services
8
- * - Enables dependency injection
9
- * - Facilitates testing with mocks
10
- */
11
-
12
- import type { AppError } from '../functional/error-types.js';
13
- import type { Result } from '../functional/result.js';
14
-
15
- /**
16
- * Logger interface
17
- */
18
- export interface ILogger {
19
- debug(message: string, ...args: any[]): void;
20
- info(message: string, ...args: any[]): void;
21
- warn(message: string, ...args: any[]): void;
22
- error(message: string, ...args: any[]): void;
23
- }
24
-
25
- /**
26
- * Configuration service interface
27
- */
28
- export interface IConfigService {
29
- /**
30
- * Get configuration value
31
- */
32
- get<T>(key: string): Result<T, AppError>;
33
-
34
- /**
35
- * Get configuration value with default
36
- */
37
- getOrDefault<T>(key: string, defaultValue: T): T;
38
-
39
- /**
40
- * Set configuration value
41
- */
42
- set<T>(key: string, value: T): Result<void, AppError>;
43
-
44
- /**
45
- * Check if configuration key exists
46
- */
47
- has(key: string): boolean;
48
-
49
- /**
50
- * Load configuration from file
51
- */
52
- load(path: string): Promise<Result<void, AppError>>;
53
-
54
- /**
55
- * Save configuration to file
56
- */
57
- save(path: string): Promise<Result<void, AppError>>;
58
- }
59
-
60
- /**
61
- * File service interface
62
- */
63
- export interface IFileService {
64
- /**
65
- * Read file contents
66
- */
67
- read(path: string): Promise<Result<string, AppError>>;
68
-
69
- /**
70
- * Write file contents
71
- */
72
- write(path: string, content: string): Promise<Result<void, AppError>>;
73
-
74
- /**
75
- * Check if file exists
76
- */
77
- exists(path: string): Promise<Result<boolean, AppError>>;
78
-
79
- /**
80
- * Delete file
81
- */
82
- delete(path: string): Promise<Result<void, AppError>>;
83
-
84
- /**
85
- * List files in directory
86
- */
87
- list(path: string): Promise<Result<string[], AppError>>;
88
-
89
- /**
90
- * Create directory
91
- */
92
- createDir(path: string, recursive?: boolean): Promise<Result<void, AppError>>;
93
- }
94
-
95
- /**
96
- * Validation service interface
97
- */
98
- export interface IValidationService<T> {
99
- /**
100
- * Validate data
101
- */
102
- validate(data: unknown): Result<T, AppError>;
103
-
104
- /**
105
- * Validate and return errors
106
- */
107
- validateWithErrors(data: unknown): Result<T, string[]>;
108
- }
109
-
110
- /**
111
- * Event emitter interface for event-driven architecture
112
- */
113
- export interface IEventEmitter<EventMap extends Record<string, any>> {
114
- /**
115
- * Emit an event
116
- */
117
- emit<K extends keyof EventMap>(event: K, data: EventMap[K]): void;
118
-
119
- /**
120
- * Subscribe to an event
121
- */
122
- on<K extends keyof EventMap>(event: K, handler: (data: EventMap[K]) => void): () => void;
123
-
124
- /**
125
- * Subscribe to an event once
126
- */
127
- once<K extends keyof EventMap>(event: K, handler: (data: EventMap[K]) => void): () => void;
128
-
129
- /**
130
- * Remove all listeners for an event
131
- */
132
- removeAllListeners<K extends keyof EventMap>(event: K): void;
133
- }
@@ -1,96 +0,0 @@
1
- /**
2
- * Core service interfaces for dependency injection
3
- */
4
-
5
- // Logger interface
6
- export interface ILogger {
7
- info(message: string, ...args: unknown[]): void;
8
- warn(message: string, ...args: unknown[]): void;
9
- error(message: string, error?: Error | unknown, ...args: unknown[]): void;
10
- debug(message: string, ...args: unknown[]): void;
11
- success(message: string, ...args: unknown[]): void;
12
- }
13
-
14
- // Configuration interface
15
- export interface IConfiguration {
16
- get<T = unknown>(key: string, defaultValue?: T): T;
17
- getRequired<T = unknown>(key: string): T;
18
- has(key: string): boolean;
19
- set(key: string, value: unknown): void;
20
- reload(): Promise<void>;
21
- }
22
-
23
- // Database connection interface
24
- export interface IDatabaseConnection {
25
- connect(): Promise<void>;
26
- disconnect(): Promise<void>;
27
- healthCheck(): Promise<{ healthy: boolean; error?: string }>;
28
- execute(sql: string, params?: unknown[]): Promise<DatabaseQueryResult>;
29
- }
30
-
31
- // Database query result
32
- export interface DatabaseQueryResult {
33
- rows: Record<string, unknown>[];
34
- rowCount: number;
35
- command: string;
36
- }
37
-
38
- // Storage interface for memory and cache
39
- export interface IStorage<T = unknown> {
40
- initialize(): Promise<void>;
41
- get(key: string, namespace?: string): Promise<T | null>;
42
- set(key: string, value: T, namespace?: string): Promise<void>;
43
- delete(key: string, namespace?: string): Promise<void>;
44
- clear(namespace?: string): Promise<void>;
45
- list(namespace?: string): Promise<string[]>;
46
- healthCheck(): Promise<{ healthy: boolean; error?: string }>;
47
- }
48
-
49
- // Target manager interface
50
- export interface ITargetManager {
51
- getTarget(id: string): Target | null;
52
- getAllTargets(): Target[];
53
- registerTarget(target: Target): void;
54
- }
55
-
56
- // Target definition
57
- export interface Target {
58
- id: string;
59
- name: string;
60
- type: string;
61
- config: Record<string, unknown>;
62
- enabled: boolean;
63
- }
64
-
65
- // Embedding provider interface
66
- export interface IEmbeddingProvider {
67
- name: string;
68
- embed(text: string): Promise<number[]>;
69
- isAvailable(): Promise<boolean>;
70
- }
71
-
72
- // MCP service interface
73
- export interface IMCPService {
74
- initialize(): Promise<void>;
75
- installServers(serverIds: string[], options?: MCPServerInstallOptions): Promise<void>;
76
- getAvailableServers(): MCPServerInfo[];
77
- getInstalledServers(): MCPServerInfo[];
78
- }
79
-
80
- // MCP server installation options
81
- export interface MCPServerInstallOptions {
82
- force?: boolean;
83
- autoStart?: boolean;
84
- config?: Record<string, unknown>;
85
- }
86
-
87
- // MCP server information
88
- export interface MCPServerInfo {
89
- id: string;
90
- name: string;
91
- version: string;
92
- description?: string;
93
- installed: boolean;
94
- enabled: boolean;
95
- config?: Record<string, unknown>;
96
- }
@@ -1,351 +0,0 @@
1
- /**
2
- * Unified Result Type - 統一結果類型
3
- * Single source of truth for Result<T, E> across the entire project
4
- *
5
- * This replaces all conflicting Result type definitions:
6
- * - src/core/type-utils.ts
7
- * - src/core/functional/result.ts
8
- * - src/utils/functional.ts
9
- */
10
-
11
- // ============================================================================
12
- // CORE RESULT TYPE
13
- // ============================================================================
14
-
15
- /**
16
- * Result type for functional error handling
17
- * Represents success or failure without exceptions
18
- */
19
- export type Result<T, E = Error> =
20
- | { success: true; data: T }
21
- | { success: false; error: E };
22
-
23
- // ============================================================================
24
- // CONSTRUCTORS
25
- // ============================================================================
26
-
27
- /**
28
- * Create a successful result
29
- */
30
- export const ok = <T>(data: T): Result<T> => ({ success: true, data });
31
-
32
- /**
33
- * Create an error result
34
- */
35
- export const err = <E>(error: E): Result<never, E> => ({ success: false, error });
36
-
37
- // ============================================================================
38
- // TYPE GUARDS
39
- // ============================================================================
40
-
41
- /**
42
- * Check if result is successful
43
- */
44
- export const isOk = <T, E>(result: Result<T, E>): result is { success: true; data: T } =>
45
- result.success;
46
-
47
- /**
48
- * Check if result is an error
49
- */
50
- export const isErr = <T, E>(result: Result<T, E>): result is { success: false; error: E } =>
51
- !result.success;
52
-
53
- // ============================================================================
54
- // TRANSFORMATIONS
55
- // ============================================================================
56
-
57
- /**
58
- * Transform the success value
59
- * Error propagates unchanged
60
- */
61
- export const map =
62
- <T, U, E>(fn: (data: T) => U) =>
63
- (result: Result<T, E>): Result<U, E> => {
64
- if (isOk(result)) {
65
- return ok(fn(result.data));
66
- }
67
- return result;
68
- };
69
-
70
- /**
71
- * Transform the success value with a function that returns a Result
72
- * Enables chaining operations that can fail
73
- * Error propagates unchanged
74
- */
75
- export const flatMap =
76
- <T, U, E>(fn: (data: T) => Result<U, E>) =>
77
- (result: Result<T, E>): Result<U, E> => {
78
- if (isOk(result)) {
79
- return fn(result.data);
80
- }
81
- return result;
82
- };
83
-
84
- /**
85
- * Transform the error
86
- * Success propagates unchanged
87
- */
88
- export const mapError =
89
- <T, E, F>(fn: (error: E) => F) =>
90
- (result: Result<T, E>): Result<T, F> => {
91
- if (isErr(result)) {
92
- return err(fn(result.error));
93
- }
94
- return result;
95
- };
96
-
97
- /**
98
- * Extract value or provide default
99
- */
100
- export const getOrElse =
101
- <T>(defaultValue: T) =>
102
- <E>(result: Result<T, E>): T => {
103
- if (isOk(result)) {
104
- return result.data;
105
- }
106
- return defaultValue;
107
- };
108
-
109
- /**
110
- * Extract value or compute default
111
- */
112
- export const getOrElseLazy =
113
- <T>(fn: () => T) =>
114
- <E>(result: Result<T, E>): T => {
115
- if (isOk(result)) {
116
- return result.data;
117
- }
118
- return fn();
119
- };
120
-
121
- /**
122
- * Pattern matching
123
- */
124
- export const match =
125
- <T, E, U>(onSuccess: (data: T) => U, onError: (error: E) => U) =>
126
- (result: Result<T, E>): U => {
127
- if (isOk(result)) {
128
- return onSuccess(result.data);
129
- }
130
- return onError(result.error);
131
- };
132
-
133
- /**
134
- * Extract value or throw error
135
- * Use only when you're certain the result is successful
136
- */
137
- export const unwrap = <T, E>(result: Result<T, E>): T => {
138
- if (isOk(result)) {
139
- return result.data;
140
- }
141
- throw result.error;
142
- };
143
-
144
- /**
145
- * Extract error or throw
146
- * Use only when you're certain the result is an error
147
- */
148
- export const unwrapError = <T, E>(result: Result<T, E>): E => {
149
- if (isErr(result)) {
150
- return result.error;
151
- }
152
- throw new Error('Expected error but got success');
153
- };
154
-
155
- // ============================================================================
156
- // ASYNC SUPPORT
157
- // ============================================================================
158
-
159
- /**
160
- * Async result type
161
- */
162
- export type AsyncResult<T, E = Error> = Promise<Result<T, E>>;
163
-
164
- /**
165
- * Convert thrown exception to Result
166
- */
167
- export const tryCatch = <T, E = Error>(
168
- fn: () => T,
169
- onError: (error: unknown) => E = (error: unknown) => error as E
170
- ): Result<T, E> => {
171
- try {
172
- return ok(fn());
173
- } catch (error) {
174
- return err(onError(error));
175
- }
176
- };
177
-
178
- /**
179
- * Convert Promise to Result
180
- */
181
- export const tryCatchAsync = async <T, E = Error>(
182
- fn: () => Promise<T>,
183
- onError: (error: unknown) => E = (error: unknown) => error as E
184
- ): Promise<Result<T, E>> => {
185
- try {
186
- const data = await fn();
187
- return ok(data);
188
- } catch (error) {
189
- return err(onError(error));
190
- }
191
- };
192
-
193
- /**
194
- * Safe async function wrapper
195
- */
196
- export const safeAsync = async <T, E = Error>(
197
- fn: () => Promise<T>,
198
- errorFn?: (error: unknown) => E
199
- ): Promise<Result<T, E>> => {
200
- return tryCatchAsync(fn, errorFn);
201
- };
202
-
203
- /**
204
- * Safe sync function wrapper
205
- */
206
- export const safeSync = <T, E = Error>(
207
- fn: () => T,
208
- errorFn?: (error: unknown) => E
209
- ): Result<T, E> => {
210
- return tryCatch(fn, errorFn);
211
- };
212
-
213
- // ============================================================================
214
- // COMBINATORS
215
- // ============================================================================
216
-
217
- /**
218
- * Combine multiple Results into a single Result containing an array
219
- * Fails if any Result is an error (short-circuits on first error)
220
- */
221
- export const all = <T, E>(results: Result<T, E>[]): Result<T[], E> => {
222
- const values: T[] = [];
223
-
224
- for (const result of results) {
225
- if (isErr(result)) {
226
- return result;
227
- }
228
- values.push(result.data);
229
- }
230
-
231
- return ok(values);
232
- };
233
-
234
- /**
235
- * Combine multiple Results into a single Result containing an array
236
- * Collects all errors instead of short-circuiting
237
- */
238
- export const allWithErrors = <T, E>(results: Result<T, E>[]): Result<T[], E[]> => {
239
- const values: T[] = [];
240
- const errors: E[] = [];
241
-
242
- for (const result of results) {
243
- if (isOk(result)) {
244
- values.push(result.data);
245
- } else {
246
- errors.push(result.error);
247
- }
248
- }
249
-
250
- return errors.length > 0 ? err(errors) : ok(values);
251
- };
252
-
253
- /**
254
- * Combine multiple AsyncResults
255
- */
256
- export const allAsync = async <T, E>(results: AsyncResult<T, E>[]): Promise<Result<T[], E>> => {
257
- const settled = await Promise.all(results);
258
- return all(settled);
259
- };
260
-
261
- /**
262
- * Race multiple AsyncResults - returns first successful result
263
- */
264
- export const raceAsync = async <T, E>(results: AsyncResult<T, E>[]): Promise<Result<T, E>> => {
265
- try {
266
- return await Promise.race(results);
267
- } catch (error) {
268
- return err(error as E);
269
- }
270
- };
271
-
272
- // ============================================================================
273
- // SIDE EFFECTS
274
- // ============================================================================
275
-
276
- /**
277
- * Run side effect for success case
278
- */
279
- export const tap =
280
- <T, E>(fn: (data: T) => void) =>
281
- (result: Result<T, E>): Result<T, E> => {
282
- if (isOk(result)) {
283
- fn(result.data);
284
- }
285
- return result;
286
- };
287
-
288
- /**
289
- * Run side effect for error case
290
- */
291
- export const tapError =
292
- <T, E>(fn: (error: E) => void) =>
293
- (result: Result<T, E>): Result<T, E> => {
294
- if (isErr(result)) {
295
- fn(result.error);
296
- }
297
- return result;
298
- };
299
-
300
- /**
301
- * Run side effect for both cases
302
- */
303
- export const tapBoth =
304
- <T, E>(onSuccess: (data: T) => void, onError: (error: E) => void) =>
305
- (result: Result<T, E>): Result<T, E> => {
306
- if (isOk(result)) {
307
- onSuccess(result.data);
308
- } else {
309
- onError(result.error);
310
- }
311
- return result;
312
- };
313
-
314
- // ============================================================================
315
- // LEGACY COMPATIBILITY
316
- // ============================================================================
317
-
318
- /**
319
- * Legacy compatibility aliases
320
- * These help migrate from old Result implementations
321
- */
322
-
323
- // For src/core/functional/result.ts users
324
- export const success = ok;
325
- export const failure = err;
326
- export const isSuccess = isOk;
327
- export const isFailure = isErr;
328
-
329
- // For src/utils/functional.ts users
330
- export const unwrapResult = unwrap;
331
- export const mapResult = map;
332
-
333
- // ============================================================================
334
- // TYPE INFERENCE HELPERS
335
- // ============================================================================
336
-
337
- /**
338
- * Helper to infer the success type from a Result
339
- */
340
- export type SuccessType<T> = T extends Result<infer U, any> ? U : never;
341
-
342
- /**
343
- * Helper to infer the error type from a Result
344
- */
345
- export type ErrorType<T> = T extends Result<any, infer E> ? E : never;
346
-
347
- /**
348
- * Create a type-safe Result from a function that might throw
349
- */
350
- export type SafeResult<T extends (...args: any[]) => any> =
351
- Result<ReturnType<T>, Error>;