@miot-rn/common-component 1.0.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.
Files changed (40) hide show
  1. package/README.md +9 -0
  2. package/dist/index.d.ts +0 -0
  3. package/dist/index.js +0 -0
  4. package/dist/resources/i18n.d.ts +55 -0
  5. package/dist/resources/i18n.js +212 -0
  6. package/dist/service/specs/error-code.d.ts +19 -0
  7. package/dist/service/specs/error-code.js +41 -0
  8. package/dist/service/specs/index.d.ts +95 -0
  9. package/dist/service/specs/index.js +412 -0
  10. package/dist/service/specs/spec.d.ts +10 -0
  11. package/dist/service/specs/spec.js +109 -0
  12. package/dist/service/specs/specCache.d.ts +85 -0
  13. package/dist/service/specs/specCache.js +421 -0
  14. package/dist/service/specs/std-spec.d.ts +5 -0
  15. package/dist/service/specs/std-spec.js +228 -0
  16. package/dist/service/specs/subject.d.ts +20 -0
  17. package/dist/service/specs/subject.js +145 -0
  18. package/dist/service/specs/utils.d.ts +28 -0
  19. package/dist/service/specs/utils.js +46 -0
  20. package/dist/specs/i18n-parser.d.ts +10 -0
  21. package/dist/specs/i18n-parser.js +300 -0
  22. package/dist/specs/instance-parser.d.ts +26 -0
  23. package/dist/specs/instance-parser.js +706 -0
  24. package/dist/store/useGlobalSpecManager.d.ts +320 -0
  25. package/dist/store/useGlobalSpecManager.js +867 -0
  26. package/dist/types/index.d.ts +23 -0
  27. package/dist/types/index.js +1 -0
  28. package/dist/utils/fns.d.ts +12 -0
  29. package/dist/utils/fns.js +308 -0
  30. package/dist/utils/get-value-or-default.d.ts +1 -0
  31. package/dist/utils/get-value-or-default.js +4 -0
  32. package/dist/utils/i18n.d.ts +1 -0
  33. package/dist/utils/i18n.js +141 -0
  34. package/dist/utils/objects.d.ts +2 -0
  35. package/dist/utils/objects.js +222 -0
  36. package/dist/utils/spec.d.ts +8 -0
  37. package/dist/utils/spec.js +171 -0
  38. package/dist/utils/types.d.ts +3 -0
  39. package/dist/utils/types.js +25 -0
  40. package/package.json +27 -0
