A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://docs.deno.com/runtime/reference/deno_namespace_apis/ below:

Deno Namespace APIs

The global Deno namespace contains APIs that are not web standard, including APIs for reading from files, opening TCP sockets, serving HTTP, and executing subprocesses, etc.

Explore all Deno APIs

Below we highlight some of the most important Deno APIs to know.

File System Jump to heading#

The Deno runtime comes with various functions for working with files and directories. You will need to use --allow-read and --allow-write permissions to gain access to the file system.

Refer to the links below for code examples of how to use the file system functions.

Network Jump to heading#

The Deno runtime comes with built-in functions for dealing with connections to network ports.

Refer to the links below for code examples for common functions.

For practical examples of networking functionality:

Subprocesses Jump to heading#

The Deno runtime comes with built-in functions for spinning up subprocesses.

Refer to the links below for code samples of how to create a subprocess.

Errors Jump to heading#

The Deno runtime comes with 20 error classes that can be raised in response to a number of conditions.

Some examples are:

Deno.errors.NotFound;
Deno.errors.WriteZero;

They can be used as below:

try {
  const file = await Deno.open("./some/file.txt");
} catch (error) {
  if (error instanceof Deno.errors.NotFound) {
    console.error("the file was not found");
  } else {
    
    throw error;
  }
}
HTTP Server Jump to heading#

Deno has two HTTP Server APIs:

To start an HTTP server on a given port, use the Deno.serve function. This function takes a handler function that will be called for each incoming request, and is expected to return a response (or a promise resolving to a response). For example:

Deno.serve((_req) => {
  return new Response("Hello, World!");
});

By default Deno.serve will listen on port 8000, but this can be changed by passing in a port number in options bag as the first or second argument.

You can read more about how to use the HTTP server APIs.

For practical examples of HTTP servers:

Permissions Jump to heading#

Permissions are granted from the CLI when running the deno command. User code will often assume its own set of required permissions, but there is no guarantee during execution that the set of granted permissions will align with this.

In some cases, ensuring a fault-tolerant program requires a way to interact with the permission system at runtime.

Permission descriptors Jump to heading#

On the CLI, read permission for /foo/bar is represented as --allow-read=/foo/bar. In runtime JS, it is represented as the following:

const desc = { name: "read", path: "/foo/bar" } as const;

Other examples:


const desc1 = { name: "write" } as const;


const desc2 = { name: "write", path: "foo/bar" } as const;


const desc3 = { name: "net" } as const;


const desc4 = { name: "net", host: "127.0.0.1:8000" } as const;


const desc5 = { name: "hrtime" } as const;

See PermissionDescriptor in API reference for more details. Synchronous API counterparts (ex. Deno.permissions.querySync) exist for all the APIs described below.

Query permissions Jump to heading#

Check, by descriptor, if a permission is granted or not.



const desc1 = { name: "read", path: "/foo" } as const;
console.log(await Deno.permissions.query(desc1));


const desc2 = { name: "read", path: "/foo/bar" } as const;
console.log(await Deno.permissions.query(desc2));


const desc3 = { name: "read", path: "/bar" } as const;
console.log(await Deno.permissions.query(desc3));

If --deny-read flag was used to restrict some of the filepaths, the result will contain partial: true describing that not all subpaths have permissions granted:



const desc1 = { name: "read", path: "/foo" } as const;
console.log(await Deno.permissions.query(desc1));


const desc2 = { name: "read", path: "/foo/bar" } as const;
console.log(await Deno.permissions.query(desc2));


const desc3 = { name: "read", path: "/bar" } as const;
console.log(await Deno.permissions.query(desc3));

Permission states Jump to heading#

A permission state can be either "granted", "prompt" or "denied". Permissions which have been granted from the CLI will query to { state: "granted" }. Those which have not been granted query to { state: "prompt" } by default, while { state: "denied" } reserved for those which have been explicitly refused. This will come up in Request permissions.

Permission strength Jump to heading#

The intuitive understanding behind the result of the second query in Query permissions is that read access was granted to /foo and /foo/bar is within /foo so /foo/bar is allowed to be read. This hold true, unless the CLI-granted permission is partial to the queried permissions (as an effect of using a --deny-* flag).

We can also say that desc1 is stronger than desc2. This means that for any set of CLI-granted permissions:

  1. If desc1 queries to { state: "granted", partial: false } then so must desc2.
  2. If desc2 queries to { state: "denied", partial: false } then so must desc1.

More examples:

const desc1 = { name: "write" } as const;

const desc2 = { name: "write", path: "/foo" } as const;

const desc3 = { name: "net", host: "127.0.0.1" } as const;

const desc4 = { name: "net", host: "127.0.0.1:8000" } as const;
Request permissions Jump to heading#

