Skip to content

Commit

Permalink
refactor(universal): env specific detail
Browse files Browse the repository at this point in the history
  • Loading branch information
07akioni committed Apr 14, 2024
1 parent da3d17c commit 6c49951
Show file tree
Hide file tree
Showing 8 changed files with 258 additions and 16 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ type LylaRequestOptions<C = undefined> = {
/**
* Callbacks fired after headers are received.
*
* only work in @lyla/web @lyla/node and lyla
* only work in @lylajs/web @lylajs/node and lyla
*/
onHeadersReceived?: Array<
(
Expand Down
2 changes: 1 addition & 1 deletion README.zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ type LylaRequestOptions<C = undefined> = {
/**
* 收到 headers 之后的回调
*
* 仅在 @lyla/web @lyla/node 和 lyla 中可用
* 仅在 @lylajs/web @lylajs/node 和 lyla 中可用
*/
onHeadersReceived?: Array<
(
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,16 +224,16 @@ export interface LylaAdapterOptions<T extends LylaAdapterMeta> {
url: string
method: T['method']
headers: Record<string, string>
body: T['requestBody']
body: T['requestBody'] | undefined
json: object | undefined
responseType: T['responseType']
withCredentials: boolean
onNetworkError(detail: T['networkErrorDetail']): void
onUploadProgress:
| ((progress: Omit<LylaProgress<T>, 'requestOptions'>) => void)
| ((progress: Omit<LylaProgress<unknown, T>, 'requestOptions'>) => void)
| undefined
onDownloadProgress:
| ((progress: Omit<LylaProgress<T>, 'requestOptions'>) => void)
| ((progress: Omit<LylaProgress<unknown, T>, 'requestOptions'>) => void)
| undefined
onHeadersReceived(
headers: Record<string, string>,
Expand Down
2 changes: 1 addition & 1 deletion packages/node/src/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export interface LylaAdapterMeta extends LylaCoreAdapterMeta {
| 'TRACE'
networkErrorDetail: Error
requestBody: string | Buffer | Uint8Array
responseDetail: any
responseDetail: null
progressDetail: null
responseType: 'text' | 'arraybuffer' | 'blob'
originalRequest: ClientRequest
Expand Down
29 changes: 29 additions & 0 deletions packages/playground/src/universal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,32 @@ lyla.head
lyla.delete
lyla.trace
lyla.connect

lyla
.get('foo', {
onDownloadProgress: (progress) => {
if (progress.detail.web !== undefined) {
const detail: ProgressEvent<XMLHttpRequestEventTarget> =
progress.detail.web
console.log('在 web 环境', detail)
} else {
const detail: null = progress.detail.node
console.log('在 node 环境', detail)
}
if (progress.originalRequest.web !== undefined) {
const originalRequest: XMLHttpRequest = progress.originalRequest.web
console.log('在 web 环境', originalRequest)
} else {
const originalRequest = progress.originalRequest.node
console.log('在 node 环境', originalRequest)
}
console.log(
'无所谓在什么环境',
progress.detail.anyhow,
progress.originalRequest.anyhow
)
}
})
.then((v) => {
v.body
})
56 changes: 50 additions & 6 deletions packages/universal/src/adapter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { LylaAdapterMeta as LylaCoreAdapterMeta } from '@lylajs/core'
import type { ClientRequest } from 'http'

// TODO: percise type
export interface LylaAdapterMeta extends LylaCoreAdapterMeta {
method:
| 'get'
Expand All @@ -21,10 +21,54 @@ export interface LylaAdapterMeta extends LylaCoreAdapterMeta {
| 'CONNECT'
| 'trace'
| 'TRACE'
networkErrorDetail: unknown
requestBody: any
responseDetail: unknown
networkErrorDetail:
| {
anyhow: ProgressEvent<XMLHttpRequestEventTarget> | Error
web: ProgressEvent<XMLHttpRequestEventTarget>
node: undefined
}
| {
anyhow: ProgressEvent<XMLHttpRequestEventTarget> | Error
node: Error
web: undefined
}
// Since body is produced in specific env, we don't need user to specify it,
// For example { anyhow?: xxx, web?: xxx, node?: xxx } is not neccessary
requestBody: XMLHttpRequestBodyInit | string | Buffer | Uint8Array
// This is for using uniform adapter to handle the response, it may be usefull
// in SSR env, however not that neccessary
responseDetail:
| {
anyhow: ProgressEvent<XMLHttpRequestEventTarget> | null
web: ProgressEvent<XMLHttpRequestEventTarget>
node: undefined
}
| {
anyhow: ProgressEvent<XMLHttpRequestEventTarget> | null
web: undefined
node: null
}
responseType: 'arraybuffer' | 'blob' | 'text'
progressDetail: unknown
originalRequest: unknown
progressDetail:
| {
anyhow: ProgressEvent<XMLHttpRequestEventTarget>
web: ProgressEvent<XMLHttpRequestEventTarget>
node: undefined
}
| {
anyhow: ProgressEvent<XMLHttpRequestEventTarget> | null
web: undefined
node: null
}
originalRequest:
| {
anyhow: XMLHttpRequest | ClientRequest
web: XMLHttpRequest
node: undefined
}
| {
anyhow: XMLHttpRequest | ClientRequest
web: undefined
node: ClientRequest
}
}
175 changes: 172 additions & 3 deletions packages/universal/src/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,183 @@ import type {
LylaRequestOptionsWithContext
} from './reexports'

const isNode = typeof window === 'undefined'

const adapter: any =
// @ts-expect-error
typeof window === 'undefined'
? (require('@lylajs/node') as typeof import('@lylajs/node')).adapter
? // webpack may handle this
(require('@lylajs/node') as typeof import('@lylajs/node')).adapter
: (require('@lylajs/web') as typeof import('@lylajs/web')).adapter

export const { lyla, isLylaError } = coreCreateLyla<undefined, LylaAdapterMeta>(
adapter,
({
url,
method,
headers,
body,
responseType,
json,
withCredentials,
onHeadersReceived,
onDownloadProgress,
onUploadProgress,
onResponse,
onNetworkError
}) => {
if (isNode) {
const _adapter = adapter as typeof import('@lylajs/node').adapter
const handle = _adapter({
url,
method,
headers,
body: body as any,
responseType,
json,
withCredentials,
onHeadersReceived(headers, originalRequest) {
return onHeadersReceived(headers, {
anyhow: originalRequest,
node: originalRequest,
web: undefined
})
},
onDownloadProgress(progress) {
return onDownloadProgress?.({
total: progress.total,
loaded: progress.loaded,
lengthComputable: progress.lengthComputable,
percent: progress.percent,
detail: {
anyhow: progress.detail,
node: progress.detail,
web: undefined
},
originalRequest: {
anyhow: progress.originalRequest,
node: progress.originalRequest,
web: undefined
}
})
},
onUploadProgress(progress) {
return onUploadProgress?.({
total: progress.total,
loaded: progress.loaded,
lengthComputable: progress.lengthComputable,
percent: progress.percent,
detail: {
anyhow: progress.detail,
node: progress.detail,
web: undefined
},
originalRequest: {
anyhow: progress.originalRequest,
node: progress.originalRequest,
web: undefined
}
})
},
onResponse({ body, status, headers }, detail) {
return onResponse(
{ body, status, headers },
{
anyhow: detail,
web: undefined,
node: detail
}
)
},
onNetworkError(detail) {
return onNetworkError({
anyhow: detail,
web: undefined,
node: detail
})
}
})
return {
abort: () => {
handle.abort()
}
}
} else {
const _adapter = adapter as typeof import('@lylajs/web').adapter
const handle = _adapter({
url,
method,
headers,
body,
responseType,
json,
withCredentials,
onHeadersReceived(headers, originalRequest) {
return onHeadersReceived(headers, {
anyhow: originalRequest,
node: undefined,
web: originalRequest
})
},
onDownloadProgress(progress) {
return onDownloadProgress?.({
total: progress.total,
loaded: progress.loaded,
lengthComputable: progress.lengthComputable,
percent: progress.percent,
detail: {
anyhow: progress.detail,
node: undefined,
web: progress.detail
},
originalRequest: {
anyhow: progress.originalRequest,
node: undefined,
web: progress.originalRequest
}
})
},
onUploadProgress(progress) {
return onUploadProgress?.({
total: progress.total,
loaded: progress.loaded,
lengthComputable: progress.lengthComputable,
percent: progress.percent,
detail: {
anyhow: progress.detail,
node: undefined,
web: progress.detail
},
originalRequest: {
anyhow: progress.originalRequest,
node: undefined,
web: progress.originalRequest
}
})
},
onResponse({ body, status, headers }, detail) {
return onResponse(
{ body, status, headers },
{
anyhow: detail,
web: detail,
node: undefined
}
)
},
onNetworkError(detail) {
return onNetworkError({
anyhow: detail,
web: detail,
node: undefined
})
}
})
return {
abort: () => {
handle.abort()
}
}
}
},
{
context: undefined
}
Expand Down
2 changes: 1 addition & 1 deletion packages/universal/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"declaration": true,
"lib": ["ES2015"],
"lib": ["ES2015", "DOM"],
"target": "ES2017",
"module": "CommonJS",
"esModuleInterop": true,
Expand Down

0 comments on commit 6c49951

Please sign in to comment.