Skip to content

Commit

Permalink
feat: expose js client from nextjs sdk and allow debugger to use next…
Browse files Browse the repository at this point in the history
…js (#942)
  • Loading branch information
ajwootto authored Aug 26, 2024
1 parent 1e89e00 commit 86c75f8
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 11 deletions.
19 changes: 19 additions & 0 deletions lib/web-debugger/next.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useEffect } from 'react'
import {
initializeDevCycleDebugger,
DebuggerIframeOptions,
} from './src/initializeDevCycleDebugger.js'
import { useDevCycleClient } from '@devcycle/nextjs-sdk'

export const DevCycleDebugger = (options: DebuggerIframeOptions): null => {
const client = useDevCycleClient()

useEffect(() => {
const cleanupPromise = initializeDevCycleDebugger(client, options)
return () => {
cleanupPromise.then((cleanup) => cleanup())
}
}, [client])

return null
}
8 changes: 8 additions & 0 deletions lib/web-debugger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,24 @@
"./react": {
"import": "./react.js",
"types": "./react.d.ts"
},
"./next": {
"import": "./next.js",
"types": "./next.d.ts"
}
},
"dependencies": {
"@devcycle/types": "^1.16.2"
},
"peerDependencies": {
"@devcycle/js-client-sdk": "*",
"@devcycle/nextjs-sdk": "*",
"@devcycle/react-client-sdk": "*"
},
"peerDependenciesMeta": {
"@devcycle/nextjs-sdk": {
"optional": true
},
"@devcycle/react-client-sdk": {
"optional": true
}
Expand Down
37 changes: 27 additions & 10 deletions lib/web-debugger/src/initializeDevCycleDebugger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
} from '@devcycle/js-client-sdk'
import { BucketedUserConfig } from '@devcycle/types'

type NextClient = Omit<DevCycleClient, 'identifyUser' | 'resetUser'>

type LiveEvent = {
type: string
key?: string
Expand All @@ -18,6 +20,7 @@ type ClientData = {
liveEvents: LiveEvent[]
loadCount: number
expanded: boolean
allowIdentify: boolean
}
}

Expand All @@ -26,6 +29,7 @@ const clientData: ClientData = {
liveEvents: [],
loadCount: 0,
expanded: false,
allowIdentify: true,
},
}

Expand All @@ -47,17 +51,18 @@ class IframeManager {
debuggerUrl: string
position: string
debugLogs: boolean
client: DevCycleClient
client: DevCycleClient | NextClient

constructor(
client: DevCycleClient,
client: DevCycleClient | NextClient,
{
position = 'right',
debuggerUrl = 'https://debugger.devcycle.com',
debugLogs = false,
}: DebuggerIframeOptions = {},
) {
this.client = client
clientData.current.allowIdentify = 'identifyUser' in client
this.debuggerUrl = debuggerUrl
this.position = position
this.debugLogs = debugLogs
Expand Down Expand Up @@ -229,13 +234,25 @@ class IframeManager {
event.data.type === 'DEVCYCLE_IDENTIFY_USER' &&
event.data.user
) {
this.client.identifyUser(event.data.user).then(() => {
this.updateIframeData()
})
if ('identifyUser' in this.client) {
this.client.identifyUser(event.data.user).then(() => {
this.updateIframeData()
})
} else {
this.log(
'Unable to change user identity from debugger in Next.js',
)
}
} else if (event.data.type === 'DEVCYCLE_RESET_USER') {
this.client.resetUser().then(() => {
this.updateIframeData()
})
if ('resetUser' in this.client) {
this.client.resetUser().then(() => {
this.updateIframeData()
})
} else {
this.log(
'Unable to change user identity from debugger in Next.js',
)
}
} else if (event.data.type === 'DEVCYCLE_REFRESH') {
this.updateIframeData()
} else if (event.data.type === 'DEVCYCLE_TOGGLE_OVERLAY') {
Expand All @@ -259,7 +276,7 @@ class IframeManager {
}

export const checkShouldEnable = async (
client: DevCycleClient,
client: DevCycleClient | NextClient,
{
shouldEnable,
shouldEnableVariable,
Expand All @@ -284,7 +301,7 @@ export const checkShouldEnable = async (
}

export const initializeDevCycleDebugger = async (
client: DevCycleClient,
client: DevCycleClient | NextClient,
{
shouldEnable,
shouldEnableVariable,
Expand Down
8 changes: 7 additions & 1 deletion lib/web-debugger/tsconfig.lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
"declaration": true,
"types": ["node"]
},
"include": ["src/**/*.ts", "src/**/*.tsx", "index.ts", "react.tsx"],
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"index.ts",
"react.tsx",
"next.tsx"
],
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
}
13 changes: 13 additions & 0 deletions sdk/js/src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,12 @@ export class DevCycleClient<
user: DevCycleUser,
callback?: ErrorCallback<DVCVariableSet>,
): Promise<DVCVariableSet> | void {
if (this.options.next) {
this.logger.error(
'Unable to change user identity from the clientside in Next.js',
)
return
}
const promise = this._identifyUser(user)

if (callback && typeof callback == 'function') {
Expand Down Expand Up @@ -460,6 +466,13 @@ export class DevCycleClient<
resetUser(
callback?: ErrorCallback<DVCVariableSet>,
): Promise<DVCVariableSet> | void {
if (this.options.next) {
this.logger.error(
'Unable to change user identity from the clientside in Next.js',
)
return
}

let oldAnonymousId: string | null | undefined
const anonUser = new DVCPopulatedUser(
{ isAnonymous: true },
Expand Down
7 changes: 7 additions & 0 deletions sdk/nextjs/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
// Use this file to export React client code (e.g. those with 'use client' directive)
// or other non-server utilities
import { DevCycleClient as JSClient } from '@devcycle/js-client-sdk'

export { useVariable, useVariableValue } from './src/client/useVariableValue'
export type * from './src/common/types'
export { useUserIdentity } from './src/client/useUserIdentity'
export { useTrack } from './src/client/useTrack'
export { useAllVariables } from './src/client/useAllVariables'
export { useAllFeatures } from './src/client/useAllFeatures'
export { renderIfEnabled } from './src/client/renderIfEnabled'
export { useDevCycleClient } from './src/client/useDevCycleClient'
export { DevCycleClientsideProvider } from './src/client/DevCycleClientsideProvider'
export { DVCVariable, DVCVariableValue } from '@devcycle/react-client-sdk'

type DevCycleClient = Omit<JSClient, 'identifyUser' | 'resetUser'>

export type { DevCycleClient }
6 changes: 6 additions & 0 deletions sdk/nextjs/src/client/useDevCycleClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { useDevCycleClient as internalUseClient } from './internal/useDevCycleClient'
import { DevCycleClient } from '@devcycle/js-client-sdk'

export const useDevCycleClient = (): DevCycleClient => {
return internalUseClient()
}
3 changes: 3 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4857,8 +4857,11 @@ __metadata:
"@devcycle/types": ^1.16.2
peerDependencies:
"@devcycle/js-client-sdk": "*"
"@devcycle/nextjs-sdk": "*"
"@devcycle/react-client-sdk": "*"
peerDependenciesMeta:
"@devcycle/nextjs-sdk":
optional: true
"@devcycle/react-client-sdk":
optional: true
languageName: unknown
Expand Down

0 comments on commit 86c75f8

Please sign in to comment.