@fmsim/api 2.0.0-beta.92 → 2.0.0-beta.95

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.
@@ -190,7 +190,7 @@
190
190
  },
191
191
  {
192
192
  "kind": "function",
193
- "name": "searchMachineUnits",
193
+ "name": "searchFigureIds",
194
194
  "return": {
195
195
  "type": {
196
196
  "text": "Promise<string[]>"
@@ -214,7 +214,7 @@
214
214
  "name": "opts",
215
215
  "default": "{}",
216
216
  "type": {
217
- "text": "MachineUnitSearchOptions"
217
+ "text": "FigureIdSearchOptions"
218
218
  }
219
219
  }
220
220
  ],
@@ -222,7 +222,7 @@
222
222
  },
223
223
  {
224
224
  "kind": "function",
225
- "name": "filterMachineUnitIds",
225
+ "name": "filterFigureIds",
226
226
  "return": {
227
227
  "type": {
228
228
  "text": "string[]"
@@ -256,9 +256,9 @@
256
256
  },
257
257
  {
258
258
  "kind": "js",
259
- "name": "MachineUnitSearchOptions",
259
+ "name": "FigureIdSearchOptions",
260
260
  "declaration": {
261
- "name": "MachineUnitSearchOptions",
261
+ "name": "FigureIdSearchOptions",
262
262
  "module": "./restful"
263
263
  }
264
264
  },
@@ -368,17 +368,17 @@
368
368
  },
369
369
  {
370
370
  "kind": "js",
371
- "name": "searchMachineUnits",
371
+ "name": "searchFigureIds",
372
372
  "declaration": {
373
- "name": "searchMachineUnits",
373
+ "name": "searchFigureIds",
374
374
  "module": "src/index.ts"
375
375
  }
376
376
  },
377
377
  {
378
378
  "kind": "js",
379
- "name": "filterMachineUnitIds",
379
+ "name": "filterFigureIds",
380
380
  "declaration": {
381
- "name": "filterMachineUnitIds",
381
+ "name": "filterFigureIds",
382
382
  "module": "src/index.ts"
383
383
  }
384
384
  }
@@ -2206,7 +2206,7 @@
2206
2206
  },
2207
2207
  {
2208
2208
  "kind": "function",
2209
- "name": "fetchMachineUnits",
2209
+ "name": "fetchFigureIds",
2210
2210
  "return": {
2211
2211
  "type": {
2212
2212
  "text": "Promise<string[]>"
@@ -2223,11 +2223,11 @@
2223
2223
  "name": "opts",
2224
2224
  "default": "{}",
2225
2225
  "type": {
2226
- "text": "MachineUnitSearchOptions"
2226
+ "text": "FigureIdSearchOptions"
2227
2227
  }
2228
2228
  }
2229
2229
  ],
2230
- "description": "컴포넌트 타입으로, 서버에 이미 정의된 머신/유닛 ID 후보를 조회.\n\n포커스 시 **항상 기존 방식(getPopupData 와 동일) 으로 실제 HTTP 호출** 한다.\n호출 대상은 getRestServiceFullPath() 가 결정한다:\n - 프로덕션(fmsim-restful): lv_server_ip_port 가 설정되어 MCS LV RESTful 호스트로 나감 (기존과 동일)\n - 테스트(fmsim): lv_server_ip_port 가 없어 same-origin 으로 나가고, fmsim 앱 서버의\n mock 라우트가 테스트 결과를 응답한다.\n\n요청 규약:\n GET {base}/machineUnits?type={type}[&machine={parentMachine}]\n - type : 컴포넌트 타입 (path 가 아니라 query 파라미터)\n - machine: unit 타입일 때만 — 부모 머신 id 로 조회를 좁힌다. machine 타입이면 생략.\n - keyword: 서버로 보내지 않는다 (후보 목록을 받아 클라이언트에서 풀텍스트 필터).\n\n결과는 **1차원 id 리스트(string[])** — machine 타입이면 머신 id, unit 타입이면 unit id.\n(머신별 그룹핑 없음.)\n\n서버 응답 호환 — 다음 형태를 모두 수용:\n - string[] (정규)\n - { ids: string[] } | { items: [] } | { data: [] }\n - 객체 배열 → 각 항목의 id/name/unit/machine 필드를 추출"
2230
+ "description": "Figure ID Mapping — 컴포넌트(figure) 타입으로 서버에 정의된 ID 후보를 조회.\n(id-lookup 백엔드 확정 명세: MCS LV RESTful)\n\n포커스 시 **항상 실제 HTTP 호출**. 대상은 getRestServiceFullPath() 가 결정:\n - 프로덕션(fmsim-restful): lv_server_ip_port + /mcs/lv → MCS LV RESTful 호스트\n - 테스트(fmsim): same-origin → fmsim 앱 서버 mock 라우트\n\n요청 규약 (확정):\n GET {base}/resource/name?figureType={type}[&machineName={parentMachine}]\n - figureType : 컴포넌트(figure) 타입\n - machineName: 부모 머신 id — 조회 범위 한정 (unit 계열일 때). 없으면 생략.\n - keyword 는 보내지 않는다 (후보 목록을 받아 클라이언트에서 풀텍스트 필터).\n\n응답 규약 (확정):\n { \"data\": string[], \"errorMessage\": string | null, \"status\": boolean }\n - status=false 면 빈 결과로 취급.\n - data 는 1차원 id 리스트(string[]). (머신별 그룹핑 없음.)"
2231
2231
  }
2232
2232
  ],
2233
2233
  "exports": [
@@ -2241,9 +2241,9 @@
2241
2241
  },
2242
2242
  {
2243
2243
  "kind": "js",
2244
- "name": "fetchMachineUnits",
2244
+ "name": "fetchFigureIds",
2245
2245
  "declaration": {
2246
- "name": "fetchMachineUnits",
2246
+ "name": "fetchFigureIds",
2247
2247
  "module": "src/restful/machine.ts"
2248
2248
  }
2249
2249
  }
@@ -12,13 +12,17 @@ export class DataSubscriptionProviderImpl {
12
12
  data(tag: "${tag}") {
13
13
  tag
14
14
  data
15
+ ts
15
16
  }
16
17
  }
