diff --git a/docs/articles/concepts/abstractions-first.md b/docs/articles/concepts/abstractions-first.md index 30e42aa4..c6f64740 100644 --- a/docs/articles/concepts/abstractions-first.md +++ b/docs/articles/concepts/abstractions-first.md @@ -4,18 +4,18 @@ SquidStd is built abstractions-first: code depends on contracts, and concrete ba ## Contract package plus provider packages -Each capability is a contract package paired with one or more provider packages. The contract package — `*.Abstractions` — defines the interfaces and DTOs. Provider packages implement them. Your application references the abstraction and depends on the provider only in the host project. See the [architecture](architecture.md) overview for how this shapes the package graph. +Each capability is a contract package paired with one or more provider packages. The contract package - `*.Abstractions` - defines the interfaces and DTOs. Provider packages implement them. Your application references the abstraction and depends on the provider only in the host project. See the [architecture](architecture.md) overview for how this shapes the package graph. ## In-memory for tests, external for prod Most capabilities ship an in-memory provider for tests and an external-backend provider for production: -- **Messaging** — in-memory, or `SquidStd.Messaging.RabbitMq` / `SquidStd.Messaging.Sqs`. -- **Caching** — in-memory, or `SquidStd.Caching.Redis`. -- **Storage** — file-backed, or `SquidStd.Storage.S3` (S3 and MinIO). +- **Messaging** - in-memory, or `SquidStd.Messaging.RabbitMq` / `SquidStd.Messaging.Sqs`. +- **Caching** - in-memory, or `SquidStd.Caching.Redis`. +- **Storage** - file-backed, or `SquidStd.Storage.S3` (S3 and MinIO). Tests run fast and deterministically against the in-memory provider; production swaps in the external backend. ## Swapping providers without touching call sites -Because call sites depend only on the contract, switching backends is a registration change in the host — `container.AddInMemoryMessaging()` versus `container.AddRabbitMqMessaging(...)` — with no edits to the code that publishes or consumes messages. See [dependency injection](dependency-injection.md) for the registration pattern that makes the swap a one-line change. +Because call sites depend only on the contract, switching backends is a registration change in the host - `container.AddInMemoryMessaging()` versus `container.AddRabbitMqMessaging(...)` - with no edits to the code that publishes or consumes messages. See [dependency injection](dependency-injection.md) for the registration pattern that makes the swap a one-line change. diff --git a/docs/articles/concepts/architecture.md b/docs/articles/concepts/architecture.md index ddd86bd0..2bc88a2d 100644 --- a/docs/articles/concepts/architecture.md +++ b/docs/articles/concepts/architecture.md @@ -10,10 +10,10 @@ Every capability is split in two: an `*.Abstractions` package that holds the con The dependency flow runs in one direction: -- **Core** (`SquidStd.Core`) — primitives, options, and the building blocks everything else sits on. -- **Abstractions** — per-capability contract packages. -- **Providers** — concrete implementations of those contracts. -- **Host** — `SquidStdBootstrap` composes services and runs them. +- **Core** (`SquidStd.Core`) - primitives, options, and the building blocks everything else sits on. +- **Abstractions** - per-capability contract packages. +- **Providers** - concrete implementations of those contracts. +- **Host** - `SquidStdBootstrap` composes services and runs them. Higher layers depend on lower ones, never the reverse. @@ -30,5 +30,5 @@ graph TD ## Next -- [Bootstrap lifecycle](bootstrap-lifecycle.md) — how the host starts and stops services. -- [Abstractions first](abstractions-first.md) — the contract-plus-provider pattern in depth. +- [Bootstrap lifecycle](bootstrap-lifecycle.md) - how the host starts and stops services. +- [Abstractions first](abstractions-first.md) - the contract-plus-provider pattern in depth. diff --git a/docs/articles/concepts/messaging-models.md b/docs/articles/concepts/messaging-models.md index 30b98907..dea11fa1 100644 --- a/docs/articles/concepts/messaging-models.md +++ b/docs/articles/concepts/messaging-models.md @@ -8,7 +8,7 @@ The Event Bus (`IEventBus`) is a stateless broadcast. Publishers call `PublishAs ## Command Dispatcher -The Command Dispatcher is a stateless request routed to a single handler that returns a result. Unlike the Event Bus there is exactly one handler per command, and the caller awaits its result. Use it for request/response work — validating input, performing an operation, returning an outcome — where ownership of the action is unambiguous. +The Command Dispatcher is a stateless request routed to a single handler that returns a result. Unlike the Event Bus there is exactly one handler per command, and the caller awaits its result. Use it for request/response work - validating input, performing an operation, returning an outcome - where ownership of the action is unambiguous. ## Actors diff --git a/docs/articles/felix.md b/docs/articles/felix.md index bc151345..610de4a0 100644 --- a/docs/articles/felix.md +++ b/docs/articles/felix.md @@ -1,7 +1,7 @@ # Felix Network **[Felix Network](https://github.com/tgiachi/SquidStd-Felix)** is a standalone companion library to -SquidStd: secure, cross-platform **binary mesh networking** for .NET — and for a constrained C +SquidStd: secure, cross-platform **binary mesh networking** for .NET - and for a constrained C target such as the ESP32. It lives in its own repository and ships its own NuGet packages under the `SquidStd.Felix.*` prefix. @@ -12,15 +12,15 @@ nodes over **ENet** (reliable UDP), behind a small **portable binary frame** tha can speak byte-for-byte. On top of that secure node it adds an optional self-forming **mesh** layer (seed discovery + gossip of the peer list with auto-connect). -- **Secure node** — ENet transport, the portable frame (its header is authenticated as AES-GCM +- **Secure node** - ENet transport, the portable frame (its header is authenticated as AES-GCM additional data), best-effort DEFLATE, and a raw `(type, bytes)` API. -- **Typed layer** — optional `Send` / `On` over MemoryPack with a `[FelixMessage(id)]` +- **Typed layer** - optional `Send` / `On` over MemoryPack with a `[FelixMessage(id)]` attribute mapping message types to wire ids. -- **Mesh** — fully-connected, self-healing peer discovery via seeds and portable gossip. -- **Pluggable transport** — the encrypted frame is transport-agnostic; `ITransport` decouples the +- **Mesh** - fully-connected, self-healing peer discovery via seeds and portable gossip. +- **Pluggable transport** - the encrypted frame is transport-agnostic; `ITransport` decouples the node from the link (ENet ships; a serial/UART transport carries Felix over a reliable serial or Bluetooth RFCOMM stream without WiFi). -- **Portable** — the wire format is documented for non-.NET targets, with a host-testable C core +- **Portable** - the wire format is documented for non-.NET targets, with a host-testable C core (`felix-c`) and ESP32 (ESP-IDF) examples proving byte-for-byte C↔.NET parity. ## Packages @@ -84,7 +84,7 @@ mesh.Broadcast(type: 7, "hi mesh"u8.ToArray()); The protocol is portable. The Felix repository ships a portable C core (`felix-c`: AES-256-GCM over mbedTLS, raw-DEFLATE inflate, the Felix frame, an ENet leaf transport, and a `felix_serial` UART -module) plus host harnesses — all testable without an ESP32, proving byte-for-byte C↔.NET parity. +module) plus host harnesses - all testable without an ESP32, proving byte-for-byte C↔.NET parity. The same C builds on an ESP32 (ESP-IDF), over ENet/WiFi or over UART / Bluetooth Classic SPP. ## Learn more diff --git a/docs/articles/guides/choosing-search-database.md b/docs/articles/guides/choosing-search-database.md index fa5c3292..cce5d76b 100644 --- a/docs/articles/guides/choosing-search-database.md +++ b/docs/articles/guides/choosing-search-database.md @@ -20,4 +20,4 @@ bootstrap.ConfigureServices(container => container.RegisterDatabase()); Reach for `AddElasticsearch` when the core requirement is searching text or documents by relevance; use `RegisterDatabase` with the FreeSql provider that -matches your engine for everything relational. They compose — many apps use both. +matches your engine for everything relational. They compose - many apps use both. diff --git a/docs/articles/guides/security.md b/docs/articles/guides/security.md index df2373f5..767f194d 100644 --- a/docs/articles/guides/security.md +++ b/docs/articles/guides/security.md @@ -39,5 +39,5 @@ hashing credentials, protecting payloads with a key, and storing named secrets. ## Recommendation Use `HashUtils` for credentials, `ISecretProtector` (AES-GCM locally, KMS in the -cloud) for encrypting blobs, and `ISecretStore` for named secrets — backed by +cloud) for encrypting blobs, and `ISecretStore` for named secrets - backed by files in development and AWS Secrets Manager in production. diff --git a/docs/articles/health-checks.md b/docs/articles/health-checks.md index a6b34a58..ae8e3016 100644 --- a/docs/articles/health-checks.md +++ b/docs/articles/health-checks.md @@ -5,7 +5,7 @@ The health-check aggregator (`IHealthCheckService` in `SquidStd.Core`, implement - Implement `IHealthCheck` (`Name` + `CheckAsync`) and register it as `IHealthCheck`. - `CheckHealthAsync()` runs all checks **in parallel**, each with a per-check timeout and exception - isolation — a failing or timed-out check becomes an `Unhealthy` entry without breaking the others. + isolation - a failing or timed-out check becomes an `Unhealthy` entry without breaking the others. - The overall `HealthReport.Status` is `Unhealthy` if any check is `Unhealthy`, otherwise `Healthy`. ```csharp diff --git a/docs/articles/scheduler.md b/docs/articles/scheduler.md index 1ee13abb..f9ca5df7 100644 --- a/docs/articles/scheduler.md +++ b/docs/articles/scheduler.md @@ -5,7 +5,7 @@ standard 5-field cron expressions evaluated in UTC. - `Schedule(name, cronExpression, handler)` → returns a job id. - `Unschedule(jobId)` / `UnscheduleByName(name)`. -- `Jobs` — a snapshot of registered jobs (`CronJobInfo`). +- `Jobs` - a snapshot of registered jobs (`CronJobInfo`). Each job is a one-shot, self-rescheduling timer on the timer wheel: when it fires, the handler is dispatched through `IJobSystem`, and the next occurrence is registered. An occurrence is **skipped** if the @@ -31,7 +31,7 @@ scheduler.Schedule("cleanup", "0 3 * * *", async ct => ## Event loop For applications that need a tight, frame-driven loop (game servers, simulations, real-time -processing), `SquidStd.Services.Core` provides `EventLoopService` — a dedicated background thread +processing), `SquidStd.Services.Core` provides `EventLoopService` - a dedicated background thread (`SquidStd-EventLoop`) that, every frame: 1. drains the `IMainThreadDispatcher` (deferred callbacks posted with `Post`), and @@ -67,7 +67,7 @@ eventLoop: ### Event loop vs. timer-wheel pump Both `EventLoopService` and `TimerWheelPumpService` advance the timer wheel, so they are **mutually -exclusive** — register exactly one. The exclusivity is structural: both implement the +exclusive** - register exactly one. The exclusivity is structural: both implement the `ITimerWheelDriver` marker, `RegisterEventLoop()` throws if a driver is already registered, and modules that need the wheel (the worker manager, the mail poller) auto-register the pump only when no driver is present. Use the pump for ordinary apps where a coarse periodic pump is enough; use the event loop when diff --git a/docs/articles/serialization.md b/docs/articles/serialization.md index 3913751a..ba1caaa5 100644 --- a/docs/articles/serialization.md +++ b/docs/articles/serialization.md @@ -2,8 +2,8 @@ SquidStd uses a single serialization abstraction across the framework, defined in `SquidStd.Core`: -- `IDataSerializer` — `ReadOnlyMemory Serialize(T value)` -- `IDataDeserializer` — `T Deserialize(ReadOnlyMemory data)` +- `IDataSerializer` - `ReadOnlyMemory Serialize(T value)` +- `IDataDeserializer` - `T Deserialize(ReadOnlyMemory data)` The default implementation, `JsonDataSerializer`, uses `System.Text.Json` Web defaults and implements both interfaces. It is registered by `RegisterCoreServices()` (via `RegisterDataSerializer()`), so both diff --git a/docs/index.md b/docs/index.md index ebd366c9..181c0d0f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,19 +8,19 @@ _layout: landing # SquidStd -A batteries-included, modular standard library for .NET 10 — distilled from years of building +A batteries-included, modular standard library for .NET 10 - distilled from years of building real-world server software. Each capability ships behind a small contract with an in-memory implementation for tests and a production backend, published as a focused NuGet package. Security & crypto, configuration, persistence, messaging, caching, storage, a virtual filesystem, -search, mail, workers, actors, telemetry, scripting — take only what you need. +search, mail, workers, actors, telemetry, scripting - take only what you need. ## Start here -- **[Tutorials](tutorials/index.md)** — learn by building: bootstrap, caching, messaging, workers, +- **[Tutorials](tutorials/index.md)** - learn by building: bootstrap, caching, messaging, workers, crypto, persistence, and more. -- **[Guides](articles/guides/configuration.md)** — task-focused how-to and "which provider" decision guides. -- **[Concepts](articles/concepts/architecture.md)** — the architecture and the ideas behind it. -- **[Packages](articles/getting-started.md)** — per-package reference. -- **[API reference](api/index.md)** — full type/member documentation. -- **[Felix Network](articles/felix.md)** — companion secure binary mesh-networking library (.NET + C/ESP32). +- **[Guides](articles/guides/configuration.md)** - task-focused how-to and "which provider" decision guides. +- **[Concepts](articles/concepts/architecture.md)** - the architecture and the ideas behind it. +- **[Packages](articles/getting-started.md)** - per-package reference. +- **[API reference](api/index.md)** - full type/member documentation. +- **[Felix Network](articles/felix.md)** - companion secure binary mesh-networking library (.NET + C/ESP32). diff --git a/docs/tutorials/caching.md b/docs/tutorials/caching.md index 2d7d84c0..5e5dec99 100644 --- a/docs/tutorials/caching.md +++ b/docs/tutorials/caching.md @@ -27,7 +27,7 @@ A host that resolves `ICacheService` (`SquidStd.Caching.Abstractions`) backed by ### 3. Switch to Redis -Replace the registration with the Redis backend — the `ICacheService` usage is identical: +Replace the registration with the Redis backend - the `ICacheService` usage is identical: ```csharp container.AddRedisCache("redis://localhost:6379"); diff --git a/docs/tutorials/command-dispatcher.md b/docs/tutorials/command-dispatcher.md index 2c90c77a..bab38c7c 100644 --- a/docs/tutorials/command-dispatcher.md +++ b/docs/tutorials/command-dispatcher.md @@ -6,7 +6,7 @@ Register typed command handlers, dispatch commands against a context, and read b A `Container` with a `RegisterCommandDispatcher` and several handlers (`SquidStd.Services.Core`), dispatching commands that carry a `Session` context. One command type -has two handlers — both run on dispatch. +has two handlers - both run on dispatch. ## Prerequisites @@ -19,14 +19,14 @@ has two handlers — both run on dispatch. Register the dispatcher for the context type, then each handler. `EchoCommand` has two handlers (`EchoHandler` and `AuditHandler`); both will run. The subscription loop is what -`CommandDispatcherActivator` does at runtime — inlined here to keep the sample +`CommandDispatcherActivator` does at runtime - inlined here to keep the sample self-contained. [!code-csharp[](../../samples/SquidStd.Samples.Commands/Program.cs#step-1)] ### 2. Dispatch commands with a context -The context (here a `Session`) is passed explicitly at dispatch time — in a server this is the +The context (here a `Session`) is passed explicitly at dispatch time - in a server this is the session the message arrived on. [!code-csharp[](../../samples/SquidStd.Samples.Commands/Program.cs#step-2)] diff --git a/docs/tutorials/crypto.md b/docs/tutorials/crypto.md index 6e8f9b65..473ea13e 100644 --- a/docs/tutorials/crypto.md +++ b/docs/tutorials/crypto.md @@ -17,7 +17,7 @@ keys survive a restart by reloading them from the armored `.asc` files on disk. ### 1. Register the PGP services and a file-backed key store -`RegisterPgp` wires the keyring and `IPgpService`; the factory chooses the key store — here a +`RegisterPgp` wires the keyring and `IPgpService`; the factory chooses the key store - here a `FilePgpKeyStore` that reads and writes armored `.asc` files in a directory. [!code-csharp[](../../samples/SquidStd.Samples.Crypto/Program.cs#step-1)] @@ -45,7 +45,7 @@ survives a restart. ## Password-based encryption -`PasswordCipher` encrypts a payload directly under a password — no key management required. Argon2id +`PasswordCipher` encrypts a payload directly under a password - no key management required. Argon2id derives the key, AES-256-GCM seals the data, and the result is a self-describing, versioned envelope (salt, nonce, tag and KDF cost are embedded). Decryption needs only the password and the blob. @@ -57,7 +57,7 @@ using SquidStd.Crypto.Password.Data; byte[] blob = PasswordCipher.Encrypt(payloadBytes, "correct horse battery staple"); byte[] back = PasswordCipher.Decrypt(blob, "correct horse battery staple"); -// Text round-trip — the envelope is base64-encoded, safe to store in config or JSON. +// Text round-trip - the envelope is base64-encoded, safe to store in config or JSON. string protectedText = PasswordCipher.EncryptString("a secret", "pw"); string clear = PasswordCipher.DecryptString(protectedText, "pw"); ``` @@ -66,7 +66,7 @@ The cost of the Argon2id key derivation defaults to `PbkdfCost.Moderate`. Raise long-lived secrets: ```csharp -// PbkdfCost.Sensitive — slower derivation, stronger resistance to offline attacks. +// PbkdfCost.Sensitive - slower derivation, stronger resistance to offline attacks. byte[] strong = PasswordCipher.Encrypt(payloadBytes, "pw", PbkdfCost.Sensitive); ``` diff --git a/docs/tutorials/events-jobs-scheduling.md b/docs/tutorials/events-jobs-scheduling.md index c73fefa8..47264730 100644 --- a/docs/tutorials/events-jobs-scheduling.md +++ b/docs/tutorials/events-jobs-scheduling.md @@ -12,7 +12,7 @@ A host that uses three core services from `SquidStd.Services.Core`: the `IEventB - .NET 10 SDK - `dotnet add package SquidStd.Services.Core` -The cron scheduler and timer wheel are opt-in — enable them with `RegisterSchedulerServices()`: +The cron scheduler and timer wheel are opt-in - enable them with `RegisterSchedulerServices()`: [!code-csharp[](../../samples/SquidStd.Samples.EventsJobsScheduling/Program.cs#step-1)] @@ -43,7 +43,7 @@ occurrence. dotnet run --project samples/SquidStd.Samples.EventsJobsScheduling ``` -You'll see `received: hello`, `job ran on a worker thread`, and—if you let it run across a 5-minute boundary— +You'll see `received: hello`, `job ran on a worker thread`, and, if you let it run across a 5-minute boundary, `cron tick`. ## How it works @@ -53,7 +53,7 @@ scheduler is driven by the timer wheel (registered by `RegisterSchedulerServices The timer wheel is advanced by a *driver*. `RegisterSchedulerServices()` uses `TimerWheelPumpService`, a periodic background pump. Apps that need a frame-rate loop can instead call `RegisterEventLoop()`, which advances -the wheel and drains the main-thread dispatcher on a dedicated thread — see +the wheel and drains the main-thread dispatcher on a dedicated thread - see [Scheduler → Event loop](../articles/scheduler.md#event-loop). The two are mutually exclusive: register exactly one. ## See also diff --git a/docs/tutorials/messaging.md b/docs/tutorials/messaging.md index b69535a4..723f0f31 100644 --- a/docs/tutorials/messaging.md +++ b/docs/tutorials/messaging.md @@ -41,7 +41,7 @@ Prints `queue handled order-1` and `topic saw order-2`. ## How it works Queues use competing-consumers with retry and dead-lettering (`MessagingOptions`); topics use transient fan-out -(at-most-once). Swap `AddInMemoryMessaging()` for `AddRabbitMqMessaging(...)` for a durable broker — the +(at-most-once). Swap `AddInMemoryMessaging()` for `AddRabbitMqMessaging(...)` for a durable broker - the `IMessageQueue`/`IMessageTopic` code is unchanged. ## See also diff --git a/docs/tutorials/persistence.md b/docs/tutorials/persistence.md index 25a28a2f..24b38c92 100644 --- a/docs/tutorials/persistence.md +++ b/docs/tutorials/persistence.md @@ -6,7 +6,7 @@ survives a restart. ## What you'll build A standalone demo of `SquidStd.Persistence`: a `Player` store that loads existing state on -startup, appends every change to a journal, and captures a snapshot. Run it twice — the second run +startup, appends every change to a journal, and captures a snapshot. Run it twice - the second run reloads what the first saved. ## Prerequisites diff --git a/docs/tutorials/scaffolding.md b/docs/tutorials/scaffolding.md index d852beb3..e65aa6e6 100644 --- a/docs/tutorials/scaffolding.md +++ b/docs/tutorials/scaffolding.md @@ -4,7 +4,7 @@ Generate ready-to-run SquidStd projects from the command line with the `SquidStd ## What you'll build -Nothing by hand — you'll install the template pack and scaffold a console host, an ASP.NET app, a worker +Nothing by hand - you'll install the template pack and scaffold a console host, an ASP.NET app, a worker microservice, and a worker manager, each pre-wired to SquidStd. ## Prerequisites diff --git a/docs/tutorials/secrets.md b/docs/tutorials/secrets.md index a98460de..50cae1d4 100644 --- a/docs/tutorials/secrets.md +++ b/docs/tutorials/secrets.md @@ -23,7 +23,7 @@ set/get/list. ### 1. Register the KMS protector and Secrets Manager store `RegisterKmsSecretProtector` and `RegisterAwsSecretsManagerStore` take the KMS key alias, the -secret name prefix, and the AWS endpoint — pointed here at a LocalStack `ServiceUrl`. +secret name prefix, and the AWS endpoint - pointed here at a LocalStack `ServiceUrl`. [!code-csharp[](../../samples/SquidStd.Samples.Secrets/Program.cs#step-1)] diff --git a/docs/tutorials/storage.md b/docs/tutorials/storage.md index 9be3be47..c49ef7bc 100644 --- a/docs/tutorials/storage.md +++ b/docs/tutorials/storage.md @@ -27,7 +27,7 @@ A host that resolves `IObjectStorageService` (`SquidStd.Storage.Abstractions`) b ### 3. Switch to S3 -Replace the registration with the S3 backend — the `IObjectStorageService` usage is identical: +Replace the registration with the S3 backend - the `IObjectStorageService` usage is identical: ```csharp container.AddS3Storage(/* endpoint, bucket and credentials */); diff --git a/docs/tutorials/tui.md b/docs/tutorials/tui.md index cecafc80..6cdb4574 100644 --- a/docs/tutorials/tui.md +++ b/docs/tutorials/tui.md @@ -1,6 +1,6 @@ # Terminal UI (MVVM) -Build a Counter terminal app with an observable ViewModel, then display it two ways — the +Build a Counter terminal app with an observable ViewModel, then display it two ways - the imperative `TuiView` and the declarative `TuiComposedView` DSL. ## What you'll build @@ -8,9 +8,9 @@ imperative `TuiView` and the declarative `TuiComposedView` DSL. A small Counter app where a `CounterViewModel` holds a `Value` property and an `IncrementCommand`. You will see both ways to build the view: -1. **Imperative** — `TuiView`: override `BuildLayout` to add Terminal.Gui widgets, then +1. **Imperative** - `TuiView`: override `BuildLayout` to add Terminal.Gui widgets, then override `Bind` to wire them through `ViewBinder`. -2. **Declarative** — `TuiComposedView`: override `Compose` and return a `TuiNode` tree built +2. **Declarative** - `TuiComposedView`: override `Compose` and return a `TuiNode` tree built with the `Ui.*` DSL; bindings and layout are inferred from the node types. ## Prerequisites @@ -43,7 +43,7 @@ public sealed partial class CounterViewModel : TuiViewModel } ``` -### 2. Imperative view — `TuiView` +### 2. Imperative view - `TuiView` Override `BuildLayout` to create and add Terminal.Gui widgets, then override `Bind` to wire them through `ViewBinder`. The binder tracks property-changed notifications and updates widgets without @@ -75,7 +75,7 @@ public sealed class CounterView : TuiView } ``` -### 3. Declarative view — `TuiComposedView` +### 3. Declarative view - `TuiComposedView` Instead of `BuildLayout` + `Bind`, derive from `TuiComposedView` and return a node tree from `Compose`. The framework infers binding direction from the node type (Label → one-way, TextField → diff --git a/docs/tutorials/vfs.md b/docs/tutorials/vfs.md index 769e599d..2e21af67 100644 --- a/docs/tutorials/vfs.md +++ b/docs/tutorials/vfs.md @@ -16,7 +16,7 @@ encrypted-vault round-trip using `CryptoFileSystem` (`SquidStd.Crypto.Vfs`). ### 1. Register a virtual filesystem -`RegisterVfs` wires `IVirtualFileSystem`; the factory chooses the backend — here a plain +`RegisterVfs` wires `IVirtualFileSystem`; the factory chooses the backend - here a plain in-memory filesystem. [!code-csharp[](../../samples/SquidStd.Samples.Vfs/Program.cs#step-1)] @@ -37,8 +37,8 @@ Re-opening a fresh instance over the same file with the passphrase decrypts the This sample backs the vault with a single on-disk zip file via `ZipFileSystem`, writes a secret, disposes the vault, then re-opens a brand-new instance over the same file to prove on-disk -persistence. The DI helper `RegisterCryptoVault` wires exactly this — a vault over a single-file -zip — as a lockable singleton. +persistence. The DI helper `RegisterCryptoVault` wires exactly this - a vault over a single-file +zip - as a lockable singleton. [!code-csharp[](../../samples/SquidStd.Samples.Vfs/Program.cs#step-3)] @@ -64,7 +64,7 @@ container.RegisterS3FileSystem(o => o.Aws.SecretKey = "..."; }); -// IVirtualFileSystem is now backed by S3 — the rest of your code is unchanged. +// IVirtualFileSystem is now backed by S3 - the rest of your code is unchanged. var fs = container.Resolve(); await fs.WriteAllBytesAsync("reports/2026.json", payload); ``` @@ -122,13 +122,13 @@ unreachable. ### Other decorators ```csharp -// Reject all writes — safe read-only access to a shared backend. +// Reject all writes - safe read-only access to a shared backend. container.RegisterVfs(_ => new ReadOnlyFileSystem(new PhysicalFileSystem("/shared/data"))); -// Chroot to a subdirectory — all paths are resolved relative to the prefix. +// Chroot to a subdirectory - all paths are resolved relative to the prefix. container.RegisterVfs(_ => new ScopedFileSystem(new PhysicalFileSystem("/var/lib/app"), "tenant-1")); -// Overlay — reads overlay-first then fall back to base; writes go to the overlay only. +// Overlay - reads overlay-first then fall back to base; writes go to the overlay only. container.RegisterVfs(_ => new OverlayFileSystem( baseFileSystem: new PhysicalFileSystem("/defaults"), overlay: new InMemoryFileSystem())); diff --git a/src/SquidStd.Abstractions/README.md b/src/SquidStd.Abstractions/README.md index 9b2b921e..39468435 100644 --- a/src/SquidStd.Abstractions/README.md +++ b/src/SquidStd.Abstractions/README.md @@ -44,4 +44,4 @@ Tutorial: [Source generators: registration](https://tgiachi.github.io/squid-std/ ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Actors/README.md b/src/SquidStd.Actors/README.md index a34364b6..fb0bdd06 100644 --- a/src/SquidStd.Actors/README.md +++ b/src/SquidStd.Actors/README.md @@ -78,8 +78,8 @@ using var sub = session.SubscribeToEventBus(eventBus, (UserJoinedEvent e) => new - **Isolate**: a throwing handler is logged and skipped; the actor stays alive. `AskAsync` exceptions always propagate to the caller regardless of policy. -`DisposeAsync` completes the mailbox and drains queued messages — every `Tell` runs and every `Ask` -replies — within `ShutdownDrainTimeout`. If a handler is still running when that budget elapses, the +`DisposeAsync` completes the mailbox and drains queued messages - every `Tell` runs and every `Ask` +replies - within `ShutdownDrainTimeout`. If a handler is still running when that budget elapses, the actor cancels its handlers and faults any requests that never completed with `ObjectDisposedException`. ## Related @@ -89,4 +89,4 @@ actor cancels its handlers and faults any requests that never completed with `Ob ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.AspNetCore/README.md b/src/SquidStd.AspNetCore/README.md index aca9dbe6..83d00c94 100644 --- a/src/SquidStd.AspNetCore/README.md +++ b/src/SquidStd.AspNetCore/README.md @@ -49,7 +49,7 @@ Each registered `IHealthCheck` appears as its own entry in the report. Check nam |---------------------------------------|------------------------------------------------------------------------| | `SquidStdAspNetCoreBuilderExtensions` | `UseSquidStd(...)` builder extension. | | `SquidStdHostedService` | Hosted service bridging SquidStd service lifecycle to the host. | -| `SquidStdHealthChecksExtensions` | `AddSquidStdHealthChecks(...)` — bridge to ASP.NET Core health checks. | +| `SquidStdHealthChecksExtensions` | `AddSquidStdHealthChecks(...)` - bridge to ASP.NET Core health checks. | ## Unified logging (opt-in) @@ -81,4 +81,4 @@ logger: ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Aws.Abstractions/README.md b/src/SquidStd.Aws.Abstractions/README.md index d849eedf..fe3bb0bf 100644 --- a/src/SquidStd.Aws.Abstractions/README.md +++ b/src/SquidStd.Aws.Abstractions/README.md @@ -35,4 +35,4 @@ client at that endpoint instead of the regional AWS endpoint. ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Caching.Abstractions/README.md b/src/SquidStd.Caching.Abstractions/README.md index 81fa611d..4ec757b0 100644 --- a/src/SquidStd.Caching.Abstractions/README.md +++ b/src/SquidStd.Caching.Abstractions/README.md @@ -38,4 +38,4 @@ public Task GetOrComputeAsync(ICacheService cache) ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Caching.Redis/README.md b/src/SquidStd.Caching.Redis/README.md index 6359de0d..98db8783 100644 --- a/src/SquidStd.Caching.Redis/README.md +++ b/src/SquidStd.Caching.Redis/README.md @@ -39,4 +39,4 @@ var user = await cache.GetAsync("user:1"); ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Caching/README.md b/src/SquidStd.Caching/README.md index fa3ece9b..228d759e 100644 --- a/src/SquidStd.Caching/README.md +++ b/src/SquidStd.Caching/README.md @@ -1,7 +1,7 @@

SquidStd.Caching

In-memory backend for SquidStd.Caching. Provides an `IMemoryCache`-backed `ICacheProvider` with -absolute TTL and eviction, wired to the shared typed `ICacheService` facade — registered with a +absolute TTL and eviction, wired to the shared typed `ICacheService` facade - registered with a single `AddInMemoryCache()` call. Ideal for single-process apps, tests, and local dev. ## Install @@ -38,4 +38,4 @@ var user = await cache.GetAsync("user:1"); ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Core/README.md b/src/SquidStd.Core/README.md index 0a16950c..563b1f85 100644 --- a/src/SquidStd.Core/README.md +++ b/src/SquidStd.Core/README.md @@ -1,8 +1,8 @@

SquidStd.Core

Foundational contracts and utilities for the SquidStd stack. It defines the core service interfaces -(configuration, event bus, jobs, timing, metrics, storage) and ships dependency-free helpers — YAML/JSON -serialization, a Serilog event sink, and string/environment/directory extensions — that the other +(configuration, event bus, jobs, timing, metrics, storage) and ships dependency-free helpers - YAML/JSON +serialization, a Serilog event sink, and string/environment/directory extensions - that the other SquidStd packages build on. ## Install @@ -68,4 +68,4 @@ pool.Return(builder); ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Crypto/README.md b/src/SquidStd.Crypto/README.md index 7d0afedf..22f34c84 100644 --- a/src/SquidStd.Crypto/README.md +++ b/src/SquidStd.Crypto/README.md @@ -37,7 +37,7 @@ keyring.Import(bobPublicArmored); // a correspondent's public key string armored = await pgp.EncryptForAsync("bob@example.com", payloadBytes); byte[] plaintext = await pgp.DecryptAsync(armoredFromBob, "passphrase"); -// Sign and verify (signed message — the data is embedded in the armored block). +// Sign and verify (signed message - the data is embedded in the armored block). string signed = await pgp.SignAsync(payloadBytes, "alice@example.com", "passphrase"); var verification = await pgp.VerifyAsync(signed); // verification.IsValid, verification.Data @@ -52,7 +52,7 @@ await keyring.LoadAsync(container.Resolve()); ## Password-based encryption -`PasswordCipher` encrypts a payload under a password — Argon2id derives the key, AES-256-GCM seals the data, +`PasswordCipher` encrypts a payload under a password - Argon2id derives the key, AES-256-GCM seals the data, and the result is a self-describing, versioned envelope (salt, nonce, tag and KDF cost are embedded, so decryption needs only the password and the blob). @@ -89,14 +89,14 @@ encryption use `CryptoUtils` / `ISecretProtector` instead. ## Key stores -- **`FilePgpKeyStore(directory)`** — one armored `.asc` per key (public, plus secret when held). gpg-interoperable. -- **`AesGcmPgpKeyStore(ISecretProtector, path)`** — the whole keyring serialized to a single file, encrypted at +- **`FilePgpKeyStore(directory)`** - one armored `.asc` per key (public, plus secret when held). gpg-interoperable. +- **`AesGcmPgpKeyStore(ISecretProtector, path)`** - the whole keyring serialized to a single file, encrypted at rest with the application key via `SquidStd`'s `ISecretProtector`. ## Notes - **Signatures are signed messages**, not detached signatures: `SignAsync` embeds the data in the armored block - and `VerifyAsync` recovers it. Verification is **pass/fail** — PgpCore does not expose the signer's key id or + and `VerifyAsync` recovers it. Verification is **pass/fail** - PgpCore does not expose the signer's key id or identity, so the results carry no signer attribution. - `DecryptAndVerifyAsync` never throws on a bad/absent signature when the ciphertext itself is valid: it always recovers `Data` and reports `IsSigned` / `IsValid`. @@ -154,4 +154,4 @@ var folderVault = new CryptoFileSystem(new PhysicalFileSystem("/secure/dir")); ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Database.Abstractions/README.md b/src/SquidStd.Database.Abstractions/README.md index bf5a5ca6..94398504 100644 --- a/src/SquidStd.Database.Abstractions/README.md +++ b/src/SquidStd.Database.Abstractions/README.md @@ -1,8 +1,8 @@

SquidStd.Database.Abstractions

Provider-agnostic data-access contracts for SquidStd. Entities derive from `BaseEntity` (a `Guid` id -plus UTC timestamps) and are accessed through the generic `IDataAccess` — full CRUD, bulk -operations, paging, and composable queries — without binding to any specific ORM. +plus UTC timestamps) and are accessed through the generic `IDataAccess` - full CRUD, bulk +operations, paging, and composable queries - without binding to any specific ORM. ## Install @@ -45,4 +45,4 @@ public async Task ExampleAsync(IDataAccess users) ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Database/README.md b/src/SquidStd.Database/README.md index 243d0af7..ed8aa31f 100644 --- a/src/SquidStd.Database/README.md +++ b/src/SquidStd.Database/README.md @@ -43,4 +43,4 @@ var page = await users.GetPagedAsync(page: 1, pageSize: 20, orderBy: u => u.Name ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Generators/README.md b/src/SquidStd.Generators/README.md index 4cf86aa9..9ee21193 100644 --- a/src/SquidStd.Generators/README.md +++ b/src/SquidStd.Generators/README.md @@ -51,4 +51,4 @@ Tutorial: [Source generators: registration](https://tgiachi.github.io/squid-std/ ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Mail.Abstractions/README.md b/src/SquidStd.Mail.Abstractions/README.md index 54f7867f..5e147a25 100644 --- a/src/SquidStd.Mail.Abstractions/README.md +++ b/src/SquidStd.Mail.Abstractions/README.md @@ -28,4 +28,4 @@ dotnet add package SquidStd.Mail.Abstractions ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Mail.MailKit/README.md b/src/SquidStd.Mail.MailKit/README.md index 0117e9bf..df89b18f 100644 --- a/src/SquidStd.Mail.MailKit/README.md +++ b/src/SquidStd.Mail.MailKit/README.md @@ -78,4 +78,4 @@ await sender.SendAsync(new OutgoingMailMessage ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Mail.Queue/README.md b/src/SquidStd.Mail.Queue/README.md index 889953dc..02ab3d4c 100644 --- a/src/SquidStd.Mail.Queue/README.md +++ b/src/SquidStd.Mail.Queue/README.md @@ -51,4 +51,4 @@ Retry/backoff/dead-letter are configured via `MessagingOptions` (`MaxDeliveryAtt ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Messaging.Abstractions/README.md b/src/SquidStd.Messaging.Abstractions/README.md index 67656222..978d71af 100644 --- a/src/SquidStd.Messaging.Abstractions/README.md +++ b/src/SquidStd.Messaging.Abstractions/README.md @@ -45,4 +45,4 @@ public async Task PublishAsync(IMessageQueue queue) ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Messaging.RabbitMq/README.md b/src/SquidStd.Messaging.RabbitMq/README.md index 5617a9cd..5261cf84 100644 --- a/src/SquidStd.Messaging.RabbitMq/README.md +++ b/src/SquidStd.Messaging.RabbitMq/README.md @@ -38,4 +38,4 @@ await queue.PublishAsync("orders", new { Id = 1 }); ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Messaging.Sqs/README.md b/src/SquidStd.Messaging.Sqs/README.md index 36db5ae0..28627cef 100644 --- a/src/SquidStd.Messaging.Sqs/README.md +++ b/src/SquidStd.Messaging.Sqs/README.md @@ -45,4 +45,4 @@ container.AddSqsMessaging(new SqsOptions { Aws = new AwsConfigEntry { Region = " ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Messaging/README.md b/src/SquidStd.Messaging/README.md index 98a37407..e723e090 100644 --- a/src/SquidStd.Messaging/README.md +++ b/src/SquidStd.Messaging/README.md @@ -1,7 +1,7 @@

