Skip to content

Commit

Permalink
feat: fetch feature toggle to enable serverside document actions (#6418)
Browse files Browse the repository at this point in the history
* feature: scaffold feature flag function

* revert back operations for now until caching issue is fixed

* refactor: try memoizing featureToggle

* refactor: use shareReplay

* feat: add feature toggle requests to operations events etc.

* refactor: rename featureToggleRequest

* fix: do not pass canUseServerActions to snapshot pair

* refactor(document-store): pass in server actions config as observable (#6582)

* feat: use real endpoint in fetchFeatureToggle

* test: update checkoutPair and add featureToggle e2e test

* chore: remove comment now that proper endpoint is in place

* fix(document-store): timeout feature flag req after 2s and treat as 'false'

* fix(sanity): make config flag override server document actions (#6634)

---------

Co-authored-by: Bjørge Næss <[email protected]>
  • Loading branch information
2 people authored and ricokahler committed May 15, 2024
1 parent 409d7df commit 8610fc6
Show file tree
Hide file tree
Showing 23 changed files with 207 additions and 59 deletions.
3 changes: 3 additions & 0 deletions dev/studio-e2e-testing/sanity.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,7 @@ export default defineConfig({

plugins: [sharedSettings()],
basePath: '/test',
unstable_serverActions: {
enabled: true,
},
})
5 changes: 2 additions & 3 deletions dev/test-studio/sanity.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,8 @@ export default defineConfig([
plugins: [sharedSettings()],
basePath: '/test',
icon: SanityMonogram,
unstable_serverActions: {
enabled: true,
},
// eslint-disable-next-line camelcase
__internal_serverDocumentActions: {},
scheduledPublishing: {
enabled: true,
inputDateTimeFormat: 'MM/dd/yy h:mm a',
Expand Down
3 changes: 2 additions & 1 deletion packages/sanity/src/core/config/prepareConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@ export function prepareConfig(
__internal: {
sources: resolvedSources,
},
serverActions: rawWorkspace.unstable_serverActions ?? {enabled: false},
// eslint-disable-next-line camelcase
__internal_serverDocumentActions: rawWorkspace.__internal_serverDocumentActions,
...defaultPluginsOptions,
}
preparedWorkspaces.set(rawWorkspace, workspaceSummary)
Expand Down
13 changes: 7 additions & 6 deletions packages/sanity/src/core/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -448,10 +448,10 @@ export interface WorkspaceOptions extends SourceOptions {

/**
* @hidden
* @beta
* @internal
*/
unstable_serverActions?: {
enabled: boolean
__internal_serverDocumentActions?: {
enabled?: boolean
}

scheduledPublishing?: DefaultPluginsWorkspaceOptions['scheduledPublishing']
Expand Down Expand Up @@ -770,8 +770,9 @@ export interface Source {
}
/** @beta */
tasks?: WorkspaceOptions['tasks']
/** @beta */
serverActions?: WorkspaceOptions['unstable_serverActions']

/** @internal */
__internal_serverDocumentActions?: WorkspaceOptions['__internal_serverDocumentActions']
}

/** @internal */
Expand Down Expand Up @@ -810,7 +811,7 @@ export interface WorkspaceSummary extends DefaultPluginsWorkspaceOptions {
source: Observable<Source>
}>
}
serverActions: WorkspaceOptions['unstable_serverActions']
__internal_serverDocumentActions: WorkspaceOptions['__internal_serverDocumentActions']
}

/**
Expand Down
17 changes: 14 additions & 3 deletions packages/sanity/src/core/store/_legacy/datastores.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable camelcase */

import {useMemo} from 'react'
import {of} from 'rxjs'

import {useClient, useSchema, useTemplates} from '../../hooks'
import {createDocumentPreviewStore, type DocumentPreviewStore} from '../../preview'
Expand All @@ -13,6 +14,7 @@ import {
createConnectionStatusStore,
} from './connection-status/connection-status-store'
import {createDocumentStore, type DocumentStore} from './document'
import {fetchFeatureToggle} from './document/document-pair/utils/fetchFeatureToggle'
import {createGrantsStore, type GrantsStore} from './grants'
import {createHistoryStore, type HistoryStore} from './history'
import {__tmp_wrap_presenceStore, type PresenceStore} from './presence/presence-store'
Expand Down Expand Up @@ -131,6 +133,14 @@ export function useDocumentStore(): DocumentStore {
const documentPreviewStore = useDocumentPreviewStore()
const workspace = useWorkspace()

const serverActionsEnabled = useMemo(() => {
const configFlag = workspace.__internal_serverDocumentActions?.enabled
// If it's explicitly set, let it override the feature toggle
return typeof configFlag === 'boolean'
? of(configFlag as boolean)
: fetchFeatureToggle(getClient(DEFAULT_STUDIO_CLIENT_OPTIONS))
}, [getClient, workspace.__internal_serverDocumentActions?.enabled])

return useMemo(() => {
const documentStore =
resourceCache.get<DocumentStore>({
Expand All @@ -144,7 +154,7 @@ export function useDocumentStore(): DocumentStore {
initialValueTemplates: templates,
schema,
i18n,
serverActionsEnabled: !!workspace.serverActions?.enabled,
serverActionsEnabled,
})

resourceCache.set({
Expand All @@ -155,14 +165,15 @@ export function useDocumentStore(): DocumentStore {

return documentStore
}, [
resourceCache,
getClient,
documentPreviewStore,
historyStore,
resourceCache,
schema,
templates,
i18n,
workspace,
templates,
serverActionsEnabled,
])
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ beforeEach(() => {

describe('checkoutPair -- local actions', () => {
test('patch', async () => {
const {draft, published} = checkoutPair(client as any as SanityClient, idPair, false)
const {draft, published} = checkoutPair(client as any as SanityClient, idPair, of(false))
const combined = merge(draft.events, published.events)
const sub = combined.subscribe()
await new Promise((resolve) => setTimeout(resolve, 0))
Expand All @@ -62,7 +62,7 @@ describe('checkoutPair -- local actions', () => {
})

test('createIfNotExists', async () => {
const {draft, published} = checkoutPair(client as any as SanityClient, idPair, false)
const {draft, published} = checkoutPair(client as any as SanityClient, idPair, of(false))
const combined = merge(draft.events, published.events)
const sub = combined.subscribe()
await new Promise((resolve) => setTimeout(resolve, 0))
Expand Down Expand Up @@ -104,7 +104,7 @@ describe('checkoutPair -- local actions', () => {
})

test('create', async () => {
const {draft, published} = checkoutPair(client as any as SanityClient, idPair, false)
const {draft, published} = checkoutPair(client as any as SanityClient, idPair, of(false))
const combined = merge(draft.events, published.events)
const sub = combined.subscribe()
await new Promise((resolve) => setTimeout(resolve, 0))
Expand Down Expand Up @@ -146,7 +146,7 @@ describe('checkoutPair -- local actions', () => {
})

test('createOrReplace', async () => {
const {draft, published} = checkoutPair(client as any as SanityClient, idPair, false)
const {draft, published} = checkoutPair(client as any as SanityClient, idPair, of(false))
const combined = merge(draft.events, published.events)
const sub = combined.subscribe()
await new Promise((resolve) => setTimeout(resolve, 0))
Expand Down Expand Up @@ -189,7 +189,7 @@ describe('checkoutPair -- local actions', () => {
})

test('delete', async () => {
const {draft, published} = checkoutPair(client as any as SanityClient, idPair, false)
const {draft, published} = checkoutPair(client as any as SanityClient, idPair, of(false))
const combined = merge(draft.events, published.events)
const sub = combined.subscribe()
await new Promise((resolve) => setTimeout(resolve, 0))
Expand Down Expand Up @@ -223,7 +223,11 @@ describe('checkoutPair -- local actions', () => {

describe('checkoutPair -- server actions', () => {
test('patch', async () => {
const {draft, published} = checkoutPair(clientWithConfig as any as SanityClient, idPair, true)
const {draft, published} = checkoutPair(
clientWithConfig as any as SanityClient,
idPair,
of(true),
)
const combined = merge(draft.events, published.events)
const sub = combined.subscribe()
await new Promise((resolve) => setTimeout(resolve, 0))
Expand Down Expand Up @@ -257,7 +261,11 @@ describe('checkoutPair -- server actions', () => {
})

test('published patch uses mutation endpoint', async () => {
const {draft, published} = checkoutPair(clientWithConfig as any as SanityClient, idPair, true)
const {draft, published} = checkoutPair(
clientWithConfig as any as SanityClient,
idPair,
of(true),
)
const combined = merge(draft.events, published.events)
const sub = combined.subscribe()
await new Promise((resolve) => setTimeout(resolve, 0))
Expand Down Expand Up @@ -286,7 +294,11 @@ describe('checkoutPair -- server actions', () => {
})

test('create', async () => {
const {draft, published} = checkoutPair(clientWithConfig as any as SanityClient, idPair, true)
const {draft, published} = checkoutPair(
clientWithConfig as any as SanityClient,
idPair,
of(true),
)
const combined = merge(draft.events, published.events)
const sub = combined.subscribe()
await new Promise((resolve) => setTimeout(resolve, 0))
Expand Down Expand Up @@ -327,7 +339,11 @@ describe('checkoutPair -- server actions', () => {
})

test('createIfNotExists', async () => {
const {draft, published} = checkoutPair(clientWithConfig as any as SanityClient, idPair, true)
const {draft, published} = checkoutPair(
clientWithConfig as any as SanityClient,
idPair,
of(true),
)
const combined = merge(draft.events, published.events)
const sub = combined.subscribe()
await new Promise((resolve) => setTimeout(resolve, 0))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {type SanityClient} from '@sanity/client'
import {type Mutation} from '@sanity/mutator'
import {type SanityDocument} from '@sanity/types'
import {EMPTY, from, merge, type Observable, Subject} from 'rxjs'
import {filter, map, mergeMap, share, tap} from 'rxjs/operators'
import {filter, map, mergeMap, share, take, tap} from 'rxjs/operators'

import {
type BufferedDocumentEvent,
Expand Down Expand Up @@ -196,7 +196,7 @@ function submitCommitRequest(
export function checkoutPair(
client: SanityClient,
idPair: IdPair,
serverActionsEnabled: boolean,
serverActionsEnabled: Observable<boolean>,
): Pair {
const {publishedId, draftId} = idPair

Expand Down Expand Up @@ -226,7 +226,12 @@ export function checkoutPair(

const commits$ = merge(draft.commitRequest$, published.commitRequest$).pipe(
mergeMap((commitRequest) =>
submitCommitRequest(client, idPair, commitRequest, serverActionsEnabled),
serverActionsEnabled.pipe(
take(1),
mergeMap((canUseServerActions) =>
submitCommitRequest(client, idPair, commitRequest, canUseServerActions),
),
),
),
mergeMap(() => EMPTY),
share(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ export const consistencyStatus: (
client: SanityClient,
idPair: IdPair,
typeName: string,
serverActionsEnabled: boolean,
serverActionsEnabled: Observable<boolean>,
) => Observable<boolean> = memoize(
(client: SanityClient, idPair: IdPair, typeName: string, serverActionsEnabled: boolean) => {
(
client: SanityClient,
idPair: IdPair,
typeName: string,
serverActionsEnabled: Observable<boolean>,
) => {
return memoizedPair(client, idPair, typeName, serverActionsEnabled).pipe(
switchMap(({draft, published}) =>
combineLatest([draft.consistency$, published.consistency$]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const documentEvents = memoize(
client: SanityClient,
idPair: IdPair,
typeName: string,
serverActionsEnabled: boolean,
serverActionsEnabled: Observable<boolean>,
): Observable<DocumentVersionEvent> => {
return memoizedPair(client, idPair, typeName, serverActionsEnabled).pipe(
switchMap(({draft, published}) => merge(draft.events, published.events)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const editOperations = memoize(
client: SanityClient
historyStore: HistoryStore
schema: Schema
serverActionsEnabled: boolean
serverActionsEnabled: Observable<boolean>
},
idPair: IdPair,
typeName: string,
Expand All @@ -34,5 +34,5 @@ export const editOperations = memoize(
merge(operationEvents$.pipe(mergeMap(() => EMPTY)), operations$),
).pipe(shareReplay({refCount: true, bufferSize: 1}))
},
(ctx, idPair, typeName) => memoizeKeyGen(ctx.client, idPair, typeName, ctx.serverActionsEnabled),
(ctx, idPair, typeName) => memoizeKeyGen(ctx.client, idPair, typeName),
)
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const editState = memoize(
ctx: {
client: SanityClient
schema: Schema
serverActionsEnabled: boolean
serverActionsEnabled: Observable<boolean>
},
idPair: IdPair,
typeName: string,
Expand Down Expand Up @@ -73,5 +73,5 @@ export const editState = memoize(
refCount(),
)
},
(ctx, idPair, typeName) => memoizeKeyGen(ctx.client, idPair, typeName, ctx.serverActionsEnabled),
(ctx, idPair, typeName) => memoizeKeyGen(ctx.client, idPair, typeName),
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@ import {type SanityClient} from '@sanity/client'

import {type IdPair} from '../types'

export function memoizeKeyGen(
client: SanityClient,
idPair: IdPair,
typeName: string,
serverActionsEnabled: boolean,
) {
export function memoizeKeyGen(client: SanityClient, idPair: IdPair, typeName: string) {
const config = client.config()
return `${config.dataset ?? ''}-${config.projectId ?? ''}-${idPair.publishedId}-${typeName}${serverActionsEnabled ? '-serverActionsEnabled' : ''}`
return `${config.dataset ?? ''}-${config.projectId ?? ''}-${idPair.publishedId}-${typeName}`
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ export const memoizedPair: (
client: SanityClient,
idPair: IdPair,
typeName: string,
serverActionsEnabled: boolean,
serverActionsEnabled: Observable<boolean>,
) => Observable<Pair> = memoize(
(
client: SanityClient,
idPair: IdPair,
_typeName: string,
serverActionsEnabled: boolean,
serverActionsEnabled: Observable<boolean>,
): Observable<Pair> => {
return new Observable<Pair>((subscriber) => {
const pair = checkoutPair(client, idPair, serverActionsEnabled)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-disable @typescript-eslint/no-use-before-define */
/* eslint-disable max-nested-callbacks */

import {type SanityClient} from '@sanity/client'
import {type Schema} from '@sanity/types'
Expand All @@ -18,19 +19,24 @@ export const operationArgs = memoize(
client: SanityClient
historyStore: HistoryStore
schema: Schema
serverActionsEnabled: boolean
serverActionsEnabled: Observable<boolean>
},
idPair: IdPair,
typeName: string,
): Observable<OperationArgs> => {
return snapshotPair(ctx.client, idPair, typeName, ctx.serverActionsEnabled).pipe(
switchMap((versions) =>
combineLatest([versions.draft.snapshots$, versions.published.snapshots$]).pipe(
combineLatest([
versions.draft.snapshots$,
versions.published.snapshots$,
ctx.serverActionsEnabled,
]).pipe(
map(
([draft, published]): OperationArgs => ({
([draft, published, canUseServerActions]): OperationArgs => ({
...ctx,
serverActionsEnabled: canUseServerActions,
idPair,
typeName: typeName,
typeName,
snapshots: {draft, published},
draft: versions.draft,
published: versions.published,
Expand All @@ -43,6 +49,6 @@ export const operationArgs = memoize(
)
},
(ctx, idPair, typeName) => {
return memoizeKeyGen(ctx.client, idPair, typeName, ctx.serverActionsEnabled)
return memoizeKeyGen(ctx.client, idPair, typeName)
},
)
Loading

0 comments on commit 8610fc6

Please sign in to comment.