@number10/jsx-core 5.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.
Files changed (340) hide show
  1. package/LICENSE +667 -0
  2. package/README.md +38 -0
  3. package/dist/animation/animated-signal.cjs +19 -0
  4. package/dist/animation/animated-signal.cjs.map +1 -0
  5. package/dist/animation/animated-signal.d.ts +35 -0
  6. package/dist/animation/animated-signal.d.ts.map +1 -0
  7. package/dist/animation/animated-signal.js +19 -0
  8. package/dist/animation/animated-signal.js.map +1 -0
  9. package/dist/animation/create-spring.cjs +80 -0
  10. package/dist/animation/create-spring.cjs.map +1 -0
  11. package/dist/animation/create-spring.d.ts +56 -0
  12. package/dist/animation/create-spring.d.ts.map +1 -0
  13. package/dist/animation/create-spring.js +80 -0
  14. package/dist/animation/create-spring.js.map +1 -0
  15. package/dist/animation/easing.cjs +76 -0
  16. package/dist/animation/easing.cjs.map +1 -0
  17. package/dist/animation/easing.d.ts +45 -0
  18. package/dist/animation/easing.d.ts.map +1 -0
  19. package/dist/animation/easing.js +76 -0
  20. package/dist/animation/easing.js.map +1 -0
  21. package/dist/animation/effect-definitions.cjs +441 -0
  22. package/dist/animation/effect-definitions.cjs.map +1 -0
  23. package/dist/animation/effect-definitions.d.ts +60 -0
  24. package/dist/animation/effect-definitions.d.ts.map +1 -0
  25. package/dist/animation/effect-definitions.js +441 -0
  26. package/dist/animation/effect-definitions.js.map +1 -0
  27. package/dist/animation/effect-engine.cjs +189 -0
  28. package/dist/animation/effect-engine.cjs.map +1 -0
  29. package/dist/animation/effect-engine.d.ts +70 -0
  30. package/dist/animation/effect-engine.d.ts.map +1 -0
  31. package/dist/animation/effect-engine.js +189 -0
  32. package/dist/animation/effect-engine.js.map +1 -0
  33. package/dist/animation/index.d.ts +24 -0
  34. package/dist/animation/index.d.ts.map +1 -0
  35. package/dist/animation/spring-physics.cjs +94 -0
  36. package/dist/animation/spring-physics.cjs.map +1 -0
  37. package/dist/animation/spring-physics.d.ts +145 -0
  38. package/dist/animation/spring-physics.d.ts.map +1 -0
  39. package/dist/animation/spring-physics.js +94 -0
  40. package/dist/animation/spring-physics.js.map +1 -0
  41. package/dist/animation/tween.cjs +67 -0
  42. package/dist/animation/tween.cjs.map +1 -0
  43. package/dist/animation/tween.d.ts +60 -0
  44. package/dist/animation/tween.d.ts.map +1 -0
  45. package/dist/animation/tween.js +67 -0
  46. package/dist/animation/tween.js.map +1 -0
  47. package/dist/animation/types.d.ts +31 -0
  48. package/dist/animation/types.d.ts.map +1 -0
  49. package/dist/animation/useSpring.cjs +152 -0
  50. package/dist/animation/useSpring.cjs.map +1 -0
  51. package/dist/animation/useSpring.d.ts +55 -0
  52. package/dist/animation/useSpring.d.ts.map +1 -0
  53. package/dist/animation/useSpring.js +149 -0
  54. package/dist/animation/useSpring.js.map +1 -0
  55. package/dist/animation/useTween.cjs +208 -0
  56. package/dist/animation/useTween.cjs.map +1 -0
  57. package/dist/animation/useTween.d.ts +116 -0
  58. package/dist/animation/useTween.d.ts.map +1 -0
  59. package/dist/animation/useTween.js +208 -0
  60. package/dist/animation/useTween.js.map +1 -0
  61. package/dist/border-geometry.cjs +447 -0
  62. package/dist/border-geometry.cjs.map +1 -0
  63. package/dist/border-geometry.d.ts +114 -0
  64. package/dist/border-geometry.d.ts.map +1 -0
  65. package/dist/border-geometry.js +447 -0
  66. package/dist/border-geometry.js.map +1 -0
  67. package/dist/colors/color-presets.cjs +236 -0
  68. package/dist/colors/color-presets.cjs.map +1 -0
  69. package/dist/colors/color-presets.d.ts +89 -0
  70. package/dist/colors/color-presets.d.ts.map +1 -0
  71. package/dist/colors/color-presets.js +236 -0
  72. package/dist/colors/color-presets.js.map +1 -0
  73. package/dist/colors/color-theme-helpers.cjs +32 -0
  74. package/dist/colors/color-theme-helpers.cjs.map +1 -0
  75. package/dist/colors/color-theme-helpers.d.ts +65 -0
  76. package/dist/colors/color-theme-helpers.d.ts.map +1 -0
  77. package/dist/colors/color-theme-helpers.js +32 -0
  78. package/dist/colors/color-theme-helpers.js.map +1 -0
  79. package/dist/colors/color-types.cjs +38 -0
  80. package/dist/colors/color-types.cjs.map +1 -0
  81. package/dist/colors/color-types.d.ts +112 -0
  82. package/dist/colors/color-types.d.ts.map +1 -0
  83. package/dist/colors/color-types.js +38 -0
  84. package/dist/colors/color-types.js.map +1 -0
  85. package/dist/colors/color-utils.cjs +197 -0
  86. package/dist/colors/color-utils.cjs.map +1 -0
  87. package/dist/colors/color-utils.d.ts +216 -0
  88. package/dist/colors/color-utils.d.ts.map +1 -0
  89. package/dist/colors/color-utils.js +197 -0
  90. package/dist/colors/color-utils.js.map +1 -0
  91. package/dist/colors/contrast-contracts.cjs +265 -0
  92. package/dist/colors/contrast-contracts.cjs.map +1 -0
  93. package/dist/colors/contrast-contracts.d.ts +289 -0
  94. package/dist/colors/contrast-contracts.d.ts.map +1 -0
  95. package/dist/colors/contrast-contracts.js +265 -0
  96. package/dist/colors/contrast-contracts.js.map +1 -0
  97. package/dist/colors/index.cjs +55 -0
  98. package/dist/colors/index.cjs.map +1 -0
  99. package/dist/colors/index.d.ts +16 -0
  100. package/dist/colors/index.d.ts.map +1 -0
  101. package/dist/colors/index.js +55 -0
  102. package/dist/colors/index.js.map +1 -0
  103. package/dist/core-props.cjs +66 -0
  104. package/dist/core-props.cjs.map +1 -0
  105. package/dist/core-props.d.ts +395 -0
  106. package/dist/core-props.d.ts.map +1 -0
  107. package/dist/core-props.js +66 -0
  108. package/dist/core-props.js.map +1 -0
  109. package/dist/design-tokens/design-token-presets.cjs +91 -0
  110. package/dist/design-tokens/design-token-presets.cjs.map +1 -0
  111. package/dist/design-tokens/design-token-presets.d.ts +34 -0
  112. package/dist/design-tokens/design-token-presets.d.ts.map +1 -0
  113. package/dist/design-tokens/design-token-presets.js +91 -0
  114. package/dist/design-tokens/design-token-presets.js.map +1 -0
  115. package/dist/design-tokens/design-token-types.d.ts +97 -0
  116. package/dist/design-tokens/design-token-types.d.ts.map +1 -0
  117. package/dist/design-tokens/index.cjs +10 -0
  118. package/dist/design-tokens/index.cjs.map +1 -0
  119. package/dist/design-tokens/index.d.ts +9 -0
  120. package/dist/design-tokens/index.d.ts.map +1 -0
  121. package/dist/design-tokens/index.js +10 -0
  122. package/dist/design-tokens/index.js.map +1 -0
  123. package/dist/dev-config.cjs +296 -0
  124. package/dist/dev-config.cjs.map +1 -0
  125. package/dist/dev-config.d.ts +238 -0
  126. package/dist/dev-config.d.ts.map +1 -0
  127. package/dist/dev-config.js +296 -0
  128. package/dist/dev-config.js.map +1 -0
  129. package/dist/effects.cjs +69 -0
  130. package/dist/effects.cjs.map +1 -0
  131. package/dist/effects.d.ts +152 -0
  132. package/dist/effects.d.ts.map +1 -0
  133. package/dist/effects.js +69 -0
  134. package/dist/effects.js.map +1 -0
  135. package/dist/global-registry.cjs +25 -0
  136. package/dist/global-registry.cjs.map +1 -0
  137. package/dist/global-registry.d.ts +19 -0
  138. package/dist/global-registry.d.ts.map +1 -0
  139. package/dist/global-registry.js +25 -0
  140. package/dist/global-registry.js.map +1 -0
  141. package/dist/hooks.cjs +378 -0
  142. package/dist/hooks.cjs.map +1 -0
  143. package/dist/hooks.d.ts +322 -0
  144. package/dist/hooks.d.ts.map +1 -0
  145. package/dist/hooks.js +378 -0
  146. package/dist/hooks.js.map +1 -0
  147. package/dist/host-adapter.d.ts +414 -0
  148. package/dist/host-adapter.d.ts.map +1 -0
  149. package/dist/index.cjs +229 -0
  150. package/dist/index.cjs.map +1 -0
  151. package/dist/index.d.ts +32 -0
  152. package/dist/index.d.ts.map +1 -0
  153. package/dist/index.js +226 -0
  154. package/dist/index.js.map +1 -0
  155. package/dist/jsx-dev-runtime.cjs +10 -0
  156. package/dist/jsx-dev-runtime.cjs.map +1 -0
  157. package/dist/jsx-dev-runtime.d.ts +5 -0
  158. package/dist/jsx-dev-runtime.d.ts.map +1 -0
  159. package/dist/jsx-dev-runtime.js +11 -0
  160. package/dist/jsx-dev-runtime.js.map +1 -0
  161. package/dist/jsx-runtime.cjs +44 -0
  162. package/dist/jsx-runtime.cjs.map +1 -0
  163. package/dist/jsx-runtime.d.ts +24 -0
  164. package/dist/jsx-runtime.d.ts.map +1 -0
  165. package/dist/jsx-runtime.js +44 -0
  166. package/dist/jsx-runtime.js.map +1 -0
  167. package/dist/jsx-types.d.ts +25 -0
  168. package/dist/jsx-types.d.ts.map +1 -0
  169. package/dist/layout/appliers/container-applier.cjs +20 -0
  170. package/dist/layout/appliers/container-applier.cjs.map +1 -0
  171. package/dist/layout/appliers/container-applier.d.ts +9 -0
  172. package/dist/layout/appliers/container-applier.d.ts.map +1 -0
  173. package/dist/layout/appliers/container-applier.js +20 -0
  174. package/dist/layout/appliers/container-applier.js.map +1 -0
  175. package/dist/layout/appliers/position-applier.cjs +31 -0
  176. package/dist/layout/appliers/position-applier.cjs.map +1 -0
  177. package/dist/layout/appliers/position-applier.d.ts +8 -0
  178. package/dist/layout/appliers/position-applier.d.ts.map +1 -0
  179. package/dist/layout/appliers/position-applier.js +31 -0
  180. package/dist/layout/appliers/position-applier.js.map +1 -0
  181. package/dist/layout/layout-engine-test-utils.d.ts +26 -0
  182. package/dist/layout/layout-engine-test-utils.d.ts.map +1 -0
  183. package/dist/layout/layout-engine.cjs +628 -0
  184. package/dist/layout/layout-engine.cjs.map +1 -0
  185. package/dist/layout/layout-engine.d.ts +140 -0
  186. package/dist/layout/layout-engine.d.ts.map +1 -0
  187. package/dist/layout/layout-engine.js +628 -0
  188. package/dist/layout/layout-engine.js.map +1 -0
  189. package/dist/layout/strategies/base-strategy.cjs +31 -0
  190. package/dist/layout/strategies/base-strategy.cjs.map +1 -0
  191. package/dist/layout/strategies/base-strategy.d.ts +59 -0
  192. package/dist/layout/strategies/base-strategy.d.ts.map +1 -0
  193. package/dist/layout/strategies/base-strategy.js +31 -0
  194. package/dist/layout/strategies/base-strategy.js.map +1 -0
  195. package/dist/layout/strategies/column-layout.cjs +145 -0
  196. package/dist/layout/strategies/column-layout.cjs.map +1 -0
  197. package/dist/layout/strategies/column-layout.d.ts +38 -0
  198. package/dist/layout/strategies/column-layout.d.ts.map +1 -0
  199. package/dist/layout/strategies/column-layout.js +145 -0
  200. package/dist/layout/strategies/column-layout.js.map +1 -0
  201. package/dist/layout/strategies/row-layout.cjs +145 -0
  202. package/dist/layout/strategies/row-layout.cjs.map +1 -0
  203. package/dist/layout/strategies/row-layout.d.ts +38 -0
  204. package/dist/layout/strategies/row-layout.d.ts.map +1 -0
  205. package/dist/layout/strategies/row-layout.js +145 -0
  206. package/dist/layout/strategies/row-layout.js.map +1 -0
  207. package/dist/layout/strategies/stack-layout.cjs +94 -0
  208. package/dist/layout/strategies/stack-layout.cjs.map +1 -0
  209. package/dist/layout/strategies/stack-layout.d.ts +30 -0
  210. package/dist/layout/strategies/stack-layout.d.ts.map +1 -0
  211. package/dist/layout/strategies/stack-layout.js +94 -0
  212. package/dist/layout/strategies/stack-layout.js.map +1 -0
  213. package/dist/layout/types.d.ts +134 -0
  214. package/dist/layout/types.d.ts.map +1 -0
  215. package/dist/layout/utils/child-utils.cjs +129 -0
  216. package/dist/layout/utils/child-utils.cjs.map +1 -0
  217. package/dist/layout/utils/child-utils.d.ts +54 -0
  218. package/dist/layout/utils/child-utils.d.ts.map +1 -0
  219. package/dist/layout/utils/child-utils.js +129 -0
  220. package/dist/layout/utils/child-utils.js.map +1 -0
  221. package/dist/layout/utils/dimension-calculator.cjs +109 -0
  222. package/dist/layout/utils/dimension-calculator.cjs.map +1 -0
  223. package/dist/layout/utils/dimension-calculator.d.ts +59 -0
  224. package/dist/layout/utils/dimension-calculator.d.ts.map +1 -0
  225. package/dist/layout/utils/dimension-calculator.js +109 -0
  226. package/dist/layout/utils/dimension-calculator.js.map +1 -0
  227. package/dist/layout/utils/flex-distributor.cjs +173 -0
  228. package/dist/layout/utils/flex-distributor.cjs.map +1 -0
  229. package/dist/layout/utils/flex-distributor.d.ts +18 -0
  230. package/dist/layout/utils/flex-distributor.d.ts.map +1 -0
  231. package/dist/layout/utils/flex-distributor.js +173 -0
  232. package/dist/layout/utils/flex-distributor.js.map +1 -0
  233. package/dist/layout/utils/size-resolver.cjs +280 -0
  234. package/dist/layout/utils/size-resolver.cjs.map +1 -0
  235. package/dist/layout/utils/size-resolver.d.ts +84 -0
  236. package/dist/layout/utils/size-resolver.d.ts.map +1 -0
  237. package/dist/layout/utils/size-resolver.js +280 -0
  238. package/dist/layout/utils/size-resolver.js.map +1 -0
  239. package/dist/layout/utils/spacing-calculator.cjs +50 -0
  240. package/dist/layout/utils/spacing-calculator.cjs.map +1 -0
  241. package/dist/layout/utils/spacing-calculator.d.ts +27 -0
  242. package/dist/layout/utils/spacing-calculator.d.ts.map +1 -0
  243. package/dist/layout/utils/spacing-calculator.js +50 -0
  244. package/dist/layout/utils/spacing-calculator.js.map +1 -0
  245. package/dist/memo.cjs +18 -0
  246. package/dist/memo.cjs.map +1 -0
  247. package/dist/memo.d.ts +29 -0
  248. package/dist/memo.d.ts.map +1 -0
  249. package/dist/memo.js +18 -0
  250. package/dist/memo.js.map +1 -0
  251. package/dist/nineslice-contract.cjs +60 -0
  252. package/dist/nineslice-contract.cjs.map +1 -0
  253. package/dist/nineslice-contract.d.ts +107 -0
  254. package/dist/nineslice-contract.d.ts.map +1 -0
  255. package/dist/nineslice-contract.js +60 -0
  256. package/dist/nineslice-contract.js.map +1 -0
  257. package/dist/placeholder.cjs +12 -0
  258. package/dist/placeholder.cjs.map +1 -0
  259. package/dist/placeholder.d.ts +44 -0
  260. package/dist/placeholder.d.ts.map +1 -0
  261. package/dist/placeholder.js +12 -0
  262. package/dist/placeholder.js.map +1 -0
  263. package/dist/portal.cjs +89 -0
  264. package/dist/portal.cjs.map +1 -0
  265. package/dist/portal.d.ts +62 -0
  266. package/dist/portal.d.ts.map +1 -0
  267. package/dist/portal.js +89 -0
  268. package/dist/portal.js.map +1 -0
  269. package/dist/primitive-contracts.cjs +12 -0
  270. package/dist/primitive-contracts.cjs.map +1 -0
  271. package/dist/primitive-contracts.d.ts +186 -0
  272. package/dist/primitive-contracts.d.ts.map +1 -0
  273. package/dist/primitive-contracts.js +12 -0
  274. package/dist/primitive-contracts.js.map +1 -0
  275. package/dist/theme.cjs +332 -0
  276. package/dist/theme.cjs.map +1 -0
  277. package/dist/theme.d.ts +204 -0
  278. package/dist/theme.d.ts.map +1 -0
  279. package/dist/theme.js +332 -0
  280. package/dist/theme.js.map +1 -0
  281. package/dist/types.d.ts +86 -0
  282. package/dist/types.d.ts.map +1 -0
  283. package/dist/vdom/create-runtime.cjs +79 -0
  284. package/dist/vdom/create-runtime.cjs.map +1 -0
  285. package/dist/vdom/create-runtime.d.ts +7 -0
  286. package/dist/vdom/create-runtime.d.ts.map +1 -0
  287. package/dist/vdom/create-runtime.js +79 -0
  288. package/dist/vdom/create-runtime.js.map +1 -0
  289. package/dist/vdom/index.cjs +8 -0
  290. package/dist/vdom/index.cjs.map +1 -0
  291. package/dist/vdom/index.d.ts +4 -0
  292. package/dist/vdom/index.d.ts.map +1 -0
  293. package/dist/vdom/index.js +8 -0
  294. package/dist/vdom/index.js.map +1 -0
  295. package/dist/vdom/mount.cjs +161 -0
  296. package/dist/vdom/mount.cjs.map +1 -0
  297. package/dist/vdom/mount.d.ts +6 -0
  298. package/dist/vdom/mount.d.ts.map +1 -0
  299. package/dist/vdom/mount.js +161 -0
  300. package/dist/vdom/mount.js.map +1 -0
  301. package/dist/vdom/patch.cjs +163 -0
  302. package/dist/vdom/patch.cjs.map +1 -0
  303. package/dist/vdom/patch.d.ts +3 -0
  304. package/dist/vdom/patch.d.ts.map +1 -0
  305. package/dist/vdom/patch.js +163 -0
  306. package/dist/vdom/patch.js.map +1 -0
  307. package/dist/vdom/registry.cjs +85 -0
  308. package/dist/vdom/registry.cjs.map +1 -0
  309. package/dist/vdom/registry.d.ts +28 -0
  310. package/dist/vdom/registry.d.ts.map +1 -0
  311. package/dist/vdom/registry.js +85 -0
  312. package/dist/vdom/registry.js.map +1 -0
  313. package/dist/vdom/runtime-helpers.cjs +23 -0
  314. package/dist/vdom/runtime-helpers.cjs.map +1 -0
  315. package/dist/vdom/runtime-helpers.d.ts +8 -0
  316. package/dist/vdom/runtime-helpers.d.ts.map +1 -0
  317. package/dist/vdom/runtime-helpers.js +23 -0
  318. package/dist/vdom/runtime-helpers.js.map +1 -0
  319. package/dist/vdom/surface.cjs +107 -0
  320. package/dist/vdom/surface.cjs.map +1 -0
  321. package/dist/vdom/surface.d.ts +9 -0
  322. package/dist/vdom/surface.d.ts.map +1 -0
  323. package/dist/vdom/surface.js +107 -0
  324. package/dist/vdom/surface.js.map +1 -0
  325. package/dist/vdom/types.d.ts +104 -0
  326. package/dist/vdom/types.d.ts.map +1 -0
  327. package/dist/vdom/utils.cjs +146 -0
  328. package/dist/vdom/utils.cjs.map +1 -0
  329. package/dist/vdom/utils.d.ts +24 -0
  330. package/dist/vdom/utils.d.ts.map +1 -0
  331. package/dist/vdom/utils.js +146 -0
  332. package/dist/vdom/utils.js.map +1 -0
  333. package/dist/vdom.d.ts +4 -0
  334. package/dist/vdom.d.ts.map +1 -0
  335. package/dist/vector-draw-context.d.ts +63 -0
  336. package/dist/vector-draw-context.d.ts.map +1 -0
  337. package/package.json +161 -0
  338. package/vdom/index.cjs +1 -0
  339. package/vdom/index.d.ts +1 -0
  340. package/vdom/index.js +1 -0
