Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Oct 24 16:48

    papandreou on master

    Fix doc typos (compare)

  • Sep 08 08:40
    papandreou commented #784
  • Sep 08 08:09
    pingvinen commented #784
  • Aug 22 05:39

    papandreou on master

    13.0.1 (compare)

  • Aug 22 05:39

    papandreou on v13.0.1

    (compare)

  • Aug 22 05:34

    papandreou on toSatisfyUndefinedProp

    (compare)

  • Aug 22 05:34

    papandreou on master

    Fix bug that caused expect({foo… Merge pull request #852 from un… (compare)

  • Aug 22 05:34
    papandreou closed #852
  • Aug 20 14:06
    papandreou assigned #852
  • Aug 20 14:06
    papandreou opened #852
  • Aug 20 14:05

    papandreou on toSatisfyUndefinedProp

    Fix bug that caused expect({foo… (compare)

  • Jul 09 14:26

    papandreou on master

    Fix CHANGELOG generation in pre… (compare)

  • Jun 05 12:09

    papandreou on master

    Unskip test that succeeds now w… (compare)

  • May 31 05:48
    papandreou synchronize #784
  • May 31 05:47

    papandreou on camelCase

    Sketch out some basic tests Slow, naive implementation of t… Support camel case syntax withi… and 16 more (compare)

  • May 31 05:41

    papandreou on master

    Fix typos in test descriptions (compare)

  • May 31 05:28
    papandreou synchronize #784
  • May 31 05:28

    papandreou on camelCase

    Clean (compare)

  • May 30 22:10
    papandreou synchronize #784
  • May 30 22:10

    papandreou on camelCase

    simplify (compare)

Sune Simonsen
@sunesimonsen
Screenshot 2022-06-17 at 09.25.25.png
I'm creating type definitions and docs to @dependable/state using JSDocs, that seems to work out pretty well.
I know it isn't the modern way 😅
Sune Simonsen
@sunesimonsen
(actually not using jsdoc, but just the TypeScript compiler)
Gustav Nikolaj
@gustavnikolaj
I've been doing that a lot too actually! It works really nicely with the code intellisense in vs code.
Sune Simonsen
@sunesimonsen
Yes and being able to generate docs is also nice, but without having any transpilation :-)
Joel Mukuthu
@joelmukuthu

Development Experience and motivation is important. But the trend in later years moving more and more functionality into, or making it dependent on, tooling is making it harder and harder to accomodate. If the cost was only the difference between having code written in 1 or 2 frameworks (or 4 or 5) then it's no problem. But when all new frameworks wants to own transpilation and bundling as well? The more integrated a new "framework" is, the higher the cost.

The cost of trying something like @sunesimonsen's new experiment here is low, while trying out Svelte is going to be more expensive.

Makes perfect sense. Thanks guys for sharing what you've learnt from your various experiences!

I was also bootstrapping a project two years ago and wanted typescript and I was pretty much forced to go all the way with their conventions. I do miss unexpected though and tbh I think not having it has negatively affected my code coverage on that project

Yes and being able to generate docs is also nice, but without having any transpilation :-)

@sunesimonsen bro just do typescript :grin: there's a bit of buy-in cost but you'll reap a lot of benefits especially once it picks up speed and you get more collaborators

Gustav Nikolaj
@gustavnikolaj
I'm curious of the benefits @joelmukuthu. I'm still not sold on TypeScript - beyond the improved DX of better intellisense in the editor, it doesn't seem that you get much from it. You don't get anything in terms of runtime guarantees, and thus the "types" you get from typescript is no better than the inpute validation you do at your edges.
Sune Simonsen
@sunesimonsen
@joelmukuthu I might if I wasn’t creating these micro libraries where I need to control everything to make them as small as possible. I also know Preact had to give up on rewriting in TypeScript. I’m not really looking for contribution to the libraries, the are small enough that I can manage on my own 😅
1 reply
Gustav Nikolaj
@gustavnikolaj
lol. I'm going to retire. Getting create-react-app with typescript working with storybook is apparently too much for me. :)
image.png

All I have done is literally the following two commands, with a bit of git commands inbetween.

  1. npx create-react-app my-app --template typescript from https://create-react-app.dev/docs/adding-typescript/
  2. npx storybook init from https://storybook.js.org/docs/react/get-started/install

And they can still not manage to get it to work.

Isn't this supposed to be the happiest of happy paths?
Joel Mukuthu
@joelmukuthu

I'm curious of the benefits @joelmukuthu. I'm still not sold on TypeScript - beyond the improved DX of better intellisense in the editor, it doesn't seem that you get much from it. You don't get anything in terms of runtime guarantees, and thus the "types" you get from typescript is no better than the inpute validation you do at your edges.

Off the top of my head: improved code quality. It helps junior developers write code somewhat similar to the more senior devs -- after getting used to writing code in typescript in the first place. It also frees up a bit of time for code reviewers. We're a pretty small team right now (4) but I see these benefits scaling.

We've only been bitten once (in 2 years) by the lack of run-time checks and that wasn't even from an external library messing things up, but rather from some change in header values from Cloudflare. I think the lack of run-time checks actually forces us to write better code -- at least better types. For example if a type declares something to be nullable, then you're forced to add a run-time check for that thing

Also something really incredibly time-saving has been using codegens to generate types for graphql operations on the client. That's helped catch a lot of bugs before they leave a devs machine
Gustav Nikolaj
@gustavnikolaj

I think the lack of run-time checks actually forces us to write better code -- at least better types

Hehe, good news, JS doesn’t have any run-time checks, other than what you add yourself. ;)

I think the types and lack of runtime checks is a bit of a footgun.

I think you could provide some of the same guidance using a linter. VS Code has grown pretty good at inferring types in javascript, especially if you actually write the runtime checks which you need anyway in ts.

Gustav Nikolaj
@gustavnikolaj
I’m sure there’s value there - but I also see indications of cargo culting in the community.
Gustav Nikolaj
@gustavnikolaj
I’m pretty hyped for the types-as-comments proposal though. Seems like a perfect compromise.
Joel Mukuthu
@joelmukuthu

I think the types and lack of runtime checks is a bit of a footgun.

Absolutely. The typical ts setup will also include a tsc -noEmit "lint" step on CI or somewhere. But yeah, ts will still do a pretty good job of type-checking plain JS code and it'll also consume JSDoc comments so that's a pretty solid setup. And even then you could still also augment it with independent type declaration files to reap all the benefits -- that just comes at a slightly higher maintenance cost

Joel Mukuthu
@joelmukuthu
I went to verify if there was a way types-as-comments supported generics, and my search led me here https://github.com/tc39/proposal-type-annotations. It's still pretty early stage but what do you think?
Gustav Nikolaj
@gustavnikolaj
If I understood and remember correctly, the tc39 proposal is only about extending the syntax to allow for types between : and = in const foo: string = “foobar”; and a interface structure as well.
So there’s space for different implementations on top of that.
Gustav Nikolaj
@gustavnikolaj
FWIW I found the solution to my problems with cra/ts and storybook. It turns out that the issue was a bad interaction between npm v8 and storybook. Storybook dependent on the old peerDependency functionality from npm v7 and older, and it caused it to break for me. It's reported here and there's a workaround, and a promise of a fix for the next major version: storybookjs/storybook#18298
Sune Simonsen
@sunesimonsen

New Dependable State with types and API docs :love_letter:
https://dependable-state-api.surge.sh/modules/state.html

I'll update dependable view with the same kind of types and docs when I have some time.

Sune Simonsen
@sunesimonsen
Screenshot 2022-06-20 at 16.29.47.png
Gustav Nikolaj
@gustavnikolaj
Looking very nice!!
Sune Simonsen
@sunesimonsen
Thanks
Sune Simonsen
@sunesimonsen

TodoMVC (source) running on @dependable/view
New API docs and types.

Don't know if the types will actually work with TypeScript - haven't made an example yet.

Gustav Nikolaj
@gustavnikolaj
  1. Why is the api functions wrapped in an observable? https://github.com/sunesimonsen/dependable-example-todomvc/blob/main/public/model.js#L4
  2. You use the module system to access a singleton state object. Would this also be your preferred solution in a real app? https://github.com/sunesimonsen/dependable-example-todomvc/blob/main/public/components/TodoList.js
Sune Simonsen
@sunesimonsen
I'm trying to figure that out, but this gives me a very easy way of mocking the api, I just replace it.

You use the module system to access a singleton state object. Would this also be your preferred solution in a real app?

Yes - I think most application state is global and can be modelled as a global state in a declarative way.

Gustav Nikolaj
@gustavnikolaj
I try to avoid having the state in a global singleton as I find it makes it pretty hard to mock in tests
3 . Is babel required for this to work?
Sune Simonsen
@sunesimonsen

3 . Is babel required for this to work?

No, I just use it to transpile htm out of the picture.

Gustav Nikolaj
@gustavnikolaj
So it could be a production only step
Looking good :)
I think I might opt to pass more things around as props, but there's nothing preventing me from doing that.
Sune Simonsen
@sunesimonsen

