Hacker Newsnew | past | comments | ask | show | jobs | submit | karthikksv's commentslogin

Orum | Full-stack developer | Remote (US only) | Full-time | https://orumhq.com/

Orum connects sales teams to their target prospects efficiently, helping them sell to their ideal customers. Using Orum's parallel dialer, sales reps can dial multiple numbers at once, and Orum's speech recognition will automatically recognize and connect reps with humans that pick up. This leads to consistent conversations, faster training, and more meetings booked.

We're a small, fully remote team that bootstrapped to almost $1M ARR in two years. Our business is young but growing quickly, and customers use our product daily (~10,000 calls/day).

This role is ideal if you like to work across the stack to make a big impact on a small team. You'll be in charge of building and owning features end-to-end, from conception to implementation to feedback/iteration. Examples include routing calls through our event-based SIP softswitch, displaying real-time call information in our UI over WebSockets, or processing streaming audio for speech recognition.

What we would love to see:

- At least 2 years of full-time, full-stack engineering experience

- Past work that shows comfort with both back-end and front-end

- Familiarity with our stack: TypeScript, Node.js, React and PostgreSQL

- You like working closely with product/sales to drive customer success

- You’re not afraid to say “I don’t know” and proactively learn new things

- You are based in the USA. This position is not open in other countries.

To apply, please reach out to jobs@orumhq.com with your resume.


Orum | Full-stack developer | Remote (US only) | Full-time | https://orumhq.com/

Orum connects sales teams to their target prospects efficiently, helping them sell to their ideal customers. Using Orum's parallel dialer, sales reps can dial multiple numbers at once, and Orum's speech recognition will automatically recognize and connect reps with humans that pick up. This leads to consistent conversations, faster training, and more meetings booked.

We're a small, fully remote team that bootstrapped to almost $1M ARR in two years. Our business is young but growing quickly, and customers use our product daily (~10,000 calls/day).

This role is ideal if you like to work across the stack to make a big impact on a small team. You'll be in charge of building and owning features end-to-end, from conception to implementation to feedback/iteration. Examples include routing calls through our event-based SIP softswitch, displaying real-time call information in our UI over WebSockets, or processing streaming audio for speech recognition.

What we would love to see:

- At least 2 years of full-time, full-stack engineering experience

- Past work that shows comfort with both back-end and front-end

- Familiarity with our stack: TypeScript, Node.js, React and PostgreSQL

- You like working closely with product/sales to drive customer success

- You’re not afraid to say “I don’t know” and proactively learn new things

- You are based in the USA. This position is not open in other countries.

To apply, please reach out to jobs@orumhq.com with your resume.


I had this same inspiration from Chris McCord's talk about LiveView ~1.5 years back, and created Purview: https://github.com/karthikv/purview - we've been using it in production at the company I work at for over a year now.

It's great to see a similar mindset here, and I hope an approach like this becomes more widely used. I appreciate how Caldera is built using React's reconciler and is centered around hooks, both of which are different than the approach Purview takes.

Two of the challenges we've experienced here:

- Transferring server-side state between processes: in production, you'll likely have multiple Node processes handling requests via the cluster module or other load balancing. If a client were to disconnect their websocket temporarily (e.g. put their laptop to sleep), they can be reconnected to a different process, which doesn't have the state of their components. As a result, you'll need some way to transfer/persist component state between processes. This same issue will also arise during deploys--you'll spawn new processes with your new code, but you don't want to disrupt existing clients, so those new processes need to load existing component state from old processes. Even more subtly, this issue can occur on page load, since two requests need to be made: one to fetch the initial page and one to initiate the websocket connection. Those two requests can be sent to two different processes/boxes.

- Working with existing client-side libraries, like selectize or date range pickers. We've opted to use the Web Component spec to create custom tags that can be sent down just like normal tags from the server, but making sure these interoperate nicely with server-side state is challenging.

Very excited to see how Caldera tackles these problems!


Great minds think alike! I had a feeling this was a relatively straightforward insight, and Purview looks like a pretty cool implementation.

To answer your questions:

1. We have a mechanism to serialize the React state tree, as long as it can be copied with the HTML structured clone algorithm (https://github.com/calderajs/caldera-react/blob/master/src/s...) which has always seemed to be the case in practice. Each tree is associated with a unique token which is stored on the client, but the current storage implementation is in-memory only as we haven't addressed the application upgrade issue. Outside of that, there's nothing stopping us from adding basic versioning (along with react-hot-loader-like reconciliation behavior) and moving the state storage to a database that is shared among application servers.

2. This isn't really fleshed out yet, but we'd likely take inspiration from React Native's native module approach where lifecycle events for mounting/unmounting/updating a component are implemented on the client, with bindings being called in the server application code (a React-specific version of your web component implementation). I know we're against high-level RPC, but React props naturally have a data/async callback structure that is amenable to being represented as RPC calls (which works for React Native), which is why we're leaning towards that approach.


For the first problem what about the option of making the session:backend-instance mapping sticky? Seems it could be simpler than the implementing the state handover.


Dialbot | Full-stack developer | Remote (US only) | Full-time | https://dialbot.co/

We’re a small, fully remote and self-funded company that helps sales teams connect with prospects faster over the phone. Our customers use our product daily (~10,000 calls/day) and give us regular feedback. Because we’re self-funded, we avoid the hyper-growth of traditional VC startups, and we believe a few people can accomplish a great deal. We validate before we build, work on our own schedule, and execute on a focused vision.

This role is ideal if you like to work across the stack, routing calls through our event-based SIP softswitch, displaying real-time call information in our UI over WebSockets, or processing streaming audio for speech recognition. We use TypeScript/Node.js, Ruby, React, and Postgres.

What we’d love to see:

  - At least 2 years of full-time engineering experience
  - Past work that shows you’re comfortable with both back-end and front-end
  - You like working closely with product and sales to drive customer success
  - You’re not afraid to say “I don’t know,” but that doesn’t stop you from learning
Please reach out at eng@dialbot.co, and feel free to include your resume, why you’re interested, and anything else that’s relevant.


All the business logic of the components (i.e. event handlers, lifecycle hooks, setState() calls, etc.) run on the server, unlike just the initial server-side rendering that Next.js provides. The server maintains the state of all components, and when an event occurs, the client notifies the server to run the appropriate event handler.


Perhaps I could've explained myself better. I meant that all the business logic of the components (i.e. event handlers, lifecycle hooks, setState() calls, etc.) run on the server, unlike just the initial server-side rendering that React provides. The server maintains the state of all components, and when an event occurs, the client notifies the server to run the appropriate event handler.


Ah! I see what you mean. It reminds me of https://github.com/airbnb/hypernova


A common criticism I heard about React a few years back was combining JS and HTML within the same file, as opposed to having them separate. As with most decisions, I think separation is an important trade-off you need to consider: it's easier to reason about the individual, separated parts that are well-contained, but it becomes harder to reason about the system as the whole.

If you have a complex front-end and back-end with a REST API, each time you modify a server route, you need to find all instances in your client where you make an AJAX request to that route and change them appropriately. The potential for inconsistency can cause numerous bugs.

GraphQL solves this by having a very flexible and standardized server (albeit complex), giving your client access to arbitrary structured information using a query language.

Purview solves this by moving your logic to the server-side, where you can access your database directly. Because everything runs on the server, the client-server interface is abstracted away, and you don't need to worry about using GraphQL or REST. You can make database queries, contact external services, etc. directly within your components.

To keep this maintainable, you split up your page into logical, reusable components, just like you would with React, and each component now not only contains your view logic, but also the server-side logic. Given that you've decomposed your components well, this makes it easy to reason about the whole system when it comes to any part of your page.


This is how cold fusion works, written by Adobe for too steep of a price. I wonder if we are just running circles around the same ideas. Are we really moving the ball with Purview? I’m lost.


> If you have a complex front-end and back-end with a REST API, each time you modify a server route, you need to find all instances in your client where you make an AJAX request to that route and change them appropriately. The potential for inconsistency can cause numerous bugs.

Sorry, but any sane codebase usually abstracts away HTTP info like routes through services which means that your components only know about the dataService and don't care if the data is coming from a REST API or localStorage


We've been using this in production at the company I work at for about the past ~1.5 months. We've gone through a fair number of fixes and improvements throughout that time (bugs, race conditions, performance, etc.). It's definitely still a nascent project, but we're excited to continue using Purview and developing it. Would love to get your thoughts if you try it out sometime.


Yes, that was my inspiration! Chris gave a great talk about it at ElixirConf is anyone is interested in watching: https://www.youtube.com/watch?v=Z2DU0qLfPIY

Some differences compared to LiveView:

- Type-checking: there are extensive JSX typings (https://github.com/karthikv/purview/blob/master/src/types/js...) that ensure you're attaching event handlers with the correct signatures, specifying supported props, using valid HTML tags and attributes, etc. Static-typing guarantees are one of my big priorities.

- I'm not sure if LiveView intends to support nested components like React does. Having the ability to split up complex pages into components that you can nest and reuse (with mostly one-way data flow) is a key part of maintainability. I wanted to maintain a very familiar React interface, so you can pick up Purview quickly if you're comfortable with React.


Neat project! We indeed support nesting in LiveView :)


Thanks for chiming in Chris! If you don't mind, I have a few implementation questions about LiveView:

- I noticed that you said you use morphdom for LiveView. I originally started with this too, but found that the DOM diffing doesn't work well with any client-side JS that may modify the page (e.g. a date picker, a tooltip library, a custom dropdown, etc.). I ended up switching to snabbdom (https://github.com/snabbdom/snabbdom/), a virtual DOM implementation, to avoid updating parts of the page that the user doesn't directly intend to modify. This helps with client-side interop, and it also gave us a nice boost in performance. Did you run into any similar issues with LiveView? Do you still use a DOM diff rather than a virtual DOM diff?

- On that note, what's the recommend way to interop with client-side libraries like I mentioned earlier? We use the WebComponents custom-elements spec to define custom tags that encapsulate client-side JS logic (e.g. we have an <audio-player>, a <date-picker>, etc.), and then in our Purview components we can just send down these tags. We also had to provide the ability to integrate with DOM events triggered by these custom elements. Is there a recommended approach in LiveView to integrate with these libraries?

- With respect to nesting in LiveView, do you call live_render() directly within a view's render() function? Do you pass props in this call? There doesn't seem to be a differentiation between props and state for LiveView--are both consolidated into "assigns"? Hence both are mutable? I'm aware that you use immutable data structures in Erlang/Elixir, but I mean in the sense that you can assign a different value to a prop that was given to you by your parent. If this is the case, how would that work if there's a re-render and the prop passed by the parent changes?



You should have a look at JSF (Java Server Faces) that explored, and failed miserably, in the same context for the last 15 years or so. (Probably less, dunno)


You're not required to use TypeScript. As janpot mentioned, the library is transpiled prior to being published on npm, so you can use it with regular JavaScript. This is true of most TypeScript libraries.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: