@voltro/plugin-comments 0.86.0 → 0.88.0

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/dist/index.js CHANGED
@@ -1,96 +1,96 @@
1
1
  import { CommentAccessRefused as e, CommentNotFound as t, CommentNotYours as n, CommentStatusRefused as r } from "./errors.js";
2
2
  import { QUOTE_MAX_LENGTH as i, findQuote as a, textQuote as o } from "./quote.js";
3
- import { BASE_NAME as s, COMMENT_THREAD_KINDS as c, commentsFeed as l, commentsRpcClientImports as u, createDescriptor as d, deleteDescriptor as f, editDescriptor as p, listDescriptor as m, markReadDescriptor as h, mentionSearchDescriptor as g, reactDescriptor as _, resolveDescriptor as v } from "./rpc.js";
4
- import { Effect as y, Option as b } from "effect";
5
- import { and as x, contains as S, eq as C, generateId as w, id as T, inSet as E, json as D, neq as O, or as k, table as A, text as j, timestamp as M } from "@voltro/database";
6
- import { definePlugin as N, pluginInstanceName as P, publishReactivity as F } from "@voltro/protocol";
3
+ import { BASE_NAME as s, COMMENT_THREAD_KINDS as c, commentsFeed as l, commentsRpcClientImports as u, createDescriptor as d, deleteDescriptor as f, editDescriptor as p, listDescriptor as m, markReadDescriptor as h, mentionSearchDescriptor as g, reactDescriptor as _, resolveDescriptor as ee } from "./rpc.js";
4
+ import { Effect as v, Option as y } from "effect";
5
+ import { and as b, contains as x, eq as S, generateId as C, id as w, inSet as T, json as E, neq as D, or as O, table as k, text as A, timestamp as j } from "@voltro/database";
6
+ import { definePlugin as M, effectiveScopes as N, pluginInstanceName as P, publishReactivity as F } from "@voltro/protocol";
7
7
  import { NotificationService as I } from "@voltro/plugin-notifications";
