lingo.lol is one of the many independent Mastodon servers you can use to participate in the fediverse.
A place for linguists, philologists, and other lovers of languages.

Server stats:

69
active users

#JavaScript

16 posts15 participants1 post today

New Kitten release

• Fix: messages that are promises are properly awaited before being sent.

kitten.small-web.org

Kitten automatically and transparently handles asynchronous content in your templates for you so you don’t have to worry about it. One place where this wasn’t working properly is if you addressed `this.component` to stream a custom update of your component manually instead of calling the `this.update()` method of Kitten component instances.

e.g.,

```js
export default class AdminPage extends kitten.Page {
// …
onSelectedPost (data) {
this.send(kitten.html`<${this.component} postId='${data.selectedPost.postId}' />`)
}
}
```

:kitten:💕

Ditch the DIY Drama: Why Use Fedify Instead of Building ActivityPub from Scratch?

hackers.pub/@hongminhee/2025/w

Hackers' Pub · Ditch the DIY Drama: Why Use Fedify Instead of Building ActivityPub from Scratch?So, you're captivated by the fediverse—the decentralized social web powered by protocols like ActivityPub. Maybe you're dreaming of building the next great federated app, a unique space connected to Mastodon, Lemmy, Pixelfed, and more. The temptation to dive deep and implement ActivityPub yourself, from the ground up, is strong. Total control, right? Understanding every byte? Sounds cool! But hold on a sec. Before you embark on that epic quest, let's talk reality. Implementing ActivityPub correctly isn't just one task; it's like juggling several complex standards while riding a unicycle… blindfolded. It’s hard. That's where Fedify comes in. It's a TypeScript framework designed to handle the gnarliest parts of ActivityPub development, letting you focus on what makes your app special, not reinventing the federation wheel. This post will break down the common headaches of DIY ActivityPub implementation and show how Fedify acts as the super-powered pain reliever, starting with the very foundation of how data is represented.Challenge #1: Data Modeling—Speaking ActivityStreams & JSON-LD Fluently At its core, ActivityPub relies on the ActivityStreams 2.0 vocabulary to describe actions and objects, and it uses JSON-LD as the syntax to encode this vocabulary. While powerful, this combination introduces significant complexity right from the start. First, understanding and correctly using the vast ActivityStreams vocabulary itself is a hurdle. You need to model everything—posts (Note, Article), profiles (Person, Organization), actions (Create, Follow, Like, Announce)—using the precise terms and properties defined in the specification. Manual JSON construction is tedious and prone to errors. Second, JSON-LD, the encoding layer, has specific rules that make direct JSON manipulation surprisingly tricky:Missing vs. Empty Array: In JSON-LD, a property being absent is often semantically identical to it being present with an empty array. Your application logic needs to treat these cases equally when checking for values. For example, these two Note objects mean the same thing regarding the name property:// No name property{ "@context": "https://www.w3.org/ns/activitystreams", "type": "Note", "content": "…"}// Equivalent to:{ "@context": "https://www.w3.org/ns/activitystreams", "type": "Note", "name": [], "content": "…"}Single Value vs. Array: Similarly, a property holding a single value directly is often equivalent to it holding a single-element array containing that value. Your code must anticipate both representations for the same meaning, like for the content property here:// Single value{ "@context": "https://www.w3.org/ns/activitystreams", "type": "Note", "content": "Hello"}// Equivalent to:{ "@context": "https://www.w3.org/ns/activitystreams", "type": "Note", "content": ["Hello"]}Object Reference vs. Embedded Object: Properties can contain either the full JSON-LD object embedded directly or just a URI string referencing that object. Your application needs to be prepared to fetch the object's data if only a URI is given (a process called dereferencing). These two Announce activities are semantically equivalent (assuming the URIs resolve correctly):{ "@context": "https://www.w3.org/ns/activitystreams", "type": "Announce", // Embedded objects: "actor": { "type": "Person", "id": "http://sally.example.org/", "name": "Sally" }, "object": { "type": "Arrive", "id": "https://sally.example.com/arrive", /* ... */ }}// Equivalent to:{ "@context": "https://www.w3.org/ns/activitystreams", "type": "Announce", // URI references: "actor": "http://sally.example.org/", "object": "https://sally.example.com/arrive"}<Attempting to manually handle all these vocabulary rules and JSON-LD variations consistently across your application inevitably leads to verbose, complex, and fragile code, ripe for subtle bugs that break federation. Fedify tackles this entire data modeling challenge with its comprehensive, type-safe Activity Vocabulary API. It provides TypeScript classes for ActivityStreams types and common extensions, giving you autocompletion and compile-time safety. Crucially, these classes internally manage all the tricky JSON-LD nuances. Fedify's property accessors present a consistent interface—non-functional properties (like tags) always return arrays, functional properties (like content) always return single values or null. It handles object references versus embedded objects seamlessly through dereferencing accessors (like activity.getActor()) which automatically fetch remote objects via URI when needed—a feature known as property hydration. With Fedify, you work with a clean, predictable TypeScript API, letting the framework handle the messy details of AS vocabulary and JSON-LD encoding.Challenge #2: Discovery & Identity—Finding Your Actors Once you can model data, you need to make your actors discoverable. This primarily involves the WebFinger protocol (RFC 7033). You'd need to build a server endpoint at /.well-known/webfinger capable of parsing resource queries (like acct: URIs), validating the requested domain against your server, and responding with a precisely formatted JSON Resource Descriptor (JRD). This JRD must include specific links, like a self link pointing to the actor's ActivityPub ID using the correct media type. Getting any part of this wrong can make your actors invisible. Fedify simplifies this significantly. It automatically handles WebFinger requests based on the actor information you provide through its setActorDispatcher() method. Fedify generates the correct JRD response. If you need more advanced control, like mapping user-facing handles to internal identifiers, you can easily register mapHandle() or mapAlias() callbacks. You focus on defining your actors; Fedify handles making them discoverable.// Example: Define how to find actorsfederation.setActorDispatcher( "/users/{username}", async (ctx, username) => { /* ... */ });// Now GET /.well-known/webfinger?resource=acct:username@your.domain just works!<Challenge #3: Core ActivityPub Mechanics—Handling Requests and Collections Serving actor profiles requires careful content negotiation. A request for an actor's ID needs JSON-LD for machine clients (Accept: application/activity+json) but HTML for browsers (Accept: text/html). Handling incoming activities at the inbox endpoint involves validating POST requests, verifying cryptographic signatures, parsing the payload, preventing duplicates (idempotency), and routing based on activity type. Implementing collections (outbox, followers, etc.) with correct pagination adds another layer. Fedify streamlines all of this. Its core request handler (via Federation.fetch() or framework adapters like @fedify/express) manages content negotiation. You define actors with setActorDispatcher() and web pages with your framework (Hono, Express, SvelteKit, etc.)—Fedify routes appropriately. For the inbox, setInboxListeners() lets you define handlers per activity type (e.g., .on(Follow, ...)), while Fedify automatically handles validation, signature verification, parsing, and idempotency checks using its KV Store. Collection implementation is simplified via dispatchers (e.g., setFollowersDispatcher()); you provide logic to fetch a page of data, and Fedify constructs the correct Collection or CollectionPage with pagination.// Define inbox handlersfederation.setInboxListeners("/inbox", "/users/{handle}/inbox") .on(Follow, async (ctx, follow) => { /* Handle follow */ }) .on(Undo, async (ctx, undo) => { /* Handle undo */ });// Define followers collection logicfederation.setFollowersDispatcher( "/users/{handle}/followers", async (ctx, handle, cursor) => { /* ... */ });<Challenge #4: Reliable Delivery & Asynchronous Processing—Sending Activities Robustly Sending an activity requires more than a simple POST. Networks fail, servers go down. You need robust failure handling and retry logic (ideally with backoff). Processing incoming activities synchronously can block your server. Efficiently broadcasting to many followers (fan-out) requires background processing and using shared inboxes where possible. Fedify addresses reliability and scalability using its MessageQueue abstraction. When configured (highly recommended), Context.sendActivity() enqueues delivery tasks. Background workers handle sending with automatic retries based on configurable policies (like outboxRetryPolicy). Fedify supports various queue backends (Deno KV, Redis, PostgreSQL, AMQP). For high-traffic fan-out, Fedify uses an optimized two-stage mechanism to distribute the load efficiently.// Configure Fedify with a persistent queue (e.g., Deno KV)const federation = createFederation({ queue: new DenoKvMessageQueue(/* ... */), // ...});// Sending is now reliable and non-blockingawait ctx.sendActivity({ handle: "myUser" }, recipient, someActivity);<Challenge #5: Security—Avoiding Common Pitfalls Securing an ActivityPub server is critical. You need to implement HTTP Signatures (draft-cavage-http-signatures-12) for server-to-server authentication—a complex process. You might also need Linked Data Signatures (LDS) or Object Integrity Proofs (OIP) based on FEP-8b32 for data integrity and compatibility. Managing cryptographic keys securely is essential. Lastly, fetching remote resources risks Server-Side Request Forgery (SSRF) if not validated properly. Fedify is designed with security in mind. It automatically handles the creation and verification of HTTP Signatures, LDS, and OIP, provided you supply keys via setKeyPairsDispatcher. It includes key management utilities. Crucially, Fedify's default document loader includes built-in SSRF protection, blocking requests to private IPs unless explicitly allowed.Challenge #6: Interoperability & Maintenance—Playing Nicely with Others The fediverse is diverse. Different servers have quirks. Ensuring compatibility requires testing and adaptation. Standards evolve with new Federation Enhancement Proposals (FEPs). You also need protocols like NodeInfo to advertise server capabilities. Fedify aims for broad interoperability and is actively maintained. It includes features like ActivityTransformers to smooth over implementation differences. NodeInfo support is built-in via setNodeInfoDispatcher.Challenge #7: Developer Experience—Actually Building Your App Beyond the protocol, building any server involves setup, testing, and debugging. With federation, debugging becomes harder—was the message malformed? Was the signature wrong? Is the remote server down? Is it a compatibility quirk? Good tooling is essential. Fedify enhances the developer experience significantly. Being built with TypeScript, it offers excellent type safety and editor auto-completion. The fedify CLI is a powerful companion designed to streamline common development tasks. You can quickly scaffold a new project tailored to your chosen runtime and web framework using fedify init. For debugging interactions and verifying data, fedify lookup is invaluable. It lets you inspect how any remote actor or object appears from the outside by performing WebFinger discovery and fetching the object's data. Fedify then displays the parsed object structure and properties directly in your terminal. For example, running:$ fedify lookup @fedify-example@fedify-blog.deno.dev<Will first show progress messages and then output the structured representation of the actor, similar to this:// Output of fedify lookup command (shows parsed object structure)Person { id: URL "https://fedify-blog.deno.dev/users/fedify-example", name: "Fedify Example Blog", published: 2024-03-03T13:18:11.857Z, // Simplified timestamp summary: "This blog is powered by Fedify, a fediverse server framework.", url: URL "https://fedify-blog.deno.dev/", preferredUsername: "fedify-example", publicKey: CryptographicKey { id: URL "https://fedify-blog.deno.dev/users/fedify-example#main-key", owner: URL "https://fedify-blog.deno.dev/users/fedify-example", publicKey: CryptoKey { /* ... CryptoKey details ... */ } }, // ... other properties like inbox, outbox, followers, endpoints ...}<This allows you to easily check how data is structured or troubleshoot why an interaction might be failing by seeing the actual properties Fedify parsed. Testing outgoing activities from your application during development is made much easier with fedify inbox. Running the command starts a temporary local server that acts as a publicly accessible inbox, displaying key information about the temporary actor it creates for receiving messages:$ fedify inbox✔ The ephemeral ActivityPub server is up and running: https://<unique_id>.lhr.life/✔ Sent follow request to @<some_test_account>@activitypub.academy.╭───────────────┬─────────────────────────────────────────╮│ Actor handle: │ i@<unique_id>.lhr.life │├───────────────┼─────────────────────────────────────────┤│ Actor URI: │ https://<unique_id>.lhr.life/i │├───────────────┼─────────────────────────────────────────┤│ Actor inbox: │ https://<unique_id>.lhr.life/i/inbox │├───────────────┼─────────────────────────────────────────┤│ Shared inbox: │ https://<unique_id>.lhr.life/inbox │╰───────────────┴─────────────────────────────────────────╯Web interface available at: http://localhost:8000/<You then configure your developing application to send an activity to the Actor inbox or Shared inbox URI provided. When an activity arrives, fedify inbox only prints a summary table to your console indicating that a request was received:╭────────────────┬─────────────────────────────────────╮│ Request #: │ 2 │├────────────────┼─────────────────────────────────────┤│ Activity type: │ Follow │├────────────────┼─────────────────────────────────────┤│ HTTP request: │ POST /i/inbox │├────────────────┼─────────────────────────────────────┤│ HTTP response: │ 202 │├────────────────┼─────────────────────────────────────┤│ Details │ https://<unique_id>.lhr.life/r/2 │╰────────────────┴─────────────────────────────────────╯<Crucially, the detailed information about the received request—including the full headers (like Signature), the request body (the Activity JSON), and the signature verification status—is only available in the web interface provided by fedify inbox. This web UI allows you to thoroughly inspect incoming activities during development.The Fedify Inbox web UI is where you view detailed activity information.<When you need to test interactions with the live fediverse from your local machine beyond just sending, fedify tunnel can securely expose your entire local development server temporarily. This suite of tools significantly eases the process of building and debugging federated applications.Conclusion: Build Features, Not Plumbing Implementing the ActivityPub suite of protocols from scratch is an incredibly complex and time-consuming undertaking. It involves deep dives into multiple technical specifications, cryptographic signing, security hardening, and navigating the nuances of a diverse ecosystem. While educational, it dramatically slows down the process of building the actual, unique features of your federated application. Fedify offers a well-architected, secure, and type-safe foundation, handling the intricacies of federation for you—data modeling, discovery, core mechanics, delivery, security, and interoperability. It lets you focus on your application's unique value and user experience. Stop wrestling with low-level protocol details and start building your vision for the fediverse faster and more reliably. Give Fedify a try! Getting started is straightforward. First, install the Fedify CLI using your preferred method. Once installed, create a new project template by running fedify init your-project-name. Check out the Fedify tutorials and Fedify manual to learn more. Happy federating!

旋宮圖 Hsüan Kung Diagram
yongzs1218.github.io/hsuan-kun
在AI的指導下,我用JavaScript、CSS和HTML架設了一份網頁版「旋宮圖」。該圖可用於旋宮犯調實踐,之調、爲調轉換等場景。

Under the guidance of AI, I developed a web-based “Hsüan Kung Diagram” using JavaScript, CSS, and HTML. This diagram is designed for Hsüan²-kung (Xuán-gōng, 旋宮) and Fan⁴-tiao⁴ (Fàn-diào, 犯調) practices, including scenes such as Chih-tiao⁴ (Zhī-diào, 之調) and Wei²-tiao⁴ (Wéi-diào, 爲調) transformations. 旋宮 and 犯調 are traditional Chinese modulation or transposition concepts, 之調 and 爲調 are traditional Chinese key notation systems.

AIの指導のもと、私はJavaScript、CSS、HTMLを用いてウェブ版「旋宮図(せんきゅうず)」を構築しました。この図は、旋宮犯調(せんきゅうはんちょう)の実践や、之調(しちょう)・爲調(いちょう)の変換などのシナリオに活用できます。

Dưới sự hướng dẫn của AI, tôi đã xây dựng một ”Đồ Huyền Cung (圖旋宮)“ phiên bản web bằng JavaScript, CSS và HTML. Bản đồ này có thể ứng dụng trong thực hành chuyển điệu Huyền Cung Phạm Điệu (旋宮 犯調), cũng như chuyển đổi giữa hệ thống Chi Điệu (之調) và Vi Điệu (爲調)./𨑜事向引𧵑AI,碎㐌𡏦𥩯“圖旋宮”翻版web憑JavaScript,CSS吧HTML。版圖尼固體應用𥪝轉調 旋宮-犯調,拱如轉𢷮𡧲系統之調吧爲調。

