@intrig/next 0.0.7 → 0.0.8

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.
@@ -0,0 +1,535 @@
1
+ import { ZodError } from 'zod';
2
+
3
+ /**
4
+ * State of an asynchronous call. Network state follows the state diagram given below.
5
+ *
6
+ *
7
+ * <pre>
8
+ * ┌──────┐
9
+ * ┌─────────────► Init ◄────────────┐
10
+ * │ └▲────┬┘ │
11
+ * │ │ │ │
12
+ * │ Reset Execute │
13
+ * Reset │ │ Reset
14
+ * │ ┌──┴────┴──┐ │
15
+ * │ ┌────► Pending ◄────┐ │
16
+ * │ │ └──┬────┬──┘ │ │
17
+ * │ Execute │ │ Execute │
18
+ * │ │ │ │ │ │
19
+ * │ │ OnSuccess OnError │ │
20
+ * │ ┌────┴──┐ │ │ ┌──┴───┐ │
21
+ * └─┤Success◄────┘ └────►Error ├─┘
22
+ * └───────┘ └──────┘
23
+ *
24
+ * </pre>
25
+ */
26
+ export interface NetworkState<T = unknown, E = unknown> {
27
+ state: 'init' | 'pending' | 'success' | 'error';
28
+ }
29
+
30
+ /**
31
+ * Network call is not yet started
32
+ */
33
+ export interface InitState<T, E = unknown> extends NetworkState<T, E> {
34
+ state: 'init';
35
+ }
36
+
37
+ /**
38
+ * Checks whether the state is init state
39
+ * @param state
40
+ */
41
+ export function isInit<T, E = unknown>(
42
+ state: NetworkState<T, E>,
43
+ ): state is InitState<T, E> {
44
+ return state.state === 'init';
45
+ }
46
+
47
+ /**
48
+ * Initializes a new state.
49
+ *
50
+ * @template T The type of the state.
51
+ * @return {InitState<T>} An object representing the initial state.
52
+ */
53
+ export function init<T, E = unknown>(): InitState<T, E> {
54
+ return {
55
+ state: 'init',
56
+ };
57
+ }
58
+
59
+ /**
60
+ * Network call is not yet completed
61
+ */
62
+ export interface PendingState<T, E = unknown> extends NetworkState<T, E> {
63
+ state: 'pending';
64
+ progress?: Progress;
65
+ }
66
+
67
+ /**
68
+ * Interface representing progress information for an upload or download operation.
69
+ *
70
+ * @typedef {object} Progress
71
+ *
72
+ * @property {'upload' | 'download'} type - The type of the operation.
73
+ *
74
+ * @property {number} loaded - The amount of data that has been loaded so far.
75
+ *
76
+ * @property {number} [total] - The total amount of data to be loaded (if known).
77
+ */
78
+ export interface Progress {
79
+ type?: 'upload' | 'download';
80
+ loaded: number;
81
+ total?: number;
82
+ }
83
+
84
+ /**
85
+ * Checks whether the state is pending state
86
+ * @param state
87
+ */
88
+ export function isPending<T, E = unknown>(
89
+ state: NetworkState<T, E>,
90
+ ): state is PendingState<T, E> {
91
+ return state.state === 'pending';
92
+ }
93
+
94
+ /**
95
+ * Generates a PendingState object with a state of "pending".
96
+ *
97
+ * @return {PendingState<T>} An object representing the pending state.
98
+ */
99
+ export function pending<T, E = unknown>(
100
+ progress: Progress | undefined = undefined,
101
+ ): PendingState<T, E> {
102
+ return {
103
+ state: 'pending',
104
+ progress,
105
+ };
106
+ }
107
+
108
+ /**
109
+ * Network call is completed with success state
110
+ */
111
+ export interface SuccessState<T, E = unknown> extends NetworkState<T, E> {
112
+ state: 'success';
113
+ data: T;
114
+ }
115
+
116
+ /**
117
+ * Checks whether the state is success response
118
+ * @param state
119
+ */
120
+ export function isSuccess<T, E = unknown>(
121
+ state: NetworkState<T, E>,
122
+ ): state is SuccessState<T, E> {
123
+ return state.state === 'success';
124
+ }
125
+
126
+ /**
127
+ * Creates a success state object with the provided data.
128
+ *
129
+ * @param {T} data - The data to be included in the success state.
130
+ * @return {SuccessState<T>} An object representing a success state containing the provided data.
131
+ */
132
+ export function success<T, E = unknown>(data: T): SuccessState<T, E> {
133
+ return {
134
+ state: 'success',
135
+ data,
136
+ };
137
+ }
138
+
139
+ /**
140
+ * Network call is completed with error response
141
+ */
142
+ export interface ErrorState<T, E = unknown> extends NetworkState<T, E> {
143
+ state: 'error';
144
+ error: E;
145
+ statusCode?: number;
146
+ request?: any;
147
+ }
148
+
149
+ /**
150
+ * Checks whether the state is error state
151
+ * @param state
152
+ */
153
+ export function isError<T, E = unknown>(
154
+ state: NetworkState<T, E>,
155
+ ): state is ErrorState<T, E> {
156
+ return state.state === 'error';
157
+ }
158
+
159
+ /**
160
+ * Constructs an ErrorState object representing an error.
161
+ *
162
+ * @param {any} error - The error object or message.
163
+ * @param {string} [statusCode] - An optional status code associated with the error.
164
+ * @return {ErrorState<T>} An object representing the error state.
165
+ */
166
+ export function error<T, E = unknown>(
167
+ error: E,
168
+ statusCode?: number,
169
+ request?: any,
170
+ ): ErrorState<T> {
171
+ return {
172
+ state: 'error',
173
+ error,
174
+ statusCode,
175
+ request,
176
+ };
177
+ }
178
+
179
+ /**
180
+ * Represents an error state with additional contextual information.
181
+ *
182
+ * @typedef {Object} ErrorWithContext
183
+ * @template T
184
+ * @extends ErrorState<T>
185
+ *
186
+ * @property {string} source - The origin of the error.
187
+ * @property {string} operation - The operation being performed when the error occurred.
188
+ * @property {string} key - A unique key identifying the specific error instance.
189
+ */
190
+ export interface ErrorWithContext<T = unknown, E = unknown>
191
+ extends ErrorState<T, E> {
192
+ source: string;
193
+ operation: string;
194
+ key: string;
195
+ }
196
+
197
+ /**
198
+ * Represents an action in the network context.
199
+ *
200
+ * @template T - The type of data associated with the network action
201
+ *
202
+ * @property {NetworkState<any>} state - The current state of the network action
203
+ * @property {string} key - The unique identifier for the network action
204
+ */
205
+ export interface NetworkAction<T, E> {
206
+ key: string;
207
+ source: string;
208
+ operation: string;
209
+ state: NetworkState<T, E>;
210
+ handled?: boolean;
211
+ }
212
+
213
+ type HookWithKey = {
214
+ key: string;
215
+ };
216
+
217
+ export type UnitHookOptions =
218
+ | { key?: string; fetchOnMount?: false; clearOnUnmount?: boolean }
219
+ | {
220
+ key?: string;
221
+ fetchOnMount: true;
222
+ params?: Record<string, any>;
223
+ clearOnUnmount?: boolean;
224
+ };
225
+ export type UnitHook<E = unknown> = ((
226
+ options: UnitHookOptions,
227
+ ) => [
228
+ NetworkState<never, E>,
229
+ (params?: Record<string, any>) => DispatchState<any>,
230
+ () => void,
231
+ ]) &
232
+ HookWithKey;
233
+ export type ConstantHook<T, E = unknown> = ((
234
+ options: UnitHookOptions,
235
+ ) => [
236
+ NetworkState<T, E>,
237
+ (params?: Record<string, any>) => DispatchState<any>,
238
+ () => void,
239
+ ]) &
240
+ HookWithKey;
241
+
242
+ export type UnaryHookOptions<P> =
243
+ | { key?: string; fetchOnMount?: false; clearOnUnmount?: boolean }
244
+ | { key?: string; fetchOnMount: true; params: P; clearOnUnmount?: boolean };
245
+ export type UnaryProduceHook<P, E = unknown> = ((
246
+ options?: UnaryHookOptions<P>,
247
+ ) => [NetworkState<never, E>, (params: P) => DispatchState<any>, () => void]) &
248
+ HookWithKey;
249
+ export type UnaryFunctionHook<P, T, E = unknown> = ((
250
+ options?: UnaryHookOptions<P>,
251
+ ) => [NetworkState<T, E>, (params: P) => DispatchState<any>, () => void]) &
252
+ HookWithKey;
253
+
254
+ export type BinaryHookOptions<P, B> =
255
+ | { key?: string; fetchOnMount?: false; clearOnUnmount?: boolean }
256
+ | {
257
+ key?: string;
258
+ fetchOnMount: true;
259
+ params: P;
260
+ body: B;
261
+ clearOnUnmount?: boolean;
262
+ };
263
+ export type BinaryProduceHook<P, B, E = unknown> = ((
264
+ options?: BinaryHookOptions<P, B>,
265
+ ) => [
266
+ NetworkState<never, E>,
267
+ (body: B, params: P) => DispatchState<any>,
268
+ () => void,
269
+ ]) &
270
+ HookWithKey;
271
+ export type BinaryFunctionHook<P, B, T, E = unknown> = ((
272
+ options?: BinaryHookOptions<P, B>,
273
+ ) => [
274
+ NetworkState<T, E>,
275
+ (body: B, params: P) => DispatchState<any>,
276
+ () => void,
277
+ ]) &
278
+ HookWithKey;
279
+
280
+ export type IntrigHookOptions<P = undefined, B = undefined> =
281
+ | UnitHookOptions
282
+ | UnaryHookOptions<P>
283
+ | BinaryHookOptions<P, B>;
284
+ export type IntrigHook<P = undefined, B = undefined, T = any, E = unknown> =
285
+ | UnitHook<E>
286
+ | ConstantHook<T, E>
287
+ | UnaryProduceHook<P, E>
288
+ | UnaryFunctionHook<P, T, E>
289
+ | BinaryProduceHook<P, B, E>
290
+ | BinaryFunctionHook<P, B, T, E>;
291
+
292
+ export interface AsyncRequestOptions {
293
+ hydrate?: boolean;
294
+ key?: string;
295
+ }
296
+
297
+ /**
298
+ * Represents the dispatch state of a process.
299
+ *
300
+ * @template T The type of the state information.
301
+ * @interface
302
+ *
303
+ * @property {string} state The current state of the dispatch process.
304
+ */
305
+ export interface DispatchState<T> {
306
+ state: string;
307
+ }
308
+
309
+ /**
310
+ * Represents a successful dispatch state.
311
+ *
312
+ * @template T - Type of the data associated with the dispatch.
313
+ *
314
+ * @extends DispatchState<T>
315
+ *
316
+ * @property {string} state - The state of the dispatch, always 'success'.
317
+ */
318
+ export interface SuccessfulDispatch<T> extends DispatchState<T> {
319
+ state: 'success';
320
+ }
321
+
322
+ /**
323
+ * Indicates a successful dispatch state.
324
+ *
325
+ * @return {DispatchState<T>} An object representing a successful state.
326
+ */
327
+ export function successfulDispatch<T>(): DispatchState<T> {
328
+ return {
329
+ state: 'success',
330
+ };
331
+ }
332
+
333
+ /**
334
+ * Determines if the provided dispatch state represents a successful dispatch.
335
+ *
336
+ * @param {DispatchState<T>} value - The dispatch state to check.
337
+ * @return {value is SuccessfulDispatch<T>} - True if the dispatch state indicates success, false otherwise.
338
+ */
339
+ export function isSuccessfulDispatch<T>(
340
+ value: DispatchState<T>,
341
+ ): value is SuccessfulDispatch<T> {
342
+ return value.state === 'success';
343
+ }
344
+
345
+ /**
346
+ * ValidationError interface represents a specific type of dispatch state
347
+ * where a validation error has occurred.
348
+ *
349
+ * @typeparam T - The type of the data associated with this dispatch state.
350
+ */
351
+ export interface ValidationError<T> extends DispatchState<T> {
352
+ state: 'validation-error';
353
+ error: any;
354
+ }
355
+
356
+ /**
357
+ * Generates a ValidationError object.
358
+ *
359
+ * @param error The error details that caused the validation to fail.
360
+ * @return The ValidationError object containing the error state and details.
361
+ */
362
+ export function validationError<T>(error: any): ValidationError<T> {
363
+ return {
364
+ state: 'validation-error',
365
+ error,
366
+ };
367
+ }
368
+
369
+ /**
370
+ * Determines if a provided DispatchState object is a ValidationError.
371
+ *
372
+ * @param {DispatchState<T>} value - The DispatchState object to evaluate.
373
+ * @return {boolean} - Returns true if the provided DispatchState object is a ValidationError, otherwise returns false.
374
+ */
375
+ export function isValidationError<T>(
376
+ value: DispatchState<T>,
377
+ ): value is ValidationError<T> {
378
+ return value.state === 'validation-error';
379
+ }
380
+
381
+ /**
382
+ * Represents an error structure with a specified type and associated data.
383
+ *
384
+ * @template T - The type of the data associated with the error.
385
+ * @template E - The type of the error detail.
386
+ *
387
+ * @property {string} type - A string representing the type of the error.
388
+ */
389
+ export interface IntrigError<T, E> {
390
+ type: string;
391
+ }
392
+
393
+ /**
394
+ * Represents an error encountered during a network operation.
395
+ * Extends from the `IntrigError` interface, adding network-specific properties.
396
+ *
397
+ * @template T - The type of the intrinsic data associated with the error.
398
+ * @template E - The type of the error details, defaulting to `unknown`.
399
+ *
400
+ * @property {string} type - A constant property representing the error type, always set to 'network'.
401
+ * @property {string} statusCode - A string representation of the HTTP status code associated with the error, indicating the nature of the network failure.
402
+ * @property {E} error - The detailed error information specific to the failure, type extends from the generic E, allowing flexibility in the error details.
403
+ * @property {any} request - The request object that was attempted when the network error occurred, providing context for what operation failed.
404
+ */
405
+ export interface NetworkError<T, E = unknown> extends IntrigError<T, E> {
406
+ type: 'network';
407
+ statusCode: string;
408
+ error: E;
409
+ request: any;
410
+ }
411
+
412
+ /**
413
+ * Constructs a network error object.
414
+ *
415
+ * @param error The error object corresponding to the network request.
416
+ * @param statusCode A string representing the HTTP status code returned.
417
+ * @param request The request object associated with the network operation.
418
+ * @return A NetworkError object containing the error type, status code, error details, and the original request.
419
+ */
420
+ export function networkError<T, E>(
421
+ error: E,
422
+ statusCode: string,
423
+ request: any,
424
+ ): NetworkError<T, E> {
425
+ return {
426
+ type: 'network',
427
+ statusCode,
428
+ error,
429
+ request,
430
+ };
431
+ }
432
+
433
+ /**
434
+ * Determines if the provided IntrigError is of type 'network'.
435
+ *
436
+ * @param {IntrigError<T, E>} value - The error value to check the type of.
437
+ * @return {boolean} - Returns true if the error is of type 'network', otherwise false.
438
+ */
439
+ export function isNetworkError<T, E>(
440
+ value: IntrigError<T, E>,
441
+ ): value is NetworkError<T, E> {
442
+ return value.type === 'network';
443
+ }
444
+
445
+ /**
446
+ * Interface representing a request validation error.
447
+ *
448
+ * This error occurs when a validation process on a request fails. It extends the IntrigError interface
449
+ * by adding specific properties related to request validation.
450
+ *
451
+ * @template T - The type of the data associated with the error.
452
+ * @template E - The optional type of additional error information. Defaults to unknown.
453
+ *
454
+ * @extends IntrigError<T, E>
455
+ *
456
+ * @property {string} type - A string literal indicating the error type as 'request-validation'.
457
+ * @property {ZodError} error - An instance of ZodError containing detailed validation error information.
458
+ */
459
+ export interface RequestValidationError<T, E = unknown>
460
+ extends IntrigError<T, E> {
461
+ type: 'request-validation';
462
+ error: ZodError;
463
+ }
464
+
465
+ /**
466
+ * Constructs a RequestValidationError object encapsulating the ZodError.
467
+ *
468
+ * @param {ZodError} error - The error object resulting from Zod schema validation.
469
+ * @return {RequestValidationError<T, E>} A RequestValidationError object containing the validation error information.
470
+ */
471
+ export function requestValidationError<T, E>(
472
+ error: ZodError,
473
+ ): RequestValidationError<T, E> {
474
+ return {
475
+ type: 'request-validation',
476
+ error,
477
+ };
478
+ }
479
+
480
+ /**
481
+ * Determines if a given error is of type RequestValidationError.
482
+ *
483
+ * @param value The error object to check, which implements the IntrigError interface.
484
+ * @return A boolean indicating whether the error is a RequestValidationError.
485
+ */
486
+ export function isRequestValidationError<T, E>(
487
+ value: IntrigError<T, E>,
488
+ ): value is RequestValidationError<T, E> {
489
+ return value.type === 'request-validation';
490
+ }
491
+
492
+ /**
493
+ * ResponseValidationError interface is designed to extend the capabilities of the IntrigError interface,
494
+ * specifically for handling errors related to response validation.
495
+ *
496
+ * @template T - Represents the type of the data or payload associated with the error.
497
+ * @template E - Represents the type of any additional error information. Defaults to unknown.
498
+ *
499
+ * @extends IntrigError
500
+ *
501
+ * @property type - A string literal that identifies the type of error as 'response-validation'.
502
+ * @property error - An instance of ZodError representing the validation error encountered.
503
+ */
504
+ export interface ResponseValidationError<T, E = unknown>
505
+ extends IntrigError<T, E> {
506
+ type: 'response-validation';
507
+ error: ZodError;
508
+ }
509
+
510
+ /**
511
+ * Constructs a ResponseValidationError object with a specified error.
512
+ *
513
+ * @param {ZodError} error - The validation error encountered during response validation.
514
+ * @return {ResponseValidationError<T, E>} An error object containing the type of error and the validation error details.
515
+ */
516
+ export function responseValidationError<T, E>(
517
+ error: ZodError,
518
+ ): ResponseValidationError<T, E> {
519
+ return {
520
+ type: 'response-validation',
521
+ error,
522
+ };
523
+ }
524
+
525
+ /**
526
+ * Determines if the given error is a response validation error.
527
+ *
528
+ * @param {IntrigError<T, E>} value - The error object to assess.
529
+ * @return {boolean} True if the error is a response validation error, otherwise false.
530
+ */
531
+ export function isResponseValidationError<T, E>(
532
+ value: IntrigError<T, E>,
533
+ ): value is ResponseValidationError<T, E> {
534
+ return value.type === 'response-validation';
535
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "files": [],
3
+ "include": [],
4
+ "references": [
5
+ {
6
+ "path": "./tsconfig.lib.json"
7
+ }
8
+ ],
9
+ "extends": "../../tsconfig.base.json"
10
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "types": [
6
+ "node",
7
+ "@nx/react/typings/cssmodule.d.ts",
8
+ "@nx/react/typings/image.d.ts",
9
+ "next",
10
+ "@nx/next/typings/image.d.ts"
11
+ ],
12
+ "rootDir": "src",
13
+ "jsx": "react-jsx",
14
+ "tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo",
15
+ "paths": {
16
+ "@intrig/next": ["./src"],
17
+ "@intrig/next/*": ["./src/*"]
18
+ }
19
+ },
20
+ "exclude": [
21
+ "out-tsc",
22
+ "dist",
23
+ "jest.config.ts",
24
+ "src/**/*.spec.ts",
25
+ "src/**/*.test.ts",
26
+ "src/**/*.spec.tsx",
27
+ "src/**/*.test.tsx",
28
+ "src/**/*.spec.js",
29
+ "src/**/*.test.js",
30
+ "src/**/*.spec.jsx",
31
+ "src/**/*.test.jsx"
32
+ ],
33
+ "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]
34
+ }