@slatedb/uniffi 0.12.0

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.
@@ -0,0 +1,122 @@
1
+ import type { HandleMapOptions } from "./handle-map.js";
2
+ import type { RustBufferStruct, RustCallStatusStruct } from "./ffi-types.js";
3
+
4
+ export interface CallbackRegistryOptions<T extends object = Record<string, unknown>>
5
+ extends HandleMapOptions
6
+ {
7
+ interfaceName?: string;
8
+ validate?: ((value: T) => void) | null;
9
+ }
10
+
11
+ export interface CallbackErrorOptions<E extends Error = Error> {
12
+ lowerError?: ((error: E) => RustBufferStruct | null | undefined) | null;
13
+ lowerString?: ((message: string) => RustBufferStruct) | null;
14
+ defaultMessage?: string;
15
+ }
16
+
17
+ export interface PendingForeignFuture<Result = unknown> {
18
+ callbackData: bigint | number | undefined;
19
+ cancelled: boolean;
20
+ complete: ((
21
+ callbackData: bigint | number | undefined,
22
+ result: Result,
23
+ ) => void) | undefined;
24
+ handle: bigint;
25
+ settled: boolean;
26
+ }
27
+
28
+ export interface PendingForeignFutureOptions<Result = unknown> {
29
+ callbackData?: bigint | number;
30
+ complete?: ((
31
+ callbackData: bigint | number | undefined,
32
+ result: Result,
33
+ ) => void) | null;
34
+ }
35
+
36
+ export interface AsyncCallbackCompletion<Lowered = unknown> {
37
+ call_status: RustCallStatusStruct;
38
+ return_value?: Lowered;
39
+ }
40
+
41
+ export interface InvokeCallbackMethodOptions<T = unknown, E extends Error = Error>
42
+ extends CallbackErrorOptions<E>
43
+ {
44
+ args?: readonly unknown[];
45
+ defaultReturnValue?: T;
46
+ interfaceName?: string;
47
+ status?: RustCallStatusStruct | null;
48
+ }
49
+
50
+ export interface InvokeAsyncCallbackMethodOptions<
51
+ Result = unknown,
52
+ Lowered = Result,
53
+ E extends Error = Error,
54
+ > extends CallbackErrorOptions<E>
55
+ {
56
+ args?: readonly unknown[];
57
+ callbackData?: bigint | number;
58
+ complete?: ((
59
+ callbackData: bigint | number | undefined,
60
+ result: AsyncCallbackCompletion<Lowered>,
61
+ ) => void) | null;
62
+ defaultReturnValue?: Lowered;
63
+ interfaceName?: string;
64
+ lowerReturn?: ((value: Result) => Lowered) | null;
65
+ }
66
+
67
+ export declare function resetCallbackCallStatus(
68
+ status?: RustCallStatusStruct | null,
69
+ ): RustCallStatusStruct;
70
+ export declare function writeCallbackError<E extends Error = Error>(
71
+ status: RustCallStatusStruct | null | undefined,
72
+ error: unknown,
73
+ options?: CallbackErrorOptions<E>,
74
+ ): E;
75
+ export declare function createPendingForeignFuture<Result = unknown>(
76
+ options?: PendingForeignFutureOptions<Result>,
77
+ ): PendingForeignFuture<Result>;
78
+ export declare function takePendingForeignFuture<Result = unknown>(
79
+ handle: bigint | number,
80
+ ): PendingForeignFuture<Result> | undefined;
81
+ export declare function freePendingForeignFuture<Result = unknown>(
82
+ handle: bigint | number,
83
+ ): PendingForeignFuture<Result> | undefined;
84
+ export declare function clearPendingForeignFutures(): void;
85
+ export declare function foreignFutureHandleCount(): number;
86
+ export declare function invokeCallbackMethod<T = unknown, E extends Error = Error>(params: {
87
+ registry: Pick<UniffiCallbackRegistry, "get"> & { interfaceName?: string };
88
+ handle: bigint | number;
89
+ methodName: string;
90
+ } & InvokeCallbackMethodOptions<T, E>): T;
91
+ export declare function invokeAsyncCallbackMethod<
92
+ Result = unknown,
93
+ Lowered = Result,
94
+ E extends Error = Error,
95
+ >(params: {
96
+ registry: Pick<UniffiCallbackRegistry, "get"> & { interfaceName?: string };
97
+ handle: bigint | number;
98
+ methodName: string;
99
+ } & InvokeAsyncCallbackMethodOptions<Result, Lowered, E>): bigint;
100
+
101
+ export declare class UniffiCallbackRegistry<T extends object = Record<string, unknown>> {
102
+ readonly interfaceName: string;
103
+ constructor(options?: CallbackRegistryOptions<T>);
104
+ register(value: T): bigint;
105
+ cloneHandle(handle: bigint | number): bigint;
106
+ get(handle: bigint | number): T;
107
+ remove(handle: bigint | number | null | undefined): T | undefined;
108
+ take(handle: bigint | number): T;
109
+ has(handle: bigint | number | null | undefined): boolean;
110
+ clear(): void;
111
+ invoke<R>(handle: bigint | number, methodName: string, args?: readonly unknown[]): R;
112
+ invokeWithRustCallStatus<R, E extends Error = Error>(
113
+ handle: bigint | number,
114
+ methodName: string,
115
+ options?: InvokeCallbackMethodOptions<R, E>,
116
+ ): R;
117
+ readonly size: number;
118
+ }
119
+
120
+ export declare function createCallbackRegistry<T extends object = Record<string, unknown>>(
121
+ options?: CallbackRegistryOptions<T>,
122
+ ): UniffiCallbackRegistry<T>;
@@ -0,0 +1,392 @@
1
+ import { UniffiRuntimeError, getErrorMessage } from "./errors.js";
2
+ import { UniffiHandleMap } from "./handle-map.js";
3
+ import { EMPTY_RUST_BUFFER } from "./ffi-types.js";
4
+ import {
5
+ CALL_ERROR,
6
+ CALL_SUCCESS,
7
+ CALL_UNEXPECTED_ERROR,
8
+ createRustCallStatus,
9
+ } from "./rust-call.js";
10
+
11
+ const PENDING_FOREIGN_FUTURES = new UniffiHandleMap();
12
+
13
+ function requireCallbackImplementation(value, interfaceName = "callback interface") {
14
+ if ((typeof value !== "object" && typeof value !== "function") || value == null) {
15
+ throw new TypeError(`${interfaceName} implementations must be objects with callable methods.`);
16
+ }
17
+ return value;
18
+ }
19
+
20
+ function requireCallbackMethod(implementation, methodName, interfaceName = "callback interface") {
21
+ const method = implementation?.[methodName];
22
+ if (typeof method !== "function") {
23
+ throw new TypeError(
24
+ `${interfaceName} is missing required method ${String(methodName)}().`,
25
+ );
26
+ }
27
+ return method;
28
+ }
29
+
30
+ function normalizeCallbackError(error, fallbackMessage = "Unknown error") {
31
+ if (error instanceof Error) {
32
+ return error;
33
+ }
34
+ return new UniffiRuntimeError(getErrorMessage(error, fallbackMessage), {
35
+ cause: error,
36
+ captureStack: false,
37
+ });
38
+ }
39
+
40
+ function lowerCallbackFailure(error, options = {}) {
41
+ const {
42
+ lowerError,
43
+ lowerString,
44
+ defaultMessage = "Callback invocation failed.",
45
+ } = options;
46
+ const message = getErrorMessage(error, defaultMessage);
47
+ let normalizedError = undefined;
48
+
49
+ function getNormalizedError() {
50
+ if (normalizedError === undefined) {
51
+ normalizedError = normalizeCallbackError(error, defaultMessage);
52
+ }
53
+ return normalizedError;
54
+ }
55
+
56
+ if (typeof lowerError === "function") {
57
+ const loweredError = lowerError(getNormalizedError());
58
+ if (loweredError != null) {
59
+ return {
60
+ code: CALL_ERROR,
61
+ error: getNormalizedError(),
62
+ error_buf: loweredError,
63
+ };
64
+ }
65
+ }
66
+
67
+ if (typeof lowerString === "function") {
68
+ return {
69
+ code: CALL_UNEXPECTED_ERROR,
70
+ error: getNormalizedError(),
71
+ error_buf: lowerString(message),
72
+ };
73
+ }
74
+
75
+ return {
76
+ code: CALL_UNEXPECTED_ERROR,
77
+ error: getNormalizedError(),
78
+ error_buf: EMPTY_RUST_BUFFER,
79
+ };
80
+ }
81
+
82
+ export function resetCallbackCallStatus(status = undefined) {
83
+ const callbackStatus = status ?? createRustCallStatus();
84
+ callbackStatus.code = CALL_SUCCESS;
85
+ callbackStatus.error_buf = EMPTY_RUST_BUFFER;
86
+ return callbackStatus;
87
+ }
88
+
89
+ export function writeCallbackError(status, error, options = {}) {
90
+ const callbackStatus = status ?? createRustCallStatus();
91
+ const lowered = lowerCallbackFailure(error, options);
92
+ callbackStatus.code = lowered.code;
93
+ callbackStatus.error_buf = lowered.error_buf ?? EMPTY_RUST_BUFFER;
94
+ return lowered.error;
95
+ }
96
+
97
+ export function createPendingForeignFuture({
98
+ callbackData = undefined,
99
+ complete = undefined,
100
+ } = {}) {
101
+ const pending = {
102
+ callbackData,
103
+ cancelled: false,
104
+ complete,
105
+ handle: 0n,
106
+ settled: false,
107
+ };
108
+ pending.handle = PENDING_FOREIGN_FUTURES.insert(pending);
109
+ return pending;
110
+ }
111
+
112
+ export function takePendingForeignFuture(handle) {
113
+ const pending = PENDING_FOREIGN_FUTURES.remove(handle);
114
+ if (pending == null) {
115
+ return undefined;
116
+ }
117
+ pending.settled = true;
118
+ return pending;
119
+ }
120
+
121
+ export function freePendingForeignFuture(handle) {
122
+ const pending = takePendingForeignFuture(handle);
123
+ if (pending == null) {
124
+ return undefined;
125
+ }
126
+ pending.cancelled = true;
127
+ return pending;
128
+ }
129
+
130
+ export function clearPendingForeignFutures() {
131
+ for (const pending of PENDING_FOREIGN_FUTURES.values()) {
132
+ pending.cancelled = true;
133
+ }
134
+ PENDING_FOREIGN_FUTURES.clear();
135
+ }
136
+
137
+ export function foreignFutureHandleCount() {
138
+ return PENDING_FOREIGN_FUTURES.size;
139
+ }
140
+
141
+ function createAsyncCallbackCompletion(callStatus, returnValue, hasReturnValue) {
142
+ const completion = {
143
+ call_status: callStatus,
144
+ };
145
+ if (hasReturnValue) {
146
+ completion.return_value = returnValue;
147
+ }
148
+ return completion;
149
+ }
150
+
151
+ function takeCompletablePendingForeignFuture(handle) {
152
+ const pending = takePendingForeignFuture(handle);
153
+ if (pending == null || pending.cancelled || typeof pending.complete !== "function") {
154
+ return undefined;
155
+ }
156
+ return pending;
157
+ }
158
+
159
+ function createAsyncCallbackFailureCompletion(error, options = {}) {
160
+ const {
161
+ defaultReturnValue = undefined,
162
+ hasReturnValue = false,
163
+ interfaceName = "callback interface",
164
+ lowerError,
165
+ lowerString,
166
+ methodName = "callback",
167
+ } = options;
168
+ const callStatus = createRustCallStatus();
169
+ writeCallbackError(callStatus, error, {
170
+ lowerError,
171
+ lowerString,
172
+ defaultMessage: `${interfaceName}.${String(methodName)}() failed.`,
173
+ });
174
+ return createAsyncCallbackCompletion(callStatus, defaultReturnValue, hasReturnValue);
175
+ }
176
+
177
+ function completeAsyncCallbackFailure(handle, error, options = {}) {
178
+ const pending = takeCompletablePendingForeignFuture(handle);
179
+ if (pending == null) {
180
+ return;
181
+ }
182
+
183
+ pending.complete(
184
+ pending.callbackData,
185
+ createAsyncCallbackFailureCompletion(error, options),
186
+ );
187
+ }
188
+
189
+ function completeAsyncCallbackSuccess(handle, result, options = {}) {
190
+ const pending = takeCompletablePendingForeignFuture(handle);
191
+ if (pending == null) {
192
+ return;
193
+ }
194
+
195
+ const {
196
+ defaultReturnValue = undefined,
197
+ hasReturnValue = false,
198
+ interfaceName = "callback interface",
199
+ lowerError,
200
+ lowerReturn = undefined,
201
+ lowerString,
202
+ methodName = "callback",
203
+ } = options;
204
+
205
+ try {
206
+ const callStatus = resetCallbackCallStatus(createRustCallStatus());
207
+ const returnValue =
208
+ typeof lowerReturn === "function"
209
+ ? lowerReturn(result)
210
+ : result;
211
+ pending.complete(
212
+ pending.callbackData,
213
+ createAsyncCallbackCompletion(callStatus, returnValue, hasReturnValue),
214
+ );
215
+ } catch (error) {
216
+ pending.complete(
217
+ pending.callbackData,
218
+ createAsyncCallbackFailureCompletion(error, {
219
+ defaultReturnValue,
220
+ hasReturnValue,
221
+ interfaceName,
222
+ lowerError,
223
+ lowerString,
224
+ methodName,
225
+ }),
226
+ );
227
+ }
228
+ }
229
+
230
+ export function invokeCallbackMethod({
231
+ registry,
232
+ handle,
233
+ methodName,
234
+ args = [],
235
+ defaultReturnValue = undefined,
236
+ interfaceName = registry?.interfaceName ?? "callback interface",
237
+ lowerError,
238
+ lowerString,
239
+ status = undefined,
240
+ }) {
241
+ try {
242
+ const implementation = registry.get(handle);
243
+ const method = requireCallbackMethod(implementation, methodName, interfaceName);
244
+ const result = method.apply(implementation, Array.from(args));
245
+ if (status != null) {
246
+ resetCallbackCallStatus(status);
247
+ }
248
+ return result;
249
+ } catch (error) {
250
+ if (status == null) {
251
+ throw error;
252
+ }
253
+ writeCallbackError(status, error, {
254
+ lowerError,
255
+ lowerString,
256
+ defaultMessage: `${interfaceName}.${String(methodName)}() failed.`,
257
+ });
258
+ return defaultReturnValue;
259
+ }
260
+ }
261
+
262
+ export function invokeAsyncCallbackMethod({
263
+ registry,
264
+ handle,
265
+ methodName,
266
+ args = [],
267
+ callbackData = undefined,
268
+ complete = undefined,
269
+ defaultReturnValue = undefined,
270
+ interfaceName = registry?.interfaceName ?? "callback interface",
271
+ lowerError,
272
+ lowerReturn = undefined,
273
+ lowerString,
274
+ }) {
275
+ const pending = createPendingForeignFuture({
276
+ callbackData,
277
+ complete,
278
+ });
279
+ const hasReturnValue =
280
+ typeof lowerReturn === "function"
281
+ || defaultReturnValue !== undefined;
282
+
283
+ let promise;
284
+ try {
285
+ const implementation = registry.get(handle);
286
+ const method = requireCallbackMethod(implementation, methodName, interfaceName);
287
+ promise = Promise.resolve(method.apply(implementation, Array.from(args)));
288
+ } catch (error) {
289
+ promise = Promise.reject(error);
290
+ }
291
+
292
+ void promise.then(
293
+ (result) => {
294
+ completeAsyncCallbackSuccess(pending.handle, result, {
295
+ defaultReturnValue,
296
+ hasReturnValue,
297
+ interfaceName,
298
+ lowerError,
299
+ lowerReturn,
300
+ lowerString,
301
+ methodName,
302
+ });
303
+ },
304
+ (error) => {
305
+ completeAsyncCallbackFailure(pending.handle, error, {
306
+ defaultReturnValue,
307
+ hasReturnValue,
308
+ interfaceName,
309
+ lowerError,
310
+ lowerString,
311
+ methodName,
312
+ });
313
+ },
314
+ );
315
+
316
+ return pending.handle;
317
+ }
318
+
319
+ export class UniffiCallbackRegistry {
320
+ constructor({
321
+ interfaceName = "callback interface",
322
+ firstHandle = undefined,
323
+ handleStep = undefined,
324
+ validate = undefined,
325
+ } = {}) {
326
+ this.interfaceName = interfaceName;
327
+ this._handleMap = new UniffiHandleMap({
328
+ firstHandle,
329
+ handleStep,
330
+ });
331
+ this._validate = validate;
332
+ }
333
+
334
+ _normalizeImplementation(value) {
335
+ const implementation = requireCallbackImplementation(value, this.interfaceName);
336
+ if (typeof this._validate === "function") {
337
+ this._validate(implementation);
338
+ }
339
+ return implementation;
340
+ }
341
+
342
+ register(value) {
343
+ return this._handleMap.insert(this._normalizeImplementation(value));
344
+ }
345
+
346
+ cloneHandle(handle) {
347
+ return this._handleMap.clone(handle);
348
+ }
349
+
350
+ get(handle) {
351
+ return this._handleMap.get(handle);
352
+ }
353
+
354
+ remove(handle) {
355
+ return this._handleMap.remove(handle);
356
+ }
357
+
358
+ take(handle) {
359
+ return this._handleMap.take(handle);
360
+ }
361
+
362
+ has(handle) {
363
+ return this._handleMap.has(handle);
364
+ }
365
+
366
+ clear() {
367
+ this._handleMap.clear();
368
+ }
369
+
370
+ invoke(handle, methodName, args = []) {
371
+ const implementation = this.get(handle);
372
+ const method = requireCallbackMethod(implementation, methodName, this.interfaceName);
373
+ return method.apply(implementation, Array.from(args));
374
+ }
375
+
376
+ invokeWithRustCallStatus(handle, methodName, options = {}) {
377
+ return invokeCallbackMethod({
378
+ registry: this,
379
+ handle,
380
+ methodName,
381
+ ...options,
382
+ });
383
+ }
384
+
385
+ get size() {
386
+ return this._handleMap.size;
387
+ }
388
+ }
389
+
390
+ export function createCallbackRegistry(options = undefined) {
391
+ return new UniffiCallbackRegistry(options);
392
+ }
@@ -0,0 +1,120 @@
1
+ export interface UniffiErrorOptions {
2
+ cause?: unknown;
3
+ code?: string | number;
4
+ details?: unknown;
5
+ }
6
+
7
+ export declare class UniffiError extends Error {
8
+ cause?: unknown;
9
+ code?: string | number;
10
+ details?: unknown;
11
+ constructor(message?: string, options?: UniffiErrorOptions);
12
+ }
13
+
14
+ export declare class UniffiGeneratedError extends UniffiError {}
15
+
16
+ export declare class UniffiRuntimeError extends UniffiError {}
17
+
18
+ export declare class RustPanic extends UniffiRuntimeError {
19
+ constructor(message?: string, options?: UniffiErrorOptions);
20
+ }
21
+
22
+ export declare class AbortError extends UniffiRuntimeError {
23
+ constructor(message?: string, options?: UniffiErrorOptions);
24
+ }
25
+
26
+ export declare class LibraryNotLoadedError extends UniffiRuntimeError {
27
+ constructor(message?: string, options?: UniffiErrorOptions);
28
+ }
29
+
30
+ export declare class ContractVersionMismatchError extends UniffiRuntimeError {
31
+ constructor(expected: bigint | number, actual: bigint | number, options?: UniffiErrorOptions);
32
+ }
33
+
34
+ export declare class ChecksumMismatchError extends UniffiRuntimeError {
35
+ constructor(
36
+ kind: string,
37
+ expected: bigint | number | string,
38
+ actual: bigint | number | string,
39
+ options?: UniffiErrorOptions,
40
+ );
41
+ }
42
+
43
+ export declare class UnexpectedRustCallError extends UniffiRuntimeError {
44
+ constructor(message?: string, options?: UniffiErrorOptions);
45
+ }
46
+
47
+ export declare class UnexpectedRustCallStatusCode extends UniffiRuntimeError {
48
+ constructor(code: bigint | number | string, options?: UniffiErrorOptions);
49
+ }
50
+
51
+ export declare class UnexpectedEnumCase extends UniffiRuntimeError {
52
+ constructor(message?: string, options?: UniffiErrorOptions);
53
+ }
54
+
55
+ export declare class UnexpectedNullPointer extends UniffiRuntimeError {
56
+ constructor(message?: string, options?: UniffiErrorOptions);
57
+ }
58
+
59
+ export declare class UnexpectedOptionTag extends UniffiRuntimeError {
60
+ constructor(tag: bigint | number | string, options?: UniffiErrorOptions);
61
+ }
62
+
63
+ export declare class ConverterRangeError extends UniffiRuntimeError {
64
+ constructor(message?: string, options?: UniffiErrorOptions);
65
+ }
66
+
67
+ export declare class BufferOverflowError extends UniffiRuntimeError {
68
+ constructor(message?: string, options?: UniffiErrorOptions);
69
+ }
70
+
71
+ export declare class BufferSizeMismatchError extends UniffiRuntimeError {
72
+ constructor(expected: bigint | number, actual: bigint | number, options?: UniffiErrorOptions);
73
+ }
74
+
75
+ export declare class TrailingBytesError extends UniffiRuntimeError {
76
+ constructor(remaining: bigint | number, options?: UniffiErrorOptions);
77
+ }
78
+
79
+ export declare class DuplicateHandleError extends UniffiRuntimeError {
80
+ constructor(handle: bigint | number | string, options?: UniffiErrorOptions);
81
+ }
82
+
83
+ export declare class StaleHandleError extends UniffiRuntimeError {
84
+ constructor(handle: bigint | number | string, options?: UniffiErrorOptions);
85
+ }
86
+
87
+ export declare class UnsupportedConverterError extends UniffiRuntimeError {
88
+ constructor(message?: string, options?: UniffiErrorOptions);
89
+ }
90
+
91
+ export declare function attachCause<T extends Error>(error: T, cause: unknown): T;
92
+ export declare function getErrorMessage(value: unknown, fallbackMessage?: string): string;
93
+ export declare function ensureError(value: unknown, fallbackMessage?: string): Error;
94
+ export declare function createUniffiErrorClass(
95
+ name: string,
96
+ options?: {
97
+ baseClass?: typeof UniffiGeneratedError;
98
+ defaultMessage?: string;
99
+ },
100
+ ): new (message?: string, options?: UniffiErrorOptions) => UniffiGeneratedError;
101
+
102
+ export declare const UniffiInternalError: Readonly<{
103
+ AbortError: typeof AbortError;
104
+ BufferOverflowError: typeof BufferOverflowError;
105
+ BufferSizeMismatchError: typeof BufferSizeMismatchError;
106
+ ChecksumMismatchError: typeof ChecksumMismatchError;
107
+ ContractVersionMismatchError: typeof ContractVersionMismatchError;
108
+ ConverterRangeError: typeof ConverterRangeError;
109
+ DuplicateHandleError: typeof DuplicateHandleError;
110
+ LibraryNotLoadedError: typeof LibraryNotLoadedError;
111
+ RustPanic: typeof RustPanic;
112
+ StaleHandleError: typeof StaleHandleError;
113
+ TrailingBytesError: typeof TrailingBytesError;
114
+ UnexpectedEnumCase: typeof UnexpectedEnumCase;
115
+ UnexpectedNullPointer: typeof UnexpectedNullPointer;
116
+ UnexpectedOptionTag: typeof UnexpectedOptionTag;
117
+ UnexpectedRustCallError: typeof UnexpectedRustCallError;
118
+ UnexpectedRustCallStatusCode: typeof UnexpectedRustCallStatusCode;
119
+ UnsupportedConverterError: typeof UnsupportedConverterError;
120
+ }>;