8
- //#region src/index.ts
9
- var L = A("_voltro_comment_threads", {
10
- id: T({ prefix: "cmtthr" }),
11
- anchor: j(),
12
- quote: D().nullable(),
13
- kind: j().default("discussion"),
14
- status: j().default("open"),
15
- createdBy: j(),
16
- createdAt: M().default("now"),
17
- tenantId: j().nullable()
18
- }).index("byThreadAnchor", ["anchor", "tenantId"]), R = A("_voltro_comments", {
19
- id: T({ prefix: "cmt" }),
20
- threadId: j(),
21
- body: j(),
22
- authorSubjectId: j(),
23
- mentions: D(),
24
- editedAt: M().nullable(),
25
- createdAt: M().default("now"),
26
- tenantId: j().nullable()
27
- }).index("byCommentThread", ["threadId"]), z = A("_voltro_comment_thread_events", {
28
- id: T({ prefix: "cmtevt" }),
29
- threadId: j(),
30
- fromStatus: j().nullable(),
31
- toStatus: j(),
32
- actor: j(),
33
- reason: j().nullable(),
34
- at: M().default("now"),
35
- tenantId: j().nullable()
36
- }).index("byThreadEvents", ["threadId"]), B = A("_voltro_comment_reactions", {
37
- id: T({ prefix: "cmtrx" }),
38
- commentId: j(),
39
- subjectId: j(),
40
- emoji: j()
8
+ // src/index.ts
9
+ var L = k("_voltro_comment_threads", {
10
+ id: w({ prefix: "cmtthr" }),
11
+ anchor: A(),
12
+ quote: E().nullable(),
13
+ kind: A().default("discussion"),
14
+ status: A().default("open"),
15
+ createdBy: A(),
16
+ createdAt: j().default("now"),
17
+ tenantId: A().nullable()
18
+ }).index("byThreadAnchor", ["anchor", "tenantId"]), R = k("_voltro_comments", {
19
+ id: w({ prefix: "cmt" }),
20
+ threadId: A(),
21
+ body: A(),
22
+ authorSubjectId: A(),
23
+ mentions: E(),
24
+ editedAt: j().nullable(),
25
+ createdAt: j().default("now"),
26
+ tenantId: A().nullable()
27
+ }).index("byCommentThread", ["threadId"]), z = k("_voltro_comment_thread_events", {
28
+ id: w({ prefix: "cmtevt" }),
29
+ threadId: A(),
30
+ fromStatus: A().nullable(),
31
+ toStatus: A(),
32
+ actor: A(),
33
+ reason: A().nullable(),
34
+ at: j().default("now"),
35
+ tenantId: A().nullable()
36
+ }).index("byThreadEvents", ["threadId"]), B = k("_voltro_comment_reactions", {
37
+ id: w({ prefix: "cmtrx" }),
38
+ commentId: A(),
39
+ subjectId: A(),
40
+ emoji: A()
41
41
  }).unique("byReactionIdentity", [
42
42
  "commentId",
43
43
  "subjectId",
44
44
  "emoji"
45
- ]).index("byReactionComment", ["commentId"]), V = A("_voltro_comment_reads", {
46
- id: T({ prefix: "cmtread" }),
47
- threadId: j(),
48
- subjectId: j(),
49
- lastReadAt: M()
45
+ ]).index("byReactionComment", ["commentId"]), V = k("_voltro_comment_reads", {
46
+ id: w({ prefix: "cmtread" }),
47
+ threadId: A(),
48
+ subjectId: A(),
49
+ lastReadAt: j()
50
50
  }).unique("byReadThreadSubject", ["threadId", "subjectId"]), H = s, U = (e) => {
51
51
  let t = e.request.subject ?? {};
52
52
  return {
53
53
  id: t.id ?? null,
54
54
  tenantId: t.tenantId ?? null,
55
- scopes: t.scopes ?? []
55
+ scopes: N(t)
56
56
  };
57
57
  }, W = (i = {}) => {
58
58
  let a = P({
59
59
  base: H,
60
60
  alias: i.alias,
61
61
  instance: i.name
62
- }), o, s, T = async (e, t, n) => o === void 0 ? [] : o.query({
62
+ }), o, s, w = async (e, t, n) => o === void 0 ? [] : o.query({
63
63
  table: e,
64
64
  predicate: t,
65
65
  order: [],
66
66
  take: n,
67
67
  skip: void 0,
68
68
  projection: void 0
69
- }), D = async (e, t, n, r) => {
69
+ }), E = async (e, t, n, r) => {
70
70
  let i = [], a = [...new Set(n)];
71
71
  for (let n = 0; n < a.length; n += 500) {
72
- let o = E(t, a.slice(n, n + 500));
73
- i.push(...await T(e, r === void 0 ? o : x(o, r)));
72
+ let o = T(t, a.slice(n, n + 500));
73
+ i.push(...await w(e, r === void 0 ? o : b(o, r)));
74
74
  }
75
75
  return i;
76
- }, A = (e, t) => {
76
+ }, k = (e, t) => {
77
77
  let n = /* @__PURE__ */ new Map();
78
78
  for (let r of e) {
79
79
  let e = String(r[t]), i = n.get(e);
80
80
  i === void 0 ? n.set(e, [r]) : i.push(r);
81
81
  }
82
82
  return n;
83
- }, j = () => {
83
+ }, A = () => {
84
84
  F(s, l);
85
- }, M = (t, n) => y.gen(function* () {
85
+ }, j = (t, n) => v.gen(function* () {
86
86
  let r = U(n);
87
- return i.access?.viaEntity === void 0 ? i.access?.scope === void 0 ? yield* y.fail(new e({
87
+ return i.access?.viaEntity === void 0 ? i.access?.scope === void 0 ? yield* v.fail(new e({
88
88
  anchor: t,
89
89
  reason: "no access rule declared — set commentsPlugin({ access: { viaEntity } }) or { access: { scope } }"
90
- })) : r.scopes.includes(i.access.scope) ? void 0 : yield* y.fail(new e({
90
+ })) : r.scopes.includes(i.access.scope) ? void 0 : yield* v.fail(new e({
91
91
  anchor: t,
92
92
  reason: `missing scope '${i.access.scope}'`
93
- })) : (yield* y.promise(async () => {
93
+ })) : (yield* v.promise(async () => {
94
94
  try {
95
95
  return await i.access.viaEntity({
96
96
  anchor: t,
@@ -100,25 +100,25 @@ var L = A("_voltro_comment_threads", {
100
100
  } catch {
101
101
  return !1;
102
102
  }
103
- })) ? void 0 : yield* y.fail(new e({
103
+ })) ? void 0 : yield* v.fail(new e({
104
104
  anchor: t,
105
105
  reason: "the anchored entity is not readable by this caller (or no longer available)"
106
106
  }));
107
- }), W = async (e) => (await T("_voltro_comment_threads", C("id", e), 1))[0], G = (e) => ({
107
+ }), N = async (e) => (await w("_voltro_comment_threads", S("id", e), 1))[0], W = (e) => ({
108
108
  id: String(e.id),
109
109
  anchor: String(e.anchor),
110
110
  kind: c.includes(String(e.kind)) ? e.kind : "discussion",
111
111
  status: e.status === "resolved" ? "resolved" : "open",
112
112
  createdBy: String(e.createdBy)
113
- }), K = (e, t) => i.visibleTo === void 0 || i.visibleTo({
114
- thread: G(e),
113
+ }), G = (e, t) => i.visibleTo === void 0 || i.visibleTo({
114
+ thread: W(e),
115
115
  subject: U(t)
116
- }), q = async (e, t) => {
117
- let n = await W(e);
118
- return n !== void 0 && K(n, t) ? n : void 0;
119
- }, J = async (e, t) => {
116
+ }), K = async (e, t) => {
117
+ let n = await N(e);
118
+ return n !== void 0 && G(n, t) ? n : void 0;
119
+ }, q = async (e, t) => {
120
120
  await e.insert("_voltro_comment_thread_events", {
121
- id: w({
121
+ id: C({
122
122
  kind: "typeid",
123
123
  prefix: "cmtevt"
124
124
  }, "_voltro_comment_thread_events"),
@@ -130,11 +130,11 @@ var L = A("_voltro_comment_threads", {
130
130
  at: (/* @__PURE__ */ new Date()).toISOString(),
131
131
  tenantId: t.tenantId
132
132
  });
133
- }, Y = (e) => e instanceof Date ? e.toISOString() : typeof e == "string" ? e : "", X = (e) => y.gen(function* () {
133
+ }, J = (e) => e instanceof Date ? e.toISOString() : typeof e == "string" ? e : "", Y = (e) => v.gen(function* () {
134
134
  if (e.mentions.length === 0) return;
135
- let t = yield* y.serviceOption(I);
136
- if (b.isNone(t)) yield* y.logInfo("comments: mention recorded without notification — @voltro/plugin-notifications is not configured");
137
- else for (let n of e.mentions) n !== e.author && (yield* y.promise(() => t.value.send({
135
+ let t = yield* v.serviceOption(I);
136
+ if (y.isNone(t)) yield* v.logInfo("comments: mention recorded without notification — @voltro/plugin-notifications is not configured");
137
+ else for (let n of e.mentions) n !== e.author && (yield* v.promise(() => t.value.send({
138
138
  to: n,
139
139
  category: i.mentionCategory ?? "mention",
140
140
  title: "You were mentioned",
@@ -145,7 +145,7 @@ var L = A("_voltro_comment_threads", {
145
145
  },
146
146
  tenantId: e.tenantId
147
147
  }).then(() => void 0).catch(() => void 0)));
148
- }), Z = async (e, t) => {
148
+ }), X = async (e, t) => {
149
149
  if (e.length === 0 || i.resolveMentions === void 0) return [];
150
150
  let n = [];
151
151
  for (let r of [...new Set(e)].slice(0, 20)) {
@@ -156,18 +156,18 @@ var L = A("_voltro_comment_threads", {
156
156
  e !== void 0 && (i.crossTenant === !0 || e.tenantId === void 0 || e.tenantId === null || e.tenantId === t.tenantId) && n.push(r);
157
157
  }
158
158
  return n;
159
- }, Q = async (e, t) => {
160
- let { tenantId: n, id: r } = U(t), i = (await T("_voltro_comment_threads", x(C("anchor", e), C("tenantId", n)))).filter((e) => K(e, t));
159
+ }, Z = async (e, t) => {
160
+ let { tenantId: n, id: r } = U(t), i = (await w("_voltro_comment_threads", b(S("anchor", e), S("tenantId", n)))).filter((e) => G(e, t));
161
161
  if (i.length === 0) return [];
162
162
  let a = i.map((e) => String(e.id)), [o, s, c] = await Promise.all([
163
- D("_voltro_comments", "threadId", a),
164
- r === null ? Promise.resolve([]) : D("_voltro_comment_reads", "threadId", a, C("subjectId", r)),
165
- D("_voltro_comment_thread_events", "threadId", a)
166
- ]), l = A(o, "threadId"), u = A(s, "threadId"), d = A(c, "threadId"), f = A(await D("_voltro_comment_reactions", "commentId", o.map((e) => String(e.id))), "commentId"), p = [];
163
+ E("_voltro_comments", "threadId", a),
164
+ r === null ? Promise.resolve([]) : E("_voltro_comment_reads", "threadId", a, S("subjectId", r)),
165
+ E("_voltro_comment_thread_events", "threadId", a)
166
+ ]), l = k(o, "threadId"), u = k(s, "threadId"), d = k(c, "threadId"), f = k(await E("_voltro_comment_reactions", "commentId", o.map((e) => String(e.id))), "commentId"), p = [];
167
167
  for (let e of i) {
168
168
  let t = l.get(String(e.id)) ?? [];
169
- t.sort((e, t) => Y(e.createdAt) < Y(t.createdAt) ? -1 : 1);
170
- let n = u.get(String(e.id)) ?? [], i = n[0] ? Y(n[0].lastReadAt) : "", a = [];
169
+ t.sort((e, t) => J(e.createdAt) < J(t.createdAt) ? -1 : 1);
170
+ let n = u.get(String(e.id)) ?? [], i = n[0] ? J(n[0].lastReadAt) : "", a = [];
171
171
  for (let e of t) {
172
172
  let t = f.get(String(e.id)) ?? [], n = /* @__PURE__ */ new Map();
173
173
  for (let e of t) {
@@ -183,8 +183,8 @@ var L = A("_voltro_comment_threads", {
183
183
  body: String(e.body),
184
184
  authorSubjectId: String(e.authorSubjectId),
185
185
  mentions: e.mentions ?? [],
186
- editedAt: e.editedAt == null ? null : Y(e.editedAt),
187
- createdAt: Y(e.createdAt),
186
+ editedAt: e.editedAt == null ? null : J(e.editedAt),
187
+ createdAt: J(e.createdAt),
188
188
  reactions: [...n.entries()].map(([e, t]) => ({
189
189
  emoji: e,
190
190
  count: t.count,
@@ -193,8 +193,8 @@ var L = A("_voltro_comment_threads", {
193
193
  });
194
194
  }
195
195
  let o = d.get(String(e.id)) ?? [];
196
- o.sort((e, t) => Y(e.at) < Y(t.at) ? -1 : Y(e.at) > Y(t.at) ? 1 : String(e.id) < String(t.id) ? -1 : 1);
197
- let s = G(e);
196
+ o.sort((e, t) => J(e.at) < J(t.at) ? -1 : J(e.at) > J(t.at) ? 1 : String(e.id) < String(t.id) ? -1 : 1);
197
+ let s = W(e);
198
198
  p.push({
199
199
  id: s.id,
200
200
  anchor: s.anchor,
@@ -202,58 +202,58 @@ var L = A("_voltro_comment_threads", {
202
202
  quote: e.quote ?? null,
203
203
  status: s.status,
204
204
  createdBy: String(e.createdBy),
205
- createdAt: Y(e.createdAt),
205
+ createdAt: J(e.createdAt),
206
206
  comments: a,
207
207
  unreadCount: a.filter((e) => String(e.authorSubjectId) !== r && String(e.createdAt) > i).length,
208
208
  history: o.map((e) => ({
209
209
  from: e.fromStatus === "open" || e.fromStatus === "resolved" ? e.fromStatus : null,
210
210
  to: e.toStatus === "resolved" ? "resolved" : "open",
211
211
  by: String(e.actor),
212
- at: Y(e.at),
212
+ at: J(e.at),
213
213
  reason: e.reason == null ? null : String(e.reason)
214
214
  }))
215
215
  });
216
216
  }
217
217
  return p.sort((e, t) => String(e.createdAt) < String(t.createdAt) ? -1 : 1), p;
218
- }, ee = [
218
+ }, Q = [
219
219
  {
220
220
  ...m,
221
221
  description: "Threads + comments + reactions + unread for one anchor, live.",
222
- execute: (e, t) => y.gen(function* () {
222
+ execute: (e, t) => v.gen(function* () {
223
223
  let { anchor: n } = e;
224
- return yield* M(n, t), yield* y.promise(() => Q(n, t));
224
+ return yield* j(n, t), yield* v.promise(() => Z(n, t));
225
225
  })
226
226
  },
227
227
  {
228
228
  ...d,
229
229
  description: "Comment on an anchor — a reply into a thread, or a new thread.",
230
- execute: (n, r) => y.gen(function* () {
230
+ execute: (n, r) => v.gen(function* () {
231
231
  let i = n;
232
- yield* M(i.anchor, r);
232
+ yield* j(i.anchor, r);
233
233
  let a = U(r), s = a.id ?? "anonymous", c = o;
234
- if (c === void 0) return yield* y.fail(new t({ id: i.anchor }));
234
+ if (c === void 0) return yield* v.fail(new t({ id: i.anchor }));
235
235
  let l = i.threadId;
236
236
  if (l !== void 0) {
237
- let e = yield* y.promise(() => q(l, r));
238
- if (e === void 0 || String(e.anchor) !== i.anchor) return yield* y.fail(new t({ id: l }));
237
+ let e = yield* v.promise(() => K(l, r));
238
+ if (e === void 0 || String(e.anchor) !== i.anchor) return yield* v.fail(new t({ id: l }));
239
239
  } else {
240
- let t = w({
240
+ let t = C({
241
241
  kind: "typeid",
242
242
  prefix: "cmtthr"
243
243
  }, "_voltro_comment_threads");
244
244
  l = t;
245
245
  let n = i.kind ?? "discussion";
246
- if (!K({
246
+ if (!G({
247
247
  id: t,
248
248
  anchor: i.anchor,
249
249
  kind: n,
250
250
  status: "open",
251
251
  createdBy: s
252
- }, r)) return yield* y.fail(new e({
252
+ }, r)) return yield* v.fail(new e({
253
253
  anchor: i.anchor,
254
254
  reason: `a ${n} thread here would not be visible to its author`
255
255
  }));
256
- yield* y.promise(async () => {
256
+ yield* v.promise(async () => {
257
257
  await c.insert("_voltro_comment_threads", {
258
258
  id: t,
259
259
  anchor: i.anchor,
@@ -263,7 +263,7 @@ var L = A("_voltro_comment_threads", {
263
263
  createdBy: s,
264
264
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
265
265
  tenantId: a.tenantId
266
- }), await J(c, {
266
+ }), await q(c, {
267
267
  threadId: t,
268
268
  from: null,
269
269
  to: "open",
@@ -273,11 +273,11 @@ var L = A("_voltro_comment_threads", {
273
273
  });
274
274
  });
275
275
  }
276
- let u = yield* y.promise(() => Z(i.mentions ?? [], a)), d = w({
276
+ let u = yield* v.promise(() => X(i.mentions ?? [], a)), d = C({
277
277
  kind: "typeid",
278
278
  prefix: "cmt"
279
279
  }, "_voltro_comments");
280
- return yield* y.promise(() => c.insert("_voltro_comments", {
280
+ return yield* v.promise(() => c.insert("_voltro_comments", {
281
281
  id: d,
282
282
  threadId: l,
283
283
  body: i.body,
@@ -286,7 +286,7 @@ var L = A("_voltro_comment_threads", {
286
286
  editedAt: null,
287
287
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
288
288
  tenantId: a.tenantId
289
- })), j(), yield* X({
289
+ })), A(), yield* Y({
290
290
  mentions: u,
291
291
  author: s,
292
292
  anchor: i.anchor,
@@ -302,27 +302,27 @@ var L = A("_voltro_comment_threads", {
302
302
  {
303
303
  ...p,
304
304
  description: "Edit your own comment.",
305
- execute: (e, r) => y.gen(function* () {
306
- let i = e, a = (yield* y.promise(() => T("_voltro_comments", C("id", i.commentId), 1)))[0];
307
- if (a === void 0) return yield* y.fail(new t({ id: i.commentId }));
308
- let s = yield* y.promise(() => q(String(a.threadId), r));
309
- return s === void 0 ? yield* y.fail(new t({ id: i.commentId })) : (yield* M(String(s.anchor), r), String(a.authorSubjectId) === (U(r).id ?? "anonymous") ? (yield* y.promise(() => o.update("_voltro_comments", i.commentId, {
305
+ execute: (e, r) => v.gen(function* () {
306
+ let i = e, a = (yield* v.promise(() => w("_voltro_comments", S("id", i.commentId), 1)))[0];
307
+ if (a === void 0) return yield* v.fail(new t({ id: i.commentId }));
308
+ let s = yield* v.promise(() => K(String(a.threadId), r));
309
+ return s === void 0 ? yield* v.fail(new t({ id: i.commentId })) : (yield* j(String(s.anchor), r), String(a.authorSubjectId) === (U(r).id ?? "anonymous") ? (yield* v.promise(() => o.update("_voltro_comments", i.commentId, {
310
310
  body: i.body,
311
311
  editedAt: (/* @__PURE__ */ new Date()).toISOString()
312
- })), j(), { ok: !0 }) : yield* y.fail(new n({ id: i.commentId })));
312
+ })), A(), { ok: !0 }) : yield* v.fail(new n({ id: i.commentId })));
313
313
  })
314
314
  },
315
315
  {
316
- ...v,
316
+ ...ee,
317
317
  description: "Resolve or reopen a thread.",
318
- execute: (e, n) => y.gen(function* () {
319
- let a = e, s = yield* y.promise(() => q(a.threadId, n));
320
- if (s === void 0) return yield* y.fail(new t({ id: a.threadId }));
321
- yield* M(String(s.anchor), n);
322
- let c = G(s), l = a.resolved ? "resolved" : "open";
318
+ execute: (e, n) => v.gen(function* () {
319
+ let a = e, s = yield* v.promise(() => K(a.threadId, n));
320
+ if (s === void 0) return yield* v.fail(new t({ id: a.threadId }));
321
+ yield* j(String(s.anchor), n);
322
+ let c = W(s), l = a.resolved ? "resolved" : "open";
323
323
  if (c.status === l) return { ok: !0 };
324
324
  let u = U(n);
325
- if (i.statusPolicy !== void 0 && !(yield* y.promise(async () => {
325
+ if (i.statusPolicy !== void 0 && !(yield* v.promise(async () => {
326
326
  try {
327
327
  return await i.statusPolicy({
328
328
  thread: c,
@@ -333,13 +333,13 @@ var L = A("_voltro_comment_threads", {
333
333
  } catch {
334
334
  return !1;
335
335
  }
336
- }))) return yield* y.fail(new r({
336
+ }))) return yield* v.fail(new r({
337
337
  threadId: a.threadId,
338
338
  reason: `the status policy does not let this caller ${a.resolved ? "resolve" : "reopen"} this ${c.kind} thread`
339
339
  }));
340
340
  let d = a.reason?.trim() ? a.reason.trim() : null;
341
- return yield* y.promise(async () => {
342
- await o.update("_voltro_comment_threads", a.threadId, { status: l }), await J(o, {
341
+ return yield* v.promise(async () => {
342
+ await o.update("_voltro_comment_threads", a.threadId, { status: l }), await q(o, {
343
343
  threadId: a.threadId,
344
344
  from: c.status,
345
345
  to: l,
@@ -347,59 +347,59 @@ var L = A("_voltro_comment_threads", {
347
347
  reason: d,
348
348
  tenantId: u.tenantId
349
349
  });
350
- }), j(), { ok: !0 };
350
+ }), A(), { ok: !0 };
351
351
  })
352
352
  },
353
353
  {
354
354
  ...f,
355
355
  description: "Delete your own comment (comments:moderate deletes any).",
356
- execute: (e, r) => y.gen(function* () {
357
- let i = e, a = (yield* y.promise(() => T("_voltro_comments", C("id", i.commentId), 1)))[0];
358
- if (a === void 0) return yield* y.fail(new t({ id: i.commentId }));
359
- let s = yield* y.promise(() => q(String(a.threadId), r));
360
- if (s === void 0) return yield* y.fail(new t({ id: i.commentId }));
361
- yield* M(String(s.anchor), r);
356
+ execute: (e, r) => v.gen(function* () {
357
+ let i = e, a = (yield* v.promise(() => w("_voltro_comments", S("id", i.commentId), 1)))[0];
358
+ if (a === void 0) return yield* v.fail(new t({ id: i.commentId }));
359
+ let s = yield* v.promise(() => K(String(a.threadId), r));
360
+ if (s === void 0) return yield* v.fail(new t({ id: i.commentId }));
361
+ yield* j(String(s.anchor), r);
362
362
  let c = U(r);
363
- return String(a.authorSubjectId) !== (c.id ?? "anonymous") && !c.scopes.includes("comments:moderate") ? yield* y.fail(new n({ id: i.commentId })) : (yield* y.promise(async () => {
364
- for (let e of await T("_voltro_comment_reactions", C("commentId", i.commentId))) await o.delete("_voltro_comment_reactions", String(e.id));
363
+ return String(a.authorSubjectId) !== (c.id ?? "anonymous") && !c.scopes.includes("comments:moderate") ? yield* v.fail(new n({ id: i.commentId })) : (yield* v.promise(async () => {
364
+ for (let e of await w("_voltro_comment_reactions", S("commentId", i.commentId))) await o.delete("_voltro_comment_reactions", String(e.id));
365
365
  await o.delete("_voltro_comments", i.commentId);
366
- }), j(), { ok: !0 });
366
+ }), A(), { ok: !0 });
367
367
  })
368
368
  },
369
369
  {
370
370
  ..._,
371
371
  description: "Toggle an emoji reaction on a comment.",
372
- execute: (e, n) => y.gen(function* () {
373
- let r = e, i = (yield* y.promise(() => T("_voltro_comments", C("id", r.commentId), 1)))[0];
374
- if (i === void 0) return yield* y.fail(new t({ id: r.commentId }));
375
- let a = yield* y.promise(() => q(String(i.threadId), n));
376
- if (a === void 0) return yield* y.fail(new t({ id: r.commentId }));
377
- yield* M(String(a.anchor), n);
378
- let s = U(n).id ?? "anonymous", c = (yield* y.promise(() => T("_voltro_comment_reactions", x(C("commentId", r.commentId), x(C("subjectId", s), C("emoji", r.emoji))), 1)))[0];
379
- if (c !== void 0) return yield* y.promise(() => o.delete("_voltro_comment_reactions", String(c.id))), j(), { reacted: !1 };
380
- let l = w({
372
+ execute: (e, n) => v.gen(function* () {
373
+ let r = e, i = (yield* v.promise(() => w("_voltro_comments", S("id", r.commentId), 1)))[0];
374
+ if (i === void 0) return yield* v.fail(new t({ id: r.commentId }));
375
+ let a = yield* v.promise(() => K(String(i.threadId), n));
376
+ if (a === void 0) return yield* v.fail(new t({ id: r.commentId }));
377
+ yield* j(String(a.anchor), n);
378
+ let s = U(n).id ?? "anonymous", c = (yield* v.promise(() => w("_voltro_comment_reactions", b(S("commentId", r.commentId), b(S("subjectId", s), S("emoji", r.emoji))), 1)))[0];
379
+ if (c !== void 0) return yield* v.promise(() => o.delete("_voltro_comment_reactions", String(c.id))), A(), { reacted: !1 };
380
+ let l = C({
381
381
  kind: "typeid",
382
382
  prefix: "cmtrx"
383
383
  }, "_voltro_comment_reactions");
384
- return yield* y.promise(() => o.insert("_voltro_comment_reactions", {
384
+ return yield* v.promise(() => o.insert("_voltro_comment_reactions", {
385
385
  id: l,
386
386
  commentId: r.commentId,
387
387
  subjectId: s,
388
388
  emoji: r.emoji
389
- })), j(), { reacted: !0 };
389
+ })), A(), { reacted: !0 };
390
390
  })
391
391
  },
392
392
  {
393
393
  ...h,
394
394
  description: "Stamp the caller's read marker for a thread.",
395
- execute: (e, n) => y.gen(function* () {
395
+ execute: (e, n) => v.gen(function* () {
396
396
  let r = e;
397
- if ((yield* y.promise(() => W(r.threadId))) === void 0) return yield* y.fail(new t({ id: r.threadId }));
398
- let i = U(n).id ?? "anonymous", a = w({
397
+ if ((yield* v.promise(() => N(r.threadId))) === void 0) return yield* v.fail(new t({ id: r.threadId }));
398
+ let i = U(n).id ?? "anonymous", a = C({
399
399
  kind: "typeid",
400
400
  prefix: "cmtread"
401
401
  }, "_voltro_comment_reads");
402
- return yield* y.promise(() => o.upsert("_voltro_comment_reads", {
402
+ return yield* v.promise(() => o.upsert("_voltro_comment_reads", {
403
403
  id: a,
404
404
  threadId: r.threadId,
405
405
  subjectId: i,
@@ -413,7 +413,7 @@ var L = A("_voltro_comment_threads", {
413
413
  {
414
414
  ...g,
415
415
  description: "@-mention autocomplete over the app-declared directory, tenant-filtered.",
416
- execute: (e, t) => y.promise(async () => {
416
+ execute: (e, t) => v.promise(async () => {
417
417
  let { query: n } = e;
418
418
  if (i.resolveMentions === void 0) return [];
419
419
  let r = U(t);
@@ -433,7 +433,7 @@ var L = A("_voltro_comment_threads", {
433
433
  kind: "json",
434
434
  data: e
435
435
  });
436
- return N({
436
+ return M({
437
437
  name: a,
438
438
  baseName: H,
439
439
  description: "Comment threads on any app entity — replies, resolve/reopen, @-mentions with notifications, reactions, unread — live over the reactive engine.",
@@ -445,17 +445,17 @@ var L = A("_voltro_comment_threads", {
445
445
  B,
446
446
  V
447
447
  ] },
448
- routes: ee,
448
+ routes: Q,
449
449
  rpcClientDescriptors: u,
450
450
  inspectEndpoints: [{
451
451
  method: "GET",
452
452
  path: "/threads",
453
453
  scope: "process",
454
454
  description: "Thread volume and searchable, paginated threads (operator surface).",
455
- handler: (e) => y.promise(async () => {
455
+ handler: (e) => v.promise(async () => {
456
456
  let t = new URL(e.url, "http://inspect.local").searchParams, n = t.get("threadId"), r = Number(t.get("offset") ?? 0), i = Number.isSafeInteger(r) && r >= 0 ? r : 0, a = (t.get("search") ?? "").trim().slice(0, 200);
457
457
  if (n) {
458
- let e = (await T("_voltro_comment_threads", C("id", n), 1))[0], t = C("threadId", n), [r, a] = e && o ? await Promise.all([o.query({
458
+ let e = (await w("_voltro_comment_threads", S("id", n), 1))[0], t = S("threadId", n), [r, a] = e && o ? await Promise.all([o.query({
459
459
  table: "_voltro_comments",
460
460
  predicate: t,
461
461
  order: [{
@@ -496,8 +496,8 @@ var L = A("_voltro_comment_threads", {
496
496
  id: String(e.id),
497
497
  body: String(e.body),
498
498
  author: String(e.authorSubjectId),
499
- createdAt: Y(e.createdAt),
500
- editedAt: e.editedAt == null ? null : Y(e.editedAt)
499
+ createdAt: J(e.createdAt),
500
+ editedAt: e.editedAt == null ? null : J(e.editedAt)
501
501
  }))
502
502
  }
503
503
  });
@@ -517,7 +517,7 @@ var L = A("_voltro_comment_threads", {
517
517
  }]
518
518
  });
519
519
  return Number(n[0]?.count ?? 0);
520
- }, c = a ? k(S("anchor", a), S("id", a), S("createdBy", a)) : void 0, [l, u, d, f, p] = await Promise.all([
520
+ }, c = a ? O(x("anchor", a), x("id", a), x("createdBy", a)) : void 0, [l, u, d, f, p] = await Promise.all([
521
521
  o.query({
522
522
  table: "_voltro_comment_threads",
523
523
  predicate: c,
@@ -533,12 +533,12 @@ var L = A("_voltro_comment_threads", {
533
533
  projection: void 0
534
534
  }),
535
535
  s("_voltro_comment_threads"),
536
- s("_voltro_comment_threads", O("status", "resolved")),
536
+ s("_voltro_comment_threads", D("status", "resolved")),
537
537
  s("_voltro_comments"),
538
538
  s("_voltro_comment_threads", c)
539
539
  ]), m = l.length === 0 ? [] : await o.query({
540
540
  table: "_voltro_comments",
541
- predicate: E("threadId", l.map((e) => String(e.id))),
541
+ predicate: T("threadId", l.map((e) => String(e.id))),
542
542
  order: [],
543
543
  take: void 0,
544
544
  skip: void 0,
@@ -570,7 +570,7 @@ var L = A("_voltro_comment_threads", {
570
570
  anchor: String(e.anchor),
571
571
  status: String(e.status),
572
572
  createdBy: String(e.createdBy),
573
- createdAt: Y(e.createdAt),
573
+ createdAt: J(e.createdAt),
574
574
  comments: h.get(String(e.id)) ?? 0
575
575
  }))
576
576
  });
@@ -579,10 +579,10 @@ var L = A("_voltro_comment_threads", {
579
579
  bindDataStore: (e) => {
580
580
  o = e, s = e;
581
581
  },
582
- onActivate: (e) => y.sync(() => {
582
+ onActivate: (e) => v.sync(() => {
583
583
  i.access?.viaEntity === void 0 && i.access?.scope === void 0 && e.logger.warn("comments: no access rule declared — EVERY read and write will be refused (fail-closed). Set commentsPlugin({ access: { viaEntity } }) or { access: { scope } }."), e.logger.info("comments active", { mentions: i.resolveMentions !== void 0 });
584
584
  }),
585
- onDeactivate: () => y.sync(() => {
585
+ onDeactivate: () => v.sync(() => {
586
586
  o = void 0, s = void 0;
587
587
  })
588
588
  });
@@ -598,20 +598,20 @@ var L = A("_voltro_comment_threads", {
598
598
  for (let [o, s] of Object.entries(t)) {
599
599
  if (s === void 0 || !(s >= 0)) continue;
600
600
  let t = n.getTime() - s * 864e5;
601
- for (let c of await r("_voltro_comment_threads", x(C("status", "resolved"), C("kind", o)))) {
602
- let o = [...await r("_voltro_comment_thread_events", C("threadId", String(c.id)))], l = (e) => new Date(e.at instanceof Date ? e.at : String(e.at)).getTime();
601
+ for (let c of await r("_voltro_comment_threads", b(S("status", "resolved"), S("kind", o)))) {
602
+ let o = [...await r("_voltro_comment_thread_events", S("threadId", String(c.id)))], l = (e) => new Date(e.at instanceof Date ? e.at : String(e.at)).getTime();
603
603
  o.sort((e, t) => l(e) - l(t));
604
604
  let u = [...o].reverse().find((e) => e.toStatus === "resolved" && e.fromStatus === "open");
605
605
  if (u === void 0 || l(u) > t) continue;
606
- let d = await r("_voltro_comments", C("threadId", String(c.id)));
606
+ let d = await r("_voltro_comments", S("threadId", String(c.id)));
607
607
  if (d.length !== 0) {
608
608
  for (let t of d) {
609
- for (let n of await r("_voltro_comment_reactions", C("commentId", String(t.id)))) await e.delete("_voltro_comment_reactions", String(n.id));
609
+ for (let n of await r("_voltro_comment_reactions", S("commentId", String(t.id)))) await e.delete("_voltro_comment_reactions", String(n.id));
610
610
  await e.delete("_voltro_comments", String(t.id));
611
611
  }
612
- for (let t of await r("_voltro_comment_reads", C("threadId", String(c.id)))) await e.delete("_voltro_comment_reads", String(t.id));
612
+ for (let t of await r("_voltro_comment_reads", S("threadId", String(c.id)))) await e.delete("_voltro_comment_reads", String(t.id));
613
613
  await e.insert("_voltro_comment_thread_events", {
614
- id: w({
614
+ id: C({
615
615
  kind: "typeid",
616
616
  prefix: "cmtevt"
617
617
  }, "_voltro_comment_thread_events"),
@@ -631,5 +631,4 @@ var L = A("_voltro_comment_threads", {
631
631
  comments: a
632
632
  };
633
633
  }, K = () => "plugin-comments";
634
- //#endregion
635
634
  export { c as COMMENT_THREAD_KINDS, e as CommentAccessRefused, t as CommentNotFound, n as CommentNotYours, r as CommentStatusRefused, i as QUOTE_MAX_LENGTH, G as applyCommentRetention, B as commentReactionsTable, V as commentReadsTable, z as commentThreadEventsTable, L as commentThreadsTable, l as commentsFeed, W as commentsPlugin, R as commentsTable, a as findQuote, K as pluginComments, o as textQuote };
package/dist/quote.js CHANGED
@@ -1,4 +1,4 @@
1
- //#region src/quote.ts
1
+ // src/quote.ts
2
2
  var e = 1e3, t = (t, n, r) => {
3
3
  let i = Math.max(0, Math.min(n, r)), a = Math.min(t.length, Math.max(n, r), i + e), o = t.slice(Math.max(0, i - 32), i), s = t.slice(a, a + 32);
4
4
  return {
@@ -21,5 +21,4 @@ var e = 1e3, t = (t, n, r) => {
21
21
  end: n.start + t.exact.length
22
22
  };
23
23
  };
24
- //#endregion
25
24
  export { e as QUOTE_MAX_LENGTH, n as findQuote, t as textQuote };