I try to avoid having the state in a global singleton as I find it makes it pretty hard to mock in tests

You would think so, but I'm using https://www.apollographql.com/docs/react/local-state/reactive-variables/ at work and we just set the state before the test and it works really well :-)

I think I might opt to pass more things around as props, but there's nothing preventing me from doing that.

That is really no reason and it makes for more re-rendering. Using the observables and computeds directly only re-renders components that is actually affected.

I'm adding tests to the example now, so you can see how that looks afterwards
Gustav Nikolaj
@gustavnikolaj
I might have to give it a shot. My gut-feeling is very much opposed to it, but I cannot find any reasonable arguments for why it shouldn't be all right. It's not like we're ever going to have more than one UI rendering at the same time from the same browser :)
Looking forward to the test examples <3
Sune Simonsen
@sunesimonsen

going to have more than one UI rendering at the same time from the same browser

what you might run into is that you need more instances of something, but they you will just have global state holding models for those. Similar to how I have a lists of todo classes in an observable. .

Gustav Nikolaj
@gustavnikolaj
It means that the components are very closely tied to that global state model, rather than having props as interface. But yeah, I get your point. Realistically, most things aren't really ever going to be used outside that initial place.
Just noticed something weird.
  1. Add a todo item "foo"
  2. Add a todo item "bar"
  3. With the cursor in the todo input field, press TAB then SPACE

