@enfyra/sdk-nuxt 0.3.29 → 0.4.2

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/module.cjs CHANGED
@@ -67,6 +67,10 @@ enfyraSDK: {
67
67
  {
68
68
  name: "useEnfyraAuth",
69
69
  from: resolve("./runtime/composables/useEnfyraAuth")
70
+ },
71
+ {
72
+ name: "useEnfyraWebSocket",
73
+ from: resolve("./runtime/composables/useEnfyraWebSocket")
70
74
  }
71
75
  ]);
72
76
  kit.addTypeTemplate({
@@ -81,6 +85,15 @@ declare module '#imports' {
81
85
  export function useEnfyra(): UseEnfyraReturn
82
86
 
83
87
  export function useEnfyraAuth(): import('@enfyra/sdk-nuxt/types').UseEnfyraAuthReturn
88
+
89
+ export function useEnfyraWebSocket(options: { path: string; reconnect?: boolean; reconnectInterval?: number; maxReconnectAttempts?: number }): {
90
+ connect: () => WebSocket
91
+ send: (event: string, data?: any) => void
92
+ close: () => void
93
+ getWebSocket: () => WebSocket | null
94
+ on: (event: 'message' | 'open' | 'close' | 'error', callback: (...args: any[]) => void) => void
95
+ off: (event: 'message' | 'open' | 'close' | 'error', callback: (...args: any[]) => void) => void
96
+ }
84
97
  }
85
98
  `
86
99
  });
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;;AAED,wBA6HG"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;;AAED,wBA0IG"}
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.0.0"
6
6
  },
7
- "version": "0.3.29",
7
+ "version": "0.4.2",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "0.8.4",
10
10
  "unbuild": "2.0.0"
package/dist/module.mjs CHANGED
@@ -64,6 +64,10 @@ enfyraSDK: {
64
64
  {
65
65
  name: "useEnfyraAuth",
66
66
  from: resolve("./runtime/composables/useEnfyraAuth")
67
+ },
68
+ {
69
+ name: "useEnfyraWebSocket",
70
+ from: resolve("./runtime/composables/useEnfyraWebSocket")
67
71
  }
68
72
  ]);
69
73
  addTypeTemplate({
@@ -78,6 +82,15 @@ declare module '#imports' {
78
82
  export function useEnfyra(): UseEnfyraReturn
79
83
 
80
84
  export function useEnfyraAuth(): import('@enfyra/sdk-nuxt/types').UseEnfyraAuthReturn
85
+
86
+ export function useEnfyraWebSocket(options: { path: string; reconnect?: boolean; reconnectInterval?: number; maxReconnectAttempts?: number }): {
87
+ connect: () => WebSocket
88
+ send: (event: string, data?: any) => void
89
+ close: () => void
90
+ getWebSocket: () => WebSocket | null
91
+ on: (event: 'message' | 'open' | 'close' | 'error', callback: (...args: any[]) => void) => void
92
+ off: (event: 'message' | 'open' | 'close' | 'error', callback: (...args: any[]) => void) => void
93
+ }
81
94
  }
82
95
  `
83
96
  });
