@mostfeatured/dbi 0.1.47 → 0.2.1

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 (299) hide show
  1. package/dist/src/DBI.d.ts.map +1 -0
  2. package/dist/src/DBI.js.map +1 -0
  3. package/dist/src/Events.d.ts.map +1 -0
  4. package/dist/src/Events.js.map +1 -0
  5. package/dist/src/index.d.ts.map +1 -0
  6. package/dist/src/index.js.map +1 -0
  7. package/dist/src/methods/handleMessageCommands.d.ts.map +1 -0
  8. package/dist/src/methods/handleMessageCommands.js.map +1 -0
  9. package/dist/src/methods/hookEventListeners.d.ts.map +1 -0
  10. package/dist/src/methods/hookEventListeners.js.map +1 -0
  11. package/dist/src/methods/hookInteractionListeners.d.ts.map +1 -0
  12. package/dist/{methods → src/methods}/hookInteractionListeners.js +22 -12
  13. package/dist/src/methods/hookInteractionListeners.js.map +1 -0
  14. package/dist/src/methods/publishInteractions.d.ts.map +1 -0
  15. package/dist/src/methods/publishInteractions.js.map +1 -0
  16. package/dist/src/types/ApplicationRoleConnectionMetadata.d.ts.map +1 -0
  17. package/dist/src/types/ApplicationRoleConnectionMetadata.js.map +1 -0
  18. package/dist/src/types/Builders/ButtonBuilder.d.ts.map +1 -0
  19. package/dist/src/types/Builders/ButtonBuilder.js.map +1 -0
  20. package/dist/src/types/Builders/ChannelSelectMenuBuilder.d.ts.map +1 -0
  21. package/dist/src/types/Builders/ChannelSelectMenuBuilder.js.map +1 -0
  22. package/dist/src/types/Builders/MentionableSelectMenuBuilder.d.ts.map +1 -0
  23. package/dist/src/types/Builders/MentionableSelectMenuBuilder.js.map +1 -0
  24. package/dist/src/types/Builders/ModalBuilder.d.ts.map +1 -0
  25. package/dist/src/types/Builders/ModalBuilder.js.map +1 -0
  26. package/dist/src/types/Builders/RoleSelectMenuBuilder.d.ts.map +1 -0
  27. package/dist/src/types/Builders/RoleSelectMenuBuilder.js.map +1 -0
  28. package/dist/src/types/Builders/StringSelectMenuBuilder.d.ts.map +1 -0
  29. package/dist/src/types/Builders/StringSelectMenuBuilder.js.map +1 -0
  30. package/dist/src/types/Builders/UserSelectMenuBuilder.d.ts.map +1 -0
  31. package/dist/src/types/Builders/UserSelectMenuBuilder.js.map +1 -0
  32. package/dist/src/types/ChatInput/ChatInput.d.ts.map +1 -0
  33. package/dist/src/types/ChatInput/ChatInput.js.map +1 -0
  34. package/dist/{types → src/types}/ChatInput/ChatInputOptions.d.ts +2 -2
  35. package/dist/src/types/ChatInput/ChatInputOptions.d.ts.map +1 -0
  36. package/dist/src/types/ChatInput/ChatInputOptions.js.map +1 -0
  37. package/dist/src/types/Components/Button.d.ts.map +1 -0
  38. package/dist/src/types/Components/Button.js.map +1 -0
  39. package/dist/src/types/Components/ChannelSelectMenu.d.ts.map +1 -0
  40. package/dist/src/types/Components/ChannelSelectMenu.js.map +1 -0
  41. package/dist/src/types/Components/HTMLComponentsV2/HTMLComponentsV2Handlers.d.ts.map +1 -0
  42. package/dist/src/types/Components/HTMLComponentsV2/HTMLComponentsV2Handlers.js.map +1 -0
  43. package/dist/src/types/Components/HTMLComponentsV2/index.d.ts +91 -0
  44. package/dist/src/types/Components/HTMLComponentsV2/index.d.ts.map +1 -0
  45. package/dist/src/types/Components/HTMLComponentsV2/index.js +300 -0
  46. package/dist/src/types/Components/HTMLComponentsV2/index.js.map +1 -0
  47. package/dist/src/types/Components/HTMLComponentsV2/parser.d.ts.map +1 -0
  48. package/dist/{types → src/types}/Components/HTMLComponentsV2/parser.js +11 -4
  49. package/dist/src/types/Components/HTMLComponentsV2/parser.js.map +1 -0
  50. package/dist/src/types/Components/HTMLComponentsV2/svelteParser.d.ts +35 -0
  51. package/dist/src/types/Components/HTMLComponentsV2/svelteParser.d.ts.map +1 -0
  52. package/dist/src/types/Components/HTMLComponentsV2/svelteParser.js +822 -0
  53. package/dist/src/types/Components/HTMLComponentsV2/svelteParser.js.map +1 -0
  54. package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.d.ts +24 -0
  55. package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.d.ts.map +1 -0
  56. package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.js +294 -0
  57. package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.js.map +1 -0
  58. package/dist/src/types/Components/MentionableSelectMenu.d.ts.map +1 -0
  59. package/dist/src/types/Components/MentionableSelectMenu.js.map +1 -0
  60. package/dist/src/types/Components/Modal.d.ts.map +1 -0
  61. package/dist/src/types/Components/Modal.js.map +1 -0
  62. package/dist/src/types/Components/RoleSelectMenu.d.ts.map +1 -0
  63. package/dist/src/types/Components/RoleSelectMenu.js.map +1 -0
  64. package/dist/src/types/Components/StringSelectMenu.d.ts.map +1 -0
  65. package/dist/src/types/Components/StringSelectMenu.js.map +1 -0
  66. package/dist/src/types/Components/UserSelectMenu.d.ts.map +1 -0
  67. package/dist/src/types/Components/UserSelectMenu.js.map +1 -0
  68. package/dist/src/types/Event.d.ts.map +1 -0
  69. package/dist/src/types/Event.js.map +1 -0
  70. package/dist/src/types/Interaction.d.ts.map +1 -0
  71. package/dist/src/types/Interaction.js.map +1 -0
  72. package/dist/src/types/other/CustomEvent.d.ts.map +1 -0
  73. package/dist/src/types/other/CustomEvent.js.map +1 -0
  74. package/dist/src/types/other/FakeMessageInteraction.d.ts.map +1 -0
  75. package/dist/src/types/other/FakeMessageInteraction.js.map +1 -0
  76. package/dist/src/types/other/InteractionLocale.d.ts.map +1 -0
  77. package/dist/src/types/other/InteractionLocale.js.map +1 -0
  78. package/dist/src/types/other/Locale.d.ts.map +1 -0
  79. package/dist/src/types/other/Locale.js.map +1 -0
  80. package/dist/src/types/other/MessageContextMenu.d.ts.map +1 -0
  81. package/dist/src/types/other/MessageContextMenu.js.map +1 -0
  82. package/dist/src/types/other/UserContextMenu.d.ts.map +1 -0
  83. package/dist/src/types/other/UserContextMenu.js.map +1 -0
  84. package/dist/src/utils/MemoryStore.d.ts.map +1 -0
  85. package/dist/src/utils/MemoryStore.js.map +1 -0
  86. package/dist/src/utils/UtilTypes.d.ts.map +1 -0
  87. package/dist/src/utils/UtilTypes.js.map +1 -0
  88. package/dist/src/utils/customId.d.ts.map +1 -0
  89. package/dist/src/utils/customId.js.map +1 -0
  90. package/dist/src/utils/permissions.d.ts.map +1 -0
  91. package/dist/src/utils/permissions.js.map +1 -0
  92. package/dist/src/utils/recursiveImport.d.ts.map +1 -0
  93. package/dist/src/utils/recursiveImport.js.map +1 -0
  94. package/dist/src/utils/recursiveUnload.d.ts.map +1 -0
  95. package/dist/src/utils/recursiveUnload.js.map +1 -0
  96. package/dist/src/utils/unloadModule.d.ts.map +1 -0
  97. package/dist/src/utils/unloadModule.js.map +1 -0
  98. package/dist/test/index.d.ts +2 -0
  99. package/dist/test/index.d.ts.map +1 -0
  100. package/dist/test/index.js +103 -0
  101. package/dist/test/index.js.map +1 -0
  102. package/docs/ADVANCED_FEATURES.md +836 -0
  103. package/docs/API_REFERENCE.md +925 -0
  104. package/docs/CHAT_INPUT.md +807 -0
  105. package/docs/COMPONENTS.md +1035 -0
  106. package/docs/EVENTS.md +564 -0
  107. package/docs/GETTING_STARTED.md +394 -0
  108. package/docs/LOCALIZATION.md +773 -0
  109. package/docs/README.md +341 -0
  110. package/docs/SVELTE_COMPONENTS.md +955 -0
  111. package/generated/globals.d.ts +1 -0
  112. package/generated/index.d.ts +30 -0
  113. package/generated/svelte-dbi.d.ts +588 -0
  114. package/package.json +57 -47
  115. package/readme.md +168 -491
  116. package/src/methods/hookInteractionListeners.ts +23 -12
  117. package/src/types/Components/HTMLComponentsV2/index.ts +353 -12
  118. package/src/types/Components/HTMLComponentsV2/parser.ts +14 -4
  119. package/src/types/Components/HTMLComponentsV2/svelteParser.ts +904 -0
  120. package/src/types/Components/HTMLComponentsV2/svelteRenderer.ts +332 -0
  121. package/test/index.ts +105 -0
  122. package/test/product-showcase.svelte +199 -0
  123. package/tsconfig.json +13 -3
  124. package/dist/DBI.d.ts.map +0 -1
  125. package/dist/DBI.js.map +0 -1
  126. package/dist/Events.d.ts.map +0 -1
  127. package/dist/Events.js.map +0 -1
  128. package/dist/index.d.ts.map +0 -1
  129. package/dist/index.js.map +0 -1
  130. package/dist/methods/handleMessageCommands.d.ts.map +0 -1
  131. package/dist/methods/handleMessageCommands.js.map +0 -1
  132. package/dist/methods/hookEventListeners.d.ts.map +0 -1
  133. package/dist/methods/hookEventListeners.js.map +0 -1
  134. package/dist/methods/hookInteractionListeners.d.ts.map +0 -1
  135. package/dist/methods/hookInteractionListeners.js.map +0 -1
  136. package/dist/methods/publishInteractions.d.ts.map +0 -1
  137. package/dist/methods/publishInteractions.js.map +0 -1
  138. package/dist/types/ApplicationRoleConnectionMetadata.d.ts.map +0 -1
  139. package/dist/types/ApplicationRoleConnectionMetadata.js.map +0 -1
  140. package/dist/types/Builders/ButtonBuilder.d.ts.map +0 -1
  141. package/dist/types/Builders/ButtonBuilder.js.map +0 -1
  142. package/dist/types/Builders/ChannelSelectMenuBuilder.d.ts.map +0 -1
  143. package/dist/types/Builders/ChannelSelectMenuBuilder.js.map +0 -1
  144. package/dist/types/Builders/MentionableSelectMenuBuilder.d.ts.map +0 -1
  145. package/dist/types/Builders/MentionableSelectMenuBuilder.js.map +0 -1
  146. package/dist/types/Builders/ModalBuilder.d.ts.map +0 -1
  147. package/dist/types/Builders/ModalBuilder.js.map +0 -1
  148. package/dist/types/Builders/RoleSelectMenuBuilder.d.ts.map +0 -1
  149. package/dist/types/Builders/RoleSelectMenuBuilder.js.map +0 -1
  150. package/dist/types/Builders/StringSelectMenuBuilder.d.ts.map +0 -1
  151. package/dist/types/Builders/StringSelectMenuBuilder.js.map +0 -1
  152. package/dist/types/Builders/UserSelectMenuBuilder.d.ts.map +0 -1
  153. package/dist/types/Builders/UserSelectMenuBuilder.js.map +0 -1
  154. package/dist/types/ChatInput/ChatInput.d.ts.map +0 -1
  155. package/dist/types/ChatInput/ChatInput.js.map +0 -1
  156. package/dist/types/ChatInput/ChatInputOptions.d.ts.map +0 -1
  157. package/dist/types/ChatInput/ChatInputOptions.js.map +0 -1
  158. package/dist/types/Components/Button.d.ts.map +0 -1
  159. package/dist/types/Components/Button.js.map +0 -1
  160. package/dist/types/Components/ChannelSelectMenu.d.ts.map +0 -1
  161. package/dist/types/Components/ChannelSelectMenu.js.map +0 -1
  162. package/dist/types/Components/HTMLComponentsV2/HTMLComponentsV2Handlers.d.ts.map +0 -1
  163. package/dist/types/Components/HTMLComponentsV2/HTMLComponentsV2Handlers.js.map +0 -1
  164. package/dist/types/Components/HTMLComponentsV2/index.d.ts +0 -19
  165. package/dist/types/Components/HTMLComponentsV2/index.d.ts.map +0 -1
  166. package/dist/types/Components/HTMLComponentsV2/index.js +0 -31
  167. package/dist/types/Components/HTMLComponentsV2/index.js.map +0 -1
  168. package/dist/types/Components/HTMLComponentsV2/parser.d.ts.map +0 -1
  169. package/dist/types/Components/HTMLComponentsV2/parser.js.map +0 -1
  170. package/dist/types/Components/MentionableSelectMenu.d.ts.map +0 -1
  171. package/dist/types/Components/MentionableSelectMenu.js.map +0 -1
  172. package/dist/types/Components/Modal.d.ts.map +0 -1
  173. package/dist/types/Components/Modal.js.map +0 -1
  174. package/dist/types/Components/RoleSelectMenu.d.ts.map +0 -1
  175. package/dist/types/Components/RoleSelectMenu.js.map +0 -1
  176. package/dist/types/Components/StringSelectMenu.d.ts.map +0 -1
  177. package/dist/types/Components/StringSelectMenu.js.map +0 -1
  178. package/dist/types/Components/UserSelectMenu.d.ts.map +0 -1
  179. package/dist/types/Components/UserSelectMenu.js.map +0 -1
  180. package/dist/types/Event.d.ts.map +0 -1
  181. package/dist/types/Event.js.map +0 -1
  182. package/dist/types/Interaction.d.ts.map +0 -1
  183. package/dist/types/Interaction.js.map +0 -1
  184. package/dist/types/other/CustomEvent.d.ts.map +0 -1
  185. package/dist/types/other/CustomEvent.js.map +0 -1
  186. package/dist/types/other/FakeMessageInteraction.d.ts.map +0 -1
  187. package/dist/types/other/FakeMessageInteraction.js.map +0 -1
  188. package/dist/types/other/InteractionLocale.d.ts.map +0 -1
  189. package/dist/types/other/InteractionLocale.js.map +0 -1
  190. package/dist/types/other/Locale.d.ts.map +0 -1
  191. package/dist/types/other/Locale.js.map +0 -1
  192. package/dist/types/other/MessageContextMenu.d.ts.map +0 -1
  193. package/dist/types/other/MessageContextMenu.js.map +0 -1
  194. package/dist/types/other/UserContextMenu.d.ts.map +0 -1
  195. package/dist/types/other/UserContextMenu.js.map +0 -1
  196. package/dist/utils/MemoryStore.d.ts.map +0 -1
  197. package/dist/utils/MemoryStore.js.map +0 -1
  198. package/dist/utils/UtilTypes.d.ts.map +0 -1
  199. package/dist/utils/UtilTypes.js.map +0 -1
  200. package/dist/utils/customId.d.ts.map +0 -1
  201. package/dist/utils/customId.js.map +0 -1
  202. package/dist/utils/permissions.d.ts.map +0 -1
  203. package/dist/utils/permissions.js.map +0 -1
  204. package/dist/utils/recursiveImport.d.ts.map +0 -1
  205. package/dist/utils/recursiveImport.js.map +0 -1
  206. package/dist/utils/recursiveUnload.d.ts.map +0 -1
  207. package/dist/utils/recursiveUnload.js.map +0 -1
  208. package/dist/utils/unloadModule.d.ts.map +0 -1
  209. package/dist/utils/unloadModule.js.map +0 -1
  210. package/examples/modal/dbi.js +0 -30
  211. package/examples/modal/login.js +0 -15
  212. package/examples/modal/package.json +0 -15
  213. package/examples/modal/publish.js +0 -13
  214. package/examples/modal/src/chatInput.js +0 -38
  215. package/examples/modal/src/components.js +0 -33
  216. package/examples/modal/src/event.js +0 -20
  217. package/examples/modal/src/interactionlocales.js +0 -24
  218. package/examples/modal/src/locales.js +0 -38
  219. package/examples/modal/src/modal.js +0 -28
  220. /package/dist/{DBI.d.ts → src/DBI.d.ts} +0 -0
  221. /package/dist/{DBI.js → src/DBI.js} +0 -0
  222. /package/dist/{Events.d.ts → src/Events.d.ts} +0 -0
  223. /package/dist/{Events.js → src/Events.js} +0 -0
  224. /package/dist/{data → src/data}/eventMap.json +0 -0
  225. /package/dist/{index.d.ts → src/index.d.ts} +0 -0
  226. /package/dist/{index.js → src/index.js} +0 -0
  227. /package/dist/{methods → src/methods}/handleMessageCommands.d.ts +0 -0
  228. /package/dist/{methods → src/methods}/handleMessageCommands.js +0 -0
  229. /package/dist/{methods → src/methods}/hookEventListeners.d.ts +0 -0
  230. /package/dist/{methods → src/methods}/hookEventListeners.js +0 -0
  231. /package/dist/{methods → src/methods}/hookInteractionListeners.d.ts +0 -0
  232. /package/dist/{methods → src/methods}/publishInteractions.d.ts +0 -0
  233. /package/dist/{methods → src/methods}/publishInteractions.js +0 -0
  234. /package/dist/{types → src/types}/ApplicationRoleConnectionMetadata.d.ts +0 -0
  235. /package/dist/{types → src/types}/ApplicationRoleConnectionMetadata.js +0 -0
  236. /package/dist/{types → src/types}/Builders/ButtonBuilder.d.ts +0 -0
  237. /package/dist/{types → src/types}/Builders/ButtonBuilder.js +0 -0
  238. /package/dist/{types → src/types}/Builders/ChannelSelectMenuBuilder.d.ts +0 -0
  239. /package/dist/{types → src/types}/Builders/ChannelSelectMenuBuilder.js +0 -0
  240. /package/dist/{types → src/types}/Builders/MentionableSelectMenuBuilder.d.ts +0 -0
  241. /package/dist/{types → src/types}/Builders/MentionableSelectMenuBuilder.js +0 -0
  242. /package/dist/{types → src/types}/Builders/ModalBuilder.d.ts +0 -0
  243. /package/dist/{types → src/types}/Builders/ModalBuilder.js +0 -0
  244. /package/dist/{types → src/types}/Builders/RoleSelectMenuBuilder.d.ts +0 -0
  245. /package/dist/{types → src/types}/Builders/RoleSelectMenuBuilder.js +0 -0
  246. /package/dist/{types → src/types}/Builders/StringSelectMenuBuilder.d.ts +0 -0
  247. /package/dist/{types → src/types}/Builders/StringSelectMenuBuilder.js +0 -0
  248. /package/dist/{types → src/types}/Builders/UserSelectMenuBuilder.d.ts +0 -0
  249. /package/dist/{types → src/types}/Builders/UserSelectMenuBuilder.js +0 -0
  250. /package/dist/{types → src/types}/ChatInput/ChatInput.d.ts +0 -0
  251. /package/dist/{types → src/types}/ChatInput/ChatInput.js +0 -0
  252. /package/dist/{types → src/types}/ChatInput/ChatInputOptions.js +0 -0
  253. /package/dist/{types → src/types}/Components/Button.d.ts +0 -0
  254. /package/dist/{types → src/types}/Components/Button.js +0 -0
  255. /package/dist/{types → src/types}/Components/ChannelSelectMenu.d.ts +0 -0
  256. /package/dist/{types → src/types}/Components/ChannelSelectMenu.js +0 -0
  257. /package/dist/{types → src/types}/Components/HTMLComponentsV2/HTMLComponentsV2Handlers.d.ts +0 -0
  258. /package/dist/{types → src/types}/Components/HTMLComponentsV2/HTMLComponentsV2Handlers.js +0 -0
  259. /package/dist/{types → src/types}/Components/HTMLComponentsV2/parser.d.ts +0 -0
  260. /package/dist/{types → src/types}/Components/MentionableSelectMenu.d.ts +0 -0
  261. /package/dist/{types → src/types}/Components/MentionableSelectMenu.js +0 -0
  262. /package/dist/{types → src/types}/Components/Modal.d.ts +0 -0
  263. /package/dist/{types → src/types}/Components/Modal.js +0 -0
  264. /package/dist/{types → src/types}/Components/RoleSelectMenu.d.ts +0 -0
  265. /package/dist/{types → src/types}/Components/RoleSelectMenu.js +0 -0
  266. /package/dist/{types → src/types}/Components/StringSelectMenu.d.ts +0 -0
  267. /package/dist/{types → src/types}/Components/StringSelectMenu.js +0 -0
  268. /package/dist/{types → src/types}/Components/UserSelectMenu.d.ts +0 -0
  269. /package/dist/{types → src/types}/Components/UserSelectMenu.js +0 -0
  270. /package/dist/{types → src/types}/Event.d.ts +0 -0
  271. /package/dist/{types → src/types}/Event.js +0 -0
  272. /package/dist/{types → src/types}/Interaction.d.ts +0 -0
  273. /package/dist/{types → src/types}/Interaction.js +0 -0
  274. /package/dist/{types → src/types}/other/CustomEvent.d.ts +0 -0
  275. /package/dist/{types → src/types}/other/CustomEvent.js +0 -0
  276. /package/dist/{types → src/types}/other/FakeMessageInteraction.d.ts +0 -0
  277. /package/dist/{types → src/types}/other/FakeMessageInteraction.js +0 -0
  278. /package/dist/{types → src/types}/other/InteractionLocale.d.ts +0 -0
  279. /package/dist/{types → src/types}/other/InteractionLocale.js +0 -0
  280. /package/dist/{types → src/types}/other/Locale.d.ts +0 -0
  281. /package/dist/{types → src/types}/other/Locale.js +0 -0
  282. /package/dist/{types → src/types}/other/MessageContextMenu.d.ts +0 -0
  283. /package/dist/{types → src/types}/other/MessageContextMenu.js +0 -0
  284. /package/dist/{types → src/types}/other/UserContextMenu.d.ts +0 -0
  285. /package/dist/{types → src/types}/other/UserContextMenu.js +0 -0
  286. /package/dist/{utils → src/utils}/MemoryStore.d.ts +0 -0
  287. /package/dist/{utils → src/utils}/MemoryStore.js +0 -0
  288. /package/dist/{utils → src/utils}/UtilTypes.d.ts +0 -0
  289. /package/dist/{utils → src/utils}/UtilTypes.js +0 -0
  290. /package/dist/{utils → src/utils}/customId.d.ts +0 -0
  291. /package/dist/{utils → src/utils}/customId.js +0 -0
  292. /package/dist/{utils → src/utils}/permissions.d.ts +0 -0
  293. /package/dist/{utils → src/utils}/permissions.js +0 -0
  294. /package/dist/{utils → src/utils}/recursiveImport.d.ts +0 -0
  295. /package/dist/{utils → src/utils}/recursiveImport.js +0 -0
  296. /package/dist/{utils → src/utils}/recursiveUnload.d.ts +0 -0
  297. /package/dist/{utils → src/utils}/recursiveUnload.js +0 -0
  298. /package/dist/{utils → src/utils}/unloadModule.d.ts +0 -0
  299. /package/dist/{utils → src/utils}/unloadModule.js +0 -0
