@cloro-dev/response-parser 0.1.2 → 0.1.3
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/README.md +70 -39
- package/dist/core/types.d.ts +2 -5
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/base-provider.d.ts +4 -0
- package/dist/providers/base-provider.d.ts.map +1 -1
- package/dist/providers/perplexity.d.ts +3 -3
- package/dist/providers/perplexity.d.ts.map +1 -1
- package/dist/react/components/AiResponseRenderer.d.ts +2 -2
- package/dist/react/components/AiResponseRenderer.d.ts.map +1 -1
- package/dist/react/components/ResponseRenderer.d.ts +24 -0
- package/dist/react/components/ResponseRenderer.d.ts.map +1 -0
- package/dist/react/core/types.d.ts +2 -5
- package/dist/react/core/types.d.ts.map +1 -1
- package/dist/react/hooks/useAiResponse.d.ts.map +1 -1
- package/dist/react/hooks/useResponse.d.ts +19 -0
- package/dist/react/hooks/useResponse.d.ts.map +1 -0
- package/dist/react/index.d.ts +10 -13
- package/dist/react/index.esm.js +1 -1
- package/dist/react/index.esm.js.map +1 -1
- package/dist/react/index.js +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/providers/base-provider.d.ts +4 -0
- package/dist/react/providers/base-provider.d.ts.map +1 -1
- package/dist/react/providers/perplexity.d.ts +3 -3
- package/dist/react/providers/perplexity.d.ts.map +1 -1
- package/dist/react/react/components/AiResponseRenderer.d.ts +2 -2
- package/dist/react/react/components/AiResponseRenderer.d.ts.map +1 -1
- package/dist/react/react/components/ResponseRenderer.d.ts +24 -0
- package/dist/react/react/components/ResponseRenderer.d.ts.map +1 -0
- package/dist/react/react/hooks/useAiResponse.d.ts.map +1 -1
- package/dist/react/react/hooks/useResponse.d.ts +19 -0
- package/dist/react/react/hooks/useResponse.d.ts.map +1 -0
- package/dist/react/react/index.d.ts +6 -6
- package/dist/react/react/index.d.ts.map +1 -1
- package/package.json +10 -11
|
@@ -23,6 +23,10 @@ export declare abstract class BaseProvider {
|
|
|
23
23
|
* Check if content is a full HTML document
|
|
24
24
|
*/
|
|
25
25
|
isFullDocument(html: string): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Remove all links from HTML, keeping the text content
|
|
28
|
+
*/
|
|
29
|
+
removeLinks(html: string): string;
|
|
26
30
|
/**
|
|
27
31
|
* Wrap HTML fragment in a document
|
|
28
32
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-provider.d.ts","sourceRoot":"","sources":["../../src/providers/base-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE1G,8BAAsB,YAAY;IAChC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAExC;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,cAAc;IAErE;;OAEG;IACH,QAAQ,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,GAAG,iBAAiB;IAEzD;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM;
|
|
1
|
+
{"version":3,"file":"base-provider.d.ts","sourceRoot":"","sources":["../../src/providers/base-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE1G,8BAAsB,YAAY;IAChC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAExC;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,cAAc;IAErE;;OAEG;IACH,QAAQ,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,GAAG,iBAAiB;IAEzD;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM;IAiC1D;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAUlC;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIrC;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAKjC;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CA0BnC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { BaseProvider } from
|
|
2
|
-
import { AIProvider, ParsedResponse, ParseOptions, ContentExtraction } from
|
|
1
|
+
import { BaseProvider } from "./base-provider";
|
|
2
|
+
import { AIProvider, ParsedResponse, ParseOptions, ContentExtraction } from "../core/types";
|
|
3
3
|
export declare class PerplexityProvider extends BaseProvider {
|
|
4
4
|
readonly name: AIProvider;
|
|
5
5
|
readonly baseUrl = "https://www.perplexity.ai";
|
|
6
|
-
readonly defaultStyles = "\n html {\n filter: invert(1) hue-rotate(180deg);\n background-color: white !important;\n }\n
|
|
6
|
+
readonly defaultStyles = "\n html {\n filter: invert(1) hue-rotate(180deg);\n background-color: white !important;\n }\n ";
|
|
7
7
|
extractContent(response: any): ContentExtraction;
|
|
8
8
|
parse(response: any, options?: ParseOptions): ParsedResponse;
|
|
9
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"perplexity.d.ts","sourceRoot":"","sources":["../../src/providers/perplexity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,
|
|
1
|
+
{"version":3,"file":"perplexity.d.ts","sourceRoot":"","sources":["../../src/providers/perplexity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,UAAU,EACV,cAAc,EACd,YAAY,EACZ,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAEvB,qBAAa,kBAAmB,SAAQ,YAAY;IAClD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAgB;IACzC,QAAQ,CAAC,OAAO,+BAA+B;IAE/C,QAAQ,CAAC,aAAa,qHAKpB;IAEF,cAAc,CAAC,QAAQ,EAAE,GAAG,GAAG,iBAAiB;IAkChD,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,cAAc;CAuC7D"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { UseAiResponseOptions } from '../hooks/useAiResponse';
|
|
3
3
|
import { IframeRendererProps } from './IframeRenderer';
|
|
4
|
-
export interface
|
|
4
|
+
export interface ResponseRendererProps extends Omit<UseAiResponseOptions, 'onError'> {
|
|
5
5
|
response: any;
|
|
6
6
|
className?: string;
|
|
7
7
|
style?: React.CSSProperties;
|
|
@@ -18,7 +18,7 @@ export interface AiResponseRendererProps extends Omit<UseAiResponseOptions, 'onE
|
|
|
18
18
|
}>;
|
|
19
19
|
onRenderComplete?: (html: string) => void;
|
|
20
20
|
}
|
|
21
|
-
export declare const
|
|
21
|
+
export declare const ResponseRenderer: React.FC<ResponseRendererProps>;
|
|
22
22
|
export { IframeRenderer } from './IframeRenderer';
|
|
23
23
|
export { useAiResponse } from '../hooks/useAiResponse';
|
|
24
24
|
//# sourceMappingURL=AiResponseRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiResponseRenderer.d.ts","sourceRoot":"","sources":["../../../src/react/components/AiResponseRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAiB,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAkB,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvE,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"AiResponseRenderer.d.ts","sourceRoot":"","sources":["../../../src/react/components/AiResponseRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAiB,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAkB,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvE,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC;IAClF,QAAQ,EAAE,GAAG,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC3C,gBAAgB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC/D,cAAc,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAC;IACjF,iBAAiB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IACrE,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAgH5D,CAAC;AAMF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { UseResponseOptions } from '../hooks/useResponse';
|
|
3
|
+
import { IframeRendererProps } from './IframeRenderer';
|
|
4
|
+
export interface ResponseRendererProps extends Omit<UseResponseOptions, 'onError'> {
|
|
5
|
+
response: any;
|
|
6
|
+
className?: string;
|
|
7
|
+
style?: React.CSSProperties;
|
|
8
|
+
iframeProps?: Partial<IframeRendererProps>;
|
|
9
|
+
loadingComponent?: React.ComponentType<{
|
|
10
|
+
isLoading: boolean;
|
|
11
|
+
}>;
|
|
12
|
+
errorComponent?: React.ComponentType<{
|
|
13
|
+
error: Error | null;
|
|
14
|
+
retry: () => void;
|
|
15
|
+
}>;
|
|
16
|
+
fallbackComponent?: React.ComponentType<{
|
|
17
|
+
provider: string | null;
|
|
18
|
+
}>;
|
|
19
|
+
onRenderComplete?: (html: string) => void;
|
|
20
|
+
}
|
|
21
|
+
export declare const ResponseRenderer: React.FC<ResponseRendererProps>;
|
|
22
|
+
export { IframeRenderer } from './IframeRenderer';
|
|
23
|
+
export { useResponse } from '../hooks/useResponse';
|
|
24
|
+
//# sourceMappingURL=ResponseRenderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResponseRenderer.d.ts","sourceRoot":"","sources":["../../../src/react/components/ResponseRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAe,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAkB,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvE,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC;IAChF,QAAQ,EAAE,GAAG,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC3C,gBAAgB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC/D,cAAc,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAC;IACjF,iBAAiB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IACrE,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAgH5D,CAAC;AAMF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -7,10 +7,8 @@ export interface ParsedResponse {
|
|
|
7
7
|
metadata?: Record<string, any>;
|
|
8
8
|
}
|
|
9
9
|
export interface ParseOptions {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
sanitize?: boolean;
|
|
13
|
-
includeStyles?: boolean;
|
|
10
|
+
removeLinks?: boolean;
|
|
11
|
+
invertColors?: boolean;
|
|
14
12
|
}
|
|
15
13
|
export interface ProviderConfig {
|
|
16
14
|
name: AIProvider;
|
|
@@ -22,7 +20,6 @@ export interface DetectedProvider {
|
|
|
22
20
|
confidence: number;
|
|
23
21
|
}
|
|
24
22
|
export interface StyleOptions {
|
|
25
|
-
theme?: 'light' | 'dark';
|
|
26
23
|
customCSS?: string;
|
|
27
24
|
hideUI?: boolean;
|
|
28
25
|
baseUrl?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,QAAQ,GACR,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,QAAQ,CAAC;AAEb,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,UAAU,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,QAAQ,GACR,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,QAAQ,CAAC;AAEb,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,UAAU,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,UAAU,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;CACjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAiResponse.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useAiResponse.ts"],"names":[],"mappings":"AACA,OAAO,EAAmC,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAExG,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC3D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,KAAK,IAAI,CAAC;CAC5D;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,GAAG,EACb,OAAO,GAAE,oBAAyB,GACjC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"useAiResponse.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useAiResponse.ts"],"names":[],"mappings":"AACA,OAAO,EAAmC,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAExG,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC3D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,KAAK,IAAI,CAAC;CAC5D;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,GAAG,EACb,OAAO,GAAE,oBAAyB,GACjC,mBAAmB,CAkFrB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ParsedResponse, ParseOptions, AIProvider } from '../../index';
|
|
2
|
+
export interface UseResponseOptions extends ParseOptions {
|
|
3
|
+
autoDetect?: boolean;
|
|
4
|
+
provider?: AIProvider;
|
|
5
|
+
onProviderDetected?: (provider: AIProvider | null) => void;
|
|
6
|
+
onError?: (error: Error) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface UseResponseReturn {
|
|
9
|
+
parsed: ParsedResponse | null;
|
|
10
|
+
provider: AIProvider | null;
|
|
11
|
+
isLoading: boolean;
|
|
12
|
+
error: Error | null;
|
|
13
|
+
html: string | null;
|
|
14
|
+
text: string | null;
|
|
15
|
+
sources: any[] | null;
|
|
16
|
+
reparse: (options?: Partial<UseResponseOptions>) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare function useResponse(response: any, options?: UseResponseOptions): UseResponseReturn;
|
|
19
|
+
//# sourceMappingURL=useResponse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useResponse.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/useResponse.ts"],"names":[],"mappings":"AACA,OAAO,EAAmC,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAExG,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC3D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAC;CAC1D;AAED,wBAAgB,WAAW,CACzB,QAAQ,EAAE,GAAG,EACb,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CA0EnB"}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -9,10 +9,8 @@ interface ParsedResponse {
|
|
|
9
9
|
metadata?: Record<string, any>;
|
|
10
10
|
}
|
|
11
11
|
interface ParseOptions {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
sanitize?: boolean;
|
|
15
|
-
includeStyles?: boolean;
|
|
12
|
+
removeLinks?: boolean;
|
|
13
|
+
invertColors?: boolean;
|
|
16
14
|
}
|
|
17
15
|
interface ProviderConfig {
|
|
18
16
|
name: AIProvider;
|
|
@@ -24,7 +22,6 @@ interface DetectedProvider {
|
|
|
24
22
|
confidence: number;
|
|
25
23
|
}
|
|
26
24
|
interface StyleOptions {
|
|
27
|
-
theme?: 'light' | 'dark';
|
|
28
25
|
customCSS?: string;
|
|
29
26
|
hideUI?: boolean;
|
|
30
27
|
baseUrl?: string;
|
|
@@ -35,13 +32,13 @@ type ContentExtraction = {
|
|
|
35
32
|
sources?: any[];
|
|
36
33
|
};
|
|
37
34
|
|
|
38
|
-
interface
|
|
35
|
+
interface UseResponseOptions extends ParseOptions {
|
|
39
36
|
autoDetect?: boolean;
|
|
40
37
|
provider?: AIProvider;
|
|
41
38
|
onProviderDetected?: (provider: AIProvider | null) => void;
|
|
42
39
|
onError?: (error: Error) => void;
|
|
43
40
|
}
|
|
44
|
-
interface
|
|
41
|
+
interface UseResponseReturn {
|
|
45
42
|
parsed: ParsedResponse | null;
|
|
46
43
|
provider: AIProvider | null;
|
|
47
44
|
isLoading: boolean;
|
|
@@ -49,9 +46,9 @@ interface UseAiResponseReturn {
|
|
|
49
46
|
html: string | null;
|
|
50
47
|
text: string | null;
|
|
51
48
|
sources: any[] | null;
|
|
52
|
-
reparse: (options?: Partial<
|
|
49
|
+
reparse: (options?: Partial<UseResponseOptions>) => void;
|
|
53
50
|
}
|
|
54
|
-
declare function
|
|
51
|
+
declare function useResponse(response: any, options?: UseResponseOptions): UseResponseReturn;
|
|
55
52
|
|
|
56
53
|
interface IframeRendererProps {
|
|
57
54
|
html: string;
|
|
@@ -64,7 +61,7 @@ interface IframeRendererProps {
|
|
|
64
61
|
}
|
|
65
62
|
declare const IframeRenderer: React.ForwardRefExoticComponent<IframeRendererProps & React.RefAttributes<HTMLIFrameElement>>;
|
|
66
63
|
|
|
67
|
-
interface
|
|
64
|
+
interface ResponseRendererProps extends Omit<UseResponseOptions, 'onError'> {
|
|
68
65
|
response: any;
|
|
69
66
|
className?: string;
|
|
70
67
|
style?: React.CSSProperties;
|
|
@@ -81,7 +78,7 @@ interface AiResponseRendererProps extends Omit<UseAiResponseOptions, 'onError'>
|
|
|
81
78
|
}>;
|
|
82
79
|
onRenderComplete?: (html: string) => void;
|
|
83
80
|
}
|
|
84
|
-
declare const
|
|
81
|
+
declare const ResponseRenderer: React.FC<ResponseRendererProps>;
|
|
85
82
|
|
|
86
|
-
export {
|
|
87
|
-
export type { AIProvider,
|
|
83
|
+
export { IframeRenderer, ResponseRenderer, useResponse };
|
|
84
|
+
export type { AIProvider, ContentExtraction, DetectedProvider, IframeRendererProps, ParseOptions, ParsedResponse, ProviderConfig, ResponseRendererProps, StyleOptions, UseResponseOptions, UseResponseReturn };
|
package/dist/react/index.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as t,jsxs as e}from"react/jsx-runtime";import n,{useState as r,useMemo as o,useEffect as i,forwardRef as s}from"react";class a{static detect(t){const e={CHATGPT:0,GEMINI:0,PERPLEXITY:0,COPILOT:0,AIOVERVIEW:0,AIMODE:0};for(const[n,r]of Object.entries(this.PROVIDER_PATTERNS))for(const o of r)try{o(t)&&e[n]++}catch(t){}let n=0,r=null;for(const[t,o]of Object.entries(e))o>n&&(n=o,r=t);return 0===n?null:{provider:r,confidence:n/Object.values(e).reduce((t,e)=>Math.max(t,e),1)}}static getAllProviders(t){const e=[];for(const[n,r]of Object.entries(this.PROVIDER_PATTERNS)){let o=0;for(const e of r)try{e(t)&&o++}catch(t){}o>0&&e.push({provider:n,confidence:o/r.length})}return e.sort((t,e)=>e.confidence-t.confidence)}static validate(t,e){const n=this.detect(t);return(null==n?void 0:n.provider)===e&&n.confidence>.5}}a.PROVIDER_PATTERNS={CHATGPT:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("bg-token-bg-primary")||n.includes("text-token-text-secondary")},t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("chatgpt.com")||n.includes("openai.com")}],GEMINI:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("bard-sidenav")||n.includes("mat-sidenav")},t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("gemini.google.com")||n.includes("gem-sys-color")}],PERPLEXITY:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("perplexity.ai")||n.includes("prose")}],COPILOT:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("copilot.microsoft.com")||n.includes('data-testid="sidebar-container"')}],AIOVERVIEW:[t=>{var e,n,r,o;if(null===(n=null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.aioverview)||void 0===n?void 0:n.text)return!0;if(null===(r=null==t?void 0:t.aioverview)||void 0===r?void 0:r.text)return!0;const i=(null===(o=null==t?void 0:t.result)||void 0===o?void 0:o.html)||(null==t?void 0:t.html)||"";return i.includes("WIZ_global_data")||i.includes("DnVkpd")}],AIMODE:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("DZ13He")||n.includes("wYq63b")||n.includes("AI Mode")}]};class l{injectStyles(t,e){let n=t;(null==e?void 0:e.baseUrl)&&!t.includes("<base ")&&(n=n.includes("<head>")?n.replace("<head>",`<head><base href="${e.baseUrl}">`):n.replace(/(<html[^>]*>)/i,`$1<head><base href="${e.baseUrl}"></head>`));const r=(null==e?void 0:e.customCSS)?this.defaultStyles+"\n"+e.customCSS:this.defaultStyles;return n=n.includes("<head>")?n.replace("<head>",`<head><style>${r}</style>`):n.replace(/(<html[^>]*>)/i,`$1<head><style>${r}</style></head>`),n}sanitizeHtml(t){let e=t.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,"");return e=e.replace(/<noscript[\s\S]*?<\/noscript>/gi,""),e}isFullDocument(t){return/^\s*(<html|<!DOCTYPE)/i.test(t)}wrapFragment(t){return`<!DOCTYPE html>\n<html>\n<head>\n <meta charset="utf-8">\n <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'none'; style-src 'unsafe-inline';">\n <style>\n body {\n margin: 0;\n padding: 16px;\n font-family: system-ui, -apple-system, sans-serif;\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n img { max-width: 100%; height: auto; }\n body {\n pointer-events: none;\n user-select: none;\n }\n </style>\n</head>\n<body>\n ${t}\n</body>\n</html>`}}class c extends l{constructor(){super(...arguments),this.name="CHATGPT",this.baseUrl="https://chatgpt.com",this.defaultStyles='\n /* Force Dark Background on main containers and wrappers */\n html, body, main, article, footer, form,\n [class*="bg-"], [class*="footer"], [class*="bottom"],\n div[class*="border-t"],\n #thread-bottom-container, #thread-bottom,\n #thread, .composer-parent, [class*="group\\/thread"] {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n border-color: #2a2b36 !important;\n }\n\n /* Force background on specific white artifacts in the footer */\n #thread-bottom-container .bg-clip-padding,\n #thread-bottom-container .content-fade,\n #thread-bottom-container .absolute {\n background-color: transparent !important;\n }\n\n /* Specific targeting for the composer/input box (was white) */\n form .bg-token-bg-primary, form .shadow-short {\n background-color: #2a2b36 !important;\n border-color: #3e3f4b !important;\n box-shadow: none !important;\n }\n\n /* Disclaimer Footer - Force Dark Background */\n div[class*="text-token-text-secondary"] {\n color: #9ca3af !important;\n background-color: #131314 !important;\n }\n\n /* Force Text Color to Light */\n p, h1, h2, h3, h4, h5, h6, li, span, div, td, th, textarea, button {\n color: #e3e3e3 !important;\n }\n\n /* Links - Light Blue */\n a, a span {\n color: #8ab4f8 !important;\n }\n\n /* Code Blocks */\n pre, code, pre div, code span {\n background-color: #2a2b36 !important;\n color: #e3e3e3 !important;\n text-shadow: none !important;\n }\n\n /* Inputs/Textareas */\n input, textarea {\n background-color: transparent !important;\n color: #e3e3e3 !important;\n border-color: #3e3f4b !important;\n }\n\n /* Placeholder text */\n textarea::placeholder {\n color: #9ca3af !important;\n }\n\n /* Hide Sidebar */\n nav, [class*="sidebar"] {\n display: none !important;\n }\n\n /* Media visibility */\n img, video {\n opacity: 1 !important;\n }\n '}extractContent(t){let e="",n="",r=t;return t.result&&(r=t.result),"string"==typeof r?r.trim().startsWith("<")&&r.includes(">")?e=r:n=r:"object"==typeof r&&null!==r&&(r.html?e=r.html:r.content?r.content.trim().startsWith("<")?e=r.content:n=r.content:r.text&&(n=r.text)),{html:e,text:n}}parse(t,e){const{html:n,text:r}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in ChatGPT response");let o=n||"";return!o&&r&&(o=`<div>${r.replace(/\n/g,"<br>")}</div>`),o=this.sanitizeHtml(o),o=this.injectStyles(o,{theme:(null==e?void 0:e.theme)||"dark",baseUrl:(null==e?void 0:e.baseUrl)||this.baseUrl}),{provider:this.name,html:o,text:r,metadata:{isFullDocument:this.isFullDocument(o)}}}}class d extends l{constructor(){super(...arguments),this.name="GEMINI",this.baseUrl="https://gemini.google.com",this.defaultStyles='\n /* Gemini Dark Mode Variable Overrides */\n :root {\n --gem-sys-color--surface: #131314 !important;\n --gem-sys-color--surface-container: #1e1f20 !important;\n --gem-sys-color--on-surface: #e3e3e3 !important;\n --bard-color-synthetic--chat-window-surface: #131314 !important;\n --bard-color-surface-dim-tmp: #131314 !important;\n }\n\n /* UI hiding - Gemini */\n bard-sidenav, mat-sidenav, .mat-drawer-backdrop, .side-nav-menu-button,\n\n /* Gemini "About Gemini" footer/navigation block */\n .gb_5a, .gb_5c, .gb_5d, .gb_5e,\n .gb_Uc, .gb_Vc, .gb_Wc,\n a[href*="about"],\n a[href*="subscriptions"],\n a[href*="business"],\n div[class*="gb_5"],\n .gb_Pd, .gb_Qd, .gb_Rd,\n .gb_Sd, .gb_Td, .gb_Ud, .gb_Vd,\n [aria-label*="About"],\n [aria-label*="Gemini App"],\n [aria-label*="Subscriptions"],\n [aria-label*="For Business"],\n *:contains("About Gemini"),\n *:contains("Gemini App"),\n *:contains("Subscriptions"),\n *:contains("For Business") {\n display: none !important;\n }\n\n /* General Layout */\n main { width: 100% !important; max-width: 100% !important; margin: 0 !important; }\n\n /* Force Dark Mode on Body and Gemini Containers */\n body, .content-container, chat-app, .main-content, .chat-container {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n }\n '}extractContent(t){let e="",n="",r=[],o=t;return t.result&&(o=t.result),"string"==typeof o?o.trim().startsWith("<")&&o.includes(">")?e=o:n=o:"object"==typeof o&&null!==o&&(o.html?e=o.html:o.content?o.content.trim().startsWith("<")?e=o.content:n=o.content:o.text&&(n=o.text),o.aioverview&&(o.aioverview.text&&(n=o.aioverview.text),o.aioverview.sources&&(r=o.aioverview.sources))),{html:e,text:n,sources:r}}parse(t,e){const{html:n,text:r,sources:o}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in Gemini response");let i=n||"";return!i&&r&&(i=`<div>${r.replace(/\n/g,"<br>")}</div>`),i=this.sanitizeHtml(i),i=this.injectStyles(i,{theme:(null==e?void 0:e.theme)||"dark",baseUrl:(null==e?void 0:e.baseUrl)||this.baseUrl}),{provider:this.name,html:i,text:r,sources:o,metadata:{isFullDocument:this.isFullDocument(i)}}}}class u extends l{constructor(){super(...arguments),this.name="PERPLEXITY",this.baseUrl="https://www.perplexity.ai",this.defaultStyles="\n html {\n filter: invert(1) hue-rotate(180deg);\n background-color: white !important;\n }\n img, video, iframe, svg {\n filter: invert(1) hue-rotate(180deg);\n }\n "}extractContent(t){let e="",n="",r=t;return t.result&&(r=t.result),"string"==typeof r?r.trim().startsWith("<")&&r.includes(">")?e=r:n=r:"object"==typeof r&&null!==r&&(r.html?e=r.html:r.content?r.content.trim().startsWith("<")?e=r.content:n=r.content:r.text&&(n=r.text)),{html:e,text:n}}parse(t,e){const{html:n,text:r}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in Perplexity response");let o=n||"";return!o&&r&&(o=`<div>${r.replace(/\n/g,"<br>")}</div>`),o=this.injectStyles(o,{theme:(null==e?void 0:e.theme)||"dark",baseUrl:(null==e?void 0:e.baseUrl)||this.baseUrl,customCSS:"light"===(null==e?void 0:e.theme)?"":this.defaultStyles}),{provider:this.name,html:o,text:r,metadata:{isFullDocument:this.isFullDocument(o)}}}}class m extends l{constructor(){super(...arguments),this.name="COPILOT",this.baseUrl="https://copilot.microsoft.com",this.defaultStyles='\n /* Copilot Sidebar & Header */\n div:has(> [data-testid="sidebar-container"]),\n [data-testid="sidebar-container"],\n [data-testid="sticky-header"],\n .side-nav-menu-button {\n display: none !important;\n }\n\n /* General Layout Fixes */\n main {\n width: 100% !important;\n max-width: 100% !important;\n margin: 0 !important;\n }\n '}extractContent(t){let e="",n="",r=t;return t.result&&(r=t.result),"string"==typeof r?r.trim().startsWith("<")&&r.includes(">")?e=r:n=r:"object"==typeof r&&null!==r&&(r.html?e=r.html:r.content?r.content.trim().startsWith("<")?e=r.content:n=r.content:r.text&&(n=r.text)),{html:e,text:n}}parse(t,e){const{html:n,text:r}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in Copilot response");let o=n||"";return!o&&r&&(o=`<div>${r.replace(/\n/g,"<br>")}</div>`),o=o.replace(/<noscript[\s\S]*?<\/noscript>/gi,""),o=this.injectStyles(o,{theme:(null==e?void 0:e.theme)||"dark",baseUrl:(null==e?void 0:e.baseUrl)||this.baseUrl}),{provider:this.name,html:o,text:r,metadata:{isFullDocument:this.isFullDocument(o)}}}}class h extends l{constructor(){super(...arguments),this.name="AIOVERVIEW",this.baseUrl="https://www.google.com",this.defaultStyles='\n /* UI hiding - Google Search (AI Overview) */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L,\n\n /* Specific AI Mode Selectors */\n .DZ13He,\n .wYq63b,\n .eT9Cje,\n .bNg8Rb,\n .S6VXfe,\n .Lu57id {\n display: none !important;\n }\n\n /* General Layout */\n main { width: 100% !important; max-width: 100% !important; margin: 0 !important; }\n '}extractContent(t){let e="",n="",r=[],o=t;if(t.result&&(o=t.result),o.aioverview&&(o.aioverview.text&&(n=o.aioverview.text),o.aioverview.sources&&(r=o.aioverview.sources)),"string"==typeof o?o.trim().startsWith("<")&&o.includes(">")?e=o:n=n||o:"object"==typeof o&&null!==o&&(o.html&&!n?e=o.html:o.content&&!n?o.content.trim().startsWith("<")?e=o.content:n=o.content:o.text&&!n&&(n=o.text)),e){const t=e.match(/"DnVkpd"\s*:\s*"((?:[^"\\]|\\.)*)"/);if(t&&t[1])try{let e=JSON.parse(`"${t[1]}"`);e=e.replace(/∰/g,'<hr class="gemini-separator">'),e=e.replace(/∞(https:\/\/[^ ]+\.(?:jpg|png|webp|gif|jpeg)(?:\?[^ ]*)?)/gi,'<br><img src="$1" class="gemini-image" alt="Generated Image"><br>'),e=e.replace(/∞/g,"<br>"),e=e.replace(/\n/g,"<br>"),n=e}catch(t){console.error("Failed to parse AI Overview WIZ data",t)}}return{html:e,text:n,sources:r}}parse(t,e){const{html:n,text:r,sources:o}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in AI Overview response");let i="";if(r&&!n){const t="\n body {\n font-family: 'Google Sans', Roboto, sans-serif;\n line-height: 1.5;\n padding: 20px;\n color: #e3e3e3;\n background-color: #131314;\n }\n .gemini-separator {\n border: 0;\n border-top: 1px solid #444;\n margin: 24px 0;\n }\n .gemini-image {\n max-width: 100%;\n border-radius: 8px;\n margin: 12px 0;\n border: 1px solid #333;\n }\n a { color: #8ab4f8; }\n table { border-collapse: collapse; width: 100%; margin: 16px 0; }\n th, td { border: 1px solid #444; padding: 8px; text-align: left; }\n th { background-color: #1f1f1f; }\n ";i=`<!DOCTYPE html>\n <html>\n <head>\n <base href="${(null==e?void 0:e.baseUrl)||this.baseUrl}">\n <style>${t}</style>\n </head>\n <body>\n ${r}\n </body>\n </html>`}else i=n||"",i=this.sanitizeHtml(i),i=this.injectStyles(i,{theme:(null==e?void 0:e.theme)||"dark",baseUrl:(null==e?void 0:e.baseUrl)||this.baseUrl,hideUI:!0});return{provider:this.name,html:i,text:r,sources:o,metadata:{isFullDocument:this.isFullDocument(i),hasWizData:!!r&&!n}}}}class p extends l{constructor(){super(...arguments),this.name="AIMODE",this.baseUrl="https://www.google.com",this.defaultStyles='\n /* UI hiding - Google Search (AI Mode) */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L,\n\n /* Specific AI Mode Selectors found in analysis */\n .DZ13He, /* Main sticky top bar */\n .wYq63b, /* Accessibility links bar */\n .eT9Cje, /* History/New Search buttons */\n .bNg8Rb, /* Hidden H1 headers */\n .S6VXfe, /* Accessibility container */\n .Lu57id /* Potential other top bar */ {\n display: none !important;\n }\n\n /* General Layout */\n main { width: 100% !important; max-width: 100% !important; margin: 0 !important; }\n '}extractContent(t){let e="",n="",r=t;return t.result&&(r=t.result),"string"==typeof r?r.trim().startsWith("<")&&r.includes(">")?e=r:n=r:"object"==typeof r&&null!==r&&(r.html?e=r.html:r.content?r.content.trim().startsWith("<")?e=r.content:n=r.content:r.text&&(n=r.text)),{html:e,text:n}}parse(t,e){const{html:n,text:r}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in AI Mode response");let o=n||"";return!o&&r&&(o=`<div>${r.replace(/\n/g,"<br>")}</div>`),o=this.sanitizeHtml(o),o=this.injectStyles(o,{theme:(null==e?void 0:e.theme)||"dark",baseUrl:(null==e?void 0:e.baseUrl)||this.baseUrl,hideUI:!0}),{provider:this.name,html:o,text:r,metadata:{isFullDocument:this.isFullDocument(o)}}}}const b=new class{constructor(){this.providers=new Map,this.providers.set("CHATGPT",new c),this.providers.set("GEMINI",new d),this.providers.set("PERPLEXITY",new u),this.providers.set("COPILOT",new m),this.providers.set("AIOVERVIEW",new h),this.providers.set("AIMODE",new p)}parse(t,e){const n=a.detect(t);if(!n)return this.parseGeneric(t,e);const r=this.providers.get(n.provider);if(!r)return null;try{const o=r.parse(t,e);return{...o,metadata:{...o.metadata,detectionConfidence:n.confidence}}}catch(t){return console.error(`Failed to parse response with ${n.provider}:`,t),null}}parseWithProvider(t,e,n){const r=this.providers.get(e);if(!r)throw new Error(`Unknown provider: ${e}`);try{return r.parse(t,n)}catch(t){return console.error(`Failed to parse response with ${e}:`,t),null}}detectProvider(t){const e=a.detect(t);return(null==e?void 0:e.provider)||null}detectAllProviders(t){return a.getAllProviders(t)}parseGeneric(t,e){let n="",r="";let o=t;var i;return t.result&&(o=t.result),"string"==typeof(i=o)?i.trim().startsWith("<")&&i.includes(">")?n=i:r=i:"object"==typeof i&&null!==i&&(i.html?n=i.html:i.content?i.content.trim().startsWith("<")?n=i.content:r=i.content:i.text&&(r=i.text)),n||r?(n&&(n=n.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,""),n=n.replace(/<noscript[\s\S]*?<\/noscript>/gi,"")),{provider:"CHATGPT",html:n,text:r,metadata:{isGeneric:!0}}):null}getSupportedProviders(){return Array.from(this.providers.keys())}registerProvider(t,e){this.providers.set(t,e)}},v=(t,e)=>b.parse(t,e);function g(t,e={}){const{autoDetect:n=!0,provider:s,theme:a="dark",baseUrl:l,sanitize:c=!0,includeStyles:d=!0,onProviderDetected:u,onError:m}=e,[h,p]=r(!1),[g,f]=r(null),[y,x]=r(null),[w,I]=r(0),S=o(()=>s||(n&&t?(t=>b.detectProvider(t))(t):null),[t,s,n,w]);i(()=>{null==u||u(S)},[S,u]),i(()=>{if(!t)return x(null),void f(null);p(!0),f(null);try{const e={theme:a,baseUrl:l,sanitize:c,includeStyles:d};let n;n=v(t,e),x(n)}catch(t){const e=t instanceof Error?t:new Error("Failed to parse AI response");f(e),null==m||m(e)}finally{p(!1)}},[t,a,l,c,d,s,w]);return{parsed:y,provider:(null==y?void 0:y.provider)||S,isLoading:h,error:g,html:(null==y?void 0:y.html)||null,text:(null==y?void 0:y.text)||null,sources:(null==y?void 0:y.sources)||null,reparse:t=>{I(t=>t+1)}}}const f=s(({html:e,className:n="",style:r,sandbox:o="allow-popups allow-same-origin",title:i="AI Response",onLoad:s,onError:a},l)=>{const c=()=>{null==s||s()},d=()=>{null==a||a()};return e.trim().startsWith("http")?t("iframe",{ref:l,src:e,className:n,style:r,sandbox:o,title:i,onLoad:c,onError:d}):t("iframe",{ref:l,srcDoc:e,className:n,style:r,sandbox:o,title:i,onLoad:c,onError:d})});f.displayName="IframeRenderer";const y=({response:r,className:o="",style:i,iframeProps:s={},loadingComponent:a,errorComponent:l,fallbackComponent:c,onRenderComplete:d,...u})=>{const{parsed:m,provider:h,isLoading:p,error:b,html:v,text:y,sources:x,reparse:w}=g(r,u);return n.useEffect(()=>{!v||p||b||null==d||d(v)},[v,p,b,d]),p?a?t(a,{isLoading:!0}):t("div",{className:`ai-response-loading ${o}`,style:i,children:e("div",{className:"animate-pulse",children:[t("div",{className:"h-4 bg-gray-300 rounded w-3/4 mb-2"}),t("div",{className:"h-4 bg-gray-300 rounded w-1/2 mb-2"}),t("div",{className:"h-4 bg-gray-300 rounded w-5/6"})]})}):b?l?t(l,{error:b,retry:w}):t("div",{className:`ai-response-error ${o}`,style:i,children:e("div",{className:"text-red-500",children:[t("p",{children:"Failed to render AI response:"}),t("p",{className:"text-sm",children:b.message}),t("button",{onClick:()=>w(),className:"mt-2 px-3 py-1 bg-red-100 text-red-700 rounded hover:bg-red-200",children:"Retry"})]})}):m||v||y?!v&&y?t("div",{className:`ai-response-text ${o}`,style:{...i,whiteSpace:"pre-wrap",wordWrap:"break-word"},children:y}):v?t("div",{className:`ai-response-container ${o}`,style:i,children:t(f,{html:v,className:"w-full h-full border-0 rounded-md",title:`${h||"AI"} Response`,...s})}):null:c?t(c,{provider:h}):t("div",{className:`ai-response-empty ${o}`,style:i,children:e("div",{className:"text-gray-500 text-center",children:[t("p",{children:"No content available"}),h&&e("p",{className:"text-sm",children:["Detected provider: ",h]})]})})};export{y as AiResponseRenderer,f as IframeRenderer,g as useAiResponse};
|
|
1
|
+
import{jsx as t,jsxs as e}from"react/jsx-runtime";import n,{useState as r,useMemo as o,useEffect as i,forwardRef as s}from"react";class a{static detect(t){const e={CHATGPT:0,GEMINI:0,PERPLEXITY:0,COPILOT:0,AIOVERVIEW:0,AIMODE:0};for(const[n,r]of Object.entries(this.PROVIDER_PATTERNS))for(const o of r)try{o(t)&&e[n]++}catch(t){}let n=0,r=null;for(const[t,o]of Object.entries(e))o>n&&(n=o,r=t);return 0===n?null:{provider:r,confidence:n/Object.values(e).reduce((t,e)=>Math.max(t,e),1)}}static getAllProviders(t){const e=[];for(const[n,r]of Object.entries(this.PROVIDER_PATTERNS)){let o=0;for(const e of r)try{e(t)&&o++}catch(t){}o>0&&e.push({provider:n,confidence:o/r.length})}return e.sort((t,e)=>e.confidence-t.confidence)}static validate(t,e){const n=this.detect(t);return(null==n?void 0:n.provider)===e&&n.confidence>.5}}a.PROVIDER_PATTERNS={CHATGPT:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("bg-token-bg-primary")||n.includes("text-token-text-secondary")},t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("chatgpt.com")||n.includes("openai.com")}],GEMINI:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("bard-sidenav")||n.includes("mat-sidenav")},t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("gemini.google.com")||n.includes("gem-sys-color")}],PERPLEXITY:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("perplexity.ai")||n.includes("prose")}],COPILOT:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("copilot.microsoft.com")||n.includes('data-testid="sidebar-container"')}],AIOVERVIEW:[t=>{var e,n,r,o;if(null===(n=null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.aioverview)||void 0===n?void 0:n.text)return!0;if(null===(r=null==t?void 0:t.aioverview)||void 0===r?void 0:r.text)return!0;const i=(null===(o=null==t?void 0:t.result)||void 0===o?void 0:o.html)||(null==t?void 0:t.html)||"";return i.includes("WIZ_global_data")||i.includes("DnVkpd")}],AIMODE:[t=>{var e;const n=(null===(e=null==t?void 0:t.result)||void 0===e?void 0:e.html)||(null==t?void 0:t.html)||"";return n.includes("DZ13He")||n.includes("wYq63b")||n.includes("AI Mode")}]};class l{injectStyles(t,e){let n=t;(null==e?void 0:e.baseUrl)&&!t.includes("<base ")&&(n=n.includes("<head>")?n.replace("<head>",`<head><base href="${e.baseUrl}">`):n.replace(/(<html[^>]*>)/i,`$1<head><base href="${e.baseUrl}"></head>`));const r=(null==e?void 0:e.customCSS)||"";return r&&n.includes("<head>")?n=n.replace("<head>",`<head><style>${r}</style>`):r&&(n=n.replace(/(<html[^>]*>)/i,`$1<head><style>${r}</style></head>`)),n}sanitizeHtml(t){let e=t.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,"");return e=e.replace(/<noscript[\s\S]*?<\/noscript>/gi,""),e}isFullDocument(t){return/^\s*(<html|<!DOCTYPE)/i.test(t)}removeLinks(t){return t.replace(/<a\b[^>]*>([\s\S]*?)<\/a>/gim,"$1")}wrapFragment(t){return`<!DOCTYPE html>\n<html>\n<head>\n <meta charset="utf-8">\n <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'none'; style-src 'unsafe-inline';">\n <style>\n body {\n margin: 0;\n padding: 16px;\n font-family: system-ui, -apple-system, sans-serif;\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n img { max-width: 100%; height: auto; }\n body {\n pointer-events: none;\n user-select: none;\n }\n </style>\n</head>\n<body>\n ${t}\n</body>\n</html>`}}class c extends l{constructor(){super(...arguments),this.name="CHATGPT",this.baseUrl="https://chatgpt.com",this.defaultStyles='\n /* Force Dark Background on main containers and wrappers */\n html, body, main, article, footer, form,\n [class*="bg-"], [class*="footer"], [class*="bottom"],\n div[class*="border-t"],\n #thread-bottom-container, #thread-bottom,\n #thread, .composer-parent, [class*="group\\/thread"] {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n border-color: #2a2b36 !important;\n }\n\n /* Force background on specific white artifacts in the footer */\n #thread-bottom-container .bg-clip-padding,\n #thread-bottom-container .content-fade,\n #thread-bottom-container .absolute {\n background-color: transparent !important;\n }\n\n /* Specific targeting for the composer/input box (was white) */\n form .bg-token-bg-primary, form .shadow-short {\n background-color: #2a2b36 !important;\n border-color: #3e3f4b !important;\n box-shadow: none !important;\n }\n\n /* Disclaimer Footer - Force Dark Background */\n div[class*="text-token-text-secondary"] {\n color: #9ca3af !important;\n background-color: #131314 !important;\n }\n\n /* Force Text Color to Light */\n p, h1, h2, h3, h4, h5, h6, li, span, div, td, th, textarea, button {\n color: #e3e3e3 !important;\n }\n\n /* Links - Light Blue */\n a, a span {\n color: #8ab4f8 !important;\n }\n\n /* Code Blocks */\n pre, code, pre div, code span {\n background-color: #2a2b36 !important;\n color: #e3e3e3 !important;\n text-shadow: none !important;\n }\n\n /* Inputs/Textareas */\n input, textarea {\n background-color: transparent !important;\n color: #e3e3e3 !important;\n border-color: #3e3f4b !important;\n }\n\n /* Placeholder text */\n textarea::placeholder {\n color: #9ca3af !important;\n }\n\n /* Hide Sidebar */\n nav, [class*="sidebar"] {\n display: none !important;\n }\n\n /* Media visibility */\n img, video {\n opacity: 1 !important;\n }\n '}extractContent(t){let e="",n="",r=t;return t.result&&(r=t.result),"string"==typeof r?r.trim().startsWith("<")&&r.includes(">")?e=r:n=r:"object"==typeof r&&null!==r&&(r.html?e=r.html:r.content?r.content.trim().startsWith("<")?e=r.content:n=r.content:r.text&&(n=r.text)),{html:e,text:n}}parse(t,e){const{html:n,text:r}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in ChatGPT response");let o=n||"";return!o&&r&&(o=`<div>${r.replace(/\n/g,"<br>")}</div>`),o=this.sanitizeHtml(o),o=this.injectStyles(o,{baseUrl:this.baseUrl,customCSS:this.defaultStyles}),{provider:this.name,html:o,text:r,metadata:{isFullDocument:this.isFullDocument(o)}}}}class d extends l{constructor(){super(...arguments),this.name="GEMINI",this.baseUrl="https://gemini.google.com",this.defaultStyles='\n /* Gemini Dark Mode Variable Overrides */\n :root {\n --gem-sys-color--surface: #131314 !important;\n --gem-sys-color--surface-container: #1e1f20 !important;\n --gem-sys-color--on-surface: #e3e3e3 !important;\n --bard-color-synthetic--chat-window-surface: #131314 !important;\n --bard-color-surface-dim-tmp: #131314 !important;\n }\n\n /* UI hiding - Gemini */\n bard-sidenav, mat-sidenav, .mat-drawer-backdrop, .side-nav-menu-button,\n\n /* Gemini "About Gemini" footer/navigation block */\n .gb_5a, .gb_5c, .gb_5d, .gb_5e,\n .gb_Uc, .gb_Vc, .gb_Wc,\n a[href*="about"],\n a[href*="subscriptions"],\n a[href*="business"],\n div[class*="gb_5"],\n .gb_Pd, .gb_Qd, .gb_Rd,\n .gb_Sd, .gb_Td, .gb_Ud, .gb_Vd,\n [aria-label*="About"],\n [aria-label*="Gemini App"],\n [aria-label*="Subscriptions"],\n [aria-label*="For Business"],\n *:contains("About Gemini"),\n *:contains("Gemini App"),\n *:contains("Subscriptions"),\n *:contains("For Business") {\n display: none !important;\n }\n\n /* General Layout */\n main { width: 100% !important; max-width: 100% !important; margin: 0 !important; }\n\n /* Force Dark Mode on Body and Gemini Containers */\n body, .content-container, chat-app, .main-content, .chat-container {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n }\n '}extractContent(t){let e="",n="",r=[],o=t;return t.result&&(o=t.result),"string"==typeof o?o.trim().startsWith("<")&&o.includes(">")?e=o:n=o:"object"==typeof o&&null!==o&&(o.html?e=o.html:o.content?o.content.trim().startsWith("<")?e=o.content:n=o.content:o.text&&(n=o.text),o.aioverview&&(o.aioverview.text&&(n=o.aioverview.text),o.aioverview.sources&&(r=o.aioverview.sources))),{html:e,text:n,sources:r}}parse(t,e){const{html:n,text:r,sources:o}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in Gemini response");let i=n||"";return!i&&r&&(i=`<div>${r.replace(/\n/g,"<br>")}</div>`),i=this.sanitizeHtml(i),i=this.injectStyles(i,{baseUrl:this.baseUrl,customCSS:this.defaultStyles}),{provider:this.name,html:i,text:r,sources:o,metadata:{isFullDocument:this.isFullDocument(i)}}}}class m extends l{constructor(){super(...arguments),this.name="PERPLEXITY",this.baseUrl="https://www.perplexity.ai",this.defaultStyles="\n html {\n filter: invert(1) hue-rotate(180deg);\n background-color: white !important;\n }\n "}extractContent(t){let e="",n="",r=t;return t.result&&(r=t.result),"string"==typeof r?r.trim().startsWith("<")&&r.includes(">")?e=r:n=r:"object"==typeof r&&null!==r&&(r.html?e=r.html:r.content?r.content.trim().startsWith("<")?e=r.content:n=r.content:r.text&&(n=r.text)),{html:e,text:n}}parse(t,e){const{html:n,text:r}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in Perplexity response");let o=n||"";return!o&&r&&(o=`<div>${r.replace(/\n/g,"<br>")}</div>`),o=this.sanitizeHtml(o),(null==e?void 0:e.removeLinks)&&(o=this.removeLinks(o)),o=this.injectStyles(o,{baseUrl:this.baseUrl,customCSS:(null==e?void 0:e.invertColors)?this.defaultStyles:""}),{provider:this.name,html:o,text:r,metadata:{isFullDocument:this.isFullDocument(o),linksRemoved:(null==e?void 0:e.removeLinks)||!1,colorsInverted:(null==e?void 0:e.invertColors)||!1}}}}class u extends l{constructor(){super(...arguments),this.name="COPILOT",this.baseUrl="https://copilot.microsoft.com",this.defaultStyles='\n /* Copilot Sidebar & Header */\n div:has(> [data-testid="sidebar-container"]),\n [data-testid="sidebar-container"],\n [data-testid="sticky-header"],\n .side-nav-menu-button {\n display: none !important;\n }\n\n /* General Layout Fixes */\n main {\n width: 100% !important;\n max-width: 100% !important;\n margin: 0 !important;\n }\n '}extractContent(t){let e="",n="",r=t;return t.result&&(r=t.result),"string"==typeof r?r.trim().startsWith("<")&&r.includes(">")?e=r:n=r:"object"==typeof r&&null!==r&&(r.html?e=r.html:r.content?r.content.trim().startsWith("<")?e=r.content:n=r.content:r.text&&(n=r.text)),{html:e,text:n}}parse(t,e){const{html:n,text:r}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in Copilot response");let o=n||"";return!o&&r&&(o=`<div>${r.replace(/\n/g,"<br>")}</div>`),o=this.sanitizeHtml(o),o=this.injectStyles(o,{baseUrl:this.baseUrl,customCSS:this.defaultStyles}),{provider:this.name,html:o,text:r,metadata:{isFullDocument:this.isFullDocument(o)}}}}class h extends l{constructor(){super(...arguments),this.name="AIOVERVIEW",this.baseUrl="https://www.google.com",this.defaultStyles='\n /* UI hiding - Google Search (AI Overview) */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L,\n\n /* Specific AI Mode Selectors */\n .DZ13He,\n .wYq63b,\n .eT9Cje,\n .bNg8Rb,\n .S6VXfe,\n .Lu57id {\n display: none !important;\n }\n\n /* General Layout */\n main { width: 100% !important; max-width: 100% !important; margin: 0 !important; }\n '}extractContent(t){let e="",n="",r=[],o=t;if(t.result&&(o=t.result),o.aioverview&&(o.aioverview.text&&(n=o.aioverview.text),o.aioverview.sources&&(r=o.aioverview.sources)),"string"==typeof o?o.trim().startsWith("<")&&o.includes(">")?e=o:n=n||o:"object"==typeof o&&null!==o&&(o.html&&!n?e=o.html:o.content&&!n?o.content.trim().startsWith("<")?e=o.content:n=o.content:o.text&&!n&&(n=o.text)),e){const t=e.match(/"DnVkpd"\s*:\s*"((?:[^"\\]|\\.)*)"/);if(t&&t[1])try{let e=JSON.parse(`"${t[1]}"`);e=e.replace(/∰/g,'<hr class="gemini-separator">'),e=e.replace(/∞(https:\/\/[^ ]+\.(?:jpg|png|webp|gif|jpeg)(?:\?[^ ]*)?)/gi,'<br><img src="$1" class="gemini-image" alt="Generated Image"><br>'),e=e.replace(/∞/g,"<br>"),e=e.replace(/\n/g,"<br>"),n=e}catch(t){console.error("Failed to parse AI Overview WIZ data",t)}}return{html:e,text:n,sources:r}}parse(t,e){const{html:n,text:r,sources:o}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in AI Overview response");let i="";if(r&&!n){const t="\n body {\n font-family: 'Google Sans', Roboto, sans-serif;\n line-height: 1.5;\n padding: 20px;\n color: #e3e3e3;\n background-color: #131314;\n }\n .gemini-separator {\n border: 0;\n border-top: 1px solid #444;\n margin: 24px 0;\n }\n .gemini-image {\n max-width: 100%;\n border-radius: 8px;\n margin: 12px 0;\n border: 1px solid #333;\n }\n a { color: #8ab4f8; }\n table { border-collapse: collapse; width: 100%; margin: 16px 0; }\n th, td { border: 1px solid #444; padding: 8px; text-align: left; }\n th { background-color: #1f1f1f; }\n ";i=`<!DOCTYPE html>\n <html>\n <head>\n <base href="${this.baseUrl}">\n <style>${t}</style>\n </head>\n <body>\n ${r}\n </body>\n </html>`}else i=n||"",i=this.sanitizeHtml(i),i=this.injectStyles(i,{baseUrl:this.baseUrl,hideUI:!0,customCSS:this.defaultStyles});return{provider:this.name,html:i,text:r,sources:o,metadata:{isFullDocument:this.isFullDocument(i),hasWizData:!!r&&!n}}}}class p extends l{constructor(){super(...arguments),this.name="AIMODE",this.baseUrl="https://www.google.com",this.defaultStyles='\n /* UI hiding - Google Search (AI Mode) */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L,\n\n /* Specific AI Mode Selectors found in analysis */\n .DZ13He, /* Main sticky top bar */\n .wYq63b, /* Accessibility links bar */\n .eT9Cje, /* History/New Search buttons */\n .bNg8Rb, /* Hidden H1 headers */\n .S6VXfe, /* Accessibility container */\n .Lu57id /* Potential other top bar */ {\n display: none !important;\n }\n\n /* General Layout */\n main { width: 100% !important; max-width: 100% !important; margin: 0 !important; }\n '}extractContent(t){let e="",n="",r=t;return t.result&&(r=t.result),"string"==typeof r?r.trim().startsWith("<")&&r.includes(">")?e=r:n=r:"object"==typeof r&&null!==r&&(r.html?e=r.html:r.content?r.content.trim().startsWith("<")?e=r.content:n=r.content:r.text&&(n=r.text)),{html:e,text:n}}parse(t,e){const{html:n,text:r}=this.extractContent(t);if(!n&&!r)throw new Error("No content found in AI Mode response");let o=n||"";return!o&&r&&(o=`<div>${r.replace(/\n/g,"<br>")}</div>`),o=this.sanitizeHtml(o),o=this.injectStyles(o,{baseUrl:this.baseUrl,hideUI:!0,customCSS:this.defaultStyles}),{provider:this.name,html:o,text:r,metadata:{isFullDocument:this.isFullDocument(o)}}}}const v=new class{constructor(){this.providers=new Map,this.providers.set("CHATGPT",new c),this.providers.set("GEMINI",new d),this.providers.set("PERPLEXITY",new m),this.providers.set("COPILOT",new u),this.providers.set("AIOVERVIEW",new h),this.providers.set("AIMODE",new p)}parse(t,e){const n=a.detect(t);if(!n)return this.parseGeneric(t,e);const r=this.providers.get(n.provider);if(!r)return null;try{const o=r.parse(t,e);return{...o,metadata:{...o.metadata,detectionConfidence:n.confidence}}}catch(t){return console.error(`Failed to parse response with ${n.provider}:`,t),null}}parseWithProvider(t,e,n){const r=this.providers.get(e);if(!r)throw new Error(`Unknown provider: ${e}`);try{return r.parse(t,n)}catch(t){return console.error(`Failed to parse response with ${e}:`,t),null}}detectProvider(t){const e=a.detect(t);return(null==e?void 0:e.provider)||null}detectAllProviders(t){return a.getAllProviders(t)}parseGeneric(t,e){let n="",r="";let o=t;var i;return t.result&&(o=t.result),"string"==typeof(i=o)?i.trim().startsWith("<")&&i.includes(">")?n=i:r=i:"object"==typeof i&&null!==i&&(i.html?n=i.html:i.content?i.content.trim().startsWith("<")?n=i.content:r=i.content:i.text&&(r=i.text)),n||r?(n&&(n=n.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,""),n=n.replace(/<noscript[\s\S]*?<\/noscript>/gi,"")),{provider:"CHATGPT",html:n,text:r,metadata:{isGeneric:!0}}):null}getSupportedProviders(){return Array.from(this.providers.keys())}registerProvider(t,e){this.providers.set(t,e)}},b=(t,e)=>v.parse(t,e);function g(t,e={}){const{autoDetect:n=!0,provider:s,removeLinks:a=!1,invertColors:l=!1,onProviderDetected:c,onError:d}=e,[m,u]=r(!1),[h,p]=r(null),[g,f]=r(null),[y,x]=r(0),w=o(()=>s||(n&&t?(t=>v.detectProvider(t))(t):null),[t,s,n,y]);i(()=>{null==c||c(w)},[w,c]),i(()=>{if(!t)return f(null),void p(null);u(!0),p(null);try{const e={removeLinks:a,invertColors:l};let n;n=b(t,e),f(n)}catch(t){const e=t instanceof Error?t:new Error("Failed to parse AI response");p(e),null==d||d(e)}finally{u(!1)}},[t,a,l,s,y]);return{parsed:g,provider:(null==g?void 0:g.provider)||w,isLoading:m,error:h,html:(null==g?void 0:g.html)||null,text:(null==g?void 0:g.text)||null,sources:(null==g?void 0:g.sources)||null,reparse:t=>{x(t=>t+1)}}}const f=s(({html:e,className:n="",style:r,sandbox:o="allow-popups allow-same-origin",title:i="AI Response",onLoad:s,onError:a},l)=>{const c=()=>{null==s||s()},d=()=>{null==a||a()};return e.trim().startsWith("http")?t("iframe",{ref:l,src:e,className:n,style:r,sandbox:o,title:i,onLoad:c,onError:d}):t("iframe",{ref:l,srcDoc:e,className:n,style:r,sandbox:o,title:i,onLoad:c,onError:d})});f.displayName="IframeRenderer";const y=({response:r,className:o="",style:i,iframeProps:s={},loadingComponent:a,errorComponent:l,fallbackComponent:c,onRenderComplete:d,...m})=>{const{parsed:u,provider:h,isLoading:p,error:v,html:b,text:y,sources:x,reparse:w}=g(r,m);return n.useEffect(()=>{!b||p||v||null==d||d(b)},[b,p,v,d]),p?a?t(a,{isLoading:!0}):t("div",{className:`ai-response-loading ${o}`,style:i,children:e("div",{className:"animate-pulse",children:[t("div",{className:"h-4 bg-gray-300 rounded w-3/4 mb-2"}),t("div",{className:"h-4 bg-gray-300 rounded w-1/2 mb-2"}),t("div",{className:"h-4 bg-gray-300 rounded w-5/6"})]})}):v?l?t(l,{error:v,retry:w}):t("div",{className:`ai-response-error ${o}`,style:i,children:e("div",{className:"text-red-500",children:[t("p",{children:"Failed to render AI response:"}),t("p",{className:"text-sm",children:v.message}),t("button",{onClick:()=>w(),className:"mt-2 px-3 py-1 bg-red-100 text-red-700 rounded hover:bg-red-200",children:"Retry"})]})}):u||b||y?!b&&y?t("div",{className:`ai-response-text ${o}`,style:{...i,whiteSpace:"pre-wrap",wordWrap:"break-word"},children:y}):b?t("div",{className:`ai-response-container ${o}`,style:i,children:t(f,{html:b,className:"w-full h-full border-0 rounded-md",title:`${h||"AI"} Response`,...s})}):null:c?t(c,{provider:h}):t("div",{className:`ai-response-empty ${o}`,style:i,children:e("div",{className:"text-gray-500 text-center",children:[t("p",{children:"No content available"}),h&&e("p",{className:"text-sm",children:["Detected provider: ",h]})]})})};y.displayName="ResponseRenderer";export{f as IframeRenderer,y as ResponseRenderer,g as useResponse};
|
|
2
2
|
//# sourceMappingURL=index.esm.js.map
|