@primate/go 0.5.0 → 0.6.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 +4 -0
- package/lib/private/default.js +90 -0
- package/lib/private/errors.d.ts +17 -0
- package/lib/private/errors.js +27 -0
- package/lib/private/module.d.ts +13 -0
- package/lib/private/module.js +11 -0
- package/lib/private/runtime.d.ts +4 -0
- package/lib/private/runtime.js +10 -0
- package/lib/private/to-request.d.ts +1 -1
- package/lib/public/default.d.ts +1 -3
- package/lib/public/default.js +1 -2
- package/lib/public/runtime.d.ts +1 -3
- package/lib/public/runtime.js +1 -2
- package/package.json +15 -11
- package/lib/private/Default.d.ts +0 -7
- package/lib/private/Default.js +0 -84
- package/lib/private/Runtime.d.ts +0 -6
- package/lib/private/Runtime.js +0 -6
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import E from "#errors";
|
|
2
|
+
import module from "#module";
|
|
3
|
+
import log from "@primate/core/log";
|
|
4
|
+
import server from "@primate/core/server";
|
|
5
|
+
import assert from "@rcompat/assert";
|
|
6
|
+
import env from "@rcompat/env";
|
|
7
|
+
import { CodeError } from "@rcompat/error";
|
|
8
|
+
import io from "@rcompat/io";
|
|
9
|
+
const COMMAND = await io.which("go");
|
|
10
|
+
const ENV = {
|
|
11
|
+
GOARCH: "wasm",
|
|
12
|
+
GOCACHE: (await io.run(`${COMMAND} env GOCACHE`, {})).replaceAll("\n", ""),
|
|
13
|
+
GOOS: "js",
|
|
14
|
+
HOME: env.get("HOME"),
|
|
15
|
+
};
|
|
16
|
+
const REPO = "github.com/primate-run/go";
|
|
17
|
+
const [MAJOR, MINOR] = server.TAG.split(".").map(Number);
|
|
18
|
+
const run = (wasm, go) => `${COMMAND} build -o ${wasm.name} ${go.name}`;
|
|
19
|
+
function postlude(code, route_id) {
|
|
20
|
+
if (!code.includes(`${REPO}/route`)) {
|
|
21
|
+
log.warn("Go file does not import {0} - skipping route registration", REPO);
|
|
22
|
+
return code;
|
|
23
|
+
}
|
|
24
|
+
return `${code}
|
|
25
|
+
func main() {
|
|
26
|
+
route.Commit("${route_id}")
|
|
27
|
+
select{}
|
|
28
|
+
}`;
|
|
29
|
+
}
|
|
30
|
+
async function check_version() {
|
|
31
|
+
try {
|
|
32
|
+
const version = (await io.run(`go list -m -f '{{.Version}}' ${REPO}`)).trim();
|
|
33
|
+
const version_match = version.match(/^v?(\d+)\.(\d+)\.(\d+)/);
|
|
34
|
+
if (version_match == null)
|
|
35
|
+
throw E.invalid_version_format(version);
|
|
36
|
+
const [, major, minor] = version_match.map(Number);
|
|
37
|
+
if (major !== MAJOR || minor !== MINOR) {
|
|
38
|
+
throw E.version_not_in_range(version, server.TAG);
|
|
39
|
+
}
|
|
40
|
+
log.info("using {0} package v{1}.{2}.x", REPO, major, minor);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (CodeError.is(error))
|
|
44
|
+
throw error;
|
|
45
|
+
const command = `go get ${REPO}@v${server.TAG}.0`;
|
|
46
|
+
throw E.dependency_not_found(REPO, command);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function wrap(route_id) {
|
|
50
|
+
return `
|
|
51
|
+
import wrapper from "@primate/go/wrapper";
|
|
52
|
+
import bytes from "app:wasm/${route_id}.wasm" with { type: "bytes" };
|
|
53
|
+
import i18n from "app:config:i18n";
|
|
54
|
+
import session from "app:config:session";
|
|
55
|
+
await wrapper(bytes, ${JSON.stringify(route_id)}, { i18n, session });
|
|
56
|
+
`;
|
|
57
|
+
}
|
|
58
|
+
export default function default_module(input = {}) {
|
|
59
|
+
const { extension = module.extension } = module.schema.parse(input);
|
|
60
|
+
return {
|
|
61
|
+
name: module.name,
|
|
62
|
+
setup({ onBuild }) {
|
|
63
|
+
onBuild(async (app) => {
|
|
64
|
+
await check_version();
|
|
65
|
+
app.bind(extension, async (route, { context }) => {
|
|
66
|
+
assert.true(context === "routes", E.only_route_files());
|
|
67
|
+
const relative = route.debase(app.path.routes);
|
|
68
|
+
const route_id = relative.path.slice(1, -relative.extension.length);
|
|
69
|
+
const build_go_file = app.runpath("wasm", `${route_id}.go`);
|
|
70
|
+
await build_go_file.directory.create();
|
|
71
|
+
await build_go_file.write(postlude(await route.text(), route_id));
|
|
72
|
+
const wasm = app.runpath("wasm", `${route_id}.wasm`);
|
|
73
|
+
try {
|
|
74
|
+
log.info("compiling {0} to WebAssembly", route);
|
|
75
|
+
await io.run(run(wasm, build_go_file), {
|
|
76
|
+
cwd: build_go_file.directory.path,
|
|
77
|
+
env: ENV,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
throw E.backend_error(route, error);
|
|
82
|
+
}
|
|
83
|
+
await build_go_file.remove();
|
|
84
|
+
return wrap(route_id);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=default.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FileRef } from "@rcompat/fs";
|
|
2
|
+
declare function backend_error(route: FileRef, cause: Error): import("@rcompat/error").TemplateError;
|
|
3
|
+
declare function only_route_files(): import("@rcompat/error").TemplateError;
|
|
4
|
+
declare function invalid_version_format(format: string): import("@rcompat/error").TemplateError;
|
|
5
|
+
declare function version_not_in_range(version: string, tag: string): import("@rcompat/error").TemplateError;
|
|
6
|
+
declare function dependency_not_found(dependency: string, command: string): import("@rcompat/error").TemplateError;
|
|
7
|
+
declare const errors: {
|
|
8
|
+
backend_error: typeof backend_error;
|
|
9
|
+
only_route_files: typeof only_route_files;
|
|
10
|
+
invalid_version_format: typeof invalid_version_format;
|
|
11
|
+
version_not_in_range: typeof version_not_in_range;
|
|
12
|
+
dependency_not_found: typeof dependency_not_found;
|
|
13
|
+
};
|
|
14
|
+
export type Code = keyof typeof errors;
|
|
15
|
+
export declare const Code: { [K in Code]: K; };
|
|
16
|
+
export default errors;
|
|
17
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import error from "@rcompat/error";
|
|
2
|
+
const t = error.template;
|
|
3
|
+
function backend_error(route, cause) {
|
|
4
|
+
return t `error in module ${route.path}\n${cause}`;
|
|
5
|
+
}
|
|
6
|
+
function only_route_files() {
|
|
7
|
+
return t `go: only route files are supported`;
|
|
8
|
+
}
|
|
9
|
+
function invalid_version_format(format) {
|
|
10
|
+
return t `invalid version format: ${format}`;
|
|
11
|
+
}
|
|
12
|
+
function version_not_in_range(version, tag) {
|
|
13
|
+
return t `installed version ${version} not in range ${tag}`;
|
|
14
|
+
}
|
|
15
|
+
function dependency_not_found(dependency, command) {
|
|
16
|
+
return t `${dependency} dependency not found - run ${command}`;
|
|
17
|
+
}
|
|
18
|
+
const errors = error.coded({
|
|
19
|
+
backend_error,
|
|
20
|
+
only_route_files,
|
|
21
|
+
invalid_version_format,
|
|
22
|
+
version_not_in_range,
|
|
23
|
+
dependency_not_found,
|
|
24
|
+
});
|
|
25
|
+
export const Code = Object.fromEntries(Object.keys(errors).map(k => [k, k]));
|
|
26
|
+
export default errors;
|
|
27
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare const module: {
|
|
2
|
+
schema: import("pema").ObjectType<import("pema").NormalizeSchemaObject<{
|
|
3
|
+
readonly extension: import("pema").OptionalType<import("pema").StringType>;
|
|
4
|
+
}>, {
|
|
5
|
+
extension: string | undefined;
|
|
6
|
+
}>;
|
|
7
|
+
name: string;
|
|
8
|
+
extension: string;
|
|
9
|
+
};
|
|
10
|
+
type Input = typeof module.schema.input;
|
|
11
|
+
export type { Input };
|
|
12
|
+
export default module;
|
|
13
|
+
//# sourceMappingURL=module.d.ts.map
|
package/lib/public/default.d.ts
CHANGED
package/lib/public/default.js
CHANGED
package/lib/public/runtime.d.ts
CHANGED
package/lib/public/runtime.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primate/go",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Go backend for Primate",
|
|
5
5
|
"homepage": "https://primate.run/docs/backend/go",
|
|
6
6
|
"bugs": "https://github.com/primate-run/primate/issues",
|
|
@@ -17,37 +17,41 @@
|
|
|
17
17
|
"!/**/*.spec.*"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@rcompat/assert": "^0.
|
|
21
|
-
"@rcompat/env": "^0.
|
|
22
|
-
"@rcompat/
|
|
23
|
-
"@rcompat/
|
|
24
|
-
"@
|
|
20
|
+
"@rcompat/assert": "^0.8.1",
|
|
21
|
+
"@rcompat/env": "^0.17.2",
|
|
22
|
+
"@rcompat/error": "^0.3.1",
|
|
23
|
+
"@rcompat/fs": "^0.28.1",
|
|
24
|
+
"@rcompat/io": "^0.5.1",
|
|
25
|
+
"@primate/core": "^0.6.0",
|
|
26
|
+
"pema": "^0.6.0"
|
|
25
27
|
},
|
|
26
28
|
"devDependencies": {
|
|
27
|
-
"@rcompat/type": "^0.
|
|
29
|
+
"@rcompat/type": "^0.11.1"
|
|
28
30
|
},
|
|
29
31
|
"peerDependencies": {
|
|
30
|
-
"primate": "^0.
|
|
32
|
+
"primate": "^0.37.0"
|
|
31
33
|
},
|
|
32
34
|
"imports": {
|
|
33
35
|
"#*": {
|
|
34
|
-
"
|
|
36
|
+
"@primate/source": "./src/private/*.ts",
|
|
35
37
|
"default": "./lib/private/*.js"
|
|
36
38
|
}
|
|
37
39
|
},
|
|
38
40
|
"exports": {
|
|
39
41
|
".": {
|
|
42
|
+
"@rcompat/source": "./src/public/default.ts",
|
|
40
43
|
"runtime": "./lib/public/runtime.js",
|
|
41
44
|
"default": "./lib/public/default.js"
|
|
42
45
|
},
|
|
43
46
|
"./*": {
|
|
44
|
-
"
|
|
47
|
+
"@primate/source": "./src/public/*.ts",
|
|
45
48
|
"default": "./lib/public/*.js"
|
|
46
49
|
}
|
|
47
50
|
},
|
|
48
51
|
"scripts": {
|
|
49
52
|
"build": "npm run clean && tsc",
|
|
50
53
|
"clean": "rm -rf ./lib",
|
|
51
|
-
"lint": "eslint ."
|
|
54
|
+
"lint": "eslint .",
|
|
55
|
+
"test": "npx proby"
|
|
52
56
|
}
|
|
53
57
|
}
|
package/lib/private/Default.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import Runtime from "#Runtime";
|
|
2
|
-
import type BuildApp from "@primate/core/BuildApp";
|
|
3
|
-
import type NextBuild from "@primate/core/NextBuild";
|
|
4
|
-
export default class Default extends Runtime {
|
|
5
|
-
build(app: BuildApp, next: NextBuild): Promise<BuildApp>;
|
|
6
|
-
}
|
|
7
|
-
//# sourceMappingURL=Default.d.ts.map
|
package/lib/private/Default.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import Runtime from "#Runtime";
|
|
2
|
-
import AppError from "@primate/core/AppError";
|
|
3
|
-
import TAG from "@primate/core/backend/TAG";
|
|
4
|
-
import fail from "@primate/core/fail";
|
|
5
|
-
import log from "@primate/core/log";
|
|
6
|
-
import assert from "@rcompat/assert";
|
|
7
|
-
import user from "@rcompat/env/user";
|
|
8
|
-
import io from "@rcompat/io";
|
|
9
|
-
const COMMAND = await io.which("go");
|
|
10
|
-
const ENV = {
|
|
11
|
-
GOARCH: "wasm",
|
|
12
|
-
GOCACHE: (await io.run(`${COMMAND} env GOCACHE`, {})).replaceAll("\n", ""),
|
|
13
|
-
GOOS: "js",
|
|
14
|
-
HOME: user.HOME,
|
|
15
|
-
};
|
|
16
|
-
const REPO = "github.com/primate-run/go";
|
|
17
|
-
const [MAJOR, MINOR] = TAG.split(".").map(Number);
|
|
18
|
-
const run = (wasm, go) => `${COMMAND} build -o ${wasm.name} ${go.name}`;
|
|
19
|
-
function postlude(code, route_id) {
|
|
20
|
-
if (!code.includes(`${REPO}/route`)) {
|
|
21
|
-
log.warn("Go file does not import {0} - skipping route registration", REPO);
|
|
22
|
-
return code;
|
|
23
|
-
}
|
|
24
|
-
return `${code}
|
|
25
|
-
func main() {
|
|
26
|
-
route.Commit("${route_id}")
|
|
27
|
-
select{}
|
|
28
|
-
}`;
|
|
29
|
-
}
|
|
30
|
-
async function check_version() {
|
|
31
|
-
try {
|
|
32
|
-
const version = await io.run(`go list -m -f '{{.Version}}' ${REPO}`);
|
|
33
|
-
const trimmed = version.trim();
|
|
34
|
-
const version_match = trimmed.match(/^v?(\d+)\.(\d+)\.(\d+)/);
|
|
35
|
-
if (!version_match)
|
|
36
|
-
throw fail("invalid version format: {0}", trimmed);
|
|
37
|
-
const [, major, minor] = version_match.map(Number);
|
|
38
|
-
if (major !== MAJOR || minor !== MINOR) {
|
|
39
|
-
throw fail("installed version {0} not in range {1}", trimmed, TAG);
|
|
40
|
-
}
|
|
41
|
-
log.info("using {0} package v{1}.{2}.x", REPO, major, minor);
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
if (error instanceof AppError)
|
|
45
|
-
throw error;
|
|
46
|
-
throw fail("{0} dependency not found - run 'go get {0}@v{1}.0'", REPO, TAG);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
export default class Default extends Runtime {
|
|
50
|
-
async build(app, next) {
|
|
51
|
-
await check_version();
|
|
52
|
-
app.bind(this.fileExtension, async (route, { context }) => {
|
|
53
|
-
assert.true(context === "routes", "go: only route files are supported");
|
|
54
|
-
const relative = route.debase(app.path.routes);
|
|
55
|
-
const route_id = relative.path.slice(1, -relative.extension.length);
|
|
56
|
-
// create a temporary .go file in the build directory for compilation
|
|
57
|
-
// this is necessary because `go build` requires an actual file on disk
|
|
58
|
-
const build_go_file = app.runpath("wasm", `${route_id}.go`);
|
|
59
|
-
await build_go_file.directory.create();
|
|
60
|
-
await build_go_file.write(postlude(await route.text(), route_id));
|
|
61
|
-
const wasm = app.runpath("wasm", `${route_id}.wasm`);
|
|
62
|
-
try {
|
|
63
|
-
log.info("compiling {0} to WebAssembly", route);
|
|
64
|
-
await io.run(run(wasm, build_go_file), {
|
|
65
|
-
cwd: build_go_file.directory.path,
|
|
66
|
-
env: ENV,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
throw fail("error in module {0}\n{1}", route, error);
|
|
71
|
-
}
|
|
72
|
-
await build_go_file.remove();
|
|
73
|
-
return `
|
|
74
|
-
import wrapper from "@primate/go/wrapper";
|
|
75
|
-
import bytes from "app:wasm/${route_id}.wasm" with { type: "bytes" };
|
|
76
|
-
import i18n from "app:config:i18n";
|
|
77
|
-
import session from "app:config:session";
|
|
78
|
-
await wrapper(bytes, ${JSON.stringify(route_id)}, { i18n, session });
|
|
79
|
-
`;
|
|
80
|
-
});
|
|
81
|
-
return next(app);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
//# sourceMappingURL=Default.js.map
|
package/lib/private/Runtime.d.ts
DELETED