@tambo-ai/react 0.37.3 → 0.38.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 (65) hide show
  1. package/dist/index.d.ts +4 -1
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +6 -2
  4. package/dist/index.js.map +1 -1
  5. package/dist/model/tambo-interactable.d.ts +24 -0
  6. package/dist/model/tambo-interactable.d.ts.map +1 -0
  7. package/dist/model/tambo-interactable.js +3 -0
  8. package/dist/model/tambo-interactable.js.map +1 -0
  9. package/dist/providers/__tests__/tambo-prop-stream-provider.test.d.ts +2 -0
  10. package/dist/providers/__tests__/tambo-prop-stream-provider.test.d.ts.map +1 -0
  11. package/dist/providers/__tests__/tambo-prop-stream-provider.test.js +278 -0
  12. package/dist/providers/__tests__/tambo-prop-stream-provider.test.js.map +1 -0
  13. package/dist/providers/hoc/with-tambo-interactable.d.ts +34 -0
  14. package/dist/providers/hoc/with-tambo-interactable.d.ts.map +1 -0
  15. package/dist/providers/hoc/with-tambo-interactable.js +119 -0
  16. package/dist/providers/hoc/with-tambo-interactable.js.map +1 -0
  17. package/dist/providers/index.d.ts +1 -0
  18. package/dist/providers/index.d.ts.map +1 -1
  19. package/dist/providers/index.js +3 -1
  20. package/dist/providers/index.js.map +1 -1
  21. package/dist/providers/tambo-interactable-provider.d.ts +20 -0
  22. package/dist/providers/tambo-interactable-provider.d.ts.map +1 -0
  23. package/dist/providers/tambo-interactable-provider.js +243 -0
  24. package/dist/providers/tambo-interactable-provider.js.map +1 -0
  25. package/dist/providers/tambo-prop-stream-provider.d.ts +96 -0
  26. package/dist/providers/tambo-prop-stream-provider.d.ts.map +1 -0
  27. package/dist/providers/tambo-prop-stream-provider.js +185 -0
  28. package/dist/providers/tambo-prop-stream-provider.js.map +1 -0
  29. package/dist/providers/tambo-provider.d.ts +6 -4
  30. package/dist/providers/tambo-provider.d.ts.map +1 -1
  31. package/dist/providers/tambo-provider.js +9 -4
  32. package/dist/providers/tambo-provider.js.map +1 -1
  33. package/esm/index.d.ts +4 -1
  34. package/esm/index.d.ts.map +1 -1
  35. package/esm/index.js +3 -1
  36. package/esm/index.js.map +1 -1
  37. package/esm/model/tambo-interactable.d.ts +24 -0
  38. package/esm/model/tambo-interactable.d.ts.map +1 -0
  39. package/esm/model/tambo-interactable.js +2 -0
  40. package/esm/model/tambo-interactable.js.map +1 -0
  41. package/esm/providers/__tests__/tambo-prop-stream-provider.test.d.ts +2 -0
  42. package/esm/providers/__tests__/tambo-prop-stream-provider.test.d.ts.map +1 -0
  43. package/esm/providers/__tests__/tambo-prop-stream-provider.test.js +273 -0
  44. package/esm/providers/__tests__/tambo-prop-stream-provider.test.js.map +1 -0
  45. package/esm/providers/hoc/with-tambo-interactable.d.ts +34 -0
  46. package/esm/providers/hoc/with-tambo-interactable.d.ts.map +1 -0
  47. package/esm/providers/hoc/with-tambo-interactable.js +83 -0
  48. package/esm/providers/hoc/with-tambo-interactable.js.map +1 -0
  49. package/esm/providers/index.d.ts +1 -0
  50. package/esm/providers/index.d.ts.map +1 -1
  51. package/esm/providers/index.js +1 -0
  52. package/esm/providers/index.js.map +1 -1
  53. package/esm/providers/tambo-interactable-provider.d.ts +20 -0
  54. package/esm/providers/tambo-interactable-provider.d.ts.map +1 -0
  55. package/esm/providers/tambo-interactable-provider.js +205 -0
  56. package/esm/providers/tambo-interactable-provider.js.map +1 -0
  57. package/esm/providers/tambo-prop-stream-provider.d.ts +96 -0
  58. package/esm/providers/tambo-prop-stream-provider.d.ts.map +1 -0
  59. package/esm/providers/tambo-prop-stream-provider.js +148 -0
  60. package/esm/providers/tambo-prop-stream-provider.js.map +1 -0
  61. package/esm/providers/tambo-provider.d.ts +6 -4
  62. package/esm/providers/tambo-provider.d.ts.map +1 -1
  63. package/esm/providers/tambo-provider.js +9 -4
  64. package/esm/providers/tambo-provider.js.map +1 -1
  65. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tambo-prop-stream-provider.js","sourceRoot":"","sources":["../../src/providers/tambo-prop-stream-provider.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\nimport React, {\n createContext,\n PropsWithChildren,\n useContext,\n useMemo,\n} from \"react\";\nimport { StreamStatus } from \"../hooks/use-tambo-stream-status\";\n\ninterface TamboPropStreamContextValue {\n /** The stream data */\n data: any;\n /** The stream status */\n streamStatus: StreamStatus;\n /** Get the status for a specific key */\n getStatusForKey: (key: string) => {\n isPending: boolean;\n isStreaming: boolean;\n isSuccess: boolean;\n isError: boolean;\n error?: Error;\n };\n}\n\nconst TamboPropStreamContext =\n createContext<TamboPropStreamContextValue | null>(null);\n\nexport interface TamboPropStreamProviderProps {\n /** The stream data */\n data: any;\n /** Optional stream status for more granular control */\n streamStatus?: StreamStatus;\n}\n\nexport interface LoadingProps {\n /** The key to identify this loading state */\n streamKey?: string;\n /** The children to render when loading */\n children: React.ReactNode;\n /** Optional className for styling */\n className?: string;\n}\n\nexport interface EmptyProps {\n /** The key to identify this empty state */\n streamKey?: string;\n /** The children to render when empty */\n children: React.ReactNode;\n /** Optional className for styling */\n className?: string;\n}\n\nexport interface CompleteProps {\n /** The key to identify this complete state */\n streamKey?: string;\n /** The children to render when complete */\n children: React.ReactNode;\n /** Optional className for styling */\n className?: string;\n}\n\n/**\n * Loading component that renders children when the stream is in a loading state\n * @param props - The props for the Loading component\n * @param props.key - The key to identify this loading state\n * @param props.children - The children to render when loading\n * @param props.className - Optional className for styling\n * @returns The Loading component\n */\nconst Loading: React.FC<LoadingProps> = ({\n streamKey = \"default\",\n children,\n className,\n}) => {\n const { getStatusForKey } = useTamboStream();\n const status = getStatusForKey(streamKey);\n\n if (!status.isPending && !status.isStreaming) {\n return null;\n }\n\n return (\n <div\n className={className}\n data-stream-key={streamKey}\n data-stream-state=\"loading\"\n >\n {children}\n </div>\n );\n};\n\n/**\n * Empty component that renders children when the stream has no data\n * @param props - The props for the Empty component\n * @param props.key - The key to identify this empty state\n * @param props.children - The children to render when empty\n * @param props.className - Optional className for styling\n * @returns The Empty component\n */\nconst Empty: React.FC<EmptyProps> = ({\n streamKey = \"default\",\n children,\n className,\n}) => {\n const { data, getStatusForKey } = useTamboStream();\n const status = getStatusForKey(streamKey);\n\n // Get the specific data for this key\n const keyData =\n data && typeof data === \"object\" && !Array.isArray(data)\n ? data[streamKey]\n : data;\n\n // Show empty state when not loading, not streaming, not successful, and no data for this key\n const shouldShowEmpty =\n !status.isPending &&\n !status.isStreaming &&\n !status.isSuccess &&\n !status.isError &&\n (keyData === undefined || keyData === null || keyData === \"\");\n\n if (!shouldShowEmpty) {\n return null;\n }\n\n return (\n <div\n className={className}\n data-stream-key={streamKey}\n data-stream-state=\"empty\"\n >\n {children}\n </div>\n );\n};\n\n/**\n * Complete component that renders children when the stream has data\n * @param props - The props for the Complete component\n * @param props.key - The key to identify this complete state\n * @param props.children - The children to render when complete\n * @param props.className - Optional className for styling\n * @returns The Complete component\n */\nconst Complete: React.FC<CompleteProps> = ({\n streamKey = \"default\",\n children,\n className,\n}) => {\n const { data, getStatusForKey } = useTamboStream();\n const status = getStatusForKey(streamKey);\n\n // Get the specific data for this key\n const keyData =\n data && typeof data === \"object\" && !Array.isArray(data)\n ? data[streamKey]\n : data;\n\n // Show complete when we have data for this key and the stream is successful\n const shouldShowComplete =\n status.isSuccess && keyData !== undefined && keyData !== null;\n\n if (!shouldShowComplete) {\n return null;\n }\n\n return (\n <div\n className={className}\n data-stream-key={streamKey}\n data-stream-state=\"complete\"\n >\n {children}\n </div>\n );\n};\n\n/**\n * Hook to use the TamboStream context\n * @returns The TamboStream context\n */\nexport const useTamboStream = () => {\n const context = useContext(TamboPropStreamContext);\n if (!context) {\n throw new Error(\n \"useTamboStream must be used within a TamboPropStreamProvider\",\n );\n }\n return context;\n};\n\n/**\n * The TamboStreamProvider provides a context for managing stream states\n * with compound components for Loading, Empty, and Complete states.\n * @param props - The props for the TamboStreamProvider\n * @param props.children - The children to wrap\n * @param props.data - The stream data\n * @param props.streamStatus - Optional stream status for more granular control\n * @returns The TamboStreamProvider component\n */\nconst TamboPropStreamProviderComponent: React.FC<\n PropsWithChildren<TamboPropStreamProviderProps>\n> = ({ children, data, streamStatus }) => {\n // Create a default stream status if none provided\n const defaultStreamStatus: StreamStatus = useMemo(\n () => ({\n isPending: false, // No external stream, so not pending\n isStreaming: false, // No external stream, so not streaming\n isSuccess: true, // If no stream status provided, assume success\n isError: false,\n streamError: undefined,\n }),\n [],\n );\n\n const finalStreamStatus = streamStatus ?? defaultStreamStatus;\n\n // Track status by key for compound components\n const keyStatusMap = useMemo(() => {\n const map = new Map<\n string,\n {\n isPending: boolean;\n isStreaming: boolean;\n isSuccess: boolean;\n isError: boolean;\n error?: Error;\n }\n >();\n\n // Track per-key status based on data structure\n // If data is an object with keys, create status for each key\n if (data && typeof data === \"object\" && !Array.isArray(data)) {\n Object.keys(data).forEach((key) => {\n const keyData = data[key];\n const hasData =\n keyData !== undefined && keyData !== null && keyData !== \"\";\n\n map.set(key, {\n // If no external stream, show loading when key has no data\n isPending:\n finalStreamStatus.isPending ||\n (!finalStreamStatus.isStreaming && !hasData),\n isStreaming: finalStreamStatus.isStreaming && !hasData,\n isSuccess: finalStreamStatus.isSuccess && hasData,\n isError: finalStreamStatus.isError,\n error: finalStreamStatus.streamError,\n });\n });\n }\n\n // Always set default status for fallback\n map.set(\"default\", {\n isPending: finalStreamStatus.isPending,\n isStreaming: finalStreamStatus.isStreaming,\n isSuccess: finalStreamStatus.isSuccess,\n isError: finalStreamStatus.isError,\n error: finalStreamStatus.streamError,\n });\n\n return map;\n }, [finalStreamStatus, data]);\n\n const getStatusForKey = useMemo(\n () => (key: string) => {\n return (\n keyStatusMap.get(key) ??\n keyStatusMap.get(\"default\") ?? {\n isPending: false,\n isStreaming: false,\n isSuccess: false,\n isError: false,\n }\n );\n },\n [keyStatusMap],\n );\n\n const contextValue = useMemo(\n () => ({\n data,\n streamStatus: finalStreamStatus,\n getStatusForKey,\n }),\n [data, finalStreamStatus, getStatusForKey],\n );\n\n return (\n <TamboPropStreamContext.Provider value={contextValue}>\n {children}\n </TamboPropStreamContext.Provider>\n );\n};\n\n// Create the compound component type\ntype TamboPropStreamProviderCompound =\n typeof TamboPropStreamProviderComponent & {\n Loading: typeof Loading;\n Empty: typeof Empty;\n Complete: typeof Complete;\n };\n\nexport const TamboPropStreamProvider =\n TamboPropStreamProviderComponent as TamboPropStreamProviderCompound;\n\nTamboPropStreamProvider.Loading = Loading;\nTamboPropStreamProvider.Empty = Empty;\nTamboPropStreamProvider.Complete = Complete;\n"]}
