@push.rocks/smartdb 2.4.1 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@push.rocks/smartdb",
3
- "version": "2.4.1",
3
+ "version": "2.5.1",
4
4
  "private": false,
5
5
  "description": "A MongoDB-compatible embedded database server with wire protocol support, backed by a high-performance Rust engine.",
6
6
  "exports": {
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartdb',
6
- version: '2.4.1',
6
+ version: '2.5.1',
7
7
  description: 'A MongoDB-compatible embedded database server with wire protocol support, backed by a high-performance Rust engine.'
8
8
  }
@@ -1,4 +1,6 @@
1
1
  import * as crypto from 'crypto';
2
+ import * as fs from 'fs/promises';
3
+ import * as net from 'net';
2
4
  import * as path from 'path';
3
5
  import * as os from 'os';
4
6
  import { SmartdbServer } from '../ts_smartdb/index.js';
@@ -66,6 +68,55 @@ export class LocalSmartDb {
66
68
  return path.join(os.tmpdir(), `smartdb-${randomId}.sock`);
67
69
  }
68
70
 
71
+ /**
72
+ * Check if a Unix socket is alive by attempting to connect.
73
+ */
74
+ private static isSocketAlive(socketPath: string): Promise<boolean> {
75
+ return new Promise((resolve) => {
76
+ const client = net.createConnection({ path: socketPath }, () => {
77
+ client.destroy();
78
+ resolve(true);
79
+ });
80
+ client.on('error', () => {
81
+ resolve(false);
82
+ });
83
+ client.setTimeout(500, () => {
84
+ client.destroy();
85
+ resolve(false);
86
+ });
87
+ });
88
+ }
89
+
90
+ /**
91
+ * Remove stale smartdb-*.sock files from /tmp.
92
+ * A socket is considered stale if connecting to it fails.
93
+ */
94
+ private static async cleanStaleSockets(): Promise<void> {
95
+ const tmpDir = os.tmpdir();
96
+ let entries: string[];
97
+ try {
98
+ entries = await fs.readdir(tmpDir);
99
+ } catch {
100
+ return;
101
+ }
102
+ const socketFiles = entries.filter(
103
+ (f) => f.startsWith('smartdb-') && f.endsWith('.sock')
104
+ );
105
+ for (const name of socketFiles) {
106
+ const fullPath = path.join(tmpDir, name);
107
+ try {
108
+ const stat = await fs.stat(fullPath);
109
+ if (!stat.isSocket()) continue;
110
+ const alive = await LocalSmartDb.isSocketAlive(fullPath);
111
+ if (!alive) {
112
+ await fs.unlink(fullPath);
113
+ }
114
+ } catch {
115
+ // File may have been removed already; ignore
116
+ }
117
+ }
118
+ }
119
+
69
120
  /**
70
121
  * Start the local SmartDB server and return connection info
71
122
  */
@@ -74,6 +125,9 @@ export class LocalSmartDb {
74
125
  throw new Error('LocalSmartDb is already running');
75
126
  }
76
127
 
128
+ // Clean up stale sockets from previous crashed instances
129
+ await LocalSmartDb.cleanStaleSockets();
130
+
77
131
  // Run storage migration before starting the Rust engine
78
132
  const migrator = new StorageMigrator(this.options.folderPath);
79
133
  await migrator.run();