Make money with Oziconnect referral program

Let’s look a little deeper into the heart of WebAssembly integration by examining the key segments of the Go-based WASM code.

This includes preparing and specifying the Go code that will be compiled for the WebAssembly runtime.

// go:build wasm
// +build wasm

These lines act as directives to the Go compiler, indicating that the following code is specified for the WebAssembly runtime environment. in particular:

  • //go:build wasm: Build constraints that ensure that code complies with modern syntax and only compiles against WASM targets.
  • // +build wasm: Similar constraints that utilize old syntax for compatibility with previous Go versions.

Essentially, these directives guide the compiler to only include this code segment when compiling for the WebAssembly architecture, ensuring proper setup and functionality within this particular runtime.

package main

import (
"context"
"encoding/json"
"syscall/js"

"google.golang.org/protobuf/encoding/protojson"

"github.com/Permify/permify/pkg/development"
)

var dev *development.Development

func run() js.Func {
// The `run` function returns a new JavaScript function
// that wraps the Go function.
return js.FuncOf(func(this js.Value, args []js.Value) interface

// t will be used to store the unmarshaled JSON data.
// The use of an empty interface type means it can hold any type of value.
var t interface

// Unmarshal JSON from JavaScript function argument (args[0]) to Go's data structure (map).
// args[0].String() gets the JSON string from the JavaScript argument,
// which is then converted to bytes and unmarshaled (parsed) into the map `t`.
err := json.Unmarshal([]byte(args[0].String()), &t)

// If an error occurs during unmarshaling (parsing) the JSON,
// it returns an array with the error message "invalid JSON" to JavaScript.
if err != nil
return js.ValueOf([]interface"invalid JSON")

// Attempt to assert that the parsed JSON (`t`) is a map with string keys.
// This step ensures that the unmarshaled JSON is of the expected type (map).
input, ok := t.(map[string]interface)

// If the assertion is false (`ok` is false),
// it returns an array with the error message "invalid JSON" to JavaScript.
if !ok
return js.ValueOf([]interface"invalid JSON")

// Run the main logic of the application with the parsed input.
// It’s assumed that `dev.Run` processes `input` in some way and returns any errors encountered during that process.
errors := dev.Run(context.Background(), input)

// If no errors are present (the length of the `errors` slice is 0),
// return an empty array to JavaScript to indicate success with no errors.
if len(errors) == 0
return js.ValueOf([]interface)

// If there are errors, each error in the `errors` slice is marshaled (converted) to a JSON string.
// `vs` is a slice that will store each of these JSON error strings.
vs := make([]interface, 0, len(errors))

// Iterate through each error in the `errors` slice.
for _, r := range errors
// Convert the error `r` to a JSON string and store it in `result`.
// If an error occurs during this marshaling, it returns an array with that error message to JavaScript.
result, err := json.Marshal(r)
if err != nil
return js.ValueOf([]interfaceerr.Error())

// Add the JSON error string to the `vs` slice.
vs = append(vs, string(result))

// Return the `vs` slice (containing all JSON error strings) to JavaScript.
return js.ValueOf(vs)
)
}

Within the realm of Permify, run Functions serve as the foundation, performing important bridging operations between JavaScript input and Go’s processing functionality. It orchestrates real-time data exchange in JSON format and secures Permify’s core functionality for smooth and instant access via a browser interface.

dig into run:

  • JSON data exchange: Converts JavaScript input to a format that Go can use. This function unmarshalls JSON and transfers data between JS and Go, allowing Go’s robust processing power to seamlessly convert input from browser sources. so that you can operate it.
  • Error Handling: To ensure clarity and user awareness, we perform meticulous error checking during data parsing and processing, and return relevant error messages to the JavaScript environment to ensure user-friendly operation.
  • Context processing: By employing dev.Runhandles parsed input within a specific context and manages application logic while handling potential errors to ensure stable data management and user feedback.
  • Two-way communication: Since errors are marshaled into JSON format and returned to JavaScript, this function ensures two-way data flow and keeps both environments in sync.