SquidStd.Messaging

In-memory transport for SquidStd.Messaging. Provides a channel-backed `IQueueProvider` with per-queue -buffering, round-robin delivery to subscribers, retry/dead-letter handling, and metrics — registered +buffering, round-robin delivery to subscribers, retry/dead-letter handling, and metrics - registered with a single `AddInMemoryMessaging()` call. Ideal for single-process apps, tests, and local dev. ## Install @@ -37,4 +37,4 @@ await queue.PublishAsync("orders", new { Id = 1 }); ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Network/README.md b/src/SquidStd.Network/README.md index a8315ecc..a1412cea 100644 --- a/src/SquidStd.Network/README.md +++ b/src/SquidStd.Network/README.md @@ -1,7 +1,7 @@

SquidStd.Network

Networking primitives for SquidStd: TCP and UDP servers and clients with per-connection sessions, a -pluggable framing + middleware pipeline, span-based binary readers/writers, and a circular buffer — +pluggable framing + middleware pipeline, span-based binary readers/writers, and a circular buffer - designed for low-allocation, high-throughput byte processing. ## Install @@ -39,4 +39,4 @@ await server.StopAsync(CancellationToken.None); ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Persistence.Abstractions/README.md b/src/SquidStd.Persistence.Abstractions/README.md index 9cef6e0f..d41864aa 100644 --- a/src/SquidStd.Persistence.Abstractions/README.md +++ b/src/SquidStd.Persistence.Abstractions/README.md @@ -25,4 +25,4 @@ dotnet add package SquidStd.Persistence.Abstractions ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Persistence.MessagePack/README.md b/src/SquidStd.Persistence.MessagePack/README.md index 16eff37d..3880edfe 100644 --- a/src/SquidStd.Persistence.MessagePack/README.md +++ b/src/SquidStd.Persistence.MessagePack/README.md @@ -35,4 +35,4 @@ container.RegisterInstance(new MessagePackDataSerializer()); ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Persistence/README.md b/src/SquidStd.Persistence/README.md index 6700d011..da1130dd 100644 --- a/src/SquidStd.Persistence/README.md +++ b/src/SquidStd.Persistence/README.md @@ -69,7 +69,7 @@ container.ApplyPersistedEntityRegistrations(); // builds descriptors into IPer ### Durability `PersistenceConfig.DurabilityMode` selects how writes reach disk. `Buffered` (default) flushes to the OS -cache — fast, and safe across a process crash. `Durable` fsyncs each journal append and the snapshot temp +cache - fast, and safe across a process crash. `Durable` fsyncs each journal append and the snapshot temp file before its atomic rename, so committed data survives power loss. Pass it through when constructing the services: `new BinaryJournalService(path, config.DurabilityMode)` and `new SnapshotService(dir, suffix, config.DurabilityMode)`. (.NET has no portable directory fsync, so the @@ -81,4 +81,4 @@ guarantee is per-file content durability plus atomic rename.) ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Plugin.Abstractions/README.md b/src/SquidStd.Plugin.Abstractions/README.md index e10fc291..4506a924 100644 --- a/src/SquidStd.Plugin.Abstractions/README.md +++ b/src/SquidStd.Plugin.Abstractions/README.md @@ -48,4 +48,4 @@ public sealed class MyPlugin : ISquidStdPlugin ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Scripting.Lua/README.md b/src/SquidStd.Scripting.Lua/README.md index 5d41802f..db106846 100644 --- a/src/SquidStd.Scripting.Lua/README.md +++ b/src/SquidStd.Scripting.Lua/README.md @@ -49,4 +49,4 @@ container.RegisterGeneratedScriptModules(); ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Search.Abstractions/README.md b/src/SquidStd.Search.Abstractions/README.md index 031b4f70..8f886389 100644 --- a/src/SquidStd.Search.Abstractions/README.md +++ b/src/SquidStd.Search.Abstractions/README.md @@ -24,4 +24,4 @@ dotnet add package SquidStd.Search.Abstractions ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Search.Elasticsearch/README.md b/src/SquidStd.Search.Elasticsearch/README.md index e1c668f1..26d2b521 100644 --- a/src/SquidStd.Search.Elasticsearch/README.md +++ b/src/SquidStd.Search.Elasticsearch/README.md @@ -33,7 +33,7 @@ var open = await search.Query() Supported LINQ: `Where` (`==`, `!=`, `<`, `>`, `<=`, `>=`, `&&`, `||`, `!`, `string.Contains`/`StartsWith`, bool members), `OrderBy`/`ThenBy`(`Descending`), `Skip`/`Take`, and `.Match(field, text)` / `.FullText(text)`. -Anything else throws `NotSupportedException` — drop down to the native `ElasticsearchClient`. +Anything else throws `NotSupportedException` - drop down to the native `ElasticsearchClient`. ## Key types @@ -50,4 +50,4 @@ Anything else throws `NotSupportedException` — drop down to the native `Elasti ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Secrets.Aws/README.md b/src/SquidStd.Secrets.Aws/README.md index 81544369..bc526c00 100644 --- a/src/SquidStd.Secrets.Aws/README.md +++ b/src/SquidStd.Secrets.Aws/README.md @@ -55,17 +55,17 @@ await foreach (var name in store.ListNamesAsync("db/")) { /* ... */ } ## Notes -- **Envelope encryption** — `KmsSecretProtector` calls `GenerateDataKey` per `Protect`, encrypts the payload +- **Envelope encryption** - `KmsSecretProtector` calls `GenerateDataKey` per `Protect`, encrypts the payload locally with AES-256-GCM, and frames the KMS-wrapped data key alongside the ciphertext. The plaintext data key is zeroed immediately after use; `Unprotect` calls `Decrypt` to unwrap it. KMS never sees the payload, and large payloads are not bound by the 4 KB KMS direct-encrypt limit. -- **NamePrefix** — `AwsSecretsManagerStore` prepends `NamePrefix` to every secret id, giving each +- **NamePrefix** - `AwsSecretsManagerStore` prepends `NamePrefix` to every secret id, giving each application its own namespace inside a shared account. `ListNamesAsync` strips the prefix so callers always see logical names. `Delete` returns `false` for a missing secret. -- **Credentials** — when `Aws.AccessKey` / `Aws.SecretKey` are omitted, the AWS SDK default credential +- **Credentials** - when `Aws.AccessKey` / `Aws.SecretKey` are omitted, the AWS SDK default credential chain is used (environment, shared profile, EC2/ECS role). Set `Aws.ServiceUrl` to target LocalStack or another compatible endpoint. -- **Tested against LocalStack** — the KMS and Secrets Manager adapters are covered by integration tests +- **Tested against LocalStack** - the KMS and Secrets Manager adapters are covered by integration tests running on a `localstack/localstack` container. ## Related @@ -74,4 +74,4 @@ await foreach (var name in store.ListNamesAsync("db/")) { /* ... */ } ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Services.Core/README.md b/src/SquidStd.Services.Core/README.md index b2fe0f75..25814a96 100644 --- a/src/SquidStd.Services.Core/README.md +++ b/src/SquidStd.Services.Core/README.md @@ -69,4 +69,4 @@ await seeded.DispatchAsync(command, connection); // factory maps connection -> ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Storage.Abstractions/README.md b/src/SquidStd.Storage.Abstractions/README.md index fbd6e858..859eb619 100644 --- a/src/SquidStd.Storage.Abstractions/README.md +++ b/src/SquidStd.Storage.Abstractions/README.md @@ -39,4 +39,4 @@ public async Task DumpKeysAsync(IStorageService storage) ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Storage.S3/README.md b/src/SquidStd.Storage.S3/README.md index ab43cd5b..50680a79 100644 --- a/src/SquidStd.Storage.S3/README.md +++ b/src/SquidStd.Storage.S3/README.md @@ -47,4 +47,4 @@ await storage.SaveAsync("reports/2026.json", "{}"u8.ToArray()); ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Storage/README.md b/src/SquidStd.Storage/README.md index a16f0537..8002c70e 100644 --- a/src/SquidStd.Storage/README.md +++ b/src/SquidStd.Storage/README.md @@ -1,7 +1,7 @@

