@plyaz/types 1.19.3 → 1.19.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/index.cjs +29 -0
- package/dist/api/index.cjs.map +1 -1
- package/dist/api/index.js +29 -0
- package/dist/api/index.js.map +1 -1
- package/dist/core/auth/types.d.ts +1 -1
- package/dist/core/domain/index.d.ts +5 -0
- package/dist/core/domain/types.d.ts +123 -0
- package/dist/core/events/enums.d.ts +25 -1
- package/dist/core/events/index.d.ts +3 -3
- package/dist/core/events/payloads.d.ts +80 -1
- package/dist/core/featureFlag/types.d.ts +37 -17
- package/dist/core/frontend/featureFlags.d.ts +106 -0
- package/dist/core/frontend/index.d.ts +6 -0
- package/dist/core/frontend/types.d.ts +318 -0
- package/dist/core/index.d.ts +6 -2
- package/dist/core/init/index.d.ts +5 -0
- package/dist/core/init/types.d.ts +347 -0
- package/dist/core/modules.d.ts +19 -3
- package/dist/core/services/index.d.ts +5 -0
- package/dist/core/{services.d.ts → services/types.d.ts} +74 -6
- package/dist/errors/codes.d.ts +3 -0
- package/dist/errors/index.cjs +29 -0
- package/dist/errors/index.cjs.map +1 -1
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.js +29 -0
- package/dist/errors/index.js.map +1 -1
- package/dist/errors/middleware.d.ts +105 -0
- package/dist/errors/store.d.ts +140 -0
- package/dist/examples/index.d.ts +1 -1
- package/dist/examples/types.d.ts +64 -0
- package/dist/features/feature-flag/dto.types.d.ts +67 -0
- package/dist/features/feature-flag/index.d.ts +3 -0
- package/dist/features/feature-flag/service.types.d.ts +184 -0
- package/dist/features/feature-flag/store.types.d.ts +166 -0
- package/dist/features/feature-flag/types.d.ts +16 -4
- package/dist/globals.d.ts +23 -0
- package/dist/index.cjs +49 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +49 -1
- package/dist/index.js.map +1 -1
- package/dist/store/index.cjs +13 -0
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.ts +2 -0
- package/dist/store/index.js +11 -0
- package/dist/store/index.js.map +1 -1
- package/dist/store/keys.d.ts +23 -0
- package/dist/store/types.d.ts +62 -71
- package/dist/testing/features/feature-flags/types.d.ts +3 -3
- package/package.json +6 -3
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Frontend Service Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for frontend domain services with store integration.
|
|
5
|
+
*/
|
|
6
|
+
import type { ReactNode } from 'react';
|
|
7
|
+
import type { StoreKey } from '../../store';
|
|
8
|
+
import type { CoreBaseDomainServiceInterface } from '../domain';
|
|
9
|
+
import type { CoreAppEnvironment, CoreAppContext } from '../modules';
|
|
10
|
+
import type { FeatureFlagValue, FeatureFlagContext } from '../../features';
|
|
11
|
+
import type { CoreBaseDomainServiceConfig } from '../domain';
|
|
12
|
+
import type { CoreBaseServiceConfig, CoreBaseMapperInstance, CoreBaseValidatorInstance } from '../domain';
|
|
13
|
+
import type { CoreDomainServiceInstance, CoreServiceEntry } from '../init';
|
|
14
|
+
/**
|
|
15
|
+
* Base store interface for frontend services.
|
|
16
|
+
* Stores must implement at least setData/setFlags.
|
|
17
|
+
* Loading and error setters are optional.
|
|
18
|
+
*/
|
|
19
|
+
export interface CoreBaseFrontendStore<TData = Record<string, unknown>> {
|
|
20
|
+
/** Set/replace all data in the store */
|
|
21
|
+
setData?(data: TData): void;
|
|
22
|
+
/** Update/merge data in the store (optional) */
|
|
23
|
+
updateData?(data: Partial<TData>): void;
|
|
24
|
+
/** Set loading state (optional) */
|
|
25
|
+
setLoading?(isLoading: boolean): void;
|
|
26
|
+
/** Set error state (optional) */
|
|
27
|
+
setError?(error: unknown): void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Configuration for frontend domain services
|
|
31
|
+
*/
|
|
32
|
+
export interface CoreBaseFrontendServiceConfig<TData = Record<string, unknown>, TStore extends CoreBaseFrontendStore<TData> = CoreBaseFrontendStore<TData>> extends CoreBaseDomainServiceConfig {
|
|
33
|
+
/** Single store to connect on initialization */
|
|
34
|
+
store?: TStore;
|
|
35
|
+
/** Multiple stores to connect on initialization */
|
|
36
|
+
stores?: TStore[];
|
|
37
|
+
/**
|
|
38
|
+
* Store keys this service should connect to.
|
|
39
|
+
* Must be a subset of the service's `allowedStoreKeys`.
|
|
40
|
+
* If not specified, no stores are connected (warning logged).
|
|
41
|
+
*/
|
|
42
|
+
storeKeys?: StoreKey[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Base interface for frontend domain services with store integration.
|
|
46
|
+
*
|
|
47
|
+
* Extends BaseDomainServiceInterface with store management capabilities.
|
|
48
|
+
* All frontend domain services implement this.
|
|
49
|
+
*
|
|
50
|
+
* @typeParam TStore - Store interface type
|
|
51
|
+
*/
|
|
52
|
+
export interface CoreBaseFrontendServiceInterface<TStore extends CoreBaseFrontendStore = CoreBaseFrontendStore> extends CoreBaseDomainServiceInterface {
|
|
53
|
+
/** Connect a store to receive updates */
|
|
54
|
+
connectStore(store: TStore): void;
|
|
55
|
+
/** Disconnect a store from receiving updates */
|
|
56
|
+
disconnectStore(store: TStore): void;
|
|
57
|
+
/** Disconnect all connected stores */
|
|
58
|
+
disconnectAllStores(): void;
|
|
59
|
+
/** Number of connected stores */
|
|
60
|
+
readonly connectedStoreCount: number;
|
|
61
|
+
/** Whether any stores are connected */
|
|
62
|
+
readonly hasConnectedStores: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* API configuration for the Plyaz provider
|
|
66
|
+
*/
|
|
67
|
+
export interface CorePlyazApiConfig {
|
|
68
|
+
/** API base URL (required) */
|
|
69
|
+
baseURL: string;
|
|
70
|
+
/** Environment (production, staging, development) */
|
|
71
|
+
env?: CoreAppEnvironment;
|
|
72
|
+
/** API key for authentication */
|
|
73
|
+
apiKey?: string;
|
|
74
|
+
/** Request timeout in ms */
|
|
75
|
+
timeout?: number;
|
|
76
|
+
/** Additional headers */
|
|
77
|
+
headers?: Record<string, string>;
|
|
78
|
+
/** Retry configuration */
|
|
79
|
+
retry?: {
|
|
80
|
+
attempts?: number;
|
|
81
|
+
delay?: number;
|
|
82
|
+
};
|
|
83
|
+
/** Enable encryption */
|
|
84
|
+
encryption?: {
|
|
85
|
+
enabled: boolean;
|
|
86
|
+
key?: string;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Frontend feature flag provider types
|
|
91
|
+
*
|
|
92
|
+
* Frontend-safe providers (no server-side dependencies):
|
|
93
|
+
* - 'memory': In-memory storage, resets on page refresh
|
|
94
|
+
* - 'api': Fetches flags from API endpoint
|
|
95
|
+
*/
|
|
96
|
+
export type FrontendFeatureFlagProvider = 'memory' | 'api';
|
|
97
|
+
/**
|
|
98
|
+
* Feature flag configuration for frontend
|
|
99
|
+
*/
|
|
100
|
+
export interface CorePlyazFeatureFlagConfig {
|
|
101
|
+
/**
|
|
102
|
+
* Provider type for feature flags
|
|
103
|
+
* - 'memory': Flags stored in memory (default)
|
|
104
|
+
* - 'api': Flags fetched from API endpoint
|
|
105
|
+
*/
|
|
106
|
+
provider?: FrontendFeatureFlagProvider;
|
|
107
|
+
/** Auto-refresh interval in ms (only for 'api' provider) */
|
|
108
|
+
refreshInterval?: number;
|
|
109
|
+
/** Default flag values */
|
|
110
|
+
defaults?: Record<string, boolean>;
|
|
111
|
+
/** API endpoint for flag fetching (default: '/feature-flags') */
|
|
112
|
+
apiEndpoint?: string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Store integration configuration
|
|
116
|
+
*/
|
|
117
|
+
export interface CorePlyazStoreConfig {
|
|
118
|
+
/**
|
|
119
|
+
* Whether to auto-initialize the feature flag store
|
|
120
|
+
* When true, creates a fetchFn that uses ServiceRegistry's featureFlags service
|
|
121
|
+
*/
|
|
122
|
+
autoInitFeatureFlags?: boolean;
|
|
123
|
+
/** Polling configuration for feature flags */
|
|
124
|
+
polling?: {
|
|
125
|
+
enabled?: boolean;
|
|
126
|
+
interval?: number;
|
|
127
|
+
};
|
|
128
|
+
/** Default feature flag values */
|
|
129
|
+
defaults?: Record<string, FeatureFlagValue>;
|
|
130
|
+
/** Callback when a flag value changes */
|
|
131
|
+
onFlagChange?: (key: string, prevValue: FeatureFlagValue | undefined, newValue: FeatureFlagValue) => void;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Full provider configuration
|
|
135
|
+
*/
|
|
136
|
+
export interface CorePlyazConfig {
|
|
137
|
+
/** API client configuration */
|
|
138
|
+
api: CorePlyazApiConfig;
|
|
139
|
+
/** Feature flag configuration */
|
|
140
|
+
featureFlags?: CorePlyazFeatureFlagConfig;
|
|
141
|
+
/**
|
|
142
|
+
* Domain services to auto-initialize via ServiceRegistry.
|
|
143
|
+
*/
|
|
144
|
+
services?: CoreServiceEntry[];
|
|
145
|
+
/**
|
|
146
|
+
* Store integration configuration.
|
|
147
|
+
*/
|
|
148
|
+
store?: CorePlyazStoreConfig;
|
|
149
|
+
/** App context (webapp, backoffice, mobile) */
|
|
150
|
+
appContext?: CoreAppContext;
|
|
151
|
+
/** Enable verbose logging */
|
|
152
|
+
verbose?: boolean;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Interface for services that can provide feature flags.
|
|
156
|
+
*/
|
|
157
|
+
export interface CoreFeatureFlagServiceLike extends CoreDomainServiceInstance {
|
|
158
|
+
evaluateAll(context?: FeatureFlagContext): Promise<Record<string, unknown>>;
|
|
159
|
+
isEnabled(key: string, context?: FeatureFlagContext): Promise<boolean>;
|
|
160
|
+
getValue<T = FeatureFlagValue>(key: string, context?: FeatureFlagContext): Promise<T>;
|
|
161
|
+
refresh(): Promise<void>;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Options for creating a feature flag fetcher.
|
|
165
|
+
*/
|
|
166
|
+
export interface CoreFeatureFlagFetcherOptions {
|
|
167
|
+
/** Service key in the registry (default: 'featureFlags') */
|
|
168
|
+
serviceKey?: string;
|
|
169
|
+
/** Default context for evaluations */
|
|
170
|
+
context?: FeatureFlagContext;
|
|
171
|
+
/** Transform the response before returning */
|
|
172
|
+
transform?: (flags: Record<string, unknown>) => Record<string, FeatureFlagValue>;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Configuration for feature flag store initialization.
|
|
176
|
+
*/
|
|
177
|
+
export interface CoreFeatureFlagStoreInitConfig {
|
|
178
|
+
/** Fetch function to get flags */
|
|
179
|
+
fetchFn: () => Promise<Record<string, FeatureFlagValue>>;
|
|
180
|
+
/** Default flag values */
|
|
181
|
+
defaults?: Record<string, FeatureFlagValue>;
|
|
182
|
+
/** Polling configuration */
|
|
183
|
+
polling?: {
|
|
184
|
+
enabled?: boolean;
|
|
185
|
+
interval?: number;
|
|
186
|
+
};
|
|
187
|
+
/** Callback when a flag value changes */
|
|
188
|
+
onFlagChange?: (key: string, prevValue: FeatureFlagValue | undefined, newValue: FeatureFlagValue) => void;
|
|
189
|
+
/** Callback when an error occurs */
|
|
190
|
+
onError?: (error: unknown) => void;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Base service config for frontend services (constructor config)
|
|
194
|
+
*/
|
|
195
|
+
export interface CoreBaseFrontendServiceConstructorConfig<TConfig extends CoreBaseFrontendServiceConfig<TData, TStore>, TStore extends CoreBaseFrontendStore<TData>, TData = Record<string, unknown>, TMapper extends CoreBaseMapperInstance = CoreBaseMapperInstance, TValidator extends CoreBaseValidatorInstance = CoreBaseValidatorInstance> extends CoreBaseServiceConfig<TConfig, TMapper, TValidator> {
|
|
196
|
+
/** Data key used for store sync (e.g., 'flags', 'items', 'data') */
|
|
197
|
+
storeDataKey?: string;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Props for initialization error component
|
|
201
|
+
*/
|
|
202
|
+
export interface CoreInitializationErrorProps {
|
|
203
|
+
/** The error that occurred */
|
|
204
|
+
error: Error;
|
|
205
|
+
/** Custom error component override */
|
|
206
|
+
errorComponent?: (error: Error) => ReactNode;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Props for initialization loading component
|
|
210
|
+
*/
|
|
211
|
+
export interface CoreInitializationLoadingProps {
|
|
212
|
+
/** Custom loading component override */
|
|
213
|
+
loading?: ReactNode;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Abstract API client interface for provider context.
|
|
217
|
+
* Implementations provide the concrete ApiClientService.
|
|
218
|
+
*/
|
|
219
|
+
export interface CoreApiClientLike {
|
|
220
|
+
/** Check if the client is initialized */
|
|
221
|
+
isInitialized(): boolean;
|
|
222
|
+
/** Get the underlying HTTP client */
|
|
223
|
+
getClient(): unknown;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Abstract event manager interface for provider context.
|
|
227
|
+
* Implementations provide the concrete CoreEventManager.
|
|
228
|
+
*/
|
|
229
|
+
export interface CoreEventManagerLike {
|
|
230
|
+
/** Subscribe to an event */
|
|
231
|
+
on(event: string, handler: (event: unknown) => void): () => void;
|
|
232
|
+
/** Emit an event */
|
|
233
|
+
emit(event: string, data?: unknown): void;
|
|
234
|
+
/** Unsubscribe from an event */
|
|
235
|
+
off(event: string, handler: (event: unknown) => void): void;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Abstract Core initializer interface for provider context.
|
|
239
|
+
* Implementations provide the concrete Core class.
|
|
240
|
+
*/
|
|
241
|
+
export interface CoreInitializerLike {
|
|
242
|
+
/** Check if Core is initialized */
|
|
243
|
+
readonly isInitialized: boolean;
|
|
244
|
+
/** Get current app context */
|
|
245
|
+
readonly appContext: CoreAppContext;
|
|
246
|
+
/** Reset Core state */
|
|
247
|
+
reset(): Promise<void>;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Services available through the Plyaz provider
|
|
251
|
+
*/
|
|
252
|
+
export interface CorePlyazServices {
|
|
253
|
+
/** Feature flags interface */
|
|
254
|
+
featureFlags: {
|
|
255
|
+
get: (key: string, defaultValue?: boolean) => boolean;
|
|
256
|
+
getAll: () => Record<string, boolean>;
|
|
257
|
+
refresh: () => Promise<void>;
|
|
258
|
+
};
|
|
259
|
+
/** App context */
|
|
260
|
+
appContext: CoreAppContext;
|
|
261
|
+
/** Current environment */
|
|
262
|
+
environment: CoreAppEnvironment;
|
|
263
|
+
/**
|
|
264
|
+
* Get a domain service by key.
|
|
265
|
+
* Services must be registered in the `services` config.
|
|
266
|
+
*/
|
|
267
|
+
getService: <T extends CoreDomainServiceInstance>(key: string) => T;
|
|
268
|
+
/**
|
|
269
|
+
* Get a domain service by key with async initialization if needed.
|
|
270
|
+
* Use this for lazy-initialized services.
|
|
271
|
+
*/
|
|
272
|
+
getServiceAsync: <T extends CoreDomainServiceInstance>(key: string) => Promise<T>;
|
|
273
|
+
/**
|
|
274
|
+
* Check if a service is registered
|
|
275
|
+
*/
|
|
276
|
+
hasService: (key: string) => boolean;
|
|
277
|
+
/**
|
|
278
|
+
* Get all initialized service keys
|
|
279
|
+
*/
|
|
280
|
+
getServiceKeys: () => string[];
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Context value provided to Plyaz consumers.
|
|
284
|
+
* Extends CorePlyazServices with implementation-specific service references.
|
|
285
|
+
*/
|
|
286
|
+
export interface CorePlyazContextValue extends CorePlyazServices {
|
|
287
|
+
/** API client for making HTTP requests (null until initialized) */
|
|
288
|
+
api: CoreApiClientLike | null;
|
|
289
|
+
/** Event manager for pub/sub */
|
|
290
|
+
events: CoreEventManagerLike;
|
|
291
|
+
/** Core initializer reference */
|
|
292
|
+
core: CoreInitializerLike;
|
|
293
|
+
/** Whether services are initialized and ready */
|
|
294
|
+
isReady: boolean;
|
|
295
|
+
/** Initialization error if any */
|
|
296
|
+
error: Error | null;
|
|
297
|
+
/** Re-initialize services */
|
|
298
|
+
reinitialize: () => Promise<void>;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Props for PlyazProvider component
|
|
302
|
+
*/
|
|
303
|
+
export interface CorePlyazProviderProps {
|
|
304
|
+
/** Child components */
|
|
305
|
+
children: ReactNode;
|
|
306
|
+
/** Configuration */
|
|
307
|
+
config: CorePlyazConfig;
|
|
308
|
+
/** Loading component to show while initializing */
|
|
309
|
+
loading?: ReactNode;
|
|
310
|
+
/** Error component to show on initialization failure */
|
|
311
|
+
error?: (error: Error) => ReactNode;
|
|
312
|
+
/** Callback when services are ready */
|
|
313
|
+
onReady?: (services: CorePlyazServices) => void;
|
|
314
|
+
/** Callback on initialization error */
|
|
315
|
+
onError?: (error: Error) => void;
|
|
316
|
+
/** Skip showing loading state (render children immediately) */
|
|
317
|
+
skipLoadingState?: boolean;
|
|
318
|
+
}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @module core
|
|
6
6
|
*/
|
|
7
|
-
export type {
|
|
7
|
+
export type { CoreApiEnvironmentConfig, CoreApiProviderProps } from './services';
|
|
8
8
|
export type { CoreIdempotencyStoreType, CoreInMemoryIdempotencyAdapterConfig, CoreRedisIdempotencyAdapterConfig, CoreIdempotencyStoreOptions, CoreIdempotencyStoreConfig, } from './idempotency';
|
|
9
|
-
export type { CoreServices, CoreRouteContext, CoreRouteHandler, CoreRouteDefinition, CoreModuleConfigSchema, CoreServiceFactory, CoreModuleLifecycle, CoreModuleDefinition, CoreRegisteredModule, CoreConfiguredModule, CoreModuleFactory, CoreFrameworkType, CoreServerConfig, CoreFrameworkAdapter, CoreAdapterFactory, CoreRuntimeEnvironment, CoreRuntimeContext, CoreNextJsHandlerContext, CoreNextJsHandlerResult, CoreNextJsHandler, CoreNextJsHandlerOptions, CoreEnvVars, CoreAppEnvironment, CoreApiInitOptions, CoreInitOptions, CoreServicesResult, CoreNestJsModuleOptions, CoreNestJsModuleAsyncOptions, CoreAppContext, CoreServiceRuntime, CoreDomainServiceConfig, } from './modules';
|
|
9
|
+
export type { CoreServices, CoreRouteContext, CoreRouteHandler, CoreRouteDefinition, CoreModuleConfigSchema, CoreServiceFactory, CoreModuleLifecycle, CoreModuleDefinition, CoreRegisteredModule, CoreConfiguredModule, CoreModuleFactory, CoreFrameworkType, CoreServerConfig, CoreFrameworkAdapter, CoreAdapterFactory, CoreRuntimeEnvironment, CoreRuntimeContext, CoreNextJsHandlerContext, CoreNextJsHandlerResult, CoreNextJsHandler, CoreNextJsHandlerOptions, CoreEnvVars, CoreAppEnvironment, CoreApiInitOptions, CoreInitOptions, CoreServicesResult, CoreNestJsModuleOptions, CoreNestJsModuleAsyncOptions, CoreNestJsCoreModuleAsyncOptions, CoreAppContext, CoreServiceRuntime, CoreDomainServiceConfig, } from './modules';
|
|
10
10
|
export { BACKEND_RUNTIMES, FRONTEND_RUNTIMES, UNIVERSAL_RUNTIMES, APP_CONTEXTS } from './modules';
|
|
11
11
|
export * from './tables/enum';
|
|
12
12
|
export type * from './auth/types';
|
|
@@ -15,3 +15,7 @@ export * from './featureFlag/enums';
|
|
|
15
15
|
export * from './featureFlag/constants';
|
|
16
16
|
export * from './events';
|
|
17
17
|
export type * from './types';
|
|
18
|
+
export type * from './domain';
|
|
19
|
+
export type * from './init';
|
|
20
|
+
export type * from './services';
|
|
21
|
+
export type * from './frontend';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Init Types
|
|
3
|
+
* Service registry and initialization type definitions
|
|
4
|
+
*/
|
|
5
|
+
export type { CoreDomainServiceInstance, CoreServiceInitConfig, CoreServiceCreateOptions, CoreInitializableDomainService, CoreServiceEntry, CoreServiceRegistryConfig, CoreExtractServiceConfig, CoreExtractServiceInstance, CoreFeatureFlagInitConfig, CoreErrorHandlerInitConfig, CoreInitOptionsBase, CoreServicesResultBase, } from './types';
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service Registry Types
|
|
3
|
+
*
|
|
4
|
+
* Defines interfaces for the frontend service registry pattern.
|
|
5
|
+
* Services must implement these interfaces to be auto-initialized.
|
|
6
|
+
*/
|
|
7
|
+
import type { ApiClientOptions } from '../../api';
|
|
8
|
+
import type { StoreKey } from '../../store';
|
|
9
|
+
import type { FeatureFlagValue, FeatureFlagPollingConfig } from '../../features';
|
|
10
|
+
import type { PackageErrorLike } from '../../errors';
|
|
11
|
+
import type { GlobalErrorHandlerConfig } from '../../errors/middleware';
|
|
12
|
+
import type { CoreAppEnvironment, CoreAppContext, CoreRuntimeEnvironment } from '../modules';
|
|
13
|
+
import type { CoreDbServiceConfig } from '../services';
|
|
14
|
+
/**
|
|
15
|
+
* Base interface that all domain service instances must implement.
|
|
16
|
+
* This allows the registry to manage services generically.
|
|
17
|
+
*/
|
|
18
|
+
export interface CoreDomainServiceInstance {
|
|
19
|
+
/** Unique service name/key */
|
|
20
|
+
readonly serviceName: string;
|
|
21
|
+
/** Whether the service is enabled */
|
|
22
|
+
readonly isServiceEnabled: boolean;
|
|
23
|
+
/** Whether the service is initialized and ready */
|
|
24
|
+
readonly isInitialized: boolean;
|
|
25
|
+
/** Check if service is available (configured and ready) */
|
|
26
|
+
isAvailable(): boolean;
|
|
27
|
+
/** Dispose/cleanup the service */
|
|
28
|
+
dispose(): void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Base configuration for service initialization
|
|
32
|
+
*/
|
|
33
|
+
export interface CoreServiceInitConfig {
|
|
34
|
+
/** Whether the service is enabled (default: true) */
|
|
35
|
+
enabled?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Store keys this service should connect to.
|
|
38
|
+
*
|
|
39
|
+
* Each frontend service can specify which stores it needs access to.
|
|
40
|
+
* The service's `allowedStoreKeys` static property defines valid options.
|
|
41
|
+
* If not specified, no stores will be connected (warning logged).
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* // Service that uses error and featureFlags stores
|
|
46
|
+
* { service: MyService, config: { storeKeys: ['error', 'featureFlags'] } }
|
|
47
|
+
*
|
|
48
|
+
* // Service that only uses error store
|
|
49
|
+
* { service: AnotherService, config: { storeKeys: ['error'] } }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
storeKeys?: StoreKey[];
|
|
53
|
+
/**
|
|
54
|
+
* When to initialize the service:
|
|
55
|
+
* - 'immediate': Initialize during Core.initialize() (default)
|
|
56
|
+
* - 'lazy': Initialize on first access
|
|
57
|
+
* - function: Initialize when function returns true
|
|
58
|
+
*/
|
|
59
|
+
initWhen?: 'immediate' | 'lazy' | (() => boolean | Promise<boolean>);
|
|
60
|
+
/**
|
|
61
|
+
* Whether to create a singleton instance (default: true).
|
|
62
|
+
*
|
|
63
|
+
* - `true`: One shared instance per service key (default)
|
|
64
|
+
* - `false`: Create a new instance each time `ServiceRegistry.create()` is called
|
|
65
|
+
*
|
|
66
|
+
* Singletons are stored in the registry and disposed on `disposeAll()`.
|
|
67
|
+
* Non-singletons must be managed by the caller.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* // Singleton (default) - same instance returned each time
|
|
72
|
+
* { service: MyService, config: { singleton: true } }
|
|
73
|
+
* const svc1 = ServiceRegistry.get('myService');
|
|
74
|
+
* const svc2 = ServiceRegistry.get('myService');
|
|
75
|
+
* svc1 === svc2; // true
|
|
76
|
+
*
|
|
77
|
+
* // Non-singleton - new instance each time via create()
|
|
78
|
+
* { service: MyService, config: { singleton: false } }
|
|
79
|
+
* const svc1 = await ServiceRegistry.create('myService');
|
|
80
|
+
* const svc2 = await ServiceRegistry.create('myService');
|
|
81
|
+
* svc1 === svc2; // false
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
singleton?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Create a dedicated API client instance for this service.
|
|
87
|
+
*
|
|
88
|
+
* By default, services share the global API client. Use this option when
|
|
89
|
+
* a service needs its own isolated API client (e.g., different base URL,
|
|
90
|
+
* separate rate limiting, different auth).
|
|
91
|
+
*
|
|
92
|
+
* - `false` or `undefined`: Use global shared API client (default)
|
|
93
|
+
* - `true`: Create dedicated instance using global config
|
|
94
|
+
* - `ApiClientOptions`: Create dedicated instance with custom config
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* // Use global shared client (default)
|
|
99
|
+
* { service: UserService, config: { enabled: true } }
|
|
100
|
+
*
|
|
101
|
+
* // Create dedicated client with global config
|
|
102
|
+
* { service: PaymentService, config: { dedicatedApiClient: true } }
|
|
103
|
+
*
|
|
104
|
+
* // Create dedicated client with custom config
|
|
105
|
+
* {
|
|
106
|
+
* service: ExternalApiService,
|
|
107
|
+
* config: {
|
|
108
|
+
* dedicatedApiClient: {
|
|
109
|
+
* baseURL: 'https://external-api.com',
|
|
110
|
+
* headers: { static: { 'X-API-Key': 'xxx' } },
|
|
111
|
+
* },
|
|
112
|
+
* },
|
|
113
|
+
* }
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
dedicatedApiClient?: boolean | ApiClientOptions;
|
|
117
|
+
/**
|
|
118
|
+
* Create a dedicated database instance for this service.
|
|
119
|
+
*
|
|
120
|
+
* By default, services share the global database connection. Use this when
|
|
121
|
+
* a service needs its own isolated DB connection (e.g., different database,
|
|
122
|
+
* separate connection pool, read replica).
|
|
123
|
+
*
|
|
124
|
+
* - `false` or `undefined`: Use global shared database (default)
|
|
125
|
+
* - `true`: Create dedicated instance using global config
|
|
126
|
+
* - `DbServiceConfig`: Create dedicated instance with custom config
|
|
127
|
+
*
|
|
128
|
+
* Note: This is typically only used in backend/Node.js contexts.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* // Use global shared database (default)
|
|
133
|
+
* { service: UserService, config: { enabled: true } }
|
|
134
|
+
*
|
|
135
|
+
* // Create dedicated DB with global config (e.g., separate connection pool)
|
|
136
|
+
* { service: ReportService, config: { dedicatedDb: true } }
|
|
137
|
+
*
|
|
138
|
+
* // Create dedicated DB with different connection
|
|
139
|
+
* {
|
|
140
|
+
* service: AnalyticsService,
|
|
141
|
+
* config: {
|
|
142
|
+
* dedicatedDb: {
|
|
143
|
+
* adapter: 'sql',
|
|
144
|
+
* sql: { connectionString: process.env.ANALYTICS_DB_URL },
|
|
145
|
+
* },
|
|
146
|
+
* },
|
|
147
|
+
* }
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
dedicatedDb?: boolean | Partial<CoreDbServiceConfig>;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Options passed to the service factory method
|
|
154
|
+
*/
|
|
155
|
+
export interface CoreServiceCreateOptions {
|
|
156
|
+
/**
|
|
157
|
+
* API client configuration and mode.
|
|
158
|
+
*/
|
|
159
|
+
apiClient?: {
|
|
160
|
+
/**
|
|
161
|
+
* Whether to use a dedicated (isolated) API client instance.
|
|
162
|
+
* - `false`: Use global shared instance (default)
|
|
163
|
+
* - `true`: Create dedicated instance
|
|
164
|
+
*/
|
|
165
|
+
dedicated: boolean;
|
|
166
|
+
/**
|
|
167
|
+
* API client options (merged global + per-service config).
|
|
168
|
+
* Used to create dedicated instance or configure global.
|
|
169
|
+
*/
|
|
170
|
+
options?: ApiClientOptions;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* Database configuration and mode.
|
|
174
|
+
*/
|
|
175
|
+
db?: {
|
|
176
|
+
/**
|
|
177
|
+
* Whether to use a dedicated (isolated) database instance.
|
|
178
|
+
* - `false`: Use global shared instance (default)
|
|
179
|
+
* - `true`: Create dedicated instance
|
|
180
|
+
*/
|
|
181
|
+
dedicated: boolean;
|
|
182
|
+
/**
|
|
183
|
+
* Database config (merged global + per-service config).
|
|
184
|
+
* Used to create dedicated instance or configure global.
|
|
185
|
+
*/
|
|
186
|
+
config?: Partial<CoreDbServiceConfig>;
|
|
187
|
+
};
|
|
188
|
+
/** Logger prefix */
|
|
189
|
+
loggerPrefix?: string;
|
|
190
|
+
/** Whether this is a singleton instance */
|
|
191
|
+
isSingleton?: boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Store keys this service should connect to.
|
|
194
|
+
* Passed from the service config to the create method.
|
|
195
|
+
*/
|
|
196
|
+
storeKeys?: StoreKey[];
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Static interface that service classes must implement.
|
|
200
|
+
* This enables the registry to call ServiceClass.create(config) generically.
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```typescript
|
|
204
|
+
* class MyDomainService extends BaseDomainService implements DomainServiceInstance {
|
|
205
|
+
* static readonly serviceKey = 'myService';
|
|
206
|
+
*
|
|
207
|
+
* static async create(
|
|
208
|
+
* config: MyServiceConfig,
|
|
209
|
+
* options?: ServiceCreateOptions
|
|
210
|
+
* ): Promise<MyDomainService> {
|
|
211
|
+
* const service = new MyDomainService(config);
|
|
212
|
+
* await service.initialize();
|
|
213
|
+
* return service;
|
|
214
|
+
* }
|
|
215
|
+
* }
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
export interface CoreInitializableDomainService<TConfig extends CoreServiceInitConfig = CoreServiceInitConfig, TInstance extends CoreDomainServiceInstance = CoreDomainServiceInstance> {
|
|
219
|
+
/** Unique key for this service (e.g., 'featureFlags', 'example') */
|
|
220
|
+
readonly serviceKey: string;
|
|
221
|
+
/**
|
|
222
|
+
* Factory method to create and initialize the service instance.
|
|
223
|
+
*
|
|
224
|
+
* @param config - Service-specific configuration
|
|
225
|
+
* @param options - Global options from the registry
|
|
226
|
+
* @returns Promise resolving to the initialized service instance
|
|
227
|
+
*/
|
|
228
|
+
create(config: TConfig, options?: CoreServiceCreateOptions): Promise<TInstance>;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Entry for a single service in the registry config.
|
|
232
|
+
* Pairs a service class with its configuration.
|
|
233
|
+
*/
|
|
234
|
+
export interface CoreServiceEntry<TConfig extends CoreServiceInitConfig = CoreServiceInitConfig, TInstance extends CoreDomainServiceInstance = CoreDomainServiceInstance> {
|
|
235
|
+
/** The service class (must have static create method) */
|
|
236
|
+
service: CoreInitializableDomainService<TConfig, TInstance>;
|
|
237
|
+
/** Configuration for this service */
|
|
238
|
+
config: TConfig;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Configuration for the service registry.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```typescript
|
|
245
|
+
* const registryConfig: ServiceRegistryConfig = {
|
|
246
|
+
* apiClient: { baseURL: '/api' },
|
|
247
|
+
* db: { adapter: 'sql', sql: { connectionString: '...' } },
|
|
248
|
+
* services: [
|
|
249
|
+
* { service: FeatureFlagDomainService, config: { enabled: true } },
|
|
250
|
+
* { service: ExampleDomainService, config: { enabled: true, useRealApi: false } },
|
|
251
|
+
* // Per-service override
|
|
252
|
+
* { service: PaymentService, config: {
|
|
253
|
+
* enabled: true,
|
|
254
|
+
* apiClient: { baseURL: 'https://payments.api.com' },
|
|
255
|
+
* }},
|
|
256
|
+
* ],
|
|
257
|
+
* };
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
export interface CoreServiceRegistryConfig {
|
|
261
|
+
/** Global API client options (shared by all services unless overridden) */
|
|
262
|
+
apiClient?: ApiClientOptions;
|
|
263
|
+
/** Global database config (shared by all services unless overridden) */
|
|
264
|
+
db?: Partial<CoreDbServiceConfig>;
|
|
265
|
+
/** Services to register and initialize */
|
|
266
|
+
services: CoreServiceEntry[];
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Extract the config type from a service class
|
|
270
|
+
*/
|
|
271
|
+
export type CoreExtractServiceConfig<T> = T extends CoreInitializableDomainService<infer C, CoreDomainServiceInstance> ? C : never;
|
|
272
|
+
/**
|
|
273
|
+
* Extract the instance type from a service class
|
|
274
|
+
*/
|
|
275
|
+
export type CoreExtractServiceInstance<T> = T extends CoreInitializableDomainService<CoreServiceInitConfig, infer I> ? I : never;
|
|
276
|
+
/**
|
|
277
|
+
* Feature flag initialization configuration
|
|
278
|
+
*/
|
|
279
|
+
export interface CoreFeatureFlagInitConfig {
|
|
280
|
+
/** Whether to enable feature flags (default: true) */
|
|
281
|
+
enabled?: boolean;
|
|
282
|
+
/** Default flag values */
|
|
283
|
+
defaults?: Record<string, FeatureFlagValue>;
|
|
284
|
+
/** Polling configuration */
|
|
285
|
+
polling?: FeatureFlagPollingConfig;
|
|
286
|
+
/** API endpoint for fetching flags (default: '/feature-flags') */
|
|
287
|
+
apiEndpoint?: string;
|
|
288
|
+
/** Callback when a flag value changes */
|
|
289
|
+
onFlagChange?: (key: string, prevValue: FeatureFlagValue | undefined, newValue: FeatureFlagValue) => void;
|
|
290
|
+
/** Callback when an error occurs */
|
|
291
|
+
onError?: (error: PackageErrorLike) => void;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Error handler initialization configuration
|
|
295
|
+
*/
|
|
296
|
+
export interface CoreErrorHandlerInitConfig extends Omit<GlobalErrorHandlerConfig, 'serialize'> {
|
|
297
|
+
/**
|
|
298
|
+
* Whether to enable auto-initialization of global error handler (default: true).
|
|
299
|
+
* Set to false to use your own error handling.
|
|
300
|
+
*/
|
|
301
|
+
enabled?: boolean;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Base core initialization options
|
|
305
|
+
* Extended by @plyaz/core's CoreInitOptions with specific types
|
|
306
|
+
*/
|
|
307
|
+
export interface CoreInitOptionsBase<TDb = unknown, TApi = unknown> {
|
|
308
|
+
/** Path to .env file (backend only) */
|
|
309
|
+
envPath?: string;
|
|
310
|
+
/** Global environment (production, staging, development) */
|
|
311
|
+
environment?: CoreAppEnvironment;
|
|
312
|
+
/** App context (webapp, backoffice, mobile) */
|
|
313
|
+
appContext?: CoreAppContext;
|
|
314
|
+
/** Direct env vars (merged with loaded) */
|
|
315
|
+
env?: Record<string, string | undefined>;
|
|
316
|
+
/** Database configuration */
|
|
317
|
+
db?: TDb;
|
|
318
|
+
/** API client configuration */
|
|
319
|
+
api?: TApi;
|
|
320
|
+
/** Skip database initialization */
|
|
321
|
+
skipDb?: boolean;
|
|
322
|
+
/** Skip API client initialization */
|
|
323
|
+
skipApi?: boolean;
|
|
324
|
+
/** Enable verbose logging */
|
|
325
|
+
verbose?: boolean;
|
|
326
|
+
/** Error handler configuration */
|
|
327
|
+
errorHandler?: CoreErrorHandlerInitConfig;
|
|
328
|
+
/** Feature flags configuration */
|
|
329
|
+
featureFlags?: CoreFeatureFlagInitConfig;
|
|
330
|
+
/** Domain services to auto-initialize */
|
|
331
|
+
services?: CoreServiceEntry[];
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Core services result from initialization
|
|
335
|
+
*/
|
|
336
|
+
export interface CoreServicesResultBase<TDb = unknown, TApi = unknown> {
|
|
337
|
+
/** Database service instance (null if skipped or on frontend) */
|
|
338
|
+
db: TDb | null;
|
|
339
|
+
/** API client service class */
|
|
340
|
+
api: TApi | null;
|
|
341
|
+
/** Loaded environment variables */
|
|
342
|
+
env: Record<string, string | undefined>;
|
|
343
|
+
/** Detected runtime environment */
|
|
344
|
+
runtime: CoreRuntimeEnvironment;
|
|
345
|
+
/** App context */
|
|
346
|
+
appContext: CoreAppContext;
|
|
347
|
+
}
|