hypercrm 1.0.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.
@@ -0,0 +1,41 @@
1
+ export interface WidgetOptions {
2
+ apiUrl?: string;
3
+ apiKey?: string;
4
+ orgId?: string;
5
+ mount?: HTMLElement | string;
6
+ theme?: Record<string, string>;
7
+ colorMode?: 'light' | 'dark' | 'auto';
8
+ position?: 'left' | 'right';
9
+ autoOpen?: boolean;
10
+ debug?: boolean;
11
+ scriptUrl?: string;
12
+ }
13
+ export declare const initWidget: (options?: WidgetOptions) => Promise<any>;
14
+ export declare const destroyWidget: () => void;
15
+ export declare const setWidgetTheme: (theme: Record<string, string>) => Promise<void>;
16
+ export declare const setWidgetColorMode: (mode: "light" | "dark" | "auto") => Promise<void>;
17
+ export declare const setWidgetPosition: (position: "left" | "right") => Promise<void>;
18
+ declare const _default: {
19
+ init: (options?: WidgetOptions) => Promise<any>;
20
+ destroy: () => void;
21
+ setTheme: (theme: Record<string, string>) => Promise<void>;
22
+ setColorMode: (mode: "light" | "dark" | "auto") => Promise<void>;
23
+ setPosition: (position: "left" | "right") => Promise<void>;
24
+ };
25
+ export default _default;
26
+ declare global {
27
+ interface Window {
28
+ HyperCRMWidget: {
29
+ init: (options?: WidgetOptions) => any;
30
+ destroy: () => void;
31
+ setTheme: (theme?: Record<string, string>) => void;
32
+ setColorMode: (mode: 'light' | 'dark' | 'auto') => void;
33
+ setPosition: (position: 'left' | 'right') => void;
34
+ open: () => void;
35
+ close: () => void;
36
+ toggle: () => void;
37
+ openLightbox: (url: string) => void;
38
+ closeLightbox: () => void;
39
+ };
40
+ }
41
+ }
package/dist/index.js ADDED
@@ -0,0 +1,104 @@
1
+ const promiseCache = new Map();
2
+ const buildScriptCandidates = (options) => {
3
+ const urls = [];
4
+ const push = (url) => {
5
+ if (!url)
6
+ return;
7
+ if (!urls.includes(url))
8
+ urls.push(url);
9
+ };
10
+ if (options.scriptUrl)
11
+ push(options.scriptUrl);
12
+ if (options.apiUrl) {
13
+ try {
14
+ const api = new URL(options.apiUrl);
15
+ push(`${api.protocol}//${api.host}/widget/widget.js`);
16
+ }
17
+ catch (_) { }
18
+ }
19
+ if (typeof window !== 'undefined' && window.location) {
20
+ push(`${window.location.origin}/widget/widget.js`);
21
+ }
22
+ push('/widget/widget.js');
23
+ return urls;
24
+ };
25
+ const loadScript = (url) => {
26
+ if (promiseCache.has(url))
27
+ return promiseCache.get(url);
28
+ const existing = document.querySelector(`script[data-hypercrm-widget="${url}"]`);
29
+ if (existing) {
30
+ const promise = new Promise((resolve, reject) => {
31
+ existing.addEventListener('load', () => resolve(), { once: true });
32
+ existing.addEventListener('error', () => reject(new Error(`Failed to load HyperCRM widget script: ${url}`)), { once: true });
33
+ });
34
+ promiseCache.set(url, promise);
35
+ return promise;
36
+ }
37
+ const promise = new Promise((resolve, reject) => {
38
+ const script = document.createElement('script');
39
+ script.src = url;
40
+ script.async = true;
41
+ script.dataset.hypercrmWidget = url;
42
+ script.onload = () => resolve();
43
+ script.onerror = () => {
44
+ script.remove();
45
+ promiseCache.delete(url);
46
+ reject(new Error(`Failed to load HyperCRM widget script: ${url}`));
47
+ };
48
+ document.head.appendChild(script);
49
+ });
50
+ promiseCache.set(url, promise);
51
+ return promise;
52
+ };
53
+ const ensureScriptLoaded = async (options = {}) => {
54
+ if (typeof window === 'undefined') {
55
+ throw new Error('HyperCRM widget can only be initialized in the browser');
56
+ }
57
+ if (window.HyperCRMWidget)
58
+ return;
59
+ const candidates = buildScriptCandidates(options);
60
+ let lastError = null;
61
+ for (const candidate of candidates) {
62
+ try {
63
+ await loadScript(candidate);
64
+ return;
65
+ }
66
+ catch (err) {
67
+ if (options.debug) {
68
+ console.warn(`[HyperCRMWidget] Failed to load script candidate ${candidate}`, err);
69
+ }
70
+ lastError = err;
71
+ }
72
+ }
73
+ if (lastError)
74
+ throw lastError;
75
+ throw new Error('Failed to load HyperCRM widget script');
76
+ };
77
+ export const initWidget = async (options = {}) => {
78
+ await ensureScriptLoaded(options);
79
+ return window.HyperCRMWidget.init(options);
80
+ };
81
+ export const destroyWidget = () => {
82
+ if (typeof window === 'undefined' || !window.HyperCRMWidget)
83
+ return;
84
+ window.HyperCRMWidget.destroy();
85
+ };
86
+ export const setWidgetTheme = async (theme) => {
87
+ await ensureScriptLoaded();
88
+ window.HyperCRMWidget.setTheme(theme);
89
+ };
90
+ export const setWidgetColorMode = async (mode) => {
91
+ await ensureScriptLoaded();
92
+ window.HyperCRMWidget.setColorMode(mode);
93
+ };
94
+ export const setWidgetPosition = async (position) => {
95
+ await ensureScriptLoaded();
96
+ window.HyperCRMWidget.setPosition(position);
97
+ };
98
+ export default {
99
+ init: initWidget,
100
+ destroy: destroyWidget,
101
+ setTheme: setWidgetTheme,
102
+ setColorMode: setWidgetColorMode,
103
+ setPosition: setWidgetPosition,
104
+ };
@@ -0,0 +1,4 @@
1
+ import type { WidgetOptions } from './index';
2
+ export type HyperCRMWidgetProps = WidgetOptions;
3
+ export declare const useHyperCRMWidget: (options?: HyperCRMWidgetProps) => void;
4
+ export declare const HyperCRMWidget: (props: HyperCRMWidgetProps) => any;
package/dist/react.js ADDED
@@ -0,0 +1,65 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import { initWidget, destroyWidget, setWidgetTheme, setWidgetColorMode, setWidgetPosition, } from './index';
3
+ export const useHyperCRMWidget = (options = {}) => {
4
+ const { apiUrl, apiKey, orgId, mount, theme, colorMode, position, autoOpen, debug, scriptUrl, } = options;
5
+ const readyRef = useRef(false);
6
+ const latestRef = useRef({ theme, colorMode, position });
7
+ useEffect(() => {
8
+ latestRef.current = { theme, colorMode, position };
9
+ }, [theme, colorMode, position]);
10
+ useEffect(() => {
11
+ let cancelled = false;
12
+ readyRef.current = false;
13
+ initWidget({
14
+ apiUrl,
15
+ apiKey,
16
+ orgId,
17
+ mount,
18
+ theme: latestRef.current.theme,
19
+ colorMode: latestRef.current.colorMode,
20
+ position: latestRef.current.position,
21
+ autoOpen,
22
+ debug,
23
+ scriptUrl,
24
+ })
25
+ .then(() => {
26
+ if (cancelled)
27
+ return;
28
+ readyRef.current = true;
29
+ const latest = latestRef.current;
30
+ setWidgetTheme(latest.theme || {});
31
+ if (latest.colorMode)
32
+ setWidgetColorMode(latest.colorMode);
33
+ if (latest.position)
34
+ setWidgetPosition(latest.position);
35
+ })
36
+ .catch((err) => {
37
+ if (debug)
38
+ console.warn('[HyperCRMWidget]', err);
39
+ });
40
+ return () => {
41
+ cancelled = true;
42
+ readyRef.current = false;
43
+ destroyWidget();
44
+ };
45
+ }, [apiUrl, apiKey, orgId, mount, autoOpen, debug, scriptUrl]);
46
+ useEffect(() => {
47
+ if (!readyRef.current)
48
+ return;
49
+ setWidgetTheme(theme || {});
50
+ }, [theme]);
51
+ useEffect(() => {
52
+ if (!readyRef.current || !colorMode)
53
+ return;
54
+ setWidgetColorMode(colorMode);
55
+ }, [colorMode]);
56
+ useEffect(() => {
57
+ if (!readyRef.current || !position)
58
+ return;
59
+ setWidgetPosition(position);
60
+ }, [position]);
61
+ };
62
+ export const HyperCRMWidget = (props) => {
63
+ useHyperCRMWidget(props);
64
+ return null;
65
+ };
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "hypercrm",
3
+ "version": "1.0.1",
4
+ "description": "HyperCRM widget loader with optional React component.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ },
13
+ "./react": {
14
+ "types": "./dist/react.d.ts",
15
+ "default": "./dist/react.js"
16
+ },
17
+ "./widget.js": "./assets/widget.js"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "assets"
22
+ ],
23
+ "sideEffects": false,
24
+ "peerDependencies": {
25
+ "react": ">=18"
26
+ },
27
+ "peerDependenciesMeta": {
28
+ "react": {
29
+ "optional": true
30
+ }
31
+ },
32
+ "keywords": [
33
+ "hypercrm",
34
+ "support",
35
+ "widget"
36
+ ],
37
+ "license": "MIT",
38
+ "publishConfig": {
39
+ "access": "public"
40
+ }
41
+ }