Christian Warden, founder of October Swimmer, joins us to talk about aer, the local Apex runtime for Salesforce developers. Christian is a Salesforce development professional and Linux enthusiast with a passion for building developer tools.
Main Points
- Core problem: slow Apex test round-trips to the cloud
- Local debugger for Apex
- Go-based interpreter with in-memory SQLite database
- Broad Salesforce feature coverage (validation rules, flows, formulas, async Apex, governor limits)
- Commercial licensing model
- Origins: apex-format parser + Writing an Interpreter in Go
- Known limitation: implicit org dependencies must be in the repo
- Challenges and future roadmap
Links
Video
Contact Me
If you enjoy this podcast, please reach me out to let me know your thoughts or simply say Hello. My (Xi’s) contact info:
Take care, until next time :)!
Transcript
AI-generated, unedited.
[00:14] Hello everyone. This is Xi Xiao. This is a new episode of Salesforce Way podcast. Today I have a new guest with me. His name is Christian Warden. Hello, Christian. Hi, Xi. Thanks for having me. Yeah, I love your last name. By the way, it's like from the games. Thanks. My my son plays baseball, and they always call him Warden out on the field. I like it. Yeah, yeah, it's really matching the theme. So, Christian, would you like to quickly introduce yourself? Yeah, sure. My name is Christian Warden. I've been developing on the Salesforce platform since two thousand eight, so almost close to twenty years now. I've been doing before that. I was doing web development since about two thousand, and I started my career as a Unix administrator. And so I've kind of been doing a mixture of. Development work and systems work, and it's kind of overlapped in in doing development tools. So that's something I've enjoyed doing. As I've been building applications, is building the the tooling to help build those and those applications and get them deployed, and I continued that into my my Salesforce career. Yeah, thanks a lot. We in the past exchanged some idea because both of us did a bit the Apex language parser thing, right? You you build it on GoLang, I build it on
[01:44] Rust. We exchanged idea how we did it briefly, and then after that, I think you took. A far further away, like step, in addition to just the parser. So you build this new tool. So how do pronounce this new tool? R or so? So I I pronounce it air. Air. Okay. A E R. A E R. In the U S, the only time you really see that is maybe with Aer Lingus, the airline. Okay, so if you pronounce it air, maybe with a little Irish accent, but most people have been pronouncing it a e r, and I'm okay with that. So, okay, yeah, okay, yeah. That was the tool actually really fall into my radar when it was published in LinkedIn. I think some of my Like technical bodies, like Anthony Heber and Scott Wells, also they did like the internal kind of like beta testing with the tool. Yes, so yeah, Anthony's been one of the the earliest. Tester, okay, was barely functional. He he was telling me, I need to try this. I need to I need this for my software development. So he's given me. He's been a great resource in testing. Yeah, he's a fantastic buddy indeed. Yeah, you know the thing is that that trick that tool trickers me because the idea behind. Is that you can run the Apex tests locally,
[03:14] and maybe you have some other features on the tool. We're going to discuss that later. But only like this one to me is like wow. That's that's the thing I've been wished for so many years. I I guess a lot of other developers also wished for such a thing because we all know Salesforce. It has to run in the Either scratch work or sandbox, it has to run on the cloud, and it's slow, right? No matter how fast you test is, whether it's unit test or integration test, it has to go to the cloud. That's like multi seconds at at least. But run locally, it was like a dream because there were so many things like restricting it. You can't do this, you can't do that, and Salesforce is black box. Since this tour really achieved that goal, isn't so? Yeah, that's right. It's the pain that we've all felt as Salesforce developers is during development. As you're editing the code, you've got to deploy it to an org to test it and make sure that it. Just to compile it, you know, make sure that it compiles, and then to actually execute it, and so during development, there's a lot of those round trips. So every day you're probably losing minutes, at least, just kind of waiting. And then when it comes time to you know run your your full test suite, you also have to deploy everything to a sandbox or a scratch org and run all of the tests, and
[04:44] that can also be very time consuming when you get a a large test suite built up. Yeah, yeah. So is that the Biggest selling point for this tool, or does the tool have some other features also helping us? That was the the main impetus for building it was to solve that pain around having to deploy to an org during development and. Kind of in your CI environment, right? The other big feature that fell out of having a local runtime is that it has a debugger as well, so you can debug your Apex locally, like you would any other.
[05:49] language really that's something unusual with Apex is that you don't have a complex you know you have a complex code base that you're trying to debug or if you're new to an organization and there's a large existing code base and you just want to get familiar with it I find that stepping through code even if you're not really trying to find a bug but just to understand how the code works having a debugger is a nice way of kind of feeling your way through a code base that's new to you. Wow, I didn't know that. I gonna definitely try it. But to me, is that the
[06:26] the local environment already sounds really intriguing. Because at the beginning, I was wondering, hey, how it can be achieved locally. Then I spend a bit time to really dig into this tool. It's open source tool, right? All the things I can open the box a bit. It's not an open source. Okay, it's a commercial tool. There's a kind of free tier that you can download it. Everyone can download it and start using it. You can run you can run your tests against your code base. If you run more than a hundred tests at a time, it requires a license. And you can test out the debugger, but the debugger is also really a commercial feature. So after five minutes of debugging, you'll you'll also need to purchase a license. I think that's fair. With so much amount of work you have put into this, it's it's it's definitely there. But would you mind to at least tell us from the concept level how this local Like run runtime and the the database like DML SOQL queries, how you have achieved it? I think that's really the the interesting part, if you don't mind. Sure, yeah, like like you mentioned, it kind of started with Apex format, which was the Apex code formatter that I I built number of years ago, and so that was that gave me a parser to start from. And, the the
[07:56] code formatter that's similar to the, because in Salesforce people usually use the, de facto what what is it the prettier right common one yeah the DMR created that the prettier one so yeah the one you created is similar to that. In many ways, I mean, it is a it takes your Apex and it formats it. It's It's an opinionated formatter, though. So it it's based on the idea of Go format, which is there's only one format that's you can't configure whether you want spaces or tabs or whether braces should be on their own line or not. It's all it's very it's an opinionated formatter. So everybody that uses it gets code that's going to look the same. And it's actually it's not as fast as your formatter I know, but it's based on the the antler grammar that came out of there's a tool called toolingforce.com which was used to as the basis for a vim plugin that's been around for. Long time, fifteen plus years, I'm sure, and so that that grammar has kind of evolved and it's splintered, or it's it's not really splintered, but it's also shared by some other tools that use that same antler grammar, or the or derivative of that original antler grammar for some some Java tools and some JavaScript tools.
[09:26] So, like I said, so started with having a parsed. Apex tree, and a couple years ago, I read a book called "Writing an Interpreter in Go" by Thorsten Ball. And I'd never written an interpreter or a compiler. I've never taken a class in it, but I found this book was very well written, and gave me the idea maybe I can write an interpreter for eight minutes. Now that I've got somewhere to start from, and. So I basically use some of the ideas from that book to say, okay, I've got this parse tree. I need to now create an AST out of it. Um, and then I'll start executing that that tree, and so that's what it started with, and then that that allows you to execute kind of the most basic Apex, but there's a lot of features in Apex, including all the the DML features, and so. I did introduce a database, so it uses a embedded SQL like database in memory, and
[10:42] basically, when you run AAR with your tests, first it's going to parse the. Metadata that's in your repo, and it's going so it'll build a database based on the schema from that metadata, and it'll parse the Apex and build a parse tree, and it's going to essentially execute that that Apex, stepping through it all and performing all of the the database operations against that that local database. Okay, let me try to repeat. If I understand, so the Apex somehow there is this parser. It can translate the. The code into a so-called AST tree, and with that AST tree, you can somehow map it to the goal line. Is that how you did it? The Engine is written in in Go, and it essentially walks that tree and executes the statements. That are in that tree. So we translate the apex into this tree structure, which has things like method calls and constructor calls, and all of the different operators, things like that. And that the
[12:13] interpreter written in Go executes that tree. Ah, okay. So. Once the Apex code logic translates to the AST or the abstract tree, then it's language agnostic already. Then you can use that ASD tree then to map it to the to the go long. For example, if it's if else condition in Apex, and you can map it to the if else if the go long has I assume it has. So it's kind of like a one one to one map. If it's assignment logic, then need to a map to the assignment. Is it like kind of like one to one translation? It's it's not getting translated to Go, but the interpreter is written in Go. So okay, we've got this big. Tree that's structured as structs in Go, and each and yeah, so there would be a conditional.
[13:13] Node in that tree for your your if or if else statement, and when it sees one of those, then it would execute the condition and evaluate whether the conditions are true, and it would descend through if the condition is nested, or there are
[13:31] if it needs to evaluate the the condition by. Calling a method, for example, it would do that, and then eventually gets the result of the the condition, and then it determines whether to go down the path of the the true condition or the false condition. And okay, you know, I also have bookmarked a book for the interpreter. It's not for for go along, but I had it in my like a bookmark. But then, when the AI era hits, then I kind of like shift my time to the AI tooling learning. So I didn't have the chance to really learn that. Maybe one day I could put more effort on that. Then I could fully understand what you say. But I more or less get the idea. You also mentioned that based on the, like the local pulled from the org, the metadata for the data model, like the object fields, we pulled in the source format to our local. Then your tool could like set up a local database, simulate the data model for that. Is that? Yep, that's correct. And it it tries to follow the the structure that is exposed by Salesforce. So, in objects. Okay, is it the same database like a Oracle database? I assume Salesforce using, or do you use some other relational database? It's using SQLite as the database.
[15:02] Okay, so then there must be some challenges when you. Do the translation. There are yeah because SQLite isn't doesn't have all of the features of Oracle and so there are different obstacles to overcome to to get it working for sure. But the idea is that there's there's one table for each object. And so, at least looks this kind of what you would expect a database schema to look like, if you're looking at a an object in Salesforce with its fields, they they map pretty directly to what's created in the SQLite database. Okay. I think I now have at least more or less a a naive picture in my head. So it tries to simulate the Apex runtime locally with this GoLang interpreter, and then when it ex when the execution hits the DML or SOQL query, then it runs against this local database, right? And especially when we run the tests, mainly the test is like setup, and then setup, especially in the database, some configurations, and then to to assert if finally the record has the correct data in the database. That's typically how a tests with the DMLs that happens. And now we can fully run it locally, right? Right. That's how how it does. Yeah. So when you get to a DML statement in the code, or you get to a SOQL query in the code, then
[16:32] that gets translated into the database. Query. Wow, I mean, it sounds simple, right? Conceptually, it is simple. Yeah, it's very complicated. Yeah, yeah. I mean, I just think about you use a soccer light to to simulate the Oracle database. I I can't imagine like how many like edge cases you hit. You have to pull your hair out to to really figure out the the good ways. So the good things, like I said, I've got I had some some early users who are providing feedback on running the code against their code bases. There are also a number of open source Apex. Repositories that I was able to to use to test against, which helped me identify many of those edge cases that weren't handled early on. Okay, yeah, but other than these. Challenges. There are also surrounding metadata in Salesforce. They are not just Apex, right? We have validation rules. We have, I don't know, flows. Especially, right? They are part of the orgs. So, how do you slice that carefully, just to make sure it really works? Yeah. So, in addition to there being an Apex engine, there's also a formula. Evaluation
[18:04] engine essentially, which is simpler than the Apex sales formulas aren't as complicated, and I'd actually done some work on similar to Apex format parsing. Apex. I've built a library called S Formula for parsing and formatting. If formula Salesforce formulas, so that was also something that I could build on top of, in building Air, was I had this at least parser for the formulas, and so that parses validation rule formulas, formulas in flows, formulas in Visualforce are also pretty similar, so I'm able to use going to the same code there, so.
[18:57] Yeah. So, in addition to evaluating Apex, we also have to evaluate formula fields and validation rules, and there are really two implementations of like formula fields, both. Kind of in memory, and a translation to SQL, so that when you're querying formula fields, the formula actually gets translated to SQL to get the data out of the database. Wow! Yeah, I I almost forgot the formula part, and you like digged into this rabbit hole and expanded this big under the ground. Okay, uh, but but how? I mean, that's already part of your solution, right? So you mean this. Air tool supports formula field, which is already a big achievement. But how about the validation rules? Those things are they outside of your tool? We are not supposed to have it in the scope. No validation rules are supported as well. So as you're as you're executing the code, if there are validation rules found in the repo. They all get loaded, and they all get evaluated when you're doing DML to determine if they fire or not, and you get back the same errors that you would on. Salesforce's implementation of Apex
[20:27] and okay, so so so you mean if I pull those validation rules to the local, then they are included when I run the test. The test will actually call those validation tool rules. Somehow you you can simulate that as well. That's right. Yeah. So when it loads in the metadata for the objects, if it finds validation rules as well in the the repo, where you're loading your sources from, those get loaded into the the schema that's used during execution, and so it checks to see if you're doing DML on an account. Are there any account validation rules that need to be executed, and if so, it'll evaluate those. How about flow? So flows as well. There's a flow engine built into it. Okay. So it finds flows. It will parse up the flows that it finds in your repo. It loads all the searches. And, it flows are actually kind of easy, in that they're already structured as a tree in the the XML. So the parsing, anyways, is relatively straightforward. And Air will actually translate the parsed flow into the same AST structure as the Apex, so that it can then execute the flow the same way it would as if it were written in Apex. That's interesting. So I think only when when you really dig
[21:57] into that and start implementing, then you will see this. I was like treated like a black box. I never really wanted to see what's going on there. The structure is a little bit you know ugly in the the XML, but if you parse it and and just separate out the all the XML tags, it's it's pretty clean to to look at. Okay, that's interesting. Okay, but how about I don't know? Are there other metadata also supported? I understand the more you support it, of course the scope is bigger, but it's more mature or more well rounded your solution is right compared to the Salesforce one. The the goal is to support all Apex that runs on Salesforce platform. So if you have tests that that run on Salesforce platform, they should run in Air as well. Yeah, and there there there are still some edge cases, probably in some of the. Well, there are there are some open bugs, and some of them are esoteric. Namespace that I'm still working on, but in general, it should it should all work. So, in addition to the flow runtime, there's also a Visual Force engine, a partial Visual Force engine. There's not yet a feature to render Visual Force pages. I haven't found a need for one,
[23:28] but you might have Apex that sends Visual Force emails. And so, in order to generate those emails, you need to be able to parse Apex or parse Visualforce and execute the. The Visual Force expressions, and so it will load in any Visual Force pages. It will load in your email templates, Visual Force components, and so if you if you send an email from Apex using a Visual Force template, it will take that email. It'll find the email template and load in the corresponding Visual Force. Component and evaluate the expressions using the defined Apex controller if there is one. So all of that's also built in. Wow. It's already a big map for me, you know. Like back when Salesforce introduced the source format, there was a table, right? Map from the metadata format to the source format. So for each type of the metadata, I know are easy to support in the source format or not. I think for your tool, maybe it's also good if we can have like one-to-one map, so we know what are already supported. I see it's like such a a big scope already you have, but I'm still missing like what things are not possible even technically on your end to support it to run locally, like asynchronous Apex and,
[24:58] for example, governor limits or those things. I guess it's not easy to be done. They're not. They weren't easy, but they are implemented. So there's you're killing me, Chris. Okay, okay, wow. Yes, the asynchronous Apex will work in your test the same way as you'd expect, where they run upon stop test.
[25:29] What's what else? Sorry, what else did you mention besides asynchronous Apex? Oh, governor limits. Governor limits, yeah. Governor limits. Also, it will it will track your your DML calls, your SOQL queries, the number of rows that are queried, and. It even will try to track your CPU usage, and that's a bit tricky because we're not running on the same execution engine or the same hardware. But basically, benchmark against how different operations work on the Salesforce platform to try to have your code. Fail at the same time or roughly the same time that it would if it were running on Salesforce's platform. Wow, I don't know what to say, but it's it's such a big achievement. You really went so far after the the the discussion we had the last time.
[26:36] I would assume there are a lot of company really are interested in this, and especially for the engineers, like the senior engineers, that they really write the code in the, like they really really require fast feedback loop, right? They really want to run it locally. Then it brings such a big benefit. But to me, it's like if one day I want to acquire or to buy the license, I still want to know what things we our code can do or cannot do. For example, I have run your tool against like a solution that I have in my work. Like it has a hundred unit tests, like sixty of them, like six o of them actually pass, and forty, I think majority of the failed forty, just because some Apexes are not pulled to the local because there are too many dependencies on some other files I don't want to do, but only the minority of the tests actually failed and I fired some bugs. You you you fix them. So it seems to be really easy to to get into this, but still, I'm missing like what it cannot do on my end. I don't know if that would be a good read me section. So that is one of the obstacles that people can run into is that there are implicit dependencies in their code base.
[28:02] That they just don't really know about, or they haven't had to deal with yet, because they're always running it against their either production org or a sandbox. And so, you do need to make those explicit by pulling in the making sure that all of your code is in the repo, and any metadata that needs to be there in order for the Apex to run successfully, you'll need to pull in as well. It tries to give you some helpful errors if things are missing. It can't resolve something. There's if you want to just kind of get past those to try it out. There's there's an option to skip errors. So if you if you wanted to just ignore those cases to get started, you could skip those ones that have dependencies on code that's not in the repo yet. The other thing that you may run into challenges with is with managed packages. So, if you have dependencies on managed packages, there, there is well, basically third-party managed packages where you don't have the code for them, right? You've installed the package in your org. There is a command to create mocks for those packages from your org, and so it'll fetch the Metadata that's associated with that package
[29:32] namespace from an org, and it will fetch the stubs that Salesforce creates for the global classes and methods, and create a file, a package, we call a package file that you can load when you're performing when you're running your tests. So it'll make available those those things that are in the namespace. Of the managed package, to your code base, and if your if your code just depends on the metadata within a package, that may just that may work right out of the box. Like you you run this package mock command, and you'll be able to run run your code to use that package. If you have dependencies on calling methods within managed package code, you may need to actually mock those methods. So there's a there's a command to edit those stubs that get created, and if you so you can have it return some. The mock data. Okay, so you have two level of mock, right? If you are really calling into the method of the managed package, which to us is also a black box, you just know the signature. You don't know the details of implementation. For those things, you can also run a command in your tool to mock the data. But under the hood, it's just a static. A text result. You try to swap with with
[31:03] basically without really calling the real method. You just return the mock data. When you're editing it, you're editing Apex, so you can have you can have that mock method be as simple or as complex as you need it. Okay. For example, I worked on a project that used Accounting Seed, and there are some methods in Accounting Seed to Like finalize transactions, accounting sequences, an accounting package that runs on the Salesforce platform, and there are some methods that our tests used to finalize kind of or post a transaction, basically. And so, when we call that method, if our code assumes that calling that method results in DML happening, you can perform that DML in the in the code if. If you don't really care what the side effects are of calling the code, but you expect it to return some value, you can have it return just some stub, mock value that is always the same. Okay. So your tool tries to facilitate as much as possible, even if it's a black box, right? Yeah, tries to let you at least work around that black box, right? And how challenging it is depends on how much your code. Depends on the side effects of calling into that black box, right? Okay. I
[32:33] also, when I run this tool, I see there are some other features. For example, I saw that
[32:41] it can serve as a Salesforce work for other applications that depend on the Salesforce work to to call this local environment. For example, like if I have a website that always calls Salesforce API to get the sales sales related data. Then this Salesforce org actually is like a backend of that website, and here that website now can use your local runtime or this tool to serve instead of calling a real Salesforce org. Is that is that also a feature? Yeah, so there's a server command. So AAR server will start up a server which acts like the Salesforce API endpoint, and you so you can run the Salesforce CLI to log into it. Um, and then you can use the the REST API, the bulk API. It doesn't support all of the API endpoints yet, but the goal is to allow you to treat it as if you were talking to a Salesforce org. So you can, if you wanted to run your tests through. The API rather than using the the test land, you could you could do that, and like yeah, if you're developing an application that uses Salesforce as the backend, you could be developing those both. Offline, you can be having a test against your local Salesforce org that that
[34:12] they're simulating for you. Wow, that's really cool. How about the data in this local org? Can it be persistent, or is it each time when I spin up the serve server command, is it? There, there is a flag to the server command to use a local database file, a SQLite database file, and so it could be persisted. To that database, I haven't come across a use case yet where that's used a lot, and. You know, it's not going to be. It's not meant to be a production environment. It's not meant to replace a Salesforce org. It's it's meant to be a developer's tool while you're developing. So you're not going to want to hit that server talking to the local SQLite database, you know, with hundreds of concurrent connections. You're not going to get right right Salesforce level performance out of it. But for doing local development, yeah, you could persist the data to a database. There is also a flag called bootstrap-db, so dash dash bootstrap-db, which can be used both with the server and with the test command to load in some data into that that ephemeral database whenever it runs, and so that's useful if you have. Things that in your database
[35:42] or in your Salesforce org that can't be represented by metadata, for example, org-wide email addresses. If you have tests that depend on them existing. You can load them in from a SQLite database from the org-wide email address database or table, or if you have some something specific in your, or you want to have some users, for example, that already exist, you can create those in a SQLite database and use that bootstrap flag to load that data into the the database. Wow, that's really amazing! It it it blew me out of the water. I I don't know what to say, but it's such a wonderful tool for the engineers. This is this is really amazing. What's what's the roadmap for this tool? What do you wish it in the future? So, so first, I just wanted to, like I said, wanted to be able to run every Apex. Method that's out there. I want to make sure that it works kind of perfectly as you'd expect. So the first version, 1.0, just came out a little over maybe two weeks ago, I think, and.
[37:04] A lot of the main focus was getting all of the code that I found, either my code that I've worked on in different projects, or open source projects, or some of the early testers, getting all of that code to work. I've been working on more enhancements to. Flag errors before it get you get to Salesforce. So now code that wouldn't work in Salesforce org to make sure it doesn't work in Air as well. So you get the same kind of errors. So you're not writing code locally and and you don't find and then find out that it doesn't actually pass when you get to. Deploying it, so there, there's some, there are more of those kind of edge cases that I'm finding and fixing, because the initial. Scope was getting as much code as I could to run, so now I'm finding the cases where code that shouldn't run also shouldn't run in there. But basically, want to want to track Salesforce's. Updates three times a year. The plan is to release updates so that you're able to keep using all of the new features that Salesforce releases in Air and develop your keep your code up to date and track the latest API versions. Yeah, I almost forget this three times release a year. That's a lot of work to catch up if
[38:34] it's like a major release, like last time I discussed with Andrew Fawcett about the version sixty seven. Right, it's a big security shift. I guess that also must be causing some challenges on your side to to update to align with that version too. Yeah, so an early version of the application didn't even track the API version of the Apex, but I started identifying cases where behavior changed between API versions, and so now when it loads in Apex files or triggers, it also tracks the API version, and it handles those API version specific. Changes, and so yeah. If you load in sixty-seven code, you now get the default user mode changes. Wow. Okay. I don't know what you're doing now, but it's it's like what it's it's like impossible for for I I don't know is this tool like so far is built by you like one person or is it like a team? So so far I've been the the only one working on it. Okay. So. My company, October Swimmer, is primarily or has been primarily a custom development shop.
[40:05] And so that's really what we've been doing. I've been building tools as well for a long time, but you know the bulk of the business has been in custom development. And so I took I took a step back from that last year to focus on on building this application. And so I've just been heads down working on on getting this application built and tested and getting it out. So you mean you you only spent a year you achieved so much? There are some pieces that, like I said, I built on top of the parser for Apex and the parser for formulas, and I had actually started working on a flow runtime. A couple years ago, for a different reason, really to to solve the problem of doing code reviews on flow changes is very painful when it's just like a bunch of XML is changed. So I started building a a local flow runtime that would allow you to check out the branch for a pull request. And kind of execute the flow locally, and so I don't know if any of that code survived, but some of the ideas, anyways, made it into air. Wow, but the the bulk of it's been since since the start of twenty twenty five. Yeah, yeah, okay. What I can
[41:35] say is, I really appreciate your effort. I couldn't imagine that it can go this far. I mean, it was a dream for a lot of people. But when we say, "Hey, Salesforce is is such a ah monolithic org, Apex is just part of it. It's kind of like tangled inside it, like interweaved inside. It's really hard to slice it out. It's almost impossible. But you have achieved, like like almost." This impossible mission is already done, yeah. But they really blow me out.
[42:13] If I may ask, what was the biggest challenge along your journey? I think that's only the author can say. There have definitely been some of those Apex quirks that I've run into that have had me stumped for a bit. There are things like mutable keys in maps behave very weird in Apex. So if you use a custom class as the key.
[42:46] Working with map, working with those maps, you'll get weird results. Things like when you call values or when you call key set on the map, you get you start getting back to different values than you did before you called it. There's some when you call into or you try to get like a field from an S object that hasn't been set. There's some weirdness where if that S object is in a wrapping class like a custom Apex class, it behaves differently. The fact that there are two default namespaces, system and schema, and they behave and they behave differently for different classes. So there are classes like location, address, site, that exist both in the system and the schema namespaces. And if you instantiate a location without the namespace, you're going to get the system location. But if you instantiate a site without a namespace, you get schema site instead. So.
[43:51] Some of those those little quirks for sure. The different the the API version issues. There's like unreachable return statements used behave differently. At some point they changed. Right, but it, I, I, I can totally understand that with the Apex language, which is a a full fledged language, and it it has so many versions along the history. So there must be a lot of edge cases like a normal developer never need to pay attention to, or even never noticed. But until people like you to creating the tooling. Then you start to find out. Okay, there are all these things you need to cover. I think like you or Scott Wells, who created the Illumina Cloud plugin. These these people just start to really dig into those things. Yeah, Scott's actually been help very helpful as well because early on he built. An integration of Air into Illuminated Cloud, and in doing so, he was able to use his existing test suite that he's built up to test Air as well. So he reported a number of bugs and you know weird edge cases. So I'm glad that Scott's been an early adopter as well. Yeah, really glad to hear that you both are collaborating there too. Okay, so before we leave, do you have anything you still want to add?
[45:21] Um, you kind of asked about future goals or direction. Yeah, yeah, yeah. One thing I haven't mentioned is that there's also a Web Assembly version, so you can run the VS Code extension in the browser, and so if you use GitHub dev, you can. Run Apex completely, not just locally, but locally in your browser. The the performance isn't isn't going to be as good as running it on natively on Linux or macOS or Windows. But it is possible for you to step through code in your debugger or run all of your Apex tests in the browser. And with the new Web Console. I'm trying to to encourage them to support extensions, which would allow using Air within the new Salesforce Web Console because it is a version of VS Code of the the VS Code Web, and so.
[46:24] I was able to get it working in kind of a development mode where I could I could load Air into the web console, but until they officially support extensions, it's not it's not really possible. But I think that's kind of an interesting idea. You'll not just be able to view your Apex from your directly from an org, but execute it, step through it, debug it. Yeah, I think I forgot to to ask you about this local debugger you mentioned at the the very beginning. I think that's circling back, which is also good. So, because Salesforce has this replay feature, right? It can lock all the Apex finest lock into your local, then you kind of like replay on that lock information. Then you can stop at some point. But on your end, because it's local work, so you can determine. It's like a real local stopper here, right? You can set the points and break it there when you execute. But now you set VS Code has this web version, which do not run it in local. I think that has been a feature for many years already. But Salesforce start to use that to for the Salesforce development, and your assembly version can be a plugging on that. Is that what you are trying to achieve? So there's an error VS Code extension which you can install in normal VS Code on your desktop. Okay, but VS
[47:54] Code also supports web extensions, which is it's an extension that doesn't require. Any local execution on your computer, just it runs entirely in the browser, and so when you when you use there's there's VS Code dev, and there's GitHub dev, which is another version of the the VS Code web version. That it will support the Air. Extension, and it will load a WebAssembly version of Air. So instead, it's a Airs compiled to Linux on ARM and AMD sixty four and macOS and Windows. But it's also compiled to WebAssembly and will run in the browser using the VS Code extension. That's a really neat feature. I guess GoLang natively support this. If you can compile to a binary with some limited plugins, then you can easily translate into a web assembly. Is it so? Yeah. So Go has web assembly as a target, so you can right compile to web assembly. Oh, that's wonderful. Okay, I'm gonna give it a try maybe later. It's it's it's cool to see. I mean, it's probably not going to be your daily use because, like I said, the performance isn't going to be as good. It's single threaded, whereas
[49:25] the the native version will use all of your CPU cores if it can try to use all as much memory as it can to run your tests as fast as possible. The the Web Assembly version is not going to be as performant. Okay, cool. I guess we have covered a lot about the tool, and I get really impressed by your tool. I would say this probably the number one tool I discussed so far. It's it's such a vast scope, and you have achieved. Really, congratulations to to you. Achievement, so I will put your LinkedIn this GitHub link and also your company OctoberSwimmer dot com is it so all these link I will put it on our show notes. I appreciate your effort again, and thanks a lot, Chris. Maybe we can chat next time. Thanks, great talking to you. Yeah, bye bye, Chris. Bye bye.
