mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
internal/warpc: Improve the JS plugin API
* Move the error handling into commons and make sure the error returned also returns message errors * Make the protocol version an int so it can be more easily compared
This commit is contained in:
parent
fe7e137e28
commit
28f621d4a7
9 changed files with 68 additions and 43 deletions
|
@ -41,13 +41,21 @@ export function readInput(handle) {
|
|||
if (currentLine[i] === 10) {
|
||||
const chunk = currentLine.splice(j, i + 1);
|
||||
const arr = new Uint8Array(chunk);
|
||||
let json;
|
||||
let message;
|
||||
try {
|
||||
json = JSON.parse(new TextDecoder().decode(arr));
|
||||
message = JSON.parse(new TextDecoder().decode(arr));
|
||||
} catch (e) {
|
||||
throw new Error(`Error parsing JSON '${new TextDecoder().decode(arr)}' from stdin: ${e.message}`);
|
||||
}
|
||||
handle(json);
|
||||
|
||||
try {
|
||||
handle(message);
|
||||
} catch (e) {
|
||||
let header = message.header;
|
||||
header.err = e.message;
|
||||
writeOutput({ header: header });
|
||||
}
|
||||
|
||||
j = i + 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
(()=>{function s(r){let e=[],c=new Uint8Array(1024);for(;;){let n=0;try{n=Javy.IO.readSync(0,c)}catch(o){if(o.message.includes("os error 29"))break;throw new Error("Error reading from stdin")}if(n<0)throw new Error("Error reading from stdin");if(n===0)break;if(e=[...e,...c.subarray(0,n)],!e.includes(10))continue;let t=0;for(let o=0;t<e.length;t++)if(e[t]===10){let u=e.splice(o,t+1),d=new Uint8Array(u),a;try{a=JSON.parse(new TextDecoder().decode(d))}catch(l){throw new Error(`Error parsing JSON '${new TextDecoder().decode(d)}' from stdin: ${l.message}`)}r(a),o=t+1}e=e.slice(t)}}function f(r){let i=new TextEncoder().encode(JSON.stringify(r)+`
|
||||
`),e=new Uint8Array(i);Javy.IO.writeSync(1,e)}var w=function(r){f({header:r.header,data:{greeting:"Hello "+r.data.name+"!"}})};console.log("Greet module loaded");s(w);})();
|
||||
(()=>{function l(r){let e=[],a=new Uint8Array(1024);for(;;){let n=0;try{n=Javy.IO.readSync(0,a)}catch(o){if(o.message.includes("os error 29"))break;throw new Error("Error reading from stdin")}if(n<0)throw new Error("Error reading from stdin");if(n===0)break;if(e=[...e,...a.subarray(0,n)],!e.includes(10))continue;let t=0;for(let o=0;t<e.length;t++)if(e[t]===10){let w=e.splice(o,t+1),f=new Uint8Array(w),c;try{c=JSON.parse(new TextDecoder().decode(f))}catch(d){throw new Error(`Error parsing JSON '${new TextDecoder().decode(f)}' from stdin: ${d.message}`)}try{r(c)}catch(d){let u=c.header;u.err=d.message,i({header:u})}o=t+1}e=e.slice(t)}}function i(r){let s=new TextEncoder().encode(JSON.stringify(r)+`
|
||||
`),e=new Uint8Array(s);Javy.IO.writeSync(1,e)}var h=function(r){i({header:r.header,data:{greeting:"Hello "+r.data.name+"!"}})};console.log("Greet module loaded");l(h);})();
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -6,13 +6,9 @@ const render = function (input) {
|
|||
const expression = data.expression;
|
||||
const options = data.options;
|
||||
const header = input.header;
|
||||
try {
|
||||
const output = katex.renderToString(expression, options);
|
||||
writeOutput({ header: header, data: { output: output } });
|
||||
} catch (e) {
|
||||
header.err = e.message;
|
||||
writeOutput({ header: header });
|
||||
}
|
||||
// Any error thrown here will be caught by the common.js readInput function.
|
||||
const output = katex.renderToString(expression, options);
|
||||
writeOutput({ header: header, data: { output: output } });
|
||||
};
|
||||
|
||||
readInput(render);
|
||||
|
|
|
@ -35,15 +35,19 @@ import (
|
|||
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
|
||||
)
|
||||
|
||||
const currentVersion = "v1"
|
||||
const currentVersion = 1
|
||||
|
||||
//go:embed wasm/quickjs.wasm
|
||||
var quickjsWasm []byte
|
||||
|
||||
// Header is in both the request and response.
|
||||
type Header struct {
|
||||
Version string `json:"version"`
|
||||
ID uint32 `json:"id"`
|
||||
// Major version of the protocol.
|
||||
Version uint16 `json:"version"`
|
||||
|
||||
// Unique ID for the request.
|
||||
// Note that this only needs to be unique within the current request set time window.
|
||||
ID uint32 `json:"id"`
|
||||
|
||||
// Set in the response if there was an error.
|
||||
Err string `json:"err"`
|
||||
|
@ -150,7 +154,11 @@ func (p *dispatcherPool[Q, R]) Execute(ctx context.Context, q Message[Q]) (Messa
|
|||
return d.zero, call.err
|
||||
}
|
||||
|
||||
return call.response, p.Err()
|
||||
resp, err := call.response, p.Err()
|
||||
if err == nil && resp.Header.Err != "" {
|
||||
err = errors.New(resp.Header.Err)
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (d *dispatcher[Q, R]) newCall(q Message[Q]) (*call[Q, R], error) {
|
||||
|
|
|
@ -45,28 +45,44 @@ func TestKatex(t *testing.T) {
|
|||
|
||||
defer d.Close()
|
||||
|
||||
ctx := context.Background()
|
||||
runExpression := func(c *qt.C, id uint32, expression string) (Message[KatexOutput], error) {
|
||||
c.Helper()
|
||||
|
||||
input := KatexInput{
|
||||
Expression: "c = \\pm\\sqrt{a^2 + b^2}",
|
||||
Options: KatexOptions{
|
||||
Output: "html",
|
||||
DisplayMode: true,
|
||||
},
|
||||
ctx := context.Background()
|
||||
|
||||
input := KatexInput{
|
||||
Expression: expression,
|
||||
Options: KatexOptions{
|
||||
Output: "html",
|
||||
DisplayMode: true,
|
||||
ThrowOnError: true,
|
||||
},
|
||||
}
|
||||
|
||||
message := Message[KatexInput]{
|
||||
Header: Header{
|
||||
Version: currentVersion,
|
||||
ID: uint32(id),
|
||||
},
|
||||
Data: input,
|
||||
}
|
||||
|
||||
return d.Execute(ctx, message)
|
||||
}
|
||||
|
||||
message := Message[KatexInput]{
|
||||
Header: Header{
|
||||
Version: currentVersion,
|
||||
ID: uint32(32),
|
||||
},
|
||||
Data: input,
|
||||
}
|
||||
c.Run("Simple", func(c *qt.C) {
|
||||
id := uint32(32)
|
||||
result, err := runExpression(c, id, "c = \\pm\\sqrt{a^2 + b^2}")
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(result.GetID(), qt.Equals, id)
|
||||
})
|
||||
|
||||
result, err := d.Execute(ctx, message)
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
c.Assert(result.GetID(), qt.Equals, message.GetID())
|
||||
c.Run("Invalid expression", func(c *qt.C) {
|
||||
id := uint32(32)
|
||||
result, err := runExpression(c, id, "c & \\foo\\")
|
||||
c.Assert(err, qt.IsNotNil)
|
||||
c.Assert(result.GetID(), qt.Equals, id)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGreet(t *testing.T) {
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -235,7 +235,7 @@ func (ns *Namespace) ToMath(ctx context.Context, args ...any) (types.Result[temp
|
|||
_, r, err := fileCache.GetOrCreate(key, func() (io.ReadCloser, error) {
|
||||
message := warpc.Message[warpc.KatexInput]{
|
||||
Header: warpc.Header{
|
||||
Version: "v1",
|
||||
Version: 1,
|
||||
ID: ns.id.Add(1),
|
||||
},
|
||||
Data: katexInput,
|
||||
|
@ -249,9 +249,6 @@ func (ns *Namespace) ToMath(ctx context.Context, args ...any) (types.Result[temp
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if result.Header.Err != "" {
|
||||
return nil, errors.New(result.Header.Err)
|
||||
}
|
||||
return hugio.NewReadSeekerNoOpCloserFromString(result.Data.Output), nil
|
||||
})
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue