@mostfeatured/dbi 0.2.13 → 0.2.15

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 (45) hide show
  1. package/dist/src/types/Components/HTMLComponentsV2/index.d.ts +33 -1
  2. package/dist/src/types/Components/HTMLComponentsV2/index.d.ts.map +1 -1
  3. package/dist/src/types/Components/HTMLComponentsV2/index.js +408 -82
  4. package/dist/src/types/Components/HTMLComponentsV2/index.js.map +1 -1
  5. package/dist/src/types/Components/HTMLComponentsV2/parser.d.ts +52 -0
  6. package/dist/src/types/Components/HTMLComponentsV2/parser.d.ts.map +1 -1
  7. package/dist/src/types/Components/HTMLComponentsV2/parser.js +275 -0
  8. package/dist/src/types/Components/HTMLComponentsV2/parser.js.map +1 -1
  9. package/dist/src/types/Components/HTMLComponentsV2/svelteParser.d.ts +26 -0
  10. package/dist/src/types/Components/HTMLComponentsV2/svelteParser.d.ts.map +1 -1
  11. package/dist/src/types/Components/HTMLComponentsV2/svelteParser.js +509 -34
  12. package/dist/src/types/Components/HTMLComponentsV2/svelteParser.js.map +1 -1
  13. package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.d.ts +10 -0
  14. package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.d.ts.map +1 -1
  15. package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.js +76 -11
  16. package/dist/src/types/Components/HTMLComponentsV2/svelteRenderer.js.map +1 -1
  17. package/dist/test/index.js +76 -3
  18. package/dist/test/index.js.map +1 -1
  19. package/docs/ADVANCED_FEATURES.md +4 -0
  20. package/docs/API_REFERENCE.md +4 -0
  21. package/docs/CHAT_INPUT.md +4 -0
  22. package/docs/COMPONENTS.md +4 -0
  23. package/docs/EVENTS.md +4 -0
  24. package/docs/GETTING_STARTED.md +4 -0
  25. package/docs/LOCALIZATION.md +4 -0
  26. package/docs/README.md +4 -0
  27. package/docs/SVELTE_COMPONENTS.md +162 -6
  28. package/docs/llm/ADVANCED_FEATURES.txt +521 -0
  29. package/docs/llm/API_REFERENCE.txt +659 -0
  30. package/docs/llm/CHAT_INPUT.txt +514 -0
  31. package/docs/llm/COMPONENTS.txt +595 -0
  32. package/docs/llm/EVENTS.txt +449 -0
  33. package/docs/llm/GETTING_STARTED.txt +296 -0
  34. package/docs/llm/LOCALIZATION.txt +501 -0
  35. package/docs/llm/README.txt +193 -0
  36. package/docs/llm/SVELTE_COMPONENTS.txt +566 -0
  37. package/generated/svelte-dbi.d.ts +122 -0
  38. package/package.json +1 -1
  39. package/src/types/Components/HTMLComponentsV2/index.ts +466 -94
  40. package/src/types/Components/HTMLComponentsV2/parser.ts +317 -0
  41. package/src/types/Components/HTMLComponentsV2/svelteParser.ts +567 -35
  42. package/src/types/Components/HTMLComponentsV2/svelteRenderer.ts +91 -13
  43. package/test/index.ts +76 -3
  44. package/test/product-showcase.svelte +380 -24
  45. package/llm.txt +0 -1088
@@ -0,0 +1,566 @@
1
+ ================================================================================
2
+ DBI - SVELTE COMPONENTS GUIDE - LLM REFERENCE DOCUMENT
3
+ ================================================================================
4
+
5
+ DOCUMENT TYPE: Svelte 5 Integration Reference
6
+ PACKAGE: @mostfeatured/dbi
7
+
8
+ ================================================================================
9
+ SECTION 1: OVERVIEW
10
+ ================================================================================
11
+
12
+ DBI provides Svelte 5-based component system for Discord UI with Components V2.
13
+
14
+ KEY FEATURES:
15
+ - Svelte 5 Syntax with $props() runes
16
+ - Auto-Reactivity when data changes
17
+ - Lifecycle Hooks (onMount, onDestroy)
18
+ - Throttled Rendering to prevent API abuse
19
+ - Full TypeScript support
20
+
21
+ ================================================================================
22
+ SECTION 2: QUICK START
23
+ ================================================================================
24
+
25
+ STEP 1 - REGISTER SVELTE COMPONENT:
26
+ -----------------------------------
27
+ import { createDBI } from "@mostfeatured/dbi";
28
+ import path from "path";
29
+
30
+ dbi.register(({ HTMLComponentsV2 }) => {
31
+ HTMLComponentsV2({
32
+ name: "my-component",
33
+ mode: "svelte",
34
+ file: path.join(__dirname, "my-component.svelte"),
35
+ });
36
+ });
37
+
38
+ STEP 2 - CREATE SVELTE FILE:
39
+ ----------------------------
40
+ <script>
41
+ let { count = 0 } = $props();
42
+
43
+ function increment() {
44
+ data.count++;
45
+ }
46
+ </script>
47
+
48
+ <components>
49
+ <text-display>Count: {count}</text-display>
50
+ <action-row>
51
+ <button style="Primary" handler={increment}>+1</button>
52
+ </action-row>
53
+ </components>
54
+
55
+ STEP 3 - SEND COMPONENT:
56
+ ------------------------
57
+ ChatInput({
58
+ name: "counter",
59
+ description: "Interactive counter",
60
+ async onExecute({ interaction, dbi }) {
61
+ const component = dbi.interaction("my-component");
62
+ await component.send(interaction, {
63
+ data: { count: 0 }
64
+ });
65
+ }
66
+ });
67
+
68
+ ================================================================================
69
+ SECTION 3: COMPONENT STRUCTURE
70
+ ================================================================================
71
+
72
+ A DBI Svelte component has two parts:
73
+
74
+ SCRIPT BLOCK:
75
+ -------------
76
+ <script>
77
+ /// <reference types="@mostfeatured/dbi/svelte" />
78
+ import stuffs from "stuffs";
79
+
80
+ let {
81
+ products = [],
82
+ currentIndex = 0,
83
+ cart = [],
84
+ view = "browse",
85
+ } = $props();
86
+
87
+ function nextProduct() {
88
+ data.currentIndex = (currentIndex + 1) % products.length;
89
+ }
90
+
91
+ function addToCart(ctx) {
92
+ const product = products[currentIndex];
93
+ data.cart = [...cart, product];
94
+ ctx.interaction.reply({
95
+ content: "Added to cart!",
96
+ flags: ["Ephemeral"],
97
+ });
98
+ }
99
+
100
+ onMount(() => {
101
+ const interval = setInterval(() => {
102
+ data.elapsedTime += 1;
103
+ }, 1000);
104
+ return () => clearInterval(interval); // Cleanup
105
+ });
106
+ </script>
107
+
108
+ TEMPLATE BLOCK:
109
+ ---------------
110
+ <components>
111
+ <container accent-color="5865F2">
112
+ <components>
113
+ <text-display>## Welcome!</text-display>
114
+ <action-row>
115
+ <button style="Primary" handler={nextProduct}>Next</button>
116
+ </action-row>
117
+ </components>
118
+ </container>
119
+ </components>
120
+
121
+ ================================================================================
122
+ SECTION 4: PROPS AND REACTIVITY
123
+ ================================================================================
124
+
125
+ DECLARING PROPS:
126
+ ----------------
127
+ <script>
128
+ let {
129
+ count = 0,
130
+ items = [],
131
+ settings = { theme: "dark" },
132
+ } = $props();
133
+ </script>
134
+
135
+ THE DATA OBJECT:
136
+ ----------------
137
+ Use global `data` object to update state. Changes trigger re-renders:
138
+
139
+ <script>
140
+ let { count = 0 } = $props();
141
+
142
+ function increment() {
143
+ data.count++; // Triggers auto-render
144
+ }
145
+
146
+ function reset() {
147
+ data.count = 0;
148
+ }
149
+ </script>
150
+
151
+ REACTIVE UPDATES:
152
+ -----------------
153
+ The `data` object is a Proxy that:
154
+ 1. Detects property changes
155
+ 2. Automatically re-renders the component
156
+ 3. Throttles updates (default: 250ms between renders)
157
+
158
+ <script>
159
+ let { items = [] } = $props();
160
+
161
+ function addItem(ctx) {
162
+ // Arrays must be reassigned to trigger reactivity
163
+ data.items = [...items, { name: "New Item" }];
164
+ }
165
+ </script>
166
+
167
+ ================================================================================
168
+ SECTION 5: LIFECYCLE HOOKS
169
+ ================================================================================
170
+
171
+ onMount:
172
+ --------
173
+ Runs when component is first sent. For timers, intervals, fetching data.
174
+
175
+ <script>
176
+ let { seconds = 0 } = $props();
177
+
178
+ onMount(() => {
179
+ console.log("Component mounted!");
180
+
181
+ const interval = setInterval(() => {
182
+ data.seconds++;
183
+ }, 1000);
184
+
185
+ // Return cleanup function (optional)
186
+ return () => {
187
+ clearInterval(interval);
188
+ console.log("Timer cleared!");
189
+ };
190
+ });
191
+ </script>
192
+
193
+ onDestroy:
194
+ ----------
195
+ Runs when component is destroyed (via $unRef or manual destroy() call).
196
+
197
+ <script>
198
+ let timer;
199
+
200
+ onMount(() => {
201
+ timer = setInterval(() => data.count++, 1000);
202
+ });
203
+
204
+ onDestroy(() => {
205
+ clearInterval(timer);
206
+ console.log("Component destroyed, cleanup complete!");
207
+ });
208
+ </script>
209
+
210
+ MANUAL DESTRUCTION:
211
+ -------------------
212
+ <script>
213
+ function handleClose() {
214
+ destroy(); // Runs onDestroy callbacks, removes ref
215
+ }
216
+ </script>
217
+
218
+ <components>
219
+ <action-row>
220
+ <button style="Danger" handler={handleClose}>Close</button>
221
+ </action-row>
222
+ </components>
223
+
224
+ ================================================================================
225
+ SECTION 6: RENDER HELPERS
226
+ ================================================================================
227
+
228
+ HELPER | DESCRIPTION
229
+ -------------------|--------------------------------------------------
230
+ render() | Force immediate render
231
+ update() | Update using interaction.update() - best for buttons
232
+ rerender() | Re-render using message.edit() - after reply/followUp
233
+ noRender() | Disable auto-render for current handler
234
+ setThrottle() | Set minimum interval between renders
235
+ lowPriorityUpdate()| Background update that yields to handler interactions
236
+
237
+ EXAMPLES:
238
+ ---------
239
+ <script>
240
+ function forceUpdate() {
241
+ data.value = computeExpensiveValue();
242
+ render(); // Force immediate render
243
+ }
244
+
245
+ async function handleButton() {
246
+ data.count++;
247
+ await update(); // Uses interaction.update()
248
+ }
249
+
250
+ async function processData(ctx) {
251
+ await ctx.interaction.reply({ content: "Processing..." });
252
+ data.result = await fetchData();
253
+ await rerender(); // Uses message.edit()
254
+ }
255
+
256
+ function backgroundTask() {
257
+ noRender(); // Don't update UI
258
+ data.internalState = calculate();
259
+ }
260
+
261
+ // For timer that updates every second
262
+ setThrottle(1000);
263
+
264
+ // Low-priority update for intervals (won't conflict with button clicks)
265
+ onMount(() => {
266
+ const interval = setInterval(() => {
267
+ lowPriorityUpdate(() => {
268
+ data.seconds++;
269
+ });
270
+ }, 1000);
271
+ return () => clearInterval(interval);
272
+ });
273
+ </script>
274
+
275
+ ================================================================================
276
+ SECTION 7: HTML ELEMENTS REFERENCE
277
+ ================================================================================
278
+
279
+ LAYOUT COMPONENTS:
280
+ ------------------
281
+ ELEMENT | DESCRIPTION
282
+ -----------------|--------------------------------------------------
283
+ <components> | Root wrapper for all Discord components
284
+ <action-row> | Container for buttons (max 5) or single select menu
285
+ <container> | Colored container with accent-color attribute
286
+ <section> | Section with components and optional accessory
287
+ <separator> | Visual divider between components
288
+
289
+ CONTAINER EXAMPLE:
290
+ <container accent-color="5865F2" spoiler>
291
+ <components>
292
+ <!-- Content -->
293
+ </components>
294
+ </container>
295
+
296
+ SECTION EXAMPLE:
297
+ <section>
298
+ <components>
299
+ <text-display>Main content</text-display>
300
+ </components>
301
+ <thumbnail url="https://example.com/image.png"></thumbnail>
302
+ </section>
303
+
304
+ SEPARATOR:
305
+ <separator divider spacing="2"></separator>
306
+
307
+ INTERACTIVE COMPONENTS:
308
+ -----------------------
309
+ BUTTON:
310
+ <button
311
+ style="Primary"
312
+ emoji="🚀"
313
+ handler={handleClick}
314
+ disabled
315
+ >
316
+ Click Me
317
+ </button>
318
+
319
+ BUTTON STYLES: Primary, Secondary, Success, Danger, Link, Premium
320
+ NOTE: Use `onclick` as alias for `handler`
321
+
322
+ STRING SELECT:
323
+ <string-select
324
+ placeholder="Choose an option..."
325
+ min-values="1"
326
+ max-values="3"
327
+ handler={handleSelect}
328
+ >
329
+ <option value="a" description="First option" emoji="1️⃣" default>
330
+ Option A
331
+ </option>
332
+ <option value="b" description="Second option">
333
+ Option B
334
+ </option>
335
+ </string-select>
336
+
337
+ OTHER SELECT MENUS:
338
+ <user-select placeholder="Select users..." handler={handleUsers}></user-select>
339
+ <role-select placeholder="Select roles..." handler={handleRoles}></role-select>
340
+ <channel-select placeholder="Select channels..." handler={handleChannels}></channel-select>
341
+ <mentionable-select placeholder="Select..." handler={handleMentionables}></mentionable-select>
342
+
343
+ DISPLAY COMPONENTS:
344
+ -------------------
345
+ TEXT DISPLAY:
346
+ <text-display>
347
+ ## Heading
348
+ **Bold** and *italic* text
349
+ - List item 1
350
+ - List item 2
351
+ </text-display>
352
+
353
+ THUMBNAIL:
354
+ <thumbnail url="https://example.com/image.png"></thumbnail>
355
+
356
+ MEDIA GALLERY:
357
+ <media-gallery>
358
+ <item url="https://example.com/1.png" description="Image 1"></item>
359
+ <item url="https://example.com/2.png" spoiler></item>
360
+ </media-gallery>
361
+
362
+ FILE:
363
+ <file url="attachment://document.pdf" spoiler></file>
364
+
365
+ ================================================================================
366
+ SECTION 8: MODAL COMPONENTS
367
+ ================================================================================
368
+
369
+ MODAL DEFINITION:
370
+ -----------------
371
+ <components
372
+ type="modal"
373
+ id="feedback-modal"
374
+ title="Submit Feedback"
375
+ >
376
+ <field label="Rating" description="How would you rate?">
377
+ <string-select id="rating" placeholder="Select rating">
378
+ <option value="5">⭐⭐⭐⭐⭐ Excellent</option>
379
+ <option value="4">⭐⭐⭐⭐ Great</option>
380
+ <option value="3">⭐⭐⭐ Good</option>
381
+ </string-select>
382
+ </field>
383
+ <field label="Comments" description="Tell us more">
384
+ <text-input id="comments" style="Paragraph" placeholder="Your feedback..." />
385
+ </field>
386
+ </components>
387
+
388
+ TEXT INPUT:
389
+ -----------
390
+ <field label="Username" description="Enter display name">
391
+ <text-input
392
+ id="username"
393
+ placeholder="Enter your username"
394
+ style="Short"
395
+ min-length="3"
396
+ max-length="32"
397
+ required
398
+ />
399
+ </field>
400
+
401
+ TEXT INPUT STYLES: Short, Paragraph
402
+
403
+ USING showModal():
404
+ ------------------
405
+ <script>
406
+ async function openFeedbackModal(ctx) {
407
+ const { fields, interaction } = await showModal("feedback-modal");
408
+
409
+ const rating = fields.rating[0]; // string-select returns array
410
+ const comments = fields.comments; // text-input returns string
411
+
412
+ interaction.reply({
413
+ content: `Thanks for your ${rating}-star feedback!`,
414
+ flags: ["Ephemeral"]
415
+ });
416
+ }
417
+ </script>
418
+
419
+ MODAL FIELD RETURN TYPES:
420
+ -------------------------
421
+ COMPONENT | RETURN TYPE
422
+ --------------------|----------------------------------
423
+ text-input | string
424
+ string-select | string[]
425
+ user-select | string[] (user IDs)
426
+ role-select | string[] (role IDs)
427
+ channel-select | string[] (channel IDs)
428
+ mentionable-select | { values, users, roles }
429
+ file-upload | Attachment[]
430
+
431
+ ================================================================================
432
+ SECTION 9: HANDLER FUNCTIONS
433
+ ================================================================================
434
+
435
+ <script>
436
+ function handleButton(ctx) {
437
+ const { interaction } = ctx;
438
+
439
+ ctx.interaction.reply({
440
+ content: "Button clicked!",
441
+ flags: ["Ephemeral"],
442
+ });
443
+
444
+ const { dbi } = ctx; // DBI instance
445
+ const { locale } = ctx; // Locale helpers
446
+ const text = locale.user("greeting");
447
+ }
448
+
449
+ // Handler without ctx - just updates data
450
+ function simpleHandler() {
451
+ data.count++;
452
+ // Auto-renders after handler completes
453
+ }
454
+ </script>
455
+
456
+ <components>
457
+ <action-row>
458
+ <button handler={handleButton}>With Context</button>
459
+ <button handler={simpleHandler}>Simple</button>
460
+ </action-row>
461
+ </components>
462
+
463
+ CONTEXT OBJECT:
464
+ ---------------
465
+ PROPERTY | TYPE | DESCRIPTION
466
+ ------------|--------------------------------|------------------------
467
+ interaction | ButtonInteraction/SelectMenu | Discord.js interaction
468
+ dbi | DBI | DBI instance
469
+ locale | object | Locale helpers
470
+
471
+ ================================================================================
472
+ SECTION 10: USING EXTERNAL MODULES
473
+ ================================================================================
474
+
475
+ <script>
476
+ import stuffs from "stuffs";
477
+ import lodash from "lodash";
478
+ import { someUtil } from "./utils";
479
+
480
+ function formatTime(seconds) {
481
+ return stuffs.formatSeconds(seconds);
482
+ }
483
+
484
+ function sortItems() {
485
+ data.items = lodash.sortBy(items, "name");
486
+ }
487
+ </script>
488
+
489
+ Modules loaded via require() at runtime - must be installed in project.
490
+
491
+ ================================================================================
492
+ SECTION 11: TYPE DEFINITIONS
493
+ ================================================================================
494
+
495
+ Add type reference for IDE support:
496
+
497
+ <script>
498
+ /// <reference types="@mostfeatured/dbi/svelte" />
499
+
500
+ // Now you get autocomplete for:
501
+ // - render(), update(), rerender(), noRender(), setThrottle()
502
+ // - onMount(), onDestroy(), destroy()
503
+ // - ctx, data
504
+ // - All HTML elements
505
+ </script>
506
+
507
+ ================================================================================
508
+ SECTION 12: API REFERENCE
509
+ ================================================================================
510
+
511
+ COMPONENT CLASS METHODS:
512
+ ------------------------
513
+ const component = dbi.interaction("my-component");
514
+
515
+ await component.send(interaction, { data: { count: 0 } });
516
+ await component.send(channel, { data: { count: 0 } });
517
+ component.destroy(refId);
518
+ component.destroyAll();
519
+ const json = component.toJSON({ data: { count: 0 } });
520
+
521
+ SEND OPTIONS:
522
+ -------------
523
+ {
524
+ data?: Record<string, any>; // Initial data
525
+ flags?: string[]; // Message flags
526
+ content?: string; // Text content
527
+ ephemeral?: boolean; // Ephemeral message
528
+ reply?: boolean; // Force reply
529
+ followUp?: boolean; // Use followUp instead
530
+ }
531
+
532
+ ================================================================================
533
+ SECTION 13: BEST PRACTICES
534
+ ================================================================================
535
+
536
+ 1. Use $props() for initial state - destructure with defaults
537
+ 2. Mutate `data` for updates - don't reassign entire data object
538
+ 3. Return cleanup from onMount - prevents memory leaks
539
+ 4. Use noRender() for background tasks - avoid unnecessary renders
540
+ 5. Set appropriate throttle - match your update frequency
541
+ 6. Use destroy() for cleanup - clean up timers when done
542
+ 7. Add type reference - get full IDE support
543
+
544
+ ================================================================================
545
+ SECTION 14: TROUBLESHOOTING
546
+ ================================================================================
547
+
548
+ COMPONENT NOT UPDATING?
549
+ - Use data.property = value, not reassigning data
550
+ - Check that noRender() wasn't called earlier
551
+
552
+ TIMER KEEPS RUNNING AFTER MESSAGE DELETED?
553
+ - Return cleanup function from onMount
554
+ - Or use onDestroy to clear intervals
555
+
556
+ RATE LIMITED BY DISCORD?
557
+ - Increase throttle with setThrottle(500) or higher
558
+ - System automatically retries on rate limits (max 3)
559
+
560
+ IDE NOT SHOWING AUTOCOMPLETE?
561
+ - Add /// <reference types="@mostfeatured/dbi/svelte" /> at top
562
+ - Make sure @mostfeatured/dbi is installed
563
+
564
+ ================================================================================
565
+ END OF DOCUMENT
566
+ ================================================================================
@@ -107,6 +107,32 @@ declare global {
107
107
  */
108
108
  function setThrottle(ms: number): void;
109
109
 
110
+ /**
111
+ * Low-priority update for background tasks like intervals.
112
+ * If a user interaction handler is currently running, the callback is executed
113
+ * but rendering is skipped (the handler's render will include these changes).
114
+ *
115
+ * Use this to prevent interval updates from conflicting with button clicks.
116
+ *
117
+ * @param callback - Function to execute that updates data
118
+ *
119
+ * @example
120
+ * ```svelte
121
+ * onMount(() => {
122
+ * const interval = setInterval(() => {
123
+ * // If user clicks a button during this interval tick,
124
+ * // this update won't trigger a conflicting render
125
+ * lowPriorityUpdate(() => {
126
+ * data.elapsedTime += 1;
127
+ * });
128
+ * }, 1000);
129
+ *
130
+ * return () => clearInterval(interval);
131
+ * });
132
+ * ```
133
+ */
134
+ function lowPriorityUpdate(callback: () => void): void;
135
+
110
136
  // ============================================
111
137
  // LIFECYCLE HOOKS
112
138
  // ============================================
@@ -183,6 +209,102 @@ declare global {
183
209
  */
184
210
  function destroy(): void;
185
211
 
212
+ // ============================================
213
+ // MODAL HELPERS
214
+ // ============================================
215
+
216
+ /**
217
+ * Modal submit response from showModal()
218
+ */
219
+ interface ModalResponse {
220
+ /** Object containing text input values keyed by input id */
221
+ fields: Record<string, string>;
222
+ /** The Discord ModalSubmitInteraction */
223
+ interaction: import("discord.js").ModalSubmitInteraction;
224
+ /** Full execution context */
225
+ ctx: any;
226
+ }
227
+
228
+ /**
229
+ * Options for showModal()
230
+ */
231
+ interface ShowModalOptions {
232
+ /**
233
+ * Timeout in milliseconds. After this time, the Promise will reject with a timeout error.
234
+ * - Default: 600000 (10 minutes)
235
+ * - Set to 0 for no timeout (unlimited wait)
236
+ *
237
+ * @example
238
+ * ```svelte
239
+ * // 1 minute timeout
240
+ * await showModal("my-modal", { timeout: 60000 });
241
+ *
242
+ * // No timeout (unlimited)
243
+ * await showModal("my-modal", { timeout: 0 });
244
+ * ```
245
+ */
246
+ timeout?: number;
247
+ }
248
+
249
+ /**
250
+ * Shows a modal defined in the component and returns a Promise.
251
+ * Modals are defined using `<components type="modal" id="...">`.
252
+ *
253
+ * You can use it in two ways:
254
+ * 1. With `onsubmit` handler on the modal - Promise resolves but you handle in callback
255
+ * 2. Without `onsubmit` - await the Promise to get fields directly
256
+ *
257
+ * @param modalId - The id of the modal to show (from `<components type="modal" id="xxx">`)
258
+ * @returns Promise that resolves with { fields, interaction, ctx } when modal is submitted
259
+ *
260
+ * @example
261
+ * ```svelte
262
+ * <script>
263
+ * // Method 1: Using onsubmit handler
264
+ * async function openEditModal() {
265
+ * await showModal("edit-item");
266
+ * // Modal was shown, handler will be called on submit
267
+ * }
268
+ *
269
+ * function handleEditSubmit(ctx, fields) {
270
+ * data.itemName = fields.name;
271
+ * ctx.interaction.reply({ content: "Updated!", flags: ["Ephemeral"] });
272
+ * }
273
+ *
274
+ * // Method 2: Await response directly (no onsubmit needed)
275
+ * async function openReviewModal(ctx) {
276
+ * data.editingProduct = products[currentIndex];
277
+ * const { fields, interaction } = await showModal("review-modal");
278
+ *
279
+ * // Handle the response inline
280
+ * data.reviews = [...reviews, {
281
+ * rating: fields.rating,
282
+ * review: fields.review
283
+ * }];
284
+ *
285
+ * interaction.reply({ content: "Thanks for your review!", flags: ["Ephemeral"] });
286
+ * }
287
+ * </script>
288
+ *
289
+ * <components>
290
+ * <button onclick={openEditModal}>Edit (with handler)</button>
291
+ * <button onclick={openReviewModal}>Review (inline)</button>
292
+ * </components>
293
+ *
294
+ * <!-- With onsubmit handler -->
295
+ * <components type="modal" id="edit-item" title="Edit" onsubmit={handleEditSubmit}>
296
+ * <text-input id="name" label="Name" required />
297
+ * </components>
298
+ *
299
+ * <!-- Without onsubmit - use await to get response -->
300
+ * <components type="modal" id="review-modal" title="Review">
301
+ * <text-input id="rating" label="Rating (1-5)" required />
302
+ * <text-input id="review" label="Your Review" style="Paragraph" />
303
+ * </components>
304
+ * ```
305
+ */
306
+ function showModal(modalId: string, options?: ShowModalOptions): Promise<ModalResponse>;
307
+
186
308
  // ============================================
187
309
  // REACTIVITY (Svelte 5 Runes)
188
310
  // ============================================
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "tslib": "^2.6.3"
16
16
  },
17
17
  "name": "@mostfeatured/dbi",
18
- "version": "0.2.13",
18
+ "version": "0.2.15",
19
19
  "main": "dist/src/index.js",
20
20
  "types": "dist/src/index.d.ts",
21
21
  "typesVersions": {