@enclave-vm/react 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@enclave-vm/react",
3
+ "version": "0.0.1",
4
+ "description": "React hooks and components for the EnclaveJS streaming runtime",
5
+ "author": "AgentFront <info@agentfront.dev>",
6
+ "homepage": "https://github.com/agentfront/enclave",
7
+ "license": "Apache-2.0",
8
+ "keywords": [
9
+ "enclavejs",
10
+ "enclave",
11
+ "react",
12
+ "hooks",
13
+ "streaming",
14
+ "runtime"
15
+ ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/agentfront/enclave.git"
19
+ },
20
+ "bugs": {
21
+ "url": "https://github.com/agentfront/enclave/issues"
22
+ },
23
+ "main": "./src/index.js",
24
+ "types": "./src/index.d.ts",
25
+ "exports": {
26
+ "./package.json": "./package.json",
27
+ ".": {
28
+ "types": "./src/index.d.ts",
29
+ "import": "./src/index.js",
30
+ "default": "./src/index.js"
31
+ }
32
+ },
33
+ "dependencies": {
34
+ "@enclave-vm/client": "0.0.1"
35
+ },
36
+ "peerDependencies": {
37
+ "react": ">=17.0.0"
38
+ },
39
+ "type": "commonjs"
40
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * EnclaveProvider
3
+ *
4
+ * React context provider for the EnclaveJS client.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import React from 'react';
9
+ import { EnclaveClient } from '@enclave-vm/client';
10
+ import type { EnclaveProviderProps, EnclaveContextValue } from './types.js';
11
+ /**
12
+ * React context for the Enclave client
13
+ */
14
+ declare const EnclaveContext: React.Context<EnclaveContextValue | null>;
15
+ /**
16
+ * EnclaveProvider component
17
+ *
18
+ * Provides the EnclaveClient to child components via React context.
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * function App() {
23
+ * return (
24
+ * <EnclaveProvider config={{ baseUrl: 'https://api.example.com' }}>
25
+ * <MyComponent />
26
+ * </EnclaveProvider>
27
+ * );
28
+ * }
29
+ * ```
30
+ */
31
+ export declare function EnclaveProvider({ config, client: providedClient, children, }: EnclaveProviderProps): React.ReactElement;
32
+ /**
33
+ * useEnclaveContext hook
34
+ *
35
+ * Access the Enclave context directly. Throws if used outside EnclaveProvider.
36
+ *
37
+ * @internal
38
+ */
39
+ export declare function useEnclaveContext(): EnclaveContextValue;
40
+ /**
41
+ * useEnclaveClient hook
42
+ *
43
+ * Get the EnclaveClient instance from context.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * function MyComponent() {
48
+ * const client = useEnclaveClient();
49
+ *
50
+ * const handleClick = async () => {
51
+ * const result = await client.execute('return 1 + 1');
52
+ * console.log(result.value);
53
+ * };
54
+ *
55
+ * return <button onClick={handleClick}>Execute</button>;
56
+ * }
57
+ * ```
58
+ */
59
+ export declare function useEnclaveClient(): EnclaveClient;
60
+ export { EnclaveContext };
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EnclaveContext = void 0;
4
+ exports.EnclaveProvider = EnclaveProvider;
5
+ exports.useEnclaveContext = useEnclaveContext;
6
+ exports.useEnclaveClient = useEnclaveClient;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ /**
9
+ * EnclaveProvider
10
+ *
11
+ * React context provider for the EnclaveJS client.
12
+ *
13
+ * @packageDocumentation
14
+ */
15
+ const react_1 = require("react");
16
+ const client_1 = require("@enclave-vm/client");
17
+ /**
18
+ * React context for the Enclave client
19
+ */
20
+ const EnclaveContext = (0, react_1.createContext)(null);
21
+ exports.EnclaveContext = EnclaveContext;
22
+ /**
23
+ * EnclaveProvider component
24
+ *
25
+ * Provides the EnclaveClient to child components via React context.
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * function App() {
30
+ * return (
31
+ * <EnclaveProvider config={{ baseUrl: 'https://api.example.com' }}>
32
+ * <MyComponent />
33
+ * </EnclaveProvider>
34
+ * );
35
+ * }
36
+ * ```
37
+ */
38
+ function EnclaveProvider({ config, client: providedClient, children, }) {
39
+ // Use ref to ensure client is only created once
40
+ const clientRef = (0, react_1.useRef)(null);
41
+ // Create or use provided client
42
+ const client = (0, react_1.useMemo)(() => {
43
+ if (providedClient) {
44
+ return providedClient;
45
+ }
46
+ // Create new client if not already created
47
+ if (!clientRef.current) {
48
+ clientRef.current = new client_1.EnclaveClient(config);
49
+ }
50
+ return clientRef.current;
51
+ }, [providedClient, config]);
52
+ // Memoize context value
53
+ const contextValue = (0, react_1.useMemo)(() => ({
54
+ client,
55
+ config,
56
+ }), [client, config]);
57
+ return (0, jsx_runtime_1.jsx)(EnclaveContext.Provider, { value: contextValue, children: children });
58
+ }
59
+ /**
60
+ * useEnclaveContext hook
61
+ *
62
+ * Access the Enclave context directly. Throws if used outside EnclaveProvider.
63
+ *
64
+ * @internal
65
+ */
66
+ function useEnclaveContext() {
67
+ const context = (0, react_1.useContext)(EnclaveContext);
68
+ if (!context) {
69
+ throw new Error('useEnclaveContext must be used within an EnclaveProvider. ' +
70
+ 'Wrap your component tree with <EnclaveProvider config={{...}}>.');
71
+ }
72
+ return context;
73
+ }
74
+ /**
75
+ * useEnclaveClient hook
76
+ *
77
+ * Get the EnclaveClient instance from context.
78
+ *
79
+ * @example
80
+ * ```tsx
81
+ * function MyComponent() {
82
+ * const client = useEnclaveClient();
83
+ *
84
+ * const handleClick = async () => {
85
+ * const result = await client.execute('return 1 + 1');
86
+ * console.log(result.value);
87
+ * };
88
+ *
89
+ * return <button onClick={handleClick}>Execute</button>;
90
+ * }
91
+ * ```
92
+ */
93
+ function useEnclaveClient() {
94
+ const { client } = useEnclaveContext();
95
+ return client;
96
+ }
97
+ //# sourceMappingURL=EnclaveProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnclaveProvider.js","sourceRoot":"","sources":["../../src/EnclaveProvider.tsx"],"names":[],"mappings":";;;AAiCA,0CAgCC;AASD,8CAWC;AAqBD,4CAGC;;AA7GD;;;;;;GAMG;AAEH,iCAA0E;AAC1E,+CAAmD;AAGnD;;GAEG;AACH,MAAM,cAAc,GAAG,IAAA,qBAAa,EAA6B,IAAI,CAAC,CAAC;AAgG9D,wCAAc;AA9FvB;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,MAAM,EAAE,cAAc,EACtB,QAAQ,GACa;IACrB,gDAAgD;IAChD,MAAM,SAAS,GAAG,IAAA,cAAM,EAAuB,IAAI,CAAC,CAAC;IAErD,gCAAgC;IAChC,MAAM,MAAM,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;QAC1B,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,cAAc,CAAC;QACxB,CAAC;QAED,2CAA2C;QAC3C,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACvB,SAAS,CAAC,OAAO,GAAG,IAAI,sBAAa,CAAC,MAAM,CAAC,CAAC;QAChD,CAAC;QAED,OAAO,SAAS,CAAC,OAAO,CAAC;IAC3B,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;IAE7B,wBAAwB;IACxB,MAAM,YAAY,GAAG,IAAA,eAAO,EAC1B,GAAG,EAAE,CAAC,CAAC;QACL,MAAM;QACN,MAAM;KACP,CAAC,EACF,CAAC,MAAM,EAAE,MAAM,CAAC,CACjB,CAAC;IAEF,OAAO,uBAAC,cAAc,CAAC,QAAQ,IAAC,KAAK,EAAE,YAAY,YAAG,QAAQ,GAA2B,CAAC;AAC5F,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,iBAAiB;IAC/B,MAAM,OAAO,GAAG,IAAA,kBAAU,EAAC,cAAc,CAAC,CAAC;IAE3C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,4DAA4D;YAC1D,iEAAiE,CACpE,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,gBAAgB;IAC9B,MAAM,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE,CAAC;IACvC,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["/**\n * EnclaveProvider\n *\n * React context provider for the EnclaveJS client.\n *\n * @packageDocumentation\n */\n\nimport React, { createContext, useContext, useMemo, useRef } from 'react';\nimport { EnclaveClient } from '@enclave-vm/client';\nimport type { EnclaveProviderProps, EnclaveContextValue } from './types.js';\n\n/**\n * React context for the Enclave client\n */\nconst EnclaveContext = createContext<EnclaveContextValue | null>(null);\n\n/**\n * EnclaveProvider component\n *\n * Provides the EnclaveClient to child components via React context.\n *\n * @example\n * ```tsx\n * function App() {\n * return (\n * <EnclaveProvider config={{ baseUrl: 'https://api.example.com' }}>\n * <MyComponent />\n * </EnclaveProvider>\n * );\n * }\n * ```\n */\nexport function EnclaveProvider({\n config,\n client: providedClient,\n children,\n}: EnclaveProviderProps): React.ReactElement {\n // Use ref to ensure client is only created once\n const clientRef = useRef<EnclaveClient | null>(null);\n\n // Create or use provided client\n const client = useMemo(() => {\n if (providedClient) {\n return providedClient;\n }\n\n // Create new client if not already created\n if (!clientRef.current) {\n clientRef.current = new EnclaveClient(config);\n }\n\n return clientRef.current;\n }, [providedClient, config]);\n\n // Memoize context value\n const contextValue = useMemo<EnclaveContextValue>(\n () => ({\n client,\n config,\n }),\n [client, config],\n );\n\n return <EnclaveContext.Provider value={contextValue}>{children}</EnclaveContext.Provider>;\n}\n\n/**\n * useEnclaveContext hook\n *\n * Access the Enclave context directly. Throws if used outside EnclaveProvider.\n *\n * @internal\n */\nexport function useEnclaveContext(): EnclaveContextValue {\n const context = useContext(EnclaveContext);\n\n if (!context) {\n throw new Error(\n 'useEnclaveContext must be used within an EnclaveProvider. ' +\n 'Wrap your component tree with <EnclaveProvider config={{...}}>.',\n );\n }\n\n return context;\n}\n\n/**\n * useEnclaveClient hook\n *\n * Get the EnclaveClient instance from context.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const client = useEnclaveClient();\n *\n * const handleClick = async () => {\n * const result = await client.execute('return 1 + 1');\n * console.log(result.value);\n * };\n *\n * return <button onClick={handleClick}>Execute</button>;\n * }\n * ```\n */\nexport function useEnclaveClient(): EnclaveClient {\n const { client } = useEnclaveContext();\n return client;\n}\n\nexport { EnclaveContext };\n"]}
package/src/index.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @enclave-vm/react
3
+ *
4
+ * React hooks and components for the EnclaveJS streaming runtime.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ export { EnclaveProvider, useEnclaveClient, useEnclaveContext } from './EnclaveProvider.js';
9
+ export { useEnclaveSession } from './useEnclaveSession.js';
10
+ export type { SessionState, UseEnclaveSessionOptions, UseEnclaveSessionReturn, EnclaveProviderProps, EnclaveContextValue, } from './types.js';
11
+ export type { EnclaveClient, EnclaveClientConfig, SessionResult, SessionHandle, StreamEvent, SessionId, } from '@enclave-vm/client';
package/src/index.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /**
3
+ * @enclave-vm/react
4
+ *
5
+ * React hooks and components for the EnclaveJS streaming runtime.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.useEnclaveSession = exports.useEnclaveContext = exports.useEnclaveClient = exports.EnclaveProvider = void 0;
11
+ // Provider and context
12
+ var EnclaveProvider_js_1 = require("./EnclaveProvider.js");
13
+ Object.defineProperty(exports, "EnclaveProvider", { enumerable: true, get: function () { return EnclaveProvider_js_1.EnclaveProvider; } });
14
+ Object.defineProperty(exports, "useEnclaveClient", { enumerable: true, get: function () { return EnclaveProvider_js_1.useEnclaveClient; } });
15
+ Object.defineProperty(exports, "useEnclaveContext", { enumerable: true, get: function () { return EnclaveProvider_js_1.useEnclaveContext; } });
16
+ // Hooks
17
+ var useEnclaveSession_js_1 = require("./useEnclaveSession.js");
18
+ Object.defineProperty(exports, "useEnclaveSession", { enumerable: true, get: function () { return useEnclaveSession_js_1.useEnclaveSession; } });
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,uBAAuB;AACvB,2DAA4F;AAAnF,qHAAA,eAAe,OAAA;AAAE,sHAAA,gBAAgB,OAAA;AAAE,uHAAA,iBAAiB,OAAA;AAE7D,QAAQ;AACR,+DAA2D;AAAlD,yHAAA,iBAAiB,OAAA","sourcesContent":["/**\n * @enclave-vm/react\n *\n * React hooks and components for the EnclaveJS streaming runtime.\n *\n * @packageDocumentation\n */\n\n// Provider and context\nexport { EnclaveProvider, useEnclaveClient, useEnclaveContext } from './EnclaveProvider.js';\n\n// Hooks\nexport { useEnclaveSession } from './useEnclaveSession.js';\n\n// Types\nexport type {\n SessionState,\n UseEnclaveSessionOptions,\n UseEnclaveSessionReturn,\n EnclaveProviderProps,\n EnclaveContextValue,\n} from './types.js';\n\n// Re-export commonly used types from @enclave-vm/client\nexport type {\n EnclaveClient,\n EnclaveClientConfig,\n SessionResult,\n SessionHandle,\n StreamEvent,\n SessionId,\n} from '@enclave-vm/client';\n"]}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Test setup for React Testing Library
3
+ */
4
+ import '@testing-library/jest-dom';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ /**
3
+ * Test setup for React Testing Library
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ require("@testing-library/jest-dom");
7
+ //# sourceMappingURL=test-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-setup.js","sourceRoot":"","sources":["../../src/test-setup.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAEH,qCAAmC","sourcesContent":["/**\n * Test setup for React Testing Library\n */\n\nimport '@testing-library/jest-dom';\n"]}
package/src/types.d.ts ADDED
@@ -0,0 +1,142 @@
1
+ /**
2
+ * React Types
3
+ *
4
+ * Types for the EnclaveJS React hooks and components.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import type { EnclaveClient, EnclaveClientConfig, SessionResult, StreamEvent, SessionId } from '@enclave-vm/client';
9
+ /**
10
+ * Session state enum
11
+ */
12
+ export type SessionState = 'idle' | 'running' | 'completed' | 'error' | 'cancelled';
13
+ /**
14
+ * useEnclaveSession hook options
15
+ */
16
+ export interface UseEnclaveSessionOptions {
17
+ /**
18
+ * Custom session ID (generated if not provided)
19
+ */
20
+ sessionId?: SessionId;
21
+ /**
22
+ * Session timeout in milliseconds
23
+ */
24
+ timeoutMs?: number;
25
+ /**
26
+ * Maximum number of tool calls
27
+ */
28
+ maxToolCalls?: number;
29
+ /**
30
+ * Heartbeat interval in milliseconds
31
+ */
32
+ heartbeatIntervalMs?: number;
33
+ /**
34
+ * Callback when session starts
35
+ */
36
+ onStart?: () => void;
37
+ /**
38
+ * Callback for stdout output
39
+ */
40
+ onStdout?: (chunk: string) => void;
41
+ /**
42
+ * Callback for log messages
43
+ */
44
+ onLog?: (level: string, message: string, data?: Record<string, unknown>) => void;
45
+ /**
46
+ * Callback for tool calls
47
+ */
48
+ onToolCall?: (callId: string, toolName: string, args: unknown) => void;
49
+ /**
50
+ * Callback when tool result is applied
51
+ */
52
+ onToolResultApplied?: (callId: string) => void;
53
+ /**
54
+ * Callback on completion
55
+ */
56
+ onComplete?: (result: SessionResult) => void;
57
+ /**
58
+ * Callback on error
59
+ */
60
+ onError?: (error: {
61
+ code?: string;
62
+ message: string;
63
+ }) => void;
64
+ }
65
+ /**
66
+ * useEnclaveSession hook return type
67
+ */
68
+ export interface UseEnclaveSessionReturn<T = unknown> {
69
+ /**
70
+ * Execute code in the enclave
71
+ */
72
+ execute: (code: string) => Promise<SessionResult<T>>;
73
+ /**
74
+ * Cancel the current session
75
+ */
76
+ cancel: (reason?: string) => Promise<void>;
77
+ /**
78
+ * Current session state
79
+ */
80
+ state: SessionState;
81
+ /**
82
+ * Whether a session is currently running
83
+ */
84
+ isRunning: boolean;
85
+ /**
86
+ * Current session ID (if running)
87
+ */
88
+ sessionId: SessionId | null;
89
+ /**
90
+ * Result of the last execution (if completed)
91
+ */
92
+ result: SessionResult<T> | null;
93
+ /**
94
+ * Error from the last execution (if failed)
95
+ */
96
+ error: {
97
+ code?: string;
98
+ message: string;
99
+ } | null;
100
+ /**
101
+ * Stdout output accumulated during execution
102
+ */
103
+ stdout: string;
104
+ /**
105
+ * Events received during execution
106
+ */
107
+ events: StreamEvent[];
108
+ /**
109
+ * Reset the hook state
110
+ */
111
+ reset: () => void;
112
+ }
113
+ /**
114
+ * EnclaveProvider props
115
+ */
116
+ export interface EnclaveProviderProps {
117
+ /**
118
+ * Client configuration
119
+ */
120
+ config: EnclaveClientConfig;
121
+ /**
122
+ * Pre-created client instance (alternative to config)
123
+ */
124
+ client?: EnclaveClient;
125
+ /**
126
+ * Children to render
127
+ */
128
+ children: React.ReactNode;
129
+ }
130
+ /**
131
+ * Enclave context value
132
+ */
133
+ export interface EnclaveContextValue {
134
+ /**
135
+ * The EnclaveClient instance
136
+ */
137
+ client: EnclaveClient;
138
+ /**
139
+ * Client configuration
140
+ */
141
+ config: EnclaveClientConfig;
142
+ }
package/src/types.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /**
3
+ * React Types
4
+ *
5
+ * Types for the EnclaveJS React hooks and components.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG","sourcesContent":["/**\n * React Types\n *\n * Types for the EnclaveJS React hooks and components.\n *\n * @packageDocumentation\n */\n\nimport type { EnclaveClient, EnclaveClientConfig, SessionResult, StreamEvent, SessionId } from '@enclave-vm/client';\n\n/**\n * Session state enum\n */\nexport type SessionState = 'idle' | 'running' | 'completed' | 'error' | 'cancelled';\n\n/**\n * useEnclaveSession hook options\n */\nexport interface UseEnclaveSessionOptions {\n /**\n * Custom session ID (generated if not provided)\n */\n sessionId?: SessionId;\n\n /**\n * Session timeout in milliseconds\n */\n timeoutMs?: number;\n\n /**\n * Maximum number of tool calls\n */\n maxToolCalls?: number;\n\n /**\n * Heartbeat interval in milliseconds\n */\n heartbeatIntervalMs?: number;\n\n /**\n * Callback when session starts\n */\n onStart?: () => void;\n\n /**\n * Callback for stdout output\n */\n onStdout?: (chunk: string) => void;\n\n /**\n * Callback for log messages\n */\n onLog?: (level: string, message: string, data?: Record<string, unknown>) => void;\n\n /**\n * Callback for tool calls\n */\n onToolCall?: (callId: string, toolName: string, args: unknown) => void;\n\n /**\n * Callback when tool result is applied\n */\n onToolResultApplied?: (callId: string) => void;\n\n /**\n * Callback on completion\n */\n onComplete?: (result: SessionResult) => void;\n\n /**\n * Callback on error\n */\n onError?: (error: { code?: string; message: string }) => void;\n}\n\n/**\n * useEnclaveSession hook return type\n */\nexport interface UseEnclaveSessionReturn<T = unknown> {\n /**\n * Execute code in the enclave\n */\n execute: (code: string) => Promise<SessionResult<T>>;\n\n /**\n * Cancel the current session\n */\n cancel: (reason?: string) => Promise<void>;\n\n /**\n * Current session state\n */\n state: SessionState;\n\n /**\n * Whether a session is currently running\n */\n isRunning: boolean;\n\n /**\n * Current session ID (if running)\n */\n sessionId: SessionId | null;\n\n /**\n * Result of the last execution (if completed)\n */\n result: SessionResult<T> | null;\n\n /**\n * Error from the last execution (if failed)\n */\n error: { code?: string; message: string } | null;\n\n /**\n * Stdout output accumulated during execution\n */\n stdout: string;\n\n /**\n * Events received during execution\n */\n events: StreamEvent[];\n\n /**\n * Reset the hook state\n */\n reset: () => void;\n}\n\n/**\n * EnclaveProvider props\n */\nexport interface EnclaveProviderProps {\n /**\n * Client configuration\n */\n config: EnclaveClientConfig;\n\n /**\n * Pre-created client instance (alternative to config)\n */\n client?: EnclaveClient;\n\n /**\n * Children to render\n */\n children: React.ReactNode;\n}\n\n/**\n * Enclave context value\n */\nexport interface EnclaveContextValue {\n /**\n * The EnclaveClient instance\n */\n client: EnclaveClient;\n\n /**\n * Client configuration\n */\n config: EnclaveClientConfig;\n}\n"]}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * useEnclaveSession Hook
3
+ *
4
+ * React hook for executing code in the EnclaveJS runtime with state management.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import type { UseEnclaveSessionOptions, UseEnclaveSessionReturn } from './types.js';
9
+ /**
10
+ * useEnclaveSession hook
11
+ *
12
+ * Provides a stateful interface for executing code in the Enclave runtime.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * function Calculator() {
17
+ * const { execute, isRunning, result, stdout } = useEnclaveSession({
18
+ * onStdout: (chunk) => console.log(chunk),
19
+ * });
20
+ *
21
+ * const calculate = async () => {
22
+ * const result = await execute('return 1 + 1');
23
+ * console.log('Result:', result.value);
24
+ * };
25
+ *
26
+ * return (
27
+ * <div>
28
+ * <button onClick={calculate} disabled={isRunning}>
29
+ * Calculate
30
+ * </button>
31
+ * {result && <p>Result: {JSON.stringify(result.value)}</p>}
32
+ * <pre>{stdout}</pre>
33
+ * </div>
34
+ * );
35
+ * }
36
+ * ```
37
+ */
38
+ export declare function useEnclaveSession<T = unknown>(options?: UseEnclaveSessionOptions): UseEnclaveSessionReturn<T>;
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ /**
3
+ * useEnclaveSession Hook
4
+ *
5
+ * React hook for executing code in the EnclaveJS runtime with state management.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.useEnclaveSession = useEnclaveSession;
11
+ const react_1 = require("react");
12
+ const EnclaveProvider_js_1 = require("./EnclaveProvider.js");
13
+ /**
14
+ * useEnclaveSession hook
15
+ *
16
+ * Provides a stateful interface for executing code in the Enclave runtime.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * function Calculator() {
21
+ * const { execute, isRunning, result, stdout } = useEnclaveSession({
22
+ * onStdout: (chunk) => console.log(chunk),
23
+ * });
24
+ *
25
+ * const calculate = async () => {
26
+ * const result = await execute('return 1 + 1');
27
+ * console.log('Result:', result.value);
28
+ * };
29
+ *
30
+ * return (
31
+ * <div>
32
+ * <button onClick={calculate} disabled={isRunning}>
33
+ * Calculate
34
+ * </button>
35
+ * {result && <p>Result: {JSON.stringify(result.value)}</p>}
36
+ * <pre>{stdout}</pre>
37
+ * </div>
38
+ * );
39
+ * }
40
+ * ```
41
+ */
42
+ function useEnclaveSession(options = {}) {
43
+ const client = (0, EnclaveProvider_js_1.useEnclaveClient)();
44
+ // State
45
+ const [state, setState] = (0, react_1.useState)('idle');
46
+ const [sessionId, setSessionId] = (0, react_1.useState)(null);
47
+ const [result, setResult] = (0, react_1.useState)(null);
48
+ const [error, setError] = (0, react_1.useState)(null);
49
+ const [stdout, setStdout] = (0, react_1.useState)('');
50
+ const [events, setEvents] = (0, react_1.useState)([]);
51
+ // Refs for current session handle
52
+ const handleRef = (0, react_1.useRef)(null);
53
+ /**
54
+ * Reset the hook state
55
+ */
56
+ const reset = (0, react_1.useCallback)(() => {
57
+ setState('idle');
58
+ setSessionId(null);
59
+ setResult(null);
60
+ setError(null);
61
+ setStdout('');
62
+ setEvents([]);
63
+ handleRef.current = null;
64
+ }, []);
65
+ /**
66
+ * Execute code in the enclave
67
+ */
68
+ const execute = (0, react_1.useCallback)(async (code) => {
69
+ // Reset state for new execution
70
+ setState('running');
71
+ setResult(null);
72
+ setError(null);
73
+ setStdout('');
74
+ setEvents([]);
75
+ // Call onStart callback
76
+ options.onStart?.();
77
+ // Build limits from options
78
+ const limits = {};
79
+ if (options.timeoutMs !== undefined) {
80
+ limits.sessionTtlMs = options.timeoutMs;
81
+ }
82
+ if (options.maxToolCalls !== undefined) {
83
+ limits.maxToolCalls = options.maxToolCalls;
84
+ }
85
+ if (options.heartbeatIntervalMs !== undefined) {
86
+ limits.heartbeatIntervalMs = options.heartbeatIntervalMs;
87
+ }
88
+ // Start streaming execution
89
+ const handle = client.executeStream(code, {
90
+ sessionId: options.sessionId,
91
+ limits: Object.keys(limits).length > 0 ? limits : undefined,
92
+ onEvent: (event) => {
93
+ setEvents((prev) => [...prev, event]);
94
+ },
95
+ onStdout: (chunk) => {
96
+ setStdout((prev) => prev + chunk);
97
+ options.onStdout?.(chunk);
98
+ },
99
+ onLog: (level, message, data) => {
100
+ options.onLog?.(level, message, data);
101
+ },
102
+ onToolCall: (callId, toolName, args) => {
103
+ options.onToolCall?.(callId, toolName, args);
104
+ },
105
+ onToolResultApplied: (callId) => {
106
+ options.onToolResultApplied?.(callId);
107
+ },
108
+ onError: (code, message) => {
109
+ options.onError?.({ code, message });
110
+ },
111
+ });
112
+ handleRef.current = handle;
113
+ setSessionId(handle.sessionId);
114
+ try {
115
+ // Wait for completion
116
+ const sessionResult = (await handle.wait());
117
+ // Update state based on result
118
+ if (sessionResult.success) {
119
+ setState('completed');
120
+ setResult(sessionResult);
121
+ }
122
+ else if (sessionResult.error?.code === 'CANCELLED') {
123
+ setState('cancelled');
124
+ setResult(sessionResult);
125
+ }
126
+ else {
127
+ setState('error');
128
+ setResult(sessionResult);
129
+ setError(sessionResult.error ?? { message: 'Unknown error' });
130
+ options.onError?.(sessionResult.error ?? { message: 'Unknown error' });
131
+ }
132
+ // Call onComplete callback
133
+ options.onComplete?.(sessionResult);
134
+ return sessionResult;
135
+ }
136
+ catch (err) {
137
+ // Handle unexpected errors
138
+ const errorInfo = {
139
+ code: 'UNEXPECTED_ERROR',
140
+ message: err instanceof Error ? err.message : 'Unknown error',
141
+ };
142
+ setState('error');
143
+ setError(errorInfo);
144
+ options.onError?.(errorInfo);
145
+ // Return error result
146
+ const errorResult = {
147
+ success: false,
148
+ sessionId: handle.sessionId,
149
+ error: errorInfo,
150
+ events: handle.getEvents(),
151
+ };
152
+ setResult(errorResult);
153
+ options.onComplete?.(errorResult);
154
+ return errorResult;
155
+ }
156
+ finally {
157
+ handleRef.current = null;
158
+ }
159
+ }, [client, options]);
160
+ /**
161
+ * Cancel the current session
162
+ */
163
+ const cancel = (0, react_1.useCallback)(async (reason) => {
164
+ if (handleRef.current) {
165
+ await handleRef.current.cancel(reason);
166
+ }
167
+ }, []);
168
+ return {
169
+ execute,
170
+ cancel,
171
+ state,
172
+ isRunning: state === 'running',
173
+ sessionId,
174
+ result,
175
+ error,
176
+ stdout,
177
+ events,
178
+ reset,
179
+ };
180
+ }
181
+ //# sourceMappingURL=useEnclaveSession.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEnclaveSession.js","sourceRoot":"","sources":["../../src/useEnclaveSession.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * useEnclaveSession Hook\n *\n * React hook for executing code in the EnclaveJS runtime with state management.\n *\n * @packageDocumentation\n */\n\nimport { useState, useCallback, useRef } from 'react';\nimport type { SessionResult, SessionHandle, StreamEvent, SessionId } from '@enclave-vm/client';\nimport { useEnclaveClient } from './EnclaveProvider.js';\nimport type { SessionState, UseEnclaveSessionOptions, UseEnclaveSessionReturn } from './types.js';\n\n/**\n * useEnclaveSession hook\n *\n * Provides a stateful interface for executing code in the Enclave runtime.\n *\n * @example\n * ```tsx\n * function Calculator() {\n * const { execute, isRunning, result, stdout } = useEnclaveSession({\n * onStdout: (chunk) => console.log(chunk),\n * });\n *\n * const calculate = async () => {\n * const result = await execute('return 1 + 1');\n * console.log('Result:', result.value);\n * };\n *\n * return (\n * <div>\n * <button onClick={calculate} disabled={isRunning}>\n * Calculate\n * </button>\n * {result && <p>Result: {JSON.stringify(result.value)}</p>}\n * <pre>{stdout}</pre>\n * </div>\n * );\n * }\n * ```\n */\nexport function useEnclaveSession<T = unknown>(options: UseEnclaveSessionOptions = {}): UseEnclaveSessionReturn<T> {\n const client = useEnclaveClient();\n\n // State\n const [state, setState] = useState<SessionState>('idle');\n const [sessionId, setSessionId] = useState<SessionId | null>(null);\n const [result, setResult] = useState<SessionResult<T> | null>(null);\n const [error, setError] = useState<{ code?: string; message: string } | null>(null);\n const [stdout, setStdout] = useState<string>('');\n const [events, setEvents] = useState<StreamEvent[]>([]);\n\n // Refs for current session handle\n const handleRef = useRef<SessionHandle | null>(null);\n\n /**\n * Reset the hook state\n */\n const reset = useCallback(() => {\n setState('idle');\n setSessionId(null);\n setResult(null);\n setError(null);\n setStdout('');\n setEvents([]);\n handleRef.current = null;\n }, []);\n\n /**\n * Execute code in the enclave\n */\n const execute = useCallback(\n async (code: string): Promise<SessionResult<T>> => {\n // Reset state for new execution\n setState('running');\n setResult(null);\n setError(null);\n setStdout('');\n setEvents([]);\n\n // Call onStart callback\n options.onStart?.();\n\n // Build limits from options\n const limits: Record<string, number> = {};\n if (options.timeoutMs !== undefined) {\n limits.sessionTtlMs = options.timeoutMs;\n }\n if (options.maxToolCalls !== undefined) {\n limits.maxToolCalls = options.maxToolCalls;\n }\n if (options.heartbeatIntervalMs !== undefined) {\n limits.heartbeatIntervalMs = options.heartbeatIntervalMs;\n }\n\n // Start streaming execution\n const handle = client.executeStream(code, {\n sessionId: options.sessionId,\n limits: Object.keys(limits).length > 0 ? limits : undefined,\n onEvent: (event) => {\n setEvents((prev) => [...prev, event]);\n },\n onStdout: (chunk) => {\n setStdout((prev) => prev + chunk);\n options.onStdout?.(chunk);\n },\n onLog: (level, message, data) => {\n options.onLog?.(level, message, data);\n },\n onToolCall: (callId, toolName, args) => {\n options.onToolCall?.(callId, toolName, args);\n },\n onToolResultApplied: (callId) => {\n options.onToolResultApplied?.(callId);\n },\n onError: (code, message) => {\n options.onError?.({ code, message });\n },\n });\n\n handleRef.current = handle;\n setSessionId(handle.sessionId);\n\n try {\n // Wait for completion\n const sessionResult = (await handle.wait()) as SessionResult<T>;\n\n // Update state based on result\n if (sessionResult.success) {\n setState('completed');\n setResult(sessionResult);\n } else if (sessionResult.error?.code === 'CANCELLED') {\n setState('cancelled');\n setResult(sessionResult);\n } else {\n setState('error');\n setResult(sessionResult);\n setError(sessionResult.error ?? { message: 'Unknown error' });\n options.onError?.(sessionResult.error ?? { message: 'Unknown error' });\n }\n\n // Call onComplete callback\n options.onComplete?.(sessionResult);\n\n return sessionResult;\n } catch (err) {\n // Handle unexpected errors\n const errorInfo = {\n code: 'UNEXPECTED_ERROR',\n message: err instanceof Error ? err.message : 'Unknown error',\n };\n\n setState('error');\n setError(errorInfo);\n options.onError?.(errorInfo);\n\n // Return error result\n const errorResult: SessionResult<T> = {\n success: false,\n sessionId: handle.sessionId,\n error: errorInfo,\n events: handle.getEvents(),\n };\n\n setResult(errorResult);\n options.onComplete?.(errorResult);\n\n return errorResult;\n } finally {\n handleRef.current = null;\n }\n },\n [client, options],\n );\n\n /**\n * Cancel the current session\n */\n const cancel = useCallback(async (reason?: string): Promise<void> => {\n if (handleRef.current) {\n await handleRef.current.cancel(reason);\n }\n }, []);\n\n return {\n execute,\n cancel,\n state,\n isRunning: state === 'running',\n sessionId,\n result,\n error,\n stdout,\n events,\n reset,\n };\n}\n"]}