@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.
- package/README.md +211 -0
- package/index.d.ts +1 -0
- package/index.js +7 -0
- package/package.json +47 -0
- package/prebuilds/darwin-arm64/libslatedb_uniffi.dylib +0 -0
- package/prebuilds/darwin-x64/libslatedb_uniffi.dylib +0 -0
- package/prebuilds/linux-arm64-gnu/libslatedb_uniffi.so +0 -0
- package/prebuilds/linux-x64-gnu/libslatedb_uniffi.so +0 -0
- package/prebuilds/win32-arm64/slatedb_uniffi.dll +0 -0
- package/prebuilds/win32-x64/slatedb_uniffi.dll +0 -0
- package/runtime/async-rust-call.d.ts +86 -0
- package/runtime/async-rust-call.js +217 -0
- package/runtime/callbacks.d.ts +122 -0
- package/runtime/callbacks.js +392 -0
- package/runtime/errors.d.ts +120 -0
- package/runtime/errors.js +274 -0
- package/runtime/ffi-converters.d.ts +100 -0
- package/runtime/ffi-converters.js +758 -0
- package/runtime/ffi-types.d.ts +120 -0
- package/runtime/ffi-types.js +456 -0
- package/runtime/handle-map.d.ts +35 -0
- package/runtime/handle-map.js +137 -0
- package/runtime/objects.d.ts +68 -0
- package/runtime/objects.js +469 -0
- package/runtime/rust-call.d.ts +77 -0
- package/runtime/rust-call.js +233 -0
- package/slatedb-ffi.d.ts +732 -0
- package/slatedb-ffi.js +11480 -0
- package/slatedb.d.ts +1393 -0
- package/slatedb.js +5873 -0
|
@@ -0,0 +1,758 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BufferOverflowError,
|
|
3
|
+
BufferSizeMismatchError,
|
|
4
|
+
ConverterRangeError,
|
|
5
|
+
TrailingBytesError,
|
|
6
|
+
UnexpectedOptionTag,
|
|
7
|
+
} from "./errors.js";
|
|
8
|
+
import {
|
|
9
|
+
coerceUint8Array,
|
|
10
|
+
normalizeInt64,
|
|
11
|
+
normalizeUInt64,
|
|
12
|
+
} from "./ffi-types.js";
|
|
13
|
+
|
|
14
|
+
const MAX_COLLECTION_LEN = 0x7fffffff;
|
|
15
|
+
const MAX_SAFE_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);
|
|
16
|
+
const MAX_DATE_MILLISECONDS = 8640000000000000n;
|
|
17
|
+
const UTF8_ENCODER = new TextEncoder();
|
|
18
|
+
const UTF8_DECODER = new TextDecoder();
|
|
19
|
+
|
|
20
|
+
function toSafeNumber(value, label) {
|
|
21
|
+
if (value < -MAX_SAFE_BIGINT || value > MAX_SAFE_BIGINT) {
|
|
22
|
+
throw new ConverterRangeError(
|
|
23
|
+
`${label} ${String(value)} exceeds Number.MAX_SAFE_INTEGER.`,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return Number(value);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function normalizeCollectionLength(value, label) {
|
|
30
|
+
if (!Number.isInteger(value) || value < 0 || value > MAX_COLLECTION_LEN) {
|
|
31
|
+
throw new ConverterRangeError(
|
|
32
|
+
`${label} must be an integer between 0 and ${MAX_COLLECTION_LEN}.`,
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function normalizeSignedInteger(value, label, min, max) {
|
|
39
|
+
if (!Number.isInteger(value) || value < min || value > max) {
|
|
40
|
+
throw new ConverterRangeError(
|
|
41
|
+
`${label} must be an integer between ${min} and ${max}.`,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function normalizeFloat(value, label) {
|
|
48
|
+
if (typeof value !== "number") {
|
|
49
|
+
throw new TypeError(`${label} must be a number.`);
|
|
50
|
+
}
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function normalizeBoolean(value, label) {
|
|
55
|
+
if (typeof value !== "boolean") {
|
|
56
|
+
throw new TypeError(`${label} must be a boolean.`);
|
|
57
|
+
}
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function normalizeDate(value) {
|
|
62
|
+
if (!(value instanceof Date) || Number.isNaN(value.getTime())) {
|
|
63
|
+
throw new TypeError("timestamp values must be valid Date instances.");
|
|
64
|
+
}
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function normalizeDurationMilliseconds(value) {
|
|
69
|
+
if (typeof value === "bigint") {
|
|
70
|
+
if (value < 0n) {
|
|
71
|
+
throw new ConverterRangeError("duration values cannot be negative.");
|
|
72
|
+
}
|
|
73
|
+
return value;
|
|
74
|
+
}
|
|
75
|
+
if (!Number.isFinite(value) || value < 0 || !Number.isInteger(value)) {
|
|
76
|
+
throw new ConverterRangeError(
|
|
77
|
+
"duration values must be non-negative integer millisecond counts.",
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
return BigInt(value);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function encodeUtf8(value) {
|
|
84
|
+
if (typeof value !== "string") {
|
|
85
|
+
throw new TypeError("string values must be strings.");
|
|
86
|
+
}
|
|
87
|
+
return UTF8_ENCODER.encode(value);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function decodeUtf8(bytes) {
|
|
91
|
+
return UTF8_DECODER.decode(bytes);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export class ByteWriter {
|
|
95
|
+
constructor(length) {
|
|
96
|
+
const byteLength = normalizeCollectionLength(length, "serialized byte length");
|
|
97
|
+
this._bytes = new Uint8Array(byteLength);
|
|
98
|
+
this._view = new DataView(this._bytes.buffer);
|
|
99
|
+
this._offset = 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
remaining() {
|
|
103
|
+
return this._bytes.byteLength - this._offset;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
_ensureAvailable(byteLength) {
|
|
107
|
+
if (this.remaining() < byteLength) {
|
|
108
|
+
throw new BufferOverflowError(
|
|
109
|
+
`Tried to write ${byteLength} byte(s) with only ${this.remaining()} remaining.`,
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
writeInt8(value) {
|
|
115
|
+
this._ensureAvailable(1);
|
|
116
|
+
this._view.setInt8(this._offset, normalizeSignedInteger(value, "i8", -128, 127));
|
|
117
|
+
this._offset += 1;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
writeUInt8(value) {
|
|
121
|
+
this._ensureAvailable(1);
|
|
122
|
+
this._view.setUint8(this._offset, normalizeSignedInteger(value, "u8", 0, 0xff));
|
|
123
|
+
this._offset += 1;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
writeInt16(value) {
|
|
127
|
+
this._ensureAvailable(2);
|
|
128
|
+
this._view.setInt16(this._offset, normalizeSignedInteger(value, "i16", -0x8000, 0x7fff));
|
|
129
|
+
this._offset += 2;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
writeUInt16(value) {
|
|
133
|
+
this._ensureAvailable(2);
|
|
134
|
+
this._view.setUint16(this._offset, normalizeSignedInteger(value, "u16", 0, 0xffff));
|
|
135
|
+
this._offset += 2;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
writeInt32(value) {
|
|
139
|
+
this._ensureAvailable(4);
|
|
140
|
+
this._view.setInt32(
|
|
141
|
+
this._offset,
|
|
142
|
+
normalizeSignedInteger(value, "i32", -0x80000000, 0x7fffffff),
|
|
143
|
+
);
|
|
144
|
+
this._offset += 4;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
writeUInt32(value) {
|
|
148
|
+
this._ensureAvailable(4);
|
|
149
|
+
this._view.setUint32(this._offset, normalizeSignedInteger(value, "u32", 0, 0xffffffff));
|
|
150
|
+
this._offset += 4;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
writeInt64(value) {
|
|
154
|
+
this._ensureAvailable(8);
|
|
155
|
+
this._view.setBigInt64(this._offset, normalizeInt64(value));
|
|
156
|
+
this._offset += 8;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
writeUInt64(value) {
|
|
160
|
+
this._ensureAvailable(8);
|
|
161
|
+
this._view.setBigUint64(this._offset, normalizeUInt64(value));
|
|
162
|
+
this._offset += 8;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
writeFloat32(value) {
|
|
166
|
+
this._ensureAvailable(4);
|
|
167
|
+
this._view.setFloat32(this._offset, normalizeFloat(value, "f32"));
|
|
168
|
+
this._offset += 4;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
writeFloat64(value) {
|
|
172
|
+
this._ensureAvailable(8);
|
|
173
|
+
this._view.setFloat64(this._offset, normalizeFloat(value, "f64"));
|
|
174
|
+
this._offset += 8;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
writeBytes(value) {
|
|
178
|
+
const bytes = coerceUint8Array(value, "serialized bytes");
|
|
179
|
+
this._ensureAvailable(bytes.byteLength);
|
|
180
|
+
this._bytes.set(bytes, this._offset);
|
|
181
|
+
this._offset += bytes.byteLength;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
finish() {
|
|
185
|
+
if (this._offset !== this._bytes.byteLength) {
|
|
186
|
+
throw new BufferSizeMismatchError(this._bytes.byteLength, this._offset);
|
|
187
|
+
}
|
|
188
|
+
return this._bytes;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export class ByteReader {
|
|
193
|
+
constructor(bytes) {
|
|
194
|
+
this._bytes = coerceUint8Array(bytes, "serialized bytes");
|
|
195
|
+
this._view = new DataView(
|
|
196
|
+
this._bytes.buffer,
|
|
197
|
+
this._bytes.byteOffset,
|
|
198
|
+
this._bytes.byteLength,
|
|
199
|
+
);
|
|
200
|
+
this._offset = 0;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
remaining() {
|
|
204
|
+
return this._bytes.byteLength - this._offset;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
_ensureAvailable(byteLength) {
|
|
208
|
+
if (this.remaining() < byteLength) {
|
|
209
|
+
throw new BufferOverflowError(
|
|
210
|
+
`Tried to read ${byteLength} byte(s) with only ${this.remaining()} remaining.`,
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
readInt8() {
|
|
216
|
+
this._ensureAvailable(1);
|
|
217
|
+
const value = this._view.getInt8(this._offset);
|
|
218
|
+
this._offset += 1;
|
|
219
|
+
return value;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
readUInt8() {
|
|
223
|
+
this._ensureAvailable(1);
|
|
224
|
+
const value = this._view.getUint8(this._offset);
|
|
225
|
+
this._offset += 1;
|
|
226
|
+
return value;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
readInt16() {
|
|
230
|
+
this._ensureAvailable(2);
|
|
231
|
+
const value = this._view.getInt16(this._offset);
|
|
232
|
+
this._offset += 2;
|
|
233
|
+
return value;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
readUInt16() {
|
|
237
|
+
this._ensureAvailable(2);
|
|
238
|
+
const value = this._view.getUint16(this._offset);
|
|
239
|
+
this._offset += 2;
|
|
240
|
+
return value;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
readInt32() {
|
|
244
|
+
this._ensureAvailable(4);
|
|
245
|
+
const value = this._view.getInt32(this._offset);
|
|
246
|
+
this._offset += 4;
|
|
247
|
+
return value;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
readUInt32() {
|
|
251
|
+
this._ensureAvailable(4);
|
|
252
|
+
const value = this._view.getUint32(this._offset);
|
|
253
|
+
this._offset += 4;
|
|
254
|
+
return value;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
readInt64() {
|
|
258
|
+
this._ensureAvailable(8);
|
|
259
|
+
const value = this._view.getBigInt64(this._offset);
|
|
260
|
+
this._offset += 8;
|
|
261
|
+
return value;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
readUInt64() {
|
|
265
|
+
this._ensureAvailable(8);
|
|
266
|
+
const value = this._view.getBigUint64(this._offset);
|
|
267
|
+
this._offset += 8;
|
|
268
|
+
return value;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
readFloat32() {
|
|
272
|
+
this._ensureAvailable(4);
|
|
273
|
+
const value = this._view.getFloat32(this._offset);
|
|
274
|
+
this._offset += 4;
|
|
275
|
+
return value;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
readFloat64() {
|
|
279
|
+
this._ensureAvailable(8);
|
|
280
|
+
const value = this._view.getFloat64(this._offset);
|
|
281
|
+
this._offset += 8;
|
|
282
|
+
return value;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
readBytes(length) {
|
|
286
|
+
const byteLength = normalizeCollectionLength(length, "byte length");
|
|
287
|
+
this._ensureAvailable(byteLength);
|
|
288
|
+
const start = this._offset;
|
|
289
|
+
const end = this._offset + byteLength;
|
|
290
|
+
this._offset = end;
|
|
291
|
+
return this._bytes.subarray(start, end);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
readCount(label) {
|
|
295
|
+
const count = this.readInt32();
|
|
296
|
+
if (count < 0) {
|
|
297
|
+
throw new ConverterRangeError(`${label} cannot be negative.`);
|
|
298
|
+
}
|
|
299
|
+
return count;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
finish() {
|
|
303
|
+
if (this.remaining() !== 0) {
|
|
304
|
+
throw new TrailingBytesError(this.remaining());
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
export class AbstractFfiConverterByteArray {
|
|
310
|
+
lower(value) {
|
|
311
|
+
const writer = new ByteWriter(this.allocationSize(value));
|
|
312
|
+
this.write(value, writer);
|
|
313
|
+
return writer.finish();
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
lift(value) {
|
|
317
|
+
const reader = new ByteReader(value);
|
|
318
|
+
const result = this.read(reader);
|
|
319
|
+
reader.finish();
|
|
320
|
+
return result;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function createPrimitiveConverter({ lower, lift, write, read, size }) {
|
|
325
|
+
return Object.freeze({
|
|
326
|
+
lower,
|
|
327
|
+
lift,
|
|
328
|
+
write,
|
|
329
|
+
read,
|
|
330
|
+
allocationSize() {
|
|
331
|
+
return size;
|
|
332
|
+
},
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export const FfiConverterInt8 = createPrimitiveConverter({
|
|
337
|
+
lower(value) {
|
|
338
|
+
return normalizeSignedInteger(value, "i8", -128, 127);
|
|
339
|
+
},
|
|
340
|
+
lift(value) {
|
|
341
|
+
return normalizeSignedInteger(value, "i8", -128, 127);
|
|
342
|
+
},
|
|
343
|
+
write(value, writer) {
|
|
344
|
+
writer.writeInt8(value);
|
|
345
|
+
},
|
|
346
|
+
read(reader) {
|
|
347
|
+
return reader.readInt8();
|
|
348
|
+
},
|
|
349
|
+
size: 1,
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
export const FfiConverterUInt8 = createPrimitiveConverter({
|
|
353
|
+
lower(value) {
|
|
354
|
+
return normalizeSignedInteger(value, "u8", 0, 0xff);
|
|
355
|
+
},
|
|
356
|
+
lift(value) {
|
|
357
|
+
return normalizeSignedInteger(value, "u8", 0, 0xff);
|
|
358
|
+
},
|
|
359
|
+
write(value, writer) {
|
|
360
|
+
writer.writeUInt8(value);
|
|
361
|
+
},
|
|
362
|
+
read(reader) {
|
|
363
|
+
return reader.readUInt8();
|
|
364
|
+
},
|
|
365
|
+
size: 1,
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
export const FfiConverterInt16 = createPrimitiveConverter({
|
|
369
|
+
lower(value) {
|
|
370
|
+
return normalizeSignedInteger(value, "i16", -0x8000, 0x7fff);
|
|
371
|
+
},
|
|
372
|
+
lift(value) {
|
|
373
|
+
return normalizeSignedInteger(value, "i16", -0x8000, 0x7fff);
|
|
374
|
+
},
|
|
375
|
+
write(value, writer) {
|
|
376
|
+
writer.writeInt16(value);
|
|
377
|
+
},
|
|
378
|
+
read(reader) {
|
|
379
|
+
return reader.readInt16();
|
|
380
|
+
},
|
|
381
|
+
size: 2,
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
export const FfiConverterUInt16 = createPrimitiveConverter({
|
|
385
|
+
lower(value) {
|
|
386
|
+
return normalizeSignedInteger(value, "u16", 0, 0xffff);
|
|
387
|
+
},
|
|
388
|
+
lift(value) {
|
|
389
|
+
return normalizeSignedInteger(value, "u16", 0, 0xffff);
|
|
390
|
+
},
|
|
391
|
+
write(value, writer) {
|
|
392
|
+
writer.writeUInt16(value);
|
|
393
|
+
},
|
|
394
|
+
read(reader) {
|
|
395
|
+
return reader.readUInt16();
|
|
396
|
+
},
|
|
397
|
+
size: 2,
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
export const FfiConverterInt32 = createPrimitiveConverter({
|
|
401
|
+
lower(value) {
|
|
402
|
+
return normalizeSignedInteger(value, "i32", -0x80000000, 0x7fffffff);
|
|
403
|
+
},
|
|
404
|
+
lift(value) {
|
|
405
|
+
return normalizeSignedInteger(value, "i32", -0x80000000, 0x7fffffff);
|
|
406
|
+
},
|
|
407
|
+
write(value, writer) {
|
|
408
|
+
writer.writeInt32(value);
|
|
409
|
+
},
|
|
410
|
+
read(reader) {
|
|
411
|
+
return reader.readInt32();
|
|
412
|
+
},
|
|
413
|
+
size: 4,
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
export const FfiConverterUInt32 = createPrimitiveConverter({
|
|
417
|
+
lower(value) {
|
|
418
|
+
return normalizeSignedInteger(value, "u32", 0, 0xffffffff);
|
|
419
|
+
},
|
|
420
|
+
lift(value) {
|
|
421
|
+
return normalizeSignedInteger(value, "u32", 0, 0xffffffff);
|
|
422
|
+
},
|
|
423
|
+
write(value, writer) {
|
|
424
|
+
writer.writeUInt32(value);
|
|
425
|
+
},
|
|
426
|
+
read(reader) {
|
|
427
|
+
return reader.readUInt32();
|
|
428
|
+
},
|
|
429
|
+
size: 4,
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
export const FfiConverterInt64 = createPrimitiveConverter({
|
|
433
|
+
lower(value) {
|
|
434
|
+
return normalizeInt64(value);
|
|
435
|
+
},
|
|
436
|
+
lift(value) {
|
|
437
|
+
return normalizeInt64(value);
|
|
438
|
+
},
|
|
439
|
+
write(value, writer) {
|
|
440
|
+
writer.writeInt64(value);
|
|
441
|
+
},
|
|
442
|
+
read(reader) {
|
|
443
|
+
return reader.readInt64();
|
|
444
|
+
},
|
|
445
|
+
size: 8,
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
export const FfiConverterUInt64 = createPrimitiveConverter({
|
|
449
|
+
lower(value) {
|
|
450
|
+
return normalizeUInt64(value);
|
|
451
|
+
},
|
|
452
|
+
lift(value) {
|
|
453
|
+
return normalizeUInt64(value);
|
|
454
|
+
},
|
|
455
|
+
write(value, writer) {
|
|
456
|
+
writer.writeUInt64(value);
|
|
457
|
+
},
|
|
458
|
+
read(reader) {
|
|
459
|
+
return reader.readUInt64();
|
|
460
|
+
},
|
|
461
|
+
size: 8,
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
export const FfiConverterFloat32 = createPrimitiveConverter({
|
|
465
|
+
lower(value) {
|
|
466
|
+
return normalizeFloat(value, "f32");
|
|
467
|
+
},
|
|
468
|
+
lift(value) {
|
|
469
|
+
return normalizeFloat(value, "f32");
|
|
470
|
+
},
|
|
471
|
+
write(value, writer) {
|
|
472
|
+
writer.writeFloat32(value);
|
|
473
|
+
},
|
|
474
|
+
read(reader) {
|
|
475
|
+
return reader.readFloat32();
|
|
476
|
+
},
|
|
477
|
+
size: 4,
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
export const FfiConverterFloat64 = createPrimitiveConverter({
|
|
481
|
+
lower(value) {
|
|
482
|
+
return normalizeFloat(value, "f64");
|
|
483
|
+
},
|
|
484
|
+
lift(value) {
|
|
485
|
+
return normalizeFloat(value, "f64");
|
|
486
|
+
},
|
|
487
|
+
write(value, writer) {
|
|
488
|
+
writer.writeFloat64(value);
|
|
489
|
+
},
|
|
490
|
+
read(reader) {
|
|
491
|
+
return reader.readFloat64();
|
|
492
|
+
},
|
|
493
|
+
size: 8,
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
export const FfiConverterBool = createPrimitiveConverter({
|
|
497
|
+
lower(value) {
|
|
498
|
+
return normalizeBoolean(value, "bool") ? 1 : 0;
|
|
499
|
+
},
|
|
500
|
+
lift(value) {
|
|
501
|
+
switch (value) {
|
|
502
|
+
case 0:
|
|
503
|
+
return false;
|
|
504
|
+
case 1:
|
|
505
|
+
return true;
|
|
506
|
+
default:
|
|
507
|
+
throw new ConverterRangeError(
|
|
508
|
+
`bool values must be encoded as 0 or 1, got ${String(value)}.`,
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
write(value, writer) {
|
|
513
|
+
writer.writeInt8(normalizeBoolean(value, "bool") ? 1 : 0);
|
|
514
|
+
},
|
|
515
|
+
read(reader) {
|
|
516
|
+
return FfiConverterBool.lift(reader.readInt8());
|
|
517
|
+
},
|
|
518
|
+
size: 1,
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
export const FfiConverterString = new (class extends AbstractFfiConverterByteArray {
|
|
522
|
+
allocationSize(value) {
|
|
523
|
+
return 4 + encodeUtf8(value).byteLength;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
write(value, writer) {
|
|
527
|
+
const bytes = encodeUtf8(value);
|
|
528
|
+
writer.writeInt32(normalizeCollectionLength(bytes.byteLength, "string byte length"));
|
|
529
|
+
writer.writeBytes(bytes);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
read(reader) {
|
|
533
|
+
return decodeUtf8(reader.readBytes(reader.readCount("string byte length")));
|
|
534
|
+
}
|
|
535
|
+
})();
|
|
536
|
+
|
|
537
|
+
export const FfiConverterBytes = new (class extends AbstractFfiConverterByteArray {
|
|
538
|
+
allocationSize(value) {
|
|
539
|
+
return 4 + coerceUint8Array(value, "byte array").byteLength;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
write(value, writer) {
|
|
543
|
+
const bytes = coerceUint8Array(value, "byte array");
|
|
544
|
+
writer.writeInt32(normalizeCollectionLength(bytes.byteLength, "byte array length"));
|
|
545
|
+
writer.writeBytes(bytes);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
read(reader) {
|
|
549
|
+
return reader.readBytes(reader.readCount("byte array length"));
|
|
550
|
+
}
|
|
551
|
+
})();
|
|
552
|
+
|
|
553
|
+
export const FfiConverterByteArray = FfiConverterBytes;
|
|
554
|
+
export const FfiConverterArrayBuffer = FfiConverterBytes;
|
|
555
|
+
|
|
556
|
+
export const FfiConverterTimestamp = new (class extends AbstractFfiConverterByteArray {
|
|
557
|
+
allocationSize() {
|
|
558
|
+
return 12;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
write(value, writer) {
|
|
562
|
+
const timestamp = normalizeDate(value);
|
|
563
|
+
const milliseconds = BigInt(timestamp.getTime());
|
|
564
|
+
const negative = milliseconds < 0n;
|
|
565
|
+
const magnitude = negative ? -milliseconds : milliseconds;
|
|
566
|
+
const seconds = magnitude / 1000n;
|
|
567
|
+
const nanos = Number((magnitude % 1000n) * 1000000n);
|
|
568
|
+
|
|
569
|
+
writer.writeInt64(negative ? -seconds : seconds);
|
|
570
|
+
writer.writeUInt32(nanos);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
read(reader) {
|
|
574
|
+
const seconds = reader.readInt64();
|
|
575
|
+
const nanos = reader.readUInt32();
|
|
576
|
+
if (nanos > 999999999) {
|
|
577
|
+
throw new ConverterRangeError(
|
|
578
|
+
`timestamp nanosecond component ${String(nanos)} is out of range.`,
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
const magnitudeMs = (seconds < 0n ? -seconds : seconds) * 1000n + BigInt(nanos / 1000000);
|
|
583
|
+
if (magnitudeMs > MAX_DATE_MILLISECONDS) {
|
|
584
|
+
throw new ConverterRangeError(
|
|
585
|
+
`timestamp ${String(magnitudeMs)}ms exceeds the supported Date range.`,
|
|
586
|
+
);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
return new Date(seconds < 0n ? -Number(magnitudeMs) : Number(magnitudeMs));
|
|
590
|
+
}
|
|
591
|
+
})();
|
|
592
|
+
|
|
593
|
+
export const FfiConverterDuration = new (class extends AbstractFfiConverterByteArray {
|
|
594
|
+
allocationSize() {
|
|
595
|
+
return 12;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
write(value, writer) {
|
|
599
|
+
const milliseconds = normalizeDurationMilliseconds(value);
|
|
600
|
+
const seconds = milliseconds / 1000n;
|
|
601
|
+
const nanos = Number((milliseconds % 1000n) * 1000000n);
|
|
602
|
+
|
|
603
|
+
writer.writeUInt64(seconds);
|
|
604
|
+
writer.writeUInt32(nanos);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
read(reader) {
|
|
608
|
+
const seconds = reader.readUInt64();
|
|
609
|
+
const nanos = reader.readUInt32();
|
|
610
|
+
if (nanos > 999999999) {
|
|
611
|
+
throw new ConverterRangeError(
|
|
612
|
+
`duration nanosecond component ${String(nanos)} is out of range.`,
|
|
613
|
+
);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
return toSafeNumber(seconds * 1000n, "duration milliseconds") + nanos / 1000000;
|
|
617
|
+
}
|
|
618
|
+
})();
|
|
619
|
+
|
|
620
|
+
export class FfiConverterOptional extends AbstractFfiConverterByteArray {
|
|
621
|
+
constructor(innerConverter) {
|
|
622
|
+
super();
|
|
623
|
+
this.innerConverter = innerConverter;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
allocationSize(value) {
|
|
627
|
+
if (value == null) {
|
|
628
|
+
return 1;
|
|
629
|
+
}
|
|
630
|
+
return 1 + this.innerConverter.allocationSize(value);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
write(value, writer) {
|
|
634
|
+
if (value == null) {
|
|
635
|
+
writer.writeInt8(0);
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
writer.writeInt8(1);
|
|
639
|
+
this.innerConverter.write(value, writer);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
read(reader) {
|
|
643
|
+
const tag = reader.readInt8();
|
|
644
|
+
switch (tag) {
|
|
645
|
+
case 0:
|
|
646
|
+
return undefined;
|
|
647
|
+
case 1:
|
|
648
|
+
return this.innerConverter.read(reader);
|
|
649
|
+
default:
|
|
650
|
+
throw new UnexpectedOptionTag(tag);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
function normalizeSequence(value) {
|
|
656
|
+
if (Array.isArray(value)) {
|
|
657
|
+
return value;
|
|
658
|
+
}
|
|
659
|
+
if (value != null && typeof value !== "string" && typeof value[Symbol.iterator] === "function") {
|
|
660
|
+
return Array.from(value);
|
|
661
|
+
}
|
|
662
|
+
throw new TypeError("sequence values must be arrays or iterable collections.");
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
export class FfiConverterArray extends AbstractFfiConverterByteArray {
|
|
666
|
+
constructor(innerConverter) {
|
|
667
|
+
super();
|
|
668
|
+
this.innerConverter = innerConverter;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
allocationSize(value) {
|
|
672
|
+
const items = normalizeSequence(value);
|
|
673
|
+
return (
|
|
674
|
+
4 +
|
|
675
|
+
items.reduce(
|
|
676
|
+
(total, item) => total + this.innerConverter.allocationSize(item),
|
|
677
|
+
0,
|
|
678
|
+
)
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
write(value, writer) {
|
|
683
|
+
const items = normalizeSequence(value);
|
|
684
|
+
writer.writeInt32(normalizeCollectionLength(items.length, "sequence length"));
|
|
685
|
+
for (const item of items) {
|
|
686
|
+
this.innerConverter.write(item, writer);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
read(reader) {
|
|
691
|
+
const itemCount = reader.readCount("sequence length");
|
|
692
|
+
const items = new Array(itemCount);
|
|
693
|
+
for (let index = 0; index < itemCount; index += 1) {
|
|
694
|
+
items[index] = this.innerConverter.read(reader);
|
|
695
|
+
}
|
|
696
|
+
return items;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
export const FfiConverterSequence = FfiConverterArray;
|
|
701
|
+
|
|
702
|
+
function normalizeEntries(value) {
|
|
703
|
+
if (value instanceof Map) {
|
|
704
|
+
return Array.from(value.entries());
|
|
705
|
+
}
|
|
706
|
+
if (Array.isArray(value)) {
|
|
707
|
+
return value;
|
|
708
|
+
}
|
|
709
|
+
if (value != null && typeof value[Symbol.iterator] === "function") {
|
|
710
|
+
return Array.from(value);
|
|
711
|
+
}
|
|
712
|
+
throw new TypeError("map values must be Maps or iterable entry collections.");
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
export class FfiConverterMap extends AbstractFfiConverterByteArray {
|
|
716
|
+
constructor(keyConverter, valueConverter) {
|
|
717
|
+
super();
|
|
718
|
+
this.keyConverter = keyConverter;
|
|
719
|
+
this.valueConverter = valueConverter;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
allocationSize(value) {
|
|
723
|
+
const entries = normalizeEntries(value);
|
|
724
|
+
return entries.reduce((total, entry) => {
|
|
725
|
+
if (!Array.isArray(entry) || entry.length !== 2) {
|
|
726
|
+
throw new TypeError("map entries must be two-item [key, value] pairs.");
|
|
727
|
+
}
|
|
728
|
+
return (
|
|
729
|
+
total +
|
|
730
|
+
this.keyConverter.allocationSize(entry[0]) +
|
|
731
|
+
this.valueConverter.allocationSize(entry[1])
|
|
732
|
+
);
|
|
733
|
+
}, 4);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
write(value, writer) {
|
|
737
|
+
const entries = normalizeEntries(value);
|
|
738
|
+
writer.writeInt32(normalizeCollectionLength(entries.length, "map length"));
|
|
739
|
+
for (const entry of entries) {
|
|
740
|
+
if (!Array.isArray(entry) || entry.length !== 2) {
|
|
741
|
+
throw new TypeError("map entries must be two-item [key, value] pairs.");
|
|
742
|
+
}
|
|
743
|
+
this.keyConverter.write(entry[0], writer);
|
|
744
|
+
this.valueConverter.write(entry[1], writer);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
read(reader) {
|
|
749
|
+
const entryCount = reader.readCount("map length");
|
|
750
|
+
const map = new Map();
|
|
751
|
+
for (let index = 0; index < entryCount; index += 1) {
|
|
752
|
+
const key = this.keyConverter.read(reader);
|
|
753
|
+
const value = this.valueConverter.read(reader);
|
|
754
|
+
map.set(key, value);
|
|
755
|
+
}
|
|
756
|
+
return map;
|
|
757
|
+
}
|
|
758
|
+
}
|