Skip to content
This repository has been archived by the owner on Oct 1, 2024. It is now read-only.

🍪react-cookie package #1002

Merged
merged 11 commits into from
Sep 27, 2019
Merged

🍪react-cookie package #1002

merged 11 commits into from
Sep 27, 2019

Conversation

cartogram
Copy link
Contributor

@cartogram cartogram commented Sep 16, 2019

Description

This PR adds a @shopify/react-cookie library that gathers cookies from both the server and client. There are three main components to this library, 1) A universal-provider that provides a set of initial cookies and instantiates 2) a manager. This manager provides common methods for getting/ setting cookies both internally, and in the document. 3) Finally, there are 2 common React hooks for operating on the cookies from within a React component.

Demo/ Tophat

You can view a demo here from this branch of @shopify/web-rails-proving-ground

If you want to tophat yourself, pull down this branch and also the cookies branch from web-rails-proving-ground.

  1. dev up in the cookies branch of web-rails-proving-ground
  2. From the quilt repo run:
cp -R packages/react-cookie/src/ ../web-rails-proving-ground/packages/\@shopify/react-cookie
cp -R packages/react-network/src/ ../web-rails-proving-ground/packages/\@shopify/react-network
cp -R packages/react-server/src/ ../web-rails-proving-ground/packages/\@shopify/react-server
  1. Then run dev run in the web-rails-proving-ground repo.

@cartogram cartogram changed the title react-cookie-package react-cookie package Sep 16, 2019
@cartogram cartogram requested a review from marutypes September 16, 2019 14:33
@@ -0,0 +1,85 @@
# `@shopify/react-cookie`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just roughed this out for completeness, but will put some more ❤️ into this Readme either before or immediately after merging.

@cartogram cartogram changed the title react-cookie package 🍪react-cookie package Sep 16, 2019
Copy link
Contributor

@marutypes marutypes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of the stuff going on in the Cookie component looks weird / suspect, and I'd like some rationale for why we rebuilt all of this instead of just hooking up something like universal-cookie to react-network.

Overall this looks pretty close either way.

packages/react-cookie/src/hooks.ts Show resolved Hide resolved
packages/react-cookie/src/hooks.ts Outdated Show resolved Hide resolved
packages/react-cookie/src/manager.ts Outdated Show resolved Hide resolved
@cartogram
Copy link
Contributor Author

@TheMallen on doing our own thing vs third-party: this library allows us to provide a cookie solution for applications devs that uses consistent patters as with the other quilt packages that also require similar client/server interaction (self-serializer, react-effect, network, etc…) . Going this route also requires no server-side middleware and everything is confined to only this package (and really one component) rather than requiring orchestrated changes across @shopify/react-server, @shopify/sewing-kit, etc.

Less important, there is only one viable third-party solution out there (the universal-cookie/ react-cookie stack) and I wasn’t the biggest fan of the imperative change-listener way that those libraries operate. I wanted to explore a way that we could leverage our own libraries to provide something better.

That said, I get that additional code is a liability (even given this library is pretty tiny) and understand the hesitation to introduce this package.

packages/react-cookie/README.md Outdated Show resolved Hide resolved
packages/react-cookie/src/Cookie.tsx Outdated Show resolved Hide resolved
packages/react-cookie/src/Cookie.tsx Outdated Show resolved Hide resolved
@cartogram cartogram force-pushed the react-cookie branch 2 times, most recently from 429941c to b6b8c6d Compare September 18, 2019 03:40
@cartogram cartogram requested a review from marutypes September 18, 2019 15:30
Copy link
Contributor

@marutypes marutypes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this again I think we need this to depend on @shopify/react-network or live as part of that if we want it to work holistically.

packages/react-cookie/src/CookieUniversalProvider.tsx Outdated Show resolved Hide resolved
packages/react-cookie/src/CookieUniversalProvider.tsx Outdated Show resolved Hide resolved
packages/react-cookie/src/manager.ts Outdated Show resolved Hide resolved
@cartogram cartogram requested a review from marutypes September 20, 2019 17:10
Copy link
Contributor

@marutypes marutypes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few questions / changes but this is looking really nice now

packages/react-cookie/README.md Outdated Show resolved Hide resolved
packages/react-cookie/src/CookieUniversalProvider.tsx Outdated Show resolved Hide resolved
packages/react-cookie/src/context.ts Outdated Show resolved Hide resolved
packages/react-cookie/src/UniversalCookies.ts Outdated Show resolved Hide resolved
packages/react-cookie/src/UniversalCookies.ts Outdated Show resolved Hide resolved
packages/react-cookie/src/tests/cookie.ts Outdated Show resolved Hide resolved
packages/react-network/src/manager.ts Outdated Show resolved Hide resolved
@cartogram cartogram force-pushed the react-cookie branch 2 times, most recently from f26304d to 4246229 Compare September 23, 2019 14:35
@cartogram
Copy link
Contributor Author

@TheMallen another look when you get a chance 🙇 Still doing a final comb through all the Readme, but otherwise all changes are in.

@cartogram cartogram requested a review from marutypes September 23, 2019 15:44
Copy link
Contributor

@marutypes marutypes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still feel a bit weird about where some of this is, @GoodForOneFare what do you think?

packages/react-cookie/README.md Outdated Show resolved Hide resolved
packages/react-cookie/README.md Outdated Show resolved Hide resolved
packages/react-cookie/src/server.ts Outdated Show resolved Hide resolved
packages/react-network/CHANGELOG.md Outdated Show resolved Hide resolved
packages/react-cookie/README.md Outdated Show resolved Hide resolved
packages/react-cookie/src/BrowserCookieManager.ts Outdated Show resolved Hide resolved
packages/react-network/src/ServerCookieManager.ts Outdated Show resolved Hide resolved
packages/react-cookie/src/BrowserCookieManager.ts Outdated Show resolved Hide resolved
Object.entries(cookies).forEach(([cookie, options]) => {
const {value, ...cookieOptions} = options;

ctx.cookies.set(cookie, value, cookieOptions as any);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


export {CookieContext} from './context';

export class BrowserCookieManager {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is consistent with the rest of Quilt, but I miss the lint rule for "this isn't really a class".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this could easily just be a constant object exported directly since it doesn't have any local state. Doesn't matter too much.

.vscode/settings.json Outdated Show resolved Hide resolved
packages/react-cookie/server.d.ts Outdated Show resolved Hide resolved
@cartogram cartogram force-pushed the react-cookie branch 2 times, most recently from 969324c to a2eb6aa Compare September 24, 2019 21:54
@cartogram cartogram force-pushed the react-cookie branch 6 times, most recently from 3b12aea to 9bef59d Compare September 25, 2019 01:10
@cartogram
Copy link
Contributor Author

cartogram commented Sep 26, 2019

@TheMallen @GoodForOneFare All changes have been addressed. I also included:

  • A react-server test that sending cookies with the request will be accessible via the client-side hooks.
  • Added the UniversalCookieProvider to our default providers
  • Tests for ServerCookieProvider
  • Tests for the react-network /server component
  • More docs for all the changed things
  • Utils for creating and clearing cookies in tests
  • probably much more that I am forgetting

The only way I was able to tophat this successfully was by building each library (react-server, react-cookie and react-network) and copying them into web-rails-proving-ground's node_modules. There is a branch there called cookies that has some application code for testing the hooks in this package.

Thanks again for your continual feedback and patience!

Copy link
Contributor

@marutypes marutypes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few nits but this looks great IMO.


export {CookieContext} from './context';

export class BrowserCookieManager {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this could easily just be a constant object exported directly since it doesn't have any local state. Doesn't matter too much.

manager.setCookie(key, {value, ...options});
};

return [cookie, setCookie];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I like the consistency with koa of doing set('name', null) as long as it's documented

}

it('provides a universal cookie manager for the server', () => {
hasDocumentCookie.mockImplementation(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might want to add a 'why' comment explaining why we have to mock this (so that we can test the server implementation despite jest always having a document.cookie defined)

<MockComponent cookie="foo" setValue={setValue} />,
);

wrapper.find('button')!.trigger('onClick');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this spacing is a bit weird IMO

</>
);
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also document the test utilities we export?

Copy link
Member

@GoodForOneFare GoodForOneFare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did not 🎩 but it looks like this should work 👍 😅

manager.setCookie(key, {value, ...options});
};

return [cookie, setCookie];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it makes sense to follow our rule, I guess it's fine. I'm not 100% sure about how strict we about following it.

Is there any kind of type-hint we can provide like:

export const UNSET = '';
...
setCookie(name: string, value: string | CookieValue | UNSET)

Eww :/

@cartogram cartogram merged commit 0bc5704 into master Sep 27, 2019
@cartogram cartogram deleted the react-cookie branch September 27, 2019 04:25
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants