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

[RFC & POC] Hiding Wasp's private API from users #1922

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions waspc/data/Cli/templates/skeleton/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
// compiler. Proper TS compiler configuration in Wasp is coming soon :)
{
"compilerOptions": {
"target": "esnext",
// We're bundling all code in the end so this is the most appropriate option,
// it's also important for autocomplete to work properly.
"moduleResolution": "bundler",
// JSX support
"jsx": "preserve",
"strict": true,
Expand Down
2 changes: 1 addition & 1 deletion waspc/data/Generator/templates/react-app/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import router from './router'
import {
initializeQueryClient,
queryClientInitialized,
} from 'wasp/client/operations'
} from 'wasp/client/operations/queryClient'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All SDK imports in the framework code have been updated according to the new code organization.


{=# setupFn.isDefined =}
{=& setupFn.importStatement =}
Expand Down
1 change: 1 addition & 0 deletions waspc/data/Generator/templates/react-app/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const defaultViteConfig = {
outDir: "build",
},
resolve: {
conditions: ["client-runtime"],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is where we set the framework runtime's condition string, thus gaining access to the SDK's private API.

// These packages rely on a single instance per page. Not dedpuing them
// causes runtime errors (e.g., hook rule violation in react, QueryClient
// instance error in react-query, Invariant Error in react-router-dom).
Expand Down
3 changes: 2 additions & 1 deletion waspc/data/Generator/templates/sdk/wasp/auth/useAuth.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{{={= =}=}}
import { deserialize as superjsonDeserialize } from 'superjson'
import { useQuery, addMetadataToQuery } from 'wasp/client/operations'
import { useQuery } from '../client/operations'
import { addMetadataToQuery } from '../client/operations/queries/core'
Comment on lines +3 to +4
Copy link
Contributor Author

@sodic sodic Mar 27, 2024

Choose a reason for hiding this comment

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

I've updated all the import paths inside the SDK have been converted from package imports to relative imports (also accounting for the updated paths).

import { api, handleApiError } from 'wasp/client/api'
import { HttpMethod } from 'wasp/client'
import type { AuthUser } from './types'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,4 @@ export {
export {
// PUBLIC API
configureQueryClient,
// PRIVATE API (framework code)
initializeQueryClient,
// PRIVATE API (framework code)
queryClientInitialized
} from './queryClient'
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,3 @@ export const {= operationName =} = createQuery<{= operationTypeName =}>(
{=& entitiesArray =},
)
{=/ queries =}

// PRIVATE API
export { addMetadataToQuery } from './core'
3 changes: 3 additions & 0 deletions waspc/data/Generator/templates/sdk/wasp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"types": "tsc --declaration --emitDeclarationOnly --stripInternal --declarationDir dist"
},
"exports": {
"./client/operations/queryClient": {
"client-runtime": "./dist/client/operations/queryClient.js"
},
Comment on lines +12 to +14
Copy link
Contributor Author

@sodic sodic Mar 27, 2024

Choose a reason for hiding this comment

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

This how we expose the SDK's private API to the framework, while hiding it from the user.

Unfortunately, we can't do:

"exports": {
  "client-runtime": {
    // private API
  },
  "default": {
    // public API
  }

Because once Vite finds an object with a matching condition, it won't trace back if it doesn't find a required symbol inside it:

Vite has a list of "allowed conditions" and will match the first condition that is in the allowed list.

Which means we would have to repeat the entire public API twice.

"exports": {
  "client-runtime": {
    // private API
    // public API
  },
  "default": {
    // public API
  }

It isn't quite as nice, but works. We can still decide which approach do we want to take.

Copy link
Contributor

Choose a reason for hiding this comment

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

Great stuff! I didn't know that exports API worked this way. I always thought that the import and require were the only options.

{=! todo(filip): Check all exports when done with SDK generation =}
{=! Some of the statements in the comments might become incorrect. =}
{=! "our code" means: "web-app", "server" or "SDK", or "some combination of the three". =}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading