@dsh-workbench/core 1.1.11 → 1.1.12

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/client.js CHANGED
@@ -802,7 +802,7 @@ window.__ModuleLoader__.load({
802
802
  react$1.useLayoutEffect;
803
803
  var useMemo$10 = react$1.useMemo;
804
804
  react$1.useCallback;
805
- var useRef$24 = react$1.useRef;
805
+ var useRef$23 = react$1.useRef;
806
806
  react$1.useSyncExternalStore;
807
807
  //#endregion
808
808
  //#region ../shared/dist/components/Activity.js
@@ -1587,7 +1587,7 @@ window.__ModuleLoader__.load({
1587
1587
  const { fields, onSubmit, submit, cancel, extra, busy = false, disabled = false, problem } = props;
1588
1588
  const [done, setDone] = useState$43(false);
1589
1589
  const [reveal, setReveal] = useState$43(0);
1590
- const rootRef = useRef$24(null);
1590
+ const rootRef = useRef$23(null);
1591
1591
  const shown = visibleFieldsOf(fields);
1592
1592
  const problems = formProblemsOf(shown, done);
1593
1593
  reportDuplicateKeys(shown);
@@ -2103,11 +2103,11 @@ window.__ModuleLoader__.load({
2103
2103
  const [openState, setOpenState] = useState$43(false);
2104
2104
  const [query, setQuery] = useState$43("");
2105
2105
  const [cursor, setCursor] = useState$43(null);
2106
- const boxRef = useRef$24(null);
2107
- const triggerRef = useRef$24(null);
2108
- const wasOpenRef = useRef$24(false);
2109
- const pickedRef = useRef$24(false);
2110
- const closedByUsRef = useRef$24(false);
2106
+ const boxRef = useRef$23(null);
2107
+ const triggerRef = useRef$23(null);
2108
+ const wasOpenRef = useRef$23(false);
2109
+ const pickedRef = useRef$23(false);
2110
+ const closedByUsRef = useRef$23(false);
2111
2111
  const open = openProp ?? openState;
2112
2112
  const setOpen = (next) => {
2113
2113
  if (openProp === void 0) setOpenState(next);
@@ -10390,11 +10390,17 @@ window.__ModuleLoader__.load({
10390
10390
  ...registry === void 0 || registry === "" ? {} : { registry }
10391
10391
  });
10392
10392
  }
10393
- function readModuleVersions(force = false) {
10394
- return apiGet(MODULE_VERSIONS_ROUTE, force ? { force: "1" } : void 0);
10393
+ function readModuleVersions(force = false, check = true) {
10394
+ return apiGet(MODULE_VERSIONS_ROUTE, {
10395
+ ...force ? { force: "1" } : {},
10396
+ ...check ? {} : { check: "0" }
10397
+ });
10395
10398
  }
10396
- function readInstalledPlugins(force = false) {
10397
- return apiGet(INSTALLED_PLUGINS_ROUTE, force ? { force: "1" } : void 0);
10399
+ function readInstalledPlugins(force = false, check = true) {
10400
+ return apiGet(INSTALLED_PLUGINS_ROUTE, {
10401
+ ...force ? { force: "1" } : {},
10402
+ ...check ? {} : { check: "0" }
10403
+ });
10398
10404
  }
10399
10405
  //#endregion
10400
10406
  //#region src/app/layouts/market/use-module-versions.ts
@@ -10423,6 +10429,10 @@ window.__ModuleLoader__.load({
10423
10429
  modules: -1,
10424
10430
  plugins: -1
10425
10431
  };
10432
+ var newestDataSeq = {
10433
+ modules: -1,
10434
+ plugins: -1
10435
+ };
10426
10436
  var epoch = 0;
10427
10437
  var allSeq = 0;
10428
10438
  function bumpModuleVersionsEpoch() {
@@ -10449,9 +10459,39 @@ window.__ModuleLoader__.load({
10449
10459
  };
10450
10460
  });
10451
10461
  }
10452
- function moduleVersionsCheckedAt(now) {
10453
- const at = [now.modulesCheck.checkedAt, now.pluginsCheck.checkedAt].filter((one) => one !== null);
10454
- return at.length === 0 ? null : Math.max(...at);
10462
+ function withPreviousLatest(modules, previous) {
10463
+ if (previous.length === 0) return modules;
10464
+ const byPkg = new Map(previous.map((module) => [module.pkg, module]));
10465
+ return modules.map((module) => {
10466
+ const old = byPkg.get(module.pkg);
10467
+ if (old === void 0) return module;
10468
+ return {
10469
+ ...module,
10470
+ ...module.latest === void 0 && old.latest !== void 0 ? { latest: old.latest } : {},
10471
+ ...module.latestBlocked === void 0 && old.latestBlocked !== void 0 ? { latestBlocked: old.latestBlocked } : {},
10472
+ ...module.latestUnavailable === void 0 && old.latestUnavailable !== void 0 ? { latestUnavailable: old.latestUnavailable } : {}
10473
+ };
10474
+ });
10475
+ }
10476
+ function withPreviousPluginLatest(plugins, previous) {
10477
+ if (previous.length === 0) return plugins;
10478
+ const byPkg = new Map(previous.map((plugin) => [plugin.pkg, plugin]));
10479
+ return plugins.map((plugin) => {
10480
+ const old = byPkg.get(plugin.pkg);
10481
+ if (old === void 0 || plugin.latest !== void 0 || old.latest === void 0) return plugin;
10482
+ return {
10483
+ ...plugin,
10484
+ latest: old.latest
10485
+ };
10486
+ });
10487
+ }
10488
+ function withPreviousWorkbenchLatest(next, previous) {
10489
+ if (next === null || previous === null) return next;
10490
+ if (next.latest !== void 0 || previous.latest === void 0 || next.pkg !== previous.pkg) return next;
10491
+ return {
10492
+ ...next,
10493
+ latest: previous.latest
10494
+ };
10455
10495
  }
10456
10496
  function moduleVersionsChecking(value) {
10457
10497
  return value.allChecking || value.modulesCheck.checking || value.pluginsCheck.checking;
@@ -10482,72 +10522,104 @@ window.__ModuleLoader__.load({
10482
10522
  checkedAt: ok ? at : seat.checkedAt
10483
10523
  };
10484
10524
  }
10485
- function readModulesOnce(force) {
10486
- return Promise.all([readModuleVersions(force), readMarketInstalled()]).catch(() => null);
10525
+ function readModulesOnce(force, check) {
10526
+ return Promise.all([readModuleVersions(force, check), readMarketInstalled()]).catch(() => null);
10487
10527
  }
10488
- function readPluginsOnce(force) {
10489
- return readInstalledPlugins(force).catch(() => null);
10528
+ function readPluginsOnce(force, check) {
10529
+ return readInstalledPlugins(force, check).catch(() => null);
10490
10530
  }
10491
- function runModuleVersionsRead(force = false, fresh = false, scope = "all") {
10531
+ function readKey(run) {
10532
+ return `${run.kind}:${run.scope}:${run.force ? "force" : "cached"}`;
10533
+ }
10534
+ function superseded(run, part, ticket) {
10535
+ if (run.kind === "data") return ticket < newestDataSeq[part];
10536
+ return !run.force && ticket < newestForceSeq[part];
10537
+ }
10538
+ function runRead(run) {
10492
10539
  const at = epoch;
10493
- const running = inFlight.get(scope);
10494
- if (!fresh && running !== void 0 && running.force === force && running.epoch === at) return running.promise;
10495
- const allTicket = scope === "all" ? allSeq += 1 : allSeq;
10540
+ const key = readKey(run);
10541
+ const running = inFlight.get(key);
10542
+ if (!run.fresh && running !== void 0 && running.epoch === at) return running.promise;
10543
+ const check = run.kind === "check";
10544
+ const allTicket = run.scope === "all" ? allSeq += 1 : allSeq;
10496
10545
  const tickets = /* @__PURE__ */ new Map();
10497
- for (const part of partsOf(scope)) {
10546
+ for (const part of partsOf(run.scope)) {
10498
10547
  const ticket = seq$1[part] += 1;
10499
10548
  tickets.set(part, ticket);
10500
- if (force) newestForceSeq[part] = ticket;
10549
+ if (run.force) newestForceSeq[part] = ticket;
10550
+ if (!check) newestDataSeq[part] = ticket;
10501
10551
  }
10502
- publish$1(checking(scope));
10503
- const modulesRead = tickets.has("modules") ? readModulesOnce(force) : null;
10504
- const pluginsRead = tickets.has("plugins") ? readPluginsOnce(force) : null;
10505
- const promise = Promise.all([modulesRead, pluginsRead]).then(([modules, plugins]) => {
10506
- if (at !== epoch) return;
10507
- const now = Date.now();
10508
- const modulesTicket = tickets.get("modules");
10509
- const pluginsTicket = tickets.get("plugins");
10510
- const modulesLanded = modulesTicket !== void 0 && (force || modulesTicket >= newestForceSeq.modules);
10511
- const pluginsLanded = pluginsTicket !== void 0 && (force || pluginsTicket >= newestForceSeq.plugins);
10512
- const modulesOk = modulesLanded && modules !== null && modules[0].ok === true;
10513
- const pluginsOk = pluginsLanded && plugins !== null && plugins.ok === true;
10552
+ if (check) publish$1(checking(run.scope));
10553
+ const modulesTicket = tickets.get("modules");
10554
+ const pluginsTicket = tickets.get("plugins");
10555
+ const modulesRead = modulesTicket === void 0 ? null : readModulesOnce(run.force, check).then((response) => {
10556
+ if (at !== epoch || response === null || superseded(run, "modules", modulesTicket)) return;
10557
+ const [modules, market] = response;
10558
+ const payload = modules.ok === true ? modules : null;
10559
+ const listed = payload === null ? null : withMarketUpdates(payload.modules, market.ok === true ? market.modules : []);
10560
+ const shown = listed === null ? null : check ? listed : withPreviousLatest(listed, state.modules ?? []);
10514
10561
  publish$1({
10515
10562
  ...state,
10516
- modules: modulesOk ? withMarketUpdates(modules[0].modules, modules[1].ok === true ? modules[1].modules : []) : state.modules,
10517
- workbench: modulesOk ? modules[0].workbench ?? null : state.workbench,
10518
- selfUpdate: modulesOk ? modules[0].selfUpdate ?? null : state.selfUpdate,
10519
- plugins: pluginsOk ? plugins.plugins : state.plugins,
10563
+ modules: shown ?? state.modules,
10564
+ workbench: payload === null ? state.workbench : check ? payload.workbench ?? null : withPreviousWorkbenchLatest(payload.workbench ?? null, state.workbench),
10565
+ selfUpdate: payload === null ? state.selfUpdate : payload.selfUpdate ?? null,
10520
10566
  read: true,
10521
- allChecking: scope === "all" && allTicket === allSeq ? false : state.allChecking,
10522
- modulesCheck: modulesLanded && modulesTicket !== void 0 ? landed(state.modulesCheck, modulesTicket, seq$1.modules, modulesOk, now) : state.modulesCheck,
10523
- pluginsCheck: pluginsLanded && pluginsTicket !== void 0 ? landed(state.pluginsCheck, pluginsTicket, seq$1.plugins, pluginsOk, now) : state.pluginsCheck
10567
+ ...check ? { modulesCheck: landed(state.modulesCheck, modulesTicket, seq$1.modules, payload !== null, Date.now()) } : {}
10568
+ });
10569
+ });
10570
+ const pluginsRead = pluginsTicket === void 0 ? null : readPluginsOnce(run.force, check).then((response) => {
10571
+ if (at !== epoch || response === null || superseded(run, "plugins", pluginsTicket)) return;
10572
+ const ok = response.ok === true;
10573
+ publish$1({
10574
+ ...state,
10575
+ plugins: ok ? check ? response.plugins : withPreviousPluginLatest(response.plugins, state.plugins ?? []) : state.plugins,
10576
+ ...check ? { pluginsCheck: landed(state.pluginsCheck, pluginsTicket, seq$1.plugins, ok, Date.now()) } : {}
10577
+ });
10578
+ });
10579
+ const promise = Promise.all([modulesRead, pluginsRead]).then(() => {
10580
+ if (at !== epoch || !check || run.scope !== "all" || allTicket !== allSeq) return;
10581
+ if (!state.allChecking) return;
10582
+ publish$1({
10583
+ ...state,
10584
+ allChecking: false
10524
10585
  });
10525
10586
  }).finally(() => {
10526
- if (inFlight.get(scope)?.promise === promise) inFlight.delete(scope);
10587
+ if (inFlight.get(key)?.promise === promise) inFlight.delete(key);
10527
10588
  });
10528
- inFlight.set(scope, {
10529
- force,
10589
+ inFlight.set(key, {
10530
10590
  epoch: at,
10531
10591
  promise
10532
10592
  });
10533
10593
  return promise;
10534
10594
  }
10595
+ function runModuleVersionsRead(force = false, fresh = false, scope = "all") {
10596
+ return runRead({
10597
+ kind: "check",
10598
+ force,
10599
+ fresh,
10600
+ scope
10601
+ });
10602
+ }
10603
+ function runInstalledRead(options = {}) {
10604
+ return runRead({
10605
+ kind: "data",
10606
+ force: false,
10607
+ fresh: options.fresh === true,
10608
+ scope: "all"
10609
+ });
10610
+ }
10535
10611
  function useModuleVersions() {
10536
10612
  const value = (0, react.useSyncExternalStore)(subscribeModuleVersions, moduleVersionsValue);
10537
10613
  const factRev = useFactRevision(CAPABILITY_FACT);
10538
- const mountedRef = (0, react.useRef)(false);
10539
10614
  (0, react.useEffect)(() => {
10540
- const first = !mountedRef.current;
10541
- mountedRef.current = true;
10542
- if (first && !shouldProbeOnEnter({
10543
- checkedAt: moduleVersionsCheckedAt(state),
10544
- now: Date.now(),
10545
- staleMs: MARKET_STALE_MS
10546
- })) return;
10547
- runModuleVersionsRead(false);
10615
+ runInstalledRead();
10548
10616
  }, [factRev]);
10549
10617
  const reload = (0, react.useCallback)((options) => {
10550
- runModuleVersionsRead(options?.force === true, options?.fresh === true, options?.scope ?? "all");
10618
+ if (options?.check === true) {
10619
+ runModuleVersionsRead(options.force === true, options.fresh === true, options.scope ?? "all");
10620
+ return;
10621
+ }
10622
+ runInstalledRead({ fresh: options?.fresh === true });
10551
10623
  }, []);
10552
10624
  return {
10553
10625
  ...value,
@@ -10564,29 +10636,36 @@ window.__ModuleLoader__.load({
10564
10636
  bumpModuleVersionsEpoch();
10565
10637
  bumpCapabilityEpoch();
10566
10638
  forceProbe();
10567
- reloadVersions({
10568
- force: true,
10569
- fresh: true
10570
- });
10571
- return;
10572
- }
10573
- reloadCapability();
10639
+ } else reloadCapability();
10574
10640
  reloadVersions();
10575
10641
  }, [
10576
10642
  reloadCapability,
10577
10643
  reloadVersions,
10578
10644
  forceProbe
10579
10645
  ]);
10580
- const checkPart = (0, react.useCallback)((part) => reloadVersions({
10581
- force: true,
10582
- fresh: true,
10583
- scope: part
10584
- }), [reloadVersions]);
10646
+ const check = (0, react.useCallback)((options) => {
10647
+ reloadVersions({
10648
+ check: true,
10649
+ force: options?.force === true,
10650
+ fresh: true,
10651
+ ...options?.scope === void 0 ? {} : { scope: options.scope }
10652
+ });
10653
+ }, [reloadVersions]);
10654
+ const recheck = (0, react.useCallback)(() => {
10655
+ bumpCapabilityEpoch();
10656
+ forceProbe();
10657
+ check({ force: true });
10658
+ }, [check, forceProbe]);
10659
+ const checkPart = (0, react.useCallback)((part) => {
10660
+ check({
10661
+ force: true,
10662
+ scope: part
10663
+ });
10664
+ }, [check]);
10585
10665
  const enteredRef = (0, react.useRef)(false);
10586
10666
  (0, react.useEffect)(() => {
10587
10667
  if (enteredRef.current) return;
10588
10668
  enteredRef.current = true;
10589
- reloadVersions();
10590
10669
  if (!shouldProbeOnEnter({
10591
10670
  checkedAt,
10592
10671
  now: Date.now(),
@@ -10594,13 +10673,15 @@ window.__ModuleLoader__.load({
10594
10673
  })) return;
10595
10674
  markNextProbeSilent();
10596
10675
  forceProbe();
10676
+ check();
10597
10677
  }, [
10598
10678
  checkedAt,
10599
10679
  forceProbe,
10600
- reloadVersions
10680
+ check
10601
10681
  ]);
10602
10682
  return {
10603
10683
  reload,
10684
+ recheck,
10604
10685
  checkPart
10605
10686
  };
10606
10687
  }
@@ -11297,7 +11378,7 @@ window.__ModuleLoader__.load({
11297
11378
  const openAddModule = (0, react.useCallback)(() => setAdding(true), []);
11298
11379
  const updates = (0, react.useMemo)(() => marketUpdatesOf(modules), [modules]);
11299
11380
  const installed = modules === null ? void 0 : withClientRefusals(modules, units.refusals());
11300
- const { reload, checkPart } = useMarketReload({
11381
+ const { reload, recheck, checkPart } = useMarketReload({
11301
11382
  checkedAt,
11302
11383
  forceProbe,
11303
11384
  reloadCapability,
@@ -11328,7 +11409,7 @@ window.__ModuleLoader__.load({
11328
11409
  busy,
11329
11410
  checking: checking || versionsAllChecking,
11330
11411
  onTab: setTab,
11331
- onReload: () => reload({ force: true }),
11412
+ onReload: recheck,
11332
11413
  onAdd: openAddModule
11333
11414
  }), devMarket.strip, /* @__PURE__ */ (0, react.createElement)("div", {
11334
11415
  id: `${MARKET_PANEL_ID}-panel-installed`,
@@ -795,7 +795,7 @@ var useEffect$33 = react$1.useEffect;
795
795
  react$1.useLayoutEffect;
796
796
  var useMemo$10 = react$1.useMemo;
797
797
  react$1.useCallback;
798
- var useRef$24 = react$1.useRef;
798
+ var useRef$23 = react$1.useRef;
799
799
  react$1.useSyncExternalStore;
800
800
  //#endregion
801
801
  //#region ../shared/dist/components/Activity.js
@@ -1580,7 +1580,7 @@ function Form(props) {
1580
1580
  const { fields, onSubmit, submit, cancel, extra, busy = false, disabled = false, problem } = props;
1581
1581
  const [done, setDone] = useState$43(false);
1582
1582
  const [reveal, setReveal] = useState$43(0);
1583
- const rootRef = useRef$24(null);
1583
+ const rootRef = useRef$23(null);
1584
1584
  const shown = visibleFieldsOf(fields);
1585
1585
  const problems = formProblemsOf(shown, done);
1586
1586
  reportDuplicateKeys(shown);
@@ -2096,11 +2096,11 @@ function useSelectState(props) {
2096
2096
  const [openState, setOpenState] = useState$43(false);
2097
2097
  const [query, setQuery] = useState$43("");
2098
2098
  const [cursor, setCursor] = useState$43(null);
2099
- const boxRef = useRef$24(null);
2100
- const triggerRef = useRef$24(null);
2101
- const wasOpenRef = useRef$24(false);
2102
- const pickedRef = useRef$24(false);
2103
- const closedByUsRef = useRef$24(false);
2099
+ const boxRef = useRef$23(null);
2100
+ const triggerRef = useRef$23(null);
2101
+ const wasOpenRef = useRef$23(false);
2102
+ const pickedRef = useRef$23(false);
2103
+ const closedByUsRef = useRef$23(false);
2104
2104
  const open = openProp ?? openState;
2105
2105
  const setOpen = (next) => {
2106
2106
  if (openProp === void 0) setOpenState(next);
@@ -10383,11 +10383,17 @@ function readBundleInspection(spec, registry) {
10383
10383
  ...registry === void 0 || registry === "" ? {} : { registry }
10384
10384
  });
10385
10385
  }
10386
- function readModuleVersions(force = false) {
10387
- return apiGet(MODULE_VERSIONS_ROUTE, force ? { force: "1" } : void 0);
10386
+ function readModuleVersions(force = false, check = true) {
10387
+ return apiGet(MODULE_VERSIONS_ROUTE, {
10388
+ ...force ? { force: "1" } : {},
10389
+ ...check ? {} : { check: "0" }
10390
+ });
10388
10391
  }
10389
- function readInstalledPlugins(force = false) {
10390
- return apiGet(INSTALLED_PLUGINS_ROUTE, force ? { force: "1" } : void 0);
10392
+ function readInstalledPlugins(force = false, check = true) {
10393
+ return apiGet(INSTALLED_PLUGINS_ROUTE, {
10394
+ ...force ? { force: "1" } : {},
10395
+ ...check ? {} : { check: "0" }
10396
+ });
10391
10397
  }
10392
10398
  //#endregion
10393
10399
  //#region src/app/layouts/market/use-module-versions.ts
@@ -10416,6 +10422,10 @@ var newestForceSeq = {
10416
10422
  modules: -1,
10417
10423
  plugins: -1
10418
10424
  };
10425
+ var newestDataSeq = {
10426
+ modules: -1,
10427
+ plugins: -1
10428
+ };
10419
10429
  var epoch = 0;
10420
10430
  var allSeq = 0;
10421
10431
  function bumpModuleVersionsEpoch() {
@@ -10442,9 +10452,39 @@ function withMarketUpdates(modules, rows) {
10442
10452
  };
10443
10453
  });
10444
10454
  }
10445
- function moduleVersionsCheckedAt(now) {
10446
- const at = [now.modulesCheck.checkedAt, now.pluginsCheck.checkedAt].filter((one) => one !== null);
10447
- return at.length === 0 ? null : Math.max(...at);
10455
+ function withPreviousLatest(modules, previous) {
10456
+ if (previous.length === 0) return modules;
10457
+ const byPkg = new Map(previous.map((module) => [module.pkg, module]));
10458
+ return modules.map((module) => {
10459
+ const old = byPkg.get(module.pkg);
10460
+ if (old === void 0) return module;
10461
+ return {
10462
+ ...module,
10463
+ ...module.latest === void 0 && old.latest !== void 0 ? { latest: old.latest } : {},
10464
+ ...module.latestBlocked === void 0 && old.latestBlocked !== void 0 ? { latestBlocked: old.latestBlocked } : {},
10465
+ ...module.latestUnavailable === void 0 && old.latestUnavailable !== void 0 ? { latestUnavailable: old.latestUnavailable } : {}
10466
+ };
10467
+ });
10468
+ }
10469
+ function withPreviousPluginLatest(plugins, previous) {
10470
+ if (previous.length === 0) return plugins;
10471
+ const byPkg = new Map(previous.map((plugin) => [plugin.pkg, plugin]));
10472
+ return plugins.map((plugin) => {
10473
+ const old = byPkg.get(plugin.pkg);
10474
+ if (old === void 0 || plugin.latest !== void 0 || old.latest === void 0) return plugin;
10475
+ return {
10476
+ ...plugin,
10477
+ latest: old.latest
10478
+ };
10479
+ });
10480
+ }
10481
+ function withPreviousWorkbenchLatest(next, previous) {
10482
+ if (next === null || previous === null) return next;
10483
+ if (next.latest !== void 0 || previous.latest === void 0 || next.pkg !== previous.pkg) return next;
10484
+ return {
10485
+ ...next,
10486
+ latest: previous.latest
10487
+ };
10448
10488
  }
10449
10489
  function moduleVersionsChecking(value) {
10450
10490
  return value.allChecking || value.modulesCheck.checking || value.pluginsCheck.checking;
@@ -10475,72 +10515,104 @@ function landed(seat, ticket, latest, ok, at) {
10475
10515
  checkedAt: ok ? at : seat.checkedAt
10476
10516
  };
10477
10517
  }
10478
- function readModulesOnce(force) {
10479
- return Promise.all([readModuleVersions(force), readMarketInstalled()]).catch(() => null);
10518
+ function readModulesOnce(force, check) {
10519
+ return Promise.all([readModuleVersions(force, check), readMarketInstalled()]).catch(() => null);
10480
10520
  }
10481
- function readPluginsOnce(force) {
10482
- return readInstalledPlugins(force).catch(() => null);
10521
+ function readPluginsOnce(force, check) {
10522
+ return readInstalledPlugins(force, check).catch(() => null);
10483
10523
  }
10484
- function runModuleVersionsRead(force = false, fresh = false, scope = "all") {
10524
+ function readKey(run) {
10525
+ return `${run.kind}:${run.scope}:${run.force ? "force" : "cached"}`;
10526
+ }
10527
+ function superseded(run, part, ticket) {
10528
+ if (run.kind === "data") return ticket < newestDataSeq[part];
10529
+ return !run.force && ticket < newestForceSeq[part];
10530
+ }
10531
+ function runRead(run) {
10485
10532
  const at = epoch;
10486
- const running = inFlight.get(scope);
10487
- if (!fresh && running !== void 0 && running.force === force && running.epoch === at) return running.promise;
10488
- const allTicket = scope === "all" ? allSeq += 1 : allSeq;
10533
+ const key = readKey(run);
10534
+ const running = inFlight.get(key);
10535
+ if (!run.fresh && running !== void 0 && running.epoch === at) return running.promise;
10536
+ const check = run.kind === "check";
10537
+ const allTicket = run.scope === "all" ? allSeq += 1 : allSeq;
10489
10538
  const tickets = /* @__PURE__ */ new Map();
10490
- for (const part of partsOf(scope)) {
10539
+ for (const part of partsOf(run.scope)) {
10491
10540
  const ticket = seq$1[part] += 1;
10492
10541
  tickets.set(part, ticket);
10493
- if (force) newestForceSeq[part] = ticket;
10542
+ if (run.force) newestForceSeq[part] = ticket;
10543
+ if (!check) newestDataSeq[part] = ticket;
10494
10544
  }
10495
- publish$1(checking(scope));
10496
- const modulesRead = tickets.has("modules") ? readModulesOnce(force) : null;
10497
- const pluginsRead = tickets.has("plugins") ? readPluginsOnce(force) : null;
10498
- const promise = Promise.all([modulesRead, pluginsRead]).then(([modules, plugins]) => {
10499
- if (at !== epoch) return;
10500
- const now = Date.now();
10501
- const modulesTicket = tickets.get("modules");
10502
- const pluginsTicket = tickets.get("plugins");
10503
- const modulesLanded = modulesTicket !== void 0 && (force || modulesTicket >= newestForceSeq.modules);
10504
- const pluginsLanded = pluginsTicket !== void 0 && (force || pluginsTicket >= newestForceSeq.plugins);
10505
- const modulesOk = modulesLanded && modules !== null && modules[0].ok === true;
10506
- const pluginsOk = pluginsLanded && plugins !== null && plugins.ok === true;
10545
+ if (check) publish$1(checking(run.scope));
10546
+ const modulesTicket = tickets.get("modules");
10547
+ const pluginsTicket = tickets.get("plugins");
10548
+ const modulesRead = modulesTicket === void 0 ? null : readModulesOnce(run.force, check).then((response) => {
10549
+ if (at !== epoch || response === null || superseded(run, "modules", modulesTicket)) return;
10550
+ const [modules, market] = response;
10551
+ const payload = modules.ok === true ? modules : null;
10552
+ const listed = payload === null ? null : withMarketUpdates(payload.modules, market.ok === true ? market.modules : []);
10553
+ const shown = listed === null ? null : check ? listed : withPreviousLatest(listed, state.modules ?? []);
10507
10554
  publish$1({
10508
10555
  ...state,
10509
- modules: modulesOk ? withMarketUpdates(modules[0].modules, modules[1].ok === true ? modules[1].modules : []) : state.modules,
10510
- workbench: modulesOk ? modules[0].workbench ?? null : state.workbench,
10511
- selfUpdate: modulesOk ? modules[0].selfUpdate ?? null : state.selfUpdate,
10512
- plugins: pluginsOk ? plugins.plugins : state.plugins,
10556
+ modules: shown ?? state.modules,
10557
+ workbench: payload === null ? state.workbench : check ? payload.workbench ?? null : withPreviousWorkbenchLatest(payload.workbench ?? null, state.workbench),
10558
+ selfUpdate: payload === null ? state.selfUpdate : payload.selfUpdate ?? null,
10513
10559
  read: true,
10514
- allChecking: scope === "all" && allTicket === allSeq ? false : state.allChecking,
10515
- modulesCheck: modulesLanded && modulesTicket !== void 0 ? landed(state.modulesCheck, modulesTicket, seq$1.modules, modulesOk, now) : state.modulesCheck,
10516
- pluginsCheck: pluginsLanded && pluginsTicket !== void 0 ? landed(state.pluginsCheck, pluginsTicket, seq$1.plugins, pluginsOk, now) : state.pluginsCheck
10560
+ ...check ? { modulesCheck: landed(state.modulesCheck, modulesTicket, seq$1.modules, payload !== null, Date.now()) } : {}
10561
+ });
10562
+ });
10563
+ const pluginsRead = pluginsTicket === void 0 ? null : readPluginsOnce(run.force, check).then((response) => {
10564
+ if (at !== epoch || response === null || superseded(run, "plugins", pluginsTicket)) return;
10565
+ const ok = response.ok === true;
10566
+ publish$1({
10567
+ ...state,
10568
+ plugins: ok ? check ? response.plugins : withPreviousPluginLatest(response.plugins, state.plugins ?? []) : state.plugins,
10569
+ ...check ? { pluginsCheck: landed(state.pluginsCheck, pluginsTicket, seq$1.plugins, ok, Date.now()) } : {}
10570
+ });
10571
+ });
10572
+ const promise = Promise.all([modulesRead, pluginsRead]).then(() => {
10573
+ if (at !== epoch || !check || run.scope !== "all" || allTicket !== allSeq) return;
10574
+ if (!state.allChecking) return;
10575
+ publish$1({
10576
+ ...state,
10577
+ allChecking: false
10517
10578
  });
10518
10579
  }).finally(() => {
10519
- if (inFlight.get(scope)?.promise === promise) inFlight.delete(scope);
10580
+ if (inFlight.get(key)?.promise === promise) inFlight.delete(key);
10520
10581
  });
10521
- inFlight.set(scope, {
10522
- force,
10582
+ inFlight.set(key, {
10523
10583
  epoch: at,
10524
10584
  promise
10525
10585
  });
10526
10586
  return promise;
10527
10587
  }
10588
+ function runModuleVersionsRead(force = false, fresh = false, scope = "all") {
10589
+ return runRead({
10590
+ kind: "check",
10591
+ force,
10592
+ fresh,
10593
+ scope
10594
+ });
10595
+ }
10596
+ function runInstalledRead(options = {}) {
10597
+ return runRead({
10598
+ kind: "data",
10599
+ force: false,
10600
+ fresh: options.fresh === true,
10601
+ scope: "all"
10602
+ });
10603
+ }
10528
10604
  function useModuleVersions() {
10529
10605
  const value = (0, react.useSyncExternalStore)(subscribeModuleVersions, moduleVersionsValue);
10530
10606
  const factRev = useFactRevision(CAPABILITY_FACT);
10531
- const mountedRef = (0, react.useRef)(false);
10532
10607
  (0, react.useEffect)(() => {
10533
- const first = !mountedRef.current;
10534
- mountedRef.current = true;
10535
- if (first && !shouldProbeOnEnter({
10536
- checkedAt: moduleVersionsCheckedAt(state),
10537
- now: Date.now(),
10538
- staleMs: MARKET_STALE_MS
10539
- })) return;
10540
- runModuleVersionsRead(false);
10608
+ runInstalledRead();
10541
10609
  }, [factRev]);
10542
10610
  const reload = (0, react.useCallback)((options) => {
10543
- runModuleVersionsRead(options?.force === true, options?.fresh === true, options?.scope ?? "all");
10611
+ if (options?.check === true) {
10612
+ runModuleVersionsRead(options.force === true, options.fresh === true, options.scope ?? "all");
10613
+ return;
10614
+ }
10615
+ runInstalledRead({ fresh: options?.fresh === true });
10544
10616
  }, []);
10545
10617
  return {
10546
10618
  ...value,
@@ -10557,29 +10629,36 @@ function useMarketReload(input) {
10557
10629
  bumpModuleVersionsEpoch();
10558
10630
  bumpCapabilityEpoch();
10559
10631
  forceProbe();
10560
- reloadVersions({
10561
- force: true,
10562
- fresh: true
10563
- });
10564
- return;
10565
- }
10566
- reloadCapability();
10632
+ } else reloadCapability();
10567
10633
  reloadVersions();
10568
10634
  }, [
10569
10635
  reloadCapability,
10570
10636
  reloadVersions,
10571
10637
  forceProbe
10572
10638
  ]);
10573
- const checkPart = (0, react.useCallback)((part) => reloadVersions({
10574
- force: true,
10575
- fresh: true,
10576
- scope: part
10577
- }), [reloadVersions]);
10639
+ const check = (0, react.useCallback)((options) => {
10640
+ reloadVersions({
10641
+ check: true,
10642
+ force: options?.force === true,
10643
+ fresh: true,
10644
+ ...options?.scope === void 0 ? {} : { scope: options.scope }
10645
+ });
10646
+ }, [reloadVersions]);
10647
+ const recheck = (0, react.useCallback)(() => {
10648
+ bumpCapabilityEpoch();
10649
+ forceProbe();
10650
+ check({ force: true });
10651
+ }, [check, forceProbe]);
10652
+ const checkPart = (0, react.useCallback)((part) => {
10653
+ check({
10654
+ force: true,
10655
+ scope: part
10656
+ });
10657
+ }, [check]);
10578
10658
  const enteredRef = (0, react.useRef)(false);
10579
10659
  (0, react.useEffect)(() => {
10580
10660
  if (enteredRef.current) return;
10581
10661
  enteredRef.current = true;
10582
- reloadVersions();
10583
10662
  if (!shouldProbeOnEnter({
10584
10663
  checkedAt,
10585
10664
  now: Date.now(),
@@ -10587,13 +10666,15 @@ function useMarketReload(input) {
10587
10666
  })) return;
10588
10667
  markNextProbeSilent();
10589
10668
  forceProbe();
10669
+ check();
10590
10670
  }, [
10591
10671
  checkedAt,
10592
10672
  forceProbe,
10593
- reloadVersions
10673
+ check
10594
10674
  ]);
10595
10675
  return {
10596
10676
  reload,
10677
+ recheck,
10597
10678
  checkPart
10598
10679
  };
10599
10680
  }
@@ -11290,7 +11371,7 @@ function MarketPanel({ t, units, titleOf }) {
11290
11371
  const openAddModule = (0, react.useCallback)(() => setAdding(true), []);
11291
11372
  const updates = (0, react.useMemo)(() => marketUpdatesOf(modules), [modules]);
11292
11373
  const installed = modules === null ? void 0 : withClientRefusals(modules, units.refusals());
11293
- const { reload, checkPart } = useMarketReload({
11374
+ const { reload, recheck, checkPart } = useMarketReload({
11294
11375
  checkedAt,
11295
11376
  forceProbe,
11296
11377
  reloadCapability,
@@ -11321,7 +11402,7 @@ function MarketPanel({ t, units, titleOf }) {
11321
11402
  busy,
11322
11403
  checking: checking || versionsAllChecking,
11323
11404
  onTab: setTab,
11324
- onReload: () => reload({ force: true }),
11405
+ onReload: recheck,
11325
11406
  onAdd: openAddModule
11326
11407
  }), devMarket.strip, /* @__PURE__ */ (0, react.createElement)("div", {
11327
11408
  id: `${MARKET_PANEL_ID}-panel-installed`,
@@ -10386,11 +10386,17 @@ function readBundleInspection(spec, registry) {
10386
10386
  ...registry === void 0 || registry === "" ? {} : { registry }
10387
10387
  });
10388
10388
  }
10389
- function readModuleVersions(force = false) {
10390
- return apiGet(MODULE_VERSIONS_ROUTE, force ? { force: "1" } : void 0);
10389
+ function readModuleVersions(force = false, check = true) {
10390
+ return apiGet(MODULE_VERSIONS_ROUTE, {
10391
+ ...force ? { force: "1" } : {},
10392
+ ...check ? {} : { check: "0" }
10393
+ });
10391
10394
  }
10392
- function readInstalledPlugins(force = false) {
10393
- return apiGet(INSTALLED_PLUGINS_ROUTE, force ? { force: "1" } : void 0);
10395
+ function readInstalledPlugins(force = false, check = true) {
10396
+ return apiGet(INSTALLED_PLUGINS_ROUTE, {
10397
+ ...force ? { force: "1" } : {},
10398
+ ...check ? {} : { check: "0" }
10399
+ });
10394
10400
  }
10395
10401
  //#endregion
10396
10402
  //#region src/app/layouts/market/use-module-versions.ts
@@ -10419,6 +10425,10 @@ var newestForceSeq = {
10419
10425
  modules: -1,
10420
10426
  plugins: -1
10421
10427
  };
10428
+ var newestDataSeq = {
10429
+ modules: -1,
10430
+ plugins: -1
10431
+ };
10422
10432
  var epoch = 0;
10423
10433
  var allSeq = 0;
10424
10434
  function bumpModuleVersionsEpoch() {
@@ -10445,9 +10455,39 @@ function withMarketUpdates(modules, rows) {
10445
10455
  };
10446
10456
  });
10447
10457
  }
10448
- function moduleVersionsCheckedAt(now) {
10449
- const at = [now.modulesCheck.checkedAt, now.pluginsCheck.checkedAt].filter((one) => one !== null);
10450
- return at.length === 0 ? null : Math.max(...at);
10458
+ function withPreviousLatest(modules, previous) {
10459
+ if (previous.length === 0) return modules;
10460
+ const byPkg = new Map(previous.map((module) => [module.pkg, module]));
10461
+ return modules.map((module) => {
10462
+ const old = byPkg.get(module.pkg);
10463
+ if (old === void 0) return module;
10464
+ return {
10465
+ ...module,
10466
+ ...module.latest === void 0 && old.latest !== void 0 ? { latest: old.latest } : {},
10467
+ ...module.latestBlocked === void 0 && old.latestBlocked !== void 0 ? { latestBlocked: old.latestBlocked } : {},
10468
+ ...module.latestUnavailable === void 0 && old.latestUnavailable !== void 0 ? { latestUnavailable: old.latestUnavailable } : {}
10469
+ };
10470
+ });
10471
+ }
10472
+ function withPreviousPluginLatest(plugins, previous) {
10473
+ if (previous.length === 0) return plugins;
10474
+ const byPkg = new Map(previous.map((plugin) => [plugin.pkg, plugin]));
10475
+ return plugins.map((plugin) => {
10476
+ const old = byPkg.get(plugin.pkg);
10477
+ if (old === void 0 || plugin.latest !== void 0 || old.latest === void 0) return plugin;
10478
+ return {
10479
+ ...plugin,
10480
+ latest: old.latest
10481
+ };
10482
+ });
10483
+ }
10484
+ function withPreviousWorkbenchLatest(next, previous) {
10485
+ if (next === null || previous === null) return next;
10486
+ if (next.latest !== void 0 || previous.latest === void 0 || next.pkg !== previous.pkg) return next;
10487
+ return {
10488
+ ...next,
10489
+ latest: previous.latest
10490
+ };
10451
10491
  }
10452
10492
  function moduleVersionsChecking(value) {
10453
10493
  return value.allChecking || value.modulesCheck.checking || value.pluginsCheck.checking;
@@ -10478,72 +10518,104 @@ function landed(seat, ticket, latest, ok, at) {
10478
10518
  checkedAt: ok ? at : seat.checkedAt
10479
10519
  };
10480
10520
  }
10481
- function readModulesOnce(force) {
10482
- return Promise.all([readModuleVersions(force), readMarketInstalled()]).catch(() => null);
10521
+ function readModulesOnce(force, check) {
10522
+ return Promise.all([readModuleVersions(force, check), readMarketInstalled()]).catch(() => null);
10483
10523
  }
10484
- function readPluginsOnce(force) {
10485
- return readInstalledPlugins(force).catch(() => null);
10524
+ function readPluginsOnce(force, check) {
10525
+ return readInstalledPlugins(force, check).catch(() => null);
10486
10526
  }
10487
- function runModuleVersionsRead(force = false, fresh = false, scope = "all") {
10527
+ function readKey(run) {
10528
+ return `${run.kind}:${run.scope}:${run.force ? "force" : "cached"}`;
10529
+ }
10530
+ function superseded(run, part, ticket) {
10531
+ if (run.kind === "data") return ticket < newestDataSeq[part];
10532
+ return !run.force && ticket < newestForceSeq[part];
10533
+ }
10534
+ function runRead(run) {
10488
10535
  const at = epoch;
10489
- const running = inFlight.get(scope);
10490
- if (!fresh && running !== void 0 && running.force === force && running.epoch === at) return running.promise;
10491
- const allTicket = scope === "all" ? allSeq += 1 : allSeq;
10536
+ const key = readKey(run);
10537
+ const running = inFlight.get(key);
10538
+ if (!run.fresh && running !== void 0 && running.epoch === at) return running.promise;
10539
+ const check = run.kind === "check";
10540
+ const allTicket = run.scope === "all" ? allSeq += 1 : allSeq;
10492
10541
  const tickets = /* @__PURE__ */ new Map();
10493
- for (const part of partsOf(scope)) {
10542
+ for (const part of partsOf(run.scope)) {
10494
10543
  const ticket = seq$1[part] += 1;
10495
10544
  tickets.set(part, ticket);
10496
- if (force) newestForceSeq[part] = ticket;
10545
+ if (run.force) newestForceSeq[part] = ticket;
10546
+ if (!check) newestDataSeq[part] = ticket;
10497
10547
  }
10498
- publish$1(checking(scope));
10499
- const modulesRead = tickets.has("modules") ? readModulesOnce(force) : null;
10500
- const pluginsRead = tickets.has("plugins") ? readPluginsOnce(force) : null;
10501
- const promise = Promise.all([modulesRead, pluginsRead]).then(([modules, plugins]) => {
10502
- if (at !== epoch) return;
10503
- const now = Date.now();
10504
- const modulesTicket = tickets.get("modules");
10505
- const pluginsTicket = tickets.get("plugins");
10506
- const modulesLanded = modulesTicket !== void 0 && (force || modulesTicket >= newestForceSeq.modules);
10507
- const pluginsLanded = pluginsTicket !== void 0 && (force || pluginsTicket >= newestForceSeq.plugins);
10508
- const modulesOk = modulesLanded && modules !== null && modules[0].ok === true;
10509
- const pluginsOk = pluginsLanded && plugins !== null && plugins.ok === true;
10548
+ if (check) publish$1(checking(run.scope));
10549
+ const modulesTicket = tickets.get("modules");
10550
+ const pluginsTicket = tickets.get("plugins");
10551
+ const modulesRead = modulesTicket === void 0 ? null : readModulesOnce(run.force, check).then((response) => {
10552
+ if (at !== epoch || response === null || superseded(run, "modules", modulesTicket)) return;
10553
+ const [modules, market] = response;
10554
+ const payload = modules.ok === true ? modules : null;
10555
+ const listed = payload === null ? null : withMarketUpdates(payload.modules, market.ok === true ? market.modules : []);
10556
+ const shown = listed === null ? null : check ? listed : withPreviousLatest(listed, state.modules ?? []);
10510
10557
  publish$1({
10511
10558
  ...state,
10512
- modules: modulesOk ? withMarketUpdates(modules[0].modules, modules[1].ok === true ? modules[1].modules : []) : state.modules,
10513
- workbench: modulesOk ? modules[0].workbench ?? null : state.workbench,
10514
- selfUpdate: modulesOk ? modules[0].selfUpdate ?? null : state.selfUpdate,
10515
- plugins: pluginsOk ? plugins.plugins : state.plugins,
10559
+ modules: shown ?? state.modules,
10560
+ workbench: payload === null ? state.workbench : check ? payload.workbench ?? null : withPreviousWorkbenchLatest(payload.workbench ?? null, state.workbench),
10561
+ selfUpdate: payload === null ? state.selfUpdate : payload.selfUpdate ?? null,
10516
10562
  read: true,
10517
- allChecking: scope === "all" && allTicket === allSeq ? false : state.allChecking,
10518
- modulesCheck: modulesLanded && modulesTicket !== void 0 ? landed(state.modulesCheck, modulesTicket, seq$1.modules, modulesOk, now) : state.modulesCheck,
10519
- pluginsCheck: pluginsLanded && pluginsTicket !== void 0 ? landed(state.pluginsCheck, pluginsTicket, seq$1.plugins, pluginsOk, now) : state.pluginsCheck
10563
+ ...check ? { modulesCheck: landed(state.modulesCheck, modulesTicket, seq$1.modules, payload !== null, Date.now()) } : {}
10564
+ });
10565
+ });
10566
+ const pluginsRead = pluginsTicket === void 0 ? null : readPluginsOnce(run.force, check).then((response) => {
10567
+ if (at !== epoch || response === null || superseded(run, "plugins", pluginsTicket)) return;
10568
+ const ok = response.ok === true;
10569
+ publish$1({
10570
+ ...state,
10571
+ plugins: ok ? check ? response.plugins : withPreviousPluginLatest(response.plugins, state.plugins ?? []) : state.plugins,
10572
+ ...check ? { pluginsCheck: landed(state.pluginsCheck, pluginsTicket, seq$1.plugins, ok, Date.now()) } : {}
10573
+ });
10574
+ });
10575
+ const promise = Promise.all([modulesRead, pluginsRead]).then(() => {
10576
+ if (at !== epoch || !check || run.scope !== "all" || allTicket !== allSeq) return;
10577
+ if (!state.allChecking) return;
10578
+ publish$1({
10579
+ ...state,
10580
+ allChecking: false
10520
10581
  });
10521
10582
  }).finally(() => {
10522
- if (inFlight.get(scope)?.promise === promise) inFlight.delete(scope);
10583
+ if (inFlight.get(key)?.promise === promise) inFlight.delete(key);
10523
10584
  });
10524
- inFlight.set(scope, {
10525
- force,
10585
+ inFlight.set(key, {
10526
10586
  epoch: at,
10527
10587
  promise
10528
10588
  });
10529
10589
  return promise;
10530
10590
  }
10591
+ function runModuleVersionsRead(force = false, fresh = false, scope = "all") {
10592
+ return runRead({
10593
+ kind: "check",
10594
+ force,
10595
+ fresh,
10596
+ scope
10597
+ });
10598
+ }
10599
+ function runInstalledRead(options = {}) {
10600
+ return runRead({
10601
+ kind: "data",
10602
+ force: false,
10603
+ fresh: options.fresh === true,
10604
+ scope: "all"
10605
+ });
10606
+ }
10531
10607
  function useModuleVersions() {
10532
10608
  const value = useSyncExternalStore(subscribeModuleVersions, moduleVersionsValue);
10533
10609
  const factRev = useFactRevision(CAPABILITY_FACT);
10534
- const mountedRef = useRef(false);
10535
10610
  useEffect(() => {
10536
- const first = !mountedRef.current;
10537
- mountedRef.current = true;
10538
- if (first && !shouldProbeOnEnter({
10539
- checkedAt: moduleVersionsCheckedAt(state),
10540
- now: Date.now(),
10541
- staleMs: MARKET_STALE_MS
10542
- })) return;
10543
- runModuleVersionsRead(false);
10611
+ runInstalledRead();
10544
10612
  }, [factRev]);
10545
10613
  const reload = useCallback((options) => {
10546
- runModuleVersionsRead(options?.force === true, options?.fresh === true, options?.scope ?? "all");
10614
+ if (options?.check === true) {
10615
+ runModuleVersionsRead(options.force === true, options.fresh === true, options.scope ?? "all");
10616
+ return;
10617
+ }
10618
+ runInstalledRead({ fresh: options?.fresh === true });
10547
10619
  }, []);
10548
10620
  return {
10549
10621
  ...value,
@@ -10560,29 +10632,36 @@ function useMarketReload(input) {
10560
10632
  bumpModuleVersionsEpoch();
10561
10633
  bumpCapabilityEpoch();
10562
10634
  forceProbe();
10563
- reloadVersions({
10564
- force: true,
10565
- fresh: true
10566
- });
10567
- return;
10568
- }
10569
- reloadCapability();
10635
+ } else reloadCapability();
10570
10636
  reloadVersions();
10571
10637
  }, [
10572
10638
  reloadCapability,
10573
10639
  reloadVersions,
10574
10640
  forceProbe
10575
10641
  ]);
10576
- const checkPart = useCallback((part) => reloadVersions({
10577
- force: true,
10578
- fresh: true,
10579
- scope: part
10580
- }), [reloadVersions]);
10642
+ const check = useCallback((options) => {
10643
+ reloadVersions({
10644
+ check: true,
10645
+ force: options?.force === true,
10646
+ fresh: true,
10647
+ ...options?.scope === void 0 ? {} : { scope: options.scope }
10648
+ });
10649
+ }, [reloadVersions]);
10650
+ const recheck = useCallback(() => {
10651
+ bumpCapabilityEpoch();
10652
+ forceProbe();
10653
+ check({ force: true });
10654
+ }, [check, forceProbe]);
10655
+ const checkPart = useCallback((part) => {
10656
+ check({
10657
+ force: true,
10658
+ scope: part
10659
+ });
10660
+ }, [check]);
10581
10661
  const enteredRef = useRef(false);
10582
10662
  useEffect(() => {
10583
10663
  if (enteredRef.current) return;
10584
10664
  enteredRef.current = true;
10585
- reloadVersions();
10586
10665
  if (!shouldProbeOnEnter({
10587
10666
  checkedAt,
10588
10667
  now: Date.now(),
@@ -10590,13 +10669,15 @@ function useMarketReload(input) {
10590
10669
  })) return;
10591
10670
  markNextProbeSilent();
10592
10671
  forceProbe();
10672
+ check();
10593
10673
  }, [
10594
10674
  checkedAt,
10595
10675
  forceProbe,
10596
- reloadVersions
10676
+ check
10597
10677
  ]);
10598
10678
  return {
10599
10679
  reload,
10680
+ recheck,
10600
10681
  checkPart
10601
10682
  };
10602
10683
  }
@@ -11293,7 +11374,7 @@ function MarketPanel({ t, units, titleOf }) {
11293
11374
  const openAddModule = useCallback(() => setAdding(true), []);
11294
11375
  const updates = useMemo(() => marketUpdatesOf(modules), [modules]);
11295
11376
  const installed = modules === null ? void 0 : withClientRefusals(modules, units.refusals());
11296
- const { reload, checkPart } = useMarketReload({
11377
+ const { reload, recheck, checkPart } = useMarketReload({
11297
11378
  checkedAt,
11298
11379
  forceProbe,
11299
11380
  reloadCapability,
@@ -11324,7 +11405,7 @@ function MarketPanel({ t, units, titleOf }) {
11324
11405
  busy,
11325
11406
  checking: checking || versionsAllChecking,
11326
11407
  onTab: setTab,
11327
- onReload: () => reload({ force: true }),
11408
+ onReload: recheck,
11328
11409
  onAdd: openAddModule
11329
11410
  }), devMarket.strip, /* @__PURE__ */ createElement("div", {
11330
11411
  id: `${MARKET_PANEL_ID}-panel-installed`,
@@ -6583,7 +6583,7 @@ async function workbenchVersion(supply, input) {
6583
6583
  const spec = dependencyReader(input.dir)(PLUGIN_ID);
6584
6584
  const registry = read.registry ?? input.fallback;
6585
6585
  const shell = input.shell;
6586
- const queried = read.local === true || shell === void 0 || registry === void 0 ? void 0 : await supply.latestVersion({
6586
+ const queried = read.local === true || !input.check || shell === void 0 || registry === void 0 ? void 0 : await supply.latestVersion({
6587
6587
  shell,
6588
6588
  name: read.pkg,
6589
6589
  registry,
@@ -6620,6 +6620,7 @@ function moduleVersionsHandler(ctx, shell, running, selfUpdate) {
6620
6620
  const found = supply.profileModules(dir);
6621
6621
  const refusals = new Map((ctx.get("workbenchUnits")?.refusals() ?? []).filter((one) => one.unit !== "").map((one) => [one.unit, one.reasons]));
6622
6622
  const force = param(search, "force") === "1";
6623
+ const check = param(search, "check") !== "0";
6623
6624
  const fallback = (await manager.registries())?.resolved ?? void 0;
6624
6625
  const dependencyOf = dependencyReader(dir);
6625
6626
  const modules = await Promise.all(found.map(async (module) => {
@@ -6627,7 +6628,7 @@ function moduleVersionsHandler(ctx, shell, running, selfUpdate) {
6627
6628
  const fromRegistry = module.fromRegistry !== false;
6628
6629
  const registry = fromRegistry ? module.registry ?? fallback : void 0;
6629
6630
  const spec = dependencyOf(module.pkg);
6630
- const latest = local || !fromRegistry || shell === void 0 || registry === void 0 ? void 0 : await supply.latestVersion({
6631
+ const latest = local || !fromRegistry || !check || shell === void 0 || registry === void 0 ? void 0 : await supply.latestVersion({
6631
6632
  shell,
6632
6633
  name: module.pkg,
6633
6634
  registry,
@@ -6662,7 +6663,7 @@ function moduleVersionsHandler(ctx, shell, running, selfUpdate) {
6662
6663
  ...local ? {
6663
6664
  local: true,
6664
6665
  latestUnavailable: "local"
6665
- } : latest !== void 0 ? {} : { latestUnavailable: !fromRegistry ? "not-registry" : registry === void 0 ? "no-registry" : "probe-failed" },
6666
+ } : latest !== void 0 ? {} : !fromRegistry ? { latestUnavailable: "not-registry" } : registry === void 0 ? { latestUnavailable: "no-registry" } : check ? { latestUnavailable: "probe-failed" } : {},
6666
6667
  ...refused === void 0 ? {} : { refused },
6667
6668
  ...spec === void 0 ? {} : { spec },
6668
6669
  ...registry === void 0 ? {} : { registry }
@@ -6681,6 +6682,7 @@ function moduleVersionsHandler(ctx, shell, running, selfUpdate) {
6681
6682
  shell,
6682
6683
  fallback,
6683
6684
  force,
6685
+ check,
6684
6686
  ...running === void 0 ? {} : { running },
6685
6687
  ...followUp === void 0 ? {} : { followUp },
6686
6688
  logger: ctx.logger
@@ -16643,7 +16645,7 @@ var INSTALLED_PLUGINS_ROUTE = "panels/plugins";
16643
16645
  //#endregion
16644
16646
  //#region src/modules/panels/model/plugin-section.ts
16645
16647
  async function installedPlugins(options) {
16646
- const { ledger, shell, force = false } = options;
16648
+ const { ledger, shell, force = false, check = true } = options;
16647
16649
  const supply = options.supply ?? requireSupply();
16648
16650
  const rows = [];
16649
16651
  for (const entry of ledger.list()) {
@@ -16651,7 +16653,8 @@ async function installedPlugins(options) {
16651
16653
  shell,
16652
16654
  package: entry.package,
16653
16655
  registry: entry.registry,
16654
- force
16656
+ force,
16657
+ check
16655
16658
  });
16656
16659
  rows.push({
16657
16660
  pkg: entry.package,
@@ -16676,7 +16679,8 @@ function pluginRoutes(options) {
16676
16679
  ledger: options.ledger,
16677
16680
  ...options.shell === void 0 ? {} : { shell: options.shell },
16678
16681
  ...options.supply === void 0 ? {} : { supply: options.supply },
16679
- force: param(search, "force") === "1"
16682
+ force: param(search, "force") === "1",
16683
+ check: param(search, "check") !== "0"
16680
16684
  })
16681
16685
  };
16682
16686
  } };
@@ -1,8 +1,14 @@
1
- import { type ModuleVersionsView, type VersionsPart } from './use-module-versions';
1
+ import { type ModuleVersionsView, type VersionsPart, type VersionsScope } from './use-module-versions';
2
+ export interface MarketReloadOptions {
3
+ readonly force?: boolean;
4
+ }
5
+ export interface MarketCheckOptions {
6
+ readonly force?: boolean;
7
+ readonly scope?: VersionsScope;
8
+ }
2
9
  export interface MarketReload {
3
- readonly reload: (options?: {
4
- readonly force?: boolean;
5
- }) => void;
10
+ readonly reload: (options?: MarketReloadOptions) => void;
11
+ readonly recheck: () => void;
6
12
  readonly checkPart: (part: VersionsPart) => void;
7
13
  }
8
14
  export interface MarketReloadInput {
@@ -18,19 +18,19 @@ export interface ModuleVersionsState {
18
18
  readonly modulesCheck: VersionsCheck;
19
19
  readonly pluginsCheck: VersionsCheck;
20
20
  }
21
- export interface ModuleVersionsView extends ModuleVersionsState {
22
- readonly checking: boolean;
23
- reload(options?: {
24
- readonly force?: boolean;
25
- readonly fresh?: boolean;
26
- readonly scope?: VersionsScope;
27
- }): void;
28
- }
29
21
  export interface ModuleVersionsRead {
22
+ check?: boolean;
30
23
  force?: boolean;
31
24
  fresh?: boolean;
32
25
  scope?: VersionsScope;
33
26
  }
27
+ export interface InstalledReadOptions {
28
+ readonly fresh?: boolean;
29
+ }
30
+ export interface ModuleVersionsView extends ModuleVersionsState {
31
+ readonly checking: boolean;
32
+ reload(options?: ModuleVersionsRead): void;
33
+ }
34
34
  export declare function bumpModuleVersionsEpoch(): void;
35
35
  export declare function moduleVersionsValue(): ModuleVersionsState;
36
36
  export declare function resetModuleVersions(): void;
@@ -39,4 +39,5 @@ export declare function withMarketUpdates(modules: readonly ModuleVersion[], row
39
39
  export declare function moduleVersionsCheckedAt(now: ModuleVersionsState): number | null;
40
40
  export declare function moduleVersionsChecking(value: ModuleVersionsState): boolean;
41
41
  export declare function runModuleVersionsRead(force?: boolean, fresh?: boolean, scope?: VersionsScope): Promise<void>;
42
+ export declare function runInstalledRead(options?: InstalledReadOptions): Promise<void>;
42
43
  export declare function useModuleVersions(): ModuleVersionsView;
@@ -9,6 +9,7 @@ import type { MarketMock } from './market-mock';
9
9
  import type { ModuleUpdateMap } from './market-rows';
10
10
  import type { WorkbenchSelfUpdate, WorkbenchVersion } from '../../../kernel/contract/bundle-install';
11
11
  import type { VersionsCheck, VersionsPart } from '../market/use-module-versions';
12
+ import type { MarketReloadOptions } from '../market/use-market-reload';
12
13
  export interface MarketViewProps {
13
14
  readonly t: Translate;
14
15
  readonly titleOf: TitleResolve;
@@ -17,9 +18,7 @@ export interface MarketViewProps {
17
18
  readonly capabilities: CapabilityMap | null;
18
19
  readonly runtimePluginMarket?: boolean | undefined;
19
20
  readonly freshness: MarketFreshness;
20
- readonly onChanged: (options?: {
21
- readonly force?: boolean;
22
- }) => void;
21
+ readonly onChanged: (options?: MarketReloadOptions) => void;
23
22
  readonly onPending?: ((pending: boolean) => void) | undefined;
24
23
  readonly updates?: ModuleUpdateMap | undefined;
25
24
  readonly modulesCheck?: VersionsCheck | undefined;
@@ -2,6 +2,7 @@ import type { Translate, WriteOutcome } from '@dsh-workbench/shared';
2
2
  import type { MarketFailure, MarketRow } from './market-row-types';
3
3
  import { type MarketRowAction } from './market-rows';
4
4
  import { type HeldRow, type Pending } from './market-view-text';
5
+ import type { MarketReloadOptions } from '../market/use-market-reload';
5
6
  export interface MarketActSeats {
6
7
  readonly setPending: (next: Pending | null) => void;
7
8
  readonly setHeld: (next: HeldRow | undefined) => void;
@@ -15,8 +16,6 @@ export interface MarketActOptions {
15
16
  readonly rowOf: (id: string) => MarketRow | undefined;
16
17
  readonly seats: MarketActSeats;
17
18
  readonly send: (body: Record<string, unknown>) => Promise<WriteOutcome<unknown>>;
18
- readonly onChanged: (options?: {
19
- readonly force?: boolean;
20
- }) => void;
19
+ readonly onChanged: (options?: MarketReloadOptions) => void;
21
20
  }
22
21
  export declare function marketActOf(options: MarketActOptions): (id: string, action: MarketRowAction) => Promise<void>;
@@ -6,6 +6,7 @@ export declare function installedPlugins(options: {
6
6
  readonly ledger: PluginLedger;
7
7
  readonly shell?: DshShell | undefined;
8
8
  readonly force?: boolean;
9
+ readonly check?: boolean;
9
10
  readonly supply?: SupplyPort | undefined;
10
11
  }): Promise<readonly InstalledPlugin[]>;
11
12
  export declare function pluginRoutes(options: {
@@ -3,5 +3,5 @@ import { type BundleInspectionPayload, type BundleRegistriesPayload, type Module
3
3
  import { type InstalledPluginsPayload } from '../api/installed-plugins';
4
4
  export declare function readBundleRegistries(): Promise<ApiResponse<BundleRegistriesPayload>>;
5
5
  export declare function readBundleInspection(spec: string, registry?: string): Promise<ApiResponse<BundleInspectionPayload>>;
6
- export declare function readModuleVersions(force?: boolean): Promise<ApiResponse<ModuleVersionsPayload>>;
7
- export declare function readInstalledPlugins(force?: boolean): Promise<ApiResponse<InstalledPluginsPayload>>;
6
+ export declare function readModuleVersions(force?: boolean, check?: boolean): Promise<ApiResponse<ModuleVersionsPayload>>;
7
+ export declare function readInstalledPlugins(force?: boolean, check?: boolean): Promise<ApiResponse<InstalledPluginsPayload>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-workbench/core",
3
- "version": "1.1.11",
3
+ "version": "1.1.12",
4
4
  "description": "个人工作台:Agent 工作台(左栏 + 常驻对话 + 自研右侧数据面板)。",
5
5
  "type": "module",
6
6
  "icon": "./icon.svg",
@@ -100,8 +100,8 @@
100
100
  "proper-lockfile": "^4.1.2",
101
101
  "which": "^7.0.0",
102
102
  "write-file-atomic": "^8.0.0",
103
- "@dsh-workbench/shared": "1.1.11",
104
- "@dsh-workbench/adapters-default": "1.1.11"
103
+ "@dsh-workbench/adapters-default": "1.1.12",
104
+ "@dsh-workbench/shared": "1.1.12"
105
105
  },
106
106
  "license": "MIT",
107
107
  "repository": {