gaesup-world 1.0.5 → 1.0.6

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 (215) hide show
  1. package/README.md +99 -20
  2. package/dist/EventBus-Ck0Dwee2.js +33 -0
  3. package/dist/EventBus-DjA75MWC.cjs +1 -0
  4. package/dist/admin.cjs +1 -1
  5. package/dist/admin.js +66 -30
  6. package/dist/{assetStore-BuE4mh1C.cjs → assetStore-DVPge_2j.cjs} +1 -1
  7. package/dist/{assetStore-2bI2BPCn.js → assetStore-mAClONjR.js} +92 -35
  8. package/dist/assets.cjs +1 -1
  9. package/dist/assets.d.cts +9 -0
  10. package/dist/assets.d.ts +9 -0
  11. package/dist/assets.js +20 -10
  12. package/dist/authority-BOPCXUrV.cjs +1 -0
  13. package/dist/authority-CysRQudy.js +134 -0
  14. package/dist/blueprints-editor.cjs +1 -1
  15. package/dist/blueprints-editor.js +4 -4
  16. package/dist/blueprints.cjs +1 -1
  17. package/dist/blueprints.js +817 -21
  18. package/dist/core/assets/stores/assetStore.d.ts +2 -1
  19. package/dist/core/assets/types.d.ts +11 -0
  20. package/dist/core/audio/index.d.ts +2 -0
  21. package/dist/core/audio/plugin.d.ts +11 -0
  22. package/dist/core/boilerplate/hooks/useEntity.d.ts +2 -0
  23. package/dist/core/building/components/BuildingNavigationObstacleDriver/index.d.ts +8 -0
  24. package/dist/core/building/components/BuildingUI/index.d.ts +8 -1
  25. package/dist/core/building/index.d.ts +2 -0
  26. package/dist/core/building/navigation.d.ts +18 -0
  27. package/dist/core/building/plugin.d.ts +24 -0
  28. package/dist/core/camera/plugin.d.ts +14 -0
  29. package/dist/core/catalog/index.d.ts +2 -0
  30. package/dist/core/catalog/plugin.d.ts +10 -0
  31. package/dist/core/character/index.d.ts +2 -0
  32. package/dist/core/character/plugin.d.ts +10 -0
  33. package/dist/core/content/index.d.ts +3 -2
  34. package/dist/core/content/loader.d.ts +1 -0
  35. package/dist/core/content/types.d.ts +8 -0
  36. package/dist/core/crafting/index.d.ts +2 -0
  37. package/dist/core/crafting/plugin.d.ts +10 -0
  38. package/dist/core/economy/index.d.ts +2 -0
  39. package/dist/core/economy/plugin.d.ts +15 -0
  40. package/dist/core/editor/components/EditorLayout/index.d.ts +3 -1
  41. package/dist/core/editor/components/EditorLayout/types.d.ts +9 -1
  42. package/dist/core/editor/components/panels/BuildingPanel/NPCPanel.d.ts +1 -1
  43. package/dist/core/editor/components/panels/BuildingPanel/index.d.ts +9 -1
  44. package/dist/core/editor/components/panels/index.d.ts +1 -0
  45. package/dist/core/editor/index.d.ts +2 -1
  46. package/dist/core/events/index.d.ts +2 -0
  47. package/dist/core/events/plugin.d.ts +10 -0
  48. package/dist/core/farming/index.d.ts +2 -0
  49. package/dist/core/farming/plugin.d.ts +10 -0
  50. package/dist/core/hooks/useClicker/types.d.ts +8 -0
  51. package/dist/core/i18n/index.d.ts +2 -0
  52. package/dist/core/i18n/plugin.d.ts +10 -0
  53. package/dist/core/index.d.ts +4 -3
  54. package/dist/core/input/touch/components/TouchControls/index.d.ts +2 -2
  55. package/dist/core/interactions/bridge/InteractionBridge.d.ts +10 -2
  56. package/dist/core/interactions/components/ControllerWrapper/index.d.ts +2 -0
  57. package/dist/core/interactions/components/GroundClicker/index.d.ts +5 -1
  58. package/dist/core/interactions/core/adapter.d.ts +39 -2
  59. package/dist/core/interactions/hooks/index.d.ts +1 -0
  60. package/dist/core/interactions/hooks/useInputBackend.d.ts +4 -0
  61. package/dist/core/inventory/index.d.ts +2 -0
  62. package/dist/core/inventory/plugin.d.ts +10 -0
  63. package/dist/core/mail/index.d.ts +2 -0
  64. package/dist/core/mail/plugin.d.ts +10 -0
  65. package/dist/core/motions/core/movement/DirectionComponent.d.ts +6 -2
  66. package/dist/core/motions/core/movement/ImpulseComponent.d.ts +8 -4
  67. package/dist/core/motions/hooks/teleportEvents.d.ts +3 -0
  68. package/dist/core/motions/hooks/useInteractionSystem.d.ts +1 -1
  69. package/dist/core/motions/hooks/usePhysicsBridge.d.ts +4 -2
  70. package/dist/core/motions/plugin.d.ts +13 -5
  71. package/dist/core/motions/types.d.ts +2 -1
  72. package/dist/core/navigation/ClickNavigationRoute.d.ts +14 -0
  73. package/dist/core/navigation/NPCNavigationAdapter.d.ts +19 -0
  74. package/dist/core/navigation/NavigationObstacleRegistry.d.ts +11 -0
  75. package/dist/core/navigation/NavigationSystem.d.ts +53 -4
  76. package/dist/core/navigation/index.d.ts +5 -1
  77. package/dist/core/networks/adapter/authority.d.ts +41 -0
  78. package/dist/core/networks/adapter/contracts.d.ts +114 -0
  79. package/dist/core/networks/adapter/index.d.ts +4 -0
  80. package/dist/core/networks/adapter/types.d.ts +2 -1
  81. package/dist/core/networks/core/PlayerNetworkManager.d.ts +3 -9
  82. package/dist/core/networks/types/index.d.ts +0 -10
  83. package/dist/core/networks/visit/serializer.d.ts +4 -0
  84. package/dist/core/networks/visit/types.d.ts +3 -2
  85. package/dist/core/npc/index.d.ts +2 -0
  86. package/dist/core/npc/plugin.d.ts +22 -0
  87. package/dist/core/platform/index.d.ts +2 -0
  88. package/dist/core/platform/serverHost.d.ts +28 -0
  89. package/dist/core/plugins/ExtensionRegistry.d.ts +17 -7
  90. package/dist/core/plugins/PluginRegistry.d.ts +16 -2
  91. package/dist/core/plugins/index.d.ts +11 -2
  92. package/dist/core/plugins/runtimeFilter.d.ts +4 -0
  93. package/dist/core/plugins/samples.d.ts +4 -0
  94. package/dist/core/plugins/storeDomainPlugin.d.ts +33 -0
  95. package/dist/core/plugins/template.d.ts +3 -0
  96. package/dist/core/plugins/types.d.ts +86 -19
  97. package/dist/core/plugins/validation.d.ts +29 -0
  98. package/dist/core/quests/index.d.ts +2 -0
  99. package/dist/core/quests/plugin.d.ts +10 -0
  100. package/dist/core/relations/index.d.ts +2 -0
  101. package/dist/core/relations/plugin.d.ts +10 -0
  102. package/dist/core/runtime/context.d.ts +10 -0
  103. package/dist/core/runtime/createGaesupRuntime.d.ts +1 -0
  104. package/dist/core/runtime/index.d.ts +6 -2
  105. package/dist/core/runtime/saveDiagnostics.d.ts +22 -0
  106. package/dist/core/runtime/types.d.ts +8 -1
  107. package/dist/core/save/core/SaveSystem.d.ts +8 -2
  108. package/dist/core/save/index.d.ts +1 -1
  109. package/dist/core/save/types.d.ts +2 -1
  110. package/dist/core/scene/index.d.ts +2 -0
  111. package/dist/core/scene/plugin.d.ts +10 -0
  112. package/dist/core/stores/slices/physics/types.d.ts +1 -0
  113. package/dist/core/time/index.d.ts +2 -0
  114. package/dist/core/time/plugin.d.ts +11 -0
  115. package/dist/core/town/index.d.ts +2 -0
  116. package/dist/core/town/plugin.d.ts +10 -0
  117. package/dist/core/ui/components/RuntimeSaveDiagnosticsToaster/index.d.ts +14 -0
  118. package/dist/core/ui/components/index.d.ts +1 -0
  119. package/dist/core/weather/index.d.ts +2 -0
  120. package/dist/core/weather/plugin.d.ts +11 -0
  121. package/dist/core/world/components/WorldContainer/index.d.ts +2 -1
  122. package/dist/core/world/components/WorldContainer/types.d.ts +22 -32
  123. package/dist/core/world/persistence/SaveLoadManager.d.ts +26 -2
  124. package/dist/core/world/persistence/index.d.ts +2 -0
  125. package/dist/core/world/persistence/saveSystem.d.ts +9 -0
  126. package/dist/core/world/stores/persistenceSlice.d.ts +2 -5
  127. package/dist/editor.cjs +1 -1
  128. package/dist/editor.js +209 -175
  129. package/dist/eventsStore-Cipkf938.cjs +1 -0
  130. package/dist/eventsStore-DqmXNVEb.js +244 -0
  131. package/dist/gaesupStore-2zKBYTYo.cjs +1 -0
  132. package/dist/{gaesupStore-dfWoSPPs.js → gaesupStore-DTu0tYBp.js} +549 -336
  133. package/dist/{index-BZ556snc.js → index-BDZRjwya.js} +222 -203
  134. package/dist/index-BHG88mPD.cjs +1 -0
  135. package/dist/index-BSxxFxKH.cjs +1 -0
  136. package/dist/index-BeeDDnef.cjs +1 -0
  137. package/dist/index-BhSman4a.cjs +1 -0
  138. package/dist/index-Bhs66Y3W.cjs +1 -0
  139. package/dist/index-BovNs_Id.js +70 -0
  140. package/dist/index-Br4Wrsuh.cjs +1 -0
  141. package/dist/index-CUYKx17r.js +278 -0
  142. package/dist/index-CaAR2VHu.js +318 -0
  143. package/dist/index-DhBFMYdt.js +4185 -0
  144. package/dist/{index-CFlLUxmf.js → index-lk7RULwc.js} +139 -138
  145. package/dist/index-pzwedi0x.cjs +1 -0
  146. package/dist/index-zpBWDFlA.js +474 -0
  147. package/dist/index.cjs +2 -2
  148. package/dist/index.css +1 -1
  149. package/dist/index.d.cts +6 -13
  150. package/dist/index.d.ts +6 -13
  151. package/dist/index.js +2516 -2171
  152. package/dist/loader-C3ZwumCe.js +881 -0
  153. package/dist/loader-D7cEHkCq.cjs +1 -0
  154. package/dist/network.cjs +1 -1
  155. package/dist/network.js +2614 -770
  156. package/dist/plugin-BbeX8JG-.cjs +731 -0
  157. package/dist/plugin-CgAVv0Ix.js +20915 -0
  158. package/dist/plugins.cjs +1 -0
  159. package/dist/plugins.d.cts +1 -0
  160. package/dist/plugins.d.ts +1 -0
  161. package/dist/plugins.js +210 -0
  162. package/dist/runtime.cjs +1 -1
  163. package/dist/runtime.d.cts +0 -1
  164. package/dist/runtime.d.ts +0 -1
  165. package/dist/runtime.js +937 -730
  166. package/dist/runtimeFilter-CS35UPHd.js +408 -0
  167. package/dist/runtimeFilter-W6iMw1pL.cjs +1 -0
  168. package/dist/server-contracts.cjs +1 -1
  169. package/dist/server-contracts.js +81 -32
  170. package/dist/serverHost-C_bhbyiP.cjs +1 -0
  171. package/dist/serverHost-DEn-35k3.js +60 -0
  172. package/dist/sfe-CRsG1dTW.js +10 -0
  173. package/dist/sfe-CpgzdMyB.cjs +1 -0
  174. package/dist/snapshot-DRqZrbCu.cjs +1 -0
  175. package/dist/snapshot-OExk53wq.js +75 -0
  176. package/dist/{useSpawnFromBlueprint-BxXAW00x.js → useSpawnFromBlueprint-BxRHlpvL.js} +1 -1
  177. package/dist/{useSpawnFromBlueprint-CVdzF396.cjs → useSpawnFromBlueprint-aIQsqI3Q.cjs} +1 -1
  178. package/package.json +296 -285
  179. package/public/gltf/ally.glb +0 -0
  180. package/public/gltf/ally_body.glb +0 -0
  181. package/public/gltf/ally_cloth.glb +0 -0
  182. package/public/gltf/ally_cloth_rabbit.glb +0 -0
  183. package/public/gltf/ally_glass.glb +0 -0
  184. package/public/gltf/ally_hat.glb +0 -0
  185. package/dist/GrassDriver-D-GuF2yK.js +0 -20087
  186. package/dist/GrassDriver-DrBaLkN_.cjs +0 -731
  187. package/dist/authStore-CU_xZzJ7.js +0 -42
  188. package/dist/authStore-CrDnYNnL.cjs +0 -1
  189. package/dist/defaultConfig-2OMrPhjb.js +0 -2229
  190. package/dist/defaultConfig-JLajbigv.cjs +0 -1
  191. package/dist/eventsStore-5J9sZm-v.cjs +0 -1
  192. package/dist/eventsStore-Br8PKcCj.js +0 -83
  193. package/dist/gaesupStore-CE-oe63F.cjs +0 -1
  194. package/dist/index-9NFE0Shy.js +0 -333
  195. package/dist/index-B7fXJCKD.cjs +0 -1
  196. package/dist/index-BMp8klOJ.cjs +0 -1
  197. package/dist/index-BdDP0bwz.js +0 -548
  198. package/dist/index-CbBqaSwX.cjs +0 -1
  199. package/dist/index-DFB_CxUA.js +0 -4175
  200. package/dist/index-DFRQ1piJ.cjs +0 -1
  201. package/dist/index-DNd7pCC8.js +0 -69
  202. package/dist/index-Dl-51pXl.cjs +0 -1
  203. package/dist/index-GtwD8qWW.cjs +0 -1
  204. package/dist/questStore-Css-uoyW.js +0 -370
  205. package/dist/questStore-D4HDyJkV.cjs +0 -1
  206. package/dist/rbac-Bjx9pTbU.js +0 -42
  207. package/dist/rbac-N7h7zNl3.cjs +0 -1
  208. package/dist/registerComponents-BrKmE56h.js +0 -813
  209. package/dist/registerComponents-DGEaT7bV.cjs +0 -1
  210. package/dist/sfe-RrB92jNe.cjs +0 -1
  211. package/dist/sfe-uIb6H2wc.js +0 -824
  212. package/dist/templates-CmBSPiF_.js +0 -572
  213. package/dist/templates-eL763zpL.cjs +0 -1
  214. package/dist/toastStore-Dho0lQiS.cjs +0 -1
  215. package/dist/toastStore-z4vFobr9.js +0 -164
package/README.md CHANGED
@@ -25,7 +25,7 @@
25
25
 
26
26
  ## 설치
27
27
 
28
- 프로젝트에서 사용할 때는 `gaesup-world`와 React Three Fiber 계열 의존성을 함께 설치하면 됩니다.
28
+ 앱에서 사용할 때는 `gaesup-world`와 3D 런타임 peer dependency를 함께 설치합니다. React, Three.js, React Three Fiber는 앱 쪽에서 직접 버전을 관리하는 것이 안전합니다.
29
29
 
30
30
  ```bash
31
31
  npm install gaesup-world three react react-dom @react-three/fiber @react-three/drei @react-three/rapier
@@ -43,6 +43,13 @@ yarn add gaesup-world three react react-dom @react-three/fiber @react-three/drei
43
43
  pnpm add gaesup-world three react react-dom @react-three/fiber @react-three/drei @react-three/rapier
44
44
  ```
45
45
 
46
+ 선택 기능을 쓰는 경우에는 아래 패키지도 앱에 설치해 주세요.
47
+
48
+ - 후처리: `@react-three/postprocessing`
49
+ - 관리자 라우팅: `react-router-dom`
50
+ - 아이콘 UI: `react-icons`
51
+ - Rapier 직접 연동: `@dimforge/rapier3d`, `@dimforge/rapier3d-compat`
52
+
46
53
  ## 빠른 시작
47
54
 
48
55
  가장 기본적인 사용 예시는 아래와 같습니다.
@@ -72,6 +79,29 @@ export default function App() {
72
79
 
73
80
  ## 핵심 개념
74
81
 
82
+ ### 런타임과 플러그인
83
+
84
+ `createGaesupRuntime`은 카메라, 모션, 저장, NPC, 경제, 날씨 같은 도메인 플러그인을 한곳에 묶는 런타임 팩토리입니다. 앱이 필요한 도메인만 골라 붙일 수 있고, 각 플러그인은 서비스, 시스템, 저장 도메인, UI 확장을 등록합니다.
85
+
86
+ ```ts
87
+ import {
88
+ createGaesupRuntime,
89
+ createBuildingPlugin,
90
+ createCameraPlugin,
91
+ createInventoryPlugin,
92
+ } from 'gaesup-world';
93
+
94
+ const runtime = createGaesupRuntime({
95
+ plugins: [
96
+ createCameraPlugin(),
97
+ createBuildingPlugin(),
98
+ createInventoryPlugin(),
99
+ ],
100
+ });
101
+
102
+ await runtime.setup();
103
+ ```
104
+
75
105
  ### 월드 설정
76
106
 
77
107
  `GaesupWorld`는 월드 관련 설정을 store에 주입하는 루트 컴포넌트입니다.
@@ -114,6 +144,26 @@ export default function App() {
114
144
  - `blueprints`
115
145
  - `admin`
116
146
 
147
+ ### 저장 시스템
148
+
149
+ 새 기능은 `SaveSystem` 중심으로 저장 도메인을 등록하는 흐름을 권장합니다. 같은 key를 중복 등록하면 에러가 나도록 보호되어 있어, 여러 런타임이나 플러그인이 같은 저장 슬롯을 조용히 덮어쓰는 일을 피할 수 있습니다.
150
+
151
+ ```ts
152
+ import { SaveSystem } from 'gaesup-world';
153
+
154
+ const unregister = saveSystem.register({
155
+ key: 'inventory',
156
+ serialize: () => ({ items: [] }),
157
+ hydrate: (data) => {
158
+ // restore your store here
159
+ },
160
+ });
161
+
162
+ unregister();
163
+ ```
164
+
165
+ `SaveLoadManager`는 legacy world save와 파일 import/export helper로 남아 있습니다. `compress: true` 저장은 gzip 지원 브라우저에서는 gzip payload를 사용하고, 저장 목록에서도 timestamp와 metadata를 읽을 수 있습니다.
166
+
117
167
  ## 자주 쓰는 공개 API
118
168
 
119
169
  대표적으로 아래 항목들을 루트 엔트리에서 바로 import 할 수 있습니다.
@@ -187,7 +237,7 @@ export default function AdminPage() {
187
237
 
188
238
  ## 개발 환경 실행
189
239
 
190
- 이 저장소 자체를 로컬에서 실행할 때는 `pnpm` 기준으로 작업하는 것이 가장 자연스럽습니다.
240
+ 이 저장소 자체를 로컬에서 실행할 때는 `pnpm` 기준으로 작업하는 것이 가장 자연스럽습니다. Node 패키지 매니저가 섞이면 lockfile과 prepare 단계가 헷갈릴 수 있으니, 처음부터 `corepack pnpm ...` 형태로 맞추는 것을 권장합니다.
191
241
 
192
242
  ```bash
193
243
  corepack pnpm install
@@ -199,16 +249,15 @@ corepack pnpm dev
199
249
  ```bash
200
250
  corepack pnpm dev
201
251
  corepack pnpm build
202
- corepack pnpm exec vite build --mode esm
203
- corepack pnpm exec vite build
204
- corepack pnpm test -- --runInBand
205
252
  corepack pnpm lint
253
+ corepack pnpm test -- --runInBand
254
+ corepack pnpm exec publint
206
255
  ```
207
256
 
208
257
  참고:
209
258
 
210
- - 현재 Windows 환경에서는 `prepare` 스크립트가 `pnpm` PATH 설정에 따라 실패할 수 있습니다.
211
- - 이런 경우 `corepack pnpm ...` 형태로 실행하면 정상 동작합니다.
259
+ - `npm pack --dry-run`은 `prepare`를 실행하므로 `dist/`가 재생성됩니다.
260
+ - 배포 전에는 `corepack pnpm build`, `corepack pnpm lint`, `corepack pnpm test -- --runInBand`, `corepack pnpm exec publint`를 함께 확인하는 것이 좋습니다.
212
261
 
213
262
  ## 데모 앱
214
263
 
@@ -223,16 +272,34 @@ corepack pnpm lint
223
272
 
224
273
  최근 정리로 인해 `examples`는 가능하면 내부 소스 경로 대신 루트 public API를 사용하도록 맞춰져 있습니다.
225
274
 
275
+ ## 패키지 엔트리
276
+
277
+ 현재 공개 export는 아래 subpath를 기준으로 관리합니다.
278
+
279
+ - `gaesup-world`: 메인 런타임, 월드, 도메인 API
280
+ - `gaesup-world/admin`: 관리자 래퍼 UI
281
+ - `gaesup-world/blueprints`: 블루프린트 런타임 API
282
+ - `gaesup-world/blueprints/editor`: 블루프린트 편집 UI
283
+ - `gaesup-world/runtime`: 런타임 중심 API
284
+ - `gaesup-world/editor`: 에디터 API
285
+ - `gaesup-world/assets`: 에셋 API
286
+ - `gaesup-world/network`: 네트워크 API
287
+ - `gaesup-world/plugins`: 플러그인 API
288
+ - `gaesup-world/server-contracts`: 서버/클라이언트 command contract
289
+ - `gaesup-world/postprocessing`: 렌더링 후처리 API
290
+ - `gaesup-world/style.css`: 라이브러리 기본 스타일
291
+
292
+ `package.json`의 export map은 ESM/CJS와 `.d.ts`/`.d.cts` 타입 선언을 함께 제공합니다.
293
+
226
294
  ## 검증 상태
227
295
 
228
296
  최근 확인 기준:
229
297
 
230
- - `corepack pnpm exec vite build`: 성공
231
- - `corepack pnpm exec vite build --mode esm`: 성공
232
- - `corepack pnpm exec jest --runInBand --watchman=false`: 성공
233
298
  - `npm run build:types`: 성공
234
-
235
- 타입 선언 빌드는 현재 통과합니다.
299
+ - `npm run lint`: 성공
300
+ - `npm test -- --runInBand`: 성공
301
+ - `npm run build`: 성공
302
+ - `npx publint`: 성공
236
303
 
237
304
  ## 문서 안내
238
305
 
@@ -242,24 +309,36 @@ corepack pnpm lint
242
309
 
243
310
  도메인 문서:
244
311
 
245
- - [애니메이션](./docs/domain/ANIMATION.md)
246
312
  - [블루프린트](./docs/domain/BLUEPRINT.md)
247
313
  - [카메라](./docs/domain/CAMERA.md)
248
314
  - [모션](./docs/domain/MOTIONS.md)
249
- - [네트워크](./docs/domain/NETWORKS.md)
250
- - [보일러플레이트 구조](./docs/domain/BOILERPLATE_ARCHITECTURE.md)
251
-
252
- 계획 문서:
253
-
254
- - [MVP 계획](./docs/plan/MVP.md)
255
315
 
256
316
  가이드 문서:
257
317
 
258
318
  - [API 가이드](./docs/guide/API_GUIDE.md)
259
- - [레이어 가이드](./docs/guide/LAYER_GUIDE.md)
260
319
  - [성능 가이드](./docs/guide/PERFORMANCE_GUIDE.md)
261
320
  - [테스트 가이드](./docs/guide/TEST_GUIDE.md)
262
321
 
322
+ API 문서:
323
+
324
+ - [블루프린트 API](./docs/api/BLUEPRINT_API.md)
325
+ - [빌딩 API](./docs/api/BUILDING_API.md)
326
+ - [렌더링 API](./docs/api/RENDERING_API.md)
327
+ - [성능 API](./docs/api/PERFORMANCE_API.md)
328
+ - [WASM API](./docs/api/WASM_API.md)
329
+
330
+ 설정 문서:
331
+
332
+ - [블루프린트 설정](./docs/config/BLUEPRINT_CONFIG.md)
333
+ - [빌딩 설정](./docs/config/BUILDING_CONFIG.md)
334
+ - [카메라 설정](./docs/config/CAMERA_CONFIG.md)
335
+ - [물리 설정](./docs/config/PHYSICS_CONFIG.md)
336
+
337
+ 계획 문서:
338
+
339
+ - [Universal Web Game Library 계획](./docs/plan/UNIVERSAL_WEB_GAME_LIBRARY.md)
340
+ - [테스트 가이드](./docs/guide/TEST_GUIDE.md)
341
+
263
342
  ## 패키지 정보
264
343
 
265
344
  - npm: https://www.npmjs.com/package/gaesup-world
@@ -0,0 +1,33 @@
1
+ class h {
2
+ handlers = /* @__PURE__ */ new Map();
3
+ on(s, e) {
4
+ const r = this.handlers.get(s) ?? /* @__PURE__ */ new Set();
5
+ return r.add(e), this.handlers.set(s, r), () => this.off(s, e);
6
+ }
7
+ once(s, e) {
8
+ const r = (t) => {
9
+ this.off(s, r), e(t);
10
+ };
11
+ return this.on(s, r);
12
+ }
13
+ off(s, e) {
14
+ const r = this.handlers.get(s);
15
+ r && (r.delete(e), r.size === 0 && this.handlers.delete(s));
16
+ }
17
+ emit(s, e) {
18
+ const r = this.handlers.get(s);
19
+ if (r)
20
+ for (const t of Array.from(r))
21
+ t(e);
22
+ }
23
+ clear(s) {
24
+ if (s === void 0) {
25
+ this.handlers.clear();
26
+ return;
27
+ }
28
+ this.handlers.delete(s);
29
+ }
30
+ }
31
+ export {
32
+ h as I
33
+ };
@@ -0,0 +1 @@
1
+ "use strict";class n{handlers=new Map;on(s,e){const r=this.handlers.get(s)??new Set;return r.add(e),this.handlers.set(s,r),()=>this.off(s,e)}once(s,e){const r=t=>{this.off(s,r),e(t)};return this.on(s,r)}off(s,e){const r=this.handlers.get(s);r&&(r.delete(e),r.size===0&&this.handlers.delete(s))}emit(s,e){const r=this.handlers.get(s);if(r)for(const t of Array.from(r))t(e)}clear(s){if(s===void 0){this.handlers.clear();return}this.handlers.delete(s)}}exports.InMemoryEventBus=n;
package/dist/admin.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),c=require("react"),l=require("./authStore-CrDnYNnL.cjs"),d=require("zustand"),g=()=>{const[o,n]=c.useState(""),[e,t]=c.useState(""),[r,i]=c.useState(""),a=l.useAuthStore(u=>u.login),m=async u=>{u.preventDefault(),i(""),await a(o,e)||i("Invalid username or password")};return s.jsxs("div",{className:"login-container",children:[s.jsx("h1",{children:"Admin Login"}),s.jsxs("form",{onSubmit:m,className:"login-form",children:[s.jsx("input",{type:"text",value:o,onChange:u=>n(u.target.value),placeholder:"Username",className:"login-input",autoComplete:"username"}),s.jsx("input",{type:"password",value:e,onChange:u=>t(u.target.value),placeholder:"Password",className:"login-input",autoComplete:"current-password"}),s.jsx("button",{type:"submit",className:"login-button",children:"Login"}),r&&s.jsx("p",{className:"login-error",children:r})]})]})},p=({children:o,requireLogin:n=!0})=>{const e=l.useAuthStore(t=>t.isLoggedIn);return n&&!e?s.jsx(g,{}):s.jsx(s.Fragment,{children:o})},h=d.create((o,n)=>({toasts:[],timers:new Map,addToast:e=>{const t=Date.now().toString(),r={...e,id:t};o(a=>({toasts:[...a.toasts,r]}));const i=setTimeout(()=>{n().removeToast(t)},3e3);o(a=>(a.timers.set(t,i),{}))},addToastAsync:async e=>new Promise(t=>{n().addToast(e),t()}),removeToast:e=>{const{timers:t}=n(),r=t.get(e);r&&(clearTimeout(r),t.delete(e)),o(i=>({toasts:i.toasts.filter(a=>a.id!==e)}))}}));exports.useAuthStore=l.useAuthStore;exports.GaesupAdmin=p;exports.useToast=h;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),l=require("react"),d=require("zustand"),m=require("zustand/middleware"),c=d.create()(m.persist(e=>({isLoggedIn:!1,user:null,loading:!1,modal:{on:!1,type:"",file:-1,username:"",gltf_url:""},login:async(s,t)=>{e({loading:!0});try{return s==="admin"&&t==="password"?(e({isLoggedIn:!0,user:{username:s},loading:!1}),!0):(e({loading:!1}),!1)}catch{return e({loading:!1}),!1}},logout:()=>{e({isLoggedIn:!1,user:null})},setLoading:s=>{e({loading:s})},setModal:s=>{e({modal:s})}}),{name:"gaesup-admin-auth",partialize:e=>({isLoggedIn:e.isLoggedIn,user:e.user})})),p=()=>{const[e,s]=l.useState(""),[t,n]=l.useState(""),[o,u]=l.useState(""),r=c(i=>i.login),g=async i=>{i.preventDefault(),u(""),await r(e,t)||u("Invalid username or password")};return a.jsxs("div",{className:"login-container",children:[a.jsx("h1",{children:"Admin Login"}),a.jsxs("form",{onSubmit:g,className:"login-form",children:[a.jsx("input",{type:"text",value:e,onChange:i=>s(i.target.value),placeholder:"Username",className:"login-input",autoComplete:"username"}),a.jsx("input",{type:"password",value:t,onChange:i=>n(i.target.value),placeholder:"Password",className:"login-input",autoComplete:"current-password"}),a.jsx("button",{type:"submit",className:"login-button",children:"Login"}),o&&a.jsx("p",{className:"login-error",children:o})]})]})},f=({children:e,requireLogin:s=!0})=>{const t=c(n=>n.isLoggedIn);return s&&!t?a.jsx(p,{}):a.jsx(a.Fragment,{children:e})},h=d.create((e,s)=>({toasts:[],timers:new Map,addToast:t=>{const n=Date.now().toString(),o={...t,id:n};e(r=>({toasts:[...r.toasts,o]}));const u=setTimeout(()=>{s().removeToast(n)},3e3);e(r=>(r.timers.set(n,u),{}))},addToastAsync:async t=>new Promise(n=>{s().addToast(t),n()}),removeToast:t=>{const{timers:n}=s(),o=n.get(t);o&&(clearTimeout(o),n.delete(t)),e(u=>({toasts:u.toasts.filter(r=>r.id!==t)}))}}));exports.GaesupAdmin=f;exports.useAuthStore=c;exports.useToast=h;
package/dist/admin.js CHANGED
@@ -1,20 +1,56 @@
1
- import { jsxs as l, jsx as i, Fragment as d } from "react/jsx-runtime";
2
- import { useState as m } from "react";
3
- import { u } from "./authStore-CU_xZzJ7.js";
4
- import { create as p } from "zustand";
5
- const g = () => {
6
- const [s, o] = m(""), [e, t] = m(""), [n, c] = m(""), r = u((a) => a.login);
7
- return /* @__PURE__ */ l("div", { className: "login-container", children: [
1
+ import { jsxs as d, jsx as i, Fragment as m } from "react/jsx-runtime";
2
+ import { useState as u } from "react";
3
+ import { create as c } from "zustand";
4
+ import { persist as p } from "zustand/middleware";
5
+ const g = c()(
6
+ p(
7
+ (e) => ({
8
+ isLoggedIn: !1,
9
+ user: null,
10
+ loading: !1,
11
+ modal: {
12
+ on: !1,
13
+ type: "",
14
+ file: -1,
15
+ username: "",
16
+ gltf_url: ""
17
+ },
18
+ login: async (s, o) => {
19
+ e({ loading: !0 });
20
+ try {
21
+ return s === "admin" && o === "password" ? (e({ isLoggedIn: !0, user: { username: s }, loading: !1 }), !0) : (e({ loading: !1 }), !1);
22
+ } catch {
23
+ return e({ loading: !1 }), !1;
24
+ }
25
+ },
26
+ logout: () => {
27
+ e({ isLoggedIn: !1, user: null });
28
+ },
29
+ setLoading: (s) => {
30
+ e({ loading: s });
31
+ },
32
+ setModal: (s) => {
33
+ e({ modal: s });
34
+ }
35
+ }),
36
+ {
37
+ name: "gaesup-admin-auth",
38
+ partialize: (e) => ({ isLoggedIn: e.isLoggedIn, user: e.user })
39
+ }
40
+ )
41
+ ), f = () => {
42
+ const [e, s] = u(""), [o, t] = u(""), [n, l] = u(""), a = g((r) => r.login);
43
+ return /* @__PURE__ */ d("div", { className: "login-container", children: [
8
44
  /* @__PURE__ */ i("h1", { children: "Admin Login" }),
9
- /* @__PURE__ */ l("form", { onSubmit: async (a) => {
10
- a.preventDefault(), c(""), await r(s, e) || c("Invalid username or password");
45
+ /* @__PURE__ */ d("form", { onSubmit: async (r) => {
46
+ r.preventDefault(), l(""), await a(e, o) || l("Invalid username or password");
11
47
  }, className: "login-form", children: [
12
48
  /* @__PURE__ */ i(
13
49
  "input",
14
50
  {
15
51
  type: "text",
16
- value: s,
17
- onChange: (a) => o(a.target.value),
52
+ value: e,
53
+ onChange: (r) => s(r.target.value),
18
54
  placeholder: "Username",
19
55
  className: "login-input",
20
56
  autoComplete: "username"
@@ -24,8 +60,8 @@ const g = () => {
24
60
  "input",
25
61
  {
26
62
  type: "password",
27
- value: e,
28
- onChange: (a) => t(a.target.value),
63
+ value: o,
64
+ onChange: (r) => t(r.target.value),
29
65
  placeholder: "Password",
30
66
  className: "login-input",
31
67
  autoComplete: "current-password"
@@ -35,30 +71,30 @@ const g = () => {
35
71
  n && /* @__PURE__ */ i("p", { className: "login-error", children: n })
36
72
  ] })
37
73
  ] });
38
- }, y = ({ children: s, requireLogin: o = !0 }) => {
39
- const e = u((t) => t.isLoggedIn);
40
- return o && !e ? /* @__PURE__ */ i(g, {}) : /* @__PURE__ */ i(d, { children: s });
41
- }, N = p((s, o) => ({
74
+ }, I = ({ children: e, requireLogin: s = !0 }) => {
75
+ const o = g((t) => t.isLoggedIn);
76
+ return s && !o ? /* @__PURE__ */ i(f, {}) : /* @__PURE__ */ i(m, { children: e });
77
+ }, N = c((e, s) => ({
42
78
  toasts: [],
43
79
  timers: /* @__PURE__ */ new Map(),
44
- addToast: (e) => {
45
- const t = Date.now().toString(), n = { ...e, id: t };
46
- s((r) => ({ toasts: [...r.toasts, n] }));
47
- const c = setTimeout(() => {
48
- o().removeToast(t);
80
+ addToast: (o) => {
81
+ const t = Date.now().toString(), n = { ...o, id: t };
82
+ e((a) => ({ toasts: [...a.toasts, n] }));
83
+ const l = setTimeout(() => {
84
+ s().removeToast(t);
49
85
  }, 3e3);
50
- s((r) => (r.timers.set(t, c), {}));
86
+ e((a) => (a.timers.set(t, l), {}));
51
87
  },
52
- addToastAsync: async (e) => new Promise((t) => {
53
- o().addToast(e), t();
88
+ addToastAsync: async (o) => new Promise((t) => {
89
+ s().addToast(o), t();
54
90
  }),
55
- removeToast: (e) => {
56
- const { timers: t } = o(), n = t.get(e);
57
- n && (clearTimeout(n), t.delete(e)), s((c) => ({ toasts: c.toasts.filter((r) => r.id !== e) }));
91
+ removeToast: (o) => {
92
+ const { timers: t } = s(), n = t.get(o);
93
+ n && (clearTimeout(n), t.delete(o)), e((l) => ({ toasts: l.toasts.filter((a) => a.id !== o) }));
58
94
  }
59
95
  }));
60
96
  export {
61
- y as GaesupAdmin,
62
- u as useAuthStore,
97
+ I as GaesupAdmin,
98
+ g as useAuthStore,
63
99
  N as useToast
64
100
  };
@@ -1 +1 @@
1
- "use strict";const d=require("zustand"),l=[{id:"warrior-cloth-rabbit",name:"Rabbit Warrior Cloth",kind:"characterPart",slot:"top",url:"gltf/ally_cloth_rabbit.glb",tags:["starter","cloth"]},{id:"warrior-cloth-basic",name:"Basic Warrior Cloth",kind:"characterPart",slot:"top",url:"gltf/ally_cloth.glb",tags:["starter","cloth"]},{id:"ally-hat",name:"Ally Hat",kind:"characterPart",slot:"hat",url:"gltf/ally_hat.glb",tags:["starter","hat"]},{id:"ally-glasses",name:"Ally Glasses",kind:"characterPart",slot:"face",url:"gltf/ally_glass.glb",tags:["starter","face"]},{id:"starter-weapon-layer",name:"Starter Weapon Layer",kind:"weapon",slot:"weapon",url:"gltf/ally_cloth.glb",tags:["starter","weapon","placeholder"],metadata:{placeholder:!0}},{id:"wall-soft-brick",name:"Soft Brick Wall",kind:"wall",tags:["building","wall","brick"],colors:{primary:"#b8795f"},metadata:{material:"STANDARD",roughness:.72}},{id:"tile-warm-wood",name:"Warm Wood Tile",kind:"tile",tags:["building","tile","wood"],colors:{primary:"#8b5a35"},metadata:{material:"STANDARD",roughness:.58}},{id:"material-glass-blue",name:"Blue Glass",kind:"material",tags:["building","material","glass"],colors:{primary:"#9bd7ff"},metadata:{material:"GLASS",opacity:.45,transparent:!0,roughness:.1}},{id:"prop-door-basic",name:"Door",kind:"object3d",url:"gltf/props/door.glb",tags:["starter","building","prop","door","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-window-basic",name:"Window",kind:"object3d",url:"gltf/props/window.glb",tags:["starter","building","prop","window","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-fence-basic",name:"Fence",kind:"object3d",url:"gltf/props/fence.glb",tags:["starter","building","prop","fence","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-lamp-basic",name:"Lamp",kind:"object3d",url:"gltf/props/lamp.glb",tags:["starter","building","prop","lamp","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-chair-basic",name:"Chair",kind:"object3d",url:"gltf/props/chair.glb",tags:["starter","building","prop","chair","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-table-basic",name:"Table",kind:"object3d",url:"gltf/props/table.glb",tags:["starter","building","prop","table","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-bed-basic",name:"Bed",kind:"object3d",url:"gltf/props/bed.glb",tags:["starter","building","prop","bed","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-storage-basic",name:"Storage",kind:"object3d",url:"gltf/props/storage.glb",tags:["starter","building","prop","storage","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-mailbox-basic",name:"Mailbox",kind:"object3d",url:"gltf/props/mailbox.glb",tags:["starter","building","prop","mailbox","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-crafting-basic",name:"Crafting Station",kind:"object3d",url:"gltf/props/crafting.glb",tags:["starter","building","prop","crafting","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-shop-stall-basic",name:"Shop Stall",kind:"object3d",url:"gltf/props/shop-stall.glb",tags:["starter","building","prop","shop","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}}],n=e=>{const a={};for(const t of e)a[t.id]={...t};return a},p=(e,a)=>a?e.filter(t=>!(a.kind&&t.kind!==a.kind||a.slot&&t.slot!==a.slot||a.tag&&!t.tags?.includes(a.tag))):e,c=n(l),g=d.create((e,a)=>({records:c,ids:l.map(t=>t.id),isLoading:!1,error:null,selectedId:null,filter:{},setFilter:t=>e({filter:{...t}}),selectAsset:t=>e({selectedId:t}),registerAssets:t=>e(s=>{const r={...s.records},o=new Set(s.ids);for(const i of t)r[i.id]={...i},o.add(i.id);return{records:r,ids:Array.from(o)}}),loadAssets:async(t,s)=>{e({isLoading:!0,error:null});try{const r=await t.listAssets(s);a().registerAssets(r.length>0?r:l),e({isLoading:!1})}catch(r){a().registerAssets(l),e({isLoading:!1,error:r instanceof Error?r.message:"Failed to load assets"})}},getAsset:t=>a().records[t],listAssets:t=>{const s=a();return p(s.ids.map(r=>s.records[r]).filter(r=>!!r),t)},resetAssets:()=>e({records:c,ids:l.map(t=>t.id),isLoading:!1,error:null,selectedId:null,filter:{}})})),b=e=>a=>a.listAssets({kind:e}),u=e=>a=>a.listAssets({slot:e});exports.SEED_ASSETS=l;exports.selectAssetsByKind=b;exports.selectAssetsBySlot=u;exports.useAssetStore=g;
1
+ "use strict";const g=require("zustand"),l=[{id:"warrior-cloth-rabbit",name:"Rabbit Warrior Cloth",kind:"characterPart",slot:"top",url:"gltf/ally_cloth_rabbit.glb",tags:["starter","cloth"]},{id:"warrior-cloth-basic",name:"Basic Warrior Cloth",kind:"characterPart",slot:"top",url:"gltf/ally_cloth.glb",tags:["starter","cloth"]},{id:"ally-hat",name:"Ally Hat",kind:"characterPart",slot:"hat",url:"gltf/ally_hat.glb",tags:["starter","hat"]},{id:"ally-glasses",name:"Ally Glasses",kind:"characterPart",slot:"face",url:"gltf/ally_glass.glb",tags:["starter","face"]},{id:"starter-weapon-layer",name:"Starter Weapon Layer",kind:"weapon",slot:"weapon",url:"gltf/ally_cloth.glb",tags:["starter","weapon","placeholder"],metadata:{placeholder:!0}},{id:"wall-soft-brick",name:"Soft Brick Wall",kind:"wall",tags:["building","wall","brick"],colors:{primary:"#b8795f"},metadata:{material:"STANDARD",roughness:.72}},{id:"tile-warm-wood",name:"Warm Wood Tile",kind:"tile",tags:["building","tile","wood"],colors:{primary:"#8b5a35"},metadata:{material:"STANDARD",roughness:.58}},{id:"material-glass-blue",name:"Blue Glass",kind:"material",tags:["building","material","glass"],colors:{primary:"#9bd7ff"},metadata:{material:"GLASS",opacity:.45,transparent:!0,roughness:.1}},{id:"prop-door-basic",name:"Door",kind:"object3d",url:"gltf/props/door.glb",tags:["starter","building","prop","door","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-window-basic",name:"Window",kind:"object3d",url:"gltf/props/window.glb",tags:["starter","building","prop","window","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-fence-basic",name:"Fence",kind:"object3d",url:"gltf/props/fence.glb",tags:["starter","building","prop","fence","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-lamp-basic",name:"Lamp",kind:"object3d",url:"gltf/props/lamp.glb",tags:["starter","building","prop","lamp","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-chair-basic",name:"Chair",kind:"object3d",url:"gltf/props/chair.glb",tags:["starter","building","prop","chair","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-table-basic",name:"Table",kind:"object3d",url:"gltf/props/table.glb",tags:["starter","building","prop","table","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-bed-basic",name:"Bed",kind:"object3d",url:"gltf/props/bed.glb",tags:["starter","building","prop","bed","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-storage-basic",name:"Storage",kind:"object3d",url:"gltf/props/storage.glb",tags:["starter","building","prop","storage","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-mailbox-basic",name:"Mailbox",kind:"object3d",url:"gltf/props/mailbox.glb",tags:["starter","building","prop","mailbox","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-crafting-basic",name:"Crafting Station",kind:"object3d",url:"gltf/props/crafting.glb",tags:["starter","building","prop","crafting","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}},{id:"prop-shop-stall-basic",name:"Shop Stall",kind:"object3d",url:"gltf/props/shop-stall.glb",tags:["starter","building","prop","shop","cc0"],metadata:{source:"Poly Pizza",license:"CC0"}}],p=e=>{const a={};for(const t of e)a[t.id]={...t};return a},u=(e,a)=>a?e.filter(t=>!(a.kind&&t.kind!==a.kind||a.slot&&t.slot!==a.slot||a.tag&&!t.tags?.includes(a.tag))):e,c=p(l),d={state:"seed",origin:"seed",assetCount:l.length,loadedAt:null,error:null,fallbackReason:null};function i(e,a){return a?{...e,query:{...a}}:e}const b=g.create((e,a)=>({records:c,ids:l.map(t=>t.id),isLoading:!1,error:null,catalogStatus:d,selectedId:null,filter:{},setFilter:t=>e({filter:{...t}}),selectAsset:t=>e({selectedId:t}),registerAssets:t=>e(r=>{const s={...r.records},o=new Set(r.ids);for(const n of t)s[n.id]={...n},o.add(n.id);return{records:s,ids:Array.from(o)}}),loadAssets:async(t,r)=>{e({isLoading:!0,error:null,catalogStatus:i({state:"loading",origin:"source",assetCount:a().ids.length,loadedAt:null,error:null,fallbackReason:null},r)});try{const s=await t.listAssets(r);if(s.length>0){a().registerAssets(s),e({isLoading:!1,catalogStatus:i({state:"loaded",origin:"source",assetCount:s.length,loadedAt:Date.now(),error:null,fallbackReason:null},r)});return}a().registerAssets(l),e({isLoading:!1,catalogStatus:i({state:"fallback",origin:"seed",assetCount:l.length,loadedAt:Date.now(),error:null,fallbackReason:"empty-source"},r)})}catch(s){const o=s instanceof Error?s.message:"Failed to load assets";a().registerAssets(l),e({isLoading:!1,error:o,catalogStatus:i({state:"fallback",origin:"seed",assetCount:l.length,loadedAt:Date.now(),error:o,fallbackReason:o},r)})}},getAsset:t=>a().records[t],listAssets:t=>{const r=a();return u(r.ids.map(s=>r.records[s]).filter(s=>!!s),t)},resetAssets:()=>e({records:c,ids:l.map(t=>t.id),isLoading:!1,error:null,catalogStatus:d,selectedId:null,filter:{}})})),f=e=>a=>a.listAssets({kind:e}),m=e=>a=>a.listAssets({slot:e});exports.SEED_ASSETS=l;exports.selectAssetsByKind=f;exports.selectAssetsBySlot=m;exports.useAssetStore=b;
@@ -1,4 +1,4 @@
1
- import { create as d } from "zustand";
1
+ import { create as g } from "zustand";
2
2
  const l = [
3
3
  {
4
4
  id: "warrior-cloth-rabbit",
@@ -172,61 +172,118 @@ const l = [
172
172
  tags: ["starter", "building", "prop", "shop", "cc0"],
173
173
  metadata: { source: "Poly Pizza", license: "CC0" }
174
174
  }
175
- ], n = (r) => {
176
- const t = {};
177
- for (const a of r)
178
- t[a.id] = { ...a };
179
- return t;
180
- }, p = (r, t) => t ? r.filter((a) => !(t.kind && a.kind !== t.kind || t.slot && a.slot !== t.slot || t.tag && !a.tags?.includes(t.tag))) : r, c = n(l), b = d((r, t) => ({
175
+ ], p = (e) => {
176
+ const a = {};
177
+ for (const t of e)
178
+ a[t.id] = { ...t };
179
+ return a;
180
+ }, u = (e, a) => a ? e.filter((t) => !(a.kind && t.kind !== a.kind || a.slot && t.slot !== a.slot || a.tag && !t.tags?.includes(a.tag))) : e, c = p(l), d = {
181
+ state: "seed",
182
+ origin: "seed",
183
+ assetCount: l.length,
184
+ loadedAt: null,
185
+ error: null,
186
+ fallbackReason: null
187
+ };
188
+ function i(e, a) {
189
+ return a ? { ...e, query: { ...a } } : e;
190
+ }
191
+ const f = g((e, a) => ({
181
192
  records: c,
182
- ids: l.map((a) => a.id),
193
+ ids: l.map((t) => t.id),
183
194
  isLoading: !1,
184
195
  error: null,
196
+ catalogStatus: d,
185
197
  selectedId: null,
186
198
  filter: {},
187
- setFilter: (a) => r({ filter: { ...a } }),
188
- selectAsset: (a) => r({ selectedId: a }),
189
- registerAssets: (a) => r((s) => {
190
- const e = { ...s.records }, i = new Set(s.ids);
191
- for (const o of a)
192
- e[o.id] = { ...o }, i.add(o.id);
199
+ setFilter: (t) => e({ filter: { ...t } }),
200
+ selectAsset: (t) => e({ selectedId: t }),
201
+ registerAssets: (t) => e((r) => {
202
+ const s = { ...r.records }, o = new Set(r.ids);
203
+ for (const n of t)
204
+ s[n.id] = { ...n }, o.add(n.id);
193
205
  return {
194
- records: e,
195
- ids: Array.from(i)
206
+ records: s,
207
+ ids: Array.from(o)
196
208
  };
197
209
  }),
198
- loadAssets: async (a, s) => {
199
- r({ isLoading: !0, error: null });
210
+ loadAssets: async (t, r) => {
211
+ e({
212
+ isLoading: !0,
213
+ error: null,
214
+ catalogStatus: i({
215
+ state: "loading",
216
+ origin: "source",
217
+ assetCount: a().ids.length,
218
+ loadedAt: null,
219
+ error: null,
220
+ fallbackReason: null
221
+ }, r)
222
+ });
200
223
  try {
201
- const e = await a.listAssets(s);
202
- t().registerAssets(e.length > 0 ? e : l), r({ isLoading: !1 });
203
- } catch (e) {
204
- t().registerAssets(l), r({
224
+ const s = await t.listAssets(r);
225
+ if (s.length > 0) {
226
+ a().registerAssets(s), e({
227
+ isLoading: !1,
228
+ catalogStatus: i({
229
+ state: "loaded",
230
+ origin: "source",
231
+ assetCount: s.length,
232
+ loadedAt: Date.now(),
233
+ error: null,
234
+ fallbackReason: null
235
+ }, r)
236
+ });
237
+ return;
238
+ }
239
+ a().registerAssets(l), e({
240
+ isLoading: !1,
241
+ catalogStatus: i({
242
+ state: "fallback",
243
+ origin: "seed",
244
+ assetCount: l.length,
245
+ loadedAt: Date.now(),
246
+ error: null,
247
+ fallbackReason: "empty-source"
248
+ }, r)
249
+ });
250
+ } catch (s) {
251
+ const o = s instanceof Error ? s.message : "Failed to load assets";
252
+ a().registerAssets(l), e({
205
253
  isLoading: !1,
206
- error: e instanceof Error ? e.message : "Failed to load assets"
254
+ error: o,
255
+ catalogStatus: i({
256
+ state: "fallback",
257
+ origin: "seed",
258
+ assetCount: l.length,
259
+ loadedAt: Date.now(),
260
+ error: o,
261
+ fallbackReason: o
262
+ }, r)
207
263
  });
208
264
  }
209
265
  },
210
- getAsset: (a) => t().records[a],
211
- listAssets: (a) => {
212
- const s = t();
213
- return p(
214
- s.ids.map((e) => s.records[e]).filter((e) => !!e),
215
- a
266
+ getAsset: (t) => a().records[t],
267
+ listAssets: (t) => {
268
+ const r = a();
269
+ return u(
270
+ r.ids.map((s) => r.records[s]).filter((s) => !!s),
271
+ t
216
272
  );
217
273
  },
218
- resetAssets: () => r({
274
+ resetAssets: () => e({
219
275
  records: c,
220
- ids: l.map((a) => a.id),
276
+ ids: l.map((t) => t.id),
221
277
  isLoading: !1,
222
278
  error: null,
279
+ catalogStatus: d,
223
280
  selectedId: null,
224
281
  filter: {}
225
282
  })
226
- })), u = (r) => (t) => t.listAssets({ kind: r }), m = (r) => (t) => t.listAssets({ slot: r });
283
+ })), m = (e) => (a) => a.listAssets({ kind: e }), h = (e) => (a) => a.listAssets({ slot: e });
227
284
  export {
228
285
  l as S,
229
- m as a,
230
- u as s,
231
- b as u
286
+ h as a,
287
+ m as s,
288
+ f as u
232
289
  };
package/dist/assets.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./assetStore-BuE4mh1C.cjs"),s=require("./index-DCa_lUwq.cjs"),t=require("./api-B58jaq5T.cjs");exports.SEED_ASSETS=e.SEED_ASSETS;exports.selectAssetsByKind=e.selectAssetsByKind;exports.selectAssetsBySlot=e.selectAssetsBySlot;exports.useAssetStore=e.useAssetStore;exports.AssetPreviewCanvas=s.AssetPreviewCanvas;exports.assetToMeshConfig=s.assetToMeshConfig;exports.createScopedAssetMeshConfig=s.createScopedAssetMeshConfig;exports.createScopedBuildingMeshId=s.createScopedBuildingMeshId;exports.HttpAssetSource=t.HttpAssetSource;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./assetStore-DVPge_2j.cjs"),s=require("./index-DCa_lUwq.cjs"),l=require("./api-B58jaq5T.cjs"),t="gltf/ally_body.glb",a={ally:"gltf/ally.glb",allyBody:t,allyCloth:"gltf/ally_cloth.glb",allyRabbitCloth:"gltf/ally_cloth_rabbit.glb",allyHat:"gltf/ally_hat.glb",allyGlass:"gltf/ally_glass.glb"};exports.SEED_ASSETS=e.SEED_ASSETS;exports.selectAssetsByKind=e.selectAssetsByKind;exports.selectAssetsBySlot=e.selectAssetsBySlot;exports.useAssetStore=e.useAssetStore;exports.AssetPreviewCanvas=s.AssetPreviewCanvas;exports.assetToMeshConfig=s.assetToMeshConfig;exports.createScopedAssetMeshConfig=s.createScopedAssetMeshConfig;exports.createScopedBuildingMeshId=s.createScopedBuildingMeshId;exports.HttpAssetSource=l.HttpAssetSource;exports.GAESUP_WORLD_CHARACTER_ASSETS=a;exports.GAESUP_WORLD_DEFAULT_CHARACTER_URL=t;
package/dist/assets.d.cts CHANGED
@@ -1 +1,10 @@
1
1
  export * from './core/assets';
2
+ export declare const GAESUP_WORLD_DEFAULT_CHARACTER_URL = "gltf/ally_body.glb";
3
+ export declare const GAESUP_WORLD_CHARACTER_ASSETS: {
4
+ readonly ally: "gltf/ally.glb";
5
+ readonly allyBody: "gltf/ally_body.glb";
6
+ readonly allyCloth: "gltf/ally_cloth.glb";
7
+ readonly allyRabbitCloth: "gltf/ally_cloth_rabbit.glb";
8
+ readonly allyHat: "gltf/ally_hat.glb";
9
+ readonly allyGlass: "gltf/ally_glass.glb";
10
+ };
package/dist/assets.d.ts CHANGED
@@ -1 +1,10 @@
1
1
  export * from './core/assets';
2
+ export declare const GAESUP_WORLD_DEFAULT_CHARACTER_URL = "gltf/ally_body.glb";
3
+ export declare const GAESUP_WORLD_CHARACTER_ASSETS: {
4
+ readonly ally: "gltf/ally.glb";
5
+ readonly allyBody: "gltf/ally_body.glb";
6
+ readonly allyCloth: "gltf/ally_cloth.glb";
7
+ readonly allyRabbitCloth: "gltf/ally_cloth_rabbit.glb";
8
+ readonly allyHat: "gltf/ally_hat.glb";
9
+ readonly allyGlass: "gltf/ally_glass.glb";
10
+ };
package/dist/assets.js CHANGED
@@ -1,14 +1,24 @@
1
- import { S as t, s as a, a as o, u as r } from "./assetStore-2bI2BPCn.js";
2
- import { A as c, a as A, b as i, c as p } from "./index-C-ViQFGa.js";
1
+ import { S as e, s as o, a as g, u as y } from "./assetStore-mAClONjR.js";
2
+ import { A as S, a as _, b as r, c as b } from "./index-C-ViQFGa.js";
3
3
  import { H as f } from "./api-BRV101Zn.js";
4
+ const l = "gltf/ally_body.glb", s = {
5
+ ally: "gltf/ally.glb",
6
+ allyBody: l,
7
+ allyCloth: "gltf/ally_cloth.glb",
8
+ allyRabbitCloth: "gltf/ally_cloth_rabbit.glb",
9
+ allyHat: "gltf/ally_hat.glb",
10
+ allyGlass: "gltf/ally_glass.glb"
11
+ };
4
12
  export {
5
- c as AssetPreviewCanvas,
13
+ S as AssetPreviewCanvas,
14
+ s as GAESUP_WORLD_CHARACTER_ASSETS,
15
+ l as GAESUP_WORLD_DEFAULT_CHARACTER_URL,
6
16
  f as HttpAssetSource,
7
- t as SEED_ASSETS,
8
- A as assetToMeshConfig,
9
- i as createScopedAssetMeshConfig,
10
- p as createScopedBuildingMeshId,
11
- a as selectAssetsByKind,
12
- o as selectAssetsBySlot,
13
- r as useAssetStore
17
+ e as SEED_ASSETS,
18
+ _ as assetToMeshConfig,
19
+ r as createScopedAssetMeshConfig,
20
+ b as createScopedBuildingMeshId,
21
+ o as selectAssetsByKind,
22
+ g as selectAssetsBySlot,
23
+ y as useAssetStore
14
24
  };
@@ -0,0 +1 @@
1
+ "use strict";function v(e){return`${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}function l(e){return{version:e.version??1,commandId:e.commandId??v("cmd"),domain:e.domain,action:e.action,actorId:e.actorId,submittedAt:e.submittedAt??Date.now(),payload:e.payload,...e.targetId?{targetId:e.targetId}:{},...e.clientSequence!==void 0?{clientSequence:e.clientSequence}:{},...e.expectedRevision!==void 0?{expectedRevision:e.expectedRevision}:{},...e.traceId?{traceId:e.traceId}:{}}}function i(e){return{version:e.version??1,eventId:e.eventId??v("evt"),domain:e.domain,type:e.type,occurredAt:e.occurredAt??Date.now(),payload:e.payload,...e.commandId?{commandId:e.commandId}:{},...e.actorId?{actorId:e.actorId}:{},...e.serverRevision!==void 0?{serverRevision:e.serverRevision}:{},...e.traceId?{traceId:e.traceId}:{}}}function R(e){return{version:e.version??1,deltaId:e.deltaId??v("delta"),domain:e.domain,path:e.path,op:e.op,serverRevision:e.serverRevision,changedAt:e.changedAt??Date.now(),...e.entityId?{entityId:e.entityId}:{},...e.commandId?{commandId:e.commandId}:{},..."value"in e?{value:e.value}:{}}}function s(e){return{version:e.version??1,ackId:e.ackId??v("ack"),snapshotId:e.snapshotId,kind:e.kind,acceptedAt:e.acceptedAt??Date.now(),...e.worldId?{worldId:e.worldId}:{},...e.playerId?{playerId:e.playerId}:{},...e.roomId?{roomId:e.roomId}:{},...e.serverRevision!==void 0?{serverRevision:e.serverRevision}:{},...e.domains?{domains:e.domains}:{}}}function n(e){return`${e.domain}:${e.action??"*"}`}function y(e,r){return`${e}-${r.commandId}`}function h(e,r={}){return{accepted:!0,command:e,events:r.events??[],deltas:r.deltas??[],...r.serverRevision!==void 0?{serverRevision:r.serverRevision}:{}}}function u(e,r,a={}){const t=i({eventId:a.eventId??`rejected-${e.commandId}`,domain:e.domain,type:"command.rejected",occurredAt:a.occurredAt??Date.now(),commandId:e.commandId,actorId:e.actorId,payload:{action:e.action,reason:r},...a.serverRevision!==void 0?{serverRevision:a.serverRevision}:{},...e.traceId?{traceId:e.traceId}:{}});return{accepted:!1,command:e,reason:r,events:[t],deltas:[],...a.serverRevision!==void 0?{serverRevision:a.serverRevision}:{}}}function A(e={}){const r=new Map,a=e.now??Date.now,t=e.createId??y,m={now:a,createId:t};return{register:(d,c)=>{const I=n(d);return r.set(I,c),()=>{r.delete(I)}},handle:async d=>{const c=r.get(n({domain:d.domain,action:d.action}))??r.get(n({domain:d.domain,action:"*"}));return c?c(d,m):u(d,`No authority handler registered for ${d.domain}:${d.action}.`,{eventId:t("rejected",d),occurredAt:a()})},has:d=>r.has(n(d)),clear:()=>{r.clear()}}}exports.createCommandAcceptedResult=h;exports.createCommandAuthorityRouter=A;exports.createCommandRejectedResult=u;exports.createGameCommand=l;exports.createServerEvent=i;exports.createSnapshotAck=s;exports.createStateDelta=R;