@sveltejs/kit 1.0.0-next.190 → 1.0.0-next.194

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.
@@ -655,28 +655,37 @@ class Renderer {
655
655
  this._init(navigation_result);
656
656
  }
657
657
 
658
- if (opts) {
658
+ if (!opts) {
659
+ await 0;
660
+ } else {
659
661
  const { hash, scroll, keepfocus } = opts;
660
662
 
661
663
  if (!keepfocus) {
662
664
  document.body.focus();
663
665
  }
664
666
 
665
- const deep_linked = hash && document.getElementById(hash.slice(1));
666
- if (scroll) {
667
- scrollTo(scroll.x, scroll.y);
668
- } else if (deep_linked) {
669
- // Here we use `scrollIntoView` on the element instead of `scrollTo`
670
- // because it natively supports the `scroll-margin` and `scroll-behavior`
671
- // CSS properties.
672
- deep_linked.scrollIntoView();
673
- } else {
674
- scrollTo(0, 0);
667
+ const oldPageYOffset = pageYOffset;
668
+ await 0;
669
+ const maxPageYOffset = document.body.scrollHeight - innerHeight;
670
+
671
+ // After `await 0`, the `onMount()` function in the component executed.
672
+ // If there was no scrolling happening (checked via `pageYOffset`),
673
+ // continue on our custom scroll handling
674
+ if (pageYOffset === Math.min(oldPageYOffset, maxPageYOffset)) {
675
+ const deep_linked = hash && document.getElementById(hash.slice(1));
676
+ if (scroll) {
677
+ scrollTo(scroll.x, scroll.y);
678
+ } else if (deep_linked) {
679
+ // Here we use `scrollIntoView` on the element instead of `scrollTo`
680
+ // because it natively supports the `scroll-margin` and `scroll-behavior`
681
+ // CSS properties.
682
+ deep_linked.scrollIntoView();
683
+ } else {
684
+ scrollTo(0, 0);
685
+ }
675
686
  }
676
687
  }
677
688
 
678
- await 0;
679
-
680
689
  this.loading.promise = null;
681
690
  this.loading.id = null;
682
691
 
@@ -4268,6 +4268,20 @@ class Watcher extends EventEmitter {
4268
4268
  });
4269
4269
  }
4270
4270
 
