From d9d1cc0b38a48b5fe0ab3e501d03b5f69fd2e998 Mon Sep 17 00:00:00 2001 From: Spark Plug Date: Tue, 27 Aug 2024 21:39:44 -0400 Subject: [PATCH 01/23] Init AppRegistry --- services/user/AppRegistry/Cargo.toml | 20 + services/user/AppRegistry/plugin/Cargo.toml | 17 + services/user/AppRegistry/plugin/src/lib.rs | 15 + .../user/AppRegistry/plugin/wit/world.wit | 13 + services/user/AppRegistry/query/Cargo.toml | 17 + services/user/AppRegistry/query/src/lib.rs | 21 + services/user/AppRegistry/service/Cargo.toml | 22 + services/user/AppRegistry/service/src/lib.rs | 14 + services/user/AppRegistry/src/lib.rs | 2 + services/user/AppRegistry/ui/.eslintignore | 1 + services/user/AppRegistry/ui/.eslintrc.cjs | 19 + services/user/AppRegistry/ui/.gitignore | 24 + services/user/AppRegistry/ui/README.md | 19 + services/user/AppRegistry/ui/components.json | 17 + services/user/AppRegistry/ui/index.html | 13 + services/user/AppRegistry/ui/package.json | 62 + .../user/AppRegistry/ui/postcss.config.cjs | 9 + .../user/AppRegistry/ui/prettier.config.cjs | 4 + services/user/AppRegistry/ui/public/vite.svg | 1 + .../ui/src/components/account-switcher.tsx | 54 + .../AppRegistry/ui/src/components/index.ts | 1 + .../ui/src/components/nav-menu.tsx | 48 + .../AppRegistry/ui/src/components/nav.tsx | 96 + .../user/AppRegistry/ui/src/fixtures/data.ts | 10 + .../user/AppRegistry/ui/src/hooks/index.ts | 2 + .../ui/src/hooks/use-local-storage.ts | 62 + .../user/AppRegistry/ui/src/hooks/use-user.ts | 12 + .../AppRegistry/ui/src/layouts/default.tsx | 26 + services/user/AppRegistry/ui/src/lib/utils.ts | 27 + services/user/AppRegistry/ui/src/main.tsx | 41 + .../user/AppRegistry/ui/src/routes/about.tsx | 15 + .../user/AppRegistry/ui/src/routes/home.tsx | 24 + .../user/AppRegistry/ui/src/routes/index.ts | 2 + .../ui/src/shad/components/ui/button.tsx | 57 + .../ui/src/shad/components/ui/form.tsx | 176 + .../ui/src/shad/components/ui/input.tsx | 25 + .../ui/src/shad/components/ui/label.tsx | 24 + .../ui/src/shad/components/ui/select.tsx | 158 + .../ui/src/shad/components/ui/separator.tsx | 31 + .../ui/src/shad/components/ui/tabs.tsx | 53 + .../ui/src/shad/components/ui/textarea.tsx | 24 + .../ui/src/shad/components/ui/toggle.tsx | 43 + .../ui/src/shad/components/ui/tooltip.tsx | 28 + .../user/AppRegistry/ui/src/styles/editor.css | 152 + .../AppRegistry/ui/src/styles/globals.css | 76 + .../user/AppRegistry/ui/src/vite-env.d.ts | 1 + .../user/AppRegistry/ui/tailwind.config.cjs | 80 + services/user/AppRegistry/ui/tsconfig.json | 44 + .../user/AppRegistry/ui/tsconfig.node.json | 9 + services/user/AppRegistry/ui/vite.config.ts | 140 + services/user/AppRegistry/ui/yarn.lock | 3534 +++++++++++++++++ 51 files changed, 5385 insertions(+) create mode 100644 services/user/AppRegistry/Cargo.toml create mode 100644 services/user/AppRegistry/plugin/Cargo.toml create mode 100644 services/user/AppRegistry/plugin/src/lib.rs create mode 100644 services/user/AppRegistry/plugin/wit/world.wit create mode 100644 services/user/AppRegistry/query/Cargo.toml create mode 100644 services/user/AppRegistry/query/src/lib.rs create mode 100644 services/user/AppRegistry/service/Cargo.toml create mode 100644 services/user/AppRegistry/service/src/lib.rs create mode 100644 services/user/AppRegistry/src/lib.rs create mode 100644 services/user/AppRegistry/ui/.eslintignore create mode 100644 services/user/AppRegistry/ui/.eslintrc.cjs create mode 100644 services/user/AppRegistry/ui/.gitignore create mode 100644 services/user/AppRegistry/ui/README.md create mode 100644 services/user/AppRegistry/ui/components.json create mode 100644 services/user/AppRegistry/ui/index.html create mode 100644 services/user/AppRegistry/ui/package.json create mode 100644 services/user/AppRegistry/ui/postcss.config.cjs create mode 100644 services/user/AppRegistry/ui/prettier.config.cjs create mode 100644 services/user/AppRegistry/ui/public/vite.svg create mode 100644 services/user/AppRegistry/ui/src/components/account-switcher.tsx create mode 100644 services/user/AppRegistry/ui/src/components/index.ts create mode 100644 services/user/AppRegistry/ui/src/components/nav-menu.tsx create mode 100644 services/user/AppRegistry/ui/src/components/nav.tsx create mode 100644 services/user/AppRegistry/ui/src/fixtures/data.ts create mode 100644 services/user/AppRegistry/ui/src/hooks/index.ts create mode 100644 services/user/AppRegistry/ui/src/hooks/use-local-storage.ts create mode 100644 services/user/AppRegistry/ui/src/hooks/use-user.ts create mode 100644 services/user/AppRegistry/ui/src/layouts/default.tsx create mode 100644 services/user/AppRegistry/ui/src/lib/utils.ts create mode 100644 services/user/AppRegistry/ui/src/main.tsx create mode 100644 services/user/AppRegistry/ui/src/routes/about.tsx create mode 100644 services/user/AppRegistry/ui/src/routes/home.tsx create mode 100644 services/user/AppRegistry/ui/src/routes/index.ts create mode 100644 services/user/AppRegistry/ui/src/shad/components/ui/button.tsx create mode 100644 services/user/AppRegistry/ui/src/shad/components/ui/form.tsx create mode 100644 services/user/AppRegistry/ui/src/shad/components/ui/input.tsx create mode 100644 services/user/AppRegistry/ui/src/shad/components/ui/label.tsx create mode 100644 services/user/AppRegistry/ui/src/shad/components/ui/select.tsx create mode 100644 services/user/AppRegistry/ui/src/shad/components/ui/separator.tsx create mode 100644 services/user/AppRegistry/ui/src/shad/components/ui/tabs.tsx create mode 100644 services/user/AppRegistry/ui/src/shad/components/ui/textarea.tsx create mode 100644 services/user/AppRegistry/ui/src/shad/components/ui/toggle.tsx create mode 100644 services/user/AppRegistry/ui/src/shad/components/ui/tooltip.tsx create mode 100644 services/user/AppRegistry/ui/src/styles/editor.css create mode 100644 services/user/AppRegistry/ui/src/styles/globals.css create mode 100644 services/user/AppRegistry/ui/src/vite-env.d.ts create mode 100644 services/user/AppRegistry/ui/tailwind.config.cjs create mode 100644 services/user/AppRegistry/ui/tsconfig.json create mode 100644 services/user/AppRegistry/ui/tsconfig.node.json create mode 100644 services/user/AppRegistry/ui/vite.config.ts create mode 100644 services/user/AppRegistry/ui/yarn.lock diff --git a/services/user/AppRegistry/Cargo.toml b/services/user/AppRegistry/Cargo.toml new file mode 100644 index 000000000..8184b77d9 --- /dev/null +++ b/services/user/AppRegistry/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "app_registry" +version.workspace = true +rust-version.workspace = true +repository.workspace = true +homepage.workspace = true +edition = "2021" +publish = false + +[package.metadata.psibase] +package-name = "AppRegistry" +description = "Registry for psibase apps" +services = ["tpack"] + +[lib] +crate-type = ["rlib"] + +[dependencies] +tpack = { path = "service", version = "0.12.0" } +r-tpack = { path = "query", version = "0.12.0" } diff --git a/services/user/AppRegistry/plugin/Cargo.toml b/services/user/AppRegistry/plugin/Cargo.toml new file mode 100644 index 000000000..41bdb9f1d --- /dev/null +++ b/services/user/AppRegistry/plugin/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "tpack-plugin" +version = "0.1.0" +edition = "2021" + +[dependencies] +wit-bindgen-rt = { version = "0.26.0", features = ["bitflags"] } +psibase = { path="../../psibase/" } + +[lib] +crate-type = ["cdylib"] + +[package.metadata.component] +package = "tpack:plugin" + +[package.metadata.component.target.dependencies] +"host:common" = { path = "../../../services/user/CommonApi/common/packages/wit/host-common.wit" } diff --git a/services/user/AppRegistry/plugin/src/lib.rs b/services/user/AppRegistry/plugin/src/lib.rs new file mode 100644 index 000000000..3203d7ef0 --- /dev/null +++ b/services/user/AppRegistry/plugin/src/lib.rs @@ -0,0 +1,15 @@ +#[allow(warnings)] +mod bindings; + +use bindings::exports::test_package::plugin::test::Guest as Test; +use bindings::host::common::types as CommonTypes; + +struct TestPlugin; + +impl Test for TestPlugin { + fn foo() -> Result<(), CommonTypes::Error> { + Ok(()) + } +} + +bindings::export!(TestPlugin with_types_in bindings); diff --git a/services/user/AppRegistry/plugin/wit/world.wit b/services/user/AppRegistry/plugin/wit/world.wit new file mode 100644 index 000000000..ebd9742ed --- /dev/null +++ b/services/user/AppRegistry/plugin/wit/world.wit @@ -0,0 +1,13 @@ +package test-package:plugin; + +interface test { + use host:common/types.{error}; + + foo: func() -> result<_, error>; +} + +world psibase-plugin { + import host:common/server; + export test; +} + diff --git a/services/user/AppRegistry/query/Cargo.toml b/services/user/AppRegistry/query/Cargo.toml new file mode 100644 index 000000000..db6df3a13 --- /dev/null +++ b/services/user/AppRegistry/query/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "r-tpack" +description = "Query service for package building test" +version.workspace = true +rust-version.workspace = true +repository.workspace = true +homepage.workspace = true +edition = "2021" +publish = false + +[package.metadata.psibase] +plugin = "tpack-plugin" + +[dependencies] +psibase = { path = "../../psibase", version = "0.12.0" } +serde = "1.0" +tpack = { path = "../service", version = "0.12.0" } diff --git a/services/user/AppRegistry/query/src/lib.rs b/services/user/AppRegistry/query/src/lib.rs new file mode 100644 index 000000000..39357466a --- /dev/null +++ b/services/user/AppRegistry/query/src/lib.rs @@ -0,0 +1,21 @@ +#[psibase::service] +#[allow(non_snake_case)] +mod service { + use psibase::*; + use tpack; + + #[table(record = "WebContentRow", index = 0)] + struct WebContentTable; + + #[action] + fn storeSys(path: String, contentType: String, content: Hex>) { + println!("{} {}", path, contentType); + store_content(path, contentType, content, &WebContentTable::new()).unwrap() + } + + #[action] + fn serveSys(request: HttpRequest) -> Option { + None.or_else(|| serve_content(&request, &WebContentTable::new())) + .or_else(|| serve_simple_ui::(&request)) + } +} diff --git a/services/user/AppRegistry/service/Cargo.toml b/services/user/AppRegistry/service/Cargo.toml new file mode 100644 index 000000000..67624f591 --- /dev/null +++ b/services/user/AppRegistry/service/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "tpack" +description = "Test service for package building" +version.workspace = true +rust-version.workspace = true +repository.workspace = true +homepage.workspace = true +edition = "2021" +publish = false + +[package.metadata.psibase] +server = "r-tpack" + +[package.metadata.psibase.dependencies] +HttpServer = "0.12.0" + +[dependencies] +psibase = { path = "../../psibase", version = "0.12.0" } +serde = "1.0" + +[dev-dependencies] +test_package = { path = "..", version = "0.12.0" } diff --git a/services/user/AppRegistry/service/src/lib.rs b/services/user/AppRegistry/service/src/lib.rs new file mode 100644 index 000000000..6bb21d612 --- /dev/null +++ b/services/user/AppRegistry/service/src/lib.rs @@ -0,0 +1,14 @@ +#[psibase::service] +#[allow(non_snake_case)] +mod service { + #[action] + fn foo(value: i32) -> i32 { + value + } +} + +#[psibase::test_case(packages("TestPackage"))] +fn test_foo(chain: psibase::Chain) -> Result<(), psibase::Error> { + assert_eq!(Wrapper::push(&chain).foo(42).get()?, 42); + Ok(()) +} diff --git a/services/user/AppRegistry/src/lib.rs b/services/user/AppRegistry/src/lib.rs new file mode 100644 index 000000000..25ee82c5a --- /dev/null +++ b/services/user/AppRegistry/src/lib.rs @@ -0,0 +1,2 @@ +pub use r_tpack; +pub use tpack; diff --git a/services/user/AppRegistry/ui/.eslintignore b/services/user/AppRegistry/ui/.eslintignore new file mode 100644 index 000000000..b512c09d4 --- /dev/null +++ b/services/user/AppRegistry/ui/.eslintignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/services/user/AppRegistry/ui/.eslintrc.cjs b/services/user/AppRegistry/ui/.eslintrc.cjs new file mode 100644 index 000000000..ff9863c41 --- /dev/null +++ b/services/user/AppRegistry/ui/.eslintrc.cjs @@ -0,0 +1,19 @@ +module.exports = { + extends: ["plugin:prettier/recommended"], + plugins: ["prettier"], + rules: { + quotes: ["error", "double"], + "react/react-in-jsx-scope": "off", + "no-unused-vars": "off", + "react/jsx-props-no-spreading": "off", + "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: ["**/*.config.ts", "**/*.config.js"], + }, + ], + "no-nested-ternary": "off", + "react/no-unstable-nested-components": "off", + }, +}; diff --git a/services/user/AppRegistry/ui/.gitignore b/services/user/AppRegistry/ui/.gitignore new file mode 100644 index 000000000..a547bf36d --- /dev/null +++ b/services/user/AppRegistry/ui/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/services/user/AppRegistry/ui/README.md b/services/user/AppRegistry/ui/README.md new file mode 100644 index 000000000..88e8e8123 --- /dev/null +++ b/services/user/AppRegistry/ui/README.md @@ -0,0 +1,19 @@ +# Psibase AppRegistry + +Steps to run the app in dev mode: + +```sh +# after building psibase at the root of the repo +cd build +./psinode --http-timeout 10 db +open http://localhost:8080 + +# go through the steps to create a network in dev mode, name the producer as prod and confirm + +# ui development, from this ui folder +yarn dev +open http://appregistry.psibase.127.0.0.1.sslip.io:8081/ + +# about writing a psibase service (kind of a smart contract in evm world) +open http://docs.psibase.127.0.0.1.sslip.io:8080/development/services/rust-service/index.html +``` diff --git a/services/user/AppRegistry/ui/components.json b/services/user/AppRegistry/ui/components.json new file mode 100644 index 000000000..d014402ad --- /dev/null +++ b/services/user/AppRegistry/ui/components.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "tailwind.config.cjs", + "css": "src/styles/globals.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "src/shad/components", + "utils": "src/lib/utils" + } +} \ No newline at end of file diff --git a/services/user/AppRegistry/ui/index.html b/services/user/AppRegistry/ui/index.html new file mode 100644 index 000000000..f33e09d7d --- /dev/null +++ b/services/user/AppRegistry/ui/index.html @@ -0,0 +1,13 @@ + + + + + + + App Registry + + +
+ + + diff --git a/services/user/AppRegistry/ui/package.json b/services/user/AppRegistry/ui/package.json new file mode 100644 index 000000000..b6699c451 --- /dev/null +++ b/services/user/AppRegistry/ui/package.json @@ -0,0 +1,62 @@ +{ + "name": "app-registry", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview" + }, + "dependencies": { + "@radix-ui/react-label": "^2.1.0", + "@radix-ui/react-select": "^2.0.0", + "@radix-ui/react-separator": "^1.0.3", + "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-tabs": "^1.0.4", + "@radix-ui/react-toggle": "^1.0.3", + "@radix-ui/react-tooltip": "^1.0.7", + "@tanstack/react-query": "^5.51.18", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "date-fns": "^3.6.0", + "jotai": "^2.8.3", + "lucide-react": "^0.378.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-hook-form": "^7.52.1", + "react-router-dom": "^6.23.1", + "tailwind-merge": "^2.3.0", + "tailwindcss-animate": "^1.0.7", + "zod": "^3.23.8" + }, + "devDependencies": { + "@rollup/plugin-alias": "^5.1.0", + "@tailwindcss/forms": "^0.5.7", + "@tailwindcss/typography": "^0.5.13", + "@types/node": "^20.12.12", + "@types/react": "^18.2.66", + "@types/react-dom": "^18.2.22", + "@typescript-eslint/eslint-plugin": "^7.2.0", + "@typescript-eslint/parser": "^7.2.0", + "@vitejs/plugin-react": "^4.2.1", + "autoprefixer": "^10.4.19", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.6", + "postcss": "^8.4.38", + "postcss-import": "^16.1.0", + "prettier": "^3.2.5", + "prettier-plugin-tailwindcss": "^0.5.14", + "tailwindcss": "^3.4.3", + "typescript": "^5.2.2", + "vite": "^5.2.0", + "vite-plugin-top-level-await": "^1.4.1", + "vite-plugin-wasm": "^3.3.0", + "vite-tsconfig-paths": "^4.3.2" + } +} \ No newline at end of file diff --git a/services/user/AppRegistry/ui/postcss.config.cjs b/services/user/AppRegistry/ui/postcss.config.cjs new file mode 100644 index 000000000..03f0d9855 --- /dev/null +++ b/services/user/AppRegistry/ui/postcss.config.cjs @@ -0,0 +1,9 @@ +// postcss.config.js +module.exports = { + plugins: { + "postcss-import": {}, + "tailwindcss/nesting": {}, + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/services/user/AppRegistry/ui/prettier.config.cjs b/services/user/AppRegistry/ui/prettier.config.cjs new file mode 100644 index 000000000..abcc39636 --- /dev/null +++ b/services/user/AppRegistry/ui/prettier.config.cjs @@ -0,0 +1,4 @@ +module.exports = { + tabWidth: 4, + plugins: ["prettier-plugin-tailwindcss"], +} \ No newline at end of file diff --git a/services/user/AppRegistry/ui/public/vite.svg b/services/user/AppRegistry/ui/public/vite.svg new file mode 100644 index 000000000..e7b8dfb1b --- /dev/null +++ b/services/user/AppRegistry/ui/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/services/user/AppRegistry/ui/src/components/account-switcher.tsx b/services/user/AppRegistry/ui/src/components/account-switcher.tsx new file mode 100644 index 000000000..2e8303114 --- /dev/null +++ b/services/user/AppRegistry/ui/src/components/account-switcher.tsx @@ -0,0 +1,54 @@ +import { useUser } from "@hooks"; +import { cn } from "@lib/utils"; +import { accounts } from "src/fixtures/data"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@shadcn/select"; + +interface AccountSwitcherProps { + isCollapsed: boolean; +} + +export function AccountSwitcher({ isCollapsed }: AccountSwitcherProps) { + const [selectedAccount, setSelectedAccount] = useUser(); + + return ( + + ); +} diff --git a/services/user/AppRegistry/ui/src/components/index.ts b/services/user/AppRegistry/ui/src/components/index.ts new file mode 100644 index 000000000..06f4679ba --- /dev/null +++ b/services/user/AppRegistry/ui/src/components/index.ts @@ -0,0 +1 @@ +export * from "./nav-menu"; diff --git a/services/user/AppRegistry/ui/src/components/nav-menu.tsx b/services/user/AppRegistry/ui/src/components/nav-menu.tsx new file mode 100644 index 000000000..57e66e741 --- /dev/null +++ b/services/user/AppRegistry/ui/src/components/nav-menu.tsx @@ -0,0 +1,48 @@ +import { PencilLine, Send, Inbox } from "lucide-react"; + +import { Separator } from "@shadcn/separator"; +import { cn } from "@lib/utils"; + +import { AccountSwitcher } from "./account-switcher"; +import { Nav } from "./nav"; +import { useLocation } from "react-router-dom"; + +interface Props { + isCollapsed?: boolean; +} + +export const NavMenu = ({ isCollapsed = false }: Props) => { + const location = useLocation(); + const at = location.pathname; + + return ( + <> +
+ +
+ +