@sveltejs/kit 1.0.0-next.430 → 1.0.0-next.433

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.
@@ -10,6 +10,7 @@ import { negotiate } from '../../utils/http.js';
10
10
  import { HttpError, Redirect } from '../../index/private.js';
11
11
  import { load_server_data } from './page/load_data.js';
12
12
  import { json } from '../../index/index.js';
13
+ import { once } from '../../utils/functions.js';
13
14
 
14
15
  /* global __SVELTEKIT_ADAPTER_NAME__ */
15
16
 
@@ -92,7 +93,7 @@ export async function respond(request, options, state) {
92
93
  }
93
94
 
94
95
  if (route) {
95
- if (route.type === 'page') {
96
+ if (route.page) {
96
97
  const normalized = normalize_path(url.pathname, options.trailing_slash);
97
98
 
98
99
  if (normalized !== url.pathname && !state.prerendering?.fallback) {
@@ -252,21 +253,28 @@ export async function respond(request, options, state) {
252
253
  if (route) {
253
254
  /** @type {Response} */
254
255
  let response;
255
- if (is_data_request && route.type === 'page') {
256
+ if (is_data_request && route.page) {
256
257
  try {
257
- /** @type {Redirect | HttpError | Error} */
258
- let error;
259
-
260
- // TODO only get the data we need for the navigation
261
- const promises = [...route.layouts, route.leaf].map(async (n, i) => {
262
- try {
263
- if (error) return;
264
-
265
- // == because it could be undefined (in dev) or null (in build, because of JSON.stringify)
266
- const node = n == undefined ? n : await options.manifest._.nodes[n]();
267
- return {
268
- // TODO return `uses`, so we can reuse server data effectively
269
- data: await load_server_data({
258
+ const node_ids = [...route.page.layouts, route.page.leaf];
259
+
260
+ const invalidated =
261
+ request.headers.get('x-sveltekit-invalidated')?.split(',').map(Boolean) ??
262
+ node_ids.map(() => true);
263
+
264
+ let aborted = false;
265
+
266
+ const functions = node_ids.map((n, i) => {
267
+ return once(async () => {
268
+ try {
269
+ if (aborted) {
270
+ return /** @type {import('types').ServerDataSkippedNode} */ ({
271
+ type: 'skip'
272
+ });
273
+ }
274
+
275
+ // == because it could be undefined (in dev) or null (in build, because of JSON.stringify)
276
+ const node = n == undefined ? n : await options.manifest._.nodes[n]();
277
+ return load_server_data({
270
278
  dev: options.dev,
271
279
  event,
272
280
  node,
@@ -274,56 +282,91 @@ export async function respond(request, options, state) {
274
282
  /** @type {Record<string, any>} */
275
283
  const data = {};
276
284
  for (let j = 0; j < i; j += 1) {
277
- const parent = await promises[j];
278
- if (!parent || parent instanceof HttpError || 'error' in parent) {
279
- return data;
280
- }
285
+ const parent = /** @type {import('types').ServerDataNode} */ (
286
+ await functions[j]()
287
+ );
281
288
  Object.assign(data, parent.data);
282
289
  }
283
290
  return data;
284
291
  }
285
- })
286
- };
287
- } catch (e) {
288
- error = normalize_error(e);
289
-
290
- if (error instanceof Redirect) {
291
- throw error;
292
- }
293
-
294
- if (error instanceof HttpError) {
295
- return error; // { status, message }
292
+ });
293
+ } catch (e) {
294
+ aborted = true;
295
+ throw e;
296
296
  }
297
+ });
298
+ });
297
299
 
298
- options.handle_error(error, event);
299
-
300
- return {
301
- error: error_to_pojo(error, options.get_stack)
302
- };
300
+ const promises = functions.map(async (fn, i) => {
301
+ if (!invalidated[i]) {
302
+ return /** @type {import('types').ServerDataSkippedNode} */ ({
303
+ type: 'skip'
304
+ });
303
305
  }
306
+
307
+ return fn();
304
308
  });
305
309
 
306
- response = json({
310
+ let length = promises.length;
311
+ const nodes = await Promise.all(
312
+ promises.map((p, i) =>
313
+ p.catch((e) => {
314
+ const error = normalize_error(e);
315
+
316
+ if (error instanceof Redirect) {
317
+ throw error;
318
+ }
319
+
320
+ // Math.min because array isn't guaranteed to resolve in order
321
+ length = Math.min(length, i + 1);
322
+
323
+ if (error instanceof HttpError) {
324
+ return /** @type {import('types').ServerErrorNode} */ ({
325
+ type: 'error',
326
+ httperror: { ...error }
327
+ });
328
+ }
329
+
330
+ options.handle_error(error, event);
331
+
332
+ return /** @type {import('types').ServerErrorNode} */ ({
333
+ type: 'error',
334
+ error: error_to_pojo(error, options.get_stack)
335
+ });
336
+ })
337
+ )
338
+ );
339
+
340
+ /** @type {import('types').ServerData} */
341
+ const server_data = {
307
342
  type: 'data',
308
- nodes: await Promise.all(promises)
309
- });
343
+ nodes: nodes.slice(0, length)
344
+ };
345
+
346
+ response = json(server_data);
310
347
  } catch (e) {
311
348
  const error = normalize_error(e);
312
349
 
313
350
  if (error instanceof Redirect) {
314
- response = json({
351
+ /** @type {import('types').ServerData} */
352
+ const server_data = {
315
353
  type: 'redirect',
316
354
  location: error.location
317
- });
355
+ };
356
+
357
+ response = json(server_data);
318
358
  } else {
319
359
  response = json(error_to_pojo(error, options.get_stack), { status: 500 });
320
360
  }
321
361
  }
362
+ } else if (route.page) {
363
+ response = await render_page(event, route, route.page, options, state, resolve_opts);
364
+ } else if (route.endpoint) {
365
+ response = await render_endpoint(event, await route.endpoint());
322
366
  } else {
323
- response =
324
- route.type === 'endpoint'
325
- ? await render_endpoint(event, route)
326
- : await render_page(event, route, options, state, resolve_opts);
367
+ // a route will always have a page or an endpoint, but TypeScript
368
+ // doesn't know that
369
+ throw new Error('This should never happen');
327
370
  }
328
371
 
329
372
  if (!is_data_request) {
@@ -9,7 +9,7 @@ import { domain_matches, path_matches } from './cookie.js';
9
9
  * event: import('types').RequestEvent;
10
10
  * options: import('types').SSROptions;
11
11
  * state: import('types').SSRState;
12
- * route: import('types').SSRPage | import('types').SSRErrorPage;
12
+ * route: import('types').SSRRoute | import('types').SSRErrorPage;
13
13
  * }} opts
14
14
  */
15
15
  export function create_fetch({ event, options, state, route }) {
@@ -5,6 +5,7 @@ import { method_not_allowed, error_to_pojo, allowed_methods } from '../utils.js'
5
5
  import { create_fetch } from './fetch.js';
6
6
  import { HttpError, Redirect } from '../../../index/private.js';
7
7
  import { error, json } from '../../../index/index.js';
8
+ import { compact } from '../../../utils/array.js';
8
9
  import { normalize_error } from '../../../utils/error.js';
9
10
  import { load_data, load_server_data } from './load_data.js';
10
11
 
@@ -17,13 +18,14 @@ import { load_data, load_server_data } from './load_data.js';
17
18
 
18
19
  /**
19
20
  * @param {import('types').RequestEvent} event
20
- * @param {import('types').SSRPage} route
21
+ * @param {import('types').SSRRoute} route
22
+ * @param {import('types').PageNodeIndexes} page
21
23
  * @param {import('types').SSROptions} options
22
24
  * @param {import('types').SSRState} state
23
25
  * @param {import('types').RequiredResolveOptions} resolve_opts
24
26
  * @returns {Promise<Response>}
25
27
  */
26
- export async function render_page(event, route, options, state, resolve_opts) {
28
+ export async function render_page(event, route, page, options, state, resolve_opts) {
27
29
  if (state.initiator === route) {
28
30
  // infinite request cycle detected
29
31
  return new Response(`Not found: ${event.url.pathname}`, {
@@ -41,7 +43,7 @@ export async function render_page(event, route, options, state, resolve_opts) {
41
43
  event.request.method !== 'GET' &&
42
44
  event.request.method !== 'HEAD'
43
45
  ) {
44
- const node = await options.manifest._.nodes[route.leaf]();
46
+ const node = await options.manifest._.nodes[page.leaf]();
45
47
  if (node.server) {
46
48
  return handle_json_request(event, options, node.server);
47
49
  }
@@ -52,8 +54,8 @@ export async function render_page(event, route, options, state, resolve_opts) {
52
54
  try {
53
55
  const nodes = await Promise.all([
54
56
  // we use == here rather than === because [undefined] serializes as "[null]"
55
- ...route.layouts.map((n) => (n == undefined ? n : options.manifest._.nodes[n]())),
56
- options.manifest._.nodes[route.leaf]()
57
+ ...page.layouts.map((n) => (n == undefined ? n : options.manifest._.nodes[n]())),
58
+ options.manifest._.nodes[page.leaf]()
57
59
  ]);
58
60
 
59
61
  const leaf_node = /** @type {import('types').SSRNode} */ (nodes.at(-1));
@@ -145,7 +147,7 @@ export async function render_page(event, route, options, state, resolve_opts) {
145
147
  /** @type {Error | null} */
146
148
  let load_error = null;
147
149
 
148
- /** @type {Array<Promise<Record<string, any> | null>>} */
150
+ /** @type {Array<Promise<import('types').ServerDataNode | null>>} */
149
151
  const server_promises = nodes.map((node, i) => {
150
152
  if (load_error) {
151
153
  // if an error happens immediately, don't bother with the rest of the nodes
@@ -168,7 +170,8 @@ export async function render_page(event, route, options, state, resolve_opts) {
168
170
  /** @type {Record<string, any>} */
169
171
  const data = {};
170
172
  for (let j = 0; j < i; j += 1) {
171
- Object.assign(data, await server_promises[j]);
173
+ const parent = await server_promises[j];
174
+ if (parent) Object.assign(data, await parent.data);
172
175
  }
173
176
  return data;
174
177
  }
@@ -243,8 +246,8 @@ export async function render_page(event, route, options, state, resolve_opts) {
243
246
  const status = error instanceof HttpError ? error.status : 500;
244
247
 
245
248
  while (i--) {
246
- if (route.errors[i]) {
247
- const index = /** @type {number} */ (route.errors[i]);
249
+ if (page.errors[i]) {
250
+ const index = /** @type {number} */ (page.errors[i]);
248
251
  const node = await options.manifest._.nodes[index]();
249
252
 
250
253
  let j = i;
@@ -291,7 +294,7 @@ export async function render_page(event, route, options, state, resolve_opts) {
291
294
  response: new Response(undefined),
292
295
  body: JSON.stringify({
293
296
  type: 'data',
294
- nodes: branch.map((branch_node) => ({ data: branch_node?.server_data }))
297
+ nodes: branch.map((branch_node) => branch_node?.server_data)
295
298
  })
296
299
  });
297
300
  }
@@ -399,18 +402,3 @@ function redirect_response(status, location) {
399
402
  headers: { location }
400
403
  });
401
404
  }
402
-
403
- /**
404
- * @template T
405
- * @param {Array<T | null>} array
406
- * @returns {T[]}
407
- */
408
- function compact(array) {
409
- const compacted = [];
410
- for (const item of array) {
411
- if (item) {
412
- compacted.push(item);
413
- }
414
- }
415
- return compacted;
416
- }
@@ -8,19 +8,46 @@ import { LoadURL, PrerenderingURL } from '../../../utils/url.js';
8
8
  * node: import('types').SSRNode | undefined;
9
9
  * parent: () => Promise<Record<string, any>>;
10
10
  * }} opts
11
+ * @returns {Promise<import('types').ServerDataNode | null>}
11
12
  */
12
13
  export async function load_server_data({ dev, event, node, parent }) {
13
14
  if (!node?.server) return null;
14
15
 
15
- const server_data = await node.server.load?.call(null, {
16
+ const uses = {
17
+ dependencies: new Set(),
18
+ params: new Set(),
19
+ parent: false,
20
+ url: false
21
+ };
22
+
23
+ /** @param {string[]} deps */
24
+ function depends(...deps) {
25
+ for (const dep of deps) {
26
+ const { href } = new URL(dep, event.url);
27
+ uses.dependencies.add(href);
28
+ }
29
+ }
30
+
31
+ const params = new Proxy(event.params, {
32
+ get: (target, key) => {
33
+ uses.params.add(key);
34
+ return target[/** @type {string} */ (key)];
35
+ }
36
+ });
37
+
38
+ const result = await node.server.load?.call(null, {
16
39
  // can't use destructuring here because it will always
17
40
  // invoke event.clientAddress, which breaks prerendering
18
41
  get clientAddress() {
19
42
  return event.clientAddress;
20
43
  },
44
+ depends,
21
45
  locals: event.locals,
22
- params: event.params,
23
- parent,
46
+ params,
47
+ parent: async () => {
48
+ uses.parent = true;
49
+ return parent();
50
+ },
24
51
  platform: event.platform,
25
52
  request: event.request,
26
53
  routeId: event.routeId,
@@ -28,13 +55,22 @@ export async function load_server_data({ dev, event, node, parent }) {
28
55
  url: event.url
29
56
  });
30
57
 
31
- const result = server_data ? await unwrap_promises(server_data) : null;
58
+ const data = result ? await unwrap_promises(result) : null;
32
59
 
33
60
  if (dev) {
34
- check_serializability(result, /** @type {string} */ (node.server_id), 'data');
61
+ check_serializability(data, /** @type {string} */ (node.server_id), 'data');
35
62
  }
36
63
 
37
- return result;
64
+ return {
65
+ type: 'data',
66
+ data,
67
+ uses: {
68
+ dependencies: uses.dependencies.size > 0 ? Array.from(uses.dependencies) : undefined,
69
+ params: uses.params.size > 0 ? Array.from(uses.params) : undefined,
70
+ parent: uses.parent ? 1 : undefined,
71
+ url: uses.url ? 1 : undefined
72
+ }
73
+ };
38
74
  }
39
75
 
40
76
  /**
@@ -44,21 +80,22 @@ export async function load_server_data({ dev, event, node, parent }) {
44
80
  * fetcher: typeof fetch;
45
81
  * node: import('types').SSRNode | undefined;
46
82
  * parent: () => Promise<Record<string, any>>;
47
- * server_data_promise: Promise<Record<string, any> | null>;
83
+ * server_data_promise: Promise<import('types').ServerDataNode | null>;
48
84
  * state: import('types').SSRState;
49
85
  * }} opts
86
+ * @returns {Promise<Record<string, any> | null>}
50
87
  */
51
88
  export async function load_data({ event, fetcher, node, parent, server_data_promise, state }) {
52
- const server_data = await server_data_promise;
89
+ const server_data_node = await server_data_promise;
53
90
 
54
91
  if (!node?.shared?.load) {
55
- return server_data;
92
+ return server_data_node?.data ?? null;
56
93
  }
57
94
 
58
95
  const load_input = {
59
96
  url: state.prerendering ? new PrerenderingURL(event.url) : new LoadURL(event.url),
60
97
  params: event.params,
61
- data: server_data,
98
+ data: server_data_node?.data ?? null,
62
99
  routeId: event.routeId,
63
100
  fetch: fetcher,
64
101
  setHeaders: event.setHeaders,
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Removes nullish values from an array.
3
+ *
4
+ * @template T
5
+ * @param {Array<T>} arr
6
+ */
7
+ export function compact(arr) {
8
+ return arr.filter(/** @returns {val is NonNullable<T>} */ (val) => val != null);
9
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @template T
3
+ * @param {() => T} fn
4
+ */
5
+ export function once(fn) {
6
+ let done = false;
7
+
8
+ /** @type T */
9
+ let result;
10
+
11
+ return () => {
12
+ if (done) return result;
13
+ done = true;
14
+ return (result = fn());
15
+ };
16
+ }
@@ -12,12 +12,21 @@ export function parse_route_id(id) {
12
12
  // const add_trailing_slash = !/\.[a-z]+$/.test(key);
13
13
  let add_trailing_slash = true;
14
14
 
15
+ if (/\]\[/.test(id)) {
16
+ throw new Error(`Invalid route ${id} — parameters must be separated`);
17
+ }
18
+
19
+ if (count_occurrences('[', id) !== count_occurrences(']', id)) {
20
+ throw new Error(`Invalid route ${id} — brackets are unbalanced`);
21
+ }
22
+
15
23
  const pattern =
16
24
  id === ''
17
25
  ? /^\/$/
18
26
  : new RegExp(
19
27
  `^${id
20
- .split(/(?:@[a-zA-Z0-9_-]+)?(?:\/|$)/)
28
+ .split(/(?:\/|$)/)
29
+ .filter(affects_path)
21
30
  .map((segment, i, segments) => {
22
31
  const decoded_segment = decodeURIComponent(segment);
23
32
  // special case — /[...rest]/ could contain zero segments
@@ -79,6 +88,14 @@ export function parse_route_id(id) {
79
88
  return { pattern, names, types };
80
89
  }
81
90
 
91
+ /**
92
+ * Returns `false` for `(group)` segments
93
+ * @param {string} segment
94
+ */
95
+ export function affects_path(segment) {
96
+ return !/^\([^)]+\)$/.test(segment);
97
+ }
98
+
82
99
  /**
83
100
  * @param {RegExpMatchArray} match
84
101
  * @param {string[]} names
@@ -106,3 +123,15 @@ export function exec(match, names, types, matchers) {
106
123
 
107
124
  return params;
108
125
  }
126
+
127
+ /**
128
+ * @param {string} needle
129
+ * @param {string} haystack
130
+ */
131
+ function count_occurrences(needle, haystack) {
132
+ let count = 0;
133
+ for (let i = 0; i < haystack.length; i += 1) {
134
+ if (haystack[i] === needle) count += 1;
135
+ }
136
+ return count;
137
+ }
@@ -84,7 +84,12 @@ export class Server {
84
84
  };
85
85
  }
86
86
 
87
- init({ env }) {
87
+ /**
88
+ * Take care: Some adapters may have to call \`Server.init\` per-request to set env vars,
89
+ * so anything that shouldn't be rerun should be wrapped in an \`if\` block to make sure it hasn't
90
+ * been done already.
91
+ */
92
+ async init({ env }) {
88
93
  const entries = Object.entries(env);
89
94
 
90
95
  const prv = Object.fromEntries(entries.filter(([k]) => !k.startsWith('${
@@ -99,12 +104,6 @@ export class Server {
99
104
  set_public_env(pub);
100
105
 
101
106
  this.options.public_env = pub;
102
- }
103
-
104
- async respond(request, options = {}) {
105
- if (!(request instanceof Request)) {
106
- throw new Error('The first argument to server.respond must be a Request object. See https://github.com/sveltejs/kit/pull/3384 for details');
107
- }
108
107
 
109
108
  if (!this.options.hooks) {
110
109
  const module = await import(${s(hooks)});
@@ -114,6 +113,12 @@ export class Server {
114
113
  externalFetch: module.externalFetch || fetch
115
114
  };
116
115
  }
116
+ }
117
+
118
+ async respond(request, options = {}) {
119
+ if (!(request instanceof Request)) {
120
+ throw new Error('The first argument to server.respond must be a Request object. See https://github.com/sveltejs/kit/pull/3384 for details');
121
+ }
117
122
 
118
123
  return respond(request, this.options, options);
119
124
  }
@@ -158,8 +163,8 @@ export async function build_server(options, client) {
158
163
 
159
164
  // add entry points for every endpoint...
160
165
  manifest_data.routes.forEach((route) => {
161
- if (route.type === 'endpoint') {
162
- const resolved = path.resolve(cwd, route.file);
166
+ if (route.endpoint) {
167
+ const resolved = path.resolve(cwd, route.endpoint.file);
163
168
  const relative = decodeURIComponent(path.relative(config.kit.files.routes, resolved));
164
169
  const name = posixify(path.join('entries/endpoints', relative.replace(/\.js$/, '')));
165
170
  input[name] = resolved;
@@ -326,10 +331,16 @@ function get_methods(cwd, output, manifest_data) {
326
331
  /** @type {Record<string, import('types').HttpMethod[]>} */
327
332
  const methods = {};
328
333
  manifest_data.routes.forEach((route) => {
329
- const file = route.type === 'endpoint' ? route.file : route.leaf.server;
334
+ if (route.endpoint) {
335
+ if (lookup[route.endpoint.file]) {
336
+ methods[route.endpoint.file] = lookup[route.endpoint.file].filter(is_http_method);
337
+ }
338
+ }
330
339
 
331
- if (file && lookup[file]) {
332
- methods[file] = lookup[file].filter(is_http_method);
340
+ if (route.leaf?.server) {
341
+ if (lookup[route.leaf.server]) {
342
+ methods[route.leaf.server] = lookup[route.leaf.server].filter(is_http_method);
343
+ }
333
344
  }
334
345
  });
335
346
 
@@ -7,12 +7,12 @@ import { getRequest, setResponse } from '../../node/index.js';
7
7
  import { installPolyfills } from '../../node/polyfills.js';
8
8
  import { coalesce_to_error } from '../../utils/error.js';
9
9
  import { posixify } from '../../utils/filesystem.js';
10
- import { parse_route_id } from '../../utils/routing.js';
11
10
  import { load_template } from '../../core/config/index.js';
12
11
  import { SVELTE_KIT_ASSETS } from '../../core/constants.js';
13
12
  import * as sync from '../../core/sync/sync.js';
14
13
  import { get_mime_lookup, runtime_base, runtime_prefix } from '../../core/utils.js';
15
14
  import { get_env, prevent_illegal_vite_imports, resolve_entry } from '../utils.js';
15
+ import { compact } from '../../utils/array.js';
16
16
 
17
17
  // Vite doesn't expose this so we just copy the list for now
18
18
  // https://github.com/vitejs/vite/blob/3edd1af56e980aef56641a5a51cf2932bb580d41/packages/vite/src/node/plugins/css.ts#L96
@@ -149,36 +149,27 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
149
149
  return result;
150
150
  };
151
151
  }),
152
- routes: manifest_data.routes.map((route) => {
153
- const { pattern, names, types } = parse_route_id(route.id);
152
+ routes: compact(
153
+ manifest_data.routes.map((route) => {
154
+ if (!route.page && !route.endpoint) return null;
155
+
156
+ const endpoint = route.endpoint;
154
157
 
155
- if (route.type === 'page') {
156
158
  return {
157
- type: 'page',
158
159
  id: route.id,
159
- pattern,
160
- names,
161
- types,
162
- errors: route.errors.map((id) => (id ? manifest_data.nodes.indexOf(id) : undefined)),
163
- layouts: route.layouts.map((id) =>
164
- id ? manifest_data.nodes.indexOf(id) : undefined
165
- ),
166
- leaf: manifest_data.nodes.indexOf(route.leaf)
160
+ pattern: route.pattern,
161
+ names: route.names,
162
+ types: route.types,
163
+ page: route.page,
164
+ endpoint: endpoint
165
+ ? async () => {
166
+ const url = path.resolve(cwd, endpoint.file);
167
+ return await vite.ssrLoadModule(url);
168
+ }
169
+ : null
167
170
  };
168
- }
169
-
170
- return {
171
- type: 'endpoint',
172
- id: route.id,
173
- pattern,
174
- names,
175
- types,
176
- load: async () => {
177
- const url = path.resolve(cwd, route.file);
178
- return await vite.ssrLoadModule(url);
179
- }
180
- };
181
- }),
171
+ })
172
+ ),
182
173
  matchers: async () => {
183
174
  /** @type {Record<string, import('types').ParamMatcher>} */
184
175
  const matchers = {};
@@ -229,15 +220,16 @@ export async function dev(vite, vite_config, svelte_config, illegal_imports) {
229
220
  to_run();
230
221
  }, 100);
231
222
  };
223
+
232
224
  // Debounce add/unlink events because in case of folder deletion or moves
233
225
  // they fire in rapid succession, causing needless invocations.
234
226
  watch('add', () => debounce(update_manifest));
235
227
  watch('unlink', () => debounce(update_manifest));
236
228
  watch('change', (file) => {
237
229
  // Don't run for a single file if the whole manifest is about to get updated
238
- if (!timeout) {
239
- sync.update(svelte_config, manifest_data, file);
240
- }
230
+ if (timeout) return;
231
+
232
+ sync.update(svelte_config, manifest_data, file);
241
233
  });
242
234
 
243
235
  const assets = svelte_config.kit.paths.assets ? SVELTE_KIT_ASSETS : svelte_config.kit.paths.base;
package/src/vite/index.js CHANGED
@@ -411,7 +411,13 @@ function kit() {
411
411
 
412
412
  const child = fork(
413
413
  script,
414
- [vite_config.build.outDir, results_path, manifest_path, '' + verbose],
414
+ [
415
+ vite_config.build.outDir,
416
+ results_path,
417
+ manifest_path,
418
+ '' + verbose,
419
+ JSON.stringify({ ...env.private, ...env.public })
420
+ ],
415
421
  {
416
422
  stdio: 'inherit'
417
423
  }
@@ -45,7 +45,7 @@ export async function preview(vite, vite_config, svelte_config) {
45
45
  });
46
46
 
47
47
  const server = new Server(manifest);
48
- server.init({
48
+ await server.init({
49
49
  env: loadEnv(vite_config.mode, process.cwd(), '')
50
50
  });
51
51
 
package/types/index.d.ts CHANGED
@@ -264,7 +264,7 @@ export interface ResolveOptions {
264
264
 
265
265
  export class Server {
266
266
  constructor(manifest: SSRManifest);
267
- init(options: ServerInitOptions): void;
267
+ init(options: ServerInitOptions): Promise<void>;
268
268
  respond(request: Request, options: RequestOptions): Promise<Response>;
269
269
  }
270
270