Request an ungranted permission from the user via CLI prompt.



const desc1 = { name: "read", path: "/foo" } as const;
const status1 = await Deno.permissions.request(desc1);

console.log(status1);


const desc2 = { name: "read", path: "/bar" } as const;
const status2 = await Deno.permissions.request(desc2);

console.log(status2);

If the current permission state is "prompt", a prompt will appear on the user's terminal asking them if they would like to grant the request. The request for desc1 was granted so its new status is returned and execution will continue as if --allow-read=/foo was specified on the CLI. The request for desc2 was denied so its permission state is downgraded from "prompt" to "denied".

If the current permission state is already either "granted" or "denied", the request will behave like a query and just return the current status. This prevents prompts both for already granted permissions and previously denied requests.

Revoke permissions Jump to heading#

Downgrade a permission from "granted" to "prompt".



const desc = { name: "read", path: "/foo" } as const;
console.log(await Deno.permissions.revoke(desc));

What happens when you try to revoke a permission which is partial to one granted on the CLI?



const desc = { name: "read", path: "/foo/bar" } as const;
console.log(await Deno.permissions.revoke(desc));

const cliDesc = { name: "read", path: "/foo" } as const;
console.log(await Deno.permissions.revoke(cliDesc));

The CLI-granted permission, which implies the revoked permission, was also revoked.

To understand this behavior, imagine that Deno stores an internal set of explicitly granted permission descriptors. Specifying --allow-read=/foo,/bar on the CLI initializes this set to:

[
  { name: "read", path: "/foo" },
  { name: "read", path: "/bar" },
];

Granting a runtime request for { name: "write", path: "/foo" } updates the set to:

[
  { name: "read", path: "/foo" },
  { name: "read", path: "/bar" },
  { name: "write", path: "/foo" },
];

Deno's permission revocation algorithm works by removing every element from this set which is stronger than the argument permission descriptor.

Deno does not allow "fragmented" permission states, where some strong permission is granted with exclusions of weak permissions implied by it. Such a system would prove increasingly complex and unpredictable as you factor in a wider variety of use cases and the "denied" state. This is a calculated trade-off of granularity for security.

Deno supports a number of properties and methods on the import.meta API. It can be used to get information about the module, such as the module's URL.

import.meta.url Jump to heading#

Returns the URL of the current module.

main.ts

console.log(import.meta.url);
$ deno run main.ts
file:///dev/main.ts

$ deno run https:/example.com/main.ts
https://example.com/main.ts
import.meta.main Jump to heading#

Returns whether the current module is the entry point to your program.

main.ts

import "./other.ts";

console.log(`Is ${import.meta.url} the main module?`, import.meta.main);

other.ts

console.log(`Is ${import.meta.url} the main module?`, import.meta.main);
$ deno run main.ts
Is file:///dev/other.ts the main module? false
Is file:///dev/main.ts the main module? true
import.meta.filename Jump to heading#

