@kosdev-code/kos-ui-sdk 0.1.0-next.807 → 0.1.0-next.809
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/transport/webSocketTransport.d.ts +30 -2
- package/core/core/transport/webSocketTransport.d.ts.map +1 -1
- package/core/types/utils/kos-fetch.d.ts +17 -0
- package/core/types/utils/kos-fetch.d.ts.map +1 -1
- package/core/util/abortable-when.d.ts +21 -0
- package/core/util/abortable-when.d.ts.map +1 -0
- package/core/util/index.d.ts +1 -0
- package/core/util/index.d.ts.map +1 -1
- package/core/util/kos-fetch.d.ts.map +1 -1
- package/core/util/kos-model-utils.d.ts +43 -0
- package/core/util/kos-model-utils.d.ts.map +1 -1
- package/core/util/kos-service-request.d.ts +10 -0
- package/core/util/kos-service-request.d.ts.map +1 -1
- package/core/util/transport-not-ready-error.d.ts +67 -0
- package/core/util/transport-not-ready-error.d.ts.map +1 -0
- package/index.cjs +137 -9
- package/index.cjs.map +1 -1
- package/index.js +137 -9
- package/index.js.map +1 -1
- package/package.json +3 -3
package/index.js
CHANGED
|
@@ -2915,6 +2915,29 @@ const isKosModelReady = (model) => {
|
|
|
2915
2915
|
}
|
|
2916
2916
|
return kosModel2.isReady();
|
|
2917
2917
|
};
|
|
2918
|
+
const getKosModelActivationState = (model) => {
|
|
2919
|
+
if (!model?.id) {
|
|
2920
|
+
return void 0;
|
|
2921
|
+
}
|
|
2922
|
+
const kosModel2 = KosCore.getInstance().modelManager.getModelById(model.id);
|
|
2923
|
+
if (!kosModel2) {
|
|
2924
|
+
return void 0;
|
|
2925
|
+
}
|
|
2926
|
+
return {
|
|
2927
|
+
get activeStatus() {
|
|
2928
|
+
return kosModel2.activeStatus;
|
|
2929
|
+
},
|
|
2930
|
+
get isActivating() {
|
|
2931
|
+
return kosModel2.activeStatus === KosModelState.ACTIVATING;
|
|
2932
|
+
},
|
|
2933
|
+
get isActive() {
|
|
2934
|
+
return kosModel2.activeStatus === KosModelState.ACTIVE;
|
|
2935
|
+
},
|
|
2936
|
+
get isFailed() {
|
|
2937
|
+
return kosModel2.activeStatus === KosModelState.FAILED;
|
|
2938
|
+
}
|
|
2939
|
+
};
|
|
2940
|
+
};
|
|
2918
2941
|
const log$L = KosLog.createLogger({ name: "kos-model-factory" });
|
|
2919
2942
|
const KosModelFactory = {
|
|
2920
2943
|
byModelType: (modelType) => KosCore.getInstance().modelManager.getModelFactory(
|
|
@@ -6339,8 +6362,38 @@ const getMessageBody = (payload, skipParse) => {
|
|
|
6339
6362
|
return payload.body || payload;
|
|
6340
6363
|
}
|
|
6341
6364
|
};
|
|
6365
|
+
const TRANSPORT_NOT_READY = "TRANSPORT_NOT_READY";
|
|
6366
|
+
class TransportNotReadyError extends Error {
|
|
6367
|
+
/** Stable discriminator; see {@link TRANSPORT_NOT_READY}. */
|
|
6368
|
+
code = TRANSPORT_NOT_READY;
|
|
6369
|
+
/**
|
|
6370
|
+
* The budget, in milliseconds, that expired while waiting. `undefined` when
|
|
6371
|
+
* the wait was cut short by a caller-supplied timeout signal rather than by
|
|
6372
|
+
* the request's own budget.
|
|
6373
|
+
*/
|
|
6374
|
+
timeout;
|
|
6375
|
+
/** The URL of the request that was never sent. */
|
|
6376
|
+
url;
|
|
6377
|
+
constructor(details = {}) {
|
|
6378
|
+
super(
|
|
6379
|
+
`Transport not ready${details.timeout === void 0 ? "" : ` after ${details.timeout}ms`}${details.url ? ` - url: ${details.url}` : ""}`
|
|
6380
|
+
);
|
|
6381
|
+
this.name = "TransportNotReadyError";
|
|
6382
|
+
this.timeout = details.timeout;
|
|
6383
|
+
this.url = details.url;
|
|
6384
|
+
}
|
|
6385
|
+
}
|
|
6386
|
+
const isTransportNotReadyError = (error) => !!error && error.code === TRANSPORT_NOT_READY;
|
|
6342
6387
|
const log$D = KosLog.createLogger({ name: "kos-fetch" });
|
|
6343
|
-
const
|
|
6388
|
+
const DEFAULT_WS_TIMEOUT = 3e4;
|
|
6389
|
+
const WS_TIMEOUT = (() => {
|
|
6390
|
+
const configured = process.env.KOS_WS_TIMEOUT ? parseInt(process.env.KOS_WS_TIMEOUT) : DEFAULT_WS_TIMEOUT;
|
|
6391
|
+
return Number.isNaN(configured) ? DEFAULT_WS_TIMEOUT : configured;
|
|
6392
|
+
})();
|
|
6393
|
+
const resolveTimeoutBudget = (timeout) => {
|
|
6394
|
+
const budget = timeout ?? WS_TIMEOUT;
|
|
6395
|
+
return Number.isFinite(budget) && budget > 0 ? budget : void 0;
|
|
6396
|
+
};
|
|
6344
6397
|
const delay = () => new Promise((resolve) => {
|
|
6345
6398
|
setTimeout(() => {
|
|
6346
6399
|
resolve(true);
|
|
@@ -6374,6 +6427,14 @@ const combineSignals = (signals) => {
|
|
|
6374
6427
|
}
|
|
6375
6428
|
return controller.signal;
|
|
6376
6429
|
};
|
|
6430
|
+
const createRequestSignal = (budget, callerSignal) => {
|
|
6431
|
+
const timeoutSignal = budget ? createTimeoutSignal(budget) : void 0;
|
|
6432
|
+
if (timeoutSignal && callerSignal) {
|
|
6433
|
+
return combineSignals([callerSignal, timeoutSignal]);
|
|
6434
|
+
}
|
|
6435
|
+
return timeoutSignal ?? callerSignal ?? new AbortController().signal;
|
|
6436
|
+
};
|
|
6437
|
+
const isTimeoutReason = (reason) => reason?.name === "TimeoutError";
|
|
6377
6438
|
const fetchMessageFactory = (options) => {
|
|
6378
6439
|
if (options?.studio) {
|
|
6379
6440
|
return createStudioMessage;
|
|
@@ -6385,15 +6446,25 @@ const fetchMessageFactory = (options) => {
|
|
|
6385
6446
|
};
|
|
6386
6447
|
const kosFetchWs = async (url, options) => {
|
|
6387
6448
|
const transport = KosCore.getInstance().transport;
|
|
6388
|
-
await transport.whenReady();
|
|
6389
6449
|
const requestId = uuid();
|
|
6390
6450
|
const urlObj = new URL(url);
|
|
6391
6451
|
const path = `${urlObj.pathname}${urlObj.search}`;
|
|
6392
6452
|
log$D.debug(`path: ${path}`);
|
|
6393
|
-
const
|
|
6453
|
+
const budget = resolveTimeoutBudget(options?.timeout);
|
|
6394
6454
|
const messageFactory = fetchMessageFactory(options);
|
|
6395
|
-
const
|
|
6396
|
-
|
|
6455
|
+
const signal = createRequestSignal(budget, options?.signal);
|
|
6456
|
+
try {
|
|
6457
|
+
await transport.whenReady({ signal });
|
|
6458
|
+
} catch (error) {
|
|
6459
|
+
if (isTimeoutReason(error)) {
|
|
6460
|
+
log$D.error(
|
|
6461
|
+
`Transport not ready${budget === void 0 ? "" : ` after ${budget}ms`} - request not sent - url: ${url}`
|
|
6462
|
+
);
|
|
6463
|
+
throw new TransportNotReadyError({ timeout: budget, url });
|
|
6464
|
+
}
|
|
6465
|
+
log$D.debug(`Request aborted while waiting for transport - url: ${url}`);
|
|
6466
|
+
throw error;
|
|
6467
|
+
}
|
|
6397
6468
|
const processedBody = await processRequestBody(options?.body);
|
|
6398
6469
|
const additionalHeaders = {};
|
|
6399
6470
|
if (processedBody.contentType) {
|
|
@@ -6556,6 +6627,7 @@ const resolveBaseUrl = () => {
|
|
|
6556
6627
|
};
|
|
6557
6628
|
const log$C = KosLog.createLogger({ name: "kos-service-request" });
|
|
6558
6629
|
const ERROR_UNKNOWN = "errUnknown";
|
|
6630
|
+
const ERROR_TRANSPORT_NOT_READY = "Transport not ready";
|
|
6559
6631
|
const MUTATING_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "DELETE", "PATCH"]);
|
|
6560
6632
|
const RETRY_DEFAULTS = {
|
|
6561
6633
|
maxAttempts: 3,
|
|
@@ -6605,6 +6677,10 @@ async function executeFetch(fullUrl, fetchOptions) {
|
|
|
6605
6677
|
const payload = await response.json();
|
|
6606
6678
|
return [null, payload.data ?? payload];
|
|
6607
6679
|
} catch (error) {
|
|
6680
|
+
if (isTransportNotReadyError(error)) {
|
|
6681
|
+
log$C.error(`Transport not ready, request not sent: ${fullUrl}`);
|
|
6682
|
+
return [ERROR_TRANSPORT_NOT_READY, null];
|
|
6683
|
+
}
|
|
6608
6684
|
if (error instanceof DOMException) {
|
|
6609
6685
|
if (error.name === "TimeoutError") {
|
|
6610
6686
|
log$C.error(`Request timed out: ${fullUrl}`);
|
|
@@ -6648,6 +6724,10 @@ async function executeFetchWithRetry(fullUrl, fetchOptions, config2) {
|
|
|
6648
6724
|
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
6649
6725
|
}
|
|
6650
6726
|
} catch (error) {
|
|
6727
|
+
if (isTransportNotReadyError(error)) {
|
|
6728
|
+
log$C.error(`Transport not ready, request not sent: ${fullUrl}`);
|
|
6729
|
+
return [ERROR_TRANSPORT_NOT_READY, null];
|
|
6730
|
+
}
|
|
6651
6731
|
if (error instanceof DOMException) {
|
|
6652
6732
|
if (error.name === "TimeoutError") {
|
|
6653
6733
|
log$C.error(`Request timed out: ${fullUrl}`);
|
|
@@ -7459,6 +7539,38 @@ class FlowControlManager {
|
|
|
7459
7539
|
return { ...this.stats };
|
|
7460
7540
|
}
|
|
7461
7541
|
}
|
|
7542
|
+
const abortReason = (signal) => signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
7543
|
+
const abortableWhen = async (predicate, signal) => {
|
|
7544
|
+
if (predicate()) {
|
|
7545
|
+
return;
|
|
7546
|
+
}
|
|
7547
|
+
if (!signal) {
|
|
7548
|
+
await when(predicate);
|
|
7549
|
+
return;
|
|
7550
|
+
}
|
|
7551
|
+
if (signal.aborted) {
|
|
7552
|
+
throw abortReason(signal);
|
|
7553
|
+
}
|
|
7554
|
+
const pending = when(predicate);
|
|
7555
|
+
let onAbort;
|
|
7556
|
+
try {
|
|
7557
|
+
await Promise.race([
|
|
7558
|
+
// `cancel()` below rejects this promise with MobX's WHEN_CANCELLED
|
|
7559
|
+
// sentinel. That rejection *is* the cancellation, never a real failure,
|
|
7560
|
+
// so it is swallowed here; the abort branch supplies the thrown reason.
|
|
7561
|
+
pending.catch(() => void 0),
|
|
7562
|
+
new Promise((_, reject) => {
|
|
7563
|
+
onAbort = () => reject(abortReason(signal));
|
|
7564
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
7565
|
+
})
|
|
7566
|
+
]);
|
|
7567
|
+
} finally {
|
|
7568
|
+
if (onAbort) {
|
|
7569
|
+
signal.removeEventListener("abort", onAbort);
|
|
7570
|
+
}
|
|
7571
|
+
pending.cancel();
|
|
7572
|
+
}
|
|
7573
|
+
};
|
|
7462
7574
|
class WebSocketBridgeTransport extends WebSocket {
|
|
7463
7575
|
constructor(address) {
|
|
7464
7576
|
super(address);
|
|
@@ -8091,15 +8203,26 @@ ${dstAddr}topics:${topic}
|
|
|
8091
8203
|
}
|
|
8092
8204
|
};
|
|
8093
8205
|
}
|
|
8094
|
-
|
|
8095
|
-
|
|
8206
|
+
/**
|
|
8207
|
+
* Resolves once the transport can carry requests: the socket (and the FOS
|
|
8208
|
+
* socket, when used) is connected and the connection is authorized.
|
|
8209
|
+
*
|
|
8210
|
+
* Pass `options.signal` to bound the wait. `connectionEstablished` flips back
|
|
8211
|
+
* to `false` on socket close, so an unbounded wait parks indefinitely while
|
|
8212
|
+
* the transport is down — callers with a deadline must supply a signal.
|
|
8213
|
+
*
|
|
8214
|
+
* @param options - See {@link KosTransportReadyOptions}.
|
|
8215
|
+
* @throws The signal's abort reason if it aborts before the transport is ready.
|
|
8216
|
+
*/
|
|
8217
|
+
async whenReady(options) {
|
|
8096
8218
|
if (!this.webSocketSupported) {
|
|
8097
8219
|
return {
|
|
8098
8220
|
status: `not supported`
|
|
8099
8221
|
};
|
|
8100
8222
|
}
|
|
8101
|
-
await
|
|
8102
|
-
() => !!
|
|
8223
|
+
await abortableWhen(
|
|
8224
|
+
() => !!this.socket?.connectionEstablished && (!this.useFosTransport || !!this.fosSocket?.connectionEstablished) && this.authorized,
|
|
8225
|
+
options?.signal
|
|
8103
8226
|
);
|
|
8104
8227
|
return {
|
|
8105
8228
|
status: `success`
|
|
@@ -26922,6 +27045,7 @@ export {
|
|
|
26922
27045
|
Device,
|
|
26923
27046
|
index$6 as DeviceServices,
|
|
26924
27047
|
DomIntersectionStrategy,
|
|
27048
|
+
ERROR_TRANSPORT_NOT_READY,
|
|
26925
27049
|
EVENT_KOS_MODEL_READY,
|
|
26926
27050
|
EVENT_TROUBLE_ADDED,
|
|
26927
27051
|
EVENT_TROUBLE_REMOVED,
|
|
@@ -27104,6 +27228,7 @@ export {
|
|
|
27104
27228
|
TIMER_END,
|
|
27105
27229
|
TIMER_EVENT,
|
|
27106
27230
|
TOPIC_TIMER_TICK_EVENT,
|
|
27231
|
+
TRANSPORT_NOT_READY,
|
|
27107
27232
|
TimerManager,
|
|
27108
27233
|
TokenContext,
|
|
27109
27234
|
TokenProvider,
|
|
@@ -27116,6 +27241,7 @@ export {
|
|
|
27116
27241
|
TranslationContainerContext,
|
|
27117
27242
|
TranslationContext,
|
|
27118
27243
|
TransportFactory,
|
|
27244
|
+
TransportNotReadyError,
|
|
27119
27245
|
Trouble,
|
|
27120
27246
|
TroubleAwareSetup,
|
|
27121
27247
|
TroubleContainer,
|
|
@@ -27211,6 +27337,7 @@ export {
|
|
|
27211
27337
|
getKosLocalizationDescriptor,
|
|
27212
27338
|
getKosMessageLogging,
|
|
27213
27339
|
getKosModel$1 as getKosModel,
|
|
27340
|
+
getKosModelActivationState,
|
|
27214
27341
|
getKosModelSync,
|
|
27215
27342
|
getKosModelType,
|
|
27216
27343
|
getKosServiceApi,
|
|
@@ -27253,6 +27380,7 @@ export {
|
|
|
27253
27380
|
isLocalRefId,
|
|
27254
27381
|
isNumber,
|
|
27255
27382
|
isPrintable,
|
|
27383
|
+
isTransportNotReadyError,
|
|
27256
27384
|
isTroubleAware,
|
|
27257
27385
|
isValidDate,
|
|
27258
27386
|
kosAction,
|