@openparachute/vault 0.4.6 → 0.4.7-rc.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 +1 -1
- package/src/config.ts +24 -0
- package/src/mirror-config.test.ts +328 -0
- package/src/mirror-config.ts +470 -0
- package/src/mirror-deps.ts +88 -0
- package/src/mirror-manager.test.ts +550 -0
- package/src/mirror-manager.ts +521 -0
- package/src/mirror-registry.ts +26 -0
- package/src/mirror-routes.test.ts +380 -0
- package/src/mirror-routes.ts +152 -0
- package/src/routing.test.ts +76 -0
- package/src/routing.ts +46 -0
- package/src/server.ts +52 -0
package/src/server.ts
CHANGED
|
@@ -27,6 +27,9 @@ import { startTranscriptionWorker, registerTranscriptionHook, type Transcription
|
|
|
27
27
|
import { assetsDir } from "./routes.ts";
|
|
28
28
|
import { resolveScribeAuthToken } from "./scribe-env.ts";
|
|
29
29
|
import { resolveBindHostname } from "./bind.ts";
|
|
30
|
+
import { MirrorManager } from "./mirror-manager.ts";
|
|
31
|
+
import { setMirrorManager } from "./mirror-registry.ts";
|
|
32
|
+
import { buildMirrorDeps, resolveMirrorVaultName } from "./mirror-deps.ts";
|
|
30
33
|
|
|
31
34
|
// Register webhook triggers from global config. Replaces the old hardcoded
|
|
32
35
|
// tts-hook and transcription-hook with config-driven webhooks.
|
|
@@ -192,6 +195,51 @@ const globalConfig = readGlobalConfig();
|
|
|
192
195
|
const port = parseInt(process.env.PORT ?? "") || globalConfig.port || DEFAULT_PORT;
|
|
193
196
|
const hostname = resolveBindHostname();
|
|
194
197
|
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
// Mirror lifecycle (vault-sync Phase A1).
|
|
200
|
+
//
|
|
201
|
+
// Boot-time bootstrap of the persistent mirror manager. Only stands up an
|
|
202
|
+
// active mirror when global config carries `mirror.enabled: true`; otherwise
|
|
203
|
+
// the manager construct + status reflects "disabled" but no filesystem work
|
|
204
|
+
// happens. The HTTP `/admin/mirror` routes can still flip it on at runtime
|
|
205
|
+
// without a vault restart — see routing.ts + mirror-routes.ts.
|
|
206
|
+
//
|
|
207
|
+
// Failure here is logged and ignored; vault keeps serving. The operator
|
|
208
|
+
// sees the error via `GET /admin/mirror` + the log line.
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
let mirrorManager: MirrorManager | null = null;
|
|
211
|
+
{
|
|
212
|
+
// Canonicalized in `mirror-deps.ts:resolveMirrorVaultName` so the
|
|
213
|
+
// binding rule (default_vault → first listed vault → null) lives in
|
|
214
|
+
// exactly one place; multi-vault-mirror work (design-doc open
|
|
215
|
+
// question 2) only has to touch one site.
|
|
216
|
+
const mirrorVaultName = resolveMirrorVaultName(listVaults);
|
|
217
|
+
if (mirrorVaultName) {
|
|
218
|
+
try {
|
|
219
|
+
mirrorManager = new MirrorManager(buildMirrorDeps(mirrorVaultName));
|
|
220
|
+
setMirrorManager(mirrorManager);
|
|
221
|
+
// Don't block server startup on a slow initial export — kick it off
|
|
222
|
+
// in the background, log the outcome. The HTTP server comes up
|
|
223
|
+
// immediately so OAuth + REST aren't blocked behind a multi-second
|
|
224
|
+
// export pass.
|
|
225
|
+
void mirrorManager
|
|
226
|
+
.start()
|
|
227
|
+
.then((status) => {
|
|
228
|
+
if (!status.enabled && status.last_error) {
|
|
229
|
+
console.warn(`[mirror] startup error: ${status.last_error}`);
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
.catch((err) => {
|
|
233
|
+
console.warn(`[mirror] startup threw: ${(err as Error).message ?? err}`);
|
|
234
|
+
});
|
|
235
|
+
} catch (err) {
|
|
236
|
+
console.warn(`[mirror] manager construction failed: ${(err as Error).message ?? err}`);
|
|
237
|
+
}
|
|
238
|
+
} else {
|
|
239
|
+
console.log("[mirror] no vaults yet — manager will be initialized on next restart after a vault exists");
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
195
243
|
const server = Bun.serve({
|
|
196
244
|
port,
|
|
197
245
|
hostname,
|
|
@@ -250,6 +298,10 @@ async function shutdown(signal: string): Promise<void> {
|
|
|
250
298
|
Promise.all([
|
|
251
299
|
defaultHookRegistry.drain(),
|
|
252
300
|
transcriptionWorker?.stop() ?? Promise.resolve(),
|
|
301
|
+
// Mirror manager: cancel the watch interval + let any in-flight
|
|
302
|
+
// export cycle settle. `stop` already has its own brief timeout
|
|
303
|
+
// (250ms) so this doesn't block the larger shutdown race.
|
|
304
|
+
mirrorManager?.stop() ?? Promise.resolve(),
|
|
253
305
|
]),
|
|
254
306
|
new Promise<void>((resolve) => setTimeout(resolve, 5000)),
|
|
255
307
|
]);
|