@things-factory/headless-twin 10.0.12 โ†’ 10.0.13

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 (312) hide show
  1. package/dist-server/engine/canonical-ingest.d.ts +57 -2
  2. package/dist-server/engine/canonical-ingest.js +43 -2
  3. package/dist-server/engine/canonical-ingest.js.map +1 -1
  4. package/dist-server/engine/command-routing.js +1 -1
  5. package/dist-server/engine/command-routing.js.map +1 -1
  6. package/dist-server/engine/index.d.ts +3 -0
  7. package/dist-server/engine/index.js +4 -0
  8. package/dist-server/engine/index.js.map +1 -1
  9. package/dist-server/engine/ingest-health.d.ts +335 -0
  10. package/dist-server/engine/ingest-health.js +434 -0
  11. package/dist-server/engine/ingest-health.js.map +1 -0
  12. package/dist-server/engine/integration-coverage.d.ts +76 -0
  13. package/dist-server/engine/integration-coverage.js +73 -0
  14. package/dist-server/engine/integration-coverage.js.map +1 -0
  15. package/dist-server/engine/integration-probes.d.ts +65 -0
  16. package/dist-server/engine/integration-probes.js +100 -0
  17. package/dist-server/engine/integration-probes.js.map +1 -0
  18. package/dist-server/engine/integration-runner.d.ts +45 -0
  19. package/dist-server/engine/integration-runner.js +59 -0
  20. package/dist-server/engine/integration-runner.js.map +1 -0
  21. package/dist-server/engine/integration-target-profile.d.ts +57 -0
  22. package/dist-server/engine/integration-target-profile.js +79 -0
  23. package/dist-server/engine/integration-target-profile.js.map +1 -0
  24. package/dist-server/engine/kpi-fold.d.ts +27 -0
  25. package/dist-server/engine/kpi-fold.js +47 -4
  26. package/dist-server/engine/kpi-fold.js.map +1 -1
  27. package/dist-server/engine/kpi-query.js +128 -14
  28. package/dist-server/engine/kpi-query.js.map +1 -1
  29. package/dist-server/engine/live-feed-registry.js +2 -16
  30. package/dist-server/engine/live-feed-registry.js.map +1 -1
  31. package/dist-server/engine/load-meter.d.ts +1 -1
  32. package/dist-server/engine/load-meter.js +12 -3
  33. package/dist-server/engine/load-meter.js.map +1 -1
  34. package/dist-server/engine/log.d.ts +18 -0
  35. package/dist-server/engine/log.js +80 -0
  36. package/dist-server/engine/log.js.map +1 -0
  37. package/dist-server/engine/loop-lag.d.ts +54 -0
  38. package/dist-server/engine/loop-lag.js +87 -0
  39. package/dist-server/engine/loop-lag.js.map +1 -0
  40. package/dist-server/engine/model-gap.d.ts +108 -0
  41. package/dist-server/engine/model-gap.js +95 -0
  42. package/dist-server/engine/model-gap.js.map +1 -0
  43. package/dist-server/engine/restart-policy.d.ts +3 -3
  44. package/dist-server/engine/restart-policy.js +4 -4
  45. package/dist-server/engine/restart-policy.js.map +1 -1
  46. package/dist-server/engine/runtime-key.js +1 -1
  47. package/dist-server/engine/runtime-key.js.map +1 -1
  48. package/dist-server/engine/stage-path.d.ts +83 -0
  49. package/dist-server/engine/stage-path.js +118 -0
  50. package/dist-server/engine/stage-path.js.map +1 -0
  51. package/dist-server/engine/twin-engine.d.ts +352 -16
  52. package/dist-server/engine/twin-engine.js +1037 -166
  53. package/dist-server/engine/twin-engine.js.map +1 -1
  54. package/dist-server/index.js +34 -2
  55. package/dist-server/index.js.map +1 -1
  56. package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.d.ts +5 -0
  57. package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js +58 -0
  58. package/dist-server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.js.map +1 -0
  59. package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.d.ts +5 -0
  60. package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js +55 -0
  61. package/dist-server/migrations/1786200000000-CarryLiveFeedCursor.js.map +1 -0
  62. package/dist-server/migrations/index.js +7 -1
  63. package/dist-server/migrations/index.js.map +1 -1
  64. package/dist-server/service/index.d.ts +5 -2
  65. package/dist-server/service/index.js +18 -7
  66. package/dist-server/service/index.js.map +1 -1
  67. package/dist-server/service/reference/discovery-result.d.ts +1 -1
  68. package/dist-server/service/reference/discovery-result.js +1 -1
  69. package/dist-server/service/reference/discovery-result.js.map +1 -1
  70. package/dist-server/service/reference/index.d.ts +4 -1
  71. package/dist-server/service/reference/index.js +6 -1
  72. package/dist-server/service/reference/index.js.map +1 -1
  73. package/dist-server/service/reference/reference-adapter.d.ts +184 -3
  74. package/dist-server/service/reference/reference-adapter.js +28 -4
  75. package/dist-server/service/reference/reference-adapter.js.map +1 -1
  76. package/dist-server/service/reference/reference-assessment.d.ts +68 -0
  77. package/dist-server/service/reference/reference-assessment.js +136 -0
  78. package/dist-server/service/reference/reference-assessment.js.map +1 -0
  79. package/dist-server/service/reference/reference-live.d.ts +12 -1
  80. package/dist-server/service/reference/reference-live.js +116 -11
  81. package/dist-server/service/reference/reference-live.js.map +1 -1
  82. package/dist-server/service/reference/reference-master.d.ts +47 -1
  83. package/dist-server/service/reference/reference-master.js +34 -4
  84. package/dist-server/service/reference/reference-master.js.map +1 -1
  85. package/dist-server/service/reference/reference-probe.d.ts +92 -0
  86. package/dist-server/service/reference/reference-probe.js +186 -0
  87. package/dist-server/service/reference/reference-probe.js.map +1 -0
  88. package/dist-server/service/reference/reference-progress-subscription.d.ts +17 -0
  89. package/dist-server/service/reference/reference-progress-subscription.js +94 -0
  90. package/dist-server/service/reference/reference-progress-subscription.js.map +1 -0
  91. package/dist-server/service/reference/reference-progress.d.ts +38 -0
  92. package/dist-server/service/reference/reference-progress.js +71 -0
  93. package/dist-server/service/reference/reference-progress.js.map +1 -0
  94. package/dist-server/service/reference/reference-resolver.js +210 -43
  95. package/dist-server/service/reference/reference-resolver.js.map +1 -1
  96. package/dist-server/service/reference/twin-reference.d.ts +32 -0
  97. package/dist-server/service/reference/twin-reference.js +10 -0
  98. package/dist-server/service/reference/twin-reference.js.map +1 -1
  99. package/dist-server/service/twin-control/twin-control-mutation.js +4 -3
  100. package/dist-server/service/twin-control/twin-control-mutation.js.map +1 -1
  101. package/dist-server/service/twin-event/journal-count.d.ts +21 -0
  102. package/dist-server/service/twin-event/journal-count.js +26 -0
  103. package/dist-server/service/twin-event/journal-count.js.map +1 -0
  104. package/dist-server/service/twin-event/twin-event-keys.d.ts +9 -0
  105. package/dist-server/service/twin-event/twin-event-keys.js +15 -18
  106. package/dist-server/service/twin-event/twin-event-keys.js.map +1 -1
  107. package/dist-server/service/twin-event/twin-event-type.d.ts +3 -1
  108. package/dist-server/service/twin-event/twin-event-type.js +18 -1
  109. package/dist-server/service/twin-event/twin-event-type.js.map +1 -1
  110. package/dist-server/service/twin-event/twin-event.d.ts +1 -0
  111. package/dist-server/service/twin-event/twin-event.js +9 -1
  112. package/dist-server/service/twin-event/twin-event.js.map +1 -1
  113. package/dist-server/service/twin-forecast/twin-forecast-query.js +2 -1
  114. package/dist-server/service/twin-forecast/twin-forecast-query.js.map +1 -1
  115. package/dist-server/service/twin-ingest-window/index.d.ts +5 -0
  116. package/dist-server/service/twin-ingest-window/index.js +10 -0
  117. package/dist-server/service/twin-ingest-window/index.js.map +1 -0
  118. package/dist-server/service/twin-ingest-window/twin-ingest-window-query.d.ts +12 -0
  119. package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js +123 -0
  120. package/dist-server/service/twin-ingest-window/twin-ingest-window-query.js.map +1 -0
  121. package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.d.ts +1 -0
  122. package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js +51 -0
  123. package/dist-server/service/twin-ingest-window/twin-ingest-window-writer.js.map +1 -0
  124. package/dist-server/service/twin-ingest-window/twin-ingest-window.d.ts +16 -0
  125. package/dist-server/service/twin-ingest-window/twin-ingest-window.js +108 -0
  126. package/dist-server/service/twin-ingest-window/twin-ingest-window.js.map +1 -0
  127. package/dist-server/service/twin-instance/twin-instance.js.map +1 -1
  128. package/dist-server/service/twin-journal/twin-journal-query.js +58 -5
  129. package/dist-server/service/twin-journal/twin-journal-query.js.map +1 -1
  130. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.d.ts +14 -0
  131. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js +72 -2
  132. package/dist-server/service/twin-lifecycle/twin-lifecycle-mutation.js.map +1 -1
  133. package/dist-server/service/twin-metrics/twin-metrics-query.d.ts +1 -0
  134. package/dist-server/service/twin-metrics/twin-metrics-query.js +78 -3
  135. package/dist-server/service/twin-metrics/twin-metrics-query.js.map +1 -1
  136. package/dist-server/service/twin-model/axis-journal-evidence.d.ts +2 -0
  137. package/dist-server/service/twin-model/axis-journal-evidence.js +89 -0
  138. package/dist-server/service/twin-model/axis-journal-evidence.js.map +1 -0
  139. package/dist-server/service/twin-model/epcis-coverage.d.ts +1 -1
  140. package/dist-server/service/twin-model/epcis-coverage.js +19 -7
  141. package/dist-server/service/twin-model/epcis-coverage.js.map +1 -1
  142. package/dist-server/service/twin-model/iec61850-coverage.d.ts +1 -1
  143. package/dist-server/service/twin-model/iec61850-coverage.js +18 -7
  144. package/dist-server/service/twin-model/iec61850-coverage.js.map +1 -1
  145. package/dist-server/service/twin-model/isa95-coverage.d.ts +14 -0
  146. package/dist-server/service/twin-model/isa95-coverage.js +23 -9
  147. package/dist-server/service/twin-model/isa95-coverage.js.map +1 -1
  148. package/dist-server/service/twin-model/item-ref.d.ts +24 -0
  149. package/dist-server/service/twin-model/item-ref.js +88 -0
  150. package/dist-server/service/twin-model/item-ref.js.map +1 -0
  151. package/dist-server/service/twin-model/name-index.d.ts +36 -0
  152. package/dist-server/service/twin-model/name-index.js +116 -0
  153. package/dist-server/service/twin-model/name-index.js.map +1 -0
  154. package/dist-server/service/twin-model/project-structure.js +1 -1
  155. package/dist-server/service/twin-model/project-structure.js.map +1 -1
  156. package/dist-server/service/twin-model/status-tally.d.ts +9 -0
  157. package/dist-server/service/twin-model/status-tally.js +37 -0
  158. package/dist-server/service/twin-model/status-tally.js.map +1 -0
  159. package/dist-server/service/twin-model/twin-lineage-query.js +40 -12
  160. package/dist-server/service/twin-model/twin-lineage-query.js.map +1 -1
  161. package/dist-server/service/twin-model/twin-model-item-query.js +38 -39
  162. package/dist-server/service/twin-model/twin-model-item-query.js.map +1 -1
  163. package/dist-server/service/twin-model/twin-model-query.js +156 -4
  164. package/dist-server/service/twin-model/twin-model-query.js.map +1 -1
  165. package/dist-server/service/twin-model/twin-model-tree-query.js +7 -0
  166. package/dist-server/service/twin-model/twin-model-tree-query.js.map +1 -1
  167. package/dist-server/service/twin-readiness/index.d.ts +2 -0
  168. package/dist-server/service/twin-readiness/index.js +6 -0
  169. package/dist-server/service/twin-readiness/index.js.map +1 -0
  170. package/dist-server/service/twin-readiness/twin-readiness-query.d.ts +3 -0
  171. package/dist-server/service/twin-readiness/twin-readiness-query.js +103 -0
  172. package/dist-server/service/twin-readiness/twin-readiness-query.js.map +1 -0
  173. package/dist-server/service/twin-space/twin-space-resolver.d.ts +2 -2
  174. package/dist-server/service/twin-space/twin-space-resolver.js +5 -4
  175. package/dist-server/service/twin-space/twin-space-resolver.js.map +1 -1
  176. package/dist-shared/entity-delta.d.ts +23 -3
  177. package/dist-shared/entity-delta.js +12 -8
  178. package/dist-shared/entity-delta.js.map +1 -1
  179. package/dist-shared/kpi-broadcast.js +1 -1
  180. package/dist-shared/kpi-broadcast.js.map +1 -1
  181. package/dist-shared/touched-items.d.ts +7 -0
  182. package/dist-shared/touched-items.js +80 -0
  183. package/dist-shared/touched-items.js.map +1 -0
  184. package/package.json +7 -7
  185. package/server/engine/canonical-ingest.ts +92 -7
  186. package/server/engine/command-routing.ts +1 -1
  187. package/server/engine/index.ts +4 -0
  188. package/server/engine/ingest-health.ts +704 -0
  189. package/server/engine/integration-coverage.ts +147 -0
  190. package/server/engine/integration-probes.ts +144 -0
  191. package/server/engine/integration-runner.ts +95 -0
  192. package/server/engine/integration-target-profile.ts +103 -0
  193. package/server/engine/kpi-fold.ts +72 -4
  194. package/server/engine/kpi-query.ts +129 -15
  195. package/server/engine/live-feed-registry.ts +2 -1
  196. package/server/engine/load-meter.ts +12 -3
  197. package/server/engine/log.ts +72 -0
  198. package/server/engine/loop-lag.ts +120 -0
  199. package/server/engine/model-gap.ts +168 -0
  200. package/server/engine/restart-policy.ts +4 -4
  201. package/server/engine/runtime-key.ts +1 -1
  202. package/server/engine/stage-path.ts +172 -0
  203. package/server/engine/twin-engine.ts +1135 -162
  204. package/server/index.ts +35 -2
  205. package/server/migrations/1786100000000-PromoteEventActionAndSyncWarnings.ts +54 -0
  206. package/server/migrations/1786200000000-CarryLiveFeedCursor.ts +53 -0
  207. package/server/migrations/index.ts +7 -1
  208. package/server/service/index.ts +11 -0
  209. package/server/service/reference/discovery-result.ts +1 -1
  210. package/server/service/reference/index.ts +6 -1
  211. package/server/service/reference/reference-adapter.ts +197 -5
  212. package/server/service/reference/reference-assessment.ts +215 -0
  213. package/server/service/reference/reference-live.ts +123 -11
  214. package/server/service/reference/reference-master.ts +64 -4
  215. package/server/service/reference/reference-probe.ts +264 -0
  216. package/server/service/reference/reference-progress-subscription.ts +73 -0
  217. package/server/service/reference/reference-progress.ts +95 -0
  218. package/server/service/reference/reference-resolver.ts +200 -12
  219. package/server/service/reference/twin-reference.ts +39 -1
  220. package/server/service/twin-control/twin-control-mutation.ts +4 -3
  221. package/server/service/twin-event/journal-count.ts +53 -0
  222. package/server/service/twin-event/twin-event-keys.ts +16 -1
  223. package/server/service/twin-event/twin-event-type.ts +26 -2
  224. package/server/service/twin-event/twin-event.ts +7 -0
  225. package/server/service/twin-forecast/twin-forecast-query.ts +2 -1
  226. package/server/service/twin-ingest-window/index.ts +7 -0
  227. package/server/service/twin-ingest-window/twin-ingest-window-query.ts +125 -0
  228. package/server/service/twin-ingest-window/twin-ingest-window-writer.ts +57 -0
  229. package/server/service/twin-ingest-window/twin-ingest-window.ts +113 -0
  230. package/server/service/twin-instance/twin-instance.ts +1 -1
  231. package/server/service/twin-journal/twin-journal-query.ts +59 -5
  232. package/server/service/twin-lifecycle/twin-lifecycle-mutation.ts +77 -3
  233. package/server/service/twin-metrics/twin-metrics-query.ts +81 -3
  234. package/server/service/twin-model/axis-journal-evidence.ts +57 -0
  235. package/server/service/twin-model/epcis-coverage.ts +2 -8
  236. package/server/service/twin-model/iec61850-coverage.ts +2 -8
  237. package/server/service/twin-model/isa95-coverage.ts +22 -9
  238. package/server/service/twin-model/item-ref.ts +80 -0
  239. package/server/service/twin-model/name-index.ts +94 -0
  240. package/server/service/twin-model/project-structure.ts +1 -1
  241. package/server/service/twin-model/status-tally.ts +37 -0
  242. package/server/service/twin-model/twin-lineage-query.ts +38 -9
  243. package/server/service/twin-model/twin-model-item-query.ts +26 -27
  244. package/server/service/twin-model/twin-model-query.ts +155 -4
  245. package/server/service/twin-model/twin-model-tree-query.ts +7 -0
  246. package/server/service/twin-readiness/index.ts +3 -0
  247. package/server/service/twin-readiness/twin-readiness-query.ts +96 -0
  248. package/server/service/twin-space/twin-space-resolver.ts +5 -4
  249. package/shared/entity-delta.ts +31 -7
  250. package/shared/kpi-broadcast.ts +1 -1
  251. package/shared/touched-items.ts +73 -0
  252. package/test/axis-journal-evidence.test.ts +71 -0
  253. package/test/axis-read.test.ts +101 -1
  254. package/test/boot-resume.test.ts +92 -26
  255. package/test/broadcast-cost-baseline.test.ts +200 -0
  256. package/test/broadcast-period.test.ts +58 -0
  257. package/test/canonical-ingest-vocabularies.test.ts +36 -1
  258. package/test/canonical-quantity-door.test.ts +61 -0
  259. package/test/command-routing.test.ts +1 -1
  260. package/test/declared-location-types.test.ts +89 -0
  261. package/test/discovery-result.test.ts +1 -1
  262. package/test/duration-estimators.test.ts +1 -1
  263. package/test/entity-delta.test.ts +2 -2
  264. package/test/ingest-bench.test.ts +3 -3
  265. package/test/ingest-health-engine.test.ts +248 -0
  266. package/test/ingest-health-wiring.test.ts +119 -0
  267. package/test/ingest-health.test.ts +306 -0
  268. package/test/ingest-history.test.ts +247 -0
  269. package/test/integration-probes.test.ts +103 -0
  270. package/test/integration-runner.test.ts +95 -0
  271. package/test/item-ref.test.ts +78 -0
  272. package/test/journal-read-discipline.test.ts +177 -0
  273. package/test/journal-retention.test.ts +133 -0
  274. package/test/journal-sort-axis.test.ts +142 -0
  275. package/test/journal-write-door.test.ts +110 -0
  276. package/test/journal-write-trend.test.ts +115 -0
  277. package/test/kernel-kind-guard.test.ts +4 -4
  278. package/test/kpi-fold.test.ts +90 -3
  279. package/test/kpi-query-bench.test.ts +2 -2
  280. package/test/lineage-survives-restart.test.ts +17 -1
  281. package/test/live-cursor-wiring.test.ts +87 -0
  282. package/test/live-feed-registry.test.ts +9 -1
  283. package/test/live-kernel-facts.test.ts +7 -7
  284. package/test/live-mirror-parity.test.ts +6 -0
  285. package/test/load-meter.test.ts +29 -15
  286. package/test/local-declarations.test.ts +1 -1
  287. package/test/log-stamp.test.ts +59 -0
  288. package/test/loop-lag.test.ts +82 -0
  289. package/test/model-gap.test.ts +153 -0
  290. package/test/oee-accumulator.test.ts +4 -0
  291. package/test/operational-vocabulary.test.ts +4 -4
  292. package/test/read-failure-visible.test.ts +145 -0
  293. package/test/reference-grounding.test.ts +70 -0
  294. package/test/resolve-ts-siblings.mjs +52 -0
  295. package/test/restart-policy.test.ts +7 -7
  296. package/test/revision-axis.test.ts +93 -0
  297. package/test/runtime-key.test.ts +2 -2
  298. package/test/scale-twin-bench.test.ts +2 -2
  299. package/test/spec-coverage.test.ts +1 -1
  300. package/test/stage-path.test.ts +95 -0
  301. package/test/standard-coverage.test.ts +15 -3
  302. package/test/status-tally.test.ts +55 -0
  303. package/test/structure-revision-db.test.ts +4 -0
  304. package/test/tenant-registry-db.test.ts +1 -1
  305. package/test/time-range.test.ts +152 -0
  306. package/test/touched-items.test.ts +61 -0
  307. package/test/twin-event-keys.test.ts +10 -2
  308. package/test/twin-model-item-db.test.ts +2 -0
  309. package/test/warm-start-seam.test.ts +4 -0
  310. package/test/yield-loop.test.ts +57 -2
  311. package/tsconfig.shared.tsbuildinfo +1 -1
  312. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ /*
3
+ * ํŠธ์œˆ ๋กœ๊ทธ์˜ ๋ฌธ โ€” **๋ชจ๋“  ์ค„์— ์‹œ๊ฐ์„ ์ฐ๋Š”๋‹ค.** ์ˆœ์ˆ˜(ํ”„๋ ˆ์ž„์›Œํฌ ์˜์กด ์—†์Œ).
4
+ *
5
+ * โ”€โ”€ ์™œ ํ•„์š”ํ•œ๊ฐ€ (2026-08-22) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
6
+ * ใ€Œ์„œ๋ฒ„๊ฐ€ ์™œ ๋А๋ฆฐ๊ฐ€ใ€๋ฅผ ์กฐ์‚ฌํ•˜๋ฉด์„œ ๋ฃจํ”„๊ฐ€ 55์ดˆ ๋ง‰ํžŒ ๊ฒƒ์„ ๊ณ„๊ธฐ๋กœ ์•Œ์•„๋ƒˆ๋Š”๋ฐ(`loop-lag.ts`),
7
+ * **๊ทธ ์‹œ๊ฐ์— ๋ฌด์Šจ ์ผ์ด ์žˆ์—ˆ๋Š”์ง€ ๋กœ๊ทธ์—์„œ ์ฐพ์„ ์ˆ˜ ์—†์—ˆ๋‹ค.** ํŠธ์œˆ์˜ ๋กœ๊ทธ๊ฐ€ `console.log` ๋กœ ๋‚˜๊ฐ€
8
+ * ์‹œ๊ฐ์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ ๋กœ๊ทธ(`2026-08-22T05:54:12+09:00 info: โ€ฆ`)์™€ ์„ž์—ฌ ์žˆ์–ด์„œ, ์–ด๋А
9
+ * ์ค„์ด ์–ธ์ œ ์ฐํ˜”๋Š”์ง€ ์•ž๋’ค ํ”„๋ ˆ์ž„์›Œํฌ ์ค„๋กœ ์ง์ž‘ํ•ด์•ผ ํ–ˆ๋‹ค.
10
+ *
11
+ * โ”€โ”€ ์™œ ํ”„๋ ˆ์ž„์›Œํฌ ๋กœ๊ฑฐ๋ฅผ ๊ทธ๋Œ€๋กœ ์“ฐ์ง€ ์•Š๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
12
+ * ์žฌ๋ฐœ๋ช…์„ ํ”ผํ•˜๋ ค๊ณ  `@things-factory/env` ์˜ `logger` ๋ฅผ ์“ฐ๋ ค ํ–ˆ๋Š”๋ฐ, ์‹ค์ธก์œผ๋กœ ๋ง‰ํ˜”๋‹ค: ์•ฑ **๋ฐ–**์—์„œ๋Š”
13
+ * ๊ทธ ๋กœ๊ฑฐ์— ์ „์†ก์ง€๊ฐ€ ํ•˜๋‚˜๋„ ์—†๋‹ค(์„ค์ •์ด ์•ฑ์—์„œ ์ฃผ์ž…๋œ๋‹ค). ๊ทธ๋ž˜์„œ ์‹œํ—˜ยท๋„๊ตฌ์—์„œ ๋ถ€๋ฅด๋ฉด
14
+ *
15
+ * [winston] Attempt to write logs with no transports โ€ฆ {"message":"โ€ฆ","level":"info"}
16
+ *
17
+ * ๊ฐ€ ๋‚˜์˜ค๊ณ  **๋ฉ”์‹œ์ง€ ์ž์ฒด๊ฐ€ ์‚ฌ๋ผ์ง„๋‹ค.** ํŠธ์œˆ ์—”์ง„์€ ์‹œํ—˜๊ณผ CLI ๋„๊ตฌ์—์„œ๋„ ๋ถˆ๋ ค ๋‹ค๋‹ˆ๋ฏ€๋กœ, ๊ทธ ์กฐ๊ฑด์—์„œ
18
+ * ๋กœ๊ทธ๊ฐ€ ์—†์–ด์ง€๋Š” ๊ฒƒ์€ ๋ฐ”๊ฟ”์„  ์•ˆ ๋˜๋Š” ๊ฑฐ๋™์ด๋‹ค(๋กœ๊ทธ๊ฐ€ ์‚ฌ๋ผ์ง€๋Š” ๊ฒƒ์ด ์ง€๊ธˆ ๋ฌธ์ œ์˜ ์›์ธ์ด์—ˆ๋‹ค).
19
+ *
20
+ * ๊ทธ๋ž˜์„œ **์‹ฑํฌ๋Š” ๊ทธ๋Œ€๋กœ ๋‘๊ณ **(console) ๋น ์ง„ ์‚ฌ์‹ค ํ•˜๋‚˜๋งŒ ์ฑ„์šด๋‹ค โ€” ์‹œ๊ฐ. ํ˜•์‹์€ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ฐ™์€
21
+ * ๋ชจ์–‘์œผ๋กœ ๋งž์ถฐ ํ•œ ํŒŒ์ผ์—์„œ ์„ž์—ฌ ์ฝํžˆ๊ฒŒ ํ•˜๊ณ , **๋ฐ€๋ฆฌ์ดˆ๊นŒ์ง€** ๋‚จ๊ธด๋‹ค(๊ณ„๊ธฐ์˜ ๊ฐ’์ด epoch ms ๋ผ
22
+ * ์ดˆ ๋‹จ์œ„๋กœ๋Š” ๊ฐ™์€ ์ดˆ ์•ˆ์˜ ์ˆœ์„œ๋ฅผ ๊ฐ€๋ฆด ์ˆ˜ ์—†๋‹ค).
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.twinError = exports.twinWarn = exports.twinLog = void 0;
26
+ exports.stamp = stamp;
27
+ exports.line = line;
28
+ /** ๋‘ ์ž๋ฆฌยท์„ธ ์ž๋ฆฌ 0 ์ฑ„์šฐ๊ธฐ โ€” ํ˜•์‹์ด ํ”๋“ค๋ฆฌ๋ฉด ์ •๋ ฌํ•ด ์ฝ์„ ์ˆ˜ ์—†๋‹ค. */
29
+ const p2 = (n) => String(n).padStart(2, '0');
30
+ const p3 = (n) => String(n).padStart(3, '0');
31
+ /**
32
+ * ์ง€์—ญ ์‹œ๊ฐ + ์˜คํ”„์…‹ โ€” `2026-08-22T05:54:12.345+09:00`.
33
+ *
34
+ * UTC ๋กœ ์ฐ์ง€ ์•Š๋Š”๋‹ค: ์ด ๋กœ๊ทธ๋ฅผ ์ฝ๋Š” ์‚ฌ๋žŒ์€ ํ˜„์žฅ์˜ ์‹œ๊ฐ์œผ๋กœ ์ด์•ผ๊ธฐํ•˜๊ณ , ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๋‹ค๋ฅธ ์ค„๋„
35
+ * ์ง€์—ญ ์‹œ๊ฐ์ด๋‹ค. ๋‘ ์ค„์ด ๋‹ค๋ฅธ ๊ธฐ์ค€์ด๋ฉด ๋‚˜๋ž€ํžˆ ๋†“๊ณ  ์ฝ์„ ์ˆ˜ ์—†๋‹ค.
36
+ */
37
+ function stamp(at = new Date()) {
38
+ const off = -at.getTimezoneOffset();
39
+ const sign = off >= 0 ? '+' : '-';
40
+ const abs = Math.abs(off);
41
+ return (`${at.getFullYear()}-${p2(at.getMonth() + 1)}-${p2(at.getDate())}` +
42
+ `T${p2(at.getHours())}:${p2(at.getMinutes())}:${p2(at.getSeconds())}.${p3(at.getMilliseconds())}` +
43
+ `${sign}${p2(Math.floor(abs / 60))}:${p2(abs % 60)}`);
44
+ }
45
+ /**
46
+ * ์ธ์ž ์—ฌ๋Ÿฟ์„ ํ•œ ์ค„๋กœ โ€” **์–ด๋–ค ์ธ์ž๋„ ๋ฒ„๋ฆฌ์ง€ ์•Š๋Š”๋‹ค.**
47
+ *
48
+ * `console.error(msg, err)` ์ฒ˜๋Ÿผ ์“ฐ๋˜ ์ž๋ฆฌ๊ฐ€ ๋งŽ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ ๋กœ๊ฑฐ์— ๊ทธ๋Œ€๋กœ ๋„˜๊ธฐ๋ฉด ๋‘ ๋ฒˆ์งธ ์ธ์ž๋Š”
49
+ * meta ๋กœ ๋“ค์–ด๊ฐ€ ์šฐ๋ฆฌ ํ˜•์‹(`message` ๋งŒ ์ฐ๋Š”๋‹ค)์—์„œ **์กฐ์šฉํžˆ ์‚ฌ๋ผ์ง„๋‹ค.** ๊ทธ๋ž˜์„œ ์—ฌ๊ธฐ์„œ ๋ฌธ์ž์—ด๋กœ ํŽธ๋‹ค.
50
+ * ์˜ค๋ฅ˜๋Š” ์Šคํƒ๊นŒ์ง€ โ€” ์Šคํƒ์ด ์—†์œผ๋ฉด ใ€Œ์–ด๋””์„œ ๋‚ฌ๋‚˜ใ€๋ฅผ ์žƒ๋Š”๋‹ค.
51
+ */
52
+ function line(args) {
53
+ return args
54
+ .map(a => {
55
+ if (typeof a === 'string')
56
+ return a;
57
+ if (a instanceof Error)
58
+ return a.stack ?? a.message;
59
+ if (a === undefined)
60
+ return 'undefined';
61
+ if (a === null)
62
+ return 'null';
63
+ try {
64
+ return typeof a === 'object' ? JSON.stringify(a) : String(a);
65
+ }
66
+ catch {
67
+ /* ์ˆœํ™˜ ์ฐธ์กฐ ๋“ฑ โ€” ๊ฐ’์„ ๋ชป ์ ์–ด๋„ **๋ฌด์—‡์ด ์žˆ์—ˆ๋‹ค๋Š” ์‚ฌ์‹ค**์€ ๋‚จ๊ธด๋‹ค. */
68
+ return String(a);
69
+ }
70
+ })
71
+ .join(' ');
72
+ }
73
+ /* ์ˆ˜์ค€ ํ‘œ๊ธฐ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ฐ™์€ ๋‚ฑ๋ง์„ ์“ด๋‹ค(`info`ยท`warn`ยท`error`) โ€” ๊ฐ™์€ ํŒŒ์ผ์—์„œ ๊ฑธ๋Ÿฌ ์ฝ๋Š”๋‹ค. */
74
+ const twinLog = (...args) => console.log(`${stamp()} info: ${line(args)}`);
75
+ exports.twinLog = twinLog;
76
+ const twinWarn = (...args) => console.warn(`${stamp()} warn: ${line(args)}`);
77
+ exports.twinWarn = twinWarn;
78
+ const twinError = (...args) => console.error(`${stamp()} error: ${line(args)}`);
79
+ exports.twinError = twinError;
80
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../server/engine/log.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * ํŠธ์œˆ ๋กœ๊ทธ์˜ ๋ฌธ โ€” **๋ชจ๋“  ์ค„์— ์‹œ๊ฐ์„ ์ฐ๋Š”๋‹ค.** ์ˆœ์ˆ˜(ํ”„๋ ˆ์ž„์›Œํฌ ์˜์กด ์—†์Œ).\n *\n * โ”€โ”€ ์™œ ํ•„์š”ํ•œ๊ฐ€ (2026-08-22) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ใ€Œ์„œ๋ฒ„๊ฐ€ ์™œ ๋А๋ฆฐ๊ฐ€ใ€๋ฅผ ์กฐ์‚ฌํ•˜๋ฉด์„œ ๋ฃจํ”„๊ฐ€ 55์ดˆ ๋ง‰ํžŒ ๊ฒƒ์„ ๊ณ„๊ธฐ๋กœ ์•Œ์•„๋ƒˆ๋Š”๋ฐ(`loop-lag.ts`),\n * **๊ทธ ์‹œ๊ฐ์— ๋ฌด์Šจ ์ผ์ด ์žˆ์—ˆ๋Š”์ง€ ๋กœ๊ทธ์—์„œ ์ฐพ์„ ์ˆ˜ ์—†์—ˆ๋‹ค.** ํŠธ์œˆ์˜ ๋กœ๊ทธ๊ฐ€ `console.log` ๋กœ ๋‚˜๊ฐ€\n * ์‹œ๊ฐ์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ ๋กœ๊ทธ(`2026-08-22T05:54:12+09:00 info: โ€ฆ`)์™€ ์„ž์—ฌ ์žˆ์–ด์„œ, ์–ด๋А\n * ์ค„์ด ์–ธ์ œ ์ฐํ˜”๋Š”์ง€ ์•ž๋’ค ํ”„๋ ˆ์ž„์›Œํฌ ์ค„๋กœ ์ง์ž‘ํ•ด์•ผ ํ–ˆ๋‹ค.\n *\n * โ”€โ”€ ์™œ ํ”„๋ ˆ์ž„์›Œํฌ ๋กœ๊ฑฐ๋ฅผ ๊ทธ๋Œ€๋กœ ์“ฐ์ง€ ์•Š๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์žฌ๋ฐœ๋ช…์„ ํ”ผํ•˜๋ ค๊ณ  `@things-factory/env` ์˜ `logger` ๋ฅผ ์“ฐ๋ ค ํ–ˆ๋Š”๋ฐ, ์‹ค์ธก์œผ๋กœ ๋ง‰ํ˜”๋‹ค: ์•ฑ **๋ฐ–**์—์„œ๋Š”\n * ๊ทธ ๋กœ๊ฑฐ์— ์ „์†ก์ง€๊ฐ€ ํ•˜๋‚˜๋„ ์—†๋‹ค(์„ค์ •์ด ์•ฑ์—์„œ ์ฃผ์ž…๋œ๋‹ค). ๊ทธ๋ž˜์„œ ์‹œํ—˜ยท๋„๊ตฌ์—์„œ ๋ถ€๋ฅด๋ฉด\n *\n * [winston] Attempt to write logs with no transports โ€ฆ {\"message\":\"โ€ฆ\",\"level\":\"info\"}\n *\n * ๊ฐ€ ๋‚˜์˜ค๊ณ  **๋ฉ”์‹œ์ง€ ์ž์ฒด๊ฐ€ ์‚ฌ๋ผ์ง„๋‹ค.** ํŠธ์œˆ ์—”์ง„์€ ์‹œํ—˜๊ณผ CLI ๋„๊ตฌ์—์„œ๋„ ๋ถˆ๋ ค ๋‹ค๋‹ˆ๋ฏ€๋กœ, ๊ทธ ์กฐ๊ฑด์—์„œ\n * ๋กœ๊ทธ๊ฐ€ ์—†์–ด์ง€๋Š” ๊ฒƒ์€ ๋ฐ”๊ฟ”์„  ์•ˆ ๋˜๋Š” ๊ฑฐ๋™์ด๋‹ค(๋กœ๊ทธ๊ฐ€ ์‚ฌ๋ผ์ง€๋Š” ๊ฒƒ์ด ์ง€๊ธˆ ๋ฌธ์ œ์˜ ์›์ธ์ด์—ˆ๋‹ค).\n *\n * ๊ทธ๋ž˜์„œ **์‹ฑํฌ๋Š” ๊ทธ๋Œ€๋กœ ๋‘๊ณ **(console) ๋น ์ง„ ์‚ฌ์‹ค ํ•˜๋‚˜๋งŒ ์ฑ„์šด๋‹ค โ€” ์‹œ๊ฐ. ํ˜•์‹์€ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ฐ™์€\n * ๋ชจ์–‘์œผ๋กœ ๋งž์ถฐ ํ•œ ํŒŒ์ผ์—์„œ ์„ž์—ฌ ์ฝํžˆ๊ฒŒ ํ•˜๊ณ , **๋ฐ€๋ฆฌ์ดˆ๊นŒ์ง€** ๋‚จ๊ธด๋‹ค(๊ณ„๊ธฐ์˜ ๊ฐ’์ด epoch ms ๋ผ\n * ์ดˆ ๋‹จ์œ„๋กœ๋Š” ๊ฐ™์€ ์ดˆ ์•ˆ์˜ ์ˆœ์„œ๋ฅผ ๊ฐ€๋ฆด ์ˆ˜ ์—†๋‹ค).\n */\n\n/** ๋‘ ์ž๋ฆฌยท์„ธ ์ž๋ฆฌ 0 ์ฑ„์šฐ๊ธฐ โ€” ํ˜•์‹์ด ํ”๋“ค๋ฆฌ๋ฉด ์ •๋ ฌํ•ด ์ฝ์„ ์ˆ˜ ์—†๋‹ค. */\nconst p2 = (n: number) => String(n).padStart(2, '0')\nconst p3 = (n: number) => String(n).padStart(3, '0')\n\n/**\n * ์ง€์—ญ ์‹œ๊ฐ + ์˜คํ”„์…‹ โ€” `2026-08-22T05:54:12.345+09:00`.\n *\n * UTC ๋กœ ์ฐ์ง€ ์•Š๋Š”๋‹ค: ์ด ๋กœ๊ทธ๋ฅผ ์ฝ๋Š” ์‚ฌ๋žŒ์€ ํ˜„์žฅ์˜ ์‹œ๊ฐ์œผ๋กœ ์ด์•ผ๊ธฐํ•˜๊ณ , ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๋‹ค๋ฅธ ์ค„๋„\n * ์ง€์—ญ ์‹œ๊ฐ์ด๋‹ค. ๋‘ ์ค„์ด ๋‹ค๋ฅธ ๊ธฐ์ค€์ด๋ฉด ๋‚˜๋ž€ํžˆ ๋†“๊ณ  ์ฝ์„ ์ˆ˜ ์—†๋‹ค.\n */\nexport function stamp(at: Date = new Date()): string {\n const off = -at.getTimezoneOffset()\n const sign = off >= 0 ? '+' : '-'\n const abs = Math.abs(off)\n return (\n `${at.getFullYear()}-${p2(at.getMonth() + 1)}-${p2(at.getDate())}` +\n `T${p2(at.getHours())}:${p2(at.getMinutes())}:${p2(at.getSeconds())}.${p3(at.getMilliseconds())}` +\n `${sign}${p2(Math.floor(abs / 60))}:${p2(abs % 60)}`\n )\n}\n\n/**\n * ์ธ์ž ์—ฌ๋Ÿฟ์„ ํ•œ ์ค„๋กœ โ€” **์–ด๋–ค ์ธ์ž๋„ ๋ฒ„๋ฆฌ์ง€ ์•Š๋Š”๋‹ค.**\n *\n * `console.error(msg, err)` ์ฒ˜๋Ÿผ ์“ฐ๋˜ ์ž๋ฆฌ๊ฐ€ ๋งŽ๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ ๋กœ๊ฑฐ์— ๊ทธ๋Œ€๋กœ ๋„˜๊ธฐ๋ฉด ๋‘ ๋ฒˆ์งธ ์ธ์ž๋Š”\n * meta ๋กœ ๋“ค์–ด๊ฐ€ ์šฐ๋ฆฌ ํ˜•์‹(`message` ๋งŒ ์ฐ๋Š”๋‹ค)์—์„œ **์กฐ์šฉํžˆ ์‚ฌ๋ผ์ง„๋‹ค.** ๊ทธ๋ž˜์„œ ์—ฌ๊ธฐ์„œ ๋ฌธ์ž์—ด๋กœ ํŽธ๋‹ค.\n * ์˜ค๋ฅ˜๋Š” ์Šคํƒ๊นŒ์ง€ โ€” ์Šคํƒ์ด ์—†์œผ๋ฉด ใ€Œ์–ด๋””์„œ ๋‚ฌ๋‚˜ใ€๋ฅผ ์žƒ๋Š”๋‹ค.\n */\nexport function line(args: unknown[]): string {\n return args\n .map(a => {\n if (typeof a === 'string') return a\n if (a instanceof Error) return a.stack ?? a.message\n if (a === undefined) return 'undefined'\n if (a === null) return 'null'\n try {\n return typeof a === 'object' ? JSON.stringify(a) : String(a)\n } catch {\n /* ์ˆœํ™˜ ์ฐธ์กฐ ๋“ฑ โ€” ๊ฐ’์„ ๋ชป ์ ์–ด๋„ **๋ฌด์—‡์ด ์žˆ์—ˆ๋‹ค๋Š” ์‚ฌ์‹ค**์€ ๋‚จ๊ธด๋‹ค. */\n return String(a)\n }\n })\n .join(' ')\n}\n\n/* ์ˆ˜์ค€ ํ‘œ๊ธฐ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ฐ™์€ ๋‚ฑ๋ง์„ ์“ด๋‹ค(`info`ยท`warn`ยท`error`) โ€” ๊ฐ™์€ ํŒŒ์ผ์—์„œ ๊ฑธ๋Ÿฌ ์ฝ๋Š”๋‹ค. */\nexport const twinLog = (...args: unknown[]): void => console.log(`${stamp()} info: ${line(args)}`)\nexport const twinWarn = (...args: unknown[]): void => console.warn(`${stamp()} warn: ${line(args)}`)\nexport const twinError = (...args: unknown[]): void => console.error(`${stamp()} error: ${line(args)}`)\n"]}
@@ -0,0 +1,54 @@
1
+ /** ํ‘œ๋ณธ ๊ฐ„๊ฒฉ(ms) โ€” ์ด˜์ด˜ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ธด ์ •์ฒด๋ฅผ ๋†“์น˜์ง€ ์•Š๋Š” ์ •๋„๋ฉด ๋œ๋‹ค. */
2
+ export declare const LAG_SAMPLE_MS = 500;
3
+ /** ์ด ๊ฐ’์„ ๋„˜๋Š” ์ง€์ฒด๋งŒ ใ€Œ์ •์ฒดใ€๋กœ ์„ผ๋‹ค(ms). ์‚ฌ๋žŒ์ด ํ™”๋ฉด์—์„œ ๋А๋ผ๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ํฌ๊ธฐ. */
4
+ export declare const LAG_STALL_MS = 200;
5
+ /** ์ฐฝ ๊ธธ์ด(ms) โ€” `twinLoad` ์˜ ์ฐฝ๊ณผ ๊ฐ™์€ ํฌ๊ธฐ๋กœ ๋‘์–ด ๋‚˜๋ž€ํžˆ ์ฝ๋Š”๋‹ค. */
6
+ export declare const LAG_WINDOW_MS = 10000;
7
+ export interface LoopLagWindow {
8
+ /** ์ด ์ฐฝ์—์„œ ๊ฐ€์žฅ ๊ธธ๊ฒŒ ๋ง‰ํžŒ ์‹œ๊ฐ„(ms). */
9
+ maxMs: number;
10
+ /** ์ •์ฒด(๋ฌธํ„ฑ ์ดˆ๊ณผ) ํšŸ์ˆ˜. */
11
+ stalls: number;
12
+ /** ํ‘œ๋ณธ ์ˆ˜ โ€” ๋ถ„๋ชจ๋‹ค. */
13
+ samples: number;
14
+ /** ์ง€์ฒด ํ•ฉ(ms) โ€” ํ‰๊ท ์€ ์ฝ๋Š” ์ชฝ์—์„œ ๋‚ธ๋‹ค. */
15
+ totalMs: number;
16
+ /** ์ฐฝ์ด ์—ด๋ฆฐ ์‹œ๊ฐ. */
17
+ startMs: number;
18
+ }
19
+ export interface LoopLagView {
20
+ /** ๋งˆ์ง€๋ง‰์œผ๋กœ ๋‹ซํžŒ ์ฐฝ โ€” ใ€Œ์ง€๊ธˆ ์–ด๋–ค๊ฐ€ใ€. ์•„์ง ํ•œ ์ฐฝ๋„ ์•ˆ ์ง€๋‚ฌ์œผ๋ฉด null. */
21
+ recent: (LoopLagWindow & {
22
+ endMs: number;
23
+ }) | null;
24
+ /** ๊ธฐ๋™ ์ดํ›„ ๋ˆ„์ . */
25
+ total: LoopLagWindow;
26
+ /** ๊ธฐ๋™ ์ดํ›„ ๊ฐ€์žฅ ๊ธธ๊ฒŒ ๋ง‰ํžŒ ์‹œ๊ฐ(ms, epoch) โ€” ์–ธ์ œ์˜€๋Š”์ง€๊ฐ€ ์›์ธ์„ ๊ฐ€๋ฆฌ๋Š” ๋ฐ ์“ฐ์ธ๋‹ค. */
27
+ worstAtMs: number | null;
28
+ /** ํ‘œ๋ณธ ๊ฐ„๊ฒฉ โ€” ์ฝ๋Š” ์ชฝ์ด ์ด ๊ฐ’๋ณด๋‹ค ์งง์€ ์ •์ฒด๋Š” ๋ชป ๋ณธ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„์•ผ ํ•œ๋‹ค. */
29
+ sampleMs: number;
30
+ /** ์ •์ฒด๋กœ ์„ธ๋Š” ๋ฌธํ„ฑ. */
31
+ stallMs: number;
32
+ }
33
+ export declare class LoopLagSampler {
34
+ private window;
35
+ private closed;
36
+ private total;
37
+ private worstAtMs;
38
+ private timer;
39
+ private expectedMs;
40
+ private sampleMs;
41
+ private stallMs;
42
+ private windowMs;
43
+ private now;
44
+ constructor(sampleMs?: number, stallMs?: number, windowMs?: number, now?: () => number);
45
+ /** ํ‘œ๋ณธ์„ ํ•˜๋‚˜ ๋„ฃ๋Š”๋‹ค โ€” ํƒ€์ด๋จธ๊ฐ€ ๋ถ€๋ฅด๊ณ , ์‹œํ—˜์€ ์ง์ ‘ ๋ถ€๋ฅธ๋‹ค(์‹œ๊ณ„๋ฅผ ๋ฐ€์–ด ๋„ฃ์–ด ์žฐ๋‹ค). */
46
+ sample(atMs?: number): number;
47
+ /** ๊ณ„๊ธฐํŒ์ด ์ฝ๋Š” ๊ฐ’. **ํ•œ ์ฐฝ๋„ ๋‹ซํžˆ์ง€ ์•Š์•˜์œผ๋ฉด `recent` ๋Š” null** โ€” ์ฑ„์šฐ๋Š” ์ค‘์ธ ์ฐฝ์€ ๊ณผ์†Œ ์ง‘๊ณ„๋‹ค. */
48
+ view(): LoopLagView;
49
+ /** ํ‘œ๋ณธ ํƒ€์ด๋จธ ๊ธฐ๋™(1ํšŒ) โ€” ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ๋ฅผ ๋ง‰์ง€ ์•Š๋Š”๋‹ค. */
50
+ start(): void;
51
+ stop(): void;
52
+ }
53
+ /** ํ”„๋กœ์„ธ์Šค ํ•˜๋‚˜์˜ ๋ฃจํ”„๋ฅผ ์žฌ๋Š” ๊ฒƒ์ด๋ฏ€๋กœ ํ‘œ๋ณธ๊ธฐ๋„ ํ•˜๋‚˜๋‹ค. */
54
+ export declare const loopLag: LoopLagSampler;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ /*
3
+ * ์ด๋ฒคํŠธ ๋ฃจํ”„ ์ง€์ฒด โ€” **ํ™”๋ฉด์ด ๋А๋ฆฐ ์ด์œ ๋ฅผ ์ง€์–ด๋‚ด์ง€ ์•Š๊ธฐ ์œ„ํ•ด.** ์ˆœ์ˆ˜(import ์—†์Œ).
4
+ *
5
+ * โ”€โ”€ ์™œ ํ•„์š”ํ•œ๊ฐ€ (2026-08-21) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
6
+ * ใ€ŒUI ๋ฐ˜์‘์„ฑ์ด ๋А๋ฆฌ๋‹คใ€๋ฅผ ์ง„๋‹จํ•˜๋ ค ํ–ˆ๋Š”๋ฐ, ์žˆ๋Š” ๊ณ„๊ธฐํŒ์œผ๋กœ๋Š” ๋‹ต์ด ๋‚˜์˜ค์ง€ ์•Š์•˜๋‹ค. `twinLoad` ๋Š” **ํŠธ์œˆ์˜
7
+ * ๊ณ„์ธก๋œ ์ž‘์—…**๋งŒ ์žฌ๊ณ , `processCpuRatio` ๋Š” ํ”„๋กœ์„ธ์Šค ์ „์ฒด๋ฅผ ์žฌ์ง€๋งŒ **์–ธ์ œ ์–ผ๋งˆ๋‚˜ ๋ฉˆ์ท„๋‚˜**๋ฅผ ๋งํ•˜์ง€
8
+ * ๋ชปํ•œ๋‹ค. ๋ฐ–์—์„œ HTTP ์ง€์—ฐ์„ ์žฌ ๋ณด๋‹ˆ ๊ฐ™์€ ์š”์ฒญ์ด 44ms ์™€ 5.8์ดˆ๋กœ ๊ฐˆ๋ผ์กŒ๋Š”๋ฐ, ๊ทธ 5.8์ดˆ๊ฐ€ ํŠธ์œˆ ๋•Œ๋ฌธ์ธ์ง€
9
+ * webpack ์žฌ๋นŒ๋“œ ๋•Œ๋ฌธ์ธ์ง€ ๋‚จ์˜ ์žฌ๊ธฐ๋™ ๋•Œ๋ฌธ์ธ์ง€ **๊ฐ€๋ฆด ๊ทผ๊ฑฐ๊ฐ€ ์—†์—ˆ๋‹ค.**
10
+ *
11
+ * ๊ทผ๊ฑฐ ์—†์ด ์›์ธ์„ ๊ณ ๋ฅด๋ฉด ์—‰๋šฑํ•œ ๊ณณ์„ ๊ณ ์นœ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฃจํ”„๊ฐ€ ์‹ค์ œ๋กœ ์–ผ๋งˆ๋‚˜ ๋ง‰ํ˜”๋Š”์ง€๋ฅผ ์žฐ๋‹ค.
12
+ *
13
+ * โ”€โ”€ ์–ด๋–ป๊ฒŒ ์žฌ๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
14
+ * ์ผ์ • ๊ฐ„๊ฒฉ์œผ๋กœ ๊นจ์–ด๋‚˜๋Š” ํƒ€์ด๋จธ๋ฅผ ๋‘๊ณ , **์˜ˆ์ • ์‹œ๊ฐ๊ณผ ์‹ค์ œ ์‹œ๊ฐ์˜ ์ฐจ์ด**๋ฅผ ๋ณธ๋‹ค. ๋ฃจํ”„๊ฐ€ ๋ง‰ํ˜€ ์žˆ์—ˆ์œผ๋ฉด
15
+ * ๊ทธ๋งŒํผ ๋Šฆ๊ฒŒ ๊นจ์–ด๋‚œ๋‹ค. ์žฌ๋Š” ๋น„์šฉ์€ ๊ทธ ์ฐจ์ด ๊ณ„์‚ฐ ํ•˜๋‚˜๋ฟ์ด๋‹ค(์ฐฝ๋งˆ๋‹ค ๊ฐ’ ๋‹ค์„ฏ).
16
+ *
17
+ * ์ด ๊ฐ’์€ **์›์ธ์„ ๋งํ•˜์ง€ ์•Š๋Š”๋‹ค** โ€” ใ€Œ200ms ์ด์ƒ ๋ง‰ํžŒ ์ผ์ด ์ด ์ฐฝ์—์„œ ์„ธ ๋ฒˆ, ๊ฐ€์žฅ ๊ธด ๊ฒƒ์€ 4.6์ดˆใ€๊นŒ์ง€๊ฐ€
18
+ * ์‚ฌ์‹ค์ด๋‹ค. ์›์ธ์€ ๊ทธ ์‹œ๊ฐ์˜ ํŠธ์œˆ ๋ถ€ํ•˜(`twinLoad`)์™€ ํ”„๋กœ์„ธ์Šค CPU ์™€ ๋‚˜๋ž€ํžˆ ๋†“๊ณ  ์‚ฌ๋žŒ์ด ๊ฐ€๋ฆฐ๋‹ค.
19
+ * ์žฌ์ง€ ์•Š์€ ๊ฒƒ์„ 0 ์œผ๋กœ ์ ์ง€ ์•Š๋Š”๋‹ค โ€” ํ•œ ๋ฒˆ๋„ ๊นจ์–ด๋‚˜์ง€ ์•Š์•˜์œผ๋ฉด `null` ์ด๋‹ค.
20
+ */
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.loopLag = exports.LoopLagSampler = exports.LAG_WINDOW_MS = exports.LAG_STALL_MS = exports.LAG_SAMPLE_MS = void 0;
23
+ /** ํ‘œ๋ณธ ๊ฐ„๊ฒฉ(ms) โ€” ์ด˜์ด˜ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ธด ์ •์ฒด๋ฅผ ๋†“์น˜์ง€ ์•Š๋Š” ์ •๋„๋ฉด ๋œ๋‹ค. */
24
+ exports.LAG_SAMPLE_MS = 500;
25
+ /** ์ด ๊ฐ’์„ ๋„˜๋Š” ์ง€์ฒด๋งŒ ใ€Œ์ •์ฒดใ€๋กœ ์„ผ๋‹ค(ms). ์‚ฌ๋žŒ์ด ํ™”๋ฉด์—์„œ ๋А๋ผ๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ํฌ๊ธฐ. */
26
+ exports.LAG_STALL_MS = 200;
27
+ /** ์ฐฝ ๊ธธ์ด(ms) โ€” `twinLoad` ์˜ ์ฐฝ๊ณผ ๊ฐ™์€ ํฌ๊ธฐ๋กœ ๋‘์–ด ๋‚˜๋ž€ํžˆ ์ฝ๋Š”๋‹ค. */
28
+ exports.LAG_WINDOW_MS = 10_000;
29
+ const emptyWindow = (startMs) => ({ maxMs: 0, stalls: 0, samples: 0, totalMs: 0, startMs });
30
+ class LoopLagSampler {
31
+ /* ์ƒ์„ฑ์ž ํŒŒ๋ผ๋ฏธํ„ฐ ํ”„๋กœํผํ‹ฐ(`private x = โ€ฆ`)๋Š” ์“ฐ์ง€ ์•Š๋Š”๋‹ค โ€” ์‹œํ—˜์ด ์†Œ์Šค๋ฅผ ๊ทธ๋Œ€๋กœ ์‹คํ–‰ํ•˜๋Š”๋ฐ
32
+ (ํƒ€์ž… ์ œ๊ฑฐ ์‹คํ–‰ ๋ฐฉ์‹) ๊ทธ ๋ฌธ๋ฒ•์€ ์ง€์›๋˜์ง€ ์•Š์•„ ํŒŒ์ผ ์ „์ฒด๊ฐ€ ์—ด๋ฆฌ์ง€ ์•Š๋Š”๋‹ค. */
33
+ constructor(sampleMs = exports.LAG_SAMPLE_MS, stallMs = exports.LAG_STALL_MS, windowMs = exports.LAG_WINDOW_MS, now = Date.now) {
34
+ this.closed = null;
35
+ this.worstAtMs = null;
36
+ this.sampleMs = sampleMs;
37
+ this.stallMs = stallMs;
38
+ this.windowMs = windowMs;
39
+ this.now = now;
40
+ const t = this.now();
41
+ this.window = emptyWindow(t);
42
+ this.total = emptyWindow(t);
43
+ this.expectedMs = t + sampleMs;
44
+ }
45
+ /** ํ‘œ๋ณธ์„ ํ•˜๋‚˜ ๋„ฃ๋Š”๋‹ค โ€” ํƒ€์ด๋จธ๊ฐ€ ๋ถ€๋ฅด๊ณ , ์‹œํ—˜์€ ์ง์ ‘ ๋ถ€๋ฅธ๋‹ค(์‹œ๊ณ„๋ฅผ ๋ฐ€์–ด ๋„ฃ์–ด ์žฐ๋‹ค). */
46
+ sample(atMs = this.now()) {
47
+ const lag = Math.max(0, atMs - this.expectedMs);
48
+ this.expectedMs = atMs + this.sampleMs;
49
+ for (const w of [this.window, this.total]) {
50
+ w.samples += 1;
51
+ w.totalMs += lag;
52
+ if (lag > this.stallMs)
53
+ w.stalls += 1;
54
+ if (lag > w.maxMs)
55
+ w.maxMs = lag;
56
+ }
57
+ if (lag >= this.total.maxMs && lag > this.stallMs)
58
+ this.worstAtMs = atMs;
59
+ if (atMs - this.window.startMs >= this.windowMs) {
60
+ this.closed = { ...this.window, endMs: atMs };
61
+ this.window = emptyWindow(atMs);
62
+ }
63
+ return lag;
64
+ }
65
+ /** ๊ณ„๊ธฐํŒ์ด ์ฝ๋Š” ๊ฐ’. **ํ•œ ์ฐฝ๋„ ๋‹ซํžˆ์ง€ ์•Š์•˜์œผ๋ฉด `recent` ๋Š” null** โ€” ์ฑ„์šฐ๋Š” ์ค‘์ธ ์ฐฝ์€ ๊ณผ์†Œ ์ง‘๊ณ„๋‹ค. */
66
+ view() {
67
+ return { recent: this.closed, total: this.total, worstAtMs: this.worstAtMs, sampleMs: this.sampleMs, stallMs: this.stallMs };
68
+ }
69
+ /** ํ‘œ๋ณธ ํƒ€์ด๋จธ ๊ธฐ๋™(1ํšŒ) โ€” ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ๋ฅผ ๋ง‰์ง€ ์•Š๋Š”๋‹ค. */
70
+ start() {
71
+ if (this.timer)
72
+ return;
73
+ this.timer = setInterval(() => this.sample(), this.sampleMs);
74
+ if (typeof this.timer?.unref === 'function')
75
+ this.timer.unref();
76
+ }
77
+ stop() {
78
+ if (!this.timer)
79
+ return;
80
+ clearInterval(this.timer);
81
+ this.timer = undefined;
82
+ }
83
+ }
84
+ exports.LoopLagSampler = LoopLagSampler;
85
+ /** ํ”„๋กœ์„ธ์Šค ํ•˜๋‚˜์˜ ๋ฃจํ”„๋ฅผ ์žฌ๋Š” ๊ฒƒ์ด๋ฏ€๋กœ ํ‘œ๋ณธ๊ธฐ๋„ ํ•˜๋‚˜๋‹ค. */
86
+ exports.loopLag = new LoopLagSampler();
87
+ //# sourceMappingURL=loop-lag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop-lag.js","sourceRoot":"","sources":["../../server/engine/loop-lag.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;AAEH,mDAAmD;AACtC,QAAA,aAAa,GAAG,GAAG,CAAA;AAChC,sDAAsD;AACzC,QAAA,YAAY,GAAG,GAAG,CAAA;AAC/B,oDAAoD;AACvC,QAAA,aAAa,GAAG,MAAM,CAAA;AA4BnC,MAAM,WAAW,GAAG,CAAC,OAAe,EAAiB,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;AAElH,MAAa,cAAc;IAazB;qDACiD;IACjD,YAAY,QAAQ,GAAG,qBAAa,EAAE,OAAO,GAAG,oBAAY,EAAE,QAAQ,GAAG,qBAAa,EAAE,MAAoB,IAAI,CAAC,GAAG;QAb5G,WAAM,GAA+C,IAAI,CAAA;QAEzD,cAAS,GAAkB,IAAI,CAAA;QAYrC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QACd,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACpB,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QAC5B,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QAC3B,IAAI,CAAC,UAAU,GAAG,CAAC,GAAG,QAAQ,CAAA;IAChC,CAAC;IAED,uDAAuD;IACvD,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAA;QAC/C,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAA;QACtC,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,CAAC,CAAC,OAAO,IAAI,CAAC,CAAA;YACd,CAAC,CAAC,OAAO,IAAI,GAAG,CAAA;YAChB,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO;gBAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAA;YACrC,IAAI,GAAG,GAAG,CAAC,CAAC,KAAK;gBAAE,CAAC,CAAC,KAAK,GAAG,GAAG,CAAA;QAClC,CAAC;QACD,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;QACxE,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChD,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;YAC7C,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;QACjC,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,uEAAuE;IACvE,IAAI;QACF,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;IAC9H,CAAC;IAED,uCAAuC;IACvC,KAAK;QACH,IAAI,IAAI,CAAC,KAAK;YAAE,OAAM;QACtB,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC5D,IAAI,OAAO,IAAI,CAAC,KAAK,EAAE,KAAK,KAAK,UAAU;YAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;IACjE,CAAC;IAED,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAM;QACvB,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACzB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAA;IACxB,CAAC;CACF;AA7DD,wCA6DC;AAED,qCAAqC;AACxB,QAAA,OAAO,GAAG,IAAI,cAAc,EAAE,CAAA","sourcesContent":["/*\n * ์ด๋ฒคํŠธ ๋ฃจํ”„ ์ง€์ฒด โ€” **ํ™”๋ฉด์ด ๋А๋ฆฐ ์ด์œ ๋ฅผ ์ง€์–ด๋‚ด์ง€ ์•Š๊ธฐ ์œ„ํ•ด.** ์ˆœ์ˆ˜(import ์—†์Œ).\n *\n * โ”€โ”€ ์™œ ํ•„์š”ํ•œ๊ฐ€ (2026-08-21) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ใ€ŒUI ๋ฐ˜์‘์„ฑ์ด ๋А๋ฆฌ๋‹คใ€๋ฅผ ์ง„๋‹จํ•˜๋ ค ํ–ˆ๋Š”๋ฐ, ์žˆ๋Š” ๊ณ„๊ธฐํŒ์œผ๋กœ๋Š” ๋‹ต์ด ๋‚˜์˜ค์ง€ ์•Š์•˜๋‹ค. `twinLoad` ๋Š” **ํŠธ์œˆ์˜\n * ๊ณ„์ธก๋œ ์ž‘์—…**๋งŒ ์žฌ๊ณ , `processCpuRatio` ๋Š” ํ”„๋กœ์„ธ์Šค ์ „์ฒด๋ฅผ ์žฌ์ง€๋งŒ **์–ธ์ œ ์–ผ๋งˆ๋‚˜ ๋ฉˆ์ท„๋‚˜**๋ฅผ ๋งํ•˜์ง€\n * ๋ชปํ•œ๋‹ค. ๋ฐ–์—์„œ HTTP ์ง€์—ฐ์„ ์žฌ ๋ณด๋‹ˆ ๊ฐ™์€ ์š”์ฒญ์ด 44ms ์™€ 5.8์ดˆ๋กœ ๊ฐˆ๋ผ์กŒ๋Š”๋ฐ, ๊ทธ 5.8์ดˆ๊ฐ€ ํŠธ์œˆ ๋•Œ๋ฌธ์ธ์ง€\n * webpack ์žฌ๋นŒ๋“œ ๋•Œ๋ฌธ์ธ์ง€ ๋‚จ์˜ ์žฌ๊ธฐ๋™ ๋•Œ๋ฌธ์ธ์ง€ **๊ฐ€๋ฆด ๊ทผ๊ฑฐ๊ฐ€ ์—†์—ˆ๋‹ค.**\n *\n * ๊ทผ๊ฑฐ ์—†์ด ์›์ธ์„ ๊ณ ๋ฅด๋ฉด ์—‰๋šฑํ•œ ๊ณณ์„ ๊ณ ์นœ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฃจํ”„๊ฐ€ ์‹ค์ œ๋กœ ์–ผ๋งˆ๋‚˜ ๋ง‰ํ˜”๋Š”์ง€๋ฅผ ์žฐ๋‹ค.\n *\n * โ”€โ”€ ์–ด๋–ป๊ฒŒ ์žฌ๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์ผ์ • ๊ฐ„๊ฒฉ์œผ๋กœ ๊นจ์–ด๋‚˜๋Š” ํƒ€์ด๋จธ๋ฅผ ๋‘๊ณ , **์˜ˆ์ • ์‹œ๊ฐ๊ณผ ์‹ค์ œ ์‹œ๊ฐ์˜ ์ฐจ์ด**๋ฅผ ๋ณธ๋‹ค. ๋ฃจํ”„๊ฐ€ ๋ง‰ํ˜€ ์žˆ์—ˆ์œผ๋ฉด\n * ๊ทธ๋งŒํผ ๋Šฆ๊ฒŒ ๊นจ์–ด๋‚œ๋‹ค. ์žฌ๋Š” ๋น„์šฉ์€ ๊ทธ ์ฐจ์ด ๊ณ„์‚ฐ ํ•˜๋‚˜๋ฟ์ด๋‹ค(์ฐฝ๋งˆ๋‹ค ๊ฐ’ ๋‹ค์„ฏ).\n *\n * ์ด ๊ฐ’์€ **์›์ธ์„ ๋งํ•˜์ง€ ์•Š๋Š”๋‹ค** โ€” ใ€Œ200ms ์ด์ƒ ๋ง‰ํžŒ ์ผ์ด ์ด ์ฐฝ์—์„œ ์„ธ ๋ฒˆ, ๊ฐ€์žฅ ๊ธด ๊ฒƒ์€ 4.6์ดˆใ€๊นŒ์ง€๊ฐ€\n * ์‚ฌ์‹ค์ด๋‹ค. ์›์ธ์€ ๊ทธ ์‹œ๊ฐ์˜ ํŠธ์œˆ ๋ถ€ํ•˜(`twinLoad`)์™€ ํ”„๋กœ์„ธ์Šค CPU ์™€ ๋‚˜๋ž€ํžˆ ๋†“๊ณ  ์‚ฌ๋žŒ์ด ๊ฐ€๋ฆฐ๋‹ค.\n * ์žฌ์ง€ ์•Š์€ ๊ฒƒ์„ 0 ์œผ๋กœ ์ ์ง€ ์•Š๋Š”๋‹ค โ€” ํ•œ ๋ฒˆ๋„ ๊นจ์–ด๋‚˜์ง€ ์•Š์•˜์œผ๋ฉด `null` ์ด๋‹ค.\n */\n\n/** ํ‘œ๋ณธ ๊ฐ„๊ฒฉ(ms) โ€” ์ด˜์ด˜ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ธด ์ •์ฒด๋ฅผ ๋†“์น˜์ง€ ์•Š๋Š” ์ •๋„๋ฉด ๋œ๋‹ค. */\nexport const LAG_SAMPLE_MS = 500\n/** ์ด ๊ฐ’์„ ๋„˜๋Š” ์ง€์ฒด๋งŒ ใ€Œ์ •์ฒดใ€๋กœ ์„ผ๋‹ค(ms). ์‚ฌ๋žŒ์ด ํ™”๋ฉด์—์„œ ๋А๋ผ๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ํฌ๊ธฐ. */\nexport const LAG_STALL_MS = 200\n/** ์ฐฝ ๊ธธ์ด(ms) โ€” `twinLoad` ์˜ ์ฐฝ๊ณผ ๊ฐ™์€ ํฌ๊ธฐ๋กœ ๋‘์–ด ๋‚˜๋ž€ํžˆ ์ฝ๋Š”๋‹ค. */\nexport const LAG_WINDOW_MS = 10_000\n\nexport interface LoopLagWindow {\n /** ์ด ์ฐฝ์—์„œ ๊ฐ€์žฅ ๊ธธ๊ฒŒ ๋ง‰ํžŒ ์‹œ๊ฐ„(ms). */\n maxMs: number\n /** ์ •์ฒด(๋ฌธํ„ฑ ์ดˆ๊ณผ) ํšŸ์ˆ˜. */\n stalls: number\n /** ํ‘œ๋ณธ ์ˆ˜ โ€” ๋ถ„๋ชจ๋‹ค. */\n samples: number\n /** ์ง€์ฒด ํ•ฉ(ms) โ€” ํ‰๊ท ์€ ์ฝ๋Š” ์ชฝ์—์„œ ๋‚ธ๋‹ค. */\n totalMs: number\n /** ์ฐฝ์ด ์—ด๋ฆฐ ์‹œ๊ฐ. */\n startMs: number\n}\n\nexport interface LoopLagView {\n /** ๋งˆ์ง€๋ง‰์œผ๋กœ ๋‹ซํžŒ ์ฐฝ โ€” ใ€Œ์ง€๊ธˆ ์–ด๋–ค๊ฐ€ใ€. ์•„์ง ํ•œ ์ฐฝ๋„ ์•ˆ ์ง€๋‚ฌ์œผ๋ฉด null. */\n recent: (LoopLagWindow & { endMs: number }) | null\n /** ๊ธฐ๋™ ์ดํ›„ ๋ˆ„์ . */\n total: LoopLagWindow\n /** ๊ธฐ๋™ ์ดํ›„ ๊ฐ€์žฅ ๊ธธ๊ฒŒ ๋ง‰ํžŒ ์‹œ๊ฐ(ms, epoch) โ€” ์–ธ์ œ์˜€๋Š”์ง€๊ฐ€ ์›์ธ์„ ๊ฐ€๋ฆฌ๋Š” ๋ฐ ์“ฐ์ธ๋‹ค. */\n worstAtMs: number | null\n /** ํ‘œ๋ณธ ๊ฐ„๊ฒฉ โ€” ์ฝ๋Š” ์ชฝ์ด ์ด ๊ฐ’๋ณด๋‹ค ์งง์€ ์ •์ฒด๋Š” ๋ชป ๋ณธ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„์•ผ ํ•œ๋‹ค. */\n sampleMs: number\n /** ์ •์ฒด๋กœ ์„ธ๋Š” ๋ฌธํ„ฑ. */\n stallMs: number\n}\n\nconst emptyWindow = (startMs: number): LoopLagWindow => ({ maxMs: 0, stalls: 0, samples: 0, totalMs: 0, startMs })\n\nexport class LoopLagSampler {\n private window: LoopLagWindow\n private closed: (LoopLagWindow & { endMs: number }) | null = null\n private total: LoopLagWindow\n private worstAtMs: number | null = null\n private timer: any\n private expectedMs: number\n\n private sampleMs: number\n private stallMs: number\n private windowMs: number\n private now: () => number\n\n /* ์ƒ์„ฑ์ž ํŒŒ๋ผ๋ฏธํ„ฐ ํ”„๋กœํผํ‹ฐ(`private x = โ€ฆ`)๋Š” ์“ฐ์ง€ ์•Š๋Š”๋‹ค โ€” ์‹œํ—˜์ด ์†Œ์Šค๋ฅผ ๊ทธ๋Œ€๋กœ ์‹คํ–‰ํ•˜๋Š”๋ฐ\n (ํƒ€์ž… ์ œ๊ฑฐ ์‹คํ–‰ ๋ฐฉ์‹) ๊ทธ ๋ฌธ๋ฒ•์€ ์ง€์›๋˜์ง€ ์•Š์•„ ํŒŒ์ผ ์ „์ฒด๊ฐ€ ์—ด๋ฆฌ์ง€ ์•Š๋Š”๋‹ค. */\n constructor(sampleMs = LAG_SAMPLE_MS, stallMs = LAG_STALL_MS, windowMs = LAG_WINDOW_MS, now: () => number = Date.now) {\n this.sampleMs = sampleMs\n this.stallMs = stallMs\n this.windowMs = windowMs\n this.now = now\n const t = this.now()\n this.window = emptyWindow(t)\n this.total = emptyWindow(t)\n this.expectedMs = t + sampleMs\n }\n\n /** ํ‘œ๋ณธ์„ ํ•˜๋‚˜ ๋„ฃ๋Š”๋‹ค โ€” ํƒ€์ด๋จธ๊ฐ€ ๋ถ€๋ฅด๊ณ , ์‹œํ—˜์€ ์ง์ ‘ ๋ถ€๋ฅธ๋‹ค(์‹œ๊ณ„๋ฅผ ๋ฐ€์–ด ๋„ฃ์–ด ์žฐ๋‹ค). */\n sample(atMs = this.now()): number {\n const lag = Math.max(0, atMs - this.expectedMs)\n this.expectedMs = atMs + this.sampleMs\n for (const w of [this.window, this.total]) {\n w.samples += 1\n w.totalMs += lag\n if (lag > this.stallMs) w.stalls += 1\n if (lag > w.maxMs) w.maxMs = lag\n }\n if (lag >= this.total.maxMs && lag > this.stallMs) this.worstAtMs = atMs\n if (atMs - this.window.startMs >= this.windowMs) {\n this.closed = { ...this.window, endMs: atMs }\n this.window = emptyWindow(atMs)\n }\n return lag\n }\n\n /** ๊ณ„๊ธฐํŒ์ด ์ฝ๋Š” ๊ฐ’. **ํ•œ ์ฐฝ๋„ ๋‹ซํžˆ์ง€ ์•Š์•˜์œผ๋ฉด `recent` ๋Š” null** โ€” ์ฑ„์šฐ๋Š” ์ค‘์ธ ์ฐฝ์€ ๊ณผ์†Œ ์ง‘๊ณ„๋‹ค. */\n view(): LoopLagView {\n return { recent: this.closed, total: this.total, worstAtMs: this.worstAtMs, sampleMs: this.sampleMs, stallMs: this.stallMs }\n }\n\n /** ํ‘œ๋ณธ ํƒ€์ด๋จธ ๊ธฐ๋™(1ํšŒ) โ€” ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒ๋ฅผ ๋ง‰์ง€ ์•Š๋Š”๋‹ค. */\n start(): void {\n if (this.timer) return\n this.timer = setInterval(() => this.sample(), this.sampleMs)\n if (typeof this.timer?.unref === 'function') this.timer.unref()\n }\n\n stop(): void {\n if (!this.timer) return\n clearInterval(this.timer)\n this.timer = undefined\n }\n}\n\n/** ํ”„๋กœ์„ธ์Šค ํ•˜๋‚˜์˜ ๋ฃจํ”„๋ฅผ ์žฌ๋Š” ๊ฒƒ์ด๋ฏ€๋กœ ํ‘œ๋ณธ๊ธฐ๋„ ํ•˜๋‚˜๋‹ค. */\nexport const loopLag = new LoopLagSampler()\n"]}
@@ -0,0 +1,108 @@
1
+ /** ์ปค๋„ ์Šค๋ƒ…์ƒท์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์ฝ๋Š” ๊ฒƒ๋งŒ. ๋‚˜๋จธ์ง€ ํ•„๋“œ๋Š” ์•Œ ํ•„์š”๊ฐ€ ์—†๋‹ค. */
2
+ export interface ModelGapSource {
3
+ locations?: {
4
+ id?: string;
5
+ origin?: string;
6
+ }[];
7
+ equipment?: {
8
+ id?: string;
9
+ origin?: string;
10
+ }[];
11
+ persons?: {
12
+ id?: string;
13
+ origin?: string;
14
+ }[];
15
+ /** ์ปค๋„์ด ๋‹ด์„ ์ค„ ๋ชฐ๋ผ ์„ธ์–ด ๋‘” ์‚ฌ๊ฑด โ€” ์ข…๋ฅ˜๋ณ„ ๊ฐœ์ˆ˜์™€ ์ฒ˜์Œยท๋งˆ์ง€๋ง‰ ์‹œ๊ฐ. */
16
+ unhandled?: {
17
+ eventType: string;
18
+ count: number;
19
+ firstAtMs?: number;
20
+ lastAtMs?: number;
21
+ }[];
22
+ /**
23
+ * EMS ์ƒํƒœ โ€” **`energy` ์•ˆ์— ์žˆ๋‹ค.**
24
+ *
25
+ * `unknownEquipment` ๋ฅผ ๋ฃจํŠธ์—์„œ ์ฝ๊ณ  ์žˆ์—ˆ๋‹ค(2026-08-20์— ์žก์Œ). ์ปค๋„์€ ๊ทธ๊ฒƒ์„ `EnergyState` ์•ˆ์—
26
+ * ๋‹ด์œผ๋ฏ€๋กœ, ๋ฃจํŠธ์—์„œ ์ฝ์œผ๋ฉด **์˜์›ํžˆ `null`** ์ด๋‹ค โ€” ์˜ค๋ฅ˜๋„ ์—†์ด ใ€Œ์—๋„ˆ์ง€ ํŠธ์œˆ์ด ์•„๋‹ˆ๋‹คใ€๋กœ ์ฝํžŒ๋‹ค.
27
+ * ๋‚˜๋งŒ ์ฝ๋Š” ํ•„๋“œ๋ฅผ ์ž˜๋ชป๋œ ๊ฒฝ๋กœ์—์„œ ์ฝ์œผ๋ฉด ์ด๋ ‡๊ฒŒ ์กฐ์šฉํžˆ ์‚ฌ๋ผ์ง„๋‹ค.
28
+ *
29
+ * ๊ณ„๋Ÿ‰ ์ง€์ ์˜ `origin` ์€ **์—†์„ ์ˆ˜ ์žˆ๋‹ค**(์˜› ์Šค๋ƒ…์ƒท์—์„œ ์ด์–ด๋ฐ›์€ ์ง€์ ). ๊ทธ๋•Œ๋Š” ใ€Œ์„ ์–ธ๋˜์—ˆ๋‹คใ€๊ฐ€
30
+ * ์•„๋‹ˆ๋ผ **๋ชจ๋ฅธ๋‹ค**๋‹ค.
31
+ */
32
+ energy?: {
33
+ points?: {
34
+ id?: string;
35
+ origin?: string;
36
+ }[];
37
+ /** ๋ชจ๋ธ์ด ๋ชจ๋ฅด๋Š” ์„ค๋น„๊ฐ€ ์—๋„ˆ์ง€ ์ƒํƒœ๋ฅผ ๋ณด๋‚ด ์˜จ ํšŸ์ˆ˜. 0 ์ด๋ฉด ์ปค๋„์ด ์ด ์นธ์„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. */
38
+ unknownEquipment?: number;
39
+ };
40
+ }
41
+ /**
42
+ * ํ™”๋ฉด์— ๋‚ด๋Š” id ์ˆ˜ ์ƒํ•œ.
43
+ *
44
+ * ์˜คํƒ€ ํ•˜๋‚˜๋ฅผ ์ฐพ๋Š” ๋ฐ ์Šค๋ฌด ๊ฐœ๋ฉด ์ถฉ๋ถ„ํ•˜๊ณ , ์›์ฒœ์ด ์ˆ˜์ฒœ ๊ฐœ๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒฝ์šฐ(๋ชจ๋ธ์„ ์•„์˜ˆ ์•ˆ ๋งž์ถ˜ ๊ฒฝ์šฐ)์—
45
+ * ๋ชฉ๋ก์œผ๋กœ ํ™”๋ฉด์„ ์ฑ„์šธ ์ด์œ ๊ฐ€ ์—†๋‹ค. **๋„˜์นœ ์ˆ˜๋Š” ํ•จ๊ป˜ ๋‚ธ๋‹ค** โ€” ์กฐ์šฉํžˆ ์ž๋ฅด์ง€ ์•Š๋Š”๋‹ค.
46
+ */
47
+ export declare const GAP_ID_LIMIT = 20;
48
+ export interface ModelGapAxis {
49
+ /** ๊ด€์ธก์œผ๋กœ๋งŒ ์•Œ๊ฒŒ ๋œ id ์ˆ˜. */
50
+ count: number;
51
+ /** ๊ทธ์ค‘ ํ™”๋ฉด์— ์‹ฃ๋Š” ๊ฒƒ(์ตœ๋Œ€ `GAP_ID_LIMIT`). */
52
+ ids: string[];
53
+ /** ์ƒํ•œ์—์„œ ๋ฐ€๋ ค๋‚œ ์ˆ˜. 0 ์ด๋ฉด ์ „๋ถ€ ์‹ค์—ˆ๋‹ค. */
54
+ more: number;
55
+ /**
56
+ * ์ถœ์ฒ˜๋ฅผ **๋ชจ๋ฅด๋Š”** ์ˆ˜ โ€” ํ‘œ์‹œ๊ฐ€ ์—†๋Š” ํ•ญ๋ชฉ.
57
+ *
58
+ * ใ€Œ์„ ์–ธ๋˜์—ˆ๋‹คใ€๋กœ ์„ธ์ง€ ์•Š๋Š”๋‹ค. ๊ณ„๋Ÿ‰๊ธฐ๋Š” ์ด ํ‘œ์‹œ๊ฐ€ ๋Šฆ๊ฒŒ ์ƒ๊ฒผ์œผ๋ฏ€๋กœ ์˜› ์Šค๋ƒ…์ƒท์—์„œ ์ด์–ด๋ฐ›์€ ์ง€์ ์—๋Š”
59
+ * ์นธ์ด ์—†๋‹ค(`undefined`). ๊ทธ๊ฒƒ์„ ๋งˆ์Šคํ„ฐ๋กœ ์„ธ๋ฉด ์˜คํƒ€๋ฅผ ๋†“์น˜๊ณ , ๊ด€์ธก์œผ๋กœ ์„ธ๋ฉด ์ •์ƒ์„ ๋ฌธ์ œ๋กœ ๋งŒ๋“ ๋‹ค.
60
+ * ๋‘˜ ๋‹ค ํ‹€๋ฆฌ๋ฏ€๋กœ **๋ชจ๋ฅธ๋‹ค๊ณ  ์„ผ๋‹ค.**
61
+ */
62
+ unknown: number;
63
+ }
64
+ export interface ModelGapView {
65
+ locations: ModelGapAxis;
66
+ equipment: ModelGapAxis;
67
+ persons: ModelGapAxis;
68
+ /**
69
+ * EMS ๊ณ„๋Ÿ‰ ์ง€์ .
70
+ *
71
+ * โ”€โ”€ ์ด ์ถ•์ด ๊ฐ€์žฅ ๋ฌด๊ฒ๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
72
+ * ๋ชจ๋ฅด๋Š” `meterId` ๋Š” ์กฐ์šฉํžˆ ์ƒˆ ๊ณ„๋Ÿ‰๊ธฐ๊ฐ€ ๋˜๊ณ  ๊ทธ kW ๊ฐ€ ๊ทธ ํ˜„์žฅ์˜ **์ˆ˜์š” ๊ตฌ๊ฐ„ยทํ”ผํฌยท์š”๊ธˆ ํŒ์ •**์—
73
+ * ๋”ํ•ด์ง„๋‹ค. ์˜คํƒ€ ํ•˜๋‚˜๋ฉด ์ง„์งœ ๊ณ„๋Ÿ‰๊ธฐ๋Š” ๋ฉˆ์ถ”๊ณ  ์œ ๋ น์ด ๋ˆ„์ ๋œ๋‹ค โ€” ์ˆซ์ž๋Š” ๊ทธ๋Ÿด๋“ฏํ•˜๊ณ  ํ‹€๋ฆฐ๋‹ค. ์ž๋ฆฌ ์˜คํƒ€๋Š”
74
+ * ์Šคํ‚ค๋งคํ‹ฑ์ด ๋น„๋Š” ๊ฒƒ์œผ๋กœ ๋“œ๋Ÿฌ๋‚˜์ง€๋งŒ, ์ด๊ฑด ๊ทธ๋Ÿด๋“ฏํ•œ ์ˆซ์ž๋กœ ๋‚˜์˜จ๋‹ค.
75
+ *
76
+ * ์ปค๋„์ด `origin` ์„ **ํ‘œ๋ณธ๋งˆ๋‹ค ๋‹ค์‹œ ๋งž์ถ˜๋‹ค** โ€” ์„ ์–ธ์˜ ์ •๋ณธ์€ ๋ชจ๋ธ์ด๊ณ  ๋ชจ๋ธ์€ ์ฑ„ํƒ์œผ๋กœ ๋Š˜์–ด๋‚˜๋ฏ€๋กœ,
77
+ * ํ•œ ๋ฒˆ ์ฐ๊ณ  ๋‘๋ฉด ๋‚˜์ค‘์— ์„ ์–ธ๋œ ๊ณ„๋Ÿ‰๊ธฐ๊ฐ€ ์˜์›ํžˆ `observed` ๋กœ ๋‚จ๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ์ด ๊ฐ’์€ ใ€Œ์ง€๊ธˆ ๋ชจ๋ธ์—
78
+ * ์žˆ๋Š”๊ฐ€ใ€์˜ ๋‹ต์ด๊ณ , ใ€Œํ•œ ๋ฒˆ ์˜คํƒ€์˜€๋‹คใ€์˜ ๋‹ต์ด ์•„๋‹ˆ๋‹ค.
79
+ */
80
+ meters: ModelGapAxis;
81
+ /** ์„ธ ์ถ•์˜ ํ•ฉ โ€” ํ™”๋ฉด์ด ใ€Œ์žˆ๋‚˜ ์—†๋‚˜ใ€๋ฅผ ํ•œ ๋ฒˆ์— ๋ฌป๊ธฐ ์œ„ํ•œ ๊ฐ’. */
82
+ total: number;
83
+ /** ์ปค๋„์ด ๋‹ด์„ ์ค„ ๋ชจ๋ฅธ ์‚ฌ๊ฑด๋“ค(์ข…๋ฅ˜๋ณ„). ์ฐธ์กฐ ๋ฌธ์ œ์™€ ๋‹ค๋ฅธ ์‚ฌ์‹ค์ด๋ฏ€๋กœ ๋”ฐ๋กœ ๋‚ธ๋‹ค. */
84
+ unhandled: {
85
+ eventType: string;
86
+ count: number;
87
+ lastAt: string | null;
88
+ }[];
89
+ /** EMS: ๋ชจ๋ธ์ด ๋ชจ๋ฅด๋Š” ์„ค๋น„์˜ ์—๋„ˆ์ง€ ๋ณด๊ณ  ํšŸ์ˆ˜. ์—†์œผ๋ฉด `null`(0 ๊ณผ ๊ตฌ๋ณ„ํ•œ๋‹ค). */
90
+ unknownEquipmentReports: number | null;
91
+ /**
92
+ * ์•„์ง ๋ฎ์ง€ ๋ชปํ•˜๋Š” ์ถ• โ€” **๋ชจ๋ฅด๋Š” ๊ฒƒ์„ ๋ชจ๋ฅธ๋‹ค๊ณ  ๋งํ•œ๋‹ค.**
93
+ *
94
+ * ๊ณ„๋Ÿ‰๊ธฐ๋Š” ์ปค๋„ 0.7.39 ๋ถ€ํ„ฐ ๋ฎ์ธ๋‹ค(๊ทธ ์ „์—๋Š” `origin` ํ‘œ์‹œ๊ฐ€ ์—†์–ด ์˜คํƒ€๋ฅผ ์ฐพ์•„ ์ค„ ์ˆ˜ ์—†์—ˆ๋‹ค).
95
+ * ๋น„์–ด ์žˆ๋Š” ๊ฒƒ์ด ์ •์ƒ์ด๊ณ , ์ƒˆ ์ถ•์ด ํ‘œ์‹œ ์—†์ด ๋“ค์–ด์˜ค๋ฉด ์—ฌ๊ธฐ์— ์ด๋ฆ„์„ ๋„ฃ๋Š”๋‹ค โ€” ํ™”๋ฉด์ด ใ€Œ๋‹ค ์ฐพ์•„
96
+ * ์ค€๋‹คใ€๊ณ  ๋งํ•˜์ง€ ์•Š๊ฒŒ.
97
+ */
98
+ notCovered: string[];
99
+ }
100
+ /** ๊ณ„๋Ÿ‰๊ธฐ ์ถ•์ด ์•„์ง ๋ฎ์ด์ง€ ์•Š๋Š” ์ด์œ  โ€” ํ™”๋ฉด์ด ๊ทธ๋Œ€๋กœ ๋งํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ด๋ฆ„์„ ์—ฌ๊ธฐ ๋‘”๋‹ค. */
101
+ export declare const NOT_COVERED_METERS = "meters";
102
+ /**
103
+ * ์Šค๋ƒ…์ƒท โ†’ ๋ชจ๋ธ ๊ฐญ.
104
+ *
105
+ * ์Šค๋ƒ…์ƒท์ด ์—†์œผ๋ฉด `null` ์ด๋‹ค โ€” **0 ์ด ์•„๋‹ˆ๋‹ค.** ํŠธ์œˆ์ด ๋Œ์ง€ ์•Š์œผ๋ฉด ๋น„๊ตํ•  ์ƒ๋Œ€๊ฐ€ ์—†๊ณ , ใ€Œ์—†๋‹คใ€์™€
106
+ * ใ€Œ์„ธ์–ด ๋ณด์ง€ ๋ชปํ–ˆ๋‹คใ€๋Š” ๋‹ค๋ฅธ ์‚ฌ์‹ค์ด๋‹ค(๋ชจ๋ธ ์ธ์ŠคํŽ™์…˜์ด ๊ฐ™์€ ๊ทœ์œจ์„ ์“ด๋‹ค).
107
+ */
108
+ export declare function modelGapOf(snapshot: ModelGapSource | null | undefined): ModelGapView | null;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ /*
3
+ * **์›๋ณธ์ด ๋งํ•œ ์  ์—†๋Š” ๊ฒƒ** โ€” ๋ฏธํ•ด๊ฒฐ ์ฐธ์กฐ๋ฅผ ์„ธ๋Š” ํ•œ ์ž๋ฆฌ. ์ˆœ์ˆ˜(import ์—†์Œ).
4
+ *
5
+ * โ”€โ”€ ๋ฌด์—‡์„ ๋‹ตํ•˜๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
6
+ * ์›์ฒœ์ด ์šฐ๋ฆฌ ๋ชจ๋ธ์— ์—†๋Š” id ๋ฅผ ๋ณด๋‚ด๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋‚˜. ์œ ์ž… ๋ฌธ(`ingestCanonicalRecords`)์€ **๊ฑฐ๋ถ€ํ•˜์ง€
7
+ * ์•Š๋Š”๋‹ค** โ€” ์‹ค์ธก์œผ๋กœ ํ™•์ธํ–ˆ๋‹ค(2026-08-20):
8
+ *
9
+ * ๋ชจ๋ฅด๋Š” ๋กœ์ผ€์ด์…˜ ใ€Œ์˜คํƒ€-99ใ€ โ†’ ํ†ต๊ณผ
10
+ * ๋ชจ๋ฅด๋Š” bizStep ใ€ŒPUTAWAY_X17ใ€ โ†’ ํ†ต๊ณผ
11
+ * ๋ชจ๋ฅด๋Š” ๊ณ„๋Ÿ‰๊ธฐ ใ€ŒMMXU-์˜คํƒ€-99ใ€ โ†’ ํ†ต๊ณผ
12
+ *
13
+ * ๊ฑฐ๋ถ€ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์˜ณ๋‹ค. ์›์ฒœ์ด ๋ชจ๋ธ๋ณด๋‹ค ๋จผ์ € ์ƒˆ ๋กœ์ผ€์ด์…˜์„ ๋งํ•˜๋Š” ๊ฒƒ์€ ์ •์ƒ์ด๊ณ (๊ตฌ์กฐ ๊ฐฑ์‹ ์€ ๋Šฆ๊ฒŒ ์˜จ๋‹ค),
14
+ * ๊ฑฐ๋ถ€ํ•˜๋ฉด ๊ทธ ์„ ํ–‰ ๊ณ„์ธก์„ ์žƒ๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ์ปค๋„์€ **ํก์ˆ˜ํ•˜๊ณ  ํ‘œ์‹œํ•œ๋‹ค** โ€” ๋งˆ์Šคํ„ฐ์— ์—†๋˜ ๋กœ์ผ€์ด์…˜์€
15
+ * `origin: 'observed'` ๋กœ ์Šน๊ฒฉ๋˜์–ด ์Šค๋ƒ…์ƒท์— ์‹ค๋ฆฐ๋‹ค(`ObservedReducer.touchLocation`).
16
+ *
17
+ * โ”€โ”€ ์™œ ์ด ํŒŒ์ผ์ด ์žˆ๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
18
+ * ๊ทธ ํ‘œ์‹œ๋ฅผ ์ฝ๋Š” ๊ณณ์ด **๋ชจ๋ธ ์ธ์ŠคํŽ™์…˜ ํ™”๋ฉด ํ•˜๋‚˜**์˜€๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด ์‚ฌ์‹ค์„ ํ•„์š”๋กœ ํ•˜๋Š” ์‚ฌ๋žŒ์€ ใ€Œ์ด ํŠธ์œˆ์ด
19
+ * ํ˜„์žฅ๊ณผ ๋งž์ถฐ์ง€๊ณ  ์žˆ๋‚˜ใ€๋ฅผ ๋ณด๋Š” ์‚ฌ๋žŒ์ด๋‹ค โ€” ์›์ฒœ์ด ์šฐ๋ฆฌ๊ฐ€ ๋ชจ๋ฅด๋Š” ๋กœ์ผ€์ด์…˜๋งŒ ๋ณด๋‚ด๊ณ  ์žˆ์œผ๋ฉด ํŠธ์œˆ์€ ๋„๋Š”๋ฐ
20
+ * ์Šคํ‚ค๋งคํ‹ฑ์€ ๋น„์–ด ์žˆ๊ณ , ๊ทธ๊ฒƒ์ด ์šฐ๋ฆฌ๊ฐ€ ใ€Œ๋นˆ ๊ณต์žฅใ€์ด๋ผ ๋ถˆ๋Ÿฌ ์˜จ ์ƒํƒœ๋‹ค.
21
+ *
22
+ * ๋„์ถœ์„ ๋‘ ๊ณณ์— ์ ์œผ๋ฉด ๋‘ ํ™”๋ฉด์ด ๋‹ค๋ฅธ ์ˆ˜๋ฅผ ๋งํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ์—ฌ๊ธฐ ํ•œ ๋ฒŒ๋งŒ ๋‘”๋‹ค.
23
+ *
24
+ * โ”€โ”€ ํŒ์ •์„ ๋ฐ”๊พธ์ง€ ์•Š๋Š”๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
25
+ * ๋™๊ธฐํ™” ํŒ์ •(`syncVerdictOf`)์€ **ํ”ผ๋“œ**๋ฅผ ๋งํ•œ๋‹ค: ์˜ค๊ณ  ์žˆ๋‚˜, ํ†ต๊ณผํ•˜๋‚˜. ์ด ๊ฐญ์€ **๋ชจ๋ธ**์„ ๋งํ•œ๋‹ค:
26
+ * ์›์ฒœ์ด ์•„๋Š” ๊ฒƒ์„ ์šฐ๋ฆฌ๊ฐ€ ์„ ์–ธํ–ˆ๋‚˜. ๋‘˜์„ ํ•œ ํŒ์ •์— ์„ž์œผ๋ฉด ใ€Œ์œ ์ž…์€ ์ •์ƒ์ธ๋ฐ ๋ชจ๋ธ์ด ๋’ค์ฒ˜์กŒ๋‹คใ€์™€
27
+ * ใ€Œ์œ ์ž…์ด ๋ง‰ํ˜”๋‹คใ€๊ฐ€ ๊ฐ™์€ ์ƒ‰์œผ๋กœ ๋ณด์ด๊ณ , ์ฒ˜๋ฐฉ์ด ์™„์ „ํžˆ ๋‹ค๋ฅด๋‹ค.
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.NOT_COVERED_METERS = exports.GAP_ID_LIMIT = void 0;
31
+ exports.modelGapOf = modelGapOf;
32
+ /**
33
+ * ํ™”๋ฉด์— ๋‚ด๋Š” id ์ˆ˜ ์ƒํ•œ.
34
+ *
35
+ * ์˜คํƒ€ ํ•˜๋‚˜๋ฅผ ์ฐพ๋Š” ๋ฐ ์Šค๋ฌด ๊ฐœ๋ฉด ์ถฉ๋ถ„ํ•˜๊ณ , ์›์ฒœ์ด ์ˆ˜์ฒœ ๊ฐœ๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒฝ์šฐ(๋ชจ๋ธ์„ ์•„์˜ˆ ์•ˆ ๋งž์ถ˜ ๊ฒฝ์šฐ)์—
36
+ * ๋ชฉ๋ก์œผ๋กœ ํ™”๋ฉด์„ ์ฑ„์šธ ์ด์œ ๊ฐ€ ์—†๋‹ค. **๋„˜์นœ ์ˆ˜๋Š” ํ•จ๊ป˜ ๋‚ธ๋‹ค** โ€” ์กฐ์šฉํžˆ ์ž๋ฅด์ง€ ์•Š๋Š”๋‹ค.
37
+ */
38
+ exports.GAP_ID_LIMIT = 20;
39
+ /** ๊ณ„๋Ÿ‰๊ธฐ ์ถ•์ด ์•„์ง ๋ฎ์ด์ง€ ์•Š๋Š” ์ด์œ  โ€” ํ™”๋ฉด์ด ๊ทธ๋Œ€๋กœ ๋งํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ด๋ฆ„์„ ์—ฌ๊ธฐ ๋‘”๋‹ค. */
40
+ exports.NOT_COVERED_METERS = 'meters';
41
+ function axisOf(rows) {
42
+ const ids = [];
43
+ let count = 0;
44
+ let unknown = 0;
45
+ for (const r of rows ?? []) {
46
+ if (r?.origin === 'observed') {
47
+ count++;
48
+ if (ids.length < exports.GAP_ID_LIMIT)
49
+ ids.push(String(r.id ?? ''));
50
+ }
51
+ else if (r?.origin !== 'master') {
52
+ /* ํ‘œ์‹œ๊ฐ€ ์—†๋‹ค โ€” ๋งˆ์Šคํ„ฐ๋กœ๋„ ๊ด€์ธก์œผ๋กœ๋„ ์„ธ์ง€ ์•Š๋Š”๋‹ค. ๋ชจ๋ฅด๋Š” ๊ฒƒ์€ ๋ชจ๋ฅธ๋‹ค๊ณ  ์„ผ๋‹ค. */
53
+ unknown++;
54
+ }
55
+ }
56
+ return { count, ids, more: Math.max(0, count - ids.length), unknown };
57
+ }
58
+ /**
59
+ * ์Šค๋ƒ…์ƒท โ†’ ๋ชจ๋ธ ๊ฐญ.
60
+ *
61
+ * ์Šค๋ƒ…์ƒท์ด ์—†์œผ๋ฉด `null` ์ด๋‹ค โ€” **0 ์ด ์•„๋‹ˆ๋‹ค.** ํŠธ์œˆ์ด ๋Œ์ง€ ์•Š์œผ๋ฉด ๋น„๊ตํ•  ์ƒ๋Œ€๊ฐ€ ์—†๊ณ , ใ€Œ์—†๋‹คใ€์™€
62
+ * ใ€Œ์„ธ์–ด ๋ณด์ง€ ๋ชปํ–ˆ๋‹คใ€๋Š” ๋‹ค๋ฅธ ์‚ฌ์‹ค์ด๋‹ค(๋ชจ๋ธ ์ธ์ŠคํŽ™์…˜์ด ๊ฐ™์€ ๊ทœ์œจ์„ ์“ด๋‹ค).
63
+ */
64
+ function modelGapOf(snapshot) {
65
+ if (!snapshot)
66
+ return null;
67
+ const locations = axisOf(snapshot.locations);
68
+ const equipment = axisOf(snapshot.equipment);
69
+ const persons = axisOf(snapshot.persons);
70
+ const meters = axisOf(snapshot.energy?.points);
71
+ return {
72
+ locations,
73
+ equipment,
74
+ persons,
75
+ meters,
76
+ total: locations.count + equipment.count + persons.count + meters.count,
77
+ unhandled: (snapshot.unhandled ?? []).map(u => ({
78
+ eventType: u.eventType,
79
+ count: u.count,
80
+ /* ๋งˆ์ง€๋ง‰ ์‹œ๊ฐ์ด ๋ฉˆ์ถ˜ ์ข…๋ฅ˜๋Š” ์ด๋ฏธ ๊ณ ์ณ์ง„ ๊ฒƒ์ด๋‹ค. ์—†์œผ๋ฉด ์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค. */
81
+ lastAt: Number.isFinite(u.lastAtMs) ? new Date(u.lastAtMs).toISOString() : null
82
+ })),
83
+ /*
84
+ * ์ปค๋„์€ 0 ์ด๋ฉด ์ด ์นธ์„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ใ€Œ์—†์Œใ€์€ ๋‘ ๋œป์ด๋‹ค โ€” ์—๋„ˆ์ง€ ํŠธ์œˆ์ด ์•„๋‹ˆ๊ฑฐ๋‚˜, ์„ธ์—ˆ๊ณ 
85
+ * 0 ์ด์—ˆ๋‹ค. ๋‘˜์„ ๊ฐ€๋ฅด๋ ค๋ฉด `energy` ์ž์ฒด๊ฐ€ ์žˆ๋Š”์ง€๋ฅผ ๋ณธ๋‹ค: ์žˆ์œผ๋ฉด ์„ธ์—ˆ๊ณ  0 ์ด๋‹ค.
86
+ */
87
+ unknownEquipmentReports: typeof snapshot.energy?.unknownEquipment === 'number' ? snapshot.energy.unknownEquipment : snapshot.energy ? 0 : null,
88
+ /*
89
+ * ์ด์ œ ๊ณ„๋Ÿ‰๊ธฐ๋„ ๋ฎ๋Š”๋‹ค(์ปค๋„ 0.7.39 ๊ฐ€ `MeterPointState.origin` ์„ ๋‚ธ๋‹ค). ๋ฎ์ง€ ๋ชปํ•˜๋Š” ์ถ•์ด ์ƒ๊ธฐ๋ฉด
90
+ * ๋‹ค์‹œ ์—ฌ๊ธฐ์— ์ด๋ฆ„์„ ๋„ฃ๋Š”๋‹ค โ€” ํ™”๋ฉด์ด ใ€Œ๋‹ค ์ฐพ์•„ ์ค€๋‹คใ€๊ณ  ๋งํ•˜์ง€ ์•Š๊ฒŒ.
91
+ */
92
+ notCovered: []
93
+ };
94
+ }
95
+ //# sourceMappingURL=model-gap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-gap.js","sourceRoot":"","sources":["../../server/engine/model-gap.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;AA6GH,gCAgCC;AAnHD;;;;;GAKG;AACU,QAAA,YAAY,GAAG,EAAE,CAAA;AAoD9B,uDAAuD;AAC1C,QAAA,kBAAkB,GAAG,QAAQ,CAAA;AAE1C,SAAS,MAAM,CAAC,IAAoD;IAClE,MAAM,GAAG,GAAa,EAAE,CAAA;IACxB,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,KAAK,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;QAC3B,IAAI,CAAC,EAAE,MAAM,KAAK,UAAU,EAAE,CAAC;YAC7B,KAAK,EAAE,CAAA;YACP,IAAI,GAAG,CAAC,MAAM,GAAG,oBAAY;gBAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAC7D,CAAC;aAAM,IAAI,CAAC,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAC;YAClC,kDAAkD;YAClD,OAAO,EAAE,CAAA;QACX,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAA;AACvE,CAAC;AAED;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,QAA2C;IACpE,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAA;IAE1B,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;IAC5C,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;IAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IACxC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAE9C,OAAO;QACL,SAAS;QACT,SAAS;QACT,OAAO;QACP,MAAM;QACN,KAAK,EAAE,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK;QACvE,SAAS,EAAE,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9C,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,8CAA8C;YAC9C,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,QAAkB,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI;SAC1F,CAAC,CAAC;QACH;;;WAGG;QACH,uBAAuB,EACrB,OAAO,QAAQ,CAAC,MAAM,EAAE,gBAAgB,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI;QACvH;;;WAGG;QACH,UAAU,EAAE,EAAE;KACf,CAAA;AACH,CAAC","sourcesContent":["/*\n * **์›๋ณธ์ด ๋งํ•œ ์  ์—†๋Š” ๊ฒƒ** โ€” ๋ฏธํ•ด๊ฒฐ ์ฐธ์กฐ๋ฅผ ์„ธ๋Š” ํ•œ ์ž๋ฆฌ. ์ˆœ์ˆ˜(import ์—†์Œ).\n *\n * โ”€โ”€ ๋ฌด์—‡์„ ๋‹ตํ•˜๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์›์ฒœ์ด ์šฐ๋ฆฌ ๋ชจ๋ธ์— ์—†๋Š” id ๋ฅผ ๋ณด๋‚ด๋ฉด ์–ด๋–ป๊ฒŒ ๋˜๋‚˜. ์œ ์ž… ๋ฌธ(`ingestCanonicalRecords`)์€ **๊ฑฐ๋ถ€ํ•˜์ง€\n * ์•Š๋Š”๋‹ค** โ€” ์‹ค์ธก์œผ๋กœ ํ™•์ธํ–ˆ๋‹ค(2026-08-20):\n *\n * ๋ชจ๋ฅด๋Š” ๋กœ์ผ€์ด์…˜ ใ€Œ์˜คํƒ€-99ใ€ โ†’ ํ†ต๊ณผ\n * ๋ชจ๋ฅด๋Š” bizStep ใ€ŒPUTAWAY_X17ใ€ โ†’ ํ†ต๊ณผ\n * ๋ชจ๋ฅด๋Š” ๊ณ„๋Ÿ‰๊ธฐ ใ€ŒMMXU-์˜คํƒ€-99ใ€ โ†’ ํ†ต๊ณผ\n *\n * ๊ฑฐ๋ถ€ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์˜ณ๋‹ค. ์›์ฒœ์ด ๋ชจ๋ธ๋ณด๋‹ค ๋จผ์ € ์ƒˆ ๋กœ์ผ€์ด์…˜์„ ๋งํ•˜๋Š” ๊ฒƒ์€ ์ •์ƒ์ด๊ณ (๊ตฌ์กฐ ๊ฐฑ์‹ ์€ ๋Šฆ๊ฒŒ ์˜จ๋‹ค),\n * ๊ฑฐ๋ถ€ํ•˜๋ฉด ๊ทธ ์„ ํ–‰ ๊ณ„์ธก์„ ์žƒ๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ์ปค๋„์€ **ํก์ˆ˜ํ•˜๊ณ  ํ‘œ์‹œํ•œ๋‹ค** โ€” ๋งˆ์Šคํ„ฐ์— ์—†๋˜ ๋กœ์ผ€์ด์…˜์€\n * `origin: 'observed'` ๋กœ ์Šน๊ฒฉ๋˜์–ด ์Šค๋ƒ…์ƒท์— ์‹ค๋ฆฐ๋‹ค(`ObservedReducer.touchLocation`).\n *\n * โ”€โ”€ ์™œ ์ด ํŒŒ์ผ์ด ์žˆ๋‚˜ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๊ทธ ํ‘œ์‹œ๋ฅผ ์ฝ๋Š” ๊ณณ์ด **๋ชจ๋ธ ์ธ์ŠคํŽ™์…˜ ํ™”๋ฉด ํ•˜๋‚˜**์˜€๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด ์‚ฌ์‹ค์„ ํ•„์š”๋กœ ํ•˜๋Š” ์‚ฌ๋žŒ์€ ใ€Œ์ด ํŠธ์œˆ์ด\n * ํ˜„์žฅ๊ณผ ๋งž์ถฐ์ง€๊ณ  ์žˆ๋‚˜ใ€๋ฅผ ๋ณด๋Š” ์‚ฌ๋žŒ์ด๋‹ค โ€” ์›์ฒœ์ด ์šฐ๋ฆฌ๊ฐ€ ๋ชจ๋ฅด๋Š” ๋กœ์ผ€์ด์…˜๋งŒ ๋ณด๋‚ด๊ณ  ์žˆ์œผ๋ฉด ํŠธ์œˆ์€ ๋„๋Š”๋ฐ\n * ์Šคํ‚ค๋งคํ‹ฑ์€ ๋น„์–ด ์žˆ๊ณ , ๊ทธ๊ฒƒ์ด ์šฐ๋ฆฌ๊ฐ€ ใ€Œ๋นˆ ๊ณต์žฅใ€์ด๋ผ ๋ถˆ๋Ÿฌ ์˜จ ์ƒํƒœ๋‹ค.\n *\n * ๋„์ถœ์„ ๋‘ ๊ณณ์— ์ ์œผ๋ฉด ๋‘ ํ™”๋ฉด์ด ๋‹ค๋ฅธ ์ˆ˜๋ฅผ ๋งํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ์—ฌ๊ธฐ ํ•œ ๋ฒŒ๋งŒ ๋‘”๋‹ค.\n *\n * โ”€โ”€ ํŒ์ •์„ ๋ฐ”๊พธ์ง€ ์•Š๋Š”๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋™๊ธฐํ™” ํŒ์ •(`syncVerdictOf`)์€ **ํ”ผ๋“œ**๋ฅผ ๋งํ•œ๋‹ค: ์˜ค๊ณ  ์žˆ๋‚˜, ํ†ต๊ณผํ•˜๋‚˜. ์ด ๊ฐญ์€ **๋ชจ๋ธ**์„ ๋งํ•œ๋‹ค:\n * ์›์ฒœ์ด ์•„๋Š” ๊ฒƒ์„ ์šฐ๋ฆฌ๊ฐ€ ์„ ์–ธํ–ˆ๋‚˜. ๋‘˜์„ ํ•œ ํŒ์ •์— ์„ž์œผ๋ฉด ใ€Œ์œ ์ž…์€ ์ •์ƒ์ธ๋ฐ ๋ชจ๋ธ์ด ๋’ค์ฒ˜์กŒ๋‹คใ€์™€\n * ใ€Œ์œ ์ž…์ด ๋ง‰ํ˜”๋‹คใ€๊ฐ€ ๊ฐ™์€ ์ƒ‰์œผ๋กœ ๋ณด์ด๊ณ , ์ฒ˜๋ฐฉ์ด ์™„์ „ํžˆ ๋‹ค๋ฅด๋‹ค.\n */\n\n/** ์ปค๋„ ์Šค๋ƒ…์ƒท์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์ฝ๋Š” ๊ฒƒ๋งŒ. ๋‚˜๋จธ์ง€ ํ•„๋“œ๋Š” ์•Œ ํ•„์š”๊ฐ€ ์—†๋‹ค. */\nexport interface ModelGapSource {\n locations?: { id?: string; origin?: string }[]\n equipment?: { id?: string; origin?: string }[]\n persons?: { id?: string; origin?: string }[]\n /** ์ปค๋„์ด ๋‹ด์„ ์ค„ ๋ชฐ๋ผ ์„ธ์–ด ๋‘” ์‚ฌ๊ฑด โ€” ์ข…๋ฅ˜๋ณ„ ๊ฐœ์ˆ˜์™€ ์ฒ˜์Œยท๋งˆ์ง€๋ง‰ ์‹œ๊ฐ. */\n unhandled?: { eventType: string; count: number; firstAtMs?: number; lastAtMs?: number }[]\n /**\n * EMS ์ƒํƒœ โ€” **`energy` ์•ˆ์— ์žˆ๋‹ค.**\n *\n * `unknownEquipment` ๋ฅผ ๋ฃจํŠธ์—์„œ ์ฝ๊ณ  ์žˆ์—ˆ๋‹ค(2026-08-20์— ์žก์Œ). ์ปค๋„์€ ๊ทธ๊ฒƒ์„ `EnergyState` ์•ˆ์—\n * ๋‹ด์œผ๋ฏ€๋กœ, ๋ฃจํŠธ์—์„œ ์ฝ์œผ๋ฉด **์˜์›ํžˆ `null`** ์ด๋‹ค โ€” ์˜ค๋ฅ˜๋„ ์—†์ด ใ€Œ์—๋„ˆ์ง€ ํŠธ์œˆ์ด ์•„๋‹ˆ๋‹คใ€๋กœ ์ฝํžŒ๋‹ค.\n * ๋‚˜๋งŒ ์ฝ๋Š” ํ•„๋“œ๋ฅผ ์ž˜๋ชป๋œ ๊ฒฝ๋กœ์—์„œ ์ฝ์œผ๋ฉด ์ด๋ ‡๊ฒŒ ์กฐ์šฉํžˆ ์‚ฌ๋ผ์ง„๋‹ค.\n *\n * ๊ณ„๋Ÿ‰ ์ง€์ ์˜ `origin` ์€ **์—†์„ ์ˆ˜ ์žˆ๋‹ค**(์˜› ์Šค๋ƒ…์ƒท์—์„œ ์ด์–ด๋ฐ›์€ ์ง€์ ). ๊ทธ๋•Œ๋Š” ใ€Œ์„ ์–ธ๋˜์—ˆ๋‹คใ€๊ฐ€\n * ์•„๋‹ˆ๋ผ **๋ชจ๋ฅธ๋‹ค**๋‹ค.\n */\n energy?: {\n points?: { id?: string; origin?: string }[]\n /** ๋ชจ๋ธ์ด ๋ชจ๋ฅด๋Š” ์„ค๋น„๊ฐ€ ์—๋„ˆ์ง€ ์ƒํƒœ๋ฅผ ๋ณด๋‚ด ์˜จ ํšŸ์ˆ˜. 0 ์ด๋ฉด ์ปค๋„์ด ์ด ์นธ์„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. */\n unknownEquipment?: number\n }\n}\n\n/**\n * ํ™”๋ฉด์— ๋‚ด๋Š” id ์ˆ˜ ์ƒํ•œ.\n *\n * ์˜คํƒ€ ํ•˜๋‚˜๋ฅผ ์ฐพ๋Š” ๋ฐ ์Šค๋ฌด ๊ฐœ๋ฉด ์ถฉ๋ถ„ํ•˜๊ณ , ์›์ฒœ์ด ์ˆ˜์ฒœ ๊ฐœ๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒฝ์šฐ(๋ชจ๋ธ์„ ์•„์˜ˆ ์•ˆ ๋งž์ถ˜ ๊ฒฝ์šฐ)์—\n * ๋ชฉ๋ก์œผ๋กœ ํ™”๋ฉด์„ ์ฑ„์šธ ์ด์œ ๊ฐ€ ์—†๋‹ค. **๋„˜์นœ ์ˆ˜๋Š” ํ•จ๊ป˜ ๋‚ธ๋‹ค** โ€” ์กฐ์šฉํžˆ ์ž๋ฅด์ง€ ์•Š๋Š”๋‹ค.\n */\nexport const GAP_ID_LIMIT = 20\n\nexport interface ModelGapAxis {\n /** ๊ด€์ธก์œผ๋กœ๋งŒ ์•Œ๊ฒŒ ๋œ id ์ˆ˜. */\n count: number\n /** ๊ทธ์ค‘ ํ™”๋ฉด์— ์‹ฃ๋Š” ๊ฒƒ(์ตœ๋Œ€ `GAP_ID_LIMIT`). */\n ids: string[]\n /** ์ƒํ•œ์—์„œ ๋ฐ€๋ ค๋‚œ ์ˆ˜. 0 ์ด๋ฉด ์ „๋ถ€ ์‹ค์—ˆ๋‹ค. */\n more: number\n /**\n * ์ถœ์ฒ˜๋ฅผ **๋ชจ๋ฅด๋Š”** ์ˆ˜ โ€” ํ‘œ์‹œ๊ฐ€ ์—†๋Š” ํ•ญ๋ชฉ.\n *\n * ใ€Œ์„ ์–ธ๋˜์—ˆ๋‹คใ€๋กœ ์„ธ์ง€ ์•Š๋Š”๋‹ค. ๊ณ„๋Ÿ‰๊ธฐ๋Š” ์ด ํ‘œ์‹œ๊ฐ€ ๋Šฆ๊ฒŒ ์ƒ๊ฒผ์œผ๋ฏ€๋กœ ์˜› ์Šค๋ƒ…์ƒท์—์„œ ์ด์–ด๋ฐ›์€ ์ง€์ ์—๋Š”\n * ์นธ์ด ์—†๋‹ค(`undefined`). ๊ทธ๊ฒƒ์„ ๋งˆ์Šคํ„ฐ๋กœ ์„ธ๋ฉด ์˜คํƒ€๋ฅผ ๋†“์น˜๊ณ , ๊ด€์ธก์œผ๋กœ ์„ธ๋ฉด ์ •์ƒ์„ ๋ฌธ์ œ๋กœ ๋งŒ๋“ ๋‹ค.\n * ๋‘˜ ๋‹ค ํ‹€๋ฆฌ๋ฏ€๋กœ **๋ชจ๋ฅธ๋‹ค๊ณ  ์„ผ๋‹ค.**\n */\n unknown: number\n}\n\nexport interface ModelGapView {\n locations: ModelGapAxis\n equipment: ModelGapAxis\n persons: ModelGapAxis\n /**\n * EMS ๊ณ„๋Ÿ‰ ์ง€์ .\n *\n * โ”€โ”€ ์ด ์ถ•์ด ๊ฐ€์žฅ ๋ฌด๊ฒ๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ๋ชจ๋ฅด๋Š” `meterId` ๋Š” ์กฐ์šฉํžˆ ์ƒˆ ๊ณ„๋Ÿ‰๊ธฐ๊ฐ€ ๋˜๊ณ  ๊ทธ kW ๊ฐ€ ๊ทธ ํ˜„์žฅ์˜ **์ˆ˜์š” ๊ตฌ๊ฐ„ยทํ”ผํฌยท์š”๊ธˆ ํŒ์ •**์—\n * ๋”ํ•ด์ง„๋‹ค. ์˜คํƒ€ ํ•˜๋‚˜๋ฉด ์ง„์งœ ๊ณ„๋Ÿ‰๊ธฐ๋Š” ๋ฉˆ์ถ”๊ณ  ์œ ๋ น์ด ๋ˆ„์ ๋œ๋‹ค โ€” ์ˆซ์ž๋Š” ๊ทธ๋Ÿด๋“ฏํ•˜๊ณ  ํ‹€๋ฆฐ๋‹ค. ์ž๋ฆฌ ์˜คํƒ€๋Š”\n * ์Šคํ‚ค๋งคํ‹ฑ์ด ๋น„๋Š” ๊ฒƒ์œผ๋กœ ๋“œ๋Ÿฌ๋‚˜์ง€๋งŒ, ์ด๊ฑด ๊ทธ๋Ÿด๋“ฏํ•œ ์ˆซ์ž๋กœ ๋‚˜์˜จ๋‹ค.\n *\n * ์ปค๋„์ด `origin` ์„ **ํ‘œ๋ณธ๋งˆ๋‹ค ๋‹ค์‹œ ๋งž์ถ˜๋‹ค** โ€” ์„ ์–ธ์˜ ์ •๋ณธ์€ ๋ชจ๋ธ์ด๊ณ  ๋ชจ๋ธ์€ ์ฑ„ํƒ์œผ๋กœ ๋Š˜์–ด๋‚˜๋ฏ€๋กœ,\n * ํ•œ ๋ฒˆ ์ฐ๊ณ  ๋‘๋ฉด ๋‚˜์ค‘์— ์„ ์–ธ๋œ ๊ณ„๋Ÿ‰๊ธฐ๊ฐ€ ์˜์›ํžˆ `observed` ๋กœ ๋‚จ๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ์ด ๊ฐ’์€ ใ€Œ์ง€๊ธˆ ๋ชจ๋ธ์—\n * ์žˆ๋Š”๊ฐ€ใ€์˜ ๋‹ต์ด๊ณ , ใ€Œํ•œ ๋ฒˆ ์˜คํƒ€์˜€๋‹คใ€์˜ ๋‹ต์ด ์•„๋‹ˆ๋‹ค.\n */\n meters: ModelGapAxis\n /** ์„ธ ์ถ•์˜ ํ•ฉ โ€” ํ™”๋ฉด์ด ใ€Œ์žˆ๋‚˜ ์—†๋‚˜ใ€๋ฅผ ํ•œ ๋ฒˆ์— ๋ฌป๊ธฐ ์œ„ํ•œ ๊ฐ’. */\n total: number\n /** ์ปค๋„์ด ๋‹ด์„ ์ค„ ๋ชจ๋ฅธ ์‚ฌ๊ฑด๋“ค(์ข…๋ฅ˜๋ณ„). ์ฐธ์กฐ ๋ฌธ์ œ์™€ ๋‹ค๋ฅธ ์‚ฌ์‹ค์ด๋ฏ€๋กœ ๋”ฐ๋กœ ๋‚ธ๋‹ค. */\n unhandled: { eventType: string; count: number; lastAt: string | null }[]\n /** EMS: ๋ชจ๋ธ์ด ๋ชจ๋ฅด๋Š” ์„ค๋น„์˜ ์—๋„ˆ์ง€ ๋ณด๊ณ  ํšŸ์ˆ˜. ์—†์œผ๋ฉด `null`(0 ๊ณผ ๊ตฌ๋ณ„ํ•œ๋‹ค). */\n unknownEquipmentReports: number | null\n /**\n * ์•„์ง ๋ฎ์ง€ ๋ชปํ•˜๋Š” ์ถ• โ€” **๋ชจ๋ฅด๋Š” ๊ฒƒ์„ ๋ชจ๋ฅธ๋‹ค๊ณ  ๋งํ•œ๋‹ค.**\n *\n * ๊ณ„๋Ÿ‰๊ธฐ๋Š” ์ปค๋„ 0.7.39 ๋ถ€ํ„ฐ ๋ฎ์ธ๋‹ค(๊ทธ ์ „์—๋Š” `origin` ํ‘œ์‹œ๊ฐ€ ์—†์–ด ์˜คํƒ€๋ฅผ ์ฐพ์•„ ์ค„ ์ˆ˜ ์—†์—ˆ๋‹ค).\n * ๋น„์–ด ์žˆ๋Š” ๊ฒƒ์ด ์ •์ƒ์ด๊ณ , ์ƒˆ ์ถ•์ด ํ‘œ์‹œ ์—†์ด ๋“ค์–ด์˜ค๋ฉด ์—ฌ๊ธฐ์— ์ด๋ฆ„์„ ๋„ฃ๋Š”๋‹ค โ€” ํ™”๋ฉด์ด ใ€Œ๋‹ค ์ฐพ์•„\n * ์ค€๋‹คใ€๊ณ  ๋งํ•˜์ง€ ์•Š๊ฒŒ.\n */\n notCovered: string[]\n}\n\n/** ๊ณ„๋Ÿ‰๊ธฐ ์ถ•์ด ์•„์ง ๋ฎ์ด์ง€ ์•Š๋Š” ์ด์œ  โ€” ํ™”๋ฉด์ด ๊ทธ๋Œ€๋กœ ๋งํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ด๋ฆ„์„ ์—ฌ๊ธฐ ๋‘”๋‹ค. */\nexport const NOT_COVERED_METERS = 'meters'\n\nfunction axisOf(rows: { id?: string; origin?: string }[] | undefined): ModelGapAxis {\n const ids: string[] = []\n let count = 0\n let unknown = 0\n for (const r of rows ?? []) {\n if (r?.origin === 'observed') {\n count++\n if (ids.length < GAP_ID_LIMIT) ids.push(String(r.id ?? ''))\n } else if (r?.origin !== 'master') {\n /* ํ‘œ์‹œ๊ฐ€ ์—†๋‹ค โ€” ๋งˆ์Šคํ„ฐ๋กœ๋„ ๊ด€์ธก์œผ๋กœ๋„ ์„ธ์ง€ ์•Š๋Š”๋‹ค. ๋ชจ๋ฅด๋Š” ๊ฒƒ์€ ๋ชจ๋ฅธ๋‹ค๊ณ  ์„ผ๋‹ค. */\n unknown++\n }\n }\n return { count, ids, more: Math.max(0, count - ids.length), unknown }\n}\n\n/**\n * ์Šค๋ƒ…์ƒท โ†’ ๋ชจ๋ธ ๊ฐญ.\n *\n * ์Šค๋ƒ…์ƒท์ด ์—†์œผ๋ฉด `null` ์ด๋‹ค โ€” **0 ์ด ์•„๋‹ˆ๋‹ค.** ํŠธ์œˆ์ด ๋Œ์ง€ ์•Š์œผ๋ฉด ๋น„๊ตํ•  ์ƒ๋Œ€๊ฐ€ ์—†๊ณ , ใ€Œ์—†๋‹คใ€์™€\n * ใ€Œ์„ธ์–ด ๋ณด์ง€ ๋ชปํ–ˆ๋‹คใ€๋Š” ๋‹ค๋ฅธ ์‚ฌ์‹ค์ด๋‹ค(๋ชจ๋ธ ์ธ์ŠคํŽ™์…˜์ด ๊ฐ™์€ ๊ทœ์œจ์„ ์“ด๋‹ค).\n */\nexport function modelGapOf(snapshot: ModelGapSource | null | undefined): ModelGapView | null {\n if (!snapshot) return null\n\n const locations = axisOf(snapshot.locations)\n const equipment = axisOf(snapshot.equipment)\n const persons = axisOf(snapshot.persons)\n const meters = axisOf(snapshot.energy?.points)\n\n return {\n locations,\n equipment,\n persons,\n meters,\n total: locations.count + equipment.count + persons.count + meters.count,\n unhandled: (snapshot.unhandled ?? []).map(u => ({\n eventType: u.eventType,\n count: u.count,\n /* ๋งˆ์ง€๋ง‰ ์‹œ๊ฐ์ด ๋ฉˆ์ถ˜ ์ข…๋ฅ˜๋Š” ์ด๋ฏธ ๊ณ ์ณ์ง„ ๊ฒƒ์ด๋‹ค. ์—†์œผ๋ฉด ์ง€์–ด๋‚ด์ง€ ์•Š๋Š”๋‹ค. */\n lastAt: Number.isFinite(u.lastAtMs) ? new Date(u.lastAtMs as number).toISOString() : null\n })),\n /*\n * ์ปค๋„์€ 0 ์ด๋ฉด ์ด ์นธ์„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ใ€Œ์—†์Œใ€์€ ๋‘ ๋œป์ด๋‹ค โ€” ์—๋„ˆ์ง€ ํŠธ์œˆ์ด ์•„๋‹ˆ๊ฑฐ๋‚˜, ์„ธ์—ˆ๊ณ \n * 0 ์ด์—ˆ๋‹ค. ๋‘˜์„ ๊ฐ€๋ฅด๋ ค๋ฉด `energy` ์ž์ฒด๊ฐ€ ์žˆ๋Š”์ง€๋ฅผ ๋ณธ๋‹ค: ์žˆ์œผ๋ฉด ์„ธ์—ˆ๊ณ  0 ์ด๋‹ค.\n */\n unknownEquipmentReports:\n typeof snapshot.energy?.unknownEquipment === 'number' ? snapshot.energy.unknownEquipment : snapshot.energy ? 0 : null,\n /*\n * ์ด์ œ ๊ณ„๋Ÿ‰๊ธฐ๋„ ๋ฎ๋Š”๋‹ค(์ปค๋„ 0.7.39 ๊ฐ€ `MeterPointState.origin` ์„ ๋‚ธ๋‹ค). ๋ฎ์ง€ ๋ชปํ•˜๋Š” ์ถ•์ด ์ƒ๊ธฐ๋ฉด\n * ๋‹ค์‹œ ์—ฌ๊ธฐ์— ์ด๋ฆ„์„ ๋„ฃ๋Š”๋‹ค โ€” ํ™”๋ฉด์ด ใ€Œ๋‹ค ์ฐพ์•„ ์ค€๋‹คใ€๊ณ  ๋งํ•˜์ง€ ์•Š๊ฒŒ.\n */\n notCovered: []\n }\n}\n"]}
@@ -2,12 +2,12 @@
2
2
  export type RestartPolicy = 'resync' | 'resume' | 'reset';
