@seed-ship/mcp-ui-solid 2.2.11 → 2.4.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.
Files changed (52) hide show
  1. package/dist/components/ChatPrompt.cjs +271 -0
  2. package/dist/components/ChatPrompt.cjs.map +1 -0
  3. package/dist/components/ChatPrompt.d.ts +33 -0
  4. package/dist/components/ChatPrompt.d.ts.map +1 -0
  5. package/dist/components/ChatPrompt.js +271 -0
  6. package/dist/components/ChatPrompt.js.map +1 -0
  7. package/dist/components/UIResourceRenderer.cjs +29 -27
  8. package/dist/components/UIResourceRenderer.cjs.map +1 -1
  9. package/dist/components/UIResourceRenderer.js +30 -28
  10. package/dist/components/UIResourceRenderer.js.map +1 -1
  11. package/dist/hooks/useChatBus.cjs +28 -0
  12. package/dist/hooks/useChatBus.cjs.map +1 -0
  13. package/dist/hooks/useChatBus.d.ts +56 -0
  14. package/dist/hooks/useChatBus.d.ts.map +1 -0
  15. package/dist/hooks/useChatBus.js +28 -0
  16. package/dist/hooks/useChatBus.js.map +1 -0
  17. package/dist/index.cjs +11 -0
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +5 -1
  20. package/dist/index.d.ts +5 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +12 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/services/chat-bus.cjs +118 -0
  25. package/dist/services/chat-bus.cjs.map +1 -0
  26. package/dist/services/chat-bus.d.ts +43 -0
  27. package/dist/services/chat-bus.d.ts.map +1 -0
  28. package/dist/services/chat-bus.js +118 -0
  29. package/dist/services/chat-bus.js.map +1 -0
  30. package/dist/services/index.d.ts +2 -1
  31. package/dist/services/index.d.ts.map +1 -1
  32. package/dist/services/validation.cjs +71 -1
  33. package/dist/services/validation.cjs.map +1 -1
  34. package/dist/services/validation.d.ts +21 -0
  35. package/dist/services/validation.d.ts.map +1 -1
  36. package/dist/services/validation.js +71 -1
  37. package/dist/services/validation.js.map +1 -1
  38. package/dist/types/chat-bus.d.ts +286 -0
  39. package/dist/types/chat-bus.d.ts.map +1 -0
  40. package/package.json +1 -1
  41. package/src/components/ChatPrompt.test.tsx +280 -0
  42. package/src/components/ChatPrompt.tsx +263 -0
  43. package/src/components/UIResourceRenderer.tsx +2 -2
  44. package/src/hooks/useChatBus.tsx +81 -0
  45. package/src/index.ts +36 -0
  46. package/src/services/chat-bus.test.ts +306 -0
  47. package/src/services/chat-bus.ts +183 -0
  48. package/src/services/index.ts +4 -0
  49. package/src/services/validation.test.ts +56 -1
  50. package/src/services/validation.ts +100 -0
  51. package/src/types/chat-bus.ts +320 -0
  52. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useChatBus.d.ts","sourceRoot":"","sources":["../../src/hooks/useChatBus.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAwC,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAErF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAMhD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,EAAE,eAAe,CAAC;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,CAY9D,CAAA;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAMpC"}
@@ -0,0 +1,28 @@
1
+ import { createComponent } from "solid-js/web";
2
+ import { createContext, onCleanup, useContext } from "solid-js";
3
+ import { createChatBus } from "../services/chat-bus.js";
4
+ const ChatBusContext = createContext();
5
+ const ChatBusProvider = (props) => {
6
+ const bus = props.bus ?? createChatBus();
7
+ onCleanup(() => {
8
+ bus.events.clear();
9
+ });
10
+ return createComponent(ChatBusContext.Provider, {
11
+ value: bus,
12
+ get children() {
13
+ return props.children;
14
+ }
15
+ });
16
+ };
17
+ function useChatBus() {
18
+ const bus = useContext(ChatBusContext);
19
+ if (!bus) {
20
+ throw new Error("useChatBus must be used within a <ChatBusProvider>");
21
+ }
22
+ return bus;
23
+ }
24
+ export {
25
+ ChatBusProvider,
26
+ useChatBus
27
+ };
28
+ //# sourceMappingURL=useChatBus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useChatBus.js","sources":["../../src/hooks/useChatBus.tsx"],"sourcesContent":["/**\n * useChatBus — SolidJS hook + context provider for the Chat Bus\n * v2.4.0: Event-driven chat toolkit\n *\n * @experimental — This API may change without major bump until v2.5.0.\n */\n\nimport { createContext, useContext, onCleanup, type ParentComponent } from 'solid-js'\nimport { createChatBus } from '../services/chat-bus'\nimport type { ChatBus } from '../types/chat-bus'\n\n// ─── Context ─────────────────────────────────────────────────\n\nconst ChatBusContext = createContext<ChatBus>()\n\n/**\n * @experimental\n * Provider that creates and shares a ChatBus with all children.\n * Cleans up all listeners on unmount.\n *\n * @example\n * <ChatBusProvider>\n * <ChatInterfaceStreaming />\n * <BriefingPanel />\n * <AgentRouter />\n * </ChatBusProvider>\n */\nexport const ChatBusProvider: ParentComponent<{ bus?: ChatBus }> = (props) => {\n const bus = props.bus ?? createChatBus()\n\n onCleanup(() => {\n bus.events.clear()\n })\n\n return (\n <ChatBusContext.Provider value={bus}>\n {props.children}\n </ChatBusContext.Provider>\n )\n}\n\n// ─── Hook ────────────────────────────────────────────────────\n\n/**\n * @experimental\n * Access the ChatBus from any child component.\n * Must be used within a `<ChatBusProvider>`.\n *\n * @example\n * function BriefingPanel() {\n * const bus = useChatBus()\n *\n * bus.events.on('onBriefing', (event) => {\n * addBriefing(event.briefing)\n * })\n *\n * return <div>...</div>\n * }\n *\n * @example\n * function AgentRouter() {\n * const bus = useChatBus()\n *\n * bus.events.on('onStreamEnd', (event) => {\n * if (event.metadata.needs_clarification) {\n * bus.commands.exec('showChatPrompt', {\n * type: 'choice',\n * title: 'Quelle periode ?',\n * config: { options: [...] }\n * })\n * }\n * })\n * }\n */\nexport function useChatBus(): ChatBus {\n const bus = useContext(ChatBusContext)\n if (!bus) {\n throw new Error('useChatBus must be used within a <ChatBusProvider>')\n }\n return bus\n}\n"],"names":["ChatBusContext","createContext","ChatBusProvider","props","bus","createChatBus","onCleanup","events","clear","_$createComponent","Provider","value","children","useChatBus","useContext","Error"],"mappings":";;;AAaA,MAAMA,iBAAiBC,cAAAA;AAchB,MAAMC,kBAAuDC,CAAAA,UAAU;AAC5E,QAAMC,MAAMD,MAAMC,OAAOC,cAAAA;AAEzBC,YAAU,MAAM;AACdF,QAAIG,OAAOC,MAAAA;AAAAA,EACb,CAAC;AAED,SAAAC,gBACGT,eAAeU,UAAQ;AAAA,IAACC,OAAOP;AAAAA,IAAG,IAAAQ,WAAA;AAAA,aAChCT,MAAMS;AAAAA,IAAQ;AAAA,EAAA,CAAA;AAGrB;AAmCO,SAASC,aAAsB;AACpC,QAAMT,MAAMU,WAAWd,cAAc;AACrC,MAAI,CAACI,KAAK;AACR,UAAM,IAAIW,MAAM,oDAAoD;AAAA,EACtE;AACA,SAAOX;AACT;"}
package/dist/index.cjs CHANGED
@@ -21,6 +21,8 @@ const ResizeHandle = require("./components/ResizeHandle.cjs");
21
21
  const EditableUIResourceRenderer = require("./components/EditableUIResourceRenderer.cjs");