AI의 지도 아래, 저는 JavaScript, CSS, HTML을 사용하여 웹 버전 「선궁도(旋宮圖)」를 구축했습니다. 이 도표는 선궁 범조(旋宮 犯調) 실습 및 지조(之調)·위조(爲調) 변환 시나리오에 활용될 수 있습니다./AI의 指導 아래, 저는 JavaScript, CSS, HTML을 사용하여 웹 版 「旋宮圖(선궁도)」를 構築했습니다. 이 圖表는 旋宮 犯調(선궁 범조) 實習 및 之調(지조)·爲調(위조) 轉換 시나리오에 活用될 수 있습니다.

yongzs1218.github.io旋宮圖 Hsüan Kung Diagram

Is the ordering of attribute values ever semantically or logically important.

For example, is there ever a practical difference between:

`<p class="a b">`
and
`<p class="b a">`

WhaleTimeLines

Blogpost: blog.illestpreacha.com/napowri

#NaPoWriMo #NaPoGenMo #packetgraphs #creativewriting

For the 6th poem of NaPoWriMo/GenMo 2025, I decided to use Packet Graphs(Via #MermaidJS) as a way to construct the poems

#Poetry

---
title: "WhaleTimeLines"
---
packet-beta
0-15: "Reading Beyond the Lines"
16-31: "Sandwiched between the times"
32-40: "Covering the oceans floor"
41-50: "rippling through the waves"
51-95: "The oceans waves that pour"
96-108: "The waves as its flows through the core"
109-117: "Adds up more and more"
118-133: "As the whales they swim"
134-145: "Swim along the edges of their fins"
146-172: "ushering in the newer phase"
173-215: "phase into the pace"
216-255: "increments seen in the place"

New Kitten feature: Icons!

You can now make use of a subset of the icons in the Phosphor icons set by @minoraxis and @rektdeckard.

kitten.small-web.org/reference

Search through them in your editor by referencing `kitten.icons.categories` and `kitten.icons.tags`.

Add this to a file called index.page.js and run `kitten` to see a large duotone pink cat (because why not?):

export default function () {
return kitten.html`
<${kitten.icons.c.Cat}
size=40%
weight=duotone
colour=deeppink
/>
`
}

(And yes, the set includes icons for the fediverse. This one of the reasons I chose it.) ;)

