@lakutata/ffi 0.0.0-stage → 3.1.2
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/LICENSE +23 -0
- package/README.md +163 -2
- package/README.zh-CN.md +140 -0
- package/dist/cjs/components/NativeLibrary.d.ts +229 -0
- package/dist/cjs/components/NativeLibrary.js +346 -0
- package/dist/cjs/decorators/Library.d.ts +61 -0
- package/dist/cjs/decorators/Library.js +44 -0
- package/dist/cjs/decorators/Native.d.ts +69 -0
- package/dist/cjs/decorators/Native.js +90 -0
- package/dist/cjs/exceptions/NativeDeclarationException.d.ts +12 -0
- package/dist/cjs/exceptions/NativeDeclarationException.js +19 -0
- package/dist/cjs/exceptions/NativeLibraryClosedException.d.ts +12 -0
- package/dist/cjs/exceptions/NativeLibraryClosedException.js +19 -0
- package/dist/cjs/exceptions/NativeLibraryNotFoundException.d.ts +11 -0
- package/dist/cjs/exceptions/NativeLibraryNotFoundException.js +18 -0
- package/dist/cjs/exceptions/NativeMemoryException.d.ts +11 -0
- package/dist/cjs/exceptions/NativeMemoryException.js +18 -0
- package/dist/cjs/exports/FFI.d.ts +12 -0
- package/dist/cjs/exports/FFI.js +40 -0
- package/dist/cjs/exports/Generator.d.ts +2 -0
- package/dist/cjs/exports/Generator.js +10 -0
- package/dist/cjs/lib/Memory.d.ts +188 -0
- package/dist/cjs/lib/Memory.js +227 -0
- package/dist/cjs/lib/Runtime.d.ts +98 -0
- package/dist/cjs/lib/Runtime.js +209 -0
- package/dist/cjs/lib/backend/Functions.d.ts +65 -0
- package/dist/cjs/lib/backend/Functions.js +214 -0
- package/dist/cjs/lib/backend/KoffiTypes.d.ts +53 -0
- package/dist/cjs/lib/backend/KoffiTypes.js +426 -0
- package/dist/cjs/lib/declarations/Builtins.d.ts +33 -0
- package/dist/cjs/lib/declarations/Builtins.js +179 -0
- package/dist/cjs/lib/declarations/Layout.d.ts +41 -0
- package/dist/cjs/lib/declarations/Layout.js +180 -0
- package/dist/cjs/lib/declarations/Lexer.d.ts +40 -0
- package/dist/cjs/lib/declarations/Lexer.js +325 -0
- package/dist/cjs/lib/declarations/Parser.d.ts +90 -0
- package/dist/cjs/lib/declarations/Parser.js +1425 -0
- package/dist/cjs/lib/declarations/Platform.d.ts +50 -0
- package/dist/cjs/lib/declarations/Platform.js +27 -0
- package/dist/cjs/lib/declarations/Types.d.ts +173 -0
- package/dist/cjs/lib/declarations/Types.js +179 -0
- package/dist/cjs/lib/generator/CText.d.ts +14 -0
- package/dist/cjs/lib/generator/CText.js +133 -0
- package/dist/cjs/lib/generator/Generator.d.ts +136 -0
- package/dist/cjs/lib/generator/Generator.js +395 -0
- package/dist/cjs/lib/generator/Preprocessor.d.ts +60 -0
- package/dist/cjs/lib/generator/Preprocessor.js +94 -0
- package/dist/cjs/lib/generator/TypeScriptTypes.d.ts +35 -0
- package/dist/cjs/lib/generator/TypeScriptTypes.js +153 -0
- package/dist/cjs/lib/library/NativeCallback.d.ts +44 -0
- package/dist/cjs/lib/library/NativeCallback.js +66 -0
- package/dist/cjs/lib/library/NativeLibraryHandle.d.ts +268 -0
- package/dist/cjs/lib/library/NativeLibraryHandle.js +540 -0
- package/dist/cjs/lib/library/Resolve.d.ts +49 -0
- package/dist/cjs/lib/library/Resolve.js +130 -0
- package/dist/cjs/lib/thread/NativeThreads.d.ts +80 -0
- package/dist/cjs/lib/thread/NativeThreads.js +384 -0
- package/dist/cjs/lib/thread/NativeWorker.d.ts +6 -0
- package/dist/cjs/lib/thread/NativeWorker.js +96 -0
- package/dist/cjs/lib/thread/NativeWorkerCode.d.ts +5 -0
- package/dist/cjs/lib/thread/NativeWorkerCode.js +4 -0
- package/dist/cjs/lib/thread/PackageRequire.d.ts +6 -0
- package/dist/cjs/lib/thread/PackageRequire.js +4 -0
- package/dist/cjs/lib/thread/ThreadProtocol.d.ts +77 -0
- package/dist/cjs/lib/thread/ThreadProtocol.js +2 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/components/NativeLibrary.js +338 -0
- package/dist/esm/decorators/Library.js +40 -0
- package/dist/esm/decorators/Native.js +85 -0
- package/dist/esm/exceptions/NativeDeclarationException.js +15 -0
- package/dist/esm/exceptions/NativeLibraryClosedException.js +15 -0
- package/dist/esm/exceptions/NativeLibraryNotFoundException.js +14 -0
- package/dist/esm/exceptions/NativeMemoryException.js +14 -0
- package/dist/esm/exports/FFI.js +10 -0
- package/dist/esm/exports/Generator.js +2 -0
- package/dist/esm/lib/Memory.js +210 -0
- package/dist/esm/lib/Runtime.js +192 -0
- package/dist/esm/lib/backend/Functions.js +206 -0
- package/dist/esm/lib/backend/KoffiTypes.js +418 -0
- package/dist/esm/lib/declarations/Builtins.js +174 -0
- package/dist/esm/lib/declarations/Layout.js +175 -0
- package/dist/esm/lib/declarations/Lexer.js +321 -0
- package/dist/esm/lib/declarations/Parser.js +1421 -0
- package/dist/esm/lib/declarations/Platform.js +23 -0
- package/dist/esm/lib/declarations/Types.js +170 -0
- package/dist/esm/lib/generator/CText.js +129 -0
- package/dist/esm/lib/generator/Generator.js +388 -0
- package/dist/esm/lib/generator/Preprocessor.js +87 -0
- package/dist/esm/lib/generator/TypeScriptTypes.js +149 -0
- package/dist/esm/lib/library/NativeCallback.js +59 -0
- package/dist/esm/lib/library/NativeLibraryHandle.js +532 -0
- package/dist/esm/lib/library/Resolve.js +122 -0
- package/dist/esm/lib/thread/NativeThreads.js +377 -0
- package/dist/esm/lib/thread/NativeWorker.js +93 -0
- package/dist/esm/lib/thread/NativeWorkerCode.js +1 -0
- package/dist/esm/lib/thread/PackageRequire.js +2 -0
- package/dist/esm/lib/thread/ThreadProtocol.js +1 -0
- package/dist/types/components/NativeLibrary.d.ts +229 -0
- package/dist/types/decorators/Library.d.ts +61 -0
- package/dist/types/decorators/Native.d.ts +69 -0
- package/dist/types/exceptions/NativeDeclarationException.d.ts +12 -0
- package/dist/types/exceptions/NativeLibraryClosedException.d.ts +12 -0
- package/dist/types/exceptions/NativeLibraryNotFoundException.d.ts +11 -0
- package/dist/types/exceptions/NativeMemoryException.d.ts +11 -0
- package/dist/types/exports/FFI.d.ts +12 -0
- package/dist/types/exports/Generator.d.ts +2 -0
- package/dist/types/lib/Memory.d.ts +188 -0
- package/dist/types/lib/Runtime.d.ts +98 -0
- package/dist/types/lib/backend/Functions.d.ts +65 -0
- package/dist/types/lib/backend/KoffiTypes.d.ts +53 -0
- package/dist/types/lib/declarations/Builtins.d.ts +33 -0
- package/dist/types/lib/declarations/Layout.d.ts +41 -0
- package/dist/types/lib/declarations/Lexer.d.ts +40 -0
- package/dist/types/lib/declarations/Parser.d.ts +90 -0
- package/dist/types/lib/declarations/Platform.d.ts +50 -0
- package/dist/types/lib/declarations/Types.d.ts +173 -0
- package/dist/types/lib/generator/CText.d.ts +14 -0
- package/dist/types/lib/generator/Generator.d.ts +136 -0
- package/dist/types/lib/generator/Preprocessor.d.ts +60 -0
- package/dist/types/lib/generator/TypeScriptTypes.d.ts +35 -0
- package/dist/types/lib/library/NativeCallback.d.ts +44 -0
- package/dist/types/lib/library/NativeLibraryHandle.d.ts +268 -0
- package/dist/types/lib/library/Resolve.d.ts +49 -0
- package/dist/types/lib/thread/NativeThreads.d.ts +80 -0
- package/dist/types/lib/thread/NativeWorker.d.ts +6 -0
- package/dist/types/lib/thread/NativeWorkerCode.d.ts +5 -0
- package/dist/types/lib/thread/PackageRequire.d.ts +6 -0
- package/dist/types/lib/thread/ThreadProtocol.d.ts +77 -0
- package/package.json +85 -4
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { type Pointer } from '../Runtime.js';
|
|
2
|
+
import { NativeCallback } from './NativeCallback.js';
|
|
3
|
+
import { type LibraryNames } from './Resolve.js';
|
|
4
|
+
/**
|
|
5
|
+
* Where a library is found, and how it is closed
|
|
6
|
+
*/
|
|
7
|
+
export interface NativeLibraryOptions {
|
|
8
|
+
/**
|
|
9
|
+
* The file of the library: the only one tried when given.
|
|
10
|
+
*/
|
|
11
|
+
path?: string;
|
|
12
|
+
/**
|
|
13
|
+
* The directories tried before the ones of the system, in their order (aliases of the application allowed).
|
|
14
|
+
*/
|
|
15
|
+
search?: string[];
|
|
16
|
+
/**
|
|
17
|
+
* The directory of the libraries of a packaged application, tried after the search directories.
|
|
18
|
+
*/
|
|
19
|
+
packaged?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Whether the library stays loaded once closed (its callbacks are released all the same).
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
keepLoaded?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* On Windows, the C library the functions of the library use, whose errno `errno()` reads.
|
|
27
|
+
* @default 'ucrtbase.dll'
|
|
28
|
+
*/
|
|
29
|
+
crt?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Handles the exceptions thrown by the persistent callbacks (the library gets zero as their result).
|
|
32
|
+
* @default writes them to the console
|
|
33
|
+
*/
|
|
34
|
+
onCallbackError?: (error: unknown) => void;
|
|
35
|
+
/**
|
|
36
|
+
* The worker threads of the library, which run its asynchronous functions: 0 for the thread pool of the runtime
|
|
37
|
+
* (the one of libuv in Node.js, shared with the file system); with one thread, the asynchronous calls run one after
|
|
38
|
+
* the other, in their order (a library that is not thread-safe). The synchronous functions run in the thread
|
|
39
|
+
* calling them.
|
|
40
|
+
* @default 0
|
|
41
|
+
*/
|
|
42
|
+
threads?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* How a function is bound
|
|
46
|
+
*/
|
|
47
|
+
export interface NativeFunctionOptions {
|
|
48
|
+
/**
|
|
49
|
+
* Whether it runs in another thread, returning a promise: for the functions that block. It runs in the threads of
|
|
50
|
+
* the library when it has some (`threads`), else in the thread pool of the runtime (Node.js runs them in the pool
|
|
51
|
+
* of libuv, 4 threads by default, shared with the file system: raise UV_THREADPOOL_SIZE for many of them), where a
|
|
52
|
+
* variadic function cannot be asynchronous.
|
|
53
|
+
* @default false
|
|
54
|
+
*/
|
|
55
|
+
async?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Frees the strings the function gives (its result, its output strings) once read: the name of the function of the
|
|
58
|
+
* library that frees them (`sqlite3_free`), or true for free() of the C library. On Windows, a library built with
|
|
59
|
+
* another C library must be given its own function.
|
|
60
|
+
*/
|
|
61
|
+
free?: string | boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Its 64-bit integers (its result, its output integers) as numbers rather than bigints: a RangeError when one is not
|
|
64
|
+
* a safe integer.
|
|
65
|
+
* @default 'bigint'
|
|
66
|
+
*/
|
|
67
|
+
int64?: 'bigint' | 'number';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A variable a library exports
|
|
71
|
+
*/
|
|
72
|
+
export interface NativeVariableAccessor<T = unknown> {
|
|
73
|
+
/**
|
|
74
|
+
* Its address.
|
|
75
|
+
*/
|
|
76
|
+
readonly address: Pointer;
|
|
77
|
+
/**
|
|
78
|
+
* Its value (an array of char of unknown length is read as a string).
|
|
79
|
+
*/
|
|
80
|
+
get(): T;
|
|
81
|
+
/**
|
|
82
|
+
* Change its value.
|
|
83
|
+
* @param value The value.
|
|
84
|
+
* @throws {NativeDeclarationException} When it is const.
|
|
85
|
+
*/
|
|
86
|
+
set(value: T): void;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* A native library loaded with its declarations, without the container (scripts, tests): its functions, variables and
|
|
90
|
+
* callbacks, and the native memory read and written with its types. Made by {@link loadNativeLibrary}; a
|
|
91
|
+
* `NativeLibrary` component holds one.
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* import {loadNativeLibrary, type NativeLibraryHandle} from '@lakutata/ffi'
|
|
95
|
+
*
|
|
96
|
+
* const libc: NativeLibraryHandle = loadNativeLibrary('c', 'typedef struct { int quot; int rem; } div_t;')
|
|
97
|
+
* const div = libc.func<(numerator: number, denominator: number) => {quot: number, rem: number}>('div_t div(int numerator, int denominator)')
|
|
98
|
+
* console.log(div(17, 5))
|
|
99
|
+
* await libc.close()
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export declare class NativeLibraryHandle {
|
|
103
|
+
#private;
|
|
104
|
+
/**
|
|
105
|
+
* Load a library (see {@link loadNativeLibrary}).
|
|
106
|
+
* @param names Its file names: one, or one by platform; `c` for the C library.
|
|
107
|
+
* @param declarations Its C declarations: the types, functions and variables its functions use.
|
|
108
|
+
* @param options Where it is found, how it is closed.
|
|
109
|
+
*/
|
|
110
|
+
constructor(names: LibraryNames, declarations?: string, options?: NativeLibraryOptions);
|
|
111
|
+
/**
|
|
112
|
+
* The file the library was loaded from.
|
|
113
|
+
*/
|
|
114
|
+
get file(): string;
|
|
115
|
+
/**
|
|
116
|
+
* Whether it is closed.
|
|
117
|
+
*/
|
|
118
|
+
get closed(): boolean;
|
|
119
|
+
/**
|
|
120
|
+
* The asynchronous calls running.
|
|
121
|
+
*/
|
|
122
|
+
get pending(): number;
|
|
123
|
+
/**
|
|
124
|
+
* The worker threads of the library (0: the asynchronous calls run in the thread pool of the runtime).
|
|
125
|
+
*/
|
|
126
|
+
get threads(): number;
|
|
127
|
+
/**
|
|
128
|
+
* Settled once the threads of the library have loaded it (at once without threads): rejected with the error of a
|
|
129
|
+
* thread that could not. The asynchronous calls wait for them anyway.
|
|
130
|
+
*/
|
|
131
|
+
get ready(): Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* The constants of its declarations: the values of the enumerations, of the static constants and of the macros whose
|
|
134
|
+
* value is an integer.
|
|
135
|
+
*/
|
|
136
|
+
get constants(): Readonly<Record<string, bigint>>;
|
|
137
|
+
/**
|
|
138
|
+
* Add C declarations to the ones of the library (and of the libraries loaded with the same declarations, which share
|
|
139
|
+
* them).
|
|
140
|
+
* @param text The declarations.
|
|
141
|
+
*/
|
|
142
|
+
declare(text: string): void;
|
|
143
|
+
/**
|
|
144
|
+
* A function of the library, from its prototype: the function of koffi itself when nothing has to be converted.
|
|
145
|
+
* @param prototype Its C prototype, with the types of the declarations: `int sqlite3_open(const char *filename,
|
|
146
|
+
* _Out_ sqlite3 **db)`.
|
|
147
|
+
* @param options Whether it is asynchronous, how its strings are freed, how its 64-bit integers are given.
|
|
148
|
+
* @returns The function.
|
|
149
|
+
*/
|
|
150
|
+
func<T extends (...args: any[]) => any = (...args: any[]) => any>(prototype: string, options?: NativeFunctionOptions): T;
|
|
151
|
+
/**
|
|
152
|
+
* A function of the declarations, by its name.
|
|
153
|
+
* @param name Its name.
|
|
154
|
+
* @param options Whether it is asynchronous, how its strings are freed, how its 64-bit integers are given.
|
|
155
|
+
* @returns The function.
|
|
156
|
+
*/
|
|
157
|
+
function<T extends (...args: any[]) => any = (...args: any[]) => any>(name: string, options?: NativeFunctionOptions): T;
|
|
158
|
+
/**
|
|
159
|
+
* A variable the library exports: declared in the declarations (`extern const char sqlite3_version[];`), or by the
|
|
160
|
+
* declaration given.
|
|
161
|
+
* @param declaration Its name, or its declaration.
|
|
162
|
+
* @returns Its address, and the functions reading and writing its value.
|
|
163
|
+
*/
|
|
164
|
+
variable<T = unknown>(declaration: string): NativeVariableAccessor<T>;
|
|
165
|
+
/**
|
|
166
|
+
* A persistent callback: a JS function the library can call at any time, released by `release()` or when the
|
|
167
|
+
* library is closed.
|
|
168
|
+
* @param type Its type: the name of a pointer-to-function type of the declarations (`vendor_log`), or its prototype
|
|
169
|
+
* (`void vendor_log(int level, const char *message)`).
|
|
170
|
+
* @param callback The JS function.
|
|
171
|
+
* @returns The callback, whose `pointer` is given to the library.
|
|
172
|
+
*/
|
|
173
|
+
callback(type: string, callback: (...args: any[]) => any): NativeCallback;
|
|
174
|
+
/**
|
|
175
|
+
* Read native memory, as a type of the declarations: a value, or an array of values.
|
|
176
|
+
* @param pointer The address.
|
|
177
|
+
* @param type The type: `int`, `struct timeval`, `char *` (a string).
|
|
178
|
+
* @param count The number of values, for an array.
|
|
179
|
+
* @returns The value, or the array.
|
|
180
|
+
*/
|
|
181
|
+
read<T = unknown>(pointer: Pointer, type: string, count?: number): T;
|
|
182
|
+
/**
|
|
183
|
+
* Write a value to native memory, as a type of the declarations.
|
|
184
|
+
* @param pointer The address.
|
|
185
|
+
* @param type The type.
|
|
186
|
+
* @param value The value.
|
|
187
|
+
*/
|
|
188
|
+
write(pointer: Pointer, type: string, value: unknown): void;
|
|
189
|
+
/**
|
|
190
|
+
* The size of a type of the declarations, in bytes.
|
|
191
|
+
* @param type The type.
|
|
192
|
+
*/
|
|
193
|
+
sizeOf(type: string): number;
|
|
194
|
+
/**
|
|
195
|
+
* The offset of a member of a struct of the declarations, in bytes.
|
|
196
|
+
* @param type The struct.
|
|
197
|
+
* @param member The member.
|
|
198
|
+
*/
|
|
199
|
+
offsetOf(type: string, member: string): number;
|
|
200
|
+
/**
|
|
201
|
+
* Allocate native memory for values of a type of the declarations: memory that does not move, which the library can
|
|
202
|
+
* keep; freed by `free()`, or when the library is closed.
|
|
203
|
+
* @param type The type.
|
|
204
|
+
* @param count The number of values.
|
|
205
|
+
* @returns Its address.
|
|
206
|
+
*/
|
|
207
|
+
alloc(type: string, count?: number): Pointer;
|
|
208
|
+
/**
|
|
209
|
+
* Free memory allocated by `alloc()`.
|
|
210
|
+
* @param pointer Its address.
|
|
211
|
+
*/
|
|
212
|
+
free(pointer: Pointer): void;
|
|
213
|
+
/**
|
|
214
|
+
* The errno of the last call of this thread (on Windows, the one of the C library given by the `crt` option); with
|
|
215
|
+
* threads, the one of the thread of the last asynchronous call completed (reliable with one thread, or when the
|
|
216
|
+
* asynchronous calls are awaited one at a time).
|
|
217
|
+
*/
|
|
218
|
+
errno(): number;
|
|
219
|
+
/**
|
|
220
|
+
* The last error of the Windows API (GetLastError) after the last call of this thread; with threads, the one of the
|
|
221
|
+
* thread of the last asynchronous call completed; undefined on the other systems.
|
|
222
|
+
*/
|
|
223
|
+
windowsError(): number | undefined;
|
|
224
|
+
/**
|
|
225
|
+
* The asynchronous calls running, once they have all returned.
|
|
226
|
+
* @param timeout How long to wait at most, in milliseconds.
|
|
227
|
+
* @returns Whether they have all returned.
|
|
228
|
+
*/
|
|
229
|
+
drain(timeout?: number): Promise<boolean>;
|
|
230
|
+
/**
|
|
231
|
+
* Close the library: new asynchronous calls are refused, the running ones awaited (a worker thread stopped during
|
|
232
|
+
* one crashes Bun), the callbacks released, the memory of `alloc()` freed, the library unloaded (unless kept
|
|
233
|
+
* loaded; musl never unloads). Its functions must not be called any more: a function of an unloaded library ends
|
|
234
|
+
* the process. When calls still run after the timeout, the ones in the thread pool go on, the ones in the threads
|
|
235
|
+
* of the library are rejected (their threads end once they return), and the library, its callbacks and its memory
|
|
236
|
+
* are left as they are: a call returning into an unloaded library, or calling a released callback, would end the
|
|
237
|
+
* process.
|
|
238
|
+
* @param timeout How long to wait for the asynchronous calls, in milliseconds.
|
|
239
|
+
*/
|
|
240
|
+
close(timeout?: number): Promise<void>;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Load a native library with its C declarations, without the container (scripts, tests); in an application, declare a
|
|
244
|
+
* `NativeLibrary` component instead. The library is looked for in the directories of `search`, then where the system
|
|
245
|
+
* looks for libraries.
|
|
246
|
+
* @param names Its file names: one (`sqlite3`, completed as the platform names libraries), one by platform
|
|
247
|
+
* (`{darwin: 'libsqlite3.dylib', linux: 'libsqlite3.so.0', win32: 'winsqlite3.dll'}`), or `c` for the C library.
|
|
248
|
+
* @param declarations Its C declarations: the types its functions use, its functions, its variables, its constants.
|
|
249
|
+
* @param options Where it is found, how it is closed.
|
|
250
|
+
* @returns The library.
|
|
251
|
+
* @throws {NativeLibraryNotFoundException} When it cannot be loaded (the message lists what was tried).
|
|
252
|
+
* @throws {NativeDeclarationException} When the declarations cannot be read.
|
|
253
|
+
* @example
|
|
254
|
+
* ```typescript
|
|
255
|
+
* import {loadNativeLibrary, type Out, type Pointer} from '@lakutata/ffi'
|
|
256
|
+
*
|
|
257
|
+
* const sqlite = loadNativeLibrary({darwin: 'libsqlite3.dylib', linux: 'libsqlite3.so.0', win32: 'winsqlite3.dll'}, `
|
|
258
|
+
* typedef struct sqlite3 sqlite3;
|
|
259
|
+
* #define SQLITE_OK 0
|
|
260
|
+
* `)
|
|
261
|
+
* const open = sqlite.func<(filename: string, db: Out<Pointer>) => number>('int sqlite3_open(const char *filename, _Out_ sqlite3 **db)')
|
|
262
|
+
* const close = sqlite.func<(db: Pointer) => number>('int sqlite3_close(sqlite3 *db)')
|
|
263
|
+
* const db: Out<Pointer> = [null]
|
|
264
|
+
* if (open(':memory:', db) === Number(sqlite.constants.SQLITE_OK)) close(db[0]!)
|
|
265
|
+
* await sqlite.close()
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
export declare function loadNativeLibrary(names: LibraryNames, declarations?: string, options?: NativeLibraryOptions): NativeLibraryHandle;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type LibraryHandle } from 'koffi';
|
|
2
|
+
/**
|
|
3
|
+
* The file of a library: one name for every platform, or one by platform (the names of process.platform, `default`
|
|
4
|
+
* for the others). A name without a directory and without an extension is completed as the platform names its
|
|
5
|
+
* libraries (`sqlite3`: `libsqlite3.dylib`, `libsqlite3.so`, `sqlite3.dll`); `c` and `m` are the C library and its
|
|
6
|
+
* mathematical functions, found where each system has them
|
|
7
|
+
*/
|
|
8
|
+
export type LibraryNames = string | Partial<Record<NodeJS.Platform | 'default', string | readonly string[]>>;
|
|
9
|
+
/**
|
|
10
|
+
* Where a library is looked for
|
|
11
|
+
*/
|
|
12
|
+
export interface ResolveOptions {
|
|
13
|
+
/**
|
|
14
|
+
* The file itself: the only one tried when given (an alias of the application can start it)
|
|
15
|
+
*/
|
|
16
|
+
readonly path?: string;
|
|
17
|
+
/**
|
|
18
|
+
* The directories tried first, in their order
|
|
19
|
+
*/
|
|
20
|
+
readonly search?: readonly string[];
|
|
21
|
+
/**
|
|
22
|
+
* The directory of the libraries of a packaged application, tried after the search directories
|
|
23
|
+
*/
|
|
24
|
+
readonly packaged?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The file names a name gives on a system: the name itself when it has a directory or an extension, else the names the
|
|
28
|
+
* system gives libraries
|
|
29
|
+
* @param name
|
|
30
|
+
* @param os
|
|
31
|
+
*/
|
|
32
|
+
export declare function fileNames(name: string, os?: NodeJS.Platform): string[];
|
|
33
|
+
/**
|
|
34
|
+
* The names of a library on a system
|
|
35
|
+
* @param names
|
|
36
|
+
* @param os
|
|
37
|
+
*/
|
|
38
|
+
export declare function libraryNames(names: LibraryNames, os?: NodeJS.Platform): string[];
|
|
39
|
+
/**
|
|
40
|
+
* Load a library: the file given; else each name in the search directories, in the directory of a packaged
|
|
41
|
+
* application, then where the system looks for libraries (dlopen, LoadLibrary)
|
|
42
|
+
* @param names
|
|
43
|
+
* @param options
|
|
44
|
+
* @returns The library and the file it was loaded from.
|
|
45
|
+
*/
|
|
46
|
+
export declare function loadLibrary(names: LibraryNames, options?: ResolveOptions): {
|
|
47
|
+
library: LibraryHandle;
|
|
48
|
+
file: string;
|
|
49
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { FunctionDeclaration } from '../declarations/Types.js';
|
|
2
|
+
import type { ThreadFunctionOptions } from './ThreadProtocol.js';
|
|
3
|
+
/**
|
|
4
|
+
* A function called in the threads: how a thread binds it
|
|
5
|
+
*/
|
|
6
|
+
export interface ThreadFunction {
|
|
7
|
+
/**
|
|
8
|
+
* Its prototype, or the name of a declared function
|
|
9
|
+
*/
|
|
10
|
+
readonly declaration: string;
|
|
11
|
+
readonly named: boolean;
|
|
12
|
+
readonly options: ThreadFunctionOptions;
|
|
13
|
+
/**
|
|
14
|
+
* Its declaration, read by the thread of the library: which arguments are written by the function, which are
|
|
15
|
+
* callbacks
|
|
16
|
+
*/
|
|
17
|
+
readonly type: FunctionDeclaration;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The result of a call in a thread: its value, and the errno of the thread after it
|
|
21
|
+
*/
|
|
22
|
+
export interface ThreadResult {
|
|
23
|
+
readonly value: unknown;
|
|
24
|
+
readonly errno: number;
|
|
25
|
+
readonly windowsError?: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The worker threads of a library: they load it, and run its asynchronous calls (synchronously, each in its thread);
|
|
29
|
+
* with one thread, in the order they are made. The arguments are copied to the thread and the ones the function writes
|
|
30
|
+
* copied back; a JS function given as a callback is registered for the call in the thread of the library, which runs it
|
|
31
|
+
* when the library calls it
|
|
32
|
+
*/
|
|
33
|
+
export declare class NativeThreads {
|
|
34
|
+
#private;
|
|
35
|
+
/**
|
|
36
|
+
* Start the threads of a library.
|
|
37
|
+
* @param file The file of the library, as loaded by this thread.
|
|
38
|
+
* @param declarations Its C declarations.
|
|
39
|
+
* @param count The number of threads.
|
|
40
|
+
* @param crt On Windows, the C library whose errno is read after each call.
|
|
41
|
+
*/
|
|
42
|
+
constructor(file: string, declarations: string, count: number, crt?: string);
|
|
43
|
+
/**
|
|
44
|
+
* Settled once every thread has loaded the library: rejected with the error of a thread that could not.
|
|
45
|
+
*/
|
|
46
|
+
get ready(): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* The number of threads.
|
|
49
|
+
*/
|
|
50
|
+
get count(): number;
|
|
51
|
+
/**
|
|
52
|
+
* Add declarations to the ones of the threads (and of the threads started later).
|
|
53
|
+
* @param declarations The declarations.
|
|
54
|
+
*/
|
|
55
|
+
declare(declarations: string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Bind a function in the threads now rather than at its first call: when the library is made, while the threads
|
|
58
|
+
* start (a thread started later binds it at its first call in it).
|
|
59
|
+
* @param fn The function.
|
|
60
|
+
*/
|
|
61
|
+
bind(fn: ThreadFunction): void;
|
|
62
|
+
/**
|
|
63
|
+
* Call a function in the least busy thread (with one thread, after the calls made before).
|
|
64
|
+
* @param fn The function.
|
|
65
|
+
* @param args Its arguments.
|
|
66
|
+
* @returns Its value and the errno of the thread after it.
|
|
67
|
+
*/
|
|
68
|
+
call(fn: ThreadFunction, args: unknown[]): Promise<ThreadResult>;
|
|
69
|
+
/**
|
|
70
|
+
* Stop a thread as if it had ended on its own (for the tests): its calls fail, the next call starts a new one.
|
|
71
|
+
* @param index The index of the thread.
|
|
72
|
+
*/
|
|
73
|
+
stopThread(index: number): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* Close the threads: each unloads the library and ends; the ones still running after a while are stopped. A thread
|
|
76
|
+
* still running a call (its native code did not return) is stopped at once, the call rejected: the thread ends
|
|
77
|
+
* once the native code returns.
|
|
78
|
+
*/
|
|
79
|
+
close(): Promise<void>;
|
|
80
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serve the calls of a library in this worker thread: it loads the library, binds the functions it is asked to bind
|
|
3
|
+
* (synchronous: the thread is the one waiting), calls them in the order of the messages, and sends back their results,
|
|
4
|
+
* the arguments asked back (the output parameters, the buffers written) and its errno after each call
|
|
5
|
+
*/
|
|
6
|
+
export declare function runNativeWorker(): void;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The require of the package (createRequire(import.meta.url) in the ES modules, require in CommonJS), written by the
|
|
3
|
+
* build (scripts/worker.mjs) in place of this one: it resolves koffi for the worker threads, from the package (in a
|
|
4
|
+
* packed application, from its native tree)
|
|
5
|
+
*/
|
|
6
|
+
export declare const packageRequire: NodeJS.Require | undefined;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a worker thread of a library is started with
|
|
3
|
+
*/
|
|
4
|
+
export interface NativeWorkerData {
|
|
5
|
+
/**
|
|
6
|
+
* The path of koffi, resolved by the thread of the library
|
|
7
|
+
*/
|
|
8
|
+
readonly koffi: string;
|
|
9
|
+
/**
|
|
10
|
+
* The file of the library, as the thread of the library loaded it
|
|
11
|
+
*/
|
|
12
|
+
readonly file: string;
|
|
13
|
+
/**
|
|
14
|
+
* The C declarations of the library
|
|
15
|
+
*/
|
|
16
|
+
readonly declarations: string;
|
|
17
|
+
/**
|
|
18
|
+
* On Windows, the C library whose errno is read after each call
|
|
19
|
+
*/
|
|
20
|
+
readonly crt?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The options a function is bound with in a thread (the synchronous ones: the thread calls it synchronously)
|
|
24
|
+
*/
|
|
25
|
+
export interface ThreadFunctionOptions {
|
|
26
|
+
readonly free?: string | boolean;
|
|
27
|
+
readonly int64?: 'bigint' | 'number';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* An error sent from a thread: made again by its name
|
|
31
|
+
*/
|
|
32
|
+
export interface ThreadError {
|
|
33
|
+
readonly name: string;
|
|
34
|
+
readonly message: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The messages to a thread: a function bound (a prototype, or the name of a declared function), declarations added, a
|
|
38
|
+
* call (the arguments to send back after it), the end
|
|
39
|
+
*/
|
|
40
|
+
export type ToNativeWorker = {
|
|
41
|
+
readonly type: 'bind';
|
|
42
|
+
readonly id: number;
|
|
43
|
+
readonly declaration: string;
|
|
44
|
+
readonly named: boolean;
|
|
45
|
+
readonly options: ThreadFunctionOptions;
|
|
46
|
+
} | {
|
|
47
|
+
readonly type: 'declare';
|
|
48
|
+
readonly declarations: string;
|
|
49
|
+
} | {
|
|
50
|
+
readonly type: 'call';
|
|
51
|
+
readonly id: number;
|
|
52
|
+
readonly function: number;
|
|
53
|
+
readonly args: unknown[];
|
|
54
|
+
readonly back: readonly number[];
|
|
55
|
+
} | {
|
|
56
|
+
readonly type: 'close';
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* The messages from a thread: the library loaded (or not), the result of a call (its value or its error, the arguments
|
|
60
|
+
* asked back, the errno of the thread after it), the end
|
|
61
|
+
*/
|
|
62
|
+
export type FromNativeWorker = {
|
|
63
|
+
readonly type: 'ready';
|
|
64
|
+
} | {
|
|
65
|
+
readonly type: 'failed';
|
|
66
|
+
readonly error: ThreadError;
|
|
67
|
+
} | {
|
|
68
|
+
readonly type: 'result';
|
|
69
|
+
readonly id: number;
|
|
70
|
+
readonly value?: unknown;
|
|
71
|
+
readonly error?: ThreadError;
|
|
72
|
+
readonly back: readonly unknown[];
|
|
73
|
+
readonly errno: number;
|
|
74
|
+
readonly windowsError?: number;
|
|
75
|
+
} | {
|
|
76
|
+
readonly type: 'closed';
|
|
77
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,87 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lakutata/ffi",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "3.1.2",
|
|
4
|
+
"description": "Native libraries for the lakutata framework: C functions of .so, .dylib and .dll files called from Node.js, Electron and Bun, declared with the C declarations of their headers, a library being a component of the application.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"lakutata",
|
|
7
|
+
"ffi",
|
|
8
|
+
"native",
|
|
9
|
+
"c",
|
|
10
|
+
"dll",
|
|
11
|
+
"shared-library",
|
|
12
|
+
"dlopen",
|
|
13
|
+
"koffi",
|
|
14
|
+
"bindings",
|
|
15
|
+
"typescript"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://lakutata.com/packages/ffi",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/lakutata/lakutata/issues",
|
|
20
|
+
"email": "admin@lakutata.com"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/lakutata/lakutata.git",
|
|
25
|
+
"directory": "packages/ffi"
|
|
26
|
+
},
|
|
27
|
+
"author": "alex.ma",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"type": "module",
|
|
30
|
+
"main": "./dist/cjs/exports/FFI.js",
|
|
31
|
+
"types": "./dist/cjs/exports/FFI.d.ts",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"import": {
|
|
35
|
+
"types": "./dist/types/exports/FFI.d.ts",
|
|
36
|
+
"default": "./dist/esm/exports/FFI.js"
|
|
37
|
+
},
|
|
38
|
+
"require": {
|
|
39
|
+
"types": "./dist/cjs/exports/FFI.d.ts",
|
|
40
|
+
"default": "./dist/cjs/exports/FFI.js"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"./generator": {
|
|
44
|
+
"import": {
|
|
45
|
+
"types": "./dist/types/exports/Generator.d.ts",
|
|
46
|
+
"default": "./dist/esm/exports/Generator.js"
|
|
47
|
+
},
|
|
48
|
+
"require": {
|
|
49
|
+
"types": "./dist/cjs/exports/Generator.d.ts",
|
|
50
|
+
"default": "./dist/cjs/exports/Generator.js"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"./package.json": "./package.json"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"clean": "node -e \"require('node:fs').rmSync('dist', {recursive: true, force: true})\"",
|
|
57
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
58
|
+
"build:esm": "tsc -p tsconfig.esm.json",
|
|
59
|
+
"build:cjs-pkg": "node ../../scripts/package-build/cjs-package.mjs",
|
|
60
|
+
"build:js": "npm run build:cjs && npm run build:esm && npm run build:cjs-pkg && npm run build:worker",
|
|
61
|
+
"rebuild": "npm run clean && npm run build:js",
|
|
62
|
+
"compile": "npm run rebuild",
|
|
63
|
+
"test:unit": "npm run compile && node --test --test-timeout=60000 \"dist/esm/tests/**/*.spec.js\"",
|
|
64
|
+
"test:bun": "sh test-env/bun.sh",
|
|
65
|
+
"test:electron": "electron test-env/electron/main.mjs",
|
|
66
|
+
"build:worker": "node scripts/worker.mjs"
|
|
67
|
+
},
|
|
68
|
+
"engines": {
|
|
69
|
+
"node": "^22.13.0 || >=24.11.0"
|
|
70
|
+
},
|
|
71
|
+
"files": [
|
|
72
|
+
"dist",
|
|
73
|
+
"!dist/*/tests",
|
|
74
|
+
"*.md",
|
|
75
|
+
"LICENSE",
|
|
76
|
+
"package.json"
|
|
77
|
+
],
|
|
78
|
+
"peerDependencies": {
|
|
79
|
+
"@lakutata/core": "~3.1.1"
|
|
80
|
+
},
|
|
81
|
+
"dependencies": {
|
|
82
|
+
"koffi": "3.3.4"
|
|
83
|
+
},
|
|
84
|
+
"devDependencies": {
|
|
85
|
+
"esbuild": "^0.28.2"
|
|
86
|
+
}
|
|
87
|
+
}
|