@ericrisco/rsc 3.3.1 → 3.4.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.
Files changed (54) hide show
  1. package/README.md +2 -2
  2. package/manifest.json +43 -22
  3. package/package.json +1 -1
  4. package/scripts/lib/default-skill-floor.js +5 -1
  5. package/scripts/lib/domains.js +2 -2
  6. package/scripts/lib/retired-skills.js +4 -0
  7. package/skills/design/SKILL.md +4 -3
  8. package/skills/design/evals/cases.yaml +2 -2
  9. package/skills/react/SKILL.md +2 -1
  10. package/skills/ux/SKILL.md +149 -0
  11. package/skills/ux/THIRD_PARTY.md +32 -0
  12. package/skills/ux/evals/cases.yaml +40 -0
  13. package/skills/ux/references/flows.md +124 -0
  14. package/skills/ux/upstream/UPSTREAM.json +59 -0
  15. package/skills/ux/upstream/ux-designer/GUIDE.md +180 -0
  16. package/skills/ux/upstream/ux-designer/LICENSE +21 -0
  17. package/skills/ux/upstream/ux-designer/references/01-core-principles.md +251 -0
  18. package/skills/ux/upstream/ux-designer/references/02-laws-of-ux.md +330 -0
  19. package/skills/ux/upstream/ux-designer/references/03-accessibility.md +411 -0
  20. package/skills/ux/upstream/ux-designer/references/04-visual-design.md +433 -0
  21. package/skills/ux/upstream/ux-designer/references/05-information-architecture.md +432 -0
  22. package/skills/ux/upstream/ux-designer/references/06-interaction-design.md +495 -0
  23. package/skills/ux/upstream/ux-designer/references/07-forms-and-inputs.md +491 -0
  24. package/skills/ux/upstream/ux-designer/references/08-mobile-ux.md +539 -0
  25. package/skills/ux/upstream/ux-designer/references/09-ux-writing.md +493 -0
  26. package/skills/ux/upstream/ux-designer/references/10-user-research.md +533 -0
  27. package/skills/ux/upstream/ux-designer/references/11-design-systems.md +618 -0
  28. package/skills/ux/upstream/ux-designer/references/12a-presence-awareness.md +395 -0
  29. package/skills/ux/upstream/ux-designer/references/12b-conflict-resolution-sync.md +420 -0
  30. package/skills/ux/upstream/ux-designer/references/13a-canvas-navigation.md +388 -0
  31. package/skills/ux/upstream/ux-designer/references/13b-canvas-objects-performance.md +559 -0
  32. package/skills/ux/upstream/ux-designer/references/14-ai-ux-patterns.md +511 -0
  33. package/skills/ux/upstream/ux-designer/references/15-ethical-design.md +419 -0
  34. package/skills/ux/upstream/ux-designer/references/16-onboarding.md +430 -0
  35. package/skills/ux/upstream/ux-designer/references/17-notifications.md +461 -0
  36. package/skills/ux/upstream/ux-designer/references/18-data-visualization.md +453 -0
  37. package/skills/ux/upstream/ux-designer/references/19-search-ux.md +479 -0
  38. package/skills/ux/upstream/ux-designer/references/20-emotional-design.md +382 -0
  39. package/skills/ux/upstream/ux-designer/references/21-data-tables.md +629 -0
  40. package/skills/ux/upstream/ux-designer/references/22-performance-ux.md +626 -0
  41. package/skills/ux/upstream/ux-designer/references/23-internationalization.md +347 -0
  42. package/skills/ux/upstream/ux-designer/references/24-voice-and-multimodal.md +308 -0
  43. package/skills/ux/upstream/ux-designer/references/25a-barcode-camera-scanning.md +342 -0
  44. package/skills/ux/upstream/ux-designer/references/25b-barcode-scanner-workflows.md +412 -0
  45. package/skills/ux/upstream/ux-designer/references/25c-barcode-display.md +277 -0
  46. package/skills/ux/upstream/ux-usability-foundations/GUIDE.md +285 -0
  47. package/skills/ux/upstream/ux-usability-foundations/LICENSE +21 -0
  48. package/skills/ux/upstream/ux-usability-foundations/references/anti-patterns.md +267 -0
  49. package/skills/ux/upstream/ux-usability-foundations/references/checklists.md +130 -0
  50. package/skills/ux/upstream/ux-usability-foundations/references/decision-prompts.md +340 -0
  51. package/skills/ux/upstream/ux-usability-foundations/references/principle-cards.md +449 -0
  52. package/targets/clone-bootstrap.mjs +1 -1
  53. package/skills/ui-engineering/SKILL.md +0 -113
  54. package/skills/ui-engineering/evals/cases.yaml +0 -38
