@byteoniclabs/intake 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.
- package/README.md +187 -0
- package/dist/index.d.mts +42 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +166 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +138 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react/index.d.mts +51 -0
- package/dist/react/index.d.ts +51 -0
- package/dist/react/index.js +392 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mjs +349 -0
- package/dist/react/index.mjs.map +1 -0
- package/dist/server.d.mts +42 -0
- package/dist/server.d.ts +42 -0
- package/dist/server.js +105 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +80 -0
- package/dist/server.mjs.map +1 -0
- package/dist/types-1XzE88JK.d.mts +13 -0
- package/dist/types-1XzE88JK.d.ts +13 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# @byteoniclabs/intake
|
|
2
|
+
|
|
3
|
+
The official, lightweight client library to easily send form submissions and integrate real-time AI Chatbots securely into your Byteonic Intake projects. Works seamlessly with **Vanilla JS**, **React**, and **Node.js** backends.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @byteoniclabs/intake
|
|
9
|
+
# or
|
|
10
|
+
yarn add @byteoniclabs/intake
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @byteoniclabs/intake
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 1. Forms (React & Vanilla JS)
|
|
18
|
+
|
|
19
|
+
The easiest way to use Intake forms in React is via our native hooks.
|
|
20
|
+
|
|
21
|
+
### React: Simple Form Hook
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { useByteonicIntake } from '@byteoniclabs/intake/react';
|
|
25
|
+
|
|
26
|
+
export default function ContactForm() {
|
|
27
|
+
// Pass your publishable API key and form slug
|
|
28
|
+
const { submit, isLoading, isSuccess, error } = useByteonicIntake({
|
|
29
|
+
formSlug: 'contact-form',
|
|
30
|
+
apiKey: 'YOUR_PUBLISHABLE_API_KEY', // You can also set VITE_BYTEONIC_API_KEY / NEXT_PUBLIC_BYTEONIC_API_KEY
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (isSuccess) {
|
|
34
|
+
return <div>Thanks for reaching out!</div>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<form onSubmit={submit}>
|
|
39
|
+
<input type="text" name="name" required placeholder="Name" />
|
|
40
|
+
<input type="email" name="email" required placeholder="Email" />
|
|
41
|
+
<button type="submit" disabled={isLoading}>
|
|
42
|
+
{isLoading ? 'Sending...' : 'Send'}
|
|
43
|
+
</button>
|
|
44
|
+
{error && <p style={{ color: 'red' }}>{error}</p>}
|
|
45
|
+
</form>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### React: Spam Protection (Honeypot)
|
|
51
|
+
|
|
52
|
+
Prevent bot spam effortlessly without annoying CAPTCHAs. Just drop `<ByteonicHoneypot />` anywhere inside your `<form>`! It renders an invisible input field that tricks bots into filling it out.
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { useByteonicIntake, ByteonicHoneypot } from '@byteoniclabs/intake/react';
|
|
56
|
+
|
|
57
|
+
export default function SafeForm() {
|
|
58
|
+
const { submit } = useByteonicIntake('contact-form');
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<form onSubmit={submit}>
|
|
62
|
+
<input type="text" name="name" placeholder="Name" />
|
|
63
|
+
{/* Invisible to humans, catches bots automatically */}
|
|
64
|
+
<ByteonicHoneypot />
|
|
65
|
+
<button type="submit">Submit</button>
|
|
66
|
+
</form>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Vanilla JS Usage
|
|
72
|
+
|
|
73
|
+
If you're not using React, import the core client and use it anywhere. It automatically parses `FormData`.
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
import { ByteonicClient } from '@byteoniclabs/intake';
|
|
77
|
+
|
|
78
|
+
const client = new ByteonicClient({ apiKey: 'YOUR_PUBLISHABLE_API_KEY' });
|
|
79
|
+
const myForm = document.getElementById('my-form');
|
|
80
|
+
|
|
81
|
+
myForm.addEventListener('submit', async (e) => {
|
|
82
|
+
e.preventDefault();
|
|
83
|
+
|
|
84
|
+
// Pass the FormData object directly!
|
|
85
|
+
const response = await client.submit('contact-form', new FormData(myForm));
|
|
86
|
+
|
|
87
|
+
if (response.success) {
|
|
88
|
+
alert('Success!');
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 2. AI Chatbot (React)
|
|
96
|
+
|
|
97
|
+
Deploy a fully customized, real-time AI Support Chatbot with built-in streaming directly into your UI.
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import { useState } from 'react';
|
|
101
|
+
import { useByteonicChatbot } from '@byteoniclabs/intake/react';
|
|
102
|
+
|
|
103
|
+
export default function SupportChat() {
|
|
104
|
+
const {
|
|
105
|
+
messages,
|
|
106
|
+
sendMessage,
|
|
107
|
+
isLoading,
|
|
108
|
+
isStreaming,
|
|
109
|
+
streamedMessage,
|
|
110
|
+
config,
|
|
111
|
+
clearHistory
|
|
112
|
+
} = useByteonicChatbot({
|
|
113
|
+
botId: 'YOUR_BOT_ID',
|
|
114
|
+
apiKey: 'YOUR_PUBLISHABLE_API_KEY'
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const [input, setInput] = useState('');
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<div className="chat-container">
|
|
121
|
+
{/* 1. Display chat history (automatically saved to localStorage!) */}
|
|
122
|
+
{messages.map((m, i) => (
|
|
123
|
+
<div key={i} className={m.role === 'user' ? 'user-bubble' : 'bot-bubble'}>
|
|
124
|
+
{m.content}
|
|
125
|
+
</div>
|
|
126
|
+
))}
|
|
127
|
+
|
|
128
|
+
{/* 2. Display real-time streaming text as the AI types */}
|
|
129
|
+
{isStreaming && streamedMessage && (
|
|
130
|
+
<div className="bot-bubble streaming-effect">
|
|
131
|
+
{streamedMessage} <span className="cursor-blink">|</span>
|
|
132
|
+
</div>
|
|
133
|
+
)}
|
|
134
|
+
|
|
135
|
+
{/* 3. Send messages */}
|
|
136
|
+
<form onSubmit={(e) => { e.preventDefault(); sendMessage(input); setInput(''); }}>
|
|
137
|
+
<input value={input} onChange={e => setInput(e.target.value)} placeholder="Ask me anything..." />
|
|
138
|
+
<button type="submit" disabled={isLoading}>Send</button>
|
|
139
|
+
</form>
|
|
140
|
+
</div>
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 3. Node.js Server SDK
|
|
148
|
+
|
|
149
|
+
If you are handling form submissions on your own backend (like Next.js API Routes, Express, or Fastify) and want to securely proxy the data to Byteonic Intake without exposing your API keys, use the Server SDK.
|
|
150
|
+
|
|
151
|
+
**Features:**
|
|
152
|
+
- Securely spoofs the Origin domain to safely bypass strict whitelisting rules.
|
|
153
|
+
- Forwards user IP addresses to Intake for accurate analytics.
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { ByteonicServerClient } from '@byteoniclabs/intake/server';
|
|
157
|
+
|
|
158
|
+
export async function POST(request) {
|
|
159
|
+
const body = await request.json();
|
|
160
|
+
|
|
161
|
+
// Create client with your private API key
|
|
162
|
+
const client = new ByteonicServerClient({
|
|
163
|
+
apiKey: process.env.BYTEONIC_PRIVATE_API_KEY,
|
|
164
|
+
origin: 'https://my-website.com' // Legally bypass domain whitelisting
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const response = await client.submit('contact-form', body, {
|
|
168
|
+
userIp: request.headers.get('x-forwarded-for'),
|
|
169
|
+
userAgent: request.headers.get('user-agent'),
|
|
170
|
+
sourceUrl: 'Backend API Submission'
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
return Response.json(response);
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Features
|
|
180
|
+
|
|
181
|
+
- **Zero Configuration**: Connects directly to Byteonic Intake's API.
|
|
182
|
+
- **Real-Time Streaming**: Handles complex SSE JSON chunking securely.
|
|
183
|
+
- **LocalStorage Sync**: The React Chatbot automatically persists user conversations securely.
|
|
184
|
+
- **FormData Support**: Automatically digests native HTML `<form>` elements.
|
|
185
|
+
- **Full TypeScript** support out of the box.
|
|
186
|
+
|
|
187
|
+
*Built by [Byteonic Labs](https://byteoniclabs.com)*
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { B as ByteonicConfig, S as SubmissionResponse } from './types-1XzE88JK.mjs';
|
|
2
|
+
|
|
3
|
+
declare class ByteonicClient {
|
|
4
|
+
private apiKey;
|
|
5
|
+
private baseUrl;
|
|
6
|
+
constructor(config: ByteonicConfig);
|
|
7
|
+
/**
|
|
8
|
+
* Submit form data to Byteonic Intake
|
|
9
|
+
* @param formSlug The slug of the form to submit to
|
|
10
|
+
* @param data The form data (Record<string, any> or FormData)
|
|
11
|
+
*/
|
|
12
|
+
submit(formSlug: string, data: Record<string, any> | FormData): Promise<SubmissionResponse>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface ChatMessage {
|
|
16
|
+
role: 'user' | 'assistant' | 'system';
|
|
17
|
+
content: string;
|
|
18
|
+
}
|
|
19
|
+
interface ChatbotConfig {
|
|
20
|
+
botId: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
theme?: string;
|
|
23
|
+
welcomeMessage?: string;
|
|
24
|
+
[key: string]: any;
|
|
25
|
+
}
|
|
26
|
+
interface GenerateResponse {
|
|
27
|
+
success: boolean;
|
|
28
|
+
message?: string;
|
|
29
|
+
error?: string;
|
|
30
|
+
}
|
|
31
|
+
interface GenerateOptions {
|
|
32
|
+
onChunk?: (fullMessage: string) => void;
|
|
33
|
+
}
|
|
34
|
+
declare class ByteonicChatClient {
|
|
35
|
+
private apiKey;
|
|
36
|
+
private baseUrl;
|
|
37
|
+
constructor(config: ByteonicConfig);
|
|
38
|
+
getConfig(botId: string): Promise<ChatbotConfig | null>;
|
|
39
|
+
generate(botId: string, sessionId: string, message: string, history?: ChatMessage[], options?: GenerateOptions): Promise<GenerateResponse>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { ByteonicChatClient, ByteonicClient, ByteonicConfig, type ChatMessage, type ChatbotConfig, type GenerateOptions, type GenerateResponse, SubmissionResponse };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { B as ByteonicConfig, S as SubmissionResponse } from './types-1XzE88JK.js';
|
|
2
|
+
|
|
3
|
+
declare class ByteonicClient {
|
|
4
|
+
private apiKey;
|
|
5
|
+
private baseUrl;
|
|
6
|
+
constructor(config: ByteonicConfig);
|
|
7
|
+
/**
|
|
8
|
+
* Submit form data to Byteonic Intake
|
|
9
|
+
* @param formSlug The slug of the form to submit to
|
|
10
|
+
* @param data The form data (Record<string, any> or FormData)
|
|
11
|
+
*/
|
|
12
|
+
submit(formSlug: string, data: Record<string, any> | FormData): Promise<SubmissionResponse>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface ChatMessage {
|
|
16
|
+
role: 'user' | 'assistant' | 'system';
|
|
17
|
+
content: string;
|
|
18
|
+
}
|
|
19
|
+
interface ChatbotConfig {
|
|
20
|
+
botId: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
theme?: string;
|
|
23
|
+
welcomeMessage?: string;
|
|
24
|
+
[key: string]: any;
|
|
25
|
+
}
|
|
26
|
+
interface GenerateResponse {
|
|
27
|
+
success: boolean;
|
|
28
|
+
message?: string;
|
|
29
|
+
error?: string;
|
|
30
|
+
}
|
|
31
|
+
interface GenerateOptions {
|
|
32
|
+
onChunk?: (fullMessage: string) => void;
|
|
33
|
+
}
|
|
34
|
+
declare class ByteonicChatClient {
|
|
35
|
+
private apiKey;
|
|
36
|
+
private baseUrl;
|
|
37
|
+
constructor(config: ByteonicConfig);
|
|
38
|
+
getConfig(botId: string): Promise<ChatbotConfig | null>;
|
|
39
|
+
generate(botId: string, sessionId: string, message: string, history?: ChatMessage[], options?: GenerateOptions): Promise<GenerateResponse>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { ByteonicChatClient, ByteonicClient, ByteonicConfig, type ChatMessage, type ChatbotConfig, type GenerateOptions, type GenerateResponse, SubmissionResponse };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ByteonicChatClient: () => ByteonicChatClient,
|
|
24
|
+
ByteonicClient: () => ByteonicClient
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
|
|
28
|
+
// src/client.ts
|
|
29
|
+
var ByteonicClient = class {
|
|
30
|
+
constructor(config) {
|
|
31
|
+
if (!config.apiKey) {
|
|
32
|
+
throw new Error("[Byteonic Intake] API Key is required");
|
|
33
|
+
}
|
|
34
|
+
this.apiKey = config.apiKey;
|
|
35
|
+
this.baseUrl = config.baseUrl || "https://intake.byteoniclabs.com/api/external";
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Submit form data to Byteonic Intake
|
|
39
|
+
* @param formSlug The slug of the form to submit to
|
|
40
|
+
* @param data The form data (Record<string, any> or FormData)
|
|
41
|
+
*/
|
|
42
|
+
async submit(formSlug, data) {
|
|
43
|
+
const url = `${this.baseUrl}/forms/${formSlug}/submit`;
|
|
44
|
+
const meta = {
|
|
45
|
+
sdk_version: "1.0.0",
|
|
46
|
+
source_url: typeof window !== "undefined" ? window.location.href : "server",
|
|
47
|
+
submission_source: "byteonic_intake_sdk"
|
|
48
|
+
};
|
|
49
|
+
let fetchOptions = {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: {
|
|
52
|
+
"Authorization": `Bearer ${this.apiKey}`
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
if (typeof FormData !== "undefined" && data instanceof FormData) {
|
|
56
|
+
data.append("_meta", JSON.stringify(meta));
|
|
57
|
+
fetchOptions.body = data;
|
|
58
|
+
} else {
|
|
59
|
+
const payload = data;
|
|
60
|
+
payload._meta = meta;
|
|
61
|
+
fetchOptions.headers = {
|
|
62
|
+
...fetchOptions.headers,
|
|
63
|
+
"Content-Type": "application/json"
|
|
64
|
+
};
|
|
65
|
+
fetchOptions.body = JSON.stringify(payload);
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
const response = await fetch(url, fetchOptions);
|
|
69
|
+
const responseData = await response.json().catch(() => ({}));
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
throw new Error(responseData.error || responseData.message || "Submission failed");
|
|
72
|
+
}
|
|
73
|
+
return responseData;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
error: error.message || "An unexpected error occurred"
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// src/chat.ts
|
|
84
|
+
var ByteonicChatClient = class {
|
|
85
|
+
constructor(config) {
|
|
86
|
+
if (!config.apiKey) {
|
|
87
|
+
throw new Error("[Byteonic Intake] API Key is required");
|
|
88
|
+
}
|
|
89
|
+
this.apiKey = config.apiKey;
|
|
90
|
+
this.baseUrl = config.baseUrl || "https://backend.intake.byteoniclabs.com/api/v1/chat";
|
|
91
|
+
}
|
|
92
|
+
async getConfig(botId) {
|
|
93
|
+
const url = `${this.baseUrl}/config?id=${botId}`;
|
|
94
|
+
try {
|
|
95
|
+
const response = await fetch(url, {
|
|
96
|
+
headers: {
|
|
97
|
+
"Authorization": `Bearer ${this.apiKey}`
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
if (!response.ok) return null;
|
|
101
|
+
return await response.json();
|
|
102
|
+
} catch {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async generate(botId, sessionId, message, history = [], options) {
|
|
107
|
+
const url = `${this.baseUrl}/generate`;
|
|
108
|
+
try {
|
|
109
|
+
const response = await fetch(url, {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: {
|
|
112
|
+
"Content-Type": "application/json",
|
|
113
|
+
"Authorization": `Bearer ${this.apiKey}`
|
|
114
|
+
},
|
|
115
|
+
body: JSON.stringify({
|
|
116
|
+
chatbot_id: botId,
|
|
117
|
+
session_id: sessionId,
|
|
118
|
+
message,
|
|
119
|
+
history
|
|
120
|
+
})
|
|
121
|
+
});
|
|
122
|
+
if (!response.ok) {
|
|
123
|
+
const errorData = await response.json().catch(() => ({}));
|
|
124
|
+
throw new Error(errorData.error || "Generation failed");
|
|
125
|
+
}
|
|
126
|
+
const reader = response.body?.getReader();
|
|
127
|
+
const decoder = new TextDecoder("utf-8");
|
|
128
|
+
let fullMessage = "";
|
|
129
|
+
if (reader) {
|
|
130
|
+
let done = false;
|
|
131
|
+
let buffer = "";
|
|
132
|
+
while (!done) {
|
|
133
|
+
const { value, done: readerDone } = await reader.read();
|
|
134
|
+
done = readerDone;
|
|
135
|
+
if (value) {
|
|
136
|
+
buffer += decoder.decode(value, { stream: true });
|
|
137
|
+
const lines = buffer.split("\n");
|
|
138
|
+
buffer = lines.pop() || "";
|
|
139
|
+
for (const line of lines) {
|
|
140
|
+
if (line.startsWith("data: ") && !line.includes("[DONE]")) {
|
|
141
|
+
try {
|
|
142
|
+
const data = JSON.parse(line.slice(6));
|
|
143
|
+
const content = data.choices?.[0]?.delta?.content;
|
|
144
|
+
if (content) {
|
|
145
|
+
fullMessage += content;
|
|
146
|
+
if (options?.onChunk) options.onChunk(fullMessage);
|
|
147
|
+
}
|
|
148
|
+
} catch (e) {
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return { success: true, message: fullMessage.trim() || "No response generated." };
|
|
156
|
+
} catch (err) {
|
|
157
|
+
return { success: false, error: err.message || "Network error" };
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
162
|
+
0 && (module.exports = {
|
|
163
|
+
ByteonicChatClient,
|
|
164
|
+
ByteonicClient
|
|
165
|
+
});
|
|
166
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/chat.ts"],"sourcesContent":["export * from './client';\r\nexport * from './chat';\r\nexport * from './types';\n","import { ByteonicConfig, SubmissionResponse } from './types';\r\n\r\nexport class ByteonicClient {\r\n private apiKey: string;\r\n private baseUrl: string;\r\n\r\n constructor(config: ByteonicConfig) {\r\n if (!config.apiKey) {\r\n throw new Error('[Byteonic Intake] API Key is required');\r\n }\r\n this.apiKey = config.apiKey;\r\n this.baseUrl = config.baseUrl || 'https://intake.byteoniclabs.com/api/external';\r\n }\r\n\r\n /**\r\n * Submit form data to Byteonic Intake\r\n * @param formSlug The slug of the form to submit to\r\n * @param data The form data (Record<string, any> or FormData)\r\n */\r\n async submit(formSlug: string, data: Record<string, any> | FormData): Promise<SubmissionResponse> {\r\n const url = `${this.baseUrl}/forms/${formSlug}/submit`;\r\n \r\n // Auto-track metadata\r\n const meta = {\r\n sdk_version: '1.0.0',\r\n source_url: typeof window !== 'undefined' ? window.location.href : 'server',\r\n submission_source: 'byteonic_intake_sdk'\r\n };\r\n\r\n let fetchOptions: RequestInit = {\r\n method: 'POST',\r\n headers: {\r\n 'Authorization': `Bearer ${this.apiKey}`\r\n }\r\n };\r\n\r\n if (typeof FormData !== 'undefined' && data instanceof FormData) {\r\n // Native File uploads require FormData to remain untouched.\r\n // Do NOT set Content-Type header, the browser sets the multi-part boundary automatically.\r\n data.append('_meta', JSON.stringify(meta));\r\n fetchOptions.body = data;\r\n } else {\r\n // Standard JSON payload\r\n const payload = data as Record<string, any>;\r\n payload._meta = meta;\r\n \r\n fetchOptions.headers = {\r\n ...fetchOptions.headers,\r\n 'Content-Type': 'application/json'\r\n };\r\n fetchOptions.body = JSON.stringify(payload);\r\n }\r\n\r\n try {\r\n const response = await fetch(url, fetchOptions);\r\n\r\n const responseData = await response.json().catch(() => ({}));\r\n \r\n if (!response.ok) {\r\n throw new Error(responseData.error || responseData.message || 'Submission failed');\r\n }\r\n \r\n return responseData;\r\n } catch (error: any) {\r\n return {\r\n success: false,\r\n error: error.message || 'An unexpected error occurred'\r\n };\r\n }\r\n }\r\n}\r\n","import { ByteonicConfig } from './types';\n\nexport interface ChatMessage {\n role: 'user' | 'assistant' | 'system';\n content: string;\n}\n\nexport interface ChatbotConfig {\n botId: string;\n name?: string;\n theme?: string;\n welcomeMessage?: string;\n [key: string]: any;\n}\n\nexport interface GenerateResponse {\n success: boolean;\n message?: string;\n error?: string;\n}\n\nexport interface GenerateOptions {\n onChunk?: (fullMessage: string) => void;\n}\n\nexport class ByteonicChatClient {\n private apiKey: string;\n private baseUrl: string;\n\n constructor(config: ByteonicConfig) {\n if (!config.apiKey) {\n throw new Error('[Byteonic Intake] API Key is required');\n }\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || 'https://backend.intake.byteoniclabs.com/api/v1/chat';\n }\n\n async getConfig(botId: string): Promise<ChatbotConfig | null> {\n const url = `${this.baseUrl}/config?id=${botId}`;\n try {\n const response = await fetch(url, {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`\n }\n });\n if (!response.ok) return null;\n return await response.json();\n } catch {\n return null;\n }\n }\n\n async generate(botId: string, sessionId: string, message: string, history: ChatMessage[] = [], options?: GenerateOptions): Promise<GenerateResponse> {\n const url = `${this.baseUrl}/generate`;\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`\n },\n body: JSON.stringify({ \n chatbot_id: botId, \n session_id: sessionId, \n message, \n history \n })\n });\n \n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error || 'Generation failed');\n }\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder('utf-8');\n let fullMessage = '';\n\n if (reader) {\n let done = false;\n let buffer = '';\n while (!done) {\n const { value, done: readerDone } = await reader.read();\n done = readerDone;\n if (value) {\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // Keep incomplete lines in buffer\n\n for (const line of lines) {\n if (line.startsWith('data: ') && !line.includes('[DONE]')) {\n try {\n const data = JSON.parse(line.slice(6));\n const content = data.choices?.[0]?.delta?.content;\n if (content) {\n fullMessage += content;\n if (options?.onChunk) options.onChunk(fullMessage);\n }\n } catch (e) {\n // Ignore partial chunk parse errors\n }\n }\n }\n }\n }\n }\n\n return { success: true, message: fullMessage.trim() || 'No response generated.' };\n } catch (err: any) {\n return { success: false, error: err.message || 'Network error' };\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
var ByteonicClient = class {
|
|
3
|
+
constructor(config) {
|
|
4
|
+
if (!config.apiKey) {
|
|
5
|
+
throw new Error("[Byteonic Intake] API Key is required");
|
|
6
|
+
}
|
|
7
|
+
this.apiKey = config.apiKey;
|
|
8
|
+
this.baseUrl = config.baseUrl || "https://intake.byteoniclabs.com/api/external";
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Submit form data to Byteonic Intake
|
|
12
|
+
* @param formSlug The slug of the form to submit to
|
|
13
|
+
* @param data The form data (Record<string, any> or FormData)
|
|
14
|
+
*/
|
|
15
|
+
async submit(formSlug, data) {
|
|
16
|
+
const url = `${this.baseUrl}/forms/${formSlug}/submit`;
|
|
17
|
+
const meta = {
|
|
18
|
+
sdk_version: "1.0.0",
|
|
19
|
+
source_url: typeof window !== "undefined" ? window.location.href : "server",
|
|
20
|
+
submission_source: "byteonic_intake_sdk"
|
|
21
|
+
};
|
|
22
|
+
let fetchOptions = {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: {
|
|
25
|
+
"Authorization": `Bearer ${this.apiKey}`
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
if (typeof FormData !== "undefined" && data instanceof FormData) {
|
|
29
|
+
data.append("_meta", JSON.stringify(meta));
|
|
30
|
+
fetchOptions.body = data;
|
|
31
|
+
} else {
|
|
32
|
+
const payload = data;
|
|
33
|
+
payload._meta = meta;
|
|
34
|
+
fetchOptions.headers = {
|
|
35
|
+
...fetchOptions.headers,
|
|
36
|
+
"Content-Type": "application/json"
|
|
37
|
+
};
|
|
38
|
+
fetchOptions.body = JSON.stringify(payload);
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const response = await fetch(url, fetchOptions);
|
|
42
|
+
const responseData = await response.json().catch(() => ({}));
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
throw new Error(responseData.error || responseData.message || "Submission failed");
|
|
45
|
+
}
|
|
46
|
+
return responseData;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return {
|
|
49
|
+
success: false,
|
|
50
|
+
error: error.message || "An unexpected error occurred"
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// src/chat.ts
|
|
57
|
+
var ByteonicChatClient = class {
|
|
58
|
+
constructor(config) {
|
|
59
|
+
if (!config.apiKey) {
|
|
60
|
+
throw new Error("[Byteonic Intake] API Key is required");
|
|
61
|
+
}
|
|
62
|
+
this.apiKey = config.apiKey;
|
|
63
|
+
this.baseUrl = config.baseUrl || "https://backend.intake.byteoniclabs.com/api/v1/chat";
|
|
64
|
+
}
|
|
65
|
+
async getConfig(botId) {
|
|
66
|
+
const url = `${this.baseUrl}/config?id=${botId}`;
|
|
67
|
+
try {
|
|
68
|
+
const response = await fetch(url, {
|
|
69
|
+
headers: {
|
|
70
|
+
"Authorization": `Bearer ${this.apiKey}`
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
if (!response.ok) return null;
|
|
74
|
+
return await response.json();
|
|
75
|
+
} catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async generate(botId, sessionId, message, history = [], options) {
|
|
80
|
+
const url = `${this.baseUrl}/generate`;
|
|
81
|
+
try {
|
|
82
|
+
const response = await fetch(url, {
|
|
83
|
+
method: "POST",
|
|
84
|
+
headers: {
|
|
85
|
+
"Content-Type": "application/json",
|
|
86
|
+
"Authorization": `Bearer ${this.apiKey}`
|
|
87
|
+
},
|
|
88
|
+
body: JSON.stringify({
|
|
89
|
+
chatbot_id: botId,
|
|
90
|
+
session_id: sessionId,
|
|
91
|
+
message,
|
|
92
|
+
history
|
|
93
|
+
})
|
|
94
|
+
});
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
const errorData = await response.json().catch(() => ({}));
|
|
97
|
+
throw new Error(errorData.error || "Generation failed");
|
|
98
|
+
}
|
|
99
|
+
const reader = response.body?.getReader();
|
|
100
|
+
const decoder = new TextDecoder("utf-8");
|
|
101
|
+
let fullMessage = "";
|
|
102
|
+
if (reader) {
|
|
103
|
+
let done = false;
|
|
104
|
+
let buffer = "";
|
|
105
|
+
while (!done) {
|
|
106
|
+
const { value, done: readerDone } = await reader.read();
|
|
107
|
+
done = readerDone;
|
|
108
|
+
if (value) {
|
|
109
|
+
buffer += decoder.decode(value, { stream: true });
|
|
110
|
+
const lines = buffer.split("\n");
|
|
111
|
+
buffer = lines.pop() || "";
|
|
112
|
+
for (const line of lines) {
|
|
113
|
+
if (line.startsWith("data: ") && !line.includes("[DONE]")) {
|
|
114
|
+
try {
|
|
115
|
+
const data = JSON.parse(line.slice(6));
|
|
116
|
+
const content = data.choices?.[0]?.delta?.content;
|
|
117
|
+
if (content) {
|
|
118
|
+
fullMessage += content;
|
|
119
|
+
if (options?.onChunk) options.onChunk(fullMessage);
|
|
120
|
+
}
|
|
121
|
+
} catch (e) {
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return { success: true, message: fullMessage.trim() || "No response generated." };
|
|
129
|
+
} catch (err) {
|
|
130
|
+
return { success: false, error: err.message || "Network error" };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
export {
|
|
135
|
+
ByteonicChatClient,
|
|
136
|
+
ByteonicClient
|
|
137
|
+
};
|
|
138
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/chat.ts"],"sourcesContent":["import { ByteonicConfig, SubmissionResponse } from './types';\r\n\r\nexport class ByteonicClient {\r\n private apiKey: string;\r\n private baseUrl: string;\r\n\r\n constructor(config: ByteonicConfig) {\r\n if (!config.apiKey) {\r\n throw new Error('[Byteonic Intake] API Key is required');\r\n }\r\n this.apiKey = config.apiKey;\r\n this.baseUrl = config.baseUrl || 'https://intake.byteoniclabs.com/api/external';\r\n }\r\n\r\n /**\r\n * Submit form data to Byteonic Intake\r\n * @param formSlug The slug of the form to submit to\r\n * @param data The form data (Record<string, any> or FormData)\r\n */\r\n async submit(formSlug: string, data: Record<string, any> | FormData): Promise<SubmissionResponse> {\r\n const url = `${this.baseUrl}/forms/${formSlug}/submit`;\r\n \r\n // Auto-track metadata\r\n const meta = {\r\n sdk_version: '1.0.0',\r\n source_url: typeof window !== 'undefined' ? window.location.href : 'server',\r\n submission_source: 'byteonic_intake_sdk'\r\n };\r\n\r\n let fetchOptions: RequestInit = {\r\n method: 'POST',\r\n headers: {\r\n 'Authorization': `Bearer ${this.apiKey}`\r\n }\r\n };\r\n\r\n if (typeof FormData !== 'undefined' && data instanceof FormData) {\r\n // Native File uploads require FormData to remain untouched.\r\n // Do NOT set Content-Type header, the browser sets the multi-part boundary automatically.\r\n data.append('_meta', JSON.stringify(meta));\r\n fetchOptions.body = data;\r\n } else {\r\n // Standard JSON payload\r\n const payload = data as Record<string, any>;\r\n payload._meta = meta;\r\n \r\n fetchOptions.headers = {\r\n ...fetchOptions.headers,\r\n 'Content-Type': 'application/json'\r\n };\r\n fetchOptions.body = JSON.stringify(payload);\r\n }\r\n\r\n try {\r\n const response = await fetch(url, fetchOptions);\r\n\r\n const responseData = await response.json().catch(() => ({}));\r\n \r\n if (!response.ok) {\r\n throw new Error(responseData.error || responseData.message || 'Submission failed');\r\n }\r\n \r\n return responseData;\r\n } catch (error: any) {\r\n return {\r\n success: false,\r\n error: error.message || 'An unexpected error occurred'\r\n };\r\n }\r\n }\r\n}\r\n","import { ByteonicConfig } from './types';\n\nexport interface ChatMessage {\n role: 'user' | 'assistant' | 'system';\n content: string;\n}\n\nexport interface ChatbotConfig {\n botId: string;\n name?: string;\n theme?: string;\n welcomeMessage?: string;\n [key: string]: any;\n}\n\nexport interface GenerateResponse {\n success: boolean;\n message?: string;\n error?: string;\n}\n\nexport interface GenerateOptions {\n onChunk?: (fullMessage: string) => void;\n}\n\nexport class ByteonicChatClient {\n private apiKey: string;\n private baseUrl: string;\n\n constructor(config: ByteonicConfig) {\n if (!config.apiKey) {\n throw new Error('[Byteonic Intake] API Key is required');\n }\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || 'https://backend.intake.byteoniclabs.com/api/v1/chat';\n }\n\n async getConfig(botId: string): Promise<ChatbotConfig | null> {\n const url = `${this.baseUrl}/config?id=${botId}`;\n try {\n const response = await fetch(url, {\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`\n }\n });\n if (!response.ok) return null;\n return await response.json();\n } catch {\n return null;\n }\n }\n\n async generate(botId: string, sessionId: string, message: string, history: ChatMessage[] = [], options?: GenerateOptions): Promise<GenerateResponse> {\n const url = `${this.baseUrl}/generate`;\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.apiKey}`\n },\n body: JSON.stringify({ \n chatbot_id: botId, \n session_id: sessionId, \n message, \n history \n })\n });\n \n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error || 'Generation failed');\n }\n\n const reader = response.body?.getReader();\n const decoder = new TextDecoder('utf-8');\n let fullMessage = '';\n\n if (reader) {\n let done = false;\n let buffer = '';\n while (!done) {\n const { value, done: readerDone } = await reader.read();\n done = readerDone;\n if (value) {\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // Keep incomplete lines in buffer\n\n for (const line of lines) {\n if (line.startsWith('data: ') && !line.includes('[DONE]')) {\n try {\n const data = JSON.parse(line.slice(6));\n const content = data.choices?.[0]?.delta?.content;\n if (content) {\n fullMessage += content;\n if (options?.onChunk) options.onChunk(fullMessage);\n }\n } catch (e) {\n // Ignore partial chunk parse errors\n }\n }\n }\n }\n }\n }\n\n return { success: true, message: fullMessage.trim() || 'No response generated.' };\n } catch (err: any) {\n return { success: false, error: err.message || 'Network error' };\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { S as SubmissionResponse, B as ByteonicConfig } from '../types-1XzE88JK.mjs';
|
|
2
|
+
import React$1, { ReactNode } from 'react';
|
|
3
|
+
import { ByteonicClient, ChatMessage, ChatbotConfig } from '../index.mjs';
|
|
4
|
+
|
|
5
|
+
interface UseByteonicIntakeOptions {
|
|
6
|
+
formSlug: string;
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
declare function useByteonicIntake<T = Record<string, any>>(options: UseByteonicIntakeOptions | string): {
|
|
11
|
+
submit: (data: T | FormData | React.FormEvent<HTMLFormElement>) => Promise<SubmissionResponse | {
|
|
12
|
+
success: boolean;
|
|
13
|
+
error: any;
|
|
14
|
+
}>;
|
|
15
|
+
isLoading: boolean;
|
|
16
|
+
isSuccess: boolean;
|
|
17
|
+
error: string | null;
|
|
18
|
+
response: SubmissionResponse | null;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
interface ByteonicProviderProps extends ByteonicConfig {
|
|
22
|
+
children: ReactNode;
|
|
23
|
+
}
|
|
24
|
+
declare function ByteonicProvider({ apiKey, baseUrl, children }: ByteonicProviderProps): React$1.JSX.Element;
|
|
25
|
+
declare function useByteonicClient(): ByteonicClient;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* A hidden input field used to trick bots into filling it out.
|
|
29
|
+
* If this field is submitted, Byteonic Intake will ignore the submission, protecting you from spam.
|
|
30
|
+
*
|
|
31
|
+
* Simply place `<ByteonicHoneypot />` anywhere inside your `<form>` element.
|
|
32
|
+
*/
|
|
33
|
+
declare function ByteonicHoneypot(): React$1.JSX.Element;
|
|
34
|
+
|
|
35
|
+
interface UseByteonicChatbotOptions {
|
|
36
|
+
botId: string;
|
|
37
|
+
apiKey?: string;
|
|
38
|
+
baseUrl?: string;
|
|
39
|
+
stream?: boolean;
|
|
40
|
+
}
|
|
41
|
+
declare function useByteonicChatbot(options: UseByteonicChatbotOptions | string): {
|
|
42
|
+
messages: ChatMessage[];
|
|
43
|
+
sendMessage: (content: string) => Promise<void>;
|
|
44
|
+
isLoading: boolean;
|
|
45
|
+
isStreaming: boolean;
|
|
46
|
+
streamedMessage: string;
|
|
47
|
+
config: ChatbotConfig | null;
|
|
48
|
+
clearHistory: () => void;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export { ByteonicHoneypot, ByteonicProvider, useByteonicChatbot, useByteonicClient, useByteonicIntake };
|