ensure-port
Advanced tools
Comparing version 0.0.0 to 0.0.1
@@ -1,52 +0,2 @@ | ||
import type { IFileSystem } from '@file-services/types'; | ||
interface PortsParameters { | ||
startPort?: number; | ||
endPort?: number; | ||
} | ||
interface PortsOptions { | ||
fs?: IFileSystem; | ||
rootDir?: string; | ||
} | ||
export declare class Ports { | ||
private portsPath; | ||
private visitedPorts; | ||
private start; | ||
private end; | ||
private fs; | ||
private rootDir; | ||
private initialEdges; | ||
private watchListener; | ||
constructor({ startPort, endPort }?: PortsParameters, options?: PortsOptions); | ||
/** | ||
* Returns a reserved port. | ||
*/ | ||
ensurePort(): Promise<number>; | ||
/** | ||
* Un-mark a ports as used. | ||
* | ||
* @param currentPorts - optional, if provided it will release only these ports | ||
*/ | ||
releasePorts(currentPorts?: number[]): Promise<void>; | ||
/** | ||
* | ||
* Sets a port as used. | ||
* | ||
* @param port - the port to mark as used | ||
*/ | ||
setPort(port: number): Promise<void>; | ||
/** | ||
* Releases all the ports. | ||
*/ | ||
clean(): Promise<void>; | ||
/** | ||
* Unwatch ports changes | ||
*/ | ||
dispose(): Promise<void>; | ||
private getPort; | ||
private getNextPort; | ||
private updatePersistentPorts; | ||
private getPersistentPorts; | ||
private updateEdges; | ||
} | ||
export {}; | ||
export { Ports, PortsOptions, PortsParameters } from './ensure-port'; | ||
//# sourceMappingURL=index.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Ports = void 0; | ||
const node_1 = require("@file-services/node"); | ||
const create_listening_server_1 = require("create-listening-server"); | ||
const find_cache_dir_1 = require("./find-cache-dir"); | ||
class Ports { | ||
constructor({ startPort = 8000, endPort = 9000 } = {}, options = {}) { | ||
var _a, _b; | ||
this.visitedPorts = new Set(); | ||
this.start = startPort; | ||
this.end = endPort; | ||
this.initialEdges = { start: this.start, end: this.end, reached: false }; | ||
this.fs = (_a = options.fs) !== null && _a !== void 0 ? _a : node_1.nodeFs; | ||
this.rootDir = (_b = options.rootDir) !== null && _b !== void 0 ? _b : process.cwd(); | ||
const tempDir = (0, find_cache_dir_1.findCacheDir)('e2e-test-kit', { fs: this.fs, rootDir: this.rootDir }); | ||
if (tempDir) { | ||
this.fs.ensureDirectorySync(tempDir); | ||
} | ||
if (!tempDir) { | ||
throw new Error('Could not find a "e2e-test-kit" temp directory'); | ||
} | ||
this.portsPath = this.fs.resolve(tempDir, 'ports'); | ||
// eslint-disable-next-line @typescript-eslint/no-misused-promises | ||
this.watchListener = async () => { | ||
this.visitedPorts = await this.getPersistentPorts(); | ||
}; | ||
void this.fs.watchService.watchPath(this.portsPath, this.watchListener); | ||
} | ||
/** | ||
* Returns a reserved port. | ||
*/ | ||
async ensurePort() { | ||
if (this.initialEdges.reached) { | ||
throw new Error(`All ports are used between ${this.initialEdges.start} and ${this.initialEdges.end}`); | ||
} | ||
if (this.start === this.end) { | ||
this.initialEdges.reached = true; | ||
} | ||
const preferredPort = await this.getPort(); | ||
const { port, httpServer } = await (0, create_listening_server_1.safeListeningHttpServer)(preferredPort); | ||
if (port !== preferredPort) { | ||
await this.setPort(port); | ||
} | ||
await new Promise((resolve, reject) => httpServer.close((error) => (error ? reject(error) : resolve(void 0)))); | ||
this.updateEdges(port); | ||
return port; | ||
} | ||
/** | ||
* Un-mark a ports as used. | ||
* | ||
* @param currentPorts - optional, if provided it will release only these ports | ||
*/ | ||
async releasePorts(currentPorts) { | ||
await this.updatePersistentPorts((ports) => { | ||
for (const port of [...(currentPorts !== null && currentPorts !== void 0 ? currentPorts : this.visitedPorts)]) { | ||
ports.delete(port); | ||
} | ||
}); | ||
} | ||
/** | ||
* | ||
* Sets a port as used. | ||
* | ||
* @param port - the port to mark as used | ||
*/ | ||
async setPort(port) { | ||
await this.updatePersistentPorts((ports) => { | ||
ports.add(port); | ||
}); | ||
} | ||
/** | ||
* Releases all the ports. | ||
*/ | ||
async clean() { | ||
this.visitedPorts.clear(); | ||
await this.fs.promises.rm(this.portsPath, { force: true }); | ||
} | ||
/** | ||
* Unwatch ports changes | ||
*/ | ||
dispose() { | ||
return this.fs.watchService.unwatchPath(this.portsPath, this.watchListener); | ||
} | ||
async getPort() { | ||
const port = await this.getNextPort(); | ||
await this.setPort(port); | ||
return port; | ||
} | ||
async getNextPort() { | ||
let port; | ||
do { | ||
port = randomNumberBetween(this.start, this.end); | ||
} while (await Promise.resolve(this.visitedPorts.has(port))); | ||
return port; | ||
} | ||
async updatePersistentPorts(callback) { | ||
const ports = await this.getPersistentPorts(); | ||
const newPorts = new Set(ports); | ||
await callback(newPorts); | ||
for (const port of ports) { | ||
if (newPorts.has(port)) { | ||
newPorts.delete(port); | ||
continue; | ||
} | ||
await this.fs.promises.rm(this.fs.join(this.portsPath, String(port)), { force: true }); | ||
} | ||
await Promise.all([...newPorts].map((port) => this.fs.promises.writeFile(this.fs.join(this.portsPath, String(port)), ''))); | ||
this.visitedPorts = await this.getPersistentPorts(); | ||
} | ||
async getPersistentPorts() { | ||
await this.fs.promises.ensureDirectory(this.portsPath); | ||
return this.fs.promises.readdir(this.portsPath).then((files) => new Set(files.map((file) => Number(file)))); | ||
} | ||
updateEdges(port) { | ||
if (port === this.start) { | ||
let candidatePort = this.start + 1; | ||
while (this.visitedPorts.has(candidatePort) && !(candidatePort === this.end)) { | ||
candidatePort++; | ||
} | ||
this.start = candidatePort; | ||
} | ||
else if (port === this.end) { | ||
let candidatePort = this.end - 1; | ||
while (this.visitedPorts.has(candidatePort) && !(candidatePort === this.start)) { | ||
candidatePort--; | ||
} | ||
this.end = candidatePort; | ||
} | ||
} | ||
} | ||
exports.Ports = Ports; | ||
function randomNumberBetween(min, max) { | ||
return Math.floor(Math.random() * (max - min + 1) + min); | ||
} | ||
var ensure_port_1 = require("./ensure-port"); | ||
Object.defineProperty(exports, "Ports", { enumerable: true, get: function () { return ensure_port_1.Ports; } }); | ||
//# sourceMappingURL=index.js.map |
@@ -1,52 +0,2 @@ | ||
import type { IFileSystem } from '@file-services/types'; | ||
interface PortsParameters { | ||
startPort?: number; | ||
endPort?: number; | ||
} | ||
interface PortsOptions { | ||
fs?: IFileSystem; | ||
rootDir?: string; | ||
} | ||
export declare class Ports { | ||
private portsPath; | ||
private visitedPorts; | ||
private start; | ||
private end; | ||
private fs; | ||
private rootDir; | ||
private initialEdges; | ||
private watchListener; | ||
constructor({ startPort, endPort }?: PortsParameters, options?: PortsOptions); | ||
/** | ||
* Returns a reserved port. | ||
*/ | ||
ensurePort(): Promise<number>; | ||
/** | ||
* Un-mark a ports as used. | ||
* | ||
* @param currentPorts - optional, if provided it will release only these ports | ||
*/ | ||
releasePorts(currentPorts?: number[]): Promise<void>; | ||
/** | ||
* | ||
* Sets a port as used. | ||
* | ||
* @param port - the port to mark as used | ||
*/ | ||
setPort(port: number): Promise<void>; | ||
/** | ||
* Releases all the ports. | ||
*/ | ||
clean(): Promise<void>; | ||
/** | ||
* Unwatch ports changes | ||
*/ | ||
dispose(): Promise<void>; | ||
private getPort; | ||
private getNextPort; | ||
private updatePersistentPorts; | ||
private getPersistentPorts; | ||
private updateEdges; | ||
} | ||
export {}; | ||
export { Ports, PortsOptions, PortsParameters } from './ensure-port'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,132 +0,2 @@ | ||
import { nodeFs } from '@file-services/node'; | ||
import { safeListeningHttpServer } from 'create-listening-server'; | ||
import { findCacheDir } from './find-cache-dir'; | ||
export class Ports { | ||
constructor({ startPort = 8000, endPort = 9000 } = {}, options = {}) { | ||
var _a, _b; | ||
this.visitedPorts = new Set(); | ||
this.start = startPort; | ||
this.end = endPort; | ||
this.initialEdges = { start: this.start, end: this.end, reached: false }; | ||
this.fs = (_a = options.fs) !== null && _a !== void 0 ? _a : nodeFs; | ||
this.rootDir = (_b = options.rootDir) !== null && _b !== void 0 ? _b : process.cwd(); | ||
const tempDir = findCacheDir('e2e-test-kit', { fs: this.fs, rootDir: this.rootDir }); | ||
if (tempDir) { | ||
this.fs.ensureDirectorySync(tempDir); | ||
} | ||
if (!tempDir) { | ||
throw new Error('Could not find a "e2e-test-kit" temp directory'); | ||
} | ||
this.portsPath = this.fs.resolve(tempDir, 'ports'); | ||
// eslint-disable-next-line @typescript-eslint/no-misused-promises | ||
this.watchListener = async () => { | ||
this.visitedPorts = await this.getPersistentPorts(); | ||
}; | ||
void this.fs.watchService.watchPath(this.portsPath, this.watchListener); | ||
} | ||
/** | ||
* Returns a reserved port. | ||
*/ | ||
async ensurePort() { | ||
if (this.initialEdges.reached) { | ||
throw new Error(`All ports are used between ${this.initialEdges.start} and ${this.initialEdges.end}`); | ||
} | ||
if (this.start === this.end) { | ||
this.initialEdges.reached = true; | ||
} | ||
const preferredPort = await this.getPort(); | ||
const { port, httpServer } = await safeListeningHttpServer(preferredPort); | ||
if (port !== preferredPort) { | ||
await this.setPort(port); | ||
} | ||
await new Promise((resolve, reject) => httpServer.close((error) => (error ? reject(error) : resolve(void 0)))); | ||
this.updateEdges(port); | ||
return port; | ||
} | ||
/** | ||
* Un-mark a ports as used. | ||
* | ||
* @param currentPorts - optional, if provided it will release only these ports | ||
*/ | ||
async releasePorts(currentPorts) { | ||
await this.updatePersistentPorts((ports) => { | ||
for (const port of [...(currentPorts !== null && currentPorts !== void 0 ? currentPorts : this.visitedPorts)]) { | ||
ports.delete(port); | ||
} | ||
}); | ||
} | ||
/** | ||
* | ||
* Sets a port as used. | ||
* | ||
* @param port - the port to mark as used | ||
*/ | ||
async setPort(port) { | ||
await this.updatePersistentPorts((ports) => { | ||
ports.add(port); | ||
}); | ||
} | ||
/** | ||
* Releases all the ports. | ||
*/ | ||
async clean() { | ||
this.visitedPorts.clear(); | ||
await this.fs.promises.rm(this.portsPath, { force: true }); | ||
} | ||
/** | ||
* Unwatch ports changes | ||
*/ | ||
dispose() { | ||
return this.fs.watchService.unwatchPath(this.portsPath, this.watchListener); | ||
} | ||
async getPort() { | ||
const port = await this.getNextPort(); | ||
await this.setPort(port); | ||
return port; | ||
} | ||
async getNextPort() { | ||
let port; | ||
do { | ||
port = randomNumberBetween(this.start, this.end); | ||
} while (await Promise.resolve(this.visitedPorts.has(port))); | ||
return port; | ||
} | ||
async updatePersistentPorts(callback) { | ||
const ports = await this.getPersistentPorts(); | ||
const newPorts = new Set(ports); | ||
await callback(newPorts); | ||
for (const port of ports) { | ||
if (newPorts.has(port)) { | ||
newPorts.delete(port); | ||
continue; | ||
} | ||
await this.fs.promises.rm(this.fs.join(this.portsPath, String(port)), { force: true }); | ||
} | ||
await Promise.all([...newPorts].map((port) => this.fs.promises.writeFile(this.fs.join(this.portsPath, String(port)), ''))); | ||
this.visitedPorts = await this.getPersistentPorts(); | ||
} | ||
async getPersistentPorts() { | ||
await this.fs.promises.ensureDirectory(this.portsPath); | ||
return this.fs.promises.readdir(this.portsPath).then((files) => new Set(files.map((file) => Number(file)))); | ||
} | ||
updateEdges(port) { | ||
if (port === this.start) { | ||
let candidatePort = this.start + 1; | ||
while (this.visitedPorts.has(candidatePort) && !(candidatePort === this.end)) { | ||
candidatePort++; | ||
} | ||
this.start = candidatePort; | ||
} | ||
else if (port === this.end) { | ||
let candidatePort = this.end - 1; | ||
while (this.visitedPorts.has(candidatePort) && !(candidatePort === this.start)) { | ||
candidatePort--; | ||
} | ||
this.end = candidatePort; | ||
} | ||
} | ||
} | ||
function randomNumberBetween(min, max) { | ||
return Math.floor(Math.random() * (max - min + 1) + min); | ||
} | ||
export { Ports } from './ensure-port'; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "ensure-port", | ||
"version": "0.0.0", | ||
"version": "0.0.1", | ||
"description": "Makes sure you get an available port", | ||
@@ -5,0 +5,0 @@ "main": "dist/cjs/index.js", |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
75504
37
474
1