@primate/core 0.8.1 → 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.
@@ -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)
@@ -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
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primate/core",
3
- "version": "0.8.1",
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",