This property is only available for local modules (module that have file:///... specifier) and returns undefined for remote modules.

Returns the fully resolved path to the current module. The value contains OS specific path separators.

main.ts

console.log(import.meta.filename);

On Unix:

$ deno run main.ts
/dev/main.ts

$ deno run https://example.com/main.ts
undefined

On Windows:

$ deno run main.ts
C:\dev\main.ts

$ deno run https://example.com/main.ts
undefined
import.meta.dirname Jump to heading#

This property is only available for local modules (module that have file:///... specifier) and returns undefined for remote modules.

Returns the fully resolved path to the directory containing the current module. The value contains OS specific path separators.

main.ts

console.log(import.meta.dirname);

On Unix:

$ deno run main.ts
/dev/

$ deno run https://example.com/main.ts
undefined

On Windows:

$ deno run main.ts
C:\dev\

$ deno run https://example.com/main.ts
undefined
import.meta.resolve Jump to heading#

Resolve specifiers relative to the current module.

const worker = new Worker(import.meta.resolve("./worker.ts"));

The import.meta.resolve API takes into account the currently applied import map, which gives you the ability to resolve "bare" specifiers as well.

With such import map loaded...

{
  "imports": {
    "fresh": "https://deno.land/x/fresh@1.0.1/dev.ts"
  }
}

...you can now resolve:

resolve.js

console.log(import.meta.resolve("fresh"));
$ deno run resolve.js
https://deno.land/x/fresh@1.0.1/dev.ts
FFI Jump to heading#

The FFI (foreign function interface) API allows users to call libraries written in native languages that support the C ABIs (C/C++, Rust, Zig, V, etc.) using Deno.dlopen.

Here's an example showing how to call a Rust function from Deno:

// add.rs
#[no_mangle]
pub extern "C" fn add(a: isize, b: isize) -> isize {
    a + b
}

Compile it to a C dynamic library (libadd.so on Linux):

rustc --crate-type cdylib add.rs

In C you can write it as:

// add.c
int add(int a, int b) {
  return a + b;
}

And compile it:

// unix
cc -c -o add.o add.c
cc -shared -W -o libadd.so add.o
// Windows
cl /LD add.c /link /EXPORT:add

Calling the library from Deno:





let libSuffix = "";
switch (Deno.build.os) {
  case "windows":
    libSuffix = "dll";
    break;
  case "darwin":
    libSuffix = "dylib";
    break;
  default:
    libSuffix = "so";
    break;
}

const libName = `./libadd.${libSuffix}`;

const dylib = Deno.dlopen(
  libName,
  {
    "add": { parameters: ["isize", "isize"], result: "isize" },
  } as const,
);


const result = dylib.symbols.add(35, 34); 

console.log(`Result from external addition of 35 and 34: ${result}`);

Run with --allow-ffi and --unstable flag:

deno run --allow-ffi --unstable ffi.ts
Non-blocking FFI Jump to heading#

There are many use cases where users might want to run CPU-bound FFI functions in the background without blocking other tasks on the main thread.

As of Deno 1.15, symbols can be marked nonblocking in Deno.dlopen. These function calls will run on a dedicated blocking thread and will return a Promise resolving to the desired result.

Example of executing expensive FFI calls with Deno:

// sleep.c
#ifdef _WIN32
#include 
#else
#include 
#endif

int sleep(unsigned int ms) {
  #ifdef _WIN32
  Sleep(ms);
  #else
  struct timespec ts;
  ts.tv_sec = ms / 1000;
  ts.tv_nsec = (ms % 1000) * 1000000;
  nanosleep(&ts, NULL);
  #endif
}

Calling it from Deno:


const library = Deno.dlopen(
  "./sleep.so",
  {
    sleep: {
      parameters: ["usize"],
      result: "void",
      nonblocking: true,
    },
  } as const,
);

library.symbols.sleep(500).then(() => console.log("After"));
console.log("Before");

Result:

$ deno run --allow-ffi --unstable unblocking_ffi.ts
Before
After
Callbacks Jump to heading#

Deno FFI API supports creating C callbacks from JavaScript functions for calling back into Deno from dynamic libraries. An example of how callbacks are created and used is as follows:


const library = Deno.dlopen(
  "./callback.so",
  {
    set_status_callback: {
      parameters: ["function"],
      result: "void",
    },
    start_long_operation: {
      parameters: [],
      result: "void",
    },
    check_status: {
      parameters: [],
      result: "void",
    },
  } as const,
);

const callback = new Deno.UnsafeCallback(
  {
    parameters: ["u8"],
    result: "void",
  } as const,
  (success: number) => {},
);


library.symbols.set_status_callback(callback.pointer);

library.symbols.start_long_operation();



library.symbols.check_status();

If an UnsafeCallback's callback function throws an error, the error will get propagated up to the function that triggered the callback to be called (above, that would be check_status()) and can be caught there. If a callback returning a value throws then Deno will return 0 (null pointer for pointers) as the result.

UnsafeCallback is not deallocated by default as it can cause use-after-free bugs. To properly dispose of an UnsafeCallback its close() method must be called.

const callback = new Deno.UnsafeCallback(
  { parameters: [], result: "void" } as const,
  () => {},
);


callback.close();

It is also possible for native libraries to setup interrupt handlers and to have those directly trigger the callback. However, this is not recommended and may cause unexpected side-effects and undefined behaviour. Preferably any interrupt handlers would only set a flag that can later be polled similarly to how check_status() is used above.

Supported types Jump to heading#

Here's a list of types supported currently by the Deno FFI API.

FFI Type Deno C Rust i8 number char / signed char i8 u8 number unsigned char u8 i16 number short int i16 u16 number unsigned short int u16 i32 number int / signed int i32 u32 number unsigned int u32 i64 bigint long long int i64 u64 bigint unsigned long long int u64 usize bigint size_t usize isize bigint size_t isize f32 number float f32 f64 number double f64 void[1] undefined void () pointer {} | null void * *mut c_void buffer[2] TypedArray | null uint8_t * *mut u8 function[3] {} | null void (*fun)() Option<extern "C" fn()> { struct: [...] }[4] TypedArray struct MyStruct MyStruct

As of Deno 1.25, the pointer type has been split into a pointer and a buffer type to ensure users take advantage of optimizations for Typed Arrays, and as of Deno 1.31 the JavaScript representation of pointer has become an opaque pointer object or null for null pointers.

deno_bindgen Jump to heading#

deno_bindgen is the official tool to simplify glue code generation of Deno FFI libraries written in Rust.

It is similar to wasm-bindgen in the Rust Wasm ecosystem.

Here's an example showing its usage:

// mul.rs
use deno_bindgen::deno_bindgen;

#[deno_bindgen]
struct Input {
  a: i32,
  b: i32,
}

#[deno_bindgen]
fn mul(input: Input) -> i32 {
  input.a * input.b
}

Run deno_bindgen to generate bindings. You can now directly import them into Deno:


import { mul } from "./bindings/bindings.ts";
mul({ a: 10, b: 2 }); 

Any issues related to deno_bindgen should be reported at https://github.com/denoland/deno_bindgen/issues

Program Lifecycle Jump to heading#

Deno supports browser compatible lifecycle events:

You can use these events to provide setup and cleanup code in your program.

Listeners for load events can be asynchronous and will be awaited, this event cannot be canceled. Listeners for beforeunload need to be synchronous and can be cancelled to keep the program running. Listeners for unload events need to be synchronous and cannot be cancelled.

main.ts

main.ts

import "./imported.ts";

const handler = (e: Event): void => {
  console.log(`got ${e.type} event in event handler (main)`);
};

globalThis.addEventListener("load", handler);

globalThis.addEventListener("beforeunload", handler);

globalThis.addEventListener("unload", handler);

globalThis.onload = (e: Event): void => {
  console.log(`got ${e.type} event in onload function (main)`);
};

globalThis.onbeforeunload = (e: Event): void => {
  console.log(`got ${e.type} event in onbeforeunload function (main)`);
};

globalThis.onunload = (e: Event): void => {
  console.log(`got ${e.type} event in onunload function (main)`);
};

console.log("log from main script");

imported.ts

const handler = (e: Event): void => {
  console.log(`got ${e.type} event in event handler (imported)`);
};

globalThis.addEventListener("load", handler);
globalThis.addEventListener("beforeunload", handler);
globalThis.addEventListener("unload", handler);

globalThis.onload = (e: Event): void => {
  console.log(`got ${e.type} event in onload function (imported)`);
};

globalThis.onbeforeunload = (e: Event): void => {
  console.log(`got ${e.type} event in onbeforeunload function (imported)`);
};

globalThis.onunload = (e: Event): void => {
  console.log(`got ${e.type} event in onunload function (imported)`);
};

console.log("log from imported script");

A couple notes on this example:

$ deno run main.ts
log from imported script
log from main script
got load event in event handler (imported)
got load event in event handler (main)
got load event in onload function (main)
got onbeforeunload event in event handler (imported)
got onbeforeunload event in event handler (main)
got onbeforeunload event in onbeforeunload function (main)
got unload event in event handler (imported)
got unload event in event handler (main)
got unload event in onunload function (main)

All listeners added using addEventListener were run, but onload, onbeforeunload and onunload defined in main.ts overrode handlers defined in imported.ts.

In other words, you can use addEventListener to register multiple "load" or "unload" event handlers, but only the last defined onload, onbeforeunload, onunload event handlers will be executed. It is preferable to use addEventListener when possible for this reason.

beforeunload Jump to heading#

let count = 0;

console.log(count);

globalThis.addEventListener("beforeunload", (e) => {
  console.log("About to exit...");
  if (count < 4) {
    e.preventDefault();
    console.log("Scheduling more work...");
    setTimeout(() => {
      console.log(count);
    }, 100);
  }

  count++;
});

globalThis.addEventListener("unload", (e) => {
  console.log("Exiting");
});

count++;
console.log(count);

setTimeout(() => {
  count++;
  console.log(count);
}, 100);

Running this program will print:

$ deno run beforeunload.js
0
1
2
About to exit...
Scheduling more work...
3
About to exit...
Scheduling more work...
4
About to exit...
Exiting
unhandledrejection event Jump to heading#

This event is fired when a promise that has no rejection handler is rejected, ie. a promise that has no .catch() handler or a second argument to .then().


globalThis.addEventListener("unhandledrejection", (e) => {
  console.log("unhandled rejection at:", e.promise, "reason:", e.reason);
  e.preventDefault();
});

function Foo() {
  this.bar = Promise.reject(new Error("bar not available"));
}

new Foo();
Promise.reject();

Running this program will print:

$ deno run unhandledrejection.js
unhandled rejection at: Promise {
  <rejected> Error: bar not available
    at new Foo (file:///dev/unhandled_rejection.js:7:29)
    at file:///dev/unhandled_rejection.js:10:1
} reason: Error: bar not available
    at new Foo (file:///dev/unhandled_rejection.js:7:29)
    at file:///dev/unhandled_rejection.js:10:1
unhandled rejection at: Promise { <rejected> undefined } reason: undefined

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4