3
3
  export declare const RESTART_POLICIES: readonly RestartPolicy[];
4
4
  /**
5
- * ์ €์žฅ๋œ ๊ฐ’์„ ์ •์ฑ…์œผ๋กœ ์ฝ๋Š”๋‹ค โ€” **๋ชจ๋ฅด๋ฉด ๋˜์ง„๋‹ค**(๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋ฉ”์šฐ์ง€ ์•Š๋Š”๋‹ค).
5
+ * ์ €์žฅ๋œ ๊ฐ’์„ ์ •์ฑ…์œผ๋กœ ์ฝ๋Š”๋‹ค โ€” **๋ชจ๋ฅด๋ฉด ์˜ค๋ฅ˜๋ฅผ ๋‚ธ๋‹ค**(๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋ฉ”์šฐ์ง€ ์•Š๋Š”๋‹ค).
6
6
  *
7
7
  * ์˜› ์–ดํœ˜(`mirror`ยท`sim-world`ยท`sim-experiment`)๋ฅผ ์—ฌ๊ธฐ์„œ ๋ฒˆ์—ญํ•˜์ง€ ์•Š๋Š”๋‹ค: ๋ฒˆ์—ญ์„ ๋‘๋ฉด ์˜› ๊ฐ’์ด ์‚ด์•„๋‚จ๊ณ ,
8
8
  * ๊ทธ ๊ฐ’์ด ๋‹ค์‹œ ์–ด๋”˜๊ฐ€์— ์ €์žฅ๋œ๋‹ค. ์ €์žฅ๋œ ๊ฐ’์€ **ํ•œ ๋ฒˆ ์˜ฎ๊ธฐ๊ณ **(๋ฐ์ดํ„ฐ ์ด๊ด€) ์ฝ”๋“œ๋Š” ์ƒˆ ์–ดํœ˜๋งŒ ์•ˆ๋‹ค.
9
- * ๊ทธ๋ž˜์„œ ์ด ํ•จ์ˆ˜๋Š” ์˜› ๊ฐ’์— ๋Œ€ํ•ด์„œ๋„ ๋˜์ง€๋ฉฐ, ๋ฌด์—‡์œผ๋กœ ์˜ฎ๊ฒจ์•ผ ํ•˜๋Š”์ง€ ๋ฌธ์žฅ์œผ๋กœ ๋งํ•œ๋‹ค.
9
+ * ๊ทธ๋ž˜์„œ ์ด ํ•จ์ˆ˜๋Š” ์˜› ๊ฐ’์— ๋Œ€ํ•ด์„œ๋„ ์˜ค๋ฅ˜๋ฅผ ๋‚ด๋ฉฐ, ๋ฌด์—‡์œผ๋กœ ์˜ฎ๊ฒจ์•ผ ํ•˜๋Š”์ง€ ๋ฌธ์žฅ์œผ๋กœ ๋งํ•œ๋‹ค.
10
10
  */
