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

Commit

Permalink
feat: [SPMVP-6868] Lazy load subscriber client in karbon (#335)
Browse files Browse the repository at this point in the history
Co-authored-by: DanSnow <dododavid006@gmail.com>
  • Loading branch information
SidStraw and DanSnow authored Feb 28, 2024
1 parent 2bb443a commit 70762e5
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 18 deletions.
3 changes: 2 additions & 1 deletion packages/karbon/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
"find-cache-dir": "^5.0.0",
"fs-extra": "^11.2.0",
"graphql": "^16.7.1",
"graphql-tag": "^2.12.6",
"hookable": "^5.5.3",
"js-yaml": "^4.1.0",
"jszip": "^3.10.1",
Expand Down Expand Up @@ -232,4 +233,4 @@
"access": "public"
},
"gitHead": "8df1f4d5837a7e2ddbff6cc79f5fec256c34a394"
}
}
5 changes: 4 additions & 1 deletion packages/karbon/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,10 @@ const karbon = defineNuxtModule<ModuleOptions>({
flags.lazySearch
? './runtime/plugins/storipress-search-client-noop'
: './runtime/plugins/storipress-search-client',
'./runtime/plugins/storipress-client',
{
src: './runtime/plugins/storipress-client',
mode: 'server',
},
'./runtime/plugins/debug-info.client',
'./runtime/plugins/track.client',
'./runtime/plugins/iframely.client',
Expand Down
9 changes: 9 additions & 0 deletions packages/karbon/src/runtime/api/siteTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import consola from 'consola'
import type { ZodError } from 'zod'
import { z } from 'zod'
import { fromZodError } from 'zod-validation-error'
import { ApolloClient, ApolloLink, HttpLink, InMemoryCache, Observable } from '@apollo/client/core/index.js'
import { createStoripressBaseClient } from '../composables/storipress-base-client'

export enum TemplateType {
Expand Down Expand Up @@ -61,6 +62,13 @@ export async function uploadSiteTemplate(key: string) {
return data.uploadSiteTemplate
}

const apollo = {
ApolloClient,
ApolloLink,
HttpLink,
InMemoryCache,
Observable,
}
async function createStoripressClient() {
const { loadNuxtConfig } = await import('@nuxt/kit')
const {
Expand All @@ -69,6 +77,7 @@ async function createStoripressClient() {
const { apiHost, apiToken, clientId } = assertConfig(storipress)

return createStoripressBaseClient(
apollo,
() => ({
authorization: `Bearer ${apiToken}`,
}),
Expand Down
9 changes: 6 additions & 3 deletions packages/karbon/src/runtime/api/track.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { gql } from '@apollo/client/core/index.js'
import { useStorage } from '@vueuse/core'
import { gql } from 'graphql-tag'
import { until, useStorage } from '@vueuse/core'
import { useSubscriberClient } from '../composables/subscriber-client'

type JSONValue = string | number | boolean | JSONObject | Array<JSONValue>
Expand Down Expand Up @@ -34,7 +34,10 @@ export async function track(input: TrackSubscriberActivityInput) {

try {
const client = useSubscriberClient()
const { data } = await client.mutate({
await until(client).toBeTruthy({ timeout: 2000 })
if (!client.value) return false

const { data } = await client.value.mutate({
mutation: TrackMutation,
variables: {
input,
Expand Down
19 changes: 17 additions & 2 deletions packages/karbon/src/runtime/composables/storipress-base-client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type { Operation } from '@apollo/client/core/index.js'
import { ApolloClient, ApolloLink, HttpLink, InMemoryCache, Observable } from '@apollo/client/core/index.js'
import type {
ApolloClient,
ApolloLink,
HttpLink,
InMemoryCache,
Observable,
Operation,
} from '@apollo/client/core/index.js'
import { setContext } from '@apollo/client/link/context/index.js'
import { fetch } from 'cross-fetch'
import { withHttps } from 'ufo'
Expand Down Expand Up @@ -78,11 +84,20 @@ export interface CreateBaseClientInput {
name?: string
}

export interface Apollo {
ApolloClient: typeof ApolloClient
ApolloLink: typeof ApolloLink
HttpLink: typeof HttpLink
InMemoryCache: typeof InMemoryCache
Observable: typeof Observable
}
export function createStoripressBaseClient(
apollo: Apollo,
getHeaders: () => Record<string, string | null | undefined>,
uri: string,
opt: CreateBaseClientInput = {},
) {
const { ApolloClient, ApolloLink, HttpLink, InMemoryCache, Observable } = apollo
const tapClient = new ApolloLink((operation, forward) => {
const id = crypto.randomUUID()

Expand Down
17 changes: 14 additions & 3 deletions packages/karbon/src/runtime/composables/storipress-client.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
import type { ApolloClient, NormalizedCacheObject } from '@apollo/client/core/index.js'
import type { NormalizedCacheObject } from '@apollo/client/core/index.js'
import { useStorage } from '@vueuse/core'
import { createContext } from 'unctx'
import { ApolloClient, ApolloLink, HttpLink, InMemoryCache, Observable } from '@apollo/client/core/index.js'
import type { Apollo } from './storipress-base-client'
import { createStoripressBaseClient, getStoripressConfig } from './storipress-base-client'

const apollo = {
ApolloClient,
ApolloLink,
HttpLink,
InMemoryCache,
Observable,
}

export function createStoripressClient() {
const storipress = getStoripressConfig()
return createStoripressBaseClient(
apollo,
() => ({
authorization: `Bearer ${storipress?.apiToken}`,
}),
Expand All @@ -26,15 +37,15 @@ export function useStoripressClient() {
return client
}

export function createSubscriberClient() {
export function createSubscriberClient(apollo: Apollo) {
const authorization = () => {
const token = useStorage('storipress-token', '')
return {
authorization: token.value ? `Bearer ${token.value}` : null,
}
}

return createStoripressBaseClient(authorization, getUri(), { name: 'storipress-subscriber' })
return createStoripressBaseClient(apollo, authorization, getUri(), { name: 'storipress-subscriber' })
}

export function getUri() {
Expand Down
25 changes: 22 additions & 3 deletions packages/karbon/src/runtime/composables/subscriber-client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
import { useNuxtApp } from '#imports'
import { createSubscriberClient } from './storipress-client'
import { ref } from '#imports'

export function useSubscriberClient() {
const { $storipress } = useNuxtApp()
return $storipress.subscriberClient
type SubscriberClient = ReturnType<typeof createSubscriberClient>
const subscriberClient = ref<SubscriberClient>()

if (process.server) return subscriberClient

async function createClient() {
const { ApolloClient, ApolloLink, HttpLink, InMemoryCache, Observable } = await import(
'@apollo/client/core/index.js'
)
const apollo = {
ApolloClient,
ApolloLink,
HttpLink,
InMemoryCache,
Observable,
}
subscriberClient.value = createSubscriberClient(apollo)
}
createClient()
return subscriberClient
}
6 changes: 4 additions & 2 deletions packages/karbon/src/runtime/plugins/paywall.client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEventBus, useStorage } from '@vueuse/core'
import { until, useEventBus, useStorage } from '@vueuse/core'
import { once } from 'remeda'
import '@storipress/builder-component/dist/style.css'
import { waitFirstInteractive } from '../utils/defer-load'
Expand Down Expand Up @@ -87,11 +87,13 @@ export default defineNuxtPlugin((_nuxtApp) => {
query,
},
}
await until(client).toBeTruthy({ timeout: 2000 })
if (!client.value) return

paywall.value = mountPaywall({
el: '#paywall',
router: routerLink,
client,
client: client.value,
favicon: runtimeConfig.public.storipress.paywall.logo,
logo: paywallLogo,
token,
Expand Down
4 changes: 1 addition & 3 deletions packages/karbon/src/runtime/plugins/storipress-client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createStoripressClient, createSubscriberClient, storipressClientCtx } from '../composables/storipress-client'
import { createStoripressClient, storipressClientCtx } from '../composables/storipress-client'
import { storipressConfigCtx } from '../composables/storipress-base-client'
import { defineNuxtPlugin, useRuntimeConfig } from '#imports'

Expand All @@ -7,15 +7,13 @@ export default defineNuxtPlugin((_nuxtApp) => {
storipressConfigCtx.set({ ...runtimeConfig.public.storipress, ...runtimeConfig.storipress })

const apolloClient = createStoripressClient()
const subscriberClient = createSubscriberClient()

storipressClientCtx.set(apolloClient, true)

return {
provide: {
storipress: {
client: apolloClient,
subscriberClient,
},
},
}
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2992,6 +2992,7 @@ __metadata:
fs-extra: "npm:11.2.0"
globby: "npm:14.0.1"
graphql: "npm:^16.7.1"
graphql-tag: "npm:^2.12.6"
hookable: "npm:^5.5.3"
js-yaml: "npm:^4.1.0"
jszip: "npm:^3.10.1"
Expand Down

0 comments on commit 70762e5

Please sign in to comment.