Socket
Socket
Sign inDemoInstall

undici

Package Overview
Dependencies
Maintainers
2
Versions
211
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

undici - npm Package Compare versions

Comparing version 3.1.0 to 3.2.0

lib/agent.js

8

index.d.ts
import Pool from './types/pool'
import Client from './types/client'
import errors from './types/errors'
import { Agent, setGlobalAgent, request, stream, pipeline } from './types/agent'
export { Pool, Client, errors }
export { Pool, Client, errors, Agent, setGlobalAgent, request, stream, pipeline }
export default Undici

@@ -14,2 +15,7 @@

var errors: typeof import('./types/errors');
var Agent: typeof import('./types/agent').Agent;
var setGlobalAgent: typeof import('./types/agent').setGlobalAgent;
var request: typeof import('./types/agent').request;
var stream: typeof import('./types/agent').stream;
var pipeline: typeof import('./types/agent').pipeline;
}

13

index.js

@@ -6,2 +6,3 @@ 'use strict'

const Pool = require('./lib/pool')
const { Agent, request, stream, pipeline, setGlobalAgent } = require('./lib/agent')

@@ -14,8 +15,2 @@ Client.prototype.request = require('./lib/client-request')

Pool.prototype.request = require('./lib/client-request')
Pool.prototype.stream = require('./lib/client-stream')
Pool.prototype.pipeline = require('./lib/client-pipeline')
Pool.prototype.upgrade = require('./lib/client-upgrade')
Pool.prototype.connect = require('./lib/client-connect')
function undici (url, opts) {

@@ -29,2 +24,8 @@ return new Pool(url, opts)

undici.Agent = Agent
undici.request = request
undici.stream = stream
undici.pipeline = pipeline
undici.setGlobalAgent = setGlobalAgent
module.exports = undici
'use strict'
/* global WeakRef, FinalizationRegistry */

@@ -8,2 +9,3 @@ const assert = require('assert')

const net = require('net')
const { NotSupportedError } = require('./errors')

@@ -81,5 +83,5 @@ function nop () {}

function parseHeaders (headers, obj = {}) {
for (var i = 0; i < headers.length; i += 2) {
var key = headers[i].toLowerCase()
var val = obj[key]
for (let i = 0; i < headers.length; i += 2) {
const key = headers[i].toLowerCase()
let val = obj[key]
if (!val) {

@@ -114,2 +116,41 @@ obj[key] = headers[i + 1]

/* istanbul ignore next: https://github.com/tc39/proposal-weakrefs */
function weakCache (fn) {
/* istanbul ignore next: */
if (typeof WeakRef === 'undefined' || typeof FinalizationRegistry === 'undefined') {
throw new NotSupportedError('In order to use this feature, `WeakRef` and `FinalizationRegistry` must be defined as global objects. Check your Node.js version to be sure it is v14.6.0 or greater.')
}
const cache = new Map()
const cleanup = new FinalizationRegistry(key => {
// get the WeakRef from the cache
const ref = cache.get(key)
// if the WeakRef exists and the object has been reclaimed
if (ref !== undefined && ref.deref() === undefined) {
// remove the WeakRef from the cache
cache.delete(key)
}
})
return key => {
// check the cache for an existing WeakRef
const ref = cache.get(key)
// if one exists in the cache try to return the WeakRef
if (ref !== undefined) {
const cached = ref.deref()
if (cached !== undefined) {
return cached
}
}
// otherwise, if it isn't in the cache or the reference has been cleaned up, create a new one!
const value = fn(key)
// add a WeakRef of the value to the cache
cache.set(key, new WeakRef(value))
// add the value to the finalization registry
cleanup.register(value, key)
return value
}
}
module.exports = {

@@ -125,3 +166,4 @@ nop,

bodyLength,
isBuffer
isBuffer,
weakCache
}

@@ -17,14 +17,20 @@ 'use strict'

const kClosedResolve = Symbol('closed resolve')
const kOptions = Symbol('options')
const kUrl = Symbol('url')
const kOnDrain = Symbol('onDrain')
const kOnConnect = Symbol('onConnect')
const kOnDisconnect = Symbol('onDisconnect')
class Pool extends EventEmitter {
constructor (url, {
connections,
...options
} = {}) {
constructor (url, options = {}) {
super()
if (connections != null && (!Number.isFinite(connections) || connections <= 0)) {
const { connections } = options
if (connections != null && (!Number.isFinite(connections) || connections < 0)) {
throw new InvalidArgumentError('invalid connections')
}
this[kUrl] = url
this[kOptions] = JSON.parse(JSON.stringify(options))
this[kQueue] = new FixedQueue()

@@ -34,8 +40,7 @@ this[kClosedPromise] = null

this[kDestroyed] = false
this[kClients] = Array.from({
length: connections || 10
}, () => new Client(url, options))
this[kClients] = []
const pool = this
function onDrain () {
this[kOnDrain] = function onDrain () {
const queue = pool[kQueue]

@@ -58,15 +63,9 @@

function onConnect () {
this[kOnConnect] = function onConnect () {
pool.emit('connect', this)
}
function onDisconnect () {
this[kOnDisconnect] = function onDisconnect () {
pool.emit('disconnect', this)
}
for (const client of this[kClients]) {
client.on('drain', onDrain)
client.on('connect', onConnect)
client.on('disconnect', onDisconnect)
}
}

@@ -84,4 +83,17 @@

const client = this[kClients].find(client => !client.busy)
let client = this[kClients].find(client => !client.busy)
if (!client) {
const { connections, ...options } = this[kOptions]
if (!connections || this[kClients].length < connections) {
client = new Client(this[kUrl], options)
.on('drain', this[kOnDrain])
.on('connect', this[kOnConnect])
.on('disconnect', this[kOnDisconnect])
this[kClients].push(client)
}
}
if (!client) {
this[kQueue].push({ opts, handler })

@@ -159,2 +171,8 @@ } else {

Pool.prototype.request = require('./client-request')
Pool.prototype.stream = require('./client-stream')
Pool.prototype.pipeline = require('./client-pipeline')
Pool.prototype.upgrade = require('./client-upgrade')
Pool.prototype.connect = require('./client-connect')
module.exports = Pool
{
"name": "undici",
"version": "3.1.0",
"version": "3.2.0",
"description": "An HTTP/1.1 client, written from scratch for Node.js",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -36,2 +36,24 @@ # undici

## Quick Start
```js
import { request } from 'undici'
const {
statusCode,
headers,
trailers,
body
} = await request('http://localhost:3000/foo')
console.log('response received', statusCode)
console.log('headers', headers)
for await (const data of body) {
console.log('data', chunk)
}
console.log('trailers', trailers)
```
## API

@@ -615,2 +637,88 @@

### `new undici.Agent(opts)`
* opts `undici.Pool.options` - options passed through to Pool constructor
Returns: `Agent`
Requires: Node.js v14+
Returns a new Agent instance for use with pool based requests or the following top-level methods `request`, `pipeline`, and `stream`.
#### `agent.get(origin): Pool`
* origin `string` - A pool origin to be retrieved from the Agent.
Requires: Node.js v14+
This method retrieves Pool instances from the Agent. If the pool does not exist it is automatically added. You do not need to manually close these pools as they are automatically removed using a WeakCache based on WeakRef and FinalizationRegistry.
The following methods `request`, `pipeline`, and `stream` utilize this feature.
### `undici.setGlobalAgent(agent)`
* agent `Agent`
Sets the global agent used by `request`, `pipeline`, and `stream` methods.
The default global agent creates `undici.Pool`s with no max number of
connections.
Requires: Node.js v14+
The agent must only **implement** the `Agent` API; not necessary extend from it.
### `undici.request(url[, opts]): Promise`
* url `string | URL | object`
* opts `{ agent: Agent } & client.request.opts`
`url` may contain path. `opts` may not contain path. `opts.method` is `GET` by default.
Calls `pool.request(opts)` on the pool returned from either the globalAgent (see [setGlobalAgent](#undicisetglobalagentagent)) or the agent passed to the `opts` argument.
Returns a promise with the result of the `request` method.
### `undici.stream(url, opts, factory): Promise`
* url `string | URL | object`
* opts `{ agent: Agent } & client.stream.opts`
* factory `client.stream.factory`
`url` may contain path. `opts` may not contain path.
See [client.stream](#clientstreamopts-factorydata-callbackerr-promisevoid) for details on the `opts` and `factory` arguments.
Calls `pool.stream(opts, factory)` on the pool returned from either the globalAgent (see [setGlobalAgent](#undicisetglobalagentagent)) or the agent passed to the `opts` argument.
Result is returned in the factory function. See [client.stream](#clientstreamopts-factorydata-callbackerr-promisevoid) for more details.
### `undici.pipeline(url, opts, handler): Duplex`
* url `string | URL | object`
* opts `{ agent: Agent } & client.pipeline.opts`
* handler `client.pipeline.handler`
`url` may contain path. `opts` may not contain path.
See [client.pipeline](#clientpipelineopts-handlerdata-duplex) for details on the `opts` and `handler` arguments.
Calls `pool.pipeline(opts, factory)` on the pool returned from either the globalAgent (see [setGlobalAgent](#undicisetglobalagentagent)) or the agent passed to the `opts` argument.
See [client.pipeline](#clientpipelineopts-handlerdata-duplex) for more details.
### `client.upgrade(opts[, callback(err, data)]): Promise|Void`
* url `string | URL | object`
* opts `{ agent: Agent } & client.upgrade.opts`
`url` may contain path. `opts` may not contain path.
### `client.connect(opts[, callback(err, data)]): Promise|Void`
* url `string | URL | object`
* opts `{ agent: Agent } & client.connect.opts`
`url` may contain path. `opts` may not contain path.
## Specification Compliance

@@ -617,0 +725,0 @@

@@ -287,4 +287,2 @@ 'use strict'

t.strictEqual(total, 10)
pool.dispatch({}, noop)

@@ -328,2 +326,4 @@ pool.dispatch({}, noop)

t.strictEqual(total, 2)
t.end()

@@ -370,12 +370,5 @@ })

test('invalid options throws', (t) => {
t.plan(6)
t.plan(4)
try {
new Pool(null, { connections: 0 }) // eslint-disable-line
} catch (err) {
t.ok(err instanceof errors.InvalidArgumentError)
t.strictEqual(err.message, 'invalid connections')
}
try {
new Pool(null, { connections: -1 }) // eslint-disable-line

@@ -382,0 +375,0 @@ } catch (err) {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc