Skip to content

Commit

Permalink
feat: use latest hypertune version (#944)
Browse files Browse the repository at this point in the history
### Description

Use latest Hypertune sdk version and small tweaks to the recommended
setup.

### Demo URL

https://feature-flag-hypertune-alpha.vercel.app/

### Type of Change

- [ ] New Example
- [ X ] Example updates (Bug fixes, new features, etc.)
- [ ] Other (changes to the codebase, but not to examples)

---------

Co-authored-by: Miraan Tabrez <[email protected]>
  • Loading branch information
SpeedyCoder and miraan authored Aug 1, 2024
1 parent 49821a0 commit 508b7d8
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 111 deletions.
18 changes: 14 additions & 4 deletions edge-middleware/feature-flag-hypertune/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type { ReactNode } from 'react'
import { Layout, getMetadata } from '@vercel/examples-ui'
import { VercelToolbar } from '@vercel/toolbar/next'
import { HypertuneSourceProvider } from '../generated/hypertune.react'
import { HypertuneProvider } from '../generated/hypertune.react'
import '@vercel/examples-ui/globals.css'
import getHypertune from '../lib/getHypertune'

export const metadata = getMetadata({
title: 'feature-flag-hypertune',
Expand All @@ -14,9 +15,18 @@ export const runtime = 'edge'
export default async function RootLayout({
children,
}: Readonly<{ children: ReactNode }>) {
const hypertune = await getHypertune()

const serverDehydratedState = hypertune.dehydrate()
const serverRootArgs = hypertune.getRootArgs()

return (
<HypertuneSourceProvider
createSourceOptions={{ token: process.env.NEXT_PUBLIC_HYPERTUNE_TOKEN! }}
<HypertuneProvider
createSourceOptions={{
token: process.env.NEXT_PUBLIC_HYPERTUNE_TOKEN!,
}}
dehydratedState={serverDehydratedState}
rootArgs={serverRootArgs}
>
<html lang="en">
<body>
Expand All @@ -32,6 +42,6 @@ export default async function RootLayout({
</Layout>
</body>
</html>
</HypertuneSourceProvider>
</HypertuneProvider>
)
}
4 changes: 2 additions & 2 deletions edge-middleware/feature-flag-hypertune/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import { Text, Page, Link, List } from '@vercel/examples-ui'
import ClientComponent from '../components/ClientComponent'
import ServerComponent from '../components/ServerComponent'
import ClientComponentWrapper from '../components/ClientComponentWrapper'

export const metadata = {
title: 'Vercel x Hypertune example',
Expand Down Expand Up @@ -37,7 +37,7 @@ export default async function Home() {

<section className="flex flex-col gap-4">
<ServerComponent />
<ClientComponentWrapper />
<ClientComponent />
<Text>
Once you&apos;ve deployed this project, open the{' '}
<Link href="https://app.hypertune.com/" target="_blank">
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export function HypertuneSourceProvider({
remoteLogging: {
mode: typeof window === 'undefined' ? 'off' : undefined,
},
// eslint-disable-next-line @typescript-eslint/no-empty-function
localLogger: typeof window === 'undefined' ? () => {} : undefined,
...createSourceOptions,
}),
// Don't recreate the source even if createSourceOptions changes
Expand Down Expand Up @@ -129,14 +131,23 @@ export function HypertuneRootProvider({
}

export function useHypertune(): hypertune.RootNode {
return React.useContext(HypertuneRootContext)
const hypertuneRoot = React.useContext(HypertuneRootContext)

if (!hypertuneRoot.props.context) {
console.warn(
'[Hypertune] Calling `useHypertune` hook outside of the `HypertuneProvider`. Fallback values will be used.'
)
}
return hypertuneRoot
}

export function HypertuneHydrator({
dehydratedState,
rootArgs,
children,
}: {
dehydratedState?: hypertune.DehydratedState | null
rootArgs?: hypertune.RootArgs
children: React.ReactElement | null
}): React.ReactElement | null {
const hypertuneSource = useHypertuneSource()
Expand All @@ -145,5 +156,13 @@ export function HypertuneHydrator({
hypertuneSource.hydrate(dehydratedState)
}

if (rootArgs) {
return (
<HypertuneRootProvider rootArgs={rootArgs}>
{children}
</HypertuneRootProvider>
)
}

return children
}
99 changes: 30 additions & 69 deletions edge-middleware/feature-flag-hypertune/generated/hypertune.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,23 @@ import * as sdk from 'hypertune'

export const queryCode = `query FullQuery{root{exampleFlag}}`

export const query = {
Query: {
objectTypeName: 'Query',
selection: {
root: {
fieldArguments: { __isPartialObject__: true },
fieldQuery: {
Root: {
objectTypeName: 'Root',
selection: {
exampleFlag: { fieldArguments: {}, fieldQuery: null },
export const query: sdk.Query<sdk.ObjectValueWithVariables> = {
variableDefinitions: {},
fragmentDefinitions: {},
fieldQuery: {
Query: {
type: 'InlineFragment',
objectTypeName: 'Query',
selection: {
root: {
fieldArguments: { __isPartialObject__: true },
fieldQuery: {
Root: {
type: 'InlineFragment',
objectTypeName: 'Root',
selection: {
exampleFlag: { fieldArguments: {}, fieldQuery: null },
},
},
},
},
Expand All @@ -23,57 +29,6 @@ export const query = {
},
}

function mergeQueryAndArgs(
query: sdk.Query<sdk.ObjectValueWithVariables>,
queryArgs: sdk.ObjectValueWithVariables | null,
unwrapObjectArgs = false
): sdk.Query<sdk.ObjectValueWithVariables> {
return Object.fromEntries(
Object.entries(query).map(([objectTypeName, fragment]) => {
const objectArgs = unwrapObjectArgs
? queryArgs &&
queryArgs[objectTypeName] &&
queryArgs[objectTypeName] instanceof Object
? (queryArgs[objectTypeName] as sdk.ObjectValueWithVariables)
: null
: queryArgs

return [
objectTypeName,
{
objectTypeName,
selection: Object.fromEntries(
Object.entries(fragment.selection).map(
([fieldName, { fieldQuery }]) => {
const fieldArgs =
objectArgs &&
objectArgs[fieldName] &&
objectArgs[fieldName] instanceof Object
? (objectArgs[fieldName] as sdk.ObjectValueWithVariables)
: null

return [
fieldName,
{
fieldArguments: {
...(fieldArgs && fieldArgs.args
? (fieldArgs.args as sdk.ObjectValueWithVariables)
: {}),
},
fieldQuery: fieldQuery
? mergeQueryAndArgs(fieldQuery, fieldArgs, true)
: null,
},
]
}
)
),
},
]
})
)
}

/**
* @deprecated use '@vercel/flags/providers/hypertune' package instead.
*/
Expand Down Expand Up @@ -123,7 +78,7 @@ export type Root = {
const rootFallback = { exampleFlag: false }

export class RootNode extends sdk.Node {
typeName = 'Root' as const
override typeName = 'Root' as const

getRootArgs(): RootArgs {
const { step } = this.props
Expand All @@ -134,7 +89,7 @@ export class RootNode extends sdk.Node {

get({ fallback = rootFallback as Root }: { fallback?: Root } = {}): Root {
const getQuery = null
return this.evaluate(getQuery, fallback) as Root
return this.getValue({ query: getQuery, fallback }) as Root
}

/**
Expand All @@ -148,7 +103,9 @@ export class RootNode extends sdk.Node {
args?: Rec
fallback: boolean
}): boolean {
const props0 = this.getField('exampleFlag', args)
const props0 = this.getFieldNodeProps('exampleFlag', {
fieldArguments: args,
})
const expression0 = props0.expression

if (expression0 && expression0.type === 'BooleanExpression') {
Expand Down Expand Up @@ -177,7 +134,7 @@ export type Rec4 = {
}

export class SourceNode extends sdk.Node {
typeName = 'Query' as const
override typeName = 'Query' as const

get({
args,
Expand All @@ -186,12 +143,16 @@ export class SourceNode extends sdk.Node {
args: Rec4
fallback?: Source
}): Source {
const getQuery = mergeQueryAndArgs(query, args)
return this.evaluate(getQuery, fallback) as Source
const getQuery = sdk.mergeFieldQueryAndArgs(
query.fragmentDefinitions,
sdk.getFieldQueryForPath(query.fragmentDefinitions, query.fieldQuery, []),
args
)
return this.getValue({ query: getQuery, fallback }) as Source
}

root({ args }: { args: RootArgs }): RootNode {
const props0 = this.getField('root', args)
const props0 = this.getFieldNodeProps('root', { fieldArguments: args })
const expression0 = props0.expression

if (
Expand Down
5 changes: 3 additions & 2 deletions edge-middleware/feature-flag-hypertune/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"@vercel/examples-ui": "^2.0.3",
"@vercel/flags": "2.5.1",
"@vercel/toolbar": "^0.1.15",
"hypertune": "2.3.3",
"hypertune": "2.4.0",
"next": "^14.1.4",
"react": "latest",
"react-dom": "latest",
Expand All @@ -32,6 +32,7 @@
"eslint-plugin-prettier": "^5.1.3",
"postcss": "^8.4.38",
"prettier": "^3.2.5",
"tailwindcss": "^3.4.3"
"tailwindcss": "^3.4.3",
"turbo": "1.13.4"
}
}
Loading

0 comments on commit 508b7d8

Please sign in to comment.