mezon-light-sdk 1.0.2 → 1.0.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.
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Copyright 2022 The Mezon Authors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /** A session authenticated for a user with Mezon server. */
17
+ export interface ISession {
18
+ /** Claims */
19
+ /** The authorization token used to construct this session. */
20
+ token: string;
21
+ /** If the user account for this session was just created. */
22
+ created: boolean;
23
+ /** The UNIX timestamp when this session was created. */
24
+ readonly created_at: number;
25
+ /** The UNIX timestamp when this session will expire. */
26
+ expires_at?: number;
27
+ /** The UNIX timestamp when the refresh token will expire. */
28
+ refresh_expires_at?: number;
29
+ /** Refresh token that can be used for session token renewal. */
30
+ refresh_token: string;
31
+ /** The username of the user who owns this session. */
32
+ username?: string;
33
+ /** The ID of the user who owns this session. */
34
+ user_id?: string;
35
+ /** Any custom properties associated with this session. */
36
+ vars?: object;
37
+ /** Validate token */
38
+ /** If the session has expired. */
39
+ isexpired(currenttime: number): boolean;
40
+ /** If the refresh token has expired. */
41
+ isrefreshexpired(currenttime: number): boolean;
42
+ }
43
+ export declare class Session implements ISession {
44
+ readonly created: boolean;
45
+ readonly api_url: string;
46
+ readonly id_token: string;
47
+ token: string;
48
+ readonly created_at: number;
49
+ expires_at?: number;
50
+ refresh_expires_at?: number;
51
+ refresh_token: string;
52
+ username?: string;
53
+ user_id?: string;
54
+ vars?: {
55
+ [key: string]: any;
56
+ };
57
+ is_remember?: boolean;
58
+ constructor(token: string, refresh_token: string, created: boolean, api_url: string, id_token: string, is_remember: boolean);
59
+ isexpired(currenttime: number): boolean;
60
+ isrefreshexpired(currenttime: number): boolean;
61
+ update(token: string, refreshToken: string, isRemember: boolean): void;
62
+ static restore(token: string, refreshToken: string, api_url: string, isRemember: boolean): Session;
63
+ }
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright 2022 The Mezon Authors
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ }) : (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ }));
28
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }) : function(o, v) {
31
+ o["default"] = v;
32
+ });
33
+ var __importStar = (this && this.__importStar) || function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.Session = void 0;
42
+ const base64 = __importStar(require("js-base64"));
43
+ class Session {
44
+ constructor(token, refresh_token, created, api_url, id_token, is_remember) {
45
+ this.created = created;
46
+ this.api_url = api_url;
47
+ this.id_token = id_token;
48
+ this.token = token;
49
+ this.refresh_token = refresh_token;
50
+ this.id_token = id_token;
51
+ this.api_url = api_url;
52
+ this.created_at = Math.floor(new Date().getTime() / 1000);
53
+ this.is_remember = is_remember;
54
+ this.update(token, refresh_token, is_remember);
55
+ }
56
+ isexpired(currenttime) {
57
+ return this.expires_at - currenttime <= 0; // expired
58
+ }
59
+ isrefreshexpired(currenttime) {
60
+ return this.refresh_expires_at - currenttime <= 0;
61
+ }
62
+ update(token, refreshToken, isRemember) {
63
+ const tokenParts = token.split(".");
64
+ if (tokenParts.length != 3) {
65
+ throw "jwt is not valid.";
66
+ }
67
+ const tokenDecoded = JSON.parse(base64.atob(tokenParts[1]));
68
+ const tokenExpiresAt = Math.floor(parseInt(tokenDecoded["exp"]));
69
+ /** clients that have just updated to the refresh tokens */
70
+ /** client release will not have a cached refresh token */
71
+ if (refreshToken) {
72
+ const refreshTokenParts = refreshToken.split(".");
73
+ if (refreshTokenParts.length != 3) {
74
+ throw "refresh jwt is not valid.";
75
+ }
76
+ const refreshTokenDecoded = JSON.parse(base64.atob(refreshTokenParts[1]));
77
+ const refreshTokenExpiresAt = Math.floor(parseInt(refreshTokenDecoded["exp"]));
78
+ this.refresh_expires_at = refreshTokenExpiresAt;
79
+ this.refresh_token = refreshToken;
80
+ this.is_remember = isRemember;
81
+ }
82
+ this.token = token;
83
+ this.expires_at = tokenExpiresAt;
84
+ this.username = tokenDecoded["usn"];
85
+ this.user_id = tokenDecoded["uid"];
86
+ this.vars = tokenDecoded["vrs"];
87
+ }
88
+ static restore(token, refreshToken, api_url, isRemember) {
89
+ return new Session(token, refreshToken, false, api_url, "", isRemember);
90
+ }
91
+ }
92
+ exports.Session = Session;
package/dist/socket.d.ts CHANGED
@@ -1,13 +1,135 @@
1
- import { Client, Session } from "mezon-js";
2
- import { ChannelMessage } from "./message";
1
+ import { SendMessagePayload } from "./types";
2
+ import { LightClient } from "./client";
3
+ import { Socket } from "./socket.gen";
4
+ import { Session } from "./session";
5
+ import { ChannelMessage } from "./api.gen";
6
+ /**
7
+ * Error thrown when socket operations fail.
8
+ */
9
+ export declare class SocketError extends Error {
10
+ constructor(message: string);
11
+ }
12
+ /**
13
+ * Configuration options for socket connection.
14
+ */
15
+ export interface SocketConnectOptions {
16
+ /** Callback for socket errors */
17
+ onError?: (error: unknown) => void;
18
+ /** Callback when socket disconnects */
19
+ onDisconnect?: () => void;
20
+ /** Whether to enable verbose logging */
21
+ verbose?: boolean;
22
+ }
23
+ /**
24
+ * Callback type for channel message events.
25
+ */
26
+ export type ChannelMessageHandler = (message: ChannelMessage) => void;
27
+ /**
28
+ * LightSocket provides a simplified interface for Mezon real-time messaging.
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * const socket = new LightSocket(client.client, client.session);
33
+ *
34
+ * await socket.connect({
35
+ * onError: (err) => console.error('Socket error:', err),
36
+ * onDisconnect: () => console.log('Disconnected')
37
+ * });
38
+ *
39
+ * socket.onChannelMessage((msg) => {
40
+ * console.log('Received message:', msg.content);
41
+ * });
42
+ *
43
+ * await socket.joinDMChannel('channel-123');
44
+ * await socket.sendDM({ channelId: 'channel-123', content: 'Hello!' });
45
+ * ```
46
+ */
3
47
  export declare class LightSocket {
4
- private client;
5
- private session;
6
- private socket;
7
- onError?: (err: any) => void;
8
- constructor(client: Client, session: Session);
9
- connect(onError?: (err: any) => void): Promise<void>;
10
- setChannelMessageHandler(cb: (msg: ChannelMessage) => void): void;
11
- joinDMChannel(channel_id: string): Promise<void>;
12
- sendDM(channelId: string, content: any, attachments?: any[]): Promise<void>;
48
+ private readonly _client;
49
+ private readonly _session;
50
+ private _socket;
51
+ private _isConnected;
52
+ private _messageHandlers;
53
+ private _errorHandler?;
54
+ private _disconnectHandler?;
55
+ constructor(_client: LightClient, _session: Session);
56
+ /**
57
+ * Gets whether the socket is currently connected.
58
+ */
59
+ get isConnected(): boolean;
60
+ /**
61
+ * Gets the underlying socket instance.
62
+ * @throws {SocketError} If socket is not connected
63
+ */
64
+ get socket(): Socket;
65
+ /**
66
+ * Connects to the Mezon real-time server.
67
+ *
68
+ * @param options - Connection options including error handlers
69
+ * @throws {SocketError} If already connected or connection fails
70
+ */
71
+ connect(options?: SocketConnectOptions): Promise<void>;
72
+ /**
73
+ * Disconnects from the Mezon server.
74
+ */
75
+ disconnect(): void;
76
+ /**
77
+ * Registers a handler for incoming channel messages.
78
+ * Multiple handlers can be registered and will all receive messages.
79
+ *
80
+ * @param handler - Callback function to handle messages
81
+ */
82
+ setChannelMessageHandler(cb: ChannelMessageHandler): void;
83
+ /**
84
+ * Registers a handler for incoming channel messages.
85
+ * Multiple handlers can be registered and will all receive messages.
86
+ *
87
+ * @param handler - Callback function to handle messages
88
+ * @returns A function to unsubscribe the handler
89
+ */
90
+ onChannelMessage(handler: ChannelMessageHandler): () => void;
91
+ /**
92
+ * Joins a DM channel to receive messages from it.
93
+ *
94
+ * @param channelId - The DM channel ID to join
95
+ * @throws {SocketError} If socket is not ready or join fails
96
+ */
97
+ joinDMChannel(channelId: string): Promise<void>;
98
+ /**
99
+ * Joins a group channel to receive messages from it.
100
+ *
101
+ * @param channelId - The group channel ID to join
102
+ * @throws {SocketError} If socket is not ready or join fails
103
+ */
104
+ joinGroupChannel(channelId: string): Promise<void>;
105
+ /**
106
+ * Leaves a DM channel.
107
+ *
108
+ * @param channelId - The DM channel ID to leave
109
+ */
110
+ leaveDMChannel(channelId: string): Promise<void>;
111
+ /**
112
+ * Leaves a group channel.
113
+ *
114
+ * @param channelId - The group channel ID to leave
115
+ */
116
+ leaveGroupChannel(channelId: string): Promise<void>;
117
+ /**
118
+ * Sends a direct message to a channel.
119
+ *
120
+ * @param options - Message options including channelId, content, and attachments
121
+ */
122
+ sendDM(payload: SendMessagePayload): Promise<void>;
123
+ /**
124
+ * Sends a direct message to a channel.
125
+ *
126
+ * @param options - Message options including channelId, content, and attachments
127
+ */
128
+ sendGroup(payload: SendMessagePayload): Promise<void>;
129
+ /**
130
+ * Sets the error handler for socket errors.
131
+ *
132
+ * @param handler - Error handler callback
133
+ */
134
+ setErrorHandler(handler: (error: unknown) => void): void;
13
135
  }
