@holoscript/core 8.0.13 → 8.0.15

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 (191) hide show
  1. package/README.md +20 -13
  2. package/bin/holo-decision.mjs +133 -0
  3. package/bin/holoscript.cjs +0 -0
  4. package/dist/{GLTFPipeline-L76YTXKA.js → GLTFPipeline-FRBZIATS.js} +7 -7
  5. package/dist/{GLTFPipeline-ZWJN7GI6.cjs → GLTFPipeline-MTPP444P.cjs} +11 -11
  6. package/dist/{HoloCompositionParser-P4Y3CXKQ.js → HoloCompositionParser-2GVQAZ2X.js} +7 -7
  7. package/dist/HoloCompositionParser-3NDF6BMX.cjs +45 -0
  8. package/dist/HoloScriptPlusParser-URSIBEAW.cjs +30 -0
  9. package/dist/HoloScriptPlusParser-YCV6L7GI.js +13 -0
  10. package/dist/{HoloScriptRuntime-YBYXJHJN.cjs → HoloScriptRuntime-CRWI6C3P.cjs} +5 -5
  11. package/dist/{HoloScriptRuntime-UTRLJI5L.js → HoloScriptRuntime-IAZGHPFP.js} +4 -4
  12. package/dist/{SceneIRCompiler-63KA3M2F.js → SceneIRCompiler-BJQMKLWL.js} +7 -7
  13. package/dist/{SceneIRCompiler-KWUFHZ4O.cjs → SceneIRCompiler-RTPPDQAV.cjs} +12 -12
  14. package/dist/{chunk-FWCHPCD4.js → chunk-22AULOAL.js} +5 -5
  15. package/dist/{chunk-G35CAQ7I.cjs → chunk-2DJIS7TH.cjs} +5 -5
  16. package/dist/{chunk-LHUDAJQT.cjs → chunk-2PVEXEOL.cjs} +5 -5
  17. package/dist/{chunk-WWNCM473.js → chunk-2UP2J3OK.js} +4 -4
  18. package/dist/{chunk-HVX7QQYK.js → chunk-3AUYBQ5I.js} +3 -3
  19. package/dist/{chunk-TSTFYGGX.js → chunk-3MQAOMKD.js} +3 -3
  20. package/dist/{chunk-FWKEY4LD.js → chunk-4AGNARX6.js} +3 -3
  21. package/dist/{chunk-WNYXT4TE.cjs → chunk-4CQ7ULXZ.cjs} +3 -3
  22. package/dist/{chunk-U3D4SYQ5.js → chunk-5LCJDX5A.js} +3 -3
  23. package/dist/{chunk-IK6Z2HNC.js → chunk-6OQHLNTT.js} +2 -2
  24. package/dist/{chunk-EI3J6LTW.cjs → chunk-6RDHWSZM.cjs} +217 -217
  25. package/dist/{chunk-77QI552M.js → chunk-7AY66PZP.js} +3 -3
  26. package/dist/{chunk-7IDJDMPU.cjs → chunk-7FYSSI3C.cjs} +27 -2
  27. package/dist/{chunk-BP4KTMLY.js → chunk-7HDRN5BW.js} +4 -4
  28. package/dist/{chunk-SQAAWO4V.cjs → chunk-7YKNV2BE.cjs} +5 -5
  29. package/dist/{chunk-WTH23ISI.js → chunk-AAUQTR7I.js} +4 -4
  30. package/dist/{chunk-OC6GV5QH.cjs → chunk-AN3ZH7M7.cjs} +38 -38
  31. package/dist/{chunk-YW3I2FQL.js → chunk-ANMME7XT.js} +4 -2
  32. package/dist/{chunk-A4OOLBZD.js → chunk-ATRAK4RC.js} +5 -5
  33. package/dist/{chunk-BQJ3YBF3.js → chunk-AUF7HFOO.js} +724 -647
  34. package/dist/{chunk-2X3IPCBK.cjs → chunk-AUMTQV64.cjs} +7 -7
  35. package/dist/chunk-AUU4ACJP.cjs +1605 -0
  36. package/dist/{chunk-QQFB4RT2.cjs → chunk-BTVHY3UB.cjs} +2 -2
  37. package/dist/{chunk-ZK7KX5CD.cjs → chunk-CMEINO5I.cjs} +190 -74
  38. package/dist/{chunk-BCP4E7MD.cjs → chunk-CRUIGXF7.cjs} +26 -10
  39. package/dist/{chunk-2E6PP5UE.cjs → chunk-E2SNPMBO.cjs} +11 -11
  40. package/dist/{chunk-2BYAUHBO.js → chunk-E4YS5SIZ.js} +90 -25
  41. package/dist/{chunk-KFVNCW4Q.js → chunk-EKNWUSGW.js} +3 -3
  42. package/dist/{chunk-JEJ7TT54.js → chunk-ETIJOUIO.js} +4 -4
  43. package/dist/{chunk-FRSKLX6I.js → chunk-F33KLYOS.js} +12 -9
  44. package/dist/{chunk-GGR7QUKK.cjs → chunk-F47FEV4X.cjs} +40 -40
  45. package/dist/{chunk-J3UHV5T4.cjs → chunk-FCGTI7FO.cjs} +4 -4
  46. package/dist/{chunk-RRQIAJLQ.cjs → chunk-FGTXAVKG.cjs} +5 -5
  47. package/dist/{chunk-2KKOYZYI.cjs → chunk-FPGYWNNA.cjs} +5 -5
  48. package/dist/{chunk-65S62L4D.cjs → chunk-FQ4MYZYU.cjs} +20 -20
  49. package/dist/{chunk-UGQ3QNV6.js → chunk-FT4FGTR6.js} +24 -8
  50. package/dist/{chunk-Q4K2GEMW.cjs → chunk-FVNV4WHQ.cjs} +20 -17
  51. package/dist/{chunk-SJIRCTIS.cjs → chunk-HSGJFCVJ.cjs} +2 -2
  52. package/dist/{chunk-B3CWTCK2.js → chunk-IA7FCSRY.js} +27 -2
  53. package/dist/{chunk-OIBRWLPY.cjs → chunk-ILO2KMER.cjs} +55 -4
  54. package/dist/{chunk-ZRPALBQB.cjs → chunk-IPBSNGAN.cjs} +92 -27
  55. package/dist/{chunk-FHVPN7BN.js → chunk-IX2U3RQT.js} +3 -3
  56. package/dist/{chunk-QEDMOGF3.cjs → chunk-IYK6LMQ7.cjs} +7 -7
  57. package/dist/{chunk-G6EKZHXY.js → chunk-J3VVM6GV.js} +4 -4
  58. package/dist/{chunk-LMB555QB.cjs → chunk-J74S4ZMF.cjs} +18 -18
  59. package/dist/{chunk-36NPLOI4.cjs → chunk-JERWCCEJ.cjs} +4 -2
  60. package/dist/{chunk-RVNXBF2M.js → chunk-JTDDLCSP.js} +4 -4
  61. package/dist/{chunk-VTEXJOSD.cjs → chunk-K53L47NH.cjs} +30 -30
  62. package/dist/{chunk-IJU6AS67.cjs → chunk-LJTM5ONX.cjs} +23 -23
  63. package/dist/{chunk-G6KACNMO.js → chunk-LJVVOVA6.js} +4 -4
  64. package/dist/{chunk-PDXX5UI4.cjs → chunk-LNJKBQ2B.cjs} +38 -38
  65. package/dist/{chunk-EM2OGPYE.js → chunk-M2GDE3NV.js} +3 -3
  66. package/dist/{chunk-CP7V3ATL.js → chunk-MSZNGI5P.js} +52 -5
  67. package/dist/{chunk-P7JEKJTZ.cjs → chunk-N2BOTBPG.cjs} +27 -16
  68. package/dist/{chunk-LB3ZZMKT.cjs → chunk-NFALJJCH.cjs} +12 -12
  69. package/dist/{chunk-XF63CZ7E.cjs → chunk-NRZRBK25.cjs} +6 -6
  70. package/dist/{chunk-GZPUA2TL.cjs → chunk-NTSLNIY7.cjs} +10 -10
  71. package/dist/{chunk-Y57AVOM2.cjs → chunk-NZJOAWJM.cjs} +4 -4
  72. package/dist/{chunk-RXQNRZ5F.js → chunk-OG7RKWWX.js} +3 -3
  73. package/dist/{chunk-VVAAZITA.cjs → chunk-OQVHCYY4.cjs} +5 -5
  74. package/dist/{chunk-PJFTTSKE.js → chunk-PFZ5WLIP.js} +4 -4
  75. package/dist/{chunk-PXVAPGTR.cjs → chunk-PHLNABJD.cjs} +3788 -1138
  76. package/dist/{chunk-SQXAZHDG.js → chunk-PLK3DLTF.js} +3 -3
  77. package/dist/{chunk-QBY7LRN2.js → chunk-PMACVMHL.js} +3 -3
  78. package/dist/{chunk-DJ5BNRIS.js → chunk-PV2OXNP5.js} +3684 -1041
  79. package/dist/{chunk-F3YT6GUF.cjs → chunk-Q6VW7MGX.cjs} +14 -14
  80. package/dist/{chunk-DUG3OQAS.js → chunk-QC3CAVFN.js} +187 -70
  81. package/dist/{chunk-NQN5LFN4.cjs → chunk-QKLEDRHN.cjs} +19 -19
  82. package/dist/{chunk-2EGGAZT3.js → chunk-QS27OYBU.js} +3 -3
  83. package/dist/{chunk-4376VHNJ.js → chunk-RUB7WL6C.js} +3 -3
  84. package/dist/{chunk-5LVFTGKH.js → chunk-TW2AH2ZS.js} +3 -3
  85. package/dist/{chunk-AATYYLYK.js → chunk-TZM6DKSJ.js} +18 -7
  86. package/dist/{chunk-ESSEF6U2.js → chunk-U227RWXB.js} +3 -3
  87. package/dist/{chunk-TC7JEO6R.cjs → chunk-U6CQOM5Q.cjs} +711 -52
  88. package/dist/{chunk-Z557DVYN.js → chunk-ULT2QAV5.js} +4 -4
  89. package/dist/{chunk-S4O7CFHQ.cjs → chunk-VSO6HPDZ.cjs} +7 -7
  90. package/dist/{chunk-ONPVM4IV.js → chunk-WQJMSSJT.js} +698 -45
  91. package/dist/{chunk-GILYQ5VH.cjs → chunk-WXSDBWGM.cjs} +4 -4
  92. package/dist/{chunk-UTUD6GJI.js → chunk-X5PMMK7H.js} +3 -3
  93. package/dist/{chunk-IFW5IW4L.cjs → chunk-X5ZLSPU2.cjs} +742 -657
  94. package/dist/{chunk-QM7FJB5W.js → chunk-X727CQ7X.js} +5 -5
  95. package/dist/{chunk-566ZB4LZ.cjs → chunk-XHZYS4QO.cjs} +5 -5
  96. package/dist/{chunk-RZ2EPXO3.cjs → chunk-XRQCTTDC.cjs} +8 -8
  97. package/dist/{chunk-5FYMCVBY.js → chunk-YBIHSN55.js} +4 -4
  98. package/dist/{chunk-FG6PYGIZ.js → chunk-Z574GVI3.js} +4 -4
  99. package/dist/{chunk-ZVQMKUGJ.js → chunk-Z5V3KA7L.js} +2 -2
  100. package/dist/chunk-ZGDEOXGU.js +1571 -0
  101. package/dist/{chunk-IS7NTKY5.cjs → chunk-ZHW6TDZ6.cjs} +14 -14
  102. package/dist/{chunk-CKV5NYAE.js → chunk-ZPHCTPR6.js} +4 -4
  103. package/dist/{chunk-3IUHTGDD.cjs → chunk-ZXXC2GXB.cjs} +38 -38
  104. package/dist/cli/holoscript-runner.cjs +169 -20
  105. package/dist/cli/holoscript-runner.js +163 -14
  106. package/dist/compiler/agent-inference.cjs +8 -8
  107. package/dist/compiler/agent-inference.js +4 -4
  108. package/dist/compiler/android-xr.cjs +7 -7
  109. package/dist/compiler/android-xr.js +5 -5
  110. package/dist/compiler/android.cjs +6 -6
  111. package/dist/compiler/android.js +4 -4
  112. package/dist/compiler/context.cjs +6 -6
  113. package/dist/compiler/context.js +3 -3
  114. package/dist/compiler/daimon-seed.cjs +9 -9
  115. package/dist/compiler/daimon-seed.js +4 -4
  116. package/dist/compiler/domain-block-utils.cjs +165 -165
  117. package/dist/compiler/domain-block-utils.js +4 -4
  118. package/dist/compiler/dtdl.cjs +7 -7
  119. package/dist/compiler/dtdl.js +4 -4
  120. package/dist/compiler/gltf-pipeline.cjs +8 -8
  121. package/dist/compiler/gltf-pipeline.js +1 -1
  122. package/dist/compiler/godot.cjs +6 -6
  123. package/dist/compiler/godot.js +5 -5
  124. package/dist/compiler/incremental.cjs +8 -8
  125. package/dist/compiler/incremental.js +3 -3
  126. package/dist/compiler/index.cjs +2275 -212
  127. package/dist/compiler/index.d.ts +29 -1
  128. package/dist/compiler/index.js +2078 -66
  129. package/dist/compiler/ios.cjs +6 -6
  130. package/dist/compiler/ios.js +4 -4
  131. package/dist/compiler/llm-provider-capabilities.cjs +6 -6
  132. package/dist/compiler/llm-provider-capabilities.js +3 -3
  133. package/dist/compiler/openxr.cjs +6 -6
  134. package/dist/compiler/openxr.js +5 -5
  135. package/dist/compiler/sdf.cjs +7 -7
  136. package/dist/compiler/sdf.js +5 -5
  137. package/dist/compiler/state.cjs +6 -6
  138. package/dist/compiler/state.js +4 -4
  139. package/dist/compiler/trait-composition.cjs +7 -7
  140. package/dist/compiler/trait-composition.js +3 -3
  141. package/dist/compiler/unity.cjs +6 -6
  142. package/dist/compiler/unity.js +5 -5
  143. package/dist/compiler/unreal.cjs +7 -7
  144. package/dist/compiler/unreal.js +5 -5
  145. package/dist/compiler/urdf.cjs +14 -14
  146. package/dist/compiler/urdf.js +5 -5
  147. package/dist/compiler/usd-physics.cjs +7 -7
  148. package/dist/compiler/usd-physics.js +4 -4
  149. package/dist/compiler/visionos.cjs +6 -6
  150. package/dist/compiler/visionos.js +5 -5
  151. package/dist/compiler/vrchat.cjs +7 -7
  152. package/dist/compiler/vrchat.js +5 -5
  153. package/dist/compiler/wasm.cjs +10 -10
  154. package/dist/compiler/wasm.js +5 -5
  155. package/dist/compiler/webgpu.cjs +6 -6
  156. package/dist/compiler/webgpu.js +5 -5
  157. package/dist/constants.cjs +99 -99
  158. package/dist/constants.js +3 -3
  159. package/dist/debugger.cjs +5 -5
  160. package/dist/debugger.js +3 -3
  161. package/dist/{dist-GRMOP2UL.cjs → dist-YGATNURH.cjs} +705 -9
  162. package/dist/{dist-ZBUKU2JG.js → dist-ZEZXRCBG.js} +701 -10
  163. package/dist/entries/scripting.cjs +8 -8
  164. package/dist/entries/scripting.js +4 -4
  165. package/dist/evolution/index.cjs +20 -20
  166. package/dist/evolution/index.js +8 -8
  167. package/dist/index.cjs +1099 -826
  168. package/dist/index.d.ts +78 -5
  169. package/dist/index.js +265 -120
  170. package/dist/parser/HoloCompositionTypes.d.ts +1 -1
  171. package/dist/parser.cjs +21 -21
  172. package/dist/parser.js +7 -7
  173. package/dist/reconstruction/index.cjs +127 -38
  174. package/dist/reconstruction/index.d.ts +159 -0
  175. package/dist/reconstruction/index.js +11 -2
  176. package/dist/runtime.cjs +9 -9
  177. package/dist/runtime.d.ts +1 -0
  178. package/dist/runtime.js +3 -3
  179. package/dist/traitDocs/traitDocs.cjs +8 -8
  180. package/dist/traitDocs/traitDocs.js +2 -2
  181. package/dist/traits/botanical-lotus.d.ts +61 -0
  182. package/dist/traits/index.cjs +761 -673
  183. package/dist/traits/index.d.ts +65 -0
  184. package/dist/traits/index.js +102 -27
  185. package/dist/types/HoloScriptPlus.d.ts +1 -1
  186. package/package.json +71 -65
  187. package/dist/HoloCompositionParser-6GW2BZID.cjs +0 -45
  188. package/dist/HoloScriptPlusParser-HQV6IJAH.js +0 -13
  189. package/dist/HoloScriptPlusParser-RFNHRMPE.cjs +0 -30
  190. package/dist/chunk-DVHZD5HV.cjs +0 -639
  191. package/dist/chunk-G72754QB.js +0 -625
