Skip to content

Commit

Permalink
Merge branch 'main' into sever-entry-e2e
Browse files Browse the repository at this point in the history
  • Loading branch information
huozhi authored Jun 18, 2023
2 parents 1ac280e + c30509f commit 38876ea
Show file tree
Hide file tree
Showing 25 changed files with 195 additions and 41 deletions.
File renamed without changes.
1 change: 1 addition & 0 deletions _internal/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from './utils/env'
export { SWRGlobalState } from './utils/global-state'
export { stableHash } from './utils/hash'
export * from './utils/helper'
export * from './utils/shared'
export { mergeConfigs } from './utils/merge-config'
export { internalMutate } from './utils/mutate'
export { normalize } from './utils/normalize-args'
Expand Down
4 changes: 3 additions & 1 deletion _internal/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,9 @@ export type MutatorOptions<Data = any> = {
populateCache?:
| boolean
| ((result: any, currentData: Data | undefined) => Data)
optimisticData?: Data | ((currentData?: Data) => Data)
optimisticData?:
| Data
| ((currentData: Data | undefined, displayedData: Data | undefined) => Data)
rollbackOnError?: boolean | ((error: unknown) => boolean)
throwOnError?: boolean
}
Expand Down
2 changes: 1 addition & 1 deletion _internal/src/utils/cache.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defaultConfigOptions } from './web-preset'
import { IS_SERVER } from './env'
import { UNDEFINED, mergeObjects, noop } from './helper'
import { UNDEFINED, mergeObjects, noop } from './shared'
import { internalMutate } from './mutate'
import { SWRGlobalState } from './global-state'
import * as revalidateEvents from '../constants'
Expand Down
2 changes: 1 addition & 1 deletion _internal/src/utils/config-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { cache as defaultCache } from './config'
import { initCache } from './cache'
import { mergeConfigs } from './merge-config'
import { UNDEFINED, mergeObjects, isFunction } from './helper'
import { UNDEFINED, mergeObjects, isFunction } from './shared'
import { useIsomorphicLayoutEffect } from './env'
import type {
SWRConfiguration,
Expand Down
2 changes: 1 addition & 1 deletion _internal/src/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { stableHash } from './hash'
import { initCache } from './cache'
import { preset } from './web-preset'
import { slowConnection } from './env'
import { isUndefined, noop, mergeObjects } from './helper'
import { isUndefined, noop, mergeObjects } from './shared'

// error retry
const onErrorRetry = (
Expand Down
2 changes: 1 addition & 1 deletion _internal/src/utils/hash.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { OBJECT, isUndefined } from './helper'
import { OBJECT, isUndefined } from './shared'

// use WeakMap to store the object->key mapping
// so the objects can be garbage collected.
Expand Down
24 changes: 4 additions & 20 deletions _internal/src/utils/helper.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,9 @@
import { SWRGlobalState } from './global-state'
import type { Cache, State, GlobalState } from '../types'
import { SWRGlobalState } from './global-state'
import { isUndefined, mergeObjects } from './shared'

const EMPTY_CACHE = {}
const INITIAL_CACHE: Record<string, any> = {}
export const noop = () => {}

// Using noop() as the undefined value as undefined can be replaced
// by something else. Prettier ignore and extra parentheses are necessary here
// to ensure that tsc doesn't remove the __NOINLINE__ comment.
// prettier-ignore
export const UNDEFINED = (/*#__NOINLINE__*/ noop()) as undefined

export const OBJECT = Object

export const isUndefined = (v: any): v is undefined => v === UNDEFINED
export const isFunction = <
T extends (...args: any[]) => any = (...args: any[]) => any
>(
v: unknown
): v is T => typeof v == 'function'
export const mergeObjects = (a: any, b?: any) => ({ ...a, ...b })
export const isPromiseLike = (x: unknown): x is PromiseLike<unknown> =>
isFunction((x as any).then)

const STR_UNDEFINED = 'undefined'

Expand Down Expand Up @@ -67,3 +49,5 @@ export const createCacheHelper = <Data = any, T = State<Data, any>>(
}
] as const
}

// export { UNDEFINED, OBJECT, isUndefined, isFunction, mergeObjects, isPromiseLike }
2 changes: 1 addition & 1 deletion _internal/src/utils/merge-config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mergeObjects } from './helper'
import { mergeObjects } from './shared'
import type { FullConfiguration } from '../types'

export const mergeConfigs = (
Expand Down
6 changes: 3 additions & 3 deletions _internal/src/utils/mutate.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { serialize } from './serialize'
import { createCacheHelper } from './helper'
import {
createCacheHelper,
isFunction,
isUndefined,
UNDEFINED,
mergeObjects,
isPromiseLike
} from './helper'
} from './shared'
import { SWRGlobalState } from './global-state'
import { getTimestamp } from './timestamp'
import * as revalidateEvents from '../constants'
Expand Down Expand Up @@ -139,7 +139,7 @@ export async function internalMutate<Data>(
// Do optimistic data update.
if (hasOptimisticData) {
optimisticData = isFunction(optimisticData)
? optimisticData(committedData)
? optimisticData(committedData, displayedData)
: optimisticData

// When we set optimistic data, backup the current committedData data in `_c`.
Expand Down
2 changes: 1 addition & 1 deletion _internal/src/utils/normalize-args.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isFunction } from './helper'
import { isFunction } from './shared'

import type { Key, Fetcher, SWRConfiguration } from '../types'

Expand Down
2 changes: 1 addition & 1 deletion _internal/src/utils/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type {
import { serialize } from './serialize'
import { cache } from './config'
import { SWRGlobalState } from './global-state'
import { isUndefined } from './helper'
import { isUndefined } from './shared'
// Basically same as Fetcher but without Conditional Fetching
type PreloadFetcher<
Data = unknown,
Expand Down
2 changes: 1 addition & 1 deletion _internal/src/utils/serialize.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { stableHash } from './hash'
import { isFunction } from './helper'
import { isFunction } from './shared'

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

Expand Down
21 changes: 21 additions & 0 deletions _internal/src/utils/shared.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Shared state between server components and client components

export const noop = () => {}

// Using noop() as the undefined value as undefined can be replaced
// by something else. Prettier ignore and extra parentheses are necessary here
// to ensure that tsc doesn't remove the __NOINLINE__ comment.
// prettier-ignore
export const UNDEFINED = (/*#__NOINLINE__*/ noop()) as undefined

export const OBJECT = Object

export const isUndefined = (v: any): v is undefined => v === UNDEFINED
export const isFunction = <
T extends (...args: any[]) => any = (...args: any[]) => any
>(
v: unknown
): v is T => typeof v == 'function'
export const mergeObjects = (a: any, b?: any) => ({ ...a, ...b })
export const isPromiseLike = (x: unknown): x is PromiseLike<unknown> =>
isFunction((x as any).then)
2 changes: 1 addition & 1 deletion _internal/src/utils/use-swr-config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useContext } from 'react'
import { defaultConfig } from './config'
import { SWRConfigContext } from './config-context'
import { mergeObjects } from './helper'
import { mergeObjects } from './shared'
import type { FullConfiguration } from '../types'

export const useSWRConfig = (): FullConfiguration => {
Expand Down
3 changes: 2 additions & 1 deletion _internal/src/utils/web-preset.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ProviderConfiguration } from '../types'
import { isUndefined, noop, isWindowDefined, isDocumentDefined } from './helper'
import { isWindowDefined, isDocumentDefined } from './helper'
import { isUndefined, noop } from './shared'

/**
* Due to the bug https://bugs.chromium.org/p/chromium/issues/detail?id=678075,
Expand Down
File renamed without changes.
4 changes: 3 additions & 1 deletion e2e/site/app/basic-ssr/block.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
'use client'

import useSWR from 'swr'
import { useDebugHistory } from '~/lib/use-debug-history'

export default function Block() {
const { data } = useSWR<string>('/api/data', async url => {
const { data } = useSWR<string>('/api/data', async (url: string) => {
const res = await fetch(url).then(v => v.json())
return res.name
})
Expand Down
3 changes: 2 additions & 1 deletion e2e/site/app/partially-hydrate/use-data.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import useSWR from 'swr'

export default function useData() {
return useSWR<string>('/api/data', async url => {
return useSWR<string>('/api/data', async (url: string) => {
const res = await fetch(url).then(v => v.json())
return res.name
})
Expand Down
File renamed without changes.
41 changes: 41 additions & 0 deletions mutation/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export type SWRMutationConfiguration<
}

type RemoveUndefined<T> = T extends undefined ? never : T
type IsUndefinedIncluded<T> = undefined extends T ? true : false
export interface TriggerWithArgs<
Data = any,
Error = any,
Expand Down Expand Up @@ -87,6 +88,44 @@ export interface TriggerWithArgs<
): Promise<Data | undefined>
}

interface TriggerWithOptionsArgs<
Data = any,
Error = any,
SWRMutationKey extends Key = Key,
ExtraArg = never
> {
<SWRData = Data>(
extraArgument?: ExtraArg,
options?: SWRMutationConfiguration<
Data,
Error,
SWRMutationKey,
ExtraArg,
SWRData
>
): Promise<Data>
<SWRData = Data>(
extraArgument?: ExtraArg,
options?: SWRMutationConfiguration<
Data,
Error,
SWRMutationKey,
ExtraArg,
SWRData
> & { throwOnError: true }
): Promise<RemoveUndefined<Data>>
<SWRData = Data>(
extraArgument?: ExtraArg,
options?: SWRMutationConfiguration<
Data,
Error,
SWRMutationKey,
ExtraArg,
SWRData
> & { throwOnError: false }
): Promise<Data | undefined>
}

export interface TriggerWithoutArgs<
Data = any,
Error = any,
Expand Down Expand Up @@ -141,6 +180,8 @@ export interface SWRMutationResponse<
*/
trigger: [ExtraArg] extends [never]
? TriggerWithoutArgs<Data, Error, SWRMutationKey, ExtraArg>
: IsUndefinedIncluded<ExtraArg> extends true
? TriggerWithOptionsArgs<Data, Error, SWRMutationKey, ExtraArg>
: TriggerWithArgs<Data, Error, SWRMutationKey, ExtraArg>
/**
* Function to reset the mutation state (`data`, `error`, and `isMutating`).
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
},
"./_internal": {
"types": "./_internal/dist/index.d.ts",
"react-server": "./_internal/dist/react-server.mjs",
"import": "./_internal/dist/index.mjs",
"module": "./_internal/dist/index.esm.js",
"require": "./_internal/dist/index.js"
Expand Down Expand Up @@ -113,7 +114,7 @@
"@types/use-sync-external-store": "^0.0.3",
"@typescript-eslint/eslint-plugin": "5.59.8",
"@typescript-eslint/parser": "5.59.8",
"bunchee": "3.3.4",
"bunchee": "3.4.0",
"eslint": "8.42.0",
"eslint-config-prettier": "8.8.0",
"eslint-plugin-jest-dom": "5.0.1",
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

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

16 changes: 16 additions & 0 deletions test/type/trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,22 @@ export function useTestSWRMutation() {
test()
}

export function useTestSWRMutationWithOptionalArgs() {
const { trigger } = useSWRMutation(
'key',
async (_, { arg }: { arg?: 'foo' }) => {
return arg?.toUpperCase()
}
)

const test = () => {
expectType<Promise<string | undefined>>(trigger('foo'))
expectType<Promise<string | undefined>>(trigger(undefined))
expectType<Promise<string | undefined>>(trigger())
}
test()
}

export function useTestSWRMutationWithSWRMutate() {
const { mutate } = useSWR('/some/key', () => {
return {
Expand Down
Loading

0 comments on commit 38876ea

Please sign in to comment.