@yogiswara/honcho-editor-ui 2.9.2 → 2.10.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.
- package/dist/hooks/demo/HonchoEditorBulkDemo.js +2 -1
- package/dist/hooks/editor/useHonchoEditorSingle.d.ts +4 -1
- package/dist/hooks/editor/useHonchoEditorSingle.js +21 -2
- package/dist/hooks/useAdjustmentHistory.d.ts +4 -1
- package/dist/hooks/useAdjustmentHistory.js +90 -10
- package/dist/hooks/useAdjustmentHistoryBatch.js +1 -1
- package/dist/hooks/useEditorHeadlessRaceFree.d.ts +15 -0
- package/dist/hooks/useEditorHeadlessRaceFree.js +88 -0
- package/dist/lib/editor/honcho-editor.d.ts +97 -119
- package/dist/lib/editor/honcho-editor.js +22 -17
- package/dist/lib/hooks/useEditor.d.ts +1 -1
- package/dist/lib/hooks/useEditor.js +1 -1
- package/dist/lib/hooks/useEditorHeadless.d.ts +1 -1
- package/dist/lib/hooks/useImageProcessor.d.ts +2 -2
- package/dist/lib/hooks/useImageProcessor.js +30 -42
- package/dist/services/base.d.ts +57 -0
- package/dist/services/base.js +243 -0
- package/dist/services/type.d.ts +197 -0
- package/dist/services/type.js +1 -0
- package/package.json +1 -1
|
@@ -23,20 +23,7 @@
|
|
|
23
23
|
* C++ handles all image processing algorithms.
|
|
24
24
|
*/
|
|
25
25
|
// Adjustment ranges for UI components
|
|
26
|
-
|
|
27
|
-
temperature: { min: -100, max: 100, default: 0, step: 1 },
|
|
28
|
-
tint: { min: -100, max: 100, default: 0, step: 1 },
|
|
29
|
-
saturation: { min: -100, max: 100, default: 0, step: 1 },
|
|
30
|
-
vibrance: { min: -100, max: 100, default: 0, step: 1 },
|
|
31
|
-
exposure: { min: -100, max: 100, default: 0, step: 1 },
|
|
32
|
-
contrast: { min: -100, max: 100, default: 0, step: 1 },
|
|
33
|
-
highlights: { min: -100, max: 100, default: 0, step: 1 },
|
|
34
|
-
shadows: { min: -100, max: 100, default: 0, step: 1 },
|
|
35
|
-
whites: { min: -100, max: 100, default: 0, step: 1 },
|
|
36
|
-
blacks: { min: -100, max: 100, default: 0, step: 1 },
|
|
37
|
-
clarity: { min: -100, max: 100, default: 0, step: 1 },
|
|
38
|
-
sharpness: { min: -100, max: 100, default: 0, step: 1 }
|
|
39
|
-
};
|
|
26
|
+
// Moved inside HonchoEditor class as static property
|
|
40
27
|
class HonchoEditor {
|
|
41
28
|
constructor() {
|
|
42
29
|
this.wasmModule = null;
|
|
@@ -554,6 +541,9 @@ class HonchoEditor {
|
|
|
554
541
|
}
|
|
555
542
|
console.log('✅ Frame applied successfully');
|
|
556
543
|
}
|
|
544
|
+
else {
|
|
545
|
+
this.clearFrame();
|
|
546
|
+
}
|
|
557
547
|
// Step 3: Apply all adjustments
|
|
558
548
|
console.log('🎛️ Applying adjustments:', adjustments);
|
|
559
549
|
const validAdjustments = [
|
|
@@ -718,7 +708,7 @@ class HonchoEditor {
|
|
|
718
708
|
* Validate adjustment value against range
|
|
719
709
|
*/
|
|
720
710
|
validateAdjustment(name, value) {
|
|
721
|
-
const range = ADJUSTMENT_RANGES[name];
|
|
711
|
+
const range = HonchoEditor.ADJUSTMENT_RANGES[name];
|
|
722
712
|
if (!range) {
|
|
723
713
|
throw new Error(`Unknown adjustment: ${name}`);
|
|
724
714
|
}
|
|
@@ -742,6 +732,21 @@ class HonchoEditor {
|
|
|
742
732
|
this.canvas = null;
|
|
743
733
|
}
|
|
744
734
|
}
|
|
735
|
+
// Static adjustment ranges for UI components
|
|
736
|
+
HonchoEditor.ADJUSTMENT_RANGES = {
|
|
737
|
+
temperature: { min: -100, max: 100, default: 0, step: 1 },
|
|
738
|
+
tint: { min: -100, max: 100, default: 0, step: 1 },
|
|
739
|
+
saturation: { min: -100, max: 100, default: 0, step: 1 },
|
|
740
|
+
vibrance: { min: -100, max: 100, default: 0, step: 1 },
|
|
741
|
+
exposure: { min: -100, max: 100, default: 0, step: 1 },
|
|
742
|
+
contrast: { min: -100, max: 100, default: 0, step: 1 },
|
|
743
|
+
highlights: { min: -100, max: 100, default: 0, step: 1 },
|
|
744
|
+
shadows: { min: -100, max: 100, default: 0, step: 1 },
|
|
745
|
+
whites: { min: -100, max: 100, default: 0, step: 1 },
|
|
746
|
+
blacks: { min: -100, max: 100, default: 0, step: 1 },
|
|
747
|
+
clarity: { min: -100, max: 100, default: 0, step: 1 },
|
|
748
|
+
sharpness: { min: -100, max: 100, default: 0, step: 1 }
|
|
749
|
+
};
|
|
745
750
|
// Export for convenience
|
|
746
751
|
// export default HonchoEditor; // Disabled for browser compatibility
|
|
747
752
|
// Helper functions for common operations
|
|
@@ -816,10 +821,10 @@ const HonchoEditorUtils = {
|
|
|
816
821
|
};
|
|
817
822
|
// Export for both Node.js and browser
|
|
818
823
|
if (typeof module !== 'undefined' && module.exports) {
|
|
819
|
-
module.exports = { HonchoEditor, HonchoEditorUtils
|
|
824
|
+
module.exports = { HonchoEditor, HonchoEditorUtils };
|
|
820
825
|
}
|
|
821
826
|
else {
|
|
822
827
|
window.HonchoEditor = HonchoEditor;
|
|
823
828
|
window.HonchoEditorUtils = HonchoEditorUtils;
|
|
824
|
-
window.ADJUSTMENT_RANGES = ADJUSTMENT_RANGES;
|
|
829
|
+
//window.ADJUSTMENT_RANGES = ADJUSTMENT_RANGES;
|
|
825
830
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useCallback } from 'react';
|
|
3
|
-
import { useEditorContext } from '
|
|
3
|
+
import { useEditorContext } from '../../lib/context/EditorContext';
|
|
4
4
|
/**
|
|
5
5
|
* Lightweight hook for components to request image processing
|
|
6
6
|
* Uses the global editor instance via context
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { AdjustmentValues } from '
|
|
1
|
+
import type { AdjustmentValues } from '../../lib/editor/honcho-editor';
|
|
2
2
|
interface UseImageProcessorProps {
|
|
3
3
|
photoId: string;
|
|
4
4
|
photoSrc: string;
|
|
5
5
|
enableEditor?: boolean;
|
|
6
6
|
adjustments?: Partial<AdjustmentValues>;
|
|
7
|
-
frame
|
|
7
|
+
frame: string | null;
|
|
8
8
|
priority?: 'high' | 'low';
|
|
9
9
|
abortSignal?: AbortSignal;
|
|
10
10
|
}
|
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import { useState, useEffect, useMemo, useRef } from 'react';
|
|
2
|
-
import { useEditorHighPriority, useEditorLowPriority } from '
|
|
2
|
+
import { useEditorHighPriority, useEditorLowPriority } from '../../lib/hooks/useEditor';
|
|
3
|
+
const initAdjustments = {
|
|
4
|
+
temperature: 0,
|
|
5
|
+
tint: 0,
|
|
6
|
+
saturation: 0,
|
|
7
|
+
vibrance: 0,
|
|
8
|
+
exposure: 0,
|
|
9
|
+
contrast: 0,
|
|
10
|
+
highlights: 0,
|
|
11
|
+
shadows: 0,
|
|
12
|
+
whites: 0,
|
|
13
|
+
blacks: 0,
|
|
14
|
+
clarity: 0,
|
|
15
|
+
sharpness: 0
|
|
16
|
+
};
|
|
3
17
|
export function useImageProcessor({ photoId, photoSrc, enableEditor = true, adjustments, frame, priority = 'low', abortSignal, }) {
|
|
4
18
|
const { processImage, isEditorReady } = priority === 'high'
|
|
5
19
|
? useEditorHighPriority()
|
|
@@ -21,78 +35,52 @@ export function useImageProcessor({ photoId, photoSrc, enableEditor = true, adju
|
|
|
21
35
|
};
|
|
22
36
|
// Memoize adjustments to prevent unnecessary effect triggers
|
|
23
37
|
const adjustmentsString = useMemo(() => adjustments ? JSON.stringify(adjustments) : '', [adjustments]);
|
|
24
|
-
const frameMemoized = useMemo(() => frame
|
|
38
|
+
const frameMemoized = useMemo(() => frame, [frame]);
|
|
39
|
+
if (!adjustments) {
|
|
40
|
+
adjustments = { ...initAdjustments };
|
|
41
|
+
}
|
|
25
42
|
// Process image when adjustments change
|
|
26
43
|
useEffect(() => {
|
|
27
|
-
|
|
28
|
-
if (abortControllerRef.current) {
|
|
29
|
-
abortControllerRef.current.abort();
|
|
30
|
-
}
|
|
31
|
-
if (!enableEditor || !isEditorReady || !adjustments) {
|
|
44
|
+
if (!enableEditor || !isEditorReady) {
|
|
32
45
|
console.debug("Skipping editor processing:", {
|
|
33
46
|
enableEditor,
|
|
34
47
|
isEditorReady,
|
|
35
|
-
hasAdjustments:
|
|
36
|
-
hasFrame: frameMemoized
|
|
37
|
-
photoId
|
|
48
|
+
hasAdjustments: adjustments,
|
|
49
|
+
hasFrame: frameMemoized
|
|
38
50
|
});
|
|
39
51
|
setProcessedImageSrc(photoSrc);
|
|
40
52
|
setIsProcessingComplete(true);
|
|
41
|
-
setIsProcessing(false);
|
|
42
53
|
return;
|
|
43
54
|
}
|
|
44
|
-
// Create new abort controller for this processing cycle
|
|
45
|
-
const controller = new AbortController();
|
|
46
|
-
abortControllerRef.current = controller;
|
|
47
55
|
// Reset processing state when starting new processing
|
|
48
56
|
setIsProcessingComplete(false);
|
|
49
|
-
|
|
57
|
+
let cancelled = false;
|
|
50
58
|
const processImageWithEditor = async () => {
|
|
51
59
|
try {
|
|
52
|
-
// Check if already aborted before starting
|
|
53
|
-
if (controller.signal.aborted || abortSignal?.aborted) {
|
|
54
|
-
console.debug(`[useImageProcessor] Aborted before processing started for image ${photoId}`);
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
console.debug(`[useImageProcessor] Starting processing for image ${photoId}`);
|
|
58
60
|
const result = await processImage({
|
|
59
61
|
id: photoId,
|
|
60
62
|
path: photoSrc,
|
|
61
63
|
frame: frameMemoized,
|
|
62
|
-
adjustments: adjustments
|
|
63
|
-
abortSignal: controller.signal // Pass the abort signal to the processing service
|
|
64
|
+
adjustments: adjustments
|
|
64
65
|
});
|
|
65
|
-
|
|
66
|
-
if (!controller.signal.aborted && !abortSignal?.aborted) {
|
|
67
|
-
console.debug(`[useImageProcessor] Completed processing for image ${photoId}`);
|
|
66
|
+
if (!cancelled) {
|
|
68
67
|
setProcessedImageSrc(result.path);
|
|
69
68
|
setIsProcessingComplete(true);
|
|
70
|
-
setIsProcessing(false);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
console.debug(`[useImageProcessor] Aborted after processing completed for image ${photoId}`);
|
|
74
69
|
}
|
|
75
70
|
}
|
|
76
71
|
catch (error) {
|
|
77
|
-
if (
|
|
78
|
-
console.debug(`[useImageProcessor] Processing cancelled for image ${photoId}`);
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
72
|
+
if (!cancelled) {
|
|
81
73
|
console.error({ error, photoKey: photoId, isEditorReady }, 'Failed to process image with editor');
|
|
74
|
+
// setProcessedImageSrc(photoSrc); // Fallback to original
|
|
75
|
+
// setIsProcessingComplete(true); // Show fallback image
|
|
82
76
|
}
|
|
83
|
-
setIsProcessing(false);
|
|
84
77
|
}
|
|
85
78
|
};
|
|
86
79
|
processImageWithEditor();
|
|
87
80
|
return () => {
|
|
88
|
-
|
|
89
|
-
controller.abort();
|
|
90
|
-
if (abortControllerRef.current === controller) {
|
|
91
|
-
abortControllerRef.current = null;
|
|
92
|
-
}
|
|
81
|
+
cancelled = true;
|
|
93
82
|
};
|
|
94
|
-
}, [photoSrc, adjustmentsString, frameMemoized, enableEditor, isEditorReady, processImage, photoId
|
|
95
|
-
// Listen to external abort signal
|
|
83
|
+
}, [photoSrc, adjustmentsString, frameMemoized, enableEditor, isEditorReady, processImage, photoId]);
|
|
96
84
|
useEffect(() => {
|
|
97
85
|
if (!abortSignal)
|
|
98
86
|
return;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";
|
|
2
|
+
import { Observable } from "rxjs/internal/Observable";
|
|
3
|
+
export declare const api: any;
|
|
4
|
+
export interface ResponseData<T> {
|
|
5
|
+
code?: number;
|
|
6
|
+
message?: string;
|
|
7
|
+
data?: T;
|
|
8
|
+
error_message?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class ResponseError extends Error {
|
|
11
|
+
code: number;
|
|
12
|
+
error_message: string;
|
|
13
|
+
isEmptyData: boolean;
|
|
14
|
+
constructor(code: number, error_message: string, originalError?: Error, isEmptyData?: boolean);
|
|
15
|
+
}
|
|
16
|
+
export declare class EmptyDataError extends Error {
|
|
17
|
+
constructor();
|
|
18
|
+
}
|
|
19
|
+
export declare function handleResponse<T>(res: AxiosResponse<ResponseData<T>>): T;
|
|
20
|
+
export declare function handleError(error: any): Observable<any>;
|
|
21
|
+
export declare function isResponseError(error: any): Boolean;
|
|
22
|
+
/**
|
|
23
|
+
* @deprecated use axiosGetObservable, axiosPostObservable, axiosPutObservable, axiosDeleteObservable instead
|
|
24
|
+
* @param promise
|
|
25
|
+
*/
|
|
26
|
+
export declare function fromAxiosToObservable<T>(promise: Promise<AxiosResponse<ResponseData<T>>>): Observable<T>;
|
|
27
|
+
export declare const apiV3: any;
|
|
28
|
+
export declare class BaseServices {
|
|
29
|
+
protected axios: AxiosInstance;
|
|
30
|
+
protected constructor(axios: AxiosInstance);
|
|
31
|
+
protected axiosGetObservable<T>(url: string, params?: AxiosRequestConfig<any> | undefined): Observable<T>;
|
|
32
|
+
protected axiosPostObservable<T>(url: string, data: any, params?: AxiosRequestConfig<any> | undefined): Observable<T>;
|
|
33
|
+
protected axiosPutObservable<T>(url: string, data: any, params?: AxiosRequestConfig<any> | undefined): Observable<T>;
|
|
34
|
+
protected axiosDeleteObservable<T>(url: string, params?: AxiosRequestConfig<any> | undefined): Observable<T>;
|
|
35
|
+
}
|
|
36
|
+
export interface Result<T> {
|
|
37
|
+
getStatus(): "loading" | "success" | "error" | "not-found" | "idle";
|
|
38
|
+
getData(): T;
|
|
39
|
+
getDataOrNull(): T | null | undefined;
|
|
40
|
+
getError(): any;
|
|
41
|
+
}
|
|
42
|
+
export declare class ResultImpl<T> implements Result<T> {
|
|
43
|
+
private readonly status;
|
|
44
|
+
private readonly data;
|
|
45
|
+
private readonly error;
|
|
46
|
+
getStatus(): "loading" | "success" | "error" | "not-found" | "idle";
|
|
47
|
+
getData(): T;
|
|
48
|
+
getError(): any;
|
|
49
|
+
getDataOrNull(): T | null | undefined;
|
|
50
|
+
private constructor();
|
|
51
|
+
static success<T>(data: T): Result<T>;
|
|
52
|
+
static loading<T>(): Result<T>;
|
|
53
|
+
static error<T>(err: any): Result<T>;
|
|
54
|
+
static notFound<T>(): Result<T>;
|
|
55
|
+
static idle<T>(): Result<T>;
|
|
56
|
+
}
|
|
57
|
+
export declare function fromPromise<T>(promise: Promise<T>): Observable<T>;
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import axiosRetry from 'axios-retry';
|
|
3
|
+
import { Observable } from "rxjs/internal/Observable";
|
|
4
|
+
import { catchError, from, map } from "rxjs";
|
|
5
|
+
const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:8080";
|
|
6
|
+
const apiConfig = (version) => {
|
|
7
|
+
return axios.create({
|
|
8
|
+
baseURL: `${BASE_URL}/${version}/`,
|
|
9
|
+
timeout: 60000 * 2,
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
export const api = axios.create({
|
|
13
|
+
baseURL: `${BASE_URL}`,
|
|
14
|
+
timeout: 60000 * 2,
|
|
15
|
+
});
|
|
16
|
+
axiosRetry(api, { retries: 3, retryDelay: axiosRetry.linearDelay() });
|
|
17
|
+
export class ResponseError extends Error {
|
|
18
|
+
constructor(code, error_message, originalError, isEmptyData = false) {
|
|
19
|
+
super(`${code}: ${error_message}`);
|
|
20
|
+
this.isEmptyData = false;
|
|
21
|
+
this.code = code;
|
|
22
|
+
this.error_message = error_message;
|
|
23
|
+
this.isEmptyData = isEmptyData;
|
|
24
|
+
if (originalError && originalError.stack) {
|
|
25
|
+
this.stack += `\nCaused by: ${originalError.stack}`;
|
|
26
|
+
}
|
|
27
|
+
// we need to set prototype to make this object can check by
|
|
28
|
+
// instanceof ResponseError
|
|
29
|
+
Object.setPrototypeOf(this, ResponseError.prototype);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export class EmptyDataError extends Error {
|
|
33
|
+
constructor() {
|
|
34
|
+
super("Data Empty, server not send any data in response");
|
|
35
|
+
// we need to set prototype to make this object can check by
|
|
36
|
+
// instanceof EmptyDataError
|
|
37
|
+
Object.setPrototypeOf(this, EmptyDataError.prototype);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// get data from response
|
|
41
|
+
export function handleResponse(res) {
|
|
42
|
+
if (!res.data.data) {
|
|
43
|
+
throw new EmptyDataError();
|
|
44
|
+
}
|
|
45
|
+
return res.data.data;
|
|
46
|
+
}
|
|
47
|
+
function mapError(error) {
|
|
48
|
+
if (error.isAxiosError) {
|
|
49
|
+
if (error.response) {
|
|
50
|
+
if (typeof error.response.data === "string") {
|
|
51
|
+
return {
|
|
52
|
+
code: error.response.status,
|
|
53
|
+
message: `${error.response.status}: ${error.response.statusText}`,
|
|
54
|
+
data: undefined,
|
|
55
|
+
error_message: error.response.data,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
return error.response?.data;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else if (error.request) {
|
|
63
|
+
return {
|
|
64
|
+
code: 400,
|
|
65
|
+
message: "`${error.name}: failed connect to server check your connection`",
|
|
66
|
+
data: undefined,
|
|
67
|
+
error_message: "failed connect to server",
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
return {
|
|
72
|
+
code: 400,
|
|
73
|
+
message: error.message,
|
|
74
|
+
data: undefined,
|
|
75
|
+
error_message: error.message,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
return {
|
|
81
|
+
code: 500,
|
|
82
|
+
message: String(error),
|
|
83
|
+
data: undefined,
|
|
84
|
+
error_message: String(error),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// handle error from response convert it and throw it as ResponseError
|
|
89
|
+
export function handleError(error) {
|
|
90
|
+
if (error instanceof EmptyDataError) {
|
|
91
|
+
// if data is empty just throw error
|
|
92
|
+
throw new ResponseError(204, "Data Empty, server not send any data in response", error, true);
|
|
93
|
+
}
|
|
94
|
+
let response = mapError(error);
|
|
95
|
+
throw new ResponseError(response.code || 500, response.error_message || "Unknown error", error);
|
|
96
|
+
}
|
|
97
|
+
export function isResponseError(error) {
|
|
98
|
+
return !!((error.code) && (error.error_message));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* @deprecated use axiosGetObservable, axiosPostObservable, axiosPutObservable, axiosDeleteObservable instead
|
|
102
|
+
* @param promise
|
|
103
|
+
*/
|
|
104
|
+
export function fromAxiosToObservable(promise) {
|
|
105
|
+
return from(promise).pipe(map(handleResponse), catchError(handleError));
|
|
106
|
+
}
|
|
107
|
+
export const apiV3 = apiConfig('v3');
|
|
108
|
+
export class BaseServices {
|
|
109
|
+
constructor(axios) {
|
|
110
|
+
this.axios = axios;
|
|
111
|
+
}
|
|
112
|
+
axiosGetObservable(url, params) {
|
|
113
|
+
return new Observable(subscriber => {
|
|
114
|
+
const controller = new AbortController();
|
|
115
|
+
const paramsData = { signal: controller.signal, ...params };
|
|
116
|
+
this.axios.get(url, paramsData)
|
|
117
|
+
.then(res => {
|
|
118
|
+
console.debug({ res, url, params }, "success GET request");
|
|
119
|
+
subscriber.next(res);
|
|
120
|
+
subscriber.complete();
|
|
121
|
+
})
|
|
122
|
+
.catch((error) => {
|
|
123
|
+
console.error({ error, url, params }, "Failed GET request");
|
|
124
|
+
subscriber.error(error);
|
|
125
|
+
});
|
|
126
|
+
return () => {
|
|
127
|
+
console.debug({ url, params, method: "GET" }, "Abort request");
|
|
128
|
+
controller.abort();
|
|
129
|
+
};
|
|
130
|
+
}).pipe(map(handleResponse), catchError(handleError));
|
|
131
|
+
}
|
|
132
|
+
axiosPostObservable(url, data, params) {
|
|
133
|
+
return new Observable(subscriber => {
|
|
134
|
+
const controller = new AbortController();
|
|
135
|
+
const paramsData = { signal: controller.signal, ...params };
|
|
136
|
+
this.axios.post(url, data, paramsData)
|
|
137
|
+
.then(res => {
|
|
138
|
+
console.debug({ res, url, params }, "success POST request");
|
|
139
|
+
subscriber.next(res);
|
|
140
|
+
subscriber.complete();
|
|
141
|
+
})
|
|
142
|
+
.catch((error) => {
|
|
143
|
+
console.error({ error, url, params }, "Failed POST request");
|
|
144
|
+
subscriber.error(error);
|
|
145
|
+
});
|
|
146
|
+
return () => {
|
|
147
|
+
console.debug({ url, params, method: "POST" }, "Abort request");
|
|
148
|
+
controller.abort();
|
|
149
|
+
};
|
|
150
|
+
}).pipe(map(handleResponse), catchError(handleError));
|
|
151
|
+
}
|
|
152
|
+
axiosPutObservable(url, data, params) {
|
|
153
|
+
return new Observable(subscriber => {
|
|
154
|
+
const controller = new AbortController();
|
|
155
|
+
const paramsData = { signal: controller.signal, ...params };
|
|
156
|
+
this.axios.put(url, data, paramsData)
|
|
157
|
+
.then(res => {
|
|
158
|
+
console.debug({ res, url, params }, "success PUT request");
|
|
159
|
+
subscriber.next(res);
|
|
160
|
+
subscriber.complete();
|
|
161
|
+
})
|
|
162
|
+
.catch((error) => {
|
|
163
|
+
console.error({ error, url, params }, "Failed PUT request");
|
|
164
|
+
subscriber.error(error);
|
|
165
|
+
});
|
|
166
|
+
return () => {
|
|
167
|
+
console.debug({ url, params, method: "PUT" }, "Abort request");
|
|
168
|
+
controller.abort();
|
|
169
|
+
};
|
|
170
|
+
}).pipe(map(handleResponse), catchError(handleError));
|
|
171
|
+
}
|
|
172
|
+
axiosDeleteObservable(url, params) {
|
|
173
|
+
return new Observable(subscriber => {
|
|
174
|
+
const controller = new AbortController();
|
|
175
|
+
const paramsData = { signal: controller.signal, ...params };
|
|
176
|
+
this.axios.delete(url, paramsData)
|
|
177
|
+
.then(res => {
|
|
178
|
+
console.debug({ res, url, params }, "success DELETE request");
|
|
179
|
+
subscriber.next(res);
|
|
180
|
+
subscriber.complete();
|
|
181
|
+
})
|
|
182
|
+
.catch((error) => {
|
|
183
|
+
console.error({ error, url, params }, "Failed DELETE request");
|
|
184
|
+
subscriber.error(error);
|
|
185
|
+
});
|
|
186
|
+
return () => {
|
|
187
|
+
console.debug({ url, params, method: "DELETE" }, "Abort request");
|
|
188
|
+
controller.abort();
|
|
189
|
+
};
|
|
190
|
+
}).pipe(map(handleResponse), catchError(handleError));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
export class ResultImpl {
|
|
194
|
+
getStatus() {
|
|
195
|
+
return this.status;
|
|
196
|
+
}
|
|
197
|
+
getData() {
|
|
198
|
+
if (this.data)
|
|
199
|
+
return this.data;
|
|
200
|
+
throw new Error("Data is not available");
|
|
201
|
+
}
|
|
202
|
+
getError() {
|
|
203
|
+
if (this.error)
|
|
204
|
+
return this.error;
|
|
205
|
+
throw new Error("Error is not available");
|
|
206
|
+
}
|
|
207
|
+
getDataOrNull() {
|
|
208
|
+
return this.data;
|
|
209
|
+
}
|
|
210
|
+
constructor(status, data, error) {
|
|
211
|
+
this.status = "idle";
|
|
212
|
+
this.status = status;
|
|
213
|
+
this.data = data;
|
|
214
|
+
this.error = error;
|
|
215
|
+
}
|
|
216
|
+
static success(data) {
|
|
217
|
+
return new ResultImpl("success", data, null);
|
|
218
|
+
}
|
|
219
|
+
static loading() {
|
|
220
|
+
return new ResultImpl("loading");
|
|
221
|
+
}
|
|
222
|
+
static error(err) {
|
|
223
|
+
return new ResultImpl("error", null, err);
|
|
224
|
+
}
|
|
225
|
+
static notFound() {
|
|
226
|
+
return new ResultImpl("not-found");
|
|
227
|
+
}
|
|
228
|
+
static idle() {
|
|
229
|
+
return new ResultImpl("idle");
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
export function fromPromise(promise) {
|
|
233
|
+
return new Observable(subscriber => {
|
|
234
|
+
promise.then(value => {
|
|
235
|
+
console.debug({ value }, "Promise success");
|
|
236
|
+
subscriber.next(value);
|
|
237
|
+
subscriber.complete();
|
|
238
|
+
}).catch(err => {
|
|
239
|
+
console.error({ err }, "Promise error");
|
|
240
|
+
subscriber.error(err);
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
}
|