Skip to content

Commit f899954

Browse files
committed
feat(ssr): support match fn
1 parent b9c9282 commit f899954

File tree

8 files changed

+106
-3
lines changed

8 files changed

+106
-3
lines changed

configs/jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module.exports = {
77
'@swc-node/jest',
88
// configuration
99
{
10-
target: 'es2019',
10+
target: 'es2020',
1111
experimentalDecorators: true,
1212
emitDecoratorMetadata: true,
1313
react: {

packages/react/src/__tests__/ssr.spec.tsx

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import 'reflect-metadata'
33

44
import { GLOBAL_KEY_SYMBOL, EffectModule, ImmerReducer, Module, Effect, Reducer, RETRY_KEY_SYMBOL } from '@sigi/core'
55
import { Injectable, Injector } from '@sigi/di'
6-
import { emitSSREffects } from '@sigi/ssr'
6+
import { emitSSREffects, match } from '@sigi/ssr'
77
import { Action } from '@sigi/types'
88
import { Draft } from 'immer'
99
import { useEffect } from 'react'
@@ -700,4 +700,42 @@ describe('SSR specs:', () => {
700700
InnerServiceModule: ['setNameWithFailure'],
701701
})
702702
})
703+
704+
it('should support match fn', async () => {
705+
@Module('InnerServiceModule2')
706+
class InnerServiceModule2 extends EffectModule<CountState> {
707+
readonly defaultState = { count: 0, name: '' }
708+
709+
@ImmerReducer()
710+
setName(state: Draft<CountState>, name: string) {
711+
state.name = name
712+
}
713+
714+
@Effect({
715+
payloadGetter: match(
716+
['/users/:id'],
717+
(ctx: any) => ctx.request.path,
718+
)((ctx) => {
719+
return ctx.request.path.length
720+
}),
721+
})
722+
setNameWithFailure(payload$: Observable<number>): Observable<Action> {
723+
return payload$.pipe(mergeMap((l) => of(this.getActions().setName(`length: ${l}`), this.terminate())))
724+
}
725+
}
726+
727+
const req = {
728+
request: {
729+
path: '/users/linus',
730+
},
731+
}
732+
const state = await emitSSREffects(req, [InnerServiceModule2], { providers: [InnerServiceModule2] }).pendingState
733+
734+
expect(state['dataToPersist']).toEqual({
735+
InnerServiceModule2: {
736+
count: 0,
737+
name: `length: ${req.request.path.length}`,
738+
},
739+
})
740+
})
703741
})

packages/ssr/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"@sigi/core": "^2.10.8",
3131
"@sigi/di": "^2.10.2",
3232
"@sigi/types": "^2.10.2",
33+
"path-to-regexp": "^6.2.0",
3334
"serialize-javascript": "^5.0.1",
3435
"tslib": "^2.2.0"
3536
},
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { match } from '../match'
2+
import { SKIP_SYMBOL } from '../run'
3+
4+
const CONTEXT = {
5+
request: {
6+
path: '/users/1111',
7+
},
8+
}
9+
10+
describe('Match function test', () => {
11+
it('should return skip symbol if not matched', () => {
12+
const payloadGetter = match(
13+
['/user/me'],
14+
(ctx: typeof CONTEXT) => ctx.request.path,
15+
)(() => {
16+
return 1
17+
})
18+
// @ts-expect-error
19+
expect(payloadGetter(CONTEXT)).toBe(SKIP_SYMBOL)
20+
})
21+
22+
it('should return skip symbol if request factory return falsy value', () => {
23+
const payloadGetter = match(
24+
['/user/me'],
25+
(_ctx: typeof CONTEXT) => '',
26+
)(() => {
27+
return 1
28+
})
29+
// @ts-expect-error
30+
expect(payloadGetter(CONTEXT)).toBe(SKIP_SYMBOL)
31+
})
32+
33+
it('should into matched router', () => {
34+
const payloadGetter = match(
35+
['/users/:id'],
36+
(ctx: typeof CONTEXT) => ctx.request.path,
37+
)(() => {
38+
return 1
39+
})
40+
expect(payloadGetter(CONTEXT, SKIP_SYMBOL)).toBe(1)
41+
})
42+
})

packages/ssr/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export { runSSREffects as emitSSREffects, ModuleMeta } from './run'
2+
export { match } from './match'

packages/ssr/src/match.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { match as matchPath } from 'path-to-regexp'
2+
3+
import { SKIP_SYMBOL } from './run'
4+
5+
export function match<Ctx>(routers: string[], pathFactory: (ctx: Ctx) => string) {
6+
return <T>(payloadGetter: (ctx: Ctx, skip: symbol) => T | Promise<T>) => {
7+
return function payloadGetterWithMatch(ctx: Ctx, skip: symbol) {
8+
const requestPath = pathFactory(ctx)
9+
if (requestPath && routers.some((router) => matchPath(router)(requestPath))) {
10+
return payloadGetter(ctx, skip)
11+
}
12+
return SKIP_SYMBOL
13+
}
14+
}
15+
}

packages/ssr/src/run.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { StateToPersist } from './state-to-persist'
66

77
export type ModuleMeta = ConstructorOf<EffectModule<any>>
88

9-
const SKIP_SYMBOL = Symbol('skip-symbol')
9+
export const SKIP_SYMBOL = Symbol('skip-symbol')
1010

1111
/**
1212
* Run all `@Effect({ ssr: true })` decorated effects of given modules and extract latest states.

yarn.lock

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5389,6 +5389,7 @@ minipass-fetch@^1.3.0, minipass-fetch@^1.3.2:
53895389
resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.3.3.tgz#34c7cea038c817a8658461bf35174551dce17a0a"
53905390
integrity sha512-akCrLDWfbdAWkMLBxJEeWTdNsjML+dt5YgOI4gJ53vuO0vrmYQkUPxa6j6V65s9CcePIr2SSWqjT2EcrNseryQ==
53915391
dependencies:
5392+
encoding "^0.1.12"
53925393
minipass "^3.1.0"
53935394
minipass-sized "^1.0.3"
53945395
minizlib "^2.0.0"
@@ -6130,6 +6131,11 @@ path-to-regexp@^1.7.0:
61306131
dependencies:
61316132
isarray "0.0.1"
61326133

6134+
path-to-regexp@^6.2.0:
6135+
version "6.2.0"
6136+
resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.0.tgz#f7b3803336104c346889adece614669230645f38"
6137+
integrity sha512-f66KywYG6+43afgE/8j/GoiNyygk/bnoCbps++3ErRKsIYkGGupyv07R2Ok5m9i67Iqc+T2g1eAUGUPzWhYTyg==
6138+
61336139
path-type@^1.0.0:
61346140
version "1.1.0"
61356141
resolved "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"

0 commit comments

Comments
 (0)