Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

qyu

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

qyu - npm Package Compare versions

Comparing version 0.7.1 to 1.0.1

18

CHANGELOG.md

@@ -5,2 +5,20 @@ # Changelog

### [1.0.1](https://github.com/shtaif/qyu/compare/v1.0.0...v1.0.1) (2022-10-21)
### Bug Fixes
* dev dependencies security related bumps ([#21](https://github.com/shtaif/qyu/issues/21)) ([146f9ea](https://github.com/shtaif/qyu/commit/146f9eada069d53653e06c0115cabee260b339ac))
## [1.0.0](https://github.com/shtaif/qyu/compare/v0.7.1...v1.0.0) (2022-10-21)
### ⚠ BREAKING CHANGES
* enqueuing API next iteration (#18)
### Features
* enqueuing API next iteration ([#18](https://github.com/shtaif/qyu/issues/18)) ([36d82ad](https://github.com/shtaif/qyu/commit/36d82adb56ed16ee21e5bbe74cdb3485d7834ed6))
### [0.7.1](https://github.com/shtaif/qyu/compare/v0.7.0...v0.7.1) (2022-10-07)

@@ -7,0 +25,0 @@

19

dist/cjs/Qyu.d.ts

@@ -1,17 +0,10 @@

import QyuBase, { QyuInputOptions, JobFunction } from './QyuBase.js';
import MaybePromise from './utils/MaybePromise.js';
import QyuBase, { QyuInputOptions, JobAddInput } from './QyuBase.js';
declare const QyuInvokable: new (opts?: QyuInputOptions) => Qyu;
declare type Qyu = QyuBase & QyuAddMethodType & QyuMapMethodType;
declare type Qyu = QyuBase & QyuAddMethodType;
declare type QyuAddMethodType = {
<JobResultType>(jobFn: JobFunction<JobResultType>, opts?: {
timeout?: number | null | undefined;
priority?: number | null | undefined;
} | undefined | null): Promise<JobResultType>;
<T>(input: JobAddInput<T>): Promise<T>;
<T extends readonly JobAddInput<unknown>[] | readonly []>(input: T): Promise<{
[K in keyof T]: T[K] extends JobAddInput<infer RetVal> ? RetVal : never;
}>;
};
declare type QyuMapMethodType = {
<IterableVal, JobResultType>(iterable: Iterable<IterableVal>, iterableMapFn: (item: IterableVal, idx: number) => MaybePromise<JobResultType>, opts?: {
timeout?: number | null | undefined;
priority?: number | null | undefined;
} | undefined | null): Promise<JobResultType[]>;
};
export { QyuInvokable as default, QyuInputOptions };

@@ -27,6 +27,4 @@ "use strict";

const qyuAsAny = q;
return new Proxy(((...args) => __awaiter(this, void 0, void 0, function* () {
return args[0][Symbol.iterator] instanceof Function
? qyuAsAny.map(args[0], args[1], args[2])
: qyuAsAny.add(...args);
return new Proxy(((input) => __awaiter(this, void 0, void 0, function* () {
return qyuAsAny.add(input);
})), {

@@ -44,10 +42,10 @@ get: (_target, prop, _receiver) => {

TODOs:
- Upgrade prettier
- Possibly replace all the initial `null` values all around here into `undefined`
- Go through entire `README.md`, most importantly probably convert all imports from `require`s to `import` statements
- Possibly replace all the initial `null` values all around here into `undefined`
- Make all nullable numeric options to be defaulted to `Infinity` to normalize all operations on them and their type checks
- Make up and extract out subtypes of the QyuError for each possible error
- Should I drop the current support for Node.js 7.6.0 in favor of 10.x.x something?
- Upgrade prettier
- Devise and publicly expose a proper way to dequeue jobs
*/
//# sourceMappingURL=Qyu.js.map

@@ -13,10 +13,6 @@ import MaybePromise from './utils/MaybePromise.js';

set(newOpts: QyuInputOptions): void;
add<JobResultVal>(fn: JobFunction<JobResultVal>, opts?: {
timeout?: number | null | undefined;
priority?: number | null | undefined;
} | undefined | null): Promise<JobResultVal>;
map<IterableVal, JobReturnVal>(iterable: Iterable<IterableVal>, iterableMapFn: (item: IterableVal, idx: number) => MaybePromise<JobReturnVal>, opts?: {
timeout?: number | null | undefined;
priority?: number | null | undefined;
} | undefined | null): Promise<JobReturnVal[]>;
add<T>(input: JobAddInput<T>): Promise<T>;
add<T extends readonly JobAddInput<unknown>[] | readonly []>(input: T): Promise<{
[K in keyof T]: T[K] extends JobAddInput<infer RetVal> ? RetVal : never;
}>;
pause(): Promise<undefined | void>;

@@ -41,2 +37,7 @@ resume(): undefined | void;

}
export { QyuBase as default, QyuInputOptions, JobFunction };
declare type JobAddInput<JobResultVal> = JobFunction<JobResultVal> | {
fn: JobFunction<JobResultVal>;
timeout?: number | undefined;
priority?: number | undefined;
};
export { QyuBase as default, QyuInputOptions, JobAddInput, JobFunction };

@@ -48,21 +48,17 @@ "use strict";

}
add(fn, opts) {
return this.enqueue({
fn,
opts: opts !== null && opts !== void 0 ? opts : undefined,
add(input) {
return __awaiter(this, void 0, void 0, function* () {
const normalizeInput = (input) => typeof input !== 'function'
? input
: {
fn: input,
timeout: undefined,
priority: undefined,
};
const result = !Array.isArray(input)
? yield this.enqueue(normalizeInput(input))
: yield Promise.all(input.map(normalizeInput).map(job => this.enqueue(job)));
return result;
});
}
map(iterable, iterableMapFn, opts) {
const promises = [];
let counter = 0;
for (const item of iterable) {
const iterationIdx = counter++;
const promise = this.enqueue({
fn: () => iterableMapFn(item, iterationIdx),
opts: opts !== null && opts !== void 0 ? opts : undefined,
});
promises.push(promise);
}
return Promise.all(promises);
}
pause() {

@@ -105,9 +101,8 @@ return __awaiter(this, void 0, void 0, function* () {

enqueue(params) {
var _a, _b;
const { fn, opts = {} } = params;
const { fn, timeout, priority } = params;
const job = {
fn,
opts: {
timeout: (_a = opts.timeout) !== null && _a !== void 0 ? _a : 0,
priority: (_b = opts.priority) !== null && _b !== void 0 ? _b : 0,
timeout: timeout !== null && timeout !== void 0 ? timeout : 0,
priority: priority !== null && priority !== void 0 ? priority : 0,
},

@@ -122,3 +117,3 @@ deferred: new Deferred_js_1.default(),

}
if (opts.timeout) {
if (typeof job.opts.timeout === 'number' && job.opts.timeout > 0) {
job.timeoutId = setTimeout(() => {

@@ -129,3 +124,3 @@ this.dequeue(job.deferred.promise);

guardUnhandledPromiseRejections(job);
}, opts.timeout);
}, job.opts.timeout);
}

@@ -132,0 +127,0 @@ let i = 0;

@@ -1,17 +0,10 @@

import QyuBase, { QyuInputOptions, JobFunction } from './QyuBase.js';
import MaybePromise from './utils/MaybePromise.js';
import QyuBase, { QyuInputOptions, JobAddInput } from './QyuBase.js';
declare const QyuInvokable: new (opts?: QyuInputOptions) => Qyu;
declare type Qyu = QyuBase & QyuAddMethodType & QyuMapMethodType;
declare type Qyu = QyuBase & QyuAddMethodType;
declare type QyuAddMethodType = {
<JobResultType>(jobFn: JobFunction<JobResultType>, opts?: {
timeout?: number | null | undefined;
priority?: number | null | undefined;
} | undefined | null): Promise<JobResultType>;
<T>(input: JobAddInput<T>): Promise<T>;
<T extends readonly JobAddInput<unknown>[] | readonly []>(input: T): Promise<{
[K in keyof T]: T[K] extends JobAddInput<infer RetVal> ? RetVal : never;
}>;
};
declare type QyuMapMethodType = {
<IterableVal, JobResultType>(iterable: Iterable<IterableVal>, iterableMapFn: (item: IterableVal, idx: number) => MaybePromise<JobResultType>, opts?: {
timeout?: number | null | undefined;
priority?: number | null | undefined;
} | undefined | null): Promise<JobResultType[]>;
};
export { QyuInvokable as default, QyuInputOptions };

@@ -11,6 +11,4 @@ import QyuBase from './QyuBase.js';

const qyuAsAny = q;
return new Proxy((async (...args) => {
return args[0][Symbol.iterator] instanceof Function
? qyuAsAny.map(args[0], args[1], args[2])
: qyuAsAny.add(...args);
return new Proxy((async (input) => {
return qyuAsAny.add(input);
}), {

@@ -29,10 +27,10 @@ get: (_target, prop, _receiver) => {

TODOs:
- Upgrade prettier
- Possibly replace all the initial `null` values all around here into `undefined`
- Go through entire `README.md`, most importantly probably convert all imports from `require`s to `import` statements
- Possibly replace all the initial `null` values all around here into `undefined`
- Make all nullable numeric options to be defaulted to `Infinity` to normalize all operations on them and their type checks
- Make up and extract out subtypes of the QyuError for each possible error
- Should I drop the current support for Node.js 7.6.0 in favor of 10.x.x something?
- Upgrade prettier
- Devise and publicly expose a proper way to dequeue jobs
*/
//# sourceMappingURL=Qyu.js.map

@@ -13,10 +13,6 @@ import MaybePromise from './utils/MaybePromise.js';

set(newOpts: QyuInputOptions): void;
add<JobResultVal>(fn: JobFunction<JobResultVal>, opts?: {
timeout?: number | null | undefined;
priority?: number | null | undefined;
} | undefined | null): Promise<JobResultVal>;
map<IterableVal, JobReturnVal>(iterable: Iterable<IterableVal>, iterableMapFn: (item: IterableVal, idx: number) => MaybePromise<JobReturnVal>, opts?: {
timeout?: number | null | undefined;
priority?: number | null | undefined;
} | undefined | null): Promise<JobReturnVal[]>;
add<T>(input: JobAddInput<T>): Promise<T>;
add<T extends readonly JobAddInput<unknown>[] | readonly []>(input: T): Promise<{
[K in keyof T]: T[K] extends JobAddInput<infer RetVal> ? RetVal : never;
}>;
pause(): Promise<undefined | void>;

@@ -41,2 +37,7 @@ resume(): undefined | void;

}
export { QyuBase as default, QyuInputOptions, JobFunction };
declare type JobAddInput<JobResultVal> = JobFunction<JobResultVal> | {
fn: JobFunction<JobResultVal>;
timeout?: number | undefined;
priority?: number | undefined;
};
export { QyuBase as default, QyuInputOptions, JobAddInput, JobFunction };

@@ -41,21 +41,15 @@ import QyuError from './qyu-error.js';

}
add(fn, opts) {
return this.enqueue({
fn,
opts: opts !== null && opts !== void 0 ? opts : undefined,
});
async add(input) {
const normalizeInput = (input) => typeof input !== 'function'
? input
: {
fn: input,
timeout: undefined,
priority: undefined,
};
const result = !Array.isArray(input)
? await this.enqueue(normalizeInput(input))
: await Promise.all(input.map(normalizeInput).map(job => this.enqueue(job)));
return result;
}
map(iterable, iterableMapFn, opts) {
const promises = [];
let counter = 0;
for (const item of iterable) {
const iterationIdx = counter++;
const promise = this.enqueue({
fn: () => iterableMapFn(item, iterationIdx),
opts: opts !== null && opts !== void 0 ? opts : undefined,
});
promises.push(promise);
}
return Promise.all(promises);
}
async pause() {

@@ -96,9 +90,8 @@ if (this.isPaused) {

enqueue(params) {
var _a, _b;
const { fn, opts = {} } = params;
const { fn, timeout, priority } = params;
const job = {
fn,
opts: {
timeout: (_a = opts.timeout) !== null && _a !== void 0 ? _a : 0,
priority: (_b = opts.priority) !== null && _b !== void 0 ? _b : 0,
timeout: timeout !== null && timeout !== void 0 ? timeout : 0,
priority: priority !== null && priority !== void 0 ? priority : 0,
},

@@ -113,3 +106,3 @@ deferred: new Deferred(),

}
if (opts.timeout) {
if (typeof job.opts.timeout === 'number' && job.opts.timeout > 0) {
job.timeoutId = setTimeout(() => {

@@ -120,3 +113,3 @@ this.dequeue(job.deferred.promise);

guardUnhandledPromiseRejections(job);
}, opts.timeout);
}, job.opts.timeout);
}

@@ -123,0 +116,0 @@ let i = 0;

{
"name": "qyu",
"description": "A general-purpose asynchronous job queue for Node.js",
"version": "0.7.1",
"version": "1.0.1",
"license": "MIT",

@@ -6,0 +6,0 @@ "author": "Dor Shtaif <dorshtaif@gmail.com>",

@@ -13,10 +13,10 @@ # Qyu

async function performRequest(){ // Note that async functions always return a promise. Same could be accomplished with any "normal" function that returns a promise
const { data } = await axios('https://www.example.com');
//....
}
(async () => {
const q = new Qyu({concurrency: 3});
const q = new Qyu({ concurrency: 3 });
async function performRequest(){ // Note that async functions always return a promise. Same could be accomplished with any "normal" function that returns a promise
const {data} = await axios('https://www.example.com');
//....
}
// Basic:

@@ -26,13 +26,16 @@ q(performRequest); // q expects a function that returns a promise

// Extra options:
q(performRequest, {priority: 2});
q({
fn: performRequest,
priority: 2,
});
// Returns promise (resolving or rejecting when job is eventually picked from queue
// Returns a promise (that resolves or rejects when the job is eventually picked from queue
// and run with the same value it resolved or rejected with):
let result = await q(performRequest);
const result = await q(performRequest);
// No matter if more jobs come around later!
// Qyu will queue them as necessary and optimally manage them all
// for you based on your concurrency setting
// Qyu will queue them as expected and optimally manage them all for you
// based on your concurrency setting
setTimeout(() => {
for (let i=0; i<10; i++) {
for (let i = 0; i < 10; i++) {
q(performRequest);

@@ -46,20 +49,18 @@ }

# Features
- Always on and ready to receive additional tasks
- Concurrency setting
- Queue capacity
- Task priority
- Task timeout
- Pause/resume
- Compatible with browsers as well as Node.js environments
- Configurable concurrency limit
- Configurable queue capacity limit
- Configurable priority per individual tasks
- Configurable queue timeout duration per individual tasks
- Pause/resume queue execution
- Compatible for browsers as well as Node.js environments
- Written in TypeScript, full type definitions built-in
- Provides both CJS and ESM builds
# Instance Config
Defaults:
```javascript
```js
new Qyu({

@@ -71,7 +72,7 @@ concurrency: 1,

```
#### concurrency:
Determines the maximum number of jobs allowed to be run concurrently.
*(default: 1)*
```javascript
const q = new Qyu({concurrency: 2}); // Max 2 jobs can run concurrently
#### `concurrency`:
Determines the maximum number of jobs allowed to be executed concurrently.
*(default: `1`)*
```js
const q = new Qyu({ concurrency: 2 }); // Max 2 jobs can run concurrently
q(job1); // Runs immediately

@@ -81,12 +82,12 @@ q(job2); // Also runs immediately

```
#### capacity:
Sets a limit on the job queue length, causing any additional job queuings to be immediately rejected with a specific `"ERR_CAPACITY_FULL"` type of `QyuError`.
*(default: Infinity)*
```javascript
const q = new Qyu({capacity: 5});
// Queuing a batch of 6 jobs; since the 6th one crosses the max capcacity, it's returned promise is going to be immediately rejected
for (let i=0; i<6; i++) {
#### `capacity`:
Sets a limit on the job queue length, causing any additional job queuings to be immediately rejected with an instance of `QyuError` with a `code` property holding `"ERR_CAPACITY_FULL"`.
*(default: `Infinity`)*
```js
const q = new Qyu({ capacity: 5 });
// Queuing a batch of 6 jobs; since the 6th one exceeds the max capcacity, the promise it's about to return is going to be rejected immediately
for (let i = 0; i < 6; i++) {
q(job)
.then(result => console.log(`Job ${i} complete!`, result))
.catch(err => console.error(`job ${i} error`, err)); // err is a QyuError with code: "ERR_CAPACITY_FULL"
.catch(err => console.error(`job ${i} error`, err)); // err is a `QyuError` with `code: "ERR_CAPACITY_FULL"`
}

@@ -97,3 +98,3 @@ ```

Represents number of milliseconds.
*(default: 0)*
*(default: `0`)*
```javascript

@@ -115,68 +116,102 @@ const q = new Qyu({

Defaults:
```javascript
q(job, {
priority: 0,
timeout: null
});
```
#### priority:
Determines order in which queued jobs will run.
#### `priority`:
Determines order in which queued jobs will be picked up for execution.
Can be any positive/negative integer/float number.
The greater the priority value, the earlier it will be called relative to other jobs.
Queuings having identical priority will be put one after another in the same order in which they were passed to the instance.
*(default: 0)*
The greater the priority value, the earlier the job will be called in relation to other queued jobs.
Queued jobs having the same priority (or similarly having no explicit `priority` provided) will get scheduled relative to one another by the very order in which they were passed on to the Qyu instance.
*(default: `0`)*
#### timeout:
If is non-zero number, will dequeue jobs that waited in queue without running for that amount of time long (in milliseconds).
additionally, when a queued job reaches it's timeout, the promise it returned from it's queuing will reject with a `"ERR_JOB_TIMEOUT"` type of `QyuError`.
*(default: null)*
Example:
```js
const q = new Qyu();
const fn1 = async () => {/* ... */};
const fn2 = async () => {/* ... */};
q([
{ fn: fn1 },
{ fn: fn2, priority: 2 },
]);
// here `fn2` will be executed before `fn1` due to its higher priorty, even though `fn1` was was passed before it
```
#### `timeout`:
If is a non-zero positive number (representing milliseconds), the given job would be dequeued and prevented were it still be pending in queue at the time this duration expires.
Additionally, when a queued job reaches its timeout, the promise that was returned when it was initially queued would immediately become rejected with an instance of `QyuError` with a `code` property holding `"ERR_JOB_TIMEOUT"`.
*(default: `undefined`)*
Example:
```js
const q = new Qyu({ concurrency: 1 });
q(async () => {/* ... */});
q({
fn: async () => {/* ... */}, // Awaits in queue for the previously queued job above to finish (due to `concurrency` of 1)
timeout: 3000
});
// If 3 seconds are due and by this time the first job is still not done (-> its promise is yet to be resolved), the second job would be dequeued and prevented from running.
```
# API
#### instance(`fn` [, `options`])
### instance(`jobs`)
*(alias: instance#add)*
Queues function `fn` on instance with optional `options`.
**Returns**: *a promise that is tied to the jobs resolution or rejection value when it will be picked from queue and run.*
Queues up the given `jobs`, which can be either a single "job", or an array of such for batch queuing.
Every job (whether given as singular or as an array) can either be a plain function or a "job object" with the following properties:
- `fn`: function
- `timeout`: number _(optional)_ - [details on timeout here](#timeout)
- `priority`: number _(optional)_ - [details on priority here](#priority)
**Returns**:
If given a __singular__ non-array input - returns a promise that fulfills with the resolution or rejection value the job will produce when it eventually gets picked up from the queue and executed. Example:
```javascript
const q = new Qyu({concurrency: 5});
const q = new Qyu();
// Default options:
q(job1);
const myTaskFn = async () => {/* ... */};
// Custom options:
q(job2, {priority: 2, timeout: 1000*10});
const result = await q(myTaskFn);
// Awaiting on the queuing-returned promise, catching potential rejections:
// (job1 and job2 keep running in the background without interruption)
try {
const result = await q(job3);
console.log("Job 3's result:", result);
} catch (err) {
console.log('Job 3 errored:', err);
}
// or with extra options:
// This will be queued (or called right away if concurrency allows) only after job3 had completed, regardless of job1 or job2's state!
q(async () => {
// Do something...
const result = await q({
fn: myTaskFn1,
priority: 1,
timeout: 3000,
});
```
#### instance(`iterator`, `mapperFn`[, `options`])
*(alias: instance#map)*
For each iteration of `iterator`(an array for example), queues `mapperFn` on instance, injected with the value and the index from that iteration.
Optional `options` will be supplied the same for all job queuings included in this call.
If given an __array__ input - returns a promise that resolves when each of the given jobs were resolved, with the value of an array containing each job's resolution value, ordered as were the jobs when originally given, or rejects as soon as any of the given jobs happens to reject, reflecting that job's rejection value (_very similarly_ to the native [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all#return_value) behavior). Example:
```javascript
const q = new Qyu({concurrency: 3});
const files = ['/path/to/file1.png', '/path/to/file2.png', '/path/to/file3.png', '/path/to/file4.png'];
// Throttled, concurrent file deletion:
q(files, async (file, i) => {
await fs.unlink(file); // `unlink` function from require('fs').promises...
});
const q = new Qyu();
await q.whenEmpty(); // Will be resolved when no queued jobs are left.
const myTaskFn1 = async () => {/* ... */};
const myTaskFn2 = async () => {/* ... */};
const [result1, result2] = await q([myTaskFn1, myTaskFn2]);
// or with extra options:
const [result1, result2] = await q([
{
fn: myTaskFn1,
priority: 1,
timeout: 3000,
},
{
fn: myTaskFn2,
priority: 2,
timeout: 3000,
},
]);
```
#### instance#whenEmpty()
### instance#whenEmpty()
**Returns**: a promise that resolves if/when an instance has no running or queued jobs.

@@ -190,3 +225,3 @@ Guaranteed to resolve, regardless if one or some jobs resulted in error.

#### instance#whenFree()
### instance#whenFree()
**Returns**: a promise that resolves if/when number of currently running jobs are below the concurrency limit.

@@ -200,3 +235,3 @@ Guaranteed to resolve, regardless if one or some jobs resulted in error.

#### instance#pause()
### instance#pause()
Pauses instance's operation, so it effectively stops picking more jobs from queue.

@@ -213,3 +248,3 @@ Jobs currently running at time `instance.pause()` was called keep running until finished.

#### instance#resume()
### instance#resume()
Resumes instance's operation after a previous call to `instance.pause()`.

@@ -225,3 +260,3 @@ An instance is in "resumed" mode by default when instantiated.

#### instance#empty()
### instance#empty()
Immediately empties the instance's queue from all queued jobs, rejecting the promises returned from their queuings with a `"ERR_JOB_DEQUEUED"` type of `QyuError`.

@@ -236,3 +271,3 @@ Jobs currently running at the time `instance.empty()` was called keep running until finished.

#### instance#set(`config`)
### instance#set(`config`)
Update a living instance's config options in real time (`concurrency`, `capacity` and `rampUpTime`).

@@ -255,2 +290,22 @@ Note these (expected) side effects:

Throttled, concurrent file deletion:
```js
const fs = require('fs/promises');
const { Qyu } = require('qyu');
const q = new Qyu({ concurrency: 3 }); // -> So we can only process up to 3 deletions at the same time!
const filesToDelete = [
'/path/to/file1.png',
'/path/to/file2.png',
'/path/to/file3.png'
'/path/to/file4.png'
// ...
];
const deletionJobs = filesToDelete.map(path => () => fs.unlink(path));
await q(deletionJobs);
```
Web Scraper:

@@ -264,16 +319,16 @@ ```js

const siteUrl = 'http://www.store-to-crawl.com/products';
const q = new Qyu({concurrency: 3});
const q = new Qyu({ concurrency: 3 });
for (let i=1; i<=10; i++) {
for (let i = 1; i <= 10; i++) {
q(async () => {
let resp = await axios(siteUrl+'?page='+i);
let $ = cheerio.load(resp.data);
let products = [];
const resp = await axios(`${siteUrl}?page=${i}`);
const $ = cheerio.load(resp.data);
const products = [];
$('.product-list .product').each((i, elem) => {
let $elem = $(elem);
let title = $elem.find('.title').text();
let price = $elem.find('.price').text();
const $elem = $(elem);
const title = $elem.find('.title').text();
const price = $elem.find('.price').text();
products.push({ title, price });
});
// Do something with products...
// Do something with `products`...
});

@@ -280,0 +335,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc