@vigla/svelte 0.0.0-stage → 5.57.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 (373) hide show
  1. package/action.d.ts +2 -0
  2. package/animate.d.ts +2 -0
  3. package/compiler/index.js +43266 -0
  4. package/compiler/index.js.map +1 -0
  5. package/compiler/package.json +3 -0
  6. package/compiler.d.ts +2 -0
  7. package/dist/compiler/diagnostics.d.ts +70 -0
  8. package/dist/compiler/diagnostics.d.ts.map +1 -0
  9. package/dist/compiler/diagnostics.js +166 -0
  10. package/dist/compiler/diagnostics.js.map +1 -0
  11. package/dist/compiler/index.d.ts +72 -0
  12. package/dist/compiler/index.d.ts.map +1 -0
  13. package/dist/compiler/index.js +178 -0
  14. package/dist/compiler/index.js.map +1 -0
  15. package/dist/compiler/options.d.ts +7 -0
  16. package/dist/compiler/options.d.ts.map +1 -0
  17. package/dist/compiler/options.js +126 -0
  18. package/dist/compiler/options.js.map +1 -0
  19. package/dist/compiler/preprocess/decode.d.ts +3 -0
  20. package/dist/compiler/preprocess/decode.d.ts.map +1 -0
  21. package/dist/compiler/preprocess/decode.js +60 -0
  22. package/dist/compiler/preprocess/decode.js.map +1 -0
  23. package/dist/compiler/preprocess/index.d.ts +27 -0
  24. package/dist/compiler/preprocess/index.d.ts.map +1 -0
  25. package/dist/compiler/preprocess/index.js +208 -0
  26. package/dist/compiler/preprocess/index.js.map +1 -0
  27. package/dist/compiler/preprocess/mapped.d.ts +25 -0
  28. package/dist/compiler/preprocess/mapped.d.ts.map +1 -0
  29. package/dist/compiler/preprocess/mapped.js +129 -0
  30. package/dist/compiler/preprocess/mapped.js.map +1 -0
  31. package/dist/compiler/proxy.d.ts +3 -0
  32. package/dist/compiler/proxy.d.ts.map +1 -0
  33. package/dist/compiler/proxy.js +133 -0
  34. package/dist/compiler/proxy.js.map +1 -0
  35. package/dist/entries/action.d.ts +2 -0
  36. package/dist/entries/action.d.ts.map +1 -0
  37. package/dist/entries/action.js +1 -0
  38. package/dist/entries/action.js.map +1 -0
  39. package/dist/entries/animate.d.ts +2 -0
  40. package/dist/entries/animate.d.ts.map +1 -0
  41. package/dist/entries/animate.js +2 -0
  42. package/dist/entries/animate.js.map +1 -0
  43. package/dist/entries/attachments.d.ts +2 -0
  44. package/dist/entries/attachments.d.ts.map +1 -0
  45. package/dist/entries/attachments.js +2 -0
  46. package/dist/entries/attachments.js.map +1 -0
  47. package/dist/entries/context.d.ts +15 -0
  48. package/dist/entries/context.d.ts.map +1 -0
  49. package/dist/entries/context.js +32 -0
  50. package/dist/entries/context.js.map +1 -0
  51. package/dist/entries/easing.d.ts +2 -0
  52. package/dist/entries/easing.d.ts.map +1 -0
  53. package/dist/entries/easing.js +2 -0
  54. package/dist/entries/easing.js.map +1 -0
  55. package/dist/entries/events.d.ts +2 -0
  56. package/dist/entries/events.d.ts.map +1 -0
  57. package/dist/entries/events.js +2 -0
  58. package/dist/entries/events.js.map +1 -0
  59. package/dist/entries/index-server.d.ts +4 -0
  60. package/dist/entries/index-server.d.ts.map +1 -0
  61. package/dist/entries/index-server.js +11 -0
  62. package/dist/entries/index-server.js.map +1 -0
  63. package/dist/entries/index.d.ts +10 -0
  64. package/dist/entries/index.d.ts.map +1 -0
  65. package/dist/entries/index.js +24 -0
  66. package/dist/entries/index.js.map +1 -0
  67. package/dist/entries/internal/client.d.ts +4 -0
  68. package/dist/entries/internal/client.d.ts.map +1 -0
  69. package/dist/entries/internal/client.js +9 -0
  70. package/dist/entries/internal/client.js.map +1 -0
  71. package/dist/entries/internal/disclose-version.d.ts +2 -0
  72. package/dist/entries/internal/disclose-version.d.ts.map +1 -0
  73. package/dist/entries/internal/disclose-version.js +4 -0
  74. package/dist/entries/internal/disclose-version.js.map +1 -0
  75. package/dist/entries/internal/index.d.ts +2 -0
  76. package/dist/entries/internal/index.d.ts.map +1 -0
  77. package/dist/entries/internal/index.js +2 -0
  78. package/dist/entries/internal/index.js.map +1 -0
  79. package/dist/entries/internal/server.d.ts +2 -0
  80. package/dist/entries/internal/server.d.ts.map +1 -0
  81. package/dist/entries/internal/server.js +7 -0
  82. package/dist/entries/internal/server.js.map +1 -0
  83. package/dist/entries/internal/tracing.d.ts +2 -0
  84. package/dist/entries/internal/tracing.d.ts.map +1 -0
  85. package/dist/entries/internal/tracing.js +2 -0
  86. package/dist/entries/internal/tracing.js.map +1 -0
  87. package/dist/entries/motion-server.d.ts +2 -0
  88. package/dist/entries/motion-server.d.ts.map +1 -0
  89. package/dist/entries/motion-server.js +2 -0
  90. package/dist/entries/motion-server.js.map +1 -0
  91. package/dist/entries/motion.d.ts +2 -0
  92. package/dist/entries/motion.d.ts.map +1 -0
  93. package/dist/entries/motion.js +2 -0
  94. package/dist/entries/motion.js.map +1 -0
  95. package/dist/entries/proxy.d.ts +6 -0
  96. package/dist/entries/proxy.d.ts.map +1 -0
  97. package/dist/entries/proxy.js +77 -0
  98. package/dist/entries/proxy.js.map +1 -0
  99. package/dist/entries/reactivity-server.d.ts +2 -0
  100. package/dist/entries/reactivity-server.d.ts.map +1 -0
  101. package/dist/entries/reactivity-server.js +2 -0
  102. package/dist/entries/reactivity-server.js.map +1 -0
  103. package/dist/entries/reactivity.d.ts +2 -0
  104. package/dist/entries/reactivity.d.ts.map +1 -0
  105. package/dist/entries/reactivity.js +2 -0
  106. package/dist/entries/reactivity.js.map +1 -0
  107. package/dist/entries/report.d.ts +3 -0
  108. package/dist/entries/report.d.ts.map +1 -0
  109. package/dist/entries/report.js +66 -0
  110. package/dist/entries/report.js.map +1 -0
  111. package/dist/entries/server.d.ts +8 -0
  112. package/dist/entries/server.d.ts.map +1 -0
  113. package/dist/entries/server.js +48 -0
  114. package/dist/entries/server.js.map +1 -0
  115. package/dist/entries/store-client.d.ts +12 -0
  116. package/dist/entries/store-client.d.ts.map +1 -0
  117. package/dist/entries/store-client.js +63 -0
  118. package/dist/entries/store-client.js.map +1 -0
  119. package/dist/entries/store-server.d.ts +12 -0
  120. package/dist/entries/store-server.d.ts.map +1 -0
  121. package/dist/entries/store-server.js +30 -0
  122. package/dist/entries/store-server.js.map +1 -0
  123. package/dist/entries/store.d.ts +25 -0
  124. package/dist/entries/store.d.ts.map +1 -0
  125. package/dist/entries/store.js +139 -0
  126. package/dist/entries/store.js.map +1 -0
  127. package/dist/entries/transition.d.ts +2 -0
  128. package/dist/entries/transition.d.ts.map +1 -0
  129. package/dist/entries/transition.js +2 -0
  130. package/dist/entries/transition.js.map +1 -0
  131. package/dist/entries/window-server.d.ts +2 -0
  132. package/dist/entries/window-server.d.ts.map +1 -0
  133. package/dist/entries/window-server.js +2 -0
  134. package/dist/entries/window-server.js.map +1 -0
  135. package/dist/entries/window.d.ts +2 -0
  136. package/dist/entries/window.d.ts.map +1 -0
  137. package/dist/entries/window.js +2 -0
  138. package/dist/entries/window.js.map +1 -0
  139. package/dist/front/ast.d.ts +290 -0
  140. package/dist/front/ast.d.ts.map +1 -0
  141. package/dist/front/ast.js +1 -0
  142. package/dist/front/ast.js.map +1 -0
  143. package/dist/front/diagnostics.d.ts +13 -0
  144. package/dist/front/diagnostics.d.ts.map +1 -0
  145. package/dist/front/diagnostics.js +38 -0
  146. package/dist/front/diagnostics.js.map +1 -0
  147. package/dist/front/ignores.d.ts +12 -0
  148. package/dist/front/ignores.d.ts.map +1 -0
  149. package/dist/front/ignores.js +75 -0
  150. package/dist/front/ignores.js.map +1 -0
  151. package/dist/front/index.d.ts +17 -0
  152. package/dist/front/index.d.ts.map +1 -0
  153. package/dist/front/index.js +65 -0
  154. package/dist/front/index.js.map +1 -0
  155. package/dist/front/legacy.d.ts +5 -0
  156. package/dist/front/legacy.d.ts.map +1 -0
  157. package/dist/front/legacy.js +408 -0
  158. package/dist/front/legacy.js.map +1 -0
  159. package/dist/front/locate.d.ts +4 -0
  160. package/dist/front/locate.d.ts.map +1 -0
  161. package/dist/front/locate.js +19 -0
  162. package/dist/front/locate.js.map +1 -0
  163. package/dist/front/lower.d.ts +39 -0
  164. package/dist/front/lower.d.ts.map +1 -0
  165. package/dist/front/lower.js +470 -0
  166. package/dist/front/lower.js.map +1 -0
  167. package/dist/front/parse/attribute.d.ts +12 -0
  168. package/dist/front/parse/attribute.d.ts.map +1 -0
  169. package/dist/front/parse/attribute.js +288 -0
  170. package/dist/front/parse/attribute.js.map +1 -0
  171. package/dist/front/parse/bracket.d.ts +3 -0
  172. package/dist/front/parse/bracket.d.ts.map +1 -0
  173. package/dist/front/parse/bracket.js +102 -0
  174. package/dist/front/parse/bracket.js.map +1 -0
  175. package/dist/front/parse/characters.d.ts +4 -0
  176. package/dist/front/parse/characters.d.ts.map +1 -0
  177. package/dist/front/parse/characters.js +6 -0
  178. package/dist/front/parse/characters.js.map +1 -0
  179. package/dist/front/parse/decode.d.ts +2 -0
  180. package/dist/front/parse/decode.d.ts.map +1 -0
  181. package/dist/front/parse/decode.js +89 -0
  182. package/dist/front/parse/decode.js.map +1 -0
  183. package/dist/front/parse/element.d.ts +3 -0
  184. package/dist/front/parse/element.d.ts.map +1 -0
  185. package/dist/front/parse/element.js +311 -0
  186. package/dist/front/parse/element.js.map +1 -0
  187. package/dist/front/parse/entities.d.ts +2 -0
  188. package/dist/front/parse/entities.d.ts.map +1 -0
  189. package/dist/front/parse/entities.js +2234 -0
  190. package/dist/front/parse/entities.js.map +1 -0
  191. package/dist/front/parse/expression.d.ts +5 -0
  192. package/dist/front/parse/expression.d.ts.map +1 -0
  193. package/dist/front/parse/expression.js +86 -0
  194. package/dist/front/parse/expression.js.map +1 -0
  195. package/dist/front/parse/html.d.ts +8 -0
  196. package/dist/front/parse/html.d.ts.map +1 -0
  197. package/dist/front/parse/html.js +146 -0
  198. package/dist/front/parse/html.js.map +1 -0
  199. package/dist/front/parse/identifier.d.ts +4 -0
  200. package/dist/front/parse/identifier.d.ts.map +1 -0
  201. package/dist/front/parse/identifier.js +24 -0
  202. package/dist/front/parse/identifier.js.map +1 -0
  203. package/dist/front/parse/index.d.ts +13 -0
  204. package/dist/front/parse/index.d.ts.map +1 -0
  205. package/dist/front/parse/index.js +74 -0
  206. package/dist/front/parse/index.js.map +1 -0
  207. package/dist/front/parse/js.d.ts +27 -0
  208. package/dist/front/parse/js.d.ts.map +1 -0
  209. package/dist/front/parse/js.js +241 -0
  210. package/dist/front/parse/js.js.map +1 -0
  211. package/dist/front/parse/options.d.ts +3 -0
  212. package/dist/front/parse/options.d.ts.map +1 -0
  213. package/dist/front/parse/options.js +198 -0
  214. package/dist/front/parse/options.js.map +1 -0
  215. package/dist/front/parse/parser.d.ts +50 -0
  216. package/dist/front/parse/parser.d.ts.map +1 -0
  217. package/dist/front/parse/parser.js +157 -0
  218. package/dist/front/parse/parser.js.map +1 -0
  219. package/dist/front/parse/pattern.d.ts +4 -0
  220. package/dist/front/parse/pattern.d.ts.map +1 -0
  221. package/dist/front/parse/pattern.js +53 -0
  222. package/dist/front/parse/pattern.js.map +1 -0
  223. package/dist/front/parse/script.d.ts +4 -0
  224. package/dist/front/parse/script.d.ts.map +1 -0
  225. package/dist/front/parse/script.js +60 -0
  226. package/dist/front/parse/script.js.map +1 -0
  227. package/dist/front/parse/style.d.ts +7 -0
  228. package/dist/front/parse/style.d.ts.map +1 -0
  229. package/dist/front/parse/style.js +397 -0
  230. package/dist/front/parse/style.js.map +1 -0
  231. package/dist/front/parse/tag.d.ts +3 -0
  232. package/dist/front/parse/tag.d.ts.map +1 -0
  233. package/dist/front/parse/tag.js +591 -0
  234. package/dist/front/parse/tag.js.map +1 -0
  235. package/dist/front/print/css.d.ts +5 -0
  236. package/dist/front/print/css.d.ts.map +1 -0
  237. package/dist/front/print/css.js +234 -0
  238. package/dist/front/print/css.js.map +1 -0
  239. package/dist/front/print/index.d.ts +18 -0
  240. package/dist/front/print/index.d.ts.map +1 -0
  241. package/dist/front/print/index.js +24 -0
  242. package/dist/front/print/index.js.map +1 -0
  243. package/dist/front/print/layout.d.ts +11 -0
  244. package/dist/front/print/layout.d.ts.map +1 -0
  245. package/dist/front/print/layout.js +73 -0
  246. package/dist/front/print/layout.js.map +1 -0
  247. package/dist/front/print/template.d.ts +5 -0
  248. package/dist/front/print/template.d.ts.map +1 -0
  249. package/dist/front/print/template.js +455 -0
  250. package/dist/front/print/template.js.map +1 -0
  251. package/dist/front/runes.d.ts +13 -0
  252. package/dist/front/runes.d.ts.map +1 -0
  253. package/dist/front/runes.js +253 -0
  254. package/dist/front/runes.js.map +1 -0
  255. package/dist/front/stores.d.ts +5 -0
  256. package/dist/front/stores.d.ts.map +1 -0
  257. package/dist/front/stores.js +84 -0
  258. package/dist/front/stores.js.map +1 -0
  259. package/dist/front/typescript.d.ts +2 -0
  260. package/dist/front/typescript.d.ts.map +1 -0
  261. package/dist/front/typescript.js +182 -0
  262. package/dist/front/typescript.js.map +1 -0
  263. package/dist/front/validate/anchors.d.ts +15 -0
  264. package/dist/front/validate/anchors.d.ts.map +1 -0
  265. package/dist/front/validate/anchors.js +43 -0
  266. package/dist/front/validate/anchors.js.map +1 -0
  267. package/dist/front/validate/index.d.ts +16 -0
  268. package/dist/front/validate/index.d.ts.map +1 -0
  269. package/dist/front/validate/index.js +139 -0
  270. package/dist/front/validate/index.js.map +1 -0
  271. package/dist/front/validate/legacy.d.ts +9 -0
  272. package/dist/front/validate/legacy.d.ts.map +1 -0
  273. package/dist/front/validate/legacy.js +102 -0
  274. package/dist/front/validate/legacy.js.map +1 -0
  275. package/dist/front/validate/report.d.ts +14 -0
  276. package/dist/front/validate/report.d.ts.map +1 -0
  277. package/dist/front/validate/report.js +29 -0
  278. package/dist/front/validate/report.js.map +1 -0
  279. package/dist/front/validate/template.d.ts +31 -0
  280. package/dist/front/validate/template.d.ts.map +1 -0
  281. package/dist/front/validate/template.js +507 -0
  282. package/dist/front/validate/template.js.map +1 -0
  283. package/dist/front/wording.d.ts +4 -0
  284. package/dist/front/wording.d.ts.map +1 -0
  285. package/dist/front/wording.js +110 -0
  286. package/dist/front/wording.js.map +1 -0
  287. package/dist/shared/format.d.ts +3 -0
  288. package/dist/shared/format.d.ts.map +1 -0
  289. package/dist/shared/format.js +7 -0
  290. package/dist/shared/format.js.map +1 -0
  291. package/easing.d.ts +2 -0
  292. package/elements.d.ts +1220 -0
  293. package/index.d.ts +2 -0
  294. package/motion.d.ts +2 -0
  295. package/package.json +128 -5
  296. package/src/compiler/diagnostics.ts +233 -0
  297. package/src/compiler/index.ts +292 -0
  298. package/src/compiler/options.ts +140 -0
  299. package/src/compiler/preprocess/decode.ts +85 -0
  300. package/src/compiler/preprocess/index.ts +299 -0
  301. package/src/compiler/preprocess/mapped.ts +146 -0
  302. package/src/compiler/proxy.ts +154 -0
  303. package/src/entries/action.ts +1 -0
  304. package/src/entries/animate.ts +1 -0
  305. package/src/entries/attachments.ts +1 -0
  306. package/src/entries/context.ts +50 -0
  307. package/src/entries/easing.ts +1 -0
  308. package/src/entries/events.ts +1 -0
  309. package/src/entries/index-server.ts +17 -0
  310. package/src/entries/index.ts +41 -0
  311. package/src/entries/internal/client.ts +15 -0
  312. package/src/entries/internal/disclose-version.ts +4 -0
  313. package/src/entries/internal/index.ts +3 -0
  314. package/src/entries/internal/server.ts +8 -0
  315. package/src/entries/internal/tracing.ts +1 -0
  316. package/src/entries/motion-server.ts +1 -0
  317. package/src/entries/motion.ts +1 -0
  318. package/src/entries/proxy.ts +86 -0
  319. package/src/entries/reactivity-server.ts +9 -0
  320. package/src/entries/reactivity.ts +9 -0
  321. package/src/entries/report.ts +81 -0
  322. package/src/entries/server.ts +76 -0
  323. package/src/entries/store-client.ts +80 -0
  324. package/src/entries/store-server.ts +44 -0
  325. package/src/entries/store.ts +201 -0
  326. package/src/entries/transition.ts +1 -0
  327. package/src/entries/window-server.ts +1 -0
  328. package/src/entries/window.ts +1 -0
  329. package/src/front/ast.ts +369 -0
  330. package/src/front/diagnostics.ts +53 -0
  331. package/src/front/ignores.ts +84 -0
  332. package/src/front/index.ts +86 -0
  333. package/src/front/legacy.ts +414 -0
  334. package/src/front/locate.ts +20 -0
  335. package/src/front/lower.ts +509 -0
  336. package/src/front/parse/attribute.ts +319 -0
  337. package/src/front/parse/bracket.ts +99 -0
  338. package/src/front/parse/characters.ts +19 -0
  339. package/src/front/parse/decode.ts +87 -0
  340. package/src/front/parse/element.ts +354 -0
  341. package/src/front/parse/entities.ts +2233 -0
  342. package/src/front/parse/expression.ts +85 -0
  343. package/src/front/parse/html.ts +158 -0
  344. package/src/front/parse/identifier.ts +29 -0
  345. package/src/front/parse/index.ts +88 -0
  346. package/src/front/parse/js.ts +284 -0
  347. package/src/front/parse/options.ts +194 -0
  348. package/src/front/parse/parser.ts +189 -0
  349. package/src/front/parse/pattern.ts +57 -0
  350. package/src/front/parse/script.ts +74 -0
  351. package/src/front/parse/style.ts +399 -0
  352. package/src/front/parse/tag.ts +601 -0
  353. package/src/front/print/css.ts +239 -0
  354. package/src/front/print/index.ts +40 -0
  355. package/src/front/print/layout.ts +87 -0
  356. package/src/front/print/template.ts +448 -0
  357. package/src/front/runes.ts +267 -0
  358. package/src/front/stores.ts +98 -0
  359. package/src/front/typescript.ts +178 -0
  360. package/src/front/validate/anchors.ts +54 -0
  361. package/src/front/validate/index.ts +174 -0
  362. package/src/front/validate/legacy.ts +119 -0
  363. package/src/front/validate/report.ts +38 -0
  364. package/src/front/validate/template.ts +549 -0
  365. package/src/front/wording.ts +112 -0
  366. package/src/shared/format.ts +8 -0
  367. package/store.d.ts +2 -0
  368. package/svelte-html.d.ts +53 -0
  369. package/transition.d.ts +2 -0
  370. package/types/compiler/interfaces.d.ts +2 -0
  371. package/types/compiler/preprocess.d.ts +2 -0
  372. package/types/index.d.ts +1453 -0
  373. package/README.md +0 -3
