@axsdk/browser 0.1.1

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 ADDED
@@ -0,0 +1,292 @@
1
+ # @axsdk/browser
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@axsdk/browser)](https://www.npmjs.com/package/@axsdk/browser)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ Vanilla JS embed SDK for the [AXSDK](https://axsdk.ai) AI chat widget. No framework required — drop a single `<script>` tag on any web page to embed a fully-featured AI chat widget inside a sandboxed iframe.
7
+
8
+ ---
9
+
10
+ ## Overview
11
+
12
+ `@axsdk/browser` loads the AXSDK chat UI inside an `<iframe>` using `srcdoc`, keeping the widget completely isolated from your host page's styles and scripts. Communication between the host page and the iframe is handled via `postMessage`.
13
+
14
+ ```
15
+ Host Page iframe (srcdoc)
16
+ ──────────────────────────────── ──────────────────────────────────────────
17
+ <script src="axsdk-browser.iife.js">
18
+ AXSDKBrowser.init(config) ─────────► AXSDK_INIT (postMessage)
19
+ AXSDK.init({ ...config, axHandler: rpc })
20
+ <AXUI /> mounted in document.body
21
+
22
+ AXSDK_HANDLER_REQUEST ◄──────────── axHandler(command, args) [RPC outbound]
23
+ user axHandler callback
24
+ AXSDK_HANDLER_RESPONSE ────────────► Promise resolves / rejects
25
+ ```
26
+
27
+ The parent-page loader (`axsdk-browser.iife.js`) has no React dependency and is very small. The full React + UI bundle (`axsdk-browser-frame.iife.js`) is loaded inside the iframe.
28
+
29
+ ---
30
+
31
+ ## Features
32
+
33
+ - **Zero-dependency embed** — plain `<script>` tag, no npm required for the host page
34
+ - **iframe isolation** — widget styles and scripts cannot bleed into your host page
35
+ - **Responsive sizing** — full-screen on mobile (≤ 767 px), 420 × 680 px panel on desktop; adapts in real-time via `matchMedia`
36
+ - **postMessage communication** — secure, structured RPC protocol between host and iframe
37
+ - **`axHandler` RPC bridge** — AI tool-call handler runs on the host page, not inside the iframe; no cross-origin trust issues
38
+ - **Automatic frame bundle resolution** — frame bundle URL is derived from the loader script's `src`, no manual configuration needed
39
+ - **`destroy()` API** — cleanly removes the widget and releases all listeners
40
+
41
+ ---
42
+
43
+ ## Installation
44
+
45
+ ### npm / bun (monorepo / build pipeline)
46
+
47
+ ```bash
48
+ npm install @axsdk/browser
49
+ # or
50
+ bun add @axsdk/browser
51
+ ```
52
+
53
+ ### CDN / static hosting (recommended for vanilla JS)
54
+
55
+ Copy both files from the package's `dist/` folder to your CDN or web server:
56
+
57
+ | File | Purpose |
58
+ |---|---|
59
+ | `axsdk-browser.iife.js` | Lightweight loader for the host page |
60
+ | `axsdk-browser-frame.iife.js` | Self-contained iframe bundle (React + AXUI + CSS) |
61
+
62
+ Both files **must be served from the same path prefix** — the loader automatically derives the frame bundle URL from its own `src` attribute.
63
+
64
+ ```html
65
+ <!-- Both files must live at the same URL prefix -->
66
+ <script src="https://cdn.example.com/axsdk/axsdk-browser.iife.js"></script>
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Quick Start
72
+
73
+ ```html
74
+ <!DOCTYPE html>
75
+ <html lang="en">
76
+ <head>
77
+ <meta charset="UTF-8" />
78
+ <title>My App</title>
79
+ </head>
80
+ <body>
81
+ <!-- Your page content -->
82
+
83
+ <script src="https://cdn.example.com/axsdk/axsdk-browser.iife.js"></script>
84
+ <script>
85
+ AXSDKBrowser.init({
86
+ apiKey: 'YOUR_API_KEY',
87
+ appId: 'YOUR_APP_ID',
88
+ });
89
+ </script>
90
+ </body>
91
+ </html>
92
+ ```
93
+
94
+ The widget will appear as a fixed floating button in the bottom-right corner of the viewport. Clicking it opens the full chat popup.
95
+
96
+ ---
97
+
98
+ ## Configuration / API Reference
99
+
100
+ ### `AXSDKBrowser.init(config)`
101
+
102
+ Initializes and mounts the chat widget. Can only be called once per page load; subsequent calls are ignored with a console warning.
103
+
104
+ ```ts
105
+ AXSDKBrowser.init(config: AXSDKBrowserConfig): void
106
+ ```
107
+
108
+ #### `AXSDKBrowserConfig`
109
+
110
+ | Option | Type | Required | Description |
111
+ |---|---|---|---|
112
+ | `apiKey` | `string` | ✅ | Your AXSDK API key |
113
+ | `appId` | `string` | ✅ | Your AXSDK application ID |
114
+ | `axHandler` | `(command: string, args: unknown) => Promise<unknown>` | — | Callback invoked when the AI triggers an action. Runs on the host page; return value is sent back to the iframe. |
115
+ | `[key: string]` | `unknown` | — | Any additional serializable keys are forwarded to `AXSDK.init()` inside the iframe (e.g. `headers`, `language`, `debug`, `translations`) |
116
+
117
+ > **Note:** `axHandler` is **not** forwarded via `postMessage` (functions are not serializable). Instead, it is bridged transparently using the `AXSDK_HANDLER_REQUEST` / `AXSDK_HANDLER_RESPONSE` RPC protocol described below.
118
+
119
+ #### Example with `axHandler`
120
+
121
+ ```html
122
+ <script src="https://cdn.example.com/axsdk/axsdk-browser.iife.js"></script>
123
+ <script>
124
+ AXSDKBrowser.init({
125
+ apiKey: 'YOUR_API_KEY',
126
+ appId: 'YOUR_APP_ID',
127
+
128
+ // Optional: handle AI tool calls from the iframe
129
+ axHandler: async (command, args) => {
130
+ if (command === 'getUser') {
131
+ return { name: 'Alice', role: 'admin' };
132
+ }
133
+ throw new Error(`Unknown command: ${command}`);
134
+ },
135
+ });
136
+ </script>
137
+ ```
138
+
139
+ ### `AXSDKBrowser.destroy()`
140
+
141
+ Removes the iframe and cleans up all internal state and listeners.
142
+
143
+ ```ts
144
+ AXSDKBrowser.destroy(): void
145
+ ```
146
+
147
+ ---
148
+
149
+ ## iframe Sizing
150
+
151
+ The iframe is positioned `fixed` and sized automatically:
152
+
153
+ | Viewport | Position | Size |
154
+ |---|---|---|
155
+ | Desktop (> 767 px) | `right: 0; bottom: 0` | `420 × 680 px` |
156
+ | Mobile (≤ 767 px) | `top: 0; left: 0; right: 0; bottom: 0` | `100% × 100dvh` |
157
+
158
+ Sizing updates in real-time when the viewport crosses the 767 px breakpoint. Styles are applied inline via JavaScript; you can override them after `init()` by targeting the iframe element directly.
159
+
160
+ ---
161
+
162
+ ## postMessage Protocol
163
+
164
+ All messages use `window.postMessage` with `'*'` as the target origin.
165
+
166
+ ### Parent → iframe: Initialize
167
+
168
+ Sent automatically by `AXSDKBrowser.init()` after the iframe loads.
169
+
170
+ ```ts
171
+ {
172
+ type: 'AXSDK_INIT';
173
+ config: {
174
+ apiKey: string;
175
+ appId: string;
176
+ // ...any other serializable config keys passed to init()
177
+ // axHandler is NOT included
178
+ };
179
+ }
180
+ ```
181
+
182
+ ### iframe → Parent: Handler RPC request
183
+
184
+ Sent by the iframe when the AI triggers an `axHandler` call.
185
+
186
+ ```ts
187
+ {
188
+ type: 'AXSDK_HANDLER_REQUEST';
189
+ requestId: string; // Unique ID used to match the response
190
+ command: string; // Handler command name
191
+ args: unknown; // Command arguments
192
+ }
193
+ ```
194
+
195
+ ### Parent → iframe: Handler RPC response
196
+
197
+ Sent by `AXSDKBrowser` after calling the user-provided `axHandler`.
198
+
199
+ ```ts
200
+ // On success:
201
+ {
202
+ type: 'AXSDK_HANDLER_RESPONSE';
203
+ requestId: string;
204
+ result: unknown;
205
+ }
206
+
207
+ // On error (axHandler threw):
208
+ {
209
+ type: 'AXSDK_HANDLER_RESPONSE';
210
+ requestId: string;
211
+ error: string; // Error message string
212
+ }
213
+ ```
214
+
215
+ ---
216
+
217
+ ## Build Output
218
+
219
+ | File | Description |
220
+ |---|---|
221
+ | `dist/axsdk-browser.iife.js` | Lightweight parent-page loader. No React. Exposes `AXSDKBrowser` global. |
222
+ | `dist/axsdk-browser-frame.iife.js` | Self-contained iframe bundle — bundles React, `@axsdk/core`, `@axsdk/react`, and inlines all CSS. |
223
+
224
+ ---
225
+
226
+ ## Development
227
+
228
+ ### Prerequisites
229
+
230
+ - [Bun](https://bun.sh) ≥ 1.0
231
+
232
+ ### Install dependencies
233
+
234
+ ```bash
235
+ bun install
236
+ ```
237
+
238
+ ### Build
239
+
240
+ ```bash
241
+ # Build both bundles (loader + frame)
242
+ bun run build
243
+
244
+ # Build only the parent-page loader
245
+ bun run build:browser
246
+
247
+ # Build only the iframe bundle
248
+ bun run build:frame
249
+ ```
250
+
251
+ ### Dev server
252
+
253
+ ```bash
254
+ bun run dev
255
+ ```
256
+
257
+ ### Publish
258
+
259
+ ```bash
260
+ bun run publish
261
+ ```
262
+
263
+ ### Package structure
264
+
265
+ ```
266
+ packages/axsdk-browser/
267
+ ├── src/
268
+ │ ├── embed.ts # Parent-page loader → dist/axsdk-browser.iife.js
269
+ │ └── frame.tsx # iframe React app → dist/axsdk-browser-frame.iife.js
270
+ ├── dist/
271
+ │ ├── axsdk-browser.iife.js
272
+ │ └── axsdk-browser-frame.iife.js
273
+ ├── vite.config.browser.ts # Vite config for the loader bundle
274
+ ├── vite.config.frame.ts # Vite config for the iframe bundle (inlines CSS)
275
+ ├── tsconfig.json
276
+ └── package.json
277
+ ```
278
+
279
+ ---
280
+
281
+ ## Related Packages
282
+
283
+ | Package | Description |
284
+ |---|---|
285
+ | [`@axsdk/core`](../axsdk-core/README.md) | Framework-agnostic core SDK — session management, SSE streaming, event bus |
286
+ | [`@axsdk/react`](../axsdk-react/README.md) | React components — drop-in chat UI built on `@axsdk/core` |
287
+
288
+ ---
289
+
290
+ ## License
291
+
292
+ MIT © [Layorix Inc.](https://github.com/layorixinc)