@minesa-org/mini-interaction 0.2.16 → 0.2.18

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.
@@ -1577,6 +1577,8 @@ function createTimeoutWrapper(handler, timeoutMs, handlerName, enableWarnings =
1577
1577
  return async (...args) => {
1578
1578
  const startTime = Date.now();
1579
1579
  let timeoutId;
1580
+ let ackResult = null;
1581
+ let ackReceived = false;
1580
1582
  const timeoutPromise = new Promise((_, reject) => {
1581
1583
  timeoutId = setTimeout(() => {
1582
1584
  const elapsed = Date.now() - startTime;
@@ -1584,31 +1586,53 @@ function createTimeoutWrapper(handler, timeoutMs, handlerName, enableWarnings =
1584
1586
  reject(new Error(`Handler timeout: ${handlerName} exceeded ${timeoutMs}ms limit`));
1585
1587
  }, timeoutMs);
1586
1588
  });
1589
+ // If we have an ackPromise, listen for it but DON'T return early
1590
+ // Instead, capture the ACK result and continue waiting for handler
1591
+ if (ackPromise) {
1592
+ ackPromise.then((result) => {
1593
+ ackResult = result;
1594
+ ackReceived = true;
1595
+ // Clear the timeout once we have an ACK - handler can now take longer
1596
+ if (timeoutId) {
1597
+ clearTimeout(timeoutId);
1598
+ timeoutId = undefined;
1599
+ }
1600
+ }).catch(() => {
1601
+ // ACK promise rejection is fine, we'll use handler result
1602
+ });
1603
+ }
1587
1604
  try {
1588
- const promises = [
1589
- Promise.resolve(handler(...args)),
1605
+ // ALWAYS wait for handler to complete
1606
+ const handlerResult = await Promise.race([
1607
+ handler(...args),
1590
1608
  timeoutPromise,
1591
- ];
1592
- if (ackPromise) {
1593
- promises.push(ackPromise);
1594
- }
1595
- const result = await Promise.race(promises);
1609
+ ]);
1596
1610
  if (timeoutId) {
1597
1611
  clearTimeout(timeoutId);
1598
1612
  }
1599
1613
  const elapsed = Date.now() - startTime;
1600
- if (enableWarnings && elapsed > timeoutMs * 0.8) {
1614
+ if (enableWarnings && elapsed > timeoutMs * 0.8 && !ackReceived) {
1601
1615
  console.warn(`[MiniInteraction] ${handlerName} completed in ${elapsed}ms (${Math.round((elapsed / timeoutMs) * 100)}% of timeout limit)`);
1602
1616
  }
1603
- return result;
1617
+ // If we got an ACK, return that for the HTTP response
1618
+ // The handler has completed at this point so all background work is done
1619
+ if (ackReceived && ackResult !== null) {
1620
+ return ackResult;
1621
+ }
1622
+ return handlerResult;
1604
1623
  }
1605
1624
  catch (error) {
1606
1625
  if (timeoutId) {
1607
1626
  clearTimeout(timeoutId);
1608
1627
  }
1609
- // Re-throw the error with additional context
1610
- if (error instanceof Error &&
1611
- error.message.includes("Handler timeout")) {
1628
+ // If handler timed out but we have an ACK, return the ACK
1629
+ // This allows deferReply to work even if later operations are slow
1630
+ if (error instanceof Error && error.message.includes("Handler timeout")) {
1631
+ if (ackReceived && ackResult !== null) {
1632
+ console.warn(`[MiniInteraction] ${handlerName} timed out but ACK was already captured. ` +
1633
+ `Background work may not complete in serverless environments.`);
1634
+ return ackResult;
1635
+ }
1612
1636
  throw error;
1613
1637
  }
1614
1638
  console.error(`[MiniInteraction] ${handlerName} failed:`, error);
@@ -48,7 +48,7 @@ export interface CommandInteraction extends Omit<APIChatInputApplicationCommandI
48
48
  reply(data: InteractionMessageData): Promise<APIInteractionResponseChannelMessageWithSource>;
49
49
  edit(data?: InteractionMessageData): APIInteractionResponseUpdateMessage;
50
50
  followUp(data: InteractionMessageData): Promise<void>;
51
- editReply(data?: InteractionMessageData): Promise<void>;
51
+ editReply(data?: InteractionMessageData): Promise<APIInteractionResponseChannelMessageWithSource | APIInteractionResponseUpdateMessage>;
52
52
  deferReply(options?: DeferReplyOptions): APIInteractionResponseDeferredChannelMessageWithSource;
53
53
  showModal(data: APIModalInteractionResponseCallbackData | {
54
54
  toJSON(): APIModalInteractionResponseCallbackData;
@@ -305,6 +305,7 @@ export function createCommandInteraction(interaction, helpers) {
305
305
  }
306
306
  this.trackResponse?.(this.id, this.token, 'responded');
307
307
  hasResponded = true;
308
+ return response;
308
309
  },
309
310
  deferReply(options) {
310
311
  if (this.canRespond && !this.canRespond(this.id)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minesa-org/mini-interaction",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
4
4
  "description": "Mini interaction, connecting your app with Discord via HTTP-interaction (Vercel support).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",