mirror of
https://github.com/syumai/workers.git
synced 2025-03-11 01:39:11 +00:00
F: add cache API
This commit is contained in:
parent
a19471694e
commit
3fed99fa50
45
cloudflare/cache/client.go
vendored
Normal file
45
cloudflare/cache/client.go
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall/js"
|
||||||
|
|
||||||
|
"github.com/syumai/workers/internal/jsutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
var cache = jsutil.Global.Get("caches")
|
||||||
|
|
||||||
|
// Cache
|
||||||
|
type Cache struct {
|
||||||
|
// instance - The object that Cache API belongs to.
|
||||||
|
instance js.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// applyOptions applies client options.
|
||||||
|
func (c *Cache) applyOptions(opts []CacheOption) {
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CacheOption
|
||||||
|
type CacheOption func(*Cache)
|
||||||
|
|
||||||
|
// WithNamespace
|
||||||
|
func WithNamespace(namespace string) CacheOption {
|
||||||
|
return func(c *Cache) {
|
||||||
|
v, err := jsutil.AwaitPromise(cache.Call("open", namespace))
|
||||||
|
if err != nil {
|
||||||
|
panic("failed to open cache")
|
||||||
|
}
|
||||||
|
c.instance = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(opts ...CacheOption) *Cache {
|
||||||
|
c := &Cache{
|
||||||
|
instance: cache.Get("default"),
|
||||||
|
}
|
||||||
|
c.applyOptions(opts)
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
102
cloudflare/cache/method.go
vendored
Normal file
102
cloudflare/cache/method.go
vendored
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"syscall/js"
|
||||||
|
|
||||||
|
"github.com/syumai/workers/internal/jshttp"
|
||||||
|
"github.com/syumai/workers/internal/jsutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// toJSResponse converts *http.Response to JS Response
|
||||||
|
func toJSResponse(res *http.Response) js.Value {
|
||||||
|
status := res.StatusCode
|
||||||
|
if status == 0 {
|
||||||
|
status = http.StatusOK
|
||||||
|
}
|
||||||
|
respInit := jsutil.NewObject()
|
||||||
|
respInit.Set("status", status)
|
||||||
|
respInit.Set("statusText", http.StatusText(status))
|
||||||
|
respInit.Set("headers", jshttp.ToJSHeader(res.Header))
|
||||||
|
|
||||||
|
readableStream := jsutil.ConvertReaderToReadableStream(res.Body)
|
||||||
|
|
||||||
|
return jsutil.ResponseClass.New(readableStream, respInit)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put attempts to add a response to the cache, using the given request as the key.
|
||||||
|
// Returns an error for the following conditions
|
||||||
|
// - the request passed is a method other than GET.
|
||||||
|
// - the response passed has a status of 206 Partial Content.
|
||||||
|
// - Cache-Control instructs not to cache or if the response is too large.
|
||||||
|
// docs: https://developers.cloudflare.com/workers/runtime-apis/cache/#put
|
||||||
|
func (c *Cache) Put(req *http.Request, res *http.Response) error {
|
||||||
|
_, err := jsutil.AwaitPromise(c.instance.Call("put", jshttp.ToJSRequest(req), toJSResponse(res)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrCacheNotFount is returned when there is no matching cache.
|
||||||
|
var ErrCacheNotFount = errors.New("cache not found")
|
||||||
|
|
||||||
|
// MatchOptions represents the options of the Match method.
|
||||||
|
type MatchOptions struct {
|
||||||
|
// IgnoreMethod - Consider the request method a GET regardless of its actual value.
|
||||||
|
IgnoreMethod bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// toJS converts MatchOptions to JS object.
|
||||||
|
func (opts *MatchOptions) toJS() js.Value {
|
||||||
|
if opts == nil {
|
||||||
|
return js.Undefined()
|
||||||
|
}
|
||||||
|
obj := jsutil.NewObject()
|
||||||
|
obj.Set("ignoreMethod", opts.IgnoreMethod)
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match returns the response object keyed to that request.
|
||||||
|
// docs: https://developers.cloudflare.com/workers/runtime-apis/cache/#match
|
||||||
|
func (c *Cache) Match(req *http.Request, opts *MatchOptions) (*http.Response, error) {
|
||||||
|
res, err := jsutil.AwaitPromise(c.instance.Call("match", jshttp.ToJSRequest(req), opts.toJS()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if res.IsUndefined() {
|
||||||
|
return nil, ErrCacheNotFount
|
||||||
|
}
|
||||||
|
return jshttp.ToResponse(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteOptions represents the options of the Delete method.
|
||||||
|
type DeleteOptions struct {
|
||||||
|
// IgnoreMethod - Consider the request method a GET regardless of its actual value.
|
||||||
|
IgnoreMethod bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// toJS converts DeleteOptions to JS object.
|
||||||
|
func (opts *DeleteOptions) toJS() js.Value {
|
||||||
|
if opts == nil {
|
||||||
|
return js.Undefined()
|
||||||
|
}
|
||||||
|
obj := jsutil.NewObject()
|
||||||
|
obj.Set("ignoreMethod", opts.IgnoreMethod)
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete removes the Response object from the cache.
|
||||||
|
// This method only purges content of the cache in the data center that the Worker was invoked.
|
||||||
|
// Returns ErrCacheNotFount if the response was not cached.
|
||||||
|
func (c *Cache) Delete(req *http.Request, opts *DeleteOptions) error {
|
||||||
|
res, err := jsutil.AwaitPromise(c.instance.Call("delete", jshttp.ToJSRequest(req), opts.toJS()))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !res.Bool() {
|
||||||
|
return ErrCacheNotFount
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user