@eslym/sveltekit-adapter-bun 2.0.0 → 2.0.3

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/README.md CHANGED
@@ -10,7 +10,8 @@ The built bundle with version `2.0.0` will be ready to compile into single execu
10
10
  bun add -d @eslym/sveltekit-adapter-bun
11
11
  ```
12
12
 
13
- > [!IMPORTANT] > **Breaking Changes**
13
+ > [!IMPORTANT]
14
+ > **Breaking Changes**
14
15
  >
15
16
  > Since version `2.0.0`, the custom hooks (`beforeServe`, `afterServe` and `setupCLI`) and CLI functionality is complemetely removed.
16
17
 
@@ -95,10 +96,12 @@ export type AdapterOptions = {
95
96
  bundler?: 'rollup' | 'bun';
96
97
 
97
98
  /**
98
- * Enable pre-compress
99
+ * Enable pre-compress, use number to specify a minimum file size which will be compressed.
100
+ * When it is true, the minimum size is 1KiB.
101
+ *
99
102
  * @default false
100
103
  */
101
- precompress?: boolean | PreCompressOptions;
104
+ precompress?: boolean | PreCompressOptions | number;
102
105
 
103
106
  /**
104
107
  * Serve static assets, set if to false if you want to handle static assets yourself
@@ -142,6 +145,22 @@ export type AdapterOptions = {
142
145
  identifiers?: boolean;
143
146
  };
144
147
  };
148
+
149
+ export type PreCompressOptions = {
150
+ /**
151
+ * Enable specific compression, number means the minimum size to compress.
152
+ * 1KiB will be used when the value is `true`, set to `0` for always compress.
153
+ *
154
+ * @default true;
155
+ */
156
+ [k in 'gzip' | 'brotli']?: boolean | number;
157
+ } & {
158
+ /**
159
+ * Extensions to pre-compress
160
+ * @default ['html','js','json','css','svg','xml','wasm']
161
+ */
162
+ files?: string[];
163
+ };
145
164
  ```
146
165
 
147
166
  ## Runtime Environments
@@ -1,4 +1,6 @@
1
+ #!/usr/bin/env bun
1
2
  // @bun
3
+
2
4
  // src/files/server.ts
3
5
  import { Server } from "SERVER";
4
6
  import { manifest } from "MANIFEST";
