Skip to content

Commit

Permalink
Merge pull request #19 from syumai/add-runtime-context
Browse files Browse the repository at this point in the history
add runtime context
  • Loading branch information
syumai committed Feb 11, 2023
2 parents 0e499ad + 0fe54fa commit 4b4a950
Show file tree
Hide file tree
Showing 18 changed files with 204 additions and 179 deletions.
10 changes: 6 additions & 4 deletions cloudflare/env.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package cloudflare

import "github.com/syumai/workers/internal/jsutil"
import (
"context"
)

// Getenv gets a value of an environment variable.
// - https://developers.cloudflare.com/workers/platform/environment-variables/
// - Technically, this function is just an alias for js.Global().Get(env_name).String().
func Getenv(name string) string {
return jsutil.Global.Get(name).String()
// - This function panics when a runtime context is not found.
func Getenv(ctx context.Context, name string) string {
return getRuntimeContextEnv(ctx).Get(name).String()
}
8 changes: 5 additions & 3 deletions cloudflare/kv.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cloudflare

import (
"context"
"fmt"
"io"
"syscall/js"
Expand All @@ -17,9 +18,10 @@ type KVNamespace struct {

// NewKVNamespace returns KVNamespace for given variable name.
// - variable name must be defined in wrangler.toml as kv_namespace's binding.
// - if the given variable name doesn't exist on Global object, returns error.
func NewKVNamespace(varName string) (*KVNamespace, error) {
inst := js.Global().Get(varName)
// - if the given variable name doesn't exist on runtime context, returns error.
// - This function panics when a runtime context is not found.
func NewKVNamespace(ctx context.Context, varName string) (*KVNamespace, error) {
inst := getRuntimeContextEnv(ctx).Get(varName)
if inst.IsUndefined() {
return nil, fmt.Errorf("%s is undefined", varName)
}
Expand Down
8 changes: 5 additions & 3 deletions cloudflare/r2bucket.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cloudflare

import (
"context"
"fmt"
"io"
"syscall/js"
Expand All @@ -18,9 +19,10 @@ type R2Bucket struct {
// NewR2Bucket returns R2Bucket for given variable name.
// - variable name must be defined in wrangler.toml.
// - see example: https://github.com/syumai/workers/tree/main/examples/r2-image-viewer
// - if the given variable name doesn't exist on Global object, returns error.
func NewR2Bucket(varName string) (*R2Bucket, error) {
inst := js.Global().Get(varName)
// - if the given variable name doesn't exist on runtime context, returns error.
// - This function panics when a runtime context is not found.
func NewR2Bucket(ctx context.Context, varName string) (*R2Bucket, error) {
inst := getRuntimeContextEnv(ctx).Get(varName)
if inst.IsUndefined() {
return nil, fmt.Errorf("%s is undefined", varName)
}
Expand Down
35 changes: 35 additions & 0 deletions cloudflare/runtimecontext.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package cloudflare

import (
"context"
"syscall/js"

"github.com/syumai/workers/internal/runtimecontext"
)

/**
* The type definition of RuntimeContext for Cloudflare Worker expects:
* ```ts
* type RuntimeContext {
* env: Env;
* ctx: ExecutionContext;
* }
* ```
* This type is based on the type definition of ExportedHandlerFetchHandler.
* - see: https://github.com/cloudflare/workers-types/blob/c8d9533caa4415c2156d2cf1daca75289d01ae70/index.d.ts#LL564
*/

// getRuntimeContextEnv gets object which holds environment variables bound to Cloudflare worker.
// - see: https://github.com/cloudflare/workers-types/blob/c8d9533caa4415c2156d2cf1daca75289d01ae70/index.d.ts#L566
func getRuntimeContextEnv(ctx context.Context) js.Value {
runtimeCtxValue := runtimecontext.MustExtract(ctx)
return runtimeCtxValue.Get("env")
}

// getExecutionContext gets ExecutionContext object from context.
// - see: https://github.com/cloudflare/workers-types/blob/c8d9533caa4415c2156d2cf1daca75289d01ae70/index.d.ts#L567
// - see also: https://github.com/cloudflare/workers-types/blob/c8d9533caa4415c2156d2cf1daca75289d01ae70/index.d.ts#L554
func getExecutionContext(ctx context.Context) js.Value {
runtimeCtxValue := runtimecontext.MustExtract(ctx)
return runtimeCtxValue.Get("ctx")
}
23 changes: 10 additions & 13 deletions examples/basic-auth-proxy/worker.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,19 @@ import mod from "./dist/app.wasm";

const go = new Go();

const readyPromise = new Promise((resolve) => {
globalThis.ready = resolve;
});

const load = WebAssembly.instantiate(mod, go.importObject).then((instance) => {
go.run(instance);
return instance;
});

const readyPromise = new Promise((resolve) => {
globalThis.ready = resolve;
});

async function processRequest(event) {
const req = event.request;
await load;
await readyPromise;
return handleRequest(req);
export default {
async fetch(req, env, ctx) {
await load;
await readyPromise;
return handleRequest(req, { env, ctx });
}
}

addEventListener("fetch", (event) => {
event.respondWith(processRequest(event));
})
2 changes: 1 addition & 1 deletion examples/env/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "MY_ENV: %s", cloudflare.Getenv("MY_ENV"))
fmt.Fprintf(w, "MY_ENV: %s", cloudflare.Getenv(req.Context(), "MY_ENV"))
})
workers.Serve(handler)
}
23 changes: 10 additions & 13 deletions examples/env/worker.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,19 @@ import mod from "./dist/app.wasm";

const go = new Go();

const readyPromise = new Promise((resolve) => {
globalThis.ready = resolve;
});

const load = WebAssembly.instantiate(mod, go.importObject).then((instance) => {
go.run(instance);
return instance;
});

const readyPromise = new Promise((resolve) => {
globalThis.ready = resolve;
});

async function processRequest(event) {
const req = event.request;
await load;
await readyPromise;
return handleRequest(req);
export default {
async fetch(req, env, ctx) {
await load;
await readyPromise;
return handleRequest(req, { env, ctx });
}
}

addEventListener("fetch", (event) => {
event.respondWith(processRequest(event));
})
23 changes: 10 additions & 13 deletions examples/hello/worker.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,19 @@ import mod from "./dist/app.wasm";

const go = new Go();

const readyPromise = new Promise((resolve) => {
globalThis.ready = resolve;
});

const load = WebAssembly.instantiate(mod, go.importObject).then((instance) => {
go.run(instance);
return instance;
});

const readyPromise = new Promise((resolve) => {
globalThis.ready = resolve;
});

async function processRequest(event) {
const req = event.request;
await load;
await readyPromise;
return handleRequest(req);
export default {
async fetch(req, env, ctx) {
await load;
await readyPromise;
return handleRequest(req, { env, ctx });
}
}

addEventListener("fetch", (event) => {
event.respondWith(processRequest(event));
})
48 changes: 8 additions & 40 deletions examples/kv-counter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import (
"os"
"strconv"

"github.com/syumai/workers/cloudflare"

"github.com/syumai/workers"
"github.com/syumai/workers/cloudflare"
)

// counterNamespace is a bounded KV namespace for storing counter.
Expand All @@ -25,35 +24,25 @@ func handleErr(w http.ResponseWriter, msg string, err error) {
}

func main() {
// initialize KV namespace instance
kv, err := cloudflare.NewKVNamespace(counterNamespace)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to init KV: %v", err)
os.Exit(1)
}

http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
if req.URL.Path != "/" {
w.WriteHeader(http.StatusNotFound)
return
}

// initialize KV namespace instance
kv, err := cloudflare.NewKVNamespace(req.Context(), counterNamespace)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to init KV: %v", err)
os.Exit(1)
}

countStr, err := kv.GetString(countKey, nil)
if err != nil {
handleErr(w, "failed to get current count\n", err)
return
}

/*
countReader, err := kv.GetReader(countKey, nil)
if err != nil {
handleErr(w, "failed to get current count\n", err)
return
}
b, _ := io.ReadAll(countReader)
countStr := string(b)
*/

// ignore err and treat count value as 0
count, _ := strconv.Atoi(countStr)

Expand All @@ -65,28 +54,7 @@ func main() {
return
}

/*
err = kv.PutReader(countKey, strings.NewReader(nextCountStr), nil)
if err != nil {
handleErr(w, "failed to put next count\n", err)
return
}
*/

w.Header().Set("Content-Type", "text/plain")

/*
// List returns only `count` as the keys in this namespace.
v, err := kv.List(nil)
if err != nil {
handleErr(w, "failed to list\n", err)
return
}
for i, key := range v.Keys {
fmt.Fprintf(w, "%d: %s\n", i, key.Name)
}
*/

w.Write([]byte(nextCountStr))
})

Expand Down
23 changes: 10 additions & 13 deletions examples/kv-counter/worker.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,19 @@ import mod from "./dist/app.wasm";

const go = new Go();

const readyPromise = new Promise((resolve) => {
globalThis.ready = resolve;
});

const load = WebAssembly.instantiate(mod, go.importObject).then((instance) => {
go.run(instance);
return instance;
});

const readyPromise = new Promise((resolve) => {
globalThis.ready = resolve;
});

async function processRequest(event) {
const req = event.request;
await load;
await readyPromise;
return handleRequest(req);
export default {
async fetch(req, env, ctx) {
await load;
await readyPromise;
return handleRequest(req, { env, ctx });
}
}

addEventListener("fetch", (event) => {
event.respondWith(processRequest(event));
})
Loading

0 comments on commit 4b4a950

Please sign in to comment.