@@ -7,7 +7,7 @@ var chunkENZCIQZC_cjs = require('./chunk-ENZCIQZC.cjs');
7
7
  var chunk4PDEPEQW_cjs = require('./chunk-4PDEPEQW.cjs');
8
8
  var chunkVHORVGCG_cjs = require('./chunk-VHORVGCG.cjs');
9
9
  var chunkYP5CHEYU_cjs = require('./chunk-YP5CHEYU.cjs');
10
- var chunkSJIRCTIS_cjs = require('./chunk-SJIRCTIS.cjs');
10
+ var chunkHSGJFCVJ_cjs = require('./chunk-HSGJFCVJ.cjs');
11
11
  var chunkILRBGFVD_cjs = require('./chunk-ILRBGFVD.cjs');
12
12
  var chunkQ47JEE2C_cjs = require('./chunk-Q47JEE2C.cjs');
13
13
  var chunkZHPMP447_cjs = require('./chunk-ZHPMP447.cjs');
@@ -2727,6 +2727,44 @@ var evolveProgramHandler = {
2727
2727
  }
2728
2728
  };
2729
2729
 
2730
+ // src/traits/FreezeWhenTrait.ts
2731
+ var DEFAULT_EXEMPT = ["fix", "native-format", "infra-repair"];
2732
+ var freezeWhenHandler = {
2733
+ name: "freeze_when",
2734
+ defaultConfig: {
2735
+ id: "",
2736
+ scope: "",
2737
+ signal: "",
2738
+ unfreeze: "",
2739
+ exempt: DEFAULT_EXEMPT,
2740
+ severity: "advisory",
2741
+ reason: "",
2742
+ repair: ""
2743
+ },
2744
+ onAttach(node, config, context) {
2745
+ node.__freezeWhen = {
2746
+ id: config.id,
2747
+ scope: config.scope,
2748
+ signal: config.signal,
2749
+ unfreeze: config.unfreeze,
2750
+ exempt: config.exempt ?? DEFAULT_EXEMPT,
2751
+ severity: config.severity ?? "advisory",
2752
+ reason: config.reason ?? "",
2753
+ repair: config.repair ?? ""
2754
+ };
2755
+ context.emit?.("freeze_declared", {
2756
+ node,
2757
+ rule: node.__freezeWhen,
2758
+ derived: true,
2759
+ nativeExempt: true
2760
+ });
2761
+ },
2762
+ onDetach(node, _config, context) {
2763
+ delete node.__freezeWhen;
2764
+ context.emit?.("freeze_when_detached", { node });
2765
+ }
2766
+ };
2767
+
2730
2768
  // src/traits/AiUpscalingTrait.ts
