@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.
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/model/tambo-interactable.d.ts +24 -0
- package/dist/model/tambo-interactable.d.ts.map +1 -0
- package/dist/model/tambo-interactable.js +3 -0
- package/dist/model/tambo-interactable.js.map +1 -0
- package/dist/providers/__tests__/tambo-prop-stream-provider.test.d.ts +2 -0
- package/dist/providers/__tests__/tambo-prop-stream-provider.test.d.ts.map +1 -0
- package/dist/providers/__tests__/tambo-prop-stream-provider.test.js +278 -0
- package/dist/providers/__tests__/tambo-prop-stream-provider.test.js.map +1 -0
- package/dist/providers/hoc/with-tambo-interactable.d.ts +34 -0
- package/dist/providers/hoc/with-tambo-interactable.d.ts.map +1 -0
- package/dist/providers/hoc/with-tambo-interactable.js +119 -0
- package/dist/providers/hoc/with-tambo-interactable.js.map +1 -0
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +3 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/tambo-interactable-provider.d.ts +20 -0
- package/dist/providers/tambo-interactable-provider.d.ts.map +1 -0
- package/dist/providers/tambo-interactable-provider.js +243 -0
- package/dist/providers/tambo-interactable-provider.js.map +1 -0
- package/dist/providers/tambo-prop-stream-provider.d.ts +96 -0
- package/dist/providers/tambo-prop-stream-provider.d.ts.map +1 -0
- package/dist/providers/tambo-prop-stream-provider.js +185 -0
- package/dist/providers/tambo-prop-stream-provider.js.map +1 -0
- package/dist/providers/tambo-provider.d.ts +6 -4
- package/dist/providers/tambo-provider.d.ts.map +1 -1
- package/dist/providers/tambo-provider.js +9 -4
- package/dist/providers/tambo-provider.js.map +1 -1
- package/esm/index.d.ts +4 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +3 -1
- package/esm/index.js.map +1 -1
- package/esm/model/tambo-interactable.d.ts +24 -0
- package/esm/model/tambo-interactable.d.ts.map +1 -0
- package/esm/model/tambo-interactable.js +2 -0
- package/esm/model/tambo-interactable.js.map +1 -0
- package/esm/providers/__tests__/tambo-prop-stream-provider.test.d.ts +2 -0
- package/esm/providers/__tests__/tambo-prop-stream-provider.test.d.ts.map +1 -0
- package/esm/providers/__tests__/tambo-prop-stream-provider.test.js +273 -0
- package/esm/providers/__tests__/tambo-prop-stream-provider.test.js.map +1 -0
- package/esm/providers/hoc/with-tambo-interactable.d.ts +34 -0
- package/esm/providers/hoc/with-tambo-interactable.d.ts.map +1 -0
- package/esm/providers/hoc/with-tambo-interactable.js +83 -0
- package/esm/providers/hoc/with-tambo-interactable.js.map +1 -0
- package/esm/providers/index.d.ts +1 -0
- package/esm/providers/index.d.ts.map +1 -1
- package/esm/providers/index.js +1 -0
- package/esm/providers/index.js.map +1 -1
- package/esm/providers/tambo-interactable-provider.d.ts +20 -0
- package/esm/providers/tambo-interactable-provider.d.ts.map +1 -0
- package/esm/providers/tambo-interactable-provider.js +205 -0
- package/esm/providers/tambo-interactable-provider.js.map +1 -0
- package/esm/providers/tambo-prop-stream-provider.d.ts +96 -0
- package/esm/providers/tambo-prop-stream-provider.d.ts.map +1 -0
- package/esm/providers/tambo-prop-stream-provider.js +148 -0
- package/esm/providers/tambo-prop-stream-provider.js.map +1 -0
- package/esm/providers/tambo-provider.d.ts +6 -4
- package/esm/providers/tambo-provider.d.ts.map +1 -1
- package/esm/providers/tambo-provider.js +9 -4
- package/esm/providers/tambo-provider.js.map +1 -1
- package/package.json +1 -1
package/dist/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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.GenerationStage = exports.useTamboThreadList = exports.useTamboThread = exports.useTamboClient = exports.useTambo = exports.TamboThreadProvider = exports.TamboStubProvider = exports.TamboProvider = exports.TamboComponentProvider = exports.TamboClientProvider = exports.useTamboThreadInput = exports.useTamboStreamStatus = exports.useTamboStreamingProps = exports.useTamboMessageContext = exports.useTamboCurrentMessage = exports.TamboMessageProvider = exports.useTamboComponentState = void 0;
|
|
17
|
+
exports.useTamboInteractable = exports.withInteractable = exports.GenerationStage = exports.useTamboThreadList = exports.useTamboThread = exports.useTamboClient = exports.useTambo = exports.TamboThreadProvider = exports.TamboStubProvider = exports.TamboProvider = exports.TamboComponentProvider = exports.TamboClientProvider = exports.useTamboThreadInput = exports.useTamboStreamStatus = exports.useTamboStreamingProps = exports.useTamboMessageContext = exports.useTamboCurrentMessage = exports.TamboMessageProvider = exports.useTamboComponentState = void 0;
|
|
18
18
|
/** 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. */
|
|
19
19
|
var use_component_state_1 = require("./hooks/use-component-state");
|
|
20
20
|
Object.defineProperty(exports, "useTamboComponentState", { enumerable: true, get: function () { return use_component_state_1.useTamboComponentState; } });
|
|
@@ -24,9 +24,9 @@ Object.defineProperty(exports, "useTamboCurrentMessage", { enumerable: true, get
|
|
|
24
24
|
Object.defineProperty(exports, "useTamboMessageContext", { enumerable: true, get: function () { return use_current_message_1.useTamboMessageContext; } });
|
|
25
25
|
var use_streaming_props_1 = require("./hooks/use-streaming-props");
|
|
26
26
|
Object.defineProperty(exports, "useTamboStreamingProps", { enumerable: true, get: function () { return use_streaming_props_1.useTamboStreamingProps; } });
|
|
27
|
+
__exportStar(require("./hooks/use-suggestions"), exports);
|
|
27
28
|
var use_tambo_stream_status_1 = require("./hooks/use-tambo-stream-status");
|
|
28
29
|
Object.defineProperty(exports, "useTamboStreamStatus", { enumerable: true, get: function () { return use_tambo_stream_status_1.useTamboStreamStatus; } });
|
|
29
|
-
__exportStar(require("./hooks/use-suggestions"), exports);
|
|
30
30
|
var use_thread_input_1 = require("./hooks/use-thread-input");
|
|
31
31
|
Object.defineProperty(exports, "useTamboThreadInput", { enumerable: true, get: function () { return use_thread_input_1.useTamboThreadInput; } });
|
|
32
32
|
// Re-export provider components
|
|
@@ -43,4 +43,8 @@ var use_tambo_threads_1 = require("./hooks/use-tambo-threads");
|
|
|
43
43
|
Object.defineProperty(exports, "useTamboThreadList", { enumerable: true, get: function () { return use_tambo_threads_1.useTamboThreadList; } });
|
|
44
44
|
var generate_component_response_1 = require("./model/generate-component-response");
|
|
45
45
|
Object.defineProperty(exports, "GenerationStage", { enumerable: true, get: function () { return generate_component_response_1.GenerationStage; } });
|
|
46
|
+
var with_tambo_interactable_1 = require("./providers/hoc/with-tambo-interactable");
|
|
47
|
+
Object.defineProperty(exports, "withInteractable", { enumerable: true, get: function () { return with_tambo_interactable_1.withTamboInteractable; } });
|
|
48
|
+
var tambo_interactable_provider_1 = require("./providers/tambo-interactable-provider");
|
|
49
|
+
Object.defineProperty(exports, "useTamboInteractable", { enumerable: true, get: function () { return tambo_interactable_provider_1.useTamboInteractable; } });
|
|
46
50
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,wKAAwK;AACxK,mEAAqE;AAA5D,6HAAA,sBAAsB,OAAA;AAC/B,mEAIqC;AAHnC,2HAAA,oBAAoB,OAAA;AACpB,6HAAA,sBAAsB,OAAA;AACtB,6HAAA,sBAAsB,OAAA;AAExB,mEAAqE;AAA5D,6HAAA,sBAAsB,OAAA;AAC/B,2EAIyC;AAHvC,+HAAA,oBAAoB,OAAA;AAItB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,wKAAwK;AACxK,mEAAqE;AAA5D,6HAAA,sBAAsB,OAAA;AAC/B,mEAIqC;AAHnC,2HAAA,oBAAoB,OAAA;AACpB,6HAAA,sBAAsB,OAAA;AACtB,6HAAA,sBAAsB,OAAA;AAExB,mEAAqE;AAA5D,6HAAA,sBAAsB,OAAA;AAC/B,0DAAwC;AACxC,2EAIyC;AAHvC,+HAAA,oBAAoB,OAAA;AAItB,6DAA+D;AAAtD,uHAAA,mBAAmB,OAAA;AAE5B,gCAAgC;AAChC,yCAYqB;AAXnB,gHAAA,mBAAmB,OAAA;AACnB,mHAAA,sBAAsB,OAAA;AACtB,0GAAA,aAAa,OAAA;AACb,8GAAA,iBAAiB,OAAA;AACjB,gHAAA,mBAAmB,OAAA;AACnB,qGAAA,QAAQ,OAAA;AACR,2GAAA,cAAc,OAAA;AACd,2GAAA,cAAc,OAAA;AAkBhB,+DAA+D;AAAtD,uHAAA,kBAAkB,OAAA;AAQ3B,mFAG6C;AAF3C,8HAAA,eAAe,OAAA;AASjB,mFAIiD;AAH/C,2HAAA,qBAAqB,OAAoB;AAI3C,uFAA+E;AAAtE,mIAAA,oBAAoB,OAAA","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 @@
|
|
|
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 @@
|
|
|
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,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = require("@testing-library/react");
|
|
7
|
+
const react_2 = __importDefault(require("react"));
|
|
8
|
+
const tambo_prop_stream_provider_1 = require("../tambo-prop-stream-provider");
|
|
9
|
+
// Helper component to test hook usage
|
|
10
|
+
const TestHookComponent = ({ testKey = "default", }) => {
|
|
11
|
+
const { data, streamStatus, getStatusForKey } = (0, tambo_prop_stream_provider_1.useTamboStream)();
|
|
12
|
+
const status = getStatusForKey(testKey);
|
|
13
|
+
return (react_2.default.createElement("div", null,
|
|
14
|
+
react_2.default.createElement("div", { "data-testid": "data" }, JSON.stringify(data)),
|
|
15
|
+
react_2.default.createElement("div", { "data-testid": "stream-status" }, JSON.stringify(streamStatus)),
|
|
16
|
+
react_2.default.createElement("div", { "data-testid": "key-status" }, JSON.stringify(status))));
|
|
17
|
+
};
|
|
18
|
+
describe("TamboPropStreamProvider", () => {
|
|
19
|
+
describe("Hook Error Handling", () => {
|
|
20
|
+
it("should throw error when useTamboStream is used outside provider", () => {
|
|
21
|
+
// Suppress console.error for this test
|
|
22
|
+
const originalError = console.error;
|
|
23
|
+
console.error = jest.fn();
|
|
24
|
+
expect(() => {
|
|
25
|
+
(0, react_1.render)(react_2.default.createElement(TestHookComponent, null));
|
|
26
|
+
}).toThrow("useTamboStream must be used within a TamboPropStreamProvider");
|
|
27
|
+
console.error = originalError;
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe("Basic Functionality", () => {
|
|
31
|
+
it("should provide data and stream status through context", () => {
|
|
32
|
+
const testData = { message: "Hello World" };
|
|
33
|
+
const testStreamStatus = {
|
|
34
|
+
isPending: false,
|
|
35
|
+
isStreaming: false,
|
|
36
|
+
isSuccess: true,
|
|
37
|
+
isError: false,
|
|
38
|
+
streamError: undefined,
|
|
39
|
+
};
|
|
40
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: testData, streamStatus: testStreamStatus },
|
|
41
|
+
react_2.default.createElement(TestHookComponent, null)));
|
|
42
|
+
expect(react_1.screen.getByTestId("data")).toHaveTextContent(JSON.stringify(testData));
|
|
43
|
+
expect(react_1.screen.getByTestId("stream-status")).toHaveTextContent(JSON.stringify(testStreamStatus));
|
|
44
|
+
});
|
|
45
|
+
it("should use default stream status when none provided", () => {
|
|
46
|
+
const testData = { message: "Hello World" };
|
|
47
|
+
const expectedDefaultStatus = {
|
|
48
|
+
isPending: false,
|
|
49
|
+
isStreaming: false,
|
|
50
|
+
isSuccess: true,
|
|
51
|
+
isError: false,
|
|
52
|
+
streamError: undefined,
|
|
53
|
+
};
|
|
54
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: testData },
|
|
55
|
+
react_2.default.createElement(TestHookComponent, null)));
|
|
56
|
+
expect(react_1.screen.getByTestId("stream-status")).toHaveTextContent(JSON.stringify(expectedDefaultStatus));
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe("Compound Components", () => {
|
|
60
|
+
describe("Loading Component", () => {
|
|
61
|
+
it("should render loading when isPending is true", () => {
|
|
62
|
+
const streamStatus = {
|
|
63
|
+
isPending: true,
|
|
64
|
+
isStreaming: false,
|
|
65
|
+
isSuccess: false,
|
|
66
|
+
isError: false,
|
|
67
|
+
};
|
|
68
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
69
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Loading, null,
|
|
70
|
+
react_2.default.createElement("div", { "data-testid": "loading" }, "Loading..."))));
|
|
71
|
+
expect(react_1.screen.getByTestId("loading")).toBeInTheDocument();
|
|
72
|
+
});
|
|
73
|
+
it("should render loading when isStreaming is true", () => {
|
|
74
|
+
const streamStatus = {
|
|
75
|
+
isPending: false,
|
|
76
|
+
isStreaming: true,
|
|
77
|
+
isSuccess: false,
|
|
78
|
+
isError: false,
|
|
79
|
+
};
|
|
80
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
81
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Loading, null,
|
|
82
|
+
react_2.default.createElement("div", { "data-testid": "loading" }, "Loading..."))));
|
|
83
|
+
expect(react_1.screen.getByTestId("loading")).toBeInTheDocument();
|
|
84
|
+
});
|
|
85
|
+
it("should not render loading when not pending or streaming", () => {
|
|
86
|
+
const streamStatus = {
|
|
87
|
+
isPending: false,
|
|
88
|
+
isStreaming: false,
|
|
89
|
+
isSuccess: true,
|
|
90
|
+
isError: false,
|
|
91
|
+
};
|
|
92
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: "test", streamStatus: streamStatus },
|
|
93
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Loading, null,
|
|
94
|
+
react_2.default.createElement("div", { "data-testid": "loading" }, "Loading..."))));
|
|
95
|
+
expect(react_1.screen.queryByTestId("loading")).not.toBeInTheDocument();
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
describe("Complete Component", () => {
|
|
99
|
+
it("should render complete when isSuccess is true and data exists", () => {
|
|
100
|
+
const streamStatus = {
|
|
101
|
+
isPending: false,
|
|
102
|
+
isStreaming: false,
|
|
103
|
+
isSuccess: true,
|
|
104
|
+
isError: false,
|
|
105
|
+
};
|
|
106
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: "test data", streamStatus: streamStatus },
|
|
107
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Complete, null,
|
|
108
|
+
react_2.default.createElement("div", { "data-testid": "complete" }, "Complete!"))));
|
|
109
|
+
expect(react_1.screen.getByTestId("complete")).toBeInTheDocument();
|
|
110
|
+
});
|
|
111
|
+
it("should not render complete when data is null", () => {
|
|
112
|
+
const streamStatus = {
|
|
113
|
+
isPending: false,
|
|
114
|
+
isStreaming: false,
|
|
115
|
+
isSuccess: true,
|
|
116
|
+
isError: false,
|
|
117
|
+
};
|
|
118
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
119
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Complete, null,
|
|
120
|
+
react_2.default.createElement("div", { "data-testid": "complete" }, "Complete!"))));
|
|
121
|
+
expect(react_1.screen.queryByTestId("complete")).not.toBeInTheDocument();
|
|
122
|
+
});
|
|
123
|
+
it("should not render complete when data is undefined", () => {
|
|
124
|
+
const streamStatus = {
|
|
125
|
+
isPending: false,
|
|
126
|
+
isStreaming: false,
|
|
127
|
+
isSuccess: true,
|
|
128
|
+
isError: false,
|
|
129
|
+
};
|
|
130
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: undefined, streamStatus: streamStatus },
|
|
131
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Complete, null,
|
|
132
|
+
react_2.default.createElement("div", { "data-testid": "complete" }, "Complete!"))));
|
|
133
|
+
expect(react_1.screen.queryByTestId("complete")).not.toBeInTheDocument();
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
describe("Empty Component", () => {
|
|
137
|
+
it("should render empty when no data and not loading/streaming/success/error", () => {
|
|
138
|
+
const streamStatus = {
|
|
139
|
+
isPending: false,
|
|
140
|
+
isStreaming: false,
|
|
141
|
+
isSuccess: false,
|
|
142
|
+
isError: false,
|
|
143
|
+
};
|
|
144
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
145
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Empty, null,
|
|
146
|
+
react_2.default.createElement("div", { "data-testid": "empty" }, "No data"))));
|
|
147
|
+
expect(react_1.screen.getByTestId("empty")).toBeInTheDocument();
|
|
148
|
+
});
|
|
149
|
+
it("should render empty when data is empty string", () => {
|
|
150
|
+
const streamStatus = {
|
|
151
|
+
isPending: false,
|
|
152
|
+
isStreaming: false,
|
|
153
|
+
isSuccess: false,
|
|
154
|
+
isError: false,
|
|
155
|
+
};
|
|
156
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: "", streamStatus: streamStatus },
|
|
157
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Empty, null,
|
|
158
|
+
react_2.default.createElement("div", { "data-testid": "empty" }, "No data"))));
|
|
159
|
+
expect(react_1.screen.getByTestId("empty")).toBeInTheDocument();
|
|
160
|
+
});
|
|
161
|
+
it("should not render empty when loading", () => {
|
|
162
|
+
const streamStatus = {
|
|
163
|
+
isPending: true,
|
|
164
|
+
isStreaming: false,
|
|
165
|
+
isSuccess: false,
|
|
166
|
+
isError: false,
|
|
167
|
+
};
|
|
168
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
169
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Empty, null,
|
|
170
|
+
react_2.default.createElement("div", { "data-testid": "empty" }, "No data"))));
|
|
171
|
+
expect(react_1.screen.queryByTestId("empty")).not.toBeInTheDocument();
|
|
172
|
+
});
|
|
173
|
+
it("should not render empty when successful", () => {
|
|
174
|
+
const streamStatus = {
|
|
175
|
+
isPending: false,
|
|
176
|
+
isStreaming: false,
|
|
177
|
+
isSuccess: true,
|
|
178
|
+
isError: false,
|
|
179
|
+
};
|
|
180
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
181
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Empty, null,
|
|
182
|
+
react_2.default.createElement("div", { "data-testid": "empty" }, "No data"))));
|
|
183
|
+
expect(react_1.screen.queryByTestId("empty")).not.toBeInTheDocument();
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
describe("Per-Key Status Tracking", () => {
|
|
188
|
+
it("should track status for object keys", () => {
|
|
189
|
+
const testData = { name: "John", age: null };
|
|
190
|
+
const streamStatus = {
|
|
191
|
+
isPending: false,
|
|
192
|
+
isStreaming: false,
|
|
193
|
+
isSuccess: true,
|
|
194
|
+
isError: false,
|
|
195
|
+
};
|
|
196
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: testData, streamStatus: streamStatus },
|
|
197
|
+
react_2.default.createElement(TestHookComponent, { testKey: "name" })));
|
|
198
|
+
const keyStatus = JSON.parse(react_1.screen.getByTestId("key-status").textContent ?? "{}");
|
|
199
|
+
expect(keyStatus.isSuccess).toBe(true); // name has data
|
|
200
|
+
});
|
|
201
|
+
it("should show loading for keys without data", () => {
|
|
202
|
+
const testData = { name: "John", age: null };
|
|
203
|
+
const streamStatus = {
|
|
204
|
+
isPending: false,
|
|
205
|
+
isStreaming: false,
|
|
206
|
+
isSuccess: true,
|
|
207
|
+
isError: false,
|
|
208
|
+
};
|
|
209
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: testData, streamStatus: streamStatus },
|
|
210
|
+
react_2.default.createElement(TestHookComponent, { testKey: "age" })));
|
|
211
|
+
const keyStatus = JSON.parse(react_1.screen.getByTestId("key-status").textContent ?? "{}");
|
|
212
|
+
expect(keyStatus.isPending).toBe(true); // age has no data
|
|
213
|
+
});
|
|
214
|
+
it("should handle per-key loading states", () => {
|
|
215
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: { name: "John", age: null } },
|
|
216
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Loading, { streamKey: "name" },
|
|
217
|
+
react_2.default.createElement("div", { "data-testid": "name-loading" }, "Name loading...")),
|
|
218
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Loading, { streamKey: "age" },
|
|
219
|
+
react_2.default.createElement("div", { "data-testid": "age-loading" }, "Age loading...")),
|
|
220
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Complete, { streamKey: "name" },
|
|
221
|
+
react_2.default.createElement("div", { "data-testid": "name-complete" }, "Name: John"))));
|
|
222
|
+
// Name should be complete (has data)
|
|
223
|
+
expect(react_1.screen.getByTestId("name-complete")).toBeInTheDocument();
|
|
224
|
+
expect(react_1.screen.queryByTestId("name-loading")).not.toBeInTheDocument();
|
|
225
|
+
// Age should be loading (no data)
|
|
226
|
+
expect(react_1.screen.getByTestId("age-loading")).toBeInTheDocument();
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
describe("Edge Cases", () => {
|
|
230
|
+
it("should handle null data gracefully", () => {
|
|
231
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: null },
|
|
232
|
+
react_2.default.createElement(TestHookComponent, null)));
|
|
233
|
+
expect(react_1.screen.getByTestId("data")).toHaveTextContent("null");
|
|
234
|
+
});
|
|
235
|
+
it("should handle undefined data gracefully", () => {
|
|
236
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: undefined },
|
|
237
|
+
react_2.default.createElement(TestHookComponent, null)));
|
|
238
|
+
expect(react_1.screen.getByTestId("data")).toHaveTextContent("");
|
|
239
|
+
});
|
|
240
|
+
it("should handle array data", () => {
|
|
241
|
+
const arrayData = ["item1", "item2"];
|
|
242
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: arrayData },
|
|
243
|
+
react_2.default.createElement(TestHookComponent, null)));
|
|
244
|
+
expect(react_1.screen.getByTestId("data")).toHaveTextContent(JSON.stringify(arrayData));
|
|
245
|
+
});
|
|
246
|
+
it("should handle primitive data types", () => {
|
|
247
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: "string data" },
|
|
248
|
+
react_2.default.createElement(TestHookComponent, null)));
|
|
249
|
+
expect(react_1.screen.getByTestId("data")).toHaveTextContent('"string data"');
|
|
250
|
+
});
|
|
251
|
+
it("should fallback to default status for unknown keys", () => {
|
|
252
|
+
const testData = { name: "John" };
|
|
253
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: testData },
|
|
254
|
+
react_2.default.createElement(TestHookComponent, { testKey: "unknown-key" })));
|
|
255
|
+
const keyStatus = JSON.parse(react_1.screen.getByTestId("key-status").textContent ?? "{}");
|
|
256
|
+
// Should fallback to default status
|
|
257
|
+
expect(keyStatus.isSuccess).toBe(true);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
describe("Component Attributes", () => {
|
|
261
|
+
it("should add correct data attributes to components", () => {
|
|
262
|
+
const streamStatus = {
|
|
263
|
+
isPending: true,
|
|
264
|
+
isStreaming: false,
|
|
265
|
+
isSuccess: false,
|
|
266
|
+
isError: false,
|
|
267
|
+
};
|
|
268
|
+
(0, react_1.render)(react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider, { data: null, streamStatus: streamStatus },
|
|
269
|
+
react_2.default.createElement(tambo_prop_stream_provider_1.TamboPropStreamProvider.Loading, { className: "loading-class" },
|
|
270
|
+
react_2.default.createElement("div", null, "Loading..."))));
|
|
271
|
+
const loadingElement = react_1.screen.getByText("Loading...").parentElement;
|
|
272
|
+
expect(loadingElement).toHaveAttribute("data-stream-key", "default");
|
|
273
|
+
expect(loadingElement).toHaveAttribute("data-stream-state", "loading");
|
|
274
|
+
expect(loadingElement).toHaveClass("loading-class");
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
//# 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"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export interface InteractableConfig {
|
|
4
|
+
componentName: string;
|
|
5
|
+
description: string;
|
|
6
|
+
propsSchema?: z.ZodTypeAny;
|
|
7
|
+
}
|
|
8
|
+
export interface WithTamboInteractableProps {
|
|
9
|
+
interactableId?: string;
|
|
10
|
+
onInteractableReady?: (id: string) => void;
|
|
11
|
+
onPropsUpdate?: (newProps: Record<string, any>) => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Higher-Order Component that makes any component interactable by tambo.
|
|
15
|
+
* @param WrappedComponent - The component to make interactable
|
|
16
|
+
* @param config - Configuration for the interactable component
|
|
17
|
+
* @returns A new component that is automatically registered as interactable
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* const MyInteractableNote = withTamboInteractable(MyNote, {
|
|
21
|
+
* componentName: "MyNote",
|
|
22
|
+
* description: "A note component",
|
|
23
|
+
* propsSchema: z.object({
|
|
24
|
+
* title: z.string(),
|
|
25
|
+
* content: z.string(),
|
|
26
|
+
* }),
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* // Usage
|
|
30
|
+
* <MyInteractableNote title="My Note" content="This is my note" />
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function withTamboInteractable<P extends object>(WrappedComponent: React.ComponentType<P>, config: InteractableConfig): React.FC<P & WithTamboInteractableProps>;
|
|
34
|
+
//# sourceMappingURL=with-tambo-interactable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with-tambo-interactable.d.ts","sourceRoot":"","sources":["../../../src/providers/hoc/with-tambo-interactable.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;CACzD;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EACpD,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EACxC,MAAM,EAAE,kBAAkB,4CA+E3B"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// react-sdk/src/providers/with-interactable.tsx
|
|
3
|
+
"use client";
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
+
}
|
|
10
|
+
Object.defineProperty(o, k2, desc);
|
|
11
|
+
}) : (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
o[k2] = m[k];
|
|
14
|
+
}));
|
|
15
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
16
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
17
|
+
}) : function(o, v) {
|
|
18
|
+
o["default"] = v;
|
|
19
|
+
});
|
|
20
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
21
|
+
var ownKeys = function(o) {
|
|
22
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
23
|
+
var ar = [];
|
|
24
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
25
|
+
return ar;
|
|
26
|
+
};
|
|
27
|
+
return ownKeys(o);
|
|
28
|
+
};
|
|
29
|
+
return function (mod) {
|
|
30
|
+
if (mod && mod.__esModule) return mod;
|
|
31
|
+
var result = {};
|
|
32
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
33
|
+
__setModuleDefault(result, mod);
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
})();
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.withTamboInteractable = withTamboInteractable;
|
|
39
|
+
const react_1 = __importStar(require("react"));
|
|
40
|
+
const tambo_interactable_provider_1 = require("../tambo-interactable-provider");
|
|
41
|
+
/**
|
|
42
|
+
* Higher-Order Component that makes any component interactable by tambo.
|
|
43
|
+
* @param WrappedComponent - The component to make interactable
|
|
44
|
+
* @param config - Configuration for the interactable component
|
|
45
|
+
* @returns A new component that is automatically registered as interactable
|
|
46
|
+
* @example
|
|
47
|
+
* ```tsx
|
|
48
|
+
* const MyInteractableNote = withTamboInteractable(MyNote, {
|
|
49
|
+
* componentName: "MyNote",
|
|
50
|
+
* description: "A note component",
|
|
51
|
+
* propsSchema: z.object({
|
|
52
|
+
* title: z.string(),
|
|
53
|
+
* content: z.string(),
|
|
54
|
+
* }),
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* // Usage
|
|
58
|
+
* <MyInteractableNote title="My Note" content="This is my note" />
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
function withTamboInteractable(WrappedComponent, config) {
|
|
62
|
+
const displayName = WrappedComponent.displayName ?? WrappedComponent.name ?? "Component";
|
|
63
|
+
const TamboInteractableWrapper = (props) => {
|
|
64
|
+
const { addInteractableComponent, updateInteractableComponentProps, getInteractableComponent, } = (0, tambo_interactable_provider_1.useTamboInteractable)();
|
|
65
|
+
const [interactableId, setInteractableId] = (0, react_1.useState)(null);
|
|
66
|
+
const isInitialized = (0, react_1.useRef)(false);
|
|
67
|
+
const lastParentProps = (0, react_1.useRef)({});
|
|
68
|
+
// Extract interactable-specific props
|
|
69
|
+
const { onInteractableReady, onPropsUpdate, ...componentProps } = props;
|
|
70
|
+
// Get the current interactable component to track prop updates
|
|
71
|
+
const currentInteractable = interactableId
|
|
72
|
+
? getInteractableComponent(interactableId)
|
|
73
|
+
: null;
|
|
74
|
+
// Use the props from the interactable component if available, otherwise use the passed props
|
|
75
|
+
// We need to be careful not to create a loop, so we only use stored props if they're different from passed props
|
|
76
|
+
const effectiveProps = currentInteractable?.props ?? componentProps;
|
|
77
|
+
// Memoize the registration function
|
|
78
|
+
const registerComponent = (0, react_1.useCallback)(() => {
|
|
79
|
+
if (!isInitialized.current) {
|
|
80
|
+
const id = addInteractableComponent({
|
|
81
|
+
name: config.componentName,
|
|
82
|
+
description: config.description,
|
|
83
|
+
component: WrappedComponent,
|
|
84
|
+
props: componentProps,
|
|
85
|
+
propsSchema: config.propsSchema,
|
|
86
|
+
});
|
|
87
|
+
setInteractableId(id);
|
|
88
|
+
onInteractableReady?.(id);
|
|
89
|
+
isInitialized.current = true;
|
|
90
|
+
}
|
|
91
|
+
}, [addInteractableComponent, componentProps, onInteractableReady]);
|
|
92
|
+
// Register the component as interactable on mount (only once)
|
|
93
|
+
(0, react_1.useEffect)(() => {
|
|
94
|
+
registerComponent();
|
|
95
|
+
}, [registerComponent]);
|
|
96
|
+
// Update the interactable component when props change from parent
|
|
97
|
+
(0, react_1.useEffect)(() => {
|
|
98
|
+
if (interactableId && isInitialized.current) {
|
|
99
|
+
// Only update if the props are different from what we last sent
|
|
100
|
+
const lastPropsString = JSON.stringify(lastParentProps.current);
|
|
101
|
+
const currentPropsString = JSON.stringify(componentProps);
|
|
102
|
+
if (lastPropsString !== currentPropsString) {
|
|
103
|
+
updateInteractableComponentProps(interactableId, componentProps);
|
|
104
|
+
onPropsUpdate?.(componentProps);
|
|
105
|
+
lastParentProps.current = componentProps;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}, [
|
|
109
|
+
interactableId,
|
|
110
|
+
componentProps,
|
|
111
|
+
updateInteractableComponentProps,
|
|
112
|
+
onPropsUpdate,
|
|
113
|
+
]);
|
|
114
|
+
return react_1.default.createElement(WrappedComponent, { ...effectiveProps });
|
|
115
|
+
};
|
|
116
|
+
TamboInteractableWrapper.displayName = `withTamboInteractable(${displayName})`;
|
|
117
|
+
return TamboInteractableWrapper;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=with-tambo-interactable.js.map
|