@@ -0,0 +1,16 @@
1
+ export interface EnfyraWebSocketOptions {
2
+ path: string;
3
+ reconnect?: boolean;
4
+ reconnectInterval?: number;
5
+ maxReconnectAttempts?: number;
6
+ }
7
+ export interface EnfyraWebSocketReturn {
8
+ connect: () => WebSocket;
9
+ send: (event: string, data?: any) => void;
10
+ close: () => void;
11
+ getWebSocket: () => WebSocket | null;
12
+ on: (event: 'message' | 'open' | 'close' | 'error', callback: (...args: any[]) => void) => void;
13
+ off: (event: 'message' | 'open' | 'close' | 'error', callback: (...args: any[]) => void) => void;
14
+ }
15
+ export declare function useEnfyraWebSocket(options: EnfyraWebSocketOptions): EnfyraWebSocketReturn;
16
+ //# sourceMappingURL=useEnfyraWebSocket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEnfyraWebSocket.d.ts","sourceRoot":"","sources":["../../../src/runtime/composables/useEnfyraWebSocket.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,SAAS,CAAC;IACzB,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC1C,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,YAAY,EAAE,MAAM,SAAS,GAAG,IAAI,CAAC;IACrC,EAAE,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC;IAChG,GAAG,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC;CAClG;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CAiGzF"}
@@ -0,0 +1,84 @@
1
+ import { useRuntimeConfig } from "#imports";
2
+ import { normalizeUrl } from "../utils/url.js";
3
+ export function useEnfyraWebSocket(options) {
4
+ const config = useRuntimeConfig().public.enfyraSDK;
5
+ const apiUrl = config?.apiUrl || process.env.API_URL || "http://localhost:1105";
6
+ let ws = null;
7
+ let reconnectTimer = null;
8
+ let reconnectAttempts = 0;
9
+ const listeners = /* @__PURE__ */ new Map();
10
+ const getWsUrl = (path) => {
11
+ const url = apiUrl.replace(/^http/, "ws");
12
+ return normalizeUrl(url, path);
13
+ };
14
+ const connect = () => {
15
+ if (ws && ws.readyState === WebSocket.OPEN) {
16
+ return ws;
17
+ }
18
+ ws = new WebSocket(getWsUrl(options.path));
19
+ ws.onopen = () => {
20
+ reconnectAttempts = 0;
21
+ emit("open");
22
+ };
23
+ ws.onmessage = (event) => {
24
+ emit("message", event.data);
25
+ };
26
+ ws.onclose = () => {
27
+ emit("close");
28
+ if (options.reconnect && (!options.maxReconnectAttempts || reconnectAttempts < (options.maxReconnectAttempts || 5))) {
29
+ reconnectTimer = setTimeout(() => {
30
+ reconnectAttempts++;
31
+ connect();
32
+ }, options.reconnectInterval || 3e3);
33
+ }
34
+ };
35
+ ws.onerror = (error) => {
36
+ emit("error", error);
37
+ };
38
+ return ws;
39
+ };
40
+ const send = (event, data) => {
41
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
42
+ throw new Error("WebSocket is not connected");
43
+ }
44
+ const payload = data !== void 0 ? { event, data } : { event };
45
+ ws.send(JSON.stringify(payload));
46
+ };
47
+ const close = () => {
48
+ if (reconnectTimer) {
49
+ clearTimeout(reconnectTimer);
50
+ reconnectTimer = null;
51
+ }
52
+ if (ws) {
53
+ ws.close();
54
+ ws = null;
55
+ }
56
+ };
57
+ const getWebSocket = () => ws;
58
+ const on = (event, callback) => {
59
+ if (!listeners.has(event)) {
60
+ listeners.set(event, /* @__PURE__ */ new Set());
61
+ }
62
+ listeners.get(event).add(callback);
63
+ };
64
+ const off = (event, callback) => {
65
+ const eventListeners = listeners.get(event);
66
+ if (eventListeners) {
67
+ eventListeners.delete(callback);
68
+ }
69
+ };
70
+ const emit = (event, ...args) => {
71
+ const eventListeners = listeners.get(event);
72
+ if (eventListeners) {
73
+ eventListeners.forEach((callback) => callback(...args));
74
+ }
75
+ };
76
+ return {
77
+ connect,
78
+ send,
79
+ close,
80
+ getWebSocket,
81
+ on,
82
+ off
83
+ };
84
+ }
@@ -1,3 +1,3 @@
1
1
  import { H3Event } from "h3";
2
- export declare function proxyToAPI(event: H3Event, customPath?: string): Promise<any> | undefined;
2
+ export declare function proxyToAPI(event: H3Event, customPath?: string): Promise<any>;
3
3
  //# sourceMappingURL=proxy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../../../src/runtime/utils/server/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAgB,MAAM,IAAI,CAAC;AAa3C,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,4BAmC7D"}
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../../../src/runtime/utils/server/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAgB,MAAM,IAAI,CAAC;AAK3C,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,gBAY7D"}
@@ -1,32 +1,13 @@
1
1
  import { proxyRequest } from "h3";
2
- import { createProxy } from "http-proxy";
3
2
  import { useRuntimeConfig } from "#imports";
4
3
  import { ENFYRA_API_PREFIX } from "../../constants/config.js";
5
4
  import { normalizeUrl } from "../url.js";