@@ -1,11 +1,12 @@
1
1
  import React, { PropsWithChildren } from "react";
2
+ import { TamboInteractableContext } from "../model/tambo-interactable";
2
3
  import { TamboClientContextProps, TamboClientProviderProps } from "./tambo-client-provider";
3
4
  import { TamboComponentContextProps } from "./tambo-component-provider";
4
5
  import { TamboRegistryProviderProps } from "./tambo-registry-provider";
5
6
  import { TamboThreadContextProps, TamboThreadProviderProps } from "./tambo-thread-provider";
6
7
  /**
7
8
  * The TamboProvider gives full access to the whole Tambo API. This includes the
8
- * TamboAI client, the component registry, and the current thread context.
9
+ * TamboAI client, the component registry, the current thread context, and interactable components.
9
10
  * @param props - The props for the TamboProvider
10
11
  * @param props.children - The children to wrap
11
12
  * @param props.tamboUrl - The URL of the Tambo API
@@ -17,11 +18,11 @@ import { TamboThreadContextProps, TamboThreadProviderProps } from "./tambo-threa
17
18
  * @returns The TamboProvider component
18
19
  */
19
20
  export declare const TamboProvider: React.FC<PropsWithChildren<TamboClientProviderProps & TamboRegistryProviderProps & TamboThreadProviderProps>>;
20
- export type TamboContextProps = TamboClientContextProps & TamboThreadContextProps & TamboComponentContextProps;
21
+ export type TamboContextProps = TamboClientContextProps & TamboThreadContextProps & TamboComponentContextProps & TamboInteractableContext;
21
22
  export declare const TamboContext: React.Context<TamboContextProps>;
22
23
  /**
23
24
  * TamboCompositeProvider is a provider that combines the TamboClient,
24
- * TamboThread, and TamboComponent providers
25
+ * TamboThread, TamboComponent, and TamboInteractable providers
25
26
  * @param props - The props for the TamboCompositeProvider
26
27
  * @param props.children - The children to wrap
27
28
  * @returns The wrapped component
@@ -31,7 +32,8 @@ export declare const TamboCompositeProvider: React.FC<PropsWithChildren>;
31
32
  * The useTambo hook provides access to the Tambo API. This is the primary entrypoint
32
33
  * for the Tambo React SDK.
33
34
  *
34
- * This includes the TamboAI client, the component registry, and the current thread context.
35
+ * This includes the TamboAI client, the component registry, the current thread context,
36
+ * and interactable component management.
35
37
  * @returns The Tambo API
36
38
  */
37
39
  export declare const useTambo: () => TamboContextProps;