Therefore, through proper data management, error handling, and ensuring fluid two-way communication channels, run It acts as an integration bridge linking JavaScript and Go, ensuring smooth real-time operation of Permify within the browser interface. This facilitation of interaction not only improves the user experience, but leverages the respective strengths of JavaScript and Go within the Permify environment.

// Continuing from the previously discussed code...

func main()
// Instantiate a channel, 'ch', with no buffer, acting as a synchronization point for the goroutine.
ch := make(chan struct, 0)

// Create a new instance of 'Container' from the 'development' package and assign it to the global variable 'dev'.
dev = development.NewContainer()

// Attach the previously defined 'run' function to the global JavaScript object,
// making it callable from the JavaScript environment.
js.Global().Set("run", run())

// Utilize a channel receive expression to halt the 'main' goroutine, preventing the program from terminating.
<-ch

  1. ch := make(chan struct, 0): Synchronization channels are created to coordinate the activities of goroutines (concurrent threads in Go).
  2. dev = development.NewContainer(): Initialize a new container instance from a development package and run it as dev.
  3. js.Global().Set("run", run()): Publish Go run Add your function to the global JavaScript context so that JavaScript can call your Go function.
  4. <-ch: Stop main Runs a goroutine indefinitely to ensure that Go WebAssembly modules remain active in the JavaScript environment.

In summary, this code establishes a Go environment running inside WebAssembly that exposes specific functionality (run function) to the JavaScript side, keeping itself active and available for function calls from JavaScript.

Before diving into Permify’s rich features, it’s most important to walk you through the steps to convert your Go code into a WASM module and prepare it to run in the browser.

Enthusiasts who want to dig deep into the complete Go codebase should feel free to check out the GitHub repository “Permify Wasm Code.”

Start converting your Go application to WASM binaries using the following command:

GOOS=js GOARCH=wasm go build -o permify.wasm main.go

This directive forces the Go compiler to .wasm Binaries tailored to the JavaScript environment. main.go as a source. output, permify.wasmis a concise representation of Go functionality in preparation for web deployment.

In conjunction with the WASM binary, the Go ecosystem provides an essential JavaScript part named . wasm_exec.js. This is extremely important to initialize and facilitate her WASM module within the browser settings. This important script is typically located in the following location within your Go installation: misc/wasm.

However, to make your trip more efficient, wasm_exec.js Click here for direct access: wasm_exec.

cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .

Armed with these vital assets, the WASM binary and accompanying JavaScript, we are ready for integration into the front end.

First, make sure you have a directory structure that clearly separates your WebAssembly-related code from the rest of your application. Based on the specified structure, loadWasm The folder seems to be where all the magic happens:

loadWasm/

├── index.tsx // Your main React component that integrates WASM.
├── wasm_exec.js // Provided by Go, bridges the gap between Go's WASM and JS.
└── wasmTypes.d.ts // TypeScript type declarations for WebAssembly.

To see the complete structure and explore the details of each file, see the Permify Playground on GitHub.

internal wasmTypes.d.tsa global type declaration is made that extends the Window interface to recognize the new methods introduced by Go’s WebAssembly.

declare global 
export interface Window
Go: any;
run: (shape: string) => any[];


export ;

This will ensure that TypeScript recognizes it. Go constructor and run Method when called globally window object.

in index.tsxsome important tasks will be completed.

  • Import dependencies. First, import the necessary JS and TypeScript declarations.
import "./wasm_exec.js";
import "./wasmTypes.d.ts";
  • Initializing WebAssembly: asynchronous function loadWasm handle the entire process.
async function loadWasm(): Promise<void> 
const goWasm = new window.Go();
const result = await WebAssembly.instantiateStreaming(
fetch("play.wasm"),
goWasm.importObject
);
goWasm.run(result.instance);

here, new window.Go() Go Initialize the WASM environment. WebAssembly.instantiateStreaming Fetch the WASM module, compile it, and create an instance. finally, goWasm.run Activate the WASM module.

  • React component with loader UI: of LoadWasm The component is useEffect Use hooks to load WebAssembly asynchronously when the component mounts.
export const LoadWasm: React.FC<React.PropsWithChildren<>> = (props) => 
const [isLoading, setIsLoading] = React.useState(true);

useEffect(() =>
loadWasm().then(() =>
setIsLoading(false);
);
, []);

if (isLoading)
return (
<div className="wasm-loader-background h-screen">
<div className="center-of-screen">
<SVG src=toAbsoluteUrl("/media/svg/rocket.svg") />
</div>
</div>
);
else
return <React.Fragment>props.children</React.Fragment>;

;

While loading, you will see an SVG rocket indicating that initialization is in progress. This feedback is very important because without it, users may not know what’s going on behind the scenes. Once loaded, the child component or content is rendered.

Suppose Go WASM exposes a method named runyou can call it like this:

function Run(shape) 
return new Promise((resolve) =>
let res = window.run(shape);
resolve(res);
);

This function essentially acts as a bridge, allowing the React frontend to communicate with the Go backend logic encapsulated in WASM.

To integrate a button that triggers a WebAssembly function when clicked, follow these steps:

  1. Creating a button component

First, create a simple React component with a button.

import React from "react";

type RunButtonProps =
shape: string;
onResult: (result: any[]) => void;
;

function RunButton( shape, onResult : RunButtonProps)
const handleClick = async () =>
let result = await Run(shape);
onResult(result);
;

return <button onClick=handleClick>Run WebAssembly</button>;

In the above code, RunButton The component accepts two props.

  • shape: Shape arguments passed to WebAssembly run function.
  • onResult: A callback function that receives the results of a WebAssembly function and can be used to update state or display the results in the UI.
  1. Integrating buttons into the main component

Then in your main component (or wherever you want the button to be), RunButton:

import React,  useState  from "react";
import RunButton from "./path_to_RunButton_component"; // Replace with the actual path

function App() {
const [result, setResult] = useState<any[]>([]);

// Define the shape content
const shapeContent = -
entity user

entity account
relation owner @user
relation following @user
relation follower @user

attribute public boolean
action view = (owner or follower) or public

entity post
relation account @account

attribute restricted boolean

action view = account.view

action comment = account.following not restricted
action like = account.following not restricted
`,
relationships: [
"account:1#owner@user:kevin",
"account:2#owner@user:george",
"account:1#following@user:george",
"account:2#follower@user:kevin",
"post:1#account@account:1",
"post:2#account@account:2",
],
attributes: [
"account:1$public;

return (
<div>
<RunButton shape=JSON.stringify(shapeContent) onResult=setResult />
<div>
Results:
<ul>
result.map((item, index) => (
<li key=index>item</li>
))
</ul>
</div>
</div>
);
}

In this example, App A component that includes. RunButton. When you click the button, the results of the WebAssembly function are displayed in a list below the button.

This research uncovered the integration of WebAssembly and Go, paving the way for enhanced web development and optimal user interaction within the browser.

This work included setting up a Go environment, converting Go code to WebAssembly, and running it within a web context, ultimately bringing to life the interactive platform featured on play.permify.co.

This platform serves not only as an example but also as a beacon of the concrete and powerful capabilities that can be achieved when these technology areas are intertwined.

Make money with Oziconnect referral program
Make money with Oziconnect referral program
Make money with Oziconnect referral program
Make money with Oziconnect referral program
84512

About Us

We are a leading IT agency in Lagos, Nigeria, providing IT consulting and custom software development services. We offer a wide range of IT solutions across software development, web and mobile application development, blockchain development services, digital marketing, and branding.

Contact Us

25B Lagos-Abekouta Expressway Lagos

info@ozitechgroup.com

Phone: (234) 907 155 5545

@2023 OzitechGroup – All Right Reserved.