22
22
  const ExpandableWrapper = require("./components/ExpandableWrapper.cjs");
23
23
  const ComponentToolbar = require("./components/ComponentToolbar.cjs");
24
+ const useChatBus = require("./hooks/useChatBus.cjs");
25
+ const ChatPrompt = require("./components/ChatPrompt.cjs");
24
26
  const GhostText = require("./components/GhostText.cjs");
25
27
  const AutocompleteDropdown = require("./components/AutocompleteDropdown.cjs");
26
28
  const AutocompleteFormField = require("./components/AutocompleteFormField.cjs");
@@ -39,6 +41,7 @@ const supabase = require("./plugins/supabase.cjs");
39
41
  const rest = require("./plugins/rest.cjs");
40
42
  const validation = require("./services/validation.cjs");
41
43
  const componentRegistry = require("./services/component-registry.cjs");
44
+ const chatBus = require("./services/chat-bus.cjs");
42
45
  exports.UIResourceRenderer = UIResourceRenderer.UIResourceRenderer;
43
46
  exports.StreamingUIRenderer = StreamingUIRenderer.StreamingUIRenderer;
44
47
  exports.GenerativeUIErrorBoundary = GenerativeUIErrorBoundary.GenerativeUIErrorBoundary;
@@ -47,6 +50,9 @@ exports.ResizeHandle = ResizeHandle.ResizeHandle;
47
50
  exports.EditableUIResourceRenderer = EditableUIResourceRenderer.EditableUIResourceRenderer;
48
51
  exports.ExpandableWrapper = ExpandableWrapper.ExpandableWrapper;
49
52
  exports.ComponentToolbar = ComponentToolbar.ComponentToolbar;
53
+ exports.ChatBusProvider = useChatBus.ChatBusProvider;
54
+ exports.useChatBus = useChatBus.useChatBus;
55
+ exports.ChatPrompt = ChatPrompt.ChatPrompt;
50
56
  exports.GhostText = GhostText.GhostText;
51
57
  exports.GhostTextInput = GhostText.GhostTextInput;
52
58
  exports.AutocompleteDropdown = AutocompleteDropdown.AutocompleteDropdown;
@@ -74,8 +80,13 @@ exports.createSupabasePlugin = supabase.createSupabasePlugin;
74
80
  exports.createRestPlugin = rest.createRestPlugin;
75
81
  exports.DEFAULT_IFRAME_DOMAINS = validation.DEFAULT_IFRAME_DOMAINS;
76
82
  exports.DEFAULT_RESOURCE_LIMITS = validation.DEFAULT_RESOURCE_LIMITS;
83
+ exports.TRUSTED_IFRAME_DOMAINS = validation.TRUSTED_IFRAME_DOMAINS;
84
+ exports.getIframeSandbox = validation.getIframeSandbox;
77
85
  exports.validateComponent = validation.validateComponent;
78
86
  exports.validateIframeDomain = validation.validateIframeDomain;
79
87
  exports.validateLayout = validation.validateLayout;
80
88
  exports.ComponentRegistry = componentRegistry.ComponentRegistry;
89
+ exports.createChatBus = chatBus.createChatBus;
90
+ exports.createCommandHandler = chatBus.createCommandHandler;
91
+ exports.createEventEmitter = chatBus.createEventEmitter;
81
92
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/index.d.cts CHANGED
@@ -33,6 +33,8 @@ export { ResizeHandle } from './components/ResizeHandle';
33
33
  export { EditableUIResourceRenderer } from './components/EditableUIResourceRenderer';
34
34
  export { ExpandableWrapper } from './components/ExpandableWrapper';
35
35
  export { ComponentToolbar } from './components/ComponentToolbar';
36
+ export { ChatBusProvider, useChatBus } from './hooks/useChatBus';
37
+ export { ChatPrompt } from './components/ChatPrompt';
36
38
  export { GhostText, GhostTextInput } from './components/GhostText';
37
39
  export { AutocompleteDropdown } from './components/AutocompleteDropdown';
38
40
  export { AutocompleteFormField } from './components/AutocompleteFormField';
@@ -42,6 +44,7 @@ export type { ResizeHandleProps as ResizeHandleComponentProps } from './componen
42
44
  export type { EditableUIResourceRendererProps } from './components/EditableUIResourceRenderer';
43
45
  export type { ExpandableWrapperProps } from './components/ExpandableWrapper';
44
46
  export type { ComponentToolbarProps, ToolbarAction, ToolbarIcon } from './components/ComponentToolbar';
47
+ export type { ChatPromptProps } from './components/ChatPrompt';
45
48
  export type { GhostTextProps, GhostTextInputProps } from './components/GhostText';
46
49
  export type { AutocompleteDropdownProps } from './components/AutocompleteDropdown';
47
50
  export type { AutocompleteFormFieldProps, AutocompleteFormFieldParams } from './components/AutocompleteFormField';