@@ -0,0 +1,420 @@
1
+ # Collaborative UX: Conflict Resolution & Sync
2
+
3
+ This reference covers the technical and UX aspects of concurrent editing, conflict resolution, version control, sharing permissions, and offline synchronization in collaborative applications.
4
+
5
+ ---
6
+
7
+ ## Contents
8
+
9
+ - Concurrent Editing
10
+ - Version Control & History
11
+ - Sharing & Permissions
12
+ - Offline & Sync
13
+ - Key Metrics
14
+ - Anti-Patterns
15
+ - Sources
16
+
17
+ ---
18
+
19
+ ## Concurrent Editing
20
+
21
+ ### Conflict Resolution Approaches
22
+
23
+ #### Operational Transformation (OT)
24
+
25
+ Used by Google Docs. Server-centric, transforms operations to maintain consistency.
26
+
27
+ ```
28
+ User A types "Hello" at position 0
29
+ User B types "World" at position 0 (simultaneously)
30
+
31
+ Server transforms B's operation:
32
+ - B intended position 0
33
+ - A inserted 5 chars before B's cursor
34
+ - B's operation becomes: insert "World" at position 5
35
+
36
+ Result: "HelloWorld" (consistent for both)
37
+ ```
38
+
39
+ **UX Implications:**
40
+ - Low-latency feel with optimistic updates
41
+ - Requires constant server connection
42
+ - Complex to implement correctly for rich content
43
+
44
+ #### CRDTs (Conflict-free Replicated Data Types)
45
+
46
+ Used by Figma, Notion. Mathematically guaranteed to converge.
47
+
48
+ ```
49
+ Benefits:
50
+ - Works offline (sync when reconnected)
51
+ - No central server required
52
+ - Automatic conflict resolution
53
+
54
+ UX Benefits:
55
+ - True offline-first capability
56
+ - Peer-to-peer collaboration possible
57
+ - Seamless reconnection experience
58
+ ```
59
+
60
+ ### Component Locking
61
+
62
+ Prevent simultaneous edits on the same element.
63
+
64
+ ```css
65
+ /* Locked component indicator */
66
+ .component--locked {
67
+ outline: 2px dashed #6b7280;
68
+ pointer-events: none;
69
+ position: relative;
70
+ }
71
+
72
+ .component--locked::after {
73
+ content: "🔒 Editing: " attr(data-locked-by);
74
+ position: absolute;
75
+ top: -24px;
76
+ left: 0;
77
+ background: #374151;
78
+ color: white;
79
+ padding: 2px 8px;
80
+ border-radius: 4px;
81
+ font-size: 12px;
82
+ }
83
+ ```
84
+
85
+ #### Lock Timeout Pattern
86
+
87
+ ```javascript
88
+ // Auto-release lock after inactivity
89
+ const LOCK_TIMEOUT = 60000; // 60 seconds
90
+ let lockTimer;
91
+
92
+ function refreshLock() {
93
+ clearTimeout(lockTimer);
94
+ lockTimer = setTimeout(() => {
95
+ showDialog("Are you still editing? Lock will release in 30 seconds.");
96
+ // If no response, release lock
97
+ }, LOCK_TIMEOUT);
98
+ }
99
+ ```
100
+
101
+ ### Optimistic Updates
102
+
103
+ Apply changes locally before server confirmation.
104
+
105
+ ```javascript
106
+ async function updateDocument(change) {
107
+ // 1. Apply immediately (optimistic)
108
+ applyLocalChange(change);
109
+ updateUI();
110
+
111
+ try {
112
+ // 2. Send to server
113
+ await sendToServer(change);
114
+ } catch (error) {
115
+ // 3. Rollback if failed
116
+ revertLocalChange(change);
117
+ showError("Failed to save. Your change was reverted.");
118
+ }
119
+ }
120
+ ```
121
+
122
+ ### Merge Conflict UI
123
+
124
+ When automatic resolution isn't possible, provide clear conflict resolution.
125
+
126
+ ```
127
+ ┌─────────────────────────────────────────────────────────────┐
128
+ │ Conflict Detected │
129
+ ├─────────────────────────────────────────────────────────────┤
130
+ │ Your version │ Server version │ Merged │
131
+ │ ─────────────────────│────────────────────│───────────────│
132
+ │ The quick brown fox │ The slow brown fox │ │
133
+ │ ↓ │ ↓ │ ↓ │
134
+ │ [Accept] │ [Accept] │ [Edit & Save]│
135
+ └─────────────────────────────────────────────────────────────┘
136
+ ```
137
+
138
+ **Best Practice:** Show differences side-by-side with accept/reject buttons for each conflicting section.
139
+
140
+ ---
141
+
142
+ ## Version Control & History
143
+
144
+ ### Version History UI
145
+
146
+ ```
147
+ ┌──────────────────────────────────────────────────────────┐
148
+ │ Version History [x] │
149
+ ├──────────────────────────────────────────────────────────┤
150
+ │ Current version │
151
+ │ ├── Today, 3:45 PM - Alice (auto-saved) │
152
+ │ ├── Today, 2:30 PM - Bob "Added new section" │
153
+ │ ├── Today, 11:00 AM - Alice "Initial draft" │
154
+ │ ├── Yesterday, 4:00 PM - Carol (auto-saved) │
155
+ │ └── Dec 15, 2024 - Document created │
156
+ │ │
157
+ │ [Restore Selected] [Compare with Current] │
158
+ └──────────────────────────────────────────────────────────┘
159
+ ```
160
+
161
+ ### Multiplayer Undo/Redo
162
+
163
+ In collaborative environments, undo must be client-specific.
164
+
165
+ ```javascript
166
+ // Each user has their own undo stack
167
+ class CollaborativeUndoManager {
168
+ constructor(userId) {
169
+ this.userId = userId;
170
+ this.undoStack = [];
171
+ this.redoStack = [];
172
+ }
173
+
174
+ execute(action) {
175
+ // Record only this user's actions
176
+ if (action.userId === this.userId) {
177
+ this.undoStack.push(action);
178
+ this.redoStack = []; // Clear redo on new action
179
+ }
180
+ }
181
+
182
+ undo() {
183
+ const action = this.undoStack.pop();
184
+ if (action) {
185
+ const inverseAction = action.inverse();
186
+ this.redoStack.push(action);
187
+ return inverseAction; // Apply to document
188
+ }
189
+ }
190
+ }
191
+ ```
192
+
193
+ **Key Principle:** Users can only undo their own actions, not others'.
194
+
195
+ ### Change Attribution
196
+
197
+ Show who changed what and when.
198
+
199
+ ```css
200
+ /* Inline attribution on hover */
201
+ .text-block[data-author]::before {
202
+ content: attr(data-author) " • " attr(data-edited);
203
+ position: absolute;
204
+ top: -20px;
205
+ left: 0;
206
+ font-size: 11px;
207
+ color: #6b7280;
208
+ opacity: 0;
209
+ transition: opacity 150ms;
210
+ }
211
+
212
+ .text-block:hover::before {
213
+ opacity: 1;
214
+ }
215
+
216
+ /* Author highlight colors */
217
+ .text-block[data-author="alice"] { border-left: 3px solid #e63946; }
218
+ .text-block[data-author="bob"] { border-left: 3px solid #2a9d8f; }
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Sharing & Permissions
224
+
225
+ ### Invite Flow Patterns
226
+
227
+ #### Email Invitation
228
+
229
+ ```
230
+ ┌─────────────────────────────────────────────────────┐
231
+ │ Invite people │
232
+ ├─────────────────────────────────────────────────────┤
233
+ │ Email address │
234
+ │ ┌─────────────────────────────────────────────────┐ │
235
+ │ │ alice@example.com │ │
236
+ │ └─────────────────────────────────────────────────┘ │
237
+ │ │
238
+ │ Permission level │
239
+ │ ┌─────────────────────────────────────────────────┐ │
240
+ │ │ Can edit ▼ │ │
241
+ │ └─────────────────────────────────────────────────┘ │
242
+ │ │
243
+ │ Add a message (optional) │
244
+ │ ┌─────────────────────────────────────────────────┐ │
245
+ │ │ Here's the project we discussed... │ │
246
+ │ └─────────────────────────────────────────────────┘ │
247
+ │ │
248
+ │ [Cancel] [Send Invite] │
249
+ └─────────────────────────────────────────────────────┘
250
+ ```
251
+
252
+ #### Link Sharing
253
+
254
+ ```
255
+ ┌─────────────────────────────────────────────────────┐
256
+ │ Share via link │
257
+ ├─────────────────────────────────────────────────────┤
258
+ │ Anyone with the link │
259
+ │ ┌─────────────────────────────────────────────────┐ │
260
+ │ │ Can view ▼ │ │
261
+ │ └─────────────────────────────────────────────────┘ │
262
+ │ │
263
+ │ ┌─────────────────────────────────────────────────┐ │
264
+ │ │ https://app.example.com/doc/abc123... [Copy] │ │
265
+ │ └─────────────────────────────────────────────────┘ │
266
+ │ │
267
+ │ ⚠️ Anyone with this link can access the document │
268
+ └─────────────────────────────────────────────────────┘
269
+ ```
270
+
271
+ ### Permission Levels
272
+
273
+ | Level | Capabilities |
274
+ |-------|-------------|
275
+ | Owner | Full control, transfer ownership, delete |
276
+ | Admin | Manage members, edit settings, edit content |
277
+ | Editor | Edit content, add comments |
278
+ | Commenter | View content, add comments |
279
+ | Viewer | View only |
280
+
281
+ ### Permission Dialog Pattern
282
+
283
+ ```
284
+ ┌─────────────────────────────────────────────────────────────┐
285
+ │ Share "Project Alpha" │
286
+ ├─────────────────────────────────────────────────────────────┤
287
+ │ People with access │
288
+ │ ┌─────────────────────────────────────────────────────────┐ │
289
+ │ │ 👤 Alice (you) Owner │ │ │
290
+ │ │ 👤 Bob Editor [▼] │ │ │
291
+ │ │ 👤 Carol Viewer [▼] │ │ │
292
+ │ │ 🔗 Anyone with link Viewer [▼] │ │ │
293
+ │ └─────────────────────────────────────────────────────────┘ │
294
+ │ │
295
+ │ [+ Add people] │
296
+ └─────────────────────────────────────────────────────────────┘
297
+ ```
298
+
299
+ ---
300
+
301
+ ## Offline & Sync
302
+
303
+ ### Connection Status Indicators
304
+
305
+ ```css
306
+ /* Connection status banner */
307
+ .connection-banner {
308
+ position: fixed;
309
+ top: 0;
310
+ left: 0;
311
+ right: 0;
312
+ padding: 8px 16px;
313
+ text-align: center;
314
+ font-size: 14px;
315
+ z-index: 9999;
316
+ }
317
+
318
+ .connection-banner--offline {
319
+ background: #fef3c7;
320
+ color: #92400e;
321
+ }
322
+
323
+ .connection-banner--syncing {
324
+ background: #dbeafe;
325
+ color: #1e40af;
326
+ }
327
+
328
+ .connection-banner--error {
329
+ background: #fee2e2;
330
+ color: #991b1b;
331
+ }
332
+ ```
333
+
334
+ ### Offline State Communication
335
+
336
+ ```
337
+ ┌─────────────────────────────────────────────────────────┐
338
+ │ ⚠️ You're offline │
339
+ │ Changes will sync when you reconnect. │
340
+ │ Last synced: 2 minutes ago [Dismiss] │
341
+ └─────────────────────────────────────────────────────────┘
342
+ ```
343
+
344
+ **Key Principles:**
345
+ - Avoid technical jargon ("no network connection" vs "offline")
346
+ - Show last sync time
347
+ - Indicate that work is safe
348
+ - Provide manual sync option when reconnected
349
+
350
+ ### Sync Queue Visualization
351
+
352
+ ```
353
+ ┌─────────────────────────────────────────────────────────┐
354
+ │ Syncing 3 changes... │
355
+ │ ████████████░░░░░░░░░░░░░░░░░░░ │
356
+ │ │
357
+ │ ✓ "Header updated" │
358
+ │ ⟳ "Added new section" │
359
+ │ ○ "Changed footer color" │
360
+ └─────────────────────────────────────────────────────────┘
361
+ ```
362
+
363
+ ### Reconnection Flow
364
+
365
+ ```javascript
366
+ // Graceful reconnection
367
+ async function handleReconnection() {
368
+ showBanner("Reconnecting...");
369
+
370
+ try {
371
+ // 1. Fetch remote changes
372
+ const remoteChanges = await fetchChanges(lastSyncTimestamp);
373
+
374
+ // 2. Merge with local changes
375
+ const merged = mergeChanges(localQueue, remoteChanges);
376
+
377
+ // 3. Apply merged state
378
+ applyChanges(merged);
379
+
380
+ // 4. Push local changes
381
+ await pushLocalChanges(localQueue);
382
+
383
+ showBanner("You're back online!", { duration: 3000 });
384
+ } catch (error) {
385
+ showBanner("Reconnection failed. Retrying...");
386
+ scheduleRetry();
387
+ }
388
+ }
389
+ ```
390
+
391
+ ---
392
+
393
+ ## Key Metrics
394
+
395
+ | Metric | Value | Context |
396
+ |--------|-------|---------|
397
+ | Lock inactivity timeout | 60s | Before prompting release |
398
+ | Reconnection retry | 1s, 2s, 4s, 8s... | Exponential backoff |
399
+ | Optimistic timeout | 5-10s | Before showing sync error |
400
+
401
+ ---
402
+
403
+ ## Anti-Patterns
404
+
405
+ 1. **No conflict prevention** - Simultaneous edits overwrite each other
406
+ 2. **Silent failures** - Sync errors without user notification
407
+ 3. **No offline indication** - Users think they're connected
408
+ 4. **Permission confusion** - Unclear what each role can do
409
+ 5. **Blocking on sync** - UI freezes during synchronization
410
+ 6. **No undo attribution** - Users undo others' work accidentally
411
+
412
+ ---
413
+
414
+ ## Sources
415
+
416
+ - [Figma - Multiplayer Editing](https://www.figma.com/blog/multiplayer-editing-in-figma/)
417
+ - [CKEditor - Real-Time Collaboration Lessons](https://ckeditor.com/blog/lessons-learned-from-creating-a-rich-text-editor-with-real-time-collaboration/)
418
+ - [DEV - Building Collaborative Interfaces: OT vs CRDTs](https://dev.to/puritanic/building-collaborative-interfaces-operational-transforms-vs-crdts-2obo)
419
+ - [Liveblocks - Undo/Redo in Multiplayer](https://liveblocks.io/blog/how-to-build-undo-redo-in-a-multiplayer-environment)
420
+ - [A List Apart - Designing Offline-First](https://alistapart.com/article/offline-first/)