@depup/svelte 5.53.3-depup.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 (386) hide show
  1. package/LICENSE.md +7 -0
  2. package/README.md +41 -0
  3. package/action.d.ts +1 -0
  4. package/animate.d.ts +1 -0
  5. package/compiler/index.js +1 -0
  6. package/compiler/package.json +3 -0
  7. package/compiler.d.ts +1 -0
  8. package/easing.d.ts +1 -0
  9. package/elements.d.ts +2078 -0
  10. package/index.d.ts +1 -0
  11. package/legacy.d.ts +1 -0
  12. package/motion.d.ts +1 -0
  13. package/package.json +185 -0
  14. package/src/animate/index.js +78 -0
  15. package/src/attachments/index.js +113 -0
  16. package/src/compiler/errors.js +1719 -0
  17. package/src/compiler/index.js +198 -0
  18. package/src/compiler/legacy.js +637 -0
  19. package/src/compiler/migrate/index.js +1996 -0
  20. package/src/compiler/phases/1-parse/acorn.js +198 -0
  21. package/src/compiler/phases/1-parse/index.js +326 -0
  22. package/src/compiler/phases/1-parse/read/context.js +116 -0
  23. package/src/compiler/phases/1-parse/read/expression.js +93 -0
  24. package/src/compiler/phases/1-parse/read/options.js +263 -0
  25. package/src/compiler/phases/1-parse/read/script.js +97 -0
  26. package/src/compiler/phases/1-parse/read/style.js +637 -0
  27. package/src/compiler/phases/1-parse/remove_typescript_nodes.js +180 -0
  28. package/src/compiler/phases/1-parse/state/element.js +937 -0
  29. package/src/compiler/phases/1-parse/state/fragment.js +17 -0
  30. package/src/compiler/phases/1-parse/state/tag.js +751 -0
  31. package/src/compiler/phases/1-parse/state/text.js +23 -0
  32. package/src/compiler/phases/1-parse/utils/bracket.js +213 -0
  33. package/src/compiler/phases/1-parse/utils/create.js +16 -0
  34. package/src/compiler/phases/1-parse/utils/entities.js +2234 -0
  35. package/src/compiler/phases/1-parse/utils/fuzzymatch.js +281 -0
  36. package/src/compiler/phases/1-parse/utils/html.js +127 -0
  37. package/src/compiler/phases/2-analyze/css/css-analyze.js +331 -0
  38. package/src/compiler/phases/2-analyze/css/css-prune.js +1206 -0
  39. package/src/compiler/phases/2-analyze/css/css-warn.js +47 -0
  40. package/src/compiler/phases/2-analyze/css/utils.js +177 -0
  41. package/src/compiler/phases/2-analyze/index.js +1300 -0
  42. package/src/compiler/phases/2-analyze/utils/check_graph_for_cycles.js +47 -0
  43. package/src/compiler/phases/2-analyze/visitors/AnimateDirective.js +15 -0
  44. package/src/compiler/phases/2-analyze/visitors/ArrowFunctionExpression.js +11 -0
  45. package/src/compiler/phases/2-analyze/visitors/AssignmentExpression.js +31 -0
  46. package/src/compiler/phases/2-analyze/visitors/AttachTag.js +17 -0
  47. package/src/compiler/phases/2-analyze/visitors/Attribute.js +66 -0
  48. package/src/compiler/phases/2-analyze/visitors/AwaitBlock.js +48 -0
  49. package/src/compiler/phases/2-analyze/visitors/AwaitExpression.js +150 -0
  50. package/src/compiler/phases/2-analyze/visitors/BindDirective.js +280 -0
  51. package/src/compiler/phases/2-analyze/visitors/CallExpression.js +339 -0
  52. package/src/compiler/phases/2-analyze/visitors/ClassBody.js +156 -0
  53. package/src/compiler/phases/2-analyze/visitors/ClassDeclaration.js +25 -0
  54. package/src/compiler/phases/2-analyze/visitors/ClassDirective.js +13 -0
  55. package/src/compiler/phases/2-analyze/visitors/Component.js +26 -0
  56. package/src/compiler/phases/2-analyze/visitors/ConstTag.js +45 -0
  57. package/src/compiler/phases/2-analyze/visitors/DebugTag.js +15 -0
  58. package/src/compiler/phases/2-analyze/visitors/EachBlock.js +97 -0
  59. package/src/compiler/phases/2-analyze/visitors/ExportDefaultDeclaration.js +20 -0
  60. package/src/compiler/phases/2-analyze/visitors/ExportNamedDeclaration.js +70 -0
  61. package/src/compiler/phases/2-analyze/visitors/ExportSpecifier.js +30 -0
  62. package/src/compiler/phases/2-analyze/visitors/ExpressionStatement.js +38 -0
  63. package/src/compiler/phases/2-analyze/visitors/ExpressionTag.js +26 -0
  64. package/src/compiler/phases/2-analyze/visitors/Fragment.js +10 -0
  65. package/src/compiler/phases/2-analyze/visitors/FunctionDeclaration.js +16 -0
  66. package/src/compiler/phases/2-analyze/visitors/FunctionExpression.js +11 -0
  67. package/src/compiler/phases/2-analyze/visitors/HtmlTag.js +19 -0
  68. package/src/compiler/phases/2-analyze/visitors/Identifier.js +194 -0
  69. package/src/compiler/phases/2-analyze/visitors/IfBlock.js +46 -0
  70. package/src/compiler/phases/2-analyze/visitors/ImportDeclaration.js +31 -0
  71. package/src/compiler/phases/2-analyze/visitors/KeyBlock.js +21 -0
  72. package/src/compiler/phases/2-analyze/visitors/LabeledStatement.js +95 -0
  73. package/src/compiler/phases/2-analyze/visitors/LetDirective.js +24 -0
  74. package/src/compiler/phases/2-analyze/visitors/Literal.js +14 -0
  75. package/src/compiler/phases/2-analyze/visitors/MemberExpression.js +28 -0
  76. package/src/compiler/phases/2-analyze/visitors/NewExpression.js +17 -0
  77. package/src/compiler/phases/2-analyze/visitors/OnDirective.js +28 -0
  78. package/src/compiler/phases/2-analyze/visitors/PropertyDefinition.js +21 -0
  79. package/src/compiler/phases/2-analyze/visitors/RegularElement.js +240 -0
  80. package/src/compiler/phases/2-analyze/visitors/RenderTag.js +68 -0
  81. package/src/compiler/phases/2-analyze/visitors/SlotElement.js +42 -0
  82. package/src/compiler/phases/2-analyze/visitors/SnippetBlock.js +113 -0
  83. package/src/compiler/phases/2-analyze/visitors/SpreadAttribute.js +13 -0
  84. package/src/compiler/phases/2-analyze/visitors/SpreadElement.js +16 -0
  85. package/src/compiler/phases/2-analyze/visitors/StyleDirective.js +39 -0
  86. package/src/compiler/phases/2-analyze/visitors/SvelteBody.js +22 -0
  87. package/src/compiler/phases/2-analyze/visitors/SvelteBoundary.js +30 -0
  88. package/src/compiler/phases/2-analyze/visitors/SvelteComponent.js +18 -0
  89. package/src/compiler/phases/2-analyze/visitors/SvelteDocument.js +24 -0
  90. package/src/compiler/phases/2-analyze/visitors/SvelteElement.js +78 -0
  91. package/src/compiler/phases/2-analyze/visitors/SvelteFragment.js +27 -0
  92. package/src/compiler/phases/2-analyze/visitors/SvelteHead.js +18 -0
  93. package/src/compiler/phases/2-analyze/visitors/SvelteSelf.js +36 -0
  94. package/src/compiler/phases/2-analyze/visitors/SvelteWindow.js +24 -0
  95. package/src/compiler/phases/2-analyze/visitors/TaggedTemplateExpression.js +16 -0
  96. package/src/compiler/phases/2-analyze/visitors/TemplateElement.js +12 -0
  97. package/src/compiler/phases/2-analyze/visitors/Text.js +52 -0
  98. package/src/compiler/phases/2-analyze/visitors/TitleElement.js +21 -0
  99. package/src/compiler/phases/2-analyze/visitors/TransitionDirective.js +19 -0
  100. package/src/compiler/phases/2-analyze/visitors/UpdateExpression.js +29 -0
  101. package/src/compiler/phases/2-analyze/visitors/UseDirective.js +18 -0
  102. package/src/compiler/phases/2-analyze/visitors/VariableDeclarator.js +160 -0
  103. package/src/compiler/phases/2-analyze/visitors/shared/a11y/constants.js +334 -0
  104. package/src/compiler/phases/2-analyze/visitors/shared/a11y/index.js +981 -0
  105. package/src/compiler/phases/2-analyze/visitors/shared/attribute.js +125 -0
  106. package/src/compiler/phases/2-analyze/visitors/shared/component.js +177 -0
  107. package/src/compiler/phases/2-analyze/visitors/shared/element.js +160 -0
  108. package/src/compiler/phases/2-analyze/visitors/shared/fragment.js +15 -0
  109. package/src/compiler/phases/2-analyze/visitors/shared/function.js +24 -0
  110. package/src/compiler/phases/2-analyze/visitors/shared/snippets.js +17 -0
  111. package/src/compiler/phases/2-analyze/visitors/shared/special-element.js +16 -0
  112. package/src/compiler/phases/2-analyze/visitors/shared/utils.js +301 -0
  113. package/src/compiler/phases/3-transform/client/transform-client.js +719 -0
  114. package/src/compiler/phases/3-transform/client/transform-template/fix-attribute-casing.js +18 -0
  115. package/src/compiler/phases/3-transform/client/transform-template/index.js +67 -0
  116. package/src/compiler/phases/3-transform/client/transform-template/template.js +164 -0
  117. package/src/compiler/phases/3-transform/client/utils.js +181 -0
  118. package/src/compiler/phases/3-transform/client/visitors/AnimateDirective.js +38 -0
  119. package/src/compiler/phases/3-transform/client/visitors/ArrowFunctionExpression.js +11 -0
  120. package/src/compiler/phases/3-transform/client/visitors/AssignmentExpression.js +247 -0
  121. package/src/compiler/phases/3-transform/client/visitors/AttachTag.js +26 -0
  122. package/src/compiler/phases/3-transform/client/visitors/Attribute.js +14 -0
  123. package/src/compiler/phases/3-transform/client/visitors/AwaitBlock.js +124 -0
  124. package/src/compiler/phases/3-transform/client/visitors/AwaitExpression.js +25 -0
  125. package/src/compiler/phases/3-transform/client/visitors/BinaryExpression.js +34 -0
  126. package/src/compiler/phases/3-transform/client/visitors/BindDirective.js +290 -0
  127. package/src/compiler/phases/3-transform/client/visitors/BlockStatement.js +32 -0
  128. package/src/compiler/phases/3-transform/client/visitors/BreakStatement.js +20 -0
  129. package/src/compiler/phases/3-transform/client/visitors/CallExpression.js +136 -0
  130. package/src/compiler/phases/3-transform/client/visitors/ClassBody.js +111 -0
  131. package/src/compiler/phases/3-transform/client/visitors/Comment.js +11 -0
  132. package/src/compiler/phases/3-transform/client/visitors/Component.js +12 -0
  133. package/src/compiler/phases/3-transform/client/visitors/ConstTag.js +134 -0
  134. package/src/compiler/phases/3-transform/client/visitors/DebugTag.js +28 -0
  135. package/src/compiler/phases/3-transform/client/visitors/EachBlock.js +362 -0
  136. package/src/compiler/phases/3-transform/client/visitors/ExportNamedDeclaration.js +19 -0
  137. package/src/compiler/phases/3-transform/client/visitors/ExpressionStatement.js +20 -0
  138. package/src/compiler/phases/3-transform/client/visitors/ForOfStatement.js +25 -0
  139. package/src/compiler/phases/3-transform/client/visitors/Fragment.js +186 -0
  140. package/src/compiler/phases/3-transform/client/visitors/FunctionDeclaration.js +12 -0
  141. package/src/compiler/phases/3-transform/client/visitors/FunctionExpression.js +11 -0
  142. package/src/compiler/phases/3-transform/client/visitors/HtmlTag.js +53 -0
  143. package/src/compiler/phases/3-transform/client/visitors/Identifier.js +45 -0
  144. package/src/compiler/phases/3-transform/client/visitors/IfBlock.js +131 -0
  145. package/src/compiler/phases/3-transform/client/visitors/KeyBlock.js +45 -0
  146. package/src/compiler/phases/3-transform/client/visitors/LabeledStatement.js +64 -0
  147. package/src/compiler/phases/3-transform/client/visitors/LetDirective.js +55 -0
  148. package/src/compiler/phases/3-transform/client/visitors/MemberExpression.js +23 -0
  149. package/src/compiler/phases/3-transform/client/visitors/OnDirective.js +38 -0
  150. package/src/compiler/phases/3-transform/client/visitors/Program.js +153 -0
  151. package/src/compiler/phases/3-transform/client/visitors/RegularElement.js +725 -0
  152. package/src/compiler/phases/3-transform/client/visitors/RenderTag.js +95 -0
  153. package/src/compiler/phases/3-transform/client/visitors/SlotElement.js +94 -0
  154. package/src/compiler/phases/3-transform/client/visitors/SnippetBlock.js +94 -0
  155. package/src/compiler/phases/3-transform/client/visitors/SpreadAttribute.js +10 -0
  156. package/src/compiler/phases/3-transform/client/visitors/SvelteBody.js +11 -0
  157. package/src/compiler/phases/3-transform/client/visitors/SvelteBoundary.js +126 -0
  158. package/src/compiler/phases/3-transform/client/visitors/SvelteComponent.js +13 -0
  159. package/src/compiler/phases/3-transform/client/visitors/SvelteDocument.js +11 -0
  160. package/src/compiler/phases/3-transform/client/visitors/SvelteElement.js +161 -0
  161. package/src/compiler/phases/3-transform/client/visitors/SvelteFragment.js +17 -0
  162. package/src/compiler/phases/3-transform/client/visitors/SvelteHead.js +23 -0
  163. package/src/compiler/phases/3-transform/client/visitors/SvelteSelf.js +13 -0
  164. package/src/compiler/phases/3-transform/client/visitors/SvelteWindow.js +11 -0
  165. package/src/compiler/phases/3-transform/client/visitors/TitleElement.js +48 -0
  166. package/src/compiler/phases/3-transform/client/visitors/TransitionDirective.js +41 -0
  167. package/src/compiler/phases/3-transform/client/visitors/UpdateExpression.js +55 -0
  168. package/src/compiler/phases/3-transform/client/visitors/UseDirective.js +49 -0
  169. package/src/compiler/phases/3-transform/client/visitors/VariableDeclaration.js +422 -0
  170. package/src/compiler/phases/3-transform/client/visitors/shared/component.js +536 -0
  171. package/src/compiler/phases/3-transform/client/visitors/shared/declarations.js +53 -0
  172. package/src/compiler/phases/3-transform/client/visitors/shared/element.js +263 -0
  173. package/src/compiler/phases/3-transform/client/visitors/shared/events.js +180 -0
  174. package/src/compiler/phases/3-transform/client/visitors/shared/fragment.js +185 -0
  175. package/src/compiler/phases/3-transform/client/visitors/shared/function.js +17 -0
  176. package/src/compiler/phases/3-transform/client/visitors/shared/special_element.js +22 -0
  177. package/src/compiler/phases/3-transform/client/visitors/shared/utils.js +513 -0
  178. package/src/compiler/phases/3-transform/css/index.js +479 -0
  179. package/src/compiler/phases/3-transform/index.js +118 -0
  180. package/src/compiler/phases/3-transform/server/transform-server.js +428 -0
  181. package/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js +124 -0
  182. package/src/compiler/phases/3-transform/server/visitors/AwaitBlock.js +36 -0
  183. package/src/compiler/phases/3-transform/server/visitors/AwaitExpression.js +40 -0
  184. package/src/compiler/phases/3-transform/server/visitors/CallExpression.js +71 -0
  185. package/src/compiler/phases/3-transform/server/visitors/ClassBody.js +81 -0
  186. package/src/compiler/phases/3-transform/server/visitors/Component.js +13 -0
  187. package/src/compiler/phases/3-transform/server/visitors/ConstTag.js +49 -0
  188. package/src/compiler/phases/3-transform/server/visitors/DebugTag.js +24 -0
  189. package/src/compiler/phases/3-transform/server/visitors/EachBlock.js +76 -0
  190. package/src/compiler/phases/3-transform/server/visitors/ExpressionStatement.js +23 -0
  191. package/src/compiler/phases/3-transform/server/visitors/Fragment.js +53 -0
  192. package/src/compiler/phases/3-transform/server/visitors/HtmlTag.js +25 -0
  193. package/src/compiler/phases/3-transform/server/visitors/Identifier.js +24 -0
  194. package/src/compiler/phases/3-transform/server/visitors/IfBlock.js +48 -0
  195. package/src/compiler/phases/3-transform/server/visitors/KeyBlock.js +22 -0
  196. package/src/compiler/phases/3-transform/server/visitors/LabeledStatement.js +24 -0
  197. package/src/compiler/phases/3-transform/server/visitors/MemberExpression.js +19 -0
  198. package/src/compiler/phases/3-transform/server/visitors/Program.js +25 -0
  199. package/src/compiler/phases/3-transform/server/visitors/PropertyDefinition.js +37 -0
  200. package/src/compiler/phases/3-transform/server/visitors/RegularElement.js +216 -0
  201. package/src/compiler/phases/3-transform/server/visitors/RenderTag.js +45 -0
  202. package/src/compiler/phases/3-transform/server/visitors/SlotElement.js +68 -0
  203. package/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js +29 -0
  204. package/src/compiler/phases/3-transform/server/visitors/SpreadAttribute.js +10 -0
  205. package/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js +139 -0
  206. package/src/compiler/phases/3-transform/server/visitors/SvelteComponent.js +12 -0
  207. package/src/compiler/phases/3-transform/server/visitors/SvelteElement.js +89 -0
  208. package/src/compiler/phases/3-transform/server/visitors/SvelteFragment.js +11 -0
  209. package/src/compiler/phases/3-transform/server/visitors/SvelteHead.js +25 -0
  210. package/src/compiler/phases/3-transform/server/visitors/SvelteSelf.js +12 -0
  211. package/src/compiler/phases/3-transform/server/visitors/TitleElement.js +21 -0
  212. package/src/compiler/phases/3-transform/server/visitors/UpdateExpression.js +35 -0
  213. package/src/compiler/phases/3-transform/server/visitors/VariableDeclaration.js +247 -0
  214. package/src/compiler/phases/3-transform/server/visitors/shared/component.js +359 -0
  215. package/src/compiler/phases/3-transform/server/visitors/shared/element.js +557 -0
  216. package/src/compiler/phases/3-transform/server/visitors/shared/utils.js +408 -0
  217. package/src/compiler/phases/3-transform/shared/assignments.js +92 -0
  218. package/src/compiler/phases/3-transform/shared/transform-async.js +114 -0
  219. package/src/compiler/phases/3-transform/utils.js +451 -0
  220. package/src/compiler/phases/bindings.js +227 -0
  221. package/src/compiler/phases/css.js +14 -0
  222. package/src/compiler/phases/nodes.js +258 -0
  223. package/src/compiler/phases/patterns.js +27 -0
  224. package/src/compiler/phases/scope.js +1432 -0
  225. package/src/compiler/preprocess/decode_sourcemap.js +96 -0
  226. package/src/compiler/preprocess/index.js +368 -0
  227. package/src/compiler/preprocess/replace_in_code.js +72 -0
  228. package/src/compiler/print/index.js +911 -0
  229. package/src/compiler/state.js +144 -0
  230. package/src/compiler/utils/assert.js +9 -0
  231. package/src/compiler/utils/ast.js +639 -0
  232. package/src/compiler/utils/builders.js +698 -0
  233. package/src/compiler/utils/compile_diagnostic.js +107 -0
  234. package/src/compiler/utils/extract_svelte_ignore.js +104 -0
  235. package/src/compiler/utils/mapped_code.js +454 -0
  236. package/src/compiler/utils/push_array.js +13 -0
  237. package/src/compiler/utils/sanitize_template_string.js +7 -0
  238. package/src/compiler/utils/slot.js +20 -0
  239. package/src/compiler/utils/string.js +9 -0
  240. package/src/compiler/validate-options.js +324 -0
  241. package/src/compiler/warnings.js +845 -0
  242. package/src/constants.js +66 -0
  243. package/src/easing/index.js +286 -0
  244. package/src/escaping.js +26 -0
  245. package/src/events/index.js +1 -0
  246. package/src/html-tree-validation.js +238 -0
  247. package/src/index-client.js +255 -0
  248. package/src/index-server.js +56 -0
  249. package/src/internal/client/constants.js +77 -0
  250. package/src/internal/client/context.js +258 -0
  251. package/src/internal/client/dev/assign.js +79 -0
  252. package/src/internal/client/dev/console-log.js +37 -0
  253. package/src/internal/client/dev/css.js +31 -0
  254. package/src/internal/client/dev/debug.js +500 -0
  255. package/src/internal/client/dev/elements.js +63 -0
  256. package/src/internal/client/dev/equality.js +101 -0
  257. package/src/internal/client/dev/hmr.js +89 -0
  258. package/src/internal/client/dev/inspect.js +72 -0
  259. package/src/internal/client/dev/legacy.js +25 -0
  260. package/src/internal/client/dev/ownership.js +81 -0
  261. package/src/internal/client/dev/tracing.js +162 -0
  262. package/src/internal/client/dev/validation.js +16 -0
  263. package/src/internal/client/dom/blocks/async.js +71 -0
  264. package/src/internal/client/dom/blocks/await.js +142 -0
  265. package/src/internal/client/dom/blocks/boundary.js +534 -0
  266. package/src/internal/client/dom/blocks/branches.js +227 -0
  267. package/src/internal/client/dom/blocks/css-props.js +28 -0
  268. package/src/internal/client/dom/blocks/each.js +723 -0
  269. package/src/internal/client/dom/blocks/html.js +128 -0
  270. package/src/internal/client/dom/blocks/if.js +82 -0
  271. package/src/internal/client/dom/blocks/key.js +40 -0
  272. package/src/internal/client/dom/blocks/slot.js +44 -0
  273. package/src/internal/client/dom/blocks/snippet.js +103 -0
  274. package/src/internal/client/dom/blocks/svelte-component.js +61 -0
  275. package/src/internal/client/dom/blocks/svelte-element.js +152 -0
  276. package/src/internal/client/dom/blocks/svelte-head.js +61 -0
  277. package/src/internal/client/dom/css.js +33 -0
  278. package/src/internal/client/dom/elements/actions.js +43 -0
  279. package/src/internal/client/dom/elements/attachments.js +33 -0
  280. package/src/internal/client/dom/elements/attributes.js +657 -0
  281. package/src/internal/client/dom/elements/bindings/document.js +17 -0
  282. package/src/internal/client/dom/elements/bindings/input.js +312 -0
  283. package/src/internal/client/dom/elements/bindings/media.js +233 -0
  284. package/src/internal/client/dom/elements/bindings/navigator.js +11 -0
  285. package/src/internal/client/dom/elements/bindings/props.js +22 -0
  286. package/src/internal/client/dom/elements/bindings/select.js +159 -0
  287. package/src/internal/client/dom/elements/bindings/shared.js +76 -0
  288. package/src/internal/client/dom/elements/bindings/size.js +107 -0
  289. package/src/internal/client/dom/elements/bindings/this.js +61 -0
  290. package/src/internal/client/dom/elements/bindings/universal.js +75 -0
  291. package/src/internal/client/dom/elements/bindings/window.js +66 -0
  292. package/src/internal/client/dom/elements/class.js +51 -0
  293. package/src/internal/client/dom/elements/custom-element.js +344 -0
  294. package/src/internal/client/dom/elements/customizable-select.js +99 -0
  295. package/src/internal/client/dom/elements/events.js +355 -0
  296. package/src/internal/client/dom/elements/misc.js +58 -0
  297. package/src/internal/client/dom/elements/style.js +57 -0
  298. package/src/internal/client/dom/elements/transitions.js +471 -0
  299. package/src/internal/client/dom/hydration.js +125 -0
  300. package/src/internal/client/dom/legacy/event-modifiers.js +127 -0
  301. package/src/internal/client/dom/legacy/lifecycle.js +82 -0
  302. package/src/internal/client/dom/legacy/misc.js +68 -0
  303. package/src/internal/client/dom/operations.js +293 -0
  304. package/src/internal/client/dom/reconciler.js +25 -0
  305. package/src/internal/client/dom/task.js +42 -0
  306. package/src/internal/client/dom/template.js +401 -0
  307. package/src/internal/client/error-handling.js +118 -0
  308. package/src/internal/client/errors.js +510 -0
  309. package/src/internal/client/hydratable.js +33 -0
  310. package/src/internal/client/index.js +183 -0
  311. package/src/internal/client/legacy.js +46 -0
  312. package/src/internal/client/loop.js +48 -0
  313. package/src/internal/client/proxy.js +432 -0
  314. package/src/internal/client/reactivity/async.js +306 -0
  315. package/src/internal/client/reactivity/batch.js +1057 -0
  316. package/src/internal/client/reactivity/deriveds.js +426 -0
  317. package/src/internal/client/reactivity/effects.js +718 -0
  318. package/src/internal/client/reactivity/equality.js +31 -0
  319. package/src/internal/client/reactivity/props.js +430 -0
  320. package/src/internal/client/reactivity/sources.js +370 -0
  321. package/src/internal/client/reactivity/status.js +25 -0
  322. package/src/internal/client/reactivity/store.js +203 -0
  323. package/src/internal/client/reactivity/utils.js +40 -0
  324. package/src/internal/client/render.js +335 -0
  325. package/src/internal/client/runtime.js +827 -0
  326. package/src/internal/client/timing.js +16 -0
  327. package/src/internal/client/validate.js +54 -0
  328. package/src/internal/client/warnings.js +271 -0
  329. package/src/internal/disclose-version.js +6 -0
  330. package/src/internal/flags/async.js +3 -0
  331. package/src/internal/flags/index.js +23 -0
  332. package/src/internal/flags/legacy.js +3 -0
  333. package/src/internal/flags/tracing.js +3 -0
  334. package/src/internal/index.js +5 -0
  335. package/src/internal/server/abort-signal.js +13 -0
  336. package/src/internal/server/blocks/html.js +11 -0
  337. package/src/internal/server/blocks/snippet.js +24 -0
  338. package/src/internal/server/context.js +132 -0
  339. package/src/internal/server/crypto.js +45 -0
  340. package/src/internal/server/dev.js +115 -0
  341. package/src/internal/server/errors.js +131 -0
  342. package/src/internal/server/hydratable.js +142 -0
  343. package/src/internal/server/hydration.js +6 -0
  344. package/src/internal/server/index.js +544 -0
  345. package/src/internal/server/render-context.js +86 -0
  346. package/src/internal/server/renderer.js +923 -0
  347. package/src/internal/server/warnings.js +29 -0
  348. package/src/internal/shared/attributes.js +225 -0
  349. package/src/internal/shared/clone.js +137 -0
  350. package/src/internal/shared/dev.js +65 -0
  351. package/src/internal/shared/errors.js +134 -0
  352. package/src/internal/shared/utils.js +144 -0
  353. package/src/internal/shared/validate.js +47 -0
  354. package/src/internal/shared/warnings.js +40 -0
  355. package/src/legacy/legacy-client.js +281 -0
  356. package/src/legacy/legacy-server.js +112 -0
  357. package/src/motion/index.js +32 -0
  358. package/src/motion/spring.js +369 -0
  359. package/src/motion/tweened.js +306 -0
  360. package/src/motion/utils.js +7 -0
  361. package/src/reactivity/create-subscriber.js +95 -0
  362. package/src/reactivity/date.js +118 -0
  363. package/src/reactivity/index-client.js +7 -0
  364. package/src/reactivity/index-server.js +23 -0
  365. package/src/reactivity/map.js +273 -0
  366. package/src/reactivity/media-query.js +55 -0
  367. package/src/reactivity/reactive-value.js +24 -0
  368. package/src/reactivity/set.js +213 -0
  369. package/src/reactivity/url-search-params.js +174 -0
  370. package/src/reactivity/url.js +205 -0
  371. package/src/reactivity/window/index.js +161 -0
  372. package/src/server/index.js +1 -0
  373. package/src/store/index-client.js +169 -0
  374. package/src/store/index-server.js +101 -0
  375. package/src/store/shared/index.js +209 -0
  376. package/src/store/utils.js +36 -0
  377. package/src/transition/index.js +300 -0
  378. package/src/utils.js +504 -0
  379. package/src/version.js +8 -0
  380. package/store.d.ts +1 -0
  381. package/svelte-html.d.ts +245 -0
  382. package/transition.d.ts +1 -0
  383. package/types/compiler/interfaces.d.ts +1 -0
  384. package/types/compiler/preprocess.d.ts +1 -0
  385. package/types/index.d.ts +3744 -0
  386. package/types/index.d.ts.map +280 -0
@@ -0,0 +1,1300 @@
1
+ /** @import * as ESTree from 'estree' */
2
+ /** @import { Binding, AST, ValidatedCompileOptions, ValidatedModuleCompileOptions } from '#compiler' */
3
+ /** @import { AnalysisState, Visitors } from './types' */
4
+ /** @import { Analysis, ComponentAnalysis, Js, ReactiveStatement, Template } from '../types' */
5
+ import { walk } from 'zimmerframe';
6
+ import { parse } from '../1-parse/acorn.js';
7
+ import * as e from '../../errors.js';
8
+ import * as w from '../../warnings.js';
9
+ import {
10
+ extract_identifiers,
11
+ has_await_expression,
12
+ object,
13
+ unwrap_pattern
14
+ } from '../../utils/ast.js';
15
+ import * as b from '#compiler/builders';
16
+ import { Scope, ScopeRoot, create_scopes, get_rune, set_scope } from '../scope.js';
17
+ import check_graph_for_cycles from './utils/check_graph_for_cycles.js';
18
+ import { create_attribute, is_custom_element_node } from '../nodes.js';
19
+ import { analyze_css } from './css/css-analyze.js';
20
+ import { prune } from './css/css-prune.js';
21
+ import { hash, is_rune } from '../../../utils.js';
22
+ import { warn_unused } from './css/css-warn.js';
23
+ import { extract_svelte_ignore } from '../../utils/extract_svelte_ignore.js';
24
+ import { ignore_map, ignore_stack, pop_ignore, push_ignore } from '../../state.js';
25
+ import { ArrowFunctionExpression } from './visitors/ArrowFunctionExpression.js';
26
+ import { AssignmentExpression } from './visitors/AssignmentExpression.js';
27
+ import { AnimateDirective } from './visitors/AnimateDirective.js';
28
+ import { AttachTag } from './visitors/AttachTag.js';
29
+ import { Attribute } from './visitors/Attribute.js';
30
+ import { AwaitBlock } from './visitors/AwaitBlock.js';
31
+ import { AwaitExpression } from './visitors/AwaitExpression.js';
32
+ import { BindDirective } from './visitors/BindDirective.js';
33
+ import { CallExpression } from './visitors/CallExpression.js';
34
+ import { ClassBody } from './visitors/ClassBody.js';
35
+ import { ClassDeclaration } from './visitors/ClassDeclaration.js';
36
+ import { ClassDirective } from './visitors/ClassDirective.js';
37
+ import { Component } from './visitors/Component.js';
38
+ import { ConstTag } from './visitors/ConstTag.js';
39
+ import { DebugTag } from './visitors/DebugTag.js';
40
+ import { EachBlock } from './visitors/EachBlock.js';
41
+ import { ExportDefaultDeclaration } from './visitors/ExportDefaultDeclaration.js';
42
+ import { ExportNamedDeclaration } from './visitors/ExportNamedDeclaration.js';
43
+ import { ExportSpecifier } from './visitors/ExportSpecifier.js';
44
+ import { ExpressionStatement } from './visitors/ExpressionStatement.js';
45
+ import { ExpressionTag } from './visitors/ExpressionTag.js';
46
+ import { Fragment } from './visitors/Fragment.js';
47
+ import { FunctionDeclaration } from './visitors/FunctionDeclaration.js';
48
+ import { FunctionExpression } from './visitors/FunctionExpression.js';
49
+ import { HtmlTag } from './visitors/HtmlTag.js';
50
+ import { Identifier } from './visitors/Identifier.js';
51
+ import { IfBlock } from './visitors/IfBlock.js';
52
+ import { ImportDeclaration } from './visitors/ImportDeclaration.js';
53
+ import { KeyBlock } from './visitors/KeyBlock.js';
54
+ import { LabeledStatement } from './visitors/LabeledStatement.js';
55
+ import { LetDirective } from './visitors/LetDirective.js';
56
+ import { Literal } from './visitors/Literal.js';
57
+ import { MemberExpression } from './visitors/MemberExpression.js';
58
+ import { NewExpression } from './visitors/NewExpression.js';
59
+ import { OnDirective } from './visitors/OnDirective.js';
60
+ import { PropertyDefinition } from './visitors/PropertyDefinition.js';
61
+ import { RegularElement } from './visitors/RegularElement.js';
62
+ import { RenderTag } from './visitors/RenderTag.js';
63
+ import { SlotElement } from './visitors/SlotElement.js';
64
+ import { SnippetBlock } from './visitors/SnippetBlock.js';
65
+ import { SpreadAttribute } from './visitors/SpreadAttribute.js';
66
+ import { SpreadElement } from './visitors/SpreadElement.js';
67
+ import { StyleDirective } from './visitors/StyleDirective.js';
68
+ import { SvelteBody } from './visitors/SvelteBody.js';
69
+ import { SvelteComponent } from './visitors/SvelteComponent.js';
70
+ import { SvelteDocument } from './visitors/SvelteDocument.js';
71
+ import { SvelteElement } from './visitors/SvelteElement.js';
72
+ import { SvelteFragment } from './visitors/SvelteFragment.js';
73
+ import { SvelteHead } from './visitors/SvelteHead.js';
74
+ import { SvelteSelf } from './visitors/SvelteSelf.js';
75
+ import { SvelteWindow } from './visitors/SvelteWindow.js';
76
+ import { SvelteBoundary } from './visitors/SvelteBoundary.js';
77
+ import { TaggedTemplateExpression } from './visitors/TaggedTemplateExpression.js';
78
+ import { TemplateElement } from './visitors/TemplateElement.js';
79
+ import { Text } from './visitors/Text.js';
80
+ import { TitleElement } from './visitors/TitleElement.js';
81
+ import { TransitionDirective } from './visitors/TransitionDirective.js';
82
+ import { UpdateExpression } from './visitors/UpdateExpression.js';
83
+ import { UseDirective } from './visitors/UseDirective.js';
84
+ import { VariableDeclarator } from './visitors/VariableDeclarator.js';
85
+ import is_reference from 'is-reference';
86
+ import { mark_subtree_dynamic } from './visitors/shared/fragment.js';
87
+ import * as state from '../../state.js';
88
+
89
+ /**
90
+ * @type {Visitors}
91
+ */
92
+ const visitors = {
93
+ _(node, { state, next, path }) {
94
+ const parent = path.at(-1);
95
+
96
+ /** @type {string[]} */
97
+ const ignores = [];
98
+
99
+ if (parent?.type === 'Fragment' && node.type !== 'Comment' && node.type !== 'Text') {
100
+ const idx = parent.nodes.indexOf(/** @type {any} */ (node));
101
+
102
+ for (let i = idx - 1; i >= 0; i--) {
103
+ const prev = parent.nodes[i];
104
+
105
+ if (prev.type === 'Comment') {
106
+ ignores.push(
107
+ ...extract_svelte_ignore(
108
+ prev.start + 4 /* '<!--'.length */,
109
+ prev.data,
110
+ state.analysis.runes
111
+ )
112
+ );
113
+ } else if (prev.type !== 'Text') {
114
+ break;
115
+ }
116
+ }
117
+ } else {
118
+ const comments = /** @type {any} */ (node).leadingComments;
119
+
120
+ if (comments) {
121
+ for (const comment of comments) {
122
+ ignores.push(
123
+ ...extract_svelte_ignore(
124
+ comment.start + 2 /* '//'.length */,
125
+ comment.value,
126
+ state.analysis.runes
127
+ )
128
+ );
129
+ }
130
+ }
131
+ }
132
+
133
+ if (ignores.length > 0) {
134
+ push_ignore(ignores);
135
+ }
136
+
137
+ ignore_map.set(node, structuredClone(ignore_stack));
138
+
139
+ const scope = state.scopes.get(node);
140
+ next(scope !== undefined && scope !== state.scope ? { ...state, scope } : state);
141
+
142
+ if (ignores.length > 0) {
143
+ pop_ignore();
144
+ }
145
+ },
146
+ AnimateDirective,
147
+ ArrowFunctionExpression,
148
+ AssignmentExpression,
149
+ AttachTag,
150
+ Attribute,
151
+ AwaitBlock,
152
+ AwaitExpression,
153
+ BindDirective,
154
+ CallExpression,
155
+ ClassBody,
156
+ ClassDeclaration,
157
+ ClassDirective,
158
+ Component,
159
+ ConstTag,
160
+ DebugTag,
161
+ EachBlock,
162
+ ExportDefaultDeclaration,
163
+ ExportNamedDeclaration,
164
+ ExportSpecifier,
165
+ ExpressionStatement,
166
+ ExpressionTag,
167
+ Fragment,
168
+ FunctionDeclaration,
169
+ FunctionExpression,
170
+ HtmlTag,
171
+ Identifier,
172
+ IfBlock,
173
+ ImportDeclaration,
174
+ KeyBlock,
175
+ LabeledStatement,
176
+ LetDirective,
177
+ Literal,
178
+ MemberExpression,
179
+ NewExpression,
180
+ OnDirective,
181
+ PropertyDefinition,
182
+ RegularElement,
183
+ RenderTag,
184
+ SlotElement,
185
+ SnippetBlock,
186
+ SpreadAttribute,
187
+ SpreadElement,
188
+ StyleDirective,
189
+ SvelteBody,
190
+ SvelteComponent,
191
+ SvelteDocument,
192
+ SvelteElement,
193
+ SvelteFragment,
194
+ SvelteHead,
195
+ SvelteSelf,
196
+ SvelteWindow,
197
+ SvelteBoundary,
198
+ TaggedTemplateExpression,
199
+ TemplateElement,
200
+ Text,
201
+ TransitionDirective,
202
+ TitleElement,
203
+ UpdateExpression,
204
+ UseDirective,
205
+ VariableDeclarator
206
+ };
207
+
208
+ /**
209
+ * @param {AST.Script | null} script
210
+ * @param {ScopeRoot} root
211
+ * @param {boolean} allow_reactive_declarations
212
+ * @param {Scope | null} parent
213
+ * @returns {Js}
214
+ */
215
+ function js(script, root, allow_reactive_declarations, parent) {
216
+ /** @type {ESTree.Program} */
217
+ const ast = script?.content ?? {
218
+ type: 'Program',
219
+ sourceType: 'module',
220
+ start: -1,
221
+ end: -1,
222
+ body: []
223
+ };
224
+
225
+ const { scope, scopes, has_await } = create_scopes(
226
+ ast,
227
+ root,
228
+ allow_reactive_declarations,
229
+ parent
230
+ );
231
+
232
+ return { ast, scope, scopes, has_await };
233
+ }
234
+
235
+ /**
236
+ * @param {string} filename
237
+ */
238
+ function get_component_name(filename) {
239
+ const parts = filename.split(/[/\\]/);
240
+ const basename = /** @type {string} */ (parts.pop());
241
+ const last_dir = /** @type {string} */ (parts.at(-1));
242
+ let name = basename.replace('.svelte', '');
243
+ if (name === 'index' && last_dir && last_dir !== 'src') {
244
+ name = last_dir;
245
+ }
246
+ return name[0].toUpperCase() + name.slice(1);
247
+ }
248
+
249
+ const RESERVED = ['$$props', '$$restProps', '$$slots'];
250
+
251
+ /**
252
+ * @param {string} source
253
+ * @param {ValidatedModuleCompileOptions} options
254
+ * @returns {Analysis}
255
+ */
256
+ export function analyze_module(source, options) {
257
+ /** @type {AST.JSComment[]} */
258
+ const comments = [];
259
+
260
+ state.set_source(source);
261
+ const ast = parse(source, comments, false, false);
262
+
263
+ const { scope, scopes, has_await } = create_scopes(ast, new ScopeRoot(), false, null);
264
+
265
+ for (const [name, references] of scope.references) {
266
+ if (name[0] !== '$' || RESERVED.includes(name)) continue;
267
+ if (name === '$' || name[1] === '$') {
268
+ e.global_reference_invalid(references[0].node, name);
269
+ }
270
+
271
+ const binding = scope.get(name.slice(1));
272
+
273
+ if (binding !== null && !is_rune(name)) {
274
+ e.store_invalid_subscription_module(references[0].node);
275
+ }
276
+ }
277
+
278
+ /** @type {Analysis} */
279
+ const analysis = {
280
+ module: { ast, scope, scopes, has_await },
281
+ name: options.filename,
282
+ accessors: false,
283
+ runes: true,
284
+ immutable: true,
285
+ tracing: false,
286
+ async_deriveds: new Set(),
287
+ comments,
288
+ classes: new Map(),
289
+ pickled_awaits: new Set()
290
+ };
291
+
292
+ state.adjust({
293
+ dev: options.dev,
294
+ rootDir: options.rootDir,
295
+ runes: true
296
+ });
297
+
298
+ walk(
299
+ /** @type {ESTree.Node} */ (ast),
300
+ {
301
+ scope,
302
+ scopes,
303
+ analysis: /** @type {ComponentAnalysis} */ (analysis),
304
+ state_fields: new Map(),
305
+ // TODO the following are not needed for modules, but we have to pass them in order to avoid type error,
306
+ // and reducing the type would result in a lot of tedious type casts elsewhere - find a good solution one day
307
+ ast_type: /** @type {any} */ (null),
308
+ component_slots: /** @type {Set<string>} */ (new Set()),
309
+ expression: null,
310
+ function_depth: 0,
311
+ has_props_rune: false,
312
+ options: /** @type {ValidatedCompileOptions} */ (options),
313
+ fragment: null,
314
+ parent_element: null,
315
+ reactive_statement: null,
316
+ derived_function_depth: -1
317
+ },
318
+ visitors
319
+ );
320
+
321
+ return analysis;
322
+ }
323
+
324
+ /**
325
+ * @param {AST.Root} root
326
+ * @param {string} source
327
+ * @param {ValidatedCompileOptions} options
328
+ * @returns {ComponentAnalysis}
329
+ */
330
+ export function analyze_component(root, source, options) {
331
+ const scope_root = new ScopeRoot();
332
+
333
+ const module = js(root.module, scope_root, false, null);
334
+ const instance = js(root.instance, scope_root, true, module.scope);
335
+
336
+ const { scope, scopes, has_await } = create_scopes(
337
+ root.fragment,
338
+ scope_root,
339
+ false,
340
+ instance.scope
341
+ );
342
+
343
+ /** @type {Template} */
344
+ const template = { ast: root.fragment, scope, scopes };
345
+
346
+ let synthetic_stores_legacy_check = [];
347
+
348
+ // create synthetic bindings for store subscriptions
349
+ for (const [name, references] of module.scope.references) {
350
+ if (name[0] !== '$' || RESERVED.includes(name)) continue;
351
+ if (name === '$' || name[1] === '$') {
352
+ e.global_reference_invalid(references[0].node, name);
353
+ }
354
+
355
+ const store_name = name.slice(1);
356
+ const declaration = instance.scope.get(store_name);
357
+ const init = /** @type {ESTree.Node | undefined} */ (declaration?.initial);
358
+
359
+ // If we're not in legacy mode through the compiler option, assume the user
360
+ // is referencing a rune and not a global store.
361
+ if (
362
+ options.runes === false ||
363
+ !is_rune(name) ||
364
+ (declaration !== null &&
365
+ // const state = $state(0) is valid
366
+ (get_rune(init, instance.scope) === null ||
367
+ // rune-line names received as props are valid too (but we have to protect against $props as store)
368
+ (store_name !== 'props' && get_rune(init, instance.scope) === '$props')) &&
369
+ // allow `import { derived } from 'svelte/store'` in the same file as `const x = $derived(..)` because one is not a subscription to the other
370
+ !(
371
+ name === '$derived' &&
372
+ declaration.initial?.type === 'ImportDeclaration' &&
373
+ declaration.initial.source.value === 'svelte/store'
374
+ ))
375
+ ) {
376
+ let is_nested_store_subscription_node = undefined;
377
+ search: for (const reference of references) {
378
+ for (let i = reference.path.length - 1; i >= 0; i--) {
379
+ const scope =
380
+ scopes.get(reference.path[i]) ||
381
+ module.scopes.get(reference.path[i]) ||
382
+ instance.scopes.get(reference.path[i]);
383
+ if (scope) {
384
+ const owner = scope?.owner(store_name);
385
+ if (!!owner && owner !== module.scope && owner !== instance.scope) {
386
+ is_nested_store_subscription_node = reference.node;
387
+ break search;
388
+ }
389
+ break;
390
+ }
391
+ }
392
+ }
393
+
394
+ if (is_nested_store_subscription_node) {
395
+ e.store_invalid_scoped_subscription(is_nested_store_subscription_node);
396
+ }
397
+
398
+ if (options.runes !== false) {
399
+ if (declaration === null && /[a-z]/.test(store_name[0])) {
400
+ e.global_reference_invalid(references[0].node, name);
401
+ } else if (declaration !== null && is_rune(name)) {
402
+ for (const { node, path } of references) {
403
+ if (path.at(-1)?.type === 'CallExpression') {
404
+ w.store_rune_conflict(node, store_name);
405
+ }
406
+ }
407
+ }
408
+ }
409
+
410
+ if (module.ast) {
411
+ for (const { node, path } of references) {
412
+ // if the reference is inside module, error. this is a bit hacky but it works
413
+ if (
414
+ /** @type {number} */ (node.start) > /** @type {number} */ (module.ast.start) &&
415
+ /** @type {number} */ (node.end) < /** @type {number} */ (module.ast.end) &&
416
+ // const state = $state(0) is valid
417
+ get_rune(/** @type {ESTree.Node} */ (path.at(-1)), module.scope) === null
418
+ ) {
419
+ e.store_invalid_subscription(node);
420
+ }
421
+ }
422
+ }
423
+
424
+ // we push to the array because at this moment in time we can't be sure if we are in legacy
425
+ // mode yet because we are still changing the module scope
426
+ synthetic_stores_legacy_check.push(() => {
427
+ // if we are creating a synthetic binding for a let declaration we should also declare
428
+ // the declaration as state in case it's reassigned and we are not in runes mode (the function will
429
+ // not be called if we are not in runes mode, that's why there's no !runes check here)
430
+ if (
431
+ declaration !== null &&
432
+ declaration.kind === 'normal' &&
433
+ declaration.declaration_kind === 'let' &&
434
+ declaration.reassigned
435
+ ) {
436
+ declaration.kind = 'state';
437
+ }
438
+ });
439
+
440
+ const binding = instance.scope.declare(b.id(name), 'store_sub', 'synthetic');
441
+ binding.references = references;
442
+ instance.scope.references.set(name, references);
443
+ module.scope.references.delete(name);
444
+ }
445
+ }
446
+
447
+ const component_name = get_component_name(options.filename);
448
+
449
+ const runes =
450
+ options.runes ??
451
+ (has_await || instance.has_await || Array.from(module.scope.references.keys()).some(is_rune));
452
+
453
+ if (!runes) {
454
+ for (let check of synthetic_stores_legacy_check) {
455
+ check();
456
+ }
457
+ }
458
+
459
+ if (runes && root.module) {
460
+ const context = root.module.attributes.find((attribute) => attribute.name === 'context');
461
+ if (context) {
462
+ w.script_context_deprecated(context);
463
+ }
464
+ }
465
+
466
+ const is_custom_element = !!options.customElementOptions || options.customElement;
467
+
468
+ const name = module.scope.generate(options.name ?? component_name);
469
+
470
+ state.adjust({
471
+ component_name: name,
472
+ dev: options.dev,
473
+ rootDir: options.rootDir,
474
+ runes
475
+ });
476
+
477
+ // TODO remove all the ?? stuff, we don't need it now that we're validating the config
478
+ /** @type {ComponentAnalysis} */
479
+ const analysis = {
480
+ name,
481
+ root: scope_root,
482
+ module,
483
+ instance,
484
+ template,
485
+ comments: root.comments,
486
+ elements: [],
487
+ runes,
488
+ // if we are not in runes mode but we have no reserved references ($$props, $$restProps)
489
+ // and no `export let` we might be in a wannabe runes component that is using runes in an external
490
+ // module...we need to fallback to the runic behavior
491
+ maybe_runes:
492
+ !runes &&
493
+ // if they explicitly disabled runes, use the legacy behavior
494
+ options.runes !== false &&
495
+ ![...module.scope.references.keys()].some((name) =>
496
+ ['$$props', '$$restProps'].includes(name)
497
+ ) &&
498
+ !instance.ast.body.some(
499
+ (node) =>
500
+ node.type === 'LabeledStatement' ||
501
+ (node.type === 'ExportNamedDeclaration' &&
502
+ ((node.declaration &&
503
+ node.declaration.type === 'VariableDeclaration' &&
504
+ node.declaration.kind === 'let') ||
505
+ node.specifiers.some(
506
+ (specifier) =>
507
+ specifier.local.type === 'Identifier' &&
508
+ instance.scope.get(specifier.local.name)?.declaration_kind === 'let'
509
+ )))
510
+ ),
511
+ tracing: false,
512
+ classes: new Map(),
513
+ immutable: runes || options.immutable,
514
+ exports: [],
515
+ uses_props: false,
516
+ props_id: null,
517
+ uses_rest_props: false,
518
+ uses_slots: false,
519
+ uses_component_bindings: false,
520
+ uses_render_tags: false,
521
+ needs_context: false,
522
+ needs_mutation_validation: false,
523
+ needs_props: false,
524
+ event_directive_node: null,
525
+ uses_event_attributes: false,
526
+ custom_element: is_custom_element,
527
+ inject_styles: options.css === 'injected' || is_custom_element,
528
+ accessors:
529
+ is_custom_element ||
530
+ (runes ? false : !!options.accessors) ||
531
+ // because $set method needs accessors
532
+ options.compatibility?.componentApi === 4,
533
+ reactive_statements: new Map(),
534
+ binding_groups: new Map(),
535
+ slot_names: new Map(),
536
+ css: {
537
+ ast: root.css,
538
+ hash: root.css
539
+ ? options.cssHash({
540
+ css: root.css.content.styles,
541
+ filename: state.filename,
542
+ name: component_name,
543
+ hash
544
+ })
545
+ : '',
546
+ keyframes: [],
547
+ has_global: false
548
+ },
549
+ source,
550
+ snippet_renderers: new Map(),
551
+ snippets: new Set(),
552
+ async_deriveds: new Set(),
553
+ pickled_awaits: new Set(),
554
+ instance_body: {
555
+ sync: [],
556
+ async: [],
557
+ declarations: [],
558
+ hoisted: []
559
+ }
560
+ };
561
+
562
+ if (!runes) {
563
+ // every exported `let` or `var` declaration becomes a prop, everything else becomes an export
564
+ for (const node of instance.ast.body) {
565
+ if (node.type !== 'ExportNamedDeclaration') continue;
566
+
567
+ analysis.needs_props = true;
568
+
569
+ if (node.declaration) {
570
+ if (
571
+ node.declaration.type === 'FunctionDeclaration' ||
572
+ node.declaration.type === 'ClassDeclaration'
573
+ ) {
574
+ analysis.exports.push({
575
+ name: /** @type {import('estree').Identifier} */ (node.declaration.id).name,
576
+ alias: null
577
+ });
578
+ } else if (node.declaration.type === 'VariableDeclaration') {
579
+ if (node.declaration.kind === 'const') {
580
+ for (const declarator of node.declaration.declarations) {
581
+ for (const node of extract_identifiers(declarator.id)) {
582
+ analysis.exports.push({ name: node.name, alias: null });
583
+ }
584
+ }
585
+ } else {
586
+ for (const declarator of node.declaration.declarations) {
587
+ for (const id of extract_identifiers(declarator.id)) {
588
+ const binding = /** @type {Binding} */ (instance.scope.get(id.name));
589
+ binding.kind = 'bindable_prop';
590
+ }
591
+ }
592
+ }
593
+ }
594
+ } else {
595
+ for (const specifier of node.specifiers) {
596
+ if (specifier.local.type !== 'Identifier' || specifier.exported.type !== 'Identifier') {
597
+ continue;
598
+ }
599
+
600
+ const binding = instance.scope.get(specifier.local.name);
601
+
602
+ if (
603
+ binding &&
604
+ (binding.declaration_kind === 'var' || binding.declaration_kind === 'let')
605
+ ) {
606
+ binding.kind = 'bindable_prop';
607
+
608
+ if (specifier.exported.name !== specifier.local.name) {
609
+ binding.prop_alias = specifier.exported.name;
610
+ }
611
+ } else {
612
+ analysis.exports.push({ name: specifier.local.name, alias: specifier.exported.name });
613
+ }
614
+ }
615
+ }
616
+ }
617
+
618
+ // if reassigned/mutated bindings are referenced in `$:` blocks
619
+ // or the template, turn them into state
620
+ for (const binding of instance.scope.declarations.values()) {
621
+ if (binding.kind !== 'normal') continue;
622
+
623
+ for (const { node, path } of binding.references) {
624
+ if (node === binding.node) continue;
625
+
626
+ if (binding.updated) {
627
+ if (
628
+ path[path.length - 1].type === 'StyleDirective' ||
629
+ path.some((node) => node.type === 'Fragment') ||
630
+ (path[1].type === 'LabeledStatement' && path[1].label.name === '$')
631
+ ) {
632
+ binding.kind = 'state';
633
+ }
634
+ }
635
+ }
636
+ }
637
+
638
+ // more legacy nonsense: if an `each` binding is reassigned/mutated,
639
+ // treat the expression as being mutated as well
640
+ walk(/** @type {AST.SvelteNode} */ (template.ast), null, {
641
+ EachBlock(node) {
642
+ const scope = /** @type {Scope} */ (template.scopes.get(node));
643
+
644
+ for (const binding of scope.declarations.values()) {
645
+ if (binding.updated) {
646
+ const state = { scope: /** @type {Scope} */ (scope.parent), scopes: template.scopes };
647
+
648
+ walk(node.expression, state, {
649
+ // @ts-expect-error
650
+ _: set_scope,
651
+ Identifier(node, context) {
652
+ const parent = /** @type {ESTree.Expression} */ (context.path.at(-1));
653
+
654
+ if (is_reference(node, parent)) {
655
+ const binding = context.state.scope.get(node.name);
656
+
657
+ if (
658
+ binding &&
659
+ binding.kind === 'normal' &&
660
+ binding.declaration_kind !== 'import' &&
661
+ binding.declaration_kind !== 'function'
662
+ ) {
663
+ binding.kind = 'state';
664
+ binding.mutated = true;
665
+ }
666
+ }
667
+ }
668
+ });
669
+
670
+ break;
671
+ }
672
+ }
673
+ }
674
+ });
675
+ }
676
+
677
+ if (root.options) {
678
+ for (const attribute of root.options.attributes) {
679
+ if (attribute.name === 'accessors' && analysis.runes) {
680
+ w.options_deprecated_accessors(attribute);
681
+ }
682
+
683
+ if (attribute.name === 'customElement' && !options.customElement) {
684
+ w.options_missing_custom_element(attribute);
685
+ }
686
+
687
+ if (attribute.name === 'immutable' && analysis.runes) {
688
+ w.options_deprecated_immutable(attribute);
689
+ }
690
+ }
691
+ }
692
+
693
+ calculate_blockers(instance, analysis);
694
+
695
+ if (analysis.runes) {
696
+ const props_refs = module.scope.references.get('$$props');
697
+ if (props_refs) {
698
+ e.legacy_props_invalid(props_refs[0].node);
699
+ }
700
+
701
+ const rest_props_refs = module.scope.references.get('$$restProps');
702
+ if (rest_props_refs) {
703
+ e.legacy_rest_props_invalid(rest_props_refs[0].node);
704
+ }
705
+
706
+ for (const { ast, scope, scopes } of [module, instance, template]) {
707
+ /** @type {AnalysisState} */
708
+ const state = {
709
+ scope,
710
+ scopes,
711
+ analysis,
712
+ options,
713
+ ast_type: ast === instance.ast ? 'instance' : ast === template.ast ? 'template' : 'module',
714
+ fragment: ast === template.ast ? ast : null,
715
+ parent_element: null,
716
+ has_props_rune: false,
717
+ component_slots: new Set(),
718
+ expression: null,
719
+ state_fields: new Map(),
720
+ function_depth: scope.function_depth,
721
+ reactive_statement: null,
722
+ derived_function_depth: -1
723
+ };
724
+
725
+ walk(/** @type {AST.SvelteNode} */ (ast), state, visitors);
726
+ }
727
+
728
+ // warn on any nonstate declarations that are a) reassigned and b) referenced in the template
729
+ for (const scope of [module.scope, instance.scope]) {
730
+ outer: for (const [name, binding] of scope.declarations) {
731
+ if (binding.kind === 'normal' && binding.reassigned) {
732
+ inner: for (const { path } of binding.references) {
733
+ if (path[0].type !== 'Fragment') continue;
734
+ for (let i = 1; i < path.length; i += 1) {
735
+ const type = path[i].type;
736
+ if (
737
+ type === 'FunctionDeclaration' ||
738
+ type === 'FunctionExpression' ||
739
+ type === 'ArrowFunctionExpression'
740
+ ) {
741
+ continue inner;
742
+ }
743
+ // bind:this doesn't need to be a state reference if it will never change
744
+ if (
745
+ type === 'BindDirective' &&
746
+ /** @type {AST.BindDirective} */ (path[i]).name === 'this'
747
+ ) {
748
+ for (let j = i - 1; j >= 0; j -= 1) {
749
+ const type = path[j].type;
750
+ if (
751
+ type === 'IfBlock' ||
752
+ type === 'EachBlock' ||
753
+ type === 'AwaitBlock' ||
754
+ type === 'KeyBlock'
755
+ ) {
756
+ w.non_reactive_update(binding.node, name);
757
+ continue outer;
758
+ }
759
+ }
760
+ continue inner;
761
+ }
762
+ }
763
+
764
+ w.non_reactive_update(binding.node, name);
765
+ continue outer;
766
+ }
767
+ }
768
+ }
769
+ }
770
+ } else {
771
+ instance.scope.declare(b.id('$$props'), 'rest_prop', 'synthetic');
772
+ instance.scope.declare(b.id('$$restProps'), 'rest_prop', 'synthetic');
773
+
774
+ for (const { ast, scope, scopes } of [module, instance, template]) {
775
+ /** @type {AnalysisState} */
776
+ const state = {
777
+ scope,
778
+ scopes,
779
+ analysis,
780
+ options,
781
+ fragment: ast === template.ast ? ast : null,
782
+ parent_element: null,
783
+ has_props_rune: false,
784
+ ast_type: ast === instance.ast ? 'instance' : ast === template.ast ? 'template' : 'module',
785
+ reactive_statement: null,
786
+ component_slots: new Set(),
787
+ expression: null,
788
+ state_fields: new Map(),
789
+ function_depth: scope.function_depth,
790
+ derived_function_depth: -1
791
+ };
792
+
793
+ walk(/** @type {AST.SvelteNode} */ (ast), state, visitors);
794
+ }
795
+
796
+ for (const [name, binding] of instance.scope.declarations) {
797
+ if (
798
+ (binding.kind === 'prop' || binding.kind === 'bindable_prop') &&
799
+ binding.node.name !== '$$props'
800
+ ) {
801
+ const references = binding.references.filter(
802
+ (r) => r.node !== binding.node && r.path.at(-1)?.type !== 'ExportSpecifier'
803
+ );
804
+ if (!references.length && !instance.scope.declarations.has(`$${name}`)) {
805
+ w.export_let_unused(binding.node, name);
806
+ }
807
+ }
808
+ }
809
+
810
+ analysis.reactive_statements = order_reactive_statements(analysis.reactive_statements);
811
+ }
812
+
813
+ for (const node of analysis.module.ast.body) {
814
+ if (node.type === 'ExportNamedDeclaration' && node.specifiers !== null && node.source == null) {
815
+ for (const specifier of node.specifiers) {
816
+ if (specifier.local.type !== 'Identifier') continue;
817
+ const name = specifier.local.name;
818
+ const binding = analysis.module.scope.get(name);
819
+ if (!binding) {
820
+ if ([...analysis.snippets].find((snippet) => snippet.expression.name === name)) {
821
+ e.snippet_invalid_export(specifier);
822
+ } else {
823
+ e.export_undefined(specifier, name);
824
+ }
825
+ }
826
+ }
827
+ }
828
+ }
829
+
830
+ if (analysis.event_directive_node && analysis.uses_event_attributes) {
831
+ e.mixed_event_handler_syntaxes(
832
+ analysis.event_directive_node,
833
+ analysis.event_directive_node.name
834
+ );
835
+ }
836
+
837
+ for (const [node, resolved] of analysis.snippet_renderers) {
838
+ if (!resolved) {
839
+ node.metadata.snippets = analysis.snippets;
840
+ }
841
+
842
+ for (const snippet of node.metadata.snippets) {
843
+ snippet.metadata.sites.add(node);
844
+ }
845
+ }
846
+
847
+ if (
848
+ analysis.uses_render_tags &&
849
+ (analysis.uses_slots || (!analysis.custom_element && analysis.slot_names.size > 0))
850
+ ) {
851
+ const pos = analysis.slot_names.values().next().value ?? analysis.source.indexOf('$$slot');
852
+ e.slot_snippet_conflict(pos);
853
+ }
854
+
855
+ if (analysis.css.ast) {
856
+ analyze_css(analysis.css.ast, analysis);
857
+
858
+ // mark nodes as scoped/unused/empty etc
859
+ for (const node of analysis.elements) {
860
+ prune(analysis.css.ast, node);
861
+ }
862
+
863
+ const { comment } = analysis.css.ast.content;
864
+ const should_ignore_unused =
865
+ comment &&
866
+ extract_svelte_ignore(comment.start, comment.data, analysis.runes).includes(
867
+ 'css_unused_selector'
868
+ );
869
+
870
+ if (!should_ignore_unused) {
871
+ warn_unused(analysis.css.ast);
872
+ }
873
+ }
874
+
875
+ for (const node of analysis.elements) {
876
+ if (node.metadata.scoped && is_custom_element_node(node)) {
877
+ mark_subtree_dynamic(node.metadata.path);
878
+ }
879
+
880
+ let has_class = false;
881
+ let has_style = false;
882
+ let has_spread = false;
883
+ let has_class_directive = false;
884
+ let has_style_directive = false;
885
+
886
+ for (const attribute of node.attributes) {
887
+ // The spread method appends the hash to the end of the class attribute on its own
888
+ if (attribute.type === 'SpreadAttribute') {
889
+ has_spread = true;
890
+ break;
891
+ } else if (attribute.type === 'Attribute') {
892
+ has_class ||= attribute.name.toLowerCase() === 'class';
893
+ has_style ||= attribute.name.toLowerCase() === 'style';
894
+ } else if (attribute.type === 'ClassDirective') {
895
+ has_class_directive = true;
896
+ } else if (attribute.type === 'StyleDirective') {
897
+ has_style_directive = true;
898
+ }
899
+ }
900
+
901
+ // We need an empty class to generate the set_class() or class="" correctly
902
+ if (!has_spread && !has_class && (node.metadata.scoped || has_class_directive)) {
903
+ node.attributes.push(
904
+ create_attribute('class', null, -1, -1, [
905
+ {
906
+ type: 'Text',
907
+ data: '',
908
+ raw: '',
909
+ start: -1,
910
+ end: -1
911
+ }
912
+ ])
913
+ );
914
+ }
915
+
916
+ // We need an empty style to generate the set_style() correctly
917
+ if (!has_spread && !has_style && has_style_directive) {
918
+ node.attributes.push(
919
+ create_attribute('style', null, -1, -1, [
920
+ {
921
+ type: 'Text',
922
+ data: '',
923
+ raw: '',
924
+ start: -1,
925
+ end: -1
926
+ }
927
+ ])
928
+ );
929
+ }
930
+ }
931
+
932
+ // TODO
933
+ // analysis.stylesheet.warn_on_unused_selectors(analysis);
934
+
935
+ return analysis;
936
+ }
937
+
938
+ /**
939
+ * Analyzes the instance's top level statements to calculate which bindings need to wait on which
940
+ * top level statements. This includes indirect blockers such as functions referencing async top level statements.
941
+ *
942
+ * @param {Js} instance
943
+ * @param {ComponentAnalysis} analysis
944
+ * @returns {void}
945
+ */
946
+ function calculate_blockers(instance, analysis) {
947
+ /**
948
+ * @param {ESTree.Node} expression
949
+ * @param {Scope} scope
950
+ * @param {Set<Binding>} touched
951
+ * @param {Set<ESTree.Node>} seen
952
+ */
953
+ const touch = (expression, scope, touched, seen = new Set()) => {
954
+ if (seen.has(expression)) return;
955
+ seen.add(expression);
956
+
957
+ walk(
958
+ expression,
959
+ { scope },
960
+ {
961
+ _(node, context) {
962
+ const scope = instance.scopes.get(node);
963
+ if (scope) {
964
+ context.next({ scope });
965
+ } else {
966
+ context.next();
967
+ }
968
+ },
969
+ ImportDeclaration(node) {},
970
+ Identifier(node, context) {
971
+ const parent = /** @type {ESTree.Node} */ (context.path.at(-1));
972
+ if (is_reference(node, parent)) {
973
+ const binding = context.state.scope.get(node.name);
974
+ if (binding) {
975
+ touched.add(binding);
976
+
977
+ for (const assignment of binding.assignments) {
978
+ touch(assignment.value, assignment.scope, touched, seen);
979
+ }
980
+ }
981
+ }
982
+ }
983
+ }
984
+ );
985
+ };
986
+
987
+ /**
988
+ * @param {ESTree.Node} node
989
+ * @param {Set<Binding>} reads
990
+ * @param {Set<Binding>} writes
991
+ * @param {Scope} scope
992
+ */
993
+ const trace_references = (node, reads, writes, scope) => {
994
+ /**
995
+ * @param {ESTree.Pattern} node
996
+ * @param {Scope} scope
997
+ */
998
+ function update(node, scope) {
999
+ for (const pattern of unwrap_pattern(node)) {
1000
+ const node = object(pattern);
1001
+ if (!node) return;
1002
+
1003
+ const binding = scope.get(node.name);
1004
+ if (!binding) return;
1005
+
1006
+ writes.add(binding);
1007
+ }
1008
+ }
1009
+
1010
+ walk(
1011
+ node,
1012
+ { scope },
1013
+ {
1014
+ _(node, context) {
1015
+ const scope = instance.scopes.get(node);
1016
+ if (scope) {
1017
+ context.next({ scope });
1018
+ } else {
1019
+ context.next();
1020
+ }
1021
+ },
1022
+ AssignmentExpression(node, context) {
1023
+ update(node.left, context.state.scope);
1024
+ },
1025
+ UpdateExpression(node, context) {
1026
+ update(
1027
+ /** @type {ESTree.Identifier | ESTree.MemberExpression} */ (node.argument),
1028
+ context.state.scope
1029
+ );
1030
+ },
1031
+ CallExpression(node, context) {
1032
+ // for now, assume everything touched by the callee ends up mutating the object
1033
+ // TODO optimise this better
1034
+
1035
+ // special case — no need to peek inside effects as they only run once async work has completed
1036
+ const rune = get_rune(node, context.state.scope);
1037
+ if (rune === '$effect') return;
1038
+
1039
+ /** @type {Set<Binding>} */
1040
+ const touched = new Set();
1041
+ touch(node, context.state.scope, touched);
1042
+
1043
+ for (const b of touched) {
1044
+ writes.add(b);
1045
+ }
1046
+ },
1047
+ Identifier(node, context) {
1048
+ const parent = /** @type {ESTree.Node} */ (context.path.at(-1));
1049
+ if (is_reference(node, parent)) {
1050
+ const binding = context.state.scope.get(node.name);
1051
+ if (binding) {
1052
+ reads.add(binding);
1053
+ }
1054
+ }
1055
+ },
1056
+ ReturnStatement(node, context) {
1057
+ // We have to assume that anything returned from a function, even if it's a function itself,
1058
+ // might be called immediately, so we have to touch all references within it. Example:
1059
+ // function foo() { return () => blocker; } foo(); // blocker is touched
1060
+ if (node.argument) {
1061
+ touch(node.argument, context.state.scope, reads);
1062
+ }
1063
+ },
1064
+ // don't look inside functions until they are called
1065
+ ArrowFunctionExpression(_, context) {},
1066
+ FunctionDeclaration(_, context) {},
1067
+ FunctionExpression(_, context) {}
1068
+ }
1069
+ );
1070
+ };
1071
+
1072
+ let awaited = false;
1073
+
1074
+ // TODO this should probably be attached to the scope?
1075
+ const promises = b.id('$$promises');
1076
+
1077
+ /**
1078
+ * @param {ESTree.Identifier} id
1079
+ * @param {NonNullable<Binding['blocker']>} blocker
1080
+ */
1081
+ function push_declaration(id, blocker) {
1082
+ analysis.instance_body.declarations.push(id);
1083
+
1084
+ const binding = /** @type {Binding} */ (instance.scope.get(id.name));
1085
+ binding.blocker = blocker;
1086
+ }
1087
+
1088
+ /**
1089
+ * Analysis of blockers for functions is deferred until we know which statements are async/blockers
1090
+ * @type {Array<ESTree.FunctionDeclaration | ESTree.VariableDeclarator>}
1091
+ */
1092
+ const functions = [];
1093
+
1094
+ for (let node of instance.ast.body) {
1095
+ if (node.type === 'ImportDeclaration') {
1096
+ analysis.instance_body.hoisted.push(node);
1097
+ continue;
1098
+ }
1099
+
1100
+ if (node.type === 'ExportDefaultDeclaration' || node.type === 'ExportAllDeclaration') {
1101
+ // these can't exist inside `<script>` but TypeScript doesn't know that
1102
+ continue;
1103
+ }
1104
+
1105
+ if (node.type === 'ExportNamedDeclaration') {
1106
+ if (node.declaration) {
1107
+ node = node.declaration;
1108
+ } else {
1109
+ continue;
1110
+ }
1111
+ }
1112
+
1113
+ const has_await = has_await_expression(node);
1114
+ awaited ||= has_await;
1115
+
1116
+ if (node.type === 'FunctionDeclaration') {
1117
+ analysis.instance_body.sync.push(node);
1118
+ functions.push(node);
1119
+ } else if (node.type === 'VariableDeclaration') {
1120
+ for (const declarator of node.declarations) {
1121
+ if (get_rune(declarator.init, instance.scope) === '$props.id') {
1122
+ // special case
1123
+ continue;
1124
+ }
1125
+
1126
+ if (
1127
+ declarator.init?.type === 'ArrowFunctionExpression' ||
1128
+ declarator.init?.type === 'FunctionExpression'
1129
+ ) {
1130
+ // One declarator per declaration, makes things simpler. The ternary ensures more accurate source maps in the common case
1131
+ analysis.instance_body.sync.push(
1132
+ node.declarations.length === 1 ? node : b.declaration(node.kind, [declarator])
1133
+ );
1134
+ functions.push(declarator);
1135
+ } else if (!awaited) {
1136
+ // One declarator per declaration, makes things simpler. The ternary ensures more accurate source maps in the common case
1137
+ analysis.instance_body.sync.push(
1138
+ node.declarations.length === 1 ? node : b.declaration(node.kind, [declarator])
1139
+ );
1140
+ } else {
1141
+ /** @type {Set<Binding>} */
1142
+ const reads = new Set(); // TODO we're not actually using this yet
1143
+
1144
+ /** @type {Set<Binding>} */
1145
+ const writes = new Set();
1146
+
1147
+ trace_references(declarator, reads, writes, instance.scope);
1148
+
1149
+ const blocker = /** @type {NonNullable<Binding['blocker']>} */ (
1150
+ b.member(promises, b.literal(analysis.instance_body.async.length), true)
1151
+ );
1152
+
1153
+ for (const binding of writes) {
1154
+ binding.blocker = blocker;
1155
+ }
1156
+
1157
+ for (const id of extract_identifiers(declarator.id)) {
1158
+ push_declaration(id, blocker);
1159
+ }
1160
+
1161
+ // one declarator per declaration, makes things simpler
1162
+ analysis.instance_body.async.push({
1163
+ node: declarator,
1164
+ has_await
1165
+ });
1166
+ }
1167
+ }
1168
+ } else if (awaited) {
1169
+ /** @type {Set<Binding>} */
1170
+ const reads = new Set(); // TODO we're not actually using this yet
1171
+
1172
+ /** @type {Set<Binding>} */
1173
+ const writes = new Set();
1174
+
1175
+ trace_references(node, reads, writes, instance.scope);
1176
+
1177
+ const blocker = /** @type {NonNullable<Binding['blocker']>} */ (
1178
+ b.member(promises, b.literal(analysis.instance_body.async.length), true)
1179
+ );
1180
+
1181
+ for (const binding of writes) {
1182
+ binding.blocker = blocker;
1183
+ }
1184
+
1185
+ if (node.type === 'ClassDeclaration') {
1186
+ push_declaration(node.id, blocker);
1187
+ analysis.instance_body.async.push({ node, has_await });
1188
+ } else {
1189
+ analysis.instance_body.async.push({ node, has_await });
1190
+ }
1191
+ } else {
1192
+ analysis.instance_body.sync.push(node);
1193
+ }
1194
+ }
1195
+
1196
+ for (const fn of functions) {
1197
+ /** @type {Set<Binding>} */
1198
+ const reads_writes = new Set();
1199
+ const init =
1200
+ fn.type === 'VariableDeclarator'
1201
+ ? /** @type {ESTree.FunctionExpression | ESTree.ArrowFunctionExpression} */ (fn.init)
1202
+ : fn;
1203
+
1204
+ trace_references(
1205
+ init.body,
1206
+ reads_writes,
1207
+ reads_writes,
1208
+ /** @type {Scope} */ (instance.scopes.get(init))
1209
+ );
1210
+
1211
+ const max = [...reads_writes].reduce((max, binding) => {
1212
+ if (binding.blocker) {
1213
+ let property = /** @type {ESTree.SimpleLiteral & { value: number }} */ (
1214
+ binding.blocker.property
1215
+ );
1216
+
1217
+ return Math.max(property.value, max);
1218
+ }
1219
+
1220
+ return max;
1221
+ }, -1);
1222
+
1223
+ if (max === -1) continue;
1224
+
1225
+ const blocker = b.member(promises, b.literal(max), true);
1226
+ const binding = /** @type {Binding} */ (
1227
+ fn.type === 'FunctionDeclaration'
1228
+ ? instance.scope.get(fn.id.name)
1229
+ : instance.scope.get(/** @type {ESTree.Identifier} */ (fn.id).name)
1230
+ );
1231
+
1232
+ binding.blocker = /** @type {typeof binding['blocker']} */ (blocker);
1233
+ }
1234
+ }
1235
+
1236
+ /**
1237
+ * @param {Map<import('estree').LabeledStatement, ReactiveStatement>} unsorted_reactive_declarations
1238
+ */
1239
+ function order_reactive_statements(unsorted_reactive_declarations) {
1240
+ /** @typedef {[import('estree').LabeledStatement, ReactiveStatement]} Tuple */
1241
+
1242
+ /** @type {Map<string, Array<Tuple>>} */
1243
+ const lookup = new Map();
1244
+
1245
+ for (const [node, declaration] of unsorted_reactive_declarations) {
1246
+ for (const binding of declaration.assignments) {
1247
+ const statements = lookup.get(binding.node.name) ?? [];
1248
+ statements.push([node, declaration]);
1249
+ lookup.set(binding.node.name, statements);
1250
+ }
1251
+ }
1252
+
1253
+ /** @type {Array<[string, string]>} */
1254
+ const edges = [];
1255
+
1256
+ for (const [, { assignments, dependencies }] of unsorted_reactive_declarations) {
1257
+ for (const assignment of assignments) {
1258
+ for (const dependency of dependencies) {
1259
+ if (!assignments.has(dependency)) {
1260
+ edges.push([assignment.node.name, dependency.node.name]);
1261
+ }
1262
+ }
1263
+ }
1264
+ }
1265
+
1266
+ const cycle = check_graph_for_cycles(edges);
1267
+ if (cycle?.length) {
1268
+ const declaration = /** @type {Tuple[]} */ (lookup.get(cycle[0]))[0];
1269
+ e.reactive_declaration_cycle(declaration[0], cycle.join(' → '));
1270
+ }
1271
+
1272
+ // We use a map and take advantage of the fact that the spec says insertion order is preserved when iterating
1273
+ /** @type {Map<import('estree').LabeledStatement, ReactiveStatement>} */
1274
+ const reactive_declarations = new Map();
1275
+
1276
+ /**
1277
+ *
1278
+ * @param {import('estree').LabeledStatement} node
1279
+ * @param {ReactiveStatement} declaration
1280
+ * @returns
1281
+ */
1282
+ const add_declaration = (node, declaration) => {
1283
+ if ([...reactive_declarations.values()].includes(declaration)) return;
1284
+
1285
+ for (const binding of declaration.dependencies) {
1286
+ if (declaration.assignments.has(binding)) continue;
1287
+ for (const [node, earlier] of lookup.get(binding.node.name) ?? []) {
1288
+ add_declaration(node, earlier);
1289
+ }
1290
+ }
1291
+
1292
+ reactive_declarations.set(node, declaration);
1293
+ };
1294
+
1295
+ for (const [node, declaration] of unsorted_reactive_declarations) {
1296
+ add_declaration(node, declaration);
1297
+ }
1298
+
1299
+ return reactive_declarations;
1300
+ }