SquidStd.Storage

Local file storage for SquidStd. Provides a filesystem-backed `IStorageService` (atomic writes, path-safe -keys) and a YAML-backed `IObjectStorageService` that layers typed objects on top of it — registered with a +keys) and a YAML-backed `IObjectStorageService` that layers typed objects on top of it - registered with a single `AddFileStorage()` call. Storage is opt-in: it is not registered by `RegisterCoreServices`. ## Install @@ -42,4 +42,4 @@ enumerates stored keys (`/`-separated), excluding in-flight temp files. ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Telemetry.Abstractions/README.md b/src/SquidStd.Telemetry.Abstractions/README.md index b475f626..c4f09eb8 100644 --- a/src/SquidStd.Telemetry.Abstractions/README.md +++ b/src/SquidStd.Telemetry.Abstractions/README.md @@ -33,4 +33,4 @@ captures every `SquidStd.*` source automatically. ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Telemetry.OpenTelemetry/README.md b/src/SquidStd.Telemetry.OpenTelemetry/README.md index 1927c527..6f04c935 100644 --- a/src/SquidStd.Telemetry.OpenTelemetry/README.md +++ b/src/SquidStd.Telemetry.OpenTelemetry/README.md @@ -2,7 +2,7 @@ OpenTelemetry tracing and metrics export for SquidStd. Adds distributed tracing (ASP.NET Core + HttpClient + the `SquidStd.*` ActivitySource), runtime metrics, and a bridge that exports the existing -SquidStd metrics snapshot — all via OTLP (+ optional console). Logs stay on Serilog. +SquidStd metrics snapshot - all via OTLP (+ optional console). Logs stay on Serilog. ## Install @@ -47,4 +47,4 @@ builder.Services.AddSquidStdTelemetry(new TelemetryOptions { ServiceName = "orde ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Templates/README.md b/src/SquidStd.Templates/README.md index 07904d96..d7cecd71 100644 --- a/src/SquidStd.Templates/README.md +++ b/src/SquidStd.Templates/README.md @@ -34,4 +34,4 @@ dotnet new squidstd-manager -n Acme.Manager ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Templating/README.md b/src/SquidStd.Templating/README.md index 0955e1d8..fe69c91b 100644 --- a/src/SquidStd.Templating/README.md +++ b/src/SquidStd.Templating/README.md @@ -46,4 +46,4 @@ var welcome = await renderer.RenderByNameAsync("welcome", new { User = new { Nam ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Tui/README.md b/src/SquidStd.Tui/README.md index e3cdb69e..32d95a0f 100644 --- a/src/SquidStd.Tui/README.md +++ b/src/SquidStd.Tui/README.md @@ -52,7 +52,7 @@ await container.Resolve().RunAsync(); Instead of imperative `BuildLayout` + `Bind`, derive from `TuiComposedView` and return a node tree from `Compose()`. One node = widget + binding; direction is inferred (Label one-way, TextField -two-way, Button command) and bindings are typed lambdas — no magic strings. +two-way, Button command) and bindings are typed lambdas - no magic strings. ```csharp public sealed class CounterView : TuiComposedView @@ -81,4 +81,4 @@ public sealed class CounterView : TuiComposedView ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Vfs.Abstractions/README.md b/src/SquidStd.Vfs.Abstractions/README.md index fa75b934..46a5acb7 100644 --- a/src/SquidStd.Vfs.Abstractions/README.md +++ b/src/SquidStd.Vfs.Abstractions/README.md @@ -24,4 +24,4 @@ dotnet add package SquidStd.Vfs.Abstractions ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Vfs.Database/README.md b/src/SquidStd.Vfs.Database/README.md index d50e938c..063f9fa3 100644 --- a/src/SquidStd.Vfs.Database/README.md +++ b/src/SquidStd.Vfs.Database/README.md @@ -33,7 +33,7 @@ await foreach (var entry in fs.ListAsync("config")) The `VfsFileEntity` table is created automatically by FreeSql on first access (sync-structure mode). -> **Single-writer assumption** — upsert operations are not serialised across concurrent writers. Use this +> **Single-writer assumption** - upsert operations are not serialised across concurrent writers. Use this > backend in single-process scenarios or where last-write-wins is acceptable. ## Key types @@ -47,9 +47,9 @@ The `VfsFileEntity` table is created automatically by FreeSql on first access (s ## Related - Tutorial: [Virtual filesystem](https://tgiachi.github.io/squid-std/tutorials/vfs.html) -- [`SquidStd.Vfs`](../SquidStd.Vfs/README.md) — core backends and decorators -- [`SquidStd.Database`](../SquidStd.Database/README.md) — required database module +- [`SquidStd.Vfs`](../SquidStd.Vfs/README.md) - core backends and decorators +- [`SquidStd.Database`](../SquidStd.Database/README.md) - required database module ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Vfs.S3/README.md b/src/SquidStd.Vfs.S3/README.md index 85ac32cf..405a9cfb 100644 --- a/src/SquidStd.Vfs.S3/README.md +++ b/src/SquidStd.Vfs.S3/README.md @@ -1,6 +1,6 @@

