studio status report: 2024-03
month 03 of 2024 was about Songhay.Player.YouTube
release 6.3.1 ๐ฆ๐
As of this writing, there is only one task left on the Songhay.Player.YouTube
project for release 6.3.1. This places the Studio very, very close to replacing the Angular app in http://kintespace.com/player.html
with a Bolero appโthis ridiculously difficult struggle to move beyond the SEO-nightmare world of Angular.
My Obsidian โsecond brainโ is really helping this Studio to function and move forward:
Selected notes from month 03:
[[xUnit.net]]: TheoryData<T>
has been thereโฆ
From โTypesafety in xUnit with TheoryData<T>
โ:
TheoryData<T>
is a class that allows to wrap the data in a strongly typed way. Here is how I used it:
public static TheoryData<Action<IServiceCollection>>Data =>new()
{
services =>services.UseSqliteAsStorageProvider(),
services =>services.UseSqlAsStorageProvider(),
services =>services.UseInMemoryAsStorageProvider(),
services =>services.UseRavenDbAsStorageProvider(),
services =>services.UseMySqlAsStorageProvider()
};
[Theory]
[MemberData(nameof(Data))]
public void GivenAlreadyRegisteredRepository_WhenTryingToAddAnotherStorage_ThenException(Action<IServiceCollection>act)
[!important] What the article does not mention ๐ถโ is that
TheoryData<T>
works best when one strongly type argument is being passed into the test method (as shown in the code sample above)โnot multiple args.
โThe โmissingโ graph datatype already exists. It was invented in the โ70sโ
I claim the reason why it is so difficult to support graphs in languages nowadays is because the imperative/structured programming model of modern programming languages is ill-suited for graph algorithms. As Wayne correctly points out, the core problem is that when you write a graph algorithm in an imperative language like Python or Rust, you have to choose some explicit representation for the graph. Then, your traversal algorithm is dependent on the representation you chose. If you find out later that your representation is no longer efficient, it is a lot of work to adapt your algorithms for a new representation.
[[SQLite]]: yes, the interactive docs are using [[WebAssembly]]
Under the hood, we leverage WebAssembly (WASM) technology to execute SQLite statements directly in the browser, providing a seamless and responsive experience. Additionally, we have preloaded a sample database, ensuring users have a rich dataset to work with from the moment they access the console.
โโInteractive SQLite Documentation: Experiment with Queries in Real-Time!โ
[[eleventy]]: the most important help document
โI Finally Understand Eleventyโs Data Cascadeโ by Ben Myers is today regarded as the most important [[eleventy]] document:
When Eleventy generates the pages of your site, it aggregates data supplied from several places and then injects that data into your contents. The process of aggregating this data from each of these different places and deciding which data should have precedence in the case of a conflict is what Eleventy calls the data cascade.
According to Ben Myers (in 2021), here is the [[eleventy]] data cascade [๐ docs ]:
- global data [๐ docs ]
- config global data [๐ docs ]
- layout frontmatter [๐ docs ]
- directory data files and template data files [๐ docs ]
- template frontmatter [๐ docs ]
- computed data [๐ docs ]
[[eleventy]]: โIntroduction to WebCโ #to-do
WebC is a new tool by Zach Leatherman (creator of Eleventy) for serializing custom elements at build time. It aggregates component-level CSS and JavaScript, allowing developers to keep their styles and scripts together with the markup as single file components, the way you may be used to if you work with JavaScript frameworks such as Svelte or Vue.
All without having to ship a single line of JavaScript to the client โ unless you want it to.
[[ASP.NET]]: FSharp.AspNetCore.WebAppBuilder
The
webApp
computation expression lets you define ASP.NET Core web applications in a succinct and declarative way, minimizing code, maximizing readability, and providing a simple but thorough set of escape hatches, so you can always drop down to the raw ASP.NET Core APIs when you need to.โhttps://github.com/brianrourkeboll/FSharp.AspNetCore.WebAppBuilder/
[[Obsidian]]: โJSON Canvas was originally created for Obsidian.โ
![[Pasted image 20240311115241.png]]
Infinite canvas tools are a way to view and organize information spatially, like a digital whiteboard. Infinite canvases encourage freedom and exploration, and have become a popular interface pattern across many apps.
The JSON Canvas format was created to provide longevity, readability, interoperability, and extensibility to data created with infinite canvas apps. The format is designed to be easy to parse and give users ownership over their data. JSON Canvas files use the
.canvas
extension.JSON Canvas was originally created for Obsidian. JSON Canvas can be implemented freely as an import, export, and storage format for any app or tool. This site, and all the resources associated with JSON Canvas are open source under the MIT license.
โShould AVIF be the dominant image format on the web?โ
Looks like highest fidelity but not so great file size:
Letโs find out how similar AVIF, JPEG, and WebP are to their original. When we compare them using full-reference image quality assessment algorithms like mean squared error, peak signal-to-noise ratio, and the structural similarity index, we see that AVIF outperforms both JPEG and WebP starting at a quality setting between 30-40%. Also, note that WebP performs slightly better than JPEG.
โTim Severien
โWeโre Bringing Responsive Video Back!โ
So along with that article, I outlined some of the points above in an explainer document, which included some markup examples that should feel familiar to folks who have used the
picture
element, like this:
<video>
<source media="(min-width: 2000px)" src="large.webm" type="video/webm">
<source media="(min-width: 2000px)" src="large.mp4" type="video/mp4">
<source media="(min-width: 1000px)" src="medium.webm" type="video/webm">
<source media="(min-width: 1000px)" src="medium.mp4" type="video/mp4">
<source src="small.webm" type="video/webm">
<source src="small.mp4" type="video/mp4">
</video>
But then, this spring the WhatWG issue thread lit up with some good news: representatives from Firefox and Chrome chimed in to say that they agreed and intend to reinstate their support! Following that, implementation bugs were filed in the Chromium and Firefox trackers.
Python-Markdown looks the the reference implementation for [[markdown]]
This is a Python implementation of John Gruber's Markdown. It is almost completely compliant with the reference implementation, though there are a few known issues. See Features for information on what exactly is supported and what is not. Additional features are supported by the Available Extensions.
[[Azure]]: dotnet user-secrets
, [[PowerShell]], Microsoft.Extensions.Configuration
and [[Bicep]] all mixed together by Frank Boucher
In โGenerate Local .NET Secrets from Azure Deploymentsโ Frank Boucher basically dumps a bunch of stuff on the readerโin part because there is video that might explain further:
What I do notice so far are the following:
- the
dotnet user-secrets
command is installed by default but not documented - today, I assume that the
dotnet user-secrets
system does not scale beyond the development environment (not seamlessly related to [[Azure Key Vault]]) - Bicep is locked into [[Azure]] while [[Terraform]] knowledge is portable
[[Obsidian]]: โ๐ง Peek Inside my Personal Obsidian Vault: Dann Berg's Complete 2024 Tourโ
Notable plugins shown in the video [๐น watch ]:
- Obsidian Better Command Palette
- Imgur
- JS Engine
- Longform
- Obsidian Meta Bind Plugin (the recommendation over the Buttons plugin)
- Obsidian Query Language
- Note Refactor
- Tag Wrangler
- Templater
Gรฉrald Barrรฉ letโs me know about a serious limitation of Swashbuckle.AspNetCore
โฆ
Most .NET developers generate the specification from the code. The
Swashbuckle.AspNetCore
library is a popular choice to generate the OpenAPI specification from ASP.NET Core Web API projects. You can easily add a page to access the specification. However, it's hard to validate the content of the specification to ensure the specification is usable by the consumers. One way to improve that is to make the specification part of your code, so you can review the specification during code reviews.Microsoft provides the NuGet package
Microsoft.Extensions.ApiDescription.Server
that allows you to generate the OpenAPI specification from the code while building the project.โโGenerate OpenAPI specification at build time from the code in ASP.NET Coreโ
Background from the docs:
The Swagger project was donated to the OpenAPI Initiative in 2015 and has since been referred to as OpenAPI. Both names are used interchangeably. However, "OpenAPI" refers to the specification. "Swagger" refers to the family of open-source and commercial products from SmartBear that work with the OpenAPI Specification. Subsequent open-source products, such as OpenAPIGenerator, also fall under the Swagger family name, despite not being released by SmartBear.
In short:
- OpenAPI is a specification.
- Swagger is tooling that uses the OpenAPI specification. For example, OpenAPIGenerator and SwaggerUI.
โโOpenAPI vs. Swaggerโ
I think I need to take action based on โ.NET OpenAPI tool command reference and installation.โ
yes, modern [[Blazor]] needs the ::deep
pseudo selector just like those used in [[Angular]]
The
::deep
pseudo-selector will allow you to target child HTML elements nested within a parent component.
[[ASP.NET]]: the Problem Details standard #to-do
The following video introduces the Problem Details standard (RFC7807) to me:
The ProblemDetails
class [๐ docs ] is the ancestor of the ValidationProblemDetails
class [๐ docs ].
Will I find the developer exception page useful?
related reading
- โHandle errors in ASP.NET Coreโ
- โHandle errors in ASP.NET Core web APIsโ
- โHandling Web API Exceptions with ProblemDetails middlewareโ (2020)
- โBest way to implement the ProblemDetails in Asp.Net Core API in clean way โ
[[Redis]] is walking slowly away from Open Source license
Beginning today, all future versions of Redis will be released with source-available licenses. Starting with Redis 7.4, Redis will be dual-licensed under the Redis Source Available License (RSALv2) and Server Side Public License (SSPLv1). Consequently, Redis will no longer be distributed under the three-clause Berkeley Software Distribution (BSD).
[[Bulma]] is version 1.0
Bulma v1 is a full rewrite of the framework using Dart Sass, which is the the primary implementation of Sass. While this affects a few development details, everything has been done to make the transition as easy as possible.
What remains the same
All HTML snippets are the same. This means you don't need to update your markup. This is important because it means, if you're using Bulma straight "out of the box", you don't need to change anything.
You can just swap
bulma@0.9.4/css/bulma.min.css
withbulma@1.0.0/css/bulma.min.css
and everything will work. Things will look slightly different, but they will still work.
[[Obsidian]]: more community plugins #to-do
The following leaves me with two community-plugin picks:
[[ASP.NET]]: [[Microsoft]] Defender for APIs?
Defender for APIsย offers full lifecycle protection, detection, and response coverage for APIs. Defender for APIs helps you to gain visibility into business-critical APIs. You can investigate and improve your API security posture, prioritize vulnerability fixes, and quickly detect active real-time threats.
โโProtect Against OWASP API Top 10 Security Risks Using Defender for APIsโ
[[ASP.NET]]: my introduction to WebAuthn
WebAuthn is a relatively new standard for authenticating users and is an incredibly secure way to authenticate users by being phishing resistant, and not requiring passwords at all. It accomplishes this via public-key cryptography. To read more about it, check out Wikipedia. โฆ We will be utilizing Bitwarden's Passwordless service as our passkey platform.
โKai Ito
related reading
- โBicep vs. Terraform: Which Should You Choose?โ
- โWhat is Bicep?โ
- โSecuring Sensitive Information with .NET User Secretsโ
- โSafe storage of app secrets in development in ASP.NET Coreโ
[[dotnet|.NET]]: sorting IReadOnlyCollection<T>
, IReadOnlyList<T>
and IEnumerable<T>
In the context of [[Entity Framework]], output of IEnumerable<T>
implies that .ToArray()
or .ToList()
has not been called in some LINQ-to-SQLcontext which means all members of the collection have not been loaded into memory:
IEnumerable<T>
is a good fit for many scenarios, but do consider thatIReadOnlyCollection<T>
might be a better fit in circumstances where the collection is always going to be fully available in memory. Avoid passing round mutable collection types as this can cause confusion about who owns the collection.โโWhat types should I use to pass collections in C#?โ (2019)
The term lazy evaluation in our [[Entity Framework]] scenario makes sense here:
โฆan
IReadOnlyCollection<T>
signals to the caller that there will be no lazy evaluation. (TheCount
property, as opposed to theCount
extension method ofIEnumerable<T>
(which is inherited byIReadOnlyCollection<T>
so it has the method as well), signals non-lazyness. And so does the fact that there seem to be no lazy implementations ofIReadOnlyCollection
.)
When the following refers to โindexer supportโ it pointing out that the IReadOnlyList<T>.Item[Int32]
property [๐ docs ] has no equivalent in IReadOnlyCollection<T>
[๐ docs ]:
I would say, if you return an object that is a
List<T>
orT[]
, you may want to expose it as at leastIReadOnlyCollection<T>
or betterIReadOnlyList<T>
which has indexer support. The advantages of doing this is:
- A call to
ToList
is not required to do multiple enumerations of the same output.- The boundaries are clearly defined
- Using an
IReadOnlyList<T>
, you could enumerate with afor
loop as opposed toforeach
, which might be advantageous in some corner cases.The main disadvantage I see of this, which could be a big one depending on the implementation:
- Your API will no longer be able to return an
IEnumerable<T>
in a streaming fashion (e.g. reading from aStream
orIDbDataReader
, etc). This would mean introducing a breaking change in your code.
[[Blazor]]: โWhat Is a Blazor Layout?โ
When a [[Blazor]] page inherits from LayoutComponentBase
it becomes a layout page:
It uses the
@inherits
directive to specify that it inherits from theLayoutComponentBase
type. It is what makes a regular Blazor component a layout component.
Cโฏ 12 Collection Expressions cannot use var
// Pre C# 12
var array = new[] { 1, 2 };
var spread = array.Concat(new[] { 3, 4 });
// Post C# 12
int[] array = [1, 2];
int[] spread = [..array, 3, 4];
Since collection literals are target-typed, we cannot use
var
but must declare the type name for our variable.โโCollection Expressions โ Using C# 12 in Rider and ReSharperโ
sketching out development projects
The current, unfinished public projects on GitHub:
-
replacing the Angular app in
http://kintespace.com/player.html
with a Bolero app ๐๐ฅ depends on:- finishing the
Songhay.Player.YouTube
release 6.3.1 ๐ฆ๐ project
- finishing the
-
start the โ
Songhay.Publications.Models
6.0.0โ ๐ฆ๐ project -
completing the
Songhay.Publications
6.1.0 ๐ฆ๐ project
The proposed project items:
- add Entity Framework (over SQLite) features to
Songhay.Publications
- generate Publication indices from SQLite for
Songhay.Publications.KinteSpace
- generate a new repo with proposed name,
Songhay.Modules.Bolero.Index
โจ๐ง and add a GitHub Project - switch Studio from Material Design to Bulma ๐ โก๏ธ ๐โจ