Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: bump node, rethinkdb-ts, typescript, uWS #7780

Merged
merged 7 commits into from Feb 21, 2023
Merged

Conversation

mattkrick
Copy link
Member

@mattkrick mattkrick commented Feb 16, 2023

Description

  • Need to bump node for security (plus i want to use lastIndexOf
  • typescript needs to get bumped to also use lastIndexOf
  • uWS needs to get bumped to work with node v18
  • rethinkdb-ts-migrate will need to get bumped because node v18 streams has a getter called closed that conflicts. EDIT: i can just resolve rethinkdb-ts to a higher version & it works great.

Demo

Everything just works 🤞

Test

biggest changes are with uWS, so test refreshing the page, subscriptions, etc.

@mattkrick mattkrick changed the title chore: bump node, rethinkdb-ts, typescript chore: bump node, rethinkdb-ts, typescript, uWS Feb 16, 2023
@github-actions github-actions bot added size/m and removed size/s labels Feb 16, 2023
@@ -36,7 +36,7 @@ const defaultExecutor: Executor<{
})
clearTimeout(timeout)
const resJSON = (await result.json()) as EndpointExecutionResult | {message?: string}
if ('data' in resJSON || 'errors' in resJSON) return resJSON
Copy link
Member Author

Choose a reason for hiding this comment

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

I think I found a bug in typescript!
...or I'm just an idiot.
Either way, I made an issue for it here: microsoft/TypeScript#52812

Copy link
Contributor

Choose a reason for hiding this comment

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

oh wow

Let's change the code to the a little bit easier to read equivalent of if ('data' in resJSON || 'errors' in resJSON) return resJSON

    if ('data' in resJSON) return resJSON
    if ('errors' in resJSON) return resJSON

TS complains because data is a mandatory property, and technically the second case indicates the data is not defined.

Let's follow the code execution of if ('data' in resJSON || 'errors' in resJSON) return resJSON

  1. if data is in the resJSON it'll go straight to return resJSON as there's no need to check second condition in the or logical statement if first part is true, the returned type will be { data, errors? }
  2. the second part of the logical or will be executed only if data is not in the resJSON, meaning it'll return a type { errors }, and TS will complain as data is mandatory

Here's what happens in the reversed version ie. if ('errors' in resJSON || 'data' in resJSON) return resJSON

  1. if errors is in the resJSON and type narrowing assumes if the optional property of type is there, then the mandatory has to be there
  2. the second part will be executed only if there are no errors, and if true the returned type will be { data } which is a valid return type

I still get Property 'data' is missing in type '{ message?: string | undefined; } & Record<"errors", unknown>' but required in type 'EndpointExecutionResult'.ts(2322) error on master here but VS code sometimes is misleading so I created a TS playground

  1. Using TS 4.6.4

Screenshot 2023-02-21 at 08 55 14

  1. Using TS 4.9.5

Screenshot 2023-02-21 at 08 55 29

and seems like the way type narrowing works has changed, actually!

