@critical-path/svelte 0.6.0 → 0.8.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/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @critical-path/svelte
2
2
 
3
+ ## 0.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 55549e9: Support @mentions in comments with extraction and segmentation utilities
8
+
9
+ - Add `mentions?: string[]` to `Comment` interface
10
+ - Add `extractMentions` and `parseMentionSegments` utilities for mention parsing and UI rendering
11
+ - Auto-extract and populate mentions during `addComment` and `updateComment` in the engine
12
+ - Update SQLite comments schema with `mentions` column and migration
13
+ - Preserve and pass through mentions in server routes, client SDK, and Svelte bindings
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies [55549e9]
18
+ - @critical-path/core@0.11.0
19
+ - @critical-path/client@0.6.0
20
+
21
+ ## 0.7.0
22
+
23
+ ### Minor Changes
24
+
25
+ - e9003d3: Add emoji reactions support for comment conversations with domain events, deduplication, REST endpoints, client SDK, and React/Svelte state integrations.
26
+
27
+ ### Patch Changes
28
+
29
+ - Updated dependencies [e9003d3]
30
+ - @critical-path/core@0.10.0
31
+ - @critical-path/client@0.5.0
32
+
3
33
  ## 0.6.0
4
34
 
5
35
  ### Minor Changes
package/README.md CHANGED
@@ -89,6 +89,13 @@ Combines threaded comments with inline attachments (`attachment.commentId === co
89
89
  </div>
90
90
  {/if}
91
91
 
92
+ <!-- Emoji Reactions -->
93
+ <div class="reactions">
94
+ <button on:click={() => activityState.addReaction(thread.id, '👍', 'user_1')}>👍</button>
95
+ <button on:click={() => activityState.addReaction(thread.id, '🚀', 'user_1')}>🚀</button>
96
+ <span>{thread.reactions?.length || 0} reactions</span>
97
+ </div>
98
+
92
99
  <!-- Threaded replies -->
93
100
  {#each thread.replies as reply}
94
101
  <div class="reply">
@@ -22,6 +22,14 @@ export declare class TaskActivityState {
22
22
  addAttachment(input: Omit<Attachment, 'id' | 'taskId' | 'createdAt' | 'updatedAt'>): Promise<Attachment>;
23
23
  deleteComment(id: string): Promise<void>;
24
24
  deleteAttachment(id: string): Promise<void>;
25
+ addReaction(commentId: string, reactionOrEmoji: {
26
+ emoji: string;
27
+ userId: string;
28
+ } | string, maybeUserId?: string): Promise<Comment>;
29
+ removeReaction(commentId: string, reactionOrEmoji: {
30
+ emoji: string;
31
+ userId: string;
32
+ } | string, maybeUserId?: string): Promise<Comment>;
25
33
  }
26
34
  export declare function createTaskActivityState(client: CriticalPathClient, taskId?: string): TaskActivityState;
27
35
  //# sourceMappingURL=activity-state.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"activity-state.svelte.d.ts","sourceRoot":"","sources":["../src/activity-state.svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,WAAW,8BAA+B,SAAQ,OAAO;IAC7D,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,OAAO,EAAE,8BAA8B,EAAE,CAAC;CAC3C;AAED,qBAAa,iBAAiB;IA6ChB,OAAO,CAAC,MAAM;IAA6B,MAAM,CAAC,EAAE,MAAM;IA5CtE,QAAQ,YAAyB;IACjC,WAAW,eAA4B;IACvC,OAAO,UAA0B;IACjC,KAAK,eAA8B;IAEnC,OAAO,mCAiCJ;IAEH,qBAAqB,eAElB;gBAEiB,MAAM,EAAE,kBAAkB,EAAS,MAAM,CAAC,EAAE,MAAM,YAAA;IAEhE,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM;IAwBrB,UAAU,CACd,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC,EACjE,gBAAgB,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC;;;;IAiCjG,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IAelF,aAAa,CAAC,EAAE,EAAE,MAAM;IAaxB,gBAAgB,CAAC,EAAE,EAAE,MAAM;CAYlC;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAEtG"}
1
+ {"version":3,"file":"activity-state.svelte.d.ts","sourceRoot":"","sources":["../src/activity-state.svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,WAAW,8BAA+B,SAAQ,OAAO;IAC7D,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,OAAO,EAAE,8BAA8B,EAAE,CAAC;CAC3C;AAED,qBAAa,iBAAiB;IA6ChB,OAAO,CAAC,MAAM;IAA6B,MAAM,CAAC,EAAE,MAAM;IA5CtE,QAAQ,YAAyB;IACjC,WAAW,eAA4B;IACvC,OAAO,UAA0B;IACjC,KAAK,eAA8B;IAEnC,OAAO,mCAiCJ;IAEH,qBAAqB,eAElB;gBAEiB,MAAM,EAAE,kBAAkB,EAAS,MAAM,CAAC,EAAE,MAAM,YAAA;IAEhE,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM;IAwBrB,UAAU,CACd,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC,EACjE,gBAAgB,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC;;;;IAiCjG,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IAelF,aAAa,CAAC,EAAE,EAAE,MAAM;IAaxB,gBAAgB,CAAC,EAAE,EAAE,MAAM;IAa3B,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,EAC3D,WAAW,CAAC,EAAE,MAAM;IAiBhB,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,EAC3D,WAAW,CAAC,EAAE,MAAM;CAgBvB;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAEtG"}
@@ -15,6 +15,14 @@ export declare class CommentState {
15
15
  addComment(input: Omit<Comment, 'id' | 'taskId' | 'createdAt' | 'updatedAt'>): Promise<Comment>;
16
16
  updateComment(id: string, updates: Partial<Comment>): Promise<Comment>;
17
17
  deleteComment(id: string): Promise<void>;
18
+ addReaction(commentId: string, reactionOrEmoji: {
19
+ emoji: string;
20
+ userId: string;
21
+ } | string, maybeUserId?: string): Promise<Comment>;
22
+ removeReaction(commentId: string, reactionOrEmoji: {
23
+ emoji: string;
24
+ userId: string;
25
+ } | string, maybeUserId?: string): Promise<Comment>;
18
26
  }
19
27
  export declare function createCommentState(client: CriticalPathClient, taskId?: string): CommentState;
20
28
  //# sourceMappingURL=comment-state.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"comment-state.svelte.d.ts","sourceRoot":"","sources":["../src/comment-state.svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,WAAW,eAAgB,SAAQ,OAAO;IAC9C,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED,qBAAa,YAAY;IAyBX,OAAO,CAAC,MAAM;IAA6B,MAAM,CAAC,EAAE,MAAM;IAxBtE,IAAI,YAAyB;IAC7B,OAAO,UAA0B;IACjC,KAAK,eAA8B;IAEnC,OAAO,oBAkBJ;gBAEiB,MAAM,EAAE,kBAAkB,EAAS,MAAM,CAAC,EAAE,MAAM,YAAA;IAEhE,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM;IAkBrB,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IAe5E,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;IAYnD,aAAa,CAAC,EAAE,EAAE,MAAM;CAY/B;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,CAE5F"}
1
+ {"version":3,"file":"comment-state.svelte.d.ts","sourceRoot":"","sources":["../src/comment-state.svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,WAAW,eAAgB,SAAQ,OAAO;IAC9C,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED,qBAAa,YAAY;IAyBX,OAAO,CAAC,MAAM;IAA6B,MAAM,CAAC,EAAE,MAAM;IAxBtE,IAAI,YAAyB;IAC7B,OAAO,UAA0B;IACjC,KAAK,eAA8B;IAEnC,OAAO,oBAkBJ;gBAEiB,MAAM,EAAE,kBAAkB,EAAS,MAAM,CAAC,EAAE,MAAM,YAAA;IAEhE,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM;IAkBrB,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IAe5E,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;IAYnD,aAAa,CAAC,EAAE,EAAE,MAAM;IAaxB,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,EAC3D,WAAW,CAAC,EAAE,MAAM;IAiBhB,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,EAC3D,WAAW,CAAC,EAAE,MAAM;CAgBvB;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,CAE5F"}
package/dist/index.js CHANGED
@@ -347,6 +347,30 @@ var c = class {
347
347
  throw this.error = n, n;
348
348
  }
349
349
  }
350
+ async addReaction(e, t, n) {
351
+ try {
352
+ let r = typeof t == "string" ? {
353
+ emoji: t,
354
+ userId: n
355
+ } : t, i = await this.client.addCommentReaction(e, r);
356
+ return this.data = this.data.map((t) => t.id === e ? i : t), i;
357
+ } catch (e) {
358
+ let t = e instanceof Error ? e : Error(String(e));
359
+ throw this.error = t, t;
360
+ }
361
+ }
362
+ async removeReaction(e, t, n) {
363
+ try {
364
+ let r = typeof t == "string" ? {
365
+ emoji: t,
366
+ userId: n
367
+ } : t, i = await this.client.removeCommentReaction(e, r);
368
+ return this.data = this.data.map((t) => t.id === e ? i : t), i;
369
+ } catch (e) {
370
+ let t = e instanceof Error ? e : Error(String(e));
371
+ throw this.error = t, t;
372
+ }
373
+ }
350
374
  };
351
375
  function l(e, t) {
352
376
  return new c(e, t);
@@ -548,6 +572,30 @@ var f = class {
548
572
  throw this.error = n, n;
549
573
  }
550
574
  }
575
+ async addReaction(e, t, n) {
576
+ try {
577
+ let r = typeof t == "string" ? {
578
+ emoji: t,
579
+ userId: n
580
+ } : t, i = await this.client.addCommentReaction(e, r);
581
+ return this.comments = this.comments.map((t) => t.id === e ? i : t), i;
582
+ } catch (e) {
583
+ let t = e instanceof Error ? e : Error(String(e));
584
+ throw this.error = t, t;
585
+ }
586
+ }
587
+ async removeReaction(e, t, n) {
588
+ try {
589
+ let r = typeof t == "string" ? {
590
+ emoji: t,
591
+ userId: n
592
+ } : t, i = await this.client.removeCommentReaction(e, r);
593
+ return this.comments = this.comments.map((t) => t.id === e ? i : t), i;
594
+ } catch (e) {
595
+ let t = e instanceof Error ? e : Error(String(e));
596
+ throw this.error = t, t;
597
+ }
598
+ }
551
599
  };
552
600
  function p(e, t) {
553
601
  return new f(e, t);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@critical-path/svelte",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Svelte 5 Runes state and reactive integrations for Critical Path headless project management framework",
5
5
  "author": "Jack James",
6
6
  "license": "MIT",
@@ -18,8 +18,8 @@
18
18
  }
19
19
  },
20
20
  "dependencies": {
21
- "@critical-path/core": "0.9.0",
22
- "@critical-path/client": "0.4.4"
21
+ "@critical-path/client": "0.6.0",
22
+ "@critical-path/core": "0.11.0"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "svelte": "^5.0.0"
@@ -153,6 +153,46 @@ export class TaskActivityState {
153
153
  throw errorObj;
154
154
  }
155
155
  }
156
+
157
+ async addReaction(
158
+ commentId: string,
159
+ reactionOrEmoji: { emoji: string; userId: string } | string,
160
+ maybeUserId?: string
161
+ ) {
162
+ try {
163
+ const payload =
164
+ typeof reactionOrEmoji === 'string'
165
+ ? { emoji: reactionOrEmoji, userId: maybeUserId! }
166
+ : reactionOrEmoji;
167
+ const updated = await this.client.addCommentReaction(commentId, payload);
168
+ this.comments = this.comments.map((c) => (c.id === commentId ? updated : c));
169
+ return updated;
170
+ } catch (err) {
171
+ const errorObj = err instanceof Error ? err : new Error(String(err));
172
+ this.error = errorObj;
173
+ throw errorObj;
174
+ }
175
+ }
176
+
177
+ async removeReaction(
178
+ commentId: string,
179
+ reactionOrEmoji: { emoji: string; userId: string } | string,
180
+ maybeUserId?: string
181
+ ) {
182
+ try {
183
+ const payload =
184
+ typeof reactionOrEmoji === 'string'
185
+ ? { emoji: reactionOrEmoji, userId: maybeUserId! }
186
+ : reactionOrEmoji;
187
+ const updated = await this.client.removeCommentReaction(commentId, payload);
188
+ this.comments = this.comments.map((c) => (c.id === commentId ? updated : c));
189
+ return updated;
190
+ } catch (err) {
191
+ const errorObj = err instanceof Error ? err : new Error(String(err));
192
+ this.error = errorObj;
193
+ throw errorObj;
194
+ }
195
+ }
156
196
  }
157
197
 
158
198
  export function createTaskActivityState(client: CriticalPathClient, taskId?: string): TaskActivityState {
@@ -90,6 +90,46 @@ export class CommentState {
90
90
  throw errorObj;
91
91
  }
92
92
  }
93
+
94
+ async addReaction(
95
+ commentId: string,
96
+ reactionOrEmoji: { emoji: string; userId: string } | string,
97
+ maybeUserId?: string
98
+ ) {
99
+ try {
100
+ const payload =
101
+ typeof reactionOrEmoji === 'string'
102
+ ? { emoji: reactionOrEmoji, userId: maybeUserId! }
103
+ : reactionOrEmoji;
104
+ const updated = await this.client.addCommentReaction(commentId, payload);
105
+ this.data = this.data.map((c) => (c.id === commentId ? updated : c));
106
+ return updated;
107
+ } catch (err) {
108
+ const errorObj = err instanceof Error ? err : new Error(String(err));
109
+ this.error = errorObj;
110
+ throw errorObj;
111
+ }
112
+ }
113
+
114
+ async removeReaction(
115
+ commentId: string,
116
+ reactionOrEmoji: { emoji: string; userId: string } | string,
117
+ maybeUserId?: string
118
+ ) {
119
+ try {
120
+ const payload =
121
+ typeof reactionOrEmoji === 'string'
122
+ ? { emoji: reactionOrEmoji, userId: maybeUserId! }
123
+ : reactionOrEmoji;
124
+ const updated = await this.client.removeCommentReaction(commentId, payload);
125
+ this.data = this.data.map((c) => (c.id === commentId ? updated : c));
126
+ return updated;
127
+ } catch (err) {
128
+ const errorObj = err instanceof Error ? err : new Error(String(err));
129
+ this.error = errorObj;
130
+ throw errorObj;
131
+ }
132
+ }
93
133
  }
94
134
 
95
135
  export function createCommentState(client: CriticalPathClient, taskId?: string): CommentState {
package/src/index.test.ts CHANGED
@@ -216,12 +216,15 @@ describe('@critical-path/svelte Svelte 5 Runes Test Suite', () => {
216
216
  updatedAt: '2026-01-01'
217
217
  };
218
218
  const updatedComment = { ...mockComment, content: 'Updated comment' };
219
+ const reactedComment = { ...mockComment, reactions: [{ emoji: '🔥', userId: 'u2', createdAt: '2026-01-01' }] };
219
220
 
220
221
  const mockClient = {
221
222
  getComments: vi.fn().mockResolvedValue([mockComment]),
222
223
  addComment: vi.fn().mockResolvedValue(mockComment),
223
224
  updateComment: vi.fn().mockResolvedValue(updatedComment),
224
- deleteComment: vi.fn().mockResolvedValue(true)
225
+ deleteComment: vi.fn().mockResolvedValue(true),
226
+ addCommentReaction: vi.fn().mockResolvedValue(reactedComment),
227
+ removeCommentReaction: vi.fn().mockResolvedValue(mockComment)
225
228
  } as unknown as CriticalPathClient;
226
229
 
227
230
  const commentState = new CommentState(mockClient, 'task_1');
@@ -232,6 +235,13 @@ describe('@critical-path/svelte Svelte 5 Runes Test Suite', () => {
232
235
  await commentState.updateComment('cmt_1', { content: 'Updated comment' });
233
236
  expect(commentState.data[0].content).toBe('Updated comment');
234
237
 
238
+ await commentState.addReaction('cmt_1', '🔥', 'u2');
239
+ expect(commentState.data[0].reactions).toHaveLength(1);
240
+ expect(commentState.data[0].reactions?.[0].emoji).toBe('🔥');
241
+
242
+ await commentState.removeReaction('cmt_1', '🔥', 'u2');
243
+ expect(commentState.data[0].reactions).toBeUndefined();
244
+
235
245
  await commentState.deleteComment('cmt_1');
236
246
  expect(commentState.data).toEqual([]);
237
247
  });