@@ -0,0 +1,145 @@
1
+ import { DeviceEventEmitter } from 'react-native';
2
+ import { removeDuplicateIf } from "../../utils/fns";
3
+ import { deepEqual } from "../../utils/objects";
4
+
5
+ /**
6
+ * 事件订阅/发布管理器,支持如下功能:
7
+ * 1 subscribe 订阅 topic、publish 发布 topic、unsubscribeAll 取消所有订阅
8
+ * 2 设置 Filter,定制事件的发布策略,如取消重复发布、延迟发布等
9
+ */
10
+ export default class Subject {
11
+ /**
12
+ * 创建 Subject
13
+ * @param keyOf 将 topic 转化为全局唯一的 String
14
+ * @param handler 可选,自定义订阅/发布的具体实现
15
+ */
16
+ constructor(keyOf, handler) {
17
+ this.keyOf = keyOf;
18
+ this.subscriptions = new Set();
19
+ if (handler) {
20
+ this.handler = handler;
21
+ } else {
22
+ // 默认使用 DeviceEvent
23
+ this.handler = {
24
+ subscribe: (topic, listener) => {
25
+ return DeviceEventEmitter.addListener(this.keyOf(topic), listener);
26
+ },
27
+ publish: topic => {
28
+ const key = this.keyOf(topic);
29
+ DeviceEventEmitter.emit(key, topic);
30
+ }
31
+ };
32
+ }
33
+ }
34
+
35
+ /**
36
+ * 设置 Filter
37
+ * @param filter 接口对象,需要实现如下接口 <p/>
38
+ * 1 setPublisher,设置实际的发布者
39
+ * 2 accept,判断当前发布的处理转移给filter, true 为转移
40
+ * 3 reset,重置 filter 的状态
41
+ */
42
+ setFilter(filter) {
43
+ this.filter = filter;
44
+ if (this.filter && this.filter.setPublisher) {
45
+ this.filter.setPublisher(this.handler.publish);
46
+ }
47
+ }
48
+
49
+ /**
50
+ * 订阅 topic,返回 subscription,其中包含:<p/>
51
+ * 1 unsubscribe,用于取消监听
52
+ * 2 isActive,表示该监听是否生效,subscribe - unsubscribe 之间为 true,否则为 false
53
+ * 2 topics,表示订阅成功的 topic 列表
54
+ * @param topics
55
+ * @param listener
56
+ * @returns {{unsubscribe: subscription.unsubscribe, topics, isActive: (function(): boolean)}}
57
+ */
58
+ subscribe(topics, listener) {
59
+ let subscribed = topics.map(t => {
60
+ return this.handler.subscribe && this.handler.subscribe(t, listener);
61
+ }).filter(l => l);
62
+ const subscription = {
63
+ unsubscribe: () => {
64
+ if (subscribed) {
65
+ subscribed.forEach(l => {
66
+ l.remove();
67
+ });
68
+ subscribed = undefined;
69
+ this.subscriptions.delete(subscription);
70
+ }
71
+ },
72
+ isActive: () => {
73
+ return !!subscribed;
74
+ },
75
+ topics
76
+ };
77
+ this.subscriptions.add(subscription);
78
+ return subscription;
79
+ }
80
+
81
+ /**
82
+ * 获取已经订阅的所有 topics
83
+ * @returns {*[]}
84
+ */
85
+ getAllTopics() {
86
+ let result = [];
87
+ for (const sub of this.subscriptions) {
88
+ if (sub.isActive()) {
89
+ result = result.concat(sub.topics);
90
+ }
91
+ }
92
+ // @ts-ignore
93
+ removeDuplicateIf(result, ele => this.keyOf(ele));
94
+ return result;
95
+ }
96
+
97
+ /**
98
+ * 发布消息
99
+ *
100
+ * @param topic
101
+ * @param active 标识改发布是主动的还是被动的,如果是插件自身触发为主动,如果从云端收到更新为被动
102
+ * @param callback
103
+ */
104
+ publish(topic, active, callback) {
105
+ const key = this.keyOf(topic);
106
+ if (this.handler.publish) {
107
+ if (this.filter && this.filter.accept(key, topic, active, callback)) {
108
+ // Filter accepted, do nothing
109
+ } else {
110
+ callback && callback(topic);
111
+ this.handler.publish(topic);
112
+ }
113
+ }
114
+ }
115
+
116
+ /**
117
+ * 取消所有订阅
118
+ */
119
+ unsubscribeAll() {
120
+ for (const sub of this.subscriptions) {
121
+ if (sub.unsubscribe) {
122
+ sub.unsubscribe();
123
+ sub.unsubscribe = undefined;
124
+ }
125
+ }
126
+ this.subscriptions && this.subscriptions.clear();
127
+ this.filter && this.filter.reset && this.filter.reset();
128
+ }
129
+ }
130
+ export function newSimpleFilter() {
131
+ let lastValues = {};
132
+ return {
133
+ accept: (key, topic) => {
134
+ const lv = lastValues[key];
135
+ if (!lv || !deepEqual(topic, lv)) {
136
+ lastValues[key] = topic;
137
+ return false;
138
+ }
139
+ return true;
140
+ },
141
+ reset: () => {
142
+ lastValues = {};
143
+ }
144
+ };
145
+ }
@@ -0,0 +1,28 @@
1
+ import { Spec } from '../../types';
2
+ export declare function mergeProps(props1: Spec[], props2: Spec[], keyOf: (prop: Spec) => string): Spec[];
3
+ export declare function getEventGenerator(name: string, keyOf: (prop: Spec) => string): (prop: Spec) => string;
4
+ export declare function mapError(props: Spec[]): (reason: any) => {
5
+ message: any;
6
+ code: any;
7
+ did?: string | undefined;
8
+ siid: number;
9
+ piid?: number | undefined;
10
+ aiid?: number | undefined;
11
+ miid?: number | undefined;
12
+ value?: any;
13
+ in?: any[] | undefined;
14
+ dataSource?: number | undefined;
15
+ }[];
16
+ export declare function genError(prop: Spec): (reason: any) => {
17
+ message: any;
18
+ code: any;
19
+ did?: string | undefined;
20
+ siid: number;
21
+ piid?: number | undefined;
22
+ aiid?: number | undefined;
23
+ miid?: number | undefined;
24
+ value?: any;
25
+ in?: any[] | undefined;
26
+ dataSource?: number | undefined;
27
+ };
28
+ export declare function reduceResults(results: any[]): any;
@@ -0,0 +1,46 @@
1
+ import { PLUGIN_UNKNOWN_ERROR } from "./error-code";
2
+ export function mergeProps(props1, props2, keyOf) {
3
+ const cache = props2.reduce((acc, cur) => {
4
+ acc.set(keyOf(cur), cur);
5
+ return acc;
6
+ }, new Map());
7
+ return props1.map(p1 => {
8
+ const p2 = cache.get(keyOf(p1));
9
+ return p2 ? {
10
+ ...p1,
11
+ ...p2
12
+ } : null;
13
+ }).filter(p => !!p);
14
+ }
15
+ export function getEventGenerator(name, keyOf) {
16
+ return prop => {
17
+ return name ? `__${name}__${keyOf(prop)}` : `${keyOf(prop)}`;
18
+ };
19
+ }
20
+ export function mapError(props) {
21
+ return reason => {
22
+ const code = reason.code !== undefined ? reason.code : PLUGIN_UNKNOWN_ERROR;
23
+ return props.map(prop => {
24
+ return {
25
+ ...prop,
26
+ message: reason,
27
+ code
28
+ };
29
+ });
30
+ };
31
+ }
32
+ export function genError(prop) {
33
+ return reason => {
34
+ const code = reason.code !== undefined ? reason.code : PLUGIN_UNKNOWN_ERROR;
35
+ return {
36
+ ...prop,
37
+ message: reason,
38
+ code
39
+ };
40
+ };
41
+ }
42
+ export function reduceResults(results) {
43
+ return (results || []).reduce((preProps, curProps) => {
44
+ return [...preProps, ...curProps];
45
+ }, []);
46
+ }
@@ -0,0 +1,10 @@
1
+ import { Spec } from '../types';
2
+ export declare function init(i18n: any): void;
3
+ export declare function getI18n(): any;
4
+ export declare function getLocalI18n(key: string, replaces?: any[]): string | Record<string, string>;
5
+ export declare function mergeI18n(...i18ns: any[]): any;
6
+ export declare function getI18nKey(spec: Spec): string;
7
+ export declare function getI18nForSpecs(specs: Spec[], fn?: (...args: any[]) => any, lang?: string): string;
8
+ export declare function getI18nForSpecValue(spec: Spec, value: any, fn?: (...args: any[]) => any, lang?: string): string;
9
+ export declare function getI18nListForSpecs(spec: Spec, lang?: string): any[];
10
+ export declare function transformUnit(unit: string, long?: boolean): string;
@@ -0,0 +1,300 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types */
2
+ // spec多语言 服务,在init 初始化后,可以通过各方法拉取功能定义的文案和内置文案
3
+
4
+ // @ts-ignore
5
+ import { Host } from 'miot';
6
+ import { i18ns as LocalI18ns } from "../resources/i18n";
7
+ import getValueOrDefault from "../utils/get-value-or-default";
8
+ import { getPluralRules } from "../utils/i18n";
9
+ import { getIndexBySpecValue } from "./instance-parser";
10
+ import { isTypeOf } from "../utils/types";
11
+ let CachedI18n = null;
12
+ const defaultLang = 'en';
13
+
14
+ /* eslint-disable camelcase */
15
+ const LangMap = {
16
+ nl: 'nl_NL',
17
+ tr: 'tr_TR',
18
+ zh: 'zh_cn',
19
+ pt: 'pt_BR',
20
+ el: 'el_gr',
21
+ cs: 'cs_cz',
22
+ ro: 'ro_ro',
23
+ uk: 'uk_ua',
24
+ sv: 'sv_SE',
25
+ es_us: 'es_US',
26
+ nb: 'nb_NO',
27
+ fi: 'fi_FI'
28
+ };
29
+ /* eslint-enable camelcase */
30
+
31
+ const FlagMap = {
32
+ module: 'module',
33
+ service: 'service',
34
+ property: 'property',
35
+ valuelist: 'valuelist',
36
+ action: 'action',
37
+ event: 'event'
38
+ };
39
+
40
+ /**
41
+ * 文案处理函数类型定义
42
+ * @typedef {function(string[], string): string} I18nProcessor
43
+ * @param {string[]} specI18ns - 多语言文案数组
44
+ * @param {string} lang - 当前语言
45
+ * @returns {string} 处理后的文案
46
+ */
47
+
48
+ function setCachedI18n(i18n) {
49
+ CachedI18n = i18n;
50
+ }
51
+
52
+ /**
53
+ * 根据功能定义对应的多语言,进行初始化,方便后续根据siid, piid 等信息直接拿对应spec 的文案
54
+ * @param {object} 多语言 {en: {}, zh_cn: {}}
55
+ * @return {void}
56
+ */
57
+ export function init(i18n) {
58
+ setCachedI18n(i18n);
59
+ }
60
+ export function getI18n() {
61
+ return CachedI18n;
62
+ }
63
+
64
+ /**
65
+ * 根据key 和替换规则,返回内置多语言文案
66
+ * @param {string} key 内置多语言(assets/i18n)中定义的文案的key
67
+ * @param {replaces} key 对应的内置文案中,将通用占位符${} 依次替换为replaces 中的文本或占位符
68
+ * @return {string} 替换后的文案
69
+ */
70
+ export function getLocalI18n(key, replaces = []) {
71
+ const lang = Host.locale.language;
72
+ const firstNumber = replaces.find(v => isTypeOf('Number', v));
73
+ const isNumber = typeof firstNumber === 'number';
74
+ const localI18n = LocalI18ns[lang] || LocalI18ns[defaultLang] || {};
75
+ let target = localI18n[key];
76
+ if (!target) {
77
+ return '';
78
+ }
79
+ // 不区分单复数的,直接替换
80
+ if (!isTypeOf('Object', target)) {
81
+ let result = target;
82
+ replaces.forEach((r, i) => {
83
+ result = result.replace('${}', r);
84
+ result = result.replace(`{${i + 1}}`, r);
85
+ });
86
+ return result;
87
+ }
88
+ // 区分单复数的
89
+ // 如果第一个参数是数字,则取最终值
90
+ if (isNumber) {
91
+ const targetObj = target;
92
+ let result = targetObj[getPluralRules(lang, firstNumber)];
93
+ replaces.forEach((r, i) => {
94
+ result = result.replace('${}', r);
95
+ result = result.replace(`{${i + 1}}`, r);
96
+ });
97
+ return result;
98
+ }
99
+ // 如果不是数字(比如占位符或其他文案),则把每一项都替换,在实际使用时由控件的i18n.get 处理
100
+ return Object.entries(target).reduce((ret, [k, v]) => {
101
+ return {
102
+ ...ret,
103
+ [k]: (v => {
104
+ let result = v;
105
+ replaces.forEach((r, i) => {
106
+ result = result.replace('${}', r);
107
+ result = result.replace(`{${i + 1}}`, r);
108
+ });
109
+ return result;
110
+ })(v)
111
+ };
112
+ }, {});
113
+ }
114
+
115
+ /**
116
+ * 将多个文案配置依次合并成一个,后者相对于前者的差异部分,替换或新增
117
+ * 注意:参数中不需要带有语言标识
118
+ * @param {object} 文案配置,如{title: 'xxx'},支持多个参数依次列开
119
+ * @return {object} 合并后的配置
120
+ */
121
+ export function mergeI18n(...i18ns) {
122
+ return i18ns.reduce((ret, i18n) => {
123
+ return {
124
+ ...ret,
125
+ ...(i18n || {})
126
+ };
127
+ }, {});
128
+ }
129
+ function getI18nKeyFlag(type, n) {
130
+ const nLength = String(n).length;
131
+ const id = nLength <= 2 ? `000${n}`.slice(-3) : String(n);
132
+ return `${type}:${id}`;
133
+ }
134
+ export function getI18nKey(spec) {
135
+ if (!spec) {
136
+ return '';
137
+ }
138
+ const {
139
+ miid,
140
+ siid,
141
+ piid,
142
+ aiid,
143
+ eiid
144
+ } = spec;
145
+ const viid = spec.viid;
146
+ const keyFlags = [];
147
+ if (miid) {
148
+ keyFlags.push(getI18nKeyFlag(FlagMap.module, miid));
149
+ }
150
+ if (siid) {
151
+ keyFlags.push(getI18nKeyFlag(FlagMap.service, siid));
152
+ }
153
+ if (piid) {
154
+ keyFlags.push(getI18nKeyFlag(FlagMap.property, piid));
155
+
156
+ // value 比较特殊,是从0开始的序号
157
+ if (viid || viid === 0) {
158
+ keyFlags.push(getI18nKeyFlag(FlagMap.valuelist, viid));
159
+ }
160
+ }
161
+ if (aiid) {
162
+ keyFlags.push(getI18nKeyFlag(FlagMap.action, aiid));
163
+ }
164
+ if (eiid) {
165
+ keyFlags.push(getI18nKeyFlag(FlagMap.event, eiid));
166
+ }
167
+ return keyFlags.join(':');
168
+ }
169
+
170
+ /**
171
+ * 通过传入的specs 获取对应的功能定义文案,若有fn 则根据fn 对文案进行处理
172
+ * @param {array} specs 支持service({siid}), property({siid, piid}), valuelist({siid, piid, viid}), action({siid, aiid}), event({siid, eiid})
173
+ * @param {function} fn 对拿到的功能定义的文案进行额外处理
174
+ * @return {string} 最终返回的文案
175
+ */
176
+ export function getI18nForSpecs(specs, fn, lang = Host.locale.language) {
177
+ if (!CachedI18n) {
178
+ return '';
179
+ }
180
+ const i18n = CachedI18n[LangMap[lang] || lang] || CachedI18n[defaultLang] || CachedI18n.zh_cn || {};
181
+ // if (!i18n) {
182
+ // return '';
183
+ // }
184
+ const keys = specs.map(spec => {
185
+ const i18nKey = getI18nKey(spec);
186
+ return i18nKey;
187
+ });
188
+ const specI18ns = keys.map(key => {
189
+ return i18n[key] || (CachedI18n[defaultLang] ? CachedI18n[defaultLang][key] : '') || (CachedI18n.zh_cn ? CachedI18n.zh_cn[key] : '') || '';
190
+ });
191
+ if (!(fn instanceof Function)) {
192
+ return specI18ns[0];
193
+ }
194
+ return fn(specI18ns, lang);
195
+ }
196
+
197
+ /**
198
+ * 根据传入的spec和value获取对应value的spec文案
199
+ * 该方法通过调用instance-parser中的getIndexBySpecValue方法获取value对应的index,
200
+ * 并将该index作为viid参数传递给getI18nForSpecs方法,实现根据spec和value获取对应文案的功能
201
+ *
202
+ * @param {SpecObject} spec - 包含规范的对象,支持property({siid, piid})
203
+ * @param {any} value - 要查找的目标值,通常为数字类型
204
+ * @param {I18nProcessor} [fn] - 对拿到的功能定义的文案进行额外处理的函数
205
+ * @param {string} [lang=Host.locale.language] - 目标语言,默认为当前设备语言
206
+ * @return {string} 最终返回的文案,如果找不到对应的value或spec无效则返回空字符串
207
+ *
208
+ * @example
209
+ * // 获取座椅加热档位的文案
210
+ * const spec = { siid: 2, piid: 1 };
211
+ * const value = 2; // 对应Level 2
212
+ * const text = getI18nForSpecValue(spec, value);
213
+ * // 返回 "Level 2" 或对应的本地化文案
214
+ */
215
+ export function getI18nForSpecValue(spec, value, fn, lang = Host.locale.language) {
216
+ // 参数验证,提高代码健壮性
217
+ if (!spec || value === undefined || value === null) {
218
+ return '';
219
+ }
220
+
221
+ // 通过spec和value获取对应的index(viid)
222
+ // 这里复用instance-parser中已有的getIndexBySpecValue方法,保证逻辑一致性
223
+ const viid = getIndexBySpecValue(spec, value);
224
+
225
+ // 如果找不到对应的value,返回空字符串
226
+ if (viid === -1) {
227
+ return '';
228
+ }
229
+ // 构建包含viid的spec对象
230
+ // 使用对象展开运算符保持原有spec的其他属性不变
231
+ const specWithViid = {
232
+ ...spec,
233
+ viid: viid + 1
234
+ };
235
+
236
+ // 调用getI18nForSpecs获取对应的文案
237
+ // 传入数组格式以保持接口一致性
238
+ return getI18nForSpecs([specWithViid], fn, lang);
239
+ }
240
+
241
+ /**
242
+ * 通过传入的spec 获取对应的功能定义文案列表
243
+ * @param {array} spec
244
+ * @return {array} 最终返回的文案列表
245
+ */
246
+ export function getI18nListForSpecs(spec, lang = Host.locale.language) {
247
+ if (!CachedI18n) {
248
+ return [];
249
+ }
250
+ let i18n = CachedI18n[LangMap[lang] || lang] || CachedI18n[defaultLang] || CachedI18n.zh_cn || {};
251
+ if (Object.keys(i18n).length === 0) i18n = CachedI18n.zh_cn;
252
+ const flag = getI18nKey(spec);
253
+ const ans = [];
254
+ if (!i18n || typeof flag !== 'string') return ans;
255
+ for (const key in i18n) {
256
+ if (key.includes(flag) && key.includes('valuelist') && key.split(':').length > 0) {
257
+ ans.push({
258
+ num: Number(key.split(':').reverse()[0]),
259
+ desc: i18n[key] || (CachedI18n[defaultLang] ? CachedI18n[defaultLang][key] : '') || (CachedI18n.zh_cn ? CachedI18n.zh_cn[key] : '') || ''
260
+ });
261
+ }
262
+ }
263
+ return ans;
264
+ }
265
+
266
+ /**
267
+ * 根据spec 属性的unit, 获取多语言处理后的文案或标识
268
+ */
269
+ export function transformUnit(unit, long) {
270
+ const kvs = {
271
+ percentage: '%',
272
+ rgb: '',
273
+ kelvin: 'k',
274
+ pascal: 'Pa',
275
+ arcdegress: '°',
276
+ watt: 'w',
277
+ L: 'L',
278
+ ppm: 'ppm',
279
+ lux: 'lux',
280
+ 'mg/m3': 'mg/m3',
281
+ celsius: '℃',
282
+ none: '',
283
+ get m() {
284
+ return getLocalI18n('common_meter');
285
+ },
286
+ get seconds() {
287
+ return getLocalI18n('seconds');
288
+ },
289
+ get minutes() {
290
+ return long ? getLocalI18n('minutesFull') : getLocalI18n('minutes');
291
+ },
292
+ get hours() {
293
+ return long ? getLocalI18n('hoursFull') : getLocalI18n('hours');
294
+ },
295
+ get days() {
296
+ return getLocalI18n('days');
297
+ }
298
+ };
299
+ return getValueOrDefault(kvs, unit, unit) || '';
300
+ }
@@ -0,0 +1,26 @@
1
+ import { Spec, QuerySpecParams } from '../types';
2
+ export declare function init(instance?: any): void;
3
+ export declare function getInstance(): any;
4
+ export declare function getSpecVersion(): number;
5
+ export declare function getDynamicType(): number;
6
+ export declare function getValidModules(): any[];
7
+ export declare function parseSpecType(type: string): {
8
+ key: string;
9
+ version: number;
10
+ };
11
+ export declare function getSpecs(keys: QuerySpecParams[]): Spec[][];
12
+ export declare function getSpecsOnly(keys: QuerySpecParams[]): (Spec | null)[];
13
+ export declare function getSpecOnly(key: QuerySpecParams): Spec | null;
14
+ export declare function getSpecsIidsOnly(specs: Spec[]): Spec[];
15
+ export declare function getIndexBySpecValue(spec: any, targetValue: any): number;
16
+ export declare function getSpecValueList(spec: Spec): any[];
17
+ export declare function getValueBySpecDescription(spec: Spec, description: string): any;
18
+ export declare function getSpecValueRange(spec: Spec): any[];
19
+ export declare function getIndexBySpecDescription(spec: Spec, description: string): number;
20
+ export declare function getValueBySpecDescriptions(spec: Spec, descriptions?: string[]): any;
21
+ export declare function getIdleIndex(spec: Spec): number;
22
+ export declare function getKeyIndexOfInstance(instance: any, search: {
23
+ skey: string;
24
+ pkey: string;
25
+ }): [number, number];
26
+ export declare function getSpecsByIids(iids: any[]): any[];