4271
+ allowed_directories() {
4272
+ return [
4273
+ ...new Set([
4274
+ this.config.kit.files.assets,
4275
+ this.config.kit.files.lib,
4276
+ this.config.kit.files.routes,
4277
+ path__default.resolve(this.cwd, 'src'),
4278
+ path__default.resolve(this.cwd, '.svelte-kit'),
4279
+ path__default.resolve(this.cwd, 'node_modules'),
4280
+ path__default.resolve(vite.searchForWorkspaceRoot(this.cwd), 'node_modules')
4281
+ ])
4282
+ ];
4283
+ }
4284
+
4271
4285
  async init_server() {
4272
4286
  if (!this.manifest) throw new Error('Must call init() before init_server()');
4273
4287
 
@@ -4277,7 +4291,8 @@ class Watcher extends EventEmitter {
4277
4291
  const default_config = {
4278
4292
  server: {
4279
4293
  fs: {
4280
- strict: true
4294
+ strict: true,
4295
+ allow: this.allowed_directories()
4281
4296
  },
4282
4297
  strictPort: true
4283
4298
  }
@@ -198,7 +198,8 @@ function generate_app(manifest_data) {
198
198
  const max_depth = Math.max(
199
199
  ...manifest_data.routes.map((route) =>
200
200
  route.type === 'page' ? route.a.filter(Boolean).length : 0
201
- )
201
+ ),
202
+ 1
202
203
  );
203
204
 
204
205
  const levels = [];
@@ -466,12 +466,6 @@ var glob = sync;
466
466
  /** @param {any} value */
467
467
  const s = (value) => JSON.stringify(value);
468
468
 
469
- /** @typedef {Record<string, {
470
- * file: string;
471
- * css: string[];
472
- * imports: string[];
473
- * }>} ClientManifest */
474
-
475
469
  /**
476
470
  * @param {import('types/config').ValidatedConfig} config
477
471
  * @param {{
@@ -562,7 +556,6 @@ async function build_client({
562
556
  process.env.VITE_SVELTEKIT_AMP = config.kit.amp ? 'true' : '';
563
557
 
564
558
  const client_out_dir = `${output_dir}/client/${config.kit.appDir}`;
565
- const client_manifest_file = `${client_out_dir}/manifest.json`;
566
559
 
567
560
  /** @type {Record<string, string>} */
568
561
  const input = {
@@ -637,7 +630,8 @@ async function build_client({
637
630
 
638
631
  await vite.build(merged_config);
639
632
 
640
- /** @type {ClientManifest} */
633
+ const client_manifest_file = `${client_out_dir}/manifest.json`;
634
+ /** @type {import('vite').Manifest} */
641
635
  const client_manifest = JSON.parse(fs__default.readFileSync(client_manifest_file, 'utf-8'));
642
636
  fs__default.renameSync(client_manifest_file, `${output_dir}/manifest.json`); // inspectable but not shipped
643
637
 
@@ -655,7 +649,7 @@ async function build_client({
655
649
  * client_entry_file: string;
656
650
  * service_worker_entry_file: string | null;
657
651
  * }} options
658
- * @param {ClientManifest} client_manifest
652
+ * @param {import('vite').Manifest} client_manifest
659
653
  * @param {string} runtime
660
654
  */
661
655
  async function build_server(
@@ -894,7 +888,12 @@ async function build_server(
894
888
 
895
889
  const default_config = {
896
890
  build: {
897
- target: 'es2020'
891
+ target: 'es2020',
892
+ rollupOptions: {
893
+ output: {
894
+ inlineDynamicImports: true
895
+ }
896
+ }
898
897
  },
899
898
  server: {
900
899
  fs: {
@@ -923,8 +922,7 @@ async function build_server(
923
922
  format: 'esm',
924
923
  entryFileNames: '[name].js',
925
924
  chunkFileNames: 'chunks/[name]-[hash].js',
926
- assetFileNames: 'assets/[name]-[hash][extname]',
927
- inlineDynamicImports: true
925
+ assetFileNames: 'assets/[name]-[hash][extname]'
928
926
  },
929
927
  preserveEntrySignatures: 'strict'
930
928
  }
@@ -961,7 +959,7 @@ async function build_server(
961
959
  * client_entry_file: string;
962
960
  * service_worker_entry_file: string | null;
963
961
  * }} options
964
- * @param {ClientManifest} client_manifest
962
+ * @param {import('vite').Manifest} client_manifest
965
963
  */
966
964
  async function build_service_worker(
967
965
  { cwd, assets_base, config, manifest, build_dir, output_dir, service_worker_entry_file },
@@ -348,15 +348,15 @@ function get_utils({ cwd, config, build_data, log }) {
348
348
  copy,
349
349
 
350
350
  copy_client_files(dest) {
351
- copy(`${cwd}/${SVELTE_KIT}/output/client`, dest, (file) => file[0] !== '.');
351
+ return copy(`${cwd}/${SVELTE_KIT}/output/client`, dest, (file) => file[0] !== '.');
352
352
  },
353
353
 
354
354
  copy_server_files(dest) {
355
- copy(`${cwd}/${SVELTE_KIT}/output/server`, dest, (file) => file[0] !== '.');
355
+ return copy(`${cwd}/${SVELTE_KIT}/output/server`, dest, (file) => file[0] !== '.');
356
356
  },
357
357
 
358
358
  copy_static_files(dest) {
359
- copy(config.kit.files.assets, dest);
359
+ return copy(config.kit.files.assets, dest);
360
360
  },
361
361
 
362
362
  async prerender({ all = false, dest, fallback }) {
@@ -153,20 +153,26 @@ function send(req, res, file, stats, headers) {
153
153
  fs.createReadStream(file, opts).pipe(res);
154
154
  }
155
155
 
156
- function isEncoding(name, type, headers) {
157
- headers['Content-Encoding'] = type;
158
- headers['Content-Type'] = lite.getType(name.replace(/\.([^.]*)$/, '')) || '';
159
- }
156
+ const ENCODING = {
157
+ '.br': 'br',
158
+ '.gz': 'gzip',
159
+ };
160
160
 
161
161
  function toHeaders(name, stats, isEtag) {
162
+ let enc = ENCODING[name.slice(-3)];
163
+
164
+ let ctype = lite.getType(name.slice(0, enc && -3)) || '';
165
+ if (ctype === 'text/html') ctype += ';charset=utf-8';
166
+
162
167
  let headers = {
163
168
  'Content-Length': stats.size,
164
- 'Content-Type': lite.getType(name) || '',
169
+ 'Content-Type': ctype,
165
170
  'Last-Modified': stats.mtime.toUTCString(),
166
171
  };
172
+
173
+ if (enc) headers['Content-Encoding'] = enc;
167
174
  if (isEtag) headers['ETag'] = `W/"${stats.size}-${stats.mtime.getTime()}"`;
168
- if (/\.br$/.test(name)) isEncoding(name, 'br', headers);
169
- if (/\.gz$/.test(name)) isEncoding(name, 'gzip', headers);
175
+
170
176
  return headers;
171
177
  }
172
178
 
package/dist/cli.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import fs__default, { existsSync } from 'fs';
2
2
  import sade from 'sade';
3
+ import path__default, { relative } from 'path';
3
4
  import { exec as exec$1 } from 'child_process';
4
5
  import { createConnection, createServer } from 'net';
5
- import path__default from 'path';
6
6
  import * as url from 'url';
7
7
  import { fileURLToPath } from 'url';
8
8
  import { networkInterfaces, release } from 'os';
@@ -817,7 +817,7 @@ async function launch(port, https) {
817
817
  exec(`${cmd} ${https ? 'https' : 'http'}://localhost:${port}`);
818
818
  }
819
819
 
820
- const prog = sade('svelte-kit').version('1.0.0-next.190');
820
+ const prog = sade('svelte-kit').version('1.0.0-next.194');
821
821
 
822
822
  prog
823
823
  .command('dev')
@@ -851,10 +851,20 @@ prog
851
851
  watcher.vite.httpServer.address()
852
852
  );
853
853
 
854
- https = https || !!config.kit.vite().server?.https;
855
- open = open || !!config.kit.vite().server?.open;
854
+ const vite_config = config.kit.vite();
856
855
 
857
- welcome({ port: address_info.port, host: address_info.address, https, open });
856
+ https = https || !!vite_config.server?.https;
857
+ open = open || !!vite_config.server?.open;
858
+
859
+ welcome({
860
+ port: address_info.port,
861
+ host: address_info.address,
862
+ https,
863
+ open,
864
+ loose: vite_config.server?.fs?.strict === false,
865
+ allow: watcher.allowed_directories(),
866
+ cwd: watcher.cwd
867
+ });
858
868
  } catch (error) {
859
869
  handle_error(error);
860
870
  }
@@ -964,12 +974,15 @@ async function check_port(port) {
964
974
  * host: string;
965
975
  * https: boolean;
966
976
  * port: number;
977
+ * loose?: boolean;
978
+ * allow?: string[];
979
+ * cwd?: string;
967
980
  * }} param0
968
981
  */
969
- function welcome({ port, host, https, open }) {
982
+ function welcome({ port, host, https, open, loose, allow, cwd }) {
970
983
  if (open) launch(port, https);
971
984
 
972
- console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.190'}\n`));
985
+ console.log($.bold().cyan(`\n SvelteKit v${'1.0.0-next.194'}\n`));
973
986
 
974
987
  const protocol = https ? 'https:' : 'http:';
975
988
  const exposed = typeof host !== 'undefined' && host !== 'localhost' && host !== '127.0.0.1';
@@ -987,6 +1000,11 @@ function welcome({ port, host, https, open }) {
987
1000
 
988
1001
  if (exposed) {
989
1002
  console.log(` ${$.gray('network:')} ${protocol}//${$.bold(`${details.address}:${port}`)}`);
1003
+ if (loose) {
1004
+ console.log(`\n ${$.yellow('Serving with vite.server.fs.strict: false. Note that all files on your machine will be accessible to anyone on your network.')}`);
1005
+ } else if (allow?.length && cwd) {
1006
+ console.log(`\n ${$.yellow('Note that all files in the following directories will be accessible to anyone on your network: ' + allow.map(a => relative(cwd, a)).join(', '))}`);
1007
+ }
990
1008
  } else {
991
1009
  console.log(` ${$.gray('network: not exposed')}`);
992
1010
  }
@@ -4238,38 +4238,54 @@ var ponyfill_es2018 = {exports: {}};
4238
4238
  const POOL_SIZE$1 = 65536;
4239
4239
 
4240
4240
  if (!globalThis.ReadableStream) {
4241
+ // `node:stream/web` got introduced in v16.5.0 as experimental
4242
+ // and it's preferred over the polyfilled version. So we also
4243
+ // suppress the warning that gets emitted by NodeJS for using it.
4241
4244
  try {
4242
- Object.assign(globalThis, require('stream/web'));
4245
+ const process = require('node:process');
4246
+ const { emitWarning } = process;
4247
+ try {
4248
+ process.emitWarning = () => {};
4249
+ Object.assign(globalThis, require('node:stream/web'));
4250
+ process.emitWarning = emitWarning;
4251
+ } catch (error) {
4252
+ process.emitWarning = emitWarning;
4253
+ throw error
4254
+ }
4243
4255
  } catch (error) {
4244
- // TODO: Remove when only supporting node >= 16.5.0
4256
+ // fallback to polyfill implementation
4245
4257
  Object.assign(globalThis, ponyfill_es2018.exports);
4246
4258
  }
4247
4259
  }
4248
4260
 
4249
4261
  try {
4250
- const {Blob} = require('buffer');
4262
+ // Don't use node: prefix for this, require+node: is not supported until node v14.14
4263
+ // Only `import()` can use prefix in 12.20 and later
4264
+ const { Blob } = require('buffer');
4251
4265
  if (Blob && !Blob.prototype.stream) {
4252
- Blob.prototype.stream = function name(params) {
4253
- let position = 0;
4254
- const blob = this;
4255
-
4256
- return new ReadableStream({
4257
- type: 'bytes',
4258
- async pull(ctrl) {
4259
- const chunk = blob.slice(position, Math.min(blob.size, position + POOL_SIZE$1));
4260
- const buffer = await chunk.arrayBuffer();
4261
- position += buffer.byteLength;
4262
- ctrl.enqueue(new Uint8Array(buffer));
4263
-
4264
- if (position === blob.size) {
4265
- ctrl.close();
4266
- }
4267
- }
4268
- })
4269
- };
4270
- }
4266
+ Blob.prototype.stream = function name (params) {
4267
+ let position = 0;
4268
+ const blob = this;
4269
+
4270
+ return new ReadableStream({
4271
+ type: 'bytes',
4272
+ async pull (ctrl) {
4273
+ const chunk = blob.slice(position, Math.min(blob.size, position + POOL_SIZE$1));
4274
+ const buffer = await chunk.arrayBuffer();
4275
+ position += buffer.byteLength;
4276
+ ctrl.enqueue(new Uint8Array(buffer));
4277
+
4278
+ if (position === blob.size) {
4279
+ ctrl.close();
4280
+ }
4281
+ }
4282
+ })
4283
+ };
4284
+ }
4271
4285
  } catch (error) {}
4272
4286
 
4287
+ /*! fetch-blob. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */
4288
+
4273
4289
  /** @typedef {import('buffer').Blob} NodeBlob} */
4274
4290
 
4275
4291
  // 64 KiB (same size chrome slice theirs blob into Uint8array's)
@@ -4277,223 +4293,238 @@ const POOL_SIZE = 65536;
4277
4293
 
4278
4294
  /** @param {(Blob | NodeBlob | Uint8Array)[]} parts */
4279
4295
  async function * toIterator (parts, clone = true) {
4280
- for (let part of parts) {
4281
- if ('stream' in part) {
4282
- yield * part.stream();
4283
- } else if (ArrayBuffer.isView(part)) {
4284
- if (clone) {
4285
- let position = part.byteOffset;
4286
- let end = part.byteOffset + part.byteLength;
4287
- while (position !== end) {
4288
- const size = Math.min(end - position, POOL_SIZE);
4289
- const chunk = part.buffer.slice(position, position + size);
4290
- position += chunk.byteLength;
4291
- yield new Uint8Array(chunk);
4292
- }
4293
- } else {
4294
- yield part;
4295
- }
4296
- } else {
4297
- /* c8 ignore start */
4298
- // For blobs that have arrayBuffer but no stream method (nodes buffer.Blob)
4299
- let position = 0;
4300
- while (position !== part.size) {
4301
- const chunk = part.slice(position, Math.min(part.size, position + POOL_SIZE));
4302
- const buffer = await chunk.arrayBuffer();
4303
- position += buffer.byteLength;
4304
- yield new Uint8Array(buffer);
4305
- }
4306
- /* c8 ignore end */
4307
- }
4308
- }
4296
+ for (const part of parts) {
4297
+ if ('stream' in part) {
4298
+ yield * part.stream();
4299
+ } else if (ArrayBuffer.isView(part)) {
4300
+ if (clone) {
4301
+ let position = part.byteOffset;
4302
+ const end = part.byteOffset + part.byteLength;
4303
+ while (position !== end) {
4304
+ const size = Math.min(end - position, POOL_SIZE);
4305
+ const chunk = part.buffer.slice(position, position + size);
4306
+ position += chunk.byteLength;
4307
+ yield new Uint8Array(chunk);
4308
+ }
4309
+ } else {
4310
+ yield part;
4311
+ }
4312
+ } else {
4313
+ /* c8 ignore start */
4314
+ // For blobs that have arrayBuffer but no stream method (nodes buffer.Blob)
4315
+ let position = 0;
4316
+ while (position !== part.size) {
4317
+ const chunk = part.slice(position, Math.min(part.size, position + POOL_SIZE));
4318
+ const buffer = await chunk.arrayBuffer();
4319
+ position += buffer.byteLength;
4320
+ yield new Uint8Array(buffer);
4321
+ }
4322
+ /* c8 ignore end */
4323
+ }
4324
+ }
4309
4325
  }
4310
4326
 
4311
4327
  const _Blob = class Blob {
4328
+ /** @type {Array.<(Blob|Uint8Array)>} */
4329
+ #parts = []
4330
+ #type = ''
4331
+ #size = 0
4312
4332
 
4313
- /** @type {Array.<(Blob|Uint8Array)>} */
4314
- #parts = [];
4315
- #type = '';
4316
- #size = 0;
4317
-
4318
- /**
4319
- * The Blob() constructor returns a new Blob object. The content
4320
- * of the blob consists of the concatenation of the values given
4321
- * in the parameter array.
4322
- *
4323
- * @param {*} blobParts
4324
- * @param {{ type?: string }} [options]
4325
- */
4326
- constructor(blobParts = [], options = {}) {
4327
- let size = 0;
4328
-
4329
- const parts = blobParts.map(element => {
4330
- let part;
4331
- if (ArrayBuffer.isView(element)) {
4332
- part = new Uint8Array(element.buffer.slice(element.byteOffset, element.byteOffset + element.byteLength));
4333
- } else if (element instanceof ArrayBuffer) {
4334
- part = new Uint8Array(element.slice(0));
4335
- } else if (element instanceof Blob) {
4336
- part = element;
4337
- } else {
4338
- part = new TextEncoder().encode(element);
4339
- }
4340
-
4341
- size += ArrayBuffer.isView(part) ? part.byteLength : part.size;
4342
- return part;
4343
- });
4333
+ /**
4334
+ * The Blob() constructor returns a new Blob object. The content
4335
+ * of the blob consists of the concatenation of the values given
4336
+ * in the parameter array.
4337
+ *
4338
+ * @param {*} blobParts
4339
+ * @param {{ type?: string }} [options]
4340
+ */
4341
+ constructor (blobParts = [], options = {}) {
4342
+ if (typeof blobParts !== 'object' || blobParts === null) {
4343
+ throw new TypeError('Failed to construct \'Blob\': The provided value cannot be converted to a sequence.')
4344
+ }
4344
4345
 
4345
- const type = options.type === undefined ? '' : String(options.type);
4346
+ if (typeof blobParts[Symbol.iterator] !== 'function') {
4347
+ throw new TypeError('Failed to construct \'Blob\': The object must have a callable @@iterator property.')
4348
+ }
4346
4349
 
4347
- this.#type = /[^\u0020-\u007E]/.test(type) ? '' : type;
4348
- this.#size = size;
4349
- this.#parts = parts;
4350
- }
4350
+ if (typeof options !== 'object' && typeof options !== 'function') {
4351
+ throw new TypeError('Failed to construct \'Blob\': parameter 2 cannot convert to dictionary.')
4352
+ }
4351
4353
 
4352
- /**
4353
- * The Blob interface's size property returns the
4354
- * size of the Blob in bytes.
4355
- */
4356
- get size() {
4357
- return this.#size;
4358
- }
4354
+ if (options === null) options = {};
4359
4355
 
4360
- /**
4361
- * The type property of a Blob object returns the MIME type of the file.
4362
- */
4363
- get type() {
4364
- return this.#type;
4365
- }
4356
+ const encoder = new TextEncoder();
4357
+ for (const element of blobParts) {
4358
+ let part;
4359
+ if (ArrayBuffer.isView(element)) {
4360
+ part = new Uint8Array(element.buffer.slice(element.byteOffset, element.byteOffset + element.byteLength));
4361
+ } else if (element instanceof ArrayBuffer) {
4362
+ part = new Uint8Array(element.slice(0));
4363
+ } else if (element instanceof Blob) {
4364
+ part = element;
4365
+ } else {
4366
+ part = encoder.encode(element);
4367
+ }
4366
4368
 
4367
- /**
4368
- * The text() method in the Blob interface returns a Promise
4369
- * that resolves with a string containing the contents of
4370
- * the blob, interpreted as UTF-8.
4371
- *
4372
- * @return {Promise<string>}
4373
- */
4374
- async text() {
4375
- // More optimized than using this.arrayBuffer()
4376
- // that requires twice as much ram
4377
- const decoder = new TextDecoder();
4378
- let str = '';
4379
- for await (let part of toIterator(this.#parts, false)) {
4380
- str += decoder.decode(part, { stream: true });
4381
- }
4382
- // Remaining
4383
- str += decoder.decode();
4384
- return str;
4385
- }
4386
-
4387
- /**
4388
- * The arrayBuffer() method in the Blob interface returns a
4389
- * Promise that resolves with the contents of the blob as
4390
- * binary data contained in an ArrayBuffer.
4391
- *
4392
- * @return {Promise<ArrayBuffer>}
4393
- */
4394
- async arrayBuffer() {
4395
- // Easier way... Just a unnecessary overhead
4396
- // const view = new Uint8Array(this.size);
4397
- // await this.stream().getReader({mode: 'byob'}).read(view);
4398
- // return view.buffer;
4399
-
4400
- const data = new Uint8Array(this.size);
4401
- let offset = 0;
4402
- for await (const chunk of toIterator(this.#parts, false)) {
4403
- data.set(chunk, offset);
4404
- offset += chunk.length;
4405
- }
4369
+ this.#size += ArrayBuffer.isView(part) ? part.byteLength : part.size;
4370
+ this.#parts.push(part);
4371
+ }
4406
4372
 
4407
- return data.buffer;
4408
- }
4373
+ const type = options.type === undefined ? '' : String(options.type);
4409
4374
 
4410
- stream() {
4411
- const it = toIterator(this.#parts, true);
4375
+ this.#type = /^[\x20-\x7E]*$/.test(type) ? type : '';
4376
+ }
4412
4377
 
4413
- return new ReadableStream({
4414
- type: 'bytes',
4415
- async pull(ctrl) {
4416
- const chunk = await it.next();
4417
- chunk.done ? ctrl.close() : ctrl.enqueue(chunk.value);
4418
- }
4419
- })
4420
- }
4378
+ /**
4379
+ * The Blob interface's size property returns the
4380
+ * size of the Blob in bytes.
4381
+ */
4382
+ get size () {
4383
+ return this.#size
4384
+ }
4421
4385
 
4422
- /**
4423
- * The Blob interface's slice() method creates and returns a
4424
- * new Blob object which contains data from a subset of the
4425
- * blob on which it's called.
4426
- *
4427
- * @param {number} [start]
4428
- * @param {number} [end]
4429
- * @param {string} [type]
4430
- */
4431
- slice(start = 0, end = this.size, type = '') {
4432
- const {size} = this;
4386
+ /**
4387
+ * The type property of a Blob object returns the MIME type of the file.
4388
+ */
4389
+ get type () {
4390
+ return this.#type
4391
+ }
4433
4392
 
4434
- let relativeStart = start < 0 ? Math.max(size + start, 0) : Math.min(start, size);
4435
- let relativeEnd = end < 0 ? Math.max(size + end, 0) : Math.min(end, size);
4393
+ /**
4394
+ * The text() method in the Blob interface returns a Promise
4395
+ * that resolves with a string containing the contents of
4396
+ * the blob, interpreted as UTF-8.
4397
+ *
4398
+ * @return {Promise<string>}
4399
+ */
4400
+ async text () {
4401
+ // More optimized than using this.arrayBuffer()
4402
+ // that requires twice as much ram
4403
+ const decoder = new TextDecoder();
4404
+ let str = '';
4405
+ for await (const part of toIterator(this.#parts, false)) {
4406
+ str += decoder.decode(part, { stream: true });
4407
+ }
4408
+ // Remaining
4409
+ str += decoder.decode();
4410
+ return str
4411
+ }
4436
4412
 
4437
- const span = Math.max(relativeEnd - relativeStart, 0);
4438
- const parts = this.#parts;
4439
- const blobParts = [];
4440
- let added = 0;
4413
+ /**
4414
+ * The arrayBuffer() method in the Blob interface returns a
4415
+ * Promise that resolves with the contents of the blob as
4416
+ * binary data contained in an ArrayBuffer.
4417
+ *
4418
+ * @return {Promise<ArrayBuffer>}
4419
+ */
4420
+ async arrayBuffer () {
4421
+ // Easier way... Just a unnecessary overhead
4422
+ // const view = new Uint8Array(this.size);
4423
+ // await this.stream().getReader({mode: 'byob'}).read(view);
4424
+ // return view.buffer;
4425
+
4426
+ const data = new Uint8Array(this.size);
4427
+ let offset = 0;
4428
+ for await (const chunk of toIterator(this.#parts, false)) {
4429
+ data.set(chunk, offset);
4430
+ offset += chunk.length;
4431
+ }
4432
+
4433
+ return data.buffer
4434
+ }
4441
4435
 
4442
- for (const part of parts) {
4443
- // don't add the overflow to new blobParts
4444
- if (added >= span) {
4445
- break;
4446
- }
4436
+ stream () {
4437
+ const it = toIterator(this.#parts, true);
4447
4438
 
4448
- const size = ArrayBuffer.isView(part) ? part.byteLength : part.size;
4449
- if (relativeStart && size <= relativeStart) {
4450
- // Skip the beginning and change the relative
4451
- // start & end position as we skip the unwanted parts
4452
- relativeStart -= size;
4453
- relativeEnd -= size;
4454
- } else {
4455
- let chunk;
4456
- if (ArrayBuffer.isView(part)) {
4457
- chunk = part.subarray(relativeStart, Math.min(size, relativeEnd));
4458
- added += chunk.byteLength;
4459
- } else {
4460
- chunk = part.slice(relativeStart, Math.min(size, relativeEnd));
4461
- added += chunk.size;
4462
- }
4463
- blobParts.push(chunk);
4464
- relativeStart = 0; // All next sequential parts should start at 0
4465
- }
4466
- }
4439
+ return new globalThis.ReadableStream({
4440
+ type: 'bytes',
4441
+ async pull (ctrl) {
4442
+ const chunk = await it.next();
4443
+ chunk.done ? ctrl.close() : ctrl.enqueue(chunk.value);
4444
+ },
4467
4445
 
4468
- const blob = new Blob([], {type: String(type).toLowerCase()});
4469
- blob.#size = span;
4470
- blob.#parts = blobParts;
4446
+ async cancel () {
4447
+ await it.return();
4448
+ }
4449
+ })
4450
+ }
4471
4451
 
4472
- return blob;
4473
- }
4452
+ /**
4453
+ * The Blob interface's slice() method creates and returns a
4454
+ * new Blob object which contains data from a subset of the
4455
+ * blob on which it's called.
4456
+ *
4457
+ * @param {number} [start]
4458
+ * @param {number} [end]
4459
+ * @param {string} [type]
4460
+ */
4461
+ slice (start = 0, end = this.size, type = '') {
4462
+ const { size } = this;
4463
+
4464
+ let relativeStart = start < 0 ? Math.max(size + start, 0) : Math.min(start, size);
4465
+ let relativeEnd = end < 0 ? Math.max(size + end, 0) : Math.min(end, size);
4466
+
4467
+ const span = Math.max(relativeEnd - relativeStart, 0);
4468
+ const parts = this.#parts;
4469
+ const blobParts = [];
4470
+ let added = 0;
4471
+
4472
+ for (const part of parts) {
4473
+ // don't add the overflow to new blobParts
4474
+ if (added >= span) {
4475
+ break
4476
+ }
4477
+
4478
+ const size = ArrayBuffer.isView(part) ? part.byteLength : part.size;
4479
+ if (relativeStart && size <= relativeStart) {
4480
+ // Skip the beginning and change the relative
4481
+ // start & end position as we skip the unwanted parts
4482
+ relativeStart -= size;
4483
+ relativeEnd -= size;
4484
+ } else {
4485
+ let chunk;
4486
+ if (ArrayBuffer.isView(part)) {
4487
+ chunk = part.subarray(relativeStart, Math.min(size, relativeEnd));
4488
+ added += chunk.byteLength;
4489
+ } else {
4490
+ chunk = part.slice(relativeStart, Math.min(size, relativeEnd));
4491
+ added += chunk.size;
4492
+ }
4493
+ relativeEnd -= size;
4494
+ blobParts.push(chunk);
4495
+ relativeStart = 0; // All next sequential parts should start at 0
4496
+ }
4497
+ }
4498
+
4499
+ const blob = new Blob([], { type: String(type).toLowerCase() });
4500
+ blob.#size = span;
4501
+ blob.#parts = blobParts;
4502
+
4503
+ return blob
4504
+ }
4474
4505
 
4475
- get [Symbol.toStringTag]() {
4476
- return 'Blob';
4477
- }
4506
+ get [Symbol.toStringTag] () {
4507
+ return 'Blob'
4508
+ }
4478
4509
 
4479
- static [Symbol.hasInstance](object) {
4480
- return (
4481
- object &&
4482
- typeof object === 'object' &&
4483
- typeof object.constructor === 'function' &&
4484
- (
4485
- typeof object.stream === 'function' ||
4486
- typeof object.arrayBuffer === 'function'
4487
- ) &&
4488
- /^(Blob|File)$/.test(object[Symbol.toStringTag])
4489
- );
4490
- }
4510
+ static [Symbol.hasInstance] (object) {
4511
+ return (
4512
+ object &&
4513
+ typeof object === 'object' &&
4514
+ typeof object.constructor === 'function' &&
4515
+ (
4516
+ typeof object.stream === 'function' ||
4517
+ typeof object.arrayBuffer === 'function'
4518
+ ) &&
4519
+ /^(Blob|File)$/.test(object[Symbol.toStringTag])
4520
+ )
4521
+ }
4491
4522
  };
4492
4523
 
4493
4524
  Object.defineProperties(_Blob.prototype, {
4494
- size: {enumerable: true},
4495
- type: {enumerable: true},
4496
- slice: {enumerable: true}
4525
+ size: { enumerable: true },
4526
+ type: { enumerable: true },
4527
+ slice: { enumerable: true }
4497
4528
  });
4498
4529
 
4499
4530
  /** @type {typeof globalThis.Blob} */
package/dist/ssr.js CHANGED
@@ -1260,8 +1260,7 @@ async function respond$1(opts) {
1260
1260
  // otherwise bail out at this point
1261
1261
  return {
1262
1262
  status: 204,
1263
- headers: {},
1264
- body: ''
1263
+ headers: {}
1265
1264
  };
1266
1265
  }
1267
1266
 
@@ -1753,8 +1752,7 @@ async function respond(incoming, options, state = {}) {
1753
1752
  if (request.headers['if-none-match'] === etag) {
1754
1753
  return {
1755
1754
  status: 304,
1756
- headers: {},
1757
- body: ''
1755
+ headers: {}
1758
1756
  };
1759
1757
  }
1760
1758
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltejs/kit",
3
- "version": "1.0.0-next.190",
3
+ "version": "1.0.0-next.194",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/sveltejs/kit",
@@ -12,7 +12,7 @@
12
12
  "@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
13
13
  "cheap-watch": "^1.0.4",
14
14
  "sade": "^1.7.4",
15
- "vite": "^2.6.11"
15
+ "vite": "^2.6.12"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@rollup/plugin-replace": "^3.0.0",
@@ -161,7 +161,7 @@ declare module '@sveltejs/kit/ssr' {
161
161
  type State = import('@sveltejs/kit/types/internal').SSRRenderState;
162
162
 
163
163
  export interface Respond {
164
- (incoming: IncomingRequest, options: Options, state?: State): Response;
164
+ (incoming: IncomingRequest, options: Options, state?: State): Promise<Response>;
165
165
  }
166
166
  export const respond: Respond;
167
167
  }
package/types/config.d.ts CHANGED
@@ -6,10 +6,27 @@ export interface AdapterUtils {
6
6
  log: Logger;
7
7
  rimraf(dir: string): void;
8
8
  mkdirp(dir: string): void;
9
- copy_client_files(dest: string): void;
10
- copy_server_files(dest: string): void;
11
- copy_static_files(dest: string): void;
12
- copy(from: string, to: string, filter?: (basename: string) => boolean): void;
9
+ /**
10
+ * @param dest the destination folder to which files should be copied
11
+ * @returns an array of paths corresponding to the files that have been created by the copy
12
+ */
13
+ copy_client_files(dest: string): string[];
14
+ /**
15
+ * @param dest the destination folder to which files should be copied
16
+ * @returns an array of paths corresponding to the files that have been created by the copy
17
+ */
18
+ copy_server_files(dest: string): string[];
19
+ /**
20
+ * @param dest the destination folder to which files should be copied
21
+ * @returns an array of paths corresponding to the files that have been created by the copy
22
+ */
23
+ copy_static_files(dest: string): string[];
24
+ /**
25
+ * @param from the source folder from which files should be copied
26
+ * @param to the destination folder to which files should be copied
27
+ * @returns an array of paths corresponding to the files that have been created by the copy
28
+ */
29
+ copy(from: string, to: string, filter?: (basename: string) => boolean): string[];
13
30
  prerender(options: { all?: boolean; dest: string; fallback?: string }): Promise<void>;
14
31
  }
15
32
 
@@ -121,9 +121,13 @@ export interface Hooks {
121
121
 
122
122
  export interface SSRNode {
123
123
  module: SSRComponent;
124
- entry: string; // client-side module corresponding to this component
124
+ /** client-side module URL for this component */
125
+ entry: string;
126
+ /** external CSS files */
125
127
  css: string[];
128
+ /** external JS files */
126
129
  js: string[];
130
+ /** inlined styles */
127
131
  styles: string[];
128
132
  }
129
133