@@ -0,0 +1,904 @@
1
+ import { parse } from "svelte/compiler";
2
+ import { walk } from "estree-walker";
3
+ import * as stuffs from "stuffs";
4
+
5
+
6
+ export interface SvelteHandlerInfo {
7
+ name: string;
8
+ handlerName: string;
9
+ eventType: string; // onclick, onchange, etc.
10
+ element: string; // button, string-select, etc.
11
+ }
12
+
13
+ export interface SvelteComponentInfo {
14
+ handlers: Map<string, SvelteHandlerInfo>;
15
+ scriptContent: string;
16
+ processedSource: string; // Source with auto-generated names injected
17
+ }
18
+
19
+ /**
20
+ * Parse a Svelte component and extract event handlers
21
+ * Also injects auto-generated names into elements that have handlers but no name
22
+ */
23
+ export function parseSvelteComponent(source: string, data?: Record<string, any>): SvelteComponentInfo {
24
+ const ast = parse(source);
25
+ const handlers = new Map<string, SvelteHandlerInfo>();
26
+ let scriptContent = "";
27
+
28
+ // Extract script content
29
+ if (ast.instance) {
30
+ scriptContent = source.substring(ast.instance.content.start, ast.instance.content.end);
31
+ }
32
+
33
+ // Track elements that need auto-generated names (node -> name mapping)
34
+ // We'll inject these into the source after the walk
35
+ const elementsNeedingNames: Array<{ node: any; name: string; handlerName: string; eventType: string; element: string }> = [];
36
+ let autoNameCounter = 0;
37
+
38
+ // Walk through HTML nodes to find event handlers
39
+ walk(ast.html as any, {
40
+ enter(node: any) {
41
+ if (node.type === "Element" || node.type === "InlineComponent") {
42
+ const attributes = node.attributes || [];
43
+
44
+ // Find name attribute
45
+ const nameAttr = attributes.find((attr: any) =>
46
+ attr.type === "Attribute" && attr.name === "name"
47
+ );
48
+
49
+ // Check if element has an onclick/onchange handler and get the handler info
50
+ let foundHandler: { eventType: string; handlerName: string } | null = null;
51
+
52
+ for (const attr of attributes) {
53
+ const isEventHandler = attr.type === "EventHandler";
54
+ const isOnAttribute = attr.type === "Attribute" && attr.name && attr.name.startsWith("on");
55
+
56
+ if (isEventHandler || isOnAttribute) {
57
+ const eventType = attr.name;
58
+ let handlerName = "";
59
+
60
+ if (attr.type === "Attribute" && Array.isArray(attr.value)) {
61
+ const exprValue = attr.value.find((v: any) => v.type === "ExpressionTag" || v.type === "MustacheTag");
62
+ if (exprValue && exprValue.expression) {
63
+ if (exprValue.expression.type === "Identifier") {
64
+ handlerName = exprValue.expression.name;
65
+ } else if (exprValue.expression.type === "CallExpression" && exprValue.expression.callee) {
66
+ handlerName = exprValue.expression.callee.name;
67
+ }
68
+ }
69
+ } else if (attr.expression) {
70
+ if (attr.expression.type === "Identifier") {
71
+ handlerName = attr.expression.name;
72
+ } else if (attr.expression.type === "CallExpression" && attr.expression.callee) {
73
+ handlerName = attr.expression.callee.name;
74
+ } else if (attr.expression.type === "MemberExpression") {
75
+ handlerName = extractMemberExpressionName(attr.expression);
76
+ }
77
+ }
78
+
79
+ if (handlerName) {
80
+ foundHandler = { eventType, handlerName };
81
+ break;
82
+ }
83
+ }
84
+ }
85
+
86
+ if (!foundHandler) return; // No handler found, skip
87
+
88
+ let componentName: string;
89
+ if (nameAttr) {
90
+ componentName = getAttributeValue(nameAttr);
91
+ } else {
92
+ // No name attribute - generate a deterministic one based on position
93
+ // Use the handler name and counter for deterministic naming
94
+ const positionKey = `${node.name.toLowerCase()}_${autoNameCounter++}`;
95
+
96
+ // If data is provided, use/store in $autoNames for persistence across re-renders
97
+ if (data) {
98
+ if (!data.$autoNames) {
99
+ data.$autoNames = {};
100
+ }
101
+ if (!data.$autoNames[positionKey]) {
102
+ data.$autoNames[positionKey] = `__auto_${positionKey}`;
103
+ }
104
+ componentName = data.$autoNames[positionKey];
105
+ } else {
106
+ // No data - use deterministic name based on position
107
+ componentName = `__auto_${positionKey}`;
108
+ }
109
+
110
+ // Track this element for source injection
111
+ elementsNeedingNames.push({
112
+ node,
113
+ name: componentName,
114
+ handlerName: foundHandler.handlerName,
115
+ eventType: foundHandler.eventType,
116
+ element: node.name.toLowerCase()
117
+ });
118
+ }
119
+
120
+ // Add to handlers map
121
+ handlers.set(componentName, {
122
+ name: componentName,
123
+ handlerName: foundHandler.handlerName,
124
+ eventType: foundHandler.eventType,
125
+ element: node.name.toLowerCase(),
126
+ });
127
+ }
128
+ }
129
+ });
130
+
131
+ // Inject auto-generated names into the source
132
+ // Sort by position descending so we don't mess up offsets
133
+ let processedSource = source;
134
+ const sortedElements = [...elementsNeedingNames].sort((a, b) => b.node.start - a.node.start);
135
+
136
+ for (const { node, name } of sortedElements) {
137
+ // Find the position right after the opening tag name
138
+ // e.g., <button ...> -> insert after "button"
139
+ const tagEnd = node.start + 1 + node.name.length; // +1 for '<'
140
+ processedSource = processedSource.slice(0, tagEnd) + ` name="${name}"` + processedSource.slice(tagEnd);
141
+ }
142
+
143
+ return {
144
+ handlers,
145
+ scriptContent,
146
+ processedSource
147
+ };
148
+ }
149
+
150
+ /**
151
+ * Extract the full name from a MemberExpression (e.g., obj.method)
152
+ */
153
+ function extractMemberExpressionName(expr: any): string {
154
+ if (expr.type === "Identifier") {
155
+ return expr.name;
156
+ }
157
+ if (expr.type === "MemberExpression") {
158
+ const object = extractMemberExpressionName(expr.object);
159
+ const property = expr.property.name || expr.property.value;
160
+ return `${object}.${property}`;
161
+ }
162
+ return "";
163
+ }
164
+
165
+ /**
166
+ * Get the value from an attribute
167
+ */
168
+ function getAttributeValue(attr: any): string {
169
+ if (!attr.value) return "";
170
+
171
+ if (Array.isArray(attr.value)) {
172
+ // Static text value
173
+ if (attr.value[0]?.type === "Text") {
174
+ return attr.value[0].data;
175
+ }
176
+ // Expression value
177
+ if (attr.value[0]?.expression) {
178
+ return extractExpressionValue(attr.value[0].expression);
179
+ }
180
+ }
181
+
182
+ return "";
183
+ }
184
+
185
+ /**
186
+ * Extract value from an expression
187
+ */
188
+ function extractExpressionValue(expr: any): string {
189
+ if (expr.type === "Identifier") {
190
+ return expr.name;
191
+ }
192
+ if (expr.type === "Literal") {
193
+ return String(expr.value);
194
+ }
195
+ return "";
196
+ }
197
+
198
+ export interface HandlerContextResult {
199
+ handlers: Record<string, Function>;
200
+ effects: Function[];
201
+ runEffects: () => void;
202
+ hasPendingRender: () => boolean;
203
+ flushRender: () => Promise<void>;
204
+ wrappedCtx: any; // Proxy-wrapped ctx for passing to handlers
205
+ // Lifecycle hooks
206
+ mountCallbacks: Function[];
207
+ destroyCallbacks: Function[];
208
+ runMount: () => void;
209
+ runDestroy: () => void;
210
+ // Handler execution tracking
211
+ setInHandler: (value: boolean) => void;
212
+ }
213
+
214
+ /**
215
+ * Parse import statements from script and extract module info
216
+ */
217
+ interface ImportInfo {
218
+ moduleName: string;
219
+ imports: { name: string; alias?: string }[];
220
+ isDefault: boolean;
221
+ defaultName?: string;
222
+ }
223
+
224
+ function parseImports(script: string): { imports: ImportInfo[]; cleanedScript: string } {
225
+ const imports: ImportInfo[] = [];
226
+
227
+ // Match: import { a, b as c } from "module"
228
+ // Match: import name from "module"
229
+ // Match: import * as name from "module"
230
+ const importRegex = /import\s+(?:(\w+)\s*,?\s*)?(?:\{\s*([^}]+)\s*\})?(?:\*\s+as\s+(\w+))?\s+from\s+["']([^"']+)["'];?/g;
231
+
232
+ let cleanedScript = script;
233
+ let match;
234
+
235
+ while ((match = importRegex.exec(script)) !== null) {
236
+ const [fullMatch, defaultImport, namedImports, namespaceImport, moduleName] = match;
237
+
238
+ // Skip svelte internal imports - we provide these ourselves
239
+ if (moduleName === 'svelte' || moduleName.startsWith('svelte/')) {
240
+ cleanedScript = cleanedScript.replace(fullMatch, '');
241
+ continue;
242
+ }
243
+
244
+ const importInfo: ImportInfo = {
245
+ moduleName,
246
+ imports: [],
247
+ isDefault: false
248
+ };
249
+
250
+ // Default import: import name from "module"
251
+ if (defaultImport) {
252
+ importInfo.isDefault = true;
253
+ importInfo.defaultName = defaultImport;
254
+ }
255
+
256
+ // Namespace import: import * as name from "module"
257
+ if (namespaceImport) {
258
+ importInfo.isDefault = true;
259
+ importInfo.defaultName = namespaceImport;
260
+ }
261
+
262
+ // Named imports: import { a, b as c } from "module"
263
+ if (namedImports) {
264
+ const parts = namedImports.split(',').map(s => s.trim()).filter(Boolean);
265
+ for (const part of parts) {
266
+ const aliasMatch = part.match(/^(\w+)\s+as\s+(\w+)$/);
267
+ if (aliasMatch) {
268
+ importInfo.imports.push({ name: aliasMatch[1], alias: aliasMatch[2] });
269
+ } else {
270
+ importInfo.imports.push({ name: part });
271
+ }
272
+ }
273
+ }
274
+
275
+ imports.push(importInfo);
276
+ cleanedScript = cleanedScript.replace(fullMatch, '');
277
+ }
278
+
279
+ return { imports, cleanedScript };
280
+ }
281
+
282
+ /**
283
+ * Load modules and create injection variables
284
+ */
285
+ function loadModules(imports: ImportInfo[]): { modules: Record<string, any>; varDeclarations: string } {
286
+ const modules: Record<string, any> = {};
287
+ const declarations: string[] = [];
288
+
289
+ for (const importInfo of imports) {
290
+ try {
291
+ // Try to require the module
292
+ const mod = require(importInfo.moduleName);
293
+
294
+ if (importInfo.isDefault && importInfo.defaultName) {
295
+ // Default or namespace import
296
+ modules[importInfo.defaultName] = mod.default || mod;
297
+ declarations.push(`var ${importInfo.defaultName} = __modules__["${importInfo.defaultName}"];`);
298
+ }
299
+
300
+ // Named imports
301
+ for (const imp of importInfo.imports) {
302
+ const varName = imp.alias || imp.name;
303
+ modules[varName] = mod[imp.name];
304
+ declarations.push(`var ${varName} = __modules__["${varName}"];`);
305
+ }
306
+ } catch (err) {
307
+ console.error(`[Svelte] Failed to import module "${importInfo.moduleName}":`, err);
308
+ }
309
+ }
310
+
311
+ return { modules, varDeclarations: declarations.join('\n') };
312
+ }
313
+
314
+ /**
315
+ * Create a handler context from script content
316
+ * This evaluates the Svelte script and returns the handler functions and effects
317
+ */
318
+ export function createHandlerContext(scriptContent: string, initialData: Record<string, any> = {}, component?: any, ctx?: any): HandlerContextResult {
319
+ const handlers: Record<string, Function> = {};
320
+ const effects: Function[] = [];
321
+
322
+ try {
323
+ // Parse and extract imports first
324
+ const { imports, cleanedScript } = parseImports(scriptContent);
325
+ const { modules, varDeclarations } = loadModules(imports);
326
+
327
+ // Extract only function declarations from the script
328
+ const functionNames = extractFunctionNames(cleanedScript);
329
+
330
+ // Extract $effect calls and convert them to collectable functions
331
+ const effectBodies = extractEffectBodies(cleanedScript);
332
+
333
+ // Process script to be safe for evaluation:
334
+ // 1. Remove reactive declarations (let x = $state(...))
335
+ // 2. Remove $props destructuring
336
+ // 3. Convert $effect to __registerEffect__
337
+ // 4. Keep only function declarations
338
+ let processedScript = cleanedScript
339
+ // Remove $state declarations completely or make them var
340
+ .replace(/let\s+(\w+)\s*=\s*\$state\(([^)]*)\);?/g, 'var $1 = $2;')
341
+ // Remove $derived declarations but keep the value
342
+ .replace(/let\s+(\w+)\s*=\s*\$derived\(([^)]+)\);?/g, 'var $1 = $2;')
343
+ // Convert $effect calls to __registerEffect__ calls
344
+ .replace(/\$effect\s*\(\s*((?:function\s*\([^)]*\)|\([^)]*\)\s*=>|\(\)\s*=>)[^}]*\{[\s\S]*?\}\s*)\);?/g, '__registerEffect__($1);')
345
+ // Simpler $effect pattern: $effect(() => { ... })
346
+ .replace(/\$effect\s*\(\s*\(\)\s*=>\s*\{([\s\S]*?)\}\s*\);?/g, '__registerEffect__(function() {$1});')
347
+ // Replace $props destructuring with data access (handles default values)
348
+ .replace(/let\s+\{\s*([^}]+)\s*\}\s*=\s*\$props\(\);?/g, (match, vars) => {
349
+ return vars.split(',').map((v: string) => {
350
+ v = v.trim();
351
+ // Skip empty strings and comments
352
+ if (!v || v.startsWith('//')) return '';
353
+ // Remove inline comments from the variable definition
354
+ v = v.replace(/\/\/.*$/, '').trim();
355
+ if (!v) return '';
356
+ // Skip 'data' prop as it's already defined in the wrapper
357
+ if (v === 'data') return '';
358
+ // Check if there's a default value: varName = defaultValue
359
+ const defaultMatch = v.match(/^(\w+)\s*=\s*(.+)$/);
360
+ if (defaultMatch) {
361
+ const [, varName, defaultValue] = defaultMatch;
362
+ // Skip 'data' prop even with default value
363
+ if (varName === 'data') return '';
364
+ // Clean default value from trailing comments
365
+ const cleanDefault = defaultValue.replace(/\/\/.*$/, '').trim();
366
+ return `var ${varName} = data.${varName} ?? ${cleanDefault};`;
367
+ }
368
+ return `var ${v} = data.${v};`;
369
+ }).filter(Boolean).join('\n');
370
+ });
371
+
372
+ // Add module variable declarations at the beginning of processed script
373
+ if (varDeclarations) {
374
+ processedScript = varDeclarations + '\n\n' + processedScript;
375
+ }
376
+
377
+ // Wrap everything in an IIFE that takes data and component as parameters
378
+ // This ensures data and 'this' are always available in the function scope
379
+ // Also provides helper functions: render(), update() and rerender()
380
+ // Data is wrapped in a Proxy for automatic reactivity
381
+ // Interaction methods (reply, followUp, deferReply) are wrapped to auto-render after completion
382
+ const wrappedScript = `
383
+ return function(__data__, __component__, __ctx__, __modules__) {
384
+ __modules__ = __modules__ || {};
385
+ var self = __component__;
386
+ var __effects__ = [];
387
+ var __renderPending__ = false;
388
+ var __autoRenderEnabled__ = true;
389
+ var __hasDataChanges__ = false;
390
+
391
+ // Lifecycle callbacks
392
+ var __mountCallbacks__ = [];
393
+ var __destroyCallbacks__ = [];
394
+ var __isMounted__ = false;
395
+
396
+ // Store last message reference for background updates (intervals, timeouts)
397
+ var __lastMessage__ = __ctx__?.interaction?.message || null;
398
+
399
+ // Throttle configuration
400
+ var __throttleMinInterval__ = 250; // Minimum ms between renders
401
+ var __lastRenderTime__ = 0;
402
+ var __pendingRenderTimeout__ = null;
403
+ var __isRateLimited__ = false;
404
+ var __rateLimitEndTime__ = 0;
405
+
406
+ function __registerEffect__(fn) {
407
+ __effects__.push(fn);
408
+ }
409
+
410
+ // Lifecycle: onMount - called when component is first rendered
411
+ // If callback returns a function, that function is called on destroy
412
+ function onMount(fn) {
413
+ __mountCallbacks__.push(fn);
414
+ }
415
+
416
+ // Lifecycle: onDestroy - called when ref is cleaned up
417
+ function onDestroy(fn) {
418
+ __destroyCallbacks__.push(fn);
419
+ }
420
+
421
+ // Rate-limit aware edit function with retry
422
+ function __safeEdit__(editFn, retryCount) {
423
+ retryCount = retryCount || 0;
424
+ var maxRetries = 3;
425
+
426
+ return editFn().catch(function(err) {
427
+ // Check for rate limit (429)
428
+ if (err.status === 429 || (err.message && err.message.includes('rate limit'))) {
429
+ var retryAfter = err.retry_after || err.retryAfter || 1;
430
+ console.log("[Svelte] Rate limited, waiting " + retryAfter + "s before retry");
431
+ __isRateLimited__ = true;
432
+ __rateLimitEndTime__ = Date.now() + (retryAfter * 1000);
433
+
434
+ return new Promise(function(resolve) {
435
+ setTimeout(function() {
436
+ __isRateLimited__ = false;
437
+ if (retryCount < maxRetries) {
438
+ resolve(__safeEdit__(editFn, retryCount + 1));
439
+ } else {
440
+ console.error("[Svelte] Max retries reached after rate limit");
441
+ resolve();
442
+ }
443
+ }, retryAfter * 1000);
444
+ });
445
+ }
446
+ console.error("[Svelte] Edit error:", err.message);
447
+ return Promise.resolve();
448
+ });
449
+ }
450
+
451
+ // Throttled render - ensures minimum interval between renders
452
+ function __throttledRender__(immediate) {
453
+ var now = Date.now();
454
+ var timeSinceLastRender = now - __lastRenderTime__;
455
+ var waitTime = 0;
456
+
457
+ // If rate limited, calculate wait time
458
+ if (__isRateLimited__ && __rateLimitEndTime__ > now) {
459
+ waitTime = Math.max(waitTime, __rateLimitEndTime__ - now);
460
+ }
461
+
462
+ // If within throttle interval, schedule for later
463
+ if (!immediate && timeSinceLastRender < __throttleMinInterval__) {
464
+ waitTime = Math.max(waitTime, __throttleMinInterval__ - timeSinceLastRender);
465
+ }
466
+
467
+ // Clear any pending render
468
+ if (__pendingRenderTimeout__) {
469
+ clearTimeout(__pendingRenderTimeout__);
470
+ __pendingRenderTimeout__ = null;
471
+ }
472
+
473
+ if (waitTime > 0) {
474
+ return new Promise(function(resolve) {
475
+ __pendingRenderTimeout__ = setTimeout(function() {
476
+ __pendingRenderTimeout__ = null;
477
+ __lastRenderTime__ = Date.now();
478
+ resolve(__executeRender__());
479
+ }, waitTime);
480
+ });
481
+ }
482
+
483
+ __lastRenderTime__ = now;
484
+ return __executeRender__();
485
+ }
486
+
487
+ // Actual render execution
488
+ function __executeRender__() {
489
+ var components = __component__.toJSON({ data: __data__ });
490
+
491
+ // Try to use current interaction if available
492
+ if (__ctx__ && __ctx__.interaction) {
493
+ try {
494
+ var i = __ctx__.interaction;
495
+
496
+ // Update last message reference
497
+ if (i.message) {
498
+ __lastMessage__ = i.message;
499
+ }
500
+
501
+ if (i.replied || i.deferred) {
502
+ // Already replied, use message.edit with rate limit handling
503
+ return __safeEdit__(function() {
504
+ return i.message.edit({
505
+ components: components,
506
+ flags: ["IsComponentsV2"],
507
+ });
508
+ });
509
+ } else {
510
+ // Not replied yet, use update with rate limit handling
511
+ return __safeEdit__(function() {
512
+ return i.update({
513
+ components: components,
514
+ flags: ["IsComponentsV2"],
515
+ });
516
+ });
517
+ }
518
+ } catch (err) {
519
+ console.error("[Svelte] Error in render with interaction:", err.message);
520
+ }
521
+ }
522
+
523
+ // Fallback: Use last message reference (for intervals/timeouts outside interaction)
524
+ if (__lastMessage__) {
525
+ return __safeEdit__(function() {
526
+ return __lastMessage__.edit({
527
+ components: components,
528
+ flags: ["IsComponentsV2"],
529
+ });
530
+ });
531
+ }
532
+
533
+ console.error("[Svelte] Cannot render: no interaction or message context");
534
+ return Promise.resolve();
535
+ }
536
+
537
+ // Helper: Auto-detect whether to use update() or rerender()
538
+ // If interaction was already replied/deferred, use message.edit
539
+ // Otherwise use interaction.update
540
+ function render(immediate) {
541
+ return __throttledRender__(immediate);
542
+ }
543
+
544
+ // Track if we're inside a handler execution
545
+ var __inHandlerExecution__ = false;
546
+
547
+ // Mark that we have pending data changes
548
+ function __markDataChanged__() {
549
+ __hasDataChanges__ = true;
550
+
551
+ // If we're NOT inside a handler (e.g., interval/timeout), trigger render immediately
552
+ // The throttle will prevent too many renders
553
+ if (!__inHandlerExecution__ && __autoRenderEnabled__ && __lastMessage__) {
554
+ __hasDataChanges__ = false;
555
+ __throttledRender__(false);
556
+ }
557
+ }
558
+
559
+ // Flush pending render (called after interaction methods complete)
560
+ function __flushRender__() {
561
+ if (__hasDataChanges__ && __autoRenderEnabled__) {
562
+ __hasDataChanges__ = false;
563
+ render();
564
+ }
565
+ }
566
+
567
+ // Create reactive proxy for data
568
+ function __createReactiveProxy__(target, path) {
569
+ if (typeof target !== 'object' || target === null) return target;
570
+
571
+ return new Proxy(target, {
572
+ get: function(obj, prop) {
573
+ var value = obj[prop];
574
+ // Wrap nested objects in proxy too
575
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
576
+ return __createReactiveProxy__(value, path + '.' + String(prop));
577
+ }
578
+ return value;
579
+ },
580
+ set: function(obj, prop, value) {
581
+ var oldValue = obj[prop];
582
+ obj[prop] = value;
583
+ // Only mark as changed if value actually changed
584
+ if (oldValue !== value) {
585
+ __markDataChanged__();
586
+ }
587
+ return true;
588
+ }
589
+ });
590
+ }
591
+
592
+ // Wrap data in reactive proxy
593
+ var data = __createReactiveProxy__(__data__, 'data');
594
+
595
+ // Track if an async interaction method was called
596
+ var __asyncInteractionCalled__ = false;
597
+
598
+ // Wrap interaction methods to auto-render after completion
599
+ var interaction = null;
600
+ var ctx = null;
601
+
602
+ if (__ctx__ && __ctx__.interaction) {
603
+ var originalInteraction = __ctx__.interaction;
604
+
605
+ // Create a proxy for interaction that wraps reply/followUp/deferReply
606
+ interaction = new Proxy(originalInteraction, {
607
+ get: function(target, prop) {
608
+ var value = target[prop];
609
+
610
+ // Wrap methods that "consume" the interaction (reply, followUp, defer)
611
+ if (prop === 'reply' || prop === 'followUp' || prop === 'deferReply' || prop === 'deferUpdate') {
612
+ return function() {
613
+ // Mark that async interaction was called - this prevents sync flush at handler end
614
+ __asyncInteractionCalled__ = true;
615
+
616
+ var result = value.apply(target, arguments);
617
+ // After the reply completes, flush any pending renders using throttled render
618
+ if (result && typeof result.then === 'function') {
619
+ result.then(function() {
620
+ if (__hasDataChanges__ && __autoRenderEnabled__) {
621
+ __hasDataChanges__ = false;
622
+ // Use throttled render which handles rate limits
623
+ __throttledRender__(false);
624
+ }
625
+ }).catch(function(err) {
626
+ console.error("[Svelte] Error in " + prop + ":", err.message);
627
+ });
628
+ }
629
+ return result;
630
+ };
631
+ }
632
+
633
+ // Wrap update method - this one renders directly, no need to flush after
634
+ if (prop === 'update') {
635
+ return function() {
636
+ __autoRenderEnabled__ = false; // Disable auto since we're doing manual update
637
+ __asyncInteractionCalled__ = true;
638
+ return value.apply(target, arguments);
639
+ };
640
+ }
641
+
642
+ // Bind functions to original target
643
+ if (typeof value === 'function') {
644
+ return value.bind(target);
645
+ }
646
+
647
+ return value;
648
+ }
649
+ });
650
+
651
+ // Create wrapped ctx with the proxied interaction
652
+ ctx = new Proxy(__ctx__, {
653
+ get: function(target, prop) {
654
+ if (prop === 'interaction') {
655
+ return interaction;
656
+ }
657
+ return target[prop];
658
+ }
659
+ });
660
+ }
661
+
662
+ // Helper: Force update message using interaction.update (for button clicks without reply)
663
+ // Helper: Force update message using interaction.update (for button clicks without reply)
664
+ function update() {
665
+ if (!__ctx__ || !__ctx__.interaction) {
666
+ console.error("[Svelte] Cannot update: no interaction context");
667
+ return Promise.resolve();
668
+ }
669
+ __autoRenderEnabled__ = false; // Disable auto-render since manual update called
670
+ return __safeEdit__(function() {
671
+ return __ctx__.interaction.update({
672
+ components: __component__.toJSON({ data: __data__ }),
673
+ flags: ["IsComponentsV2"],
674
+ });
675
+ });
676
+ }
677
+
678
+ // Helper: Force re-render message using message.edit (after reply/followUp)
679
+ function rerender() {
680
+ if (!__ctx__ || !__ctx__.interaction || !__ctx__.interaction.message) {
681
+ console.error("[Svelte] Cannot rerender: no message context");
682
+ return Promise.resolve();
683
+ }
684
+ __autoRenderEnabled__ = false; // Disable auto-render since manual rerender called
685
+ return __safeEdit__(function() {
686
+ return __ctx__.interaction.message.edit({
687
+ components: __component__.toJSON({ data: __data__ }),
688
+ flags: ["IsComponentsV2"],
689
+ });
690
+ });
691
+ }
692
+
693
+ // Helper: Disable auto-render (for handlers that don't need UI update)
694
+ function noRender() {
695
+ __autoRenderEnabled__ = false;
696
+ }
697
+
698
+ // Helper: Set throttle interval (minimum ms between renders)
699
+ function setThrottle(ms) {
700
+ __throttleMinInterval__ = ms;
701
+ }
702
+
703
+ // Helper: Destroy this component instance (clears intervals, timers, removes ref)
704
+ // Call this when you want to clean up the component manually
705
+ function destroy() {
706
+ // Run all destroy callbacks (clears intervals, timers, etc.)
707
+ __runDestroy__();
708
+
709
+ // Clear the ref from DBI store if available
710
+ if (__data__ && __data__.$ref && __component__ && __component__.dbi) {
711
+ __component__.dbi.data.refs.delete(__data__.$ref);
712
+ }
713
+
714
+ // Disable further auto-renders
715
+ __autoRenderEnabled__ = false;
716
+ }
717
+
718
+ // Check if there are pending data changes that need SYNC render
719
+ // Returns false if async interaction was called (reply/followUp will handle render)
720
+ function __hasPendingRender__() {
721
+ return __hasDataChanges__ && __autoRenderEnabled__ && !__asyncInteractionCalled__;
722
+ }
723
+
724
+ // Synchronous flush for when handler completes without async interaction
725
+ // Only called when no reply/followUp was made - uses throttled render
726
+ function __syncFlushRender__() {
727
+ if (__hasDataChanges__ && __autoRenderEnabled__ && !__asyncInteractionCalled__) {
728
+ __hasDataChanges__ = false;
729
+ return __throttledRender__(true); // immediate=true for sync flush
730
+ }
731
+ return Promise.resolve();
732
+ }
733
+
734
+ // Run all mount callbacks, if callback returns a function add it to destroy callbacks
735
+ function __runMount__() {
736
+ if (__isMounted__) return;
737
+ __isMounted__ = true;
738
+ for (var i = 0; i < __mountCallbacks__.length; i++) {
739
+ try {
740
+ var result = __mountCallbacks__[i]();
741
+ // If mount callback returns a function, add it to destroy callbacks
742
+ if (typeof result === 'function') {
743
+ __destroyCallbacks__.push(result);
744
+ }
745
+ } catch (err) {
746
+ console.error("[Svelte] Error in onMount:", err);
747
+ }
748
+ }
749
+ }
750
+
751
+ // Run all destroy callbacks
752
+ function __runDestroy__() {
753
+ for (var i = 0; i < __destroyCallbacks__.length; i++) {
754
+ try {
755
+ __destroyCallbacks__[i]();
756
+ } catch (err) {
757
+ console.error("[Svelte] Error in onDestroy:", err);
758
+ }
759
+ }
760
+ // Clear pending timeouts
761
+ if (__pendingRenderTimeout__) {
762
+ clearTimeout(__pendingRenderTimeout__);
763
+ __pendingRenderTimeout__ = null;
764
+ }
765
+ }
766
+
767
+ // Set handler execution flag
768
+ function __setInHandler__(value) {
769
+ __inHandlerExecution__ = value;
770
+ }
771
+
772
+ ${processedScript}
773
+ return {
774
+ handlers: { ${functionNames.length > 0 ? functionNames.join(", ") : ''} },
775
+ effects: __effects__,
776
+ hasPendingRender: __hasPendingRender__,
777
+ flushRender: __syncFlushRender__,
778
+ wrappedCtx: ctx,
779
+ mountCallbacks: __mountCallbacks__,
780
+ destroyCallbacks: __destroyCallbacks__,
781
+ runMount: __runMount__,
782
+ runDestroy: __runDestroy__,
783
+ setInHandler: __setInHandler__
784
+ };
785
+ };
786
+ `;
787
+
788
+ console.log("[Svelte] Processed script:", processedScript);
789
+ console.log("[Svelte] Wrapped script:", wrappedScript);
790
+ console.log("[Svelte] Initial data:", initialData);
791
+
792
+ // Create the factory function
793
+ const factoryFunc = new Function('console', wrappedScript);
794
+ const createHandlers = factoryFunc(console);
795
+
796
+ // Execute with the actual data, component, ctx, and imported modules to get handlers with proper closure
797
+ const result = createHandlers(initialData, component, ctx, modules);
798
+
799
+ Object.assign(handlers, result.handlers || {});
800
+ effects.push(...(result.effects || []));
801
+
802
+ // Return full result including render helpers
803
+ // Function to run all effects
804
+ const runEffects = () => {
805
+ for (const effect of effects) {
806
+ try {
807
+ effect();
808
+ } catch (error) {
809
+ console.error("Error running effect:", error);
810
+ }
811
+ }
812
+ };
813
+
814
+ return {
815
+ handlers,
816
+ effects,
817
+ runEffects,
818
+ hasPendingRender: result.hasPendingRender || (() => false),
819
+ flushRender: result.flushRender || (() => Promise.resolve()),
820
+ wrappedCtx: result.wrappedCtx || ctx,
821
+ mountCallbacks: result.mountCallbacks || [],
822
+ destroyCallbacks: result.destroyCallbacks || [],
823
+ runMount: result.runMount || (() => { }),
824
+ runDestroy: result.runDestroy || (() => { }),
825
+ setInHandler: result.setInHandler || (() => { })
826
+ };
827
+ } catch (error) {
828
+ console.error("Error creating handler context:", error);
829
+ console.error("Processed script:", scriptContent);
830
+ }
831
+
832
+ // Function to run all effects (fallback)
833
+ const runEffects = () => {
834
+ for (const effect of effects) {
835
+ try {
836
+ effect();
837
+ } catch (error) {
838
+ console.error("Error running effect:", error);
839
+ }
840
+ }
841
+ };
842
+
843
+ return {
844
+ handlers,
845
+ effects,
846
+ runEffects,
847
+ hasPendingRender: () => false,
848
+ flushRender: () => Promise.resolve(),
849
+ wrappedCtx: ctx,
850
+ mountCallbacks: [],
851
+ destroyCallbacks: [],
852
+ runMount: () => { },
853
+ runDestroy: () => { },
854
+ setInHandler: () => { }
855
+ };
856
+ }
857
+
858
+ /**
859
+ * Extract $effect callback bodies from script content
860
+ */
861
+ function extractEffectBodies(script: string): string[] {
862
+ const bodies: string[] = [];
863
+ // Match $effect(() => { ... }) or $effect(function() { ... })
864
+ const effectRegex = /\$effect\s*\(\s*(?:(?:function\s*\([^)]*\)|\([^)]*\)\s*=>|\(\)\s*=>)\s*\{([\s\S]*?)\})\s*\)/g;
865
+ let match;
866
+ while ((match = effectRegex.exec(script)) !== null) {
867
+ bodies.push(match[1]);
868
+ }
869
+ return bodies;
870
+ }
871
+
872
+ /**
873
+ * Extract function names from script content (excluding effect callbacks)
874
+ */
875
+ function extractFunctionNames(script: string): string[] {
876
+ const names: string[] = [];
877
+
878
+ // Match function declarations: function name() {}
879
+ const functionDeclRegex = /function\s+(\w+)\s*\(/g;
880
+ let match;
881
+ while ((match = functionDeclRegex.exec(script)) !== null) {
882
+ names.push(match[1]);
883
+ }
884
+
885
+ // Match function expressions: const name = function() {}
886
+ const functionExprRegex = /(?:const|let|var)\s+(\w+)\s*=\s*function\s*\(/g;
887
+ while ((match = functionExprRegex.exec(script)) !== null) {
888
+ names.push(match[1]);
889
+ }
890
+
891
+ // Match arrow functions: const name = () => {}
892
+ const arrowFunctionRegex = /(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s*)?\([^)]*\)\s*=>/g;
893
+ while ((match = arrowFunctionRegex.exec(script)) !== null) {
894
+ names.push(match[1]);
895
+ }
896
+
897
+ // Match arrow functions without parentheses: const name = x => {}
898
+ const simpleArrowRegex = /(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s*)?\w+\s*=>/g;
899
+ while ((match = simpleArrowRegex.exec(script)) !== null) {
900
+ names.push(match[1]);
901
+ }
902
+
903
+ return [...new Set(names)]; // Remove duplicates
904
+ }