11
11
  export declare function readRestartPolicy(raw: unknown, where: string): RestartPolicy;
12
- /** ์ด ๊ฐ’์ด ์ •์ฑ…์ธ๊ฐ€ โ€” ๋˜์ง€์ง€ ์•Š๊ณ  ๋ฌป๋Š” ์ž๋ฆฌ(ํ™”๋ฉดยท๊ฒ€์‚ฌ)๋ฅผ ์œ„ํ•ด. */
12
+ /** ์ด ๊ฐ’์ด ์ •์ฑ…์ธ๊ฐ€ โ€” ์˜ค๋ฅ˜๋ฅผ ๋‚ด์ง€ ์•Š๊ณ  ๋ฌป๋Š” ์ž๋ฆฌ(ํ™”๋ฉดยท๊ฒ€์‚ฌ)๋ฅผ ์œ„ํ•ด. */
13
13
  export declare function isRestartPolicy(raw: unknown): raw is RestartPolicy;
@@ -19,7 +19,7 @@
19
19
  * โ”€โ”€ ๊ธฐ๋ณธ๊ฐ’์„ ๋‘์ง€ ์•Š๋Š”๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
20
20
  * ์˜ˆ์ „์—๋Š” ๋ฏธ์„ ์–ธ์ด ์กฐ์šฉํžˆ `sim-experiment`(=์ €๋„ ์ดˆ๊ธฐํ™”)๋กœ ๋–จ์–ด์กŒ๋‹ค. ๊ทธ ๊ด€์šฉ์€ ๊ฐ’์ด ํ•˜๋‚˜ ์–ด๊ธ‹๋‚˜๋Š”
