-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NPM and Typescript support #647
base: master
Are you sure you want to change the base?
Conversation
types/index.d.ts
Outdated
screen_dummy?: boolean | ||
} | ||
|
||
declare class V86Starter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be called V86, V86Starter is on its way out (would also be good to rename V86StarterOptions and other mentions).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copy: I am able to rename the interfaces, not the class declarations, or do you wish to rename the V86Starter
to V86
inside the codebase?
types/index.d.ts
Outdated
* @param {number} offset | ||
*/ | ||
write_memory(blob: Array<number> | Uint8Array, offset: number): void | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is brilliant, thanks! Did you write this from scratch or is (at least partially) generated from some of the source files? I'm a bit worried this might become out-of-date over time, although that shouldn't be a blocker for merging for now.
(nitpick: Add a newline at the end of the file)
Minor suggestion: Could you add a test, something very simple (e.g., similar to tests/api/clean-shutdown.js) that demonstrates loading this file with ts-node and using V86 from typescript? Doesn't need to be part of CI or mentioned in the readme yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copy: this is generated from your JSDoc @param types. My approach was to scan through your starter.js
and add typings for members with @exports
, write_memory
or read_memory
had no @exports
on them, but It felt essential.
Minor suggestion: Could you add a test, something very simple (e.g., similar to tests/api/clean-shutdown.js) that demonstrates loading this file with ts-node and using V86 from typescript? Doesn't need to be part of CI or mentioned in the readme yet.
sure.
@ambientlight @copy instead of publishing more mirrors of v86 on NPM, why don't we all maintain the same one? Otherwise it's easy for people to get unmaintained versions and be frustrated with the library. Regarding this PR: very nice work with the TS typings! I think, though, that when publishing it on NPM it should be a module, so that users can import it using bundlers. That's the reason of existence of my fork, but I don't know if @copy wants to have his original work as module also. |
That would be the best, certainly. I am fine with any way @giulioz and @copy think it is best, this draft is what I added few month back for my own experiment.
So here is why this PR is a draft: I am personally consuming it via importmaps for now: <script type="importmap">
{
"imports": {
"@glasssh/v86": "/libv86.js",
"xterm": "./xterm.js",
"xterm-addon-fit": "./xterm-addon-fit.js"
}
}
</script> I think what we can do is probably make closure compiler produce a UMD bundle (I haven't checked @giulioz's fork yet), the UMD can be then distributed and served with both NPM and CDN style. What do you think? I want to do this in the scope of this PR and then make sure it is smooth with bundling via something like rollup or webpack. I don't remember how to make typescript work smoothly with global-scoped and module at the same time, but that's my idea for now. I see other libraries just shipped typescript for moduled bundle and then I need to reimport myself the definitions to the global namespace via something like: declare namespace globalThis {
export { Terminal } from 'xterm'
} |
@copy: I think what was also discussed in a gitter, is that this PR should also add the |
I've tried a lot with it and unfortunately it's quite difficult to produce module-friendly javascript with closure compiler, so I ended up removing it completely and using Rollup instead. I also have performed some tests and the performance benefits introduced by closure compiler are none, so there should be no harm in doing that. The main problem is that v86 relies a lot on working with the global scope, which is difficult to handle when using bundler and typescript. My solution in the fork was to explicitly import and export everything so that it can avoid polluting the global namespace. |
Absolutely agreed. Let's do this now, since we're all here.
I would love to have your changes in the repository. If we can remove the horrible loader code in debug.html — even better. My only requirement is no mandatory
That would be great, and I'd strongly prefer this over using rollup inside of this repository (see the next paragraph).
Removing Closure Compiler entirely is not really an option for me. It does bundling, minifying, basic linting, type-checking, and is much more stable than most things in the npm ecosystem (and it can be installed through npm for the folks who don't want to install java). We could use Rollup only for the npm build, but having a single build system would obviously be nicer. I'm not opposed to refactoring the global stuff if it makes bundling easier.
It is used as the version number (perhaps prefixed with |
True, but closure compiler has a really hard time producing "modern" js understandable by bundlers. Would you be ok with having both of them? I've tried to use closure to make importable modules, but the documentation about that non-existent. Do you have any info for that? |
@giulioz, @copy: Thanks for great input, understood. @giulioz: I was thinking more of a scaffold like at https://stackoverflow.com/a/39862418/2380455, however I have limited experience with I'm seeing a non-minified libv86-debug.js having the following structure: It should fit in to the UMD scaffold if we substitute those with referenced scaffold in the SO's answer. The UMD should then be consumable with tooling like bundlers that understand commonjs or amd. This is quite hypothetic though as I haven't tried it yet. |
I'm not strongly opposed to having both, but it would be nicer if everything was built using a single tool.
There is some support for exports with the V86Starter.prototype.run = function() {
...
};
goog.exportProperty(V86Starter.prototype, "run", V86Starter.prototype.run); (where Indeed there seems to be no support for generating I see two options:
|
@copy, @giulioz : 2 seems to be cleaner (removing those Line 136 in d685053
--output_wrapper 'var v86=(function(){%output% return {V86Starter,CPU}}).call(this);if(typeof module === 'object' && module.exports){module.exports = v86;}'\ need to play around with this more, maybe there is a cleaner way for this. But without code changes, I have failed with my original idea of tampering around the compiled bundle via changing that const path = require('path');
const isProduction = process.env.NODE_ENV == 'production';
const config = {
entry: './src/index.wp.ts',
output: {
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.(js|jsx|tsx|ts)$/i,
loader: 'babel-loader',
exclude: ['/node_modules/'],
}
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
fallback: {
"crypto": false,
"perf_hooks": false,
"fs": false,
"path": false
}
},
externals: {
'./libwabt.js': 'WabtModule',
'./capstone-x86.min.js': 'MCapstone'
}
};
module.exports = () => {
if (isProduction) {
config.mode = 'production';
} else {
config.mode = 'development';
}
return config;
}; |
…v86,V86Starter,CPU,MemoryFileStorage,ServerFileStorageWrapper
I'm testing your typings and I found one missing in
Now the typings result in: Argument of type '{ wasm_fn: (options: WebAssembly.Imports) => Promise<WebAssembly.Exports>; memory_size: number; vga_memory_size: number; screen_container: HTMLElement; bios: { ...; }; vga_bios: { ...; }; fda: { ...; }; autostart: true; }' is not assignable to parameter of type 'V86StarterOptions'.
Object literal may only specify known properties, and 'wasm_fn' does not exist in type 'V86StarterOptions' To fix this, you can simply add to /**
* Reference to the v86 wasm exorted function.
* @default undefined
*/
wasm_fn: (options: WebAssembly.Imports) => Promise<WebAssembly.Exports> |
Btw, I'm working on the "internal" typings as well. I use them because I, despite reading the At the moment, export class CPU {
...
}
declare class V86 {
...
cpu: CPU
...
}
declare class V86Starter {
...
v86: V86
...
} What would be the best way to join this PR? Would you guys like to merge this first and I open another one on top of this? btw, another one: If someone is testing this and already using one of the existing NPM packages out there, they will run in the error below until all of the definitions are wrapped in: Of course this wouldn't be a problem for the when this package is released, as long as we include |
@kyr0: thanks for the feedback, I suspect the typings are incomplete - as at the moment of me writing them - I wasn't much familiar with v86, so anything is certainly very helpful for this PR, thanks.
Sure, you can just add your typing directly to this PR, I can give your write access to the fork (I have sent you the invite)
I will have this addressed now as per original @copy's comment. For now the typing here assume global scope. @copy: I also want to clarify on what should be exposed in total (I just scanned the codebase for those exports snippets). Is it like?:
|
@@ -13,7 +13,7 @@ | |||
"build": "npm run build:all_debug & npm run build:all", | |||
"build:all_debug": "make all-debug", | |||
"build:all": "make all", | |||
"build:release": "make build/libv86.js build/v86.wasm build/v86-fallback.wasm", | |||
"build:release": "make build/libv86.js build/v86.wasm build/v86-fallback.wasm build/capstone-x86.min.js build/libwabt.js", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are only for debugging, I don't think they should be included in a release build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the bundlers will parse the debug.js requires by defaults and would try to bundle those - if we don’t distribute them the bundlers would complain unless we add explicit externs, my thought here was is to make bundling succeed on defaults, but we can also do something so that the compiled code does not contain require() on those two libraries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. If you add if(!DEBUG) return;
to the beginning of the functions that call require
that should cause closure compiler to remove those calls. Alternatively, I'd fine with removing the require call entirely. I haven't used those libraries from node in a long time anyway.
V86Starter has been renamed to V86, and I don't want to expose the name v86 (I actually want to get rid of it). |
@ambientlight You're welcome. I'll add a few hundred more lines tomorrow. Btw, depending on the configuration (no implicit any) |
Hey @ambientlight @copy , sry, I'm sick since yesterday. I'll get back to this once I've recovered. I hope for tomorrow.. |
Are u good now broo?? |
@copy @Zaid-maker @ambientlight My most recent TypeScript types code in 2023 was: declare global {
interface Window { emulator: V86Starter; }
/** set when v86 is built with debug mode enabled */
export const DEBUG: boolean;
export type V86Image =
| { url: string }
| { buffer: ArrayBuffer }
| { url: string, async: false, size?: number }
| { url: string, async: true, size: number }
/**
* A 9p filesystem is supported by the emulator, using a virtio transport. Using it, files can be exchanged with the guest OS
* If `basefs` and `baseurl` are omitted, an empty 9p filesystem is created.
*/
export interface Filesystem9pOptions {
/**
* json file created using [fs2json](https://github.com/copy/v86/blob/master/tools/fs2json.py).
*/
baseurl?: string,
/**
* The base url is the prefix of a url from which the files are available.
* For instance, if the 9p filesystem has a file `/bin/sh`, that file must be accessible from http://localhost/9p/base/bin/sh
*/
basefs?: string
}
export enum LogLevel {
LOG_ALL = -1,
LOG_NONE = 0,
LOG_OTHER = 0x000001,
LOG_CPU = 0x000002,
LOG_FPU = 0x000004,
LOG_MEM = 0x000008,
LOG_DMA = 0x000010,
LOG_IO = 0x000020,
LOG_PS2 = 0x000040,
LOG_PIC = 0x000080,
LOG_VGA = 0x000100,
LOG_PIT = 0x000200,
LOG_MOUSE = 0x000400,
LOG_PCI = 0x000800,
LOG_BIOS = 0x001000,
LOG_FLOPPY = 0x002000,
LOG_SERIAL = 0x004000,
LOG_DISK = 0x008000,
LOG_RTC = 0x010000,
LOG_HPET = 0x020000,
LOG_ACPI = 0x040000,
LOG_APIC = 0x080000,
LOG_NET = 0x100000,
LOG_VIRTIO = 0x200000,
LOG_9P = 0x400000,
LOG_SB16 = 0x800000
}
export enum BootOrder {
CD_FLOPPY_HARDDISK = 0x213,
CD_HARDDISK_FLOPPY = 0x123,
FLOPPY_CD_HARDDISK = 0x231,
FLOPPY_HARDDISK_CD = 0x321,
HARDDISK_CD_FLOPPY = 0x132
}
export interface BusListener {
fn: Function
this_value: V86
}
export class BusConnector {
constructor()
pair: BusConnector
listeners: {
[eventName: string]: Array<BusListener>,
}
/**
* @param {string} name
* @param {function(?)} fn
* @param {Object} this_value
*/
register(name: string, fn: Function, this_value: Object): void
/**
* Unregister one message with the given name and callback
*
* @param {string} name
* @param {function()} fn
*/
unregister(name: string, fn: Function): void
/**
* Send ("emit") a message
*
* @param {string} name
* @param {*=} value
* @param {*=} unused_transfer
*/
send(name: string, value: any, unused_transfer?: any): void
/**
* Send a message, guaranteeing that it is received asynchronously
*
* @param {string} name
* @param {Object=} value
*/
send_async(name: string, value: any): void
}
/**
* Custom emulated ethernet card adapter (pass in V86StarterOptions)
* @see https://github.com/copy/v86/blob/master/src/browser/network.js
*/
export class NetworkAdapter {
constructor(bus: BusConnector)
handle_message(event: any & { data: string | ArrayBufferLike | Blob | ArrayBufferView }): void
handle_close(event: any): void
handle_open(event: any): void
handle_error(event: any): void
destroy(event: any): void
connect(): void
send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void
change_proxy(url: string): void
}
export type V86AutomaticStep =
| {
/** wait for x seconds */
sleep: number
}
| {
/** wait until vga_text is present on the screen */
vga_text: string
}
| {
/** text or scancodes to send */
keyboard_send: number[] | string
}
| {
/** callback to execute */
call: () => void
}
export interface BIOS {
main: ArrayBuffer
vga: ArrayBuffer
}
export interface PackedMemory {
bitmap: Uint8Array
packed_memory: Uint8Array
}
export class CPU {
wm: {
exports: WebAssembly.Exports,
wasm_table: WebAssembly.Table,
}
wasm_memory: WebAssembly.Memory
memory_size: Uint32Array
mem8: Uint8Array
mem32s: Int32Array
segment_is_null: Uint8Array
segment_offsets: Int32Array
segment_limits: Uint32Array
/**
* Wheter or not in protected mode
*/
protected_mode: Int32Array
idtr_size: Int32Array
idtr_offset: Int32Array
/**
* global descriptor table register
*/
gdtr_size: Int32Array
gdtr_offset: Int32Array
tss_size_32: Int32Array
/*
* whether or not a page fault occured
*/
page_fault: Uint32Array
cr: Int32Array
// current privilege level
cpl: Uint8Array
// current operand/address size
is_32: Int32Array
stack_size_32: Int32Array
/**
* Was the last instruction a hlt?
*/
in_hlt: Uint8Array
last_virt_eip: Int32Array
eip_phys: Int32Array
sysenter_cs: Int32Array
sysenter_esp: Int32Array
sysenter_eip: Int32Array
prefixes: Int32Array
flags: Int32Array
/**
* bitmap of flags which are not updated in the flags variable
* changed by arithmetic instructions, so only relevant to arithmetic flags
*/
flags_changed: Int32Array
/**
* enough infos about the last arithmetic operation to compute eflags
*/
last_op1: Int32Array
last_op_size: Int32Array
last_result: Int32Array
current_tsc: Uint32Array
instruction_pointer: Int32Array
previous_ip: Int32Array
/**
* configured by guest
*/
apic_enabled: Uint8Array
/**
* configured when the emulator starts (changes bios initialisation)
*/
acpi_enabled: Uint8Array
bios: BIOS
instruction_counter: Uint32Array
reg32: Int32Array
fpu_st: Int32Array
fpu_stack_empty: Uint8Array
fpu_stack_ptr: Uint8Array
fpu_control_word: Uint16Array
fpu_status_word: Uint16Array
fpu_ip: Int32Array
fpu_ip_selector: Int32Array
fpu_opcode: Int32Array
fpu_dp: Int32Array
fpu_dp_selector: Int32Array
reg_xmm32s: Int32Array
mxcsr: Int32Array
/**
* segment registers, tr and ldtr
*/
sreg: Uint16Array
/**
* Debug registers
*/
dreg: Int32Array
reg_pdpte: Int32Array
svga_dirty_bitmap_min_offset: Uint32Array
svga_dirty_bitmap_max_offset: Uint32Array
/**
* Firmware id value
*/
fw_value: Int32Array
fw_pointer: number
bus: BusConnector
do_many_cycles_count?: number
do_many_cycles_total?: number
seen_code?: Object
seen_code_uncompiled?: Object
get_state: () => Array<number|ArrayBuffer>
set_state: (state: Array<number|ArrayBuffer>) => void
pack_memory: () => PackedMemory
unpack_memory: (bitmap: Uint8Array, packed_memory: Uint8Array) => void
main_run: () => number
reboot_internal: () => void
reset_memory: () => void
create_memory: (size: number) => void
hlt_loop: () => void
hlt_op: () => void
}
export class V86 {
/**
* Set true when the CPU is in idle state
*/
idle: boolean
cpu: CPU
running: boolean
stopped: boolean
tick_counter: boolean
bus: BusConnector
worker: Worker
}
/**
* emulator instance constructor options.
*/
export interface V86StarterOptions {
/**
* Reference to the v86 wasm exorted function.
* @default undefined
*/
wasm_fn: (options: WebAssembly.Imports) => Promise<WebAssembly.Exports>
/**
* Path to v86 wasm artifact
* @default "build/v86.wasm" or "build/v86-debug.wasm" when debug mode enabled
*/
wasm_path?: string
/**
* The memory size in bytes, should be a power of 2.
* @example 16 * 1024 * 1024
* @default 64 * 1024 * 1024
*/
memory_size?: number
/**
* VGA memory size in bytes.
* @example 8 * 1024 * 1024
* @default 8 * 1024 * 1024
*/
vga_memory_size?: number
/**
* If emulation should be started when emulator is ready.
* @default false
*/
autostart?: boolean
/**
* If keyboard should be disabled.
* @default false
*/
disable_keyboard?: boolean
/**
* If mouse should be disabled.
* @default false
*/
disable_mouse?: boolean
/**
* If speaker should be disabled.
* @default false
*/
disable_speaker?: boolean
/**
* The url of a server running websockproxy. See [networking.md](networking.md). Setting this will enable an emulated network card.
* @default undefined
*/
network_relay_url?: string
/**
* Either a url pointing to a bios or an ArrayBuffer, see below.
* @default undefined
*/
bios?: V86Image
/**
* VGA bios, see below.
* @default undefined
*/
vga_bios?: V86Image
/**
* First hard disk, see below.
* @default undefined
*/
hda?: V86Image
/**
* First floppy disk, see below.
* @default undefined
*/
fda?: V86Image
/**
* cdrom
* @default undefined
*/
cdrom?: V86Image
/**
* A Linux kernel image to boot (only bzimage format)
* @default undefined
*/
bzimage?: V86Image
/**
* A Linux ramdisk image
* @default undefined
*/
initrd?: V86Image
/**
* Automatically fetch bzimage and initrd from the specified `filesystem`.
*/
bzimage_initrd_from_filesystem?: boolean
/**
* An initial state to load
* @default undefined
*/
initial_state?: V86Image
/**
* A 9p filesystem
* @default undefined
*/
filesystem?: Filesystem9pOptions
/**
* A textarea that will receive and send data to the emulated serial terminal.
* Alternatively the serial terminal can also be accessed programatically, see [serial.html](../examples/serial.html).
* @default undefined
*/
serial_container?: HTMLTextAreaElement
/**
* Xtermjs serial terminal container. When set, serial_container option is ignored.
* @default undefined
*/
serial_container_xtermjs?: HTMLElement
/**
* An HTMLElement. This should have a certain structure, see [basic.html](../examples/basic.html).
* @default undefined
*/
screen_container?: HTMLElement | null
/**
* ACPI
* @default false
*/
acpi?: boolean
/**
* log level
* @default LogLevel.LOG_NONE
*/
log_level?: LogLevel
/**
* boot order
* @default BootOrder.CD_FLOPPY_HARDDISK
*/
boot_order?: BootOrder
/**
* fast boot
* @default false
*/
fastboot?: boolean
/**
* enables UART1 (Serial port)
* @see http://wiki.osdev.org/UART
* @see https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js
* @see https://www.freebsd.org/doc/en/articles/serial-uart/
* @default undefined
*/
uart1?: boolean
/**
* enables UART2 (Serial port)
* @see http://wiki.osdev.org/UART
* @see https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js
* @see https://www.freebsd.org/doc/en/articles/serial-uart/
* @default undefined
*/
uart2?: boolean
/**
* enables UART3 (Serial port)
* @see http://wiki.osdev.org/UART
* @see https://github.com/s-macke/jor1k/blob/master/js/worker/dev/uart.js
* @see https://www.freebsd.org/doc/en/articles/serial-uart/
* @default undefined
*/
uart3?: boolean
/**
* boot cmdline
*/
cmdline?: string
/**
* Ne2k: should MAC be preserved from the state image
* @default undefined
*/
preserve_mac_from_state_image?: boolean
/**
* custom network adapter
* @default undefined
*/
network_adapter?: NetworkAdapter
/**
* enables screen dummy
* @default undefined
*/
screen_dummy?: boolean
}
export class V86Starter {
constructor(options?: V86StarterOptions)
/**
* bus, use it when you must (there are a few wrappers on top of it in V86Starter that you might find helpful instead)
*/
bus: BusConnector
/**
* The v86 instance.
*/
v86: V86
/**
* Start emulation. Do nothing if emulator is running already. Can be asynchronous.
*/
run(): void
/**
* Stop emulation. Do nothing if emulator is not running. Can be asynchronous.
*/
stop(): void
destroy(): void
/**
* Restart (force a reboot).
*/
restart(): void
/**
* Add an event listener (the emulator is an event emitter). A list of events
* can be found at [events.md](events.md).
*
* The callback function gets a single argument which depends on the event.
*
* @param event Name of the event.
* @param listener The callback function.
*/
add_listener(event: string, listener: Function): void
/**
* Remove an event listener.
*
* @param event
* @param listener
*/
remove_listener(event: string, listener: Function): void
/**
* Restore the emulator state from the given state, which must be an
* ArrayBuffer returned by
* [`save_state`](#save_statefunctionobject-arraybuffer-callback).
*
* Note that the state can only be restored correctly if this constructor has
* been created with the same options as the original instance (e.g., same disk
* images, memory size, etc.).
*
* Different versions of the emulator might use a different format for the
* state buffer.
*
* @param state
*/
restore_state(state: ArrayBuffer): void
/**
* Asynchronously save the current state of the emulator. The first argument to
* the callback is an Error object if something went wrong and is null
* otherwise.
*
* @param callback
*/
save_state(callback: (error: Object | null, state: ArrayBuffer) => void): void
/**
* Return an object with several statistics. Return value looks similar to
* (but can be subject to change in future versions or different
* configurations, so use defensively):
*
* ```javascript
* {
* "cpu": {
* "instruction_counter": 2821610069
* },
* "hda": {
* "sectors_read": 95240,
* "sectors_written": 952,
* "bytes_read": 48762880,
* "bytes_written": 487424,
* "loading": false
* },
* "cdrom": {
* "sectors_read": 0,
* "sectors_written": 0,
* "bytes_read": 0,
* "bytes_written": 0,
* "loading": false
* },
* "mouse": {
* "enabled": true
* },
* "vga": {
* "is_graphical": true,
* "res_x": 800,
* "res_y": 600,
* "bpp": 32
* }
* }
* ```
*
* @deprecated
*/
get_statistics(): Object
get_instruction_counter(): number
is_running(): boolean
/**
* Send a sequence of scan codes to the emulated PS2 controller. A list of
* codes can be found at http://stanislavs.org/helppc/make_codes.html.
* Do nothing if there is no keyboard controller.
*
* @param codes
*/
keyboard_send_scancodes(codes: number[]): void
/**
* Send translated keys
*/
keyboard_send_keys(codes: any[]): void
/**
* Send text
*/
keyboard_send_text(string: string): void
/**
* Download a screenshot.
*/
screen_make_screenshot(): void
/**
* Set the scaling level of the emulated screen.
*
* @param {number} sx
* @param {number} sy
*
* @ignore
* @export
*/
screen_set_scale(sx: number, sy: number): void
/**
* Go fullscreen.
*/
screen_go_fullscreen(): void
/**
* Lock the mouse cursor: It becomes invisble and is not moved out of the browser window.
*/
lock_mouse(): void
/**
* Enable or disable sending mouse events to the emulated PS2 controller.
*/
mouse_set_status(enabled: boolean): void
/**
* Enable or disable sending keyboard events to the emulated PS2 controller.
*/
keyboard_set_status(enabled: boolean): void
/**
* Send a string to the first emulated serial terminal.
*
* @param data
*/
serial0_send(data: string): void
/**
* Send bytes to a serial port (to be received by the emulated PC).
*
* @param serial the index of the serial port
* @param data
*/
serial_send_bytes(serial: number, data: Uint8Array): void
/**
* Mount another filesystem to the current filesystem.
* @param path Path for the mount point
* @param baseurl
* @param basefs As a JSON string
* @param callback
* @export
*/
mount_fs(path: string, baseurl?: string, basefs?: string, callback?: (error: Object | null) => void): void
/**
* Write to a file in the 9p filesystem. Nothing happens if no filesystem has
* been initialized. First argument to the callback is an error object if
* something went wrong and null otherwise.
*
* @param file
* @param data
* @param callback
*/
create_file(file: string, data: Uint8Array, callback?: (error: Object | null) => void): void
/**
* Runs a set of automatic steps
* @param steps
*/
automatically(steps: V86AutomaticStep[]): void
/**
* Reads data from memory at specified offset.
*
* @param offset
* @param length
*/
read_memory(offset: number, length: number): Array<number> | Uint8Array
/**
* Writes data to memory at specified offset.
*
* @param {Array.<number>|Uint8Array} blob
* @param {number} offset
*/
write_memory(blob: Array<number> | Uint8Array, offset: number): void
}
} |
V86Starter
exposed APIsI have used
v86
as a package name