@holoscript/core 7.0.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/bin/holoscript.cjs +3 -0
- package/dist/GLTFPipeline-276GE64O.js +16 -0
- package/dist/GLTFPipeline-M7WSSJED.cjs +37 -0
- package/dist/HoloScriptPlusParser-7FBIFUFC.js +693 -0
- package/dist/HoloScriptPlusParser-A2W7OCN2.cjs +698 -0
- package/dist/HoloScriptPlusParser-F2Z56FJR.js +10 -0
- package/dist/HoloScriptPlusParser-WKHRIH6T.cjs +27 -0
- package/dist/HoloScriptRuntime-3URVTKPJ.js +10 -0
- package/dist/HoloScriptRuntime-SXEAEU2N.cjs +19 -0
- package/dist/USDZExporter-3FWJ25JI.cjs +1037 -0
- package/dist/USDZExporter-D2HQLQYK.js +1035 -0
- package/dist/agents/index.cjs +19 -0
- package/dist/agents/index.d.ts +100 -0
- package/dist/agents/index.js +17 -0
- package/dist/chunk-23J755AR.js +1046 -0
- package/dist/chunk-253GBQZY.cjs +627 -0
- package/dist/chunk-25IQCHTO.cjs +781 -0
- package/dist/chunk-2BSMSUCE.js +1941 -0
- package/dist/chunk-2M2DPHKB.js +762 -0
- package/dist/chunk-2YSNA2F2.cjs +1274 -0
- package/dist/chunk-3AO425MZ.cjs +886 -0
- package/dist/chunk-3FOKASKO.cjs +348 -0
- package/dist/chunk-3HYYMEXI.cjs +56578 -0
- package/dist/chunk-3NFFOWGG.js +4287 -0
- package/dist/chunk-3WZEJHUQ.cjs +116 -0
- package/dist/chunk-4C57PR42.js +468 -0
- package/dist/chunk-4N4SXXWF.js +769 -0
- package/dist/chunk-4PDEPEQW.cjs +41 -0
- package/dist/chunk-4R6SBXDB.js +45 -0
- package/dist/chunk-4V2E7U7Q.cjs +2015 -0
- package/dist/chunk-5FSKKMR7.cjs +2092 -0
- package/dist/chunk-5GLCTO44.js +161 -0
- package/dist/chunk-5JEU52DW.js +382 -0
- package/dist/chunk-5S7RKFGR.cjs +446 -0
- package/dist/chunk-5WUNN6ZN.cjs +428 -0
- package/dist/chunk-62FBK3B7.js +70 -0
- package/dist/chunk-6CTRH7HT.cjs +1985 -0
- package/dist/chunk-6DPSFNJB.cjs +847 -0
- package/dist/chunk-6EX3I5P4.cjs +130 -0
- package/dist/chunk-73FELZVJ.cjs +611 -0
- package/dist/chunk-7CUEMLDZ.cjs +6445 -0
- package/dist/chunk-7HIASF7S.cjs +814 -0
- package/dist/chunk-A6KINLZJ.js +236 -0
- package/dist/chunk-AIA52I7T.cjs +543 -0
- package/dist/chunk-ANXZFVY2.js +113 -0
- package/dist/chunk-AYBXB26F.js +2176 -0
- package/dist/chunk-B4TFTDG4.js +449 -0
- package/dist/chunk-BE4UJCQT.js +623 -0
- package/dist/chunk-BRQJKJGT.cjs +20 -0
- package/dist/chunk-C2A5DUMF.cjs +689 -0
- package/dist/chunk-C37BHB7N.cjs +636 -0
- package/dist/chunk-CBJY23VL.js +126 -0
- package/dist/chunk-CIWWXYHZ.cjs +50 -0
- package/dist/chunk-CXFDRBQU.cjs +672 -0
- package/dist/chunk-D54CNIAJ.cjs +413 -0
- package/dist/chunk-DAJXW4KX.js +725 -0
- package/dist/chunk-DTGBOSEM.cjs +319 -0
- package/dist/chunk-E7JP3BS3.cjs +61 -0
- package/dist/chunk-EKBKLK7P.js +1169 -0
- package/dist/chunk-EKYL4PE3.cjs +404 -0
- package/dist/chunk-EUDQTK7N.cjs +4310 -0
- package/dist/chunk-EXKSFGSX.cjs +274 -0
- package/dist/chunk-EXUP2BUM.cjs +1173 -0
- package/dist/chunk-F43YAA34.js +623 -0
- package/dist/chunk-FDSGHPAK.js +130 -0
- package/dist/chunk-FEWUHQNM.cjs +144 -0
- package/dist/chunk-FGGJQRLZ.js +270 -0
- package/dist/chunk-FHP6LXJS.js +415 -0
- package/dist/chunk-FJPADH77.cjs +666 -0
- package/dist/chunk-FYSPZT4V.cjs +169 -0
- package/dist/chunk-GIOYPNTH.js +5575 -0
- package/dist/chunk-GJNCFRJU.cjs +125 -0
- package/dist/chunk-GMP623FG.cjs +1508 -0
- package/dist/chunk-GQHQOPXZ.cjs +5580 -0
- package/dist/chunk-GQT4TYKY.cjs +4381 -0
- package/dist/chunk-GTU2Z2WW.cjs +262 -0
- package/dist/chunk-GYZE55MO.js +2007 -0
- package/dist/chunk-GZG4KA4E.js +529 -0
- package/dist/chunk-H652NHX5.js +600 -0
- package/dist/chunk-HCCQLAA4.cjs +74 -0
- package/dist/chunk-HINXWAOD.cjs +1049 -0
- package/dist/chunk-HYNTS5CP.js +422 -0
- package/dist/chunk-HZSPDCXV.cjs +457 -0
- package/dist/chunk-HZTDET3N.js +1399 -0
- package/dist/chunk-I6XZ5DZF.cjs +488 -0
- package/dist/chunk-ILRBGFVD.cjs +72 -0
- package/dist/chunk-IPWSXCCN.js +1183 -0
- package/dist/chunk-IUTY5WQ2.cjs +424 -0
- package/dist/chunk-IVSZDECV.js +882 -0
- package/dist/chunk-IVY74O6C.js +247 -0
- package/dist/chunk-IZM5VQZD.js +714 -0
- package/dist/chunk-J32ZJZJH.js +554 -0
- package/dist/chunk-J6M4FPK5.js +421 -0
- package/dist/chunk-JC5YBPSF.cjs +984 -0
- package/dist/chunk-JCLBKPMX.js +3813 -0
- package/dist/chunk-JD7CIZ33.js +1949 -0
- package/dist/chunk-JIYN45TV.cjs +2525 -0
- package/dist/chunk-JJBE3TIH.cjs +1189 -0
- package/dist/chunk-JX7YL6ZE.js +2252 -0
- package/dist/chunk-K4VVR7CN.cjs +2433 -0
- package/dist/chunk-KEFNV2WM.cjs +2257 -0
- package/dist/chunk-KH4CNH66.cjs +424 -0
- package/dist/chunk-KJLB4OPV.js +5731 -0
- package/dist/chunk-KKFZ3B6J.cjs +557 -0
- package/dist/chunk-KKP7JKN4.cjs +6002 -0
- package/dist/chunk-KPJL34Y7.cjs +186 -0
- package/dist/chunk-KQCN6AKJ.cjs +3042 -0
- package/dist/chunk-KVRSTFNH.cjs +72 -0
- package/dist/chunk-LICPB5HZ.cjs +1409 -0
- package/dist/chunk-LM2VU56C.cjs +37 -0
- package/dist/chunk-M56JSP4A.js +400 -0
- package/dist/chunk-MBOOR7X4.js +18 -0
- package/dist/chunk-MGE5Z4GS.js +608 -0
- package/dist/chunk-MXFUTKCO.js +56 -0
- package/dist/chunk-MYY4PMWX.cjs +264 -0
- package/dist/chunk-N75IH2HY.js +258 -0
- package/dist/chunk-NBMHU6SW.js +669 -0
- package/dist/chunk-NG77ATEW.cjs +778 -0
- package/dist/chunk-NGKREZ36.js +6384 -0
- package/dist/chunk-NHWSN2SD.cjs +718 -0
- package/dist/chunk-NV4VMVXU.js +421 -0
- package/dist/chunk-NW5G5FBQ.js +215 -0
- package/dist/chunk-NXZFOPVD.cjs +5737 -0
- package/dist/chunk-OBIYPYYS.cjs +1993 -0
- package/dist/chunk-OIQYIIO3.cjs +473 -0
- package/dist/chunk-OL46QLBJ.js +61 -0
- package/dist/chunk-OMXII44L.js +5386 -0
- package/dist/chunk-OR4Q2BGL.cjs +759 -0
- package/dist/chunk-OSYNRVOV.cjs +243 -0
- package/dist/chunk-PGANYCAG.cjs +220 -0
- package/dist/chunk-PHENW4MQ.js +65 -0
- package/dist/chunk-PHVRG4I2.js +844 -0
- package/dist/chunk-Q56TT7IL.js +483 -0
- package/dist/chunk-QPOQ7VPI.js +1491 -0
- package/dist/chunk-QPSKHBJP.js +5963 -0
- package/dist/chunk-QXH7QDSZ.js +1989 -0
- package/dist/chunk-R75BSDH7.cjs +50 -0
- package/dist/chunk-RARB3MBR.js +207 -0
- package/dist/chunk-RVBHAXFG.js +56160 -0
- package/dist/chunk-S3MDHNKB.cjs +490 -0
- package/dist/chunk-S4W6Z2MN.js +2426 -0
- package/dist/chunk-S6YWHCKV.cjs +410 -0
- package/dist/chunk-SIEXCILW.js +229 -0
- package/dist/chunk-SJBGLS25.cjs +2196 -0
- package/dist/chunk-SLU6UPJI.cjs +410 -0
- package/dist/chunk-SMIWS6DE.cjs +212 -0
- package/dist/chunk-T2QCTZMO.js +811 -0
- package/dist/chunk-T5J7ZKP3.cjs +4885 -0
- package/dist/chunk-TDCNJHWO.js +341 -0
- package/dist/chunk-TG7O4WBC.js +406 -0
- package/dist/chunk-THCK6ECW.js +2085 -0
- package/dist/chunk-TJHVSBP2.js +439 -0
- package/dist/chunk-TVHSPJ4N.cjs +606 -0
- package/dist/chunk-U44IKGG7.cjs +5390 -0
- package/dist/chunk-UJXISJBN.js +487 -0
- package/dist/chunk-UM6C3CGK.js +4375 -0
- package/dist/chunk-UMABK6SI.js +686 -0
- package/dist/chunk-UOIGFQXC.cjs +9750 -0
- package/dist/chunk-URG2SJLK.js +2521 -0
- package/dist/chunk-V6MKC2FZ.js +979 -0
- package/dist/chunk-VECQYRXL.js +474 -0
- package/dist/chunk-VJ3L7CHT.cjs +169 -0
- package/dist/chunk-VMLKSV26.js +1216 -0
- package/dist/chunk-VVKVQZI6.js +55 -0
- package/dist/chunk-W6RW64BB.cjs +1219 -0
- package/dist/chunk-W7VDOASB.cjs +639 -0
- package/dist/chunk-WDT3JTGM.cjs +483 -0
- package/dist/chunk-WJIHFLMJ.js +404 -0
- package/dist/chunk-WKX5AMOY.js +309 -0
- package/dist/chunk-WNNE3PO3.js +34 -0
- package/dist/chunk-WRKUDAZJ.js +3038 -0
- package/dist/chunk-WRLUBRKS.cjs +1943 -0
- package/dist/chunk-WRNEH5MO.js +3169 -0
- package/dist/chunk-WRWEX5ZF.js +658 -0
- package/dist/chunk-X3GJPRVK.cjs +3246 -0
- package/dist/chunk-XHIV6326.cjs +793 -0
- package/dist/chunk-XIVIE43A.cjs +729 -0
- package/dist/chunk-XJAN7CZG.cjs +432 -0
- package/dist/chunk-XKTPFXGA.js +164 -0
- package/dist/chunk-XL6INWKT.js +121 -0
- package/dist/chunk-XSFNHP2E.js +632 -0
- package/dist/chunk-XT6JY5W5.js +9684 -0
- package/dist/chunk-XUILI4KB.cjs +430 -0
- package/dist/chunk-XUUVDHIF.cjs +3962 -0
- package/dist/chunk-YF2I3MV3.js +46 -0
- package/dist/chunk-YIMN575O.js +4847 -0
- package/dist/chunk-YIVFJNYV.js +176 -0
- package/dist/chunk-YKGPCZEE.cjs +237 -0
- package/dist/chunk-YN6V7R3L.cjs +327 -0
- package/dist/chunk-YQELFNJV.js +39 -0
- package/dist/chunk-YYXH45E2.js +426 -0
- package/dist/chunk-ZBQXLH2L.js +756 -0
- package/dist/chunk-ZDSYWBIE.cjs +69 -0
- package/dist/chunk-ZU7NIRT6.js +325 -0
- package/dist/chunk-ZZ7RO2UQ.js +1243 -0
- package/dist/chunk-ZZEI7MV4.js +778 -0
- package/dist/cli/holoscript-runner.cjs +2255 -0
- package/dist/cli/holoscript-runner.js +2230 -0
- package/dist/codebase/index.cjs +336 -0
- package/dist/codebase/index.js +331 -0
- package/dist/compiler/agent-inference.cjs +31 -0
- package/dist/compiler/agent-inference.js +8 -0
- package/dist/compiler/android-xr.cjs +24 -0
- package/dist/compiler/android-xr.js +14 -0
- package/dist/compiler/android.cjs +24 -0
- package/dist/compiler/android.js +14 -0
- package/dist/compiler/ar.cjs +23 -0
- package/dist/compiler/ar.js +11 -0
- package/dist/compiler/babylon.cjs +21 -0
- package/dist/compiler/babylon.js +15 -0
- package/dist/compiler/business-quest.cjs +43 -0
- package/dist/compiler/business-quest.js +4 -0
- package/dist/compiler/coco.cjs +27 -0
- package/dist/compiler/coco.js +4 -0
- package/dist/compiler/context.cjs +25 -0
- package/dist/compiler/context.d.ts +28 -0
- package/dist/compiler/context.js +8 -0
- package/dist/compiler/domain-block-utils.cjs +605 -0
- package/dist/compiler/domain-block-utils.js +11 -0
- package/dist/compiler/dtdl.cjs +27 -0
- package/dist/compiler/dtdl.js +11 -0
- package/dist/compiler/gltf-pipeline.cjs +39 -0
- package/dist/compiler/gltf-pipeline.js +4 -0
- package/dist/compiler/godot.cjs +18 -0
- package/dist/compiler/godot.js +12 -0
- package/dist/compiler/incremental.cjs +34 -0
- package/dist/compiler/incremental.js +9 -0
- package/dist/compiler/index.cjs +5860 -0
- package/dist/compiler/index.d.ts +322 -21
- package/dist/compiler/index.js +5525 -0
- package/dist/compiler/ios.cjs +23 -0
- package/dist/compiler/ios.js +13 -0
- package/dist/compiler/llm-provider-capabilities.cjs +25 -0
- package/dist/compiler/llm-provider-capabilities.d.ts +43 -0
- package/dist/compiler/llm-provider-capabilities.js +8 -0
- package/dist/compiler/multi-layer.cjs +24 -0
- package/dist/compiler/multi-layer.js +15 -0
- package/dist/compiler/nodetoy.cjs +23 -0
- package/dist/compiler/nodetoy.js +4 -0
- package/dist/compiler/openxr.cjs +19 -0
- package/dist/compiler/openxr.js +13 -0
- package/dist/compiler/playcanvas.cjs +19 -0
- package/dist/compiler/playcanvas.js +13 -0
- package/dist/compiler/r3f.cjs +38 -0
- package/dist/compiler/r3f.d.ts +22 -0
- package/dist/compiler/r3f.js +16 -0
- package/dist/compiler/remotion.cjs +23 -0
- package/dist/compiler/remotion.js +4 -0
- package/dist/compiler/reproducibility.cjs +39 -0
- package/dist/compiler/reproducibility.js +4 -0
- package/dist/compiler/sdf.cjs +24 -0
- package/dist/compiler/sdf.js +12 -0
- package/dist/compiler/semantic-scene.cjs +31 -0
- package/dist/compiler/semantic-scene.js +4 -0
- package/dist/compiler/state.cjs +21 -0
- package/dist/compiler/state.js +11 -0
- package/dist/compiler/trait-composition.cjs +30 -0
- package/dist/compiler/trait-composition.js +9 -0
- package/dist/compiler/unity.cjs +19 -0
- package/dist/compiler/unity.js +13 -0
- package/dist/compiler/unreal.cjs +23 -0
- package/dist/compiler/unreal.js +13 -0
- package/dist/compiler/urdf.cjs +52 -0
- package/dist/compiler/urdf.js +12 -0
- package/dist/compiler/usd-physics.cjs +26 -0
- package/dist/compiler/usd-physics.js +9 -0
- package/dist/compiler/visionos.cjs +19 -0
- package/dist/compiler/visionos.js +13 -0
- package/dist/compiler/vrchat.cjs +22 -0
- package/dist/compiler/vrchat.js +12 -0
- package/dist/compiler/vrr.cjs +24 -0
- package/dist/compiler/vrr.js +12 -0
- package/dist/compiler/wasm.cjs +36 -0
- package/dist/compiler/wasm.js +12 -0
- package/dist/compiler/webgpu.cjs +18 -0
- package/dist/compiler/webgpu.js +12 -0
- package/dist/coordinators/index.cjs +1266 -0
- package/dist/coordinators/index.d.ts +72 -1
- package/dist/coordinators/index.js +1259 -0
- package/dist/debugger.cjs +24 -0
- package/dist/debugger.js +11 -0
- package/dist/entries/interop.cjs +64 -0
- package/dist/entries/interop.js +7 -0
- package/dist/entries/scripting.cjs +55 -0
- package/dist/entries/scripting.js +10 -0
- package/dist/hololand/index.cjs +146 -0
- package/dist/hololand/index.d.ts +70 -0
- package/dist/hololand/index.js +5 -0
- package/dist/index.cjs +43233 -0
- package/dist/index.d.ts +976 -21
- package/dist/index.js +39995 -0
- package/dist/math/tropical-spmv.cjs +45 -0
- package/dist/math/tropical-spmv.js +4 -0
- package/dist/math/vec3.cjs +57 -0
- package/dist/math/vec3.js +4 -0
- package/dist/ml-dsa-FSKBTE3W.cjs +1265 -0
- package/dist/ml-dsa-Z7JDKW4L.js +1265 -0
- package/dist/paper-0c-spike/index.cjs +150 -0
- package/dist/paper-0c-spike/index.js +141 -0
- package/dist/parser.cjs +61 -0
- package/dist/parser.d.ts +11 -0
- package/dist/parser.js +12 -0
- package/dist/playwright-3AT3AKTV.cjs +98673 -0
- package/dist/playwright-VZPDVUEQ.js +98660 -0
- package/dist/reconstruction/index.cjs +153 -0
- package/dist/reconstruction/index.d.ts +29 -2
- package/dist/reconstruction/index.js +8 -0
- package/dist/runtime.cjs +316 -0
- package/dist/runtime.d.ts +61 -0
- package/dist/runtime.js +31 -0
- package/dist/self-improvement/index.cjs +563 -0
- package/dist/self-improvement/index.js +545 -0
- package/dist/storage/index.cjs +38 -0
- package/dist/storage/index.js +5 -0
- package/dist/testing.cjs +25 -0
- package/dist/testing.d.ts +70 -0
- package/dist/testing.js +4 -0
- package/dist/traitDocs/traitDocs.cjs +33 -0
- package/dist/traitDocs/traitDocs.js +7 -0
- package/dist/traits/botanical-lotus.cjs +41 -0
- package/dist/traits/botanical-lotus.d.ts +172 -0
- package/dist/traits/botanical-lotus.js +4 -0
- package/dist/traits/engines/index.cjs +520 -0
- package/dist/traits/engines/index.js +380 -0
- package/dist/traits/index.cjs +24409 -0
- package/dist/traits/index.d.ts +171 -35
- package/dist/traits/index.js +21634 -0
- package/dist/traits/simulation-solver-factory.cjs +13 -0
- package/dist/traits/simulation-solver-factory.d.ts +23 -0
- package/dist/traits/simulation-solver-factory.js +4 -0
- package/dist/traits/webcam-gaze.cjs +35 -0
- package/dist/traits/webcam-gaze.d.ts +17 -0
- package/dist/traits/webcam-gaze.js +4 -0
- package/dist/type-checker.cjs +19 -0
- package/dist/type-checker.js +6 -0
- package/dist/world/index.cjs +947 -0
- package/dist/world/index.d.ts +147 -0
- package/dist/world/index.js +939 -0
- package/dist/world-model/index.cjs +1446 -0
- package/dist/world-model/index.d.ts +119 -0
- package/dist/world-model/index.js +1414 -0
- package/dist/wot/index.cjs +29 -0
- package/dist/wot/index.js +4 -0
- package/package.json +93 -49
|
@@ -0,0 +1,1985 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkGTU2Z2WW_cjs = require('./chunk-GTU2Z2WW.cjs');
|
|
4
|
+
var chunkHCCQLAA4_cjs = require('./chunk-HCCQLAA4.cjs');
|
|
5
|
+
|
|
6
|
+
// src/hololand/index.ts
|
|
7
|
+
var hololand_exports = {};
|
|
8
|
+
chunkHCCQLAA4_cjs.__export(hololand_exports, {
|
|
9
|
+
CrossValidationRegistry: () => CrossValidationRegistry,
|
|
10
|
+
DEFAULT_ENVELOPES: () => DEFAULT_ENVELOPES,
|
|
11
|
+
DEFAULT_ITEM_AUTONOMOUS_AGENDA: () => DEFAULT_ITEM_AUTONOMOUS_AGENDA,
|
|
12
|
+
DEFAULT_ITEM_REPUTATION_LEDGER: () => DEFAULT_ITEM_REPUTATION_LEDGER,
|
|
13
|
+
DEFAULT_ITEM_VERBAL_FINGERPRINT: () => DEFAULT_ITEM_VERBAL_FINGERPRINT,
|
|
14
|
+
DEFAULT_ITEM_VOCABULARY_REGISTER: () => DEFAULT_ITEM_VOCABULARY_REGISTER,
|
|
15
|
+
HEARTBEAT_INTERVAL: () => HEARTBEAT_INTERVAL,
|
|
16
|
+
HololandClient: () => HololandClient,
|
|
17
|
+
ITEM_DEFAULT_TICK_INTERVAL_MS: () => ITEM_DEFAULT_TICK_INTERVAL_MS,
|
|
18
|
+
MAX_CHUNK_SIZE: () => MAX_CHUNK_SIZE,
|
|
19
|
+
MAX_MESSAGE_SIZE: () => MAX_MESSAGE_SIZE,
|
|
20
|
+
PROTOCOL_VERSION: () => PROTOCOL_VERSION,
|
|
21
|
+
PhysicsBoundsRegistry: () => PhysicsBoundsRegistry,
|
|
22
|
+
StreamProtocol: () => StreamProtocol,
|
|
23
|
+
TIMEOUT_INTERVAL: () => TIMEOUT_INTERVAL,
|
|
24
|
+
computeConsensus: () => computeConsensus,
|
|
25
|
+
connectToHololand: () => connectToHololand,
|
|
26
|
+
createHoloLandItem: () => createHoloLandItem,
|
|
27
|
+
createStreamMessage: () => createMessage,
|
|
28
|
+
createWorldConfig: () => createWorldConfig,
|
|
29
|
+
createWorldDefinition: () => createWorldDefinition,
|
|
30
|
+
createWorldEnvironment: () => createWorldEnvironment,
|
|
31
|
+
createWorldMetadata: () => createWorldMetadata,
|
|
32
|
+
disconnectFromHololand: () => disconnectFromHololand,
|
|
33
|
+
getCrossValidationRegistry: () => getCrossValidationRegistry,
|
|
34
|
+
getHololandClient: () => getHololandClient,
|
|
35
|
+
getItemChain: () => getItemChain,
|
|
36
|
+
getPhysicsBoundsRegistry: () => getPhysicsBoundsRegistry,
|
|
37
|
+
getStreamProtocol: () => getStreamProtocol,
|
|
38
|
+
linkItems: () => linkItems,
|
|
39
|
+
resetCrossValidationRegistry: () => resetCrossValidationRegistry,
|
|
40
|
+
resetPhysicsBoundsRegistry: () => resetPhysicsBoundsRegistry,
|
|
41
|
+
suggestedQuorum: () => suggestedQuorum,
|
|
42
|
+
wrapPhysicsService: () => wrapPhysicsService
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// src/hololand/WorldDefinitionSchema.ts
|
|
46
|
+
function createWorldMetadata(id, name, options = {}) {
|
|
47
|
+
return {
|
|
48
|
+
id,
|
|
49
|
+
name,
|
|
50
|
+
displayName: options.displayName ?? name,
|
|
51
|
+
description: options.description,
|
|
52
|
+
version: options.version ?? "1.0.0",
|
|
53
|
+
author: options.author,
|
|
54
|
+
license: options.license,
|
|
55
|
+
tags: options.tags ?? [],
|
|
56
|
+
thumbnailUrl: options.thumbnailUrl,
|
|
57
|
+
previewImages: options.previewImages ?? [],
|
|
58
|
+
platforms: options.platforms ?? ["web"],
|
|
59
|
+
ageRating: options.ageRating ?? "everyone",
|
|
60
|
+
category: options.category ?? "experience",
|
|
61
|
+
createdAt: options.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
62
|
+
modifiedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
63
|
+
status: options.status ?? "draft",
|
|
64
|
+
metadata: options.metadata ?? {}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function createWorldConfig(options = {}) {
|
|
68
|
+
return {
|
|
69
|
+
maxUsers: options.maxUsers ?? 50,
|
|
70
|
+
bounds: options.bounds ?? {
|
|
71
|
+
minX: -1e3,
|
|
72
|
+
maxX: 1e3,
|
|
73
|
+
minY: -100,
|
|
74
|
+
maxY: 500,
|
|
75
|
+
minZ: -1e3,
|
|
76
|
+
maxZ: 1e3,
|
|
77
|
+
wrap: false,
|
|
78
|
+
outOfBoundsAction: "teleport"
|
|
79
|
+
},
|
|
80
|
+
physics: options.physics ?? {
|
|
81
|
+
engine: "rapier",
|
|
82
|
+
gravity: [0, -9.81, 0],
|
|
83
|
+
fixedTimestep: 1 / 60,
|
|
84
|
+
maxSubsteps: 4,
|
|
85
|
+
collisionDetection: "continuous",
|
|
86
|
+
sleepThreshold: 0.01
|
|
87
|
+
},
|
|
88
|
+
rendering: options.rendering ?? {
|
|
89
|
+
targetFPS: 72,
|
|
90
|
+
shadows: true,
|
|
91
|
+
shadowQuality: "medium",
|
|
92
|
+
antiAliasing: "fxaa",
|
|
93
|
+
msaaSamples: 4,
|
|
94
|
+
bloom: true,
|
|
95
|
+
ambientOcclusion: true,
|
|
96
|
+
aoQuality: "medium",
|
|
97
|
+
toneMapping: "aces",
|
|
98
|
+
exposure: 1,
|
|
99
|
+
fog: false
|
|
100
|
+
},
|
|
101
|
+
audio: options.audio ?? {
|
|
102
|
+
masterVolume: 1,
|
|
103
|
+
spatialAudio: true,
|
|
104
|
+
hrtfProfile: "default",
|
|
105
|
+
reverbPreset: "room",
|
|
106
|
+
maxSources: 32,
|
|
107
|
+
distanceModel: "inverse",
|
|
108
|
+
rolloffFactor: 1
|
|
109
|
+
},
|
|
110
|
+
networking: options.networking ?? {
|
|
111
|
+
region: "auto",
|
|
112
|
+
tickRate: 20,
|
|
113
|
+
interpolationDelay: 100,
|
|
114
|
+
prediction: true,
|
|
115
|
+
protocol: "websocket",
|
|
116
|
+
compression: "lz4",
|
|
117
|
+
syncStrategy: "delta",
|
|
118
|
+
interestRadius: 100
|
|
119
|
+
},
|
|
120
|
+
performance: options.performance ?? {
|
|
121
|
+
maxDrawCalls: 1e3,
|
|
122
|
+
maxTriangles: 2e6,
|
|
123
|
+
maxTextureMemory: 512,
|
|
124
|
+
maxAudioSources: 32,
|
|
125
|
+
maxPhysicsBodies: 1e3,
|
|
126
|
+
maxNetworkedEntities: 500,
|
|
127
|
+
cpuBudgetMs: 11
|
|
128
|
+
},
|
|
129
|
+
accessibility: options.accessibility ?? {
|
|
130
|
+
subtitles: true,
|
|
131
|
+
audioDescriptions: false,
|
|
132
|
+
colorblindMode: "none",
|
|
133
|
+
reduceMotion: false,
|
|
134
|
+
highContrast: false,
|
|
135
|
+
screenReader: true,
|
|
136
|
+
hapticIntensity: 1
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function createWorldEnvironment(options = {}) {
|
|
141
|
+
return {
|
|
142
|
+
skybox: options.skybox ?? {
|
|
143
|
+
type: "procedural",
|
|
144
|
+
procedural: {
|
|
145
|
+
turbidity: 10,
|
|
146
|
+
rayleigh: 2,
|
|
147
|
+
mieCoefficient: 5e-3,
|
|
148
|
+
mieDirectionalG: 0.8,
|
|
149
|
+
sunPosition: [0, 1, 0]
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
ambientLight: options.ambientLight ?? {
|
|
153
|
+
color: "#ffffff",
|
|
154
|
+
intensity: 0.4,
|
|
155
|
+
groundColor: "#444444"
|
|
156
|
+
},
|
|
157
|
+
directionalLights: options.directionalLights ?? [
|
|
158
|
+
{
|
|
159
|
+
id: "sun",
|
|
160
|
+
color: "#fffaf0",
|
|
161
|
+
intensity: 1,
|
|
162
|
+
direction: [-0.5, -1, -0.5],
|
|
163
|
+
castShadow: true,
|
|
164
|
+
shadowMapSize: 2048,
|
|
165
|
+
shadowBias: -1e-4
|
|
166
|
+
}
|
|
167
|
+
],
|
|
168
|
+
environmentMap: options.environmentMap,
|
|
169
|
+
timeOfDay: options.timeOfDay,
|
|
170
|
+
weather: options.weather,
|
|
171
|
+
postProcessing: options.postProcessing ?? {
|
|
172
|
+
enabled: true,
|
|
173
|
+
effects: []
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function createWorldDefinition(id, name, options = {}) {
|
|
178
|
+
return {
|
|
179
|
+
schemaVersion: "1.0.0",
|
|
180
|
+
metadata: createWorldMetadata(id, name),
|
|
181
|
+
config: createWorldConfig(),
|
|
182
|
+
environment: createWorldEnvironment(),
|
|
183
|
+
zones: options.zones ?? [],
|
|
184
|
+
spawnPoints: options.spawnPoints ?? [
|
|
185
|
+
{
|
|
186
|
+
id: "default-spawn",
|
|
187
|
+
name: "Default Spawn",
|
|
188
|
+
position: [0, 0, 0],
|
|
189
|
+
rotation: [0, 0, 0],
|
|
190
|
+
type: "default",
|
|
191
|
+
priority: 10,
|
|
192
|
+
capacity: 100,
|
|
193
|
+
tags: ["default"]
|
|
194
|
+
}
|
|
195
|
+
],
|
|
196
|
+
assetManifest: options.assetManifest ?? "",
|
|
197
|
+
prefabs: options.prefabs ?? [],
|
|
198
|
+
sceneGraph: options.sceneGraph ?? {
|
|
199
|
+
id: "root",
|
|
200
|
+
name: "Root",
|
|
201
|
+
type: "group",
|
|
202
|
+
transform: {
|
|
203
|
+
position: [0, 0, 0],
|
|
204
|
+
rotation: [0, 0, 0],
|
|
205
|
+
scale: [1, 1, 1]
|
|
206
|
+
},
|
|
207
|
+
components: [],
|
|
208
|
+
children: [],
|
|
209
|
+
active: true,
|
|
210
|
+
tags: [],
|
|
211
|
+
layers: 1
|
|
212
|
+
},
|
|
213
|
+
scripts: options.scripts ?? [],
|
|
214
|
+
events: options.events ?? [],
|
|
215
|
+
lod: options.lod ?? {
|
|
216
|
+
enabled: true,
|
|
217
|
+
distances: [25, 50, 100, 200],
|
|
218
|
+
chunkSize: 64,
|
|
219
|
+
maxLoadedChunks: 9,
|
|
220
|
+
unloadDelay: 5
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// src/hololand/HololandIntegration.ts
|
|
226
|
+
var _HololandClient = class _HololandClient {
|
|
227
|
+
constructor(config) {
|
|
228
|
+
this.services = null;
|
|
229
|
+
this.world = null;
|
|
230
|
+
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
231
|
+
this.config = {
|
|
232
|
+
serverUrl: config.serverUrl ?? "wss://api.hololand.io",
|
|
233
|
+
apiKey: config.apiKey,
|
|
234
|
+
debug: config.debug ?? false,
|
|
235
|
+
autoReconnect: config.autoReconnect ?? true,
|
|
236
|
+
reconnectDelay: config.reconnectDelay ?? 1e3,
|
|
237
|
+
maxReconnectAttempts: config.maxReconnectAttempts ?? 10,
|
|
238
|
+
connectionTimeout: config.connectionTimeout ?? 3e4
|
|
239
|
+
};
|
|
240
|
+
this.connectionInfo = {
|
|
241
|
+
state: "disconnected",
|
|
242
|
+
serverUrl: this.config.serverUrl,
|
|
243
|
+
latency: 0,
|
|
244
|
+
bytesSent: 0,
|
|
245
|
+
bytesReceived: 0
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
static getInstance(config) {
|
|
249
|
+
if (!_HololandClient.instance) {
|
|
250
|
+
_HololandClient.instance = new _HololandClient(config ?? {});
|
|
251
|
+
}
|
|
252
|
+
return _HololandClient.instance;
|
|
253
|
+
}
|
|
254
|
+
static resetInstance() {
|
|
255
|
+
_HololandClient.instance?.disconnect();
|
|
256
|
+
_HololandClient.instance = null;
|
|
257
|
+
}
|
|
258
|
+
// ─── Connection Management ────────────────────────────────────────────────
|
|
259
|
+
/**
|
|
260
|
+
* Connect to Hololand server
|
|
261
|
+
*/
|
|
262
|
+
async connect(worldId) {
|
|
263
|
+
if (this.connectionInfo.state === "connected") {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
this.setConnectionState("connecting");
|
|
267
|
+
try {
|
|
268
|
+
await this.simulateConnection();
|
|
269
|
+
if (worldId) {
|
|
270
|
+
await this.joinWorld(worldId);
|
|
271
|
+
}
|
|
272
|
+
this.setConnectionState("connected");
|
|
273
|
+
this.emit("connected", { sessionId: this.connectionInfo.sessionId });
|
|
274
|
+
} catch (error) {
|
|
275
|
+
this.connectionInfo.lastError = error.message;
|
|
276
|
+
this.setConnectionState("error");
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Disconnect from server
|
|
282
|
+
*/
|
|
283
|
+
disconnect() {
|
|
284
|
+
if (this.connectionInfo.state === "disconnected") {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
this.setConnectionState("disconnected");
|
|
288
|
+
this.services = null;
|
|
289
|
+
this.world = null;
|
|
290
|
+
this.emit("disconnected", {});
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Get connection info
|
|
294
|
+
*/
|
|
295
|
+
getConnectionInfo() {
|
|
296
|
+
return { ...this.connectionInfo };
|
|
297
|
+
}
|
|
298
|
+
// ─── World Management ─────────────────────────────────────────────────────
|
|
299
|
+
/**
|
|
300
|
+
* Join a world
|
|
301
|
+
*/
|
|
302
|
+
async joinWorld(worldId) {
|
|
303
|
+
if (this.connectionInfo.state !== "connected") {
|
|
304
|
+
throw new Error("Not connected to server");
|
|
305
|
+
}
|
|
306
|
+
const world = await this.fetchWorldDefinition(worldId);
|
|
307
|
+
this.world = world;
|
|
308
|
+
this.emit("worldJoined", { worldId, world });
|
|
309
|
+
return world;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Leave current world
|
|
313
|
+
*/
|
|
314
|
+
async leaveWorld() {
|
|
315
|
+
if (!this.world) return;
|
|
316
|
+
const worldId = this.world.metadata.id;
|
|
317
|
+
this.world = null;
|
|
318
|
+
this.emit("worldLeft", { worldId });
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Get current world
|
|
322
|
+
*/
|
|
323
|
+
getCurrentWorld() {
|
|
324
|
+
return this.world;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Register a world definition
|
|
328
|
+
*/
|
|
329
|
+
async registerWorld(world) {
|
|
330
|
+
if (this.connectionInfo.state !== "connected") {
|
|
331
|
+
throw new Error("Not connected to server");
|
|
332
|
+
}
|
|
333
|
+
const worldId = world.metadata.id;
|
|
334
|
+
this.emit("worldRegistered", { worldId });
|
|
335
|
+
return worldId;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Update world definition
|
|
339
|
+
*/
|
|
340
|
+
async updateWorld(worldId, updates) {
|
|
341
|
+
if (this.connectionInfo.state !== "connected") {
|
|
342
|
+
throw new Error("Not connected to server");
|
|
343
|
+
}
|
|
344
|
+
this.emit("worldUpdated", { worldId, updates });
|
|
345
|
+
}
|
|
346
|
+
// ─── Runtime Services ─────────────────────────────────────────────────────
|
|
347
|
+
/**
|
|
348
|
+
* Get runtime services
|
|
349
|
+
*/
|
|
350
|
+
getServices() {
|
|
351
|
+
if (!this.services) {
|
|
352
|
+
this.services = this.createServices();
|
|
353
|
+
}
|
|
354
|
+
return this.services;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Create runtime services (stub implementations)
|
|
358
|
+
*/
|
|
359
|
+
createServices() {
|
|
360
|
+
return {
|
|
361
|
+
assets: this.createAssetService(),
|
|
362
|
+
networking: this.createNetworkingService(),
|
|
363
|
+
audio: this.createAudioService(),
|
|
364
|
+
physics: this.createPhysicsService(),
|
|
365
|
+
input: this.createInputService(),
|
|
366
|
+
analytics: this.createAnalyticsService(),
|
|
367
|
+
voice: this.createVoiceService(),
|
|
368
|
+
storage: this.createStorageService()
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
// ─── Service Factory Methods ──────────────────────────────────────────────
|
|
372
|
+
createAssetService() {
|
|
373
|
+
return {
|
|
374
|
+
requestAsset: async (assetId, _priority) => {
|
|
375
|
+
this.log(`Requesting asset: ${assetId}`);
|
|
376
|
+
return null;
|
|
377
|
+
},
|
|
378
|
+
prefetch: async (assetIds) => {
|
|
379
|
+
this.log(`Prefetching ${assetIds.length} assets`);
|
|
380
|
+
},
|
|
381
|
+
cancelLoad: (assetId) => {
|
|
382
|
+
this.log(`Cancelling load: ${assetId}`);
|
|
383
|
+
},
|
|
384
|
+
getProgress: (_assetId) => 0,
|
|
385
|
+
clearCache: () => {
|
|
386
|
+
this.log("Clearing asset cache");
|
|
387
|
+
},
|
|
388
|
+
getCacheStats: () => ({ size: 0, maxSize: 256 * 1024 * 1024, hitRate: 0 })
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
createNetworkingService() {
|
|
392
|
+
const subscriptions = /* @__PURE__ */ new Map();
|
|
393
|
+
return {
|
|
394
|
+
send: (channel, data) => {
|
|
395
|
+
this.log(`Send to ${channel}:`, data);
|
|
396
|
+
},
|
|
397
|
+
subscribe: (channel, handler) => {
|
|
398
|
+
if (!subscriptions.has(channel)) {
|
|
399
|
+
subscriptions.set(channel, /* @__PURE__ */ new Set());
|
|
400
|
+
}
|
|
401
|
+
subscriptions.get(channel).add(handler);
|
|
402
|
+
return () => subscriptions.get(channel)?.delete(handler);
|
|
403
|
+
},
|
|
404
|
+
rpc: async (_method, _params) => {
|
|
405
|
+
return null;
|
|
406
|
+
},
|
|
407
|
+
getConnectionInfo: () => this.connectionInfo,
|
|
408
|
+
setPlayerData: (_key, _value) => {
|
|
409
|
+
},
|
|
410
|
+
getPlayerData: (_key) => null
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
createAudioService() {
|
|
414
|
+
let handleId = 0;
|
|
415
|
+
return {
|
|
416
|
+
play: (soundId, _options) => {
|
|
417
|
+
const id = `audio_${handleId++}`;
|
|
418
|
+
this.log(`Playing sound: ${soundId}`);
|
|
419
|
+
return {
|
|
420
|
+
id,
|
|
421
|
+
stop: () => {
|
|
422
|
+
},
|
|
423
|
+
setVolume: () => {
|
|
424
|
+
},
|
|
425
|
+
setPitch: () => {
|
|
426
|
+
},
|
|
427
|
+
isPlaying: () => false
|
|
428
|
+
};
|
|
429
|
+
},
|
|
430
|
+
stop: (_handle) => {
|
|
431
|
+
},
|
|
432
|
+
setListenerPosition: (_position) => {
|
|
433
|
+
},
|
|
434
|
+
setListenerOrientation: (_forward, _up) => {
|
|
435
|
+
},
|
|
436
|
+
setMasterVolume: (_volume) => {
|
|
437
|
+
},
|
|
438
|
+
createSource: (soundId, _position) => {
|
|
439
|
+
const id = `source_${handleId++}`;
|
|
440
|
+
this.log(`Creating audio source: ${soundId}`);
|
|
441
|
+
return {
|
|
442
|
+
id,
|
|
443
|
+
play: () => {
|
|
444
|
+
},
|
|
445
|
+
stop: () => {
|
|
446
|
+
},
|
|
447
|
+
setPosition: () => {
|
|
448
|
+
},
|
|
449
|
+
setVolume: () => {
|
|
450
|
+
},
|
|
451
|
+
destroy: () => {
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
createPhysicsService() {
|
|
458
|
+
let bodyId = 0;
|
|
459
|
+
return {
|
|
460
|
+
createBody: (config) => {
|
|
461
|
+
const id = `body_${bodyId++}`;
|
|
462
|
+
this.log(`Creating physics body: ${config.type}`);
|
|
463
|
+
return {
|
|
464
|
+
id,
|
|
465
|
+
setPosition: () => {
|
|
466
|
+
},
|
|
467
|
+
setRotation: () => {
|
|
468
|
+
},
|
|
469
|
+
setVelocity: () => {
|
|
470
|
+
},
|
|
471
|
+
applyForce: () => {
|
|
472
|
+
},
|
|
473
|
+
applyImpulse: () => {
|
|
474
|
+
},
|
|
475
|
+
getPosition: () => [config.position[0], config.position[1], config.position[2]],
|
|
476
|
+
getVelocity: () => [0, 0, 0],
|
|
477
|
+
destroy: () => {
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
},
|
|
481
|
+
raycast: (_origin, _direction, _maxDistance) => null,
|
|
482
|
+
overlap: (_shape, _position) => [],
|
|
483
|
+
setGravity: (_gravity) => {
|
|
484
|
+
},
|
|
485
|
+
step: (_deltaTime) => {
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
createInputService() {
|
|
490
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
491
|
+
return {
|
|
492
|
+
getValue: (_action) => 0,
|
|
493
|
+
isPressed: (_action) => false,
|
|
494
|
+
isJustPressed: (_action) => false,
|
|
495
|
+
isJustReleased: (_action) => false,
|
|
496
|
+
getPointerPosition: () => ({ x: 0, y: 0 }),
|
|
497
|
+
getXRController: (_hand) => null,
|
|
498
|
+
bindAction: (action, binding) => {
|
|
499
|
+
bindings.set(action, binding);
|
|
500
|
+
},
|
|
501
|
+
setVibration: (_hand, _intensity, _duration) => {
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
createAnalyticsService() {
|
|
506
|
+
const timings = /* @__PURE__ */ new Map();
|
|
507
|
+
return {
|
|
508
|
+
track: (event, properties) => {
|
|
509
|
+
this.log(`Analytics: ${event}`, properties);
|
|
510
|
+
},
|
|
511
|
+
setUserProperty: (_key, _value) => {
|
|
512
|
+
},
|
|
513
|
+
startTiming: (label) => {
|
|
514
|
+
timings.set(label, performance.now());
|
|
515
|
+
},
|
|
516
|
+
endTiming: (label) => {
|
|
517
|
+
const start = timings.get(label);
|
|
518
|
+
if (!start) return 0;
|
|
519
|
+
const duration = performance.now() - start;
|
|
520
|
+
timings.delete(label);
|
|
521
|
+
return duration;
|
|
522
|
+
},
|
|
523
|
+
getMetrics: () => ({
|
|
524
|
+
fps: 60,
|
|
525
|
+
frameTime: 16.67,
|
|
526
|
+
drawCalls: 0,
|
|
527
|
+
triangles: 0,
|
|
528
|
+
textureMemory: 0,
|
|
529
|
+
geometryMemory: 0,
|
|
530
|
+
physicsTime: 0,
|
|
531
|
+
networkLatency: this.connectionInfo.latency
|
|
532
|
+
})
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
createVoiceService() {
|
|
536
|
+
return {
|
|
537
|
+
startVoiceChat: async () => {
|
|
538
|
+
},
|
|
539
|
+
stopVoiceChat: () => {
|
|
540
|
+
},
|
|
541
|
+
setMuted: (_muted) => {
|
|
542
|
+
},
|
|
543
|
+
setVolume: (_userId, _volume) => {
|
|
544
|
+
},
|
|
545
|
+
getSpeakingUsers: () => [],
|
|
546
|
+
speak: async (_text, _options) => {
|
|
547
|
+
},
|
|
548
|
+
startListening: async () => {
|
|
549
|
+
},
|
|
550
|
+
stopListening: async () => ""
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
createStorageService() {
|
|
554
|
+
const storage = /* @__PURE__ */ new Map();
|
|
555
|
+
return {
|
|
556
|
+
get: async (key) => storage.get(key) ?? null,
|
|
557
|
+
set: async (key, value) => {
|
|
558
|
+
storage.set(key, value);
|
|
559
|
+
},
|
|
560
|
+
delete: async (key) => {
|
|
561
|
+
storage.delete(key);
|
|
562
|
+
},
|
|
563
|
+
keys: async () => Array.from(storage.keys()),
|
|
564
|
+
clear: async () => {
|
|
565
|
+
storage.clear();
|
|
566
|
+
},
|
|
567
|
+
getQuota: async () => ({ used: 0, total: 50 * 1024 * 1024 })
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
// ─── Event System ─────────────────────────────────────────────────────────
|
|
571
|
+
/**
|
|
572
|
+
* Subscribe to events
|
|
573
|
+
*/
|
|
574
|
+
on(event, handler) {
|
|
575
|
+
if (!this.eventHandlers.has(event)) {
|
|
576
|
+
this.eventHandlers.set(event, /* @__PURE__ */ new Set());
|
|
577
|
+
}
|
|
578
|
+
this.eventHandlers.get(event).add(handler);
|
|
579
|
+
return () => this.eventHandlers.get(event)?.delete(handler);
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Emit event
|
|
583
|
+
*/
|
|
584
|
+
emit(event, data) {
|
|
585
|
+
const handlers = this.eventHandlers.get(event);
|
|
586
|
+
if (handlers) {
|
|
587
|
+
for (const handler of handlers) {
|
|
588
|
+
try {
|
|
589
|
+
handler(data);
|
|
590
|
+
} catch (error) {
|
|
591
|
+
console.error(`Event handler error for ${event}:`, error);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
// ─── Internal Helpers ─────────────────────────────────────────────────────
|
|
597
|
+
setConnectionState(state) {
|
|
598
|
+
this.connectionInfo.state = state;
|
|
599
|
+
this.emit("connectionStateChanged", { state });
|
|
600
|
+
}
|
|
601
|
+
async simulateConnection() {
|
|
602
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
603
|
+
this.connectionInfo.sessionId = `session_${Date.now()}`;
|
|
604
|
+
this.connectionInfo.connectedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
605
|
+
this.connectionInfo.latency = 50;
|
|
606
|
+
}
|
|
607
|
+
async fetchWorldDefinition(worldId) {
|
|
608
|
+
const httpBaseUrl = this.config.serverUrl.replace(/^wss:\/\//, "https://").replace(/^ws:\/\//, "http://");
|
|
609
|
+
const url = `${httpBaseUrl}/api/worlds/${encodeURIComponent(worldId)}`;
|
|
610
|
+
const headers = {
|
|
611
|
+
Accept: "application/json"
|
|
612
|
+
};
|
|
613
|
+
if (this.config.apiKey) {
|
|
614
|
+
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
615
|
+
}
|
|
616
|
+
const controller = new AbortController();
|
|
617
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.connectionTimeout);
|
|
618
|
+
try {
|
|
619
|
+
const response = await fetch(url, {
|
|
620
|
+
method: "GET",
|
|
621
|
+
headers,
|
|
622
|
+
signal: controller.signal
|
|
623
|
+
});
|
|
624
|
+
if (!response.ok) {
|
|
625
|
+
throw new Error(`Failed to fetch world "${worldId}": ${response.status} ${response.statusText}`);
|
|
626
|
+
}
|
|
627
|
+
return await response.json();
|
|
628
|
+
} finally {
|
|
629
|
+
clearTimeout(timeoutId);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
log(...args) {
|
|
633
|
+
if (this.config.debug) {
|
|
634
|
+
console.log("[Hololand]", ...args);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
_HololandClient.instance = null;
|
|
639
|
+
var HololandClient = _HololandClient;
|
|
640
|
+
function getHololandClient(config) {
|
|
641
|
+
return HololandClient.getInstance(config);
|
|
642
|
+
}
|
|
643
|
+
async function connectToHololand(config, worldId) {
|
|
644
|
+
const client = getHololandClient(config);
|
|
645
|
+
await client.connect(worldId);
|
|
646
|
+
return client;
|
|
647
|
+
}
|
|
648
|
+
function disconnectFromHololand() {
|
|
649
|
+
HololandClient.resetInstance();
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// src/hololand/PhysicsBoundsRegistry.ts
|
|
653
|
+
chunkGTU2Z2WW_cjs.init_AgentRiskRegistry();
|
|
654
|
+
var DEFAULT_ENVELOPES = {
|
|
655
|
+
["low" /* LOW */]: {
|
|
656
|
+
maxForceN: 1e3,
|
|
657
|
+
maxImpulseNs: 200,
|
|
658
|
+
maxVelocityMps: 50,
|
|
659
|
+
maxGravityMps2: 30,
|
|
660
|
+
allowSetGravity: true,
|
|
661
|
+
allowDynamicMutation: true
|
|
662
|
+
},
|
|
663
|
+
["medium" /* MEDIUM */]: {
|
|
664
|
+
maxForceN: 500,
|
|
665
|
+
maxImpulseNs: 100,
|
|
666
|
+
maxVelocityMps: 20,
|
|
667
|
+
maxGravityMps2: 15,
|
|
668
|
+
allowSetGravity: true,
|
|
669
|
+
allowDynamicMutation: true
|
|
670
|
+
},
|
|
671
|
+
["high" /* HIGH */]: {
|
|
672
|
+
maxForceN: 100,
|
|
673
|
+
maxImpulseNs: 25,
|
|
674
|
+
maxVelocityMps: 5,
|
|
675
|
+
maxGravityMps2: 10,
|
|
676
|
+
// High-risk agents can't reshape gravity — that's a global effect that
|
|
677
|
+
// would propagate confabulation risk to every body in the world.
|
|
678
|
+
allowSetGravity: false,
|
|
679
|
+
allowDynamicMutation: true
|
|
680
|
+
},
|
|
681
|
+
["quarantined" /* QUARANTINED */]: {
|
|
682
|
+
maxForceN: 0,
|
|
683
|
+
maxImpulseNs: 0,
|
|
684
|
+
maxVelocityMps: 0,
|
|
685
|
+
maxGravityMps2: 0,
|
|
686
|
+
allowSetGravity: false,
|
|
687
|
+
allowDynamicMutation: false
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
var PhysicsBoundsRegistry = class {
|
|
691
|
+
constructor(config = {}) {
|
|
692
|
+
const overrides = config.envelopeOverrides ?? {};
|
|
693
|
+
const merged = {
|
|
694
|
+
["low" /* LOW */]: { ...DEFAULT_ENVELOPES["low" /* LOW */] },
|
|
695
|
+
["medium" /* MEDIUM */]: { ...DEFAULT_ENVELOPES["medium" /* MEDIUM */] },
|
|
696
|
+
["high" /* HIGH */]: { ...DEFAULT_ENVELOPES["high" /* HIGH */] },
|
|
697
|
+
["quarantined" /* QUARANTINED */]: { ...DEFAULT_ENVELOPES["quarantined" /* QUARANTINED */] }
|
|
698
|
+
};
|
|
699
|
+
for (const tier of Object.keys(overrides)) {
|
|
700
|
+
const partial = overrides[tier];
|
|
701
|
+
if (!partial) continue;
|
|
702
|
+
merged[tier] = { ...merged[tier], ...partial };
|
|
703
|
+
}
|
|
704
|
+
this.envelopes = merged;
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Look up the envelope for a risk tier (read-only view).
|
|
708
|
+
*/
|
|
709
|
+
getEnvelope(tier) {
|
|
710
|
+
return { ...this.envelopes[tier] };
|
|
711
|
+
}
|
|
712
|
+
};
|
|
713
|
+
var globalBoundsRegistry = null;
|
|
714
|
+
function getPhysicsBoundsRegistry(config) {
|
|
715
|
+
if (!globalBoundsRegistry) {
|
|
716
|
+
globalBoundsRegistry = new PhysicsBoundsRegistry(config);
|
|
717
|
+
}
|
|
718
|
+
return globalBoundsRegistry;
|
|
719
|
+
}
|
|
720
|
+
function resetPhysicsBoundsRegistry() {
|
|
721
|
+
globalBoundsRegistry = null;
|
|
722
|
+
}
|
|
723
|
+
function wrapPhysicsService(service, agentId, options = {}) {
|
|
724
|
+
const riskRegistry = options.riskRegistry ?? chunkGTU2Z2WW_cjs.getAgentRiskRegistry();
|
|
725
|
+
const boundsRegistry = options.boundsRegistry ?? getPhysicsBoundsRegistry();
|
|
726
|
+
const onViolation = options.onViolation;
|
|
727
|
+
function currentEnvelope() {
|
|
728
|
+
const tier = riskRegistry.getTier(agentId);
|
|
729
|
+
return { tier, env: boundsRegistry.getEnvelope(tier) };
|
|
730
|
+
}
|
|
731
|
+
function emit(v) {
|
|
732
|
+
if (onViolation) {
|
|
733
|
+
try {
|
|
734
|
+
onViolation(v);
|
|
735
|
+
} catch {
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
function wrapBody(body) {
|
|
740
|
+
return {
|
|
741
|
+
get id() {
|
|
742
|
+
return body.id;
|
|
743
|
+
},
|
|
744
|
+
setPosition(position) {
|
|
745
|
+
const { tier, env } = currentEnvelope();
|
|
746
|
+
if (!env.allowDynamicMutation) {
|
|
747
|
+
emit({
|
|
748
|
+
agentId,
|
|
749
|
+
tier,
|
|
750
|
+
kind: "rejected",
|
|
751
|
+
operation: "setPosition",
|
|
752
|
+
requestedMagnitude: vectorMagnitude(position),
|
|
753
|
+
allowedMagnitude: 0,
|
|
754
|
+
bodyId: body.id
|
|
755
|
+
});
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
body.setPosition(position);
|
|
759
|
+
},
|
|
760
|
+
setRotation(rotation) {
|
|
761
|
+
const { tier, env } = currentEnvelope();
|
|
762
|
+
if (!env.allowDynamicMutation) {
|
|
763
|
+
emit({
|
|
764
|
+
agentId,
|
|
765
|
+
tier,
|
|
766
|
+
kind: "rejected",
|
|
767
|
+
operation: "setRotation",
|
|
768
|
+
requestedMagnitude: 0,
|
|
769
|
+
allowedMagnitude: 0,
|
|
770
|
+
bodyId: body.id
|
|
771
|
+
});
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
body.setRotation(rotation);
|
|
775
|
+
},
|
|
776
|
+
setVelocity(velocity) {
|
|
777
|
+
const { tier, env } = currentEnvelope();
|
|
778
|
+
if (!env.allowDynamicMutation) {
|
|
779
|
+
emit({
|
|
780
|
+
agentId,
|
|
781
|
+
tier,
|
|
782
|
+
kind: "rejected",
|
|
783
|
+
operation: "setVelocity",
|
|
784
|
+
requestedMagnitude: vectorMagnitude(velocity),
|
|
785
|
+
allowedMagnitude: 0,
|
|
786
|
+
bodyId: body.id
|
|
787
|
+
});
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
const { value, clamped, requested } = clampVector(velocity, env.maxVelocityMps);
|
|
791
|
+
if (clamped) {
|
|
792
|
+
emit({
|
|
793
|
+
agentId,
|
|
794
|
+
tier,
|
|
795
|
+
kind: "clamped",
|
|
796
|
+
operation: "setVelocity",
|
|
797
|
+
requestedMagnitude: requested,
|
|
798
|
+
allowedMagnitude: env.maxVelocityMps,
|
|
799
|
+
bodyId: body.id
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
body.setVelocity(value);
|
|
803
|
+
},
|
|
804
|
+
applyForce(force) {
|
|
805
|
+
const { tier, env } = currentEnvelope();
|
|
806
|
+
if (!env.allowDynamicMutation) {
|
|
807
|
+
emit({
|
|
808
|
+
agentId,
|
|
809
|
+
tier,
|
|
810
|
+
kind: "rejected",
|
|
811
|
+
operation: "applyForce",
|
|
812
|
+
requestedMagnitude: vectorMagnitude(force),
|
|
813
|
+
allowedMagnitude: 0,
|
|
814
|
+
bodyId: body.id
|
|
815
|
+
});
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
const { value, clamped, requested } = clampVector(force, env.maxForceN);
|
|
819
|
+
if (clamped) {
|
|
820
|
+
emit({
|
|
821
|
+
agentId,
|
|
822
|
+
tier,
|
|
823
|
+
kind: "clamped",
|
|
824
|
+
operation: "applyForce",
|
|
825
|
+
requestedMagnitude: requested,
|
|
826
|
+
allowedMagnitude: env.maxForceN,
|
|
827
|
+
bodyId: body.id
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
body.applyForce(value);
|
|
831
|
+
},
|
|
832
|
+
applyImpulse(impulse) {
|
|
833
|
+
const { tier, env } = currentEnvelope();
|
|
834
|
+
if (!env.allowDynamicMutation) {
|
|
835
|
+
emit({
|
|
836
|
+
agentId,
|
|
837
|
+
tier,
|
|
838
|
+
kind: "rejected",
|
|
839
|
+
operation: "applyImpulse",
|
|
840
|
+
requestedMagnitude: vectorMagnitude(impulse),
|
|
841
|
+
allowedMagnitude: 0,
|
|
842
|
+
bodyId: body.id
|
|
843
|
+
});
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
const { value, clamped, requested } = clampVector(impulse, env.maxImpulseNs);
|
|
847
|
+
if (clamped) {
|
|
848
|
+
emit({
|
|
849
|
+
agentId,
|
|
850
|
+
tier,
|
|
851
|
+
kind: "clamped",
|
|
852
|
+
operation: "applyImpulse",
|
|
853
|
+
requestedMagnitude: requested,
|
|
854
|
+
allowedMagnitude: env.maxImpulseNs,
|
|
855
|
+
bodyId: body.id
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
body.applyImpulse(value);
|
|
859
|
+
},
|
|
860
|
+
// Reads pass through unchanged — confabulation doesn't propagate via
|
|
861
|
+
// queries.
|
|
862
|
+
getPosition() {
|
|
863
|
+
return body.getPosition();
|
|
864
|
+
},
|
|
865
|
+
getVelocity() {
|
|
866
|
+
return body.getVelocity();
|
|
867
|
+
},
|
|
868
|
+
destroy() {
|
|
869
|
+
body.destroy();
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
return {
|
|
874
|
+
createBody(config) {
|
|
875
|
+
const body = service.createBody(config);
|
|
876
|
+
return wrapBody(body);
|
|
877
|
+
},
|
|
878
|
+
raycast(origin, direction, maxDistance) {
|
|
879
|
+
const result = service.raycast(origin, direction, maxDistance);
|
|
880
|
+
if (!result) return null;
|
|
881
|
+
return { ...result, body: wrapBody(result.body) };
|
|
882
|
+
},
|
|
883
|
+
overlap(shape, position) {
|
|
884
|
+
return service.overlap(shape, position).map(wrapBody);
|
|
885
|
+
},
|
|
886
|
+
setGravity(gravity) {
|
|
887
|
+
const { tier, env } = currentEnvelope();
|
|
888
|
+
const requested = vectorMagnitude(gravity);
|
|
889
|
+
if (!env.allowSetGravity) {
|
|
890
|
+
emit({
|
|
891
|
+
agentId,
|
|
892
|
+
tier,
|
|
893
|
+
kind: "rejected",
|
|
894
|
+
operation: "setGravity",
|
|
895
|
+
requestedMagnitude: requested,
|
|
896
|
+
allowedMagnitude: 0,
|
|
897
|
+
bodyId: null
|
|
898
|
+
});
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
const { value, clamped } = clampVector(gravity, env.maxGravityMps2);
|
|
902
|
+
if (clamped) {
|
|
903
|
+
emit({
|
|
904
|
+
agentId,
|
|
905
|
+
tier,
|
|
906
|
+
kind: "clamped",
|
|
907
|
+
operation: "setGravity",
|
|
908
|
+
requestedMagnitude: requested,
|
|
909
|
+
allowedMagnitude: env.maxGravityMps2,
|
|
910
|
+
bodyId: null
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
service.setGravity(value);
|
|
914
|
+
},
|
|
915
|
+
step(deltaTime) {
|
|
916
|
+
service.step(deltaTime);
|
|
917
|
+
}
|
|
918
|
+
};
|
|
919
|
+
}
|
|
920
|
+
function vectorMagnitude(v) {
|
|
921
|
+
return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
|
922
|
+
}
|
|
923
|
+
function clampVector(v, maxMagnitude) {
|
|
924
|
+
const requested = vectorMagnitude(v);
|
|
925
|
+
if (maxMagnitude <= 0) {
|
|
926
|
+
return { value: [0, 0, 0], clamped: requested > 0, requested };
|
|
927
|
+
}
|
|
928
|
+
if (requested <= maxMagnitude) {
|
|
929
|
+
return { value: [v[0], v[1], v[2]], clamped: false, requested };
|
|
930
|
+
}
|
|
931
|
+
const scale = maxMagnitude / requested;
|
|
932
|
+
return {
|
|
933
|
+
value: [v[0] * scale, v[1] * scale, v[2] * scale],
|
|
934
|
+
clamped: true,
|
|
935
|
+
requested
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
// src/hololand/CrossValidationRegistry.ts
|
|
940
|
+
chunkGTU2Z2WW_cjs.init_AgentRiskRegistry();
|
|
941
|
+
var DEFAULT_MIN_OBSERVERS = 3;
|
|
942
|
+
var DEFAULT_NUMERIC_TOLERANCE = 1;
|
|
943
|
+
var DEFAULT_AGREEMENT_SEVERITY = 15;
|
|
944
|
+
var DEFAULT_MAX_ROUNDS = 1024;
|
|
945
|
+
var CrossValidationRegistry = class {
|
|
946
|
+
constructor(config = {}) {
|
|
947
|
+
/** eventId -> round state. Insertion order = age order (Map preserves it). */
|
|
948
|
+
this.rounds = /* @__PURE__ */ new Map();
|
|
949
|
+
/**
|
|
950
|
+
* Per-round set of agentIds we have ALREADY emitted feedback for, so a
|
|
951
|
+
* late submission after `resolved=true` doesn't double-count.
|
|
952
|
+
*/
|
|
953
|
+
this.emittedFor = /* @__PURE__ */ new Map();
|
|
954
|
+
this.defaultMinObservers = config.defaultMinObservers ?? DEFAULT_MIN_OBSERVERS;
|
|
955
|
+
this.tolerance = {
|
|
956
|
+
defaultNumericTolerance: config.tolerance?.defaultNumericTolerance ?? DEFAULT_NUMERIC_TOLERANCE,
|
|
957
|
+
perField: config.tolerance?.perField
|
|
958
|
+
};
|
|
959
|
+
this.agreementSeverityThreshold = config.agreementSeverityThreshold ?? DEFAULT_AGREEMENT_SEVERITY;
|
|
960
|
+
this.riskRegistry = config.riskRegistry ?? chunkGTU2Z2WW_cjs.getAgentRiskRegistry();
|
|
961
|
+
this.maxRounds = config.maxRounds ?? DEFAULT_MAX_ROUNDS;
|
|
962
|
+
this.now = config.now ?? (() => Date.now());
|
|
963
|
+
if (this.defaultMinObservers < 2) {
|
|
964
|
+
throw new Error(
|
|
965
|
+
"CrossValidationRegistry: defaultMinObservers must be >= 2 (consensus requires at least two observers)"
|
|
966
|
+
);
|
|
967
|
+
}
|
|
968
|
+
if (this.agreementSeverityThreshold < 0 || this.agreementSeverityThreshold > 100) {
|
|
969
|
+
throw new Error(
|
|
970
|
+
"CrossValidationRegistry: agreementSeverityThreshold must be in [0,100]"
|
|
971
|
+
);
|
|
972
|
+
}
|
|
973
|
+
if (this.tolerance.defaultNumericTolerance <= 0) {
|
|
974
|
+
throw new Error(
|
|
975
|
+
"CrossValidationRegistry: defaultNumericTolerance must be > 0"
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
if (this.maxRounds < 1) {
|
|
979
|
+
throw new Error("CrossValidationRegistry: maxRounds must be >= 1");
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
// ---------------------------------------------------------------------------
|
|
983
|
+
// ROUND LIFECYCLE
|
|
984
|
+
// ---------------------------------------------------------------------------
|
|
985
|
+
/**
|
|
986
|
+
* Open a new validation round for a world-state event.
|
|
987
|
+
*
|
|
988
|
+
* Idempotent: if a round with `eventId` already exists, this is a no-op
|
|
989
|
+
* (returns the existing snapshot). This matters for CRDT correctness: two
|
|
990
|
+
* peers may both call `openRound` on the same event before any
|
|
991
|
+
* observations arrive.
|
|
992
|
+
*/
|
|
993
|
+
openRound(eventId, minObservers) {
|
|
994
|
+
const existing = this.rounds.get(eventId);
|
|
995
|
+
if (existing) return existing;
|
|
996
|
+
const round = {
|
|
997
|
+
eventId,
|
|
998
|
+
openedAt: this.now(),
|
|
999
|
+
minObservers: minObservers ?? this.defaultMinObservers,
|
|
1000
|
+
observations: {},
|
|
1001
|
+
resolved: false
|
|
1002
|
+
};
|
|
1003
|
+
this.rounds.set(eventId, round);
|
|
1004
|
+
this.evictIfNeeded();
|
|
1005
|
+
return round;
|
|
1006
|
+
}
|
|
1007
|
+
/**
|
|
1008
|
+
* Submit an observation. Implicitly opens the round if it doesn't exist.
|
|
1009
|
+
*
|
|
1010
|
+
* Returns a `SubmissionResult` describing whether quorum was reached
|
|
1011
|
+
* (and therefore whether risk feedback was emitted).
|
|
1012
|
+
*/
|
|
1013
|
+
submitObservation(observation) {
|
|
1014
|
+
const submittedAt = observation.submittedAt ?? this.now();
|
|
1015
|
+
const round = this.openRound(observation.eventId);
|
|
1016
|
+
const existing = round.observations[observation.agentId];
|
|
1017
|
+
if (existing && existing.submittedAt > submittedAt) {
|
|
1018
|
+
return {
|
|
1019
|
+
resolved: round.resolved,
|
|
1020
|
+
observerCount: Object.keys(round.observations).length,
|
|
1021
|
+
consensus: null,
|
|
1022
|
+
emittedRiskEvents: []
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1025
|
+
const merged = {
|
|
1026
|
+
eventId: observation.eventId,
|
|
1027
|
+
agentId: observation.agentId,
|
|
1028
|
+
claim: observation.claim,
|
|
1029
|
+
submittedAt
|
|
1030
|
+
};
|
|
1031
|
+
const next = {
|
|
1032
|
+
...round,
|
|
1033
|
+
observations: { ...round.observations, [observation.agentId]: merged }
|
|
1034
|
+
};
|
|
1035
|
+
this.rounds.set(observation.eventId, next);
|
|
1036
|
+
return this.maybeResolve(observation.eventId);
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* Merge a remote round snapshot into the local registry.
|
|
1040
|
+
*
|
|
1041
|
+
* CRDT semantics:
|
|
1042
|
+
* - Per-agent observations merge by LWW on `submittedAt`.
|
|
1043
|
+
* - The local `resolved` flag is sticky once true (don't un-resolve a
|
|
1044
|
+
* round just because a peer hadn't seen the resolution yet).
|
|
1045
|
+
* - `minObservers` and `openedAt` from the EARLIEST `openedAt` win
|
|
1046
|
+
* (deterministic across peers).
|
|
1047
|
+
* - After merging, attempts to resolve in case the merged observations
|
|
1048
|
+
* just crossed quorum.
|
|
1049
|
+
*/
|
|
1050
|
+
mergeRound(remote) {
|
|
1051
|
+
const local = this.rounds.get(remote.eventId);
|
|
1052
|
+
const mergedObservations = {};
|
|
1053
|
+
const allAgents = /* @__PURE__ */ new Set([
|
|
1054
|
+
...Object.keys(local?.observations ?? {}),
|
|
1055
|
+
...Object.keys(remote.observations)
|
|
1056
|
+
]);
|
|
1057
|
+
for (const agentId of allAgents) {
|
|
1058
|
+
const l = local?.observations[agentId];
|
|
1059
|
+
const r = remote.observations[agentId];
|
|
1060
|
+
if (l && r) {
|
|
1061
|
+
mergedObservations[agentId] = l.submittedAt >= r.submittedAt ? l : r;
|
|
1062
|
+
} else {
|
|
1063
|
+
mergedObservations[agentId] = l ?? r;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
const openedAt = local ? Math.min(local.openedAt, remote.openedAt) : remote.openedAt;
|
|
1067
|
+
const minObservers = local ? Math.min(local.minObservers, remote.minObservers) : remote.minObservers;
|
|
1068
|
+
const resolved = (local?.resolved ?? false) || remote.resolved;
|
|
1069
|
+
const merged = {
|
|
1070
|
+
eventId: remote.eventId,
|
|
1071
|
+
openedAt,
|
|
1072
|
+
minObservers,
|
|
1073
|
+
observations: mergedObservations,
|
|
1074
|
+
resolved
|
|
1075
|
+
};
|
|
1076
|
+
this.rounds.set(remote.eventId, merged);
|
|
1077
|
+
this.evictIfNeeded();
|
|
1078
|
+
return this.maybeResolve(remote.eventId);
|
|
1079
|
+
}
|
|
1080
|
+
/**
|
|
1081
|
+
* Force-resolve a round even if the quorum hasn't been met. Used by
|
|
1082
|
+
* orchestrators that want to close a round on a deadline. The consensus
|
|
1083
|
+
* is computed over whatever observations are present (>=1 required).
|
|
1084
|
+
*/
|
|
1085
|
+
forceResolve(eventId) {
|
|
1086
|
+
const round = this.rounds.get(eventId);
|
|
1087
|
+
if (!round) return null;
|
|
1088
|
+
if (Object.keys(round.observations).length === 0) return null;
|
|
1089
|
+
const result = this.resolveNow(eventId);
|
|
1090
|
+
return result.consensus;
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Read-only snapshot of a round (for diagnostics, exports, CRDT sync).
|
|
1094
|
+
*/
|
|
1095
|
+
exportRound(eventId) {
|
|
1096
|
+
const r = this.rounds.get(eventId);
|
|
1097
|
+
if (!r) return null;
|
|
1098
|
+
return {
|
|
1099
|
+
eventId: r.eventId,
|
|
1100
|
+
openedAt: r.openedAt,
|
|
1101
|
+
minObservers: r.minObservers,
|
|
1102
|
+
observations: { ...r.observations },
|
|
1103
|
+
resolved: r.resolved
|
|
1104
|
+
};
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* List active rounds (for diagnostics).
|
|
1108
|
+
*/
|
|
1109
|
+
listRounds() {
|
|
1110
|
+
return Array.from(this.rounds.keys());
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Compute a consensus result without mutating the round or emitting
|
|
1114
|
+
* feedback. Useful for dashboards and tests.
|
|
1115
|
+
*
|
|
1116
|
+
* Returns null if the round doesn't exist or has no observations.
|
|
1117
|
+
*/
|
|
1118
|
+
previewConsensus(eventId) {
|
|
1119
|
+
const round = this.rounds.get(eventId);
|
|
1120
|
+
if (!round) return null;
|
|
1121
|
+
const observations = Object.values(round.observations);
|
|
1122
|
+
if (observations.length === 0) return null;
|
|
1123
|
+
return computeConsensus(eventId, observations, this.tolerance);
|
|
1124
|
+
}
|
|
1125
|
+
/**
|
|
1126
|
+
* Drop a round from memory. Idempotent.
|
|
1127
|
+
*/
|
|
1128
|
+
clearRound(eventId) {
|
|
1129
|
+
this.rounds.delete(eventId);
|
|
1130
|
+
this.emittedFor.delete(eventId);
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Drop all state (tests).
|
|
1134
|
+
*/
|
|
1135
|
+
clearAll() {
|
|
1136
|
+
this.rounds.clear();
|
|
1137
|
+
this.emittedFor.clear();
|
|
1138
|
+
}
|
|
1139
|
+
// ---------------------------------------------------------------------------
|
|
1140
|
+
// INTERNAL — RESOLUTION + FEEDBACK
|
|
1141
|
+
// ---------------------------------------------------------------------------
|
|
1142
|
+
maybeResolve(eventId) {
|
|
1143
|
+
const round = this.rounds.get(eventId);
|
|
1144
|
+
const observerCount = Object.keys(round.observations).length;
|
|
1145
|
+
if (round.resolved) {
|
|
1146
|
+
const events = this.emitForLateAgents(eventId);
|
|
1147
|
+
return {
|
|
1148
|
+
resolved: true,
|
|
1149
|
+
observerCount,
|
|
1150
|
+
consensus: null,
|
|
1151
|
+
emittedRiskEvents: events
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1154
|
+
if (observerCount < round.minObservers) {
|
|
1155
|
+
return {
|
|
1156
|
+
resolved: false,
|
|
1157
|
+
observerCount,
|
|
1158
|
+
consensus: null,
|
|
1159
|
+
emittedRiskEvents: []
|
|
1160
|
+
};
|
|
1161
|
+
}
|
|
1162
|
+
return this.resolveNow(eventId);
|
|
1163
|
+
}
|
|
1164
|
+
resolveNow(eventId) {
|
|
1165
|
+
const round = this.rounds.get(eventId);
|
|
1166
|
+
const observations = Object.values(round.observations);
|
|
1167
|
+
const consensus = computeConsensus(eventId, observations, this.tolerance);
|
|
1168
|
+
const emitted = [];
|
|
1169
|
+
const emittedSet = this.getEmittedSet(eventId);
|
|
1170
|
+
for (const div of consensus.divergence) {
|
|
1171
|
+
if (emittedSet.has(div.agentId)) continue;
|
|
1172
|
+
emittedSet.add(div.agentId);
|
|
1173
|
+
const ev = this.emitForObserver(eventId, div.agentId, div.severity);
|
|
1174
|
+
if (ev) emitted.push(ev);
|
|
1175
|
+
}
|
|
1176
|
+
const resolvedRound = { ...round, resolved: true };
|
|
1177
|
+
this.rounds.set(eventId, resolvedRound);
|
|
1178
|
+
return {
|
|
1179
|
+
resolved: true,
|
|
1180
|
+
observerCount: observations.length,
|
|
1181
|
+
consensus,
|
|
1182
|
+
emittedRiskEvents: emitted
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
emitForLateAgents(eventId) {
|
|
1186
|
+
const round = this.rounds.get(eventId);
|
|
1187
|
+
const observations = Object.values(round.observations);
|
|
1188
|
+
const consensus = computeConsensus(eventId, observations, this.tolerance);
|
|
1189
|
+
const emitted = [];
|
|
1190
|
+
const emittedSet = this.getEmittedSet(eventId);
|
|
1191
|
+
for (const div of consensus.divergence) {
|
|
1192
|
+
if (emittedSet.has(div.agentId)) continue;
|
|
1193
|
+
emittedSet.add(div.agentId);
|
|
1194
|
+
const ev = this.emitForObserver(eventId, div.agentId, div.severity);
|
|
1195
|
+
if (ev) emitted.push(ev);
|
|
1196
|
+
}
|
|
1197
|
+
return emitted;
|
|
1198
|
+
}
|
|
1199
|
+
emitForObserver(eventId, agentId, severity) {
|
|
1200
|
+
if (severity < this.agreementSeverityThreshold) {
|
|
1201
|
+
this.riskRegistry.recordSuccess(agentId);
|
|
1202
|
+
return null;
|
|
1203
|
+
}
|
|
1204
|
+
const event = {
|
|
1205
|
+
agentId,
|
|
1206
|
+
severity: Math.round(severity),
|
|
1207
|
+
reason: `cross-validation-divergence:${eventId}`,
|
|
1208
|
+
timestamp: this.now()
|
|
1209
|
+
};
|
|
1210
|
+
this.riskRegistry.recordEvent(event);
|
|
1211
|
+
return event;
|
|
1212
|
+
}
|
|
1213
|
+
getEmittedSet(eventId) {
|
|
1214
|
+
let set = this.emittedFor.get(eventId);
|
|
1215
|
+
if (!set) {
|
|
1216
|
+
set = /* @__PURE__ */ new Set();
|
|
1217
|
+
this.emittedFor.set(eventId, set);
|
|
1218
|
+
}
|
|
1219
|
+
return set;
|
|
1220
|
+
}
|
|
1221
|
+
evictIfNeeded() {
|
|
1222
|
+
while (this.rounds.size > this.maxRounds) {
|
|
1223
|
+
const oldest = this.rounds.keys().next().value;
|
|
1224
|
+
if (!oldest) break;
|
|
1225
|
+
this.rounds.delete(oldest);
|
|
1226
|
+
this.emittedFor.delete(oldest);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
};
|
|
1230
|
+
function computeConsensus(eventId, observations, tolerance) {
|
|
1231
|
+
if (observations.length === 0) {
|
|
1232
|
+
return {
|
|
1233
|
+
eventId,
|
|
1234
|
+
observerCount: 0,
|
|
1235
|
+
consensus: {},
|
|
1236
|
+
divergence: []
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1239
|
+
const sorted = [...observations].sort(
|
|
1240
|
+
(a, b) => a.agentId < b.agentId ? -1 : a.agentId > b.agentId ? 1 : 0
|
|
1241
|
+
);
|
|
1242
|
+
const numericFields = /* @__PURE__ */ new Set();
|
|
1243
|
+
const enumFields = /* @__PURE__ */ new Set();
|
|
1244
|
+
for (const obs of sorted) {
|
|
1245
|
+
if (obs.claim.numeric) {
|
|
1246
|
+
for (const f of Object.keys(obs.claim.numeric)) numericFields.add(f);
|
|
1247
|
+
}
|
|
1248
|
+
if (obs.claim.enum) {
|
|
1249
|
+
for (const f of Object.keys(obs.claim.enum)) enumFields.add(f);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
const consensusNumeric = {};
|
|
1253
|
+
for (const field of numericFields) {
|
|
1254
|
+
const samples = [];
|
|
1255
|
+
let dim = 0;
|
|
1256
|
+
for (const obs of sorted) {
|
|
1257
|
+
const v = obs.claim.numeric?.[field];
|
|
1258
|
+
if (!v) continue;
|
|
1259
|
+
samples.push([...v]);
|
|
1260
|
+
dim = Math.max(dim, v.length);
|
|
1261
|
+
}
|
|
1262
|
+
if (samples.length === 0 || dim === 0) continue;
|
|
1263
|
+
const median = [];
|
|
1264
|
+
for (let i = 0; i < dim; i++) {
|
|
1265
|
+
const col = [];
|
|
1266
|
+
for (const s of samples) {
|
|
1267
|
+
if (i < s.length) col.push(s[i]);
|
|
1268
|
+
}
|
|
1269
|
+
median.push(medianOf(col));
|
|
1270
|
+
}
|
|
1271
|
+
consensusNumeric[field] = median;
|
|
1272
|
+
}
|
|
1273
|
+
const consensusEnum = {};
|
|
1274
|
+
for (const field of enumFields) {
|
|
1275
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1276
|
+
for (const obs of sorted) {
|
|
1277
|
+
const v = obs.claim.enum?.[field];
|
|
1278
|
+
if (v === void 0) continue;
|
|
1279
|
+
counts.set(v, (counts.get(v) ?? 0) + 1);
|
|
1280
|
+
}
|
|
1281
|
+
if (counts.size === 0) continue;
|
|
1282
|
+
const sortedByCount = Array.from(counts.entries()).sort((a, b) => {
|
|
1283
|
+
if (b[1] !== a[1]) return b[1] - a[1];
|
|
1284
|
+
return a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0;
|
|
1285
|
+
});
|
|
1286
|
+
consensusEnum[field] = sortedByCount[0][0];
|
|
1287
|
+
}
|
|
1288
|
+
const divergence = sorted.map((obs) => {
|
|
1289
|
+
const breakdown = [];
|
|
1290
|
+
let maxSeverity = 0;
|
|
1291
|
+
if (obs.claim.numeric) {
|
|
1292
|
+
for (const [field, v] of Object.entries(obs.claim.numeric)) {
|
|
1293
|
+
const cons = consensusNumeric[field];
|
|
1294
|
+
if (!cons) continue;
|
|
1295
|
+
const tol = tolerance.perField?.[field] ?? tolerance.defaultNumericTolerance;
|
|
1296
|
+
let lInf = 0;
|
|
1297
|
+
const dim = Math.min(v.length, cons.length);
|
|
1298
|
+
for (let i = 0; i < dim; i++) {
|
|
1299
|
+
const d = Math.abs(v[i] - cons[i]);
|
|
1300
|
+
if (d > lInf) lInf = d;
|
|
1301
|
+
}
|
|
1302
|
+
const sev = numericSeverity(lInf, tol);
|
|
1303
|
+
breakdown.push({ field, kind: "numeric", delta: lInf, severity: sev });
|
|
1304
|
+
if (sev > maxSeverity) maxSeverity = sev;
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
if (obs.claim.enum) {
|
|
1308
|
+
for (const [field, v] of Object.entries(obs.claim.enum)) {
|
|
1309
|
+
const cons = consensusEnum[field];
|
|
1310
|
+
if (cons === void 0) continue;
|
|
1311
|
+
const matches = v === cons;
|
|
1312
|
+
const sev = matches ? 0 : 100;
|
|
1313
|
+
breakdown.push({
|
|
1314
|
+
field,
|
|
1315
|
+
kind: "enum",
|
|
1316
|
+
delta: matches ? 0 : 1,
|
|
1317
|
+
severity: sev
|
|
1318
|
+
});
|
|
1319
|
+
if (sev > maxSeverity) maxSeverity = sev;
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
return {
|
|
1323
|
+
agentId: obs.agentId,
|
|
1324
|
+
severity: maxSeverity,
|
|
1325
|
+
breakdown
|
|
1326
|
+
};
|
|
1327
|
+
});
|
|
1328
|
+
const consensusClaim = {};
|
|
1329
|
+
if (Object.keys(consensusNumeric).length > 0) {
|
|
1330
|
+
consensusClaim.numeric = consensusNumeric;
|
|
1331
|
+
}
|
|
1332
|
+
if (Object.keys(consensusEnum).length > 0) {
|
|
1333
|
+
consensusClaim.enum = consensusEnum;
|
|
1334
|
+
}
|
|
1335
|
+
return {
|
|
1336
|
+
eventId,
|
|
1337
|
+
observerCount: sorted.length,
|
|
1338
|
+
consensus: consensusClaim,
|
|
1339
|
+
divergence
|
|
1340
|
+
};
|
|
1341
|
+
}
|
|
1342
|
+
function numericSeverity(delta, tol) {
|
|
1343
|
+
if (delta <= tol) return 0;
|
|
1344
|
+
if (delta >= 2 * tol) return 100;
|
|
1345
|
+
return (delta - tol) / tol * 100;
|
|
1346
|
+
}
|
|
1347
|
+
function medianOf(xs) {
|
|
1348
|
+
if (xs.length === 0) return 0;
|
|
1349
|
+
const sorted = [...xs].sort((a, b) => a - b);
|
|
1350
|
+
const mid = Math.floor(sorted.length / 2);
|
|
1351
|
+
if (sorted.length % 2 === 1) return sorted[mid];
|
|
1352
|
+
return (sorted[mid - 1] + sorted[mid]) / 2;
|
|
1353
|
+
}
|
|
1354
|
+
var globalCrossValidationRegistry = null;
|
|
1355
|
+
function getCrossValidationRegistry(config) {
|
|
1356
|
+
if (!globalCrossValidationRegistry) {
|
|
1357
|
+
globalCrossValidationRegistry = new CrossValidationRegistry(config);
|
|
1358
|
+
}
|
|
1359
|
+
return globalCrossValidationRegistry;
|
|
1360
|
+
}
|
|
1361
|
+
function resetCrossValidationRegistry() {
|
|
1362
|
+
globalCrossValidationRegistry = null;
|
|
1363
|
+
}
|
|
1364
|
+
function suggestedQuorum(observerTiers, options = {}) {
|
|
1365
|
+
const base = options.base ?? 3;
|
|
1366
|
+
const maxObservers = options.maxObservers ?? 9;
|
|
1367
|
+
let bonus = 0;
|
|
1368
|
+
for (const tier of observerTiers) {
|
|
1369
|
+
switch (tier) {
|
|
1370
|
+
case "low" /* LOW */:
|
|
1371
|
+
break;
|
|
1372
|
+
case "medium" /* MEDIUM */:
|
|
1373
|
+
bonus += 1;
|
|
1374
|
+
break;
|
|
1375
|
+
case "high" /* HIGH */:
|
|
1376
|
+
bonus += 2;
|
|
1377
|
+
break;
|
|
1378
|
+
case "quarantined" /* QUARANTINED */:
|
|
1379
|
+
bonus += 3;
|
|
1380
|
+
break;
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
return Math.min(maxObservers, base + bonus);
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
// src/hololand/ItemManifest.ts
|
|
1387
|
+
var ITEM_DEFAULT_TICK_INTERVAL_MS = 864e5;
|
|
1388
|
+
var DEFAULT_ITEM_VERBAL_FINGERPRINT = {
|
|
1389
|
+
fingerprint_key: "item_default",
|
|
1390
|
+
style: {
|
|
1391
|
+
label: "item_neutral",
|
|
1392
|
+
minSentenceLength: 5,
|
|
1393
|
+
maxSentenceLength: 40,
|
|
1394
|
+
forbiddenPhrases: [],
|
|
1395
|
+
requiredPhrases: [],
|
|
1396
|
+
tone: "neutral"
|
|
1397
|
+
},
|
|
1398
|
+
enforce: false,
|
|
1399
|
+
rolling_window: 50
|
|
1400
|
+
};
|
|
1401
|
+
var DEFAULT_ITEM_AUTONOMOUS_AGENDA = {
|
|
1402
|
+
agent_class: "item",
|
|
1403
|
+
tick_interval_ms: ITEM_DEFAULT_TICK_INTERVAL_MS,
|
|
1404
|
+
daily_budget_usd: 0.05,
|
|
1405
|
+
max_actions_per_tick: 1,
|
|
1406
|
+
max_actions_per_day: 5,
|
|
1407
|
+
pause_on_ceiling: true
|
|
1408
|
+
};
|
|
1409
|
+
var DEFAULT_ITEM_REPUTATION_LEDGER = {
|
|
1410
|
+
world_id: "",
|
|
1411
|
+
subject_id: "",
|
|
1412
|
+
initial_trust: 50,
|
|
1413
|
+
max_behavior_facts: 20,
|
|
1414
|
+
world_ttl_days: 90,
|
|
1415
|
+
emit_world_entry_disclosure: true,
|
|
1416
|
+
disclosure_text: "",
|
|
1417
|
+
deletion_modes: ["npc", "global"],
|
|
1418
|
+
ttl_breach_alert_rule: "behavior_fact_ttl_breach"
|
|
1419
|
+
};
|
|
1420
|
+
var DEFAULT_ITEM_VOCABULARY_REGISTER = {
|
|
1421
|
+
active_register: "medieval-fantasy",
|
|
1422
|
+
max_injected_entries: 20,
|
|
1423
|
+
prepend_tone_hint: true
|
|
1424
|
+
};
|
|
1425
|
+
function createHoloLandItem(id, name, options = {}) {
|
|
1426
|
+
const ancestry = {
|
|
1427
|
+
originType: options.ancestry?.originType ?? "world_spawn",
|
|
1428
|
+
originId: options.ancestry?.originId ?? "world",
|
|
1429
|
+
originName: options.ancestry?.originName ?? "World Spawn",
|
|
1430
|
+
loreEvent: options.ancestry?.loreEvent,
|
|
1431
|
+
crafterNpcId: options.ancestry?.crafterNpcId,
|
|
1432
|
+
materialSourceItemId: options.ancestry?.materialSourceItemId
|
|
1433
|
+
};
|
|
1434
|
+
const state = {
|
|
1435
|
+
durability: options.state?.durability ?? 1,
|
|
1436
|
+
corrosion: options.state?.corrosion ?? 0,
|
|
1437
|
+
curseDepth: options.state?.curseDepth ?? 0,
|
|
1438
|
+
restorationProgress: options.state?.restorationProgress ?? 0,
|
|
1439
|
+
awakened: options.state?.awakened ?? false,
|
|
1440
|
+
equippedDurationSeconds: options.state?.equippedDurationSeconds ?? 0,
|
|
1441
|
+
boundToPlayerId: options.state?.boundToPlayerId
|
|
1442
|
+
};
|
|
1443
|
+
const trajectory = {
|
|
1444
|
+
type: options.trajectory?.type ?? "none",
|
|
1445
|
+
conditionDescription: options.trajectory?.conditionDescription ?? "",
|
|
1446
|
+
targetState: options.trajectory?.targetState ?? {},
|
|
1447
|
+
requiredNpcId: options.trajectory?.requiredNpcId,
|
|
1448
|
+
requiredLocationId: options.trajectory?.requiredLocationId,
|
|
1449
|
+
requiredItemId: options.trajectory?.requiredItemId
|
|
1450
|
+
};
|
|
1451
|
+
const constraint = {
|
|
1452
|
+
description: options.constraint?.description ?? "",
|
|
1453
|
+
affectedEquipmentSlots: options.constraint?.affectedEquipmentSlots,
|
|
1454
|
+
maxEquipDurationSeconds: options.constraint?.maxEquipDurationSeconds,
|
|
1455
|
+
playstyleImpact: options.constraint?.playstyleImpact ?? ""
|
|
1456
|
+
};
|
|
1457
|
+
const verbalFingerprint = {
|
|
1458
|
+
...DEFAULT_ITEM_VERBAL_FINGERPRINT,
|
|
1459
|
+
...options.verbalFingerprint,
|
|
1460
|
+
style: {
|
|
1461
|
+
...DEFAULT_ITEM_VERBAL_FINGERPRINT.style,
|
|
1462
|
+
...options.verbalFingerprint?.style
|
|
1463
|
+
}
|
|
1464
|
+
};
|
|
1465
|
+
const autonomousAgenda = {
|
|
1466
|
+
...DEFAULT_ITEM_AUTONOMOUS_AGENDA,
|
|
1467
|
+
...options.autonomousAgenda
|
|
1468
|
+
};
|
|
1469
|
+
const reputationLedger = {
|
|
1470
|
+
...DEFAULT_ITEM_REPUTATION_LEDGER,
|
|
1471
|
+
subject_id: id,
|
|
1472
|
+
...options.reputationLedger
|
|
1473
|
+
};
|
|
1474
|
+
const vocabularyRegister = {
|
|
1475
|
+
...DEFAULT_ITEM_VOCABULARY_REGISTER,
|
|
1476
|
+
...options.vocabularyRegister
|
|
1477
|
+
};
|
|
1478
|
+
return {
|
|
1479
|
+
id,
|
|
1480
|
+
name,
|
|
1481
|
+
displayName: options.displayName ?? name,
|
|
1482
|
+
description: options.description ?? "",
|
|
1483
|
+
ancestry,
|
|
1484
|
+
state,
|
|
1485
|
+
trajectory,
|
|
1486
|
+
constraint,
|
|
1487
|
+
verbalFingerprint,
|
|
1488
|
+
autonomousAgenda,
|
|
1489
|
+
reputationLedger,
|
|
1490
|
+
vocabularyRegister,
|
|
1491
|
+
speechAwareEncounter: options.speechAwareEncounter,
|
|
1492
|
+
previousItemId: options.previousItemId,
|
|
1493
|
+
nextItemId: options.nextItemId,
|
|
1494
|
+
chainDepth: options.chainDepth ?? 0,
|
|
1495
|
+
traits: options.traits ?? [],
|
|
1496
|
+
tags: options.tags ?? []
|
|
1497
|
+
};
|
|
1498
|
+
}
|
|
1499
|
+
function linkItems(source, derivative) {
|
|
1500
|
+
source.nextItemId = derivative.id;
|
|
1501
|
+
derivative.previousItemId = source.id;
|
|
1502
|
+
derivative.chainDepth = source.chainDepth + 1;
|
|
1503
|
+
derivative.ancestry.materialSourceItemId = source.id;
|
|
1504
|
+
}
|
|
1505
|
+
function getItemChain(item, itemIndex) {
|
|
1506
|
+
const chain = [item];
|
|
1507
|
+
let current = item.previousItemId;
|
|
1508
|
+
while (current) {
|
|
1509
|
+
const prev = itemIndex.get(current);
|
|
1510
|
+
if (!prev) break;
|
|
1511
|
+
chain.unshift(prev);
|
|
1512
|
+
current = prev.previousItemId;
|
|
1513
|
+
}
|
|
1514
|
+
return chain;
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
// src/hololand/StreamingProtocol.ts
|
|
1518
|
+
var PROTOCOL_VERSION = "1.0.0";
|
|
1519
|
+
var MAX_MESSAGE_SIZE = 64 * 1024;
|
|
1520
|
+
var MAX_CHUNK_SIZE = 16 * 1024;
|
|
1521
|
+
var HEARTBEAT_INTERVAL = 5e3;
|
|
1522
|
+
var TIMEOUT_INTERVAL = 15e3;
|
|
1523
|
+
var _StreamProtocol = class _StreamProtocol {
|
|
1524
|
+
constructor() {
|
|
1525
|
+
this.connection = null;
|
|
1526
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
1527
|
+
this.pendingAcks = /* @__PURE__ */ new Map();
|
|
1528
|
+
this.sequenceNumber = 0;
|
|
1529
|
+
this.lastAckSeq = 0;
|
|
1530
|
+
this.heartbeatTimer = null;
|
|
1531
|
+
this.connectionState = "disconnected";
|
|
1532
|
+
}
|
|
1533
|
+
static getInstance() {
|
|
1534
|
+
if (!_StreamProtocol.instance) {
|
|
1535
|
+
_StreamProtocol.instance = new _StreamProtocol();
|
|
1536
|
+
}
|
|
1537
|
+
return _StreamProtocol.instance;
|
|
1538
|
+
}
|
|
1539
|
+
static resetInstance() {
|
|
1540
|
+
_StreamProtocol.instance?.close();
|
|
1541
|
+
_StreamProtocol.instance = null;
|
|
1542
|
+
}
|
|
1543
|
+
// ─── Connection Management ────────────────────────────────────────────────
|
|
1544
|
+
/**
|
|
1545
|
+
* Connect to streaming server
|
|
1546
|
+
*/
|
|
1547
|
+
async connect(url, options) {
|
|
1548
|
+
if (this.connectionState !== "disconnected") {
|
|
1549
|
+
throw new Error("Already connected or connecting");
|
|
1550
|
+
}
|
|
1551
|
+
this.connectionState = "connecting";
|
|
1552
|
+
return new Promise((resolve, reject) => {
|
|
1553
|
+
try {
|
|
1554
|
+
this.connection = new WebSocket(url);
|
|
1555
|
+
this.connection.binaryType = "arraybuffer";
|
|
1556
|
+
this.connection.onopen = () => {
|
|
1557
|
+
this.sendHandshake(options);
|
|
1558
|
+
};
|
|
1559
|
+
this.connection.onmessage = (event) => {
|
|
1560
|
+
const message = this.deserialize(event.data);
|
|
1561
|
+
if (!message) return;
|
|
1562
|
+
this.handleMessage(message);
|
|
1563
|
+
if (message.type === "handshake_ack") {
|
|
1564
|
+
this.connectionState = "connected";
|
|
1565
|
+
this.startHeartbeat();
|
|
1566
|
+
resolve();
|
|
1567
|
+
}
|
|
1568
|
+
};
|
|
1569
|
+
this.connection.onerror = (_event) => {
|
|
1570
|
+
const error = new Error("WebSocket error");
|
|
1571
|
+
if (this.connectionState === "connecting") {
|
|
1572
|
+
reject(error);
|
|
1573
|
+
}
|
|
1574
|
+
this.emit("error", {
|
|
1575
|
+
type: "error",
|
|
1576
|
+
seq: 0,
|
|
1577
|
+
timestamp: Date.now(),
|
|
1578
|
+
reliable: false,
|
|
1579
|
+
priority: 0,
|
|
1580
|
+
payload: { error }
|
|
1581
|
+
});
|
|
1582
|
+
};
|
|
1583
|
+
this.connection.onclose = (event) => {
|
|
1584
|
+
this.connectionState = "disconnected";
|
|
1585
|
+
this.stopHeartbeat();
|
|
1586
|
+
this.emit("close", {
|
|
1587
|
+
type: "close",
|
|
1588
|
+
seq: 0,
|
|
1589
|
+
timestamp: Date.now(),
|
|
1590
|
+
reliable: false,
|
|
1591
|
+
priority: 0,
|
|
1592
|
+
payload: { code: event.code, reason: event.reason }
|
|
1593
|
+
});
|
|
1594
|
+
};
|
|
1595
|
+
} catch (error) {
|
|
1596
|
+
this.connectionState = "disconnected";
|
|
1597
|
+
reject(error);
|
|
1598
|
+
}
|
|
1599
|
+
});
|
|
1600
|
+
}
|
|
1601
|
+
/**
|
|
1602
|
+
* Close connection
|
|
1603
|
+
*/
|
|
1604
|
+
close() {
|
|
1605
|
+
this.stopHeartbeat();
|
|
1606
|
+
if (this.connection) {
|
|
1607
|
+
this.connection.close(1e3, "Client disconnect");
|
|
1608
|
+
this.connection = null;
|
|
1609
|
+
}
|
|
1610
|
+
this.connectionState = "disconnected";
|
|
1611
|
+
}
|
|
1612
|
+
/**
|
|
1613
|
+
* Check if connected
|
|
1614
|
+
*/
|
|
1615
|
+
isConnected() {
|
|
1616
|
+
return this.connectionState === "connected";
|
|
1617
|
+
}
|
|
1618
|
+
// ─── Message Handling ─────────────────────────────────────────────────────
|
|
1619
|
+
/**
|
|
1620
|
+
* Subscribe to message type
|
|
1621
|
+
*/
|
|
1622
|
+
on(type, handler) {
|
|
1623
|
+
if (!this.handlers.has(type)) {
|
|
1624
|
+
this.handlers.set(type, /* @__PURE__ */ new Set());
|
|
1625
|
+
}
|
|
1626
|
+
const h = handler;
|
|
1627
|
+
this.handlers.get(type).add(h);
|
|
1628
|
+
return () => this.handlers.get(type)?.delete(h);
|
|
1629
|
+
}
|
|
1630
|
+
/**
|
|
1631
|
+
* Emit message to handlers
|
|
1632
|
+
*/
|
|
1633
|
+
emit(type, message) {
|
|
1634
|
+
const handlers = this.handlers.get(type);
|
|
1635
|
+
if (handlers) {
|
|
1636
|
+
for (const handler of handlers) {
|
|
1637
|
+
try {
|
|
1638
|
+
handler(message);
|
|
1639
|
+
} catch (error) {
|
|
1640
|
+
console.error(`Handler error for ${type}:`, error);
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
/**
|
|
1646
|
+
* Handle incoming message
|
|
1647
|
+
*/
|
|
1648
|
+
handleMessage(message) {
|
|
1649
|
+
this.lastAckSeq = Math.max(this.lastAckSeq, message.seq);
|
|
1650
|
+
const msgExt = message;
|
|
1651
|
+
if (message.type === "heartbeat_ack" || msgExt.ack) {
|
|
1652
|
+
const ackKey = msgExt.ackSeq || message.seq;
|
|
1653
|
+
const pending = this.pendingAcks.get(ackKey);
|
|
1654
|
+
if (pending) {
|
|
1655
|
+
clearTimeout(pending.timeout);
|
|
1656
|
+
pending.resolve();
|
|
1657
|
+
this.pendingAcks.delete(ackKey);
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
this.emit(message.type, message);
|
|
1661
|
+
}
|
|
1662
|
+
// ─── Message Sending ──────────────────────────────────────────────────────
|
|
1663
|
+
/**
|
|
1664
|
+
* Send message
|
|
1665
|
+
*/
|
|
1666
|
+
send(message) {
|
|
1667
|
+
if (!this.connection || this.connectionState !== "connected") {
|
|
1668
|
+
throw new Error("Not connected");
|
|
1669
|
+
}
|
|
1670
|
+
const fullMessage = {
|
|
1671
|
+
...message,
|
|
1672
|
+
seq: this.sequenceNumber++,
|
|
1673
|
+
timestamp: Date.now()
|
|
1674
|
+
};
|
|
1675
|
+
const data = this.serialize(fullMessage);
|
|
1676
|
+
this.connection.send(data);
|
|
1677
|
+
}
|
|
1678
|
+
/**
|
|
1679
|
+
* Send message and wait for acknowledgment
|
|
1680
|
+
*/
|
|
1681
|
+
async sendReliable(message, timeout = 5e3) {
|
|
1682
|
+
const fullMessage = {
|
|
1683
|
+
...message,
|
|
1684
|
+
seq: this.sequenceNumber++,
|
|
1685
|
+
timestamp: Date.now(),
|
|
1686
|
+
reliable: true
|
|
1687
|
+
};
|
|
1688
|
+
return new Promise((resolve, reject) => {
|
|
1689
|
+
const timeoutId = setTimeout(() => {
|
|
1690
|
+
this.pendingAcks.delete(fullMessage.seq);
|
|
1691
|
+
reject(new Error("Message timeout"));
|
|
1692
|
+
}, timeout);
|
|
1693
|
+
this.pendingAcks.set(fullMessage.seq, { resolve, reject, timeout: timeoutId });
|
|
1694
|
+
const data = this.serialize(fullMessage);
|
|
1695
|
+
this.connection.send(data);
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1698
|
+
// ─── Specific Message Senders ─────────────────────────────────────────────
|
|
1699
|
+
/**
|
|
1700
|
+
* Send handshake
|
|
1701
|
+
*/
|
|
1702
|
+
sendHandshake(options) {
|
|
1703
|
+
const message = {
|
|
1704
|
+
type: "handshake",
|
|
1705
|
+
reliable: true,
|
|
1706
|
+
priority: 255,
|
|
1707
|
+
payload: {
|
|
1708
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
1709
|
+
clientId: options.clientId,
|
|
1710
|
+
clientVersion: options.clientVersion,
|
|
1711
|
+
capabilities: options.capabilities ?? ["entity_sync", "asset_streaming"],
|
|
1712
|
+
compression: "lz4",
|
|
1713
|
+
encryption: "none"
|
|
1714
|
+
}
|
|
1715
|
+
};
|
|
1716
|
+
const fullMessage = {
|
|
1717
|
+
...message,
|
|
1718
|
+
seq: this.sequenceNumber++,
|
|
1719
|
+
timestamp: Date.now()
|
|
1720
|
+
};
|
|
1721
|
+
const data = this.serialize(fullMessage);
|
|
1722
|
+
this.connection.send(data);
|
|
1723
|
+
}
|
|
1724
|
+
/**
|
|
1725
|
+
* Send heartbeat
|
|
1726
|
+
*/
|
|
1727
|
+
sendHeartbeat() {
|
|
1728
|
+
if (!this.isConnected()) return;
|
|
1729
|
+
this.send({
|
|
1730
|
+
type: "heartbeat",
|
|
1731
|
+
reliable: false,
|
|
1732
|
+
priority: 128,
|
|
1733
|
+
payload: {
|
|
1734
|
+
clientTime: Date.now(),
|
|
1735
|
+
lastAckSeq: this.lastAckSeq
|
|
1736
|
+
}
|
|
1737
|
+
});
|
|
1738
|
+
}
|
|
1739
|
+
/**
|
|
1740
|
+
* Join world
|
|
1741
|
+
*/
|
|
1742
|
+
async joinWorld(worldId, spawnPoint) {
|
|
1743
|
+
await this.sendReliable({
|
|
1744
|
+
type: "world_join",
|
|
1745
|
+
priority: 200,
|
|
1746
|
+
payload: {
|
|
1747
|
+
worldId,
|
|
1748
|
+
spawnPoint
|
|
1749
|
+
}
|
|
1750
|
+
});
|
|
1751
|
+
}
|
|
1752
|
+
/**
|
|
1753
|
+
* Leave world
|
|
1754
|
+
*/
|
|
1755
|
+
async leaveWorld() {
|
|
1756
|
+
await this.sendReliable({
|
|
1757
|
+
type: "world_leave",
|
|
1758
|
+
priority: 200,
|
|
1759
|
+
payload: {}
|
|
1760
|
+
});
|
|
1761
|
+
}
|
|
1762
|
+
/**
|
|
1763
|
+
* Send entity update
|
|
1764
|
+
*/
|
|
1765
|
+
sendEntityUpdate(entityId, changes) {
|
|
1766
|
+
this.send({
|
|
1767
|
+
type: "entity_update",
|
|
1768
|
+
reliable: false,
|
|
1769
|
+
priority: 128,
|
|
1770
|
+
payload: {
|
|
1771
|
+
id: entityId,
|
|
1772
|
+
changes,
|
|
1773
|
+
timestamp: Date.now()
|
|
1774
|
+
}
|
|
1775
|
+
});
|
|
1776
|
+
}
|
|
1777
|
+
/**
|
|
1778
|
+
* Send entity RPC
|
|
1779
|
+
*/
|
|
1780
|
+
async sendEntityRPC(entityId, method, args) {
|
|
1781
|
+
const callId = `rpc_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
1782
|
+
await this.sendReliable({
|
|
1783
|
+
type: "entity_rpc",
|
|
1784
|
+
priority: 192,
|
|
1785
|
+
payload: {
|
|
1786
|
+
entityId,
|
|
1787
|
+
method,
|
|
1788
|
+
args,
|
|
1789
|
+
callId
|
|
1790
|
+
}
|
|
1791
|
+
});
|
|
1792
|
+
}
|
|
1793
|
+
/**
|
|
1794
|
+
* Request asset
|
|
1795
|
+
*/
|
|
1796
|
+
async requestAsset(assetId, options = {}) {
|
|
1797
|
+
await this.sendReliable({
|
|
1798
|
+
type: "asset_request",
|
|
1799
|
+
priority: options.priority ?? 128,
|
|
1800
|
+
payload: {
|
|
1801
|
+
assetId,
|
|
1802
|
+
priority: options.priority ?? 128,
|
|
1803
|
+
acceptedFormats: options.acceptedFormats ?? ["gltf", "glb"],
|
|
1804
|
+
maxQuality: options.maxQuality ?? "high"
|
|
1805
|
+
}
|
|
1806
|
+
});
|
|
1807
|
+
}
|
|
1808
|
+
/**
|
|
1809
|
+
* Send player input
|
|
1810
|
+
*/
|
|
1811
|
+
sendPlayerInput(inputs) {
|
|
1812
|
+
this.send({
|
|
1813
|
+
type: "player_input",
|
|
1814
|
+
reliable: false,
|
|
1815
|
+
priority: 192,
|
|
1816
|
+
payload: {
|
|
1817
|
+
playerId: "",
|
|
1818
|
+
// Set by server
|
|
1819
|
+
inputs,
|
|
1820
|
+
timestamp: Date.now()
|
|
1821
|
+
}
|
|
1822
|
+
});
|
|
1823
|
+
}
|
|
1824
|
+
/**
|
|
1825
|
+
* Send chat message
|
|
1826
|
+
*/
|
|
1827
|
+
async sendChat(content, channel = "world", targetId) {
|
|
1828
|
+
await this.sendReliable({
|
|
1829
|
+
type: "chat_message",
|
|
1830
|
+
priority: 160,
|
|
1831
|
+
payload: {
|
|
1832
|
+
senderId: "",
|
|
1833
|
+
// Set by server
|
|
1834
|
+
senderName: "",
|
|
1835
|
+
// Set by server
|
|
1836
|
+
content,
|
|
1837
|
+
channel,
|
|
1838
|
+
targetId
|
|
1839
|
+
}
|
|
1840
|
+
});
|
|
1841
|
+
}
|
|
1842
|
+
/**
|
|
1843
|
+
* Send voice data
|
|
1844
|
+
*/
|
|
1845
|
+
sendVoiceData(data, codec = "opus") {
|
|
1846
|
+
this.send({
|
|
1847
|
+
type: "voice_data",
|
|
1848
|
+
reliable: false,
|
|
1849
|
+
priority: 224,
|
|
1850
|
+
payload: {
|
|
1851
|
+
playerId: "",
|
|
1852
|
+
// Set by server
|
|
1853
|
+
data,
|
|
1854
|
+
codec,
|
|
1855
|
+
sampleRate: 48e3
|
|
1856
|
+
}
|
|
1857
|
+
});
|
|
1858
|
+
}
|
|
1859
|
+
// ─── Serialization ────────────────────────────────────────────────────────
|
|
1860
|
+
/**
|
|
1861
|
+
* Serialize message to binary
|
|
1862
|
+
*/
|
|
1863
|
+
serialize(message) {
|
|
1864
|
+
const json = JSON.stringify(message, (key, value) => {
|
|
1865
|
+
if (value instanceof ArrayBuffer) {
|
|
1866
|
+
return { __type: "ArrayBuffer", data: Array.from(new Uint8Array(value)) };
|
|
1867
|
+
}
|
|
1868
|
+
return value;
|
|
1869
|
+
});
|
|
1870
|
+
const encoder = new TextEncoder();
|
|
1871
|
+
return encoder.encode(json).buffer;
|
|
1872
|
+
}
|
|
1873
|
+
/**
|
|
1874
|
+
* Deserialize binary to message. Returns null on malformed payloads so the
|
|
1875
|
+
* WebSocket onmessage handler does not crash the connection (W2-T1).
|
|
1876
|
+
*
|
|
1877
|
+
* Note: uses raw JSON.parse with a reviver because safeJsonParse does not
|
|
1878
|
+
* expose the reviver hook. The outer try/catch restores crash-safety.
|
|
1879
|
+
*/
|
|
1880
|
+
deserialize(data) {
|
|
1881
|
+
let json;
|
|
1882
|
+
if (data instanceof ArrayBuffer) {
|
|
1883
|
+
const decoder = new TextDecoder();
|
|
1884
|
+
json = decoder.decode(data);
|
|
1885
|
+
} else {
|
|
1886
|
+
json = data;
|
|
1887
|
+
}
|
|
1888
|
+
try {
|
|
1889
|
+
return JSON.parse(json, (_key, value) => {
|
|
1890
|
+
if (value && value.__type === "ArrayBuffer") {
|
|
1891
|
+
return new Uint8Array(value.data).buffer;
|
|
1892
|
+
}
|
|
1893
|
+
return value;
|
|
1894
|
+
});
|
|
1895
|
+
} catch (err) {
|
|
1896
|
+
console.error(
|
|
1897
|
+
`[StreamingProtocol] Malformed JSON payload (${err instanceof Error ? err.message : String(err)})`
|
|
1898
|
+
);
|
|
1899
|
+
return null;
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
// ─── Heartbeat ────────────────────────────────────────────────────────────
|
|
1903
|
+
/**
|
|
1904
|
+
* Start heartbeat timer
|
|
1905
|
+
*/
|
|
1906
|
+
startHeartbeat() {
|
|
1907
|
+
this.stopHeartbeat();
|
|
1908
|
+
this.heartbeatTimer = setInterval(() => {
|
|
1909
|
+
this.sendHeartbeat();
|
|
1910
|
+
}, HEARTBEAT_INTERVAL);
|
|
1911
|
+
}
|
|
1912
|
+
/**
|
|
1913
|
+
* Stop heartbeat timer
|
|
1914
|
+
*/
|
|
1915
|
+
stopHeartbeat() {
|
|
1916
|
+
if (this.heartbeatTimer) {
|
|
1917
|
+
clearInterval(this.heartbeatTimer);
|
|
1918
|
+
this.heartbeatTimer = null;
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
// ─── Statistics ───────────────────────────────────────────────────────────
|
|
1922
|
+
/**
|
|
1923
|
+
* Get protocol statistics
|
|
1924
|
+
*/
|
|
1925
|
+
getStats() {
|
|
1926
|
+
return {
|
|
1927
|
+
messagesSent: this.sequenceNumber,
|
|
1928
|
+
messagesReceived: this.lastAckSeq,
|
|
1929
|
+
pendingAcks: this.pendingAcks.size,
|
|
1930
|
+
connectionState: this.connectionState
|
|
1931
|
+
};
|
|
1932
|
+
}
|
|
1933
|
+
};
|
|
1934
|
+
_StreamProtocol.instance = null;
|
|
1935
|
+
var StreamProtocol = _StreamProtocol;
|
|
1936
|
+
function getStreamProtocol() {
|
|
1937
|
+
return StreamProtocol.getInstance();
|
|
1938
|
+
}
|
|
1939
|
+
function createMessage(type, payload, options = {}) {
|
|
1940
|
+
return {
|
|
1941
|
+
type,
|
|
1942
|
+
payload,
|
|
1943
|
+
reliable: options.reliable ?? (type.includes("_rpc") || type.includes("request")),
|
|
1944
|
+
priority: options.priority ?? 128,
|
|
1945
|
+
channel: options.channel
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
exports.CrossValidationRegistry = CrossValidationRegistry;
|
|
1950
|
+
exports.DEFAULT_ENVELOPES = DEFAULT_ENVELOPES;
|
|
1951
|
+
exports.DEFAULT_ITEM_AUTONOMOUS_AGENDA = DEFAULT_ITEM_AUTONOMOUS_AGENDA;
|
|
1952
|
+
exports.DEFAULT_ITEM_REPUTATION_LEDGER = DEFAULT_ITEM_REPUTATION_LEDGER;
|
|
1953
|
+
exports.DEFAULT_ITEM_VERBAL_FINGERPRINT = DEFAULT_ITEM_VERBAL_FINGERPRINT;
|
|
1954
|
+
exports.DEFAULT_ITEM_VOCABULARY_REGISTER = DEFAULT_ITEM_VOCABULARY_REGISTER;
|
|
1955
|
+
exports.HEARTBEAT_INTERVAL = HEARTBEAT_INTERVAL;
|
|
1956
|
+
exports.HololandClient = HololandClient;
|
|
1957
|
+
exports.ITEM_DEFAULT_TICK_INTERVAL_MS = ITEM_DEFAULT_TICK_INTERVAL_MS;
|
|
1958
|
+
exports.MAX_CHUNK_SIZE = MAX_CHUNK_SIZE;
|
|
1959
|
+
exports.MAX_MESSAGE_SIZE = MAX_MESSAGE_SIZE;
|
|
1960
|
+
exports.PROTOCOL_VERSION = PROTOCOL_VERSION;
|
|
1961
|
+
exports.PhysicsBoundsRegistry = PhysicsBoundsRegistry;
|
|
1962
|
+
exports.StreamProtocol = StreamProtocol;
|
|
1963
|
+
exports.TIMEOUT_INTERVAL = TIMEOUT_INTERVAL;
|
|
1964
|
+
exports.computeConsensus = computeConsensus;
|
|
1965
|
+
exports.connectToHololand = connectToHololand;
|
|
1966
|
+
exports.createHoloLandItem = createHoloLandItem;
|
|
1967
|
+
exports.createMessage = createMessage;
|
|
1968
|
+
exports.createWorldConfig = createWorldConfig;
|
|
1969
|
+
exports.createWorldDefinition = createWorldDefinition;
|
|
1970
|
+
exports.createWorldEnvironment = createWorldEnvironment;
|
|
1971
|
+
exports.createWorldMetadata = createWorldMetadata;
|
|
1972
|
+
exports.disconnectFromHololand = disconnectFromHololand;
|
|
1973
|
+
exports.getCrossValidationRegistry = getCrossValidationRegistry;
|
|
1974
|
+
exports.getHololandClient = getHololandClient;
|
|
1975
|
+
exports.getItemChain = getItemChain;
|
|
1976
|
+
exports.getPhysicsBoundsRegistry = getPhysicsBoundsRegistry;
|
|
1977
|
+
exports.getStreamProtocol = getStreamProtocol;
|
|
1978
|
+
exports.hololand_exports = hololand_exports;
|
|
1979
|
+
exports.linkItems = linkItems;
|
|
1980
|
+
exports.resetCrossValidationRegistry = resetCrossValidationRegistry;
|
|
1981
|
+
exports.resetPhysicsBoundsRegistry = resetPhysicsBoundsRegistry;
|
|
1982
|
+
exports.suggestedQuorum = suggestedQuorum;
|
|
1983
|
+
exports.wrapPhysicsService = wrapPhysicsService;
|
|
1984
|
+
//# sourceMappingURL=chunk-6CTRH7HT.cjs.map
|
|
1985
|
+
//# sourceMappingURL=chunk-6CTRH7HT.cjs.map
|