Enjoy!

:kitten:💕

To #repurpose an old #Kindle e-ink e-reader you would usually require it's root password.

This tool is a single web page that uses #javascript (running locally) to compute the root password for your device from it's serial number (located on the device's settings page). There is also a link to the original #Python script that this tool is derived from.

sven.de/kindle/

One example of how they can be repurposed:
blog.lidskialf.net/2021/02/08/

#reuse #repurposing #eink #ereader 14673889

www.sven.deAmazon Kindle root password tool

PHP friends. I am looking to experiment with Protobuf as a way to define an API, for which we'll want code-generation for both (modern) PHP and Javascript/TypeScript. What's your recommendation? I'm finding lots of decade-old projects...

Alternatively, is there tooling to generate Protobuf off of PHP code/attributes, the way OpenAPI can?

This month's performance hero is a person after my own heart – someone who is passionate about building a secure, accessible, performant web for EVERYONE, and who always leads with a deep compassion for users. Let's all join in celebrating Alex Russell (@slightlyoff)!

speedcurve.com/blog/performanc

SpeedCurveSpeedCurve | Performance Hero: Alex RussellOur newest performance hero is passionate, provocative, and unapologetically honest. Join us in celebrating Alex Russell!
Continued thread

So it does look like the TypeScript language server has a limit of 4MB source size where it disables type checking (and actually shows an erroneous error stating that exports that exist in the file do not exist) for files that are imported but not open in the current workspace/session.

Still not sure if this is documented anywhere or not (haven’t been able to find it, if it is).

99.99999% of the time, unless you’re doing niche stuff like I am, you won’t run into this.

Workaround: should you have such a large file, e.g., with a large generated object, try and refactor to split it up into multiple files and rejoin it a separate file. The actual object size/memory usage isn’t the issue, it’s the file size.

github.com/typescript-language

#TypeScript#max#lines
Continued thread

🤩 An der Akademie der Wissenschaften und der Literatur in #Mainz wurde am #girlsday in Zusammenarbeit mit #NFDI4Culture an einer Webanwendung gearbeitet, die sich "In meiner Nähe/Around me" nennt.

👏 Es wurden Wikidata-Einträge zu Museen, Schulen und Parks zur #Georeferenzierung um einen Kartenmarker abgefragt. Dabei hatten die Mädchen Einblick in #wikidata #SPARQL -Queries, #html #CSS und #javascript Und vor allem viel Spaß! 😃

#NFDI4rocks

^gp (sp)