@primate/core 0.8.0 → 0.8.2

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.
@@ -7,7 +7,7 @@ export default function plugin_client_routes(app) {
7
7
  build.onResolve({ filter: /.*/ }, async (args) => {
8
8
  if (args.pluginData === "primate-client-route-inner")
9
9
  return null;
10
- if (intercept(args, app.path.views))
10
+ if (intercept(args, app.root))
11
11
  return null;
12
12
  const result = await build.resolve(args.path, {
13
13
  resolveDir: args.resolveDir,
@@ -1,4 +1,4 @@
1
1
  import type { FileRef } from "@rcompat/fs";
2
2
  import type { OnResolveArgs } from "esbuild";
3
- export default function intercept(args: OnResolveArgs, views: FileRef): boolean;
3
+ export default function intercept(args: OnResolveArgs, root: FileRef): boolean;
4
4
  //# sourceMappingURL=intercept.d.ts.map
@@ -17,8 +17,10 @@ function is_npm_package(path, resolve_dir) {
17
17
  return false;
18
18
  }
19
19
  }
20
- export default function intercept(args, views) {
21
- if (!args.resolveDir.startsWith(views.path))
20
+ export default function intercept(args, root) {
21
+ if (!args.resolveDir.startsWith(root.path))
22
+ return true;
23
+ if (args.resolveDir.includes("node_modules"))
22
24
  return true;
23
25
  if (is_bare(args.path))
24
26
  return true;
@@ -22,6 +22,7 @@ export type MethodMeta = {
22
22
  export type ClientMethod<Values extends Dict = Dict, Path extends Dict = Dict, Result = unknown> = MethodMeta & ((args: {
23
23
  body: Values;
24
24
  path: Path;
25
+ headers?: HeadersInit;
25
26
  }) => Promise<Response>);
26
27
  export type FormInit = {
27
28
  id?: string;
@@ -31,6 +32,7 @@ export type FormInit = {
31
32
  action?: (args: {
32
33
  body: unknown;
33
34
  path?: Dict<string>;
35
+ headers?: HeadersInit;
34
36
  }) => Promise<Response>;
35
37
  contentType?: string;
36
38
  path?: Dict<string>;
@@ -1,5 +1,9 @@
1
1
  import extract_issues from "#client/extract-issues";
2
+ import root from "#client/root";
3
+ import storage from "#client/storage";
2
4
  import submit from "#client/submit";
5
+ import transport from "#client/transport";
6
+ import http from "@rcompat/http";
3
7
  import is from "@rcompat/is";
4
8
  function decode_pointer_segment(segment) {
5
9
  // decode JSON Pointer: ~1 -> /, ~0 -> ~
@@ -37,6 +41,25 @@ function form_data_body(form_data) {
37
41
  }
38
42
  return new URLSearchParams(form_data);
39
43
  }
44
+ async function redirect(response) {
45
+ if (!response.redirected)
46
+ return false;
47
+ if (!transport.is_json(response)) {
48
+ globalThis.location.assign(response.url);
49
+ return true;
50
+ }
51
+ const { location, document, history } = globalThis;
52
+ const scrollTop = document.scrollingElement?.scrollTop ?? 0;
53
+ root.update(await response.json());
54
+ storage.new({
55
+ hash: location.hash,
56
+ pathname: location.pathname,
57
+ scrollTop,
58
+ });
59
+ const url = new URL(response.url);
60
+ history.pushState({}, "", url.pathname + url.search);
61
+ return true;
62
+ }
40
63
  function createForm(init) {
41
64
  const id = init.id ?? `form-${crypto.randomUUID()}`;
42
65
  let snapshot = {
@@ -104,8 +127,14 @@ function createForm(init) {
104
127
  ? init.action({
105
128
  body: content_type_body(init.contentType, form_data),
106
129
  path: init.path,
130
+ headers: {
131
+ Accept: http.MIME.APPLICATION_JSON,
132
+ ...(init.headers ?? {}),
133
+ },
107
134
  })
108
135
  : submit(url, form_data_body(form_data), method));
136
+ if (await redirect(response))
137
+ return;
109
138
  if (response.ok) {
110
139
  // on success: clear errors, let the app decide what to do next
111
140
  // (redirect/reload)
@@ -151,7 +151,7 @@ function session_id_string() {
151
151
  return t `session store session_id must be a string type`;
152
152
  }
153
153
  function session_id_data() {
154
- return t `"both ${"id"} and ${"data"} must be defined or undefined`;
154
+ return t `both ${"id"} and ${"data"} must be defined or undefined`;
155
155
  }
156
156
  function session_handle_unavailable() {
157
157
  return t `session handle not available in this context`;
@@ -16,21 +16,24 @@ type Path<O extends RouteOptions> = O extends {
16
16
  type MethodMeta = {
17
17
  contentType?: string;
18
18
  };
19
+ type RequestMeta = {
20
+ headers?: HeadersInit;
21
+ };
19
22
  type ClientMethod<O extends RouteOptions, R = unknown> = MethodMeta & {
20
23
  _result?: R;
21
- } & (Body<O> extends never ? Path<O> extends never ? () => Promise<Response> : (args: {
24
+ } & (Body<O> extends never ? Path<O> extends never ? (args?: RequestMeta) => Promise<Response> : (args: {
22
25
  path: Path<O>;
23
- }) => Promise<Response> : Path<O> extends never ? (args: {
26
+ } & RequestMeta) => Promise<Response> : Path<O> extends never ? (args: {
24
27
  body: Body<O>;
25
- }) => Promise<Response> : (args: {
28
+ } & RequestMeta) => Promise<Response> : (args: {
26
29
  body: Body<O>;
27
30
  path: Path<O>;
28
- }) => Promise<Response>);
31
+ } & RequestMeta) => Promise<Response>);
29
32
  type ClientRoute<R> = {
30
33
  [K in keyof R]: R[K] extends {
31
34
  options: infer O extends RouteOptions;
32
35
  result?: infer Result;
33
- } ? ClientMethod<O, Result> : () => Promise<Response>;
36
+ } ? ClientMethod<O, Result> : (args?: RequestMeta) => Promise<Response>;
34
37
  };
35
38
  type WithResult<O extends RouteOptions, R = unknown> = {
36
39
  handler: RouteHandler<O>;
@@ -38,7 +38,10 @@ function route(handlers) {
38
38
  : path;
39
39
  return fetch(resolved, {
40
40
  method: method.toUpperCase(),
41
- headers: headers(contentType),
41
+ headers: {
42
+ ...headers(contentType),
43
+ ...(args.headers ?? {}),
44
+ },
42
45
  body: serialize_body(contentType, args.body),
43
46
  });
44
47
  };
@@ -53,7 +53,7 @@ export default function session_module(config) {
53
53
  db_id = _id;
54
54
  }
55
55
  const session_type = p.omit(store.schema, "id", "session_id");
56
- const session = new SessionHandle(sid, data, session_type);
56
+ const session = new SessionHandle(exists ? sid : undefined, data, session_type);
57
57
  const response = await new Promise((resolve, reject) => {
58
58
  storage().run(session, async () => {
59
59
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primate/core",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "The universal web framework",
5
5
  "homepage": "https://primate.run",
6
6
  "bugs": "https://github.com/primate-run/primate/issues",