@sveltejs/kit 1.3.5 → 1.3.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.3.5",
3
+ "version": "1.3.6",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -127,8 +127,19 @@ function build_selector(resource, opts) {
127
127
 
128
128
  let selector = `script[data-sveltekit-fetched][data-url=${url}]`;
129
129
 
130
- if (opts?.body && (typeof opts.body === 'string' || ArrayBuffer.isView(opts.body))) {
131
- selector += `[data-hash="${hash(opts.body)}"]`;
130
+ if (opts?.headers || opts?.body) {
131
+ /** @type {import('types').StrictBody[]} */
132
+ const values = [];
133
+
134
+ if (opts.headers) {
135
+ values.push([...new Headers(opts.headers)].join(','));
136
+ }
137
+
138
+ if (opts.body && (typeof opts.body === 'string' || ArrayBuffer.isView(opts.body))) {
139
+ values.push(opts.body);
140
+ }
141
+
142
+ selector += `[data-hash="${hash(...values)}"]`;
132
143
  }
133
144
 
134
145
  return selector;
@@ -1,19 +1,21 @@
1
1
  /**
2
2
  * Hash using djb2
3
- * @param {import('types').StrictBody} value
3
+ * @param {import('types').StrictBody[]} values
4
4
  */
5
- export function hash(value) {
5
+ export function hash(...values) {
6
6
  let hash = 5381;
7
7
 
8
- if (typeof value === 'string') {
9
- let i = value.length;
10
- while (i) hash = (hash * 33) ^ value.charCodeAt(--i);
11
- } else if (ArrayBuffer.isView(value)) {
12
- const buffer = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
13
- let i = buffer.length;
14
- while (i) hash = (hash * 33) ^ buffer[--i];
15
- } else {
16
- throw new TypeError('value must be a string or TypedArray');
8
+ for (const value of values) {
9
+ if (typeof value === 'string') {
10
+ let i = value.length;
11
+ while (i) hash = (hash * 33) ^ value.charCodeAt(--i);
12
+ } else if (ArrayBuffer.isView(value)) {
13
+ const buffer = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
14
+ let i = buffer.length;
15
+ while (i) hash = (hash * 33) ^ buffer[--i];
16
+ } else {
17
+ throw new TypeError('value must be a string or TypedArray');
18
+ }
17
19
  }
18
20
 
19
21
  return (hash >>> 0).toString(36);
@@ -194,6 +194,7 @@ export function create_universal_fetch(event, state, fetched, csr, resolve_opts)
194
194
  ? await stream_to_string(cloned_body)
195
195
  : init?.body
196
196
  ),
197
+ request_headers: init?.headers,
197
198
  response_body: body,
198
199
  response: response
199
200
  });
@@ -73,8 +73,19 @@ export function serialize_data(fetched, filter, prerendering = false) {
73
73
  `data-url=${escape_html_attr(fetched.url)}`
74
74
  ];
75
75
 
76
- if (fetched.request_body) {
77
- attrs.push(`data-hash=${escape_html_attr(hash(fetched.request_body))}`);
76
+ if (fetched.request_headers || fetched.request_body) {
77
+ /** @type {import('types').StrictBody[]} */
78
+ const values = [];
79
+
80
+ if (fetched.request_headers) {
81
+ values.push([...new Headers(fetched.request_headers)].join(','));
82
+ }
83
+
84
+ if (fetched.request_body) {
85
+ values.push(fetched.request_body);
86
+ }
87
+
88
+ attrs.push(`data-hash="${hash(...values)}"`);
78
89
  }
79
90
 
80
91
  // Compute the time the response should be cached, taking into account max-age and age.
@@ -5,6 +5,7 @@ export interface Fetched {
5
5
  url: string;
6
6
  method: string;
7
7
  request_body?: string | ArrayBufferView | null;
8
+ request_headers?: HeadersInit | undefined;
8
9
  response_body: string;
9
10
  response: Response;
10
11
  }
@@ -126,57 +126,44 @@ export function exec(match, params, matchers) {
126
126
 
127
127
  const values = match.slice(1);
128
128
 
129
- let buffered = '';
129
+ let buffered = 0;
130
130
 
131
131
  for (let i = 0; i < params.length; i += 1) {
132
132
  const param = params[i];
133
- let value = values[i];
133
+ const value = values[i - buffered];
134
134
 
135
+ // in the `[[a=b]]/.../[...rest]` case, if one or more optional parameters
136
+ // weren't matched, roll the skipped values into the rest
135
137
  if (param.chained && param.rest && buffered) {
136
- // in the `[[lang=lang]]/[...rest]` case, if `lang` didn't
137
- // match, we roll it over into the rest value
138
- value = value ? buffered + '/' + value : buffered;
139
- }
138
+ result[param.name] = values
139
+ .slice(i - buffered, i + 1)
140
+ .filter((s) => s)
141
+ .join('/');
140
142
 
141
- buffered = '';
143
+ buffered = 0;
144
+ continue;
145
+ }
142
146
 
147
+ // if `value` is undefined, it means this is an optional or rest parameter
143
148
  if (value === undefined) {
144
- // if `value` is undefined, it means this is
145
- // an optional or rest parameter
146
149
  if (param.rest) result[param.name] = '';
147
- } else {
148
- if (param.matcher && !matchers[param.matcher](value)) {
149
- // in the `/[[a=b]]/[[c=d]]` case, if the value didn't satisfy the `b` matcher,
150
- // try again with the next segment by shifting values rightwards
151
- if (param.optional && param.chained) {
152
- // @ts-expect-error TypeScript is... wrong
153
- let j = values.indexOf(undefined, i);
154
-
155
- if (j === -1) {
156
- // we can't shift values any further, so hang on to this value
157
- // so it can be rolled into a subsequent `[...rest]` param
158
- const next = params[i + 1];
159
- if (next?.rest && next.chained) {
160
- buffered = value;
161
- } else {
162
- return;
163
- }
164
- }
165
-
166
- while (j >= i) {
167
- values[j] = values[j - 1];
168
- j -= 1;
169
- }
170
-
171
- continue;
172
- }
173
-
174
- // otherwise, if the matcher returns `false`, the route did not match
175
- return;
176
- }
150
+ continue;
151
+ }
177
152
 
153
+ if (!param.matcher || matchers[param.matcher](value)) {
178
154
  result[param.name] = value;
155
+ continue;
179
156
  }
157
+
158
+ // in the `/[[a=b]]/...` case, if the value didn't satisfy the matcher,
159
+ // keep track of the number of skipped optional parameters and continue
160
+ if (param.optional && param.chained) {
161
+ buffered++;
162
+ continue;
163
+ }
164
+
165
+ // otherwise, if the matcher returns `false`, the route did not match
166
+ return;
180
167
  }
181
168
 
182
169
  if (buffered) return;