@@ -0,0 +1,136 @@
1
+ import { Channel, ChannelMessageAck } from "./proto/realtime";
2
+ import { WebSocketAdapter } from "./web_socket_adapter_pb";
3
+ import { Session } from "./session";
4
+ import { ApiMessageAttachment, ChannelMessage } from "./api.gen";
5
+ /** A socket connection to Mezon server. */
6
+ export interface Socket {
7
+ /** Connection is Open */
8
+ isOpen(): boolean;
9
+ /** Connect to the server. */
10
+ connect(session: Session, createStatus: boolean, platform: string, connectTimeoutMs?: number, signal?: AbortSignal): Promise<Session>;
11
+ /** Disconnect from the server. */
12
+ disconnect(fireDisconnectEvent: boolean): void;
13
+ /** Join a chat channel on the server. */
14
+ joinChat(clan_id: string, channel_id: string, channel_type: number, is_public: boolean): Promise<Channel>;
15
+ /** Leave a chat channel on the server. */
16
+ leaveChat(clan_id: string, channel_id: string, channel_type: number, is_public: boolean): Promise<void>;
17
+ /** Send a chat message to a chat channel on the server. */
18
+ writeChatMessage(clan_id: string, channel_id: string, mode: number, is_public: boolean, content?: any, attachments?: Array<ApiMessageAttachment>, anonymous_message?: boolean, mention_everyone?: boolean, avatar?: string, code?: number, topic_id?: string, id?: string): Promise<ChannelMessageAck>;
19
+ setHeartbeatTimeoutMs(ms: number): void;
20
+ getHeartbeatTimeoutMs(): number;
21
+ onreconnect: (evt: Event) => void;
22
+ /** Handle disconnect events received from the socket. */
23
+ ondisconnect: (evt: Event) => void;
24
+ /** Handle error events received from the socket. */
25
+ onerror: (evt: Event) => void;
26
+ /**
27
+ * An application-level heartbeat timeout that fires after the client does not receive a pong from the server after the heartbeat interval.
28
+ * Most browsers maintain an internal heartbeat, in which case its unlikely you'll need to use this callback. However, Chrome does not implement an internal heartbeat.
29
+ * We fire this separately from `onclose` because heartbeats fail when there's no connectivity, and many browsers don't fire `onclose` until the closing handshake either succeeds or fails.
30
+ * In any case, be aware that `onclose` will still fire if there is a heartbeat timeout in a potentially delayed manner.
31
+ */
32
+ onheartbeattimeout: () => void;
33
+ /** Receive channel message. */
34
+ onchannelmessage: (channelMessage: ChannelMessage) => void;
35
+ }
36
+ /** Represents an error returned from the socket. */
37
+ export interface SocketError {
38
+ /** The error code. */
39
+ code: number;
40
+ /** A message in English to help developers debug the response. */
41
+ message: string;
42
+ }
43
+ export declare const ConnectionState: {
44
+ readonly DISCONNECTED: "disconnected";
45
+ readonly CONNECTING: "connecting";
46
+ readonly CONNECTED: "connected";
47
+ };
48
+ export type ConnectionStateType = (typeof ConnectionState)[keyof typeof ConnectionState];
49
+ /** Application-level heartbeat ping. */
50
+ interface Ping {
51
+ }
52
+ /** Send a message to a realtime chat channel. */
53
+ interface ChannelMessageSend {
54
+ channel_message_send: {
55
+ /** Clan Id */
56
+ clan_id: string;
57
+ /** The server-assigned channel ID. */
58
+ channel_id: string;
59
+ mode: number;
60
+ channel_label: string;
61
+ /** The content payload. */
62
+ content: any;
63
+ attachments?: Array<ApiMessageAttachment>;
64
+ anonymous_message?: boolean;
65
+ mention_everyone?: boolean;
66
+ avatar: string;
67
+ is_public: boolean;
68
+ code: number;
69
+ topic_id?: string;
70
+ };
71
+ }
72
+ /** Join a realtime chat channel. */
73
+ interface ChannelJoin {
74
+ channel_join: {
75
+ /** The id of the channel to join. */
76
+ channel_id: string;
77
+ /** The name of the channel to join. */
78
+ channel_label: string;
79
+ /** The channel type: 1 = Channel, 2 = Direct Message, 3 = Group. */
80
+ type: number;
81
+ /** Whether channel messages are persisted in the database. */
82
+ persistence: boolean;
83
+ /** Whether the user's channel presence is hidden when joining. */
84
+ hidden: boolean;
85
+ is_public: boolean;
86
+ };
87
+ }
88
+ /** Leave a realtime chat channel. */
89
+ interface ChannelLeave {
90
+ channel_leave: {
91
+ /** The id of the channel to leave. */
92
+ channel_id: string;
93
+ mode: number;
94
+ channel_label: string;
95
+ is_public: boolean;
96
+ };
97
+ }
98
+ export declare class DefaultSocket implements Socket {
99
+ readonly host: string;
100
+ readonly port: string;
101
+ readonly useSSL: boolean;
102
+ verbose: boolean;
103
+ readonly adapter: WebSocketAdapter;
104
+ readonly sendTimeoutMs: number;
105
+ static readonly DefaultHeartbeatTimeoutMs = 10000;
106
+ static readonly DefaultSendTimeoutMs = 10000;
107
+ static readonly DefaultConnectTimeoutMs = 30000;
108
+ private readonly cIds;
109
+ private nextCid;
110
+ private _heartbeatTimeoutMs;
111
+ private _connectionState;
112
+ private _heartbeatTimer?;
113
+ private _connectTimeoutTimer?;
114
+ private _connectPromise?;
115
+ constructor(host: string, port: string, useSSL?: boolean, verbose?: boolean, adapter?: WebSocketAdapter, sendTimeoutMs?: number);
116
+ generatecid(): string;
117
+ isOpen(): boolean;
118
+ connect(session: Session, createStatus?: boolean, platform?: string, connectTimeoutMs?: number, signal?: AbortSignal): Promise<Session>;
119
+ disconnect(fireDisconnectEvent?: boolean): void;
120
+ setHeartbeatTimeoutMs(ms: number): void;
121
+ getHeartbeatTimeoutMs(): number;
122
+ onreconnect(evt: Event): void;
123
+ ondisconnect(evt: Event): void;
124
+ onerror(evt: Event): void;
125
+ onheartbeattimeout(): void;
126
+ onchannelmessage(channelMessage: ChannelMessage): void;
127
+ send(message: ChannelJoin | ChannelLeave | ChannelMessageSend | Ping, sendTimeout?: number): Promise<any>;
128
+ joinChat(clan_id: string, channel_id: string, channel_type: number, is_public: boolean): Promise<Channel>;
129
+ leaveChat(clan_id: string, channel_id: string, channel_type: number, is_public: boolean): Promise<void>;
130
+ writeChatMessage(clan_id: string, channel_id: string, mode: number, is_public: boolean, content: any, attachments?: Array<ApiMessageAttachment>, anonymous_message?: boolean, mention_everyone?: Boolean, avatar?: string, code?: number, topic_id?: string): Promise<ChannelMessageAck>;
131
+ private pingPong;
132
+ private startHeartbeatLoop;
133
+ private stopHeartbeatLoop;
134
+ private clearConnectTimeout;
135
+ }
136
+ export {};