SquidStd.Vfs.S3

-An `IVirtualFileSystem` over S3-compatible object storage — AWS S3, MinIO, Cloudflare R2, Backblaze B2 — via +An `IVirtualFileSystem` over S3-compatible object storage - AWS S3, MinIO, Cloudflare R2, Backblaze B2 - via the MinIO .NET SDK. Each logical path maps directly to an object key inside a single bucket. The bucket is created lazily on first use. @@ -48,8 +48,8 @@ For native AWS with the default credential chain, omit `AccessKey`/`SecretKey` a ## Related - Tutorial: [Virtual filesystem](https://tgiachi.github.io/squid-std/tutorials/vfs.html) -- [`SquidStd.Vfs`](../SquidStd.Vfs/README.md) — core backends and decorators +- [`SquidStd.Vfs`](../SquidStd.Vfs/README.md) - core backends and decorators ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Vfs/README.md b/src/SquidStd.Vfs/README.md index 02089b5a..c06994a4 100644 --- a/src/SquidStd.Vfs/README.md +++ b/src/SquidStd.Vfs/README.md @@ -1,7 +1,7 @@

SquidStd.Vfs

A path-based virtual filesystem abstraction for SquidStd with interchangeable backends. One interface -(`IVirtualFileSystem`) is implemented by real directories, a single zip archive, and an in-memory store — and +(`IVirtualFileSystem`) is implemented by real directories, a single zip archive, and an in-memory store - and decorated by an encrypted vault in `SquidStd.Crypto`. `VfsDirectories` is a VFS-backed analogue of `DirectoriesConfig`, so named directory layouts work over any backend (a zip or an encrypted container can stand in for real folders). @@ -71,7 +71,7 @@ Decorators wrap any `IVirtualFileSystem` to add behaviour without touching the b | `OverlayFileSystem(base, overlay)` | Reads overlay-first then falls back to base. Writes and deletes go to the overlay only. List returns the union of both; overlay entries shadow base entries with the same path. | | `CachingFileSystem(remote, cache)` | Read-through cache: reads prefer the remote and refresh the cache copy on success; on a transport failure they fall back to the (possibly stale) cache. Writes are write-through (remote then cache) and fail when the remote is unreachable. | -Composition example — S3 with a local disk cache for resilience to an unstable connection: +Composition example - S3 with a local disk cache for resilience to an unstable connection: ```csharp // S3 with a local disk cache for resilience to an unstable connection. @@ -92,4 +92,4 @@ container.RegisterVfs(_ => new ReadOnlyFileSystem(new PhysicalFileSystem("/var/l ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Workers.Abstractions/README.md b/src/SquidStd.Workers.Abstractions/README.md index 7138606e..a5f3c00c 100644 --- a/src/SquidStd.Workers.Abstractions/README.md +++ b/src/SquidStd.Workers.Abstractions/README.md @@ -25,4 +25,4 @@ dotnet add package SquidStd.Workers.Abstractions ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Workers.Manager/README.md b/src/SquidStd.Workers.Manager/README.md index 7a164562..44b6dba2 100644 --- a/src/SquidStd.Workers.Manager/README.md +++ b/src/SquidStd.Workers.Manager/README.md @@ -40,4 +40,4 @@ app.MapWorkerManagerEndpoints(); // GET /workers, GET /workers/{id}, POST /jobs ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std). diff --git a/src/SquidStd.Workers/README.md b/src/SquidStd.Workers/README.md index 0f7dc948..f750bf3b 100644 --- a/src/SquidStd.Workers/README.md +++ b/src/SquidStd.Workers/README.md @@ -52,4 +52,4 @@ public sealed class ResizeImageHandler : IJobHandler ## License -MIT — part of [SquidStd](https://github.com/tgiachi/squid-std). +MIT - part of [SquidStd](https://github.com/tgiachi/squid-std).