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

slonik

Package Overview
Dependencies
Maintainers
1
Versions
395
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

slonik - npm Package Compare versions

Comparing version 39.0.1 to 39.1.0

dist/factories/createDriver.d.ts

1

dist/factories/createClientConfiguration.js

@@ -13,2 +13,3 @@ "use strict";

connectionUri,
gracefulTerminationTimeout: 5000,
idleInTransactionSessionTimeout: 60000,

@@ -15,0 +16,0 @@ idleTimeout: 5000,

@@ -14,2 +14,3 @@ "use strict";

connectionUri: 'postgres://',
gracefulTerminationTimeout: 5000,
idleInTransactionSessionTimeout: 60000,

@@ -16,0 +17,0 @@ idleTimeout: 5000,

50

dist/factories/createConnectionPool.d.ts

@@ -1,33 +0,3 @@

/// <reference types="node" />
import { type ClientConfiguration, type TypedReadable } from '../types';
import EventEmitter from 'node:events';
import { type StrictEventEmitter } from 'strict-event-emitter-types';
export type DriverNotice = {
message: string;
};
type ClientEventEmitter = StrictEventEmitter<EventEmitter, {
acquire: () => void;
destroy: () => void;
error: (error: Error) => void;
notice: (event: DriverNotice) => void;
release: () => void;
}>;
export type DriverFactory = ({ clientConfiguration, }: {
clientConfiguration: ClientConfiguration;
}) => Promise<ConnectionPoolClient>;
type DriverField = {
dataTypeId: number;
name: string;
};
export type DriverCommand = 'COPY' | 'DELETE' | 'INSERT' | 'SELECT' | 'UPDATE';
export type DriverQueryResult = {
readonly command: DriverCommand;
readonly fields: DriverField[];
readonly rowCount: number | null;
readonly rows: Array<Record<string, unknown>>;
};
export type DriverStreamResult = {
readonly fields: DriverField[];
readonly row: Record<string, unknown>;
};
import { type ClientEventEmitter, type DriverFactory, type DriverQueryResult, type DriverStreamResult } from './createDriver';
export type ConnectionPoolClient = {

@@ -46,19 +16,2 @@ acquire: () => void;

};
/**
* @property {Function} connect - Connect to the database. The client must not be used before this method is called.
* @property {Function} end - Disconnect from the database. The client must not be used after this method is called.
* @property {Function} query - Execute a SQL query.
*/
type InternalPoolClient = {
connect: () => Promise<void>;
end: () => Promise<void>;
query: (query: string, values?: unknown[]) => Promise<DriverQueryResult>;
stream: (query: string, values?: unknown[]) => TypedReadable<DriverStreamResult>;
};
type InternalPoolClientFactorySetup = ({ eventEmitter, clientConfiguration, }: {
clientConfiguration: ClientConfiguration;
eventEmitter: ClientEventEmitter;
}) => Promise<InternalPoolClientFactory>;
type InternalPoolClientFactory = () => InternalPoolClient;
export declare const createDriver: (setup: InternalPoolClientFactorySetup) => DriverFactory;
export type ConnectionPool = {

@@ -81,3 +34,2 @@ acquire: () => Promise<ConnectionPoolClient>;

}) => ConnectionPool;
export {};
//# sourceMappingURL=createConnectionPool.d.ts.map
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createConnectionPool = exports.createDriver = void 0;
exports.createConnectionPool = void 0;
const createUid_1 = require("../utilities/createUid");
const defer_1 = require("../utilities/defer");
const node_events_1 = __importDefault(require("node:events"));
const createDriver = (setup) => {
return async ({ clientConfiguration }) => {
const eventEmitter = new node_events_1.default();
const createPoolClient = await setup({
clientConfiguration,
eventEmitter,
});
const { query, stream, connect, end } = createPoolClient();
let isActive = false;
let isDestroyed = false;
let idleTimeout = null;
let activeQueryPromise = null;
const id = (0, createUid_1.createUid)();
const clearIdleTimeout = () => {
if (idleTimeout) {
clearTimeout(idleTimeout);
idleTimeout = null;
}
};
const client = {
acquire: () => {
if (isDestroyed) {
throw new Error('Client is destroyed.');
}
if (isActive) {
throw new Error('Client is already acquired.');
}
clearIdleTimeout();
isActive = true;
eventEmitter.emit('acquire');
},
destroy: async () => {
if (isDestroyed) {
return;
}
clearIdleTimeout();
isDestroyed = true;
eventEmitter.emit('destroy');
await end();
},
id: () => id,
isActive: () => isActive,
isIdle: () => {
return !isActive;
},
off: (event, listener) => {
return eventEmitter.off(event, listener);
},
on: (event, listener) => {
return eventEmitter.on(event, listener);
},
query: async (sql, values) => {
if (isDestroyed) {
throw new Error('Client is destroyed.');
}
if (!isActive) {
throw new Error('Client is not active.');
}
try {
activeQueryPromise = query(sql, values);
const result = await activeQueryPromise;
// eslint-disable-next-line require-atomic-updates
activeQueryPromise = null;
return result;
}
catch (error) {
eventEmitter.emit('error', error);
throw error;
}
},
release: async () => {
if (activeQueryPromise) {
throw new Error('Cannot release client while there is an active query.');
}
if (!isActive) {
return;
}
isActive = false;
if (clientConfiguration.idleTimeout !== 'DISABLE_TIMEOUT') {
clearIdleTimeout();
idleTimeout = setTimeout(() => {
void client.destroy();
idleTimeout = null;
}, clientConfiguration.idleTimeout).unref();
}
eventEmitter.emit('release');
},
removeListener: eventEmitter.removeListener.bind(eventEmitter),
stream: (sql, values) => {
if (isDestroyed) {
throw new Error('Client is destroyed.');
}
if (!isActive) {
throw new Error('Client is not active.');
}
// TODO determine if streaming and do not allow to release the client until the stream is finished
return stream(sql, values);
},
};
await connect();
return client;
};
};
exports.createDriver = createDriver;
const createConnectionPool = ({ clientConfiguration, createClient, poolSize = 1, }) => {

@@ -115,0 +7,0 @@ const connections = [];

@@ -9,2 +9,3 @@ "use strict";

const createConnectionPool_1 = require("./createConnectionPool");
const createDriver_1 = require("./createDriver");
const ava_1 = __importDefault(require("ava"));

@@ -14,3 +15,3 @@ const node_stream_1 = require("node:stream");

const createSimpleConnectionClientFactory = () => {
return (0, createConnectionPool_1.createDriver)(async () => {
return (0, createDriver_1.createDriver)(async () => {
return () => {

@@ -20,3 +21,6 @@ return {

end: async () => { },
query: async () => {
query: async (sql) => {
if (sql === 'SELECT pg_sleep(1)') {
await (0, promises_1.setTimeout)(1000);
}
return {

@@ -143,2 +147,28 @@ command: 'SELECT',

});
(0, ava_1.default)('destroys client that goes over the grace period', async (t) => {
t.timeout(500);
const clientConfiguration = (0, createClientConfiguration_1.createClientConfiguration)('postgres://localhost:5432/test', {
gracefulTerminationTimeout: 100,
});
const connectionPool = (0, createConnectionPool_1.createConnectionPool)({
clientConfiguration,
createClient: createSimpleConnectionClientFactory(),
});
const client = await connectionPool.acquire();
void client.query('SELECT pg_sleep(1)');
await (0, promises_1.setTimeout)(50);
t.deepEqual(connectionPool.state(), {
activeConnections: 1,
ended: false,
idleConnections: 0,
waitingClients: 0,
});
await client.release();
t.deepEqual(connectionPool.state(), {
activeConnections: 0,
ended: false,
idleConnections: 1,
waitingClients: 0,
});
});
//# sourceMappingURL=createConnectionPool.test.js.map

@@ -1,2 +0,2 @@

export declare const createPgDriver: () => import("./createConnectionPool").DriverFactory;
export declare const createPgDriver: () => import("./createDriver").DriverFactory;
//# sourceMappingURL=createPgDriver.d.ts.map

@@ -9,3 +9,3 @@ "use strict";

const parseDsn_1 = require("../utilities/parseDsn");
const createConnectionPool_1 = require("./createConnectionPool");
const createDriver_1 = require("./createDriver");
const node_stream_1 = require("node:stream");

@@ -112,3 +112,3 @@ // eslint-disable-next-line no-restricted-imports

let getTypeParserPromise = null;
return (0, createConnectionPool_1.createDriver)(async ({ clientConfiguration, eventEmitter }) => {
return (0, createDriver_1.createDriver)(async ({ clientConfiguration, eventEmitter }) => {
const pgClientConfiguration = createClientConfiguration(clientConfiguration);

@@ -115,0 +115,0 @@ if (!getTypeParserPromise) {

@@ -10,2 +10,3 @@ "use strict";

connectionUri: 'postgres://',
gracefulTerminationTimeout: 5000,
idleInTransactionSessionTimeout: 60000,

@@ -12,0 +13,0 @@ idleTimeout: 5000,

@@ -1,2 +0,2 @@

import { type DriverFactory } from '../factories/createConnectionPool';
import { type DriverFactory } from '../factories/createDriver';
import { type TestContextType } from './createTestRunner';

@@ -3,0 +3,0 @@ import { type TestFn } from 'ava';

@@ -1,2 +0,2 @@

import { type DriverFactory } from '../factories/createConnectionPool';
import { type DriverFactory } from '../factories/createDriver';
import { type TestFn } from 'ava';

@@ -3,0 +3,0 @@ export type TestContextType = {

@@ -5,3 +5,4 @@ /// <reference types="node" />

import { type SlonikError } from './errors';
import { type ConnectionPoolClient, type DriverFactory, type DriverNotice } from './factories/createConnectionPool';
import { type ConnectionPoolClient } from './factories/createConnectionPool';
import { type DriverFactory, type DriverNotice } from './factories/createDriver';
import type * as tokens from './tokens';

@@ -80,2 +81,6 @@ import { type Readable } from 'node:stream';

/**
* Timeout (in milliseconds) that kicks in after a connection with an active query is requested to end. This is the amount of time that is allowed for query to complete before terminating it. (Default: 5000)
*/
readonly gracefulTerminationTimeout: number;
/**
* Timeout (in milliseconds) after which idle clients are closed. Use 'DISABLE_TIMEOUT' constant to disable the timeout. (Default: 60000)

@@ -82,0 +87,0 @@ */

@@ -97,3 +97,3 @@ {

"types": "./dist/index.d.ts",
"version": "39.0.1"
"version": "39.1.0"
}
import {
type DriverNotice,
type DriverQueryResult,
} from '../factories/createConnectionPool';
} from '../factories/createDriver';
import { executeQuery, type ExecutionRoutine } from '../routines/executeQuery';

@@ -6,0 +6,0 @@ import {

@@ -1,2 +0,2 @@

import { type DriverStreamResult } from '../factories/createConnectionPool';
import { type DriverStreamResult } from '../factories/createDriver';
import { executeQuery, type ExecutionRoutine } from '../routines/executeQuery';

@@ -3,0 +3,0 @@ import {

@@ -10,2 +10,3 @@ import { createClientConfiguration } from './createClientConfiguration';

connectionUri: 'postgres://',
gracefulTerminationTimeout: 5_000,
idleInTransactionSessionTimeout: 60_000,

@@ -12,0 +13,0 @@ idleTimeout: 5_000,

@@ -20,2 +20,3 @@ import { InvalidConfigurationError } from '../errors';

connectionUri,
gracefulTerminationTimeout: 5_000,
idleInTransactionSessionTimeout: 60_000,

@@ -22,0 +23,0 @@ idleTimeout: 5_000,

/* eslint-disable canonical/id-match */
import { createClientConfiguration } from './createClientConfiguration';
import { createConnectionPool, createDriver } from './createConnectionPool';
import { createConnectionPool } from './createConnectionPool';
import { createDriver } from './createDriver';
import test from 'ava';

@@ -15,3 +16,7 @@ import { Readable } from 'node:stream';

end: async () => {},
query: async () => {
query: async (sql) => {
if (sql === 'SELECT pg_sleep(1)') {
await delay(1_000);
}
return {

@@ -179,1 +184,39 @@ command: 'SELECT',

});
test('destroys client that goes over the grace period', async (t) => {
t.timeout(500);
const clientConfiguration = createClientConfiguration(
'postgres://localhost:5432/test',
{
gracefulTerminationTimeout: 100,
},
);
const connectionPool = createConnectionPool({
clientConfiguration,
createClient: createSimpleConnectionClientFactory(),
});
const client = await connectionPool.acquire();
void client.query('SELECT pg_sleep(1)');
await delay(50);
t.deepEqual(connectionPool.state(), {
activeConnections: 1,
ended: false,
idleConnections: 0,
waitingClients: 0,
});
await client.release();
t.deepEqual(connectionPool.state(), {
activeConnections: 0,
ended: false,
idleConnections: 1,
waitingClients: 0,
});
});
import { type ClientConfiguration, type TypedReadable } from '../types';
import { createUid } from '../utilities/createUid';
import { defer, type DeferredPromise } from '../utilities/defer';
import EventEmitter from 'node:events';
import { type StrictEventEmitter } from 'strict-event-emitter-types';
import {
type ClientEventEmitter,
type DriverFactory,
type DriverQueryResult,
type DriverStreamResult,
} from './createDriver';
export type DriverNotice = {
message: string;
};
type ClientEventEmitter = StrictEventEmitter<
EventEmitter,
{
acquire: () => void;
destroy: () => void;
error: (error: Error) => void;
notice: (event: DriverNotice) => void;
release: () => void;
}
>;
export type DriverFactory = ({
clientConfiguration,
}: {
clientConfiguration: ClientConfiguration;
}) => Promise<ConnectionPoolClient>;
type DriverField = {
dataTypeId: number;
name: string;
};
export type DriverCommand = 'COPY' | 'DELETE' | 'INSERT' | 'SELECT' | 'UPDATE';
export type DriverQueryResult = {
readonly command: DriverCommand;
readonly fields: DriverField[];
readonly rowCount: number | null;
readonly rows: Array<Record<string, unknown>>;
};
export type DriverStreamResult = {
readonly fields: DriverField[];
readonly row: Record<string, unknown>;
};
export type ConnectionPoolClient = {

@@ -64,167 +28,2 @@ acquire: () => void;

/**
* @property {Function} connect - Connect to the database. The client must not be used before this method is called.
* @property {Function} end - Disconnect from the database. The client must not be used after this method is called.
* @property {Function} query - Execute a SQL query.
*/
type InternalPoolClient = {
connect: () => Promise<void>;
end: () => Promise<void>;
query: (query: string, values?: unknown[]) => Promise<DriverQueryResult>;
stream: (
query: string,
values?: unknown[],
) => TypedReadable<DriverStreamResult>;
};
type InternalPoolClientFactorySetup = ({
eventEmitter,
clientConfiguration,
}: {
clientConfiguration: ClientConfiguration;
eventEmitter: ClientEventEmitter;
}) => Promise<InternalPoolClientFactory>;
type InternalPoolClientFactory = () => InternalPoolClient;
export const createDriver = (
setup: InternalPoolClientFactorySetup,
): DriverFactory => {
return async ({ clientConfiguration }) => {
const eventEmitter = new EventEmitter();
const createPoolClient = await setup({
clientConfiguration,
eventEmitter,
});
const { query, stream, connect, end } = createPoolClient();
let isActive = false;
let isDestroyed = false;
let idleTimeout: NodeJS.Timeout | null = null;
let activeQueryPromise: Promise<DriverQueryResult> | null = null;
const id = createUid();
const clearIdleTimeout = () => {
if (idleTimeout) {
clearTimeout(idleTimeout);
idleTimeout = null;
}
};
const client = {
acquire: () => {
if (isDestroyed) {
throw new Error('Client is destroyed.');
}
if (isActive) {
throw new Error('Client is already acquired.');
}
clearIdleTimeout();
isActive = true;
eventEmitter.emit('acquire');
},
destroy: async () => {
if (isDestroyed) {
return;
}
clearIdleTimeout();
isDestroyed = true;
eventEmitter.emit('destroy');
await end();
},
id: () => id,
isActive: () => isActive,
isIdle: () => {
return !isActive;
},
off: (event, listener) => {
return eventEmitter.off(event, listener);
},
on: (event, listener) => {
return eventEmitter.on(event, listener);
},
query: async (sql, values) => {
if (isDestroyed) {
throw new Error('Client is destroyed.');
}
if (!isActive) {
throw new Error('Client is not active.');
}
try {
activeQueryPromise = query(sql, values);
const result = await activeQueryPromise;
// eslint-disable-next-line require-atomic-updates
activeQueryPromise = null;
return result;
} catch (error) {
eventEmitter.emit('error', error);
throw error;
}
},
release: async () => {
if (activeQueryPromise) {
throw new Error(
'Cannot release client while there is an active query.',
);
}
if (!isActive) {
return;
}
isActive = false;
if (clientConfiguration.idleTimeout !== 'DISABLE_TIMEOUT') {
clearIdleTimeout();
idleTimeout = setTimeout(() => {
void client.destroy();
idleTimeout = null;
}, clientConfiguration.idleTimeout).unref();
}
eventEmitter.emit('release');
},
removeListener: eventEmitter.removeListener.bind(eventEmitter),
stream: (sql, values) => {
if (isDestroyed) {
throw new Error('Client is destroyed.');
}
if (!isActive) {
throw new Error('Client is not active.');
}
// TODO determine if streaming and do not allow to release the client until the stream is finished
return stream(sql, values);
},
};
await connect();
return client;
};
};
export type ConnectionPool = {

@@ -231,0 +30,0 @@ acquire: () => Promise<ConnectionPoolClient>;

@@ -9,3 +9,3 @@ /* eslint-disable canonical/id-match */

import { parseDsn } from '../utilities/parseDsn';
import { createDriver, type DriverCommand } from './createConnectionPool';
import { createDriver, type DriverCommand } from './createDriver';
import { Transform } from 'node:stream';

@@ -12,0 +12,0 @@ // eslint-disable-next-line no-restricted-imports

@@ -5,6 +5,4 @@ import { bindPool } from '../binders/bindPool';

import { createClientConfiguration } from './createClientConfiguration';
import {
createConnectionPool,
type DriverFactory,
} from './createConnectionPool';
import { createConnectionPool } from './createConnectionPool';
import { type DriverFactory } from './createDriver';
import { createPgDriver } from './createPgDriver';

@@ -11,0 +9,0 @@ import { createPoolConfiguration } from './createPoolConfiguration';

@@ -9,2 +9,3 @@ import { type ClientConfiguration } from '../types';

connectionUri: 'postgres://',
gracefulTerminationTimeout: 5_000,
idleInTransactionSessionTimeout: 60_000,

@@ -11,0 +12,0 @@ idleTimeout: 5_000,

@@ -17,3 +17,3 @@ /* eslint-disable id-length */

} from '..';
import { type DriverFactory } from '../factories/createConnectionPool';
import { type DriverFactory } from '../factories/createDriver';
import { type TestContextType } from './createTestRunner';

@@ -20,0 +20,0 @@ // eslint-disable-next-line ava/use-test

import { sql } from '..';
import { type DriverFactory } from '../factories/createConnectionPool';
import { type DriverFactory } from '../factories/createDriver';
import { createPool } from '../factories/createPool';

@@ -4,0 +4,0 @@ import anyTest, { type TestFn } from 'ava';

@@ -16,6 +16,4 @@ import { TRANSACTION_ROLLBACK_ERROR_PREFIX } from '../constants';

} from '../errors';
import {
type ConnectionPoolClient,
type DriverNotice,
} from '../factories/createConnectionPool';
import { type ConnectionPoolClient } from '../factories/createConnectionPool';
import { type DriverNotice } from '../factories/createDriver';
import { getPoolClientState } from '../state';

@@ -353,2 +351,3 @@ import {

error.notices = notices;
throw error;

@@ -355,0 +354,0 @@ }

import { type SlonikError } from './errors';
import { type ConnectionPoolClient } from './factories/createConnectionPool';
import {
type ConnectionPoolClient,
type DriverFactory,
type DriverNotice,
} from './factories/createConnectionPool';
} from './factories/createDriver';
import type * as tokens from './tokens';

@@ -113,2 +113,6 @@ import { type Readable } from 'node:stream';

/**
* Timeout (in milliseconds) that kicks in after a connection with an active query is requested to end. This is the amount of time that is allowed for query to complete before terminating it. (Default: 5000)
*/
readonly gracefulTerminationTimeout: number;
/**
* Timeout (in milliseconds) after which idle clients are closed. Use 'DISABLE_TIMEOUT' constant to disable the timeout. (Default: 60000)

@@ -115,0 +119,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

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 too big to display

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