@portel/photon 1.32.3 → 1.32.4
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/dist/auto-ui/beam.d.ts.map +1 -1
- package/dist/auto-ui/beam.js +21 -10
- package/dist/auto-ui/beam.js.map +1 -1
- package/dist/auto-ui/streamable-http-transport.d.ts.map +1 -1
- package/dist/auto-ui/streamable-http-transport.js +50 -4
- package/dist/auto-ui/streamable-http-transport.js.map +1 -1
- package/dist/daemon/client.d.ts.map +1 -1
- package/dist/daemon/client.js +22 -11
- package/dist/daemon/client.js.map +1 -1
- package/dist/daemon/manager.d.ts +1 -0
- package/dist/daemon/manager.d.ts.map +1 -1
- package/dist/daemon/manager.js +39 -10
- package/dist/daemon/manager.js.map +1 -1
- package/dist/daemon/server.js +63 -12
- package/dist/daemon/server.js.map +1 -1
- package/package.json +1 -1
package/dist/daemon/server.js
CHANGED
|
@@ -57,27 +57,34 @@ async function isSocketResponsive(target) {
|
|
|
57
57
|
return false;
|
|
58
58
|
return new Promise((resolve) => {
|
|
59
59
|
const client = new net.Socket();
|
|
60
|
+
let done = false;
|
|
61
|
+
const finish = (alive) => {
|
|
62
|
+
if (done)
|
|
63
|
+
return;
|
|
64
|
+
done = true;
|
|
65
|
+
clearTimeout(timer);
|
|
66
|
+
if (alive) {
|
|
67
|
+
client.end();
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
client.destroy();
|
|
71
|
+
}
|
|
72
|
+
resolve(alive);
|
|
73
|
+
};
|
|
60
74
|
const timer = setTimeout(() => {
|
|
61
|
-
|
|
62
|
-
resolve(false);
|
|
75
|
+
finish(false);
|
|
63
76
|
}, 1000);
|
|
64
77
|
client.on('error', () => {
|
|
65
|
-
|
|
66
|
-
client.destroy();
|
|
67
|
-
resolve(false);
|
|
78
|
+
finish(false);
|
|
68
79
|
});
|
|
69
80
|
client.on('connect', () => {
|
|
70
|
-
|
|
71
|
-
client.destroy();
|
|
72
|
-
resolve(true);
|
|
81
|
+
finish(true);
|
|
73
82
|
});
|
|
74
83
|
try {
|
|
75
84
|
client.connect(target);
|
|
76
85
|
}
|
|
77
86
|
catch {
|
|
78
|
-
|
|
79
|
-
client.destroy();
|
|
80
|
-
resolve(false);
|
|
87
|
+
finish(false);
|
|
81
88
|
}
|
|
82
89
|
});
|
|
83
90
|
}
|
|
@@ -286,6 +293,9 @@ const stateDirWatchers = new Map();
|
|
|
286
293
|
// @scheduled cron changes and @webhook additions reach the declared-set
|
|
287
294
|
// without a daemon restart. See watchBaseForProactiveMetadata().
|
|
288
295
|
const baseDirWatchers = new Map();
|
|
296
|
+
// photonDir -> SafeWatcher: startup watcher for new .photon.ts files in each
|
|
297
|
+
// active base. Tracked separately so Bun poll timers are closed on shutdown.
|
|
298
|
+
const startupPhotonDirWatchers = new Map();
|
|
289
299
|
import { compositeKey as _compositeKey, declaredKey as _declaredKey, webhookKey as _webhookKey, locationKey as _locationKey, findByPhoton, asScheduleKey, } from './registry-keys.js';
|
|
290
300
|
/**
|
|
291
301
|
* Create a composite key from photonName + workingDir for map lookups.
|
|
@@ -5155,15 +5165,33 @@ function startupWatchPhotons() {
|
|
|
5155
5165
|
const defaultBase = getDefaultContext().baseDir;
|
|
5156
5166
|
const bases = new Set([defaultBase]);
|
|
5157
5167
|
for (const base of listActiveBases()) {
|
|
5168
|
+
if (!shouldStartupWatchBase(base.path, defaultBase))
|
|
5169
|
+
continue;
|
|
5158
5170
|
bases.add(base.path);
|
|
5159
5171
|
}
|
|
5160
5172
|
for (const photonDir of bases) {
|
|
5161
5173
|
startupWatchPhotonDir(photonDir, defaultBase);
|
|
5162
5174
|
}
|
|
5163
5175
|
}
|
|
5176
|
+
function shouldStartupWatchBase(basePath, defaultBase) {
|
|
5177
|
+
const resolved = path.resolve(basePath);
|
|
5178
|
+
if (resolved === path.resolve(defaultBase))
|
|
5179
|
+
return true;
|
|
5180
|
+
// Temporary directories are common in Beam and daemon regression tests. The
|
|
5181
|
+
// bases registry keeps them while the OS temp cleaner has not removed them,
|
|
5182
|
+
// but a production daemon should not spend long-lived watchers on them at
|
|
5183
|
+
// every startup. If a user actively invokes a temp photon later, the normal
|
|
5184
|
+
// request path still loads it and registers on-demand watchers.
|
|
5185
|
+
const tmpRoot = path.resolve(os.tmpdir());
|
|
5186
|
+
if (resolved === tmpRoot || resolved.startsWith(tmpRoot + path.sep))
|
|
5187
|
+
return false;
|
|
5188
|
+
return true;
|
|
5189
|
+
}
|
|
5164
5190
|
function startupWatchPhotonDir(photonDir, defaultBase) {
|
|
5165
5191
|
if (!fs.existsSync(photonDir))
|
|
5166
5192
|
return;
|
|
5193
|
+
if (startupPhotonDirWatchers.has(photonDir))
|
|
5194
|
+
return;
|
|
5167
5195
|
// Host mode: when the default base is host-disabled, skip the file
|
|
5168
5196
|
// watcher, the eager onInitialize loader, and the directory watcher
|
|
5169
5197
|
// entirely. They all activate background work that the marker is
|
|
@@ -5288,6 +5316,7 @@ function startupWatchPhotonDir(photonDir, defaultBase) {
|
|
|
5288
5316
|
if (typeof dirWatcher.on === 'function') {
|
|
5289
5317
|
dirWatcher.on('error', () => { }); // Non-fatal
|
|
5290
5318
|
}
|
|
5319
|
+
startupPhotonDirWatchers.set(photonDir, dirWatcher);
|
|
5291
5320
|
}
|
|
5292
5321
|
catch {
|
|
5293
5322
|
logger.warn('Failed to watch photon directory for new files', { dir: photonDir });
|
|
@@ -5335,7 +5364,13 @@ function startServer() {
|
|
|
5335
5364
|
cleanupSocketSubscriptions(socket);
|
|
5336
5365
|
});
|
|
5337
5366
|
socket.on('error', (error) => {
|
|
5338
|
-
|
|
5367
|
+
const code = error?.code;
|
|
5368
|
+
if (code === 'ECONNRESET' || code === 'EPIPE') {
|
|
5369
|
+
logger.debug('Socket closed by client', { error: getErrorMessage(error) });
|
|
5370
|
+
}
|
|
5371
|
+
else {
|
|
5372
|
+
logger.warn('Socket error', { error: getErrorMessage(error) });
|
|
5373
|
+
}
|
|
5339
5374
|
connectedSockets.delete(socket);
|
|
5340
5375
|
cleanupSocketSubscriptions(socket);
|
|
5341
5376
|
});
|
|
@@ -5670,6 +5705,22 @@ function shutdown() {
|
|
|
5670
5705
|
for (const photonPath of fileWatchers.keys()) {
|
|
5671
5706
|
unwatchPhotonFile(photonPath);
|
|
5672
5707
|
}
|
|
5708
|
+
for (const watcher of startupPhotonDirWatchers.values()) {
|
|
5709
|
+
watcher.close();
|
|
5710
|
+
}
|
|
5711
|
+
startupPhotonDirWatchers.clear();
|
|
5712
|
+
for (const watcher of baseDirWatchers.values()) {
|
|
5713
|
+
watcher.close();
|
|
5714
|
+
}
|
|
5715
|
+
baseDirWatchers.clear();
|
|
5716
|
+
for (const watcher of parentDirWatchers.values()) {
|
|
5717
|
+
watcher.close();
|
|
5718
|
+
}
|
|
5719
|
+
parentDirWatchers.clear();
|
|
5720
|
+
for (const watcher of stateDirWatchers.values()) {
|
|
5721
|
+
watcher.close();
|
|
5722
|
+
}
|
|
5723
|
+
stateDirWatchers.clear();
|
|
5673
5724
|
// Clean up poll-based watchers (bun fallback)
|
|
5674
5725
|
for (const timer of pollTimers) {
|
|
5675
5726
|
clearInterval(timer);
|