diff --git a/Cargo.lock b/Cargo.lock index 9bf21d2..d2d21a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2194,8 +2194,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] diff --git a/README.md b/README.md index 6e2d3df..3074908 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ [![Crates.io Version](https://img.shields.io/crates/v/nextgraph)](https://crates.io/crates/nextgraph) [![docs.rs](https://img.shields.io/docsrs/nextgraph)](https://docs.rs/nextgraph) [node:![NPM Version node](https://img.shields.io/npm/v/nextgraph)](https://www.npmjs.com/package/nextgraph) -[web:![NPM Version web](https://img.shields.io/npm/v/nextgraphweb)](https://www.npmjs.com/package/nextgraphweb) +[web:![NPM Version web](https://img.shields.io/npm/v/@ng-org/web)](https://www.npmjs.com/package/@ng-org/web) [![PyPI - Version](https://img.shields.io/pypi/v/nextgraphpy)](https://pypi.org/project/nextgraphpy/) Rust implementation of NextGraph diff --git a/app/ui-common/src/api.ts b/app/ui-common/src/api.ts index 28fa001..283455a 100644 --- a/app/ui-common/src/api.ts +++ b/app/ui-common/src/api.ts @@ -28,10 +28,10 @@ export const NG_EU_BSP_REGISTER = import.meta.env.PROD ? "https://account.nextgraph.eu/#/create" : "http://account-dev.nextgraph.eu:5173/#/create"; -export const NG_NET_BSP = "https://nextgraph.net"; -export const NG_NET_BSP_REGISTER = import.meta.env.PROD -? "https://account.nextgraph.net/#/create" -: "http://account-dev.nextgraph.net:5173/#/create"; +export const NG_ONE_BSP = "https://nextgraph.one"; +export const NG_ONE_BSP_REGISTER = import.meta.env.PROD +? "https://account.nextgraph.one/#/create" +: "http://account-dev.nextgraph.one:5173/#/create"; export const APP_ACCOUNT_REGISTERED_SUFFIX = "/#/user/registered"; export const APP_WALLET_CREATE_SUFFIX = "/#/wallet/create"; diff --git a/app/ui-common/src/lib/NoWallet.svelte b/app/ui-common/src/lib/NoWallet.svelte index 6f954d0..274339a 100644 --- a/app/ui-common/src/lib/NoWallet.svelte +++ b/app/ui-common/src/lib/NoWallet.svelte @@ -20,6 +20,8 @@ import { link } from "svelte-spa-router"; import CenteredLayout from "./CenteredLayout.svelte"; import { t } from "svelte-i18n"; + + export let without_create = false; @@ -30,8 +32,14 @@

{$t("pages.no_wallet.welcome")}

- {@html $t("pages.no_wallet.description")} + {@html $t("pages.no_wallet.description")}
+ {@html $t("pages.no_wallet.instructions_login")}{#if !without_create}{@html $t("pages.no_wallet.instructions_create")} + {:else} + {@html $t("pages.no_wallet.instructions_nocreate")} + {/if} +

+ {#if !without_create}
+ {/if}
+
+ + )} + + ); +}; \ No newline at end of file diff --git a/sdk/js/examples/react-ldo/src/MakeContact.tsx b/sdk/js/examples/react-ldo/src/MakeContact.tsx new file mode 100644 index 0000000..a8fe52d --- /dev/null +++ b/sdk/js/examples/react-ldo/src/MakeContact.tsx @@ -0,0 +1,60 @@ +import { FormEvent, FunctionComponent, useCallback, useState } from "react"; +import { BrowserNGLdoProvider, useLdo, dataset } from './reactMethods'; +import { SocialContactShapeType } from "./.ldo/contact.shapeTypes.ts"; +import { LdSet } from "@ldo/ldo"; + +export const MakeContact: FunctionComponent = () => { + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + + const { createData, commitData } = useLdo(); + + const onSubmit = useCallback( + async (e: FormEvent) => { + e.preventDefault(); + const new_name = name.trim(); + const new_email = email.trim(); + if (new_name.trim().length > 2 && new_email.trim().length > 6 && new_email.indexOf("@") >= 0) { + setName(""); + setEmail(""); + const resource = await dataset.createResource("nextgraph"); + if (!resource.isError) { + //console.log("Created resource:", resource.uri); + + const contact = createData( + SocialContactShapeType, + resource.uri.substring(0,53), + resource + ); + + contact.type = { "@id": "Individual" }; + contact.fn = new_name; + contact.hasEmail = new_email; + const result = await commitData(contact); + if (result.isError) { + console.error(result.message); + } + } + } + }, + [name, email] + ); + + return ( +
+ setName(e.target.value)} + /> + setEmail(e.target.value)} + /> + +
+ ); +}; \ No newline at end of file diff --git a/sdk/js/examples/react-ldo/src/NextGraphAuthContext.ts b/sdk/js/examples/react-ldo/src/NextGraphAuthContext.ts new file mode 100644 index 0000000..59b169a --- /dev/null +++ b/sdk/js/examples/react-ldo/src/NextGraphAuthContext.ts @@ -0,0 +1,20 @@ +import { createContext, useContext } from "react"; + +/** + * Functions for authenticating with NextGraph + */ +export interface NGWalletAuthFunctions { + login: () => Promise; + logout: () => Promise; + session: unknown; + ranInitialAuthCheck: boolean; +} + +// There is no initial value for this context. It will be given in the provider +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +export const NextGraphAuthContext = createContext(undefined); + +export function useNextGraphAuth(): NGWalletAuthFunctions { + return useContext(NextGraphAuthContext); +} \ No newline at end of file diff --git a/sdk/js/examples/react-ldo/src/createBrowserNGReactMethods.tsx b/sdk/js/examples/react-ldo/src/createBrowserNGReactMethods.tsx new file mode 100644 index 0000000..d819789 --- /dev/null +++ b/sdk/js/examples/react-ldo/src/createBrowserNGReactMethods.tsx @@ -0,0 +1,112 @@ +import React, { useCallback, useEffect, useMemo, useState } from "react"; +import type { FunctionComponent, PropsWithChildren } from "react"; +import { NextGraphAuthContext, useNextGraphAuth } from "./NextGraphAuthContext"; + +import {ng, init} from "@ng-org/web"; + +import type { ConnectedLdoDataset, ConnectedPlugin } from "@ldo/connected"; +import type { NextGraphConnectedPlugin, NextGraphConnectedContext } from "@ldo/connected-nextgraph"; + +/** + * Creates special react methods specific to the NextGraph Auth + * @param dataset the connectedLdoDataset with a nextGraphConnectedPlugin + * @returns { BrowserNGLdoProvider, useNextGraphAuth } + */ +export function createBrowserNGReactMethods( + dataset: ConnectedLdoDataset<(NextGraphConnectedPlugin | ConnectedPlugin)[]>, +) { + + const BrowserNGLdoProvider: FunctionComponent = ({ + children, + }) => { + const [session, setSession] = useState( + { + ng: undefined, + } + ); + const [ranInitialAuthCheck, setRanInitialAuthCheck] = useState(false); + + const runInitialAuthCheck = useCallback(async () => { + //console.log("runInitialAuthCheck called", ranInitialAuthCheck) + if (ranInitialAuthCheck) return; + + //console.log("init called"); + setRanInitialAuthCheck(true); + // TODO: export the types for the session object coming from NG. + await init( (event: { status: string; session: { session_id: unknown; protected_store_id: unknown; private_store_id: unknown; public_store_id: unknown; }; }) => { + //console.log("called back in react", event) + + // callback + // once you receive event.status == "loggedin" + // you can use the full API + if (event.status == "loggedin") { + setSession({ + ng, + sessionId: event.session.session_id as string, //FIXME: sessionId should be a Number. + protectedStoreId: event.session.protected_store_id as string, + privateStoreId: event.session.private_store_id as string, + publicStoreId: event.session.public_store_id as string + }); // TODO: add event.session.user too + + dataset.setContext("nextgraph", { + ng, + sessionId: event.session.session_id as string + }); + } + else if (event.status == "cancelled" || event.status == "error" || event.status == "loggedout") { + setSession({ ng: undefined }); + dataset.setContext("nextgraph", { + ng: undefined, + }); + } + } + , true // singleton: boolean (should it be launched as a unique instance, or will your app create many docs in the system) + , []); //list of AccessRequests (for now, leave this empty) + + }, []); + + + const login = useCallback( + async () => { + await ng.login(); + }, + [], + ); + + const logout = useCallback(async () => { + await ng.logout(); + }, []); + + useEffect(() => { + runInitialAuthCheck(); + }, []); + + const nextGraphAuthFunctions = useMemo( + () => ({ + runInitialAuthCheck, + login, + logout, + session, + ranInitialAuthCheck, + }), + [ + login, + logout, + ranInitialAuthCheck, + runInitialAuthCheck, + session, + ], + ); + + return ( + + {children} + + ); + }; + + return { + BrowserNGLdoProvider, + useNextGraphAuth: useNextGraphAuth + }; +}; \ No newline at end of file diff --git a/sdk/js/examples/react-ldo/src/index.css b/sdk/js/examples/react-ldo/src/index.css new file mode 100644 index 0000000..bd6213e --- /dev/null +++ b/sdk/js/examples/react-ldo/src/index.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; \ No newline at end of file diff --git a/sdk/js/examples/react-ldo/src/main.tsx b/sdk/js/examples/react-ldo/src/main.tsx new file mode 100644 index 0000000..5b08362 --- /dev/null +++ b/sdk/js/examples/react-ldo/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.tsx' + +createRoot(document.getElementById('app')!).render( + // + + // , +) diff --git a/sdk/js/examples/react-ldo/src/reactMethods.ts b/sdk/js/examples/react-ldo/src/reactMethods.ts new file mode 100644 index 0000000..cacf973 --- /dev/null +++ b/sdk/js/examples/react-ldo/src/reactMethods.ts @@ -0,0 +1,18 @@ +import { nextGraphConnectedPlugin } from "@ldo/connected-nextgraph"; +import { createLdoReactMethods } from "@ldo/react"; +import { createBrowserNGReactMethods } from "./createBrowserNGReactMethods"; + +export const { + dataset, + useLdo, + useMatchObject, + useMatchSubject, + useResource, + useSubject, + useSubscribeToResource, +} = createLdoReactMethods([nextGraphConnectedPlugin]); + +const methods = createBrowserNGReactMethods(dataset); + +export const { BrowserNGLdoProvider, useNextGraphAuth } = methods; + diff --git a/sdk/js/examples/react-ldo/src/vite-env.d.ts b/sdk/js/examples/react-ldo/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/sdk/js/examples/react-ldo/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/sdk/js/examples/react-ldo/tailwind.config.js b/sdk/js/examples/react-ldo/tailwind.config.js new file mode 100644 index 0000000..a803e85 --- /dev/null +++ b/sdk/js/examples/react-ldo/tailwind.config.js @@ -0,0 +1,12 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: [ + "./index.html", + "./src/**/*.{js,jsx,ts,tsx}" + ], + theme: { + extend: {}, + }, + plugins: [], +} + diff --git a/sdk/js/examples/react-ldo/tsconfig.app.json b/sdk/js/examples/react-ldo/tsconfig.app.json new file mode 100644 index 0000000..358ca9b --- /dev/null +++ b/sdk/js/examples/react-ldo/tsconfig.app.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/sdk/js/examples/react-ldo/tsconfig.json b/sdk/js/examples/react-ldo/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/sdk/js/examples/react-ldo/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/sdk/js/examples/react-ldo/tsconfig.node.json b/sdk/js/examples/react-ldo/tsconfig.node.json new file mode 100644 index 0000000..db0becc --- /dev/null +++ b/sdk/js/examples/react-ldo/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/sdk/js/examples/react-ldo/vite.config.ts b/sdk/js/examples/react-ldo/vite.config.ts new file mode 100644 index 0000000..8b0f57b --- /dev/null +++ b/sdk/js/examples/react-ldo/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/sdk/js/web/README.md b/sdk/js/web/README.md index 6b200aa..d1b9d37 100644 --- a/sdk/js/web/README.md +++ b/sdk/js/web/README.md @@ -27,7 +27,7 @@ Read our [getting started guide](https://docs.nextgraph.org/en/getting-started/) You need to create a Wallet for yourself, on one of our Public Broker Service Provider. Alternatively, you can do everything locally, as [described below](#local-development) ``` -npm i nextgraphweb +npm i @ng-org/web ``` Additionally, you can use [LDO (Linked Data Object) library](https://ldo.js.org/latest/guides/nextgraph/) to help you with RDF handling in the client side. @@ -68,10 +68,10 @@ You will need to create an admin wallet on the local ngd instance, as explained Then you can use that wallet to log in inside your webapp. -Then compile the nextgraphweb package in dev mode: +Then compile the @ng-org/web package in dev mode: ``` -pnpm run -C ../../helpers/nextgraphweb builddev +pnpm run -C ../../web builddev ``` Then create your app, by example, with the command: @@ -83,9 +83,8 @@ npm create vite@latest change directory to where our app is located. and install dependencies, then run the dev server. ``` -npm install -npm link ../../helpers/nextgraphweb -npm run dev +pnpm install +pnpm dev ``` Due to the way `npm link` works, you will have to run this command again, after every time you use `npm install`. @@ -97,7 +96,7 @@ See the example code in [src/main.js](./src/main.js) call : ```javascript -import { default as ng, init } from "nextgraphweb"; +import { ng, init } from "@ng-org/web"; await init( (event) => { @@ -108,15 +107,12 @@ await init( true, // singleton: boolean (will your app create many docs in the system, or should it be launched as a unique instance) [] ); //list of AccessRequests (for now, leave this empty) - -await ng.login(); // this will return false at the first attempt. but it will open the wallet login page so the user can login. -// if you call it again later once the user has logged in already, it will return true, and nothing more will happen ``` You can alternatively wrap the callback inside a Promise in order to wait for the "loggedin" event. ```javascript -import {default as ng, init} from "nextgraphweb"; +import {default as ng, init} from "@ng-org/web"; let loggedin = new Promise( async (resolve) => { await init( (event) => { diff --git a/sdk/js/web/package.json b/sdk/js/web/package.json index 6982ca2..abca4a5 100644 --- a/sdk/js/web/package.json +++ b/sdk/js/web/package.json @@ -28,14 +28,13 @@ } }, "scripts": { - "dev": "vite", "build": "tsc && vite build", - "builddev": "tsc && cross-env NG_DEV=1 vite build", + "builddevlocal": "tsc && cross-env NG_DEV=1 vite build", + "builddev": "tsc && cross-env NG_DEV_LOCAL_BROKER=1 vite build", "preview": "vite preview" }, "dependencies": { - "async-proxy": "^0.4.1", - "remote-web-streams": "^0.2.0" + "async-proxy": "^0.4.1" }, "devDependencies": { "@types/node": "^18.7.10", diff --git a/sdk/js/web/src/index.ts b/sdk/js/web/src/index.ts index ae6a687..bb84745 100644 --- a/sdk/js/web/src/index.ts +++ b/sdk/js/web/src/index.ts @@ -8,186 +8,88 @@ // according to those terms. import { createAsyncProxy } from "async-proxy"; -import { RemoteReadableStream } from 'remote-web-streams'; -let initialized: null | Window = null; +let initialized = false; -const css = `.nextgraph-auth-modal { - visibility: hidden; - background-color: rgba(0, 0, 0, 0.4); - display: grid; - place-items: center; - - height: 100vh; - width: 100vw; - - position: fixed; - left: 0; - top: 0; -} - -.nextgraph-auth-modal.nextgraph-auth-modal--fade { - opacity: 0; - transition: 0.2s; -} - -.nextgraph-auth-modal.nextgraph-auth-modal--active { - visibility: visible; - z-index: 9999; - opacity: 1; -} - -.nextgraph-auth-modal__content { - width: 100%; - height: 100%; - background-color: #fff; -} - -.nextgraph-auth-modal.nextgraph-auth-modal--active.nextgraph-auth-modal--fade { - opacity: 1; - animation-name: fadeInOpacity; - animation-iteration-count: 1; - animation-timing-function: ease-in; - animation-duration: 0.5s; -} - -@keyframes fadeInOpacity { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } -}`; - -const html = ` -
-
- -
-
`; - -// const javascript = ` -// `; - -function addTags() { - const style = window.document.createElement('style'); - style.textContent = css; - window.document.head.append(style); - - let body = document.getElementsByTagName("body")[0]; - body.insertAdjacentHTML("afterbegin", html); - - // const js = window.document.createElement('script'); - // js.type = "text/javascript"; - // js.textContent = javascript; - // body.append(js); -} - -const iframe_config = import.meta.env.NG_DEV ? {src:"http://localhost:1421/auth.html?o=", origin: "http://localhost:1421"} : {src:"https://nextgraph.net/auth/?o=", origin: "https://nextgraph.net"} ; -// when developing net-auth -//const iframe_config = {src:"http://localhost:14402/?o=", origin: "http://localhost:14402"}; +const config = import.meta.env.NG_DEV ? {redirect:"http://localhost:14402/#/?o=", origin: "http://localhost:14404"} : + import.meta.env.NG_DEV_LOCAL_BROKER ? {redirect:"http://localhost:1421/redir.html#/?o=", origin: "http://localhost:1421"} : + {redirect:"https://nextgraph.net/redir/#/?o=", origin: "https://nextgraph.net"} ; // to test ngnet -//const iframe_config = {src:"http://127.0.0.1:3033/auth/?o=", origin: "http://127.0.0.1:3033"}; - -export const init = async function(callback:Function, singleton:boolean, access_requests:any) { - if (initialized === null) { - if (!window) throw new Error("init(callback,..) can only be called from a browser's window"); - let origin = location.origin; - let encoded_origin = encodeURIComponent(origin); - addTags(); - let iframe: HTMLIFrameElement = window.document.getElementById('nextgraph-auth-iframe'); - if (iframe) { - return new Promise(async (resolve) => { - iframe.addEventListener("load", async function() { - initialized = this.contentWindow; - const { readable, writablePort } = new RemoteReadableStream(); - initialized?.postMessage({ method: "init", singleton, access_requests, port: writablePort }, iframe_config.origin, [writablePort]); - const reader = readable.getReader(); - resolve(true); - for (var msg; msg = await reader.read(); ) { - if (msg.done) break; - if (msg.value.status == "error") { - console.error(msg.value.error); - } else if ( msg.value.status == "cancelled") { - hide_nextgraph_auth(); - } else if (msg.value.status == "loggedin") { - hide_nextgraph_auth(); - } - await (callback)(msg.value); - } - }); - iframe.src = `${iframe_config.src}${encoded_origin}`; - }); - } +//const config = {redirect:"http://127.0.0.1:3033/auth/#/?o=", origin: "http://127.0.0.1:3033"}; + +export const init = async function(callback:Function | null, singleton:boolean, access_requests:any) { + if (!window) throw new Error("init(callback,..) can only be called from a browser's window"); + if (window.self === window.top){ + window.location.href = config.redirect + encodeURIComponent(window.location.href); + } else if (initialized === false) { + const { port1, port2 } = new MessageChannel(); + port1.onmessage = async (m) => { + //console.log("got message in ng-web", m); + if (m.data.ok) { + initialized = m.data.ret; + if (callback) { await (callback)({status:"loggedin", session:initialized}); } + } + port1.close(); + }; + parent.postMessage({ method: "init", origin: window.location.href, singleton, access_requests, port: port2 }, config.origin, [port2]); + } else { + throw new Error("you must call init() only once"); } } -function show_nextgraph_auth() { - window.document.getElementById("nextgraph-auth")?.classList.add('nextgraph-auth-modal--active'); -} - -function hide_nextgraph_auth() { - window.document.getElementById("nextgraph-auth")?.classList.remove('nextgraph-auth-modal--active'); -} - -async function rpc( method:string, args?: any) : Promise { - const { readable, writablePort } = new RemoteReadableStream(); +function rpc( method:string, args?: any) : Promise { + const { port1, port2 } = new MessageChannel(); //console.log("POSTING",method, args); - if (method==="doc_subscribe") { + if (method==="doc_subscribe") { //TODO: add all the streamed functions let callback = args[2]; let new_args = [args[0],args[1]]; - initialized?.postMessage({ method, args:new_args, port: writablePort }, iframe_config.origin, [writablePort]); - const reader = readable.getReader(); + parent.postMessage({ method, args:new_args, port: port2 }, config.origin, [port2]); let unsub = new Promise(async (resolve)=> { resolve(()=>{ - // unsub function that does nothing. - //TODO: implement it + port1.close(); }); - for (var msg; msg = await reader.read(); ) { - if (msg.done) break; - if (msg.value.error) { - throw new Error(msg.value.ret); - } else if (msg.value.stream) { - (callback)(msg.value.ret); - } - // TODO: deal with end of stream - } }); + port1.onmessage = async (m) => { + if (m.data.stream) { + await (callback)(m.data.ret); + } else if (!m.data.ok) { + throw new Error(m.data.ret); + } + }; + //port2.onclose = () return unsub; } else { - initialized?.postMessage({ method, args, port: writablePort }, iframe_config.origin, [writablePort]); - const reader = readable.getReader(); - let ret = await reader.read(); - //console.log(ret) - await reader.read(); // the close - if (ret.value.ok) - return ret.value.ret; - else - throw new Error(ret.value.ret); + parent.postMessage({ method, args, port: port2 }, config.origin, [port2]); + return new Promise((resolve, reject)=> { + port1.onmessage = (m) => { + //console.log(m.data); + if (m.data.ok) { + resolve(m.data.ret); + } else { + console.error("method "+method+" with args ", args, " failed with ",m.data.ret); + reject(new Error(m.data.ret)); + } + }; + }); } - } const handler = { - async apply(_target: object, path: PropertyKey[], _caller: any, args?: any) :Promise { - if (initialized === null) { + apply(_target: object, path: PropertyKey[], _caller: any, args?: any) :Promise { + if (initialized === false) { throw new Error("you must call init() first (and once)"); } - if (path[0] === "login") { - if (await rpc("login") !== true) { - show_nextgraph_auth(); - return false; - } else { - return true; - } - } else { - return await rpc(path[0], args); - } + // if (path[0] === "login") { + // if (await rpc("login") !== true) { + // return false; + // } else { + // return true; + // } + // } else { + return rpc(path[0], args); + //} } }; diff --git a/sdk/rust/README.md b/sdk/rust/README.md index d658116..eb39451 100644 --- a/sdk/rust/README.md +++ b/sdk/rust/README.md @@ -11,7 +11,7 @@ [![Crates.io Version](https://img.shields.io/crates/v/nextgraph)](https://crates.io/crates/nextgraph) [![docs.rs](https://img.shields.io/docsrs/nextgraph)](https://docs.rs/nextgraph) [node:![NPM Version node](https://img.shields.io/npm/v/nextgraph)](https://www.npmjs.com/package/nextgraph) -[web:![NPM Version web](https://img.shields.io/npm/v/nextgraphweb)](https://www.npmjs.com/package/nextgraphweb) +[web:![NPM Version web](https://img.shields.io/npm/v/@ng-org/web)](https://www.npmjs.com/package/@ng-org/web) Rust client library for NextGraph framework