topsyde-utils 1.0.207 → 1.0.209
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/client/api/base.api.d.ts +63 -0
- package/dist/client/api/base.api.js +61 -0
- package/dist/client/api/base.api.js.map +1 -0
- package/dist/client/api/index.d.ts +2 -0
- package/dist/client/api/index.js +5 -0
- package/dist/client/api/index.js.map +1 -0
- package/dist/external/index.d.ts +1 -0
- package/dist/external/index.js +4 -0
- package/dist/external/index.js.map +1 -0
- package/dist/external/re-exports.d.ts +16 -0
- package/dist/external/re-exports.js +24 -0
- package/dist/external/re-exports.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/server/bun/websocket/Websocket.js +2 -2
- package/dist/server/bun/websocket/Websocket.js.map +1 -1
- package/package.json +16 -1
- package/src/client/api/base.api.ts +111 -0
- package/src/client/api/index.ts +5 -0
- package/src/external/index.ts +4 -0
- package/src/external/re-exports.ts +54 -0
- package/src/index.ts +24 -0
- package/src/server/bun/websocket/Websocket.ts +14 -8
@@ -0,0 +1,63 @@
|
|
1
|
+
import { AxiosResponse } from "axios";
|
2
|
+
declare class BaseAPI {
|
3
|
+
private api;
|
4
|
+
protected controller: string;
|
5
|
+
protected base_url: string;
|
6
|
+
constructor(controller: string, base_url?: string);
|
7
|
+
private initAxios;
|
8
|
+
static Status(response: AxiosResponse<{
|
9
|
+
status: boolean;
|
10
|
+
}>): void;
|
11
|
+
/**
|
12
|
+
* @description Axios GET request wrapper
|
13
|
+
* @param endpoint string
|
14
|
+
* @generic T
|
15
|
+
* @returns Promise<AxiosResponse<T>>
|
16
|
+
*/
|
17
|
+
get<T extends {
|
18
|
+
status: boolean;
|
19
|
+
}>(endpoint: string): Promise<AxiosResponse<T>>;
|
20
|
+
/**
|
21
|
+
* @description Axios GET request wrapper
|
22
|
+
* @param controller string - which controller to use
|
23
|
+
* @param endpoint string - controller action to call
|
24
|
+
* @generic T
|
25
|
+
* @returns Promise<AxiosResponse<T>>
|
26
|
+
*/
|
27
|
+
get<T extends {
|
28
|
+
status: boolean;
|
29
|
+
}>(controller: string, endpoint: string): Promise<AxiosResponse<T>>;
|
30
|
+
/**
|
31
|
+
* @description Axios GET request wrapper
|
32
|
+
* @param controller string - which controller to use
|
33
|
+
* @param endpoint string - controller action to call
|
34
|
+
* @param debounceDelay number - debounce delay
|
35
|
+
* @generic T
|
36
|
+
* @returns Promise<AxiosResponse<T>>
|
37
|
+
*/
|
38
|
+
get<T extends {
|
39
|
+
status: boolean;
|
40
|
+
}>(controller: string, endpoint: string, debounceDelay?: number): Promise<AxiosResponse<T>>;
|
41
|
+
/**
|
42
|
+
* @description Axios POST request wrapper
|
43
|
+
* @param endpoint string - controller action to call
|
44
|
+
* @param payload any
|
45
|
+
* @generic T
|
46
|
+
* @returns Promise<AxiosResponse<T>>
|
47
|
+
*/
|
48
|
+
post<T extends {
|
49
|
+
status: boolean;
|
50
|
+
}>(endpoint: string, payload: any): Promise<AxiosResponse<T>>;
|
51
|
+
/**
|
52
|
+
* @description Axios POST request wrapper
|
53
|
+
* @param controller string - which controller to use
|
54
|
+
* @param endpoint string - controller action to call
|
55
|
+
* @param payload any
|
56
|
+
* @generic T
|
57
|
+
* @returns Promise<AxiosResponse<T>>
|
58
|
+
*/
|
59
|
+
post<T extends {
|
60
|
+
status: boolean;
|
61
|
+
}>(controller: string, endpoint: string, payload: any): Promise<AxiosResponse<T>>;
|
62
|
+
}
|
63
|
+
export default BaseAPI;
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import Axios, { isAxiosError } from "axios";
|
2
|
+
class BaseAPI {
|
3
|
+
constructor(controller, base_url) {
|
4
|
+
this.controller = controller;
|
5
|
+
this.base_url = base_url || import.meta.env.VITE_HOST || "";
|
6
|
+
this.api = this.initAxios();
|
7
|
+
}
|
8
|
+
initAxios() {
|
9
|
+
const config = {
|
10
|
+
headers: {
|
11
|
+
"Content-Type": "application/json",
|
12
|
+
},
|
13
|
+
};
|
14
|
+
const instance = Axios.create(config);
|
15
|
+
// Add interceptor to modify request config
|
16
|
+
instance.interceptors.request.use((config) => {
|
17
|
+
// Ensure the correct content type
|
18
|
+
config.headers["Content-Type"] = "application/json";
|
19
|
+
return config;
|
20
|
+
});
|
21
|
+
return instance;
|
22
|
+
}
|
23
|
+
static Status(response) {
|
24
|
+
if (!response.data.status)
|
25
|
+
throw new Error("Something went wrong");
|
26
|
+
}
|
27
|
+
async get(controllerOrEndpoint, endpoint, _debounceDelay) {
|
28
|
+
let controller = endpoint ? controllerOrEndpoint : this.controller;
|
29
|
+
let action = endpoint ? endpoint : controllerOrEndpoint;
|
30
|
+
return this.api.get(`${this.base_url}/${controller}/${action}`).catch((err) => {
|
31
|
+
if (isAxiosError(err))
|
32
|
+
throw err.response;
|
33
|
+
throw err;
|
34
|
+
});
|
35
|
+
}
|
36
|
+
async post(controllerOrEndpoint, endpointOrPayload, payload) {
|
37
|
+
let controller;
|
38
|
+
let action;
|
39
|
+
let data;
|
40
|
+
if (payload !== null && payload !== undefined) {
|
41
|
+
controller = controllerOrEndpoint;
|
42
|
+
action = endpointOrPayload;
|
43
|
+
data = payload;
|
44
|
+
}
|
45
|
+
else {
|
46
|
+
controller = this.controller;
|
47
|
+
action = controllerOrEndpoint;
|
48
|
+
data = endpointOrPayload;
|
49
|
+
}
|
50
|
+
const response = await this.api.post(`${this.base_url}/${controller}/${action}`, data).catch((err) => {
|
51
|
+
if (isAxiosError(err))
|
52
|
+
throw err.response;
|
53
|
+
throw err;
|
54
|
+
});
|
55
|
+
if (!response.data.status)
|
56
|
+
throw new Error("Something went wrong");
|
57
|
+
return response;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
export default BaseAPI;
|
61
|
+
//# sourceMappingURL=base.api.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"base.api.js","sourceRoot":"","sources":["../../../src/client/api/base.api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAoD,YAAY,EAAE,MAAM,OAAO,CAAC;AAC9F,MAAM,OAAO;IAKZ,YAAY,UAAkB,EAAE,QAAiB;QAChD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC;QAC5D,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;IAC7B,CAAC;IAEO,SAAS;QAChB,MAAM,MAAM,GAAuB;YAClC,OAAO,EAAE;gBACR,cAAc,EAAE,kBAAkB;aAClC;SACD,CAAC;QAEF,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAEtC,2CAA2C;QAC3C,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC5C,kCAAkC;YAClC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAEpD,OAAO,MAAM,CAAC;QACf,CAAC,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC;IACjB,CAAC;IAEM,MAAM,CAAC,MAAM,CAAC,QAA4C;QAChE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACpE,CAAC;IA0BD,KAAK,CAAC,GAAG,CAAgC,oBAA4B,EAAE,QAA6B,EAAE,cAAuB;QAC5H,IAAI,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QACnE,IAAI,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,oBAAoB,CAAC;QAExD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,UAAU,IAAI,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YAChF,IAAI,YAAY,CAAC,GAAG,CAAC;gBAAE,MAAM,GAAG,CAAC,QAAQ,CAAC;YAC1C,MAAM,GAAG,CAAC;QACX,CAAC,CAAC,CAAC;IACJ,CAAC;IAmBD,KAAK,CAAC,IAAI,CAAgC,oBAA4B,EAAE,iBAA+B,EAAE,OAAa;QACrH,IAAI,UAAkB,CAAC;QACvB,IAAI,MAAc,CAAC;QACnB,IAAI,IAAS,CAAC;QAEd,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/C,UAAU,GAAG,oBAAoB,CAAC;YAClC,MAAM,GAAG,iBAAiB,CAAC;YAC3B,IAAI,GAAG,OAAO,CAAC;QAChB,CAAC;aAAM,CAAC;YACP,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;YAC7B,MAAM,GAAG,oBAAoB,CAAC;YAC9B,IAAI,GAAG,iBAAiB,CAAC;QAC1B,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,UAAU,IAAI,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACvG,IAAI,YAAY,CAAC,GAAG,CAAC;gBAAE,MAAM,GAAG,CAAC,QAAQ,CAAC;YAC1C,MAAM,GAAG,CAAC;QACX,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACnE,OAAO,QAAQ,CAAC;IACjB,CAAC;CACD;AAED,eAAe,OAAO,CAAC","sourcesContent":["import Axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, isAxiosError } from \"axios\";\nclass BaseAPI {\n\tprivate api: AxiosInstance;\n\tprotected controller: string;\n\tprotected base_url: string;\n\n\tconstructor(controller: string, base_url?: string) {\n\t\tthis.controller = controller;\n\t\tthis.base_url = base_url || import.meta.env.VITE_HOST || \"\";\n\t\tthis.api = this.initAxios();\n\t}\n\n\tprivate initAxios(): AxiosInstance {\n\t\tconst config: AxiosRequestConfig = {\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t};\n\n\t\tconst instance = Axios.create(config);\n\n\t\t// Add interceptor to modify request config\n\t\tinstance.interceptors.request.use((config) => {\n\t\t\t// Ensure the correct content type\n\t\t\tconfig.headers[\"Content-Type\"] = \"application/json\";\n\n\t\t\treturn config;\n\t\t});\n\n\t\treturn instance;\n\t}\n\n\tpublic static Status(response: AxiosResponse<{ status: boolean }>) {\n\t\tif (!response.data.status) throw new Error(\"Something went wrong\");\n\t}\n\n\t/**\n\t * @description Axios GET request wrapper\n\t * @param endpoint string\n\t * @generic T\n\t * @returns Promise<AxiosResponse<T>>\n\t */\n\tasync get<T extends { status: boolean }>(endpoint: string): Promise<AxiosResponse<T>>;\n\t/**\n\t * @description Axios GET request wrapper\n\t * @param controller string - which controller to use\n\t * @param endpoint string - controller action to call\n\t * @generic T\n\t * @returns Promise<AxiosResponse<T>>\n\t */\n\tasync get<T extends { status: boolean }>(controller: string, endpoint: string): Promise<AxiosResponse<T>>;\n\t/**\n\t * @description Axios GET request wrapper\n\t * @param controller string - which controller to use\n\t * @param endpoint string - controller action to call\n\t * @param debounceDelay number - debounce delay\n\t * @generic T\n\t * @returns Promise<AxiosResponse<T>>\n\t */\n\tasync get<T extends { status: boolean }>(controller: string, endpoint: string, debounceDelay?: number): Promise<AxiosResponse<T>>;\n\tasync get<T extends { status: boolean }>(controllerOrEndpoint: string, endpoint?: string | undefined, _debounceDelay?: number): Promise<AxiosResponse<T>> {\n\t\tlet controller = endpoint ? controllerOrEndpoint : this.controller;\n\t\tlet action = endpoint ? endpoint : controllerOrEndpoint;\n\n\t\treturn this.api.get<T>(`${this.base_url}/${controller}/${action}`).catch((err) => {\n\t\t\tif (isAxiosError(err)) throw err.response;\n\t\t\tthrow err;\n\t\t});\n\t}\n\n\t/**\n\t * @description Axios POST request wrapper\n\t * @param endpoint string - controller action to call\n\t * @param payload any\n\t * @generic T\n\t * @returns Promise<AxiosResponse<T>>\n\t */\n\tasync post<T extends { status: boolean }>(endpoint: string, payload: any): Promise<AxiosResponse<T>>;\n\t/**\n\t * @description Axios POST request wrapper\n\t * @param controller string - which controller to use\n\t * @param endpoint string - controller action to call\n\t * @param payload any\n\t * @generic T\n\t * @returns Promise<AxiosResponse<T>>\n\t */\n\tasync post<T extends { status: boolean }>(controller: string, endpoint: string, payload: any): Promise<AxiosResponse<T>>;\n\tasync post<T extends { status: boolean }>(controllerOrEndpoint: string, endpointOrPayload: string | any, payload?: any): Promise<AxiosResponse<T>> {\n\t\tlet controller: string;\n\t\tlet action: string;\n\t\tlet data: any;\n\n\t\tif (payload !== null && payload !== undefined) {\n\t\t\tcontroller = controllerOrEndpoint;\n\t\t\taction = endpointOrPayload;\n\t\t\tdata = payload;\n\t\t} else {\n\t\t\tcontroller = this.controller;\n\t\t\taction = controllerOrEndpoint;\n\t\t\tdata = endpointOrPayload;\n\t\t}\n\t\tconst response = await this.api.post<T>(`${this.base_url}/${controller}/${action}`, data).catch((err) => {\n\t\t\tif (isAxiosError(err)) throw err.response;\n\t\t\tthrow err;\n\t\t});\n\t\tif (!response.data.status) throw new Error(\"Something went wrong\");\n\t\treturn response;\n\t}\n}\n\nexport default BaseAPI;\n"]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/api/index.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,iCAAiC;AAEjC,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,YAAY,CAAC","sourcesContent":["// This file is auto-generated by scripts/generate-indexes.ts\n// Do not edit this file directly\n\nexport * from './base.api';\nexport { default as BaseAPI } from './base.api';\n"]}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './re-exports';
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/external/index.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,iCAAiC;AAEjC,cAAc,cAAc,CAAC","sourcesContent":["// This file is auto-generated by scripts/generate-indexes.ts\n// Do not edit this file directly\n\nexport * from './re-exports';\n"]}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/**
|
2
|
+
* Re-exports of external dependencies for convenience
|
3
|
+
*
|
4
|
+
* This module re-exports commonly used types, classes, and decorators from
|
5
|
+
* class-transformer and class-validator to provide a single import source
|
6
|
+
* for projects using topsyde-utils.
|
7
|
+
*
|
8
|
+
* This prevents the need to separately install these dependencies in
|
9
|
+
* consuming projects, as they're already bundled with topsyde-utils.
|
10
|
+
*/
|
11
|
+
export type { ClassConstructor, ClassTransformOptions } from "class-transformer";
|
12
|
+
export { instanceToPlain, plainToInstance } from "class-transformer";
|
13
|
+
export { Expose } from "class-transformer";
|
14
|
+
export { ValidationError } from "class-validator";
|
15
|
+
export { validateSync } from "class-validator";
|
16
|
+
export { IsArray, IsBoolean, IsDate, IsEnum, IsNumber, IsObject, IsOptional, IsString, Validate, IsAlphanumeric, IsBooleanString, IsDateString, IsDecimal, IsDefined, IsNumberString, IsNotEmpty, IsNotEmptyObject, } from "class-validator";
|
@@ -0,0 +1,24 @@
|
|
1
|
+
/**
|
2
|
+
* Re-exports of external dependencies for convenience
|
3
|
+
*
|
4
|
+
* This module re-exports commonly used types, classes, and decorators from
|
5
|
+
* class-transformer and class-validator to provide a single import source
|
6
|
+
* for projects using topsyde-utils.
|
7
|
+
*
|
8
|
+
* This prevents the need to separately install these dependencies in
|
9
|
+
* consuming projects, as they're already bundled with topsyde-utils.
|
10
|
+
*/
|
11
|
+
// Core transformation functions
|
12
|
+
export { instanceToPlain, plainToInstance } from "class-transformer";
|
13
|
+
// Decorators
|
14
|
+
export { Expose } from "class-transformer";
|
15
|
+
// ============================================================================
|
16
|
+
// class-validator exports
|
17
|
+
// ============================================================================
|
18
|
+
// Types and Classes
|
19
|
+
export { ValidationError } from "class-validator";
|
20
|
+
// Validation function
|
21
|
+
export { validateSync } from "class-validator";
|
22
|
+
// Property decorators
|
23
|
+
export { IsArray, IsBoolean, IsDate, IsEnum, IsNumber, IsObject, IsOptional, IsString, Validate, IsAlphanumeric, IsBooleanString, IsDateString, IsDecimal, IsDefined, IsNumberString, IsNotEmpty, IsNotEmptyObject, } from "class-validator";
|
24
|
+
//# sourceMappingURL=re-exports.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"re-exports.js","sourceRoot":"","sources":["../../src/external/re-exports.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,gCAAgC;AAChC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAErE,aAAa;AACb,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,+EAA+E;AAC/E,0BAA0B;AAC1B,+EAA+E;AAE/E,oBAAoB;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,sBAAsB;AACtB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,sBAAsB;AACtB,OAAO,EACN,OAAO,EACP,SAAS,EACT,MAAM,EACN,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,eAAe,EACf,YAAY,EACZ,SAAS,EACT,SAAS,EACT,cAAc,EACd,UAAU,EACV,gBAAgB,GAChB,MAAM,iBAAiB,CAAC","sourcesContent":["/**\n * Re-exports of external dependencies for convenience\n *\n * This module re-exports commonly used types, classes, and decorators from\n * class-transformer and class-validator to provide a single import source\n * for projects using topsyde-utils.\n *\n * This prevents the need to separately install these dependencies in\n * consuming projects, as they're already bundled with topsyde-utils.\n */\n\n// ============================================================================\n// class-transformer exports\n// ============================================================================\n\n// Types\nexport type { ClassConstructor, ClassTransformOptions } from \"class-transformer\";\n\n// Core transformation functions\nexport { instanceToPlain, plainToInstance } from \"class-transformer\";\n\n// Decorators\nexport { Expose } from \"class-transformer\";\n\n// ============================================================================\n// class-validator exports\n// ============================================================================\n\n// Types and Classes\nexport { ValidationError } from \"class-validator\";\n\n// Validation function\nexport { validateSync } from \"class-validator\";\n\n// Property decorators\nexport {\n\tIsArray,\n\tIsBoolean,\n\tIsDate,\n\tIsEnum,\n\tIsNumber,\n\tIsObject,\n\tIsOptional,\n\tIsString,\n\tValidate,\n\tIsAlphanumeric,\n\tIsBooleanString,\n\tIsDateString,\n\tIsDecimal,\n\tIsDefined,\n\tIsNumberString,\n\tIsNotEmpty,\n\tIsNotEmptyObject,\n} from \"class-validator\";\n"]}
|
package/dist/index.d.ts
CHANGED
@@ -6,8 +6,10 @@ export * from "./consts";
|
|
6
6
|
export * from "./types";
|
7
7
|
export * from "./throwable";
|
8
8
|
export * from "./enums";
|
9
|
+
export * from "./client/api/base.api";
|
9
10
|
export * from "./client/rxjs/useRxjs";
|
10
11
|
export * from "./client/vite/plugins/topsydeUtilsVitePlugin";
|
12
|
+
export * from "./external/re-exports";
|
11
13
|
export * from "./server/controller";
|
12
14
|
export * from "./server/service";
|
13
15
|
export * from "./server/base/base.database";
|
@@ -33,6 +35,7 @@ export { default as Singleton } from "./singleton";
|
|
33
35
|
export { default as Initializable } from "./initializable";
|
34
36
|
export { default as Application } from "./application";
|
35
37
|
export { default as Throwable } from "./throwable";
|
38
|
+
export { default as BaseAPI } from "./client/api/base.api";
|
36
39
|
export { default as TopsydeUtilsVitePlugin } from "./client/vite/plugins/topsydeUtilsVitePlugin";
|
37
40
|
export { default as Controller } from "./server/controller";
|
38
41
|
export { default as Service } from "./server/service";
|
@@ -54,6 +57,7 @@ export { DEFAULT_FALSE_RESPONSE, LOG_COLORS, LOG_ICONS } from "./consts";
|
|
54
57
|
export { ClassConstructor, NonNullableType, ObjectKeys, KVObj, I_ApplicationResponse } from "./types";
|
55
58
|
export { E_IS, E_ENVIRONMENTS } from "./enums";
|
56
59
|
export { RxjsDataType, NamespaceActions, MultiNamespaceActions } from "./client/rxjs/useRxjs";
|
60
|
+
export { Expose, ValidationError, IsArray, IsBoolean, IsDate, IsEnum, IsNumber, IsObject, IsOptional, IsString, Validate, IsAlphanumeric, IsBooleanString, IsDateString, IsDecimal, IsDefined, IsNumberString, IsNotEmpty, IsNotEmptyObject, } from "./external/re-exports";
|
57
61
|
export { ControllerResponse, ControllerAction, ControllerMap, ControllerOptions } from "./server/controller";
|
58
62
|
export { Routes } from "./server/bun/router/routes";
|
59
63
|
export { WebsocketConstructorOptions, I_WebsocketConstructor } from "./server/bun/websocket/Websocket";
|
package/dist/index.js
CHANGED
@@ -9,8 +9,10 @@ export * from "./consts.js";
|
|
9
9
|
export * from "./types.js";
|
10
10
|
export * from "./throwable.js";
|
11
11
|
export * from "./enums.js";
|
12
|
+
export * from "./client/api/base.api.js";
|
12
13
|
export * from "./client/rxjs/useRxjs.js";
|
13
14
|
export * from "./client/vite/plugins/topsydeUtilsVitePlugin.js";
|
15
|
+
export * from "./external/re-exports.js";
|
14
16
|
export * from "./server/controller.js";
|
15
17
|
export * from "./server/service.js";
|
16
18
|
export * from "./server/base/base.database.js";
|
@@ -37,6 +39,7 @@ export { default as Singleton } from "./singleton.js";
|
|
37
39
|
export { default as Initializable } from "./initializable.js";
|
38
40
|
export { default as Application } from "./application.js";
|
39
41
|
export { default as Throwable } from "./throwable.js";
|
42
|
+
export { default as BaseAPI } from "./client/api/base.api.js";
|
40
43
|
export { default as TopsydeUtilsVitePlugin } from "./client/vite/plugins/topsydeUtilsVitePlugin.js";
|
41
44
|
export { default as Controller } from "./server/controller.js";
|
42
45
|
export { default as Service } from "./server/service.js";
|
@@ -56,6 +59,7 @@ export { ERROR_CODE, HTTP_ERROR_CODE, WS_ERROR_CODE } from "./errors.js";
|
|
56
59
|
export { RESPONSE_INIT, HEADERS_INIT, RESPONSE_METHOD_OPTIONS } from "./application.js";
|
57
60
|
export { DEFAULT_FALSE_RESPONSE, LOG_COLORS, LOG_ICONS } from "./consts.js";
|
58
61
|
export { E_IS, E_ENVIRONMENTS } from "./enums.js";
|
62
|
+
export { Expose, ValidationError, IsArray, IsBoolean, IsDate, IsEnum, IsNumber, IsObject, IsOptional, IsString, Validate, IsAlphanumeric, IsBooleanString, IsDateString, IsDecimal, IsDefined, IsNumberString, IsNotEmpty, IsNotEmptyObject, } from "./external/re-exports.js";
|
59
63
|
export { E_WebsocketMessageType, E_WebsocketMessagePriority, E_ClientState } from "./server/bun/websocket/websocket.enums.js";
|
60
64
|
export { E_SUBJET_TYPE, AsyncSubject, BehaviorSubject, ReplaySubject, Subject, Subscription } from "./utils/Rxjs.js";
|
61
65
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,iCAAiC;AAEjC,qBAAqB;AACrB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,uBAAuB,CAAC;AACtC,cAAc,8CAA8C,CAAC;AAC7D,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0CAA0C,CAAC;AACzD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qCAAqC,CAAC;AACpD,cAAc,kCAAkC,CAAC;AACjD,cAAc,yCAAyC,CAAC;AACxD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC;AACvD,cAAc,wCAAwC,CAAC;AACvD,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kDAAkD,CAAC;AAEjE,yBAAyB;AACzB,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AACjG,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAErD,sDAAsD;AACtD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEtE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// This file is auto-generated by scripts/generate-indexes.ts\n// Do not edit this file directly\n\n// Export all modules\nexport * from \"./errors\";\nexport * from \"./singleton\";\nexport * from \"./initializable\";\nexport * from \"./application\";\nexport * from \"./consts\";\nexport * from \"./types\";\nexport * from \"./throwable\";\nexport * from \"./enums\";\nexport * from \"./client/api/base.api\";\nexport * from \"./client/rxjs/useRxjs\";\nexport * from \"./client/vite/plugins/topsydeUtilsVitePlugin\";\nexport * from \"./external/re-exports\";\nexport * from \"./server/controller\";\nexport * from \"./server/service\";\nexport * from \"./server/base/base.database\";\nexport * from \"./server/bun/router/controller-discovery\";\nexport * from \"./server/bun/router/routes\";\nexport * from \"./server/bun/router/router\";\nexport * from \"./server/bun/router/router.internal\";\nexport * from \"./server/bun/websocket/Websocket\";\nexport * from \"./server/bun/websocket/websocket.guards\";\nexport * from \"./server/bun/websocket/Message\";\nexport * from \"./server/bun/websocket/Channel\";\nexport * from \"./server/bun/websocket/Client\";\nexport * from \"./server/bun/websocket/websocket.enums\";\nexport * from \"./server/bun/websocket/websocket.types\";\nexport * from \"./utils/Rxjs\";\nexport * from \"./utils/Lib\";\nexport * from \"./utils/Guards\";\nexport * from \"./utils/BaseEntity\";\nexport * from \"./utils/Console\";\nexport * from \"./utils/BaseDto\";\nexport * from \"./utils/dto_validators/IsNumberOrRangeConstraint\";\n\n// Export default classes\nexport { default as Singleton } from \"./singleton\";\nexport { default as Initializable } from \"./initializable\";\nexport { default as Application } from \"./application\";\nexport { default as Throwable } from \"./throwable\";\nexport { default as BaseAPI } from \"./client/api/base.api\";\nexport { default as TopsydeUtilsVitePlugin } from \"./client/vite/plugins/topsydeUtilsVitePlugin\";\nexport { default as Controller } from \"./server/controller\";\nexport { default as Service } from \"./server/service\";\nexport { default as Database } from \"./server/base/base.database\";\nexport { default as Router } from \"./server/bun/router/router\";\nexport { default as Router_Internal } from \"./server/bun/router/router.internal\";\nexport { default as Websocket } from \"./server/bun/websocket/Websocket\";\nexport { default as Message } from \"./server/bun/websocket/Message\";\nexport { default as Channel } from \"./server/bun/websocket/Channel\";\nexport { default as Client } from \"./server/bun/websocket/Client\";\nexport { default as Lib } from \"./utils/Lib\";\nexport { default as Guards } from \"./utils/Guards\";\nexport { default as BaseEntity } from \"./utils/BaseEntity\";\nexport { default as Console } from \"./utils/Console\";\n\n// Re-export specific items for backward compatibility\nexport { ERROR_CODE, HTTP_ERROR_CODE, WS_ERROR_CODE } from \"./errors\";\nexport { InitializableOptions, InitializableEvent } from \"./initializable\";\nexport { RESPONSE_INIT, HEADERS_INIT, RESPONSE_METHOD_OPTIONS } from \"./application\";\nexport { DEFAULT_FALSE_RESPONSE, LOG_COLORS, LOG_ICONS } from \"./consts\";\nexport { ClassConstructor, NonNullableType, ObjectKeys, KVObj, I_ApplicationResponse } from \"./types\";\nexport { E_IS, E_ENVIRONMENTS } from \"./enums\";\nexport { RxjsDataType, NamespaceActions, MultiNamespaceActions } from \"./client/rxjs/useRxjs\";\nexport {\n\tExpose,\n\tValidationError,\n\tIsArray,\n\tIsBoolean,\n\tIsDate,\n\tIsEnum,\n\tIsNumber,\n\tIsObject,\n\tIsOptional,\n\tIsString,\n\tValidate,\n\tIsAlphanumeric,\n\tIsBooleanString,\n\tIsDateString,\n\tIsDecimal,\n\tIsDefined,\n\tIsNumberString,\n\tIsNotEmpty,\n\tIsNotEmptyObject,\n} from \"./external/re-exports\";\nexport { ControllerResponse, ControllerAction, ControllerMap, ControllerOptions } from \"./server/controller\";\nexport { Routes } from \"./server/bun/router/routes\";\nexport { WebsocketConstructorOptions, I_WebsocketConstructor } from \"./server/bun/websocket/Websocket\";\nexport { E_WebsocketMessageType, E_WebsocketMessagePriority, E_ClientState } from \"./server/bun/websocket/websocket.enums\";\nexport {\n\tBunWebsocketMessage,\n\tWebsocketChannel,\n\tWebsocketClients,\n\tWebsocketMessageOptions,\n\tWebsocketMessage,\n\tWebsocketStructuredMessage,\n\tWebsocketEntityId,\n\tWebsocketEntityName,\n\tWebsocketEntityData,\n\tI_WebsocketEntity,\n\tI_WebsocketClient,\n\tI_WebsocketChannelEntity,\n\tBroadcastOptions,\n\tAddMemberResult,\n\tAddMemberOptions,\n\tI_WebsocketChannel,\n\tWebsocketInterfaceHandlers,\n\tI_WebsocketInterface,\n} from \"./server/bun/websocket/websocket.types\";\nexport { E_SUBJET_TYPE, I_RxjsPayload, RxjsNamespaces, AsyncSubject, BehaviorSubject, ReplaySubject, Subject, Subscription } from \"./utils/Rxjs\";\n"]}
|
@@ -46,7 +46,7 @@ export default class Websocket extends Singleton {
|
|
46
46
|
client.send({ type: E_WebsocketMessageType.CLIENT_CONNECTED, content: { message: "Welcome to the server", client: client.whoami() } });
|
47
47
|
// Client handles its own joining logic with rollback support
|
48
48
|
if (!client.joinChannel(global)) {
|
49
|
-
|
49
|
+
throw new Error("Failed to join global channel");
|
50
50
|
}
|
51
51
|
// Mark as fully connected
|
52
52
|
client.markConnected();
|
@@ -268,7 +268,7 @@ export default class Websocket extends Singleton {
|
|
268
268
|
*/
|
269
269
|
static GetConnectedClients() {
|
270
270
|
const ws = this.GetInstance();
|
271
|
-
return Array.from(ws._clients.values()).filter(client => client.state === "connected");
|
271
|
+
return Array.from(ws._clients.values()).filter((client) => client.state === "connected");
|
272
272
|
}
|
273
273
|
/**
|
274
274
|
* Get client statistics by state
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"Websocket.js","sourceRoot":"","sources":["../../../../src/server/bun/websocket/Websocket.ts"],"names":[],"mappings":"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","sourcesContent":["import { Server, ServerWebSocket, WebSocketHandler } from \"bun\";\nimport Singleton from \"../../../singleton\";\nimport { Lib } from \"../../../utils\";\nimport { Console } from \"../../../utils/Console\";\nimport Channel from \"./Channel\";\nimport Client from \"./Client\";\nimport type {\n\tI_WebsocketChannel,\n\tI_WebsocketClient,\n\tI_WebsocketEntity,\n\tI_WebsocketInterface,\n\tWebsocketChannel,\n\tWebsocketEntityData,\n\tBunWebsocketMessage,\n\tWebsocketStructuredMessage,\n} from \"./websocket.types\";\nimport { E_WebsocketMessageType } from \"./websocket.enums\";\n\nexport type WebsocketConstructorOptions = {\n\tdebug?: boolean;\n};\n\nexport interface I_WebsocketConstructor {\n\tws_interface?: I_WebsocketInterface;\n\tchannels?: WebsocketChannel;\n\tclientClass?: typeof Client;\n\tchannelClass?: typeof Channel;\n\toptions?: WebsocketConstructorOptions;\n}\n\n/**\n * Websocket - Singleton managing clients, channels, and message routing\n *\n * ## API Design: Static vs Instance\n * - **Static methods**: Use in application code (e.g., `Websocket.Broadcast()`, `Websocket.GetClient()`)\n * - **Instance methods**: Use when extending the class (e.g., `protected createClient()`)\n *\n * Static methods are facades that call the singleton instance internally.\n *\n * @example\n * // Application code - use static methods\n * Websocket.Broadcast(\"lobby\", { type: \"chat\", content: { message: \"Hi!\" } });\n *\n * // Extension - override instance methods\n * MyWebsocket extends Websocket:\n * protected createClient(entity) {\n * return new MyCustomClient(entity);\n * }\n */\nexport default class Websocket extends Singleton {\n\tprotected _channels: WebsocketChannel;\n\tprotected _clients: Map<string, I_WebsocketClient> = new Map();\n\tprotected _server!: Server;\n\tprotected _channelClass: typeof Channel;\n\tprotected _clientClass: typeof Client;\n\tprotected _ws_interface?: I_WebsocketInterface;\n\tprotected _options: WebsocketConstructorOptions;\n\tprotected _ws_interface_handlers: Partial<WebSocketHandler<WebsocketEntityData>>;\n\n\tprotected constructor(options?: I_WebsocketConstructor) {\n\t\tsuper();\n\t\tthis._ws_interface = options?.ws_interface;\n\t\tthis._channels = options?.channels ?? new Map<string, Channel>();\n\t\tthis._clientClass = options?.clientClass ?? Client;\n\t\tthis._channelClass = options?.channelClass ?? Channel.GetChannelType(options?.channels);\n\t\tthis._options = options?.options ?? { debug: false };\n\t\tthis.createChannel(\"global\", \"Global\", 1000);\n\t\tthis._ws_interface_handlers = this._ws_interface?.handlers(this._channels, this._clients) ?? {};\n\t}\n\n\tprotected set server(value: Server) {\n\t\tthis._server = value;\n\t}\n\n\tpublic get server(): Server {\n\t\treturn this._server;\n\t}\n\n\tpublic set(server: Server) {\n\t\tthis.server = server;\n\t\tConsole.blank();\n\t\tConsole.success(\"Websocket server set\");\n\t}\n\n\t/**\n\t * Create a new channel\n\t * @param id - The id of the channel\n\t * @param name - The name of the channel\n\t * @param limit - The limit of the channel\n\t * @returns The created channel\n\t */\n\tpublic createChannel(id: string, name: string, limit?: number): I_WebsocketChannel {\n\t\tif (this._channels.has(id)) return this._channels.get(id) as I_WebsocketChannel;\n\t\tconst channel = new this._channelClass(id, name, this, limit);\n\t\tthis._channels.set(id, channel);\n\t\treturn channel;\n\t}\n\n\t/**\n\t * Remove a channel\n\t * @param id - The id of the channel\n\t */\n\tpublic removeChannel(id: string) {\n\t\tthis._channels.delete(id);\n\t}\n\n\t/**\n\t * Create a new channel\n\t * @param id - The id of the channel\n\t * @param name - The name of the channel\n\t * @param limit - The limit of the channel\n\t * @returns The created channel\n\t */\n\tpublic static CreateChannel(id: string, name: string, limit?: number) {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn ws.createChannel(id, name, limit);\n\t}\n\n\tpublic handlers(): WebSocketHandler<WebsocketEntityData> {\n\t\treturn {\n\t\t\topen: this.clientConnected,\n\t\t\tmessage: this.clientMessageReceived,\n\t\t\tclose: this.clientDisconnected,\n\t\t};\n\t}\n\n\tprivate clientMessageReceived = (ws: ServerWebSocket<WebsocketEntityData>, message: BunWebsocketMessage) => {\n\t\tif (Websocket.Heartbeat(ws, message)) return;\n\n\t\tif (this._ws_interface_handlers.message) return this._ws_interface_handlers.message(ws, message);\n\n\t\tws.send(\"This is the message from the server: \" + message);\n\t\tWebsocket.BroadCastAll({ type: \"client.message.received\", content: { message } });\n\t};\n\n\tprivate clientConnected = (ws: ServerWebSocket<WebsocketEntityData>) => {\n\t\tif (this._options.debug) Lib.Log(\"[debug] Client connected\", ws.data);\n\n\t\tconst global = this._channels.get(\"global\");\n\t\tif (!global) throw new Error(\"Global channel not found\");\n\n\t\tconst client = Websocket.CreateClient({ id: ws.data.id, ws: ws, name: ws.data.name });\n\t\tthis._clients.set(client.id, client);\n\n\t\tclient.send({ type: E_WebsocketMessageType.CLIENT_CONNECTED, content: { message: \"Welcome to the server\", client: client.whoami() } });\n\n\t\t// Client handles its own joining logic with rollback support\n\t\tif (!client.joinChannel(global)) {\n\t\t\tLib.Warn(`Failed to add client ${client.id} to global channel`);\n\t\t}\n\n\t\t// Mark as fully connected\n\t\tclient.markConnected();\n\n\t\tif (this._ws_interface_handlers.open) this._ws_interface_handlers.open(ws);\n\t};\n\n\tprivate clientDisconnected = (ws: ServerWebSocket<WebsocketEntityData>, code: number, reason: string) => {\n\t\tif (this._options.debug) Lib.Log(\"Client disconnected\", ws.data);\n\n\t\tconst client = this._clients.get(ws.data.id);\n\t\tif (!client) return;\n\n\t\t// Mark as disconnecting\n\t\tclient.markDisconnecting();\n\n\t\tif (this._ws_interface_handlers.close) this._ws_interface_handlers.close(ws, code, reason);\n\n\t\t// Remove from all channels\n\t\tthis._channels.forEach((channel) => {\n\t\t\tchannel.removeMember(client);\n\t\t});\n\n\t\t// Mark as disconnected\n\t\tclient.markDisconnected();\n\n\t\t// Remove from registry\n\t\tthis._clients.delete(ws.data.id);\n\t};\n\n\tprivate handleHeartbeat = (ws: ServerWebSocket<WebsocketEntityData>, message: BunWebsocketMessage) => {\n\t\tif (message === \"ping\") {\n\t\t\tconst pong: WebsocketStructuredMessage = { type: \"pong\", content: { message: \"pong\" } };\n\t\t\tws.send(JSON.stringify(pong));\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t};\n\n\tprotected createClient(entity: I_WebsocketEntity): I_WebsocketClient {\n\t\treturn new this._clientClass(entity);\n\t}\n\n\t/**\n\t * Handle the heartbeat\n\t * @param ws - The websocket\n\t * @param message - The message\n\t * @returns True if the heartbeat was handled, false otherwise\n\t */\n\tpublic static Heartbeat(ws: ServerWebSocket<WebsocketEntityData>, message: BunWebsocketMessage) {\n\t\tconst self = this.GetInstance<Websocket>();\n\t\treturn self.handleHeartbeat(ws, message);\n\t}\n\n\t/**\n\t * Get the server\n\t * @returns The server\n\t */\n\tpublic static Server() {\n\t\treturn this.GetInstance<Websocket>().server;\n\t}\n\n\t/**\n\t * Broadcast a message to a channel\n\t * @param channel - The channel\n\t * @param message - The message\n\t * @param args - The arguments\n\t */\n\tpublic static Broadcast(channel: string, message: WebsocketStructuredMessage, ...args: any[]) {\n\t\t// Get the server from the singleton instance\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\tif (!ws.server) {\n\t\t\tthrow new Error(\"Websocket server not set\");\n\t\t}\n\t\tws.server.publish(channel, JSON.stringify({ message, args }));\n\t}\n\n\t/**\n\t * Broadcast a message to all channels\n\t * @param message - The message\n\t * @param args - The arguments\n\t */\n\tpublic static BroadCastAll(message: WebsocketStructuredMessage, ...args: any[]) {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\tws._channels.forEach((channel) => channel.broadcast(message, ...args));\n\t}\n\n\t/**\n\t * Join a channel\n\t * @param channel - The channel\n\t * @param entity - The entity\n\t */\n\tpublic static Join(channel: string, entity: I_WebsocketEntity) {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\tconst client = ws._clients.get(entity.id);\n\t\tif (!client) return;\n\t\tws._channels.get(channel)?.addMember(client);\n\t}\n\n\t/**\n\t * Leave a channel\n\t * @param channel - The channel\n\t * @param entity - The entity\n\t */\n\tpublic static Leave(channel: string, entity: I_WebsocketEntity) {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\tconst client = ws._clients.get(entity.id);\n\t\tif (!client) return;\n\t\tws._channels.get(channel)?.removeMember(client);\n\t}\n\n\t/**\n\t * Get a client\n\t * @param id - The id of the client\n\t * @param throw_if_nil - Whether to throw an error if the client is not found\n\t * @returns The client\n\t */\n\tpublic static GetClient(id: string, throw_if_nil?: true): I_WebsocketClient;\n\tpublic static GetClient(id: string, throw_if_nil?: false): I_WebsocketClient | undefined;\n\tpublic static GetClient(id: string, throw_if_nil: boolean = true): I_WebsocketClient | undefined {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\tconst client = ws._clients.get(id);\n\t\tif (!client && throw_if_nil) throw new Error(`Client with id ${id} not found`);\n\t\treturn client;\n\t}\n\n\t/**\n\t * Get a channel\n\t * @param id - The id of the channel\n\t * @returns The channel\n\t */\n\tpublic static GetChannel(id: string) {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn ws._channels.get(id);\n\t}\n\n\t/**\n\t * Get all channels\n\t * @returns The channels\n\t */\n\tpublic static GetChannels() {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn Array.from(ws._channels.values());\n\t}\n\n\t/**\n\t * Get all clients\n\t * @returns The clients\n\t */\n\tpublic static GetClients() {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn Array.from(ws._clients.values());\n\t}\n\n\t/**\n\t * Get the number of clients\n\t * @returns The number of clients\n\t */\n\tpublic static GetClientCount() {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn ws._clients.size;\n\t}\n\n\t/**\n\t * Get the number of channels\n\t * @returns The number of channels\n\t */\n\tpublic static GetChannelCount() {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn ws._channels.size;\n\t}\n\n\t/**\n\t * Create a client\n\t * @param entity - The entity\n\t * @returns The created client\n\t */\n\tpublic static CreateClient(entity: I_WebsocketEntity): I_WebsocketClient {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn ws.createClient(entity);\n\t}\n\n\t/**\n\t * Get all connected clients (excluding connecting/disconnecting)\n\t * @returns Array of connected clients\n\t */\n\tpublic static GetConnectedClients(): I_WebsocketClient[] {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn Array.from(ws._clients.values()).filter(\n\t\t\tclient => client.state === \"connected\"\n\t\t);\n\t}\n\n\t/**\n\t * Get client statistics by state\n\t * @returns Object with counts by state\n\t */\n\tpublic static GetClientStats() {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\tconst stats = {\n\t\t\ttotal: ws._clients.size,\n\t\t\tconnecting: 0,\n\t\t\tconnected: 0,\n\t\t\tdisconnecting: 0,\n\t\t\tdisconnected: 0,\n\t\t};\n\n\t\tfor (const client of ws._clients.values()) {\n\t\t\tswitch (client.state) {\n\t\t\t\tcase \"connecting\": stats.connecting++; break;\n\t\t\t\tcase \"connected\": stats.connected++; break;\n\t\t\t\tcase \"disconnecting\": stats.disconnecting++; break;\n\t\t\t\tcase \"disconnected\": stats.disconnected++; break;\n\t\t\t}\n\t\t}\n\n\t\treturn stats;\n\t}\n}\n"]}
|
1
|
+
{"version":3,"file":"Websocket.js","sourceRoot":"","sources":["../../../../src/server/bun/websocket/Websocket.ts"],"names":[],"mappings":"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","sourcesContent":["import { Server, ServerWebSocket, WebSocketHandler } from \"bun\";\nimport Singleton from \"../../../singleton\";\nimport { Lib } from \"../../../utils\";\nimport { Console } from \"../../../utils/Console\";\nimport Channel from \"./Channel\";\nimport Client from \"./Client\";\nimport type {\n\tI_WebsocketChannel,\n\tI_WebsocketClient,\n\tI_WebsocketEntity,\n\tI_WebsocketInterface,\n\tWebsocketChannel,\n\tWebsocketEntityData,\n\tBunWebsocketMessage,\n\tWebsocketStructuredMessage,\n} from \"./websocket.types\";\nimport { E_WebsocketMessageType } from \"./websocket.enums\";\n\nexport type WebsocketConstructorOptions = {\n\tdebug?: boolean;\n};\n\nexport interface I_WebsocketConstructor {\n\tws_interface?: I_WebsocketInterface;\n\tchannels?: WebsocketChannel;\n\tclientClass?: typeof Client;\n\tchannelClass?: typeof Channel;\n\toptions?: WebsocketConstructorOptions;\n}\n\n/**\n * Websocket - Singleton managing clients, channels, and message routing\n *\n * ## API Design: Static vs Instance\n * - **Static methods**: Use in application code (e.g., `Websocket.Broadcast()`, `Websocket.GetClient()`)\n * - **Instance methods**: Use when extending the class (e.g., `protected createClient()`)\n *\n * Static methods are facades that call the singleton instance internally.\n *\n * @example\n * // Application code - use static methods\n * Websocket.Broadcast(\"lobby\", { type: \"chat\", content: { message: \"Hi!\" } });\n *\n * // Extension - override instance methods\n * MyWebsocket extends Websocket:\n * protected createClient(entity) {\n * return new MyCustomClient(entity);\n * }\n */\nexport default class Websocket extends Singleton {\n\tprotected _channels: WebsocketChannel;\n\tprotected _clients: Map<string, I_WebsocketClient> = new Map();\n\tprotected _server!: Server;\n\tprotected _channelClass: typeof Channel;\n\tprotected _clientClass: typeof Client;\n\tprotected _ws_interface?: I_WebsocketInterface;\n\tprotected _options: WebsocketConstructorOptions;\n\tprotected _ws_interface_handlers: Partial<WebSocketHandler<WebsocketEntityData>>;\n\n\tprotected constructor(options?: I_WebsocketConstructor) {\n\t\tsuper();\n\t\tthis._ws_interface = options?.ws_interface;\n\t\tthis._channels = options?.channels ?? new Map<string, Channel>();\n\t\tthis._clientClass = options?.clientClass ?? Client;\n\t\tthis._channelClass = options?.channelClass ?? Channel.GetChannelType(options?.channels);\n\t\tthis._options = options?.options ?? { debug: false };\n\t\tthis.createChannel(\"global\", \"Global\", 1000);\n\t\tthis._ws_interface_handlers = this._ws_interface?.handlers(this._channels, this._clients) ?? {};\n\t}\n\n\tprotected set server(value: Server) {\n\t\tthis._server = value;\n\t}\n\n\tpublic get server(): Server {\n\t\treturn this._server;\n\t}\n\n\tpublic set(server: Server) {\n\t\tthis.server = server;\n\t\tConsole.blank();\n\t\tConsole.success(\"Websocket server set\");\n\t}\n\n\t/**\n\t * Create a new channel\n\t * @param id - The id of the channel\n\t * @param name - The name of the channel\n\t * @param limit - The limit of the channel\n\t * @returns The created channel\n\t */\n\tpublic createChannel(id: string, name: string, limit?: number): I_WebsocketChannel {\n\t\tif (this._channels.has(id)) return this._channels.get(id) as I_WebsocketChannel;\n\t\tconst channel = new this._channelClass(id, name, this, limit);\n\t\tthis._channels.set(id, channel);\n\t\treturn channel;\n\t}\n\n\t/**\n\t * Remove a channel\n\t * @param id - The id of the channel\n\t */\n\tpublic removeChannel(id: string) {\n\t\tthis._channels.delete(id);\n\t}\n\n\t/**\n\t * Create a new channel\n\t * @param id - The id of the channel\n\t * @param name - The name of the channel\n\t * @param limit - The limit of the channel\n\t * @returns The created channel\n\t */\n\tpublic static CreateChannel(id: string, name: string, limit?: number) {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn ws.createChannel(id, name, limit);\n\t}\n\n\tpublic handlers(): WebSocketHandler<WebsocketEntityData> {\n\t\treturn {\n\t\t\topen: this.clientConnected,\n\t\t\tmessage: this.clientMessageReceived,\n\t\t\tclose: this.clientDisconnected,\n\t\t};\n\t}\n\n\tprivate clientMessageReceived = (ws: ServerWebSocket<WebsocketEntityData>, message: BunWebsocketMessage) => {\n\t\tif (Websocket.Heartbeat(ws, message)) return;\n\n\t\tif (this._ws_interface_handlers.message) return this._ws_interface_handlers.message(ws, message);\n\n\t\tws.send(\"This is the message from the server: \" + message);\n\t\tWebsocket.BroadCastAll({ type: \"client.message.received\", content: { message } });\n\t};\n\n\tprivate clientConnected = (ws: ServerWebSocket<WebsocketEntityData>) => {\n\t\tif (this._options.debug) Lib.Log(\"[debug] Client connected\", ws.data);\n\n\t\tconst global = this._channels.get(\"global\");\n\t\tif (!global) throw new Error(\"Global channel not found\");\n\n\t\tconst client = Websocket.CreateClient({ id: ws.data.id, ws: ws, name: ws.data.name });\n\t\tthis._clients.set(client.id, client);\n\n\t\tclient.send({ type: E_WebsocketMessageType.CLIENT_CONNECTED, content: { message: \"Welcome to the server\", client: client.whoami() } });\n\n\t\t// Client handles its own joining logic with rollback support\n\t\tif (!client.joinChannel(global)) {\n\t\t\tthrow new Error(\"Failed to join global channel\");\n\t\t}\n\n\t\t// Mark as fully connected\n\t\tclient.markConnected();\n\n\t\tif (this._ws_interface_handlers.open) this._ws_interface_handlers.open(ws);\n\t};\n\n\tprivate clientDisconnected = (ws: ServerWebSocket<WebsocketEntityData>, code: number, reason: string) => {\n\t\tif (this._options.debug) Lib.Log(\"Client disconnected\", ws.data);\n\n\t\tconst client = this._clients.get(ws.data.id);\n\t\tif (!client) return;\n\n\t\t// Mark as disconnecting\n\t\tclient.markDisconnecting();\n\n\t\tif (this._ws_interface_handlers.close) this._ws_interface_handlers.close(ws, code, reason);\n\n\t\t// Remove from all channels\n\t\tthis._channels.forEach((channel) => {\n\t\t\tchannel.removeMember(client);\n\t\t});\n\n\t\t// Mark as disconnected\n\t\tclient.markDisconnected();\n\n\t\t// Remove from registry\n\t\tthis._clients.delete(ws.data.id);\n\t};\n\n\tprivate handleHeartbeat = (ws: ServerWebSocket<WebsocketEntityData>, message: BunWebsocketMessage) => {\n\t\tif (message === \"ping\") {\n\t\t\tconst pong: WebsocketStructuredMessage = { type: \"pong\", content: { message: \"pong\" } };\n\t\t\tws.send(JSON.stringify(pong));\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t};\n\n\tprotected createClient(entity: I_WebsocketEntity): I_WebsocketClient {\n\t\treturn new this._clientClass(entity);\n\t}\n\n\t/**\n\t * Handle the heartbeat\n\t * @param ws - The websocket\n\t * @param message - The message\n\t * @returns True if the heartbeat was handled, false otherwise\n\t */\n\tpublic static Heartbeat(ws: ServerWebSocket<WebsocketEntityData>, message: BunWebsocketMessage) {\n\t\tconst self = this.GetInstance<Websocket>();\n\t\treturn self.handleHeartbeat(ws, message);\n\t}\n\n\t/**\n\t * Get the server\n\t * @returns The server\n\t */\n\tpublic static Server() {\n\t\treturn this.GetInstance<Websocket>().server;\n\t}\n\n\t/**\n\t * Broadcast a message to a channel\n\t * @param channel - The channel\n\t * @param message - The message\n\t * @param args - The arguments\n\t */\n\tpublic static Broadcast(channel: string, message: WebsocketStructuredMessage, ...args: any[]) {\n\t\t// Get the server from the singleton instance\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\tif (!ws.server) {\n\t\t\tthrow new Error(\"Websocket server not set\");\n\t\t}\n\t\tws.server.publish(channel, JSON.stringify({ message, args }));\n\t}\n\n\t/**\n\t * Broadcast a message to all channels\n\t * @param message - The message\n\t * @param args - The arguments\n\t */\n\tpublic static BroadCastAll(message: WebsocketStructuredMessage, ...args: any[]) {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\tws._channels.forEach((channel) => channel.broadcast(message, ...args));\n\t}\n\n\t/**\n\t * Join a channel\n\t * @param channel - The channel\n\t * @param entity - The entity\n\t */\n\tpublic static Join(channel: string, entity: I_WebsocketEntity) {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\tconst client = ws._clients.get(entity.id);\n\t\tif (!client) return;\n\t\tws._channels.get(channel)?.addMember(client);\n\t}\n\n\t/**\n\t * Leave a channel\n\t * @param channel - The channel\n\t * @param entity - The entity\n\t */\n\tpublic static Leave(channel: string, entity: I_WebsocketEntity) {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\tconst client = ws._clients.get(entity.id);\n\t\tif (!client) return;\n\t\tws._channels.get(channel)?.removeMember(client);\n\t}\n\n\t/**\n\t * Get a client\n\t * @param id - The id of the client\n\t * @param throw_if_nil - Whether to throw an error if the client is not found\n\t * @returns The client\n\t */\n\tpublic static GetClient(id: string, throw_if_nil?: true): I_WebsocketClient;\n\tpublic static GetClient(id: string, throw_if_nil?: false): I_WebsocketClient | undefined;\n\tpublic static GetClient(id: string, throw_if_nil: boolean = true): I_WebsocketClient | undefined {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\tconst client = ws._clients.get(id);\n\t\tif (!client && throw_if_nil) throw new Error(`Client with id ${id} not found`);\n\t\treturn client;\n\t}\n\n\t/**\n\t * Get a channel\n\t * @param id - The id of the channel\n\t * @returns The channel\n\t */\n\tpublic static GetChannel(id: string) {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn ws._channels.get(id);\n\t}\n\n\t/**\n\t * Get all channels\n\t * @returns The channels\n\t */\n\tpublic static GetChannels() {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn Array.from(ws._channels.values());\n\t}\n\n\t/**\n\t * Get all clients\n\t * @returns The clients\n\t */\n\tpublic static GetClients() {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn Array.from(ws._clients.values());\n\t}\n\n\t/**\n\t * Get the number of clients\n\t * @returns The number of clients\n\t */\n\tpublic static GetClientCount() {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn ws._clients.size;\n\t}\n\n\t/**\n\t * Get the number of channels\n\t * @returns The number of channels\n\t */\n\tpublic static GetChannelCount() {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn ws._channels.size;\n\t}\n\n\t/**\n\t * Create a client\n\t * @param entity - The entity\n\t * @returns The created client\n\t */\n\tpublic static CreateClient(entity: I_WebsocketEntity): I_WebsocketClient {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn ws.createClient(entity);\n\t}\n\n\t/**\n\t * Get all connected clients (excluding connecting/disconnecting)\n\t * @returns Array of connected clients\n\t */\n\tpublic static GetConnectedClients(): I_WebsocketClient[] {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\treturn Array.from(ws._clients.values()).filter((client) => client.state === \"connected\");\n\t}\n\n\t/**\n\t * Get client statistics by state\n\t * @returns Object with counts by state\n\t */\n\tpublic static GetClientStats() {\n\t\tconst ws = this.GetInstance<Websocket>();\n\t\tconst stats = {\n\t\t\ttotal: ws._clients.size,\n\t\t\tconnecting: 0,\n\t\t\tconnected: 0,\n\t\t\tdisconnecting: 0,\n\t\t\tdisconnected: 0,\n\t\t};\n\n\t\tfor (const client of ws._clients.values()) {\n\t\t\tswitch (client.state) {\n\t\t\t\tcase \"connecting\":\n\t\t\t\t\tstats.connecting++;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"connected\":\n\t\t\t\t\tstats.connected++;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"disconnecting\":\n\t\t\t\t\tstats.disconnecting++;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"disconnected\":\n\t\t\t\t\tstats.disconnected++;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn stats;\n\t}\n}\n"]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "topsyde-utils",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.209",
|
4
4
|
"description": "A bundle of TypeScript utility classes and functions",
|
5
5
|
"type": "module",
|
6
6
|
"main": "dist/index.js",
|
@@ -32,6 +32,10 @@
|
|
32
32
|
"types": "./dist/index.d.ts",
|
33
33
|
"default": "./dist/index.js"
|
34
34
|
},
|
35
|
+
"./client/api": {
|
36
|
+
"types": "./dist/client/api/index.d.ts",
|
37
|
+
"default": "./dist/client/api/index.js"
|
38
|
+
},
|
35
39
|
"./client/rxjs": {
|
36
40
|
"types": "./dist/client/rxjs/index.d.ts",
|
37
41
|
"default": "./dist/client/rxjs/index.js"
|
@@ -40,6 +44,10 @@
|
|
40
44
|
"types": "./dist/client/vite/plugins/index.d.ts",
|
41
45
|
"default": "./dist/client/vite/plugins/index.js"
|
42
46
|
},
|
47
|
+
"./external": {
|
48
|
+
"types": "./dist/external/index.d.ts",
|
49
|
+
"default": "./dist/external/index.js"
|
50
|
+
},
|
43
51
|
"./server/base": {
|
44
52
|
"types": "./dist/server/base/index.d.ts",
|
45
53
|
"default": "./dist/server/base/index.js"
|
@@ -59,12 +67,18 @@
|
|
59
67
|
},
|
60
68
|
"typesVersions": {
|
61
69
|
"*": {
|
70
|
+
"client/api": [
|
71
|
+
"./dist/client/api/index.d.ts"
|
72
|
+
],
|
62
73
|
"client/rxjs": [
|
63
74
|
"./dist/client/rxjs/index.d.ts"
|
64
75
|
],
|
65
76
|
"client/vite/plugins": [
|
66
77
|
"./dist/client/vite/plugins/index.d.ts"
|
67
78
|
],
|
79
|
+
"external": [
|
80
|
+
"./dist/external/index.d.ts"
|
81
|
+
],
|
68
82
|
"server/base": [
|
69
83
|
"./dist/server/base/index.d.ts"
|
70
84
|
],
|
@@ -110,6 +124,7 @@
|
|
110
124
|
"node": ">=14.0.0"
|
111
125
|
},
|
112
126
|
"dependencies": {
|
127
|
+
"axios": "^1.12.2",
|
113
128
|
"class-transformer": "^0.5.1",
|
114
129
|
"class-validator": "^0.14.2",
|
115
130
|
"rxjs": "^7.8.2",
|
@@ -0,0 +1,111 @@
|
|
1
|
+
import Axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, isAxiosError } from "axios";
|
2
|
+
class BaseAPI {
|
3
|
+
private api: AxiosInstance;
|
4
|
+
protected controller: string;
|
5
|
+
protected base_url: string;
|
6
|
+
|
7
|
+
constructor(controller: string, base_url?: string) {
|
8
|
+
this.controller = controller;
|
9
|
+
this.base_url = base_url || import.meta.env.VITE_HOST || "";
|
10
|
+
this.api = this.initAxios();
|
11
|
+
}
|
12
|
+
|
13
|
+
private initAxios(): AxiosInstance {
|
14
|
+
const config: AxiosRequestConfig = {
|
15
|
+
headers: {
|
16
|
+
"Content-Type": "application/json",
|
17
|
+
},
|
18
|
+
};
|
19
|
+
|
20
|
+
const instance = Axios.create(config);
|
21
|
+
|
22
|
+
// Add interceptor to modify request config
|
23
|
+
instance.interceptors.request.use((config) => {
|
24
|
+
// Ensure the correct content type
|
25
|
+
config.headers["Content-Type"] = "application/json";
|
26
|
+
|
27
|
+
return config;
|
28
|
+
});
|
29
|
+
|
30
|
+
return instance;
|
31
|
+
}
|
32
|
+
|
33
|
+
public static Status(response: AxiosResponse<{ status: boolean }>) {
|
34
|
+
if (!response.data.status) throw new Error("Something went wrong");
|
35
|
+
}
|
36
|
+
|
37
|
+
/**
|
38
|
+
* @description Axios GET request wrapper
|
39
|
+
* @param endpoint string
|
40
|
+
* @generic T
|
41
|
+
* @returns Promise<AxiosResponse<T>>
|
42
|
+
*/
|
43
|
+
async get<T extends { status: boolean }>(endpoint: string): Promise<AxiosResponse<T>>;
|
44
|
+
/**
|
45
|
+
* @description Axios GET request wrapper
|
46
|
+
* @param controller string - which controller to use
|
47
|
+
* @param endpoint string - controller action to call
|
48
|
+
* @generic T
|
49
|
+
* @returns Promise<AxiosResponse<T>>
|
50
|
+
*/
|
51
|
+
async get<T extends { status: boolean }>(controller: string, endpoint: string): Promise<AxiosResponse<T>>;
|
52
|
+
/**
|
53
|
+
* @description Axios GET request wrapper
|
54
|
+
* @param controller string - which controller to use
|
55
|
+
* @param endpoint string - controller action to call
|
56
|
+
* @param debounceDelay number - debounce delay
|
57
|
+
* @generic T
|
58
|
+
* @returns Promise<AxiosResponse<T>>
|
59
|
+
*/
|
60
|
+
async get<T extends { status: boolean }>(controller: string, endpoint: string, debounceDelay?: number): Promise<AxiosResponse<T>>;
|
61
|
+
async get<T extends { status: boolean }>(controllerOrEndpoint: string, endpoint?: string | undefined, _debounceDelay?: number): Promise<AxiosResponse<T>> {
|
62
|
+
let controller = endpoint ? controllerOrEndpoint : this.controller;
|
63
|
+
let action = endpoint ? endpoint : controllerOrEndpoint;
|
64
|
+
|
65
|
+
return this.api.get<T>(`${this.base_url}/${controller}/${action}`).catch((err) => {
|
66
|
+
if (isAxiosError(err)) throw err.response;
|
67
|
+
throw err;
|
68
|
+
});
|
69
|
+
}
|
70
|
+
|
71
|
+
/**
|
72
|
+
* @description Axios POST request wrapper
|
73
|
+
* @param endpoint string - controller action to call
|
74
|
+
* @param payload any
|
75
|
+
* @generic T
|
76
|
+
* @returns Promise<AxiosResponse<T>>
|
77
|
+
*/
|
78
|
+
async post<T extends { status: boolean }>(endpoint: string, payload: any): Promise<AxiosResponse<T>>;
|
79
|
+
/**
|
80
|
+
* @description Axios POST request wrapper
|
81
|
+
* @param controller string - which controller to use
|
82
|
+
* @param endpoint string - controller action to call
|
83
|
+
* @param payload any
|
84
|
+
* @generic T
|
85
|
+
* @returns Promise<AxiosResponse<T>>
|
86
|
+
*/
|
87
|
+
async post<T extends { status: boolean }>(controller: string, endpoint: string, payload: any): Promise<AxiosResponse<T>>;
|
88
|
+
async post<T extends { status: boolean }>(controllerOrEndpoint: string, endpointOrPayload: string | any, payload?: any): Promise<AxiosResponse<T>> {
|
89
|
+
let controller: string;
|
90
|
+
let action: string;
|
91
|
+
let data: any;
|
92
|
+
|
93
|
+
if (payload !== null && payload !== undefined) {
|
94
|
+
controller = controllerOrEndpoint;
|
95
|
+
action = endpointOrPayload;
|
96
|
+
data = payload;
|
97
|
+
} else {
|
98
|
+
controller = this.controller;
|
99
|
+
action = controllerOrEndpoint;
|
100
|
+
data = endpointOrPayload;
|
101
|
+
}
|
102
|
+
const response = await this.api.post<T>(`${this.base_url}/${controller}/${action}`, data).catch((err) => {
|
103
|
+
if (isAxiosError(err)) throw err.response;
|
104
|
+
throw err;
|
105
|
+
});
|
106
|
+
if (!response.data.status) throw new Error("Something went wrong");
|
107
|
+
return response;
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
export default BaseAPI;
|
@@ -0,0 +1,54 @@
|
|
1
|
+
/**
|
2
|
+
* Re-exports of external dependencies for convenience
|
3
|
+
*
|
4
|
+
* This module re-exports commonly used types, classes, and decorators from
|
5
|
+
* class-transformer and class-validator to provide a single import source
|
6
|
+
* for projects using topsyde-utils.
|
7
|
+
*
|
8
|
+
* This prevents the need to separately install these dependencies in
|
9
|
+
* consuming projects, as they're already bundled with topsyde-utils.
|
10
|
+
*/
|
11
|
+
|
12
|
+
// ============================================================================
|
13
|
+
// class-transformer exports
|
14
|
+
// ============================================================================
|
15
|
+
|
16
|
+
// Types
|
17
|
+
export type { ClassConstructor, ClassTransformOptions } from "class-transformer";
|
18
|
+
|
19
|
+
// Core transformation functions
|
20
|
+
export { instanceToPlain, plainToInstance } from "class-transformer";
|
21
|
+
|
22
|
+
// Decorators
|
23
|
+
export { Expose } from "class-transformer";
|
24
|
+
|
25
|
+
// ============================================================================
|
26
|
+
// class-validator exports
|
27
|
+
// ============================================================================
|
28
|
+
|
29
|
+
// Types and Classes
|
30
|
+
export { ValidationError } from "class-validator";
|
31
|
+
|
32
|
+
// Validation function
|
33
|
+
export { validateSync } from "class-validator";
|
34
|
+
|
35
|
+
// Property decorators
|
36
|
+
export {
|
37
|
+
IsArray,
|
38
|
+
IsBoolean,
|
39
|
+
IsDate,
|
40
|
+
IsEnum,
|
41
|
+
IsNumber,
|
42
|
+
IsObject,
|
43
|
+
IsOptional,
|
44
|
+
IsString,
|
45
|
+
Validate,
|
46
|
+
IsAlphanumeric,
|
47
|
+
IsBooleanString,
|
48
|
+
IsDateString,
|
49
|
+
IsDecimal,
|
50
|
+
IsDefined,
|
51
|
+
IsNumberString,
|
52
|
+
IsNotEmpty,
|
53
|
+
IsNotEmptyObject,
|
54
|
+
} from "class-validator";
|
package/src/index.ts
CHANGED
@@ -10,8 +10,10 @@ export * from "./consts";
|
|
10
10
|
export * from "./types";
|
11
11
|
export * from "./throwable";
|
12
12
|
export * from "./enums";
|
13
|
+
export * from "./client/api/base.api";
|
13
14
|
export * from "./client/rxjs/useRxjs";
|
14
15
|
export * from "./client/vite/plugins/topsydeUtilsVitePlugin";
|
16
|
+
export * from "./external/re-exports";
|
15
17
|
export * from "./server/controller";
|
16
18
|
export * from "./server/service";
|
17
19
|
export * from "./server/base/base.database";
|
@@ -39,6 +41,7 @@ export { default as Singleton } from "./singleton";
|
|
39
41
|
export { default as Initializable } from "./initializable";
|
40
42
|
export { default as Application } from "./application";
|
41
43
|
export { default as Throwable } from "./throwable";
|
44
|
+
export { default as BaseAPI } from "./client/api/base.api";
|
42
45
|
export { default as TopsydeUtilsVitePlugin } from "./client/vite/plugins/topsydeUtilsVitePlugin";
|
43
46
|
export { default as Controller } from "./server/controller";
|
44
47
|
export { default as Service } from "./server/service";
|
@@ -62,6 +65,27 @@ export { DEFAULT_FALSE_RESPONSE, LOG_COLORS, LOG_ICONS } from "./consts";
|
|
62
65
|
export { ClassConstructor, NonNullableType, ObjectKeys, KVObj, I_ApplicationResponse } from "./types";
|
63
66
|
export { E_IS, E_ENVIRONMENTS } from "./enums";
|
64
67
|
export { RxjsDataType, NamespaceActions, MultiNamespaceActions } from "./client/rxjs/useRxjs";
|
68
|
+
export {
|
69
|
+
Expose,
|
70
|
+
ValidationError,
|
71
|
+
IsArray,
|
72
|
+
IsBoolean,
|
73
|
+
IsDate,
|
74
|
+
IsEnum,
|
75
|
+
IsNumber,
|
76
|
+
IsObject,
|
77
|
+
IsOptional,
|
78
|
+
IsString,
|
79
|
+
Validate,
|
80
|
+
IsAlphanumeric,
|
81
|
+
IsBooleanString,
|
82
|
+
IsDateString,
|
83
|
+
IsDecimal,
|
84
|
+
IsDefined,
|
85
|
+
IsNumberString,
|
86
|
+
IsNotEmpty,
|
87
|
+
IsNotEmptyObject,
|
88
|
+
} from "./external/re-exports";
|
65
89
|
export { ControllerResponse, ControllerAction, ControllerMap, ControllerOptions } from "./server/controller";
|
66
90
|
export { Routes } from "./server/bun/router/routes";
|
67
91
|
export { WebsocketConstructorOptions, I_WebsocketConstructor } from "./server/bun/websocket/Websocket";
|
@@ -146,7 +146,7 @@ export default class Websocket extends Singleton {
|
|
146
146
|
|
147
147
|
// Client handles its own joining logic with rollback support
|
148
148
|
if (!client.joinChannel(global)) {
|
149
|
-
|
149
|
+
throw new Error("Failed to join global channel");
|
150
150
|
}
|
151
151
|
|
152
152
|
// Mark as fully connected
|
@@ -336,9 +336,7 @@ export default class Websocket extends Singleton {
|
|
336
336
|
*/
|
337
337
|
public static GetConnectedClients(): I_WebsocketClient[] {
|
338
338
|
const ws = this.GetInstance<Websocket>();
|
339
|
-
return Array.from(ws._clients.values()).filter(
|
340
|
-
client => client.state === "connected"
|
341
|
-
);
|
339
|
+
return Array.from(ws._clients.values()).filter((client) => client.state === "connected");
|
342
340
|
}
|
343
341
|
|
344
342
|
/**
|
@@ -357,10 +355,18 @@ export default class Websocket extends Singleton {
|
|
357
355
|
|
358
356
|
for (const client of ws._clients.values()) {
|
359
357
|
switch (client.state) {
|
360
|
-
case "connecting":
|
361
|
-
|
362
|
-
|
363
|
-
case "
|
358
|
+
case "connecting":
|
359
|
+
stats.connecting++;
|
360
|
+
break;
|
361
|
+
case "connected":
|
362
|
+
stats.connected++;
|
363
|
+
break;
|
364
|
+
case "disconnecting":
|
365
|
+
stats.disconnecting++;
|
366
|
+
break;
|
367
|
+
case "disconnected":
|
368
|
+
stats.disconnected++;
|
369
|
+
break;
|
364
370
|
}
|
365
371
|
}
|
366
372
|
|