The sqlite cli supports loading modules at runtime, so you can do things like load and use a db via a custom vfs. My Go implementation of this vfs supports running in loadable module mode[1].
There was something sort of terrifying about the enemy tanks. Maybe a minimap would help with this, but I almost got Slenderman vibes when I would turn around and see a tank right there in front of my face. Got my heartrate going.
I fully get it. Their seeking algo is pretty primitive, but their steady relentlessness is unnerving. At level 3 or higher there are green pads you can run over that gives you an overhead view
I've also talked to a number of teams who just implemented pattern 3 internally with a custom service. Generally they've determined it's worth it to centralize all authorization data (like roles, groups, etc) into one place and perform ALL permission checks there.
There are also some companies building essentially Zanzibar clones, like Auth0, Authzed, Ory Keto, and a few more.
In most cases (even with many 100s of thousands or millions of users), there are far fewer _roles_. So you can generally answer the question of "which users can access this resource" by answering the questions "which roles can access this resource", and "which users have those roles". If you're using SQL to store roles and role assignments, your query for all users becomes:
select * from users
join user_roles on user_roles.user_id = users.id
where user_roles.role_id in [... small list ...]
This can get tricky if you have 100s of thousands or millions of _roles_, and each of those roles can be dynamically assigned access to a significant percentage of your resources. But that might suggest you're structuring roles incorrectly in the first place (and you should be using fewer roles with more users per role).
All that being said, I think there's definitely more to be written here. Keep a lookout -- we might do some more writing about the topic.
> This can get tricky if you have 100s of thousands or millions of _roles_
If you use something like a bitmap index (e.g. Roaring Bitmaps), you can easily manage roles in-line on each user row if the role membership is typically sparse.
You can still maintain a separate Roles table as a canonical reference, but you would no longer need to join on it to determine who has what.
Yes and no: there is no bitmap SQL type, but at least MSSQL packs multiple BIT-columns on the same table into the same word/byte and then uses bit tests for filtering. I suspect Oracle and Postgresql can do the same, but I don't know for sure.
The rust core is indeed called from the ruby library (as it is with all of our 5 other host libraries). The core itself is pretty complex (there's a whole parser/interpreter in there), so maintaining it in a bunch of languages would be a bit hectic.
I actually came to this thread expecting more people to call out MobX. When I use MobX with react, I find it to be as simple and _fun_ as the author finds svelte. Most of the problems people tend to raise with React are problems that are solved by observable state objects.
I also evangelize it whenever I can -- I don't want MobX to be forever doomed to its status as a cult hit!
It's baffling to me how distant of a second it is in terms of popularity. Instead of forcing you to contort your program into a special paradigm in order to deal with reactivity in a sane way, it simply makes reactivity a non-concern (while remaining pretty simple and predictable when you do actually care to dig beneath the magic). You can write code in a way that's natural and simply not think about reactivity most of the time, and you'll even get better performance in many cases because of the highly-granular pub/sub that it sets up automatically. I cannot praise this paradigm enough.
And then there's Vue.js which essentially has MobX functionality built in. When you want to update the state, you just...update the state, which can be a plain JS object that knows nothing about the front-end framework. I've used it for several medium-size projects and haven't gotten close to needing anything like Redux or Vuex.
Yeah, although when I played with Vue a couple years ago it seemed like it wasn't quite as powerful as MobX (particularly when you start stacking up a graph of computed values, or when you want to create side-effects of your own). But definitely a similar idea.
In my experience it’s not about “bad” vs. “good” code, and not about a tradeoff between speed and quality.
It’s more about how much abstraction is built into the system. A mature codebase has a clear purpose and therefore can contain durable, high level, even beautiful abstractions. On the other hand, a founder doesn’t always (nor should they) know what their code will need to do in 6 months time, so they typically avoid writing abstractions.
You can still write good code as a founder—it’s just that good founder code looks different than good BigCo code.
Curious why you're so opposed to spacer components. In my experience they work quite well--often a designer has specified that two widgets lie a certain distance apart, either vertically or horizontally, and the programmer needs to express that in code. Makes much more sense to use a spacer component than to add a margin to one or both of the widgets themselves.
If responsiveness is what you're after, you can easily make your spacers adaptable to different screen sizes.
Why not let the parent lay its children out? In my experience, a lot of engineers resort to things like spacer components due to not being very good at css. Flex, grid and even table layout should give just about everything needed for all but the most crazy layout needs. With flex and grid, you can often build responsive layouts without needing media queries.
That's exactly what the article is talking about. "Let the parent lay its children out" means "use layout components in the parent". This is what this `Stack` component is: probably a flex container. They use the term "spacer component" but "layout component" would be more accurate and wouldn't trigger all these knee-jerk reactions
My argument is that component isn't needed. The article is basically proposing Parent -> Stack -> Children. I argue the parent should own both its parent roles and the layout roles. The Stack component adds an unnecessary layer IMO. It will probably add an unnecessary DOM node too which is unfortunate. My experience with layout-like components such as this Stack is they often have limitations people work around in bad ways, or sometimes they just end up having props like `columnGap` and basically just end up being a little re-implementation of inline styles. I have pretty much always found just having the parent do layout using standard CSS to be better.
It's a more subtle argument, but a lot of people (me included) think that `<Stack>...</Stack>` is better than `<div class="stack">...</div>`. More readable, more reusable, that's the sort of thing Flutter went with (not a Flutter user personally).
There's no reason it would add unnecessary DOM nodes. You can add styling on top of any component if needed (styled-components is one way but not the only one). Having a `columnGap="small"` is perfectly acceptable for me (`columnGap={3}` too if 3 refers to some scaling, `columnGap="10px"` is bad).
It's similar to the Tailwind approach: have ready-made pieces of UI you can compose. But I also get why you wouldn't like it, and I think any of these approaches work fine enough if you they're used diligently
Because then the designer comes back and decides to change that spacing by 5% on one page, but not another. And now you're using the same spacer component across your entire application, so you're adding config to a component that needs to be documented and learned by the next developer using it. Instead, just express that spacing in CSS that is specific to a page. Use mixins if you like to set a base default spacing, then extend it whenever needed. Application/component structure should be completely divorced from presentation. It's literally the same problem we had with <table> based layouts.
>In this scenario, you can add props/params to override defaults.
Of course. But why? You're just adding complexity at that point. It's the same problem with frameworks like Bootstrap that use complex combinations of class names for styling. Now instead of having a semantic BEM style class name on the component that I can look up in a stylesheet and modify, I have to memorize an entire framework of esoteric 'col-md-whatever' class names and know how/where/when to apply them. It adds a massive cognitive load beyond just using CSS. In the instance of a custom spacer component described above, I'm now also on the hook for documenting and testing a component that is entirely visual, rather than just writing a couple lines of CSS.
Well then what’s the alternative? Using the same spacer component everywhere is bad because the designer might want to change the spacing in only one spot? Okay. But what if the designer wants to change the spacing in all spots? That’s a much more likely scenario in my experience, but the point is you need to be able to do both.
The point is that layout should be handled at the highest level possible. Have a CSS file at the application shell component level which defines a baseline margin and grid for components, then have individual page component level CSS that can tweak those layouts where needed. Actual UI components should then only ever need to use padding.
At the same time, I find that it's often hard to comprehend projects that are broken into too many little files. There's normally no guide on what pieces are where, so you don't know which order to read things. Makes it a little tougher to dive in. I just want to find the file that has the "meat", and I don't mind if that file is 1000+ lines long, especially if the code itself makes sense and is clear.
But I’m advocating something much stronger than that: breaking them down into small modules each with a published interface.
You can see what all any given module depends on by looking at one set of imports at the top of one file.
Each of those has a github repo and a README, so it’s easy to find out what they do...
But most importantly, the architecture of such a library will be wholly different than what it would have been if developed as a monorepo.
My point is not really that this structure of code is ergonomic. It’s that forcing yourself to do things this way forces you to clarify the purpose of modules. And to discover interfaces which are truly orthogonal.
Completely agree. This is a common problem with object-oriented code bases. You've got hundreds of 20 line source files and the only way to decipher them is to trace the execution all the way from main() down to the last util class.
It'd be very handy if this was packaged as a CLI that worked like `sqlite3`, so you could get a SQL repl by running: