Skip to content

Commit

Permalink
feat(ssr): support match fn
Browse files Browse the repository at this point in the history
  • Loading branch information
Brooooooklyn committed Jul 19, 2021
1 parent b9c9282 commit f899954
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 3 deletions.
2 changes: 1 addition & 1 deletion configs/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {
'@swc-node/jest',
// configuration
{
target: 'es2019',
target: 'es2020',
experimentalDecorators: true,
emitDecoratorMetadata: true,
react: {
Expand Down
40 changes: 39 additions & 1 deletion packages/react/src/__tests__/ssr.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'reflect-metadata'

import { GLOBAL_KEY_SYMBOL, EffectModule, ImmerReducer, Module, Effect, Reducer, RETRY_KEY_SYMBOL } from '@sigi/core'
import { Injectable, Injector } from '@sigi/di'
import { emitSSREffects } from '@sigi/ssr'
import { emitSSREffects, match } from '@sigi/ssr'
import { Action } from '@sigi/types'
import { Draft } from 'immer'
import { useEffect } from 'react'
Expand Down Expand Up @@ -700,4 +700,42 @@ describe('SSR specs:', () => {
InnerServiceModule: ['setNameWithFailure'],
})
})

it('should support match fn', async () => {
@Module('InnerServiceModule2')
class InnerServiceModule2 extends EffectModule<CountState> {
readonly defaultState = { count: 0, name: '' }

@ImmerReducer()
setName(state: Draft<CountState>, name: string) {
state.name = name
}

@Effect({
payloadGetter: match(
['/users/:id'],
(ctx: any) => ctx.request.path,
)((ctx) => {
return ctx.request.path.length
}),
})
setNameWithFailure(payload$: Observable<number>): Observable<Action> {
return payload$.pipe(mergeMap((l) => of(this.getActions().setName(`length: ${l}`), this.terminate())))
}
}

const req = {
request: {
path: '/users/linus',
},
}
const state = await emitSSREffects(req, [InnerServiceModule2], { providers: [InnerServiceModule2] }).pendingState

expect(state['dataToPersist']).toEqual({
InnerServiceModule2: {
count: 0,
name: `length: ${req.request.path.length}`,
},
})
})
})
1 change: 1 addition & 0 deletions packages/ssr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@sigi/core": "^2.10.8",
"@sigi/di": "^2.10.2",
"@sigi/types": "^2.10.2",
"path-to-regexp": "^6.2.0",
"serialize-javascript": "^5.0.1",
"tslib": "^2.2.0"
},
Expand Down
42 changes: 42 additions & 0 deletions packages/ssr/src/__tests__/match.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { match } from '../match'
import { SKIP_SYMBOL } from '../run'

const CONTEXT = {
request: {
path: '/users/1111',
},
}

describe('Match function test', () => {
it('should return skip symbol if not matched', () => {
const payloadGetter = match(
['/user/me'],
(ctx: typeof CONTEXT) => ctx.request.path,
)(() => {
return 1
})
// @ts-expect-error
expect(payloadGetter(CONTEXT)).toBe(SKIP_SYMBOL)
})

it('should return skip symbol if request factory return falsy value', () => {
const payloadGetter = match(
['/user/me'],
(_ctx: typeof CONTEXT) => '',
)(() => {
return 1
})
// @ts-expect-error
expect(payloadGetter(CONTEXT)).toBe(SKIP_SYMBOL)
})

it('should into matched router', () => {
const payloadGetter = match(
['/users/:id'],
(ctx: typeof CONTEXT) => ctx.request.path,
)(() => {
return 1
})
expect(payloadGetter(CONTEXT, SKIP_SYMBOL)).toBe(1)
})
})
1 change: 1 addition & 0 deletions packages/ssr/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { runSSREffects as emitSSREffects, ModuleMeta } from './run'
export { match } from './match'
15 changes: 15 additions & 0 deletions packages/ssr/src/match.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { match as matchPath } from 'path-to-regexp'

import { SKIP_SYMBOL } from './run'

export function match<Ctx>(routers: string[], pathFactory: (ctx: Ctx) => string) {
return <T>(payloadGetter: (ctx: Ctx, skip: symbol) => T | Promise<T>) => {
return function payloadGetterWithMatch(ctx: Ctx, skip: symbol) {
const requestPath = pathFactory(ctx)
if (requestPath && routers.some((router) => matchPath(router)(requestPath))) {
return payloadGetter(ctx, skip)
}
return SKIP_SYMBOL
}
}
}
2 changes: 1 addition & 1 deletion packages/ssr/src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { StateToPersist } from './state-to-persist'

export type ModuleMeta = ConstructorOf<EffectModule<any>>

const SKIP_SYMBOL = Symbol('skip-symbol')
export const SKIP_SYMBOL = Symbol('skip-symbol')

/**
* Run all `@Effect({ ssr: true })` decorated effects of given modules and extract latest states.
Expand Down
6 changes: 6 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5389,6 +5389,7 @@ minipass-fetch@^1.3.0, minipass-fetch@^1.3.2:
resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.3.tgz#34c7cea038c817a8658461bf35174551dce17a0a"
integrity sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ==
dependencies:
encoding "^0.1.12"
minipass "^3.1.0"
minipass-sized "^1.0.3"
minizlib "^2.0.0"
Expand Down Expand Up @@ -6130,6 +6131,11 @@ path-to-regexp@^1.7.0:
dependencies:
isarray "0.0.1"

path-to-regexp@^6.2.0:
version "6.2.0"
resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.0.tgz#f7b3803336104c346889adece614669230645f38"
integrity sha512-f66KywYG6+43afgE/8j/GoiNyygk/bnoCbps++3ErRKsIYkGGupyv07R2Ok5m9i67Iqc+T2g1eAUGUPzWhYTyg==

path-type@^1.0.0:
version "1.1.0"
resolved "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
Expand Down

0 comments on commit f899954

Please sign in to comment.