21
21
  * ์ˆœ๊ฐ„ **์ €๋„์„ ์ง€์šฐ๋Š” ๊ธธ**์ด ๋œ๋‹ค โ€” ๊ฐœ๋ช… ๋’ค ์˜› ๊ฐ’์ด ๋‚จ์•„ ์žˆ๋Š” ํ–‰์„ ๊ทธ ๊ธธ๋กœ ์ฝ์œผ๋ฉด ์žฌ๊ธฐ๋™ ํ•œ ๋ฒˆ์—
22
- * ์ด๋ ฅ์ด ์‚ฌ๋ผ์ง„๋‹ค. ๊ทธ๋ž˜์„œ ๋ชจ๋ฅด๋Š” ๊ฐ’์€ **๋˜์ง„๋‹ค.** ๋ถ€๋ฅด๋Š” ์ชฝ์ด ์„ ์–ธํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ด ์ถ•์˜ ์š”์ ์ด๋‹ค.
22
+ * ์ด๋ ฅ์ด ์‚ฌ๋ผ์ง„๋‹ค. ๊ทธ๋ž˜์„œ ๋ชจ๋ฅด๋Š” ๊ฐ’์€ **์˜ค๋ฅ˜๋ฅผ ๋‚ธ๋‹ค.** ๋ถ€๋ฅด๋Š” ์ชฝ์ด ์„ ์–ธํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ด ์ถ•์˜ ์š”์ ์ด๋‹ค.
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.RESTART_POLICIES = void 0;
@@ -27,11 +27,11 @@ exports.readRestartPolicy = readRestartPolicy;
27
27
  exports.isRestartPolicy = isRestartPolicy;
