Replies: 1 comment
-
This is patently false. The text on the page you link is: "Runes are similar to RxJS-style observables ... However, there is an important difference" I have not once said that runes are superior to observables, because I do not think that is true. I think that they are different, and thus that, for certain use cases, one may be preferable to the other. In my solutions, I wrap the mock API exposed by the tests into a runic API like Capi exposes. I then ported your vanilla solutions to use the runic API. These solutions do not use runes end-to-end, which clearly shows that Rune does not require that, and thus does not limit the user. For example, Capi uses Rune, but users are free to use Capi however they like – whether that's using vanilla JS logic around it, or integrating into other libraries they use, or using Rune themselves. Rune provides:
|
Beta Was this translation helpful? Give feedback.
-
In our recent discussions about "Challenging the Rune Primitive" I've expressed my skepticism about the utility of Runes, especially when dealing with complex projects. To put these concerns to the test, I started developing a set of scenarios that emulate the challenges I encountered during a DEX development.
I'll be honest, I'm doubtful if Runes, as they stand, could successfully meet these challenges. However, I believe it's only fair to give them an opportunity to prove otherwise. I've heard concerns from some peers who feel that the creators of Runes may not have the time to address these challenges. So, I've made the decision to simplify my original plan and devise just four straightforward tests, which can be tackled using any state-management library or even basic JavaScript.
Runes proudly declare themselves as a superior alternative to RxJS Observables. So, logically, these tests should be manageable for Runes. I was able to solve these four tests using RxJS in under five minutes, so I expect it should be achievable for Runes in a comparable time.
In an effort to dispel any accusations of bias, I've decided to base these tests on an example shared by one of the Rune creators. In addition, I've intentionally designed the API to be unergonomic for Observables. This is to ensure a level playing field.
The tests are structured around a typical scenario in which a single entity emits hashes over time, with two derived entities performing different actions:
The first derived entity retrieves the block number from the hash.
The second derived entity fetches a timestamp from storage.
A third entity combines all this information.
In my experience, the real test of any such system is managing the data flow. To illustrate, consider the following timeline:
This timeline shows a 'hot' source that emits several values (
a
,b
, andc
) simultaneously when a listener first subscribes. This is a common scenario when dealing with hot sources. After this initial burst, the source continues to emit hashes over time, for exampled
at moment 4,e
at moment 8, and so on.The diagram also represents the moments in time when the asynchronous values related to these hashes actually get resolved. The complexity arises from managing these asynchronous operations and responses.
Next, let's delve into the four tests and their relevance to various realistic use cases:
ignoreNewOnesUntilResolved
Test: In scenarios where the source that emits hashes does so at a fast pace (for instance, on Arbitrum Nitro), a dApp might opt to operate as follows: each time a hash is received, it triggers a data pull. Only after this data is resolved does the dApp react to new hashes. Any incoming hashes during the data pull are ignored. Referring to the timeline above, this results in the following hashes:a
,d
,e
,f
,g
.newOneCancelsOldOne
Test: In some cases, it's vital to showcase the most recent data. Therefore, whenever a new hash arrives, if there's an ongoing unresolved request, it gets cancelled as the latest data request begins. Referring to the timeline above, this results in the following hashes:d
,e
,f
,h
.allInOrder
Test: Sometimes, all data needs to be presented, but in a consistent order. This behavior can potentially lead to back-pressure, which could be problematic. Nevertheless, for simplicity, this test aims to present all data in the correct order as it arrives.asTheyCome
Test: At times, the primary requirement is to receive all the data as it comes, even if it's out of sequence. Referring to the timeline above, this results in the following hashes:a
,b
,d
,c
,e
,f
,h
,g
.While these scenarios are far simpler than the multitude of complexities I've faced professionally, they are a suitable starting point. Let's see if CAPI Runes can pass these preliminary tests.
You'll find the test scenarios in this repository. For your convenience, here are some critical points to keep in mind:
h
, the test must immediately unsubscribe from the producer.null
value. This serves as an indicator of the end of the data flow.The rest of the details should be straightforward once you examine the already implemented examples.
I've already prepared a
capi
folder to ease the process. So, all you need to do is clone the repository, executenpm i
, implement your solutions in thesrc/capi/solution.ts
file (there's also ahelpers.ts
file in case you want to separate helper functions from the main logic), and then runnpm test
. It's as simple as that!I am eager to see how the CAPI solutions tackle these four tests!
PS: Please note that I haven't completed two of the vanilla tests yet due to time constraints. I plan to wrap those up when I get a chance.Beta Was this translation helpful? Give feedback.
All reactions