Skip to content

Commit 87bea29

Browse files
committed
defer imports
1 parent 2cb1729 commit 87bea29

File tree

1 file changed

+48
-23
lines changed

1 file changed

+48
-23
lines changed

d2js/js.go

+48-23
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ package main
55
import (
66
"encoding/json"
77
"errors"
8+
"io"
89
"io/fs"
10+
"os"
911
"strings"
1012
"syscall/js"
1113

@@ -133,48 +135,71 @@ type jsParseResponse struct {
133135
D2Error string `json:"d2Error"`
134136
}
135137

136-
type blockFS struct{}
138+
type emptyFile struct{}
137139

138-
func (blockFS blockFS) Open(name string) (fs.File, error) {
139-
return nil, errors.New("import statements not currently implemented")
140+
func (f *emptyFile) Stat() (os.FileInfo, error) {
141+
return nil, nil
142+
}
143+
144+
func (f *emptyFile) Read(p []byte) (int, error) {
145+
return 0, io.EOF
146+
}
147+
148+
func (f *emptyFile) Close() error {
149+
return nil
150+
}
151+
152+
type detectFS struct {
153+
importUsed bool
154+
}
155+
156+
func (detectFS detectFS) Open(name string) (fs.File, error) {
157+
detectFS.importUsed = true
158+
return &emptyFile{}, nil
140159
}
141160

142161
func jsParse(this js.Value, args []js.Value) interface{} {
143162
dsl := args[0].String()
144163
themeID := args[1].Int()
145164

165+
detectFS := detectFS{}
166+
146167
g, err := d2compiler.Compile("", strings.NewReader(dsl), &d2compiler.CompileOptions{
147168
UTF16: true,
148-
FS: blockFS{},
169+
FS: detectFS,
149170
})
150-
var pe *d2parser.ParseError
151-
if err != nil {
152-
if errors.As(err, &pe) {
153-
serialized, _ := json.Marshal(err)
154-
ret := jsParseResponse{ParseError: string(serialized)}
171+
// If an import was used, client side D2 cannot reliably compile
172+
// Defer to backend compilation
173+
if !detectFS.importUsed {
174+
var pe *d2parser.ParseError
175+
if err != nil {
176+
if errors.As(err, &pe) {
177+
serialized, _ := json.Marshal(err)
178+
ret := jsParseResponse{ParseError: string(serialized)}
179+
str, _ := json.Marshal(ret)
180+
return string(str)
181+
}
182+
ret := jsParseResponse{D2Error: err.Error()}
155183
str, _ := json.Marshal(ret)
156184
return string(str)
157185
}
158-
ret := jsParseResponse{D2Error: err.Error()}
159-
str, _ := json.Marshal(ret)
160-
return string(str)
161-
}
162186

163-
for _, o := range g.Objects {
164-
if (o.Attributes.Top == nil) != (o.Attributes.Left == nil) {
165-
ret := jsParseResponse{UserError: `keywords "top" and "left" currently must be used together`}
187+
for _, o := range g.Objects {
188+
if (o.Attributes.Top == nil) != (o.Attributes.Left == nil) {
189+
ret := jsParseResponse{UserError: `keywords "top" and "left" currently must be used together`}
190+
str, _ := json.Marshal(ret)
191+
return string(str)
192+
}
193+
}
194+
195+
err = g.ApplyTheme(int64(themeID))
196+
if err != nil {
197+
ret := jsParseResponse{D2Error: err.Error()}
166198
str, _ := json.Marshal(ret)
167199
return string(str)
168200
}
169201
}
170202

171-
err = g.ApplyTheme(int64(themeID))
172-
if err != nil {
173-
ret := jsParseResponse{D2Error: err.Error()}
174-
str, _ := json.Marshal(ret)
175-
return string(str)
176-
}
177-
178203
m, err := d2parser.Parse("", strings.NewReader(dsl), nil)
179204
if err != nil {
180205
return err

0 commit comments

Comments
 (0)