koffi 3.1.0 → 3.1.1

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/CHANGELOG.md CHANGED
@@ -7,12 +7,19 @@
7
7
 
8
8
  ### Koffi 3.1
9
9
 
10
+ #### Koffi 3.1.1
11
+
12
+ *Released on 2026-07-10*
13
+
14
+ - Restore missing Windows ARM64 build
15
+ - Slightly optimize memory allocation routines
16
+
10
17
  #### Koffi 3.1.0
11
18
 
12
19
  *Released on 2026-06-29*
13
20
 
14
21
  - Add endian-sensitive integer decoding functions
15
- - Drop required but useless type specifier from `lib.symbol()`
22
+ - Drop useless but required type specifier from `lib.symbol()`
16
23
  - Add `wstring` type alias for wide strings
17
24
  - Add platform-dependent `koffi.decode.wstring()` function
18
25
  - Improve performance of various functions and value conversions
@@ -20,7 +27,7 @@
20
27
  - Fix static native loading from the koffi ESM entry point ([@yibe](https://codeberg.org/yibe))
21
28
  - Fix minor memory and reference leaks on exit
22
29
  - Fix length argument types in TypeScript definition
23
- - Reorganize documentation pages
30
+ - Reorganize documentation
24
31
 
25
32
  ### Koffi 3.0
26
33
 
package/cnoke.cjs CHANGED
@@ -22,16 +22,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
 
25
- // ../cnoke/cnoke.js
25
+ // src/cnoke/cnoke.js
26
26
  var import_node_fs4 = __toESM(require("node:fs"), 1);
27
27
 
28
- // ../cnoke/src/builder.js
28
+ // src/cnoke/src/builder.js
29
29
  var import_node_fs3 = __toESM(require("node:fs"), 1);
30
30
  var import_node_os = __toESM(require("node:os"), 1);
31
31
  var import_node_path = __toESM(require("node:path"), 1);
32
32
  var import_node_child_process = require("node:child_process");
33
33
 
34
- // ../cnoke/src/abi.js
34
+ // src/cnoke/src/abi.js
35
35
  var import_node_fs = __toESM(require("node:fs"), 1);
36
36
  function determineAbi() {
37
37
  let abi = process.arch.toString();
@@ -121,7 +121,7 @@ function decodeElfHeader(buf) {
121
121
  return header;
122
122
  }
123
123
 
124
- // ../cnoke/src/util.js
124
+ // src/cnoke/src/util.js
125
125
  var import_node_fs2 = __toESM(require("node:fs"), 1);
126
126
  function pathIsAbsolute(path2) {
127
127
  if (process.platform == "win32" && path2.match(/^[a-zA-Z]:/))
@@ -194,7 +194,7 @@ function compareVersions(ver1, ver2) {
194
194
  return cmp;
195
195
  }
196
196
 
197
- // ../cnoke/src/assets.js
197
+ // src/cnoke/src/assets.js
198
198
  var FIND_CNOKE_CMAKE = `# SPDX-License-Identifier: MIT
199
199
  # SPDX-FileCopyrightText: 2026 Niels Martign\xE8ne <niels.martignene@protonmail.com>
200
200
 
@@ -361,7 +361,7 @@ const PfnDliHook __pfnDliNotifyHook2 = self_exe_hook;
361
361
  #endif
362
362
  `;
363
363
 
364
- // ../cnoke/src/builder.js
364
+ // src/cnoke/src/builder.js
365
365
  var DefaultOptions = {
366
366
  mode: "RelWithDebInfo"
367
367
  };
@@ -650,7 +650,7 @@ function Builder(config = {}) {
650
650
  }
651
651
  }
652
652
 
653
- // ../cnoke/cnoke.js
653
+ // src/cnoke/cnoke.js
654
654
  var VALID_COMMANDS = ["build", "configure", "clean"];
655
655
  main();
656
656
  async function main() {
package/doc/callbacks.md CHANGED
@@ -9,7 +9,7 @@ import koffi from 'koffi';
9
9
  // With the classic syntax, this callback expects an integer and returns nothing
10
10
  const ExampleCallback = koffi.proto('ExampleCallback', 'void', ['int']);
11
11
 
12
- // With the prototype parser, this callback expects a double and float, and returns the sum as a double
12
+ // With the prototype parser, this callback expects a double and float, and returns a double
13
13
  const AddDoubleFloat = koffi.proto('double AddDoubleFloat(double d, float f)');
14
14
  ```
15
15
 
@@ -186,15 +186,12 @@ void *MallocAllocator::Resize(void *ptr, Size old_size, Size new_size)
186
186
  {
187
187
  if (!new_size) {
188
188
  Release(ptr, old_size);
189
- ptr = nullptr;
190
- } else {
191
- void *new_ptr = realloc(ptr, (size_t)new_size);
192
- K_CRITICAL(new_ptr || !new_size, "Failed to resize %1 memory block to %2",
193
- FmtMemSize(old_size), FmtMemSize(new_size));
194
-
195
- ptr = new_ptr;
189
+ return nullptr;
196
190
  }
197
191
 
192
+ ptr = realloc(ptr, (size_t)new_size);
193
+ K_CRITICAL(ptr || !new_size, "Failed to resize %1 memory block to %2", FmtMemSize(old_size), FmtMemSize(new_size));
194
+
198
195
  return ptr;
199
196
  }
200
197
 
@@ -216,6 +213,8 @@ Allocator *GetNullAllocator()
216
213
  LinkedAllocator& LinkedAllocator::operator=(LinkedAllocator &&other)
217
214
  {
218
215
  ReleaseAll();
216
+
217
+ allocator = other.allocator;
219
218
  list = other.list;
220
219
  other.list = nullptr;
221
220
 
@@ -363,10 +362,13 @@ BlockAllocator& BlockAllocator::operator=(BlockAllocator &&other)
363
362
  allocator.operator=(std::move(other.allocator));
364
363
 
365
364
  block_size = other.block_size;
366
- current_bucket = other.current_bucket;
365
+
366
+ bucket_ptr = other.bucket_ptr;
367
+ bucket_end = other.bucket_end;
367
368
  last_alloc = other.last_alloc;
368
369
 
369
- other.current_bucket = nullptr;
370
+ other.bucket_ptr = nullptr;
371
+ other.bucket_end = nullptr;
370
372
  other.last_alloc = nullptr;
371
373
 
372
374
  return *this;
@@ -374,19 +376,23 @@ BlockAllocator& BlockAllocator::operator=(BlockAllocator &&other)
374
376
 
375
377
  void BlockAllocator::Reset()
376
378
  {
377
- last_alloc = nullptr;
379
+ if (bucket_ptr) {
380
+ bucket_ptr = bucket_end - block_size;
378
381
 
379
- if (current_bucket) {
380
- current_bucket->used = 0;
381
- allocator.ReleaseAllExcept(current_bucket);
382
+ // Not true but Resize code assumes that last_alloc is not null when a bucket exists.
383
+ // I could also let it as-is, but for some reason I find that less clean.
384
+ last_alloc = bucket_ptr;
385
+
386
+ allocator.ReleaseAllExcept(bucket_ptr);
382
387
  } else {
383
- allocator.ReleaseAll();
388
+ ReleaseAll();
384
389
  }
385
390
  }
386
391
 
387
392
  void BlockAllocator::ReleaseAll()
388
393
  {
389
- current_bucket = nullptr;
394
+ bucket_ptr = nullptr;
395
+ bucket_end = nullptr;
390
396
  last_alloc = nullptr;
391
397
 
392
398
  allocator.ReleaseAll();
@@ -396,88 +402,78 @@ void *BlockAllocator::Allocate(Size size)
396
402
  {
397
403
  K_ASSERT(size >= 0);
398
404
 
399
- // Keep alignement requirements
400
- Size aligned_size = AlignLen(size, 8);
405
+ uint8_t *ptr = bucket_ptr;
406
+
407
+ // Fast path
408
+ if (uint8_t *new_ptr = AlignUp(ptr + size, 8); new_ptr <= bucket_end) [[likely]] {
409
+ bucket_ptr = new_ptr;
401
410
 
402
- if (AllocateSeparately(aligned_size)) {
403
- uint8_t *ptr = (uint8_t *)allocator.Allocate(size);
411
+ last_alloc = ptr;
404
412
  return ptr;
405
- } else {
406
- if (!current_bucket || (current_bucket->used + aligned_size) > block_size) {
407
- current_bucket = (Bucket *)allocator.Allocate(K_SIZE(Bucket) + block_size);
408
- current_bucket->used = 0;
409
- }
413
+ }
410
414
 
411
- uint8_t *ptr = current_bucket->data + current_bucket->used;
412
- current_bucket->used += aligned_size;
415
+ if (size <= block_size) {
416
+ bucket_ptr = (uint8_t *)allocator.Allocate(block_size);
417
+ bucket_end = bucket_ptr + block_size;
418
+
419
+ ptr = bucket_ptr;
420
+ bucket_ptr = AlignUp(ptr + size, 8);
413
421
 
414
422
  last_alloc = ptr;
415
423
  return ptr;
416
424
  }
425
+
426
+ // Fallback for big allocations
427
+ return allocator.Allocate(size);
417
428
  }
418
429
 
419
430
  void *BlockAllocator::Resize(void *ptr, Size old_size, Size new_size)
420
431
  {
421
432
  K_ASSERT(old_size >= 0);
422
433
  K_ASSERT(new_size >= 0);
434
+ K_ASSERT(ptr || !old_size);
423
435
 
424
436
  if (!new_size) {
425
437
  Release(ptr, old_size);
426
- ptr = nullptr;
427
- } else {
428
- if (!ptr) {
429
- old_size = 0;
430
- }
438
+ return nullptr;
439
+ }
431
440
 
432
- Size aligned_old_size = AlignLen(old_size, 8);
433
- Size aligned_new_size = AlignLen(new_size, 8);
434
- Size aligned_delta = aligned_new_size - aligned_old_size;
441
+ // Fast path
442
+ if (uint8_t *new_ptr = AlignUp((uint8_t *)ptr + new_size, 8); ptr == last_alloc && new_ptr <= bucket_end) {
443
+ K_ASSERT(ptr);
435
444
 
436
- // Try fast path
437
- if (ptr && ptr == last_alloc &&
438
- (current_bucket->used + aligned_delta) <= block_size &&
439
- !AllocateSeparately(aligned_new_size)) {
440
- current_bucket->used += aligned_delta;
441
- } else if (AllocateSeparately(aligned_old_size)) {
442
- ptr = allocator.Resize(ptr, old_size, new_size);
443
- } else {
444
- void *new_ptr = Allocate(new_size);
445
+ bucket_ptr = new_ptr;
446
+ return ptr;
447
+ }
445
448
 
446
- Size copy = std::min(old_size, new_size);
447
- MemCpy(new_ptr, ptr, copy);
449
+ if (old_size <= block_size) {
450
+ uint8_t *copy_ptr = (uint8_t *)Allocate(new_size);
451
+ Size copy_len = std::min(old_size, new_size);
448
452
 
449
- ptr = new_ptr;
450
- }
453
+ MemCpy(copy_ptr, ptr, copy_len);
454
+
455
+ return copy_ptr;
451
456
  }
452
457
 
453
- return ptr;
458
+ // Old allocation fell back to separate allocation, we can resize at will now!
459
+ return allocator.Resize(ptr, old_size, new_size);
454
460
  }
455
461
 
456
462
  void BlockAllocator::Release(const void *ptr, Size size)
457
463
  {
458
464
  K_ASSERT(size >= 0);
459
465
 
460
- if (ptr) {
461
- Size aligned_size = AlignLen(size, 8);
462
-
463
- if (ptr == last_alloc) {
464
- current_bucket->used -= aligned_size;
465
-
466
- if (!current_bucket->used) {
467
- allocator.Release(current_bucket, K_SIZE(Bucket) + block_size);
468
- current_bucket = nullptr;
469
- }
470
-
471
- last_alloc = nullptr;
472
- } else if (AllocateSeparately(aligned_size)) {
473
- allocator.Release(ptr, size);
474
- }
466
+ if (ptr == last_alloc) {
467
+ bucket_ptr = last_alloc;
468
+ } else if (size > block_size) {
469
+ allocator.Release(ptr, size);
475
470
  }
476
471
  }
477
472
 
478
473
  void BlockAllocator::GiveTo(LinkedAllocator *alloc)
479
474
  {
480
- current_bucket = nullptr;
475
+ bucket_ptr = nullptr;
476
+ bucket_end = nullptr;
481
477
  last_alloc = nullptr;
482
478
 
483
479
  allocator.GiveTo(alloc);
@@ -5689,8 +5685,13 @@ Size ReadCommandOutput(const char *cmd_line, Span<uint8_t> out_output)
5689
5685
  };
5690
5686
 
5691
5687
  int exit_code;
5692
- if (!ExecuteCommandLine(cmd_line, info, MakeSpan((const uint8_t *)nullptr, 0), write, &exit_code))
5688
+ if (!ExecuteCommandLine(cmd_line, info, MakeSpan((const uint8_t *)nullptr, 0), write, &exit_code)) {
5689
+ if (out_output.len) {
5690
+ Span<const char> output = out_output.As<const char>();
5691
+ LogError("Command '%1' failed: %2", cmd_line, output);
5692
+ }
5693
5693
  return -1;
5694
+ }
5694
5695
  if (exit_code) {
5695
5696
  LogDebug("Command '%1' failed (exit code: %2)", cmd_line, exit_code);
5696
5697
  return -1;
@@ -5706,17 +5707,26 @@ bool ReadCommandOutput(const char *cmd_line, HeapArray<uint8_t> *out_output)
5706
5707
  { "LC_ALL", "C" }
5707
5708
  };
5708
5709
 
5710
+ Size start_len = out_output->len;
5711
+ K_DEFER_N(err_guard) { out_output->RemoveFrom(start_len); };
5712
+
5709
5713
  ExecuteInfo info = {};
5710
5714
  info.env_variables = variables;
5711
5715
 
5712
5716
  int exit_code;
5713
- if (!ExecuteCommandLine(cmd_line, info, {}, Mebibytes(1), out_output, &exit_code))
5717
+ if (!ExecuteCommandLine(cmd_line, info, {}, Mebibytes(1), out_output, &exit_code)) {
5718
+ if (out_output->len > start_len) {
5719
+ Span<const char> output = out_output->Take(start_len, out_output->len - start_len).As<const char>();
5720
+ LogError("Command '%1' failed: %2", cmd_line, output);
5721
+ }
5714
5722
  return false;
5723
+ }
5715
5724
  if (exit_code) {
5716
5725
  LogDebug("Command '%1' failed (exit code: %2)", cmd_line, exit_code);
5717
5726
  return false;
5718
5727
  }
5719
5728
 
5729
+ err_guard.Disable();
5720
5730
  return true;
5721
5731
  }
5722
5732
 
@@ -467,21 +467,30 @@ constexpr T BigEndian(T v) { return ReverseBytes(v); }
467
467
 
468
468
  static inline Size AlignLen(Size len, Size align)
469
469
  {
470
- Size aligned = (len + align - 1) / align * align;
470
+ K_ASSERT(align >= 1 && !((align - 1) & align));
471
+
472
+ // Compilers can optimize x / align * align... for unsigned types.
473
+ // It's pessimized for signed types, to handle len < 0.
474
+
475
+ Size aligned = (len + align - 1) & ~(align - 1);
471
476
  return aligned;
472
477
  }
473
478
 
474
479
  template <typename T>
475
480
  static inline T *AlignUp(T *ptr, Size align)
476
481
  {
477
- uint8_t *aligned = (uint8_t *)(((uintptr_t)ptr + align - 1) / align * align);
482
+ K_ASSERT(align >= 1 && !((align - 1) & align));
483
+
484
+ uint8_t *aligned = (uint8_t *)(((uintptr_t)ptr + align - 1) & ~(align - 1));
478
485
  return (T *)aligned;
479
486
  }
480
487
 
481
488
  template <typename T>
482
489
  static inline T *AlignDown(T *ptr, Size align)
483
490
  {
484
- uint8_t *aligned = (uint8_t *)((uintptr_t)ptr / align * align);
491
+ K_ASSERT(align >= 1 && !((align - 1) & align));
492
+
493
+ uint8_t *aligned = (uint8_t *)((uintptr_t)ptr & ~(align - 1));
485
494
  return (T *)aligned;
486
495
  }
487
496
 
@@ -1157,15 +1166,11 @@ private:
1157
1166
  };
1158
1167
 
1159
1168
  class BlockAllocator final: public Allocator {
1160
- struct Bucket {
1161
- Size used;
1162
- uint8_t data[];
1163
- };
1164
-
1165
1169
  LinkedAllocator allocator;
1166
1170
  Size block_size;
1167
1171
 
1168
- Bucket *current_bucket = nullptr;
1172
+ uint8_t *bucket_ptr = nullptr;
1173
+ uint8_t *bucket_end = nullptr;
1169
1174
  uint8_t *last_alloc = nullptr;
1170
1175
 
1171
1176
  public:
@@ -1191,9 +1196,6 @@ public:
1191
1196
 
1192
1197
  void GiveTo(LinkedAllocator *alloc);
1193
1198
  void GiveTo(BlockAllocator *alloc) { GiveTo(&alloc->allocator); }
1194
-
1195
- private:
1196
- bool AllocateSeparately(Size aligned_size) const { return aligned_size > block_size / 2; }
1197
1199
  };
1198
1200
 
1199
1201
  static inline void *AllocateRaw(Allocator *alloc, Size size)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
4
4
  "description": "Fast and easy-to-use dynamic C FFI (foreign function interface) for Node.js",
5
5
  "keywords": [
6
6
  "foreign",
@@ -33,20 +33,21 @@
33
33
  },
34
34
  "funding": "https://liberapay.com/Koromix",
35
35
  "optionalDependencies": {
36
- "@koromix/koffi-linux-arm64": "3.1.0",
37
- "@koromix/koffi-linux-ia32": "3.1.0",
38
- "@koromix/koffi-linux-x64": "3.1.0",
39
- "@koromix/koffi-linux-riscv64": "3.1.0",
40
- "@koromix/koffi-freebsd-ia32": "3.1.0",
41
- "@koromix/koffi-freebsd-x64": "3.1.0",
42
- "@koromix/koffi-freebsd-arm64": "3.1.0",
43
- "@koromix/koffi-openbsd-ia32": "3.1.0",
44
- "@koromix/koffi-openbsd-x64": "3.1.0",
45
- "@koromix/koffi-win32-ia32": "3.1.0",
46
- "@koromix/koffi-win32-x64": "3.1.0",
47
- "@koromix/koffi-darwin-x64": "3.1.0",
48
- "@koromix/koffi-darwin-arm64": "3.1.0",
49
- "@koromix/koffi-linux-loong64": "3.1.0"
36
+ "@koromix/koffi-linux-arm64": "3.1.1",
37
+ "@koromix/koffi-linux-ia32": "3.1.1",
38
+ "@koromix/koffi-linux-x64": "3.1.1",
39
+ "@koromix/koffi-linux-riscv64": "3.1.1",
40
+ "@koromix/koffi-freebsd-ia32": "3.1.1",
41
+ "@koromix/koffi-freebsd-x64": "3.1.1",
42
+ "@koromix/koffi-freebsd-arm64": "3.1.1",
43
+ "@koromix/koffi-openbsd-ia32": "3.1.1",
44
+ "@koromix/koffi-openbsd-x64": "3.1.1",
45
+ "@koromix/koffi-win32-ia32": "3.1.1",
46
+ "@koromix/koffi-win32-x64": "3.1.1",
47
+ "@koromix/koffi-win32-arm64": "3.1.1",
48
+ "@koromix/koffi-darwin-x64": "3.1.1",
49
+ "@koromix/koffi-darwin-arm64": "3.1.1",
50
+ "@koromix/koffi-linux-loong64": "3.1.1"
50
51
  },
51
52
  "type": "module",
52
53
  "main": "./index.cjs",
@@ -34,7 +34,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
34
34
  ));
35
35
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
36
36
 
37
- // ../cnoke/src/abi.js
37
+ // src/cnoke/src/abi.js
38
38
  function determineAbi() {
39
39
  let abi = process.arch.toString();
40
40
  if (abi == "riscv32" || abi == "riscv64") {
@@ -124,20 +124,20 @@ function decodeElfHeader(buf) {
124
124
  }
125
125
  var import_node_fs;
126
126
  var init_abi = __esm({
127
- "../cnoke/src/abi.js"() {
127
+ "src/cnoke/src/abi.js"() {
128
128
  import_node_fs = __toESM(require("node:fs"), 1);
129
129
  }
130
130
  });
131
131
 
132
- // package.json
132
+ // src/koffi/package.json
133
133
  var package_default;
134
134
  var init_package = __esm({
135
- "package.json"() {
136
- package_default = { name: "koffi", version: "3.1.0", cnoke: { api: "../../vendor/node-api-headers", output: "../../bin/Koffi/{{ toolchain }}", node: 16, napi: 8 } };
135
+ "src/koffi/package.json"() {
136
+ package_default = { name: "koffi", version: "3.1.1", cnoke: { api: "../../vendor/node-api-headers", output: "../../bin/Koffi/{{ toolchain }}", node: 16, napi: 8 } };
137
137
  }
138
138
  });
139
139
 
140
- // src/init.js
140
+ // src/koffi/src/init.js
141
141
  var init_exports = {};
142
142
  __export(init_exports, {
143
143
  detectPlatform: () => detectPlatform,
@@ -233,7 +233,7 @@ function wrapNative(native2, version2) {
233
233
  }
234
234
  var import_node_util, import_node_fs2, import_node_module, require2;
235
235
  var init_init = __esm({
236
- "src/init.js"() {
236
+ "src/koffi/src/init.js"() {
237
237
  import_node_util = __toESM(require("node:util"));
238
238
  import_node_fs2 = __toESM(require("node:fs"));
239
239
  import_node_module = require("node:module");
@@ -243,7 +243,7 @@ var init_init = __esm({
243
243
  }
244
244
  });
245
245
 
246
- // index.cjs
246
+ // src/koffi/index.cjs
247
247
  var { detectPlatform: detectPlatform2, loadDynamic: loadDynamic2, wrapNative: wrapNative2 } = (init_init(), __toCommonJS(init_exports));
248
248
  var { loadStatic } = require("./src/static.cjs");
249
249
  var [version, pkg, triplets] = detectPlatform2();
@@ -1,9 +1,9 @@
1
- // src/init.js
1
+ // src/koffi/src/init.js
2
2
  import util from "node:util";
3
3
  import fs2 from "node:fs";
4
4
  import { createRequire } from "node:module";
5
5
 
6
- // ../cnoke/src/abi.js
6
+ // src/cnoke/src/abi.js
7
7
  import fs from "node:fs";
8
8
  function determineAbi() {
9
9
  let abi = process.arch.toString();
@@ -93,10 +93,10 @@ function decodeElfHeader(buf) {
93
93
  return header;
94
94
  }
95
95
 
96
- // package.json
97
- var package_default = { name: "koffi", version: "3.1.0", cnoke: { api: "../../vendor/node-api-headers", output: "../../bin/Koffi/{{ toolchain }}", node: 16, napi: 8 } };
96
+ // src/koffi/package.json
97
+ var package_default = { name: "koffi", version: "3.1.1", cnoke: { api: "../../vendor/node-api-headers", output: "../../bin/Koffi/{{ toolchain }}", node: 16, napi: 8 } };
98
98
 
99
- // src/init.js
99
+ // src/koffi/src/init.js
100
100
  var require2 = createRequire(import.meta.url);
101
101
  function detectPlatform() {
102
102
  if (process.versions.napi == null || process.versions.napi < package_default.cnoke.napi) {
@@ -186,7 +186,7 @@ function wrapNative(native2, version2) {
186
186
  }
187
187
  }
188
188
 
189
- // index.js
189
+ // src/koffi/index.js
190
190
  import { loadStatic } from "./src/static.js";
191
191
  var [version, pkg, triplets] = detectPlatform();
192
192
  var native = loadStatic(pkg) ?? loadDynamic(import.meta.dirname, pkg, triplets);
@@ -34,7 +34,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
34
34
  ));
35
35
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
36
36
 
37
- // ../cnoke/src/abi.js
37
+ // src/cnoke/src/abi.js
38
38
  function determineAbi() {
39
39
  let abi = process.arch.toString();
40
40
  if (abi == "riscv32" || abi == "riscv64") {
@@ -124,20 +124,20 @@ function decodeElfHeader(buf) {
124
124
  }
125
125
  var import_node_fs;
126
126
  var init_abi = __esm({
127
- "../cnoke/src/abi.js"() {
127
+ "src/cnoke/src/abi.js"() {
128
128
  import_node_fs = __toESM(require("node:fs"), 1);
129
129
  }
130
130
  });
131
131
 
132
- // package.json
132
+ // src/koffi/package.json
133
133
  var package_default;
134
134
  var init_package = __esm({
135
- "package.json"() {
136
- package_default = { name: "koffi", version: "3.1.0", cnoke: { api: "../../vendor/node-api-headers", output: "../../bin/Koffi/{{ toolchain }}", node: 16, napi: 8 } };
135
+ "src/koffi/package.json"() {
136
+ package_default = { name: "koffi", version: "3.1.1", cnoke: { api: "../../vendor/node-api-headers", output: "../../bin/Koffi/{{ toolchain }}", node: 16, napi: 8 } };
137
137
  }
138
138
  });
139
139
 
140
- // src/init.js
140
+ // src/koffi/src/init.js
141
141
  var init_exports = {};
142
142
  __export(init_exports, {
143
143
  detectPlatform: () => detectPlatform,
@@ -233,7 +233,7 @@ function wrapNative(native2, version2) {
233
233
  }
234
234
  var import_node_util, import_node_fs2, import_node_module, require2;
235
235
  var init_init = __esm({
236
- "src/init.js"() {
236
+ "src/koffi/src/init.js"() {
237
237
  import_node_util = __toESM(require("node:util"));
238
238
  import_node_fs2 = __toESM(require("node:fs"));
239
239
  import_node_module = require("node:module");
@@ -243,7 +243,7 @@ var init_init = __esm({
243
243
  }
244
244
  });
245
245
 
246
- // indirect.cjs
246
+ // src/koffi/indirect.cjs
247
247
  var { detectPlatform: detectPlatform2, loadDynamic: loadDynamic2, wrapNative: wrapNative2 } = (init_init(), __toCommonJS(init_exports));
248
248
  var [version, pkg, triplets] = detectPlatform2();
249
249
  var native = loadDynamic2(__dirname, pkg, triplets);
@@ -1,9 +1,9 @@
1
- // src/init.js
1
+ // src/koffi/src/init.js
2
2
  import util from "node:util";
3
3
  import fs2 from "node:fs";
4
4
  import { createRequire } from "node:module";
5
5
 
6
- // ../cnoke/src/abi.js
6
+ // src/cnoke/src/abi.js
7
7
  import fs from "node:fs";
8
8
  function determineAbi() {
9
9
  let abi = process.arch.toString();
@@ -93,10 +93,10 @@ function decodeElfHeader(buf) {
93
93
  return header;
94
94
  }
95
95
 
96
- // package.json
97
- var package_default = { name: "koffi", version: "3.1.0", cnoke: { api: "../../vendor/node-api-headers", output: "../../bin/Koffi/{{ toolchain }}", node: 16, napi: 8 } };
96
+ // src/koffi/package.json
97
+ var package_default = { name: "koffi", version: "3.1.1", cnoke: { api: "../../vendor/node-api-headers", output: "../../bin/Koffi/{{ toolchain }}", node: 16, napi: 8 } };
98
98
 
99
- // src/init.js
99
+ // src/koffi/src/init.js
100
100
  var require2 = createRequire(import.meta.url);
101
101
  function detectPlatform() {
102
102
  if (process.versions.napi == null || process.versions.napi < package_default.cnoke.napi) {
@@ -186,7 +186,7 @@ function wrapNative(native2, version2) {
186
186
  }
187
187
  }
188
188
 
189
- // indirect.js
189
+ // src/koffi/indirect.js
190
190
  var [version, pkg, triplets] = detectPlatform();
191
191
  var native = loadDynamic(import.meta.dirname, pkg, triplets);
192
192
  wrapNative(native, version);
@@ -92,6 +92,14 @@ function loadStatic(pkg) {
92
92
  }
93
93
  }
94
94
 
95
+ if (pkg == 'win32-arm64') {
96
+ try {
97
+ native = require('@koromix/koffi-win32-arm64');
98
+ } catch (err) {
99
+ // Go on
100
+ }
101
+ }
102
+
95
103
  if (pkg == 'darwin-x64') {
96
104
  try {
97
105
  native = require('@koromix/koffi-darwin-x64');
@@ -95,6 +95,14 @@ function loadStatic(pkg) {
95
95
  }
96
96
  }
97
97
 
98
+ if (pkg == 'win32-arm64') {
99
+ try {
100
+ native = require('@koromix/koffi-win32-arm64');
101
+ } catch (err) {
102
+ // Go on
103
+ }
104
+ }
105
+
98
106
  if (pkg == 'darwin-x64') {
99
107
  try {
100
108
  native = require('@koromix/koffi-darwin-x64');