Skip to content

Commit

Permalink
Remove code related to nodejs usages
Browse files Browse the repository at this point in the history
  • Loading branch information
CNSeniorious000 authored Sep 24, 2024
1 parent 7e7cadb commit 6c7be8d
Show file tree
Hide file tree
Showing 11 changed files with 36 additions and 664 deletions.
38 changes: 4 additions & 34 deletions src/js/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { CanvasInterface, canvas } from "./canvas";

import { PackageData, loadPackage, loadedPackages } from "./load-package";
import { type PyProxy, type PyDict } from "generated/pyproxy";
import { loadBinaryFile, nodeFSMod } from "./compat";
import { loadBinaryFile } from "./compat";
import { version } from "./version";
import { setStdin, setStdout, setStderr } from "./streams";
import { scheduleCallback } from "./scheduler";
import { TypedArray } from "./types";
import { IN_NODE, detectEnvironment } from "./environments";
import { detectEnvironment } from "./environments";
import "./literal-map.js";
import {
makeGlobalsProxy,
Expand Down Expand Up @@ -195,8 +195,8 @@ export class PyodideAPI {
errorCallback?: (message: string) => void;
checkIntegrity?: boolean;
} = {
checkIntegrity: true,
},
checkIntegrity: true,
},
): Promise<Array<PackageData>> {
let pyimports = API.pyodide_code.find_imports(code);
let imports;
Expand Down Expand Up @@ -552,36 +552,6 @@ export class PyodideAPI {
};
}

/**
* Mounts a host directory into Pyodide file system. Only works in node.
*
* @param emscriptenPath The absolute path in the Emscripten file system to
* mount the native directory. If the directory does not exist, it will be
* created. If it does exist, it must be empty.
* @param hostPath The host path to mount. It must be a directory that exists.
*/
static mountNodeFS(emscriptenPath: string, hostPath: string): void {
if (!IN_NODE) {
throw new Error("mountNodeFS only works in Node");
}
ensureMountPathExists(emscriptenPath);
let stat;
try {
stat = nodeFSMod.lstatSync(hostPath);
} catch (e) {
throw new Error(`hostPath '${hostPath}' does not exist`);
}
if (!stat.isDirectory()) {
throw new Error(`hostPath '${hostPath}' is not a directory`);
}

Module.FS.mount(
Module.FS.filesystems.NODEFS,
{ root: hostPath },
emscriptenPath,
);
}

/**
* Tell Pyodide about Comlink.
* Necessary to enable importing Comlink proxies into Python.
Expand Down
162 changes: 4 additions & 158 deletions src/js/compat.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,16 @@
import ErrorStackParser from "./vendor/stackframe/error-stack-parser";
import {
IN_NODE,
IN_NODE_ESM,
IN_BROWSER_MAIN_THREAD,
IN_BROWSER_WEB_WORKER,
IN_NODE_COMMONJS,
} from "./environments";
import { Lockfile } from "./types";

let nodeUrlMod: typeof import("node:url");
let nodePath: typeof import("node:path");
let nodeVmMod: typeof import("node:vm");
/** @private */
export let nodeFSMod: typeof import("node:fs");
/** @private */
export let nodeFsPromisesMod: typeof import("node:fs/promises");

declare var globalThis: {
importScripts: (url: string) => void;
document?: typeof document;
fetch?: typeof fetch;
};

/**
* If we're in node, it's most convenient to import various node modules on
* initialization. Otherwise, this does nothing.
* @private
*/
export async function initNodeModules() {
if (!IN_NODE) {
return;
}
// @ts-ignore
nodeUrlMod = (await import("node:url")).default;
nodeFSMod = await import("node:fs");
nodeFsPromisesMod = await import("node:fs/promises");

// @ts-ignore
nodeVmMod = (await import("node:vm")).default;
nodePath = await import("node:path");
pathSep = nodePath.sep;

// Emscripten uses `require`, so if it's missing (because we were imported as
// an ES6 module) we need to polyfill `require` with `import`. `import` is
// async and `require` is synchronous, so we import all packages that might be
// required up front and define require to look them up in this table.

if (typeof require !== "undefined") {
return;
}
// These are all the packages required in pyodide.asm.js. You can get this
// list with:
// $ grep -o 'require("[a-z]*")' pyodide.asm.js | sort -u
const fs = nodeFSMod;
const crypto = await import("node:crypto");
const ws = await import("ws");
const child_process = await import("node:child_process");
const node_modules: { [mode: string]: any } = {
fs,
crypto,
ws,
child_process,
};
// Since we're in an ES6 module, this is only modifying the module namespace,
// it's still private to Pyodide.
(globalThis as any).require = function (mod: string): any {
return node_modules[mod];
};
}