6
- const proxy = createProxy({
7
- target: process.env.API_URL || "http://localhost:1105",
8
- ws: true,
9
- changeOrigin: true
10
- });
11
5
  export function proxyToAPI(event, customPath) {
12
6
  const config = useRuntimeConfig();
13
7
  const apiPrefix = config.public?.enfyraSDK?.apiPrefix || ENFYRA_API_PREFIX;
14
8
  const rawPath = customPath || event.path.replace(new RegExp(`^${apiPrefix}`), "");
15
9
  const targetUrl = normalizeUrl(config.public?.enfyraSDK?.apiUrl, rawPath);
16
10
  const headers = event.context.proxyHeaders || {};
17
- const isWebSocket = event.node.req.headers["upgrade"]?.toLowerCase() === "websocket";
18
- if (isWebSocket) {
19
- const originalUrl = event.node.req.url || "";
20
- event.node.req.url = rawPath;
21
- proxy.web(event.node.req, event.node.res, {
22
- target: config.public?.enfyraSDK?.apiUrl || process.env.API_URL || "http://localhost:1105",
23
- ws: true,
24
- changeOrigin: true,
25
- headers
26
- });
27
- event.node.req.url = originalUrl;
28
- return void 0;
29
- }
30
11
  return proxyRequest(event, targetUrl, {
31
12
  headers
32
13
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enfyra/sdk-nuxt",
3
- "version": "0.3.29",
3
+ "version": "0.4.2",
4
4
  "type": "module",
5
5
  "description": "Nuxt SDK for Enfyra CMS",
6
6
  "repository": {
package/src/module.ts CHANGED
@@ -96,6 +96,10 @@ export default defineNuxtModule<ModuleOptions>({
96
96
  name: "useEnfyraAuth",
97
97
  from: resolve("./runtime/composables/useEnfyraAuth"),
98
98
  },
99
+ {
100
+ name: "useEnfyraWebSocket",
101
+ from: resolve("./runtime/composables/useEnfyraWebSocket"),
102
+ },
99
103
  ]);
100
104
  addTypeTemplate({
101
105
  filename: "types/enfyra-sdk.d.ts",
@@ -109,6 +113,15 @@ declare module '#imports' {
109
113
  export function useEnfyra(): UseEnfyraReturn
110
114
 
111
115
  export function useEnfyraAuth(): import('@enfyra/sdk-nuxt/types').UseEnfyraAuthReturn
116
+
117
+ export function useEnfyraWebSocket(options: { path: string; reconnect?: boolean; reconnectInterval?: number; maxReconnectAttempts?: number }): {
118
+ connect: () => WebSocket
119
+ send: (event: string, data?: any) => void
120
+ close: () => void
121
+ getWebSocket: () => WebSocket | null
122
+ on: (event: 'message' | 'open' | 'close' | 'error', callback: (...args: any[]) => void) => void
123
+ off: (event: 'message' | 'open' | 'close' | 'error', callback: (...args: any[]) => void) => void
124
+ }
112
125
  }
113
126
  `,
114
127
  });
@@ -0,0 +1,117 @@
1
+ import { useRuntimeConfig } from "#imports";
2
+ import { normalizeUrl } from "../utils/url";
3
+
4
+ export interface EnfyraWebSocketOptions {
5
+ path: string;
6
+ reconnect?: boolean;
7
+ reconnectInterval?: number;
8
+ maxReconnectAttempts?: number;
9
+ }
10
+
11
+ export interface EnfyraWebSocketReturn {
12
+ connect: () => WebSocket;
13
+ send: (event: string, data?: any) => void;
14
+ close: () => void;
15
+ getWebSocket: () => WebSocket | null;
16
+ on: (event: 'message' | 'open' | 'close' | 'error', callback: (...args: any[]) => void) => void;
17
+ off: (event: 'message' | 'open' | 'close' | 'error', callback: (...args: any[]) => void) => void;
18
+ }
19
+
20
+ export function useEnfyraWebSocket(options: EnfyraWebSocketOptions): EnfyraWebSocketReturn {
21
+ const config = useRuntimeConfig().public.enfyraSDK;
22
+ const apiUrl = config?.apiUrl || process.env.API_URL || 'http://localhost:1105';
23
+
24
+ let ws: WebSocket | null = null;
25
+ let reconnectTimer: ReturnType<typeof setTimeout> | null = null;
26
+ let reconnectAttempts = 0;
27
+ const listeners: Map<string, Set<(...args: any[]) => void>> = new Map();
28
+
29
+ const getWsUrl = (path: string): string => {
30
+ const url = apiUrl.replace(/^http/, 'ws');
31
+ return normalizeUrl(url, path);
32
+ };
33
+
34
+ const connect = (): WebSocket => {
35
+ if (ws && ws.readyState === WebSocket.OPEN) {
36
+ return ws;
37
+ }
38
+
39
+ ws = new WebSocket(getWsUrl(options.path));
40
+
41
+ ws.onopen = () => {
42
+ reconnectAttempts = 0;
43
+ emit('open');
44
+ };
45
+
46
+ ws.onmessage = (event: MessageEvent) => {
47
+ emit('message', event.data);
48
+ };
49
+
50
+ ws.onclose = () => {
51
+ emit('close');
52
+ if (options.reconnect && (!options.maxReconnectAttempts || reconnectAttempts < (options.maxReconnectAttempts || 5))) {
53
+ reconnectTimer = setTimeout(() => {
54
+ reconnectAttempts++;
55
+ connect();
56
+ }, options.reconnectInterval || 3000);
57
+ }
58
+ };
59
+
60
+ ws.onerror = (error: Event) => {
61
+ emit('error', error);
62
+ };
63
+
64
+ return ws;
65
+ };
66
+
67
+ const send = (event: string, data?: any): void => {
68
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
69
+ throw new Error('WebSocket is not connected');
70
+ }
71
+ const payload = data !== undefined ? { event, data } : { event };
72
+ ws.send(JSON.stringify(payload));
73
+ };
74
+
75
+ const close = (): void => {
76
+ if (reconnectTimer) {
77
+ clearTimeout(reconnectTimer);
78
+ reconnectTimer = null;
79
+ }
80
+ if (ws) {
81
+ ws.close();
82
+ ws = null;
83
+ }
84
+ };
85
+
86
+ const getWebSocket = (): WebSocket | null => ws;
87
+
88
+ const on = (event: 'message' | 'open' | 'close' | 'error', callback: (...args: any[]) => void): void => {
89
+ if (!listeners.has(event)) {
90
+ listeners.set(event, new Set());
91
+ }
92
+ listeners.get(event)!.add(callback);
93
+ };
94
+
95
+ const off = (event: 'message' | 'open' | 'close' | 'error', callback: (...args: any[]) => void): void => {
96
+ const eventListeners = listeners.get(event);
97
+ if (eventListeners) {
98
+ eventListeners.delete(callback);
99
+ }
100
+ };
101
+
102
+ const emit = (event: string, ...args: any[]): void => {
103
+ const eventListeners = listeners.get(event);
104
+ if (eventListeners) {
105
+ eventListeners.forEach(callback => callback(...args));
106
+ }
107
+ };
108
+
109
+ return {
110
+ connect,
111
+ send,
112
+ close,
113
+ getWebSocket,
114
+ on,
115
+ off,
116
+ };
117
+ }
@@ -1,16 +1,8 @@
1
1
  import { H3Event, proxyRequest } from "h3";
2
- import { createProxy } from "http-proxy";
3
2
  import { useRuntimeConfig } from "#imports";
4
3
  import { ENFYRA_API_PREFIX } from "../../constants/config";
5
4
  import { normalizeUrl } from "../url";
6
5
 
7
- // Create proxy instance (reuse for performance)
8
- const proxy = createProxy({
9
- target: process.env.API_URL || 'http://localhost:1105',
10
- ws: true,
11
- changeOrigin: true,
12
- });
13
-
14
6
  export function proxyToAPI(event: H3Event, customPath?: string) {
15
7
  const config = useRuntimeConfig();
16
8
  const apiPrefix = config.public?.enfyraSDK?.apiPrefix || ENFYRA_API_PREFIX;
@@ -20,29 +12,6 @@ export function proxyToAPI(event: H3Event, customPath?: string) {
20
12
 
21
13
  const headers = event.context.proxyHeaders || {};
22
14
 
23
- // Detect WebSocket upgrade request
24
- const isWebSocket = event.node.req.headers['upgrade']?.toLowerCase() === 'websocket';
25
-
26
- if (isWebSocket) {
27
- // Modify req.url to remove the apiPrefix before proxying
28
- // The incoming request is /api/chat/test-room but backend expects /chat/test-room
29
- const originalUrl = event.node.req.url || '';
30
- event.node.req.url = rawPath;
31
-
32
- // For WebSocket, use http-proxy directly
33
- proxy.web(event.node.req, event.node.res, {
34
- target: config.public?.enfyraSDK?.apiUrl || process.env.API_URL || 'http://localhost:1105',
35
- ws: true,
36
- changeOrigin: true,
37
- headers,
38
- });
39
-
40
- // Restore original url
41
- event.node.req.url = originalUrl;
42
- // Return undefined to signal we've handled the response asynchronously
43
- return undefined;
44
- }
45
-
46
15
  return proxyRequest(event, targetUrl, {
47
16
  headers,
48
17
  });