@primate/go 0.1.6 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/private/Default.d.ts +7 -0
- package/lib/private/Default.js +115 -0
- package/lib/private/Runtime.d.ts +6 -0
- package/lib/private/Runtime.js +6 -0
- package/lib/private/to-request.d.ts +45 -0
- package/lib/private/to-request.js +76 -0
- package/lib/private/to-response.d.ts +9 -0
- package/lib/private/to-response.js +24 -0
- package/lib/private/vendored/wasm_exec.d.ts +3 -0
- package/lib/private/vendored/wasm_exec.js +502 -0
- package/lib/public/default.d.ts +4 -0
- package/lib/public/default.js +3 -0
- package/lib/public/env.d.ts +2 -0
- package/lib/public/env.js +2 -0
- package/lib/public/runtime.d.ts +4 -0
- package/lib/public/runtime.js +3 -0
- package/lib/public/to-request.d.ts +2 -0
- package/lib/public/to-request.js +2 -0
- package/lib/public/to-response.d.ts +2 -0
- package/lib/public/to-response.js +2 -0
- package/package.json +29 -28
- package/src/default.js +0 -12
- package/src/env.js +0 -1
- package/src/private/build.js +0 -180
- package/src/private/error/route-error.js +0 -11
- package/src/private/extension.js +0 -1
- package/src/private/go.mod +0 -5
- package/src/private/go.sum +0 -2
- package/src/private/pkgname.js +0 -1
- package/src/private/request.go +0 -117
- package/src/private/session.go +0 -70
- package/src/runtime.js +0 -3
- package/src/to-request.js +0 -54
- package/src/to-response.js +0 -23
- package/src/vendored/wasm_exec.js +0 -559
package/src/private/build.js
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import route_error from "#error/route-error";
|
|
2
|
-
import pkgname from "#pkgname";
|
|
3
|
-
import verbs from "@primate/core/http/verbs";
|
|
4
|
-
import log from "@primate/core/log";
|
|
5
|
-
import dim from "@rcompat/cli/color/dim";
|
|
6
|
-
import { user } from "@rcompat/env";
|
|
7
|
-
import file from "@rcompat/fs/file";
|
|
8
|
-
import runtime from "@rcompat/runtime";
|
|
9
|
-
import execute from "@rcompat/stdio/execute";
|
|
10
|
-
import which from "@rcompat/stdio/which";
|
|
11
|
-
import upperfirst from "@rcompat/string/upperfirst";
|
|
12
|
-
|
|
13
|
-
const command = await which("go");
|
|
14
|
-
const env = {
|
|
15
|
-
GOOS: "js",
|
|
16
|
-
GOARCH: "wasm",
|
|
17
|
-
GOCACHE: (await execute(`${command} env GOCACHE`)).replaceAll("\n", ""),
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const run = (wasm, go, includes = "request.go") =>
|
|
21
|
-
`${command} build -o ${wasm} ${go} ${includes}`;
|
|
22
|
-
const verbs_string = verbs.map(upperfirst).join("|");
|
|
23
|
-
const routes_re = new RegExp(`func (?<route>${verbs_string})`, "gu");
|
|
24
|
-
const add_setter = route => `
|
|
25
|
-
var cb${route} js.Func;
|
|
26
|
-
cb${route} = js.FuncOf(func(this js.Value, args[]js.Value) any {
|
|
27
|
-
cb${route}.Release();
|
|
28
|
-
return make_request(${route}, args[0]);
|
|
29
|
-
});
|
|
30
|
-
js.Global().Set("${route}", cb${route});
|
|
31
|
-
`;
|
|
32
|
-
|
|
33
|
-
const make_route = route =>
|
|
34
|
-
` ${route.toLowerCase()}(request) {
|
|
35
|
-
const go = new globalThis.Go();
|
|
36
|
-
return WebAssembly.instantiate(route, {...go.importObject}).then(result => {
|
|
37
|
-
go.run(result.instance);
|
|
38
|
-
return to_response(globalThis.${route}(to_request(request)));
|
|
39
|
-
});
|
|
40
|
-
}`;
|
|
41
|
-
|
|
42
|
-
const js_wrapper = (path, routes) => `
|
|
43
|
-
import env from "@primate/go/env";
|
|
44
|
-
import to_request from "@primate/go/to-request";
|
|
45
|
-
import to_response from "@primate/go/to-response";
|
|
46
|
-
${
|
|
47
|
-
runtime === "bun" ? `
|
|
48
|
-
import route_path from "${path}" with { type: "file" };
|
|
49
|
-
const route = await Bun.file(route_path).arrayBuffer();
|
|
50
|
-
` : `
|
|
51
|
-
import file from "primate/runtime/file";
|
|
52
|
-
const route = new Uint8Array(await file(import.meta.url+"/../${path}")
|
|
53
|
-
.arrayBuffer());
|
|
54
|
-
`
|
|
55
|
-
}
|
|
56
|
-
env();
|
|
57
|
-
|
|
58
|
-
export default {
|
|
59
|
-
${routes.map(route => make_route(route)).join(",\n")}
|
|
60
|
-
};`;
|
|
61
|
-
|
|
62
|
-
const go_wrapper = (code, routes) =>
|
|
63
|
-
`// {{{ wrapper prefix
|
|
64
|
-
package main
|
|
65
|
-
import "syscall/js"
|
|
66
|
-
// }}} end
|
|
67
|
-
${code}
|
|
68
|
-
// {{{ wrapper postfix
|
|
69
|
-
func main() {
|
|
70
|
-
${routes.map(route => add_setter(route)).join("\n ")}
|
|
71
|
-
select{};
|
|
72
|
-
}
|
|
73
|
-
// }}} end`;
|
|
74
|
-
|
|
75
|
-
const get_routes = code => [...code.matchAll(routes_re)]
|
|
76
|
-
.map(({ groups: { route } }) => route);
|
|
77
|
-
|
|
78
|
-
const type_map = {
|
|
79
|
-
boolean: { transfer: "Bool", type: "bool" },
|
|
80
|
-
i8: { transfer: "Int", type: "int8" },
|
|
81
|
-
i16: { transfer: "Int", type: "int16" },
|
|
82
|
-
i32: { transfer: "Int", type: "int32" },
|
|
83
|
-
i64: { transfer: "Int", type: "int64" },
|
|
84
|
-
f32: { transfer: "Float", type: "float32" },
|
|
85
|
-
f64: { transfer: "Float", type: "float64" },
|
|
86
|
-
u8: { transfer: "Int", type: "uint8" },
|
|
87
|
-
u16: { transfer: "Int", type: "uint16" },
|
|
88
|
-
u32: { transfer: "Int", type: "uint32", nullval: "0" },
|
|
89
|
-
u64: { transfer: "Int", type: "uint64" },
|
|
90
|
-
string: { transfer: "String", type: "string" },
|
|
91
|
-
uuid: { transfer: "String", type: "string" },
|
|
92
|
-
};
|
|
93
|
-
const error_default = {
|
|
94
|
-
Bool: false,
|
|
95
|
-
Int: 0,
|
|
96
|
-
Float: 0,
|
|
97
|
-
String: "\"\"",
|
|
98
|
-
};
|
|
99
|
-
const root = file(import.meta.url).up(1);
|
|
100
|
-
|
|
101
|
-
const create_meta_files = async (directory, app) => {
|
|
102
|
-
const meta = {
|
|
103
|
-
mod: "go.mod",
|
|
104
|
-
sum: "go.sum",
|
|
105
|
-
request: "request.go",
|
|
106
|
-
session: "session.go",
|
|
107
|
-
};
|
|
108
|
-
const has_session = app.modules.names.includes("@primate/session");
|
|
109
|
-
|
|
110
|
-
if (!await directory.join(meta.mod).exists()) {
|
|
111
|
-
const request_struct_items = [];
|
|
112
|
-
const request_make_items = [];
|
|
113
|
-
|
|
114
|
-
if (has_session) {
|
|
115
|
-
request_struct_items.push(
|
|
116
|
-
"Session Session",
|
|
117
|
-
);
|
|
118
|
-
request_make_items.push(
|
|
119
|
-
"make_session(request),",
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const request_struct = request_struct_items.join("\n");
|
|
124
|
-
const request_make = request_make_items.join("\n");
|
|
125
|
-
|
|
126
|
-
// copy go.mod file
|
|
127
|
-
await directory.join(meta.mod).write(await root.join(meta.mod).text());
|
|
128
|
-
// copy go.sum file
|
|
129
|
-
await directory.join(meta.sum).write(await root.join(meta.sum).text());
|
|
130
|
-
|
|
131
|
-
// copy transformed request.go file
|
|
132
|
-
await directory.join(meta.request).write((await root.join(meta.request)
|
|
133
|
-
.text())
|
|
134
|
-
.replace("%%REQUEST_STRUCT%%", _ => request_struct)
|
|
135
|
-
.replace("%%REQUEST_MAKE%%", _ => request_make),
|
|
136
|
-
);
|
|
137
|
-
|
|
138
|
-
if (has_session) {
|
|
139
|
-
// copy session.go file
|
|
140
|
-
directory.join(meta.session).write(await root.join(meta.session).text());
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return ["request.go"]
|
|
145
|
-
.concat(has_session ? ["session.go"] : [])
|
|
146
|
-
;
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
export default ({ extension }) => (app, next) => {
|
|
150
|
-
app.bind(extension, async (directory, file) => {
|
|
151
|
-
const path = directory.join(file);
|
|
152
|
-
const base = path.directory;
|
|
153
|
-
const go = path.base.concat(".go");
|
|
154
|
-
const wasm = path.base.concat(".wasm");
|
|
155
|
-
const js = path.base.concat(".js");
|
|
156
|
-
|
|
157
|
-
// create meta files
|
|
158
|
-
const includes = await create_meta_files(base, app);
|
|
159
|
-
|
|
160
|
-
const code = await path.text();
|
|
161
|
-
const routes = get_routes(code);
|
|
162
|
-
// write .go file
|
|
163
|
-
await path.write(go_wrapper(code, routes));
|
|
164
|
-
// write .js wrapper
|
|
165
|
-
const wasm_route_path = `./${file.name.slice(0, -extension.length)}.wasm`;
|
|
166
|
-
await base.join(js).write(js_wrapper(wasm_route_path, routes));
|
|
167
|
-
|
|
168
|
-
try {
|
|
169
|
-
log.info(`compiling ${dim(file)} to WebAssembly`, { module: pkgname });
|
|
170
|
-
const cwd = `${base}`;
|
|
171
|
-
// compile .go to .wasm
|
|
172
|
-
await execute(run(wasm, go, includes.join(" ")),
|
|
173
|
-
{ cwd, env: { HOME: user.HOME, ...env } });
|
|
174
|
-
} catch (error) {
|
|
175
|
-
route_error(file, error);
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
return next(app);
|
|
180
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import pkgname from "#pkgname";
|
|
2
|
-
import log from "@primate/core/log";
|
|
3
|
-
import file from "@rcompat/fs/file";
|
|
4
|
-
|
|
5
|
-
export default (...params) => log.error({
|
|
6
|
-
params,
|
|
7
|
-
name: file(import.meta.url).base,
|
|
8
|
-
module: pkgname,
|
|
9
|
-
message: "error in Go route {0}",
|
|
10
|
-
fix: "fix route error:\n{1}",
|
|
11
|
-
});
|
package/src/private/extension.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default ".go";
|
package/src/private/go.mod
DELETED
package/src/private/go.sum
DELETED
package/src/private/pkgname.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default "@primate/go";
|
package/src/private/request.go
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
package main
|
|
2
|
-
|
|
3
|
-
import "syscall/js"
|
|
4
|
-
import "encoding/json"
|
|
5
|
-
|
|
6
|
-
type t_request func(Request) any
|
|
7
|
-
type t_response func(js.Value, []js.Value) any
|
|
8
|
-
type Object map[string]any
|
|
9
|
-
type Array []any
|
|
10
|
-
|
|
11
|
-
type Dispatcher struct {
|
|
12
|
-
Get func(string) any
|
|
13
|
-
Json func() map[string]any
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
type URL struct {
|
|
17
|
-
Href string
|
|
18
|
-
Origin string
|
|
19
|
-
Protocol string
|
|
20
|
-
Username string
|
|
21
|
-
Password string
|
|
22
|
-
Host string
|
|
23
|
-
Hostname string
|
|
24
|
-
Port string
|
|
25
|
-
Pathname string
|
|
26
|
-
Search string
|
|
27
|
-
SearchParams map[string]any
|
|
28
|
-
Hash string
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
type Request struct {
|
|
32
|
-
Url URL
|
|
33
|
-
Body map[string]any
|
|
34
|
-
Path Dispatcher
|
|
35
|
-
Query Dispatcher
|
|
36
|
-
Cookies Dispatcher
|
|
37
|
-
Headers Dispatcher
|
|
38
|
-
%%REQUEST_STRUCT%%
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
func make_url(request js.Value) URL {
|
|
42
|
-
url := request.Get("url");
|
|
43
|
-
search_params := make(map[string]any);
|
|
44
|
-
json.Unmarshal([]byte(request.Get("search_params").String()), &search_params);
|
|
45
|
-
|
|
46
|
-
return URL{
|
|
47
|
-
url.Get("href").String(),
|
|
48
|
-
url.Get("origin").String(),
|
|
49
|
-
url.Get("protocol").String(),
|
|
50
|
-
url.Get("username").String(),
|
|
51
|
-
url.Get("password").String(),
|
|
52
|
-
url.Get("host").String(),
|
|
53
|
-
url.Get("hostname").String(),
|
|
54
|
-
url.Get("port").String(),
|
|
55
|
-
url.Get("pathname").String(),
|
|
56
|
-
url.Get("search").String(),
|
|
57
|
-
search_params,
|
|
58
|
-
url.Get("hash").String(),
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
func make_dispatcher(key string, request js.Value) Dispatcher {
|
|
63
|
-
properties := make(map[string]any);
|
|
64
|
-
value := request.Get(key)
|
|
65
|
-
json.Unmarshal([]byte(value.Get("stringified").String()), &properties);
|
|
66
|
-
|
|
67
|
-
return Dispatcher{
|
|
68
|
-
// Get
|
|
69
|
-
func(property string) any {
|
|
70
|
-
switch properties[property].(type) {
|
|
71
|
-
case string:
|
|
72
|
-
return properties[property].(string);
|
|
73
|
-
default:
|
|
74
|
-
return nil;
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
// Json
|
|
78
|
-
func() map[string]any {
|
|
79
|
-
return properties;
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
func make_request(route t_request, request js.Value) any {
|
|
85
|
-
body := make(map[string]any);
|
|
86
|
-
json.Unmarshal([]byte(request.Get("body").String()), &body);
|
|
87
|
-
|
|
88
|
-
go_request := Request{
|
|
89
|
-
make_url(request),
|
|
90
|
-
body,
|
|
91
|
-
make_dispatcher("path", request),
|
|
92
|
-
make_dispatcher("query", request),
|
|
93
|
-
make_dispatcher("cookies", request),
|
|
94
|
-
make_dispatcher("headers", request),
|
|
95
|
-
%%REQUEST_MAKE%%
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
response := route(go_request);
|
|
99
|
-
switch response.(type) {
|
|
100
|
-
case js.Func:
|
|
101
|
-
return response;
|
|
102
|
-
default:
|
|
103
|
-
marshalled, _ := json.Marshal(response);
|
|
104
|
-
return string(marshalled);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
func make_empty(route func() any) any {
|
|
109
|
-
response := route();
|
|
110
|
-
switch response.(type) {
|
|
111
|
-
case js.Func:
|
|
112
|
-
return response;
|
|
113
|
-
default:
|
|
114
|
-
marshalled, _ := json.Marshal(response);
|
|
115
|
-
return string(marshalled);
|
|
116
|
-
}
|
|
117
|
-
}
|
package/src/private/session.go
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
package main
|
|
2
|
-
|
|
3
|
-
import "syscall/js"
|
|
4
|
-
import "encoding/json"
|
|
5
|
-
import "errors"
|
|
6
|
-
|
|
7
|
-
type Session struct {
|
|
8
|
-
Exists func() bool
|
|
9
|
-
Get func(string) any
|
|
10
|
-
Json func() map[string]any
|
|
11
|
-
Set func(string, any) error
|
|
12
|
-
Create func(map[string]any)
|
|
13
|
-
Destroy func()
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
func make_session(request js.Value) Session {
|
|
17
|
-
session := request.Get("session");
|
|
18
|
-
properties := make(map[string]any);
|
|
19
|
-
json.Unmarshal([]byte(session.Get("stringified").String()), &properties);
|
|
20
|
-
|
|
21
|
-
return Session{
|
|
22
|
-
// Exists
|
|
23
|
-
func() bool {
|
|
24
|
-
return session.Get("exists").Invoke().Bool();
|
|
25
|
-
},
|
|
26
|
-
// Get
|
|
27
|
-
func(key string) any {
|
|
28
|
-
invoked := session.Get("get").Invoke(key);
|
|
29
|
-
jstype := invoked.Type()
|
|
30
|
-
switch jstype {
|
|
31
|
-
case 0:
|
|
32
|
-
case 1:
|
|
33
|
-
return nil;
|
|
34
|
-
case 2:
|
|
35
|
-
return invoked.Bool();
|
|
36
|
-
case 3:
|
|
37
|
-
return invoked.Float();
|
|
38
|
-
case 4:
|
|
39
|
-
return invoked.String();
|
|
40
|
-
// currently unsupported
|
|
41
|
-
case 5:
|
|
42
|
-
case 6:
|
|
43
|
-
case 7:
|
|
44
|
-
return nil;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return nil;
|
|
48
|
-
},
|
|
49
|
-
// Json
|
|
50
|
-
func() map[string]any {
|
|
51
|
-
return properties;
|
|
52
|
-
},
|
|
53
|
-
// Set
|
|
54
|
-
func(key string, value any) error {
|
|
55
|
-
r := session.Get("set").Invoke(key, value);
|
|
56
|
-
if (r.Type() == 7) {
|
|
57
|
-
return errors.New(r.Invoke().String());
|
|
58
|
-
}
|
|
59
|
-
return nil
|
|
60
|
-
},
|
|
61
|
-
// Create
|
|
62
|
-
func(data map[string]any) {
|
|
63
|
-
session.Get("create").Invoke(data);
|
|
64
|
-
},
|
|
65
|
-
// Destroy
|
|
66
|
-
func() {
|
|
67
|
-
session.Get("destroy").Invoke();
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
}
|
package/src/runtime.js
DELETED
package/src/to-request.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import exclude from "@rcompat/object/exclude";
|
|
2
|
-
import stringify from "@rcompat/object/stringify";
|
|
3
|
-
import valmap from "@rcompat/object/valmap";
|
|
4
|
-
|
|
5
|
-
const to_search_params = url =>
|
|
6
|
-
stringify(Object.fromEntries(url.searchParams.entries()));
|
|
7
|
-
const dispatchers = ["path", "query", "cookies", "headers"];
|
|
8
|
-
|
|
9
|
-
const to_dispatcher = dispatcher =>
|
|
10
|
-
valmap(exclude(dispatcher, ["get", "raw"]), getter => {
|
|
11
|
-
try {
|
|
12
|
-
return getter();
|
|
13
|
-
} catch ({ message }) {
|
|
14
|
-
return () => message;
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
const make_session = session => {
|
|
19
|
-
if (session === undefined) {
|
|
20
|
-
return {};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
session: {
|
|
25
|
-
...session,
|
|
26
|
-
set: (key, value) => {
|
|
27
|
-
try {
|
|
28
|
-
return session.set(key, value);
|
|
29
|
-
} catch ({ message }) {
|
|
30
|
-
return () => message;
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
get: session.get,
|
|
34
|
-
stringified: session.toString(),
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export default request => {
|
|
40
|
-
dispatchers.map(property => to_dispatcher(request[property]));
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
url: request.url,
|
|
44
|
-
search_params: to_search_params(request.url),
|
|
45
|
-
body: JSON.stringify(request.body),
|
|
46
|
-
...Object.fromEntries(dispatchers.map(property => [
|
|
47
|
-
property, {
|
|
48
|
-
stringified: request[property].toString(),
|
|
49
|
-
...to_dispatcher(request[property]),
|
|
50
|
-
},
|
|
51
|
-
])),
|
|
52
|
-
...make_session(request.session),
|
|
53
|
-
};
|
|
54
|
-
};
|
package/src/to-response.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import error from "@primate/core/handler/error";
|
|
2
|
-
import redirect from "@primate/core/handler/redirect";
|
|
3
|
-
import view from "@primate/core/handler/view";
|
|
4
|
-
|
|
5
|
-
const handlers = {
|
|
6
|
-
view({ component, props = "{}", options = "{}" }) {
|
|
7
|
-
return view(component, JSON.parse(props), JSON.parse(options));
|
|
8
|
-
},
|
|
9
|
-
redirect({ location, options = "{}" }) {
|
|
10
|
-
return redirect(location, JSON.parse(options));
|
|
11
|
-
},
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const handle_function = response => {
|
|
15
|
-
const { handler, ...args } = response;
|
|
16
|
-
return handlers[handler]?.(args) ?? error();
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const handle_other = response => JSON.parse(response);
|
|
20
|
-
|
|
21
|
-
export default response => typeof response === "function"
|
|
22
|
-
? handle_function(response())
|
|
23
|
-
: handle_other(response);
|