28
28
  exports.RESTART_POLICIES = ['resync', 'resume', 'reset'];
29
29
  /**
30
- * ์ €์žฅ๋œ ๊ฐ’์„ ์ •์ฑ…์œผ๋กœ ์ฝ๋Š”๋‹ค โ€” **๋ชจ๋ฅด๋ฉด ๋˜์ง„๋‹ค**(๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋ฉ”์šฐ์ง€ ์•Š๋Š”๋‹ค).
30
+ * ์ €์žฅ๋œ ๊ฐ’์„ ์ •์ฑ…์œผ๋กœ ์ฝ๋Š”๋‹ค โ€” **๋ชจ๋ฅด๋ฉด ์˜ค๋ฅ˜๋ฅผ ๋‚ธ๋‹ค**(๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋ฉ”์šฐ์ง€ ์•Š๋Š”๋‹ค).
31
31
  *
32
32
  * ์˜› ์–ดํœ˜(`mirror`ยท`sim-world`ยท`sim-experiment`)๋ฅผ ์—ฌ๊ธฐ์„œ ๋ฒˆ์—ญํ•˜์ง€ ์•Š๋Š”๋‹ค: ๋ฒˆ์—ญ์„ ๋‘๋ฉด ์˜› ๊ฐ’์ด ์‚ด์•„๋‚จ๊ณ ,
33
33
  * ๊ทธ ๊ฐ’์ด ๋‹ค์‹œ ์–ด๋”˜๊ฐ€์— ์ €์žฅ๋œ๋‹ค. ์ €์žฅ๋œ ๊ฐ’์€ **ํ•œ ๋ฒˆ ์˜ฎ๊ธฐ๊ณ **(๋ฐ์ดํ„ฐ ์ด๊ด€) ์ฝ”๋“œ๋Š” ์ƒˆ ์–ดํœ˜๋งŒ ์•ˆ๋‹ค.
34
- * ๊ทธ๋ž˜์„œ ์ด ํ•จ์ˆ˜๋Š” ์˜› ๊ฐ’์— ๋Œ€ํ•ด์„œ๋„ ๋˜์ง€๋ฉฐ, ๋ฌด์—‡์œผ๋กœ ์˜ฎ๊ฒจ์•ผ ํ•˜๋Š”์ง€ ๋ฌธ์žฅ์œผ๋กœ ๋งํ•œ๋‹ค.
34
+ * ๊ทธ๋ž˜์„œ ์ด ํ•จ์ˆ˜๋Š” ์˜› ๊ฐ’์— ๋Œ€ํ•ด์„œ๋„ ์˜ค๋ฅ˜๋ฅผ ๋‚ด๋ฉฐ, ๋ฌด์—‡์œผ๋กœ ์˜ฎ๊ฒจ์•ผ ํ•˜๋Š”์ง€ ๋ฌธ์žฅ์œผ๋กœ ๋งํ•œ๋‹ค.
35
35
  */
36
36
  function readRestartPolicy(raw, where) {
37
37
  const value = typeof raw === 'string' ? raw.trim() : '';
@@ -45,7 +45,7 @@ function readRestartPolicy(raw, where) {
45
45
  throw new Error(`${where}: restart policy ${value ? `"${value}"` : 'is missing'} โ€” declare one of ${exports.RESTART_POLICIES.join(' | ')}. ` +
46
46
  'There is no default: an unspecified policy used to fall through to "reset", which erases the journal on the next reboot.');
47
47
  }
48
- /** ์ด ๊ฐ’์ด ์ •์ฑ…์ธ๊ฐ€ โ€” ๋˜์ง€์ง€ ์•Š๊ณ  ๋ฌป๋Š” ์ž๋ฆฌ(ํ™”๋ฉดยท๊ฒ€์‚ฌ)๋ฅผ ์œ„ํ•ด. */
48
+ /** ์ด ๊ฐ’์ด ์ •์ฑ…์ธ๊ฐ€ โ€” ์˜ค๋ฅ˜๋ฅผ ๋‚ด์ง€ ์•Š๊ณ  ๋ฌป๋Š” ์ž๋ฆฌ(ํ™”๋ฉดยท๊ฒ€์‚ฌ)๋ฅผ ์œ„ํ•ด. */
49
49
  function isRestartPolicy(raw) {
50
50
  return typeof raw === 'string' && exports.RESTART_POLICIES.includes(raw);
51
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"restart-policy.js","sourceRoot":"","sources":["../../server/engine/restart-policy.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;;AAcH,8CAcC;AAGD,0CAEC;AA5BY,QAAA,gBAAgB,GAA6B,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAU,CAAA;AAEhG;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAAC,GAAY,EAAE,KAAa;IAC3D,MAAM,KAAK,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IACvD,IAAK,wBAAsC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAsB,CAAA;IAC1F,MAAM,MAAM,GAAkC,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAA;IACpH,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,qBAAqB,KAAK,uDAAuD,MAAM,CAAC,KAAK,CAAC,IAAI;YACxG,4IAA4I,CAC/I,CAAA;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,oBAAoB,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,YAAY,qBAAqB,wBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI;QAClH,0HAA0H,CAC7H,CAAA;AACH,CAAC;AAED,2CAA2C;AAC3C,SAAgB,eAAe,CAAC,GAAY;IAC1C,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAK,wBAAsC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;AACzF,CAAC","sourcesContent":["/*\n * **์žฌ๊ธฐ๋™ ์ •์ฑ…** โ€” ์ด ํŠธ์œˆ์€ ๋‹ค์‹œ ์„ธ์›Œ์งˆ ๋•Œ ์ž๊ธฐ ๊ณผ๊ฑฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๋Œ€ํ•˜๋‚˜.\n *\n * โ”€โ”€ ์™œ ์ด ์ด๋ฆ„์ธ๊ฐ€ (ADR-0029 ยท plans/simulator-as-source.md ยง2) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์˜› ์ด๋ฆ„์€ `realityMode` ์˜€๊ณ  ๊ฐ’์€ `mirror`ยท`sim-world`ยท`sim-experiment` ์˜€๋‹ค. ๊ทธ ์ถ•์€ ใ€Œํ˜„์‹ค์ด ์–ด๋””์„œ\n * ์˜ค๋‚˜ใ€๋ฅผ ๋งํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์˜€์ง€๋งŒ, ์ฝ”๋“œ๊ฐ€ ๊ทธ๊ฒƒ์œผ๋กœ ๊ฐ€๋ฅธ ๊ฒƒ์€ **์žฌ๊ธฐ๋™ ๊ฑฐ๋™ ํ•˜๋‚˜**์˜€๋‹ค. ๊ทธ๋ฆฌ๊ณ  ใ€Œํ˜„์‹ค์ด\n * ์–ด๋””์„œ ์˜ค๋‚˜ใ€๋Š” ADR-0029 ๊ฐ€ **์›๋ณธ์˜ ์ข…๋ฅ˜**๋กœ ์˜ฎ๊ธด ๋ฌผ์Œ์ด๋‹ค(`TwinReference.adapterType`) โ€” ํŠธ์œˆ์€ ํ•œ\n * ์ข…๋ฅ˜์ด๊ณ  ์–ธ์ œ๋‚˜ ์›๋ณธ์„ ๋ฐ˜์˜ํ•œ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์ด ์ถ•์€ ์‚ฌ๋ผ์ง€์ง€ ์•Š๊ณ  **ํŠธ์œˆ์— ๋‚จ์•„ ์ด๋ฆ„์„ ๋ฐ”๊ฟจ๋‹ค.** ๋‚จ๋Š” ์ด์œ : ใ€Œ์ž๊ธฐ ์ €๋„์„ ์ž‡๋Š”๊ฐ€ใ€๋Š” ์›๋ณธ์˜\n * ์„ฑ์งˆ์ด ์•„๋‹ˆ๋ผ **ํŠธ์œˆ๊ณผ ์ž๊ธฐ ๊ณผ๊ฑฐ์˜ ๊ด€๊ณ„**๋‹ค. ๊ฐ™์€ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ์›๋ณธ์„ ๋ณด๋Š” ๋‘ ํŠธ์œˆ์ด ํ•˜๋‚˜๋Š” ์ด์–ด๊ฐ€๊ณ \n * ํ•˜๋‚˜๋Š” ๋งค๋ฒˆ ์ฒ˜์Œ๋ถ€ํ„ฐ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค โ€” ์›๋ณธ์€ ๊ทธ ๋‘˜์„ ๊ตฌ๋ณ„ํ•˜์ง€ ๋ชปํ•œ๋‹ค.\n *\n * resync โ€” ์™ธ๋ถ€ ์‹ค๋ฌผ์—์„œ ๋‹ค์‹œ ์ฝ๋Š”๋‹ค(์›๋ณธ์ด ์ง„์‹ค์ด๋ฏ€๋กœ ์šฐ๋ฆฌ ๊ณผ๊ฑฐ๋ฅผ ์ด์–ด ๋ถ™์ด์ง€ ์•Š๋Š”๋‹ค).\n * resume โ€” ์ €๋„์„ ์ด์–ด ์„ธ์šด๋‹ค(์ด ํŠธ์œˆ์ด ๋‚ณ์€ ํƒ€์ž„๋ผ์ธ์ด ๊ณง ์‚ฌ์‹ค์ด๋‹ค).\n * reset โ€” ์ €๋„์„ ๋น„์šฐ๊ณ  ์”จ์•—๋ถ€ํ„ฐ ๋‹ค์‹œ ๋Œ๋ฆฐ๋‹ค(์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ์‹คํ—˜).\n *\n * โ”€โ”€ ๊ธฐ๋ณธ๊ฐ’์„ ๋‘์ง€ ์•Š๋Š”๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์˜ˆ์ „์—๋Š” ๋ฏธ์„ ์–ธ์ด ์กฐ์šฉํžˆ `sim-experiment`(=์ €๋„ ์ดˆ๊ธฐํ™”)๋กœ ๋–จ์–ด์กŒ๋‹ค. ๊ทธ ๊ด€์šฉ์€ ๊ฐ’์ด ํ•˜๋‚˜ ์–ด๊ธ‹๋‚˜๋Š”\n * ์ˆœ๊ฐ„ **์ €๋„์„ ์ง€์šฐ๋Š” ๊ธธ**์ด ๋œ๋‹ค โ€” ๊ฐœ๋ช… ๋’ค ์˜› ๊ฐ’์ด ๋‚จ์•„ ์žˆ๋Š” ํ–‰์„ ๊ทธ ๊ธธ๋กœ ์ฝ์œผ๋ฉด ์žฌ๊ธฐ๋™ ํ•œ ๋ฒˆ์—\n * ์ด๋ ฅ์ด ์‚ฌ๋ผ์ง„๋‹ค. ๊ทธ๋ž˜์„œ ๋ชจ๋ฅด๋Š” ๊ฐ’์€ **๋˜์ง„๋‹ค.** ๋ถ€๋ฅด๋Š” ์ชฝ์ด ์„ ์–ธํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ด ์ถ•์˜ ์š”์ ์ด๋‹ค.\n */\n\n/** ์žฌ๊ธฐ๋™ ์ •์ฑ… โ€” ์…‹๋ฟ์ด๋‹ค. */\nexport type RestartPolicy = 'resync' | 'resume' | 'reset'\n\nexport const RESTART_POLICIES: readonly RestartPolicy[] = ['resync', 'resume', 'reset'] as const\n\n/**\n * ์ €์žฅ๋œ ๊ฐ’์„ ์ •์ฑ…์œผ๋กœ ์ฝ๋Š”๋‹ค โ€” **๋ชจ๋ฅด๋ฉด ๋˜์ง„๋‹ค**(๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋ฉ”์šฐ์ง€ ์•Š๋Š”๋‹ค).\n *\n * ์˜› ์–ดํœ˜(`mirror`ยท`sim-world`ยท`sim-experiment`)๋ฅผ ์—ฌ๊ธฐ์„œ ๋ฒˆ์—ญํ•˜์ง€ ์•Š๋Š”๋‹ค: ๋ฒˆ์—ญ์„ ๋‘๋ฉด ์˜› ๊ฐ’์ด ์‚ด์•„๋‚จ๊ณ ,\n * ๊ทธ ๊ฐ’์ด ๋‹ค์‹œ ์–ด๋”˜๊ฐ€์— ์ €์žฅ๋œ๋‹ค. ์ €์žฅ๋œ ๊ฐ’์€ **ํ•œ ๋ฒˆ ์˜ฎ๊ธฐ๊ณ **(๋ฐ์ดํ„ฐ ์ด๊ด€) ์ฝ”๋“œ๋Š” ์ƒˆ ์–ดํœ˜๋งŒ ์•ˆ๋‹ค.\n * ๊ทธ๋ž˜์„œ ์ด ํ•จ์ˆ˜๋Š” ์˜› ๊ฐ’์— ๋Œ€ํ•ด์„œ๋„ ๋˜์ง€๋ฉฐ, ๋ฌด์—‡์œผ๋กœ ์˜ฎ๊ฒจ์•ผ ํ•˜๋Š”์ง€ ๋ฌธ์žฅ์œผ๋กœ ๋งํ•œ๋‹ค.\n */\nexport function readRestartPolicy(raw: unknown, where: string): RestartPolicy {\n const value = typeof raw === 'string' ? raw.trim() : ''\n if ((RESTART_POLICIES as readonly string[]).includes(value)) return value as RestartPolicy\n const legacy: Record<string, RestartPolicy> = { mirror: 'resync', 'sim-world': 'resume', 'sim-experiment': 'reset' }\n if (legacy[value]) {\n throw new Error(\n `${where}: restart policy \"${value}\" is the old vocabulary โ€” move the stored value to \"${legacy[value]}\" ` +\n '(ADR-0029 ยท plans/simulator-as-source.md ยง2). Nothing is translated at read time on purpose: a translation would keep the old value alive.'\n )\n }\n throw new Error(\n `${where}: restart policy ${value ? `\"${value}\"` : 'is missing'} โ€” declare one of ${RESTART_POLICIES.join(' | ')}. ` +\n 'There is no default: an unspecified policy used to fall through to \"reset\", which erases the journal on the next reboot.'\n )\n}\n\n/** ์ด ๊ฐ’์ด ์ •์ฑ…์ธ๊ฐ€ โ€” ๋˜์ง€์ง€ ์•Š๊ณ  ๋ฌป๋Š” ์ž๋ฆฌ(ํ™”๋ฉดยท๊ฒ€์‚ฌ)๋ฅผ ์œ„ํ•ด. */\nexport function isRestartPolicy(raw: unknown): raw is RestartPolicy {\n return typeof raw === 'string' && (RESTART_POLICIES as readonly string[]).includes(raw)\n}\n"]}
1
+ {"version":3,"file":"restart-policy.js","sourceRoot":"","sources":["../../server/engine/restart-policy.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;;AAcH,8CAcC;AAGD,0CAEC;AA5BY,QAAA,gBAAgB,GAA6B,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAU,CAAA;AAEhG;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAAC,GAAY,EAAE,KAAa;IAC3D,MAAM,KAAK,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IACvD,IAAK,wBAAsC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAsB,CAAA;IAC1F,MAAM,MAAM,GAAkC,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAA;IACpH,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,qBAAqB,KAAK,uDAAuD,MAAM,CAAC,KAAK,CAAC,IAAI;YACxG,4IAA4I,CAC/I,CAAA;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,oBAAoB,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,YAAY,qBAAqB,wBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI;QAClH,0HAA0H,CAC7H,CAAA;AACH,CAAC;AAED,8CAA8C;AAC9C,SAAgB,eAAe,CAAC,GAAY;IAC1C,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAK,wBAAsC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;AACzF,CAAC","sourcesContent":["/*\n * **์žฌ๊ธฐ๋™ ์ •์ฑ…** โ€” ์ด ํŠธ์œˆ์€ ๋‹ค์‹œ ์„ธ์›Œ์งˆ ๋•Œ ์ž๊ธฐ ๊ณผ๊ฑฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๋Œ€ํ•˜๋‚˜.\n *\n * โ”€โ”€ ์™œ ์ด ์ด๋ฆ„์ธ๊ฐ€ (ADR-0029 ยท plans/simulator-as-source.md ยง2) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์˜› ์ด๋ฆ„์€ `realityMode` ์˜€๊ณ  ๊ฐ’์€ `mirror`ยท`sim-world`ยท`sim-experiment` ์˜€๋‹ค. ๊ทธ ์ถ•์€ ใ€Œํ˜„์‹ค์ด ์–ด๋””์„œ\n * ์˜ค๋‚˜ใ€๋ฅผ ๋งํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์˜€์ง€๋งŒ, ์ฝ”๋“œ๊ฐ€ ๊ทธ๊ฒƒ์œผ๋กœ ๊ฐ€๋ฅธ ๊ฒƒ์€ **์žฌ๊ธฐ๋™ ๊ฑฐ๋™ ํ•˜๋‚˜**์˜€๋‹ค. ๊ทธ๋ฆฌ๊ณ  ใ€Œํ˜„์‹ค์ด\n * ์–ด๋””์„œ ์˜ค๋‚˜ใ€๋Š” ADR-0029 ๊ฐ€ **์›๋ณธ์˜ ์ข…๋ฅ˜**๋กœ ์˜ฎ๊ธด ๋ฌผ์Œ์ด๋‹ค(`TwinReference.adapterType`) โ€” ํŠธ์œˆ์€ ํ•œ\n * ์ข…๋ฅ˜์ด๊ณ  ์–ธ์ œ๋‚˜ ์›๋ณธ์„ ๋ฐ˜์˜ํ•œ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ์ด ์ถ•์€ ์‚ฌ๋ผ์ง€์ง€ ์•Š๊ณ  **ํŠธ์œˆ์— ๋‚จ์•„ ์ด๋ฆ„์„ ๋ฐ”๊ฟจ๋‹ค.** ๋‚จ๋Š” ์ด์œ : ใ€Œ์ž๊ธฐ ์ €๋„์„ ์ž‡๋Š”๊ฐ€ใ€๋Š” ์›๋ณธ์˜\n * ์„ฑ์งˆ์ด ์•„๋‹ˆ๋ผ **ํŠธ์œˆ๊ณผ ์ž๊ธฐ ๊ณผ๊ฑฐ์˜ ๊ด€๊ณ„**๋‹ค. ๊ฐ™์€ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ์›๋ณธ์„ ๋ณด๋Š” ๋‘ ํŠธ์œˆ์ด ํ•˜๋‚˜๋Š” ์ด์–ด๊ฐ€๊ณ \n * ํ•˜๋‚˜๋Š” ๋งค๋ฒˆ ์ฒ˜์Œ๋ถ€ํ„ฐ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค โ€” ์›๋ณธ์€ ๊ทธ ๋‘˜์„ ๊ตฌ๋ณ„ํ•˜์ง€ ๋ชปํ•œ๋‹ค.\n *\n * resync โ€” ์™ธ๋ถ€ ์‹ค๋ฌผ์—์„œ ๋‹ค์‹œ ์ฝ๋Š”๋‹ค(์›๋ณธ์ด ์ง„์‹ค์ด๋ฏ€๋กœ ์šฐ๋ฆฌ ๊ณผ๊ฑฐ๋ฅผ ์ด์–ด ๋ถ™์ด์ง€ ์•Š๋Š”๋‹ค).\n * resume โ€” ์ €๋„์„ ์ด์–ด ์„ธ์šด๋‹ค(์ด ํŠธ์œˆ์ด ๋‚ณ์€ ํƒ€์ž„๋ผ์ธ์ด ๊ณง ์‚ฌ์‹ค์ด๋‹ค).\n * reset โ€” ์ €๋„์„ ๋น„์šฐ๊ณ  ์”จ์•—๋ถ€ํ„ฐ ๋‹ค์‹œ ๋Œ๋ฆฐ๋‹ค(์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ์‹คํ—˜).\n *\n * โ”€โ”€ ๊ธฐ๋ณธ๊ฐ’์„ ๋‘์ง€ ์•Š๋Š”๋‹ค โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * ์˜ˆ์ „์—๋Š” ๋ฏธ์„ ์–ธ์ด ์กฐ์šฉํžˆ `sim-experiment`(=์ €๋„ ์ดˆ๊ธฐํ™”)๋กœ ๋–จ์–ด์กŒ๋‹ค. ๊ทธ ๊ด€์šฉ์€ ๊ฐ’์ด ํ•˜๋‚˜ ์–ด๊ธ‹๋‚˜๋Š”\n * ์ˆœ๊ฐ„ **์ €๋„์„ ์ง€์šฐ๋Š” ๊ธธ**์ด ๋œ๋‹ค โ€” ๊ฐœ๋ช… ๋’ค ์˜› ๊ฐ’์ด ๋‚จ์•„ ์žˆ๋Š” ํ–‰์„ ๊ทธ ๊ธธ๋กœ ์ฝ์œผ๋ฉด ์žฌ๊ธฐ๋™ ํ•œ ๋ฒˆ์—\n * ์ด๋ ฅ์ด ์‚ฌ๋ผ์ง„๋‹ค. ๊ทธ๋ž˜์„œ ๋ชจ๋ฅด๋Š” ๊ฐ’์€ **์˜ค๋ฅ˜๋ฅผ ๋‚ธ๋‹ค.** ๋ถ€๋ฅด๋Š” ์ชฝ์ด ์„ ์–ธํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ด ์ถ•์˜ ์š”์ ์ด๋‹ค.\n */\n\n/** ์žฌ๊ธฐ๋™ ์ •์ฑ… โ€” ์…‹๋ฟ์ด๋‹ค. */\nexport type RestartPolicy = 'resync' | 'resume' | 'reset'\n\nexport const RESTART_POLICIES: readonly RestartPolicy[] = ['resync', 'resume', 'reset'] as const\n\n/**\n * ์ €์žฅ๋œ ๊ฐ’์„ ์ •์ฑ…์œผ๋กœ ์ฝ๋Š”๋‹ค โ€” **๋ชจ๋ฅด๋ฉด ์˜ค๋ฅ˜๋ฅผ ๋‚ธ๋‹ค**(๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋ฉ”์šฐ์ง€ ์•Š๋Š”๋‹ค).\n *\n * ์˜› ์–ดํœ˜(`mirror`ยท`sim-world`ยท`sim-experiment`)๋ฅผ ์—ฌ๊ธฐ์„œ ๋ฒˆ์—ญํ•˜์ง€ ์•Š๋Š”๋‹ค: ๋ฒˆ์—ญ์„ ๋‘๋ฉด ์˜› ๊ฐ’์ด ์‚ด์•„๋‚จ๊ณ ,\n * ๊ทธ ๊ฐ’์ด ๋‹ค์‹œ ์–ด๋”˜๊ฐ€์— ์ €์žฅ๋œ๋‹ค. ์ €์žฅ๋œ ๊ฐ’์€ **ํ•œ ๋ฒˆ ์˜ฎ๊ธฐ๊ณ **(๋ฐ์ดํ„ฐ ์ด๊ด€) ์ฝ”๋“œ๋Š” ์ƒˆ ์–ดํœ˜๋งŒ ์•ˆ๋‹ค.\n * ๊ทธ๋ž˜์„œ ์ด ํ•จ์ˆ˜๋Š” ์˜› ๊ฐ’์— ๋Œ€ํ•ด์„œ๋„ ์˜ค๋ฅ˜๋ฅผ ๋‚ด๋ฉฐ, ๋ฌด์—‡์œผ๋กœ ์˜ฎ๊ฒจ์•ผ ํ•˜๋Š”์ง€ ๋ฌธ์žฅ์œผ๋กœ ๋งํ•œ๋‹ค.\n */\nexport function readRestartPolicy(raw: unknown, where: string): RestartPolicy {\n const value = typeof raw === 'string' ? raw.trim() : ''\n if ((RESTART_POLICIES as readonly string[]).includes(value)) return value as RestartPolicy\n const legacy: Record<string, RestartPolicy> = { mirror: 'resync', 'sim-world': 'resume', 'sim-experiment': 'reset' }\n if (legacy[value]) {\n throw new Error(\n `${where}: restart policy \"${value}\" is the old vocabulary โ€” move the stored value to \"${legacy[value]}\" ` +\n '(ADR-0029 ยท plans/simulator-as-source.md ยง2). Nothing is translated at read time on purpose: a translation would keep the old value alive.'\n )\n }\n throw new Error(\n `${where}: restart policy ${value ? `\"${value}\"` : 'is missing'} โ€” declare one of ${RESTART_POLICIES.join(' | ')}. ` +\n 'There is no default: an unspecified policy used to fall through to \"reset\", which erases the journal on the next reboot.'\n )\n}\n\n/** ์ด ๊ฐ’์ด ์ •์ฑ…์ธ๊ฐ€ โ€” ์˜ค๋ฅ˜๋ฅผ ๋‚ด์ง€ ์•Š๊ณ  ๋ฌป๋Š” ์ž๋ฆฌ(ํ™”๋ฉดยท๊ฒ€์‚ฌ)๋ฅผ ์œ„ํ•ด. */\nexport function isRestartPolicy(raw: unknown): raw is RestartPolicy {\n return typeof raw === 'string' && (RESTART_POLICIES as readonly string[]).includes(raw)\n}\n"]}
@@ -26,7 +26,7 @@
26
26
  * `${domainId}:${instanceId}` โ€” ์ด ์ €์žฅ์†Œ๊ฐ€ ์ด๋ฏธ ์“ฐ๋Š” ๋ชจ์–‘์ด๋‹ค(`structureRevCache`ยท`measuredCache`).
27
27
  * ์ƒˆ ๋ชจ์–‘์„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. ํŒŒ์‹ฑ์€ **์ฒซ ๊ตฌ๋ถ„์ž**์—์„œ ์ž๋ฅด๋ฏ€๋กœ `instanceId` ์— `:` ๊ฐ€ ๋“ค์–ด ์žˆ์–ด๋„
28
28
  * ์•ˆ์ „ํ•˜๋‹ค(๋ ˆํผ๋Ÿฐ์Šค ์†Œ์Šค ์ด๋ฆ„์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค). ๋Œ€์‹  `domainId` ์— ๊ตฌ๋ถ„์ž๊ฐ€ ์žˆ์œผ๋ฉด ํ‚ค๊ฐ€ ๋ชจํ˜ธํ•ด์ง€๋ฏ€๋กœ
29
- * **๊ทธ๋•Œ๋Š” ๋˜์ง„๋‹ค** โ€” ์กฐ์šฉํžˆ ์ž˜๋ชป๋œ ํ‚ค๋ฅผ ๋งŒ๋“ค๋ฉด ๊ทธ๊ฒŒ ๊ณง ์ด ๊ฒฐํ•จ์˜ ์žฌ๋ฐœ์ด๋‹ค.
29
+ * **๊ทธ๋•Œ๋Š” ์˜ค๋ฅ˜๋ฅผ ๋‚ธ๋‹ค** โ€” ์กฐ์šฉํžˆ ์ž˜๋ชป๋œ ํ‚ค๋ฅผ ๋งŒ๋“ค๋ฉด ๊ทธ๊ฒŒ ๊ณง ์ด ๊ฒฐํ•จ์˜ ์žฌ๋ฐœ์ด๋‹ค.
30
30
  */
31
31
  Object.defineProperty(exports, "__esModule", { value: true });
32
32
  exports.RUNTIME_KEY_SEP = void 0;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-key.js","sourceRoot":"","sources":["../../server/engine/runtime-key.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;;;AAUH,gCAOC;AAGD,0CAIC;AAGD,gCAEC;AA3BD,kDAAkD;AACrC,QAAA,eAAe,GAAG,GAAG,CAAA;AAElC;;;;GAIG;AACH,SAAgB,UAAU,CAAC,QAAgB,EAAE,UAAkB;IAC7D,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAA;IAC9G,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;IACtE,IAAI,QAAQ,CAAC,QAAQ,CAAC,uBAAe,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,0CAA0C,uBAAe,kCAAkC,CAAC,CAAA;IAC9G,CAAC;IACD,OAAO,GAAG,QAAQ,GAAG,uBAAe,GAAG,UAAU,EAAE,CAAA;AACrD,CAAC;AAED,iDAAiD;AACjD,SAAgB,eAAe,CAAC,GAAW;IACzC,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,uBAAe,CAAC,CAAA;IACvC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,wBAAwB,CAAC,CAAA;IACvG,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAA;AACtE,CAAC;AAED,iDAAiD;AACjD,SAAgB,UAAU,CAAC,GAAW,EAAE,QAAgB;IACtD,OAAO,CAAC,CAAC,QAAQ,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,uBAAe,EAAE,CAAC,CAAA;AACtE,CAAC","sourcesContent":["/*\n * ๋Ÿฐํƒ€์ž„ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ํ‚ค โ€” **ํŠธ์œˆ์˜ ์ •์ฒด์„ฑ์€ `(๋„๋ฉ”์ธ, ์ธ์Šคํ„ด์Šค id)` ๋‹ค.** ์ˆœ์ˆ˜.\n *\n * โ”€โ”€ ์™œ ์žˆ๋‚˜ (2026-08-06 ํ…Œ๋„ŒํŠธ ๊ฒฉ๋ฆฌ ์ „์ˆ˜ ํ™•์ธ) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * `TwinEngine.instances` ์™€ `recovered` ๊ฐ€ **`instanceId` ํ•˜๋‚˜๋กœ** ํ‚ค๋ฅผ ์žก๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ DB ์œ ์ผ์„ฑ์€\n * `[domain, instanceId]` ์ด๊ณ (`TwinInstance` ์ธ๋ฑ์Šค) ํŠธ์œˆ์˜ ์ •์ฒด์„ฑ๋„ ๊ทธ์ชฝ์ด๋‹ค. ์ฆ‰ ๋Ÿฐํƒ€์ž„ ๋งต๋งŒ **์ „์—ญ\n * ์ด๋ฆ„ ๊ณต๊ฐ„**์ด์—ˆ๋‹ค.\n *\n * **์ถฉ๋Œ์€ ์ด๋ก ์ด ์•„๋‹ˆ๋‹ค.** ๋ ˆํผ๋Ÿฐ์Šค ๊ฒฝ๋กœ๊ฐ€ `instanceId` ๋กœ **๋ ˆํผ๋Ÿฐ์Šค ์†Œ์Šค ์ด๋ฆ„**์„ ์“ด๋‹ค\n * (`sap-ewm-1710`). ๋ฒค๋” ์‹œ์Šคํ…œ ์ด๋ฆ„์€ ํ…Œ๋„ŒํŠธ๊ฐ€ **๊ณต์œ ํ•˜๋Š” ์–ดํœ˜**๋ผ, ๋‘ ํ…Œ๋„ŒํŠธ๊ฐ€ ๊ฐ™์€ ์‹œ์Šคํ…œ์—\n * ์—ฐ๊ฒฐํ•˜๋ฉด ๊ฐ™์€ id ๊ฐ€ ๋œ๋‹ค โ€” ๋“œ๋ฌธ ์‚ฌ๊ณ ๊ฐ€ ์•„๋‹ˆ๋ผ ์˜ˆ์ƒ๋˜๋Š” ๊ฒฝ์šฐ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ๋ฌด์—‡์ด ์–ด๊ธ‹๋‚ฌ๋‚˜:\n * ยท `startLive` ์˜ ์กฐ๊ธฐ ๋ฐ˜ํ™˜์ด A ์˜ ๋Ÿฐํƒ€์ž„์„ B ์—๊ฒŒ ๋Œ๋ ค์ฃผ๊ณ  `ingestLive` ๋Š” ๋„๋ฉ”์ธ์„ ํ™•์ธํ•˜์ง€ ์•Š์•„\n * **B ์˜ ๋ผ์ด๋ธŒ ์ด๋ฒคํŠธ๊ฐ€ A ์˜ ์ปค๋„์— ์ ์šฉ**๋  ์ˆ˜ ์žˆ์—ˆ๋‹ค.\n * ยท `recovered` ๊ฐ€ ๊ฒน์น˜๋ฉด ์›œ์Šคํƒ€ํŠธ ์”จ์•—์ด **๋‚จ์˜ ์Šค๋ƒ…์ƒท**์ด ๋˜์–ด ์žฌ๊ณ ๊ฐ€ ์„ž์ธ๋‹ค.\n * ยท `start`/`stop` ์ด ๋‚จ์˜ ๋Ÿฐํƒ€์ž„์„ ์ง‘์œผ๋ฏ€๋กœ B ๋Š” \"๊ธฐ๋™๋จ\" ์„ ๋ฐ›๊ณ ๋„ ์ดํ›„ ์ „๋ถ€ ๊ฑฐ๋ถ€๋๋‹ค.\n *\n * ์ด ๋ถ€๋ฅ˜๋Š” **์ด๋ฏธ ํ•œ ๋ฒˆ ๋ฌผ์—ˆ๋‹ค** โ€” `twin-lifecycle-mutation.ts` ์ฃผ์„์ด ์ฆ์–ธํ•œ๋‹ค: \"๊ณผ๊ฑฐ์—”\n * `Object.keys(TwinEngine.instances)` ๋กœ ์ „์—ญ ๋ฐ˜ํ™˜ โ†’ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ ํŠธ์œˆ์ด ์ƒˆ๋˜ ๋ฒ„๊ทธ.\" ๊ทธ ์ž๋ฆฌ๋งŒ ๊ณ ์ณค๋‹ค.\n * ๊ทธ๋ž˜์„œ ์ด๋ฒˆ์—๋Š” ๊ฐ€๋“œ๋ฅผ ๋” ๋ถ™์ด์ง€ ์•Š๊ณ  **ํ‚ค๋ฅผ ๊ณ ์นœ๋‹ค** โ€” ์ €์ˆ˜์ค€ ๋ฉ”์„œ๋“œ๊ฐ€ `domainId` ๋ฅผ ๋ฐ›๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด\n * ์š”์ ์ด๋‹ค. \"๋ˆ„๊ตฌ์˜ ํŠธ์œˆ์ธ๊ฐ€\" ๋ฅผ ๋งํ•˜์ง€ ์•Š๊ณ ๋Š” ๋งŒ์งˆ ์ˆ˜ ์—†๋‹ค.\n *\n * โ”€โ”€ ๊ตฌ๋ถ„์ž ๊ทœ์•ฝ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * `${domainId}:${instanceId}` โ€” ์ด ์ €์žฅ์†Œ๊ฐ€ ์ด๋ฏธ ์“ฐ๋Š” ๋ชจ์–‘์ด๋‹ค(`structureRevCache`ยท`measuredCache`).\n * ์ƒˆ ๋ชจ์–‘์„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. ํŒŒ์‹ฑ์€ **์ฒซ ๊ตฌ๋ถ„์ž**์—์„œ ์ž๋ฅด๋ฏ€๋กœ `instanceId` ์— `:` ๊ฐ€ ๋“ค์–ด ์žˆ์–ด๋„\n * ์•ˆ์ „ํ•˜๋‹ค(๋ ˆํผ๋Ÿฐ์Šค ์†Œ์Šค ์ด๋ฆ„์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค). ๋Œ€์‹  `domainId` ์— ๊ตฌ๋ถ„์ž๊ฐ€ ์žˆ์œผ๋ฉด ํ‚ค๊ฐ€ ๋ชจํ˜ธํ•ด์ง€๋ฏ€๋กœ\n * **๊ทธ๋•Œ๋Š” ๋˜์ง„๋‹ค** โ€” ์กฐ์šฉํžˆ ์ž˜๋ชป๋œ ํ‚ค๋ฅผ ๋งŒ๋“ค๋ฉด ๊ทธ๊ฒŒ ๊ณง ์ด ๊ฒฐํ•จ์˜ ์žฌ๋ฐœ์ด๋‹ค.\n */\n\n/** ๋„๋ฉ”์ธ๊ณผ ์ธ์Šคํ„ด์Šค id ๋ฅผ ์ž‡๋Š” ๋ฌธ์ž โ€” ์ €์žฅ์†Œ์˜ ๊ธฐ์กด ์บ์‹œ ํ‚ค์™€ ๊ฐ™์€ ๋ชจ์–‘. */\nexport const RUNTIME_KEY_SEP = ':'\n\n/**\n * ๋Ÿฐํƒ€์ž„ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ํ‚ค.\n *\n * @throws ๋„๋ฉ”์ธ id ๊ฐ€ ๋น„์—ˆ๊ฑฐ๋‚˜ ๊ตฌ๋ถ„์ž๋ฅผ ๋‹ด๊ณ  ์žˆ์œผ๋ฉด(ํ‚ค๊ฐ€ ๋ชจํ˜ธํ•ด์ง„๋‹ค). ์ธ์Šคํ„ด์Šค id ๊ฐ€ ๋น„์—ˆ์œผ๋ฉด.\n */\nexport function runtimeKey(domainId: string, instanceId: string): string {\n if (!domainId) throw new Error('runtimeKey: domainId is required โ€” a twin runtime always belongs to a tenant')\n if (!instanceId) throw new Error('runtimeKey: instanceId is required')\n if (domainId.includes(RUNTIME_KEY_SEP)) {\n throw new Error(`runtimeKey: domainId must not contain \"${RUNTIME_KEY_SEP}\" (would make the key ambiguous)`)\n }\n return `${domainId}${RUNTIME_KEY_SEP}${instanceId}`\n}\n\n/** ํ‚ค๋ฅผ ๋˜๋Œ๋ฆฐ๋‹ค โ€” ์ฒซ ๊ตฌ๋ถ„์ž์—์„œ ์ž๋ฅธ๋‹ค(์ธ์Šคํ„ด์Šค id ์•ˆ์˜ ๊ตฌ๋ถ„์ž๋Š” ๋ณด์กด). */\nexport function parseRuntimeKey(key: string): { domainId: string; instanceId: string } {\n const at = key.indexOf(RUNTIME_KEY_SEP)\n if (at <= 0 || at === key.length - 1) throw new Error(`parseRuntimeKey: \"${key}\" is not a runtime key`)\n return { domainId: key.slice(0, at), instanceId: key.slice(at + 1) }\n}\n\n/** ์ด ํ‚ค๊ฐ€ ์ด ํ…Œ๋„ŒํŠธ์˜ ๊ฒƒ์ธ๊ฐ€ โ€” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ฅผ ์กฐํšŒํ•  ๋•Œ ๋„๋ฉ”์ธ์œผ๋กœ ๊ฑธ๋Ÿฌ๋‚ธ๋‹ค. */\nexport function isOfDomain(key: string, domainId: string): boolean {\n return !!domainId && key.startsWith(`${domainId}${RUNTIME_KEY_SEP}`)\n}\n"]}
1
+ {"version":3,"file":"runtime-key.js","sourceRoot":"","sources":["../../server/engine/runtime-key.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;;;AAUH,gCAOC;AAGD,0CAIC;AAGD,gCAEC;AA3BD,kDAAkD;AACrC,QAAA,eAAe,GAAG,GAAG,CAAA;AAElC;;;;GAIG;AACH,SAAgB,UAAU,CAAC,QAAgB,EAAE,UAAkB;IAC7D,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAA;IAC9G,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;IACtE,IAAI,QAAQ,CAAC,QAAQ,CAAC,uBAAe,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,0CAA0C,uBAAe,kCAAkC,CAAC,CAAA;IAC9G,CAAC;IACD,OAAO,GAAG,QAAQ,GAAG,uBAAe,GAAG,UAAU,EAAE,CAAA;AACrD,CAAC;AAED,iDAAiD;AACjD,SAAgB,eAAe,CAAC,GAAW;IACzC,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,uBAAe,CAAC,CAAA;IACvC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,wBAAwB,CAAC,CAAA;IACvG,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAA;AACtE,CAAC;AAED,iDAAiD;AACjD,SAAgB,UAAU,CAAC,GAAW,EAAE,QAAgB;IACtD,OAAO,CAAC,CAAC,QAAQ,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,uBAAe,EAAE,CAAC,CAAA;AACtE,CAAC","sourcesContent":["/*\n * ๋Ÿฐํƒ€์ž„ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ํ‚ค โ€” **ํŠธ์œˆ์˜ ์ •์ฒด์„ฑ์€ `(๋„๋ฉ”์ธ, ์ธ์Šคํ„ด์Šค id)` ๋‹ค.** ์ˆœ์ˆ˜.\n *\n * โ”€โ”€ ์™œ ์žˆ๋‚˜ (2026-08-06 ํ…Œ๋„ŒํŠธ ๊ฒฉ๋ฆฌ ์ „์ˆ˜ ํ™•์ธ) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * `TwinEngine.instances` ์™€ `recovered` ๊ฐ€ **`instanceId` ํ•˜๋‚˜๋กœ** ํ‚ค๋ฅผ ์žก๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ DB ์œ ์ผ์„ฑ์€\n * `[domain, instanceId]` ์ด๊ณ (`TwinInstance` ์ธ๋ฑ์Šค) ํŠธ์œˆ์˜ ์ •์ฒด์„ฑ๋„ ๊ทธ์ชฝ์ด๋‹ค. ์ฆ‰ ๋Ÿฐํƒ€์ž„ ๋งต๋งŒ **์ „์—ญ\n * ์ด๋ฆ„ ๊ณต๊ฐ„**์ด์—ˆ๋‹ค.\n *\n * **์ถฉ๋Œ์€ ์ด๋ก ์ด ์•„๋‹ˆ๋‹ค.** ๋ ˆํผ๋Ÿฐ์Šค ๊ฒฝ๋กœ๊ฐ€ `instanceId` ๋กœ **๋ ˆํผ๋Ÿฐ์Šค ์†Œ์Šค ์ด๋ฆ„**์„ ์“ด๋‹ค\n * (`sap-ewm-1710`). ๋ฒค๋” ์‹œ์Šคํ…œ ์ด๋ฆ„์€ ํ…Œ๋„ŒํŠธ๊ฐ€ **๊ณต์œ ํ•˜๋Š” ์–ดํœ˜**๋ผ, ๋‘ ํ…Œ๋„ŒํŠธ๊ฐ€ ๊ฐ™์€ ์‹œ์Šคํ…œ์—\n * ์—ฐ๊ฒฐํ•˜๋ฉด ๊ฐ™์€ id ๊ฐ€ ๋œ๋‹ค โ€” ๋“œ๋ฌธ ์‚ฌ๊ณ ๊ฐ€ ์•„๋‹ˆ๋ผ ์˜ˆ์ƒ๋˜๋Š” ๊ฒฝ์šฐ๋‹ค.\n *\n * ๊ทธ๋ž˜์„œ ๋ฌด์—‡์ด ์–ด๊ธ‹๋‚ฌ๋‚˜:\n * ยท `startLive` ์˜ ์กฐ๊ธฐ ๋ฐ˜ํ™˜์ด A ์˜ ๋Ÿฐํƒ€์ž„์„ B ์—๊ฒŒ ๋Œ๋ ค์ฃผ๊ณ  `ingestLive` ๋Š” ๋„๋ฉ”์ธ์„ ํ™•์ธํ•˜์ง€ ์•Š์•„\n * **B ์˜ ๋ผ์ด๋ธŒ ์ด๋ฒคํŠธ๊ฐ€ A ์˜ ์ปค๋„์— ์ ์šฉ**๋  ์ˆ˜ ์žˆ์—ˆ๋‹ค.\n * ยท `recovered` ๊ฐ€ ๊ฒน์น˜๋ฉด ์›œ์Šคํƒ€ํŠธ ์”จ์•—์ด **๋‚จ์˜ ์Šค๋ƒ…์ƒท**์ด ๋˜์–ด ์žฌ๊ณ ๊ฐ€ ์„ž์ธ๋‹ค.\n * ยท `start`/`stop` ์ด ๋‚จ์˜ ๋Ÿฐํƒ€์ž„์„ ์ง‘์œผ๋ฏ€๋กœ B ๋Š” \"๊ธฐ๋™๋จ\" ์„ ๋ฐ›๊ณ ๋„ ์ดํ›„ ์ „๋ถ€ ๊ฑฐ๋ถ€๋๋‹ค.\n *\n * ์ด ๋ถ€๋ฅ˜๋Š” **์ด๋ฏธ ํ•œ ๋ฒˆ ๋ฌผ์—ˆ๋‹ค** โ€” `twin-lifecycle-mutation.ts` ์ฃผ์„์ด ์ฆ์–ธํ•œ๋‹ค: \"๊ณผ๊ฑฐ์—”\n * `Object.keys(TwinEngine.instances)` ๋กœ ์ „์—ญ ๋ฐ˜ํ™˜ โ†’ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ ํŠธ์œˆ์ด ์ƒˆ๋˜ ๋ฒ„๊ทธ.\" ๊ทธ ์ž๋ฆฌ๋งŒ ๊ณ ์ณค๋‹ค.\n * ๊ทธ๋ž˜์„œ ์ด๋ฒˆ์—๋Š” ๊ฐ€๋“œ๋ฅผ ๋” ๋ถ™์ด์ง€ ์•Š๊ณ  **ํ‚ค๋ฅผ ๊ณ ์นœ๋‹ค** โ€” ์ €์ˆ˜์ค€ ๋ฉ”์„œ๋“œ๊ฐ€ `domainId` ๋ฅผ ๋ฐ›๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด\n * ์š”์ ์ด๋‹ค. \"๋ˆ„๊ตฌ์˜ ํŠธ์œˆ์ธ๊ฐ€\" ๋ฅผ ๋งํ•˜์ง€ ์•Š๊ณ ๋Š” ๋งŒ์งˆ ์ˆ˜ ์—†๋‹ค.\n *\n * โ”€โ”€ ๊ตฌ๋ถ„์ž ๊ทœ์•ฝ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n * `${domainId}:${instanceId}` โ€” ์ด ์ €์žฅ์†Œ๊ฐ€ ์ด๋ฏธ ์“ฐ๋Š” ๋ชจ์–‘์ด๋‹ค(`structureRevCache`ยท`measuredCache`).\n * ์ƒˆ ๋ชจ์–‘์„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. ํŒŒ์‹ฑ์€ **์ฒซ ๊ตฌ๋ถ„์ž**์—์„œ ์ž๋ฅด๋ฏ€๋กœ `instanceId` ์— `:` ๊ฐ€ ๋“ค์–ด ์žˆ์–ด๋„\n * ์•ˆ์ „ํ•˜๋‹ค(๋ ˆํผ๋Ÿฐ์Šค ์†Œ์Šค ์ด๋ฆ„์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค). ๋Œ€์‹  `domainId` ์— ๊ตฌ๋ถ„์ž๊ฐ€ ์žˆ์œผ๋ฉด ํ‚ค๊ฐ€ ๋ชจํ˜ธํ•ด์ง€๋ฏ€๋กœ\n * **๊ทธ๋•Œ๋Š” ์˜ค๋ฅ˜๋ฅผ ๋‚ธ๋‹ค** โ€” ์กฐ์šฉํžˆ ์ž˜๋ชป๋œ ํ‚ค๋ฅผ ๋งŒ๋“ค๋ฉด ๊ทธ๊ฒŒ ๊ณง ์ด ๊ฒฐํ•จ์˜ ์žฌ๋ฐœ์ด๋‹ค.\n */\n\n/** ๋„๋ฉ”์ธ๊ณผ ์ธ์Šคํ„ด์Šค id ๋ฅผ ์ž‡๋Š” ๋ฌธ์ž โ€” ์ €์žฅ์†Œ์˜ ๊ธฐ์กด ์บ์‹œ ํ‚ค์™€ ๊ฐ™์€ ๋ชจ์–‘. */\nexport const RUNTIME_KEY_SEP = ':'\n\n/**\n * ๋Ÿฐํƒ€์ž„ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ํ‚ค.\n *\n * @throws ๋„๋ฉ”์ธ id ๊ฐ€ ๋น„์—ˆ๊ฑฐ๋‚˜ ๊ตฌ๋ถ„์ž๋ฅผ ๋‹ด๊ณ  ์žˆ์œผ๋ฉด(ํ‚ค๊ฐ€ ๋ชจํ˜ธํ•ด์ง„๋‹ค). ์ธ์Šคํ„ด์Šค id ๊ฐ€ ๋น„์—ˆ์œผ๋ฉด.\n */\nexport function runtimeKey(domainId: string, instanceId: string): string {\n if (!domainId) throw new Error('runtimeKey: domainId is required โ€” a twin runtime always belongs to a tenant')\n if (!instanceId) throw new Error('runtimeKey: instanceId is required')\n if (domainId.includes(RUNTIME_KEY_SEP)) {\n throw new Error(`runtimeKey: domainId must not contain \"${RUNTIME_KEY_SEP}\" (would make the key ambiguous)`)\n }\n return `${domainId}${RUNTIME_KEY_SEP}${instanceId}`\n}\n\n/** ํ‚ค๋ฅผ ๋˜๋Œ๋ฆฐ๋‹ค โ€” ์ฒซ ๊ตฌ๋ถ„์ž์—์„œ ์ž๋ฅธ๋‹ค(์ธ์Šคํ„ด์Šค id ์•ˆ์˜ ๊ตฌ๋ถ„์ž๋Š” ๋ณด์กด). */\nexport function parseRuntimeKey(key: string): { domainId: string; instanceId: string } {\n const at = key.indexOf(RUNTIME_KEY_SEP)\n if (at <= 0 || at === key.length - 1) throw new Error(`parseRuntimeKey: \"${key}\" is not a runtime key`)\n return { domainId: key.slice(0, at), instanceId: key.slice(at + 1) }\n}\n\n/** ์ด ํ‚ค๊ฐ€ ์ด ํ…Œ๋„ŒํŠธ์˜ ๊ฒƒ์ธ๊ฐ€ โ€” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ฅผ ์กฐํšŒํ•  ๋•Œ ๋„๋ฉ”์ธ์œผ๋กœ ๊ฑธ๋Ÿฌ๋‚ธ๋‹ค. */\nexport function isOfDomain(key: string, domainId: string): boolean {\n return !!domainId && key.startsWith(`${domainId}${RUNTIME_KEY_SEP}`)\n}\n"]}