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

@atproto/common-web

Package Overview
Dependencies
Maintainers
4
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@atproto/common-web - npm Package Compare versions

Comparing version 0.3.1 to 0.3.2

tsconfig.build.tsbuildinfo

8

CHANGELOG.md
# @atproto/common-web
## 0.3.2
### Patch Changes
- [#3177](https://github.com/bluesky-social/atproto/pull/3177) [`72eba67af`](https://github.com/bluesky-social/atproto/commit/72eba67af1af8320b5400bcb9319d5c3c8407d99) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add `createRetryable` utility function
- [#3177](https://github.com/bluesky-social/atproto/pull/3177) [`72eba67af`](https://github.com/bluesky-social/atproto/commit/72eba67af1af8320b5400bcb9319d5c3c8407d99) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add `allFulfilled` utility
## 0.3.1

@@ -4,0 +12,0 @@

16

dist/async.d.ts

@@ -30,3 +30,17 @@ export declare const readFromGenerator: <T>(gen: AsyncGenerator<T>, isDone: (last?: T) => Promise<boolean> | boolean, waitFor?: Promise<unknown>, maxLength?: number) => Promise<T[]>;

}
export declare const handleAllSettledErrors: (results: PromiseSettledResult<unknown>[]) => void;
/**
* Utility function that behaves like {@link Promise.allSettled} but returns the
* same result as {@link Promise.all} in case every promise is fulfilled, and
* throws an {@link AggregateError} if there are more than one errors.
*/
export declare function allFulfilled<T extends readonly unknown[] | []>(promises: T): Promise<{
-readonly [P in keyof T]: Awaited<T[P]>;
}>;
export declare function allFulfilled<T>(promises: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>;
export declare function handleAllSettledErrors<T extends readonly PromiseSettledResult<unknown>[] | []>(results: T): {
-readonly [P in keyof T]: T[P] extends PromiseSettledResult<infer U> ? U : never;
};
export declare function handleAllSettledErrors<T>(results: PromiseSettledResult<T>[]): T[];
export declare function isRejectedResult(result: PromiseSettledResult<unknown>): result is PromiseRejectedResult;
export declare function isFulfilledResult<T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T>;
//# sourceMappingURL=async.d.ts.map

40

dist/async.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleAllSettledErrors = exports.AsyncBufferFullError = exports.AsyncBuffer = exports.allComplete = exports.createDeferrables = exports.createDeferrable = exports.readFromGenerator = void 0;
exports.AsyncBufferFullError = exports.AsyncBuffer = exports.allComplete = exports.createDeferrables = exports.createDeferrable = exports.readFromGenerator = void 0;
exports.allFulfilled = allFulfilled;
exports.handleAllSettledErrors = handleAllSettledErrors;
exports.isRejectedResult = isRejectedResult;
exports.isFulfilledResult = isFulfilledResult;
const util_1 = require("./util");

@@ -173,6 +177,10 @@ // reads values from a generator into a list

exports.AsyncBufferFullError = AsyncBufferFullError;
const handleAllSettledErrors = (results) => {
const errors = results.filter(isRejected).map((res) => res.reason);
function allFulfilled(promises) {
return Promise.allSettled(promises).then(handleAllSettledErrors);
}
function handleAllSettledErrors(results) {
const errors = results.filter(isRejectedResult).map(extractReason);
if (errors.length === 0) {
return;
// No need to filter here, it is safe to assume that all promises are fulfilled
return results.map(extractValue);
}

@@ -182,8 +190,22 @@ if (errors.length === 1) {

}
throw new AggregateError(errors, 'Multiple errors: ' + errors.map((err) => err?.message).join('\n'));
};
exports.handleAllSettledErrors = handleAllSettledErrors;
const isRejected = (result) => {
throw new AggregateError(errors, `Multiple errors: ${errors.map(stringifyReason).join('\n')}`);
}
function isRejectedResult(result) {
return result.status === 'rejected';
};
}
function extractReason(result) {
return result.reason;
}
function isFulfilledResult(result) {
return result.status === 'fulfilled';
}
function extractValue(result) {
return result.value;
}
function stringifyReason(reason) {
if (reason instanceof Error) {
return reason.message;
}
return String(reason);
}
//# sourceMappingURL=async.js.map
import { z } from 'zod';
export declare const isValidDidDoc: (doc: unknown) => doc is {
id: string;
alsoKnownAs?: string[] | undefined;
verificationMethod?: {
id: string;
type: string;
controller: string;
publicKeyMultibase?: string | undefined;
}[] | undefined;
service?: {
id: string;
type: string;
serviceEndpoint: string | Record<string, unknown>;
}[] | undefined;
};
export declare const isValidDidDoc: (doc: unknown) => doc is DidDocument;
export declare const getDid: (doc: DidDocument) => string;

@@ -18,0 +4,0 @@ export declare const getHandle: (doc: DidDocument) => string | undefined;

export type RetryOptions = {
maxRetries?: number;
getWaitMs?: (n: number) => number | null;
};
export declare function retry<T>(fn: () => Promise<T>, opts?: RetryOptions & {
retryable?: (err: unknown) => boolean;
};
export declare function retry<T>(fn: () => Promise<T>, opts?: RetryOptions): Promise<T>;
}): Promise<T>;
export declare function createRetryable(retryable: (err: unknown) => boolean): <T>(fn: () => Promise<T>, opts?: RetryOptions) => Promise<T>;
export declare function backoffMs(n: number, multiplier?: number, max?: number): number;
//# sourceMappingURL=retry.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.backoffMs = exports.retry = void 0;
exports.retry = retry;
exports.createRetryable = createRetryable;
exports.backoffMs = backoffMs;
const util_1 = require("./util");

@@ -29,3 +31,5 @@ async function retry(fn, opts = {}) {

}
exports.retry = retry;
function createRetryable(retryable) {
return async (fn, opts) => retry(fn, { ...opts, retryable });
}
// Waits exponential backoff with max and jitter: ~100, ~200, ~400, ~800, ~1000, ~1000, ...

@@ -37,3 +41,2 @@ function backoffMs(n, multiplier = 100, max = 1000) {

}
exports.backoffMs = backoffMs;
// Adds randomness +/-15% of value

@@ -40,0 +43,0 @@ function jitter(value) {

@@ -1,4 +0,7 @@

/// <reference types="node" />
export declare const noUndefinedVals: <T>(obj: Record<string, T | undefined>) => Record<string, T>;
export declare function omit<T extends undefined | Record<string, unknown>, K extends keyof NonNullable<T>>(obj: T, keys: readonly K[]): T extends undefined ? undefined : Omit<T, K>;
/**
* Returns a shallow copy of the object without the specified keys. If the input
* is nullish, it returns the input.
*/
export declare function omit<T extends undefined | null | Record<string, unknown>, K extends keyof NonNullable<T>>(object: T, rejectedKeys: readonly K[]): T extends undefined ? undefined : T extends null ? null : Omit<T, K>;
export declare const jitter: (maxMs: number) => number;

@@ -5,0 +8,0 @@ export declare const wait: (ms: number) => Promise<unknown>;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseIntWithFallback = exports.dedupeStrs = exports.range = exports.chunkArray = exports.errHasMsg = exports.isErrnoException = exports.asyncFilter = exports.s32decode = exports.s32encode = exports.streamToBuffer = exports.flattenUint8Arrays = exports.bailableWait = exports.wait = exports.jitter = exports.omit = exports.noUndefinedVals = void 0;
exports.parseIntWithFallback = exports.dedupeStrs = exports.range = exports.chunkArray = exports.errHasMsg = exports.isErrnoException = exports.asyncFilter = exports.s32decode = exports.s32encode = exports.streamToBuffer = exports.flattenUint8Arrays = exports.bailableWait = exports.wait = exports.jitter = exports.noUndefinedVals = void 0;
exports.omit = omit;
const noUndefinedVals = (obj) => {

@@ -13,8 +14,16 @@ Object.keys(obj).forEach((k) => {

exports.noUndefinedVals = noUndefinedVals;
function omit(obj, keys) {
if (!obj)
return obj;
return Object.fromEntries(Object.entries(obj).filter((entry) => !keys.includes(entry[0])));
function omit(src, rejectedKeys) {
// Hot path
if (!src)
return src;
const dst = {};
const srcKeys = Object.keys(src);
for (let i = 0; i < srcKeys.length; i++) {
const key = srcKeys[i];
if (!rejectedKeys.includes(key)) {
dst[key] = src[key];
}
}
return dst;
}
exports.omit = omit;
const jitter = (maxMs) => {

@@ -21,0 +30,0 @@ return Math.round((Math.random() - 0.5) * maxMs * 2);

{
"name": "@atproto/common-web",
"version": "0.3.1",
"version": "0.3.2",
"license": "MIT",

@@ -24,3 +24,4 @@ "description": "Shared web-platform-friendly code for atproto libraries",

"devDependencies": {
"jest": "^28.1.2"
"jest": "^28.1.2",
"typescript": "^5.6.3"
},

@@ -27,0 +28,0 @@ "scripts": {

@@ -155,8 +155,38 @@ import { bailableWait } from './util'

export const handleAllSettledErrors = (
/**
* Utility function that behaves like {@link Promise.allSettled} but returns the
* same result as {@link Promise.all} in case every promise is fulfilled, and
* throws an {@link AggregateError} if there are more than one errors.
*/
export function allFulfilled<T extends readonly unknown[] | []>(
promises: T,
): Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>
export function allFulfilled<T>(
promises: Iterable<T | PromiseLike<T>>,
): Promise<Awaited<T>[]>
export function allFulfilled(
promises: Iterable<Promise<unknown>>,
): Promise<unknown[]> {
return Promise.allSettled(promises).then(handleAllSettledErrors)
}
export function handleAllSettledErrors<
T extends readonly PromiseSettledResult<unknown>[] | [],
>(
results: T,
): {
-readonly [P in keyof T]: T[P] extends PromiseSettledResult<infer U>
? U
: never
}
export function handleAllSettledErrors<T>(
results: PromiseSettledResult<T>[],
): T[]
export function handleAllSettledErrors(
results: PromiseSettledResult<unknown>[],
) => {
const errors = results.filter(isRejected).map((res) => res.reason)
): unknown[] {
const errors = results.filter(isRejectedResult).map(extractReason)
if (errors.length === 0) {
return
// No need to filter here, it is safe to assume that all promises are fulfilled
return (results as PromiseFulfilledResult<unknown>[]).map(extractValue)
}

@@ -168,10 +198,31 @@ if (errors.length === 1) {

errors,
'Multiple errors: ' + errors.map((err) => err?.message).join('\n'),
`Multiple errors: ${errors.map(stringifyReason).join('\n')}`,
)
}
const isRejected = (
export function isRejectedResult(
result: PromiseSettledResult<unknown>,
): result is PromiseRejectedResult => {
): result is PromiseRejectedResult {
return result.status === 'rejected'
}
function extractReason(result: PromiseRejectedResult): unknown {
return result.reason
}
export function isFulfilledResult<T>(
result: PromiseSettledResult<T>,
): result is PromiseFulfilledResult<T> {
return result.status === 'fulfilled'
}
function extractValue<T>(result: PromiseFulfilledResult<T>): T {
return result.value
}
function stringifyReason(reason: unknown): string {
if (reason instanceof Error) {
return reason.message
}
return String(reason)
}

@@ -6,3 +6,2 @@ import { wait } from './util'

getWaitMs?: (n: number) => number | null
retryable?: (err: unknown) => boolean
}

@@ -12,3 +11,5 @@

fn: () => Promise<T>,
opts: RetryOptions = {},
opts: RetryOptions & {
retryable?: (err: unknown) => boolean
} = {},
): Promise<T> {

@@ -38,2 +39,7 @@ const { maxRetries = 3, retryable = () => true, getWaitMs = backoffMs } = opts

export function createRetryable(retryable: (err: unknown) => boolean) {
return async <T>(fn: () => Promise<T>, opts?: RetryOptions) =>
retry(fn, { ...opts, retryable })
}
// Waits exponential backoff with max and jitter: ~100, ~200, ~400, ~800, ~1000, ~1000, ...

@@ -40,0 +46,0 @@ export function backoffMs(n: number, multiplier = 100, max = 1000) {

@@ -12,15 +12,30 @@ export const noUndefinedVals = <T>(

/**
* Returns a shallow copy of the object without the specified keys. If the input
* is nullish, it returns the input.
*/
export function omit<
T extends undefined | Record<string, unknown>,
T extends undefined | null | Record<string, unknown>,
K extends keyof NonNullable<T>,
>(obj: T, keys: readonly K[]): T extends undefined ? undefined : Omit<T, K>
>(
object: T,
rejectedKeys: readonly K[],
): T extends undefined ? undefined : T extends null ? null : Omit<T, K>
export function omit(
obj: Record<string, unknown>,
keys: readonly string[],
): undefined | Record<string, unknown> {
if (!obj) return obj
src: undefined | null | Record<string, unknown>,
rejectedKeys: readonly string[],
): undefined | null | Record<string, unknown> {
// Hot path
return Object.fromEntries(
Object.entries(obj).filter((entry) => !keys.includes(entry[0])),
)
if (!src) return src
const dst = {}
const srcKeys = Object.keys(src)
for (let i = 0; i < srcKeys.length; i++) {
const key = srcKeys[i]
if (!rejectedKeys.includes(key)) {
dst[key] = src[key]
}
}
return dst
}

@@ -27,0 +42,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

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

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