From 39fff12b669d4fb1168ea8cd3bf91efba283abe9 Mon Sep 17 00:00:00 2001 From: Seweryn Kras Date: Thu, 25 Jan 2024 18:44:50 +0100 Subject: [PATCH 1/7] feat(provider): allow using provider without yagna app-key Removed the mandatory config parameter from YagnaProvider. Added functions to `useYagna`'s export to set/unset/see the app-key. BREAKING CHANGE: YagnaProvider can now be used without a yagna app-key. The key can now be set using the `useYagna` hook. --- .prettierrc | 4 ++ packages/react/package.json | 1 + packages/react/src/index.ts | 6 ++- packages/react/src/provider.tsx | 61 ++++++++++++++++-------- packages/react/src/useDebitNotes.ts | 12 ++++- packages/react/src/useExecutor.ts | 14 ++---- packages/react/src/useHandleDebitNote.ts | 17 +++++-- packages/react/src/useHandleInvoice.ts | 17 +++++-- packages/react/src/useTask.ts | 2 +- packages/react/src/useYagna.ts | 24 ++++++++-- 10 files changed, 112 insertions(+), 46 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..222861c --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "tabWidth": 2, + "useTabs": false +} diff --git a/packages/react/package.json b/packages/react/package.json index 166901d..f724f31 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -55,6 +55,7 @@ "dist" ], "scripts": { + "dev": "tsc -w -p tsconfig.build.json --module esNext --outDir dist/esm --target es6", "clean": "rimraf dist", "build": "npm run clean && npm run build:cjs && npm run build:esm", "build:cjs": "tsc -p tsconfig.build.json --module commonjs --outDir dist/cjs --target es5", diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index f3efb31..ac1989c 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -2,7 +2,11 @@ export { YagnaProvider } from "./provider"; export { useYagna } from "./useYagna"; export { useExecutor, TaskExecutor, type ExecutorOptions } from "./useExecutor"; export { useTask, type Worker } from "./useTask"; -export { useInvoices, InvoiceStatus } from "./useInvoices"; +export { + useInvoices, + InvoiceStatus, + type InvoiceSearchParameters, +} from "./useInvoices"; export { useDebitNotes } from "./useDebitNotes"; export { useHandleInvoice } from "./useHandleInvoice"; export { useHandleDebitNote } from "./useHandleDebitNote"; diff --git a/packages/react/src/provider.tsx b/packages/react/src/provider.tsx index 5c8356e..31ff9f8 100644 --- a/packages/react/src/provider.tsx +++ b/packages/react/src/provider.tsx @@ -2,17 +2,22 @@ import React, { createContext, PropsWithChildren } from "react"; import { Yagna } from "@golem-sdk/golem-js"; export interface YagnaContext { - yagnaClient: Yagna; yagnaOptions: { - apiKey: string; + client?: Yagna; + apiKey: string | null; basePath: string; }; swrKey: string; + + setYagnaOptions: (options: { + apiKey: string | null; + basePath?: string; + }) => void; } export const yagnaContext = createContext(undefined); export type YagnaProviderConfig = { - yagnaAppKey: string; + yagnaAppKey?: string; yagnaUrl?: string; swrKey?: string; }; @@ -21,7 +26,7 @@ export type YagnaProviderConfig = { * Provides context for all hooks that interact with Yagna. * * @param config - The configuration object for the provider. - * @param config.yagnaAppKey - The API key for the Yagna client. This is required. + * @param config.yagnaAppKey - The API key for the Yagna client. This is optional and can be set later with `useYagna` * @param config.yagnaUrl - The base URL for the Yagna client. This is optional and defaults to "http://127.0.0.1:7465". * @param config.swrKey - The key used to prefix all SWR cache keys. This is optional and defaults to "golem-sdk". * @@ -36,25 +41,41 @@ export function YagnaProvider({ children, config, }: PropsWithChildren<{ - config: YagnaProviderConfig; + config?: YagnaProviderConfig; }>) { - const yagnaClient = new Yagna({ - apiKey: config.yagnaAppKey, - basePath: config.yagnaUrl, + const [options, setOptions] = React.useState({ + swrKey: config?.swrKey || "golem-sdk", + yagnaOptions: { + apiKey: config?.yagnaAppKey || null, + basePath: config?.yagnaUrl || "http://127.0.0.1:7465", + client: config?.yagnaAppKey + ? new Yagna({ + apiKey: config?.yagnaAppKey, + basePath: config?.yagnaUrl || "http://127.0.0.1:7465", + }) + : undefined, + }, + setYagnaOptions: (options) => { + setOptions((prev) => { + const newClient = options.apiKey + ? new Yagna({ + apiKey: options.apiKey, + basePath: options.basePath || prev.yagnaOptions.basePath, + }) + : undefined; + return { + ...prev, + yagnaOptions: { + ...prev.yagnaOptions, + ...options, + client: newClient, + }, + }; + }); + }, }); return ( - - {children} - + {children} ); } diff --git a/packages/react/src/useDebitNotes.ts b/packages/react/src/useDebitNotes.ts index 0d3791b..024f8eb 100644 --- a/packages/react/src/useDebitNotes.ts +++ b/packages/react/src/useDebitNotes.ts @@ -48,11 +48,19 @@ export function useDebitNotes({ limit?: number; swrConfig?: SWRConfiguration; } = {}) { - const { yagnaClient, swrKey } = useConfig(); + const { + yagnaOptions: { client: yagnaClient }, + swrKey, + } = useConfig(); const { data, isLoading, isValidating, error, mutate } = useSWR( - [swrKey, "debit-notes", limit], + [swrKey, "debit-notes", limit, yagnaClient], async () => { + if (!yagnaClient) { + throw new Error( + "Connection to Yagna is not established, use `useYagna` hook to set the app key and connect.", + ); + } return ( yagnaClient .getApi() diff --git a/packages/react/src/useExecutor.ts b/packages/react/src/useExecutor.ts index d6d0f11..55017bc 100644 --- a/packages/react/src/useExecutor.ts +++ b/packages/react/src/useExecutor.ts @@ -46,6 +46,11 @@ export function useExecutor( if (isInitialized || isInitializing) { throw new Error("Executor is already initialized"); } + if (!config.yagnaOptions.apiKey) { + throw new Error( + "Connection to Yagna is not established, use `useYagna` hook to set the app key and connect.", + ); + } setIsInitializing(true); @@ -58,15 +63,6 @@ export function useExecutor( apiKey: config.yagnaOptions.apiKey, basePath: config.yagnaOptions.basePath, }, - logger: { - log: (msg) => console.log(msg), - info: (msg) => console.log(msg), - warn: (msg) => console.log(msg), - error: (msg) => console.log(msg), - debug: (msg) => console.log(msg), - level: "debug", - setLevel: (level) => console.log(level), - }, enableLogging: false, ...options, }); diff --git a/packages/react/src/useHandleDebitNote.ts b/packages/react/src/useHandleDebitNote.ts index d7cd690..44ed757 100644 --- a/packages/react/src/useHandleDebitNote.ts +++ b/packages/react/src/useHandleDebitNote.ts @@ -26,7 +26,9 @@ export function useHandleDebitNote( debitNote: string, { onAccepted, onRejected, allocationTimeoutMs = 60_000 }: Options = {}, ) { - const { yagnaClient } = useConfig(); + const { + yagnaOptions: { client }, + } = useConfig(); const [isLoading, setIsLoading] = useState(false); const [isAccepted, setIsAccepted] = useState(false); const [error, setError] = useState(); @@ -41,10 +43,15 @@ export function useHandleDebitNote( if (isLoading) { return; } + if (!client) { + throw new Error( + "Connection to Yagna is not established, use `useYagna` hook to set the app key and connect.", + ); + } reset(); setIsLoading(true); try { - const debitNoteDetails = await yagnaClient + const debitNoteDetails = await client .getApi() .payment.getDebitNote(debitNote) .then((res) => res.data); @@ -59,11 +66,11 @@ export function useHandleDebitNote( spentAmount: "", allocationId: "", }; - const { allocationId } = await yagnaClient + const { allocationId } = await client .getApi() .payment.createAllocation(allocation) .then((res) => res.data); - await yagnaClient.getApi().payment.acceptDebitNote(debitNote, { + await client.getApi().payment.acceptDebitNote(debitNote, { allocationId, totalAmountAccepted: debitNoteDetails.totalAmountDue, }); @@ -79,7 +86,7 @@ export function useHandleDebitNote( } finally { setIsLoading(false); } - }, [debitNote, isLoading, onAccepted, onRejected, reset, yagnaClient]); + }, [debitNote, isLoading, onAccepted, onRejected, reset, client]); return { acceptDebitNote, diff --git a/packages/react/src/useHandleInvoice.ts b/packages/react/src/useHandleInvoice.ts index 23f27cb..34b5806 100644 --- a/packages/react/src/useHandleInvoice.ts +++ b/packages/react/src/useHandleInvoice.ts @@ -27,7 +27,9 @@ export function useHandleInvoice( invoice: string, { onAccepted, onRejected, allocationTimeoutMs = 60_000 }: Options = {}, ) { - const { yagnaClient } = useConfig(); + const { + yagnaOptions: { client }, + } = useConfig(); const [isLoading, setIsLoading] = useState(false); const [isAccepted, setIsAccepted] = useState(false); const [error, setError] = useState(); @@ -42,10 +44,15 @@ export function useHandleInvoice( if (isLoading) { return; } + if (!client) { + throw new Error( + "Connection to Yagna is not established, use `useYagna` hook to set the app key and connect.", + ); + } reset(); setIsLoading(true); try { - const invoiceDetails = await yagnaClient + const invoiceDetails = await client .getApi() .payment.getInvoice(invoice) .then((res) => res.data); @@ -60,11 +67,11 @@ export function useHandleInvoice( spentAmount: "", allocationId: "", }; - const { allocationId } = await yagnaClient + const { allocationId } = await client .getApi() .payment.createAllocation(allocation) .then((res) => res.data); - await yagnaClient.getApi().payment.acceptInvoice(invoice, { + await client.getApi().payment.acceptInvoice(invoice, { allocationId, totalAmountAccepted: invoiceDetails.amount, }); @@ -80,7 +87,7 @@ export function useHandleInvoice( } finally { setIsLoading(false); } - }, [invoice, isLoading, onAccepted, onRejected, reset, yagnaClient]); + }, [invoice, isLoading, onAccepted, onRejected, reset, client]); return { acceptInvoice, diff --git a/packages/react/src/useTask.ts b/packages/react/src/useTask.ts index bfcb103..41d5ffb 100644 --- a/packages/react/src/useTask.ts +++ b/packages/react/src/useTask.ts @@ -45,7 +45,7 @@ export function useTask(executor: TaskExecutor) { const [error, setError] = useState(); const run = useCallback( - async (worker: Worker) => { + async (worker: Worker) => { if (isRunning) { throw new Error("Task is already running"); } diff --git a/packages/react/src/useYagna.ts b/packages/react/src/useYagna.ts index efcded0..dec7e65 100644 --- a/packages/react/src/useYagna.ts +++ b/packages/react/src/useYagna.ts @@ -1,3 +1,4 @@ +import { useCallback } from "react"; import { useConfig } from "./useConfig"; import useSwr from "swr"; @@ -26,12 +27,15 @@ import useSwr from "swr"; * ``` */ export function useYagna() { - const { yagnaClient, swrKey } = useConfig(); + const { yagnaOptions, swrKey, setYagnaOptions } = useConfig(); const { isLoading, error, mutate } = useSwr( - [swrKey, "yagna-connection-status"], + [swrKey, "yagna-connection-status", yagnaOptions], async () => { - return yagnaClient.getApi().identity.getIdentity(); + if (!yagnaOptions.client) { + throw new Error("Cannot connect to Yagna, provide an app key."); + } + return yagnaOptions.client.getApi().identity.getIdentity(); }, { refreshInterval: 3000, // ping yagna every 3 seconds to check if it's still connected @@ -40,10 +44,24 @@ export function useYagna() { }, ); + const setAppKey = useCallback( + (appKey: string) => setYagnaOptions({ apiKey: appKey }), + [setYagnaOptions], + ); + const unsetAppKey = useCallback( + () => setYagnaOptions({ apiKey: null }), + [setYagnaOptions], + ); + const isAppKeySet = !!yagnaOptions.apiKey; + return { isConnected: !error && !isLoading, reconnect: mutate, isLoading, error, + setAppKey, + unsetAppKey, + isAppKeySet, + appKey: yagnaOptions.apiKey, }; } From d2a61e2f00758ef0c075454b252e5a88056347bf Mon Sep 17 00:00:00 2001 From: Seweryn Kras Date: Thu, 25 Jan 2024 18:51:25 +0100 Subject: [PATCH 2/7] feat(useInvoice): allow searching for invoices with the new InvoiceProcessor --- packages/react/src/useHandleInvoice.ts | 42 ++++++++--------------- packages/react/src/useInvoices.ts | 47 ++++++++++++++++++++------ 2 files changed, 50 insertions(+), 39 deletions(-) diff --git a/packages/react/src/useHandleInvoice.ts b/packages/react/src/useHandleInvoice.ts index 34b5806..107cacf 100644 --- a/packages/react/src/useHandleInvoice.ts +++ b/packages/react/src/useHandleInvoice.ts @@ -1,5 +1,6 @@ import { useCallback, useState } from "react"; import { useConfig } from "./useConfig"; +import { InvoiceProcessor } from "@golem-sdk/golem-js"; interface Options { onAccepted?: () => void; @@ -25,11 +26,9 @@ interface Options { */ export function useHandleInvoice( invoice: string, - { onAccepted, onRejected, allocationTimeoutMs = 60_000 }: Options = {}, + { onAccepted, onRejected }: Options = {}, ) { - const { - yagnaOptions: { client }, - } = useConfig(); + const { yagnaOptions } = useConfig(); const [isLoading, setIsLoading] = useState(false); const [isAccepted, setIsAccepted] = useState(false); const [error, setError] = useState(); @@ -44,7 +43,9 @@ export function useHandleInvoice( if (isLoading) { return; } - if (!client) { + const apiKey = yagnaOptions.apiKey; + const basePath = yagnaOptions.basePath; + if (!apiKey) { throw new Error( "Connection to Yagna is not established, use `useYagna` hook to set the app key and connect.", ); @@ -52,28 +53,13 @@ export function useHandleInvoice( reset(); setIsLoading(true); try { - const invoiceDetails = await client - .getApi() - .payment.getInvoice(invoice) - .then((res) => res.data); - const allocation = { - totalAmount: invoiceDetails.amount, - paymentPlatform: invoiceDetails.paymentPlatform, - address: invoiceDetails.payerAddr, - timestamp: new Date().toISOString(), - timeout: new Date(Date.now() + allocationTimeoutMs).toISOString(), - makeDeposit: false, - remainingAmount: "", - spentAmount: "", - allocationId: "", - }; - const { allocationId } = await client - .getApi() - .payment.createAllocation(allocation) - .then((res) => res.data); - await client.getApi().payment.acceptInvoice(invoice, { - allocationId, - totalAmountAccepted: invoiceDetails.amount, + const invoiceProcessor = await InvoiceProcessor.create({ + apiKey, + basePath, + }); + const invoiceDetails = await invoiceProcessor.fetchSingleInvoice(invoice); + await invoiceProcessor.acceptInvoice({ + invoice: invoiceDetails, }); setIsAccepted(true); onAccepted?.(); @@ -87,7 +73,7 @@ export function useHandleInvoice( } finally { setIsLoading(false); } - }, [invoice, isLoading, onAccepted, onRejected, reset, client]); + }, [invoice, isLoading, onAccepted, onRejected, reset, yagnaOptions]); return { acceptInvoice, diff --git a/packages/react/src/useInvoices.ts b/packages/react/src/useInvoices.ts index 584c468..6771f25 100644 --- a/packages/react/src/useInvoices.ts +++ b/packages/react/src/useInvoices.ts @@ -1,10 +1,23 @@ import useSwr, { SWRConfiguration } from "swr"; import { useConfig } from "./useConfig"; import { yaPayment } from "ya-ts-client"; +import { InvoiceProcessor } from "@golem-sdk/golem-js"; export const InvoiceStatus = yaPayment.InvoiceStatus; export type InvoiceStatus = yaPayment.InvoiceStatus; +export type InvoiceSearchParameters = { + after?: Date; + limit?: number; + statuses?: string[]; + providerIds?: string[]; + minAmount?: string | number; + maxAmount?: string | number; + providerWallets?: string[]; + invoiceIds?: string[]; + paymentPlatforms?: string[]; +}; + /** * A hook that fetches invoices from the Yagna API. * @@ -39,22 +52,34 @@ export type InvoiceStatus = yaPayment.InvoiceStatus; * ``` */ export function useInvoices({ - after, - limit, swrConfig, -}: { - after?: string; - limit?: number; + ...searchParameters +}: InvoiceSearchParameters & { swrConfig?: SWRConfiguration; } = {}) { - const { yagnaClient, swrKey } = useConfig(); + const { swrKey, yagnaOptions } = useConfig(); const { data, isLoading, isValidating, error, mutate } = useSwr( - [swrKey, "invoices", after, limit], + [swrKey, "invoices", searchParameters, yagnaOptions], async () => { - return yagnaClient - .getApi() - .payment.getInvoices(after, limit) - .then((response) => response.data); + const apiKey = yagnaOptions.apiKey; + const basePath = yagnaOptions.basePath; + if (!apiKey) { + throw new Error( + "Connection to Yagna is not established, use `useYagna` hook to set the app key and connect.", + ); + } + const invoiceProcessor = await InvoiceProcessor.create({ + apiKey, + basePath, + }); + if (searchParameters.invoiceIds) { + return Promise.all( + searchParameters.invoiceIds.map((id) => + invoiceProcessor.fetchSingleInvoice(id), + ), + ); + } + return invoiceProcessor.collectInvoices(searchParameters); }, { keepPreviousData: true, From 7bb82be307c605b662831828650dca6c84dd40fc Mon Sep 17 00:00:00 2001 From: Seweryn Kras Date: Thu, 25 Jan 2024 18:55:19 +0100 Subject: [PATCH 3/7] docs(example): update example app to use the new invoice search --- .gitignore | 3 + examples/react-with-vite/.env.example | 1 - examples/react-with-vite/index.html | 6 +- examples/react-with-vite/package.json | 5 +- examples/react-with-vite/src/App.tsx | 40 +++- .../src/connection/ConnectToYagna.tsx | 43 +++- .../src/connection/SetAppKeyDropdown.tsx | 43 ++++ .../react-with-vite/src/header/Navbar.tsx | 7 +- examples/react-with-vite/src/index.css | 13 ++ .../react-with-vite/src/invoices/Copy.tsx | 33 +++ .../src/invoices/InvoiceSearch.tsx | 194 ++++++++++++++++++ .../src/invoices/InvoiceTableRow.tsx | 42 +++- .../src/invoices/InvoicesTab.tsx | 34 +++ .../src/invoices/InvoicesTable.tsx | 145 ++++++------- examples/react-with-vite/src/main.tsx | 21 +- .../src/run-task/ImageClassification.tsx | 4 +- examples/react-with-vite/tailwind.config.js | 20 +- package-lock.json | 54 ++--- 18 files changed, 560 insertions(+), 148 deletions(-) delete mode 100644 examples/react-with-vite/.env.example create mode 100644 examples/react-with-vite/src/connection/SetAppKeyDropdown.tsx create mode 100644 examples/react-with-vite/src/invoices/Copy.tsx create mode 100644 examples/react-with-vite/src/invoices/InvoiceSearch.tsx create mode 100644 examples/react-with-vite/src/invoices/InvoicesTab.tsx diff --git a/.gitignore b/.gitignore index b83a963..a3f95a6 100644 --- a/.gitignore +++ b/.gitignore @@ -25,5 +25,8 @@ node_modules/ .vscode/ .idea/ +# Ignore vercel files +.vercel/ + # Ignore build directory dist/ \ No newline at end of file diff --git a/examples/react-with-vite/.env.example b/examples/react-with-vite/.env.example deleted file mode 100644 index f5de46b..0000000 --- a/examples/react-with-vite/.env.example +++ /dev/null @@ -1 +0,0 @@ -VITE_YAGNA_APPKEY= \ No newline at end of file diff --git a/examples/react-with-vite/index.html b/examples/react-with-vite/index.html index dd82bc1..77b50d5 100644 --- a/examples/react-with-vite/index.html +++ b/examples/react-with-vite/index.html @@ -1,12 +1,12 @@ - + Golem + React + Vite demo - -
+ +
diff --git a/examples/react-with-vite/package.json b/examples/react-with-vite/package.json index 1988b2b..6841fc7 100644 --- a/examples/react-with-vite/package.json +++ b/examples/react-with-vite/package.json @@ -10,10 +10,11 @@ "preview": "vite preview" }, "dependencies": { + "@fontsource/kanit": "^5.0.18", "decimal.js": "^10.4.3", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-toastify": "^9.1.3" + "react-toastify": "^10.0.4" }, "devDependencies": { "@types/react": "^18.2.15", @@ -22,7 +23,7 @@ "@typescript-eslint/parser": "^6.0.0", "@vitejs/plugin-react": "^4.0.3", "autoprefixer": "^10.4.15", - "daisyui": "^3.6.4", + "daisyui": "^4.6.0", "eslint": "^8.45.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", diff --git a/examples/react-with-vite/src/App.tsx b/examples/react-with-vite/src/App.tsx index 5d76edf..460b3d1 100644 --- a/examples/react-with-vite/src/App.tsx +++ b/examples/react-with-vite/src/App.tsx @@ -1,28 +1,56 @@ import Navbar from "./header/Navbar"; import React, { useState } from "react"; import RunTaskCard from "./run-task/RunTaskCard"; -import InvoicesTable from "./invoices/InvoicesTable"; import DebitNotesTable from "./debit-notes/DebitNotesTable"; import { useYagna } from "@golem-sdk/react"; import ConnectToYagna from "./connection/ConnectToYagna"; +import InvoicesTab from "./invoices/InvoicesTab"; function Tab({ visible, children, }: React.PropsWithChildren<{ visible: boolean }>) { - return
{children}
; + return ( +
+ {children} +
+ ); } function App() { - const [activeTab, setActiveTab] = useState< + if ( + !window.location.hash || + !["run-task", "invoices", "debit-notes"].includes( + window.location.hash.slice(1), + ) + ) { + window.location.hash = "run-task"; + } + const [activeTab, _setActiveTab] = useState< "run-task" | "invoices" | "debit-notes" - >("run-task"); + >( + (window.location.hash.slice(1) as + | "run-task" + | "invoices" + | "debit-notes") || "run-task", + ); + const setActiveTab = (tab: "run-task" | "invoices" | "debit-notes") => { + window.location.hash = tab; + _setActiveTab(tab); + }; + const { isConnected } = useYagna(); return ( <> -
+
{!isConnected ? ( ) : ( @@ -31,7 +59,7 @@ function App() { - + diff --git a/examples/react-with-vite/src/connection/ConnectToYagna.tsx b/examples/react-with-vite/src/connection/ConnectToYagna.tsx index 9ab8b96..954deb9 100644 --- a/examples/react-with-vite/src/connection/ConnectToYagna.tsx +++ b/examples/react-with-vite/src/connection/ConnectToYagna.tsx @@ -1,26 +1,33 @@ import { useYagna } from "@golem-sdk/react"; +import { useRef } from "react"; export default function ConnectToYagna() { - const { reconnect } = useYagna(); + const { reconnect, appKey, setAppKey, unsetAppKey } = useYagna(); + const appKeyInputRef = useRef(null); return (
-

Not connected to yagna

-

- Looks like yagna is not running on your local machine. Please follow - the instructions in the{" "} +

Not connected to yagna

+

+ Make sure yagna is running on your local machine. Please follow the + instructions in this{" "} quickstart - + {" "} + to learn more about how to install and run yagna.

+

+ 1. Start yagna on your local machine +

Make sure to include the flag {`--api-allow-origin`} with the url of this app:

+
             
@@ -28,7 +35,29 @@ export default function ConnectToYagna() {
             
           
-
+

2. Set the app-key

+
+ + +
+
diff --git a/examples/react-with-vite/src/connection/SetAppKeyDropdown.tsx b/examples/react-with-vite/src/connection/SetAppKeyDropdown.tsx new file mode 100644 index 0000000..423481d --- /dev/null +++ b/examples/react-with-vite/src/connection/SetAppKeyDropdown.tsx @@ -0,0 +1,43 @@ +import { useYagna } from "@golem-sdk/react"; +import { useRef } from "react"; + +export default function SetAppKeyDropdown() { + const { appKey, setAppKey, unsetAppKey } = useYagna(); + const appKeyInputRef = useRef(null); + + return ( +
+
+ Set Yagna AppKey +
+
+
+
+ + +
+
+
+
+ ); +} diff --git a/examples/react-with-vite/src/header/Navbar.tsx b/examples/react-with-vite/src/header/Navbar.tsx index 7549322..6145560 100644 --- a/examples/react-with-vite/src/header/Navbar.tsx +++ b/examples/react-with-vite/src/header/Navbar.tsx @@ -1,4 +1,5 @@ import { useYagna } from "@golem-sdk/react"; +import SetAppKeyDropdown from "../connection/SetAppKeyDropdown"; interface NavbarProps { activeTab: "run-task" | "invoices" | "debit-notes"; @@ -6,10 +7,10 @@ interface NavbarProps { } export default function Navbar({ activeTab, setActiveTab }: NavbarProps) { - const { isConnected, reconnect, isLoading, error } = useYagna(); + const { isConnected, reconnect, isLoading } = useYagna(); return ( -
+
Golem + React = ๐Ÿ˜ป @@ -56,7 +57,7 @@ export default function Navbar({ activeTab, setActiveTab }: NavbarProps) {
- {error && {`${error}`}} + + ); +} diff --git a/examples/react-with-vite/src/invoices/InvoiceSearch.tsx b/examples/react-with-vite/src/invoices/InvoiceSearch.tsx new file mode 100644 index 0000000..d5fb7c1 --- /dev/null +++ b/examples/react-with-vite/src/invoices/InvoiceSearch.tsx @@ -0,0 +1,194 @@ +import { InvoiceSearchParameters } from "@golem-sdk/react"; + +type InvoiceSearchParametersProps = { + searchParams: InvoiceSearchParameters; + setSearchParams: (params: InvoiceSearchParameters) => void; +}; + +export default function InvoiceSearch({ + searchParams, + setSearchParams, +}: InvoiceSearchParametersProps) { + return ( +
+ + + + + setSearchParams({ + ...searchParams, + after: new Date(e.target.value), + }) + } + /> + +
+ + + +
+ + + + +
+ ); +} diff --git a/examples/react-with-vite/src/invoices/InvoiceTableRow.tsx b/examples/react-with-vite/src/invoices/InvoiceTableRow.tsx index 304caf0..07ae4e4 100644 --- a/examples/react-with-vite/src/invoices/InvoiceTableRow.tsx +++ b/examples/react-with-vite/src/invoices/InvoiceTableRow.tsx @@ -1,19 +1,31 @@ import Decimal from "decimal.js"; import { InvoiceStatus, useHandleInvoice } from "@golem-sdk/react"; import { toast } from "react-toastify"; +import Copy from "./Copy"; interface InvoiceItemProps { id: string; price: Decimal; issuedAt: Date; status: InvoiceStatus; + providerId: string; + providerWallet: string; + platform: string; onAction?: () => void; } +function truncateAddress(str: string) { + if (str.length <= 6) return str; + return `${str.slice(0, 6)}...${str.slice(-4)}`; +} + export default function InvoiceTableRow({ id, price, issuedAt, status, + providerId, + providerWallet, + platform, onAction, }: InvoiceItemProps) { const { acceptInvoice, isAccepted, isLoading } = useHandleInvoice(id, { @@ -29,11 +41,33 @@ export default function InvoiceTableRow({ }, }); return ( - - {id} + + + + {truncateAddress(id)} + + + {price.toFixed(5)} GLM - {issuedAt.toLocaleString("pl")} - {`${status}`} + + {issuedAt.toLocaleDateString()} +
+ {issuedAt.toLocaleTimeString()} + + {status} + + + {truncateAddress(providerId)} + + + + + + {truncateAddress(providerWallet)} + + + + {platform} - -
- )} -
-
-
+ + + + + + + + + + + + + + + {invoices && + invoices.map((invoice) => ( + { + refetch(); + }} + /> + ))} + {invoices && invoices.length === 0 && ( + + + + )} + {error && ( + + + + )} + {isLoading && ( + + + + )} + +
IdAmountIssued atStatusProvider IDProvider walletPlatformAction
+ No invoices found +
+ {`${error}`} +
+
+
); } diff --git a/examples/react-with-vite/src/main.tsx b/examples/react-with-vite/src/main.tsx index 96687ab..6c6573f 100644 --- a/examples/react-with-vite/src/main.tsx +++ b/examples/react-with-vite/src/main.tsx @@ -2,25 +2,22 @@ import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App.tsx"; import { YagnaProvider } from "@golem-sdk/react"; +import "@fontsource/kanit/400.css"; // regular +import "@fontsource/kanit/600.css"; // semi-bold import "./index.css"; import "react-toastify/dist/ReactToastify.css"; import { ToastContainer } from "react-toastify"; -if (!import.meta.env.VITE_YAGNA_APPKEY) { - throw new Error( - "VITE_YAGNA_APPKEY env variable not set. Please specify it in .env file.", - ); -} - ReactDOM.createRoot(document.getElementById("root")!).render( - + - + , ); diff --git a/examples/react-with-vite/src/run-task/ImageClassification.tsx b/examples/react-with-vite/src/run-task/ImageClassification.tsx index 7e463a8..9f289fc 100644 --- a/examples/react-with-vite/src/run-task/ImageClassification.tsx +++ b/examples/react-with-vite/src/run-task/ImageClassification.tsx @@ -31,7 +31,9 @@ function readFile(file: File): Promise { async function classifyOnGolem( image: File, - runFunction: (ctx: Worker) => Promise, + runFunction: ( + ctx: Worker<{ className: string; probability: number }>, + ) => Promise, ) { const extension = image.name.split(".").pop(); const input = `/golem/input/img.${extension}`; diff --git a/examples/react-with-vite/tailwind.config.js b/examples/react-with-vite/tailwind.config.js index 51587f1..e9f05be 100644 --- a/examples/react-with-vite/tailwind.config.js +++ b/examples/react-with-vite/tailwind.config.js @@ -3,10 +3,26 @@ export default { content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], theme: { - extend: {}, + extend: { + screens: { + "3xl": "1921px", + }, + }, }, plugins: [require("daisyui")], daisyui: { - themes: ["light"], + themes: [ + { + light: { + ...require("daisyui/src/theming/themes")["light"], + primary: "#181EA9", + "base-100": "#F6F8FC", + error: "#A71919", + success: "#367946", + + "--rounded-btn": "3px", + }, + }, + ], }, }; diff --git a/package-lock.json b/package-lock.json index 0dace78..2e72903 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "golem-sdk-react", + "name": "golem-react", "lockfileVersion": 3, "requires": true, "packages": { @@ -25,10 +25,11 @@ "examples/react-with-vite": { "version": "0.0.0", "dependencies": { + "@fontsource/kanit": "^5.0.18", "decimal.js": "^10.4.3", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-toastify": "^9.1.3" + "react-toastify": "^10.0.4" }, "devDependencies": { "@types/react": "^18.2.15", @@ -37,7 +38,7 @@ "@typescript-eslint/parser": "^6.0.0", "@vitejs/plugin-react": "^4.0.3", "autoprefixer": "^10.4.15", - "daisyui": "^3.6.4", + "daisyui": "^4.6.0", "eslint": "^8.45.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", @@ -1309,6 +1310,11 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fontsource/kanit": { + "version": "5.0.18", + "resolved": "https://registry.npmjs.org/@fontsource/kanit/-/kanit-5.0.18.tgz", + "integrity": "sha512-mvC19JOSxT1sbWtk+aOKXTvqqhHVXP9eCMiZNkU66amZ5kdY0bcctx5mLD7MpvEmcOjBYxpZGiK1pT+5hwChcA==" + }, "node_modules/@golem-sdk/golem-js": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@golem-sdk/golem-js/-/golem-js-0.12.0.tgz", @@ -3544,9 +3550,9 @@ } }, "node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", "engines": { "node": ">=6" } @@ -3574,12 +3580,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true - }, "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", @@ -3833,17 +3833,25 @@ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", "dev": true }, + "node_modules/culori": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/culori/-/culori-3.3.0.tgz", + "integrity": "sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/daisyui": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-3.9.3.tgz", - "integrity": "sha512-8li177QCu6dqlEOzE3h/dAV1y9Movbjx5bzJIO/hNqMNZtJkbHM0trjTzbDejV7N57eNGdjBvAGtxZYKzS4jow==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.6.0.tgz", + "integrity": "sha512-B5ZB/sczXpp4LMdo/SZrtYY/U2hq+Vr9I15QawuWZ0VwgtSAbuZpAZUftKVryEsPuv3BM0yVlBED0nAmtis/dw==", "dev": true, "dependencies": { - "colord": "^2.9", "css-selector-tokenizer": "^0.8", - "postcss": "^8", - "postcss-js": "^4", - "tailwindcss": "^3.1" + "culori": "^3", + "picocolors": "^1", + "postcss-js": "^4" }, "engines": { "node": ">=16.9.0" @@ -11587,11 +11595,11 @@ } }, "node_modules/react-toastify": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz", - "integrity": "sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==", + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.4.tgz", + "integrity": "sha512-etR3RgueY8pe88SA67wLm8rJmL1h+CLqUGHuAoNsseW35oTGJEri6eBTyaXnFKNQ80v/eO10hBYLgz036XRGgA==", "dependencies": { - "clsx": "^1.1.1" + "clsx": "^2.1.0" }, "peerDependencies": { "react": ">=16", From 7c203a67cd7cafcf14a2500fd4903069c091868c Mon Sep 17 00:00:00 2001 From: Seweryn Kras Date: Thu, 25 Jan 2024 19:02:21 +0100 Subject: [PATCH 4/7] feat(debit-notes): remove debit notes hooks BREAKING CHANGE: The `useDebitNotes` and `useHandleDebitNote` hooks were removed --- examples/react-with-vite/src/App.tsx | 19 +--- .../src/debit-notes/DebitNoteTableRow.tsx | 56 ----------- .../src/debit-notes/DebitNotesTable.tsx | 70 ------------- .../react-with-vite/src/header/Navbar.tsx | 20 +--- packages/react/src/index.ts | 2 - packages/react/src/useDebitNotes.ts | 87 ----------------- packages/react/src/useHandleDebitNote.ts | 97 ------------------- 7 files changed, 8 insertions(+), 343 deletions(-) delete mode 100644 examples/react-with-vite/src/debit-notes/DebitNoteTableRow.tsx delete mode 100644 examples/react-with-vite/src/debit-notes/DebitNotesTable.tsx delete mode 100644 packages/react/src/useDebitNotes.ts delete mode 100644 packages/react/src/useHandleDebitNote.ts diff --git a/examples/react-with-vite/src/App.tsx b/examples/react-with-vite/src/App.tsx index 460b3d1..febdb26 100644 --- a/examples/react-with-vite/src/App.tsx +++ b/examples/react-with-vite/src/App.tsx @@ -1,7 +1,6 @@ import Navbar from "./header/Navbar"; import React, { useState } from "react"; import RunTaskCard from "./run-task/RunTaskCard"; -import DebitNotesTable from "./debit-notes/DebitNotesTable"; import { useYagna } from "@golem-sdk/react"; import ConnectToYagna from "./connection/ConnectToYagna"; import InvoicesTab from "./invoices/InvoicesTab"; @@ -26,21 +25,14 @@ function Tab({ function App() { if ( !window.location.hash || - !["run-task", "invoices", "debit-notes"].includes( - window.location.hash.slice(1), - ) + !["run-task", "invoices"].includes(window.location.hash.slice(1)) ) { window.location.hash = "run-task"; } - const [activeTab, _setActiveTab] = useState< - "run-task" | "invoices" | "debit-notes" - >( - (window.location.hash.slice(1) as - | "run-task" - | "invoices" - | "debit-notes") || "run-task", + const [activeTab, _setActiveTab] = useState<"run-task" | "invoices">( + (window.location.hash.slice(1) as "run-task" | "invoices") || "run-task", ); - const setActiveTab = (tab: "run-task" | "invoices" | "debit-notes") => { + const setActiveTab = (tab: "run-task" | "invoices") => { window.location.hash = tab; _setActiveTab(tab); }; @@ -61,9 +53,6 @@ function App() { - - - )}
diff --git a/examples/react-with-vite/src/debit-notes/DebitNoteTableRow.tsx b/examples/react-with-vite/src/debit-notes/DebitNoteTableRow.tsx deleted file mode 100644 index 11d11d0..0000000 --- a/examples/react-with-vite/src/debit-notes/DebitNoteTableRow.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import Decimal from "decimal.js"; -import { InvoiceStatus, useHandleDebitNote } from "@golem-sdk/react"; -import { toast } from "react-toastify"; - -interface DebitNoteTableRowProps { - id: string; - amountDue: Decimal; - issuedAt: Date; - status: InvoiceStatus; - onAction?: () => void; -} - -export default function DebitNoteTableRow({ - id, - amountDue, - issuedAt, - status, - onAction, -}: DebitNoteTableRowProps) { - const { acceptDebitNote, isAccepted, isLoading } = useHandleDebitNote(id, { - onAccepted: () => { - toast("Debit note accepted ๐Ÿ’ธ", { type: "success" }); - onAction?.(); - }, - onRejected: () => { - toast("There was an error while accepting debit note ๐Ÿ˜ข", { - type: "error", - }); - onAction?.(); - }, - }); - - return ( - - {id} - {amountDue.toFixed(5)} GLM - {issuedAt.toLocaleString("pl")} - {`${status}`} - - - - - ); -} diff --git a/examples/react-with-vite/src/debit-notes/DebitNotesTable.tsx b/examples/react-with-vite/src/debit-notes/DebitNotesTable.tsx deleted file mode 100644 index 43f628d..0000000 --- a/examples/react-with-vite/src/debit-notes/DebitNotesTable.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { useState } from "react"; -import { useDebitNotes } from "@golem-sdk/react"; -import Decimal from "decimal.js"; -import DebitNoteTableRow from "./DebitNoteTableRow"; - -export default function DebitNotesTable() { - const [limit, setLimit] = useState(10); - - const { debitNotes, refetch, isLoading, error } = useDebitNotes({ - limit, - }); - - return ( -
-
-

- Debit Notes (from newest to oldest) - -

-
- - - - - - - - - - - {!!debitNotes && - debitNotes.map((debitNote) => ( - refetch()} - /> - ))} - -
IdAmount dueIssued atStatus
- {error && {`${error}`}} -
-
- {isLoading ? ( - - ) : ( - - )} -
-
-
- ); -} diff --git a/examples/react-with-vite/src/header/Navbar.tsx b/examples/react-with-vite/src/header/Navbar.tsx index 6145560..005c6ad 100644 --- a/examples/react-with-vite/src/header/Navbar.tsx +++ b/examples/react-with-vite/src/header/Navbar.tsx @@ -2,8 +2,8 @@ import { useYagna } from "@golem-sdk/react"; import SetAppKeyDropdown from "../connection/SetAppKeyDropdown"; interface NavbarProps { - activeTab: "run-task" | "invoices" | "debit-notes"; - setActiveTab: (tab: "run-task" | "invoices" | "debit-notes") => void; + activeTab: "run-task" | "invoices"; + setActiveTab: (tab: "run-task" | "invoices") => void; } export default function Navbar({ activeTab, setActiveTab }: NavbarProps) { @@ -27,7 +27,7 @@ export default function Navbar({ activeTab, setActiveTab }: NavbarProps) { }`} onClick={() => setActiveTab("run-task")} > - Run Task + Run a simple Task
  • @@ -39,19 +39,7 @@ export default function Navbar({ activeTab, setActiveTab }: NavbarProps) { }`} onClick={() => setActiveTab("invoices")} > - Invoices - -
  • -
  • - setActiveTab("debit-notes")} - > - Debit Notes + Search your invoice history
  • diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index ac1989c..2ce57bb 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -7,6 +7,4 @@ export { InvoiceStatus, type InvoiceSearchParameters, } from "./useInvoices"; -export { useDebitNotes } from "./useDebitNotes"; export { useHandleInvoice } from "./useHandleInvoice"; -export { useHandleDebitNote } from "./useHandleDebitNote"; diff --git a/packages/react/src/useDebitNotes.ts b/packages/react/src/useDebitNotes.ts deleted file mode 100644 index 024f8eb..0000000 --- a/packages/react/src/useDebitNotes.ts +++ /dev/null @@ -1,87 +0,0 @@ -import useSWR, { SWRConfiguration } from "swr"; -import { useConfig } from "./useConfig"; - -/** - * A hook that fetches debit notes from the Yagna API and returns them along with - * loading, validation, and error states. Note that the API always sorts debit - * notes by timestamp descending, so the `debitNotes` array will always be sorted - * from newest to oldest. - * - * @param {Object} options - Options for the hook. - * @param {number} [options.limit] - The maximum number of debit notes to fetch. - * @param {SWRConfiguration} [options.swrConfig] - Configuration options for the underlying SWR hook. - * @returns An object containing the fetched debit notes, loading and validation states, error state, and a function to refetch the data. - * - * @example - * ```jsx - * function MyComponent() { - * const [limit, setLimit] = useState(10); - * const { debitNotes, isLoading, error, refetch } = useDebitNotes({ - * limit, - * }); - * if (isLoading) { - * return
    Loading...
    ; - * } - * if (error) { - * return
    Error: {error.toString()}
    ; - * } - * return ( - *
    - *
      - * {debitNotes.map((debitNote) => ( - *
    • - * {debitNote.debitNoteId} - {debitNote.status} - *
    • - * ))} - *
    - * - * - *
    - * ); - * } - * ``` - */ -export function useDebitNotes({ - limit, - swrConfig, -}: { - limit?: number; - swrConfig?: SWRConfiguration; -} = {}) { - const { - yagnaOptions: { client: yagnaClient }, - swrKey, - } = useConfig(); - - const { data, isLoading, isValidating, error, mutate } = useSWR( - [swrKey, "debit-notes", limit, yagnaClient], - async () => { - if (!yagnaClient) { - throw new Error( - "Connection to Yagna is not established, use `useYagna` hook to set the app key and connect.", - ); - } - return ( - yagnaClient - .getApi() - // timestampAfter argument is irrelevant because the - // API always sorts by timestamp descending - // TODO: fix when API is fixed - .payment.getDebitNotes(undefined, limit) - .then((response) => response.data) - ); - }, - { - keepPreviousData: true, - ...swrConfig, - }, - ); - - return { - debitNotes: data, - isLoading, - isValidating, - error, - refetch: mutate, - }; -} diff --git a/packages/react/src/useHandleDebitNote.ts b/packages/react/src/useHandleDebitNote.ts deleted file mode 100644 index 44ed757..0000000 --- a/packages/react/src/useHandleDebitNote.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { useCallback, useState } from "react"; -import { useConfig } from "./useConfig"; - -interface Options { - onAccepted?: () => void; - onRejected?: () => void; - allocationTimeoutMs?: number; -} - -/** - * A hook that handles the acceptance of a debit note. - * - * @param debitNote - The debit note to be accepted. - * @param options - An optional object containing the following properties: - * @param options.onAccepted - A function to be called when the debit note is accepted (for example to show a success message to the user). - * @param options.onRejected - A function to be called when the debit note is rejected (for example to show an error message to the user). - * @param options.allocationTimeoutMs - The timeout for the allocation in milliseconds (defaults to 60 seconds). - * - * @returns An object containing the following properties: - * - acceptDebitNote: A function that accepts the debit note. - * - isLoading: A boolean indicating whether the hook is currently loading. - * - error: Error that occurred while accepting the debit note. - * - isAccepted: A boolean indicating whether the debit note was accepted. - */ -export function useHandleDebitNote( - debitNote: string, - { onAccepted, onRejected, allocationTimeoutMs = 60_000 }: Options = {}, -) { - const { - yagnaOptions: { client }, - } = useConfig(); - const [isLoading, setIsLoading] = useState(false); - const [isAccepted, setIsAccepted] = useState(false); - const [error, setError] = useState(); - - const reset = useCallback(() => { - setIsLoading(false); - setError(undefined); - setIsAccepted(false); - }, []); - - const acceptDebitNote = useCallback(async () => { - if (isLoading) { - return; - } - if (!client) { - throw new Error( - "Connection to Yagna is not established, use `useYagna` hook to set the app key and connect.", - ); - } - reset(); - setIsLoading(true); - try { - const debitNoteDetails = await client - .getApi() - .payment.getDebitNote(debitNote) - .then((res) => res.data); - const allocation = { - totalAmount: debitNoteDetails.totalAmountDue, - paymentPlatform: debitNoteDetails.paymentPlatform, - address: debitNoteDetails.payerAddr, - timestamp: new Date().toISOString(), - timeout: new Date(Date.now() + allocationTimeoutMs).toISOString(), - makeDeposit: false, - remainingAmount: "", - spentAmount: "", - allocationId: "", - }; - const { allocationId } = await client - .getApi() - .payment.createAllocation(allocation) - .then((res) => res.data); - await client.getApi().payment.acceptDebitNote(debitNote, { - allocationId, - totalAmountAccepted: debitNoteDetails.totalAmountDue, - }); - setIsAccepted(true); - onAccepted?.(); - } catch (err) { - if (err instanceof Error) { - setError(err); - } else { - setError(new Error(JSON.stringify(err))); - } - onRejected?.(); - } finally { - setIsLoading(false); - } - }, [debitNote, isLoading, onAccepted, onRejected, reset, client]); - - return { - acceptDebitNote, - isLoading, - isAccepted, - error, - }; -} From 9edcf246459c76041a0619068ef4591795192127 Mon Sep 17 00:00:00 2001 From: Seweryn Kras Date: Thu, 25 Jan 2024 19:30:23 +0100 Subject: [PATCH 5/7] docs(README): update examples in README --- packages/react/README.md | 79 +++++++------------------------ packages/react/src/useInvoices.ts | 6 ++- packages/react/src/useYagna.ts | 14 +++--- 3 files changed, 28 insertions(+), 71 deletions(-) diff --git a/packages/react/README.md b/packages/react/README.md index a2c92d0..99e7406 100644 --- a/packages/react/README.md +++ b/packages/react/README.md @@ -16,9 +16,7 @@ bun add @golem-sdk/react Then make sure to wrap your app with the `YagnaProvider` component: ```jsx - + ``` @@ -44,35 +42,29 @@ npm install npm run build ``` -Then create a `.env` file in the `examples/react-with-vite` directory with the following content: - -``` -VITE_YAGNA_APPKEY= -``` - -Finally, run the demo application: +Then run the following command to start the demo application: ``` npm run example:vite ``` +If you just want to see how the demo application looks like, you can check out the live version [here](https://golem-react-showcase.vercel.app/). + ## Features -### `useYagna` - check if you're connected to Yagna +### `useYagna` - check if you're connected to Yagna and manage the app-key ```jsx function MyComponent() { - const { isConnected, reconnect, isLoading, error } = useYagna(); - if (isLoading) { - return
    Loading...
    ; - } + const { isConnected, appKey, setAppKey } = useYagna(); + const inputRef = useRef(null); return (
    -
    Yagna is {isConnected ? "connected" : "disconnected"}
    - - {error &&
    Error: {error.toString()}
    }
    ); } @@ -147,7 +139,11 @@ function Invoice({ invoiceId }) { } function MyComponent() { - const { invoices, isLoading, error, refetch } = useInvoices(); + const { invoices, isLoading, error, refetch } = useInvoices({ + limit: 10, + statuses: ["RECEIVED"], + after: new Date("2021-01-01"), + }); if (isLoading) { return
    Loading...
    ; } @@ -167,49 +163,6 @@ function MyComponent() { } ``` -### `useDebitNotes` + `useHandleDebitNote` - list and handle debit notes - -```jsx -function DebitNote({ debitNoteId }) { - const { acceptDebitNote } = useHandleDebitNote(); - - return ( -
  • - {debitNoteId} - {debitNote.status} - -
  • - ); -} - -function MyComponent() { - const { debitNotes, isLoading, error, refetch } = useDebitNotes(); - if (isLoading) { - return
    Loading...
    ; - } - if (error) { - return
    Error: {error.toString()}
    ; - } - return ( -
    -
      - {debitNotes.map((debitNote) => ( - - ))} -
    - -
    - ); -} -``` - ## Developing If you want to contribute to the SDK, you can clone the repository and install the dependencies: diff --git a/packages/react/src/useInvoices.ts b/packages/react/src/useInvoices.ts index 6771f25..7c6da9b 100644 --- a/packages/react/src/useInvoices.ts +++ b/packages/react/src/useInvoices.ts @@ -29,7 +29,11 @@ export type InvoiceSearchParameters = { * @example * ```jsx * function MyComponent() { - * const { invoices, isLoading, error, refetch } = useInvoices(); + * const { invoices, isLoading, error, refetch } = useInvoices({ + * limit: 10, + * statuses: ["RECEIVED"], + * after: new Date("2021-01-01"), + * }); * if (isLoading) { * return
    Loading...
    ; * } diff --git a/packages/react/src/useYagna.ts b/packages/react/src/useYagna.ts index dec7e65..69b2a1d 100644 --- a/packages/react/src/useYagna.ts +++ b/packages/react/src/useYagna.ts @@ -12,15 +12,15 @@ import useSwr from "swr"; * @example * ```jsx * function MyComponent() { - * const { isConnected, reconnect, isLoading, error } = useYagna(); - * if (isLoading) { - * return
    Loading...
    ; - * } + * const { isConnected, appKey, setAppKey } = useYagna(); + * const inputRef = useRef(null); * return ( *
    - *
    Yagna is {isConnected ? "connected" : "disconnected"}
    - * - * {error &&
    Error: {error.toString()}
    } + *
    Connected to Yagna: {isConnected ? "yes" : "no"}
    + * + * *
    * ); * } From 503fb6da1eff63605be6246ef0d1197e36b6f592 Mon Sep 17 00:00:00 2001 From: Seweryn Kras Date: Tue, 30 Jan 2024 21:37:05 +0100 Subject: [PATCH 6/7] feat(useYagna): allow changing basePath with `useYagna` --- .../src/connection/ConnectToYagna.tsx | 26 ++++++--- .../src/connection/SetAppKeyDropdown.tsx | 43 -------------- .../src/connection/SetYagnaOptionsButton.tsx | 19 +++++++ .../connection/SetYagnaOptionsDropdown.tsx | 56 +++++++++++++++++++ .../react-with-vite/src/header/Navbar.tsx | 4 +- .../src/run-task/ImageClassification.tsx | 4 +- .../src/run-task/RunTaskCard.tsx | 2 +- packages/react/README.md | 6 +- packages/react/src/provider.tsx | 2 +- packages/react/src/useYagna.ts | 34 +++++++---- 10 files changed, 125 insertions(+), 71 deletions(-) delete mode 100644 examples/react-with-vite/src/connection/SetAppKeyDropdown.tsx create mode 100644 examples/react-with-vite/src/connection/SetYagnaOptionsButton.tsx create mode 100644 examples/react-with-vite/src/connection/SetYagnaOptionsDropdown.tsx diff --git a/examples/react-with-vite/src/connection/ConnectToYagna.tsx b/examples/react-with-vite/src/connection/ConnectToYagna.tsx index 954deb9..4656246 100644 --- a/examples/react-with-vite/src/connection/ConnectToYagna.tsx +++ b/examples/react-with-vite/src/connection/ConnectToYagna.tsx @@ -2,8 +2,9 @@ import { useYagna } from "@golem-sdk/react"; import { useRef } from "react"; export default function ConnectToYagna() { - const { reconnect, appKey, setAppKey, unsetAppKey } = useYagna(); + const { reconnect, appKey, basePath, setYagnaOptions } = useYagna(); const appKeyInputRef = useRef(null); + const basePathInputRef = useRef(null); return (
    @@ -35,23 +36,32 @@ export default function ConnectToYagna() {
    -

    2. Set the app-key

    +

    2. Set the app-key and yagna url

    + App-key: + Yagna url: + + -
    -
    - - - ); -} diff --git a/examples/react-with-vite/src/connection/SetYagnaOptionsButton.tsx b/examples/react-with-vite/src/connection/SetYagnaOptionsButton.tsx new file mode 100644 index 0000000..e3b35b9 --- /dev/null +++ b/examples/react-with-vite/src/connection/SetYagnaOptionsButton.tsx @@ -0,0 +1,19 @@ +import { useState } from "react"; +import SetYagnaOptionsDropdown from "./SetYagnaOptionsDropdown"; + +export default function SetYagnaOptionsButton() { + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + + return ( +
    + +
    + {isDropdownOpen && ( + setIsDropdownOpen(false)} /> + )} +
    +
    + ); +} diff --git a/examples/react-with-vite/src/connection/SetYagnaOptionsDropdown.tsx b/examples/react-with-vite/src/connection/SetYagnaOptionsDropdown.tsx new file mode 100644 index 0000000..e6241cb --- /dev/null +++ b/examples/react-with-vite/src/connection/SetYagnaOptionsDropdown.tsx @@ -0,0 +1,56 @@ +import { useYagna } from "@golem-sdk/react"; +import { useRef } from "react"; + +interface SetYagnaOptionsDropdownProps { + onClose?: () => void; +} + +export default function SetYagnaOptionsDropdown({ + onClose, +}: SetYagnaOptionsDropdownProps) { + const { appKey, basePath, setYagnaOptions } = useYagna(); + const appKeyInputRef = useRef(null); + const basePathInputRef = useRef(null); + + return ( + <> +
    onClose?.()} + >
    +
    +
    +
    +
    + + + +
    +
    +
    +
    + + ); +} diff --git a/examples/react-with-vite/src/header/Navbar.tsx b/examples/react-with-vite/src/header/Navbar.tsx index 005c6ad..8581a91 100644 --- a/examples/react-with-vite/src/header/Navbar.tsx +++ b/examples/react-with-vite/src/header/Navbar.tsx @@ -1,5 +1,5 @@ import { useYagna } from "@golem-sdk/react"; -import SetAppKeyDropdown from "../connection/SetAppKeyDropdown"; +import SetYagnaOptionsButton from "../connection/SetYagnaOptionsButton"; interface NavbarProps { activeTab: "run-task" | "invoices"; @@ -45,7 +45,7 @@ export default function Navbar({ activeTab, setActiveTab }: NavbarProps) {
    - + {isConnected && }
    diff --git a/packages/react/src/provider.tsx b/packages/react/src/provider.tsx index 31ff9f8..2f8f913 100644 --- a/packages/react/src/provider.tsx +++ b/packages/react/src/provider.tsx @@ -27,7 +27,7 @@ export type YagnaProviderConfig = { * * @param config - The configuration object for the provider. * @param config.yagnaAppKey - The API key for the Yagna client. This is optional and can be set later with `useYagna` - * @param config.yagnaUrl - The base URL for the Yagna client. This is optional and defaults to "http://127.0.0.1:7465". + * @param config.yagnaUrl - The base URL for the Yagna client. This is optional, defaults to "http://127.0.0.1:7465" and can be set later with `useYagna` * @param config.swrKey - The key used to prefix all SWR cache keys. This is optional and defaults to "golem-sdk". * * @example diff --git a/packages/react/src/useYagna.ts b/packages/react/src/useYagna.ts index 69b2a1d..54f9a86 100644 --- a/packages/react/src/useYagna.ts +++ b/packages/react/src/useYagna.ts @@ -12,13 +12,13 @@ import useSwr from "swr"; * @example * ```jsx * function MyComponent() { - * const { isConnected, appKey, setAppKey } = useYagna(); + * const { isConnected, appKey, setYagnaOptions } = useYagna(); * const inputRef = useRef(null); * return ( *
    *
    Connected to Yagna: {isConnected ? "yes" : "no"}
    * - * *
    @@ -27,7 +27,11 @@ import useSwr from "swr"; * ``` */ export function useYagna() { - const { yagnaOptions, swrKey, setYagnaOptions } = useConfig(); + const { + yagnaOptions, + swrKey, + setYagnaOptions: setInternalYagnaOptions, + } = useConfig(); const { isLoading, error, mutate } = useSwr( [swrKey, "yagna-connection-status", yagnaOptions], @@ -44,14 +48,20 @@ export function useYagna() { }, ); - const setAppKey = useCallback( - (appKey: string) => setYagnaOptions({ apiKey: appKey }), - [setYagnaOptions], - ); - const unsetAppKey = useCallback( - () => setYagnaOptions({ apiKey: null }), - [setYagnaOptions], + const setYagnaOptions = useCallback( + (options: { apiKey?: string | null; basePath?: string }) => { + setInternalYagnaOptions({ + apiKey: + options.apiKey === undefined ? yagnaOptions.apiKey : options.apiKey, + basePath: + options.basePath === undefined + ? yagnaOptions.basePath + : options.basePath, + }); + }, + [setInternalYagnaOptions, yagnaOptions], ); + const isAppKeySet = !!yagnaOptions.apiKey; return { @@ -59,9 +69,9 @@ export function useYagna() { reconnect: mutate, isLoading, error, - setAppKey, - unsetAppKey, + setYagnaOptions, isAppKeySet, appKey: yagnaOptions.apiKey, + basePath: yagnaOptions.basePath, }; } From af03fbe495a3c3a6523517477c6f05865265eb30 Mon Sep 17 00:00:00 2001 From: Seweryn Kras Date: Tue, 13 Feb 2024 13:52:57 +0100 Subject: [PATCH 7/7] chore: bump golem-js to 2.0 --- package-lock.json | 168 ++++++++++++------------------ packages/react/package.json | 2 +- packages/react/src/useExecutor.ts | 2 +- 3 files changed, 67 insertions(+), 105 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2e72903..0cf875b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1316,21 +1316,26 @@ "integrity": "sha512-mvC19JOSxT1sbWtk+aOKXTvqqhHVXP9eCMiZNkU66amZ5kdY0bcctx5mLD7MpvEmcOjBYxpZGiK1pT+5hwChcA==" }, "node_modules/@golem-sdk/golem-js": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@golem-sdk/golem-js/-/golem-js-0.12.0.tgz", - "integrity": "sha512-pyxBl1wNNlEe2sDUn1gpZyqH/oZo9HGnaU9GzzpRgZ/aBY23wApQwd+8U7RM0yUlR7Mg0CsDnIaf7W+MVCRnoQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@golem-sdk/golem-js/-/golem-js-2.0.0.tgz", + "integrity": "sha512-jv9Ny2EHx7Qsb06rb9JE76+T2qux1wirfNhQ9a4vPwN+UPcieB96wVhQC/8Va+reJO0sRCaw82nBPscWhkADJQ==", "dependencies": { - "axios": "^1.1.3", + "async-lock": "^1.4.0", + "axios": "^1.6.2", "bottleneck": "^2.19.5", - "collect.js": "^4.34.3", + "collect.js": "^4.36.1", + "debug": "^4.3.4", + "decimal.js-light": "^2.5.1", + "eventemitter3": "^5.0.1", "eventsource": "^2.0.2", "flatbuffers": "^23.5.26", - "ip-num": "^1.4.1", - "js-sha3": "^0.9.1", - "pino": "^8.11.0", - "pino-pretty": "^10.0.1", + "ip-num": "^1.5.1", + "js-sha3": "^0.9.3", + "pino": "^8.17.1", + "pino-pretty": "^10.3.0", + "semver": "^7.5.4", "tmp": "^0.2.1", - "uuid": "^9.0.0", + "uuid": "^9.0.1", "ya-ts-client": "^0.5.3" }, "engines": { @@ -3096,6 +3101,11 @@ "node": ">=0.10.0" } }, + "node_modules/async-lock": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz", + "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==" + }, "node_modules/asynciterator.prototype": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", @@ -3168,11 +3178,11 @@ } }, "node_modules/axios": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", - "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.4", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -3882,7 +3892,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -3934,6 +3943,11 @@ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==" + }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -4901,6 +4915,11 @@ "node": ">=6" } }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -5134,9 +5153,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "funding": [ { "type": "individual", @@ -5539,24 +5558,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -5569,25 +5570,6 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/global-dirs": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", @@ -5786,26 +5768,9 @@ } }, "node_modules/help-me": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/help-me/-/help-me-4.2.0.tgz", - "integrity": "sha512-TAOnTB8Tz5Dw8penUuzHVrKNKlCIbwwbHnXraNJxPwf8LRtE2HlM84RYuezMFcwOJmoYOCWVDyJ8TQGxn9PgxA==", - "dependencies": { - "glob": "^8.0.0", - "readable-stream": "^3.6.0" - } - }, - "node_modules/help-me/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==" }, "node_modules/hook-std": { "version": "3.0.0", @@ -6569,9 +6534,9 @@ } }, "node_modules/js-sha3": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.9.2.tgz", - "integrity": "sha512-8kgvwd03wNGQG1GRvl3yy1Yt40sICAcIMsDU2ZLgoL0Z6z9rkRmf9Vd+bi/gYSzgAqMUGl/jiDKu0J8AWFd+BQ==" + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.9.3.tgz", + "integrity": "sha512-BcJPCQeLg6WjEx3FE591wVAevlli8lxsxm9/FzV4HXkV49TmBH38Yvrpce6fjbADGMKFrBMGTqrVz3qPIZ88Gg==" }, "node_modules/js-tokens": { "version": "4.0.0", @@ -6902,7 +6867,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -7108,8 +7072,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mz": { "version": "2.7.0", @@ -11035,16 +10998,16 @@ } }, "node_modules/pino": { - "version": "8.16.1", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.16.1.tgz", - "integrity": "sha512-3bKsVhBmgPjGV9pyn4fO/8RtoVDR8ssW1ev819FsRXlRNgW8gR/9Kx+gCK4UPWd4JjrRDLWpzd/pb1AyWm3MGA==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.18.0.tgz", + "integrity": "sha512-Mz/gKiRyuXu4HnpHgi1YWdHQCoWMufapzooisvFn78zl4dZciAxS+YeRkUxXl1ee/SzU80YCz1zpECCh4oC6Aw==", "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "v1.1.0", "pino-std-serializers": "^6.0.0", - "process-warning": "^2.0.0", + "process-warning": "^3.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", @@ -11065,15 +11028,15 @@ } }, "node_modules/pino-pretty": { - "version": "10.2.3", - "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.2.3.tgz", - "integrity": "sha512-4jfIUc8TC1GPUfDyMSlW1STeORqkoxec71yhxIpLDQapUu8WOuoz2TTCoidrIssyz78LZC69whBMPIKCMbi3cw==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-10.3.1.tgz", + "integrity": "sha512-az8JbIYeN/1iLj2t0jR9DV48/LQ3RC6hZPpapKPkb84Q+yTidMCpgWxIT3N0flnBDilyBQ1luWNpOeJptjdp/g==", "dependencies": { "colorette": "^2.0.7", "dateformat": "^4.6.3", "fast-copy": "^3.0.0", "fast-safe-stringify": "^2.1.1", - "help-me": "^4.0.1", + "help-me": "^5.0.0", "joycon": "^3.1.1", "minimist": "^1.2.6", "on-exit-leak-free": "^2.1.0", @@ -11442,9 +11405,9 @@ "dev": true }, "node_modules/process-warning": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", - "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==" }, "node_modules/prop-types": { "version": "15.8.1", @@ -11784,9 +11747,9 @@ } }, "node_modules/readable-stream": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", - "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -12673,7 +12636,6 @@ "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -12900,9 +12862,9 @@ } }, "node_modules/sonic-boom": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.7.0.tgz", - "integrity": "sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.0.tgz", + "integrity": "sha512-ybz6OYOUjoQQCQ/i4LU8kaToD8ACtYP+Cj5qd2AO36bwbdewxWJ3ArmJ2cr6AvxlL2o0PqnCcPGUgkILbfkaCA==", "dependencies": { "atomic-sleep": "^1.0.0" } @@ -13862,7 +13824,8 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true }, "node_modules/uuid": { "version": "9.0.1", @@ -14123,8 +14086,7 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yaml": { "version": "2.3.3", @@ -14199,7 +14161,7 @@ "version": "0.1.0", "license": "GPL-3.0", "dependencies": { - "@golem-sdk/golem-js": "^0.12.0", + "@golem-sdk/golem-js": "^2.0.0", "swr": "^2.2.2" }, "devDependencies": { diff --git a/packages/react/package.json b/packages/react/package.json index f724f31..c1adec4 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -17,7 +17,7 @@ } }, "dependencies": { - "@golem-sdk/golem-js": "^0.12.0", + "@golem-sdk/golem-js": "^2.0.0", "swr": "^2.2.2" }, "devDependencies": { diff --git a/packages/react/src/useExecutor.ts b/packages/react/src/useExecutor.ts index 55017bc..37db93e 100644 --- a/packages/react/src/useExecutor.ts +++ b/packages/react/src/useExecutor.ts @@ -84,7 +84,7 @@ export function useExecutor( removeBeforeUnloadHandler(); if (executor && !isTerminating) { setIsTerminating(true); - await executor.end(); + await executor.shutdown(); setExecutor(null); setIsTerminating(false); }