Aurism CAD parser adaptation for occt-import-js 0.0.23 The adaptation replaces two Emscripten binding factories in occt-import-js.js. The WASM is the unmodified npm release artifact. The build transformation reads the binding functions below from tools/aurism-cad-bindings.txt and inserts them into the wrapper. Build transformation: function adaptOcctBindings(source: string): string { const sourcePath = new URL('./tools/aurism-cad-bindings.txt', import.meta.url); const bindings = readFileSync(sourcePath, 'utf8').replace(/^\uFEFF/, ''); const cppStart = source.indexOf('function newFunc('); const cppEnd = source.indexOf('var ensureOverloadTable=', cppStart); const jsStart = source.indexOf('var __emval_get_method_caller=', cppEnd); const jsEnd = source.indexOf('var __emval_', jsStart + 10); if (!(cppStart >= 0 && cppEnd > cppStart && jsStart > cppEnd && jsEnd > jsStart) || (source.match(/newFunc\(Function,/g) ?? []).length !== 2) { throw new Error('The CAD parser changed. Verify its browser bindings before building.'); } return '/* Aurism modifies two Emscripten binding functions to run without dynamic JavaScript. */\n' + source.slice(0, cppStart) + bindings + 'var craftInvokerFunction=bindCppFunction;' + source.slice(cppEnd, jsStart) + 'var __emval_get_method_caller=bindJsMethod;' + source.slice(jsEnd); } Binding functions: // Apply only to the pinned occt-import-js 0.0.23 browser wrapper. function bindCppFunction(humanName, argTypes, classType, cppInvokerFunc, cppTargetFunc) { if (argTypes.length < 2) { throwBindingError("Arg types must include the return type and receiver"); } const [returnType, receiverType, ...parameterTypes] = argTypes; const hasReceiver = receiverType !== null && classType !== null; const wiredTypes = hasReceiver ? [receiverType, ...parameterTypes] : parameterTypes; const useStack = usesDestructorStack(argTypes); return createNamedFunction(humanName, function (...args) { const destructors = useStack ? [] : null; const values = hasReceiver ? [this, ...args] : args; const wiredValues = wiredTypes.map((type, index) => type.toWireType(destructors, values[index])); const result = cppInvokerFunc(cppTargetFunc, ...wiredValues); if (destructors) { runDestructors(destructors); } else { wiredTypes.forEach((type, index) => type.destructorFunction?.(wiredValues[index])); } return returnType.name === "void" ? undefined : returnType.fromWireType(result); }); } function bindJsMethod(argCount, argTypes, kind) { const [returnType, ...parameterTypes] = emval_lookupTypes(argCount, argTypes); const invoker = (object, func, destructorsRef, address) => { const args = parameterTypes.map(type => { const value = type.readValueFromPointer(address); address += type.argPackAdvance; return value; }); const result = kind === 1 ? Reflect.construct(func, args) : func.call(...(kind === 0 ? [object, ...args] : args)); return returnType.isVoid ? undefined : emval_returnValue(returnType, destructorsRef, result); }; return emval_addMethodCaller(invoker); }