Skip to content

Commit 8826a0e

Browse files
authored
feat: File uploads. (#49)
BREAKING CHANGE: Socket data in a template is now under `.Assigns`.
1 parent d1f387c commit 8826a0e

22 files changed

+711
-152
lines changed

.github/workflows/release.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
- uses: actions/checkout@v2
1313
- uses: actions/setup-node@v1
1414
with:
15-
node-version: "15.x"
15+
node-version: "16.x"
1616
registry-url: "https://registry.npmjs.org"
1717
- run: npm install
1818
- run: npm --no-git-tag-version version ${{ github.event.release.tag_name }}

.github/workflows/test.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ jobs:
44
test:
55
strategy:
66
matrix:
7-
go-version: [1.15.x, 1.16.x]
8-
node-version: [14.x, 15.x]
7+
go-version: [1.17.x, 1.18.x]
8+
node-version: [16.x, 17.x]
99
os: [ubuntu-latest, macos-latest, windows-latest]
1010
runs-on: ${{ matrix.os }}
1111
steps:

README.md

+26-2
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,9 @@ func Example() {
104104

105105
// Provide a render function. Here we are doing it manually, but there is a
106106
// provided WithTemplateRenderer which can be used to work with `html/template`
107-
h.HandleRender(func(ctx context.Context, data interface{}) (io.Reader, error) {
107+
h.HandleRender(func(ctx context.Context, data *RenderContext) (io.Reader, error) {
108108
tmpl, err := template.New("thermo").Parse(`
109-
<div>{{.C}}</div>
109+
<div>{{.Assigns.C}}</div>
110110
<button live-click="temp-up">+</button>
111111
<button live-click="temp-down">-</button>
112112
<!-- Include to make live work -->
@@ -506,3 +506,27 @@ In production it is often required to have multiple instances of the same applic
506506
live has a PubSub element. This allows nodes to publish onto topics and receive those messages as if they were all
507507
running as the same instance. See the [cluster example](https://github.com/jfyne/live-examples/tree/main/cluster) for
508508
usage.
509+
510+
## Uploads
511+
512+
Live supports interactive file uploads with progress indication. See the [uploads example](https://github.com/jfyne/live-examples/tree/main/uploads)
513+
for usage.
514+
515+
### Features
516+
517+
Accept specification - Define accepted file types, max number of entries, max file size, etc. When the client
518+
selects file(s), the file metadata can be validated with a helper function.
519+
520+
Reactive entries - Uploads are populated in the `.Uploads` template context. Entries automatically respond
521+
to progress and errors.
522+
523+
### Entry validataion
524+
525+
File selection triggers the usual form change event and there is a helper function to validate the uploads.
526+
Use `live.ValidateUploads` to validate the incoming files. Any validation errors will be available in the `.Uploads`
527+
context in the template.
528+
529+
### Consume the uploads
530+
531+
When a form is submitted files will first be uploaded to a staging area, then the submit event is triggered. Within the event
532+
handler use the `live.ConsumeUploads` helper function to then move the uploaded files to where you need them.

configs.go

-22
This file was deleted.

configs_test.go

-1
This file was deleted.

engine.go

+38-35
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ import (
77
"sync"
88
"time"
99

10-
"golang.org/x/net/html"
1110
"golang.org/x/time/rate"
1211
)
1312

1413
var _ Engine = &BaseEngine{}
1514

15+
// EngineConfig applies configuration to an engine.
16+
type EngineConfig func(e Engine) error
17+
1618
// BroadcastHandler a way for processes to communicate.
1719
type BroadcastHandler func(ctx context.Context, e Engine, msg Event)
1820

@@ -34,6 +36,9 @@ type Engine interface {
3436
Error() ErrorHandler
3537
// AddSocket add a socket to the engine.
3638
AddSocket(sock Socket)
39+
// GetSocket from a session get an already connected
40+
// socket.
41+
GetSocket(session Session) (Socket, error)
3742
// DeleteSocket remove a socket from the engine.
3843
DeleteSocket(sock Socket)
3944
// CallParams on params change run the handlers.
@@ -65,21 +70,36 @@ type BaseEngine struct {
6570
// event lock.
6671
eventMu sync.Mutex
6772

68-
// ignoreFaviconRequest setting to ignore requests for /favicon.ico.
69-
ignoreFaviconRequest bool
73+
// IgnoreFaviconRequest setting to ignore requests for /favicon.ico.
74+
IgnoreFaviconRequest bool
75+
76+
// MaxUploadSize the maximum upload size in bytes to allow. This defaults
77+
// too 100MB.
78+
MaxUploadSize int64
79+
80+
// UploadStagingLocation where uploads are stored before they are consumed. This defaults
81+
// too the default OS temp directory.
82+
UploadStagingLocation string
7083
}
7184

7285
// NewBaseEngine creates a new base engine.
73-
func NewBaseEngine(h Handler) *BaseEngine {
74-
return &BaseEngine{
86+
func NewBaseEngine(h Handler, configs ...EngineConfig) *BaseEngine {
87+
e := &BaseEngine{
7588
broadcastLimiter: rate.NewLimiter(rate.Every(time.Millisecond*100), 8),
7689
broadcastHandler: func(ctx context.Context, h Engine, msg Event) {
7790
h.self(ctx, nil, msg)
7891
},
7992
socketMap: make(map[SocketID]Socket),
80-
ignoreFaviconRequest: true,
93+
IgnoreFaviconRequest: true,
94+
MaxUploadSize: 100 * 1024 * 1024,
8195
handler: h,
8296
}
97+
for _, conf := range configs {
98+
if err := conf(e); err != nil {
99+
log.Println("warning:", fmt.Errorf("could not apply config to engine: %w", err))
100+
}
101+
}
102+
return e
83103
}
84104

85105
func (e *BaseEngine) Handler(hand Handler) {
@@ -148,6 +168,18 @@ func (e *BaseEngine) AddSocket(sock Socket) {
148168
e.socketMap[sock.ID()] = sock
149169
}
150170

171+
// GetSocket get a socket from a session.
172+
func (e *BaseEngine) GetSocket(session Session) (Socket, error) {
173+
e.socketsMu.Lock()
174+
defer e.socketsMu.Unlock()
175+
for _, s := range e.socketMap {
176+
if SessionID(session) == SessionID(s.Session()) {
177+
return s, nil
178+
}
179+
}
180+
return nil, ErrNoSocket
181+
}
182+
151183
// DeleteSocket remove a socket from the engine.
152184
func (e *BaseEngine) DeleteSocket(sock Socket) {
153185
e.socketsMu.Lock()
@@ -238,32 +270,3 @@ func (e *BaseEngine) hasSocket(s Socket) error {
238270
}
239271
return nil
240272
}
241-
242-
// RenderSocket takes the engine and current socket and renders it to html.
243-
func RenderSocket(ctx context.Context, e Engine, s Socket) (*html.Node, error) {
244-
// Render handler.
245-
output, err := e.Render()(ctx, s.Assigns())
246-
if err != nil {
247-
return nil, fmt.Errorf("render error: %w", err)
248-
}
249-
render, err := html.Parse(output)
250-
if err != nil {
251-
return nil, fmt.Errorf("html parse error: %w", err)
252-
}
253-
shapeTree(render)
254-
255-
// Get diff
256-
if s.LatestRender() != nil {
257-
patches, err := Diff(s.LatestRender(), render)
258-
if err != nil {
259-
return nil, fmt.Errorf("diff error: %w", err)
260-
}
261-
if len(patches) != 0 {
262-
s.Send(EventPatch, patches)
263-
}
264-
} else {
265-
anchorTree(render, newAnchorGenerator())
266-
}
267-
268-
return render, nil
269-
}

event.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type Event struct {
3131
T string `json:"t"`
3232
ID int `json:"i,omitempty"`
3333
Data json.RawMessage `json:"d,omitempty"`
34-
SelfData interface{} `json:"-"`
34+
SelfData interface{} `json:"s,omitempty"`
3535
}
3636

3737
// Params extract params from inbound message.

example_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ func Example() {
6363

6464
// Provide a render function. Here we are doing it manually, but there is a
6565
// provided WithTemplateRenderer which can be used to work with `html/template`
66-
h.HandleRender(func(ctx context.Context, data interface{}) (io.Reader, error) {
66+
h.HandleRender(func(ctx context.Context, data *RenderContext) (io.Reader, error) {
6767
tmpl, err := template.New("thermo").Parse(`
68-
<div>{{.C}}</div>
68+
<div>{{.Assigns.C}}</div>
6969
<button live-click="temp-up">+</button>
7070
<button live-click="temp-down">-</button>
7171
<!-- Include to make live work -->

go.mod

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
module github.com/jfyne/live
22

3-
go 1.15
3+
go 1.17
44

55
require (
6-
github.com/google/go-cmp v0.5.6
6+
github.com/google/go-cmp v0.5.7
77
github.com/gorilla/sessions v1.2.1
8-
github.com/klauspost/compress v1.13.1 // indirect
9-
github.com/rs/xid v1.2.1
10-
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
11-
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
12-
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
8+
github.com/rs/xid v1.4.0
9+
golang.org/x/net v0.0.0-20220325170049-de3da57026de
10+
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65
1311
nhooyr.io/websocket v1.8.7
1412
)
13+
14+
require (
15+
github.com/gorilla/securecookie v1.1.1 // indirect
16+
github.com/klauspost/compress v1.15.1 // indirect
17+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
18+
)

go.sum

+15-20
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2-
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
32
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
43
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
54
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
65
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
76
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
8-
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
97
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
108
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
119
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
@@ -22,10 +20,9 @@ github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/E
2220
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
2321
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
2422
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
25-
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
2623
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
27-
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
28-
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
24+
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
25+
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
2926
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
3027
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
3128
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
@@ -36,8 +33,8 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
3633
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
3734
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
3835
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
39-
github.com/klauspost/compress v1.13.1 h1:wXr2uRxZTJXHLly6qhJabee5JqIhTRoLBhDOA74hDEQ=
40-
github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
36+
github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A=
37+
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
4138
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
4239
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
4340
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
@@ -46,34 +43,32 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OH
4643
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
4744
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
4845
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
49-
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
5046
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
51-
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
52-
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
47+
github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
48+
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
5349
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
5450
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
55-
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
5651
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
5752
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
5853
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
5954
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
6055
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
61-
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
62-
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
56+
golang.org/x/net v0.0.0-20220325170049-de3da57026de h1:pZB1TWnKi+o4bENlbzAgLrEbY4RMYmUIRobMcSmfeYc=
57+
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
6358
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
64-
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
65-
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
66-
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
59+
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
60+
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
61+
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
62+
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
6763
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
68-
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
64+
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
6965
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
70-
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
71-
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
66+
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs=
67+
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
7268
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
7369
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
7470
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
7571
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
76-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
7772
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
7873
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
7974
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=

handler.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type MountHandler func(ctx context.Context, c Socket) (interface{}, error)
2020

2121
// RenderHandler the func that is called to render the current state of the
2222
// data for the socket.
23-
type RenderHandler func(ctx context.Context, data interface{}) (io.Reader, error)
23+
type RenderHandler func(ctx context.Context, rc *RenderContext) (io.Reader, error)
2424

2525
// ErrorHandler if an error occurs during the mount and render cycle
2626
// a handler of this type will be called.
@@ -90,7 +90,7 @@ func NewHandler(configs ...HandlerConfig) *BaseHandler {
9090
mountHandler: func(ctx context.Context, s Socket) (interface{}, error) {
9191
return nil, nil
9292
},
93-
renderHandler: func(ctx context.Context, data interface{}) (io.Reader, error) {
93+
renderHandler: func(ctx context.Context, rc *RenderContext) (io.Reader, error) {
9494
return nil, ErrNoRenderer
9595
},
9696
errorHandler: func(ctx context.Context, err error) {
@@ -103,7 +103,7 @@ func NewHandler(configs ...HandlerConfig) *BaseHandler {
103103
}
104104
for _, conf := range configs {
105105
if err := conf(h); err != nil {
106-
log.Println("warning:", fmt.Errorf("could not apply config: %w", err))
106+
log.Println("warning:", fmt.Errorf("could not apply config to handler: %w", err))
107107
}
108108
}
109109
return h

handler_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func TestHandler(t *testing.T) {
1717
output := `<html _l00=""><head _l000=""></head><body _l001="" live-rendered="">test</body></html>`
1818

1919
h := &Tester{NewHandler()}
20-
h.HandleRender(func(ctx context.Context, data interface{}) (io.Reader, error) {
20+
h.HandleRender(func(ctx context.Context, data *RenderContext) (io.Reader, error) {
2121
return strings.NewReader(output), nil
2222
})
2323

@@ -30,7 +30,7 @@ func TestHandler(t *testing.T) {
3030

3131
rr := httptest.NewRecorder()
3232
ctx := httpContext(rr, req)
33-
e.serveHttp(ctx, rr, req)
33+
e.get(ctx, rr, req)
3434

3535
if rr.Code != http.StatusOK {
3636
t.Errorf("handler returned wrong status code: got %v want %v", rr.Code, http.StatusOK)
@@ -53,7 +53,7 @@ func TestHandlerErrorNoRenderer(t *testing.T) {
5353

5454
rr := httptest.NewRecorder()
5555
ctx := httpContext(rr, req)
56-
e.serveHttp(ctx, rr, req)
56+
e.get(ctx, rr, req)
5757

5858
if rr.Code != http.StatusInternalServerError {
5959
t.Errorf("handler returned wrong status code: got %v want %v", rr.Code, http.StatusInternalServerError)

0 commit comments

Comments
 (0)