bun-types 1.1.39-canary.20241204T140703 → 1.1.39-canary.20241206T140546

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/bun.d.ts CHANGED
@@ -14,6 +14,7 @@
14
14
  * This module aliases `globalThis.Bun`.
15
15
  */
16
16
  declare module "bun" {
17
+ import type { FFIFunctionCallableSymbol } from "bun:ffi";
17
18
  import type { Encoding as CryptoEncoding } from "crypto";
18
19
  import type {
19
20
  CipherNameAndProtocol,
@@ -4043,7 +4044,11 @@ declare module "bun" {
4043
4044
  defer: () => Promise<void>;
4044
4045
  }
4045
4046
 
4046
- type OnLoadResult = OnLoadResultSourceCode | OnLoadResultObject | undefined;
4047
+ type OnLoadResult =
4048
+ | OnLoadResultSourceCode
4049
+ | OnLoadResultObject
4050
+ | undefined
4051
+ | void;
4047
4052
  type OnLoadCallback = (
4048
4053
  args: OnLoadArgs,
4049
4054
  ) => OnLoadResult | Promise<OnLoadResult>;
@@ -4099,7 +4104,34 @@ declare module "bun" {
4099
4104
  | undefined
4100
4105
  | null;
4101
4106
 
4107
+ type FFIFunctionCallable = Function & {
4108
+ // Making a nominally typed function so that the user must get it from dlopen
4109
+ readonly __ffi_function_callable: typeof FFIFunctionCallableSymbol;
4110
+ };
4111
+
4102
4112
  interface PluginBuilder {
4113
+ /**
4114
+ * Register a callback which will be invoked when bundling starts.
4115
+ * @example
4116
+ * ```ts
4117
+ * Bun.plugin({
4118
+ * setup(builder) {
4119
+ * builder.onStart(() => {
4120
+ * console.log("bundle just started!!")
4121
+ * });
4122
+ * },
4123
+ * });
4124
+ * ```
4125
+ */
4126
+ onStart(callback: OnStartCallback): void;
4127
+ onBeforeParse(
4128
+ constraints: PluginConstraints,
4129
+ callback: {
4130
+ napiModule: unknown;
4131
+ symbol: string;
4132
+ external?: unknown | undefined;
4133
+ },
4134
+ ): void;
4103
4135
  /**
4104
4136
  * Register a callback to load imports with a specific import specifier
4105
4137
  * @param constraints The constraints to apply the plugin to
@@ -4135,20 +4167,6 @@ declare module "bun" {
4135
4167
  constraints: PluginConstraints,
4136
4168
  callback: OnResolveCallback,
4137
4169
  ): void;
4138
- /**
4139
- * Register a callback which will be invoked when bundling starts.
4140
- * @example
4141
- * ```ts
4142
- * Bun.plugin({
4143
- * setup(builder) {
4144
- * builder.onStart(() => {
4145
- * console.log("bundle just started!!")
4146
- * });
4147
- * },
4148
- * });
4149
- * ```
4150
- */
4151
- onStart(callback: OnStartCallback): void;
4152
4170
  /**
4153
4171
  * The config object passed to `Bun.build` as is. Can be mutated.
4154
4172
  */
@@ -30,7 +30,6 @@ Bun implements the vast majority of Jest's matchers, but compatibility isn't 100
30
30
 
31
31
  Some notable missing features:
32
32
 
33
- - `expect().toMatchInlineSnapshot()`
34
33
  - `expect().toHaveReturned()`
35
34
 
36
35
  ---
@@ -4,10 +4,6 @@ name: Use snapshot testing in `bun test`
4
4
 
5
5
  Bun's test runner supports Jest-style snapshot testing via `.toMatchSnapshot()`.
6
6
 
7
- {% callout %}
8
- The `.toMatchInlineSnapshot()` method is not yet supported.
9
- {% /callout %}
10
-
11
7
  ```ts#snap.test.ts
12
8
  import { test, expect } from "bun:test";
13
9
 
@@ -96,4 +92,4 @@ Ran 1 tests across 1 files. [102.00ms]
96
92
 
97
93
  ---
98
94
 
99
- See [Docs > Test Runner > Snapshots](https://bun.sh/docs/test/mocks) for complete documentation on mocking with the Bun test runner.
95
+ See [Docs > Test Runner > Snapshots](https://bun.sh/docs/test/snapshots) for complete documentation on snapshots with the Bun test runner.
@@ -4,10 +4,6 @@ name: Update snapshots in `bun test`
4
4
 
5
5
  Bun's test runner supports Jest-style snapshot testing via `.toMatchSnapshot()`.
6
6
 
7
- {% callout %}
8
- The `.toMatchInlineSnapshot()` method is not yet supported.
9
- {% /callout %}
10
-
11
7
  ```ts#snap.test.ts
12
8
  import { test, expect } from "bun:test";
13
9
 
@@ -47,4 +43,4 @@ Ran 1 tests across 1 files. [102.00ms]
47
43
 
48
44
  ---
49
45
 
50
- See [Docs > Test Runner > Snapshots](https://bun.sh/docs/test/mocks) for complete documentation on mocking with the Bun test runner.
46
+ See [Docs > Test Runner > Snapshots](https://bun.sh/docs/test/snapshots) for complete documentation on snapshots with the Bun test runner.
@@ -355,7 +355,7 @@ Bun.build({
355
355
 
356
356
  {% /callout %}
357
357
 
358
- ## Lifecycle callbacks
358
+ ## Lifecycle hooks
359
359
 
360
360
  Plugins can register callbacks to be run at various points in the lifecycle of a bundle:
361
361
 
@@ -363,6 +363,8 @@ Plugins can register callbacks to be run at various points in the lifecycle of a
363
363
  - [`onResolve()`](#onresolve): Run before a module is resolved
364
364
  - [`onLoad()`](#onload): Run before a module is loaded.
365
365
 
366
+ ### Reference
367
+
366
368
  A rough overview of the types (please refer to Bun's `bun.d.ts` for the full type definitions):
367
369
 
368
370
  ```ts
@@ -603,3 +605,98 @@ plugin({
603
605
  ```
604
606
 
605
607
  Note that the `.defer()` function currently has the limitation that it can only be called once per `onLoad` callback.
608
+
609
+ ## Native plugins
610
+
611
+ {% callout %}
612
+ **NOTE** — This is an advanced and experiemental API recommended for plugin developers who are familiar with systems programming and the C ABI. Use with caution.
613
+ {% /callout %}
614
+
615
+ One of the reasons why Bun's bundler is so fast is that it is written in native code and leverages multi-threading to load and parse modules in parallel.
616
+
617
+ However, one limitation of plugins written in JavaScript is that JavaScript itself is single-threaded.
618
+
619
+ Native plugins are written as [NAPI](/docs/node-api) modules and can be run on multiple threads. This allows native plugins to run much faster than JavaScript plugins.
620
+
621
+ In addition, native plugins can skip unnecessary work such as the UTF-8 -> UTF-16 conversion needed to pass strings to JavaScript.
622
+
623
+ These are the following lifecycle hooks which are available to native plugins:
624
+
625
+ - [`onBeforeParse()`](#onbeforeparse): Called on any thread before a file is parsed by Bun's bundler.
626
+
627
+ ### Creating a native plugin
628
+
629
+ Native plugins are NAPI modules which expose lifecycle hooks as C ABI functions.
630
+
631
+ To create a native plugin, you must export a C ABI function which matches the signature of the native lifecycle hook you want to implement.
632
+
633
+ #### Example: Rust with napi-rs
634
+
635
+ First initialize a napi project (see [here](https://napi.rs/docs/introduction/getting-started) for a more comprehensive guide).
636
+
637
+ Then install Bun's official safe plugin wrapper crate:
638
+
639
+ ```bash
640
+ cargo add bun-native-plugin
641
+ ```
642
+
643
+ Now you can export an `extern "C" fn` which is the implementation of your plugin:
644
+
645
+ ```rust
646
+ #[no_mangle]
647
+ extern "C" fn on_before_parse_impl(
648
+ args: *const bun_native_plugin::sys::OnBeforeParseArguments,
649
+ result: *mut bun_native_plugin::sys::OnBeforeParseResult,
650
+ ) {
651
+ let args = unsafe { &*args };
652
+ let result = unsafe { &mut *result };
653
+
654
+ let mut handle = match bun_native_plugin::OnBeforeParse::from_raw(args, result) {
655
+ Ok(handle) => handle,
656
+ Err(_) => {
657
+ return;
658
+ }
659
+ };
660
+
661
+ let source_code = match handle.input_source_code() {
662
+ Ok(source_code) => source_code,
663
+ Err(_) => {
664
+ handle.log_error("Fetching source code failed!");
665
+ return;
666
+ }
667
+ };
668
+
669
+ let loader = handle.output_loader();
670
+ handle.set_output_source_code(source_code.replace("foo", "bar"), loader);
671
+ ```
672
+
673
+ Use napi-rs to compile the plugin to a `.node` file, then you can `require()` it from JS and use it:
674
+
675
+ ```js
676
+ await Bun.build({
677
+ entrypoints: ["index.ts"],
678
+ setup(build) {
679
+ const myNativePlugin = require("./path/to/plugin.node");
680
+
681
+ build.onBeforeParse(
682
+ { filter: /\.ts/ },
683
+ { napiModule: myNativePlugin, symbol: "on_before_parse_impl" },
684
+ );
685
+ },
686
+ });
687
+ ```
688
+
689
+ ### `onBeforeParse`
690
+
691
+ ```ts
692
+ onBeforeParse(
693
+ args: { filter: RegExp; namespace?: string },
694
+ callback: { napiModule: NapiModule; symbol: string; external?: unknown },
695
+ ): void;
696
+ ```
697
+
698
+ This lifecycle callback is run immediately before a file is parsed by Bun's bundler.
699
+
700
+ As input, it receives the file's contents and can optionally return new source code.
701
+
702
+ This callback can be called from any thread and so the napi module implementation must be thread-safe.
@@ -531,17 +531,17 @@ Bun implements the following matchers. Full Jest compatibility is on the roadmap
531
531
 
532
532
  ---
533
533
 
534
- -
534
+ -
535
535
  - [`.toMatchInlineSnapshot()`](https://jestjs.io/docs/expect#tomatchinlinesnapshotpropertymatchers-inlinesnapshot)
536
536
 
537
537
  ---
538
538
 
539
- -
539
+ -
540
540
  - [`.toThrowErrorMatchingSnapshot()`](https://jestjs.io/docs/expect#tothrowerrormatchingsnapshothint)
541
541
 
542
542
  ---
543
543
 
544
- -
544
+ -
545
545
  - [`.toThrowErrorMatchingInlineSnapshot()`](https://jestjs.io/docs/expect#tothrowerrormatchinginlinesnapshotinlinesnapshot)
546
546
 
547
547
  {% /table %}
package/ffi.d.ts CHANGED
@@ -570,17 +570,22 @@ declare module "bun:ffi" {
570
570
  ? FFITypeStringToType[T]
571
571
  : never;
572
572
 
573
+ const FFIFunctionCallableSymbol: unique symbol;
573
574
  type ConvertFns<Fns extends Symbols> = {
574
- [K in keyof Fns]: (
575
- ...args: Fns[K]["args"] extends infer A extends readonly FFITypeOrString[]
576
- ? { [L in keyof A]: FFITypeToArgsType[ToFFIType<A[L]>] }
577
- : // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type
578
- [unknown] extends [Fns[K]["args"]]
579
- ? []
580
- : never
581
- ) => [unknown] extends [Fns[K]["returns"]] // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type
582
- ? undefined
583
- : FFITypeToReturnsType[ToFFIType<NonNullable<Fns[K]["returns"]>>];
575
+ [K in keyof Fns]: {
576
+ (
577
+ ...args: Fns[K]["args"] extends infer A extends
578
+ readonly FFITypeOrString[]
579
+ ? { [L in keyof A]: FFITypeToArgsType[ToFFIType<A[L]>] }
580
+ : // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type
581
+ [unknown] extends [Fns[K]["args"]]
582
+ ? []
583
+ : never
584
+ ): [unknown] extends [Fns[K]["returns"]] // eslint-disable-next-line @definitelytyped/no-single-element-tuple-type
585
+ ? undefined
586
+ : FFITypeToReturnsType[ToFFIType<NonNullable<Fns[K]["returns"]>>];
587
+ __ffi_function_callable: typeof FFIFunctionCallableSymbol;
588
+ };
584
589
  };
585
590
 
586
591
  /**
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.39-canary.20241204T140703",
2
+ "version": "1.1.39-canary.20241206T140546",
3
3
  "name": "bun-types",
4
4
  "license": "MIT",
5
5
  "main": "",
package/test.d.ts CHANGED
@@ -1358,6 +1358,57 @@ declare module "bun:test" {
1358
1358
  * @param hint Hint used to identify the snapshot in the snapshot file.
1359
1359
  */
1360
1360
  toMatchSnapshot(propertyMatchers?: object, hint?: string): void;
1361
+ /**
1362
+ * Asserts that a value matches the most recent inline snapshot.
1363
+ *
1364
+ * @example
1365
+ * expect("Hello").toMatchInlineSnapshot();
1366
+ * expect("Hello").toMatchInlineSnapshot(`"Hello"`);
1367
+ *
1368
+ * @param value The latest automatically-updated snapshot value.
1369
+ */
1370
+ toMatchInlineSnapshot(value?: string): void;
1371
+ /**
1372
+ * Asserts that a value matches the most recent inline snapshot.
1373
+ *
1374
+ * @example
1375
+ * expect({ c: new Date() }).toMatchInlineSnapshot({ c: expect.any(Date) });
1376
+ * expect({ c: new Date() }).toMatchInlineSnapshot({ c: expect.any(Date) }, `
1377
+ * {
1378
+ * "v": Any<Date>,
1379
+ * }
1380
+ * `);
1381
+ *
1382
+ * @param propertyMatchers Object containing properties to match against the value.
1383
+ * @param value The latest automatically-updated snapshot value.
1384
+ */
1385
+ toMatchInlineSnapshot(propertyMatchers?: object, value?: string): void;
1386
+ /**
1387
+ * Asserts that a function throws an error matching the most recent snapshot.
1388
+ *
1389
+ * @example
1390
+ * function fail() {
1391
+ * throw new Error("Oops!");
1392
+ * }
1393
+ * expect(fail).toThrowErrorMatchingSnapshot();
1394
+ * expect(fail).toThrowErrorMatchingSnapshot("This one should say Oops!");
1395
+ *
1396
+ * @param value The latest automatically-updated snapshot value.
1397
+ */
1398
+ toThrowErrorMatchingSnapshot(hint?: string): void;
1399
+ /**
1400
+ * Asserts that a function throws an error matching the most recent snapshot.
1401
+ *
1402
+ * @example
1403
+ * function fail() {
1404
+ * throw new Error("Oops!");
1405
+ * }
1406
+ * expect(fail).toThrowErrorMatchingInlineSnapshot();
1407
+ * expect(fail).toThrowErrorMatchingInlineSnapshot(`"Oops!"`);
1408
+ *
1409
+ * @param value The latest automatically-updated snapshot value.
1410
+ */
1411
+ toThrowErrorMatchingInlineSnapshot(value?: string): void;
1361
1412
  /**
1362
1413
  * Asserts that an object matches a subset of properties.
1363
1414
  *