From c45fe10d6556d14d64d08d7a4c6b8cffdf496477 Mon Sep 17 00:00:00 2001 From: Xavier Brinon Date: Fri, 17 Nov 2023 07:27:29 +0000 Subject: [PATCH] create basic http-ts app --- hi/.gitignore | 4 + hi/README.md | 3 + hi/package.json | 22 +++++ hi/spin.toml | 17 ++++ hi/src/index.ts | 9 ++ hi/tsconfig.json | 15 ++++ hi/webpack.config.js | 25 ++++++ quickstart.org | 197 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 292 insertions(+) create mode 100644 hi/.gitignore create mode 100644 hi/README.md create mode 100644 hi/package.json create mode 100644 hi/spin.toml create mode 100644 hi/src/index.ts create mode 100644 hi/tsconfig.json create mode 100644 hi/webpack.config.js create mode 100644 quickstart.org diff --git a/hi/.gitignore b/hi/.gitignore new file mode 100644 index 0000000..502e225 --- /dev/null +++ b/hi/.gitignore @@ -0,0 +1,4 @@ +node_modules +dist +target +.spin/ \ No newline at end of file diff --git a/hi/README.md b/hi/README.md new file mode 100644 index 0000000..f6b0556 --- /dev/null +++ b/hi/README.md @@ -0,0 +1,3 @@ +## HTTP-TS template + +This is a simple template to get started with spin-js-sdk using typescript. \ No newline at end of file diff --git a/hi/package.json b/hi/package.json new file mode 100644 index 0000000..6543a92 --- /dev/null +++ b/hi/package.json @@ -0,0 +1,22 @@ +{ + "name": "hi", + "version": "1.0.0", + "description": "says hi", + "main": "index.js", + "scripts": { + "build": "npx webpack --mode=production && mkdir -p target && spin js2wasm -o target/hi.wasm dist/spin.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "ts-loader": "^9.4.1", + "typescript": "^4.8.4", + "webpack": "^5.74.0", + "webpack-cli": "^4.10.0" + }, + "dependencies": { + "@fermyon/spin-sdk": "0.6.0" + } +} diff --git a/hi/spin.toml b/hi/spin.toml new file mode 100644 index 0000000..4f7e8fd --- /dev/null +++ b/hi/spin.toml @@ -0,0 +1,17 @@ +spin_manifest_version = 2 + +[application] +authors = ["haqadosch"] +description = "says hi" +name = "hi" +version = "0.1.0" + +[[trigger.http]] +route = "/hi" +component = "hi" + +[component.hi] +source = "target/hi.wasm" +exclude_files = ["**/node_modules"] +[component.hi.build] +command = "npm run build" diff --git a/hi/src/index.ts b/hi/src/index.ts new file mode 100644 index 0000000..e9dcdc9 --- /dev/null +++ b/hi/src/index.ts @@ -0,0 +1,9 @@ +import { HandleRequest, HttpRequest, HttpResponse } from "@fermyon/spin-sdk" + +export const handleRequest: HandleRequest = async function (request: HttpRequest): Promise { + return { + status: 200, + headers: { "content-type": "text/plain" }, + body: "Hello from TS-SDK" + } +} diff --git a/hi/tsconfig.json b/hi/tsconfig.json new file mode 100644 index 0000000..ab79d5a --- /dev/null +++ b/hi/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "outDir": "./dist/", + "noImplicitAny": true, + "module": "es6", + "target": "es5", + "jsx": "react", + "skipLibCheck": true, + "lib": ["ES2015"], + "allowJs": true, + "strict": true, + "noImplicitReturns": true, + "moduleResolution": "node" + } +} \ No newline at end of file diff --git a/hi/webpack.config.js b/hi/webpack.config.js new file mode 100644 index 0000000..0b0c45e --- /dev/null +++ b/hi/webpack.config.js @@ -0,0 +1,25 @@ +const path = require('path'); + +module.exports = { + entry: './src/index.ts', + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'spin.js', + library: 'spin' + }, + optimization: { + minimize: false + }, +}; diff --git a/quickstart.org b/quickstart.org new file mode 100644 index 0000000..030f91e --- /dev/null +++ b/quickstart.org @@ -0,0 +1,197 @@ +#+title: quickstart to the spin wasm build +#+date:[2023-11-16 Thu] +#+author: Xavier Brinon +#+startup: indent +* Org shortcuts +- create footnote :: ~C-c C-x f~ +- jump to the footnote ref :: ~C-c C-c~ +* Setup +** 1: Install +#+description: check if ~spin~ is installed +#+name: installed? +#+begin_src shell + spin -V +#+end_src + +#+RESULTS: installed? +: spin 2.0.1 (1d72f1c 2023-11-10) + +If it is not installed, ~curl~ the shell file. Make sure to install it in your +path, something like =/usr/local/bin=. +#+description: installing spin +#+name: install spin +#+begin_src shell + curl -fsSL https://developer.fermyon.com/downloads/install.sh | bash + sudo mv ./spin /usr/local/bin/spin +#+end_src +** 2: Using templates +The shell script in first step installs the template. If this is missing, use +~spin~. +#+description: installing the templates +#+name: templates install +#+begin_src shell + # Rust templates + spin templates install --git https://github.com/fermyon/spin --update + rustup target add wasm32-wasi + # Typescript to Wasm + spin plugins update + spin plugins install js2wasm --yes + spin templates install --git https://github.com/fermyon/spin-js-sdk --update +#+end_src + +* Creating the App +** Spin new +We use ~spin new~ with the =http-ts= template to create the skeleton of a new +*Spin application* +#+description: spin a new app using http-ts template +#+name: new http-ts template +#+begin_src shell + spin new -t http-ts # We can do http-js for pure javascript +#+end_src +When prompted, enter: +- =name= :: hi +- =description= :: says hi +- =path= :: /hi + + +A new folder has been created with the =name= of the application. +#+description: content of the spin application folder +#+name: content folder +#+begin_src shell + cd hi/ + tree +#+end_src + +#+RESULTS: content folder +| . +| ├── package.json +| ├── README.md +| ├── spin.toml +| ├── src +| │   └── index.ts +| ├── tsconfig.json +| └── webpack.config.js +| +| 2 directories, 6 files + +** Manifest file +The =spin.toml= is the *manifest* for the application. It tells *spin* what +*events* should trigger what *components* + +#+begin_src toml + spin_manifest_version = 2 + + [application] + authors = ["haqadosch"] + description = "says hi" + name = "hi" + version = "0.1.0" + + [[trigger.http]] + route = "/hi" + component = "hi" + + [component.hi] + source = "target/hi.wasm" + exclude_files = ["**/node_modules"] + [component.hi.build] + command = "npm run build" +#+end_src +We can see that the app is configured to trigger the component "hi" at the route +"/hi". Any other routes will be ignored. +* Build the application +** Install the node modules +Since this is a *typesccript* app, we need to ~npm install~ everything. This is +no different than any other node app, in the same folder as =package.json=, the +root folder, do the install. +#+description: installing the node modules for the app +#+name: npm install +#+begin_src shell + npm install +#+end_src +** Build the spin app +To run the *build* instruction for all the *components* defined is the +*manifest* file, +#+begin_src shell + spin build +#+end_src + +The ~spin build~ command is a shortcut of the build command in the *manifest* +#+begin_src toml + [component.hi.build] + command = "npm run build" +#+end_src +That means you can directly type ~npm run build~ in the root folder instead of +~spin build~. +** Run the application +You can spin up the application by running the following command +#+name: spin up +#+begin_src shell + cd hi + spin up +#+end_src + +#+RESULTS: spin up +| Logging component stdio to .spin/logs/ +| +| Serving http://127.0.0.1:3000 +| Available Routes: +| hi: http://127.0.0.1:3000/hi + +Visiting the URL =http://localhost:3000/hi= will display the message +"Hello from TS-SDK". + +You can log the activity of the app by setting the *environment variable* +~RUST_LOG~. This variable is independent of the template used for the app. +#+description: logging app activity +#+name: rust_log +#+begin_src shell + export RUST_LOG=spin=trace + spin up +#+end_src + +By visiting the same URL as before, you can see the following logs +#+begin_src shell + 2023-11-16T21:46:59.858033Z DEBUG spin_loader::cache: using cache root directory .cache/spin/registry + 2023-11-16T21:46:59.859288Z TRACE spin_cli::commands::up: Running trigger executor: SPIN_LOCAL_APP_DIR="" SPIN_LOCKED_URL="file:///tmp/spinup-Chh8Cn/spin.lock" SPIN_WORKING_DIR="/tmp/spinup-Chh8Cn" "/usr/local/bin/spin" "trigger" "http" + Logging component stdio to ".spin/logs/" + 2023-11-16T21:47:00.272884Z TRACE spin_trigger_http: Constructed router for application hi: [(Exact("/hi"), "hi")] + + Serving http://127.0.0.1:3000 + 2023-11-16T21:47:00.273007Z INFO spin_trigger_http: Serving http://127.0.0.1:3000 + Available Routes: + hi: http://127.0.0.1:3000/hi + 2023-11-16T21:47:07.785975Z INFO spin_trigger_http: Processing request for application hi on URI http://localhost:3000/hi + 2023-11-16T21:47:07.786012Z TRACE spin_trigger_http::handler: Executing request using the Spin executor for component hi + 2023-11-16T21:47:07.790199Z INFO spin_trigger_http::handler: Request finished, sending response with status code 200 OK + 2023-11-16T21:47:07.887633Z INFO spin_trigger_http: Processing request for application hi on URI http://localhost:3000/favicon.ico +#+end_src +* Deploy the application +** Login +Make sure you're logged in with *Github* first. Once done the deployment +process can start. +#+description: deploying +#+name: spin deploy +#+begin_src shell + spin deploy +#+end_src + +#+RESULTS: spin deploy +Copy your one-time code: + +djqIipGu + +...and open the authorization page in your browser: + +https://cloud.fermyon.com/device-authorization + +Waiting for device authorization... +Device authorized! +Uploading hi version 0.1.0 to Fermyon Cloud... +Deploying... +Waiting for application to become ready............ ready +Available Routes: + hi: https://hi-7tx.fermyon.app/hi +** Running the app in the cloud +Now visiting https://hi-7tx.fermyon.app/hi will display the same message. +The [[https://cloud.fermyon.com/][Fermyon Cloud]] has a dashboard for your app.