jsockdclient

package module
v0.0.150 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 28, 2026 License: MIT Imports: 25 Imported by: 0

README

Go JSockD client

GoDoc

Add JSockD to your Go project

go get github.com/addrummond/jsockd/clients/go/jsockdclient

Example usage

package main
import (
	"fmt"
	"log"

	"github.com/addrummond/jsockd/clients/go/jsockdclient"
)

func main() {
	config := jsockdclient.DefaultConfig()
	config.SourceMap = "example_module.mjs.map"
	client, err := jsockdclient.InitJsockDClientViaAutoDownload(config)
	if err != nil {
		log.Fatalf("Failed to initialize JSockD client: %v", err)
	}
	defer client.Close()

	response, err := jsockdclient.SendCommand[string](client, "(_, name) => 'Hello ' + name", "World")
	if err != nil {
		log.Fatalf("Failed to send command: %v", err)
	}

	fmt.Println(response) // Should print: Hello, World!
}

Example of SSR with React 19

See this documentation and the associated example code for an example of using JSockD for server-side rendering with React 19.

Documentation

Overview

Package jsockdclient provides a Go client for communicating with a jsockd server.

See https://github.com/addrummond/jsockd for general information about JSockD.

Example usage:

config := jsockdclient.DefaultConfig()

config.Logger = func(timestamp time.Time, level, message string) {
	fmt.Printf("%s [%s] %s\n", timestamp.Format(time.RFC3339Nano), level, message)
}

client, err := jsockdclient.InitJSockD(config, "/path/to/jsockd", []string{"/tmp/jsockd.sock1", "/tmp/jsockd.sock2"})

if err != nil {
	log.Fatal(err)
}

defer client.Close()
response, err := jsockdclient.SendRawCommand(client, "(m, p) => p+1", "99")

if err != nil {
	log.Fatal(err)
}

fmt.Printf("%+v\n", response)

Index

Constants

View Source
const JSockDVersion = "0.0.150"

JSockDVersion specifies the expected version of JSockD [__jsockd_version_check__ <- for automatic CI check]

Variables

View Source
var ErrDownload = errors.New("failed to download file")

If an errors.Is(err, ErrDownload) is true then the function that returned err may reasonably be retried.

Functions

This section is empty.

Types

type Config

type Config struct {
	// The number of threads that JSockD should use. If 0, the number of CPU cores is used. This config value is ignored if the Sockets field is non-nil.
	NThreads int
	// The filename of the bytecode module to load, or "" if no bytecode module should be loaded.
	BytecodeModuleFile string
	// The hex-encoded public key used to verify the signature of the bytecode module, or "" if none.
	BytecodeModulePublicKey string
	// The filename of the source map to load, or "" if no source map should be loaded.
	SourceMap string
	// The maximum time in microseconds a connection is allowed to be idle before JSockD shuts down its associated QuickJS instance. If 0, no idle timeout is applied.
	MaxIdleTimeUs int
	// The maximum time in microseconds a command is allowed to run (0 for default max time)
	MaxCommandRuntimeUs int
	// The timeout in microseconds when communicating with JSockD
	TimeoutUs int
	// If true, the JSockD server version is not checked against the version expected by this client. This should always be set to 'false' in production systems.
	SkipJSockDVersionCheck bool
	// If set, this function is called for each log message sent by JSockD.
	Logger func(timestamp time.Time, level string, message string)
	// The maximum number of times that the jscockd process will be restarted within one minute if it crashes. If 0, it will never be restarted.
	MaxRestartsPerMinute int
	// Value for JSOCKD_LOG_PREFIX env var
	LogPrefix string
}

The configuration for the JSockDClient. The zero value is not a sensible configuration, so use DefaultConfig() and then modify the desired fields.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the default JSockD client configuration.

type JSockDClient

type JSockDClient struct {
	// contains filtered or unexported fields
}

JSockDClient represents a client connection to a JSockD server. It should be created via InitJSockDClient and closed via its Close method.

func InitJSockDClient

func InitJSockDClient(config Config, jsockdExec string) (*JSockDClient, error)

InitJSockDClientWithSockets starts a JSockD server process with the specified configuration, connects to it via the specified Unix domain sockets, and returns a JSockDClient that can be used to send commands to the server.

func InitJsockDClientViaAutoDownload

func InitJsockDClientViaAutoDownload(config Config) (*JSockDClient, error)

Like InitJSockDClient, but downloads the jsockd executable automatically from GitHub releases and verifies its signature. This is not recommended for production use. If the error returned satisfies errors.Is(err, jsockdclient.ErrDownload) then it is reasonable to retry the call.

func (*JSockDClient) Close

func (client *JSockDClient) Close() error

Close closes all connections to the JSockD server, all channels used internally by the JDockD client code, and waits for the JSockD process to terminate. Close may be called multiple times without ill effect; subsequent calls are no-ops.

func (*JSockDClient) GetJSockDProcess

func (client *JSockDClient) GetJSockDProcess() *os.Process

GetJSockDProcess returns the underlying JSockD process for the client. You wouldn't usually need to use this.

type RawResponse

type RawResponse struct {
	// True iff the command raised an exception. When true, ResultJson is the
	// JSON blob sent by the server containing information about the error.
	Exception  bool
	ResultJson string
}

RawResponse represents the raw response to a command sent to the JSockD server. The ResultJson field contains the JSON string returned by the server.

func SendRawCommand

func SendRawCommand(client *JSockDClient, query string, jsonParam string) (RawResponse, error)

SendRawCommand sends a command to the JSockD server and returns the response. JSON values are passed and returned as strings.

func SendRawCommandWithMessageHandler

func SendRawCommandWithMessageHandler(client *JSockDClient, query string, jsonParam string, messageHandler func(jsonMessage string) (string, error)) (RawResponse, error)

SendRawCommandWithMessageHandler is like SendRawCommand but with a message handling function as an additional parameter. The message handling function receives JSON-encoded messages and should return a valid JSON-encoded response. If messageHandler is nil then all messages receive a `null` response.

Note that messageHandler, when called, will execute in a different goroutine to the one that called SendRawCommandWithMessageHandler. This goroutine is guaranteed to have finished executing by the time SendRawCommandWithMessageHandler returns.

type Response

type Response[T any] struct {
	// True iff the command raised an exception. When true, Result has its default
	// value; check RawResponse for further information about the error.
	Exception   bool
	Result      T
	RawResponse RawResponse
}

Response represents the response to a command sent to the JSockD server. The Result field is of the type specified by the caller when sending the command.

func SendCommand

func SendCommand[ResponseT any](client *JSockDClient, query string, jsonParam any) (Response[ResponseT], error)

SendCommand sends a command to the JSockD server and returns the response. The parameter is serialized to JSON via json.Marshal and the result is deserialized from JSON via json.Unmarshal.

func SendCommandWithMessageHandler

func SendCommandWithMessageHandler[ResponseT any, MessageT any, MessageResponseT any](client *JSockDClient, query string, jsonParam any, messageHandler func(message MessageT) (MessageResponseT, error)) (Response[ResponseT], error)

SendCommandWithMessageHandler is like SendCommand but with a message handling function as an additional parameter. If there is an error JSON-decoding the `message` argument of the message handler, or if there is an error JSON-encoding its return value, then null will be sent as the response to the JSockD server, and SendCommandWithMessageHandler will return a non-nil error.

Note that messageHandler, when called, will execute in a different goroutine to the one that called SendCommandWithMessageHandler. This goroutine is guaranteed to have finished executing by the time SendCommandWithMessageHandler returns.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL