@route-forge/core 2.1.0 → 2.2.1
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/README.md +282 -210
- package/README_zh.md +408 -0
- package/dist/codegen.cjs +2 -26
- package/dist/codegen.cjs.map +1 -1
- package/dist/codegen.d.cts +2 -9
- package/dist/codegen.d.ts +2 -9
- package/dist/codegen.js +2 -26
- package/dist/codegen.js.map +1 -1
- package/dist/index.cjs +101 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -5
- package/dist/index.d.ts +13 -5
- package/dist/index.js +101 -48
- package/dist/index.js.map +1 -1
- package/dist/route-forge.global.js +101 -48
- package/dist/route-forge.global.js.map +1 -1
- package/dist/route-forge.global.min.js +2 -2
- package/dist/{types-C51rXaiY.d.cts → types-CDKE8rw-.d.cts} +41 -22
- package/dist/{types-C51rXaiY.d.ts → types-CDKE8rw-.d.ts} +41 -22
- package/package.json +20 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as RouteForgeOptions, b as RouteForge, I as InterceptorManager, c as InterceptorHandler, C as CacheStorage, R as RouteMeta, L as LevelRoutesResponse } from './types-
|
|
2
|
-
export { A as AdapterOption, d as ApiCallParams, B as BoundForge, F as Fetcher, e as ForgeApiParams, f as ForgeApiResponse, g as ForgeRequest, h as ForgeRouteMap, i as ForgeRouteName, j as LoadingChangeCallback, k as LoadingChangeEvent, l as LoadingTracker, m as RequestConfig, n as ResponseData, S as SummaryResponse, U as UseForgeApiBoundCall, o as UseForgeApiBoundReturn, p as UseForgeApiCall, q as UseForgeApiReturn } from './types-
|
|
1
|
+
import { a as RouteForgeOptions, b as RouteForge, I as InterceptorManager, c as InterceptorHandler, C as CacheStorage, R as RouteMeta, L as LevelRoutesResponse } from './types-CDKE8rw-.cjs';
|
|
2
|
+
export { A as AdapterOption, d as ApiCallParams, B as BoundForge, F as Fetcher, e as ForgeApiParams, f as ForgeApiResponse, g as ForgeRequest, h as ForgeRouteMap, i as ForgeRouteName, j as LoadingChangeCallback, k as LoadingChangeEvent, l as LoadingTracker, m as RequestConfig, n as ResponseData, S as SummaryResponse, U as UseForgeApiBoundCall, o as UseForgeApiBoundReturn, p as UseForgeApiCall, q as UseForgeApiReturn } from './types-CDKE8rw-.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Route Forge 主入口:createRouteForge
|
|
@@ -13,7 +13,7 @@ export { A as AdapterOption, d as ApiCallParams, B as BoundForge, F as Fetcher,
|
|
|
13
13
|
* - Adapter auto 检测 / builtin / axios / 自定义 Fetcher(§4.3)
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
declare function createRouteForge(options
|
|
16
|
+
declare function createRouteForge(options?: RouteForgeOptions): RouteForge;
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* 拦截器管理器实现
|
|
@@ -57,7 +57,8 @@ declare function createInterceptorManager<TIn, TOut = TIn>(): InterceptorManager
|
|
|
57
57
|
*
|
|
58
58
|
* 规则:
|
|
59
59
|
* - 每层级独立条目,互不污染(cache key = `route-forge:${level}`)
|
|
60
|
-
* - TTL
|
|
60
|
+
* - 后端 TTL 唯一来源为摘要 config.cache_ttl(全局,经 set 的 backendTtl 参数传入):
|
|
61
|
+
* null=不缓存(只留内存镜像、不落存储)、0=永久、正整数=min(后端, 前端 cache.ttl 兜底)
|
|
61
62
|
* - storage: 'memory' | 'sessionStorage' | 'localStorage'
|
|
62
63
|
* - storage 模式下维护内存镜像:首次读盘解析后驻留内存,后续 get 直接命中
|
|
63
64
|
* (读盘 + JSON.parse 整层路由表是同步阻塞操作,热路径重复执行代价高);
|
|
@@ -85,7 +86,14 @@ declare class RouteCache {
|
|
|
85
86
|
private key;
|
|
86
87
|
get(level: string): CacheEntry | undefined;
|
|
87
88
|
private getFromMemory;
|
|
88
|
-
|
|
89
|
+
/**
|
|
90
|
+
* 写入某层级缓存。后端 TTL 唯一来源为摘要 config.cache_ttl(全局),经参数 backendTtl 传入:
|
|
91
|
+
* - null → 后端声明"不缓存":不写 storage,仅留内存镜像供 route() 同步读(load 层"每次重取"由调用方跳过 get 短路实现)
|
|
92
|
+
* - 0 → 永久缓存(内存 + storage)
|
|
93
|
+
* - undefined → 后端未下发该字段:用前端兜底 TTL(options.cache.ttl)
|
|
94
|
+
* - 正整数 → min(后端, 前端兜底):后端为上限,前端只能缩短不能延长(SPEC §5.3)
|
|
95
|
+
*/
|
|
96
|
+
set(resp: LevelRoutesResponse, backendTtl: number | null | undefined): void;
|
|
89
97
|
del(level: string): void;
|
|
90
98
|
clear(): void;
|
|
91
99
|
private isExpired;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as RouteForgeOptions, b as RouteForge, I as InterceptorManager, c as InterceptorHandler, C as CacheStorage, R as RouteMeta, L as LevelRoutesResponse } from './types-
|
|
2
|
-
export { A as AdapterOption, d as ApiCallParams, B as BoundForge, F as Fetcher, e as ForgeApiParams, f as ForgeApiResponse, g as ForgeRequest, h as ForgeRouteMap, i as ForgeRouteName, j as LoadingChangeCallback, k as LoadingChangeEvent, l as LoadingTracker, m as RequestConfig, n as ResponseData, S as SummaryResponse, U as UseForgeApiBoundCall, o as UseForgeApiBoundReturn, p as UseForgeApiCall, q as UseForgeApiReturn } from './types-
|
|
1
|
+
import { a as RouteForgeOptions, b as RouteForge, I as InterceptorManager, c as InterceptorHandler, C as CacheStorage, R as RouteMeta, L as LevelRoutesResponse } from './types-CDKE8rw-.js';
|
|
2
|
+
export { A as AdapterOption, d as ApiCallParams, B as BoundForge, F as Fetcher, e as ForgeApiParams, f as ForgeApiResponse, g as ForgeRequest, h as ForgeRouteMap, i as ForgeRouteName, j as LoadingChangeCallback, k as LoadingChangeEvent, l as LoadingTracker, m as RequestConfig, n as ResponseData, S as SummaryResponse, U as UseForgeApiBoundCall, o as UseForgeApiBoundReturn, p as UseForgeApiCall, q as UseForgeApiReturn } from './types-CDKE8rw-.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Route Forge 主入口:createRouteForge
|
|
@@ -13,7 +13,7 @@ export { A as AdapterOption, d as ApiCallParams, B as BoundForge, F as Fetcher,
|
|
|
13
13
|
* - Adapter auto 检测 / builtin / axios / 自定义 Fetcher(§4.3)
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
declare function createRouteForge(options
|
|
16
|
+
declare function createRouteForge(options?: RouteForgeOptions): RouteForge;
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* 拦截器管理器实现
|
|
@@ -57,7 +57,8 @@ declare function createInterceptorManager<TIn, TOut = TIn>(): InterceptorManager
|
|
|
57
57
|
*
|
|
58
58
|
* 规则:
|
|
59
59
|
* - 每层级独立条目,互不污染(cache key = `route-forge:${level}`)
|
|
60
|
-
* - TTL
|
|
60
|
+
* - 后端 TTL 唯一来源为摘要 config.cache_ttl(全局,经 set 的 backendTtl 参数传入):
|
|
61
|
+
* null=不缓存(只留内存镜像、不落存储)、0=永久、正整数=min(后端, 前端 cache.ttl 兜底)
|
|
61
62
|
* - storage: 'memory' | 'sessionStorage' | 'localStorage'
|
|
62
63
|
* - storage 模式下维护内存镜像:首次读盘解析后驻留内存,后续 get 直接命中
|
|
63
64
|
* (读盘 + JSON.parse 整层路由表是同步阻塞操作,热路径重复执行代价高);
|
|
@@ -85,7 +86,14 @@ declare class RouteCache {
|
|
|
85
86
|
private key;
|
|
86
87
|
get(level: string): CacheEntry | undefined;
|
|
87
88
|
private getFromMemory;
|
|
88
|
-
|
|
89
|
+
/**
|
|
90
|
+
* 写入某层级缓存。后端 TTL 唯一来源为摘要 config.cache_ttl(全局),经参数 backendTtl 传入:
|
|
91
|
+
* - null → 后端声明"不缓存":不写 storage,仅留内存镜像供 route() 同步读(load 层"每次重取"由调用方跳过 get 短路实现)
|
|
92
|
+
* - 0 → 永久缓存(内存 + storage)
|
|
93
|
+
* - undefined → 后端未下发该字段:用前端兜底 TTL(options.cache.ttl)
|
|
94
|
+
* - 正整数 → min(后端, 前端兜底):后端为上限,前端只能缩短不能延长(SPEC §5.3)
|
|
95
|
+
*/
|
|
96
|
+
set(resp: LevelRoutesResponse, backendTtl: number | null | undefined): void;
|
|
89
97
|
del(level: string): void;
|
|
90
98
|
clear(): void;
|
|
91
99
|
private isExpired;
|
package/dist/index.js
CHANGED
|
@@ -61,12 +61,28 @@ var RouteCache = class {
|
|
|
61
61
|
}
|
|
62
62
|
return entry;
|
|
63
63
|
}
|
|
64
|
-
|
|
64
|
+
/**
|
|
65
|
+
* 写入某层级缓存。后端 TTL 唯一来源为摘要 config.cache_ttl(全局),经参数 backendTtl 传入:
|
|
66
|
+
* - null → 后端声明"不缓存":不写 storage,仅留内存镜像供 route() 同步读(load 层"每次重取"由调用方跳过 get 短路实现)
|
|
67
|
+
* - 0 → 永久缓存(内存 + storage)
|
|
68
|
+
* - undefined → 后端未下发该字段:用前端兜底 TTL(options.cache.ttl)
|
|
69
|
+
* - 正整数 → min(后端, 前端兜底):后端为上限,前端只能缩短不能延长(SPEC §5.3)
|
|
70
|
+
*/
|
|
71
|
+
set(resp, backendTtl) {
|
|
65
72
|
let ttl;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
let persist;
|
|
74
|
+
if (backendTtl === null) {
|
|
75
|
+
ttl = 0;
|
|
76
|
+
persist = false;
|
|
77
|
+
} else if (backendTtl === void 0) {
|
|
69
78
|
ttl = this.fallbackTtl;
|
|
79
|
+
persist = true;
|
|
80
|
+
} else if (backendTtl === 0) {
|
|
81
|
+
ttl = 0;
|
|
82
|
+
persist = true;
|
|
83
|
+
} else {
|
|
84
|
+
ttl = Math.min(backendTtl, this.fallbackTtl);
|
|
85
|
+
persist = true;
|
|
70
86
|
}
|
|
71
87
|
const entry = {
|
|
72
88
|
level: resp.level,
|
|
@@ -75,7 +91,7 @@ var RouteCache = class {
|
|
|
75
91
|
cachedAt: Date.now()
|
|
76
92
|
};
|
|
77
93
|
this.memory.set(resp.level, entry);
|
|
78
|
-
if (this.storage === "memory" || !this.backend) {
|
|
94
|
+
if (!persist || this.storage === "memory" || !this.backend) {
|
|
79
95
|
return;
|
|
80
96
|
}
|
|
81
97
|
try {
|
|
@@ -655,9 +671,11 @@ function resolveApiParams(input) {
|
|
|
655
671
|
}
|
|
656
672
|
|
|
657
673
|
// src/auto-discovery.ts
|
|
658
|
-
var UNASSIGNED_LEVEL = "unassigned";
|
|
659
674
|
async function fetchSummary(inputs, baseURL, fetchMeta) {
|
|
660
675
|
const { explicitLevels, explicitEndpoint } = inputs;
|
|
676
|
+
if (!explicitEndpoint) {
|
|
677
|
+
throw new UnknownLevelError("(auto-discovery)");
|
|
678
|
+
}
|
|
661
679
|
try {
|
|
662
680
|
const base = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
|
|
663
681
|
const ep = explicitEndpoint.startsWith("/") ? explicitEndpoint : `/${explicitEndpoint}`;
|
|
@@ -673,35 +691,42 @@ async function fetchSummary(inputs, baseURL, fetchMeta) {
|
|
|
673
691
|
throw new UnknownLevelError("(auto-discovery)");
|
|
674
692
|
}
|
|
675
693
|
}
|
|
694
|
+
function normalizeCacheTtl(raw) {
|
|
695
|
+
if (typeof raw === "number" && raw < 0) return null;
|
|
696
|
+
return raw;
|
|
697
|
+
}
|
|
676
698
|
function applySummaryToState(summary, state, inputs) {
|
|
677
699
|
const { explicitLevels, explicitEager, explicitEndpoint } = inputs;
|
|
678
|
-
const
|
|
679
|
-
if (
|
|
700
|
+
const schemeVersion = summary.schemeVersion ?? 1;
|
|
701
|
+
if (schemeVersion > 1) {
|
|
680
702
|
console.warn(
|
|
681
|
-
`[route-forge] backend
|
|
703
|
+
`[route-forge] backend schemeVersion=${schemeVersion} > client supported 1; some features may be unavailable`
|
|
682
704
|
);
|
|
683
705
|
}
|
|
684
706
|
if (summary.config.endpoint_prefix && summary.config.endpoint_prefix !== explicitEndpoint) {
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
707
|
+
if (explicitEndpoint) {
|
|
708
|
+
console.warn(
|
|
709
|
+
`[route-forge] backend endpoint_prefix "${summary.config.endpoint_prefix}" overrides frontend endpoint "${explicitEndpoint}"`
|
|
710
|
+
);
|
|
711
|
+
}
|
|
688
712
|
state.endpoint = summary.config.endpoint_prefix;
|
|
689
713
|
}
|
|
690
714
|
if (summary.config.url_prefix) {
|
|
691
715
|
state.urlPrefix = summary.config.url_prefix.endsWith("/") ? summary.config.url_prefix.slice(0, -1) : summary.config.url_prefix;
|
|
692
716
|
}
|
|
717
|
+
state.cacheTtl = normalizeCacheTtl(summary.config.cache_ttl);
|
|
693
718
|
const backendLevels = Object.keys(summary.levels);
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
availableLevels.push(UNASSIGNED_LEVEL);
|
|
719
|
+
const levelRoutes = {};
|
|
720
|
+
for (const lvl of backendLevels) {
|
|
721
|
+
const r = summary.levels[lvl]?.route;
|
|
722
|
+
if (r && typeof r.uri === "string") {
|
|
723
|
+
levelRoutes[lvl] = { uri: r.uri, methods: r.methods ?? ["GET", "HEAD"] };
|
|
724
|
+
}
|
|
701
725
|
}
|
|
726
|
+
state.levelRoutes = levelRoutes;
|
|
702
727
|
if (explicitLevels && explicitLevels.length > 0) {
|
|
703
|
-
const intersection = explicitLevels.filter((l) =>
|
|
704
|
-
const removed = explicitLevels.filter((l) => !
|
|
728
|
+
const intersection = explicitLevels.filter((l) => backendLevels.includes(l));
|
|
729
|
+
const removed = explicitLevels.filter((l) => !backendLevels.includes(l));
|
|
705
730
|
if (removed.length > 0) {
|
|
706
731
|
console.warn(
|
|
707
732
|
`[route-forge] levels not in backend summary and dropped: ${removed.join(", ")}`
|
|
@@ -709,7 +734,7 @@ function applySummaryToState(summary, state, inputs) {
|
|
|
709
734
|
}
|
|
710
735
|
state.levels = intersection;
|
|
711
736
|
} else {
|
|
712
|
-
state.levels =
|
|
737
|
+
state.levels = backendLevels.slice();
|
|
713
738
|
}
|
|
714
739
|
const backendEager = backendLevels.filter((lvl) => summary.levels[lvl]?.load === "eager");
|
|
715
740
|
if (!explicitEager) {
|
|
@@ -720,6 +745,25 @@ function applySummaryToState(summary, state, inputs) {
|
|
|
720
745
|
}
|
|
721
746
|
}
|
|
722
747
|
|
|
748
|
+
// src/embedded-summary.ts
|
|
749
|
+
var EMBEDDED_GLOBAL_KEY = "__ROUTE_FORGE__";
|
|
750
|
+
var memo;
|
|
751
|
+
function readEmbeddedSummary() {
|
|
752
|
+
if (memo !== void 0) return memo;
|
|
753
|
+
if (typeof window === "undefined") {
|
|
754
|
+
memo = null;
|
|
755
|
+
return null;
|
|
756
|
+
}
|
|
757
|
+
let raw;
|
|
758
|
+
try {
|
|
759
|
+
raw = window[EMBEDDED_GLOBAL_KEY];
|
|
760
|
+
} catch {
|
|
761
|
+
raw = void 0;
|
|
762
|
+
}
|
|
763
|
+
memo = raw !== null && typeof raw === "object" ? raw : null;
|
|
764
|
+
return memo;
|
|
765
|
+
}
|
|
766
|
+
|
|
723
767
|
// src/route-store.ts
|
|
724
768
|
var RouteStore = class {
|
|
725
769
|
constructor(deps) {
|
|
@@ -739,33 +783,30 @@ var RouteStore = class {
|
|
|
739
783
|
}
|
|
740
784
|
}
|
|
741
785
|
async fetchLevel(level) {
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
786
|
+
const uri = this.state.levelRoutes[level]?.uri;
|
|
787
|
+
const url = uri ? this.joinBaseAndPath(this.baseURL, uri) : buildUrl(level, { baseURL: this.baseURL, endpoint: this.state.endpoint });
|
|
788
|
+
return await this.fetchMeta(`route-forge.${level}`, url, level);
|
|
789
|
+
}
|
|
790
|
+
/** baseURL 与后端下发的绝对 path 拼接(规范化斜杠),与 buildUrl 的 base 处理一致 */
|
|
791
|
+
joinBaseAndPath(baseURL, path) {
|
|
792
|
+
const base = baseURL.endsWith("/") ? baseURL.slice(0, -1) : baseURL;
|
|
793
|
+
const p = path.startsWith("/") ? path : `/${path}`;
|
|
794
|
+
return `${base}${p}`;
|
|
747
795
|
}
|
|
748
796
|
async loadOne(level) {
|
|
749
797
|
const autoDiscoveryError = this.getAutoDiscoveryError();
|
|
750
798
|
if (autoDiscoveryError) throw autoDiscoveryError;
|
|
751
799
|
this.assertLevelDeclared(level);
|
|
752
|
-
|
|
800
|
+
const noCache = this.state.cacheTtl === null;
|
|
801
|
+
if (!noCache && this.cache.get(level)) return;
|
|
753
802
|
const existing = this.inflight.get(level);
|
|
754
803
|
if (existing) return existing;
|
|
755
804
|
const gen = this.invalidationGens.get(level) ?? 0;
|
|
756
805
|
const p = (async () => {
|
|
757
806
|
try {
|
|
758
|
-
if (level === UNASSIGNED_LEVEL && !this.state.backendHasUnassignedLevel && this.state.summaryUnassigned) {
|
|
759
|
-
const routes = {};
|
|
760
|
-
for (const r of this.state.summaryUnassigned) {
|
|
761
|
-
routes[r.name] = { ...r, level: UNASSIGNED_LEVEL };
|
|
762
|
-
}
|
|
763
|
-
this.cache.set({ level: UNASSIGNED_LEVEL, routes, cache: null });
|
|
764
|
-
return;
|
|
765
|
-
}
|
|
766
807
|
const resp = await this.fetchLevel(level);
|
|
767
808
|
if ((this.invalidationGens.get(level) ?? 0) === gen) {
|
|
768
|
-
this.cache.set(resp);
|
|
809
|
+
this.cache.set(resp, this.state.cacheTtl);
|
|
769
810
|
}
|
|
770
811
|
} finally {
|
|
771
812
|
this.inflight.delete(level);
|
|
@@ -1048,8 +1089,13 @@ function createBoundForgeFactory(deps) {
|
|
|
1048
1089
|
// src/forge.ts
|
|
1049
1090
|
var DEFAULT_TIMEOUT = 3e4;
|
|
1050
1091
|
var DEFAULT_CACHE_TTL = 3600;
|
|
1051
|
-
function createRouteForge(options) {
|
|
1052
|
-
|
|
1092
|
+
function createRouteForge(options = {}) {
|
|
1093
|
+
const bootstrapSummary = readEmbeddedSummary() ?? options.summary ?? null;
|
|
1094
|
+
if (!bootstrapSummary && !options.endpoint) {
|
|
1095
|
+
throw new TypeError(
|
|
1096
|
+
"createRouteForge: \u9700\u8981 options.endpoint\uFF0C\u6216 options.summary\uFF0C\u6216\u9875\u9762\u5185\u5D4C window.__ROUTE_FORGE__"
|
|
1097
|
+
);
|
|
1098
|
+
}
|
|
1053
1099
|
const {
|
|
1054
1100
|
adapter = "auto",
|
|
1055
1101
|
timeout = DEFAULT_TIMEOUT,
|
|
@@ -1064,10 +1110,10 @@ function createRouteForge(options) {
|
|
|
1064
1110
|
const discoveryState = {
|
|
1065
1111
|
levels: explicitLevels ?? [],
|
|
1066
1112
|
eager: explicitEager ?? [],
|
|
1067
|
-
endpoint: explicitEndpoint,
|
|
1113
|
+
endpoint: explicitEndpoint ?? bootstrapSummary?.config?.endpoint_prefix ?? "",
|
|
1068
1114
|
urlPrefix: "",
|
|
1069
|
-
|
|
1070
|
-
|
|
1115
|
+
cacheTtl: void 0,
|
|
1116
|
+
levelRoutes: {}
|
|
1071
1117
|
};
|
|
1072
1118
|
const discoveryInputs = { explicitLevels, explicitEager, explicitEndpoint };
|
|
1073
1119
|
let autoDiscoveryCompleted = false;
|
|
@@ -1159,12 +1205,19 @@ function createRouteForge(options) {
|
|
|
1159
1205
|
}
|
|
1160
1206
|
return resp.data;
|
|
1161
1207
|
}
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
}
|
|
1208
|
+
let autoDiscoveryPromise;
|
|
1209
|
+
if (bootstrapSummary) {
|
|
1210
|
+
applySummaryToState(bootstrapSummary, discoveryState, discoveryInputs);
|
|
1211
|
+
autoDiscoveryCompleted = true;
|
|
1212
|
+
autoDiscoveryPromise = Promise.resolve();
|
|
1213
|
+
} else {
|
|
1214
|
+
autoDiscoveryPromise = fetchSummary(discoveryInputs, baseURL, fetchMeta).then((summary) => {
|
|
1215
|
+
if (summary === null) {
|
|
1216
|
+
return;
|
|
1217
|
+
}
|
|
1218
|
+
applySummaryToState(summary, discoveryState, discoveryInputs);
|
|
1219
|
+
});
|
|
1220
|
+
}
|
|
1168
1221
|
let autoDiscoveryError = null;
|
|
1169
1222
|
autoDiscoveryPromise.catch((e) => {
|
|
1170
1223
|
autoDiscoveryError = e;
|