crossbind 2.0.0-beta.60 → 2.0.0-beta.63
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 +8 -6
- package/package.json +6 -1
- package/src/actions/buildDependencies.js +37 -9
- package/src/actions/buildExternal.js +9 -1
- package/src/actions/buildJs.js +1 -1
- package/src/actions/buildLib.js +27 -8
- package/src/actions/buildNativeCommand.js +84 -0
- package/src/actions/buildNode.js +190 -0
- package/src/actions/buildTypes.js +8 -2
- package/src/actions/buildWasiCommand.js +0 -4
- package/src/actions/buildWasm.js +92 -95
- package/src/actions/cloudCommands.js +133 -0
- package/src/actions/createImportedBridges.js +64 -0
- package/src/actions/createInterface.js +318 -65
- package/src/actions/createLib.js +60 -43
- package/src/actions/getAllBridges.js +1 -1
- package/src/actions/getData.js +4 -1
- package/src/actions/getLinkInputs.js +70 -0
- package/src/actions/isSourceNewer.js +2 -0
- package/src/actions/licenses.js +175 -17
- package/src/actions/prepareConanDependencies.js +51 -0
- package/src/actions/publishBinary.js +32 -0
- package/src/actions/run.js +124 -32
- package/src/actions/runnerCommands.js +421 -0
- package/src/actions/writeRuntimeEntry.js +69 -0
- package/src/assets/cmake/CMakeLists.txt +1 -1
- package/src/assets/cmake/command/CMakeLists.txt +21 -0
- package/src/assets/cmake/command/command.cpp +1 -0
- package/src/assets/cmake/dist.cmake +2 -1
- package/src/assets/configure/install.sh +22 -0
- package/src/assets/js-runtime/adapters/path-url.js +6 -3
- package/src/assets/js-runtime/adapters/unboundMessage.js +2 -0
- package/src/assets/js-runtime/adapters/worker-comlink.js +87 -56
- package/src/assets/js-runtime/core.js +11 -0
- package/src/assets/node-import-hooks.mjs +61 -0
- package/src/assets/toolchain-digests.json +27 -13
- package/src/assets/wasi-runtime/stubs.c +29 -0
- package/src/bin.js +290 -37
- package/src/index.js +6 -1
- package/src/integration/bindHeaderImports.js +18 -0
- package/src/integration/getCrossbindScript.js +53 -19
- package/src/integration/getDependFilePath.js +18 -12
- package/src/integration/resolveNativeImport.js +14 -0
- package/src/node/dev.mjs +19 -0
- package/src/runner/blobs.js +135 -0
- package/src/runner/files.js +193 -0
- package/src/runner/server.js +320 -0
- package/src/state/attachConanDependencies.js +56 -0
- package/src/state/index.js +31 -20
- package/src/state/loadConfig.js +36 -24
- package/src/state/refreshBuiltDependencies.js +20 -0
- package/src/state/refreshConanDependencies.js +17 -0
- package/src/utils/androidToolchain.js +4 -0
- package/src/utils/appRustCrates.js +17 -1
- package/src/utils/appSources.js +112 -0
- package/src/utils/archiveFlags.js +12 -0
- package/src/utils/boundHeaders.js +79 -0
- package/src/utils/bridgeExtras.js +486 -0
- package/src/utils/bridgeRuntimeFixes.js +48 -0
- package/src/utils/bundledLicenses.js +26 -0
- package/src/utils/cargoImport.js +44 -0
- package/src/utils/cargoTarget.js +23 -3
- package/src/utils/cloudAccount.js +55 -0
- package/src/utils/conanDependencies.js +66 -0
- package/src/utils/conanImport.js +58 -0
- package/src/utils/conanInstall.js +154 -0
- package/src/utils/conanProfile.js +203 -0
- package/src/utils/conanStage.js +292 -0
- package/src/utils/copyToDistSource.js +13 -0
- package/src/utils/cppDts.js +134 -55
- package/src/utils/darwinToolchain.js +11 -0
- package/src/utils/dirLock.js +137 -28
- package/src/utils/downloadAndExtractFile.js +34 -7
- package/src/utils/embindArgumentGuards.js +84 -0
- package/src/utils/embindCallArguments.js +19 -0
- package/src/utils/embindJspiQueue.js +25 -0
- package/src/utils/embindRsFingerprint.js +26 -0
- package/src/utils/execContainer.js +49 -0
- package/src/utils/headerImports.js +56 -0
- package/src/utils/hostPlatform.js +21 -0
- package/src/utils/inputStamp.js +23 -0
- package/src/utils/iosToolchain.js +6 -0
- package/src/utils/isSourceCmakePackage.js +10 -0
- package/src/utils/licenseReport.js +11 -2
- package/src/utils/linkLayout.js +8 -1
- package/src/utils/linuxToolchain.js +24 -0
- package/src/utils/makeTreeWritable.js +12 -0
- package/src/utils/nativeImports.js +23 -0
- package/src/utils/nativeSourceStamp.js +36 -0
- package/src/utils/nodeDevBuild.js +92 -0
- package/src/utils/packageLicense.js +101 -0
- package/src/utils/pthreadMainScript.js +14 -0
- package/src/utils/pullDockerImage.js +10 -5
- package/src/utils/relocatePrebuilt.js +119 -0
- package/src/utils/remoteClient.js +127 -0
- package/src/utils/remoteOutputs.js +39 -0
- package/src/utils/remoteRunner.js +97 -0
- package/src/utils/remoteUpload.js +134 -0
- package/src/utils/replaceFile.js +8 -0
- package/src/utils/resolveCompanionPackage.js +51 -0
- package/src/utils/resolveEmbindNapi.js +22 -0
- package/src/utils/resolveEmbindRust.js +17 -52
- package/src/utils/runCargo.js +51 -53
- package/src/utils/runConan.js +257 -0
- package/src/utils/runtimeEntries.js +56 -0
- package/src/utils/rustBridgeGen.js +903 -253
- package/src/utils/rustMt.js +4 -0
- package/src/utils/scopedEmbind.js +22 -0
- package/src/utils/selectRunner.js +81 -0
- package/src/utils/sourceFingerprint.js +4 -3
- package/src/utils/swigInterface.js +86 -6
- package/src/utils/systemKeys.js +43 -3
- package/src/utils/targets.js +104 -3
- package/src/utils/toolchainNotices.js +5 -0
- package/src/utils/wasiToolchain.js +14 -1
- package/src/utils/windowsToolchain.js +18 -0
- package/vitest.config.js +11 -0
- package/src/utils/cppFieldBindings.js +0 -23
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
callWithVectorCoercion, wrapWithVectorCoercion, setCoercionModule, unwrapCoercionProxy,
|
|
6
6
|
} from './vector-coercion.js';
|
|
7
7
|
import { patchModuleForExceptionDecode } from './exception-decode.js';
|
|
8
|
+
import urlPath from './path-url.js';
|
|
9
|
+
import { UNBOUND_MESSAGE } from './unboundMessage.js';
|
|
8
10
|
|
|
9
11
|
const isWorkerScope = typeof WorkerGlobalScope !== 'undefined'
|
|
10
12
|
&& typeof self !== 'undefined'
|
|
@@ -12,17 +14,39 @@ const isWorkerScope = typeof WorkerGlobalScope !== 'undefined'
|
|
|
12
14
|
|
|
13
15
|
// === Embind <-> Comlink Bridge ===
|
|
14
16
|
// Worker-side registry: id -> original embind object
|
|
15
|
-
// Main-thread registry:
|
|
17
|
+
// Main-thread registry: handle -> id
|
|
16
18
|
const embindRegistry = new Map();
|
|
17
19
|
const embindProxyIds = new WeakMap();
|
|
18
20
|
let nextEmbindId = 1;
|
|
19
21
|
|
|
22
|
+
// The objects the worker hands out are reached through the module's channel, so writes to them keep their order
|
|
23
|
+
// with the calls after them; messages on different channels keep none.
|
|
24
|
+
const HANDLES = '__crossbindHandles';
|
|
25
|
+
let remoteModule = null;
|
|
26
|
+
|
|
20
27
|
function registerEmbindObject(obj) {
|
|
21
28
|
const id = nextEmbindId++;
|
|
22
29
|
embindRegistry.set(id, obj);
|
|
23
30
|
return id;
|
|
24
31
|
}
|
|
25
32
|
|
|
33
|
+
// Comlink answers every member with a remote one: JSON.stringify and String() called toJSON and Symbol.toPrimitive
|
|
34
|
+
// on the worker's object, which has neither, and a member below the module is thenable. A handle answers them as a
|
|
35
|
+
// direct-mode object does.
|
|
36
|
+
const LOCAL_MEMBERS = {
|
|
37
|
+
then: undefined,
|
|
38
|
+
toJSON: () => ({}),
|
|
39
|
+
[Symbol.toPrimitive]: (hint) => (hint === 'number' ? NaN : '[object Object]'),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
function handleFor(id) {
|
|
43
|
+
const handle = new Proxy(remoteModule[HANDLES][id], {
|
|
44
|
+
get: (target, prop) => (Object.hasOwn(LOCAL_MEMBERS, prop) ? LOCAL_MEMBERS[prop] : target[prop]),
|
|
45
|
+
});
|
|
46
|
+
embindProxyIds.set(handle, id);
|
|
47
|
+
return handle;
|
|
48
|
+
}
|
|
49
|
+
|
|
26
50
|
// Reorder transfer handlers for correct priority
|
|
27
51
|
const _proxyHandler = Comlink.transferHandlers.get('proxy');
|
|
28
52
|
const _throwHandler = Comlink.transferHandlers.get('throw');
|
|
@@ -47,22 +71,16 @@ Comlink.transferHandlers.set('proxy', {
|
|
|
47
71
|
canHandle: _proxyHandler.canHandle,
|
|
48
72
|
serialize(obj) {
|
|
49
73
|
if (typeof obj.delete === 'function' && typeof obj.isDeleted === 'function') {
|
|
50
|
-
// CONSTRUCT results (Comlink marks them with proxy()) are
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
const raw = unwrapCoercionProxy(obj);
|
|
55
|
-
const [port, transferables] = _proxyHandler.serialize(wrapWithVectorCoercion(raw));
|
|
56
|
-
const id = registerEmbindObject(raw);
|
|
57
|
-
return [{ __embindId: id, __port: port }, transferables];
|
|
74
|
+
// CONSTRUCT results (Comlink marks them with proxy()) are handed out as
|
|
75
|
+
// method-returned objects are (embindObject handler), and the registry keeps
|
|
76
|
+
// the RAW object so arguments resolve back to real embind identities.
|
|
77
|
+
return [{ __embindId: registerEmbindObject(unwrapCoercionProxy(obj)) }, []];
|
|
58
78
|
}
|
|
59
79
|
return _proxyHandler.serialize(obj);
|
|
60
80
|
},
|
|
61
81
|
deserialize(data) {
|
|
62
82
|
if (data != null && typeof data === 'object' && '__embindId' in data) {
|
|
63
|
-
|
|
64
|
-
embindProxyIds.set(proxy, data.__embindId);
|
|
65
|
-
return proxy;
|
|
83
|
+
return handleFor(data.__embindId);
|
|
66
84
|
}
|
|
67
85
|
return _proxyHandler.deserialize(data);
|
|
68
86
|
},
|
|
@@ -102,40 +120,18 @@ Comlink.transferHandlers.set('embindVector', {
|
|
|
102
120
|
serialize(obj) {
|
|
103
121
|
const len = obj.size();
|
|
104
122
|
const elements = new Array(len);
|
|
105
|
-
let hasObjects = false;
|
|
106
123
|
for (let i = 0; i < len; i++) {
|
|
107
124
|
const elem = obj.get(i);
|
|
108
|
-
elements[i] = elem
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
if (!hasObjects) {
|
|
114
|
-
return [elements, []];
|
|
115
|
-
}
|
|
116
|
-
const transferables = [];
|
|
117
|
-
for (let i = 0; i < len; i++) {
|
|
118
|
-
const elem = elements[i];
|
|
119
|
-
if (elem !== null && typeof elem === 'object') {
|
|
120
|
-
const id = registerEmbindObject(elem);
|
|
121
|
-
const { port1, port2 } = new MessageChannel();
|
|
122
|
-
Comlink.expose(wrapWithVectorCoercion(elem), port1);
|
|
123
|
-
transferables.push(port2);
|
|
124
|
-
elements[i] = { __comlinkProxy: true, __embindId: id, port: port2 };
|
|
125
|
-
}
|
|
125
|
+
elements[i] = elem !== null && typeof elem === 'object'
|
|
126
|
+
? { __comlinkProxy: true, __embindId: registerEmbindObject(elem) }
|
|
127
|
+
: elem;
|
|
126
128
|
}
|
|
127
|
-
return [elements,
|
|
129
|
+
return [elements, []];
|
|
128
130
|
},
|
|
129
131
|
deserialize(elements) {
|
|
130
|
-
return elements.map((elem) =>
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const proxy = Comlink.wrap(elem.port);
|
|
134
|
-
embindProxyIds.set(proxy, elem.__embindId);
|
|
135
|
-
return proxy;
|
|
136
|
-
}
|
|
137
|
-
return elem;
|
|
138
|
-
});
|
|
132
|
+
return elements.map((elem) => (elem && typeof elem === 'object' && elem.__comlinkProxy
|
|
133
|
+
? handleFor(elem.__embindId)
|
|
134
|
+
: elem));
|
|
139
135
|
},
|
|
140
136
|
});
|
|
141
137
|
|
|
@@ -210,16 +206,13 @@ Comlink.transferHandlers.set('embindObject', {
|
|
|
210
206
|
&& typeof obj.isDeleted === 'function';
|
|
211
207
|
},
|
|
212
208
|
serialize(obj) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return [{ __embindId:
|
|
209
|
+
// An object a property returns comes wrapped by its owner's coercion proxy. Registering the raw object,
|
|
210
|
+
// as the proxy handler does, keeps objects read from it one wrapper deep, which an argument's unwrapping
|
|
211
|
+
// undoes.
|
|
212
|
+
return [{ __embindId: registerEmbindObject(unwrapCoercionProxy(obj)) }, []];
|
|
217
213
|
},
|
|
218
214
|
deserialize(data) {
|
|
219
|
-
data.
|
|
220
|
-
const proxy = Comlink.wrap(data.port);
|
|
221
|
-
embindProxyIds.set(proxy, data.__embindId);
|
|
222
|
-
return proxy;
|
|
215
|
+
return handleFor(data.__embindId);
|
|
223
216
|
},
|
|
224
217
|
});
|
|
225
218
|
|
|
@@ -247,16 +240,28 @@ Comlink.transferHandlers.set('embindProxyArray', {
|
|
|
247
240
|
|
|
248
241
|
let _worker = null;
|
|
249
242
|
|
|
243
|
+
// Configurable, so the coercion wrapper wraps the objects read through it as it does every other member.
|
|
244
|
+
export function moduleRoot(m) {
|
|
245
|
+
Object.defineProperty(m, HANDLES, {
|
|
246
|
+
value: new Proxy({}, { get: (_, id) => embindRegistry.get(Number(id)) }),
|
|
247
|
+
configurable: true,
|
|
248
|
+
});
|
|
249
|
+
return wrapWithVectorCoercion(m);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export function adoptModule(remote) {
|
|
253
|
+
remoteModule = remote;
|
|
254
|
+
return remote;
|
|
255
|
+
}
|
|
256
|
+
|
|
250
257
|
function resolveScriptUrl(config) {
|
|
251
258
|
const fileName = config.paths.js || config.paths.worker;
|
|
252
|
-
let prefix =
|
|
259
|
+
let prefix = urlPath.getDefaultPathPrefix();
|
|
253
260
|
if (config.path) {
|
|
254
261
|
prefix = config.path;
|
|
255
262
|
if (prefix.slice(-1) !== '/') prefix += '/';
|
|
256
263
|
}
|
|
257
|
-
|
|
258
|
-
if (output.substring(0, 4) !== 'http' && output[0] !== '/') output = `/${output}`;
|
|
259
|
-
return output;
|
|
264
|
+
return urlPath.finalizePath(prefix + fileName);
|
|
260
265
|
}
|
|
261
266
|
|
|
262
267
|
function exposeWorker(systemConfig, createModule) {
|
|
@@ -269,7 +274,7 @@ function exposeWorker(systemConfig, createModule) {
|
|
|
269
274
|
// comlink throw handler, a raw WebAssembly.Exception does not.
|
|
270
275
|
patchModuleForExceptionDecode(m);
|
|
271
276
|
registerModuleEnums(m);
|
|
272
|
-
return Comlink.proxy(
|
|
277
|
+
return Comlink.proxy(moduleRoot(m));
|
|
273
278
|
},
|
|
274
279
|
};
|
|
275
280
|
Comlink.expose(workerApi);
|
|
@@ -284,10 +289,35 @@ async function initWithWorker(config, userConfig) {
|
|
|
284
289
|
logHandler, errorHandler, onRuntimeInitialized, getWasmFunction, useWorker, workerUrl,
|
|
285
290
|
...serializableConfig
|
|
286
291
|
} = userConfig;
|
|
287
|
-
|
|
292
|
+
// The worker resolves a relative URL against its own script, so it gets the path resolved against the page.
|
|
293
|
+
const workerConfig = config.path ? { ...serializableConfig, path: urlPath.finalizePath(config.path) } : serializableConfig;
|
|
294
|
+
return moduleOnMainThread(adoptModule(await workerApi.init(workerConfig)));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// A call the worker cannot make, because the module lacks the function, fails there with a TypeError from inside comlink
|
|
298
|
+
// that names nothing: the failed call asks for the member, and names it when the module has none.
|
|
299
|
+
function namedCall(member, name, module) {
|
|
300
|
+
return new Proxy(member, {
|
|
301
|
+
// A member still needs Comlink's then to read its value (including an absent export).
|
|
302
|
+
get(target, prop) {
|
|
303
|
+
// Console formatters inspect function names and constructors synchronously.
|
|
304
|
+
if (prop === 'name') return name;
|
|
305
|
+
if (prop === 'constructor') return Function;
|
|
306
|
+
return prop !== 'then' && Object.hasOwn(LOCAL_MEMBERS, prop) ? LOCAL_MEMBERS[prop] : target[prop];
|
|
307
|
+
},
|
|
308
|
+
apply: (call, thisArg, args) => Reflect.apply(call, thisArg, args).catch(async (error) => {
|
|
309
|
+
const isBound = await Promise.resolve(module[name]).then((value) => value !== undefined, () => true);
|
|
310
|
+
if (isBound) throw error;
|
|
311
|
+
throw new Error(`crossbind: ${name} ${UNBOUND_MESSAGE}`);
|
|
312
|
+
}),
|
|
313
|
+
});
|
|
314
|
+
}
|
|
288
315
|
|
|
316
|
+
export function moduleOnMainThread(module) {
|
|
289
317
|
return new Proxy(module, {
|
|
290
318
|
get(target, prop) {
|
|
319
|
+
if (Object.hasOwn(LOCAL_MEMBERS, prop)) return LOCAL_MEMBERS[prop];
|
|
320
|
+
if (prop === 'constructor') return Object;
|
|
291
321
|
if (prop === 'toArray') {
|
|
292
322
|
return function toArray(vector) {
|
|
293
323
|
if (Array.isArray(vector)) return vector;
|
|
@@ -302,7 +332,8 @@ async function initWithWorker(config, userConfig) {
|
|
|
302
332
|
return target.toVector(classOrName, array);
|
|
303
333
|
};
|
|
304
334
|
}
|
|
305
|
-
|
|
335
|
+
const member = target[prop];
|
|
336
|
+
return typeof prop === 'string' && typeof member === 'function' ? namedCall(member, prop, target) : member;
|
|
306
337
|
},
|
|
307
338
|
});
|
|
308
339
|
}
|
|
@@ -73,6 +73,16 @@ function buildLocateFile(config, adapter) {
|
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
// WASMFS's FS.writeFile writes at the end of a file that exists (emsdk 6.0.9 js_api.cpp), where the classic FS
|
|
77
|
+
// replaces it; opening the file for writing empties it first.
|
|
78
|
+
function replaceOnWriteFile(FS) {
|
|
79
|
+
const { writeFile } = FS;
|
|
80
|
+
FS.writeFile = (path, data) => {
|
|
81
|
+
FS.close(FS.open(path, 'w'));
|
|
82
|
+
return writeFile(path, data);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
76
86
|
export function createBaseModule(Module, config, adapter) {
|
|
77
87
|
return new Promise((resolve, reject) => {
|
|
78
88
|
const locateFile = buildLocateFile(config, adapter);
|
|
@@ -137,6 +147,7 @@ export function createBaseModule(Module, config, adapter) {
|
|
|
137
147
|
// fs-browser), which emscripten's onRuntimeInitialized callback cannot, so
|
|
138
148
|
// both hooks run after the factory settles - adapter first, then the user's.
|
|
139
149
|
Module(m).then(async (mod) => {
|
|
150
|
+
if (mod.FS) replaceOnWriteFile(mod.FS);
|
|
140
151
|
if (adapter.onModuleReady) await adapter.onModuleReady(mod, config);
|
|
141
152
|
if (config.onRuntimeInitialized) config.onRuntimeInitialized(mod);
|
|
142
153
|
return mod;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Node's module hooks for the native imports one crossbind build bound, so a Node app imports a header, a
|
|
2
|
+
// conan: header or a package's header the way a bundler plugin lets it. Each resolves to a module that
|
|
3
|
+
// re-exports its names from the runtime entry, which initNative() fills. Copied into dist by the build.
|
|
4
|
+
import { registerHooks } from 'node:module';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const SCHEME = /^(cargo|conan):/;
|
|
9
|
+
const isBare = (specifier) => !/^(\.{1,2}\/|\/|[A-Za-z]:[\\/]|file:)/.test(specifier);
|
|
10
|
+
|
|
11
|
+
function notBound(what, parentURL, cause) {
|
|
12
|
+
const from = parentURL ? `, imported from ${parentURL},` : '';
|
|
13
|
+
return new Error(`crossbind: ${what}${from} is not bound by the last crossbind build. Build again after adding a native import, or start Node with --import crossbind/node/dev to build whenever one is added; an import specifier computed at run time is not found by the build.`, { cause });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const exportOf = (name) => (typeof name === 'string' ? name : `${name.wire} as ${name.local}`);
|
|
17
|
+
const proxyOf = (entry, names) => `export { ${['initNative', 'AllSymbols', ...names.map(exportOf)].join(', ')} } from ${JSON.stringify(entry)};\n`;
|
|
18
|
+
|
|
19
|
+
// Another hook may still serve it; Node's own resolver hands an unknown scheme on unresolved.
|
|
20
|
+
function resolveUnbound(specifier, context, nextResolve) {
|
|
21
|
+
let resolved;
|
|
22
|
+
try {
|
|
23
|
+
resolved = nextResolve(specifier, context);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
throw notBound(specifier, context.parentURL, error);
|
|
26
|
+
}
|
|
27
|
+
if (SCHEME.test(resolved.url)) throw notBound(specifier, context.parentURL);
|
|
28
|
+
return resolved;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// `natives` lists each bound file, relative to the entry, with the bare specifiers that name it and the names it
|
|
32
|
+
// exports, a name the entry exports under another as { local, wire }.
|
|
33
|
+
export default function registerNativeImports(entry, { extensions, natives }) {
|
|
34
|
+
const entryUrl = new URL(entry).href;
|
|
35
|
+
const dir = path.dirname(fileURLToPath(entryUrl));
|
|
36
|
+
const isNative = new RegExp(`\\.(${extensions.join('|')})$`);
|
|
37
|
+
const byFile = new Map();
|
|
38
|
+
const bySpecifier = new Map();
|
|
39
|
+
natives.forEach(({ file, specifiers, names }) => {
|
|
40
|
+
const absolute = path.resolve(dir, file);
|
|
41
|
+
byFile.set(absolute, names);
|
|
42
|
+
specifiers.forEach((specifier) => bySpecifier.set(specifier, pathToFileURL(absolute).href));
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
registerHooks({
|
|
46
|
+
resolve(specifier, context, nextResolve) {
|
|
47
|
+
const url = bySpecifier.get(specifier);
|
|
48
|
+
if (url) return { url, format: 'module', shortCircuit: true };
|
|
49
|
+
if (isBare(specifier) && (SCHEME.test(specifier) || isNative.test(specifier))) return resolveUnbound(specifier, context, nextResolve);
|
|
50
|
+
return nextResolve(specifier, context);
|
|
51
|
+
},
|
|
52
|
+
load(url, context, nextLoad) {
|
|
53
|
+
if (!url.startsWith('file:')) return nextLoad(url, context);
|
|
54
|
+
const file = fileURLToPath(url);
|
|
55
|
+
const names = byFile.get(file);
|
|
56
|
+
if (names) return { format: 'module', source: proxyOf(entryUrl, names), shortCircuit: true };
|
|
57
|
+
if (isNative.test(file)) throw notBound(file);
|
|
58
|
+
return nextLoad(url, context);
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
@@ -1,35 +1,49 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.0.
|
|
2
|
+
"version": "1.0.12",
|
|
3
3
|
"registry": "ghcr.io/crossbind",
|
|
4
4
|
"toolchains": {
|
|
5
|
-
"rust": "1.
|
|
5
|
+
"rust": "1.99.0"
|
|
6
6
|
},
|
|
7
7
|
"images": {
|
|
8
8
|
"rust-sysroot": {
|
|
9
|
-
"index": "sha256:
|
|
9
|
+
"index": "sha256:fcaddb9514956c80c28152679d11817599b3c544e2bb56568d79dbd7699af805",
|
|
10
10
|
"platforms": {
|
|
11
|
-
"linux/arm64": "sha256:
|
|
12
|
-
"linux/amd64": "sha256:
|
|
11
|
+
"linux/arm64": "sha256:70dca2248666ee712ad5cb11fd013274ca4bb1efdafee732a0ec15492889f622",
|
|
12
|
+
"linux/amd64": "sha256:a3377c70598ef4e1918a73feeebb0ec1b80b3cde956daac9b2b62f9d742b88dc"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"base": {
|
|
16
|
-
"index": "sha256:
|
|
16
|
+
"index": "sha256:86c6559bd51c10f8fc1ff6cbc0cf5386115fd7f0491a59f30f0d26a0203c200d",
|
|
17
17
|
"platforms": {
|
|
18
|
-
"linux/amd64": "sha256:
|
|
19
|
-
"linux/arm64": "sha256:
|
|
18
|
+
"linux/amd64": "sha256:16056b4bd85ba1792791401003db0325c31d4aa4821ff40f6f2eb1e0fff1d3ce",
|
|
19
|
+
"linux/arm64": "sha256:8d213f83ddd1ad9101b74b2b071f304ac8924ffbe68d79ece50668076e0172c0"
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"web": {
|
|
23
|
-
"index": "sha256:
|
|
23
|
+
"index": "sha256:ffa089b83160e380e0b4447f483bf66cb87324f89b8e80b5776ed9346275a5ca",
|
|
24
24
|
"platforms": {
|
|
25
|
-
"linux/arm64": "sha256:
|
|
26
|
-
"linux/amd64": "sha256:
|
|
25
|
+
"linux/arm64": "sha256:1baf14ee0f1a821c1562d12902fe362d3639f57acb31f969402f2a2d8486647f",
|
|
26
|
+
"linux/amd64": "sha256:d3bd3aa785447f1679fdcb898921f614579d9eaad2aa9e828675ba7f82dc11ec"
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
29
|
"android": {
|
|
30
|
-
"index": "sha256:
|
|
30
|
+
"index": "sha256:830286886d8bb259e94e112e4f1bab5f153106365b17859d20c9ef714349e520",
|
|
31
31
|
"platforms": {
|
|
32
|
-
"linux/amd64": "sha256:
|
|
32
|
+
"linux/amd64": "sha256:1004144243fea89a8915417954073e8ffabb20d8a9aed31045ce2a95c1abe1da"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"linux": {
|
|
36
|
+
"index": "sha256:8d4cc55d2ef8ea40845fd13708575e06f6aecdc035e7200deddf8c662d5c910f",
|
|
37
|
+
"platforms": {
|
|
38
|
+
"linux/arm64": "sha256:0de59cc6ce7b381f213af0d26ccc83e0c41545a91eb0b36c51832c7fb660566c",
|
|
39
|
+
"linux/amd64": "sha256:3b3bc24d8f5dffe3a2408193265a807764fcf2744243c0a5e07f312f608fc6c0"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"windows": {
|
|
43
|
+
"index": "sha256:a31110874a9b6b9e3fec177edc8a8093905902bcc6abc6a85e45eb0927d4f070",
|
|
44
|
+
"platforms": {
|
|
45
|
+
"linux/arm64": "sha256:bd9ec6ba60952f929e09777374a3bb05512bbe796325c0e8a0b84e1a12d1b86c",
|
|
46
|
+
"linux/amd64": "sha256:01f4bd8c4d1044bde68fe758d2632c510f8efb76aa4bad28696f9e9b199c8f4e"
|
|
33
47
|
}
|
|
34
48
|
}
|
|
35
49
|
}
|
|
@@ -7,12 +7,32 @@
|
|
|
7
7
|
|
|
8
8
|
#include <netinet/in.h>
|
|
9
9
|
#include <sys/socket.h>
|
|
10
|
+
#include <sys/stat.h>
|
|
11
|
+
#include <unistd.h>
|
|
10
12
|
|
|
11
13
|
/* Compiled by the C++ driver at the command link; keep C linkage. */
|
|
12
14
|
#ifdef __cplusplus
|
|
13
15
|
extern "C" {
|
|
14
16
|
#endif
|
|
15
17
|
|
|
18
|
+
/* wasi-libc p2/p3 leaves its output stream at the old offset after SEEK_END. SEEK_SET resets
|
|
19
|
+
that stream, so resolve the end offset through fstat and perform an absolute seek instead. */
|
|
20
|
+
off_t __real_lseek(int fd, off_t offset, int whence);
|
|
21
|
+
off_t __wrap_lseek(int fd, off_t offset, int whence)
|
|
22
|
+
{
|
|
23
|
+
if (whence == SEEK_END) {
|
|
24
|
+
struct stat status;
|
|
25
|
+
if (fstat(fd, &status) != 0) return (off_t)-1;
|
|
26
|
+
off_t absolute;
|
|
27
|
+
if (__builtin_add_overflow(status.st_size, offset, &absolute)) {
|
|
28
|
+
errno = EOVERFLOW;
|
|
29
|
+
return (off_t)-1;
|
|
30
|
+
}
|
|
31
|
+
return __real_lseek(fd, absolute, SEEK_SET);
|
|
32
|
+
}
|
|
33
|
+
return __real_lseek(fd, offset, whence);
|
|
34
|
+
}
|
|
35
|
+
|
|
16
36
|
/* No dynamic loading on WASI; loaders treat NULL as "plugin unavailable". */
|
|
17
37
|
void *dlopen(const char *file, int mode)
|
|
18
38
|
{
|
|
@@ -79,6 +99,15 @@ int getpeername(int fd, struct sockaddr *addr, socklen_t *len)
|
|
|
79
99
|
return crossbind_zeroed_inet(addr, len);
|
|
80
100
|
}
|
|
81
101
|
|
|
102
|
+
/* The WASI SQLite leaves extension loading out, yet SpatiaLite's stored procedures switch it off; this answers
|
|
103
|
+
SQLITE_ERROR as such a build does. Weak, so a SQLite that has the function keeps its own. */
|
|
104
|
+
__attribute__((weak)) int sqlite3_enable_load_extension(void *db, int onoff)
|
|
105
|
+
{
|
|
106
|
+
(void)db;
|
|
107
|
+
(void)onoff;
|
|
108
|
+
return 1;
|
|
109
|
+
}
|
|
110
|
+
|
|
82
111
|
#ifdef __cplusplus
|
|
83
112
|
}
|
|
84
113
|
#endif
|