@helyx/module-reactionroles 1.0.9 → 1.0.11

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @helyx/module-reactionroles
2
2
 
3
+ ## 1.0.11
4
+
5
+ ### Patch Changes
6
+
7
+ - Report missing managed panel messages correctly during Server Health inspections.
8
+
9
+ ## 1.0.10
10
+
11
+ ### Patch Changes
12
+
13
+ - Harden dashboard authentication, privacy execution, control routing, database transactions, and self-host configuration.
14
+
15
+ Add bounded multi-value record reads and use them to batch Polls and Reaction Roles dashboard queries. Improve dashboard presentation, Forms workflows, release safety, and operational tooling across hosted and self-hosted deployments.
16
+
17
+ - Updated dependencies
18
+ - @helyx/sdk@0.7.0
19
+
3
20
  ## 1.0.9
4
21
 
5
22
  ### Patch Changes
package/dist/index.js CHANGED
@@ -400,7 +400,7 @@ export const reactionRolesModule = defineModule({
400
400
  healthMessage = cache.saturated()
401
401
  ? `Reaction Roles loaded the bounded maximum of ${count} active panels`
402
402
  : cleanup.failed > 0 || cleanup.abandoned > 0
403
- ? `Reaction Roles loaded ${count} active panels; ${cleanup.failed + cleanup.abandoned} message cleanups need attention`
403
+ ? `Reaction Roles could not clean up ${cleanup.failed + cleanup.abandoned} old panel message${cleanup.failed + cleanup.abandoned === 1 ? "" : "s"}.`
404
404
  : `Reaction Roles loaded ${count} active panels`;
405
405
  context.logger.info({
406
406
  event: "reactionroles.started",
package/dist/records.js CHANGED
@@ -240,7 +240,7 @@ export class ReactionRolePanelRepository {
240
240
  limit: input.limit,
241
241
  });
242
242
  return {
243
- panels: await Promise.all(page.records.map((panel) => this.#withEntries(panel))),
243
+ panels: await this.#withEntriesForPanels(page.records),
244
244
  nextCursor: page.nextCursor,
245
245
  };
246
246
  }
@@ -287,7 +287,7 @@ export class ReactionRolePanelRepository {
287
287
  ],
288
288
  limit: Math.min(100, Math.max(1, limit)),
289
289
  });
290
- return Promise.all(page.records.map((panel) => this.#withEntries(panel)));
290
+ return this.#withEntriesForPanels(page.records);
291
291
  }
292
292
  async listByRole(guildId, roleId, limit = 100) {
293
293
  return this.#listByEntryField(guildId, "role_id", roleId, limit);
@@ -309,7 +309,7 @@ export class ReactionRolePanelRepository {
309
309
  limit: input.limit,
310
310
  });
311
311
  return {
312
- panels: await Promise.all(page.records.map((panel) => this.#withEntries(panel))),
312
+ panels: await this.#withEntriesForPanels(page.records),
313
313
  nextCursor: page.nextCursor,
314
314
  };
315
315
  }
@@ -444,6 +444,32 @@ export class ReactionRolePanelRepository {
444
444
  });
445
445
  return mapPanel(panel, entries.records);
446
446
  }
447
+ async #withEntriesForPanels(panels) {
448
+ if (panels.length === 0)
449
+ return [];
450
+ const panelIds = panels.map((panel) => requiredString(panel, "panel_id"));
451
+ const entries = await this.records.findManyByValues({
452
+ moduleId: MODULE_ID,
453
+ collection: "entries",
454
+ select: entrySelect,
455
+ where: {},
456
+ whereAny: { field: "panel_id", values: panelIds },
457
+ orderBy: [
458
+ { field: "position", direction: "asc" },
459
+ { field: "entry_id", direction: "asc" },
460
+ ],
461
+ });
462
+ const entriesByPanel = new Map();
463
+ for (const entry of entries) {
464
+ const panelId = requiredString(entry, "panel_id");
465
+ const grouped = entriesByPanel.get(panelId);
466
+ if (grouped)
467
+ grouped.push(entry);
468
+ else
469
+ entriesByPanel.set(panelId, [entry]);
470
+ }
471
+ return panels.map((panel, index) => mapPanel(panel, entriesByPanel.get(panelIds[index]) ?? []));
472
+ }
447
473
  async #listByEntryField(guildId, field, value, limit) {
448
474
  const entries = await this.records.findMany({
449
475
  moduleId: MODULE_ID,
@@ -456,8 +482,27 @@ export class ReactionRolePanelRepository {
456
482
  ],
457
483
  limit: Math.min(100, Math.max(1, limit)),
458
484
  });
459
- const panels = await Promise.all(entries.records.map((entry) => this.findById(guildId, requiredString(entry, "panel_id"))));
460
- return panels.filter((panel) => panel !== null);
485
+ const panelIds = entries.records.map((entry) => requiredString(entry, "panel_id"));
486
+ const uniquePanelIds = [...new Set(panelIds)];
487
+ if (uniquePanelIds.length === 0)
488
+ return [];
489
+ const panels = await this.records.findManyByValues({
490
+ moduleId: MODULE_ID,
491
+ collection: "panels",
492
+ select: panelSelect,
493
+ where: { guild_id: guildId },
494
+ whereAny: { field: "panel_id", values: uniquePanelIds },
495
+ orderBy: [
496
+ { field: "updated_at", direction: "desc" },
497
+ { field: "panel_id", direction: "asc" },
498
+ ],
499
+ });
500
+ const hydrated = await this.#withEntriesForPanels(panels);
501
+ const byId = new Map(hydrated.map((panel) => [panel.panelId, panel]));
502
+ return uniquePanelIds.flatMap((panelId) => {
503
+ const panel = byId.get(panelId);
504
+ return panel ? [panel] : [];
505
+ });
461
506
  }
462
507
  }
463
508
  function panelValues(input) {
package/manifest.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "releaseStatus": "live",
4
4
  "id": "helyx.reactionroles",
5
5
  "name": "Reaction Roles",
6
- "version": "1.0.9",
6
+ "version": "1.0.11",
7
7
  "description": "Let members select approved roles themselves.",
8
8
  "entry": "./dist/index.js",
9
9
  "framework": "^0.1.0",
@@ -0,0 +1,6 @@
1
+ CREATE INDEX IF NOT EXISTS reactionroles_entries_role_panel_idx
2
+ ON reactionroles_entries (role_id, panel_id);
3
+
4
+ CREATE INDEX IF NOT EXISTS reactionroles_entries_emoji_panel_idx
5
+ ON reactionroles_entries (emoji_id, panel_id)
6
+ WHERE emoji_id IS NOT NULL;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helyx/module-reactionroles",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Configurable self-service Discord role panels for Helyx.",
5
5
  "keywords": [
6
6
  "helyx",
@@ -50,6 +50,6 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@helyx/module-manifest": ">=0.6.0 <0.7.0",
53
- "@helyx/sdk": ">=0.6.0 <0.7.0"
53
+ "@helyx/sdk": ">=0.7.0 <0.8.0"
54
54
  }
55
55
  }