Expected: I can see a focus indicator, and the first item would be selected, and completed when space is selected|

Actual: No focus indicator, both items are completed

Sune Simonsen
@sunesimonsen
Yes I expect the example to be a bit bugging - slammed it together really quickly - I'll come back and brush of things.
Example of a simple state test, if you are curious:
import {
  allTodos,
  createTodo,
  visibilityFilter,
  visibleTodos,
  Todo,
} from "../public/model.js";

import unexpected from "unexpected";
import unexpectedDependable from "unexpected-dependable";

const expect = unexpected.clone().use(unexpectedDependable);

describe("visibleTodos", () => {
  describe("with an empty list of todos", () => {
    beforeEach(() => {
      allTodos([]);
    });

    it("returns an empty array", () => {
      expect(visibleTodos(), "to equal", []);
    });
  });

  describe("with list of todos that is all completed", () => {
    beforeEach(() => {
      allTodos([
        new Todo({ id: 0, text: "By milk", completed: true }),
        new Todo({ id: 1, text: "Paint the fence", completed: true }),
        new Todo({ id: 2, text: "Mow the lawn", completed: true }),
      ]);
    });

    describe("and the visibility filter is active", () => {
      beforeEach(() => {
        visibilityFilter("active");
      });

      it("returns an empty array", () => {
        expect(visibleTodos(), "to equal", []);
      });
    });
  });
});