@jeffusion/bungee-core 6.0.1 → 6.0.3

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.
@@ -10419,6 +10419,7 @@ class ConfigRepository {
10419
10419
  migrateConfigurationDatabase(db);
10420
10420
  verifyRepositoryIntegrity(db);
10421
10421
  const repository = new ConfigRepository(db, options, freezeSnapshot(readRepositorySnapshot(db)));
10422
+ repository.removeUnavailablePlugins();
10422
10423
  repository.getSnapshot();
10423
10424
  repository.getSupervisionState();
10424
10425
  repository.getRuntimeRecoveryBudget();
@@ -10450,6 +10451,80 @@ class ConfigRepository {
10450
10451
  this.snapshot = projection.snapshot;
10451
10452
  return projection;
10452
10453
  }
10454
+ removeUnavailablePlugins() {
10455
+ const available = this.options.compileOptions?.availablePlugins;
10456
+ if (available === undefined)
10457
+ return;
10458
+ runRepositoryAction(() => this.mutationTransaction(() => {
10459
+ const snapshot = readRepositorySnapshot(this.db);
10460
+ const removed = new Set;
10461
+ const installed = (name) => {
10462
+ if (available.has(name))
10463
+ return true;
10464
+ removed.add(name);
10465
+ return false;
10466
+ };
10467
+ const bindings = (values) => values.filter((value) => installed(value.name));
10468
+ const endpoints = (values) => values.map((value) => {
10469
+ const { managedBy, ...endpoint } = value;
10470
+ return {
10471
+ ...endpoint,
10472
+ plugins: bindings(value.plugins),
10473
+ ...managedBy && installed(managedBy.plugin) ? { managedBy } : {}
10474
+ };
10475
+ });
10476
+ const logical = snapshot.aggregate.logical_configuration;
10477
+ const aggregate = {
10478
+ plugin_activations: snapshot.aggregate.plugin_activations.filter((value) => installed(value.plugin_name)),
10479
+ logical_configuration: {
10480
+ ...logical,
10481
+ plugins: bindings(logical.plugins),
10482
+ services: logical.services.map((service) => ({
10483
+ ...service,
10484
+ plugins: bindings(service.plugins),
10485
+ endpoints: endpoints(service.endpoints)
10486
+ })),
10487
+ routes: logical.routes.map((route) => ({
10488
+ ...route,
10489
+ plugins: bindings(route.plugins),
10490
+ ...route.endpoints === undefined ? {} : { endpoints: endpoints(route.endpoints) }
10491
+ }))
10492
+ }
10493
+ };
10494
+ if (removed.size === 0)
10495
+ return;
10496
+ const protection = readManagementProtection(this.db);
10497
+ const provider = protection.selectedProvider !== null && available.has(protection.selectedProvider) ? protection.selectedProvider : null;
10498
+ const now = Date.now(), operationId = randomUUID2();
10499
+ const prepared = prepareCommitCommand({
10500
+ mutation_id: operationId,
10501
+ expected_revision: snapshot.revision,
10502
+ aggregate,
10503
+ kind: "config",
10504
+ created_at: now,
10505
+ target_worker_slots: []
10506
+ });
10507
+ const command = {
10508
+ ...prepared,
10509
+ managementProvider: provider,
10510
+ requestHash: hashConfigurationRequest({
10511
+ kind: prepared.kind,
10512
+ expected_revision: prepared.expectedRevision,
10513
+ aggregate: prepared.aggregate,
10514
+ target_worker_slots: [],
10515
+ management_provider: provider,
10516
+ offline_management: true
10517
+ })
10518
+ };
10519
+ const result = commitTransaction(this.db, command, this.options, snapshot, true);
10520
+ if (result.kind !== "committed")
10521
+ throw new ConfigRepositoryError("invalid_operation", `plugin catalog reconciliation cannot proceed (${result.kind})`);
10522
+ beginPublication(this.db, operationId, now);
10523
+ markDraining(this.db, operationId, now);
10524
+ finalizePublication(this.db, operationId, { outcome: "converged", old_workers_exited: true }, now);
10525
+ }));
10526
+ this.snapshot = freezeSnapshot(readRepositorySnapshot(this.db));
10527
+ }
10453
10528
  setManagementProviderOffline(provider, operationId, now) {
10454
10529
  if (this.options.offline !== true)
10455
10530
  throw new ConfigRepositoryError("invalid_command", "management protection changes require an offline repository");
@@ -10884,12 +10959,16 @@ scope.onmessage = (event) => {
10884
10959
  if (closed || !Array.isArray(request.args))
10885
10960
  throw new ConfigRepositoryError("invalid_command", "storage request is invalid");
10886
10961
  if (request.method === "open") {
10887
- if (repository !== null || request.args.length !== 2 || typeof request.args[0] !== "string" || typeof request.args[1] !== "object" || request.args[1] === null || typeof request.args[1].offline !== "boolean" || !Array.isArray(request.args[1].managementProviders) || request.args[1].managementProviders.some((name) => typeof name !== "string")) {
10962
+ if (repository !== null || request.args.length !== 2 || typeof request.args[0] !== "string" || typeof request.args[1] !== "object" || request.args[1] === null || typeof request.args[1].offline !== "boolean" || !Array.isArray(request.args[1].managementProviders) || request.args[1].managementProviders.some((name) => typeof name !== "string") || request.args[1].availablePlugins !== undefined && (!Array.isArray(request.args[1].availablePlugins) || request.args[1].availablePlugins.some((name) => typeof name !== "string"))) {
10888
10963
  throw new ConfigRepositoryError("invalid_command", "storage open request is invalid");
10889
10964
  }
10890
10965
  repository = ConfigRepository.open(request.args[0], {
10891
10966
  offline: request.args[1].offline,
10892
- compileOptions: { pluginSchemas: new Map, managementProviders: new Set(request.args[1].managementProviders) }
10967
+ compileOptions: {
10968
+ pluginSchemas: new Map,
10969
+ managementProviders: new Set(request.args[1].managementProviders),
10970
+ availablePlugins: request.args[1].availablePlugins === undefined ? undefined : new Set(request.args[1].availablePlugins)
10971
+ }
10893
10972
  });
10894
10973
  scope.postMessage({ id, ok: true, result: {
10895
10974
  ...repository.getControlProjection(),
package/dist/main.js CHANGED
@@ -9182,7 +9182,11 @@ class AsyncConfigRepository {
9182
9182
  static async open(dbPath, options = {}) {
9183
9183
  const client = new AsyncConfigRepository(options);
9184
9184
  try {
9185
- const startup = await client.send("open", [dbPath, { offline: options.offline === true, managementProviders: [...options.compileOptions?.managementProviders ?? []] }]);
9185
+ const startup = await client.send("open", [dbPath, {
9186
+ offline: options.offline === true,
9187
+ managementProviders: [...options.compileOptions?.managementProviders ?? []],
9188
+ availablePlugins: options.compileOptions?.availablePlugins === undefined ? undefined : [...options.compileOptions.availablePlugins]
9189
+ }]);
9186
9190
  client.installControlProjection(startup);
9187
9191
  client.supervision = freezeProjection(startup.supervision);
9188
9192
  client.state = "open";
@@ -201121,7 +201125,7 @@ var package_default;
201121
201125
  var init_package = __esm(() => {
201122
201126
  package_default = {
201123
201127
  name: "@jeffusion/bungee-core",
201124
- version: "6.0.1",
201128
+ version: "6.0.3",
201125
201129
  description: "Bungee reverse proxy core engine",
201126
201130
  main: "./dist/main.js",
201127
201131
  types: "./dist/main.d.ts",
@@ -259559,6 +259563,18 @@ function keepStoppedProcessAlive() {
259559
259563
  process.exitCode = undefined;
259560
259564
  const keeper = setInterval(() => {}, 60000);
259561
259565
  let listener = null;
259566
+ let stopping = false;
259567
+ const stop = () => {
259568
+ if (stopping)
259569
+ return;
259570
+ stopping = true;
259571
+ Promise.resolve(listener?.stop()).finally(() => {
259572
+ clearInterval(keeper);
259573
+ process.exit(0);
259574
+ });
259575
+ };
259576
+ process.once("SIGTERM", stop);
259577
+ process.once("SIGINT", stop);
259562
259578
  try {
259563
259579
  const options = readMasterProcessOptions();
259564
259580
  listener = createManagementListener({
@@ -259574,18 +259590,6 @@ function keepStoppedProcessAlive() {
259574
259590
  } catch {
259575
259591
  logger2.error({ code: "stopped_listener_unavailable" }, "Stopped master requires local offline recovery");
259576
259592
  }
259577
- let stopping = false;
259578
- const stop = () => {
259579
- if (stopping)
259580
- return;
259581
- stopping = true;
259582
- Promise.resolve(listener?.stop()).finally(() => {
259583
- clearInterval(keeper);
259584
- process.exit(0);
259585
- });
259586
- };
259587
- process.once("SIGTERM", stop);
259588
- process.once("SIGINT", stop);
259589
259593
  }
259590
259594
  var init_stopped_process = __esm(() => {
259591
259595
  init_management_listener();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jeffusion/bungee-core",
3
- "version": "6.0.1",
3
+ "version": "6.0.3",
4
4
  "description": "Bungee reverse proxy core engine",
5
5
  "main": "./dist/main.js",
6
6
  "types": "./dist/main.d.ts",
@@ -16,7 +16,7 @@
16
16
  "@iconify-json/lucide": "^1.2.145",
17
17
  "@iconify-json/tabler": "^1.2.42",
18
18
  "@iconify/utils": "^3.1.7",
19
- "@jeffusion/bungee-types": "^6.0.1",
19
+ "@jeffusion/bungee-types": "^6.0.3",
20
20
  "@types/lodash-es": "^4.17.12",
21
21
  "@types/ws": "^8.18.1",
22
22
  "acorn": "^8.15.0",