@@ -53,5 +56,6 @@ export type { MCPActionContextValue, MCPActionProviderProps, ActionRequest, Acti
53
56
  export type { AutocompleteContextValue, AutocompleteProviderProps, } from './context/AutocompleteContext';
54
57
  export { createGroqPlugin, createSupabasePlugin, createRestPlugin, } from './plugins';
55
58
  export type { UIComponent, UILayout, GridPosition, ComponentType, RendererError, ChartComponentParams, TableComponentParams, MetricComponentParams, TextComponentParams, ActionComponentParams, GridComponentParams, FormFieldOption, FormFieldType, FormFieldParams, FormComponentParams, ShowWhenOperator, ShowWhenCondition, ActionRequestBase, ActionResultBase, ActionLifecycleCallbacks, ModalSize, ModalComponentParams, ActionGroupLayout, ActionGroupGap, ActionGroupParams, GalleryImage, ImageGalleryParams, VideoComponentParams, CodeComponentParams, MapMarker, MapComponentParams, IframePolicy, ValidationOptions, ResizeConstraints, DragDropConfig, DragEventData, DraggableGridItemProps as DraggableGridItemPropsType, AutocompleteResultType, AutocompleteOption, AutocompleteResult, AutocompleteContext, AutocompletePlugin, GroqPluginConfig, SupabasePluginConfig, DuckDBPluginConfig, RestPluginConfig, FieldAutocompleteConfig, AutocompleteProviderConfig, } from './types';
56
- export { validateComponent, validateLayout, validateIframeDomain, DEFAULT_RESOURCE_LIMITS, DEFAULT_IFRAME_DOMAINS, ComponentRegistry, } from './services';
59
+ export { validateComponent, validateLayout, validateIframeDomain, getIframeSandbox, DEFAULT_RESOURCE_LIMITS, DEFAULT_IFRAME_DOMAINS, TRUSTED_IFRAME_DOMAINS, ComponentRegistry, createEventEmitter, createCommandHandler, createChatBus, } from './services';
60
+ export type { ChatEventBase, ChatEvents, ChatCommands, ChatBus, ChatEventEmitter, ChatCommandHandler, EventSubscribeOptions, ChatPromptConfig, ChatPromptResponse, ChoicePromptConfig, ConfirmPromptConfig, FormPromptConfig, SelectPromptConfig, SuggestionItem, AgentContext, BriefingEvent, BriefingSection, StreamDoneMetadata, ChatError, Citation, ToolCallEvent, ClarificationEvent, } from './types/chat-bus';
57
61
  //# sourceMappingURL=index.d.ts.map
package/dist/index.d.ts CHANGED
@@ -33,6 +33,8 @@ export { ResizeHandle } from './components/ResizeHandle';
33
33
  export { EditableUIResourceRenderer } from './components/EditableUIResourceRenderer';
34
34
  export { ExpandableWrapper } from './components/ExpandableWrapper';
35
35
  export { ComponentToolbar } from './components/ComponentToolbar';
36
+ export { ChatBusProvider, useChatBus } from './hooks/useChatBus';
37
+ export { ChatPrompt } from './components/ChatPrompt';
36
38
  export { GhostText, GhostTextInput } from './components/GhostText';
37
39
  export { AutocompleteDropdown } from './components/AutocompleteDropdown';
38
40
  export { AutocompleteFormField } from './components/AutocompleteFormField';
@@ -42,6 +44,7 @@ export type { ResizeHandleProps as ResizeHandleComponentProps } from './componen
42
44
  export type { EditableUIResourceRendererProps } from './components/EditableUIResourceRenderer';
43
45
  export type { ExpandableWrapperProps } from './components/ExpandableWrapper';
44
46
  export type { ComponentToolbarProps, ToolbarAction, ToolbarIcon } from './components/ComponentToolbar';
47
+ export type { ChatPromptProps } from './components/ChatPrompt';
45
48
  export type { GhostTextProps, GhostTextInputProps } from './components/GhostText';
46
49
  export type { AutocompleteDropdownProps } from './components/AutocompleteDropdown';
47
50
  export type { AutocompleteFormFieldProps, AutocompleteFormFieldParams } from './components/AutocompleteFormField';
@@ -53,5 +56,6 @@ export type { MCPActionContextValue, MCPActionProviderProps, ActionRequest, Acti
53
56
  export type { AutocompleteContextValue, AutocompleteProviderProps, } from './context/AutocompleteContext';
54
57
  export { createGroqPlugin, createSupabasePlugin, createRestPlugin, } from './plugins';
55
58
  export type { UIComponent, UILayout, GridPosition, ComponentType, RendererError, ChartComponentParams, TableComponentParams, MetricComponentParams, TextComponentParams, ActionComponentParams, GridComponentParams, FormFieldOption, FormFieldType, FormFieldParams, FormComponentParams, ShowWhenOperator, ShowWhenCondition, ActionRequestBase, ActionResultBase, ActionLifecycleCallbacks, ModalSize, ModalComponentParams, ActionGroupLayout, ActionGroupGap, ActionGroupParams, GalleryImage, ImageGalleryParams, VideoComponentParams, CodeComponentParams, MapMarker, MapComponentParams, IframePolicy, ValidationOptions, ResizeConstraints, DragDropConfig, DragEventData, DraggableGridItemProps as DraggableGridItemPropsType, AutocompleteResultType, AutocompleteOption, AutocompleteResult, AutocompleteContext, AutocompletePlugin, GroqPluginConfig, SupabasePluginConfig, DuckDBPluginConfig, RestPluginConfig, FieldAutocompleteConfig, AutocompleteProviderConfig, } from './types';
56
- export { validateComponent, validateLayout, validateIframeDomain, DEFAULT_RESOURCE_LIMITS, DEFAULT_IFRAME_DOMAINS, ComponentRegistry, } from './services';
59
+ export { validateComponent, validateLayout, validateIframeDomain, getIframeSandbox, DEFAULT_RESOURCE_LIMITS, DEFAULT_IFRAME_DOMAINS, TRUSTED_IFRAME_DOMAINS, ComponentRegistry, createEventEmitter, createCommandHandler, createChatBus, } from './services';
60
+ export type { ChatEventBase, ChatEvents, ChatCommands, ChatBus, ChatEventEmitter, ChatCommandHandler, EventSubscribeOptions, ChatPromptConfig, ChatPromptResponse, ChoicePromptConfig, ConfirmPromptConfig, FormPromptConfig, SelectPromptConfig, SuggestionItem, AgentContext, BriefingEvent, BriefingSection, StreamDoneMetadata, ChatError, Citation, ToolCallEvent, ClarificationEvent, } from './types/chat-bus';
57
61
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -19,6 +19,8 @@ import { ResizeHandle } from "./components/ResizeHandle.js";
19
19
  import { EditableUIResourceRenderer } from "./components/EditableUIResourceRenderer.js";
20
20
  import { ExpandableWrapper } from "./components/ExpandableWrapper.js";
21
21
  import { ComponentToolbar } from "./components/ComponentToolbar.js";
22
+ import { ChatBusProvider, useChatBus } from "./hooks/useChatBus.js";
23
+ import { ChatPrompt } from "./components/ChatPrompt.js";
22
24
  import { GhostText, GhostTextInput } from "./components/GhostText.js";
23
25
  import { AutocompleteDropdown } from "./components/AutocompleteDropdown.js";
24
26
  import { AutocompleteFormField } from "./components/AutocompleteFormField.js";
@@ -35,12 +37,15 @@ import { AutocompleteProvider, useAutocompleteContext, useAutocompleteContextSaf
35
37
  import { createGroqPlugin } from "./plugins/groq.js";
36
38
  import { createSupabasePlugin } from "./plugins/supabase.js";
37
39
  import { createRestPlugin } from "./plugins/rest.js";
38
- import { DEFAULT_IFRAME_DOMAINS, DEFAULT_RESOURCE_LIMITS, validateComponent, validateIframeDomain, validateLayout } from "./services/validation.js";
40
+ import { DEFAULT_IFRAME_DOMAINS, DEFAULT_RESOURCE_LIMITS, TRUSTED_IFRAME_DOMAINS, getIframeSandbox, validateComponent, validateIframeDomain, validateLayout } from "./services/validation.js";
39
41
  import { ComponentRegistry } from "./services/component-registry.js";
42
+ import { createChatBus, createCommandHandler, createEventEmitter } from "./services/chat-bus.js";
40
43
  export {
41
44
  AutocompleteDropdown,
42
45
  AutocompleteFormField,
43
46
  AutocompleteProvider,
47
+ ChatBusProvider,
48
+ ChatPrompt,
44
49
  ComponentRegistry,
45
50
  ComponentToolbar,
46
51
  DEFAULT_IFRAME_DOMAINS,
@@ -55,15 +60,21 @@ export {
55
60
  MCPActionProvider,
56
61
  ResizeHandle,
57
62
  StreamingUIRenderer,
63
+ TRUSTED_IFRAME_DOMAINS,
58
64
  UIResourceRenderer,
65
+ createChatBus,
66
+ createCommandHandler,
67
+ createEventEmitter,
59
68
  createGroqPlugin,
60
69
  createRestPlugin,
61
70
  createSupabasePlugin,
62
71
  evaluateCondition,
72
+ getIframeSandbox,
63
73
  useAction,
64
74
  useAutocomplete,
65
75
  useAutocompleteContext,
66
76
  useAutocompleteContextSafe,
77
+ useChatBus,
67
78
  useConditionalField,
68
79
  useConfirmModal,
69
80
  useDragDrop,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ function createEventEmitter() {
4
+ const listeners = /* @__PURE__ */ new Map();
5
+ function createThrottled(fn, ms) {
6
+ let lastCall = 0;
7
+ let timer = null;
8
+ let lastArgs = null;
9
+ let cancelled = false;
10
+ const throttled = ((...args) => {
11
+ if (cancelled) return;
12
+ lastArgs = args;
13
+ const now = Date.now();
14
+ const remaining = ms - (now - lastCall);
15
+ if (remaining <= 0) {
16
+ if (timer) {
17
+ clearTimeout(timer);
18
+ timer = null;
19
+ }
20
+ lastCall = now;
21
+ fn(...args);
22
+ } else if (!timer) {
23
+ timer = setTimeout(() => {
24
+ lastCall = Date.now();
25
+ timer = null;
26
+ if (lastArgs && !cancelled) {
27
+ try {
28
+ fn(...lastArgs);
29
+ } catch (err) {
30
+ console.error("[ChatBus] Error in throttled handler:", err);
31
+ }
32
+ }
33
+ }, remaining);
34
+ }
35
+ });
36
+ return {
37
+ fn: throttled,
38
+ cancel: () => {
39
+ cancelled = true;
40
+ if (timer) {
41
+ clearTimeout(timer);
42
+ timer = null;
43
+ }
44
+ }
45
+ };
46
+ }
47
+ return {
48
+ on(event, handler, options) {
49
+ if (!listeners.has(event)) {
50
+ listeners.set(event, /* @__PURE__ */ new Set());
51
+ }
52
+ const listener = { handler, options };
53
+ let throttleHandle = null;
54
+ if ((options == null ? void 0 : options.throttle) && options.throttle > 0) {
55
+ throttleHandle = createThrottled(handler, options.throttle);
56
+ listener.throttledHandler = throttleHandle.fn;
57
+ }
58
+ listeners.get(event).add(listener);
59
+ return () => {
60
+ var _a;
61
+ throttleHandle == null ? void 0 : throttleHandle.cancel();
62
+ (_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
63
+ };
64
+ },
65
+ emit(event, ...args) {
66
+ var _a;
67
+ const set = listeners.get(event);
68
+ if (!set) return;
69
+ for (const listener of set) {
70
+ if ((_a = listener.options) == null ? void 0 : _a.streamKey) {
71
+ let streamKeyArg;
72
+ for (const arg of args) {
73
+ if (arg && typeof arg === "object" && "streamKey" in arg) {
74
+ streamKeyArg = arg.streamKey;
75
+ break;
76
+ }
77
+ }
78
+ if (streamKeyArg !== void 0 && streamKeyArg !== listener.options.streamKey) continue;
79
+ }
80
+ const fn = listener.throttledHandler || listener.handler;
81
+ try {
82
+ fn(...args);
83
+ } catch (err) {
84
+ console.error(`[ChatBus] Error in ${event} handler:`, err);
85
+ }
86
+ }
87
+ },
88
+ clear() {
89
+ listeners.clear();
90
+ }
91
+ };
92
+ }
93
+ function createCommandHandler() {
94
+ const handlers = /* @__PURE__ */ new Map();
95
+ return {
96
+ handle(command, handler) {
97
+ handlers.set(command, handler);
98
+ },
99
+ exec(command, ...args) {
100
+ const handler = handlers.get(command);
101
+ if (!handler) {
102
+ console.warn(`[ChatBus] No handler registered for command: ${command}`);
103
+ return void 0;
104
+ }
105
+ return handler(...args);
106
+ }
107
+ };
108
+ }
109
+ function createChatBus() {
110
+ return {
111
+ events: createEventEmitter(),
112
+ commands: createCommandHandler()
113
+ };
114
+ }
115
+ exports.createChatBus = createChatBus;
116
+ exports.createCommandHandler = createCommandHandler;
117
+ exports.createEventEmitter = createEventEmitter;
118
+ //# sourceMappingURL=chat-bus.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-bus.cjs","sources":["../../src/services/chat-bus.ts"],"sourcesContent":["/**\n * Chat Bus — Event Emitter + Command Handler\n * v2.4.0: Core primitives for the chat event/command bus\n *\n * @experimental — This API may change without major bump until v2.5.0.\n */\n\nimport type {\n ChatEvents,\n ChatCommands,\n ChatEventEmitter,\n ChatCommandHandler,\n ChatBus,\n EventSubscribeOptions,\n} from '../types/chat-bus'\n\n// ─── Event Emitter ───────────────────────────────────────────\n\ninterface Listener<F extends (...args: any[]) => any> {\n handler: F\n options?: EventSubscribeOptions\n throttledHandler?: F\n}\n\n/**\n * Create a typed event emitter with throttle and streamKey filtering support.\n *\n * @experimental\n *\n * @example\n * const emitter = createEventEmitter<ChatEvents>()\n * const unsub = emitter.on('onToken', (event) => console.log(event.token), { throttle: 100 })\n * emitter.emit('onToken', { streamKey: 'abc', token: 'hello' })\n * unsub()\n */\nexport function createEventEmitter(): ChatEventEmitter {\n const listeners = new Map<string, Set<Listener<any>>>()\n\n interface ThrottledFn<F> {\n fn: F\n cancel: () => void\n }\n\n function createThrottled<F extends (...args: any[]) => void>(fn: F, ms: number): ThrottledFn<F> {\n let lastCall = 0\n let timer: ReturnType<typeof setTimeout> | null = null\n let lastArgs: any[] | null = null\n let cancelled = false\n\n const throttled = ((...args: any[]) => {\n if (cancelled) return\n lastArgs = args\n const now = Date.now()\n const remaining = ms - (now - lastCall)\n\n if (remaining <= 0) {\n if (timer) { clearTimeout(timer); timer = null }\n lastCall = now\n fn(...args)\n } else if (!timer) {\n timer = setTimeout(() => {\n lastCall = Date.now()\n timer = null\n if (lastArgs && !cancelled) {\n try { fn(...lastArgs) } catch (err) { console.error('[ChatBus] Error in throttled handler:', err) }\n }\n }, remaining)\n }\n }) as F\n\n return {\n fn: throttled,\n cancel: () => { cancelled = true; if (timer) { clearTimeout(timer); timer = null } },\n }\n }\n\n return {\n on(event, handler, options) {\n if (!listeners.has(event as string)) {\n listeners.set(event as string, new Set())\n }\n\n const listener: Listener<typeof handler> = { handler, options }\n\n // Apply throttle if requested\n let throttleHandle: ThrottledFn<typeof handler> | null = null\n if (options?.throttle && options.throttle > 0) {\n throttleHandle = createThrottled(handler, options.throttle)\n listener.throttledHandler = throttleHandle.fn\n }\n\n listeners.get(event as string)!.add(listener)\n\n // Return unsubscribe function — cancels pending throttle timers\n return () => {\n throttleHandle?.cancel()\n listeners.get(event as string)?.delete(listener)\n }\n },\n\n emit(event, ...args) {\n const set = listeners.get(event as string)\n if (!set) return\n\n for (const listener of set) {\n // StreamKey filtering: skip if listener wants a specific streamKey\n // For most events args[0] has streamKey; for onCustomEvent args[1] has it\n if (listener.options?.streamKey) {\n let streamKeyArg: unknown\n for (const arg of args) {\n if (arg && typeof arg === 'object' && 'streamKey' in (arg as any)) {\n streamKeyArg = (arg as any).streamKey\n break\n }\n }\n if (streamKeyArg !== undefined && streamKeyArg !== listener.options.streamKey) continue\n }\n\n const fn = listener.throttledHandler || listener.handler\n try {\n fn(...args)\n } catch (err) {\n console.error(`[ChatBus] Error in ${event as string} handler:`, err)\n }\n }\n },\n\n clear() {\n listeners.clear()\n },\n } as ChatEventEmitter\n}\n\n// ─── Command Handler ─────────────────────────────────────────\n\n/**\n * Create a typed command handler. The host app registers handlers,\n * agents execute commands.\n *\n * @experimental\n *\n * @example\n * const commands = createCommandHandler<ChatCommands>()\n * commands.handle('injectPrompt', (text) => setInputValue(text))\n * commands.exec('injectPrompt', 'Hello world')\n */\nexport function createCommandHandler(): ChatCommandHandler {\n const handlers = new Map<string, (...args: any[]) => any>()\n\n return {\n handle(command, handler) {\n handlers.set(command as string, handler)\n },\n\n exec(command, ...args) {\n const handler = handlers.get(command as string)\n if (!handler) {\n console.warn(`[ChatBus] No handler registered for command: ${command as string}`)\n return undefined as any\n }\n return handler(...args)\n },\n } as ChatCommandHandler\n}\n\n// ─── Chat Bus Factory ────────────────────────────────────────\n\n/**\n * Create a complete ChatBus with events + commands.\n *\n * @experimental\n *\n * @example\n * const bus = createChatBus()\n * bus.events.on('onStreamEnd', (event) => { ... })\n * bus.commands.handle('sendPrompt', (text) => { ... })\n */\nexport function createChatBus(): ChatBus {\n return {\n events: createEventEmitter(),\n commands: createCommandHandler(),\n }\n}\n"],"names":[],"mappings":";;AAmCO,SAAS,qBAAuC;AACrD,QAAM,gCAAgB,IAAA;AAOtB,WAAS,gBAAoD,IAAO,IAA4B;AAC9F,QAAI,WAAW;AACf,QAAI,QAA8C;AAClD,QAAI,WAAyB;AAC7B,QAAI,YAAY;AAEhB,UAAM,aAAa,IAAI,SAAgB;AACrC,UAAI,UAAW;AACf,iBAAW;AACX,YAAM,MAAM,KAAK,IAAA;AACjB,YAAM,YAAY,MAAM,MAAM;AAE9B,UAAI,aAAa,GAAG;AAClB,YAAI,OAAO;AAAE,uBAAa,KAAK;AAAG,kBAAQ;AAAA,QAAK;AAC/C,mBAAW;AACX,WAAG,GAAG,IAAI;AAAA,MACZ,WAAW,CAAC,OAAO;AACjB,gBAAQ,WAAW,MAAM;AACvB,qBAAW,KAAK,IAAA;AAChB,kBAAQ;AACR,cAAI,YAAY,CAAC,WAAW;AAC1B,gBAAI;AAAE,iBAAG,GAAG,QAAQ;AAAA,YAAE,SAAS,KAAK;AAAE,sBAAQ,MAAM,yCAAyC,GAAG;AAAA,YAAE;AAAA,UACpG;AAAA,QACF,GAAG,SAAS;AAAA,MACd;AAAA,IACF;AAEA,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ,MAAM;AAAE,oBAAY;AAAM,YAAI,OAAO;AAAE,uBAAa,KAAK;AAAG,kBAAQ;AAAA,QAAK;AAAA,MAAE;AAAA,IAAA;AAAA,EAEvF;AAEA,SAAO;AAAA,IACL,GAAG,OAAO,SAAS,SAAS;AAC1B,UAAI,CAAC,UAAU,IAAI,KAAe,GAAG;AACnC,kBAAU,IAAI,OAAiB,oBAAI,IAAA,CAAK;AAAA,MAC1C;AAEA,YAAM,WAAqC,EAAE,SAAS,QAAA;AAGtD,UAAI,iBAAqD;AACzD,WAAI,mCAAS,aAAY,QAAQ,WAAW,GAAG;AAC7C,yBAAiB,gBAAgB,SAAS,QAAQ,QAAQ;AAC1D,iBAAS,mBAAmB,eAAe;AAAA,MAC7C;AAEA,gBAAU,IAAI,KAAe,EAAG,IAAI,QAAQ;AAG5C,aAAO,MAAM;;AACX,yDAAgB;AAChB,wBAAU,IAAI,KAAe,MAA7B,mBAAgC,OAAO;AAAA,MACzC;AAAA,IACF;AAAA,IAEA,KAAK,UAAU,MAAM;;AACnB,YAAM,MAAM,UAAU,IAAI,KAAe;AACzC,UAAI,CAAC,IAAK;AAEV,iBAAW,YAAY,KAAK;AAG1B,aAAI,cAAS,YAAT,mBAAkB,WAAW;AAC/B,cAAI;AACJ,qBAAW,OAAO,MAAM;AACtB,gBAAI,OAAO,OAAO,QAAQ,YAAY,eAAgB,KAAa;AACjE,6BAAgB,IAAY;AAC5B;AAAA,YACF;AAAA,UACF;AACA,cAAI,iBAAiB,UAAa,iBAAiB,SAAS,QAAQ,UAAW;AAAA,QACjF;AAEA,cAAM,KAAK,SAAS,oBAAoB,SAAS;AACjD,YAAI;AACF,aAAG,GAAG,IAAI;AAAA,QACZ,SAAS,KAAK;AACZ,kBAAQ,MAAM,sBAAsB,KAAe,aAAa,GAAG;AAAA,QACrE;AAAA,MACF;AAAA,IACF;AAAA,IAEA,QAAQ;AACN,gBAAU,MAAA;AAAA,IACZ;AAAA,EAAA;AAEJ;AAeO,SAAS,uBAA2C;AACzD,QAAM,+BAAe,IAAA;AAErB,SAAO;AAAA,IACL,OAAO,SAAS,SAAS;AACvB,eAAS,IAAI,SAAmB,OAAO;AAAA,IACzC;AAAA,IAEA,KAAK,YAAY,MAAM;AACrB,YAAM,UAAU,SAAS,IAAI,OAAiB;AAC9C,UAAI,CAAC,SAAS;AACZ,gBAAQ,KAAK,gDAAgD,OAAiB,EAAE;AAChF,eAAO;AAAA,MACT;AACA,aAAO,QAAQ,GAAG,IAAI;AAAA,IACxB;AAAA,EAAA;AAEJ;AAcO,SAAS,gBAAyB;AACvC,SAAO;AAAA,IACL,QAAQ,mBAAA;AAAA,IACR,UAAU,qBAAA;AAAA,EAAqB;AAEnC;;;;"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Chat Bus — Event Emitter + Command Handler
3
+ * v2.4.0: Core primitives for the chat event/command bus
4
+ *
5
+ * @experimental — This API may change without major bump until v2.5.0.
6
+ */
7
+ import type { ChatEventEmitter, ChatCommandHandler, ChatBus } from '../types/chat-bus';
8
+ /**
9
+ * Create a typed event emitter with throttle and streamKey filtering support.
10
+ *
11
+ * @experimental
12
+ *
13
+ * @example
14
+ * const emitter = createEventEmitter<ChatEvents>()
15
+ * const unsub = emitter.on('onToken', (event) => console.log(event.token), { throttle: 100 })
16
+ * emitter.emit('onToken', { streamKey: 'abc', token: 'hello' })
17
+ * unsub()
18
+ */
19
+ export declare function createEventEmitter(): ChatEventEmitter;
20
+ /**
21
+ * Create a typed command handler. The host app registers handlers,
22
+ * agents execute commands.
23
+ *
24
+ * @experimental
25
+ *
26
+ * @example
27
+ * const commands = createCommandHandler<ChatCommands>()
28
+ * commands.handle('injectPrompt', (text) => setInputValue(text))
29
+ * commands.exec('injectPrompt', 'Hello world')
30
+ */
31
+ export declare function createCommandHandler(): ChatCommandHandler;
32
+ /**
33
+ * Create a complete ChatBus with events + commands.
34
+ *
35
+ * @experimental
36
+ *
37
+ * @example
38
+ * const bus = createChatBus()
39
+ * bus.events.on('onStreamEnd', (event) => { ... })
40
+ * bus.commands.handle('sendPrompt', (text) => { ... })
41
+ */
42
+ export declare function createChatBus(): ChatBus;
43
+ //# sourceMappingURL=chat-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-bus.d.ts","sourceRoot":"","sources":["../../src/services/chat-bus.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAGV,gBAAgB,EAChB,kBAAkB,EAClB,OAAO,EAER,MAAM,mBAAmB,CAAA;AAU1B;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,IAAI,gBAAgB,CAgGrD;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,IAAI,kBAAkB,CAiBzD;AAID;;;;;;;;;GASG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAKvC"}
@@ -0,0 +1,118 @@
1
+ function createEventEmitter() {
2
+ const listeners = /* @__PURE__ */ new Map();
3
+ function createThrottled(fn, ms) {
4
+ let lastCall = 0;
5
+ let timer = null;
6
+ let lastArgs = null;
7
+ let cancelled = false;
8
+ const throttled = ((...args) => {
9
+ if (cancelled) return;
10
+ lastArgs = args;
11
+ const now = Date.now();
12
+ const remaining = ms - (now - lastCall);
13
+ if (remaining <= 0) {
14
+ if (timer) {
15
+ clearTimeout(timer);
16
+ timer = null;
17
+ }
18
+ lastCall = now;
19
+ fn(...args);
20
+ } else if (!timer) {
21
+ timer = setTimeout(() => {
22
+ lastCall = Date.now();
23
+ timer = null;
24
+ if (lastArgs && !cancelled) {
25
+ try {
26
+ fn(...lastArgs);
27
+ } catch (err) {
28
+ console.error("[ChatBus] Error in throttled handler:", err);
29
+ }
30
+ }
31
+ }, remaining);
32
+ }
33
+ });
34
+ return {
35
+ fn: throttled,
36
+ cancel: () => {
37
+ cancelled = true;
38
+ if (timer) {
39
+ clearTimeout(timer);
40
+ timer = null;
41
+ }
42
+ }
43
+ };
44
+ }
45
+ return {
46
+ on(event, handler, options) {
47
+ if (!listeners.has(event)) {
48
+ listeners.set(event, /* @__PURE__ */ new Set());
49
+ }
50
+ const listener = { handler, options };
51
+ let throttleHandle = null;
52
+ if ((options == null ? void 0 : options.throttle) && options.throttle > 0) {
53
+ throttleHandle = createThrottled(handler, options.throttle);
54
+ listener.throttledHandler = throttleHandle.fn;
55
+ }
56
+ listeners.get(event).add(listener);
57
+ return () => {
58
+ var _a;
59
+ throttleHandle == null ? void 0 : throttleHandle.cancel();
60
+ (_a = listeners.get(event)) == null ? void 0 : _a.delete(listener);
61
+ };
62
+ },
63
+ emit(event, ...args) {
64
+ var _a;
65
+ const set = listeners.get(event);
66
+ if (!set) return;
67
+ for (const listener of set) {
68
+ if ((_a = listener.options) == null ? void 0 : _a.streamKey) {
69
+ let streamKeyArg;
70
+ for (const arg of args) {
71
+ if (arg && typeof arg === "object" && "streamKey" in arg) {
72
+ streamKeyArg = arg.streamKey;
73
+ break;
74
+ }
75
+ }
76
+ if (streamKeyArg !== void 0 && streamKeyArg !== listener.options.streamKey) continue;
77
+ }
78
+ const fn = listener.throttledHandler || listener.handler;
79
+ try {
80
+ fn(...args);
81
+ } catch (err) {
82
+ console.error(`[ChatBus] Error in ${event} handler:`, err);
83
+ }
84
+ }
85
+ },
86
+ clear() {
87
+ listeners.clear();
88
+ }
89
+ };
90
+ }
91
+ function createCommandHandler() {
92
+ const handlers = /* @__PURE__ */ new Map();
93
+ return {
94
+ handle(command, handler) {
95
+ handlers.set(command, handler);
96
+ },
97
+ exec(command, ...args) {
98
+ const handler = handlers.get(command);
99
+ if (!handler) {
100
+ console.warn(`[ChatBus] No handler registered for command: ${command}`);
101
+ return void 0;
102
+ }
103
+ return handler(...args);
104
+ }
105
+ };
106
+ }
107
+ function createChatBus() {
108
+ return {
109
+ events: createEventEmitter(),
110
+ commands: createCommandHandler()
111
+ };
112
+ }
113
+ export {
114
+ createChatBus,
115
+ createCommandHandler,
116
+ createEventEmitter
117
+ };
118
+ //# sourceMappingURL=chat-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-bus.js","sources":["../../src/services/chat-bus.ts"],"sourcesContent":["/**\n * Chat Bus — Event Emitter + Command Handler\n * v2.4.0: Core primitives for the chat event/command bus\n *\n * @experimental — This API may change without major bump until v2.5.0.\n */\n\nimport type {\n ChatEvents,\n ChatCommands,\n ChatEventEmitter,\n ChatCommandHandler,\n ChatBus,\n EventSubscribeOptions,\n} from '../types/chat-bus'\n\n// ─── Event Emitter ───────────────────────────────────────────\n\ninterface Listener<F extends (...args: any[]) => any> {\n handler: F\n options?: EventSubscribeOptions\n throttledHandler?: F\n}\n\n/**\n * Create a typed event emitter with throttle and streamKey filtering support.\n *\n * @experimental\n *\n * @example\n * const emitter = createEventEmitter<ChatEvents>()\n * const unsub = emitter.on('onToken', (event) => console.log(event.token), { throttle: 100 })\n * emitter.emit('onToken', { streamKey: 'abc', token: 'hello' })\n * unsub()\n */\nexport function createEventEmitter(): ChatEventEmitter {\n const listeners = new Map<string, Set<Listener<any>>>()\n\n interface ThrottledFn<F> {\n fn: F\n cancel: () => void\n }\n\n function createThrottled<F extends (...args: any[]) => void>(fn: F, ms: number): ThrottledFn<F> {\n let lastCall = 0\n let timer: ReturnType<typeof setTimeout> | null = null\n let lastArgs: any[] | null = null\n let cancelled = false\n\n const throttled = ((...args: any[]) => {\n if (cancelled) return\n lastArgs = args\n const now = Date.now()\n const remaining = ms - (now - lastCall)\n\n if (remaining <= 0) {\n if (timer) { clearTimeout(timer); timer = null }\n lastCall = now\n fn(...args)\n } else if (!timer) {\n timer = setTimeout(() => {\n lastCall = Date.now()\n timer = null\n if (lastArgs && !cancelled) {\n try { fn(...lastArgs) } catch (err) { console.error('[ChatBus] Error in throttled handler:', err) }\n }\n }, remaining)\n }\n }) as F\n\n return {\n fn: throttled,\n cancel: () => { cancelled = true; if (timer) { clearTimeout(timer); timer = null } },\n }\n }\n\n return {\n on(event, handler, options) {\n if (!listeners.has(event as string)) {\n listeners.set(event as string, new Set())\n }\n\n const listener: Listener<typeof handler> = { handler, options }\n\n // Apply throttle if requested\n let throttleHandle: ThrottledFn<typeof handler> | null = null\n if (options?.throttle && options.throttle > 0) {\n throttleHandle = createThrottled(handler, options.throttle)\n listener.throttledHandler = throttleHandle.fn\n }\n\n listeners.get(event as string)!.add(listener)\n\n // Return unsubscribe function — cancels pending throttle timers\n return () => {\n throttleHandle?.cancel()\n listeners.get(event as string)?.delete(listener)\n }\n },\n\n emit(event, ...args) {\n const set = listeners.get(event as string)\n if (!set) return\n\n for (const listener of set) {\n // StreamKey filtering: skip if listener wants a specific streamKey\n // For most events args[0] has streamKey; for onCustomEvent args[1] has it\n if (listener.options?.streamKey) {\n let streamKeyArg: unknown\n for (const arg of args) {\n if (arg && typeof arg === 'object' && 'streamKey' in (arg as any)) {\n streamKeyArg = (arg as any).streamKey\n break\n }\n }\n if (streamKeyArg !== undefined && streamKeyArg !== listener.options.streamKey) continue\n }\n\n const fn = listener.throttledHandler || listener.handler\n try {\n fn(...args)\n } catch (err) {\n console.error(`[ChatBus] Error in ${event as string} handler:`, err)\n }\n }\n },\n\n clear() {\n listeners.clear()\n },\n } as ChatEventEmitter\n}\n\n// ─── Command Handler ─────────────────────────────────────────\n\n/**\n * Create a typed command handler. The host app registers handlers,\n * agents execute commands.\n *\n * @experimental\n *\n * @example\n * const commands = createCommandHandler<ChatCommands>()\n * commands.handle('injectPrompt', (text) => setInputValue(text))\n * commands.exec('injectPrompt', 'Hello world')\n */\nexport function createCommandHandler(): ChatCommandHandler {\n const handlers = new Map<string, (...args: any[]) => any>()\n\n return {\n handle(command, handler) {\n handlers.set(command as string, handler)\n },\n\n exec(command, ...args) {\n const handler = handlers.get(command as string)\n if (!handler) {\n console.warn(`[ChatBus] No handler registered for command: ${command as string}`)\n return undefined as any\n }\n return handler(...args)\n },\n } as ChatCommandHandler\n}\n\n// ─── Chat Bus Factory ────────────────────────────────────────\n\n/**\n * Create a complete ChatBus with events + commands.\n *\n * @experimental\n *\n * @example\n * const bus = createChatBus()\n * bus.events.on('onStreamEnd', (event) => { ... })\n * bus.commands.handle('sendPrompt', (text) => { ... })\n */\nexport function createChatBus(): ChatBus {\n return {\n events: createEventEmitter(),\n commands: createCommandHandler(),\n }\n}\n"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * Business logic for component validation and registry management
5
5
  */
6
- export { validateComponent, validateLayout, validateIframeDomain, DEFAULT_RESOURCE_LIMITS, DEFAULT_IFRAME_DOMAINS, } from './validation';
6
+ export { validateComponent, validateLayout, validateIframeDomain, getIframeSandbox, DEFAULT_RESOURCE_LIMITS, DEFAULT_IFRAME_DOMAINS, TRUSTED_IFRAME_DOMAINS, } from './validation';
7
7
  export { ComponentRegistry } from './component-registry';
8
+ export { createEventEmitter, createCommandHandler, createChatBus } from './chat-bus';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAExD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA"}
@@ -123,7 +123,57 @@ const DEFAULT_IFRAME_DOMAINS = [
123
123
  "clinicaltrials.gov",
124
124
  "www.clinicaltrials.gov",
125
125
  "linear.app",
126
- "www.linear.app"
126
+ "www.linear.app",
127
+ // Payment platforms (v2.2.12)
128
+ "polar.sh",
129
+ "www.polar.sh",
130
+ "checkout.stripe.com",
131
+ "js.stripe.com",
132
+ "billing.stripe.com",
133
+ "buy.stripe.com",
134
+ "connect.stripe.com",
135
+ "invoice.stripe.com"
136
+ ];
137
+ const TRUSTED_IFRAME_DOMAINS = [
138
+ // Deposium (own domains)
139
+ "deposium.com",
140
+ "deposium.vip",
141
+ "deposium.ai",
142
+ "localhost",
143
+ // Google services (need auth cookies)
144
+ "docs.google.com",
145
+ "drive.google.com",
146
+ "sheets.google.com",
147
+ "slides.google.com",
148
+ "maps.google.com",
149
+ "datastudio.google.com",
150
+ "lookerstudio.google.com",
151
+ // Productivity (need auth)
152
+ "notion.so",
153
+ "www.notion.so",
154
+ "airtable.com",
155
+ "figma.com",
156
+ "www.figma.com",
157
+ "miro.com",
158
+ // Payment (need auth + cookies for checkout)
159
+ "polar.sh",
160
+ "www.polar.sh",
161
+ "checkout.stripe.com",
162
+ "js.stripe.com",
163
+ "billing.stripe.com",
164
+ "buy.stripe.com",
165
+ "connect.stripe.com",
166
+ "invoice.stripe.com",
167
+ // Business tools (need auth)
168
+ "app.hubspot.com",
169
+ "share.hubspot.com",
170
+ "app.powerbi.com",
171
+ "linear.app",
172
+ "www.linear.app",
173
+ "calendly.com",
174
+ "typeform.com",
175
+ "cal.com",
176
+ "canva.com"
127
177
  ];
128
178
  function validateGridPosition(position) {
129
179
  const errors = [];
@@ -350,6 +400,24 @@ function validateIframeDomain(url, options) {
350
400
  };
351
401
  }
352
402
  }
403
+ function getIframeSandbox(url, options) {
404
+ const baseSandbox = "allow-scripts allow-popups";
405
+ try {
406
+ const domain = new URL(url).hostname;
407
+ let trustedList = TRUSTED_IFRAME_DOMAINS;
408
+ if (options == null ? void 0 : options.customTrustedDomains) {
409
+ trustedList = [...TRUSTED_IFRAME_DOMAINS, ...options.customTrustedDomains];
410
+ }
411
+ const isTrusted = trustedList.some(
412
+ (trusted) => domain === trusted || domain.endsWith(`.${trusted}`)
413
+ );
414
+ if (isTrusted) {
415
+ return `${baseSandbox} allow-same-origin allow-forms`;
416
+ }
417
+ } catch {
418
+ }
419
+ return baseSandbox;
420
+ }
353
421
  function validateComponent(component, options) {
354
422
  const limits = (options == null ? void 0 : options.limits) ?? DEFAULT_RESOURCE_LIMITS;
355
423
  const errors = [];
@@ -654,6 +722,8 @@ function validateFormData(data, fields) {
654
722
  }
655
723
  exports.DEFAULT_IFRAME_DOMAINS = DEFAULT_IFRAME_DOMAINS;
656
724
  exports.DEFAULT_RESOURCE_LIMITS = DEFAULT_RESOURCE_LIMITS;
725
+ exports.TRUSTED_IFRAME_DOMAINS = TRUSTED_IFRAME_DOMAINS;
726
+ exports.getIframeSandbox = getIframeSandbox;
657
727
  exports.sanitizeString = sanitizeString;
658
728
  exports.validateChartComponent = validateChartComponent;
659
729
  exports.validateComponent = validateComponent;