This repository has been archived by the owner on Nov 19, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
options.go
134 lines (111 loc) · 3.14 KB
/
options.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// SPDX-FileCopyrightText: 2023 Iván Szkiba
//
// SPDX-License-Identifier: MIT
package muxpress
import (
"context"
"os"
"sync"
"github.com/dop251/goja"
"github.com/sirupsen/logrus"
"github.com/spf13/afero"
)
// RunnerFunc is used to execute middlewares on incoming requests.
type RunnerFunc func(func() error)
type options struct {
runner RunnerFunc
logger logrus.FieldLogger
filesystem afero.Fs
context func() context.Context
}
func getopts(with ...Option) (*options, error) {
opts := new(options)
for _, o := range with {
o(opts)
}
if opts.logger == nil {
opts.logger = logrus.StandardLogger()
}
if opts.filesystem == nil {
cwd, err := os.Getwd()
if err != nil {
return nil, err
}
opts.filesystem = afero.NewBasePathFs(afero.NewOsFs(), cwd)
}
if opts.runner == nil {
opts.runner = syncRunner()
}
if opts.context == nil {
opts.context = context.TODO
}
return opts, nil
}
// Option is an option for the [NewApplicationConstructor] factory function.
type Option = func(*options)
// WithLogger returns an Option that specifies a [logrus.FieldLogger] logger to be used for logging.
func WithLogger(logger logrus.FieldLogger) Option {
return func(o *options) {
o.logger = logger
}
}
// WithFS returns an Option that specifies a [afero.Fs] filesystem to be used for accessing static files.
func WithFS(filesystem afero.Fs) Option {
return func(o *options) {
o.filesystem = filesystem
}
}
// WithContext returns an Option that specifies a [context.Context] getter function to be used for stopping application when context is canceled or done.
// Default is to use [context.TODO].
func WithContext(context func() context.Context) Option {
return func(o *options) {
o.context = context
}
}
// WithRunner returns an Option that specifies a runner function to be used for execute middlewares for incoming requests.
// This option allows you to schedule middleware calls in the event loop.
//
// Since [goja.Runtime] is not goroutine-safe, the default is to execute middlewares in synchronous way.
//
// func syncRunner() RunnerFunc {
// var mu sync.Mutex
//
// return func(fn func() error) {
// mu.Lock()
// defer mu.Unlock()
//
// if err := fn(); err != nil {
// panic(err)
// }
// }
// }
//nolint:gci,gofmt,gofumpt,goimports
func WithRunner(runner RunnerFunc) Option {
return func(o *options) {
o.runner = runner
}
}
// WithRunOnLoop returns an Option that specifies [RunOnLoop] function from [goja_nodejs] package to be used for execute middlewares for incoming requests.
//
// [RunOnLoop]: https://pkg.go.dev/github.com/dop251/goja_nodejs/eventloop#EventLoop.RunOnLoop
// [goja_nodejs]: https://github.com/dop251/goja_nodejs
func WithRunOnLoop(runOnLoop func(func(*goja.Runtime))) Option {
return WithRunner(runOnLoopRunner(runOnLoop))
}
func runOnLoopRunner(runOnLoop func(func(*goja.Runtime))) RunnerFunc {
return func(fn func() error) {
runOnLoop(func(runtime *goja.Runtime) {
must(runtime, fn())
})
}
}
func syncRunner() RunnerFunc {
var mu sync.Mutex
return func(fn func() error) {
mu.Lock()
defer mu.Unlock()
if err := fn(); err != nil {
panic(err)
}
}
}