Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bbe56247bd | |||
| 71a0ec3202 | |||
| cda2c06087 | |||
| a762c9acd0 | |||
| 6cdc619cd0 | |||
| c3d4c4abb5 |
21
changelog.md
21
changelog.md
@@ -1,5 +1,26 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2026-02-26 - 5.2.3 - fix(delivery)
|
||||||
|
prevent throttle reset timer from firing after stop and avoid scheduling duplicate timers
|
||||||
|
|
||||||
|
- add throttleResetTimer property to track scheduled throttle-reset timeout
|
||||||
|
- clear throttleResetTimer when stopping to prevent it firing after shutdown
|
||||||
|
- clear existing throttleResetTimer before scheduling a new one and null it when fired to avoid duplicate timers and potential leaks
|
||||||
|
|
||||||
|
## 2026-02-12 - 5.2.2 - fix(deps)
|
||||||
|
bump dependencies: @push.rocks/smartrust to ^1.2.1, lru-cache to ^11.2.6
|
||||||
|
|
||||||
|
- Bumped @push.rocks/smartrust from ^1.2.0 to ^1.2.1
|
||||||
|
- Bumped lru-cache from ^11.2.5 to ^11.2.6
|
||||||
|
|
||||||
|
## 2026-02-11 - 5.2.1 - fix(rust-bridge)
|
||||||
|
map Node.js platform/arch to tsrust-style suffix and add platform-specific and dev localPaths for RustBridge
|
||||||
|
|
||||||
|
- Add getPlatformSuffix() to map process.platform/process.arch to tsrust-style suffixes (e.g. linux_amd64)
|
||||||
|
- Include dist_rust/mailer-bin_{suffix} when available to prefer cross-compiled binaries
|
||||||
|
- Consolidate localPaths and add local dev build paths (rust/target/release and rust/target/debug)
|
||||||
|
- Pass the computed localPaths array into plugins.smartrust.RustBridge (searchSystemPath remains disabled)
|
||||||
|
|
||||||
## 2026-02-11 - 5.2.0 - feat(packaging)
|
## 2026-02-11 - 5.2.0 - feat(packaging)
|
||||||
add package exports entry, include ts/dist_ts in package files, and add TS barrel index re-exports
|
add package exports entry, include ts/dist_ts in package files, and add TS barrel index re-exports
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@push.rocks/smartmta",
|
"name": "@push.rocks/smartmta",
|
||||||
"version": "5.2.0",
|
"version": "5.2.3",
|
||||||
"description": "A high-performance, enterprise-grade Mail Transfer Agent (MTA) built from scratch in TypeScript with Rust acceleration.",
|
"description": "A high-performance, enterprise-grade Mail Transfer Agent (MTA) built from scratch in TypeScript with Rust acceleration.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"mta",
|
"mta",
|
||||||
@@ -52,9 +52,9 @@
|
|||||||
"@push.rocks/smartlog": "^3.1.8",
|
"@push.rocks/smartlog": "^3.1.8",
|
||||||
"@push.rocks/smartmail": "^2.2.0",
|
"@push.rocks/smartmail": "^2.2.0",
|
||||||
"@push.rocks/smartpath": "^6.0.0",
|
"@push.rocks/smartpath": "^6.0.0",
|
||||||
"@push.rocks/smartrust": "^1.2.0",
|
"@push.rocks/smartrust": "^1.2.1",
|
||||||
"@tsclass/tsclass": "^9.2.0",
|
"@tsclass/tsclass": "^9.2.0",
|
||||||
"lru-cache": "^11.2.5",
|
"lru-cache": "^11.2.6",
|
||||||
"mailparser": "^3.9.3",
|
"mailparser": "^3.9.3",
|
||||||
"uuid": "^13.0.0"
|
"uuid": "^13.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
40
pnpm-lock.yaml
generated
40
pnpm-lock.yaml
generated
@@ -24,14 +24,14 @@ importers:
|
|||||||
specifier: ^6.0.0
|
specifier: ^6.0.0
|
||||||
version: 6.0.0
|
version: 6.0.0
|
||||||
'@push.rocks/smartrust':
|
'@push.rocks/smartrust':
|
||||||
specifier: ^1.2.0
|
specifier: ^1.2.1
|
||||||
version: 1.2.0
|
version: 1.2.1
|
||||||
'@tsclass/tsclass':
|
'@tsclass/tsclass':
|
||||||
specifier: ^9.2.0
|
specifier: ^9.2.0
|
||||||
version: 9.3.0
|
version: 9.3.0
|
||||||
lru-cache:
|
lru-cache:
|
||||||
specifier: ^11.2.5
|
specifier: ^11.2.6
|
||||||
version: 11.2.5
|
version: 11.2.6
|
||||||
mailparser:
|
mailparser:
|
||||||
specifier: ^3.9.3
|
specifier: ^3.9.3
|
||||||
version: 3.9.3
|
version: 3.9.3
|
||||||
@@ -69,6 +69,9 @@ packages:
|
|||||||
'@api.global/typedrequest@3.2.5':
|
'@api.global/typedrequest@3.2.5':
|
||||||
resolution: {integrity: sha512-LM/sUTuYnU5xY4gNZrN6ERMiKr+SpDZuSxJkAZz1YazC7ymGfo6uQ8sCnN8eNNQNFqIOkC+BtfYRayfbGwYLLg==}
|
resolution: {integrity: sha512-LM/sUTuYnU5xY4gNZrN6ERMiKr+SpDZuSxJkAZz1YazC7ymGfo6uQ8sCnN8eNNQNFqIOkC+BtfYRayfbGwYLLg==}
|
||||||
|
|
||||||
|
'@api.global/typedrequest@3.2.6':
|
||||||
|
resolution: {integrity: sha512-CnvbjYjnGGw3rwL+7bTHSgRHEpDujzhs3cv7l1xgCXMPQe3DcPg74+9ep1Y5cu21T/w0pxNnDCJpbb0SHqHzAw==}
|
||||||
|
|
||||||
'@api.global/typedserver@3.0.80':
|
'@api.global/typedserver@3.0.80':
|
||||||
resolution: {integrity: sha512-dcp0oXsjBL+XdFg1wUUP08uJQid5bQ0Yv3V3Y3lnI2QCbat0FU+Tsb0TZRnZ4+P150Vj/ITBqJUgDzFsF34grA==}
|
resolution: {integrity: sha512-dcp0oXsjBL+XdFg1wUUP08uJQid5bQ0Yv3V3Y3lnI2QCbat0FU+Tsb0TZRnZ4+P150Vj/ITBqJUgDzFsF34grA==}
|
||||||
|
|
||||||
@@ -830,8 +833,8 @@ packages:
|
|||||||
'@push.rocks/smartrouter@1.3.3':
|
'@push.rocks/smartrouter@1.3.3':
|
||||||
resolution: {integrity: sha512-1+xZEnWlhzqLWAaJ1zFNhQ0zgbfCWQl1DBT72LygLxTs+P0K8AwJKgqo/IX6CT55kGCFnPAZIYSbVJlGsgrB0w==}
|
resolution: {integrity: sha512-1+xZEnWlhzqLWAaJ1zFNhQ0zgbfCWQl1DBT72LygLxTs+P0K8AwJKgqo/IX6CT55kGCFnPAZIYSbVJlGsgrB0w==}
|
||||||
|
|
||||||
'@push.rocks/smartrust@1.2.0':
|
'@push.rocks/smartrust@1.2.1':
|
||||||
resolution: {integrity: sha512-JlaALselIHoP6C3ceQbrvz424G21cND/QsH/KI3E/JrO4XphJiGZwM6f4yJWrijdPYR/YYMoaIiYN7ybZp0C4w==}
|
resolution: {integrity: sha512-ANwXXibUwoHNWF1hhXhXVVrfzYlhgHYRa2205Jkd/s/wXzcWHftYZthilJj+52B7nkzSB76umfxKfK5eBYY2Ug==}
|
||||||
|
|
||||||
'@push.rocks/smartrx@3.0.10':
|
'@push.rocks/smartrx@3.0.10':
|
||||||
resolution: {integrity: sha512-USjIYcsSfzn14cwOsxgq/bBmWDTTzy3ouWAnW5NdMyRRzEbmeNrvmy6TRqNeDlJ2PsYNTt1rr/zGUqvIy72ITg==}
|
resolution: {integrity: sha512-USjIYcsSfzn14cwOsxgq/bBmWDTTzy3ouWAnW5NdMyRRzEbmeNrvmy6TRqNeDlJ2PsYNTt1rr/zGUqvIy72ITg==}
|
||||||
@@ -2491,8 +2494,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==}
|
resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==}
|
||||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
|
|
||||||
lru-cache@11.2.5:
|
lru-cache@11.2.6:
|
||||||
resolution: {integrity: sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==}
|
resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==}
|
||||||
engines: {node: 20 || >=22}
|
engines: {node: 20 || >=22}
|
||||||
|
|
||||||
lru-cache@7.18.3:
|
lru-cache@7.18.3:
|
||||||
@@ -3594,6 +3597,19 @@ snapshots:
|
|||||||
'@push.rocks/webrequest': 3.0.37
|
'@push.rocks/webrequest': 3.0.37
|
||||||
'@push.rocks/webstream': 1.0.10
|
'@push.rocks/webstream': 1.0.10
|
||||||
|
|
||||||
|
'@api.global/typedrequest@3.2.6':
|
||||||
|
dependencies:
|
||||||
|
'@api.global/typedrequest-interfaces': 3.0.19
|
||||||
|
'@push.rocks/isounique': 1.0.5
|
||||||
|
'@push.rocks/lik': 6.2.2
|
||||||
|
'@push.rocks/smartbuffer': 3.0.5
|
||||||
|
'@push.rocks/smartdelay': 3.0.5
|
||||||
|
'@push.rocks/smartguard': 3.1.0
|
||||||
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
|
'@push.rocks/webrequest': 4.0.1
|
||||||
|
'@push.rocks/webstream': 1.0.10
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@api.global/typedserver@3.0.80(@push.rocks/smartserve@2.0.1)':
|
'@api.global/typedserver@3.0.80(@push.rocks/smartserve@2.0.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.5
|
'@api.global/typedrequest': 3.2.5
|
||||||
@@ -5326,7 +5342,7 @@ snapshots:
|
|||||||
'@push.rocks/smartrx': 3.0.10
|
'@push.rocks/smartrx': 3.0.10
|
||||||
path-to-regexp: 8.3.0
|
path-to-regexp: 8.3.0
|
||||||
|
|
||||||
'@push.rocks/smartrust@1.2.0':
|
'@push.rocks/smartrust@1.2.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@push.rocks/smartpath': 6.0.0
|
'@push.rocks/smartpath': 6.0.0
|
||||||
|
|
||||||
@@ -5347,7 +5363,7 @@ snapshots:
|
|||||||
|
|
||||||
'@push.rocks/smartserve@2.0.1':
|
'@push.rocks/smartserve@2.0.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.5
|
'@api.global/typedrequest': 3.2.6
|
||||||
'@cfworker/json-schema': 4.1.1
|
'@cfworker/json-schema': 4.1.1
|
||||||
'@push.rocks/lik': 6.2.2
|
'@push.rocks/lik': 6.2.2
|
||||||
'@push.rocks/smartenv': 6.0.0
|
'@push.rocks/smartenv': 6.0.0
|
||||||
@@ -7313,7 +7329,7 @@ snapshots:
|
|||||||
|
|
||||||
lowercase-keys@3.0.0: {}
|
lowercase-keys@3.0.0: {}
|
||||||
|
|
||||||
lru-cache@11.2.5: {}
|
lru-cache@11.2.6: {}
|
||||||
|
|
||||||
lru-cache@7.18.3: {}
|
lru-cache@7.18.3: {}
|
||||||
|
|
||||||
@@ -7920,7 +7936,7 @@ snapshots:
|
|||||||
|
|
||||||
path-scurry@2.0.1:
|
path-scurry@2.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
lru-cache: 11.2.5
|
lru-cache: 11.2.6
|
||||||
minipass: 7.1.2
|
minipass: 7.1.2
|
||||||
|
|
||||||
path-to-regexp@8.3.0: {}
|
path-to-regexp@8.3.0: {}
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@push.rocks/smartmta',
|
name: '@push.rocks/smartmta',
|
||||||
version: '5.2.0',
|
version: '5.2.3',
|
||||||
description: 'A high-performance, enterprise-grade Mail Transfer Agent (MTA) built from scratch in TypeScript with Rust acceleration.'
|
description: 'A high-performance, enterprise-grade Mail Transfer Agent (MTA) built from scratch in TypeScript with Rust acceleration.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ export class MultiModeDeliverySystem extends EventEmitter {
|
|||||||
private activeDeliveries: Set<string> = new Set();
|
private activeDeliveries: Set<string> = new Set();
|
||||||
private running: boolean = false;
|
private running: boolean = false;
|
||||||
private throttled: boolean = false;
|
private throttled: boolean = false;
|
||||||
|
private throttleResetTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
private rateLimitLastCheck: number = Date.now();
|
private rateLimitLastCheck: number = Date.now();
|
||||||
private rateLimitCounter: number = 0;
|
private rateLimitCounter: number = 0;
|
||||||
private emailServer?: UnifiedEmailServer;
|
private emailServer?: UnifiedEmailServer;
|
||||||
@@ -211,7 +212,13 @@ export class MultiModeDeliverySystem extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.running = false;
|
this.running = false;
|
||||||
|
|
||||||
|
// Clear throttle reset timer to prevent it firing after stop
|
||||||
|
if (this.throttleResetTimer) {
|
||||||
|
clearTimeout(this.throttleResetTimer);
|
||||||
|
this.throttleResetTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for active deliveries to complete
|
// Wait for active deliveries to complete
|
||||||
if (this.activeDeliveries.size > 0) {
|
if (this.activeDeliveries.size > 0) {
|
||||||
logger.log('info', `Waiting for ${this.activeDeliveries.size} active deliveries to complete`);
|
logger.log('info', `Waiting for ${this.activeDeliveries.size} active deliveries to complete`);
|
||||||
@@ -776,7 +783,11 @@ export class MultiModeDeliverySystem extends EventEmitter {
|
|||||||
|
|
||||||
// Schedule throttle reset
|
// Schedule throttle reset
|
||||||
const resetDelay = 60000 - elapsed;
|
const resetDelay = 60000 - elapsed;
|
||||||
setTimeout(() => {
|
if (this.throttleResetTimer) {
|
||||||
|
clearTimeout(this.throttleResetTimer);
|
||||||
|
}
|
||||||
|
this.throttleResetTimer = setTimeout(() => {
|
||||||
|
this.throttleResetTimer = null;
|
||||||
this.throttled = false;
|
this.throttled = false;
|
||||||
this.rateLimitLastCheck = Date.now();
|
this.rateLimitLastCheck = Date.now();
|
||||||
this.rateLimitCounter = 0;
|
this.rateLimitCounter = 0;
|
||||||
|
|||||||
@@ -375,18 +375,39 @@ export class RustSecurityBridge extends EventEmitter {
|
|||||||
private _deliberateStop = false;
|
private _deliberateStop = false;
|
||||||
private _smtpServerConfig: ISmtpServerConfig | null = null;
|
private _smtpServerConfig: ISmtpServerConfig | null = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map Node.js process.platform / process.arch to the tsrust-style suffix
|
||||||
|
* used for cross-compiled binaries, e.g. mailer-bin_linux_amd64.
|
||||||
|
*/
|
||||||
|
private static getPlatformSuffix(): string | null {
|
||||||
|
const archMap: Record<string, string> = { x64: 'amd64', arm64: 'arm64' };
|
||||||
|
const os = process.platform; // 'linux', 'darwin', 'win32', …
|
||||||
|
const arch = archMap[process.arch];
|
||||||
|
if (!arch) return null;
|
||||||
|
return `${os}_${arch}`;
|
||||||
|
}
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
const suffix = RustSecurityBridge.getPlatformSuffix();
|
||||||
|
const localPaths: string[] = [];
|
||||||
|
|
||||||
|
// dist_rust/ candidates (tsrust cross-compiled output)
|
||||||
|
if (suffix) {
|
||||||
|
localPaths.push(plugins.path.join(paths.packageDir, 'dist_rust', `mailer-bin_${suffix}`));
|
||||||
|
}
|
||||||
|
localPaths.push(plugins.path.join(paths.packageDir, 'dist_rust', 'mailer-bin'));
|
||||||
|
// Local dev build paths
|
||||||
|
localPaths.push(plugins.path.join(paths.packageDir, 'rust', 'target', 'release', 'mailer-bin'));
|
||||||
|
localPaths.push(plugins.path.join(paths.packageDir, 'rust', 'target', 'debug', 'mailer-bin'));
|
||||||
|
|
||||||
this.bridge = new plugins.smartrust.RustBridge<TMailerCommands>({
|
this.bridge = new plugins.smartrust.RustBridge<TMailerCommands>({
|
||||||
binaryName: 'mailer-bin',
|
binaryName: 'mailer-bin',
|
||||||
cliArgs: ['--management'],
|
cliArgs: ['--management'],
|
||||||
requestTimeoutMs: 30_000,
|
requestTimeoutMs: 30_000,
|
||||||
readyTimeoutMs: 10_000,
|
readyTimeoutMs: 10_000,
|
||||||
localPaths: [
|
localPaths,
|
||||||
plugins.path.join(paths.packageDir, 'dist_rust', 'mailer-bin'),
|
|
||||||
plugins.path.join(paths.packageDir, 'rust', 'target', 'release', 'mailer-bin'),
|
|
||||||
plugins.path.join(paths.packageDir, 'rust', 'target', 'debug', 'mailer-bin'),
|
|
||||||
],
|
|
||||||
searchSystemPath: false,
|
searchSystemPath: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user