[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71NB5FEKJ035AFRFEBM9E04":3,"skill-same:01M71NB5FEKJ035AFRFEBM9E04":110},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":49,"linkOnly":50,"markdownContent":51,"markdownBody":52,"frontMatter":53,"refName":68,"commitSha":69,"skillDirectory":70,"forksCount":14,"repositoryHtmlUrl":71,"repositoryHomepageUrl":72,"ownerHtmlUrl":73,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":74,"install":75,"resources":87},"01M71NB5FEKJ035AFRFEBM9E04","golang-samber-ro",null,"Reactive streams and event-driven programming in Golang using samber\u002Fro — ReactiveX implementation with 150+ type-safe operators, cold\u002Fhot observables, 5 subject types (Publish, Behavior, Replay, Async, Unicast), declarative pipelines via Pipe, 40+ plugins (HTTP, cron, fsnotify, JSON, logging), automatic backpressure, error propagation, and Go context integration. Apply when using or adopting samber\u002Fro, when the codebase imports github.com\u002Fsamber\u002Fro, or when building asynchronous event-driven pipelines, real-time data processing, streams, or reactive architectures in Go. Not for finite slice transforms (→ See `samber\u002Fcc-skills-golang@golang-samber-lo` skill).","pattanation\u002FNorvik","pattanation","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F235419268?v=4","01M71M5THHYYB15ME8R2E4FCZG","Patta","01M71M5TJM1NDM992M8PDKYR2K",0,"MIT","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fgolang-samber-ro\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],"golang","golang samber ro","query","when","imports","streams","types","processing","cold","error","time","lsp","MCP","projects","gopls","Bash","publish","asynchronous","code","ai coding agents","2026-11-10 10:56:23",false,"---\nname: golang-samber-ro\ndescription: \"Reactive streams and event-driven programming in Golang using samber\u002Fro — ReactiveX implementation with 150+ type-safe operators, cold\u002Fhot observables, 5 subject types (Publish, Behavior, Replay, Async, Unicast), declarative pipelines via Pipe, 40+ plugins (HTTP, cron, fsnotify, JSON, logging), automatic backpressure, error propagation, and Go context integration. Apply when using or adopting samber\u002Fro, when the codebase imports github.com\u002Fsamber\u002Fro, or when building asynchronous event-driven pipelines, real-time data processing, streams, or reactive architectures in Go. Not for finite slice transforms (→ See `samber\u002Fcc-skills-golang@golang-samber-lo` skill).\"\nuser-invocable: true\nlicense: MIT\ncompatibility: Designed for Claude Code or similar AI coding agents, and for projects using Golang.\nmetadata:\n  author: samber\n  version: \"1.1.3\"\n  openclaw:\n    emoji: \"👁\"\n    homepage: https:\u002F\u002Fgithub.com\u002Fsamber\u002Fcc-skills-golang\n    requires:\n      bins:\n        - go\n    install: []\n    skill-library-version: \"0.3.0\"\nallowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent mcp__context7__resolve-library-id mcp__context7__query-docs AskUserQuestion Bash(godig:*) Bash(gopls:*) LSP mcp__gopls__*\n---\n\n**Persona:** You are a Go engineer who reaches for reactive streams when data flows asynchronously or infinitely. You use samber\u002Fro to build declarative pipelines instead of manual goroutine\u002Fchannel wiring, but you know when a simple slice + samber\u002Flo is enough.\n\n**Thinking mode:** Use `ultrathink` when designing advanced reactive pipelines or choosing between cold\u002Fhot observables, subjects, and combining operators. Wrong architecture leads to resource leaks or missed events.\n\n# samber\u002Fro — Reactive Streams for Go\n\nGo implementation of [ReactiveX](https:\u002F\u002Freactivex.io\u002F). Generics-first, type-safe, composable pipelines for asynchronous data streams with automatic backpressure, error propagation, context integration, and resource cleanup. 150+ operators, 5 subject types, 40+ plugins.\n\n**Official Resources:**\n\n- [github.com\u002Fsamber\u002Fro](https:\u002F\u002Fgithub.com\u002Fsamber\u002Fro)\n- [ro.samber.dev](https:\u002F\u002Fro.samber.dev)\n- [pkg.go.dev\u002Fgithub.com\u002Fsamber\u002Fro](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fsamber\u002Fro)\n\nThis skill is not exhaustive. Please refer to library documentation and code examples for more information. For Go package docs, symbols, versions, importers, and known vulnerabilities, → See `samber\u002Fcc-skills-golang@golang-pkg-go-dev` skill (`godig`) — prefer it over Context7 for Go package facts. To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See `samber\u002Fcc-skills-golang@golang-gopls` skill (`gopls`). Context7 remains a fallback for docs not indexed on pkg.go.dev.\n\n## Why samber\u002Fro (Streams vs Slices)\n\nGo channels + goroutines become unwieldy for complex async pipelines: manual channel closures, verbose goroutine lifecycle, error propagation across nested selects, and no composable operators. `samber\u002Fro` solves this with declarative, chainable stream operators.\n\n**When to use which tool:**\n\n| Scenario | Tool | Why |\n| --- | --- | --- |\n| Transform a slice (map, filter, reduce) | `samber\u002Flo` | Finite, synchronous, eager — no stream overhead needed |\n| Simple goroutine fan-out with error handling | `errgroup` | Standard lib, lightweight, sufficient for bounded concurrency |\n| Infinite event stream (WebSocket, tickers, file watcher) | `samber\u002Fro` | Declarative pipeline with backpressure, retry, timeout, combine |\n| Real-time data enrichment from multiple async sources | `samber\u002Fro` | CombineLatest\u002FZip compose dependent streams without manual select |\n| Pub\u002Fsub with multiple consumers sharing one source | `samber\u002Fro` | Hot observables (Share\u002FSubjects) handle multicast natively |\n\n**Key differences: lo vs ro**\n\n| Aspect | `samber\u002Flo` | `samber\u002Fro` |\n| --- | --- | --- |\n| Data | Finite slices | Infinite streams |\n| Execution | Synchronous, blocking | Asynchronous, non-blocking |\n| Evaluation | Eager (allocates intermediate slices) | Lazy (processes items as they arrive) |\n| Timing | Immediate | Time-aware (delay, throttle, interval, timeout) |\n| Error model | Return `(T, error)` per call | Error channel propagates through pipeline |\n| Use case | Collection transforms | Event-driven, real-time, async pipelines |\n\n## Installation\n\n```bash\ngo get github.com\u002Fsamber\u002Fro\n```\n\n## Core Concepts\n\nFour building blocks:\n\n1. **Observable** — a data source that emits values over time. Cold by default: each subscriber triggers independent execution from scratch\n2. **Observer** — a consumer with three callbacks: `onNext(T)`, `onError(error)`, `onComplete()`\n3. **Operator** — a function that transforms an observable into another observable, chained via `Pipe`\n4. **Subscription** — the connection between observable and observer. Call `.Wait()` to block or `.Unsubscribe()` to cancel\n\n```go\nobservable := ro.Pipe2(\n    ro.RangeWithInterval(0, 5, 1*time.Second),\n    ro.Filter(func(x int) bool { return x%2 == 0 }),\n    ro.Map(func(x int) string { return fmt.Sprintf(\"even-%d\", x) }),\n)\n\nobservable.Subscribe(ro.NewObserver(\n    func(s string) { fmt.Println(s) },      \u002F\u002F onNext\n    func(err error) { log.Println(err) },    \u002F\u002F onError\n    func() { fmt.Println(\"Done!\") },         \u002F\u002F onComplete\n))\n\u002F\u002F Output: \"even-0\", \"even-2\", \"even-4\", \"Done!\"\n\n\u002F\u002F Or collect synchronously:\nvalues, err := ro.Collect(observable)\n```\n\n## Cold vs Hot Observables\n\n**Cold** (default): each `.Subscribe()` starts a new independent execution. Safe and predictable — use by default.\n\n**Hot**: multiple subscribers share a single execution. Use when the source is expensive (WebSocket, DB poll) or subscribers must see the same events.\n\n| Convert with | Behavior |\n| --- | --- |\n| `Share()` | Cold → hot with reference counting. Last unsubscribe tears down |\n| `ShareReplay(n)` | Same as Share + buffers last N values for late subscribers |\n| `Connectable()` | Cold → hot, but waits for explicit `.Connect()` call |\n| Subjects | Natively hot — call `.Send()`, `.Error()`, `.Complete()` directly |\n\n| Subject | Constructor | Replay behavior |\n| --- | --- | --- |\n| `PublishSubject` | `NewPublishSubject[T]()` | None — late subscribers miss past events |\n| `BehaviorSubject` | `NewBehaviorSubject[T](initial)` | Replays last value to new subscribers |\n| `ReplaySubject` | `NewReplaySubject[T](bufferSize)` | Replays last N values |\n| `AsyncSubject` | `NewAsyncSubject[T]()` | Emits only last value, only on complete |\n| `UnicastSubject` | `NewUnicastSubject[T](bufferSize)` | Single subscriber only |\n\nFor subject details and hot observable patterns, see [Subjects Guide](.\u002Freferences\u002Fsubjects-guide.md).\n\n## Operator Quick Reference\n\n| Category | Key operators | Purpose |\n| --- | --- | --- |\n| Creation | `Just`, `FromSlice`, `FromChannel`, `Range`, `Interval`, `Defer`, `Future` | Create observables from various sources |\n| Transform | `Map`, `MapErr`, `FlatMap`, `Scan`, `Reduce`, `GroupBy` | Transform or accumulate stream values |\n| Filter | `Filter`, `Take`, `TakeLast`, `Skip`, `Distinct`, `Find`, `First`, `Last` | Selectively emit values |\n| Combine | `Merge`, `Concat`, `Zip2`–`Zip6`, `CombineLatest2`–`CombineLatest5`, `Race` | Merge multiple observables |\n| Error | `Catch`, `OnErrorReturn`, `OnErrorResumeNextWith`, `Retry`, `RetryWithConfig` | Recover from errors |\n| Timing | `Delay`, `DelayEach`, `Timeout`, `ThrottleTime`, `SampleTime`, `BufferWithTime` | Control emission timing |\n| Side effect | `Tap`\u002F`Do`, `TapOnNext`, `TapOnError`, `TapOnComplete` | Observe without altering stream |\n| Terminal | `Collect`, `ToSlice`, `ToChannel`, `ToMap` | Consume stream into Go types |\n\nUse typed `Pipe2`, `Pipe3` ... `Pipe25` for compile-time type safety across operator chains. The untyped `Pipe` uses `any` and loses type checking.\n\nFor the complete operator catalog (150+ operators with signatures), see [Operators Guide](.\u002Freferences\u002Foperators-guide.md).\n\n## Common Mistakes\n\n| Mistake | Why it fails | Fix |\n| --- | --- | --- |\n| Using `ro.OnNext()` without error handler | Errors are silently dropped — bugs hide in production | Use `ro.NewObserver(onNext, onError, onComplete)` with all 3 callbacks |\n| Using untyped `Pipe()` instead of `Pipe2`\u002F`Pipe3` | Loses compile-time type safety, errors surface at runtime | Use `Pipe2`, `Pipe3`...`Pipe25` for typed operator chains |\n| Forgetting `.Unsubscribe()` on infinite streams | Goroutine leak — the observable runs forever | Use `TakeUntil(signal)`, context cancellation, or explicit `Unsubscribe()` |\n| Using `Share()` when cold is sufficient | Unnecessary complexity, harder to reason about lifecycle | Use hot observables only when multiple consumers need the same stream |\n| Using `samber\u002Fro` for finite slice transforms | Stream overhead (goroutines, subscriptions) for a synchronous operation | Use `samber\u002Flo` — it's simpler, faster, and purpose-built for slices |\n| Not propagating context for cancellation | Streams ignore shutdown signals, causing resource leaks on termination | Chain `ContextWithTimeout` or `ThrowOnContextCancel` in the pipeline |\n\n## Best Practices\n\n1. **Always handle all three events** — use `NewObserver(onNext, onError, onComplete)`, not just `OnNext`. Unhandled errors cause silent data loss\n2. **Use `Collect()` for synchronous consumption** — when the stream is finite and you need `[]T`, `Collect` blocks until complete and returns the slice + error\n3. **Prefer typed Pipe functions** — `Pipe2`, `Pipe3`...`Pipe25` catch type mismatches at compile time. Reserve untyped `Pipe` for dynamic operator chains\n4. **Bound infinite streams** — use `Take(n)`, `TakeUntil(signal)`, `Timeout(d)`, or context cancellation. Unbounded streams leak goroutines\n5. **Use `Tap`\u002F`Do` for observability** — log, trace, or meter emissions without altering the stream. Chain `TapOnError` for error monitoring\n6. **Prefer `samber\u002Flo` for simple transforms** — if the data is a finite slice and you need Map\u002FFilter\u002FReduce, use `lo`. Reach for `ro` when data arrives over time, from multiple sources, or needs retry\u002Ftimeout\u002Fbackpressure\n\n## Plugin Ecosystem\n\n40+ plugins extend ro with domain-specific operators:\n\n| Category | Plugins | Import path prefix |\n| --- | --- | --- |\n| Encoding | JSON, CSV, Base64, Gob | `plugins\u002Fencoding\u002F...` |\n| Network | HTTP, I\u002FO, FSNotify | `plugins\u002Fhttp`, `plugins\u002Fio`, `plugins\u002Ffsnotify` |\n| Scheduling | Cron, ICS | `plugins\u002Fcron`, `plugins\u002Fics` |\n| Observability | Zap, Slog, Zerolog, Logrus, Sentry, Oops | `plugins\u002Fobservability\u002F...`, `plugins\u002Fsamber\u002Foops` |\n| Rate limiting | Native, Ulule | `plugins\u002Fratelimit\u002F...` |\n| Data | Bytes, Strings, Sort, Strconv, Regexp, Template | `plugins\u002Fbytes`, `plugins\u002Fstrings`, etc. |\n| System | Process, Signal | `plugins\u002Fproc`, `plugins\u002Fsignal` |\n\nFor the full plugin catalog with import paths and usage examples, see [Plugin Ecosystem](.\u002Freferences\u002Fplugin-ecosystem.md).\n\nFor real-world reactive patterns (retry+timeout, WebSocket fan-out, graceful shutdown, stream combination), see [Patterns](.\u002Freferences\u002Fpatterns.md).\n\nIf you encounter a bug or unexpected behavior in samber\u002Fro, open an issue at [github.com\u002Fsamber\u002Fro\u002Fissues](https:\u002F\u002Fgithub.com\u002Fsamber\u002Fro\u002Fissues).\n\n## Cross-References\n\n- → See `samber\u002Fcc-skills-golang@golang-samber-lo` skill for finite slice transforms (Map, Filter, Reduce, GroupBy) — use lo when data is already in a slice\n- → See `samber\u002Fcc-skills-golang@golang-samber-mo` skill for monadic types (Option, Result, Either) that compose with ro pipelines\n- → See `samber\u002Fcc-skills-golang@golang-samber-hot` skill for in-memory caching (also available as an ro plugin)\n- → See `samber\u002Fcc-skills-golang@golang-concurrency` skill for goroutine\u002Fchannel patterns when reactive streams are overkill\n- → See `samber\u002Fcc-skills-golang@golang-observability` skill for monitoring reactive pipelines in production\n","**Persona:** You are a Go engineer who reaches for reactive streams when data flows asynchronously or infinitely. You use samber\u002Fro to build declarative pipelines instead of manual goroutine\u002Fchannel wiring, but you know when a simple slice + samber\u002Flo is enough.\n\n**Thinking mode:** Use `ultrathink` when designing advanced reactive pipelines or choosing between cold\u002Fhot observables, subjects, and combining operators. Wrong architecture leads to resource leaks or missed events.\n\n# samber\u002Fro — Reactive Streams for Go\n\nGo implementation of [ReactiveX](https:\u002F\u002Freactivex.io\u002F). Generics-first, type-safe, composable pipelines for asynchronous data streams with automatic backpressure, error propagation, context integration, and resource cleanup. 150+ operators, 5 subject types, 40+ plugins.\n\n**Official Resources:**\n\n- [github.com\u002Fsamber\u002Fro](https:\u002F\u002Fgithub.com\u002Fsamber\u002Fro)\n- [ro.samber.dev](https:\u002F\u002Fro.samber.dev)\n- [pkg.go.dev\u002Fgithub.com\u002Fsamber\u002Fro](https:\u002F\u002Fpkg.go.dev\u002Fgithub.com\u002Fsamber\u002Fro)\n\nThis skill is not exhaustive. Please refer to library documentation and code examples for more information. For Go package docs, symbols, versions, importers, and known vulnerabilities, → See `samber\u002Fcc-skills-golang@golang-pkg-go-dev` skill (`godig`) — prefer it over Context7 for Go package facts. To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See `samber\u002Fcc-skills-golang@golang-gopls` skill (`gopls`). Context7 remains a fallback for docs not indexed on pkg.go.dev.\n\n## Why samber\u002Fro (Streams vs Slices)\n\nGo channels + goroutines become unwieldy for complex async pipelines: manual channel closures, verbose goroutine lifecycle, error propagation across nested selects, and no composable operators. `samber\u002Fro` solves this with declarative, chainable stream operators.\n\n**When to use which tool:**\n\n| Scenario | Tool | Why |\n| --- | --- | --- |\n| Transform a slice (map, filter, reduce) | `samber\u002Flo` | Finite, synchronous, eager — no stream overhead needed |\n| Simple goroutine fan-out with error handling | `errgroup` | Standard lib, lightweight, sufficient for bounded concurrency |\n| Infinite event stream (WebSocket, tickers, file watcher) | `samber\u002Fro` | Declarative pipeline with backpressure, retry, timeout, combine |\n| Real-time data enrichment from multiple async sources | `samber\u002Fro` | CombineLatest\u002FZip compose dependent streams without manual select |\n| Pub\u002Fsub with multiple consumers sharing one source | `samber\u002Fro` | Hot observables (Share\u002FSubjects) handle multicast natively |\n\n**Key differences: lo vs ro**\n\n| Aspect | `samber\u002Flo` | `samber\u002Fro` |\n| --- | --- | --- |\n| Data | Finite slices | Infinite streams |\n| Execution | Synchronous, blocking | Asynchronous, non-blocking |\n| Evaluation | Eager (allocates intermediate slices) | Lazy (processes items as they arrive) |\n| Timing | Immediate | Time-aware (delay, throttle, interval, timeout) |\n| Error model | Return `(T, error)` per call | Error channel propagates through pipeline |\n| Use case | Collection transforms | Event-driven, real-time, async pipelines |\n\n## Installation\n\n```bash\ngo get github.com\u002Fsamber\u002Fro\n```\n\n## Core Concepts\n\nFour building blocks:\n\n1. **Observable** — a data source that emits values over time. Cold by default: each subscriber triggers independent execution from scratch\n2. **Observer** — a consumer with three callbacks: `onNext(T)`, `onError(error)`, `onComplete()`\n3. **Operator** — a function that transforms an observable into another observable, chained via `Pipe`\n4. **Subscription** — the connection between observable and observer. Call `.Wait()` to block or `.Unsubscribe()` to cancel\n\n```go\nobservable := ro.Pipe2(\n    ro.RangeWithInterval(0, 5, 1*time.Second),\n    ro.Filter(func(x int) bool { return x%2 == 0 }),\n    ro.Map(func(x int) string { return fmt.Sprintf(\"even-%d\", x) }),\n)\n\nobservable.Subscribe(ro.NewObserver(\n    func(s string) { fmt.Println(s) },      \u002F\u002F onNext\n    func(err error) { log.Println(err) },    \u002F\u002F onError\n    func() { fmt.Println(\"Done!\") },         \u002F\u002F onComplete\n))\n\u002F\u002F Output: \"even-0\", \"even-2\", \"even-4\", \"Done!\"\n\n\u002F\u002F Or collect synchronously:\nvalues, err := ro.Collect(observable)\n```\n\n## Cold vs Hot Observables\n\n**Cold** (default): each `.Subscribe()` starts a new independent execution. Safe and predictable — use by default.\n\n**Hot**: multiple subscribers share a single execution. Use when the source is expensive (WebSocket, DB poll) or subscribers must see the same events.\n\n| Convert with | Behavior |\n| --- | --- |\n| `Share()` | Cold → hot with reference counting. Last unsubscribe tears down |\n| `ShareReplay(n)` | Same as Share + buffers last N values for late subscribers |\n| `Connectable()` | Cold → hot, but waits for explicit `.Connect()` call |\n| Subjects | Natively hot — call `.Send()`, `.Error()`, `.Complete()` directly |\n\n| Subject | Constructor | Replay behavior |\n| --- | --- | --- |\n| `PublishSubject` | `NewPublishSubject[T]()` | None — late subscribers miss past events |\n| `BehaviorSubject` | `NewBehaviorSubject[T](initial)` | Replays last value to new subscribers |\n| `ReplaySubject` | `NewReplaySubject[T](bufferSize)` | Replays last N values |\n| `AsyncSubject` | `NewAsyncSubject[T]()` | Emits only last value, only on complete |\n| `UnicastSubject` | `NewUnicastSubject[T](bufferSize)` | Single subscriber only |\n\nFor subject details and hot observable patterns, see [Subjects Guide](.\u002Freferences\u002Fsubjects-guide.md).\n\n## Operator Quick Reference\n\n| Category | Key operators | Purpose |\n| --- | --- | --- |\n| Creation | `Just`, `FromSlice`, `FromChannel`, `Range`, `Interval`, `Defer`, `Future` | Create observables from various sources |\n| Transform | `Map`, `MapErr`, `FlatMap`, `Scan`, `Reduce`, `GroupBy` | Transform or accumulate stream values |\n| Filter | `Filter`, `Take`, `TakeLast`, `Skip`, `Distinct`, `Find`, `First`, `Last` | Selectively emit values |\n| Combine | `Merge`, `Concat`, `Zip2`–`Zip6`, `CombineLatest2`–`CombineLatest5`, `Race` | Merge multiple observables |\n| Error | `Catch`, `OnErrorReturn`, `OnErrorResumeNextWith`, `Retry`, `RetryWithConfig` | Recover from errors |\n| Timing | `Delay`, `DelayEach`, `Timeout`, `ThrottleTime`, `SampleTime`, `BufferWithTime` | Control emission timing |\n| Side effect | `Tap`\u002F`Do`, `TapOnNext`, `TapOnError`, `TapOnComplete` | Observe without altering stream |\n| Terminal | `Collect`, `ToSlice`, `ToChannel`, `ToMap` | Consume stream into Go types |\n\nUse typed `Pipe2`, `Pipe3` ... `Pipe25` for compile-time type safety across operator chains. The untyped `Pipe` uses `any` and loses type checking.\n\nFor the complete operator catalog (150+ operators with signatures), see [Operators Guide](.\u002Freferences\u002Foperators-guide.md).\n\n## Common Mistakes\n\n| Mistake | Why it fails | Fix |\n| --- | --- | --- |\n| Using `ro.OnNext()` without error handler | Errors are silently dropped — bugs hide in production | Use `ro.NewObserver(onNext, onError, onComplete)` with all 3 callbacks |\n| Using untyped `Pipe()` instead of `Pipe2`\u002F`Pipe3` | Loses compile-time type safety, errors surface at runtime | Use `Pipe2`, `Pipe3`...`Pipe25` for typed operator chains |\n| Forgetting `.Unsubscribe()` on infinite streams | Goroutine leak — the observable runs forever | Use `TakeUntil(signal)`, context cancellation, or explicit `Unsubscribe()` |\n| Using `Share()` when cold is sufficient | Unnecessary complexity, harder to reason about lifecycle | Use hot observables only when multiple consumers need the same stream |\n| Using `samber\u002Fro` for finite slice transforms | Stream overhead (goroutines, subscriptions) for a synchronous operation | Use `samber\u002Flo` — it's simpler, faster, and purpose-built for slices |\n| Not propagating context for cancellation | Streams ignore shutdown signals, causing resource leaks on termination | Chain `ContextWithTimeout` or `ThrowOnContextCancel` in the pipeline |\n\n## Best Practices\n\n1. **Always handle all three events** — use `NewObserver(onNext, onError, onComplete)`, not just `OnNext`. Unhandled errors cause silent data loss\n2. **Use `Collect()` for synchronous consumption** — when the stream is finite and you need `[]T`, `Collect` blocks until complete and returns the slice + error\n3. **Prefer typed Pipe functions** — `Pipe2`, `Pipe3`...`Pipe25` catch type mismatches at compile time. Reserve untyped `Pipe` for dynamic operator chains\n4. **Bound infinite streams** — use `Take(n)`, `TakeUntil(signal)`, `Timeout(d)`, or context cancellation. Unbounded streams leak goroutines\n5. **Use `Tap`\u002F`Do` for observability** — log, trace, or meter emissions without altering the stream. Chain `TapOnError` for error monitoring\n6. **Prefer `samber\u002Flo` for simple transforms** — if the data is a finite slice and you need Map\u002FFilter\u002FReduce, use `lo`. Reach for `ro` when data arrives over time, from multiple sources, or needs retry\u002Ftimeout\u002Fbackpressure\n\n## Plugin Ecosystem\n\n40+ plugins extend ro with domain-specific operators:\n\n| Category | Plugins | Import path prefix |\n| --- | --- | --- |\n| Encoding | JSON, CSV, Base64, Gob | `plugins\u002Fencoding\u002F...` |\n| Network | HTTP, I\u002FO, FSNotify | `plugins\u002Fhttp`, `plugins\u002Fio`, `plugins\u002Ffsnotify` |\n| Scheduling | Cron, ICS | `plugins\u002Fcron`, `plugins\u002Fics` |\n| Observability | Zap, Slog, Zerolog, Logrus, Sentry, Oops | `plugins\u002Fobservability\u002F...`, `plugins\u002Fsamber\u002Foops` |\n| Rate limiting | Native, Ulule | `plugins\u002Fratelimit\u002F...` |\n| Data | Bytes, Strings, Sort, Strconv, Regexp, Template | `plugins\u002Fbytes`, `plugins\u002Fstrings`, etc. |\n| System | Process, Signal | `plugins\u002Fproc`, `plugins\u002Fsignal` |\n\nFor the full plugin catalog with import paths and usage examples, see [Plugin Ecosystem](.\u002Freferences\u002Fplugin-ecosystem.md).\n\nFor real-world reactive patterns (retry+timeout, WebSocket fan-out, graceful shutdown, stream combination), see [Patterns](.\u002Freferences\u002Fpatterns.md).\n\nIf you encounter a bug or unexpected behavior in samber\u002Fro, open an issue at [github.com\u002Fsamber\u002Fro\u002Fissues](https:\u002F\u002Fgithub.com\u002Fsamber\u002Fro\u002Fissues).\n\n## Cross-References\n\n- → See `samber\u002Fcc-skills-golang@golang-samber-lo` skill for finite slice transforms (Map, Filter, Reduce, GroupBy) — use lo when data is already in a slice\n- → See `samber\u002Fcc-skills-golang@golang-samber-mo` skill for monadic types (Option, Result, Either) that compose with ro pipelines\n- → See `samber\u002Fcc-skills-golang@golang-samber-hot` skill for in-memory caching (also available as an ro plugin)\n- → See `samber\u002Fcc-skills-golang@golang-concurrency` skill for goroutine\u002Fchannel patterns when reactive streams are overkill\n- → See `samber\u002Fcc-skills-golang@golang-observability` skill for monitoring reactive pipelines in production\n",{"name":5,"license":15,"metadata":54,"description":7,"allowed-tools":65,"compatibility":66,"user-invocable":67},{"author":55,"version":56,"openclaw":57},"samber","1.1.3",{"emoji":58,"install":59,"homepage":60,"requires":61,"skill-library-version":64},"👁",[],"https:\u002F\u002Fgithub.com\u002Fsamber\u002Fcc-skills-golang",{"bins":62},[63],"go","0.3.0","Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent mcp__context7__resolve-library-id mcp__context7__query-docs AskUserQuestion Bash(godig:*) Bash(gopls:*) LSP mcp__gopls__*","Designed for Claude Code or similar AI coding agents, and for projects using Golang.",true,"claude\u002Finstall-gsd-build-foQdV","d86cd127f527124b5fd0fd0bc679a4d79b7d01d7",".agents\u002Fskills\u002Fgolang-samber-ro","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik","https:\u002F\u002Fnorvik-orpin.vercel.app","https:\u002F\u002Fgithub.com\u002Fpattanation","2026-07-17 11:17:04",{"source":8,"skillName":5,"commands":76,"prompt":86,"zipAvailable":67},[77,80,83],{"tool":78,"command":79},"npx","npx skills add pattanation\u002FNorvik --skill golang-samber-ro",{"tool":81,"command":82},"bunx","bunx skills add pattanation\u002FNorvik --skill golang-samber-ro",{"tool":84,"command":85},"pnpm","pnpm dlx skills add pattanation\u002FNorvik --skill golang-samber-ro","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fgolang-samber-ro\u002FSKILL.md",[88,94,98,102,106],{"path":89,"resourceType":90,"resourceTypeDesc":91,"sizeBytes":92,"sourceHtmlUrl":93},"evals\u002Fevals.json","REFERENCE","参考文档",17758,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fgolang-samber-ro\u002Fevals\u002Fevals.json",{"path":95,"resourceType":90,"resourceTypeDesc":91,"sizeBytes":96,"sourceHtmlUrl":97},"references\u002Foperators-guide.md",14184,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fgolang-samber-ro\u002Freferences\u002Foperators-guide.md",{"path":99,"resourceType":90,"resourceTypeDesc":91,"sizeBytes":100,"sourceHtmlUrl":101},"references\u002Fpatterns.md",7430,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fgolang-samber-ro\u002Freferences\u002Fpatterns.md",{"path":103,"resourceType":90,"resourceTypeDesc":91,"sizeBytes":104,"sourceHtmlUrl":105},"references\u002Fplugin-ecosystem.md",5974,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fgolang-samber-ro\u002Freferences\u002Fplugin-ecosystem.md",{"path":107,"resourceType":90,"resourceTypeDesc":91,"sizeBytes":108,"sourceHtmlUrl":109},"references\u002Fsubjects-guide.md",5836,"https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fgolang-samber-ro\u002Freferences\u002Fsubjects-guide.md",[111,144,170,193,215,230],{"skillNo":112,"name":113,"nameZh":6,"description":114,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":115,"licenseFileUrl":116,"sourceHtmlUrl":117,"categories":118,"keywords":125,"publishedAt":143},"01M71QDV4DM8T19HEHWATEF1K4","webapp-testing","Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fwebapp-testing\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fwebapp-testing\u002FSKILL.md",[119,122],{"categoryNo":120,"categoryName":121,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":123,"categoryName":124,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",[126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142],"webapp","testing","webapp testing","for","applications","local","frontend","debugging","toolkit","logs","browser","with","playwright","web","behavior","ui","screenshots","2026-11-10 13:02:02",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":115,"licenseFileUrl":148,"sourceHtmlUrl":149,"categories":150,"keywords":152,"publishedAt":143},"01M71QDH2GGMXGA9105C9W1N7B","web-artifacts-builder","Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn\u002Fui). Use for complex artifacts requiring state management, routing, or shadcn\u002Fui components - not for simple single-file HTML\u002FJSX artifacts.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fweb-artifacts-builder\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fweb-artifacts-builder\u002FSKILL.md",[151],{"categoryNo":123,"categoryName":124,"taxonomyType":21,"taxonomyTypeDesc":22},[153,154,155,139,156,157,158,129,159,160,132,161,162,163,164,165,166,167,168,169],"builder","artifacts builder","artifacts","web artifacts builder","single-file","css","Tailwind","ui components","single","use","file","components","react","multi","state","routing","state management",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":174,"sourceHtmlUrl":175,"categories":176,"keywords":178,"publishedAt":143},"01M71QD9T2XC3EWMQNN9ACNWQ1","vueuse-functions","Apply VueUse composables where appropriate to build concise, maintainable Vue.js \u002F Nuxt features.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvueuse-functions\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvueuse-functions\u002FSKILL.md",[177],{"categoryNo":123,"categoryName":124,"taxonomyType":21,"taxonomyTypeDesc":22},[179,180,181,182,183,184,185,186,187,188,189,190,191,192],"functions","vueuse","vueuse functions","project","nuxt","apply","github","concise","build","https","features","vue","js","composables",{"skillNo":194,"name":195,"nameZh":6,"description":196,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":197,"sourceHtmlUrl":198,"categories":199,"keywords":202,"publishedAt":143},"01M71QD51HWSGYMCMB7RW7PGK8","vue-testing-best-practices","Use for Vue.js testing. Covers Vitest, Vue Test Utils, component testing, mocking, testing patterns, and Playwright for E2E testing.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-testing-best-practices\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-testing-best-practices\u002FSKILL.md",[200,201],{"categoryNo":120,"categoryName":121,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":123,"categoryName":124,"taxonomyType":21,"taxonomyTypeDesc":22},[203,127,204,190,205,138,206,207,208,185,209,129,210,211,212,162,213,191,214],"vue testing best practices","testing best practices","best practices","test","testing patterns","component","vitest","mocking","e2e","utils","patterns","e2e testing",{"skillNo":216,"name":217,"nameZh":6,"description":218,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":219,"sourceHtmlUrl":220,"categories":221,"keywords":223,"publishedAt":143},"01M71QD358H2DJ9THJRBP77T3T","vue-router-best-practices","Vue Router 4 patterns, navigation guards, route params, and route-component lifecycle interactions.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-router-best-practices\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-router-best-practices\u002FSKILL.md",[222],{"categoryNo":123,"categoryName":124,"taxonomyType":21,"taxonomyTypeDesc":22},[224,190,225,205,226,208,227,185,213,228,229],"router","vue router best practices","route","guards","navigation","lifecycle",{"skillNo":231,"name":232,"nameZh":6,"description":233,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":234,"sourceHtmlUrl":235,"categories":236,"keywords":238,"publishedAt":143},"01M71QCYPNWDE2MQZ1TF3ED5S4","vue-best-practices","MUST be used for Vue.js tasks. Strongly recommends Composition API with `\u003Cscript setup>` and TypeScript as the standard approach. Covers Vue 3, SSR, Volar, vue-tsc. Load for any Vue, .vue files, Vue Router, Pinia, or Vite with Vue work. ALWAYS use Composition API unless the project explicitly requires Options API.","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-best-practices\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fpattanation\u002FNorvik\u002Fblob\u002Fclaude\u002Finstall-gsd-build-foQdV\u002F.agents\u002Fskills\u002Fvue-best-practices\u002FSKILL.md",[237],{"categoryNo":123,"categoryName":124,"taxonomyType":21,"taxonomyTypeDesc":22},[239,190,205,240,182,241,242,243,224,244,245,246,247,248,249,129,250,162,251,252],"vue best practices","Composition","files","tasks","api","pinia","work","options","ssr","typescript","as","vite","load","standard"]