@kosdev-code/kos-ui-sdk 3.0.17 → 3.0.19

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/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const log$R = require("loglevel");
3
+ const log$S = require("loglevel");
4
4
  const mobx = require("mobx");
5
5
  const robot3 = require("robot3");
6
6
  const dateFns = require("date-fns");
@@ -50,7 +50,7 @@ var KosWsEvents = /* @__PURE__ */ ((KosWsEvents2) => {
50
50
  return KosWsEvents2;
51
51
  })(KosWsEvents || {});
52
52
  const EVENT_KOS_MODEL_READY = "/kos/model/ready/";
53
- log$R.info("Initializing event bus");
53
+ log$S.info("Initializing event bus");
54
54
  globalThis.kos = globalThis.kos || {};
55
55
  globalThis.kos.subscriptions = globalThis.kos.subscriptions || {};
56
56
  const subscriptions = globalThis.kos.subscriptions;
@@ -61,15 +61,15 @@ function hasEventSubscriptions(eventType) {
61
61
  function subscribe(eventType, callback) {
62
62
  const id = getNextUniqueId();
63
63
  if (!subscriptions[eventType]) {
64
- log$R.debug(`Initializing subscription for ${eventType}`);
64
+ log$S.debug(`Initializing subscription for ${eventType}`);
65
65
  subscriptions[eventType] = {};
66
66
  }
67
- log$R.debug(`Subscribing to ${eventType} with id ${id.toString()}`);
67
+ log$S.debug(`Subscribing to ${eventType} with id ${id.toString()}`);
68
68
  subscriptions[eventType][id] = callback;
69
69
  return {
70
70
  count: subscriptions[eventType] ? Object.getOwnPropertySymbols(subscriptions[eventType]).length : 0,
71
71
  unsubscribe: () => {
72
- log$R.debug(`Unsubscribing from ${eventType} with id ${id.toString()}`);
72
+ log$S.debug(`Unsubscribing from ${eventType} with id ${id.toString()}`);
73
73
  if (subscriptions[eventType] && subscriptions[eventType][id]) {
74
74
  delete subscriptions[eventType][id];
75
75
  }
@@ -84,7 +84,7 @@ function subscribe(eventType, callback) {
84
84
  }
85
85
  function publish(eventType, msg, headers = {}) {
86
86
  if (!subscriptions[eventType] || Object.getOwnPropertySymbols(subscriptions[eventType]).length === 0) {
87
- log$R.debug(`No subscriptions for ${eventType}. Not publishing.`);
87
+ log$S.debug(`No subscriptions for ${eventType}. Not publishing.`);
88
88
  return {
89
89
  eventType,
90
90
  subscribers: 0
@@ -94,19 +94,19 @@ function publish(eventType, msg, headers = {}) {
94
94
  Object.getOwnPropertySymbols(subscriptions[eventType]).forEach((id) => {
95
95
  if (headers["sync"]) {
96
96
  const responseId = headers["sync"];
97
- log$R.debug(
97
+ log$S.debug(
98
98
  `Performing sync publish for ${eventType} with sync id ${responseId}`
99
99
  );
100
100
  subscriptions[eventType][id]({ body: msg, headers }).then(
101
101
  (response) => {
102
- log$R.debug(
102
+ log$S.debug(
103
103
  `Response recieved for ${responseId}, publishing back to source.`
104
104
  );
105
105
  publish(responseId, response);
106
106
  }
107
107
  );
108
108
  } else {
109
- log$R.debug(`Performing async publish for ${eventType}`);
109
+ log$S.debug(`Performing async publish for ${eventType}`);
110
110
  subscriptions[eventType][id]({ body: msg, headers });
111
111
  }
112
112
  });
@@ -116,7 +116,7 @@ function publish(eventType, msg, headers = {}) {
116
116
  };
117
117
  }
118
118
  function reset() {
119
- log$R.warn("Resetting event bus");
119
+ log$S.warn("Resetting event bus");
120
120
  Object.keys(subscriptions).forEach((key) => delete subscriptions[key]);
121
121
  }
122
122
  function once$1(eventType, callback) {
@@ -766,6 +766,17 @@ const defaultConfig = {
766
766
  };
767
767
  const config = globalThis.getKosConfig?.() || JSON.stringify(defaultConfig);
768
768
  const configObj = JSON.parse(config);
769
+ const urlProfiles = () => {
770
+ if (typeof window === "undefined") {
771
+ return [];
772
+ }
773
+ const value = getQueryParams()?.["kosProfiles"];
774
+ return value ? value.split(",").map((profile) => profile.trim()).filter(Boolean) : [];
775
+ };
776
+ configObj.profiles = [
777
+ ...configObj.profiles ?? [],
778
+ ...urlProfiles().filter((profile) => !configObj.profiles?.includes(profile))
779
+ ];
769
780
  globalThis.kosConfig = configObj;
770
781
  const KosGlobalConfig = configObj;
771
782
  const resolveKosProfiles = () => KosGlobalConfig.profiles || [];
@@ -795,10 +806,10 @@ const getLogMessageToStudio = () => {
795
806
  return enableAll;
796
807
  };
797
808
  const WS_LOG = "ws-log";
798
- const originalFactory = log$R.methodFactory;
809
+ const originalFactory = log$S.methodFactory;
799
810
  const enableMessageLogging = getKosMessageLogging();
800
811
  const enableStudioMessageLogging = getLogMessageToStudio();
801
- log$R.methodFactory = function(methodName, logLevel, loggerName) {
812
+ log$S.methodFactory = function(methodName, logLevel, loggerName) {
802
813
  const rawMethod = originalFactory(methodName, logLevel, loggerName);
803
814
  return function(...args) {
804
815
  const _name = loggerName ? String(loggerName) : "";
@@ -813,17 +824,17 @@ log$R.methodFactory = function(methodName, logLevel, loggerName) {
813
824
  };
814
825
  };
815
826
  let level = getLogLevel();
816
- log$R.setLevel(level);
827
+ log$S.setLevel(level);
817
828
  window.setKosLogLevel = (_level) => {
818
829
  level = _level;
819
- log$R.setLevel(_level);
830
+ log$S.setLevel(_level);
820
831
  };
821
- const wsLog = log$R.getLogger(WS_LOG);
832
+ const wsLog = log$S.getLogger(WS_LOG);
822
833
  window.enableKosMessageLog = () => {
823
- wsLog.setLevel(log$R.levels.INFO);
834
+ wsLog.setLevel(log$S.levels.INFO);
824
835
  };
825
836
  window.disableKosMessageLog = () => {
826
- wsLog.setLevel(log$R.levels.ERROR);
837
+ wsLog.setLevel(log$S.levels.ERROR);
827
838
  };
828
839
  if (enableMessageLogging) {
829
840
  window.enableKosMessageLog();
@@ -851,21 +862,21 @@ const received = [
851
862
  "font-weight: bold"
852
863
  ].join(";");
853
864
  const conditionallyLog = (level2) => (fn) => {
854
- if (log$R.getLevel() <= level2) {
865
+ if (log$S.getLevel() <= level2) {
855
866
  fn();
856
867
  }
857
868
  };
858
869
  const KosLog = {
859
- ...log$R,
860
- ifDebug: conditionallyLog(log$R.levels.DEBUG),
861
- ifInfo: conditionallyLog(log$R.levels.INFO),
862
- ifWarn: conditionallyLog(log$R.levels.WARN),
863
- ifError: conditionallyLog(log$R.levels.ERROR),
864
- getLogger: (name) => log$R.getLogger(`kos::${name}`),
865
- getLoggers: () => log$R.getLoggers(),
870
+ ...log$S,
871
+ ifDebug: conditionallyLog(log$S.levels.DEBUG),
872
+ ifInfo: conditionallyLog(log$S.levels.INFO),
873
+ ifWarn: conditionallyLog(log$S.levels.WARN),
874
+ ifError: conditionallyLog(log$S.levels.ERROR),
875
+ getLogger: (name) => log$S.getLogger(`kos::${name}`),
876
+ getLoggers: () => log$S.getLoggers(),
866
877
  createLogger: ({ name, group }) => {
867
878
  const loggerName = `${group ? `${group}:` : "kos"}::${name}`;
868
- const _log = log$R.getLogger(loggerName);
879
+ const _log = log$S.getLogger(loggerName);
869
880
  let _level = globalThis.kos.logOverrides?.find(
870
881
  (override) => override.name === loggerName
871
882
  )?.level;
@@ -916,7 +927,7 @@ const OptionsRequired = /* @__PURE__ */ Symbol(`OptionsRequired`);
916
927
  const KosViewModelSymbol = /* @__PURE__ */ Symbol(`KosViewModelSymbol`);
917
928
  const ViewModelConfig = /* @__PURE__ */ Symbol(`ViewModelConfig`);
918
929
  const ReloadAwareSetup = /* @__PURE__ */ Symbol(`ReloadAwareSetup`);
919
- const log$Q = KosLog.createLogger({ group: "decorators", name: "fsm-injection" });
930
+ const log$R = KosLog.createLogger({ group: "decorators", name: "fsm-injection" });
920
931
  function injectStateMachineSupport(modelInstance) {
921
932
  const fsmSetup = modelInstance[StateMachineSetup];
922
933
  if (!fsmSetup) return;
@@ -960,7 +971,7 @@ function initializeFsmProperties(modelInstance, options) {
960
971
  const config2 = modelInstance._fsmConfig;
961
972
  const initialState = computeInitialState ? computeInitialState(modelInstance) : config2.initial;
962
973
  if (computeInitialState && !config2.states[initialState]) {
963
- log$Q.warn(
974
+ log$R.warn(
964
975
  `computeInitialState returned "${initialState}" which is not a valid state. Falling back to "${config2.initial}".`
965
976
  );
966
977
  modelInstance[stateProperty] = config2.initial;
@@ -1090,7 +1101,7 @@ function handleAsyncEntryResult(instance, state, stateProperty, result) {
1090
1101
  if (stateConfig.onError && instance[stateProperty] === state) {
1091
1102
  instance.transition(stateConfig.onError);
1092
1103
  } else {
1093
- log$Q.error(`Async entry handler for state "${state}" failed:`, err);
1104
+ log$R.error(`Async entry handler for state "${state}" failed:`, err);
1094
1105
  }
1095
1106
  }
1096
1107
  );
@@ -1131,7 +1142,7 @@ function initializeStateMachine(modelInstance, lifecycle) {
1131
1142
  modelInstance._fsmInitialized = true;
1132
1143
  trackInitialStateInHistory(modelInstance, config2.initial, options);
1133
1144
  executeInitialStateEntryHandler(modelInstance, config2.initial);
1134
- log$Q.debug(
1145
+ log$R.debug(
1135
1146
  `FSM initialized for model ${modelInstance.id} at lifecycle ${lifecycle} with initial state "${config2.initial}"`
1136
1147
  );
1137
1148
  }
@@ -1389,7 +1400,7 @@ class ServiceRequestError extends Error {
1389
1400
  this.responseHeaders = details.responseHeaders ?? {};
1390
1401
  }
1391
1402
  }
1392
- const log$P = KosLog.createLogger({ name: "resolve-parameters" });
1403
+ const log$Q = KosLog.createLogger({ name: "resolve-parameters" });
1393
1404
  const resolveParameters = ({
1394
1405
  value,
1395
1406
  modelId,
@@ -1421,11 +1432,11 @@ const resolveParameters = ({
1421
1432
  )) {
1422
1433
  const prop = modelData[propName];
1423
1434
  if (prop !== null && prop !== void 0) {
1424
- log$P.debug(`Resolved ${match} to ${prop}`);
1435
+ log$Q.debug(`Resolved ${match} to ${prop}`);
1425
1436
  return prop;
1426
1437
  } else {
1427
1438
  const logLevel2 = isOnlyPropKey ? "debug" : "warn";
1428
- log$P[logLevel2](
1439
+ log$Q[logLevel2](
1429
1440
  `Property ${propName} is null or undefined${isOnlyPropKey ? "" : " in composite string"}, marking for undefined return`
1430
1441
  );
1431
1442
  hasUnresolvedProp = true;
@@ -1433,7 +1444,7 @@ const resolveParameters = ({
1433
1444
  }
1434
1445
  }
1435
1446
  const logLevel = isOnlyPropKey ? "debug" : "warn";
1436
- log$P[logLevel](
1447
+ log$Q[logLevel](
1437
1448
  `Property ${propName} not found in modelData${isOnlyPropKey ? "" : " for composite string"}`
1438
1449
  );
1439
1450
  return match;
@@ -1448,7 +1459,7 @@ const resolveParameters = ({
1448
1459
  }
1449
1460
  return _value;
1450
1461
  };
1451
- const log$O = KosLog.createLogger({ name: "ServiceRequestHelpers" });
1462
+ const log$P = KosLog.createLogger({ name: "ServiceRequestHelpers" });
1452
1463
  function resolveServiceRequestParameters(metadata, modelInstance, args, runtimeOptions) {
1453
1464
  const resolvedPath = resolveParameters({
1454
1465
  value: metadata.path,
@@ -1517,7 +1528,7 @@ function handleServiceRequestError(error, response, errorHandler, modelInstance,
1517
1528
  });
1518
1529
  switch (errorHandler.strategy) {
1519
1530
  case "log":
1520
- log$O.error(`Service request status ${richError.status} error: ${error}`);
1531
+ log$P.error(`Service request status ${richError.status} error: ${error}`);
1521
1532
  if (errorHandler.onError) {
1522
1533
  errorHandler.onError(richError, modelInstance);
1523
1534
  }
@@ -1640,7 +1651,7 @@ var ReplayStrategy = /* @__PURE__ */ ((ReplayStrategy2) => {
1640
1651
  ReplayStrategy2["NONE"] = "none";
1641
1652
  return ReplayStrategy2;
1642
1653
  })(ReplayStrategy || {});
1643
- const log$N = KosLog.createLogger({ name: "kos-state-machine" });
1654
+ const log$O = KosLog.createLogger({ name: "kos-state-machine" });
1644
1655
  function kosStateMachine(config2, options) {
1645
1656
  return (target) => {
1646
1657
  target.prototype[StateMachineSetup] = {
@@ -1695,7 +1706,7 @@ function kosStateGuard(options) {
1695
1706
  if (shouldThrow) {
1696
1707
  throw new Error(message2);
1697
1708
  } else {
1698
- log$N.warn(message2);
1709
+ log$O.warn(message2);
1699
1710
  return void 0;
1700
1711
  }
1701
1712
  }
@@ -2261,7 +2272,7 @@ function observeComputedProperties(model, callback, keys = []) {
2261
2272
  );
2262
2273
  return disposers;
2263
2274
  }
2264
- const log$M = KosLog.createLogger({ name: "kos-container-model" });
2275
+ const log$N = KosLog.createLogger({ name: "kos-container-model" });
2265
2276
  class KosModelContainer {
2266
2277
  _data;
2267
2278
  _sortKey;
@@ -2383,14 +2394,14 @@ class KosModelContainer {
2383
2394
  async removeAndDestroy(id) {
2384
2395
  const model = this.getModel(id);
2385
2396
  if (!model) {
2386
- log$M.debug(`Model ${id} not found in container, skipping destroy`);
2397
+ log$N.debug(`Model ${id} not found in container, skipping destroy`);
2387
2398
  return;
2388
2399
  }
2389
2400
  this.removeModel(id);
2390
2401
  try {
2391
2402
  await destroyKosModel(model);
2392
2403
  } catch (error) {
2393
- log$M.error(`Failed to destroy model ${id}:`, error);
2404
+ log$N.error(`Failed to destroy model ${id}:`, error);
2394
2405
  throw error;
2395
2406
  }
2396
2407
  }
@@ -2407,7 +2418,7 @@ class KosModelContainer {
2407
2418
  async removeAndDestroyAll(ids) {
2408
2419
  const models2 = ids.map((id) => this.getModel(id)).filter((model) => model !== void 0);
2409
2420
  if (models2.length === 0) {
2410
- log$M.debug("No models found to destroy");
2421
+ log$N.debug("No models found to destroy");
2411
2422
  return;
2412
2423
  }
2413
2424
  this.removeAll(ids);
@@ -2416,7 +2427,7 @@ class KosModelContainer {
2416
2427
  );
2417
2428
  results.forEach((result, index2) => {
2418
2429
  if (result.status === "rejected") {
2419
- log$M.error(
2430
+ log$N.error(
2420
2431
  `Failed to destroy model ${models2[index2].id}:`,
2421
2432
  result.reason
2422
2433
  );
@@ -2589,7 +2600,7 @@ class KosModelContainer {
2589
2600
  const idx = this.index.get(indexName);
2590
2601
  return idx.keys ?? [];
2591
2602
  } else {
2592
- log$M.info(
2603
+ log$N.info(
2593
2604
  `index ${indexName} not found in ${Array.from(this.index.keys())}`
2594
2605
  );
2595
2606
  return [];
@@ -2601,7 +2612,7 @@ class KosModelContainer {
2601
2612
  if (idx.index.has(indexKey)) {
2602
2613
  return idx.getByKey(indexKey);
2603
2614
  } else {
2604
- log$M.info(
2615
+ log$N.info(
2605
2616
  `key ${indexKey} not found in ${indexName} index: ${Array.from(
2606
2617
  idx.index.keys()
2607
2618
  )}`
@@ -2609,7 +2620,7 @@ class KosModelContainer {
2609
2620
  return [];
2610
2621
  }
2611
2622
  } else {
2612
- log$M.info(
2623
+ log$N.info(
2613
2624
  `index ${indexName} not found in ${Array.from(this.index.keys())}`
2614
2625
  );
2615
2626
  return [];
@@ -2636,7 +2647,7 @@ class KosModelContainer {
2636
2647
  * @private
2637
2648
  */
2638
2649
  _logCapacityWarning(toEvict) {
2639
- log$M.info(
2650
+ log$N.info(
2640
2651
  `Container capacity exceeded (${this._data.size}/${this._maxCapacity}). Evicting ${toEvict} models using ${this._evictionStrategy} strategy.`,
2641
2652
  { parentId: this._parentId }
2642
2653
  );
@@ -2699,7 +2710,7 @@ class KosModelContainer {
2699
2710
  const candidates = this._customEvictionFilter(this.data);
2700
2711
  return candidates.slice(0, count);
2701
2712
  }
2702
- log$M.error(
2713
+ log$N.error(
2703
2714
  "Custom eviction strategy specified but no customEvictionFilter provided. Falling back to FIFO.",
2704
2715
  { parentId: this._parentId }
2705
2716
  );
@@ -2711,7 +2722,7 @@ class KosModelContainer {
2711
2722
  */
2712
2723
  async _removeEvictedModels(models2) {
2713
2724
  for (const model of models2) {
2714
- log$M.info(
2725
+ log$N.info(
2715
2726
  `Evicting model: ${model.id} (type: ${model.constructor.name})`,
2716
2727
  {
2717
2728
  modelId: model.id,
@@ -2721,7 +2732,7 @@ class KosModelContainer {
2721
2732
  );
2722
2733
  this.removeModel(model.id, true);
2723
2734
  destroyKosModel(model).catch(
2724
- (e) => log$M.error(`Failed to destroy evicted model ${model.id}:`, e)
2735
+ (e) => log$N.error(`Failed to destroy evicted model ${model.id}:`, e)
2725
2736
  );
2726
2737
  }
2727
2738
  }
@@ -2730,7 +2741,7 @@ class KosModelContainer {
2730
2741
  * @private
2731
2742
  */
2732
2743
  _logEvictionComplete(evictedCount) {
2733
- log$M.info(
2744
+ log$N.info(
2734
2745
  `Evicted ${evictedCount} models. Current size: ${this._data.size}/${this._maxCapacity}`,
2735
2746
  { parentId: this._parentId }
2736
2747
  );
@@ -2739,9 +2750,9 @@ class KosModelContainer {
2739
2750
  this._data.forEach((model) => {
2740
2751
  const modelId = model.id;
2741
2752
  destroyKosModel(model).then(() => {
2742
- log$M.debug(`${modelId} destroyed, removing from map`);
2753
+ log$N.debug(`${modelId} destroyed, removing from map`);
2743
2754
  this.removeModel(modelId, true);
2744
- }).catch((e) => log$M.error(e));
2755
+ }).catch((e) => log$N.error(e));
2745
2756
  });
2746
2757
  this.increment();
2747
2758
  }
@@ -2956,7 +2967,7 @@ const getKosModelActivationState = (model) => {
2956
2967
  }
2957
2968
  };
2958
2969
  };
2959
- const log$L = KosLog.createLogger({ name: "kos-model-factory" });
2970
+ const log$M = KosLog.createLogger({ name: "kos-model-factory" });
2960
2971
  const KosModelFactory = {
2961
2972
  byModelType: (modelType) => KosCore.getInstance().modelManager.getModelFactory(
2962
2973
  modelType
@@ -2964,7 +2975,7 @@ const KosModelFactory = {
2964
2975
  getModelInstance: (id, modelType, options) => {
2965
2976
  const factory = KosModelFactory.byModelType(modelType);
2966
2977
  if (!factory) {
2967
- log$L.error(
2978
+ log$M.error(
2968
2979
  `No registered factory found for model type ${modelType}. Please register a factory for this model type. `
2969
2980
  );
2970
2981
  throw Error(`No factory found for model type ${modelType}`);
@@ -3275,7 +3286,7 @@ class SingletonKosModelRegistrationFactory extends KosBaseModelRegistration {
3275
3286
  };
3276
3287
  }
3277
3288
  }
3278
- const log$K = KosLog.createLogger({ group: "decorators", name: "kos-model" });
3289
+ const log$L = KosLog.createLogger({ group: "decorators", name: "kos-model" });
3279
3290
  function resolveParentContext(TargetClass, modelId, modelData) {
3280
3291
  const parentIdRaw = TargetClass[ParentModel]?.parentId;
3281
3292
  if (!parentIdRaw) return;
@@ -3579,7 +3590,7 @@ function injectCompanionSupport(modelInstance, initialData) {
3579
3590
  const { mode, parentProperty, excludeProperties } = companionConfig;
3580
3591
  const parentModel = initialData.companionParent;
3581
3592
  if (!parentModel) {
3582
- log$K.warn(
3593
+ log$L.warn(
3583
3594
  `Companion decorator configured but no parent model found in initialData.companionParent`
3584
3595
  );
3585
3596
  return;
@@ -3653,7 +3664,7 @@ function injectCompanionSupport(modelInstance, initialData) {
3653
3664
  });
3654
3665
  }
3655
3666
  } catch (error) {
3656
- log$K.debug(
3667
+ log$L.debug(
3657
3668
  `Skipping companion proxy for property ${propertyName}:`,
3658
3669
  error
3659
3670
  );
@@ -3681,7 +3692,7 @@ function makeSafeObservable$1(instance) {
3681
3692
  try {
3682
3693
  return mobx.makeAutoObservable(instance);
3683
3694
  } catch (e) {
3684
- log$K.error("Failed to make observable:", e);
3695
+ log$L.error("Failed to make observable:", e);
3685
3696
  return instance;
3686
3697
  }
3687
3698
  }
@@ -4165,7 +4176,7 @@ const KosDeletionManager = {
4165
4176
  }
4166
4177
  }
4167
4178
  };
4168
- const log$J = KosLog.createLogger({ name: "kos-dependency-manager" });
4179
+ const log$K = KosLog.createLogger({ name: "kos-dependency-manager" });
4169
4180
  class KosDependencyManager {
4170
4181
  _usedByCache = /* @__PURE__ */ new Map();
4171
4182
  _usesCache = /* @__PURE__ */ new Map();
@@ -4190,10 +4201,37 @@ class KosDependencyManager {
4190
4201
  uses.filter((id) => id !== dependencyId)
4191
4202
  );
4192
4203
  }
4204
+ /**
4205
+ * Drops every edge into and out of a model. Called when the model is
4206
+ * destroyed, so its dependencies are not left pinned by a model that is
4207
+ * gone and can never release them.
4208
+ */
4209
+ removeAll(modelId) {
4210
+ for (const dependencyId of this._usesCache.get(modelId) ?? []) {
4211
+ const usedBy = this._usedByCache.get(dependencyId);
4212
+ if (usedBy) {
4213
+ this._usedByCache.set(
4214
+ dependencyId,
4215
+ usedBy.filter((id) => id !== modelId)
4216
+ );
4217
+ }
4218
+ }
4219
+ this._usesCache.delete(modelId);
4220
+ for (const dependentId of this._usedByCache.get(modelId) ?? []) {
4221
+ const uses = this._usesCache.get(dependentId);
4222
+ if (uses) {
4223
+ this._usesCache.set(
4224
+ dependentId,
4225
+ uses.filter((id) => id !== modelId)
4226
+ );
4227
+ }
4228
+ }
4229
+ this._usedByCache.delete(modelId);
4230
+ }
4193
4231
  canDestroy(modelId) {
4194
4232
  const usedBy = this._usedByCache.get(modelId);
4195
4233
  if (usedBy?.length) {
4196
- log$J.info(`Model ${modelId} is still used by: ${usedBy.join(", ")}`);
4234
+ log$K.info(`Model ${modelId} is still used by: ${usedBy.join(", ")}`);
4197
4235
  return false;
4198
4236
  }
4199
4237
  return true;
@@ -4203,7 +4241,7 @@ class KosDependencyManager {
4203
4241
  this._usesCache.clear();
4204
4242
  }
4205
4243
  }
4206
- const log$I = KosLog.createLogger({ name: "kos-model-cache" });
4244
+ const log$J = KosLog.createLogger({ name: "kos-model-cache" });
4207
4245
  class KosModelCache {
4208
4246
  constructor(preloadKeys = []) {
4209
4247
  this.preloadKeys = preloadKeys;
@@ -4254,11 +4292,11 @@ class KosModelCache {
4254
4292
  }
4255
4293
  preload(createFn) {
4256
4294
  if (this._isPreloaded) {
4257
- log$I.debug("Returning cached preloaded models");
4295
+ log$J.debug("Returning cached preloaded models");
4258
4296
  return this._preloaded;
4259
4297
  }
4260
4298
  this._preloaded = this.preloadKeys.map((key) => {
4261
- log$I.debug(
4299
+ log$J.debug(
4262
4300
  `Preloading model: ${typeof key === "string" ? key : key.modelType}`
4263
4301
  );
4264
4302
  return createFn(key);
@@ -4267,6 +4305,19 @@ class KosModelCache {
4267
4305
  return this._preloaded;
4268
4306
  }
4269
4307
  }
4308
+ const cache$1 = /* @__PURE__ */ new Map();
4309
+ const modelHookCache = {
4310
+ has: (key) => cache$1.has(key),
4311
+ get: (key) => cache$1.get(key),
4312
+ set: (key, entry) => cache$1.set(key, entry),
4313
+ delete: (key) => cache$1.delete(key),
4314
+ clear: () => cache$1.clear()
4315
+ };
4316
+ const clearModelHookCacheEntry = (modelId) => {
4317
+ if (modelId) {
4318
+ cache$1.delete(modelId);
4319
+ }
4320
+ };
4270
4321
  class KosModelError extends Error {
4271
4322
  context;
4272
4323
  originalCause;
@@ -4347,7 +4398,7 @@ function logModelInstantiationError(error, context) {
4347
4398
  });
4348
4399
  }
4349
4400
  const isKosCompanionTypeFactory = (obj) => typeof obj === "function";
4350
- const log$H = KosLog.createLogger({ name: "kos-companion-instantiator" });
4401
+ const log$I = KosLog.createLogger({ name: "kos-companion-instantiator" });
4351
4402
  class KosCompanionInstantiator {
4352
4403
  constructor(registry, cache2, createModel) {
4353
4404
  this.registry = registry;
@@ -4369,7 +4420,7 @@ class KosCompanionInstantiator {
4369
4420
  createCompanionModels(model, options, lifecycle) {
4370
4421
  const companionDefs = this.getCompanionDefinitions(model.modelTypeName);
4371
4422
  if (lifecycle !== void 0) {
4372
- log$H.debug(
4423
+ log$I.debug(
4373
4424
  `Creating ${lifecycle} lifecycle companions for ${model.modelTypeName} [${model.modelId}]`
4374
4425
  );
4375
4426
  }
@@ -4412,7 +4463,7 @@ class KosCompanionInstantiator {
4412
4463
  resolveFactoryCompanion(companionDef, model, options, requestedLifecycle) {
4413
4464
  const companionType = companionDef.type(model.modelData, options);
4414
4465
  if (!companionType) {
4415
- log$H.debug(
4466
+ log$I.debug(
4416
4467
  `Companion factory returned undefined for ${model.modelTypeName} at ${requestedLifecycle || "INIT"} phase`
4417
4468
  );
4418
4469
  return null;
@@ -4471,7 +4522,7 @@ class KosCompanionInstantiator {
4471
4522
  );
4472
4523
  if (companion) {
4473
4524
  this.attachCompanionToParent(companion, parentModel);
4474
- log$H.debug(
4525
+ log$I.debug(
4475
4526
  `Created ${lifecycle || "INIT"} companion ${companionType} for ${parentModel.modelTypeName} [${parentModel.modelId}]`
4476
4527
  );
4477
4528
  }
@@ -4487,7 +4538,7 @@ class KosCompanionInstantiator {
4487
4538
  */
4488
4539
  companionAlreadyExists(companionId, companionType, parentTypeName) {
4489
4540
  if (this.cache.hasModel(companionId)) {
4490
- log$H.debug(
4541
+ log$I.debug(
4491
4542
  `Companion ${companionType} already exists for ${parentTypeName}`
4492
4543
  );
4493
4544
  return true;
@@ -5183,7 +5234,7 @@ class KosEffectManager {
5183
5234
  this.disposers = [];
5184
5235
  }
5185
5236
  }
5186
- const log$G = KosLog.createLogger({ name: "model-active-machine" });
5237
+ const log$H = KosLog.createLogger({ name: "model-active-machine" });
5187
5238
  const activeMachine = (model) => {
5188
5239
  const machine2 = robot3.createMachine(KosModelState.INACTIVE, {
5189
5240
  [KosModelState.FAILED]: robot3.state(
@@ -5238,11 +5289,11 @@ const activeMachine = (model) => {
5238
5289
  });
5239
5290
  const service2 = robot3.interpret(
5240
5291
  machine2,
5241
- (_service) => log$G.debug(_service.machine.current)
5292
+ (_service) => log$H.debug(_service.machine.current)
5242
5293
  );
5243
5294
  return { service: service2, machine: machine2 };
5244
5295
  };
5245
- const log$F = KosLog.createLogger({ name: "model-online-machine" });
5296
+ const log$G = KosLog.createLogger({ name: "model-online-machine" });
5246
5297
  const onlineMachine = (model) => {
5247
5298
  const machine2 = robot3.createMachine(KosModelState.OFFLINE, {
5248
5299
  [KosModelState.ONLINE]: robot3.state(
@@ -5260,7 +5311,7 @@ const onlineMachine = (model) => {
5260
5311
  KosModelEvents.GO_ONLINE,
5261
5312
  KosModelState.ONLINE,
5262
5313
  robot3.action(async () => {
5263
- log$F.debug(`Going online with model ${model.modelId}`);
5314
+ log$G.debug(`Going online with model ${model.modelId}`);
5264
5315
  await model.online();
5265
5316
  model.onlineStatus = KosModelState.ONLINE;
5266
5317
  await model.fsm.transitionTo(
@@ -5273,7 +5324,7 @@ const onlineMachine = (model) => {
5273
5324
  });
5274
5325
  const service2 = robot3.interpret(
5275
5326
  machine2,
5276
- (_service) => log$F.debug(_service.machine.current)
5327
+ (_service) => log$G.debug(_service.machine.current)
5277
5328
  );
5278
5329
  return { machine: machine2, service: service2 };
5279
5330
  };
@@ -5418,11 +5469,11 @@ const machine = (model) => {
5418
5469
  [KosModelState.FAILED]: robot3.state()
5419
5470
  });
5420
5471
  };
5421
- const log$E = KosLog.createLogger({ name: "kos-model-lifecycle" });
5472
+ const log$F = KosLog.createLogger({ name: "kos-model-lifecycle" });
5422
5473
  const fsm = (model) => {
5423
5474
  const service2 = robot3.interpret(
5424
5475
  machine(model),
5425
- (_service) => log$E.debug(
5476
+ (_service) => log$F.debug(
5426
5477
  `state machine for model ${model.modelId}: ${_service.machine.current});`
5427
5478
  )
5428
5479
  );
@@ -6402,7 +6453,7 @@ class TransportNotReadyError extends Error {
6402
6453
  }
6403
6454
  }
6404
6455
  const isTransportNotReadyError = (error) => !!error && error.code === TRANSPORT_NOT_READY;
6405
- const log$D = KosLog.createLogger({ name: "kos-fetch" });
6456
+ const log$E = KosLog.createLogger({ name: "kos-fetch" });
6406
6457
  const DEFAULT_WS_TIMEOUT = 3e4;
6407
6458
  const WS_TIMEOUT = (() => {
6408
6459
  const configured = process.env.KOS_WS_TIMEOUT ? parseInt(process.env.KOS_WS_TIMEOUT) : DEFAULT_WS_TIMEOUT;
@@ -6467,7 +6518,7 @@ const kosFetchWs = async (url, options) => {
6467
6518
  const requestId = uuid();
6468
6519
  const urlObj = new URL(url);
6469
6520
  const path = `${urlObj.pathname}${urlObj.search}`;
6470
- log$D.debug(`path: ${path}`);
6521
+ log$E.debug(`path: ${path}`);
6471
6522
  const budget = resolveTimeoutBudget(options?.timeout);
6472
6523
  const messageFactory = fetchMessageFactory(options);
6473
6524
  const signal = createRequestSignal(budget, options?.signal);
@@ -6475,12 +6526,12 @@ const kosFetchWs = async (url, options) => {
6475
6526
  await transport.whenReady({ signal });
6476
6527
  } catch (error) {
6477
6528
  if (isTimeoutReason(error)) {
6478
- log$D.error(
6529
+ log$E.error(
6479
6530
  `Transport not ready${budget === void 0 ? "" : ` after ${budget}ms`} - request not sent - url: ${url}`
6480
6531
  );
6481
6532
  throw new TransportNotReadyError({ timeout: budget, url });
6482
6533
  }
6483
- log$D.debug(`Request aborted while waiting for transport - url: ${url}`);
6534
+ log$E.debug(`Request aborted while waiting for transport - url: ${url}`);
6484
6535
  throw error;
6485
6536
  }
6486
6537
  const processedBody = await processRequestBody(options?.body);
@@ -6509,9 +6560,9 @@ const kosFetchWs = async (url, options) => {
6509
6560
  if (signal.aborted) {
6510
6561
  const reason = signal.reason;
6511
6562
  if (reason?.name === "TimeoutError") {
6512
- log$D.error(`Timeout occurred - url: ${url}`);
6563
+ log$E.error(`Timeout occurred - url: ${url}`);
6513
6564
  } else {
6514
- log$D.debug(`Request aborted - url: ${url}`);
6565
+ log$E.debug(`Request aborted - url: ${url}`);
6515
6566
  }
6516
6567
  reject(reason || new DOMException("Aborted", "AbortError"));
6517
6568
  return;
@@ -6520,9 +6571,9 @@ const kosFetchWs = async (url, options) => {
6520
6571
  if (unsubscribe) unsubscribe();
6521
6572
  const reason = signal.reason;
6522
6573
  if (reason?.name === "TimeoutError") {
6523
- log$D.error(`Timeout occurred - url: ${url}`);
6574
+ log$E.error(`Timeout occurred - url: ${url}`);
6524
6575
  } else {
6525
- log$D.debug(`Request aborted - url: ${url}`);
6576
+ log$E.debug(`Request aborted - url: ${url}`);
6526
6577
  }
6527
6578
  reject(reason || new DOMException("Aborted", "AbortError"));
6528
6579
  };
@@ -6538,7 +6589,7 @@ const kosFetchWs = async (url, options) => {
6538
6589
  try {
6539
6590
  bodyData = base64ToArrayBuffer(responseBody);
6540
6591
  } catch (e) {
6541
- log$D.error("Failed to decode base64 response", e);
6592
+ log$E.error("Failed to decode base64 response", e);
6542
6593
  }
6543
6594
  }
6544
6595
  const response = {
@@ -6592,7 +6643,7 @@ const kosFetchWs = async (url, options) => {
6592
6643
  });
6593
6644
  }
6594
6645
  if (parsed.files) {
6595
- log$D.warn(
6646
+ log$E.warn(
6596
6647
  "File reconstruction in FormData not fully implemented"
6597
6648
  );
6598
6649
  }
@@ -6643,7 +6694,7 @@ const resolveBaseUrl = () => {
6643
6694
  const URL2 = exports.BASE_URL;
6644
6695
  return { isMock: MOCK, URL: URL2 };
6645
6696
  };
6646
- const log$C = KosLog.createLogger({ name: "kos-service-request" });
6697
+ const log$D = KosLog.createLogger({ name: "kos-service-request" });
6647
6698
  const ERROR_UNKNOWN = "errUnknown";
6648
6699
  const ERROR_TRANSPORT_NOT_READY = "Transport not ready";
6649
6700
  const MUTATING_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "DELETE", "PATCH"]);
@@ -6669,7 +6720,7 @@ async function clientRequest(endpoint, method, options, params2, body) {
6669
6720
  )}`
6670
6721
  ).join("&") : "";
6671
6722
  const fullUrl = `${resolveBaseUrl().URL}${url}${query ? `?${query}` : ""}`;
6672
- log$C.debug(`fullUrl: ${fullUrl}`);
6723
+ log$D.debug(`fullUrl: ${fullUrl}`);
6673
6724
  const fetchOptions = {
6674
6725
  method: String(method).toUpperCase(),
6675
6726
  body: null,
@@ -6696,20 +6747,20 @@ async function executeFetch(fullUrl, fetchOptions) {
6696
6747
  return [null, payload.data ?? payload];
6697
6748
  } catch (error) {
6698
6749
  if (isTransportNotReadyError(error)) {
6699
- log$C.error(`Transport not ready, request not sent: ${fullUrl}`);
6750
+ log$D.error(`Transport not ready, request not sent: ${fullUrl}`);
6700
6751
  return [ERROR_TRANSPORT_NOT_READY, null];
6701
6752
  }
6702
6753
  if (error instanceof DOMException) {
6703
6754
  if (error.name === "TimeoutError") {
6704
- log$C.error(`Request timed out: ${fullUrl}`);
6755
+ log$D.error(`Request timed out: ${fullUrl}`);
6705
6756
  return ["Request timed out", null];
6706
6757
  }
6707
6758
  if (error.name === "AbortError") {
6708
- log$C.debug(`Request aborted: ${fullUrl}`);
6759
+ log$D.debug(`Request aborted: ${fullUrl}`);
6709
6760
  return ["Request aborted", null];
6710
6761
  }
6711
6762
  }
6712
- log$C.error(`Unexpected error during fetch: ${error}`);
6763
+ log$D.error(`Unexpected error during fetch: ${error}`);
6713
6764
  return [error instanceof Error ? error.message : ERROR_UNKNOWN, null];
6714
6765
  }
6715
6766
  }
@@ -6729,38 +6780,38 @@ async function executeFetchWithRetry(fullUrl, fetchOptions, config2) {
6729
6780
  errorContext
6730
6781
  ];
6731
6782
  if (config2.retryOn && !config2.retryOn(response)) {
6732
- log$C.debug(
6783
+ log$D.debug(
6733
6784
  `Retry predicate returned false for ${fullUrl} (status ${response.status}), stopping`
6734
6785
  );
6735
6786
  return lastResult;
6736
6787
  }
6737
6788
  if (attempt < config2.maxAttempts) {
6738
6789
  const delayMs = config2.baseDelayMs * Math.pow(config2.backoffFactor, attempt - 1);
6739
- log$C.warn(
6790
+ log$D.warn(
6740
6791
  `Request to ${fullUrl} failed (status ${response.status}), retrying in ${delayMs}ms (attempt ${attempt}/${config2.maxAttempts})`
6741
6792
  );
6742
6793
  await new Promise((resolve) => setTimeout(resolve, delayMs));
6743
6794
  }
6744
6795
  } catch (error) {
6745
6796
  if (isTransportNotReadyError(error)) {
6746
- log$C.error(`Transport not ready, request not sent: ${fullUrl}`);
6797
+ log$D.error(`Transport not ready, request not sent: ${fullUrl}`);
6747
6798
  return [ERROR_TRANSPORT_NOT_READY, null];
6748
6799
  }
6749
6800
  if (error instanceof DOMException) {
6750
6801
  if (error.name === "TimeoutError") {
6751
- log$C.error(`Request timed out: ${fullUrl}`);
6802
+ log$D.error(`Request timed out: ${fullUrl}`);
6752
6803
  return ["Request timed out", null];
6753
6804
  }
6754
6805
  if (error.name === "AbortError") {
6755
- log$C.debug(`Request aborted: ${fullUrl}`);
6806
+ log$D.debug(`Request aborted: ${fullUrl}`);
6756
6807
  return ["Request aborted", null];
6757
6808
  }
6758
6809
  }
6759
- log$C.error(`Unexpected error during fetch: ${error}`);
6810
+ log$D.error(`Unexpected error during fetch: ${error}`);
6760
6811
  return [error instanceof Error ? error.message : ERROR_UNKNOWN, null];
6761
6812
  }
6762
6813
  }
6763
- log$C.error(`All ${config2.maxAttempts} attempts failed for ${fullUrl}`);
6814
+ log$D.error(`All ${config2.maxAttempts} attempts failed for ${fullUrl}`);
6764
6815
  return lastResult;
6765
6816
  }
6766
6817
  async function captureErrorResponseContext(response) {
@@ -6809,7 +6860,7 @@ const service$8 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePro
6809
6860
  default: api$9,
6810
6861
  kosServiceRequest: kosServiceRequest$8
6811
6862
  }, Symbol.toStringTag, { value: "Module" }));
6812
- const log$B = KosLog.createLogger({
6863
+ const log$C = KosLog.createLogger({
6813
6864
  name: "kos-service-request-manager",
6814
6865
  group: "Model"
6815
6866
  });
@@ -6862,7 +6913,7 @@ function isValueMissing(value) {
6862
6913
  }
6863
6914
  function validateRequiredField(value, fieldName, path, isRequired) {
6864
6915
  if (isRequired && isValueMissing(value)) {
6865
- log$B.warn(
6916
+ log$C.warn(
6866
6917
  `Required field '${fieldName}' is missing in response for ${path}`
6867
6918
  );
6868
6919
  }
@@ -6894,7 +6945,7 @@ class ServiceRequestManager {
6894
6945
  this.handlers.get(lifecycle).push(metadata);
6895
6946
  });
6896
6947
  if (Object.keys(handlerMetadata).length > 0) {
6897
- log$B.debug(
6948
+ log$C.debug(
6898
6949
  `Discovered ${Object.keys(handlerMetadata).length} service request handlers for model ${this.model.id}`
6899
6950
  );
6900
6951
  }
@@ -6909,7 +6960,7 @@ class ServiceRequestManager {
6909
6960
  if (!handlers || handlers.length === 0) {
6910
6961
  return;
6911
6962
  }
6912
- log$B.debug(
6963
+ log$C.debug(
6913
6964
  `Executing ${handlers.length} service requests for lifecycle ${lifecycle}`
6914
6965
  );
6915
6966
  await Promise.all(handlers.map((handler) => this.executeHandler(handler)));
@@ -6934,7 +6985,7 @@ class ServiceRequestManager {
6934
6985
  */
6935
6986
  shouldProcessRequest(metadata) {
6936
6987
  if (!shouldExecuteRequest(metadata, this.model)) {
6937
- log$B.debug(`Skipping request ${metadata.path} - condition returned false`);
6988
+ log$C.debug(`Skipping request ${metadata.path} - condition returned false`);
6938
6989
  return false;
6939
6990
  }
6940
6991
  return true;
@@ -7151,7 +7202,7 @@ class ServiceRequestManager {
7151
7202
  case "json":
7152
7203
  return typeof value === "string" ? JSON.parse(value) : value;
7153
7204
  default:
7154
- log$B.warn(`Unknown transformer: ${transform}`);
7205
+ log$C.warn(`Unknown transformer: ${transform}`);
7155
7206
  return value;
7156
7207
  }
7157
7208
  }
@@ -7162,7 +7213,7 @@ class ServiceRequestManager {
7162
7213
  if (!metadata.iterateOver) return data;
7163
7214
  const array = this.getNestedValue(data, metadata.iterateOver);
7164
7215
  if (!Array.isArray(array)) {
7165
- log$B.warn(
7216
+ log$C.warn(
7166
7217
  `iterateOver path '${metadata.iterateOver}' did not resolve to an array`
7167
7218
  );
7168
7219
  return [];
@@ -7205,7 +7256,7 @@ class ServiceRequestManager {
7205
7256
  case "throw":
7206
7257
  throw error;
7207
7258
  case "log":
7208
- log$B.error(
7259
+ log$C.error(
7209
7260
  `Service request failed for ${metadata.path}:`,
7210
7261
  error.message
7211
7262
  );
@@ -8335,6 +8386,7 @@ class KosMockRecorder {
8335
8386
  pending = /* @__PURE__ */ new Map();
8336
8387
  exchanges = [];
8337
8388
  pushes = [];
8389
+ sends = [];
8338
8390
  get isRecording() {
8339
8391
  return this.recording;
8340
8392
  }
@@ -8346,6 +8398,7 @@ class KosMockRecorder {
8346
8398
  this.pending.clear();
8347
8399
  this.exchanges = [];
8348
8400
  this.pushes = [];
8401
+ this.sends = [];
8349
8402
  KosLog.info(
8350
8403
  `KosMock recorder started${options.name ? ` (${options.name})` : ""}`
8351
8404
  );
@@ -8354,7 +8407,7 @@ class KosMockRecorder {
8354
8407
  const fixture = this.toFixture();
8355
8408
  this.recording = false;
8356
8409
  KosLog.info(
8357
- `KosMock recorder stopped: ${fixture.exchanges.length} exchanges, ${fixture.pushes.length} pushes`
8410
+ `KosMock recorder stopped: ${fixture.exchanges.length} exchanges, ${fixture.pushes.length} pushes, ${fixture.sends?.length ?? 0} sends`
8358
8411
  );
8359
8412
  return fixture;
8360
8413
  }
@@ -8364,7 +8417,8 @@ class KosMockRecorder {
8364
8417
  name: this.name,
8365
8418
  capturedAt: this.capturedAt,
8366
8419
  exchanges: [...this.exchanges],
8367
- pushes: [...this.pushes]
8420
+ pushes: [...this.pushes],
8421
+ sends: [...this.sends]
8368
8422
  };
8369
8423
  }
8370
8424
  download(filename) {
@@ -8393,6 +8447,7 @@ class KosMockRecorder {
8393
8447
  }
8394
8448
  const frame = decodeRequestFrame(data);
8395
8449
  if (!frame) {
8450
+ this.noteSend(data);
8396
8451
  return;
8397
8452
  }
8398
8453
  this.pending.set(frame.requestId, {
@@ -8400,7 +8455,31 @@ class KosMockRecorder {
8400
8455
  method: frame.method,
8401
8456
  url: frame.url,
8402
8457
  tracker: frame.tracker,
8403
- requestBody: frame.rawBody
8458
+ requestBody: frame.rawBody,
8459
+ requestHeaders: frame.headers
8460
+ });
8461
+ }
8462
+ /**
8463
+ * Everything else a window sends: alias registration, broker subscribes,
8464
+ * client-sent futures. What a window asked for is not recoverable from the
8465
+ * responses it got back, so it is captured rather than discarded.
8466
+ */
8467
+ noteSend(data) {
8468
+ if (typeof data !== "string") {
8469
+ return;
8470
+ }
8471
+ let headers;
8472
+ let body;
8473
+ try {
8474
+ ({ headers, body } = processKosMessage(data));
8475
+ } catch {
8476
+ return;
8477
+ }
8478
+ this.sends.push({
8479
+ tMs: this.elapsed(),
8480
+ type: headers["type"],
8481
+ headers,
8482
+ ...body ? { body } : {}
8404
8483
  });
8405
8484
  }
8406
8485
  /** Interceptor tap: every inbound frame (real, mocked, injected). Internal. */
@@ -8426,6 +8505,7 @@ class KosMockRecorder {
8426
8505
  ...request2,
8427
8506
  status: parseInt(headers["status"] ?? "200", 10) || 200,
8428
8507
  responseBody: body ?? "",
8508
+ responseHeaders: headers,
8429
8509
  latencyMs: Math.max(0, this.elapsed() - request2.tMs),
8430
8510
  ...headers[KOS_MOCKED_HEADER] === "true" ? { mocked: true } : {}
8431
8511
  });
@@ -8437,7 +8517,8 @@ class KosMockRecorder {
8437
8517
  tMs: this.elapsed(),
8438
8518
  kind: "topic",
8439
8519
  topic,
8440
- body: body ?? ""
8520
+ body: body ?? "",
8521
+ headers
8441
8522
  });
8442
8523
  return;
8443
8524
  }
@@ -8451,7 +8532,8 @@ class KosMockRecorder {
8451
8532
  tMs: this.elapsed(),
8452
8533
  kind: "future",
8453
8534
  tracker,
8454
- body: body ?? ""
8535
+ body: body ?? "",
8536
+ headers
8455
8537
  });
8456
8538
  }
8457
8539
  }
@@ -9272,32 +9354,53 @@ const resolveSingleton = () => {
9272
9354
  };
9273
9355
  const kosMockRegistry = resolveSingleton();
9274
9356
  const KosMock = kosMockRegistry;
9275
- if (typeof window !== "undefined" && window.location?.search) {
9276
- const params2 = getQueryParams();
9277
- if (params2["kosMock"] === "standalone") {
9357
+ const PROFILE_MOCK = "studio.mock";
9358
+ const PROFILE_MOCK_STANDALONE = "studio.mock.standalone";
9359
+ const PROFILE_MOCK_RECORD = "studio.mock.record";
9360
+ const PROFILE_MOCK_FIXTURE_SERVER = "studio.mock.fixtureServer";
9361
+ const PROFILE_MOCK_FIXTURE = "studio.mock.fixture";
9362
+ const PROFILE_MOCK_SETUP = "studio.mock.setup";
9363
+ const profileValue = (name) => {
9364
+ const match = resolveKosProfiles().find(
9365
+ (profile) => profile === name || profile.startsWith(`${name}=`)
9366
+ );
9367
+ return match === void 0 ? void 0 : match.slice(name.length + 1);
9368
+ };
9369
+ if (typeof window !== "undefined") {
9370
+ const params2 = window.location?.search ? getQueryParams() : {};
9371
+ const setting = (param, profile) => params2[param] !== void 0 ? params2[param] : profileValue(profile);
9372
+ const mock = params2["kosMock"] !== void 0 ? params2["kosMock"] : hasKosProfile(PROFILE_MOCK_STANDALONE) ? "standalone" : hasKosProfile(PROFILE_MOCK) ? "on" : void 0;
9373
+ const record = setting("kosRecord", PROFILE_MOCK_RECORD);
9374
+ const fixtureServer = setting(
9375
+ "kosFixtureServer",
9376
+ PROFILE_MOCK_FIXTURE_SERVER
9377
+ );
9378
+ const fixture = setting("kosFixture", PROFILE_MOCK_FIXTURE);
9379
+ const setups = setting("kosSetup", PROFILE_MOCK_SETUP);
9380
+ if (mock === "standalone") {
9278
9381
  KosMock.configure({ standalone: true });
9279
- } else if (params2["kosMock"] === "on") {
9382
+ } else if (mock === "on") {
9280
9383
  KosMock.enable();
9281
9384
  }
9282
- if (params2["kosRecord"] !== void 0) {
9283
- KosMock.recorder.start({ name: params2["kosRecord"] || void 0 });
9385
+ if (record !== void 0) {
9386
+ KosMock.recorder.start({ name: record || void 0 });
9284
9387
  }
9285
- if (params2["kosFixtureServer"] !== void 0) {
9286
- KosMock.fixtures.useServer(params2["kosFixtureServer"] || true);
9388
+ if (fixtureServer !== void 0) {
9389
+ KosMock.fixtures.useServer(fixtureServer || true);
9287
9390
  }
9288
9391
  const bootLoads = [];
9289
- if (params2["kosFixture"]) {
9392
+ if (fixture) {
9290
9393
  bootLoads.push(
9291
- KosMock.fixtures.play(params2["kosFixture"]).then(() => void 0).catch(
9394
+ KosMock.fixtures.play(fixture).then(() => void 0).catch(
9292
9395
  (error) => KosLog.error(
9293
- `KosMock: boot fixture "${params2["kosFixture"]}" failed to load`,
9396
+ `KosMock: boot fixture "${fixture}" failed to load`,
9294
9397
  error?.message
9295
9398
  )
9296
9399
  )
9297
9400
  );
9298
9401
  }
9299
- if (params2["kosSetup"]) {
9300
- for (const name of params2["kosSetup"].split(",").filter(Boolean)) {
9402
+ if (setups) {
9403
+ for (const name of setups.split(",").filter(Boolean)) {
9301
9404
  bootLoads.push(
9302
9405
  KosMock.setups.load(name).then(() => void 0).catch(
9303
9406
  (error) => KosLog.error(
@@ -9631,7 +9734,7 @@ class BridgeTransport {
9631
9734
  messageQueue = [];
9632
9735
  isSending = false;
9633
9736
  constructor(addr) {
9634
- log$R.debug(`called Bridge Transport with addr ${addr}`);
9737
+ log$S.debug(`called Bridge Transport with addr ${addr}`);
9635
9738
  const that = this;
9636
9739
  globalThis.kosWindowWebsocketRecv = (msg) => {
9637
9740
  if (that.onmessage) {
@@ -9639,19 +9742,19 @@ class BridgeTransport {
9639
9742
  that.onmessage(data);
9640
9743
  }
9641
9744
  };
9642
- log$R.debug("Opening bridge transport");
9745
+ log$S.debug("Opening bridge transport");
9643
9746
  globalThis.kosWindowWebsocketOpen();
9644
- log$R.debug("Opened bridge transport");
9747
+ log$S.debug("Opened bridge transport");
9645
9748
  this._onclose = null;
9646
9749
  this._onerror = null;
9647
9750
  this._onmessage = null;
9648
9751
  this._onopen = null;
9649
- this.addEventListener = () => log$R.debug("not implemented");
9650
- this.dispatchEvent = () => log$R.debug("not implemented");
9651
- this.removeEventListener = () => log$R.debug("not implemented");
9752
+ this.addEventListener = () => log$S.debug("not implemented");
9753
+ this.dispatchEvent = () => log$S.debug("not implemented");
9754
+ this.removeEventListener = () => log$S.debug("not implemented");
9652
9755
  }
9653
9756
  close() {
9654
- log$R.debug("closing");
9757
+ log$S.debug("closing");
9655
9758
  }
9656
9759
  sendNextMessage() {
9657
9760
  if (this.messageQueue.length > 0) {
@@ -9866,7 +9969,7 @@ if (params$1.fos) {
9866
9969
  const fosPort = process.env.KOS_FOS_PORT;
9867
9970
  window.kosUseFos = !!(window.kosUseFos || process.env.KOS_USE_FOS === "true");
9868
9971
  window.kosFosPort = fosPort ? parseInt(fosPort) : 0;
9869
- const log$A = log$R.getLogger("web-socket-transport");
9972
+ const log$B = log$S.getLogger("web-socket-transport");
9870
9973
  var KosWSTransportStatus = /* @__PURE__ */ ((KosWSTransportStatus2) => {
9871
9974
  KosWSTransportStatus2["NOT_INITIALIZED"] = "not_initialized";
9872
9975
  KosWSTransportStatus2["INITIALIZED"] = "initialized";
@@ -9923,7 +10026,7 @@ class WebSocketTransport {
9923
10026
  () => this.connectionEstablished,
9924
10027
  (connectionEstablished) => {
9925
10028
  if (connectionEstablished) {
9926
- log$A.warn("Connection Established");
10029
+ log$B.warn("Connection Established");
9927
10030
  this.reconnectAttempts = 0;
9928
10031
  publish(
9929
10032
  WebSocketEvents.CONNECTED,
@@ -9974,7 +10077,7 @@ class WebSocketTransport {
9974
10077
  protocol: this.protocol,
9975
10078
  alias: this.alias,
9976
10079
  onConnectionLost: () => {
9977
- log$A.error(`Connection Lost`);
10080
+ log$B.error(`Connection Lost`);
9978
10081
  this.scheduleReconnect();
9979
10082
  }
9980
10083
  });
@@ -10020,7 +10123,7 @@ class WebSocketTransport {
10020
10123
  return Math.floor(exponentialDelay + jitter);
10021
10124
  }
10022
10125
  _sendSubscriptionMessage(topic, type, fos = false, bridge = false, connectionId, explicitDestination = false) {
10023
- log$A.debug(`${type} to topic ${topic}`);
10126
+ log$B.debug(`${type} to topic ${topic}`);
10024
10127
  let connId;
10025
10128
  if (explicitDestination) {
10026
10129
  connId = connectionId;
@@ -10029,7 +10132,7 @@ class WebSocketTransport {
10029
10132
  const connectionParam = params2?.connId;
10030
10133
  connId = connectionId ?? connectionParam ?? window?.kosBridge?.("connId");
10031
10134
  }
10032
- log$A.debug(`subscribing with connId ${connId}`);
10135
+ log$B.debug(`subscribing with connId ${connId}`);
10033
10136
  const dstAddr = connId ? `dst-addr:${connId}
10034
10137
  ` : "";
10035
10138
  const msg = fos ? `subscribe:${topic}` : bridge ? `type:fos.broker
@@ -10043,7 +10146,7 @@ ${dstAddr}topics:${topic}
10043
10146
  const socket = fos ? this.fosSocket : this.socket;
10044
10147
  socket?.socket?.send(msg);
10045
10148
  } else {
10046
- log$A.debug(`no connection adding to offline messages`);
10149
+ log$B.debug(`no connection adding to offline messages`);
10047
10150
  const socket = fos ? this.fosSocket : this.socket;
10048
10151
  socket?.addOfflineMessage(msg);
10049
10152
  }
@@ -10057,7 +10160,7 @@ ${dstAddr}topics:${topic}
10057
10160
  explicitDestination
10058
10161
  }) {
10059
10162
  const { unsubscribe, count } = subscribe(topic, callback);
10060
- log$A.debug(`Topic ${topic} currently has ${count} subscribers`);
10163
+ log$B.debug(`Topic ${topic} currently has ${count} subscribers`);
10061
10164
  this._sendSubscriptionMessage(
10062
10165
  topic,
10063
10166
  "subscribe",
@@ -10068,7 +10171,7 @@ ${dstAddr}topics:${topic}
10068
10171
  );
10069
10172
  return () => {
10070
10173
  const { count: count2 } = unsubscribe();
10071
- log$A.debug(`Topic ${topic} currently has ${count2} subscribers`);
10174
+ log$B.debug(`Topic ${topic} currently has ${count2} subscribers`);
10072
10175
  if (count2 === 0) {
10073
10176
  this._sendSubscriptionMessage(
10074
10177
  topic,
@@ -10915,7 +11018,7 @@ class KosModelComponentFactory {
10915
11018
  return components;
10916
11019
  }
10917
11020
  }
10918
- const log$z = log$R.getLogger("kos-model");
11021
+ const log$A = log$S.getLogger("kos-model");
10919
11022
  const MODEL_LOADER = "kos.extension.model.loader";
10920
11023
  class KosModel {
10921
11024
  _id;
@@ -11023,23 +11126,23 @@ class KosModel {
11023
11126
  return this._status === KosModelState.READY;
11024
11127
  }
11025
11128
  async deactivate() {
11026
- log$z.debug(
11129
+ log$A.debug(
11027
11130
  `deactivating model ${this.modelTypeName} with id ${this.modelId}`
11028
11131
  );
11029
11132
  try {
11030
11133
  const context = KosContextManager.getContext(this.modelId);
11031
11134
  await this.modelData?.deactivate?.(context);
11032
- log$z.debug(
11135
+ log$A.debug(
11033
11136
  `Model ${this.modelTypeName} with id ${this.modelId} deactivated`
11034
11137
  );
11035
11138
  this.subscriptionManager?.deactivate();
11036
11139
  } catch (e) {
11037
- log$z.debug(`Model ${this.modelId} failed to deactivated`);
11140
+ log$A.debug(`Model ${this.modelId} failed to deactivated`);
11038
11141
  throw e;
11039
11142
  }
11040
11143
  }
11041
11144
  async activate() {
11042
- log$z.debug(`activating model ${this.modelTypeName} with id ${this.modelId}`);
11145
+ log$A.debug(`activating model ${this.modelTypeName} with id ${this.modelId}`);
11043
11146
  await executeDependentModelLifecycle(this, DependencyLifecycle.ACTIVATE);
11044
11147
  try {
11045
11148
  await this.serviceRequestManager?.executeForLifecycle(
@@ -11048,16 +11151,16 @@ class KosModel {
11048
11151
  const context = KosContextManager.getContext(this.modelId);
11049
11152
  await this.modelData?.activate?.(context);
11050
11153
  this.initializeStateMachineForLifecycle(DependencyLifecycle.ACTIVATE);
11051
- log$z.debug(
11154
+ log$A.debug(
11052
11155
  `Model ${this.modelTypeName} with id ${this.modelId} subscribing to all topics`
11053
11156
  );
11054
11157
  this.subscriptionManager?.registerAll(DependencyLifecycle.ACTIVATE);
11055
11158
  this.createLifecycleCompanions(DependencyLifecycle.ACTIVATE);
11056
- log$z.debug(
11159
+ log$A.debug(
11057
11160
  `Model ${this.modelTypeName} with id ${this.modelId} activated`
11058
11161
  );
11059
11162
  } catch (e) {
11060
- log$z.debug(`Model ${this.modelId} failed to activate`);
11163
+ log$A.debug(`Model ${this.modelId} failed to activate`);
11061
11164
  throw e;
11062
11165
  }
11063
11166
  return;
@@ -11073,7 +11176,7 @@ class KosModel {
11073
11176
  {
11074
11177
  condition: () => this.loaded,
11075
11178
  onMatch: () => {
11076
- log$z.debug(`Model ${this.modelId} is loaded`);
11179
+ log$A.debug(`Model ${this.modelId} is loaded`);
11077
11180
  }
11078
11181
  }
11079
11182
  ]);
@@ -11089,7 +11192,7 @@ class KosModel {
11089
11192
  {
11090
11193
  condition: () => this.initialized,
11091
11194
  onMatch: () => {
11092
- log$z.debug(`Model ${this.modelId} is initialized`);
11195
+ log$A.debug(`Model ${this.modelId} is initialized`);
11093
11196
  }
11094
11197
  }
11095
11198
  ]);
@@ -11105,20 +11208,20 @@ class KosModel {
11105
11208
  {
11106
11209
  condition: () => this.status === KosModelState.READY,
11107
11210
  onMatch: () => {
11108
- log$z.debug(`Model ${this.modelId} is ready`);
11211
+ log$A.debug(`Model ${this.modelId} is ready`);
11109
11212
  }
11110
11213
  }
11111
11214
  ]);
11112
11215
  }
11113
11216
  async ready() {
11114
11217
  if (this.fsm.current === KosModelState.READY) {
11115
- log$z.debug(
11218
+ log$A.debug(
11116
11219
  `already readying model ${this.modelTypeName} with id ${this.modelId} returning`
11117
11220
  );
11118
11221
  return;
11119
11222
  }
11120
11223
  try {
11121
- log$z.debug(`readying model ${this.modelTypeName} with id ${this.modelId}`);
11224
+ log$A.debug(`readying model ${this.modelTypeName} with id ${this.modelId}`);
11122
11225
  await executeDependentModelLifecycle(this, DependencyLifecycle.READY);
11123
11226
  await executeChildrenModelLifecycle(
11124
11227
  this,
@@ -11134,7 +11237,7 @@ class KosModel {
11134
11237
  this.initializeStateMachineForLifecycle(DependencyLifecycle.READY);
11135
11238
  this.subscriptionManager?.registerAll(DependencyLifecycle.READY);
11136
11239
  this.createLifecycleCompanions(DependencyLifecycle.READY);
11137
- log$z.debug(`Model ${this.modelId} is ready`);
11240
+ log$A.debug(`Model ${this.modelId} is ready`);
11138
11241
  const payload = {
11139
11242
  modelId: this.modelId,
11140
11243
  modelType: this.modelTypeName
@@ -11145,7 +11248,7 @@ class KosModel {
11145
11248
  );
11146
11249
  publish(modelTypeEventTopicFactory(this.modelTypeName), payload);
11147
11250
  } catch (e) {
11148
- log$z.error(e);
11251
+ log$A.error(e);
11149
11252
  throw Error(e);
11150
11253
  }
11151
11254
  }
@@ -11156,18 +11259,18 @@ class KosModel {
11156
11259
  }
11157
11260
  const { modelTypeName, modelId } = this;
11158
11261
  if (this.fsm.current === KosModelState.LOADED) {
11159
- log$z.debug(`Model ${modelTypeName} with id ${modelId} already loaded`);
11262
+ log$A.debug(`Model ${modelTypeName} with id ${modelId} already loaded`);
11160
11263
  return;
11161
11264
  }
11162
11265
  if (this._isLoadExecuting) {
11163
- log$z.debug(
11266
+ log$A.debug(
11164
11267
  `Model ${modelTypeName} with id ${modelId} is currently executing load`
11165
11268
  );
11166
11269
  return;
11167
11270
  }
11168
11271
  this._isLoadExecuting = true;
11169
11272
  try {
11170
- log$z.debug(`Loading model ${modelTypeName} with id ${modelId}`);
11273
+ log$A.debug(`Loading model ${modelTypeName} with id ${modelId}`);
11171
11274
  await executeDependentModelLifecycle(this, DependencyLifecycle.LOAD);
11172
11275
  const context = KosContextManager.getContext(modelId);
11173
11276
  const MODEL_LOADER_TYPE = `${MODEL_LOADER}.${modelTypeName}`;
@@ -11176,7 +11279,7 @@ class KosModel {
11176
11279
  {}
11177
11280
  );
11178
11281
  if (loadedContext) {
11179
- log$z.info(
11282
+ log$A.info(
11180
11283
  `Setting loaded context for ${modelId}, type: ${modelTypeName}`
11181
11284
  );
11182
11285
  context?.set(MODEL_LOADER_TYPE, loadedContext);
@@ -11188,7 +11291,7 @@ class KosModel {
11188
11291
  kosAction(() => {
11189
11292
  this.loaded = true;
11190
11293
  });
11191
- log$z.debug(
11294
+ log$A.debug(
11192
11295
  `Model ${modelTypeName} with id ${modelId} successfully loaded`
11193
11296
  );
11194
11297
  this.initializeStateMachineForLifecycle(DependencyLifecycle.LOAD);
@@ -11197,14 +11300,14 @@ class KosModel {
11197
11300
  this.effectManager?.setup();
11198
11301
  this.createLifecycleCompanions(DependencyLifecycle.LOAD);
11199
11302
  } catch (e) {
11200
- log$z.error(`Model ${modelId} failed to load`, e);
11303
+ log$A.error(`Model ${modelId} failed to load`, e);
11201
11304
  throw e;
11202
11305
  } finally {
11203
11306
  this._isLoadExecuting = false;
11204
11307
  }
11205
11308
  }
11206
11309
  async unload() {
11207
- log$z.debug(`unloading model ${this.modelTypeName} with id ${this.modelId}`);
11310
+ log$A.debug(`unloading model ${this.modelTypeName} with id ${this.modelId}`);
11208
11311
  try {
11209
11312
  const childrenUnload = this.getChildren().map((child) => child.unload?.()).filter((p) => !!p);
11210
11313
  await Promise.allSettled(childrenUnload);
@@ -11223,12 +11326,12 @@ class KosModel {
11223
11326
  modelData.stateHistory = [];
11224
11327
  }
11225
11328
  }
11226
- log$z.debug(`Model ${this.modelTypeName} with id ${this.modelId} unloaded`);
11329
+ log$A.debug(`Model ${this.modelTypeName} with id ${this.modelId} unloaded`);
11227
11330
  this.effectManager?.disposeAll();
11228
11331
  this.subscriptionManager?.disposeAll();
11229
11332
  this.httpRouteManager?.dispose();
11230
11333
  } catch (e) {
11231
- log$z.debug(`Model ${this.modelId} failed to unload`);
11334
+ log$A.debug(`Model ${this.modelId} failed to unload`);
11232
11335
  throw e;
11233
11336
  }
11234
11337
  }
@@ -11239,7 +11342,7 @@ class KosModel {
11239
11342
  }
11240
11343
  const { modelId, modelTypeName } = this;
11241
11344
  const context = KosContextManager.getContext(modelId);
11242
- log$z.debug(`Initializing model ${modelTypeName} with id ${modelId}`);
11345
+ log$A.debug(`Initializing model ${modelTypeName} with id ${modelId}`);
11243
11346
  await executeDependentModelLifecycle(this, DependencyLifecycle.INIT);
11244
11347
  try {
11245
11348
  await this.serviceRequestManager?.executeForLifecycle(
@@ -11247,18 +11350,18 @@ class KosModel {
11247
11350
  );
11248
11351
  await this.modelData?.init?.(context);
11249
11352
  this.initialized = true;
11250
- log$z.debug(`Model ${modelTypeName} with id ${modelId} initialized`);
11353
+ log$A.debug(`Model ${modelTypeName} with id ${modelId} initialized`);
11251
11354
  this.onlineLifecycleManager?.register();
11252
11355
  this.initializeStateMachineForLifecycle(DependencyLifecycle.INIT);
11253
11356
  this.registerSubscribers(DependencyLifecycle.INIT);
11254
11357
  this.createLifecycleCompanions(DependencyLifecycle.INIT);
11255
11358
  } catch (e) {
11256
- log$z.error(`Model ${modelId} failed to initialize`, e);
11359
+ log$A.error(`Model ${modelId} failed to initialize`, e);
11257
11360
  throw e;
11258
11361
  }
11259
11362
  }
11260
11363
  async registerSubscribers(lifecycle) {
11261
- log$z.debug(
11364
+ log$A.debug(
11262
11365
  `registering subscribers in ${this.modelTypeName} with id ${this.modelId}`
11263
11366
  );
11264
11367
  this.subscriptionManager?.registerAll(lifecycle);
@@ -11282,14 +11385,14 @@ class KosModel {
11282
11385
  this.modelManager.createLifecycleCompanions(this, {}, lifecycle);
11283
11386
  }
11284
11387
  async online() {
11285
- log$z.debug(`online model ${this.modelTypeName} with id ${this.modelId}`);
11388
+ log$A.debug(`online model ${this.modelTypeName} with id ${this.modelId}`);
11286
11389
  this.registerSubscribers();
11287
11390
  const context = KosContextManager.getContext(this.modelId);
11288
11391
  await this.modelData?.online?.(context);
11289
11392
  this.createLifecycleCompanions(DependencyLifecycle.ONLINE);
11290
11393
  }
11291
11394
  async offline() {
11292
- log$z.debug(`offline model ${this.modelTypeName} with id ${this.modelId}`);
11395
+ log$A.debug(`offline model ${this.modelTypeName} with id ${this.modelId}`);
11293
11396
  this.subscriptionManager?.disposeAll();
11294
11397
  const context = KosContextManager.getContext(this.modelId);
11295
11398
  await this.modelData?.offline?.(context);
@@ -11307,7 +11410,7 @@ class KosModel {
11307
11410
  this.companionManager.clear();
11308
11411
  }
11309
11412
  }
11310
- const log$y = KosLog.createLogger({ name: "kos-model-instantiator" });
11413
+ const log$z = KosLog.createLogger({ name: "kos-model-instantiator" });
11311
11414
  class KosModelInstantiator {
11312
11415
  constructor(registry, cache2) {
11313
11416
  this.registry = registry;
@@ -11325,7 +11428,7 @@ class KosModelInstantiator {
11325
11428
  const modelRegistry = this.registry.models[typeId];
11326
11429
  if (!modelRegistry) {
11327
11430
  const errorMessage = `No model registered for type ${typeId}`;
11328
- log$y.error(errorMessage, {
11431
+ log$z.error(errorMessage, {
11329
11432
  modelType: typeId,
11330
11433
  requestedId: id,
11331
11434
  providedOptions: options,
@@ -11344,7 +11447,7 @@ class KosModelInstantiator {
11344
11447
  const modelId = modelRegistry.singleton ? typeId : id;
11345
11448
  this.cache.restoreFromDeleteCache(modelId);
11346
11449
  if (!this.cache.hasModel(modelId)) {
11347
- log$y.debug(`Creating model instance: ${typeId} [${modelId}]`);
11450
+ log$z.debug(`Creating model instance: ${typeId} [${modelId}]`);
11348
11451
  const hasOptions = options && Object.keys(options).length > 0;
11349
11452
  const modelClass = modelRegistry.class || modelRegistry.create;
11350
11453
  const requiresOptions = modelClass?.prototype?.[OptionsRequired] === true;
@@ -11390,7 +11493,7 @@ class KosModelInstantiator {
11390
11493
  }
11391
11494
  const activeModel = this.cache.getModelById(modelId);
11392
11495
  if (!activeModel) {
11393
- log$y.error(`Model ${typeId} [${modelId}] not found in cache`);
11496
+ log$z.error(`Model ${typeId} [${modelId}] not found in cache`);
11394
11497
  throw new Error(`Model ${typeId} [${modelId}] not found in cache`);
11395
11498
  }
11396
11499
  return { model: activeModel, data: activeModel.modelData };
@@ -11456,7 +11559,7 @@ let KosModelRegistry$1 = class KosModelRegistry {
11456
11559
  }
11457
11560
  };
11458
11561
  const MODEL_DELETION_DELAY = 10;
11459
- const log$x = KosLog.createLogger({ name: "kos-model-manager" });
11562
+ const log$y = KosLog.createLogger({ name: "kos-model-manager" });
11460
11563
  class KosModelManager {
11461
11564
  cache;
11462
11565
  instantiator;
@@ -11499,7 +11602,7 @@ class KosModelManager {
11499
11602
  }
11500
11603
  static getInstance(reset2) {
11501
11604
  if (!globalThis.kos?.modelManager || reset2) {
11502
- log$x.debug("Creating new instance of KosModelManager");
11605
+ log$y.debug("Creating new instance of KosModelManager");
11503
11606
  new this();
11504
11607
  }
11505
11608
  return globalThis.kos?.modelManager;
@@ -11521,7 +11624,7 @@ class KosModelManager {
11521
11624
  */
11522
11625
  get preloadedModels() {
11523
11626
  return this.cache.preload((modelKey) => {
11524
- log$x.debug(`preloading ${modelKey}`);
11627
+ log$y.debug(`preloading ${modelKey}`);
11525
11628
  if (typeof modelKey === "string") {
11526
11629
  return this.createModelInstance(modelKey).model;
11527
11630
  } else {
@@ -11721,6 +11824,8 @@ class KosModelManager {
11721
11824
  if (model?.modelId && this.dependencies.canDestroy(model.modelId)) {
11722
11825
  await model.unload?.();
11723
11826
  this.removeModel(model);
11827
+ this.dependencies.removeAll(model.modelId);
11828
+ clearModelHookCacheEntry(model.modelId);
11724
11829
  }
11725
11830
  }
11726
11831
  /**
@@ -11809,7 +11914,7 @@ const reportFailure = async (step, run2) => {
11809
11914
  return await run2();
11810
11915
  } catch (error) {
11811
11916
  const detail = error instanceof Error ? error.stack ?? `${error.name}: ${error.message}` : String(error);
11812
- log$R.error(`KOS Core lifecycle step "${step}" failed. ${detail}`);
11917
+ log$S.error(`KOS Core lifecycle step "${step}" failed. ${detail}`);
11813
11918
  throw error;
11814
11919
  }
11815
11920
  };
@@ -11848,7 +11953,7 @@ const coreFsm = (core) => {
11848
11953
  });
11849
11954
  const online = robot3.interpret(
11850
11955
  onlineMachine2,
11851
- (_service) => log$R.debug(_service.machine.current)
11956
+ (_service) => log$S.debug(_service.machine.current)
11852
11957
  );
11853
11958
  const failed = robot3.transition(
11854
11959
  `error`,
@@ -11996,11 +12101,11 @@ const coreFsm = (core) => {
11996
12101
  });
11997
12102
  const service2 = robot3.interpret(
11998
12103
  machine2,
11999
- (_service) => log$R.debug(_service.machine.current)
12104
+ (_service) => log$S.debug(_service.machine.current)
12000
12105
  );
12001
12106
  return { service: service2, online };
12002
12107
  };
12003
- const log$w = KosLog.createLogger({ name: "kos-core" });
12108
+ const log$x = KosLog.createLogger({ name: "kos-core" });
12004
12109
  const getConnectionAlias = () => {
12005
12110
  const params2 = getQueryParams();
12006
12111
  const alias = params2?.alias;
@@ -12114,7 +12219,7 @@ class KosCore {
12114
12219
  try {
12115
12220
  await model.offline?.();
12116
12221
  } catch (e) {
12117
- log$w.error(`model ${model.modelId} offline() threw:`, e);
12222
+ log$x.error(`model ${model.modelId} offline() threw:`, e);
12118
12223
  }
12119
12224
  model.onlineLifecycleManager?.dispose();
12120
12225
  })
@@ -12129,7 +12234,7 @@ class KosCore {
12129
12234
  try {
12130
12235
  await model.online?.();
12131
12236
  } catch (e) {
12132
- log$w.error(`model ${model.modelId} online() threw:`, e);
12237
+ log$x.error(`model ${model.modelId} online() threw:`, e);
12133
12238
  }
12134
12239
  })
12135
12240
  );
@@ -12145,11 +12250,11 @@ class KosCore {
12145
12250
  this.transport.authorized = false;
12146
12251
  });
12147
12252
  subscribe(WebSocketEvents.RELOAD, () => {
12148
- log$w.warn("WebSocket requested reload");
12253
+ log$x.warn("WebSocket requested reload");
12149
12254
  this.fsmService.service.send(KosCoreEvents.RELOAD);
12150
12255
  });
12151
12256
  subscribe("/studio/project/reload", () => {
12152
- log$w.warn("Project requested reload");
12257
+ log$x.warn("Project requested reload");
12153
12258
  this.fsmService.service.send(KosCoreEvents.RELOAD);
12154
12259
  });
12155
12260
  const ws = WebSocketTransport.getInstance();
@@ -12188,33 +12293,33 @@ class KosCore {
12188
12293
  async reload() {
12189
12294
  const currentTime = Date.now();
12190
12295
  if (this._reloading) {
12191
- log$w.info("reload already in progress");
12296
+ log$x.info("reload already in progress");
12192
12297
  return;
12193
12298
  }
12194
12299
  this._reloading = true;
12195
- log$w.warn("reloading KOS Core");
12196
- log$w.warn("reloading preloaded models");
12300
+ log$x.warn("reloading KOS Core");
12301
+ log$x.warn("reloading preloaded models");
12197
12302
  const modelManager = this.modelManager;
12198
12303
  for (const model of modelManager.preloadedModels) {
12199
12304
  if (isReloadable(model.modelData)) {
12200
12305
  if (isSelfManagedReload(model.modelData)) {
12201
- log$w.info(`skipping self-managed model ${model.modelId}`);
12306
+ log$x.info(`skipping self-managed model ${model.modelId}`);
12202
12307
  continue;
12203
12308
  }
12204
- log$w.info(`reloading model ${model.modelId}`);
12309
+ log$x.info(`reloading model ${model.modelId}`);
12205
12310
  model.unload?.();
12206
12311
  await model.modelData.reload();
12207
12312
  model.registerSubscribers?.();
12208
- log$w.info(`reloading model ${model.modelId} complete`);
12313
+ log$x.info(`reloading model ${model.modelId} complete`);
12209
12314
  }
12210
12315
  }
12211
12316
  for (const model of modelManager.models) {
12212
12317
  if (!modelManager.preloadedModels.includes(model) && isReloadable(model.modelData)) {
12213
12318
  if (isSelfManagedReload(model.modelData)) {
12214
- log$w.info(`skipping self-managed model ${model.modelId}`);
12319
+ log$x.info(`skipping self-managed model ${model.modelId}`);
12215
12320
  continue;
12216
12321
  }
12217
- log$w.warn(`reloading model ${model.modelId}`);
12322
+ log$x.warn(`reloading model ${model.modelId}`);
12218
12323
  model.unload?.();
12219
12324
  await model.modelData.reload();
12220
12325
  model.registerSubscribers?.();
@@ -12223,27 +12328,27 @@ class KosCore {
12223
12328
  const elapsed = Date.now() - currentTime;
12224
12329
  setTimeout(() => {
12225
12330
  mobx.runInAction(() => {
12226
- log$w.warn("reloading KOS Core complete");
12331
+ log$x.warn("reloading KOS Core complete");
12227
12332
  this._reloading = false;
12228
12333
  });
12229
12334
  }, 1e3 - elapsed);
12230
12335
  }
12231
12336
  async online() {
12232
- log$w.debug("KOS Core going online");
12337
+ log$x.debug("KOS Core going online");
12233
12338
  await this._transport.whenReady();
12234
- log$w.debug("KOS Transport Ready. Calling online() for models");
12339
+ log$x.debug("KOS Transport Ready. Calling online() for models");
12235
12340
  publish("/kosCore/online", "/kosCore/online");
12236
12341
  console.timeEnd("kosCore:startup");
12237
12342
  }
12238
12343
  async offline() {
12239
- log$w.debug("KOS Core going offline");
12344
+ log$x.debug("KOS Core going offline");
12240
12345
  publish("/kosCore/offline", "/kosCore/offline");
12241
12346
  }
12242
12347
  async unload() {
12243
- log$w.debug("Unloading KOS Core");
12348
+ log$x.debug("Unloading KOS Core");
12244
12349
  const currentTime = Date.now();
12245
12350
  this._unloading = true;
12246
- log$w.debug("unloading KOS Core");
12351
+ log$x.debug("unloading KOS Core");
12247
12352
  const modelManager = this.modelManager;
12248
12353
  for (const model of modelManager.models) {
12249
12354
  if (isUnloadable(model.modelData)) {
@@ -12261,9 +12366,9 @@ class KosCore {
12261
12366
  await mobx.when(() => this.status === KosCoreState.READY);
12262
12367
  }
12263
12368
  async ready() {
12264
- log$w.debug("Readying KOS Core");
12369
+ log$x.debug("Readying KOS Core");
12265
12370
  await this._transport.whenReady();
12266
- log$w.debug("KOS Transport ready. Preloading models");
12371
+ log$x.debug("KOS Transport ready. Preloading models");
12267
12372
  if (!this.modelManager) {
12268
12373
  throw new Error(
12269
12374
  "KOS Core reached ready() with no model manager. Its lifecycle was started without a registry."
@@ -12276,7 +12381,7 @@ class KosCore {
12276
12381
  promise: model.whenReady()
12277
12382
  };
12278
12383
  });
12279
- log$w.debug(`Preloaded ${promises.length} models`);
12384
+ log$x.debug(`Preloaded ${promises.length} models`);
12280
12385
  const settled = await Promise.allSettled(
12281
12386
  promises.map((promise) => {
12282
12387
  const { promise: timeoutPromise, cancel: timeoutCancel } = rejectAfterDelay(5e3, promise.model);
@@ -12290,14 +12395,14 @@ class KosCore {
12290
12395
  );
12291
12396
  const failed = settled.filter((p) => p.status === "rejected");
12292
12397
  if (failed.length) {
12293
- log$w.error(
12398
+ log$x.error(
12294
12399
  `There were ${failed.length} failed models on model preloading`
12295
12400
  );
12296
12401
  throw Error(
12297
12402
  `There were ${failed.length} failed models on model preloading`
12298
12403
  );
12299
12404
  }
12300
- log$w.debug(`leaving kos-core ready() `);
12405
+ log$x.debug(`leaving kos-core ready() `);
12301
12406
  }
12302
12407
  get isReady() {
12303
12408
  return this.status === KosCoreState.READY;
@@ -12315,19 +12420,19 @@ class KosCore {
12315
12420
  return this.loaded;
12316
12421
  }
12317
12422
  async init() {
12318
- log$w.debug("entering kos-core init()");
12423
+ log$x.debug("entering kos-core init()");
12319
12424
  console.time("kosCore:startup");
12320
12425
  console.time("kosCore:init");
12321
12426
  await this._transport.whenReady();
12322
12427
  this.initialized = true;
12323
- log$w.debug("initialized - leaving kos-core init()");
12428
+ log$x.debug("initialized - leaving kos-core init()");
12324
12429
  console.timeEnd("kosCore:init");
12325
12430
  }
12326
12431
  async load() {
12327
- log$w.debug("entering kos-core load()");
12432
+ log$x.debug("entering kos-core load()");
12328
12433
  console.time("kosCore:load");
12329
12434
  this.loaded = true;
12330
- log$w.debug("loaded - leaving kos-core load()");
12435
+ log$x.debug("loaded - leaving kos-core load()");
12331
12436
  console.timeEnd("kosCore:load");
12332
12437
  }
12333
12438
  static create(registry, reset2, connectionAlias) {
@@ -12407,7 +12512,7 @@ class KosCore {
12407
12512
  return this._instance;
12408
12513
  }
12409
12514
  }
12410
- const log$v = KosLog.createLogger({
12515
+ const log$w = KosLog.createLogger({
12411
12516
  name: "kos-model-visitor",
12412
12517
  group: "kos-ui-core"
12413
12518
  });
@@ -12448,7 +12553,7 @@ class KosModelVisitor {
12448
12553
  */
12449
12554
  visit(model) {
12450
12555
  if (this.visitedModels.has(model.modelId)) {
12451
- log$v.info(`model ${model.modelId} already visited`);
12556
+ log$w.info(`model ${model.modelId} already visited`);
12452
12557
  return;
12453
12558
  }
12454
12559
  const stopVisiting = !!this.visitModel(model.modelData, this);
@@ -12941,7 +13046,7 @@ async function retryWithExponentialBackoff(operation, options) {
12941
13046
  }
12942
13047
  throw new Error("All attempts failed");
12943
13048
  }
12944
- const log$u = KosLog.createLogger({ name: "kos-service-request" });
13049
+ const log$v = KosLog.createLogger({ name: "kos-service-request" });
12945
13050
  const resolveServiceUrl = (_service) => {
12946
13051
  const MOCK = false;
12947
13052
  const URL2 = exports.BASE_URL;
@@ -13113,7 +13218,7 @@ const getOne$7 = (destinationAddress2, url, _fetch) => async ({
13113
13218
  destinationAddress: destinationAddressOverride
13114
13219
  });
13115
13220
  const resolvedUrl = urlOverride || url;
13116
- log$u.debug(`resolvedUrl: ${resolvedUrl}`);
13221
+ log$v.debug(`resolvedUrl: ${resolvedUrl}`);
13117
13222
  try {
13118
13223
  const response = await _fetch(resolvedUrl, options);
13119
13224
  if (!response.ok) {
@@ -13487,7 +13592,7 @@ const getKosSessionKey = () => `kos-${_sessionKey}`;
13487
13592
  const isLocalRefId = (id) => !!id && !id.includes("VM_SERVICE") && id.startsWith(getKosSessionKey());
13488
13593
  const waitForRequest = async (requestId, timeout = 6e4) => new Promise((resolve, reject) => {
13489
13594
  const { unsubscribe } = subscribe(requestId, (op) => {
13490
- log$R.debug(`recieved response for refId ${requestId}: ${op}`);
13595
+ log$S.debug(`recieved response for refId ${requestId}: ${op}`);
13491
13596
  unsubscribe();
13492
13597
  clearTimeout(cancel);
13493
13598
  try {
@@ -13762,7 +13867,7 @@ function collectRecords(items) {
13762
13867
  }
13763
13868
  return result;
13764
13869
  }
13765
- const log$t = KosLog.createLogger({ name: "kos-data-container" });
13870
+ const log$u = KosLog.createLogger({ name: "kos-data-container" });
13766
13871
  class KosDataContainer {
13767
13872
  _data;
13768
13873
  _sortKey;
@@ -13967,7 +14072,7 @@ class KosDataContainer {
13967
14072
  const idx = this.index.get(indexName);
13968
14073
  return idx.keys ?? [];
13969
14074
  } else {
13970
- log$t.info(
14075
+ log$u.info(
13971
14076
  `index ${indexName} not found in ${Array.from(this.index.keys())}`
13972
14077
  );
13973
14078
  return [];
@@ -13979,7 +14084,7 @@ class KosDataContainer {
13979
14084
  if (idx.index.has(indexKey)) {
13980
14085
  return idx.getByKey(indexKey);
13981
14086
  } else {
13982
- log$t.info(
14087
+ log$u.info(
13983
14088
  `key ${indexKey} not found in ${indexName} index: ${Array.from(
13984
14089
  idx.index.keys()
13985
14090
  )}`
@@ -13987,7 +14092,7 @@ class KosDataContainer {
13987
14092
  return [];
13988
14093
  }
13989
14094
  } else {
13990
- log$t.info(
14095
+ log$u.info(
13991
14096
  `index ${indexName} not found in ${Array.from(this.index.keys())}`
13992
14097
  );
13993
14098
  return [];
@@ -14014,7 +14119,7 @@ class KosDataContainer {
14014
14119
  * @private
14015
14120
  */
14016
14121
  _logDataCapacityWarning(toEvict) {
14017
- log$t.info(
14122
+ log$u.info(
14018
14123
  `Data container capacity exceeded (${this._data.size}/${this._maxCapacity}). Evicting ${toEvict} items using ${this._evictionStrategy} strategy. This may indicate missing cleanup handlers or data inconsistency.`
14019
14124
  );
14020
14125
  }
@@ -14074,7 +14179,7 @@ class KosDataContainer {
14074
14179
  const candidates = this._customEvictionFilter(this.data);
14075
14180
  return candidates.slice(0, count).map((item) => item.id);
14076
14181
  }
14077
- log$t.error(
14182
+ log$u.error(
14078
14183
  "Custom eviction strategy specified but no customEvictionFilter provided. Falling back to FIFO."
14079
14184
  );
14080
14185
  return this._selectFifoData(count);
@@ -14086,7 +14191,7 @@ class KosDataContainer {
14086
14191
  _removeEvictedData(ids) {
14087
14192
  ids.forEach((id) => {
14088
14193
  const item = this._data.get(id);
14089
- log$t.info(`Evicting data item: ${id}`, {
14194
+ log$u.info(`Evicting data item: ${id}`, {
14090
14195
  itemId: id,
14091
14196
  itemType: item ? item.constructor?.name : "unknown",
14092
14197
  strategy: this._evictionStrategy
@@ -14099,7 +14204,7 @@ class KosDataContainer {
14099
14204
  * @private
14100
14205
  */
14101
14206
  _logDataEvictionComplete(evictedCount) {
14102
- log$t.info(
14207
+ log$u.info(
14103
14208
  `Evicted ${evictedCount} data items. Current size: ${this._data.size}/${this._maxCapacity}`
14104
14209
  );
14105
14210
  }
@@ -14338,14 +14443,14 @@ class BrowserKosRouter {
14338
14443
  }, {});
14339
14444
  }
14340
14445
  }
14341
- const log$s = KosLog.createLogger({ name: "intent-service" });
14446
+ const log$t = KosLog.createLogger({ name: "intent-service" });
14342
14447
  const sendIntent = (intent) => {
14343
14448
  if (hasEventSubscriptions(`/kos/intent/${intent.type}`)) {
14344
14449
  publish(`/kos/intent/${intent.type}`, intent.options, {
14345
14450
  "kos.intent.type": intent.type
14346
14451
  });
14347
14452
  } else {
14348
- log$s.info(`No subscribers for intent ${intent.type}. Intent not sent.`);
14453
+ log$t.info(`No subscribers for intent ${intent.type}. Intent not sent.`);
14349
14454
  }
14350
14455
  };
14351
14456
  const sendAsyncIntent = async (intent) => new Promise((resolve) => {
@@ -14375,11 +14480,11 @@ const sendAsyncIntent = async (intent) => new Promise((resolve) => {
14375
14480
  sync: requestId
14376
14481
  });
14377
14482
  } else {
14378
- log$s.info(`No subscribers for intent ${intent.type}. Intent not sent.`);
14483
+ log$t.info(`No subscribers for intent ${intent.type}. Intent not sent.`);
14379
14484
  resolve([null, { body: void 0, payload: void 0 }]);
14380
14485
  }
14381
14486
  });
14382
- const log$r = KosLog.createLogger({ name: "app-startup-service" });
14487
+ const log$s = KosLog.createLogger({ name: "app-startup-service" });
14383
14488
  async function waitForAppsToStart(appIds, options = {}) {
14384
14489
  const {
14385
14490
  timeout = 3e4,
@@ -14387,10 +14492,10 @@ async function waitForAppsToStart(appIds, options = {}) {
14387
14492
  requirePostStarted = false
14388
14493
  } = options;
14389
14494
  if (appIds.length === 0) {
14390
- log$r.warn("No app IDs provided to waitForAppsToStart");
14495
+ log$s.warn("No app IDs provided to waitForAppsToStart");
14391
14496
  return true;
14392
14497
  }
14393
- log$r.debug(`Waiting for apps to start: ${appIds.join(", ")}`);
14498
+ log$s.debug(`Waiting for apps to start: ${appIds.join(", ")}`);
14394
14499
  try {
14395
14500
  const eventTopics = appIds.map((appId) => `/kos/app/started/${appId}`);
14396
14501
  const startedApps = await waitForAllWithState(eventTopics, {
@@ -14399,12 +14504,12 @@ async function waitForAppsToStart(appIds, options = {}) {
14399
14504
  const { default: api2 } = await Promise.resolve().then(() => service$8);
14400
14505
  const [error, data] = await api2.get("/api/kos/apps/started");
14401
14506
  if (error) {
14402
- log$r.error("Error fetching started apps:", error);
14507
+ log$s.error("Error fetching started apps:", error);
14403
14508
  return [];
14404
14509
  }
14405
14510
  return data;
14406
14511
  } catch (error) {
14407
- log$r.error("Failed to fetch app startup status:", error);
14512
+ log$s.error("Failed to fetch app startup status:", error);
14408
14513
  }
14409
14514
  return [];
14410
14515
  },
@@ -14426,17 +14531,17 @@ async function waitForAppsToStart(appIds, options = {}) {
14426
14531
  });
14427
14532
  if (notStartedApps.length > 0) {
14428
14533
  const message2 = `Apps not started: ${notStartedApps.join(", ")}`;
14429
- log$r.error(message2);
14534
+ log$s.error(message2);
14430
14535
  if (throwOnTimeout) {
14431
14536
  throw new Error(`App startup timeout: ${message2}`);
14432
14537
  }
14433
14538
  return false;
14434
14539
  }
14435
- log$r.info(`All apps started successfully: ${appIds.join(", ")}`);
14540
+ log$s.info(`All apps started successfully: ${appIds.join(", ")}`);
14436
14541
  return true;
14437
14542
  } catch (error) {
14438
14543
  const message2 = `Failed to wait for apps to start: ${appIds.join(", ")}`;
14439
- log$r.error(message2, error);
14544
+ log$s.error(message2, error);
14440
14545
  if (throwOnTimeout) {
14441
14546
  throw new Error(
14442
14547
  `${message2} - ${error instanceof Error ? error.message : String(error)}`
@@ -14463,7 +14568,7 @@ async function checkAppsStarted(appIds, requirePostStarted = false) {
14463
14568
  result[appId] = app?.started === true && (!requirePostStarted || app?.postStarted === true);
14464
14569
  });
14465
14570
  } catch (error) {
14466
- log$r.error("Failed to check app startup status:", error);
14571
+ log$s.error("Failed to check app startup status:", error);
14467
14572
  appIds.forEach((appId) => result[appId] = false);
14468
14573
  }
14469
14574
  return result;
@@ -14477,7 +14582,7 @@ async function getStartedApps() {
14477
14582
  const result = await response.json();
14478
14583
  return result?.data ?? [];
14479
14584
  } catch (error) {
14480
- log$r.error("Failed to fetch started apps:", error);
14585
+ log$s.error("Failed to fetch started apps:", error);
14481
14586
  return [];
14482
14587
  }
14483
14588
  }
@@ -14504,7 +14609,7 @@ var Topics = /* @__PURE__ */ ((Topics2) => {
14504
14609
  Topics2["TIMEZONE_CHANGE"] = "/kos/internal/time/timezone";
14505
14610
  return Topics2;
14506
14611
  })(Topics || {});
14507
- const log$q = KosLog.createLogger({
14612
+ const log$r = KosLog.createLogger({
14508
14613
  name: "config-bean-service",
14509
14614
  group: "Services"
14510
14615
  });
@@ -14515,7 +14620,7 @@ const { postModel: postModel$5, getOne: getOne$6 } = ServiceFactory.build({
14515
14620
  basePath: `${URL$e}/kos/config/`
14516
14621
  });
14517
14622
  const modifyConfigBean = async (id, model, path = `/api/kos/config`) => {
14518
- log$q.debug(`sending modify request for ConfigBean: ${id}`);
14623
+ log$r.debug(`sending modify request for ConfigBean: ${id}`);
14519
14624
  const response = postModel$5({
14520
14625
  model,
14521
14626
  urlOverride: `${URL$e}${path}/${id}`
@@ -14523,7 +14628,7 @@ const modifyConfigBean = async (id, model, path = `/api/kos/config`) => {
14523
14628
  return response;
14524
14629
  };
14525
14630
  const getConfigBean = async (id, path = `/api/kos/config`) => {
14526
- log$q.debug(`sending get request for ConfigBean: ${id}`);
14631
+ log$r.debug(`sending get request for ConfigBean: ${id}`);
14527
14632
  const response = await getOne$6({
14528
14633
  urlOverride: `${URL$e}${path}/details/${id}/15`
14529
14634
  });
@@ -14635,7 +14740,7 @@ function matchValue(patterns, value) {
14635
14740
  return void 0;
14636
14741
  }
14637
14742
  const CONFIG_BEAN_MODEL_TYPE = "config-bean-model";
14638
- const log$p = KosLog.getLogger(CONFIG_BEAN_MODEL_TYPE);
14743
+ const log$q = KosLog.getLogger(CONFIG_BEAN_MODEL_TYPE);
14639
14744
  const PATH_PROP$3 = createPropKey("path");
14640
14745
  function servicePathMapper$1(configBeanModel) {
14641
14746
  const hasMapper = ExtensionManager.propertyMapper.hasMapper(
@@ -14708,8 +14813,8 @@ let ConfigBeanModelImpl = class {
14708
14813
  * @internal
14709
14814
  */
14710
14815
  async ready() {
14711
- log$p.debug(`readying config bean ${this.path}`);
14712
- log$p.debug(`complete readying config bean ${this.path}`);
14816
+ log$q.debug(`readying config bean ${this.path}`);
14817
+ log$q.debug(`complete readying config bean ${this.path}`);
14713
14818
  }
14714
14819
  /**
14715
14820
  * @internal
@@ -14720,12 +14825,12 @@ let ConfigBeanModelImpl = class {
14720
14825
  * In future additional information about the workspace could be loaded
14721
14826
  */
14722
14827
  async load() {
14723
- log$p.debug(`loading config bean ${this.path}`);
14828
+ log$q.debug(`loading config bean ${this.path}`);
14724
14829
  const response = await this._getConfigBean(this.path, this.serviceBasePath);
14725
14830
  if (response?.data) {
14726
14831
  const data = response.data;
14727
14832
  mapDtoToConfigBeanModel(data, this);
14728
- log$p.debug(this.values);
14833
+ log$q.debug(this.values);
14729
14834
  const schemaResponse = response?.data.details[0].schema;
14730
14835
  kosAction(() => {
14731
14836
  if (schemaResponse) {
@@ -14993,7 +15098,7 @@ var __decorateClass$z = (decorators, target, key, kind) => {
14993
15098
  return result;
14994
15099
  };
14995
15100
  const MODEL_TYPE$w = "region-info-model";
14996
- const log$o = KosLog.createLogger({ name: "region-info-model" });
15101
+ const log$p = KosLog.createLogger({ name: "region-info-model" });
14997
15102
  function servicePathMapper(regionInfoModel) {
14998
15103
  const hasMapper = ExtensionManager.propertyMapper.hasMapper(
14999
15104
  KosCoreModelPropertyMapper.RegionServicePath
@@ -15284,7 +15389,7 @@ let RegionInfoModelImpl = class {
15284
15389
  }
15285
15390
  toUnit = measureSystems[to.system]?.["default"];
15286
15391
  if (!toUnit) {
15287
- log$o.info("Could not find default unit for measure", to.measure);
15392
+ log$p.info("Could not find default unit for measure", to.measure);
15288
15393
  }
15289
15394
  }
15290
15395
  if (!fromUnit && from.measure && from.system) {
@@ -15298,11 +15403,11 @@ let RegionInfoModelImpl = class {
15298
15403
  }
15299
15404
  fromUnit = measureSystems[from.system]?.["default"];
15300
15405
  if (!fromUnit) {
15301
- log$o.info("Could not find default unit for measure", from.measure);
15406
+ log$p.info("Could not find default unit for measure", from.measure);
15302
15407
  }
15303
15408
  }
15304
15409
  if (!fromUnit || !toUnit) {
15305
- log$o.warn("Could not find unit to convert to or from. Return value as is");
15410
+ log$p.warn("Could not find unit to convert to or from. Return value as is");
15306
15411
  return String(value);
15307
15412
  }
15308
15413
  return this.convertByUnit(value, fromUnit, toUnit);
@@ -15312,13 +15417,13 @@ let RegionInfoModelImpl = class {
15312
15417
  * @internal
15313
15418
  */
15314
15419
  async init() {
15315
- log$o.debug("initializing region info");
15420
+ log$p.debug("initializing region info");
15316
15421
  }
15317
15422
  /**
15318
15423
  * @internal
15319
15424
  */
15320
15425
  async load() {
15321
- log$o.debug("loading region info");
15426
+ log$p.debug("loading region info");
15322
15427
  const regions = await getRegions(this.serviceBasePath);
15323
15428
  if (regions) {
15324
15429
  this.regions = regions.data.map((region) => region.id);
@@ -15638,7 +15743,7 @@ function secondsToFormattedTime(secondsSinceMidnight, formatString) {
15638
15743
  return dateFns.format(time, formatString);
15639
15744
  }
15640
15745
  const MODEL_TYPE$v = "config-bean-prop-model";
15641
- const log$n = KosLog.createLogger({ name: "config-bean-prop-model" });
15746
+ const log$o = KosLog.createLogger({ name: "config-bean-prop-model" });
15642
15747
  const PATH_PROP$2 = createPropKey("path");
15643
15748
  const SERVICE_PATH_PROP = createPropKey("serviceBasePath");
15644
15749
  let KosConfigPropertyImpl = class {
@@ -15834,7 +15939,7 @@ let KosConfigPropertyImpl = class {
15834
15939
  return Number(result2);
15835
15940
  }
15836
15941
  } catch (e) {
15837
- log$n.info(`error formatting value ${_val}`, e);
15942
+ log$o.info(`error formatting value ${_val}`, e);
15838
15943
  }
15839
15944
  const result = Number(_val).toFixed(decimals);
15840
15945
  return result;
@@ -15873,7 +15978,7 @@ let KosConfigPropertyImpl = class {
15873
15978
  * @internal
15874
15979
  */
15875
15980
  async activate() {
15876
- log$n.debug(`activating config bean ${this.id}`);
15981
+ log$o.debug(`activating config bean ${this.id}`);
15877
15982
  }
15878
15983
  /**
15879
15984
  * Gets the formatted display string with units and localization.
@@ -15906,7 +16011,7 @@ let KosConfigPropertyImpl = class {
15906
16011
  return result;
15907
16012
  }
15908
16013
  } catch (e) {
15909
- log$n.error(`error formatting value ${_val}`, e);
16014
+ log$o.error(`error formatting value ${_val}`, e);
15910
16015
  }
15911
16016
  }
15912
16017
  return String(_val);
@@ -16004,13 +16109,13 @@ let KosConfigPropertyImpl = class {
16004
16109
  try {
16005
16110
  formatter2 = new Intl.NumberFormat(locale, { ...formatOptions });
16006
16111
  } catch (e) {
16007
- log$n.error(
16112
+ log$o.error(
16008
16113
  `error creating formatter ${formatOptions}. Returning the raw value`,
16009
16114
  e
16010
16115
  );
16011
16116
  }
16012
16117
  } else {
16013
- log$n.debug(
16118
+ log$o.debug(
16014
16119
  `no formatter found for config bean prop ${this.id}. Returning the raw value`
16015
16120
  );
16016
16121
  }
@@ -16079,7 +16184,7 @@ let KosConfigPropertyImpl = class {
16079
16184
  * ```
16080
16185
  */
16081
16186
  async updateProperty(value) {
16082
- log$n.debug(`updating property ${this.attribute} with value ${value}`);
16187
+ log$o.debug(`updating property ${this.attribute} with value ${value}`);
16083
16188
  let _value = value;
16084
16189
  const converter = this.getConverter();
16085
16190
  if (converter && !isNaN(_value)) {
@@ -16196,7 +16301,7 @@ const buildFuture = (factory) => (future) => pipe(
16196
16301
  mapDtoToFutureOptions,
16197
16302
  buildFutureModel$1(factory)(future.tracker || future.id)
16198
16303
  )(future);
16199
- const log$m = KosLog.createLogger({ name: "future-service", group: "Services" });
16304
+ const log$n = KosLog.createLogger({ name: "future-service", group: "Services" });
16200
16305
  const { isMock, URL: URL$c } = resolveServiceUrl();
16201
16306
  var FutureEndState = /* @__PURE__ */ ((FutureEndState2) => {
16202
16307
  FutureEndState2["Success"] = "SUCCESS";
@@ -16215,7 +16320,7 @@ const getFutures = async () => {
16215
16320
  return response;
16216
16321
  };
16217
16322
  const deleteFuture = async (id, path = "/api/kos/future") => {
16218
- log$m.info(`sending delete request for Future: ${id}`);
16323
+ log$n.info(`sending delete request for Future: ${id}`);
16219
16324
  const response = await deleteModel$1({
16220
16325
  id,
16221
16326
  urlOverride: `${URL$c}${path}/${id}`
@@ -16223,7 +16328,7 @@ const deleteFuture = async (id, path = "/api/kos/future") => {
16223
16328
  return response;
16224
16329
  };
16225
16330
  const addFuture = async (future, path = "/api/kos/future") => {
16226
- log$m.info(`sending add request for Future`);
16331
+ log$n.info(`sending add request for Future`);
16227
16332
  const response = await addModel({
16228
16333
  model: future,
16229
16334
  urlOverride: `${URL$c}${path}`
@@ -16231,7 +16336,7 @@ const addFuture = async (future, path = "/api/kos/future") => {
16231
16336
  return response;
16232
16337
  };
16233
16338
  const modifyFuture = async (id, model, path = "/api/kos/future") => {
16234
- log$m.info(`sending modify request for Future: ${id}`);
16339
+ log$n.info(`sending modify request for Future: ${id}`);
16235
16340
  const response = modifyModel({
16236
16341
  model,
16237
16342
  id,
@@ -16240,7 +16345,7 @@ const modifyFuture = async (id, model, path = "/api/kos/future") => {
16240
16345
  return response;
16241
16346
  };
16242
16347
  const cancelFuture = async (id, path = "/api/kos/future") => {
16243
- log$m.info(`sending cancel request for Future: ${id}`);
16348
+ log$n.info(`sending cancel request for Future: ${id}`);
16244
16349
  const response = postModel$4({
16245
16350
  urlOverride: `${URL$c}${path}/${id}/cancel`,
16246
16351
  ordered: true,
@@ -16423,12 +16528,12 @@ const { URL: URL$b } = resolveServiceUrl();
16423
16528
  const { getOne: getOne$4 } = ServiceFactory.build({
16424
16529
  basePath: `${URL$b}/api/kos/state`
16425
16530
  });
16426
- const log$l = KosLog.createLogger({
16531
+ const log$m = KosLog.createLogger({
16427
16532
  name: "state-bean-service",
16428
16533
  group: "Services"
16429
16534
  });
16430
16535
  const getStateBeanData = async ({ path }) => {
16431
- log$l.debug("sending GET for state-bean");
16536
+ log$m.debug("sending GET for state-bean");
16432
16537
  const response = await getOne$4({
16433
16538
  urlOverride: `${URL$b}/api/kos/state/${path}`
16434
16539
  });
@@ -16621,12 +16726,12 @@ const { URL: URL$a } = resolveServiceUrl();
16621
16726
  const { getAll: getAll$5 } = ServiceFactory.build({
16622
16727
  basePath: `${URL$a}/api/state-prop`
16623
16728
  });
16624
- const log$k = KosLog.createLogger({
16729
+ const log$l = KosLog.createLogger({
16625
16730
  name: "state-prop-service",
16626
16731
  group: "Services"
16627
16732
  });
16628
16733
  const getStateProps = async () => {
16629
- log$k.debug("sending GET for state-prop");
16734
+ log$l.debug("sending GET for state-prop");
16630
16735
  const response = await getAll$5({});
16631
16736
  return response;
16632
16737
  };
@@ -16786,7 +16891,7 @@ var __decorateClass$u = (decorators, target, key, kind) => {
16786
16891
  if (kind && result) __defProp$p(target, key, result);
16787
16892
  return result;
16788
16893
  };
16789
- const log$j = KosLog.getLogger(FutureFactory.type);
16894
+ const log$k = KosLog.getLogger(FutureFactory.type);
16790
16895
  let FutureModel$1 = class FutureModel {
16791
16896
  logger;
16792
16897
  _cancelFuture;
@@ -16810,7 +16915,7 @@ let FutureModel$1 = class FutureModel {
16810
16915
  kosWhen(
16811
16916
  () => this.status === FutureEndState.Success || this.status === FutureEndState.Fail,
16812
16917
  () => {
16813
- log$j.info(`Future ${this.id} has completed with status ${this.status}`);
16918
+ log$k.info(`Future ${this.id} has completed with status ${this.status}`);
16814
16919
  destroyKosModel(this);
16815
16920
  }
16816
16921
  );
@@ -16824,13 +16929,13 @@ let FutureModel$1 = class FutureModel {
16824
16929
  * In future additional information about the workspace could be loaded
16825
16930
  */
16826
16931
  async load() {
16827
- log$j.debug(`loading Future ${this.id}`);
16932
+ log$k.debug(`loading Future ${this.id}`);
16828
16933
  }
16829
16934
  /**
16830
16935
  * @internal
16831
16936
  */
16832
16937
  unload() {
16833
- log$j.info(`unloading Future ${this.id}`);
16938
+ log$k.info(`unloading Future ${this.id}`);
16834
16939
  }
16835
16940
  // -------------------ACTIONS----------------------------
16836
16941
  /**
@@ -16849,7 +16954,7 @@ let FutureModel$1 = class FutureModel {
16849
16954
  await kosWhen(() => this.futureId !== FUTURE_NOT_ASSIGNED);
16850
16955
  const response = await this._cancelFuture(this.futureId, path);
16851
16956
  if (response?.status !== 200) {
16852
- log$j.error(
16957
+ log$k.error(
16853
16958
  `Failed to cancel Future ${this.id}. Response: ${JSON.stringify(
16854
16959
  response
16855
16960
  )}`
@@ -16938,7 +17043,7 @@ var __decorateClass$t = (decorators, target, key, kind) => {
16938
17043
  if (kind && result) __defProp$o(target, key, result);
16939
17044
  return result;
16940
17045
  };
16941
- const log$i = KosLog.getLogger(FutureContainerFactory.type);
17046
+ const log$j = KosLog.getLogger(FutureContainerFactory.type);
16942
17047
  let FutureContainerModel$1 = class FutureContainerModel {
16943
17048
  id;
16944
17049
  logger;
@@ -17053,8 +17158,8 @@ let FutureContainerModel$1 = class FutureContainerModel {
17053
17158
  try {
17054
17159
  await this._deleteFuture(id);
17055
17160
  } catch (e) {
17056
- log$i.error(`error deleting a Future`);
17057
- log$i.error(e);
17161
+ log$j.error(`error deleting a Future`);
17162
+ log$j.error(e);
17058
17163
  }
17059
17164
  }
17060
17165
  /**
@@ -17081,8 +17186,8 @@ let FutureContainerModel$1 = class FutureContainerModel {
17081
17186
  return model2;
17082
17187
  }
17083
17188
  } catch (e) {
17084
- log$i.error(`error creating a Future`);
17085
- log$i.error(e);
17189
+ log$j.error(`error creating a Future`);
17190
+ log$j.error(e);
17086
17191
  throw e;
17087
17192
  }
17088
17193
  return void 0;
@@ -17111,7 +17216,7 @@ const { URL: URL$9 } = resolveServiceUrl();
17111
17216
  const { getOne: getOne$3, postModel: postModel$3, deleteModel } = ServiceFactory.build({
17112
17217
  basePath: `${URL$9}/api/keyVal`
17113
17218
  });
17114
- const log$h = KosLog.createLogger({
17219
+ const log$i = KosLog.createLogger({
17115
17220
  name: "key-value-service",
17116
17221
  group: "Services"
17117
17222
  });
@@ -17127,7 +17232,7 @@ const updateKeyValue = async (namespace, key, value) => {
17127
17232
  model: value.toString()
17128
17233
  });
17129
17234
  if (response?.status !== 200) {
17130
- log$h.error("Failed to update key-value data", response);
17235
+ log$i.error("Failed to update key-value data", response);
17131
17236
  throw new Error(
17132
17237
  `Failed to update key-value data for namespace ${namespace}`
17133
17238
  );
@@ -17135,12 +17240,12 @@ const updateKeyValue = async (namespace, key, value) => {
17135
17240
  return response.data;
17136
17241
  };
17137
17242
  const getKeyValue = async (namespace = "studio") => {
17138
- log$h.debug(`Retrieving all key-value data for namespace: ${namespace}`);
17243
+ log$i.debug(`Retrieving all key-value data for namespace: ${namespace}`);
17139
17244
  const response = await getOne$3({
17140
17245
  urlOverride: `${URL$9}/api/keyVal/${namespace}`
17141
17246
  });
17142
17247
  if (response?.status !== 200) {
17143
- log$h.error("Failed to retrieve key-value data", response);
17248
+ log$i.error("Failed to retrieve key-value data", response);
17144
17249
  throw new Error(
17145
17250
  `Failed to retrieve key-value data for namespace ${namespace}`
17146
17251
  );
@@ -19211,13 +19316,13 @@ KosExpressionEvaluatorModelImpl = __decorateClass$r([
19211
19316
  kosModel({ modelTypeId: MODEL_TYPE$q, singleton: false })
19212
19317
  ], KosExpressionEvaluatorModelImpl);
19213
19318
  const KosExpressionEvaluator = KosExpressionEvaluatorModelImpl.Registration;
19214
- const log$g = KosLog.createLogger({
19319
+ const log$h = KosLog.createLogger({
19215
19320
  name: "kos-log-manager-service",
19216
19321
  group: "Services"
19217
19322
  });
19218
19323
  const SERVICE_PATH$2 = "/api/kos/logs/overrides";
19219
19324
  const getLogOverrides = async () => {
19220
- log$g.debug("sending GET for kos-log-manager");
19325
+ log$h.debug("sending GET for kos-log-manager");
19221
19326
  return await api$9.get(SERVICE_PATH$2);
19222
19327
  };
19223
19328
  const index$b = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
@@ -19626,7 +19731,7 @@ __decorateClass$o([
19626
19731
  LogBlockContainerModelImpl = __decorateClass$o([
19627
19732
  kosModel(MODEL_TYPE$n)
19628
19733
  ], LogBlockContainerModelImpl);
19629
- const log$f = KosLog.createLogger({
19734
+ const log$g = KosLog.createLogger({
19630
19735
  name: "log-stream-container-service",
19631
19736
  group: "Services"
19632
19737
  });
@@ -19640,7 +19745,7 @@ const getKosConnectionId$2 = () => {
19640
19745
  const destinationAddress$3 = getKosConnectionId$2();
19641
19746
  const SERVICE_PATH$1 = "/api/kos/logs/node/{nodeId}/streams";
19642
19747
  const getLogStreams = async () => {
19643
- log$f.debug("sending GET for log-stream-container");
19748
+ log$g.debug("sending GET for log-stream-container");
19644
19749
  return await api$9.get(
19645
19750
  SERVICE_PATH$1,
19646
19751
  {
@@ -20241,23 +20346,23 @@ const { URL: URL$7 } = resolveServiceUrl();
20241
20346
  const { getAll: getAll$4, postModel: postModel$1 } = ServiceFactory.build({
20242
20347
  basePath: `${URL$7}/api/kos/troubles`
20243
20348
  });
20244
- const log$e = KosLog.createLogger({ name: "trouble-services" });
20349
+ const log$f = KosLog.createLogger({ name: "trouble-services" });
20245
20350
  const getKosConnectionId$1 = () => {
20246
20351
  const params2 = getQueryParams();
20247
20352
  const connId = params2?.connId;
20248
- log$e.debug(`connId from query params: ${connId}`);
20249
- log$e.debug(
20353
+ log$f.debug(`connId from query params: ${connId}`);
20354
+ log$f.debug(
20250
20355
  `window.kosBridge: ${window?.kosBridge ? "available" : "not available"} - ${window?.kosBridge?.("connId")}`
20251
20356
  );
20252
20357
  const result = connId || window?.kosBridge?.("connId");
20253
- log$e.info(`getKosConnectionId: ${result}`);
20358
+ log$f.info(`getKosConnectionId: ${result}`);
20254
20359
  return result;
20255
20360
  };
20256
20361
  const destinationAddress$2 = getKosConnectionId$1();
20257
- log$e.info(`Destination address for trouble services: ${destinationAddress$2}`);
20362
+ log$f.info(`Destination address for trouble services: ${destinationAddress$2}`);
20258
20363
  const getTroubles = async (servicePath) => {
20259
20364
  const isKosTroubles = servicePath.includes("/kos/troubles");
20260
- log$e.info(
20365
+ log$f.info(
20261
20366
  `Fetching troubles from ${servicePath} with destination address: ${isKosTroubles ? destinationAddress$2 : "N/A (not a kos troubles path)"}`
20262
20367
  );
20263
20368
  const response = await getAll$4({
@@ -20771,16 +20876,16 @@ const { URL: URL$6 } = resolveServiceUrl();
20771
20876
  const { getAll: getAll$3 } = ServiceFactory.build({
20772
20877
  basePath: `${URL$6}/api/kos/ota`
20773
20878
  });
20774
- const log$d = KosLog.createLogger({
20879
+ const log$e = KosLog.createLogger({
20775
20880
  name: "ota-service",
20776
20881
  group: "Services"
20777
20882
  });
20778
20883
  const getArtifacts = async () => {
20779
- log$d.debug("sending GET request to /api/kos/ota/artifacts");
20884
+ log$e.debug("sending GET request to /api/kos/ota/artifacts");
20780
20885
  const response = await getAll$3({
20781
20886
  urlOverride: `${URL$6}/api/kos/ota/artifacts`
20782
20887
  });
20783
- log$d.debug("getArtifacts - response:", response);
20888
+ log$e.debug("getArtifacts - response:", response);
20784
20889
  return response?.data;
20785
20890
  };
20786
20891
  var __defProp$e = Object.defineProperty;
@@ -20964,7 +21069,7 @@ const Ota = new SingletonKosModelRegistrationFactory({
20964
21069
  class: OtaModelImpl,
20965
21070
  type: MODEL_TYPE$h
20966
21071
  });
20967
- const log$c = KosLog.createLogger({ name: "await-future-call", group: "Models" });
21072
+ const log$d = KosLog.createLogger({ name: "await-future-call", group: "Models" });
20968
21073
  class FutureCallError extends Error {
20969
21074
  endState;
20970
21075
  reason;
@@ -21015,7 +21120,7 @@ function awaitFutureCall(model, methodCall, options = {}) {
21015
21120
  const watchTracked = (future) => {
21016
21121
  tracked = future;
21017
21122
  if (cancelRequested) {
21018
- future.cancelFuture().catch((e) => log$c.error(e));
21123
+ future.cancelFuture().catch((e) => log$d.error(e));
21019
21124
  }
21020
21125
  disposers.push(
21021
21126
  mobx.reaction(
@@ -21032,7 +21137,7 @@ function awaitFutureCall(model, methodCall, options = {}) {
21032
21137
  try {
21033
21138
  cb(progress, status);
21034
21139
  } catch (e) {
21035
- log$c.warn("progress callback error", e);
21140
+ log$d.warn("progress callback error", e);
21036
21141
  }
21037
21142
  });
21038
21143
  },
@@ -23647,9 +23752,9 @@ const { URL: URL$5 } = resolveServiceUrl();
23647
23752
  const { getOne: getOne$1 } = ServiceFactory.build({
23648
23753
  basePath: `${URL$5}/api/device`
23649
23754
  });
23650
- const log$b = KosLog.createLogger({ name: "device-service", group: "Services" });
23755
+ const log$c = KosLog.createLogger({ name: "device-service", group: "Services" });
23651
23756
  const getSerialNumber = async () => {
23652
- log$b.debug("sending GET for device serial number");
23757
+ log$c.debug("sending GET for device serial number");
23653
23758
  try {
23654
23759
  const response = await getOne$1({
23655
23760
  urlOverride: `${URL$5}/api/kos/device/serialNumber`
@@ -23657,14 +23762,14 @@ const getSerialNumber = async () => {
23657
23762
  return [void 0, response?.data.serialNumber];
23658
23763
  } catch (error) {
23659
23764
  if (error instanceof FetchError) {
23660
- log$b.error(`Error fetching device serial number: ${error.payload.error}`);
23765
+ log$c.error(`Error fetching device serial number: ${error.payload.error}`);
23661
23766
  return [error.payload.error, void 0];
23662
23767
  }
23663
23768
  }
23664
23769
  return ["unknownError", void 0];
23665
23770
  };
23666
23771
  const getDeviceDetails = async () => {
23667
- log$b.debug("sending GET for device details");
23772
+ log$c.debug("sending GET for device details");
23668
23773
  try {
23669
23774
  const response = await getOne$1({
23670
23775
  urlOverride: `${URL$5}/api/kos/device`
@@ -23675,7 +23780,7 @@ const getDeviceDetails = async () => {
23675
23780
  return [void 0, response.data];
23676
23781
  } catch (error) {
23677
23782
  if (error instanceof FetchError) {
23678
- log$b.error(`Error fetching device serial number: ${error.payload.error}`);
23783
+ log$c.error(`Error fetching device serial number: ${error.payload.error}`);
23679
23784
  return [error.payload.error, void 0];
23680
23785
  }
23681
23786
  }
@@ -24010,12 +24115,12 @@ const { getAll: getAll$2 } = ServiceFactory.build({
24010
24115
  basePath: `${URL$4}/api/kos/network/interfaces`
24011
24116
  });
24012
24117
  const destinationAddress$1 = getKosConnectionId();
24013
- const log$a = KosLog.createLogger({
24118
+ const log$b = KosLog.createLogger({
24014
24119
  name: "network-interface-service",
24015
24120
  group: "Services"
24016
24121
  });
24017
24122
  const getNetworkInterfaces = async () => {
24018
- log$a.debug("sending GET for copy-logs");
24123
+ log$b.debug("sending GET for copy-logs");
24019
24124
  try {
24020
24125
  const response = await getAll$2({
24021
24126
  destinationAddress: destinationAddress$1
@@ -24023,7 +24128,7 @@ const getNetworkInterfaces = async () => {
24023
24128
  return [void 0, response?.data];
24024
24129
  } catch (error) {
24025
24130
  if (error instanceof FetchError) {
24026
- log$a.error(`Error fetching log file size: ${error.payload.error}`);
24131
+ log$b.error(`Error fetching log file size: ${error.payload.error}`);
24027
24132
  return [error.payload.error, void 0];
24028
24133
  }
24029
24134
  }
@@ -24125,15 +24230,15 @@ const { URL: URL$3 } = resolveServiceUrl();
24125
24230
  const { getAll: getAll$1 } = ServiceFactory.build({
24126
24231
  basePath: `${URL$3}/api/kos/storage/devices`
24127
24232
  });
24128
- const log$9 = KosLog.createLogger({
24233
+ const log$a = KosLog.createLogger({
24129
24234
  name: "storage-device-service",
24130
24235
  group: "Services"
24131
24236
  });
24132
24237
  const getStorageDevices = async () => {
24133
- log$9.debug("sending GET for storage-device");
24238
+ log$a.debug("sending GET for storage-device");
24134
24239
  const response = await getAll$1({});
24135
24240
  if (!response?.data || response.status !== 200) {
24136
- log$9.error("Failed to retrieve storage-device data", response);
24241
+ log$a.error("Failed to retrieve storage-device data", response);
24137
24242
  return [];
24138
24243
  }
24139
24244
  return response.data;
@@ -24335,17 +24440,17 @@ const { URL: URL$2 } = resolveServiceUrl();
24335
24440
  const { getAll, postModel } = ServiceFactory.build({
24336
24441
  basePath: `${URL$2}/api/kos/update/available`
24337
24442
  });
24338
- const log$8 = KosLog.createLogger({
24443
+ const log$9 = KosLog.createLogger({
24339
24444
  name: "usb-update-service",
24340
24445
  group: "Services"
24341
24446
  });
24342
24447
  const getAvailableUpdates = async () => {
24343
- log$8.debug("sending GET for usb-update");
24448
+ log$9.debug("sending GET for usb-update");
24344
24449
  const response = await getAll({
24345
24450
  urlOverride: `${URL$2}/api/kos/update/available`
24346
24451
  });
24347
24452
  if (!response?.data || response?.status !== 200) {
24348
- log$8.error("Failed to retrieve usb-update data", response);
24453
+ log$9.error("Failed to retrieve usb-update data", response);
24349
24454
  return [];
24350
24455
  }
24351
24456
  return response.data;
@@ -24564,7 +24669,7 @@ const { URL: URL$1 } = resolveServiceUrl();
24564
24669
  const { getOne } = ServiceFactory.build({
24565
24670
  basePath: `${URL$1}/api/translation`
24566
24671
  });
24567
- const log$7 = KosLog.createLogger({
24672
+ const log$8 = KosLog.createLogger({
24568
24673
  name: "translation-service",
24569
24674
  group: "Services"
24570
24675
  });
@@ -24576,23 +24681,23 @@ const getDefaultHost$1 = () => {
24576
24681
  return result;
24577
24682
  };
24578
24683
  const getTranslations = async (url, root) => {
24579
- log$7.debug(`Loading translations from: ${url}`);
24684
+ log$8.debug(`Loading translations from: ${url}`);
24580
24685
  const rootUrl = root ?? getDefaultHost$1();
24581
24686
  try {
24582
24687
  const response = await fetch(`${rootUrl}${url}`);
24583
24688
  if (response.status !== 200) {
24584
- log$7.warn(`Failed to fetch translations at ${url}: ${response.status}`);
24689
+ log$8.warn(`Failed to fetch translations at ${url}: ${response.status}`);
24585
24690
  return {};
24586
24691
  }
24587
24692
  const json = await response.json();
24588
24693
  return json;
24589
24694
  } catch (error) {
24590
- log$7.error("Error fetching translations", error);
24695
+ log$8.error("Error fetching translations", error);
24591
24696
  throw error;
24592
24697
  }
24593
24698
  };
24594
24699
  const getLocalizationDescriptor = async () => {
24595
- log$7.debug("Getting system localization descriptor");
24700
+ log$8.debug("Getting system localization descriptor");
24596
24701
  const response = await getOne({
24597
24702
  urlOverride: `${URL$1}/api/system/kos/localization`
24598
24703
  });
@@ -24604,7 +24709,7 @@ const getLocalizationDescriptor = async () => {
24604
24709
  return response.data;
24605
24710
  };
24606
24711
  const getKosLocalizationDescriptor = (context) => async () => {
24607
- log$7.debug(`Getting KOS localization descriptor for context: ${context}`);
24712
+ log$8.debug(`Getting KOS localization descriptor for context: ${context}`);
24608
24713
  const response = await getOne({
24609
24714
  urlOverride: `${URL$1}/api/kos/localization/contexts`
24610
24715
  });
@@ -25434,7 +25539,7 @@ const service = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
25434
25539
  const TIMER_EVENT = `/kos-timer-event`;
25435
25540
  const TOPIC_TIMER_TICK_EVENT = `/kos-timer-event/tick`;
25436
25541
  const TIMER_END = "defaultTimerEnd";
25437
- const log$6 = KosLog.createLogger({ name: "timer-manager" });
25542
+ const log$7 = KosLog.createLogger({ name: "timer-manager" });
25438
25543
  const isConfigProperty = (value) => value.updateProperty !== void 0;
25439
25544
  class KosTimer {
25440
25545
  name;
@@ -25482,7 +25587,7 @@ class KosTimer {
25482
25587
  */
25483
25588
  start() {
25484
25589
  if (this.state === "active") {
25485
- log$6.debug(`Timer ${this.name} already started`);
25590
+ log$7.debug(`Timer ${this.name} already started`);
25486
25591
  return;
25487
25592
  }
25488
25593
  if (this.state === "inactive" || this.state === "paused") {
@@ -25495,7 +25600,7 @@ class KosTimer {
25495
25600
  */
25496
25601
  pause() {
25497
25602
  if (this.timer) {
25498
- log$6.debug(`Pausing timer ${this.name}`);
25603
+ log$7.debug(`Pausing timer ${this.name}`);
25499
25604
  this.state = "paused";
25500
25605
  clearInterval(this.timer);
25501
25606
  }
@@ -25577,11 +25682,11 @@ class KosTimer {
25577
25682
  executeActions(time) {
25578
25683
  if (this.timeoutActions.has(time)) {
25579
25684
  this.timeoutActions.get(time).forEach((timerAction) => {
25580
- log$6.debug(`Executing timer action ${timerAction.name} at ${time}`);
25685
+ log$7.debug(`Executing timer action ${timerAction.name} at ${time}`);
25581
25686
  timerAction.action?.(timerAction.name, time);
25582
25687
  this.notifyTimeoutAction(timerAction);
25583
25688
  if (timerAction.singleUse) {
25584
- log$6.info(
25689
+ log$7.info(
25585
25690
  `${this.name} Removing single-use action ${timerAction.name}`
25586
25691
  );
25587
25692
  this.removeTimeoutAction(timerAction.name);
@@ -25612,7 +25717,7 @@ const timers = /* @__PURE__ */ new Map();
25612
25717
  const executeOnTimer = (name, action) => {
25613
25718
  const timer = timers.get(name);
25614
25719
  if (!timer) {
25615
- log$6.error(`Timer ${name} not found`);
25720
+ log$7.error(`Timer ${name} not found`);
25616
25721
  return;
25617
25722
  }
25618
25723
  action(timer);
@@ -25709,23 +25814,23 @@ const updateTimeZone = async (timezone) => {
25709
25814
  await whenReady(timezoneInfo);
25710
25815
  timezoneInfo.updateProperty(timezone);
25711
25816
  };
25712
- const log$5 = KosLog.createLogger({
25817
+ const log$6 = KosLog.createLogger({
25713
25818
  name: "software-info-service",
25714
25819
  group: "Services"
25715
25820
  });
25716
25821
  const destinationAddress = getKosConnectionId();
25717
25822
  const getSoftwareInfos = async (signal) => {
25718
- log$5.debug("sending GET for software-info");
25823
+ log$6.debug("sending GET for software-info");
25719
25824
  const [error, response] = await api$8.get("/api/kos/manifest/info", void 0, {
25720
25825
  signal,
25721
25826
  destinationAddress
25722
25827
  });
25723
25828
  if (!response) {
25724
25829
  if (signal?.aborted) {
25725
- log$5.debug("Request was aborted");
25830
+ log$6.debug("Request was aborted");
25726
25831
  throw new FetchError("Request was aborted");
25727
25832
  }
25728
- log$5.error("Failed to fetch software-info", error);
25833
+ log$6.error("Failed to fetch software-info", error);
25729
25834
  throw new FetchError("Failed to fetch software-info");
25730
25835
  }
25731
25836
  return response;
@@ -25824,7 +25929,7 @@ const SoftwareInfo = {
25824
25929
  function isTroubleAware(obj) {
25825
25930
  return obj?.troubles !== void 0 && obj?.troubles instanceof Array && obj?.troublesByType !== void 0 && typeof obj?.troublesByType === "object";
25826
25931
  }
25827
- const log$4 = KosLog.createLogger({ name: "services", group: "Services" });
25932
+ const log$5 = KosLog.createLogger({ name: "services", group: "Services" });
25828
25933
  const studioLogin = async (username, password) => login(username, password, `${exports.BASE_URL}/api/server/login`);
25829
25934
  const login = async (username, password, url = `${exports.BASE_URL}/api/login`) => {
25830
25935
  const response = await exports.kosFetch(`${url}`, {
@@ -25858,7 +25963,7 @@ const startPasswordReset = async (userId, url = `${exports.BASE_URL}/api/startPa
25858
25963
  };
25859
25964
  const studioResetPassword = async (token2, password) => resetPassword(token2, password, `${exports.BASE_URL}/api/server/resetPassword`);
25860
25965
  const resetPassword = async (token2, password, url = `${exports.BASE_URL}/api/resetPassword`) => {
25861
- log$4.debug(
25966
+ log$5.debug(
25862
25967
  `resetting password with token ${token2} and password ${password.replace(
25863
25968
  /./g,
25864
25969
  "*"
@@ -25872,9 +25977,9 @@ const resetPassword = async (token2, password, url = `${exports.BASE_URL}/api/re
25872
25977
  password
25873
25978
  })
25874
25979
  });
25875
- log$4.debug(`password reset returned status ${response.status}`);
25980
+ log$5.debug(`password reset returned status ${response.status}`);
25876
25981
  if (!response.ok) {
25877
- log$4.error(`password reset failed with message ${response.statusText}`);
25982
+ log$5.error(`password reset failed with message ${response.statusText}`);
25878
25983
  const configResponse2 = await response.json();
25879
25984
  throw Error(
25880
25985
  `${configResponse2?.error}:There was a problem resetting the password.`
@@ -25890,7 +25995,7 @@ const studioAcceptOrgInvitation = async (token2, password, name) => acceptOrgInv
25890
25995
  `${exports.BASE_URL}/api/server/acceptInvite`
25891
25996
  );
25892
25997
  const acceptOrgInvitation = async (token2, password, name, url = `${exports.BASE_URL}/api/server/acceptInvite`) => {
25893
- log$4.debug(
25998
+ log$5.debug(
25894
25999
  `accepting invite with token ${token2} and password ${password.replace(
25895
26000
  /./g,
25896
26001
  "*"
@@ -25905,9 +26010,9 @@ const acceptOrgInvitation = async (token2, password, name, url = `${exports.BASE
25905
26010
  name
25906
26011
  })
25907
26012
  });
25908
- log$4.debug(`invitation accept returned status ${response.status}`);
26013
+ log$5.debug(`invitation accept returned status ${response.status}`);
25909
26014
  if (!response.ok) {
25910
- log$4.error(`invite failed with message ${response.statusText}`);
26015
+ log$5.error(`invite failed with message ${response.statusText}`);
25911
26016
  const configResponse2 = await response.json();
25912
26017
  throw Error(
25913
26018
  `${configResponse2?.error}:There was a problem accepting the invite.`
@@ -26213,15 +26318,15 @@ GpioChipContainerModelImpl = __decorateClass$1([
26213
26318
  ], GpioChipContainerModelImpl);
26214
26319
  const GpioChipContainer = GpioChipContainerModelImpl.Registration;
26215
26320
  GpioChipContainer.addRelatedModel(GpioChip);
26216
- const log$3 = KosLog.createLogger({
26321
+ const log$4 = KosLog.createLogger({
26217
26322
  name: "studio-properties-service",
26218
26323
  group: "Services"
26219
26324
  });
26220
26325
  const SERVICE_PATH = "/api/kos/studio/properties";
26221
26326
  const getStudioProperties = async (connectionId) => {
26222
- log$3.debug("sending GET for studio-properties");
26327
+ log$4.debug("sending GET for studio-properties");
26223
26328
  if (!connectionId) {
26224
- log$3.error("connectionId is undefined");
26329
+ log$4.error("connectionId is undefined");
26225
26330
  throw new Error("connectionId is undefined");
26226
26331
  }
26227
26332
  return await api$9.get(
@@ -26387,25 +26492,41 @@ const MessageContainer = styled.div`
26387
26492
  color: ${({ theme }) => theme === "light" ? "black" : "white"};
26388
26493
  z-index: 10000;
26389
26494
  `;
26495
+ const log$3 = KosLog.createLogger({ name: "error-boundary" });
26390
26496
  class ErrorBoundary extends React.Component {
26391
26497
  constructor(props) {
26392
26498
  super(props);
26393
26499
  this.state = { error: null, errorInfo: null };
26394
26500
  }
26501
+ /**
26502
+ * Recovers during the render phase. Without this React renders the boundary
26503
+ * with `null` children and waits for `componentDidCatch` to schedule a
26504
+ * fallback, and a second error in the same batch escalates past the boundary
26505
+ * to the root, unmounting the whole tree.
26506
+ */
26507
+ static getDerivedStateFromError(error) {
26508
+ return { error };
26509
+ }
26395
26510
  componentDidCatch(error, errorInfo) {
26511
+ const seam = this.props.name ? ` in ${this.props.name}` : "";
26512
+ log$3.error(
26513
+ `Error boundary caught${seam}: ${error?.message ?? error}`,
26514
+ error,
26515
+ errorInfo.componentStack
26516
+ );
26396
26517
  this.setState({
26397
26518
  error,
26398
26519
  errorInfo
26399
26520
  });
26400
26521
  }
26401
26522
  render() {
26402
- if (this.state.errorInfo) {
26523
+ if (this.state.error) {
26403
26524
  return this.props.fallback || /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
26404
26525
  /* @__PURE__ */ jsxRuntime.jsx("h2", { children: "Something went wrong." }),
26405
26526
  /* @__PURE__ */ jsxRuntime.jsxs("details", { style: { whiteSpace: `pre-wrap` }, children: [
26406
- this.state.error && this.state.error.toString(),
26527
+ this.state.error.toString(),
26407
26528
  /* @__PURE__ */ jsxRuntime.jsx("br", {}),
26408
- this.state.errorInfo.componentStack
26529
+ this.state.errorInfo?.componentStack
26409
26530
  ] })
26410
26531
  ] });
26411
26532
  }
@@ -26800,33 +26921,32 @@ const waitForRetry = (depth = 0) => new Promise((resolve) => {
26800
26921
  resolve(true);
26801
26922
  }, 2 ** depth * 10);
26802
26923
  });
26803
- const cache$1 = /* @__PURE__ */ new Map();
26804
- function fetchData$1(key, fetcher) {
26805
- if (cache$1.has(key)) {
26806
- const entry = cache$1.get(key);
26924
+ function readModelHookEntry(key, fetcher) {
26925
+ const entry = modelHookCache.get(key);
26926
+ if (entry) {
26807
26927
  if (entry.status === "finished") {
26808
26928
  const kosModel2 = KosCore.getInstance().modelManager.getModelById(key);
26809
26929
  return { kosModel: kosModel2, model: kosModel2?.modelData };
26810
- } else {
26811
- throw entry.promise;
26812
26930
  }
26813
- } else {
26814
- const promise = fetcher().then(
26815
- () => {
26816
- cache$1.set(key, { status: "finished", key });
26817
- },
26818
- (error) => {
26819
- cache$1.set(key, { status: "error", error });
26820
- throw error;
26821
- }
26822
- );
26823
- const entry = { status: "pending", promise };
26824
- cache$1.set(key, entry);
26825
- throw promise;
26931
+ if (entry.status === "error") {
26932
+ throw entry.error;
26933
+ }
26934
+ throw entry.promise;
26826
26935
  }
26936
+ const promise = fetcher().then(
26937
+ () => {
26938
+ modelHookCache.set(key, { status: "finished", key });
26939
+ },
26940
+ (error) => {
26941
+ modelHookCache.set(key, { status: "error", error });
26942
+ throw error;
26943
+ }
26944
+ );
26945
+ modelHookCache.set(key, { status: "pending", promise });
26946
+ throw promise;
26827
26947
  }
26828
26948
  function useSuspenseData$1(key, fetcher) {
26829
- const data = fetchData$1(key, fetcher);
26949
+ const data = readModelHookEntry(key, fetcher);
26830
26950
  return data;
26831
26951
  }
26832
26952
  async function fetchModel$1(kosCore, modelOptions) {
@@ -26914,7 +27034,7 @@ const useKosModel = (modelOptions) => {
26914
27034
  if (destroyOnUnmount) {
26915
27035
  const modelId2 = model.id;
26916
27036
  destroyKosModel(model).then(() => {
26917
- cache$1.delete(modelId2);
27037
+ clearModelHookCacheEntry(modelId2);
26918
27038
  disposer?.();
26919
27039
  });
26920
27040
  }
@@ -26923,7 +27043,7 @@ const useKosModel = (modelOptions) => {
26923
27043
  } else {
26924
27044
  if (destroyOnUnmount && model) {
26925
27045
  destroyKosModel(model).then(() => {
26926
- cache$1.delete(modelId);
27046
+ clearModelHookCacheEntry(modelId);
26927
27047
  disposer?.();
26928
27048
  });
26929
27049
  }
@@ -27541,9 +27661,11 @@ function fetchData(key, fetcher) {
27541
27661
  const entry = cache.get(key);
27542
27662
  if (entry.status === "finished") {
27543
27663
  return entry.result;
27544
- } else {
27545
- throw entry.promise;
27546
27664
  }
27665
+ if (entry.status === "error") {
27666
+ throw entry.error;
27667
+ }
27668
+ throw entry.promise;
27547
27669
  } else {
27548
27670
  const promise = fetcher().then(
27549
27671
  (result) => {
@@ -29205,6 +29327,7 @@ exports.cancelFuture = cancelFuture;
29205
29327
  exports.checkAppsStarted = checkAppsStarted;
29206
29328
  exports.checkWildcardPattern = checkWildcardPattern;
29207
29329
  exports.clearAllServiceResponses = clearAllServiceResponses;
29330
+ exports.clearModelHookCacheEntry = clearModelHookCacheEntry;
29208
29331
  exports.clearPath = clearPath;
29209
29332
  exports.clearServiceResponse = clearServiceResponse;
29210
29333
  exports.convert = convert;
@@ -29359,6 +29482,7 @@ exports.mapDtoToFutureOptions = mapDtoToFutureOptions;
29359
29482
  exports.mapUpdateDtoToConfigBeanModel = mapUpdateDtoToConfigBeanModel;
29360
29483
  exports.modelEventTopicFactory = modelEventTopicFactory;
29361
29484
  exports.modelFactory = modelFactory;
29485
+ exports.modelHookCache = modelHookCache;
29362
29486
  exports.modelTypeEventTopicFactory = modelTypeEventTopicFactory;
29363
29487
  exports.modifyConfigBean = modifyConfigBean;
29364
29488
  exports.modifyFuture = modifyFuture;
@@ -29370,6 +29494,7 @@ exports.preloadKosModel = preloadKosModel;
29370
29494
  exports.processId = processId;
29371
29495
  exports.processMiddleware = processMiddleware;
29372
29496
  exports.put = put;
29497
+ exports.readModelHookEntry = readModelHookEntry;
29373
29498
  exports.registerCompanionModel = registerCompanionModel;
29374
29499
  exports.registerCoreModels = registerCoreModels;
29375
29500
  exports.registerExtensionPoint = registerExtensionPoint;