package/dist/hooks.cjs ADDED
@@ -0,0 +1,378 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const globalRegistry = require("./global-registry.cjs");
4
+ const GLOBAL_NS = "@number10/jsx-core";
5
+ const _currentCtxKey = /* @__PURE__ */ Symbol.for(`${GLOBAL_NS}:currentCtx`);
6
+ const _onScheduleUpdateKey = /* @__PURE__ */ Symbol.for(`${GLOBAL_NS}:onScheduleUpdate`);
7
+ function getCurrentCtx() {
8
+ return globalRegistry.getGlobalValue(_currentCtxKey) ?? null;
9
+ }
10
+ function setCurrentCtx(ctx) {
11
+ globalRegistry.setGlobalValue(_currentCtxKey, ctx);
12
+ }
13
+ function withHooks(ctx, render, opts) {
14
+ if (opts?.isAlive && !opts.isAlive()) return null;
15
+ const prev = getCurrentCtx();
16
+ setCurrentCtx(ctx);
17
+ ctx.index = 0;
18
+ ctx.effects = [];
19
+ try {
20
+ const out = render();
21
+ opts?.onAfterRender?.();
22
+ return out;
23
+ } finally {
24
+ setCurrentCtx(prev);
25
+ }
26
+ }
27
+ function getCurrentOrThrow() {
28
+ const ctx = getCurrentCtx();
29
+ if (!ctx) {
30
+ throw new Error(
31
+ "Hook called outside of component render. Hooks (useState, useRef, useEffect, etc.) must be called synchronously during a function component render. This error commonly occurs when:\n 1. A hook is called in an async callback or event handler\n 2. A hook is called after the component has unmounted\n 3. A hook is called in a non-component function"
32
+ );
33
+ }
34
+ return ctx;
35
+ }
36
+ function setUpdateHandler(handler) {
37
+ globalRegistry.setGlobalValue(_onScheduleUpdateKey, handler);
38
+ }
39
+ function useState(initial) {
40
+ const c = getCurrentOrThrow();
41
+ const i = c.index++;
42
+ if (i >= c.slots.length)
43
+ c.slots[i] = typeof initial === "function" ? initial() : initial;
44
+ const value = c.slots[i];
45
+ const set = (v) => {
46
+ const next = typeof v === "function" ? v(c.slots[i]) : v;
47
+ if (Object.is(next, c.slots[i])) return;
48
+ c.slots[i] = next;
49
+ scheduleUpdate(c);
50
+ };
51
+ return [value, set];
52
+ }
53
+ function useRef(val) {
54
+ const c = getCurrentOrThrow();
55
+ const i = c.index++;
56
+ if (i >= c.slots.length) c.slots[i] = { current: val };
57
+ return c.slots[i];
58
+ }
59
+ function useMemo(fn, deps) {
60
+ const c = getCurrentOrThrow();
61
+ const i = c.index++;
62
+ const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, value: void 0 });
63
+ if (!depsChanged(slot.deps, deps)) return slot.value;
64
+ slot.value = fn();
65
+ slot.deps = deps;
66
+ return slot.value;
67
+ }
68
+ function useCallback(fn, deps) {
69
+ return useMemo(() => fn, deps);
70
+ }
71
+ function useEffect(fn, deps) {
72
+ const c = getCurrentOrThrow();
73
+ const i = c.index++;
74
+ const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, cleanup: void 0 });
75
+ c.effects.push(() => {
76
+ if (!depsChanged(slot.deps, deps)) return;
77
+ if (typeof slot.cleanup === "function") slot.cleanup();
78
+ slot.cleanup = fn();
79
+ if (deps !== void 0) {
80
+ slot.deps = deps;
81
+ }
82
+ });
83
+ }
84
+ function useTheme() {
85
+ return getCurrentCtx()?.theme;
86
+ }
87
+ function useThemeTokens() {
88
+ return getCurrentCtx()?.themeTokens;
89
+ }
90
+ function useForceRedraw(first, ...rest) {
91
+ const [, setForceRedraw] = useState(0);
92
+ const throttleMs = typeof first === "number" ? first : void 0;
93
+ const signals = typeof first === "number" ? rest : [first, ...rest];
94
+ useEffect(() => {
95
+ const unsubscribes = [];
96
+ let lastUpdate = 0;
97
+ const triggerUpdate = () => {
98
+ const now = Date.now();
99
+ if (throttleMs && now - lastUpdate < throttleMs) return;
100
+ lastUpdate = now;
101
+ setForceRedraw({});
102
+ };
103
+ for (const signal of signals) {
104
+ if (signal && typeof signal === "object" && "subscribe" in signal) {
105
+ unsubscribes.push(signal.subscribe(triggerUpdate));
106
+ }
107
+ }
108
+ return () => {
109
+ unsubscribes.forEach((unsubscribe) => unsubscribe());
110
+ };
111
+ }, [throttleMs, ...signals]);
112
+ }
113
+ function useRedraw() {
114
+ const c = getCurrentCtx();
115
+ return () => {
116
+ if (c != null) scheduleUpdate(c);
117
+ };
118
+ }
119
+ function scheduleUpdate(c) {
120
+ if (c.updater) return;
121
+ c.updater = () => {
122
+ c.updater = void 0;
123
+ if (c.disposed) return;
124
+ const handler = c.updateHandler ?? globalRegistry.getGlobalValue(_onScheduleUpdateKey);
125
+ if (handler) handler(c);
126
+ };
127
+ queueMicrotask(c.updater);
128
+ }
129
+ function depsChanged(a, b) {
130
+ if (!a || !b) return true;
131
+ if (a.length !== b.length) return true;
132
+ for (let i = 0; i < a.length; i++) {
133
+ if (!Object.is(a[i], b[i])) return true;
134
+ }
135
+ return false;
136
+ }
137
+ function shallowEqual(a, b) {
138
+ if (Object.is(a, b)) return true;
139
+ if (a == null || b == null) return false;
140
+ if (typeof a !== "object" || typeof b !== "object") return false;
141
+ const keysA = Object.keys(a);
142
+ const keysB = Object.keys(b);
143
+ if (keysA.length !== keysB.length) return false;
144
+ for (const key of keysA) {
145
+ if (!Object.prototype.hasOwnProperty.call(b, key) || !Object.is(a[key], b[key])) {
146
+ return false;
147
+ }
148
+ }
149
+ return true;
150
+ }
151
+ function shouldComponentUpdate(ctx, newProps) {
152
+ if (ctx.memoized === false) return true;
153
+ if (ctx.componentVNode.__memo === false) return true;
154
+ if (ctx.lastProps === void 0) {
155
+ ctx.lastProps = newProps;
156
+ return true;
157
+ }
158
+ const hasChanged = !shallowEqual(ctx.lastProps, newProps);
159
+ ctx.lastProps = newProps;
160
+ return hasChanged;
161
+ }
162
+ function disposeCtx(c) {
163
+ c.disposed = true;
164
+ for (const cl of c.cleanups) {
165
+ if (typeof cl === "function") cl();
166
+ }
167
+ for (const slot of c.slots) {
168
+ if (slot && typeof slot === "object" && "cleanup" in slot && typeof slot.cleanup === "function") {
169
+ slot.cleanup();
170
+ }
171
+ }
172
+ c.cleanups.length = 0;
173
+ }
174
+ function useSurface() {
175
+ const ctx = getCurrentCtx();
176
+ return ctx?.surface ?? null;
177
+ }
178
+ function useViewportSize() {
179
+ const ctx = getCurrentOrThrow();
180
+ return ctx.surface?.viewport ?? { width: 0, height: 0 };
181
+ }
182
+ function useDebugSnapshot(intervalMs = 250) {
183
+ const ctx = getCurrentCtx();
184
+ const collector = ctx?.surface?.debugSnapshotCollector;
185
+ const getInitial = () => {
186
+ if (!collector) return {};
187
+ try {
188
+ return collector();
189
+ } catch {
190
+ return {};
191
+ }
192
+ };
193
+ const [snapshot, setSnapshot] = useState(getInitial());
194
+ useEffect(() => {
195
+ if (!collector) return;
196
+ const delay = Math.max(50, intervalMs);
197
+ try {
198
+ setSnapshot(collector());
199
+ } catch {
200
+ }
201
+ const timer = window.setInterval(() => {
202
+ try {
203
+ setSnapshot(collector());
204
+ } catch {
205
+ }
206
+ }, delay);
207
+ return () => {
208
+ window.clearInterval(timer);
209
+ };
210
+ }, [intervalMs, collector]);
211
+ return snapshot;
212
+ }
213
+ function useLayoutEffect(fn, deps) {
214
+ const c = getCurrentOrThrow();
215
+ const i = c.index++;
216
+ const slot = c.slots[i] ?? (c.slots[i] = { deps: void 0, cleanup: void 0 });
217
+ c.effects.push(() => {
218
+ if (!depsChanged(slot.deps, deps)) return;
219
+ if (typeof slot.cleanup === "function") slot.cleanup();
220
+ const scheduler = c.surface?.scheduler;
221
+ if (scheduler) {
222
+ scheduler.requestAnimationFrame(() => {
223
+ slot.cleanup = fn();
224
+ });
225
+ } else {
226
+ requestAnimationFrame(() => {
227
+ slot.cleanup = fn();
228
+ });
229
+ }
230
+ if (deps !== void 0) {
231
+ slot.deps = deps;
232
+ }
233
+ });
234
+ }
235
+ function useTexture(key, url) {
236
+ const [ready, setReady] = useState(false);
237
+ const ctx = getCurrentOrThrow();
238
+ const loader = ctx.surface?.textureLoader;
239
+ useEffect(() => {
240
+ if (!loader) {
241
+ setReady(true);
242
+ return;
243
+ }
244
+ let cancelled = false;
245
+ loader.load(key, url).then(() => {
246
+ if (!cancelled) setReady(true);
247
+ });
248
+ return () => {
249
+ cancelled = true;
250
+ };
251
+ }, [key, url, loader]);
252
+ return { ready, key };
253
+ }
254
+ function useSVGTexture(keyOrConfigs, svg, width = 32, height = 32) {
255
+ if (typeof keyOrConfigs === "string") {
256
+ const key = keyOrConfigs;
257
+ if (svg == null) throw new Error("SVG string must be provided for single texture load");
258
+ const svgStr = svg;
259
+ const [ready2, setReady2] = useState(false);
260
+ const ctx2 = getCurrentOrThrow();
261
+ const loader2 = ctx2.surface?.textureLoader;
262
+ useEffect(() => {
263
+ if (!loader2) {
264
+ setReady2(true);
265
+ return;
266
+ }
267
+ let cancelled = false;
268
+ setReady2(false);
269
+ loader2.loadSVG(key, svgStr, width, height).then(() => {
270
+ if (!cancelled) setReady2(true);
271
+ });
272
+ return () => {
273
+ cancelled = true;
274
+ };
275
+ }, [key, svgStr, width, height, loader2]);
276
+ return ready2;
277
+ }
278
+ const configs = keyOrConfigs;
279
+ const [ready, setReady] = useState(false);
280
+ const ctx = getCurrentOrThrow();
281
+ const loader = ctx.surface?.textureLoader;
282
+ const configKey = useMemo(
283
+ () => configs.map((c) => `${c.key}:${c.width ?? 32}:${c.height ?? 32}`).join("|"),
284
+ [configs]
285
+ );
286
+ useEffect(() => {
287
+ if (!loader || configs.length === 0) {
288
+ setReady(true);
289
+ return;
290
+ }
291
+ let cancelled = false;
292
+ setReady(false);
293
+ const loadSequentially = async () => {
294
+ for (const { key, svg: s, width: w = 32, height: h = 32 } of configs) {
295
+ if (cancelled) return;
296
+ await loader.loadSVG(key, s, w, h);
297
+ }
298
+ if (!cancelled) setReady(true);
299
+ };
300
+ loadSequentially();
301
+ return () => {
302
+ cancelled = true;
303
+ };
304
+ }, [configKey, loader]);
305
+ return ready;
306
+ }
307
+ function asTextureResolver(loader) {
308
+ if (loader && typeof loader.getFrameNames === "function" && typeof loader.getFrameInfo === "function" && typeof loader.getFrameRect === "function" && typeof loader.getTextureSize === "function") {
309
+ return loader;
310
+ }
311
+ return void 0;
312
+ }
313
+ function useAtlas(key, imageUrl, dataUrl) {
314
+ const [ready, setReady] = useState(false);
315
+ const ctx = getCurrentOrThrow();
316
+ const loader = ctx.surface?.textureLoader;
317
+ const resolver = asTextureResolver(loader);
318
+ useEffect(() => {
319
+ if (!loader) {
320
+ setReady(true);
321
+ return;
322
+ }
323
+ let cancelled = false;
324
+ loader.loadAtlas(key, imageUrl, dataUrl).then(() => {
325
+ if (!cancelled) setReady(true);
326
+ });
327
+ return () => {
328
+ cancelled = true;
329
+ };
330
+ }, [key, imageUrl, dataUrl, loader]);
331
+ const textureSize = useMemo(
332
+ () => ready && resolver ? resolver.getTextureSize(key) : void 0,
333
+ [ready, resolver, key]
334
+ );
335
+ const frameNames = useMemo(
336
+ () => ready && resolver ? resolver.getFrameNames(key) : [],
337
+ [ready, resolver, key]
338
+ );
339
+ const frames = useMemo(
340
+ () => frameNames.map((frame) => resolver?.getFrameInfo(key, frame)).filter((frame) => frame !== void 0),
341
+ [frameNames, resolver, key]
342
+ );
343
+ const getFrameInfo = useCallback(
344
+ (frame) => ready && resolver ? resolver.getFrameInfo(key, frame) : void 0,
345
+ [ready, resolver, key]
346
+ );
347
+ const getFrameRect = useCallback(
348
+ (frame) => ready && resolver ? resolver.getFrameRect(key, frame) : void 0,
349
+ [ready, resolver, key]
350
+ );
351
+ return { ready, key, textureSize, frameNames, frames, getFrameInfo, getFrameRect };
352
+ }
353
+ exports.depsChanged = depsChanged;
354
+ exports.disposeCtx = disposeCtx;
355
+ exports.getCurrentCtx = getCurrentCtx;
356
+ exports.getCurrentOrThrow = getCurrentOrThrow;
357
+ exports.setCurrentCtx = setCurrentCtx;
358
+ exports.setUpdateHandler = setUpdateHandler;
359
+ exports.shallowEqual = shallowEqual;
360
+ exports.shouldComponentUpdate = shouldComponentUpdate;
361
+ exports.useAtlas = useAtlas;
362
+ exports.useCallback = useCallback;
363
+ exports.useDebugSnapshot = useDebugSnapshot;
364
+ exports.useEffect = useEffect;
365
+ exports.useForceRedraw = useForceRedraw;
366
+ exports.useLayoutEffect = useLayoutEffect;
367
+ exports.useMemo = useMemo;
368
+ exports.useRedraw = useRedraw;
369
+ exports.useRef = useRef;
370
+ exports.useSVGTexture = useSVGTexture;
371
+ exports.useState = useState;
372
+ exports.useSurface = useSurface;
373
+ exports.useTexture = useTexture;
374
+ exports.useTheme = useTheme;
375
+ exports.useThemeTokens = useThemeTokens;
376
+ exports.useViewportSize = useViewportSize;
377
+ exports.withHooks = withHooks;
378
+ //# sourceMappingURL=hooks.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.cjs","sources":["../src/hooks.ts"],"sourcesContent":["/**\n * Portable hook runtime — renderer-neutral component state management.\n *\n * Provides React-like hooks (useState, useEffect, useMemo, useRef, useCallback)\n * that work against a generic HookContext. Each renderer provides its own\n * `withHooks()` wrapper that supplies the context and manages the render cycle.\n *\n * @migration(audit:scene-portal-mount) Phase 3G — extracted from packages/ui/src/hooks.ts.\n * Pure hook functions live here. Phaser-specific hooks (useScene, layout helpers)\n * and the render cycle (withHooks, scheduleUpdate) remain in the renderer package.\n */\n\nimport type { Signal } from '@preact/signals-core'\nimport type { DesignTokens } from './design-tokens/design-token-types'\nimport { getGlobalValue, setGlobalValue } from './global-registry'\nimport type {\n AtlasFrameInfo,\n FrameRect,\n Size,\n SurfaceContext,\n TextureResolver,\n} from './host-adapter'\nimport type { PartialTheme } from './theme'\n\n// ---------------------------------------------------------------------------\n// HookContext — portable context for hook state\n// ---------------------------------------------------------------------------\n\ntype Cleanup = void | (() => void)\n\n/**\n * Portable hook context — the data structure passed through the hook runtime.\n * Each renderer extends this with renderer-specific fields (e.g., Phaser adds `parent: ParentType`).\n */\nexport interface HookContext {\n /** Current hook slot index (incremented by each hook call) */\n index: number\n /** Hook state slots (one per hook call) */\n slots: unknown[]\n /** Pending effects to run after render */\n effects: (() => Cleanup)[]\n /** Cleanup functions to run on unmount */\n cleanups: Cleanup[]\n /** The rendered VNode output of the component */\n vnode: unknown | null\n /** The component VNode itself (type = function) */\n componentVNode: {\n type: unknown\n props?: Record<string, unknown> | undefined\n children?: unknown[]\n __memo?: boolean\n }\n /** The component function */\n function: (props: unknown) => unknown\n /** Optional updater callback (set by renderer's withHooks/scheduleUpdate) */\n updater?: (() => void) | undefined\n /** Optional per-runtime update handler for concurrent renderer runtimes */\n updateHandler?: ((ctx: HookContext) => void) | undefined\n /** Whether this is a VNode factory (no hooks used) */\n isFactory: boolean\n /** Last rendered props (for memoization) */\n lastProps?: unknown\n /** Whether component uses memoization (default: true) */\n memoized?: boolean\n /** Theme context for this component */\n theme?: PartialTheme | undefined\n /** Design tokens injected by the renderer (colors, text styles, spacing, etc.) */\n themeTokens?: Record<string, unknown> | undefined\n /** Flag to prevent updates after disposal */\n disposed?: boolean\n /**\n * Surface context for accessing viewport, scheduler, and capabilities.\n * Set by the renderer's withHooks() wrapper during component render.\n *\n * @migration(audit:scene-portal-mount) Phase 6G — enables portable hooks\n * (useViewportSize, useLayoutEffect via HostScheduler, ...).\n */\n surface?: SurfaceContext | undefined\n}\n\n// ---------------------------------------------------------------------------\n// Global registry for bundler-safe module-level state\n// ---------------------------------------------------------------------------\n\nconst GLOBAL_NS = '@number10/jsx-core'\nconst _currentCtxKey = Symbol.for(`${GLOBAL_NS}:currentCtx`)\nconst _onScheduleUpdateKey = Symbol.for(`${GLOBAL_NS}:onScheduleUpdate`)\n\n/**\n * Get the current hook context. Must be called during component render.\n * Uses a global registry to ensure correctness even when bundlers duplicate modules.\n * @returns Current context or null if not in render\n */\nexport function getCurrentCtx(): HookContext | null {\n return getGlobalValue<HookContext | null>(_currentCtxKey) ?? null\n}\n\n/**\n * Set the current hook context. Called by withHooks() in the renderer.\n * @internal\n */\nexport function setCurrentCtx(ctx: HookContext | null): void {\n setGlobalValue(_currentCtxKey, ctx)\n}\n\n/**\n * Portable render cycle — sets up hook context, runs render, runs effects.\n * Each renderer wraps this with its own lifecycle guards.\n *\n * @param ctx - The hook context for this component\n * @param render - The render function to execute\n * @param opts - Optional renderer-specific hooks\n * @returns The result of the render function, or null if the guard fails\n *\n * @migration(audit:scene-portal-mount) Phase 6I — extracted from Phaser withHooks().\n * The guard callback replaces Phaser-specific scene/shutdown checks.\n */\nexport function withHooks<T>(\n ctx: HookContext,\n render: () => T,\n opts?: {\n /** Renderer-specific lifecycle guard. Return false to abort render. */\n isAlive?: () => boolean\n /** Called after render, before restoring context. For renderer-specific side effects. */\n onAfterRender?: () => void\n }\n): T | null {\n if (opts?.isAlive && !opts.isAlive()) return null\n\n const prev = getCurrentCtx()\n setCurrentCtx(ctx)\n ctx.index = 0\n ctx.effects = []\n\n try {\n const out = render()\n opts?.onAfterRender?.()\n return out\n } finally {\n setCurrentCtx(prev)\n }\n}\n\n/**\n * Get current hook context, throwing if not in a render context.\n * Used by hooks that MUST be called during render.\n * @returns Non-null hook context\n * @throws Error if called outside of a component render\n */\nexport function getCurrentOrThrow(): HookContext {\n const ctx = getCurrentCtx()\n if (!ctx) {\n throw new Error(\n 'Hook called outside of component render. ' +\n 'Hooks (useState, useRef, useEffect, etc.) must be called synchronously ' +\n 'during a function component render. ' +\n 'This error commonly occurs when:\\n' +\n ' 1. A hook is called in an async callback or event handler\\n' +\n ' 2. A hook is called after the component has unmounted\\n' +\n ' 3. A hook is called in a non-component function'\n )\n }\n return ctx\n}\n\n// ---------------------------------------------------------------------------\n// Injectable update handler — renderer-provided VDOM patching\n// ---------------------------------------------------------------------------\n\n/** Callback type for renderer-specific update logic */\nexport type UpdateHandler = (ctx: HookContext) => void\n\n/**\n * Register a renderer-specific update handler.\n * Called once by the renderer package to override core's no-op scheduleUpdate.\n * Uses a global registry to ensure correctness even when bundlers duplicate modules.\n * @param handler - Function that performs the actual VDOM patching for a component\n */\nexport function setUpdateHandler(handler: UpdateHandler): void {\n setGlobalValue(_onScheduleUpdateKey, handler)\n}\n\n// ---------------------------------------------------------------------------\n// State hook\n// ---------------------------------------------------------------------------\n\n/**\n * State hook for managing component state.\n * @param initial - Initial state value or initializer function\n * @returns Tuple of current state and setter function\n */\nexport function useState<T>(initial: T): [T, (v: T | ((p: T) => T)) => void] {\n const c = getCurrentOrThrow()\n const i = c.index++\n if (i >= c.slots.length)\n c.slots[i] = typeof initial === 'function' ? (initial as () => T)() : initial\n const value = c.slots[i] as T\n const set = (v: T | ((p: T) => T)) => {\n const next = typeof v === 'function' ? (v as (p: T) => T)(c.slots[i] as T) : v\n if (Object.is(next, c.slots[i])) return\n c.slots[i] = next\n scheduleUpdate(c)\n }\n return [value, set]\n}\n\n// ---------------------------------------------------------------------------\n// Ref hook\n// ---------------------------------------------------------------------------\n\n/**\n * Ref hook for storing mutable values.\n * @param val - Initial ref value\n * @returns Ref object with current property\n */\nexport function useRef<T>(val: T): { current: T } {\n const c = getCurrentOrThrow()\n const i = c.index++\n if (i >= c.slots.length) c.slots[i] = { current: val }\n return c.slots[i] as { current: T }\n}\n\n// ---------------------------------------------------------------------------\n// Memoization hook\n// ---------------------------------------------------------------------------\n\n/**\n * Memoization hook for expensive computations.\n * @param fn - Function to memoize\n * @param deps - Dependency array\n * @returns Memoized value\n */\nexport function useMemo<T>(fn: () => T, deps: readonly unknown[]): T {\n const c = getCurrentOrThrow()\n const i = c.index++\n const slot = (c.slots[i] ?? (c.slots[i] = { deps: undefined, value: undefined as T })) as {\n deps?: readonly unknown[]\n value: T\n }\n if (!depsChanged(slot.deps, deps)) return slot.value\n slot.value = fn()\n slot.deps = deps\n return slot.value\n}\n\n// ---------------------------------------------------------------------------\n// Callback memoization hook\n// ---------------------------------------------------------------------------\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function useCallback<T extends (...args: any[]) => any>(fn: T, deps: readonly unknown[]): T {\n return useMemo(() => fn, deps)\n}\n\n// ---------------------------------------------------------------------------\n// Effect hook\n// ---------------------------------------------------------------------------\n\n/**\n * Effect hook for side effects with cleanup.\n * @param fn - Effect function that optionally returns cleanup\n * @param deps - Optional dependency array\n */\nexport function useEffect(fn: () => Cleanup, deps?: readonly unknown[] | undefined) {\n const c = getCurrentOrThrow()\n const i = c.index++\n const slot = (c.slots[i] ??\n (c.slots[i] = { deps: undefined, cleanup: undefined as Cleanup })) as {\n deps?: readonly unknown[] | undefined\n cleanup: Cleanup\n }\n c.effects.push(() => {\n if (!depsChanged(slot.deps, deps)) return\n if (typeof slot.cleanup === 'function') slot.cleanup()\n slot.cleanup = fn()\n if (deps !== undefined) {\n slot.deps = deps\n }\n })\n}\n\n// ---------------------------------------------------------------------------\n// Theme hook\n// ---------------------------------------------------------------------------\n\n/**\n * Hook to access current theme context.\n * Returns the theme that was passed down through the VDOM tree.\n * @returns Current theme context or undefined if no theme is set\n */\nexport function useTheme(): PartialTheme | undefined {\n return getCurrentCtx()?.theme as PartialTheme | undefined\n}\n\n/**\n * Hook to access design tokens injected by the renderer.\n * Each renderer sets `themeTokens` on the hook context during component render\n * (e.g., Phaser's plugin injects color presets, text styles, spacing).\n * Returns undefined if no tokens are configured by the active renderer.\n * @returns Design tokens or undefined\n */\nexport function useThemeTokens<T = DesignTokens>(): T | undefined {\n return getCurrentCtx()?.themeTokens as T | undefined\n}\n\n// ---------------------------------------------------------------------------\n// Force re-render via signals\n// ---------------------------------------------------------------------------\n\n/**\n * Hook to force component re-render when signals change.\n */\nexport function useForceRedraw(throttleMs: number, ...signals: Signal<unknown>[]): void\nexport function useForceRedraw(...signals: Signal<unknown>[]): void\nexport function useForceRedraw(first: number | Signal<unknown>, ...rest: Signal<unknown>[]): void {\n const [, setForceRedraw] = useState<unknown>(0)\n const throttleMs = typeof first === 'number' ? first : undefined\n const signals = typeof first === 'number' ? rest : [first, ...rest]\n\n useEffect(() => {\n const unsubscribes: (() => void)[] = []\n let lastUpdate = 0\n\n const triggerUpdate = () => {\n const now = Date.now()\n if (throttleMs && now - lastUpdate < throttleMs) return\n lastUpdate = now\n setForceRedraw({})\n }\n\n for (const signal of signals) {\n if (signal && typeof signal === 'object' && 'subscribe' in signal) {\n unsubscribes.push(signal.subscribe(triggerUpdate))\n }\n }\n\n return () => {\n unsubscribes.forEach((unsubscribe) => unsubscribe())\n }\n }, [throttleMs, ...signals])\n}\n\n// ---------------------------------------------------------------------------\n// Manual redraw trigger\n// ---------------------------------------------------------------------------\n\n/**\n * Hook to manually trigger a component redraw.\n * @returns Function to trigger redraw\n */\nexport function useRedraw(): () => void {\n const c = getCurrentCtx()\n return () => {\n if (c != null) scheduleUpdate(c)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Scheduling — portable version (calls ctx.updater)\n// ---------------------------------------------------------------------------\n\n/**\n * Schedule a component update on next microtask.\n * The renderer provides the actual update logic via ctx.updater.\n * @param c - Component context to update\n */\nfunction scheduleUpdate(c: HookContext) {\n if (c.updater) return\n c.updater = () => {\n c.updater = undefined\n if (c.disposed) return\n // Delegates to renderer-provided update handler (e.g., Phaser's VDOM patching)\n const handler = c.updateHandler ?? getGlobalValue<UpdateHandler>(_onScheduleUpdateKey)\n if (handler) handler(c)\n }\n queueMicrotask(c.updater)\n}\n\n// ---------------------------------------------------------------------------\n// Utilities\n// ---------------------------------------------------------------------------\n\n/**\n * Checks if dependency arrays have changed.\n */\nexport function depsChanged(a?: readonly unknown[], b?: readonly unknown[]) {\n if (!a || !b) return true\n if (a.length !== b.length) return true\n for (let i = 0; i < a.length; i++) {\n if (!Object.is(a[i], b[i])) return true\n }\n return false\n}\n\n/**\n * Shallow comparison for props objects.\n * Used for component memoization (React.memo equivalent).\n */\nexport function shallowEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true\n if (a == null || b == null) return false\n if (typeof a !== 'object' || typeof b !== 'object') return false\n\n const keysA = Object.keys(a as object)\n const keysB = Object.keys(b as object)\n if (keysA.length !== keysB.length) return false\n\n for (const key of keysA) {\n if (\n !Object.prototype.hasOwnProperty.call(b, key) ||\n !Object.is((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])\n ) {\n return false\n }\n }\n return true\n}\n\n/**\n * Check if component should update based on props comparison.\n */\nexport function shouldComponentUpdate(ctx: HookContext, newProps: unknown): boolean {\n if (ctx.memoized === false) return true\n if (ctx.componentVNode.__memo === false) return true\n\n if (ctx.lastProps === undefined) {\n ctx.lastProps = newProps\n return true\n }\n\n const hasChanged = !shallowEqual(ctx.lastProps, newProps)\n ctx.lastProps = newProps\n return hasChanged\n}\n\n/**\n * Disposes component context and runs cleanups.\n */\nexport function disposeCtx(c: HookContext) {\n c.disposed = true\n\n for (const cl of c.cleanups) {\n if (typeof cl === 'function') cl()\n }\n\n for (const slot of c.slots) {\n if (\n slot &&\n typeof slot === 'object' &&\n 'cleanup' in slot &&\n typeof (slot as { cleanup?: () => void }).cleanup === 'function'\n ) {\n ;(slot as { cleanup: () => void }).cleanup()\n }\n }\n\n c.cleanups.length = 0\n}\n\n// ---------------------------------------------------------------------------\n// Surface-aware hooks (Phase 6G+)\n// ---------------------------------------------------------------------------\n\n/**\n * Hook to access the full SurfaceContext (viewport, scheduler, capabilities).\n * Must be called during component render. Returns null if no surface is available.\n *\n * Portable — works with any renderer that provides SurfaceContext.\n * @returns SurfaceContext or null\n *\n * @migration(audit:surface-access) Phase 7 — new hook, replaces manual ctx.surface access.\n */\nexport function useSurface(): SurfaceContext | null {\n const ctx = getCurrentCtx()\n return ctx?.surface ?? null\n}\n\n/**\n * Hook to get the current viewport size from the surface context.\n * Portable — works with any renderer that provides SurfaceContext.\n * @returns Viewport dimensions { width, height }\n *\n * @migration(audit:scene-portal-mount) Phase 6G — extracted from Phaser hooks.ts.\n * Uses ctx.surface.viewport instead of Phaser-specific RenderContext.\n */\nexport function useViewportSize(): { width: number; height: number } {\n const ctx = getCurrentOrThrow()\n return ctx.surface?.viewport ?? { width: 0, height: 0 }\n}\n\n// ---------------------------------------------------------------------------\n// useDebugSnapshot — renderer-agnostic debug metrics hook\n// ---------------------------------------------------------------------------\n\n/**\n * Hook that collects debug metrics from the active renderer on an interval.\n *\n * Delegates to the `debugSnapshotCollector` function registered by the\n * renderer on the {@link SurfaceContext}. When no collector is registered,\n * returns an empty snapshot.\n *\n * Portable — works with any renderer (Phaser, Pixi, …). Each renderer\n * wires its own collector into the SurfaceContext during surface creation.\n *\n * @param intervalMs - Refresh interval in milliseconds (default: 250)\n * @returns Debug snapshot (key → string|number), refreshed on interval\n *\n * @example\n * ```tsx\n * import { useDebugSnapshot } from '@number10/jsx-core'\n * import { DebugPanel } from '@number10/jsx-components'\n *\n * function App() {\n * const snapshot = useDebugSnapshot(500)\n * return <DebugPanel snapshot={snapshot} metrics={['fps', 'renderer']} />\n * }\n * ```\n */\nexport function useDebugSnapshot(intervalMs = 250): Record<string, string | number> {\n const ctx = getCurrentCtx()\n const collector = ctx?.surface?.debugSnapshotCollector\n\n const getInitial = (): Record<string, string | number> => {\n if (!collector) return {}\n try {\n return collector()\n } catch {\n return {}\n }\n }\n\n const [snapshot, setSnapshot] = useState(getInitial())\n\n useEffect(() => {\n if (!collector) return\n\n const delay = Math.max(50, intervalMs)\n try {\n setSnapshot(collector())\n } catch {\n // collector may throw if renderer not ready yet\n }\n\n const timer = window.setInterval(() => {\n try {\n setSnapshot(collector())\n } catch {\n // silently ignore\n }\n }, delay)\n\n return () => {\n window.clearInterval(timer)\n }\n }, [intervalMs, collector])\n\n return snapshot\n}\n\n// ---------------------------------------------------------------------------\n// Layout-aware effect hook (Phase 6H)\n// ---------------------------------------------------------------------------\n\ntype CleanupFn = void | (() => void)\n\n/**\n * Layout-aware effect hook — defers execution to the next animation frame.\n * Uses HostScheduler.requestAnimationFrame() when available, falls back to\n * global requestAnimationFrame.\n *\n * Portable across renderers. Each renderer's HostScheduler provides the tick source.\n * Phaser uses scene.events.once('update'), PixiJS would use app.ticker.addOnce().\n *\n * @param fn - Effect function that optionally returns a cleanup\n * @param deps - Optional dependency array\n *\n * @migration(audit:scene-portal-mount) Phase 6H — portable version uses HostScheduler.\n */\nexport function useLayoutEffect(fn: () => CleanupFn, deps?: readonly unknown[] | undefined) {\n const c = getCurrentOrThrow()\n const i = c.index++\n const slot = (c.slots[i] ??\n (c.slots[i] = { deps: undefined, cleanup: undefined as CleanupFn })) as {\n deps?: readonly unknown[] | undefined\n cleanup: CleanupFn\n }\n c.effects.push(() => {\n if (!depsChanged(slot.deps, deps)) return\n if (typeof slot.cleanup === 'function') slot.cleanup()\n\n const scheduler = c.surface?.scheduler\n if (scheduler) {\n scheduler.requestAnimationFrame(() => {\n slot.cleanup = fn()\n })\n } else {\n requestAnimationFrame(() => {\n slot.cleanup = fn()\n })\n }\n\n if (deps !== undefined) {\n slot.deps = deps\n }\n })\n}\n\n// ---------------------------------------------------------------------------\n// useTexture — portable texture loading hook\n// ---------------------------------------------------------------------------\n\n/**\n * Load a texture from a URL and register it under the given key.\n * Returns `{ ready, key }` — use `key` as the `texture` prop on `<Image>`.\n *\n * Portable — works with any renderer that provides `textureLoader` on\n * its SurfaceContext. Replaces Phaser-specific preload functions.\n *\n * @param key — Unique texture key (e.g. 'icon', 'background')\n * @param url — URL to load the texture from\n * @returns `{ ready: boolean, key: string }`\n *\n * @example\n * ```tsx\n * function MyIcon() {\n * const { ready, key } = useTexture('star', '/assets/star.png')\n * if (!ready) return <Text text=\"Loading...\" />\n * return <Image texture={key} width={48} height={48} />\n * }\n * ```\n */\nexport function useTexture(key: string, url: string): { ready: boolean; key: string } {\n const [ready, setReady] = useState(false)\n const ctx = getCurrentOrThrow()\n const loader = ctx.surface?.textureLoader\n\n useEffect(() => {\n if (!loader) {\n setReady(true)\n return\n }\n\n let cancelled = false\n loader.load(key, url).then(() => {\n if (!cancelled) setReady(true)\n })\n\n return () => {\n cancelled = true\n }\n }, [key, url, loader])\n\n return { ready, key }\n}\n\n// ---------------------------------------------------------------------------\n// SVGTextureConfig — portable SVG texture configuration\n// ---------------------------------------------------------------------------\n\n/**\n * Configuration for loading a single SVG as a texture.\n * Used by {@link useSVGTexture} for batch loading.\n */\nexport interface SVGTextureConfig {\n /** Unique texture key */\n key: string\n /** SVG markup string */\n svg: string\n /** Texture width in pixels (default: 32) */\n width?: number\n /** Texture height in pixels (default: 32) */\n height?: number\n}\n\n// ---------------------------------------------------------------------------\n// useSVGTexture — portable single & batch SVG→texture hook\n// ---------------------------------------------------------------------------\n\n/**\n * Render an SVG string to a texture and register it under the given key.\n * Returns `ready: boolean` — when true, use the key as `<Image texture={key} />`.\n *\n * Portable — works with any renderer that provides `textureLoader.loadSVG`\n * on its SurfaceContext.\n */\nexport function useSVGTexture(key: string, svg: string, width?: number, height?: number): boolean\n/**\n * Load multiple SVGs as textures in batch.\n * Returns `ready: boolean` — when true, all textures are registered.\n */\nexport function useSVGTexture(configs: SVGTextureConfig[]): boolean\nexport function useSVGTexture(\n keyOrConfigs: string | SVGTextureConfig[],\n svg?: string,\n width: number = 32,\n height: number = 32\n): boolean {\n // Singular mode\n if (typeof keyOrConfigs === 'string') {\n const key = keyOrConfigs\n if (svg == null) throw new Error('SVG string must be provided for single texture load')\n const svgStr = svg\n const [ready, setReady] = useState(false)\n const ctx = getCurrentOrThrow()\n const loader = ctx.surface?.textureLoader\n\n useEffect(() => {\n if (!loader) {\n setReady(true)\n return\n }\n\n let cancelled = false\n setReady(false)\n loader.loadSVG(key, svgStr, width, height).then(() => {\n if (!cancelled) setReady(true)\n })\n\n return () => {\n cancelled = true\n }\n }, [key, svgStr, width, height, loader])\n\n return ready\n }\n\n // Batch mode\n const configs = keyOrConfigs\n const [ready, setReady] = useState(false)\n const ctx = getCurrentOrThrow()\n const loader = ctx.surface?.textureLoader\n\n // Stable key from configs to detect semantic changes (not referential)\n const configKey = useMemo(\n () => configs.map((c) => `${c.key}:${c.width ?? 32}:${c.height ?? 32}`).join('|'),\n [configs]\n )\n\n useEffect(() => {\n if (!loader || configs.length === 0) {\n setReady(true)\n return\n }\n\n let cancelled = false\n setReady(false)\n\n const loadSequentially = async () => {\n for (const { key, svg: s, width: w = 32, height: h = 32 } of configs) {\n if (cancelled) return\n await loader.loadSVG(key, s, w, h)\n }\n if (!cancelled) setReady(true)\n }\n\n loadSequentially()\n\n return () => {\n cancelled = true\n }\n }, [configKey, loader])\n\n return ready\n}\n\n// ---------------------------------------------------------------------------\n// useAtlas — portable atlas (spritesheet) loading hook\n// ---------------------------------------------------------------------------\n\n/**\n * Result object returned by {@link useAtlas}.\n *\n * Combines atlas loading state with portable metadata access so callers can\n * render frames and inspect atlas contents without renderer-specific APIs.\n */\nexport interface UseAtlasResult {\n /** Whether the atlas image and JSON data are fully loaded and queryable. */\n ready: boolean\n /** Texture key to pass into portable image-like components. */\n key: string\n /** Dimensions of the full atlas texture, if available from the active renderer. */\n textureSize: Size | undefined\n /** All known frame names within the loaded atlas. */\n frameNames: string[]\n /** Full portable metadata for every known frame in the atlas. */\n frames: AtlasFrameInfo[]\n /** Look up full metadata for a specific frame name. */\n getFrameInfo: (frame: string) => AtlasFrameInfo | undefined\n /** Look up only the atlas rectangle for a specific frame name. */\n getFrameRect: (frame: string) => FrameRect | undefined\n}\n\nfunction asTextureResolver(\n loader: SurfaceContext['textureLoader'] | undefined\n): TextureResolver | undefined {\n if (\n loader &&\n typeof (loader as Partial<TextureResolver>).getFrameNames === 'function' &&\n typeof (loader as Partial<TextureResolver>).getFrameInfo === 'function' &&\n typeof (loader as Partial<TextureResolver>).getFrameRect === 'function' &&\n typeof (loader as Partial<TextureResolver>).getTextureSize === 'function'\n ) {\n return loader as TextureResolver\n }\n return undefined\n}\n\n/**\n * Load a texture atlas from image + data URLs.\n * Returns `{ ready, key }` plus portable atlas metadata helpers.\n * Use `key` as `texture` and frame names as `frame`.\n *\n * @param key — Unique atlas key (e.g. 'buttons')\n * @param imageUrl — URL to the atlas image (PNG)\n * @param dataUrl — URL to the atlas data (JSON)\n *\n * @example\n * ```tsx\n * const { ready, key } = useAtlas('buttons', '/ui/buttons.png', '/ui/buttons.json')\n * if (!ready) return <Text text=\"Loading...\" />\n * return <Image texture={key} frame=\"ButtonGreen\" />\n * ```\n */\nexport function useAtlas(key: string, imageUrl: string, dataUrl: string): UseAtlasResult {\n const [ready, setReady] = useState(false)\n const ctx = getCurrentOrThrow()\n const loader = ctx.surface?.textureLoader\n const resolver = asTextureResolver(loader)\n\n useEffect(() => {\n if (!loader) {\n setReady(true)\n return\n }\n\n let cancelled = false\n loader.loadAtlas(key, imageUrl, dataUrl).then(() => {\n if (!cancelled) setReady(true)\n })\n\n return () => {\n cancelled = true\n }\n }, [key, imageUrl, dataUrl, loader])\n\n const textureSize = useMemo(\n () => (ready && resolver ? resolver.getTextureSize(key) : undefined),\n [ready, resolver, key]\n )\n const frameNames = useMemo(\n () => (ready && resolver ? resolver.getFrameNames(key) : []),\n [ready, resolver, key]\n )\n const frames = useMemo(\n () =>\n frameNames\n .map((frame) => resolver?.getFrameInfo(key, frame))\n .filter((frame): frame is AtlasFrameInfo => frame !== undefined),\n [frameNames, resolver, key]\n )\n const getFrameInfo = useCallback(\n (frame: string) => (ready && resolver ? resolver.getFrameInfo(key, frame) : undefined),\n [ready, resolver, key]\n )\n const getFrameRect = useCallback(\n (frame: string) => (ready && resolver ? resolver.getFrameRect(key, frame) : undefined),\n [ready, resolver, key]\n )\n\n return { ready, key, textureSize, frameNames, frames, getFrameInfo, getFrameRect }\n}\n"],"names":["getGlobalValue","setGlobalValue","ready","setReady","ctx","loader"],"mappings":"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"}