@needle-tools/engine
Version:
Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.
94 lines (78 loc) • 2.92 kB
JavaScript
const peerjsString = `/* needle: fix for peerjs */ window.global = window; var parcelRequire;`
import { needleLog } from './logging.js';
/**
* @param {"build" | "serve"} command
* @param {import('../types/needleConfig').needleMeta | null | undefined} config
* @param {import('../types').userSettings} userSettings
* @returns {import("vite").Plugin | undefined}
*/
export function needlePeerjs(command, config, userSettings) {
if (userSettings.noPeer === true) return;
return {
name: 'needle:peerjs',
enforce: "pre",
transformIndexHtml: {
order: 'pre',
handler(html, _ctx) {
return {
html,
tags: [
{
tag: 'script',
children: peerjsString,
injectTo: 'body-prepend',
},
]
}
},
},
transform: (code, id) => {
return patchWebRTCAdapterForGemini(code, id);
}
}
}
/**
* @param {string} code
* @param {string} id
* @returns {string | undefined}
*/
function patchWebRTCAdapterForGemini(code, id) {
// Match navigator.mediaDevices.getUserMedia assignments
const assignmentRegex = /(navigator\d{0,1})\.mediaDevices\.getUserMedia\s*=\s*function/gm;
let didTransform = false;
let transformedCode = code;
let match;
while ((match = assignmentRegex.exec(code)) !== null) {
const navigatorRef = match[1];
const matchStart = match.index;
// Find the end of the function assignment
let braceCount = 0;
let inFunction = false;
let endIndex = matchStart;
for (let i = matchStart; i < code.length; i++) {
const char = code[i];
if (char === '{') {
braceCount++;
inFunction = true;
} else if (char === '}') {
braceCount--;
if (inFunction && braceCount === 0) {
endIndex = i + 1;
break;
}
}
}
const originalAssignment = code.substring(matchStart, endIndex);
const wrappedAssignment = `if (Object.getOwnPropertyDescriptor(${navigatorRef}.mediaDevices, "getUserMedia")?.writable) {\n ${originalAssignment}\n}`;
didTransform = true;
transformedCode = transformedCode.replace(originalAssignment, wrappedAssignment);
// console.log("-------------------------------\nTRANSFORMED\n", id, "\nOriginal:", originalAssignment, "\nWrapped:", wrappedAssignment, "\n\n");
}
if(!didTransform) return undefined;
if(!didLog) {
needleLog("needle:peerjs", "Fixed WebRTC assignment", "log", { dimBody: false });
didLog = true;
}
return transformedCode;
}
let didLog = false;