@primate/core 0.6.3 → 0.7.1
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/App.d.ts +76 -149
- package/lib/private/App.js +22 -6
- package/lib/private/Flags.d.ts +5 -3
- package/lib/private/Flags.js +4 -2
- package/lib/private/app/Facade.d.ts +77 -156
- package/lib/private/app/Facade.js +4 -1
- package/lib/private/build/App.d.ts +4 -2
- package/lib/private/build/App.js +13 -4
- package/lib/private/build/client/index.js +24 -10
- package/lib/private/build/client/plugin/routes.d.ts +4 -0
- package/lib/private/build/client/plugin/routes.js +77 -0
- package/lib/private/build/hook.js +14 -6
- package/lib/private/build/index.d.ts +3 -2
- package/lib/private/build/index.js +9 -15
- package/lib/private/build/preclient/index.d.ts +3 -0
- package/lib/private/build/preclient/index.js +69 -0
- package/lib/private/build/preclient/plugin/routes.d.ts +4 -0
- package/lib/private/build/preclient/plugin/routes.js +44 -0
- package/lib/private/build/server/index.js +8 -5
- package/lib/private/build/server/plugin/assets.js +3 -3
- package/lib/private/build/server/plugin/native-addons.js +6 -8
- package/lib/private/build/server/plugin/node-imports.js +5 -7
- package/lib/private/build/server/plugin/route-client.d.ts +4 -0
- package/lib/private/build/server/plugin/route-client.js +111 -0
- package/lib/private/build/server/plugin/route.js +3 -10
- package/lib/private/build/server/plugin/virtual-pages.js +3 -3
- package/lib/private/build/server/plugin/virtual-routes.d.ts +2 -1
- package/lib/private/build/server/plugin/virtual-routes.js +27 -8
- package/lib/private/build/server/plugin/wasm.js +3 -2
- package/lib/private/build/shared/intercept.d.ts +4 -0
- package/lib/private/build/shared/intercept.js +29 -0
- package/lib/private/client/Data.d.ts +1 -1
- package/lib/private/client/boot.js +2 -2
- package/lib/private/client/create-form.d.ts +11 -1
- package/lib/private/client/create-form.js +21 -3
- package/lib/private/client/index.d.ts +2 -2
- package/lib/private/client/navigate.d.ts +1 -0
- package/lib/private/client/navigate.js +7 -6
- package/lib/private/client/submit.d.ts +2 -1
- package/lib/private/client/submit.js +8 -7
- package/lib/private/client/{http.d.ts → transport.d.ts} +3 -3
- package/lib/private/client/{http.js → transport.js} +7 -9
- package/lib/private/config/schema.d.ts +5 -13
- package/lib/private/config/schema.js +1 -5
- package/lib/private/db/DB.d.ts +3 -1
- package/lib/private/db/MemoryDB.d.ts +5 -2
- package/lib/private/db/MemoryDB.js +33 -19
- package/lib/private/db/SQLDB.d.ts +23 -0
- package/lib/private/db/SQLDB.js +2 -0
- package/lib/private/db/errors.d.ts +74 -7
- package/lib/private/db/errors.js +31 -7
- package/lib/private/db/migrate/apply.js +8 -9
- package/lib/private/db/migrate/bundle.js +2 -2
- package/lib/private/db/migrate/create.js +18 -20
- package/lib/private/db/migrate/status.js +9 -10
- package/lib/private/db/migrate/store.d.ts +3 -3
- package/lib/private/db/migrate/store.js +5 -5
- package/lib/private/db/test.js +256 -115
- package/lib/private/db/testSQL.d.ts +50 -0
- package/lib/private/db/testSQL.js +196 -0
- package/lib/private/errors.d.ts +66 -9
- package/lib/private/errors.js +37 -16
- package/lib/private/frontend.d.ts +4 -4
- package/lib/private/frontend.js +11 -8
- package/lib/private/i18n/errors.d.ts +7 -1
- package/lib/private/i18n/errors.js +1 -1
- package/lib/private/i18n/index/types.d.ts +1 -1
- package/lib/private/i18n/locale.d.ts +1 -1
- package/lib/private/i18n/module.js +6 -5
- package/lib/private/index.d.ts +10 -2
- package/lib/private/index.js +13 -1
- package/lib/private/logger.d.ts +24 -0
- package/lib/private/logger.js +66 -0
- package/lib/private/module/Setup.d.ts +3 -0
- package/lib/private/module/create.d.ts +2 -1
- package/lib/private/module/create.js +4 -0
- package/lib/private/paths.d.ts +2 -3
- package/lib/private/paths.js +6 -12
- package/lib/private/request/ContentType.d.ts +3 -0
- package/lib/private/request/ContentType.js +2 -0
- package/lib/private/request/RequestBag.d.ts +2 -18
- package/lib/private/request/RequestBag.js +4 -16
- package/lib/private/request/RequestBody.d.ts +20 -28
- package/lib/private/request/RequestBody.js +63 -86
- package/lib/private/request/RequestFacade.d.ts +2 -2
- package/lib/private/request/handle.js +2 -2
- package/lib/private/request/parse.js +2 -4
- package/lib/private/request/route.js +15 -8
- package/lib/private/response/binary.d.ts +2 -2
- package/lib/private/response/binary.js +6 -6
- package/lib/private/response/error.js +6 -2
- package/lib/private/response/json.js +2 -2
- package/lib/private/response/null.d.ts +3 -0
- package/lib/private/response/null.js +6 -0
- package/lib/private/response/redirect.js +4 -3
- package/lib/private/response/respond.js +4 -4
- package/lib/private/response/sse.js +2 -2
- package/lib/private/response/text.js +2 -2
- package/lib/private/route/ContentTypeMap.d.ts +10 -0
- package/lib/private/route/ContentTypeMap.js +2 -0
- package/lib/private/route/Handler.d.ts +3 -2
- package/lib/private/route/NarrowedRequest.d.ts +23 -0
- package/lib/private/route/NarrowedRequest.js +2 -0
- package/lib/private/route/Options.d.ts +6 -1
- package/lib/private/route/Path.d.ts +2 -2
- package/lib/private/route/hook.d.ts +3 -1
- package/lib/private/route/hook.js +1 -2
- package/lib/private/route/router.d.ts +7 -11
- package/lib/private/route/router.js +13 -20
- package/lib/private/route.client.d.ts +36 -0
- package/lib/private/route.client.js +8 -0
- package/lib/private/route.d.ts +21 -5
- package/lib/private/route.js +21 -5
- package/lib/private/serve/App.d.ts +1 -2
- package/lib/private/serve/App.js +64 -58
- package/lib/private/serve/Init.d.ts +2 -0
- package/lib/private/serve/dev-module.js +2 -3
- package/lib/private/serve/index.js +5 -6
- package/lib/private/server/TAG.d.ts +1 -1
- package/lib/private/server/TAG.js +1 -1
- package/lib/private/session/index.d.ts +1 -1
- package/lib/private/session/index.js +3 -2
- package/lib/private/session/module.js +3 -3
- package/lib/private/session/schema.d.ts +3 -3
- package/lib/private/session/schema.js +4 -3
- package/lib/private/store/ExtractRelation.d.ts +7 -0
- package/lib/private/store/ExtractRelation.js +2 -0
- package/lib/private/store/ExtractSchema.d.ts +10 -0
- package/lib/private/{orm → store}/ForeignKey.d.ts +1 -1
- package/lib/private/store/Init.d.ts +13 -0
- package/lib/private/store/Init.js +2 -0
- package/lib/private/{orm/store.d.ts → store/Store.d.ts} +50 -50
- package/lib/private/{orm/store.js → store/Store.js} +163 -107
- package/lib/private/store/StoreInput.d.ts +11 -0
- package/lib/private/store/key.d.ts +8 -0
- package/lib/private/store/key.js +8 -0
- package/lib/private/{orm → store}/parse.d.ts +3 -3
- package/lib/private/{orm → store}/parse.js +7 -2
- package/lib/private/store/relation.d.ts +29 -0
- package/lib/private/store/relation.js +26 -0
- package/lib/private/store.d.ts +24 -0
- package/lib/private/store.js +10 -0
- package/lib/public/db/errors.d.ts +1 -1
- package/lib/public/db/errors.js +1 -1
- package/lib/public/db/testSQL.d.ts +2 -0
- package/lib/public/db/testSQL.js +2 -0
- package/lib/public/db.d.ts +1 -0
- package/lib/public/index.d.ts +1 -0
- package/lib/public/index.js +1 -1
- package/lib/public/response.d.ts +6 -6
- package/lib/public/response.js +4 -1
- package/lib/public/route.client.d.ts +2 -0
- package/lib/public/route.client.js +2 -0
- package/lib/public/store.d.ts +2 -0
- package/lib/public/store.js +2 -0
- package/package.json +24 -17
- package/lib/private/bye.d.ts +0 -3
- package/lib/private/bye.js +0 -4
- package/lib/private/log.d.ts +0 -20
- package/lib/private/log.js +0 -47
- package/lib/private/orm/ExtractSchema.d.ts +0 -9
- package/lib/private/orm/StoreInput.d.ts +0 -10
- package/lib/private/orm/key.d.ts +0 -8
- package/lib/private/orm/key.js +0 -8
- package/lib/private/orm/relation.d.ts +0 -43
- package/lib/private/orm/relation.js +0 -26
- package/lib/private/request/Verb.d.ts +0 -4
- package/lib/private/request/Verb.js +0 -2
- package/lib/private/request/verbs.d.ts +0 -3
- package/lib/private/request/verbs.js +0 -12
- package/lib/private/route/wrap.d.ts +0 -2
- package/lib/private/route/wrap.js +0 -12
- package/lib/public/log.d.ts +0 -2
- package/lib/public/log.js +0 -2
- package/lib/public/orm/key.d.ts +0 -2
- package/lib/public/orm/key.js +0 -2
- package/lib/public/orm/relation.d.ts +0 -2
- package/lib/public/orm/relation.js +0 -2
- package/lib/public/orm/store.d.ts +0 -2
- package/lib/public/orm/store.js +0 -2
- package/lib/public/request/verbs.d.ts +0 -2
- package/lib/public/request/verbs.js +0 -2
- /package/lib/private/{orm → store}/ExtractSchema.js +0 -0
- /package/lib/private/{orm → store}/ForeignKey.js +0 -0
- /package/lib/private/{orm → store}/PrimaryKey.d.ts +0 -0
- /package/lib/private/{orm → store}/PrimaryKey.js +0 -0
- /package/lib/private/{orm → store}/StoreInput.js +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import E from "#errors";
|
|
2
|
-
import wrap from "#route/wrap";
|
|
3
2
|
import fs from "@rcompat/fs";
|
|
4
|
-
const
|
|
3
|
+
const empty = "export default {};";
|
|
5
4
|
export default function plugin_server_route(app) {
|
|
6
5
|
const path_routes = app.path.routes;
|
|
7
6
|
return {
|
|
@@ -28,23 +27,17 @@ export default function plugin_server_route(app) {
|
|
|
28
27
|
if (!file || !extension) {
|
|
29
28
|
throw E.build_missing_route(relative, path_routes);
|
|
30
29
|
}
|
|
31
|
-
// normalise "routes/foo.ext" -> "foo" for router
|
|
32
|
-
const relative_from_routes = file.path.split("routes").pop();
|
|
33
|
-
const no_extensions = relative_from_routes
|
|
34
|
-
.replace(/^[\\/]/, "")
|
|
35
|
-
.slice(0, -extension.length);
|
|
36
|
-
const route_path = no_extensions.replace(/\\/g, "/");
|
|
37
30
|
const resolveDir = file.directory.path;
|
|
38
31
|
const watchFiles = [file.path];
|
|
39
32
|
const binder = app.binder(file);
|
|
40
33
|
if (!binder)
|
|
41
|
-
return { contents, loader: "js", resolveDir, watchFiles };
|
|
34
|
+
return { contents: empty, loader: "js", resolveDir, watchFiles };
|
|
42
35
|
const compiled = await binder(file, {
|
|
43
36
|
build: { id: app.id },
|
|
44
37
|
context: "routes",
|
|
45
38
|
});
|
|
46
39
|
return {
|
|
47
|
-
contents:
|
|
40
|
+
contents: compiled,
|
|
48
41
|
loader: extension === ".ts" ? "ts" : "js",
|
|
49
42
|
resolveDir,
|
|
50
43
|
watchFiles,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
const
|
|
1
|
+
import runtime from "@rcompat/runtime";
|
|
2
|
+
const core = await runtime.projectRoot(import.meta.dirname);
|
|
3
3
|
export default function plugin_server_virtual_pages(app) {
|
|
4
4
|
return {
|
|
5
5
|
name: "primate/server/virtual/pages",
|
|
@@ -9,7 +9,7 @@ export default function plugin_server_virtual_pages(app) {
|
|
|
9
9
|
});
|
|
10
10
|
build.onLoad({ filter: /.*/, namespace: "primate-pages" }, async () => {
|
|
11
11
|
const filter = /^.*\.html$/ui;
|
|
12
|
-
const defaults =
|
|
12
|
+
const defaults = core.join("lib", "private", "defaults");
|
|
13
13
|
const pages = {};
|
|
14
14
|
for (const file of await defaults.files({ filter })) {
|
|
15
15
|
pages[file.name] = file;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type BuildApp from "#build/App";
|
|
2
2
|
import type { Plugin } from "esbuild";
|
|
3
|
-
|
|
3
|
+
declare function plugin_server_virtual_routes(app: BuildApp): Plugin;
|
|
4
|
+
export default plugin_server_virtual_routes;
|
|
4
5
|
//# sourceMappingURL=virtual-routes.d.ts.map
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
function is_hook_file(p) {
|
|
2
|
+
const basename = p.split("/").at(-1) ?? p;
|
|
3
|
+
return basename === "+hook" || basename.startsWith("+hook.");
|
|
4
|
+
}
|
|
5
|
+
function plugin_server_virtual_routes(app) {
|
|
2
6
|
const extension_pattern = new RegExp(`(${app.extensions.map(e => e.replace(".", "\\.")).join("|")})$`);
|
|
3
|
-
|
|
4
|
-
!f.name.
|
|
5
|
-
|
|
7
|
+
function is_route_file(f) {
|
|
8
|
+
return !f.name.endsWith("~") &&
|
|
9
|
+
!f.name.startsWith(".") &&
|
|
10
|
+
!f.name.startsWith("-") &&
|
|
11
|
+
extension_pattern.test(f.path);
|
|
12
|
+
}
|
|
6
13
|
return {
|
|
7
14
|
name: "primate/server/virtual/routes",
|
|
8
15
|
setup(build) {
|
|
@@ -16,13 +23,24 @@ export default function plugin_server_virtual_routes(app) {
|
|
|
16
23
|
recursive: true,
|
|
17
24
|
});
|
|
18
25
|
const contents = `
|
|
19
|
-
|
|
26
|
+
import router from "primate/router";
|
|
27
|
+
${route_files.map((file, i) => {
|
|
28
|
+
const path = app.basename(file, app.path.routes);
|
|
29
|
+
return `import route${i} from "app:route/${path}";`;
|
|
30
|
+
}).join("\n")}
|
|
31
|
+
const routes = [];
|
|
20
32
|
${route_files.map((file, i) => {
|
|
21
33
|
const path = app.basename(file, app.path.routes);
|
|
22
|
-
return
|
|
23
|
-
|
|
34
|
+
return is_hook_file(path)
|
|
35
|
+
? `router.addHook("${path}", route${i});
|
|
36
|
+
routes.push(["${path}", route${i}]);
|
|
37
|
+
`
|
|
38
|
+
: `for (const [method, { handler, options }] of Object.entries(route${i})) {
|
|
39
|
+
router.add("${path}", method, handler, options);
|
|
40
|
+
}
|
|
41
|
+
routes.push(["${path}", route${i}]);`;
|
|
24
42
|
}).join("\n")}
|
|
25
|
-
export default
|
|
43
|
+
export default routes;
|
|
26
44
|
`;
|
|
27
45
|
const watchDirs = (await app.path.routes.dirs({
|
|
28
46
|
recursive: true,
|
|
@@ -38,4 +56,5 @@ export default function plugin_server_virtual_routes(app) {
|
|
|
38
56
|
},
|
|
39
57
|
};
|
|
40
58
|
}
|
|
59
|
+
export default plugin_server_virtual_routes;
|
|
41
60
|
//# sourceMappingURL=virtual-routes.js.map
|
|
@@ -20,13 +20,14 @@ export default function plugin_server_wasm(app) {
|
|
|
20
20
|
});
|
|
21
21
|
build.onLoad({ filter: /.*/, namespace: "wasm-dev" }, async (args) => {
|
|
22
22
|
const wasm_file = app.runpath("wasm", args.path + ".wasm");
|
|
23
|
+
const fs_path = import.meta.resolve("@rcompat/fs");
|
|
23
24
|
return {
|
|
24
25
|
contents: `
|
|
25
|
-
|
|
26
|
+
const { default: fs } = await import("${fs_path}");
|
|
26
27
|
export default await fs.ref("${wasm_file.path}").bytes();
|
|
27
28
|
`,
|
|
28
29
|
loader: "js",
|
|
29
|
-
resolveDir:
|
|
30
|
+
resolveDir: new URL(".", import.meta.url).pathname,
|
|
30
31
|
};
|
|
31
32
|
});
|
|
32
33
|
},
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import runtime from "@rcompat/runtime";
|
|
2
|
+
function is_bare(path) {
|
|
3
|
+
return /^[a-z]/.test(path);
|
|
4
|
+
}
|
|
5
|
+
function is_npm_package(path, resolve_dir) {
|
|
6
|
+
if (!path.startsWith("@"))
|
|
7
|
+
return false;
|
|
8
|
+
const parts = path.split("/");
|
|
9
|
+
if (parts.length < 2)
|
|
10
|
+
return false;
|
|
11
|
+
const pkg = parts[0] + "/" + parts[1];
|
|
12
|
+
try {
|
|
13
|
+
runtime.resolve(pkg, resolve_dir);
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export default function intercept(args, views) {
|
|
21
|
+
if (!args.resolveDir.startsWith(views.path))
|
|
22
|
+
return true;
|
|
23
|
+
if (is_bare(args.path))
|
|
24
|
+
return true;
|
|
25
|
+
if (is_npm_package(args.path, args.resolveDir))
|
|
26
|
+
return true;
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=intercept.js.map
|
|
@@ -2,7 +2,7 @@ import navigate from "#client/navigate";
|
|
|
2
2
|
import root from "#client/root";
|
|
3
3
|
import storage from "#client/storage";
|
|
4
4
|
import submit from "#client/submit";
|
|
5
|
-
import
|
|
5
|
+
import http from "@rcompat/http";
|
|
6
6
|
export default (u) => {
|
|
7
7
|
root.set(u);
|
|
8
8
|
const { location, history } = globalThis;
|
|
@@ -50,7 +50,7 @@ export default (u) => {
|
|
|
50
50
|
const action = target.action ?? location.pathname;
|
|
51
51
|
const url = new URL(action);
|
|
52
52
|
const data = new FormData(target);
|
|
53
|
-
const form = enctype === MIME.MULTIPART_FORM_DATA
|
|
53
|
+
const form = enctype === http.MIME.MULTIPART_FORM_DATA
|
|
54
54
|
? data
|
|
55
55
|
: new URLSearchParams(data);
|
|
56
56
|
try {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Dict } from "@rcompat/type";
|
|
2
2
|
type FormId = string;
|
|
3
|
-
type FieldErrors =
|
|
3
|
+
type FieldErrors = string[];
|
|
4
4
|
type FormErrors = {
|
|
5
5
|
form: FieldErrors;
|
|
6
6
|
fields: Dict<FieldErrors>;
|
|
@@ -15,11 +15,21 @@ export type FormView = FormSnapshot & {
|
|
|
15
15
|
submit: (event?: Event) => Promise<void>;
|
|
16
16
|
};
|
|
17
17
|
type FormSubscriber = (snapshot: FormSnapshot) => void;
|
|
18
|
+
export type MethodMeta = {
|
|
19
|
+
contentType?: string;
|
|
20
|
+
};
|
|
21
|
+
export type ClientMethod<Values extends Dict = Dict> = MethodMeta & ((args: {
|
|
22
|
+
body: Values;
|
|
23
|
+
}) => Promise<Response>);
|
|
18
24
|
export type FormInit = {
|
|
19
25
|
id?: string;
|
|
20
26
|
method?: "POST" | "PUT" | "PATCH" | "DELETE";
|
|
21
27
|
url?: string;
|
|
22
28
|
headers?: Dict<string>;
|
|
29
|
+
action?: (args: {
|
|
30
|
+
body: unknown;
|
|
31
|
+
}) => Promise<Response>;
|
|
32
|
+
contentType?: string;
|
|
23
33
|
};
|
|
24
34
|
type FormController = {
|
|
25
35
|
subscribe(fn: FormSubscriber): () => void;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import extract_issues from "#client/extract-issues";
|
|
2
2
|
import submit from "#client/submit";
|
|
3
|
+
import is from "@rcompat/is";
|
|
3
4
|
function decode_pointer_segment(segment) {
|
|
4
5
|
// decode JSON Pointer: ~1 -> /, ~0 -> ~
|
|
5
6
|
return segment.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
@@ -21,6 +22,21 @@ function pointer_to_fieldname(path) {
|
|
|
21
22
|
}
|
|
22
23
|
return name;
|
|
23
24
|
}
|
|
25
|
+
function content_type_body(contentType, form_data) {
|
|
26
|
+
if (contentType === "application/json")
|
|
27
|
+
return Object.fromEntries(form_data);
|
|
28
|
+
if (contentType === "multipart/form-data")
|
|
29
|
+
return form_data;
|
|
30
|
+
// default: application/x-www-form-urlencoded
|
|
31
|
+
return new URLSearchParams(form_data);
|
|
32
|
+
}
|
|
33
|
+
function form_data_body(form_data) {
|
|
34
|
+
for (const value of form_data.values()) {
|
|
35
|
+
if (value instanceof File && value.size > 0)
|
|
36
|
+
return form_data;
|
|
37
|
+
}
|
|
38
|
+
return new URLSearchParams(form_data);
|
|
39
|
+
}
|
|
24
40
|
export default function createForm(init) {
|
|
25
41
|
const id = init.id ?? `form-${crypto.randomUUID()}`;
|
|
26
42
|
let snapshot = {
|
|
@@ -83,7 +99,9 @@ export default function createForm(init) {
|
|
|
83
99
|
const form_data = new FormData(form_element);
|
|
84
100
|
setSubmitting(true);
|
|
85
101
|
try {
|
|
86
|
-
const response = await
|
|
102
|
+
const response = await (is.defined(init.action)
|
|
103
|
+
? init.action({ body: content_type_body(init.contentType, form_data) })
|
|
104
|
+
: submit(url, form_data_body(form_data), method));
|
|
87
105
|
if (response.ok) {
|
|
88
106
|
// on success: clear errors, let the app decide what to do next
|
|
89
107
|
// (redirect/reload)
|
|
@@ -91,8 +109,8 @@ export default function createForm(init) {
|
|
|
91
109
|
publish();
|
|
92
110
|
return;
|
|
93
111
|
}
|
|
94
|
-
|
|
95
|
-
const issues = extract_issues(
|
|
112
|
+
// all issues, all paths
|
|
113
|
+
const issues = extract_issues(await response.json());
|
|
96
114
|
setErrors(issues);
|
|
97
115
|
}
|
|
98
116
|
catch (error) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FormInit, FormView } from "#client/create-form";
|
|
1
|
+
import type { ClientMethod, FormInit, FormView, MethodMeta } from "#client/create-form";
|
|
2
2
|
import createForm from "#client/create-form";
|
|
3
3
|
import type Data from "#client/Data";
|
|
4
4
|
import type Publish from "#client/Publish";
|
|
@@ -19,5 +19,5 @@ declare const client: {
|
|
|
19
19
|
toValidated: typeof toValidated;
|
|
20
20
|
};
|
|
21
21
|
export default client;
|
|
22
|
-
export type { Data, FormInit, FormView, Publish, Render, ValidateInit, ValidateUpdater, ValidationError, ViewResponse
|
|
22
|
+
export type { ClientMethod, Data, FormInit, FormView, MethodMeta, Publish, Render, ValidateInit, ValidateUpdater, ValidationError, ViewResponse };
|
|
23
23
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import http from "#client/http";
|
|
2
1
|
import root from "#client/root";
|
|
3
2
|
import storage from "#client/storage";
|
|
4
|
-
import
|
|
3
|
+
import transport from "#client/transport";
|
|
4
|
+
import http from "@rcompat/http";
|
|
5
5
|
const headers = {
|
|
6
|
-
Accept: MIME.APPLICATION_JSON,
|
|
6
|
+
Accept: http.MIME.APPLICATION_JSON,
|
|
7
7
|
};
|
|
8
8
|
const get_by_id_or_name = (name) => document.getElementById(name) ?? document.getElementsByName(name)[0];
|
|
9
9
|
const scroll_hash = (hash) => {
|
|
@@ -18,13 +18,14 @@ async function goto(target, state = false, after) {
|
|
|
18
18
|
try {
|
|
19
19
|
const { scrollTop } = globalThis.document.scrollingElement;
|
|
20
20
|
const { location } = globalThis;
|
|
21
|
-
const
|
|
22
|
-
|
|
21
|
+
const path = target.pathname + target.search;
|
|
22
|
+
const { requested, response } = await transport.refetch(path, { headers });
|
|
23
|
+
if (transport.is_json(response)) {
|
|
23
24
|
if (response.ok)
|
|
24
25
|
root.update(await response.json());
|
|
25
26
|
if (state) {
|
|
26
27
|
storage.new({ hash: location.hash, pathname: location.pathname, scrollTop });
|
|
27
|
-
history.pushState({}, "", `${
|
|
28
|
+
history.pushState({}, "", `${path}${target.hash}`);
|
|
28
29
|
}
|
|
29
30
|
after?.();
|
|
30
31
|
return;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import http from "#client/http";
|
|
2
1
|
import root from "#client/root";
|
|
3
2
|
import storage from "#client/storage";
|
|
4
|
-
import
|
|
3
|
+
import transport from "#client/transport";
|
|
4
|
+
import http from "@rcompat/http";
|
|
5
5
|
const headers = {
|
|
6
|
-
Accept: MIME.APPLICATION_JSON,
|
|
6
|
+
Accept: http.MIME.APPLICATION_JSON,
|
|
7
7
|
};
|
|
8
|
-
|
|
9
|
-
const { requested, response } = await
|
|
8
|
+
async function submit(pathname, body, method) {
|
|
9
|
+
const { requested, response } = await transport.refetch(pathname, {
|
|
10
10
|
body, headers, method,
|
|
11
11
|
});
|
|
12
12
|
if (response.redirected) {
|
|
13
13
|
const { location, document, history } = globalThis;
|
|
14
14
|
const scrollTop = document.scrollingElement?.scrollTop ?? 0;
|
|
15
|
-
if (
|
|
15
|
+
if (transport.is_json(response))
|
|
16
16
|
root.update(await response.json());
|
|
17
17
|
storage.new({
|
|
18
18
|
hash: location.hash,
|
|
@@ -23,7 +23,7 @@ export default async function submit(pathname, body, method) {
|
|
|
23
23
|
history.pushState({}, "", url.pathname + url.search);
|
|
24
24
|
return response;
|
|
25
25
|
}
|
|
26
|
-
if (
|
|
26
|
+
if (transport.is_json(response)) {
|
|
27
27
|
if (response.ok) {
|
|
28
28
|
root.update(await response.json());
|
|
29
29
|
history.replaceState({}, "", requested.pathname + requested.search);
|
|
@@ -38,4 +38,5 @@ export default async function submit(pathname, body, method) {
|
|
|
38
38
|
globalThis.location.assign(target);
|
|
39
39
|
return response;
|
|
40
40
|
}
|
|
41
|
+
export default submit;
|
|
41
42
|
//# sourceMappingURL=submit.js.map
|
|
@@ -4,10 +4,10 @@ declare function refetch(input: string | URL, init?: RequestInit, max_hops?: num
|
|
|
4
4
|
}>;
|
|
5
5
|
declare function is_json(response: Response): boolean;
|
|
6
6
|
declare function submit(pathname: string, body: any, method: string): Promise<Response>;
|
|
7
|
-
declare const
|
|
7
|
+
declare const transport: {
|
|
8
8
|
refetch: typeof refetch;
|
|
9
9
|
is_json: typeof is_json;
|
|
10
10
|
submit: typeof submit;
|
|
11
11
|
};
|
|
12
|
-
export default
|
|
13
|
-
//# sourceMappingURL=
|
|
12
|
+
export default transport;
|
|
13
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import http from "@rcompat/http";
|
|
2
2
|
const sameorigin = (url) => url.origin === globalThis.location.origin;
|
|
3
3
|
const get_location = (response, base) => {
|
|
4
4
|
if (response.type === "opaqueredirect")
|
|
@@ -7,6 +7,8 @@ const get_location = (response, base) => {
|
|
|
7
7
|
return location !== null ? new URL(location, base) : null;
|
|
8
8
|
};
|
|
9
9
|
async function refetch(input, init = {}, max_hops = 5) {
|
|
10
|
+
console.log("location.href", globalThis.location.href);
|
|
11
|
+
console.log("input", input.toString());
|
|
10
12
|
let url = new URL(input.toString(), globalThis.location.href);
|
|
11
13
|
const method = (init.method ?? "GET").toUpperCase();
|
|
12
14
|
let hops = 0;
|
|
@@ -36,7 +38,7 @@ async function refetch(input, init = {}, max_hops = 5) {
|
|
|
36
38
|
}
|
|
37
39
|
function is_json(response) {
|
|
38
40
|
const raw = response.headers.get("content-type") ?? "";
|
|
39
|
-
return raw.split(";")[0].trim() === MIME.APPLICATION_JSON;
|
|
41
|
+
return raw.split(";")[0].trim() === http.MIME.APPLICATION_JSON;
|
|
40
42
|
}
|
|
41
43
|
async function submit(pathname, body, method) {
|
|
42
44
|
const { requested, response } = await refetch(pathname, { body, method });
|
|
@@ -48,10 +50,6 @@ async function submit(pathname, body, method) {
|
|
|
48
50
|
}
|
|
49
51
|
return response;
|
|
50
52
|
}
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
submit,
|
|
55
|
-
};
|
|
56
|
-
export default http;
|
|
57
|
-
//# sourceMappingURL=http.js.map
|
|
53
|
+
const transport = { refetch, is_json, submit };
|
|
54
|
+
export default transport;
|
|
55
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -3,6 +3,7 @@ import type Module from "#Module";
|
|
|
3
3
|
import type { Dict } from "@rcompat/type";
|
|
4
4
|
import type { ObjectType, Parsed } from "pema";
|
|
5
5
|
declare const _default: ObjectType<import("pema").NormalizeSchemaObject<{
|
|
6
|
+
readonly conditions: import("pema").DefaultType<import("pema").ArrayType<import("pema").StringType>, string[]>;
|
|
6
7
|
readonly http: {
|
|
7
8
|
readonly csp: import("pema").OptionalType<import("pema").RecordType<import("pema").StringType, import("pema").ArrayType<import("pema").StringType>>>;
|
|
8
9
|
readonly headers: import("pema").OptionalType<import("pema").RecordType<import("pema").StringType, import("pema").StringType>>;
|
|
@@ -24,10 +25,10 @@ declare const _default: ObjectType<import("pema").NormalizeSchemaObject<{
|
|
|
24
25
|
readonly db: {
|
|
25
26
|
readonly migrations: import("pema").OptionalType<ObjectType<{
|
|
26
27
|
table: import("pema").StringType;
|
|
27
|
-
db: import("pema").PureType<DB
|
|
28
|
+
db: import("pema").PureType<DB<unknown>, "PureType">;
|
|
28
29
|
}, {
|
|
29
30
|
table: string;
|
|
30
|
-
db: DB
|
|
31
|
+
db: DB<unknown>;
|
|
31
32
|
}>>;
|
|
32
33
|
};
|
|
33
34
|
readonly env: {
|
|
@@ -39,12 +40,8 @@ declare const _default: ObjectType<import("pema").NormalizeSchemaObject<{
|
|
|
39
40
|
name: import("pema").StringType;
|
|
40
41
|
setup: import("pema").FunctionType;
|
|
41
42
|
}, Module>>, Module[]>;
|
|
42
|
-
readonly request: {
|
|
43
|
-
readonly body: {
|
|
44
|
-
readonly parse: import("pema").DefaultType<import("pema").BooleanType, true>;
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
43
|
}>, {
|
|
44
|
+
conditions: string[];
|
|
48
45
|
http: {
|
|
49
46
|
csp: Record<string, string[]> | undefined;
|
|
50
47
|
headers: Record<string, string> | undefined;
|
|
@@ -66,7 +63,7 @@ declare const _default: ObjectType<import("pema").NormalizeSchemaObject<{
|
|
|
66
63
|
db: {
|
|
67
64
|
migrations: {
|
|
68
65
|
table: string;
|
|
69
|
-
db: DB
|
|
66
|
+
db: DB<unknown>;
|
|
70
67
|
} | undefined;
|
|
71
68
|
};
|
|
72
69
|
env: {
|
|
@@ -75,11 +72,6 @@ declare const _default: ObjectType<import("pema").NormalizeSchemaObject<{
|
|
|
75
72
|
}> | undefined;
|
|
76
73
|
};
|
|
77
74
|
modules: Module[];
|
|
78
|
-
request: {
|
|
79
|
-
body: {
|
|
80
|
-
parse: boolean;
|
|
81
|
-
};
|
|
82
|
-
};
|
|
83
75
|
}>;
|
|
84
76
|
export default _default;
|
|
85
77
|
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "@rcompat/fs";
|
|
2
2
|
import p from "pema";
|
|
3
3
|
export default p({
|
|
4
|
+
conditions: p.array(p.string).unique().default([]),
|
|
4
5
|
http: {
|
|
5
6
|
csp: p.dict(p.array(p.string)).optional(),
|
|
6
7
|
headers: p.dict().optional(),
|
|
@@ -34,10 +35,5 @@ export default p({
|
|
|
34
35
|
}).shape())
|
|
35
36
|
.uniqueBy(member => member.name)
|
|
36
37
|
.default([]),
|
|
37
|
-
request: {
|
|
38
|
-
body: {
|
|
39
|
-
parse: p.boolean.default(true),
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
38
|
});
|
|
43
39
|
//# sourceMappingURL=schema.js.map
|
package/lib/private/db/DB.d.ts
CHANGED
|
@@ -21,9 +21,10 @@ export type Schema = {
|
|
|
21
21
|
introspect(name: string, pk?: PK): MaybePromise<MaybeTable>;
|
|
22
22
|
alter(name: string, diff: SchemaDiff): MaybePromise<void>;
|
|
23
23
|
};
|
|
24
|
-
export default interface DB {
|
|
24
|
+
export default interface DB<Client = unknown> {
|
|
25
25
|
schema: Schema;
|
|
26
26
|
close(): MaybePromise<void>;
|
|
27
|
+
readonly client: Client;
|
|
27
28
|
create<O extends Dict>(as: As, record: Dict): MaybePromise<O>;
|
|
28
29
|
read(as: As, args: {
|
|
29
30
|
count: true;
|
|
@@ -34,6 +35,7 @@ export default interface DB {
|
|
|
34
35
|
where: Dict;
|
|
35
36
|
fields?: string[];
|
|
36
37
|
limit?: number;
|
|
38
|
+
offset?: number;
|
|
37
39
|
sort?: Sort;
|
|
38
40
|
with?: With;
|
|
39
41
|
}): MaybePromise<Dict[]>;
|
|
@@ -4,9 +4,11 @@ import type { Schema } from "#db/DB";
|
|
|
4
4
|
import type DataDict from "#db/DataDict";
|
|
5
5
|
import type Sort from "#db/Sort";
|
|
6
6
|
import type With from "#db/With";
|
|
7
|
-
import type { Dict, MaybePromise } from "@rcompat/type";
|
|
8
|
-
|
|
7
|
+
import type { Dict, MaybePromise, PartialDict } from "@rcompat/type";
|
|
8
|
+
type Tables = PartialDict<Dict[]>;
|
|
9
|
+
export default class MemoryDB implements DB<Tables> {
|
|
9
10
|
#private;
|
|
11
|
+
get client(): Tables;
|
|
10
12
|
get schema(): Schema;
|
|
11
13
|
close(): void;
|
|
12
14
|
create<O extends Dict>(as: As, record: Dict): MaybePromise<O>;
|
|
@@ -30,4 +32,5 @@ export default class MemoryDB implements DB {
|
|
|
30
32
|
where: DataDict;
|
|
31
33
|
}): number;
|
|
32
34
|
}
|
|
35
|
+
export {};
|
|
33
36
|
//# sourceMappingURL=MemoryDB.d.ts.map
|