function node_resolvePath(path: string, base?: string): string {
return nodePath.resolve(base || ".", path);
}

function browser_resolvePath(path: string, base?: string): string {
if (base === undefined) {
// @ts-ignore
Expand All @@ -82,11 +20,7 @@ function browser_resolvePath(path: string, base?: string): string {
}

export let resolvePath: (rest: string, base?: string) => string;
if (IN_NODE) {
resolvePath = node_resolvePath;
} else {
resolvePath = browser_resolvePath;
}
resolvePath = browser_resolvePath;

/**
* Get the path separator. If we are on Linux or in the browser, it's /.
Expand All @@ -95,45 +29,6 @@ if (IN_NODE) {
*/
export let pathSep: string;

if (!IN_NODE) {
pathSep = "/";
}

/**
* Load a binary file, only for use in Node. If the path explicitly is a URL,
* then fetch from a URL, else load from the file system.
* @param indexURL base path to resolve relative paths
* @param path the path to load
* @param checksum sha-256 checksum of the package
* @returns An ArrayBuffer containing the binary data
* @private
*/
function node_getBinaryResponse(
path: string,
_file_sub_resource_hash?: string | undefined, // Ignoring sub resource hash. See issue-2431.
):
| { response: Promise<Response>; binary?: undefined }
| { binary: Promise<Uint8Array> } {
if (path.startsWith("file://")) {
// handle file:// with filesystem operations rather than with fetch.
path = path.slice("file://".length);
}
if (path.includes("://")) {
// If it has a protocol, make a fetch request
return { response: fetch(path) };
} else {
// Otherwise get it from the file system
return {
binary: nodeFsPromisesMod
.readFile(path)
.then(
(data: Buffer) =>
new Uint8Array(data.buffer, data.byteOffset, data.byteLength),
),
};
}
}

/**
* Load a binary file, only for use in browser. Resolves relative paths against
* indexURL.
Expand All @@ -159,11 +54,7 @@ export let getBinaryResponse: (
) =>
| { response: Promise<Response>; binary?: undefined }
| { response?: undefined; binary: Promise<Uint8Array> };
if (IN_NODE) {
getBinaryResponse = node_getBinaryResponse;
} else {
getBinaryResponse = browser_getBinaryResponse;
}
getBinaryResponse = browser_getBinaryResponse;

export async function loadBinaryFile(
path: string,
Expand Down Expand Up @@ -206,53 +97,21 @@ if (IN_BROWSER_MAIN_THREAD) {
}
}
};
} else if (IN_NODE) {
loadScript = nodeLoadScript;
} else {
throw new Error("Cannot determine runtime environment");
}

/**
* Load a text file and executes it as Javascript
* @param url The path to load. May be a url or a relative file system path.
* @private
*/
async function nodeLoadScript(url: string) {
if (url.startsWith("file://")) {
// handle file:// with filesystem operations rather than with fetch.
url = url.slice("file://".length);
}
if (url.includes("://")) {
// If it's a url, load it with fetch then eval it.
nodeVmMod.runInThisContext(await (await fetch(url)).text());
} else {
// Otherwise, hopefully it is a relative path we can load from the file
// system.
await import(/* webpackIgnore: true */ nodeUrlMod.pathToFileURL(url).href);
}
}

export async function loadLockFile(lockFileURL: string): Promise<Lockfile> {
if (IN_NODE) {
await initNodeModules();
const package_string = await nodeFsPromisesMod.readFile(lockFileURL, {
encoding: "utf8",
});
return JSON.parse(package_string);
} else {
let response = await fetch(lockFileURL);
return await response.json();
}
let response = await fetch(lockFileURL);
return await response.json();
}

/**
* Calculate the directory name of the current module.
* This is used to guess the indexURL when it is not provided.
*/
export async function calculateDirname(): Promise<string> {
if (IN_NODE_COMMONJS) {
return __dirname;
}

let err: Error;
try {
Expand All @@ -262,19 +121,6 @@ export async function calculateDirname(): Promise<string> {
}
let fileName = ErrorStackParser.parse(err)[0].fileName!;

if (IN_NODE && !fileName.startsWith("file://")) {
fileName = `file://${fileName}`; // Error stack filenames are not starting with `file://` in `Bun`
}

if (IN_NODE_ESM) {
const nodePath = await import("node:path");
const nodeUrl = await import("node:url");

// FIXME: We would like to use import.meta.url here,
// but mocha seems to mess with compiling typescript files to ES6.
return nodeUrl.fileURLToPath(nodePath.dirname(fileName));
}

const indexOfLastSlash = fileName.lastIndexOf(pathSep);
if (indexOfLastSlash === -1) {
throw new Error(
Expand Down
16 changes: 0 additions & 16 deletions src/js/emscripten-settings.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/** @private */

import { ConfigType } from "./pyodide";
import { initializeNativeFS } from "./nativefs";
import { loadBinaryFile, getBinaryResponse } from "./compat";
import { API, PreRunFunc } from "./types";

Expand Down Expand Up @@ -100,19 +99,6 @@ function setEnvironment(env: { [key: string]: string }): PreRunFunc {
};
}

/**
* Mount local directories to the virtual file system. Only for Node.js.
* @param mounts The list of paths to mount.
*/
function mountLocalDirectories(mounts: string[]): PreRunFunc {
return (Module) => {
for (const mount of mounts) {
Module.FS.mkdirTree(mount);
Module.FS.mount(Module.FS.filesystems.NODEFS, { root: mount }, mount);
}
};
}

/**
* Install the Python standard library to the virtual file system.
*
Expand Down Expand Up @@ -169,8 +155,6 @@ function getFileSystemInitializationFuncs(config: ConfigType): PreRunFunc[] {
installStdlib(stdLibURL),
createHomeDirectory(config.env.HOME),
setEnvironment(config.env),
mountLocalDirectories(config._node_mounts),
initializeNativeFS,
];
}

Expand Down
31 changes: 1 addition & 30 deletions src/js/environments.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,7 @@
// @ts-nocheck

/** @private */
export const IN_NODE =
typeof process === "object" &&
typeof process.versions === "object" &&
typeof process.versions.node === "string" &&
!process.browser; /* This last condition checks if we run the browser shim of process */

/** @private */
export const IN_NODE_COMMONJS =
IN_NODE &&
typeof module !== "undefined" &&
typeof module.exports !== "undefined" &&
typeof require !== "undefined" &&
typeof __dirname !== "undefined";

/** @private */
export const IN_NODE_ESM = IN_NODE && !IN_NODE_COMMONJS;

/** @private */
export const IN_BUN = typeof globalThis.Bun !== "undefined";

/** @private */
export const IN_DENO = typeof Deno !== "undefined"; // just in case...

/** @private */
export const IN_BROWSER = !IN_NODE && !IN_DENO;
export const IN_BROWSER = true;

/** @private */
export const IN_BROWSER_MAIN_THREAD =
Expand Down Expand Up @@ -54,11 +30,6 @@ export const IN_SAFARI =
*/
export function detectEnvironment(): Record<string, boolean> {
return {
IN_NODE: IN_NODE,
IN_NODE_COMMONJS: IN_NODE_COMMONJS,
IN_NODE_ESM: IN_NODE_ESM,
IN_BUN: IN_BUN,
IN_DENO: IN_DENO,
IN_BROWSER: IN_BROWSER,
IN_BROWSER_MAIN_THREAD: IN_BROWSER_MAIN_THREAD,
IN_BROWSER_WEB_WORKER: IN_BROWSER_WEB_WORKER,
Expand Down
Loading

0 comments on commit 6c7be8d

Please sign in to comment.