@plyaz/types 1.22.8 → 1.23.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.
@@ -2,6 +2,7 @@
2
2
  * CRUD Operation Types
3
3
  * Type definitions for CRUD operations in @plyaz/core domain services
4
4
  */
5
+ import type { TransactionOptions } from '../../db/Transaction';
5
6
  /**
6
7
  * Cache-specific options for CRUD operations
7
8
  */
@@ -15,6 +16,16 @@ export interface CrudCacheOptions {
15
16
  /** Custom cache key (will still be prefixed with cachePrefix) */
16
17
  customKey?: string;
17
18
  }
19
+ /**
20
+ * Transaction-specific options for CRUD operations
21
+ */
22
+ export interface CrudTransactionOptions extends TransactionOptions {
23
+ /**
24
+ * Enable transaction for bulk operations (default: false for backwards compatibility)
25
+ * When true, all operations in bulkCreate/bulkDelete will be atomic
26
+ */
27
+ useTransaction?: boolean;
28
+ }
18
29
  /**
19
30
  * Options for CRUD operations (create, getById, patch, delete, getAll)
20
31
  *
@@ -24,4 +35,6 @@ export interface CrudCacheOptions {
24
35
  export interface CrudOperationOptions {
25
36
  /** Cache-related options */
26
37
  cache?: CrudCacheOptions;
38
+ /** Transaction-related options (for bulk operations) */
39
+ transaction?: CrudTransactionOptions;
27
40
  }
@@ -3,4 +3,4 @@
3
3
  * Type definitions for @plyaz/core domain services
4
4
  */
5
5
  export type { CoreBaseDomainServiceInterface, CoreEventSubscribable, CoreProviderSubscribable, CoreValidationResult, CoreValidatorConfig, CoreBaseValidatorInstance, CoreBaseMapperInstance, CoreBaseDomainServiceConfig, CoreBaseBackendServiceConfig, CoreMapperClass, CoreValidatorClass, CoreBaseServiceConfig, CoreInjectedServices, } from './types';
6
- export type { CrudCacheOptions, CrudOperationOptions, } from './crud';
6
+ export type { CrudCacheOptions, CrudTransactionOptions, CrudOperationOptions, } from './crud';
@@ -106,14 +106,33 @@ export type CoreValidatorClass<T extends CoreBaseValidatorInstance = CoreBaseVal
106
106
  /**
107
107
  * Injected services/dependencies for domain services.
108
108
  * These are created/managed by ServiceRegistry and injected into services.
109
+ *
110
+ * @typeParam TCache - Cache manager type (defaults to unknown for flexibility)
111
+ * @typeParam TDb - Database service type (defaults to unknown for flexibility)
112
+ * @typeParam TApi - API client type (defaults to unknown for flexibility)
113
+ * @typeParam TStores - Store types map (defaults to unknown)
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * // With specific types
118
+ * interface MyInjectedServices extends CoreInjectedServices<
119
+ * CacheManager,
120
+ * DatabaseServiceInterface,
121
+ * ApiClient,
122
+ * { users: UserStoreSlice }
123
+ * > {}
124
+ *
125
+ * // With defaults (unknown types)
126
+ * interface BasicInjectedServices extends CoreInjectedServices {}
127
+ * ```
109
128
  */
