@mademi_dev/chatemi 1.0.0

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,44 @@
1
+ import { NextResponse } from "next/server";
2
+
3
+ export async function GET() {
4
+ return NextResponse.json({
5
+ messageCreated: {
6
+ type: "message.created",
7
+ payload: {
8
+ id: "message_1",
9
+ conversationId: "conversation_1",
10
+ sender: {
11
+ id: "user_1",
12
+ name: "Ava",
13
+ avatarUrl: "https://example.com/ava.png"
14
+ },
15
+ text: "Hello from ChatEmi",
16
+ status: "sent",
17
+ createdAt: new Date().toISOString()
18
+ }
19
+ },
20
+ notification: {
21
+ type: "notification",
22
+ payload: {
23
+ id: "notification_1",
24
+ kind: "message",
25
+ title: "Ava",
26
+ body: "Hello from ChatEmi",
27
+ conversationId: "conversation_1",
28
+ messageId: "message_1",
29
+ read: false,
30
+ createdAt: new Date().toISOString()
31
+ }
32
+ },
33
+ receipt: {
34
+ type: "message.receipt",
35
+ payload: {
36
+ conversationId: "conversation_1",
37
+ messageIds: ["message_1"],
38
+ userId: "user_2",
39
+ status: "read",
40
+ at: new Date().toISOString()
41
+ }
42
+ }
43
+ });
44
+ }
@@ -0,0 +1,35 @@
1
+ "use client";
2
+
3
+ import { ChatEmiLauncher, ChatEmiProvider } from "chatemi";
4
+ import { useMemo } from "react";
5
+ import { createChatEmiConfig } from "../lib/chatemi-config";
6
+
7
+ export function ChatWidget() {
8
+ const config = useMemo(() => createChatEmiConfig(), []);
9
+
10
+ return (
11
+ <ChatEmiProvider config={config}>
12
+ <ChatEmiLauncher
13
+ defaultOpen={false}
14
+ markNotificationsReadOnOpen
15
+ placement="bottom-right"
16
+ showNotificationList
17
+ subtitle="We are here to help"
18
+ theme="glass"
19
+ title="Messages"
20
+ initialSize={{
21
+ width: 460,
22
+ height: 720
23
+ }}
24
+ minSize={{
25
+ width: 360,
26
+ height: 520
27
+ }}
28
+ maxSize={{
29
+ width: 960,
30
+ height: 860
31
+ }}
32
+ />
33
+ </ChatEmiProvider>
34
+ );
35
+ }
@@ -0,0 +1,20 @@
1
+ import "chatemi/styles.css";
2
+ import type { Metadata } from "next";
3
+ import type { ReactNode } from "react";
4
+ import { ChatWidget } from "./components/ChatWidget";
5
+
6
+ export const metadata: Metadata = {
7
+ title: "ChatEmi Next.js example",
8
+ description: "A Next.js app using the ChatEmi launcher widget."
9
+ };
10
+
11
+ export default function RootLayout({ children }: { children: ReactNode }) {
12
+ return (
13
+ <html lang="en">
14
+ <body>
15
+ {children}
16
+ <ChatWidget />
17
+ </body>
18
+ </html>
19
+ );
20
+ }
@@ -0,0 +1,52 @@
1
+ import type { ChatEmiConfig } from "chatemi";
2
+
3
+ export function createChatEmiConfig(): ChatEmiConfig {
4
+ return {
5
+ apiBaseUrl: requiredPublicEnv("NEXT_PUBLIC_CHAT_API_URL"),
6
+ socketUrl: process.env.NEXT_PUBLIC_CHAT_SOCKET_URL,
7
+ token: () => localStorage.getItem("access_token") ?? undefined,
8
+ theme: "glass",
9
+ notifications: {
10
+ enabled: true,
11
+ browser: true,
12
+ showWhenOpen: false,
13
+ maxStored: 100
14
+ },
15
+ userDirectory: {
16
+ baseUrl: requiredPublicEnv("NEXT_PUBLIC_IDENTITY_API_URL"),
17
+ searchPath: "/users/search",
18
+ userPath: (userId) => `/users/${encodeURIComponent(userId)}`,
19
+ headers: () => {
20
+ const identityToken = localStorage.getItem("identity_token");
21
+ return identityToken ? { Authorization: `Bearer ${identityToken}` } : {};
22
+ },
23
+ mapUser: (rawUser) => {
24
+ const user = rawUser as {
25
+ id: string;
26
+ displayName?: string;
27
+ name?: string;
28
+ username?: string;
29
+ avatarUrl?: string;
30
+ photoUrl?: string;
31
+ };
32
+
33
+ return {
34
+ id: user.id,
35
+ name: user.displayName ?? user.name ?? user.username ?? "Unknown user",
36
+ username: user.username,
37
+ avatarUrl: user.avatarUrl ?? user.photoUrl
38
+ };
39
+ }
40
+ }
41
+ };
42
+ }
43
+
44
+ function requiredPublicEnv(name: string): string {
45
+ const value = process.env[name];
46
+
47
+ if (!value) {
48
+ throw new Error(`Missing ${name}`);
49
+ }
50
+
51
+ return value;
52
+ }
@@ -0,0 +1,27 @@
1
+ import { createChatEmiMongoConnection } from "chatemi/server";
2
+
3
+ let connectionPromise: ReturnType<typeof createChatEmiMongoConnection> | undefined;
4
+
5
+ export function getChatEmiMongo() {
6
+ if (!connectionPromise) {
7
+ connectionPromise = createChatEmiMongoConnection({
8
+ uri: requiredServerEnv("MONGODB_URI"),
9
+ databaseName: process.env.MONGODB_DB ?? "chatemi",
10
+ clientOptions: {
11
+ appName: "chatemi-nextjs-example"
12
+ }
13
+ });
14
+ }
15
+
16
+ return connectionPromise;
17
+ }
18
+
19
+ function requiredServerEnv(name: string): string {
20
+ const value = process.env[name];
21
+
22
+ if (!value) {
23
+ throw new Error(`Missing ${name}`);
24
+ }
25
+
26
+ return value;
27
+ }
@@ -0,0 +1,11 @@
1
+ export default function HomePage() {
2
+ return (
3
+ <main style={{ minHeight: "100vh", padding: 48 }}>
4
+ <h1>ChatEmi widget example</h1>
5
+ <p>
6
+ Open the floating chat button. The provider stays connected in the background,
7
+ so notification badges continue to update when the modal is closed.
8
+ </p>
9
+ </main>
10
+ );
11
+ }
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "@mademi_dev/chatemi",
3
+ "version": "1.0.0",
4
+ "description": "A React messaging kit with API clients, realtime socket support, hooks, provider state, and default Telegram-style UI.",
5
+ "type": "module",
6
+ "main": "dist/chatemi.umd.cjs",
7
+ "module": "dist/chatemi.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/chatemi.js",
13
+ "require": "./dist/chatemi.umd.cjs"
14
+ },
15
+ "./server": {
16
+ "types": "./dist/server/index.d.ts",
17
+ "import": "./dist/server/index.js"
18
+ },
19
+ "./styles.css": "./dist/assets/styles.css"
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "docs",
24
+ "examples",
25
+ "README.md",
26
+ "LICENSE"
27
+ ],
28
+ "sideEffects": [
29
+ "**/*.css"
30
+ ],
31
+ "scripts": {
32
+ "build": "tsc --noEmit && vite build && tsc -p tsconfig.build.json && tsc -p tsconfig.server.json",
33
+ "typecheck": "tsc --noEmit",
34
+ "prepublishOnly": "npm run build"
35
+ },
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "git+https://github.com/mademi-dev/ChatEmi.git"
39
+ },
40
+ "keywords": [
41
+ "react",
42
+ "chat",
43
+ "messaging",
44
+ "messenger",
45
+ "websocket",
46
+ "socket",
47
+ "telegram",
48
+ "ui"
49
+ ],
50
+ "author": "",
51
+ "license": "MIT",
52
+ "bugs": {
53
+ "url": "https://github.com/mademi-dev/ChatEmi/issues"
54
+ },
55
+ "homepage": "https://github.com/mademi-dev/ChatEmi#readme",
56
+ "peerDependencies": {
57
+ "mongodb": ">=7.0.0",
58
+ "react": ">=18.0.0",
59
+ "react-dom": ">=18.0.0"
60
+ },
61
+ "peerDependenciesMeta": {
62
+ "mongodb": {
63
+ "optional": true
64
+ }
65
+ },
66
+ "devDependencies": {
67
+ "@types/node": "^26.0.0",
68
+ "@types/react": "^19.2.17",
69
+ "@types/react-dom": "^19.2.3",
70
+ "@vitejs/plugin-react": "^6.0.2",
71
+ "mongodb": "^7.3.0",
72
+ "react": "^19.2.7",
73
+ "react-dom": "^19.2.7",
74
+ "typescript": "^6.0.3",
75
+ "vite": "^8.0.16"
76
+ }
77
+ }