@@ -1 +1 @@
1
- {"version":3,"file":"tambo-provider.d.ts","sourceRoot":"","sources":["../../src/providers/tambo-provider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,iBAAiB,EAA6B,MAAM,OAAO,CAAC;AAC5E,OAAO,EACL,uBAAuB,EAEvB,wBAAwB,EAGzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,0BAA0B,EAG3B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEL,0BAA0B,EAC3B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,uBAAuB,EAEvB,wBAAwB,EAEzB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAClC,iBAAiB,CACf,wBAAwB,GACtB,0BAA0B,GAC1B,wBAAwB,CAC3B,CAgCF,CAAC;AACF,MAAM,MAAM,iBAAiB,GAAG,uBAAuB,GACrD,uBAAuB,GACvB,0BAA0B,CAAC;AAE7B,eAAO,MAAM,YAAY,kCAExB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAoB9D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,yBAEpB,CAAC"}
1
+ {"version":3,"file":"tambo-provider.d.ts","sourceRoot":"","sources":["../../src/providers/tambo-provider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,iBAAiB,EAA6B,MAAM,OAAO,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EACL,uBAAuB,EAEvB,wBAAwB,EAGzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,0BAA0B,EAG3B,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EAEL,0BAA0B,EAC3B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,uBAAuB,EAEvB,wBAAwB,EAEzB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAClC,iBAAiB,CACf,wBAAwB,GACtB,0BAA0B,GAC1B,wBAAwB,CAC3B,CAkCF,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,uBAAuB,GACrD,uBAAuB,GACvB,0BAA0B,GAC1B,wBAAwB,CAAC;AAE3B,eAAO,MAAM,YAAY,kCAExB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAsB9D,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,yBAEpB,CAAC"}
@@ -38,11 +38,12 @@ exports.useTambo = exports.TamboCompositeProvider = exports.TamboContext = expor
38
38
  const react_1 = __importStar(require("react"));
39
39
  const tambo_client_provider_1 = require("./tambo-client-provider");
40
40
  const tambo_component_provider_1 = require("./tambo-component-provider");
41
+ const tambo_interactable_provider_1 = require("./tambo-interactable-provider");
41
42
  const tambo_registry_provider_1 = require("./tambo-registry-provider");
42
43
  const tambo_thread_provider_1 = require("./tambo-thread-provider");
43
44
  /**
44
45
  * The TamboProvider gives full access to the whole Tambo API. This includes the
45
- * TamboAI client, the component registry, and the current thread context.
46
+ * TamboAI client, the component registry, the current thread context, and interactable components.
46
47
  * @param props - The props for the TamboProvider
47
48
  * @param props.children - The children to wrap
48
49
  * @param props.tamboUrl - The URL of the Tambo API
@@ -62,13 +63,14 @@ const TamboProvider = ({ children, tamboUrl, apiKey, userToken, components, envi
62
63
  react_1.default.createElement(tambo_registry_provider_1.TamboRegistryProvider, { components: components, tools: tools },
63
64
  react_1.default.createElement(tambo_thread_provider_1.TamboThreadProvider, { streaming: streaming },
64
65
  react_1.default.createElement(tambo_component_provider_1.TamboComponentProvider, null,
65
- react_1.default.createElement(exports.TamboCompositeProvider, null, children))))));
66
+ react_1.default.createElement(tambo_interactable_provider_1.TamboInteractableProvider, null,
67
+ react_1.default.createElement(exports.TamboCompositeProvider, null, children)))))));
66
68
  };
67
69
  exports.TamboProvider = TamboProvider;
68
70
  exports.TamboContext = (0, react_1.createContext)({});
69
71
  /**
70
72
  * TamboCompositeProvider is a provider that combines the TamboClient,
71
- * TamboThread, and TamboComponent providers
73
+ * TamboThread, TamboComponent, and TamboInteractable providers
72
74
  * @param props - The props for the TamboCompositeProvider
73
75
  * @param props.children - The children to wrap
74
76
  * @returns The wrapped component
@@ -78,11 +80,13 @@ const TamboCompositeProvider = ({ children, }) => {
78
80
  const client = (0, tambo_client_provider_1.useTamboClient)();
79
81
  const queryClient = (0, tambo_client_provider_1.useTamboQueryClient)();
80
82
  const componentRegistry = (0, tambo_component_provider_1.useTamboComponent)();
83
+ const interactableComponents = (0, tambo_interactable_provider_1.useTamboInteractable)();
81
84
  return (react_1.default.createElement(exports.TamboContext.Provider, { value: {
82
85
  client,
83
86
  queryClient,
84
87
  ...componentRegistry,
85
88
  ...threads,
89
+ ...interactableComponents,
86
90
  } }, children));
87
91
  };
88
92
  exports.TamboCompositeProvider = TamboCompositeProvider;
@@ -90,7 +94,8 @@ exports.TamboCompositeProvider = TamboCompositeProvider;
90
94
  * The useTambo hook provides access to the Tambo API. This is the primary entrypoint
91
95
  * for the Tambo React SDK.
92
96
  *
93
- * This includes the TamboAI client, the component registry, and the current thread context.
97
+ * This includes the TamboAI client, the component registry, the current thread context,
98
+ * and interactable component management.
94
99
  * @returns The Tambo API
95
100
  */
96
101
  const useTambo = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"tambo-provider.js","sourceRoot":"","sources":["../../src/providers/tambo-provider.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACb,+CAA4E;AAC5E,mEAMiC;AACjC,yEAIoC;AACpC,uEAGmC;AACnC,mEAKiC;AAEjC;;;;;;;;;;;;GAYG;AACI,MAAM,aAAa,GAMtB,CAAC,EACH,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,SAAS,EACT,UAAU,EACV,WAAW,EACX,KAAK,EACL,SAAS,GACV,EAAE,EAAE;IACH,iCAAiC;IACjC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,CACL,8BAAC,2CAAmB,IAClB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS;QAEpB,8BAAC,+CAAqB,IAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK;YACzD,8BAAC,2CAAmB,IAAC,SAAS,EAAE,SAAS;gBACvC,8BAAC,iDAAsB;oBACrB,8BAAC,8BAAsB,QAAE,QAAQ,CAA0B,CACpC,CACL,CACA,CACJ,CACvB,CAAC;AACJ,CAAC,CAAC;AArCW,QAAA,aAAa,iBAqCxB;AAKW,QAAA,YAAY,GAAG,IAAA,qBAAa,EACvC,EAAuB,CACxB,CAAC;AAEF;;;;;;GAMG;AACI,MAAM,sBAAsB,GAAgC,CAAC,EAClE,QAAQ,GACT,EAAE,EAAE;IACH,MAAM,OAAO,GAAG,IAAA,sCAAc,GAAE,CAAC;IACjC,MAAM,MAAM,GAAG,IAAA,sCAAc,GAAE,CAAC;IAChC,MAAM,WAAW,GAAG,IAAA,2CAAmB,GAAE,CAAC;IAC1C,MAAM,iBAAiB,GAAG,IAAA,4CAAiB,GAAE,CAAC;IAE9C,OAAO,CACL,8BAAC,oBAAY,CAAC,QAAQ,IACpB,KAAK,EAAE;YACL,MAAM;YACN,WAAW;YACX,GAAG,iBAAiB;YACpB,GAAG,OAAO;SACX,IAEA,QAAQ,CACa,CACzB,CAAC;AACJ,CAAC,CAAC;AApBW,QAAA,sBAAsB,0BAoBjC;AAEF;;;;;;GAMG;AACI,MAAM,QAAQ,GAAG,GAAG,EAAE;IAC3B,OAAO,IAAA,kBAAU,EAAC,oBAAY,CAAC,CAAC;AAClC,CAAC,CAAC;AAFW,QAAA,QAAQ,YAEnB","sourcesContent":["\"use client\";\nimport React, { PropsWithChildren, createContext, useContext } from \"react\";\nimport {\n TamboClientContextProps,\n TamboClientProvider,\n TamboClientProviderProps,\n useTamboClient,\n useTamboQueryClient,\n} from \"./tambo-client-provider\";\nimport {\n TamboComponentContextProps,\n TamboComponentProvider,\n useTamboComponent,\n} from \"./tambo-component-provider\";\nimport {\n TamboRegistryProvider,\n TamboRegistryProviderProps,\n} from \"./tambo-registry-provider\";\nimport {\n TamboThreadContextProps,\n TamboThreadProvider,\n TamboThreadProviderProps,\n useTamboThread,\n} from \"./tambo-thread-provider\";\n\n/**\n * The TamboProvider gives full access to the whole Tambo API. This includes the\n * TamboAI client, the component registry, and the current thread context.\n * @param props - The props for the TamboProvider\n * @param props.children - The children to wrap\n * @param props.tamboUrl - The URL of the Tambo API\n * @param props.apiKey - The API key for the Tambo API\n * @param props.components - The components to register\n * @param props.environment - The environment to use for the Tambo API\n * @param props.tools - The tools to register\n * @param props.streaming - Whether to stream the response by default. Defaults to true.\n * @returns The TamboProvider component\n */\nexport const TamboProvider: React.FC<\n PropsWithChildren<\n TamboClientProviderProps &\n TamboRegistryProviderProps &\n TamboThreadProviderProps\n >\n> = ({\n children,\n tamboUrl,\n apiKey,\n userToken,\n components,\n environment,\n tools,\n streaming,\n}) => {\n // Should only be used in browser\n if (typeof window === \"undefined\") {\n console.error(\"TamboProvider must be used within a browser\");\n }\n\n return (\n <TamboClientProvider\n tamboUrl={tamboUrl}\n apiKey={apiKey}\n environment={environment}\n userToken={userToken}\n >\n <TamboRegistryProvider components={components} tools={tools}>\n <TamboThreadProvider streaming={streaming}>\n <TamboComponentProvider>\n <TamboCompositeProvider>{children}</TamboCompositeProvider>\n </TamboComponentProvider>\n </TamboThreadProvider>\n </TamboRegistryProvider>\n </TamboClientProvider>\n );\n};\nexport type TamboContextProps = TamboClientContextProps &\n TamboThreadContextProps &\n TamboComponentContextProps;\n\nexport const TamboContext = createContext<TamboContextProps>(\n {} as TamboContextProps,\n);\n\n/**\n * TamboCompositeProvider is a provider that combines the TamboClient,\n * TamboThread, and TamboComponent providers\n * @param props - The props for the TamboCompositeProvider\n * @param props.children - The children to wrap\n * @returns The wrapped component\n */\nexport const TamboCompositeProvider: React.FC<PropsWithChildren> = ({\n children,\n}) => {\n const threads = useTamboThread();\n const client = useTamboClient();\n const queryClient = useTamboQueryClient();\n const componentRegistry = useTamboComponent();\n\n return (\n <TamboContext.Provider\n value={{\n client,\n queryClient,\n ...componentRegistry,\n ...threads,\n }}\n >\n {children}\n </TamboContext.Provider>\n );\n};\n\n/**\n * The useTambo hook provides access to the Tambo API. This is the primary entrypoint\n * for the Tambo React SDK.\n *\n * This includes the TamboAI client, the component registry, and the current thread context.\n * @returns The Tambo API\n */\nexport const useTambo = () => {\n return useContext(TamboContext);\n};\n"]}
1
+ {"version":3,"file":"tambo-provider.js","sourceRoot":"","sources":["../../src/providers/tambo-provider.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACb,+CAA4E;AAE5E,mEAMiC;AACjC,yEAIoC;AACpC,+EAGuC;AACvC,uEAGmC;AACnC,mEAKiC;AAEjC;;;;;;;;;;;;GAYG;AACI,MAAM,aAAa,GAMtB,CAAC,EACH,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,SAAS,EACT,UAAU,EACV,WAAW,EACX,KAAK,EACL,SAAS,GACV,EAAE,EAAE;IACH,iCAAiC;IACjC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,CACL,8BAAC,2CAAmB,IAClB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS;QAEpB,8BAAC,+CAAqB,IAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK;YACzD,8BAAC,2CAAmB,IAAC,SAAS,EAAE,SAAS;gBACvC,8BAAC,iDAAsB;oBACrB,8BAAC,uDAAyB;wBACxB,8BAAC,8BAAsB,QAAE,QAAQ,CAA0B,CACjC,CACL,CACL,CACA,CACJ,CACvB,CAAC;AACJ,CAAC,CAAC;AAvCW,QAAA,aAAa,iBAuCxB;AAOW,QAAA,YAAY,GAAG,IAAA,qBAAa,EACvC,EAAuB,CACxB,CAAC;AAEF;;;;;;GAMG;AACI,MAAM,sBAAsB,GAAgC,CAAC,EAClE,QAAQ,GACT,EAAE,EAAE;IACH,MAAM,OAAO,GAAG,IAAA,sCAAc,GAAE,CAAC;IACjC,MAAM,MAAM,GAAG,IAAA,sCAAc,GAAE,CAAC;IAChC,MAAM,WAAW,GAAG,IAAA,2CAAmB,GAAE,CAAC;IAC1C,MAAM,iBAAiB,GAAG,IAAA,4CAAiB,GAAE,CAAC;IAC9C,MAAM,sBAAsB,GAAG,IAAA,kDAAoB,GAAE,CAAC;IAEtD,OAAO,CACL,8BAAC,oBAAY,CAAC,QAAQ,IACpB,KAAK,EAAE;YACL,MAAM;YACN,WAAW;YACX,GAAG,iBAAiB;YACpB,GAAG,OAAO;YACV,GAAG,sBAAsB;SAC1B,IAEA,QAAQ,CACa,CACzB,CAAC;AACJ,CAAC,CAAC;AAtBW,QAAA,sBAAsB,0BAsBjC;AAEF;;;;;;;GAOG;AACI,MAAM,QAAQ,GAAG,GAAG,EAAE;IAC3B,OAAO,IAAA,kBAAU,EAAC,oBAAY,CAAC,CAAC;AAClC,CAAC,CAAC;AAFW,QAAA,QAAQ,YAEnB","sourcesContent":["\"use client\";\nimport React, { PropsWithChildren, createContext, useContext } from \"react\";\nimport { TamboInteractableContext } from \"../model/tambo-interactable\";\nimport {\n TamboClientContextProps,\n TamboClientProvider,\n TamboClientProviderProps,\n useTamboClient,\n useTamboQueryClient,\n} from \"./tambo-client-provider\";\nimport {\n TamboComponentContextProps,\n TamboComponentProvider,\n useTamboComponent,\n} from \"./tambo-component-provider\";\nimport {\n TamboInteractableProvider,\n useTamboInteractable,\n} from \"./tambo-interactable-provider\";\nimport {\n TamboRegistryProvider,\n TamboRegistryProviderProps,\n} from \"./tambo-registry-provider\";\nimport {\n TamboThreadContextProps,\n TamboThreadProvider,\n TamboThreadProviderProps,\n useTamboThread,\n} from \"./tambo-thread-provider\";\n\n/**\n * The TamboProvider gives full access to the whole Tambo API. This includes the\n * TamboAI client, the component registry, the current thread context, and interactable components.\n * @param props - The props for the TamboProvider\n * @param props.children - The children to wrap\n * @param props.tamboUrl - The URL of the Tambo API\n * @param props.apiKey - The API key for the Tambo API\n * @param props.components - The components to register\n * @param props.environment - The environment to use for the Tambo API\n * @param props.tools - The tools to register\n * @param props.streaming - Whether to stream the response by default. Defaults to true.\n * @returns The TamboProvider component\n */\nexport const TamboProvider: React.FC<\n PropsWithChildren<\n TamboClientProviderProps &\n TamboRegistryProviderProps &\n TamboThreadProviderProps\n >\n> = ({\n children,\n tamboUrl,\n apiKey,\n userToken,\n components,\n environment,\n tools,\n streaming,\n}) => {\n // Should only be used in browser\n if (typeof window === \"undefined\") {\n console.error(\"TamboProvider must be used within a browser\");\n }\n\n return (\n <TamboClientProvider\n tamboUrl={tamboUrl}\n apiKey={apiKey}\n environment={environment}\n userToken={userToken}\n >\n <TamboRegistryProvider components={components} tools={tools}>\n <TamboThreadProvider streaming={streaming}>\n <TamboComponentProvider>\n <TamboInteractableProvider>\n <TamboCompositeProvider>{children}</TamboCompositeProvider>\n </TamboInteractableProvider>\n </TamboComponentProvider>\n </TamboThreadProvider>\n </TamboRegistryProvider>\n </TamboClientProvider>\n );\n};\n\nexport type TamboContextProps = TamboClientContextProps &\n TamboThreadContextProps &\n TamboComponentContextProps &\n TamboInteractableContext;\n\nexport const TamboContext = createContext<TamboContextProps>(\n {} as TamboContextProps,\n);\n\n/**\n * TamboCompositeProvider is a provider that combines the TamboClient,\n * TamboThread, TamboComponent, and TamboInteractable providers\n * @param props - The props for the TamboCompositeProvider\n * @param props.children - The children to wrap\n * @returns The wrapped component\n */\nexport const TamboCompositeProvider: React.FC<PropsWithChildren> = ({\n children,\n}) => {\n const threads = useTamboThread();\n const client = useTamboClient();\n const queryClient = useTamboQueryClient();\n const componentRegistry = useTamboComponent();\n const interactableComponents = useTamboInteractable();\n\n return (\n <TamboContext.Provider\n value={{\n client,\n queryClient,\n ...componentRegistry,\n ...threads,\n ...interactableComponents,\n }}\n >\n {children}\n </TamboContext.Provider>\n );\n};\n\n/**\n * The useTambo hook provides access to the Tambo API. This is the primary entrypoint\n * for the Tambo React SDK.\n *\n * This includes the TamboAI client, the component registry, the current thread context,\n * and interactable component management.\n * @returns The Tambo API\n */\nexport const useTambo = () => {\n return useContext(TamboContext);\n};\n"]}
package/esm/index.d.ts CHANGED
@@ -2,8 +2,8 @@
2
2
  export { useTamboComponentState } from "./hooks/use-component-state";
3
3
  export { TamboMessageProvider, useTamboCurrentMessage, useTamboMessageContext, } from "./hooks/use-current-message";
4
4
  export { useTamboStreamingProps } from "./hooks/use-streaming-props";
5
- export { useTamboStreamStatus, type StreamStatus, type PropStatus, } from "./hooks/use-tambo-stream-status";
6
5
  export * from "./hooks/use-suggestions";
6
+ export { useTamboStreamStatus, type PropStatus, type StreamStatus, } from "./hooks/use-tambo-stream-status";
7
7
  export { useTamboThreadInput } from "./hooks/use-thread-input";
8
8
  export { TamboClientProvider, TamboComponentProvider, TamboProvider, TamboStubProvider, TamboThreadProvider, useTambo, useTamboClient, useTamboThread, type TamboComponent, type TamboRegistryContext, type TamboStubProviderProps, } from "./providers";
9
9
  export type { APIError, RateLimitError, TamboAIError, } from "@tambo-ai/typescript-sdk";
@@ -12,4 +12,7 @@ export { useTamboThreadList } from "./hooks/use-tambo-threads";
12
12
  export { type ComponentContextToolMetadata, type ComponentRegistry, type ParameterSpec, type RegisteredComponent, type TamboTool, } from "./model/component-metadata";
13
13
  export { GenerationStage, type TamboThreadMessage, } from "./model/generate-component-response";
14
14
  export { type TamboThread } from "./model/tambo-thread";
15
+ export type { TamboInteractableComponent as InteractableComponent, TamboInteractableContext, } from "./model/tambo-interactable";
16
+ export { withTamboInteractable as withInteractable, type InteractableConfig, type WithTamboInteractableProps, } from "./providers/hoc/with-tambo-interactable";
17
+ export { useTamboInteractable } from "./providers/tambo-interactable-provider";
15
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wKAAwK;AACxK,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,oBAAoB,EACpB,KAAK,YAAY,EACjB,KAAK,UAAU,GAChB,MAAM,iCAAiC,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAG/D,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,QAAQ,EACR,cAAc,EACd,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC5B,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,QAAQ,EACR,cAAc,EACd,YAAY,GACb,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,UAAU,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,6DAA6D,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,SAAS,GACf,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,eAAe,EACf,KAAK,kBAAkB,GACxB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wKAAwK;AACxK,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,cAAc,yBAAyB,CAAC;AACxC,OAAO,EACL,oBAAoB,EACpB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAG/D,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,QAAQ,EACR,cAAc,EACd,cAAc,EACd,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC5B,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,QAAQ,EACR,cAAc,EACd,YAAY,GACb,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,UAAU,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,6DAA6D,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,SAAS,GACf,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,eAAe,EACf,KAAK,kBAAkB,GACxB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,YAAY,EACV,0BAA0B,IAAI,qBAAqB,EACnD,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,qBAAqB,IAAI,gBAAgB,EACzC,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,GAChC,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC"}
package/esm/index.js CHANGED
@@ -2,11 +2,13 @@
2
2
  export { useTamboComponentState } from "./hooks/use-component-state";
3
3
  export { TamboMessageProvider, useTamboCurrentMessage, useTamboMessageContext, } from "./hooks/use-current-message";
4
4
  export { useTamboStreamingProps } from "./hooks/use-streaming-props";
5
- export { useTamboStreamStatus, } from "./hooks/use-tambo-stream-status";
6
5
  export * from "./hooks/use-suggestions";
6
+ export { useTamboStreamStatus, } from "./hooks/use-tambo-stream-status";
7
7
  export { useTamboThreadInput } from "./hooks/use-thread-input";
8
8
  // Re-export provider components
9
9
  export { TamboClientProvider, TamboComponentProvider, TamboProvider, TamboStubProvider, TamboThreadProvider, useTambo, useTamboClient, useTamboThread, } from "./providers";
10
10
  export { useTamboThreadList } from "./hooks/use-tambo-threads";
11
11
  export { GenerationStage, } from "./model/generate-component-response";
12
+ export { withTamboInteractable as withInteractable, } from "./providers/hoc/with-tambo-interactable";
13
+ export { useTamboInteractable } from "./providers/tambo-interactable-provider";
12
14
  //# sourceMappingURL=index.js.map
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wKAAwK;AACxK,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,oBAAoB,GAGrB,MAAM,iCAAiC,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,gCAAgC;AAChC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,QAAQ,EACR,cAAc,EACd,cAAc,GAIf,MAAM,aAAa,CAAC;AAcrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAQ/D,OAAO,EACL,eAAe,GAEhB,MAAM,qCAAqC,CAAC","sourcesContent":["/** Exports for the library. Only publically available exports are re-exported here. Anything not exported here is not supported and may change or break at any time. */\nexport { useTamboComponentState } from \"./hooks/use-component-state\";\nexport {\n TamboMessageProvider,\n useTamboCurrentMessage,\n useTamboMessageContext,\n} from \"./hooks/use-current-message\";\nexport { useTamboStreamingProps } from \"./hooks/use-streaming-props\";\nexport {\n useTamboStreamStatus,\n type StreamStatus,\n type PropStatus,\n} from \"./hooks/use-tambo-stream-status\";\nexport * from \"./hooks/use-suggestions\";\nexport { useTamboThreadInput } from \"./hooks/use-thread-input\";\n\n// Re-export provider components\nexport {\n TamboClientProvider,\n TamboComponentProvider,\n TamboProvider,\n TamboStubProvider,\n TamboThreadProvider,\n useTambo,\n useTamboClient,\n useTamboThread,\n type TamboComponent,\n type TamboRegistryContext,\n type TamboStubProviderProps,\n} from \"./providers\";\n\n// Re-export types from Tambo Node SDK\nexport type {\n APIError,\n RateLimitError,\n TamboAIError,\n} from \"@tambo-ai/typescript-sdk\";\nexport type {\n Suggestion,\n SuggestionGenerateParams,\n SuggestionGenerateResponse,\n SuggestionListResponse,\n} from \"@tambo-ai/typescript-sdk/resources/beta/threads/suggestions\";\nexport { useTamboThreadList } from \"./hooks/use-tambo-threads\";\nexport {\n type ComponentContextToolMetadata,\n type ComponentRegistry,\n type ParameterSpec,\n type RegisteredComponent,\n type TamboTool,\n} from \"./model/component-metadata\";\nexport {\n GenerationStage,\n type TamboThreadMessage,\n} from \"./model/generate-component-response\";\nexport { type TamboThread } from \"./model/tambo-thread\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wKAAwK;AACxK,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,cAAc,yBAAyB,CAAC;AACxC,OAAO,EACL,oBAAoB,GAGrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,gCAAgC;AAChC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,QAAQ,EACR,cAAc,EACd,cAAc,GAIf,MAAM,aAAa,CAAC;AAcrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAQ/D,OAAO,EACL,eAAe,GAEhB,MAAM,qCAAqC,CAAC;AAO7C,OAAO,EACL,qBAAqB,IAAI,gBAAgB,GAG1C,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC","sourcesContent":["/** Exports for the library. Only publically available exports are re-exported here. Anything not exported here is not supported and may change or break at any time. */\nexport { useTamboComponentState } from \"./hooks/use-component-state\";\nexport {\n TamboMessageProvider,\n useTamboCurrentMessage,\n useTamboMessageContext,\n} from \"./hooks/use-current-message\";\nexport { useTamboStreamingProps } from \"./hooks/use-streaming-props\";\nexport * from \"./hooks/use-suggestions\";\nexport {\n useTamboStreamStatus,\n type PropStatus,\n type StreamStatus,\n} from \"./hooks/use-tambo-stream-status\";\nexport { useTamboThreadInput } from \"./hooks/use-thread-input\";\n\n// Re-export provider components\nexport {\n TamboClientProvider,\n TamboComponentProvider,\n TamboProvider,\n TamboStubProvider,\n TamboThreadProvider,\n useTambo,\n useTamboClient,\n useTamboThread,\n type TamboComponent,\n type TamboRegistryContext,\n type TamboStubProviderProps,\n} from \"./providers\";\n\n// Re-export types from Tambo Node SDK\nexport type {\n APIError,\n RateLimitError,\n TamboAIError,\n} from \"@tambo-ai/typescript-sdk\";\nexport type {\n Suggestion,\n SuggestionGenerateParams,\n SuggestionGenerateResponse,\n SuggestionListResponse,\n} from \"@tambo-ai/typescript-sdk/resources/beta/threads/suggestions\";\nexport { useTamboThreadList } from \"./hooks/use-tambo-threads\";\nexport {\n type ComponentContextToolMetadata,\n type ComponentRegistry,\n type ParameterSpec,\n type RegisteredComponent,\n type TamboTool,\n} from \"./model/component-metadata\";\nexport {\n GenerationStage,\n type TamboThreadMessage,\n} from \"./model/generate-component-response\";\nexport { type TamboThread } from \"./model/tambo-thread\";\n\nexport type {\n TamboInteractableComponent as InteractableComponent,\n TamboInteractableContext,\n} from \"./model/tambo-interactable\";\nexport {\n withTamboInteractable as withInteractable,\n type InteractableConfig,\n type WithTamboInteractableProps,\n} from \"./providers/hoc/with-tambo-interactable\";\nexport { useTamboInteractable } from \"./providers/tambo-interactable-provider\";\n"]}
@@ -0,0 +1,24 @@
1
+ import { TamboComponent } from "./component-metadata";
2
+ export interface TamboInteractableComponent extends TamboComponent {
3
+ /** Unique identifier for this component instance */
4
+ id: string;
5
+ /** Current props for the component */
6
+ props: Record<string, any>;
7
+ }
8
+ export interface TamboInteractableContext {
9
+ /** List of all interactable components */
10
+ interactableComponents: TamboInteractableComponent[];
11
+ /** Add a new interactable component */
12
+ addInteractableComponent: (component: Omit<TamboInteractableComponent, "id" | "createdAt">) => string;
13
+ /** Remove an interactable component by ID */
14
+ removeInteractableComponent: (id: string) => void;
15
+ /** Update an interactable component's props */
16
+ updateInteractableComponentProps: (id: string, newProps: Record<string, any>) => void;
17
+ /** Get an interactable component by ID */
18
+ getInteractableComponent: (id: string) => TamboInteractableComponent | undefined;
19
+ /** Get all interactable components by component name */
20
+ getInteractableComponentsByName: (componentName: string) => TamboInteractableComponent[];
21
+ /** Clear all interactable components */
22
+ clearAllInteractableComponents: () => void;
23
+ }
24
+ //# sourceMappingURL=tambo-interactable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tambo-interactable.d.ts","sourceRoot":"","sources":["../../src/model/tambo-interactable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,WAAW,0BAA2B,SAAQ,cAAc;IAChE,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,0CAA0C;IAC1C,sBAAsB,EAAE,0BAA0B,EAAE,CAAC;IACrD,uCAAuC;IACvC,wBAAwB,EAAE,CACxB,SAAS,EAAE,IAAI,CAAC,0BAA0B,EAAE,IAAI,GAAG,WAAW,CAAC,KAC5D,MAAM,CAAC;IACZ,6CAA6C;IAC7C,2BAA2B,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,+CAA+C;IAC/C,gCAAgC,EAAE,CAChC,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAC1B,IAAI,CAAC;IACV,0CAA0C;IAC1C,wBAAwB,EAAE,CACxB,EAAE,EAAE,MAAM,KACP,0BAA0B,GAAG,SAAS,CAAC;IAC5C,wDAAwD;IACxD,+BAA+B,EAAE,CAC/B,aAAa,EAAE,MAAM,KAClB,0BAA0B,EAAE,CAAC;IAClC,wCAAwC;IACxC,8BAA8B,EAAE,MAAM,IAAI,CAAC;CAC5C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tambo-interactable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tambo-interactable.js","sourceRoot":"","sources":["../../src/model/tambo-interactable.ts"],"names":[],"mappings":"","sourcesContent":["import { TamboComponent } from \"./component-metadata\";\n\nexport interface TamboInteractableComponent extends TamboComponent {\n /** Unique identifier for this component instance */\n id: string;\n /** Current props for the component */\n props: Record<string, any>;\n}\n\nexport interface TamboInteractableContext {\n /** List of all interactable components */\n interactableComponents: TamboInteractableComponent[];\n /** Add a new interactable component */\n addInteractableComponent: (\n component: Omit<TamboInteractableComponent, \"id\" | \"createdAt\">,\n ) => string;\n /** Remove an interactable component by ID */\n removeInteractableComponent: (id: string) => void;\n /** Update an interactable component's props */\n updateInteractableComponentProps: (\n id: string,\n newProps: Record<string, any>,\n ) => void;\n /** Get an interactable component by ID */\n getInteractableComponent: (\n id: string,\n ) => TamboInteractableComponent | undefined;\n /** Get all interactable components by component name */\n getInteractableComponentsByName: (\n componentName: string,\n ) => TamboInteractableComponent[];\n /** Clear all interactable components */\n clearAllInteractableComponents: () => void;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tambo-prop-stream-provider.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tambo-prop-stream-provider.test.d.ts","sourceRoot":"","sources":["../../../src/providers/__tests__/tambo-prop-stream-provider.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,273 @@
1
+ import { render, screen } from "@testing-library/react";
2
+ import React from "react";
3
+ import { TamboPropStreamProvider, useTamboStream, } from "../tambo-prop-stream-provider";
4
+ // Helper component to test hook usage
5
+ const TestHookComponent = ({ testKey = "default", }) => {
6
+ const { data, streamStatus, getStatusForKey } = useTamboStream();
7
+ const status = getStatusForKey(testKey);
8
+ return (React.createElement("div", null,
9
+ React.createElement("div", { "data-testid": "data" }, JSON.stringify(data)),
10
+ React.createElement("div", { "data-testid": "stream-status" }, JSON.stringify(streamStatus)),
11
+ React.createElement("div", { "data-testid": "key-status" }, JSON.stringify(status))));
12
+ };
13
+ describe("TamboPropStreamProvider", () => {
14
+ describe("Hook Error Handling", () => {
15
+ it("should throw error when useTamboStream is used outside provider", () => {
16
+ // Suppress console.error for this test
17
+ const originalError = console.error;
18
+ console.error = jest.fn();
19
+ expect(() => {
20
+ render(React.createElement(TestHookComponent, null));
21
+ }).toThrow("useTamboStream must be used within a TamboPropStreamProvider");
22
+ console.error = originalError;
23
+ });
24
+ });
25
+ describe("Basic Functionality", () => {
26
+ it("should provide data and stream status through context", () => {
27
+ const testData = { message: "Hello World" };
28
+ const testStreamStatus = {
29
+ isPending: false,
30
+ isStreaming: false,
31
+ isSuccess: true,
32
+ isError: false,
33
+ streamError: undefined,
34
+ };
35
+ render(React.createElement(TamboPropStreamProvider, { data: testData, streamStatus: testStreamStatus },
36
+ React.createElement(TestHookComponent, null)));
37
+ expect(screen.getByTestId("data")).toHaveTextContent(JSON.stringify(testData));
38
+ expect(screen.getByTestId("stream-status")).toHaveTextContent(JSON.stringify(testStreamStatus));
39
+ });
40
+ it("should use default stream status when none provided", () => {
41
+ const testData = { message: "Hello World" };
42
+ const expectedDefaultStatus = {
43
+ isPending: false,
44
+ isStreaming: false,
45
+ isSuccess: true,
46
+ isError: false,
47
+ streamError: undefined,
48
+ };
49
+ render(React.createElement(TamboPropStreamProvider, { data: testData },
50
+ React.createElement(TestHookComponent, null)));
51
+ expect(screen.getByTestId("stream-status")).toHaveTextContent(JSON.stringify(expectedDefaultStatus));
52
+ });
53
+ });
54
+ describe("Compound Components", () => {
55
+ describe("Loading Component", () => {
56
+ it("should render loading when isPending is true", () => {
57
+ const streamStatus = {
58
+ isPending: true,
59
+ isStreaming: false,
60
+ isSuccess: false,
61
+ isError: false,
62
+ };
63
+ render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
64
+ React.createElement(TamboPropStreamProvider.Loading, null,
65
+ React.createElement("div", { "data-testid": "loading" }, "Loading..."))));
66
+ expect(screen.getByTestId("loading")).toBeInTheDocument();
67
+ });
68
+ it("should render loading when isStreaming is true", () => {
69
+ const streamStatus = {
70
+ isPending: false,
71
+ isStreaming: true,
72
+ isSuccess: false,
73
+ isError: false,
74
+ };
75
+ render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
76
+ React.createElement(TamboPropStreamProvider.Loading, null,
77
+ React.createElement("div", { "data-testid": "loading" }, "Loading..."))));
78
+ expect(screen.getByTestId("loading")).toBeInTheDocument();
79
+ });
80
+ it("should not render loading when not pending or streaming", () => {
81
+ const streamStatus = {
82
+ isPending: false,
83
+ isStreaming: false,
84
+ isSuccess: true,
85
+ isError: false,
86
+ };
87
+ render(React.createElement(TamboPropStreamProvider, { data: "test", streamStatus: streamStatus },
88
+ React.createElement(TamboPropStreamProvider.Loading, null,
89
+ React.createElement("div", { "data-testid": "loading" }, "Loading..."))));
90
+ expect(screen.queryByTestId("loading")).not.toBeInTheDocument();
91
+ });
92
+ });
93
+ describe("Complete Component", () => {
94
+ it("should render complete when isSuccess is true and data exists", () => {
95
+ const streamStatus = {
96
+ isPending: false,
97
+ isStreaming: false,
98
+ isSuccess: true,
99
+ isError: false,
100
+ };
101
+ render(React.createElement(TamboPropStreamProvider, { data: "test data", streamStatus: streamStatus },
102
+ React.createElement(TamboPropStreamProvider.Complete, null,
103
+ React.createElement("div", { "data-testid": "complete" }, "Complete!"))));
104
+ expect(screen.getByTestId("complete")).toBeInTheDocument();
105
+ });
106
+ it("should not render complete when data is null", () => {
107
+ const streamStatus = {
108
+ isPending: false,
109
+ isStreaming: false,
110
+ isSuccess: true,
111
+ isError: false,
112
+ };
113
+ render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
114
+ React.createElement(TamboPropStreamProvider.Complete, null,
115
+ React.createElement("div", { "data-testid": "complete" }, "Complete!"))));
116
+ expect(screen.queryByTestId("complete")).not.toBeInTheDocument();
117
+ });
118
+ it("should not render complete when data is undefined", () => {
119
+ const streamStatus = {
120
+ isPending: false,
121
+ isStreaming: false,
122
+ isSuccess: true,
123
+ isError: false,
124
+ };
125
+ render(React.createElement(TamboPropStreamProvider, { data: undefined, streamStatus: streamStatus },
126
+ React.createElement(TamboPropStreamProvider.Complete, null,
127
+ React.createElement("div", { "data-testid": "complete" }, "Complete!"))));
128
+ expect(screen.queryByTestId("complete")).not.toBeInTheDocument();
129
+ });
130
+ });
131
+ describe("Empty Component", () => {
132
+ it("should render empty when no data and not loading/streaming/success/error", () => {
133
+ const streamStatus = {
134
+ isPending: false,
135
+ isStreaming: false,
136
+ isSuccess: false,
137
+ isError: false,
138
+ };
139
+ render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
140
+ React.createElement(TamboPropStreamProvider.Empty, null,
141
+ React.createElement("div", { "data-testid": "empty" }, "No data"))));
142
+ expect(screen.getByTestId("empty")).toBeInTheDocument();
143
+ });
144
+ it("should render empty when data is empty string", () => {
145
+ const streamStatus = {
146
+ isPending: false,
147
+ isStreaming: false,
148
+ isSuccess: false,
149
+ isError: false,
150
+ };
151
+ render(React.createElement(TamboPropStreamProvider, { data: "", streamStatus: streamStatus },
152
+ React.createElement(TamboPropStreamProvider.Empty, null,
153
+ React.createElement("div", { "data-testid": "empty" }, "No data"))));
154
+ expect(screen.getByTestId("empty")).toBeInTheDocument();
155
+ });
156
+ it("should not render empty when loading", () => {
157
+ const streamStatus = {
158
+ isPending: true,
159
+ isStreaming: false,
160
+ isSuccess: false,
161
+ isError: false,
162
+ };
163
+ render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
164
+ React.createElement(TamboPropStreamProvider.Empty, null,
165
+ React.createElement("div", { "data-testid": "empty" }, "No data"))));
166
+ expect(screen.queryByTestId("empty")).not.toBeInTheDocument();
167
+ });
168
+ it("should not render empty when successful", () => {
169
+ const streamStatus = {
170
+ isPending: false,
171
+ isStreaming: false,
172
+ isSuccess: true,
173
+ isError: false,
174
+ };
175
+ render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
176
+ React.createElement(TamboPropStreamProvider.Empty, null,
177
+ React.createElement("div", { "data-testid": "empty" }, "No data"))));
178
+ expect(screen.queryByTestId("empty")).not.toBeInTheDocument();
179
+ });
180
+ });
181
+ });
182
+ describe("Per-Key Status Tracking", () => {
183
+ it("should track status for object keys", () => {
184
+ const testData = { name: "John", age: null };
185
+ const streamStatus = {
186
+ isPending: false,
187
+ isStreaming: false,
188
+ isSuccess: true,
189
+ isError: false,
190
+ };
191
+ render(React.createElement(TamboPropStreamProvider, { data: testData, streamStatus: streamStatus },
192
+ React.createElement(TestHookComponent, { testKey: "name" })));
193
+ const keyStatus = JSON.parse(screen.getByTestId("key-status").textContent ?? "{}");
194
+ expect(keyStatus.isSuccess).toBe(true); // name has data
195
+ });
196
+ it("should show loading for keys without data", () => {
197
+ const testData = { name: "John", age: null };
198
+ const streamStatus = {
199
+ isPending: false,
200
+ isStreaming: false,
201
+ isSuccess: true,
202
+ isError: false,
203
+ };
204
+ render(React.createElement(TamboPropStreamProvider, { data: testData, streamStatus: streamStatus },
205
+ React.createElement(TestHookComponent, { testKey: "age" })));
206
+ const keyStatus = JSON.parse(screen.getByTestId("key-status").textContent ?? "{}");
207
+ expect(keyStatus.isPending).toBe(true); // age has no data
208
+ });
209
+ it("should handle per-key loading states", () => {
210
+ render(React.createElement(TamboPropStreamProvider, { data: { name: "John", age: null } },
211
+ React.createElement(TamboPropStreamProvider.Loading, { streamKey: "name" },
212
+ React.createElement("div", { "data-testid": "name-loading" }, "Name loading...")),
213
+ React.createElement(TamboPropStreamProvider.Loading, { streamKey: "age" },
214
+ React.createElement("div", { "data-testid": "age-loading" }, "Age loading...")),
215
+ React.createElement(TamboPropStreamProvider.Complete, { streamKey: "name" },
216
+ React.createElement("div", { "data-testid": "name-complete" }, "Name: John"))));
217
+ // Name should be complete (has data)
218
+ expect(screen.getByTestId("name-complete")).toBeInTheDocument();
219
+ expect(screen.queryByTestId("name-loading")).not.toBeInTheDocument();
220
+ // Age should be loading (no data)
221
+ expect(screen.getByTestId("age-loading")).toBeInTheDocument();
222
+ });
223
+ });
224
+ describe("Edge Cases", () => {
225
+ it("should handle null data gracefully", () => {
226
+ render(React.createElement(TamboPropStreamProvider, { data: null },
227
+ React.createElement(TestHookComponent, null)));
228
+ expect(screen.getByTestId("data")).toHaveTextContent("null");
229
+ });
230
+ it("should handle undefined data gracefully", () => {
231
+ render(React.createElement(TamboPropStreamProvider, { data: undefined },
232
+ React.createElement(TestHookComponent, null)));
233
+ expect(screen.getByTestId("data")).toHaveTextContent("");
234
+ });
235
+ it("should handle array data", () => {
236
+ const arrayData = ["item1", "item2"];
237
+ render(React.createElement(TamboPropStreamProvider, { data: arrayData },
238
+ React.createElement(TestHookComponent, null)));
239
+ expect(screen.getByTestId("data")).toHaveTextContent(JSON.stringify(arrayData));
240
+ });
241
+ it("should handle primitive data types", () => {
242
+ render(React.createElement(TamboPropStreamProvider, { data: "string data" },
243
+ React.createElement(TestHookComponent, null)));
244
+ expect(screen.getByTestId("data")).toHaveTextContent('"string data"');
245
+ });
246
+ it("should fallback to default status for unknown keys", () => {
247
+ const testData = { name: "John" };
248
+ render(React.createElement(TamboPropStreamProvider, { data: testData },
249
+ React.createElement(TestHookComponent, { testKey: "unknown-key" })));
250
+ const keyStatus = JSON.parse(screen.getByTestId("key-status").textContent ?? "{}");
251
+ // Should fallback to default status
252
+ expect(keyStatus.isSuccess).toBe(true);
253
+ });
254
+ });
255
+ describe("Component Attributes", () => {
256
+ it("should add correct data attributes to components", () => {
257
+ const streamStatus = {
258
+ isPending: true,
259
+ isStreaming: false,
260
+ isSuccess: false,
261
+ isError: false,
262
+ };
263
+ render(React.createElement(TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
264
+ React.createElement(TamboPropStreamProvider.Loading, { className: "loading-class" },
265
+ React.createElement("div", null, "Loading..."))));
266
+ const loadingElement = screen.getByText("Loading...").parentElement;
267
+ expect(loadingElement).toHaveAttribute("data-stream-key", "default");
268
+ expect(loadingElement).toHaveAttribute("data-stream-state", "loading");
269
+ expect(loadingElement).toHaveClass("loading-class");
270
+ });
271
+ });
272
+ });
273
+ //# sourceMappingURL=tambo-prop-stream-provider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tambo-prop-stream-provider.test.js","sourceRoot":"","sources":["../../../src/providers/__tests__/tambo-prop-stream-provider.test.tsx"],"names":[],"mappings":"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","sourcesContent":["import { render, screen } from \"@testing-library/react\";\nimport React from \"react\";\nimport { StreamStatus } from \"../../hooks/use-tambo-stream-status\";\nimport {\n TamboPropStreamProvider,\n useTamboStream,\n} from \"../tambo-prop-stream-provider\";\n\n// Helper component to test hook usage\nconst TestHookComponent: React.FC<{ testKey?: string }> = ({\n testKey = \"default\",\n}) => {\n const { data, streamStatus, getStatusForKey } = useTamboStream();\n const status = getStatusForKey(testKey);\n\n return (\n <div>\n <div data-testid=\"data\">{JSON.stringify(data)}</div>\n <div data-testid=\"stream-status\">{JSON.stringify(streamStatus)}</div>\n <div data-testid=\"key-status\">{JSON.stringify(status)}</div>\n </div>\n );\n};\n\ndescribe(\"TamboPropStreamProvider\", () => {\n describe(\"Hook Error Handling\", () => {\n it(\"should throw error when useTamboStream is used outside provider\", () => {\n // Suppress console.error for this test\n const originalError = console.error;\n console.error = jest.fn();\n\n expect(() => {\n render(<TestHookComponent />);\n }).toThrow(\n \"useTamboStream must be used within a TamboPropStreamProvider\",\n );\n\n console.error = originalError;\n });\n });\n\n describe(\"Basic Functionality\", () => {\n it(\"should provide data and stream status through context\", () => {\n const testData = { message: \"Hello World\" };\n const testStreamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n streamError: undefined,\n };\n\n render(\n <TamboPropStreamProvider\n data={testData}\n streamStatus={testStreamStatus}\n >\n <TestHookComponent />\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"data\")).toHaveTextContent(\n JSON.stringify(testData),\n );\n expect(screen.getByTestId(\"stream-status\")).toHaveTextContent(\n JSON.stringify(testStreamStatus),\n );\n });\n\n it(\"should use default stream status when none provided\", () => {\n const testData = { message: \"Hello World\" };\n const expectedDefaultStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n streamError: undefined,\n };\n\n render(\n <TamboPropStreamProvider data={testData}>\n <TestHookComponent />\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"stream-status\")).toHaveTextContent(\n JSON.stringify(expectedDefaultStatus),\n );\n });\n });\n\n describe(\"Compound Components\", () => {\n describe(\"Loading Component\", () => {\n it(\"should render loading when isPending is true\", () => {\n const streamStatus: StreamStatus = {\n isPending: true,\n isStreaming: false,\n isSuccess: false,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Loading>\n <div data-testid=\"loading\">Loading...</div>\n </TamboPropStreamProvider.Loading>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"loading\")).toBeInTheDocument();\n });\n\n it(\"should render loading when isStreaming is true\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: true,\n isSuccess: false,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Loading>\n <div data-testid=\"loading\">Loading...</div>\n </TamboPropStreamProvider.Loading>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"loading\")).toBeInTheDocument();\n });\n\n it(\"should not render loading when not pending or streaming\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data=\"test\" streamStatus={streamStatus}>\n <TamboPropStreamProvider.Loading>\n <div data-testid=\"loading\">Loading...</div>\n </TamboPropStreamProvider.Loading>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.queryByTestId(\"loading\")).not.toBeInTheDocument();\n });\n });\n\n describe(\"Complete Component\", () => {\n it(\"should render complete when isSuccess is true and data exists\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data=\"test data\" streamStatus={streamStatus}>\n <TamboPropStreamProvider.Complete>\n <div data-testid=\"complete\">Complete!</div>\n </TamboPropStreamProvider.Complete>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"complete\")).toBeInTheDocument();\n });\n\n it(\"should not render complete when data is null\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Complete>\n <div data-testid=\"complete\">Complete!</div>\n </TamboPropStreamProvider.Complete>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.queryByTestId(\"complete\")).not.toBeInTheDocument();\n });\n\n it(\"should not render complete when data is undefined\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={undefined} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Complete>\n <div data-testid=\"complete\">Complete!</div>\n </TamboPropStreamProvider.Complete>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.queryByTestId(\"complete\")).not.toBeInTheDocument();\n });\n });\n\n describe(\"Empty Component\", () => {\n it(\"should render empty when no data and not loading/streaming/success/error\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: false,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Empty>\n <div data-testid=\"empty\">No data</div>\n </TamboPropStreamProvider.Empty>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"empty\")).toBeInTheDocument();\n });\n\n it(\"should render empty when data is empty string\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: false,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data=\"\" streamStatus={streamStatus}>\n <TamboPropStreamProvider.Empty>\n <div data-testid=\"empty\">No data</div>\n </TamboPropStreamProvider.Empty>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"empty\")).toBeInTheDocument();\n });\n\n it(\"should not render empty when loading\", () => {\n const streamStatus: StreamStatus = {\n isPending: true,\n isStreaming: false,\n isSuccess: false,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Empty>\n <div data-testid=\"empty\">No data</div>\n </TamboPropStreamProvider.Empty>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.queryByTestId(\"empty\")).not.toBeInTheDocument();\n });\n\n it(\"should not render empty when successful\", () => {\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Empty>\n <div data-testid=\"empty\">No data</div>\n </TamboPropStreamProvider.Empty>\n </TamboPropStreamProvider>,\n );\n\n expect(screen.queryByTestId(\"empty\")).not.toBeInTheDocument();\n });\n });\n });\n\n describe(\"Per-Key Status Tracking\", () => {\n it(\"should track status for object keys\", () => {\n const testData = { name: \"John\", age: null };\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={testData} streamStatus={streamStatus}>\n <TestHookComponent testKey=\"name\" />\n </TamboPropStreamProvider>,\n );\n\n const keyStatus = JSON.parse(\n screen.getByTestId(\"key-status\").textContent ?? \"{}\",\n );\n expect(keyStatus.isSuccess).toBe(true); // name has data\n });\n\n it(\"should show loading for keys without data\", () => {\n const testData = { name: \"John\", age: null };\n const streamStatus: StreamStatus = {\n isPending: false,\n isStreaming: false,\n isSuccess: true,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={testData} streamStatus={streamStatus}>\n <TestHookComponent testKey=\"age\" />\n </TamboPropStreamProvider>,\n );\n\n const keyStatus = JSON.parse(\n screen.getByTestId(\"key-status\").textContent ?? \"{}\",\n );\n expect(keyStatus.isPending).toBe(true); // age has no data\n });\n\n it(\"should handle per-key loading states\", () => {\n render(\n <TamboPropStreamProvider data={{ name: \"John\", age: null }}>\n <TamboPropStreamProvider.Loading streamKey=\"name\">\n <div data-testid=\"name-loading\">Name loading...</div>\n </TamboPropStreamProvider.Loading>\n <TamboPropStreamProvider.Loading streamKey=\"age\">\n <div data-testid=\"age-loading\">Age loading...</div>\n </TamboPropStreamProvider.Loading>\n <TamboPropStreamProvider.Complete streamKey=\"name\">\n <div data-testid=\"name-complete\">Name: John</div>\n </TamboPropStreamProvider.Complete>\n </TamboPropStreamProvider>,\n );\n\n // Name should be complete (has data)\n expect(screen.getByTestId(\"name-complete\")).toBeInTheDocument();\n expect(screen.queryByTestId(\"name-loading\")).not.toBeInTheDocument();\n\n // Age should be loading (no data)\n expect(screen.getByTestId(\"age-loading\")).toBeInTheDocument();\n });\n });\n\n describe(\"Edge Cases\", () => {\n it(\"should handle null data gracefully\", () => {\n render(\n <TamboPropStreamProvider data={null}>\n <TestHookComponent />\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"data\")).toHaveTextContent(\"null\");\n });\n\n it(\"should handle undefined data gracefully\", () => {\n render(\n <TamboPropStreamProvider data={undefined}>\n <TestHookComponent />\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"data\")).toHaveTextContent(\"\");\n });\n\n it(\"should handle array data\", () => {\n const arrayData = [\"item1\", \"item2\"];\n render(\n <TamboPropStreamProvider data={arrayData}>\n <TestHookComponent />\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"data\")).toHaveTextContent(\n JSON.stringify(arrayData),\n );\n });\n\n it(\"should handle primitive data types\", () => {\n render(\n <TamboPropStreamProvider data=\"string data\">\n <TestHookComponent />\n </TamboPropStreamProvider>,\n );\n\n expect(screen.getByTestId(\"data\")).toHaveTextContent('\"string data\"');\n });\n\n it(\"should fallback to default status for unknown keys\", () => {\n const testData = { name: \"John\" };\n\n render(\n <TamboPropStreamProvider data={testData}>\n <TestHookComponent testKey=\"unknown-key\" />\n </TamboPropStreamProvider>,\n );\n\n const keyStatus = JSON.parse(\n screen.getByTestId(\"key-status\").textContent ?? \"{}\",\n );\n // Should fallback to default status\n expect(keyStatus.isSuccess).toBe(true);\n });\n });\n\n describe(\"Component Attributes\", () => {\n it(\"should add correct data attributes to components\", () => {\n const streamStatus: StreamStatus = {\n isPending: true,\n isStreaming: false,\n isSuccess: false,\n isError: false,\n };\n\n render(\n <TamboPropStreamProvider data={null} streamStatus={streamStatus}>\n <TamboPropStreamProvider.Loading className=\"loading-class\">\n <div>Loading...</div>\n </TamboPropStreamProvider.Loading>\n </TamboPropStreamProvider>,\n );\n\n const loadingElement = screen.getByText(\"Loading...\").parentElement;\n expect(loadingElement).toHaveAttribute(\"data-stream-key\", \"default\");\n expect(loadingElement).toHaveAttribute(\"data-stream-state\", \"loading\");\n expect(loadingElement).toHaveClass(\"loading-class\");\n });\n });\n});\n"]}