@kosdev-code/kos-ui-sdk 0.1.0-next.850 → 0.1.0-next.852

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.js CHANGED
@@ -4190,6 +4190,33 @@ class KosDependencyManager {
4190
4190
  uses.filter((id) => id !== dependencyId)
4191
4191
  );
4192
4192
  }
4193
+ /**
4194
+ * Drops every edge into and out of a model. Called when the model is
4195
+ * destroyed, so its dependencies are not left pinned by a model that is
4196
+ * gone and can never release them.
4197
+ */
4198
+ removeAll(modelId) {
4199
+ for (const dependencyId of this._usesCache.get(modelId) ?? []) {
4200
+ const usedBy = this._usedByCache.get(dependencyId);
4201
+ if (usedBy) {
4202
+ this._usedByCache.set(
4203
+ dependencyId,
4204
+ usedBy.filter((id) => id !== modelId)
4205
+ );
4206
+ }
4207
+ }
4208
+ this._usesCache.delete(modelId);
4209
+ for (const dependentId of this._usedByCache.get(modelId) ?? []) {
4210
+ const uses = this._usesCache.get(dependentId);
4211
+ if (uses) {
4212
+ this._usesCache.set(
4213
+ dependentId,
4214
+ uses.filter((id) => id !== modelId)
4215
+ );
4216
+ }
4217
+ }
4218
+ this._usedByCache.delete(modelId);
4219
+ }
4193
4220
  canDestroy(modelId) {
4194
4221
  const usedBy = this._usedByCache.get(modelId);
4195
4222
  if (usedBy?.length) {
@@ -4267,6 +4294,19 @@ class KosModelCache {
4267
4294
  return this._preloaded;
4268
4295
  }
4269
4296
  }
4297
+ const cache$1 = /* @__PURE__ */ new Map();
4298
+ const modelHookCache = {
4299
+ has: (key) => cache$1.has(key),
4300
+ get: (key) => cache$1.get(key),
4301
+ set: (key, entry) => cache$1.set(key, entry),
4302
+ delete: (key) => cache$1.delete(key),
4303
+ clear: () => cache$1.clear()
4304
+ };
4305
+ const clearModelHookCacheEntry = (modelId) => {
4306
+ if (modelId) {
4307
+ cache$1.delete(modelId);
4308
+ }
4309
+ };
4270
4310
  class KosModelError extends Error {
4271
4311
  context;
4272
4312
  originalCause;
@@ -8335,6 +8375,7 @@ class KosMockRecorder {
8335
8375
  pending = /* @__PURE__ */ new Map();
8336
8376
  exchanges = [];
8337
8377
  pushes = [];
8378
+ sends = [];
8338
8379
  get isRecording() {
8339
8380
  return this.recording;
8340
8381
  }
@@ -8346,6 +8387,7 @@ class KosMockRecorder {
8346
8387
  this.pending.clear();
8347
8388
  this.exchanges = [];
8348
8389
  this.pushes = [];
8390
+ this.sends = [];
8349
8391
  KosLog.info(
8350
8392
  `KosMock recorder started${options.name ? ` (${options.name})` : ""}`
8351
8393
  );
@@ -8354,7 +8396,7 @@ class KosMockRecorder {
8354
8396
  const fixture = this.toFixture();
8355
8397
  this.recording = false;
8356
8398
  KosLog.info(
8357
- `KosMock recorder stopped: ${fixture.exchanges.length} exchanges, ${fixture.pushes.length} pushes`
8399
+ `KosMock recorder stopped: ${fixture.exchanges.length} exchanges, ${fixture.pushes.length} pushes, ${fixture.sends?.length ?? 0} sends`
8358
8400
  );
8359
8401
  return fixture;
8360
8402
  }
@@ -8364,7 +8406,8 @@ class KosMockRecorder {
8364
8406
  name: this.name,
8365
8407
  capturedAt: this.capturedAt,
8366
8408
  exchanges: [...this.exchanges],
8367
- pushes: [...this.pushes]
8409
+ pushes: [...this.pushes],
8410
+ sends: [...this.sends]
8368
8411
  };
8369
8412
  }
8370
8413
  download(filename) {
@@ -8393,6 +8436,7 @@ class KosMockRecorder {
8393
8436
  }
8394
8437
  const frame = decodeRequestFrame(data);
8395
8438
  if (!frame) {
8439
+ this.noteSend(data);
8396
8440
  return;
8397
8441
  }
8398
8442
  this.pending.set(frame.requestId, {
@@ -8400,7 +8444,31 @@ class KosMockRecorder {
8400
8444
  method: frame.method,
8401
8445
  url: frame.url,
8402
8446
  tracker: frame.tracker,
8403
- requestBody: frame.rawBody
8447
+ requestBody: frame.rawBody,
8448
+ requestHeaders: frame.headers
8449
+ });
8450
+ }
8451
+ /**
8452
+ * Everything else a window sends: alias registration, broker subscribes,
8453
+ * client-sent futures. What a window asked for is not recoverable from the
8454
+ * responses it got back, so it is captured rather than discarded.
8455
+ */
8456
+ noteSend(data) {
8457
+ if (typeof data !== "string") {
8458
+ return;
8459
+ }
8460
+ let headers;
8461
+ let body;
8462
+ try {
8463
+ ({ headers, body } = processKosMessage(data));
8464
+ } catch {
8465
+ return;
8466
+ }
8467
+ this.sends.push({
8468
+ tMs: this.elapsed(),
8469
+ type: headers["type"],
8470
+ headers,
8471
+ ...body ? { body } : {}
8404
8472
  });
8405
8473
  }
8406
8474
  /** Interceptor tap: every inbound frame (real, mocked, injected). Internal. */
@@ -8426,6 +8494,7 @@ class KosMockRecorder {
8426
8494
  ...request2,
8427
8495
  status: parseInt(headers["status"] ?? "200", 10) || 200,
8428
8496
  responseBody: body ?? "",
8497
+ responseHeaders: headers,
8429
8498
  latencyMs: Math.max(0, this.elapsed() - request2.tMs),
8430
8499
  ...headers[KOS_MOCKED_HEADER] === "true" ? { mocked: true } : {}
8431
8500
  });
@@ -8437,7 +8506,8 @@ class KosMockRecorder {
8437
8506
  tMs: this.elapsed(),
8438
8507
  kind: "topic",
8439
8508
  topic,
8440
- body: body ?? ""
8509
+ body: body ?? "",
8510
+ headers
8441
8511
  });
8442
8512
  return;
8443
8513
  }
@@ -8451,7 +8521,8 @@ class KosMockRecorder {
8451
8521
  tMs: this.elapsed(),
8452
8522
  kind: "future",
8453
8523
  tracker,
8454
- body: body ?? ""
8524
+ body: body ?? "",
8525
+ headers
8455
8526
  });
8456
8527
  }
8457
8528
  }
@@ -11742,6 +11813,8 @@ class KosModelManager {
11742
11813
  if (model?.modelId && this.dependencies.canDestroy(model.modelId)) {
11743
11814
  await model.unload?.();
11744
11815
  this.removeModel(model);
11816
+ this.dependencies.removeAll(model.modelId);
11817
+ clearModelHookCacheEntry(model.modelId);
11745
11818
  }
11746
11819
  }
11747
11820
  /**
@@ -26821,33 +26894,32 @@ const waitForRetry = (depth = 0) => new Promise((resolve) => {
26821
26894
  resolve(true);
26822
26895
  }, 2 ** depth * 10);
26823
26896
  });
26824
- const cache$1 = /* @__PURE__ */ new Map();
26825
- function fetchData$1(key, fetcher) {
26826
- if (cache$1.has(key)) {
26827
- const entry = cache$1.get(key);
26897
+ function readModelHookEntry(key, fetcher) {
26898
+ const entry = modelHookCache.get(key);
26899
+ if (entry) {
26828
26900
  if (entry.status === "finished") {
26829
26901
  const kosModel2 = KosCore.getInstance().modelManager.getModelById(key);
26830
26902
  return { kosModel: kosModel2, model: kosModel2?.modelData };
26831
- } else {
26832
- throw entry.promise;
26833
26903
  }
26834
- } else {
26835
- const promise = fetcher().then(
26836
- () => {
26837
- cache$1.set(key, { status: "finished", key });
26838
- },
26839
- (error) => {
26840
- cache$1.set(key, { status: "error", error });
26841
- throw error;
26842
- }
26843
- );
26844
- const entry = { status: "pending", promise };
26845
- cache$1.set(key, entry);
26846
- throw promise;
26904
+ if (entry.status === "error") {
26905
+ throw entry.error;
26906
+ }
26907
+ throw entry.promise;
26847
26908
  }
26909
+ const promise = fetcher().then(
26910
+ () => {
26911
+ modelHookCache.set(key, { status: "finished", key });
26912
+ },
26913
+ (error) => {
26914
+ modelHookCache.set(key, { status: "error", error });
26915
+ throw error;
26916
+ }
26917
+ );
26918
+ modelHookCache.set(key, { status: "pending", promise });
26919
+ throw promise;
26848
26920
  }
26849
26921
  function useSuspenseData$1(key, fetcher) {
26850
- const data = fetchData$1(key, fetcher);
26922
+ const data = readModelHookEntry(key, fetcher);
26851
26923
  return data;
26852
26924
  }
26853
26925
  async function fetchModel$1(kosCore, modelOptions) {
@@ -26935,7 +27007,7 @@ const useKosModel = (modelOptions) => {
26935
27007
  if (destroyOnUnmount) {
26936
27008
  const modelId2 = model.id;
26937
27009
  destroyKosModel(model).then(() => {
26938
- cache$1.delete(modelId2);
27010
+ clearModelHookCacheEntry(modelId2);
26939
27011
  disposer?.();
26940
27012
  });
26941
27013
  }
@@ -26944,7 +27016,7 @@ const useKosModel = (modelOptions) => {
26944
27016
  } else {
26945
27017
  if (destroyOnUnmount && model) {
26946
27018
  destroyKosModel(model).then(() => {
26947
- cache$1.delete(modelId);
27019
+ clearModelHookCacheEntry(modelId);
26948
27020
  disposer?.();
26949
27021
  });
26950
27022
  }
@@ -29217,6 +29289,7 @@ export {
29217
29289
  checkAppsStarted,
29218
29290
  checkWildcardPattern,
29219
29291
  clearAllServiceResponses,
29292
+ clearModelHookCacheEntry,
29220
29293
  clearPath,
29221
29294
  clearServiceResponse,
29222
29295
  convert,
@@ -29375,6 +29448,7 @@ export {
29375
29448
  mapUpdateDtoToConfigBeanModel,
29376
29449
  modelEventTopicFactory,
29377
29450
  modelFactory,
29451
+ modelHookCache,
29378
29452
  modelTypeEventTopicFactory,
29379
29453
  modifyConfigBean,
29380
29454
  modifyFuture,
@@ -29386,6 +29460,7 @@ export {
29386
29460
  processId,
29387
29461
  processMiddleware,
29388
29462
  put,
29463
+ readModelHookEntry,
29389
29464
  registerCompanionModel,
29390
29465
  registerCoreModels,
29391
29466
  registerExtensionPoint,