openskill-ai 1.0.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 (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +230 -0
  3. package/dist/chunk-63EFN7CX.js +450 -0
  4. package/dist/cli.d.ts +1 -0
  5. package/dist/cli.js +286 -0
  6. package/dist/index.d.ts +158 -0
  7. package/dist/index.js +391 -0
  8. package/package.json +70 -0
  9. package/skills/backend-best-practices/SKILL.md +116 -0
  10. package/skills/backend-best-practices/rules/api-consistent-responses.md +127 -0
  11. package/skills/backend-best-practices/rules/api-pagination.md +83 -0
  12. package/skills/backend-best-practices/rules/api-rate-limiting.md +94 -0
  13. package/skills/backend-best-practices/rules/api-restful-conventions.md +67 -0
  14. package/skills/backend-best-practices/rules/api-versioning.md +69 -0
  15. package/skills/backend-best-practices/rules/arch-dependency-injection.md +55 -0
  16. package/skills/backend-best-practices/rules/arch-dto-pattern.md +64 -0
  17. package/skills/backend-best-practices/rules/arch-repository-pattern.md +74 -0
  18. package/skills/backend-best-practices/rules/arch-separation-concerns.md +80 -0
  19. package/skills/backend-best-practices/rules/arch-service-layer.md +48 -0
  20. package/skills/backend-best-practices/rules/code-documentation.md +77 -0
  21. package/skills/backend-best-practices/rules/code-dry-principle.md +49 -0
  22. package/skills/backend-best-practices/rules/code-naming-conventions.md +47 -0
  23. package/skills/backend-best-practices/rules/code-single-responsibility.md +78 -0
  24. package/skills/backend-best-practices/rules/code-type-safety.md +64 -0
  25. package/skills/backend-best-practices/rules/db-connection-pooling.md +136 -0
  26. package/skills/backend-best-practices/rules/db-indexing.md +88 -0
  27. package/skills/backend-best-practices/rules/db-migrations.md +189 -0
  28. package/skills/backend-best-practices/rules/db-n-plus-one.md +118 -0
  29. package/skills/backend-best-practices/rules/db-transactions.md +178 -0
  30. package/skills/backend-best-practices/rules/deploy-environment-variables.md +63 -0
  31. package/skills/backend-best-practices/rules/deploy-graceful-shutdown.md +77 -0
  32. package/skills/backend-best-practices/rules/deploy-health-checks.md +70 -0
  33. package/skills/backend-best-practices/rules/deploy-monitoring.md +87 -0
  34. package/skills/backend-best-practices/rules/deploy-zero-downtime.md +85 -0
  35. package/skills/backend-best-practices/rules/error-global-handler.md +94 -0
  36. package/skills/backend-best-practices/rules/error-graceful-degradation.md +70 -0
  37. package/skills/backend-best-practices/rules/error-http-status-codes.md +77 -0
  38. package/skills/backend-best-practices/rules/error-logging.md +71 -0
  39. package/skills/backend-best-practices/rules/error-meaningful-messages.md +61 -0
  40. package/skills/backend-best-practices/rules/perf-async-operations.md +55 -0
  41. package/skills/backend-best-practices/rules/perf-caching.md +81 -0
  42. package/skills/backend-best-practices/rules/perf-compression.md +33 -0
  43. package/skills/backend-best-practices/rules/perf-database-queries.md +54 -0
  44. package/skills/backend-best-practices/rules/perf-lazy-loading.md +47 -0
  45. package/skills/backend-best-practices/rules/security-https-only.md +116 -0
  46. package/skills/backend-best-practices/rules/security-input-validation.md +96 -0
  47. package/skills/backend-best-practices/rules/security-jwt-best-practices.md +140 -0
  48. package/skills/backend-best-practices/rules/security-sql-injection.md +77 -0
  49. package/skills/clean-code-skills/references/solid.md +304 -0
  50. package/skills/clean-code-skills/skills.md +263 -0
  51. package/skills/flutter-skills/AGENTS.md +1265 -0
  52. package/skills/flutter-skills/SKILL.md +116 -0
  53. package/skills/flutter-skills/rules/advanced-custom-painter.md +117 -0
  54. package/skills/flutter-skills/rules/advanced-layer-link.md +103 -0
  55. package/skills/flutter-skills/rules/advanced-render-object.md +105 -0
  56. package/skills/flutter-skills/rules/advanced-sliver-persistent.md +111 -0
  57. package/skills/flutter-skills/rules/animation-animated-builder.md +118 -0
  58. package/skills/flutter-skills/rules/animation-cached-images.md +112 -0
  59. package/skills/flutter-skills/rules/animation-physics.md +105 -0
  60. package/skills/flutter-skills/rules/animation-reduce-overdraw.md +111 -0
  61. package/skills/flutter-skills/rules/animation-tween-sequence.md +112 -0
  62. package/skills/flutter-skills/rules/async-cancel-subscriptions.md +112 -0
  63. package/skills/flutter-skills/rules/async-compute.md +78 -0
  64. package/skills/flutter-skills/rules/async-debounce-throttle.md +104 -0
  65. package/skills/flutter-skills/rules/async-future-builder.md +106 -0
  66. package/skills/flutter-skills/rules/async-parallel.md +75 -0
  67. package/skills/flutter-skills/rules/build-avoid-rebuild.md +80 -0
  68. package/skills/flutter-skills/rules/build-const-constructors.md +56 -0
  69. package/skills/flutter-skills/rules/build-itemextent.md +73 -0
  70. package/skills/flutter-skills/rules/build-keys.md +74 -0
  71. package/skills/flutter-skills/rules/build-split-widgets.md +99 -0
  72. package/skills/flutter-skills/rules/dart-avoid-dynamic.md +86 -0
  73. package/skills/flutter-skills/rules/dart-cascade-notation.md +89 -0
  74. package/skills/flutter-skills/rules/dart-collection-if.md +92 -0
  75. package/skills/flutter-skills/rules/dart-final-const.md +70 -0
  76. package/skills/flutter-skills/rules/dart-spread-operator.md +90 -0
  77. package/skills/flutter-skills/rules/dart-string-buffer.md +77 -0
  78. package/skills/flutter-skills/rules/layout-avoid-opacity.md +110 -0
  79. package/skills/flutter-skills/rules/layout-clip-behavior.md +94 -0
  80. package/skills/flutter-skills/rules/layout-intrinsic-dimensions.md +89 -0
  81. package/skills/flutter-skills/rules/layout-repaint-boundary.md +117 -0
  82. package/skills/flutter-skills/rules/layout-slivers.md +94 -0
  83. package/skills/flutter-skills/rules/memory-dispose.md +90 -0
  84. package/skills/flutter-skills/rules/memory-image-cache.md +86 -0
  85. package/skills/flutter-skills/rules/memory-isolate.md +91 -0
  86. package/skills/flutter-skills/rules/memory-precache.md +114 -0
  87. package/skills/flutter-skills/rules/memory-weak-references.md +79 -0
  88. package/skills/flutter-skills/rules/state-late-final.md +90 -0
  89. package/skills/flutter-skills/rules/state-lift-state-up.md +84 -0
  90. package/skills/flutter-skills/rules/state-minimize-rebuilds.md +95 -0
  91. package/skills/flutter-skills/rules/state-selector.md +87 -0
  92. package/skills/flutter-skills/rules/state-valuenotifier.md +85 -0
  93. package/skills/frontend-design/SKILL.md +42 -0
  94. package/skills/skill-writer-skills/AGENTS.md +637 -0
  95. package/skills/skill-writer-skills/README.md +49 -0
  96. package/skills/skill-writer-skills/SKILL.md +97 -0
  97. package/skills/skill-writer-skills/metadata.json +17 -0
  98. package/skills/skill-writer-skills/references/common-pitfalls.md +291 -0
  99. package/skills/skill-writer-skills/references/core-principles.md +147 -0
  100. package/skills/skill-writer-skills/references/creation-process.md +250 -0
  101. package/skills/skill-writer-skills/references/design-patterns.md +300 -0
  102. package/skills/skill-writer-skills/references/skill-anatomy.md +174 -0
  103. package/skills/skill-writer-skills/references/validation-checklist.md +194 -0
@@ -0,0 +1,112 @@
1
+ ---
2
+ title: Cache Animation Frames When Possible
3
+ impact: MEDIUM
4
+ impactDescription: Reduces per-frame computation
5
+ tags: animation, cache, frames, performance
6
+ ---
7
+
8
+ ## Cache Animation Frames When Possible
9
+
10
+ For complex animations that repeat, consider caching rendered frames or using simpler representations during motion.
11
+
12
+ **Incorrect (complex rendering every frame):**
13
+
14
+ ```dart
15
+ class BadComplexAnim extends StatefulWidget {
16
+ @override
17
+ State<BadComplexAnim> createState() => _BadComplexAnimState();
18
+ }
19
+
20
+ class _BadComplexAnimState extends State<BadComplexAnim>
21
+ with SingleTickerProviderStateMixin {
22
+ late AnimationController _controller;
23
+
24
+ @override
25
+ Widget build(BuildContext context) {
26
+ return AnimatedBuilder(
27
+ animation: _controller,
28
+ builder: (context, _) {
29
+ // Complex widget rebuilt 60 times per second
30
+ return Transform.rotate(
31
+ angle: _controller.value * 2 * pi,
32
+ child: ComplexShadowedWidget(), // Expensive!
33
+ );
34
+ },
35
+ );
36
+ }
37
+ }
38
+ ```
39
+
40
+ **Correct (cache animated content in layer):**
41
+
42
+ ```dart
43
+ class GoodComplexAnim extends StatefulWidget {
44
+ const GoodComplexAnim({super.key});
45
+
46
+ @override
47
+ State<GoodComplexAnim> createState() => _GoodComplexAnimState();
48
+ }
49
+
50
+ class _GoodComplexAnimState extends State<GoodComplexAnim>
51
+ with SingleTickerProviderStateMixin {
52
+ late AnimationController _controller;
53
+
54
+ @override
55
+ Widget build(BuildContext context) {
56
+ return AnimatedBuilder(
57
+ animation: _controller,
58
+ // Child is built ONCE and cached
59
+ child: const RepaintBoundary(
60
+ child: ComplexShadowedWidget(),
61
+ ),
62
+ builder: (context, child) {
63
+ // Only transform is applied per-frame
64
+ return Transform.rotate(
65
+ angle: _controller.value * 2 * pi,
66
+ child: child, // Reused cached child
67
+ );
68
+ },
69
+ );
70
+ }
71
+ }
72
+ ```
73
+
74
+ **For repeated sprite animations:**
75
+
76
+ ```dart
77
+ class SpriteAnimation extends StatelessWidget {
78
+ final List<ui.Image> frames; // Pre-rendered frames
79
+ final int currentFrame;
80
+
81
+ const SpriteAnimation({
82
+ super.key,
83
+ required this.frames,
84
+ required this.currentFrame,
85
+ });
86
+
87
+ @override
88
+ Widget build(BuildContext context) {
89
+ return CustomPaint(
90
+ painter: SpritePainter(frames[currentFrame]),
91
+ );
92
+ }
93
+ }
94
+
95
+ class SpritePainter extends CustomPainter {
96
+ final ui.Image frame;
97
+ SpritePainter(this.frame);
98
+
99
+ @override
100
+ void paint(Canvas canvas, Size size) {
101
+ canvas.drawImage(frame, Offset.zero, Paint());
102
+ }
103
+
104
+ @override
105
+ bool shouldRepaint(SpritePainter old) => frame != old.frame;
106
+ }
107
+ ```
108
+
109
+ **When to cache:**
110
+ - Rotating complex widgets with shadows
111
+ - Scaling elaborate UI
112
+ - Looping animations with static content
@@ -0,0 +1,105 @@
1
+ ---
2
+ title: Use Physics-Based Animations
3
+ impact: MEDIUM
4
+ impactDescription: More natural, interruptible animations
5
+ tags: animation, physics, spring, fling
6
+ ---
7
+
8
+ ## Use Physics-Based Animations
9
+
10
+ Use physics-based animations for natural feeling interactions that can be interrupted and redirected.
11
+
12
+ **Incorrect (fixed duration feels artificial):**
13
+
14
+ ```dart
15
+ class BadDrag extends StatefulWidget {
16
+ @override
17
+ State<BadDrag> createState() => _BadDragState();
18
+ }
19
+
20
+ class _BadDragState extends State<BadDrag>
21
+ with SingleTickerProviderStateMixin {
22
+ late AnimationController _controller;
23
+ double _offset = 0;
24
+
25
+ void _onDragEnd(DragEndDetails details) {
26
+ // Fixed duration regardless of velocity - unnatural
27
+ _controller.animateTo(
28
+ 0,
29
+ duration: const Duration(milliseconds: 300),
30
+ );
31
+ }
32
+ }
33
+ ```
34
+
35
+ **Correct (physics-based spring):**
36
+
37
+ ```dart
38
+ class GoodDrag extends StatefulWidget {
39
+ const GoodDrag({super.key});
40
+
41
+ @override
42
+ State<GoodDrag> createState() => _GoodDragState();
43
+ }
44
+
45
+ class _GoodDragState extends State<GoodDrag>
46
+ with SingleTickerProviderStateMixin {
47
+ late AnimationController _controller;
48
+
49
+ void _onDragEnd(DragEndDetails details) {
50
+ // Spring simulation - natural bounce back
51
+ final simulation = SpringSimulation(
52
+ SpringDescription(
53
+ mass: 1,
54
+ stiffness: 500,
55
+ damping: 25,
56
+ ),
57
+ _controller.value, // Current position
58
+ 0, // Target position
59
+ details.velocity.pixelsPerSecond.dx / 1000, // Initial velocity
60
+ );
61
+
62
+ _controller.animateWith(simulation);
63
+ }
64
+ }
65
+ ```
66
+
67
+ **Fling animation for scrolling:**
68
+
69
+ ```dart
70
+ void _onPanEnd(DragEndDetails details) {
71
+ final velocity = details.velocity.pixelsPerSecond.dx;
72
+
73
+ final simulation = FrictionSimulation(
74
+ 0.135, // Friction coefficient
75
+ _position,
76
+ velocity,
77
+ );
78
+
79
+ _controller.animateWith(simulation);
80
+ }
81
+ ```
82
+
83
+ **Built-in spring curves:**
84
+
85
+ ```dart
86
+ // Use Curves.elasticOut for spring-like effect
87
+ AnimatedContainer(
88
+ duration: const Duration(milliseconds: 500),
89
+ curve: Curves.elasticOut, // Spring overshoot
90
+ transform: Matrix4.translationValues(_offset, 0, 0),
91
+ child: content,
92
+ )
93
+
94
+ // Or SpringCurve for more control
95
+ const spring = SpringDescription(
96
+ mass: 1,
97
+ stiffness: 100,
98
+ damping: 10,
99
+ );
100
+ ```
101
+
102
+ Physics animations feel more natural because:
103
+ - Duration depends on distance and velocity
104
+ - Can be interrupted mid-animation
105
+ - Respect user gesture momentum
@@ -0,0 +1,111 @@
1
+ ---
2
+ title: Minimize Overdraw in Animations
3
+ impact: MEDIUM
4
+ impactDescription: Reduces GPU workload
5
+ tags: animation, overdraw, gpu, performance
6
+ ---
7
+
8
+ ## Minimize Overdraw in Animations
9
+
10
+ Reduce overlapping painted areas during animations to decrease GPU workload.
11
+
12
+ **Incorrect (multiple overlapping layers):**
13
+
14
+ ```dart
15
+ class BadOverdraw extends StatelessWidget {
16
+ @override
17
+ Widget build(BuildContext context) {
18
+ return Stack(
19
+ children: [
20
+ // Background painted everywhere
21
+ Container(color: Colors.blue),
22
+ // Card overlaps background
23
+ Center(
24
+ child: Container(
25
+ width: 200,
26
+ height: 200,
27
+ decoration: BoxDecoration(
28
+ color: Colors.white,
29
+ boxShadow: [
30
+ BoxShadow(
31
+ blurRadius: 20,
32
+ color: Colors.black26,
33
+ ),
34
+ ],
35
+ ),
36
+ // Icon overlaps card
37
+ child: Icon(Icons.star, size: 100, color: Colors.yellow),
38
+ ),
39
+ ),
40
+ ],
41
+ );
42
+ }
43
+ }
44
+ ```
45
+
46
+ **Correct (minimize overlap):**
47
+
48
+ ```dart
49
+ class GoodOverdraw extends StatelessWidget {
50
+ const GoodOverdraw({super.key});
51
+
52
+ @override
53
+ Widget build(BuildContext context) {
54
+ return ColoredBox(
55
+ color: Colors.blue,
56
+ child: Center(
57
+ child: PhysicalModel(
58
+ color: Colors.white,
59
+ elevation: 8, // Uses GPU shadow, more efficient
60
+ borderRadius: BorderRadius.circular(8),
61
+ child: const SizedBox(
62
+ width: 200,
63
+ height: 200,
64
+ child: Icon(Icons.star, size: 100, color: Colors.yellow),
65
+ ),
66
+ ),
67
+ ),
68
+ );
69
+ }
70
+ }
71
+ ```
72
+
73
+ **Debug overdraw:**
74
+
75
+ ```dart
76
+ void main() {
77
+ // Shows overdraw with colors
78
+ // Green = 1x, Light green = 2x, Yellow = 3x, Red = 4x+
79
+ debugPaintLayerBordersEnabled = true;
80
+ runApp(MyApp());
81
+ }
82
+
83
+ // Or use DevTools Performance Overlay
84
+ MaterialApp(
85
+ showPerformanceOverlay: true,
86
+ home: MyHomePage(),
87
+ )
88
+ ```
89
+
90
+ **Tips to reduce overdraw:**
91
+ - Use `ColoredBox` instead of `Container(color: ...)`
92
+ - Use `PhysicalModel` for shadows instead of `BoxShadow`
93
+ - Avoid stacking opaque widgets
94
+ - Use `saveLayer` sparingly (opacity, clips with antialiasing)
95
+ - Prefer solid backgrounds over gradients where possible
96
+
97
+ **For animated opacity:**
98
+
99
+ ```dart
100
+ // Bad - saveLayer on every frame
101
+ Opacity(
102
+ opacity: animation.value,
103
+ child: ComplexWidget(),
104
+ )
105
+
106
+ // Better - use FadeTransition
107
+ FadeTransition(
108
+ opacity: animation,
109
+ child: const ComplexWidget(),
110
+ )
111
+ ```
@@ -0,0 +1,112 @@
1
+ ---
2
+ title: Use TweenSequence for Complex Animations
3
+ impact: MEDIUM
4
+ impactDescription: Cleaner multi-phase animations
5
+ tags: animation, tween, sequence, multi-step
6
+ ---
7
+
8
+ ## Use TweenSequence for Complex Animations
9
+
10
+ Use `TweenSequence` for multi-phase animations instead of chaining or complex state logic.
11
+
12
+ **Incorrect (manual phase management):**
13
+
14
+ ```dart
15
+ class BadMultiPhase extends StatefulWidget {
16
+ @override
17
+ State<BadMultiPhase> createState() => _BadMultiPhaseState();
18
+ }
19
+
20
+ class _BadMultiPhaseState extends State<BadMultiPhase>
21
+ with SingleTickerProviderStateMixin {
22
+ late AnimationController _controller;
23
+ int _phase = 0;
24
+
25
+ @override
26
+ void initState() {
27
+ super.initState();
28
+ _controller = AnimationController(
29
+ duration: const Duration(seconds: 1),
30
+ vsync: this,
31
+ )..addStatusListener((status) {
32
+ if (status == AnimationStatus.completed) {
33
+ _phase++;
34
+ if (_phase < 3) _controller.forward(from: 0);
35
+ }
36
+ });
37
+ }
38
+
39
+ double get _scale {
40
+ switch (_phase) {
41
+ case 0: return 1.0 + _controller.value * 0.5; // 1.0 -> 1.5
42
+ case 1: return 1.5 - _controller.value * 0.3; // 1.5 -> 1.2
43
+ case 2: return 1.2 - _controller.value * 0.2; // 1.2 -> 1.0
44
+ default: return 1.0;
45
+ }
46
+ }
47
+ }
48
+ ```
49
+
50
+ **Correct (TweenSequence):**
51
+
52
+ ```dart
53
+ class GoodMultiPhase extends StatefulWidget {
54
+ const GoodMultiPhase({super.key});
55
+
56
+ @override
57
+ State<GoodMultiPhase> createState() => _GoodMultiPhaseState();
58
+ }
59
+
60
+ class _GoodMultiPhaseState extends State<GoodMultiPhase>
61
+ with SingleTickerProviderStateMixin {
62
+ late AnimationController _controller;
63
+ late Animation<double> _scaleAnimation;
64
+
65
+ @override
66
+ void initState() {
67
+ super.initState();
68
+ _controller = AnimationController(
69
+ duration: const Duration(seconds: 3),
70
+ vsync: this,
71
+ );
72
+
73
+ _scaleAnimation = TweenSequence<double>([
74
+ TweenSequenceItem(
75
+ tween: Tween(begin: 1.0, end: 1.5)
76
+ .chain(CurveTween(curve: Curves.easeOut)),
77
+ weight: 33,
78
+ ),
79
+ TweenSequenceItem(
80
+ tween: Tween(begin: 1.5, end: 1.2)
81
+ .chain(CurveTween(curve: Curves.easeInOut)),
82
+ weight: 33,
83
+ ),
84
+ TweenSequenceItem(
85
+ tween: Tween(begin: 1.2, end: 1.0)
86
+ .chain(CurveTween(curve: Curves.easeIn)),
87
+ weight: 34,
88
+ ),
89
+ ]).animate(_controller);
90
+ }
91
+
92
+ @override
93
+ void dispose() {
94
+ _controller.dispose();
95
+ super.dispose();
96
+ }
97
+
98
+ @override
99
+ Widget build(BuildContext context) {
100
+ return ScaleTransition(
101
+ scale: _scaleAnimation,
102
+ child: const Icon(Icons.favorite, size: 50),
103
+ );
104
+ }
105
+ }
106
+ ```
107
+
108
+ **Benefits:**
109
+ - Single animation controller
110
+ - Declarative phase definitions
111
+ - Each phase can have its own curve
112
+ - Weight controls relative duration
@@ -0,0 +1,112 @@
1
+ ---
2
+ title: Cancel Stream Subscriptions on Dispose
3
+ impact: HIGH
4
+ impactDescription: Prevents memory leaks and errors
5
+ tags: async, streams, dispose, memory
6
+ ---
7
+
8
+ ## Cancel Stream Subscriptions on Dispose
9
+
10
+ Always cancel stream subscriptions in `dispose()` to prevent memory leaks and errors from updates to disposed widgets.
11
+
12
+ **Incorrect (subscription never cancelled):**
13
+
14
+ ```dart
15
+ class BadStreamWidget extends StatefulWidget {
16
+ @override
17
+ State<BadStreamWidget> createState() => _BadStreamWidgetState();
18
+ }
19
+
20
+ class _BadStreamWidgetState extends State<BadStreamWidget> {
21
+ String data = '';
22
+
23
+ @override
24
+ void initState() {
25
+ super.initState();
26
+ // This subscription will leak!
27
+ myStream.listen((value) {
28
+ setState(() => data = value);
29
+ });
30
+ }
31
+
32
+ @override
33
+ Widget build(BuildContext context) => Text(data);
34
+ }
35
+ ```
36
+
37
+ **Correct (subscription cancelled on dispose):**
38
+
39
+ ```dart
40
+ class GoodStreamWidget extends StatefulWidget {
41
+ const GoodStreamWidget({super.key});
42
+
43
+ @override
44
+ State<GoodStreamWidget> createState() => _GoodStreamWidgetState();
45
+ }
46
+
47
+ class _GoodStreamWidgetState extends State<GoodStreamWidget> {
48
+ String data = '';
49
+ StreamSubscription<String>? _subscription;
50
+
51
+ @override
52
+ void initState() {
53
+ super.initState();
54
+ _subscription = myStream.listen((value) {
55
+ setState(() => data = value);
56
+ });
57
+ }
58
+
59
+ @override
60
+ void dispose() {
61
+ _subscription?.cancel(); // Critical!
62
+ super.dispose();
63
+ }
64
+
65
+ @override
66
+ Widget build(BuildContext context) => Text(data);
67
+ }
68
+ ```
69
+
70
+ **Or use StreamBuilder (handles subscription automatically):**
71
+
72
+ ```dart
73
+ class BetterStreamWidget extends StatelessWidget {
74
+ const BetterStreamWidget({super.key});
75
+
76
+ @override
77
+ Widget build(BuildContext context) {
78
+ return StreamBuilder<String>(
79
+ stream: myStream,
80
+ builder: (context, snapshot) {
81
+ if (snapshot.hasData) {
82
+ return Text(snapshot.data!);
83
+ }
84
+ return const CircularProgressIndicator();
85
+ },
86
+ );
87
+ }
88
+ }
89
+ ```
90
+
91
+ **Multiple subscriptions pattern:**
92
+
93
+ ```dart
94
+ class _MultiStreamState extends State<MultiStreamWidget> {
95
+ final List<StreamSubscription> _subscriptions = [];
96
+
97
+ @override
98
+ void initState() {
99
+ super.initState();
100
+ _subscriptions.add(stream1.listen((_) {}));
101
+ _subscriptions.add(stream2.listen((_) {}));
102
+ }
103
+
104
+ @override
105
+ void dispose() {
106
+ for (final sub in _subscriptions) {
107
+ sub.cancel();
108
+ }
109
+ super.dispose();
110
+ }
111
+ }
112
+ ```
@@ -0,0 +1,78 @@
1
+ ---
2
+ title: Use compute() for Heavy Synchronous Work
3
+ impact: HIGH
4
+ impactDescription: Prevents UI jank
5
+ tags: async, compute, isolate, performance
6
+ ---
7
+
8
+ ## Use compute() for Heavy Synchronous Work
9
+
10
+ Offload CPU-intensive synchronous work to an isolate using `compute()` to prevent UI jank.
11
+
12
+ **Incorrect (blocks UI thread):**
13
+
14
+ ```dart
15
+ class BadJsonParser extends StatelessWidget {
16
+ Future<void> parseData() async {
17
+ final response = await http.get(Uri.parse('api/data'));
18
+
19
+ // This blocks the UI thread!
20
+ final parsed = jsonDecode(response.body);
21
+ final processed = heavyProcessing(parsed);
22
+ }
23
+ }
24
+ ```
25
+
26
+ **Correct (offload to isolate):**
27
+
28
+ ```dart
29
+ class GoodJsonParser extends StatelessWidget {
30
+ const GoodJsonParser({super.key});
31
+
32
+ // Must be top-level or static function
33
+ static Map<String, dynamic> parseJson(String json) {
34
+ final parsed = jsonDecode(json);
35
+ return heavyProcessing(parsed);
36
+ }
37
+
38
+ Future<Map<String, dynamic>> parseData() async {
39
+ final response = await http.get(Uri.parse('api/data'));
40
+
41
+ // Runs in separate isolate, UI stays responsive
42
+ return compute(parseJson, response.body);
43
+ }
44
+ }
45
+ ```
46
+
47
+ **For multiple heavy operations:**
48
+
49
+ ```dart
50
+ Future<ProcessedData> processAll(RawData raw) async {
51
+ // Run heavy computations in parallel on separate isolates
52
+ final results = await Future.wait([
53
+ compute(parseImages, raw.images),
54
+ compute(parseVideos, raw.videos),
55
+ compute(parseDocuments, raw.documents),
56
+ ]);
57
+
58
+ return ProcessedData(
59
+ images: results[0],
60
+ videos: results[1],
61
+ documents: results[2],
62
+ );
63
+ }
64
+ ```
65
+
66
+ **When to use compute():**
67
+ - JSON parsing of large payloads (>100KB)
68
+ - Image processing or compression
69
+ - Cryptographic operations
70
+ - Complex data transformations
71
+ - Any operation taking >16ms
72
+
73
+ **Limitations:**
74
+ - Function must be top-level or static
75
+ - Arguments must be serializable (no closures)
76
+ - Has isolate spawn overhead (~5-20ms)
77
+
78
+ For very frequent operations, consider using `Isolate.spawn` with ports for persistent workers.