ByteCode.NewsSubmit
Use quotes for an exact word.

Subscribe

RSSPodcast
Log in

Chat Logs

  1. bot[ByteCode.News] Andrew Lombardi: Unit Tests are Not the Enemy - https://bytecode.news/posts/2026/10/andrew-lombardi-unit-tests-are-not-the-enemy
  2. bot[ByteCode.News] Arcana Reads Everything, and Then Some - https://bytecode.news/posts/2026/10/arcana-reads-everything-and-then-some
  3. bluedreamreal: good take by Lombardi there
  4. bluealso, what kind of idiot just deletes unit tests...
  5. liolocblue: Hey blue ! Just to remember, right now there is no package to help with caching in the browser right? Like for instance if you receive props and you wanted to cache those props for the next time the user visits the page, would there be a way to do this?
  6. liolocCaching is a topic that's always been a bit tough for me to understand (backend vs browser)
  7. liolocI usually just use packages like tanstack/query that handles the caching mechanisms for me for the browser, and since now I instead typically make the queries in the route, these are backend fetches right? So I can't cache those unless I use redis or something like that right?
  8. liolocI'm trying to understand what would be the right mechanisms to use caching in Primate for both use cases:
  9. lioloc1. You're doing a fetch in a route
  10. lioloc2. You receive props and maybe you want to cache those (or do you need to instead use a query library on the frontend instead and do the call here instead?)
  11. bluehi lioloc
  12. bluecan you describe the use case so it's easier to understand? when do you want to cache props? And if you're fetching in a route, that's already on the server, there you'd probably use a caching server like redis. There are plans for a @primate/kv package: https://repopack.com/project/primate/tasks/10
  13. bluebut I think it'd be easier for me to offer you paths forward if I understand your actual use case
  14. dreamrealblue: revamped the primate build's topbar
  15. dreamrealit was getting gross
  16. bluegood good
  17. bluedreamreal: release artifacts landed today in repopack; it turned out a bit more than I'd bargained for, but the model is strong, I think; it has products, channels, and releases; releases draw from job runs; and can be promoted to channels. Channels carry access levels (PUBLIC or PROJECT). products are, well, a single publishable entity
  18. liolocblue: Let's say in a route I fetch: Races and pass them as a prop to Index.vue, races is an array of objects and maybe it can contain 100 results
  19. dreamrealNoice!
  20. blueso the `rp` cli is a "product"; it has channels (stable, unstable); and there are releases, either unassigned to any channel (in which case they are project-private), or assigned to a channel
  21. liolocblue: This is small enough that it isn't an issue without caching I would assume. But let's say there are like 10000 races and I want the experience of the application to feel extremely rapid when I'm moving from page to page, so that I can come back to a previous tab
  22. bluelioloc: so you load 10k races at once and want to keep it in the browser tab's memory; and those 10k races never change?
  23. liolocLet's say we want to control when they change, like maybe we want to refetch only after 5 minutes
  24. liolocso they won't change for 5 minutes
  25. bluehow would you feel about `response.page(props, { cache: { ttl: 60 /* seconds */ } })`?
  26. liolocI'm not sure if keeping it in the browser's memory is the best answer btw, I'm just trying to get the fastest experience for a user
  27. blueand same for response.view
  28. liolocthat would be neat
  29. bluethat would be transparent for you; the primate fetch-client would serialise the path, and cache on the serialised key
  30. bluethe route itself would likely send something like `Primate-Cache: max-age=60` along the response
  31. blueas a header
  32. liolocthis is for browser caching or server side caching btw?
  33. bluebrowser caching
  34. blueprops caching
  35. blueserver side caching is the easier problem there because you can write a small cache yourself fairly easily. @primate/kv could help there but it's relatively trivial to do it yourself first. the client part isn't
  36. liolochave you used something like tanstack/query? They also have the ability to invalidate a cache on the client, for optimistic updates, it can quickly can get confusing imo
  37. blueI haven't, but I was going to say that what I just purposed is a streamlined version of tanstack/query, where you don't need to manage the caching keys yourself
  38. bluefrom the documentation of tanstack/query, it appears terribly overengineered to me
  39. liolocbut what if you wanted to invalidate the cache once a user presses a button for instance?
  40. liolocwould be neat to be able to do that too
  41. bluethen we should expose something on `primate/navigate`, probably
  42. bluehttps://primate-master.repopack.app/blog/primate-043#navigation-that-says-what-it-does
  43. nevetPrimate — Primate 0.43: diamond migrations, deferred navigation and direct SQL
  44. bluemaybe navigate.cache.clear()
  45. liolocyeah would be neat
  46. liolocI guess it's also because something like tanstack/query is used client side, not server side
  47. liolocso you'll have multiple different query calls client side, each with their own cache key
  48. liolocIn primate's case, if you do the fetch in the route directly, wouldn't that mean that "Time to first paint" would be slower than in an app using tanstack/query to load things after?
  49. liolocI mean naturally it would right? Cause you're fetching before serving the page. I'm thinking like the case of an app's dashboard for a logged in user for instance.
  50. blueThat's a real distinction, however primate 0.43 will have response.defer
  51. bluewhich will allow you to use suspence boundaries or awaits inside clients
  52. bluesuspense*
  53. bluehttps://primate-master.repopack.app/blog/primate-043#stream-page-data-during-navigation
  54. nevetPrimate — Primate 0.43: diamond migrations, deferred navigation and direct SQL
  55. liolocoh wow
  56. liolocvery neat
  57. liolocif we introduce caching then maybe with defer you should also be able to invalidate a specific one?
  58. bluea specific prop?
  59. liolocyeah
  60. lioloccause if you have many props, perhaps you don't want everything to reload if you invalidate the cache
  61. liolocI mean reload every prop
  62. liolocwhat do you think?
  63. bluehm, selective browser updates can be hard
  64. blueI mean, we could potentially support navigate.cache.clear(key). but the mechanism behind it could turn out complicated
  65. blueif we have `response.page(props, { cache: { ttl: 60 /* seconds */ } })`, the browser would simply not call the route for 60 seconds
  66. bluebut if we start breaking it down to props, that's a bit harder: the browser needs to call the route for *some* props, and the route suddenly might need to know not to care about some props. the complexity is higher
  67. liolocyeah for sure
  68. bluelioloc: this is complex stuff. however, this could make sense:
  69. blueactivity: response.defer(() => loadActivity(), { ttl: 600 })
  70. bluethe lazy form means we can save actual work on the server, *for the particular client*
  71. bluewithout the lazy form, the gains aren't significant
  72. liolocin essence what does that lazy call mean? as opposed to without the lazy call
  73. bluewell, imagine we browse back to the page within the cache's lifetime. since we have a mixture between cached and non-cached prompts, primate has to issue a server request
  74. blueso it issues it with something like "I want this prop, but this prop is already cached and I don't need it)
  75. bluehowever, something like on this server:
  76. blueactivity: response.defer(loadActivity(project)),
  77. bluewill always do the work. loadActivity is essentially a promise-returning function, so the promise will return anyway on the server, and its output would be discard
  78. bluesomething like:
  79. blueresponse.defer(() => loadActivity(project), { ttl: 600 })
  80. bluecan be prevented from running at all if the cache boundary holds
  81. blues/prompts/props/
  82. bluethe question whether page-level caching (so an option on response.page) is enough or whether you want the prop granularity
  83. blueI'm not sure having both mechanisms makes sense, that's a lot of different combinations needed to be accounted for
  84. blueif prop granularity is actually what you're looking for, then we should explore extending response.defer to accept a lazy function and a ttl
  85. blueif caching an entire page (=all its props) is what you're looking for, that's easier
  86. bluebut I'm a bit hesitant to do both
  87. bluefwiw, the non-lazy form could still make a revisit *feel faster*. since the server work isn't blocking. but it happens anyway, that's a bit of a waste; maybe it's insignificant; though if we're talking about getting 10k records from a db, it might be
  88. bluedreamreal: would you also benefit from a client cache?
  89. bluespecifically I think that if someone has loaded an article before, it might be useful to cache. but I don't know the exact model of how you serve articles. you serve the entire rendered html, no?
  90. liolocwhat if it wasn't a response.defer function but just a "browserCache(" function (name irrelevant)? That way you can just decide whatever you want cached, whether it is the entire html or a specific portion, like props
  91. liolocjust spitballing ideas
  92. dreamrealI mean... maybe, but it would rely on a lot of retention
  93. blueyeah, but "whatever you want" cache still implies someone has to bookkeep that cache, and that's the complex part
  94. bluea different approach, lioloc, is a offer a `primate/query` or so
  95. bluehttps://dpaste.com/7NMKZMRM7
  96. bluebut I feel this is perhaps more relevant for BCN than what you just described
  97. dreamrealWell, it presumes retention, still
  98. bluelioloc: maybe you can create a small example and I can play around with it
  99. blueyes dreamreal, caching is widely also known as retention
  100. dreamrealstandard use on BCN is not a lot of interrelated post traffic, which annoys me but is reflected in traffic patterns
  101. bluethank you for stating the obvious :P
  102. dreamrealI'm not trying to state the obvious, I'm talking about whether that pattern makes sense for BCN, whose traffic patterns would NOT show a benefit as yet
  103. blueconst response = await posts.get({ path: { slug }, cache: { ttl: 300 },
  104. blue});
  105. dreamrealYou wanted me to look, I looked, damn it
  106. bluedreamreal: lioloc: what do we think about this?
  107. bluein one line: `const response = await posts.get({ path: { slug }, cache: { ttl: 300 }});`
  108. blueidk if any of those ideas seems coherent
  109. dreamrealsure
  110. dreamrealI don't have a problem with it at all, it just wouldn't affect BCN :D
  111. bluewell you know me, I'm loath to add things that are over-engineered, or complicated to understand or use
  112. dreamrealI don't think it's overengineered or difficult to understand
  113. dreamrealin fact I think its' really easy to understand
  114. bluewhich of the five options I offered?
  115. dreamrealThe one that seemed to make sense to me was https://dpaste.com/7NMKZMRM7
  116. blueoh
  117. bluedreamreal: flog is live and installable at https://flog.run
  118. nevetflog — predictable JavaScript package management
  119. blue(using repopack release primitives)
  120. blueI will also publish an sdk for releases at @repopack/release; do you need one for java/kotlin as well?
  121. dreamrealblue: what would primate's BCN build look like with flog?
  122. dreamrealshould have a "conversion from those other stupid package managers" section
  123. dreamrealjava's a much harder climb because of maven repositories
  124. bluedreamreal: well, flog is currently mostly for npm; but the commands aren't js specific. the question is what do you need / what do you expect the workflow to be; generally, flog works like this:
  125. blueflog add / remove: adds or removes a dependency
  126. blueflog upgrade: upgrades dependencies (interactively)
  127. blueflog lock: create a lockfile
  128. blueflog install: materialises a lockfile
  129. blueif those primitives are transferable to maven, then there is no reason flog wouldn't be able to manage maven projects / pom.xml projects
  130. blue(flog add/remove/upgrade also changes a lockfile)
  131. dreamrealmaven IS a lockfile, there're analogs but they're not esp applicable in the space
  132. bluedreamreal: just to be clear, you're looking to replace maven on the kotlin/java app, or pnpm on the primate-ui app, or both?
  133. dreamrealpnpm mainly, although it actually used npm itself unless you changed it
  134. blueoh ok, then it's different from what I thought
  135. blueflog should be able to replace pnpm/npm 1:1 and be much faster
  136. dreamreal*nod* if you want to, try it on ui-primate
  137. dreamrealgood real-world-ish project
  138. blueya