tungsten 0.3.2 → 0.3.4

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 (397) hide show
  1. package/dist/.build-complete +1 -0
  2. package/dist/Components.d.ts +6 -1
  3. package/dist/Components.d.ts.map +1 -1
  4. package/dist/Components.js +103 -40
  5. package/dist/DomPointer.d.ts +11 -0
  6. package/dist/DomPointer.d.ts.map +1 -1
  7. package/dist/DomPointer.js +15 -0
  8. package/dist/DomRegion.d.ts +2 -0
  9. package/dist/DomRegion.d.ts.map +1 -1
  10. package/dist/DomRegion.js +23 -3
  11. package/dist/Framework.d.ts +2 -0
  12. package/dist/Framework.d.ts.map +1 -1
  13. package/dist/Framework.js +94 -61
  14. package/dist/FrameworkConfig.d.ts +4 -0
  15. package/dist/FrameworkConfig.d.ts.map +1 -1
  16. package/dist/Instance/Instance.d.ts +1 -1
  17. package/dist/Instance/Instance.d.ts.map +1 -1
  18. package/dist/Instance/Instance.js +18 -1
  19. package/dist/Instance/InstanceConfig.d.ts +1 -0
  20. package/dist/Instance/InstanceConfig.d.ts.map +1 -1
  21. package/dist/PopMessage.type.d.ts +6 -0
  22. package/dist/PopMessage.type.d.ts.map +1 -0
  23. package/dist/PopMessage.type.js +1 -0
  24. package/dist/Servers/DevServer.d.ts +2 -0
  25. package/dist/Servers/DevServer.d.ts.map +1 -1
  26. package/dist/Servers/DevServer.js +87 -11
  27. package/dist/Servers/MatchedRouteInfo.d.ts +1 -1
  28. package/dist/Servers/MatchedRouteInfo.d.ts.map +1 -1
  29. package/dist/Servers/ProdServer.d.ts +2 -1
  30. package/dist/Servers/ProdServer.d.ts.map +1 -1
  31. package/dist/Servers/ProdServer.js +92 -8
  32. package/dist/Servers/hono/DevServerHono.js +25 -29
  33. package/dist/Servers/hono/ProdServerHono.js +49 -142
  34. package/dist/Servers/hono/TungstenServerHono.d.ts +1 -1
  35. package/dist/Servers/hono/TungstenServerHono.d.ts.map +1 -1
  36. package/dist/Servers/hono/TungstenServerHono.js +12 -29
  37. package/dist/Servers/loadEnvsDev.d.ts.map +1 -1
  38. package/dist/Servers/loadEnvsDev.js +16 -5
  39. package/dist/Servers/routing.d.ts.map +1 -1
  40. package/dist/Servers/routing.js +10 -6
  41. package/dist/Servers/tungstenCorePrivateEnvSchema.d.ts +0 -3
  42. package/dist/Servers/tungstenCorePrivateEnvSchema.d.ts.map +1 -1
  43. package/dist/Servers/tungstenCorePrivateEnvSchema.js +3 -3
  44. package/dist/Servers/tungstenCorePublicEnvSchema.d.ts +8 -0
  45. package/dist/Servers/tungstenCorePublicEnvSchema.d.ts.map +1 -0
  46. package/dist/Servers/tungstenCorePublicEnvSchema.js +14 -0
  47. package/dist/Store/InternalStoreSchema.d.ts +2 -0
  48. package/dist/Store/InternalStoreSchema.d.ts.map +1 -1
  49. package/dist/Store/InternalStoreSchema.js +1 -0
  50. package/dist/api/Request.d.ts +1 -1
  51. package/dist/api/Request.d.ts.map +1 -1
  52. package/dist/api/Response.d.ts +1 -1
  53. package/dist/api/Response.d.ts.map +1 -1
  54. package/dist/babelPlugins/BabelExtractComponentStylesheet.d.ts +13 -0
  55. package/dist/babelPlugins/BabelExtractComponentStylesheet.d.ts.map +1 -0
  56. package/dist/babelPlugins/BabelExtractComponentStylesheet.js +24 -0
  57. package/dist/babelPlugins/BabelTransformComponentStyles.d.ts +2 -0
  58. package/dist/babelPlugins/BabelTransformComponentStyles.d.ts.map +1 -1
  59. package/dist/babelPlugins/BabelTransformComponentStyles.js +21 -5
  60. package/dist/babelPlugins/BabelTransformPackageImports.d.ts +1 -0
  61. package/dist/babelPlugins/BabelTransformPackageImports.d.ts.map +1 -1
  62. package/dist/babelPlugins/BabelTransformPackageImports.js +21 -9
  63. package/dist/babelPlugins/BabelTypes.d.ts +2 -2
  64. package/dist/babelPlugins/BabelTypes.d.ts.map +1 -1
  65. package/dist/babelPlugins/BabelTypes.js +0 -1
  66. package/dist/bin/commands/build.d.ts.map +1 -1
  67. package/dist/bin/commands/build.js +12 -2
  68. package/dist/bin/commands/compile.d.ts.map +1 -1
  69. package/dist/bin/commands/compile.js +7 -2
  70. package/dist/bin/commands/dev.d.ts.map +1 -1
  71. package/dist/bin/commands/dev.js +15 -4
  72. package/dist/bin/commands/devmon.d.ts +2 -0
  73. package/dist/bin/commands/devmon.d.ts.map +1 -0
  74. package/dist/bin/commands/devmon.js +66 -0
  75. package/dist/bin/index.d.ts.map +1 -1
  76. package/dist/bin/index.js +6 -0
  77. package/dist/booleanAttributeValue.d.ts +21 -0
  78. package/dist/booleanAttributeValue.d.ts.map +1 -0
  79. package/dist/booleanAttributeValue.js +23 -0
  80. package/dist/build/CompilationInfo.d.ts +1 -0
  81. package/dist/build/CompilationInfo.d.ts.map +1 -1
  82. package/dist/build/combineComponentCss.d.ts +1 -1
  83. package/dist/build/combineComponentCss.d.ts.map +1 -1
  84. package/dist/build/combineComponentCss.js +3 -3
  85. package/dist/build/compileJavascript.d.ts.map +1 -1
  86. package/dist/build/compileJavascript.js +3 -3
  87. package/dist/build/compileUserApp.d.ts +2 -1
  88. package/dist/build/compileUserApp.d.ts.map +1 -1
  89. package/dist/build/compileUserApp.js +18 -8
  90. package/dist/build/createInstanceConfigFile.js +1 -1
  91. package/dist/build/frameworkStylesheets.d.ts +5 -0
  92. package/dist/build/frameworkStylesheets.d.ts.map +1 -0
  93. package/dist/build/frameworkStylesheets.js +49 -0
  94. package/dist/build/getPackageDirForFile.d.ts +2 -0
  95. package/dist/build/getPackageDirForFile.d.ts.map +1 -0
  96. package/dist/build/getPackageDirForFile.js +11 -0
  97. package/dist/build/getSxyClientPackageAliases.d.ts.map +1 -1
  98. package/dist/build/getSxyClientPackageAliases.js +3 -1
  99. package/dist/build/makeBabelUserDevConfig.d.ts +1 -1
  100. package/dist/build/makeBabelUserDevConfig.d.ts.map +1 -1
  101. package/dist/build/makeBabelUserDevConfig.js +3 -2
  102. package/dist/build/makeBabelUserProdConfig.d.ts +1 -1
  103. package/dist/build/makeBabelUserProdConfig.d.ts.map +1 -1
  104. package/dist/build/makeBabelUserProdConfig.js +4 -2
  105. package/dist/build/rollup.user.prod.config.d.ts.map +1 -1
  106. package/dist/build/rollup.user.prod.config.js +4 -1
  107. package/dist/build/rollupExtractComponentStylesheets.d.ts +12 -0
  108. package/dist/build/rollupExtractComponentStylesheets.d.ts.map +1 -0
  109. package/dist/build/rollupExtractComponentStylesheets.js +35 -0
  110. package/dist/compat/context.d.ts +1 -1
  111. package/dist/compat/context.d.ts.map +1 -1
  112. package/dist/compat/types.d.ts +1 -1
  113. package/dist/compat/types.d.ts.map +1 -1
  114. package/dist/componentCss/i/T-components-library-RichTextEditor-RichTextEditor.css +115 -0
  115. package/dist/componentCss/i/T-components-library-__StatefulMessage-StatefulMessage.css +25 -0
  116. package/dist/componentCss/tungsten.css +2 -0
  117. package/dist/componentProxyHandlers.d.ts +2 -1
  118. package/dist/componentProxyHandlers.d.ts.map +1 -1
  119. package/dist/componentProxyHandlers.js +45 -9
  120. package/dist/components/GoToComponent.d.ts +1 -1
  121. package/dist/components/GoToComponent.d.ts.map +1 -1
  122. package/dist/components/PopMessages.d.ts +12 -0
  123. package/dist/components/PopMessages.d.ts.map +1 -0
  124. package/dist/components/PopMessages.js +45 -0
  125. package/dist/components/_GoToComponent.d.ts +10 -0
  126. package/dist/components/_GoToComponent.d.ts.map +1 -0
  127. package/dist/components/_GoToComponent.js +13 -0
  128. package/dist/components/library/RichTextEditor/RichTextEditor.d.ts +50 -0
  129. package/dist/components/library/RichTextEditor/RichTextEditor.d.ts.map +1 -0
  130. package/dist/components/library/RichTextEditor/RichTextEditor.js +458 -0
  131. package/dist/components/library/RichTextEditor/StoredContentNode.d.ts +5 -0
  132. package/dist/components/library/RichTextEditor/StoredContentNode.d.ts.map +1 -0
  133. package/dist/components/library/RichTextEditor/StoredContentNode.js +1 -0
  134. package/dist/components/library/RichTextEditor/activeFormats.d.ts +20 -0
  135. package/dist/components/library/RichTextEditor/activeFormats.d.ts.map +1 -0
  136. package/dist/components/library/RichTextEditor/activeFormats.js +48 -0
  137. package/dist/components/library/RichTextEditor/contentTree.d.ts +30 -0
  138. package/dist/components/library/RichTextEditor/contentTree.d.ts.map +1 -0
  139. package/dist/components/library/RichTextEditor/contentTree.js +81 -0
  140. package/dist/components/library/RichTextEditor/sanitizeAuthoredHtml.d.ts +30 -0
  141. package/dist/components/library/RichTextEditor/sanitizeAuthoredHtml.d.ts.map +1 -0
  142. package/dist/components/library/RichTextEditor/sanitizeAuthoredHtml.js +97 -0
  143. package/dist/components/library/__StatefulMessage/MessageData.d.ts +7 -0
  144. package/dist/components/library/__StatefulMessage/MessageData.d.ts.map +1 -0
  145. package/dist/components/library/__StatefulMessage/MessageData.js +1 -0
  146. package/dist/components/library/__StatefulMessage/StatefulMessage.d.ts +22 -0
  147. package/dist/components/library/__StatefulMessage/StatefulMessage.d.ts.map +1 -0
  148. package/dist/components/library/__StatefulMessage/StatefulMessage.js +88 -0
  149. package/dist/components/library/index.d.ts +5 -0
  150. package/dist/components/library/index.d.ts.map +1 -0
  151. package/dist/components/library/index.js +7 -0
  152. package/dist/defaultConfig.d.ts +2 -0
  153. package/dist/defaultConfig.d.ts.map +1 -1
  154. package/dist/defaultConfig.js +3 -1
  155. package/dist/env/Interfaces.d.ts +2 -1
  156. package/dist/env/Interfaces.d.ts.map +1 -1
  157. package/dist/env/getEnvSchemas.d.ts +1 -1
  158. package/dist/env/getEnvSchemas.d.ts.map +1 -1
  159. package/dist/env/injectEnv.d.ts +1 -1
  160. package/dist/env/injectEnv.d.ts.map +1 -1
  161. package/dist/env/injectEnv.js +16 -6
  162. package/dist/env/publicEnv.d.ts.map +1 -1
  163. package/dist/env/publicEnv.js +4 -1
  164. package/dist/findUserConfig.d.ts +1 -1
  165. package/dist/frameworkConfigSchema.d.ts +4 -0
  166. package/dist/frameworkConfigSchema.d.ts.map +1 -1
  167. package/dist/frameworkConfigSchema.js +2 -1
  168. package/dist/hooks/index.d.ts +1 -0
  169. package/dist/hooks/index.d.ts.map +1 -1
  170. package/dist/hooks/index.js +1 -0
  171. package/dist/hooks/useInstance.d.ts +3 -0
  172. package/dist/hooks/useInstance.d.ts.map +1 -0
  173. package/dist/hooks/useInstance.js +4 -0
  174. package/dist/hydrate/hydrate.d.ts +6 -4
  175. package/dist/hydrate/hydrate.d.ts.map +1 -1
  176. package/dist/hydrate/hydrate.js +51 -13
  177. package/dist/hydrate/reconcileHydratedAttributes.d.ts.map +1 -1
  178. package/dist/hydrate/reconcileHydratedAttributes.js +4 -3
  179. package/dist/hydrate/renderHydrationMismatchBanner.d.ts +7 -0
  180. package/dist/hydrate/renderHydrationMismatchBanner.d.ts.map +1 -0
  181. package/dist/hydrate/renderHydrationMismatchBanner.js +69 -0
  182. package/dist/indexInner.d.ts +13 -5
  183. package/dist/indexInner.d.ts.map +1 -1
  184. package/dist/indexInner.js +9 -2
  185. package/dist/makeInstanceConfigFromFrameworkConfig.d.ts.map +1 -1
  186. package/dist/makeInstanceConfigFromFrameworkConfig.js +2 -1
  187. package/dist/pop.d.ts +10 -0
  188. package/dist/pop.d.ts.map +1 -0
  189. package/dist/pop.js +49 -0
  190. package/dist/postcssPlugins/TransformCssNames.d.ts.map +1 -1
  191. package/dist/postcssPlugins/TransformCssNames.js +10 -2
  192. package/dist/propsAreEqual.d.ts +8 -0
  193. package/dist/propsAreEqual.d.ts.map +1 -0
  194. package/dist/propsAreEqual.js +97 -0
  195. package/dist/rawHtml/filterContentNode.d.ts +20 -0
  196. package/dist/rawHtml/filterContentNode.d.ts.map +1 -0
  197. package/dist/rawHtml/filterContentNode.js +96 -0
  198. package/dist/rawHtml/parseHtml.d.ts +14 -0
  199. package/dist/rawHtml/parseHtml.d.ts.map +1 -1
  200. package/dist/rawHtml/parseHtml.js +4 -4
  201. package/dist/rawHtml/sanitizeHtml.d.ts +17 -0
  202. package/dist/rawHtml/sanitizeHtml.d.ts.map +1 -0
  203. package/dist/rawHtml/sanitizeHtml.js +19 -0
  204. package/dist/render/HeadData.d.ts +2 -0
  205. package/dist/render/HeadData.d.ts.map +1 -1
  206. package/dist/render/contentNodeToHtml.d.ts +18 -0
  207. package/dist/render/contentNodeToHtml.d.ts.map +1 -0
  208. package/dist/render/contentNodeToHtml.js +66 -0
  209. package/dist/render/contentToHtml.d.ts.map +1 -1
  210. package/dist/render/contentToHtml.js +3 -1
  211. package/dist/render/instantiateClassComponent.d.ts.map +1 -1
  212. package/dist/render/instantiateClassComponent.js +4 -0
  213. package/dist/render/processHead.d.ts.map +1 -1
  214. package/dist/render/processHead.js +22 -3
  215. package/dist/render/renderingTreeToHtml.d.ts.map +1 -1
  216. package/dist/render/renderingTreeToHtml.js +8 -1
  217. package/dist/routing/ErrorRouteType.d.ts +6 -0
  218. package/dist/routing/ErrorRouteType.d.ts.map +1 -0
  219. package/dist/routing/ErrorRouteType.js +1 -0
  220. package/dist/routing/RouteTypes.d.ts +2 -1
  221. package/dist/routing/RouteTypes.d.ts.map +1 -1
  222. package/dist/routing/Routes.d.ts +5 -0
  223. package/dist/routing/Routes.d.ts.map +1 -1
  224. package/dist/routing/TungstenErrorInfo.d.ts +6 -0
  225. package/dist/routing/TungstenErrorInfo.d.ts.map +1 -0
  226. package/dist/routing/TungstenErrorInfo.js +6 -0
  227. package/dist/settings.d.ts +2 -0
  228. package/dist/settings.d.ts.map +1 -1
  229. package/dist/settings.js +3 -0
  230. package/dist/stateTracking.d.ts +47 -0
  231. package/dist/stateTracking.d.ts.map +1 -0
  232. package/dist/stateTracking.js +83 -0
  233. package/dist/staticGen/staticGen.d.ts.map +1 -1
  234. package/dist/staticGen/staticGen.js +117 -107
  235. package/dist/style/styleContentSxy.js +21 -0
  236. package/dist/testing/hydrateTestApp.d.ts +38 -0
  237. package/dist/testing/hydrateTestApp.d.ts.map +1 -0
  238. package/dist/testing/hydrateTestApp.js +242 -0
  239. package/dist/testing/index.d.ts +4 -3
  240. package/dist/testing/index.d.ts.map +1 -1
  241. package/dist/testing/index.js +16 -2
  242. package/dist/testing/installTestStyleProcessors.d.ts +2 -0
  243. package/dist/testing/installTestStyleProcessors.d.ts.map +1 -0
  244. package/dist/testing/installTestStyleProcessors.js +21 -0
  245. package/dist/testing/temp/componentPackageMock.d.ts +18 -0
  246. package/dist/testing/temp/componentPackageMock.d.ts.map +1 -0
  247. package/dist/testing/temp/componentPackageMock.js +37 -0
  248. package/dist/testing/temp/contentHtmlElements.d.ts +3 -0
  249. package/dist/testing/temp/contentHtmlElements.d.ts.map +1 -0
  250. package/dist/testing/temp/contentHtmlElements.js +12 -0
  251. package/dist/timeProfiler.d.ts +6 -0
  252. package/dist/timeProfiler.d.ts.map +1 -0
  253. package/dist/timeProfiler.js +31 -0
  254. package/dist/update/integrateUpdateVdom.d.ts +11 -0
  255. package/dist/update/integrateUpdateVdom.d.ts.map +1 -1
  256. package/dist/update/integrateUpdateVdom.js +169 -54
  257. package/dist/update/pendingMounts.d.ts +25 -0
  258. package/dist/update/pendingMounts.d.ts.map +1 -0
  259. package/dist/update/pendingMounts.js +55 -0
  260. package/dist/warnOnFrameworkChange.d.ts.map +1 -1
  261. package/dist/warnOnFrameworkChange.js +8 -8
  262. package/package.json +21 -17
  263. package/dist/FunctionComponentStandIn.sxyt.d.ts +0 -2
  264. package/dist/FunctionComponentStandIn.sxyt.d.ts.map +0 -1
  265. package/dist/FunctionComponentStandIn.sxyt.js +0 -52
  266. package/dist/Instance/gotoRedirect.sxyt.d.ts +0 -2
  267. package/dist/Instance/gotoRedirect.sxyt.d.ts.map +0 -1
  268. package/dist/Instance/gotoRedirect.sxyt.js +0 -148
  269. package/dist/Instance/runTrackedWork.sxyt.d.ts +0 -2
  270. package/dist/Instance/runTrackedWork.sxyt.d.ts.map +0 -1
  271. package/dist/Instance/runTrackedWork.sxyt.js +0 -35
  272. package/dist/Servers/devErrorPageAutoRetry.sxyt.d.ts +0 -2
  273. package/dist/Servers/devErrorPageAutoRetry.sxyt.d.ts.map +0 -1
  274. package/dist/Servers/devErrorPageAutoRetry.sxyt.js +0 -117
  275. package/dist/_client/cjsHelpers.sxyt.d.ts +0 -2
  276. package/dist/_client/cjsHelpers.sxyt.d.ts.map +0 -1
  277. package/dist/_client/cjsHelpers.sxyt.js +0 -45
  278. package/dist/auth/passwordHashing.sxyt.d.ts +0 -2
  279. package/dist/auth/passwordHashing.sxyt.d.ts.map +0 -1
  280. package/dist/auth/passwordHashing.sxyt.js +0 -46
  281. package/dist/auth/ref/checkPasswordResetToken.sxyt.d.ts +0 -2
  282. package/dist/auth/ref/checkPasswordResetToken.sxyt.d.ts.map +0 -1
  283. package/dist/auth/ref/checkPasswordResetToken.sxyt.js +0 -40
  284. package/dist/auth/ref/createPasswordResetToken.sxyt.d.ts +0 -2
  285. package/dist/auth/ref/createPasswordResetToken.sxyt.d.ts.map +0 -1
  286. package/dist/auth/ref/createPasswordResetToken.sxyt.js +0 -10
  287. package/dist/babelPlugins/BabelAddDevCacheBust.sxyt.d.ts +0 -2
  288. package/dist/babelPlugins/BabelAddDevCacheBust.sxyt.d.ts.map +0 -1
  289. package/dist/babelPlugins/BabelAddDevCacheBust.sxyt.js +0 -138
  290. package/dist/babelPlugins/fixImportsInSassErrorMessage.sxyt.d.ts +0 -2
  291. package/dist/babelPlugins/fixImportsInSassErrorMessage.sxyt.d.ts.map +0 -1
  292. package/dist/babelPlugins/fixImportsInSassErrorMessage.sxyt.js +0 -108
  293. package/dist/babelPlugins/transformPackageImports/resolveBareImport.sxyt.d.ts +0 -2
  294. package/dist/babelPlugins/transformPackageImports/resolveBareImport.sxyt.d.ts.map +0 -1
  295. package/dist/babelPlugins/transformPackageImports/resolveBareImport.sxyt.js +0 -104
  296. package/dist/bin/commands/compile.sxyt.d.ts +0 -2
  297. package/dist/bin/commands/compile.sxyt.d.ts.map +0 -1
  298. package/dist/bin/commands/compile.sxyt.js +0 -255
  299. package/dist/build/modifySassImports.sxyt.d.ts +0 -2
  300. package/dist/build/modifySassImports.sxyt.d.ts.map +0 -1
  301. package/dist/build/modifySassImports.sxyt.js +0 -55
  302. package/dist/build/sassImportParser.sxyt.d.ts +0 -2
  303. package/dist/build/sassImportParser.sxyt.d.ts.map +0 -1
  304. package/dist/build/sassImportParser.sxyt.js +0 -110
  305. package/dist/build/scssImportParserChatgpt.sxyt.d.ts +0 -2
  306. package/dist/build/scssImportParserChatgpt.sxyt.d.ts.map +0 -1
  307. package/dist/build/scssImportParserChatgpt.sxyt.js +0 -120
  308. package/dist/clone.sxyt.d.ts +0 -2
  309. package/dist/clone.sxyt.d.ts.map +0 -1
  310. package/dist/clone.sxyt.js +0 -24
  311. package/dist/componentProxyHandlers.sxyt.d.ts +0 -2
  312. package/dist/componentProxyHandlers.sxyt.d.ts.map +0 -1
  313. package/dist/componentProxyHandlers.sxyt.js +0 -130
  314. package/dist/components/RawHtml.sxyt.d.ts +0 -2
  315. package/dist/components/RawHtml.sxyt.d.ts.map +0 -1
  316. package/dist/components/RawHtml.sxyt.js +0 -104
  317. package/dist/components/bindable/BindableSelect.sxyt.d.ts +0 -2
  318. package/dist/components/bindable/BindableSelect.sxyt.d.ts.map +0 -1
  319. package/dist/components/bindable/BindableSelect.sxyt.js +0 -186
  320. package/dist/env/injectEnv.sxyt.d.ts +0 -2
  321. package/dist/env/injectEnv.sxyt.d.ts.map +0 -1
  322. package/dist/env/injectEnv.sxyt.js +0 -20
  323. package/dist/env/parseEnv.d.ts +0 -2
  324. package/dist/env/parseEnv.d.ts.map +0 -1
  325. package/dist/env/parseEnv.js +0 -14
  326. package/dist/env/parseEnv.sxyt.d.ts +0 -2
  327. package/dist/env/parseEnv.sxyt.d.ts.map +0 -1
  328. package/dist/env/parseEnv.sxyt.js +0 -11
  329. package/dist/findProjectDir.sxyt.d.ts +0 -2
  330. package/dist/findProjectDir.sxyt.d.ts.map +0 -1
  331. package/dist/findProjectDir.sxyt.js +0 -82
  332. package/dist/hmr/applyHmrModule.sxyt.d.ts +0 -2
  333. package/dist/hmr/applyHmrModule.sxyt.d.ts.map +0 -1
  334. package/dist/hmr/applyHmrModule.sxyt.js +0 -182
  335. package/dist/hmr/instanceRegistry.sxyt.d.ts +0 -2
  336. package/dist/hmr/instanceRegistry.sxyt.d.ts.map +0 -1
  337. package/dist/hmr/instanceRegistry.sxyt.js +0 -24
  338. package/dist/hmr/refreshStylesheets.sxyt.d.ts +0 -2
  339. package/dist/hmr/refreshStylesheets.sxyt.d.ts.map +0 -1
  340. package/dist/hmr/refreshStylesheets.sxyt.js +0 -46
  341. package/dist/hydrate/hydrate.sxyt.d.ts +0 -2
  342. package/dist/hydrate/hydrate.sxyt.d.ts.map +0 -1
  343. package/dist/hydrate/hydrate.sxyt.js +0 -302
  344. package/dist/hydrate/reconcileHydratedAttributes.sxyt.d.ts +0 -2
  345. package/dist/hydrate/reconcileHydratedAttributes.sxyt.d.ts.map +0 -1
  346. package/dist/hydrate/reconcileHydratedAttributes.sxyt.js +0 -190
  347. package/dist/importDevModuleWithRetry.sxyt.d.ts +0 -2
  348. package/dist/importDevModuleWithRetry.sxyt.d.ts.map +0 -1
  349. package/dist/importDevModuleWithRetry.sxyt.js +0 -104
  350. package/dist/innerHtmlFromProps.sxyt.d.ts +0 -2
  351. package/dist/innerHtmlFromProps.sxyt.d.ts.map +0 -1
  352. package/dist/innerHtmlFromProps.sxyt.js +0 -99
  353. package/dist/postcssPlugins/parseSelectors.sxyt.d.ts +0 -2
  354. package/dist/postcssPlugins/parseSelectors.sxyt.d.ts.map +0 -1
  355. package/dist/postcssPlugins/parseSelectors.sxyt.js +0 -62
  356. package/dist/postcssPlugins/parseSelectorsRich.sxyt.d.ts +0 -2
  357. package/dist/postcssPlugins/parseSelectorsRich.sxyt.d.ts.map +0 -1
  358. package/dist/postcssPlugins/parseSelectorsRich.sxyt.js +0 -155
  359. package/dist/rawHtml/parseHtml.sxyt.d.ts +0 -2
  360. package/dist/rawHtml/parseHtml.sxyt.d.ts.map +0 -1
  361. package/dist/rawHtml/parseHtml.sxyt.js +0 -239
  362. package/dist/render/getFunctionBodyAsString.sxyt.d.ts +0 -2
  363. package/dist/render/getFunctionBodyAsString.sxyt.d.ts.map +0 -1
  364. package/dist/render/getFunctionBodyAsString.sxyt.js +0 -37
  365. package/dist/render/processHead.sxyt.d.ts +0 -2
  366. package/dist/render/processHead.sxyt.d.ts.map +0 -1
  367. package/dist/render/processHead.sxyt.js +0 -93
  368. package/dist/render/processProps.sxyt.d.ts +0 -2
  369. package/dist/render/processProps.sxyt.d.ts.map +0 -1
  370. package/dist/render/processProps.sxyt.js +0 -90
  371. package/dist/routing/compareRequestToRegex.sxyt.d.ts +0 -2
  372. package/dist/routing/compareRequestToRegex.sxyt.d.ts.map +0 -1
  373. package/dist/routing/compareRequestToRegex.sxyt.js +0 -65
  374. package/dist/routing/getPathPriority.sxyt.d.ts +0 -2
  375. package/dist/routing/getPathPriority.sxyt.d.ts.map +0 -1
  376. package/dist/routing/getPathPriority.sxyt.js +0 -24
  377. package/dist/routing/matchPath.sxyt.d.ts +0 -2
  378. package/dist/routing/matchPath.sxyt.d.ts.map +0 -1
  379. package/dist/routing/matchPath.sxyt.js +0 -41
  380. package/dist/routing/patternToRegex.sxyt.d.ts +0 -2
  381. package/dist/routing/patternToRegex.sxyt.d.ts.map +0 -1
  382. package/dist/routing/patternToRegex.sxyt.js +0 -69
  383. package/dist/routing/splitRequest.sxyt.d.ts +0 -2
  384. package/dist/routing/splitRequest.sxyt.d.ts.map +0 -1
  385. package/dist/routing/splitRequest.sxyt.js +0 -47
  386. package/dist/style/jssToCss.sxyt.d.ts +0 -2
  387. package/dist/style/jssToCss.sxyt.d.ts.map +0 -1
  388. package/dist/style/jssToCss.sxyt.js +0 -17
  389. package/dist/testing/createTestApp.sxyt.d.ts +0 -2
  390. package/dist/testing/createTestApp.sxyt.d.ts.map +0 -1
  391. package/dist/testing/createTestApp.sxyt.js +0 -470
  392. package/dist/testing/ensureTestEnvLoaded.sxyt.d.ts +0 -2
  393. package/dist/testing/ensureTestEnvLoaded.sxyt.d.ts.map +0 -1
  394. package/dist/testing/ensureTestEnvLoaded.sxyt.js +0 -20
  395. package/dist/update/hotSwap.sxyt.d.ts +0 -2
  396. package/dist/update/hotSwap.sxyt.d.ts.map +0 -1
  397. package/dist/update/hotSwap.sxyt.js +0 -252