if (!ws.connectionContext) return
ws.done = true
const handleClose = (ws: WebSocket<SocketUserData>) => {
const userData = ws.getUserData()
Copy link
Member Author

Choose a reason for hiding this comment

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

with the new version of uWS, we can't just assign objects to the WebSocket object. we have to get a UserData object off of it & assign our stuff there.

import ConnectionContext from '../socketHelpers/ConnectionContext'
import keepAlive from '../socketHelpers/keepAlive'
import {sendEncodedMessage} from '../socketHelpers/sendEncodedMessage'
import handleConnect from './handleConnect'

const APP_VERSION = process.env.npm_package_version
export type SocketUserData = {
Copy link
Member Author

Choose a reason for hiding this comment

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

tbh, i kinda like that they make us do this. it's more explicit.

@@ -6,7 +6,7 @@ import getQueryToken from '../utils/getQueryToken'
import sendToSentry from '../utils/sendToSentry'
import uwsGetIP from '../utils/uwsGetIP'

const handleUpgrade: WebSocketBehavior['upgrade'] = async (res, req, context) => {
const handleUpgrade: WebSocketBehavior<void>['upgrade'] = async (res, req, context) => {
Copy link
Member Author

Choose a reason for hiding this comment

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

during upgrade we don't have any UserData yet, so this is the exception where we use void

@mattkrick mattkrick marked this pull request as ready for review February 16, 2023 22:36
Copy link
Contributor

@BartoszJarocki BartoszJarocki left a comment

Choose a reason for hiding this comment

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

I tested everything I can think of locally and seems everything seems to be good!

CHANGELOG.md Outdated
Comment on lines 61 to 73
-

### Added

- chore: Migrate MeetingTemplate to PG (Phase 1 of 3) (#7679)
- chore(checkout-flow): add checkout feature flag (#7709)
-

### Changed

- chore: update team invite email (#7710)
- chore(ai-summary): update meeting summary url (#7705)
-
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 no need for empty -

Copy link
Member Author

Choose a reason for hiding this comment

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

i have no idea why my markdown plugin automatically added those... will fix

@@ -171,7 +171,7 @@ export default class LocalCache<T extends keyof CacheType> {
Object.keys(this.cacheMap).forEach((key) => {
if (!key.startsWith(`${table}:`)) return
const doc = this.cacheMap[key]
Object.assign(doc, updater)
Object.assign(doc as any, updater)
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 I see TS is complaining about doc being possibly undefined so seems like the correct solution here would be to add {} in this case so Object.assign won't try to write to undefined, am I correct?

      const doc = this.cacheMap[key] || {}
      Object.assign(doc, updater)

not related to PR but this file comment on the top says it's only used for User table but seems like it's only being used for meeting templates, is that something we should fix? also, once we migrate to postgres, is there any need for this functionality?

Copy link
Member Author

Choose a reason for hiding this comment

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

heh, yeah this file is very old & only used by 1 thing, it will absolutely go away when we move to pg so i didn't take too much time making it perfect. just want it to stop complaining until i can delete it 🙂

@@ -36,7 +36,7 @@ const defaultExecutor: Executor<{
})
clearTimeout(timeout)
const resJSON = (await result.json()) as EndpointExecutionResult | {message?: string}
if ('data' in resJSON || 'errors' in resJSON) return resJSON
Copy link
Contributor

Choose a reason for hiding this comment

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

oh wow

Let's change the code to the a little bit easier to read equivalent of if ('data' in resJSON || 'errors' in resJSON) return resJSON

    if ('data' in resJSON) return resJSON
    if ('errors' in resJSON) return resJSON

TS complains because data is a mandatory property, and technically the second case indicates the data is not defined.

Let's follow the code execution of if ('data' in resJSON || 'errors' in resJSON) return resJSON

  1. if data is in the resJSON it'll go straight to return resJSON as there's no need to check second condition in the or logical statement if first part is true, the returned type will be { data, errors? }
  2. the second part of the logical or will be executed only if data is not in the resJSON, meaning it'll return a type { errors }, and TS will complain as data is mandatory

Here's what happens in the reversed version ie. if ('errors' in resJSON || 'data' in resJSON) return resJSON

  1. if errors is in the resJSON and type narrowing assumes if the optional property of type is there, then the mandatory has to be there
  2. the second part will be executed only if there are no errors, and if true the returned type will be { data } which is a valid return type

I still get Property 'data' is missing in type '{ message?: string | undefined; } & Record<"errors", unknown>' but required in type 'EndpointExecutionResult'.ts(2322) error on master here but VS code sometimes is misleading so I created a TS playground

  1. Using TS 4.6.4

Screenshot 2023-02-21 at 08 55 14

  1. Using TS 4.9.5

Screenshot 2023-02-21 at 08 55 29

and seems like the way type narrowing works has changed, actually!

Signed-off-by: Matt Krick <matt.krick@gmail.com>
@mattkrick mattkrick merged commit 47dfb31 into master Feb 21, 2023
@mattkrick mattkrick deleted the chore/bump-ts-node branch February 21, 2023 19:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants