@kosdev-code/kos-ui-sdk 3.0.17 → 3.0.18
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/core/core/dependency-manager.d.ts +6 -0
- package/core/core/dependency-manager.d.ts.map +1 -1
- package/core/core/kosModelManager.d.ts.map +1 -1
- package/core/core/model/model-hook-cache.d.ts +30 -0
- package/core/core/model/model-hook-cache.d.ts.map +1 -0
- package/core/core/transport/mock/mock-recorder.d.ts +7 -0
- package/core/core/transport/mock/mock-recorder.d.ts.map +1 -1
- package/core/core/transport/mock/mock-registry.d.ts.map +1 -1
- package/core/core/transport/mock/mock-types.d.ts +26 -0
- package/core/core/transport/mock/mock-types.d.ts.map +1 -1
- package/core/index.d.ts +1 -0
- package/core/index.d.ts.map +1 -1
- package/core/util/kos-config-init.d.ts.map +1 -1
- package/index.cjs +147 -40
- package/index.cjs.map +1 -1
- package/index.js +147 -40
- package/index.js.map +1 -1
- package/package.json +2 -2
- package/ui/hooks/use-kos-model.d.ts +8 -0
- package/ui/hooks/use-kos-model.d.ts.map +1 -1
package/index.js
CHANGED
|
@@ -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 || [];
|
|
@@ -4190,6 +4201,33 @@ 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) {
|
|
@@ -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;
|
|
@@ -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
|
-
|
|
9276
|
-
|
|
9277
|
-
|
|
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 (
|
|
9382
|
+
} else if (mock === "on") {
|
|
9280
9383
|
KosMock.enable();
|
|
9281
9384
|
}
|
|
9282
|
-
if (
|
|
9283
|
-
KosMock.recorder.start({ name:
|
|
9385
|
+
if (record !== void 0) {
|
|
9386
|
+
KosMock.recorder.start({ name: record || void 0 });
|
|
9284
9387
|
}
|
|
9285
|
-
if (
|
|
9286
|
-
KosMock.fixtures.useServer(
|
|
9388
|
+
if (fixtureServer !== void 0) {
|
|
9389
|
+
KosMock.fixtures.useServer(fixtureServer || true);
|
|
9287
9390
|
}
|
|
9288
9391
|
const bootLoads = [];
|
|
9289
|
-
if (
|
|
9392
|
+
if (fixture) {
|
|
9290
9393
|
bootLoads.push(
|
|
9291
|
-
KosMock.fixtures.play(
|
|
9394
|
+
KosMock.fixtures.play(fixture).then(() => void 0).catch(
|
|
9292
9395
|
(error) => KosLog.error(
|
|
9293
|
-
`KosMock: boot fixture "${
|
|
9396
|
+
`KosMock: boot fixture "${fixture}" failed to load`,
|
|
9294
9397
|
error?.message
|
|
9295
9398
|
)
|
|
9296
9399
|
)
|
|
9297
9400
|
);
|
|
9298
9401
|
}
|
|
9299
|
-
if (
|
|
9300
|
-
for (const name of
|
|
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(
|
|
@@ -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
|
/**
|
|
@@ -26800,33 +26905,32 @@ const waitForRetry = (depth = 0) => new Promise((resolve) => {
|
|
|
26800
26905
|
resolve(true);
|
|
26801
26906
|
}, 2 ** depth * 10);
|
|
26802
26907
|
});
|
|
26803
|
-
|
|
26804
|
-
|
|
26805
|
-
if (
|
|
26806
|
-
const entry = cache$1.get(key);
|
|
26908
|
+
function readModelHookEntry(key, fetcher) {
|
|
26909
|
+
const entry = modelHookCache.get(key);
|
|
26910
|
+
if (entry) {
|
|
26807
26911
|
if (entry.status === "finished") {
|
|
26808
26912
|
const kosModel2 = KosCore.getInstance().modelManager.getModelById(key);
|
|
26809
26913
|
return { kosModel: kosModel2, model: kosModel2?.modelData };
|
|
26810
|
-
} else {
|
|
26811
|
-
throw entry.promise;
|
|
26812
26914
|
}
|
|
26813
|
-
|
|
26814
|
-
|
|
26815
|
-
|
|
26816
|
-
|
|
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;
|
|
26915
|
+
if (entry.status === "error") {
|
|
26916
|
+
throw entry.error;
|
|
26917
|
+
}
|
|
26918
|
+
throw entry.promise;
|
|
26826
26919
|
}
|
|
26920
|
+
const promise = fetcher().then(
|
|
26921
|
+
() => {
|
|
26922
|
+
modelHookCache.set(key, { status: "finished", key });
|
|
26923
|
+
},
|
|
26924
|
+
(error) => {
|
|
26925
|
+
modelHookCache.set(key, { status: "error", error });
|
|
26926
|
+
throw error;
|
|
26927
|
+
}
|
|
26928
|
+
);
|
|
26929
|
+
modelHookCache.set(key, { status: "pending", promise });
|
|
26930
|
+
throw promise;
|
|
26827
26931
|
}
|
|
26828
26932
|
function useSuspenseData$1(key, fetcher) {
|
|
26829
|
-
const data =
|
|
26933
|
+
const data = readModelHookEntry(key, fetcher);
|
|
26830
26934
|
return data;
|
|
26831
26935
|
}
|
|
26832
26936
|
async function fetchModel$1(kosCore, modelOptions) {
|
|
@@ -26914,7 +27018,7 @@ const useKosModel = (modelOptions) => {
|
|
|
26914
27018
|
if (destroyOnUnmount) {
|
|
26915
27019
|
const modelId2 = model.id;
|
|
26916
27020
|
destroyKosModel(model).then(() => {
|
|
26917
|
-
|
|
27021
|
+
clearModelHookCacheEntry(modelId2);
|
|
26918
27022
|
disposer?.();
|
|
26919
27023
|
});
|
|
26920
27024
|
}
|
|
@@ -26923,7 +27027,7 @@ const useKosModel = (modelOptions) => {
|
|
|
26923
27027
|
} else {
|
|
26924
27028
|
if (destroyOnUnmount && model) {
|
|
26925
27029
|
destroyKosModel(model).then(() => {
|
|
26926
|
-
|
|
27030
|
+
clearModelHookCacheEntry(modelId);
|
|
26927
27031
|
disposer?.();
|
|
26928
27032
|
});
|
|
26929
27033
|
}
|
|
@@ -29196,6 +29300,7 @@ export {
|
|
|
29196
29300
|
checkAppsStarted,
|
|
29197
29301
|
checkWildcardPattern,
|
|
29198
29302
|
clearAllServiceResponses,
|
|
29303
|
+
clearModelHookCacheEntry,
|
|
29199
29304
|
clearPath,
|
|
29200
29305
|
clearServiceResponse,
|
|
29201
29306
|
convert,
|
|
@@ -29354,6 +29459,7 @@ export {
|
|
|
29354
29459
|
mapUpdateDtoToConfigBeanModel,
|
|
29355
29460
|
modelEventTopicFactory,
|
|
29356
29461
|
modelFactory,
|
|
29462
|
+
modelHookCache,
|
|
29357
29463
|
modelTypeEventTopicFactory,
|
|
29358
29464
|
modifyConfigBean,
|
|
29359
29465
|
modifyFuture,
|
|
@@ -29365,6 +29471,7 @@ export {
|
|
|
29365
29471
|
processId,
|
|
29366
29472
|
processMiddleware,
|
|
29367
29473
|
put,
|
|
29474
|
+
readModelHookEntry,
|
|
29368
29475
|
registerCompanionModel,
|
|
29369
29476
|
registerCoreModels,
|
|
29370
29477
|
registerExtensionPoint,
|