techhub.social is one of the many independent Mastodon servers you can use to participate in the fediverse.
A hub primarily for passionate technologists, but everyone is welcome

Administered by:

Server stats:

4.6K
active users

#functionality

3 posts3 participants0 posts today

#Decentralized #Module #Federation #Microfrontend #Architecture

I'm working on a #webapp and I'm being #creative on the #approach. It might be considered #overcomplicated (because it is), but I'm just trying something out. It's entirely possible this approach won't work #longterm. I see it as there is #onewaytofindout. I don't recommend this approach. Just sharing what I'm trying/#investigating.

How it will be #architected: [positive-intentions.com/blog/d
Some #benefits of the #approach: [positive-intentions.com/blog/s

I find that #modulefederation and #microfrontends to generally be #discouraged when I see posts, but I think it works for me in my #approach. I'm #optimistic about the approach and the #benefits and so I wanted to #share details.

When I serve the #federatedmodules, I can also host the #storybook statics so I think this could be a good way to #document the modules in #isolation.

#Cryptography modules - cryptography.positive-intentio

#P2P framework - p2p.positive-intentions.com/?p

This way, I can create #microfrontends that consume these #modules. I can then #share the #functionality between #apps. The following apps are using a different codebase from each other (there is a #distinction between these apps in #opensource and #closesource). Sharing those #dependencies could help make it easier to roll out #updates to #coremechanics.

#P2P chat - [chat.positive-intentions.com/]
#P2P file transfer - [file.positive-intentions.com/]

The #functionality also works when I create an #Android build with #Tauri. This could also lead to it being easier to create #newapps that could use the #modules created.

I'm sure there will be some distinct #test/#maintenance #overhead, but depending on how it's #architected I think it could work and make it easier to #improve on the current #implementation.

Everything about the #project is far from finished. It could be seen as this is a #complicated way to do what #npm does, but I think this #approach allows for greater #flexibility by being able to #separate #opensource and #closesource code for the #web. (Of course as #javascript, it will always be "source code available". Especially in the age of #AI, I'm sure it's possible to #reverseengineer it like never before.)

(mastodon might not be the place for something like this, so let me know if you dont like this kind of content. i typically post on reddit and would like to shift it more towards mastodon. i also use lemmy, but mastodon has a better reach.)

positive-intentionsDecentralized P2P Chat & File Transfer - Secure Messaging Without Central Servers | positive-intentionsExperience secure P2P chat, file transfer, and video calls without registration. Built on decentralized architecture with end-to-end encryption and complete data ownership.

🧐 So you wrote a "simple" coding agent in 94 lines of #Ruby, huh? 🚀 Wow, truly groundbreaking—if only the rest of us had thought of removing comments and whitespace to achieve such brevity! 😂 Meanwhile, Thorsten Ball's 400 lines in #Go is probably just him being humble with actual #functionality.
radanskoric.com/articles/codin #codingagent #brevity #humor #HackerNews #ngated

Radan Skorić’s website · Coding agent in 94 lines of Ruby“It’s not that hard to build a fully functioning, code-editing agent.” Thorsten Ball

"Windows Portable Apps" and "Cool Browsers Apps" develop Useful Apps for Windows, Android and Web Browsers that Increase the Daily Productivity of many People. (If you love "#Simplicity, #Functionality and #Productivity", then our Apps are a #Must for you!)
.
Microsoft Store:
apps.microsoft.com/search/publ
.
Amazon Appstore:
amazon.com/s?rh=p_4%3AWindows+
.
Official Web Pages:
windowsportableapps.blogspot.c
.
cool-browsers-apps.blogspot.com
.
#Automation
#Windows #windows11 #windows10 #Windows7
#Android
#Firefox #Chrome

UI Algorithms: A Tiny Undo Stack, by @julik:

blog.julik.nl/2025/03/a-tiny-u

Julik Tarkhanov · UI Algorithms: A Tiny Undo StackI’ve needed this before - a couple of times. Third time I figured I needed something small, nimble - yet complete. And - at the same time - wondering about how to do it in a very simple manner. I think it worked out great, so let’s dig in. Most UIs will have some form of undo functionality. Now, there are generally two forms of it: undo stacks and version histories. A “version history” is what Photoshop history gives you - the ability to “paint through” to a previous state of the system. You can add five paint strokes, and then reveal a stroke you have made 4 steps back. But most apps won’t need that. What you will need is an undo stack, which can be specced out as follows: An undoable action gets performed and gets pushed onto the stack. If undo is requested, the stack is popped and the rollback action gets applied for the popped action. If an action was undone, you can redo that action. If you have undone 2 actions, you can redo 2 actions. If you push an undoable action onto the stack in presence of actions that can be redone, they get discarded - there is no branching, remember? If you are curious how “the big guys” used to do it - check out the NSUndoManager documentation So, as I usually like to do, I want to understand the API that would be optimal. For this use case - drawing - I had the following workflow: When you draw a stroke the input points get added to currentStroke When you release the pen the currentStroke gets appended to strokes and reset for the next stroke. I wanted something like this: let addStroke = () => strokes.push(currentPaintStroke); let removeStroke = () => strokes.pop(); undoThing.push(addStroke, removeStroke); // then, on user action undoThing.undo(); // calls removeStroke() undoThing.redo(); // calls strokes.push(...) again The perils of stack pointers Simplest thing in the world. Now, if you look at most recommended (and some existing!) implementations of an undo stack, you will find they usually make use of a stack with a pointer. Like here and here - you would have a stack, usually represented as a JS array, and some kind of pointer or an index that you would use to index into it. And while it is workable and standard, it just didn’t jive with me well. See, using an index into an array usually makes JS code susceptible to two things, which bite me every single time: Indexing into a nonexistent index - hello undefined checks Mistakes in offsets when calling Array.slice and Array.splice. Oh, and confusing slice and splice, of course. The fact that Ruby and JS have different semantics for slice - one uses the index bounds, the other uses two offsets - doesn’t help things. And what happens if an API uses offsets into a vector? Exactly: confusion whether those offsets are inclusive or exclusive. Oh, and the offsets change after you mutate the array, which makes it even more painful. Could we not index? So what came to mind was this: we effectively have two stacks, not one. We have an undoStack (things that can be rolled back) and a redoStack - things that can be rolled forward. All the things we do with our undo-redo actions actually do not change the pointer - they move things from one stack to another. And rules change between these two stacks! We erase the redoable actions when we add a new undoable action, remember? So while an undoable stack will rarely get “nullified”, the redoable stack likely will be nullified frequently. Once this became clear, the implementation practically wrote itself: function createUndoStack() { let past = []; let future = []; return { push(doFn, undoFn) { doFn(); past.push({doFn, undoFn}); // Adding a new action wipes the redoable steps future.length = 0; }, undo() { let action = past.pop(); if (action) { action.undoFn(); future.unshift(action); } }, redo() { let action = future.shift(); if (action) { action.doFn(); past.push(action); } } }; } So instead of trying to save resources by having just one array (and miserably failing with off-by-one index errors), we can embrace dynamically sized arrays and just forget indices altogether. Neat! Let’s add a couple more methods to display our UI: get canUndo() { return past.length > 0; }, get canRedo() { return future.length > 0; } The call-by-sharing problem There is a catch with our implementation though. JS has rather interesting lexical scoping rules: what is defined in the scope of the definition of the function will be referenced from within the function. This means that when we start pulling a new currentStroke our undoFn closure will not use a copy of the currentStroke it was created with, but our current one. And our doFn and undoFn must satisfy an important guarantee: they must be idempotent. No matter what the state of the surrounding system is, appending the currentStroke should always append the stroke the redoFn was created for. If we do not take care of this, the following doFn: let doFn = () => strokes.push(currentStroke) is going to grab the currentStroke from the surrounding scope (whatever its value is) and append it to the strokes array. The currentStroke at that time may be just empty. To avoid this behavior, we want our doFn to use a cloned copy of the currentStroke - current at time of definition of doFn, and we want it to do so always. If your undoable action is some kind of delete (“pop”) you want the reverse for your undoFn - the undo function must push the deleted object back into the array, and not mutate it in any way. To create a deep copy of our currentStroke, modern JS offers us a feature called structuredClone(). We can use the ... rest parameters to package any arguments into one array, which we will then clone: push(doFn, undoFn, ...withArgumentsToClone) { const clonedArgs = structuredClone(withArgumentsToClone); const action = { doWithData() { doFn(...clonedArgs); }, undoWithData() { undoFn(...clonedArgs); }, }; action.doWithData(); // Adding a new action wipes the redoable steps past.push(action); future.length = 0; } and we’ll amend our functions accordingly. Instead of closuring over currentStroke we’ll make it an argument: let appendStroke = strokes.push.bind(strokes); undoStack.push(appendStroke, () => strokes.pop(), currentStroke); with the push() of our undoStack taking care of making a deep clone for us. Nice! The complete definition then becomes: function createUndoStack() { const past = []; const future = []; return { push(doFn, undoFn, ...withArgumentsToClone) { const clonedArgs = structuredClone(withArgumentsToClone); const action = { doWithData() { doFn(...clonedArgs); }, undoWithData() { undoFn(...clonedArgs); }, }; action.doWithData(); // Adding a new action wipes the redoable steps past.push(action); future.length = 0; }, undo() { let action = past.pop(); if (action) { action.undoWithData(); future.unshift(action); } }, redo() { let action = future.shift(); if (action) { action.doWithData(); past.push(action); } }, get undoAvailable() { return past.length > 0; }, get redoAvailable() { return future.length > 0; }, clear() { past.length = 0; future.length = 0; return true; } } } export {createUndoStack}; Robust, small, and no indexing errors. My jam.

Oh, look! Another #AI function calling thingamajig named Gemma—because apparently, the only thing more predictable than #AI is #naming it after a posh first name 🙄. In a bold move, the article manages to tell us absolutely nothing about how it actually works, but hey, they sure did nail the whole "skip to main content" part! 🚀
ai.google.dev/gemma/docs/capab #Trends #Functionality #Tech #Humor #Innovation #HackerNews #ngated

Google AI for DevelopersFunction calling with Gemma  |  Google AI for Developers

Doubt if #Elektron will ever make another Analog Keys synth. It probably was too much of a disaster, mostly due their own #design mistakes on holding off some important features in the beginning, most notably the MIDI sequencing #functionality. This later became an essential element of every new product Elektron has released but it was too late for the humble Analog Keys. For me, this entire story is an example how #marketing department will destroy your best products if you are not careful.