@kosdev-code/kos-ui-sdk 3.0.21 → 3.0.23
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/kosCore.d.ts +1 -0
- package/core/core/kosCore.d.ts.map +1 -1
- package/core/core/kosModel.d.ts +11 -0
- package/core/core/kosModel.d.ts.map +1 -1
- package/core/core/kosModelManager.d.ts +8 -0
- package/core/core/kosModelManager.d.ts.map +1 -1
- package/core/core/lifecycle/constants.d.ts +1 -1
- package/core/core/lifecycle/constants.d.ts.map +1 -1
- package/core/core/model/kos-subscription-manager.d.ts +1 -0
- package/core/core/model/kos-subscription-manager.d.ts.map +1 -1
- package/core/core/registration/index.d.ts +1 -1
- package/core/core/registration/index.d.ts.map +1 -1
- package/core/core/registration/model-registration.d.ts +11 -0
- package/core/core/registration/model-registration.d.ts.map +1 -1
- package/core/index.d.ts +1 -1
- package/core/index.d.ts.map +1 -1
- package/core/util/kos-model-utils.d.ts +13 -0
- package/core/util/kos-model-utils.d.ts.map +1 -1
- package/{index-DUoSahlA.cjs → index-CRb8ucfF.cjs} +115 -48
- package/index-CRb8ucfF.cjs.map +1 -0
- package/{index-BUwbSjst.js → index-YzHb2lnB.js} +116 -49
- package/index-YzHb2lnB.js.map +1 -0
- package/index.cjs +113 -26
- package/index.cjs.map +1 -1
- package/index.js +114 -27
- package/index.js.map +1 -1
- package/models/decorators/kos-config-bean-prop.d.ts +5 -0
- package/models/decorators/kos-config-bean-prop.d.ts.map +1 -1
- package/models/decorators/kos-config-bean.d.ts +7 -1
- package/models/decorators/kos-config-bean.d.ts.map +1 -1
- package/models/models/config-bean/config-bean-model.d.ts +9 -0
- package/models/models/config-bean/config-bean-model.d.ts.map +1 -1
- package/models/models/config-bean/config-bean-types.d.ts +2 -0
- package/models/models/config-bean/config-bean-types.d.ts.map +1 -1
- package/models/models/config-bean-prop/config-bean-prop-model.d.ts +3 -0
- package/models/models/config-bean-prop/config-bean-prop-model.d.ts.map +1 -1
- package/models/models/config-bean-prop/types/index.d.ts +10 -0
- package/models/models/region-info/region-info-model.d.ts +12 -1
- package/models/models/region-info/region-info-model.d.ts.map +1 -1
- package/models/models/region-info/services/region-info-services.d.ts +2 -2
- package/models/models/region-info/services/region-info-services.d.ts.map +1 -1
- package/models/models/region-info/types/index.d.ts +7 -0
- package/models/models/region-info/types/index.d.ts.map +1 -1
- package/models/services/config-bean/index.d.ts +2 -2
- package/models/services/config-bean/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/testing/index.d.ts +51 -9
- package/testing/index.d.ts.map +1 -1
- package/testing.cjs +57 -3
- package/testing.cjs.map +1 -1
- package/testing.js +57 -3
- package/testing.js.map +1 -1
- package/index-BUwbSjst.js.map +0 -1
- package/index-DUoSahlA.cjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { makeAutoObservable, observable, makeObservable, action, createAtom, autorun, runInAction, observe, isComputedProp, reaction,
|
|
1
|
+
import { makeAutoObservable, observable, makeObservable, action, createAtom, autorun, runInAction, observe, isComputedProp, reaction, ObservableMap, when, computed, isObservable } from "mobx";
|
|
2
2
|
import log$q from "loglevel";
|
|
3
3
|
import { createMachine, invoke, transition, action as action$1, state, interpret, immediate } from "robot3";
|
|
4
4
|
const HEADER_METHOD = `method`;
|
|
@@ -2491,7 +2491,7 @@ var KosModelEvents = /* @__PURE__ */ ((KosModelEvents2) => {
|
|
|
2491
2491
|
KosModelEvents2["READY"] = `ready`;
|
|
2492
2492
|
KosModelEvents2["GO_ONLINE"] = `go_online`;
|
|
2493
2493
|
KosModelEvents2["GO_OFFLINE"] = `go_offline`;
|
|
2494
|
-
KosModelEvents2["RESET"] = `
|
|
2494
|
+
KosModelEvents2["RESET"] = `reset`;
|
|
2495
2495
|
KosModelEvents2["UNLOAD"] = `unload`;
|
|
2496
2496
|
KosModelEvents2["FAILED"] = "failed";
|
|
2497
2497
|
KosModelEvents2["GO_ACTIVE"] = "go_active";
|
|
@@ -2516,6 +2516,9 @@ const destroyKosModel = async (model) => {
|
|
|
2516
2516
|
await KosCore.getInstance().modelManager.initiateDestroyModel(model);
|
|
2517
2517
|
};
|
|
2518
2518
|
const unloadKosModel = async (dataModel) => {
|
|
2519
|
+
KosLog.warn(
|
|
2520
|
+
`unloadKosModel(${dataModel?.id}) is deprecated and never resolves. Use destroyKosModel() to release a model, or reload() to refresh it.`
|
|
2521
|
+
);
|
|
2519
2522
|
await KosCore.getInstance().whenReady();
|
|
2520
2523
|
if (!dataModel.id) {
|
|
2521
2524
|
throw new Error("Model ID is required");
|
|
@@ -2526,6 +2529,9 @@ const unloadKosModel = async (dataModel) => {
|
|
|
2526
2529
|
}
|
|
2527
2530
|
};
|
|
2528
2531
|
const resetKosModel = async (model) => {
|
|
2532
|
+
KosLog.warn(
|
|
2533
|
+
`resetKosModel(${model?.id}) is deprecated: the reset route drops every topic handler registered at INIT or with no lifecycle. Implement reload() on the model and refetch and reconcile in place.`
|
|
2534
|
+
);
|
|
2529
2535
|
await KosCore.getInstance().whenReady();
|
|
2530
2536
|
await KosCore.getInstance().modelManager.reloadModel(model);
|
|
2531
2537
|
KosLog.debug(
|
|
@@ -3692,6 +3698,21 @@ function setupReplayHandler(topic, bufferSize) {
|
|
|
3692
3698
|
replay(t, bufferSize);
|
|
3693
3699
|
});
|
|
3694
3700
|
}
|
|
3701
|
+
const isPrintable = (model) => typeof model.toJSON === "function";
|
|
3702
|
+
const isKosDataModel = (model) => model[DependencyModels] !== void 0;
|
|
3703
|
+
const isKosModelContainer = (model) => model.revision !== void 0 && model.index !== void 0;
|
|
3704
|
+
const resolveChild = (attribute) => {
|
|
3705
|
+
if (!attribute) return void 0;
|
|
3706
|
+
if (isKosDataModel(attribute)) return attribute;
|
|
3707
|
+
if (isKosModelContainer(attribute)) return attribute.data;
|
|
3708
|
+
if (attribute instanceof Map || attribute instanceof ObservableMap || attribute instanceof Set) {
|
|
3709
|
+
return Array.from(attribute.values()).filter(isKosDataModel);
|
|
3710
|
+
}
|
|
3711
|
+
if (Array.isArray(attribute)) {
|
|
3712
|
+
return attribute.filter(isKosDataModel);
|
|
3713
|
+
}
|
|
3714
|
+
return void 0;
|
|
3715
|
+
};
|
|
3695
3716
|
const deletionMap = /* @__PURE__ */ new Map();
|
|
3696
3717
|
const KosDeletionManager = {
|
|
3697
3718
|
addToDeletionQueue: (modelId, timeout) => {
|
|
@@ -4182,21 +4203,6 @@ const rejectAfterDelay$1 = (ms, model, status) => {
|
|
|
4182
4203
|
};
|
|
4183
4204
|
return { promise, cancel };
|
|
4184
4205
|
};
|
|
4185
|
-
const isPrintable = (model) => typeof model.toJSON === "function";
|
|
4186
|
-
const isKosDataModel = (model) => model[DependencyModels] !== void 0;
|
|
4187
|
-
const isKosModelContainer = (model) => model.revision !== void 0 && model.index !== void 0;
|
|
4188
|
-
const resolveChild = (attribute) => {
|
|
4189
|
-
if (!attribute) return void 0;
|
|
4190
|
-
if (isKosDataModel(attribute)) return attribute;
|
|
4191
|
-
if (isKosModelContainer(attribute)) return attribute.data;
|
|
4192
|
-
if (attribute instanceof Map || attribute instanceof ObservableMap || attribute instanceof Set) {
|
|
4193
|
-
return Array.from(attribute.values()).filter(isKosDataModel);
|
|
4194
|
-
}
|
|
4195
|
-
if (Array.isArray(attribute)) {
|
|
4196
|
-
return attribute.filter(isKosDataModel);
|
|
4197
|
-
}
|
|
4198
|
-
return void 0;
|
|
4199
|
-
};
|
|
4200
4206
|
const createModelDependency = (model, dependency) => {
|
|
4201
4207
|
const _dataModelId = dependency.id || dependency.modelType;
|
|
4202
4208
|
const dataModelId = resolveParameters({
|
|
@@ -9803,6 +9809,8 @@ class KosSubscriptionManager {
|
|
|
9803
9809
|
const config2 = subscriptions2[topic];
|
|
9804
9810
|
const topicLifecycle = config2.lifecycle;
|
|
9805
9811
|
if (lifecycle && lifecycle !== topicLifecycle) return;
|
|
9812
|
+
if (!lifecycle && topicLifecycle === DependencyLifecycle.ACTIVATE && this.model.activeStatus !== KosModelState.ACTIVE)
|
|
9813
|
+
return;
|
|
9806
9814
|
const resolvedTopic = this.resolvePropKey(topic);
|
|
9807
9815
|
if (this.onceTopics.has(resolvedTopic)) {
|
|
9808
9816
|
this.log.debug(`Skipping once topic (already fired): ${resolvedTopic}`);
|
|
@@ -9875,7 +9883,7 @@ class KosSubscriptionManager {
|
|
|
9875
9883
|
this.registeredTopics.clear();
|
|
9876
9884
|
}
|
|
9877
9885
|
subscribe(subscription, topic, handler, activatable) {
|
|
9878
|
-
const destinationAddress
|
|
9886
|
+
const { destinationAddress, explicitDestination } = this.resolveDestination(subscription);
|
|
9879
9887
|
if (subscription.websocket) {
|
|
9880
9888
|
this.log.debug(`Subscribing to WebSocket topic: ${topic}`);
|
|
9881
9889
|
const socketSub = WebSocketTransport.getInstance().subscribeTopic({
|
|
@@ -9884,7 +9892,7 @@ class KosSubscriptionManager {
|
|
|
9884
9892
|
fos: subscription.fos,
|
|
9885
9893
|
bridge: subscription.bridge,
|
|
9886
9894
|
destinationAddress,
|
|
9887
|
-
explicitDestination
|
|
9895
|
+
explicitDestination
|
|
9888
9896
|
});
|
|
9889
9897
|
if (activatable) {
|
|
9890
9898
|
this.activatableDisposers.push(socketSub);
|
|
@@ -9984,6 +9992,27 @@ class KosSubscriptionManager {
|
|
|
9984
9992
|
);
|
|
9985
9993
|
}
|
|
9986
9994
|
}
|
|
9995
|
+
// A destination template whose model property is unset names no destination:
|
|
9996
|
+
// it resolves to null and is not treated as explicit, so the transport keeps
|
|
9997
|
+
// its connId fallback for that model.
|
|
9998
|
+
resolveDestination(subscription) {
|
|
9999
|
+
const template = subscription.destinationAddress;
|
|
10000
|
+
const explicitDestination = subscription.explicitDestination ?? false;
|
|
10001
|
+
if (!template) {
|
|
10002
|
+
return { destinationAddress: null, explicitDestination };
|
|
10003
|
+
}
|
|
10004
|
+
const match = template.match(/{PROP_(.+?)}/);
|
|
10005
|
+
if (match) {
|
|
10006
|
+
const value = this.modelData?.[match[1]];
|
|
10007
|
+
if (value === null || value === void 0) {
|
|
10008
|
+
return { destinationAddress: null, explicitDestination: false };
|
|
10009
|
+
}
|
|
10010
|
+
}
|
|
10011
|
+
return {
|
|
10012
|
+
destinationAddress: this.resolvePropKey(template),
|
|
10013
|
+
explicitDestination
|
|
10014
|
+
};
|
|
10015
|
+
}
|
|
9987
10016
|
resolvePropKey(template) {
|
|
9988
10017
|
const propRegex = /.*({PROP_(.+)})/;
|
|
9989
10018
|
let topic = template.includes("{MODEL_ID}") ? template.replace("{MODEL_ID}", this.modelId) : template;
|
|
@@ -10023,7 +10052,7 @@ class KosSubscriptionManager {
|
|
|
10023
10052
|
try {
|
|
10024
10053
|
let eventSource;
|
|
10025
10054
|
if (config2.websocket) {
|
|
10026
|
-
const destinationAddress
|
|
10055
|
+
const { destinationAddress, explicitDestination } = this.resolveDestination(config2);
|
|
10027
10056
|
WebSocketTransport.getInstance().subscribeTopic({
|
|
10028
10057
|
topic: resolvedTopic,
|
|
10029
10058
|
callback: () => {
|
|
@@ -10032,7 +10061,7 @@ class KosSubscriptionManager {
|
|
|
10032
10061
|
fos: config2.fos,
|
|
10033
10062
|
bridge: config2.bridge,
|
|
10034
10063
|
destinationAddress,
|
|
10035
|
-
explicitDestination
|
|
10064
|
+
explicitDestination
|
|
10036
10065
|
});
|
|
10037
10066
|
eventSource = iterate(resolvedTopic);
|
|
10038
10067
|
} else {
|
|
@@ -10905,6 +10934,20 @@ class KosModel {
|
|
|
10905
10934
|
);
|
|
10906
10935
|
this.subscriptionManager?.registerAll(lifecycle);
|
|
10907
10936
|
}
|
|
10937
|
+
/**
|
|
10938
|
+
* The counterpart of `unload()` for a reload that keeps the instance: every
|
|
10939
|
+
* manager `unload()` disposed comes back, not only the subscriptions.
|
|
10940
|
+
* @internal
|
|
10941
|
+
*/
|
|
10942
|
+
restoreAfterReload() {
|
|
10943
|
+
this.onlineLifecycleManager?.register();
|
|
10944
|
+
this.subscriptionManager?.registerAll();
|
|
10945
|
+
this.httpRouteManager?.registerAll();
|
|
10946
|
+
this.effectManager?.setup();
|
|
10947
|
+
kosAction(() => {
|
|
10948
|
+
this.loaded = true;
|
|
10949
|
+
});
|
|
10950
|
+
}
|
|
10908
10951
|
/**
|
|
10909
10952
|
* Initialize the state machine for a specific lifecycle phase.
|
|
10910
10953
|
* Called from lifecycle hooks (init, load, ready, activate).
|
|
@@ -11305,6 +11348,10 @@ class KosModelManager {
|
|
|
11305
11348
|
* by its ID, it transitions the model to the RESETTING state using the
|
|
11306
11349
|
* RESET event.
|
|
11307
11350
|
*
|
|
11351
|
+
* @deprecated The reset route re-runs load() and ready() only and loses the
|
|
11352
|
+
* handlers registered at INIT or with no lifecycle. Models refresh through
|
|
11353
|
+
* `reload()`, driven by KOS Core.
|
|
11354
|
+
*
|
|
11308
11355
|
* @param model - The data model to be reloaded. Must implement the `IKosDataModel` interface.
|
|
11309
11356
|
* The `id` property of the model is used to locate the corresponding model.
|
|
11310
11357
|
*
|
|
@@ -11355,17 +11402,51 @@ class KosModelManager {
|
|
|
11355
11402
|
* the following actions:
|
|
11356
11403
|
* 1. Calls the `unload` method on the model, if it exists.
|
|
11357
11404
|
* 2. Removes the model from the manager using the `removeModel` method.
|
|
11405
|
+
* 3. Releases the model's children (decorated children, container members,
|
|
11406
|
+
* companions) from the manager the same way, recursively.
|
|
11358
11407
|
*
|
|
11359
11408
|
* @throws This method does not explicitly throw errors, but any errors occurring
|
|
11360
11409
|
* during the `unload` or `removeModel` operations will propagate to the caller.
|
|
11361
11410
|
*/
|
|
11362
11411
|
async destroyModel(model) {
|
|
11363
11412
|
if (model?.modelId && this.dependencies.canDestroy(model.modelId)) {
|
|
11413
|
+
const children = model.getChildren();
|
|
11364
11414
|
await model.unload?.();
|
|
11365
11415
|
this.removeModel(model);
|
|
11366
11416
|
this.dependencies.removeAll(model.modelId);
|
|
11367
11417
|
clearModelHookCacheEntry(model.modelId);
|
|
11368
|
-
|
|
11418
|
+
this.emptyContainersOf(model);
|
|
11419
|
+
children.forEach((child) => this.releaseUnloadedChild(child));
|
|
11420
|
+
}
|
|
11421
|
+
}
|
|
11422
|
+
// Each container held as a child is emptied with one bulk removal, so its
|
|
11423
|
+
// indexes are recalculated once and its per-member observers are released.
|
|
11424
|
+
emptyContainersOf(model) {
|
|
11425
|
+
const data = model.modelData;
|
|
11426
|
+
const childKeys = Object.keys(data?.[ChildModels] || {});
|
|
11427
|
+
for (const key of childKeys) {
|
|
11428
|
+
const container = data[key];
|
|
11429
|
+
if (!isKosModelContainer(container)) continue;
|
|
11430
|
+
const ids = container.data.map((member) => member.id);
|
|
11431
|
+
if (ids.length) container.removeAll(ids);
|
|
11432
|
+
}
|
|
11433
|
+
}
|
|
11434
|
+
// A destroyed model's unload() has already unloaded its children; only the
|
|
11435
|
+
// registry half of destruction is left for them. Never walks dependencies:
|
|
11436
|
+
// a child something else depends on stays registered, and a child already
|
|
11437
|
+
// removed or queued for deletion is left to that path.
|
|
11438
|
+
releaseUnloadedChild(child) {
|
|
11439
|
+
const { modelId } = child;
|
|
11440
|
+
if (!this.getModelById(modelId)) return;
|
|
11441
|
+
if (!this.dependencies.canDestroy(modelId)) return;
|
|
11442
|
+
const grandchildren = child.getChildren();
|
|
11443
|
+
this.removeModel(child);
|
|
11444
|
+
this.dependencies.removeAll(modelId);
|
|
11445
|
+
clearModelHookCacheEntry(modelId);
|
|
11446
|
+
this.emptyContainersOf(child);
|
|
11447
|
+
grandchildren.forEach(
|
|
11448
|
+
(grandchild) => this.releaseUnloadedChild(grandchild)
|
|
11449
|
+
);
|
|
11369
11450
|
}
|
|
11370
11451
|
/**
|
|
11371
11452
|
* Creates an instance of a model based on the specified type ID and optional model ID.
|
|
@@ -11752,30 +11833,13 @@ class KosCore {
|
|
|
11752
11833
|
this.transport.token = data.body;
|
|
11753
11834
|
}
|
|
11754
11835
|
});
|
|
11755
|
-
subscribe(WebSocketEvents.DISCONNECTED,
|
|
11756
|
-
await Promise.allSettled(
|
|
11757
|
-
this.modelManager.models.map(async (model) => {
|
|
11758
|
-
try {
|
|
11759
|
-
await model.offline?.();
|
|
11760
|
-
} catch (e) {
|
|
11761
|
-
log$5.error(`model ${model.modelId} offline() threw:`, e);
|
|
11762
|
-
}
|
|
11763
|
-
model.onlineLifecycleManager?.dispose();
|
|
11764
|
-
})
|
|
11765
|
-
);
|
|
11836
|
+
subscribe(WebSocketEvents.DISCONNECTED, () => {
|
|
11766
11837
|
this.fsmService.service.send(KosCoreEvents.GO_OFFLINE);
|
|
11767
11838
|
});
|
|
11768
11839
|
subscribe(WebSocketEvents.CONNECTED, async () => {
|
|
11769
11840
|
await this.whenReady();
|
|
11770
|
-
|
|
11771
|
-
|
|
11772
|
-
model.onlineLifecycleManager?.register();
|
|
11773
|
-
try {
|
|
11774
|
-
await model.online?.();
|
|
11775
|
-
} catch (e) {
|
|
11776
|
-
log$5.error(`model ${model.modelId} online() threw:`, e);
|
|
11777
|
-
}
|
|
11778
|
-
})
|
|
11841
|
+
this.modelManager.models.forEach(
|
|
11842
|
+
(model) => model.onlineLifecycleManager?.register()
|
|
11779
11843
|
);
|
|
11780
11844
|
this.fsmService.service.send(KosCoreEvents.GO_ONLINE);
|
|
11781
11845
|
});
|
|
@@ -11846,9 +11910,7 @@ class KosCore {
|
|
|
11846
11910
|
continue;
|
|
11847
11911
|
}
|
|
11848
11912
|
log$5.info(`reloading model ${model.modelId}`);
|
|
11849
|
-
model.
|
|
11850
|
-
await model.modelData.reload();
|
|
11851
|
-
model.registerSubscribers?.();
|
|
11913
|
+
await this.reloadModel(model, model.modelData);
|
|
11852
11914
|
log$5.info(`reloading model ${model.modelId} complete`);
|
|
11853
11915
|
}
|
|
11854
11916
|
}
|
|
@@ -11859,9 +11921,7 @@ class KosCore {
|
|
|
11859
11921
|
continue;
|
|
11860
11922
|
}
|
|
11861
11923
|
log$5.warn(`reloading model ${model.modelId}`);
|
|
11862
|
-
model.
|
|
11863
|
-
await model.modelData.reload();
|
|
11864
|
-
model.registerSubscribers?.();
|
|
11924
|
+
await this.reloadModel(model, model.modelData);
|
|
11865
11925
|
}
|
|
11866
11926
|
}
|
|
11867
11927
|
const elapsed = Date.now() - currentTime;
|
|
@@ -11872,6 +11932,13 @@ class KosCore {
|
|
|
11872
11932
|
});
|
|
11873
11933
|
}, 1e3 - elapsed);
|
|
11874
11934
|
}
|
|
11935
|
+
// unload() must finish before reload() starts, and whatever it disposed must
|
|
11936
|
+
// come back afterwards; the data model's reload() only refreshes data.
|
|
11937
|
+
async reloadModel(model, data) {
|
|
11938
|
+
await model.unload?.();
|
|
11939
|
+
await data.reload();
|
|
11940
|
+
model.restoreAfterReload?.();
|
|
11941
|
+
}
|
|
11875
11942
|
async online() {
|
|
11876
11943
|
log$5.debug("KOS Core going online");
|
|
11877
11944
|
await this._transport.whenReady();
|
|
@@ -13537,4 +13604,4 @@ export {
|
|
|
13537
13604
|
ObservableData as y,
|
|
13538
13605
|
kosAction as z
|
|
13539
13606
|
};
|
|
13540
|
-
//# sourceMappingURL=index-
|
|
13607
|
+
//# sourceMappingURL=index-YzHb2lnB.js.map
|