Skip to content

Commit

Permalink
fix: off by one error in LSP that prevents autocomplete from function…
Browse files Browse the repository at this point in the history
…ing in some contexts
  • Loading branch information
a-h committed Jul 4, 2024
1 parent 26bf77f commit 37faae0
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.2.742
0.2.745
6 changes: 4 additions & 2 deletions cmd/templ/lspcmd/proxy/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,10 +396,12 @@ func (p *Server) Completion(ctx context.Context, params *lsp.CompletionParams) (

// Ensure that Go source is available.
gosrc := strings.Split(p.GoSource[string(templURI)], "\n")
if len(gosrc)-1 < int(params.TextDocumentPositionParams.Position.Line) {
if len(gosrc) < int(params.TextDocumentPositionParams.Position.Line) {
p.Log.Info("completion: line position out of range")
return nil, nil
}
if len(gosrc[params.TextDocumentPositionParams.Position.Line])-1 < int(params.TextDocumentPositionParams.Position.Character) {
if len(gosrc[params.TextDocumentPositionParams.Position.Line]) < int(params.TextDocumentPositionParams.Position.Character) {
p.Log.Info("completion: col position out of range")
return nil, nil
}

Expand Down
42 changes: 42 additions & 0 deletions docs/docs/05-server-side-rendering/05-streaming.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# HTTP Streaming

The default behaviour of the `templ.Handler` is to render the template to a buffer and then write the buffer to the response.

This ensures that the template has successfully rendered before the response is sent to the client, so that appropriate repsonse codes can be set if the template fails to render, and partial responses are not sent to the client.

## Rendering lifecycle

Typical usage of templ involves collecting data that is used to populate the template, before rendering the template and sending a response.

For example, executing several database queries, calling an API, or reading from a file, before rendering the template.

```mermaid
flowchart TD;
r[Request]
q[DB Queries]
q1[Query result]
q2[Query result]
a[API Calls]
api[API call result]
t[Render template]
h[HTML]
response[Response]
r-->q;
r-->a;
q-->q1
q-->q2
a-->api
q1-->t
q2-->t
api-->t
t-->h
h-->response;
```

However, if the queries and API calls take a long time, this has an impact on Time to First Byte (TTFB) because the client has to wait for all database queries and API calls to complete before sending the response.

To improve TTFB, the template can be streamed to the client as soon as the first part of the template is rendered, while the remaining queries and API calls are still in progress, at the cost of not being able to set response codes or headers after the first part of the template is rendered.

## Enabling streaming

Streaming can be enabled by setting the `Streaming` field of the `templ.Handler` to `true`.
2 changes: 1 addition & 1 deletion examples/counter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
)

func main() {
log := slog.New(slog.NewJSONHandler(os.Stderr))
log := slog.New(slog.NewJSONHandler(os.Stderr, nil))
s, err := db.NewCountStore(os.Getenv("TABLE_NAME"), os.Getenv("AWS_REGION"))
if err != nil {
log.Error("failed to create store", slog.Any("error", err))
Expand Down

0 comments on commit 37faae0

Please sign in to comment.