110
- export interface CoreInjectedServices<TStores = unknown> {
129
+ export interface CoreInjectedServices<TCache = unknown, TDb = unknown, TApi = unknown, TStores = unknown> {
111
130
  /** Cache manager instance */
112
- cache?: unknown;
131
+ cache?: TCache;
113
132
  /** Database service instance */
114
- db?: unknown;
115
- /** API client instance */
116
- api?: unknown;
133
+ db?: TDb;
134
+ /** API client instance (supports multiple API clients via generics) */
135
+ api?: TApi;
117
136
  /**
118
137
  * Store instances (from root store) keyed by store key.
119
138
  * Type-safe: each key maps to its specific slice type.
@@ -161,3 +180,188 @@ export interface CoreBaseBackendServiceConfig extends CoreBaseDomainServiceConfi
161
180
  defaultTtl?: number;
162
181
  };
163
182
  }
183
+ /**
184
+ * Base interface for service type bundles.
185
+ * Define your concrete types by implementing this interface.
186
+ *
187
+ * This reduces the number of generic parameters from 13 to 5:
188
+ * - TConfig (service config)
189
+ * - TTypes (this bundle)
190
+ * - TRepository
191
+ * - TMapper
192
+ * - TValidator
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * // Define your service types bundle (no extends needed!)
197
+ * interface UserServiceTypes {
198
+ * Entity: User;
199
+ * ResponseDTO: UserResponseDTO;
200
+ * CreateDTO: CreateUserDTO;
201
+ * UpdateDTO: UpdateUserDTO;
202
+ * PatchDTO: PatchUserDTO;
203
+ * QueryDTO: QueryUserDTO;
204
+ * DeleteOptions: { soft: boolean };
205
+ * DatabaseRow: UserDatabaseRow;
206
+ * StoreState: UserStoreItem;
207
+ * }
208
+ *
209
+ * // Use in service (5 generics instead of 13!)
210
+ * class UserService extends BaseBackendDomainServiceV2<
211
+ * UserServiceConfig,
212
+ * UserServiceTypes,
213
+ * UserRepository,
214
+ * UserMapper,
215
+ * UserValidator
216
+ * > {}
217
+ * ```
218
+ */
219
+ export interface BackendServiceTypesShape {
220
+ /** Domain entity type */
221
+ Entity: unknown;
222
+ /** API response DTO type */
223
+ ResponseDTO: unknown;
224
+ /** Create input DTO type (POST body) - must be Record<string, unknown> */
225
+ CreateDTO: Record<string, unknown>;
226
+ /** Update input DTO type (PUT body) - must be Record<string, unknown> */
227
+ UpdateDTO: Record<string, unknown>;
228
+ /** Patch input DTO type (PATCH body) */
229
+ PatchDTO: Partial<Record<string, unknown>>;
230
+ /** Query params DTO type */
231
+ QueryDTO: Record<string, unknown>;
232
+ /** Delete options type */
233
+ DeleteOptions: unknown;
234
+ /** Database row type - must be Record<string, unknown> */
235
+ DatabaseRow: Record<string, unknown>;
236
+ /** Store state type (serializable) */
237
+ StoreState: unknown;
238
+ }
239
+ /**
240
+ * Frontend service types shape (without database-specific types)
241
+ */
242
+ export interface FrontendServiceTypesShape {
243
+ /** Domain entity type */
244
+ Entity: unknown;
245
+ /** API response DTO type */
246
+ ResponseDTO: unknown;
247
+ /** Create input DTO type */
248
+ CreateDTO: unknown;
249
+ /** Update input DTO type */
250
+ UpdateDTO: unknown;
251
+ /** Patch input DTO type */
252
+ PatchDTO: unknown;
253
+ /** Query params DTO type */
254
+ QueryDTO: unknown;
255
+ /** Store state type */
256
+ StoreState: unknown;
257
+ }
258
+ /**
259
+ * Helper to create a backend service types bundle with defaults.
260
+ * Use this when you want type inference with sensible defaults.
261
+ *
262
+ * @example
263
+ * ```typescript
264
+ * type UserTypes = DefineBackendServiceTypes<{
265
+ * Entity: User;
266
+ * ResponseDTO: UserResponseDTO;
267
+ * CreateDTO: CreateUserDTO;
268
+ * // UpdateDTO defaults to CreateDTO
269
+ * // PatchDTO defaults to Partial<CreateDTO>
270
+ * QueryDTO: QueryUserDTO;
271
+ * DatabaseRow: UserDatabaseRow;
272
+ * }>;
273
+ * ```
274
+ */
275
+ export type DefineBackendServiceTypes<T extends Partial<BackendServiceTypesShape> & {
276
+ Entity: unknown;
277
+ CreateDTO: Record<string, unknown>;
278
+ }> = {
279
+ Entity: T['Entity'];
280
+ ResponseDTO: T extends {
281
+ ResponseDTO: infer R;
282
+ } ? R : T['Entity'];
283
+ CreateDTO: T['CreateDTO'];
284
+ UpdateDTO: T extends {
285
+ UpdateDTO: infer U;
286
+ } ? U : T['CreateDTO'];
287
+ PatchDTO: T extends {
288
+ PatchDTO: infer P;
289
+ } ? P : Partial<T['CreateDTO']>;
290
+ QueryDTO: T extends {
291
+ QueryDTO: infer Q;
292
+ } ? Q : Record<string, unknown>;
293
+ DeleteOptions: T extends {
294
+ DeleteOptions: infer D;
295
+ } ? D : {
296
+ soft: boolean;
297
+ };
298
+ DatabaseRow: T extends {
299
+ DatabaseRow: infer DB;
300
+ } ? DB : T['CreateDTO'] & {
301
+ id: string;
302
+ };
303
+ StoreState: T extends {
304
+ StoreState: infer S;
305
+ } ? S : T['Entity'];
306
+ };
307
+ /**
308
+ * Helper to create a frontend service types bundle with defaults.
309
+ */
310
+ export type DefineFrontendServiceTypes<T extends Partial<FrontendServiceTypesShape> & {
311
+ Entity: unknown;
312
+ }> = {
313
+ Entity: T['Entity'];
314
+ ResponseDTO: T extends {
315
+ ResponseDTO: infer R;
316
+ } ? R : T['Entity'];
317
+ CreateDTO: T extends {
318
+ CreateDTO: infer C;
319
+ } ? C : Record<string, unknown>;
320
+ UpdateDTO: T extends {
321
+ UpdateDTO: infer U;
322
+ } ? U : T extends {
323
+ CreateDTO: infer C;
324
+ } ? C : Record<string, unknown>;
325
+ PatchDTO: T extends {
326
+ PatchDTO: infer P;
327
+ } ? P : Partial<T extends {
328
+ CreateDTO: infer C;
329
+ } ? C : Record<string, unknown>>;
330
+ QueryDTO: T extends {
331
+ QueryDTO: infer Q;
332
+ } ? Q : Record<string, unknown>;
333
+ StoreState: T extends {
334
+ StoreState: infer S;
335
+ } ? S : T['Entity'];
336
+ };
337
+ /**
338
+ * Type-safe extraction helpers for service type bundles.
339
+ * These work with any object that has the expected shape.
340
+ */
341
+ export type ExtractEntity<T extends {
342
+ Entity: unknown;
343
+ }> = T['Entity'];
344
+ export type ExtractResponseDTO<T extends {
345
+ ResponseDTO: unknown;
346
+ }> = T['ResponseDTO'];
347
+ export type ExtractCreateDTO<T extends {
348
+ CreateDTO: unknown;
349
+ }> = T['CreateDTO'];
350
+ export type ExtractUpdateDTO<T extends {
351
+ UpdateDTO: unknown;
352
+ }> = T['UpdateDTO'];
353
+ export type ExtractPatchDTO<T extends {
354
+ PatchDTO: unknown;
355
+ }> = T['PatchDTO'];
356
+ export type ExtractQueryDTO<T extends {
357
+ QueryDTO: unknown;
358
+ }> = T['QueryDTO'];
359
+ export type ExtractDeleteOptions<T extends {
360
+ DeleteOptions: unknown;
361
+ }> = T['DeleteOptions'];
362
+ export type ExtractDatabaseRow<T extends {
363
+ DatabaseRow: unknown;
364
+ }> = T['DatabaseRow'];
365
+ export type ExtractStoreState<T extends {
366
+ StoreState: unknown;
367
+ }> = T['StoreState'];
@@ -13,7 +13,7 @@
13
13
  * ```
14
14
  */
15
15
  import type { CORE_EVENTS } from './enums';
16
- import type { PackageErrorLike } from '../../errors';
16
+ import type { PackageErrorLike, SerializedError } from '../../errors';
17
17
  /**
18
18
  * Core event structure
19
19
  *
@@ -206,9 +206,12 @@ export interface CoreSystemShutdownPayload {
206
206
  * Payload for system:error events
207
207
  */
208
208
  export interface CoreSystemErrorPayload {
209
- error: unknown;
209
+ /** Array of serialized errors */
210
+ errors: SerializedError[];
211
+ /** Error context description */
210
212
  context?: string;
211
- recoverable: boolean;
213
+ /** Whether the error is recoverable */
214
+ recoverable?: boolean;
212
215
  }
213
216
  /**
214
217
  * Payload for system:warning events
@@ -2,5 +2,5 @@
2
2
  * Core Frontend Types
3
3
  * Type definitions for @plyaz/core frontend services
4
4
  */
5
- export type { CoreBaseFrontendStore, CoreBaseFrontendServiceConfig, CoreBaseFrontendServiceInterface, CoreStoreHandlers, CoreFetcherFunction, CoreServiceFetchers, CorePlyazApiConfig, FrontendFeatureFlagProvider, CorePlyazFeatureFlagConfig, CorePlyazStoreConfig, CorePlyazConfig, CoreFeatureFlagServiceLike, CoreFeatureFlagFetcherOptions, CoreFeatureFlagStoreInitConfig, CoreBaseFrontendServiceConstructorConfig, CoreInitializationErrorProps, CoreInitializationLoadingProps, CorePlyazServices, CorePlyazContextValue, CorePlyazProviderProps, } from './types';
5
+ export type { CoreBaseFrontendStore, CoreBaseFrontendServiceConfig, CoreBaseFrontendServiceInterface, CoreStoreHandlers, CoreOptimisticUpdateConfig, OptimisticConflictResolution, CoreFetcherFunction, CoreServiceFetchers, CorePlyazApiConfig, FrontendFeatureFlagProvider, CorePlyazFeatureFlagConfig, CorePlyazStoreConfig, CorePlyazConfig, CoreFeatureFlagServiceLike, CoreFeatureFlagFetcherOptions, CoreFeatureFlagStoreInitConfig, CoreBaseFrontendServiceConstructorConfig, CoreInitializationErrorProps, CoreInitializationLoadingProps, CorePlyazServices, CorePlyazContextValue, CorePlyazProviderProps, } from './types';
6
6
  export type { CoreFrontendFeatureFlagEventType, CoreFeatureFlagStore, CoreFeatureFlagServiceConfig, CoreFeatureFlagServiceInitConfig, CoreFeatureFlagServiceInterface, } from './featureFlags';
@@ -638,6 +638,68 @@ export interface CoreStoreHandlers<TData = Record<string, unknown>, TStore exten
638
638
  */
639
639
  removeData?: (store: TStore, id: string) => void;
640
640
  }
641
+ /**
642
+ * Conflict resolution strategy for optimistic updates
643
+ */
644
+ export type OptimisticConflictResolution = 'server-wins' | 'client-wins' | 'merge' | 'manual';
645
+ /**
646
+ * Optimistic update configuration
647
+ *
648
+ * When enabled, store updates happen immediately before API call completes.
649
+ * If the API call fails, changes are rolled back automatically.
650
+ *
651
+ * @example
652
+ * ```typescript
653
+ * optimisticUpdates: {
654
+ * enabled: true,
655
+ * rollbackOnError: true,
656
+ * conflictResolution: 'server-wins',
657
+ * }
658
+ * ```
659
+ */
660
+ export interface CoreOptimisticUpdateConfig {
661
+ /**
662
+ * Enable optimistic updates for CRUD operations.
663
+ * When true, store is updated before API response.
664
+ * @default false
665
+ */
666
+ enabled?: boolean;
667
+ /**
668
+ * Automatically rollback on API error.
669
+ * When true, reverts store to previous state if API fails.
670
+ * @default true
671
+ */
672
+ rollbackOnError?: boolean;
673
+ /**
674
+ * How to resolve conflicts when server response differs from optimistic state.
675
+ * - 'server-wins': Always use server response (default, safest)
676
+ * - 'client-wins': Keep client changes, ignore server differences
677
+ * - 'merge': Deep merge server and client data
678
+ * - 'manual': Call onConflict handler for resolution
679
+ * @default 'server-wins'
680
+ */
681
+ conflictResolution?: OptimisticConflictResolution;
682
+ /**
683
+ * Delay before applying optimistic update (ms).
684
+ * Useful for debouncing rapid updates.
685
+ * @default 0
686
+ */
687
+ debounceMs?: number;
688
+ /**
689
+ * Operations to enable optimistic updates for.
690
+ * @default ['create', 'update', 'delete']
691
+ */
692
+ operations?: ('create' | 'update' | 'delete')[];
693
+ /**
694
+ * Called when conflict detected (only when conflictResolution is 'manual').
695
+ * Return the resolved data to use.
696
+ */
697
+ onConflict?: <T>(optimistic: T, server: T) => T;
698
+ /**
699
+ * Called when rollback occurs due to error.
700
+ */
701
+ onRollback?: (operation: string, error: Error, previousState: unknown) => void;
702
+ }
641
703
  /**
642
704
  * Configuration for frontend domain services
643
705
  */
@@ -684,6 +746,24 @@ export interface CoreBaseFrontendServiceConfig<TData = Record<string, unknown>,
684
746
  * ```
685
747
  */
686
748
  storeHandlers?: CoreStoreHandlers<TData, TStore>;
749
+ /**
750
+ * Optimistic update configuration.
751
+ *
752
+ * When enabled, store updates happen immediately before API completes.
753
+ * If API fails, changes are automatically rolled back.
754
+ *
755
+ * @see {@link CoreOptimisticUpdateConfig} for options
756
+ *
757
+ * @example
758
+ * ```typescript
759
+ * optimisticUpdates: {
760
+ * enabled: true,
761
+ * rollbackOnError: true,
762
+ * conflictResolution: 'server-wins',
763
+ * }
764
+ * ```
765
+ */
766
+ optimisticUpdates?: CoreOptimisticUpdateConfig;
687
767
  }
688
768
  /**
689
769
  * Base interface for frontend domain services with store integration.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plyaz/types",
3
- "version": "1.22.8",
3
+ "version": "1.23.0",
4
4
  "author": "Redeemer Pace",
5
5
  "license": "ISC",
6
6
  "description": "Provides shared TypeScript types and schema utilities for validation and parsing in the @playz ecosystem.",