@trustgraph/react-state 1.4.1 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -150,12 +150,7 @@ const useSessionStore = zustand.create()((set) => ({
150
150
  }));
151
151
 
152
152
  const useConversation = zustand.create()((set) => ({
153
- messages: [
154
- {
155
- role: "ai",
156
- text: "Welcome to the TrustGraph Test Suite. Use the chat interface to perform Graph RAG requests.",
157
- },
158
- ],
153
+ messages: [],
159
154
  input: "",
160
155
  chatMode: "graph-rag",
161
156
  setMessages: (v) => set(() => ({
@@ -931,17 +926,19 @@ const useTriples = ({ flow, s, p, o, limit, collection }) => {
931
926
  const notify = useNotification();
932
927
  // Settings for default collection
933
928
  const { settings } = useSettings();
934
- if (!flow)
935
- flow = "default";
929
+ // Session state for default flow ID
930
+ const sessionFlowId = useSessionStore((state) => state.flowId);
931
+ // Use explicit param if provided, otherwise fall back to session state
932
+ const effectiveFlow = flow ?? sessionFlowId;
936
933
  /**
937
934
  * Query for fetching all token costs
938
935
  * Uses React Query for caching and background refetching
939
936
  */
940
937
  const query = reactQuery.useQuery({
941
- queryKey: ["triples", { flow, s, p, o, limit }],
938
+ queryKey: ["triples", { flow: effectiveFlow, s, p, o, limit }],
942
939
  queryFn: () => {
943
940
  return socket
944
- .flow(flow)
941
+ .flow(effectiveFlow)
945
942
  .triplesQuery(s, p, o, limit, collection || settings.collection)
946
943
  .then((x) => {
947
944
  if (x["error"]) {
@@ -1307,13 +1304,17 @@ const updateSubgraphByRelationship = (socket, selectedNodeId, relationshipUri, d
1307
1304
  * Custom hook for managing graph visualization operations using React Query
1308
1305
  * Provides functionality for fetching and updating graph subgraphs
1309
1306
  * @param entityUri - The URI of the entity to build the graph around
1310
- * @param flowId - The flow ID to use for the query
1307
+ * @param flow - Optional flow ID to use for the query (defaults to session state)
1311
1308
  * @param collection - The collection to query
1312
1309
  * @returns {Object} Graph state and operations
1313
1310
  */
1314
- const useGraphSubgraph = (entityUri, flowId, collection) => {
1311
+ const useGraphSubgraph = ({ entityUri, flow, collection, }) => {
1315
1312
  // WebSocket connection for communicating with the graph service
1316
1313
  const socket = reactProvider.useSocket();
1314
+ // Session state for default flow ID
1315
+ const sessionFlowId = useSessionStore((state) => state.flowId);
1316
+ // Use explicit param if provided, otherwise fall back to session state
1317
+ const effectiveFlow = flow ?? sessionFlowId;
1317
1318
  const addActivity = useProgressStateStore((state) => state.addActivity);
1318
1319
  const removeActivity = useProgressStateStore((state) => state.removeActivity);
1319
1320
  // Hook for displaying user notifications
@@ -1325,29 +1326,29 @@ const useGraphSubgraph = (entityUri, flowId, collection) => {
1325
1326
  * Uses React Query for caching and background refetching
1326
1327
  */
1327
1328
  const query = reactQuery.useQuery({
1328
- queryKey: ["graph-subgraph", { entityUri, flowId, collection }],
1329
+ queryKey: ["graph-subgraph", { entityUri, flow: effectiveFlow, collection }],
1329
1330
  queryFn: async () => {
1330
1331
  if (!entityUri) {
1331
1332
  throw new Error("Entity URI is required");
1332
1333
  }
1333
1334
  const sg = createSubgraph();
1334
1335
  // Use the existing updateSubgraph utility function for initial load
1335
- const api = socket.flow(flowId);
1336
+ const api = socket.flow(effectiveFlow);
1336
1337
  return updateSubgraph(api, entityUri, sg, addActivity, removeActivity, collection);
1337
1338
  },
1338
- enabled: !!entityUri && !!flowId, // Only run query if both entityUri and flowId are available
1339
+ enabled: !!entityUri && !!effectiveFlow, // Only run query if both entityUri and effectiveFlow are available
1339
1340
  });
1340
1341
  /**
1341
1342
  * Mutation for updating the graph subgraph when nodes are clicked
1342
1343
  */
1343
1344
  const updateMutation = reactQuery.useMutation({
1344
1345
  mutationFn: async ({ nodeId, currentGraph, }) => {
1345
- const api = socket.flow(flowId);
1346
+ const api = socket.flow(effectiveFlow);
1346
1347
  return updateSubgraph(api, nodeId, currentGraph, addActivity, removeActivity);
1347
1348
  },
1348
1349
  onSuccess: (newGraph) => {
1349
1350
  // Update the cache with the new graph data
1350
- queryClient.setQueryData(["graph-subgraph", { entityUri, flowId, collection }], newGraph);
1351
+ queryClient.setQueryData(["graph-subgraph", { entityUri, flow: effectiveFlow, collection }], newGraph);
1351
1352
  },
1352
1353
  onError: (err) => {
1353
1354
  console.log("Graph update error:", err);
@@ -1359,12 +1360,12 @@ const useGraphSubgraph = (entityUri, flowId, collection) => {
1359
1360
  */
1360
1361
  const relationshipNavigationMutation = reactQuery.useMutation({
1361
1362
  mutationFn: async ({ selectedNodeId, relationshipUri, direction, currentGraph, }) => {
1362
- const api = socket.flow(flowId);
1363
+ const api = socket.flow(effectiveFlow);
1363
1364
  return updateSubgraphByRelationship(api, selectedNodeId, relationshipUri, direction, currentGraph, addActivity, removeActivity, collection);
1364
1365
  },
1365
1366
  onSuccess: (newGraph) => {
1366
1367
  // Update the cache with the new graph data
1367
- queryClient.setQueryData(["graph-subgraph", { entityUri, flowId, collection }], newGraph);
1368
+ queryClient.setQueryData(["graph-subgraph", { entityUri, flow: effectiveFlow, collection }], newGraph);
1368
1369
  },
1369
1370
  onError: (err) => {
1370
1371
  console.log("Relationship navigation error:", err);
@@ -1410,17 +1411,19 @@ const useGraphEmbeddings = ({ flow, vecs, limit, collection }) => {
1410
1411
  const notify = useNotification();
1411
1412
  // Settings for default collection
1412
1413
  const { settings } = useSettings();
1413
- if (!flow)
1414
- flow = "default";
1414
+ // Session state for default flow ID
1415
+ const sessionFlowId = useSessionStore((state) => state.flowId);
1416
+ // Use explicit param if provided, otherwise fall back to session state
1417
+ const effectiveFlow = flow ?? sessionFlowId;
1415
1418
  /**
1416
1419
  * Query for fetching graph embeddings
1417
1420
  * Uses React Query for caching and background refetching
1418
1421
  */
1419
1422
  const query = reactQuery.useQuery({
1420
- queryKey: ["graph-embeddings", { vecs, limit }],
1423
+ queryKey: ["graph-embeddings", { flow: effectiveFlow, vecs, limit }],
1421
1424
  queryFn: () => {
1422
1425
  return socket
1423
- .flow(flow)
1426
+ .flow(effectiveFlow)
1424
1427
  .graphEmbeddingsQuery(vecs, limit, collection || settings.collection)
1425
1428
  .then((x) => {
1426
1429
  return x;
@@ -1626,6 +1629,8 @@ const useVectorSearch = () => {
1626
1629
  const removeActivity = useProgressStateStore((state) => state.removeActivity);
1627
1630
  // Hook for displaying user notifications
1628
1631
  const notify = useNotification();
1632
+ // Session state for default flow ID
1633
+ const sessionFlowId = useSessionStore((state) => state.flowId);
1629
1634
  // State to track current search parameters
1630
1635
  const [searchParams, setSearchParams] = react.useState(null);
1631
1636
  /**
@@ -1637,7 +1642,7 @@ const useVectorSearch = () => {
1637
1642
  enabled: !!searchParams?.term,
1638
1643
  queryFn: () => {
1639
1644
  const { flow, term, limit, collection } = searchParams;
1640
- return vectorSearch(socket, flow || "default", addActivity, removeActivity, term, collection, limit)
1645
+ return vectorSearch(socket, flow ?? sessionFlowId, addActivity, removeActivity, term, collection, limit)
1641
1646
  .then((x) => {
1642
1647
  if (x["error"]) {
1643
1648
  console.log("Error:", x);
@@ -1659,7 +1664,7 @@ const useVectorSearch = () => {
1659
1664
  return;
1660
1665
  }
1661
1666
  setSearchParams({
1662
- flow: flow || "default",
1667
+ flow: flow ?? sessionFlowId,
1663
1668
  term,
1664
1669
  limit: limit || 10,
1665
1670
  collection,
@@ -1683,13 +1688,17 @@ const useVectorSearch = () => {
1683
1688
  * Custom hook for managing entity detail operations using React Query
1684
1689
  * Provides functionality for fetching entity details and related triples
1685
1690
  * @param entityUri - The URI of the entity to fetch details for
1686
- * @param flowId - The flow ID to use for the query
1691
+ * @param flow - Optional flow ID to use for the query (defaults to session state)
1687
1692
  * @param collection - The collection to query
1688
1693
  * @returns {Object} Entity detail state and operations
1689
1694
  */
1690
- const useEntityDetail = (entityUri, flowId, collection) => {
1695
+ const useEntityDetail = ({ entityUri, flow, collection, }) => {
1691
1696
  // WebSocket connection for communicating with the graph service
1692
1697
  const socket = reactProvider.useSocket();
1698
+ // Session state for default flow ID
1699
+ const sessionFlowId = useSessionStore((state) => state.flowId);
1700
+ // Use explicit param if provided, otherwise fall back to session state
1701
+ const effectiveFlow = flow ?? sessionFlowId;
1693
1702
  const addActivity = useProgressStateStore((state) => state.addActivity);
1694
1703
  const removeActivity = useProgressStateStore((state) => state.removeActivity);
1695
1704
  // Hook for displaying user notifications
@@ -1699,17 +1708,17 @@ const useEntityDetail = (entityUri, flowId, collection) => {
1699
1708
  * Uses React Query for caching and background refetching
1700
1709
  */
1701
1710
  const query = reactQuery.useQuery({
1702
- queryKey: ["entity-detail", { entityUri, flowId, collection }],
1711
+ queryKey: ["entity-detail", { entityUri, flow: effectiveFlow, collection }],
1703
1712
  queryFn: async () => {
1704
1713
  if (!entityUri) {
1705
1714
  throw new Error("Entity URI is required");
1706
1715
  }
1707
1716
  // Use the existing getTriples utility function
1708
- const api = socket.flow(flowId);
1717
+ const api = socket.flow(effectiveFlow);
1709
1718
  return getTriples(api, entityUri, addActivity, removeActivity, undefined, collection);
1710
1719
  },
1711
- // Only run query if both entityUri and flowId are available
1712
- enabled: !!entityUri && !!flowId,
1720
+ // Only run query if both entityUri and effectiveFlow are available
1721
+ enabled: !!entityUri && !!effectiveFlow,
1713
1722
  });
1714
1723
  // Show loading indicators for long-running operations
1715
1724
  useActivity(query.isLoading, entityUri ? `Knowledge graph search: ${entityUri}` : "Loading entity");
@@ -1733,9 +1742,11 @@ const useEntityDetail = (entityUri, flowId, collection) => {
1733
1742
  * Hook providing low-level access to LLM inference services
1734
1743
  * No conversation state or side effects - just the API calls
1735
1744
  */
1736
- const useInference = () => {
1745
+ const useInference = ({ flow } = {}) => {
1737
1746
  const socket = reactProvider.useSocket();
1738
- const flowId = useSessionStore((state) => state.flowId);
1747
+ const sessionFlowId = useSessionStore((state) => state.flowId);
1748
+ // Use explicit param if provided, otherwise fall back to session state
1749
+ const effectiveFlow = flow ?? sessionFlowId;
1739
1750
  /**
1740
1751
  * Graph RAG inference with entity discovery
1741
1752
  */
@@ -1757,15 +1768,15 @@ const useInference = () => {
1757
1768
  reject(new Error(error));
1758
1769
  };
1759
1770
  socket
1760
- .flow(flowId)
1771
+ .flow(effectiveFlow)
1761
1772
  .graphRagStreaming(input, onChunk, onError, options, collection);
1762
1773
  })
1763
- : await socket.flow(flowId).graphRag(input, options || {}, collection);
1774
+ : await socket.flow(effectiveFlow).graphRag(input, options || {}, collection);
1764
1775
  // Get embeddings for entity discovery
1765
- const embeddings = await socket.flow(flowId).embeddings(input);
1776
+ const embeddings = await socket.flow(effectiveFlow).embeddings(input);
1766
1777
  // Query graph embeddings to find entities
1767
1778
  const entities = await socket
1768
- .flow(flowId)
1779
+ .flow(effectiveFlow)
1769
1780
  .graphEmbeddingsQuery(embeddings, options?.entityLimit || 10, collection);
1770
1781
  return { response, entities };
1771
1782
  },
@@ -1791,10 +1802,10 @@ const useInference = () => {
1791
1802
  reject(new Error(error));
1792
1803
  };
1793
1804
  socket
1794
- .flow(flowId)
1805
+ .flow(effectiveFlow)
1795
1806
  .textCompletionStreaming(systemPrompt, input, onChunk, onError);
1796
1807
  })
1797
- : await socket.flow(flowId).textCompletion(systemPrompt, input);
1808
+ : await socket.flow(effectiveFlow).textCompletion(systemPrompt, input);
1798
1809
  },
1799
1810
  });
1800
1811
  /**
@@ -1822,7 +1833,7 @@ const useInference = () => {
1822
1833
  reject(new Error(error));
1823
1834
  };
1824
1835
  socket
1825
- .flow(flowId)
1836
+ .flow(effectiveFlow)
1826
1837
  .agent(input, onThink, onObserve, onAnswer, onError);
1827
1838
  });
1828
1839
  },
@@ -1842,7 +1853,7 @@ const useInference = () => {
1842
1853
  * Combines conversation state with inference services
1843
1854
  * Handles routing, progress tracking, entity management, and notifications
1844
1855
  */
1845
- const useChatSession = () => {
1856
+ const useChatSession = ({ flow } = {}) => {
1846
1857
  const socket = reactProvider.useSocket();
1847
1858
  const notify = useNotification();
1848
1859
  // Conversation state
@@ -1854,12 +1865,14 @@ const useChatSession = () => {
1854
1865
  const addActivity = useProgressStateStore((state) => state.addActivity);
1855
1866
  const removeActivity = useProgressStateStore((state) => state.removeActivity);
1856
1867
  // Session and workbench state
1857
- const flowId = useSessionStore((state) => state.flowId);
1868
+ const sessionFlowId = useSessionStore((state) => state.flowId);
1858
1869
  const setEntities = useWorkbenchStateStore((state) => state.setEntities);
1870
+ // Use explicit param if provided, otherwise fall back to session state
1871
+ const effectiveFlow = flow ?? sessionFlowId;
1859
1872
  // Settings for GraphRAG configuration
1860
1873
  const { settings } = useSettings();
1861
1874
  // Inference services
1862
- const inference = useInference();
1875
+ const inference = useInference({ flow });
1863
1876
  /**
1864
1877
  * Graph RAG chat handling with entity discovery
1865
1878
  */
@@ -1904,7 +1917,7 @@ const useChatSession = () => {
1904
1917
  addActivity(labelActivity);
1905
1918
  try {
1906
1919
  const triples = await socket
1907
- .flow(flowId)
1920
+ .flow(effectiveFlow)
1908
1921
  .triplesQuery(entity, { t: "i", i: RDFS_LABEL }, undefined, 1, settings.collection);
1909
1922
  removeActivity(labelActivity);
1910
1923
  return triples;
@@ -2166,16 +2179,18 @@ const useStructuredQuery = () => {
2166
2179
  * Provides functionality for executing semantic searches on structured data indexes
2167
2180
  * First converts query text to embeddings, then searches for similar records
2168
2181
  */
2169
- const useRowEmbeddingsQuery = () => {
2182
+ const useRowEmbeddingsQuery = ({ flow } = {}) => {
2170
2183
  // Socket connection for API calls
2171
2184
  const socket = reactProvider.useSocket();
2172
2185
  const connectionState = reactProvider.useConnectionState();
2173
2186
  // Notification system for user feedback
2174
2187
  const notify = useNotification();
2175
2188
  // Session state for current flow ID
2176
- const flowId = useSessionStore((state) => state.flowId);
2189
+ const sessionFlowId = useSessionStore((state) => state.flowId);
2177
2190
  // Settings for default collection
2178
2191
  const { settings } = useSettings();
2192
+ // Use explicit param if provided, otherwise fall back to session state
2193
+ const effectiveFlow = flow ?? sessionFlowId;
2179
2194
  // Only enable operations when socket is connected and ready
2180
2195
  const isSocketReady = connectionState?.status === "authenticated" ||
2181
2196
  connectionState?.status === "unauthenticated";
@@ -2185,11 +2200,11 @@ const useRowEmbeddingsQuery = () => {
2185
2200
  if (!isSocketReady) {
2186
2201
  throw new Error("Socket connection not ready");
2187
2202
  }
2188
- const flow = socket.flow(flowId);
2203
+ const flowApi = socket.flow(effectiveFlow);
2189
2204
  // First, get embeddings for the query text
2190
- const vectors = await flow.embeddings(query);
2205
+ const vectors = await flowApi.embeddings(query);
2191
2206
  // Then query row embeddings with those vectors
2192
- return flow.rowEmbeddingsQuery(vectors, schemaName, collection || settings.collection, indexName, limit || 10);
2207
+ return flowApi.rowEmbeddingsQuery(vectors, schemaName, collection || settings.collection, indexName, limit || 10);
2193
2208
  },
2194
2209
  onError: (err) => {
2195
2210
  console.log("Row embeddings query error:", err);
@@ -2232,14 +2247,16 @@ const useRowEmbeddingsQuery = () => {
2232
2247
  * Custom hook for managing GraphQL rows queries
2233
2248
  * Provides functionality for executing GraphQL queries against structured row data
2234
2249
  */
2235
- const useRowsQuery = () => {
2250
+ const useRowsQuery = ({ flow } = {}) => {
2236
2251
  // Socket connection for API calls
2237
2252
  const socket = reactProvider.useSocket();
2238
2253
  const connectionState = reactProvider.useConnectionState();
2239
2254
  // Notification system for user feedback
2240
2255
  const notify = useNotification();
2241
2256
  // Session state for current flow ID
2242
- const flowId = useSessionStore((state) => state.flowId);
2257
+ const sessionFlowId = useSessionStore((state) => state.flowId);
2258
+ // Use explicit param if provided, otherwise fall back to session state
2259
+ const effectiveFlow = flow ?? sessionFlowId;
2243
2260
  // Settings for default collection
2244
2261
  const { settings } = useSettings();
2245
2262
  // Only enable operations when socket is connected and ready
@@ -2252,7 +2269,7 @@ const useRowsQuery = () => {
2252
2269
  throw new Error("Socket connection not ready");
2253
2270
  }
2254
2271
  return socket
2255
- .flow(flowId)
2272
+ .flow(effectiveFlow)
2256
2273
  .rowsQuery(query, collection || settings.collection, variables, operationName);
2257
2274
  },
2258
2275
  onError: (err) => {
@@ -2298,18 +2315,20 @@ const useEmbeddings = ({ flow, term }) => {
2298
2315
  connectionState?.status === "unauthenticated";
2299
2316
  // Hook for displaying user notifications
2300
2317
  const notify = useNotification();
2301
- if (!flow)
2302
- flow = "default";
2318
+ // Session state for default flow ID
2319
+ const sessionFlowId = useSessionStore((state) => state.flowId);
2320
+ // Use explicit param if provided, otherwise fall back to session state
2321
+ const effectiveFlow = flow ?? sessionFlowId;
2303
2322
  /**
2304
2323
  * Query for fetching all token costs
2305
2324
  * Uses React Query for caching and background refetching
2306
2325
  */
2307
2326
  const query = reactQuery.useQuery({
2308
- queryKey: ["embeddings", { flow, term }],
2309
- enabled: isSocketReady && !!term && !!flow,
2327
+ queryKey: ["embeddings", { flow: effectiveFlow, term }],
2328
+ enabled: isSocketReady && !!term && !!effectiveFlow,
2310
2329
  queryFn: () => {
2311
2330
  return socket
2312
- .flow(flow)
2331
+ .flow(effectiveFlow)
2313
2332
  .embeddings(term)
2314
2333
  .then((x) => {
2315
2334
  if (x["error"]) {
@@ -2447,14 +2466,16 @@ const useCollections = () => {
2447
2466
  * Custom hook for managing NLP query operations
2448
2467
  * Provides functionality for converting natural language questions to GraphQL queries
2449
2468
  */
2450
- const useNlpQuery = () => {
2469
+ const useNlpQuery = ({ flow } = {}) => {
2451
2470
  // Socket connection for API calls
2452
2471
  const socket = reactProvider.useSocket();
2453
2472
  const connectionState = reactProvider.useConnectionState();
2454
2473
  // Notification system for user feedback
2455
2474
  const notify = useNotification();
2456
2475
  // Session state for current flow ID
2457
- const flowId = useSessionStore((state) => state.flowId);
2476
+ const sessionFlowId = useSessionStore((state) => state.flowId);
2477
+ // Use explicit param if provided, otherwise fall back to session state
2478
+ const effectiveFlow = flow ?? sessionFlowId;
2458
2479
  // Only enable operations when socket is connected and ready
2459
2480
  const isSocketReady = connectionState?.status === "authenticated" ||
2460
2481
  connectionState?.status === "unauthenticated";
@@ -2464,7 +2485,7 @@ const useNlpQuery = () => {
2464
2485
  if (!isSocketReady) {
2465
2486
  throw new Error("Socket connection not ready");
2466
2487
  }
2467
- return socket.flow(flowId).nlpQuery(question, maxResults);
2488
+ return socket.flow(effectiveFlow).nlpQuery(question, maxResults);
2468
2489
  },
2469
2490
  onError: (err) => {
2470
2491
  console.log("NLP query error:", err);