@yak-io/react 0.7.1 → 0.9.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 +186 -0
- package/dist/YakProvider.d.ts +27 -9
- package/dist/YakProvider.d.ts.map +1 -1
- package/dist/YakProvider.js +72 -17
- package/dist/YakWidget.d.ts +8 -11
- package/dist/YakWidget.d.ts.map +1 -1
- package/dist/YakWidget.js +44 -17
- package/dist/context.d.ts +25 -9
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +13 -8
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/package.json +5 -5
package/README.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# @yak-io/react
|
|
2
|
+
|
|
3
|
+
React integration for the Yak embeddable chat widget. Provides `YakProvider`, `YakWidget`, `useYak`, and `useYakToolEvent`.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @yak-io/react
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For Next.js, use [`@yak-io/nextjs`](../nextjs) instead — it adds route scanning and server handler factories on top of this package.
|
|
12
|
+
|
|
13
|
+
## Quickstart
|
|
14
|
+
|
|
15
|
+
### 1. Wrap your app with `YakProvider`
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
// src/App.tsx (or your root layout)
|
|
19
|
+
import { YakProvider, YakWidget } from "@yak-io/react";
|
|
20
|
+
|
|
21
|
+
export default function App({ children }: { children: React.ReactNode }) {
|
|
22
|
+
return (
|
|
23
|
+
<YakProvider
|
|
24
|
+
appId={import.meta.env.VITE_YAK_APP_ID}
|
|
25
|
+
theme={{ position: "bottom-right", colorMode: "system" }}
|
|
26
|
+
getConfig={async () => {
|
|
27
|
+
const res = await fetch("/api/yak");
|
|
28
|
+
return res.json();
|
|
29
|
+
}}
|
|
30
|
+
onToolCall={async (name, args) => {
|
|
31
|
+
const res = await fetch("/api/yak", {
|
|
32
|
+
method: "POST",
|
|
33
|
+
headers: { "Content-Type": "application/json" },
|
|
34
|
+
body: JSON.stringify({ name, args }),
|
|
35
|
+
});
|
|
36
|
+
const data = await res.json();
|
|
37
|
+
if (!data.ok) throw new Error(data.error);
|
|
38
|
+
return data.result;
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
{children}
|
|
42
|
+
<YakWidget />
|
|
43
|
+
</YakProvider>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2. Control the widget programmatically
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { useYak } from "@yak-io/react";
|
|
52
|
+
|
|
53
|
+
export function HelpButton() {
|
|
54
|
+
const { open, openWithPrompt, isOpen } = useYak();
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div>
|
|
58
|
+
<button onClick={open}>Open Chat</button>
|
|
59
|
+
<button onClick={() => openWithPrompt("How do I get started?")}>
|
|
60
|
+
Get Help
|
|
61
|
+
</button>
|
|
62
|
+
{isOpen && <p>Chat is open</p>}
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 3. Invalidate data after tool calls
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
import { useYakToolEvent } from "@yak-io/react";
|
|
72
|
+
|
|
73
|
+
function TasksPage() {
|
|
74
|
+
const [tasks, setTasks] = useState([]);
|
|
75
|
+
|
|
76
|
+
// Re-fetch when the chatbot modifies tasks
|
|
77
|
+
useYakToolEvent((event) => {
|
|
78
|
+
if (event.ok && event.name.startsWith("tasks.")) {
|
|
79
|
+
fetchTasks().then(setTasks);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// ...
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## API Reference
|
|
88
|
+
|
|
89
|
+
### `YakProvider`
|
|
90
|
+
|
|
91
|
+
Sets up context, initializes the widget, and delegates DOM rendering to `@yak-io/javascript`.
|
|
92
|
+
|
|
93
|
+
**Props:**
|
|
94
|
+
|
|
95
|
+
| Prop | Type | Required | Description |
|
|
96
|
+
|------|------|----------|-------------|
|
|
97
|
+
| `appId` | `string` | ✅ | Your Yak app ID |
|
|
98
|
+
| `children` | `ReactNode` | ✅ | Your app content |
|
|
99
|
+
| `getConfig` | `ChatConfigProvider` | — | Async function returning routes + tools config. Called when the widget opens. |
|
|
100
|
+
| `onToolCall` | `ToolCallHandler` | — | Handle tool calls from the assistant |
|
|
101
|
+
| `onGraphQLSchemaCall` | `GraphQLSchemaHandler` | — | Handle GraphQL schema tool calls |
|
|
102
|
+
| `onRESTSchemaCall` | `RESTSchemaHandler` | — | Handle REST/OpenAPI schema tool calls |
|
|
103
|
+
| `theme` | `Theme` | — | Widget theme (position, colorMode, colors) |
|
|
104
|
+
| `onRedirect` | `(path: string) => void` | — | Custom navigation handler (defaults to `window.location.assign`) |
|
|
105
|
+
| `disableRestartButton` | `boolean` | — | Hide the restart session button |
|
|
106
|
+
| `trigger` | `boolean \| TriggerButtonConfig` | — | Built-in trigger button config (`false` by default — use `<YakWidget>` instead) |
|
|
107
|
+
|
|
108
|
+
### `YakWidget`
|
|
109
|
+
|
|
110
|
+
Renders a fixed-position launcher button. Place it anywhere inside `YakProvider`.
|
|
111
|
+
|
|
112
|
+
**Props:**
|
|
113
|
+
|
|
114
|
+
| Prop | Type | Description |
|
|
115
|
+
|------|------|-------------|
|
|
116
|
+
| `triggerLabel` | `string` | Button label (default: `"Ask with AI"`) |
|
|
117
|
+
| `position` | `WidgetPosition` | Button position (default: `"bottom-right"`) |
|
|
118
|
+
| `colorMode` | `"light" \| "dark" \| "system"` | Color mode override |
|
|
119
|
+
| `lightButton` | `{ background?, color?, border? }` | Custom light mode button colors |
|
|
120
|
+
| `darkButton` | `{ background?, color?, border? }` | Custom dark mode button colors |
|
|
121
|
+
|
|
122
|
+
### `useYak()`
|
|
123
|
+
|
|
124
|
+
Access the widget API from any component inside `YakProvider`.
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
const {
|
|
128
|
+
isOpen, // boolean — whether the widget is open
|
|
129
|
+
isReady, // boolean — whether the iframe is ready
|
|
130
|
+
open, // () => void
|
|
131
|
+
close, // () => void
|
|
132
|
+
openWithPrompt, // (prompt: string) => void
|
|
133
|
+
subscribeToToolEvents, // (handler) => () => void
|
|
134
|
+
} = useYak();
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Throws if called outside `YakProvider`.
|
|
138
|
+
|
|
139
|
+
### `useYakToolEvent(handler)`
|
|
140
|
+
|
|
141
|
+
Subscribe to tool call completion events. Automatically unsubscribes on unmount. Useful for cache invalidation when the chatbot modifies data.
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
useYakToolEvent((event) => {
|
|
145
|
+
// event.name — the tool name called ("tasks.list")
|
|
146
|
+
// event.args — arguments passed to the tool
|
|
147
|
+
// event.ok — whether the call succeeded
|
|
148
|
+
// event.result — the result (if ok)
|
|
149
|
+
// event.error — error message (if not ok)
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Logging
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { enableYakLogging, disableYakLogging, isYakLoggingEnabled } from "@yak-io/react";
|
|
157
|
+
|
|
158
|
+
enableYakLogging(); // Enable verbose SDK logs
|
|
159
|
+
disableYakLogging(); // Disable SDK logs
|
|
160
|
+
isYakLoggingEnabled(); // → boolean
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Types
|
|
164
|
+
|
|
165
|
+
All key types are re-exported for convenience:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import type {
|
|
169
|
+
ChatConfigProvider,
|
|
170
|
+
ToolCallHandler,
|
|
171
|
+
ToolCallEvent,
|
|
172
|
+
GraphQLSchemaHandler,
|
|
173
|
+
RESTSchemaHandler,
|
|
174
|
+
Theme,
|
|
175
|
+
ThemeColors,
|
|
176
|
+
TriggerButtonConfig,
|
|
177
|
+
WidgetPosition,
|
|
178
|
+
SchemaSource,
|
|
179
|
+
GraphQLSchemaSource,
|
|
180
|
+
OpenAPISchemaSource,
|
|
181
|
+
} from "@yak-io/react";
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
Proprietary — see LICENSE file.
|
package/dist/YakProvider.d.ts
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
|
+
import { type ChatConfigProvider, type GraphQLSchemaHandler, type RESTSchemaHandler, type Theme, type ToolCallHandler, type TriggerButtonConfig, type UserIdentity, type WidgetMode } from "@yak-io/javascript";
|
|
1
2
|
import type React from "react";
|
|
2
|
-
import { type TriggerButtonConfig, type ChatConfigProvider, type ToolCallHandler, type GraphQLSchemaHandler, type RESTSchemaHandler, type Theme } from "@yak-io/javascript";
|
|
3
3
|
/**
|
|
4
4
|
* Props for YakProvider
|
|
5
5
|
*/
|
|
6
6
|
export type YakProviderProps = {
|
|
7
7
|
/** App identifier in the yak SaaS */
|
|
8
8
|
appId: string;
|
|
9
|
+
/**
|
|
10
|
+
* Which experiences this widget exposes.
|
|
11
|
+
* "chat" — chat only (iframe).
|
|
12
|
+
* "voice" — voice only (WebRTC).
|
|
13
|
+
* "both" — both, sharing one trigger pill.
|
|
14
|
+
* Default: "chat".
|
|
15
|
+
*/
|
|
16
|
+
mode?: WidgetMode;
|
|
9
17
|
/**
|
|
10
18
|
* Provider function for chat configuration (routes + tools).
|
|
11
19
|
* The consuming platform decides how to get the config (static, fetch, etc.)
|
|
12
|
-
* Called when the
|
|
20
|
+
* Called when the chat is opened or when a voice session starts.
|
|
13
21
|
*/
|
|
14
22
|
getConfig?: ChatConfigProvider;
|
|
15
23
|
/**
|
|
16
|
-
* Handler for tool calls from the chat
|
|
24
|
+
* Handler for tool calls from the chat or voice runtime.
|
|
17
25
|
* The consuming platform decides how to execute (browser, server fetch, etc.)
|
|
18
26
|
*/
|
|
19
27
|
onToolCall?: ToolCallHandler;
|
|
@@ -32,17 +40,27 @@ export type YakProviderProps = {
|
|
|
32
40
|
/** Disable the restart session button in the header */
|
|
33
41
|
disableRestartButton?: boolean;
|
|
34
42
|
/**
|
|
35
|
-
* Trigger button configuration. Pass `false` to disable the built-in trigger
|
|
36
|
-
* (useful when
|
|
43
|
+
* Trigger button configuration. Pass `false` to disable the built-in trigger
|
|
44
|
+
* (useful when rendering `<YakWidget />` separately). Defaults to `false`.
|
|
37
45
|
*/
|
|
38
46
|
trigger?: boolean | TriggerButtonConfig;
|
|
47
|
+
/**
|
|
48
|
+
* Signed end-user identity for server-side conversation persistence.
|
|
49
|
+
*
|
|
50
|
+
* Compute the `hash` on your backend with
|
|
51
|
+
* `HMAC-SHA256(application.apiSecret, user.id)` and pass it down to the
|
|
52
|
+
* browser. When supplied, the widget stores conversations server-side and
|
|
53
|
+
* shows a history pane so end-users can resume past chats. When omitted,
|
|
54
|
+
* the widget runs in anonymous mode (no persistence).
|
|
55
|
+
*/
|
|
56
|
+
user?: UserIdentity;
|
|
39
57
|
/** Children components */
|
|
40
58
|
children: React.ReactNode;
|
|
41
59
|
};
|
|
42
60
|
/**
|
|
43
|
-
* YakProvider sets up the
|
|
44
|
-
*
|
|
45
|
-
*
|
|
61
|
+
* YakProvider sets up the unified chat + voice runtime. All DOM rendering
|
|
62
|
+
* (panel, iframe, optional trigger) is delegated to YakEmbed. Consumers
|
|
63
|
+
* access both surfaces via `useYak()`.
|
|
46
64
|
*/
|
|
47
|
-
export declare function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall, onRESTSchemaCall, theme, onRedirect, disableRestartButton, trigger, children, }: YakProviderProps): React.JSX.Element;
|
|
65
|
+
export declare function YakProvider({ appId, mode, getConfig, onToolCall, onGraphQLSchemaCall, onRESTSchemaCall, theme, onRedirect, disableRestartButton, trigger, user, children, }: YakProviderProps): React.JSX.Element;
|
|
48
66
|
//# sourceMappingURL=YakProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"YakProvider.d.ts","sourceRoot":"","sources":["../src/YakProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"YakProvider.d.ts","sourceRoot":"","sources":["../src/YakProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EAGzB,KAAK,iBAAiB,EACtB,KAAK,KAAK,EAEV,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EAEjB,KAAK,UAAU,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;;OAIG;IACH,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B;;;OAGG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B;;OAEG;IACH,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;IAC3C;;OAEG;IACH,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IACrC,mCAAmC;IACnC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,qEAAqE;IACrE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,uDAAuD;IACvD,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAC;IACxC;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,0BAA0B;IAC1B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,IAAa,EACb,SAAS,EACT,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,EACL,UAAU,EACV,oBAAoB,EACpB,OAAe,EACf,IAAI,EACJ,QAAQ,GACT,EAAE,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA6MtC"}
|
package/dist/YakProvider.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { INITIAL_VOICE_MACHINE, logger, YakEmbed, } from "@yak-io/javascript";
|
|
4
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
5
|
import { YakContext } from "./context.js";
|
|
5
|
-
import { YakEmbed, } from "@yak-io/javascript";
|
|
6
|
-
import { logger } from "@yak-io/javascript";
|
|
7
6
|
/**
|
|
8
|
-
* YakProvider sets up the
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* YakProvider sets up the unified chat + voice runtime. All DOM rendering
|
|
8
|
+
* (panel, iframe, optional trigger) is delegated to YakEmbed. Consumers
|
|
9
|
+
* access both surfaces via `useYak()`.
|
|
11
10
|
*/
|
|
12
|
-
export function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall, onRESTSchemaCall, theme, onRedirect, disableRestartButton, trigger = false, children, }) {
|
|
11
|
+
export function YakProvider({ appId, mode = "chat", getConfig, onToolCall, onGraphQLSchemaCall, onRESTSchemaCall, theme, onRedirect, disableRestartButton, trigger = false, user, children, }) {
|
|
13
12
|
const [isOpen, setIsOpen] = useState(false);
|
|
14
|
-
const [
|
|
13
|
+
const [isReady, setIsReady] = useState(false);
|
|
14
|
+
const [voiceMachine, setVoiceMachine] = useState(INITIAL_VOICE_MACHINE);
|
|
15
15
|
// Store event subscribers for tool call events
|
|
16
16
|
const toolEventSubscribersRef = useRef(new Set());
|
|
17
17
|
// Handler that notifies all subscribers when a tool call completes
|
|
@@ -45,30 +45,36 @@ export function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall,
|
|
|
45
45
|
if (!embedRef.current) {
|
|
46
46
|
embedRef.current = new YakEmbed({
|
|
47
47
|
appId,
|
|
48
|
+
mode,
|
|
48
49
|
theme,
|
|
49
50
|
trigger,
|
|
51
|
+
getConfig,
|
|
50
52
|
onToolCall,
|
|
51
53
|
onGraphQLSchemaCall,
|
|
52
54
|
onRESTSchemaCall,
|
|
53
55
|
onRedirect: resolvedRedirect,
|
|
54
56
|
options: { disableRestartButton },
|
|
55
57
|
onToolCallComplete: handleToolCallComplete,
|
|
58
|
+
user,
|
|
56
59
|
});
|
|
57
60
|
}
|
|
58
61
|
const embed = embedRef.current;
|
|
59
|
-
// Mount/unmount embed and subscribe to state changes
|
|
62
|
+
// Mount/unmount embed and subscribe to chat + voice state changes
|
|
60
63
|
useEffect(() => {
|
|
61
64
|
embed.mount();
|
|
62
|
-
const
|
|
65
|
+
const unsubscribeChat = embed.onStateChange((state) => {
|
|
63
66
|
setIsOpen(state.isOpen);
|
|
64
|
-
|
|
67
|
+
setIsReady(state.isReady);
|
|
65
68
|
});
|
|
69
|
+
const unsubscribeVoice = embed.onVoiceStateChange((m) => setVoiceMachine(m));
|
|
66
70
|
return () => {
|
|
67
|
-
|
|
71
|
+
unsubscribeChat();
|
|
72
|
+
unsubscribeVoice();
|
|
68
73
|
embed.destroy();
|
|
69
74
|
};
|
|
70
75
|
}, [embed]);
|
|
71
|
-
// Update embed config when props change
|
|
76
|
+
// Update embed config when props change. Chat config goes via the client;
|
|
77
|
+
// voice config goes via the voice session.
|
|
72
78
|
useEffect(() => {
|
|
73
79
|
embed.getClient().updateConfig({
|
|
74
80
|
appId,
|
|
@@ -79,9 +85,19 @@ export function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall,
|
|
|
79
85
|
onRedirect: resolvedRedirect,
|
|
80
86
|
options: { disableRestartButton },
|
|
81
87
|
onToolCallComplete: handleToolCallComplete,
|
|
88
|
+
user,
|
|
89
|
+
});
|
|
90
|
+
embed.getVoiceSession()?.updateConfig({
|
|
91
|
+
appId,
|
|
92
|
+
getConfig,
|
|
93
|
+
onToolCall,
|
|
94
|
+
onGraphQLSchemaCall,
|
|
95
|
+
onRESTSchemaCall,
|
|
96
|
+
onRedirect: resolvedRedirect,
|
|
82
97
|
});
|
|
83
98
|
}, [
|
|
84
99
|
appId,
|
|
100
|
+
getConfig,
|
|
85
101
|
onToolCall,
|
|
86
102
|
onGraphQLSchemaCall,
|
|
87
103
|
onRESTSchemaCall,
|
|
@@ -90,8 +106,9 @@ export function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall,
|
|
|
90
106
|
disableRestartButton,
|
|
91
107
|
embed,
|
|
92
108
|
handleToolCallComplete,
|
|
109
|
+
user,
|
|
93
110
|
]);
|
|
94
|
-
// Fetch chat config when
|
|
111
|
+
// Fetch chat config when the chat is opened
|
|
95
112
|
useEffect(() => {
|
|
96
113
|
if (typeof window === "undefined" || !isOpen || !getConfig)
|
|
97
114
|
return;
|
|
@@ -113,10 +130,21 @@ export function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall,
|
|
|
113
130
|
cancelled = true;
|
|
114
131
|
};
|
|
115
132
|
}, [getConfig, isOpen, embed]);
|
|
116
|
-
//
|
|
133
|
+
// Chat methods
|
|
117
134
|
const open = useCallback(() => embed.open(), [embed]);
|
|
118
135
|
const close = useCallback(() => embed.close(), [embed]);
|
|
119
136
|
const openWithPrompt = useCallback((prompt) => embed.openWithPrompt(prompt), [embed]);
|
|
137
|
+
// Voice methods
|
|
138
|
+
const voiceStart = useCallback(async () => {
|
|
139
|
+
try {
|
|
140
|
+
await embed.voiceStart();
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
logger.warn("Voice start failed", err);
|
|
144
|
+
}
|
|
145
|
+
}, [embed]);
|
|
146
|
+
const voiceStop = useCallback(() => embed.voiceStop(), [embed]);
|
|
147
|
+
const voiceToggle = useCallback(() => embed.voiceToggle(), [embed]);
|
|
120
148
|
// Subscribe to tool call completion events
|
|
121
149
|
const subscribeToToolEvents = useCallback((handler) => {
|
|
122
150
|
toolEventSubscribersRef.current.add(handler);
|
|
@@ -128,14 +156,41 @@ export function YakProvider({ appId, getConfig, onToolCall, onGraphQLSchemaCall,
|
|
|
128
156
|
}, []);
|
|
129
157
|
// Expose iframe origin for YakWidget
|
|
130
158
|
const getIframeOrigin = useCallback(() => embed.getClient().getIframeOrigin(), [embed]);
|
|
159
|
+
const voiceState = voiceMachine.state;
|
|
160
|
+
const voiceIsActive = voiceState !== "idle" && voiceState !== "error";
|
|
131
161
|
const contextValue = useMemo(() => ({
|
|
162
|
+
mode,
|
|
132
163
|
isOpen,
|
|
133
|
-
|
|
164
|
+
isReady,
|
|
134
165
|
open,
|
|
135
166
|
close,
|
|
136
167
|
openWithPrompt,
|
|
137
168
|
subscribeToToolEvents,
|
|
169
|
+
voiceMachine,
|
|
170
|
+
voiceState,
|
|
171
|
+
voiceErrorMessage: voiceMachine.errorMessage,
|
|
172
|
+
voiceIsActive,
|
|
173
|
+
voiceStart,
|
|
174
|
+
voiceStop,
|
|
175
|
+
voiceToggle,
|
|
138
176
|
getIframeOrigin,
|
|
139
|
-
|
|
177
|
+
theme,
|
|
178
|
+
}), [
|
|
179
|
+
mode,
|
|
180
|
+
isOpen,
|
|
181
|
+
isReady,
|
|
182
|
+
open,
|
|
183
|
+
close,
|
|
184
|
+
openWithPrompt,
|
|
185
|
+
subscribeToToolEvents,
|
|
186
|
+
voiceMachine,
|
|
187
|
+
voiceState,
|
|
188
|
+
voiceIsActive,
|
|
189
|
+
voiceStart,
|
|
190
|
+
voiceStop,
|
|
191
|
+
voiceToggle,
|
|
192
|
+
getIframeOrigin,
|
|
193
|
+
theme,
|
|
194
|
+
]);
|
|
140
195
|
return _jsx(YakContext.Provider, { value: contextValue, children: children });
|
|
141
196
|
}
|
package/dist/YakWidget.d.ts
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
+
import type { WidgetMode } from "@yak-io/javascript";
|
|
1
2
|
import type React from "react";
|
|
2
|
-
import type { WidgetPosition } from "@yak-io/javascript";
|
|
3
3
|
/**
|
|
4
4
|
* Props for YakWidget
|
|
5
5
|
*/
|
|
6
6
|
export type YakWidgetProps = {
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
/** Position of the button (defaults to theme position or "bottom-right") */
|
|
10
|
-
position?: WidgetPosition;
|
|
11
|
-
/** Color mode override */
|
|
12
|
-
colorMode?: "light" | "dark" | "system";
|
|
7
|
+
/** Override the mode from the provider. */
|
|
8
|
+
mode?: WidgetMode;
|
|
13
9
|
/** Custom button colors for light mode */
|
|
14
10
|
lightButton?: {
|
|
15
11
|
background?: string;
|
|
@@ -24,9 +20,10 @@ export type YakWidgetProps = {
|
|
|
24
20
|
};
|
|
25
21
|
};
|
|
26
22
|
/**
|
|
27
|
-
* YakWidget renders a fixed-position launcher
|
|
28
|
-
*
|
|
29
|
-
*
|
|
23
|
+
* YakWidget renders a fixed-position launcher pill. The logo sits on the
|
|
24
|
+
* left; one or two icon buttons sit on the right based on `mode`. Trigger
|
|
25
|
+
* CSS is injected by YakEmbed (via YakProvider) — this component only
|
|
26
|
+
* provides the React markup using those shared class names.
|
|
30
27
|
*/
|
|
31
|
-
export declare function YakWidget({
|
|
28
|
+
export declare function YakWidget({ mode, lightButton, darkButton, }?: YakWidgetProps): React.JSX.Element;
|
|
32
29
|
//# sourceMappingURL=YakWidget.d.ts.map
|
package/dist/YakWidget.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"YakWidget.d.ts","sourceRoot":"","sources":["../src/YakWidget.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"YakWidget.d.ts","sourceRoot":"","sources":["../src/YakWidget.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,2CAA2C;IAC3C,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,0CAA0C;IAC1C,WAAW,CAAC,EAAE;QACZ,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,yCAAyC;IACzC,UAAU,CAAC,EAAE;QACX,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AAsGF;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,WAAW,EACX,UAAU,GACX,GAAE,cAAmB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAkEzC"}
|
package/dist/YakWidget.js
CHANGED
|
@@ -1,10 +1,32 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import { useYakInternal } from "./context.js";
|
|
4
|
+
const VOICE_ARIA = {
|
|
5
|
+
idle: "Start voice mode",
|
|
6
|
+
connecting: "Connecting voice session",
|
|
7
|
+
listening: "Voice listening — tap to stop",
|
|
8
|
+
thinking: "Voice thinking — tap to stop",
|
|
9
|
+
speaking: "Voice speaking — tap to stop",
|
|
10
|
+
error: "Voice error — tap to retry",
|
|
11
|
+
};
|
|
12
|
+
function MessageCircleIcon() {
|
|
13
|
+
return (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", width: 20, height: 20, "aria-hidden": "true", children: _jsx("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }) }));
|
|
14
|
+
}
|
|
15
|
+
function AudioLinesIcon() {
|
|
16
|
+
return (_jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", width: 20, height: 20, "aria-hidden": "true", children: [_jsx("path", { d: "M2 10v3" }), _jsx("path", { d: "M6 6v11" }), _jsx("path", { d: "M10 3v18" }), _jsx("path", { d: "M14 8v7" }), _jsx("path", { d: "M18 5v13" }), _jsx("path", { d: "M22 10v3" })] }));
|
|
17
|
+
}
|
|
18
|
+
function StopIcon() {
|
|
19
|
+
return (_jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", width: 20, height: 20, "aria-hidden": "true", children: _jsx("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2" }) }));
|
|
20
|
+
}
|
|
21
|
+
function VoiceIcon({ state }) {
|
|
22
|
+
if (state === "connecting") {
|
|
23
|
+
return _jsx("span", { className: "yak-widget-spinner", "aria-hidden": "true" });
|
|
24
|
+
}
|
|
25
|
+
if (state === "listening" || state === "speaking" || state === "thinking") {
|
|
26
|
+
return _jsx(StopIcon, {});
|
|
27
|
+
}
|
|
28
|
+
return _jsx(AudioLinesIcon, {});
|
|
29
|
+
}
|
|
8
30
|
function buildButtonStyle(lightButton, darkButton) {
|
|
9
31
|
const style = {};
|
|
10
32
|
if (lightButton?.background)
|
|
@@ -21,9 +43,6 @@ function buildButtonStyle(lightButton, darkButton) {
|
|
|
21
43
|
style["--yak-btn-dark-border"] = darkButton.border;
|
|
22
44
|
return style;
|
|
23
45
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Compute button class names from color mode and custom theme flags
|
|
26
|
-
*/
|
|
27
46
|
function buildButtonClasses(colorMode, hasLightCustom, hasDarkCustom) {
|
|
28
47
|
const colorModeClass = colorMode === "light" ? "yak-widget-light" : colorMode === "dark" ? "yak-widget-dark" : "";
|
|
29
48
|
let customButtonClass = "";
|
|
@@ -36,18 +55,26 @@ function buildButtonClasses(colorMode, hasLightCustom, hasDarkCustom) {
|
|
|
36
55
|
return ["yak-widget-trigger", colorModeClass, customButtonClass].filter(Boolean).join(" ");
|
|
37
56
|
}
|
|
38
57
|
/**
|
|
39
|
-
* YakWidget renders a fixed-position launcher
|
|
40
|
-
*
|
|
41
|
-
*
|
|
58
|
+
* YakWidget renders a fixed-position launcher pill. The logo sits on the
|
|
59
|
+
* left; one or two icon buttons sit on the right based on `mode`. Trigger
|
|
60
|
+
* CSS is injected by YakEmbed (via YakProvider) — this component only
|
|
61
|
+
* provides the React markup using those shared class names.
|
|
42
62
|
*/
|
|
43
|
-
export function YakWidget({
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
const
|
|
63
|
+
export function YakWidget({ mode, lightButton, darkButton, } = {}) {
|
|
64
|
+
const ctx = useYakInternal();
|
|
65
|
+
const resolvedMode = mode ?? ctx.mode;
|
|
66
|
+
const position = ctx.theme?.position ?? "bottom-left";
|
|
67
|
+
const colorMode = ctx.theme?.colorMode;
|
|
68
|
+
const logoUrl = `${ctx.getIframeOrigin()}/logo.svg`;
|
|
69
|
+
const showChat = resolvedMode === "chat" || resolvedMode === "both";
|
|
70
|
+
const showVoice = resolvedMode === "voice" || resolvedMode === "both";
|
|
71
|
+
const chatLoading = ctx.isOpen && !ctx.isReady;
|
|
72
|
+
const voiceConnecting = ctx.voiceState === "connecting";
|
|
48
73
|
const hasLightCustom = lightButton?.background || lightButton?.color || lightButton?.border;
|
|
49
74
|
const hasDarkCustom = darkButton?.background || darkButton?.color || darkButton?.border;
|
|
50
75
|
const buttonStyle = buildButtonStyle(lightButton, darkButton);
|
|
51
76
|
const buttonClasses = buildButtonClasses(colorMode, hasLightCustom, hasDarkCustom);
|
|
52
|
-
return (_jsxs("
|
|
77
|
+
return (_jsxs("div", { className: buttonClasses, style: Object.keys(buttonStyle).length > 0 ? buttonStyle : undefined, "data-position": position, "data-mode": resolvedMode, "data-has-light-custom": hasLightCustom || undefined, "data-has-dark-custom": hasDarkCustom || undefined, children: [_jsx("div", { className: "yak-widget-icon-bg", children: _jsx("img", { src: logoUrl, alt: "", width: 20, height: 20, className: "yak-widget-icon" }) }), showChat && (_jsx("button", { type: "button", className: "yak-widget-trigger-icon-btn", "data-action": "chat", "aria-label": chatLoading ? "Loading chat" : "Open chat", disabled: chatLoading, onClick: ctx.open, children: chatLoading ? (_jsx("span", { className: "yak-widget-spinner", "aria-hidden": "true" })) : (_jsx(MessageCircleIcon, {})) })), showVoice && (_jsx("button", { type: "button", className: "yak-widget-trigger-icon-btn", "data-action": "voice", "data-state": ctx.voiceState, "aria-label": VOICE_ARIA[ctx.voiceState], disabled: voiceConnecting, onClick: () => {
|
|
78
|
+
void ctx.voiceToggle();
|
|
79
|
+
}, children: _jsx(VoiceIcon, { state: ctx.voiceState }) }))] }));
|
|
53
80
|
}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ChatConfig, Theme, ToolCallEvent, VoiceMachine, VoiceState, WidgetMode } from "@yak-io/javascript";
|
|
2
2
|
/**
|
|
3
3
|
* Configuration for the yak provider
|
|
4
4
|
*/
|
|
@@ -13,14 +13,16 @@ export type YakConfig = {
|
|
|
13
13
|
*/
|
|
14
14
|
export type ToolCallEventHandler = (event: ToolCallEvent) => void;
|
|
15
15
|
/**
|
|
16
|
-
* Public API for controlling the Yak chat
|
|
16
|
+
* Public API for controlling the Yak widget — chat + voice combined.
|
|
17
17
|
* This is what consumers get from useYak().
|
|
18
18
|
*/
|
|
19
19
|
export type YakContextValue = {
|
|
20
|
+
/** Which modes are exposed: "chat", "voice", or "both". */
|
|
21
|
+
mode: WidgetMode;
|
|
20
22
|
/** Whether the chat widget is currently open */
|
|
21
23
|
isOpen: boolean;
|
|
22
24
|
/** Whether the iframe is ready to receive messages */
|
|
23
|
-
|
|
25
|
+
isReady: boolean;
|
|
24
26
|
/** Open the chat widget */
|
|
25
27
|
open: () => void;
|
|
26
28
|
/** Close the chat widget */
|
|
@@ -29,6 +31,20 @@ export type YakContextValue = {
|
|
|
29
31
|
openWithPrompt: (prompt: string) => void;
|
|
30
32
|
/** Subscribe to tool call completion events */
|
|
31
33
|
subscribeToToolEvents: (handler: ToolCallEventHandler) => () => void;
|
|
34
|
+
/** Current voice state machine snapshot. `idle` when mode === "chat". */
|
|
35
|
+
voiceMachine: VoiceMachine;
|
|
36
|
+
/** Convenience: `voiceMachine.state`. */
|
|
37
|
+
voiceState: VoiceState;
|
|
38
|
+
/** Convenience: error message when voiceState === "error". */
|
|
39
|
+
voiceErrorMessage: string | undefined;
|
|
40
|
+
/** Whether a voice session is currently live (connecting/listening/thinking/speaking). */
|
|
41
|
+
voiceIsActive: boolean;
|
|
42
|
+
/** Start a voice session. Must be invoked from a user gesture. */
|
|
43
|
+
voiceStart: () => Promise<void>;
|
|
44
|
+
/** Stop the current voice session. */
|
|
45
|
+
voiceStop: () => Promise<void>;
|
|
46
|
+
/** Toggle: start if idle/error, stop if active. */
|
|
47
|
+
voiceToggle: () => Promise<void>;
|
|
32
48
|
};
|
|
33
49
|
/**
|
|
34
50
|
* Internal context with additional methods for widget internals.
|
|
@@ -37,21 +53,21 @@ export type YakContextValue = {
|
|
|
37
53
|
export type YakInternalContextValue = YakContextValue & {
|
|
38
54
|
/** Get the iframe origin URL (determined by environment) */
|
|
39
55
|
getIframeOrigin: () => string;
|
|
56
|
+
/** Theme passed to YakProvider — used by YakWidget to mirror panel placement. */
|
|
57
|
+
theme: Theme | undefined;
|
|
40
58
|
};
|
|
41
59
|
export declare const YakContext: import("react").Context<YakInternalContextValue | null>;
|
|
42
60
|
/**
|
|
43
|
-
* Hook to access the Yak chat
|
|
44
|
-
* Provides methods for opening, closing, and triggering prompts.
|
|
61
|
+
* Hook to access the Yak widget API — chat and voice.
|
|
45
62
|
*
|
|
46
63
|
* @example
|
|
47
64
|
* ```tsx
|
|
48
65
|
* function MyComponent() {
|
|
49
|
-
* const { open,
|
|
50
|
-
*
|
|
66
|
+
* const { open, voiceToggle, voiceState } = useYak();
|
|
51
67
|
* return (
|
|
52
68
|
* <div>
|
|
53
|
-
* <button onClick={
|
|
54
|
-
* <button onClick={
|
|
69
|
+
* <button onClick={open}>Open chat</button>
|
|
70
|
+
* <button onClick={voiceToggle}>{voiceState === "idle" ? "Start voice" : "Stop voice"}</button>
|
|
55
71
|
* </div>
|
|
56
72
|
* );
|
|
57
73
|
* }
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,UAAU,EACV,KAAK,EACL,aAAa,EACb,YAAY,EACZ,UAAU,EACV,UAAU,EACX,MAAM,oBAAoB,CAAC;AAG5B;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,2DAA2D;IAC3D,IAAI,EAAE,UAAU,CAAC;IAGjB,gDAAgD;IAChD,MAAM,EAAE,OAAO,CAAC;IAChB,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;IACjB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,yDAAyD;IACzD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,+CAA+C;IAC/C,qBAAqB,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,MAAM,IAAI,CAAC;IAGrE,yEAAyE;IACzE,YAAY,EAAE,YAAY,CAAC;IAC3B,yCAAyC;IACzC,UAAU,EAAE,UAAU,CAAC;IACvB,8DAA8D;IAC9D,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,0FAA0F;IAC1F,aAAa,EAAE,OAAO,CAAC;IACvB,kEAAkE;IAClE,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,sCAAsC;IACtC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,mDAAmD;IACnD,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,eAAe,GAAG;IACtD,4DAA4D;IAC5D,eAAe,EAAE,MAAM,MAAM,CAAC;IAC9B,iFAAiF;IACjF,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,UAAU,yDAAsD,CAAC;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,MAAM,IAAI,eAAe,CAqBxC;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,uBAAuB,CAMxD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAkBnE"}
|
package/dist/context.js
CHANGED
|
@@ -2,18 +2,16 @@
|
|
|
2
2
|
import { createContext, useContext, useEffect, useRef } from "react";
|
|
3
3
|
export const YakContext = createContext(null);
|
|
4
4
|
/**
|
|
5
|
-
* Hook to access the Yak chat
|
|
6
|
-
* Provides methods for opening, closing, and triggering prompts.
|
|
5
|
+
* Hook to access the Yak widget API — chat and voice.
|
|
7
6
|
*
|
|
8
7
|
* @example
|
|
9
8
|
* ```tsx
|
|
10
9
|
* function MyComponent() {
|
|
11
|
-
* const { open,
|
|
12
|
-
*
|
|
10
|
+
* const { open, voiceToggle, voiceState } = useYak();
|
|
13
11
|
* return (
|
|
14
12
|
* <div>
|
|
15
|
-
* <button onClick={
|
|
16
|
-
* <button onClick={
|
|
13
|
+
* <button onClick={open}>Open chat</button>
|
|
14
|
+
* <button onClick={voiceToggle}>{voiceState === "idle" ? "Start voice" : "Stop voice"}</button>
|
|
17
15
|
* </div>
|
|
18
16
|
* );
|
|
19
17
|
* }
|
|
@@ -26,14 +24,21 @@ export function useYak() {
|
|
|
26
24
|
if (!context) {
|
|
27
25
|
throw new Error("useYak must be used within YakProvider");
|
|
28
26
|
}
|
|
29
|
-
// Return only the public API
|
|
30
27
|
return {
|
|
28
|
+
mode: context.mode,
|
|
31
29
|
isOpen: context.isOpen,
|
|
32
|
-
|
|
30
|
+
isReady: context.isReady,
|
|
33
31
|
open: context.open,
|
|
34
32
|
close: context.close,
|
|
35
33
|
openWithPrompt: context.openWithPrompt,
|
|
36
34
|
subscribeToToolEvents: context.subscribeToToolEvents,
|
|
35
|
+
voiceMachine: context.voiceMachine,
|
|
36
|
+
voiceState: context.voiceState,
|
|
37
|
+
voiceErrorMessage: context.voiceErrorMessage,
|
|
38
|
+
voiceIsActive: context.voiceIsActive,
|
|
39
|
+
voiceStart: context.voiceStart,
|
|
40
|
+
voiceStop: context.voiceStop,
|
|
41
|
+
voiceToggle: context.voiceToggle,
|
|
37
42
|
};
|
|
38
43
|
}
|
|
39
44
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
export type { ChatConfigProvider, GraphQLRequest, GraphQLSchemaHandler, GraphQLSchemaSource, OpenAPISchemaSource, RESTRequest, RESTSchemaHandler, SchemaSource, Theme, ThemeColors, ToolCallEvent, ToolCallHandler, TriggerButtonConfig, VoiceMachine, VoiceState, WidgetMode, WidgetPosition, } from "@yak-io/javascript";
|
|
2
|
+
export { disableYakLogging, enableYakLogging, isYakLoggingEnabled } from "@yak-io/javascript";
|
|
3
|
+
export type { ToolCallEventHandler, YakConfig, YakContextValue } from "./context.js";
|
|
1
4
|
export { useYak, useYakToolEvent } from "./context.js";
|
|
2
|
-
export type { YakConfig, YakContextValue, ToolCallEventHandler } from "./context.js";
|
|
3
|
-
export { YakProvider } from "./YakProvider.js";
|
|
4
5
|
export type { YakProviderProps } from "./YakProvider.js";
|
|
5
|
-
export {
|
|
6
|
+
export { YakProvider } from "./YakProvider.js";
|
|
6
7
|
export type { YakWidgetProps } from "./YakWidget.js";
|
|
7
|
-
export
|
|
8
|
+
export { YakWidget } from "./YakWidget.js";
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,KAAK,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,UAAU,EACV,cAAc,GACf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9F,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAErF,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
// Re-export useful types and constants from @yak-io/javascript for consumers
|
|
3
|
+
export { disableYakLogging, enableYakLogging, isYakLoggingEnabled } from "@yak-io/javascript";
|
|
2
4
|
// Public API - only export what consumers need
|
|
3
5
|
export { useYak, useYakToolEvent } from "./context.js";
|
|
4
6
|
export { YakProvider } from "./YakProvider.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yak-io/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "React SDK for embedding yak chatbot",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"./package.json": "./package.json"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@yak-io/javascript": "0.
|
|
44
|
+
"@yak-io/javascript": "0.8.0"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@testing-library/jest-dom": "^6.9.1",
|
|
52
52
|
"@testing-library/react": "^16.3.2",
|
|
53
|
-
"@types/node": "^24.12.
|
|
53
|
+
"@types/node": "^24.12.4",
|
|
54
54
|
"@types/react": "^19.2.14",
|
|
55
55
|
"@types/react-dom": "^19.2.0",
|
|
56
56
|
"jsdom": "^28.1.0",
|
|
57
|
-
"react": "^19.2.
|
|
58
|
-
"react-dom": "^19.2.
|
|
57
|
+
"react": "^19.2.6",
|
|
58
|
+
"react-dom": "^19.2.6",
|
|
59
59
|
"typescript": "^5.3.0",
|
|
60
60
|
"@repo/typescript-config": "0.0.0"
|
|
61
61
|
},
|