@@ -0,0 +1,448 @@
1
+ import type { Context, Visitors } from 'esrap';
2
+ import type * as AST from '../ast.ts';
3
+ import { isVoid } from '../parse/html.ts';
4
+ import { attributes, block, lineBreak, type State } from './layout.ts';
5
+
6
+ type Node = { type: string; [key: string]: unknown };
7
+
8
+ const blockElements = new Set([
9
+ 'RegularElement',
10
+ 'Component',
11
+ 'SvelteBody',
12
+ 'SvelteHead',
13
+ 'SvelteFragment',
14
+ 'SvelteBoundary',
15
+ 'SvelteDocument',
16
+ 'SvelteSelf',
17
+ 'SvelteWindow',
18
+ 'SvelteComponent',
19
+ 'SvelteElement',
20
+ 'SlotElement',
21
+ 'TitleElement'
22
+ ]);
23
+
24
+ const startsWithSpace = /^\s/;
25
+ const endsWithSpace = /\s$/;
26
+ const whitespaceRun = /[^\S]+/g;
27
+ const lineBreakChar = /[\r\n]/;
28
+
29
+ interface Item {
30
+ nodes: Node[];
31
+ leading: boolean;
32
+ }
33
+
34
+ function directive(
35
+ context: Context,
36
+ prefix: string,
37
+ node: AST.Directive,
38
+ withModifiers: boolean
39
+ ): void {
40
+ context.write(`${prefix}:${node.name}`);
41
+ if (withModifiers) for (const modifier of node.modifiers) context.write(`|${modifier}`);
42
+ const expression = node.expression as { type: string; name?: string } | null;
43
+ if (expression !== null && !(expression.type === 'Identifier' && expression.name === node.name)) {
44
+ context.write('={');
45
+ context.visit(expression);
46
+ context.write('}');
47
+ }
48
+ }
49
+
50
+ export function templateVisitors(comments: readonly AST.JSComment[], state: State): Visitors {
51
+ const preserved = (): boolean => state.preserve > 0;
52
+
53
+ const element = (node: AST.ElementLike, context: Context): void => {
54
+ const name = node.name.toLowerCase();
55
+ const preserve =
56
+ (node.type === 'RegularElement' || node.type === 'TitleElement') &&
57
+ (name === 'pre' || name === 'textarea' || name === 'title');
58
+ if (preserve) state.preserve += 1;
59
+ const child = context.new();
60
+ child.write(`<${node.name}`);
61
+ const multiline = attributes(node, node.attributes, child, comments);
62
+ const selfClosing =
63
+ isVoid(node.name) || (node.type === 'Component' && node.fragment.nodes.length === 0);
64
+ if (name === '!doctype') child.write('>');
65
+ else if (selfClosing) child.write(`${multiline ? '' : ' '}/>`);
66
+ else {
67
+ child.write('>');
68
+ block(child, node.fragment, preserved(), true);
69
+ child.write(`</${node.name}>`);
70
+ }
71
+ context.append(child);
72
+ if (preserve) state.preserve -= 1;
73
+ };
74
+
75
+ const fragment = (node: AST.Fragment, context: Context): void => {
76
+ if (preserved()) {
77
+ for (const child of node.nodes) {
78
+ context.visit(child);
79
+ context.multiline ||= child.type === 'Text' && lineBreakChar.test(child.data);
80
+ }
81
+ return;
82
+ }
83
+ const nodes = node.nodes;
84
+ const first = nodes[0];
85
+ const last = nodes.at(-1);
86
+ const surrounded =
87
+ first?.type === 'Text' &&
88
+ startsWithSpace.test(first.data) &&
89
+ last?.type === 'Text' &&
90
+ endsWithSpace.test(last.data);
91
+
92
+ const items: Item[] = [];
93
+ let sequence: Node[] = [];
94
+ let leading = false;
95
+ const flush = (): void => {
96
+ if (sequence.length > 0) {
97
+ items.push({ nodes: sequence, leading });
98
+ sequence = [];
99
+ leading = false;
100
+ }
101
+ };
102
+
103
+ for (let index = 0; index < nodes.length; index += 1) {
104
+ const child = nodes[index] as AST.TemplateNode;
105
+ const previous = nodes[index - 1];
106
+ const following = nodes[index + 1];
107
+ if (child.type !== 'Text') {
108
+ const isBlock = blockElements.has(child.type);
109
+ if (isBlock && sequence.length > 0) flush();
110
+ sequence.push(child as unknown as Node);
111
+ if (isBlock) flush();
112
+ continue;
113
+ }
114
+ let data = child.data.replace(whitespaceRun, ' ');
115
+ if (index === 0) data = data.trimStart();
116
+ if (index === nodes.length - 1) data = data.trimEnd();
117
+ if (data === '') continue;
118
+ if (data.startsWith(' ') && previous && previous.type !== 'ExpressionTag') {
119
+ flush();
120
+ leading = true;
121
+ data = data.trimStart();
122
+ }
123
+ if (data !== '') {
124
+ sequence.push({ ...child, data } as unknown as Node);
125
+ if (data.endsWith(' ') && following && following.type !== 'ExpressionTag') flush();
126
+ }
127
+ }
128
+ flush();
129
+
130
+ let multiline = false;
131
+ let width = 0;
132
+ const contexts = items.map((item) => {
133
+ const child = context.new();
134
+ for (const part of item.nodes) {
135
+ child.visit(part);
136
+ multiline ||= child.multiline;
137
+ }
138
+ width += child.measure() + (item.leading ? 1 : 0);
139
+ return { context: child, leading: item.leading };
140
+ });
141
+ multiline ||= width > lineBreak;
142
+ context.multiline ||= surrounded && width > lineBreak * 2;
143
+
144
+ for (let index = 0; index < contexts.length; index += 1) {
145
+ const current = contexts[index] as { context: Context; leading: boolean };
146
+ const following = contexts[index + 1];
147
+ context.append(current.context);
148
+ if (following === undefined) continue;
149
+ if (current.context.multiline || following.context.multiline) {
150
+ context.margin();
151
+ context.newline();
152
+ } else if (multiline) {
153
+ context.newline();
154
+ } else if (following.leading) {
155
+ context.write(' ');
156
+ }
157
+ }
158
+ };
159
+
160
+ const dynamic = (
161
+ node: AST.ElementLike,
162
+ context: Context,
163
+ tag: string,
164
+ value: unknown,
165
+ inline: boolean
166
+ ): void => {
167
+ context.write(`<${tag}${tag === 'svelte:element' ? ' ' : ' '}this={`);
168
+ context.visit(value as Node);
169
+ context.write('}');
170
+ attributes(node, node.attributes, context, comments);
171
+ if (node.fragment.nodes.length > 0) {
172
+ context.write('>');
173
+ block(context, node.fragment, preserved(), inline);
174
+ context.write(`</${tag}>`);
175
+ } else {
176
+ context.write(' />');
177
+ }
178
+ };
179
+
180
+ const visitors: Record<string, (node: never, context: Context) => void> = {
181
+ Root(node: AST.Root, context: Context) {
182
+ if (node.options) {
183
+ context.write('<svelte:options');
184
+ for (const attribute of node.options.attributes) {
185
+ context.write(' ');
186
+ context.visit(attribute);
187
+ }
188
+ context.write(' />');
189
+ }
190
+ let started = false;
191
+ for (const item of [node.module, node.instance, node.fragment, node.css]) {
192
+ if (!item) continue;
193
+ if (started) {
194
+ context.margin();
195
+ context.newline();
196
+ }
197
+ context.visit(item);
198
+ started = true;
199
+ }
200
+ },
201
+ Script(node: AST.Script, context: Context) {
202
+ context.write('<script');
203
+ attributes(node, node.attributes, context, comments);
204
+ context.write('>');
205
+ block(context, node.content, preserved());
206
+ context.write('</script>');
207
+ },
208
+ Fragment: fragment,
209
+ AnimateDirective(node: AST.Directive, context: Context) {
210
+ directive(context, 'animate', node, false);
211
+ },
212
+ AttachTag(node: AST.AttachTag, context: Context) {
213
+ context.write('{@attach ');
214
+ context.visit(node.expression);
215
+ context.write('}');
216
+ },
217
+ Attribute(node: AST.Attribute, context: Context) {
218
+ context.write(node.name);
219
+ if (node.value === true) return;
220
+ context.write('=');
221
+ if (!Array.isArray(node.value)) {
222
+ context.visit(node.value);
223
+ return;
224
+ }
225
+ const quoted = node.value.length > 1 || node.value[0]?.type === 'Text';
226
+ if (quoted) context.write('"');
227
+ for (const chunk of node.value) context.visit(chunk);
228
+ if (quoted) context.write('"');
229
+ },
230
+ AwaitBlock(node: AST.AwaitBlock, context: Context) {
231
+ context.write('{#await ');
232
+ context.visit(node.expression);
233
+ if (node.pending) {
234
+ context.write('}');
235
+ block(context, node.pending, preserved());
236
+ if (node.then || node.catch) context.write('{:');
237
+ } else {
238
+ context.write(' ');
239
+ }
240
+ if (node.then) {
241
+ context.write(node.value ? 'then ' : 'then');
242
+ if (node.value) context.visit(node.value);
243
+ context.write('}');
244
+ block(context, node.then, preserved());
245
+ if (node.catch) context.write('{:');
246
+ }
247
+ if (node.catch) {
248
+ context.write(node.error ? 'catch ' : 'catch');
249
+ if (node.error) context.visit(node.error);
250
+ context.write('}');
251
+ block(context, node.catch, preserved());
252
+ }
253
+ context.write('{/await}');
254
+ },
255
+ BindDirective(node: AST.Directive, context: Context) {
256
+ context.write(`bind:${node.name}`);
257
+ const expression = node.expression as ES;
258
+ if (expression.type === 'Identifier' && expression.name === node.name) return;
259
+ context.write('={');
260
+ if (expression.type === 'SequenceExpression') {
261
+ const [getter, setter] = expression.expressions as Node[];
262
+ context.visit(getter as Node);
263
+ context.write(', ');
264
+ context.visit(setter as Node);
265
+ } else {
266
+ context.visit(expression);
267
+ }
268
+ context.write('}');
269
+ },
270
+ ClassDirective(node: AST.Directive, context: Context) {
271
+ directive(context, 'class', node, false);
272
+ },
273
+ Comment(node: AST.Comment, context: Context) {
274
+ context.write(`<!--${node.data}-->`);
275
+ },
276
+ ConstTag(node: AST.ConstTag, context: Context) {
277
+ context.write('{@const ');
278
+ node.declaration.declarations.forEach((declarator, index) => {
279
+ if (index > 0) context.write(', ');
280
+ context.visit(declarator);
281
+ });
282
+ context.write('}');
283
+ },
284
+ DeclarationTag(node: AST.DeclarationTag, context: Context) {
285
+ context.write('{');
286
+ const open = context.new();
287
+ const join = context.new();
288
+ const child = context.new();
289
+ context.append(child);
290
+ child.write(`${node.declaration.kind} `);
291
+ child.append(open);
292
+ const declarations = node.declaration.declarations;
293
+ declarations.forEach((declarator, index) => {
294
+ if (index > 0) child.append(join);
295
+ child.visit(declarator);
296
+ });
297
+ const length = child.measure() + 2 * (declarations.length - 1);
298
+ if (child.multiline || (declarations.length > 1 && length > 50)) {
299
+ context.multiline = true;
300
+ if (declarations.length > 1) open.indent();
301
+ join.write(',');
302
+ join.newline();
303
+ if (declarations.length > 1) context.dedent();
304
+ } else {
305
+ join.write(', ');
306
+ }
307
+ context.write('}');
308
+ },
309
+ DebugTag(node: AST.DebugTag, context: Context) {
310
+ context.write('{@debug ');
311
+ node.identifiers.forEach((identifier, index) => {
312
+ if (index > 0) context.write(', ');
313
+ context.visit(identifier);
314
+ });
315
+ context.write('}');
316
+ },
317
+ EachBlock(node: AST.EachBlock, context: Context) {
318
+ context.write('{#each ');
319
+ context.visit(node.expression);
320
+ if (node.context) {
321
+ context.write(' as ');
322
+ context.visit(node.context);
323
+ }
324
+ if (node.index) context.write(`, ${node.index}`);
325
+ if (node.key) {
326
+ context.write(' (');
327
+ context.visit(node.key);
328
+ context.write(')');
329
+ }
330
+ context.write('}');
331
+ block(context, node.body, preserved());
332
+ if (node.fallback) {
333
+ context.write('{:else}');
334
+ block(context, node.fallback, preserved());
335
+ }
336
+ context.write('{/each}');
337
+ },
338
+ ExpressionTag(node: AST.ExpressionTag, context: Context) {
339
+ context.write('{');
340
+ context.visit(node.expression);
341
+ context.write('}');
342
+ },
343
+ HtmlTag(node: AST.HtmlTag, context: Context) {
344
+ context.write('{@html ');
345
+ context.visit(node.expression);
346
+ context.write('}');
347
+ },
348
+ IfBlock(node: AST.IfBlock, context: Context) {
349
+ context.write(node.elseif ? '{:else if ' : '{#if ');
350
+ context.visit(node.test);
351
+ context.write('}');
352
+ block(context, node.consequent, preserved());
353
+ if (node.alternate !== null) {
354
+ const only = node.alternate.nodes[0];
355
+ if (node.alternate.nodes.length === 1 && only?.type === 'IfBlock' && only.elseif) {
356
+ context.visit(node.alternate);
357
+ } else {
358
+ context.write('{:else}');
359
+ block(context, node.alternate, preserved());
360
+ }
361
+ }
362
+ if (!node.elseif) context.write('{/if}');
363
+ },
364
+ KeyBlock(node: AST.KeyBlock, context: Context) {
365
+ context.write('{#key ');
366
+ context.visit(node.expression);
367
+ context.write('}');
368
+ block(context, node.fragment, preserved());
369
+ context.write('{/key}');
370
+ },
371
+ LetDirective(node: AST.Directive, context: Context) {
372
+ directive(context, 'let', node, false);
373
+ },
374
+ OnDirective(node: AST.Directive, context: Context) {
375
+ directive(context, 'on', node, true);
376
+ },
377
+ RenderTag(node: AST.RenderTag, context: Context) {
378
+ context.write('{@render ');
379
+ context.visit(node.expression);
380
+ context.write('}');
381
+ },
382
+ SnippetBlock(node: AST.SnippetBlock, context: Context) {
383
+ context.write('{#snippet ');
384
+ context.visit(node.expression);
385
+ if (node.typeParams) context.write(`<${node.typeParams}>`);
386
+ context.write('(');
387
+ node.parameters.forEach((parameter, index) => {
388
+ if (index > 0) context.write(', ');
389
+ context.visit(parameter);
390
+ });
391
+ context.write(')}');
392
+ block(context, node.body, preserved());
393
+ context.write('{/snippet}');
394
+ },
395
+ SpreadAttribute(node: AST.SpreadAttribute, context: Context) {
396
+ context.write('{...');
397
+ context.visit(node.expression);
398
+ context.write('}');
399
+ },
400
+ StyleDirective(node: AST.StyleDirective, context: Context) {
401
+ context.write(`style:${node.name}`);
402
+ for (const modifier of node.modifiers) context.write(`|${modifier}`);
403
+ if (node.value === true) return;
404
+ context.write('=');
405
+ if (Array.isArray(node.value)) {
406
+ context.write('"');
407
+ for (const chunk of node.value) context.visit(chunk);
408
+ context.write('"');
409
+ } else {
410
+ context.visit(node.value);
411
+ }
412
+ },
413
+ SvelteComponent(node: AST.ElementLike, context: Context) {
414
+ dynamic(node, context, 'svelte:component', node.expression, true);
415
+ },
416
+ SvelteElement(node: AST.ElementLike, context: Context) {
417
+ dynamic(node, context, 'svelte:element', node.tag, false);
418
+ },
419
+ Text(node: AST.Text, context: Context) {
420
+ context.write(node.data);
421
+ },
422
+ TransitionDirective(node: AST.Directive, context: Context) {
423
+ const prefix = node.intro && node.outro ? 'transition' : node.intro ? 'in' : 'out';
424
+ directive(context, prefix, node, true);
425
+ },
426
+ UseDirective(node: AST.Directive, context: Context) {
427
+ directive(context, 'use', node, false);
428
+ }
429
+ };
430
+ for (const type of [
431
+ 'Component',
432
+ 'RegularElement',
433
+ 'SlotElement',
434
+ 'SvelteBody',
435
+ 'SvelteBoundary',
436
+ 'SvelteDocument',
437
+ 'SvelteFragment',
438
+ 'SvelteHead',
439
+ 'SvelteSelf',
440
+ 'SvelteWindow',
441
+ 'TitleElement'
442
+ ]) {
443
+ visitors[type] = element as (node: never, context: Context) => void;
444
+ }
445
+ return visitors as unknown as Visitors;
446
+ }
447
+
448
+ type ES = Node & { name?: string; expressions?: Node[] };
@@ -0,0 +1,267 @@
1
+ import type * as ES from 'estree';
2
+ import { CompileError, type Rune } from 'vigla/compiler';
3
+
4
+ const known = new Set<string>([
5
+ '$state',
6
+ '$state.raw',
7
+ '$state.snapshot',
8
+ '$state.eager',
9
+ '$derived',
10
+ '$derived.by',
11
+ '$effect',
12
+ '$effect.pre',
13
+ '$effect.root',
14
+ '$effect.tracking',
15
+ '$effect.pending',
16
+ '$props',
17
+ '$props.id',
18
+ '$bindable',
19
+ '$inspect',
20
+ '$inspect.trace',
21
+ '$host'
22
+ ]);
23
+
24
+ const skipped = new Set(['type', 'loc', 'range', 'start', 'end']);
25
+
26
+ interface Scope {
27
+ readonly parent: Scope | null;
28
+ readonly names: ReadonlySet<string>;
29
+ }
30
+
31
+ type Callable = ES.FunctionDeclaration | ES.FunctionExpression | ES.ArrowFunctionExpression;
32
+
33
+ function children(node: ES.Node, each: (child: ES.Node) => void): void {
34
+ for (const key of Object.keys(node)) {
35
+ if (skipped.has(key)) continue;
36
+ const value = (node as unknown as Record<string, unknown>)[key];
37
+ for (const item of Array.isArray(value) ? value : [value]) {
38
+ if (typeof item === 'object' && item !== null && typeof (item as ES.Node).type === 'string') {
39
+ each(item as ES.Node);
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ function patternNames(pattern: ES.Pattern, into: ES.Identifier[]): void {
46
+ switch (pattern.type) {
47
+ case 'Identifier':
48
+ into.push(pattern);
49
+ break;
50
+ case 'ObjectPattern':
51
+ for (const property of pattern.properties)
52
+ patternNames(property.type === 'RestElement' ? property.argument : property.value, into);
53
+ break;
54
+ case 'ArrayPattern':
55
+ for (const element of pattern.elements) if (element !== null) patternNames(element, into);
56
+ break;
57
+ case 'RestElement':
58
+ patternNames(pattern.argument, into);
59
+ break;
60
+ case 'AssignmentPattern':
61
+ patternNames(pattern.left, into);
62
+ break;
63
+ default:
64
+ break;
65
+ }
66
+ }
67
+
68
+ function isCallable(node: ES.Node): node is Callable {
69
+ return (
70
+ node.type === 'FunctionDeclaration' ||
71
+ node.type === 'FunctionExpression' ||
72
+ node.type === 'ArrowFunctionExpression'
73
+ );
74
+ }
75
+
76
+ function declared(statement: ES.Node, into: ES.Identifier[]): void {
77
+ switch (statement.type) {
78
+ case 'VariableDeclaration':
79
+ if (statement.kind !== 'var')
80
+ for (const item of statement.declarations) patternNames(item.id, into);
81
+ break;
82
+ case 'FunctionDeclaration':
83
+ case 'ClassDeclaration':
84
+ if (statement.id) into.push(statement.id);
85
+ break;
86
+ case 'ImportDeclaration':
87
+ for (const specifier of statement.specifiers) into.push(specifier.local);
88
+ break;
89
+ case 'ExportNamedDeclaration':
90
+ if (statement.declaration) declared(statement.declaration, into);
91
+ break;
92
+ case 'ExportDefaultDeclaration': {
93
+ const declaration = statement.declaration;
94
+ if (
95
+ (declaration.type === 'FunctionDeclaration' || declaration.type === 'ClassDeclaration') &&
96
+ declaration.id
97
+ ) {
98
+ into.push(declaration.id);
99
+ }
100
+ break;
101
+ }
102
+ default:
103
+ break;
104
+ }
105
+ }
106
+
107
+ function hoisted(node: ES.Node, into: ES.Identifier[]): void {
108
+ if (node.type === 'VariableDeclaration' && node.kind === 'var') {
109
+ for (const item of node.declarations) patternNames(item.id, into);
110
+ }
111
+ if (isCallable(node)) return;
112
+ children(node, (child) => hoisted(child, into));
113
+ }
114
+
115
+ function lexical(node: ES.Node): ES.Identifier[] {
116
+ const into: ES.Identifier[] = [];
117
+ switch (node.type) {
118
+ case 'Program':
119
+ case 'BlockStatement':
120
+ case 'StaticBlock':
121
+ for (const statement of node.body) declared(statement, into);
122
+ break;
123
+ case 'ForStatement':
124
+ if (node.init?.type === 'VariableDeclaration') declared(node.init, into);
125
+ break;
126
+ case 'ForInStatement':
127
+ case 'ForOfStatement':
128
+ declared(node.left, into);
129
+ break;
130
+ case 'SwitchStatement':
131
+ for (const entry of node.cases)
132
+ for (const statement of entry.consequent) declared(statement, into);
133
+ break;
134
+ case 'CatchClause':
135
+ if (node.param !== null) patternNames(node.param, into);
136
+ break;
137
+ default:
138
+ break;
139
+ }
140
+ return into;
141
+ }
142
+
143
+ function runeName(callee: ES.Node): { rune: Rune; base: string } | null {
144
+ if (callee.type === 'Identifier') {
145
+ return known.has(callee.name) ? { rune: callee.name as Rune, base: callee.name } : null;
146
+ }
147
+ if (
148
+ callee.type === 'MemberExpression' &&
149
+ !callee.computed &&
150
+ callee.object.type === 'Identifier' &&
151
+ callee.property.type === 'Identifier'
152
+ ) {
153
+ const name = `${callee.object.name}.${callee.property.name}`;
154
+ return known.has(name) ? { rune: name as Rune, base: callee.object.name } : null;
155
+ }
156
+ return null;
157
+ }
158
+
159
+ function shadowed(scope: Scope | null, name: string): boolean {
160
+ for (let current = scope; current !== null; current = current.parent) {
161
+ if (current.names.has(name)) return true;
162
+ }
163
+ return false;
164
+ }
165
+
166
+ function reserved(name: ES.Identifier): void {
167
+ if (!name.name.startsWith('$')) return;
168
+ const located = name as ES.Identifier & { start?: number; end?: number };
169
+ const span = { start: located.start ?? 0, end: located.end ?? 0 };
170
+ throw new CompileError(
171
+ name.name === '$'
172
+ ? {
173
+ code: 'dollar_binding_invalid',
174
+ message: 'The $ name is reserved, and cannot be used for variables and imports',
175
+ ...span
176
+ }
177
+ : {
178
+ code: 'dollar_prefix_invalid',
179
+ message: 'The $ prefix is reserved, and cannot be used for variables and imports',
180
+ ...span
181
+ }
182
+ );
183
+ }
184
+
185
+ export class Resolution {
186
+ readonly runes = new Map<ES.Node, Rune>();
187
+ readonly references = new Map<ES.Identifier, string>();
188
+ readonly #seen: ((node: ES.Node) => void) | undefined;
189
+
190
+ constructor(seen?: (node: ES.Node) => void) {
191
+ this.#seen = seen;
192
+ }
193
+
194
+ program(program: ES.Program): void {
195
+ this.visit(program, null, false);
196
+ }
197
+
198
+ expression(node: ES.Node): void {
199
+ this.visit(node, null, true);
200
+ }
201
+
202
+ private scope(parent: Scope | null, names: readonly ES.Identifier[], nested: boolean): Scope {
203
+ if (!nested) for (const name of names) reserved(name);
204
+ return { parent, names: new Set(names.map((name) => name.name)) };
205
+ }
206
+
207
+ private visit(
208
+ node: ES.Node,
209
+ scope: Scope | null,
210
+ nested: boolean,
211
+ parent: ES.Node | null = null
212
+ ): void {
213
+ this.#seen?.(node);
214
+ if (node.type === 'Identifier' && node.name.startsWith('$') && !shadowed(scope, node.name)) {
215
+ const property =
216
+ (parent?.type === 'MemberExpression' && parent.property === node && !parent.computed) ||
217
+ (parent?.type === 'Property' &&
218
+ parent.key === node &&
219
+ parent.value !== node &&
220
+ !parent.computed) ||
221
+ (parent?.type === 'MethodDefinition' && parent.key === node && !parent.computed);
222
+ if (!property) this.references.set(node, node.name);
223
+ }
224
+ if (node.type === 'CallExpression') {
225
+ const found = runeName(node.callee);
226
+ if (found !== null && !shadowed(scope, found.base)) this.runes.set(node.callee, found.rune);
227
+ }
228
+ if (isCallable(node)) {
229
+ const names: ES.Identifier[] = [];
230
+ if (node.type === 'FunctionExpression' && node.id) names.push(node.id);
231
+ for (const param of node.params) patternNames(param, names);
232
+ if (node.body.type === 'BlockStatement') {
233
+ hoisted(node.body, names);
234
+ names.push(...lexical(node.body));
235
+ }
236
+ const inner = this.scope(scope, names, true);
237
+ for (const param of node.params) this.visit(param, inner, true);
238
+ if (node.body.type === 'BlockStatement') {
239
+ for (const statement of node.body.body) this.visit(statement, inner, true);
240
+ } else {
241
+ this.visit(node.body, inner, true);
242
+ }
243
+ return;
244
+ }
245
+ let inner = scope;
246
+ switch (node.type) {
247
+ case 'Program': {
248
+ const names = lexical(node);
249
+ hoisted(node, names);
250
+ inner = this.scope(scope, names, nested);
251
+ break;
252
+ }
253
+ case 'BlockStatement':
254
+ case 'StaticBlock':
255
+ case 'ForStatement':
256
+ case 'ForInStatement':
257
+ case 'ForOfStatement':
258
+ case 'SwitchStatement':
259
+ case 'CatchClause':
260
+ inner = this.scope(scope, lexical(node), nested);
261
+ break;
262
+ default:
263
+ break;
264
+ }
265
+ children(node, (child) => this.visit(child, inner, nested, node));
266
+ }
267
+ }