@yak-io/angular 0.5.1 → 0.6.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/dist/index.cjs ADDED
@@ -0,0 +1,156 @@
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
+ createYakProvider: () => createYakProvider,
24
+ createYakServerAdapter: () => import_javascript2.createYakServerAdapter,
25
+ createYakToolset: () => import_javascript2.createYakToolset,
26
+ disableYakLogging: () => import_javascript2.disableYakLogging,
27
+ enableYakLogging: () => import_javascript2.enableYakLogging,
28
+ isYakLoggingEnabled: () => import_javascript2.isYakLoggingEnabled
29
+ });
30
+ module.exports = __toCommonJS(index_exports);
31
+ var import_javascript2 = require("@yak-io/javascript");
32
+
33
+ // src/service.ts
34
+ var import_javascript = require("@yak-io/javascript");
35
+ function createYakProvider(options) {
36
+ let _isOpen = false;
37
+ let _isReady = false;
38
+ let _voiceMachine = import_javascript.INITIAL_VOICE_MACHINE;
39
+ const toolEventSubscribers = /* @__PURE__ */ new Set();
40
+ const stateSubscribers = /* @__PURE__ */ new Set();
41
+ const notifyState = () => {
42
+ const snap = {
43
+ isOpen: _isOpen,
44
+ isReady: _isReady,
45
+ chatLoading: _isOpen && !_isReady,
46
+ voiceMachine: _voiceMachine,
47
+ voiceLoading: _voiceMachine.state === "connecting"
48
+ };
49
+ for (const subscriber of stateSubscribers) {
50
+ try {
51
+ subscriber(snap);
52
+ } catch (err) {
53
+ import_javascript.logger.warn("Error in state subscriber:", err);
54
+ }
55
+ }
56
+ };
57
+ const handleToolCallComplete = (event) => {
58
+ import_javascript.logger.debug("Tool call completed, notifying subscribers:", {
59
+ name: event.name,
60
+ ok: event.ok,
61
+ subscriberCount: toolEventSubscribers.size
62
+ });
63
+ for (const handler of toolEventSubscribers) {
64
+ try {
65
+ handler(event);
66
+ } catch (err) {
67
+ import_javascript.logger.warn("Error in tool event subscriber:", err);
68
+ }
69
+ }
70
+ };
71
+ const resolvedRedirect = options.onRedirect ?? (typeof window !== "undefined" ? (path) => window.location.assign(path) : void 0);
72
+ const embed = new import_javascript.YakEmbed({
73
+ appId: options.appId,
74
+ mode: options.mode,
75
+ theme: options.theme,
76
+ trigger: options.trigger ?? false,
77
+ getConfig: options.getConfig,
78
+ onToolCall: options.onToolCall,
79
+ onRedirect: resolvedRedirect,
80
+ options: { disableRestartButton: options.disableRestartButton },
81
+ onToolCallComplete: handleToolCallComplete
82
+ });
83
+ embed.onStateChange((state) => {
84
+ _isOpen = state.isOpen;
85
+ _isReady = state.isReady;
86
+ notifyState();
87
+ });
88
+ embed.onVoiceStateChange((m) => {
89
+ _voiceMachine = m;
90
+ notifyState();
91
+ });
92
+ if (options.getConfig) {
93
+ const getConfig = options.getConfig;
94
+ let configFetched = false;
95
+ embed.onStateChange((state) => {
96
+ if (state.isOpen && !configFetched) {
97
+ configFetched = true;
98
+ import_javascript.logger.debug("Getting chat config");
99
+ Promise.resolve(getConfig()).then((config) => {
100
+ import_javascript.logger.debug(
101
+ `Chat config loaded with ${config.tools?.tools.length ?? 0} tools and ${config.routes?.routes.length ?? 0} routes`
102
+ );
103
+ embed.getClient().updateConfig({ chatConfig: config });
104
+ }).catch((err) => {
105
+ import_javascript.logger.warn("Error getting chat config:", err);
106
+ configFetched = false;
107
+ });
108
+ }
109
+ });
110
+ }
111
+ const voiceStart = async () => {
112
+ try {
113
+ await embed.voiceStart();
114
+ } catch (err) {
115
+ import_javascript.logger.warn("Voice start failed", err);
116
+ }
117
+ };
118
+ return {
119
+ get isOpen() {
120
+ return _isOpen;
121
+ },
122
+ get isReady() {
123
+ return _isReady;
124
+ },
125
+ get chatLoading() {
126
+ return _isOpen && !_isReady;
127
+ },
128
+ get voiceMachine() {
129
+ return _voiceMachine;
130
+ },
131
+ get voiceLoading() {
132
+ return _voiceMachine.state === "connecting";
133
+ },
134
+ open: () => embed.open(),
135
+ close: () => embed.close(),
136
+ openWithPrompt: (prompt) => embed.openWithPrompt(prompt),
137
+ voiceStart,
138
+ voiceStop: () => embed.voiceStop(),
139
+ voiceToggle: () => embed.voiceToggle(),
140
+ subscribeToToolEvents: (handler) => {
141
+ toolEventSubscribers.add(handler);
142
+ return () => {
143
+ toolEventSubscribers.delete(handler);
144
+ };
145
+ },
146
+ subscribeToState: (handler) => {
147
+ stateSubscribers.add(handler);
148
+ return () => {
149
+ stateSubscribers.delete(handler);
150
+ };
151
+ },
152
+ mount: () => embed.mount(),
153
+ destroy: () => embed.destroy()
154
+ };
155
+ }
156
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts", "../src/service.ts"],
4
+ "sourcesContent": ["// Public API\n\n// Re-export useful types from @yak-io/javascript for consumers\nexport type {\n ChatConfigProvider,\n GraphQLRequest,\n RESTRequest,\n Theme,\n ThemeColors,\n ToolAdapter,\n ToolCallEvent,\n ToolCallHandler,\n TriggerButtonConfig,\n VoiceMachine,\n VoiceState,\n WidgetMode,\n WidgetPosition,\n YakServerAdapterConfig,\n YakToolset,\n} from \"@yak-io/javascript\";\n// Re-export tool composition + logging utilities\nexport {\n createYakServerAdapter,\n createYakToolset,\n disableYakLogging,\n enableYakLogging,\n isYakLoggingEnabled,\n} from \"@yak-io/javascript\";\nexport type {\n ToolCallEventHandler,\n YakApi,\n YakProviderOptions,\n YakState,\n} from \"./service.js\";\nexport { createYakProvider } from \"./service.js\";\n", "import {\n type ChatConfigProvider,\n INITIAL_VOICE_MACHINE,\n logger,\n type Theme,\n type ToolCallEvent,\n type ToolCallHandler,\n type TriggerButtonConfig,\n type VoiceMachine,\n type WidgetMode,\n YakEmbed,\n} from \"@yak-io/javascript\";\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type ToolCallEventHandler = (event: ToolCallEvent) => void;\n\nexport type YakProviderOptions = {\n appId: string;\n mode?: WidgetMode;\n getConfig?: ChatConfigProvider;\n onToolCall?: ToolCallHandler;\n theme?: Theme;\n onRedirect?: (path: string) => void;\n disableRestartButton?: boolean;\n trigger?: boolean | TriggerButtonConfig;\n};\n\nexport type YakState = {\n isOpen: boolean;\n isReady: boolean;\n chatLoading: boolean;\n voiceMachine: VoiceMachine;\n voiceLoading: boolean;\n};\n\n/** Handle for controlling the Yak widget \u2014 chat + voice \u2014 from Angular. */\nexport type YakApi = {\n /** Whether the chat panel is currently open. */\n readonly isOpen: boolean;\n /** Whether the chat iframe is ready to receive messages. */\n readonly isReady: boolean;\n /** Whether the chat is opening but not yet interactive (`isOpen && !isReady`). */\n readonly chatLoading: boolean;\n /** Current voice state-machine snapshot. `idle` when mode is `chat`. */\n readonly voiceMachine: VoiceMachine;\n /** Whether the voice session is establishing its connection (`state === \"connecting\"`). */\n readonly voiceLoading: boolean;\n /** Open the chat panel. */\n open: () => void;\n /** Close the chat panel. */\n close: () => void;\n /** Open the chat panel and send a specific prompt. */\n openWithPrompt: (prompt: string) => void;\n /** Start a voice session. Must be invoked from a user gesture. */\n voiceStart: () => Promise<void>;\n /** Stop the current voice session. */\n voiceStop: () => Promise<void>;\n /** Toggle voice: start if idle/error, stop if active. */\n voiceToggle: () => Promise<void>;\n /** Subscribe to tool-call completion events; returns an unsubscribe function. */\n subscribeToToolEvents: (handler: ToolCallEventHandler) => () => void;\n /** Subscribe to chat + voice state changes. */\n subscribeToState: (handler: (state: YakState) => void) => () => void;\n /** Mount the widget into the DOM. */\n mount: () => void;\n /** Tear down the widget and remove its listeners. */\n destroy: () => void;\n};\n\n// \u2500\u2500 Provider factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Creates a yak widget (chat + voice) for Angular.\n * Call `mount()` in `ngOnInit` and `destroy()` in `ngOnDestroy`.\n */\nexport function createYakProvider(options: YakProviderOptions): YakApi {\n let _isOpen = false;\n let _isReady = false;\n let _voiceMachine: VoiceMachine = INITIAL_VOICE_MACHINE;\n const toolEventSubscribers = new Set<ToolCallEventHandler>();\n const stateSubscribers = new Set<(state: YakState) => void>();\n\n const notifyState = () => {\n const snap: YakState = {\n isOpen: _isOpen,\n isReady: _isReady,\n chatLoading: _isOpen && !_isReady,\n voiceMachine: _voiceMachine,\n voiceLoading: _voiceMachine.state === \"connecting\",\n };\n for (const subscriber of stateSubscribers) {\n try {\n subscriber(snap);\n } catch (err) {\n logger.warn(\"Error in state subscriber:\", err);\n }\n }\n };\n\n const handleToolCallComplete = (event: ToolCallEvent) => {\n logger.debug(\"Tool call completed, notifying subscribers:\", {\n name: event.name,\n ok: event.ok,\n subscriberCount: toolEventSubscribers.size,\n });\n for (const handler of toolEventSubscribers) {\n try {\n handler(event);\n } catch (err) {\n logger.warn(\"Error in tool event subscriber:\", err);\n }\n }\n };\n\n const resolvedRedirect =\n options.onRedirect ??\n (typeof window !== \"undefined\" ? (path: string) => window.location.assign(path) : undefined);\n\n const embed = new YakEmbed({\n appId: options.appId,\n mode: options.mode,\n theme: options.theme,\n trigger: options.trigger ?? false,\n getConfig: options.getConfig,\n onToolCall: options.onToolCall,\n onRedirect: resolvedRedirect,\n options: { disableRestartButton: options.disableRestartButton },\n onToolCallComplete: handleToolCallComplete,\n });\n\n embed.onStateChange((state) => {\n _isOpen = state.isOpen;\n _isReady = state.isReady;\n notifyState();\n });\n embed.onVoiceStateChange((m) => {\n _voiceMachine = m;\n notifyState();\n });\n\n // Fetch chat config on first open\n if (options.getConfig) {\n const getConfig = options.getConfig;\n let configFetched = false;\n\n embed.onStateChange((state) => {\n if (state.isOpen && !configFetched) {\n configFetched = true;\n logger.debug(\"Getting chat config\");\n\n Promise.resolve(getConfig())\n .then((config) => {\n logger.debug(\n `Chat config loaded with ${config.tools?.tools.length ?? 0} tools and ${config.routes?.routes.length ?? 0} routes`\n );\n embed.getClient().updateConfig({ chatConfig: config });\n })\n .catch((err) => {\n logger.warn(\"Error getting chat config:\", err);\n configFetched = false;\n });\n }\n });\n }\n\n const voiceStart = async () => {\n try {\n await embed.voiceStart();\n } catch (err) {\n logger.warn(\"Voice start failed\", err);\n }\n };\n\n return {\n get isOpen() {\n return _isOpen;\n },\n get isReady() {\n return _isReady;\n },\n get chatLoading() {\n return _isOpen && !_isReady;\n },\n get voiceMachine() {\n return _voiceMachine;\n },\n get voiceLoading() {\n return _voiceMachine.state === \"connecting\";\n },\n open: () => embed.open(),\n close: () => embed.close(),\n openWithPrompt: (prompt: string) => embed.openWithPrompt(prompt),\n voiceStart,\n voiceStop: () => embed.voiceStop(),\n voiceToggle: () => embed.voiceToggle(),\n subscribeToToolEvents: (handler: ToolCallEventHandler) => {\n toolEventSubscribers.add(handler);\n return () => {\n toolEventSubscribers.delete(handler);\n };\n },\n subscribeToState: (handler: (state: YakState) => void) => {\n stateSubscribers.add(handler);\n return () => {\n stateSubscribers.delete(handler);\n };\n },\n mount: () => embed.mount(),\n destroy: () => embed.destroy(),\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_javascript"]
7
+ }
package/dist/index.js CHANGED
@@ -1,4 +1,145 @@
1
- // Public API
2
- // Re-export tool composition + logging utilities
3
- export { createYakServerAdapter, createYakToolset, disableYakLogging, enableYakLogging, isYakLoggingEnabled, } from "@yak-io/javascript";
4
- export { createYakProvider } from "./service.js";
1
+ // src/index.ts
2
+ import {
3
+ createYakServerAdapter,
4
+ createYakToolset,
5
+ disableYakLogging,
6
+ enableYakLogging,
7
+ isYakLoggingEnabled
8
+ } from "@yak-io/javascript";
9
+
10
+ // src/service.ts
11
+ import {
12
+ INITIAL_VOICE_MACHINE,
13
+ logger,
14
+ YakEmbed
15
+ } from "@yak-io/javascript";
16
+ function createYakProvider(options) {
17
+ let _isOpen = false;
18
+ let _isReady = false;
19
+ let _voiceMachine = INITIAL_VOICE_MACHINE;
20
+ const toolEventSubscribers = /* @__PURE__ */ new Set();
21
+ const stateSubscribers = /* @__PURE__ */ new Set();
22
+ const notifyState = () => {
23
+ const snap = {
24
+ isOpen: _isOpen,
25
+ isReady: _isReady,
26
+ chatLoading: _isOpen && !_isReady,
27
+ voiceMachine: _voiceMachine,
28
+ voiceLoading: _voiceMachine.state === "connecting"
29
+ };
30
+ for (const subscriber of stateSubscribers) {
31
+ try {
32
+ subscriber(snap);
33
+ } catch (err) {
34
+ logger.warn("Error in state subscriber:", err);
35
+ }
36
+ }
37
+ };
38
+ const handleToolCallComplete = (event) => {
39
+ logger.debug("Tool call completed, notifying subscribers:", {
40
+ name: event.name,
41
+ ok: event.ok,
42
+ subscriberCount: toolEventSubscribers.size
43
+ });
44
+ for (const handler of toolEventSubscribers) {
45
+ try {
46
+ handler(event);
47
+ } catch (err) {
48
+ logger.warn("Error in tool event subscriber:", err);
49
+ }
50
+ }
51
+ };
52
+ const resolvedRedirect = options.onRedirect ?? (typeof window !== "undefined" ? (path) => window.location.assign(path) : void 0);
53
+ const embed = new YakEmbed({
54
+ appId: options.appId,
55
+ mode: options.mode,
56
+ theme: options.theme,
57
+ trigger: options.trigger ?? false,
58
+ getConfig: options.getConfig,
59
+ onToolCall: options.onToolCall,
60
+ onRedirect: resolvedRedirect,
61
+ options: { disableRestartButton: options.disableRestartButton },
62
+ onToolCallComplete: handleToolCallComplete
63
+ });
64
+ embed.onStateChange((state) => {
65
+ _isOpen = state.isOpen;
66
+ _isReady = state.isReady;
67
+ notifyState();
68
+ });
69
+ embed.onVoiceStateChange((m) => {
70
+ _voiceMachine = m;
71
+ notifyState();
72
+ });
73
+ if (options.getConfig) {
74
+ const getConfig = options.getConfig;
75
+ let configFetched = false;
76
+ embed.onStateChange((state) => {
77
+ if (state.isOpen && !configFetched) {
78
+ configFetched = true;
79
+ logger.debug("Getting chat config");
80
+ Promise.resolve(getConfig()).then((config) => {
81
+ logger.debug(
82
+ `Chat config loaded with ${config.tools?.tools.length ?? 0} tools and ${config.routes?.routes.length ?? 0} routes`
83
+ );
84
+ embed.getClient().updateConfig({ chatConfig: config });
85
+ }).catch((err) => {
86
+ logger.warn("Error getting chat config:", err);
87
+ configFetched = false;
88
+ });
89
+ }
90
+ });
91
+ }
92
+ const voiceStart = async () => {
93
+ try {
94
+ await embed.voiceStart();
95
+ } catch (err) {
96
+ logger.warn("Voice start failed", err);
97
+ }
98
+ };
99
+ return {
100
+ get isOpen() {
101
+ return _isOpen;
102
+ },
103
+ get isReady() {
104
+ return _isReady;
105
+ },
106
+ get chatLoading() {
107
+ return _isOpen && !_isReady;
108
+ },
109
+ get voiceMachine() {
110
+ return _voiceMachine;
111
+ },
112
+ get voiceLoading() {
113
+ return _voiceMachine.state === "connecting";
114
+ },
115
+ open: () => embed.open(),
116
+ close: () => embed.close(),
117
+ openWithPrompt: (prompt) => embed.openWithPrompt(prompt),
118
+ voiceStart,
119
+ voiceStop: () => embed.voiceStop(),
120
+ voiceToggle: () => embed.voiceToggle(),
121
+ subscribeToToolEvents: (handler) => {
122
+ toolEventSubscribers.add(handler);
123
+ return () => {
124
+ toolEventSubscribers.delete(handler);
125
+ };
126
+ },
127
+ subscribeToState: (handler) => {
128
+ stateSubscribers.add(handler);
129
+ return () => {
130
+ stateSubscribers.delete(handler);
131
+ };
132
+ },
133
+ mount: () => embed.mount(),
134
+ destroy: () => embed.destroy()
135
+ };
136
+ }
137
+ export {
138
+ createYakProvider,
139
+ createYakServerAdapter,
140
+ createYakToolset,
141
+ disableYakLogging,
142
+ enableYakLogging,
143
+ isYakLoggingEnabled
144
+ };
145
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts", "../src/service.ts"],
4
+ "sourcesContent": ["// Public API\n\n// Re-export useful types from @yak-io/javascript for consumers\nexport type {\n ChatConfigProvider,\n GraphQLRequest,\n RESTRequest,\n Theme,\n ThemeColors,\n ToolAdapter,\n ToolCallEvent,\n ToolCallHandler,\n TriggerButtonConfig,\n VoiceMachine,\n VoiceState,\n WidgetMode,\n WidgetPosition,\n YakServerAdapterConfig,\n YakToolset,\n} from \"@yak-io/javascript\";\n// Re-export tool composition + logging utilities\nexport {\n createYakServerAdapter,\n createYakToolset,\n disableYakLogging,\n enableYakLogging,\n isYakLoggingEnabled,\n} from \"@yak-io/javascript\";\nexport type {\n ToolCallEventHandler,\n YakApi,\n YakProviderOptions,\n YakState,\n} from \"./service.js\";\nexport { createYakProvider } from \"./service.js\";\n", "import {\n type ChatConfigProvider,\n INITIAL_VOICE_MACHINE,\n logger,\n type Theme,\n type ToolCallEvent,\n type ToolCallHandler,\n type TriggerButtonConfig,\n type VoiceMachine,\n type WidgetMode,\n YakEmbed,\n} from \"@yak-io/javascript\";\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type ToolCallEventHandler = (event: ToolCallEvent) => void;\n\nexport type YakProviderOptions = {\n appId: string;\n mode?: WidgetMode;\n getConfig?: ChatConfigProvider;\n onToolCall?: ToolCallHandler;\n theme?: Theme;\n onRedirect?: (path: string) => void;\n disableRestartButton?: boolean;\n trigger?: boolean | TriggerButtonConfig;\n};\n\nexport type YakState = {\n isOpen: boolean;\n isReady: boolean;\n chatLoading: boolean;\n voiceMachine: VoiceMachine;\n voiceLoading: boolean;\n};\n\n/** Handle for controlling the Yak widget \u2014 chat + voice \u2014 from Angular. */\nexport type YakApi = {\n /** Whether the chat panel is currently open. */\n readonly isOpen: boolean;\n /** Whether the chat iframe is ready to receive messages. */\n readonly isReady: boolean;\n /** Whether the chat is opening but not yet interactive (`isOpen && !isReady`). */\n readonly chatLoading: boolean;\n /** Current voice state-machine snapshot. `idle` when mode is `chat`. */\n readonly voiceMachine: VoiceMachine;\n /** Whether the voice session is establishing its connection (`state === \"connecting\"`). */\n readonly voiceLoading: boolean;\n /** Open the chat panel. */\n open: () => void;\n /** Close the chat panel. */\n close: () => void;\n /** Open the chat panel and send a specific prompt. */\n openWithPrompt: (prompt: string) => void;\n /** Start a voice session. Must be invoked from a user gesture. */\n voiceStart: () => Promise<void>;\n /** Stop the current voice session. */\n voiceStop: () => Promise<void>;\n /** Toggle voice: start if idle/error, stop if active. */\n voiceToggle: () => Promise<void>;\n /** Subscribe to tool-call completion events; returns an unsubscribe function. */\n subscribeToToolEvents: (handler: ToolCallEventHandler) => () => void;\n /** Subscribe to chat + voice state changes. */\n subscribeToState: (handler: (state: YakState) => void) => () => void;\n /** Mount the widget into the DOM. */\n mount: () => void;\n /** Tear down the widget and remove its listeners. */\n destroy: () => void;\n};\n\n// \u2500\u2500 Provider factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Creates a yak widget (chat + voice) for Angular.\n * Call `mount()` in `ngOnInit` and `destroy()` in `ngOnDestroy`.\n */\nexport function createYakProvider(options: YakProviderOptions): YakApi {\n let _isOpen = false;\n let _isReady = false;\n let _voiceMachine: VoiceMachine = INITIAL_VOICE_MACHINE;\n const toolEventSubscribers = new Set<ToolCallEventHandler>();\n const stateSubscribers = new Set<(state: YakState) => void>();\n\n const notifyState = () => {\n const snap: YakState = {\n isOpen: _isOpen,\n isReady: _isReady,\n chatLoading: _isOpen && !_isReady,\n voiceMachine: _voiceMachine,\n voiceLoading: _voiceMachine.state === \"connecting\",\n };\n for (const subscriber of stateSubscribers) {\n try {\n subscriber(snap);\n } catch (err) {\n logger.warn(\"Error in state subscriber:\", err);\n }\n }\n };\n\n const handleToolCallComplete = (event: ToolCallEvent) => {\n logger.debug(\"Tool call completed, notifying subscribers:\", {\n name: event.name,\n ok: event.ok,\n subscriberCount: toolEventSubscribers.size,\n });\n for (const handler of toolEventSubscribers) {\n try {\n handler(event);\n } catch (err) {\n logger.warn(\"Error in tool event subscriber:\", err);\n }\n }\n };\n\n const resolvedRedirect =\n options.onRedirect ??\n (typeof window !== \"undefined\" ? (path: string) => window.location.assign(path) : undefined);\n\n const embed = new YakEmbed({\n appId: options.appId,\n mode: options.mode,\n theme: options.theme,\n trigger: options.trigger ?? false,\n getConfig: options.getConfig,\n onToolCall: options.onToolCall,\n onRedirect: resolvedRedirect,\n options: { disableRestartButton: options.disableRestartButton },\n onToolCallComplete: handleToolCallComplete,\n });\n\n embed.onStateChange((state) => {\n _isOpen = state.isOpen;\n _isReady = state.isReady;\n notifyState();\n });\n embed.onVoiceStateChange((m) => {\n _voiceMachine = m;\n notifyState();\n });\n\n // Fetch chat config on first open\n if (options.getConfig) {\n const getConfig = options.getConfig;\n let configFetched = false;\n\n embed.onStateChange((state) => {\n if (state.isOpen && !configFetched) {\n configFetched = true;\n logger.debug(\"Getting chat config\");\n\n Promise.resolve(getConfig())\n .then((config) => {\n logger.debug(\n `Chat config loaded with ${config.tools?.tools.length ?? 0} tools and ${config.routes?.routes.length ?? 0} routes`\n );\n embed.getClient().updateConfig({ chatConfig: config });\n })\n .catch((err) => {\n logger.warn(\"Error getting chat config:\", err);\n configFetched = false;\n });\n }\n });\n }\n\n const voiceStart = async () => {\n try {\n await embed.voiceStart();\n } catch (err) {\n logger.warn(\"Voice start failed\", err);\n }\n };\n\n return {\n get isOpen() {\n return _isOpen;\n },\n get isReady() {\n return _isReady;\n },\n get chatLoading() {\n return _isOpen && !_isReady;\n },\n get voiceMachine() {\n return _voiceMachine;\n },\n get voiceLoading() {\n return _voiceMachine.state === \"connecting\";\n },\n open: () => embed.open(),\n close: () => embed.close(),\n openWithPrompt: (prompt: string) => embed.openWithPrompt(prompt),\n voiceStart,\n voiceStop: () => embed.voiceStop(),\n voiceToggle: () => embed.voiceToggle(),\n subscribeToToolEvents: (handler: ToolCallEventHandler) => {\n toolEventSubscribers.add(handler);\n return () => {\n toolEventSubscribers.delete(handler);\n };\n },\n subscribeToState: (handler: (state: YakState) => void) => {\n stateSubscribers.add(handler);\n return () => {\n stateSubscribers.delete(handler);\n };\n },\n mount: () => embed.mount(),\n destroy: () => embed.destroy(),\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yak-io/angular",
3
- "version": "0.5.1",
3
+ "version": "0.6.1",
4
4
  "description": "Angular SDK for embedding yak chatbot",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -30,19 +30,20 @@
30
30
  "LICENSE"
31
31
  ],