@@ -23,6 +23,58 @@ import { setCurrentComponent } from 'tungsten/hooks/setCurrentComponent.js';
23
23
  import { clearCurrentComponent } from 'tungsten/hooks/clearCurrentComponent.js';
24
24
  import { isDev } from "../isDev.js";
25
25
  import { $original } from "../componentProxyHandlers.js";
26
+ import { booleanAttributeValue } from "../booleanAttributeValue.js";
27
+ import { propsAreEqual } from "../propsAreEqual.js";
28
+ import { markRendered, refreshTracing, renderedAt, trace, tracing } from "../stateTracking.js";
29
+ import { beginMountScope, discardPendingMounts, endMountScope, queueMount } from "./pendingMounts.js";
30
+ /**
31
+ * How many dom nodes each element's rendered content currently occupies, recorded on
32
+ * every real update. When an update is skipped for unchanged props the child's dom is
33
+ * untouched, so the count still holds -- and the dom pointer can be advanced without
34
+ * measuring the region, which would mean scanning parent.childNodes.
35
+ */
36
+ const skippedNodesLength = new WeakMap();
37
+ const reconcileStats = new Map();
38
+ let reconcileDepth = 0;
39
+ function bucket(name) {
40
+ const existing = reconcileStats.get(name);
41
+ if (existing !== undefined) return existing;
42
+ const created = {
43
+ n: 0,
44
+ ms: 0
45
+ };
46
+ reconcileStats.set(name, created);
47
+ return created;
48
+ }
49
+ /** times `work` into `name` when tracing, and is a plain call-through when not */
50
+ async function timed(name, work) {
51
+ if (!tracing()) return work();
52
+ const b = bucket(name);
53
+ const start = performance.now();
54
+ try {
55
+ return await work();
56
+ } finally {
57
+ b.n++;
58
+ b.ms += performance.now() - start;
59
+ }
60
+ }
61
+ function timedSync(name, work) {
62
+ if (!tracing()) return work();
63
+ const b = bucket(name);
64
+ const start = performance.now();
65
+ try {
66
+ return work();
67
+ } finally {
68
+ b.n++;
69
+ b.ms += performance.now() - start;
70
+ }
71
+ }
72
+ function reportReconcileStats(elementName) {
73
+ if (reconcileStats.size === 0) return;
74
+ const parts = [...reconcileStats.entries()].sort(([, a], [, b]) => b.ms - a.ms).map(([name, b]) => `${name} ${b.ms.toFixed(1)}ms/${b.n}`);
75
+ trace('RECONCILE', elementName, parts.join(' '));
76
+ reconcileStats.clear();
77
+ }
26
78
  function debug(...texts) {
27
79
  //console.log(...texts)
28
80
  //console.log(getStackTrace().split('\n')[2])
@@ -32,6 +84,15 @@ const timing = false; // eslint-disable-line no-type-assertion/no-type-assertion
32
84
  export async function integrateElementUpdateVdom(element, newContent) {
33
85
  let startTime = 0;
34
86
  if (timing) startTime = new Date().getMilliseconds();
87
+ // Only the outermost call reports, so nested components roll up into one line per
88
+ // update rather than one per component. Depth is restored from the value captured on
89
+ // entry rather than decremented, so a throw in a nested call cannot leave the counter
90
+ // stuck above zero and silently suppress every later report.
91
+ const reconcileEntryDepth = ++reconcileDepth;
92
+ if (reconcileEntryDepth === 1) refreshTracing();
93
+ // anything created during this update mounts detached and is attached before the
94
+ // outermost integrate returns, so its mount hooks wait until then
95
+ beginMountScope();
35
96
  debug(`integrateElementUpdateVdom`, element);
36
97
  debug(`integrateElementUpdateVdom`, newContent);
37
98
  //console.log('***** integrateElementUpdateVdom', element.constructor.name, '*****')
@@ -96,11 +157,17 @@ export async function integrateElementUpdateVdom(element, newContent) {
96
157
  //console.log('firstElement', element.__domRegion?.firstElement)
97
158
  //console.log('lastElement', element.__domRegion?.lastElement)
98
159
  //console.log('Current Content after update for element', element.constructor.name, 'is', element.__currentContent)
99
- const newPositionOfFirstElement = domRegion.positionOfFirst();
100
- const newPositionOfLastElement = domRegion.positionOfLast();
160
+ // These were just written by updateByIndexes() immediately above, so the region's
161
+ // bounds are already known -- asking positionOfFirst()/positionOfLast() would
162
+ // indexOf them back out of parent.childNodes, an O(n) scan per component update.
163
+ const newPositionOfFirstElement = previousPositionOfFirstElement;
164
+ const newPositionOfLastElement = domPointer.index - 1;
101
165
  const newNodesLength = newPositionOfFirstElement >= 0 ? 1 + newPositionOfLastElement - newPositionOfFirstElement : 0;
102
166
  //console.log('finished updating element. ', element.constructor.name, ' El positions:', newPositionOfFirstElement, newPositionOfLastElement)
103
167
  if (timing) out(`Updated ${element.constructor.name} in ${new Date().getMilliseconds() - startTime}ms`);
168
+ reconcileDepth = reconcileEntryDepth - 1;
169
+ if (reconcileDepth === 0 && tracing()) reportReconcileStats(element.constructor.name);
170
+ endMountScope();
104
171
  // newNodesLength previousNodesLength
105
172
  return {
106
173
  renderedContent: renderedTree,
@@ -118,7 +185,9 @@ function getKeyedOldChildren(array) {
118
185
  }
119
186
  return keyedChildren;
120
187
  }
121
- async function applyUpdate({
188
+ // oldNode: $contentNull reconciles as a pure create (falls through to createNode()) - used by
189
+ // hydrate.tsx's CSR branch for <body>.
190
+ export async function applyUpdate({
122
191
  tungstenElement,
123
192
  instance,
124
193
  newNode,
@@ -146,7 +215,7 @@ async function applyUpdate({
146
215
  //oldNode
147
216
  //console.log('array update', newNode)
148
217
  //console.log('old array', oldNode)
149
- const keyedOldChildren = getKeyedOldChildren(oldNode);
218
+ const keyedOldChildren = timedSync('indexOldKeys', () => getKeyedOldChildren(oldNode));
150
219
  const tempOldChildren = [...oldNode];
151
220
  if (Object.keys(keyedOldChildren).length > 0) {
152
221
  //console.log('handling a keyed array')
@@ -195,7 +264,7 @@ async function applyUpdate({
195
264
  // create a throwaway DomPointer because we are going to manage our DomPointer differently
196
265
  const tempDomPointer = new DomPointer(domPointer.parent, domPointer.index);
197
266
  // update
198
- renderedContent = await applyUpdate({
267
+ const updated = await timed('keyedUpdate', () => applyUpdate({
199
268
  tungstenElement,
200
269
  instance,
201
270
  newNode: childNode,
@@ -203,10 +272,11 @@ async function applyUpdate({
203
272
  domRegion,
204
273
  domPointer: tempDomPointer,
205
274
  parentNode
206
- });
275
+ }));
276
+ renderedContent = updated;
207
277
  // move
208
278
  //console.log('moving the keyed item', childNode[$key])
209
- moveRenderedContent(renderedContent, domPointer);
279
+ timedSync('keyedMove', () => moveRenderedContent(updated, domPointer));
210
280
  // delete oldChild from temp list
211
281
  delete tempOldChildren[oldChildIndex];
212
282
  } else {
@@ -218,7 +288,7 @@ async function applyUpdate({
218
288
  //console.log('update/replace a non keyed item', _nki)
219
289
  //throwError('b', 'b')
220
290
  // update/replace as required
221
- renderedContent = await applyUpdate({
291
+ const updated = await timed('unkeyedUpdate', () => applyUpdate({
222
292
  tungstenElement,
223
293
  instance,
224
294
  newNode: childNode,
@@ -226,11 +296,12 @@ async function applyUpdate({
226
296
  domRegion,
227
297
  domPointer: tempDomPointer,
228
298
  parentNode
229
- });
299
+ }));
300
+ renderedContent = updated;
230
301
  // move -- we need to move it, because we may have removed or inserted elements
231
302
  // pushing the original out of place
232
303
  //console.log('moving the non keyed item', _nki)
233
- moveRenderedContent(renderedContent, domPointer);
304
+ timedSync('unkeyedMove', () => moveRenderedContent(updated, domPointer));
234
305
  // remove replaced node from list
235
306
  delete tempOldChildren[i];
236
307
  } else {
@@ -238,13 +309,13 @@ async function applyUpdate({
238
309
  //console.log('dp', domPointer)
239
310
  //throwError('c', 'c')
240
311
  // create
241
- renderedContent = await createNode({
312
+ renderedContent = await timed('create', () => createNode({
242
313
  tungstenElement,
243
314
  instance,
244
315
  newNode: childNode,
245
316
  domPointer,
246
317
  parentNode
247
- });
318
+ }));
248
319
  }
249
320
  }
250
321
  renderedNodes.push(renderedContent);
@@ -255,7 +326,7 @@ async function applyUpdate({
255
326
  for (const oldChild of tempOldChildren) {
256
327
  if (oldChild) {
257
328
  //console.log('deleting old child', oldChild)
258
- deleteNodeIfRendered(oldChild);
329
+ timedSync('trim', () => deleteNodeIfRendered(oldChild));
259
330
  }
260
331
  }
261
332
  return renderedNodes;
@@ -487,17 +558,26 @@ function moveRenderedContent(renderedContent, domPointer) {
487
558
  }
488
559
  function moveDomNode(domNode, domPointer) {
489
560
  //console.log('moving domNode', domNode)
490
- if (domPointer.positionOf(domNode) !== domPointer.index) {
561
+ // O(1) position check. positionOf() is Array.indexOf over parent.childNodes, which
562
+ // is O(n) in the sibling count -- and this runs once per node per update, making a
563
+ // keyed array update O(n^2): 20k rows cost ~400M comparisons even when nothing moved.
564
+ // Reading the node already at `index` answers the same question, and differs from
565
+ // domNode in exactly the cases indexOf(domNode) !== index did: the node is elsewhere,
566
+ // is not a child at all (indexOf -1), or index is past the end (undefined).
567
+ // one live-NodeList read, reused as the insertBefore reference below -- see
568
+ // DomPointer.insert() for why these reads are worth counting
569
+ const reference = domPointer.parent.childNodes[domPointer.index]; // eslint-disable-line no-type-assertion/no-type-assertion -- indexing past the end gives undefined, which the DOM types do not model
570
+ if (reference !== domNode) {
491
571
  //console.log('document.activeElement', document.activeElement, domNode == document.activeElement, domNode === document.activeElement)
492
572
  const ownerDocument = domNode.ownerDocument;
493
573
  const hasFocus = domNode === ownerDocument.activeElement;
494
574
  const activeElement = ownerDocument.activeElement;
495
- if (domPointer.index >= domPointer.parent.childNodes.length) {
575
+ if (reference === undefined) {
496
576
  //console.log('appending', domNode)
497
577
  domPointer.parent.appendChild(domNode);
498
578
  } else {
499
579
  //console.log('inserting at', domPointer.index, domNode)
500
- domPointer.parent.insertBefore(domNode, domPointer.parent.childNodes[domPointer.index]);
580
+ domPointer.parent.insertBefore(domNode, reference);
501
581
  }
502
582
  //console.log('had focus', hasFocus)
503
583
  if (hasFocus) domNode.focus();
@@ -595,12 +675,7 @@ function createComment({
595
675
  debug('-createComment');
596
676
  //console.log('createComment', text)
597
677
  const comment = documentFromParent(domPointer.parent).createComment(text);
598
- if (domPointer.index >= domPointer.parent.childNodes.length) {
599
- domPointer.parent.appendChild(comment);
600
- } else {
601
- domPointer.parent.insertBefore(comment, domPointer.parent.childNodes[domPointer.index]);
602
- }
603
- domPointer.increment();
678
+ domPointer.insert(comment);
604
679
  return comment;
605
680
  }
606
681
  export function processHtmlNode(node, parentNode) {
@@ -741,15 +816,10 @@ function createLiteral(value, domPointer) {
741
816
  debug('-createLiteral:', value);
742
817
  //const textNode = createTextElement(String(value), domPointer)
743
818
  const text = String(value);
744
- debug('dom parent', domPointer.parent);
745
- debug('dom index', domPointer.index);
819
+ if (isDev) debug('dom parent', domPointer.parent);
820
+ if (isDev) debug('dom index', domPointer.index);
746
821
  const textNode = documentFromParent(domPointer.parent).createTextNode(text);
747
- if (domPointer.parent.childNodes.length === domPointer.index) {
748
- domPointer.parent.appendChild(textNode);
749
- } else {
750
- domPointer.parent.insertBefore(textNode, domPointer.parent.childNodes[domPointer.index]);
751
- }
752
- domPointer.increment();
822
+ domPointer.insert(textNode);
753
823
  //domPointer.increment()
754
824
  return typeof value === 'string' ? {
755
825
  [$type]: $string,
@@ -769,7 +839,8 @@ async function createHtmlElement(tungstenElement, instance, node, domPointer, pa
769
839
  processHtmlNode(node, parentNode);
770
840
  debug('-createHtmlElement', node);
771
841
  const htmlEl = documentFromParent(domPointer.parent).createElement(node[$type]);
772
- addAttributes(tungstenElement, instance, node, htmlEl);
842
+ const extendableEl = htmlEl; // eslint-disable-line no-type-assertion/no-type-assertion -- attributes are attached to the element later
843
+ addAttributes(tungstenElement, instance, node, extendableEl);
773
844
  if (node[$type] === 'head') {
774
845
  for (const el of instance.persistentHeadChildren) {
775
846
  htmlEl.appendChild(el.cloneNode(true));
@@ -780,21 +851,19 @@ async function createHtmlElement(tungstenElement, instance, node, domPointer, pa
780
851
  if ('ref' in node[$props]) {
781
852
  node[$props].ref.current = htmlEl;
782
853
  }
783
- debug('dom parent', domPointer.parent);
784
- debug('dom parent children length', domPointer.parent.childNodes.length);
785
- debug('domPointer.index', domPointer.index);
786
- if (domPointer.index >= domPointer.parent.childNodes.length) {
787
- domPointer.parent.appendChild(htmlEl);
788
- } else {
789
- debug('new html el', htmlEl);
790
- debug('insert before', domPointer.parent.childNodes[domPointer.index]);
791
- domPointer.parent.insertBefore(htmlEl, domPointer.parent.childNodes[domPointer.index]);
792
- debug('created el', domPointer.get());
793
- }
794
- domPointer.increment();
854
+ // debug() has a commented-out body, but its arguments are still evaluated -- and these
855
+ // ones read the live NodeList, which walks the child list. Behind `if (isDev)` they
856
+ // short-circuit in dev and are removed from the production bundle entirely.
857
+ if (isDev) debug('dom parent', domPointer.parent);
858
+ if (isDev) debug('dom parent children length', domPointer.parent.childNodes.length);
859
+ if (isDev) debug('domPointer.index', domPointer.index);
860
+ if (isDev) debug('new html el', htmlEl);
795
861
  //!!!! node.domElement = el
796
862
  if (IsHTMLElement(domPointer.parent)) debug('***', node[$type], 'html created', htmlEl);
797
- // children
863
+ // children -- built while htmlEl is still detached, then the finished subtree is
864
+ // inserted once below. Appending into an element that is already in the document
865
+ // makes the browser invalidate style and layout on every child; off document it
866
+ // does none of that until the subtree lands.
798
867
  const innerHtml = innerHtmlFromProps(node[$type], node[$props], validChildren(node[$props].children));
799
868
  let renderedChildren;
800
869
  if (innerHtml !== null) {
@@ -816,6 +885,8 @@ async function createHtmlElement(tungstenElement, instance, node, domPointer, pa
816
885
  htmlEl.value = String(node[$props].value);
817
886
  }
818
887
  }
888
+ // the subtree is complete, so attach it in one operation
889
+ domPointer.insert(htmlEl);
819
890
  return {
820
891
  ...node,
821
892
  domNode: htmlEl,
@@ -849,7 +920,8 @@ function addAttributes(tungstenElement, instance, node, domNode) {
849
920
  //console.log('add attr', key, attributes[key])
850
921
  if (typeof attributes[key] === 'boolean') {
851
922
  //console.log('bool attr', attributes[key])
852
- if (attributes[key]) domNode.setAttribute(key, '');
923
+ const attrValue = booleanAttributeValue(key, attributes[key]);
924
+ if (attrValue !== null) domNode.setAttribute(key, attrValue);
853
925
  } else if (attributes[key] !== undefined && attributes[key] !== null) {
854
926
  //console.log('string attr', String(attributes[key]))
855
927
  domNode.setAttribute(key, String(attributes[key]));
@@ -913,7 +985,8 @@ function updateAttributes(tungstenElement, instance, node, oldNode, domNodeHTMLE
913
985
  domNode.value = String(newAttributes[key]);
914
986
  } else {
915
987
  if (typeof newAttributes[key] === 'boolean') {
916
- if (newAttributes[key]) domNode.setAttribute(key, '');else removeAttribute(domNode, key);
988
+ const attrValue = booleanAttributeValue(key, newAttributes[key]);
989
+ if (attrValue !== null) domNode.setAttribute(key, attrValue);else removeAttribute(domNode, key);
917
990
  } else if (newAttributes[key] === undefined || newAttributes[key] === null) {
918
991
  removeAttribute(domNode, key);
919
992
  } else {
@@ -1004,6 +1077,7 @@ function processAttributes(node) {
1004
1077
  } else {
1005
1078
  attributes.style = attributes.css;
1006
1079
  }
1080
+ delete attributes.css;
1007
1081
  }
1008
1082
  return attributes;
1009
1083
  }
@@ -1033,6 +1107,7 @@ export async function createTungstenRootComponent(RootComponent, props, routePar
1033
1107
  instance,
1034
1108
  parentElement: null
1035
1109
  });
1110
+ beginMountScope();
1036
1111
  try {
1037
1112
  await component.__init();
1038
1113
  const content = await component.__initialContent();
@@ -1054,13 +1129,16 @@ export async function createTungstenRootComponent(RootComponent, props, routePar
1054
1129
  });
1055
1130
  component.__domRegion = new DomRegion(container, domStartIndex, domPointer.index - domStartIndex);
1056
1131
  component.__currentContent = renderedContent;
1057
- component.__didMount();
1132
+ queueMount(() => component.__didMount());
1133
+ // everything this root created is attached by now, so the queued hooks can run
1134
+ endMountScope();
1058
1135
  return {
1059
1136
  component,
1060
1137
  openingComment,
1061
1138
  closingComment
1062
1139
  };
1063
1140
  } catch (error) {
1141
+ discardPendingMounts();
1064
1142
  component.__delete();
1065
1143
  while (container.childNodes.length > domStartIndex) {
1066
1144
  container.removeChild(container.childNodes[domStartIndex]);
@@ -1135,7 +1213,7 @@ async function createTungstenClassComponent(parent, instance, node, domPointer)
1135
1213
  debug(`[${c}]`, '&& dom region last element', element.__domRegion.lastElement);
1136
1214
  //console.log('created dom region', element.__domRegion)
1137
1215
  element.__currentContent = renderedContent;
1138
- element.__didMount();
1216
+ queueMount(() => element.__didMount());
1139
1217
  const wrapper = {
1140
1218
  ...node,
1141
1219
  element,
@@ -1179,11 +1257,14 @@ async function createTungstenFunctionComponent(parent, instance, node, domPointe
1179
1257
  });
1180
1258
  //const renderedContent: RenderedContentNode = await integrateNode({ node: content, domRegion: null, domPointer, parent: element, instance })
1181
1259
  const domLength = domPointer.index - domStartIndex;
1182
- debug(`[${x}]`, '&& Continuing create FC', node);
1183
- debug(`[${x}]`, '&& domPointer.parent', domPointer.parent);
1184
- debug(`[${x}]`, '&& dom start index', domStartIndex);
1185
- debug(`[${x}]`, '&& dom length', domLength);
1186
- debug(`[${x}]`, '&& dom pointer children', domPointer.parent.childNodes);
1260
+ if (isDev) {
1261
+ // these run once per created component, and each allocates a template literal
1262
+ debug(`[${x}]`, '&& Continuing create FC', node);
1263
+ debug(`[${x}]`, '&& domPointer.parent', domPointer.parent);
1264
+ debug(`[${x}]`, '&& dom start index', domStartIndex);
1265
+ debug(`[${x}]`, '&& dom length', domLength);
1266
+ debug(`[${x}]`, '&& dom pointer children', domPointer.parent.childNodes);
1267
+ }
1187
1268
  //console.log('new dom region when creating func comp', node[$type].name, domPointer.parent)
1188
1269
  element.__domRegion = new DomRegion(domPointer.parent, domStartIndex, domLength);
1189
1270
  //console.log('&& dom region first element', element.__domRegion.firstElement)
@@ -1205,6 +1286,27 @@ async function updateClassComponent({
1205
1286
  }) {
1206
1287
  //console.log('-updateClassComponent', newNode)
1207
1288
  const element = oldNode.element;
1289
+ // element.props still holds what was last rendered, so this asks "has anything
1290
+ // changed since we last rendered?". If not, the child's dom is already correct and
1291
+ // re-rendering it is wasted work -- which for a large list child means reconciling
1292
+ // every row so an unrelated sibling can update. componentDidUpdate deliberately does
1293
+ // not fire: the component did not update.
1294
+ if (propsAreEqual(element.props, newNode[$props], renderedAt(element))) {
1295
+ if (tracing()) trace('SKIP', element.constructor.name, '(props unchanged since tick', renderedAt(element), ')');
1296
+ // the dom is current for these props, so the baseline moves with it -- otherwise a
1297
+ // component that only ever skips keeps comparing against its mount tick, and the
1298
+ // first shared object it is handed always looks changed
1299
+ markRendered(element);
1300
+ // the weakmap is only written by a previous update, so on the first update after
1301
+ // mount fall back to measuring the element's own region -- its index caches were
1302
+ // seeded when it was created, so this is not a scan either
1303
+ const cachedLength = skippedNodesLength.get(element) ?? element.__domRegion?.length();
1304
+ if (cachedLength !== undefined) {
1305
+ domPointer.increment(cachedLength);
1306
+ return oldNode;
1307
+ }
1308
+ }
1309
+ if (tracing()) trace('RENDER', element.constructor.name, '(since tick', renderedAt(element), ')');
1208
1310
  element.props = newNode[$props];
1209
1311
  debug('update class component', newNode);
1210
1312
  //console.log('update class component', newNode)
@@ -1213,6 +1315,8 @@ async function updateClassComponent({
1213
1315
  //console.log('domPointer children', [...domPointer.parent.childNodes])
1214
1316
  //throwError('','')
1215
1317
  const updateResult = await element.__update();
1318
+ markRendered(element);
1319
+ skippedNodesLength.set(element, updateResult.nodesLength);
1216
1320
  domPointer.increment(updateResult.nodesLength); // bump the dom pointer index forward by the number of nodes within that element's content
1217
1321
  const wrapper = {
1218
1322
  ...newNode,
@@ -1231,8 +1335,19 @@ async function updateFunctionComponent({
1231
1335
  // this func does not seem to be updating the dom pointer index
1232
1336
  //console.log('updateFunctionComponent')
1233
1337
  const standIn = oldNode.element;
1338
+ // see updateClassComponent: unchanged props mean the rendered dom is already correct
1339
+ if (propsAreEqual(standIn.props, newNode[$props], renderedAt(standIn))) {
1340
+ markRendered(standIn); // see updateClassComponent
1341
+ const cachedLength = skippedNodesLength.get(standIn) ?? standIn.__domRegion?.length();
1342
+ if (cachedLength !== undefined) {
1343
+ domPointer.increment(cachedLength);
1344
+ return oldNode;
1345
+ }
1346
+ }
1234
1347
  standIn.props = newNode[$props];
1235
1348
  const updateResult = await standIn.update();
1349
+ markRendered(standIn);
1350
+ skippedNodesLength.set(standIn, updateResult.nodesLength);
1236
1351
  domPointer.increment(updateResult.nodesLength); // bump the dom pointer index forward by the number of nodes within that element's content
1237
1352
  const wrapper = {
1238
1353
  ...newNode,
@@ -1331,7 +1446,7 @@ export async function hotSwapClassComponent(oldElement, NewType) {
1331
1446
  });
1332
1447
  newElement.__domRegion = new DomRegion(parent, domStartIndex, domPointer.index - domStartIndex);
1333
1448
  newElement.__currentContent = renderedContent;
1334
- newElement.__didMount();
1449
+ queueMount(() => newElement.__didMount());
1335
1450
  wrapper.element = newElement;
1336
1451
  wrapper[$props] = newElement.props;
1337
1452
  newElement.__renderedNode = wrapper;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Defers mount hooks until the dom they belong to is in the document.
3
+ *
4
+ * Elements are assembled off document and inserted once their subtree is complete, which
5
+ * is what React, Vue and Svelte all do -- appending into an already-attached element makes
6
+ * the browser invalidate style and layout on every child. The cost is that a component
7
+ * created part way through that build would see a detached node in componentDidMount, where
8
+ * getBoundingClientRect returns zeros and .focus() does nothing, failing silently rather
9
+ * than throwing.
10
+ *
11
+ * So creation opens a scope, mount hooks queue inside it, and the scope's owner flushes
12
+ * them once everything it created has been attached. Hooks are queued as their components
13
+ * finish creating -- children before parents -- and the queue drains in that order, so a
14
+ * parent's hook can still rely on its children having mounted.
15
+ */
16
+ export declare function beginMountScope(): void;
17
+ /**
18
+ * Runs `hook` when the current scope closes, or immediately if there is no scope -- the
19
+ * dom is already attached in that case, so there is nothing to wait for.
20
+ */
21
+ export declare function queueMount(hook: () => void): void;
22
+ export declare function endMountScope(): void;
23
+ /** drops anything still queued -- used when a create pass fails and unwinds */
24
+ export declare function discardPendingMounts(): void;
25
+ //# sourceMappingURL=pendingMounts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pendingMounts.d.ts","sourceRoot":"","sources":["../../src/update/pendingMounts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI,CAMjD;AAED,wBAAgB,aAAa,IAAI,IAAI,CAgBpC;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,IAAI,IAAI,CAI3C"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Defers mount hooks until the dom they belong to is in the document.
3
+ *
4
+ * Elements are assembled off document and inserted once their subtree is complete, which
5
+ * is what React, Vue and Svelte all do -- appending into an already-attached element makes
6
+ * the browser invalidate style and layout on every child. The cost is that a component
7
+ * created part way through that build would see a detached node in componentDidMount, where
8
+ * getBoundingClientRect returns zeros and .focus() does nothing, failing silently rather
9
+ * than throwing.
10
+ *
11
+ * So creation opens a scope, mount hooks queue inside it, and the scope's owner flushes
12
+ * them once everything it created has been attached. Hooks are queued as their components
13
+ * finish creating -- children before parents -- and the queue drains in that order, so a
14
+ * parent's hook can still rely on its children having mounted.
15
+ */
16
+ const pending = [];
17
+ let depth = 0;
18
+ let flushing = false;
19
+ export function beginMountScope() {
20
+ depth++;
21
+ }
22
+ /**
23
+ * Runs `hook` when the current scope closes, or immediately if there is no scope -- the
24
+ * dom is already attached in that case, so there is nothing to wait for.
25
+ */
26
+ export function queueMount(hook) {
27
+ if (depth === 0) {
28
+ hook();
29
+ return;
30
+ }
31
+ pending.push(hook);
32
+ }
33
+ export function endMountScope() {
34
+ if (depth > 0) depth--;
35
+ if (depth > 0) return;
36
+ // A hook may create more components, which opens and closes further scopes. Draining
37
+ // from the front means anything they queue joins the end of this same pass rather than
38
+ // starting a nested one.
39
+ if (flushing) return;
40
+ flushing = true;
41
+ try {
42
+ while (pending.length > 0) {
43
+ const hook = pending.shift();
44
+ if (hook !== undefined) hook();
45
+ }
46
+ } finally {
47
+ flushing = false;
48
+ }
49
+ }
50
+ /** drops anything still queued -- used when a create pass fails and unwinds */
51
+ export function discardPendingMounts() {
52
+ pending.length = 0;
53
+ depth = 0;
54
+ flushing = false;
55
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"warnOnFrameworkChange.d.ts","sourceRoot":"","sources":["../src/warnOnFrameworkChange.ts"],"names":[],"mappings":"AASA,wBAAgB,qBAAqB,IAAI,IAAI,CAmB5C"}
1
+ {"version":3,"file":"warnOnFrameworkChange.d.ts","sourceRoot":"","sources":["../src/warnOnFrameworkChange.ts"],"names":[],"mappings":"AAcA,wBAAgB,qBAAqB,IAAI,IAAI,CAc5C"}
@@ -6,11 +6,15 @@ import { cliWarn } from "./cliOutput.js";
6
6
  // cache can't be invalidated at runtime, so an already-running dev server can't pick up a
7
7
  // change to the tungsten package itself (e.g. a linked/workspace copy being rebuilt) without a
8
8
  // full process restart - this just tells the developer that's needed, rather than attempting it.
9
+ //
10
+ // Watches a single marker file (dist/.build-complete) rather than all of dist - tungsten's own
11
+ // build scripts touch it as their last step (see scripts/writeBuildMarker.mjs), so one file
12
+ // covers every file a build could have changed without chokidar scanning the whole tree. Watch
13
+ // mode (build-babel --watch) does not yet write it on each cycle, only the one-shot builds do.
9
14
  export function warnOnFrameworkChange() {
10
15
  const frameworkDistDir = join(getFrameworkDir(), 'dist');
11
- // debounced so one rebuild (many files touched at once) produces one warning, not one per file
12
- let debounceTimer = null;
13
- const watcher = chokidar.watch(frameworkDistDir, {
16
+ const buildMarkerPath = join(frameworkDistDir, '.build-complete');
17
+ const watcher = chokidar.watch(buildMarkerPath, {
14
18
  ignoreInitial: true,
15
19
  awaitWriteFinish: {
16
20
  stabilityThreshold: 200,
@@ -18,10 +22,6 @@ export function warnOnFrameworkChange() {
18
22
  }
19
23
  });
20
24
  watcher.on('all', () => {
21
- if (debounceTimer !== null) clearTimeout(debounceTimer);
22
- debounceTimer = setTimeout(() => {
23
- debounceTimer = null;
24
- cliWarn(`tungsten framework files changed (${frameworkDistDir}) - restart the dev server` + ` to pick up the change.`);
25
- }, 300);
25
+ cliWarn(`tungsten framework files changed (${frameworkDistDir}) - restart the dev server` + ` to pick up the change.`);
26
26
  });
27
27
  }