2731
2769
  var aiUpscalingHandler = {
2732
2770
  name: "ai_upscaling",
@@ -21115,6 +21153,33 @@ var NetworkedTrait = class {
21115
21153
  lerpVector3(a, b, t) {
21116
21154
  return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];
21117
21155
  }
21156
+ /**
21157
+ * SLERP for networked rotation interpolation (tuple-in / tuple-out).
21158
+ *
21159
+ * DO NOT "dedup" this into `../math/Quaternion.slerp` without reading this first.
21160
+ * It is a near-duplicate of that function — same shortest-arc flip, same
21161
+ * `dot > 0.9995` normalize-lerp fallback, same s0/s1 coefficients — but it is
21162
+ * deliberately NOT bit-identical: the main branch below returns the raw
21163
+ * `s0*a + s1*b` combination, whereas `Quaternion.slerp` wraps its result in
21164
+ * `normalize(...)`. For exact unit inputs the two agree analytically; in floating
21165
+ * point they differ in the last ULPs.
21166
+ *
21167
+ * That matters here because this is a netcode path: rotations interpolated by two
21168
+ * clients on different builds must agree, and a last-ULP change is a *behavior*
21169
+ * change that no single-version test can catch (the failure mode is version-skew
21170
+ * divergence, which only reproduces with two builds live). Migrating this requires
21171
+ * either bit-exactness proven against golden values for every branch, or a
21172
+ * cross-version replay test — neither exists today.
21173
+ *
21174
+ * Also note `Quaternion.slerp` is currently package-private (not in core's
21175
+ * package.json `exports`) and returns a hybrid `{x,y,z,w}` object with
21176
+ * NON-enumerable numeric indices — it indexes like a tuple but `JSON.stringify`
21177
+ * drops the indices and spreading it throws. It is not a drop-in for a real tuple
21178
+ * on a serialization path.
21179
+ *
21180
+ * Analysis: ai-ecosystem `research/2026-07-15_interpolation.md` +
21181
+ * `research/2026-07-15_native-interpolate-trait-feasibility.md`.
21182
+ */
21118
21183
  slerpQuat(a, b, t) {
21119
21184
  let dot = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
21120
21185
  const bNorm = dot < 0 ? [-b[0], -b[1], -b[2], -b[3]] : [...b];
@@ -24325,6 +24390,200 @@ export default IframeSandbox;`;
24325
24390
  }
24326
24391
  };
24327
24392
 
24393
+ // src/traits/RetryTrait.ts
24394
+ function computeDelay(config, attempt) {
24395
+ let delay;
24396
+ switch (config.backoff) {
24397
+ case "exponential":
24398
+ delay = config.base_delay_ms * Math.pow(2, attempt);
24399
+ break;
24400
+ case "linear":
24401
+ delay = config.base_delay_ms * (attempt + 1);
24402
+ break;
24403
+ case "constant":
24404
+ default:
24405
+ delay = config.base_delay_ms;
24406
+ break;
24407
+ }
24408
+ delay = Math.min(delay, config.max_delay_ms);
24409
+ if (config.jitter > 0) {
24410
+ const jitterAmount = delay * config.jitter;
24411
+ delay += Math.random() * jitterAmount * 2 - jitterAmount;
24412
+ }
24413
+ return Math.max(0, Math.round(delay));
24414
+ }
24415
+ var retryHandler = {
24416
+ name: "retry",
24417
+ defaultConfig: {
24418
+ max_retries: 3,
24419
+ base_delay_ms: 1e3,
24420
+ max_delay_ms: 3e4,
24421
+ backoff: "exponential",
24422
+ jitter: 0.1,
24423
+ circuit_threshold: 5,
24424
+ circuit_reset_ms: 6e4
24425
+ },
24426
+ onAttach(node, _config, _context) {
24427
+ const state = {
24428
+ circuit: "closed",
24429
+ consecutiveFailures: 0,
24430
+ circuitOpenedAt: 0,
24431
+ totalAttempts: 0,
24432
+ totalSuccesses: 0,
24433
+ totalFailures: 0,
24434
+ pendingActions: /* @__PURE__ */ new Map(),
24435
+ actionCounter: 0
24436
+ };
24437
+ node.__retryState = state;
24438
+ },
24439
+ onDetach(node, _config, _context) {
24440
+ delete node.__retryState;
24441
+ },
24442
+ onUpdate(node, config, context, _delta) {
24443
+ const state = node.__retryState;
24444
+ if (!state) return;
24445
+ if (state.circuit === "open") {
24446
+ const elapsed = Date.now() - state.circuitOpenedAt;
24447
+ if (elapsed >= config.circuit_reset_ms) {
24448
+ state.circuit = "half-open";
24449
+ context.emit?.("retry:circuit_half", {
24450
+ testAttempt: state.totalAttempts + 1
24451
+ });
24452
+ }
24453
+ }
24454
+ },
24455
+ onEvent(node, config, context, event) {
24456
+ const state = node.__retryState;
24457
+ if (!state) return;
24458
+ const eventType = typeof event === "string" ? event : event.type;
24459
+ const payload = extractPayload(event);
24460
+ switch (eventType) {
24461
+ case "retry:execute": {
24462
+ const actionName = payload.action;
24463
+ if (!actionName) break;
24464
+ if (state.circuit === "open") {
24465
+ context.emit?.("retry:failure", {
24466
+ actionName,
24467
+ attempt: 0,
24468
+ error: "Circuit breaker is OPEN"
24469
+ });
24470
+ break;
24471
+ }
24472
+ const retryId = `retry_${state.actionCounter++}`;
24473
+ state.pendingActions.set(retryId, {
24474
+ actionName,
24475
+ attempt: 0,
24476
+ startedAt: Date.now()
24477
+ });
24478
+ state.totalAttempts++;
24479
+ context.emit?.("retry:attempt", {
24480
+ retryId,
24481
+ actionName,
24482
+ attempt: 0,
24483
+ maxRetries: config.max_retries
24484
+ });
24485
+ context.emit?.(actionName, {
24486
+ ...payload.params,
24487
+ __retryId: retryId
24488
+ });
24489
+ break;
24490
+ }
24491
+ case "retry:action_result": {
24492
+ const retryId = payload.retryId;
24493
+ const success = payload.success;
24494
+ const error = payload.error;
24495
+ const pending = state.pendingActions.get(retryId);
24496
+ if (!pending) break;
24497
+ if (success) {
24498
+ state.totalSuccesses++;
24499
+ state.consecutiveFailures = 0;
24500
+ state.pendingActions.delete(retryId);
24501
+ if (state.circuit === "half-open") {
24502
+ state.circuit = "closed";
24503
+ context.emit?.("retry:circuit_close", {
24504
+ recoveredAfterMs: Date.now() - state.circuitOpenedAt
24505
+ });
24506
+ }
24507
+ context.emit?.("retry:success", {
24508
+ actionName: pending.actionName,
24509
+ attempt: pending.attempt,
24510
+ elapsed: Date.now() - pending.startedAt
24511
+ });
24512
+ } else {
24513
+ state.totalFailures++;
24514
+ state.consecutiveFailures++;
24515
+ pending.attempt++;
24516
+ context.emit?.("retry:failure", {
24517
+ actionName: pending.actionName,
24518
+ attempt: pending.attempt,
24519
+ error: error ?? "unknown"
24520
+ });
24521
+ if (state.consecutiveFailures >= config.circuit_threshold) {
24522
+ state.circuit = "open";
24523
+ state.circuitOpenedAt = Date.now();
24524
+ state.pendingActions.delete(retryId);
24525
+ context.emit?.("retry:circuit_open", {
24526
+ consecutiveFailures: state.consecutiveFailures,
24527
+ resetMs: config.circuit_reset_ms
24528
+ });
24529
+ break;
24530
+ }
24531
+ if (state.circuit === "half-open") {
24532
+ state.circuit = "open";
24533
+ state.circuitOpenedAt = Date.now();
24534
+ state.pendingActions.delete(retryId);
24535
+ context.emit?.("retry:circuit_open", {
24536
+ consecutiveFailures: state.consecutiveFailures,
24537
+ resetMs: config.circuit_reset_ms
24538
+ });
24539
+ break;
24540
+ }
24541
+ if (pending.attempt > config.max_retries) {
24542
+ state.pendingActions.delete(retryId);
24543
+ context.emit?.("retry:exhausted", {
24544
+ actionName: pending.actionName,
24545
+ totalAttempts: pending.attempt
24546
+ });
24547
+ } else {
24548
+ const delay = computeDelay(config, pending.attempt - 1);
24549
+ state.totalAttempts++;
24550
+ setTimeout(() => {
24551
+ if (!node.__retryState) return;
24552
+ context.emit?.("retry:attempt", {
24553
+ retryId,
24554
+ actionName: pending.actionName,
24555
+ attempt: pending.attempt,
24556
+ maxRetries: config.max_retries
24557
+ });
24558
+ context.emit?.(pending.actionName, {
24559
+ __retryId: retryId
24560
+ });
24561
+ }, delay);
24562
+ }
24563
+ }
24564
+ break;
24565
+ }
24566
+ case "retry:reset_circuit": {
24567
+ state.circuit = "closed";
24568
+ state.consecutiveFailures = 0;
24569
+ context.emit?.("retry:circuit_close", { recoveredAfterMs: 0 });
24570
+ break;
24571
+ }
24572
+ case "retry:get_status": {
24573
+ context.emit?.("retry:status", {
24574
+ circuit: state.circuit,
24575
+ consecutiveFailures: state.consecutiveFailures,
24576
+ totalAttempts: state.totalAttempts,
24577
+ totalSuccesses: state.totalSuccesses,
24578
+ totalFailures: state.totalFailures,
24579
+ pending: state.pendingActions.size
24580
+ });
24581
+ break;
24582
+ }
24583
+ }
24584
+ }
24585
+ };
24586
+
24328
24587
  // src/traits/SchedulerTrait.ts
24329
24588
  var schedulerHandler = {
24330
24589
  name: "scheduler",
@@ -25414,6 +25673,110 @@ function addEntry(state, config, context, level, payload) {
25414
25673
  }
25415
25674
  }
25416
25675
 
25676
+ // src/traits/CacheTrait.ts
25677
+ var cacheHandler = {
25678
+ name: "cache",
25679
+ defaultConfig: {
25680
+ max_size: 1e3,
25681
+ default_ttl_ms: 6e4,
25682
+ eviction_policy: "lru"
25683
+ },
25684
+ onAttach(node, _config, _context) {
25685
+ node.__cacheState = {
25686
+ entries: /* @__PURE__ */ new Map(),
25687
+ hits: 0,
25688
+ misses: 0,
25689
+ evictions: 0
25690
+ };
25691
+ },
25692
+ onDetach(node) {
25693
+ delete node.__cacheState;
25694
+ },
25695
+ onUpdate(node, config, _context, _delta) {
25696
+ const state = node.__cacheState;
25697
+ if (!state) return;
25698
+ const now = Date.now();
25699
+ for (const [key, entry] of state.entries) {
25700
+ if (entry.expiresAt > 0 && now >= entry.expiresAt) {
25701
+ state.entries.delete(key);
25702
+ state.evictions++;
25703
+ }
25704
+ }
25705
+ },
25706
+ onEvent(node, config, context, event) {
25707
+ const state = node.__cacheState;
25708
+ if (!state) return;
25709
+ const eventType = typeof event === "string" ? event : event.type;
25710
+ switch (eventType) {
25711
+ case "cache:set": {
25712
+ const key = event.key;
25713
+ if (!key) break;
25714
+ const ttl = event.ttl ?? config.default_ttl_ms;
25715
+ if (state.entries.size >= config.max_size && !state.entries.has(key)) {
25716
+ evictOne(state, config, context);
25717
+ }
25718
+ const now = Date.now();
25719
+ state.entries.set(key, {
25720
+ value: event.value,
25721
+ expiresAt: ttl > 0 ? now + ttl : 0,
25722
+ accessedAt: now,
25723
+ createdAt: now
25724
+ });
25725
+ break;
25726
+ }
25727
+ case "cache:get": {
25728
+ const key = event.key;
25729
+ if (!key) break;
25730
+ const entry = state.entries.get(key);
25731
+ if (entry && (entry.expiresAt === 0 || Date.now() < entry.expiresAt)) {
25732
+ state.hits++;
25733
+ entry.accessedAt = Date.now();
25734
+ context.emit?.("cache:result", { key, value: entry.value, hit: true });
25735
+ } else {
25736
+ state.misses++;
25737
+ if (entry) state.entries.delete(key);
25738
+ context.emit?.("cache:result", { key, value: void 0, hit: false });
25739
+ }
25740
+ break;
25741
+ }
25742
+ case "cache:invalidate": {
25743
+ const key = event.key;
25744
+ if (key) state.entries.delete(key);
25745
+ break;
25746
+ }
25747
+ case "cache:clear": {
25748
+ state.entries.clear();
25749
+ break;
25750
+ }
25751
+ case "cache:get_stats": {
25752
+ context.emit?.("cache:stats", {
25753
+ hits: state.hits,
25754
+ misses: state.misses,
25755
+ size: state.entries.size,
25756
+ evictions: state.evictions,
25757
+ hitRate: state.hits + state.misses > 0 ? state.hits / (state.hits + state.misses) : 0
25758
+ });
25759
+ break;
25760
+ }
25761
+ }
25762
+ }
25763
+ };
25764
+ function evictOne(state, config, context) {
25765
+ if (state.entries.size === 0) return;
25766
+ let oldest = null;
25767
+ for (const [key, entry] of state.entries) {
25768
+ const time = config.eviction_policy === "lru" ? entry.accessedAt : entry.createdAt;
25769
+ if (!oldest || time < oldest.time) {
25770
+ oldest = { key, time };
25771
+ }
25772
+ }
25773
+ if (oldest) {
25774
+ state.entries.delete(oldest.key);
25775
+ state.evictions++;
25776
+ context.emit?.("cache:evict", { key: oldest.key, reason: config.eviction_policy });
25777
+ }
25778
+ }
25779
+
25417
25780
  // src/traits/FairnessMonitorTrait.ts
25418
25781
  var DEFAULT_POSITIVE_DECISION_VALUES = ["true", "approved", "approve", "pass", "1", "yes"];
25419
25782
  var DEFAULT_CONFIG5 = {
@@ -40457,7 +40820,7 @@ function sampleTrack(keyframes, t, defaultEasing = "linear") {
40457
40820
  if (t >= a.time && t <= b.time) {
40458
40821
  const span = b.time - a.time;
40459
40822
  const localT = span <= 0 ? 0 : (t - a.time) / span;
40460
- const eased = chunkSJIRCTIS_cjs.applyEasing(localT, b.easing ?? defaultEasing);
40823
+ const eased = chunkHSGJFCVJ_cjs.applyEasing(localT, b.easing ?? defaultEasing);
40461
40824
  return a.value + (b.value - a.value) * eased;
40462
40825
  }
40463
40826
  }
@@ -40690,7 +41053,7 @@ var AnimationStateMachine = class {
40690
41053
  emit({ type: "transition-end", toState: crossfade.to.state, timestamp: Date.now() });
40691
41054
  emit({ type: "state-enter", state: crossfade.to.state, timestamp: Date.now() });
40692
41055
  } else {
40693
- const eased = chunkSJIRCTIS_cjs.applyEasing(crossfade.progress, crossfade.easing ?? "linear");
41056
+ const eased = chunkHSGJFCVJ_cjs.applyEasing(crossfade.progress, crossfade.easing ?? "linear");
40694
41057
  crossfade.from.weight = 1 - eased;
40695
41058
  crossfade.to.weight = eased;
40696
41059
  if (!crossfade.pauseWhenExiting) {
@@ -41047,7 +41410,7 @@ var AnimationTrait = class {
41047
41410
  fromState: crossfade.from.state,
41048
41411
  toState: crossfade.to.state,
41049
41412
  progress: crossfade.progress,
41050
- easedProgress: chunkSJIRCTIS_cjs.applyEasing(crossfade.progress, crossfade.easing ?? "linear"),
41413
+ easedProgress: chunkHSGJFCVJ_cjs.applyEasing(crossfade.progress, crossfade.easing ?? "linear"),
41051
41414
  duration: crossfade.duration,
41052
41415
  easing: crossfade.easing,
41053
41416
  pauseWhenExiting: crossfade.pauseWhenExiting
@@ -44490,6 +44853,333 @@ var environmentalAudioHandler = {
44490
44853
  }
44491
44854
  };
44492
44855
 
44856
+ // src/traits/FluidSimulationTrait.ts
44857
+ function poly6Kernel(r, h) {
44858
+ if (r < 0 || r > h) return 0;
44859
+ const coeff = 315 / (64 * Math.PI * h ** 9);
44860
+ return coeff * (h * h - r * r) ** 3;
44861
+ }
44862
+ function spikyKernelGradient(dx, dy, dz, h) {
44863
+ const r = Math.sqrt(dx * dx + dy * dy + dz * dz);
44864
+ if (r > h || r < 1e-5) return [0, 0, 0];
44865
+ const coeff = -45 / (Math.PI * h ** 6) * (h - r) ** 2;
44866
+ return [coeff * (dx / r), coeff * (dy / r), coeff * (dz / r)];
44867
+ }
44868
+ function viscosityKernelLaplacian(r, h) {
44869
+ if (r < 0 || r > h) return 0;
44870
+ return 45 / (Math.PI * h ** 6) * (h - r);
44871
+ }
44872
+ var SpatialHash = class {
44873
+ constructor(cellSize) {
44874
+ this.cells = /* @__PURE__ */ new Map();
44875
+ this.cellSize = cellSize;
44876
+ }
44877
+ key(x, y, z) {
44878
+ const cx = Math.floor(x / this.cellSize);
44879
+ const cy = Math.floor(y / this.cellSize);
44880
+ const cz = Math.floor(z / this.cellSize);
44881
+ return `${cx},${cy},${cz}`;
44882
+ }
44883
+ insert(id, pos) {
44884
+ const k = this.key(pos[0], pos[1], pos[2]);
44885
+ if (!this.cells.has(k)) this.cells.set(k, []);
44886
+ this.cells.get(k).push(id);
44887
+ }
44888
+ getNeighbors(pos) {
44889
+ const cx = Math.floor(pos[0] / this.cellSize);
44890
+ const cy = Math.floor(pos[1] / this.cellSize);
44891
+ const cz = Math.floor(pos[2] / this.cellSize);
44892
+ const result = [];
44893
+ for (let dx = -1; dx <= 1; dx++) {
44894
+ for (let dy = -1; dy <= 1; dy++) {
44895
+ for (let dz = -1; dz <= 1; dz++) {
44896
+ const k = `${cx + dx},${cy + dy},${cz + dz}`;
44897
+ const cell = this.cells.get(k);
44898
+ if (cell) result.push(...cell);
44899
+ }
44900
+ }
44901
+ }
44902
+ return result;
44903
+ }
44904
+ clear() {
44905
+ this.cells.clear();
44906
+ }
44907
+ };
44908
+ var FluidSimulationSystem = class {
44909
+ constructor(config = {}) {
44910
+ this.particles = /* @__PURE__ */ new Map();
44911
+ this.nextId = 0;
44912
+ this.boundaries = [];
44913
+ this.cfg = {
44914
+ restDensity: config.restDensity ?? 1e3,
44915
+ viscosity: config.viscosity ?? 1e-3,
44916
+ gravity: config.gravity ?? [0, -9.81, 0],
44917
+ solverType: config.solverType ?? "sph",
44918
+ timeStep: config.timeStep ?? 0.016,
44919
+ maxVelocity: config.maxVelocity ?? 100,
44920
+ smoothingRadius: config.smoothingRadius ?? 0.04,
44921
+ gridCellSize: config.gridCellSize ?? 0.04,
44922
+ particleRadius: config.particleRadius ?? 0.01,
44923
+ gasConstant: config.gasConstant ?? 8.314,
44924
+ surfaceTension: config.surfaceTension ?? 0.072
44925
+ };
44926
+ this.spatialHash = new SpatialHash(this.cfg.gridCellSize);
44927
+ }
44928
+ // ── Particle Management ────────────────────────────────────────────────
44929
+ addParticle(position, velocity) {
44930
+ const id = this.nextId++;
44931
+ this.particles.set(id, {
44932
+ id,
44933
+ position: [...position],
44934
+ velocity: velocity ? [...velocity] : [0, 0, 0],
44935
+ force: [0, 0, 0],
44936
+ density: this.cfg.restDensity,
44937
+ pressure: 0,
44938
+ mass: 1
44939
+ });
44940
+ return id;
44941
+ }
44942
+ getParticle(id) {
44943
+ return this.particles.get(id);
44944
+ }
44945
+ getParticles() {
44946
+ return Array.from(this.particles.values());
44947
+ }
44948
+ getParticleCount() {
44949
+ return this.particles.size;
44950
+ }
44951
+ removeParticle(id) {
44952
+ return this.particles.delete(id);
44953
+ }
44954
+ clearParticles() {
44955
+ this.particles.clear();
44956
+ this.nextId = 0;
44957
+ }
44958
+ // ── Boundary Management ────────────────────────────────────────────────
44959
+ addBoundary(boundary) {
44960
+ this.boundaries.push(boundary);
44961
+ }
44962
+ getBoundaries() {
44963
+ return [...this.boundaries];
44964
+ }
44965
+ clearBoundaries() {
44966
+ this.boundaries.length = 0;
44967
+ }
44968
+ // ── Configuration ──────────────────────────────────────────────────────
44969
+ getConfig() {
44970
+ return { ...this.cfg };
44971
+ }
44972
+ setConfig(partial) {
44973
+ Object.assign(this.cfg, partial);
44974
+ if (partial.gridCellSize !== void 0) {
44975
+ this.spatialHash = new SpatialHash(this.cfg.gridCellSize);
44976
+ }
44977
+ }
44978
+ // ── Simulation Step ────────────────────────────────────────────────────
44979
+ step(dt) {
44980
+ const h = this.cfg.smoothingRadius;
44981
+ const deltaT = dt ?? this.cfg.timeStep;
44982
+ const particles = Array.from(this.particles.values());
44983
+ this.spatialHash.clear();
44984
+ for (const p of particles) {
44985
+ this.spatialHash.insert(p.id, p.position);
44986
+ }
44987
+ for (const pi of particles) {
44988
+ let density = 0;
44989
+ for (const pj of particles) {
44990
+ const r = this.dist(pi.position, pj.position);
44991
+ density += pj.mass * poly6Kernel(r, h);
44992
+ }
44993
+ pi.density = Math.max(density, this.cfg.restDensity * 0.01);
44994
+ pi.pressure = this.cfg.gasConstant * (pi.density - this.cfg.restDensity);
44995
+ }
44996
+ for (const pi of particles) {
44997
+ pi.force = [
44998
+ this.cfg.gravity[0] * pi.mass,
44999
+ this.cfg.gravity[1] * pi.mass,
45000
+ this.cfg.gravity[2] * pi.mass
45001
+ ];
45002
+ for (const pj of particles) {
45003
+ if (pi.id === pj.id) continue;
45004
+ const dx = pi.position[0] - pj.position[0];
45005
+ const dy = pi.position[1] - pj.position[1];
45006
+ const dz = pi.position[2] - pj.position[2];
45007
+ const r = Math.sqrt(dx * dx + dy * dy + dz * dz);
45008
+ if (r < h && r > 1e-5) {
45009
+ const grad = spikyKernelGradient(dx, dy, dz, h);
45010
+ const pScale = -pj.mass * ((pi.pressure + pj.pressure) / (2 * pj.density));
45011
+ pi.force[0] += pScale * grad[0];
45012
+ pi.force[1] += pScale * grad[1];
45013
+ pi.force[2] += pScale * grad[2];
45014
+ const viscLap = viscosityKernelLaplacian(r, h);
45015
+ const vScale = this.cfg.viscosity * pj.mass * (1 / pj.density) * viscLap;
45016
+ pi.force[0] += vScale * (pj.velocity[0] - pi.velocity[0]);
45017
+ pi.force[1] += vScale * (pj.velocity[1] - pi.velocity[1]);
45018
+ pi.force[2] += vScale * (pj.velocity[2] - pi.velocity[2]);
45019
+ }
45020
+ }
45021
+ }
45022
+ for (const p of particles) {
45023
+ p.velocity[0] += p.force[0] / p.mass * deltaT;
45024
+ p.velocity[1] += p.force[1] / p.mass * deltaT;
45025
+ p.velocity[2] += p.force[2] / p.mass * deltaT;
45026
+ const speed = Math.sqrt(p.velocity[0] ** 2 + p.velocity[1] ** 2 + p.velocity[2] ** 2);
45027
+ if (speed > this.cfg.maxVelocity) {
45028
+ const scale = this.cfg.maxVelocity / speed;
45029
+ p.velocity[0] *= scale;
45030
+ p.velocity[1] *= scale;
45031
+ p.velocity[2] *= scale;
45032
+ }
45033
+ p.position[0] += p.velocity[0] * deltaT;
45034
+ p.position[1] += p.velocity[1] * deltaT;
45035
+ p.position[2] += p.velocity[2] * deltaT;
45036
+ }
45037
+ for (const p of particles) {
45038
+ this.applyBoundaries(p);
45039
+ }
45040
+ }
45041
+ // ── Density Queries ────────────────────────────────────────────────────
45042
+ getDensityAt(position) {
45043
+ const h = this.cfg.smoothingRadius;
45044
+ let density = 0;
45045
+ for (const p of this.particles.values()) {
45046
+ const r = this.dist(position, p.position);
45047
+ density += p.mass * poly6Kernel(r, h);
45048
+ }
45049
+ return density;
45050
+ }
45051
+ isInsideFluid(position) {
45052
+ return this.getDensityAt(position) > this.cfg.restDensity * 0.5;
45053
+ }
45054
+ // ── Statistics ─────────────────────────────────────────────────────────
45055
+ getKineticEnergy() {
45056
+ let energy = 0;
45057
+ for (const p of this.particles.values()) {
45058
+ energy += 0.5 * p.mass * (p.velocity[0] ** 2 + p.velocity[1] ** 2 + p.velocity[2] ** 2);
45059
+ }
45060
+ return energy;
45061
+ }
45062
+ getAverageDensity() {
45063
+ if (this.particles.size === 0) return 0;
45064
+ let total = 0;
45065
+ for (const p of this.particles.values()) total += p.density;
45066
+ return total / this.particles.size;
45067
+ }
45068
+ reset() {
45069
+ this.particles.clear();
45070
+ this.spatialHash.clear();
45071
+ this.boundaries.length = 0;
45072
+ this.nextId = 0;
45073
+ }
45074
+ // ── Private Helpers ────────────────────────────────────────────────────
45075
+ dist(a, b) {
45076
+ return Math.sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2 + (a[2] - b[2]) ** 2);
45077
+ }
45078
+ applyBoundaries(p) {
45079
+ const pr = this.cfg.particleRadius;
45080
+ for (const b of this.boundaries) {
45081
+ if (b.type === "plane") {
45082
+ const dx = p.position[0] - b.position[0];
45083
+ const dy = p.position[1] - b.position[1];
45084
+ const dz = p.position[2] - b.position[2];
45085
+ const d = dx * b.normal[0] + dy * b.normal[1] + dz * b.normal[2];
45086
+ if (d < pr) {
45087
+ p.position[0] += b.normal[0] * (pr - d);
45088
+ p.position[1] += b.normal[1] * (pr - d);
45089
+ p.position[2] += b.normal[2] * (pr - d);
45090
+ const vn = p.velocity[0] * b.normal[0] + p.velocity[1] * b.normal[1] + p.velocity[2] * b.normal[2];
45091
+ if (vn < 0) {
45092
+ p.velocity[0] -= (1 + b.restitution) * vn * b.normal[0];
45093
+ p.velocity[1] -= (1 + b.restitution) * vn * b.normal[1];
45094
+ p.velocity[2] -= (1 + b.restitution) * vn * b.normal[2];
45095
+ }
45096
+ }
45097
+ } else if (b.type === "sphere") {
45098
+ const dx = p.position[0] - b.position[0];
45099
+ const dy = p.position[1] - b.position[1];
45100
+ const dz = p.position[2] - b.position[2];
45101
+ const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
45102
+ const maxDist = b.radius - pr;
45103
+ if (dist > maxDist && dist > 1e-6) {
45104
+ const nx = dx / dist;
45105
+ const ny = dy / dist;
45106
+ const nz = dz / dist;
45107
+ p.position[0] = b.position[0] + nx * maxDist;
45108
+ p.position[1] = b.position[1] + ny * maxDist;
45109
+ p.position[2] = b.position[2] + nz * maxDist;
45110
+ const vn = p.velocity[0] * nx + p.velocity[1] * ny + p.velocity[2] * nz;
45111
+ if (vn > 0) {
45112
+ p.velocity[0] -= (1 + b.restitution) * vn * nx;
45113
+ p.velocity[1] -= (1 + b.restitution) * vn * ny;
45114
+ p.velocity[2] -= (1 + b.restitution) * vn * nz;
45115
+ }
45116
+ }
45117
+ } else if (b.type === "box") {
45118
+ const halfX = b.size[0] / 2;
45119
+ const halfY = b.size[1] / 2;
45120
+ const halfZ = b.size[2] / 2;
45121
+ const limit = pr;
45122
+ if (p.position[0] > b.position[0] + halfX - limit) {
45123
+ p.position[0] = b.position[0] + halfX - limit;
45124
+ p.velocity[0] *= -b.restitution;
45125
+ } else if (p.position[0] < b.position[0] - halfX + limit) {
45126
+ p.position[0] = b.position[0] - halfX + limit;
45127
+ p.velocity[0] *= -b.restitution;
45128
+ }
45129
+ if (p.position[1] > b.position[1] + halfY - limit) {
45130
+ p.position[1] = b.position[1] + halfY - limit;
45131
+ p.velocity[1] *= -b.restitution;
45132
+ } else if (p.position[1] < b.position[1] - halfY + limit) {
45133
+ p.position[1] = b.position[1] - halfY + limit;
45134
+ p.velocity[1] *= -b.restitution;
45135
+ }
45136
+ if (p.position[2] > b.position[2] + halfZ - limit) {
45137
+ p.position[2] = b.position[2] + halfZ - limit;
45138
+ p.velocity[2] *= -b.restitution;
45139
+ } else if (p.position[2] < b.position[2] - halfZ + limit) {
45140
+ p.position[2] = b.position[2] - halfZ + limit;
45141
+ p.velocity[2] *= -b.restitution;
45142
+ }
45143
+ }
45144
+ }
45145
+ }
45146
+ };
45147
+ var fluidSimulationHandler = {
45148
+ name: "fluid_simulation",
45149
+ defaultConfig: {},
45150
+ onAttach(node, config, ctx) {
45151
+ const instance = new FluidSimulationSystem(config);
45152
+ node.__fluid_simulation_instance = instance;
45153
+ ctx.emit("fluid_simulation_attached", { node, config });
45154
+ },
45155
+ onDetach(node, _config, ctx) {
45156
+ const instance = node.__fluid_simulation_instance;
45157
+ if (instance) {
45158
+ if (typeof instance.onDetach === "function") instance.onDetach(node, ctx);
45159
+ else if (typeof instance.dispose === "function") instance.dispose();
45160
+ else if (typeof instance.cleanup === "function") instance.cleanup();
45161
+ }
45162
+ ctx.emit("fluid_simulation_detached", { node });
45163
+ delete node.__fluid_simulation_instance;
45164
+ },
45165
+ onEvent(node, _config, ctx, event) {
45166
+ const instance = node.__fluid_simulation_instance;
45167
+ if (!instance) return;
45168
+ if (typeof instance.onEvent === "function") instance.onEvent(event);
45169
+ else if (typeof instance.emit === "function" && event.type) instance.emit(event);
45170
+ if (event.type === "fluid_simulation_configure" && event.payload) {
45171
+ Object.assign(instance, event.payload);
45172
+ ctx.emit("fluid_simulation_configured", { node });
45173
+ }
45174
+ },
45175
+ onUpdate(node, _config, ctx, dt) {
45176
+ const instance = node.__fluid_simulation_instance;
45177
+ if (!instance) return;
45178
+ if (typeof instance.onUpdate === "function") instance.onUpdate(node, ctx, dt);
45179
+ else if (typeof instance.step === "function") instance.step(dt);
45180
+ }
45181
+ };
45182
+
44493
45183
  // src/traits/GranularMaterialTrait.ts
44494
45184
  function toVec3(v) {
44495
45185
  if (Array.isArray(v)) {
@@ -52337,7 +53027,7 @@ var eventTraitHandler = {
52337
53027
  name: "events",
52338
53028
  defaultConfig: {},
52339
53029
  onAttach(node, config, _context) {
52340
- const bus = chunkSJIRCTIS_cjs.getSharedEventBus();
53030
+ const bus = chunkHSGJFCVJ_cjs.getSharedEventBus();
52341
53031
  const nodeId = node.id;
52342
53032
  const ids = [];
52343
53033
  if (config.listen) {
@@ -52356,7 +53046,7 @@ var eventTraitHandler = {
52356
53046
  }
52357
53047
  },
52358
53048
  onDetach(node, config, _context) {
52359
- const bus = chunkSJIRCTIS_cjs.getSharedEventBus();
53049
+ const bus = chunkHSGJFCVJ_cjs.getSharedEventBus();
52360
53050
  const nodeId = node.id;
52361
53051
  const ids = nodeListenerIds.get(nodeId) || [];
52362
53052
  for (const id of ids) bus.off(id);
@@ -53790,200 +54480,6 @@ var httpClientHandler = {
53790
54480
  }
53791
54481
  };
53792
54482
 
53793
- // src/traits/RetryTrait.ts
53794
- function computeDelay(config, attempt) {
53795
- let delay;
53796
- switch (config.backoff) {
53797
- case "exponential":
53798
- delay = config.base_delay_ms * Math.pow(2, attempt);
53799
- break;
53800
- case "linear":
53801
- delay = config.base_delay_ms * (attempt + 1);
53802
- break;
53803
- case "constant":
53804
- default:
53805
- delay = config.base_delay_ms;
53806
- break;
53807
- }
53808
- delay = Math.min(delay, config.max_delay_ms);
53809
- if (config.jitter > 0) {
53810
- const jitterAmount = delay * config.jitter;
53811
- delay += Math.random() * jitterAmount * 2 - jitterAmount;
53812
- }
53813
- return Math.max(0, Math.round(delay));
53814
- }
53815
- var retryHandler = {
53816
- name: "retry",
53817
- defaultConfig: {
53818
- max_retries: 3,
53819
- base_delay_ms: 1e3,
53820
- max_delay_ms: 3e4,
53821
- backoff: "exponential",
53822
- jitter: 0.1,
53823
- circuit_threshold: 5,
53824
- circuit_reset_ms: 6e4
53825
- },
53826
- onAttach(node, _config, _context) {
53827
- const state = {
53828
- circuit: "closed",
53829
- consecutiveFailures: 0,
53830
- circuitOpenedAt: 0,
53831
- totalAttempts: 0,
53832
- totalSuccesses: 0,
53833
- totalFailures: 0,
53834
- pendingActions: /* @__PURE__ */ new Map(),
53835
- actionCounter: 0
53836
- };
53837
- node.__retryState = state;
53838
- },
53839
- onDetach(node, _config, _context) {
53840
- delete node.__retryState;
53841
- },
53842
- onUpdate(node, config, context, _delta) {
53843
- const state = node.__retryState;
53844
- if (!state) return;
53845
- if (state.circuit === "open") {
53846
- const elapsed = Date.now() - state.circuitOpenedAt;
53847
- if (elapsed >= config.circuit_reset_ms) {
53848
- state.circuit = "half-open";
53849
- context.emit?.("retry:circuit_half", {
53850
- testAttempt: state.totalAttempts + 1
53851
- });
53852
- }
53853
- }
53854
- },
53855
- onEvent(node, config, context, event) {
53856
- const state = node.__retryState;
53857
- if (!state) return;
53858
- const eventType = typeof event === "string" ? event : event.type;
53859
- const payload = extractPayload(event);
53860
- switch (eventType) {
53861
- case "retry:execute": {
53862
- const actionName = payload.action;
53863
- if (!actionName) break;
53864
- if (state.circuit === "open") {
53865
- context.emit?.("retry:failure", {
53866
- actionName,
53867
- attempt: 0,
53868
- error: "Circuit breaker is OPEN"
53869
- });
53870
- break;
53871
- }
53872
- const retryId = `retry_${state.actionCounter++}`;
53873
- state.pendingActions.set(retryId, {
53874
- actionName,
53875
- attempt: 0,
53876
- startedAt: Date.now()
53877
- });
53878
- state.totalAttempts++;
53879
- context.emit?.("retry:attempt", {
53880
- retryId,
53881
- actionName,
53882
- attempt: 0,
53883
- maxRetries: config.max_retries
53884
- });
53885
- context.emit?.(actionName, {
53886
- ...payload.params,
53887
- __retryId: retryId
53888
- });
53889
- break;
53890
- }
53891
- case "retry:action_result": {
53892
- const retryId = payload.retryId;
53893
- const success = payload.success;
53894
- const error = payload.error;
53895
- const pending = state.pendingActions.get(retryId);
53896
- if (!pending) break;
53897
- if (success) {
53898
- state.totalSuccesses++;
53899
- state.consecutiveFailures = 0;
53900
- state.pendingActions.delete(retryId);
53901
- if (state.circuit === "half-open") {
53902
- state.circuit = "closed";
53903
- context.emit?.("retry:circuit_close", {
53904
- recoveredAfterMs: Date.now() - state.circuitOpenedAt
53905
- });
53906
- }
53907
- context.emit?.("retry:success", {
53908
- actionName: pending.actionName,
53909
- attempt: pending.attempt,
53910
- elapsed: Date.now() - pending.startedAt
53911
- });
53912
- } else {
53913
- state.totalFailures++;
53914
- state.consecutiveFailures++;
53915
- pending.attempt++;
53916
- context.emit?.("retry:failure", {
53917
- actionName: pending.actionName,
53918
- attempt: pending.attempt,
53919
- error: error ?? "unknown"
53920
- });
53921
- if (state.consecutiveFailures >= config.circuit_threshold) {
53922
- state.circuit = "open";
53923
- state.circuitOpenedAt = Date.now();
53924
- state.pendingActions.delete(retryId);
53925
- context.emit?.("retry:circuit_open", {
53926
- consecutiveFailures: state.consecutiveFailures,
53927
- resetMs: config.circuit_reset_ms
53928
- });
53929
- break;
53930
- }
53931
- if (state.circuit === "half-open") {
53932
- state.circuit = "open";
53933
- state.circuitOpenedAt = Date.now();
53934
- state.pendingActions.delete(retryId);
53935
- context.emit?.("retry:circuit_open", {
53936
- consecutiveFailures: state.consecutiveFailures,
53937
- resetMs: config.circuit_reset_ms
53938
- });
53939
- break;
53940
- }
53941
- if (pending.attempt > config.max_retries) {
53942
- state.pendingActions.delete(retryId);
53943
- context.emit?.("retry:exhausted", {
53944
- actionName: pending.actionName,
53945
- totalAttempts: pending.attempt
53946
- });
53947
- } else {
53948
- const delay = computeDelay(config, pending.attempt - 1);
53949
- state.totalAttempts++;
53950
- setTimeout(() => {
53951
- if (!node.__retryState) return;
53952
- context.emit?.("retry:attempt", {
53953
- retryId,
53954
- actionName: pending.actionName,
53955
- attempt: pending.attempt,
53956
- maxRetries: config.max_retries
53957
- });
53958
- context.emit?.(pending.actionName, {
53959
- __retryId: retryId
53960
- });
53961
- }, delay);
53962
- }
53963
- }
53964
- break;
53965
- }
53966
- case "retry:reset_circuit": {
53967
- state.circuit = "closed";
53968
- state.consecutiveFailures = 0;
53969
- context.emit?.("retry:circuit_close", { recoveredAfterMs: 0 });
53970
- break;
53971
- }
53972
- case "retry:get_status": {
53973
- context.emit?.("retry:status", {
53974
- circuit: state.circuit,
53975
- consecutiveFailures: state.consecutiveFailures,
53976
- totalAttempts: state.totalAttempts,
53977
- totalSuccesses: state.totalSuccesses,
53978
- totalFailures: state.totalFailures,
53979
- pending: state.pendingActions.size
53980
- });
53981
- break;
53982
- }
53983
- }
53984
- }
53985
- };
53986
-
53987
54483
  // src/traits/DatabaseTrait.ts
53988
54484
  var databaseHandler = {
53989
54485
  name: "database",
@@ -54085,110 +54581,6 @@ var databaseHandler = {
54085
54581
  }
54086
54582
  };
54087
54583
 
54088
- // src/traits/CacheTrait.ts
54089
- var cacheHandler = {
54090
- name: "cache",
54091
- defaultConfig: {
54092
- max_size: 1e3,
54093
- default_ttl_ms: 6e4,
54094
- eviction_policy: "lru"
54095
- },
54096
- onAttach(node, _config, _context) {
54097
- node.__cacheState = {
54098
- entries: /* @__PURE__ */ new Map(),
54099
- hits: 0,
54100
- misses: 0,
54101
- evictions: 0
54102
- };
54103
- },
54104
- onDetach(node) {
54105
- delete node.__cacheState;
54106
- },
54107
- onUpdate(node, config, _context, _delta) {
54108
- const state = node.__cacheState;
54109
- if (!state) return;
54110
- const now = Date.now();
54111
- for (const [key, entry] of state.entries) {
54112
- if (entry.expiresAt > 0 && now >= entry.expiresAt) {
54113
- state.entries.delete(key);
54114
- state.evictions++;
54115
- }
54116
- }
54117
- },
54118
- onEvent(node, config, context, event) {
54119
- const state = node.__cacheState;
54120
- if (!state) return;
54121
- const eventType = typeof event === "string" ? event : event.type;
54122
- switch (eventType) {
54123
- case "cache:set": {
54124
- const key = event.key;
54125
- if (!key) break;
54126
- const ttl = event.ttl ?? config.default_ttl_ms;
54127
- if (state.entries.size >= config.max_size && !state.entries.has(key)) {
54128
- evictOne(state, config, context);
54129
- }
54130
- const now = Date.now();
54131
- state.entries.set(key, {
54132
- value: event.value,
54133
- expiresAt: ttl > 0 ? now + ttl : 0,
54134
- accessedAt: now,
54135
- createdAt: now
54136
- });
54137
- break;
54138
- }
54139
- case "cache:get": {
54140
- const key = event.key;
54141
- if (!key) break;
54142
- const entry = state.entries.get(key);
54143
- if (entry && (entry.expiresAt === 0 || Date.now() < entry.expiresAt)) {
54144
- state.hits++;
54145
- entry.accessedAt = Date.now();
54146
- context.emit?.("cache:result", { key, value: entry.value, hit: true });
54147
- } else {
54148
- state.misses++;
54149
- if (entry) state.entries.delete(key);
54150
- context.emit?.("cache:result", { key, value: void 0, hit: false });
54151
- }
54152
- break;
54153
- }
54154
- case "cache:invalidate": {
54155
- const key = event.key;
54156
- if (key) state.entries.delete(key);
54157
- break;
54158
- }
54159
- case "cache:clear": {
54160
- state.entries.clear();
54161
- break;
54162
- }
54163
- case "cache:get_stats": {
54164
- context.emit?.("cache:stats", {
54165
- hits: state.hits,
54166
- misses: state.misses,
54167
- size: state.entries.size,
54168
- evictions: state.evictions,
54169
- hitRate: state.hits + state.misses > 0 ? state.hits / (state.hits + state.misses) : 0
54170
- });
54171
- break;
54172
- }
54173
- }
54174
- }
54175
- };
54176
- function evictOne(state, config, context) {
54177
- if (state.entries.size === 0) return;
54178
- let oldest = null;
54179
- for (const [key, entry] of state.entries) {
54180
- const time = config.eviction_policy === "lru" ? entry.accessedAt : entry.createdAt;
54181
- if (!oldest || time < oldest.time) {
54182
- oldest = { key, time };
54183
- }
54184
- }
54185
- if (oldest) {
54186
- state.entries.delete(oldest.key);
54187
- state.evictions++;
54188
- context.emit?.("cache:evict", { key: oldest.key, reason: config.eviction_policy });
54189
- }
54190
- }
54191
-
54192
54584
  // src/traits/StreamTrait.ts
54193
54585
  var streamHandler = {
54194
54586
  name: "stream",
@@ -55010,6 +55402,19 @@ var discordHandler = {
55010
55402
  }
55011
55403
  };
55012
55404
 
55405
+ // src/traits/unwired.ts
55406
+ function emitUnwired(context, errorEvent, detail) {
55407
+ const payload = {
55408
+ ok: false,
55409
+ error: "not_implemented",
55410
+ capability: detail.capability,
55411
+ reason: "trait declared but its backend is not wired \u2014 no external effect was performed"
55412
+ };
55413
+ if (detail.wiring) payload.wiring = detail.wiring;
55414
+ if (detail.requested) payload.requested = detail.requested;
55415
+ context.emit?.(errorEvent, payload);
55416
+ }
55417
+
55013
55418
  // src/traits/MqttPubTrait.ts
55014
55419
  var mqttPubHandler = {
55015
55420
  name: "mqtt_pub",
@@ -55027,10 +55432,10 @@ var mqttPubHandler = {
55027
55432
  if (!state) return;
55028
55433
  if ((typeof event === "string" ? event : event.type) === "mqtt:publish") {
55029
55434
  state.published++;
55030
- context.emit?.("mqtt:published", {
55031
- topic: event.topic,
55032
- messageId: `mqtt_${Date.now()}`,
55033
- qos: event.qos ?? config.default_qos
55435
+ emitUnwired(context, "mqtt:error", {
55436
+ capability: "mqtt",
55437
+ wiring: "mqtt npm client + persistent broker connection + QoS 1/2 PUBACK",
55438
+ requested: { topic: event.topic, qos: event.qos ?? config.default_qos }
55034
55439
  });
55035
55440
  }
55036
55441
  }
@@ -56113,11 +56518,10 @@ var stripeHandler = {
56113
56518
  if (t === "stripe:charge") {
56114
56519
  state.charges++;
56115
56520
  state.totalAmount += event.amount ?? 0;
56116
- context.emit?.("stripe:charged", {
56117
- chargeId: `ch_${Date.now()}`,
56118
- amount: event.amount,
56119
- currency: config.currency,
56120
- customerId: event.customerId
56521
+ emitUnwired(context, "stripe:error", {
56522
+ capability: "stripe",
56523
+ wiring: "Stripe SDK + vault secret_key + per-charge idempotency key",
56524
+ requested: { amount: event.amount, currency: config.currency, customerId: event.customerId }
56121
56525
  });
56122
56526
  } else if (t === "stripe:get_stats") {
56123
56527
  context.emit?.("stripe:stats", {
@@ -57410,10 +57814,10 @@ var s3UploadHandler = {
57410
57814
  if ((typeof event === "string" ? event : event.type) === "s3:upload") {
57411
57815
  state.uploads++;
57412
57816
  state.totalBytes += event.size ?? 0;
57413
- context.emit?.("s3:uploaded", {
57414
- key: event.key,
57415
- bucket: event.bucket ?? config.bucket,
57416
- uploads: state.uploads
57817
+ emitUnwired(context, "s3:error", {
57818
+ capability: "s3",
57819
+ wiring: "@aws-sdk/client-s3 (or MinIO/R2) + credentials + multipart for large files",
57820
+ requested: { key: event.key, bucket: event.bucket ?? config.bucket }
57417
57821
  });
57418
57822
  }
57419
57823
  }
@@ -57612,11 +58016,10 @@ var restEndpointHandler = {
57612
58016
  break;
57613
58017
  case "rest:request":
57614
58018
  state.requests++;
57615
- context.emit?.("rest:response", {
57616
- method: event.method,
57617
- path: event.path,
57618
- status: 200,
57619
- requestCount: state.requests
58019
+ emitUnwired(context, "rest:error", {
58020
+ capability: "rest_endpoint",
58021
+ wiring: "express/fastify route dispatch to the registered handler",
58022
+ requested: { method: event.method, path: event.path }
57620
58023
  });
57621
58024
  break;
57622
58025
  }
@@ -59989,333 +60392,6 @@ var gotchaHandler = {
59989
60392
  }
59990
60393
  };
59991
60394
 
59992
- // src/traits/FluidSimulationTrait.ts
59993
- function poly6Kernel(r, h) {
59994
- if (r < 0 || r > h) return 0;
59995
- const coeff = 315 / (64 * Math.PI * h ** 9);
59996
- return coeff * (h * h - r * r) ** 3;
59997
- }
59998
- function spikyKernelGradient(dx, dy, dz, h) {
59999
- const r = Math.sqrt(dx * dx + dy * dy + dz * dz);
60000
- if (r > h || r < 1e-5) return [0, 0, 0];
60001
- const coeff = -45 / (Math.PI * h ** 6) * (h - r) ** 2;
60002
- return [coeff * (dx / r), coeff * (dy / r), coeff * (dz / r)];
60003
- }
60004
- function viscosityKernelLaplacian(r, h) {
60005
- if (r < 0 || r > h) return 0;
60006
- return 45 / (Math.PI * h ** 6) * (h - r);
60007
- }
60008
- var SpatialHash = class {
60009
- constructor(cellSize) {
60010
- this.cells = /* @__PURE__ */ new Map();
60011
- this.cellSize = cellSize;
60012
- }
60013
- key(x, y, z) {
60014
- const cx = Math.floor(x / this.cellSize);
60015
- const cy = Math.floor(y / this.cellSize);
60016
- const cz = Math.floor(z / this.cellSize);
60017
- return `${cx},${cy},${cz}`;
60018
- }
60019
- insert(id, pos) {
60020
- const k = this.key(pos[0], pos[1], pos[2]);
60021
- if (!this.cells.has(k)) this.cells.set(k, []);
60022
- this.cells.get(k).push(id);
60023
- }
60024
- getNeighbors(pos) {
60025
- const cx = Math.floor(pos[0] / this.cellSize);
60026
- const cy = Math.floor(pos[1] / this.cellSize);
60027
- const cz = Math.floor(pos[2] / this.cellSize);
60028
- const result = [];
60029
- for (let dx = -1; dx <= 1; dx++) {
60030
- for (let dy = -1; dy <= 1; dy++) {
60031
- for (let dz = -1; dz <= 1; dz++) {
60032
- const k = `${cx + dx},${cy + dy},${cz + dz}`;
60033
- const cell = this.cells.get(k);
60034
- if (cell) result.push(...cell);
60035
- }
60036
- }
60037
- }
60038
- return result;
60039
- }
60040
- clear() {
60041
- this.cells.clear();
60042
- }
60043
- };
60044
- var FluidSimulationSystem = class {
60045
- constructor(config = {}) {
60046
- this.particles = /* @__PURE__ */ new Map();
60047
- this.nextId = 0;
60048
- this.boundaries = [];
60049
- this.cfg = {
60050
- restDensity: config.restDensity ?? 1e3,
60051
- viscosity: config.viscosity ?? 1e-3,
60052
- gravity: config.gravity ?? [0, -9.81, 0],
60053
- solverType: config.solverType ?? "sph",
60054
- timeStep: config.timeStep ?? 0.016,
60055
- maxVelocity: config.maxVelocity ?? 100,
60056
- smoothingRadius: config.smoothingRadius ?? 0.04,
60057
- gridCellSize: config.gridCellSize ?? 0.04,
60058
- particleRadius: config.particleRadius ?? 0.01,
60059
- gasConstant: config.gasConstant ?? 8.314,
60060
- surfaceTension: config.surfaceTension ?? 0.072
60061
- };
60062
- this.spatialHash = new SpatialHash(this.cfg.gridCellSize);
60063
- }
60064
- // ── Particle Management ────────────────────────────────────────────────
60065
- addParticle(position, velocity) {
60066
- const id = this.nextId++;
60067
- this.particles.set(id, {
60068
- id,
60069
- position: [...position],
60070
- velocity: velocity ? [...velocity] : [0, 0, 0],
60071
- force: [0, 0, 0],
60072
- density: this.cfg.restDensity,
60073
- pressure: 0,
60074
- mass: 1
60075
- });
60076
- return id;
60077
- }
60078
- getParticle(id) {
60079
- return this.particles.get(id);
60080
- }
60081
- getParticles() {
60082
- return Array.from(this.particles.values());
60083
- }
60084
- getParticleCount() {
60085
- return this.particles.size;
60086
- }
60087
- removeParticle(id) {
60088
- return this.particles.delete(id);
60089
- }
60090
- clearParticles() {
60091
- this.particles.clear();
60092
- this.nextId = 0;
60093
- }
60094
- // ── Boundary Management ────────────────────────────────────────────────
60095
- addBoundary(boundary) {
60096
- this.boundaries.push(boundary);
60097
- }
60098
- getBoundaries() {
60099
- return [...this.boundaries];
60100
- }
60101
- clearBoundaries() {
60102
- this.boundaries.length = 0;
60103
- }
60104
- // ── Configuration ──────────────────────────────────────────────────────
60105
- getConfig() {
60106
- return { ...this.cfg };
60107
- }
60108
- setConfig(partial) {
60109
- Object.assign(this.cfg, partial);
60110
- if (partial.gridCellSize !== void 0) {
60111
- this.spatialHash = new SpatialHash(this.cfg.gridCellSize);
60112
- }
60113
- }
60114
- // ── Simulation Step ────────────────────────────────────────────────────
60115
- step(dt) {
60116
- const h = this.cfg.smoothingRadius;
60117
- const deltaT = dt ?? this.cfg.timeStep;
60118
- const particles = Array.from(this.particles.values());
60119
- this.spatialHash.clear();
60120
- for (const p of particles) {
60121
- this.spatialHash.insert(p.id, p.position);
60122
- }
60123
- for (const pi of particles) {
60124
- let density = 0;
60125
- for (const pj of particles) {
60126
- const r = this.dist(pi.position, pj.position);
60127
- density += pj.mass * poly6Kernel(r, h);
60128
- }
60129
- pi.density = Math.max(density, this.cfg.restDensity * 0.01);
60130
- pi.pressure = this.cfg.gasConstant * (pi.density - this.cfg.restDensity);
60131
- }
60132
- for (const pi of particles) {
60133
- pi.force = [
60134
- this.cfg.gravity[0] * pi.mass,
60135
- this.cfg.gravity[1] * pi.mass,
60136
- this.cfg.gravity[2] * pi.mass
60137
- ];
60138
- for (const pj of particles) {
60139
- if (pi.id === pj.id) continue;
60140
- const dx = pi.position[0] - pj.position[0];
60141
- const dy = pi.position[1] - pj.position[1];
60142
- const dz = pi.position[2] - pj.position[2];
60143
- const r = Math.sqrt(dx * dx + dy * dy + dz * dz);
60144
- if (r < h && r > 1e-5) {
60145
- const grad = spikyKernelGradient(dx, dy, dz, h);
60146
- const pScale = -pj.mass * ((pi.pressure + pj.pressure) / (2 * pj.density));
60147
- pi.force[0] += pScale * grad[0];
60148
- pi.force[1] += pScale * grad[1];
60149
- pi.force[2] += pScale * grad[2];
60150
- const viscLap = viscosityKernelLaplacian(r, h);
60151
- const vScale = this.cfg.viscosity * pj.mass * (1 / pj.density) * viscLap;
60152
- pi.force[0] += vScale * (pj.velocity[0] - pi.velocity[0]);
60153
- pi.force[1] += vScale * (pj.velocity[1] - pi.velocity[1]);
60154
- pi.force[2] += vScale * (pj.velocity[2] - pi.velocity[2]);
60155
- }
60156
- }
60157
- }
60158
- for (const p of particles) {
60159
- p.velocity[0] += p.force[0] / p.mass * deltaT;
60160
- p.velocity[1] += p.force[1] / p.mass * deltaT;
60161
- p.velocity[2] += p.force[2] / p.mass * deltaT;
60162
- const speed = Math.sqrt(p.velocity[0] ** 2 + p.velocity[1] ** 2 + p.velocity[2] ** 2);
60163
- if (speed > this.cfg.maxVelocity) {
60164
- const scale = this.cfg.maxVelocity / speed;
60165
- p.velocity[0] *= scale;
60166
- p.velocity[1] *= scale;
60167
- p.velocity[2] *= scale;
60168
- }
60169
- p.position[0] += p.velocity[0] * deltaT;
60170
- p.position[1] += p.velocity[1] * deltaT;
60171
- p.position[2] += p.velocity[2] * deltaT;
60172
- }
60173
- for (const p of particles) {
60174
- this.applyBoundaries(p);
60175
- }
60176
- }
60177
- // ── Density Queries ────────────────────────────────────────────────────
60178
- getDensityAt(position) {
60179
- const h = this.cfg.smoothingRadius;
60180
- let density = 0;
60181
- for (const p of this.particles.values()) {
60182
- const r = this.dist(position, p.position);
60183
- density += p.mass * poly6Kernel(r, h);
60184
- }
60185
- return density;
60186
- }
60187
- isInsideFluid(position) {
60188
- return this.getDensityAt(position) > this.cfg.restDensity * 0.5;
60189
- }
60190
- // ── Statistics ─────────────────────────────────────────────────────────
60191
- getKineticEnergy() {
60192
- let energy = 0;
60193
- for (const p of this.particles.values()) {
60194
- energy += 0.5 * p.mass * (p.velocity[0] ** 2 + p.velocity[1] ** 2 + p.velocity[2] ** 2);
60195
- }
60196
- return energy;
60197
- }
60198
- getAverageDensity() {
60199
- if (this.particles.size === 0) return 0;
60200
- let total = 0;
60201
- for (const p of this.particles.values()) total += p.density;
60202
- return total / this.particles.size;
60203
- }
60204
- reset() {
60205
- this.particles.clear();
60206
- this.spatialHash.clear();
60207
- this.boundaries.length = 0;
60208
- this.nextId = 0;
60209
- }
60210
- // ── Private Helpers ────────────────────────────────────────────────────
60211
- dist(a, b) {
60212
- return Math.sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2 + (a[2] - b[2]) ** 2);
60213
- }
60214
- applyBoundaries(p) {
60215
- const pr = this.cfg.particleRadius;
60216
- for (const b of this.boundaries) {
60217
- if (b.type === "plane") {
60218
- const dx = p.position[0] - b.position[0];
60219
- const dy = p.position[1] - b.position[1];
60220
- const dz = p.position[2] - b.position[2];
60221
- const d = dx * b.normal[0] + dy * b.normal[1] + dz * b.normal[2];
60222
- if (d < pr) {
60223
- p.position[0] += b.normal[0] * (pr - d);
60224
- p.position[1] += b.normal[1] * (pr - d);
60225
- p.position[2] += b.normal[2] * (pr - d);
60226
- const vn = p.velocity[0] * b.normal[0] + p.velocity[1] * b.normal[1] + p.velocity[2] * b.normal[2];
60227
- if (vn < 0) {
60228
- p.velocity[0] -= (1 + b.restitution) * vn * b.normal[0];
60229
- p.velocity[1] -= (1 + b.restitution) * vn * b.normal[1];
60230
- p.velocity[2] -= (1 + b.restitution) * vn * b.normal[2];
60231
- }
60232
- }
60233
- } else if (b.type === "sphere") {
60234
- const dx = p.position[0] - b.position[0];
60235
- const dy = p.position[1] - b.position[1];
60236
- const dz = p.position[2] - b.position[2];
60237
- const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
60238
- const maxDist = b.radius - pr;
60239
- if (dist > maxDist && dist > 1e-6) {
60240
- const nx = dx / dist;
60241
- const ny = dy / dist;
60242
- const nz = dz / dist;
60243
- p.position[0] = b.position[0] + nx * maxDist;
60244
- p.position[1] = b.position[1] + ny * maxDist;
60245
- p.position[2] = b.position[2] + nz * maxDist;
60246
- const vn = p.velocity[0] * nx + p.velocity[1] * ny + p.velocity[2] * nz;
60247
- if (vn > 0) {
60248
- p.velocity[0] -= (1 + b.restitution) * vn * nx;
60249
- p.velocity[1] -= (1 + b.restitution) * vn * ny;
60250
- p.velocity[2] -= (1 + b.restitution) * vn * nz;
60251
- }
60252
- }
60253
- } else if (b.type === "box") {
60254
- const halfX = b.size[0] / 2;
60255
- const halfY = b.size[1] / 2;
60256
- const halfZ = b.size[2] / 2;
60257
- const limit = pr;
60258
- if (p.position[0] > b.position[0] + halfX - limit) {
60259
- p.position[0] = b.position[0] + halfX - limit;
60260
- p.velocity[0] *= -b.restitution;
60261
- } else if (p.position[0] < b.position[0] - halfX + limit) {
60262
- p.position[0] = b.position[0] - halfX + limit;
60263
- p.velocity[0] *= -b.restitution;
60264
- }
60265
- if (p.position[1] > b.position[1] + halfY - limit) {
60266
- p.position[1] = b.position[1] + halfY - limit;
60267
- p.velocity[1] *= -b.restitution;
60268
- } else if (p.position[1] < b.position[1] - halfY + limit) {
60269
- p.position[1] = b.position[1] - halfY + limit;
60270
- p.velocity[1] *= -b.restitution;
60271
- }
60272
- if (p.position[2] > b.position[2] + halfZ - limit) {
60273
- p.position[2] = b.position[2] + halfZ - limit;
60274
- p.velocity[2] *= -b.restitution;
60275
- } else if (p.position[2] < b.position[2] - halfZ + limit) {
60276
- p.position[2] = b.position[2] - halfZ + limit;
60277
- p.velocity[2] *= -b.restitution;
60278
- }
60279
- }
60280
- }
60281
- }
60282
- };
60283
- var fluidSimulationHandler = {
60284
- name: "fluid_simulation",
60285
- defaultConfig: {},
60286
- onAttach(node, config, ctx) {
60287
- const instance = new FluidSimulationSystem(config);
60288
- node.__fluid_simulation_instance = instance;
60289
- ctx.emit("fluid_simulation_attached", { node, config });
60290
- },
60291
- onDetach(node, _config, ctx) {
60292
- const instance = node.__fluid_simulation_instance;
60293
- if (instance) {
60294
- if (typeof instance.onDetach === "function") instance.onDetach(node, ctx);
60295
- else if (typeof instance.dispose === "function") instance.dispose();
60296
- else if (typeof instance.cleanup === "function") instance.cleanup();
60297
- }
60298
- ctx.emit("fluid_simulation_detached", { node });
60299
- delete node.__fluid_simulation_instance;
60300
- },
60301
- onEvent(node, _config, ctx, event) {
60302
- const instance = node.__fluid_simulation_instance;
60303
- if (!instance) return;
60304
- if (typeof instance.onEvent === "function") instance.onEvent(event);
60305
- else if (typeof instance.emit === "function" && event.type) instance.emit(event);
60306
- if (event.type === "fluid_simulation_configure" && event.payload) {
60307
- Object.assign(instance, event.payload);
60308
- ctx.emit("fluid_simulation_configured", { node });
60309
- }
60310
- },
60311
- onUpdate(node, _config, ctx, dt) {
60312
- const instance = node.__fluid_simulation_instance;
60313
- if (!instance) return;
60314
- if (typeof instance.onUpdate === "function") instance.onUpdate(node, ctx, dt);
60315
- else if (typeof instance.step === "function") instance.step(dt);
60316
- }
60317
- };
60318
-
60319
60395
  // src/traits/VRTraitSystem.ts
60320
60396
  function vec3ToTuple(v) {
60321
60397
  return v;
@@ -61139,6 +61215,7 @@ var VRTraitRegistry = class {
61139
61215
  this.register(provenanceHandler);
61140
61216
  this.register(provenanceDensifyHandler);
61141
61217
  this.register(evolveProgramHandler);
61218
+ this.register(freezeWhenHandler);
61142
61219
  this.register(bodyHandler);
61143
61220
  this.register(proactiveHandler);
61144
61221
  this.register(eventTraitHandler);
@@ -61146,7 +61223,7 @@ var VRTraitRegistry = class {
61146
61223
  this.register(hapticHandler);
61147
61224
  this.register(eyeTrackedHandler);
61148
61225
  this.register(roadmapNodeHandler);
61149
- this.register(chunkSJIRCTIS_cjs.mitosisHandler);
61226
+ this.register(chunkHSGJFCVJ_cjs.mitosisHandler);
61150
61227
  this.register(formationControlHandler);
61151
61228
  this.register(planeDetectionHandler);
61152
61229
  this.register(meshDetectionHandler);
@@ -61317,8 +61394,8 @@ var VRTraitRegistry = class {
61317
61394
  this.register(sseHandler);
61318
61395
  this.register(modelLoadHandler);
61319
61396
  this.register(inferenceHandler);
61320
- this.register(chunkSJIRCTIS_cjs.embeddingHandler);
61321
- this.register(chunkSJIRCTIS_cjs.jepObjectiveHandler);
61397
+ this.register(chunkHSGJFCVJ_cjs.embeddingHandler);
61398
+ this.register(chunkHSGJFCVJ_cjs.jepObjectiveHandler);
61322
61399
  this.register(fineTuneHandler);
61323
61400
  this.register(vectorSearchHandler);
61324
61401
  this.register(promptTemplateHandler);
@@ -61401,8 +61478,8 @@ var VRTraitRegistry = class {
61401
61478
  this.register(trainingLoopHandler);
61402
61479
  this.register(modelLoadHandler);
61403
61480
  this.register(inferenceHandler);
61404
- this.register(chunkSJIRCTIS_cjs.embeddingHandler);
61405
- this.register(chunkSJIRCTIS_cjs.jepObjectiveHandler);
61481
+ this.register(chunkHSGJFCVJ_cjs.embeddingHandler);
61482
+ this.register(chunkHSGJFCVJ_cjs.jepObjectiveHandler);
61406
61483
  this.register(sqlQueryHandler);
61407
61484
  this.register(ormEntityHandler);
61408
61485
  this.register(offlineSyncHandler);
@@ -61454,7 +61531,7 @@ var VRTraitRegistry = class {
61454
61531
  this.register(npcAIHandler);
61455
61532
  this.register(objectTrackingHandler);
61456
61533
  this.register(openXRHALHandler);
61457
- this.register(chunkSJIRCTIS_cjs.orbitalHandler);
61534
+ this.register(chunkHSGJFCVJ_cjs.orbitalHandler);
61458
61535
  this.register(partnerSDKHandler);
61459
61536
  this.register(poseEstimationHandler);
61460
61537
  this.register(ragKnowledgeHandler);
@@ -61673,6 +61750,7 @@ exports.DraftManager = DraftManager;
61673
61750
  exports.ECSWorld = ECSWorld;
61674
61751
  exports.EmotionDirectiveTrait = EmotionDirectiveTrait;
61675
61752
  exports.EnvironmentalAudioSystem = EnvironmentalAudioSystem;
61753
+ exports.ExpressionParseError = ExpressionParseError;
61676
61754
  exports.GEM_RESONANCE_ELEMENT_FREQUENCIES = GEM_RESONANCE_ELEMENT_FREQUENCIES;
61677
61755
  exports.GOAPPlanner = GOAPPlanner;
61678
61756
  exports.GOLDEN_ANGLE_DEG = GOLDEN_ANGLE_DEG;
@@ -61757,6 +61835,7 @@ exports.bufferHandler = bufferHandler;
61757
61835
  exports.buildBehaviorFactDisclosure = buildBehaviorFactDisclosure;
61758
61836
  exports.buoyancyHandler = buoyancyHandler;
61759
61837
  exports.cRDTRoomHandler = cRDTRoomHandler;
61838
+ exports.cacheHandler = cacheHandler;
61760
61839
  exports.careEthicsHandler = careEthicsHandler;
61761
61840
  exports.chainHandler = chainHandler;
61762
61841
  exports.characterHandler = characterHandler;
@@ -61833,6 +61912,7 @@ exports.economyPrimitivesHandler = economyPrimitivesHandler;
61833
61912
  exports.effectiveWeight = effectiveWeight;
61834
61913
  exports.embeddingSearchHandler = embeddingSearchHandler;
61835
61914
  exports.emissiveAt = emissiveAt;
61915
+ exports.emitUnwired = emitUnwired;
61836
61916
  exports.emotionDirectiveHandler = emotionDirectiveHandler;
61837
61917
  exports.emotionHandler = emotionHandler;
61838
61918
  exports.emotionalVoiceHandler = emotionalVoiceHandler;
@@ -61841,6 +61921,7 @@ exports.environmentalAudioHandler = environmentalAudioHandler;
61841
61921
  exports.evaluateAction = evaluateAction;
61842
61922
  exports.evaluateAutonomyGuard = evaluateAutonomyGuard;
61843
61923
  exports.evaluateCareEthicsTurn = evaluateCareEthicsTurn;
61924
+ exports.evaluateExpressionIR = evaluateExpressionIR;
61844
61925
  exports.evolveProgramHandler = evolveProgramHandler;
61845
61926
  exports.extractLotusGenesisAnchorHash = extractLotusGenesisAnchorHash;
61846
61927
  exports.extractPayload = extractPayload;
@@ -61854,8 +61935,10 @@ exports.findReachablePath = findReachablePath;
61854
61935
  exports.findWalkableNodeAt = findWalkableNodeAt;
61855
61936
  exports.flowFieldHandler = flowFieldHandler;
61856
61937
  exports.fluidHandler = fluidHandler;
61938
+ exports.fluidSimulationHandler = fluidSimulationHandler;
61857
61939
  exports.forgetPolicyHandler = forgetPolicyHandler;
61858
61940
  exports.formationControlHandler = formationControlHandler;
61941
+ exports.freezeWhenHandler = freezeWhenHandler;
61859
61942
  exports.gardenerPulseJitter = gardenerPulseJitter;
61860
61943
  exports.gaussianSplatHandler = gaussianSplatHandler;
61861
61944
  exports.gazeFocusAnalyticsHandler = gazeFocusAnalyticsHandler;
@@ -61985,6 +62068,7 @@ exports.onboardingHandler = onboardingHandler;
61985
62068
  exports.openXRHALHandler = openXRHALHandler;
61986
62069
  exports.parseCRDTRoomEntityConfig = parseCRDTRoomEntityConfig;
61987
62070
  exports.parseCRDTRoomTraitConfig = parseCRDTRoomTraitConfig;
62071
+ exports.parseExpressionToIR = parseExpressionToIR;
61988
62072
  exports.partnerSDKHandler = partnerSDKHandler;
61989
62073
  exports.passthroughCameraHandler = passthroughCameraHandler;
61990
62074
  exports.patrolHandler = patrolHandler;
@@ -62023,6 +62107,7 @@ exports.resolveBloomStage = resolveBloomStage;
62023
62107
  exports.resolveCRDTRoomTraitConfig = resolveCRDTRoomTraitConfig;
62024
62108
  exports.resolvePulseHz = resolvePulseHz;
62025
62109
  exports.resourceAccountingHandler = resourceAccountingHandler;
62110
+ exports.retryHandler = retryHandler;
62026
62111
  exports.reverbZoneHandler = reverbZoneHandler;
62027
62112
  exports.rigidbodyHandler = rigidbodyHandler;
62028
62113
  exports.roadmapNodeHandler = roadmapNodeHandler;
@@ -62105,5 +62190,5 @@ exports.withNegotiation = withNegotiation;
62105
62190
  exports.worldPortalHandler = worldPortalHandler;
62106
62191
  exports.wotThingHandler = wotThingHandler;
62107
62192
  exports.zkPrivateHandler = zkPrivateHandler;
62108
- //# sourceMappingURL=chunk-IFW5IW4L.cjs.map
62109
- //# sourceMappingURL=chunk-IFW5IW4L.cjs.map
62193
+ //# sourceMappingURL=chunk-X5ZLSPU2.cjs.map
62194
+ //# sourceMappingURL=chunk-X5ZLSPU2.cjs.map