32
32
  "sideEffects": false,
33
- "main": "./dist/index.js",
33
+ "main": "./dist/index.cjs",
34
34
  "module": "./dist/index.js",
35
35
  "types": "./dist/index.d.ts",
36
36
  "exports": {
37
37
  ".": {
38
38
  "types": "./dist/index.d.ts",
39
39
  "import": "./dist/index.js",
40
+ "require": "./dist/index.cjs",
40
41
  "default": "./dist/index.js"
41
42
  },
42
43
  "./package.json": "./package.json"
43
44
  },
44
45
  "dependencies": {
45
- "@yak-io/javascript": "0.10.1"
46
+ "@yak-io/javascript": "0.11.1"
46
47
  },
47
48
  "peerDependencies": {
48
49
  "@angular/core": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0"
@@ -54,7 +55,7 @@
54
55
  },
55
56
  "homepage": "https://docs.yak.io/docs/sdks/angular",
56
57
  "scripts": {
57
- "build": "tsc",
58
+ "build": "node ../../scripts/build-package.mjs && tsc --emitDeclarationOnly",
58
59
  "check-types": "tsc --noEmit",
59
60
  "test": "vitest run",
60
61
  "lint": "biome lint ./src --fix",
package/dist/service.js DELETED
@@ -1,132 +0,0 @@
1
- import { INITIAL_VOICE_MACHINE, logger, YakEmbed, } from "@yak-io/javascript";
2
- // ── Provider factory ────────────────────────────────────────────────────────
3
- /**
4
- * Creates a yak widget (chat + voice) for Angular.
5
- * Call `mount()` in `ngOnInit` and `destroy()` in `ngOnDestroy`.
6
- */
7
- export function createYakProvider(options) {
8
- let _isOpen = false;
9
- let _isReady = false;
10
- let _voiceMachine = INITIAL_VOICE_MACHINE;
11
- const toolEventSubscribers = new Set();
12
- const stateSubscribers = new Set();
13
- const notifyState = () => {
14
- const snap = {
15
- isOpen: _isOpen,
16
- isReady: _isReady,
17
- chatLoading: _isOpen && !_isReady,
18
- voiceMachine: _voiceMachine,
19
- voiceLoading: _voiceMachine.state === "connecting",
20
- };
21
- for (const subscriber of stateSubscribers) {
22
- try {
23
- subscriber(snap);
24
- }
25
- catch (err) {
26
- logger.warn("Error in state subscriber:", err);
27
- }
28
- }
29
- };
30
- const handleToolCallComplete = (event) => {
31
- logger.debug("Tool call completed, notifying subscribers:", {
32
- name: event.name,
33
- ok: event.ok,
34
- subscriberCount: toolEventSubscribers.size,
35
- });
36
- for (const handler of toolEventSubscribers) {
37
- try {
38
- handler(event);
39
- }
40
- catch (err) {
41
- logger.warn("Error in tool event subscriber:", err);
42
- }
43
- }
44
- };
45
- const resolvedRedirect = options.onRedirect ??
46
- (typeof window !== "undefined" ? (path) => window.location.assign(path) : undefined);
47
- const embed = new YakEmbed({
48
- appId: options.appId,
49
- mode: options.mode,
50
- theme: options.theme,
51
- trigger: options.trigger ?? false,
52
- getConfig: options.getConfig,
53
- onToolCall: options.onToolCall,
54
- onRedirect: resolvedRedirect,
55
- options: { disableRestartButton: options.disableRestartButton },
56
- onToolCallComplete: handleToolCallComplete,
57
- });
58
- embed.onStateChange((state) => {
59
- _isOpen = state.isOpen;
60
- _isReady = state.isReady;
61
- notifyState();
62
- });
63
- embed.onVoiceStateChange((m) => {
64
- _voiceMachine = m;
65
- notifyState();
66
- });
67
- // Fetch chat config on first open
68
- if (options.getConfig) {
69
- const getConfig = options.getConfig;
70
- let configFetched = false;
71
- embed.onStateChange((state) => {
72
- if (state.isOpen && !configFetched) {
73
- configFetched = true;
74
- logger.debug("Getting chat config");
75
- Promise.resolve(getConfig())
76
- .then((config) => {
77
- logger.debug(`Chat config loaded with ${config.tools?.tools.length ?? 0} tools and ${config.routes?.routes.length ?? 0} routes`);
78
- embed.getClient().updateConfig({ chatConfig: config });
79
- })
80
- .catch((err) => {
81
- logger.warn("Error getting chat config:", err);
82
- configFetched = false;
83
- });
84
- }
85
- });
86
- }
87
- const voiceStart = async () => {
88
- try {
89
- await embed.voiceStart();
90
- }
91
- catch (err) {
92
- logger.warn("Voice start failed", err);
93
- }
94
- };
95
- return {
96
- get isOpen() {
97
- return _isOpen;
98
- },
99
- get isReady() {
100
- return _isReady;
101
- },
102
- get chatLoading() {
103
- return _isOpen && !_isReady;
104
- },
105
- get voiceMachine() {
106
- return _voiceMachine;
107
- },
108
- get voiceLoading() {
109
- return _voiceMachine.state === "connecting";
110
- },
111
- open: () => embed.open(),
112
- close: () => embed.close(),
113
- openWithPrompt: (prompt) => embed.openWithPrompt(prompt),
114
- voiceStart,
115
- voiceStop: () => embed.voiceStop(),
116
- voiceToggle: () => embed.voiceToggle(),
117
- subscribeToToolEvents: (handler) => {
118
- toolEventSubscribers.add(handler);
119
- return () => {
120
- toolEventSubscribers.delete(handler);
121
- };
122
- },
123
- subscribeToState: (handler) => {
124
- stateSubscribers.add(handler);
125
- return () => {
126
- stateSubscribers.delete(handler);
127
- };
128
- },
129
- mount: () => embed.mount(),
130
- destroy: () => embed.destroy(),
131
- };
132
- }