17
18
  `
18
19
  }, {
19
20
  next: async ({ data }) => {
21
+ var _a, _b, _c;
20
22
  if (data && !this._paused) {
21
- component.data = data.data.data;
23
+ const payload = data.data;
24
+ (_c = (_b = (_a = component.app) === null || _a === void 0 ? void 0 : _a.lagTracker) === null || _b === void 0 ? void 0 : _b.record) === null || _c === void 0 ? void 0 : _c.call(_b, payload.tag, payload.ts);
25
+ component.data = payload.data;
22
26
  }
23
27
  }
24
28
  });
@@ -1 +1 @@
1
- {"version":3,"file":"data-subscription.js","sourceRoot":"","sources":["../../../src/graphql/data-subscription.ts"],"names":[],"mappings":"AAEA,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C,MAAM,OAAO,4BAA4B;IAAzC;QACU,YAAO,GAAG,KAAK,CAAA;QACf,mBAAc,GAA6D,IAAI,GAAG,EAAE,CAAA;IAwD9F,CAAC;IAtDC,KAAK,CAAC,SAAS,CAAC,GAAW,EAAE,SAAoB;QAC/C,MAAM,GAAG,GAAG,MAAM,SAAS,CACzB;YACE,KAAK,EAAE,GAAG,CAAA;;iCAEe,GAAG;;;;;iBAKnB;SACV,EACD;YACE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAiB,EAAE,EAAE;gBACtC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;oBAC1B,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAA;gBACjC,CAAC;YACH,CAAC;SACF,CACF,CAAA;QAED,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAA;QAEzE,OAAO;YACL,WAAW,EAAE,GAAG,EAAE;gBAChB,GAAG,CAAC,WAAW,EAAE,CAAA;gBACjB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;YACvC,CAAC;SACF,CAAA;IACH,CAAC;IAED,4BAA4B;IAC5B,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,KAAK,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACtD,IAAI,CAAC;gBAAC,WAAW,EAAE,CAAA;YAAC,CAAC;YAAC,WAAM,CAAC,CAAA,CAAC;QAChC,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,KAAK,CAAC,MAAM;QACV,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAA;QAClD,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;QAC3B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QAEpB,KAAK,MAAM,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;YAC3C,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,CAAC,KAAK,EAAE,CAAA;QACZ,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;IAC7B,CAAC;CACF","sourcesContent":["import { Component, DataSubscriptionProvider } from '@hatiolab/things-scene'\n\nimport gql from 'graphql-tag'\nimport { subscribe } from '@operato/graphql'\n\nexport class DataSubscriptionProviderImpl implements DataSubscriptionProvider {\n private _paused = false\n private _subscriptions: Map<Component, { tag: string; unsubscribe: () => void }> = new Map()\n\n async subscribe(tag: string, component: Component): Promise<{ unsubscribe: () => void }> {\n const sub = await subscribe(\n {\n query: gql`\n subscription {\n data(tag: \"${tag}\") {\n tag\n data\n }\n }\n `\n },\n {\n next: async ({ data }: { data: any }) => {\n if (data && !this._paused) {\n component.data = data.data.data\n }\n }\n }\n )\n\n this._subscriptions.set(component, { tag, unsubscribe: sub.unsubscribe })\n\n return {\n unsubscribe: () => {\n sub.unsubscribe()\n this._subscriptions.delete(component)\n }\n }\n }\n\n /** 플레이백 시작: 모든 구독을 실제 해제 */\n pause() {\n this._paused = true\n for (const [, { unsubscribe }] of this._subscriptions) {\n try { unsubscribe() } catch {}\n }\n }\n\n /** 플레이백 종료: 보관된 tag 로 재구독 */\n async resume() {\n const entries = [...this._subscriptions.entries()]\n this._subscriptions.clear()\n this._paused = false\n\n for (const [component, { tag }] of entries) {\n await this.subscribe(tag, component)\n }\n }\n\n dispose() {\n this.pause()\n this._subscriptions.clear()\n }\n}\n"]}
1
+ {"version":3,"file":"data-subscription.js","sourceRoot":"","sources":["../../../src/graphql/data-subscription.ts"],"names":[],"mappings":"AAEA,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C,MAAM,OAAO,4BAA4B;IAAzC;QACU,YAAO,GAAG,KAAK,CAAA;QACf,mBAAc,GAA6D,IAAI,GAAG,EAAE,CAAA;IA4D9F,CAAC;IA1DC,KAAK,CAAC,SAAS,CAAC,GAAW,EAAE,SAAoB;QAC/C,MAAM,GAAG,GAAG,MAAM,SAAS,CACzB;YACE,KAAK,EAAE,GAAG,CAAA;;iCAEe,GAAG;;;;;;iBAMnB;SACV,EACD;YACE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAiB,EAAE,EAAE;;gBACtC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;oBAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAExB;oBAAA,MAAA,MAAA,MAAC,SAAiB,CAAC,GAAG,0CAAE,UAAU,0CAAE,MAAM,mDAAG,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;oBACtE,SAAS,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;gBAC/B,CAAC;YACH,CAAC;SACF,CACF,CAAA;QAED,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAA;QAEzE,OAAO;YACL,WAAW,EAAE,GAAG,EAAE;gBAChB,GAAG,CAAC,WAAW,EAAE,CAAA;gBACjB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;YACvC,CAAC;SACF,CAAA;IACH,CAAC;IAED,4BAA4B;IAC5B,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,KAAK,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACtD,IAAI,CAAC;gBAAC,WAAW,EAAE,CAAA;YAAC,CAAC;YAAC,WAAM,CAAC,CAAA,CAAC;QAChC,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,KAAK,CAAC,MAAM;QACV,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAA;QAClD,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;QAC3B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QAEpB,KAAK,MAAM,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;YAC3C,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,CAAC,KAAK,EAAE,CAAA;QACZ,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;IAC7B,CAAC;CACF","sourcesContent":["import { Component, DataSubscriptionProvider } from '@hatiolab/things-scene'\n\nimport gql from 'graphql-tag'\nimport { subscribe } from '@operato/graphql'\n\nexport class DataSubscriptionProviderImpl implements DataSubscriptionProvider {\n private _paused = false\n private _subscriptions: Map<Component, { tag: string; unsubscribe: () => void }> = new Map()\n\n async subscribe(tag: string, component: Component): Promise<{ unsubscribe: () => void }> {\n const sub = await subscribe(\n {\n query: gql`\n subscription {\n data(tag: \"${tag}\") {\n tag\n data\n ts\n }\n }\n `\n },\n {\n next: async ({ data }: { data: any }) => {\n if (data && !this._paused) {\n const payload = data.data\n // 전달 지연 기록 (scene/app 레벨 트래커) — ts 는 component.data 에 넣지 않음.\n ;(component as any).app?.lagTracker?.record?.(payload.tag, payload.ts)\n component.data = payload.data\n }\n }\n }\n )\n\n this._subscriptions.set(component, { tag, unsubscribe: sub.unsubscribe })\n\n return {\n unsubscribe: () => {\n sub.unsubscribe()\n this._subscriptions.delete(component)\n }\n }\n }\n\n /** 플레이백 시작: 모든 구독을 실제 해제 */\n pause() {\n this._paused = true\n for (const [, { unsubscribe }] of this._subscriptions) {\n try { unsubscribe() } catch {}\n }\n }\n\n /** 플레이백 종료: 보관된 tag 로 재구독 */\n async resume() {\n const entries = [...this._subscriptions.entries()]\n this._subscriptions.clear()\n this._paused = false\n\n for (const [component, { tag }] of entries) {\n await this.subscribe(tag, component)\n }\n }\n\n dispose() {\n this.pause()\n this._subscriptions.clear()\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  export * from './graphql';
2
- import type { MachineUnitSearchOptions } from './restful';
3
- export type { MachineUnitSearchOptions } from './restful';
2
+ import type { FigureIdSearchOptions } from './restful';
3
+ export type { FigureIdSearchOptions } from './restful';
4
4
  import { Board } from './types';
5
5
  export declare function isRestfulAvailable(): string | null;
6
6
  export declare function fetchGroupList(): Promise<any>;
@@ -28,10 +28,10 @@ export declare function getPopupData(type: string, id: string): Promise<any>;
28
28
  *
29
29
  * 결과는 **1차원 id 리스트(string[])** — machine 타입이면 머신 id, unit 타입이면 unit id.
30
30
  */
31
- export declare function searchMachineUnits(type: string, keyword?: string, opts?: MachineUnitSearchOptions): Promise<string[]>;
31
+ export declare function searchFigureIds(type: string, keyword?: string, opts?: FigureIdSearchOptions): Promise<string[]>;
32
32
  /**
33
33
  * 머신/유닛 id 리스트를 keyword 로 **풀텍스트 필터** — 서버 재조회 없이 로컬에서 사용.
34
34
  * keyword 를 공백 토큰화하고, 각 토큰이 (순서 무관) id 에 부분일치(AND) 하면 통과.
35
35
  * 빈 keyword 는 전체 반환. 예: "stk01 p03" ↔ "STK01-P03", "p03 stk01" 동일.
36
36
  */
37
- export declare function filterMachineUnitIds(ids: string[], keyword: string): string[];
37
+ export declare function filterFigureIds(ids: string[], keyword: string): string[];
package/dist/src/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  export * from './graphql';
2
2
  import { themesColorMap as graphqlThemesColorMap, themesColorRange as graphqlThemesColorRange, themesAnimationMap as graphqlThemesAnimationMap } from './graphql';
3
3
  import { getPopupData as restfulGetPopupData, themesColorMap as restfulThemesColorMap, themesColorRange as restfulThemesColorRange, themesAnimationMap as restfulThemesAnimationMap } from './restful';
4
- import { fetchGroupList as restfulFetchGroupList, fetchBoardList as restfulFetchBoardList, createBoard as restfulCreateBoard, fetchBoardById as restfulFetchBoardById, fetchBoardNameById as restfulFetchBoardNameById, reorderBoard as restfulReorderBoard, fetchPlayback as restfulFetchPlayback, fetchCarrierLocationHistory as restfulFetchCarrierLocationHistory, fetchMachineUnits as restfulFetchMachineUnits } from './restful';
4
+ import { fetchGroupList as restfulFetchGroupList, fetchBoardList as restfulFetchBoardList, createBoard as restfulCreateBoard, fetchBoardById as restfulFetchBoardById, fetchBoardNameById as restfulFetchBoardNameById, reorderBoard as restfulReorderBoard, fetchPlayback as restfulFetchPlayback, fetchCarrierLocationHistory as restfulFetchCarrierLocationHistory, fetchFigureIds as restfulFetchFigureIds } from './restful';
5
5
  import { fetchGroupList as graphqlFetchGroupList, fetchBoardList as graphqlFetchBoardList, createBoard as graphqlCreateBoard, fetchBoardById as graphqlFetchBoardById, fetchBoardNameById as graphqlFetchBoardNameById, reorderBoard as graphqlReorderBoard, fetchPlayback as graphqlFetchPlayback, fetchCarrierLocationHistory as graphqlFetchCarrierLocationHistory } from './graphql';
6
6
  export function isRestfulAvailable() {
7
7
  return sessionStorage.getItem('lv_server_ip_port');
@@ -126,15 +126,15 @@ export async function getPopupData(type, id) {
126
126
  *
127
127
  * 결과는 **1차원 id 리스트(string[])** — machine 타입이면 머신 id, unit 타입이면 unit id.
128
128
  */
129
- export async function searchMachineUnits(type, keyword = '', opts = {}) {
130
- return filterMachineUnitIds(await restfulFetchMachineUnits(type, opts), keyword);
129
+ export async function searchFigureIds(type, keyword = '', opts = {}) {
130
+ return filterFigureIds(await restfulFetchFigureIds(type, opts), keyword);
131
131
  }
132
132
  /**
133
133
  * 머신/유닛 id 리스트를 keyword 로 **풀텍스트 필터** — 서버 재조회 없이 로컬에서 사용.
134
134
  * keyword 를 공백 토큰화하고, 각 토큰이 (순서 무관) id 에 부분일치(AND) 하면 통과.
135
135
  * 빈 keyword 는 전체 반환. 예: "stk01 p03" ↔ "STK01-P03", "p03 stk01" 동일.
136
136
  */
137
- export function filterMachineUnitIds(ids, keyword) {
137
+ export function filterFigureIds(ids, keyword) {
138
138
  const terms = keyword.trim().toLowerCase().split(/\s+/).filter(Boolean);
139
139
  if (!terms.length)
140
140
  return ids;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export * from './graphql'\n\nimport {\n themesColorMap as graphqlThemesColorMap,\n themesColorRange as graphqlThemesColorRange,\n themesAnimationMap as graphqlThemesAnimationMap\n} from './graphql'\n\nimport {\n getPopupData as restfulGetPopupData,\n themesColorMap as restfulThemesColorMap,\n themesColorRange as restfulThemesColorRange,\n themesAnimationMap as restfulThemesAnimationMap\n} from './restful'\n\nimport {\n fetchGroupList as restfulFetchGroupList,\n fetchBoardList as restfulFetchBoardList,\n createBoard as restfulCreateBoard,\n fetchBoardById as restfulFetchBoardById,\n fetchBoardNameById as restfulFetchBoardNameById,\n reorderBoard as restfulReorderBoard,\n fetchPlayback as restfulFetchPlayback,\n fetchCarrierLocationHistory as restfulFetchCarrierLocationHistory,\n fetchMachineUnits as restfulFetchMachineUnits\n} from './restful'\n\nimport type { MachineUnitSearchOptions } from './restful'\nexport type { MachineUnitSearchOptions } from './restful'\n\nimport {\n fetchGroupList as graphqlFetchGroupList,\n fetchBoardList as graphqlFetchBoardList,\n createBoard as graphqlCreateBoard,\n fetchBoardById as graphqlFetchBoardById,\n fetchBoardNameById as graphqlFetchBoardNameById,\n reorderBoard as graphqlReorderBoard,\n fetchPlayback as graphqlFetchPlayback,\n fetchCarrierLocationHistory as graphqlFetchCarrierLocationHistory\n} from './graphql'\n\nimport { Board } from './types'\n\nexport function isRestfulAvailable() {\n return sessionStorage.getItem('lv_server_ip_port')\n}\n\nexport async function fetchGroupList() {\n if (isRestfulAvailable()) {\n return await restfulFetchGroupList()\n } else {\n return await graphqlFetchGroupList()\n }\n}\n\nexport async function fetchBoardList(listParam: any = {}) {\n if (isRestfulAvailable()) {\n return await restfulFetchBoardList(listParam)\n } else {\n return await graphqlFetchBoardList(listParam)\n }\n}\n\nexport async function reorderBoard(id: string, prevId?: string, nextId?: string) {\n if (isRestfulAvailable()) {\n return await restfulReorderBoard(id, prevId, nextId)\n } else {\n return await graphqlReorderBoard(id, prevId, nextId)\n }\n}\n\nexport async function fetchPlayback(\n startTime: string,\n endTime?: string,\n includeSnapshot: boolean = true,\n count?: number\n) {\n if (isRestfulAvailable()) {\n return await restfulFetchPlayback(startTime, endTime, includeSnapshot, count)\n } else {\n return await graphqlFetchPlayback(startTime, endTime, includeSnapshot, count)\n }\n}\n\nexport async function fetchCarrierLocationHistory(\n startTime: string,\n endTime: string,\n carrierName: string\n) {\n if (isRestfulAvailable()) {\n return await restfulFetchCarrierLocationHistory(startTime, endTime, carrierName)\n } else {\n return await graphqlFetchCarrierLocationHistory(startTime, endTime, carrierName)\n }\n}\n\nexport async function fetchBoardById(id: string, cachedUpdatedAt?: string) {\n if (isRestfulAvailable()) {\n return await restfulFetchBoardById(id, cachedUpdatedAt)\n } else {\n return await graphqlFetchBoardById(id, cachedUpdatedAt)\n }\n}\n\nexport async function fetchBoardNameById(id: string): Promise<string> {\n if (isRestfulAvailable()) {\n return await restfulFetchBoardNameById(id)\n } else {\n return await graphqlFetchBoardNameById(id)\n }\n}\n\nexport async function createBoard(board: Board) {\n if (isRestfulAvailable()) {\n return await restfulCreateBoard(board)\n } else {\n return await graphqlCreateBoard(board)\n }\n}\n\nexport async function themesColorMap() {\n if (isRestfulAvailable()) {\n return await restfulThemesColorMap()\n } else {\n return await graphqlThemesColorMap()\n }\n}\n\nexport async function themesColorRange() {\n if (isRestfulAvailable()) {\n return await restfulThemesColorRange()\n } else {\n return await graphqlThemesColorRange()\n }\n}\n\nexport async function themesAnimationMap() {\n if (isRestfulAvailable()) {\n return await restfulThemesAnimationMap()\n } else {\n return await graphqlThemesAnimationMap()\n }\n}\n\nexport async function getPopupData(type: string, id: string) {\n if (isRestfulAvailable()) {\n const response = (await restfulGetPopupData(type, id))?.data\n\n if (!response || !response.status) {\n document.dispatchEvent(\n new CustomEvent('notify', {\n detail: {\n level: 'error',\n message: 'Error : getPopupData'\n }\n })\n )\n throw new Error('Error : getPopupData')\n }\n\n return response.popupData\n } else {\n await new Promise(resolve => setTimeout(resolve, 1000))\n }\n}\n\n/**\n * 컴포넌트 타입 + 검색어로, MCS 에 이미 정의된 머신/유닛 ID 후보를 검색.\n * 보드 작화 시 컴포넌트 ID 를 자유 입력 대신 *검색해서 선택* 하기 위한 용도.\n *\n * 서버에는 type(+unit 이면 machine)만 보내 후보 목록을 받고, keyword 는 받은 목록을\n * 클라이언트에서 **풀텍스트 매칭** 으로 필터한다 — 서버에 keyword 를 보내지 않는다.\n *\n * 풀텍스트 전략: keyword 를 공백으로 토큰화하고, 각 토큰이 (순서 무관) 후보의 전체\n * 식별자(\"{machine} {unit}\", 대소문자 무관) 에 부분일치하면(AND) 매치로 본다.\n * 예) \"stk01 p03\" → STK01-P03 매치, \"p03 stk01\" 도 동일 매치.\n *\n * 결과는 **1차원 id 리스트(string[])** — machine 타입이면 머신 id, unit 타입이면 unit id.\n */\nexport async function searchMachineUnits(\n type: string,\n keyword: string = '',\n opts: MachineUnitSearchOptions = {}\n): Promise<string[]> {\n return filterMachineUnitIds(await restfulFetchMachineUnits(type, opts), keyword)\n}\n\n/**\n * 머신/유닛 id 리스트를 keyword 로 **풀텍스트 필터** — 서버 재조회 없이 로컬에서 사용.\n * keyword 를 공백 토큰화하고, 각 토큰이 (순서 무관) id 에 부분일치(AND) 하면 통과.\n * 빈 keyword 는 전체 반환. 예: \"stk01 p03\" ↔ \"STK01-P03\", \"p03 stk01\" 동일.\n */\nexport function filterMachineUnitIds(ids: string[], keyword: string): string[] {\n const terms = keyword.trim().toLowerCase().split(/\\s+/).filter(Boolean)\n if (!terms.length) return ids\n return ids.filter(id => {\n const s = id.toLowerCase()\n return terms.every(t => s.includes(t))\n })\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export * from './graphql'\n\nimport {\n themesColorMap as graphqlThemesColorMap,\n themesColorRange as graphqlThemesColorRange,\n themesAnimationMap as graphqlThemesAnimationMap\n} from './graphql'\n\nimport {\n getPopupData as restfulGetPopupData,\n themesColorMap as restfulThemesColorMap,\n themesColorRange as restfulThemesColorRange,\n themesAnimationMap as restfulThemesAnimationMap\n} from './restful'\n\nimport {\n fetchGroupList as restfulFetchGroupList,\n fetchBoardList as restfulFetchBoardList,\n createBoard as restfulCreateBoard,\n fetchBoardById as restfulFetchBoardById,\n fetchBoardNameById as restfulFetchBoardNameById,\n reorderBoard as restfulReorderBoard,\n fetchPlayback as restfulFetchPlayback,\n fetchCarrierLocationHistory as restfulFetchCarrierLocationHistory,\n fetchFigureIds as restfulFetchFigureIds\n} from './restful'\n\nimport type { FigureIdSearchOptions } from './restful'\nexport type { FigureIdSearchOptions } from './restful'\n\nimport {\n fetchGroupList as graphqlFetchGroupList,\n fetchBoardList as graphqlFetchBoardList,\n createBoard as graphqlCreateBoard,\n fetchBoardById as graphqlFetchBoardById,\n fetchBoardNameById as graphqlFetchBoardNameById,\n reorderBoard as graphqlReorderBoard,\n fetchPlayback as graphqlFetchPlayback,\n fetchCarrierLocationHistory as graphqlFetchCarrierLocationHistory\n} from './graphql'\n\nimport { Board } from './types'\n\nexport function isRestfulAvailable() {\n return sessionStorage.getItem('lv_server_ip_port')\n}\n\nexport async function fetchGroupList() {\n if (isRestfulAvailable()) {\n return await restfulFetchGroupList()\n } else {\n return await graphqlFetchGroupList()\n }\n}\n\nexport async function fetchBoardList(listParam: any = {}) {\n if (isRestfulAvailable()) {\n return await restfulFetchBoardList(listParam)\n } else {\n return await graphqlFetchBoardList(listParam)\n }\n}\n\nexport async function reorderBoard(id: string, prevId?: string, nextId?: string) {\n if (isRestfulAvailable()) {\n return await restfulReorderBoard(id, prevId, nextId)\n } else {\n return await graphqlReorderBoard(id, prevId, nextId)\n }\n}\n\nexport async function fetchPlayback(\n startTime: string,\n endTime?: string,\n includeSnapshot: boolean = true,\n count?: number\n) {\n if (isRestfulAvailable()) {\n return await restfulFetchPlayback(startTime, endTime, includeSnapshot, count)\n } else {\n return await graphqlFetchPlayback(startTime, endTime, includeSnapshot, count)\n }\n}\n\nexport async function fetchCarrierLocationHistory(\n startTime: string,\n endTime: string,\n carrierName: string\n) {\n if (isRestfulAvailable()) {\n return await restfulFetchCarrierLocationHistory(startTime, endTime, carrierName)\n } else {\n return await graphqlFetchCarrierLocationHistory(startTime, endTime, carrierName)\n }\n}\n\nexport async function fetchBoardById(id: string, cachedUpdatedAt?: string) {\n if (isRestfulAvailable()) {\n return await restfulFetchBoardById(id, cachedUpdatedAt)\n } else {\n return await graphqlFetchBoardById(id, cachedUpdatedAt)\n }\n}\n\nexport async function fetchBoardNameById(id: string): Promise<string> {\n if (isRestfulAvailable()) {\n return await restfulFetchBoardNameById(id)\n } else {\n return await graphqlFetchBoardNameById(id)\n }\n}\n\nexport async function createBoard(board: Board) {\n if (isRestfulAvailable()) {\n return await restfulCreateBoard(board)\n } else {\n return await graphqlCreateBoard(board)\n }\n}\n\nexport async function themesColorMap() {\n if (isRestfulAvailable()) {\n return await restfulThemesColorMap()\n } else {\n return await graphqlThemesColorMap()\n }\n}\n\nexport async function themesColorRange() {\n if (isRestfulAvailable()) {\n return await restfulThemesColorRange()\n } else {\n return await graphqlThemesColorRange()\n }\n}\n\nexport async function themesAnimationMap() {\n if (isRestfulAvailable()) {\n return await restfulThemesAnimationMap()\n } else {\n return await graphqlThemesAnimationMap()\n }\n}\n\nexport async function getPopupData(type: string, id: string) {\n if (isRestfulAvailable()) {\n const response = (await restfulGetPopupData(type, id))?.data\n\n if (!response || !response.status) {\n document.dispatchEvent(\n new CustomEvent('notify', {\n detail: {\n level: 'error',\n message: 'Error : getPopupData'\n }\n })\n )\n throw new Error('Error : getPopupData')\n }\n\n return response.popupData\n } else {\n await new Promise(resolve => setTimeout(resolve, 1000))\n }\n}\n\n/**\n * 컴포넌트 타입 + 검색어로, MCS 에 이미 정의된 머신/유닛 ID 후보를 검색.\n * 보드 작화 시 컴포넌트 ID 를 자유 입력 대신 *검색해서 선택* 하기 위한 용도.\n *\n * 서버에는 type(+unit 이면 machine)만 보내 후보 목록을 받고, keyword 는 받은 목록을\n * 클라이언트에서 **풀텍스트 매칭** 으로 필터한다 — 서버에 keyword 를 보내지 않는다.\n *\n * 풀텍스트 전략: keyword 를 공백으로 토큰화하고, 각 토큰이 (순서 무관) 후보의 전체\n * 식별자(\"{machine} {unit}\", 대소문자 무관) 에 부분일치하면(AND) 매치로 본다.\n * 예) \"stk01 p03\" → STK01-P03 매치, \"p03 stk01\" 도 동일 매치.\n *\n * 결과는 **1차원 id 리스트(string[])** — machine 타입이면 머신 id, unit 타입이면 unit id.\n */\nexport async function searchFigureIds(\n type: string,\n keyword: string = '',\n opts: FigureIdSearchOptions = {}\n): Promise<string[]> {\n return filterFigureIds(await restfulFetchFigureIds(type, opts), keyword)\n}\n\n/**\n * 머신/유닛 id 리스트를 keyword 로 **풀텍스트 필터** — 서버 재조회 없이 로컬에서 사용.\n * keyword 를 공백 토큰화하고, 각 토큰이 (순서 무관) id 에 부분일치(AND) 하면 통과.\n * 빈 keyword 는 전체 반환. 예: \"stk01 p03\" ↔ \"STK01-P03\", \"p03 stk01\" 동일.\n */\nexport function filterFigureIds(ids: string[], keyword: string): string[] {\n const terms = keyword.trim().toLowerCase().split(/\\s+/).filter(Boolean)\n if (!terms.length) return ids\n return ids.filter(id => {\n const s = id.toLowerCase()\n return terms.every(t => s.includes(t))\n })\n}\n"]}
@@ -1,30 +1,26 @@
1
- /** 머신/유닛 ID 조회 옵션. */
2
- export interface MachineUnitSearchOptions {
1
+ /** Figure ID 조회 옵션. */
2
+ export interface FigureIdSearchOptions {
3
3
  /** 부모 machine id — unit 타입 조회를 그 machine 소속으로 좁힌다 (machine 타입이면 생략). */
4
4
  machine?: string;
5
5
  }
6
6
  export declare function getPopupData(type: string, id: string): Promise<import("./common").RestfulReturnType | undefined>;
7
7
  /**
8
- * 컴포넌트 타입으로, 서버에 이미 정의된 머신/유닛 ID 후보를 조회.
8
+ * Figure ID Mapping — 컴포넌트(figure) 타입으로 서버에 정의된 ID 후보를 조회.
9
+ * (id-lookup 백엔드 확정 명세: MCS LV RESTful)
9
10
  *
10
- * 포커스 시 **항상 기존 방식(getPopupData 와 동일) 으로 실제 HTTP 호출** 한다.
11
- * 호출 대상은 getRestServiceFullPath() 가 결정한다:
12
- * - 프로덕션(fmsim-restful): lv_server_ip_port 가 설정되어 MCS LV RESTful 호스트로 나감 (기존과 동일)
13
- * - 테스트(fmsim): lv_server_ip_port 가 없어 same-origin 으로 나가고, fmsim 앱 서버의
14
- * mock 라우트가 테스트 결과를 응답한다.
11
+ * 포커스 시 **항상 실제 HTTP 호출**. 대상은 getRestServiceFullPath() 가 결정:
12
+ * - 프로덕션(fmsim-restful): lv_server_ip_port + /mcs/lv → MCS LV RESTful 호스트
13
+ * - 테스트(fmsim): same-origin → fmsim 앱 서버 mock 라우트
15
14
  *
16
- * 요청 규약:
17
- * GET {base}/machineUnits?type={type}[&machine={parentMachine}]
18
- * - type : 컴포넌트 타입 (path 가 아니라 query 파라미터)
19
- * - machine: unit 타입일 때만 — 부모 머신 id 로 조회를 좁힌다. machine 타입이면 생략.
20
- * - keyword: 서버로 보내지 않는다 (후보 목록을 받아 클라이언트에서 풀텍스트 필터).
15
+ * 요청 규약 (확정):
16
+ * GET {base}/resource/name?figureType={type}[&machineName={parentMachine}]
17
+ * - figureType : 컴포넌트(figure) 타입
18
+ * - machineName: 부모 머신 id — 조회 범위 한정 (unit 계열일 때). 없으면 생략.
19
+ * - keyword 는 보내지 않는다 (후보 목록을 받아 클라이언트에서 풀텍스트 필터).
21
20
  *
22
- * 결과는 **1차원 id 리스트(string[])** — machine 타입이면 머신 id, unit 타입이면 unit id.
23
- * (머신별 그룹핑 없음.)
24
- *
25
- * 서버 응답 호환 — 다음 형태를 모두 수용:
26
- * - string[] (정규)
27
- * - { ids: string[] } | { items: [] } | { data: [] }
28
- * - 객체 배열 → 각 항목의 id/name/unit/machine 필드를 추출
21
+ * 응답 규약 (확정):
22
+ * { "data": string[], "errorMessage": string | null, "status": boolean }
23
+ * - status=false 면 빈 결과로 취급.
24
+ * - data 는 1차원 id 리스트(string[]). (머신별 그룹핑 없음.)
29
25
  */
30
- export declare function fetchMachineUnits(type: string, opts?: MachineUnitSearchOptions): Promise<string[]>;
26
+ export declare function fetchFigureIds(type: string, opts?: FigureIdSearchOptions): Promise<string[]>;
@@ -3,38 +3,38 @@ export function getPopupData(type, id) {
3
3
  return callApi(getRestServiceFullPath() + `/popup/${(type || '').toLowerCase()}/${id}`, 'get', null, null);
4
4
  }
5
5
  /**
6
- * 컴포넌트 타입으로, 서버에 이미 정의된 머신/유닛 ID 후보를 조회.
6
+ * Figure ID Mapping — 컴포넌트(figure) 타입으로 서버에 정의된 ID 후보를 조회.
7
+ * (id-lookup 백엔드 확정 명세: MCS LV RESTful)
7
8
  *
8
- * 포커스 시 **항상 기존 방식(getPopupData 와 동일) 으로 실제 HTTP 호출** 한다.
9
- * 호출 대상은 getRestServiceFullPath() 가 결정한다:
10
- * - 프로덕션(fmsim-restful): lv_server_ip_port 가 설정되어 MCS LV RESTful 호스트로 나감 (기존과 동일)
11
- * - 테스트(fmsim): lv_server_ip_port 가 없어 same-origin 으로 나가고, fmsim 앱 서버의
12
- * mock 라우트가 테스트 결과를 응답한다.
9
+ * 포커스 시 **항상 실제 HTTP 호출**. 대상은 getRestServiceFullPath() 가 결정:
10
+ * - 프로덕션(fmsim-restful): lv_server_ip_port + /mcs/lv → MCS LV RESTful 호스트
11
+ * - 테스트(fmsim): same-origin → fmsim 앱 서버 mock 라우트
13
12
  *
14
- * 요청 규약:
15
- * GET {base}/machineUnits?type={type}[&machine={parentMachine}]
16
- * - type : 컴포넌트 타입 (path 가 아니라 query 파라미터)
17
- * - machine: unit 타입일 때만 — 부모 머신 id 로 조회를 좁힌다. machine 타입이면 생략.
18
- * - keyword: 서버로 보내지 않는다 (후보 목록을 받아 클라이언트에서 풀텍스트 필터).
13
+ * 요청 규약 (확정):
14
+ * GET {base}/resource/name?figureType={type}[&machineName={parentMachine}]
15
+ * - figureType : 컴포넌트(figure) 타입
16
+ * - machineName: 부모 머신 id — 조회 범위 한정 (unit 계열일 때). 없으면 생략.
17
+ * - keyword 는 보내지 않는다 (후보 목록을 받아 클라이언트에서 풀텍스트 필터).
19
18
  *
20
- * 결과는 **1차원 id 리스트(string[])** — machine 타입이면 머신 id, unit 타입이면 unit id.
21
- * (머신별 그룹핑 없음.)
22
- *
23
- * 서버 응답 호환 — 다음 형태를 모두 수용:
24
- * - string[] (정규)
25
- * - { ids: string[] } | { items: [] } | { data: [] }
26
- * - 객체 배열 → 각 항목의 id/name/unit/machine 필드를 추출
19
+ * 응답 규약 (확정):
20
+ * { "data": string[], "errorMessage": string | null, "status": boolean }
21
+ * - status=false 면 빈 결과로 취급.
22
+ * - data 는 1차원 id 리스트(string[]). (머신별 그룹핑 없음.)
27
23
  */
28
- export async function fetchMachineUnits(type, opts = {}) {
24
+ export async function fetchFigureIds(type, opts = {}) {
29
25
  const query = new URLSearchParams();
30
26
  if (type)
31
- query.set('type', type);
27
+ query.set('figureType', type);
32
28
  if (opts.machine)
33
- query.set('machine', opts.machine);
29
+ query.set('machineName', opts.machine);
34
30
  const qs = query.toString();
35
- const url = getRestServiceFullPath() + `/machineUnits` + (qs ? `?${qs}` : '');
31
+ const url = getRestServiceFullPath() + `/resource/name` + (qs ? `?${qs}` : '');
36
32
  const response = await callApi(url, 'get', null, null);
37
- return normalizeIds(response === null || response === void 0 ? void 0 : response.data);
33
+ const body = response === null || response === void 0 ? void 0 : response.data;
34
+ // 명세: { data, errorMessage, status } — status=false 면 빈 결과로 취급.
35
+ if (body && body.status === false)
36
+ return [];
37
+ return normalizeIds(body);
38
38
  }
39
39
  /** 서버 응답을 1차원 id 리스트(string[]) 로 정규화. */
40
40
  function normalizeIds(body) {
@@ -1 +1 @@
1
- {"version":3,"file":"machine.js","sourceRoot":"","sources":["../../../src/restful/machine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAQ1D,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,EAAU;IACnD,OAAO,OAAO,CAAC,sBAAsB,EAAE,GAAG,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;AAC5G,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY,EAAE,OAAiC,EAAE;IACvF,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAA;IACnC,IAAI,IAAI;QAAE,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACjC,IAAI,IAAI,CAAC,OAAO;QAAE,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IACpD,MAAM,EAAE,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAA;IAE3B,MAAM,GAAG,GAAG,sBAAsB,EAAE,GAAG,eAAe,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAC7E,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IAEtD,OAAO,YAAY,CAAC,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,CAAC,CAAA;AACrC,CAAC;AAED,yCAAyC;AACzC,SAAS,YAAY,CAAC,IAAS;IAC7B,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAA;IACpB,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAC7B,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;YACvB,CAAC,CAAC,IAAI,CAAC,GAAG;YACV,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;gBACzB,CAAC,CAAC,IAAI,CAAC,KAAK;gBACZ,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;oBACxB,CAAC,CAAC,IAAI,CAAC,IAAI;oBACX,CAAC,CAAC,IAAI,CAAA;IACd,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAA;IAEnB,OAAO,GAAG;SACP,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,uBAAC,OAAA,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAA,MAAA,MAAA,MAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,EAAE,mCAAI,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,IAAI,mCAAI,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,IAAI,mCAAI,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,mCAAI,EAAE,CAAC,CAAA,EAAA,CAAC;SAC9F,MAAM,CAAC,CAAC,CAAM,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AAC3E,CAAC","sourcesContent":["import { callApi, getRestServiceFullPath } from './common'\n\n/** 머신/유닛 ID 조회 옵션. */\nexport interface MachineUnitSearchOptions {\n /** 부모 machine id — unit 타입 조회를 그 machine 소속으로 좁힌다 (machine 타입이면 생략). */\n machine?: string\n}\n\nexport function getPopupData(type: string, id: string) {\n return callApi(getRestServiceFullPath() + `/popup/${(type || '').toLowerCase()}/${id}`, 'get', null, null)\n}\n\n/**\n * 컴포넌트 타입으로, 서버에 이미 정의된 머신/유닛 ID 후보를 조회.\n *\n * 포커스 시 **항상 기존 방식(getPopupData 와 동일) 으로 실제 HTTP 호출** 한다.\n * 호출 대상은 getRestServiceFullPath() 가 결정한다:\n * - 프로덕션(fmsim-restful): lv_server_ip_port 가 설정되어 MCS LV RESTful 호스트로 나감 (기존과 동일)\n * - 테스트(fmsim): lv_server_ip_port 가 없어 same-origin 으로 나가고, fmsim 앱 서버의\n * mock 라우트가 테스트 결과를 응답한다.\n *\n * 요청 규약:\n * GET {base}/machineUnits?type={type}[&machine={parentMachine}]\n * - type : 컴포넌트 타입 (path 가 아니라 query 파라미터)\n * - machine: unit 타입일 때만 — 부모 머신 id 로 조회를 좁힌다. machine 타입이면 생략.\n * - keyword: 서버로 보내지 않는다 (후보 목록을 받아 클라이언트에서 풀텍스트 필터).\n *\n * 결과는 **1차원 id 리스트(string[])** — machine 타입이면 머신 id, unit 타입이면 unit id.\n * (머신별 그룹핑 없음.)\n *\n * 서버 응답 호환 — 다음 형태를 모두 수용:\n * - string[] (정규)\n * - { ids: string[] } | { items: [] } | { data: [] }\n * - 객체 배열 → 각 항목의 id/name/unit/machine 필드를 추출\n */\nexport async function fetchMachineUnits(type: string, opts: MachineUnitSearchOptions = {}): Promise<string[]> {\n const query = new URLSearchParams()\n if (type) query.set('type', type)\n if (opts.machine) query.set('machine', opts.machine)\n const qs = query.toString()\n\n const url = getRestServiceFullPath() + `/machineUnits` + (qs ? `?${qs}` : '')\n const response = await callApi(url, 'get', null, null)\n\n return normalizeIds(response?.data)\n}\n\n/** 서버 응답을 1차원 id 리스트(string[]) 로 정규화. */\nfunction normalizeIds(body: any): string[] {\n if (!body) return []\n const arr = Array.isArray(body)\n ? body\n : Array.isArray(body.ids)\n ? body.ids\n : Array.isArray(body.items)\n ? body.items\n : Array.isArray(body.data)\n ? body.data\n : null\n if (!arr) return []\n\n return arr\n .map((x: any) => (typeof x === 'string' ? x : x?.id ?? x?.name ?? x?.unit ?? x?.machine ?? ''))\n .filter((s: any): s is string => typeof s === 'string' && s.length > 0)\n}\n"]}
1
+ {"version":3,"file":"machine.js","sourceRoot":"","sources":["../../../src/restful/machine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAQ1D,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,EAAU;IACnD,OAAO,OAAO,CAAC,sBAAsB,EAAE,GAAG,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;AAC5G,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY,EAAE,OAA8B,EAAE;IACjF,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAA;IACnC,IAAI,IAAI;QAAE,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,CAAA;IACvC,IAAI,IAAI,CAAC,OAAO;QAAE,KAAK,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IACxD,MAAM,EAAE,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAA;IAE3B,MAAM,GAAG,GAAG,sBAAsB,EAAE,GAAG,gBAAgB,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAC9E,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IAEtD,MAAM,IAAI,GAAQ,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,CAAA;IAChC,gEAAgE;IAChE,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK;QAAE,OAAO,EAAE,CAAA;IAC5C,OAAO,YAAY,CAAC,IAAI,CAAC,CAAA;AAC3B,CAAC;AAED,yCAAyC;AACzC,SAAS,YAAY,CAAC,IAAS;IAC7B,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAA;IACpB,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAC7B,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;YACvB,CAAC,CAAC,IAAI,CAAC,GAAG;YACV,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;gBACzB,CAAC,CAAC,IAAI,CAAC,KAAK;gBACZ,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;oBACxB,CAAC,CAAC,IAAI,CAAC,IAAI;oBACX,CAAC,CAAC,IAAI,CAAA;IACd,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAA;IAEnB,OAAO,GAAG;SACP,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,uBAAC,OAAA,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAA,MAAA,MAAA,MAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,EAAE,mCAAI,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,IAAI,mCAAI,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,IAAI,mCAAI,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,mCAAI,EAAE,CAAC,CAAA,EAAA,CAAC;SAC9F,MAAM,CAAC,CAAC,CAAM,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AAC3E,CAAC","sourcesContent":["import { callApi, getRestServiceFullPath } from './common'\n\n/** Figure ID 조회 옵션. */\nexport interface FigureIdSearchOptions {\n /** 부모 machine id — unit 타입 조회를 그 machine 소속으로 좁힌다 (machine 타입이면 생략). */\n machine?: string\n}\n\nexport function getPopupData(type: string, id: string) {\n return callApi(getRestServiceFullPath() + `/popup/${(type || '').toLowerCase()}/${id}`, 'get', null, null)\n}\n\n/**\n * Figure ID Mapping — 컴포넌트(figure) 타입으로 서버에 정의된 ID 후보를 조회.\n * (id-lookup 백엔드 확정 명세: MCS LV RESTful)\n *\n * 포커스 시 **항상 실제 HTTP 호출**. 대상은 getRestServiceFullPath() 가 결정:\n * - 프로덕션(fmsim-restful): lv_server_ip_port + /mcs/lv → MCS LV RESTful 호스트\n * - 테스트(fmsim): same-origin → fmsim 앱 서버 mock 라우트\n *\n * 요청 규약 (확정):\n * GET {base}/resource/name?figureType={type}[&machineName={parentMachine}]\n * - figureType : 컴포넌트(figure) 타입\n * - machineName: 부모 머신 id — 조회 범위 한정 (unit 계열일 때). 없으면 생략.\n * - keyword 는 보내지 않는다 (후보 목록을 받아 클라이언트에서 풀텍스트 필터).\n *\n * 응답 규약 (확정):\n * { \"data\": string[], \"errorMessage\": string | null, \"status\": boolean }\n * - status=false 면 빈 결과로 취급.\n * - data 는 1차원 id 리스트(string[]). (머신별 그룹핑 없음.)\n */\nexport async function fetchFigureIds(type: string, opts: FigureIdSearchOptions = {}): Promise<string[]> {\n const query = new URLSearchParams()\n if (type) query.set('figureType', type)\n if (opts.machine) query.set('machineName', opts.machine)\n const qs = query.toString()\n\n const url = getRestServiceFullPath() + `/resource/name` + (qs ? `?${qs}` : '')\n const response = await callApi(url, 'get', null, null)\n\n const body: any = response?.data\n // 명세: { data, errorMessage, status } — status=false 면 빈 결과로 취급.\n if (body && body.status === false) return []\n return normalizeIds(body)\n}\n\n/** 서버 응답을 1차원 id 리스트(string[]) 로 정규화. */\nfunction normalizeIds(body: any): string[] {\n if (!body) return []\n const arr = Array.isArray(body)\n ? body\n : Array.isArray(body.ids)\n ? body.ids\n : Array.isArray(body.items)\n ? body.items\n : Array.isArray(body.data)\n ? body.data\n : null\n if (!arr) return []\n\n return arr\n .map((x: any) => (typeof x === 'string' ? x : x?.id ?? x?.name ?? x?.unit ?? x?.machine ?? ''))\n .filter((s: any): s is string => typeof s === 'string' && s.length > 0)\n}\n"]}