@@ -12,7 +14,6 @@ await server.init({
12
14
 
13
15
  // src/files/utils.ts
14
16
  var urls = new WeakMap;
15
- var basePath = Symbol.for("app.basepath");
16
17
  function get_url(request) {
17
18
  if (!urls.has(request)) {
18
19
  urls.set(request, new URL(request.url));
@@ -23,16 +24,10 @@ function set_url(request, url) {
23
24
  urls.set(request, url);
24
25
  return url;
25
26
  }
26
- function get_basepath() {
27
- return globalThis[basePath] || "";
28
- }
29
- function set_basepath(path) {
30
- globalThis[basePath] = path;
31
- }
32
27
 
33
28
  // src/files/static.ts
34
29
  import { normalize } from "path/posix";
35
- import { assets } from "sveltekit-adapter-bun:assets";
30
+ import { assets } from "ASSETS";
36
31
  var headersMap = ["last-modified", "etag", "content-length"];
37
32
  var methods = new Set(["HEAD", "GET"]);
38
33
  function lookup(pathname) {
@@ -72,7 +67,7 @@ function parse_range(header) {
72
67
  return [true, +match[3], null];
73
68
  return [true, +match[1], match[2] ? +match[2] + 1 : null];
74
69
  }
75
- function serve(request, basePath2) {
70
+ async function serve_static({ request }) {
76
71
  if (!methods.has(request.method))
77
72
  return;
78
73
  const url = get_url(request);
@@ -166,9 +161,6 @@ function serve(request, basePath2) {
166
161
  headers
167
162
  });
168
163
  }
169
- var serve_static = SERVE_STATIC ? serve : () => {
170
- return;
171
- };
172
164
 
173
165
  // src/files/handle.ts
174
166
  function clone_req(url, request) {
@@ -194,13 +186,13 @@ async function first_resolve(request, resolvers) {
194
186
  return response;
195
187
  }
196
188
  }
197
- function override_origin(args, origin) {
189
+ function override_origin(origin, args) {
198
190
  const url = get_url(args.request);
199
191
  const newUrl = new URL(url.pathname + url.search, origin);
200
192
  args.request = clone_req(newUrl, args.request);
201
193
  set_url(args.request, newUrl);
202
194
  }
203
- function override_origin_with_header(args, hostHeader, protocolHeader) {
195
+ function override_origin_with_header(hostHeader, protocolHeader, args) {
204
196
  const url = get_url(args.request);
205
197
  let newUrl = new URL(url);
206
198
  if (hostHeader && args.request.headers.has(hostHeader)) {
@@ -220,14 +212,13 @@ function resolve_xff_ip(request, depth) {
220
212
  const ips = request.headers.get("x-forwarded-for").split(",");
221
213
  return ips.at(-depth) || undefined;
222
214
  }
223
- function create_fetch({
215
+ async function create_fetch({
224
216
  overrideOrigin,
225
217
  hostHeader,
226
218
  protocolHeader,
227
219
  ipHeader,
228
220
  xffDepth
229
221
  }) {
230
- const basePath2 = get_basepath();
231
222
  let getIp = undefined;
232
223
  if (ipHeader === "x-forwarded-for") {
233
224
  getIp = (req, fallback) => resolve_xff_ip(req, xffDepth) ?? fallback;
@@ -241,11 +232,13 @@ function create_fetch({
241
232
  return response;
242
233
  }
243
234
  if (overrideOrigin) {
244
- resolvers.push((args) => override_origin(args, new URL(overrideOrigin)));
235
+ resolvers.push(override_origin.bind(null, new URL(overrideOrigin)));
245
236
  } else if (hostHeader || protocolHeader) {
246
- resolvers.push((args) => override_origin_with_header(args, hostHeader, protocolHeader));
237
+ resolvers.push(override_origin_with_header.bind(null, hostHeader, protocolHeader));
238
+ }
239
+ if (SERVE_STATIC) {
240
+ resolvers.push(serve_static);
247
241
  }
248
- resolvers.push(({ request }) => serve_static(request, basePath2));
249
242
  return (request, srv) => {
250
243
  const request_ip = srv.requestIP(request)?.address;
251
244
  const try_get_ip = getIp ? () => getIp(request, request_ip) : () => request_ip;
@@ -385,8 +378,18 @@ function bool_env(fn, name, fallback = false) {
385
378
  }
386
379
 
387
380
  // src/files/index.ts
388
- set_basepath(import.meta.dir);
389
- async function serve2() {
381
+ import { resolve } from "path";
382
+ Bun.plugin({
383
+ name: "asset-module",
384
+ target: "bun",
385
+ setup(build) {
386
+ build.module("sveltekit-adapter-bun:assets", async () => ({
387
+ loader: "object",
388
+ exports: await import(resolve(import.meta.dir, "./assets"))
389
+ }));
390
+ }
391
+ });
392
+ async function serve() {
390
393
  const socket = http_env("SOCKET");
391
394
  const serverOptions = socket ? {
392
395
  unix: socket
@@ -398,7 +401,7 @@ async function serve2() {
398
401
  ...serverOptions,
399
402
  idleTimeout: duration_env(http_env, "IDLE_TIMEOUT", 30),
400
403
  maxRequestBodySize: bytes_env(http_env, "MAX_BODY", 128 * 1024 * 1024),
401
- fetch: create_fetch({
404
+ fetch: await create_fetch({
402
405
  overrideOrigin: http_env("OVERRIDE_ORIGIN"),
403
406
  hostHeader: http_env("HOST_HEADER"),
404
407
  protocolHeader: http_env("PROTOCOL_HEADER"),
@@ -432,7 +435,7 @@ async function serve2() {
432
435
  console.log(`Serving on ${server2.url}`);
433
436
  }
434
437
  if (Bun.main === Bun.fileURLToPath(import.meta.url)) {
435
- serve2();
438
+ serve();
436
439
  }
437
440
  export {
438
441
  create_fetch as createBunFetch
package/dist/index.js CHANGED
@@ -407,15 +407,21 @@ var T;
407
407
  }
408
408
  T.collect = collect;
409
409
  })(T ||= {});
410
+ function to_base36(n) {
411
+ return n.toString(36);
412
+ }
410
413
  function get_imports_n(imports, declared, import_path) {
411
414
  let n = declared.get(import_path);
412
415
  if (n === undefined) {
413
- n = imports.length;
414
- imports.push(T.concat(`import file${n} from `, T.stringify(import_path), ' with { type: "file" };'));
416
+ n = to_base36(imports.length);
417
+ imports.push(T.concat(`import f_${n} from `, T.stringify(import_path), ' with { type: "file" };'));
415
418
  declared.set(import_path, n);
416
419
  }
417
420
  return n;
418
421
  }
422
+ function normalize_path(path) {
423
+ return path.replace(/\\/g, "/");
424
+ }
419
425
  async function build_assets_js(base_path, client_files, prerendered_pages, immutable_prefix, ignores) {
420
426
  const imports = [];
421
427
  const records = [];
@@ -423,7 +429,8 @@ async function build_assets_js(base_path, client_files, prerendered_pages, immut
423
429
  for await (const path of client_files) {
424
430
  if (ignores.some((ignore) => ignore.match(path)))
425
431
  continue;
426
- records.push(await build_asset_record(declared, imports, path.replace(/^(?:\.?\/)?/, "/"), join(base_path, "client", path), "./" + join("client", path), immutable_prefix));
432
+ const normalized = normalize_path(path);
433
+ records.push(await build_asset_record(declared, imports, normalized.replace(/^(?:\.?\/)?/, "/"), join(base_path, "client", normalized), "./" + join("client", normalized), immutable_prefix));
427
434
  }
428
435
  for await (const [pathname, target] of prerendered_pages) {
429
436
  records.push(await build_asset_record(declared, imports, pathname, join(base_path, "prerendered", target.file), "./" + join("prerendered", target.file), immutable_prefix));
@@ -453,7 +460,7 @@ async function build_asset_record(declared, imports, pathname, filepath, import_
453
460
  `, T.indent(T.join([
454
461
  T.stringify(pathname),
455
462
  T.obj([
456
- ["file", T.fn("file", `file${file_n}`)],
463
+ ["file", T.fn("file", `f_${file_n}`)],
457
464
  ["immutable", pathname.startsWith(immutable_prefix) ? "true" : "false"],
458
465
  [
459
466
  "headers",
@@ -461,7 +468,7 @@ async function build_asset_record(declared, imports, pathname, filepath, import_
461
468
  ],
462
469
  [
463
470
  "compression",
464
- T.concat("[", br_n ? T.fn("file", `file${br_n}`) : "undefined", ", ", gz_n ? T.fn("file", `file${gz_n}`) : "undefined", "]")
471
+ T.concat("[", br_n ? T.fn("file", `f_${br_n}`) : "undefined", ", ", gz_n ? T.fn("file", `f_${gz_n}`) : "undefined", "]")
465
472
  ]
466
473
  ])
467
474
  ], `,
@@ -686,25 +693,18 @@ function adapter(userOpts = {}) {
686
693
  ]);
687
694
  }
688
695
  builder.log.minor("Building server");
689
- builder.writeServer(`${tmp}/server`);
690
- writeFileSync(`${tmp}/server/manifest.js`, `export const manifest = ${builder.generateManifest({ relativePath: "./" })};
696
+ builder.writeServer(tmp);
697
+ writeFileSync(`${tmp}/manifest.js`, `export const manifest = ${builder.generateManifest({ relativePath: "./" })};
691
698
 
692
699
  ` + `export const prerendered = new Set(${JSON.stringify(builder.prerendered.paths)});
693
700
  `);
694
701
  const pkg = JSON.parse(readFileSync("package.json", "utf8"));
695
- builder.copy(files, tmp, {
696
- replace: {
697
- SERVER: "./server/index.js",
698
- MANIFEST: "./server/manifest.js",
699
- SERVE_STATIC: opts.serveStatic ? "true" : "false"
700
- }
701
- });
702
702
  builder.log.minor("Bundling...");
703
703
  if (opts.bundler === "rollup") {
704
704
  const bundle = await rollup({
705
705
  input: {
706
706
  index: `${tmp}/index.js`,
707
- manifest: `${tmp}/server/manifest.js`
707
+ manifest: `${tmp}/manifest.js`
708
708
  },
709
709
  external: [
710
710
  assets_module,
@@ -723,20 +723,20 @@ function adapter(userOpts = {}) {
723
723
  }
724
724
  });
725
725
  await bundle.write({
726
- dir: out,
726
+ dir: `${out}/server`,
727
727
  format: "esm",
728
728
  sourcemap: opts.sourceMap,
729
- chunkFileNames: "server/[name]-[hash].js"
729
+ chunkFileNames: "chunks/[name]-[hash].js"
730
730
  });
731
731
  } else {
732
732
  const res = await Bun.build({
733
733
  target: "bun",
734
- entrypoints: [`${tmp}/index.js`, `${tmp}/server/manifest.js`],
735
- outdir: out,
734
+ entrypoints: [`${tmp}/index.js`, `${tmp}/manifest.js`],
735
+ outdir: `${out}/server`,
736
736
  sourcemap: opts.sourceMap === true ? "linked" : opts.sourceMap ? "inline" : "none",
737
737
  naming: {
738
738
  entry: "[name].[ext]",
739
- chunk: "server/[name]-[hash].[ext]"
739
+ chunk: "chunks/[name]-[hash].[ext]"
740
740
  },
741
741
  external: [assets_module, ...Object.keys(pkg.dependencies || {})],
742
742
  splitting: true,
@@ -760,8 +760,14 @@ function adapter(userOpts = {}) {
760
760
  process.exit(1);
761
761
  }
762
762
  }
763
- const index = await Bun.file(`${out}/index.js`).text();
764
- await Bun.write(`${out}/index.js`, index.replace(` from "${assets_module}"`, ' from "./assets.js"'));
763
+ builder.copy(files, out, {
764
+ replace: {
765
+ SERVER: "./server/index.js",
766
+ MANIFEST: "./server/manifest.js",
767
+ ASSETS: "./assets.js",
768
+ SERVE_STATIC: opts.serveStatic ? "true" : "false"
769
+ }
770
+ });
765
771
  const immutable = `${builder.config.kit.appDir}/immutable/`.replace(/^\/?/, "/");
766
772
  const staticIgnores = opts.staticIgnores.map((p) => new Bun.Glob(p));
767
773
  const clientFiles = new Bun.Glob("**/*");
@@ -771,7 +777,8 @@ function adapter(userOpts = {}) {
771
777
  dot: true,
772
778
  absolute: false,
773
779
  onlyFiles: true
774
- }), builder.prerendered.pages, immutable, staticIgnores) : "export const assets = new Map();";
780
+ }), builder.prerendered.pages, immutable, staticIgnores) : `// @bun
781
+ export const assets = new Map();`;
775
782
  await Bun.write(`${out}/assets.js`, assets_js);
776
783
  if ("patchedDependencies" in pkg) {
777
784
  const deps = Object.keys(pkg.devDependencies || {});
@@ -829,11 +836,12 @@ function adapter(userOpts = {}) {
829
836
  }
830
837
  };
831
838
  }
839
+ var default_minimum_size = 1024;
832
840
  async function compress(directory, options) {
833
841
  if (!existsSync(directory)) {
834
842
  return;
835
843
  }
836
- const files_ext = options === true || !options.files ? ["html", "js", "json", "css", "svg", "xml", "wasm"] : options.files;
844
+ const files_ext = options === true || typeof options === "number" || !options.files ? ["html", "js", "json", "css", "svg", "xml", "wasm"] : options.files;
837
845
  const glob = new Bun.Glob(`**/*.{${files_ext.join()}}`);
838
846
  const files2 = [
839
847
  ...glob.scanSync({
@@ -845,12 +853,20 @@ async function compress(directory, options) {
845
853
  ];
846
854
  let doBr = false, doGz = false;
847
855
  if (options === true) {
848
- doBr = doGz = true;
856
+ doBr = doGz = default_minimum_size;
857
+ } else if (typeof options == "number") {
858
+ doBr = doGz = options;
849
859
  } else if (typeof options == "object") {
850
- doBr = options.brotli ?? false;
851
- doGz = options.gzip ?? false;
860
+ doBr = typeof options.brotli === "number" ? options.brotli : options.brotli ? default_minimum_size : false;
861
+ doGz = typeof options.gzip === "number" ? options.gzip : options.gzip ? default_minimum_size : false;
852
862
  }
853
- await Promise.all(files2.map((file) => Promise.all([doGz && compress_file(file, "gz"), doBr && compress_file(file, "br")])));
863
+ await Promise.all(files2.map((file) => {
864
+ const size = Bun.file(file).size;
865
+ return Promise.all([
866
+ doGz !== false && size >= doGz && compress_file(file, "gz"),
867
+ doBr !== false && size >= doBr && compress_file(file, "br")
868
+ ]);
869
+ }));
854
870
  }
855
871
  async function compress_file(file, format = "gz") {
856
872
  if (format === "br" && typeof zlib.createBrotliCompress !== "function") {
package/dist/types.d.ts CHANGED
@@ -88,15 +88,6 @@ export interface AdapterPlatform {
88
88
  */
89
89
  markForUpgrade(response: Response, ws: WebSocketHandler): Response;
90
90
  }
91
- export type PreCompressOptions = {
92
- [k in 'gzip' | 'brotli']?: boolean;
93
- } & {
94
- /**
95
- * Extensions to pre-compress
96
- * @default ['html','js','json','css','svg','xml','wasm']
97
- */
98
- files?: string[];
99
- };
100
91
  export type AdapterOptions = {
101
92
  /**
102
93
  * Output path
@@ -109,10 +100,12 @@ export type AdapterOptions = {
109
100
  */
110
101
  bundler?: 'rollup' | 'bun';
111
102
  /**
112
- * Enable pre-compress
103
+ * Enable pre-compress, use number to specify a minimum file size which will be compressed.
104
+ * When it is true, the minimum size is 1KiB.
105
+ *
113
106
  * @default false
114
107
  */
115
- precompress?: boolean | PreCompressOptions;
108
+ precompress?: boolean | PreCompressOptions | number;
116
109
  /**
117
110
  * Serve static assets, set if to false if you want to handle static assets yourself
118
111
  * like using nginx or caddy. When it is true, an index of assets will build with
@@ -149,4 +142,13 @@ export type AdapterOptions = {
149
142
  identifiers?: boolean;
150
143
  };
151
144
  };
145
+ export type PreCompressOptions = {
146
+ [k in 'gzip' | 'brotli']?: boolean | number;
147
+ } & {
148
+ /**
149
+ * Extensions to pre-compress
150
+ * @default ['html','js','json','css','svg','xml','wasm']
151
+ */
152
+ files?: string[];
153
+ };
152
154
  export {};
package/package.json CHANGED
@@ -34,5 +34,5 @@
34
34
  "@rollup/plugin-node-resolve": "^15.3.1",
35
35
  "rollup": "^4.34.8"
36
36
  },
37
- "version": "2.0.0"
37
+ "version": "2.0.3"
38
38
  }